Compare commits
420 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4b21ef4f14 | |||
| 1e2869abb5 | |||
| 8bd46c6c18 | |||
| f7b4382a62 | |||
| 63d3ca4971 | |||
| 29518ddea6 | |||
| 20dd2ffd5d | |||
| e406511755 | |||
| e4abc61456 | |||
| c0c4df1254 | |||
| cc826afff1 | |||
| 53c18c4c4c | |||
| 0c9f29d3b4 | |||
| 14f03facd2 | |||
| b469be1b14 | |||
| c3e5b0c4b8 | |||
| 5ee992efb4 | |||
| 44b28f2d0a | |||
| b1db5bebd3 | |||
| 3f3caaaffe | |||
| b3d5b5f75e | |||
| ee5708f905 | |||
| 140a7bb3fd | |||
| 65ac1498b1 | |||
| 0f15eaabff | |||
| 54c8f71af7 | |||
| b31178c0c0 | |||
| 0af6919b5a | |||
| 393c915884 | |||
| ed274d2812 | |||
| 072e076bea | |||
| d6b5badccd | |||
| d237da548f | |||
| dee6bebcb7 | |||
| 40a98048bb | |||
| 1ea978eccd | |||
| bc8aeb8d7c | |||
| c35ec016dd | |||
| 283524cb4f | |||
| 10c9f6b8cc | |||
| e291953d09 | |||
| 1094c8ce2a | |||
| 747bb29729 | |||
| 4cab822a52 | |||
| adaa085e56 | |||
| 1f97243482 | |||
| b272a748ec | |||
| b121db89f0 | |||
| 35e6a47f2d | |||
| afeebf662b | |||
| 23ae346cee | |||
| d52c23b5c4 | |||
| 70e851e10d | |||
| a371db7522 | |||
| b755d12d7c | |||
| 30e3a363a8 | |||
| 6f692c34c2 | |||
| 6dac36ba1a | |||
| 2623a42ea7 | |||
| 8613c0a064 | |||
| e159f8a82b | |||
| 416793018f | |||
| c714a81edf | |||
| d9b5298572 | |||
| 38ec3d55ae | |||
| 046715fd07 | |||
| 07bd02d3c8 | |||
| b6ad1722f6 | |||
| 240b8218f0 | |||
| 8345b5b47d | |||
| 54f6fc1b12 | |||
| 2b59cb5d02 | |||
| d9d0ceac76 | |||
| 35400b4952 | |||
| 1d33619a85 | |||
| a4f3c4bb81 | |||
| 166c5f3f9c | |||
| 54c7e6cc7c | |||
| 859c9e4161 | |||
| b33fb79718 | |||
| 24faa2d887 | |||
| e9d3dda160 | |||
| 53ad439257 | |||
| d577410bb4 | |||
| df0e4ddcfa | |||
| 9948ea8df3 | |||
| 763220dcef | |||
| 208dab27dc | |||
| 3c816e989e | |||
| c44c333997 | |||
| 5fc700123f | |||
| 49437034a3 | |||
| 74486c8e30 | |||
| d6fc7f7911 | |||
| 2b5066f967 | |||
| a577589a92 | |||
| 62f02528c2 | |||
| 5b950914e3 | |||
| 99942982f6 | |||
| 18e9005c3d | |||
| d9f6dd22e1 | |||
| f5579c3deb | |||
| 60c0c66d22 | |||
| a2c17da35e | |||
| 20f46f2dab | |||
| cbf63c0f9c | |||
| f3db7525f9 | |||
| 694325e6b9 | |||
| 138702f077 | |||
| a739f856b4 | |||
| 68af0578d0 | |||
| 9042017a90 | |||
| 59b053faa9 | |||
| 63b9f4e775 | |||
| efe2e7f063 | |||
| 19b1d022e0 | |||
| 9e1372dc01 | |||
| a6a409c750 | |||
| fdcb81306d | |||
| ff395f1d56 | |||
| e346593ebb | |||
| fab6c8c55a | |||
| 282e56e5fc | |||
| a600f11422 | |||
| 2db4a293ed | |||
| 8641a11b53 | |||
| 980248d899 | |||
| 372ee55241 | |||
| 799c579121 | |||
| 4841a9ac1e | |||
| 287dd5d0bf | |||
| 32e23ca0a2 | |||
| b7d7b8c815 | |||
| 96fd034c5a | |||
| 6118e0a4f8 | |||
| c00d1fb89c | |||
| 900f4dfb64 | |||
| 11f8c9ca56 | |||
| 026f63c730 | |||
| e322952ff4 | |||
| e762da2bf5 | |||
| 822a4331aa | |||
| 2b2ba2a551 | |||
| 317fbc2ea7 | |||
| 0cd9d666c1 | |||
| 187ea3b92f | |||
| d2beb399dd | |||
| 15623ab515 | |||
| f771a23c2a | |||
| f20b8708a3 | |||
| 536ed731ed | |||
| 5b10619460 | |||
| 311ac85419 | |||
| ed8d2e285f | |||
| dba3351195 | |||
| 506d6504c7 | |||
| 1eede7832b | |||
| 5ec79bb61b | |||
| 548863845b | |||
| 2f73376ff6 | |||
| 9a8ee3a6aa | |||
| 28e367eb88 | |||
| 7d642b46c9 | |||
| 2be6757e23 | |||
| 4ca67212aa | |||
| 503f99ccbe | |||
| 93410b4075 | |||
| a96945201f | |||
| 35c495f8a8 | |||
| 9abd8e2c54 | |||
| b9a79f0658 | |||
| 83111d3338 | |||
| 92072d3640 | |||
| fd0ea313c2 | |||
| 79a15a08cc | |||
| 1af798fb04 | |||
| c19eb5bab7 | |||
| db693de576 | |||
| 651fa35018 | |||
| 36f1e9e8dd | |||
| 7e454467d1 | |||
| 978caf8e9c | |||
| 2bf4e5d8fd | |||
| dfb0c5a61c | |||
| 9d54fac8c5 | |||
| 5842590f6d | |||
| 06a60cac38 | |||
| dac5eb0d7d | |||
| 923edf166b | |||
| a0776e5462 | |||
| 9ac6d3df70 | |||
| a8a3104019 | |||
| 7cd476028a | |||
| fe96ff5924 | |||
| 890d349ee9 | |||
| 895eaa42c8 | |||
| 2e4457b56d | |||
| b30638fa82 | |||
| a3fac7bcb1 | |||
| 7228bdd9e9 | |||
| fa84171da4 | |||
| f4c3f685eb | |||
| db17d23360 | |||
| 76fe1e12d3 | |||
| d7f455c740 | |||
| d62d7172d0 | |||
| 9bfdb2f06a | |||
| d6436b01d4 | |||
| e848ee1972 | |||
| 2716b462b1 | |||
| 10f3db1ec2 | |||
| 0848a441b1 | |||
| 00c59958e6 | |||
| 9cc438a647 | |||
| 1053fdc8a8 | |||
| e1ee129f41 | |||
| dae0cab261 | |||
| 5871d054d3 | |||
| a69e8969a4 | |||
| dd05e26feb | |||
| 8cd8b7cf43 | |||
| 1d90aba7cd | |||
| 826aff3d36 | |||
| 718294f776 | |||
| 7a003eb490 | |||
| bcceb5d42d | |||
| b1802d7d79 | |||
| e14eeb4da3 | |||
| f726088cc9 | |||
| 4082850b7a | |||
| 641d61d242 | |||
| e2b67bb3f5 | |||
| 1f3e1ceb37 | |||
| 254e9508b6 | |||
| 631be6d7c7 | |||
| ca31e9a062 | |||
| 9fd7d9928a | |||
| 9362b2fb23 | |||
| 1735a4621e | |||
| 6ff332367d | |||
| e045302d38 | |||
| 88793cf011 | |||
| a4181f819b | |||
| 79aeb663c6 | |||
| 169301836a | |||
| 71bd67ba01 | |||
| 3e94dc6518 | |||
| 503322d57e | |||
| 0c9ffbf5e4 | |||
| fae7889995 | |||
| 532e514060 | |||
| b3a5047ba8 | |||
| 810e6ccb19 | |||
| 352e719fae | |||
| d8e0c73f56 | |||
| 46374be4c0 | |||
| 020c5280b3 | |||
| 4beba23f99 | |||
| 59f36cceb4 | |||
| d08b409f0e | |||
| 1612201101 | |||
| 924347361a | |||
| 061d212623 | |||
| af937b3f53 | |||
| 1faa72c5ea | |||
| db53e5a60b | |||
| 802e768bad | |||
| 67f17cffe0 | |||
| 70160cb937 | |||
| 6e22246555 | |||
| 7ed0258cfd | |||
| ddd06c8313 | |||
| d33b84c245 | |||
| 14cd5dd91c | |||
| 2b29ebc29b | |||
| 84b65ee122 | |||
| c3e9024a57 | |||
| d49b5663ba | |||
| e1386da5ae | |||
| b9f9af06f4 | |||
| 01a79e0612 | |||
| 3e69d72597 | |||
| f69c7af9d6 | |||
| ae03503d76 | |||
| 39eade67f0 | |||
| e6d7a0c0e0 | |||
| 98103451e9 | |||
| b64eed88cf | |||
| bafe61ae64 | |||
| 0579c4aeda | |||
| 7599e06b9d | |||
| 8e77d2e3ed | |||
| c2a129c56a | |||
| 111d5509bc | |||
| 7c9987f3de | |||
| f1471b6424 | |||
| 935369c05c | |||
| 2b03f382bd | |||
| 152a142d82 | |||
| f55ce703b0 | |||
| a08c8a0d64 | |||
| 76dd0c46ae | |||
| 1e8056f689 | |||
| d719015fa2 | |||
| 73fa62e6a2 | |||
| bb3f612772 | |||
| 99b6c63de7 | |||
| 8b046e61ab | |||
| ff2c619df7 | |||
| c9ffa64560 | |||
| 2969306d1e | |||
| 2fb558d388 | |||
| 9a0859f915 | |||
| 19bf8210f6 | |||
| 7a30fd0f28 | |||
| 432bf1ae12 | |||
| 967c0114d8 | |||
| 0f55c6da9d | |||
| 5e345418fb | |||
| de19c5bc32 | |||
| 1998842200 | |||
| 25a18e8366 | |||
| a2966e761c | |||
| 0508b8ffb3 | |||
| 9d4c69b39a | |||
| e11790ea92 | |||
| e559c2503b | |||
| c0a383ef58 | |||
| 9b6ddb0f16 | |||
| 45db942f66 | |||
| 41efcbfdf1 | |||
| 76c69a8464 | |||
| abe42ef3cf | |||
| 40f744ea4a | |||
| 7bc0d7f3dc | |||
| 9bbac291b6 | |||
| d7da7b69d4 | |||
| f6530cfb32 | |||
| 376dcc5bd5 | |||
| 89546b9874 | |||
| 385c40c895 | |||
| 8b9580abc8 | |||
| 3b9c8efeba | |||
| 5ba831c044 | |||
| 1141cc20e9 | |||
| 11a439a48f | |||
| 9ef3e53d77 | |||
| 104f46c9db | |||
| 0f0c670ec8 | |||
| c901f0e3d1 | |||
| 63e9428d6d | |||
| cbe7270f4b | |||
| fd67dad4b2 | |||
| 38b8f0085b | |||
| ab0e7afdb8 | |||
| 8045f96106 | |||
| 6481aa37e7 | |||
| 0b9ee87039 | |||
| 9b0d68d26d | |||
| 8ee7d7018f | |||
| 7c1c45417f | |||
| 1fbda0327c | |||
| 12f91c3b99 | |||
| 7d7c350df6 | |||
| caffff259e | |||
| 80b3defd37 | |||
| bbe1642786 | |||
| 4a2b9fdb41 | |||
| f7bc32ed90 | |||
| 592de4deb4 | |||
| ad5c36930e | |||
| c4570ebe62 | |||
| fdaf7180c0 | |||
| ee9152bbc4 | |||
| 413503e0f4 | |||
| 27c41af918 | |||
| fd21cf2539 | |||
| da485e1dde | |||
| 24dfa32ad4 | |||
| 1f9d9b2831 | |||
| 6211506aee | |||
| e1bd659dc5 | |||
| b56d45f411 | |||
| 35a2a0cc61 | |||
| ff43a5e71b | |||
| 8bdbc67535 | |||
| 85261bc3cf | |||
| 311359f6b8 | |||
| 0cb3646554 | |||
| cd02042d63 | |||
| db73a841b2 | |||
| a3e773cb4f | |||
| 09ed4adc93 | |||
| 530e4d412c | |||
| bff593394f | |||
| 32c38e9f95 | |||
| 005b0b9e0d | |||
| fdb124b12e | |||
| 652a446737 | |||
| 098196b599 | |||
| 01c5b96bc7 | |||
| 334743f3f0 | |||
| bd60f48cd1 | |||
| 4fe915cfd8 | |||
| 14cc78cffc | |||
| a04ae45402 | |||
| 0f68f170ad | |||
| 4033c8d004 | |||
| 68d320d9cf | |||
| 603a522c4b | |||
| 030aa36f94 | |||
| 577f35a3fe | |||
| 790ac40f4e | |||
| 44d9c23c0c | |||
| 547bd54085 | |||
| 388dac5f8d | |||
| ec0a4aeef9 | |||
| 8bf0be9699 | |||
| 7707b339dc | |||
| 8eaa6606c4 |
@@ -0,0 +1,9 @@
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<!-- 在这里定义所有项目共享的属性 -->
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<!-- 如果需要Nullable等全局设置,也可以加在这里 -->
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
@@ -1,37 +1,35 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.11" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.6.2" />
|
||||
<PackageReference Include="AlibabaCloud.SDK.Sts20150401" Version="1.1.5" />
|
||||
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="10.0.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="10.0.8" />
|
||||
<PackageReference Include="AlibabaCloud.SDK.Sts20150401" Version="1.2.0" />
|
||||
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="11.0.0" />
|
||||
<PackageReference Include="Aliyun.OSS.SDK.NetCore" Version="2.14.1" />
|
||||
<PackageReference Include="AWSSDK.S3" Version="4.0.21" />
|
||||
<PackageReference Include="AWSSDK.SecurityToken" Version="4.0.5.19" />
|
||||
<PackageReference Include="AWSSDK.S3" Version="4.0.24" />
|
||||
<PackageReference Include="AWSSDK.SecurityToken" Version="4.0.7" />
|
||||
|
||||
<PackageReference Include="DistributedLock.Core" Version="1.0.8" />
|
||||
<PackageReference Include="DistributedLock.SqlServer" Version="1.0.6" />
|
||||
<PackageReference Include="fo-dicom" Version="5.2.1" />
|
||||
<PackageReference Include="fo-dicom.Codecs" Version="5.16.1" />
|
||||
<PackageReference Include="fo-dicom.Imaging.ImageSharp" Version="5.2.1" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="8.0.10" />
|
||||
<PackageReference Include="AutoMapper" Version="13.0.1" />
|
||||
<PackageReference Include="Minio" Version="6.0.4" />
|
||||
<PackageReference Include="My.Extensions.Localization.Json" Version="3.3.0">
|
||||
<PackageReference Include="DistributedLock.Core" Version="1.0.9" />
|
||||
<PackageReference Include="DistributedLock.SqlServer" Version="1.0.7" />
|
||||
<PackageReference Include="fo-dicom" Version="5.2.6" />
|
||||
<PackageReference Include="fo-dicom.Codecs" Version="5.16.7" />
|
||||
<PackageReference Include="fo-dicom.Imaging.ImageSharp" Version="5.2.6" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="10.0.8" />
|
||||
<PackageReference Include="AutoMapper" Version="14.0.0" />
|
||||
<PackageReference Include="Minio" Version="7.0.0" />
|
||||
<PackageReference Include="My.Extensions.Localization.Json" Version="4.0.0">
|
||||
<TreatAsUsed>true</TreatAsUsed>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Panda.DynamicWebApi" Version="1.2.2" />
|
||||
<PackageReference Include="Serilog.Enrichers.ClientInfo" Version="2.1.2" />
|
||||
<PackageReference Include="Serilog.Extensions.Hosting" Version="9.0.0" />
|
||||
<PackageReference Include="Serilog.Sinks.Console" Version="6.0.0" />
|
||||
<PackageReference Include="Serilog.Sinks.File" Version="6.0.0" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="8.1.1" />
|
||||
<PackageReference Include="Serilog.Enrichers.ClientInfo" Version="2.9.0" />
|
||||
<PackageReference Include="Serilog.Extensions.Hosting" Version="10.0.0" />
|
||||
<PackageReference Include="Serilog.Sinks.Console" Version="6.1.1" />
|
||||
<PackageReference Include="Serilog.Sinks.File" Version="7.0.0" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="10.2.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -56,7 +56,7 @@ var _configuration = builder.Configuration;
|
||||
builder.Services.AddHealthChecks();
|
||||
|
||||
//本地化
|
||||
builder.Services.AddJsonLocalization(options => options.ResourcesPath = "Resources");
|
||||
builder.Services.AddJsonLocalization(options => options.ResourcesPath = new[] { "Resources" });
|
||||
|
||||
|
||||
// 异常、参数统一验证过滤器、Json序列化配置、字符串参数绑型统一Trim()
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -10,17 +8,17 @@
|
||||
<PackageReference Include="AlibabaCloud.SDK.Sts20150401" Version="1.2.0" />
|
||||
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="11.0.0" />
|
||||
<PackageReference Include="Aliyun.OSS.SDK.NetCore" Version="2.14.1" />
|
||||
<PackageReference Include="AWSSDK.S3" Version="4.0.21" />
|
||||
<PackageReference Include="AWSSDK.SecurityToken" Version="4.0.5.19" />
|
||||
<PackageReference Include="AWSSDK.S3" Version="4.0.24" />
|
||||
<PackageReference Include="AWSSDK.SecurityToken" Version="4.0.7" />
|
||||
<PackageReference Include="DistributedLock.Core" Version="1.0.9" />
|
||||
<PackageReference Include="DistributedLock.SqlServer" Version="1.0.7" />
|
||||
<PackageReference Include="fo-dicom" Version="5.2.6" />
|
||||
<PackageReference Include="fo-dicom.Codecs" Version="5.16.7" />
|
||||
<PackageReference Include="fo-dicom.Imaging.ImageSharp" Version="5.2.6" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="8.0.10" />
|
||||
<PackageReference Include="AutoMapper" Version="16.1.1" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="10.0.8" />
|
||||
<PackageReference Include="AutoMapper" Version="14.0.0" />
|
||||
<PackageReference Include="Minio" Version="7.0.0" />
|
||||
<PackageReference Include="My.Extensions.Localization.Json" Version="3.3.0">
|
||||
<PackageReference Include="My.Extensions.Localization.Json" Version="4.0.0">
|
||||
<TreatAsUsed>true</TreatAsUsed>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Panda.DynamicWebApi" Version="1.2.2" />
|
||||
@@ -28,7 +26,7 @@
|
||||
<PackageReference Include="Serilog.Extensions.Hosting" Version="10.0.0" />
|
||||
<PackageReference Include="Serilog.Sinks.Console" Version="6.1.1" />
|
||||
<PackageReference Include="Serilog.Sinks.File" Version="7.0.0" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="10.1.7" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="10.2.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -13,7 +13,6 @@ using IRaCIS.Core.SCP.Service;
|
||||
using MassTransit;
|
||||
using MassTransit.NewIdProviders;
|
||||
using Microsoft.AspNetCore.HttpOverrides;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Panda.DynamicWebApi;
|
||||
using Serilog;
|
||||
using Serilog.Events;
|
||||
@@ -71,7 +70,7 @@ builder.Services.AddHostedService<FileSyncWorker>();
|
||||
builder.Services.AddHealthChecks();
|
||||
|
||||
//本地化
|
||||
builder.Services.AddJsonLocalization(options => options.ResourcesPath = "Resources");
|
||||
builder.Services.AddJsonLocalization(options => options.ResourcesPath = new[] { "Resources" });
|
||||
|
||||
|
||||
// 异常、参数统一验证过滤器、Json序列化配置、字符串参数绑型统一Trim()
|
||||
|
||||
@@ -8,6 +8,7 @@ using IRaCIS.Core.Infra.EFCore;
|
||||
using IRaCIS.Core.Infrastructure;
|
||||
using IRaCIS.Core.Infrastructure.Extention;
|
||||
using IRaCIS.Core.SCP.Service;
|
||||
using MassTransit;
|
||||
using Medallion.Threading;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion.Internal;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
@@ -95,7 +96,7 @@ namespace IRaCIS.Core.SCP.Service
|
||||
public Task OnReceiveAssociationRequestAsync(DicomAssociation association)
|
||||
{
|
||||
|
||||
_upload = new SCPImageUpload() { StartTime = DateTime.Now, CallingAE = association.CallingAE, CalledAE = association.CalledAE, CallingAEIP = association.RemoteHost };
|
||||
_upload = new SCPImageUpload() { Id = NewId.NextSequentialGuid(), StartTime = DateTime.Now, CallingAE = association.CallingAE, CalledAE = association.CalledAE, CallingAEIP = association.RemoteHost };
|
||||
|
||||
|
||||
Log.Logger.Warning($"接收到来自{association.CallingAE}的连接");
|
||||
@@ -644,7 +645,7 @@ namespace IRaCIS.Core.SCP.Service
|
||||
ms.Position = 0;
|
||||
|
||||
//irc 从路径最后一截取Guid
|
||||
storeRelativePath = await ossService.UploadToOSSAsync(ms, ossFolderPath, instanceId.ToString(), false, uploadInfo: new FileUploadRecordAddOrEdit() { TrialId = _trialId, BatchDataType = BatchDataType.PACSReceive });
|
||||
storeRelativePath = await ossService.UploadToOSSAsync(ms, ossFolderPath, instanceId.ToString(), false, uploadInfo: new FileUploadRecordAddOrEdit() { TrialId = _trialId, BatchDataType = BatchDataType.PACSReceive, UploadBatchId = _upload.Id.ToString() });
|
||||
|
||||
fileSize = ms.Length;
|
||||
|
||||
|
||||
@@ -63,6 +63,8 @@ public class FileUploadRecordAddOrEdit
|
||||
public bool? IsNeedSync { get; set; }
|
||||
public string UploadRegion { get; set; }
|
||||
public string TargetRegion { get; set; }
|
||||
|
||||
public bool? IsSync { get; set; }
|
||||
}
|
||||
public interface IFileUploadRecordService
|
||||
{
|
||||
@@ -113,6 +115,19 @@ public class FileUploadRecordService(IRepository<FileUploadRecord> _fileUploadRe
|
||||
}
|
||||
}
|
||||
|
||||
//SCP推送过来IP为空,后端归档的,设置区域
|
||||
if (_userInfo.IP.IsNullOrEmpty() && _userInfo.Domain.IsNullOrEmpty())
|
||||
{
|
||||
var apiDefalut = ObjectStoreServiceConfig.SyncConfigList.FirstOrDefault(t => t.UploadRegion == ObjectStoreServiceConfig.ApiDeployRegion);
|
||||
|
||||
if (apiDefalut != null)
|
||||
{
|
||||
addOrEditFileUploadRecord.UploadRegion = apiDefalut.UploadRegion;
|
||||
addOrEditFileUploadRecord.TargetRegion = apiDefalut.TargetRegion;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (addOrEditFileUploadRecord.TrialId != null)
|
||||
{
|
||||
|
||||
@@ -129,9 +144,9 @@ public class FileUploadRecordService(IRepository<FileUploadRecord> _fileUploadRe
|
||||
{
|
||||
addOrEditFileUploadRecord.IsNeedSync = true;
|
||||
|
||||
addOrEditFileUploadRecord.Priority = 0;
|
||||
|
||||
addOrEditFileUploadRecord.Priority = addOrEditFileUploadRecord.Priority ?? 0;
|
||||
|
||||
addOrEditFileUploadRecord.IsSync = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -147,7 +162,9 @@ public class FileUploadRecordService(IRepository<FileUploadRecord> _fileUploadRe
|
||||
//系统文件,默认同步
|
||||
addOrEditFileUploadRecord.IsNeedSync = true;
|
||||
|
||||
addOrEditFileUploadRecord.Priority = 0;
|
||||
addOrEditFileUploadRecord.IsSync = false;
|
||||
|
||||
addOrEditFileUploadRecord.Priority = addOrEditFileUploadRecord.Priority ?? 0;
|
||||
}
|
||||
|
||||
var entity = await _fileUploadRecordRepository.InsertOrUpdateAsync(addOrEditFileUploadRecord, true);
|
||||
|
||||
@@ -194,7 +194,7 @@ public interface IOSSService
|
||||
|
||||
List<string> GetRootFolderNames();
|
||||
|
||||
public ObjectStoreDTO GetObjectStoreTempToken(string? domain = null, bool? isGetAllTempToken = null);
|
||||
public ObjectStoreDTO GetObjectStoreTempToken(string? domain = null, bool? isGetAllTempToken = null, string? objectUse = null);
|
||||
|
||||
public Task MoveObject(string sourcePath, string destPath, bool overwrite = true);
|
||||
|
||||
@@ -825,10 +825,12 @@ public class OSSService(IOptionsMonitor<ObjectStoreServiceOptions> options,
|
||||
|
||||
if (ObjectStoreServiceOptions.IsOpenStoreSync && uploadInfo != null)
|
||||
{
|
||||
var fileType = Path.GetExtension(returnPath).TrimStart('.');
|
||||
|
||||
uploadInfo.FileSize = fileStream.CanSeek ? fileStream.Length : 0;
|
||||
uploadInfo.Path = returnPath;
|
||||
uploadInfo.FileName = fileRealName;
|
||||
uploadInfo.FileType = Path.GetExtension(returnPath);
|
||||
uploadInfo.FileType = fileType.IsNullOrEmpty()?"dcm": fileType;
|
||||
|
||||
|
||||
await _fileUploadRecordService.AddOrUpdateFileUploadRecord(uploadInfo);
|
||||
@@ -964,10 +966,14 @@ public class OSSService(IOptionsMonitor<ObjectStoreServiceOptions> options,
|
||||
|
||||
if (ObjectStoreServiceOptions.IsOpenStoreSync && uploadInfo != null)
|
||||
{
|
||||
|
||||
var fileType = Path.GetExtension(returnPath).TrimStart('.');
|
||||
|
||||
uploadInfo.FileSize = fileSize;
|
||||
uploadInfo.Path = returnPath;
|
||||
uploadInfo.FileName = Path.GetFileName(localFilePath);
|
||||
uploadInfo.FileType = Path.GetExtension(returnPath);
|
||||
uploadInfo.FileType = fileType.IsNullOrEmpty() ? "dcm" : fileType;
|
||||
|
||||
|
||||
|
||||
await _fileUploadRecordService.AddOrUpdateFileUploadRecord(uploadInfo);
|
||||
@@ -1856,23 +1862,39 @@ public class OSSService(IOptionsMonitor<ObjectStoreServiceOptions> options,
|
||||
|
||||
|
||||
|
||||
public ObjectStoreDTO GetObjectStoreTempToken(string? domain = null, bool? isGetAllTempToken = null)
|
||||
public ObjectStoreDTO GetObjectStoreTempToken(string? domain = null, bool? isGetAllTempToken = null, string? objectUse = null)
|
||||
{
|
||||
//如果传递了域名,并且打开了存储同步,根据域名使用的具体存储覆盖之前的配置,否则就用固定的配置
|
||||
if (ObjectStoreServiceOptions.IsOpenStoreSync && domain.IsNotNullOrEmpty())
|
||||
string objectStoreUse = string.Empty;
|
||||
//使用指定配置
|
||||
if (objectUse != null)
|
||||
{
|
||||
var userDomain = domain?.Trim();
|
||||
|
||||
var find = ObjectStoreServiceOptions.SyncConfigList.FirstOrDefault(t => t.Domain == userDomain);
|
||||
if (find != null)
|
||||
objectStoreUse = objectUse?.Trim() ?? string.Empty;
|
||||
}
|
||||
//根据域名动态判断
|
||||
else
|
||||
{
|
||||
//如果传递了域名,并且打开了存储同步,根据域名使用的具体存储覆盖之前的配置,否则就用固定的配置
|
||||
if (ObjectStoreServiceOptions.IsOpenStoreSync && domain.IsNotNullOrEmpty() && ObjectStoreServiceOptions.SyncConfigList.Any(t => t.Domain == domain))
|
||||
{
|
||||
ObjectStoreServiceOptions.ObjectStoreUse = find.Primary;
|
||||
|
||||
var find = ObjectStoreServiceOptions.SyncConfigList.FirstOrDefault(t => t.Domain == domain);
|
||||
if (find != null)
|
||||
{
|
||||
objectStoreUse = find.Primary;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
//兜底,如果是本地测试环境,那就使用部署默认配置
|
||||
objectStoreUse = ObjectStoreServiceOptions.ObjectStoreUse;
|
||||
}
|
||||
}
|
||||
|
||||
var objectStoreDTO = new ObjectStoreDTO() { ObjectStoreUse = ObjectStoreServiceOptions.ObjectStoreUse, IsOpenStoreSync = ObjectStoreServiceOptions.IsOpenStoreSync, SyncConfigList = ObjectStoreServiceOptions.SyncConfigList };
|
||||
|
||||
if (ObjectStoreServiceOptions.ObjectStoreUse == "AliyunOSS" || isGetAllTempToken == true)
|
||||
var objectStoreDTO = new ObjectStoreDTO() { ObjectStoreUse = objectStoreUse, IsOpenStoreSync = ObjectStoreServiceOptions.IsOpenStoreSync, SyncConfigList = ObjectStoreServiceOptions.SyncConfigList };
|
||||
|
||||
if (objectStoreUse == "AliyunOSS" || isGetAllTempToken == true)
|
||||
{
|
||||
var ossOptions = ObjectStoreServiceOptions.AliyunOSS;
|
||||
|
||||
@@ -1920,11 +1942,11 @@ public class OSSService(IOptionsMonitor<ObjectStoreServiceOptions> options,
|
||||
objectStoreDTO.AliyunOSS = tempToken;
|
||||
|
||||
}
|
||||
else if (ObjectStoreServiceOptions.ObjectStoreUse == "MinIO")
|
||||
if (objectStoreUse == "MinIO")
|
||||
{
|
||||
objectStoreDTO.MinIO = ObjectStoreServiceOptions.MinIO;
|
||||
}
|
||||
else if (ObjectStoreServiceOptions.ObjectStoreUse == "AWS" || isGetAllTempToken == true)
|
||||
if (objectStoreUse == "AWS" || isGetAllTempToken == true)
|
||||
{
|
||||
var awsOptions = ObjectStoreServiceOptions.AWS;
|
||||
|
||||
@@ -1969,7 +1991,8 @@ public class OSSService(IOptionsMonitor<ObjectStoreServiceOptions> options,
|
||||
|
||||
objectStoreDTO.AWS = tempToken;
|
||||
}
|
||||
else
|
||||
|
||||
if (objectStoreUse.IsNullOrEmpty())
|
||||
{
|
||||
throw new BusinessValidationFailedException("未定义的存储介质类型");
|
||||
}
|
||||
@@ -1980,7 +2003,7 @@ public class OSSService(IOptionsMonitor<ObjectStoreServiceOptions> options,
|
||||
|
||||
public async Task SyncFileAsync(string objectKey, ObjectStoreUse source, ObjectStoreUse destination, CancellationToken ct = default)
|
||||
{
|
||||
GetObjectStoreTempToken(isGetAllTempToken: true);
|
||||
var tempConfig = GetObjectStoreTempToken(isGetAllTempToken: true);
|
||||
|
||||
|
||||
var aliConfig = ObjectStoreServiceOptions.AliyunOSS;
|
||||
@@ -1999,36 +2022,76 @@ public class OSSService(IOptionsMonitor<ObjectStoreServiceOptions> options,
|
||||
|
||||
var amazonS3Client = new AmazonS3Client(credentials, clientConfig);
|
||||
|
||||
// ⭐ 关键变量
|
||||
IDisposable? owner = null;
|
||||
Stream sourceStream;
|
||||
long contentLength;
|
||||
|
||||
// 根据源选择流式下载
|
||||
Stream sourceStream = source switch
|
||||
// ========= 获取流 + 长度 =========
|
||||
switch (source)
|
||||
{
|
||||
ObjectStoreUse.AliyunOSS => _ossClient.GetObject(aliConfig.BucketName, objectKey).Content,
|
||||
ObjectStoreUse.AWS => (await amazonS3Client.GetObjectAsync(awsConfig.BucketName, objectKey, ct)).ResponseStream,
|
||||
_ => throw new BusinessValidationFailedException("未定义的同步类型")
|
||||
};
|
||||
case ObjectStoreUse.AliyunOSS:
|
||||
{
|
||||
|
||||
if (source == ObjectStoreUse.AliyunOSS)
|
||||
var obj = _ossClient.GetObject(
|
||||
aliConfig.BucketName,
|
||||
objectKey);
|
||||
|
||||
owner = obj;
|
||||
sourceStream = obj.Content;
|
||||
contentLength = obj.ContentLength;
|
||||
break;
|
||||
}
|
||||
|
||||
case ObjectStoreUse.AWS:
|
||||
{
|
||||
var response = await amazonS3Client.GetObjectAsync(
|
||||
awsConfig.BucketName,
|
||||
objectKey,
|
||||
ct);
|
||||
|
||||
owner = response;
|
||||
sourceStream = response.ResponseStream;
|
||||
contentLength = response.Headers.ContentLength;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
throw new BusinessValidationFailedException("未定义的同步类型");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var putRequest = new Amazon.S3.Model.PutObjectRequest
|
||||
// ========= 上传 =========
|
||||
if (destination == ObjectStoreUse.AWS)
|
||||
{
|
||||
BucketName = awsConfig.BucketName,
|
||||
Key = objectKey,
|
||||
InputStream = sourceStream
|
||||
};
|
||||
var putRequest = new Amazon.S3.Model.PutObjectRequest
|
||||
{
|
||||
BucketName = awsConfig.BucketName,
|
||||
Key = objectKey,
|
||||
InputStream = sourceStream,
|
||||
Headers = { ContentLength = contentLength }
|
||||
};
|
||||
|
||||
await amazonS3Client.PutObjectAsync(putRequest, ct);
|
||||
await amazonS3Client.PutObjectAsync(putRequest, ct);
|
||||
}
|
||||
else if (destination == ObjectStoreUse.AliyunOSS)
|
||||
{
|
||||
_ossClient.PutObject(
|
||||
aliConfig.BucketName,
|
||||
objectKey,
|
||||
sourceStream);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new BusinessValidationFailedException("未定义的同步类型");
|
||||
}
|
||||
}
|
||||
else if (source == ObjectStoreUse.AWS)
|
||||
finally
|
||||
{
|
||||
_ossClient.PutObject(aliConfig.BucketName, objectKey, sourceStream);
|
||||
// ⭐⭐⭐ 真正释放 HTTP 连接
|
||||
owner?.Dispose();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new BusinessValidationFailedException("未定义的同步类型");
|
||||
}
|
||||
|
||||
await sourceStream.DisposeAsync(); // 释放流
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
using AutoMapper;
|
||||
using IRaCIS.Core.Domain.Models;
|
||||
using IRaCIS.Core.SCP.Service;
|
||||
|
||||
|
||||
namespace IRaCIS.Core.Application.Service
|
||||
{
|
||||
public class CommonConfig : Profile
|
||||
{
|
||||
public CommonConfig()
|
||||
{
|
||||
CreateMap<FileUploadRecordAddOrEdit, FileUploadRecord>().ReverseMap();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -8,6 +8,26 @@
|
||||
},
|
||||
"ObjectStoreService": {
|
||||
"ObjectStoreUse": "AliyunOSS",
|
||||
"IsOpenStoreSync": true,
|
||||
"ApiDeployRegion": "CN",
|
||||
"SyncConfigList": [
|
||||
{
|
||||
"Domain": "irc.extimaging.com",
|
||||
"Primary": "AliyunOSS",
|
||||
"Target": "AWS",
|
||||
"UploadRegion": "CN",
|
||||
"TargetRegion": "US",
|
||||
"IsOpenSync": true
|
||||
},
|
||||
{
|
||||
"Domain": "eiirc.extimaging.com",
|
||||
"Primary": "AWS",
|
||||
"Target": "AliyunOSS",
|
||||
"UploadRegion": "US",
|
||||
"TargetRegion": "CN",
|
||||
"IsOpenSync": true
|
||||
}
|
||||
],
|
||||
"AliyunOSS": {
|
||||
"RegionId": "cn-shanghai",
|
||||
"InternalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com",
|
||||
@@ -19,6 +39,18 @@
|
||||
"ViewEndpoint": "https://zy-irc-cache.oss-cn-shanghai.aliyuncs.com",
|
||||
"Region": "oss-cn-shanghai",
|
||||
"DurationSeconds": 7200
|
||||
},
|
||||
|
||||
"AWS": {
|
||||
"Region": "us-east-1",
|
||||
"EndPoint": "s3.us-east-1.amazonaws.com",
|
||||
"UseSSL": true,
|
||||
"RoleArn": "arn:aws:iam::471112624751:role/lili_s3_access",
|
||||
"AccessKeyId": "AKIAW3MEAFJXZ2TZK7GM",
|
||||
"SecretAccessKey": "9MLQCQ1HifEVW1gf068zBRAOb4wNnfrOkvBVByth",
|
||||
"BucketName": "ei-med-s3-irc-store",
|
||||
"ViewEndpoint": "https://ei-med-s3-irc-store.s3.amazonaws.com",
|
||||
"DurationSeconds": 7200
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft": "Warning",
|
||||
"Microsoft.Hosting.Lifetime": "Information"
|
||||
}
|
||||
},
|
||||
"ObjectStoreService": {
|
||||
"ObjectStoreUse": "AliyunOSS",
|
||||
"IsOpenStoreSync": true,
|
||||
"ApiDeployRegion": "CN",
|
||||
"SyncConfigList": [
|
||||
{
|
||||
"Domain": "irc.test.rayplus.net",
|
||||
"Primary": "AliyunOSS",
|
||||
"Target": "AWS",
|
||||
"UploadRegion": "CN",
|
||||
"TargetRegion": "US",
|
||||
"IsOpenSync": false
|
||||
},
|
||||
{
|
||||
"Domain": "lili.uat.extimaging.com",
|
||||
"Primary": "AWS",
|
||||
"Target": "AliyunOSS",
|
||||
"UploadRegion": "US",
|
||||
"TargetRegion": "CN",
|
||||
"IsOpenSync": false
|
||||
}
|
||||
],
|
||||
"AliyunOSS": {
|
||||
"RegionId": "cn-shanghai",
|
||||
"InternalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com",
|
||||
"EndPoint": "https://oss-cn-shanghai.aliyuncs.com",
|
||||
"AccessKeyId": "LTAI5tRRZehUp2V9pyTPtAJm",
|
||||
"AccessKeySecret": "FLizxkHsMm4CGYHtkV8E3PNJJZU7oV",
|
||||
"RoleArn": "acs:ram::1899121822495495:role/dev-oss-access",
|
||||
"BucketName": "rayplus-irc-test-store",
|
||||
"ViewEndpoint": "https://rayplus-irc-test-store.oss-cn-shanghai.aliyuncs.com",
|
||||
"Region": "oss-cn-shanghai",
|
||||
"DurationSeconds": 7200
|
||||
},
|
||||
// AWS S3 对象存储服务的配置
|
||||
"AWS": {
|
||||
// AWS S3 的Region
|
||||
"Region": "us-east-1",
|
||||
// AWS S3 的内部访问端点
|
||||
"EndPoint": "s3.us-east-1.amazonaws.com",
|
||||
// 是否使用 SSL
|
||||
"UseSSL": true,
|
||||
// AWS S3 的角色 ARN
|
||||
"RoleArn": "arn:aws:iam::471112624751:role/uat_s3_access",
|
||||
// AWS S3 的访问密钥 ID
|
||||
"AccessKeyId": "AKIAW3MEAFJX7IPXISP4",
|
||||
// AWS S3 的访问密钥 Secret
|
||||
"SecretAccessKey": "Pgrg3le5jPxZQ7MR1yYNS30J0XRyJeKVyIIjElXc",
|
||||
// AWS S3 的Bucket名称
|
||||
"BucketName": "ei-med-s3-lili-uat-store",
|
||||
// AWS S3 的访问端点
|
||||
"ViewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com",
|
||||
// AWS S3 的持续数秒
|
||||
"DurationSeconds": 7200
|
||||
}
|
||||
},
|
||||
"ConnectionStrings": {
|
||||
"RemoteNew": "Server=prod_mssql_standard,1433;Database=Prod_Rayplus;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true",
|
||||
"Hangfire": "Server=prod_mssql_standard,1433;Database=Prod_Rayplus_Hangfire;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true"
|
||||
},
|
||||
"DicomSCPServiceConfig": {
|
||||
"CalledAEList": [
|
||||
"STORESCP"
|
||||
],
|
||||
"ServerPort": 11112
|
||||
}
|
||||
|
||||
}
|
||||
@@ -7,7 +7,28 @@
|
||||
}
|
||||
},
|
||||
"ObjectStoreService": {
|
||||
// 使用的对象存储服务类型
|
||||
"ObjectStoreUse": "AliyunOSS",
|
||||
"IsOpenStoreSync": true,
|
||||
"ApiDeployRegion": "CN",
|
||||
"SyncConfigList": [
|
||||
{
|
||||
"Domain": "irc.test.extimaging.com",
|
||||
"Primary": "AliyunOSS",
|
||||
"Target": "AWS",
|
||||
"UploadRegion": "CN",
|
||||
"TargetRegion": "US",
|
||||
"IsOpenSync": true
|
||||
},
|
||||
{
|
||||
"Domain": "lili.test.extimaging.com",
|
||||
"Primary": "AWS",
|
||||
"Target": "AliyunOSS",
|
||||
"UploadRegion": "US",
|
||||
"TargetRegion": "CN",
|
||||
"IsOpenSync": true
|
||||
}
|
||||
],
|
||||
"AliyunOSS": {
|
||||
"RegionId": "cn-shanghai",
|
||||
"InternalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com",
|
||||
@@ -29,6 +50,27 @@
|
||||
"secretKey": "TzgvyA3zGXMUnpilJNUlyMYHfosl1hBMl6lxPmjy",
|
||||
"bucketName": "hir-test",
|
||||
"viewEndpoint": "http://106.14.89.110:9001/hir-test/"
|
||||
},
|
||||
// AWS S3 对象存储服务的配置
|
||||
"AWS": {
|
||||
// AWS S3 的Region
|
||||
"Region": "us-east-1",
|
||||
// AWS S3 的内部访问端点
|
||||
"EndPoint": "s3.us-east-1.amazonaws.com",
|
||||
// 是否使用 SSL
|
||||
"UseSSL": true,
|
||||
// AWS S3 的角色 ARN
|
||||
"RoleArn": "arn:aws:iam::471112624751:role/uat_s3_access",
|
||||
// AWS S3 的访问密钥 ID
|
||||
"AccessKeyId": "AKIAW3MEAFJX7IPXISP4",
|
||||
// AWS S3 的访问密钥 Secret
|
||||
"SecretAccessKey": "Pgrg3le5jPxZQ7MR1yYNS30J0XRyJeKVyIIjElXc",
|
||||
// AWS S3 的Bucket名称
|
||||
"BucketName": "ei-med-s3-lili-uat-store",
|
||||
// AWS S3 的访问端点
|
||||
"ViewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com",
|
||||
// AWS S3 的持续数秒
|
||||
"DurationSeconds": 7200
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft": "Warning",
|
||||
"Microsoft.Hosting.Lifetime": "Information"
|
||||
}
|
||||
},
|
||||
"ObjectStoreService": {
|
||||
"ObjectStoreUse": "AliyunOSS",
|
||||
"IsOpenStoreSync": true,
|
||||
"ApiDeployRegion": "CN",
|
||||
"SyncConfigList": [
|
||||
{
|
||||
"Domain": "irc.test.rayplus.net",
|
||||
"Primary": "AliyunOSS",
|
||||
"Target": "AWS",
|
||||
"UploadRegion": "CN",
|
||||
"TargetRegion": "US",
|
||||
"IsOpenSync": false
|
||||
},
|
||||
{
|
||||
"Domain": "lili.uat.extimaging.com",
|
||||
"Primary": "AWS",
|
||||
"Target": "AliyunOSS",
|
||||
"UploadRegion": "US",
|
||||
"TargetRegion": "CN",
|
||||
"IsOpenSync": false
|
||||
}
|
||||
],
|
||||
"AliyunOSS": {
|
||||
"RegionId": "cn-shanghai",
|
||||
"InternalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com",
|
||||
"EndPoint": "https://oss-cn-shanghai.aliyuncs.com",
|
||||
"AccessKeyId": "LTAI5tRRZehUp2V9pyTPtAJm",
|
||||
"AccessKeySecret": "FLizxkHsMm4CGYHtkV8E3PNJJZU7oV",
|
||||
"RoleArn": "acs:ram::1899121822495495:role/dev-oss-access",
|
||||
"BucketName": "rayplus-irc-test-store",
|
||||
"ViewEndpoint": "https://rayplus-irc-test-store.oss-cn-shanghai.aliyuncs.com",
|
||||
"Region": "oss-cn-shanghai",
|
||||
"DurationSeconds": 7200
|
||||
},
|
||||
// AWS S3 对象存储服务的配置
|
||||
"AWS": {
|
||||
// AWS S3 的Region
|
||||
"Region": "us-east-1",
|
||||
// AWS S3 的内部访问端点
|
||||
"EndPoint": "s3.us-east-1.amazonaws.com",
|
||||
// 是否使用 SSL
|
||||
"UseSSL": true,
|
||||
// AWS S3 的角色 ARN
|
||||
"RoleArn": "arn:aws:iam::471112624751:role/uat_s3_access",
|
||||
// AWS S3 的访问密钥 ID
|
||||
"AccessKeyId": "AKIAW3MEAFJX7IPXISP4",
|
||||
// AWS S3 的访问密钥 Secret
|
||||
"SecretAccessKey": "Pgrg3le5jPxZQ7MR1yYNS30J0XRyJeKVyIIjElXc",
|
||||
// AWS S3 的Bucket名称
|
||||
"BucketName": "ei-med-s3-lili-uat-store",
|
||||
// AWS S3 的访问端点
|
||||
"ViewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com",
|
||||
// AWS S3 的持续数秒
|
||||
"DurationSeconds": 7200
|
||||
}
|
||||
},
|
||||
"ConnectionStrings": {
|
||||
"RemoteNew": "Server=106.14.89.110,1435;Database=Test_Rayplus;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
|
||||
"Hangfire": "Server=106.14.89.110,1435;Database=Test_Rayplus_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true"
|
||||
},
|
||||
"DicomSCPServiceConfig": {
|
||||
"CalledAEList": [
|
||||
"STORESCP"
|
||||
],
|
||||
"ServerPort": 11112
|
||||
}
|
||||
|
||||
}
|
||||
@@ -8,6 +8,38 @@
|
||||
},
|
||||
"ObjectStoreService": {
|
||||
"ObjectStoreUse": "AWS",
|
||||
"IsOpenStoreSync": true,
|
||||
"ApiDeployRegion": "US",
|
||||
"SyncConfigList": [
|
||||
{
|
||||
"Domain": "eilili.elevateimaging.ai",
|
||||
"Primary": "AliyunOSS",
|
||||
"Target": "AWS",
|
||||
"UploadRegion": "CN",
|
||||
"TargetRegion": "US",
|
||||
"IsOpenSync": true
|
||||
},
|
||||
{
|
||||
"Domain": "lili.elevateimaging.ai",
|
||||
"Primary": "AWS",
|
||||
"Target": "AliyunOSS",
|
||||
"UploadRegion": "US",
|
||||
"TargetRegion": "CN",
|
||||
"IsOpenSync": true
|
||||
}
|
||||
],
|
||||
"AliyunOSS": {
|
||||
"RegionId": "cn-shanghai",
|
||||
"InternalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com",
|
||||
"EndPoint": "https://oss-cn-shanghai.aliyuncs.com",
|
||||
"AccessKeyId": "LTAI5tNRTsqL6aWmHkDmTwoH",
|
||||
"AccessKeySecret": "7mtGz3qrYWI6JMMBZiLeC119VWicZH",
|
||||
"RoleArn": "acs:ram::1899121822495495:role/irc-oss-access",
|
||||
"BucketName": "zy-lili-store",
|
||||
"ViewEndpoint": "https://zy-lili-cache.oss-cn-shanghai.aliyuncs.com",
|
||||
"Region": "oss-cn-shanghai",
|
||||
"DurationSeconds": 7200
|
||||
},
|
||||
"AWS": {
|
||||
"Region": "us-east-1",
|
||||
"EndPoint": "s3.us-east-1.amazonaws.com",
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft": "Warning",
|
||||
"Microsoft.Hosting.Lifetime": "Information"
|
||||
}
|
||||
},
|
||||
"ObjectStoreService": {
|
||||
"ObjectStoreUse": "AliyunOSS",
|
||||
"IsOpenStoreSync": true,
|
||||
"ApiDeployRegion": "CN",
|
||||
"SyncConfigList": [
|
||||
{
|
||||
"Domain": "irc.uat.extimaging.com",
|
||||
"Primary": "AliyunOSS",
|
||||
"Target": "AWS",
|
||||
"UploadRegion": "CN",
|
||||
"TargetRegion": "US",
|
||||
"IsOpenSync": true
|
||||
},
|
||||
{
|
||||
"Domain": "lili.uat.extimaging.com",
|
||||
"Primary": "AWS",
|
||||
"Target": "AliyunOSS",
|
||||
"UploadRegion": "US",
|
||||
"TargetRegion": "CN",
|
||||
"IsOpenSync": true
|
||||
}
|
||||
],
|
||||
"AliyunOSS": {
|
||||
"RegionId": "cn-shanghai",
|
||||
"InternalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com",
|
||||
"EndPoint": "https://oss-cn-shanghai.aliyuncs.com",
|
||||
"AccessKeyId": "LTAI5tRRZehUp2V9pyTPtAJm",
|
||||
"AccessKeySecret": "FLizxkHsMm4CGYHtkV8E3PNJJZU7oV",
|
||||
"RoleArn": "acs:ram::1899121822495495:role/dev-oss-access",
|
||||
"BucketName": "zy-irc-test-store",
|
||||
"ViewEndpoint": "https://zy-irc-test-store.oss-cn-shanghai.aliyuncs.com",
|
||||
"Region": "oss-cn-shanghai",
|
||||
"DurationSeconds": 7200
|
||||
},
|
||||
// AWS S3 对象存储服务的配置
|
||||
"AWS": {
|
||||
// AWS S3 的Region
|
||||
"Region": "us-east-1",
|
||||
// AWS S3 的内部访问端点
|
||||
"EndPoint": "s3.us-east-1.amazonaws.com",
|
||||
// 是否使用 SSL
|
||||
"UseSSL": true,
|
||||
// AWS S3 的角色 ARN
|
||||
"RoleArn": "arn:aws:iam::471112624751:role/uat_s3_access",
|
||||
// AWS S3 的访问密钥 ID
|
||||
"AccessKeyId": "AKIAW3MEAFJX7IPXISP4",
|
||||
// AWS S3 的访问密钥 Secret
|
||||
"SecretAccessKey": "Pgrg3le5jPxZQ7MR1yYNS30J0XRyJeKVyIIjElXc",
|
||||
// AWS S3 的Bucket名称
|
||||
"BucketName": "ei-med-s3-lili-uat-store",
|
||||
// AWS S3 的访问端点
|
||||
"ViewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com",
|
||||
// AWS S3 的持续数秒
|
||||
"DurationSeconds": 7200
|
||||
}
|
||||
},
|
||||
"ConnectionStrings": {
|
||||
"RemoteNew": "Server=101.132.253.119,1435;Database=Uat_HeAnShu;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
|
||||
"Hangfire": "Server101.132.253.119,1435;Database=Uat_HeAnShu_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true"
|
||||
},
|
||||
"DicomSCPServiceConfig": {
|
||||
"CalledAEList": [
|
||||
"STORESCP"
|
||||
],
|
||||
"ServerPort": 11112
|
||||
}
|
||||
|
||||
}
|
||||
@@ -8,17 +8,58 @@
|
||||
},
|
||||
"ObjectStoreService": {
|
||||
"ObjectStoreUse": "AliyunOSS",
|
||||
"IsOpenStoreSync": true,
|
||||
"ApiDeployRegion": "CN",
|
||||
"SyncConfigList": [
|
||||
{
|
||||
"Domain": "irc.uat.extimaging.com",
|
||||
"Primary": "AliyunOSS",
|
||||
"Target": "AWS",
|
||||
"UploadRegion": "CN",
|
||||
"TargetRegion": "US",
|
||||
"IsOpenSync": true
|
||||
},
|
||||
{
|
||||
"Domain": "lili.uat.extimaging.com",
|
||||
"Primary": "AWS",
|
||||
"Target": "AliyunOSS",
|
||||
"UploadRegion": "US",
|
||||
"TargetRegion": "CN",
|
||||
"IsOpenSync": true
|
||||
}
|
||||
],
|
||||
"AliyunOSS": {
|
||||
"RegionId": "cn-shanghai",
|
||||
"InternalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com",
|
||||
"EndPoint": "https://oss-cn-shanghai.aliyuncs.com",
|
||||
"AccessKeyId": "LTAI5tFUCCmz5TwghZHsj45Y",
|
||||
"AccessKeySecret": "8evrBy1fVfzJG25i67Jm0xqn9Xcw2T",
|
||||
"RoleArn": "acs:ram::1078130221702011:role/uat-oss-access",
|
||||
"BucketName": "tl-med-irc-uat-store",
|
||||
"ViewEndpoint": "https://tl-med-irc-uat-store.oss-cn-shanghai.aliyuncs.com",
|
||||
"AccessKeyId": "LTAI5tRRZehUp2V9pyTPtAJm",
|
||||
"AccessKeySecret": "FLizxkHsMm4CGYHtkV8E3PNJJZU7oV",
|
||||
"RoleArn": "acs:ram::1899121822495495:role/dev-oss-access",
|
||||
"BucketName": "zy-irc-test-store",
|
||||
"ViewEndpoint": "https://zy-irc-test-store.oss-cn-shanghai.aliyuncs.com",
|
||||
"Region": "oss-cn-shanghai",
|
||||
"DurationSeconds": 7200
|
||||
},
|
||||
// AWS S3 对象存储服务的配置
|
||||
"AWS": {
|
||||
// AWS S3 的Region
|
||||
"Region": "us-east-1",
|
||||
// AWS S3 的内部访问端点
|
||||
"EndPoint": "s3.us-east-1.amazonaws.com",
|
||||
// 是否使用 SSL
|
||||
"UseSSL": true,
|
||||
// AWS S3 的角色 ARN
|
||||
"RoleArn": "arn:aws:iam::471112624751:role/uat_s3_access",
|
||||
// AWS S3 的访问密钥 ID
|
||||
"AccessKeyId": "AKIAW3MEAFJX7IPXISP4",
|
||||
// AWS S3 的访问密钥 Secret
|
||||
"SecretAccessKey": "Pgrg3le5jPxZQ7MR1yYNS30J0XRyJeKVyIIjElXc",
|
||||
// AWS S3 的Bucket名称
|
||||
"BucketName": "ei-med-s3-lili-uat-store",
|
||||
// AWS S3 的访问端点
|
||||
"ViewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com",
|
||||
// AWS S3 的持续数秒
|
||||
"DurationSeconds": 7200
|
||||
}
|
||||
},
|
||||
"ConnectionStrings": {
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft": "Warning",
|
||||
"Microsoft.Hosting.Lifetime": "Information"
|
||||
}
|
||||
},
|
||||
"ObjectStoreService": {
|
||||
"ObjectStoreUse": "AliyunOSS",
|
||||
"IsOpenStoreSync": true,
|
||||
"ApiDeployRegion": "CN",
|
||||
"SyncConfigList": [
|
||||
{
|
||||
"Domain": "irc.uat.rayplus.net",
|
||||
"Primary": "AliyunOSS",
|
||||
"Target": "AWS",
|
||||
"UploadRegion": "CN",
|
||||
"TargetRegion": "US",
|
||||
"IsOpenSync": false
|
||||
},
|
||||
{
|
||||
"Domain": "lili.uat.extimaging.com",
|
||||
"Primary": "AWS",
|
||||
"Target": "AliyunOSS",
|
||||
"UploadRegion": "US",
|
||||
"TargetRegion": "CN",
|
||||
"IsOpenSync": false
|
||||
}
|
||||
],
|
||||
"AliyunOSS": {
|
||||
"RegionId": "cn-shanghai",
|
||||
"InternalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com",
|
||||
"EndPoint": "https://oss-cn-shanghai.aliyuncs.com",
|
||||
"AccessKeyId": "LTAI5tFUCCmz5TwghZHsj45Y",
|
||||
"AccessKeySecret": "8evrBy1fVfzJG25i67Jm0xqn9Xcw2T",
|
||||
"RoleArn": "acs:ram::1078130221702011:role/uat-oss-access",
|
||||
"BucketName": "rayplus-irc-uat-store",
|
||||
"ViewEndpoint": "https://rayplus-irc-uat-store.oss-cn-shanghai.aliyuncs.com",
|
||||
"Region": "oss-cn-shanghai",
|
||||
"DurationSeconds": 7200
|
||||
},
|
||||
// AWS S3 对象存储服务的配置
|
||||
"AWS": {
|
||||
// AWS S3 的Region
|
||||
"Region": "us-east-1",
|
||||
// AWS S3 的内部访问端点
|
||||
"EndPoint": "s3.us-east-1.amazonaws.com",
|
||||
// 是否使用 SSL
|
||||
"UseSSL": true,
|
||||
// AWS S3 的角色 ARN
|
||||
"RoleArn": "arn:aws:iam::471112624751:role/uat_s3_access",
|
||||
// AWS S3 的访问密钥 ID
|
||||
"AccessKeyId": "AKIAW3MEAFJX7IPXISP4",
|
||||
// AWS S3 的访问密钥 Secret
|
||||
"SecretAccessKey": "Pgrg3le5jPxZQ7MR1yYNS30J0XRyJeKVyIIjElXc",
|
||||
// AWS S3 的Bucket名称
|
||||
"BucketName": "ei-med-s3-lili-uat-store",
|
||||
// AWS S3 的访问端点
|
||||
"ViewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com",
|
||||
// AWS S3 的持续数秒
|
||||
"DurationSeconds": 7200
|
||||
}
|
||||
},
|
||||
"ConnectionStrings": {
|
||||
"RemoteNew": "Server=101.132.253.119,1435;Database=Uat_Rayplus;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
|
||||
"Hangfire": "Server101.132.253.119,1435;Database=Uat_Rayplus_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true"
|
||||
},
|
||||
"DicomSCPServiceConfig": {
|
||||
"CalledAEList": [
|
||||
"STORESCP"
|
||||
],
|
||||
"ServerPort": 11112
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,43 +1,21 @@
|
||||
using AlibabaCloud.SDK.Sts20150401;
|
||||
using Amazon.Auth.AccessControlPolicy;
|
||||
using Amazon.SecurityToken;
|
||||
using AutoMapper;
|
||||
using Azure.Core;
|
||||
using IdentityModel.Client;
|
||||
using IdentityModel.OidcClient;
|
||||
using IRaCIS.Application.Contracts;
|
||||
using IRaCIS.Application.Interfaces;
|
||||
using IRaCIS.Core.Application.Auth;
|
||||
using IRaCIS.Core.Application.Contracts;
|
||||
using IRaCIS.Core.Application.Helper;
|
||||
using IRaCIS.Core.Application.Service;
|
||||
using IRaCIS.Core.Domain.Models;
|
||||
using IRaCIS.Core.Domain.Share;
|
||||
using IRaCIS.Core.Infra.EFCore;
|
||||
using IRaCIS.Core.Infrastructure.Extention;
|
||||
using MassTransit;
|
||||
using MassTransit.Futures.Contracts;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Org.BouncyCastle.Tls;
|
||||
using RestSharp;
|
||||
using RestSharp.Authenticators;
|
||||
using Serilog;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
using ZiggyCreatures.Caching.Fusion;
|
||||
using AssumeRoleRequest = Amazon.SecurityToken.Model.AssumeRoleRequest;
|
||||
using LoginReturnDTO = IRaCIS.Application.Contracts.LoginReturnDTO;
|
||||
|
||||
namespace IRaCIS.Api.Controllers
|
||||
{
|
||||
|
||||
@@ -351,6 +351,23 @@ namespace IRaCIS.Core.API.Controllers
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 提交阅片裁判表单
|
||||
/// </summary>
|
||||
/// <param name="opt"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost, Route("Inspection/ReadingImageTask/SubmitJudgeForm")]
|
||||
[TrialGlobalLimit("AfterStopCannNotOpt")]
|
||||
|
||||
[UnitOfWork]
|
||||
|
||||
public async Task<IResponseOutput> SubmitJudgeForm(DataInspectionDto<SetJudgeFormInDto> opt)
|
||||
{
|
||||
var singid = await _inspectionService.RecordSing(opt.SignInfo);
|
||||
var result = await _iReadingImageTaskService.SubmitJudgeForm(opt.Data);
|
||||
await _inspectionService.CompletedSign(singid, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 配置 基础逻辑信息并确认
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
using AutoMapper;
|
||||
using ExcelDataReader;
|
||||
using IRaCIS.Application.Interfaces;
|
||||
using IRaCIS.Core.Application.BusinessFilter;
|
||||
using IRaCIS.Core.Application.Contracts;
|
||||
using IRaCIS.Core.Application.Contracts.Dicom;
|
||||
using IRaCIS.Core.Application.Contracts.Dicom.DTO;
|
||||
using IRaCIS.Core.Application.Filter;
|
||||
using IRaCIS.Core.Application.Helper;
|
||||
using IRaCIS.Core.Application.MassTransit.Command;
|
||||
using IRaCIS.Core.Application.Service;
|
||||
@@ -17,8 +15,6 @@ using IRaCIS.Core.Infrastructure;
|
||||
using IRaCIS.Core.Infrastructure.Extention;
|
||||
using MassTransit.Mediator;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
||||
@@ -27,21 +23,15 @@ using Microsoft.AspNetCore.StaticFiles;
|
||||
using Microsoft.AspNetCore.WebUtilities;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Localization;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
using MiniExcelLibs;
|
||||
using Newtonsoft.Json;
|
||||
using SharpCompress.Archives;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Data;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using Path = System.IO.Path;
|
||||
|
||||
namespace IRaCIS.Core.API.Controllers
|
||||
@@ -132,7 +122,7 @@ namespace IRaCIS.Core.API.Controllers
|
||||
//处理压缩文件
|
||||
if (fileName.Contains(".Zip", StringComparison.OrdinalIgnoreCase) || fileName.Contains(".rar", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
var archive = ArchiveFactory.Open(section.Body);
|
||||
var archive = ArchiveFactory.OpenArchive(section.Body);
|
||||
|
||||
foreach (var entry in archive.Entries)
|
||||
{
|
||||
@@ -213,7 +203,7 @@ namespace IRaCIS.Core.API.Controllers
|
||||
//处理压缩文件
|
||||
if (fileName.Contains(".Zip", StringComparison.OrdinalIgnoreCase) || fileName.Contains(".rar", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
var archive = ArchiveFactory.Open(section.Body);
|
||||
var archive = ArchiveFactory.OpenArchive(section.Body);
|
||||
|
||||
foreach (var entry in archive.Entries)
|
||||
{
|
||||
@@ -857,7 +847,7 @@ namespace IRaCIS.Core.API.Controllers
|
||||
throw new BusinessValidationFailedException(_localizer["UploadDownLoad_TemplateUploadData"]);
|
||||
}
|
||||
|
||||
var ossRelativePath = await oSSService.UploadToOSSAsync(fileStream, $"{trialId.ToString()}/InspectionUpload/SiteSurvey", realFileName, uploadInfo: new FileUploadRecordAddOrEdit() { TrialId = trialId ,BatchDataType=BatchDataType.SiteUserSurvey});
|
||||
var ossRelativePath = await oSSService.UploadToOSSAsync(fileStream, $"{trialId.ToString()}/InspectionUpload/SiteSurvey", realFileName, uploadInfo: new FileUploadRecordAddOrEdit() { TrialId = trialId, BatchDataType = BatchDataType.SiteUserSurvey });
|
||||
|
||||
await _inspectionFileRepository.AddAsync(new InspectionFile() { FileName = realFileName, RelativePath = ossRelativePath, TrialId = trialId }, true);
|
||||
|
||||
@@ -933,7 +923,7 @@ namespace IRaCIS.Core.API.Controllers
|
||||
}
|
||||
//处理好 用户类型 和用户类型枚举
|
||||
var sysUserTypeList = _usertypeRepository.Where(t => t.UserTypeEnum == UserTypeEnum.CRA || t.UserTypeEnum == UserTypeEnum.ClinicalResearchCoordinator).Select(t => new { UserTypeId = t.Id, t.UserTypeEnum }).ToList();
|
||||
var siteList = _trialSiteRepository.Where(t => t.TrialId == trialId && siteCodeList.Contains(t.TrialSiteCode)).Select(t => new { t.TrialSiteCode, TrialSiteId = t.Id }).ToList();
|
||||
var siteList = _trialSiteRepository.Where(t => t.TrialId == trialId && siteCodeList.Contains(t.TrialSiteCode)).Select(t => new { t.TrialSiteCode, TrialSiteId = t.Id, t.Country }).ToList();
|
||||
|
||||
foreach (var item in excelList)
|
||||
{
|
||||
@@ -955,6 +945,8 @@ namespace IRaCIS.Core.API.Controllers
|
||||
}
|
||||
|
||||
item.TrialSiteId = siteList.FirstOrDefault(t => t.TrialSiteCode.Trim().ToUpper() == item.TrialSiteCode.Trim().ToUpper()).TrialSiteId;
|
||||
|
||||
item.Country = siteList.FirstOrDefault(t => t.TrialSiteCode.Trim().ToUpper() == item.TrialSiteCode.Trim().ToUpper()).Country;
|
||||
}
|
||||
|
||||
var list = excelList.Where(t => t.UserTypeEnum == UserTypeEnum.ClinicalResearchCoordinator || t.UserTypeEnum == UserTypeEnum.CRA).ToList();
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<SignAssembly>false</SignAssembly>
|
||||
<UserSecretsId>354572d4-9e15-4099-807c-63a2d29ff9f2</UserSecretsId>
|
||||
<LangVersion>default</LangVersion>
|
||||
@@ -10,6 +9,7 @@
|
||||
<Company>上海展影医疗科技有限公司</Company>
|
||||
<Product>IRC影像系统 (EICS)</Product>
|
||||
<Copyright>上海展影医疗科技有限公司版权所有</Copyright>
|
||||
<NoWarn>$(NoWarn);NU1903</NoWarn>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
@@ -69,22 +69,21 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AspNetCoreRateLimit" Version="5.0.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.14" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="10.0.8" />
|
||||
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.15">
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="10.0.8">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="ConfigMapFileProvider" Version="2.0.1" />
|
||||
<PackageReference Include="Hangfire.AspNetCore" Version="1.8.20" />
|
||||
<PackageReference Include="Hangfire.AspNetCore" Version="1.8.23" />
|
||||
<PackageReference Include="Hangfire.Dashboard.BasicAuthorization" Version="1.0.2" />
|
||||
<PackageReference Include="Hangfire.InMemory" Version="1.0.0" />
|
||||
<PackageReference Include="Hangfire.SqlServer" Version="1.8.20" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="8.0.10" />
|
||||
<PackageReference Include="Hangfire.SqlServer" Version="1.8.23" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="10.0.8" />
|
||||
<PackageReference Include="Serilog.Formatting.Compact" Version="3.0.0" />
|
||||
<PackageReference Include="Serilog.Sinks.Email" Version="4.1.0" />
|
||||
<PackageReference Include="Serilog.Sinks.File" Version="7.0.0" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="9.0.1" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="10.2.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -213,6 +213,13 @@
|
||||
<param name="opt"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.API.Controllers.InspectionController.SubmitJudgeForm(IRaCIS.Core.Application.Service.Inspection.DTO.DataInspectionDto{IRaCIS.Core.Application.Service.Reading.Dto.SetJudgeFormInDto})">
|
||||
<summary>
|
||||
提交阅片裁判表单
|
||||
</summary>
|
||||
<param name="opt"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.API.Controllers.InspectionController.ConfigTrialBasicInfoConfirm(IRaCIS.Core.Application.Service.Inspection.DTO.DataInspectionDto{IRaCIS.Core.Application.Contracts.BasicTrialConfig})">
|
||||
<summary>
|
||||
配置 基础逻辑信息并确认
|
||||
@@ -378,6 +385,11 @@
|
||||
LowerCamelCaseJsonAttribute 可以设置类小写返回给前端
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:Program">
|
||||
<summary>
|
||||
Auto-generated public partial Program class for top-level statement apps.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:ZhaoXi._001.NET5Demo.Practice.WebApi.Utility.Jwt.CustomHSJWTService">
|
||||
<summary>
|
||||
对称可逆加密
|
||||
@@ -413,5 +425,49 @@
|
||||
<param name="withPrivate"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:Microsoft.AspNetCore.OpenApi.Generated.DocumentationCommentIdHelper.CreateDocumentationId(System.Type)">
|
||||
<summary>
|
||||
Generates a documentation comment ID for a type.
|
||||
Example: T:Namespace.Outer+Inner`1 becomes T:Namespace.Outer.Inner`1
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Microsoft.AspNetCore.OpenApi.Generated.DocumentationCommentIdHelper.CreateDocumentationId(System.Reflection.PropertyInfo)">
|
||||
<summary>
|
||||
Generates a documentation comment ID for a property.
|
||||
Example: P:Namespace.ContainingType.PropertyName or for an indexer P:Namespace.ContainingType.Item(System.Int32)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Microsoft.AspNetCore.OpenApi.Generated.DocumentationCommentIdHelper.CreateDocumentationId(System.Type,System.String)">
|
||||
<summary>
|
||||
Generates a documentation comment ID for a property given its container type and property name.
|
||||
Example: P:Namespace.ContainingType.PropertyName
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Microsoft.AspNetCore.OpenApi.Generated.DocumentationCommentIdHelper.CreateDocumentationId(System.Reflection.MethodInfo)">
|
||||
<summary>
|
||||
Generates a documentation comment ID for a method (or constructor).
|
||||
For example:
|
||||
M:Namespace.ContainingType.MethodName(ParamType1,ParamType2)~ReturnType
|
||||
M:Namespace.ContainingType.#ctor(ParamType)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Microsoft.AspNetCore.OpenApi.Generated.DocumentationCommentIdHelper.GetTypeDocId(System.Type,System.Boolean,System.Boolean)">
|
||||
<summary>
|
||||
Generates a documentation ID string for a type.
|
||||
This method handles nested types (replacing '+' with '.'),
|
||||
generic types, arrays, pointers, by-ref types, and generic parameters.
|
||||
The <paramref name="includeGenericArguments"/> flag controls whether
|
||||
constructed generic type arguments are emitted, while <paramref name="omitGenericArity"/>
|
||||
controls whether the generic arity marker (e.g. "`1") is appended.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Microsoft.AspNetCore.OpenApi.Generated.DocumentationCommentIdHelper.NormalizeDocId(System.String)">
|
||||
<summary>
|
||||
Normalizes a documentation comment ID to match the compiler-style format.
|
||||
Strips the return type suffix for ordinary methods but retains it for conversion operators.
|
||||
</summary>
|
||||
<param name="docId">The documentation comment ID to normalize.</param>
|
||||
<returns>The normalized documentation comment ID.</returns>
|
||||
</member>
|
||||
</members>
|
||||
</doc>
|
||||
|
||||
@@ -4,30 +4,16 @@ using IRaCIS.Core.API.HostService;
|
||||
using IRaCIS.Core.Application.BusinessFilter;
|
||||
using IRaCIS.Core.Application.BusinessFilter.LegacyController.Database.Api;
|
||||
using IRaCIS.Core.Application.Filter;
|
||||
using IRaCIS.Core.Application.MassTransit.Consumer;
|
||||
using IRaCIS.Core.Application.Service;
|
||||
using IRaCIS.Core.Application.Service.BusinessFilter;
|
||||
using IRaCIS.Core.Infra.EFCore;
|
||||
using IRaCIS.Core.Infrastructure.Extention;
|
||||
using MassTransit;
|
||||
using MassTransit.NewIdProviders;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.SignalR;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Localization;
|
||||
using Newtonsoft.Json;
|
||||
using Serilog;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using UAParser;
|
||||
|
||||
AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true);
|
||||
AppContext.SetSwitch("Npgsql.DisableDateTimeInfinityConversions", true);
|
||||
@@ -65,7 +51,8 @@ SerilogExtension.AddSerilogSetup(enviromentName);
|
||||
var builder = WebApplication.CreateBuilder(new WebApplicationOptions
|
||||
{
|
||||
|
||||
EnvironmentName = enviromentName
|
||||
EnvironmentName = enviromentName,
|
||||
Args = args
|
||||
});
|
||||
|
||||
#region 主机配置
|
||||
@@ -94,6 +81,8 @@ builder.Services.AddSingleton<FileSyncQueue>();
|
||||
builder.Services.AddHostedService<SyncFileRecoveryService>();
|
||||
builder.Services.AddHostedService<FileSyncWorker>();
|
||||
|
||||
builder.Services.AddSingleton(_ => Parser.GetDefault());
|
||||
|
||||
//minimal api 异常处理
|
||||
builder.Services.AddExceptionHandler<GlobalExceptionHandler>();
|
||||
//builder.Services.AddProblemDetails();
|
||||
@@ -102,7 +91,7 @@ builder.Services.AddExceptionHandler<GlobalExceptionHandler>();
|
||||
builder.Services.AddHealthChecks();
|
||||
builder.Services.AddSerilog();
|
||||
//本地化
|
||||
builder.Services.AddJsonLocalization(options => options.ResourcesPath = "Resources");
|
||||
builder.Services.AddJsonLocalization(options => options.ResourcesPath = new[] { "Resources" });
|
||||
|
||||
// 异常、参数统一验证过滤器、Json序列化配置、字符串参数绑型统一Trim()
|
||||
builder.Services.AddControllers(options =>
|
||||
@@ -285,6 +274,7 @@ try
|
||||
#region 运行环境 部署平台
|
||||
|
||||
Log.Logger.Warning($"当前环境:{enviromentName}");
|
||||
Log.Logger.Warning($".NET 运行时版本:{Environment.Version}");
|
||||
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
{
|
||||
|
||||
@@ -25,6 +25,24 @@
|
||||
},
|
||||
"applicationUrl": "http://0.0.0.0:6100"
|
||||
},
|
||||
"IRaCIS.Test_Rayplus": {
|
||||
"commandName": "Project",
|
||||
"launchBrowser": true,
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Test_Rayplus",
|
||||
"ASPNETCORE_OpenSwagger": "true"
|
||||
},
|
||||
"applicationUrl": "http://0.0.0.0:6100"
|
||||
},
|
||||
"IRaCIS.Uat_Rayplus": {
|
||||
"commandName": "Project",
|
||||
"launchBrowser": true,
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Uat_Rayplus",
|
||||
"ASPNETCORE_OpenSwagger": "true"
|
||||
},
|
||||
"applicationUrl": "http://0.0.0.0:6100"
|
||||
},
|
||||
"IRaCIS.Test_IRC_PGSQL": {
|
||||
"commandName": "Project",
|
||||
"launchBrowser": true,
|
||||
@@ -33,11 +51,11 @@
|
||||
},
|
||||
"applicationUrl": "http://0.0.0.0:6100"
|
||||
},
|
||||
"IRaCIS.Event_IRC": {
|
||||
"IRaCIS.Prod_Event_IRC": {
|
||||
"commandName": "Project",
|
||||
"launchBrowser": true,
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Event_IRC"
|
||||
"ASPNETCORE_ENVIRONMENT": "Prod_Event_IRC"
|
||||
},
|
||||
"applicationUrl": "http://0.0.0.0:6100"
|
||||
},
|
||||
|
||||
@@ -5,6 +5,7 @@ using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Serilog;
|
||||
using System.Linq;
|
||||
using UAParser;
|
||||
|
||||
namespace IRaCIS.Core.API
|
||||
{
|
||||
@@ -17,11 +18,14 @@ namespace IRaCIS.Core.API
|
||||
{
|
||||
app.UseMiddleware<RequestResponseLoggingMiddleware>();
|
||||
|
||||
// 从 DI 容器中获取 Parser 实例
|
||||
var uaParser = app.ApplicationServices.GetRequiredService<Parser>();
|
||||
|
||||
app.UseSerilogRequestLogging(opts
|
||||
=>
|
||||
{
|
||||
|
||||
opts.MessageTemplate = "{FullName} {UserType} {UserIp} {Host} {RequestMethod} {RequestPath} {RequestBody} responded {StatusCode} in {Elapsed:0.0000} ms";
|
||||
opts.MessageTemplate = "{FullName} {UserType} {UserIp} {Host} {RequestMethod} {RequestPath}{QueryString} {RequestBody} {OS} {Browser} {DeviceType} responded {StatusCode} in {Elapsed:0.0000} ms";
|
||||
|
||||
opts.EnrichDiagnosticContext = (diagnosticContext, httpContext) =>
|
||||
{
|
||||
@@ -33,10 +37,9 @@ namespace IRaCIS.Core.API
|
||||
|
||||
|
||||
// Only set it if available. You're not sending sensitive data in a querystring right?!
|
||||
if (request.QueryString.HasValue)
|
||||
{
|
||||
diagnosticContext.Set("QueryString", request.QueryString.Value);
|
||||
}
|
||||
|
||||
diagnosticContext.Set("QueryString", request.QueryString.Value ?? "");
|
||||
|
||||
|
||||
diagnosticContext.Set("FullName", httpContext?.User?.FindFirst(JwtIRaCISClaimType.FullName)?.Value);
|
||||
|
||||
@@ -52,6 +55,38 @@ namespace IRaCIS.Core.API
|
||||
|
||||
diagnosticContext.Set("UserIp", clientIp);
|
||||
|
||||
|
||||
// ==================== 新增:解析 User-Agent ====================
|
||||
try
|
||||
{
|
||||
var userAgent = httpContext.Request.Headers["User-Agent"].ToString();
|
||||
|
||||
if (!string.IsNullOrEmpty(userAgent))
|
||||
{
|
||||
var clientInfo = uaParser.Parse(userAgent);
|
||||
|
||||
diagnosticContext.Set("OS", clientInfo.OS.ToString());
|
||||
diagnosticContext.Set("Browser", clientInfo.UA.ToString());
|
||||
//diagnosticContext.Set("DeviceType", clientInfo.Device.ToString());
|
||||
diagnosticContext.Set("DeviceType", userAgent.Contains("Mobile") ? "Mobile": "Desktop");
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
diagnosticContext.Set("OS", "Unknown");
|
||||
diagnosticContext.Set("Browser", "Unknown");
|
||||
diagnosticContext.Set("DeviceType", "Unknown");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// 解析失败时记录异常,但不要影响主流程
|
||||
diagnosticContext.Set("OS", "ParseError");
|
||||
diagnosticContext.Set("Browser", "ParseError");
|
||||
diagnosticContext.Set("DeviceType", "ParseError");
|
||||
}
|
||||
// ==============================================================
|
||||
|
||||
#region 非必要不记录
|
||||
//diagnosticContext.Set("Protocol", request.Protocol);
|
||||
//diagnosticContext.Set("Scheme", request.Scheme);
|
||||
|
||||
@@ -46,19 +46,19 @@ namespace IRaCIS.Core.API
|
||||
var emailConfig = new SystemEmailSendConfig();
|
||||
configuration.GetSection("SystemEmailSendConfig").Bind(emailConfig);
|
||||
|
||||
if (emailConfig.IsOpenErrorNoticeEmail)
|
||||
{
|
||||
config.WriteTo.Email(options: new Serilog.Sinks.Email.EmailSinkOptions()
|
||||
{
|
||||
From = emailConfig.FromEmail,
|
||||
To = emailConfig.ErrorNoticeEmailList,
|
||||
Host = emailConfig.Host,
|
||||
Port = emailConfig.Port,
|
||||
Subject = new MessageTemplateTextFormatter("Log Alert - 系统发生了异常,请核查"),
|
||||
Credentials = new NetworkCredential(emailConfig.FromEmail, emailConfig.AuthorizationCode)
|
||||
//if (emailConfig.IsOpenErrorNoticeEmail)
|
||||
//{
|
||||
// config.WriteTo.Email(options: new Serilog.Sinks.Email.EmailSinkOptions()
|
||||
// {
|
||||
// From = emailConfig.FromEmail,
|
||||
// To = emailConfig.ErrorNoticeEmailList,
|
||||
// Host = emailConfig.Host,
|
||||
// Port = emailConfig.Port,
|
||||
// Subject = new MessageTemplateTextFormatter("Log Alert - 系统发生了异常,请核查"),
|
||||
// Credentials = new NetworkCredential(emailConfig.FromEmail, emailConfig.AuthorizationCode)
|
||||
|
||||
}, restrictedToMinimumLevel: Serilog.Events.LogEventLevel.Error);
|
||||
}
|
||||
// }, restrictedToMinimumLevel: Serilog.Events.LogEventLevel.Error);
|
||||
//}
|
||||
#endregion
|
||||
|
||||
Log.Logger = config.CreateLogger();
|
||||
|
||||
@@ -1,15 +1,7 @@
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using Microsoft.OpenApi;
|
||||
using Swashbuckle.AspNetCore.Filters;
|
||||
using Swashbuckle.AspNetCore.SwaggerGen;
|
||||
using Swashbuckle.AspNetCore.SwaggerUI;
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
namespace IRaCIS.Core.API;
|
||||
@@ -52,18 +44,21 @@ public static class SwaggerSetup
|
||||
services.AddSwaggerGen(options =>
|
||||
{
|
||||
|
||||
typeof(SwaggerVersion).GetFields(BindingFlags.Public | BindingFlags.Static).ToList()
|
||||
.ForEach(field =>
|
||||
{
|
||||
var description = field.GetCustomAttribute<DescriptionAttribute>()?.Description ?? field.Name;
|
||||
options.SwaggerDoc(field.Name, new Microsoft.OpenApi.Models.OpenApiInfo
|
||||
{
|
||||
Version = field.Name,
|
||||
Description = $"{field.Name} API",
|
||||
Title = description // 使用Description作为Title
|
||||
});
|
||||
});
|
||||
// 使用反射获取字段并动态创建 Swagger 文档
|
||||
typeof(SwaggerVersion).GetFields(BindingFlags.Public | BindingFlags.Static)
|
||||
.ToList()
|
||||
.ForEach(field =>
|
||||
{
|
||||
var description = field.GetCustomAttribute<DescriptionAttribute>()?.Description ?? field.Name;
|
||||
options.SwaggerDoc(field.Name, new OpenApiInfo
|
||||
{
|
||||
Version = field.Name,
|
||||
Description = $"{field.Name} API",
|
||||
Title = description // 使用 Description 作为 Title
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
// 接口排序
|
||||
options.OrderActionsBy(o => o.GroupName);
|
||||
|
||||
|
||||
@@ -7,8 +7,10 @@
|
||||
}
|
||||
},
|
||||
"ConnectionStrings": {
|
||||
"RemoteNew": "Server=101.132.253.119,1435;Database=irc_Prpd_bak;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
|
||||
"Hangfire": "Server=101.132.253.119,1435;Database=irc_Hangfire_bak;User ID=sa;Password=xc@123456;TrustServerCertificate=true"
|
||||
"RemoteNew": "Server=101.132.193.237,1433;Database=Prod_IRC_pidr_restore;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
|
||||
"Hangfire": "Server=101.132.193.237,1433;Database=irc_Hangfire_bak;User ID=sa;Password=xc@123456;TrustServerCertificate=true"
|
||||
//"RemoteNew": "Server=prod_mssql_standard,1433;Database=Prod_IRC;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true",
|
||||
//"Hangfire": "Server=prod_mssql_standard,1433;Database=Prod_IRC_Hangfire;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true"
|
||||
},
|
||||
"WeComNoticeConfig": {
|
||||
"IsOpenWeComNotice": true,
|
||||
@@ -17,48 +19,51 @@
|
||||
"VueNoticeUserList": [ "wangxiaoshuang", "6b7717a31647293621b97b96f74e6f3d" ]
|
||||
},
|
||||
"ObjectStoreService": {
|
||||
|
||||
"ObjectStoreUse": "AliyunOSS",
|
||||
|
||||
"IsOpenStoreSync": true,
|
||||
"ApiDeployRegion": "CN",
|
||||
"SyncConfigList": [
|
||||
{
|
||||
"Domain": "irc.extimaging.com",
|
||||
"Primary": "AliyunOSS",
|
||||
"Target": "AWS",
|
||||
"UploadRegion": "CN",
|
||||
"TargetRegion": "US",
|
||||
"IsOpenSync": true
|
||||
},
|
||||
{
|
||||
"Domain": "eiirc.extimaging.com",
|
||||
"Primary": "AWS",
|
||||
"Target": "AliyunOSS",
|
||||
"UploadRegion": "US",
|
||||
"TargetRegion": "CN",
|
||||
"IsOpenSync": true
|
||||
}
|
||||
],
|
||||
"AliyunOSS": {
|
||||
"RegionId": "cn-shanghai",
|
||||
"InternalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com",
|
||||
"EndPoint": "https://oss-cn-shanghai.aliyuncs.com",
|
||||
"AccessKeyId": "LTAI5tFUCCmz5TwghZHsj45Y",
|
||||
"AccessKeySecret": "8evrBy1fVfzJG25i67Jm0xqn9Xcw2T",
|
||||
"RoleArn": "acs:ram::1078130221702011:role/uat-oss-access",
|
||||
"BucketName": "tl-med-irc-event-store",
|
||||
"ViewEndpoint": "https://tl-med-irc-event-store.oss-cn-shanghai.aliyuncs.com",
|
||||
"AccessKeyId": "LTAI5tNRTsqL6aWmHkDmTwoH",
|
||||
"AccessKeySecret": "7mtGz3qrYWI6JMMBZiLeC119VWicZH",
|
||||
"RoleArn": "acs:ram::1899121822495495:role/irc-oss-access",
|
||||
"BucketName": "zy-irc-store",
|
||||
"ViewEndpoint": "https://zy-irc-cache.oss-cn-shanghai.aliyuncs.com",
|
||||
"Region": "oss-cn-shanghai",
|
||||
"DurationSeconds": 7200
|
||||
},
|
||||
|
||||
"MinIO": {
|
||||
"endPoint": "hir-oss.uat.extimaging.com",
|
||||
"port": "80",
|
||||
"useSSL": false,
|
||||
"viewEndpoint": "http://hir-oss.uat.extimaging.com/irc-uat",
|
||||
//"port": "443",
|
||||
//"useSSL": true,
|
||||
//"viewEndpoint": "https://hir-oss.uat.extimaging.com/irc-uat",
|
||||
"accessKey": "b9Ul0e98xPzt6PwRXA1Q",
|
||||
"secretKey": "DzMaU2L4OXl90uytwOmDXF2encN0Jf4Nxu2XkYqQ",
|
||||
"bucketName": "irc-uat"
|
||||
|
||||
},
|
||||
"AWS": {
|
||||
"Region": "us-east-1",
|
||||
"EndPoint": "s3.us-east-1.amazonaws.com",
|
||||
"UseSSL": true,
|
||||
"RoleArn": "arn:aws:iam::471112624751:role/sts_s3_upload",
|
||||
"AccessKeyId": "AKIAW3MEAFJXWRCGSX5Z",
|
||||
"SecretAccessKey": "miais4jQGSd37A+TfBEP11AQM5u/CvotSmznJd8k",
|
||||
"BucketName": "ei-med-s3-lili-uat-store",
|
||||
"ViewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com/",
|
||||
"RoleArn": "arn:aws:iam::471112624751:role/lili_s3_access",
|
||||
"AccessKeyId": "AKIAW3MEAFJXZ2TZK7GM",
|
||||
"SecretAccessKey": "9MLQCQ1HifEVW1gf068zBRAOb4wNnfrOkvBVByth",
|
||||
"BucketName": "ei-med-s3-irc-store",
|
||||
"ViewEndpoint": "https://ei-med-s3-irc-store.s3.amazonaws.com",
|
||||
"DurationSeconds": 7200
|
||||
}
|
||||
},
|
||||
|
||||
"BasicSystemConfig": {
|
||||
// 启用质控风险控制功能
|
||||
"QCRiskControl": true,
|
||||
@@ -67,7 +72,6 @@
|
||||
|
||||
"OpenLoginLimit": true,
|
||||
"LoginMaxFailCount": 5,
|
||||
|
||||
"LoginFailLockMinutes": 30,
|
||||
"AutoLoginOutMinutes": 120,
|
||||
|
||||
@@ -82,17 +86,17 @@
|
||||
"TemplateType": 2,
|
||||
//MFA免验证发送天数
|
||||
"UserMFAVerifyMinutes": 1440
|
||||
|
||||
},
|
||||
|
||||
"SystemEmailSendConfig": {
|
||||
"Port": 465,
|
||||
"Host": "smtp.qiye.aliyun.com",
|
||||
"Imap": "imap.qiye.aliyun.com",
|
||||
"ImapPort": 993,
|
||||
"FromEmail": "uat@extimaging.com",
|
||||
"FromName": "Uat IRC Imaging System",
|
||||
"AuthorizationCode": "SHzyyl2021",
|
||||
"SiteUrl": "http://irc.uat.extimaging.com/login",
|
||||
"FromEmail": "irc@extimaging.com",
|
||||
"FromName": "EIC Imaging System",
|
||||
"AuthorizationCode": "ExtImg@2022",
|
||||
"SiteUrl": "http://irc.event.extimaging.com/login",
|
||||
|
||||
"PlatformName": "EICS",
|
||||
"PlatformNameCN": "展影云平台",
|
||||
@@ -104,19 +108,16 @@
|
||||
"CompanyShortName": "Extensive Imaging",
|
||||
"CompanyShortNameCN": "展影医疗",
|
||||
"IsEnv_US": false,
|
||||
"IsOpenErrorNoticeEmail": false,
|
||||
"EmailRegexStr": "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$",
|
||||
"CronEmailDefaultCulture": "zh-CN",
|
||||
"ErrorNoticeEmailList": [ "872297557@qq.com" ]
|
||||
"CronEmailDefaultCulture": "zh-CN"
|
||||
},
|
||||
|
||||
"SystemPacsConfig": {
|
||||
"Port": "11116",
|
||||
"IP": "101.132.253.119"
|
||||
"Port": "11113",
|
||||
"IP": "101.132.193.237"
|
||||
},
|
||||
"RequestDuplicationOptions": {
|
||||
"IsEnabled": true,
|
||||
"DuplicationWindowMs": 200,
|
||||
"DuplicationWindowMs": 500,
|
||||
"CacheTimeSeconds": 5,
|
||||
"ExcludedPaths": [
|
||||
]
|
||||
|
||||
@@ -7,10 +7,10 @@
|
||||
}
|
||||
},
|
||||
"ConnectionStrings": {
|
||||
"RemoteNew": "Server=10.10.10.49,1434;Database=Prod_IRC;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true",
|
||||
"Hangfire": "Server=10.10.10.49,1434;Database=Prod_IRC_Hangfire;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true"
|
||||
//"RemoteNew": "Server=prod_mssql_standard,1433;Database=Prod_IRC;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true",
|
||||
//"Hangfire": "Server=prod_mssql_standard,1433;Database=Prod_IRC_Hangfire;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true"
|
||||
//"RemoteNew": "Server=10.10.10.49,1434;Database=Prod_IRC;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true",
|
||||
//"Hangfire": "Server=10.10.10.49,1434;Database=Prod_IRC_Hangfire;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true"
|
||||
"RemoteNew": "Server=prod_mssql_standard,1433;Database=Prod_IRC;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true",
|
||||
"Hangfire": "Server=prod_mssql_standard,1433;Database=Prod_IRC_Hangfire;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true"
|
||||
},
|
||||
"WeComNoticeConfig": {
|
||||
"IsOpenWeComNotice": true,
|
||||
@@ -20,6 +20,26 @@
|
||||
},
|
||||
"ObjectStoreService": {
|
||||
"ObjectStoreUse": "AliyunOSS",
|
||||
"IsOpenStoreSync": true,
|
||||
"ApiDeployRegion": "CN",
|
||||
"SyncConfigList": [
|
||||
{
|
||||
"Domain": "irc.extimaging.com",
|
||||
"Primary": "AliyunOSS",
|
||||
"Target": "AWS",
|
||||
"UploadRegion": "CN",
|
||||
"TargetRegion": "US",
|
||||
"IsOpenSync": true
|
||||
},
|
||||
{
|
||||
"Domain": "eiirc.extimaging.com",
|
||||
"Primary": "AWS",
|
||||
"Target": "AliyunOSS",
|
||||
"UploadRegion": "US",
|
||||
"TargetRegion": "CN",
|
||||
"IsOpenSync": true
|
||||
}
|
||||
],
|
||||
"AliyunOSS": {
|
||||
"RegionId": "cn-shanghai",
|
||||
"InternalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com",
|
||||
@@ -32,13 +52,16 @@
|
||||
"Region": "oss-cn-shanghai",
|
||||
"DurationSeconds": 7200
|
||||
},
|
||||
"MinIO": {
|
||||
"endpoint": "http://192.168.3.68",
|
||||
"port": "8001",
|
||||
"useSSL": false,
|
||||
"accessKey": "IDFkwEpWej0b4DtiuThL",
|
||||
"secretKey": "Lhuu83yMhVwu7c1SnjvGY6lq74jzpYqifK6Qtj4h",
|
||||
"bucketName": "test"
|
||||
"AWS": {
|
||||
"Region": "us-east-1",
|
||||
"EndPoint": "s3.us-east-1.amazonaws.com",
|
||||
"UseSSL": true,
|
||||
"RoleArn": "arn:aws:iam::471112624751:role/lili_s3_access",
|
||||
"AccessKeyId": "AKIAW3MEAFJXZ2TZK7GM",
|
||||
"SecretAccessKey": "9MLQCQ1HifEVW1gf068zBRAOb4wNnfrOkvBVByth",
|
||||
"BucketName": "ei-med-s3-irc-store",
|
||||
"ViewEndpoint": "https://ei-med-s3-irc-store.s3.amazonaws.com",
|
||||
"DurationSeconds": 7200
|
||||
}
|
||||
},
|
||||
"BasicSystemConfig": {
|
||||
@@ -71,7 +94,7 @@
|
||||
"Imap": "imap.qiye.aliyun.com",
|
||||
"ImapPort": 993,
|
||||
"FromEmail": "irc@extimaging.com",
|
||||
"FromName": "IRC Imaging System",
|
||||
"FromName": "EIC Imaging System",
|
||||
"AuthorizationCode": "ExtImg@2022",
|
||||
"SiteUrl": "http://irc.extimaging.com/login",
|
||||
|
||||
@@ -85,10 +108,8 @@
|
||||
"CompanyShortName": "Extensive Imaging",
|
||||
"CompanyShortNameCN": "展影医疗",
|
||||
"IsEnv_US": false,
|
||||
"IsOpenErrorNoticeEmail": false,
|
||||
"EmailRegexStr": "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$",
|
||||
"CronEmailDefaultCulture": "zh-CN",
|
||||
"ErrorNoticeEmailList": [ "872297557@qq.com" ]
|
||||
"CronEmailDefaultCulture": "zh-CN"
|
||||
},
|
||||
"SystemPacsConfig": {
|
||||
"Port": "11113",
|
||||
@@ -96,7 +117,7 @@
|
||||
},
|
||||
"RequestDuplicationOptions": {
|
||||
"IsEnabled": true,
|
||||
"DuplicationWindowMs": 200,
|
||||
"DuplicationWindowMs": 500,
|
||||
"CacheTimeSeconds": 5,
|
||||
"ExcludedPaths": [
|
||||
]
|
||||
|
||||
@@ -0,0 +1,143 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft": "Warning",
|
||||
"Microsoft.Hosting.Lifetime": "Information"
|
||||
}
|
||||
},
|
||||
"ConnectionStrings": {
|
||||
"RemoteNew": "Server=prod_mssql_standard,1433;Database=Prod_Rayplus;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true",
|
||||
"Hangfire": "Server=prod_mssql_standard,1433;Database=Prod_Rayplus_Hangfire;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true"
|
||||
},
|
||||
"WeComNoticeConfig": {
|
||||
"IsOpenWeComNotice": true,
|
||||
"WebhookUrl": "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=4355b98e-1e72-4678-8dfb-2fc6ad0bf449", //4355b98e-1e72-4678-8dfb-2fc6ad0bf449 //cdd97aab-d256-4f07-9145-a0a2b1555322
|
||||
"APINoticeUserList": [ "u", "wait..." ],
|
||||
"VueNoticeUserList": [ "wangxiaoshuang", "6b7717a31647293621b97b96f74e6f3d" ]
|
||||
},
|
||||
"ObjectStoreService": {
|
||||
|
||||
"ObjectStoreUse": "AliyunOSS",
|
||||
"IsOpenStoreSync": true,
|
||||
"ApiDeployRegion": "CN",
|
||||
"SyncConfigList": [
|
||||
{
|
||||
"Domain": "irc.uat.rayplus.net",
|
||||
"Primary": "AliyunOSS",
|
||||
"Target": "AWS",
|
||||
"UploadRegion": "CN",
|
||||
"TargetRegion": "US",
|
||||
"IsOpenSync": false
|
||||
},
|
||||
{
|
||||
"Domain": "lili.uat.extimaging.com",
|
||||
"Primary": "AWS",
|
||||
"Target": "AliyunOSS",
|
||||
"UploadRegion": "US",
|
||||
"TargetRegion": "CN",
|
||||
"IsOpenSync": false
|
||||
}
|
||||
],
|
||||
|
||||
"AliyunOSS": {
|
||||
"RegionId": "cn-shanghai",
|
||||
"InternalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com",
|
||||
"EndPoint": "https://oss-cn-shanghai.aliyuncs.com",
|
||||
"AccessKeyId": "LTAI5tNRTsqL6aWmHkDmTwoH",
|
||||
"AccessKeySecret": "7mtGz3qrYWI6JMMBZiLeC119VWicZH",
|
||||
"RoleArn": "acs:ram::1899121822495495:role/irc-oss-access",
|
||||
"BucketName": "rayplus-irc-store",
|
||||
"ViewEndpoint": "https://rayplus-irc-store.oss-cn-shanghai.aliyuncs.com",
|
||||
"Region": "oss-cn-shanghai",
|
||||
"DurationSeconds": 7200
|
||||
},
|
||||
|
||||
"MinIO": {
|
||||
"endPoint": "hir-oss.uat.extimaging.com",
|
||||
"port": "80",
|
||||
"useSSL": false,
|
||||
"viewEndpoint": "http://hir-oss.uat.extimaging.com/irc-uat",
|
||||
//"port": "443",
|
||||
//"useSSL": true,
|
||||
//"viewEndpoint": "https://hir-oss.uat.extimaging.com/irc-uat",
|
||||
"accessKey": "b9Ul0e98xPzt6PwRXA1Q",
|
||||
"secretKey": "DzMaU2L4OXl90uytwOmDXF2encN0Jf4Nxu2XkYqQ",
|
||||
"bucketName": "irc-uat"
|
||||
|
||||
},
|
||||
"AWS": {
|
||||
"Region": "us-east-1",
|
||||
"EndPoint": "s3.us-east-1.amazonaws.com",
|
||||
"UseSSL": true,
|
||||
"RoleArn": "arn:aws:iam::471112624751:role/uat_s3_access",
|
||||
"AccessKeyId": "AKIAW3MEAFJX7IPXISP4",
|
||||
"SecretAccessKey": "Pgrg3le5jPxZQ7MR1yYNS30J0XRyJeKVyIIjElXc",
|
||||
"BucketName": "ei-med-s3-lili-uat-store",
|
||||
"ViewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com/",
|
||||
"DurationSeconds": 7200
|
||||
}
|
||||
},
|
||||
|
||||
"BasicSystemConfig": {
|
||||
// 启用质控风险控制功能
|
||||
"QCRiskControl": true,
|
||||
"OpenUserComplexPassword": true,
|
||||
"OpenSignDocumentBeforeWork": true,
|
||||
|
||||
"OpenLoginLimit": true,
|
||||
"LoginMaxFailCount": 5,
|
||||
|
||||
"LoginFailLockMinutes": 30,
|
||||
"AutoLoginOutMinutes": 120,
|
||||
|
||||
"OpenLoginMFA": false,
|
||||
|
||||
"ContinuousReadingTimeMin": 120,
|
||||
"ReadingRestTimeMin": 10,
|
||||
|
||||
"IsNeedChangePassWord": true,
|
||||
"ChangePassWordDays": 90,
|
||||
// 模板类型 1 Elevate 2 Extensive
|
||||
"TemplateType": 2,
|
||||
//MFA免验证发送天数
|
||||
"UserMFAVerifyMinutes": 1440
|
||||
|
||||
},
|
||||
"SystemEmailSendConfig": {
|
||||
"Port": 465,
|
||||
"Host": "smtp.qiye.aliyun.com",
|
||||
"Imap": "imap.qiye.aliyun.com",
|
||||
"ImapPort": 993,
|
||||
"FromEmail": "irc@mail.rayplus.net",
|
||||
"FromName": "RayPlus Imaging System",
|
||||
"AuthorizationCode": "QWE1zxcv7632",
|
||||
"SiteUrl": "https://irc.rayplus.net/login",
|
||||
|
||||
"PlatformName": "RayPlus",
|
||||
"PlatformNameCN": "睿佳影像云平台",
|
||||
"SystemShortName": "RayPlus",
|
||||
"OrganizationName": "RayPlus",
|
||||
"OrganizationNameCN": "RayPlus",
|
||||
"CompanyName": "RayPlus",
|
||||
"CompanyNameCN": "睿佳(武汉)软件科技有限公司",
|
||||
"CompanyShortName": "RayPlus",
|
||||
"CompanyShortNameCN": "睿佳",
|
||||
"IsEnv_US": false,
|
||||
"EmailRegexStr": "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$",
|
||||
"CronEmailDefaultCulture": "zh-CN"
|
||||
},
|
||||
|
||||
"SystemPacsConfig": {
|
||||
"Port": "11113",
|
||||
"IP": "47.117.165.18"
|
||||
},
|
||||
"RequestDuplicationOptions": {
|
||||
"IsEnabled": true,
|
||||
"DuplicationWindowMs": 200,
|
||||
"CacheTimeSeconds": 5,
|
||||
"ExcludedPaths": [
|
||||
]
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,32 +1,28 @@
|
||||
{
|
||||
// 日志信息
|
||||
"Logging": {
|
||||
// 日志等级
|
||||
"LogLevel": {
|
||||
// 默认日志等级
|
||||
"Default": "Information",
|
||||
// 调试日志等级
|
||||
"Microsoft": "Warning",
|
||||
// ASP.NET Core 日志等级
|
||||
"Microsoft.Hosting.Lifetime": "Information"
|
||||
}
|
||||
},
|
||||
// 数据库链接字符串
|
||||
"ConnectionStrings": {
|
||||
// 本地数据库链接字符串
|
||||
"RemoteNew": "Server=106.14.89.110,1435;Database=Test_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
|
||||
// Hangfire 定时任务数据库链接字符串
|
||||
"Hangfire": "Server=106.14.89.110,1435;Database=Test_IRC_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true"
|
||||
},
|
||||
"WeComNoticeConfig": {
|
||||
"IsOpenWeComNotice": true,
|
||||
"WebhookUrl": "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=4355b98e-1e72-4678-8dfb-2fc6ad0bf449", //4355b98e-1e72-4678-8dfb-2fc6ad0bf449 //cdd97aab-d256-4f07-9145-a0a2b1555322
|
||||
"APINoticeUserList": [ "u", "wait..." ],
|
||||
"VueNoticeUserList": [ "wangxiaoshuang", "6b7717a31647293621b97b96f74e6f3d" ]
|
||||
"WebhookUrl": "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=4355b98e-1e72-4678-8dfb-2fc6ad0bf449",
|
||||
"APINoticeUserList": [
|
||||
"u",
|
||||
"wait..."
|
||||
],
|
||||
"VueNoticeUserList": [
|
||||
"wangxiaoshuang",
|
||||
"6b7717a31647293621b97b96f74e6f3d"
|
||||
]
|
||||
},
|
||||
// 对象存储服务配置
|
||||
"ObjectStoreService": {
|
||||
// 使用的对象存储服务类型
|
||||
"ObjectStoreUse": "AliyunOSS",
|
||||
"IsOpenStoreSync": true,
|
||||
"ApiDeployRegion": "CN",
|
||||
@@ -48,166 +44,89 @@
|
||||
"IsOpenSync": true
|
||||
}
|
||||
],
|
||||
// 阿里云对象存储服务的配置
|
||||
"AliyunOSS": {
|
||||
// 阿里云 OSS 的 Region ID
|
||||
"RegionId": "cn-shanghai",
|
||||
// 阿里云 OSS 的内部访问端点
|
||||
"InternalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com",
|
||||
// 阿里云 OSS 的外部访问端点
|
||||
"EndPoint": "https://oss-cn-shanghai.aliyuncs.com",
|
||||
// 阿里云 OSS 的访问密钥 ID
|
||||
"AccessKeyId": "LTAI5tRRZehUp2V9pyTPtAJm",
|
||||
// 阿里云 OSS 的访问密钥 Secret
|
||||
"AccessKeySecret": "FLizxkHsMm4CGYHtkV8E3PNJJZU7oV",
|
||||
// 阿里云 OSS 的角色 ARN
|
||||
"RoleArn": "acs:ram::1899121822495495:role/dev-oss-access",
|
||||
// 阿里云 OSS 的Bucket名称
|
||||
"BucketName": "zy-irc-test-store",
|
||||
// 阿里云 OSS 的访问端点
|
||||
"ViewEndpoint": "https://zy-irc-test-dev-cache.oss-cn-shanghai.aliyuncs.com",
|
||||
// 阿里云 OSS 的预览端点
|
||||
"Region": "oss-cn-shanghai",
|
||||
// 阿里云 OSS 的临时访问凭证有效时间(秒)
|
||||
"DurationSeconds": 7200,
|
||||
// 阿里云 OSS 的预览端点
|
||||
"PreviewEndpoint": "https://test-oss.test.extimaging.com"
|
||||
},
|
||||
// MinIO 对象存储服务的配置
|
||||
"MinIO": {
|
||||
// MinIO 的访问端点
|
||||
"EndPoint": "hir-oss.test.extimaging.com",
|
||||
// MinIO 的端口
|
||||
"Port": "443",
|
||||
// 是否使用 SSL
|
||||
"UseSSL": true,
|
||||
// MinIO 的角色 ARN
|
||||
"AccessKey": "fbStsVYCIPKHQneeqMwD",
|
||||
// MinIO 的访问密钥
|
||||
"SecretKey": "TzgvyA3zGXMUnpilJNUlyMYHfosl1hBMl6lxPmjy",
|
||||
// MinIO 的BucketName
|
||||
"BucketName": "irc-test",
|
||||
// MinIO 的访问端点
|
||||
"ViewEndpoint": "https://hir-oss.test.extimaging.com/irc-test"
|
||||
},
|
||||
// AWS S3 对象存储服务的配置
|
||||
"AWS": {
|
||||
// AWS S3 的Region
|
||||
"Region": "us-east-1",
|
||||
// AWS S3 的内部访问端点
|
||||
"EndPoint": "s3.us-east-1.amazonaws.com",
|
||||
// 是否使用 SSL
|
||||
"UseSSL": true,
|
||||
// AWS S3 的角色 ARN
|
||||
"RoleArn": "arn:aws:iam::471112624751:role/uat_s3_access",
|
||||
// AWS S3 的访问密钥 ID
|
||||
"AccessKeyId": "AKIAW3MEAFJX7IPXISP4",
|
||||
// AWS S3 的访问密钥 Secret
|
||||
"SecretAccessKey": "Pgrg3le5jPxZQ7MR1yYNS30J0XRyJeKVyIIjElXc",
|
||||
// AWS S3 的Bucket名称
|
||||
"BucketName": "ei-med-s3-lili-uat-store",
|
||||
// AWS S3 的访问端点
|
||||
"ViewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com",
|
||||
// AWS S3 的持续数秒
|
||||
"DurationSeconds": 7200
|
||||
}
|
||||
},
|
||||
// 系统配置
|
||||
"BasicSystemConfig": {
|
||||
// 启用质控风险控制功能
|
||||
"QCRiskControl": true,
|
||||
// 打开用户复杂密码
|
||||
"OpenUserComplexPassword": false,
|
||||
// 是否在开始工作前强制签署电子知情同意书
|
||||
"OpenSignDocumentBeforeWork": false,
|
||||
// 是否启用登录失败次数限制(防暴力破解)
|
||||
"OpenLoginLimit": false,
|
||||
// 连续登录失败多少次后触发锁定
|
||||
"LoginMaxFailCount": 5,
|
||||
// 触发锁定后账号锁定时长(分钟)
|
||||
"LoginFailLockMinutes": 1,
|
||||
// 无操作自动登出的超时时间(分钟)
|
||||
"AutoLoginOutMinutes": 10,
|
||||
// 是否启用多因子登录认证(MFA)
|
||||
"OpenLoginMFA": false,
|
||||
// 连续阅片的最长工作时间(分钟),超时后强制休息
|
||||
"ContinuousReadingTimeMin": 120,
|
||||
// 强制休息时长(分钟)
|
||||
"ReadingRestTimeMin": 10,
|
||||
// 是否强制用户定期修改密码
|
||||
"IsNeedChangePassWord": true,
|
||||
// 密码有效期(天),到期后必须修改
|
||||
"ChangePassWordDays": 90,
|
||||
// 模板类型 1 Elevate(LiLi) 2 Extensive(展影)
|
||||
"TemplateType": 2,
|
||||
// 是否打开项目关联删除
|
||||
"OpenTrialRelationDelete": true,
|
||||
// 转换PDF服务配置
|
||||
"OpenTrialRelationDelete": false,
|
||||
"ThirdPdfUrl": "http://106.14.89.110:30088/api/v1/convert/file/pdf",
|
||||
//MFA免验证发送天数
|
||||
"UserMFAVerifyMinutes": 1440
|
||||
},
|
||||
// 邮件服务配置(用于系统通知、找回密码、错误报警等)
|
||||
"SystemEmailSendConfig": {
|
||||
// SMTP端口
|
||||
"Port": 465,
|
||||
// 企业邮箱SMTP服务器地址
|
||||
"Host": "smtp.qiye.aliyun.com",
|
||||
|
||||
"Port": 465,
|
||||
"Imap": "imap.qiye.aliyun.com",
|
||||
|
||||
"ImapPort": 993,
|
||||
// 发件人邮箱地址
|
||||
"FromEmail": "test@extimaging.com",
|
||||
// 发件人显示名称
|
||||
"FromName": "Test IRC Imaging System",
|
||||
// SMTP授权码
|
||||
"FromName": "Test EIC Imaging System",
|
||||
"AuthorizationCode": "SHzyyl2021",
|
||||
// 系统对外访问地址
|
||||
"SiteUrl": "http://irc.test.extimaging.com/login",
|
||||
|
||||
"SystemShortName": "IRC",
|
||||
"OrganizationName": "ExtImaging",
|
||||
"OrganizationNameCN": "ExtImaging",
|
||||
"PlatformName": "EICS",
|
||||
"PlatformNameCN": "展影云平台",
|
||||
// 系统简称一致性核查使用
|
||||
"SystemShortName": "IRC",
|
||||
// 组织英文名称
|
||||
"OrganizationName": "ExtImaging",
|
||||
// 组织中文名称
|
||||
"OrganizationNameCN": "ExtImaging",
|
||||
// 公司英文全称
|
||||
"CompanyName": "Extensive Imaging",
|
||||
// 公司中文全称
|
||||
"CompanyNameCN": "上海展影医疗科技有限公司",
|
||||
// 公司英文简称
|
||||
"CompanyShortName": "Extensive Imaging",
|
||||
// 公司中文简称
|
||||
"CompanyShortNameCN": "展影医疗",
|
||||
// 是否为国际版环境
|
||||
"IsEnv_US": false,
|
||||
// 是否开启系统异常邮件报警
|
||||
"IsOpenErrorNoticeEmail": false,
|
||||
// 邮箱格式校验正则表达式
|
||||
"EmailRegexStr": "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$",
|
||||
"CronEmailDefaultCulture": "zh-CN",
|
||||
// 接收系统异常报警的邮箱列表
|
||||
"ErrorNoticeEmailList": [ "872297557@qq.com" ]
|
||||
"CronEmailDefaultCulture": "zh-CN"
|
||||
},
|
||||
// PACS 连接配置
|
||||
"SystemPacsConfig": {
|
||||
// PACS服务器端口
|
||||
"Port": "11113",
|
||||
// PACS服务器IP地址
|
||||
"IP": "106.14.89.110"
|
||||
},
|
||||
// 重复请求配置
|
||||
"RequestDuplicationOptions": {
|
||||
// 是否启用重复请求检测
|
||||
"IsEnabled": true,
|
||||
// 重复请求时间窗口(毫秒)
|
||||
"DuplicationWindowMs": 200,
|
||||
// 缓存请求时间(秒)
|
||||
"DuplicationWindowMs": 500,
|
||||
"CacheTimeSeconds": 5,
|
||||
"ExcludedPaths": [
|
||||
]
|
||||
}
|
||||
}
|
||||
"ExcludedPaths": []
|
||||
},
|
||||
"FrontWebConfig": "222"
|
||||
}
|
||||
@@ -97,7 +97,7 @@
|
||||
},
|
||||
"RequestDuplicationOptions": {
|
||||
"IsEnabled": true,
|
||||
"DuplicationWindowMs": 200,
|
||||
"DuplicationWindowMs": 500,
|
||||
"CacheTimeSeconds": 5,
|
||||
"ExcludedPaths": [
|
||||
]
|
||||
|
||||
@@ -0,0 +1,143 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft": "Warning",
|
||||
"Microsoft.Hosting.Lifetime": "Information"
|
||||
}
|
||||
},
|
||||
"ConnectionStrings": {
|
||||
"RemoteNew": "Server=106.14.89.110,1435;Database=Test_Rayplus;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
|
||||
"Hangfire": "Server=106.14.89.110,1435;Database=Test_Rayplus_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true"
|
||||
},
|
||||
"WeComNoticeConfig": {
|
||||
"IsOpenWeComNotice": true,
|
||||
"WebhookUrl": "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=4355b98e-1e72-4678-8dfb-2fc6ad0bf449", //4355b98e-1e72-4678-8dfb-2fc6ad0bf449 //cdd97aab-d256-4f07-9145-a0a2b1555322
|
||||
"APINoticeUserList": [ "u", "wait..." ],
|
||||
"VueNoticeUserList": [ "wangxiaoshuang", "6b7717a31647293621b97b96f74e6f3d" ]
|
||||
},
|
||||
"ObjectStoreService": {
|
||||
|
||||
"ObjectStoreUse": "AliyunOSS",
|
||||
"IsOpenStoreSync": true,
|
||||
"ApiDeployRegion": "CN",
|
||||
"SyncConfigList": [
|
||||
{
|
||||
"Domain": "irc.test.rayplus.net",
|
||||
"Primary": "AliyunOSS",
|
||||
"Target": "AWS",
|
||||
"UploadRegion": "CN",
|
||||
"TargetRegion": "US",
|
||||
"IsOpenSync": false
|
||||
},
|
||||
{
|
||||
"Domain": "lili.uat.extimaging.com",
|
||||
"Primary": "AWS",
|
||||
"Target": "AliyunOSS",
|
||||
"UploadRegion": "US",
|
||||
"TargetRegion": "CN",
|
||||
"IsOpenSync": false
|
||||
}
|
||||
],
|
||||
|
||||
"AliyunOSS": {
|
||||
"RegionId": "cn-shanghai",
|
||||
"InternalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com",
|
||||
"EndPoint": "https://oss-cn-shanghai.aliyuncs.com",
|
||||
"AccessKeyId": "LTAI5tRRZehUp2V9pyTPtAJm",
|
||||
"AccessKeySecret": "FLizxkHsMm4CGYHtkV8E3PNJJZU7oV",
|
||||
"RoleArn": "acs:ram::1899121822495495:role/dev-oss-access",
|
||||
"BucketName": "rayplus-irc-test-store",
|
||||
"ViewEndpoint": "https://rayplus-irc-test-store.oss-cn-shanghai.aliyuncs.com",
|
||||
"Region": "oss-cn-shanghai",
|
||||
"DurationSeconds": 7200
|
||||
},
|
||||
|
||||
"MinIO": {
|
||||
"endPoint": "hir-oss.uat.extimaging.com",
|
||||
"port": "80",
|
||||
"useSSL": false,
|
||||
"viewEndpoint": "http://hir-oss.uat.extimaging.com/irc-uat",
|
||||
//"port": "443",
|
||||
//"useSSL": true,
|
||||
//"viewEndpoint": "https://hir-oss.uat.extimaging.com/irc-uat",
|
||||
"accessKey": "b9Ul0e98xPzt6PwRXA1Q",
|
||||
"secretKey": "DzMaU2L4OXl90uytwOmDXF2encN0Jf4Nxu2XkYqQ",
|
||||
"bucketName": "irc-uat"
|
||||
|
||||
},
|
||||
"AWS": {
|
||||
"Region": "us-east-1",
|
||||
"EndPoint": "s3.us-east-1.amazonaws.com",
|
||||
"UseSSL": true,
|
||||
"RoleArn": "arn:aws:iam::471112624751:role/uat_s3_access",
|
||||
"AccessKeyId": "AKIAW3MEAFJX7IPXISP4",
|
||||
"SecretAccessKey": "Pgrg3le5jPxZQ7MR1yYNS30J0XRyJeKVyIIjElXc",
|
||||
"BucketName": "ei-med-s3-lili-uat-store",
|
||||
"ViewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com/",
|
||||
"DurationSeconds": 7200
|
||||
}
|
||||
},
|
||||
|
||||
"BasicSystemConfig": {
|
||||
// 启用质控风险控制功能
|
||||
"QCRiskControl": true,
|
||||
"OpenUserComplexPassword": true,
|
||||
"OpenSignDocumentBeforeWork": true,
|
||||
|
||||
"OpenLoginLimit": true,
|
||||
"LoginMaxFailCount": 5,
|
||||
|
||||
"LoginFailLockMinutes": 30,
|
||||
"AutoLoginOutMinutes": 120,
|
||||
|
||||
"OpenLoginMFA": false,
|
||||
|
||||
"ContinuousReadingTimeMin": 120,
|
||||
"ReadingRestTimeMin": 10,
|
||||
|
||||
"IsNeedChangePassWord": true,
|
||||
"ChangePassWordDays": 90,
|
||||
// 模板类型 1 Elevate 2 Extensive
|
||||
"TemplateType": 2,
|
||||
//MFA免验证发送天数
|
||||
"UserMFAVerifyMinutes": 1440
|
||||
|
||||
},
|
||||
"SystemEmailSendConfig": {
|
||||
"Port": 465,
|
||||
"Host": "smtp.qiye.aliyun.com",
|
||||
"Imap": "imap.qiye.aliyun.com",
|
||||
"ImapPort": 993,
|
||||
"FromEmail": "test_irc@mail.rayplus.net",
|
||||
"FromName": "Test RayPlus Imaging System",
|
||||
"AuthorizationCode": "QWE1zxcv7632",
|
||||
"SiteUrl": "https://irc.test.rayplus.net/login",
|
||||
|
||||
"PlatformName": "RayPlus",
|
||||
"PlatformNameCN": "睿佳影像云平台",
|
||||
"SystemShortName": "RayPlus",
|
||||
"OrganizationName": "RayPlus",
|
||||
"OrganizationNameCN": "RayPlus",
|
||||
"CompanyName": "RayPlus",
|
||||
"CompanyNameCN": "睿佳(武汉)软件科技有限公司",
|
||||
"CompanyShortName": "RayPlus",
|
||||
"CompanyShortNameCN": "睿佳",
|
||||
"IsEnv_US": false,
|
||||
"EmailRegexStr": "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$",
|
||||
"CronEmailDefaultCulture": "zh-CN"
|
||||
},
|
||||
|
||||
"SystemPacsConfig": {
|
||||
"Port": "11113",
|
||||
"IP": "101.132.253.119"
|
||||
},
|
||||
"RequestDuplicationOptions": {
|
||||
"IsEnabled": true,
|
||||
"DuplicationWindowMs": 200,
|
||||
"CacheTimeSeconds": 5,
|
||||
"ExcludedPaths": [
|
||||
]
|
||||
}
|
||||
|
||||
}
|
||||
@@ -20,16 +20,38 @@
|
||||
},
|
||||
"ObjectStoreService": {
|
||||
"ObjectStoreUse": "AWS",
|
||||
"MinIO": {
|
||||
"endPoint": "44.210.231.169",
|
||||
"port": "9001",
|
||||
"useSSL": false,
|
||||
"accessKey": "e9bT1isTOqSAUxb6wd4n",
|
||||
"secretKey": "b5TaDzNdQCBtCvfm8eZ3dR6yY7tfZu2JYze2Po1i",
|
||||
"bucketName": "prod-irc-us",
|
||||
"viewEndpoint": "http://44.210.231.169:9001/prod-irc-us/"
|
||||
"IsOpenStoreSync": true,
|
||||
"ApiDeployRegion": "US",
|
||||
"SyncConfigList": [
|
||||
{
|
||||
"Domain": "eilili.elevateimaging.ai",
|
||||
"Primary": "AliyunOSS",
|
||||
"Target": "AWS",
|
||||
"UploadRegion": "CN",
|
||||
"TargetRegion": "US",
|
||||
"IsOpenSync": true
|
||||
},
|
||||
{
|
||||
"Domain": "lili.elevateimaging.ai",
|
||||
"Primary": "AWS",
|
||||
"Target": "AliyunOSS",
|
||||
"UploadRegion": "US",
|
||||
"TargetRegion": "CN",
|
||||
"IsOpenSync": true
|
||||
}
|
||||
],
|
||||
"AliyunOSS": {
|
||||
"RegionId": "cn-shanghai",
|
||||
"InternalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com",
|
||||
"EndPoint": "https://oss-cn-shanghai.aliyuncs.com",
|
||||
"AccessKeyId": "LTAI5tNRTsqL6aWmHkDmTwoH",
|
||||
"AccessKeySecret": "7mtGz3qrYWI6JMMBZiLeC119VWicZH",
|
||||
"RoleArn": "acs:ram::1899121822495495:role/irc-oss-access",
|
||||
"BucketName": "zy-lili-store",
|
||||
"ViewEndpoint": "https://zy-lili-cache.oss-cn-shanghai.aliyuncs.com",
|
||||
"Region": "oss-cn-shanghai",
|
||||
"DurationSeconds": 7200
|
||||
},
|
||||
|
||||
"AWS": {
|
||||
"Region": "us-east-1",
|
||||
"EndPoint": "s3.us-east-1.amazonaws.com",
|
||||
@@ -90,10 +112,8 @@
|
||||
"CompanyShortNameCN": "展影医疗",
|
||||
"SiteUrl": "https://lili.elevateimaging.ai/login",
|
||||
"IsEnv_US": true,
|
||||
"IsOpenErrorNoticeEmail": false,
|
||||
"EmailRegexStr": "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$",
|
||||
"CronEmailDefaultCulture": "en-US",
|
||||
"ErrorNoticeEmailList": [ "872297557@qq.com" ]
|
||||
"CronEmailDefaultCulture": "en-US"
|
||||
},
|
||||
|
||||
"SystemPacsConfig": {
|
||||
@@ -102,7 +122,7 @@
|
||||
},
|
||||
"RequestDuplicationOptions": {
|
||||
"IsEnabled": true,
|
||||
"DuplicationWindowMs": 200,
|
||||
"DuplicationWindowMs": 500,
|
||||
"CacheTimeSeconds": 5,
|
||||
"ExcludedPaths": [
|
||||
]
|
||||
|
||||
@@ -93,9 +93,7 @@
|
||||
"CompanyShortName": "Elevate Imaging",
|
||||
"CompanyShortNameCN": "展影医疗",
|
||||
"SiteUrl": "https://lili.test.elevateimaging.ai/login",
|
||||
"IsEnv_US": true,
|
||||
"IsOpenErrorNoticeEmail": false,
|
||||
"ErrorNoticeEmailList": [ "872297557@qq.com" ]
|
||||
"IsEnv_US": true
|
||||
},
|
||||
|
||||
"SystemPacsConfig": {
|
||||
@@ -104,7 +102,7 @@
|
||||
},
|
||||
"RequestDuplicationOptions": {
|
||||
"IsEnabled": true,
|
||||
"DuplicationWindowMs": 200,
|
||||
"DuplicationWindowMs": 500,
|
||||
"CacheTimeSeconds": 5,
|
||||
"ExcludedPaths": [
|
||||
]
|
||||
|
||||
@@ -97,10 +97,8 @@
|
||||
"CompanyShortNameCN": "展影医疗",
|
||||
"SiteUrl": "https://lili.uat.elevateimaging.ai/login",
|
||||
"IsEnv_US": true,
|
||||
"IsOpenErrorNoticeEmail": false,
|
||||
"EmailRegexStr": "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$",
|
||||
"CronEmailDefaultCulture": "en-US",
|
||||
"ErrorNoticeEmailList": [ "872297557@qq.com" ]
|
||||
"CronEmailDefaultCulture": "en-US"
|
||||
},
|
||||
|
||||
"SystemPacsConfig": {
|
||||
@@ -109,7 +107,7 @@
|
||||
},
|
||||
"RequestDuplicationOptions": {
|
||||
"IsEnabled": true,
|
||||
"DuplicationWindowMs": 200,
|
||||
"DuplicationWindowMs": 500,
|
||||
"CacheTimeSeconds": 5,
|
||||
"ExcludedPaths": [
|
||||
]
|
||||
|
||||
@@ -0,0 +1,152 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft": "Warning",
|
||||
"Microsoft.Hosting.Lifetime": "Information"
|
||||
}
|
||||
},
|
||||
"ConnectionStrings": {
|
||||
"RemoteNew": "Server=101.132.253.119,1435;Database=Uat_HeAnShu;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
|
||||
"Hangfire": "Server=101.132.253.119,1435;Database=Uat_HeAnShu_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true"
|
||||
},
|
||||
"WeComNoticeConfig": {
|
||||
"IsOpenWeComNotice": true,
|
||||
"WebhookUrl": "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=4355b98e-1e72-4678-8dfb-2fc6ad0bf449", //4355b98e-1e72-4678-8dfb-2fc6ad0bf449 //cdd97aab-d256-4f07-9145-a0a2b1555322
|
||||
"APINoticeUserList": [ "u", "wait..." ],
|
||||
"VueNoticeUserList": [ "wangxiaoshuang", "6b7717a31647293621b97b96f74e6f3d" ]
|
||||
},
|
||||
"ObjectStoreService": {
|
||||
|
||||
"ObjectStoreUse": "AliyunOSS",
|
||||
"IsOpenStoreSync": true,
|
||||
"ApiDeployRegion": "CN",
|
||||
"SyncConfigList": [
|
||||
{
|
||||
"Domain": "irc.uat.rayplus.net",
|
||||
"Primary": "AliyunOSS",
|
||||
"Target": "AWS",
|
||||
"UploadRegion": "CN",
|
||||
"TargetRegion": "US",
|
||||
"IsOpenSync": false
|
||||
},
|
||||
{
|
||||
"Domain": "lili.uat.extimaging.com",
|
||||
"Primary": "AWS",
|
||||
"Target": "AliyunOSS",
|
||||
"UploadRegion": "US",
|
||||
"TargetRegion": "CN",
|
||||
"IsOpenSync": false
|
||||
}
|
||||
],
|
||||
|
||||
"AliyunOSS": {
|
||||
"RegionId": "cn-shanghai",
|
||||
"InternalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com",
|
||||
"EndPoint": "https://oss-cn-shanghai.aliyuncs.com",
|
||||
"AccessKeyId": "LTAI5tFUCCmz5TwghZHsj45Y",
|
||||
"AccessKeySecret": "8evrBy1fVfzJG25i67Jm0xqn9Xcw2T",
|
||||
"RoleArn": "acs:ram::1078130221702011:role/uat-oss-access",
|
||||
"BucketName": "heanshu-irc-uat-store",
|
||||
"ViewEndpoint": "https://heanshu-irc-uat-store.oss-cn-shanghai.aliyuncs.com",
|
||||
"Region": "oss-cn-shanghai",
|
||||
"DurationSeconds": 7200
|
||||
},
|
||||
|
||||
"MinIO": {
|
||||
"endPoint": "hir-oss.uat.extimaging.com",
|
||||
"port": "80",
|
||||
"useSSL": false,
|
||||
"viewEndpoint": "http://hir-oss.uat.extimaging.com/irc-uat",
|
||||
//"port": "443",
|
||||
//"useSSL": true,
|
||||
//"viewEndpoint": "https://hir-oss.uat.extimaging.com/irc-uat",
|
||||
"accessKey": "b9Ul0e98xPzt6PwRXA1Q",
|
||||
"secretKey": "DzMaU2L4OXl90uytwOmDXF2encN0Jf4Nxu2XkYqQ",
|
||||
"bucketName": "irc-uat"
|
||||
|
||||
},
|
||||
"AWS": {
|
||||
"Region": "us-east-1",
|
||||
"EndPoint": "s3.us-east-1.amazonaws.com",
|
||||
"UseSSL": true,
|
||||
"RoleArn": "arn:aws:iam::471112624751:role/uat_s3_access",
|
||||
"AccessKeyId": "AKIAW3MEAFJX7IPXISP4",
|
||||
"SecretAccessKey": "Pgrg3le5jPxZQ7MR1yYNS30J0XRyJeKVyIIjElXc",
|
||||
"BucketName": "ei-med-s3-lili-uat-store",
|
||||
"ViewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com/",
|
||||
"DurationSeconds": 7200
|
||||
}
|
||||
},
|
||||
|
||||
"BasicSystemConfig": {
|
||||
// 启用质控风险控制功能
|
||||
"QCRiskControl": true,
|
||||
"OpenUserComplexPassword": true,
|
||||
"OpenSignDocumentBeforeWork": true,
|
||||
|
||||
"OpenLoginLimit": true,
|
||||
"LoginMaxFailCount": 5,
|
||||
|
||||
"LoginFailLockMinutes": 30,
|
||||
"AutoLoginOutMinutes": 120,
|
||||
|
||||
"OpenLoginMFA": false,
|
||||
|
||||
"ContinuousReadingTimeMin": 120,
|
||||
"ReadingRestTimeMin": 10,
|
||||
|
||||
"IsNeedChangePassWord": true,
|
||||
"ChangePassWordDays": 90,
|
||||
// 模板类型 1 Elevate 2 Extensive
|
||||
"TemplateType": 2,
|
||||
//MFA免验证发送天数
|
||||
"UserMFAVerifyMinutes": 1440
|
||||
|
||||
},
|
||||
"SystemEmailSendConfig": {
|
||||
//"Port": 465,
|
||||
//"Host": "smtp.qiye.163.com",
|
||||
//"Imap": "imap.qiye.163.com",
|
||||
//"ImapPort": 993,
|
||||
//"FromEmail": "service@heanshu.com",
|
||||
//"FromName": "Uat HeAnShu Imaging System",
|
||||
//"AuthorizationCode": "j#cAPU%XgvcHWn3N",
|
||||
//"SiteUrl": "https://irc.uat.heanshu.com",
|
||||
|
||||
"Port": 465,
|
||||
"Host": "smtp.qiye.aliyun.com",
|
||||
"Imap": "imap.qiye.aliyun.com",
|
||||
"ImapPort": 993,
|
||||
"FromEmail": "service@mail.rayplus.net",
|
||||
"FromName": "Uat HeAnShu Imaging System",
|
||||
"AuthorizationCode": "crefHpx3WtenFr6X",
|
||||
"SiteUrl": "https://irc.uat.heanshu.com",
|
||||
|
||||
"PlatformName": "HeAnShu",
|
||||
"PlatformNameCN": "禾安枢影像云平台",
|
||||
"SystemShortName": "HeAnShu",
|
||||
"OrganizationName": "HeAnShu",
|
||||
"OrganizationNameCN": "HeAnShu",
|
||||
"CompanyName": "HeAnShu",
|
||||
"CompanyNameCN": "禾安枢软件科技有限公司",
|
||||
"CompanyShortName": "HeAnShu",
|
||||
"CompanyShortNameCN": "禾安枢",
|
||||
"IsEnv_US": false,
|
||||
"EmailRegexStr": "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$",
|
||||
"CronEmailDefaultCulture": "zh-CN"
|
||||
},
|
||||
|
||||
"SystemPacsConfig": {
|
||||
"Port": "11113",
|
||||
"IP": "101.132.253.119"
|
||||
},
|
||||
"RequestDuplicationOptions": {
|
||||
"IsEnabled": true,
|
||||
"DuplicationWindowMs": 200,
|
||||
"CacheTimeSeconds": 5,
|
||||
"ExcludedPaths": [
|
||||
]
|
||||
}
|
||||
|
||||
}
|
||||
@@ -19,6 +19,26 @@
|
||||
"ObjectStoreService": {
|
||||
|
||||
"ObjectStoreUse": "AliyunOSS",
|
||||
"IsOpenStoreSync": true,
|
||||
"ApiDeployRegion": "CN",
|
||||
"SyncConfigList": [
|
||||
{
|
||||
"Domain": "irc.uat.extimaging.com",
|
||||
"Primary": "AliyunOSS",
|
||||
"Target": "AWS",
|
||||
"UploadRegion": "CN",
|
||||
"TargetRegion": "US",
|
||||
"IsOpenSync": true
|
||||
},
|
||||
{
|
||||
"Domain": "lili.uat.extimaging.com",
|
||||
"Primary": "AWS",
|
||||
"Target": "AliyunOSS",
|
||||
"UploadRegion": "US",
|
||||
"TargetRegion": "CN",
|
||||
"IsOpenSync": true
|
||||
}
|
||||
],
|
||||
|
||||
"AliyunOSS": {
|
||||
"RegionId": "cn-shanghai",
|
||||
@@ -50,9 +70,9 @@
|
||||
"Region": "us-east-1",
|
||||
"EndPoint": "s3.us-east-1.amazonaws.com",
|
||||
"UseSSL": true,
|
||||
"RoleArn": "arn:aws:iam::471112624751:role/sts_s3_upload",
|
||||
"AccessKeyId": "AKIAW3MEAFJXWRCGSX5Z",
|
||||
"SecretAccessKey": "miais4jQGSd37A+TfBEP11AQM5u/CvotSmznJd8k",
|
||||
"RoleArn": "arn:aws:iam::471112624751:role/uat_s3_access",
|
||||
"AccessKeyId": "AKIAW3MEAFJX7IPXISP4",
|
||||
"SecretAccessKey": "Pgrg3le5jPxZQ7MR1yYNS30J0XRyJeKVyIIjElXc",
|
||||
"BucketName": "ei-med-s3-lili-uat-store",
|
||||
"ViewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com/",
|
||||
"DurationSeconds": 7200
|
||||
@@ -90,7 +110,7 @@
|
||||
"Imap": "imap.qiye.aliyun.com",
|
||||
"ImapPort": 993,
|
||||
"FromEmail": "uat@extimaging.com",
|
||||
"FromName": "Uat IRC Imaging System",
|
||||
"FromName": "Uat EIC Imaging System",
|
||||
"AuthorizationCode": "SHzyyl2021",
|
||||
"SiteUrl": "http://irc.uat.extimaging.com/login",
|
||||
|
||||
@@ -104,10 +124,8 @@
|
||||
"CompanyShortName": "Extensive Imaging",
|
||||
"CompanyShortNameCN": "展影医疗",
|
||||
"IsEnv_US": false,
|
||||
"IsOpenErrorNoticeEmail": false,
|
||||
"EmailRegexStr": "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$",
|
||||
"CronEmailDefaultCulture": "zh-CN",
|
||||
"ErrorNoticeEmailList": [ "872297557@qq.com" ]
|
||||
"CronEmailDefaultCulture": "zh-CN"
|
||||
},
|
||||
|
||||
"SystemPacsConfig": {
|
||||
@@ -116,7 +134,7 @@
|
||||
},
|
||||
"RequestDuplicationOptions": {
|
||||
"IsEnabled": true,
|
||||
"DuplicationWindowMs": 200,
|
||||
"DuplicationWindowMs": 500,
|
||||
"CacheTimeSeconds": 5,
|
||||
"ExcludedPaths": [
|
||||
]
|
||||
|
||||
@@ -0,0 +1,143 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft": "Warning",
|
||||
"Microsoft.Hosting.Lifetime": "Information"
|
||||
}
|
||||
},
|
||||
"ConnectionStrings": {
|
||||
"RemoteNew": "Server=101.132.253.119,1435;Database=Uat_Rayplus;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
|
||||
"Hangfire": "Server=101.132.253.119,1435;Database=Uat_Rayplus_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true"
|
||||
},
|
||||
"WeComNoticeConfig": {
|
||||
"IsOpenWeComNotice": true,
|
||||
"WebhookUrl": "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=4355b98e-1e72-4678-8dfb-2fc6ad0bf449", //4355b98e-1e72-4678-8dfb-2fc6ad0bf449 //cdd97aab-d256-4f07-9145-a0a2b1555322
|
||||
"APINoticeUserList": [ "u", "wait..." ],
|
||||
"VueNoticeUserList": [ "wangxiaoshuang", "6b7717a31647293621b97b96f74e6f3d" ]
|
||||
},
|
||||
"ObjectStoreService": {
|
||||
|
||||
"ObjectStoreUse": "AliyunOSS",
|
||||
"IsOpenStoreSync": true,
|
||||
"ApiDeployRegion": "CN",
|
||||
"SyncConfigList": [
|
||||
{
|
||||
"Domain": "irc.uat.rayplus.net",
|
||||
"Primary": "AliyunOSS",
|
||||
"Target": "AWS",
|
||||
"UploadRegion": "CN",
|
||||
"TargetRegion": "US",
|
||||
"IsOpenSync": false
|
||||
},
|
||||
{
|
||||
"Domain": "lili.uat.extimaging.com",
|
||||
"Primary": "AWS",
|
||||
"Target": "AliyunOSS",
|
||||
"UploadRegion": "US",
|
||||
"TargetRegion": "CN",
|
||||
"IsOpenSync": false
|
||||
}
|
||||
],
|
||||
|
||||
"AliyunOSS": {
|
||||
"RegionId": "cn-shanghai",
|
||||
"InternalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com",
|
||||
"EndPoint": "https://oss-cn-shanghai.aliyuncs.com",
|
||||
"AccessKeyId": "LTAI5tFUCCmz5TwghZHsj45Y",
|
||||
"AccessKeySecret": "8evrBy1fVfzJG25i67Jm0xqn9Xcw2T",
|
||||
"RoleArn": "acs:ram::1078130221702011:role/uat-oss-access",
|
||||
"BucketName": "rayplus-irc-uat-store",
|
||||
"ViewEndpoint": "https://rayplus-irc-uat-store.oss-cn-shanghai.aliyuncs.com",
|
||||
"Region": "oss-cn-shanghai",
|
||||
"DurationSeconds": 7200
|
||||
},
|
||||
|
||||
"MinIO": {
|
||||
"endPoint": "hir-oss.uat.extimaging.com",
|
||||
"port": "80",
|
||||
"useSSL": false,
|
||||
"viewEndpoint": "http://hir-oss.uat.extimaging.com/irc-uat",
|
||||
//"port": "443",
|
||||
//"useSSL": true,
|
||||
//"viewEndpoint": "https://hir-oss.uat.extimaging.com/irc-uat",
|
||||
"accessKey": "b9Ul0e98xPzt6PwRXA1Q",
|
||||
"secretKey": "DzMaU2L4OXl90uytwOmDXF2encN0Jf4Nxu2XkYqQ",
|
||||
"bucketName": "irc-uat"
|
||||
|
||||
},
|
||||
"AWS": {
|
||||
"Region": "us-east-1",
|
||||
"EndPoint": "s3.us-east-1.amazonaws.com",
|
||||
"UseSSL": true,
|
||||
"RoleArn": "arn:aws:iam::471112624751:role/uat_s3_access",
|
||||
"AccessKeyId": "AKIAW3MEAFJX7IPXISP4",
|
||||
"SecretAccessKey": "Pgrg3le5jPxZQ7MR1yYNS30J0XRyJeKVyIIjElXc",
|
||||
"BucketName": "ei-med-s3-lili-uat-store",
|
||||
"ViewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com/",
|
||||
"DurationSeconds": 7200
|
||||
}
|
||||
},
|
||||
|
||||
"BasicSystemConfig": {
|
||||
// 启用质控风险控制功能
|
||||
"QCRiskControl": true,
|
||||
"OpenUserComplexPassword": true,
|
||||
"OpenSignDocumentBeforeWork": true,
|
||||
|
||||
"OpenLoginLimit": true,
|
||||
"LoginMaxFailCount": 5,
|
||||
|
||||
"LoginFailLockMinutes": 30,
|
||||
"AutoLoginOutMinutes": 120,
|
||||
|
||||
"OpenLoginMFA": false,
|
||||
|
||||
"ContinuousReadingTimeMin": 120,
|
||||
"ReadingRestTimeMin": 10,
|
||||
|
||||
"IsNeedChangePassWord": true,
|
||||
"ChangePassWordDays": 90,
|
||||
// 模板类型 1 Elevate 2 Extensive
|
||||
"TemplateType": 2,
|
||||
//MFA免验证发送天数
|
||||
"UserMFAVerifyMinutes": 1440
|
||||
|
||||
},
|
||||
"SystemEmailSendConfig": {
|
||||
"Port": 465,
|
||||
"Host": "smtp.qiye.aliyun.com",
|
||||
"Imap": "imap.qiye.aliyun.com",
|
||||
"ImapPort": 993,
|
||||
"FromEmail": "uat@mail.rayplus.net",
|
||||
"FromName": "Uat RayPlus Imaging System",
|
||||
"AuthorizationCode": "QWE1zxcv7632",
|
||||
"SiteUrl": "https://irc.uat.rayplus.net/login",
|
||||
|
||||
"PlatformName": "RayPlus",
|
||||
"PlatformNameCN": "睿佳影像云平台",
|
||||
"SystemShortName": "RayPlus",
|
||||
"OrganizationName": "RayPlus",
|
||||
"OrganizationNameCN": "RayPlus",
|
||||
"CompanyName": "RayPlus",
|
||||
"CompanyNameCN": "睿佳(武汉)软件科技有限公司",
|
||||
"CompanyShortName": "RayPlus",
|
||||
"CompanyShortNameCN": "睿佳",
|
||||
"IsEnv_US": false,
|
||||
"EmailRegexStr": "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$",
|
||||
"CronEmailDefaultCulture": "zh-CN"
|
||||
},
|
||||
|
||||
"SystemPacsConfig": {
|
||||
"Port": "11113",
|
||||
"IP": "101.132.253.119"
|
||||
},
|
||||
"RequestDuplicationOptions": {
|
||||
"IsEnabled": true,
|
||||
"DuplicationWindowMs": 200,
|
||||
"CacheTimeSeconds": 5,
|
||||
"ExcludedPaths": [
|
||||
]
|
||||
}
|
||||
|
||||
}
|
||||
@@ -77,7 +77,7 @@
|
||||
},
|
||||
"RequestDuplicationOptions": {
|
||||
"IsEnabled": true,
|
||||
"DuplicationWindowMs": 200,
|
||||
"DuplicationWindowMs": 500,
|
||||
"CacheTimeSeconds": 5,
|
||||
"ExcludedPaths": [
|
||||
]
|
||||
|
||||
@@ -39,7 +39,8 @@ namespace IRaCIS.Core.Application.Auth
|
||||
new Claim(JwtIRaCISClaimType.UserTypeShortName,user.UserTypeShortName),
|
||||
new Claim(JwtIRaCISClaimType.PermissionStr,user.PermissionStr),
|
||||
new Claim(JwtIRaCISClaimType.IsZhiZhun,user.IsZhiZhun.ToString()),
|
||||
new Claim(JwtIRaCISClaimType.IsTestUser,user.IsTestUser.ToString())
|
||||
new Claim(JwtIRaCISClaimType.IsTestUser,user.IsTestUser.ToString()),
|
||||
new Claim(JwtIRaCISClaimType.UserWorkLanguage,user.UserWorkLanguage.ToString())
|
||||
};
|
||||
|
||||
////创建令牌
|
||||
|
||||
@@ -23,5 +23,7 @@ namespace IRaCIS.Core.Application.Auth
|
||||
public bool IsZhiZhun { get; set; }
|
||||
|
||||
public string UserTypeShortName { get; set; } = string.Empty;
|
||||
|
||||
public UserWorkLanguage UserWorkLanguage { get; set; }
|
||||
}
|
||||
}
|
||||
+58
-10
@@ -8,6 +8,8 @@ namespace IRaCIS.Core.Application.BusinessFilter.LegacyController
|
||||
{
|
||||
using Database.Api;
|
||||
using DocumentFormat.OpenXml.InkML;
|
||||
using global::MassTransit;
|
||||
using IRaCIS.Core.Application.Helper.OtherTool;
|
||||
using IRaCIS.Core.Application.Service.Common;
|
||||
using IRaCIS.Core.Infrastructure;
|
||||
using IRaCIS.Core.Infrastructure.Extention;
|
||||
@@ -17,6 +19,7 @@ namespace IRaCIS.Core.Application.BusinessFilter.LegacyController
|
||||
using Microsoft.AspNetCore.Mvc.Controllers;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
@@ -35,7 +38,7 @@ namespace IRaCIS.Core.Application.BusinessFilter.LegacyController
|
||||
/// </summary>
|
||||
/// <param name="logger">logger</param>
|
||||
/// <param name="accessor">loggerHelper</param>
|
||||
public class RequestDuplicationFilter(ILogger<RequestDuplicationFilter> logger, IHttpContextAccessor accessor, IUserInfo _userInfo, IStringLocalizer _localizer, IOptionsMonitor<RequestDuplicationOptions> RequestDuplicationOptionsMonitor) : ExceptionFilterAttribute, IAsyncActionFilter
|
||||
public class RequestDuplicationFilter(ILogger<RequestDuplicationFilter> logger, IHttpContextAccessor accessor, IUserInfo _userInfo, IStringLocalizer _localizer, IOptionsMonitor<RequestDuplicationOptions> RequestDuplicationOptionsMonitor, IConfiguration _config) : ExceptionFilterAttribute, IAsyncActionFilter
|
||||
{
|
||||
/// <summary>
|
||||
/// 传入的参数
|
||||
@@ -70,6 +73,10 @@ namespace IRaCIS.Core.Application.BusinessFilter.LegacyController
|
||||
{
|
||||
this.RequestDuplication();
|
||||
}
|
||||
catch (BusinessValidationFailedException)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
||||
@@ -89,8 +96,12 @@ namespace IRaCIS.Core.Application.BusinessFilter.LegacyController
|
||||
{
|
||||
var requestPath = accessor?.HttpContext?.Request?.Path.ToString() ?? string.Empty;
|
||||
|
||||
var httpMethod = accessor?.HttpContext?.Request?.Method?.ToUpper() ?? string.Empty;
|
||||
|
||||
// 验证请求频繁情况
|
||||
if (
|
||||
!httpMethod.Equals("GET", StringComparison.OrdinalIgnoreCase) &&
|
||||
|
||||
!requestPath
|
||||
.Split("/", StringSplitOptions.RemoveEmptyEntries)
|
||||
.Any(segment => segment.StartsWith("get", StringComparison.OrdinalIgnoreCase)) &&
|
||||
@@ -106,17 +117,54 @@ namespace IRaCIS.Core.Application.BusinessFilter.LegacyController
|
||||
RequestTime = DateTime.Now
|
||||
};
|
||||
|
||||
IRCSystemInfo.RequestRecordList= IRCSystemInfo.RequestRecordList.Where(x => x.RequestTime >= DateTime.Now.AddSeconds(-RequestDuplicationOptionsMonitor.CurrentValue.CacheTimeSeconds)).ToList();
|
||||
|
||||
|
||||
var requestsTimes = IRCSystemInfo.RequestRecordList.Any(x=>
|
||||
x.RequestTime>= requestInfo.RequestTime.AddMilliseconds(-RequestDuplicationOptionsMonitor.CurrentValue.DuplicationWindowMs)&&
|
||||
x.RequestKey== requestInfo.RequestKey);
|
||||
if (requestsTimes)
|
||||
var isAdded = IRCSystemInfo.TryAddRequestRecord(
|
||||
requestInfo,
|
||||
RequestDuplicationOptionsMonitor.CurrentValue.CacheTimeSeconds,
|
||||
RequestDuplicationOptionsMonitor.CurrentValue.DuplicationWindowMs);
|
||||
if (!isAdded)
|
||||
{
|
||||
throw new BusinessValidationFailedException(_localizer["RequestDuplicationFilter_RequestDuplication"], ApiResponseCodeEnum.BusinessValidationFailed);
|
||||
SendRequestDuplicationWeComNotice(requestPath);
|
||||
logger.LogError($"重复请求出现错误:{this.Intoparam}");
|
||||
throw new BusinessValidationFailedException(_localizer["RequestDuplicationFilter_RequestDuplication"], ApiResponseCodeEnum.NotRemind);
|
||||
}
|
||||
IRCSystemInfo.RequestRecordList.Add(requestInfo);
|
||||
}
|
||||
}
|
||||
|
||||
private void SendRequestDuplicationWeComNotice(string requestPath)
|
||||
{
|
||||
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:VueNoticeUserList").Get<string[]>();
|
||||
|
||||
var request = accessor?.HttpContext?.Request;
|
||||
|
||||
_ = WeComNotifier.SendAlertAsync(
|
||||
webhook: webhook,
|
||||
alert: new WeComAlert
|
||||
{
|
||||
Env = baseUrl,
|
||||
UserName = _userInfo.UserName.IsNotNullOrEmpty() ? $"{_userInfo.UserName}({_userInfo.UserTypeShortName})" : "匿名",
|
||||
Api = $"{request?.Method} {requestPath}",
|
||||
Message = "重复请求拦截",
|
||||
JsonData = this.Intoparam,
|
||||
Stack = string.Empty,
|
||||
AtUsers = userList ?? []
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.LogError($"重复请求过滤器里发送企业微信出现错误:{ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -79,11 +79,12 @@ public class SystemEmailSendConfig
|
||||
|
||||
public bool IsEnv_US { get; set; }
|
||||
|
||||
public bool IsOpenErrorNoticeEmail { get; set; }
|
||||
|
||||
public string EmailRegexStr { get; set; }
|
||||
|
||||
public List<string> ErrorNoticeEmailList { get; set; } = new List<string>();
|
||||
//public bool IsOpenErrorNoticeEmail { get; set; }
|
||||
|
||||
|
||||
//public List<string> ErrorNoticeEmailList { get; set; } = new List<string>();
|
||||
}
|
||||
|
||||
public class SystemEmailSendConfigView
|
||||
@@ -145,6 +146,31 @@ public class RequestDuplicationOptions
|
||||
public static class IRCSystemInfo
|
||||
{
|
||||
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
|
||||
@@ -235,4 +261,4 @@ public static class AppSettings
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,8 @@ public static class CacheKeys
|
||||
//项目缓存
|
||||
public static string Trial(string trialIdStr) => $"TrialId:{trialIdStr}";
|
||||
|
||||
public static string TrialVisitTaskMaxCode(Guid trialId) => $"TrialVisitTaskMaxCode:{trialId}";
|
||||
|
||||
//检查编号递增锁
|
||||
public static string TrialStudyMaxCode(Guid trialId) => $"TrialStudyMaxCode:{trialId}";
|
||||
|
||||
|
||||
@@ -1,15 +1,8 @@
|
||||
using DocumentFormat.OpenXml.Office.CustomUI;
|
||||
using FellowOakDicom;
|
||||
using FellowOakDicom;
|
||||
using FellowOakDicom.Media;
|
||||
using IRaCIS.Core.Application.ViewModel;
|
||||
using IRaCIS.Core.Domain.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace IRaCIS.Core.Application.Helper
|
||||
{
|
||||
@@ -160,6 +153,91 @@ namespace IRaCIS.Core.Application.Helper
|
||||
}
|
||||
|
||||
|
||||
public static async Task GenerateStudyDIR(List<StudyDIRInfo> list, Dictionary<string, string> dic, string? dirSavePath = null, Stream? outputStream = null)
|
||||
{
|
||||
var mappings = new List<string>();
|
||||
int index = 1;
|
||||
|
||||
var trialId = Guid.Empty;
|
||||
|
||||
|
||||
var studyUid = list.FirstOrDefault()?.StudyInstanceUid;
|
||||
|
||||
var dicomDir = new DicomDirectory();
|
||||
|
||||
foreach (var item in list.OrderBy(t => t.SeriesNumber).ThenBy(t => t.InstanceNumber))
|
||||
{
|
||||
var dicomUid = DicomUID.Enumerate().FirstOrDefault(uid => uid.UID == item.TransferSytaxUID);
|
||||
|
||||
if (dicomUid != null)
|
||||
{
|
||||
var ts = DicomTransferSyntax.Query(dicomUid);
|
||||
|
||||
var dataset = new DicomDataset(ts)
|
||||
{
|
||||
{ DicomTag.PatientID, item.PatientId ?? string.Empty },
|
||||
{ DicomTag.PatientName, item.PatientName ?? string.Empty },
|
||||
{ DicomTag.PatientBirthDate, item.PatientBirthDate ?? string.Empty },
|
||||
{ DicomTag.PatientSex, item.PatientSex ?? string.Empty },
|
||||
|
||||
{ DicomTag.StudyInstanceUID, item.StudyInstanceUid ?? string.Empty },
|
||||
{ DicomTag.StudyID, item.StudyId ?? string.Empty },
|
||||
{ DicomTag.StudyDate, item.DicomStudyDate ?? string.Empty },
|
||||
{ DicomTag.StudyTime, item.DicomStudyTime ?? string.Empty },
|
||||
{ DicomTag.AccessionNumber, item.AccessionNumber ?? string.Empty },
|
||||
{ DicomTag.StudyDescription, item.StudyDescription ?? string.Empty },
|
||||
|
||||
{ DicomTag.SeriesInstanceUID, item.SeriesInstanceUid ?? string.Empty },
|
||||
{ DicomTag.Modality, item.Modality ?? string.Empty },
|
||||
{ DicomTag.SeriesDate, item.DicomSeriesDate ?? string.Empty },
|
||||
{ DicomTag.SeriesTime, item.DicomSeriesTime ?? string.Empty },
|
||||
{ DicomTag.SeriesNumber, item.SeriesNumber.ToString() ?? string.Empty },
|
||||
{ DicomTag.SeriesDescription, item.SeriesDescription ?? string.Empty },
|
||||
|
||||
{ DicomTag.SOPInstanceUID, item.SopInstanceUid ?? string.Empty },
|
||||
{ DicomTag.SOPClassUID, item.SOPClassUID ?? string.Empty },
|
||||
{ DicomTag.InstanceNumber, item.InstanceNumber.ToString() ?? string.Empty },
|
||||
{ DicomTag.MediaStorageSOPClassUID, item.MediaStorageSOPClassUID ?? string.Empty },
|
||||
{ DicomTag.MediaStorageSOPInstanceUID, item.MediaStorageSOPInstanceUID ?? string.Empty },
|
||||
{ DicomTag.TransferSyntaxUID, item.TransferSytaxUID ?? string.Empty },
|
||||
};
|
||||
|
||||
var dicomFile = new DicomFile(dataset);
|
||||
|
||||
// 文件名递增格式:IM_00001, IM_00002, ...
|
||||
string filename = $@"IMAGE\IM_{index:D5}"; // :D5 表示补足5位
|
||||
|
||||
mappings.Add($"{filename} => {item.InstanceId}");
|
||||
|
||||
dic.Add(item.InstanceId.ToString(), filename.TrimEnd('/', '\\').Split('/', '\\').Last());
|
||||
|
||||
dicomDir.AddFile(dicomFile, filename);
|
||||
|
||||
index++;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
//有实际的文件
|
||||
if (mappings.Count > 0)
|
||||
{
|
||||
// 保存 DICOMDIR 到临时文件 不能直接写入到流种
|
||||
|
||||
if (dirSavePath.IsNotNullOrEmpty())
|
||||
{
|
||||
await dicomDir.SaveAsync(dirSavePath);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
await dicomDir.SaveAsync(outputStream);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static StudyDIRInfo ReadDicomDIRInfo(DicomFile dicomFile)
|
||||
{
|
||||
|
||||
@@ -17,7 +17,7 @@ public static class SendEmailHelper
|
||||
|
||||
//没有收件人 那么不发送
|
||||
if (messageToSend.To.Count == 0)
|
||||
{
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
@@ -62,8 +62,15 @@ public static class SendEmailHelper
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static async Task<string> SendEmailAsync(MimeMessage messageToSend, Trial trial, EventHandler<MessageSentEventArgs>? messageSentSuccess = null)
|
||||
/// <summary>
|
||||
/// 发送项目邮件
|
||||
/// </summary>
|
||||
/// <param name="messageToSend"></param>
|
||||
/// <param name="trial"></param>
|
||||
/// <param name="messageSentSuccess"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="Exception"></exception>
|
||||
public static async Task<string> SendTrialEmailAsync(MimeMessage messageToSend, Trial trial, EventHandler<MessageSentEventArgs>? messageSentSuccess = null)
|
||||
{
|
||||
|
||||
// 项目的需要重设 发件地址与邮件地址
|
||||
@@ -78,12 +85,39 @@ public static class SendEmailHelper
|
||||
string result = string.Empty;
|
||||
result = messageToSend.MessageId;
|
||||
|
||||
|
||||
//没有收件人 那么不发送
|
||||
if (messageToSend.To.Count == 0)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
// 替换邮件标题
|
||||
if (!string.IsNullOrEmpty(messageToSend.Subject))
|
||||
{
|
||||
foreach (var item in trial.TrialObjectNameList)
|
||||
{
|
||||
// 把标题里的占位符替换成真实名称
|
||||
messageToSend.Subject = messageToSend.Subject.Replace(item.Name, item.TrialName);
|
||||
}
|
||||
}
|
||||
|
||||
// 构建替换字典
|
||||
var replacements = new Dictionary<string, string>();
|
||||
foreach (var item in trial.TrialObjectNameList)
|
||||
{
|
||||
replacements[item.Name] = item.TrialName;
|
||||
}
|
||||
|
||||
// 安全替换 HTML
|
||||
ReplaceHtmlContent(messageToSend.Body, replacements);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
using (var smtp = new MailKit.Net.Smtp.SmtpClient())
|
||||
@@ -128,6 +162,27 @@ public static class SendEmailHelper
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 遍历邮件体,找到 HTML 部分并替换
|
||||
public static void ReplaceHtmlContent(MimeEntity entity, Dictionary<string, string> replacements)
|
||||
{
|
||||
if (entity is Multipart multipart)
|
||||
{
|
||||
foreach (var part in multipart)
|
||||
{
|
||||
ReplaceHtmlContent(part, replacements);
|
||||
}
|
||||
}
|
||||
else if (entity is TextPart textPart && textPart.IsHtml)
|
||||
{
|
||||
// 只有这里才是真正的 HTML
|
||||
foreach (var kv in replacements)
|
||||
{
|
||||
textPart.Text = textPart.Text.Replace(kv.Key, kv.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
public static async Task<bool> TestEmailConfigAsync(SystemEmailSendConfig _systemEmailConfig)
|
||||
{
|
||||
using (var cts = new CancellationTokenSource(TimeSpan.FromSeconds(5)))
|
||||
@@ -147,7 +202,7 @@ public static class SendEmailHelper
|
||||
return true;
|
||||
}
|
||||
|
||||
public static async Task SendEmailAsync(SMTPEmailConfig sMTPEmailConfig,Trial? trial, EventHandler<MessageSentEventArgs>? messageSentSuccess = null)
|
||||
public static async Task SendEmailAsync(SMTPEmailConfig sMTPEmailConfig, Trial? trial, EventHandler<MessageSentEventArgs>? messageSentSuccess = null)
|
||||
{
|
||||
var messageToSend = new MimeMessage();
|
||||
|
||||
@@ -161,8 +216,9 @@ public static class SendEmailHelper
|
||||
|
||||
if (sMTPEmailConfig.ToMailAddressList.Count == 0)
|
||||
{
|
||||
return;
|
||||
//---没有收件人
|
||||
throw new ArgumentException(I18n.T("SendEmail_NoRecipient"));
|
||||
//throw new ArgumentException(I18n.T("SendEmail_NoRecipient"));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,4 @@
|
||||
using IRaCIS.Core.Domain.Share;
|
||||
using NPOI.XWPF.UserModel;
|
||||
using System.Globalization;
|
||||
using System.Globalization;
|
||||
using Xceed.Document.NET;
|
||||
using Xceed.Words.NET;
|
||||
|
||||
@@ -54,42 +52,42 @@ public static class WordTempleteHelper
|
||||
}
|
||||
|
||||
|
||||
public static void Npoi_GetInternationalTempleteStream(string filePath, Stream memoryStream)
|
||||
{
|
||||
//public static void Npoi_GetInternationalTempleteStream(string filePath, Stream memoryStream)
|
||||
//{
|
||||
|
||||
var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;
|
||||
// var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;
|
||||
|
||||
using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
|
||||
{
|
||||
XWPFDocument doc = new XWPFDocument(fs);
|
||||
// using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
|
||||
// {
|
||||
// XWPFDocument doc = new XWPFDocument(fs);
|
||||
|
||||
// 查找包含指定书签的段落及其索引
|
||||
var bookmarkParagraph = doc.Paragraphs
|
||||
.FirstOrDefault(p => p.GetCTP().GetBookmarkStartList().Any(b => b.name == StaticData.CultureInfo.en_US_bookMark));
|
||||
// // 查找包含指定书签的段落及其索引
|
||||
// var bookmarkParagraph = doc.Paragraphs
|
||||
// .FirstOrDefault(p => p.GetCTP().GetBookmarkStartList().Any(b => b.name == StaticData.CultureInfo.en_US_bookMark));
|
||||
|
||||
if (bookmarkParagraph != null)
|
||||
{
|
||||
int bookmarkIndex = doc.Paragraphs.IndexOf(bookmarkParagraph);
|
||||
// if (bookmarkParagraph != null)
|
||||
// {
|
||||
// int bookmarkIndex = doc.Paragraphs.IndexOf(bookmarkParagraph);
|
||||
|
||||
if (isEn_US)
|
||||
{
|
||||
// 从书签所在段落开始,删除之前的所有段落
|
||||
for (int i = bookmarkIndex - 1; i >= 0; i--)
|
||||
{
|
||||
doc.RemoveBodyElement(i);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 删除书签之后的所有段落
|
||||
for (int i = doc.Paragraphs.Count - 1; i >= bookmarkIndex; i--)
|
||||
{
|
||||
doc.RemoveBodyElement(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
doc.Write(memoryStream);
|
||||
}
|
||||
}
|
||||
// if (isEn_US)
|
||||
// {
|
||||
// // 从书签所在段落开始,删除之前的所有段落
|
||||
// for (int i = bookmarkIndex - 1; i >= 0; i--)
|
||||
// {
|
||||
// doc.RemoveBodyElement(i);
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// // 删除书签之后的所有段落
|
||||
// for (int i = doc.Paragraphs.Count - 1; i >= bookmarkIndex; i--)
|
||||
// {
|
||||
// doc.RemoveBodyElement(i);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// doc.Write(memoryStream);
|
||||
// }
|
||||
//}
|
||||
|
||||
}
|
||||
|
||||
@@ -220,7 +220,7 @@ public class OSSService(IOptionsMonitor<ObjectStoreServiceOptions> options,
|
||||
public object result { get; private set; }
|
||||
|
||||
|
||||
|
||||
private static readonly object _tokenLock = new();
|
||||
|
||||
/// <summary>
|
||||
/// 将指定前缀下的所有现有文件立即转为目标存储类型
|
||||
@@ -934,32 +934,52 @@ public class OSSService(IOptionsMonitor<ObjectStoreServiceOptions> options,
|
||||
//后端批量上传 或者下载,不每个文件获取临时token
|
||||
private void BackBatchGetToken()
|
||||
{
|
||||
|
||||
|
||||
// 过期时间 ≤ 当前时间 + 15分钟 时需要续期
|
||||
|
||||
if (ObjectStoreServiceOptions.ObjectStoreUse == "AliyunOSS")
|
||||
{
|
||||
if (AliyunOSSTempToken == null)
|
||||
if (AliyunOSSTempToken != null && AliyunOSSTempToken.Expiration > DateTime.Now.AddMinutes(15))
|
||||
{
|
||||
GetObjectStoreTempToken();
|
||||
}
|
||||
//token 过期了
|
||||
if (AliyunOSSTempToken?.Expiration.AddSeconds(10) <= DateTime.Now)
|
||||
{
|
||||
GetObjectStoreTempToken();
|
||||
return; // 还有15分钟以上,不需要续期
|
||||
}
|
||||
|
||||
lock (_tokenLock)
|
||||
{
|
||||
if (AliyunOSSTempToken == null ||
|
||||
AliyunOSSTempToken.Expiration <= DateTime.Now.AddMinutes(15))
|
||||
{
|
||||
GetObjectStoreTempToken();
|
||||
|
||||
Log.Logger.Warning("后端获取阿里云临时 Token");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else if (ObjectStoreServiceOptions.ObjectStoreUse == "AWS")
|
||||
{
|
||||
if (AWSTempToken == null)
|
||||
|
||||
|
||||
if (AWSTempToken != null && AWSTempToken.Expiration > DateTime.Now.AddMinutes(15))
|
||||
{
|
||||
GetObjectStoreTempToken();
|
||||
return;
|
||||
}
|
||||
//token 过期了
|
||||
if (AWSTempToken.Expiration?.AddSeconds(10) <= DateTime.Now)
|
||||
|
||||
lock (_tokenLock)
|
||||
{
|
||||
GetObjectStoreTempToken();
|
||||
if (AWSTempToken == null ||
|
||||
AWSTempToken.Expiration <= DateTime.Now.AddMinutes(15))
|
||||
{
|
||||
GetObjectStoreTempToken();
|
||||
|
||||
Log.Logger.Warning("后端获取s3 临时 Token");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1080,12 +1080,15 @@ public static class DicomSortHelper
|
||||
IEnumerable<T> source,
|
||||
Func<T, string?> ippSelector,
|
||||
Func<T, string?> iopSelector,
|
||||
Func<T, int?> instanceNumberSelector)
|
||||
Func<T, int?> instanceNumberSelector,string seriesDescription)
|
||||
{
|
||||
var list = source.ToList();
|
||||
if (list.Count < 2)
|
||||
return list;
|
||||
|
||||
if(seriesDescription.Contains("Dixon", StringComparison.OrdinalIgnoreCase))
|
||||
return list.OrderBy(instanceNumberSelector).ToList();
|
||||
|
||||
var first = list[0];
|
||||
|
||||
var reference = ParseVector(ippSelector(first));
|
||||
|
||||
@@ -3,8 +3,11 @@ using FellowOakDicom.Imaging;
|
||||
using SixLabors.ImageSharp;
|
||||
using SixLabors.ImageSharp.Formats.Jpeg;
|
||||
using SixLabors.ImageSharp.Processing;
|
||||
using SixLabors.ImageSharp.PixelFormats;
|
||||
using IRaCIS.Core.Application.Helper;
|
||||
using SixLabors.ImageSharp.Drawing.Processing;
|
||||
|
||||
|
||||
namespace IRaCIS.Core.Application.Helper;
|
||||
|
||||
public static class ImageHelper
|
||||
{
|
||||
@@ -28,7 +31,7 @@ public static class ImageHelper
|
||||
image.Save(fileStorePath, new JpegEncoder());
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -60,6 +63,36 @@ public static class ImageHelper
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public static class ImageMaskHelper
|
||||
{
|
||||
public static async Task MaskAsync(Stream input, Stream output, IEnumerable<MaskRegion> regions)
|
||||
{
|
||||
// 确保输入流从起始位置读取
|
||||
if (input.CanSeek && input.Position != 0)
|
||||
{
|
||||
input.Position = 0;
|
||||
}
|
||||
|
||||
using var image = await Image.LoadAsync(input);
|
||||
|
||||
// 保存原始图片的编码格式
|
||||
var originalFormat = image.Metadata.DecodedImageFormat;
|
||||
|
||||
image.Mutate(ctx =>
|
||||
{
|
||||
foreach (var r in regions)
|
||||
{
|
||||
ctx.Fill(Color.Black, new Rectangle(r.X, r.Y, r.Width, r.Height));
|
||||
}
|
||||
});
|
||||
|
||||
// 使用原始格式保存,保持格式不变
|
||||
await image.SaveAsync(output, originalFormat);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,15 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Security;
|
||||
using System.Net;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json;
|
||||
using RestSharp;
|
||||
using Newtonsoft.Json;
|
||||
using IRaCIS.Core.Infrastructure.Extention;
|
||||
using NPOI.SS.Formula.Functions;
|
||||
|
||||
namespace IRaCIS.Core.Application.Helper.OtherTool
|
||||
{
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<LangVersion>default</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<GenerateDocumentationFile>True</GenerateDocumentationFile>
|
||||
</PropertyGroup>
|
||||
@@ -12,6 +10,7 @@
|
||||
<OutputPath>..\bin\</OutputPath>
|
||||
<DocumentationFile>.\IRaCIS.Core.Application.xml</DocumentationFile>
|
||||
<NoWarn>1701;1702;1591</NoWarn>
|
||||
<NoWarn>$(NoWarn);NU1903</NoWarn>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
||||
@@ -32,13 +31,14 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="ClosedXML" Version="0.105.0" />
|
||||
<PackageReference Include="IdentityModel.OidcClient" Version="6.0.0" />
|
||||
<PackageReference Include="AlibabaCloud.SDK.Sts20150401" Version="1.2.0" />
|
||||
<PackageReference Include="Aliyun.OSS.SDK.NetCore" Version="2.14.1" />
|
||||
<PackageReference Include="AWSSDK.S3" Version="4.0.21" />
|
||||
<PackageReference Include="AWSSDK.SecurityToken" Version="4.0.5.19" />
|
||||
<PackageReference Include="AWSSDK.S3" Version="4.0.24" />
|
||||
<PackageReference Include="AWSSDK.SecurityToken" Version="4.0.7" />
|
||||
<PackageReference Include="DocX" Version="5.0.0" />
|
||||
<PackageReference Include="FreeSpire.Doc" Version="12.2.0" />
|
||||
<PackageReference Include="FreeSpire.Doc" Version="14.4.0" />
|
||||
<PackageReference Include="ExcelDataReader" Version="3.8.0" />
|
||||
<PackageReference Include="ExcelDataReader.DataSet" Version="3.8.0" />
|
||||
<PackageReference Include="DistributedLock.Redis" Version="1.1.1" />
|
||||
@@ -47,23 +47,23 @@
|
||||
<PackageReference Include="fo-dicom.Imaging.ImageSharp" Version="5.2.6" />
|
||||
<PackageReference Include="fo-dicom.Codecs" Version="5.16.7" />
|
||||
<PackageReference Include="IP2Region.Net" Version="3.0.2" />
|
||||
<PackageReference Include="MailKit" Version="4.15.1" />
|
||||
<PackageReference Include="MailKit" Version="4.17.0" />
|
||||
<PackageReference Include="Masa.Contrib.Service.MinimalAPIs" Version="1.1.0" />
|
||||
<PackageReference Include="MaxMind.GeoIP2" Version="5.4.1" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.10" />
|
||||
<PackageReference Include="MimeKit" Version="4.15.1" />
|
||||
<PackageReference Include="MiniExcel" Version="1.41.2" />
|
||||
<PackageReference Include="Minio" Version="6.0.3" />
|
||||
<PackageReference Include="MaxMind.GeoIP2" Version="6.0.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="10.0.8" />
|
||||
<PackageReference Include="MimeKit" Version="4.17.0" />
|
||||
<PackageReference Include="MiniExcel" Version="1.44.1" />
|
||||
<PackageReference Include="Minio" Version="7.0.0" />
|
||||
<PackageReference Include="MiniWord" Version="0.9.2" />
|
||||
<PackageReference Include="Serilog.AspNetCore" Version="10.0.0" />
|
||||
<PackageReference Include="My.Extensions.Localization.Json" Version="3.3.0">
|
||||
<PackageReference Include="My.Extensions.Localization.Json" Version="4.0.0">
|
||||
<TreatAsUsed>true</TreatAsUsed>
|
||||
</PackageReference>
|
||||
<PackageReference Include="NPOI" Version="2.7.4" />
|
||||
<PackageReference Include="Panda.DynamicWebApi" Version="1.2.2" />
|
||||
<PackageReference Include="RestSharp" Version="114.0.0" />
|
||||
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.12" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore.Filters" Version="8.0.2" />
|
||||
<PackageReference Include="SixLabors.ImageSharp.Drawing" Version="2.1.7" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore.Filters" Version="10.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -34,6 +34,8 @@ namespace IRaCIS.Core.Application.MassTransit.Command
|
||||
public Guid SubjectVisitId { get; set; }
|
||||
|
||||
public Guid StudyId { get; set; }
|
||||
|
||||
public string SiteCounty { get; set; }
|
||||
}
|
||||
|
||||
public class FullCheckResult: CheckViewModel
|
||||
@@ -62,7 +64,7 @@ namespace IRaCIS.Core.Application.MassTransit.Command
|
||||
|
||||
//[Required(ErrorMessage = "受试者筛选号不能为空")]
|
||||
//[ImporterHeader(Name = "Subject ID", AutoTrim = true)]
|
||||
[ExcelColumnName("Subject ID")]
|
||||
[ExcelColumnName("Participant ID")]
|
||||
public string SubjectCode { get; set; } = string.Empty;
|
||||
|
||||
//[Required(ErrorMessage = "访视名称不能为空")]
|
||||
|
||||
@@ -21,12 +21,14 @@ public static class CommonEmailHelper
|
||||
/// <param name="configInfo"></param>
|
||||
/// <param name="messageToSend"></param>
|
||||
/// <param name="emailFunc"></param>
|
||||
/// <param name="userWorkLanguage"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="BusinessValidationFailedException"></exception>
|
||||
public static async Task<EmailNoticeConfig> GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailNoticeConfig configInfo, MimeMessage messageToSend,
|
||||
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailFunc)
|
||||
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailFunc, UserWorkLanguage? userWorkLanguage = null)
|
||||
{
|
||||
var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;
|
||||
|
||||
bool isEn_US = userWorkLanguage.HasValue ? userWorkLanguage.Value == UserWorkLanguage.US : CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;
|
||||
|
||||
var (topicStr, htmlBodyStr) = isEn_US ? (configInfo.EmailTopic, configInfo.EmailHtmlContent) : (configInfo.EmailTopicCN, configInfo.EmailHtmlContentCN);
|
||||
|
||||
@@ -60,13 +62,14 @@ Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr
|
||||
/// <param name="configInfo"></param>
|
||||
/// <param name="messageToSend"></param>
|
||||
/// <param name="emailFunc"></param>
|
||||
/// <param name="userWorkLanguage"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="BusinessValidationFailedException"></exception>
|
||||
public static async Task<TrialEmailNoticeConfig> GetTrialEmailSubejctAndHtmlInfoAndBuildAsync(TrialEmailNoticeConfig configInfo, MimeMessage messageToSend,
|
||||
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailFunc)
|
||||
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailFunc, UserWorkLanguage? userWorkLanguage = null)
|
||||
{
|
||||
var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;
|
||||
|
||||
bool isEn_US = userWorkLanguage.HasValue ? userWorkLanguage.Value == UserWorkLanguage.US : CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;
|
||||
|
||||
var (topicStr, htmlBodyStr) = isEn_US ? (configInfo.EmailTopic, configInfo.EmailHtmlContent) : (configInfo.EmailTopicCN, configInfo.EmailHtmlContentCN);
|
||||
|
||||
@@ -94,12 +97,20 @@ Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr
|
||||
return configInfo;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public static string ReplaceCompanyName(SystemEmailSendConfig _systemEmailConfig, string needDealtxt)
|
||||
public static string ReplacePlatformName(SystemEmailSendConfig _systemEmailConfig, string needDealtxt, UserWorkLanguage? userWorkLanguage = null)
|
||||
{
|
||||
var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;
|
||||
var isEn_US = userWorkLanguage.HasValue ? userWorkLanguage.Value == UserWorkLanguage.US : CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;
|
||||
|
||||
var platformName = isEn_US ? _systemEmailConfig.PlatformName : _systemEmailConfig.PlatformNameCN;
|
||||
|
||||
var str = needDealtxt.Replace("{platformName}", platformName);
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
public static string ReplaceCompanyName(SystemEmailSendConfig _systemEmailConfig, string needDealtxt, UserWorkLanguage? userWorkLanguage = null)
|
||||
{
|
||||
var isEn_US = userWorkLanguage.HasValue ? userWorkLanguage.Value == UserWorkLanguage.US : CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;
|
||||
|
||||
var str = needDealtxt.Replace("{company}", isEn_US ? _systemEmailConfig.CompanyName : _systemEmailConfig.CompanyNameCN)
|
||||
.Replace("{company abbreviation}", isEn_US ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN);
|
||||
|
||||
@@ -10,12 +10,14 @@ using IRaCIS.Core.Application.ViewModel;
|
||||
using IRaCIS.Core.Domain.Models;
|
||||
using IRaCIS.Core.Domain.Share;
|
||||
using MassTransit;
|
||||
using MaxMind.GeoIP2.Model;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Localization;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Newtonsoft.Json;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
@@ -79,6 +81,8 @@ namespace IRaCIS.Core.Application.MassTransit.Consumer
|
||||
Modality = study.ModalityForEdit,
|
||||
SubjectCode = subject.Code,
|
||||
VisitName = sv.VisitName,
|
||||
|
||||
SiteCounty = sv.TrialSite.Country,
|
||||
};
|
||||
|
||||
var noneDicomQuey = from sv in _subjectVisitRepository.Where(subjectVisitLambda)
|
||||
@@ -93,6 +97,8 @@ namespace IRaCIS.Core.Application.MassTransit.Consumer
|
||||
Modality = noneDicomStudy.Modality,
|
||||
SubjectCode = subject.Code,
|
||||
VisitName = sv.VisitName,
|
||||
|
||||
SiteCounty = sv.TrialSite.Country,
|
||||
};
|
||||
|
||||
var dbList = (await dicomQuery.ToListAsync()).Union(await noneDicomQuey.ToListAsync()).ToList();
|
||||
@@ -120,6 +126,21 @@ namespace IRaCIS.Core.Application.MassTransit.Consumer
|
||||
|
||||
var dbVisitStudyList = dbList.Where(t => t.SubjectCode == sv.SubjectCode && t.SiteCode == sv.SiteCode && t.VisitName == sv.VisitName).ToList();
|
||||
|
||||
//设置当前中心语言
|
||||
|
||||
var isEn_us = dbVisitStudyList.First().SiteCounty == StaticData.SiteCountry.US;
|
||||
|
||||
var cultureInfoName = StaticData.CultureInfo.en_US;
|
||||
|
||||
if (isEn_us == false)
|
||||
{
|
||||
cultureInfoName = StaticData.CultureInfo.zh_CN;
|
||||
}
|
||||
|
||||
CultureInfo.CurrentCulture = new CultureInfo(cultureInfoName);
|
||||
CultureInfo.CurrentUICulture = new CultureInfo(cultureInfoName);
|
||||
|
||||
|
||||
//找到etc 当前visit site 和subject 一致的检查列表
|
||||
var etcVisitStudyList = etcList.Where(t => t.SubjectCode == sv.SubjectCode && t.SiteCode == sv.SiteCode && t.VisitName == sv.VisitName).ToList();
|
||||
|
||||
|
||||
@@ -27,5 +27,16 @@ namespace IRaCIS.Core.Application.MassTransit.Consumer.Dto
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
public class SendEmailUserDto
|
||||
{
|
||||
public UserTypeEnum UserTypeEnum { get; set; }
|
||||
|
||||
public string FullName { get; set; }
|
||||
|
||||
public UserWorkLanguage UserWorkLanguage { get; set; }
|
||||
|
||||
public string EMail { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -273,15 +273,30 @@ public class ImageConsumer(
|
||||
};
|
||||
|
||||
// 根据不同场景获取不同角色的用户 先排除CRC和CRA
|
||||
var trialUserList = await _trialUseRoleRepository.Where(x => x.TrialId == inDto.TrialId && !x.TrialUser.IsDeleted && !filterUserTypeList.Contains(x.UserRole.UserTypeEnum) ).Include(x => x.UserRole).Select(x => x.UserRole).ToListAsync();
|
||||
var trialUserList = await _trialUseRoleRepository.Where(x => x.TrialId == inDto.TrialId && !x.TrialUser.IsDeleted && !filterUserTypeList.Contains(x.UserRole.UserTypeEnum) ).Include(x => x.UserRole).Select(x => x.UserRole)
|
||||
.Select(x => new SendEmailUserDto()
|
||||
{
|
||||
UserTypeEnum = x.UserTypeEnum,
|
||||
FullName = x.FullName,
|
||||
UserWorkLanguage = x.IdentityUser.UserWorkLanguage,
|
||||
EMail=x.EMail,
|
||||
})
|
||||
.ToListAsync();
|
||||
|
||||
// CRC和CRA单独取
|
||||
var crcAndcraUserList = await _trialSiteRepository.Where(x => x.Id == inDto.SubjectVisit.TrialSiteId).SelectMany(x => x.CRCUserList.Select(y => y.UserRole)).ToListAsync();
|
||||
var crcAndcraUserList = await _trialSiteRepository.Where(x => x.Id == inDto.SubjectVisit.TrialSiteId).SelectMany(x => x.CRCUserList.Select(y => y.UserRole))
|
||||
.Select(x => new SendEmailUserDto()
|
||||
{
|
||||
UserTypeEnum = x.UserTypeEnum,
|
||||
FullName = x.FullName,
|
||||
UserWorkLanguage = x.IdentityUser.UserWorkLanguage,
|
||||
EMail = x.EMail,
|
||||
}).ToListAsync();
|
||||
trialUserList.AddRange(crcAndcraUserList);
|
||||
|
||||
// 根据场景确定收件人
|
||||
List<UserRole> toUserList = new List<UserRole>();
|
||||
List<UserRole> ccUserList = new List<UserRole>();
|
||||
List<SendEmailUserDto> toUserList = new List<SendEmailUserDto>();
|
||||
List<SendEmailUserDto> ccUserList = new List<SendEmailUserDto>();
|
||||
|
||||
var emailNoticeUserList = await _emailNoticeUserTypeRepository.Where(x => x.EmailNoticeConfigId == inDto.EmailNoticeConfig.Id).ToListAsync();
|
||||
var userTypeEnumList = emailNoticeUserList.Select(x => x.UserType).ToList();
|
||||
@@ -334,42 +349,55 @@ public class ImageConsumer(
|
||||
DictionaryList = dictionaryDtos
|
||||
});
|
||||
|
||||
foreach (var userinfo in toUserList)
|
||||
|
||||
var userWorkLanguageList = toUserList.Select(x => x.UserWorkLanguage).Distinct().ToList();
|
||||
|
||||
foreach (var workLanguage in userWorkLanguageList)
|
||||
{
|
||||
|
||||
var userinfoList = toUserList.Where(x => x.UserWorkLanguage == workLanguage).ToList();
|
||||
var messageToSend = new MimeMessage();
|
||||
// 发件地址
|
||||
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
|
||||
messageToSend.To.Add(new MailboxAddress(userinfo.FullName, userinfo.EMail));
|
||||
|
||||
foreach (var userinfo in userinfoList)
|
||||
{
|
||||
messageToSend.To.Add(new MailboxAddress(userinfo.FullName, userinfo.EMail));
|
||||
}
|
||||
|
||||
|
||||
// 添加抄送
|
||||
foreach (var ccUser in ccUserList)
|
||||
{
|
||||
messageToSend.Cc.Add(new MailboxAddress(ccUser.FullName, ccUser.EMail));
|
||||
}
|
||||
|
||||
var userNames = userinfoList.Select(x => x.FullName).ToList();
|
||||
|
||||
// 格式化邮件内容
|
||||
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
|
||||
{
|
||||
var subjectCode = inDto.SubjectVisit.Subject.Code;
|
||||
var topicStr = string.Format(input.topicStr, trialInfo.ResearchProgramNo, subjectCode, inDto.SubjectVisit.VisitName);
|
||||
var htmlBodyStr = string.Format(
|
||||
CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr),
|
||||
userinfo.FullName, // 用户名 {0}
|
||||
trialInfo.ExperimentName, // 项目 {1}
|
||||
subjectCode, // 受试者 {2}
|
||||
inDto.SubjectVisit.VisitName, // 访视 {3}
|
||||
dictionValue[0], // 是否加急 {4}
|
||||
dictionValue[1], // 审批结果 {5}
|
||||
_systemEmailConfig.SiteUrl // 链接 {6}
|
||||
);
|
||||
{
|
||||
var subjectCode = inDto.SubjectVisit.Subject.Code;
|
||||
var topicStr = string.Format(input.topicStr, trialInfo.ResearchProgramNo, subjectCode, inDto.SubjectVisit.VisitName);
|
||||
var htmlBodyStr = string.Format(
|
||||
CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr, workLanguage),
|
||||
string.Join(',', userNames), // 用户名 {0}
|
||||
trialInfo.ExperimentName, // 项目 {1}
|
||||
subjectCode, // 受试者 {2}
|
||||
inDto.SubjectVisit.VisitName, // 访视 {3}
|
||||
dictionValue[0], // 是否加急 {4}
|
||||
dictionValue[1], // 审批结果 {5}
|
||||
_systemEmailConfig.SiteUrl // 链接 {6}
|
||||
);
|
||||
|
||||
return (topicStr, htmlBodyStr);
|
||||
};
|
||||
return (topicStr, htmlBodyStr);
|
||||
};
|
||||
|
||||
|
||||
|
||||
await CommonEmailHelper.GetEmailSubejctAndHtmlInfoAndBuildAsync(inDto.EmailNoticeConfig, messageToSend, emailConfigFunc);
|
||||
|
||||
await SendEmailHelper.SendEmailAsync(messageToSend, trialInfo);
|
||||
|
||||
await CommonEmailHelper.GetEmailSubejctAndHtmlInfoAndBuildAsync(inDto.EmailNoticeConfig, messageToSend, emailConfigFunc, workLanguage);
|
||||
|
||||
await SendEmailHelper.SendTrialEmailAsync(messageToSend, trialInfo);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -446,11 +474,19 @@ public class ImageConsumer(
|
||||
var trialInfo = await _trialRepository.FirstOrDefaultAsync(t => t.Id == trialId);
|
||||
|
||||
// 根据不同场景获取不同角色的用户
|
||||
var trialUser = await _trialUseRoleRepository.Where(x => x.TrialId == trialId && !x.TrialUser.IsDeleted).Include(x => x.UserRole).Select(x => x.UserRole).ToListAsync();
|
||||
var trialUser = await _trialUseRoleRepository.Where(x => x.TrialId == trialId && !x.TrialUser.IsDeleted).Include(x => x.UserRole).Select(x => x.UserRole)
|
||||
.Select(x => new SendEmailUserDto()
|
||||
{
|
||||
UserTypeEnum = x.UserTypeEnum,
|
||||
FullName = x.FullName,
|
||||
UserWorkLanguage = x.IdentityUser.UserWorkLanguage,
|
||||
EMail = x.EMail,
|
||||
})
|
||||
.ToListAsync();
|
||||
|
||||
// 根据场景确定收件人
|
||||
List<UserRole> toUserList = new List<UserRole>();
|
||||
List<UserRole> ccUserList = new List<UserRole>();
|
||||
List<SendEmailUserDto> toUserList = new List<SendEmailUserDto>();
|
||||
List<SendEmailUserDto> ccUserList = new List<SendEmailUserDto>();
|
||||
|
||||
var emailNoticeUserList = await _emailNoticeUserTypeRepository.Where(x => x.EmailNoticeConfigId == emailNoticeConfig.Id).ToListAsync();
|
||||
|
||||
@@ -469,12 +505,19 @@ public class ImageConsumer(
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var userinfo in toUserList)
|
||||
var userWorkLanguageList = toUserList.Select(x => x.UserWorkLanguage).Distinct().ToList();
|
||||
|
||||
foreach (var workLanguage in userWorkLanguageList)
|
||||
{
|
||||
var userinfoList = toUserList.Where(x => x.UserWorkLanguage == workLanguage).ToList();
|
||||
var messageToSend = new MimeMessage();
|
||||
// 发件地址
|
||||
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
|
||||
messageToSend.To.Add(new MailboxAddress(userinfo.FullName, userinfo.EMail));
|
||||
|
||||
foreach (var userinfo in userinfoList)
|
||||
{
|
||||
messageToSend.To.Add(new MailboxAddress(userinfo.FullName, userinfo.EMail));
|
||||
}
|
||||
|
||||
// 添加抄送
|
||||
foreach (var ccUser in ccUserList)
|
||||
@@ -482,13 +525,15 @@ public class ImageConsumer(
|
||||
messageToSend.Cc.Add(new MailboxAddress(ccUser.FullName, ccUser.EMail));
|
||||
}
|
||||
|
||||
var userNames = userinfoList.Select(x => x.FullName).ToList();
|
||||
|
||||
// 格式化邮件内容
|
||||
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
|
||||
{
|
||||
var topicStr = string.Format(input.topicStr, trialInfo.ResearchProgramNo);
|
||||
var htmlBodyStr = string.Format(
|
||||
CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr),
|
||||
userinfo.FullName, // 用户名 {0}
|
||||
CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr, workLanguage),
|
||||
string.Join(',', userNames), // 用户名 {0}
|
||||
trialInfo.ExperimentName, // 项目 {1}
|
||||
"", // 受试者 {2} - 阅片人筛选不涉及受试者
|
||||
"", // 访视 {3} - 阅片人筛选不涉及访视
|
||||
@@ -500,9 +545,9 @@ public class ImageConsumer(
|
||||
return (topicStr, htmlBodyStr);
|
||||
};
|
||||
|
||||
await CommonEmailHelper.GetEmailSubejctAndHtmlInfoAndBuildAsync(emailNoticeConfig, messageToSend, emailConfigFunc);
|
||||
await CommonEmailHelper.GetEmailSubejctAndHtmlInfoAndBuildAsync(emailNoticeConfig, messageToSend, emailConfigFunc, workLanguage);
|
||||
|
||||
await SendEmailHelper.SendEmailAsync(messageToSend, trialInfo);
|
||||
await SendEmailHelper.SendTrialEmailAsync(messageToSend, trialInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using IRaCIS.Core.Application.Helper;
|
||||
using IRaCIS.Core.Application.Helper;
|
||||
using IRaCIS.Core.Application.MassTransit.Command;
|
||||
using IRaCIS.Core.Application.MassTransit.Consumer.Dto;
|
||||
using IRaCIS.Core.Domain;
|
||||
using IRaCIS.Core.Domain.BaseModel;
|
||||
using IRaCIS.Core.Domain.Models;
|
||||
@@ -68,7 +69,7 @@ public class UrgentMedicalReviewAddedEventConsumer(
|
||||
|
||||
|
||||
var criterion = await _readingQuestionCriterionTrialRepository.FirstOrDefaultAsync(x => x.Id == medicalReview.VisitTask.TrialReadingCriterionId);
|
||||
var userinfo = await _userRoleRepository.Where(x => x.Id == medicalReview.MedicalManagerUserId).FirstOrDefaultAsync();
|
||||
var userinfo = await _userRoleRepository.Where(x => x.Id == medicalReview.MedicalManagerUserId).Include(x => x.IdentityUser).FirstOrDefaultAsync();
|
||||
|
||||
var taskInfo = await _visitTaskRepository.Where(x => x.Id == medicalReview.VisitTaskId).Include(x => x.SourceSubjectVisit).Include(x => x.ReadModule).Include(x => x.Subject).FirstNotNullAsync();
|
||||
|
||||
@@ -78,7 +79,8 @@ public class UrgentMedicalReviewAddedEventConsumer(
|
||||
|
||||
var subjectVisit = await _subjectVisitRepository.Where(x => x.Id == visitid).FirstOrDefaultAsync();
|
||||
|
||||
|
||||
var workLanguage = userinfo.IdentityUser?.UserWorkLanguage;
|
||||
var userIsEn_US = workLanguage.HasValue ? workLanguage.Value == UserWorkLanguage.US : isEn_US;
|
||||
|
||||
var messageToSend = new MimeMessage();
|
||||
//发件地址
|
||||
@@ -86,14 +88,14 @@ public class UrgentMedicalReviewAddedEventConsumer(
|
||||
messageToSend.To.Add(new MailboxAddress(userinfo.FullName, userinfo.EMail));
|
||||
|
||||
var trialInfo = await _trialRepository.FirstOrDefaultAsync(t => t.Id == medicalReview.TrialId);
|
||||
var companyName = isEn_US ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
|
||||
var companyName = userIsEn_US ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
|
||||
|
||||
|
||||
var dictionValue = await CommonEmailHelper.TranslationDictionary(new TranslationDictionaryDto()
|
||||
{
|
||||
|
||||
DictionaryRepository = _dictionaryRepository,
|
||||
IsEn_US = isEn_US,
|
||||
IsEn_US = userIsEn_US,
|
||||
|
||||
|
||||
DictionaryList = new List<DictionaryDto>()
|
||||
@@ -110,7 +112,7 @@ public class UrgentMedicalReviewAddedEventConsumer(
|
||||
var subjectName = taskInfo.BlindSubjectCode.IsNullOrEmpty() ? taskInfo.Subject.Code : taskInfo.BlindSubjectCode;
|
||||
var topicStr = string.Format(input.topicStr, trialInfo.ResearchProgramNo, subjectName, taskInfo.TaskBlindName);
|
||||
var htmlBodyStr = string.Format(
|
||||
CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr),
|
||||
CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr, workLanguage),
|
||||
userinfo.FullName, // 用户名 {0}
|
||||
trialInfo.ExperimentName, // 项目 {1}
|
||||
criterion.CriterionName, // 阅片标准 {2}
|
||||
@@ -126,9 +128,9 @@ public class UrgentMedicalReviewAddedEventConsumer(
|
||||
return (topicStr, htmlBodyStr);
|
||||
};
|
||||
|
||||
await CommonEmailHelper.GetTrialEmailSubejctAndHtmlInfoAndBuildAsync(trialEmailConfig, messageToSend, emailConfigFunc);
|
||||
await CommonEmailHelper.GetTrialEmailSubejctAndHtmlInfoAndBuildAsync(trialEmailConfig, messageToSend, emailConfigFunc, workLanguage);
|
||||
|
||||
await SendEmailHelper.SendEmailAsync(messageToSend, trialInfo);
|
||||
await SendEmailHelper.SendTrialEmailAsync(messageToSend, trialInfo);
|
||||
|
||||
}
|
||||
|
||||
@@ -177,7 +179,7 @@ public class UrgentIRRepliedMedicalReviewConsumer(
|
||||
|
||||
|
||||
var criterion = await _readingQuestionCriterionTrialRepository.FirstOrDefaultAsync(x => x.Id == medicalReview.VisitTask.TrialReadingCriterionId);
|
||||
var userinfo = await _userRoleRepository.Where(x => x.Id == medicalReview.MedicalManagerUserId).FirstOrDefaultAsync();
|
||||
var userinfo = await _userRoleRepository.Where(x => x.Id == medicalReview.MedicalManagerUserId).Include(x => x.IdentityUser).FirstOrDefaultAsync();
|
||||
|
||||
var taskInfo = await _visitTaskRepository.Where(x => x.Id == medicalReview.VisitTaskId).Include(x => x.SourceSubjectVisit).Include(x => x.ReadModule).Include(x => x.Subject).FirstNotNullAsync();
|
||||
|
||||
@@ -187,6 +189,8 @@ public class UrgentIRRepliedMedicalReviewConsumer(
|
||||
|
||||
var subjectVisit = await _subjectVisitRepository.Where(x => x.Id == visitid).FirstOrDefaultAsync();
|
||||
|
||||
var workLanguage = userinfo.IdentityUser?.UserWorkLanguage;
|
||||
var userIsEn_US = workLanguage.HasValue ? workLanguage.Value == UserWorkLanguage.US : isEn_US;
|
||||
|
||||
|
||||
var messageToSend = new MimeMessage();
|
||||
@@ -195,14 +199,14 @@ public class UrgentIRRepliedMedicalReviewConsumer(
|
||||
messageToSend.To.Add(new MailboxAddress(userinfo.FullName, userinfo.EMail));
|
||||
|
||||
var trialInfo = await _trialRepository.FirstOrDefaultAsync(t => t.Id == medicalReview.TrialId);
|
||||
var companyName = isEn_US ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
|
||||
var companyName = userIsEn_US ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
|
||||
|
||||
|
||||
var dictionValue = await CommonEmailHelper.TranslationDictionary(new TranslationDictionaryDto()
|
||||
{
|
||||
|
||||
DictionaryRepository = _dictionaryRepository,
|
||||
IsEn_US = isEn_US,
|
||||
IsEn_US = userIsEn_US,
|
||||
|
||||
|
||||
DictionaryList = new List<DictionaryDto>()
|
||||
@@ -219,7 +223,7 @@ public class UrgentIRRepliedMedicalReviewConsumer(
|
||||
var subjectCode = taskInfo.BlindSubjectCode.IsNullOrEmpty() ? taskInfo.Subject.Code : taskInfo.BlindSubjectCode;
|
||||
var topicStr = string.Format(input.topicStr, trialInfo.ResearchProgramNo, subjectCode, taskInfo.TaskBlindName);
|
||||
var htmlBodyStr = string.Format(
|
||||
CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr),
|
||||
CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr, workLanguage),
|
||||
userinfo.FullName, // 用户名 {0}
|
||||
trialInfo.ExperimentName, // 项目 {1}
|
||||
criterion.CriterionName, // 阅片标准 {2}
|
||||
@@ -234,9 +238,9 @@ public class UrgentIRRepliedMedicalReviewConsumer(
|
||||
|
||||
return (topicStr, htmlBodyStr);
|
||||
};
|
||||
await CommonEmailHelper.GetTrialEmailSubejctAndHtmlInfoAndBuildAsync(trialEmailConfig, messageToSend, emailConfigFunc);
|
||||
await CommonEmailHelper.GetTrialEmailSubejctAndHtmlInfoAndBuildAsync(trialEmailConfig, messageToSend, emailConfigFunc, workLanguage);
|
||||
|
||||
await SendEmailHelper.SendEmailAsync(messageToSend, trialInfo);
|
||||
await SendEmailHelper.SendTrialEmailAsync(messageToSend, trialInfo);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -293,7 +297,7 @@ public class UrgentMIMRepliedMedicalReviewConsumer(
|
||||
var criterion = await _readingQuestionCriterionTrialRepository.FirstOrDefaultAsync(x => x.Id == medicalReview.VisitTask.TrialReadingCriterionId);
|
||||
var taskInfo = await _visitTaskRepository.Where(x => x.Id == medicalReview.VisitTaskId).Include(x => x.SourceSubjectVisit).Include(x => x.ReadModule).Include(x => x.Subject).FirstNotNullAsync();
|
||||
|
||||
var userinfo = await _userRoleRepository.Where(x => x.Id == taskInfo.DoctorUserId).FirstOrDefaultAsync();
|
||||
var userinfo = await _userRoleRepository.Where(x => x.Id == taskInfo.DoctorUserId).Include(x => x.IdentityUser).FirstOrDefaultAsync();
|
||||
|
||||
|
||||
|
||||
@@ -303,6 +307,9 @@ public class UrgentMIMRepliedMedicalReviewConsumer(
|
||||
|
||||
var subjectVisit = await _subjectVisitRepository.Where(x => x.Id == visitid).FirstOrDefaultAsync();
|
||||
|
||||
var workLanguage = userinfo.IdentityUser?.UserWorkLanguage;
|
||||
var userIsEn_US = workLanguage.HasValue ? workLanguage.Value == UserWorkLanguage.US : isEn_US;
|
||||
|
||||
|
||||
|
||||
var messageToSend = new MimeMessage();
|
||||
@@ -311,14 +318,14 @@ public class UrgentMIMRepliedMedicalReviewConsumer(
|
||||
messageToSend.To.Add(new MailboxAddress(userinfo.FullName, userinfo.EMail));
|
||||
|
||||
var trialInfo = await _trialRepository.FirstOrDefaultAsync(t => t.Id == medicalReview.TrialId);
|
||||
var companyName = isEn_US ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
|
||||
var companyName = userIsEn_US ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
|
||||
|
||||
|
||||
var dictionValue = await CommonEmailHelper.TranslationDictionary(new TranslationDictionaryDto()
|
||||
{
|
||||
|
||||
DictionaryRepository = _dictionaryRepository,
|
||||
IsEn_US = isEn_US,
|
||||
IsEn_US = userIsEn_US,
|
||||
|
||||
|
||||
DictionaryList = new List<DictionaryDto>()
|
||||
@@ -335,7 +342,7 @@ public class UrgentMIMRepliedMedicalReviewConsumer(
|
||||
var subjectCode = taskInfo.BlindSubjectCode.IsNullOrEmpty() ? taskInfo.Subject.Code : taskInfo.BlindSubjectCode;
|
||||
var topicStr = string.Format(input.topicStr, trialInfo.ResearchProgramNo, subjectCode, taskInfo.TaskBlindName);
|
||||
var htmlBodyStr = string.Format(
|
||||
CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr),
|
||||
CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr, workLanguage),
|
||||
userinfo.FullName, // 用户名 {0}
|
||||
trialInfo.ExperimentName, // 项目 {1}
|
||||
subjectCode, // 受试者 {2}
|
||||
@@ -352,8 +359,8 @@ public class UrgentMIMRepliedMedicalReviewConsumer(
|
||||
return (topicStr, htmlBodyStr);
|
||||
};
|
||||
|
||||
await CommonEmailHelper.GetTrialEmailSubejctAndHtmlInfoAndBuildAsync(trialEmailConfig, messageToSend, emailConfigFunc);
|
||||
await SendEmailHelper.SendEmailAsync(messageToSend, trialInfo);
|
||||
await CommonEmailHelper.GetTrialEmailSubejctAndHtmlInfoAndBuildAsync(trialEmailConfig, messageToSend, emailConfigFunc, workLanguage);
|
||||
await SendEmailHelper.SendTrialEmailAsync(messageToSend, trialInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -399,7 +406,15 @@ public class UrgentIRApplyedReReadingConsumer(
|
||||
|
||||
var doctorInfo = await _userRoleRepository.Where(x => x.Id == taskInfo.DoctorUserId).FirstOrDefaultAsync();
|
||||
|
||||
var trialUserList = await _trialUseRoleRepository.Where(x => x.TrialId == taskInfo.TrialId && x.TrialUser.IsDeleted==false).Include(x => x.UserRole).Select(x => x.UserRole).ToListAsync();
|
||||
var trialUserList = await _trialUseRoleRepository.Where(x => x.TrialId == taskInfo.TrialId && x.TrialUser.IsDeleted==false).Include(x => x.UserRole).Select(x => x.UserRole)
|
||||
.Select(x => new SendEmailUserDto()
|
||||
{
|
||||
UserTypeEnum = x.UserTypeEnum,
|
||||
FullName = x.FullName,
|
||||
UserWorkLanguage = x.IdentityUser.UserWorkLanguage,
|
||||
EMail = x.EMail,
|
||||
})
|
||||
.ToListAsync();
|
||||
|
||||
var userinfoList = trialUserList.Where(x => x.UserTypeEnum == UserTypeEnum.ProjectManager || x.UserTypeEnum == UserTypeEnum.APM).ToList();
|
||||
if (context.Message.ReReadingApplyState == ReReadingApplyState.TrialGroupHaveApplyed)
|
||||
@@ -412,37 +427,48 @@ public class UrgentIRApplyedReReadingConsumer(
|
||||
|
||||
var subjectVisit = await _subjectVisitRepository.Where(x => x.Id == visitid).FirstOrDefaultAsync();
|
||||
|
||||
var trialInfo = await _trialRepository.FirstOrDefaultAsync(t => t.Id == taskInfo.TrialId);
|
||||
|
||||
foreach (var userinfo in userinfoList)
|
||||
var userWorkLanguageList = userinfoList.Select(x => x.UserWorkLanguage).Distinct().ToList();
|
||||
|
||||
foreach (var workLanguage in userWorkLanguageList)
|
||||
{
|
||||
var messageToSend = new MimeMessage();
|
||||
//发件地址
|
||||
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
|
||||
messageToSend.To.Add(new MailboxAddress(userinfo.FullName, userinfo.EMail));
|
||||
|
||||
var trialInfo = await _trialRepository.FirstOrDefaultAsync(t => t.Id == taskInfo.TrialId);
|
||||
var companyName = isEn_US ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
|
||||
var langUserinfoList = userinfoList.Where(x => x.UserWorkLanguage == workLanguage).ToList();
|
||||
if (!langUserinfoList.Any()) continue;
|
||||
|
||||
var userIsEn_US = workLanguage == UserWorkLanguage.US;
|
||||
|
||||
var dictionValue = await CommonEmailHelper.TranslationDictionary(new TranslationDictionaryDto()
|
||||
{
|
||||
|
||||
DictionaryRepository = _dictionaryRepository,
|
||||
IsEn_US = isEn_US,
|
||||
IsEn_US = userIsEn_US,
|
||||
DictionaryList = new List<DictionaryDto>()
|
||||
{
|
||||
new DictionaryDto (){DictionaryCode= "ReadingCategory",EnumValue=taskInfo.ReadingCategory.GetEnumInt(), }, //任务类型
|
||||
new DictionaryDto (){DictionaryCode= "RequestReReadingResult",EnumValue="0", }, //审批结果 都是待审批
|
||||
}
|
||||
{
|
||||
new DictionaryDto (){DictionaryCode= "ReadingCategory",EnumValue=taskInfo.ReadingCategory.GetEnumInt(), }, //任务类型
|
||||
new DictionaryDto (){DictionaryCode= "RequestReReadingResult",EnumValue="0", }, //审批结果 都是待审批
|
||||
}
|
||||
});
|
||||
|
||||
var messageToSend = new MimeMessage();
|
||||
//发件地址
|
||||
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
|
||||
|
||||
foreach (var userinfo in langUserinfoList)
|
||||
{
|
||||
messageToSend.To.Add(new MailboxAddress(userinfo.FullName, userinfo.EMail));
|
||||
}
|
||||
|
||||
var companyName = userIsEn_US ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
|
||||
|
||||
var userNames = langUserinfoList.Select(x => x.FullName).ToList();
|
||||
|
||||
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
|
||||
{
|
||||
var subjectCode = taskInfo.BlindSubjectCode.IsNullOrEmpty() ? taskInfo.Subject.Code : taskInfo.BlindSubjectCode;
|
||||
var topicStr = string.Format(input.topicStr, trialInfo.ResearchProgramNo, subjectCode, taskInfo.TaskBlindName);
|
||||
var htmlBodyStr = string.Format(
|
||||
CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr),
|
||||
userinfo.FullName, // 用户名 {0}
|
||||
CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr, workLanguage),
|
||||
string.Join(',', userNames), // 用户名 {0}
|
||||
trialInfo.ExperimentName, // 项目 {1}
|
||||
subjectCode, // 受试者 {2}
|
||||
taskInfo.TaskBlindName, // 访视 {3}
|
||||
@@ -451,18 +477,14 @@ public class UrgentIRApplyedReReadingConsumer(
|
||||
criterion.CriterionName, // 阅片标准 {6}
|
||||
dictionValue[1], // 审批结果 {7}
|
||||
_systemEmailConfig.SiteUrl // 链接 {8}
|
||||
|
||||
|
||||
|
||||
|
||||
);
|
||||
|
||||
return (topicStr, htmlBodyStr);
|
||||
};
|
||||
|
||||
await CommonEmailHelper.GetTrialEmailSubejctAndHtmlInfoAndBuildAsync(trialEmailConfig, messageToSend, emailConfigFunc);
|
||||
await CommonEmailHelper.GetTrialEmailSubejctAndHtmlInfoAndBuildAsync(trialEmailConfig, messageToSend, emailConfigFunc, workLanguage);
|
||||
|
||||
await SendEmailHelper.SendEmailAsync(messageToSend, trialInfo);
|
||||
await SendEmailHelper.SendTrialEmailAsync(messageToSend, trialInfo);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,27 +1,9 @@
|
||||
using DocumentFormat.OpenXml.Office2013.Excel;
|
||||
using DocumentFormat.OpenXml.Spreadsheet;
|
||||
using DocumentFormat.OpenXml.Vml;
|
||||
using DocumentFormat.OpenXml.Wordprocessing;
|
||||
using IRaCIS.Application.Contracts;
|
||||
using IRaCIS.Core.Application.Contracts;
|
||||
using IRaCIS.Core.Application.Helper;
|
||||
using IRaCIS.Core.Application.MassTransit.Command;
|
||||
using IRaCIS.Core.Application.Helper;
|
||||
using IRaCIS.Core.Domain;
|
||||
using IRaCIS.Core.Domain.BaseModel;
|
||||
using IRaCIS.Core.Domain.Models;
|
||||
using IRaCIS.Core.Domain.Share;
|
||||
using MassTransit;
|
||||
using Microsoft.AspNetCore.Components.Routing;
|
||||
using Microsoft.Extensions.Options;
|
||||
using MimeKit;
|
||||
using NPOI.SS.Formula.Functions;
|
||||
using NPOI.Util;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace IRaCIS.Core.Application.MassTransit.Consumer;
|
||||
|
||||
@@ -57,73 +39,85 @@ public class UserSiteSurveySubmitedEventConsumer(
|
||||
if (emailConfig != null)
|
||||
{
|
||||
var trialInfo = await _trialRepository.FirstOrDefaultAsync(t => t.Id == trialId);
|
||||
var siteInfo = await _trialSiteRepository.FirstOrDefaultAsync(t => t.TrialId == trialId && t.Id == siteSurveyInfo.TrialSiteId, true);
|
||||
|
||||
|
||||
var trialUserList = await _trialUserRoleRepository.Where(t => t.TrialId == siteSurveyInfo.TrialId && t.TrialUser.IsDeleted == false)
|
||||
.Where(t => t.UserRole.UserTypeEnum == UserTypeEnum.SPM || t.UserRole.UserTypeEnum == UserTypeEnum.CPM || t.UserRole.UserTypeEnum == UserTypeEnum.ProjectManager || t.UserRole.UserTypeEnum == UserTypeEnum.APM)
|
||||
.Select(t => new { t.UserRole.FullName, t.UserRole.IdentityUser.EMail, t.UserRole.UserTypeEnum }).ToListAsync();
|
||||
.Select(t => new { t.UserRole.FullName, t.UserRole.IdentityUser.EMail, t.UserRole.UserTypeEnum, t.UserRole.IdentityUser.UserWorkLanguage }).ToListAsync();
|
||||
|
||||
var sPMOrCPMList = trialUserList.Where(t => t.UserTypeEnum == UserTypeEnum.SPM || t.UserTypeEnum == UserTypeEnum.CPM).ToList();
|
||||
var pmAndAPMList = trialUserList.Where(t => t.UserTypeEnum == UserTypeEnum.ProjectManager || t.UserTypeEnum == UserTypeEnum.APM).ToList();
|
||||
|
||||
var messageToSend = new MimeMessage();
|
||||
|
||||
var toUserName = string.Empty;
|
||||
|
||||
//有SPM 并且参与
|
||||
if (trialInfo.IsSPMJoinSiteSurvey && sPMOrCPMList.Count > 0)
|
||||
// 遍历语言枚举 在底层判断收件人是否为空,决定是否跳过邮件发送,避免每个邮件场景的地方都重复判断
|
||||
foreach (UserWorkLanguage workLanguage in Enum.GetValues<UserWorkLanguage>())
|
||||
{
|
||||
foreach (var user in sPMOrCPMList)
|
||||
//重新设置当前发送邮件的语言
|
||||
isEn_US = workLanguage == UserWorkLanguage.US;
|
||||
|
||||
var messageToSend = new MimeMessage();
|
||||
|
||||
var toUserName = string.Empty;
|
||||
|
||||
//有SPM 并且参与
|
||||
if (trialInfo.IsSPMJoinSiteSurvey && sPMOrCPMList.Count > 0)
|
||||
{
|
||||
messageToSend.To.Add(new MailboxAddress(user.FullName, user.EMail));
|
||||
var lan_SPMOrCPMList = sPMOrCPMList.Where(t => t.UserWorkLanguage == workLanguage);
|
||||
|
||||
foreach (var user in lan_SPMOrCPMList)
|
||||
{
|
||||
messageToSend.To.Add(new MailboxAddress(user.FullName, user.EMail));
|
||||
}
|
||||
|
||||
toUserName = string.Join('、', lan_SPMOrCPMList.Select(t => t.FullName));
|
||||
|
||||
foreach (var user in pmAndAPMList)
|
||||
{
|
||||
messageToSend.Cc.Add(new MailboxAddress(user.FullName, user.EMail));
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
var lan_pmAndAPMList = pmAndAPMList.Where(t => t.UserWorkLanguage == workLanguage);
|
||||
|
||||
foreach (var user in lan_pmAndAPMList)
|
||||
{
|
||||
messageToSend.To.Add(new MailboxAddress(user.FullName, user.EMail));
|
||||
}
|
||||
|
||||
toUserName = string.Join('、', lan_pmAndAPMList.Select(t => t.FullName));
|
||||
}
|
||||
|
||||
toUserName = string.Join('、', sPMOrCPMList.Select(t => t.FullName));
|
||||
//发件地址
|
||||
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
|
||||
|
||||
foreach (var user in pmAndAPMList)
|
||||
|
||||
var companyName = isEn_US ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
|
||||
|
||||
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
|
||||
{
|
||||
messageToSend.Cc.Add(new MailboxAddress(user.FullName, user.EMail));
|
||||
}
|
||||
var topicStr = string.Format(input.topicStr, trialInfo.ResearchProgramNo);
|
||||
var htmlBodyStr = string.Format(CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr, workLanguage),
|
||||
toUserName,
|
||||
siteInfo.TrialSiteCode,
|
||||
siteInfo.TrialSiteAliasName,
|
||||
|
||||
siteSurveyInfo.UserName,
|
||||
siteSurveyInfo.Email,
|
||||
siteSurveyInfo.Phone,
|
||||
_systemEmailConfig.SiteUrl
|
||||
);
|
||||
|
||||
return (topicStr, htmlBodyStr);
|
||||
};
|
||||
|
||||
|
||||
await CommonEmailHelper.GetEmailSubejctAndHtmlInfoAndBuildAsync(emailConfig, messageToSend, emailConfigFunc, workLanguage);
|
||||
|
||||
await SendEmailHelper.SendTrialEmailAsync(messageToSend, trialInfo);
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var user in pmAndAPMList)
|
||||
{
|
||||
messageToSend.To.Add(new MailboxAddress(user.FullName, user.EMail));
|
||||
}
|
||||
|
||||
toUserName = string.Join('、', pmAndAPMList.Select(t => t.FullName));
|
||||
}
|
||||
|
||||
//发件地址
|
||||
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
|
||||
|
||||
|
||||
var siteInfo = await _trialSiteRepository.FirstOrDefaultAsync(t => t.TrialId == trialId && t.Id == siteSurveyInfo.TrialSiteId, true);
|
||||
|
||||
var companyName = isEn_US ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
|
||||
|
||||
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
|
||||
{
|
||||
var topicStr = string.Format(input.topicStr, trialInfo.ResearchProgramNo);
|
||||
var htmlBodyStr = string.Format(CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr),
|
||||
toUserName,
|
||||
siteInfo.TrialSiteCode,
|
||||
siteInfo.TrialSiteAliasName,
|
||||
|
||||
siteSurveyInfo.UserName,
|
||||
siteSurveyInfo.Email,
|
||||
siteSurveyInfo.Phone,
|
||||
_systemEmailConfig.SiteUrl
|
||||
);
|
||||
|
||||
return (topicStr, htmlBodyStr);
|
||||
};
|
||||
|
||||
|
||||
await CommonEmailHelper.GetEmailSubejctAndHtmlInfoAndBuildAsync(emailConfig, messageToSend, emailConfigFunc);
|
||||
|
||||
await SendEmailHelper.SendEmailAsync(messageToSend, trialInfo);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -152,61 +146,74 @@ public class SiteSurveySPMSubmitedEventConsumer(
|
||||
|
||||
var trialId = siteSurveyInfo.TrialId;
|
||||
|
||||
var trialInfo = await _trialRepository.FirstOrDefaultAsync(t => t.Id == trialId);
|
||||
|
||||
var siteInfo = await _trialSiteRepository.FirstOrDefaultAsync(t => t.TrialId == trialId && t.Id == siteSurveyInfo.TrialSiteId, true);
|
||||
|
||||
var trialUserList = _trialUserRoleRepository.Where(t => t.TrialId == trialId && t.TrialUser.IsDeleted == false)
|
||||
.Where(t => t.UserRole.UserTypeEnum == UserTypeEnum.SPM || t.UserRole.UserTypeEnum == UserTypeEnum.CPM || t.UserRole.UserTypeEnum == UserTypeEnum.ProjectManager || t.UserRole.UserTypeEnum == UserTypeEnum.APM)
|
||||
.Select(t => new { t.UserRole.IdentityUser.EMail, t.UserRole.FullName, t.UserRole.UserTypeEnum, t.UserRole.IdentityUser.UserWorkLanguage }).ToList();
|
||||
|
||||
var scenario = EmailBusinessScenario.Approval_SubmitSiteSurvey;
|
||||
|
||||
var emailConfig = _emailNoticeConfigrepository.Where(t => t.BusinessScenarioEnum == scenario && t.IsAutoSend && t.IsEnable).FirstOrDefault();
|
||||
|
||||
if (emailConfig != null)
|
||||
{
|
||||
var messageToSend = new MimeMessage();
|
||||
|
||||
var trialUserList = _trialUserRoleRepository.Where(t => t.TrialId == trialId && t.TrialUser.IsDeleted == false)
|
||||
.Where(t => t.UserRole.UserTypeEnum == UserTypeEnum.SPM || t.UserRole.UserTypeEnum == UserTypeEnum.CPM || t.UserRole.UserTypeEnum == UserTypeEnum.ProjectManager || t.UserRole.UserTypeEnum == UserTypeEnum.APM)
|
||||
.Select(t => new { t.UserRole.IdentityUser.EMail, t.UserRole.FullName, t.UserRole.UserTypeEnum }).ToList();
|
||||
|
||||
var sPMOrCPMList = trialUserList.Where(t => t.UserTypeEnum == UserTypeEnum.SPM || t.UserTypeEnum == UserTypeEnum.CPM).ToList();
|
||||
var pmAndAPMList = trialUserList.Where(t => t.UserTypeEnum == UserTypeEnum.ProjectManager || t.UserTypeEnum == UserTypeEnum.APM).ToList();
|
||||
|
||||
var toUserName = string.Empty;
|
||||
|
||||
foreach (var item in pmAndAPMList)
|
||||
// 遍历语言枚举 在底层判断收件人是否为空,决定是否跳过邮件发送,避免每个邮件场景的地方都重复判断
|
||||
foreach (UserWorkLanguage workLanguage in Enum.GetValues<UserWorkLanguage>())
|
||||
{
|
||||
messageToSend.To.Add(new MailboxAddress(item.FullName, item.EMail));
|
||||
//重新设置当前发送邮件的语言
|
||||
isEn_US = workLanguage == UserWorkLanguage.US;
|
||||
|
||||
|
||||
var sPMOrCPMList = trialUserList.Where(t => t.UserTypeEnum == UserTypeEnum.SPM || t.UserTypeEnum == UserTypeEnum.CPM).ToList();
|
||||
var pmAndAPMList = trialUserList.Where(t => t.UserTypeEnum == UserTypeEnum.ProjectManager || t.UserTypeEnum == UserTypeEnum.APM).ToList();
|
||||
|
||||
var messageToSend = new MimeMessage();
|
||||
|
||||
var toUserName = string.Empty;
|
||||
|
||||
var lan_pmAndAPMList = pmAndAPMList.Where(t => t.UserWorkLanguage == workLanguage);
|
||||
|
||||
foreach (var item in lan_pmAndAPMList)
|
||||
{
|
||||
messageToSend.To.Add(new MailboxAddress(item.FullName, item.EMail));
|
||||
|
||||
toUserName = string.Join('、', lan_pmAndAPMList.Select(t => t.FullName));
|
||||
}
|
||||
|
||||
//发件地址
|
||||
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
|
||||
|
||||
var companyName = isEn_US ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
|
||||
|
||||
|
||||
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
|
||||
{
|
||||
var topicStr = string.Format(input.topicStr, trialInfo.ResearchProgramNo);
|
||||
var htmlBodyStr = string.Format(CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr, workLanguage),
|
||||
toUserName,
|
||||
siteInfo.TrialSiteCode, //中心编号
|
||||
siteInfo.TrialSiteAliasName,//中心名称
|
||||
|
||||
siteSurveyInfo.UserName, //联系人
|
||||
siteSurveyInfo.Email, //联系邮箱
|
||||
siteSurveyInfo.Phone, //联系电话
|
||||
_systemEmailConfig.SiteUrl
|
||||
);
|
||||
|
||||
return (topicStr, htmlBodyStr);
|
||||
};
|
||||
|
||||
await CommonEmailHelper.GetEmailSubejctAndHtmlInfoAndBuildAsync(emailConfig, messageToSend, emailConfigFunc, workLanguage);
|
||||
|
||||
await SendEmailHelper.SendTrialEmailAsync(messageToSend, trialInfo);
|
||||
|
||||
toUserName = string.Join('、', pmAndAPMList.Select(t => t.FullName));
|
||||
}
|
||||
|
||||
//发件地址
|
||||
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
|
||||
|
||||
var trialInfo = await _trialRepository.FirstOrDefaultAsync(t => t.Id == trialId);
|
||||
|
||||
var siteInfo = await _trialSiteRepository.FirstOrDefaultAsync(t => t.TrialId == trialId && t.Id == siteSurveyInfo.TrialSiteId, true);
|
||||
|
||||
|
||||
var companyName = isEn_US ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
|
||||
|
||||
|
||||
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
|
||||
{
|
||||
var topicStr = string.Format(input.topicStr, trialInfo.ResearchProgramNo);
|
||||
var htmlBodyStr = string.Format(CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr),
|
||||
toUserName,
|
||||
siteInfo.TrialSiteCode, //中心编号
|
||||
siteInfo.TrialSiteAliasName,//中心名称
|
||||
|
||||
siteSurveyInfo.UserName, //联系人
|
||||
siteSurveyInfo.Email, //联系邮箱
|
||||
siteSurveyInfo.Phone, //联系电话
|
||||
_systemEmailConfig.SiteUrl
|
||||
);
|
||||
|
||||
return (topicStr, htmlBodyStr);
|
||||
};
|
||||
|
||||
await CommonEmailHelper.GetEmailSubejctAndHtmlInfoAndBuildAsync(emailConfig, messageToSend, emailConfigFunc);
|
||||
|
||||
await SendEmailHelper.SendEmailAsync(messageToSend, trialInfo);
|
||||
}
|
||||
|
||||
|
||||
@@ -235,92 +242,136 @@ public class SiteSurverRejectedEventConsumer(
|
||||
|
||||
var trialSiteSurveyId = context.Message.TrialSiteSurveyId;
|
||||
|
||||
var siteSurveyInfo = _trialSiteSurveyRepository.Where(t => t.Id == trialSiteSurveyId ,ignoreQueryFilters:true).FirstOrDefault().IfNullThrowException();
|
||||
var siteSurveyInfo = _trialSiteSurveyRepository.Where(t => t.Id == trialSiteSurveyId, ignoreQueryFilters: true).FirstOrDefault().IfNullThrowException();
|
||||
|
||||
var trialId = siteSurveyInfo.TrialId;
|
||||
|
||||
var trialInfo = await _trialRepository.FirstOrDefaultAsync(t => t.Id == trialId);
|
||||
|
||||
var siteInfo = await _trialSiteRepository.FirstOrDefaultAsync(t => t.TrialId == trialId && t.Id == siteSurveyInfo.TrialSiteId, true);
|
||||
|
||||
var scenario = EmailBusinessScenario.SiteSurveyReject;
|
||||
|
||||
var emailConfig = _emailNoticeConfigrepository.Where(t => t.BusinessScenarioEnum == scenario && t.IsAutoSend && t.IsEnable).FirstOrDefault();
|
||||
|
||||
if (emailConfig != null)
|
||||
{
|
||||
|
||||
|
||||
var messageToSend = new MimeMessage();
|
||||
|
||||
var toUserName = siteSurveyInfo.UserName;
|
||||
|
||||
if (context.Message.IsHaveSPMOrCPM)
|
||||
// 遍历语言枚举 在底层判断收件人是否为空,决定是否跳过邮件发送,避免每个邮件场景的地方都重复判断
|
||||
foreach (UserWorkLanguage workLanguage in Enum.GetValues<UserWorkLanguage>())
|
||||
{
|
||||
//PM 驳回到SPM
|
||||
if (siteSurveyInfo.State == TrialSiteSurveyEnum.CRCSubmitted)
|
||||
//重新设置当前发送邮件的语言
|
||||
isEn_US = workLanguage == UserWorkLanguage.US;
|
||||
|
||||
|
||||
var messageToSend = new MimeMessage();
|
||||
|
||||
var toUserName = siteSurveyInfo.UserName;
|
||||
|
||||
if (context.Message.IsHaveSPMOrCPM)
|
||||
{
|
||||
//var user = await _userRoleRepository.FirstOrDefaultAsync(t => t.Id == siteSurveyInfo.PreliminaryUserId);
|
||||
////PM 驳回到SPM
|
||||
//if (siteSurveyInfo.State == TrialSiteSurveyEnum.CRCSubmitted)
|
||||
//{
|
||||
|
||||
//name = user.FullName;
|
||||
// var sPMOrCPMList = _trialUserRoleRepository.Where(t => t.TrialId == trialId && t.TrialUser.IsDeleted == false)
|
||||
// .Where(t => t.UserRole.UserTypeEnum == UserTypeEnum.SPM || t.UserRole.UserTypeEnum == UserTypeEnum.CPM)
|
||||
// .Select(t => new { t.UserRole.IdentityUser.EMail, t.UserRole.FullName, t.UserRole.UserTypeEnum, t.UserRole.IdentityUser.UserWorkLanguage }).ToList();
|
||||
|
||||
var sPMOrCPMList = _trialUserRoleRepository.Where(t => t.TrialId == trialId && t.TrialUser.IsDeleted == false)
|
||||
.Where(t => t.UserRole.UserTypeEnum == UserTypeEnum.SPM || t.UserRole.UserTypeEnum == UserTypeEnum.CPM)
|
||||
.Select(t => new { t.UserRole.IdentityUser.EMail, t.UserRole.FullName, t.UserRole.UserTypeEnum }).ToList();
|
||||
// var lan_SPMOrCPMList = sPMOrCPMList.Where(t => t.UserWorkLanguage == workLanguage);
|
||||
|
||||
// foreach (var user in lan_SPMOrCPMList)
|
||||
// {
|
||||
// messageToSend.To.Add(new MailboxAddress(user.FullName, user.EMail));
|
||||
// }
|
||||
|
||||
foreach (var user in sPMOrCPMList)
|
||||
// toUserName = string.Join('、', lan_SPMOrCPMList.Select(t => t.FullName));
|
||||
|
||||
//}
|
||||
////SPM 驳回到CRC
|
||||
//else if (siteSurveyInfo.State == TrialSiteSurveyEnum.ToSubmit)
|
||||
//{
|
||||
// //使用中心国家语言 一致才发送
|
||||
// if ((siteInfo.Country == StaticData.SiteCountry.US && isEn_US) || (siteInfo.Country == StaticData.SiteCountry.CN && isEn_US == false))
|
||||
// {
|
||||
// messageToSend.To.Add(new MailboxAddress(toUserName, siteSurveyInfo.Email));
|
||||
|
||||
// }
|
||||
|
||||
//}
|
||||
|
||||
// PM 驳回到CRC
|
||||
if (siteSurveyInfo.State == TrialSiteSurveyEnum.ToSubmit)
|
||||
{
|
||||
messageToSend.To.Add(new MailboxAddress(user.FullName, user.EMail));
|
||||
//使用中心国家语言 一致才发送
|
||||
if ((siteInfo.Country == StaticData.SiteCountry.US && isEn_US) || (siteInfo.Country == StaticData.SiteCountry.CN && isEn_US == false))
|
||||
{
|
||||
messageToSend.To.Add(new MailboxAddress(toUserName, siteSurveyInfo.Email));
|
||||
|
||||
}
|
||||
|
||||
var sPMOrCPMList = _trialUserRoleRepository.Where(t => t.TrialId == trialId && t.TrialUser.IsDeleted == false)
|
||||
.Where(t => t.UserRole.UserTypeEnum == UserTypeEnum.SPM || t.UserRole.UserTypeEnum == UserTypeEnum.CPM)
|
||||
.Select(t => new { t.UserRole.IdentityUser.EMail, t.UserRole.FullName, t.UserRole.UserTypeEnum, t.UserRole.IdentityUser.UserWorkLanguage }).ToList();
|
||||
|
||||
var lan_SPMOrCPMList = sPMOrCPMList.Where(t => t.UserWorkLanguage == workLanguage);
|
||||
|
||||
foreach (var user in lan_SPMOrCPMList)
|
||||
{
|
||||
messageToSend.Cc.Add(new MailboxAddress(user.FullName, user.EMail));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
toUserName = string.Join('、', sPMOrCPMList.Select(t => t.FullName));
|
||||
|
||||
}
|
||||
//SPM 驳回到CRC
|
||||
else if (siteSurveyInfo.State == TrialSiteSurveyEnum.ToSubmit)
|
||||
else
|
||||
{
|
||||
messageToSend.To.Add(new MailboxAddress(toUserName, siteSurveyInfo.Email));
|
||||
//没有SPM PM驳回到CRC
|
||||
|
||||
//使用中心国家语言 一致才发送
|
||||
if ((siteInfo.Country == StaticData.SiteCountry.US && isEn_US) || (siteInfo.Country == StaticData.SiteCountry.CN && isEn_US == false))
|
||||
{
|
||||
messageToSend.To.Add(new MailboxAddress(toUserName, siteSurveyInfo.Email));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
//没有SPM PM驳回到CRC
|
||||
Uri uri = new Uri(_systemEmailConfig.SiteUrl);
|
||||
|
||||
// 获取 Scheme + Host(不包含路径)
|
||||
string baseUrl = uri.GetLeftPart(UriPartial.Authority);
|
||||
|
||||
//发件地址
|
||||
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
|
||||
|
||||
var companyName = isEn_US ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
|
||||
|
||||
|
||||
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
|
||||
{
|
||||
var topicStr = string.Format(input.topicStr, companyName, trialInfo.ResearchProgramNo);
|
||||
var htmlBodyStr = string.Format(CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr, workLanguage),
|
||||
toUserName,
|
||||
trialInfo.TrialCode,
|
||||
trialInfo.ResearchProgramNo,
|
||||
trialInfo.ExperimentName,
|
||||
|
||||
siteInfo.TrialSiteCode, //中心编号
|
||||
siteInfo.TrialSiteAliasName,//中心名称
|
||||
siteSurveyInfo.LatestBackReason, //驳回原因
|
||||
$"{baseUrl}/researchLogin?trialId={trialId}", //链接
|
||||
(siteSurveyInfo.State == TrialSiteSurveyEnum.ToSubmit ? "inline - block" : "none"),
|
||||
trialInfo.LinkVerificationCode.IsNullOrEmpty()? trialInfo.ResearchProgramNo: trialInfo.LinkVerificationCode
|
||||
);
|
||||
|
||||
return (topicStr, htmlBodyStr);
|
||||
};
|
||||
|
||||
await CommonEmailHelper.GetEmailSubejctAndHtmlInfoAndBuildAsync(emailConfig, messageToSend, emailConfigFunc);
|
||||
|
||||
await SendEmailHelper.SendTrialEmailAsync(messageToSend, trialInfo);
|
||||
|
||||
messageToSend.To.Add(new MailboxAddress(siteSurveyInfo.UserName, siteSurveyInfo.Email));
|
||||
}
|
||||
|
||||
//发件地址
|
||||
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
|
||||
|
||||
|
||||
var trialInfo = await _trialRepository.FirstOrDefaultAsync(t => t.Id == trialId);
|
||||
|
||||
var siteInfo = await _trialSiteRepository.FirstOrDefaultAsync(t => t.TrialId == trialId && t.Id == siteSurveyInfo.TrialSiteId, true);
|
||||
|
||||
|
||||
var companyName = isEn_US ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
|
||||
|
||||
|
||||
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
|
||||
{
|
||||
var topicStr = string.Format(input.topicStr, companyName,trialInfo.ResearchProgramNo);
|
||||
var htmlBodyStr = string.Format(CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr),
|
||||
toUserName,
|
||||
trialInfo.TrialCode,
|
||||
trialInfo.ResearchProgramNo,
|
||||
trialInfo.ExperimentName,
|
||||
|
||||
siteInfo.TrialSiteCode, //中心编号
|
||||
siteInfo.TrialSiteAliasName,//中心名称
|
||||
siteSurveyInfo.LatestBackReason, //驳回原因
|
||||
_systemEmailConfig.SiteUrl, //链接
|
||||
(siteSurveyInfo.State == TrialSiteSurveyEnum.ToSubmit ? "inline - block" : "none")
|
||||
);
|
||||
|
||||
return (topicStr, htmlBodyStr);
|
||||
};
|
||||
|
||||
await CommonEmailHelper.GetEmailSubejctAndHtmlInfoAndBuildAsync(emailConfig, messageToSend, emailConfigFunc);
|
||||
|
||||
await SendEmailHelper.SendEmailAsync(messageToSend, trialInfo);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ public class CRCSubmitedAndQCToAuditEventConsumer(
|
||||
private readonly SystemEmailSendConfig _systemEmailConfig = systemEmailConfig.CurrentValue;
|
||||
public async Task Consume(ConsumeContext<CRCSubmitedAndQCToAuditEvent> context)
|
||||
{
|
||||
Console.WriteLine("发送(005,006) 【加急项目所有IQC待领取质控任务】邮件!!!");
|
||||
Log.Logger.Warning("发送(005,006) 【加急项目所有IQC待领取质控任务】邮件!!!");
|
||||
var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;
|
||||
|
||||
var subjectVisitId = context.Message.SubjectVisitId;
|
||||
@@ -49,80 +49,91 @@ public class CRCSubmitedAndQCToAuditEventConsumer(
|
||||
|
||||
var trialEmailConfig = _trialEmailNoticeConfigrepository.Where(t => t.TrialId == trialId && t.BusinessScenarioEnum == scenario && t.IsAutoSend && t.IsEnable).FirstOrDefault();
|
||||
|
||||
var trialUserList = await _trialUseRoleRepository.Where(x => x.TrialId == subjectVisit.TrialId && x.TrialUser.IsDeleted == false)
|
||||
.Select(t => new { t.UserRole.IdentityUser.EMail, t.UserRole.FullName, t.UserRole.UserTypeEnum, t.UserRole.IdentityUser.UserWorkLanguage }).ToListAsync();
|
||||
|
||||
var trialInfo = await _trialRepository.FirstOrDefaultAsync(t => t.Id == subjectVisit.TrialId);
|
||||
|
||||
if (trialEmailConfig != null)
|
||||
{
|
||||
|
||||
var trialUserList = await _trialUseRoleRepository.Where(x => x.TrialId == subjectVisit.TrialId && x.TrialUser.IsDeleted == false).Include(x => x.UserRole).Select(x => x.UserRole).ToListAsync();
|
||||
|
||||
var userinfoList = trialUserList.Where(x => x.UserTypeEnum == UserTypeEnum.IQC).ToList();
|
||||
|
||||
|
||||
var pmandAPm = trialUserList.Where(x => x.UserTypeEnum == UserTypeEnum.APM || x.UserTypeEnum == UserTypeEnum.ProjectManager).ToList();
|
||||
|
||||
var trialInfo = await _trialRepository.FirstOrDefaultAsync(t => t.Id == subjectVisit.TrialId);
|
||||
|
||||
var auditStateCode = "AuditStatePE";
|
||||
|
||||
if (trialInfo.QCProcessEnum == TrialQCProcess.DoubleAudit)
|
||||
// 遍历语言枚举 在底层判断收件人是否为空,决定是否跳过邮件发送,避免每个邮件场景的地方都重复判断
|
||||
foreach (UserWorkLanguage workLanguage in Enum.GetValues<UserWorkLanguage>())
|
||||
{
|
||||
auditStateCode = "AuditStateRC";
|
||||
}
|
||||
//重新设置当前发送邮件的语言
|
||||
isEn_US = workLanguage == UserWorkLanguage.US;
|
||||
|
||||
|
||||
var iqcList = trialUserList.Where(x => x.UserTypeEnum == UserTypeEnum.IQC).Where(t => t.UserWorkLanguage == workLanguage).ToList();
|
||||
|
||||
var dictionValue = await CommonEmailHelper.TranslationDictionary(new TranslationDictionaryDto()
|
||||
{
|
||||
|
||||
DictionaryRepository = _dictionaryRepository,
|
||||
IsEn_US = isEn_US,
|
||||
DictionaryList = new List<DictionaryDto>()
|
||||
var pmandAPm = trialUserList.Where(x => x.UserTypeEnum == UserTypeEnum.APM || x.UserTypeEnum == UserTypeEnum.ProjectManager).ToList();
|
||||
|
||||
|
||||
var auditStateCode = "AuditStatePE";
|
||||
|
||||
if (trialInfo.QCProcessEnum == TrialQCProcess.DoubleAudit)
|
||||
{
|
||||
auditStateCode = "AuditStateRC";
|
||||
}
|
||||
|
||||
var dictionValue = await CommonEmailHelper.TranslationDictionary(new TranslationDictionaryDto()
|
||||
{
|
||||
|
||||
DictionaryRepository = _dictionaryRepository,
|
||||
IsEn_US = isEn_US,
|
||||
DictionaryList = new List<DictionaryDto>()
|
||||
{
|
||||
new DictionaryDto (){DictionaryCode= auditStateCode,EnumValue=subjectVisit.AuditState.GetEnumInt(), }, //审核状态
|
||||
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
var messageToSend = new MimeMessage();
|
||||
//发件地址
|
||||
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
|
||||
var messageToSend = new MimeMessage();
|
||||
//发件地址
|
||||
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
|
||||
|
||||
|
||||
foreach (var userinfo in iqcList)
|
||||
{
|
||||
messageToSend.To.Add(new MailboxAddress(userinfo.FullName, userinfo.EMail));
|
||||
}
|
||||
|
||||
var userNames = iqcList.Select(x => x.FullName).ToList();
|
||||
|
||||
foreach (var pm in pmandAPm)
|
||||
{
|
||||
messageToSend.Cc.Add(new MailboxAddress(pm.FullName, pm.EMail));
|
||||
}
|
||||
|
||||
var companyName = isEn_US ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
|
||||
|
||||
|
||||
|
||||
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
|
||||
{
|
||||
var subjectCode = subjectVisit.Subject.Code;
|
||||
var topicStr = string.Format(input.topicStr, trialInfo.ResearchProgramNo, subjectCode, subjectVisit.VisitName);
|
||||
var htmlBodyStr = string.Format(
|
||||
CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr, workLanguage),
|
||||
string.Join(',', userNames), // 用户名 {0}
|
||||
trialInfo.ExperimentName, // 项目 {1}
|
||||
subjectCode, // 受试者 {2}
|
||||
subjectVisit.VisitName, // 访视 {3}
|
||||
dictionValue[0], // 审核状态 {4}
|
||||
_systemEmailConfig.SiteUrl // 链接 {5}
|
||||
);
|
||||
|
||||
return (topicStr, htmlBodyStr);
|
||||
};
|
||||
|
||||
await CommonEmailHelper.GetTrialEmailSubejctAndHtmlInfoAndBuildAsync(trialEmailConfig, messageToSend, emailConfigFunc, workLanguage);
|
||||
|
||||
await SendEmailHelper.SendTrialEmailAsync(messageToSend, trialInfo);
|
||||
|
||||
|
||||
foreach (var userinfo in userinfoList)
|
||||
{
|
||||
messageToSend.To.Add(new MailboxAddress(userinfo.FullName, userinfo.EMail));
|
||||
}
|
||||
|
||||
var userNames = userinfoList.Select(x => x.FullName).ToList();
|
||||
|
||||
foreach (var pm in pmandAPm)
|
||||
{
|
||||
messageToSend.Cc.Add(new MailboxAddress(pm.FullName, pm.EMail));
|
||||
}
|
||||
|
||||
var companyName = isEn_US ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
|
||||
|
||||
|
||||
|
||||
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
|
||||
{
|
||||
var subjectCode = subjectVisit.Subject.Code;
|
||||
var topicStr = string.Format(input.topicStr, trialInfo.ResearchProgramNo, subjectCode, subjectVisit.VisitName);
|
||||
var htmlBodyStr = string.Format(
|
||||
CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr),
|
||||
string.Join(',', userNames), // 用户名 {0}
|
||||
trialInfo.ExperimentName, // 项目 {1}
|
||||
subjectCode, // 受试者 {2}
|
||||
subjectVisit.VisitName, // 访视 {3}
|
||||
dictionValue[0], // 审核状态 {4}
|
||||
_systemEmailConfig.SiteUrl // 链接 {5}
|
||||
);
|
||||
|
||||
return (topicStr, htmlBodyStr);
|
||||
};
|
||||
|
||||
await CommonEmailHelper.GetTrialEmailSubejctAndHtmlInfoAndBuildAsync(trialEmailConfig, messageToSend, emailConfigFunc);
|
||||
|
||||
await SendEmailHelper.SendEmailAsync(messageToSend, trialInfo);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -147,7 +158,7 @@ public class CRCRepliedQCChallengeEventConsumer(
|
||||
private readonly SystemEmailSendConfig _systemEmailConfig = systemEmailConfig.CurrentValue;
|
||||
public async Task Consume(ConsumeContext<CRCRepliedQCChallengeEvent> context)
|
||||
{
|
||||
Console.WriteLine("发送(Code012,013) 【CRC 回复质控质疑 通知QC】邮件!!!");
|
||||
Log.Logger.Warning("发送(Code012,013) 【CRC 回复质控质疑 通知QC】邮件!!!");
|
||||
var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;
|
||||
|
||||
var subjectVisitId = context.Message.SubjectVisitId;
|
||||
@@ -158,26 +169,29 @@ public class CRCRepliedQCChallengeEventConsumer(
|
||||
|
||||
var scenario = context.Message.IsPd ? EmailBusinessScenario.PDVerification_UnderQCQuery : EmailBusinessScenario.EligibilityVerification_Pending;
|
||||
|
||||
|
||||
|
||||
var trialEmailConfig = _trialEmailNoticeConfigrepository.Where(t => t.TrialId == trialId && t.BusinessScenarioEnum == scenario && t.IsAutoSend && t.IsEnable).FirstOrDefault();
|
||||
|
||||
if (trialEmailConfig != null)
|
||||
{
|
||||
|
||||
|
||||
var qCChallengeDialog = await _qCChallengeDialogRepository.Where(x => x.Id == context.Message.QCChallengeDialogId).Include(x => x.QCChallenge).FirstNotNullAsync();
|
||||
|
||||
var trialUserList = await _trialUseRoleRepository.Where(x => x.TrialId == subjectVisit.TrialId && x.TrialUser.IsDeleted == false)
|
||||
.Select(t => new { t.UserRole.IdentityUser.EMail, t.UserRole.FullName, t.UserRole.UserTypeEnum, t.UserRole.IdentityUser.UserWorkLanguage }).ToListAsync();
|
||||
|
||||
var trialUserList = await _trialUseRoleRepository.Where(x => x.TrialId == subjectVisit.TrialId && x.TrialUser.IsDeleted == false).Include(x => x.UserRole).Select(x => x.UserRole).ToListAsync();
|
||||
|
||||
var userinfoList = trialUserList.Where(x => x.UserTypeEnum == UserTypeEnum.IQC).ToList();
|
||||
var pmandAPm = trialUserList.Where(x => x.UserTypeEnum == UserTypeEnum.APM || x.UserTypeEnum == UserTypeEnum.ProjectManager).ToList();
|
||||
|
||||
|
||||
var trialInfo = await _trialRepository.FirstOrDefaultAsync(t => t.Id == subjectVisit.TrialId);
|
||||
|
||||
|
||||
var userinfo = subjectVisit.CurrentActionUser;
|
||||
|
||||
//重新设置当前发送邮件的语言
|
||||
var workLanguage = _userRoleRepository.Where(t => t.Id == userinfo.Id).Select(t => t.IdentityUser.UserWorkLanguage).First();
|
||||
isEn_US = workLanguage == UserWorkLanguage.US;
|
||||
|
||||
var messageToSend = new MimeMessage();
|
||||
//发件地址
|
||||
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
|
||||
@@ -207,7 +221,7 @@ public class CRCRepliedQCChallengeEventConsumer(
|
||||
var subjectCode = subjectVisit.Subject.Code;
|
||||
var topicStr = string.Format(input.topicStr, trialInfo.ResearchProgramNo, subjectCode, subjectVisit.VisitName);
|
||||
var htmlBodyStr = string.Format(
|
||||
CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr),
|
||||
CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr, workLanguage),
|
||||
userinfo.FullName, // 用户名 {0}
|
||||
trialInfo.ExperimentName, // 项目 {1}
|
||||
subjectCode, // 受试者 {2}
|
||||
@@ -219,9 +233,9 @@ public class CRCRepliedQCChallengeEventConsumer(
|
||||
|
||||
return (topicStr, htmlBodyStr);
|
||||
};
|
||||
await CommonEmailHelper.GetTrialEmailSubejctAndHtmlInfoAndBuildAsync(trialEmailConfig, messageToSend, emailConfigFunc);
|
||||
await CommonEmailHelper.GetTrialEmailSubejctAndHtmlInfoAndBuildAsync(trialEmailConfig, messageToSend, emailConfigFunc, workLanguage);
|
||||
|
||||
await SendEmailHelper.SendEmailAsync(messageToSend, trialInfo);
|
||||
await SendEmailHelper.SendTrialEmailAsync(messageToSend, trialInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -244,7 +258,7 @@ public class QCRepliedQCChallengeEventConsumer(
|
||||
private readonly SystemEmailSendConfig _systemEmailConfig = systemEmailConfig.CurrentValue;
|
||||
public async Task Consume(ConsumeContext<QCRepliedQCChallengeEvent> context)
|
||||
{
|
||||
Console.WriteLine("发送(014,015) 【 QC回复 质控质疑,通知CRC】邮件!!!");
|
||||
Log.Logger.Warning("发送(014,015) 【 QC回复 质控质疑,通知CRC】邮件!!!");
|
||||
var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;
|
||||
|
||||
var subjectVisitId = context.Message.SubjectVisitId;
|
||||
@@ -277,54 +291,61 @@ public class QCRepliedQCChallengeEventConsumer(
|
||||
}
|
||||
|
||||
|
||||
|
||||
var trialUserList = await _trialUseRoleRepository.Where(x => x.TrialId == subjectVisit.TrialId && x.TrialUser.IsDeleted == false).Include(x => x.UserRole).Select(x => x.UserRole).ToListAsync();
|
||||
|
||||
var userinfoList = trialUserList.Where(x => x.UserTypeEnum == UserTypeEnum.ClinicalResearchCoordinator).ToList();
|
||||
|
||||
var craInfo = trialUserList.Where(x => x.UserTypeEnum == UserTypeEnum.CRA).FirstOrDefault();
|
||||
var trialUserList = await _trialUseRoleRepository.Where(x => x.TrialId == subjectVisit.TrialId && x.TrialUser.IsDeleted == false)
|
||||
.Select(t => new { t.UserRole.IdentityUser.EMail, t.UserRole.FullName, t.UserRole.UserTypeEnum, t.UserRole.IdentityUser.UserWorkLanguage }).ToListAsync();
|
||||
|
||||
var trialInfo = await _trialRepository.FirstOrDefaultAsync(t => t.Id == subjectVisit.TrialId);
|
||||
|
||||
|
||||
|
||||
|
||||
var dictionValue = await CommonEmailHelper.TranslationDictionary(new TranslationDictionaryDto()
|
||||
// 遍历语言枚举 在底层判断收件人是否为空,决定是否跳过邮件发送,避免每个邮件场景的地方都重复判断
|
||||
foreach (UserWorkLanguage workLanguage in Enum.GetValues<UserWorkLanguage>())
|
||||
{
|
||||
|
||||
DictionaryRepository = _dictionaryRepository,
|
||||
IsEn_US = isEn_US,
|
||||
DictionaryList = new List<DictionaryDto>()
|
||||
{
|
||||
new DictionaryDto (){DictionaryCode= "YesOrNo",EnumValue=isclose.ToString().ToLower(), }, //是否关闭
|
||||
|
||||
}
|
||||
});
|
||||
//重新设置当前发送邮件的语言
|
||||
isEn_US = workLanguage == UserWorkLanguage.US;
|
||||
|
||||
|
||||
var userinfoList = trialUserList.Where(x => x.UserTypeEnum == UserTypeEnum.ClinicalResearchCoordinator).Where(t => t.UserWorkLanguage == workLanguage).ToList();
|
||||
|
||||
var craInfoList = trialUserList.Where(x => x.UserTypeEnum == UserTypeEnum.CRA).ToList();
|
||||
|
||||
var dictionValue = await CommonEmailHelper.TranslationDictionary(new TranslationDictionaryDto()
|
||||
{
|
||||
|
||||
DictionaryRepository = _dictionaryRepository,
|
||||
IsEn_US = isEn_US,
|
||||
DictionaryList = new List<DictionaryDto>()
|
||||
{
|
||||
new DictionaryDto (){DictionaryCode= "YesOrNo",EnumValue=isclose.ToString().ToLower(), }, //是否关闭
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
foreach (var userinfo in userinfoList)
|
||||
{
|
||||
var messageToSend = new MimeMessage();
|
||||
//发件地址
|
||||
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
|
||||
messageToSend.To.Add(new MailboxAddress(userinfo.FullName, userinfo.EMail));
|
||||
if (craInfo != null)
|
||||
|
||||
var toUserName = string.Join('、', userinfoList.Select(t => t.FullName));
|
||||
|
||||
foreach (var userinfo in userinfoList)
|
||||
{
|
||||
messageToSend.Cc.Add(new MailboxAddress(craInfo.FullName, craInfo.EMail));
|
||||
messageToSend.To.Add(new MailboxAddress(userinfo.FullName, userinfo.EMail));
|
||||
}
|
||||
|
||||
foreach (var user in craInfoList)
|
||||
{
|
||||
messageToSend.Cc.Add(new MailboxAddress(user.FullName, user.EMail));
|
||||
}
|
||||
|
||||
var companyName = isEn_US ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
|
||||
|
||||
|
||||
|
||||
|
||||
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
|
||||
{
|
||||
var subjectCode = subjectVisit.Subject.Code;
|
||||
var topicStr = string.Format(input.topicStr, trialInfo.ResearchProgramNo, subjectCode, subjectVisit.VisitName);
|
||||
var htmlBodyStr = string.Format(
|
||||
CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr),
|
||||
userinfo.FullName, // 用户名 {0}
|
||||
CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr, workLanguage),
|
||||
toUserName, // 用户名 {0}
|
||||
trialInfo.ExperimentName, // 项目 {1}
|
||||
subjectCode, // 受试者 {2}
|
||||
subjectVisit.VisitName, // 访视 {3}
|
||||
@@ -337,10 +358,13 @@ public class QCRepliedQCChallengeEventConsumer(
|
||||
};
|
||||
|
||||
|
||||
await CommonEmailHelper.GetTrialEmailSubejctAndHtmlInfoAndBuildAsync(trialEmailConfig, messageToSend, emailConfigFunc);
|
||||
await CommonEmailHelper.GetTrialEmailSubejctAndHtmlInfoAndBuildAsync(trialEmailConfig, messageToSend, emailConfigFunc, workLanguage);
|
||||
|
||||
await SendEmailHelper.SendTrialEmailAsync(messageToSend, trialInfo);
|
||||
|
||||
await SendEmailHelper.SendEmailAsync(messageToSend, trialInfo);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -364,7 +388,7 @@ public class CRCRepliedCheckChallengeEventConsumer(
|
||||
private readonly SystemEmailSendConfig _systemEmailConfig = systemEmailConfig.CurrentValue;
|
||||
public async Task Consume(ConsumeContext<CRCRepliedCheckChallengeEvent> context)
|
||||
{
|
||||
Console.WriteLine("发送(019,020) 【 CRC 回复一致性核查质疑 通知PM】邮件!!!");
|
||||
Log.Logger.Warning("发送(019,020) 【 CRC 回复一致性核查质疑 通知PM】邮件!!!");
|
||||
var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;
|
||||
|
||||
|
||||
@@ -383,49 +407,58 @@ public class CRCRepliedCheckChallengeEventConsumer(
|
||||
{
|
||||
|
||||
|
||||
var trialUserList = await _trialUseRoleRepository.Where(x => x.TrialId == subjectVisit.TrialId && x.TrialUser.IsDeleted == false).Include(x => x.UserRole).Select(x => x.UserRole).ToListAsync();
|
||||
var trialUserList = await _trialUseRoleRepository.Where(x => x.TrialId == subjectVisit.TrialId && x.TrialUser.IsDeleted == false)
|
||||
.Select(t => new { t.UserRole.IdentityUser.EMail, t.UserRole.FullName, t.UserRole.UserTypeEnum, t.UserRole.IdentityUser.UserWorkLanguage }).ToListAsync();
|
||||
|
||||
var userinfoList = trialUserList.Where(x => x.UserTypeEnum == UserTypeEnum.APM || x.UserTypeEnum == UserTypeEnum.ProjectManager).ToList();
|
||||
|
||||
|
||||
var trialInfo = await _trialRepository.FirstOrDefaultAsync(t => t.Id == subjectVisit.TrialId);
|
||||
|
||||
|
||||
|
||||
|
||||
var dictionValue = await CommonEmailHelper.TranslationDictionary(new TranslationDictionaryDto()
|
||||
// 遍历语言枚举 在底层判断收件人是否为空,决定是否跳过邮件发送,避免每个邮件场景的地方都重复判断
|
||||
foreach (UserWorkLanguage workLanguage in Enum.GetValues<UserWorkLanguage>())
|
||||
{
|
||||
|
||||
DictionaryRepository = _dictionaryRepository,
|
||||
IsEn_US = isEn_US,
|
||||
DictionaryList = new List<DictionaryDto>()
|
||||
{
|
||||
new DictionaryDto (){DictionaryCode= "CheckState",EnumValue=subjectVisit.CheckState.GetEnumInt(), }, //审核状态
|
||||
|
||||
}
|
||||
});
|
||||
//重新设置当前发送邮件的语言
|
||||
isEn_US = workLanguage == UserWorkLanguage.US;
|
||||
|
||||
|
||||
|
||||
var dictionValue = await CommonEmailHelper.TranslationDictionary(new TranslationDictionaryDto()
|
||||
{
|
||||
|
||||
DictionaryRepository = _dictionaryRepository,
|
||||
IsEn_US = isEn_US,
|
||||
DictionaryList = new List<DictionaryDto>()
|
||||
{
|
||||
new DictionaryDto (){DictionaryCode= "CheckState",EnumValue=subjectVisit.CheckState.GetEnumInt(), }, //审核状态
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
var userinfoList = trialUserList.Where(x => x.UserTypeEnum == UserTypeEnum.APM || x.UserTypeEnum == UserTypeEnum.ProjectManager)
|
||||
.Where(t => t.UserWorkLanguage == workLanguage).ToList();
|
||||
|
||||
|
||||
foreach (var userinfo in userinfoList)
|
||||
{
|
||||
var messageToSend = new MimeMessage();
|
||||
|
||||
//发件地址
|
||||
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
|
||||
messageToSend.To.Add(new MailboxAddress(String.Empty, userinfo.EMail));
|
||||
|
||||
var toUserName = string.Join('、', userinfoList.Select(t => t.FullName));
|
||||
foreach (var userinfo in userinfoList)
|
||||
{
|
||||
messageToSend.To.Add(new MailboxAddress(userinfo.FullName, userinfo.EMail));
|
||||
}
|
||||
|
||||
var companyName = isEn_US ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
|
||||
|
||||
|
||||
|
||||
|
||||
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
|
||||
{
|
||||
var subjectCode = subjectVisit.Subject.Code;
|
||||
var topicStr = string.Format(input.topicStr, trialInfo.ResearchProgramNo, subjectCode, subjectVisit.VisitName);
|
||||
var htmlBodyStr = string.Format(
|
||||
CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr),
|
||||
userinfo.FullName, // 用户名 {0}
|
||||
CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr, workLanguage),
|
||||
toUserName, // 用户名 {0}
|
||||
trialInfo.ExperimentName, // 项目 {1}
|
||||
subjectCode, // 受试者 {2}
|
||||
subjectVisit.VisitName, // 访视 {3}
|
||||
@@ -437,10 +470,17 @@ public class CRCRepliedCheckChallengeEventConsumer(
|
||||
};
|
||||
|
||||
|
||||
await CommonEmailHelper.GetTrialEmailSubejctAndHtmlInfoAndBuildAsync(trialEmailConfig, messageToSend, emailConfigFunc);
|
||||
await CommonEmailHelper.GetTrialEmailSubejctAndHtmlInfoAndBuildAsync(trialEmailConfig, messageToSend, emailConfigFunc, workLanguage);
|
||||
|
||||
await SendEmailHelper.SendTrialEmailAsync(messageToSend, trialInfo);
|
||||
|
||||
await SendEmailHelper.SendEmailAsync(messageToSend, trialInfo);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -466,12 +506,12 @@ public class PMRepliedCheckChallengeEventConsumer(
|
||||
private readonly SystemEmailSendConfig _systemEmailConfig = systemEmailConfig.CurrentValue;
|
||||
public async Task Consume(ConsumeContext<PMRepliedCheckChallengeEvent> context)
|
||||
{
|
||||
Console.WriteLine("发送(016,017) 【 PM 一致性核查 通知CRC】邮件!!!");
|
||||
Log.Logger.Warning("发送(016,017) 【 PM 一致性核查 通知CRC】邮件!!!");
|
||||
var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;
|
||||
|
||||
var subjectVisitId = context.Message.SubjectVisitId;
|
||||
|
||||
var subjectVisit = await _subjectVisitRepository.Where(x => x.Id == subjectVisitId).Include(x => x.NoneDicomStudyList).Include(x => x.StudyList).Include(x => x.Subject).FirstNotNullAsync();
|
||||
var subjectVisit = await _subjectVisitRepository.Where(x => x.Id == subjectVisitId).Include(x => x.NoneDicomStudyList).Include(x => x.StudyList).Include(x => x.Subject).Include(t => t.TrialSite).FirstNotNullAsync();
|
||||
|
||||
var trialId = subjectVisit.TrialId;
|
||||
|
||||
@@ -486,11 +526,11 @@ public class PMRepliedCheckChallengeEventConsumer(
|
||||
var checkChallengeDialog = await _checkChallengeDialogRepository.Where(x => x.Id == context.Message.CheckChallengeDialogId).FirstNotNullAsync();
|
||||
|
||||
|
||||
var trialUserList = await _trialUseRoleRepository.Where(x => x.TrialId == subjectVisit.TrialId && x.TrialUser.IsDeleted == false).Include(x => x.UserRole).Select(x => x.UserRole).ToListAsync();
|
||||
var trialUserList = await _trialUseRoleRepository.Where(x => x.TrialId == subjectVisit.TrialId && x.TrialUser.IsDeleted == false)
|
||||
.Select(t => new { t.UserRole.IdentityUser.EMail, t.UserRole.FullName, t.UserRole.UserTypeEnum, t.UserRole.IdentityUser.UserWorkLanguage }).ToListAsync();
|
||||
|
||||
var userinfoList = trialUserList.Where(x => x.UserTypeEnum == UserTypeEnum.ClinicalResearchCoordinator).ToList();
|
||||
|
||||
var craInfo = trialUserList.Where(x => x.UserTypeEnum == UserTypeEnum.CRA).FirstOrDefault();
|
||||
var craInfoList = trialUserList.Where(x => x.UserTypeEnum == UserTypeEnum.CRA).ToList();
|
||||
|
||||
var trialInfo = await _trialRepository.FirstOrDefaultAsync(t => t.Id == subjectVisit.TrialId);
|
||||
|
||||
@@ -499,28 +539,46 @@ public class PMRepliedCheckChallengeEventConsumer(
|
||||
modalities = subjectVisit.NoneDicomStudyList.Select(t => t.Modality)
|
||||
.Union(subjectVisit.StudyList.Select(k => k.ModalityForEdit)).ToList();
|
||||
|
||||
var dictionValue = await CommonEmailHelper.TranslationDictionary(new TranslationDictionaryDto()
|
||||
|
||||
|
||||
// 遍历语言枚举 在底层判断收件人是否为空,决定是否跳过邮件发送,避免每个邮件场景的地方都重复判断
|
||||
//foreach (UserWorkLanguage workLanguage in Enum.GetValues<UserWorkLanguage>())
|
||||
{
|
||||
//重新设置当前发送邮件的语言
|
||||
|
||||
DictionaryRepository = _dictionaryRepository,
|
||||
IsEn_US = isEn_US,
|
||||
DictionaryList = new List<DictionaryDto>()
|
||||
{
|
||||
new DictionaryDto (){DictionaryCode= "CheckState",EnumValue=subjectVisit.CheckState.GetEnumInt(), }, //核查状态
|
||||
isEn_US = subjectVisit.TrialSite.Country == StaticData.SiteCountry.US;
|
||||
|
||||
}
|
||||
});
|
||||
var workLanguage = isEn_US ? UserWorkLanguage.US : UserWorkLanguage.CN;
|
||||
|
||||
var userinfoList = trialUserList.Where(x => x.UserTypeEnum == UserTypeEnum.ClinicalResearchCoordinator).Where(t => t.UserWorkLanguage == workLanguage).ToList();
|
||||
|
||||
|
||||
foreach (var userinfo in userinfoList)
|
||||
{
|
||||
var dictionValue = await CommonEmailHelper.TranslationDictionary(new TranslationDictionaryDto()
|
||||
{
|
||||
|
||||
DictionaryRepository = _dictionaryRepository,
|
||||
IsEn_US = isEn_US,
|
||||
DictionaryList = new List<DictionaryDto>()
|
||||
{
|
||||
new DictionaryDto (){DictionaryCode= "CheckState",EnumValue=subjectVisit.CheckState.GetEnumInt(), }, //核查状态
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
var messageToSend = new MimeMessage();
|
||||
|
||||
//发件地址
|
||||
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
|
||||
messageToSend.To.Add(new MailboxAddress(userinfo.FullName, userinfo.EMail));
|
||||
if (craInfo != null)
|
||||
|
||||
var toUserName = string.Join('、', userinfoList.Select(t => t.FullName));
|
||||
foreach (var userinfo in userinfoList)
|
||||
{
|
||||
messageToSend.Cc.Add(new MailboxAddress(craInfo.FullName, craInfo.EMail));
|
||||
messageToSend.To.Add(new MailboxAddress(userinfo.FullName, userinfo.EMail));
|
||||
}
|
||||
|
||||
foreach (var user in craInfoList)
|
||||
{
|
||||
messageToSend.Cc.Add(new MailboxAddress(user.FullName, user.EMail));
|
||||
}
|
||||
|
||||
var companyName = isEn_US ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
|
||||
@@ -531,8 +589,8 @@ public class PMRepliedCheckChallengeEventConsumer(
|
||||
var subjectCode = subjectVisit.Subject.Code;
|
||||
var topicStr = string.Format(input.topicStr, trialInfo.ResearchProgramNo, subjectCode, subjectVisit.VisitName);
|
||||
var htmlBodyStr = string.Format(
|
||||
CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr),
|
||||
userinfo.FullName, // 用户名 {0}
|
||||
CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr, workLanguage),
|
||||
toUserName, // 用户名 {0}
|
||||
trialInfo.ExperimentName, // 项目 {1}
|
||||
|
||||
subjectCode, // 受试者 {2}
|
||||
@@ -547,10 +605,11 @@ public class PMRepliedCheckChallengeEventConsumer(
|
||||
};
|
||||
|
||||
|
||||
await CommonEmailHelper.GetTrialEmailSubejctAndHtmlInfoAndBuildAsync(trialEmailConfig, messageToSend, emailConfigFunc);
|
||||
await CommonEmailHelper.GetTrialEmailSubejctAndHtmlInfoAndBuildAsync(trialEmailConfig, messageToSend, emailConfigFunc, workLanguage);
|
||||
|
||||
await SendEmailHelper.SendEmailAsync(messageToSend, trialInfo);
|
||||
await SendEmailHelper.SendTrialEmailAsync(messageToSend, trialInfo);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -592,49 +651,57 @@ public class CheckStateChangedToAuditEventConsumer(
|
||||
|
||||
|
||||
|
||||
var trialUserList = await _trialUseRoleRepository.Where(x => x.TrialId == subjectVisit.TrialId && x.TrialUser.IsDeleted == false).Include(x => x.UserRole).Select(x => x.UserRole).ToListAsync();
|
||||
var trialUserList = await _trialUseRoleRepository.Where(x => x.TrialId == subjectVisit.TrialId && x.TrialUser.IsDeleted == false)
|
||||
.Select(t => new { t.UserRole.IdentityUser.EMail, t.UserRole.FullName, t.UserRole.UserTypeEnum, t.UserRole.IdentityUser.UserWorkLanguage }).ToListAsync();
|
||||
|
||||
var userinfoList = trialUserList.Where(x => x.UserTypeEnum == UserTypeEnum.APM || x.UserTypeEnum == UserTypeEnum.ProjectManager).ToList();
|
||||
|
||||
|
||||
var trialInfo = await _trialRepository.FirstOrDefaultAsync(t => t.Id == subjectVisit.TrialId);
|
||||
|
||||
|
||||
|
||||
|
||||
var dictionValue = await CommonEmailHelper.TranslationDictionary(new TranslationDictionaryDto()
|
||||
// 遍历语言枚举 在底层判断收件人是否为空,决定是否跳过邮件发送,避免每个邮件场景的地方都重复判断
|
||||
foreach (UserWorkLanguage workLanguage in Enum.GetValues<UserWorkLanguage>())
|
||||
{
|
||||
//重新设置当前发送邮件的语言
|
||||
isEn_US = workLanguage == UserWorkLanguage.US;
|
||||
|
||||
DictionaryRepository = _dictionaryRepository,
|
||||
IsEn_US = isEn_US,
|
||||
DictionaryList = new List<DictionaryDto>()
|
||||
{
|
||||
new DictionaryDto (){DictionaryCode= "CheckState",EnumValue=subjectVisit.CheckState.GetEnumInt(), }, //审核状态
|
||||
var userinfoList = trialUserList.Where(x => x.UserTypeEnum == UserTypeEnum.APM || x.UserTypeEnum == UserTypeEnum.ProjectManager)
|
||||
.Where(t => t.UserWorkLanguage == workLanguage).ToList();
|
||||
|
||||
}
|
||||
});
|
||||
var dictionValue = await CommonEmailHelper.TranslationDictionary(new TranslationDictionaryDto()
|
||||
{
|
||||
|
||||
DictionaryRepository = _dictionaryRepository,
|
||||
IsEn_US = isEn_US,
|
||||
DictionaryList = new List<DictionaryDto>()
|
||||
{
|
||||
new DictionaryDto (){DictionaryCode= "CheckState",EnumValue=subjectVisit.CheckState.GetEnumInt(), }, //审核状态
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
foreach (var userinfo in userinfoList)
|
||||
{
|
||||
var messageToSend = new MimeMessage();
|
||||
//发件地址
|
||||
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
|
||||
messageToSend.To.Add(new MailboxAddress(userinfo.FullName, userinfo.EMail));
|
||||
|
||||
var toUserName = string.Join('、', userinfoList.Select(t => t.FullName));
|
||||
|
||||
foreach (var userinfo in userinfoList)
|
||||
{
|
||||
messageToSend.To.Add(new MailboxAddress(userinfo.FullName, userinfo.EMail));
|
||||
}
|
||||
|
||||
|
||||
var companyName = isEn_US ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
|
||||
|
||||
|
||||
|
||||
|
||||
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
|
||||
{
|
||||
var subjectCode = subjectVisit.Subject.Code;
|
||||
var topicStr = string.Format(input.topicStr, trialInfo.ResearchProgramNo, subjectCode, subjectVisit.VisitName);
|
||||
var htmlBodyStr = string.Format(
|
||||
CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr),
|
||||
userinfo.FullName, // 姓名 {0}
|
||||
CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr, workLanguage),
|
||||
toUserName, // 姓名 {0}
|
||||
trialInfo.ExperimentName, // 项目 {1}
|
||||
subjectCode, // 受试者 {2}
|
||||
subjectVisit.VisitName, // 访视 {3}
|
||||
@@ -646,10 +713,11 @@ public class CheckStateChangedToAuditEventConsumer(
|
||||
};
|
||||
|
||||
|
||||
await CommonEmailHelper.GetTrialEmailSubejctAndHtmlInfoAndBuildAsync(trialEmailConfig, messageToSend, emailConfigFunc);
|
||||
await CommonEmailHelper.GetTrialEmailSubejctAndHtmlInfoAndBuildAsync(trialEmailConfig, messageToSend, emailConfigFunc, workLanguage);
|
||||
|
||||
await SendEmailHelper.SendEmailAsync(messageToSend, trialInfo);
|
||||
await SendEmailHelper.SendTrialEmailAsync(messageToSend, trialInfo);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -671,7 +739,7 @@ public class QCClaimTaskEventConsumer(
|
||||
private readonly SystemEmailSendConfig _systemEmailConfig = systemEmailConfig.CurrentValue;
|
||||
public async Task Consume(ConsumeContext<QCClaimTaskEvent> context)
|
||||
{
|
||||
Console.WriteLine("发送(Code007,008) 【QC 领取了质控任务】邮件!!!");
|
||||
Log.Logger.Warning("发送(Code007,008) 【QC 领取了质控任务】邮件!!!");
|
||||
var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;
|
||||
|
||||
|
||||
@@ -708,6 +776,10 @@ public class QCClaimTaskEventConsumer(
|
||||
return;
|
||||
}
|
||||
|
||||
//重新设置当前发送邮件的语言
|
||||
var workLanguage = _userRoleRepository.Where(t => t.Id == userinfo.Id).Select(t => t.IdentityUser.UserWorkLanguage).First();
|
||||
isEn_US = workLanguage == UserWorkLanguage.US;
|
||||
|
||||
var messageToSend = new MimeMessage();
|
||||
//发件地址
|
||||
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
|
||||
@@ -745,7 +817,7 @@ public class QCClaimTaskEventConsumer(
|
||||
var subjectCode = subjectVisit.Subject.Code;
|
||||
var topicStr = string.Format(input.topicStr, trialInfo.ResearchProgramNo, subjectCode, subjectVisit.VisitName);
|
||||
var htmlBodyStr = string.Format(
|
||||
CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr),
|
||||
CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr, workLanguage),
|
||||
userinfo.FullName, // 用户名 {0}
|
||||
trialInfo.ExperimentName, // 项目 {1}
|
||||
string.Join(',', subjectcodes), // 受试者 {2}
|
||||
@@ -759,9 +831,9 @@ public class QCClaimTaskEventConsumer(
|
||||
};
|
||||
|
||||
|
||||
await CommonEmailHelper.GetTrialEmailSubejctAndHtmlInfoAndBuildAsync(trialEmailConfig, messageToSend, emailConfigFunc);
|
||||
await CommonEmailHelper.GetTrialEmailSubejctAndHtmlInfoAndBuildAsync(trialEmailConfig, messageToSend, emailConfigFunc, workLanguage);
|
||||
|
||||
await SendEmailHelper.SendEmailAsync(messageToSend, trialInfo);
|
||||
await SendEmailHelper.SendTrialEmailAsync(messageToSend, trialInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
using System.Globalization;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using IRaCIS.Core.Domain.BaseModel;
|
||||
using IRaCIS.Core.Domain.Share;
|
||||
using IRaCIS.Core.Domain.BaseModel;
|
||||
using MassTransit;
|
||||
using NPOI.SS.Formula.Functions;
|
||||
using System.Globalization;
|
||||
|
||||
public class CultureInfoFilter<T> (IRepository<EventStoreRecord> _eventStoreRecordRepository) : IFilter<ConsumeContext<T>> where T : DomainEvent
|
||||
{
|
||||
|
||||
@@ -74,13 +74,17 @@ namespace IRaCIS.Core.Application.MassTransit.Recurring
|
||||
t.UserRole.IdentityUser.EMail,
|
||||
t.UserRole.IdentityUser.UserName,
|
||||
t.Trial.TrialCode,
|
||||
t.Trial.ResearchProgramNo
|
||||
t.Trial.ResearchProgramNo,
|
||||
t.UserRole.IdentityUser.UserWorkLanguage
|
||||
//TrialReadingCriterionList = t.Trial.TrialReadingCriterionList.Select(t => new { t.CriterionName, TrialReadingCriterionId = t.Id }).ToList()
|
||||
});
|
||||
|
||||
|
||||
foreach (var trialUser in trialUserList)
|
||||
{
|
||||
//重新设置当前发送邮件的语言
|
||||
var workLanguage = trialUser.UserWorkLanguage;
|
||||
isEn_US = workLanguage == UserWorkLanguage.US;
|
||||
|
||||
var userId = trialUser.UserId;
|
||||
|
||||
@@ -153,7 +157,7 @@ namespace IRaCIS.Core.Application.MassTransit.Recurring
|
||||
|
||||
|
||||
|
||||
var htmlBodyStr = string.Format(CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, emailContent),
|
||||
var htmlBodyStr = string.Format(CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, emailContent, workLanguage),
|
||||
trialUser.FullName,
|
||||
|
||||
DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
|
||||
@@ -167,9 +171,9 @@ namespace IRaCIS.Core.Application.MassTransit.Recurring
|
||||
return (topicStr, htmlBodyStr);
|
||||
};
|
||||
|
||||
await CommonEmailHelper.GetTrialEmailSubejctAndHtmlInfoAndBuildAsync(trialEmailConfig, messageToSend, emailConfigFunc);
|
||||
await CommonEmailHelper.GetTrialEmailSubejctAndHtmlInfoAndBuildAsync(trialEmailConfig, messageToSend, emailConfigFunc, workLanguage);
|
||||
|
||||
await SendEmailHelper.SendEmailAsync(messageToSend, trialInfo);
|
||||
await SendEmailHelper.SendTrialEmailAsync(messageToSend, trialInfo);
|
||||
|
||||
//处理标记已通知的任务
|
||||
|
||||
|
||||
@@ -44,12 +44,17 @@ public class QCImageQuestionRecurringEventConsumer(IRepository<Trial> _trialRepo
|
||||
var trialInfo = await _trialRepository.Where(t => t.Id == trialId).Select(t => new { t.ResearchProgramNo, t.ExperimentName, t.TrialCode, t.TrialStatusStr }).FirstNotNullAsync();
|
||||
|
||||
//找到 该项目的CRC 用户Id
|
||||
var userList = await _trialUserRoleRepository.Where(t => t.TrialId == trialId).Where(t => t.UserRole.UserTypeEnum == UserTypeEnum.ClinicalResearchCoordinator).Select(t => new { t.UserId, t.UserRole.FullName }).ToListAsync();
|
||||
var userList = await _trialUserRoleRepository.Where(t => t.TrialId == trialId).Where(t => t.UserRole.UserTypeEnum == UserTypeEnum.ClinicalResearchCoordinator).Select(t => new { t.UserId, t.UserRole.FullName, t.UserRole.IdentityUser.UserWorkLanguage }).ToListAsync();
|
||||
|
||||
//判断是否任务可以领取 ,可以的话 发送邮件
|
||||
|
||||
foreach (var user in userList)
|
||||
{
|
||||
|
||||
//重新设置当前发送邮件的语言
|
||||
var workLanguage = user.UserWorkLanguage;
|
||||
isEn_us = workLanguage == UserWorkLanguage.US;
|
||||
|
||||
var userId = user.UserId;
|
||||
//过滤项目 并且 将 _userInfo.Id 换位 当前发送邮件的Id
|
||||
var query = _trialRepository.Where(t => t.Id == trialId)
|
||||
@@ -72,7 +77,7 @@ public class QCImageQuestionRecurringEventConsumer(IRepository<Trial> _trialRepo
|
||||
{
|
||||
var topicStr = string.Format(isEn_us ? trialEmailConfig.EmailTopic : trialEmailConfig.EmailTopicCN, trialInfo.ResearchProgramNo);
|
||||
var htmlContent = isEn_us ? trialEmailConfig.EmailHtmlContent : trialEmailConfig.EmailHtmlContentCN;
|
||||
var htmlBodyStr = string.Format(CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, htmlContent),
|
||||
var htmlBodyStr = string.Format(CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, htmlContent, workLanguage),
|
||||
user.FullName, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), sendStat.ToBeDealedCount, _SystemEmailSendConfig.CurrentValue.SiteUrl);
|
||||
|
||||
return (topicStr, htmlBodyStr, isEn_us, userId);
|
||||
@@ -116,12 +121,17 @@ public class CRCImageQuestionRecurringEventConsumer(IRepository<Trial> _trialRep
|
||||
var trialInfo = await _trialRepository.Where(t => t.Id == trialId).Select(t => new { t.ResearchProgramNo, t.ExperimentName, t.TrialCode, t.TrialStatusStr, t.DeclarationTypeEnumList }).FirstNotNullAsync();
|
||||
|
||||
//找到 该项目的IQC 用户Id
|
||||
var userList = await _trialUserRoleRepository.Where(t => t.TrialId == trialId).Where(t => t.UserRole.UserTypeEnum == UserTypeEnum.IQC).Select(t => new { t.UserId, t.UserRole.FullName }).ToListAsync();
|
||||
var userList = await _trialUserRoleRepository.Where(t => t.TrialId == trialId).Where(t => t.UserRole.UserTypeEnum == UserTypeEnum.IQC).Select(t => new { t.UserId, t.UserRole.FullName, t.UserRole.IdentityUser.UserWorkLanguage }).ToListAsync();
|
||||
|
||||
//判断是否任务可以领取 ,可以的话 发送邮件
|
||||
|
||||
foreach (var user in userList)
|
||||
{
|
||||
|
||||
//重新设置当前发送邮件的语言
|
||||
var workLanguage = user.UserWorkLanguage;
|
||||
isEn_us = workLanguage == UserWorkLanguage.US;
|
||||
|
||||
var userId = user.UserId;
|
||||
|
||||
//过滤项目 并且 将 _userInfo.Id 换位 当前发送邮件的Id
|
||||
@@ -147,7 +157,7 @@ public class CRCImageQuestionRecurringEventConsumer(IRepository<Trial> _trialRep
|
||||
{
|
||||
var topicStr = string.Format(isEn_us ? trialEmailConfig.EmailTopic : trialEmailConfig.EmailTopicCN, trialInfo.ResearchProgramNo);
|
||||
var htmlContent = isEn_us ? trialEmailConfig.EmailHtmlContent : trialEmailConfig.EmailHtmlContentCN;
|
||||
var htmlBodyStr = string.Format(CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, htmlContent),
|
||||
var htmlBodyStr = string.Format(CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, htmlContent, workLanguage),
|
||||
|
||||
user.FullName, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), sendStat.ToBeDealedCount - sendStat.ReUploadTobeDealedCount, sendStat.ReUploadTobeDealedCount, _SystemEmailSendConfig.CurrentValue.SiteUrl);
|
||||
|
||||
@@ -181,7 +191,7 @@ public class ImageQCRecurringEventConsumer(IRepository<Trial> _trialRepository,
|
||||
private readonly SystemEmailSendConfig _systemEmailConfig = systemEmailConfig.CurrentValue;
|
||||
public async Task Consume(ConsumeContext<ImageQCRecurringEvent> context)
|
||||
{
|
||||
var trialId=context.Message.TrialId;
|
||||
var trialId = context.Message.TrialId;
|
||||
|
||||
var isEn_us = context.Message.CultureInfoName == StaticData.CultureInfo.en_US;
|
||||
|
||||
@@ -192,13 +202,17 @@ public class ImageQCRecurringEventConsumer(IRepository<Trial> _trialRepository,
|
||||
var trialInfo = await _trialRepository.Where(t => t.Id == trialId).Select(t => new { t.ResearchProgramNo, t.ExperimentName, t.TrialCode, t.TrialStatusStr }).FirstNotNullAsync();
|
||||
|
||||
//找到 该项目的IQC 用户Id
|
||||
var userList = await _trialUserRoleRepository.Where(t => t.TrialId == trialId).Where(t => t.UserRole.UserTypeEnum == UserTypeEnum.IQC).Select(t => new { t.UserId, t.UserRole.FullName }).ToListAsync();
|
||||
var userList = await _trialUserRoleRepository.Where(t => t.TrialId == trialId).Where(t => t.UserRole.UserTypeEnum == UserTypeEnum.IQC).Select(t => new { t.UserId, t.UserRole.FullName, t.UserRole.IdentityUser.UserWorkLanguage }).ToListAsync();
|
||||
|
||||
//判断是否任务可以领取 ,可以的话 发送邮件
|
||||
var userIdList = userList.Select(t => t.UserId).ToList();
|
||||
|
||||
foreach (var user in userList)
|
||||
{
|
||||
//重新设置当前发送邮件的语言
|
||||
var workLanguage = user.UserWorkLanguage;
|
||||
isEn_us = workLanguage == UserWorkLanguage.US;
|
||||
|
||||
var userId = user.UserId;
|
||||
|
||||
//过滤项目 并且 将 _userInfo.Id 换位 当前发送邮件的Id
|
||||
@@ -222,11 +236,11 @@ public class ImageQCRecurringEventConsumer(IRepository<Trial> _trialRepository,
|
||||
|
||||
Func<TrialEmailNoticeConfig, (string topicStr, string htmlBodyStr, bool isEn_us, Guid? onlyToUserId)> topicAndHtmlFunc = trialEmailConfig =>
|
||||
{
|
||||
|
||||
|
||||
var topicStr = string.Format(isEn_us ? trialEmailConfig.EmailTopic : trialEmailConfig.EmailTopicCN, trialInfo.ResearchProgramNo);
|
||||
|
||||
var htmlContent = isEn_us ? trialEmailConfig.EmailHtmlContent : trialEmailConfig.EmailHtmlContentCN;
|
||||
var htmlBodyStr = string.Format(CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, htmlContent),
|
||||
var htmlBodyStr = string.Format(CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, htmlContent, workLanguage),
|
||||
user.FullName, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), sendStat.ToBeClaimedCount, sendStat.ToBeReviewedCount, _SystemEmailSendConfig.CurrentValue.SiteUrl);
|
||||
|
||||
return (topicStr, htmlBodyStr, false, userId);
|
||||
|
||||
@@ -5,6 +5,7 @@ using IRaCIS.Core.Application.Helper;
|
||||
using IRaCIS.Core.Application.MassTransit.Consumer;
|
||||
using IRaCIS.Core.Application.Service.Reading.Dto;
|
||||
using IRaCIS.Core.Domain.Models;
|
||||
using IRaCIS.Core.Domain.Share;
|
||||
using MassTransit;
|
||||
using Microsoft.Extensions.Options;
|
||||
using MimeKit;
|
||||
@@ -50,11 +51,13 @@ namespace IRaCIS.Core.Application.MassTransit.Recurring
|
||||
|
||||
var systemDocQuery =
|
||||
from sysDoc in _systemDocumentRepository.AsQueryable(false)
|
||||
from identityUser in _identityUserRepository.AsQueryable(false).Where(t => 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).Where(t => t.UserRoleList.Where(t => t.IsUserRoleDisabled == false).Any(t => sysDoc.NeedConfirmedUserTypeList.AsQueryable().Any(c => c.NeedConfirmUserTypeId == t.UserTypeId)))
|
||||
join confirmc in _systemDocConfirmedUserRepository.Where() on new { ConfirmUserId = identityUser.Id, SystemDocumentId = sysDoc.Id } equals new { confirmc.ConfirmUserId, confirmc.SystemDocumentId } into cc
|
||||
from confirm in cc.DefaultIfEmpty()
|
||||
select new UnionDocumentWithConfirmInfoView()
|
||||
select new TriaAndSystemlSignDocView()
|
||||
{
|
||||
DocLanguageType=sysDoc.DocLanguageType,
|
||||
UserWorkLanguage=identityUser.UserWorkLanguage,
|
||||
IsSystemDoc = true,
|
||||
Id = sysDoc.Id,
|
||||
CreateTime = sysDoc.CreateTime,
|
||||
@@ -78,209 +81,211 @@ namespace IRaCIS.Core.Application.MassTransit.Recurring
|
||||
};
|
||||
var datalist = await systemDocQuery.IgnoreQueryFilters().Where(t => t.IsDeleted == false && t.ConfirmTime == null)
|
||||
.ToListAsync();
|
||||
datalist = datalist.Where(x => x.SuggestFinishTime != null && x.SuggestFinishTime.Value.Date == DateTime.Now.Date)
|
||||
datalist = datalist
|
||||
.Where(x=>x.DocLanguageType == DocLanguageType.CN_US || (int)x.DocLanguageType == (int)x.UserWorkLanguage)
|
||||
.Where(x => x.SuggestFinishTime != null && x.SuggestFinishTime.Value.Date == DateTime.Now.Date)
|
||||
.Where(x => x.IsNeedSendEmial).ToList();
|
||||
var confirmUserIdList = datalist.Select(t => t.ConfirmUserId).Distinct().ToList();
|
||||
var userinfoList = await _identityUserRepository.Where(x => confirmUserIdList.Contains(x.Id)).ToListAsync();
|
||||
|
||||
Console.WriteLine("发送定时过期提醒:人员数量" + userinfoList.Count);
|
||||
int index = 1;
|
||||
foreach (var userinfo in userinfoList)
|
||||
|
||||
var scenario = EmailBusinessScenario.GeneralTraining_ExpirationNotification;
|
||||
var emailConfig = _emailNoticeConfigrepository.Where(t => t.BusinessScenarioEnum == scenario && t.IsAutoSend && t.IsEnable).FirstOrDefault();
|
||||
if (emailConfig == null)
|
||||
{
|
||||
try
|
||||
{
|
||||
Console.WriteLine($"{index}发送定时过期提醒,邮箱:{userinfo.EMail},姓名{userinfo.UserName}");
|
||||
index++;
|
||||
var messageToSend = new MimeMessage();
|
||||
//发件地址
|
||||
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
|
||||
messageToSend.To.Add(new MailboxAddress(userinfo.FullName, userinfo.EMail));
|
||||
|
||||
|
||||
|
||||
var companyName = isEn_US ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
|
||||
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
|
||||
{
|
||||
var topicStr = string.Format(input.topicStr, companyName);
|
||||
|
||||
var htmlBodyStr = string.Format(
|
||||
CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr),
|
||||
userinfo.UserName, // 用户名 {0}
|
||||
_systemEmailConfig.SiteUrl
|
||||
);
|
||||
|
||||
return (topicStr, htmlBodyStr);
|
||||
};
|
||||
|
||||
var scenario = EmailBusinessScenario.GeneralTraining_ExpirationNotification;
|
||||
|
||||
var emailConfig = _emailNoticeConfigrepository.Where(t => t.BusinessScenarioEnum == scenario && t.IsAutoSend && t.IsEnable).FirstOrDefault();
|
||||
|
||||
if (emailConfig != null)
|
||||
{
|
||||
await CommonEmailHelper.GetEmailSubejctAndHtmlInfoAndBuildAsync(emailConfig, messageToSend, emailConfigFunc);
|
||||
|
||||
await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
var userWorkLanguageList = userinfoList.Select(x => x.UserWorkLanguage).Distinct().ToList();
|
||||
foreach (var workLanguage in userWorkLanguageList)
|
||||
{
|
||||
var langUserInfoList = userinfoList.Where(x => x.UserWorkLanguage == workLanguage).ToList();
|
||||
if (!langUserInfoList.Any())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var userIsEn_US = workLanguage == UserWorkLanguage.US;
|
||||
var companyName = userIsEn_US ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
|
||||
|
||||
foreach (var userinfo in langUserInfoList)
|
||||
{
|
||||
try
|
||||
{
|
||||
var messageToSend = new MimeMessage();
|
||||
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
|
||||
messageToSend.To.Add(new MailboxAddress(userinfo.FullName, userinfo.EMail));
|
||||
|
||||
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
|
||||
{
|
||||
var topicStr = string.Format(input.topicStr, companyName);
|
||||
|
||||
var htmlBodyStr = string.Format(
|
||||
CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr, workLanguage),
|
||||
userinfo.FullName,
|
||||
_systemEmailConfig.SiteUrl
|
||||
);
|
||||
|
||||
return (topicStr, htmlBodyStr);
|
||||
};
|
||||
|
||||
await CommonEmailHelper.GetEmailSubejctAndHtmlInfoAndBuildAsync(emailConfig, messageToSend, emailConfigFunc, workLanguage);
|
||||
await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 生效通知
|
||||
/// </summary>
|
||||
public class SystemDocumentPublishEventConsumer(
|
||||
IRepository<ReadingQuestionCriterionTrial> _trialReadingCriterionRepository,
|
||||
IRepository<VisitTask> _visitTaskRepository,
|
||||
IRepository<SystemDocument> _systemDocumentRepository,
|
||||
IRepository<IdentityUser> _identityUserRepository,
|
||||
IRepository<SystemDocConfirmedIdentityUser> _systemDocConfirmedUserRepository,
|
||||
IRepository<Dictionary> _dictionaryRepository,
|
||||
IRepository<TrialUserRole> _trialUserRoleRepository,
|
||||
IRepository<EmailNoticeConfig> _emailNoticeConfigrepository,
|
||||
/// <summary>
|
||||
/// 生效通知
|
||||
/// </summary>
|
||||
public class SystemDocumentPublishEventConsumer(
|
||||
IRepository<ReadingQuestionCriterionTrial> _trialReadingCriterionRepository,
|
||||
IRepository<VisitTask> _visitTaskRepository,
|
||||
IRepository<SystemDocument> _systemDocumentRepository,
|
||||
IRepository<IdentityUser> _identityUserRepository,
|
||||
IRepository<SystemDocConfirmedIdentityUser> _systemDocConfirmedUserRepository,
|
||||
IRepository<Dictionary> _dictionaryRepository,
|
||||
IRepository<TrialUserRole> _trialUserRoleRepository,
|
||||
IRepository<EmailNoticeConfig> _emailNoticeConfigrepository,
|
||||
|
||||
IOptionsMonitor<SystemEmailSendConfig> systemEmailConfig) : IConsumer<SystemDocumentPublishEvent>
|
||||
{
|
||||
private readonly SystemEmailSendConfig _systemEmailConfig = systemEmailConfig.CurrentValue;
|
||||
|
||||
public async Task Consume(ConsumeContext<SystemDocumentPublishEvent> context)
|
||||
IOptionsMonitor<SystemEmailSendConfig> systemEmailConfig) : IConsumer<SystemDocumentPublishEvent>
|
||||
{
|
||||
var isEn_US = context.Message.CultureInfoName == StaticData.CultureInfo.en_US;
|
||||
private readonly SystemEmailSendConfig _systemEmailConfig = systemEmailConfig.CurrentValue;
|
||||
|
||||
//设置当前事件传递过来的语言
|
||||
var culture = context.Message.CultureInfoName;
|
||||
CultureInfo.CurrentCulture = new CultureInfo(culture);
|
||||
|
||||
// 记录是否只发送给新增角色的日志
|
||||
if (context.Message.NewUserTypeIds != null && context.Message.NewUserTypeIds.Any())
|
||||
public async Task Consume(ConsumeContext<SystemDocumentPublishEvent> context)
|
||||
{
|
||||
Console.WriteLine($"只发送给新增的角色,角色数量: {context.Message.NewUserTypeIds.Count}");
|
||||
}
|
||||
// 构建查询
|
||||
IQueryable<UnionDocumentWithConfirmInfoView> systemDocQuery;
|
||||
var isEn_US = context.Message.CultureInfoName == StaticData.CultureInfo.en_US;
|
||||
|
||||
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 => context.Message.NewUserTypeIds.Contains(t.UserTypeId) &&
|
||||
sysDoc.NeedConfirmedUserTypeList.AsQueryable().Any(c => c.NeedConfirmUserTypeId == t.UserTypeId)))
|
||||
select new UnionDocumentWithConfirmInfoView()
|
||||
//设置当前事件传递过来的语言
|
||||
var culture = context.Message.CultureInfoName;
|
||||
CultureInfo.CurrentCulture = new CultureInfo(culture);
|
||||
|
||||
// 记录是否只发送给新增角色的日志
|
||||
if (context.Message.NewUserTypeIds != null && context.Message.NewUserTypeIds.Any())
|
||||
{
|
||||
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
|
||||
};
|
||||
}
|
||||
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()
|
||||
Console.WriteLine($"只发送给新增的角色,角色数量: {context.Message.NewUserTypeIds.Count}");
|
||||
}
|
||||
// 构建查询
|
||||
IQueryable<TriaAndSystemlSignDocView> systemDocQuery;
|
||||
|
||||
if (context.Message.NewUserTypeIds != null && context.Message.NewUserTypeIds.Any())
|
||||
{
|
||||
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();
|
||||
var userinfoList = await _identityUserRepository.Where(x => confirmUserIdList.Contains(x.Id)).ToListAsync();
|
||||
int index = 1;
|
||||
foreach (var userinfo in userinfoList)
|
||||
{
|
||||
string msg = $"{index}生效通知,邮箱:{userinfo.EMail},姓名{userinfo.UserName},";
|
||||
index++;
|
||||
try
|
||||
{
|
||||
|
||||
var messageToSend = new MimeMessage();
|
||||
//发件地址
|
||||
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
|
||||
messageToSend.To.Add(new MailboxAddress(userinfo.FullName, userinfo.EMail));
|
||||
|
||||
|
||||
|
||||
var companyName = isEn_US ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
|
||||
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
|
||||
// 只查询新增角色的用户
|
||||
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 => context.Message.NewUserTypeIds.Contains(t.UserTypeId) &&
|
||||
sysDoc.NeedConfirmedUserTypeList.AsQueryable().Any(c => c.NeedConfirmUserTypeId == t.UserTypeId)))
|
||||
select new TriaAndSystemlSignDocView()
|
||||
{
|
||||
var topicStr = string.Format(input.topicStr, companyName);
|
||||
|
||||
var htmlBodyStr = string.Format(
|
||||
CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr),
|
||||
userinfo.UserName, // 用户名 {0}
|
||||
_systemEmailConfig.SiteUrl
|
||||
);
|
||||
|
||||
return (topicStr, htmlBodyStr);
|
||||
DocLanguageType = sysDoc.DocLanguageType,
|
||||
UserWorkLanguage = identityUser.UserWorkLanguage,
|
||||
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 scenario = EmailBusinessScenario.GeneralTraining_EffectiveNotification;
|
||||
|
||||
var emailConfig = _emailNoticeConfigrepository.Where(t => t.BusinessScenarioEnum == scenario && t.IsAutoSend && t.IsEnable).FirstOrDefault();
|
||||
|
||||
if (emailConfig != null)
|
||||
}
|
||||
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 TriaAndSystemlSignDocView()
|
||||
{
|
||||
await CommonEmailHelper.GetEmailSubejctAndHtmlInfoAndBuildAsync(emailConfig, messageToSend, emailConfigFunc);
|
||||
DocLanguageType = sysDoc.DocLanguageType,
|
||||
UserWorkLanguage = identityUser.UserWorkLanguage,
|
||||
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();
|
||||
datalist = datalist.Where(x => x.DocLanguageType == DocLanguageType.CN_US || (int)x.DocLanguageType == (int)x.UserWorkLanguage).ToList();
|
||||
var confirmUserIdList = datalist.Select(t => t.ConfirmUserId).Distinct().ToList();
|
||||
var userinfoList = await _identityUserRepository.Where(x => confirmUserIdList.Contains(x.Id)).ToListAsync();
|
||||
|
||||
var scenario = EmailBusinessScenario.GeneralTraining_EffectiveNotification;
|
||||
var emailConfig = _emailNoticeConfigrepository.Where(t => t.BusinessScenarioEnum == scenario && t.IsAutoSend && t.IsEnable).FirstOrDefault();
|
||||
if (emailConfig == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var userinfo in userinfoList)
|
||||
{
|
||||
string msg = $"{userinfo.UserName}生效通知,";
|
||||
try
|
||||
{
|
||||
var messageToSend = new MimeMessage();
|
||||
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
|
||||
messageToSend.To.Add(new MailboxAddress(userinfo.FullName, userinfo.EMail));
|
||||
|
||||
var workLanguage = userinfo.UserWorkLanguage;
|
||||
var userIsEn_US = workLanguage == UserWorkLanguage.US;
|
||||
var companyName = userIsEn_US ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
|
||||
|
||||
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
|
||||
{
|
||||
var topicStr = string.Format(input.topicStr, companyName);
|
||||
|
||||
var htmlBodyStr = string.Format(
|
||||
CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr, workLanguage),
|
||||
userinfo.FullName,
|
||||
_systemEmailConfig.SiteUrl
|
||||
);
|
||||
|
||||
return (topicStr, htmlBodyStr);
|
||||
};
|
||||
await CommonEmailHelper.GetEmailSubejctAndHtmlInfoAndBuildAsync(emailConfig, messageToSend, emailConfigFunc, workLanguage);
|
||||
await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig);
|
||||
msg += "发送成功";
|
||||
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
msg += "发送失败";
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
msg += "发送失败";
|
||||
|
||||
Console.WriteLine(msg);
|
||||
}
|
||||
|
||||
|
||||
Console.WriteLine(msg);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,24 +1,16 @@
|
||||
using DocumentFormat.OpenXml;
|
||||
using IRaCIS.Application.Contracts;
|
||||
using IRaCIS.Core.Application.Contracts;
|
||||
using IRaCIS.Core.Application.Helper;
|
||||
using IRaCIS.Core.Application.MassTransit.Consumer;
|
||||
using IRaCIS.Core.Application.Service.Reading.Dto;
|
||||
using IRaCIS.Core.Domain.Models;
|
||||
using IRaCIS.Core.Domain.Share;
|
||||
using MassTransit;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Options;
|
||||
using MimeKit;
|
||||
using NPOI.SS.Formula.Functions;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Linq.Dynamic.Core;
|
||||
using System.Reactive.Joins;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace IRaCIS.Core.Application.MassTransit.Recurring
|
||||
{
|
||||
@@ -60,7 +52,7 @@ namespace IRaCIS.Core.Application.MassTransit.Recurring
|
||||
|
||||
var trialDocQuery =
|
||||
from trialDoc in _trialDocumentRepository.AsQueryable(true)
|
||||
|
||||
join trial in _trialRepository.Where(x => x.IsDeleted == false) on trialDoc.TrialId equals trial.Id
|
||||
join trialIdentityUser in _trialIdentityUserRepository.Where(x => x.IsDeleted == false) on trialDoc.TrialId equals trialIdentityUser.TrialId
|
||||
join trialUserRole in _trialUserRoleRepository.Where(x => x.IsDeleted == false) on trialIdentityUser.Id equals trialUserRole.TrialUserId
|
||||
join identityUser in _identityUserRepository.AsQueryable(false).Where(u => u.Status == UserStateEnum.Enable)
|
||||
@@ -72,15 +64,18 @@ namespace IRaCIS.Core.Application.MassTransit.Recurring
|
||||
|
||||
from confirm in cc.DefaultIfEmpty()
|
||||
where trialIdentityUser.TrialUserRoleList.Any(ur => !ur.IsDeleted && trialDoc.NeedConfirmedUserTypeList.Any(c => c.NeedConfirmUserTypeId == ur.UserRole.UserTypeId))
|
||||
select new TrialSignDocView()
|
||||
select new TriaAndSystemlSignDocView()
|
||||
{
|
||||
|
||||
TrialCode = trialDoc.Trial.TrialCode,
|
||||
ResearchProgramNo = trialDoc.Trial.ResearchProgramNo,
|
||||
ExperimentName = trialDoc.Trial.ExperimentName,
|
||||
CurrentStaffTrainDays = trialDoc.CurrentStaffTrainDays,
|
||||
NewStaffTrainDays = trialDoc.NewStaffTrainDays,
|
||||
Id = trialDoc.Id,
|
||||
TrialId= trialDoc.TrialId,
|
||||
TrialType= trial.TrialType,
|
||||
IsTestUser= identityUser.IsTestUser,
|
||||
TrialId = trialDoc.TrialId,
|
||||
IsSystemDoc = false,
|
||||
CreateTime = trialDoc.CreateTime,
|
||||
FullFilePath = trialDoc.Path,
|
||||
@@ -102,57 +97,79 @@ namespace IRaCIS.Core.Application.MassTransit.Recurring
|
||||
};
|
||||
var datalist = await trialDocQuery.IgnoreQueryFilters().Where(t => t.IsDeleted == false && t.ConfirmTime == null&&t.ConfirmTime==null)
|
||||
.ToListAsync();
|
||||
datalist = datalist.Where(x => x.SuggestFinishTime != null && x.SuggestFinishTime.Value.Date == DateTime.Now.Date)
|
||||
|
||||
|
||||
datalist = datalist
|
||||
.Where(x=>((x.TrialType== TrialType.OfficialTrial|| x.TrialType== TrialType.Training) && !x.IsTestUser) || (x.TrialType==TrialType.NoneOfficial &&x.IsTestUser))
|
||||
.Where(x => x.SuggestFinishTime != null && x.SuggestFinishTime.Value.Date == DateTime.Now.Date)
|
||||
.ToList();
|
||||
var confirmUserIdList = datalist.Select(t => t.ConfirmUserId).Distinct().ToList();
|
||||
var userinfoList = await _identityUserRepository.Where(x => confirmUserIdList.Contains(x.Id)).ToListAsync();
|
||||
|
||||
Console.WriteLine("发送定时项目过期提醒:人员数量" + userinfoList.Count);
|
||||
int index = 1;
|
||||
foreach (var userinfo in userinfoList)
|
||||
|
||||
var scenario = EmailBusinessScenario.TrialTraining_ExpirationNotification;
|
||||
var emailConfig = _emailNoticeConfigrepository.Where(t => t.BusinessScenarioEnum == scenario && t.IsAutoSend && t.IsEnable).FirstOrDefault();
|
||||
if (emailConfig == null)
|
||||
{
|
||||
try
|
||||
return;
|
||||
}
|
||||
|
||||
var userTrialIdList = datalist.Select(t => new { t.ConfirmUserId, t.TrialId }).Distinct().ToList();
|
||||
var userWithTrialList = (from ut in userTrialIdList
|
||||
join u in userinfoList on ut.ConfirmUserId equals u.Id
|
||||
select new { ut.TrialId, User = u }).ToList();
|
||||
|
||||
var groupedList = userWithTrialList.GroupBy(x => new { x.TrialId, x.User.UserWorkLanguage }).ToList();
|
||||
foreach (var groupItem in groupedList)
|
||||
{
|
||||
var langUserInfoList = groupItem.Select(x => x.User).Distinct().ToList();
|
||||
if (!langUserInfoList.Any())
|
||||
{
|
||||
Console.WriteLine($"{index}发送定时过期提醒,邮箱:{userinfo.EMail},姓名{userinfo.UserName}");
|
||||
index++;
|
||||
var trialInfo = _trialRepository.Where(x => x.Id == userinfo.TrialId).FirstOrDefault();
|
||||
var messageToSend = new MimeMessage();
|
||||
//发件地址
|
||||
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
|
||||
messageToSend.To.Add(new MailboxAddress(userinfo.FullName, userinfo.EMail));
|
||||
|
||||
|
||||
|
||||
var companyName = isEn_US ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
|
||||
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
|
||||
{
|
||||
var topicStr = string.Format(input.topicStr, companyName);
|
||||
|
||||
var htmlBodyStr = string.Format(
|
||||
CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr),
|
||||
userinfo.UserName, // 用户名 {0}
|
||||
_systemEmailConfig.SiteUrl
|
||||
);
|
||||
|
||||
return (topicStr, htmlBodyStr);
|
||||
};
|
||||
|
||||
var scenario = EmailBusinessScenario.TrialTraining_ExpirationNotification;
|
||||
|
||||
var emailConfig = _emailNoticeConfigrepository.Where(t => t.BusinessScenarioEnum == scenario && t.IsAutoSend && t.IsEnable).FirstOrDefault();
|
||||
|
||||
if (emailConfig != null)
|
||||
{
|
||||
await CommonEmailHelper.GetEmailSubejctAndHtmlInfoAndBuildAsync(emailConfig, messageToSend, emailConfigFunc);
|
||||
|
||||
await SendEmailHelper.SendEmailAsync(messageToSend, trialInfo);
|
||||
}
|
||||
|
||||
|
||||
continue;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
||||
Console.WriteLine($"发送定时过期提醒,数量:{langUserInfoList.Count}");
|
||||
|
||||
var trialInfo = await _trialRepository.Where(x => x.Id == groupItem.Key.TrialId).FirstOrDefaultAsync();
|
||||
if (trialInfo == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var workLanguage = groupItem.Key.UserWorkLanguage;
|
||||
var userIsEn_US = workLanguage == UserWorkLanguage.US;
|
||||
var companyName = userIsEn_US ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
|
||||
|
||||
foreach (var userinfo in langUserInfoList)
|
||||
{
|
||||
try
|
||||
{
|
||||
var messageToSend = new MimeMessage();
|
||||
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
|
||||
messageToSend.To.Add(new MailboxAddress(userinfo.FullName, userinfo.EMail));
|
||||
|
||||
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
|
||||
{
|
||||
var topicStr = string.Format(input.topicStr, companyName);
|
||||
|
||||
var htmlBodyStr = string.Format(
|
||||
CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr, workLanguage),
|
||||
userinfo.FullName,
|
||||
_systemEmailConfig.SiteUrl
|
||||
);
|
||||
|
||||
return (topicStr, htmlBodyStr);
|
||||
};
|
||||
|
||||
await CommonEmailHelper.GetEmailSubejctAndHtmlInfoAndBuildAsync(emailConfig, messageToSend, emailConfigFunc, workLanguage);
|
||||
await SendEmailHelper.SendTrialEmailAsync(messageToSend, trialInfo);
|
||||
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -193,20 +210,21 @@ namespace IRaCIS.Core.Application.MassTransit.Recurring
|
||||
Console.WriteLine($"只发送给新增项目的角色,角色数量: {context.Message.NewUserTypeIds.Count}");
|
||||
}
|
||||
// 构建查询
|
||||
IQueryable<UnionDocumentWithConfirmInfoView> systemDocQuery;
|
||||
IQueryable<TriaAndSystemlSignDocView> trialDocQuery;
|
||||
|
||||
if (context.Message.NewUserTypeIds != null && context.Message.NewUserTypeIds.Any())
|
||||
{
|
||||
// 只查询新增角色的用户
|
||||
systemDocQuery =
|
||||
trialDocQuery =
|
||||
from trialDoc in _trialDocumentRepository.AsQueryable(false).Where(x => context.Message.Ids.Contains(x.Id))
|
||||
join trial in _trialRepository.Where(x => x.IsDeleted == false) on trialDoc.TrialId equals trial.Id
|
||||
join trialIdentityUser in _trialIdentityUserRepository.Where(x=>x.IsDeleted==false) on trialDoc.TrialId equals trialIdentityUser.TrialId
|
||||
join trialUserRole in _trialUserRoleRepository.Where(x => x.IsDeleted == false) on trialIdentityUser.Id equals trialUserRole.TrialUserId
|
||||
join identityUser in _identityUserRepository.AsQueryable(false).Where(u => u.Status == UserStateEnum.Enable)
|
||||
on trialIdentityUser.IdentityUserId equals identityUser.Id
|
||||
where trialIdentityUser.TrialUserRoleList.Any(ur => !ur.IsDeleted && context.Message.NewUserTypeIds.Contains(ur.UserRole.UserTypeId) && trialDoc.NeedConfirmedUserTypeList.Any(c => c.NeedConfirmUserTypeId == ur.UserRole.UserTypeId))
|
||||
|
||||
select new UnionDocumentWithConfirmInfoView()
|
||||
select new TriaAndSystemlSignDocView()
|
||||
{
|
||||
IsSystemDoc = true,
|
||||
Id = trialDoc.Id,
|
||||
@@ -214,6 +232,8 @@ namespace IRaCIS.Core.Application.MassTransit.Recurring
|
||||
CreateTime = trialDoc.CreateTime,
|
||||
IsDeleted = trialDoc.IsDeleted,
|
||||
SignViewMinimumMinutes = trialDoc.SignViewMinimumMinutes,
|
||||
TrialType = trial.TrialType,
|
||||
IsTestUser = identityUser.IsTestUser,
|
||||
Name = trialDoc.Name,
|
||||
Path = trialDoc.Path,
|
||||
FileTypeId = trialDoc.FileTypeId,
|
||||
@@ -228,8 +248,9 @@ namespace IRaCIS.Core.Application.MassTransit.Recurring
|
||||
else
|
||||
{
|
||||
// 查询所有相关角色的用户
|
||||
systemDocQuery =
|
||||
trialDocQuery =
|
||||
from trialDoc in _trialDocumentRepository.AsQueryable(false).Where(x => context.Message.Ids.Contains(x.Id))
|
||||
|
||||
join trialIdentityUser in _trialIdentityUserRepository.Where(x => x.IsDeleted == false) on trialDoc.TrialId equals trialIdentityUser.TrialId
|
||||
join trialUserRole in _trialUserRoleRepository.Where(x=>x.IsDeleted==false) on trialIdentityUser.Id equals trialUserRole.TrialUserId
|
||||
|
||||
@@ -239,7 +260,7 @@ namespace IRaCIS.Core.Application.MassTransit.Recurring
|
||||
where trialIdentityUser.TrialUserRoleList.Any(ur => !ur.IsDeleted &&trialDoc.NeedConfirmedUserTypeList.Any(c => c.NeedConfirmUserTypeId == ur.UserRole.UserTypeId))
|
||||
|
||||
|
||||
select new UnionDocumentWithConfirmInfoView()
|
||||
select new TriaAndSystemlSignDocView()
|
||||
{
|
||||
IsSystemDoc = false,
|
||||
Id = trialDoc.Id,
|
||||
@@ -248,6 +269,8 @@ namespace IRaCIS.Core.Application.MassTransit.Recurring
|
||||
CreateTime = trialDoc.CreateTime,
|
||||
IsDeleted = trialDoc.IsDeleted,
|
||||
SignViewMinimumMinutes = trialDoc.SignViewMinimumMinutes,
|
||||
TrialType = trial.TrialType,
|
||||
IsTestUser = identityUser.IsTestUser,
|
||||
Name = trialDoc.Name,
|
||||
Path = trialDoc.Path,
|
||||
FileTypeId = trialDoc.FileTypeId,
|
||||
@@ -260,56 +283,60 @@ namespace IRaCIS.Core.Application.MassTransit.Recurring
|
||||
};
|
||||
}
|
||||
|
||||
var datalist = await systemDocQuery.IgnoreQueryFilters().ToListAsync();
|
||||
var datalist = await trialDocQuery.IgnoreQueryFilters().ToListAsync();
|
||||
datalist = datalist.Where(x => ((x.TrialType == TrialType.OfficialTrial || x.TrialType == TrialType.Training) && !x.IsTestUser) || (x.TrialType == TrialType.NoneOfficial && x.IsTestUser)).ToList();
|
||||
|
||||
|
||||
var confirmUserIdList = datalist.Select(t => t.ConfirmUserId).Distinct().ToList();
|
||||
var userinfoList = await _identityUserRepository.Where(x => confirmUserIdList.Contains(x.Id)).ToListAsync();
|
||||
int index = 1;
|
||||
foreach (var userinfo in userinfoList)
|
||||
|
||||
var scenario = EmailBusinessScenario.TrialTraining_EffectiveNotification;
|
||||
var emailConfig = _emailNoticeConfigrepository.Where(t => t.BusinessScenarioEnum == scenario && t.IsEnable).FirstOrDefault();
|
||||
if (emailConfig == null)
|
||||
{
|
||||
string msg = $"{index}项目生效通知,邮箱:{userinfo.EMail},姓名{userinfo.UserName},";
|
||||
index++;
|
||||
return;
|
||||
}
|
||||
|
||||
var userTrialIdList = datalist.Select(t => new { t.ConfirmUserId, t.TrialId }).Distinct().ToList();
|
||||
var userWithTrialList = (from ut in userTrialIdList
|
||||
join u in userinfoList on ut.ConfirmUserId equals u.Id
|
||||
select new { ut.TrialId, User = u }).ToList();
|
||||
|
||||
foreach (var userWithTrial in userWithTrialList)
|
||||
{
|
||||
var userinfo = userWithTrial.User;
|
||||
string msg = $"{userinfo.UserName}项目生效通知,";
|
||||
try
|
||||
{
|
||||
|
||||
var messageToSend = new MimeMessage();
|
||||
//发件地址
|
||||
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
|
||||
messageToSend.To.Add(new MailboxAddress(userinfo.FullName, userinfo.EMail));
|
||||
|
||||
|
||||
|
||||
var companyName = isEn_US ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
|
||||
var workLanguage = userinfo.UserWorkLanguage;
|
||||
var userIsEn_US = workLanguage == UserWorkLanguage.US;
|
||||
var companyName = userIsEn_US ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
|
||||
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
|
||||
{
|
||||
var topicStr = string.Format(input.topicStr, companyName);
|
||||
|
||||
var htmlBodyStr = string.Format(
|
||||
CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr),
|
||||
userinfo.UserName, // 用户名 {0}
|
||||
CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr, workLanguage),
|
||||
userinfo.FullName,
|
||||
_systemEmailConfig.SiteUrl
|
||||
);
|
||||
|
||||
return (topicStr, htmlBodyStr);
|
||||
};
|
||||
await CommonEmailHelper.GetEmailSubejctAndHtmlInfoAndBuildAsync(emailConfig, messageToSend, emailConfigFunc, workLanguage);
|
||||
|
||||
var scenario = EmailBusinessScenario.TrialTraining_EffectiveNotification;
|
||||
|
||||
var emailConfig = _emailNoticeConfigrepository.Where(t => t.BusinessScenarioEnum == scenario && t.IsEnable).FirstOrDefault();
|
||||
|
||||
if (emailConfig != null)
|
||||
var trialInfo = await _trialRepository.Where(x => x.Id == userWithTrial.TrialId).FirstOrDefaultAsync();
|
||||
if (trialInfo == null)
|
||||
{
|
||||
await CommonEmailHelper.GetEmailSubejctAndHtmlInfoAndBuildAsync(emailConfig, messageToSend, emailConfigFunc);
|
||||
|
||||
var trial = datalist.Where(x => x.ConfirmUserId == userinfo.Id).FirstOrDefault();
|
||||
|
||||
var trialInfo = await _trialRepository.Where(x=>x.Id==trial.TrialId).FirstNotNullAsync();
|
||||
|
||||
|
||||
await SendEmailHelper.SendEmailAsync(messageToSend, trialInfo);
|
||||
msg += "发送成功";
|
||||
continue;
|
||||
}
|
||||
|
||||
await SendEmailHelper.SendTrialEmailAsync(messageToSend, trialInfo);
|
||||
msg += "发送成功";
|
||||
|
||||
}
|
||||
catch (Exception)
|
||||
|
||||
@@ -439,6 +439,8 @@ namespace IRaCIS.Core.Application.ViewModel
|
||||
|
||||
public string TaskName { get; set; } = String.Empty;
|
||||
|
||||
public string TaskBlindName { get; set; } = String.Empty;
|
||||
|
||||
public Guid? DoctorUserId { get; set; }
|
||||
|
||||
public ReadingCategory? ReadingCategory { get; set; }
|
||||
|
||||
@@ -54,8 +54,8 @@ namespace IRaCIS.Core.Application.Service
|
||||
|
||||
.WhereIf(inQuery.DoctorUserIdeaEnum != null, t => t.DoctorUserIdeaEnum == inQuery.DoctorUserIdeaEnum)
|
||||
.WhereIf(inQuery.TrialReadingCriterionId != null, t => t.VisitTask.TrialReadingCriterionId == inQuery.TrialReadingCriterionId)
|
||||
.WhereIf(inQuery.IsInvalid != null, t => t.IsInvalid == inQuery.IsInvalid)
|
||||
.WhereIf(inQuery.IsHaveQuestion != null, t => t.IsHaveQuestion == inQuery.IsHaveQuestion)
|
||||
.WhereIf(inQuery.IsInvalid != null, t => t.IsInvalid == inQuery.IsInvalid)
|
||||
.WhereIf(inQuery.IsHaveQuestion != null, t => t.IsHaveQuestion == inQuery.IsHaveQuestion)
|
||||
|
||||
.WhereIf(inQuery.BeginAllocateDate != null, t => t.AllocateTime >= inQuery.BeginAllocateDate)
|
||||
.WhereIf(inQuery.EndAllocateDate != null, t => t.AllocateTime <= inQuery.EndAllocateDate)
|
||||
@@ -211,23 +211,23 @@ namespace IRaCIS.Core.Application.Service
|
||||
.WhereIf(inQuery.SubjectId != null, t => t.VisitTask.SubjectId == inQuery.SubjectId)
|
||||
.WhereIf(inQuery.TrialSiteId != null, t => t.VisitTask.Subject.TrialSiteId == inQuery.TrialSiteId)
|
||||
.WhereIf(inQuery.IsUrgent != null, t => t.VisitTask.IsUrgent == inQuery.IsUrgent)
|
||||
.WhereIf(inQuery.AuditState != null, t => t.AuditState == inQuery.AuditState)
|
||||
.WhereIf(inQuery.DoctorUserIdeaEnum != null, t => t.DoctorUserIdeaEnum == inQuery.DoctorUserIdeaEnum)
|
||||
.WhereIf(inQuery.TaskState != null, t => t.VisitTask.TaskState == inQuery.TaskState)
|
||||
.WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => t.VisitTask.Subject.Code.Contains(inQuery.SubjectCode) || t.VisitTask.Subject.MedicalNo.Contains(inQuery.SubjectCode))
|
||||
.WhereIf(!string.IsNullOrEmpty(inQuery.TaskName), t => t.VisitTask.TaskName.Contains(inQuery.TaskName) || t.VisitTask.TaskBlindName.Contains(inQuery.TaskName))
|
||||
.WhereIf(inQuery.AuditState != null, t => t.AuditState == inQuery.AuditState)
|
||||
.WhereIf(inQuery.DoctorUserIdeaEnum != null, t => t.DoctorUserIdeaEnum == inQuery.DoctorUserIdeaEnum)
|
||||
.WhereIf(inQuery.TaskState != null, t => t.VisitTask.TaskState == inQuery.TaskState)
|
||||
.WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => t.VisitTask.Subject.Code.Contains(inQuery.SubjectCode) || t.VisitTask.Subject.MedicalNo.Contains(inQuery.SubjectCode))
|
||||
.WhereIf(!string.IsNullOrEmpty(inQuery.TaskName), t => t.VisitTask.TaskName.Contains(inQuery.TaskName) || t.VisitTask.TaskBlindName.Contains(inQuery.TaskName))
|
||||
.WhereIf(inQuery.DoctorUserId != null, t => t.VisitTask.DoctorUserId == inQuery.DoctorUserId)
|
||||
.WhereIf(inQuery.ReadingCategory != null, t => t.VisitTask.ReadingCategory == inQuery.ReadingCategory)
|
||||
.WhereIf(inQuery.ReadingTaskState != null, t => t.VisitTask.ReadingTaskState == inQuery.ReadingTaskState)
|
||||
.WhereIf(inQuery.IsInvalid != null, t => t.IsInvalid == inQuery.IsInvalid)
|
||||
.WhereIf(inQuery.IsInvalid != null, t => t.IsInvalid == inQuery.IsInvalid)
|
||||
.WhereIf(inQuery.IsGetBeRead, x => !x.IsInvalid && x.AuditState != MedicalReviewAuditState.HaveSigned)
|
||||
.WhereIf(inQuery.TrialReadingCriterionId != null, t => t.VisitTask.TrialReadingCriterionId == inQuery.TrialReadingCriterionId)
|
||||
.WhereIf(inQuery.BeginAuditSignTime != null, t => t.AuditSignTime >= inQuery.BeginAuditSignTime)
|
||||
.WhereIf(inQuery.EndAuditSignTime != null, t => t.AuditSignTime <= inQuery.EndAuditSignTime)
|
||||
.WhereIf(inQuery.BeginAllocateDate != null, t => t.AllocateTime >= inQuery.BeginAllocateDate)
|
||||
.WhereIf(inQuery.TrialReadingCriterionId != null, t => t.VisitTask.TrialReadingCriterionId == inQuery.TrialReadingCriterionId)
|
||||
.WhereIf(inQuery.BeginAuditSignTime != null, t => t.AuditSignTime >= inQuery.BeginAuditSignTime)
|
||||
.WhereIf(inQuery.EndAuditSignTime != null, t => t.AuditSignTime <= inQuery.EndAuditSignTime)
|
||||
.WhereIf(inQuery.BeginAllocateDate != null, t => t.AllocateTime >= inQuery.BeginAllocateDate)
|
||||
.WhereIf(inQuery.EndAllocateDate != null, t => t.AllocateTime <= inQuery.EndAllocateDate)
|
||||
|
||||
.WhereIf(inQuery.ArmEnum != null, t => t.VisitTask.ArmEnum == inQuery.ArmEnum)
|
||||
.WhereIf(inQuery.ArmEnum != null, t => t.VisitTask.ArmEnum == inQuery.ArmEnum)
|
||||
.WhereIf(inQuery.MedicalManagerUserId != null, t => t.MedicalManagerUserId == inQuery.MedicalManagerUserId)
|
||||
.WhereIf(inQuery.BeginSignTime != null, t => t.VisitTask.SignTime > inQuery.BeginSignTime)
|
||||
.WhereIf(inQuery.EndSignTime != null, t => t.VisitTask.SignTime < inQuery.EndSignTime)
|
||||
|
||||
@@ -124,6 +124,45 @@ namespace IRaCIS.Core.Application.Service
|
||||
}
|
||||
|
||||
|
||||
#region 获取随机编号
|
||||
/// <summary>
|
||||
/// 从 NewId 的后 3 个字节(24 位)生成一个 6 位十六进制字符串
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static string GenerateTaskNo()
|
||||
{
|
||||
var bytes = NewId.Next().ToByteArray();
|
||||
|
||||
uint value =
|
||||
BitConverter.ToUInt32(bytes, 0)
|
||||
^ BitConverter.ToUInt32(bytes, 4)
|
||||
^ BitConverter.ToUInt32(bytes, 8)
|
||||
^ BitConverter.ToUInt32(bytes, 12);
|
||||
|
||||
return (value & 0xFFFFFF).ToString("X6");
|
||||
}
|
||||
|
||||
private async Task<string> GetRandomTaskName(Guid trialId, List<string> existList)
|
||||
{
|
||||
var taskName = GenerateTaskNo();
|
||||
|
||||
while (existList.Any(t => t == taskName))
|
||||
{
|
||||
taskName = GenerateTaskNo();
|
||||
}
|
||||
|
||||
while (await _visitTaskRepository.AnyAsync(t => t.TaskBlindName == taskName && t.TrialId == trialId))
|
||||
{
|
||||
taskName = GenerateTaskNo();
|
||||
}
|
||||
|
||||
existList.Add(taskName);
|
||||
|
||||
return taskName;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
//基于标准签名 产生任务 (或者手动选择某些访视生成该标准的任务)
|
||||
public async Task BaseCritrionGenerateVisitTask(Guid trialId, Guid confirmedTrialReadingCriterionId, bool? isManualSelectVisit = null, List<Guid>? subjectVisitIdList = null)
|
||||
@@ -151,11 +190,11 @@ namespace IRaCIS.Core.Application.Service
|
||||
|
||||
var dbMaxCode = _visitTaskRepository.Where(t => t.TrialId == trialId).Select(t => t.Code).DefaultIfEmpty().Max();
|
||||
|
||||
var cacheMaxCodeInt = _fusionCache.GetOrDefault<int>(CacheKeys.TrialStudyMaxCode(trialId));
|
||||
var cacheMaxCodeInt = _fusionCache.GetOrDefault<int>(CacheKeys.TrialVisitTaskMaxCode(trialId));
|
||||
|
||||
int currentMaxCodeInt = cacheMaxCodeInt > dbMaxCode ? cacheMaxCodeInt : dbMaxCode;
|
||||
|
||||
|
||||
var randomTaskBlindNameList = new List<string>();
|
||||
|
||||
foreach (var subjectGroup in needGenerateVisit.GroupBy(t => t.SubjectId).Select(g => new { SubjectId = g.Key, SubjectVisitList = g.ToList() }))
|
||||
{
|
||||
@@ -173,6 +212,8 @@ namespace IRaCIS.Core.Application.Service
|
||||
|
||||
var blindTaskName = string.Empty;
|
||||
|
||||
var isRandom = false;
|
||||
|
||||
if (trialReadingCriterionConfig.IsReadingTaskViewInOrder == ReadingOrder.InOrder)
|
||||
{
|
||||
if (visitNumList.IndexOf(subjectVisit.VisitNum) == 0 && subjectVisit.VisitNum == 0)
|
||||
@@ -185,6 +226,12 @@ namespace IRaCIS.Core.Application.Service
|
||||
|
||||
}
|
||||
}
|
||||
else if (trialReadingCriterionConfig.IsReadingTaskViewInOrder == ReadingOrder.Random)
|
||||
{
|
||||
blindTaskName = await GetRandomTaskName(trialId, randomTaskBlindNameList);
|
||||
|
||||
isRandom = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
blindTaskName = "Timepoint";
|
||||
@@ -258,12 +305,14 @@ namespace IRaCIS.Core.Application.Service
|
||||
currentMaxCodeInt = currentMaxCodeInt + 1;
|
||||
|
||||
|
||||
var blindTaskName2 = isRandom ? await GetRandomTaskName(trialId, randomTaskBlindNameList) : blindTaskName;
|
||||
|
||||
task2 = await _visitTaskRepository.AddAsync(new VisitTask()
|
||||
{
|
||||
TrialId = trialId,
|
||||
SubjectId = subjectVisit.SubjectId,
|
||||
IsUrgent = subjectVisit.IsUrgent,
|
||||
TaskBlindName = blindTaskName,
|
||||
TaskBlindName = blindTaskName2,
|
||||
TaskName = subjectVisit.VisitName,
|
||||
TaskUrgentType = taskUrgentType,
|
||||
IsCanEditUrgentState = isCanEditUrgentState,
|
||||
@@ -283,7 +332,7 @@ namespace IRaCIS.Core.Application.Service
|
||||
|
||||
}
|
||||
|
||||
_fusionCache.Set<int>(CacheKeys.TrialStudyMaxCode(trialId), currentMaxCodeInt, TimeSpan.FromMinutes(30));
|
||||
_fusionCache.Set<int>(CacheKeys.TrialVisitTaskMaxCode(trialId), currentMaxCodeInt, TimeSpan.FromMinutes(30));
|
||||
|
||||
|
||||
|
||||
@@ -344,7 +393,7 @@ namespace IRaCIS.Core.Application.Service
|
||||
|
||||
|
||||
|
||||
_fusionCache.Set<int>(CacheKeys.TrialStudyMaxCode(trialId), currentMaxCodeInt, TimeSpan.FromMinutes(30));
|
||||
_fusionCache.Set<int>(CacheKeys.TrialVisitTaskMaxCode(trialId), currentMaxCodeInt, TimeSpan.FromMinutes(30));
|
||||
|
||||
|
||||
|
||||
@@ -590,11 +639,11 @@ namespace IRaCIS.Core.Application.Service
|
||||
|
||||
var dbMaxCode = _visitTaskRepository.Where(t => t.TrialId == trialId).Select(t => t.Code).DefaultIfEmpty().Max();
|
||||
|
||||
var cacheMaxCodeInt = _fusionCache.GetOrDefault<int>(CacheKeys.TrialStudyMaxCode(trialId));
|
||||
var cacheMaxCodeInt = _fusionCache.GetOrDefault<int>(CacheKeys.TrialVisitTaskMaxCode(trialId));
|
||||
|
||||
int currentMaxCodeInt = cacheMaxCodeInt > dbMaxCode ? cacheMaxCodeInt : dbMaxCode;
|
||||
|
||||
|
||||
var randomTaskBlindNameList = new List<string>();
|
||||
|
||||
|
||||
switch (generateTaskCommand.ReadingCategory)
|
||||
@@ -654,7 +703,9 @@ namespace IRaCIS.Core.Application.Service
|
||||
|
||||
var isFrontTaskNeedSignButNotSign = await _visitTaskRepository.AnyAsync(t => t.TrialReadingCriterionId == trialReadingCriterionId && t.SubjectId == subjectVisit.SubjectId && t.TaskState == TaskState.Effect && t.VisitTaskNum < subjectVisit.VisitNum && t.IsNeedClinicalDataSign == true && t.IsClinicalDataSign == false);
|
||||
|
||||
|
||||
var blindTaskName = string.Empty;
|
||||
var isFullRandom = false;
|
||||
|
||||
if (trialReadingCriterionConfig.IsReadingTaskViewInOrder == ReadingOrder.InOrder)
|
||||
{
|
||||
@@ -668,6 +719,12 @@ namespace IRaCIS.Core.Application.Service
|
||||
|
||||
}
|
||||
}
|
||||
else if (trialReadingCriterionConfig.IsReadingTaskViewInOrder == ReadingOrder.Random)
|
||||
{
|
||||
blindTaskName = await GetRandomTaskName(trialId, randomTaskBlindNameList);
|
||||
isFullRandom = true;
|
||||
}
|
||||
//受试者随机
|
||||
else
|
||||
{
|
||||
blindTaskName = "Timepoint";
|
||||
@@ -710,6 +767,7 @@ namespace IRaCIS.Core.Application.Service
|
||||
TaskCode = AppSettings.GetCodeStr(currentMaxCodeInt, nameof(VisitTask)),
|
||||
ReadingCategory = ReadingCategory.Visit,
|
||||
|
||||
|
||||
TrialReadingCriterionId = trialReadingCriterionConfig.TrialReadingCriterionId,
|
||||
IsNeedClinicalDataSign = isNeedClinicalDataSign,
|
||||
IsClinicalDataSign = isClinicalDataSign,
|
||||
@@ -721,11 +779,15 @@ namespace IRaCIS.Core.Application.Service
|
||||
if (!existCurrentVisitTaskList.Any(t => t.ArmEnum == Arm.DoubleReadingArm2))
|
||||
{
|
||||
currentMaxCodeInt = currentMaxCodeInt + 1;
|
||||
|
||||
var blindTaskName2 = isFullRandom ? await GetRandomTaskName(trialId, randomTaskBlindNameList) : blindTaskName;
|
||||
|
||||
|
||||
task2 = await _visitTaskRepository.AddAsync(new VisitTask()
|
||||
{
|
||||
TrialId = trialId,
|
||||
SubjectId = subjectVisit.SubjectId,
|
||||
TaskBlindName = blindTaskName,
|
||||
TaskBlindName = blindTaskName2,
|
||||
TaskName = subjectVisit.VisitName,
|
||||
IsUrgent = subjectVisit.IsUrgent,
|
||||
|
||||
@@ -747,7 +809,7 @@ namespace IRaCIS.Core.Application.Service
|
||||
}
|
||||
|
||||
|
||||
_fusionCache.Set<int>(CacheKeys.TrialStudyMaxCode(trialId), currentMaxCodeInt, TimeSpan.FromMinutes(30));
|
||||
_fusionCache.Set<int>(CacheKeys.TrialVisitTaskMaxCode(trialId), currentMaxCodeInt, TimeSpan.FromMinutes(30));
|
||||
|
||||
|
||||
#region 分配
|
||||
@@ -873,7 +935,7 @@ namespace IRaCIS.Core.Application.Service
|
||||
{
|
||||
arm1.TaskAllocationState = TaskAllocationState.Allocated;
|
||||
arm1.AllocateTime = DateTime.Now;
|
||||
arm1.DoctorUserId = task1.DoctorUserId;
|
||||
arm1.DoctorUserId = assignConfigList.FirstOrDefault(t => t.ArmEnum == Arm.DoubleReadingArm1)!.DoctorUserId;
|
||||
arm1.SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget);
|
||||
}
|
||||
|
||||
@@ -913,14 +975,14 @@ namespace IRaCIS.Core.Application.Service
|
||||
{
|
||||
taskOne.TaskAllocationState = TaskAllocationState.Allocated;
|
||||
taskOne.AllocateTime = DateTime.Now;
|
||||
taskOne.DoctorUserId = task1!.DoctorUserId;
|
||||
taskOne.DoctorUserId = assignConfigList.FirstOrDefault(t => t.ArmEnum == Arm.DoubleReadingArm1)!.DoctorUserId;
|
||||
taskOne.SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget);
|
||||
}
|
||||
|
||||
|
||||
currentMaxCodeInt = currentMaxCodeInt + 1;
|
||||
|
||||
_fusionCache.Set<int>(CacheKeys.TrialStudyMaxCode(trialId), currentMaxCodeInt, TimeSpan.FromMinutes(30));
|
||||
_fusionCache.Set<int>(CacheKeys.TrialVisitTaskMaxCode(trialId), currentMaxCodeInt, TimeSpan.FromMinutes(30));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -944,7 +1006,7 @@ namespace IRaCIS.Core.Application.Service
|
||||
{
|
||||
arm2.TaskAllocationState = TaskAllocationState.Allocated;
|
||||
arm2.AllocateTime = DateTime.Now;
|
||||
arm2.DoctorUserId = task2.DoctorUserId;
|
||||
arm2.DoctorUserId = assignConfigList.FirstOrDefault(t => t.ArmEnum == Arm.DoubleReadingArm2)!.DoctorUserId;
|
||||
arm2.SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget);
|
||||
}
|
||||
|
||||
@@ -986,13 +1048,13 @@ namespace IRaCIS.Core.Application.Service
|
||||
{
|
||||
taskTwo.TaskAllocationState = TaskAllocationState.Allocated;
|
||||
taskTwo.AllocateTime = DateTime.Now;
|
||||
taskTwo.DoctorUserId = task2!.DoctorUserId;
|
||||
taskTwo.DoctorUserId = assignConfigList.FirstOrDefault(t => t.ArmEnum == Arm.DoubleReadingArm2)!.DoctorUserId;
|
||||
taskTwo.SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget);
|
||||
}
|
||||
|
||||
currentMaxCodeInt = currentMaxCodeInt + 1;
|
||||
|
||||
_fusionCache.Set<int>(CacheKeys.TrialStudyMaxCode(trialId), currentMaxCodeInt, TimeSpan.FromMinutes(30));
|
||||
_fusionCache.Set<int>(CacheKeys.TrialVisitTaskMaxCode(trialId), currentMaxCodeInt, TimeSpan.FromMinutes(30));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1069,7 +1131,7 @@ namespace IRaCIS.Core.Application.Service
|
||||
|
||||
currentMaxCodeInt = currentMaxCodeInt + 1;
|
||||
|
||||
_fusionCache.Set<int>(CacheKeys.TrialStudyMaxCode(trialId), currentMaxCodeInt, TimeSpan.FromMinutes(30));
|
||||
_fusionCache.Set<int>(CacheKeys.TrialVisitTaskMaxCode(trialId), currentMaxCodeInt, TimeSpan.FromMinutes(30));
|
||||
|
||||
#region 分配
|
||||
|
||||
@@ -1197,7 +1259,7 @@ namespace IRaCIS.Core.Application.Service
|
||||
|
||||
currentMaxCodeInt = currentMaxCodeInt + 1;
|
||||
|
||||
_fusionCache.Set<int>(CacheKeys.TrialStudyMaxCode(trialId), currentMaxCodeInt, TimeSpan.FromMinutes(30));
|
||||
_fusionCache.Set<int>(CacheKeys.TrialVisitTaskMaxCode(trialId), currentMaxCodeInt, TimeSpan.FromMinutes(30));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1277,6 +1339,7 @@ namespace IRaCIS.Core.Application.Service
|
||||
|
||||
var reReadingVisitTask = generateTaskCommand.ReReadingTask;
|
||||
|
||||
|
||||
Guid? subjectVisitId = Guid.Empty;
|
||||
|
||||
if (reReadingVisitTask.SourceSubjectVisitId == null)
|
||||
@@ -1317,6 +1380,10 @@ namespace IRaCIS.Core.Application.Service
|
||||
//&& t.TrialReadingCriterionId == reReadingVisitTask.TrialReadingCriterionId && t.TaskState == TaskState.Effect
|
||||
// && t.SourceSubjectVisitId == reReadingVisitTask.SourceSubjectVisitId && t.ArmEnum == reReadingVisitTask.ArmEnum && t.DoctorUserId == reReadingVisitTask.DoctorUserId).FirstOrDefault();
|
||||
|
||||
var isRandomReading = trialReadingCriterionConfigList.FirstOrDefault(t => t.TrialReadingCriterionId == reReadingVisitTask.TrialReadingCriterionId)?.IsReadingTaskViewInOrder == ReadingOrder.Random;
|
||||
|
||||
var taskBlindName = isRandomReading ? await GetRandomTaskName(trialId, randomTaskBlindNameList) : reReadingVisitTask.TaskBlindName;
|
||||
|
||||
|
||||
var newTask = await _visitTaskRepository.AddAsync(new VisitTask()
|
||||
{
|
||||
@@ -1325,7 +1392,7 @@ namespace IRaCIS.Core.Application.Service
|
||||
SubjectId = reReadingVisitTask.SubjectId,
|
||||
ArmEnum = reReadingVisitTask.ArmEnum,
|
||||
TaskName = reReadingVisitTask.TaskName,
|
||||
TaskBlindName = reReadingVisitTask.TaskBlindName,
|
||||
TaskBlindName = taskBlindName,
|
||||
|
||||
IsUrgent = reReadingVisitTask.IsAnalysisCreate ? false : subjectVisitUrgentInfo.IsUrgent,
|
||||
TaskUrgentType = reReadingVisitTask.IsAnalysisCreate ? null : taskUrgent,
|
||||
@@ -1355,6 +1422,7 @@ namespace IRaCIS.Core.Application.Service
|
||||
// AllocateTime = DateTime.Now,
|
||||
//DoctorUserId = reReadingVisitTask.DoctorUserId,
|
||||
|
||||
IsIRImageDownloaded= reReadingVisitTask.IsIRImageDownloaded,
|
||||
});
|
||||
|
||||
generateTaskCommand.Action(newTask);
|
||||
@@ -1386,7 +1454,7 @@ namespace IRaCIS.Core.Application.Service
|
||||
|
||||
currentMaxCodeInt = currentMaxCodeInt + 1;
|
||||
|
||||
_fusionCache.Set<int>(CacheKeys.TrialStudyMaxCode(trialId), currentMaxCodeInt, TimeSpan.FromMinutes(30));
|
||||
_fusionCache.Set<int>(CacheKeys.TrialVisitTaskMaxCode(trialId), currentMaxCodeInt, TimeSpan.FromMinutes(30));
|
||||
|
||||
//}
|
||||
|
||||
@@ -1491,7 +1559,7 @@ namespace IRaCIS.Core.Application.Service
|
||||
|
||||
currentMaxCodeInt = currentMaxCodeInt + 1;
|
||||
|
||||
_fusionCache.Set<int>(CacheKeys.TrialStudyMaxCode(trialId), currentMaxCodeInt, TimeSpan.FromMinutes(30));
|
||||
_fusionCache.Set<int>(CacheKeys.TrialVisitTaskMaxCode(trialId), currentMaxCodeInt, TimeSpan.FromMinutes(30));
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -1538,7 +1606,7 @@ namespace IRaCIS.Core.Application.Service
|
||||
|
||||
currentMaxCodeInt = currentMaxCodeInt + 1;
|
||||
|
||||
_fusionCache.Set<int>(CacheKeys.TrialStudyMaxCode(trialId), currentMaxCodeInt, TimeSpan.FromMinutes(30));
|
||||
_fusionCache.Set<int>(CacheKeys.TrialVisitTaskMaxCode(trialId), currentMaxCodeInt, TimeSpan.FromMinutes(30));
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -1548,6 +1616,11 @@ namespace IRaCIS.Core.Application.Service
|
||||
|
||||
var subjectUser = await _subjectUserRepository.Where(x => x.SubjectId == firstTask.SubjectId && x.ArmEnum == Arm.JudgeArm && x.IsConfirmed && x.TrialReadingCriterionId == firstTask.TrialReadingCriterionId).FirstOrDefaultAsync();
|
||||
|
||||
|
||||
var isRandom = trialReadingCriterionConfigList.FirstOrDefault(t => t.TrialReadingCriterionId == firstTask.TrialReadingCriterionId)?.IsReadingTaskViewInOrder == ReadingOrder.Random;
|
||||
|
||||
var blindName = isRandom ? await GetRandomTaskName(trialId, randomTaskBlindNameList) : firstTask.TaskBlindName;
|
||||
|
||||
VisitTask visitTask = new VisitTask()
|
||||
{
|
||||
ArmEnum = Arm.JudgeArm,
|
||||
@@ -1564,7 +1637,7 @@ namespace IRaCIS.Core.Application.Service
|
||||
SouceReadModuleId = firstTask.SouceReadModuleId,
|
||||
TaskCode = AppSettings.GetCodeStr(currentMaxCodeInt + 1, nameof(VisitTask)),
|
||||
TaskState = TaskState.Effect,
|
||||
TaskBlindName = firstTask.TaskBlindName,
|
||||
TaskBlindName = blindName,
|
||||
DoctorUserId = subjectUser == null ? null : subjectUser.DoctorUserId,
|
||||
TaskAllocationState = subjectUser == null ? TaskAllocationState.NotAllocate : TaskAllocationState.Allocated,
|
||||
AllocateTime = subjectUser == null ? null : DateTime.Now,
|
||||
@@ -1576,7 +1649,7 @@ namespace IRaCIS.Core.Application.Service
|
||||
await _visitTaskRepository.AddAsync(visitTask);
|
||||
currentMaxCodeInt = currentMaxCodeInt + 1;
|
||||
|
||||
_fusionCache.Set<int>(CacheKeys.TrialStudyMaxCode(trialId), currentMaxCodeInt, TimeSpan.FromMinutes(30));
|
||||
_fusionCache.Set<int>(CacheKeys.TrialVisitTaskMaxCode(trialId), currentMaxCodeInt, TimeSpan.FromMinutes(30));
|
||||
|
||||
await _visitTaskRepository.BatchUpdateNoTrackingAsync(x => generateTaskCommand.JudgeVisitTaskIdList.Contains(x.Id), x => new VisitTask()
|
||||
{
|
||||
@@ -1637,7 +1710,7 @@ namespace IRaCIS.Core.Application.Service
|
||||
});
|
||||
|
||||
currentMaxCodeInt = currentMaxCodeInt + 1;
|
||||
_fusionCache.Set<int>(CacheKeys.TrialStudyMaxCode(trialId), currentMaxCodeInt, TimeSpan.FromMinutes(30));
|
||||
_fusionCache.Set<int>(CacheKeys.TrialVisitTaskMaxCode(trialId), currentMaxCodeInt, TimeSpan.FromMinutes(30));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1707,7 +1780,7 @@ namespace IRaCIS.Core.Application.Service
|
||||
TrialId = originalTaskInfo.TrialId
|
||||
});
|
||||
|
||||
_fusionCache.Set<int>(CacheKeys.TrialStudyMaxCode(trialId), currentMaxCodeInt, TimeSpan.FromMinutes(30));
|
||||
_fusionCache.Set<int>(CacheKeys.TrialVisitTaskMaxCode(trialId), currentMaxCodeInt, TimeSpan.FromMinutes(30));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -53,7 +53,11 @@ public class VisitTaskService(IRepository<VisitTask> _visitTaskRepository,
|
||||
IRepository<ReadingNoneDicomMark> _readingNoneDicomMarkRepository,
|
||||
IRepository<ReadingNoneDicomMarkBinding> _readingNoneDicomMarkBindingRepository,
|
||||
IRepository<ReadingTableAnswerRowInfo> _readingTableAnswerRowInfoRepository,
|
||||
//IRepository<ReadingCustomTag> _readingCustomTagRepository,
|
||||
//IRepository<ReadingCustomTag> _readingCustomTagRepository,
|
||||
IRepository<TaskStudy> _taskStudyRepository,
|
||||
IRepository<TaskSeries> _taskSeriesRepository,
|
||||
IRepository<TaskInstance> _taskInstanceRepository,
|
||||
IRepository<NoneDicomStudyFile> _noneDicomStudyFileRepository,
|
||||
IRepository<TaskInfluence> _taskInfluenceRepository,
|
||||
IRepository<TrialQCQuestionAnswer> _trialQCQuestionAnswerRepository,
|
||||
ILogger<VisitTaskService> _logger,
|
||||
@@ -91,6 +95,7 @@ public class VisitTaskService(IRepository<VisitTask> _visitTaskRepository,
|
||||
{
|
||||
TrialReadingCriterionId = t.Id,
|
||||
IsAutoCreate = t.IsAutoCreate,
|
||||
ReadingTool = t.ReadingTool,
|
||||
IsAdditionalAssessment = t.IsAdditionalAssessment,
|
||||
TrialReadingCriterionName = t.CriterionName,
|
||||
CriterionType = t.CriterionType,
|
||||
@@ -849,7 +854,7 @@ public class VisitTaskService(IRepository<VisitTask> _visitTaskRepository,
|
||||
/// <param name="inQuery"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<PageOutput<ReReadingTaskView>> GetIRReReadingTaskList(VisitTaskQuery inQuery)
|
||||
public async Task<IResponseOutput<PageOutput<ReReadingTaskView>>> GetIRReReadingTaskList(VisitTaskQuery inQuery)
|
||||
{
|
||||
|
||||
var visitTaskQueryable = _visitTaskReReadingRepository
|
||||
@@ -873,6 +878,7 @@ public class VisitTaskService(IRepository<VisitTask> _visitTaskRepository,
|
||||
|
||||
.WhereIf(!string.IsNullOrEmpty(inQuery.TrialSiteCode), t => (t.OriginalReReadingTask.BlindTrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.OriginalReReadingTask.IsAnalysisCreate) || (t.OriginalReReadingTask.Subject.TrialSite.TrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.OriginalReReadingTask.IsAnalysisCreate == false))
|
||||
.WhereIf(!string.IsNullOrEmpty(inQuery.TaskName), t => t.OriginalReReadingTask.TaskName.Contains(inQuery.TaskName) || t.NewReReadingTask.TaskBlindName.Contains(inQuery.TaskName))
|
||||
.WhereIf(!string.IsNullOrEmpty(inQuery.TaskBlindName), t => t.NewReReadingTask.TaskBlindName.Contains(inQuery.TaskBlindName))
|
||||
.WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => (t.OriginalReReadingTask.Subject.Code.Contains(inQuery.SubjectCode) && t.OriginalReReadingTask.IsAnalysisCreate == false) || (t.OriginalReReadingTask.BlindSubjectCode.Contains(inQuery.SubjectCode) && t.OriginalReReadingTask.IsAnalysisCreate))
|
||||
.WhereIf(inQuery.BeginAllocateDate != null, t => t.OriginalReReadingTask.AllocateTime > inQuery.BeginAllocateDate)
|
||||
.WhereIf(inQuery.EndAllocateDate != null, t => t.OriginalReReadingTask.AllocateTime < inQuery.EndAllocateDate!.Value.AddDays(1))
|
||||
@@ -884,7 +890,11 @@ public class VisitTaskService(IRepository<VisitTask> _visitTaskRepository,
|
||||
|
||||
var pageList = await visitTaskQueryable.ToPagedListAsync(inQuery, defalutSortArray);
|
||||
|
||||
return pageList;
|
||||
var criterionInfo = await _readingQuestionCriterionTrialRepository.Where(t => t.Id == inQuery.TrialReadingCriterionId)
|
||||
.Select(t => new { t.IsReadingTaskViewInOrder }).FirstNotNullAsync();
|
||||
|
||||
return ResponseOutput.Ok(pageList, criterionInfo);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1016,9 +1026,9 @@ public class VisitTaskService(IRepository<VisitTask> _visitTaskRepository,
|
||||
|
||||
if (critrion.IsReadingTaskViewInOrder == ReadingOrder.InOrder)
|
||||
{
|
||||
var extralObj = _trialRepository.Where(t => t.Id == trialId).Select(t => new { t.TrialExtraConfigJsonStr }).FirstOrDefault();
|
||||
var extralObj = _trialRepository.Where(t => t.Id == trialId).Select(t => new { t.IsOpenLostVistRead }).FirstOrDefault();
|
||||
|
||||
var extralConfig = JsonConvert.DeserializeObject<TrialExtraConfig>(extralObj?.TrialExtraConfigJsonStr) ?? new TrialExtraConfig();
|
||||
//var extralConfig = JsonConvert.DeserializeObject<TrialExtraConfig>(extralObj?.TrialExtraConfigJsonStr) ?? new TrialExtraConfig();
|
||||
|
||||
var visitQuery = _visitTaskRepository.Where(x => x.TrialId == inQuery.TrialId && x.DoctorUserId == _userInfo.UserRoleId && x.TaskState == TaskState.Effect && x.Subject.IsSubjectQuit == false)
|
||||
|
||||
@@ -1027,7 +1037,7 @@ public class VisitTaskService(IRepository<VisitTask> _visitTaskRepository,
|
||||
.WhereIf(critrion.IsAutoCreate == false, t => !t.Subject.SubjectCriteriaEvaluationVisitFilterList.Where(t => t.TrialReadingCriterionId == trialReadingCriterionId).Any(f => f.IsGeneratedTask == false && t.VisitTaskNum > f.SubjectVisit.VisitNum))
|
||||
|
||||
// 前序 不存在 未一致性核查未通过的
|
||||
.Where(t => !t.Subject.SubjectVisitList.Where(t => extralConfig.IsOpenLostVistRead ? t.IsLostVisit == false : true).Any(sv => sv.CheckState != CheckStateEnum.CVPassed && t.VisitTaskNum >= sv.VisitNum))
|
||||
.Where(t => !t.Subject.SubjectVisitList.Where(t => extralObj.IsOpenLostVistRead ? t.IsLostVisit == false : true).Any(sv => sv.CheckState != CheckStateEnum.CVPassed && t.VisitTaskNum >= sv.VisitNum))
|
||||
//.WhereIf(critrion.IsAutoCreate == false, t => t.Subject.SubjectCriteriaEvaluationVisitFilterList.Where(t => t.TrialReadingCriterionId == trialReadingCriterionId).Any(t => t.IsGeneratedTask == false) ?
|
||||
//t.VisitTaskNum <= t.Subject.SubjectCriteriaEvaluationVisitFilterList.Where(t => t.TrialReadingCriterionId == trialReadingCriterionId && t.IsGeneratedTask == false).Min(t => t.SubjectVisit.VisitNum) : true)
|
||||
//.Where(t => t.Subject.SubjectVisitList.Any(t => t.CheckState != CheckStateEnum.CVPassed) ? t.VisitTaskNum <= t.Subject.SubjectVisitList.Where(t => t.CheckState != CheckStateEnum.CVPassed).Min(t => t.VisitNum) : true)
|
||||
@@ -1050,14 +1060,14 @@ public class VisitTaskService(IRepository<VisitTask> _visitTaskRepository,
|
||||
UnReadTaskCount = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned).Count(),
|
||||
|
||||
//未读 里可读任务量
|
||||
UnReadCanReadTaskCount = x.Where(t => extralConfig.IsOpenLostVistRead ? true : t.IsFrontTaskNeedSignButNotSign == false).Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned && (y.IsNeedClinicalDataSign == false || y.IsClinicalDataSign == true)
|
||||
UnReadCanReadTaskCount = x.Where(t => extralObj.IsOpenLostVistRead ? true : t.IsFrontTaskNeedSignButNotSign == false).Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned && (y.IsNeedClinicalDataSign == false || y.IsClinicalDataSign == true)
|
||||
//不能对包含聚合或子查询的表达式执行聚合函数
|
||||
//&& !x.Any(t => t.ReadingTaskState != ReadingTaskState.HaveSigned && t.IsNeedClinicalDataSign == true && t.IsClinicalDataSign == false && t.VisitTaskNum<y.VisitTaskNum )
|
||||
).Count(),
|
||||
|
||||
|
||||
UnReadCanReadTaskList = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned)
|
||||
.Where(t => extralConfig.IsOpenLostVistRead ? true : t.IsFrontTaskNeedSignButNotSign == false)
|
||||
.Where(t => extralObj.IsOpenLostVistRead ? true : t.IsFrontTaskNeedSignButNotSign == false)
|
||||
.Where(y => /*y.IsFrontTaskNeedSignButNotSign == false &&*/ (y.IsNeedClinicalDataSign == false || y.IsClinicalDataSign == true))
|
||||
.OrderBy(x => x.VisitTaskNum)
|
||||
.Select(u => new IRUnreadTaskView()
|
||||
@@ -1237,7 +1247,7 @@ public class VisitTaskService(IRepository<VisitTask> _visitTaskRepository,
|
||||
/// <param name="inQuery"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<PageOutput<IRHaveReadView>> GetIRHaveReadTaskList(VisitTaskQuery inQuery)
|
||||
public async Task<IResponseOutput<PageOutput<IRHaveReadView>>> GetIRHaveReadTaskList(VisitTaskQuery inQuery)
|
||||
{
|
||||
|
||||
|
||||
@@ -1256,6 +1266,7 @@ public class VisitTaskService(IRepository<VisitTask> _visitTaskRepository,
|
||||
.WhereIf(inQuery.TaskState != null, t => t.TaskState == inQuery.TaskState)
|
||||
.WhereIf(!string.IsNullOrEmpty(inQuery.TrialSiteCode), t => (t.BlindTrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.IsAnalysisCreate) || (t.Subject.TrialSite.TrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.IsAnalysisCreate == false))
|
||||
.WhereIf(!string.IsNullOrEmpty(inQuery.TaskName), t => t.TaskName.Contains(inQuery.TaskName) || t.TaskBlindName.Contains(inQuery.TaskName))
|
||||
.WhereIf(!string.IsNullOrEmpty(inQuery.TaskBlindName), t => t.TaskBlindName.Contains(inQuery.TaskBlindName))
|
||||
.WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => (t.Subject.Code.Contains(inQuery.SubjectCode) && t.IsAnalysisCreate == false) || (t.BlindSubjectCode.Contains(inQuery.SubjectCode) && t.IsAnalysisCreate))
|
||||
.WhereIf(inQuery.BeginAllocateDate != null, t => t.AllocateTime > inQuery.BeginAllocateDate)
|
||||
.WhereIf(inQuery.EndAllocateDate != null, t => t.AllocateTime < inQuery.EndAllocateDate!.Value.AddDays(1))
|
||||
@@ -1265,7 +1276,10 @@ public class VisitTaskService(IRepository<VisitTask> _visitTaskRepository,
|
||||
|
||||
var pageList = await visitTaskQueryable.ToPagedListAsync(inQuery, defalutSortArray);
|
||||
|
||||
return pageList;
|
||||
var criterionInfo = await _readingQuestionCriterionTrialRepository.Where(t => t.Id == inQuery.TrialReadingCriterionId)
|
||||
.Select(t => new { t.IsReadingTaskViewInOrder }).FirstNotNullAsync();
|
||||
|
||||
return ResponseOutput.Ok(pageList, criterionInfo);
|
||||
}
|
||||
|
||||
|
||||
@@ -2074,29 +2088,37 @@ public class VisitTaskService(IRepository<VisitTask> _visitTaskRepository,
|
||||
//申请表 设置新任务Id
|
||||
visitTaskReReadingAppply.NewReReadingTaskId = newTask.Id;
|
||||
|
||||
//拷贝原始表单
|
||||
if (visitTaskReReadingAppply.IsCopyOrigenalForms && influenceTask.Id == origenalTask.Id)
|
||||
|
||||
if (origenalTask.ReadingCategory == ReadingCategory.Visit)
|
||||
{
|
||||
if (origenalTask.ReadingCategory == ReadingCategory.Visit)
|
||||
CopyImages(newTask, influenceTask);
|
||||
|
||||
//拷贝原始表单
|
||||
if (visitTaskReReadingAppply.IsCopyOrigenalForms && influenceTask.Id == origenalTask.Id)
|
||||
{
|
||||
CopyForms(newTask, origenalTask);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//拷贝后续表单
|
||||
if (visitTaskReReadingAppply.IsCopyFollowForms && origenalTask.VisitTaskNum != influenceTask.VisitTaskNum)
|
||||
{
|
||||
if (origenalTask.ReadingCategory == ReadingCategory.Visit)
|
||||
//拷贝后续表单
|
||||
if (visitTaskReReadingAppply.IsCopyFollowForms && origenalTask.VisitTaskNum != influenceTask.VisitTaskNum)
|
||||
{
|
||||
newTask.IsCopyLesionAnswer = true;
|
||||
|
||||
//CopyForms(newTask, origenalTask);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
if (origenalTask.ReadingCategory == ReadingCategory.Judge)
|
||||
{
|
||||
//拷贝原始表单
|
||||
if (visitTaskReReadingAppply.IsCopyOrigenalForms && influenceTask.Id == origenalTask.Id)
|
||||
{
|
||||
CopyForms(newTask, origenalTask);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2178,6 +2200,9 @@ public class VisitTaskService(IRepository<VisitTask> _visitTaskRepository,
|
||||
newTask.SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget);
|
||||
|
||||
|
||||
CopyImages(newTask, influenceTask);
|
||||
|
||||
|
||||
//裁判任务 需要进行特殊处理 在重阅逻辑里面处理
|
||||
|
||||
if (visitTaskReReadingAppply != null)
|
||||
@@ -2194,16 +2219,16 @@ public class VisitTaskService(IRepository<VisitTask> _visitTaskRepository,
|
||||
|
||||
}
|
||||
|
||||
//拷贝后续表单
|
||||
if (visitTaskReReadingAppply.IsCopyFollowForms && origenalTask.VisitTaskNum != influenceTask.VisitTaskNum)
|
||||
{
|
||||
if (origenalTask.ReadingCategory == ReadingCategory.Visit)
|
||||
{
|
||||
newTask.IsCopyLesionAnswer = true;
|
||||
//CopyForms(newTask, origenalTask);
|
||||
////拷贝后续表单
|
||||
//if (visitTaskReReadingAppply.IsCopyFollowForms && origenalTask.VisitTaskNum != influenceTask.VisitTaskNum)
|
||||
//{
|
||||
// if (origenalTask.ReadingCategory == ReadingCategory.Visit)
|
||||
// {
|
||||
// newTask.IsCopyLesionAnswer = true;
|
||||
// //CopyForms(newTask, origenalTask);
|
||||
|
||||
}
|
||||
}
|
||||
// }
|
||||
//}
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -2223,7 +2248,84 @@ public class VisitTaskService(IRepository<VisitTask> _visitTaskRepository,
|
||||
}
|
||||
}
|
||||
|
||||
private async Task CopyForms(VisitTask newTask, VisitTask origenalTask)
|
||||
|
||||
private void CopyImages(VisitTask newTask, VisitTask origenalTask)
|
||||
{
|
||||
//拷贝后处理绑定的的Dicom影像
|
||||
|
||||
var newTaskId = newTask.Id;
|
||||
|
||||
var taskStudyList = _taskStudyRepository.Where(t => t.VisitTaskId == origenalTask.Id).ToList();
|
||||
|
||||
var taskSeriesList = _taskSeriesRepository.Where(t => t.VisitTaskId == origenalTask.Id).ToList();
|
||||
var taskInstanceList = _taskInstanceRepository.Where(t => t.VisitTaskId == origenalTask.Id).ToList();
|
||||
|
||||
|
||||
foreach (var taskStudy in taskStudyList)
|
||||
{
|
||||
var newStudyId = IdentifierHelper.CreateGuid(taskStudy.StudyInstanceUid, taskStudy.TrialId.ToString(), newTaskId.ToString());
|
||||
|
||||
var newStudy = taskStudy.Clone();
|
||||
newStudy.Id = newStudyId;
|
||||
newStudy.SeqId = NewId.NextSequentialGuid();
|
||||
newStudy.VisitTaskId = newTaskId;
|
||||
|
||||
_ = _taskStudyRepository.AddAsync(newStudy).Result;
|
||||
|
||||
var studySeriesList = taskSeriesList.Where(t => t.StudyId == taskStudy.Id).ToList();
|
||||
|
||||
foreach (var series in studySeriesList)
|
||||
{
|
||||
var newSeriesId = IdentifierHelper.CreateGuid(series.StudyInstanceUid, series.SeriesInstanceUid, series.TrialId.ToString(), newTaskId.ToString());
|
||||
|
||||
var newSeries = series.Clone();
|
||||
newSeries.Id = newSeriesId;
|
||||
newSeries.SeqId = NewId.NextSequentialGuid();
|
||||
newSeries.StudyId = newStudyId;
|
||||
newSeries.VisitTaskId = newTaskId;
|
||||
|
||||
|
||||
_ = _taskSeriesRepository.AddAsync(newSeries).Result;
|
||||
|
||||
|
||||
var studyInstanceList = taskInstanceList.Where(t => t.StudyId == taskStudy.Id && t.SeriesId == series.Id).ToList();
|
||||
|
||||
foreach (var instance in studyInstanceList)
|
||||
{
|
||||
var newInstanceId = IdentifierHelper.CreateGuid(newStudy.StudyInstanceUid, newSeries.SeriesInstanceUid, instance.SopInstanceUid, newStudy.TrialId.ToString(), newTaskId.ToString());
|
||||
|
||||
var newInstance = instance.Clone();
|
||||
|
||||
newInstance.Id = newInstanceId;
|
||||
newInstance.SeqId = NewId.NextSequentialGuid();
|
||||
newInstance.StudyId = newStudyId;
|
||||
newInstance.SeriesId = newSeriesId;
|
||||
newInstance.VisitTaskId = newTaskId;
|
||||
|
||||
Console.WriteLine($"StudyInstanceUid:{newStudy.StudyInstanceUid} SeriesInstanceUid:{newSeries.SeriesInstanceUid} SopInstanceUid: {instance.SopInstanceUid},newInstanceId:{newInstanceId} ");
|
||||
|
||||
_ = _taskInstanceRepository.AddAsync(newInstance).Result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//拷贝后处理的NoneDicom
|
||||
|
||||
var fileList = _noneDicomStudyFileRepository.Where(t => t.VisitTaskId == origenalTask.Id).ToList();
|
||||
|
||||
foreach (var file in fileList)
|
||||
{
|
||||
var newFile = file.Clone();
|
||||
|
||||
newFile.Id = NewId.NextSequentialGuid();
|
||||
newFile.VisitTaskId = newTaskId;
|
||||
|
||||
_ = _noneDicomStudyFileRepository.AddAsync(newFile).Result;
|
||||
}
|
||||
}
|
||||
private void CopyForms(VisitTask newTask, VisitTask origenalTask)
|
||||
{
|
||||
newTask.IsCopyLesionAnswer = true;
|
||||
//自定义
|
||||
@@ -2239,7 +2341,9 @@ public class VisitTaskService(IRepository<VisitTask> _visitTaskRepository,
|
||||
//_ = _readingCustomTagRepository.AddRangeAsync(readingCustomTagList).Result;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
var readingTaskQuestionAnswerList = _readingTaskQuestionAnswerRepository.Where(t => t.VisitTaskId == origenalTask.Id).ToList();
|
||||
@@ -2301,7 +2405,7 @@ public class VisitTaskService(IRepository<VisitTask> _visitTaskRepository,
|
||||
|
||||
#region 分割
|
||||
Dictionary<Guid, Guid> segmentationRelationship = new Dictionary<Guid, Guid>() { };
|
||||
var segmentationList = _segmentationRepository.Where(t => t.VisitTaskId == origenalTask.Id).ToList();
|
||||
var segmentationList = _segmentationRepository.Where(t => t.VisitTaskId == origenalTask.Id).ToList();
|
||||
|
||||
foreach (var item in segmentationList)
|
||||
{
|
||||
@@ -2314,7 +2418,7 @@ public class VisitTaskService(IRepository<VisitTask> _visitTaskRepository,
|
||||
|
||||
|
||||
Dictionary<Guid, Guid> segmentRelationship = new Dictionary<Guid, Guid>() { };
|
||||
var segmentList = _segmentRepository.Where(t => t.VisitTaskId == origenalTask.Id).ToList();
|
||||
var segmentList = _segmentRepository.Where(t => t.VisitTaskId == origenalTask.Id).ToList();
|
||||
foreach (var item in segmentList)
|
||||
{
|
||||
var newSegmentationId = NewId.NextSequentialGuid();
|
||||
@@ -2327,7 +2431,7 @@ public class VisitTaskService(IRepository<VisitTask> _visitTaskRepository,
|
||||
item.VisitTaskId = newTask.Id;
|
||||
}
|
||||
|
||||
var segmentBindingList = _segmentBindingRepository.Where(x => x.VisitTaskId == origenalTask.Id).ToList();
|
||||
var segmentBindingList = _segmentBindingRepository.Where(x => x.VisitTaskId == origenalTask.Id).ToList();
|
||||
|
||||
foreach (var item in segmentBindingList)
|
||||
{
|
||||
@@ -2718,7 +2822,7 @@ public class VisitTaskService(IRepository<VisitTask> _visitTaskRepository,
|
||||
|
||||
|
||||
// 处理阅片期的临床数据
|
||||
var readModuleIdList =await _readModuleRepository.Where(x => x.SubjectVisitId == sv.Id).Select(x => x.Id).ToListAsync();
|
||||
var readModuleIdList = await _readModuleRepository.Where(x => x.SubjectVisitId == sv.Id).Select(x => x.Id).ToListAsync();
|
||||
|
||||
|
||||
await _readingClinicalDataReposiotry.UpdatePartialFromQueryAsync(t => readModuleIdList.Contains(t.ReadingId), c => new ReadingClinicalData()
|
||||
|
||||
@@ -96,6 +96,8 @@ namespace IRaCIS.Application.Contracts
|
||||
public Guid? TrialReadingCriterionId { get; set; }
|
||||
|
||||
public Guid? SystemReadingCriterionId { get; set; }
|
||||
|
||||
public Guid? TrialId { get; set; }
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
// 生成时间 2026-03-10 06:15:31Z
|
||||
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
|
||||
//--------------------------------------------------------------------
|
||||
using System;
|
||||
using IRaCIS.Core.Domain.Share;
|
||||
using System.Collections.Generic;
|
||||
namespace IRaCIS.Core.Application.ViewModel;
|
||||
@@ -96,7 +95,22 @@ public class FileUploadRecordAddOrEdit
|
||||
public bool? IsSync { get; set; }
|
||||
}
|
||||
|
||||
public class CommonUploadRecordDto: CommonUploadRecordAddOrEdit
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public class CommonUploadRecordAddOrEdit
|
||||
{
|
||||
public Guid? Id { get; set; }
|
||||
public string FileType { get; set; }
|
||||
|
||||
public string FileName { get; set; }
|
||||
|
||||
public long FileSize { get; set; }
|
||||
|
||||
public string Path { get; set; }
|
||||
}
|
||||
public class SubjectFileUploadRecordQuery : PageInput
|
||||
{
|
||||
public Guid TrialId { get; set; }
|
||||
|
||||
@@ -0,0 +1,221 @@
|
||||
using DocumentFormat.OpenXml.Spreadsheet;
|
||||
using IRaCIS.Application.Contracts;
|
||||
using Medallion.Threading;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace IRaCIS.Core.Application.Service.Common;
|
||||
|
||||
[ApiExplorerSettings(GroupName = "Common")]
|
||||
public class DeployConfigService(IMapper _mapper, IConfiguration _configuration, IDistributedLockProvider _distributedLockProvider, IUserInfo _userInfo, IWebHostEnvironment _hostEnvironment, IStringLocalizer _localizer, IFusionCache _fusionCache) : BaseService
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// 获取系统基础配置信息
|
||||
/// </summary>
|
||||
/// <param name="options"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<ServiceVerifyConfigOption> GetSystemBasicConfigInfo([FromServices] IOptionsMonitor<ServiceVerifyConfigOption> options)
|
||||
{
|
||||
//var config = _configuration.GetSection("BasicSystemConfig").Get<ServiceVerifyConfigOption>();
|
||||
//return config;
|
||||
|
||||
|
||||
var path = Path.Combine(_hostEnvironment.ContentRootPath, $"appsettings.{_hostEnvironment.EnvironmentName}.json");
|
||||
|
||||
var json = File.ReadAllText(path);
|
||||
|
||||
var obj = JObject.Parse(json);
|
||||
|
||||
return obj["BasicSystemConfig"]!.ToObject<ServiceVerifyConfigOption>()!;
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新系统基础配置
|
||||
/// </summary>
|
||||
/// <param name="basicSystemConfigOption"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<IResponseOutput> UpdateSystemBasicConfig(ServiceVerifyConfigOption basicSystemConfigOption)
|
||||
{
|
||||
//var path = $"appsettings.{_hostEnvironment.EnvironmentName}.json";
|
||||
var path = Path.Combine(_hostEnvironment.ContentRootPath, $"appsettings.{_hostEnvironment.EnvironmentName}.json");
|
||||
|
||||
|
||||
var @lock = _distributedLockProvider.CreateLock("WriteConfigFile");
|
||||
|
||||
|
||||
using (await @lock.AcquireAsync())
|
||||
{
|
||||
|
||||
|
||||
string text = System.IO.File.ReadAllText(path);
|
||||
|
||||
// 修改
|
||||
JObject obj = JObject.Parse(text);
|
||||
// QCRiskControl 相关配置
|
||||
obj["BasicSystemConfig"][nameof(ServiceVerifyConfigOption.QCRiskControl)] = basicSystemConfigOption.QCRiskControl;
|
||||
obj["BasicSystemConfig"][nameof(ServiceVerifyConfigOption.OpenUserComplexPassword)] = basicSystemConfigOption.OpenUserComplexPassword;
|
||||
obj["BasicSystemConfig"][nameof(ServiceVerifyConfigOption.OpenSignDocumentBeforeWork)] = basicSystemConfigOption.OpenSignDocumentBeforeWork;
|
||||
obj["BasicSystemConfig"][nameof(ServiceVerifyConfigOption.OpenTrialRelationDelete)] = basicSystemConfigOption.OpenTrialRelationDelete;
|
||||
obj["BasicSystemConfig"][nameof(ServiceVerifyConfigOption.OpenLoginLimit)] = basicSystemConfigOption.OpenLoginLimit;
|
||||
obj["BasicSystemConfig"][nameof(ServiceVerifyConfigOption.LoginMaxFailCount)] = basicSystemConfigOption.LoginMaxFailCount;
|
||||
obj["BasicSystemConfig"][nameof(ServiceVerifyConfigOption.LoginFailLockMinutes)] = basicSystemConfigOption.LoginFailLockMinutes;
|
||||
obj["BasicSystemConfig"][nameof(ServiceVerifyConfigOption.AutoLoginOutMinutes)] = basicSystemConfigOption.AutoLoginOutMinutes;
|
||||
obj["BasicSystemConfig"][nameof(ServiceVerifyConfigOption.OpenLoginMFA)] = basicSystemConfigOption.OpenLoginMFA;
|
||||
obj["BasicSystemConfig"][nameof(ServiceVerifyConfigOption.ContinuousReadingTimeMin)] = basicSystemConfigOption.ContinuousReadingTimeMin;
|
||||
obj["BasicSystemConfig"][nameof(ServiceVerifyConfigOption.ReadingRestTimeMin)] = basicSystemConfigOption.ReadingRestTimeMin;
|
||||
obj["BasicSystemConfig"][nameof(ServiceVerifyConfigOption.IsNeedChangePassWord)] = basicSystemConfigOption.IsNeedChangePassWord;
|
||||
obj["BasicSystemConfig"][nameof(ServiceVerifyConfigOption.ChangePassWordDays)] = basicSystemConfigOption.ChangePassWordDays;
|
||||
obj["BasicSystemConfig"][nameof(ServiceVerifyConfigOption.TemplateType)] = ((int)basicSystemConfigOption.TemplateType); // 枚举需要转换为字符串
|
||||
obj["BasicSystemConfig"][nameof(ServiceVerifyConfigOption.ThirdPdfUrl)] = basicSystemConfigOption.ThirdPdfUrl;
|
||||
obj["BasicSystemConfig"][nameof(ServiceVerifyConfigOption.UserMFAVerifyMinutes)] = basicSystemConfigOption.UserMFAVerifyMinutes;
|
||||
|
||||
|
||||
// 重新写入appsettings.json
|
||||
string result = obj.ToString();
|
||||
System.IO.File.WriteAllText(path, result);
|
||||
|
||||
}
|
||||
|
||||
|
||||
return ResponseOutput.Ok();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取系统邮件配置信息
|
||||
/// </summary>
|
||||
/// <param name="options"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<SystemEmailSendConfig> GetEmailConfigInfo([FromServices] IOptionsMonitor<SystemEmailSendConfig> options)
|
||||
{
|
||||
//两种方式都有问题
|
||||
//var config = _configuration.GetSection("BasicSystemConfig").Get<SystemEmailSendConfig>();
|
||||
//return config;
|
||||
//return options.CurrentValue;
|
||||
|
||||
var path = Path.Combine(_hostEnvironment.ContentRootPath, $"appsettings.{_hostEnvironment.EnvironmentName}.json");
|
||||
|
||||
var json = File.ReadAllText(path);
|
||||
|
||||
var obj = JObject.Parse(json);
|
||||
|
||||
return obj["SystemEmailSendConfig"]!.ToObject<SystemEmailSendConfig>()!;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 更新系统邮件配置
|
||||
/// </summary>
|
||||
/// <param name="emailConfig"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<IResponseOutput> UpdateSystemEmailConfig(SystemEmailSendConfig emailConfig)
|
||||
{
|
||||
var path = Path.Combine(_hostEnvironment.ContentRootPath, $"appsettings.{_hostEnvironment.EnvironmentName}.json");
|
||||
//var path = $"appsettings.{_hostEnvironment.EnvironmentName}.json";
|
||||
|
||||
var @lock = _distributedLockProvider.CreateLock("WriteConfigFile");
|
||||
|
||||
|
||||
using (await @lock.AcquireAsync())
|
||||
{
|
||||
|
||||
|
||||
string text = System.IO.File.ReadAllText(path);
|
||||
|
||||
// 修改
|
||||
JObject obj = JObject.Parse(text);
|
||||
|
||||
// SystemEmailSendConfig 相关配置
|
||||
obj["SystemEmailSendConfig"][nameof(SystemEmailSendConfig.Port)] = emailConfig.Port;
|
||||
obj["SystemEmailSendConfig"][nameof(SystemEmailSendConfig.Host)] = emailConfig.Host;
|
||||
obj["SystemEmailSendConfig"][nameof(SystemEmailSendConfig.Imap)] = emailConfig.Imap;
|
||||
obj["SystemEmailSendConfig"][nameof(SystemEmailSendConfig.ImapPort)] = emailConfig.ImapPort;
|
||||
obj["SystemEmailSendConfig"][nameof(SystemEmailSendConfig.FromEmail)] = emailConfig.FromEmail;
|
||||
obj["SystemEmailSendConfig"][nameof(SystemEmailSendConfig.FromName)] = emailConfig.FromName;
|
||||
obj["SystemEmailSendConfig"][nameof(SystemEmailSendConfig.AuthorizationCode)] = emailConfig.AuthorizationCode;
|
||||
obj["SystemEmailSendConfig"][nameof(SystemEmailSendConfig.SiteUrl)] = emailConfig.SiteUrl;
|
||||
obj["SystemEmailSendConfig"][nameof(SystemEmailSendConfig.PlatformName)] = emailConfig.PlatformName;
|
||||
obj["SystemEmailSendConfig"][nameof(SystemEmailSendConfig.PlatformNameCN)] = emailConfig.PlatformNameCN;
|
||||
obj["SystemEmailSendConfig"][nameof(SystemEmailSendConfig.SystemShortName)] = emailConfig.SystemShortName;
|
||||
obj["SystemEmailSendConfig"][nameof(SystemEmailSendConfig.OrganizationName)] = emailConfig.OrganizationName;
|
||||
obj["SystemEmailSendConfig"][nameof(SystemEmailSendConfig.OrganizationNameCN)] = emailConfig.OrganizationNameCN;
|
||||
obj["SystemEmailSendConfig"][nameof(SystemEmailSendConfig.CompanyName)] = emailConfig.CompanyName;
|
||||
obj["SystemEmailSendConfig"][nameof(SystemEmailSendConfig.CompanyNameCN)] = emailConfig.CompanyNameCN;
|
||||
obj["SystemEmailSendConfig"][nameof(SystemEmailSendConfig.CompanyShortName)] = emailConfig.CompanyShortName;
|
||||
obj["SystemEmailSendConfig"][nameof(SystemEmailSendConfig.CompanyShortNameCN)] = emailConfig.CompanyShortNameCN;
|
||||
obj["SystemEmailSendConfig"][nameof(SystemEmailSendConfig.IsEnv_US)] = emailConfig.IsEnv_US;
|
||||
obj["SystemEmailSendConfig"][nameof(SystemEmailSendConfig.EmailRegexStr)] = emailConfig.EmailRegexStr;
|
||||
|
||||
|
||||
|
||||
// 重新写入appsettings.json
|
||||
string result = obj.ToString();
|
||||
System.IO.File.WriteAllText(path, result);
|
||||
|
||||
|
||||
}
|
||||
|
||||
return ResponseOutput.Ok();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取前端配置
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[AllowAnonymous]
|
||||
public async Task<string> GetWebConfigInfo()
|
||||
{
|
||||
|
||||
|
||||
var path = Path.Combine(_hostEnvironment.ContentRootPath, $"appsettings.{_hostEnvironment.EnvironmentName}.json");
|
||||
|
||||
var json = File.ReadAllText(path);
|
||||
|
||||
var obj = JObject.Parse(json);
|
||||
|
||||
return obj["FrontWebConfig"]!.ToString();
|
||||
}
|
||||
|
||||
|
||||
public async Task<IResponseOutput> UpdateWebConfigInfo(string configStr)
|
||||
{
|
||||
var path = Path.Combine(_hostEnvironment.ContentRootPath, $"appsettings.{_hostEnvironment.EnvironmentName}.json");
|
||||
//var path = $"appsettings.{_hostEnvironment.EnvironmentName}.json";
|
||||
|
||||
var @lock = _distributedLockProvider.CreateLock("WriteConfigFile");
|
||||
|
||||
using (await @lock.AcquireAsync())
|
||||
{
|
||||
string text = System.IO.File.ReadAllText(path);
|
||||
// 修改
|
||||
JObject obj = JObject.Parse(text);
|
||||
|
||||
// SystemEmailSendConfig 相关配置
|
||||
obj["FrontWebConfig"] = configStr;
|
||||
|
||||
// 重新写入appsettings.json
|
||||
string result = obj.ToString();
|
||||
|
||||
System.IO.File.WriteAllText(path, result);
|
||||
|
||||
}
|
||||
|
||||
return ResponseOutput.Ok();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -452,14 +452,14 @@ namespace IRaCIS.Core.Application.Service
|
||||
|
||||
if (inDto.TrialReadingCriterionId == null && inDto.SystemReadingCriterionId == null)
|
||||
{
|
||||
return result;
|
||||
return await ChangeTrialObjectNameList(result,inDto.TrialId);
|
||||
}
|
||||
else if (inDto.TrialReadingCriterionId != null)
|
||||
{
|
||||
var trialCriterionType = await _readingQuestionCriterionTrial.Where(x => x.Id == inDto.TrialReadingCriterionId).Select(x => x.CriterionType).FirstOrDefaultAsync();
|
||||
if (trialCriterionType == CriterionType.SelfDefine)
|
||||
{
|
||||
return result;
|
||||
return await ChangeTrialObjectNameList(result, inDto.TrialId);
|
||||
}
|
||||
|
||||
|
||||
@@ -505,7 +505,7 @@ namespace IRaCIS.Core.Application.Service
|
||||
result[item.Key] = item.Value;
|
||||
}
|
||||
|
||||
return result;
|
||||
return await ChangeTrialObjectNameList(result, inDto.TrialId);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -548,12 +548,76 @@ namespace IRaCIS.Core.Application.Service
|
||||
result[item.Key] = item.Value;
|
||||
}
|
||||
|
||||
return result;
|
||||
return await ChangeTrialObjectNameList(result, inDto.TrialId);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 替换字典中的项目名称为试验对象名称 --New
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
/// <param name="trialId"></param>
|
||||
/// <returns></returns>
|
||||
private async Task<Dictionary<string, List<BasicDicSelect>>> ChangeTrialObjectNameList(Dictionary<string, List<BasicDicSelect>> data,Guid? trialId)
|
||||
{
|
||||
if (!trialId.HasValue)
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
// 查询映射集合
|
||||
var trialObjectNameList = await _trialRepository
|
||||
.Where(x => x.Id == trialId)
|
||||
.Select(x => x.TrialObjectNameList)
|
||||
.FirstOrDefaultAsync();
|
||||
|
||||
// 无映射数据直接返回
|
||||
if (trialObjectNameList == null || !trialObjectNameList.Any())
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
// 构建映射字典,过滤空名称,避免无效替换
|
||||
var replaceDict = trialObjectNameList
|
||||
.Where(m => !string.IsNullOrEmpty(m.Name))
|
||||
.ToDictionary(m => m.Name, m => m.TrialName);
|
||||
|
||||
// 遍历替换
|
||||
foreach (var (_, selectList) in data)
|
||||
{
|
||||
foreach (var selectItem in selectList)
|
||||
{
|
||||
// 替换Value,判null保护
|
||||
if (selectItem.Value != null)
|
||||
{
|
||||
string tempVal = selectItem.Value;
|
||||
foreach (var (oldStr, newStr) in replaceDict)
|
||||
{
|
||||
tempVal = tempVal.Replace(oldStr, newStr);
|
||||
}
|
||||
selectItem.Value = tempVal;
|
||||
}
|
||||
|
||||
// 替换中文名称ValueCN
|
||||
if (selectItem.ValueCN != null)
|
||||
{
|
||||
string tempCn = selectItem.ValueCN;
|
||||
foreach (var (oldStr, newStr) in replaceDict)
|
||||
{
|
||||
tempCn = tempCn.Replace(oldStr, newStr);
|
||||
}
|
||||
selectItem.ValueCN = tempCn;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
#region 稽查相关
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -4,19 +4,13 @@
|
||||
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
using DocumentFormat.OpenXml.Spreadsheet;
|
||||
using IRaCIS.Core.Application.Helper;
|
||||
using IRaCIS.Core.Domain.Share;
|
||||
using MailKit;
|
||||
using MailKit.Net.Imap;
|
||||
using MailKit.Search;
|
||||
using MailKit.Security;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
|
||||
using Newtonsoft.Json;
|
||||
using NPOI.SS.Formula.Functions;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace IRaCIS.Core.Application.Contracts
|
||||
|
||||
@@ -1,27 +1,16 @@
|
||||
using DocumentFormat.OpenXml.Spreadsheet;
|
||||
using ClosedXML.Excel;
|
||||
using DocumentFormat.OpenXml.Spreadsheet;
|
||||
using IRaCIS.Application.Contracts;
|
||||
using IRaCIS.Application.Interfaces;
|
||||
using IRaCIS.Core.API._ServiceExtensions.NewtonsoftJson;
|
||||
using IRaCIS.Core.Application.Contracts;
|
||||
using IRaCIS.Core.Application.Contracts.DTO;
|
||||
using IRaCIS.Core.Application.Service.Reading.Dto;
|
||||
using IRaCIS.Core.Application.ViewModel;
|
||||
using IRaCIS.Core.Domain.Models;
|
||||
using IRaCIS.Core.Domain.Share;
|
||||
using IRaCIS.Core.Infra.EFCore.Common;
|
||||
using IRaCIS.Core.Infra.EFCore.Migrations;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Internal;
|
||||
using NPOI.HPSF;
|
||||
using NPOI.POIFS.Properties;
|
||||
using NPOI.SS.Formula.Functions;
|
||||
using NPOI.XSSF.UserModel;
|
||||
using System.ComponentModel.Design;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Newtonsoft.Json;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using static IRaCIS.Core.Application.Service.ExcelExportHelper;
|
||||
@@ -52,6 +41,191 @@ namespace IRaCIS.Core.Application.Service.Common
|
||||
IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer, IWebHostEnvironment _hostEnvironment) : BaseService
|
||||
{
|
||||
|
||||
|
||||
#region 中心调研导出
|
||||
|
||||
[HttpPost]
|
||||
public async Task<IActionResult> GetTrialSiteSurveyList_Export(TrialSiteSurveyQueryDTO inQuery,
|
||||
[FromServices] IRepository<TrialSiteSurvey> _trialSiteSurveyRepository,
|
||||
[FromServices] IDictionaryService _dictionaryService)
|
||||
{
|
||||
var trialSiteSurveyQueryable = _trialSiteSurveyRepository.Where(t => t.TrialId == inQuery.TrialId).IgnoreQueryFilters()
|
||||
.WhereIf(inQuery.TrialSiteId != null, t => t.TrialSiteId == inQuery.TrialSiteId)
|
||||
.WhereIf(inQuery.IsDeleted != null, t => t.IsDeleted == inQuery.IsDeleted)
|
||||
.WhereIf(!string.IsNullOrWhiteSpace(inQuery.UserKeyInfo), t => t.UserName.Contains(inQuery.UserKeyInfo) || t.Phone.Contains(inQuery.UserKeyInfo) || t.Email.Contains(inQuery.UserKeyInfo))
|
||||
.WhereIf(inQuery.State != null, t => t.State == inQuery.State)
|
||||
.WhereIf(inQuery.UpdateTimeBegin != null, t => t.UpdateTime >= inQuery.UpdateTimeBegin)
|
||||
.WhereIf(inQuery.UpdateTimeEnd != null, t => t.UpdateTime <= inQuery.UpdateTimeEnd)
|
||||
|
||||
.ProjectTo<TrialSiteSurveyView>(_mapper.ConfigurationProvider, new { isEn_Us = _userInfo.IsEn_Us })
|
||||
.WhereIf(!string.IsNullOrWhiteSpace(inQuery.PreliminaryUserName), t => t.PreliminaryUser.RealName.Contains(inQuery.PreliminaryUserName))
|
||||
.WhereIf(!string.IsNullOrWhiteSpace(inQuery.ReviewerUserName), t => t.ReviewerUser.RealName.Contains(inQuery.ReviewerUserName))
|
||||
;
|
||||
|
||||
//var defalutSortArray = new string[] { /*nameof(TrialSiteSurveyView.LanguageType) + " desc", nameof(TrialSiteSurveyView.ShowOrder)*/ };
|
||||
|
||||
|
||||
var list = await trialSiteSurveyQueryable.SortToListAsync(inQuery /*,defalutSortArray*/);
|
||||
|
||||
var exportInfo = new ExcelExportInfo();
|
||||
|
||||
exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(list, _userInfo.TimeZoneId);
|
||||
exportInfo.CurrentTime = ExportExcelConverterDate.DateTimeInternationalToString(DateTime.Now, _userInfo.TimeZoneId);
|
||||
|
||||
return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialSiteSurvey_BasicInfo_Export, exportInfo, exportInfo.TrialCode, _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(TrialSiteSurveyView));
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取中心设备信息
|
||||
/// </summary>
|
||||
/// <param name="inQuery"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<IActionResult> GetSiteSurveyEquipmentList_Export(SiteSurveyEquipmentQuery inQuery,
|
||||
[FromServices] IRepository<TrialSiteEquipmentSurvey> _trialSiteEquipmentSurveyRepository,
|
||||
[FromServices] IRepository<TrialSiteSurvey> _trialSiteSurveyRepository,
|
||||
[FromServices] IDictionaryService _dictionaryService)
|
||||
{
|
||||
|
||||
|
||||
//找到该中心最新的调研记录
|
||||
var groupSelectIdQuery =
|
||||
_trialSiteSurveyRepository.Where(t => t.TrialId == inQuery.TrialId)
|
||||
.WhereIf(inQuery.TrialSiteId != null, t => t.TrialSiteId == inQuery.TrialSiteId)
|
||||
.GroupBy(t => t.TrialSiteId)
|
||||
.Select(g => g.OrderByDescending(u => u.CreateTime).Select(t => t.Id).First());
|
||||
|
||||
|
||||
var query = _trialSiteEquipmentSurveyRepository.Where(t => t.TrialSiteSurvey.TrialId == inQuery.TrialId)
|
||||
.IgnoreQueryFilters().Where(t => groupSelectIdQuery.Contains(t.TrialSiteSurveyId))
|
||||
.WhereIf(inQuery.IsDeleted != null, t => t.TrialSiteSurvey.IsDeleted == inQuery.IsDeleted)
|
||||
.WhereIf(inQuery.State != null, t => t.TrialSiteSurvey.State == inQuery.State)
|
||||
.WhereIf(inQuery.TrialSiteId != null, t => t.TrialSiteSurvey.TrialSiteId == inQuery.TrialSiteId)
|
||||
.WhereIf(inQuery.TrialSiteCode.IsNotNullOrEmpty(), t => t.TrialSiteSurvey.TrialSite.TrialSiteCode.Contains(inQuery.TrialSiteCode))
|
||||
.WhereIf(inQuery.TrialSiteName.IsNotNullOrEmpty(), t => t.TrialSiteSurvey.TrialSite.TrialSiteAliasName.Contains(inQuery.TrialSiteName) ||
|
||||
t.TrialSiteSurvey.TrialSite.TrialSiteName.Contains(inQuery.TrialSiteName))
|
||||
.ProjectTo<SiteSurveyEquipmentDto>(_mapper.ConfigurationProvider);
|
||||
|
||||
var siteSurveryConfig = _trialRepository.Where(t => t.Id == inQuery.TrialId).Select(t => t.TrialExtraConfigJsonStr).FirstOrDefault() ?? string.Empty;
|
||||
|
||||
var config = JsonConvert.DeserializeObject<TrialExtraConfig>(siteSurveryConfig) ?? new TrialExtraConfig();
|
||||
|
||||
|
||||
var fields = new List<(string FieldName, int excelIndex)>()
|
||||
{
|
||||
|
||||
("Parameters", 9),
|
||||
("ManufacturerType", 10),
|
||||
("ScannerType", 11),
|
||||
("MagneticFieldStrengthType", 12),
|
||||
("BodyCoilChannelCount", 13),
|
||||
("HasDedicatedPdfFatQuantificationSequence", 14),
|
||||
("PdfFatQuantificationSequenceType", 15),
|
||||
//("OtherSequenceSpecification", 15),
|
||||
("HasT2R2Correction", 16),
|
||||
("CanFullyExportPdfParameterMapsAndRawDicom", 17),
|
||||
("Note", 18),
|
||||
};
|
||||
|
||||
|
||||
var viewNameList = config.EquipmentControlFieldList.Where(t => t.IsView == true).Select(t => t.FiledName).ToList();
|
||||
|
||||
var columnsToDelete = fields.Where(f => !viewNameList.Any(t => f.FieldName == t)).Select(f => f.excelIndex).Distinct().OrderByDescending(i => i).ToList();
|
||||
|
||||
|
||||
//var defalutSortArray = new string[] { /*nameof(TrialSiteSurveyView.LanguageType) + " desc", nameof(TrialSiteSurveyView.ShowOrder)*/ };
|
||||
|
||||
|
||||
var list = await query.SortToListAsync(inQuery /*,defalutSortArray*/);
|
||||
|
||||
var exportInfo = new ExcelExportInfo();
|
||||
|
||||
exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(list, _userInfo.TimeZoneId);
|
||||
exportInfo.CurrentTime = ExportExcelConverterDate.DateTimeInternationalToString(DateTime.Now, _userInfo.TimeZoneId);
|
||||
|
||||
return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialSiteSurvey_Equipment_Export, exportInfo, exportInfo.TrialCode, _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(SiteSurveyEquipmentDto), removeExcelIndexList: columnsToDelete);
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 调研表基本信息
|
||||
/// </summary>
|
||||
/// <param name="inQuery"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<IActionResult> GetSiteSurveyInfoList_Export(SiteSurveyInfoQuery inQuery,
|
||||
[FromServices] IRepository<TrialSiteSurvey> _trialSiteSurveyRepository,
|
||||
[FromServices] IDictionaryService _dictionaryService)
|
||||
{
|
||||
|
||||
//找到该中心最新的调研记录
|
||||
var groupSelectIdQuery =
|
||||
_trialSiteSurveyRepository.Where(t => t.TrialId == inQuery.TrialId)
|
||||
.WhereIf(inQuery.TrialSiteId != null, t => t.TrialSiteId == inQuery.TrialSiteId)
|
||||
.GroupBy(t => t.TrialSiteId)
|
||||
.Select(g => g.OrderByDescending(u => u.CreateTime).Select(t => t.Id).First());
|
||||
|
||||
var query = _trialSiteSurveyRepository.Where(t => t.TrialId == inQuery.TrialId).IgnoreQueryFilters()
|
||||
.Where(t => groupSelectIdQuery.Contains(t.Id))
|
||||
.WhereIf(inQuery.IsDeleted != null, t => t.IsDeleted == inQuery.IsDeleted)
|
||||
.WhereIf(inQuery.State != null, t => t.State == inQuery.State)
|
||||
.WhereIf(inQuery.TrialSiteId != null, t => t.TrialSiteId == inQuery.TrialSiteId)
|
||||
.WhereIf(inQuery.TrialSiteCode.IsNotNullOrEmpty(), t => t.TrialSite.TrialSiteCode.Contains(inQuery.TrialSiteCode))
|
||||
.WhereIf(inQuery.TrialSiteName.IsNotNullOrEmpty(), t => t.TrialSite.TrialSiteAliasName.Contains(inQuery.TrialSiteName) ||
|
||||
t.TrialSite.TrialSiteName.Contains(inQuery.TrialSiteName))
|
||||
|
||||
.ProjectTo<TrialSiteSurveyView>(_mapper.ConfigurationProvider);
|
||||
|
||||
|
||||
var siteSurveryConfig = _trialRepository.Where(t => t.Id == inQuery.TrialId).Select(t => t.TrialExtraConfigJsonStr).FirstOrDefault() ?? string.Empty;
|
||||
|
||||
var config = JsonConvert.DeserializeObject<TrialExtraConfig>(siteSurveryConfig) ?? new TrialExtraConfig();
|
||||
|
||||
|
||||
var fields = new List<(string FieldName, int excelIndex)>()
|
||||
{
|
||||
|
||||
("AverageEngravingCycle", 8),
|
||||
("IsRoutineMRIPDEE", 9),
|
||||
("MRIPDFFScanTime", 10),
|
||||
("MRIPDFFLeadTime", 11),
|
||||
("MRIPDFFOther", 12),
|
||||
("IsAuthorizeRadiologistsParticipate", 13),
|
||||
("AssignFixedTechnologists", 14),
|
||||
("IsConfirmImagingTechnologist", 15),
|
||||
("NotConfirmReson", 16),
|
||||
("EfficacyEvaluatorType", 17),
|
||||
|
||||
("IsFollowStudyParameters", 18),
|
||||
("NotFollowReson", 19),
|
||||
("ISStrictManualBurnFlag", 20),
|
||||
("NotStrictManualBurnFlagReason",21)
|
||||
};
|
||||
|
||||
|
||||
//var viewNameList = config.NotShowFieldList;
|
||||
|
||||
var columnsToDelete = fields.Where(f => config.NotShowFieldList.Any(t => f.FieldName == t)).Select(f => f.excelIndex).Distinct().OrderByDescending(i => i).ToList();
|
||||
|
||||
|
||||
//var defalutSortArray = new string[] { /*nameof(TrialSiteSurveyView.LanguageType) + " desc", nameof(TrialSiteSurveyView.ShowOrder)*/ };
|
||||
|
||||
|
||||
var list = await query.SortToListAsync(inQuery /*,defalutSortArray*/);
|
||||
|
||||
var exportInfo = new ExcelExportInfo();
|
||||
|
||||
exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(list, _userInfo.TimeZoneId);
|
||||
exportInfo.CurrentTime = ExportExcelConverterDate.DateTimeInternationalToString(DateTime.Now, _userInfo.TimeZoneId);
|
||||
|
||||
return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialSiteSurvey_Info_Export, exportInfo, exportInfo.TrialCode, _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(TrialSiteSurveyView), removeExcelIndexList: columnsToDelete);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 质控问题答案导出
|
||||
/// </summary>
|
||||
@@ -153,9 +327,9 @@ namespace IRaCIS.Core.Application.Service.Common
|
||||
|
||||
var dynamicColumnConfig = new DynamicColumnConfig()
|
||||
{
|
||||
AutoColumnTitleRowIndex = 2,
|
||||
AutoColumnStartIndex = 7,
|
||||
TempalteLastColumnIndex = 6,
|
||||
AutoColumnTitleRowIndex = 3, //2
|
||||
AutoColumnStartIndex = 8, //7
|
||||
TempalteLastColumnIndex = 7, //6
|
||||
DynamicItemDicName = "TranslateDicName",
|
||||
DynamicItemValueName = "Answer",
|
||||
DynamicItemTitleName = "QuestionName",
|
||||
@@ -167,7 +341,7 @@ namespace IRaCIS.Core.Application.Service.Common
|
||||
};
|
||||
|
||||
|
||||
var (memoryStream, fileName) = await ExcelExportHelper.DataExport_NpoiTestAsync(StaticData.Export.TrialQCResult_Export, exportInfo, _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(QCQuestionResult_Export), dynamicColumnConfig: dynamicColumnConfig);
|
||||
var (memoryStream, fileName) = await ExcelExportHelper.DataExport_ClosedXMLAsync(StaticData.Export.TrialQCResult_Export, exportInfo, _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(QCQuestionResult_Export), dynamicColumnConfig: dynamicColumnConfig);
|
||||
|
||||
return new FileStreamResult(memoryStream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
|
||||
{
|
||||
@@ -1209,7 +1383,7 @@ namespace IRaCIS.Core.Application.Service.Common
|
||||
t.VisitTaskList.Where(t => t.TaskState == TaskState.Effect && t.TrialReadingCriterionId == dto.TrialReadingCriterionId && t.TaskAllocationState == TaskAllocationState.Allocated && t.IsAnalysisCreate == false && t.ReadingCategory == ReadingCategory.Visit && t.ReadingTaskState == ReadingTaskState.HaveSigned).Count() == (int)trialReadingCriterion.ReadingType ?
|
||||
ReadingStatusEnum.ReadCompleted : t.VisitTaskList.Where(t => t.TaskState == TaskState.Effect && t.TrialReadingCriterionId == dto.TrialReadingCriterionId && t.IsAnalysisCreate == false && t.ReadingCategory == ReadingCategory.Visit && t.TaskAllocationState == TaskAllocationState.Allocated).Count() == (int)trialReadingCriterion.ReadingType ? ReadingStatusEnum.ImageReading :
|
||||
t.ReadingStatus
|
||||
}).ToList(),
|
||||
}).OrderBy(t => t.VisitTaskNum).ToList(),
|
||||
|
||||
ModuleList = subject.ReadModuleList.Where(t => t.TrialReadingCriterionId == dto.TrialReadingCriterionId).Select(t => new SubjectProgressDto.MouduleProgress()
|
||||
{
|
||||
@@ -1239,55 +1413,60 @@ namespace IRaCIS.Core.Application.Service.Common
|
||||
exportInfo.CurrentTime = ExportExcelConverterDate.DateTimeInternationalToString(DateTime.Now, _userInfo.TimeZoneId);
|
||||
|
||||
|
||||
var (memoryStream, fileName) = await ExcelExportHelper.DataExport_NpoiTestAsync(StaticData.Export.TrialSubjectProgressList_Export, exportInfo, /*"", */_commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(SubjectProgressDto));
|
||||
var (memoryStream, fileName) = await ExcelExportHelper.DataExport_ClosedXMLAsync(StaticData.Export.TrialSubjectProgressList_Export, exportInfo, /*"", */_commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(SubjectProgressDto));
|
||||
|
||||
|
||||
// 使用NPOI 进行二次处理
|
||||
|
||||
var wb = new XSSFWorkbook(memoryStream);
|
||||
|
||||
var sheet = wb.GetSheetAt(0);
|
||||
// 使用 ClosedXML 进行二次处理
|
||||
using var workbook = new XLWorkbook(memoryStream);
|
||||
var worksheet = workbook.Worksheet(1); // 获取第一个工作表,索引从1开始
|
||||
|
||||
foreach (var subject in list)
|
||||
{
|
||||
var index = list.IndexOf(subject);
|
||||
var row = sheet.GetRow(index + 4);
|
||||
|
||||
// ClosedXML 行索引从1开始,原来 NPOI 从0开始,所以 +1
|
||||
var row = worksheet.Row(index + 4 + 1); // NPOI: index + 4, ClosedXML: +1 = index + 5
|
||||
|
||||
|
||||
foreach (var item in subject.TotalList)
|
||||
{
|
||||
//从第五列开始动态写
|
||||
var visitIndex = subject.TotalList.IndexOf(item) + 4;
|
||||
// 从第五列开始动态写(ClosedXML 列索引从1开始)
|
||||
var visitIndex = subject.TotalList.IndexOf(item) + 4 + 1; // NPOI: +4, ClosedXML: +1 = +5
|
||||
|
||||
var cell = row.CreateCell(visitIndex);
|
||||
var cell = row.Cell(visitIndex);
|
||||
|
||||
if (item.IsLostVisit == true)
|
||||
{
|
||||
cell.CellStyle = sheet.GetRow(1).GetCell(7).CellStyle;
|
||||
//cell.CellStyle = sheet.GetRow(1).GetCell(7).CellStyle;
|
||||
|
||||
// 复制样式 - ClosedXML 需要先获取源样式,然后应用到目标单元格
|
||||
var sourceCell = worksheet.Row(2).Cell(8); // 原 NPOI: GetRow(1).GetCell(7) -> +1 转换
|
||||
|
||||
cell.Style = sourceCell.Style;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (item.ReadingStatus)
|
||||
{
|
||||
case ReadingStatusEnum.ImageNotSubmit:
|
||||
|
||||
cell.CellStyle = sheet.GetRow(1).GetCell(1).CellStyle;
|
||||
cell.Style = worksheet.Row(2).Cell(2).Style; // NPOI: (1,1) -> ClosedXML: (2,2)
|
||||
|
||||
break;
|
||||
case ReadingStatusEnum.ImageQuality:
|
||||
cell.CellStyle = sheet.GetRow(1).GetCell(2).CellStyle;
|
||||
cell.Style = worksheet.Row(2).Cell(3).Style; // (1,2) -> (2,3)
|
||||
break;
|
||||
case ReadingStatusEnum.ConsistencyCheck:
|
||||
cell.CellStyle = sheet.GetRow(1).GetCell(3).CellStyle;
|
||||
cell.Style = worksheet.Row(2).Cell(4).Style; // (1,3) -> (2,4)
|
||||
break;
|
||||
case ReadingStatusEnum.TaskAllocate:
|
||||
cell.CellStyle = sheet.GetRow(1).GetCell(4).CellStyle;
|
||||
cell.Style = worksheet.Row(2).Cell(5).Style;// (1,4) -> (2,5)
|
||||
break;
|
||||
case ReadingStatusEnum.ImageReading:
|
||||
cell.CellStyle = sheet.GetRow(1).GetCell(5).CellStyle;
|
||||
cell.Style = worksheet.Row(2).Cell(6).Style;// (1,5) -> (2,6)
|
||||
break;
|
||||
case ReadingStatusEnum.ReadCompleted:
|
||||
cell.CellStyle = sheet.GetRow(1).GetCell(6).CellStyle;
|
||||
cell.Style = worksheet.Row(2).Cell(7).Style; // (1,6) -> (2,7)
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -1297,12 +1476,13 @@ namespace IRaCIS.Core.Application.Service.Common
|
||||
|
||||
|
||||
|
||||
cell.SetCellValue(item.TaskName);
|
||||
cell.SetValue(item.TaskName);
|
||||
}
|
||||
}
|
||||
|
||||
// 保存到 MemoryStream
|
||||
var memoryStream2 = new MemoryStream();
|
||||
wb.Write(memoryStream2, true);
|
||||
workbook.SaveAs(memoryStream2);
|
||||
memoryStream2.Seek(0, SeekOrigin.Begin);
|
||||
|
||||
return new FileStreamResult(memoryStream2, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
|
||||
@@ -2709,9 +2889,10 @@ namespace IRaCIS.Core.Application.Service.Common
|
||||
var dynamicColumnConfig = new DynamicColumnConfig()
|
||||
{
|
||||
//可读的列表名行索引,不是{{}} 模板行索引
|
||||
AutoColumnTitleRowIndex = 2,
|
||||
AutoColumnStartIndex = 5,
|
||||
TempalteLastColumnIndex = 4,
|
||||
AutoColumnTitleRowIndex = 3, //2
|
||||
AutoColumnStartIndex = 6, //5
|
||||
TempalteLastColumnIndex = 5, //4
|
||||
|
||||
DynamicItemDicName = "TranslateDicName",
|
||||
DynamicItemValueName = "QuestionValue",
|
||||
DynamicItemTitleName = "QuestionName",
|
||||
@@ -2722,7 +2903,7 @@ namespace IRaCIS.Core.Application.Service.Common
|
||||
};
|
||||
|
||||
|
||||
var (memoryStream, fileName) = await ExcelExportHelper.DataExport_NpoiTestAsync(export_Template, exportInfo, _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(AnalysisDynamicCommonExport), criterion.CriterionType, dynamicColumnConfig);
|
||||
var (memoryStream, fileName) = await ExcelExportHelper.DataExport_ClosedXMLAsync(export_Template, exportInfo, _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(AnalysisDynamicCommonExport), criterion.CriterionType, dynamicColumnConfig);
|
||||
|
||||
return new FileStreamResult(memoryStream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
|
||||
{
|
||||
@@ -2768,11 +2949,11 @@ namespace IRaCIS.Core.Application.Service.Common
|
||||
if (criterion.CriterionType == CriterionType.OCT)
|
||||
{
|
||||
list.Add(new ExportDocumentDes() { Code = StaticData.Export.OCT_ReadingLession_Export, ExportCatogory = ExportResult.OCT_ReadingLession_Export });
|
||||
list.Add(new ExportDocumentDes() { Code = StaticData.Export.OCT_CDISC_Export, ExportCatogory = ExportResult.OCT_CDISC_Export });
|
||||
//list.Add(new ExportDocumentDes() { Code = StaticData.Export.OCT_CDISC_Export, ExportCatogory = ExportResult.OCT_CDISC_Export });
|
||||
}
|
||||
if (criterion.CriterionType == CriterionType.IVUS)
|
||||
{
|
||||
list.Add(new ExportDocumentDes() { Code = StaticData.Export.IVUS_CDISC_Export, ExportCatogory = ExportResult.IVUS_CDISC_Export });
|
||||
//list.Add(new ExportDocumentDes() { Code = StaticData.Export.IVUS_CDISC_Export, ExportCatogory = ExportResult.IVUS_CDISC_Export });
|
||||
}
|
||||
if (criterion.CriterionGroup != CriterionGroup.Tumor /*&& criterion.CriterionType != CriterionType.OCT && criterion.CriterionType != CriterionType.IVUS*/)
|
||||
{
|
||||
@@ -2867,7 +3048,8 @@ namespace IRaCIS.Core.Application.Service.Common
|
||||
if (!criterion.IsArbitrationReading)
|
||||
{
|
||||
//仲裁阅片 才有裁判阅片明细表 同时要把模板里面的三列给去掉
|
||||
removeColumnIndexList = new List<int>() { 6, 7, 8 };
|
||||
//removeColumnIndexList = new List<int>() { 6, 7, 8 };
|
||||
removeColumnIndexList = new List<int>() { 7, 8, 9 };
|
||||
}
|
||||
|
||||
//阅片结果表 和阅片结果明细表 没有肿瘤学的时候需要移除肿瘤学三个字段
|
||||
@@ -2876,7 +3058,8 @@ namespace IRaCIS.Core.Application.Service.Common
|
||||
{
|
||||
if (inQuery.ReadingExportType == ExportResult.TableOfAssessmentResults || inQuery.ReadingExportType == ExportResult.DetailedTableOfAssessmentResults)
|
||||
{
|
||||
removeColumnIndexList = removeColumnIndexList.Union(new List<int>() { 9, 10, 11 }).ToList();
|
||||
//removeColumnIndexList = removeColumnIndexList.Union(new List<int>() { 9, 10, 11 }).ToList();
|
||||
removeColumnIndexList = removeColumnIndexList.Union(new List<int>() { 10, 11, 12 }).ToList();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2903,7 +3086,7 @@ namespace IRaCIS.Core.Application.Service.Common
|
||||
//阅片结果表
|
||||
export_Template = StaticData.Export.CommonReading_Export;
|
||||
}
|
||||
//斑块表
|
||||
//斑块表
|
||||
else if (inQuery.ReadingExportType == ExportResult.OCT_ReadingLession_Export)
|
||||
{
|
||||
//OCT
|
||||
@@ -2933,7 +3116,7 @@ namespace IRaCIS.Core.Application.Service.Common
|
||||
arbitrationRule = criterion.ArbitrationRule,
|
||||
trialReadingCriterionId = inQuery.TrialReadingCriterionId,
|
||||
isEn_Us = _userInfo.IsEn_Us
|
||||
}).ToListAsync();
|
||||
}).AsSplitQuery().ToListAsync();
|
||||
|
||||
}
|
||||
//肿瘤标准 病灶明细表 按照病灶级别 (OCT 暂时不删除,先看是否能覆盖)
|
||||
@@ -2952,7 +3135,7 @@ namespace IRaCIS.Core.Application.Service.Common
|
||||
arbitrationRule = criterion.ArbitrationRule,
|
||||
trialReadingCriterionId = inQuery.TrialReadingCriterionId,
|
||||
isEn_Us = _userInfo.IsEn_Us
|
||||
}).ToListAsync();
|
||||
}).AsSplitQuery().ToListAsync();
|
||||
|
||||
}
|
||||
// 非肿瘤标准 包括自定义,以及系统非肿瘤 会配置到表格层级 问题名称是 表格名称_表格子问题名
|
||||
@@ -2970,7 +3153,7 @@ namespace IRaCIS.Core.Application.Service.Common
|
||||
arbitrationRule = criterion.ArbitrationRule,
|
||||
trialReadingCriterionId = inQuery.TrialReadingCriterionId,
|
||||
isEn_Us = _userInfo.IsEn_Us
|
||||
}).ToListAsync();
|
||||
}).AsSplitQuery().ToListAsync();
|
||||
|
||||
}
|
||||
// CDISC 导出 只管到 外层问题层级 和阅片结果表是保持一致
|
||||
@@ -2988,7 +3171,7 @@ namespace IRaCIS.Core.Application.Service.Common
|
||||
arbitrationRule = criterion.ArbitrationRule,
|
||||
trialReadingCriterionId = inQuery.TrialReadingCriterionId,
|
||||
isEn_Us = _userInfo.IsEn_Us
|
||||
}).ToListAsync();
|
||||
}).AsSplitQuery().ToListAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -3000,7 +3183,7 @@ namespace IRaCIS.Core.Application.Service.Common
|
||||
arbitrationRule = criterion.ArbitrationRule,
|
||||
trialReadingCriterionId = inQuery.TrialReadingCriterionId,
|
||||
isEn_Us = _userInfo.IsEn_Us
|
||||
}).ToListAsync();
|
||||
}).AsSplitQuery().ToListAsync();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -3170,7 +3353,7 @@ namespace IRaCIS.Core.Application.Service.Common
|
||||
addLessionInfoList.Add(new CommonQuesionInfo() { QuestionName = _userInfo.IsEn_Us ? "Lesion Type" : "病灶类型", QuestionValue = lession.LessionType, TranslateDicName = "LesionType" });
|
||||
}
|
||||
|
||||
var dynamicPartialLessionInfoList = lession.LessionAnswerList.Select(t => new CommonQuesionInfo() { QuestionName = t.QuestionName, OptionTypeEnum = t.OptionTypeEnum, QuestionValue = t.QuestionValue, TranslateDicName = t.TranslateDicName ,Unit=t.Unit});
|
||||
var dynamicPartialLessionInfoList = lession.LessionAnswerList.Select(t => new CommonQuesionInfo() { QuestionName = t.QuestionName, OptionTypeEnum = t.OptionTypeEnum, QuestionValue = t.QuestionValue, TranslateDicName = t.TranslateDicName, Unit = t.Unit });
|
||||
|
||||
//有三部分组成 外层问题+ 没有配置病灶编号和类型+ 动态的表格问题
|
||||
var dynamicLessionInfoList = item.QuestionAnswerList.Union(addLessionInfoList).Union(dynamicPartialLessionInfoList).ToList();
|
||||
@@ -3358,9 +3541,10 @@ namespace IRaCIS.Core.Application.Service.Common
|
||||
|
||||
dynamicColumnConfig = new DynamicColumnConfig()
|
||||
{
|
||||
AutoColumnTitleRowIndex = 2,
|
||||
AutoColumnStartIndex = 6,
|
||||
TempalteLastColumnIndex = 11,
|
||||
|
||||
AutoColumnTitleRowIndex = 3, //2
|
||||
AutoColumnStartIndex = 7, //6
|
||||
TempalteLastColumnIndex = 12,//11
|
||||
DynamicItemDicName = "TranslateDicName",
|
||||
DynamicItemValueName = "QuestionValue",
|
||||
DynamicItemTitleName = "QuestionName",
|
||||
@@ -3372,7 +3556,7 @@ namespace IRaCIS.Core.Application.Service.Common
|
||||
TranslateDicNameList = translateDicNameList
|
||||
};
|
||||
|
||||
if (export_Template == StaticData.Export.ReadingLession_Export || export_Template == StaticData.Export.CommonJudgeReadingDetail_Export || export_Template== StaticData.Export.OCT_ReadingLession_Export)
|
||||
if (export_Template == StaticData.Export.ReadingLession_Export || export_Template == StaticData.Export.CommonJudgeReadingDetail_Export || export_Template == StaticData.Export.OCT_ReadingLession_Export)
|
||||
{
|
||||
dynamicColumnConfig.TempalteLastColumnIndex = 8;
|
||||
}
|
||||
@@ -3391,7 +3575,7 @@ namespace IRaCIS.Core.Application.Service.Common
|
||||
var trialConfigTableQuestionList = _trialReadingTableQuestionRepository.Where(t => t.TrialId == trialId && t.TrialCriterionId == trialReadingCriterionId).Where(t => t.ExportResultStr.Contains(((int)inQuery.ReadingExportType).ToString()))
|
||||
.Select(t => new ExportQuestionBasicInfo()
|
||||
{
|
||||
QuestionId = t.Id,
|
||||
QuestionId = t.Id,
|
||||
TableName = _userInfo.IsEn_Us ? t.ReadingQuestionTrial.QuestionEnName : t.ReadingQuestionTrial.QuestionName,
|
||||
QuestionName = _userInfo.IsEn_Us ? t.QuestionEnName : t.QuestionName,
|
||||
CDISCCode = t.CDISCCode,
|
||||
@@ -3435,7 +3619,7 @@ namespace IRaCIS.Core.Application.Service.Common
|
||||
var dynamicLessionInfoList = new List<CommonQuesionInfo>();
|
||||
|
||||
|
||||
var dynamicPartialLessionInfoList = lession.LessionAnswerList.Select(t => new CommonQuesionInfo() { QuestionId = t.TableQuesionId,OptionTypeEnum=t.OptionTypeEnum, QuestionName = t.QuestionName, QuestionValue = t.QuestionValue, TranslateDicName = t.TranslateDicName, CDISCCode = t.CDISCCode, Unit = t.Unit });
|
||||
var dynamicPartialLessionInfoList = lession.LessionAnswerList.Select(t => new CommonQuesionInfo() { QuestionId = t.TableQuesionId, OptionTypeEnum = t.OptionTypeEnum, QuestionName = t.QuestionName, QuestionValue = t.QuestionValue, TranslateDicName = t.TranslateDicName, CDISCCode = t.CDISCCode, Unit = t.Unit });
|
||||
|
||||
//两部分组成 外层问题+ 动态的表格问题
|
||||
dynamicLessionInfoList = item.QuestionAnswerList.Union(dynamicPartialLessionInfoList).ToList();
|
||||
@@ -3458,9 +3642,9 @@ namespace IRaCIS.Core.Application.Service.Common
|
||||
|
||||
dynamicColumnConfig = new DynamicColumnConfig()
|
||||
{
|
||||
AutoColumnTitleRowIndex = 1,
|
||||
AutoColumnStartIndex = 6,
|
||||
TempalteLastColumnIndex = 10,
|
||||
AutoColumnTitleRowIndex = 2, //1
|
||||
AutoColumnStartIndex = 7, //6
|
||||
TempalteLastColumnIndex = 11, //10
|
||||
DynamicItemDicName = "TranslateDicName",
|
||||
DynamicItemValueName = "QuestionValue",
|
||||
DynamicItemTitleName = "QuestionName",
|
||||
@@ -3543,9 +3727,9 @@ namespace IRaCIS.Core.Application.Service.Common
|
||||
|
||||
dynamicColumnConfig = new DynamicColumnConfig()
|
||||
{
|
||||
AutoColumnTitleRowIndex = 1,
|
||||
AutoColumnStartIndex = 6,
|
||||
TempalteLastColumnIndex = 15,
|
||||
AutoColumnTitleRowIndex = 2, //1
|
||||
AutoColumnStartIndex = 7, //6
|
||||
TempalteLastColumnIndex = 16, //15
|
||||
DynamicItemDicName = "TranslateDicName",
|
||||
DynamicItemValueName = "QuestionValue",
|
||||
DynamicItemTitleName = "QuestionName",
|
||||
@@ -3578,9 +3762,9 @@ namespace IRaCIS.Core.Application.Service.Common
|
||||
|
||||
dynamicColumnConfig = new DynamicColumnConfig()
|
||||
{
|
||||
AutoColumnTitleRowIndex = 1,
|
||||
AutoColumnStartIndex = 6,
|
||||
TempalteLastColumnIndex = 10,
|
||||
AutoColumnTitleRowIndex = 2, //1
|
||||
AutoColumnStartIndex = 7, //6
|
||||
TempalteLastColumnIndex = 11, //10
|
||||
DynamicItemDicName = "TranslateDicName",
|
||||
DynamicItemValueName = "QuestionValue",
|
||||
DynamicItemTitleName = "QuestionName",
|
||||
@@ -3650,12 +3834,12 @@ namespace IRaCIS.Core.Application.Service.Common
|
||||
|
||||
if (inQuery.ReadingExportType == ExportResult.NoneTumorCDISC)
|
||||
{
|
||||
(memoryStream, fileName) = await ExcelExportHelper.DataExport_NpoiTestAsync(export_Template, exportInfo, _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(CommonEvaluationExport), criterion.CriterionType, dynamicColumnConfig);
|
||||
(memoryStream, fileName) = await ExcelExportHelper.DataExport_ClosedXMLAsync(export_Template, exportInfo, _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(CommonEvaluationExport), criterion.CriterionType, dynamicColumnConfig);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
(memoryStream, fileName) = await ExcelExportHelper.DataExport_NpoiTestAsync(export_Template, exportInfo, _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(CommonEvaluationExport), criterion.CriterionType, dynamicColumnConfig);
|
||||
(memoryStream, fileName) = await ExcelExportHelper.DataExport_ClosedXMLAsync(export_Template, exportInfo, _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(CommonEvaluationExport), criterion.CriterionType, dynamicColumnConfig);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,26 +1,15 @@
|
||||
using DocumentFormat.OpenXml.Spreadsheet;
|
||||
using IRaCIS.Application.Contracts;
|
||||
using IRaCIS.Application.Contracts;
|
||||
using IRaCIS.Application.Interfaces;
|
||||
using IRaCIS.Core.Application.Helper;
|
||||
using IRaCIS.Core.Application.ViewModel;
|
||||
using IRaCIS.Core.Domain.Share;
|
||||
using IRaCIS.Core.Infra.EFCore.Common;
|
||||
using IRaCIS.Core.Infrastructure.Extention;
|
||||
using MassTransit;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using MiniExcelLibs;
|
||||
using MiniExcelLibs.OpenXml;
|
||||
using Newtonsoft.Json;
|
||||
using NPOI.SS.Formula.Functions;
|
||||
using Org.BouncyCastle.Asn1.X509;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace IRaCIS.Core.Application.Service.Common;
|
||||
|
||||
|
||||
@@ -1,32 +1,9 @@
|
||||
using Amazon.Runtime.Internal.Transform;
|
||||
using DocumentFormat.OpenXml.Bibliography;
|
||||
using DocumentFormat.OpenXml.Office2010.CustomUI;
|
||||
using DocumentFormat.OpenXml.Office2021.DocumentTasks;
|
||||
using DocumentFormat.OpenXml.Spreadsheet;
|
||||
using IRaCIS.Application.Contracts;
|
||||
using IRaCIS.Application.Contracts;
|
||||
using IRaCIS.Application.Interfaces;
|
||||
using IRaCIS.Core.API._ServiceExtensions.NewtonsoftJson;
|
||||
using IRaCIS.Core.Application.Contracts;
|
||||
using IRaCIS.Core.Application.Service.Reading.Dto;
|
||||
using IRaCIS.Core.Application.ViewModel;
|
||||
using IRaCIS.Core.Domain.Models;
|
||||
using IRaCIS.Core.Domain.Share;
|
||||
using IRaCIS.Core.Infra.EFCore.Common;
|
||||
using MailKit;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using NetTopologySuite.Triangulate.Tri;
|
||||
using NPOI.OpenXmlFormats.Spreadsheet;
|
||||
using NPOI.SS.Formula.Functions;
|
||||
using NPOI.Util;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using static IRaCIS.Core.Application.Service.ExcelExportHelper;
|
||||
|
||||
namespace IRaCIS.Core.Application.Service.Common;
|
||||
|
||||
|
||||
@@ -24,11 +24,26 @@ namespace IRaCIS.Core.Application.Service;
|
||||
[ApiExplorerSettings(GroupName = "Common")]
|
||||
public class FileUploadRecordService(IRepository<FileUploadRecord> _fileUploadRecordRepository, IRepository<UploadFileSyncRecord> _uploadFileSyncRecordRepository,
|
||||
IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer, IOptionsMonitor<ObjectStoreServiceOptions> options,
|
||||
IRepository<CommonUploadRecord> _commonUploadRecordRepository,
|
||||
IFusionCache _fusionCache, IRepository<Trial> _trialRepository, FileSyncQueue _fileSyncQueue) : BaseService, IFileUploadRecordService
|
||||
{
|
||||
|
||||
ObjectStoreServiceOptions ObjectStoreServiceConfig = options.CurrentValue;
|
||||
|
||||
/// <summary>
|
||||
/// 上传通用文件记录
|
||||
/// </summary>
|
||||
/// <param name="addOrEditCommonUploadRecord"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<IResponseOutput> AddOrUpdateCommonUploadRecord(CommonUploadRecordAddOrEdit addOrEditCommonUploadRecord)
|
||||
{
|
||||
|
||||
var entity = await _commonUploadRecordRepository.InsertOrUpdateAsync(addOrEditCommonUploadRecord, true);
|
||||
|
||||
return ResponseOutput.Ok(entity.Id.ToString());
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
@@ -222,7 +237,7 @@ public class FileUploadRecordService(IRepository<FileUploadRecord> _fileUploadRe
|
||||
{
|
||||
addOrEditFileUploadRecord.IsNeedSync = true;
|
||||
|
||||
addOrEditFileUploadRecord.Priority = addOrEditFileUploadRecord.Priority?? 0;
|
||||
addOrEditFileUploadRecord.Priority = addOrEditFileUploadRecord.Priority ?? 0;
|
||||
|
||||
addOrEditFileUploadRecord.IsSync = false;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
using IRaCIS.Application.Contracts;
|
||||
using DocumentFormat.OpenXml.Spreadsheet;
|
||||
using IRaCIS.Application.Contracts;
|
||||
using IRaCIS.Core.Application.Auth;
|
||||
using IRaCIS.Core.Application.Helper;
|
||||
using IRaCIS.Core.Application.MassTransit.Consumer;
|
||||
using IRaCIS.Core.Domain.Models;
|
||||
using IRaCIS.Core.Domain.Share;
|
||||
using IRaCIS.Core.Infrastructure;
|
||||
@@ -66,7 +68,7 @@ namespace IRaCIS.Core.Application.Service
|
||||
|
||||
Task AddUserSendEmailAsync(Guid userId, string baseUrl, string routeUrl);
|
||||
|
||||
Task AdminResetPwdSendEmailAsync(Guid userId, string pwdNotMd5 = "123456", string baseUrl="");
|
||||
Task AdminResetPwdSendEmailAsync(Guid userId, string pwdNotMd5 = "123456", string baseUrl = "");
|
||||
|
||||
Task SiteSurveyUserJoinEmail(Guid trialId, Guid userId, string userTypes, string baseUrl, string rootUrl);
|
||||
|
||||
@@ -104,10 +106,18 @@ namespace IRaCIS.Core.Application.Service
|
||||
{
|
||||
private readonly SystemEmailSendConfig _systemEmailConfig = systemEmailConfig.CurrentValue;
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取邮件主题和html 通用封装 以用户语言为主,没有的就用当前的请求语言_userInfo.IsEn_Us
|
||||
/// </summary>
|
||||
/// <param name="scenario"></param>
|
||||
/// <param name="messageToSend"></param>
|
||||
/// <param name="emailFunc"></param>
|
||||
/// <param name="userWorkLanguage"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="BusinessValidationFailedException"></exception>
|
||||
private async Task<EmailNoticeConfig> GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario scenario, MimeMessage messageToSend,
|
||||
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailFunc)
|
||||
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailFunc, UserWorkLanguage? userWorkLanguage = null)
|
||||
{
|
||||
var configInfo = await _emailNoticeConfigrepository.Where(t => t.BusinessScenarioEnum == scenario).FirstOrDefaultAsync();
|
||||
|
||||
@@ -119,7 +129,9 @@ namespace IRaCIS.Core.Application.Service
|
||||
}
|
||||
|
||||
|
||||
var (topicStr, htmlBodyStr) = _userInfo.IsEn_Us ? (configInfo.EmailTopic, configInfo.EmailHtmlContent) : (configInfo.EmailTopicCN, configInfo.EmailHtmlContentCN);
|
||||
bool isEn_Us = userWorkLanguage.HasValue ? userWorkLanguage.Value == UserWorkLanguage.US : _userInfo.IsEn_Us;
|
||||
|
||||
var (topicStr, htmlBodyStr) = isEn_Us ? (configInfo.EmailTopic, configInfo.EmailHtmlContent) : (configInfo.EmailTopicCN, configInfo.EmailHtmlContentCN);
|
||||
|
||||
try
|
||||
{
|
||||
@@ -182,24 +194,16 @@ namespace IRaCIS.Core.Application.Service
|
||||
return sucessHandle;
|
||||
}
|
||||
|
||||
private string ReplaceCompanyName(string needDealtxt)
|
||||
{
|
||||
var str = needDealtxt.Replace("{company}", _userInfo.IsEn_Us ? _systemEmailConfig.CompanyName : _systemEmailConfig.CompanyNameCN)
|
||||
.Replace("{company abbreviation}", _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN);
|
||||
return str;
|
||||
}
|
||||
|
||||
private string ReplacePlatformName(string needDealtxt)
|
||||
{
|
||||
var platformName = _userInfo.IsEn_Us ? _systemEmailConfig.PlatformName : _systemEmailConfig.PlatformNameCN;
|
||||
|
||||
var str = needDealtxt.Replace("{platformName}", platformName);
|
||||
return str;
|
||||
}
|
||||
|
||||
//MFA
|
||||
public async Task SenMFAVerifyEmail(Guid userId, string userName, string emailAddress, int verificationCode, UserMFAType mfaType = UserMFAType.Login)
|
||||
{
|
||||
|
||||
//设置工作语言
|
||||
var workLanguage = _identityUserRepository.Where(t => t.Id == userId).Select(t => t.UserWorkLanguage).First();
|
||||
var isEn_US = workLanguage == UserWorkLanguage.US;
|
||||
|
||||
var messageToSend = new MimeMessage();
|
||||
//发件地址
|
||||
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
|
||||
@@ -207,13 +211,13 @@ namespace IRaCIS.Core.Application.Service
|
||||
messageToSend.To.Add(new MailboxAddress(userName, emailAddress));
|
||||
//主题---[来自{0}] 关于MFA邮箱验证的提醒
|
||||
|
||||
var companyName = _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
|
||||
var companyName = isEn_US ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
|
||||
|
||||
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
|
||||
{
|
||||
var topicStr = string.Format(input.topicStr, companyName);
|
||||
|
||||
var htmlBodyStr = string.Format(ReplaceCompanyName(input.htmlBodyStr),
|
||||
var htmlBodyStr = string.Format(CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr, workLanguage),
|
||||
userName,
|
||||
verificationCode
|
||||
);
|
||||
@@ -222,7 +226,7 @@ namespace IRaCIS.Core.Application.Service
|
||||
};
|
||||
|
||||
|
||||
await GetEmailSubejctAndHtmlInfoAndBuildAsync(mfaType == UserMFAType.Login ? EmailBusinessScenario.MFALogin : EmailBusinessScenario.MFAUnlock, messageToSend, emailConfigFunc);
|
||||
await GetEmailSubejctAndHtmlInfoAndBuildAsync(mfaType == UserMFAType.Login ? EmailBusinessScenario.MFALogin : EmailBusinessScenario.MFAUnlock, messageToSend, emailConfigFunc, workLanguage);
|
||||
|
||||
|
||||
var sucessHandle = GetEmailSuccessHandle(userId, verificationCode, emailAddress);
|
||||
@@ -245,6 +249,11 @@ namespace IRaCIS.Core.Application.Service
|
||||
public async Task SendEmailVerification(string emailAddress, int verificationCode)
|
||||
{
|
||||
|
||||
//设置工作语言
|
||||
var isEn_US = _userInfo.IsEn_Us;
|
||||
var workLanguage = isEn_US ? UserWorkLanguage.US : UserWorkLanguage.CN;
|
||||
|
||||
|
||||
var messageToSend = new MimeMessage();
|
||||
//发件地址
|
||||
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
|
||||
@@ -253,13 +262,13 @@ namespace IRaCIS.Core.Application.Service
|
||||
//主题
|
||||
//---[来自展影IRC]的提醒
|
||||
|
||||
var companyName = _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
|
||||
var companyName = isEn_US ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
|
||||
|
||||
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
|
||||
{
|
||||
var topicStr = string.Format(input.topicStr, companyName);
|
||||
|
||||
var htmlBodyStr = string.Format(ReplaceCompanyName(input.htmlBodyStr),
|
||||
var htmlBodyStr = string.Format(CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr, workLanguage),
|
||||
|
||||
"Sir/Madam",
|
||||
//---您正在参与展影医疗IRC项目
|
||||
@@ -271,7 +280,7 @@ namespace IRaCIS.Core.Application.Service
|
||||
};
|
||||
|
||||
|
||||
await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.ReviewerLogin, messageToSend, emailConfigFunc);
|
||||
await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.ReviewerLogin, messageToSend, emailConfigFunc, workLanguage);
|
||||
|
||||
//此时不知道用户
|
||||
var sucessHandle = GetEmailSuccessHandle(Guid.Empty, verificationCode, emailAddress);
|
||||
@@ -286,8 +295,10 @@ namespace IRaCIS.Core.Application.Service
|
||||
//中心调研 登陆 发送验证码
|
||||
public async Task AnolymousSendEmail(Guid trialId, string emailAddress, int verificationCode)
|
||||
{
|
||||
//throw new BusinessValidationFailedException("模拟邮件取数据或者发送异常!!!");
|
||||
|
||||
//设置工作语言
|
||||
var isEn_US = _userInfo.IsEn_Us;
|
||||
var workLanguage = isEn_US ? UserWorkLanguage.US : UserWorkLanguage.CN;
|
||||
|
||||
var trialInfo = await _trialRepository.FirstOrDefaultAsync(t => t.Id == trialId);
|
||||
|
||||
@@ -299,13 +310,13 @@ namespace IRaCIS.Core.Application.Service
|
||||
//主题
|
||||
//$"[来自展影IRC] [{researchProgramNo}] 关于中心调研的提醒";
|
||||
|
||||
var companyName = _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
|
||||
var companyName = isEn_US ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
|
||||
|
||||
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
|
||||
{
|
||||
var topicStr = string.Format(input.topicStr, companyName, trialInfo.ResearchProgramNo);
|
||||
|
||||
var htmlBodyStr = string.Format(ReplaceCompanyName(input.htmlBodyStr),
|
||||
var htmlBodyStr = string.Format(CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr, workLanguage),
|
||||
|
||||
"Sir/Madam",
|
||||
//---您正在参与展影医疗IRC项目中心调研工作
|
||||
@@ -317,13 +328,13 @@ namespace IRaCIS.Core.Application.Service
|
||||
};
|
||||
|
||||
|
||||
await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.SiteSurveyLogin, messageToSend, emailConfigFunc);
|
||||
await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.SiteSurveyLogin, messageToSend, emailConfigFunc, workLanguage);
|
||||
|
||||
//此时不知道用户
|
||||
var sucessHandle = GetEmailSuccessHandle(Guid.Empty, verificationCode, emailAddress);
|
||||
|
||||
|
||||
await SendEmailHelper.SendEmailAsync(messageToSend, trialInfo, sucessHandle);
|
||||
await SendEmailHelper.SendTrialEmailAsync(messageToSend, trialInfo, sucessHandle);
|
||||
|
||||
}
|
||||
|
||||
@@ -335,6 +346,9 @@ namespace IRaCIS.Core.Application.Service
|
||||
|
||||
var sysUserInfo = (await _identityUserRepository.Where(t => t.Id == userId).Include(t => t.UserRoleList).ThenInclude(c => c.UserTypeRole).FirstOrDefaultAsync()).IfNullThrowException();
|
||||
|
||||
//设置工作语言
|
||||
var workLanguage = sysUserInfo.UserWorkLanguage;
|
||||
var isEn_US = workLanguage == UserWorkLanguage.US;
|
||||
|
||||
var messageToSend = new MimeMessage();
|
||||
//发件地址
|
||||
@@ -349,20 +363,19 @@ namespace IRaCIS.Core.Application.Service
|
||||
|
||||
await _identityUserRepository.BatchUpdateNoTrackingAsync(t => t.Id == sysUserInfo.Id, u => new IdentityUser() { EmailToken = token });
|
||||
|
||||
routeUrl = routeUrl + "?UserId=" + sysUserInfo.Id + "&Email=" + sysUserInfo.EMail + "&UserName=" + sysUserInfo.UserName + "&lang=" + (_userInfo.IsEn_Us ? "en" : "zh") + "&access_token=" + token;
|
||||
routeUrl = routeUrl + "?UserId=" + sysUserInfo.Id + "&Email=" + sysUserInfo.EMail + "&UserName=" + sysUserInfo.UserName + "&lang=" + (isEn_US ? "en" : "zh") + "&access_token=" + token;
|
||||
|
||||
var domain = baseUrl.Substring(0, baseUrl.IndexOf("/login"));
|
||||
|
||||
var redirectUrl = $"{domain}/api/User/UserRedirect?url={System.Web.HttpUtility.UrlEncode(routeUrl)}";
|
||||
|
||||
|
||||
var companyName = _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
|
||||
var companyName = isEn_US ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
|
||||
|
||||
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
|
||||
{
|
||||
var topicStr = string.Format(input.topicStr, companyName);
|
||||
|
||||
var htmlBodyStr = string.Format(ReplaceCompanyName(input.htmlBodyStr),
|
||||
var htmlBodyStr = string.Format(CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr, workLanguage),
|
||||
|
||||
sysUserInfo.FullName,
|
||||
sysUserInfo.EMail,
|
||||
@@ -374,7 +387,7 @@ namespace IRaCIS.Core.Application.Service
|
||||
};
|
||||
|
||||
|
||||
await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.SysCreateUser, messageToSend, emailConfigFunc);
|
||||
await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.SysCreateUser, messageToSend, emailConfigFunc, sysUserInfo.UserWorkLanguage);
|
||||
|
||||
|
||||
await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig);
|
||||
@@ -385,6 +398,11 @@ namespace IRaCIS.Core.Application.Service
|
||||
{
|
||||
var sysUserInfo = (await _identityUserRepository.Where(t => t.Id == userId).Include(t => t.UserRoleList).ThenInclude(c => c.UserTypeRole).FirstOrDefaultAsync()).IfNullThrowException();
|
||||
|
||||
|
||||
//设置工作语言
|
||||
var workLanguage = sysUserInfo.UserWorkLanguage;
|
||||
var isEn_US = workLanguage == UserWorkLanguage.US;
|
||||
|
||||
var messageToSend = new MimeMessage();
|
||||
//发件地址
|
||||
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
|
||||
@@ -393,13 +411,13 @@ namespace IRaCIS.Core.Application.Service
|
||||
//主题
|
||||
//---[来自展影IRC] 关于重置账户密码的提醒
|
||||
|
||||
var companyName = _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
|
||||
var companyName = isEn_US ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
|
||||
|
||||
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
|
||||
{
|
||||
var topicStr = string.Format(input.topicStr, companyName);
|
||||
|
||||
var htmlBodyStr = string.Format(ReplaceCompanyName(input.htmlBodyStr),
|
||||
var htmlBodyStr = string.Format(CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr, workLanguage),
|
||||
|
||||
sysUserInfo.FullName,
|
||||
sysUserInfo.UserName,
|
||||
@@ -413,7 +431,7 @@ namespace IRaCIS.Core.Application.Service
|
||||
};
|
||||
|
||||
|
||||
await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.SysResetPassword, messageToSend, emailConfigFunc);
|
||||
await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.SysResetPassword, messageToSend, emailConfigFunc, sysUserInfo.UserWorkLanguage);
|
||||
|
||||
await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig);
|
||||
}
|
||||
@@ -421,6 +439,10 @@ namespace IRaCIS.Core.Application.Service
|
||||
//用户重置邮箱
|
||||
public async Task SendMailEditEmail(Guid userId, string userName, string emailAddress, int verificationCode)
|
||||
{
|
||||
//设置工作语言
|
||||
var workLanguage = _identityUserRepository.Where(t => t.Id == userId).Select(t => t.UserWorkLanguage).First();
|
||||
var isEn_US = workLanguage == UserWorkLanguage.US;
|
||||
|
||||
|
||||
var messageToSend = new MimeMessage();
|
||||
//发件地址
|
||||
@@ -430,13 +452,13 @@ namespace IRaCIS.Core.Application.Service
|
||||
//主题
|
||||
//---[来自展影IRC] 关于重置邮箱的提醒
|
||||
|
||||
var companyName = _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
|
||||
var companyName = isEn_US ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
|
||||
|
||||
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
|
||||
{
|
||||
var topicStr = string.Format(input.topicStr, companyName);
|
||||
|
||||
var htmlBodyStr = string.Format(ReplaceCompanyName(input.htmlBodyStr),
|
||||
var htmlBodyStr = string.Format(CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr, workLanguage),
|
||||
|
||||
userName,
|
||||
//---您正在进行邮箱重置操作
|
||||
@@ -447,7 +469,7 @@ namespace IRaCIS.Core.Application.Service
|
||||
};
|
||||
|
||||
|
||||
await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.UserResetEmail, messageToSend, emailConfigFunc);
|
||||
await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.UserResetEmail, messageToSend, emailConfigFunc, workLanguage);
|
||||
|
||||
|
||||
var sucessHandle = GetEmailSuccessHandle(userId, verificationCode, emailAddress);
|
||||
@@ -460,6 +482,11 @@ namespace IRaCIS.Core.Application.Service
|
||||
//不登录 通过邮箱重置密码
|
||||
public async Task AnolymousSendEmailForResetAccount(string emailAddress, int verificationCode)
|
||||
{
|
||||
|
||||
//设置工作语言
|
||||
var isEn_US = _userInfo.IsEn_Us;
|
||||
var workLanguage = isEn_US ? UserWorkLanguage.US : UserWorkLanguage.CN;
|
||||
|
||||
var messageToSend = new MimeMessage();
|
||||
//发件地址
|
||||
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
|
||||
@@ -467,13 +494,13 @@ namespace IRaCIS.Core.Application.Service
|
||||
messageToSend.To.Add(new MailboxAddress(String.Empty, emailAddress));
|
||||
|
||||
|
||||
var companyName = _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
|
||||
var companyName = isEn_US ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
|
||||
|
||||
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
|
||||
{
|
||||
var topicStr = string.Format(input.topicStr, companyName);
|
||||
|
||||
var htmlBodyStr = string.Format(ReplaceCompanyName(input.htmlBodyStr),
|
||||
var htmlBodyStr = string.Format(CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr, workLanguage),
|
||||
|
||||
"Sir/Madam",
|
||||
//---您正在进行邮箱重置密码操作
|
||||
@@ -484,7 +511,7 @@ namespace IRaCIS.Core.Application.Service
|
||||
};
|
||||
|
||||
|
||||
await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.UnloginUseEmailResetPassword, messageToSend, emailConfigFunc);
|
||||
await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.UnloginUseEmailResetPassword, messageToSend, emailConfigFunc, workLanguage);
|
||||
|
||||
////此时不知道用户
|
||||
var sucessHandle = GetEmailSuccessHandle(Guid.Empty, verificationCode, emailAddress);
|
||||
@@ -500,6 +527,11 @@ namespace IRaCIS.Core.Application.Service
|
||||
|
||||
var sysUserInfo = (await _identityUserRepository.Where(t => t.Id == userId).FirstOrDefaultAsync()).IfNullThrowException();
|
||||
|
||||
//设置工作语言
|
||||
var workLanguage = sysUserInfo.UserWorkLanguage;
|
||||
var isEn_US = workLanguage == UserWorkLanguage.US;
|
||||
|
||||
|
||||
var messageToSend = new MimeMessage();
|
||||
//发件地址
|
||||
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
|
||||
@@ -518,18 +550,18 @@ namespace IRaCIS.Core.Application.Service
|
||||
|
||||
var domain = baseUrl.Substring(0, baseUrl.IndexOf("/login"));
|
||||
|
||||
var routeUrl = rootUrl + "?UserId=" + sysUserInfo.Id + "&Email=" + sysUserInfo.EMail + "&lang=" + (_userInfo.IsEn_Us ? "en" : "zh") + "&access_token=" + token;
|
||||
var routeUrl = rootUrl + "?UserId=" + sysUserInfo.Id + "&Email=" + sysUserInfo.EMail + "&lang=" + (isEn_US ? "en" : "zh") + "&access_token=" + token;
|
||||
|
||||
var redirectUrl = $"{domain}/api/User/UserRedirect?url={System.Web.HttpUtility.UrlEncode(routeUrl)}";
|
||||
|
||||
|
||||
var companyName = _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
|
||||
var companyName = isEn_US ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
|
||||
|
||||
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
|
||||
{
|
||||
var topicStr = string.Format(input.topicStr, companyName, trialInfo.ResearchProgramNo);
|
||||
|
||||
var htmlBodyStr = string.Format(ReplaceCompanyName(input.htmlBodyStr),
|
||||
var htmlBodyStr = string.Format(CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr, workLanguage),
|
||||
|
||||
sysUserInfo.FullName,
|
||||
trialInfo.ExperimentName,
|
||||
@@ -544,9 +576,9 @@ namespace IRaCIS.Core.Application.Service
|
||||
};
|
||||
|
||||
|
||||
await GetEmailSubejctAndHtmlInfoAndBuildAsync(sysUserInfo.IsFirstAdd ? EmailBusinessScenario.SiteUseOrExternalUserFirstrJoinTrial : EmailBusinessScenario.SiteUserOrExternalUserExistJoinTrial, messageToSend, emailConfigFunc);
|
||||
await GetEmailSubejctAndHtmlInfoAndBuildAsync(sysUserInfo.IsFirstAdd ? EmailBusinessScenario.SiteUseOrExternalUserFirstrJoinTrial : EmailBusinessScenario.SiteUserOrExternalUserExistJoinTrial, messageToSend, emailConfigFunc, workLanguage);
|
||||
|
||||
await SendEmailHelper.SendEmailAsync(messageToSend, trialInfo, null);
|
||||
await SendEmailHelper.SendTrialEmailAsync(messageToSend, trialInfo);
|
||||
|
||||
}
|
||||
|
||||
@@ -555,10 +587,12 @@ namespace IRaCIS.Core.Application.Service
|
||||
{
|
||||
var sysUserInfo = (await _identityUserRepository.Where(t => t.Id == userId).FirstOrDefaultAsync()).IfNullThrowException();
|
||||
|
||||
|
||||
|
||||
var trialInfo = await _trialRepository.FirstOrDefaultAsync(t => t.Id == trialId);
|
||||
|
||||
//设置工作语言
|
||||
var workLanguage = sysUserInfo.UserWorkLanguage;
|
||||
var isEn_US = workLanguage == UserWorkLanguage.US;
|
||||
|
||||
var messageToSend = new MimeMessage();
|
||||
//发件地址
|
||||
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
|
||||
@@ -575,20 +609,20 @@ namespace IRaCIS.Core.Application.Service
|
||||
await _identityUserRepository.BatchUpdateNoTrackingAsync(t => t.Id == sysUserInfo.Id, u => new Domain.Models.IdentityUser() { EmailToken = token });
|
||||
}
|
||||
|
||||
var routeUrl = rootUrl + "?UserId=" + sysUserInfo.Id + "&Email=" + sysUserInfo.EMail + "&lang=" + (_userInfo.IsEn_Us ? "en" : "zh") + "&access_token=" + token;
|
||||
var routeUrl = rootUrl + "?UserId=" + sysUserInfo.Id + "&Email=" + sysUserInfo.EMail + "&lang=" + (isEn_US ? "en" : "zh") + "&access_token=" + token;
|
||||
|
||||
var domain = baseUrl.Substring(0, baseUrl.IndexOf("/login"));
|
||||
|
||||
var redirectUrl = $"{domain}/api/User/UserRedirect?url={System.Web.HttpUtility.UrlEncode(routeUrl)}";
|
||||
|
||||
|
||||
var companyName = _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
|
||||
var companyName = isEn_US ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
|
||||
|
||||
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
|
||||
{
|
||||
var topicStr = string.Format(input.topicStr, companyName, trialInfo.ResearchProgramNo);
|
||||
|
||||
var htmlBodyStr = string.Format(ReplaceCompanyName(input.htmlBodyStr),
|
||||
var htmlBodyStr = string.Format(CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr, workLanguage),
|
||||
|
||||
sysUserInfo.FullName,
|
||||
trialInfo.ExperimentName,
|
||||
@@ -603,9 +637,9 @@ namespace IRaCIS.Core.Application.Service
|
||||
};
|
||||
|
||||
|
||||
await GetEmailSubejctAndHtmlInfoAndBuildAsync(sysUserInfo.IsFirstAdd ? EmailBusinessScenario.SiteUseOrExternalUserFirstrJoinTrial : EmailBusinessScenario.SiteUserOrExternalUserExistJoinTrial, messageToSend, emailConfigFunc);
|
||||
await GetEmailSubejctAndHtmlInfoAndBuildAsync(sysUserInfo.IsFirstAdd ? EmailBusinessScenario.SiteUseOrExternalUserFirstrJoinTrial : EmailBusinessScenario.SiteUserOrExternalUserExistJoinTrial, messageToSend, emailConfigFunc, workLanguage);
|
||||
|
||||
await SendEmailHelper.SendEmailAsync(messageToSend, trialInfo);
|
||||
await SendEmailHelper.SendTrialEmailAsync(messageToSend, trialInfo);
|
||||
|
||||
}
|
||||
|
||||
@@ -644,6 +678,12 @@ namespace IRaCIS.Core.Application.Service
|
||||
saveItem.IsTestUser = true;
|
||||
}
|
||||
|
||||
|
||||
//通过医生信息,设置工作语言
|
||||
var nation = _doctorTypeRepository.Where(t => t.Id == doctorId).Select(t => t.Nation).FirstOrDefault();
|
||||
saveItem.UserWorkLanguage = nation == DoctorNation.CN ? UserWorkLanguage.CN : UserWorkLanguage.US;
|
||||
|
||||
|
||||
saveItem.UserCeateSource = UserCeateSource.ReviewerSelect;
|
||||
saveItem.TrialId = trialId;
|
||||
|
||||
@@ -686,6 +726,11 @@ namespace IRaCIS.Core.Application.Service
|
||||
|
||||
var trialInfo = await _trialRepository.FirstOrDefaultAsync(t => t.Id == trialId);
|
||||
|
||||
|
||||
//设置工作语言
|
||||
var workLanguage = sysUserInfo.UserWorkLanguage;
|
||||
var isEn_US = workLanguage == UserWorkLanguage.US;
|
||||
|
||||
var messageToSend = new MimeMessage();
|
||||
//发件地址
|
||||
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
|
||||
@@ -701,7 +746,7 @@ namespace IRaCIS.Core.Application.Service
|
||||
await _identityUserRepository.BatchUpdateNoTrackingAsync(t => t.Id == sysUserInfo.Id, u => new Domain.Models.IdentityUser() { EmailToken = token });
|
||||
}
|
||||
|
||||
var routeUrl = rootUrl + "?UserId=" + sysUserInfo.Id + "&Email=" + sysUserInfo.EMail + "&lang=" + (_userInfo.IsEn_Us ? "en" : "zh") + "&access_token=" + token;
|
||||
var routeUrl = rootUrl + "?UserId=" + sysUserInfo.Id + "&Email=" + sysUserInfo.EMail + "&lang=" + (isEn_US ? "en" : "zh") + "&access_token=" + token;
|
||||
|
||||
var domain = baseUrl.Substring(0, baseUrl.IndexOf("/login"));
|
||||
|
||||
@@ -711,13 +756,13 @@ namespace IRaCIS.Core.Application.Service
|
||||
// $"[来自展影IRC] [{trialInfo.ResearchProgramNo}]邀请信";
|
||||
|
||||
|
||||
var companyName = _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
|
||||
var companyName = isEn_US ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
|
||||
|
||||
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
|
||||
{
|
||||
var topicStr = string.Format(input.topicStr, companyName, trialInfo.ResearchProgramNo);
|
||||
|
||||
var htmlBodyStr = string.Format(ReplaceCompanyName(input.htmlBodyStr),
|
||||
var htmlBodyStr = string.Format(CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr, workLanguage),
|
||||
|
||||
sysUserInfo.FullName,
|
||||
trialInfo.ExperimentName,
|
||||
@@ -732,9 +777,9 @@ namespace IRaCIS.Core.Application.Service
|
||||
};
|
||||
|
||||
|
||||
await GetEmailSubejctAndHtmlInfoAndBuildAsync(sysUserInfo.IsFirstAdd ? EmailBusinessScenario.DoctorUserFirstJoinTrial : EmailBusinessScenario.DoctorUserExistJoinTrial, messageToSend, emailConfigFunc);
|
||||
await GetEmailSubejctAndHtmlInfoAndBuildAsync(sysUserInfo.IsFirstAdd ? EmailBusinessScenario.DoctorUserFirstJoinTrial : EmailBusinessScenario.DoctorUserExistJoinTrial, messageToSend, emailConfigFunc,workLanguage);
|
||||
|
||||
await SendEmailHelper.SendEmailAsync(messageToSend, trialInfo, null);
|
||||
await SendEmailHelper.SendTrialEmailAsync(messageToSend, trialInfo, null);
|
||||
|
||||
//创建账号 和创建角色 一条,更新的时候才记录更新角色
|
||||
if (isNeedCreateNewUser == false)
|
||||
@@ -754,6 +799,10 @@ namespace IRaCIS.Core.Application.Service
|
||||
{
|
||||
var feedBack = await _userFeedBackRepository.Where(t => t.Id == feedBackId).Include(t => t.CreateUserRole.UserTypeRole).Include(t => t.CreateUserRole.IdentityUser).FirstNotNullAsync();
|
||||
|
||||
//设置工作语言
|
||||
var workLanguage = _identityUserRepository.Where(t => t.Id == _userInfo.IdentityUserId).Select(t => t.UserWorkLanguage).First();
|
||||
var isEn_US = workLanguage == UserWorkLanguage.US;
|
||||
|
||||
var messageToSend = new MimeMessage();
|
||||
//发件地址
|
||||
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
|
||||
@@ -762,7 +811,7 @@ namespace IRaCIS.Core.Application.Service
|
||||
|
||||
var trialinfo = await _trialRepository.Where(x => x.Id == feedBack.TrialId).FirstOrDefaultAsync();
|
||||
|
||||
var companyName = _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
|
||||
var companyName = isEn_US ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
|
||||
|
||||
var emialScenario = feedBack.VisitTaskId != null ? EmailBusinessScenario.IRImageError : (feedBack.SubjectVisitId != null ? EmailBusinessScenario.TrialSubjectVisitFeedBack : (feedBack.TrialId != null ? EmailBusinessScenario.TrialFeedBack : EmailBusinessScenario.SysFeedBack));
|
||||
|
||||
@@ -785,7 +834,7 @@ namespace IRaCIS.Core.Application.Service
|
||||
if (feedBack.VisitTaskId != null)
|
||||
{
|
||||
|
||||
var emailType = await _dictionaryRepository.Where(t => t.Parent.Code == "FeedBackTypeToIR" && t.ParentId != null && t.Code == ((int)feedBack.QuestionType).ToString()).Select(t => _userInfo.IsEn_Us ? t.Value : t.ValueCN).FirstOrDefaultAsync();
|
||||
var emailType = await _dictionaryRepository.Where(t => t.Parent.Code == "FeedBackTypeToIR" && t.ParentId != null && t.Code == ((int)feedBack.QuestionType).ToString()).Select(t => isEn_US ? t.Value : t.ValueCN).FirstOrDefaultAsync();
|
||||
|
||||
|
||||
var info = await _visitTaskRepository.Where(t => t.Id == feedBack.VisitTaskId).Select(t => new { t.Trial.ResearchProgramNo, t.Trial.TrialCode, SubejctCode = t.Subject.Code, t.SourceSubjectVisit.VisitName }).FirstNotNullAsync();
|
||||
@@ -794,7 +843,7 @@ namespace IRaCIS.Core.Application.Service
|
||||
{
|
||||
var topicStr = string.Format(input.topicStr, info.ResearchProgramNo, info.SubejctCode, info.VisitName);
|
||||
|
||||
var htmlBodyStr = string.Format(ReplaceCompanyName(input.htmlBodyStr),
|
||||
var htmlBodyStr = string.Format(CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr, workLanguage),
|
||||
userNames,
|
||||
info.TrialCode,
|
||||
info.SubejctCode,
|
||||
@@ -810,12 +859,12 @@ namespace IRaCIS.Core.Application.Service
|
||||
};
|
||||
|
||||
|
||||
await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.IRImageError, messageToSend, emailConfigFunc);
|
||||
await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.IRImageError, messageToSend, emailConfigFunc, workLanguage);
|
||||
|
||||
}
|
||||
else if (feedBack.SubjectVisitId != null)
|
||||
{
|
||||
var emailType = await _dictionaryRepository.Where(t => t.Parent.Code == "Email_BusinessScenario" && t.ParentId != null && t.Code == ((int)EmailBusinessScenario.TrialSubjectVisitFeedBack).ToString()).Select(t => _userInfo.IsEn_Us ? t.Value : t.ValueCN).FirstOrDefaultAsync();
|
||||
var emailType = await _dictionaryRepository.Where(t => t.Parent.Code == "Email_BusinessScenario" && t.ParentId != null && t.Code == ((int)EmailBusinessScenario.TrialSubjectVisitFeedBack).ToString()).Select(t => isEn_US ? t.Value : t.ValueCN).FirstOrDefaultAsync();
|
||||
|
||||
|
||||
var info = await _subjectVisitRepository.Where(t => t.Id == feedBack.SubjectVisitId).Select(t => new { t.Trial.ResearchProgramNo, t.Trial.TrialCode, SubejctCode = t.Subject.Code, t.VisitName }).FirstNotNullAsync();
|
||||
@@ -824,7 +873,7 @@ namespace IRaCIS.Core.Application.Service
|
||||
{
|
||||
var topicStr = string.Format(input.topicStr, info.ResearchProgramNo, info.SubejctCode, info.VisitName);
|
||||
|
||||
var htmlBodyStr = string.Format(ReplaceCompanyName(input.htmlBodyStr),
|
||||
var htmlBodyStr = string.Format(CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr, workLanguage),
|
||||
userNames,
|
||||
info.TrialCode,
|
||||
info.SubejctCode,
|
||||
@@ -840,13 +889,13 @@ namespace IRaCIS.Core.Application.Service
|
||||
};
|
||||
|
||||
|
||||
await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.TrialSubjectVisitFeedBack, messageToSend, emailConfigFunc);
|
||||
await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.TrialSubjectVisitFeedBack, messageToSend, emailConfigFunc, workLanguage);
|
||||
}
|
||||
//项目相关的反馈 pm admin
|
||||
else if (feedBack.TrialId != null)
|
||||
{
|
||||
|
||||
var emailType = await _dictionaryRepository.Where(t => t.Parent.Code == "Email_BusinessScenario" && t.ParentId != null && t.Code == ((int)EmailBusinessScenario.TrialFeedBack).ToString()).Select(t => _userInfo.IsEn_Us ? t.Value : t.ValueCN).FirstOrDefaultAsync();
|
||||
var emailType = await _dictionaryRepository.Where(t => t.Parent.Code == "Email_BusinessScenario" && t.ParentId != null && t.Code == ((int)EmailBusinessScenario.TrialFeedBack).ToString()).Select(t => isEn_US ? t.Value : t.ValueCN).FirstOrDefaultAsync();
|
||||
|
||||
|
||||
var info = await _trialRepository.Where(t => t.Id == feedBack.TrialId).Select(t => new { t.ResearchProgramNo, t.TrialCode }).FirstNotNullAsync();
|
||||
@@ -855,7 +904,7 @@ namespace IRaCIS.Core.Application.Service
|
||||
{
|
||||
var topicStr = string.Format(input.topicStr, info.ResearchProgramNo);
|
||||
|
||||
var htmlBodyStr = string.Format(ReplaceCompanyName(input.htmlBodyStr),
|
||||
var htmlBodyStr = string.Format(CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr, workLanguage),
|
||||
userNames,
|
||||
info.TrialCode,
|
||||
feedBack.CreateUserRole.UserTypeRole.UserTypeShortName,
|
||||
@@ -869,7 +918,7 @@ namespace IRaCIS.Core.Application.Service
|
||||
};
|
||||
|
||||
|
||||
await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.TrialFeedBack, messageToSend, emailConfigFunc);
|
||||
await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.TrialFeedBack, messageToSend, emailConfigFunc, workLanguage);
|
||||
|
||||
}
|
||||
//项目无关的反馈 admin
|
||||
@@ -881,7 +930,7 @@ namespace IRaCIS.Core.Application.Service
|
||||
{
|
||||
var topicStr = string.Format(input.topicStr);
|
||||
|
||||
var htmlBodyStr = string.Format(ReplaceCompanyName(input.htmlBodyStr),
|
||||
var htmlBodyStr = string.Format(CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr, workLanguage),
|
||||
userNames,
|
||||
feedBack.CreateUserRole.UserTypeRole.UserTypeShortName,
|
||||
feedBack.CreateUserRole.IdentityUser.FullName,
|
||||
@@ -893,7 +942,7 @@ namespace IRaCIS.Core.Application.Service
|
||||
};
|
||||
|
||||
|
||||
await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.SysFeedBack, messageToSend, emailConfigFunc);
|
||||
await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.SysFeedBack, messageToSend, emailConfigFunc, workLanguage);
|
||||
}
|
||||
|
||||
if (trialinfo == null)
|
||||
@@ -902,9 +951,9 @@ namespace IRaCIS.Core.Application.Service
|
||||
}
|
||||
else
|
||||
{
|
||||
await SendEmailHelper.SendEmailAsync(messageToSend, trialinfo);
|
||||
await SendEmailHelper.SendTrialEmailAsync(messageToSend, trialinfo);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -915,6 +964,10 @@ namespace IRaCIS.Core.Application.Service
|
||||
|
||||
var sysUserInfo = (await _identityUserRepository.Where(t => t.Id == userId).FirstOrDefaultAsync()).IfNullThrowException();
|
||||
|
||||
//设置工作语言
|
||||
var workLanguage = sysUserInfo.UserWorkLanguage;
|
||||
var isEn_US = workLanguage == UserWorkLanguage.US;
|
||||
|
||||
var messageToSend = new MimeMessage();
|
||||
//发件地址
|
||||
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
|
||||
@@ -923,22 +976,23 @@ namespace IRaCIS.Core.Application.Service
|
||||
//主题
|
||||
//---[来自展影IRC] 关于重置邮箱的提醒
|
||||
|
||||
var companyName = _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
|
||||
var companyName = isEn_US ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
|
||||
|
||||
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
|
||||
{
|
||||
var topicStr = string.Format(input.topicStr, companyName);
|
||||
|
||||
var htmlBodyStr = string.Format(ReplacePlatformName(ReplaceCompanyName(input.htmlBodyStr)) ,
|
||||
var htmlBodyStr = string.Format(CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr, workLanguage),
|
||||
|
||||
sysUserInfo.FullName
|
||||
sysUserInfo.FullName,
|
||||
_systemEmailConfig.PlatformName
|
||||
);
|
||||
|
||||
return (topicStr, htmlBodyStr);
|
||||
};
|
||||
|
||||
|
||||
await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.IdentityUser_ModifyPassword, messageToSend, emailConfigFunc);
|
||||
await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.IdentityUser_ModifyPassword, messageToSend, emailConfigFunc, workLanguage);
|
||||
|
||||
await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig);
|
||||
}
|
||||
@@ -948,6 +1002,10 @@ namespace IRaCIS.Core.Application.Service
|
||||
{
|
||||
var trialInfo = await _trialRepository.Where(t => t.Id == trialId).FirstOrDefaultAsync();
|
||||
|
||||
//设置工作语言
|
||||
var isEn_US = _userInfo.IsEn_Us;
|
||||
var workLanguage = isEn_US ? UserWorkLanguage.US : UserWorkLanguage.CN;
|
||||
|
||||
var messageToSend = new MimeMessage();
|
||||
//发件地址
|
||||
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
|
||||
@@ -956,14 +1014,14 @@ namespace IRaCIS.Core.Application.Service
|
||||
//主题
|
||||
//---[来自展影IRC] 关于重置邮箱的提醒
|
||||
|
||||
var companyName = _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
|
||||
var companyName = isEn_US ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
|
||||
|
||||
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
|
||||
{
|
||||
|
||||
var topicStr = string.Format(input.topicStr, companyName, trialInfo.ResearchProgramNo);
|
||||
|
||||
var htmlBodyStr = string.Format(ReplaceCompanyName(input.htmlBodyStr),
|
||||
var htmlBodyStr = string.Format(CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr, workLanguage),
|
||||
name,
|
||||
trialInfo.TrialCode,
|
||||
trialInfo.ResearchProgramNo
|
||||
@@ -974,14 +1032,20 @@ namespace IRaCIS.Core.Application.Service
|
||||
|
||||
|
||||
await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.SiteSurvey_CheckUser, messageToSend, emailConfigFunc);
|
||||
await SendEmailHelper.SendEmailAsync(messageToSend, trialInfo);
|
||||
await SendEmailHelper.SendTrialEmailAsync(messageToSend, trialInfo);
|
||||
}
|
||||
|
||||
public async Task SiteSuervyUpdateUser(Guid trialSiteId, string email, string name, string url)
|
||||
{
|
||||
var siteInfo = await _trialSiteRepository.Where(t => t.Id == trialSiteId).Include(x=>x.Trial).FirstOrDefaultAsync();
|
||||
var siteInfo = await _trialSiteRepository.Where(t => t.Id == trialSiteId).Include(x => x.Trial).FirstOrDefaultAsync();
|
||||
|
||||
var trialInfo = siteInfo.Trial;
|
||||
|
||||
|
||||
//设置工作语言
|
||||
var isEn_US = _userInfo.IsEn_Us;
|
||||
var workLanguage = isEn_US ? UserWorkLanguage.US : UserWorkLanguage.CN;
|
||||
|
||||
var messageToSend = new MimeMessage();
|
||||
//发件地址
|
||||
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
|
||||
@@ -990,14 +1054,14 @@ namespace IRaCIS.Core.Application.Service
|
||||
//主题
|
||||
//---[来自展影IRC] 关于重置邮箱的提醒
|
||||
|
||||
var companyName = _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
|
||||
var companyName = isEn_US ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
|
||||
|
||||
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
|
||||
{
|
||||
|
||||
var topicStr = string.Format(input.topicStr, companyName, trialInfo.ResearchProgramNo);
|
||||
|
||||
var htmlBodyStr = string.Format(ReplaceCompanyName(input.htmlBodyStr),
|
||||
var htmlBodyStr = string.Format(CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr, workLanguage),
|
||||
name,
|
||||
trialInfo.TrialCode,
|
||||
siteInfo.TrialSiteCode,
|
||||
@@ -1010,7 +1074,7 @@ namespace IRaCIS.Core.Application.Service
|
||||
|
||||
|
||||
await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.SiteSurvey_UpdateUser, messageToSend, emailConfigFunc);
|
||||
await SendEmailHelper.SendEmailAsync(messageToSend, trialInfo);
|
||||
await SendEmailHelper.SendTrialEmailAsync(messageToSend, trialInfo);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -131,6 +131,11 @@ namespace IRaCIS.Core.Application.Service
|
||||
CreateMap<FileUploadRecord, FileUploadRecordAddOrEdit>().ReverseMap();
|
||||
|
||||
|
||||
CreateMap<CommonUploadRecordAddOrEdit, CommonUploadRecord>().ReverseMap();
|
||||
|
||||
CreateMap<CommonUploadRecord, CommonUploadRecordDto>();
|
||||
|
||||
|
||||
CreateMap<UploadFileSyncRecord, UploadFileSyncRecordView>()
|
||||
.ForMember(d => d.FileName, u => u.MapFrom(s => s.FileUploadRecord.FileName))
|
||||
.ForMember(d => d.FileType, u => u.MapFrom(s => s.FileUploadRecord.FileType))
|
||||
|
||||
@@ -149,7 +149,7 @@ namespace IRaCIS.Application.Contracts
|
||||
|
||||
public bool? AcceptingNewTrial { get; set; }//是否接受新的项目
|
||||
public bool? ActivelyReading { get; set; }// 是否接受新的读片任务
|
||||
public int? Nation { get; set; }// 0-中国医生,2-美国医生,3-全部
|
||||
public DoctorNation? Nation { get; set; }// 0-中国医生,2-美国医生,3-全部
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -4,26 +4,10 @@
|
||||
// 生成时间 2025-03-27 06:13:33Z
|
||||
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
|
||||
//--------------------------------------------------------------------
|
||||
using IRaCIS.Core.Domain.Models;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using IRaCIS.Core.Application.Interfaces;
|
||||
using IRaCIS.Core.Application.ViewModel;
|
||||
using IRaCIS.Core.Infrastructure.Extention;
|
||||
using System.Threading.Tasks;
|
||||
using IRaCIS.Core.Infra.EFCore;
|
||||
using AutoMapper.Execution;
|
||||
using System.Linq;
|
||||
using IRaCIS.Core.Infrastructure;
|
||||
using DocumentFormat.OpenXml.Office2010.Excel;
|
||||
using MassTransit;
|
||||
using NPOI.POIFS.Properties;
|
||||
using Org.BouncyCastle.Crypto;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using IRaCIS.Core.Application.Contracts;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using static Microsoft.Extensions.Logging.EventSource.LoggingEventSource;
|
||||
using NPOI.SS.Formula.Functions;
|
||||
using EFCore.BulkExtensions;
|
||||
namespace IRaCIS.Core.Application.Service;
|
||||
|
||||
|
||||
|
||||
@@ -50,6 +50,7 @@ namespace IRaCIS.Core.Application.Contracts
|
||||
public bool? OffLine { get; set; }
|
||||
|
||||
public Guid? SystemDocumentId { get; set; }
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -79,14 +80,18 @@ namespace IRaCIS.Core.Application.Contracts
|
||||
|
||||
}
|
||||
|
||||
public class TrialSignDocView : UnionDocumentWithConfirmInfoView
|
||||
public class TriaAndSystemlSignDocView : UnionDocumentWithConfirmInfoView
|
||||
{
|
||||
public string TrialCode { get; set; }
|
||||
public string ResearchProgramNo { get; set; }
|
||||
|
||||
public string ExperimentName { get; set; }
|
||||
|
||||
public TrialType TrialType { get; set; }
|
||||
|
||||
public bool IsTestUser { get; set; }
|
||||
|
||||
public UserWorkLanguage UserWorkLanguage { get; set; }
|
||||
}
|
||||
|
||||
|
||||
@@ -205,7 +210,7 @@ namespace IRaCIS.Core.Application.Contracts
|
||||
|
||||
public DateTime? EndCreateTime { get; set; }
|
||||
|
||||
|
||||
public DocLanguageType? DocLanguageType { get; set; }
|
||||
}
|
||||
|
||||
public class GetNextUnSignDocumentInDto
|
||||
@@ -362,6 +367,10 @@ namespace IRaCIS.Core.Application.Contracts
|
||||
|
||||
public bool IsPublish { get; set; } = false;
|
||||
|
||||
public DocLanguageType DocLanguageType { get; set; }
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -62,42 +62,51 @@ namespace IRaCIS.Core.Application.Service
|
||||
|
||||
}).FirstNotNullAsync();
|
||||
|
||||
var isEn_us = _userInfo.IsEn_Us;
|
||||
//找到当前收件人语言
|
||||
var workLanguageList = _trialUserRoleRepository.Where(t => t.TrialId == taskInfo.TrialId && t.UserRole.UserTypeEnum == UserTypeEnum.ClinicalResearchCoordinator).Select(t => t.UserRole.IdentityUser.UserWorkLanguage).Distinct().ToList();
|
||||
|
||||
var resultStr = isEn_us ? (result == true ? "Yes" : "No") : (result == true ? "是" : "否");
|
||||
|
||||
if (isEnrollment == true)
|
||||
foreach (var workLanguage in workLanguageList)
|
||||
{
|
||||
Func<TrialEmailNoticeConfig, (string topicStr, string htmlBodyStr, bool isEn_us, Guid? onlyToUserId)> topicAndHtmlFunc = trialEmailConfig =>
|
||||
//设置工作语言
|
||||
var isEn_us = workLanguage == UserWorkLanguage.US;
|
||||
|
||||
var resultStr = isEn_us ? (result == true ? "Yes" : "No") : (result == true ? "是" : "否");
|
||||
|
||||
|
||||
|
||||
if (isEnrollment == true)
|
||||
{
|
||||
var topicStr = string.Format(isEn_us ? trialEmailConfig.EmailTopic : trialEmailConfig.EmailTopicCN, taskInfo.ResearchProgramNo, taskInfo.SubjectCode);
|
||||
Func<TrialEmailNoticeConfig, (string topicStr, string htmlBodyStr, bool isEn_us, Guid? onlyToUserId)> topicAndHtmlFunc = trialEmailConfig =>
|
||||
{
|
||||
var topicStr = string.Format(isEn_us ? trialEmailConfig.EmailTopic : trialEmailConfig.EmailTopicCN, taskInfo.ResearchProgramNo, taskInfo.SubjectCode);
|
||||
|
||||
var htmlBodyStr = string.Format(isEn_us ? trialEmailConfig.EmailHtmlContent : trialEmailConfig.EmailHtmlContentCN,
|
||||
EmailNamePlaceholder, taskInfo.ResearchProgramNo, taskInfo.SubjectCode, resultStr);
|
||||
var htmlBodyStr = string.Format(isEn_us ? trialEmailConfig.EmailHtmlContent : trialEmailConfig.EmailHtmlContentCN,
|
||||
EmailNamePlaceholder, taskInfo.ResearchProgramNo, taskInfo.SubjectCode, resultStr);
|
||||
|
||||
|
||||
return (topicStr, htmlBodyStr, isEn_us, null);
|
||||
};
|
||||
return (topicStr, htmlBodyStr, isEn_us, null);
|
||||
};
|
||||
|
||||
await SendTrialEmailAsync(taskInfo.TrialId, taskInfo.CriterionType, businessScenarioEnum, topicAndHtmlFunc, taskInfo.TrialSiteId);
|
||||
}
|
||||
else
|
||||
{
|
||||
Func<TrialEmailNoticeConfig, (string topicStr, string htmlBodyStr, bool isEn_us, Guid? onlyToUserId)> topicAndHtmlFunc = trialEmailConfig =>
|
||||
await SendTrialEmailAsync(taskInfo.TrialId, taskInfo.CriterionType, businessScenarioEnum, topicAndHtmlFunc, taskInfo.TrialSiteId);
|
||||
}
|
||||
else
|
||||
{
|
||||
var topicStr = string.Format(isEn_us ? trialEmailConfig.EmailTopic : trialEmailConfig.EmailTopicCN, taskInfo.ResearchProgramNo, taskInfo.SubjectCode, taskInfo.VisitName);
|
||||
Func<TrialEmailNoticeConfig, (string topicStr, string htmlBodyStr, bool isEn_us, Guid? onlyToUserId)> topicAndHtmlFunc = trialEmailConfig =>
|
||||
{
|
||||
var topicStr = string.Format(isEn_us ? trialEmailConfig.EmailTopic : trialEmailConfig.EmailTopicCN, taskInfo.ResearchProgramNo, taskInfo.SubjectCode, taskInfo.VisitName);
|
||||
|
||||
var htmlBodyStr = string.Format(isEn_us ? trialEmailConfig.EmailHtmlContent : trialEmailConfig.EmailHtmlContentCN,
|
||||
EmailNamePlaceholder, taskInfo.ResearchProgramNo, taskInfo.SubjectCode, taskInfo.VisitName, resultStr);
|
||||
var htmlBodyStr = string.Format(isEn_us ? trialEmailConfig.EmailHtmlContent : trialEmailConfig.EmailHtmlContentCN,
|
||||
EmailNamePlaceholder, taskInfo.ResearchProgramNo, taskInfo.SubjectCode, taskInfo.VisitName, resultStr);
|
||||
|
||||
|
||||
return (topicStr, htmlBodyStr, isEn_us, null);
|
||||
};
|
||||
return (topicStr, htmlBodyStr, isEn_us, null);
|
||||
};
|
||||
|
||||
await SendTrialEmailAsync(taskInfo.TrialId, taskInfo.CriterionType, businessScenarioEnum, topicAndHtmlFunc, taskInfo.TrialSiteId);
|
||||
}
|
||||
|
||||
await SendTrialEmailAsync(taskInfo.TrialId, taskInfo.CriterionType, businessScenarioEnum, topicAndHtmlFunc, taskInfo.TrialSiteId);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -133,8 +142,12 @@ namespace IRaCIS.Core.Application.Service
|
||||
|
||||
var (topicStr, htmlBodyStr, isEn_us, onlyToUserId) = topicAndHtmlFunc(trialEmailConfig);
|
||||
|
||||
//设置工作语言
|
||||
var workLanguage = isEn_us ? UserWorkLanguage.US : UserWorkLanguage.CN;
|
||||
|
||||
|
||||
//处理替换公司名
|
||||
htmlBodyStr = CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, htmlBodyStr);
|
||||
htmlBodyStr = CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, htmlBodyStr, workLanguage);
|
||||
|
||||
|
||||
sendEmailConfig.TopicDescription = topicStr;
|
||||
@@ -150,10 +163,10 @@ namespace IRaCIS.Core.Application.Service
|
||||
|
||||
var allUserTypeEnumList = toUserTypeEnumList.Union(copyUserTypeEnumList).Distinct().ToList();
|
||||
|
||||
var allUserList = await _trialUserRoleRepository.Where(t => t.TrialId == trialId && allUserTypeEnumList.Contains(t.UserRole.UserTypeEnum)).Select(t => new { t.UserId, t.UserRole.IdentityUser.EMail, t.UserRole.FullName, t.UserRole.UserTypeEnum }).ToListAsync();
|
||||
var allUserList = await _trialUserRoleRepository.Where(t => t.TrialId == trialId && allUserTypeEnumList.Contains(t.UserRole.UserTypeEnum)).Select(t => new { t.UserId, t.UserRole.IdentityUser.EMail, t.UserRole.FullName, t.UserRole.UserTypeEnum, t.UserRole.IdentityUser.UserWorkLanguage }).ToListAsync();
|
||||
|
||||
|
||||
var toUserList = allUserList.Where(t => toUserTypeEnumList.Contains(t.UserTypeEnum))
|
||||
//过滤当前语言
|
||||
var toUserList = allUserList.Where(t => toUserTypeEnumList.Contains(t.UserTypeEnum)).Where(t=>t.UserWorkLanguage==workLanguage)
|
||||
.ToList();
|
||||
|
||||
//收件人 有CRC CRA , CRC CRA的账户要按照中心发送
|
||||
@@ -191,11 +204,6 @@ namespace IRaCIS.Core.Application.Service
|
||||
sendEmailConfig.HtmlBodyStr = htmlBodyStr.Replace(EmailNamePlaceholder, string.Join(isEn_us ? ", " : "、", toUserList.Select(t => t.FullName).ToList()));
|
||||
}
|
||||
|
||||
if (toUserList.Count == 0)
|
||||
{
|
||||
//---没有收件人,无法发送邮件
|
||||
throw new BusinessValidationFailedException(_localizer["TrialEmailN_NoRecipient"]);
|
||||
}
|
||||
|
||||
|
||||
if (trialEmailConfig.FromEmail.Contains("@") && !string.IsNullOrEmpty(trialEmailConfig.FromEmail))
|
||||
@@ -235,20 +243,7 @@ namespace IRaCIS.Core.Application.Service
|
||||
}
|
||||
}
|
||||
|
||||
//邮件附件 这里是原格式发送,不是PDF
|
||||
|
||||
//if (trialEmailConfig.AttachCNPath != string.Empty && trialEmailConfig.AttachPath != string.Empty)
|
||||
//{
|
||||
// var phyPath = FileStoreHelper.GetPhysicalFilePath(_hostEnvironment, isEn_us? trialEmailConfig.AttachName: trialEmailConfig.AttachNameCN);
|
||||
|
||||
// //先预先生成了邮件,发送预先生成的邮件
|
||||
// sendEmailConfig.EmailAttachMentConfigList.Add(new EmailAttachMentConfig()
|
||||
// {
|
||||
// FileName = $"{attachPrefix}_{Path.GetFileName(_userInfo.IsEn_Us ? trialEmailConfig.AttachName : trialEmailConfig.AttachNameCN)}",
|
||||
|
||||
// FileStream = File.OpenRead(phyPath),
|
||||
// });
|
||||
//}
|
||||
|
||||
return (trialEmailConfig, sendEmailConfig);
|
||||
|
||||
|
||||
@@ -42,6 +42,7 @@ namespace IRaCIS.Core.Application.Services
|
||||
.WhereIf(inQuery.OffLine != null, t => t.OffLine == inQuery.OffLine)
|
||||
.WhereIf(inQuery.FileName != null, t => t.FileName == inQuery.FileName)
|
||||
.WhereIf(inQuery.FileFormat != null, t => t.FileFormat == inQuery.FileFormat)
|
||||
|
||||
.ProjectTo<SystemDocumentAttachmentView>(_mapper.ConfigurationProvider);
|
||||
|
||||
var pageList = await systemDocumentAttachmentQueryable.ToPagedListAsync(inQuery);
|
||||
@@ -95,6 +96,7 @@ namespace IRaCIS.Core.Application.Services
|
||||
.WhereIf(inQuery.EndCreateTime != null, t => t.CreateTime <= inQuery.EndCreateTime)
|
||||
.WhereIf(inQuery.UserTypeId != null, t => t.NeedConfirmedUserTypeList.Any(t => t.NeedConfirmUserTypeId == inQuery.UserTypeId))
|
||||
.WhereIf(inQuery.IsDeleted != null, t => t.IsDeleted == inQuery.IsDeleted)
|
||||
.WhereIf(inQuery.DocLanguageType != null, t => t.DocLanguageType == inQuery.DocLanguageType)
|
||||
.ProjectTo<SystemDocumentView>(_mapper.ConfigurationProvider, new { isEn_Us = _userInfo.IsEn_Us, userId = _userInfo.UserRoleId });
|
||||
|
||||
return await systemDocumentQueryable.ToPagedListAsync(inQuery);
|
||||
@@ -171,23 +173,16 @@ namespace IRaCIS.Core.Application.Services
|
||||
if (newUserTypeIds.Any()&& newUserTypeIds.Count()>0)
|
||||
{
|
||||
// 发送邮件给新增的角色
|
||||
Console.WriteLine("开始 发送系统文档更新邮件给新增角色");
|
||||
Console.WriteLine(string.Join(",", newUserTypeIds));
|
||||
Log.Logger.Warning("开始 发送系统文档更新邮件给新增角色");
|
||||
Log.Logger.Warning(string.Join(",", newUserTypeIds));
|
||||
|
||||
Task.Run(async () =>
|
||||
// 只发送给新增的角色
|
||||
await _mediatorScoped.Publish(new SystemDocumentPublishEvent
|
||||
{
|
||||
// 创建独立作用域
|
||||
using (var scope = serviceScopeFactory.CreateScope())
|
||||
{
|
||||
// 从新作用域解析服务
|
||||
var mediator = scope.ServiceProvider.GetRequiredService<IMediator>();
|
||||
// 只发送给新增的角色
|
||||
await mediator.Publish(new SystemDocumentPublishEvent {
|
||||
Ids = new List<Guid> { document.Id },
|
||||
NewUserTypeIds = newUserTypeIds
|
||||
});
|
||||
}
|
||||
Ids = new List<Guid> { document.Id },
|
||||
NewUserTypeIds = newUserTypeIds
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -212,23 +207,17 @@ namespace IRaCIS.Core.Application.Services
|
||||
IsDeleted = false,
|
||||
});
|
||||
|
||||
Console.WriteLine("开始 发布系统文档");
|
||||
Log.Logger.Warning("开始 发布系统文档");
|
||||
|
||||
await _mediatorScoped.Publish(new SystemDocumentPublishEvent { Ids = inDto.Ids });
|
||||
|
||||
Task.Run(async () =>
|
||||
{
|
||||
// 创建独立作用域
|
||||
using (var scope = serviceScopeFactory.CreateScope())
|
||||
{
|
||||
// 从新作用域解析服务
|
||||
var mediator = scope.ServiceProvider.GetRequiredService<IMediator>();
|
||||
await mediator.Publish(new SystemDocumentPublishEvent { Ids = inDto.Ids });
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
return ResponseOutput.Result(true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 下线系统文档
|
||||
/// </summary>
|
||||
@@ -286,9 +275,12 @@ namespace IRaCIS.Core.Application.Services
|
||||
{
|
||||
|
||||
var isInternal = _userInfo.IsZhiZhun;
|
||||
var workLanguage = _userInfo.UserWorkLanguage;
|
||||
|
||||
var query = from sysDoc in _systemDocumentRepository.Where(t=>t.IsPublish)
|
||||
.Where(t => t.NeedConfirmedUserTypeList.Any(t => t.NeedConfirmUserTypeId == _userInfo.UserTypeId))
|
||||
.WhereIf(workLanguage == UserWorkLanguage.CN, t => t.DocLanguageType == DocLanguageType.CN || t.DocLanguageType == DocLanguageType.CN_US)
|
||||
.WhereIf(workLanguage == UserWorkLanguage.US, t => t.DocLanguageType == DocLanguageType.US || t.DocLanguageType == DocLanguageType.CN_US)
|
||||
.Where(t => t.NeedConfirmedUserTypeList.Any(t => t.NeedConfirmUserTypeId == _userInfo.UserTypeId))
|
||||
.WhereIf(!string.IsNullOrEmpty(inQuery.Name), t => t.Name.Contains(inQuery.Name))
|
||||
//外部人员 只签署 外部需要签署的
|
||||
.WhereIf(isInternal == false, t => t.DocUserSignType == DocUserSignType.InnerAndOuter)
|
||||
|
||||
@@ -5,18 +5,10 @@
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
using IRaCIS.Core.Application.Contracts;
|
||||
using IRaCIS.Core.Application.Filter;
|
||||
using IRaCIS.Core.Application.MassTransit.Consumer;
|
||||
using IRaCIS.Core.Application.ViewModel;
|
||||
using IRaCIS.Core.Domain.Models;
|
||||
using IRaCIS.Core.Domain.Share;
|
||||
using MassTransit.Mediator;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using NPOI.SS.Formula.Functions;
|
||||
using System.Linq;
|
||||
using System.Linq.Dynamic.Core;
|
||||
|
||||
namespace IRaCIS.Core.Application.Services
|
||||
@@ -27,6 +19,7 @@ namespace IRaCIS.Core.Application.Services
|
||||
[ApiExplorerSettings(GroupName = "Trial")]
|
||||
public class TrialDocumentService(IRepository<TrialDocument> _trialDocumentRepository,
|
||||
IRepository<Trial> _trialRepository,
|
||||
IScopedMediator _mediatorScoped,
|
||||
IRepository<AuditRecord> _auditRecordRepository,
|
||||
IRepository<TrialDocumentAttachment> _trialDocumentAttachmentRepository,
|
||||
ISystemDocumentService _systemDocumentService,
|
||||
@@ -105,18 +98,11 @@ namespace IRaCIS.Core.Application.Services
|
||||
IsDeleted = false,
|
||||
}, false, true);
|
||||
await _trialDocumentRepository.SaveChangesAsync();
|
||||
Console.WriteLine("开始 发布项目文档");
|
||||
Serilog.Log.Logger.Warning("开始 发布项目文档");
|
||||
|
||||
Task.Run(async () =>
|
||||
{
|
||||
// 创建独立作用域
|
||||
using (var scope = serviceScopeFactory.CreateScope())
|
||||
{
|
||||
// 从新作用域解析服务
|
||||
var mediator = scope.ServiceProvider.GetRequiredService<IMediator>();
|
||||
await mediator.Publish(new TrialDocumentPublishEvent { Ids = inDto.Ids });
|
||||
}
|
||||
});
|
||||
await _mediatorScoped.Publish(new TrialDocumentPublishEvent { Ids = inDto.Ids });
|
||||
|
||||
|
||||
|
||||
|
||||
return ResponseOutput.Result(true);
|
||||
@@ -128,32 +114,20 @@ namespace IRaCIS.Core.Application.Services
|
||||
/// <returns></returns>
|
||||
public async Task<IResponseOutput> TestPush()
|
||||
{
|
||||
Task.Run(async () =>
|
||||
{
|
||||
// 创建独立作用域
|
||||
using (var scope = serviceScopeFactory.CreateScope())
|
||||
{
|
||||
// 从新作用域解析服务
|
||||
var mediator = scope.ServiceProvider.GetRequiredService<IMediator>();
|
||||
await mediator.Publish(new TrialDocumentErverDayEvent { });
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
await _mediatorScoped.Publish(new TrialDocumentErverDayEvent { });
|
||||
|
||||
return ResponseOutput.Result(true);
|
||||
}
|
||||
|
||||
|
||||
public async Task<IResponseOutput> TestSendEmail()
|
||||
{
|
||||
Task.Run(async () =>
|
||||
{
|
||||
// 创建独立作用域
|
||||
using (var scope = serviceScopeFactory.CreateScope())
|
||||
{
|
||||
// 从新作用域解析服务
|
||||
var mediator = scope.ServiceProvider.GetRequiredService<IMediator>();
|
||||
await mediator.Publish(new ImageQCRecurringEvent { TrialId = Guid.Parse("08de2254-5d7d-581a-0242-0a0001000000") });
|
||||
}
|
||||
});
|
||||
|
||||
await _mediatorScoped.Publish(new ImageQCRecurringEvent { TrialId = Guid.Parse("08de2254-5d7d-581a-0242-0a0001000000") });
|
||||
|
||||
|
||||
return ResponseOutput.Result(true);
|
||||
}
|
||||
|
||||
@@ -179,7 +153,7 @@ namespace IRaCIS.Core.Application.Services
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public async Task<PageOutput<TrialSignDocView>> GetTrialSignDocumentList(TrialDocQuery inQuery)
|
||||
public async Task<PageOutput<TriaAndSystemlSignDocView>> GetTrialSignDocumentList(TrialDocQuery inQuery)
|
||||
{
|
||||
var trialDocQueryable = from trialDoc in _trialDocumentRepository.Where(t => t.IsPublish)
|
||||
.WhereIf(inQuery.TrialId != null, t => t.TrialId == inQuery.TrialId)
|
||||
@@ -190,7 +164,7 @@ namespace IRaCIS.Core.Application.Services
|
||||
new { trialUser.IdentityUserId, TrialDocumentId = trialDoc.Id } equals new { IdentityUserId = confirm.ConfirmUserId, confirm.TrialDocumentId } into cc
|
||||
|
||||
from confirm in cc.DefaultIfEmpty()
|
||||
select new TrialSignDocView()
|
||||
select new TriaAndSystemlSignDocView()
|
||||
{
|
||||
TrialCode = trialDoc.Trial.TrialCode,
|
||||
ResearchProgramNo = trialDoc.Trial.ResearchProgramNo,
|
||||
@@ -351,12 +325,16 @@ namespace IRaCIS.Core.Application.Services
|
||||
|
||||
var isInternal = _userInfo.IsZhiZhun;
|
||||
|
||||
var workLanguage = _userInfo.UserWorkLanguage;
|
||||
|
||||
#region 统一用户修改
|
||||
|
||||
var systemDocQuery =
|
||||
from sysDoc in _systemDocumentRepository.Where(t => t.IsPublish).Where(t => t.NeedConfirmedUserTypeList.Any(c => c.NeedConfirmUserTypeId == _userInfo.UserTypeId))
|
||||
//外部人员 只签署 外部需要签署的
|
||||
.WhereIf(isInternal == false, t => t.DocUserSignType == DocUserSignType.InnerAndOuter)
|
||||
.WhereIf(workLanguage == UserWorkLanguage.CN, t => t.DocLanguageType == DocLanguageType.CN || t.DocLanguageType == DocLanguageType.CN_US)
|
||||
.WhereIf(workLanguage == UserWorkLanguage.US, t => t.DocLanguageType == DocLanguageType.US || t.DocLanguageType == DocLanguageType.CN_US)
|
||||
from trialUser in _trialIdentityUserRepository.AsQueryable(false)
|
||||
.Where(t => t.TrialId == inQuery.TrialId && t.IdentityUserId == _userInfo.IdentityUserId
|
||||
&& t.TrialUserRoleList.Any(t => sysDoc.NeedConfirmedUserTypeList.Any(c => c.NeedConfirmUserTypeId == t.UserRole.UserTypeId)))
|
||||
@@ -584,6 +562,7 @@ namespace IRaCIS.Core.Application.Services
|
||||
|
||||
|
||||
var needSignTrialDocCount = await _trialDocumentRepository.AsQueryable(true).Where(t => t.IsPublish)
|
||||
|
||||
.Where(t => t.TrialId == inQuery.TrialId && t.Trial.TrialStatusStr != StaticData.TrialState.TrialStopped)
|
||||
.Where(t => t.Trial.TrialIdentityUserList.Any(t => t.IdentityUserId == _userInfo.IdentityUserId && t.TrialUserRoleList.Any(t => t.UserRole.UserTypeId == _userInfo.UserTypeId)))
|
||||
.Where(t => t.IsDeleted == false && !t.TrialDocConfirmedUserList.Any(t => t.ConfirmUserId == _userInfo.IdentityUserId && t.ConfirmTime != null) && t.NeedConfirmedUserTypeList.Any(u => u.NeedConfirmUserTypeId == _userInfo.UserTypeId))
|
||||
@@ -591,7 +570,9 @@ namespace IRaCIS.Core.Application.Services
|
||||
|
||||
|
||||
var needSignSystemDocCount = await _systemDocumentRepository.AsQueryable(true).Where(t => t.IsPublish)
|
||||
.WhereIf(isInternal == false, t => t.DocUserSignType == DocUserSignType.InnerAndOuter)
|
||||
.WhereIf(workLanguage == UserWorkLanguage.CN, t => t.DocLanguageType == DocLanguageType.CN || t.DocLanguageType == DocLanguageType.CN_US)
|
||||
.WhereIf(workLanguage == UserWorkLanguage.US, t => t.DocLanguageType == DocLanguageType.US || t.DocLanguageType == DocLanguageType.CN_US)
|
||||
.WhereIf(isInternal == false, t => t.DocUserSignType == DocUserSignType.InnerAndOuter)
|
||||
.Where(t => t.IsDeleted == false && !t.SystemDocConfirmedUserList.Any(t => t.ConfirmUserId == _userInfo.IdentityUserId && t.ConfirmTime != null) && t.NeedConfirmedUserTypeList.Any(u => u.NeedConfirmUserTypeId == _userInfo.UserTypeId))
|
||||
.CountAsync();
|
||||
|
||||
@@ -969,7 +950,7 @@ namespace IRaCIS.Core.Application.Services
|
||||
IsSystemDoc = true,
|
||||
SysDocUserSignType = sysDoc.DocUserSignType,
|
||||
IsConfirmIdentityUserInner = identityUser.IsZhiZhun,
|
||||
IsPublish=sysDoc.IsPublish,
|
||||
IsPublish = sysDoc.IsPublish,
|
||||
Id = sysDoc.Id,
|
||||
CreateTime = sysDoc.CreateTime,
|
||||
IsDeleted = sysDoc.IsDeleted,
|
||||
@@ -1115,7 +1096,7 @@ namespace IRaCIS.Core.Application.Services
|
||||
return ResponseOutput.NotOk(_localizer["TrialD_DuplicateFileInProject"]);
|
||||
}
|
||||
|
||||
var document = (await _trialDocumentRepository.Where(t => t.Id == addOrEditTrialDocument.Id, true,true).Include(t => t.NeedConfirmedUserTypeList).FirstOrDefaultAsync()).IfNullThrowException();
|
||||
var document = (await _trialDocumentRepository.Where(t => t.Id == addOrEditTrialDocument.Id, true, true).Include(t => t.NeedConfirmedUserTypeList).FirstOrDefaultAsync()).IfNullThrowException();
|
||||
|
||||
bool beforeIsPublish = document.IsPublish;
|
||||
bool beforeIsDeleted = document.IsDeleted;
|
||||
@@ -1163,21 +1144,13 @@ namespace IRaCIS.Core.Application.Services
|
||||
Console.WriteLine("开始 发送项目文档更新邮件给新增角色");
|
||||
Console.WriteLine(string.Join(",", newUserTypeIds));
|
||||
|
||||
Task.Run(async () =>
|
||||
await _mediatorScoped.Publish(new TrialDocumentPublishEvent
|
||||
{
|
||||
// 创建独立作用域
|
||||
using (var scope = serviceScopeFactory.CreateScope())
|
||||
{
|
||||
// 从新作用域解析服务
|
||||
var mediator = scope.ServiceProvider.GetRequiredService<IMediator>();
|
||||
// 只发送给新增的角色
|
||||
await mediator.Publish(new TrialDocumentPublishEvent
|
||||
{
|
||||
Ids = new List<Guid> { document.Id },
|
||||
NewUserTypeIds = newUserTypeIds
|
||||
});
|
||||
}
|
||||
Ids = new List<Guid> { document.Id },
|
||||
NewUserTypeIds = newUserTypeIds
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
return ResponseOutput.Ok(document.Id.ToString());
|
||||
|
||||
@@ -24,6 +24,7 @@ using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Spire.Doc;
|
||||
using System.Linq.Dynamic.Core;
|
||||
using System.Runtime;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace IRaCIS.Core.Application.Service
|
||||
@@ -137,7 +138,7 @@ namespace IRaCIS.Core.Application.Service
|
||||
var isNeedSend = true;
|
||||
|
||||
//手动发送的时候,也有可能答案是是 此时是 这里不发送,发送已经生成的文件
|
||||
if (answer == "是" && isHandSend == null)
|
||||
if ((answer == "是" || answer == "Yes") && isHandSend == null)
|
||||
{
|
||||
isNeedSend = true;
|
||||
|
||||
@@ -194,7 +195,15 @@ namespace IRaCIS.Core.Application.Service
|
||||
/// <exception cref="BusinessValidationFailedException"></exception>
|
||||
public async Task<string> BaseBusinessScenarioSendEmailAsync(Guid visitTaskId, bool? isHandSend, EmailStoreSendMode emailStoreMode, string sendFileRelativePath)
|
||||
{
|
||||
var isEn_us = _userInfo.IsEn_Us;
|
||||
|
||||
//简单处理,找到该中心的语言 设置工作语言
|
||||
|
||||
var country = _visitTaskRepository.Where(t => t.Id == visitTaskId).Select(t => t.Subject.TrialSite.Country).First();
|
||||
|
||||
var isEn_us = country == StaticData.SiteCountry.US;
|
||||
|
||||
var workLanguage = isEn_us ? UserWorkLanguage.US : UserWorkLanguage.CN;
|
||||
|
||||
EmailBusinessScenario businessScenarioEnum = EmailBusinessScenario.None;
|
||||
|
||||
var enrollReplace = "";
|
||||
@@ -330,7 +339,7 @@ namespace IRaCIS.Core.Application.Service
|
||||
{
|
||||
var findItem = (await _dictionaryService.GetBasicDataSelect("Trial_Enroll_Report")).Where(t => t.Code == ((int)taskInfo.CriterionType).ToString()).FirstOrDefault();
|
||||
|
||||
enrollReplace = _userInfo.IsEn_Us ? findItem.Value : findItem.ValueCN;
|
||||
enrollReplace = isEn_us ? findItem.Value : findItem.ValueCN;
|
||||
|
||||
//如果其他阅片人已经做了,说明发送了入组确认报告,第二个人做完就不发送了
|
||||
|
||||
@@ -348,7 +357,7 @@ namespace IRaCIS.Core.Application.Service
|
||||
{
|
||||
bool isEnroll = false;
|
||||
|
||||
(answer, isEnroll) = await DealEnrollAnswer(visitTaskId, (Guid)taskInfo.SourceSubjectVisitId, taskInfo.CriterionType, taskInfo.TrialReadingCriterionId);
|
||||
(answer, isEnroll) = await DealEnrollAnswer(visitTaskId, (Guid)taskInfo.SourceSubjectVisitId, taskInfo.CriterionType, taskInfo.TrialReadingCriterionId, workLanguage);
|
||||
|
||||
isNeedSend = await DealMedicalReviewTasKGenerateAndIsSendAsync(taskInfo.TrialId, isHandSend, answer, new List<Guid>() { visitTaskId }, minUserIdList);
|
||||
}
|
||||
@@ -357,7 +366,7 @@ namespace IRaCIS.Core.Application.Service
|
||||
{
|
||||
var findItem = (await _dictionaryService.GetBasicDataSelect("Trial_PD_Report")).Where(t => t.Code == ((int)taskInfo.CriterionType).ToString()).FirstOrDefault();
|
||||
|
||||
PdReplace = _userInfo.IsEn_Us ? findItem.Value : findItem.ValueCN;
|
||||
PdReplace = isEn_us ? findItem.Value : findItem.ValueCN;
|
||||
|
||||
//有序
|
||||
|
||||
@@ -384,7 +393,7 @@ namespace IRaCIS.Core.Application.Service
|
||||
if (taskList.Count == 2 && taskList.Count(t => t.ReadingTaskState == ReadingTaskState.HaveSigned && t.ReadingCategory == ReadingCategory.Visit) == 2)
|
||||
{
|
||||
|
||||
answer = await TranslatePdStateAsync(visitTaskId, taskInfo.ReadingCategory, taskInfo.CriterionType);
|
||||
answer = await TranslatePdStateAsync(visitTaskId, taskInfo.ReadingCategory, taskInfo.CriterionType, workLanguage);
|
||||
|
||||
|
||||
isNeedSend = await DealMedicalReviewTasKGenerateAndIsSendAsync(taskInfo.TrialId, isHandSend, answer, taskList.Select(t => t.Id).ToList(), minUserIdList);
|
||||
@@ -394,7 +403,7 @@ namespace IRaCIS.Core.Application.Service
|
||||
else if (taskList.Count == 3 && taskList.Count(t => t.ReadingTaskState == ReadingTaskState.HaveSigned) == 3 && taskList.Where(t => t.ReadingCategory == ReadingCategory.Judge).Count() == 1)
|
||||
{
|
||||
var judgeResultId = taskList.Where(t => t.ReadingCategory == ReadingCategory.Judge).First()!.JudgeResultTaskId!.Value;
|
||||
answer = await TranslatePdStateAsync(judgeResultId, ReadingCategory.Visit, taskInfo.CriterionType);
|
||||
answer = await TranslatePdStateAsync(judgeResultId, ReadingCategory.Visit, taskInfo.CriterionType, workLanguage);
|
||||
|
||||
isNeedSend = await DealMedicalReviewTasKGenerateAndIsSendAsync(taskInfo.TrialId, isHandSend, answer, taskList.Where(t => t.ReadingCategory == ReadingCategory.Judge).Select(t => t.Id).ToList(), minUserIdList);
|
||||
|
||||
@@ -431,7 +440,7 @@ namespace IRaCIS.Core.Application.Service
|
||||
if (taskList.Count == 2 && taskList.Count(t => t.ReadingTaskState == ReadingTaskState.HaveSigned && t.ReadingCategory == ReadingCategory.Global) == 2)
|
||||
{
|
||||
|
||||
answer = await TranslatePdStateAsync(visitTaskId, taskInfo.ReadingCategory, taskInfo.CriterionType);
|
||||
answer = await TranslatePdStateAsync(visitTaskId, taskInfo.ReadingCategory, taskInfo.CriterionType, workLanguage);
|
||||
|
||||
isNeedSend = await DealMedicalReviewTasKGenerateAndIsSendAsync(taskInfo.TrialId, isHandSend, answer, taskList.Select(t => t.Id).ToList(), minUserIdList);
|
||||
}
|
||||
@@ -440,7 +449,7 @@ namespace IRaCIS.Core.Application.Service
|
||||
{
|
||||
|
||||
var judgeResultId = taskList.Where(t => t.ReadingCategory == ReadingCategory.Judge).First().JudgeResultTaskId!.Value;
|
||||
answer = await TranslatePdStateAsync(judgeResultId, ReadingCategory.Global, taskInfo.CriterionType);
|
||||
answer = await TranslatePdStateAsync(judgeResultId, ReadingCategory.Global, taskInfo.CriterionType, workLanguage);
|
||||
|
||||
isNeedSend = await DealMedicalReviewTasKGenerateAndIsSendAsync(taskInfo.TrialId, isHandSend, answer, taskList.Where(t => t.ReadingCategory == ReadingCategory.Judge).Select(t => t.Id).ToList(), minUserIdList);
|
||||
|
||||
@@ -613,7 +622,7 @@ namespace IRaCIS.Core.Application.Service
|
||||
//先预先生成了邮件,发送预先生成的邮件
|
||||
sendEmailConfig.EmailAttachMentConfigList.Add(new EmailAttachMentConfig()
|
||||
{
|
||||
FileName = $"{attachPrefix}_{Path.GetFileNameWithoutExtension(_userInfo.IsEn_Us ? trialEmailConfig.AttachName : trialEmailConfig!.AttachNameCN)}.pdf",
|
||||
FileName = $"{attachPrefix}_{Path.GetFileNameWithoutExtension(isEn_us ? trialEmailConfig.AttachName : trialEmailConfig!.AttachNameCN)}.pdf",
|
||||
|
||||
FileStream = File.OpenRead(phyPath),
|
||||
});
|
||||
@@ -639,7 +648,7 @@ namespace IRaCIS.Core.Application.Service
|
||||
|
||||
};
|
||||
|
||||
var path = FileStoreHelper.GetPhysicalFilePath(_hostEnvironment, _userInfo.IsEn_Us ? trialEmailConfig.AttachPath : trialEmailConfig.AttachCNPath);
|
||||
var path = FileStoreHelper.GetPhysicalFilePath(_hostEnvironment, isEn_us ? trialEmailConfig.AttachPath : trialEmailConfig.AttachCNPath);
|
||||
|
||||
//获取从word 到 PDF的路径
|
||||
var (serverFilePath, relativePath, fileRealName) = FileStoreHelper.GetSubjectEnrollConfirmOrPDEmailPath(_hostEnvironment, Path.GetFileName(path), taskInfo.TrialId, taskInfo.TrialSiteId, taskInfo.SubjectId, true);
|
||||
@@ -729,7 +738,7 @@ namespace IRaCIS.Core.Application.Service
|
||||
pdfMemoryStream.Seek(0, SeekOrigin.Begin);
|
||||
sendEmailConfig.EmailAttachMentConfigList.Add(new EmailAttachMentConfig()
|
||||
{
|
||||
FileName = $"{taskInfo.SubjectCode}_{Path.GetFileNameWithoutExtension(_userInfo.IsEn_Us ? trialEmailConfig.AttachName : trialEmailConfig.AttachNameCN)}.pdf",
|
||||
FileName = $"{taskInfo.SubjectCode}_{Path.GetFileNameWithoutExtension(isEn_us ? trialEmailConfig.AttachName : trialEmailConfig.AttachNameCN)}.pdf",
|
||||
|
||||
FileStream = pdfMemoryStream
|
||||
});
|
||||
@@ -1067,11 +1076,14 @@ namespace IRaCIS.Core.Application.Service
|
||||
/// <param name="subjectVisitId"></param>
|
||||
/// <param name="criterionType"></param>
|
||||
/// <param name="trialReadingCriterionId"></param>
|
||||
/// <param name="userWorkLanguage"></param>
|
||||
/// <returns></returns>
|
||||
private async Task<(string enrollAnswer, bool isEnroll)> DealEnrollAnswer(Guid visitTaskId, Guid subjectVisitId, CriterionType criterionType, Guid trialReadingCriterionId)
|
||||
private async Task<(string enrollAnswer, bool isEnroll)> DealEnrollAnswer(Guid visitTaskId, Guid subjectVisitId, CriterionType criterionType, Guid trialReadingCriterionId, UserWorkLanguage userWorkLanguage)
|
||||
{
|
||||
|
||||
var enrollAnswer = _userInfo.IsEn_Us ? "No" : "否";
|
||||
var isEn_us = userWorkLanguage == UserWorkLanguage.US;
|
||||
|
||||
var enrollAnswer = isEn_us ? "No" : "否";
|
||||
var isEnroll = false;
|
||||
|
||||
switch (criterionType)
|
||||
@@ -1088,7 +1100,7 @@ namespace IRaCIS.Core.Application.Service
|
||||
if (await _readingTableQuestionAnswerRepository.Where().AnyAsync(x => x.VisitTaskId == visitTaskId && x.Answer == TargetState.Exist.GetEnumInt() &&
|
||||
x.ReadingTableQuestionTrial.QuestionMark == QuestionMark.State && x.ReadingQuestionTrial.LesionType == LesionType.TargetLesion))
|
||||
{
|
||||
enrollAnswer = _userInfo.IsEn_Us ? "Yes" : "是";
|
||||
enrollAnswer = isEn_us ? "Yes" : "是";
|
||||
isEnroll = true;
|
||||
}
|
||||
|
||||
@@ -1102,7 +1114,7 @@ x.ReadingTableQuestionTrial.QuestionMark == QuestionMark.LesionNumber && x.Readi
|
||||
bool exists = list.Any(s => int.TryParse(s, out var n) && n >= 1);
|
||||
if (exists)
|
||||
{
|
||||
enrollAnswer = _userInfo.IsEn_Us ? "Yes" : "是";
|
||||
enrollAnswer = isEn_us ? "Yes" : "是";
|
||||
isEnroll = true;
|
||||
}
|
||||
|
||||
@@ -1168,9 +1180,10 @@ x.ReadingTableQuestionTrial.QuestionMark == QuestionMark.LesionNumber && x.Readi
|
||||
/// <param name="readingCategory"> 任务类型</param>
|
||||
/// <param name="criterionType">标准类型</param>
|
||||
/// <param name="IsGlobalGenerate"> 是否是全局产生(区分裁判任务)</param>
|
||||
/// <param name="userWorkLanguage"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="BusinessValidationFailedException"></exception>
|
||||
private async Task<string> TranslatePdStateAsync(Guid visitTaskId, ReadingCategory readingCategory, CriterionType criterionType, bool? IsGlobalGenerate = null)
|
||||
private async Task<string> TranslatePdStateAsync(Guid visitTaskId, ReadingCategory readingCategory, CriterionType criterionType, UserWorkLanguage userWorkLanguage, bool? IsGlobalGenerate = null)
|
||||
{
|
||||
|
||||
var answer = string.Empty;
|
||||
@@ -1361,6 +1374,7 @@ x.ReadingTableQuestionTrial.QuestionMark == QuestionMark.LesionNumber && x.Readi
|
||||
throw new BusinessValidationFailedException(_localizer["TrialEmailN_InvalidTaskTypeForEmailSending"]);
|
||||
}
|
||||
|
||||
var isEn_us = userWorkLanguage == UserWorkLanguage.US;
|
||||
|
||||
switch (criterionType)
|
||||
{
|
||||
@@ -1372,11 +1386,11 @@ x.ReadingTableQuestionTrial.QuestionMark == QuestionMark.LesionNumber && x.Readi
|
||||
|
||||
if (answer == OverallAssessment.PD.GetEnumInt())
|
||||
{
|
||||
answer = _userInfo.IsEn_Us ? "Yes" : "是";
|
||||
answer = isEn_us ? "Yes" : "是";
|
||||
}
|
||||
else
|
||||
{
|
||||
answer = _userInfo.IsEn_Us ? "No" : "否";
|
||||
answer = isEn_us ? "No" : "否";
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -1384,11 +1398,11 @@ x.ReadingTableQuestionTrial.QuestionMark == QuestionMark.LesionNumber && x.Readi
|
||||
|
||||
if (answer == OverallAssessment.iCPD.GetEnumInt())
|
||||
{
|
||||
answer = _userInfo.IsEn_Us ? "Yes" : "是";
|
||||
answer = isEn_us ? "Yes" : "是";
|
||||
}
|
||||
else
|
||||
{
|
||||
answer = _userInfo.IsEn_Us ? "No" : "否";
|
||||
answer = isEn_us ? "No" : "否";
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -1396,11 +1410,11 @@ x.ReadingTableQuestionTrial.QuestionMark == QuestionMark.LesionNumber && x.Readi
|
||||
|
||||
if (answer == CTMRIOverallAssessment.PD.GetEnumInt())
|
||||
{
|
||||
answer = _userInfo.IsEn_Us ? "Yes" : "是";
|
||||
answer = isEn_us ? "Yes" : "是";
|
||||
}
|
||||
else
|
||||
{
|
||||
answer = _userInfo.IsEn_Us ? "No" : "否";
|
||||
answer = isEn_us ? "No" : "否";
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -1408,11 +1422,11 @@ x.ReadingTableQuestionTrial.QuestionMark == QuestionMark.LesionNumber && x.Readi
|
||||
|
||||
if (answer == ImagingOverallAssessment_Lugano.PMDPD.GetEnumInt())
|
||||
{
|
||||
answer = _userInfo.IsEn_Us ? "Yes" : "是";
|
||||
answer = isEn_us ? "Yes" : "是";
|
||||
}
|
||||
else
|
||||
{
|
||||
answer = _userInfo.IsEn_Us ? "No" : "否";
|
||||
answer = isEn_us ? "No" : "否";
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -1423,11 +1437,11 @@ x.ReadingTableQuestionTrial.QuestionMark == QuestionMark.LesionNumber && x.Readi
|
||||
|
||||
if (answer == VisitTumorEvaluation.PD.GetEnumInt())
|
||||
{
|
||||
answer = _userInfo.IsEn_Us ? "Yes" : "是";
|
||||
answer = isEn_us ? "Yes" : "是";
|
||||
}
|
||||
else
|
||||
{
|
||||
answer = _userInfo.IsEn_Us ? "No" : "否";
|
||||
answer = isEn_us ? "No" : "否";
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1537,14 +1551,23 @@ x.ReadingTableQuestionTrial.QuestionMark == QuestionMark.LesionNumber && x.Readi
|
||||
.WhereIf(inQuery.IsReturnRequired != null, t => t.IsReturnRequired == inQuery.IsReturnRequired)
|
||||
.WhereIf(inQuery.IsEnable != null, t => t.IsEnable == inQuery.IsEnable)
|
||||
.WhereIf(inQuery.IsDistinguishCriteria != null, t => t.IsDistinguishCriteria == inQuery.IsDistinguishCriteria)
|
||||
.WhereIf(inQuery.IsDistinguishCriteria == true && trialConfig.IsEnrollementQualificationConfirm == true && trialConfig.IsPDProgressView == false, t => t.IsDistinguishCriteria == true && t.BusinessScenarioEnum == EmailBusinessScenario.EnrollConfirmed)
|
||||
.WhereIf(inQuery.IsDistinguishCriteria == true && trialConfig.IsEnrollementQualificationConfirm == false && trialConfig.IsPDProgressView == true, t => t.IsDistinguishCriteria == true && t.BusinessScenarioEnum == EmailBusinessScenario.PDConfirmed)
|
||||
.WhereIf(inQuery.IsDistinguishCriteria == true && trialConfig.IsEnrollementQualificationConfirm == true && trialConfig.IsPDProgressView == true, t => t.IsDistinguishCriteria == true)
|
||||
.WhereIf(inQuery.IsDistinguishCriteria == true && trialConfig.IsEnrollementQualificationConfirm == false && trialConfig.IsPDProgressView == false, t => t.IsDistinguishCriteria == true && (t.BusinessScenarioEnum != EmailBusinessScenario.EnrollConfirmed && t.BusinessScenarioEnum != EmailBusinessScenario.PDConfirmed))
|
||||
|
||||
.WhereIf(inQuery.BusinessModuleEnum != null, t => t.BusinessModuleEnum == inQuery.BusinessModuleEnum)
|
||||
.WhereIf(inQuery.EmailUrgentEnum != null, t => t.EmailUrgentEnum == inQuery.EmailUrgentEnum)
|
||||
.WhereIf(inQuery.ToUserType != null, t => t.EmailNoticeUserTypeList.Any(t => t.UserType == inQuery.ToUserType && t.EmailUserType == EmailUserType.To))
|
||||
.WhereIf(inQuery.CopyUserType != null, t => t.EmailNoticeUserTypeList.Any(t => t.UserType == inQuery.CopyUserType && t.EmailUserType == EmailUserType.Copy))
|
||||
.WhereIf(trialConfig.IsEnrollementQualificationConfirm == false, t => t.BusinessModuleEnum != BusinessModule.EligibilityVerification)
|
||||
.WhereIf(trialConfig.IsPDProgressView == false, t => t.BusinessModuleEnum != BusinessModule.PDVerification)
|
||||
|
||||
.WhereIf(trialConfig.IsEnrollementQualificationConfirm == false && trialConfig.IsPDProgressView == true, t => t.BusinessModuleEnum != BusinessModule.EligibilityVerification)
|
||||
.WhereIf(trialConfig.IsEnrollementQualificationConfirm == true && trialConfig.IsPDProgressView == false, t => t.BusinessModuleEnum != BusinessModule.PDVerification)
|
||||
|
||||
.WhereIf(trialConfig.IsPDProgressView == false && trialConfig.IsEnrollementQualificationConfirm == false, t => t.BusinessModuleEnum != BusinessModule.PDVerification
|
||||
&& t.BusinessModuleEnum != BusinessModule.EligibilityVerification)
|
||||
&& t.BusinessModuleEnum != BusinessModule.EligibilityVerification && t.BusinessModuleEnum != BusinessModule.Eligibility_PDVerification)
|
||||
|
||||
|
||||
.ProjectTo<TrialSelectEmailNoticeConfigView>(_mapper.ConfigurationProvider, new { trialId = inQuery.TrialId });
|
||||
|
||||
return await emailNoticeConfigQueryable.ToPagedListAsync(inQuery);
|
||||
|
||||
@@ -105,7 +105,7 @@
|
||||
public string Reviewer { get; set; } = String.Empty;
|
||||
public DateTime BeginMonth { get; set; }
|
||||
public DateTime EndMonth { get; set; }
|
||||
public int? Nation { get; set; }
|
||||
public DoctorNation? Nation { get; set; }
|
||||
}
|
||||
public class MonthlyPaymentDTO
|
||||
{
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
{
|
||||
public DateTime StatisticsDate { get; set; }
|
||||
public string KeyWord { get; set; } = String.Empty;
|
||||
public int? Nation { get; set; }
|
||||
public DoctorNation? Nation { get; set; }
|
||||
}
|
||||
|
||||
public class MonthlyPaymentDetailQuery
|
||||
@@ -162,7 +162,7 @@
|
||||
public DateTime BeginDate { get; set; }
|
||||
public DateTime EndDate { get; set; }
|
||||
|
||||
public int? Nation { get; set; }
|
||||
public DoctorNation? Nation { get; set; }
|
||||
}
|
||||
|
||||
public class TrialAnalysisQueryDTO
|
||||
|
||||
@@ -5,6 +5,8 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc.DTO
|
||||
{
|
||||
public class SubjectImageUploadDTO
|
||||
{
|
||||
public bool? IsIRImageDownloaded { get; set; }
|
||||
|
||||
public Guid VisitTaskId { get; set; }
|
||||
|
||||
public Guid TrialSiteId { get; set; }
|
||||
|
||||
@@ -676,6 +676,7 @@ namespace IRaCIS.Core.Application.Contracts
|
||||
|
||||
public class TaskNoneDicomStudyDTO : NoneDicomStudyBasicInfo
|
||||
{
|
||||
public bool? IsIRImageDownloaded { get; set; }
|
||||
public Guid VisitTaskId { get; set; }
|
||||
|
||||
public int UploadedFileCount { get; set; }
|
||||
@@ -749,6 +750,17 @@ namespace IRaCIS.Core.Application.Contracts
|
||||
public long? FileSize { get; set; }
|
||||
}
|
||||
|
||||
public class DownloadFileDto
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
|
||||
public string Path { get; set; }
|
||||
|
||||
public string FileName { get; set; }
|
||||
|
||||
public string FileType { get; set; }
|
||||
}
|
||||
|
||||
public class DownloadNoneDicomStudyDto
|
||||
{
|
||||
public string Modality { get; set; }
|
||||
@@ -776,6 +788,9 @@ namespace IRaCIS.Core.Application.Contracts
|
||||
public List<Guid> DicomStudyIdList { get; set; }
|
||||
|
||||
public List<Guid> NoneDicomStudyIdList { get; set; }
|
||||
|
||||
// true 导出阅片,null 就是所有影像
|
||||
public bool? IsExportReading { get; set; }
|
||||
}
|
||||
|
||||
public class IRReadingDownloadQuery : SortInput
|
||||
@@ -846,9 +861,13 @@ namespace IRaCIS.Core.Application.Contracts
|
||||
public List<TrialKeyPicturePath> QuestionMarkPictureList { get; set; }
|
||||
|
||||
public List<TrialKeyPicturePath> TableQuestionRowPictureList { get; set; }
|
||||
|
||||
public List<TrialKeyPicturePath> SegmentationFileList { get; set; }
|
||||
}
|
||||
public class TrialKeyPicturePath
|
||||
{
|
||||
public string SegmentationName { get; set; }
|
||||
|
||||
public string PicturePath { get; set; }
|
||||
|
||||
public string OtherPicturePath { get; set; }
|
||||
@@ -1055,6 +1074,13 @@ namespace IRaCIS.Core.Application.Contracts
|
||||
public string? Name { get; set; }
|
||||
}
|
||||
|
||||
public class DownloadImageSuccessCommand
|
||||
{
|
||||
public Guid TrialImageDownloadId { get; set; }
|
||||
|
||||
public List<Guid> VisitTaskIdList { get; set; }
|
||||
}
|
||||
|
||||
public class SubjectVisitTaskInfo
|
||||
{
|
||||
public Guid SubjectVisitId { get; set; }
|
||||
@@ -1075,6 +1101,8 @@ namespace IRaCIS.Core.Application.Contracts
|
||||
|
||||
public bool? IsUrgent { get; set; }
|
||||
|
||||
public int? State { get; set; }
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1104,6 +1132,10 @@ namespace IRaCIS.Core.Application.Contracts
|
||||
public int? NoneDicomStudyCount { get; set; }
|
||||
|
||||
public int? MarkNoneDicomStudyCount { get; set; }
|
||||
|
||||
public DateTime? LatestDownloadTime { get; set; }
|
||||
|
||||
public DateTime? LatestUploadTime { get; set; }
|
||||
}
|
||||
|
||||
public class SubjectVisitMarkStudyDto
|
||||
@@ -1157,6 +1189,20 @@ namespace IRaCIS.Core.Application.Contracts
|
||||
public List<MaskRegion> MaskRegionList { get; set; }
|
||||
|
||||
|
||||
}
|
||||
public class NoneDicomStudyMaskImageCommand
|
||||
{
|
||||
public Guid? NodicomStudyId { get; set; }
|
||||
public List<Guid>? NoneDicomStudyFileIdList { get; set; }
|
||||
public List<MaskRegion> MaskRegionList { get; set; }
|
||||
}
|
||||
|
||||
public class NoneDicomStudyUndoMaskImageCommand
|
||||
{
|
||||
public Guid? NodicomStudyId { get; set; }
|
||||
|
||||
public List<Guid>? NoneDicomStudyFileIdList { get; set; }
|
||||
|
||||
}
|
||||
|
||||
public class StudyUndoMaskImageCommand
|
||||
|
||||
@@ -1,31 +1,18 @@
|
||||
using DocumentFormat.OpenXml.EMMA;
|
||||
using FellowOakDicom;
|
||||
using FellowOakDicom.Media;
|
||||
using FellowOakDicom;
|
||||
using IRaCIS.Core.Application.Contracts;
|
||||
using IRaCIS.Core.Application.Contracts.Dicom.DTO;
|
||||
using IRaCIS.Core.Application.Filter;
|
||||
using IRaCIS.Core.Application.Helper;
|
||||
using IRaCIS.Core.Application.Service.ImageAndDoc.DTO;
|
||||
using IRaCIS.Core.Application.Service.Reading.Dto;
|
||||
using IRaCIS.Core.Domain.Models;
|
||||
using IRaCIS.Core.Domain.Share;
|
||||
using IRaCIS.Core.Infra.EFCore.Common;
|
||||
using IRaCIS.Core.Infrastructure;
|
||||
using MassTransit;
|
||||
using MassTransit.Initializers;
|
||||
using MathNet.Numerics;
|
||||
using Medallion.Threading;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using NetTopologySuite.Mathematics;
|
||||
using Newtonsoft.Json;
|
||||
using NPOI.SS.Formula.Functions;
|
||||
using System.Data;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Web;
|
||||
using ZiggyCreatures.Caching.Fusion;
|
||||
|
||||
namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||
{
|
||||
@@ -71,8 +58,9 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||
{
|
||||
//subject 随机阅片 或者无序 有上传 才处理任务编号
|
||||
if (_visitTaskRepository.Any(t => t.SubjectId == subjectId && t.TrialReadingCriterionId == trialReadingCriterionId &&
|
||||
(t.TrialReadingCriterion.IsReadingTaskViewInOrder == ReadingOrder.SubjectRandom ||
|
||||
(t.TrialReadingCriterion.IsReadingTaskViewInOrder == ReadingOrder.Random && t.TrialReadingCriterion.ImageDownloadEnum != ReadingImageDownload.None))))
|
||||
(t.TrialReadingCriterion.IsReadingTaskViewInOrder == ReadingOrder.SubjectRandom
|
||||
//||(t.TrialReadingCriterion.IsReadingTaskViewInOrder == ReadingOrder.Random && t.TrialReadingCriterion.ImageDownloadEnum != ReadingImageDownload.None)
|
||||
)))
|
||||
{
|
||||
//找到 非一致性分析,未签名,状态正常的 并且任务名称是TimePoint的 任务
|
||||
var needDealTaskList = await _visitTaskRepository.Where(t => t.SubjectId == subjectId && t.TrialReadingCriterionId == trialReadingCriterionId && t.IsAnalysisCreate == false && t.DoctorUserId == _userInfo.UserRoleId
|
||||
@@ -131,6 +119,12 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||
|
||||
var subjectCode = string.Empty;
|
||||
var subjectId = inQuery.SubjectId;
|
||||
bool? isIRImageDownloaded = null;
|
||||
|
||||
if (inQuery.VisitTaskId != null)
|
||||
{
|
||||
isIRImageDownloaded = _visitTaskRepository.Where(t => t.Id == inQuery.VisitTaskId).Select(t => t.IsIRImageDownloaded).FirstOrDefault();
|
||||
}
|
||||
|
||||
if (criterionInfo.IsReadingTaskViewInOrder == ReadingOrder.Random)
|
||||
{
|
||||
@@ -224,7 +218,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||
|
||||
var SVlist = await querySV.ToListAsync();
|
||||
|
||||
return ResponseOutput.Ok(SVlist, new { TrialModality = criterionInfo.Modalitys });
|
||||
return ResponseOutput.Ok(SVlist, new { TrialModality = criterionInfo.Modalitys, IsReadingTaskViewInOrder = criterionInfo.IsReadingTaskViewInOrder });
|
||||
|
||||
}
|
||||
else
|
||||
@@ -240,6 +234,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||
.Select(u => new SubjectImageUploadDTO()
|
||||
{
|
||||
VisitTaskId = u.Id,
|
||||
IsIRImageDownloaded = u.IsIRImageDownloaded,
|
||||
|
||||
SubejctId = u.SubjectId,
|
||||
|
||||
@@ -337,7 +332,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||
}
|
||||
|
||||
|
||||
return ResponseOutput.Ok(list, new { TrialModality = criterionInfo.Modalitys });
|
||||
return ResponseOutput.Ok(list, new { TrialModality = criterionInfo.Modalitys, IsReadingTaskViewInOrder = criterionInfo.IsReadingTaskViewInOrder, IsIRImageDownloaded = isIRImageDownloaded });
|
||||
}
|
||||
|
||||
|
||||
@@ -714,9 +709,12 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||
|
||||
TaskSeries dicomSeries = await _taskSeriesRepository.FirstOrDefaultAsync(t => t.Id == seriesId);
|
||||
|
||||
var isNewSeries = false;
|
||||
//判断重复
|
||||
if (dicomSeries == null)
|
||||
{
|
||||
isNewSeries = true;
|
||||
|
||||
var series = _mapper.Map<TaskSeries>(seriesItem);
|
||||
|
||||
series.Id = seriesId;
|
||||
@@ -761,7 +759,10 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||
|
||||
await _taskInstanceRepository.AddAsync(insntance);
|
||||
|
||||
dicomSeries.InstanceCount++;
|
||||
if (isNewSeries == false)
|
||||
{
|
||||
dicomSeries.InstanceCount++;
|
||||
}
|
||||
findStudy.InstanceCount++;
|
||||
}
|
||||
|
||||
@@ -911,6 +912,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||
var subjectCode = inQuery.SubjectCode;
|
||||
var subjectId = inQuery.SubjectId;
|
||||
var doctorUserId = _userInfo.UserRoleId;
|
||||
bool? isIRImageDownloaded = null;
|
||||
|
||||
if (inQuery.VisitTaskId != null)
|
||||
{
|
||||
@@ -922,18 +924,20 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||
SubjectCode = t.IsAnalysisCreate ? t.BlindSubjectCode : t.Subject.Code,
|
||||
SubjectId = t.SubjectId,
|
||||
t.DoctorUserId,
|
||||
t.IsAnalysisCreate
|
||||
t.IsAnalysisCreate,
|
||||
t.IsIRImageDownloaded,
|
||||
}).FirstNotNullAsync();
|
||||
|
||||
subjectId = taskInfo.SubjectId;
|
||||
subjectCode = taskInfo.SubjectCode;
|
||||
doctorUserId = (Guid)taskInfo.DoctorUserId!;
|
||||
isIRImageDownloaded = taskInfo.IsIRImageDownloaded;
|
||||
}
|
||||
|
||||
var info = await _readingQuestionCriterionTrialRepository.Where(t => t.Id == inQuery.TrialReadingCriterionId)
|
||||
.Select(t => new { t.IsImageFilter, t.CriterionType, t.TrialId, t.CriterionModalitys, t.IsReadingTaskViewInOrder }).FirstNotNullAsync();
|
||||
|
||||
var config = await _subjectRepository.Where(t => t.Id == subjectId).Select(t => new { t.Trial.ImageFormatList, t.Trial.StudyNameList, t.Trial.IsShowStudyName }).FirstOrDefaultAsync();
|
||||
var config = await _subjectRepository.Where(t => t.Id == subjectId).Select(t => new { t.Trial.ImageFormatList, t.Trial.StudyNameList, t.Trial.IsShowStudyName, IsIRImageDownloaded = isIRImageDownloaded }).FirstOrDefaultAsync();
|
||||
|
||||
|
||||
//靶段标注上传,查看访视级别,上传绑定访视级别
|
||||
@@ -998,7 +1002,8 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||
|
||||
|
||||
|
||||
var list = _noneDicomStudyReposiotry.Where(t => t.SubjectId == subjectId && t.SubjectVisit.CheckState == CheckStateEnum.CVPassed)
|
||||
var list = _noneDicomStudyReposiotry.Where(t => t.IsReading)
|
||||
.Where(t => t.SubjectId == subjectId && t.SubjectVisit.CheckState == CheckStateEnum.CVPassed)
|
||||
.WhereIf(inQuery.SubjectVisitId != null, t => t.SubjectVisitId == inQuery.SubjectVisitId)
|
||||
//.WhereIf(info.IsImageFilter, t => ("|" + info.CriterionModalitys + "|").Contains("|" + t.Modality + "|"))
|
||||
.Select(u => new TaskNoneDicomStudyDTO()
|
||||
@@ -1027,12 +1032,13 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||
|
||||
ReadingFileCount = u.NoneDicomFileList.Where(t => t.IsReading).Count(),
|
||||
|
||||
}).ToList();
|
||||
}).OrderBy(t => t.VisitName).ThenBy(t => t.Modality).ToList();
|
||||
|
||||
var noneDicomStudyIdList = list.Select(t => t.Id).ToList();
|
||||
var noneDicomStudyIdList = list.Where(t => !(t.Modality != "IVUS" && t.ReadingFileCount == 0)).Select(t => t.Id).ToList();
|
||||
|
||||
|
||||
var noneDicomStudyList = _noneDicomStudyFileReposiotry.Where(t => t.ImageLabelNoneDicomStudyId != null)
|
||||
var noneDicomStudyList = _noneDicomStudyFileReposiotry.Where(t => t.IsReading)
|
||||
.Where(t => t.ImageLabelNoneDicomStudyId != null)
|
||||
.Where(t => noneDicomStudyIdList.Contains((Guid)t.ImageLabelNoneDicomStudyId!))
|
||||
.Select(u => new NoneDicomFileInfo
|
||||
{
|
||||
@@ -1059,7 +1065,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||
&& t.SourceSubjectVisit.CheckState == CheckStateEnum.CVPassed && t.DoctorUserId == doctorUserId && t.TaskState == TaskState.Effect)
|
||||
//满足 有序,或者随机只看到当前任务的dicom 非dicom检查
|
||||
.WhereIf(info.IsReadingTaskViewInOrder != ReadingOrder.SubjectRandom && inQuery.VisitTaskId != null, t => t.Id == inQuery.VisitTaskId)
|
||||
join ns in _noneDicomStudyReposiotry.Where(t => t.SubjectId == subjectId).WhereIf(info.IsImageFilter, t => ("|" + info.CriterionModalitys + "|").Contains("|" + t.Modality + "|"))
|
||||
join ns in _noneDicomStudyReposiotry.Where(t => t.SubjectId == subjectId).Where(t => t.IsReading).WhereIf(info.IsImageFilter, t => ("|" + info.CriterionModalitys + "|").Contains("|" + t.Modality + "|"))
|
||||
on u.SourceSubjectVisitId equals ns.SubjectVisitId
|
||||
|
||||
select new TaskNoneDicomStudyDTO()
|
||||
@@ -1071,6 +1077,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||
ReadingTaskState = u.ReadingTaskState,
|
||||
SourceSubjectVisitId = u.SourceSubjectVisitId,
|
||||
VisitTaskId = u.Id,
|
||||
IsIRImageDownloaded = u.IsIRImageDownloaded,
|
||||
|
||||
Id = ns.Id,
|
||||
Description = ns.Description,
|
||||
@@ -1141,6 +1148,8 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||
var isQueryDicom = inQuery.DicomStudyIdList.Count > 0;
|
||||
var isQueryNoneDicom = inQuery.NoneDicomStudyIdList.Count > 0;
|
||||
|
||||
var isExportReading = inQuery.IsExportReading == true;
|
||||
|
||||
var imageType = (isQueryDicom && isQueryNoneDicom) ? ImageType.DicomAndNoneDicom : (isQueryDicom ? ImageType.Dicom : ImageType.NoneDicom);
|
||||
|
||||
var dirDic = new Dictionary<string, string>();
|
||||
@@ -1150,11 +1159,12 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||
|
||||
//有传输语法值的导出 才生成DIR
|
||||
//if (_subjectVisitRepository.Where(t => t.Id == inQuery.SubjectVisitId).SelectMany(t => t.StudyList.SelectMany(t => t.InstanceList)).All(c => c.TransferSytaxUID != string.Empty))
|
||||
if (!_instanceRepository.Where(t => inQuery.SubjectVisitId == t.SubjectVisitId).Any(c => c.TransferSytaxUID == string.Empty))
|
||||
if (!_instanceRepository.Where(t => isExportReading ? (t.IsReading && t.DicomSerie.IsReading) : true)
|
||||
.Where(t => inQuery.SubjectVisitId == t.SubjectVisitId).Any(c => c.TransferSytaxUID == string.Empty))
|
||||
{
|
||||
var list = _subjectVisitRepository.Where(t => t.Id == inQuery.SubjectVisitId).SelectMany(t => t.StudyList)
|
||||
.Where(t => isQueryDicom ? inQuery.DicomStudyIdList.Contains(t.Id) : false)
|
||||
.SelectMany(t => t.InstanceList)
|
||||
.SelectMany(t => t.InstanceList.Where(t => isExportReading ? (t.IsReading && t.DicomSerie.IsReading) : true))
|
||||
.Select(t => new StudyDIRInfo()
|
||||
{
|
||||
|
||||
@@ -1235,11 +1245,11 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||
StudyInstanceUid = u.StudyInstanceUid,
|
||||
StudyDIRPath = u.StudyDIRPath,
|
||||
|
||||
SeriesList = u.SeriesList.Select(z => new DownloadDicomSeriesDto()
|
||||
SeriesList = u.SeriesList.Where(t => isExportReading ? t.IsReading : true).Select(z => new DownloadDicomSeriesDto()
|
||||
{
|
||||
Modality = z.Modality,
|
||||
|
||||
InstanceList = z.DicomInstanceList.Select(k => new DownloadDicomInstanceDto()
|
||||
InstanceList = z.DicomInstanceList.Where(t => isExportReading ? t.IsReading : true).Select(k => new DownloadDicomInstanceDto()
|
||||
{
|
||||
IsEncapsulated = k.IsEncapsulated,
|
||||
InstanceId = k.Id,
|
||||
@@ -1251,7 +1261,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||
|
||||
}).ToList(),
|
||||
|
||||
NoneDicomStudyList = sv.NoneDicomStudyList.Where(t => isQueryNoneDicom ? inQuery.NoneDicomStudyIdList.Contains(t.Id) : false)
|
||||
NoneDicomStudyList = sv.NoneDicomStudyList.Where(t => isExportReading ? t.IsReading : true).Where(t => isQueryNoneDicom ? inQuery.NoneDicomStudyIdList.Contains(t.Id) : false)
|
||||
|
||||
.Select(nd => new DownloadNoneDicomStudyDto()
|
||||
{
|
||||
@@ -1259,7 +1269,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||
StudyCode = nd.StudyCode,
|
||||
ImageDate = nd.ImageDate,
|
||||
|
||||
FileList = nd.NoneDicomFileList.Select(file => new DownloadNoneDicomFileDto()
|
||||
FileList = nd.NoneDicomFileList.Where(t => isExportReading ? t.IsReading : true).Select(file => new DownloadNoneDicomFileDto()
|
||||
{
|
||||
FileName = file.FileName,
|
||||
Path = file.Path,
|
||||
@@ -1363,7 +1373,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||
VisitName = item.VisitName,
|
||||
|
||||
//取dicom
|
||||
DicomStudyList = item.DicomStudyList,
|
||||
DicomStudyList = item.DicomStudyList.Where(t => t.ReadingSeriesCount > 0).ToList(),
|
||||
}).ToList();
|
||||
|
||||
var noneStudyList = list.Where(item => item.NoneDicomStudyList.Count > 0)
|
||||
@@ -1376,12 +1386,12 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||
VisitName = item.VisitName,
|
||||
|
||||
//非dicom
|
||||
NoneDicomStudyList = item.NoneDicomStudyList,
|
||||
NoneDicomStudyList = item.NoneDicomStudyList.Where(t => t.ReadingFileCount > 0).ToList(),
|
||||
}).ToList();
|
||||
|
||||
|
||||
result.AddRange(dicomStudyList);
|
||||
result.AddRange(noneStudyList);
|
||||
result.AddRange(dicomStudyList.Where(t => t.DicomStudyList.Count > 0));
|
||||
result.AddRange(noneStudyList.Where(t => t.NoneDicomStudyList.Count > 0));
|
||||
#endregion
|
||||
|
||||
return ResponseOutput.Ok(result);
|
||||
@@ -1482,7 +1492,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||
CriterionModalitys = item.CriterionModalitys,
|
||||
SourceSubjectVisitId = item.SourceSubjectVisitId,
|
||||
//取dicom
|
||||
DicomStudyList = item.DicomStudyList,
|
||||
DicomStudyList = item.DicomStudyList.Where(t => t.ReadingSeriesCount > 0).ToList(),
|
||||
}).ToList();
|
||||
|
||||
var noneStudyList = list.Where(item => item.NoneDicomStudyList.Count > 0)
|
||||
@@ -1497,12 +1507,12 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||
CriterionModalitys = item.CriterionModalitys,
|
||||
SourceSubjectVisitId = item.SourceSubjectVisitId,
|
||||
//非dicom
|
||||
NoneDicomStudyList = item.NoneDicomStudyList,
|
||||
NoneDicomStudyList = item.NoneDicomStudyList.Where(t => t.ReadingFileCount > 0).ToList()
|
||||
}).ToList();
|
||||
|
||||
|
||||
result.AddRange(dicomStudyList);
|
||||
result.AddRange(noneStudyList);
|
||||
result.AddRange(dicomStudyList.Where(t => t.DicomStudyList.Count > 0));
|
||||
result.AddRange(noneStudyList.Where(t => t.NoneDicomStudyList.Count > 0));
|
||||
#endregion
|
||||
|
||||
|
||||
@@ -1882,12 +1892,19 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||
/// <summary>
|
||||
/// 影像下载成功回调
|
||||
/// </summary>
|
||||
/// <param name="trialImageDownloadId"></param>
|
||||
/// <param name="incommand"></param>
|
||||
|
||||
/// <returns></returns>
|
||||
public async Task<IResponseOutput> DownloadImageSuccess(Guid trialImageDownloadId)
|
||||
public async Task<IResponseOutput> DownloadImageSuccess(DownloadImageSuccessCommand incommand)
|
||||
{
|
||||
await _trialImageDownloadRepository.UpdatePartialFromQueryAsync(t => t.Id == trialImageDownloadId, u => new TrialImageDownload()
|
||||
await _trialImageDownloadRepository.UpdatePartialFromQueryAsync(t => t.Id == incommand.TrialImageDownloadId, u => new TrialImageDownload()
|
||||
{ DownloadEndTime = DateTime.Now, IsSuccess = true }, true);
|
||||
|
||||
if (incommand.VisitTaskIdList != null && incommand.VisitTaskIdList.Count > 0)
|
||||
{
|
||||
incommand.VisitTaskIdList = incommand.VisitTaskIdList.Distinct().ToList();
|
||||
await _visitTaskRepository.BatchUpdateNoTrackingAsync(t => incommand.VisitTaskIdList.Contains(t.Id), u => new VisitTask() { IsIRImageDownloaded = true });
|
||||
}
|
||||
return ResponseOutput.Ok();
|
||||
}
|
||||
|
||||
@@ -2014,7 +2031,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||
public async Task<List<Guid?>> GetTrialUnreadVisitList(Guid trialId)
|
||||
{
|
||||
|
||||
var subjectVisitList = await _visitTaskRepository.Where(t => t.TrialId == trialId && t.TaskState == TaskState.Effect && t.ReadingCategory == ReadingCategory.Visit && t.ReadingTaskState != ReadingTaskState.HaveSigned && t.SourceSubjectVisitId!=null).Select(t => t.SourceSubjectVisitId)
|
||||
var subjectVisitList = await _visitTaskRepository.Where(t => t.TrialId == trialId && t.TaskState == TaskState.Effect && t.ReadingCategory == ReadingCategory.Visit && t.ReadingTaskState != ReadingTaskState.HaveSigned && t.SourceSubjectVisitId != null).Select(t => t.SourceSubjectVisitId)
|
||||
.Distinct().ToListAsync();
|
||||
|
||||
return subjectVisitList;
|
||||
@@ -2064,6 +2081,8 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||
|
||||
TableQuestionRowPictureList = t.LesionList.Select(c => new TrialKeyPicturePath { PicturePath = c.PicturePath, OtherPicturePath = c.OtherPicturePath }).ToList(),
|
||||
|
||||
SegmentationFileList = t.SegmentationList.Select(c => new TrialKeyPicturePath { PicturePath = c.SEGUrl, SegmentationName = c.SegmentationName, OtherPicturePath = string.Empty }).ToList(),
|
||||
|
||||
Id = t.Id,
|
||||
//裁判选择结果
|
||||
JudgeResultTaskId = t.JudgeVisitTask.JudgeResultTaskId,
|
||||
@@ -2443,18 +2462,42 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||
SubjectCode = t.Code,
|
||||
IsUrgent = t.IsUrgent,
|
||||
|
||||
LatestDownloadTime = t.TrialImageDownloadList.Where(t => t.CreateUserRole.UserTypeEnum == UserTypeEnum.IndependentReviewer)
|
||||
.OrderByDescending(t => t.CreateTime).Select(t => (DateTime?)t.CreateTime).FirstOrDefault(),
|
||||
|
||||
LatestUploadTime = t.SubjectVisitList
|
||||
.Where(v => v.SubmitState == SubmitStateEnum.Submitted && v.CheckState == CheckStateEnum.CVPassed)
|
||||
.SelectMany(v => v.TaskStudyList)
|
||||
.Select(s => (DateTime?)s.CreateTime) // 假设字段名为 CreateTime,根据实际情况调整
|
||||
.Union(
|
||||
t.SubjectVisitList
|
||||
.Where(v => v.SubmitState == SubmitStateEnum.Submitted && v.CheckState == CheckStateEnum.CVPassed)
|
||||
.SelectMany(v => v.NoneDicomStudyList)
|
||||
.Where(n => n.ImageLabelNoneDicomFileList.Any())
|
||||
.Select(s => (DateTime?)s.CreateTime) // 假设字段名为 CreateTime,根据实际情况调整
|
||||
)
|
||||
.OrderByDescending(time => time)
|
||||
.FirstOrDefault(),
|
||||
|
||||
VisitCount = t.SubjectVisitList.Where(t => t.SubmitState == SubmitStateEnum.Submitted && t.CheckState == CheckStateEnum.CVPassed).Count(),
|
||||
|
||||
MarkIVUSVisitCount = t.SubjectVisitList.Where(t => t.SubmitState == SubmitStateEnum.Submitted && t.CheckState == CheckStateEnum.CVPassed).Count(t => t.NoneDicomStudyList.Where(t => t.Modality == "IVUS").SelectMany(c => c.ImageLabelNoneDicomFileList).Any()),
|
||||
|
||||
MarkOCTVisitCount = t.SubjectVisitList.Where(t => t.SubmitState == SubmitStateEnum.Submitted && t.CheckState == CheckStateEnum.CVPassed).Count(t => t.NoneDicomStudyList.Where(t => t.Modality == "OCT").SelectMany(c => c.ImageLabelNoneDicomFileList).Any()),
|
||||
|
||||
DicomStudyCount = t.SubjectVisitList.Where(t => t.SubmitState == SubmitStateEnum.Submitted && t.CheckState == CheckStateEnum.CVPassed).SelectMany(t => t.StudyList).Count(),
|
||||
//MarkDicomStudyCount = t.SubjectVisitList.Where(t => t.SubmitState == SubmitStateEnum.Submitted).SelectMany(t => t.TaskStudyList).Count(),
|
||||
//DicomStudyCount = t.SubjectVisitList.Where(t => t.SubmitState == SubmitStateEnum.Submitted && t.CheckState == CheckStateEnum.CVPassed).SelectMany(t => t.StudyList).Count(),
|
||||
|
||||
NoneDicomStudyCount = t.SubjectVisitList.Where(t => t.SubmitState == SubmitStateEnum.Submitted && t.CheckState == CheckStateEnum.CVPassed).SelectMany(t => t.NoneDicomStudyList).Count(),
|
||||
//MarkNoneDicomStudyCount = t.SubjectVisitList.Where(t => t.SubmitState == SubmitStateEnum.Submitted).SelectMany(t => t.NoneDicomStudyList).Where(t => t.ImageLabelNoneDicomFileList.Any()).Count(),
|
||||
}).ToPagedListAsync(inQuery);
|
||||
//MarkDicomStudyCount = t.SubjectVisitList.Where(t => t.SubmitState == SubmitStateEnum.Submitted && t.CheckState == CheckStateEnum.CVPassed).SelectMany(t => t.TaskStudyList).Count(),
|
||||
|
||||
//NoneDicomStudyCount = t.SubjectVisitList.Where(t => t.SubmitState == SubmitStateEnum.Submitted && t.CheckState == CheckStateEnum.CVPassed).SelectMany(t => t.NoneDicomStudyList).Count(),
|
||||
|
||||
//MarkNoneDicomStudyCount = t.SubjectVisitList.Where(t => t.SubmitState == SubmitStateEnum.Submitted && t.CheckState == CheckStateEnum.CVPassed).SelectMany(t => t.NoneDicomStudyList).Where(t => t.ImageLabelNoneDicomFileList.Any()).Count(),
|
||||
})
|
||||
.Where(t => t.VisitCount > 0)
|
||||
.WhereIf(inQuery.State == 0, t => t.LatestDownloadTime == null)//待处理
|
||||
.WhereIf(inQuery.State == 1, t => t.LatestDownloadTime != null && (2 * t.VisitCount) != (t.MarkIVUSVisitCount + t.MarkOCTVisitCount))//处理中
|
||||
.WhereIf(inQuery.State == 2, t => t.LatestDownloadTime != null && (2 * t.VisitCount) == (t.MarkIVUSVisitCount + t.MarkOCTVisitCount))//已完成
|
||||
.ToPagedListAsync(inQuery);
|
||||
|
||||
return ResponseOutput.Ok(list);
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace IRaCIS.Core.Application.Services
|
||||
{
|
||||
[ApiExplorerSettings(GroupName = "Image")]
|
||||
[AllowAnonymous]
|
||||
public class InstanceService(IRepository<DicomInstance> _instanceRepository,
|
||||
public class InstanceService(IRepository<DicomInstance> _instanceRepository, IRepository<DicomSeries> _seriesRepository,
|
||||
IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer, IWebHostEnvironment _hostEnvironment) : BaseService, IInstanceService
|
||||
{
|
||||
|
||||
@@ -29,12 +29,15 @@ namespace IRaCIS.Core.Application.Services
|
||||
.OrderBy(s => s.InstanceNumber).ThenBy(s => s.InstanceTime).ThenBy(s => s.CreateTime)
|
||||
.ProjectTo<DicomInstanceDTO>(_mapper.ConfigurationProvider).ToListAsync();
|
||||
|
||||
var des = _seriesRepository.Where(t => t.Id == seriesId).Select(t => t.Description).FirstOrDefault();
|
||||
|
||||
// ⭐ DICOM 空间排序(带兜底)
|
||||
var sorted = DicomSortHelper.SortSlices(
|
||||
list,
|
||||
x => x.ImagePositionPatient,
|
||||
x => x.ImageOrientationPatient,
|
||||
x => x.InstanceNumber
|
||||
x => x.InstanceNumber,
|
||||
des
|
||||
);
|
||||
|
||||
var seriesInfo = await _instanceRepository.Where(s => s.SeriesId == seriesId).Select(t => new
|
||||
|
||||
@@ -3,16 +3,12 @@
|
||||
// 生成时间 2021-12-06 10:54:55
|
||||
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
|
||||
//--------------------------------------------------------------------
|
||||
using DocumentFormat.OpenXml.EMMA;
|
||||
using IRaCIS.Core.Application.Filter;
|
||||
using IRaCIS.Core.Application.Service.Reading.Dto;
|
||||
using IRaCIS.Core.Domain.Models;
|
||||
using IRaCIS.Core.Domain.Share;
|
||||
using IRaCIS.Core.Application.Helper;
|
||||
using IRaCIS.Core.Infrastructure;
|
||||
using Medallion.Threading;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using NPOI.SS.Formula.Functions;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using static ImageHelper;
|
||||
|
||||
namespace IRaCIS.Core.Application.Contracts
|
||||
{
|
||||
@@ -25,11 +21,176 @@ namespace IRaCIS.Core.Application.Contracts
|
||||
IRepository<Trial> _trialRepository,
|
||||
IDistributedLockProvider _distributedLockProvider,
|
||||
IRepository<SubjectVisit> _subjectVisitRepository,
|
||||
IRepository<VisitTask> _visitTaskRepository,
|
||||
IRepository<VisitTask> _visitTaskRepository, IOSSService _oSSService,
|
||||
QCCommon _qCCommon, IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer) : BaseService, INoneDicomStudyService
|
||||
{
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 标注遮盖影像 路径后面加了.MaskNoneDicom_ 就是遮盖的新路径
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<IResponseOutput> NoneDicomStudyMaskImage(NoneDicomStudyMaskImageCommand inCommand)
|
||||
{
|
||||
if (inCommand.NodicomStudyId == null && inCommand.NoneDicomStudyFileIdList == null)
|
||||
{
|
||||
return ResponseOutput.NotOk("NodicomStudyId and NoneDicomStudyFileIdList can not both be null");
|
||||
}
|
||||
|
||||
|
||||
var idPathList = new List<DownloadFileDto>();
|
||||
|
||||
if (inCommand.NodicomStudyId == null && inCommand.NoneDicomStudyFileIdList != null)
|
||||
{
|
||||
idPathList = await _noneDicomStudyFileRepository.Where(t => inCommand.NoneDicomStudyFileIdList.Contains(t.Id)).ProjectTo<DownloadFileDto>(_mapper.ConfigurationProvider).ToListAsync();
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
idPathList = await _noneDicomStudyFileRepository.Where(t => inCommand.NodicomStudyId == t.NoneDicomStudyId).ProjectTo<DownloadFileDto>(_mapper.ConfigurationProvider).ToListAsync();
|
||||
|
||||
}
|
||||
|
||||
|
||||
var errorList = new List<DownloadFileDto>();
|
||||
|
||||
var okList = new List<DownloadFileDto>();
|
||||
|
||||
var batchId = Guid.NewGuid();
|
||||
|
||||
foreach (var item in idPathList)
|
||||
{
|
||||
var path = item.Path;
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
// 1. 下载文件
|
||||
using var inputStream = new MemoryStream();
|
||||
await (await _oSSService.GetStreamFromOSSAsync(path)).CopyToAsync(inputStream);
|
||||
inputStream.Position = 0;
|
||||
|
||||
// 2. 处理图片
|
||||
using var outputStream = new MemoryStream();
|
||||
await ImageMaskHelper.MaskAsync(inputStream, outputStream, inCommand.MaskRegionList);
|
||||
outputStream.Position = 0;
|
||||
|
||||
|
||||
|
||||
var prefix = path.Substring(1, path.LastIndexOf('/') - 1);
|
||||
|
||||
//每次都用一个新的名字
|
||||
var maskFileName = string.Empty;
|
||||
|
||||
if (path.Contains(".MaskNoneDicom_"))
|
||||
{
|
||||
//清理缓存的里面的遮盖图,多次遮盖同一张图时,清除缓存很重要
|
||||
await _oSSService.DeleteFromPrefix(path, true); //清理缓存的里面的遮盖图,多次遮盖同一张图时,清除缓存很重要
|
||||
|
||||
//本身就是遮盖的图,那么就要要替换guid
|
||||
var length = Guid.Empty.ToString().Length + ".MaskNoneDicom_".Length;
|
||||
|
||||
var restorePath = item.Path[..^length];
|
||||
|
||||
maskFileName = $"{Path.GetFileName(restorePath)}.MaskNoneDicom_{batchId}";
|
||||
}
|
||||
else
|
||||
{
|
||||
//没有遮盖的,直接加上.批次_MaskDicom
|
||||
maskFileName = $"{Path.GetFileName(path)}.MaskNoneDicom_{batchId}";
|
||||
}
|
||||
|
||||
|
||||
await _oSSService.UploadToOSSAsync(outputStream, prefix, maskFileName, false);
|
||||
|
||||
var newPath = $"/{prefix}/{maskFileName}";
|
||||
|
||||
okList.Add(new DownloadFileDto() { Id = item.Id, Path = newPath });
|
||||
|
||||
await _noneDicomStudyFileRepository.BatchUpdateNoTrackingAsync(t => t.Id == item.Id, u => new NoneDicomStudyFile() { Path = newPath, IsMasked = true });
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
errorList.Add(new DownloadFileDto() { Id = item.Id, Path = path });
|
||||
|
||||
Log.Logger.Error(ex, $"NoneDicomStudyMaskImage Error for NoneDicomStudyFileIdList Path:{path} {ex.Message}");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
await _noneDicomStudyFileRepository.SaveChangesAsync();
|
||||
|
||||
return ResponseOutput.Ok(new { OkList = okList, ErrorList = errorList });
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 撤销遮盖的影像,可以单张,也可以整个检查
|
||||
/// </summary>
|
||||
/// <param name="inCommand"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<IResponseOutput> NoneDicomStudyUndoMaskImage(NoneDicomStudyUndoMaskImageCommand inCommand)
|
||||
{
|
||||
if (inCommand.NodicomStudyId == null && inCommand.NoneDicomStudyFileIdList == null)
|
||||
{
|
||||
return ResponseOutput.NotOk("NodicomStudyId and NoneDicomStudyFileIdList can not both be null");
|
||||
}
|
||||
|
||||
|
||||
var idPathList = new List<DownloadFileDto>();
|
||||
|
||||
if (inCommand.NodicomStudyId == null && inCommand.NoneDicomStudyFileIdList != null)
|
||||
{
|
||||
idPathList = await _noneDicomStudyFileRepository.Where(t => inCommand.NoneDicomStudyFileIdList.Contains(t.Id)).ProjectTo<DownloadFileDto>(_mapper.ConfigurationProvider).ToListAsync();
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
idPathList = await _noneDicomStudyFileRepository.Where(t => inCommand.NodicomStudyId == t.NoneDicomStudyId).ProjectTo<DownloadFileDto>(_mapper.ConfigurationProvider).ToListAsync();
|
||||
|
||||
}
|
||||
|
||||
|
||||
var okList = new List<DownloadFileDto>();
|
||||
|
||||
foreach (var item in idPathList)
|
||||
{
|
||||
if (item.Path.Contains(".MaskNoneDicom_"))
|
||||
{
|
||||
await _oSSService.DeleteFromPrefix(item.Path, true);
|
||||
|
||||
var length = Guid.Empty.ToString().Length + ".MaskNoneDicom_".Length;
|
||||
var newPath = item.Path[..^length];
|
||||
|
||||
okList.Add(new DownloadFileDto() { Id = item.Id, Path = newPath });
|
||||
|
||||
await _noneDicomStudyFileRepository.BatchUpdateNoTrackingAsync(t => t.Id == item.Id, u => new NoneDicomStudyFile() { Path = newPath, IsMasked = false });
|
||||
}
|
||||
|
||||
//if (item.Path.EndsWith("."))
|
||||
//{
|
||||
// await _oSSService.DeleteFromPrefix(item.Path, true);
|
||||
|
||||
// var newPath = item.Path[..^1];
|
||||
|
||||
// okList.Add(new InstanceIdPath() { Id = item.Id, Path = newPath });
|
||||
|
||||
// await _dicomInstanceRepository.BatchUpdateNoTrackingAsync(t => t.Id == item.Id, u => new DicomInstance() { Path = newPath, IsMasked = false });
|
||||
//}
|
||||
|
||||
|
||||
}
|
||||
|
||||
await _noneDicomStudyFileRepository.SaveChangesAsync();
|
||||
|
||||
return ResponseOutput.Ok(new { OkList = okList });
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
[HttpGet]
|
||||
public async Task<IResponseOutput<List<NoneDicomStudyView>>> GetNoneDicomStudyList(
|
||||
|
||||
@@ -59,7 +59,8 @@ namespace IRaCIS.Core.Application.Services
|
||||
instances,
|
||||
x => x.ImagePositionPatient,
|
||||
x => x.ImageOrientationPatient,
|
||||
x => x.InstanceNumber
|
||||
x => x.InstanceNumber,
|
||||
series.Description
|
||||
);
|
||||
|
||||
series.InstanceInfoList = sorted.Select(k =>
|
||||
@@ -104,13 +105,24 @@ namespace IRaCIS.Core.Application.Services
|
||||
.WhereIf(isReading == true, t => t.IsReading == true)
|
||||
.OrderBy(t => t.SeriesId).ThenBy(t => t.InstanceNumber)
|
||||
.ThenBy(s => s.InstanceTime).ThenBy(s => s.CreateTime)
|
||||
.Select(t => new { t.SeriesId, t.Id, t.Path, t.NumberOfFrames, t.InstanceNumber, t.HtmlPath, t.IsReading, t.IsDeleted, t.FileSize ,t.IsMasked}).ToListAsync();//.GroupBy(u => u.SeriesId);
|
||||
.Select(t => new { t.SeriesId, t.Id, t.Path, t.NumberOfFrames, t.InstanceNumber, t.HtmlPath, t.IsReading, t.IsDeleted, t.FileSize ,t.IsMasked, t.ImagePositionPatient, t.ImageOrientationPatient }).ToListAsync();//.GroupBy(u => u.SeriesId);
|
||||
|
||||
|
||||
foreach (var series in seriesList)
|
||||
{
|
||||
|
||||
series.InstanceInfoList = instanceList.Where(t => t.SeriesId == series.Id).OrderBy(t => t.InstanceNumber).Select(k =>
|
||||
var instances = instanceList.Where(x => x.SeriesId == series.Id);
|
||||
|
||||
// ⭐ DICOM 空间排序(带兜底)
|
||||
var sorted = DicomSortHelper.SortSlices(
|
||||
instances,
|
||||
x => x.ImagePositionPatient,
|
||||
x => x.ImageOrientationPatient,
|
||||
x => x.InstanceNumber,
|
||||
series.Description
|
||||
);
|
||||
|
||||
series.InstanceInfoList = sorted.Select(k =>
|
||||
new InstanceBasicInfo()
|
||||
{
|
||||
Id = k.Id,
|
||||
|
||||
@@ -2,24 +2,14 @@
|
||||
using FellowOakDicom.Imaging;
|
||||
using FellowOakDicom.IO.Buffer;
|
||||
using IRaCIS.Core.Application.Contracts;
|
||||
using IRaCIS.Core.Application.Filter;
|
||||
using IRaCIS.Core.Application.Helper;
|
||||
using IRaCIS.Core.Application.Service.ImageAndDoc.DTO;
|
||||
using IRaCIS.Core.Domain.Share;
|
||||
using IRaCIS.Core.Infrastructure;
|
||||
using MathNet.Numerics;
|
||||
using Medallion.Threading;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Components.Forms;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using NetTopologySuite.Algorithm;
|
||||
using SharpCompress.Common;
|
||||
using SkiaSharp;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using ZiggyCreatures.Caching.Fusion;
|
||||
|
||||
namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||
{
|
||||
@@ -82,9 +72,35 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||
{
|
||||
try
|
||||
{
|
||||
#region 方式一 有的必须在内存中,不能用这种
|
||||
//await using var source = await sourceFactory();
|
||||
//// 如果你是从 stream 打开
|
||||
//var dicomFile = await DicomFile.OpenAsync(source);
|
||||
#endregion
|
||||
|
||||
#region 方式二
|
||||
|
||||
await using var source = await sourceFactory();
|
||||
|
||||
// 【关键修复】将 OSS 流缓冲到 MemoryStream
|
||||
using var bufferedStream = new MemoryStream();
|
||||
|
||||
if (source.CanSeek)
|
||||
{
|
||||
source.Position = 0;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// 完全复制到内存流
|
||||
await source.CopyToAsync(bufferedStream);
|
||||
bufferedStream.Position = 0; // 重置位置
|
||||
}
|
||||
|
||||
// 如果你是从 stream 打开
|
||||
var dicomFile = await DicomFile.OpenAsync(source);
|
||||
var dicomFile = await DicomFile.OpenAsync(source.CanSeek ? source : bufferedStream);
|
||||
|
||||
#endregion
|
||||
|
||||
//获取像素是否为封装形式
|
||||
var syntax = dicomFile.Dataset.InternalTransferSyntax;
|
||||
@@ -104,11 +120,11 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||
newFragments.Fragments.Add(new MemoryByteBuffer(frameData.Data));
|
||||
}
|
||||
|
||||
var frag = dicomFile.Dataset.GetDicomItem<DicomOtherByteFragment>(DicomTag.PixelData);
|
||||
//var frag = dicomFile.Dataset.GetDicomItem<DicomOtherByteFragment>(DicomTag.PixelData);
|
||||
|
||||
var originOffsetTable = frag?.OffsetTable;
|
||||
//var originOffsetTable = frag?.OffsetTable;
|
||||
|
||||
newFragments.OffsetTable.AddRange(originOffsetTable?.ToArray());
|
||||
//newFragments.OffsetTable.AddRange(originOffsetTable?.ToArray());
|
||||
// 替换原有的片段序列
|
||||
dicomFile.Dataset.AddOrUpdate(newFragments);
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user