Compare commits
558 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0a6ee05417 | |||
| 8325ccad72 | |||
| c27c4ce617 | |||
| b9ecabf915 | |||
| 4f13a98eff | |||
| 2a4e4e66fa | |||
| b72cc5cbc0 | |||
| 04f91560b8 | |||
| 87af2edf17 | |||
| 856977612d | |||
| d1ac17cee1 | |||
| 9748e70cdf | |||
| f9bd8c3f5c | |||
| 5ba0a9bbd0 | |||
| d8ea1e8f94 | |||
| cb83c2a737 | |||
| 806d663cfb | |||
| 7ab1728bc7 | |||
| fdd9afd4f0 | |||
| 32e64eaeff | |||
| 7b6efd52bb | |||
| 53d26c0445 | |||
| 7467f2ae11 | |||
| c498ffb21b | |||
| 1dadf7b8b6 | |||
| 793cf1b570 | |||
| 5a8f564b74 | |||
| e24c9e6ac2 | |||
| 814f6fd83c | |||
| 40d035e7a7 | |||
| a13807ae5f | |||
| 9d5aaf1e26 | |||
| c347d08e2b | |||
| d34be9b07d | |||
| e205ea0018 | |||
| ba9d3a30b9 | |||
| 10cf908775 | |||
| ee9ad472f0 | |||
| 1cdfc5f2b5 | |||
| 9e9f07e4fd | |||
| a0294e6bd6 | |||
| 55fdf431e0 | |||
| 9f1110f91a | |||
| d76b24bc25 | |||
| 0787875b3b | |||
| b33aca3230 | |||
| 0b291e8b21 | |||
| 0cf7e5fddd | |||
| 95f708da58 | |||
| ce47776f19 | |||
| 7fff48b07a | |||
| 4688cb388e | |||
| 21e1a7ab01 | |||
| 5952af85f1 | |||
| 5e193db33b | |||
| 30bcfcc675 | |||
| 514764ee6e | |||
| 685269eebf | |||
| 276ad83080 | |||
| 7a318eae45 | |||
| 0769f8fe05 | |||
| 03ac25835e | |||
| 29c3888108 | |||
| 91951be107 | |||
| 935e46a8f1 | |||
| 1345808019 | |||
| 400d0d3336 | |||
| ca0fd77176 | |||
| f7cf6d9669 | |||
| 7f19944005 | |||
| e8aec5f04c | |||
| 0afbd24923 | |||
| 932772f8c8 | |||
| b7a803678c | |||
| e99360bf5b | |||
| 5064630d1f | |||
| 4034da47f2 | |||
| 381b1965cf | |||
| d5e747becd | |||
| 758273d362 | |||
| 1560a0278e | |||
| 64c275a91c | |||
| 05189b4e5a | |||
| 80aaac997d | |||
| c560921092 | |||
| 81cd9aa6b7 | |||
| 4bfc6dd295 | |||
| a8464364c1 | |||
| e333368528 | |||
| 58c1c25fc2 | |||
| 3045b0ec48 | |||
| 2d50037c03 | |||
| 6a1cd07951 | |||
| c7103654e3 | |||
| 4e03071c4c | |||
| bf9e8a6758 | |||
| 00c6705161 | |||
| 209d932757 | |||
| e954ea8538 | |||
| f79a8b4cfb | |||
| 8fc01e2509 | |||
| 232e607b8c | |||
| bdeb7c464e | |||
| 3668079479 | |||
| c115e9453b | |||
| f157a0f473 | |||
| c2252b4e9f | |||
| b0554119f1 | |||
| 37387692dd | |||
| 970c41a064 | |||
| 67a3fe0f1b | |||
| 15108156c2 | |||
| 1a2c51da12 | |||
| 3d10482da8 | |||
| 3abc8787c6 | |||
| df346d31e6 | |||
| a8babb53f2 | |||
| 3c1cc92e1b | |||
| 99ee8c4757 | |||
| fc81d6da22 | |||
| 47edcbd761 | |||
| a499971e91 | |||
| afd34c7c9b | |||
| 529c646277 | |||
| b8f03153ca | |||
| a14df73879 | |||
| cb9141c1ce | |||
| ff2461dafc | |||
| 779af013e6 | |||
| 75fb357cc5 | |||
| 89eb1032cf | |||
| eca9c36110 | |||
| 2430651ed4 | |||
| 87d658031b | |||
| 34b90538ab | |||
| d2571d5f79 | |||
| 1688d7c934 | |||
| 9ab5dc7d02 | |||
| 97cdec61be | |||
| c0d6eb3203 | |||
| d125ff6324 | |||
| 1b830b386e | |||
| ee83909123 | |||
| 844e27e94e | |||
| 6fded9f028 | |||
| b5103f1940 | |||
| 8bf54dfc1b | |||
| 1069292c54 | |||
| 88c6f574ec | |||
| f5f6d3b6ac | |||
| 38f937ea9e | |||
| 2913eb67f4 | |||
| a0ceec28e7 | |||
| b77a50caf6 | |||
| 87f2d0e429 | |||
| e17fc6bce9 | |||
| 0970e2807b | |||
| a64d26513a | |||
| 73e80f2571 | |||
| 770f361d04 | |||
| 7476472071 | |||
| 1fff2f7256 | |||
| 1e4044488d | |||
| 1e1822151b | |||
| c37b6c4c84 | |||
| 8f65b9e60e | |||
| a8a9a09f88 | |||
| 7526ca2905 | |||
| fd83c3e7a7 | |||
| a3c575857a | |||
| c292f6ce44 | |||
| 84a7d75174 | |||
| 048afdcc7b | |||
| 06e319cf09 | |||
| cee0730e03 | |||
| adaa672185 | |||
| b6b5d3e4c9 | |||
| 6ac057a0c7 | |||
| 6607a0ff8f | |||
| 0374551655 | |||
| be9f0075e3 | |||
| 2cc004746e | |||
| b1a7ac1d28 | |||
| 5a31e16c65 | |||
| 0b56836097 | |||
| a4a11aaaec | |||
| ae1b2523b1 | |||
| 87f9d08c74 | |||
| 81abd9622f | |||
| faf87f5b86 | |||
| 66dc231850 | |||
| 34ff47bc1c | |||
| 842b7117a2 | |||
| 6543aba53f | |||
| 06cee8926e | |||
| a35fe11f5b | |||
| cc13544968 | |||
| 19ee511d8d | |||
| 0b47d6ca09 | |||
| 00193bb4bc | |||
| 4379fcbdb3 | |||
| 8464625bbf | |||
| e88f949cb7 | |||
| 4fdb0737fc | |||
| 04be8cf642 | |||
| 089ecbf144 | |||
| b95e97a5df | |||
| e84710c4aa | |||
| f549d1fca9 | |||
| 2c72dc000f | |||
| 2ceddc1340 | |||
| f118c48d0e | |||
| a3a1236d5b | |||
| a7848727ee | |||
| 5787c36687 | |||
| 89d009fcbf | |||
| 4e66ea43d7 | |||
| 68d69181a9 | |||
| 7d65cf5051 | |||
| b879b3f2c7 | |||
| 4fd77ce70d | |||
| e74427c45c | |||
| e8825c7efa | |||
| 8213c6d10f | |||
| b79b4567b4 | |||
| 8c5b759a92 | |||
| ab1e33a799 | |||
| 824b65d5ee | |||
| c68004b804 | |||
| d5cd8dc338 | |||
| 1fef5509d1 | |||
| 06d12ce709 | |||
| ad7ac80444 | |||
| 29d0ebdb7c | |||
| 9bcaa07c1a | |||
| bf5f56f5f2 | |||
| c1c2b59641 | |||
| 33820c2acb | |||
| 9814f63246 | |||
| 5e6c018199 | |||
| b24751287c | |||
| 759cc6c1be | |||
| 1a929ce2ca | |||
| 1e4571a814 | |||
| 848670d128 | |||
| 6d9b5fdb2d | |||
| ab00d64725 | |||
| 5e36054ee9 | |||
| 2b11042f35 | |||
| e9e5075c1c | |||
| 628e0ad034 | |||
| 2f3f639918 | |||
| 87caf24dd1 | |||
| 9149dd6cf6 | |||
| 24bfb4920c | |||
| 553ad4760c | |||
| 5acd56689b | |||
| 5f0643d4d4 | |||
| 17e4ed38be | |||
| c49f16b055 | |||
| aa42d64cac | |||
| 8f0ef86ab9 | |||
| c17b2f6bac | |||
| be498f2329 | |||
| fea3d8d415 | |||
| bffc8626c7 | |||
| 1efe1228ac | |||
| f900b811c7 | |||
| a5f7e03f6c | |||
| 7aba4adc14 | |||
| 12c8c641ea | |||
| 977adf3153 | |||
| 409b76df26 | |||
| 2d9ebe7094 | |||
| 71e797cf7d | |||
| f781027388 | |||
| 56e316e6a1 | |||
| edef3e1990 | |||
| d6d0965467 | |||
| 62f888710c | |||
| 58e8c2392f | |||
| 0e1310324d | |||
| efcda61104 | |||
| 97133a5554 | |||
| 577ed42f97 | |||
| 8f704c4617 | |||
| a03d7f55c7 | |||
| 2bbc101f95 | |||
| 2b11e9165f | |||
| b25dec68cb | |||
| 2f57238f66 | |||
| 8239061a84 | |||
| a43ebc016a | |||
| c036aab9c4 | |||
| dd6419dc44 | |||
| 54a9cfbb8e | |||
| 2eb85b6b71 | |||
| 712f1ceb61 | |||
| adf873639c | |||
| 4e9460e7da | |||
| 5481eac988 | |||
| b7c9abca02 | |||
| 447d3fc36f | |||
| 71702b2abb | |||
| 2ffb24d630 | |||
| 81ecd9ff7f | |||
| ebe012ca67 | |||
| 805176c3ea | |||
| f99cab6983 | |||
| c94d800646 | |||
| 0cbc345f49 | |||
| d34f3f1576 | |||
| 73f5e67e3c | |||
| 5cf8c7a898 | |||
| 11c9cebf47 | |||
| bd9362fb25 | |||
| 3aa588f125 | |||
| 6d33a2c1b0 | |||
| 9e4cf1d1db | |||
| ae38c84ef7 | |||
| 6306c6752a | |||
| 5490630922 | |||
| d1ea886e76 | |||
| 7dc1205bb6 | |||
| 15b094a422 | |||
| 78c46572a2 | |||
| abeda7820d | |||
| 2dac67618c | |||
| bb9b1283bf | |||
| b9458ecb38 | |||
| b205757f8f | |||
| 0b937663ff | |||
| 7a75d107dc | |||
| 0f682dd184 | |||
| c2360dd519 | |||
| f9c2ac030a | |||
| 7ce2386aea | |||
| 67b226ee44 | |||
| 70c7f8a740 | |||
| e409aa3c05 | |||
| a3b5129ee2 | |||
| 57cd0281fa | |||
| ba9d3abc52 | |||
| b9bc1f6da0 | |||
| 08f1998e61 | |||
| bc19ead2f5 | |||
| f9327c56db | |||
| 17f3d821ea | |||
| 02f3e97654 | |||
| 94bba7837c | |||
| 626fcb9cf3 | |||
| bf92165432 | |||
| 92e99edbbd | |||
| 94507c7887 | |||
| 0cce75befa | |||
| 96469c28d3 | |||
| a12db2637e | |||
| 0a406da3a4 | |||
| 6271dd4144 | |||
| 4182809657 | |||
| ab6ec064fa | |||
| d921a48a09 | |||
| 0f03dbc75b | |||
| e5fa3a09b3 | |||
| 4cdfb60fdf | |||
| 200bdaccc4 | |||
| 17a35e0fdb | |||
| 28f2bf1629 | |||
| bec04ab795 | |||
| 54cefab633 | |||
| 2918c0e93f | |||
| 92c495ed07 | |||
| d9d807e3d1 | |||
| 959b49a2cc | |||
| 17f131cf63 | |||
| 4ef67beafc | |||
| 826a04ef31 | |||
| 104b1208ed | |||
| 8b3040c24d | |||
| 153dbd2016 | |||
| 91d5cbce16 | |||
| 7218427ec2 | |||
| 5d91ae8157 | |||
| 0f61d746e5 | |||
| e931e740e6 | |||
| 38917e05ab | |||
| dd33f7e086 | |||
| 43d4d679b5 | |||
| e02fa28cd0 | |||
| 055e085d2a | |||
| caf1fb6b32 | |||
| 6b049e68cd | |||
| 2a4360cc64 | |||
| 8efc254f3c | |||
| f89b3daf50 | |||
| 29f6196698 | |||
| 09ff2468e9 | |||
| 1867277e1b | |||
| 053a09a5b2 | |||
| fae86f0836 | |||
| 2e539dfa71 | |||
| a9efd85aec | |||
| 09e70b9f21 | |||
| 2d184e0f08 | |||
| 43d6c7d8db | |||
| 19487acc64 | |||
| 336e7768b8 | |||
| 9b49dc41c8 | |||
| 74f896cf00 | |||
| 10b0bde1d0 | |||
| 411b5d5f8f | |||
| b6da27ac07 | |||
| a6b81b038f | |||
| e2c80babfa | |||
| 01b9f28e7b | |||
| 2c9fad60fb | |||
| 398baea876 | |||
| aec94d0a46 | |||
| 4b69e45d44 | |||
| 12f2c2becb | |||
| 699f79278b | |||
| 88e07d28fd | |||
| 226ba06bf3 | |||
| c1667fc48b | |||
| f900e675da | |||
| ee51b9eade | |||
| bf62ee92dd | |||
| 78532803bc | |||
| 86ea3ebc32 | |||
| 01aba3f3e0 | |||
| 6dc1ef5728 | |||
| 02e5d770db | |||
| f8c3704c87 | |||
| 4c21459e00 | |||
| cdbbe460ab | |||
| 45da1645e0 | |||
| 9a1f4697c2 | |||
| 217b8713ff | |||
| 0998f047e4 | |||
| 47755bc2aa | |||
| 72efd36649 | |||
| 553a8d392f | |||
| f050416265 | |||
| a7d1a92a01 | |||
| bf9ce9b213 | |||
| a9c7c79fb5 | |||
| dc3a830909 | |||
| 171bfde031 | |||
| f471ce1535 | |||
| 56170b73ed | |||
| 2a9c1ec45c | |||
| 3ccb3ff4de | |||
| 6c078806cd | |||
| c2f768bef8 | |||
| 1b7bb5a4fe | |||
| dfe6d13182 | |||
| 4c04718db4 | |||
| 64d803cbc0 | |||
| 54ccae5762 | |||
| 8d6bf0c7b1 | |||
| 8496e6bcd7 | |||
| 7770fc264b | |||
| 51f21805be | |||
| 434e49ea85 | |||
| 468f7c7070 | |||
| 4577db7582 | |||
| cc17816dae | |||
| 172cecebe4 | |||
| 7913acdf70 | |||
| e9f57b5001 | |||
| b8c0bd7082 | |||
| 6200ec1ba7 | |||
| 73912fd875 | |||
| 812035686e | |||
| 1f8caa4616 | |||
| 4a1e0a87ba | |||
| 337bda45fd | |||
| c2412bfb4b | |||
| cff6b87daa | |||
| 2f93a490f0 | |||
| 1856ef9483 | |||
| b45602556c | |||
| b5326d4928 | |||
| 8bbc8c449f | |||
| dcd6375d7d | |||
| 8b53517f2c | |||
| 1c3ddcf1cd | |||
| fc4ef6b939 | |||
| 6d009c4f86 | |||
| f995187925 | |||
| 67a6a5f861 | |||
| 6bfa4da72d | |||
| 9797c94aa8 | |||
| 5dd2dfd17b | |||
| 5791aca9fd | |||
| f61ce70b82 | |||
| c8091d3215 | |||
| 7153d810aa | |||
| 68053d24b6 | |||
| a49b4c8ef7 | |||
| c6c036c152 | |||
| db0d087396 | |||
| 263f43b1a9 | |||
| 77d920a2ef | |||
| bbf7af8405 | |||
| d0bbc58b20 | |||
| 4d4bb08423 | |||
| dd09c78cd2 | |||
| 771091a557 | |||
| 8ce1bdf21c | |||
| 679cc26225 | |||
| ff5be827d0 | |||
| 3b43bee0f1 | |||
| 26500aa1cf | |||
| b58bdc184e | |||
| 655fe18138 | |||
| 9d70d61013 | |||
| 68452beba0 | |||
| 409e9e9bc0 | |||
| f241f2cd2b | |||
| 2ea90a66ae | |||
| a578be8336 | |||
| 823ada5673 | |||
| 0578263e10 | |||
| 9316c0814f | |||
| 2a170cc97e | |||
| c109e14a93 | |||
| 240d406a1a | |||
| c16153fa19 | |||
| a0797a99ff | |||
| 376cfa3167 | |||
| 14690dc3cc | |||
| 7cb8d04ca9 | |||
| a2fc2c5075 | |||
| 1ed8788c83 | |||
| 14e95fd303 | |||
| 3dca5aa06f | |||
| faea3a4f86 | |||
| a5dcad1767 | |||
| 6754121b17 | |||
| 131425774a | |||
| 585e4cdc1b | |||
| 12ddeba2a3 | |||
| ab0c256e0b | |||
| 8a24b33757 | |||
| 8f6e2e342a | |||
| 4dfeb653b1 | |||
| 670a754eb2 | |||
| 3f46103dc3 | |||
| 6c2901daca | |||
| a73e5d4133 | |||
| b067cb66f3 | |||
| f1185758d6 | |||
| 0d4a0adf00 | |||
| 20f6f95b89 | |||
| 7e7c186784 | |||
| 70e0a1325a | |||
| 91471dee13 |
@@ -7,28 +7,28 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="AlibabaCloud.SDK.Sts20150401" Version="1.1.4" />
|
<PackageReference Include="AlibabaCloud.SDK.Sts20150401" Version="1.1.5" />
|
||||||
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="10.0.0" />
|
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="10.0.0" />
|
||||||
<PackageReference Include="Aliyun.OSS.SDK.NetCore" Version="2.14.1" />
|
<PackageReference Include="Aliyun.OSS.SDK.NetCore" Version="2.14.1" />
|
||||||
<PackageReference Include="AWSSDK.S3" Version="3.7.405" />
|
<PackageReference Include="AWSSDK.S3" Version="3.7.416.8" />
|
||||||
<PackageReference Include="AWSSDK.SecurityToken" Version="3.7.400.36" />
|
<PackageReference Include="AWSSDK.SecurityToken" Version="3.7.401.81" />
|
||||||
<PackageReference Include="DistributedLock.Core" Version="1.0.7" />
|
<PackageReference Include="DistributedLock.Core" Version="1.0.8" />
|
||||||
<PackageReference Include="DistributedLock.SqlServer" Version="1.0.5" />
|
<PackageReference Include="DistributedLock.SqlServer" Version="1.0.6" />
|
||||||
<PackageReference Include="fo-dicom" Version="5.1.3" />
|
<PackageReference Include="fo-dicom" Version="5.2.1" />
|
||||||
<PackageReference Include="fo-dicom.Codecs" Version="5.15.1" />
|
<PackageReference Include="fo-dicom.Codecs" Version="5.16.1" />
|
||||||
<PackageReference Include="fo-dicom.Imaging.ImageSharp" Version="5.1.3" />
|
<PackageReference Include="fo-dicom.Imaging.ImageSharp" Version="5.2.1" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="8.0.10" />
|
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="8.0.10" />
|
||||||
<PackageReference Include="AutoMapper" Version="13.0.1" />
|
<PackageReference Include="AutoMapper" Version="13.0.1" />
|
||||||
<PackageReference Include="Minio" Version="6.0.3" />
|
<PackageReference Include="Minio" Version="6.0.4" />
|
||||||
<PackageReference Include="My.Extensions.Localization.Json" Version="3.3.0">
|
<PackageReference Include="My.Extensions.Localization.Json" Version="3.3.0">
|
||||||
<TreatAsUsed>true</TreatAsUsed>
|
<TreatAsUsed>true</TreatAsUsed>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="Panda.DynamicWebApi" Version="1.2.2" />
|
<PackageReference Include="Panda.DynamicWebApi" Version="1.2.2" />
|
||||||
<PackageReference Include="Serilog.Enrichers.ClientInfo" Version="2.1.2" />
|
<PackageReference Include="Serilog.Enrichers.ClientInfo" Version="2.1.2" />
|
||||||
<PackageReference Include="Serilog.Extensions.Hosting" Version="8.0.0" />
|
<PackageReference Include="Serilog.Extensions.Hosting" Version="9.0.0" />
|
||||||
<PackageReference Include="Serilog.Sinks.Console" Version="6.0.0" />
|
<PackageReference Include="Serilog.Sinks.Console" Version="6.0.0" />
|
||||||
<PackageReference Include="Serilog.Sinks.File" Version="6.0.0" />
|
<PackageReference Include="Serilog.Sinks.File" Version="6.0.0" />
|
||||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.9.0" />
|
<PackageReference Include="Swashbuckle.AspNetCore" Version="8.1.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
+16
-8
@@ -126,16 +126,22 @@ builder.Services.Configure<ForwardedHeadersOptions>(options =>
|
|||||||
ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
|
ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
builder.Services.AddFellowOakDicom().AddTranscoderManager<NativeTranscoderManager>()
|
||||||
|
//.AddTranscoderManager<FellowOakDicom.Imaging.NativeCodec.NativeTranscoderManager>()
|
||||||
|
.AddImageManager<ImageSharpImageManager>();
|
||||||
|
|
||||||
|
|
||||||
//Dicom影像渲染图片 跨平台
|
//Dicom影像渲染图片 跨平台
|
||||||
//builder.Services.AddDicomSetup();
|
//builder.Services.AddDicomSetup();
|
||||||
new DicomSetupBuilder()
|
//new DicomSetupBuilder()
|
||||||
.RegisterServices(s =>
|
// .RegisterServices(s =>
|
||||||
s.AddFellowOakDicom()
|
// s.AddFellowOakDicom()
|
||||||
.AddTranscoderManager<NativeTranscoderManager>()
|
// .AddTranscoderManager<NativeTranscoderManager>()
|
||||||
//.AddTranscoderManager<FellowOakDicom.Imaging.NativeCodec.NativeTranscoderManager>()
|
// //.AddTranscoderManager<FellowOakDicom.Imaging.NativeCodec.NativeTranscoderManager>()
|
||||||
.AddImageManager<ImageSharpImageManager>())
|
// .AddImageManager<ImageSharpImageManager>())
|
||||||
.SkipValidation()
|
// .SkipValidation()
|
||||||
.Build();
|
// .Build();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -211,6 +217,8 @@ else
|
|||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
DicomSetupBuilder.UseServiceProvider(app.Services);
|
||||||
|
|
||||||
var logger = app.Services.GetService<Microsoft.Extensions.Logging.ILogger<Program>>();
|
var logger = app.Services.GetService<Microsoft.Extensions.Logging.ILogger<Program>>();
|
||||||
|
|
||||||
var server = DicomServerFactory.Create<CStoreSCPService>(_configuration.GetSection("DicomSCPServiceConfig").GetValue<int>("ServerPort"), userState: app.Services,logger: logger);
|
var server = DicomServerFactory.Create<CStoreSCPService>(_configuration.GetSection("DicomSCPServiceConfig").GetValue<int>("ServerPort"), userState: app.Services,logger: logger);
|
||||||
|
|||||||
@@ -76,9 +76,10 @@ namespace IRaCIS.Core.SCP.Service
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
public CStoreSCPService(INetworkStream stream, Encoding fallbackEncoding, Microsoft.Extensions.Logging.ILogger log, DicomServiceDependencies dependencies)
|
public CStoreSCPService(INetworkStream stream, Encoding fallbackEncoding, Microsoft.Extensions.Logging.ILogger log, DicomServiceDependencies dependencies, IServiceProvider injectServiceProvider)
|
||||||
: base(stream, fallbackEncoding, log, dependencies)
|
: base(stream, fallbackEncoding, log, dependencies)
|
||||||
{
|
{
|
||||||
|
_serviceProvider = injectServiceProvider.CreateScope().ServiceProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -92,9 +93,7 @@ namespace IRaCIS.Core.SCP.Service
|
|||||||
|
|
||||||
Log.Logger.Warning($"接收到来自{association.CallingAE}的连接");
|
Log.Logger.Warning($"接收到来自{association.CallingAE}的连接");
|
||||||
|
|
||||||
_serviceProvider = (IServiceProvider)this.UserState;
|
//_serviceProvider = (IServiceProvider)this.UserState;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var _trialDicomAERepository = _serviceProvider.GetService<IRepository<TrialDicomAE>>();
|
var _trialDicomAERepository = _serviceProvider.GetService<IRepository<TrialDicomAE>>();
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Amazon.Auth.AccessControlPolicy;
|
using AlibabaCloud.SDK.Sts20150401;
|
||||||
|
using Amazon.Auth.AccessControlPolicy;
|
||||||
using Amazon.SecurityToken;
|
using Amazon.SecurityToken;
|
||||||
using AutoMapper;
|
using AutoMapper;
|
||||||
using Azure.Core;
|
using Azure.Core;
|
||||||
@@ -21,10 +22,12 @@ using Microsoft.AspNetCore.Http;
|
|||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
|
using Org.BouncyCastle.Tls;
|
||||||
using RestSharp;
|
using RestSharp;
|
||||||
using RestSharp.Authenticators;
|
using RestSharp.Authenticators;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Globalization;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
@@ -181,11 +184,74 @@ namespace IRaCIS.Api.Controllers
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#region 老项目依赖
|
||||||
|
|
||||||
|
[HttpGet("user/GenerateSTS")]
|
||||||
|
public IResponseOutput GenerateSTS([FromServices] IOptionsMonitor<ObjectStoreServiceOptions> options)
|
||||||
|
{
|
||||||
|
|
||||||
|
var ossOptions = options.CurrentValue.AliyunOSS;
|
||||||
|
|
||||||
|
var client = new Client(new AlibabaCloud.OpenApiClient.Models.Config()
|
||||||
|
{
|
||||||
|
AccessKeyId = ossOptions.AccessKeyId,
|
||||||
|
AccessKeySecret = ossOptions.AccessKeySecret,
|
||||||
|
Endpoint = "sts.cn-hangzhou.aliyuncs.com"
|
||||||
|
});
|
||||||
|
|
||||||
|
var assumeRoleRequest = new AlibabaCloud.SDK.Sts20150401.Models.AssumeRoleRequest();
|
||||||
|
// 将<YOUR_ROLE_SESSION_NAME>设置为自定义的会话名称,例如oss-role-session。
|
||||||
|
assumeRoleRequest.RoleSessionName = $"session-name-{NewId.NextGuid()}";
|
||||||
|
// 将<YOUR_ROLE_ARN>替换为拥有上传文件到指定OSS Bucket权限的RAM角色的ARN。
|
||||||
|
assumeRoleRequest.RoleArn = ossOptions.RoleArn;
|
||||||
|
//assumeRoleRequest.RoleArn = "acs:ram::1899121822495495:role/webdirect";
|
||||||
|
assumeRoleRequest.DurationSeconds = ossOptions.DurationSeconds;
|
||||||
|
var runtime = new AlibabaCloud.TeaUtil.Models.RuntimeOptions();
|
||||||
|
var response = client.AssumeRoleWithOptions(assumeRoleRequest, runtime);
|
||||||
|
var credentials = response.Body.Credentials;
|
||||||
|
|
||||||
|
var tempToken = new AliyunOSSTempToken()
|
||||||
|
{
|
||||||
|
AccessKeyId = credentials.AccessKeyId,
|
||||||
|
AccessKeySecret = credentials.AccessKeySecret,
|
||||||
|
|
||||||
|
//转为服务器时区,最后统一转为客户端时区
|
||||||
|
Expiration = TimeZoneInfo.ConvertTimeFromUtc(DateTime.Parse(credentials.Expiration), TimeZoneInfo.Local),
|
||||||
|
SecurityToken = credentials.SecurityToken,
|
||||||
|
|
||||||
|
|
||||||
|
Region = ossOptions.Region,
|
||||||
|
BucketName = ossOptions.BucketName,
|
||||||
|
EndPoint = ossOptions.EndPoint,
|
||||||
|
ViewEndpoint = ossOptions.ViewEndpoint,
|
||||||
|
PreviewEndpoint = ossOptions.PreviewEndpoint
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
// 返回STS令牌信息给前端
|
||||||
|
var stsToken = new
|
||||||
|
{
|
||||||
|
AccessKeyId = credentials.AccessKeyId,
|
||||||
|
AccessKeySecret = credentials.AccessKeySecret,
|
||||||
|
SecurityToken = credentials.SecurityToken,
|
||||||
|
Expiration = credentials.Expiration,
|
||||||
|
|
||||||
|
Region = ossOptions.Region,
|
||||||
|
BucketName = ossOptions.BucketName,
|
||||||
|
ViewEndpoint = ossOptions.ViewEndpoint,
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
return ResponseOutput.Ok(stsToken);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
[HttpGet("User/UserRedirect")]
|
[HttpGet("User/UserRedirect")]
|
||||||
[AllowAnonymous]
|
[AllowAnonymous]
|
||||||
public async Task<IActionResult> UserRedirect([FromServices] IRepository<IdentityUser> _useRepository, string url, [FromServices] ILogger<ExtraController> _logger)
|
public async Task<IActionResult> UserRedirect([FromServices] IRepository<IdentityUser> _useRepository, string url, [FromServices] ILogger<ExtraController> _logger, [FromServices] ITokenService _tokenService)
|
||||||
{
|
{
|
||||||
|
|
||||||
var decodeUrl = System.Web.HttpUtility.UrlDecode(url);
|
var decodeUrl = System.Web.HttpUtility.UrlDecode(url);
|
||||||
@@ -200,10 +266,22 @@ namespace IRaCIS.Api.Controllers
|
|||||||
|
|
||||||
var errorUrl = domainStrList[0] + "//" + domainStrList[2] + "/error";
|
var errorUrl = domainStrList[0] + "//" + domainStrList[2] + "/error";
|
||||||
|
|
||||||
|
if (lang == "zh")
|
||||||
if (!await _useRepository.AnyAsync(t => t.Id == Guid.Parse(userId) && t.EmailToken == token && t.IsFirstAdd))
|
|
||||||
{
|
{
|
||||||
decodeUrl = errorUrl + $"?lang={lang}&ErrorMessage={System.Web.HttpUtility.UrlEncode(lang == "zh" ? "您的初始化链接已过期" : "Error!The initialization link has expired.")} ";
|
CultureInfo.CurrentCulture = new CultureInfo(StaticData.CultureInfo.zh_CN);
|
||||||
|
CultureInfo.CurrentUICulture = new CultureInfo(StaticData.CultureInfo.zh_CN);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CultureInfo.CurrentCulture = new CultureInfo(StaticData.CultureInfo.en_US);
|
||||||
|
CultureInfo.CurrentUICulture = new CultureInfo(StaticData.CultureInfo.en_US);
|
||||||
|
}
|
||||||
|
|
||||||
|
var isExpire = _tokenService.IsTokenExpired(token);
|
||||||
|
|
||||||
|
if (!await _useRepository.AnyAsync(t => t.Id == Guid.Parse(userId) && t.EmailToken == token && t.IsFirstAdd) || isExpire)
|
||||||
|
{
|
||||||
|
decodeUrl = errorUrl + $"?lang={lang}&ErrorMessage={System.Web.HttpUtility.UrlEncode(I18n.T("UserRedirect_InitializationLinkExpire"))} ";
|
||||||
}
|
}
|
||||||
|
|
||||||
return Redirect(decodeUrl);
|
return Redirect(decodeUrl);
|
||||||
|
|||||||
@@ -527,7 +527,7 @@ namespace IRaCIS.Core.API.Controllers
|
|||||||
}
|
}
|
||||||
var uploadFinishedTime = DateTime.Now;
|
var uploadFinishedTime = DateTime.Now;
|
||||||
|
|
||||||
var noneDicomStudy = await _noneDicomStudyRepository.FirstOrDefaultAsync((t => t.Id == noneDicomStudyId));
|
var noneDicomStudy = await _noneDicomStudyRepository.FirstOrDefaultAsync(t => t.Id == noneDicomStudyId,true);
|
||||||
|
|
||||||
noneDicomStudy.FileCount = noneDicomStudy.FileCount + (incommand.VisitTaskId != null ? 0 : incommand.UploadedFileList.Count);
|
noneDicomStudy.FileCount = noneDicomStudy.FileCount + (incommand.VisitTaskId != null ? 0 : incommand.UploadedFileList.Count);
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ namespace IRaCIS.Core.API.HostService;
|
|||||||
|
|
||||||
public class HangfireHostService(IRecurringMessageScheduler _recurringMessageScheduler,
|
public class HangfireHostService(IRecurringMessageScheduler _recurringMessageScheduler,
|
||||||
IRepository<TrialEmailNoticeConfig> _trialEmailNoticeConfigRepository,
|
IRepository<TrialEmailNoticeConfig> _trialEmailNoticeConfigRepository,
|
||||||
|
|
||||||
|
IRepository<EmailNoticeConfig> _emailNoticeConfigrepository,
|
||||||
IMediator _mediator,
|
IMediator _mediator,
|
||||||
ILogger<HangfireHostService> _logger) : IHostedService
|
ILogger<HangfireHostService> _logger) : IHostedService
|
||||||
{
|
{
|
||||||
@@ -55,6 +57,20 @@ public class HangfireHostService(IRecurringMessageScheduler _recurringMessageSch
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 系统邮件定时任务
|
||||||
|
var systemTaskInfoList = await _emailNoticeConfigrepository.Where(t => t.EmailCron != string.Empty && t.IsAutoSend)
|
||||||
|
.Select(t => new { t.Id, t.Code, t.EmailCron, t.BusinessScenarioEnum, })
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
foreach (var task in systemTaskInfoList)
|
||||||
|
{
|
||||||
|
//利用主键作为任务Id
|
||||||
|
var jobId = $"{task.Id}_({task.BusinessScenarioEnum})";
|
||||||
|
|
||||||
|
HangfireJobHelper.AddOrUpdateSystemCronJob(jobId, task.BusinessScenarioEnum, task.EmailCron);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//await _recurringMessageScheduler.ScheduleRecurringPublish(new QCImageQuestionSchedule() { CronExpression = "0/3 * * * * ? " }, new MasstransiTestCommand { value = "message at " + DateTime.Now.ToString() });
|
//await _recurringMessageScheduler.ScheduleRecurringPublish(new QCImageQuestionSchedule() { CronExpression = "0/3 * * * * ? " }, new MasstransiTestCommand { value = "message at " + DateTime.Now.ToString() });
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -69,24 +69,23 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="AspNetCoreRateLimit" Version="5.0.0" />
|
<PackageReference Include="AspNetCoreRateLimit" Version="5.0.0" />
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.14" />
|
||||||
|
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.10">
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.15">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="ConfigMapFileProvider" Version="2.0.1" />
|
<PackageReference Include="ConfigMapFileProvider" Version="2.0.1" />
|
||||||
<PackageReference Include="Hangfire.AspNetCore" Version="1.8.14" />
|
<PackageReference Include="Hangfire.AspNetCore" Version="1.8.18" />
|
||||||
<PackageReference Include="Hangfire.Dashboard.BasicAuthorization" Version="1.0.2" />
|
<PackageReference Include="Hangfire.Dashboard.BasicAuthorization" Version="1.0.2" />
|
||||||
<PackageReference Include="Hangfire.InMemory" Version="1.0.0" />
|
<PackageReference Include="Hangfire.InMemory" Version="1.0.0" />
|
||||||
<PackageReference Include="Hangfire.SqlServer" Version="1.8.14" />
|
<PackageReference Include="Hangfire.SqlServer" Version="1.8.18" />
|
||||||
<PackageReference Include="Invio.Extensions.Authentication.JwtBearer" Version="2.0.1" />
|
|
||||||
<PackageReference Include="LogDashboard" Version="1.4.8" />
|
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="8.0.10" />
|
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="8.0.10" />
|
||||||
<PackageReference Include="Serilog.AspNetCore" Version="8.0.3" />
|
<PackageReference Include="Serilog.AspNetCore" Version="9.0.0" />
|
||||||
<PackageReference Include="Serilog.Formatting.Compact" Version="3.0.0" />
|
<PackageReference Include="Serilog.Formatting.Compact" Version="3.0.0" />
|
||||||
<PackageReference Include="Serilog.Sinks.Email" Version="4.0.0" />
|
<PackageReference Include="Serilog.Sinks.Email" Version="4.0.0" />
|
||||||
<PackageReference Include="Serilog.Sinks.File" Version="6.0.0" />
|
<PackageReference Include="Serilog.Sinks.File" Version="6.0.0" />
|
||||||
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="6.9.0" />
|
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="8.1.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -114,6 +113,12 @@
|
|||||||
</Content>
|
</Content>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<None Update="Resources\GeoLite2-City.mmdb">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
<ProjectExtensions>
|
<ProjectExtensions>
|
||||||
<VisualStudio>
|
<VisualStudio>
|
||||||
<UserProperties properties_4launchsettings_1json__JsonSchema="" />
|
<UserProperties properties_4launchsettings_1json__JsonSchema="" />
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ using IRaCIS.Core.Application.Service;
|
|||||||
using IRaCIS.Core.Application.Service.BusinessFilter;
|
using IRaCIS.Core.Application.Service.BusinessFilter;
|
||||||
using IRaCIS.Core.Infra.EFCore;
|
using IRaCIS.Core.Infra.EFCore;
|
||||||
using IRaCIS.Core.Infrastructure.Extention;
|
using IRaCIS.Core.Infrastructure.Extention;
|
||||||
using LogDashboard;
|
|
||||||
using MassTransit;
|
using MassTransit;
|
||||||
using MassTransit.NewIdProviders;
|
using MassTransit.NewIdProviders;
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
@@ -37,6 +36,11 @@ var config = new ConfigurationBuilder()
|
|||||||
|
|
||||||
var enviromentName = config["ASPNETCORE_ENVIRONMENT"];
|
var enviromentName = config["ASPNETCORE_ENVIRONMENT"];
|
||||||
|
|
||||||
|
var openSwaggerStr = config["ASPNETCORE_OpenSwagger"];
|
||||||
|
|
||||||
|
var isOpenSwagger= openSwaggerStr == null|| openSwaggerStr?.ToLower()=="true";
|
||||||
|
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(enviromentName))
|
if (string.IsNullOrWhiteSpace(enviromentName))
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -111,8 +115,13 @@ builder.Services.AddAutoMapperSetup();
|
|||||||
builder.Services.AddEFSetup(_configuration, enviromentName);
|
builder.Services.AddEFSetup(_configuration, enviromentName);
|
||||||
//Http 响应压缩
|
//Http 响应压缩
|
||||||
builder.Services.AddResponseCompressionSetup();
|
builder.Services.AddResponseCompressionSetup();
|
||||||
//Swagger Api 文档
|
|
||||||
builder.Services.AddSwaggerSetup();
|
if (isOpenSwagger)
|
||||||
|
{
|
||||||
|
//Swagger Api 文档
|
||||||
|
builder.Services.AddSwaggerSetup();
|
||||||
|
}
|
||||||
|
|
||||||
//JWT Token 验证
|
//JWT Token 验证
|
||||||
builder.Services.AddJWTAuthSetup(_configuration);
|
builder.Services.AddJWTAuthSetup(_configuration);
|
||||||
|
|
||||||
@@ -126,7 +135,7 @@ builder.Services.AddFusionCache();
|
|||||||
builder.Services.AddhangfireSetup(_configuration);
|
builder.Services.AddhangfireSetup(_configuration);
|
||||||
|
|
||||||
//Serilog 日志可视化 LogDashboard日志
|
//Serilog 日志可视化 LogDashboard日志
|
||||||
builder.Services.AddLogDashboardSetup();
|
//builder.Services.AddLogDashboardSetup();
|
||||||
|
|
||||||
//Dicom影像渲染图片 跨平台
|
//Dicom影像渲染图片 跨平台
|
||||||
builder.Services.AddDicomSetup();
|
builder.Services.AddDicomSetup();
|
||||||
@@ -211,13 +220,18 @@ app.UseResponseCompression();
|
|||||||
app.UseStaticFiles();
|
app.UseStaticFiles();
|
||||||
|
|
||||||
//LogDashboard
|
//LogDashboard
|
||||||
app.UseLogDashboard("/LogDashboard");
|
//app.UseLogDashboard("/LogDashboard");
|
||||||
|
|
||||||
//hangfire
|
//hangfire
|
||||||
app.UseHangfireConfig(env);
|
app.UseHangfireConfig(env);
|
||||||
|
|
||||||
// Swagger
|
// Swagger
|
||||||
SwaggerSetup.Configure(app, env);
|
|
||||||
|
if (isOpenSwagger)
|
||||||
|
{
|
||||||
|
SwaggerSetup.Configure(app, env);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//serilog 记录请求的用户信息
|
//serilog 记录请求的用户信息
|
||||||
app.UseSerilogConfig(env);
|
app.UseSerilogConfig(env);
|
||||||
|
|||||||
@@ -20,7 +20,8 @@
|
|||||||
"commandName": "Project",
|
"commandName": "Project",
|
||||||
"launchBrowser": true,
|
"launchBrowser": true,
|
||||||
"environmentVariables": {
|
"environmentVariables": {
|
||||||
"ASPNETCORE_ENVIRONMENT": "Test_IRC"
|
"ASPNETCORE_ENVIRONMENT": "Test_IRC",
|
||||||
|
"ASPNETCORE_OpenSwagger": "true"
|
||||||
},
|
},
|
||||||
"applicationUrl": "http://localhost:6100"
|
"applicationUrl": "http://localhost:6100"
|
||||||
},
|
},
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 73 MiB |
@@ -1,15 +1,15 @@
|
|||||||
using LogDashboard;
|
//using LogDashboard;
|
||||||
using LogDashboard.Authorization;
|
//using LogDashboard.Authorization;
|
||||||
|
|
||||||
namespace IRaCIS.Core.API.Filter
|
//namespace IRaCIS.Core.API.Filter
|
||||||
{
|
//{
|
||||||
|
|
||||||
public class LogDashBoardAuthFilter : ILogDashboardAuthorizationFilter
|
// public class LogDashBoardAuthFilter : ILogDashboardAuthorizationFilter
|
||||||
{
|
// {
|
||||||
//在此可以利用 本系统的UerTypeEnum 判断
|
// //在此可以利用 本系统的UerTypeEnum 判断
|
||||||
public bool Authorization(LogDashboardContext context)
|
// public bool Authorization(LogDashboardContext context)
|
||||||
{
|
// {
|
||||||
return context.HttpContext.User.Identity.IsAuthenticated;
|
// return context.HttpContext.User.Identity.IsAuthenticated;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
@@ -1,25 +1,25 @@
|
|||||||
|
|
||||||
using LogDashboard;
|
//using LogDashboard;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
//using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
namespace IRaCIS.Core.API
|
//namespace IRaCIS.Core.API
|
||||||
{
|
//{
|
||||||
public static class LogDashboardSetup
|
// public static class LogDashboardSetup
|
||||||
{
|
// {
|
||||||
public static void AddLogDashboardSetup(this IServiceCollection services)
|
// public static void AddLogDashboardSetup(this IServiceCollection services)
|
||||||
{
|
// {
|
||||||
//IIS 配置虚拟路径部署,会出现IIS静态文件404
|
// //IIS 配置虚拟路径部署,会出现IIS静态文件404
|
||||||
services.AddLogDashboard(opt =>
|
// services.AddLogDashboard(opt =>
|
||||||
{
|
// {
|
||||||
//opt.PathMatch = "/api/LogDashboard";
|
// //opt.PathMatch = "/api/LogDashboard";
|
||||||
opt.PathMatch = "/LogDashboard";
|
// opt.PathMatch = "/LogDashboard";
|
||||||
|
|
||||||
//opt.AddAuthorizationFilter(new LogDashboardBasicAuthFilter("admin", "zhizhun2018"));
|
// //opt.AddAuthorizationFilter(new LogDashboardBasicAuthFilter("admin", "zhizhun2018"));
|
||||||
|
|
||||||
//opt.AddAuthorizationFilter(new LogDashBoardAuthFilter());
|
// //opt.AddAuthorizationFilter(new LogDashBoardAuthFilter());
|
||||||
|
|
||||||
});
|
// });
|
||||||
|
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
|||||||
@@ -16,27 +16,30 @@ namespace IRaCIS.Core.API;
|
|||||||
|
|
||||||
public enum SwaggerVersion
|
public enum SwaggerVersion
|
||||||
{
|
{
|
||||||
[Description("医生模块")]
|
[Description("文件记录(FileRecord)")]
|
||||||
|
FileRecord = -1,
|
||||||
|
|
||||||
|
[Description("医生模块(Reviewer)")]
|
||||||
Reviewer = 1,
|
Reviewer = 1,
|
||||||
[Description("项目模块")]
|
[Description("项目模块(Trial)")]
|
||||||
Trial = 2,
|
Trial = 2,
|
||||||
[Description("入组模块")]
|
[Description("入组模块(Enroll)")]
|
||||||
Enroll = 3,
|
Enroll = 3,
|
||||||
[Description("工作量模块")]
|
[Description("工作量模块(Workload)")]
|
||||||
Workload = 4,
|
Workload = 4,
|
||||||
[Description("通用信息获取")]
|
[Description("通用信息获取(Common)")]
|
||||||
Common = 5,
|
Common = 5,
|
||||||
[Description("机构信息模块")]
|
[Description("机构信息模块(Institution)")]
|
||||||
Institution = 6,
|
Institution = 6,
|
||||||
[Description("统计模块")]
|
[Description("统计模块(DashboardStatistics)")]
|
||||||
DashboardStatistics = 7,
|
DashboardStatistics = 7,
|
||||||
[Description("财务模块")]
|
[Description("财务模块(Financial)")]
|
||||||
Financial = 8,
|
Financial = 8,
|
||||||
[Description("管理模块")]
|
[Description("管理模块(Management)")]
|
||||||
Management =9,
|
Management =9,
|
||||||
[Description("影像模块")]
|
[Description("影像模块(Image)")]
|
||||||
Image =10,
|
Image =10,
|
||||||
[Description("读片模块")]
|
[Description("读片模块(Reading)")]
|
||||||
Reading =11
|
Reading =11
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -7,8 +7,8 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ConnectionStrings": {
|
"ConnectionStrings": {
|
||||||
"RemoteNew": "Server=47.117.164.182,1434;Database=Event_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
|
"RemoteNew": "Server=101.132.253.119,1435;Database=irc_Prpd_bak;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
|
||||||
"Hangfire": "Server=47.117.164.182,1434;Database=Event_IRC_Hangfire;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"
|
||||||
},
|
},
|
||||||
"ObjectStoreService": {
|
"ObjectStoreService": {
|
||||||
"ObjectStoreUse": "AliyunOSS",
|
"ObjectStoreUse": "AliyunOSS",
|
||||||
@@ -52,7 +52,10 @@
|
|||||||
|
|
||||||
"IsNeedChangePassWord": true,
|
"IsNeedChangePassWord": true,
|
||||||
|
|
||||||
"ChangePassWordDays": 90
|
"ChangePassWordDays": 90,
|
||||||
|
|
||||||
|
// 模板类型 1 Elevate 2 Extensive
|
||||||
|
"TemplateType": 2
|
||||||
},
|
},
|
||||||
"SystemEmailSendConfig": {
|
"SystemEmailSendConfig": {
|
||||||
"Port": 465,
|
"Port": 465,
|
||||||
|
|||||||
@@ -51,7 +51,9 @@
|
|||||||
"ReadingRestTimeMin": 10,
|
"ReadingRestTimeMin": 10,
|
||||||
|
|
||||||
"IsNeedChangePassWord": true,
|
"IsNeedChangePassWord": true,
|
||||||
"ChangePassWordDays": 90
|
"ChangePassWordDays": 90,
|
||||||
|
// 模板类型 1 Elevate 2 Extensive
|
||||||
|
"TemplateType": 2
|
||||||
},
|
},
|
||||||
|
|
||||||
"SystemEmailSendConfig": {
|
"SystemEmailSendConfig": {
|
||||||
@@ -61,6 +63,7 @@
|
|||||||
"FromName": "irc",
|
"FromName": "irc",
|
||||||
"AuthorizationCode": "ExtImg@2022",
|
"AuthorizationCode": "ExtImg@2022",
|
||||||
"SiteUrl": "http://irc.extimaging.com/login",
|
"SiteUrl": "http://irc.extimaging.com/login",
|
||||||
|
"SystemShortName": "IRC",
|
||||||
"OrganizationName": "Extlmaging",
|
"OrganizationName": "Extlmaging",
|
||||||
"OrganizationNameCN": "Extlmaging",
|
"OrganizationNameCN": "Extlmaging",
|
||||||
"CompanyName": "Extensive Imaging",
|
"CompanyName": "Extensive Imaging",
|
||||||
|
|||||||
@@ -23,9 +23,11 @@
|
|||||||
"AccessKeySecret": "FLizxkHsMm4CGYHtkV8E3PNJJZU7oV",
|
"AccessKeySecret": "FLizxkHsMm4CGYHtkV8E3PNJJZU7oV",
|
||||||
"RoleArn": "acs:ram::1899121822495495:role/dev-oss-access",
|
"RoleArn": "acs:ram::1899121822495495:role/dev-oss-access",
|
||||||
"BucketName": "zy-irc-test-store",
|
"BucketName": "zy-irc-test-store",
|
||||||
"ViewEndpoint": "https://zy-irc-test-store.oss-cn-shanghai.aliyuncs.com",
|
//"ViewEndpoint": "https://zy-irc-test-store.oss-cn-shanghai.aliyuncs.com",
|
||||||
|
"ViewEndpoint": "https://zy-irc-test-dev-cache.oss-cn-shanghai.aliyuncs.com",
|
||||||
"Region": "oss-cn-shanghai",
|
"Region": "oss-cn-shanghai",
|
||||||
"DurationSeconds": 7200
|
"DurationSeconds": 7200,
|
||||||
|
"PreviewEndpoint": "https://test-oss.test.extimaging.com"
|
||||||
},
|
},
|
||||||
"MinIO": {
|
"MinIO": {
|
||||||
"EndPoint": "hir-oss.test.extimaging.com",
|
"EndPoint": "hir-oss.test.extimaging.com",
|
||||||
@@ -67,6 +69,8 @@
|
|||||||
"IsNeedChangePassWord": true,
|
"IsNeedChangePassWord": true,
|
||||||
"ChangePassWordDays": 90,
|
"ChangePassWordDays": 90,
|
||||||
|
|
||||||
|
// 模板类型 1 Elevate 2 Extensive
|
||||||
|
"TemplateType": 2,
|
||||||
|
|
||||||
"OpenTrialRelationDelete": true,
|
"OpenTrialRelationDelete": true,
|
||||||
|
|
||||||
@@ -81,6 +85,7 @@
|
|||||||
"AuthorizationCode": "SHzyyl2021",
|
"AuthorizationCode": "SHzyyl2021",
|
||||||
"SiteUrl": "http://irc.test.extimaging.com/login",
|
"SiteUrl": "http://irc.test.extimaging.com/login",
|
||||||
|
|
||||||
|
"SystemShortName": "IRC",
|
||||||
"OrganizationName": "Extlmaging",
|
"OrganizationName": "Extlmaging",
|
||||||
"OrganizationNameCN": "Extlmaging",
|
"OrganizationNameCN": "Extlmaging",
|
||||||
"CompanyName": "Extensive Imaging",
|
"CompanyName": "Extensive Imaging",
|
||||||
|
|||||||
@@ -54,7 +54,8 @@
|
|||||||
|
|
||||||
"IsNeedChangePassWord": true,
|
"IsNeedChangePassWord": true,
|
||||||
"ChangePassWordDays": 90,
|
"ChangePassWordDays": 90,
|
||||||
|
// 模板类型 1 Elevate 2 Extensive
|
||||||
|
"TemplateType": 1,
|
||||||
|
|
||||||
"OpenTrialRelationDelete": false
|
"OpenTrialRelationDelete": false
|
||||||
|
|
||||||
@@ -67,6 +68,7 @@
|
|||||||
"FromName": "LiLi",
|
"FromName": "LiLi",
|
||||||
"AuthorizationCode": "Q#669869497420ul",
|
"AuthorizationCode": "Q#669869497420ul",
|
||||||
|
|
||||||
|
"SystemShortName": "LiLi",
|
||||||
"OrganizationName": "Elevate Imaging",
|
"OrganizationName": "Elevate Imaging",
|
||||||
"OrganizationNameCN": "Elevate Imaging",
|
"OrganizationNameCN": "Elevate Imaging",
|
||||||
"CompanyName": "Elevate Imaging Inc.",
|
"CompanyName": "Elevate Imaging Inc.",
|
||||||
|
|||||||
@@ -64,7 +64,8 @@
|
|||||||
"IsNeedChangePassWord": true,
|
"IsNeedChangePassWord": true,
|
||||||
|
|
||||||
"ChangePassWordDays": 90,
|
"ChangePassWordDays": 90,
|
||||||
|
// 模板类型 1 Elevate 2 Extensive
|
||||||
|
"TemplateType": 1,
|
||||||
"OpenLoginMFA": true
|
"OpenLoginMFA": true
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -75,6 +76,7 @@
|
|||||||
"FromName": "LiLi",
|
"FromName": "LiLi",
|
||||||
"AuthorizationCode": "Q#669869497420ul",
|
"AuthorizationCode": "Q#669869497420ul",
|
||||||
|
|
||||||
|
"SystemShortName": "LiLi",
|
||||||
"OrganizationName": "Elevate Imaging",
|
"OrganizationName": "Elevate Imaging",
|
||||||
"OrganizationNameCN": "Elevate Imaging",
|
"OrganizationNameCN": "Elevate Imaging",
|
||||||
"CompanyName": "Elevate Imaging Inc.",
|
"CompanyName": "Elevate Imaging Inc.",
|
||||||
|
|||||||
@@ -63,7 +63,9 @@
|
|||||||
"ReadingRestTimeMin": 10,
|
"ReadingRestTimeMin": 10,
|
||||||
|
|
||||||
"IsNeedChangePassWord": true,
|
"IsNeedChangePassWord": true,
|
||||||
"ChangePassWordDays": 90
|
"ChangePassWordDays": 90,
|
||||||
|
// 模板类型 1 Elevate 2 Extensive
|
||||||
|
"TemplateType": 1
|
||||||
},
|
},
|
||||||
|
|
||||||
"SystemEmailSendConfig": {
|
"SystemEmailSendConfig": {
|
||||||
@@ -73,6 +75,7 @@
|
|||||||
"FromName": "LiLi",
|
"FromName": "LiLi",
|
||||||
"AuthorizationCode": "Q#669869497420ul",
|
"AuthorizationCode": "Q#669869497420ul",
|
||||||
|
|
||||||
|
"SystemShortName": "LiLi",
|
||||||
"OrganizationName": "Elevate Imaging",
|
"OrganizationName": "Elevate Imaging",
|
||||||
"OrganizationNameCN": "Elevate Imaging",
|
"OrganizationNameCN": "Elevate Imaging",
|
||||||
"CompanyName": "Elevate Imaging Inc.",
|
"CompanyName": "Elevate Imaging Inc.",
|
||||||
|
|||||||
@@ -70,7 +70,9 @@
|
|||||||
"ReadingRestTimeMin": 10,
|
"ReadingRestTimeMin": 10,
|
||||||
|
|
||||||
"IsNeedChangePassWord": true,
|
"IsNeedChangePassWord": true,
|
||||||
"ChangePassWordDays": 90
|
"ChangePassWordDays": 90,
|
||||||
|
// 模板类型 1 Elevate 2 Extensive
|
||||||
|
"TemplateType": 2
|
||||||
|
|
||||||
},
|
},
|
||||||
"SystemEmailSendConfig": {
|
"SystemEmailSendConfig": {
|
||||||
@@ -80,6 +82,8 @@
|
|||||||
"FromName": "UAT_IRC",
|
"FromName": "UAT_IRC",
|
||||||
"AuthorizationCode": "SHzyyl2021",
|
"AuthorizationCode": "SHzyyl2021",
|
||||||
"SiteUrl": "http://irc.uat.extimaging.com/login",
|
"SiteUrl": "http://irc.uat.extimaging.com/login",
|
||||||
|
|
||||||
|
"SystemShortName": "IRC",
|
||||||
"OrganizationName": "Extlmaging",
|
"OrganizationName": "Extlmaging",
|
||||||
"OrganizationNameCN": "Extlmaging",
|
"OrganizationNameCN": "Extlmaging",
|
||||||
"CompanyName": "Extensive Imaging",
|
"CompanyName": "Extensive Imaging",
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
"SecurityKey": "ShangHaiZhanYing_SecurityKey_SHzyyl@2021",
|
"SecurityKey": "ShangHaiZhanYing_SecurityKey_SHzyyl@2021",
|
||||||
"Issuer": "Extimaging",
|
"Issuer": "Extimaging",
|
||||||
"Audience": "EICS",
|
"Audience": "EICS",
|
||||||
"TokenExpireDays": "7"
|
"TokenExpireMinute": "10080"//7天
|
||||||
},
|
},
|
||||||
"IpRateLimiting": {
|
"IpRateLimiting": {
|
||||||
"EnableEndpointRateLimiting": true,
|
"EnableEndpointRateLimiting": true,
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ namespace IRaCIS.Core.Application.Auth
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 过期时间
|
/// 过期时间
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int TokenExpireDays { get; set; }
|
public int TokenExpireMinute { get; set; }
|
||||||
|
|
||||||
//public Dictionary<string, object> Claims { get; set; }
|
//public Dictionary<string, object> Claims { get; set; }
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ namespace IRaCIS.Core.Application.Auth
|
|||||||
public interface ITokenService
|
public interface ITokenService
|
||||||
{
|
{
|
||||||
string GetToken(UserTokenInfo user);
|
string GetToken(UserTokenInfo user);
|
||||||
|
|
||||||
|
bool IsTokenExpired(string token);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -47,13 +49,27 @@ namespace IRaCIS.Core.Application.Auth
|
|||||||
signingCredentials: _jwtSetting.Credentials,
|
signingCredentials: _jwtSetting.Credentials,
|
||||||
claims: claims,
|
claims: claims,
|
||||||
notBefore: DateTime.Now,
|
notBefore: DateTime.Now,
|
||||||
expires: DateTime.Now.AddDays(_jwtSetting.TokenExpireDays)
|
expires: DateTime.Now.AddMinutes(_jwtSetting.TokenExpireMinute)
|
||||||
);
|
);
|
||||||
|
|
||||||
string jwtToken = new JwtSecurityTokenHandler().WriteToken(token);
|
string jwtToken = new JwtSecurityTokenHandler().WriteToken(token);
|
||||||
return jwtToken;
|
return jwtToken;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool IsTokenExpired(string token)
|
||||||
|
{
|
||||||
|
var handler = new JwtSecurityTokenHandler();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var jwtToken = handler.ReadJwtToken(token);
|
||||||
|
return jwtToken.ValidTo < DateTime.UtcNow;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return true; // 无效 Token 也视为已过期
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -34,6 +34,8 @@ public class ServiceVerifyConfigOption
|
|||||||
[Description("修改密码的天数")]
|
[Description("修改密码的天数")]
|
||||||
public int ChangePassWordDays { get; set; }
|
public int ChangePassWordDays { get; set; }
|
||||||
|
|
||||||
|
public SysTemplateType TemplateType { get; set; }
|
||||||
|
|
||||||
public string ThirdPdfUrl { get; set; }
|
public string ThirdPdfUrl { get; set; }
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -51,6 +53,8 @@ public class SystemEmailSendConfig
|
|||||||
|
|
||||||
public string SiteUrl { get; set; } = string.Empty;
|
public string SiteUrl { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public string SystemShortName { get; set; } = string.Empty;
|
||||||
|
|
||||||
public string OrganizationName { get; set; } = string.Empty;
|
public string OrganizationName { get; set; } = string.Empty;
|
||||||
public string OrganizationNameCN { get; set; } = string.Empty;
|
public string OrganizationNameCN { get; set; } = string.Empty;
|
||||||
|
|
||||||
@@ -71,6 +75,7 @@ public class SystemEmailSendConfig
|
|||||||
|
|
||||||
public class SystemEmailSendConfigView
|
public class SystemEmailSendConfigView
|
||||||
{
|
{
|
||||||
|
public string SystemShortName { get; set; } = string.Empty;
|
||||||
public string CompanyName { get; set; } = string.Empty;
|
public string CompanyName { get; set; } = string.Empty;
|
||||||
|
|
||||||
public string CompanyNameCN { get; set; } = string.Empty;
|
public string CompanyNameCN { get; set; } = string.Empty;
|
||||||
|
|||||||
@@ -11,6 +11,12 @@ public static class SendEmailHelper
|
|||||||
|
|
||||||
public static async Task SendEmailAsync(MimeMessage messageToSend, SystemEmailSendConfig _systemEmailConfig, EventHandler<MessageSentEventArgs>? messageSentSuccess = null)
|
public static async Task SendEmailAsync(MimeMessage messageToSend, SystemEmailSendConfig _systemEmailConfig, EventHandler<MessageSentEventArgs>? messageSentSuccess = null)
|
||||||
{
|
{
|
||||||
|
//没有收件人 那么不发送
|
||||||
|
if (messageToSend.To.Count == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
using (var smtp = new MailKit.Net.Smtp.SmtpClient())
|
using (var smtp = new MailKit.Net.Smtp.SmtpClient())
|
||||||
|
|||||||
@@ -300,6 +300,17 @@ public static class ExcelExportHelper
|
|||||||
{
|
{
|
||||||
public Guid Id { get; set; }
|
public Guid Id { get; set; }
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
public override bool Equals(object obj)
|
||||||
|
{
|
||||||
|
if (obj is not ColumItem other) return false;
|
||||||
|
return Id == other.Id && Name == other.Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int GetHashCode()
|
||||||
|
{
|
||||||
|
return HashCode.Combine(Id, Name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<string> ColumnIdList => ColumnIdNameList == null ? new List<string>() : ColumnIdNameList.Select(t => t.Id.ToString()).ToList();
|
public List<string> ColumnIdList => ColumnIdNameList == null ? new List<string>() : ColumnIdNameList.Select(t => t.Id.ToString()).ToList();
|
||||||
|
|||||||
@@ -20,12 +20,12 @@ namespace IRaCIS.Core.Application.Helper
|
|||||||
//添加 或者更新定时任务 Id 要唯一标识一个定义任务
|
//添加 或者更新定时任务 Id 要唯一标识一个定义任务
|
||||||
public static void AddOrUpdateCronJob<T>(string jobId, Expression<Action<T>> methodCall, string cron, string queueName = "default")
|
public static void AddOrUpdateCronJob<T>(string jobId, Expression<Action<T>> methodCall, string cron, string queueName = "default")
|
||||||
{
|
{
|
||||||
RecurringJob.AddOrUpdate<T>(jobId, queueName, methodCall, cron);
|
RecurringJob.AddOrUpdate<T>(jobId, queueName, methodCall, cron, new RecurringJobOptions() { TimeZone = TimeZoneInfo.Local });
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void AddOrUpdateInitCronJob<T>(string jobId, Expression<Action<T>> methodCall, string cron)
|
public static void AddOrUpdateInitCronJob<T>(string jobId, Expression<Action<T>> methodCall, string cron)
|
||||||
{
|
{
|
||||||
RecurringJob.AddOrUpdate<T>(jobId, "sys_init", methodCall, cron);
|
RecurringJob.AddOrUpdate<T>(jobId, "sys_init", methodCall, cron, new RecurringJobOptions() { TimeZone = TimeZoneInfo.Local });
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void RemoveCronJob(string jobId)
|
public static void RemoveCronJob(string jobId)
|
||||||
@@ -73,17 +73,30 @@ namespace IRaCIS.Core.Application.Helper
|
|||||||
case EmailBusinessScenario.QCToCRCImageQuestion:
|
case EmailBusinessScenario.QCToCRCImageQuestion:
|
||||||
HangfireJobHelper.AddOrUpdateCronJob<IMediator>(jobId, t => t.Send(new QCImageQuestionRecurringEvent() { TrialId = trialId }, default), emailCron);
|
HangfireJobHelper.AddOrUpdateCronJob<IMediator>(jobId, t => t.Send(new QCImageQuestionRecurringEvent() { TrialId = trialId }, default), emailCron);
|
||||||
break;
|
break;
|
||||||
//加急阅片 10分钟
|
//加急阅片 10分钟
|
||||||
case EmailBusinessScenario.ExpeditedReading:
|
case EmailBusinessScenario.ExpeditedReading:
|
||||||
HangfireJobHelper.AddOrUpdateCronJob<IMediator>(jobId, t => t.Send(new UrgentIRUnReadTaskRecurringEvent() { TrialId = trialId }, default), emailCron);
|
HangfireJobHelper.AddOrUpdateCronJob<IMediator>(jobId, t => t.Send(new UrgentIRUnReadTaskRecurringEvent() { TrialId = trialId }, default), emailCron);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void AddOrUpdateSystemCronJob(string jobId, EmailBusinessScenario businessScenario, string emailCron)
|
||||||
|
{
|
||||||
|
switch (businessScenario)
|
||||||
|
{
|
||||||
|
|
||||||
|
case EmailBusinessScenario.GeneralTraining_ExpirationNotification:
|
||||||
|
|
||||||
|
HangfireJobHelper.AddOrUpdateCronJob<IMediator>(jobId, t => t.Send(new SystemDocumentErverDayEvent() { }, default), emailCron);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
using IRaCIS.Core.Domain.Models;
|
||||||
|
using MaxMind.GeoIP2;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace IRaCIS.Core.Application.Helper
|
||||||
|
{
|
||||||
|
public static class IPCityHelper
|
||||||
|
{
|
||||||
|
|
||||||
|
public static string GetCityResponse(string ip)
|
||||||
|
{
|
||||||
|
var path = Path.Combine(AppContext.BaseDirectory, StaticData.Folder.Resources, "GeoLite2-City.mmdb");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (var reader = new DatabaseReader(path))
|
||||||
|
{
|
||||||
|
|
||||||
|
var city = reader.City(ip);
|
||||||
|
|
||||||
|
//Console.WriteLine(city.Country.IsoCode); // 'US' 'CN'
|
||||||
|
//Console.WriteLine(city.Country.Name); // 'United States' 'China'
|
||||||
|
////Console.WriteLine(city.Country.Names["zh-CN"]); // '美国'
|
||||||
|
//Console.WriteLine(city.MostSpecificSubdivision.Name); // 'Minnesota' 'Hubei'
|
||||||
|
//Console.WriteLine(city.City.Name); // 'Minneapolis' 'WUHan'
|
||||||
|
|
||||||
|
return $"{city.Country.Name} | {city.MostSpecificSubdivision.Name} | {city.City.Name}";
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
|
||||||
|
return $"UN | UN | {ip}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
using AlibabaCloud.SDK.Sts20150401;
|
using AlibabaCloud.SDK.Sts20150401;
|
||||||
using Aliyun.OSS;
|
using Aliyun.OSS;
|
||||||
|
using Aliyun.OSS.Common;
|
||||||
using Amazon;
|
using Amazon;
|
||||||
using Amazon.Runtime;
|
using Amazon.Runtime;
|
||||||
using Amazon.S3;
|
using Amazon.S3;
|
||||||
@@ -9,9 +10,12 @@ using Amazon.SecurityToken.Model;
|
|||||||
using IRaCIS.Core.Infrastructure;
|
using IRaCIS.Core.Infrastructure;
|
||||||
using IRaCIS.Core.Infrastructure.NewtonsoftJson;
|
using IRaCIS.Core.Infrastructure.NewtonsoftJson;
|
||||||
using MassTransit;
|
using MassTransit;
|
||||||
|
using MassTransit.Caching.Internals;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using Minio;
|
using Minio;
|
||||||
|
using Minio.DataModel;
|
||||||
using Minio.DataModel.Args;
|
using Minio.DataModel.Args;
|
||||||
|
using Minio.Exceptions;
|
||||||
using System.Reactive.Linq;
|
using System.Reactive.Linq;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
@@ -59,7 +63,7 @@ public class AliyunOSSOptions
|
|||||||
|
|
||||||
public int DurationSeconds { get; set; }
|
public int DurationSeconds { get; set; }
|
||||||
|
|
||||||
|
public string PreviewEndpoint { get; set; }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,6 +109,7 @@ public class AliyunOSSTempToken
|
|||||||
public string SecurityToken { get; set; }
|
public string SecurityToken { get; set; }
|
||||||
public DateTime Expiration { get; set; }
|
public DateTime Expiration { get; set; }
|
||||||
|
|
||||||
|
public string PreviewEndpoint { get; set; }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -143,11 +148,17 @@ public interface IOSSService
|
|||||||
|
|
||||||
public Task<string> GetSignedUrl(string ossRelativePath);
|
public Task<string> GetSignedUrl(string ossRelativePath);
|
||||||
|
|
||||||
public Task DeleteFromPrefix(string prefix);
|
public Task DeleteFromPrefix(string prefix, bool isCache = false);
|
||||||
|
|
||||||
|
public Task DeleteObjects(List<string> objectKeys);
|
||||||
|
|
||||||
List<string> GetRootFolderNames();
|
List<string> GetRootFolderNames();
|
||||||
|
|
||||||
public ObjectStoreDTO GetObjectStoreTempToken();
|
public ObjectStoreDTO GetObjectStoreTempToken();
|
||||||
|
|
||||||
|
public Task MoveObject(string sourcePath, string destPath, bool overwrite = true);
|
||||||
|
|
||||||
|
public Task<long> GetObjectSizeAsync(string sourcePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -528,6 +539,185 @@ public class OSSService : IOSSService
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 移动OSS文件到新路径
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sourcePath">原文件路径(格式:bucket/key)</param>
|
||||||
|
/// <param name="destPath">新文件路径(格式:bucket/key)</param>
|
||||||
|
/// <param name="overwrite">是否覆盖已存在的目标文件(默认true)</param>
|
||||||
|
public async Task MoveObject(string sourcePath, string destPath, bool overwrite = true)
|
||||||
|
{
|
||||||
|
GetObjectStoreTempToken();
|
||||||
|
|
||||||
|
switch (ObjectStoreServiceOptions.ObjectStoreUse)
|
||||||
|
{
|
||||||
|
case "AliyunOSS":
|
||||||
|
#region 阿里云
|
||||||
|
var aliConfig = ObjectStoreServiceOptions.AliyunOSS;
|
||||||
|
var client = new OssClient(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? aliConfig.EndPoint : aliConfig.InternalEndpoint, AliyunOSSTempToken.AccessKeyId, AliyunOSSTempToken.AccessKeySecret, AliyunOSSTempToken.SecurityToken);
|
||||||
|
if (sourcePath.StartsWith("/"))
|
||||||
|
{
|
||||||
|
sourcePath = sourcePath.Substring(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (destPath.StartsWith("/"))
|
||||||
|
{
|
||||||
|
destPath = destPath.Substring(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
var sourceBucket = aliConfig.BucketName;
|
||||||
|
var sourceKey = sourcePath;
|
||||||
|
|
||||||
|
var destBucket = aliConfig.BucketName;
|
||||||
|
|
||||||
|
var destKey = destPath;
|
||||||
|
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// 检查目标是否存在(当不允许覆盖时)
|
||||||
|
if (!overwrite && client.DoesObjectExist(destBucket, destKey))
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("File Exist");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//var copyRequest = new Aliyun.OSS.CopyObjectRequest(sourceBucket, sourceKey, sourceBucket, destKey);
|
||||||
|
//var result = client.CopyObject(copyRequest);
|
||||||
|
|
||||||
|
//// 2. 删除原文件(可选,根据是否需要保留原文件)
|
||||||
|
//client.DeleteObject(sourceBucket, sourceKey);
|
||||||
|
|
||||||
|
// 执行复制
|
||||||
|
var copyRequestAli = new Aliyun.OSS.CopyObjectRequest(
|
||||||
|
sourceBucket, sourceKey,
|
||||||
|
destBucket, destKey);
|
||||||
|
|
||||||
|
// 保持原文件元数据
|
||||||
|
copyRequestAli.NewObjectMetadata = new ObjectMetadata
|
||||||
|
{
|
||||||
|
ContentType = client.GetObjectMetadata(sourceBucket, sourceKey).ContentType
|
||||||
|
};
|
||||||
|
|
||||||
|
var result = client.CopyObject(copyRequestAli);
|
||||||
|
|
||||||
|
// 删除原文件(仅在复制成功后)
|
||||||
|
client.DeleteObject(sourceBucket, sourceKey);
|
||||||
|
}
|
||||||
|
catch (OssException ex)
|
||||||
|
{
|
||||||
|
throw new Exception($"[{ex.ErrorCode}] {ex.Message}", ex);
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
break;
|
||||||
|
case "MinIO":
|
||||||
|
#region MinIO
|
||||||
|
var minIOConfig = ObjectStoreServiceOptions.MinIO;
|
||||||
|
var minioClient = new MinioClient()
|
||||||
|
.WithEndpoint($"{minIOConfig.EndPoint}:{minIOConfig.Port}")
|
||||||
|
.WithCredentials(minIOConfig.AccessKeyId, minIOConfig.SecretAccessKey)
|
||||||
|
.WithSSL(minIOConfig.UseSSL)
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
// 定义源路径和目标路径
|
||||||
|
string destinationKey = "b路径/文件名";
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// 1. 复制文件到新路径[2,5](@ref)
|
||||||
|
using (var memoryStream = new MemoryStream())
|
||||||
|
{
|
||||||
|
// 下载源文件流
|
||||||
|
await minioClient.GetObjectAsync(new GetObjectArgs()
|
||||||
|
.WithBucket(minIOConfig.BucketName)
|
||||||
|
.WithObject(sourcePath)
|
||||||
|
.WithCallbackStream(stream => stream.CopyTo(memoryStream)));
|
||||||
|
|
||||||
|
memoryStream.Position = 0; // 重置流位置
|
||||||
|
|
||||||
|
// 上传到新路径
|
||||||
|
await minioClient.PutObjectAsync(new PutObjectArgs()
|
||||||
|
.WithBucket(minIOConfig.BucketName)
|
||||||
|
.WithObject(destinationKey)
|
||||||
|
.WithStreamData(memoryStream)
|
||||||
|
.WithObjectSize(memoryStream.Length));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 删除原文件[1,6](@ref)
|
||||||
|
await minioClient.RemoveObjectAsync(new RemoveObjectArgs()
|
||||||
|
.WithBucket(minIOConfig.BucketName)
|
||||||
|
.WithObject(sourcePath));
|
||||||
|
}
|
||||||
|
catch (MinioException ex)
|
||||||
|
{
|
||||||
|
// 处理异常(例如:记录日志或抛出)
|
||||||
|
throw new Exception();
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
break;
|
||||||
|
case "AWS":
|
||||||
|
#region AWS
|
||||||
|
var awsConfig = ObjectStoreServiceOptions.AWS;
|
||||||
|
|
||||||
|
var credentials = new SessionAWSCredentials(
|
||||||
|
AWSTempToken.AccessKeyId,
|
||||||
|
AWSTempToken.SecretAccessKey,
|
||||||
|
AWSTempToken.SessionToken
|
||||||
|
);
|
||||||
|
|
||||||
|
var clientConfig = new AmazonS3Config
|
||||||
|
{
|
||||||
|
RegionEndpoint = RegionEndpoint.USEast1,
|
||||||
|
UseHttp = true,
|
||||||
|
};
|
||||||
|
|
||||||
|
var amazonS3Client = new AmazonS3Client(credentials, clientConfig);
|
||||||
|
|
||||||
|
// 定义原路径和目标路径
|
||||||
|
|
||||||
|
|
||||||
|
// 1. 复制对象到新路径
|
||||||
|
var copyRequest = new Amazon.S3.Model.CopyObjectRequest
|
||||||
|
{
|
||||||
|
SourceBucket = awsConfig.BucketName,
|
||||||
|
SourceKey = sourcePath,
|
||||||
|
DestinationBucket = awsConfig.BucketName,
|
||||||
|
DestinationKey = destPath
|
||||||
|
};
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// 执行复制操作
|
||||||
|
await amazonS3Client.CopyObjectAsync(copyRequest);
|
||||||
|
|
||||||
|
// 2. 删除原对象
|
||||||
|
var deleteRequest = new Amazon.S3.Model.DeleteObjectRequest
|
||||||
|
{
|
||||||
|
BucketName = awsConfig.BucketName,
|
||||||
|
Key = sourcePath
|
||||||
|
};
|
||||||
|
await amazonS3Client.DeleteObjectAsync(deleteRequest);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (AmazonS3Exception ex)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"ERROR: {ex.Message}");
|
||||||
|
// 可根据异常类型细化处理(如文件不存在、权限问题等)
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new BusinessValidationFailedException("ERROR");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取所有根目录名称
|
/// 获取所有根目录名称
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -550,9 +740,9 @@ public class OSSService : IOSSService
|
|||||||
do
|
do
|
||||||
{
|
{
|
||||||
// 列出根目录下的对象和文件夹
|
// 列出根目录下的对象和文件夹
|
||||||
objectListing = _ossClient.ListObjects(new Aliyun.OSS.ListObjectsRequest(aliConfig.BucketName)
|
objectListing = _ossClient.ListObjects(new Aliyun.OSS.ListObjectsRequest(aliConfig.BucketName)
|
||||||
{
|
{
|
||||||
|
|
||||||
MaxKeys = 1000,
|
MaxKeys = 1000,
|
||||||
Marker = nextMarker,
|
Marker = nextMarker,
|
||||||
Delimiter = "/" // 使用分隔符来模拟文件夹
|
Delimiter = "/" // 使用分隔符来模拟文件夹
|
||||||
@@ -582,7 +772,7 @@ public class OSSService : IOSSService
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="prefix"></param>
|
/// <param name="prefix"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public async Task DeleteFromPrefix(string prefix)
|
public async Task DeleteFromPrefix(string prefix, bool isCache = false)
|
||||||
{
|
{
|
||||||
GetObjectStoreTempToken();
|
GetObjectStoreTempToken();
|
||||||
|
|
||||||
@@ -592,6 +782,21 @@ public class OSSService : IOSSService
|
|||||||
|
|
||||||
var _ossClient = new OssClient(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? aliConfig.EndPoint : aliConfig.InternalEndpoint, AliyunOSSTempToken.AccessKeyId, AliyunOSSTempToken.AccessKeySecret, AliyunOSSTempToken.SecurityToken);
|
var _ossClient = new OssClient(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? aliConfig.EndPoint : aliConfig.InternalEndpoint, AliyunOSSTempToken.AccessKeyId, AliyunOSSTempToken.AccessKeySecret, AliyunOSSTempToken.SecurityToken);
|
||||||
|
|
||||||
|
var bucketName = string.Empty;
|
||||||
|
|
||||||
|
if (isCache)
|
||||||
|
{
|
||||||
|
Uri uri = new Uri(aliConfig.ViewEndpoint);
|
||||||
|
string host = uri.Host; // 获取 "zy-irc-test-dev-cache.oss-cn-shanghai.aliyuncs.com"
|
||||||
|
string[] parts = host.Split('.');
|
||||||
|
bucketName = parts[0];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bucketName = aliConfig.BucketName;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -600,7 +805,7 @@ public class OSSService : IOSSService
|
|||||||
do
|
do
|
||||||
{
|
{
|
||||||
// 使用 prefix 模拟目录结构,设置 MaxKeys 和 NextMarker
|
// 使用 prefix 模拟目录结构,设置 MaxKeys 和 NextMarker
|
||||||
objectListing = _ossClient.ListObjects(new Aliyun.OSS.ListObjectsRequest(aliConfig.BucketName)
|
objectListing = _ossClient.ListObjects(new Aliyun.OSS.ListObjectsRequest(bucketName)
|
||||||
{
|
{
|
||||||
Prefix = prefix,
|
Prefix = prefix,
|
||||||
MaxKeys = 1000,
|
MaxKeys = 1000,
|
||||||
@@ -612,7 +817,7 @@ public class OSSService : IOSSService
|
|||||||
// 删除获取到的文件
|
// 删除获取到的文件
|
||||||
if (keys.Count > 0)
|
if (keys.Count > 0)
|
||||||
{
|
{
|
||||||
_ossClient.DeleteObjects(new Aliyun.OSS.DeleteObjectsRequest(aliConfig.BucketName, keys, false));
|
_ossClient.DeleteObjects(new Aliyun.OSS.DeleteObjectsRequest(bucketName, keys, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 设置 NextMarker 以获取下一页的数据
|
// 设置 NextMarker 以获取下一页的数据
|
||||||
@@ -669,7 +874,6 @@ public class OSSService : IOSSService
|
|||||||
|
|
||||||
var awsConfig = ObjectStoreServiceOptions.AWS;
|
var awsConfig = ObjectStoreServiceOptions.AWS;
|
||||||
|
|
||||||
|
|
||||||
// 提供awsAccessKeyId和awsSecretAccessKey构造凭证
|
// 提供awsAccessKeyId和awsSecretAccessKey构造凭证
|
||||||
var credentials = new SessionAWSCredentials(AWSTempToken.AccessKeyId, AWSTempToken.SecretAccessKey, AWSTempToken.SessionToken);
|
var credentials = new SessionAWSCredentials(AWSTempToken.AccessKeyId, AWSTempToken.SecretAccessKey, AWSTempToken.SessionToken);
|
||||||
|
|
||||||
@@ -721,6 +925,159 @@ public class OSSService : IOSSService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task DeleteObjects(List<string> objectKeys)
|
||||||
|
{
|
||||||
|
GetObjectStoreTempToken();
|
||||||
|
|
||||||
|
if (ObjectStoreServiceOptions.ObjectStoreUse == "AliyunOSS")
|
||||||
|
{
|
||||||
|
var aliConfig = ObjectStoreServiceOptions.AliyunOSS;
|
||||||
|
|
||||||
|
var _ossClient = new OssClient(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? aliConfig.EndPoint : aliConfig.InternalEndpoint, AliyunOSSTempToken.AccessKeyId, AliyunOSSTempToken.AccessKeySecret, AliyunOSSTempToken.SecurityToken);
|
||||||
|
|
||||||
|
if (objectKeys.Count > 0)
|
||||||
|
{
|
||||||
|
var result = _ossClient.DeleteObjects(new Aliyun.OSS.DeleteObjectsRequest(aliConfig.BucketName, objectKeys, false));
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (ObjectStoreServiceOptions.ObjectStoreUse == "MinIO")
|
||||||
|
{
|
||||||
|
var minIOConfig = ObjectStoreServiceOptions.MinIO;
|
||||||
|
|
||||||
|
|
||||||
|
var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.EndPoint}:{minIOConfig.Port}")
|
||||||
|
.WithCredentials(minIOConfig.AccessKeyId, minIOConfig.SecretAccessKey).WithSSL(minIOConfig.UseSSL)
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
|
||||||
|
if (objectKeys.Count > 0)
|
||||||
|
{
|
||||||
|
var objArgs = new RemoveObjectsArgs()
|
||||||
|
.WithBucket(minIOConfig.BucketName)
|
||||||
|
.WithObjects(objectKeys);
|
||||||
|
|
||||||
|
// 删除对象
|
||||||
|
await minioClient.RemoveObjectsAsync(objArgs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (ObjectStoreServiceOptions.ObjectStoreUse == "AWS")
|
||||||
|
{
|
||||||
|
|
||||||
|
var awsConfig = ObjectStoreServiceOptions.AWS;
|
||||||
|
|
||||||
|
|
||||||
|
// 提供awsAccessKeyId和awsSecretAccessKey构造凭证
|
||||||
|
var credentials = new SessionAWSCredentials(AWSTempToken.AccessKeyId, AWSTempToken.SecretAccessKey, AWSTempToken.SessionToken);
|
||||||
|
|
||||||
|
//提供awsEndPoint(域名)进行访问配置
|
||||||
|
var clientConfig = new AmazonS3Config
|
||||||
|
{
|
||||||
|
RegionEndpoint = RegionEndpoint.USEast1,
|
||||||
|
UseHttp = true,
|
||||||
|
};
|
||||||
|
|
||||||
|
var amazonS3Client = new AmazonS3Client(credentials, clientConfig);
|
||||||
|
|
||||||
|
if (objectKeys.Count > 0)
|
||||||
|
{
|
||||||
|
// 准备删除请求
|
||||||
|
var deleteObjectsRequest = new Amazon.S3.Model.DeleteObjectsRequest
|
||||||
|
{
|
||||||
|
BucketName = awsConfig.BucketName,
|
||||||
|
Objects = objectKeys.Select(t => new KeyVersion() { Key = t }).ToList()
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// 批量删除对象
|
||||||
|
var deleteObjectsResponse = await amazonS3Client.DeleteObjectsAsync(deleteObjectsRequest);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new BusinessValidationFailedException("未定义的存储介质类型");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool isFirstCall = true;
|
||||||
|
public async Task<long> GetObjectSizeAsync(string sourcePath)
|
||||||
|
{
|
||||||
|
if (isFirstCall)
|
||||||
|
{
|
||||||
|
GetObjectStoreTempToken();
|
||||||
|
isFirstCall = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var objectkey = sourcePath.Trim('/');
|
||||||
|
|
||||||
|
if (ObjectStoreServiceOptions.ObjectStoreUse == "AliyunOSS")
|
||||||
|
{
|
||||||
|
var aliConfig = ObjectStoreServiceOptions.AliyunOSS;
|
||||||
|
|
||||||
|
var _ossClient = new OssClient(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? aliConfig.EndPoint : aliConfig.InternalEndpoint, AliyunOSSTempToken.AccessKeyId, AliyunOSSTempToken.AccessKeySecret, AliyunOSSTempToken.SecurityToken);
|
||||||
|
|
||||||
|
var metadata = _ossClient.GetObjectMetadata(aliConfig.BucketName, objectkey);
|
||||||
|
|
||||||
|
long fileSize = metadata.ContentLength; // 文件大小(字节)
|
||||||
|
|
||||||
|
return fileSize;
|
||||||
|
}
|
||||||
|
else if (ObjectStoreServiceOptions.ObjectStoreUse == "MinIO")
|
||||||
|
{
|
||||||
|
var minIOConfig = ObjectStoreServiceOptions.MinIO;
|
||||||
|
|
||||||
|
|
||||||
|
var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.EndPoint}:{minIOConfig.Port}")
|
||||||
|
.WithCredentials(minIOConfig.AccessKeyId, minIOConfig.SecretAccessKey).WithSSL(minIOConfig.UseSSL)
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
|
||||||
|
var stat = await minioClient.StatObjectAsync(new Minio.DataModel.Args.StatObjectArgs()
|
||||||
|
.WithBucket(minIOConfig.BucketName)
|
||||||
|
.WithObject(objectkey));
|
||||||
|
|
||||||
|
return stat.Size; // 文件大小(字节)
|
||||||
|
}
|
||||||
|
else if (ObjectStoreServiceOptions.ObjectStoreUse == "AWS")
|
||||||
|
{
|
||||||
|
|
||||||
|
var awsConfig = ObjectStoreServiceOptions.AWS;
|
||||||
|
|
||||||
|
|
||||||
|
// 提供awsAccessKeyId和awsSecretAccessKey构造凭证
|
||||||
|
var credentials = new SessionAWSCredentials(AWSTempToken.AccessKeyId, AWSTempToken.SecretAccessKey, AWSTempToken.SessionToken);
|
||||||
|
|
||||||
|
//提供awsEndPoint(域名)进行访问配置
|
||||||
|
var clientConfig = new AmazonS3Config
|
||||||
|
{
|
||||||
|
RegionEndpoint = RegionEndpoint.USEast1,
|
||||||
|
UseHttp = true,
|
||||||
|
};
|
||||||
|
|
||||||
|
var request = new Amazon.S3.Model.GetObjectMetadataRequest
|
||||||
|
{
|
||||||
|
BucketName = awsConfig.BucketName,
|
||||||
|
Key = objectkey
|
||||||
|
};
|
||||||
|
|
||||||
|
var amazonS3Client = new AmazonS3Client(credentials, clientConfig);
|
||||||
|
|
||||||
|
var response = await amazonS3Client.GetObjectMetadataAsync(request);
|
||||||
|
|
||||||
|
long fileSize = response.ContentLength; // 文件大小(字节)
|
||||||
|
|
||||||
|
return fileSize;
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new BusinessValidationFailedException("未定义的存储介质类型");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public ObjectStoreDTO GetObjectStoreTempToken()
|
public ObjectStoreDTO GetObjectStoreTempToken()
|
||||||
{
|
{
|
||||||
@@ -764,6 +1121,7 @@ public class OSSService : IOSSService
|
|||||||
BucketName = ossOptions.BucketName,
|
BucketName = ossOptions.BucketName,
|
||||||
EndPoint = ossOptions.EndPoint,
|
EndPoint = ossOptions.EndPoint,
|
||||||
ViewEndpoint = ossOptions.ViewEndpoint,
|
ViewEndpoint = ossOptions.ViewEndpoint,
|
||||||
|
PreviewEndpoint = ossOptions.PreviewEndpoint
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -15,14 +15,20 @@ public static class ImageHelper
|
|||||||
|
|
||||||
fileStorePath = fileStorePath ?? filePath + ".preview.jpeg";
|
fileStorePath = fileStorePath ?? filePath + ".preview.jpeg";
|
||||||
|
|
||||||
using (var image = SixLabors.ImageSharp.Image.Load(filePath))
|
// 读取 DICOM 文件
|
||||||
{
|
var dicomImage = new DicomImage(filePath);
|
||||||
|
|
||||||
|
// 渲染 DICOM 图像到 ImageSharp 格式
|
||||||
|
using (var image = dicomImage.RenderImage().AsSharpImage())
|
||||||
|
{
|
||||||
|
// 生成缩略图(调整大小)
|
||||||
image.Mutate(x => x.Resize(500, 500));
|
image.Mutate(x => x.Resize(500, 500));
|
||||||
|
|
||||||
image.Save(fileStorePath);
|
// 保存缩略图为 JPEG
|
||||||
|
image.Save(fileStorePath, new JpegEncoder());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -33,37 +33,38 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="IdentityModel.OidcClient" Version="6.0.0" />
|
<PackageReference Include="IdentityModel.OidcClient" Version="6.0.0" />
|
||||||
<PackageReference Include="AlibabaCloud.SDK.Sts20150401" Version="1.1.4" />
|
<PackageReference Include="AlibabaCloud.SDK.Sts20150401" Version="1.1.5" />
|
||||||
<PackageReference Include="AWSSDK.SecurityToken" Version="3.7.400.36" />
|
<PackageReference Include="AWSSDK.SecurityToken" Version="3.7.401.81" />
|
||||||
<PackageReference Include="Aliyun.OSS.SDK.NetCore" Version="2.14.1" />
|
<PackageReference Include="Aliyun.OSS.SDK.NetCore" Version="2.14.1" />
|
||||||
<PackageReference Include="AWSSDK.S3" Version="3.7.405" />
|
<PackageReference Include="AWSSDK.S3" Version="3.7.416.8" />
|
||||||
<PackageReference Include="DocX" Version="3.0.1" />
|
<PackageReference Include="DocX" Version="4.0.25105.5786" />
|
||||||
<PackageReference Include="FreeSpire.Doc" Version="12.2.0" />
|
<PackageReference Include="FreeSpire.Doc" Version="12.2.0" />
|
||||||
<PackageReference Include="Hangfire.Core" Version="1.8.14" />
|
<PackageReference Include="Hangfire.Core" Version="1.8.18" />
|
||||||
<PackageReference Include="ExcelDataReader" Version="3.7.0" />
|
<PackageReference Include="ExcelDataReader" Version="3.7.0" />
|
||||||
<PackageReference Include="ExcelDataReader.DataSet" Version="3.7.0" />
|
<PackageReference Include="ExcelDataReader.DataSet" Version="3.7.0" />
|
||||||
<PackageReference Include="DistributedLock.Redis" Version="1.0.3" />
|
<PackageReference Include="DistributedLock.Redis" Version="1.0.3" />
|
||||||
<PackageReference Include="DistributedLock.SqlServer" Version="1.0.5" />
|
<PackageReference Include="DistributedLock.SqlServer" Version="1.0.6" />
|
||||||
<PackageReference Include="fo-dicom" Version="5.1.3" />
|
<PackageReference Include="fo-dicom" Version="5.2.1" />
|
||||||
<PackageReference Include="fo-dicom.Imaging.ImageSharp" Version="5.1.3" />
|
<PackageReference Include="fo-dicom.Imaging.ImageSharp" Version="5.2.1" />
|
||||||
<PackageReference Include="fo-dicom.Codecs" Version="5.15.1" />
|
<PackageReference Include="fo-dicom.Codecs" Version="5.16.1" />
|
||||||
<PackageReference Include="IP2Region.Net" Version="2.0.2" />
|
<PackageReference Include="IP2Region.Net" Version="2.0.2" />
|
||||||
<PackageReference Include="MailKit" Version="4.7.1.1" />
|
<PackageReference Include="MailKit" Version="4.11.0" />
|
||||||
<PackageReference Include="Masa.Contrib.Service.MinimalAPIs" Version="1.0.0" />
|
<PackageReference Include="Masa.Contrib.Service.MinimalAPIs" Version="1.0.0" />
|
||||||
|
<PackageReference Include="MaxMind.GeoIP2" Version="5.2.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.10" />
|
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.10" />
|
||||||
<PackageReference Include="MimeKit" Version="4.7.1" />
|
<PackageReference Include="MimeKit" Version="4.11.0" />
|
||||||
<PackageReference Include="MiniExcel" Version="1.34.2" />
|
<PackageReference Include="MiniExcel" Version="1.40.0" />
|
||||||
<PackageReference Include="Minio" Version="6.0.3" />
|
<PackageReference Include="Minio" Version="6.0.4" />
|
||||||
<PackageReference Include="MiniWord" Version="0.8.0" />
|
<PackageReference Include="MiniWord" Version="0.9.2" />
|
||||||
<PackageReference Include="My.Extensions.Localization.Json" Version="3.3.0">
|
<PackageReference Include="My.Extensions.Localization.Json" Version="3.3.0">
|
||||||
<TreatAsUsed>true</TreatAsUsed>
|
<TreatAsUsed>true</TreatAsUsed>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="NPOI" Version="2.7.1" />
|
<PackageReference Include="NPOI" Version="2.7.3" />
|
||||||
<PackageReference Include="Panda.DynamicWebApi" Version="1.2.2" />
|
<PackageReference Include="Panda.DynamicWebApi" Version="1.2.2" />
|
||||||
<PackageReference Include="RestSharp" Version="112.1.0" />
|
<PackageReference Include="RestSharp" Version="112.1.0" />
|
||||||
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.5" />
|
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.7" />
|
||||||
<PackageReference Include="Swashbuckle.AspNetCore.Filters" Version="8.0.2" />
|
<PackageReference Include="Swashbuckle.AspNetCore.Filters" Version="8.0.2" />
|
||||||
<PackageReference Include="ZiggyCreatures.FusionCache" Version="1.4.0" />
|
<PackageReference Include="ZiggyCreatures.FusionCache" Version="2.1.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -14,19 +14,20 @@ namespace IRaCIS.Core.Application.MassTransit.Consumer;
|
|||||||
|
|
||||||
public static class CommonEmailHelper
|
public static class CommonEmailHelper
|
||||||
{
|
{
|
||||||
public static async Task<EmailNoticeConfig> GetEmailSubejctAndHtmlInfoAndBuildAsync(IRepository<EmailNoticeConfig> _emailNoticeConfigrepository, EmailBusinessScenario scenario, MimeMessage messageToSend,
|
|
||||||
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailFunc)
|
/// <summary>
|
||||||
|
/// 系统默认邮件 + 项目默认邮件 (不用添加到项目邮件配置中,才发送)
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="configInfo"></param>
|
||||||
|
/// <param name="messageToSend"></param>
|
||||||
|
/// <param name="emailFunc"></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)
|
||||||
{
|
{
|
||||||
var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;
|
var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;
|
||||||
|
|
||||||
var configInfo = await _emailNoticeConfigrepository.Where(t => t.BusinessScenarioEnum == scenario).FirstOrDefaultAsync();
|
|
||||||
|
|
||||||
if (configInfo == null)
|
|
||||||
{
|
|
||||||
throw new BusinessValidationFailedException("系统未找到当前场景邮件配置信息,请联系运维人员核查");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
var (topicStr, htmlBodyStr) = isEn_US ? (configInfo.EmailTopic, configInfo.EmailHtmlContent) : (configInfo.EmailTopicCN, configInfo.EmailHtmlContentCN);
|
var (topicStr, htmlBodyStr) = isEn_US ? (configInfo.EmailTopic, configInfo.EmailHtmlContent) : (configInfo.EmailTopicCN, configInfo.EmailHtmlContentCN);
|
||||||
|
|
||||||
try
|
try
|
||||||
@@ -36,8 +37,9 @@ public static class CommonEmailHelper
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
//"邮件模板内容有误,填充内容出现问题,请联系运维人员核查"
|
||||||
|
|
||||||
throw new BusinessValidationFailedException("邮件模板内容有误,填充内容出现问题,请联系运维人员核查");
|
throw new BusinessValidationFailedException(I18n.T("CommonEmail_ConfigError"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -52,6 +54,49 @@ public static class CommonEmailHelper
|
|||||||
return configInfo;
|
return configInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 项目手动邮件 (需要添加到项目邮件配置中,才发送)
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="configInfo"></param>
|
||||||
|
/// <param name="messageToSend"></param>
|
||||||
|
/// <param name="emailFunc"></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)
|
||||||
|
{
|
||||||
|
var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;
|
||||||
|
|
||||||
|
|
||||||
|
var (topicStr, htmlBodyStr) = isEn_US ? (configInfo.EmailTopic, configInfo.EmailHtmlContent) : (configInfo.EmailTopicCN, configInfo.EmailHtmlContentCN);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
//每个场景修改主题 和body的逻辑不一样
|
||||||
|
(topicStr, htmlBodyStr) = emailFunc((topicStr, htmlBodyStr));
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
//"邮件模板内容有误,填充内容出现问题,请联系运维人员核查"
|
||||||
|
|
||||||
|
throw new BusinessValidationFailedException(I18n.T("CommonEmail_ConfigError"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
messageToSend.Subject = topicStr;
|
||||||
|
|
||||||
|
var builder = new BodyBuilder();
|
||||||
|
|
||||||
|
builder.HtmlBody = htmlBodyStr;
|
||||||
|
|
||||||
|
messageToSend.Body = builder.ToMessageBody();
|
||||||
|
|
||||||
|
return configInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static string ReplaceCompanyName(SystemEmailSendConfig _systemEmailConfig, string needDealtxt)
|
public static string ReplaceCompanyName(SystemEmailSendConfig _systemEmailConfig, string needDealtxt)
|
||||||
{
|
{
|
||||||
var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;
|
var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;
|
||||||
@@ -74,12 +119,13 @@ public static class CommonEmailHelper
|
|||||||
var enumValueList = inDto.DictionaryList.Select(x => x.EnumValue).ToList();
|
var enumValueList = inDto.DictionaryList.Select(x => x.EnumValue).ToList();
|
||||||
|
|
||||||
|
|
||||||
var dicList =await inDto.DictionaryRepository.Where(x => dictionaryCodelist.Contains(x.Parent.Code) && enumValueList.Contains(x.Code)).Select(x=>new DictionaryData() {
|
var dicList = await inDto.DictionaryRepository.Where(x => dictionaryCodelist.Contains(x.Parent.Code) && enumValueList.Contains(x.Code)).Select(x => new DictionaryData()
|
||||||
|
{
|
||||||
DictionaryCode=x.Parent.Code,
|
|
||||||
EnumValue=x.Code,
|
DictionaryCode = x.Parent.Code,
|
||||||
Value=x.Value,
|
EnumValue = x.Code,
|
||||||
ValueCN=x.ValueCN
|
Value = x.Value,
|
||||||
|
ValueCN = x.ValueCN
|
||||||
}).ToListAsync();
|
}).ToListAsync();
|
||||||
|
|
||||||
|
|
||||||
@@ -88,7 +134,7 @@ public static class CommonEmailHelper
|
|||||||
inDto.DictionaryList.ForEach(x =>
|
inDto.DictionaryList.ForEach(x =>
|
||||||
{
|
{
|
||||||
|
|
||||||
var dic = dicList.Where(y => y.EnumValue == x.EnumValue && y.DictionaryCode == x.DictionaryCode).FirstOrDefault();
|
var dic = dicList.Where(y => y.EnumValue == x.EnumValue && y.DictionaryCode.Equals(x.DictionaryCode,StringComparison.OrdinalIgnoreCase)).FirstOrDefault();
|
||||||
result.Add(dic == null ? string.Empty : (inDto.IsEn_US ? dic.Value : dic.ValueCN));
|
result.Add(dic == null ? string.Empty : (inDto.IsEn_US ? dic.Value : dic.ValueCN));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
using AutoMapper;
|
using AutoMapper;
|
||||||
|
using IRaCIS.Application.Interfaces;
|
||||||
using IRaCIS.Core.Application.Contracts.DTO;
|
using IRaCIS.Core.Application.Contracts.DTO;
|
||||||
using IRaCIS.Core.Application.MassTransit.Command;
|
using IRaCIS.Core.Application.MassTransit.Command;
|
||||||
using IRaCIS.Core.Domain.Share;
|
using IRaCIS.Core.Domain.Share;
|
||||||
using MassTransit;
|
using MassTransit;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.Extensions.Localization;
|
using Microsoft.Extensions.Localization;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
@@ -21,6 +24,9 @@ namespace IRaCIS.Core.Application.MassTransit.Consumer
|
|||||||
private readonly IRepository<NoneDicomStudy> _noneDicomStudyRepository;
|
private readonly IRepository<NoneDicomStudy> _noneDicomStudyRepository;
|
||||||
public IStringLocalizer _localizer { get; set; }
|
public IStringLocalizer _localizer { get; set; }
|
||||||
|
|
||||||
|
private readonly SystemEmailSendConfig _systemEmailConfig;
|
||||||
|
|
||||||
|
private readonly IRepository<Dictionary> _dictionaryRepository;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 构造函数注入
|
/// 构造函数注入
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -28,7 +34,7 @@ namespace IRaCIS.Core.Application.MassTransit.Consumer
|
|||||||
public ConsistencyCheckConsumer(IRepository<DicomStudy> studyRepository, IUserInfo userInfo,
|
public ConsistencyCheckConsumer(IRepository<DicomStudy> studyRepository, IUserInfo userInfo,
|
||||||
IRepository<Subject> subjectRepository, IRepository<SubjectVisit> subjectVisitRepository,
|
IRepository<Subject> subjectRepository, IRepository<SubjectVisit> subjectVisitRepository,
|
||||||
IRepository<TrialSite> trialSiteRepository, IRepository<NoneDicomStudy> noneDicomStudyRepository,
|
IRepository<TrialSite> trialSiteRepository, IRepository<NoneDicomStudy> noneDicomStudyRepository,
|
||||||
IMapper mapper, IStringLocalizer localizer)
|
IMapper mapper, IStringLocalizer localizer, IOptionsMonitor<SystemEmailSendConfig> systemEmailConfig, IRepository<Dictionary> dictionaryRepository)
|
||||||
{
|
{
|
||||||
_noneDicomStudyRepository = noneDicomStudyRepository;
|
_noneDicomStudyRepository = noneDicomStudyRepository;
|
||||||
_studyRepository = studyRepository;
|
_studyRepository = studyRepository;
|
||||||
@@ -38,6 +44,9 @@ namespace IRaCIS.Core.Application.MassTransit.Consumer
|
|||||||
_trialSiteRepository = trialSiteRepository;
|
_trialSiteRepository = trialSiteRepository;
|
||||||
_mapper = mapper;
|
_mapper = mapper;
|
||||||
_localizer = localizer;
|
_localizer = localizer;
|
||||||
|
|
||||||
|
_systemEmailConfig = systemEmailConfig.CurrentValue;
|
||||||
|
_dictionaryRepository = dictionaryRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -47,6 +56,9 @@ namespace IRaCIS.Core.Application.MassTransit.Consumer
|
|||||||
|
|
||||||
var trialId = context.Message.TrialId;
|
var trialId = context.Message.TrialId;
|
||||||
|
|
||||||
|
//系统定义MRI 到底是MR 还是MRI
|
||||||
|
var mriModality = await _dictionaryRepository.Where(t => t.Parent.Code == "Modality").Where(t => t.Code == "MRI").Select(t => t.Value).FirstNotNullAsync();
|
||||||
|
|
||||||
//处理Excel大小写
|
//处理Excel大小写
|
||||||
context.Message.ETCList.ForEach(t => { t.Modality = t.Modality.ToUpper().Trim(); t.StudyDate = Convert.ToDateTime(t.StudyDate).ToString("yyyy-MM-dd"); t.SiteCode = t.SiteCode.ToUpper().Trim(); t.VisitName = t.VisitName.ToUpper().Trim(); t.SubjectCode = t.SubjectCode.ToUpper().Trim(); });
|
context.Message.ETCList.ForEach(t => { t.Modality = t.Modality.ToUpper().Trim(); t.StudyDate = Convert.ToDateTime(t.StudyDate).ToString("yyyy-MM-dd"); t.SiteCode = t.SiteCode.ToUpper().Trim(); t.VisitName = t.VisitName.ToUpper().Trim(); t.SubjectCode = t.SubjectCode.ToUpper().Trim(); });
|
||||||
var etcList = context.Message.ETCList;
|
var etcList = context.Message.ETCList;
|
||||||
@@ -115,6 +127,16 @@ namespace IRaCIS.Core.Application.MassTransit.Consumer
|
|||||||
var etcVisitStudyList = etcList.Where(t => t.SubjectCode == sv.SubjectCode && t.SiteCode == sv.SiteCode && t.VisitName == sv.VisitName).ToList();
|
var etcVisitStudyList = etcList.Where(t => t.SubjectCode == sv.SubjectCode && t.SiteCode == sv.SiteCode && t.VisitName == sv.VisitName).ToList();
|
||||||
|
|
||||||
|
|
||||||
|
//以我们系统数据库为准 ,判断是MR 还是MRI, 把Excel 里的MR 或者MRI 处理成一致,MR MRI 是一致的
|
||||||
|
foreach (var item in etcVisitStudyList)
|
||||||
|
{
|
||||||
|
if (item.Modality == "MR" || item.Modality == "MRI")
|
||||||
|
{
|
||||||
|
item.Modality = mriModality;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
StringBuilder dialogMsg = new StringBuilder();
|
StringBuilder dialogMsg = new StringBuilder();
|
||||||
//---您好,根据本系统自动识别,该受试者当前访视在IRC系统中已提交的影像检查情况如下:
|
//---您好,根据本系统自动识别,该受试者当前访视在IRC系统中已提交的影像检查情况如下:
|
||||||
@@ -186,7 +208,7 @@ namespace IRaCIS.Core.Application.MassTransit.Consumer
|
|||||||
{
|
{
|
||||||
dialogMsg.AppendLine($"<br/>");
|
dialogMsg.AppendLine($"<br/>");
|
||||||
//---核对EDC数据,完全一致, 审核通过
|
//---核对EDC数据,完全一致, 审核通过
|
||||||
dialogMsg.AppendLine(_localizer["ConsistencyVerification_EDCA"]);
|
dialogMsg.AppendLine(_localizer["ConsistencyVerification_EDCA", _systemEmailConfig.SystemShortName]);
|
||||||
|
|
||||||
|
|
||||||
// dialogMsg.AppendLine(@$"<br>说明:为高效解决/处理以上全部质疑问题,麻烦您准确核实实际影像检查情况。请注意影像日期与实际检查的日期可能会不一致,部分检查(如PET -CT)可能同时存在多种模态影像。准确核实后,请回复该访视正确的影像检查情况。");
|
// dialogMsg.AppendLine(@$"<br>说明:为高效解决/处理以上全部质疑问题,麻烦您准确核实实际影像检查情况。请注意影像日期与实际检查的日期可能会不一致,部分检查(如PET -CT)可能同时存在多种模态影像。准确核实后,请回复该访视正确的影像检查情况。");
|
||||||
@@ -196,7 +218,7 @@ namespace IRaCIS.Core.Application.MassTransit.Consumer
|
|||||||
dbSV.CheckChallengeState = CheckChanllengeTypeEnum.Closed;
|
dbSV.CheckChallengeState = CheckChanllengeTypeEnum.Closed;
|
||||||
|
|
||||||
//---核对EDC数据,完全一致
|
//---核对EDC数据,完全一致
|
||||||
dbSV.CheckResult = _localizer["ConsistencyVerification_EDCB"];
|
dbSV.CheckResult = _localizer["ConsistencyVerification_EDCB", _systemEmailConfig.SystemShortName];
|
||||||
//---自动核查通过
|
//---自动核查通过
|
||||||
dbSV.ManualPassReason = _localizer["ConsistencyVerification_Auto"];
|
dbSV.ManualPassReason = _localizer["ConsistencyVerification_Auto"];
|
||||||
|
|
||||||
@@ -224,7 +246,7 @@ namespace IRaCIS.Core.Application.MassTransit.Consumer
|
|||||||
{
|
{
|
||||||
num++;
|
num++;
|
||||||
//影像检查(EDC 缺少) ConsistencyVerification_EdcL
|
//影像检查(EDC 缺少) ConsistencyVerification_EdcL
|
||||||
dialogMsg.AppendLine($"<br/><div style='text-indent: 20px;'>{num}. {_localizer["ConsistencyVerification_EdcL", item.StudyDate, item.Modality]}</div>");
|
dialogMsg.AppendLine($"<br/><div style='text-indent: 20px;'>{num}. {_localizer["ConsistencyVerification_EdcL", item.StudyDate, item.Modality/*, _systemEmailConfig.SystemShortName*/]}</div>");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -232,15 +254,15 @@ namespace IRaCIS.Core.Application.MassTransit.Consumer
|
|||||||
{
|
{
|
||||||
num++;
|
num++;
|
||||||
// 影像检查(IRC 缺少)
|
// 影像检查(IRC 缺少)
|
||||||
dialogMsg.AppendLine($"<br/><div style='text-indent: 20px;'>{num}. {_localizer["ConsistencyVerification_IrcLi", item.StudyDate, item.Modality]}</div>");
|
dialogMsg.AppendLine($"<br/><div style='text-indent: 20px;'>{num}. {_localizer["ConsistencyVerification_IrcLi", item.StudyDate, item.Modality, _systemEmailConfig.SystemShortName]}</div>");
|
||||||
}
|
}
|
||||||
|
|
||||||
dialogMsg.AppendLine($"<br/>");
|
dialogMsg.AppendLine($"<br/>");
|
||||||
dialogMsg.AppendLine(@$"<div>{_localizer["ConsistencyVerification_Desc"]}</div>");
|
dialogMsg.AppendLine(@$"<div>{_localizer["ConsistencyVerification_Desc"]}</div>");
|
||||||
|
|
||||||
dbSV.CheckResult = _localizer["ConsistencyVerification_Conf"] +
|
dbSV.CheckResult =
|
||||||
String.Join(" | ", dbExceptExcel.Select(t => $"{_localizer["ConsistencyVerification_EdcL", t.StudyDate, t.Modality]}")) + " | "
|
String.Join(" | ", dbExceptExcel.Select(t => $"{_localizer["ConsistencyVerification_EdcL", t.StudyDate, t.Modality/*, _systemEmailConfig.SystemShortName*/]}")) + " | "
|
||||||
+ String.Join(" | ", excelExceptDB.Select(t => $"{_localizer["ConsistencyVerification_IrcLi", t.StudyDate, t.Modality]}"));
|
+ String.Join(" | ", excelExceptDB.Select(t => $"{_localizer["ConsistencyVerification_IrcLi", t.StudyDate, t.Modality, _systemEmailConfig.SystemShortName]}"));
|
||||||
|
|
||||||
//新增一致性核查质疑记录
|
//新增一致性核查质疑记录
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace IRaCIS.Core.Application.MassTransit.Consumer.Dto
|
||||||
|
{
|
||||||
|
public class SendImageReuploadEmailInDto
|
||||||
|
{
|
||||||
|
public EmailNoticeConfig EmailNoticeConfig { get; set; }
|
||||||
|
|
||||||
|
public EmailBusinessScenario Scenario { get; set; }
|
||||||
|
|
||||||
|
public SubjectVisit SubjectVisit { get; set; }
|
||||||
|
|
||||||
|
public Guid TrialId { get; set; }
|
||||||
|
public List<UserTypeEnum> UserTypes { get; set; } = null;
|
||||||
|
|
||||||
|
public ImageBackStateEnum ImageBackStateEnum { get; set; } = ImageBackStateEnum.None;
|
||||||
|
|
||||||
|
public RequestBackStateEnum RequestBackStateEnum { get; set; } = RequestBackStateEnum.NotRequest;
|
||||||
|
|
||||||
|
public ReReadingApplyState ReReadingApplyState { get; set; } = ReReadingApplyState.Default;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,522 @@
|
|||||||
|
using IRaCIS.Core.Application.Helper;
|
||||||
|
using IRaCIS.Core.Application.MassTransit.Command;
|
||||||
|
using IRaCIS.Core.Application.MassTransit.Consumer.Dto;
|
||||||
|
using IRaCIS.Core.Application.Service.Reading.Dto;
|
||||||
|
using IRaCIS.Core.Domain;
|
||||||
|
using IRaCIS.Core.Domain._DomainEvent;
|
||||||
|
using IRaCIS.Core.Domain.BaseModel;
|
||||||
|
using IRaCIS.Core.Domain.Models;
|
||||||
|
using IRaCIS.Core.Domain.Share;
|
||||||
|
using IRaCIS.Core.Infra.EFCore.Common;
|
||||||
|
using MassTransit;
|
||||||
|
using MassTransit.Mediator;
|
||||||
|
using MassTransit.Scheduling;
|
||||||
|
using Medallion.Threading;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.AspNetCore.StaticFiles;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
|
using MimeKit;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Panda.DynamicWebApi.Attributes;
|
||||||
|
using RestSharp;
|
||||||
|
using SkiaSharp;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace IRaCIS.Core.Application.MassTransit.Consumer;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 影像重传和阅片人筛选相关邮件发送
|
||||||
|
/// </summary>
|
||||||
|
public class ImageConsumer(
|
||||||
|
IRepository<UserRole> _userRoleRepository,
|
||||||
|
IRepository<TrialUserRole> _trialUseRoleRepository,
|
||||||
|
IRepository<SubjectVisit> _subjectVisitRepository,
|
||||||
|
IRepository<Trial> _trialRepository,
|
||||||
|
IRepository<Enroll> _enrollRepository,
|
||||||
|
IRepository<VisitTask> _visitTaskRepository,
|
||||||
|
IRepository<ReadModule> _readModuleRepository,
|
||||||
|
IRepository<EmailNoticeUserType> _emailNoticeUserTypeRepository,
|
||||||
|
IRepository<TrialSite> _trialSiteRepository,
|
||||||
|
IRepository<Dictionary> _dictionaryRepository,
|
||||||
|
IRepository<EmailNoticeConfig> _emailNoticeConfigrepository,
|
||||||
|
IOptionsMonitor<SystemEmailSendConfig> systemEmailConfig) :
|
||||||
|
IConsumer<DirectApplyReupdloadEvent>,
|
||||||
|
IConsumer<CheckReuploadEvent>,
|
||||||
|
IConsumer<QCChanllengeReuploadEvent>,
|
||||||
|
IConsumer<HaveReadVisitTaskReReading>,
|
||||||
|
IConsumer<ReviewerPMApplyEvent>,
|
||||||
|
IConsumer<ReviewerSPMApprovedEvent>
|
||||||
|
{
|
||||||
|
private readonly SystemEmailSendConfig _systemEmailConfig = systemEmailConfig.CurrentValue;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 处理直接申请流程的重传事件
|
||||||
|
/// </summary>
|
||||||
|
public async Task Consume(ConsumeContext<DirectApplyReupdloadEvent> context)
|
||||||
|
{
|
||||||
|
Console.WriteLine("发送【影像重传-直接申请流程】邮件!!!");
|
||||||
|
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.Subject).FirstNotNullAsync();
|
||||||
|
var trialId = subjectVisit.TrialId;
|
||||||
|
List<UserTypeEnum> userTypes = null;
|
||||||
|
// 根据申请角色和状态确定邮件场景
|
||||||
|
EmailBusinessScenario scenario;
|
||||||
|
if (context.Message.ImageBackState == ImageBackStateEnum.None)
|
||||||
|
{
|
||||||
|
switch (context.Message.ApplyUserRole)
|
||||||
|
{
|
||||||
|
case ImageBackApplyEnum.IQCRequestBack:
|
||||||
|
scenario = EmailBusinessScenario.ImageQC_IQCApplyRe_Uploading; // 64
|
||||||
|
break;
|
||||||
|
case ImageBackApplyEnum.CRCRequestBack:
|
||||||
|
scenario = EmailBusinessScenario.ImageUploadCRCApplyRe_Uploading; // 65
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
scenario = EmailBusinessScenario.ImageQC_IQCApplyRe_Uploading; // 64
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
scenario = EmailBusinessScenario.ImageReUpload_PMApprovalRe_Uploading; // 66
|
||||||
|
if (context.Message.ApplyUserRole == ImageBackApplyEnum.IQCRequestBack)
|
||||||
|
{
|
||||||
|
userTypes = new List<UserTypeEnum>() { UserTypeEnum.IQC, UserTypeEnum.ClinicalResearchCoordinator };
|
||||||
|
}
|
||||||
|
else if (context.Message.ApplyUserRole == ImageBackApplyEnum.CRCRequestBack)
|
||||||
|
{
|
||||||
|
userTypes = new List<UserTypeEnum>() { UserTypeEnum.ClinicalResearchCoordinator };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var emailConfig = _emailNoticeConfigrepository.Where(t => t.BusinessScenarioEnum == scenario && t.IsEnable && t.IsAutoSend).FirstOrDefault();
|
||||||
|
|
||||||
|
if (emailConfig != null)
|
||||||
|
{
|
||||||
|
var inDto = new SendImageReuploadEmailInDto
|
||||||
|
{
|
||||||
|
EmailNoticeConfig = emailConfig,
|
||||||
|
Scenario = scenario,
|
||||||
|
SubjectVisit = subjectVisit,
|
||||||
|
TrialId = trialId,
|
||||||
|
UserTypes = userTypes,
|
||||||
|
ImageBackStateEnum = context.Message.ImageBackState
|
||||||
|
};
|
||||||
|
await SendImageReuploadEmail(inDto);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 处理一致性核查申请重传事件
|
||||||
|
/// </summary>
|
||||||
|
public async Task Consume(ConsumeContext<CheckReuploadEvent> context)
|
||||||
|
{
|
||||||
|
Console.WriteLine("发送【一致性核查-影像重传】邮件!!!");
|
||||||
|
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.Subject).FirstNotNullAsync();
|
||||||
|
var trialId = subjectVisit.TrialId;
|
||||||
|
|
||||||
|
// 根据状态确定邮件场景
|
||||||
|
EmailBusinessScenario scenario;
|
||||||
|
switch (context.Message.RequestBackState)
|
||||||
|
{
|
||||||
|
case RequestBackStateEnum.CRC_RequestBack:
|
||||||
|
scenario = EmailBusinessScenario.DataReconciliation_CRCApplyRe_Uploading; // 62
|
||||||
|
break;
|
||||||
|
case RequestBackStateEnum.PM_AgressBack:
|
||||||
|
case RequestBackStateEnum.PM_NotAgree:
|
||||||
|
scenario = EmailBusinessScenario.DataReconciliation_PMApprovalRe_Uploading; // 63
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return; // 其他状态不发送邮件
|
||||||
|
}
|
||||||
|
|
||||||
|
var emailConfig = _emailNoticeConfigrepository.Where(t => t.BusinessScenarioEnum == scenario && t.IsEnable && t.IsAutoSend).FirstOrDefault();
|
||||||
|
|
||||||
|
if (emailConfig != null)
|
||||||
|
{
|
||||||
|
var inDto = new SendImageReuploadEmailInDto
|
||||||
|
{
|
||||||
|
EmailNoticeConfig = emailConfig,
|
||||||
|
Scenario = scenario,
|
||||||
|
SubjectVisit = subjectVisit,
|
||||||
|
TrialId = trialId,
|
||||||
|
RequestBackStateEnum = context.Message.RequestBackState,
|
||||||
|
};
|
||||||
|
await SendImageReuploadEmail(inDto);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 处理质疑CRC申请重传事件
|
||||||
|
/// </summary>
|
||||||
|
public async Task Consume(ConsumeContext<QCChanllengeReuploadEvent> context)
|
||||||
|
{
|
||||||
|
Console.WriteLine("发送【影像质疑-影像重传】邮件!!!");
|
||||||
|
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.Subject).FirstNotNullAsync();
|
||||||
|
var trialId = subjectVisit.TrialId;
|
||||||
|
|
||||||
|
// 根据状态确定邮件场景
|
||||||
|
EmailBusinessScenario scenario;
|
||||||
|
switch (context.Message.ReuploadEnum)
|
||||||
|
{
|
||||||
|
case QCChanllengeReuploadEnum.CRCRequestReupload:
|
||||||
|
scenario = EmailBusinessScenario.ImageQueryCRCApplyRe_Uploading; // 60
|
||||||
|
break;
|
||||||
|
case QCChanllengeReuploadEnum.QCAgreeUpload:
|
||||||
|
scenario = EmailBusinessScenario.ImageQuery_IQCApprovalRe_Uploading; // 61
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return; // 其他状态不发送邮件
|
||||||
|
}
|
||||||
|
|
||||||
|
var emailConfig = _emailNoticeConfigrepository.Where(t => t.BusinessScenarioEnum == scenario && t.IsEnable && t.IsAutoSend).FirstOrDefault();
|
||||||
|
|
||||||
|
if (emailConfig != null)
|
||||||
|
{
|
||||||
|
var inDto = new SendImageReuploadEmailInDto
|
||||||
|
{
|
||||||
|
EmailNoticeConfig = emailConfig,
|
||||||
|
Scenario = scenario,
|
||||||
|
SubjectVisit = subjectVisit,
|
||||||
|
TrialId = trialId
|
||||||
|
};
|
||||||
|
await SendImageReuploadEmail(inDto);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 处理已阅任务重阅申请事件
|
||||||
|
/// </summary>
|
||||||
|
public async Task Consume(ConsumeContext<HaveReadVisitTaskReReading> context)
|
||||||
|
{
|
||||||
|
Console.WriteLine("发送【重阅-影像重传】邮件!!!");
|
||||||
|
var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;
|
||||||
|
|
||||||
|
var visitTaskId = context.Message.VisitTaskId;
|
||||||
|
// 获取VisitTask关联的SubjectVisit
|
||||||
|
var visitTask = await _visitTaskRepository.Where(x => x.Id == visitTaskId).Include(x => x.Subject).Include(x => x.SourceSubjectVisit).FirstNotNullAsync();
|
||||||
|
var subjectVisit = new SubjectVisit() { };
|
||||||
|
if (visitTask.SourceSubjectVisitId != null)
|
||||||
|
{
|
||||||
|
subjectVisit = visitTask.SourceSubjectVisit;
|
||||||
|
}
|
||||||
|
else if (visitTask.SouceReadModuleId != null)
|
||||||
|
{
|
||||||
|
var readModule = await _readModuleRepository.Where(x => x.Id == visitTask.SouceReadModuleId).Include(x => x.SubjectVisit).FirstOrDefaultAsync();
|
||||||
|
subjectVisit = readModule.SubjectVisit;
|
||||||
|
}
|
||||||
|
|
||||||
|
var trialId = subjectVisit.TrialId;
|
||||||
|
|
||||||
|
// 根据状态确定邮件场景
|
||||||
|
EmailBusinessScenario scenario;
|
||||||
|
switch (context.Message.ReReadingApplyState)
|
||||||
|
{
|
||||||
|
case ReReadingApplyState.TrialGroupHaveApplyed:
|
||||||
|
scenario = EmailBusinessScenario.ReadTracking_PMApplyRe_Reading; // 67
|
||||||
|
break;
|
||||||
|
case ReReadingApplyState.Agree:
|
||||||
|
case ReReadingApplyState.Reject:
|
||||||
|
scenario = EmailBusinessScenario.Re_ReadApproval_SPMCPMApprovalRe_Reading; // 68
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return; // 其他状态不发送邮件
|
||||||
|
}
|
||||||
|
|
||||||
|
var emailConfig = _emailNoticeConfigrepository.Where(t => t.BusinessScenarioEnum == scenario && t.IsEnable && t.IsAutoSend).FirstOrDefault();
|
||||||
|
|
||||||
|
if (emailConfig != null)
|
||||||
|
{
|
||||||
|
var inDto = new SendImageReuploadEmailInDto
|
||||||
|
{
|
||||||
|
EmailNoticeConfig = emailConfig,
|
||||||
|
Scenario = scenario,
|
||||||
|
SubjectVisit = subjectVisit,
|
||||||
|
TrialId = trialId,
|
||||||
|
ReReadingApplyState= context.Message.ReReadingApplyState,
|
||||||
|
};
|
||||||
|
await SendImageReuploadEmail(inDto);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 发送影像重传相关邮件的通用方法
|
||||||
|
/// </summary>
|
||||||
|
private async Task SendImageReuploadEmail(SendImageReuploadEmailInDto inDto)
|
||||||
|
{
|
||||||
|
var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;
|
||||||
|
|
||||||
|
inDto.SubjectVisit = await _subjectVisitRepository.Where(x => x.Id == inDto.SubjectVisit.Id).Include(x => x.Subject).FirstNotNullAsync();
|
||||||
|
// 获取项目信息
|
||||||
|
var trialInfo = await _trialRepository.FirstOrDefaultAsync(t => t.Id == inDto.TrialId);
|
||||||
|
|
||||||
|
// 根据不同场景获取不同角色的用户
|
||||||
|
var trialUser = await _trialUseRoleRepository.Where(x => x.TrialId == inDto.TrialId && !x.TrialUser.IsDeleted).Include(x => x.UserRole).Select(x => x.UserRole).ToListAsync();
|
||||||
|
|
||||||
|
// 根据场景确定收件人
|
||||||
|
List<UserRole> toUserList = new List<UserRole>();
|
||||||
|
List<UserRole> ccUserList = new List<UserRole>();
|
||||||
|
|
||||||
|
var emailNoticeUserList = await _emailNoticeUserTypeRepository.Where(x => x.EmailNoticeConfigId == inDto.EmailNoticeConfig.Id).ToListAsync();
|
||||||
|
var userTypeEnum = emailNoticeUserList.Select(x => x.UserType).ToList();
|
||||||
|
if (inDto.UserTypes != null)
|
||||||
|
{
|
||||||
|
userTypeEnum = inDto.UserTypes;
|
||||||
|
}
|
||||||
|
var crcUserList = new List<UserRole>() { };
|
||||||
|
if (userTypeEnum.Contains(UserTypeEnum.ClinicalResearchCoordinator))
|
||||||
|
{
|
||||||
|
crcUserList = await _trialSiteRepository.Where(x => x.Id == inDto.SubjectVisit.TrialSiteId).SelectMany(x => x.CRCUserList.Select(y => y.UserRole)).ToListAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inDto.UserTypes == null)
|
||||||
|
{
|
||||||
|
var toList = emailNoticeUserList.Where(x => x.EmailUserType == EmailUserType.To && x.UserType != UserTypeEnum.ClinicalResearchCoordinator).Select(x => x.UserType).ToList();
|
||||||
|
|
||||||
|
toUserList = trialUser.Where(x => toList.Contains(x.UserTypeEnum)).ToList();
|
||||||
|
|
||||||
|
if (emailNoticeUserList.Any(x => x.EmailUserType == EmailUserType.To && x.UserType == UserTypeEnum.ClinicalResearchCoordinator))
|
||||||
|
{
|
||||||
|
toUserList.AddRange(crcUserList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var toList = inDto.UserTypes.Where(x => x != UserTypeEnum.ClinicalResearchCoordinator).ToList();
|
||||||
|
|
||||||
|
toUserList = trialUser.Where(x => toList.Contains(x.UserTypeEnum)).ToList();
|
||||||
|
|
||||||
|
if (inDto.UserTypes.Any(x => x == UserTypeEnum.ClinicalResearchCoordinator))
|
||||||
|
{
|
||||||
|
toUserList.AddRange(crcUserList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var ccList = emailNoticeUserList.Where(x => x.EmailUserType == EmailUserType.Copy && x.UserType != UserTypeEnum.ClinicalResearchCoordinator).Select(x => x.UserType).ToList();
|
||||||
|
|
||||||
|
ccUserList = trialUser.Where(x => ccList.Contains(x.UserTypeEnum)).ToList();
|
||||||
|
|
||||||
|
if (emailNoticeUserList.Any(x => x.EmailUserType == EmailUserType.Copy && x.UserType == UserTypeEnum.ClinicalResearchCoordinator))
|
||||||
|
{
|
||||||
|
ccUserList.AddRange(crcUserList);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果没有收件人,则不发送邮件
|
||||||
|
if (toUserList.Count == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
List<DictionaryDto> dictionaryDtos = new List<DictionaryDto>() {
|
||||||
|
new DictionaryDto (){DictionaryCode= "YesOrNo",EnumValue=inDto.SubjectVisit.IsUrgent.ToString().ToLower(), }, //是否加急
|
||||||
|
};
|
||||||
|
switch (inDto.Scenario)
|
||||||
|
{
|
||||||
|
case EmailBusinessScenario.Re_ReadApproval_SPMCPMApprovalRe_Reading:
|
||||||
|
dictionaryDtos.Add(new DictionaryDto() { DictionaryCode = "ReReadingApplyState", EnumValue = inDto.ReReadingApplyState.GetEnumInt(), });
|
||||||
|
break;
|
||||||
|
case EmailBusinessScenario.DataReconciliation_PMApprovalRe_Uploading:
|
||||||
|
dictionaryDtos.Add(new DictionaryDto() { DictionaryCode = "RequestBackState", EnumValue = inDto.RequestBackStateEnum.GetEnumInt(), });
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
dictionaryDtos.Add(new DictionaryDto() { DictionaryCode = "ImageBackStateEnum", EnumValue = inDto.ImageBackStateEnum.GetEnumInt(), });//审批结果
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
var dictionValue = await CommonEmailHelper.TranslationDictionary(new TranslationDictionaryDto()
|
||||||
|
{
|
||||||
|
|
||||||
|
DictionaryRepository = _dictionaryRepository,
|
||||||
|
IsEn_US = isEn_US,
|
||||||
|
DictionaryList = dictionaryDtos
|
||||||
|
});
|
||||||
|
|
||||||
|
foreach (var userinfo in toUserList)
|
||||||
|
{
|
||||||
|
var messageToSend = new MimeMessage();
|
||||||
|
// 发件地址
|
||||||
|
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
|
||||||
|
messageToSend.To.Add(new MailboxAddress(String.Empty, userinfo.EMail));
|
||||||
|
|
||||||
|
// 添加抄送
|
||||||
|
foreach (var ccUser in ccUserList)
|
||||||
|
{
|
||||||
|
messageToSend.Cc.Add(new MailboxAddress(String.Empty, ccUser.EMail));
|
||||||
|
}
|
||||||
|
// 格式化邮件内容
|
||||||
|
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}
|
||||||
|
);
|
||||||
|
|
||||||
|
return (topicStr, htmlBodyStr);
|
||||||
|
};
|
||||||
|
|
||||||
|
await CommonEmailHelper.GetEmailSubejctAndHtmlInfoAndBuildAsync(inDto.EmailNoticeConfig, messageToSend, emailConfigFunc);
|
||||||
|
|
||||||
|
await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 处理PM申请阅片人筛选事件
|
||||||
|
/// </summary>
|
||||||
|
public async Task Consume(ConsumeContext<ReviewerPMApplyEvent> context)
|
||||||
|
{
|
||||||
|
Console.WriteLine("发送【阅片人筛选-PM申请审批】邮件!!!");
|
||||||
|
var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;
|
||||||
|
|
||||||
|
// 获取项目信息
|
||||||
|
var enrollIdList = context.Message.EnrollIdList;
|
||||||
|
if (enrollIdList == null || !enrollIdList.Any())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取第一个Enroll的TrialId
|
||||||
|
var enrollId = enrollIdList.First();
|
||||||
|
var enroll = await _enrollRepository.Where(x => x.Id == enrollId).FirstNotNullAsync();
|
||||||
|
var trialId = enroll.TrialId;
|
||||||
|
|
||||||
|
// 设置邮件场景
|
||||||
|
var scenario = EmailBusinessScenario.ReviewerSelection_PMApplyApproving; // 69
|
||||||
|
|
||||||
|
var emailConfig = _emailNoticeConfigrepository.Where(t => t.BusinessScenarioEnum == scenario && t.IsEnable && t.IsAutoSend).FirstOrDefault();
|
||||||
|
|
||||||
|
if (emailConfig != null)
|
||||||
|
{
|
||||||
|
await SendReviewerSelectionEmail(emailConfig, trialId, enrollIdList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 处理SPM审批阅片人筛选事件
|
||||||
|
/// </summary>
|
||||||
|
public async Task Consume(ConsumeContext<ReviewerSPMApprovedEvent> context)
|
||||||
|
{
|
||||||
|
Console.WriteLine("发送【阅片人筛选-SPM审批】邮件!!!");
|
||||||
|
var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;
|
||||||
|
|
||||||
|
// 获取项目信息
|
||||||
|
var enrollIdList = context.Message.EnrollIdList;
|
||||||
|
if (enrollIdList == null || !enrollIdList.Any())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取第一个Enroll的TrialId
|
||||||
|
var enrollId = enrollIdList.First();
|
||||||
|
var enroll = await _enrollRepository.Where(x => x.Id == enrollId).FirstNotNullAsync();
|
||||||
|
var trialId = enroll.TrialId;
|
||||||
|
|
||||||
|
// 设置邮件场景
|
||||||
|
var scenario = EmailBusinessScenario.ReviewerSelection_SPMCPMApproval; // 70
|
||||||
|
|
||||||
|
var emailConfig = _emailNoticeConfigrepository.Where(t => t.BusinessScenarioEnum == scenario && t.IsEnable && t.IsAutoSend).FirstOrDefault();
|
||||||
|
|
||||||
|
if (emailConfig != null)
|
||||||
|
{
|
||||||
|
await SendReviewerSelectionEmail(emailConfig, trialId, enrollIdList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 发送阅片人筛选相关邮件的通用方法
|
||||||
|
/// </summary>
|
||||||
|
private async Task SendReviewerSelectionEmail(EmailNoticeConfig emailNoticeConfig, Guid trialId, List<Guid> enrollIdList)
|
||||||
|
{
|
||||||
|
var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;
|
||||||
|
|
||||||
|
// 获取项目信息
|
||||||
|
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();
|
||||||
|
|
||||||
|
// 根据场景确定收件人
|
||||||
|
List<UserRole> toUserList = new List<UserRole>();
|
||||||
|
List<UserRole> ccUserList = new List<UserRole>();
|
||||||
|
|
||||||
|
var emailNoticeUserList = await _emailNoticeUserTypeRepository.Where(x => x.EmailNoticeConfigId == emailNoticeConfig.Id).ToListAsync();
|
||||||
|
|
||||||
|
var toList = emailNoticeUserList.Where(x => x.EmailUserType == EmailUserType.To).Select(x => x.UserType).ToList();
|
||||||
|
|
||||||
|
toUserList = trialUser.Where(x => toList.Contains(x.UserTypeEnum)).ToList();
|
||||||
|
|
||||||
|
var ccList = emailNoticeUserList.Where(x => x.EmailUserType == EmailUserType.Copy && x.UserType != UserTypeEnum.ClinicalResearchCoordinator).Select(x => x.UserType).ToList();
|
||||||
|
|
||||||
|
ccUserList = trialUser.Where(x => ccList.Contains(x.UserTypeEnum)).ToList();
|
||||||
|
|
||||||
|
|
||||||
|
// 如果没有收件人,则不发送邮件
|
||||||
|
if (toUserList.Count == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var userinfo in toUserList)
|
||||||
|
{
|
||||||
|
var messageToSend = new MimeMessage();
|
||||||
|
// 发件地址
|
||||||
|
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
|
||||||
|
messageToSend.To.Add(new MailboxAddress(String.Empty, userinfo.EMail));
|
||||||
|
|
||||||
|
// 添加抄送
|
||||||
|
foreach (var ccUser in ccUserList)
|
||||||
|
{
|
||||||
|
messageToSend.Cc.Add(new MailboxAddress(String.Empty, ccUser.EMail));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 格式化邮件内容
|
||||||
|
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}
|
||||||
|
trialInfo.ExperimentName, // 项目 {1}
|
||||||
|
"", // 受试者 {2} - 阅片人筛选不涉及受试者
|
||||||
|
"", // 访视 {3} - 阅片人筛选不涉及访视
|
||||||
|
"", // 是否加急 {4}
|
||||||
|
"", // 预留 {5}
|
||||||
|
_systemEmailConfig.SiteUrl // 链接 {6}
|
||||||
|
);
|
||||||
|
|
||||||
|
return (topicStr, htmlBodyStr);
|
||||||
|
};
|
||||||
|
|
||||||
|
await CommonEmailHelper.GetEmailSubejctAndHtmlInfoAndBuildAsync(emailNoticeConfig, messageToSend, emailConfigFunc);
|
||||||
|
|
||||||
|
await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -29,7 +29,7 @@ public class UrgentMedicalReviewAddedEventConsumer(
|
|||||||
IRepository<ReadingQuestionCriterionTrial> _readingQuestionCriterionTrialRepository,
|
IRepository<ReadingQuestionCriterionTrial> _readingQuestionCriterionTrialRepository,
|
||||||
IRepository<VisitTask> _visitTaskRepository,
|
IRepository<VisitTask> _visitTaskRepository,
|
||||||
IRepository<Dictionary> _dictionaryRepository,
|
IRepository<Dictionary> _dictionaryRepository,
|
||||||
IRepository<EmailNoticeConfig> _emailNoticeConfigrepository,
|
IRepository<TrialEmailNoticeConfig> _trialEmailNoticeConfigrepository,
|
||||||
IOptionsMonitor<SystemEmailSendConfig> systemEmailConfig
|
IOptionsMonitor<SystemEmailSendConfig> systemEmailConfig
|
||||||
) : IConsumer<UrgentMedicalReviewAddedEvent>
|
) : IConsumer<UrgentMedicalReviewAddedEvent>
|
||||||
{
|
{
|
||||||
@@ -48,52 +48,62 @@ public class UrgentMedicalReviewAddedEventConsumer(
|
|||||||
|
|
||||||
var medicalReviewId = context.Message.MedicalReviewId;
|
var medicalReviewId = context.Message.MedicalReviewId;
|
||||||
|
|
||||||
var medicalReview = await _taskMedicalReviewRepository.Where(x => x.Id == medicalReviewId).Include(x => x.VisitTask).Include(x=>x.MedicalManagerUser).FirstOrDefaultAsync();
|
var medicalReview = await _taskMedicalReviewRepository.Where(x => x.Id == medicalReviewId).Include(x => x.VisitTask).Include(x => x.MedicalManagerUser).FirstOrDefaultAsync();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (medicalReview.MedicalManagerUserId == null)
|
if (medicalReview.MedicalManagerUserId == null)
|
||||||
{
|
{
|
||||||
Console.WriteLine("MIMId为空 ID"+ medicalReviewId);
|
Console.WriteLine("MIMId为空 ID" + medicalReviewId);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var criterion = await _readingQuestionCriterionTrialRepository.FirstOrDefaultAsync(x => x.Id == medicalReview.VisitTask.TrialReadingCriterionId);
|
|
||||||
var userinfo = await _userRoleRepository.Where(x => x.Id == medicalReview.MedicalManagerUserId).FirstOrDefaultAsync();
|
|
||||||
|
|
||||||
var taskInfo = await _visitTaskRepository.Where(x => x.Id == medicalReview.VisitTaskId).Include(x=>x.SourceSubjectVisit).Include(x => x.ReadModule).Include(x => x.Subject).FirstNotNullAsync();
|
var trialId = medicalReview.TrialId;
|
||||||
|
|
||||||
|
var scenario = context.Message.IsPD ? EmailBusinessScenario.PDVerification_MedicalQC : EmailBusinessScenario.EligibilityVerification_MedicalQC;
|
||||||
|
|
||||||
var visitid = taskInfo.SourceSubjectVisit == null ? taskInfo.ReadModule.SubjectVisitId : taskInfo.SourceSubjectVisitId;
|
var trialEmailConfig = _trialEmailNoticeConfigrepository.Where(t => t.TrialId == trialId && t.BusinessScenarioEnum == scenario && t.IsAutoSend && t.IsEnable).FirstOrDefault();
|
||||||
|
|
||||||
|
if (trialEmailConfig != null)
|
||||||
var subjectVisit = await _subjectVisitRepository.Where(x => x.Id == visitid).FirstOrDefaultAsync();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var messageToSend = new MimeMessage();
|
|
||||||
//发件地址
|
|
||||||
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
|
|
||||||
messageToSend.To.Add(new MailboxAddress(String.Empty, userinfo.EMail));
|
|
||||||
|
|
||||||
var trialInfo = await _trialRepository.FirstOrDefaultAsync(t => t.Id == medicalReview.TrialId);
|
|
||||||
var companyName = isEn_US ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
|
|
||||||
|
|
||||||
|
|
||||||
var dictionValue = await CommonEmailHelper.TranslationDictionary(new TranslationDictionaryDto()
|
|
||||||
{
|
{
|
||||||
|
|
||||||
DictionaryRepository = _dictionaryRepository,
|
|
||||||
IsEn_US = isEn_US,
|
var criterion = await _readingQuestionCriterionTrialRepository.FirstOrDefaultAsync(x => x.Id == medicalReview.VisitTask.TrialReadingCriterionId);
|
||||||
|
var userinfo = await _userRoleRepository.Where(x => x.Id == medicalReview.MedicalManagerUserId).FirstOrDefaultAsync();
|
||||||
|
|
||||||
|
var taskInfo = await _visitTaskRepository.Where(x => x.Id == medicalReview.VisitTaskId).Include(x => x.SourceSubjectVisit).Include(x => x.ReadModule).Include(x => x.Subject).FirstNotNullAsync();
|
||||||
|
|
||||||
|
|
||||||
DictionaryList = new List<DictionaryDto>()
|
var visitid = taskInfo.SourceSubjectVisit == null ? taskInfo.ReadModule.SubjectVisitId : taskInfo.SourceSubjectVisitId;
|
||||||
{
|
|
||||||
|
|
||||||
|
var subjectVisit = await _subjectVisitRepository.Where(x => x.Id == visitid).FirstOrDefaultAsync();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var messageToSend = new MimeMessage();
|
||||||
|
//发件地址
|
||||||
|
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
|
||||||
|
messageToSend.To.Add(new MailboxAddress(String.Empty, userinfo.EMail));
|
||||||
|
|
||||||
|
var trialInfo = await _trialRepository.FirstOrDefaultAsync(t => t.Id == medicalReview.TrialId);
|
||||||
|
var companyName = isEn_US ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
|
||||||
|
|
||||||
|
|
||||||
|
var dictionValue = await CommonEmailHelper.TranslationDictionary(new TranslationDictionaryDto()
|
||||||
|
{
|
||||||
|
|
||||||
|
DictionaryRepository = _dictionaryRepository,
|
||||||
|
IsEn_US = isEn_US,
|
||||||
|
|
||||||
|
|
||||||
|
DictionaryList = new List<DictionaryDto>()
|
||||||
|
{
|
||||||
new DictionaryDto (){DictionaryCode= "ReadingCategory",EnumValue=taskInfo.ReadingCategory.GetEnumInt(), },
|
new DictionaryDto (){DictionaryCode= "ReadingCategory",EnumValue=taskInfo.ReadingCategory.GetEnumInt(), },
|
||||||
new DictionaryDto (){DictionaryCode= "MedicalReviewDoctorUserIdea",EnumValue=medicalReview.DoctorUserIdeaEnum.GetEnumInt(), },
|
new DictionaryDto (){DictionaryCode= "MedicalReviewDoctorUserIdea",EnumValue=medicalReview.DoctorUserIdeaEnum.GetEnumInt(), },
|
||||||
new DictionaryDto (){DictionaryCode= "MedicalReviewAuditState",EnumValue=medicalReview.AuditState.GetEnumInt(), },
|
new DictionaryDto (){DictionaryCode= "MedicalReviewAuditState",EnumValue=medicalReview.AuditState.GetEnumInt(), },
|
||||||
new DictionaryDto (){DictionaryCode= "YesOrNo",EnumValue=taskInfo.IsUrgent.ToString().ToLower(), }
|
new DictionaryDto (){DictionaryCode= "YesOrNo",EnumValue=taskInfo.IsUrgent.ToString().ToLower(), }
|
||||||
}
|
}
|
||||||
}) ;
|
});
|
||||||
|
|
||||||
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
|
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
|
||||||
{
|
{
|
||||||
@@ -107,7 +117,7 @@ public class UrgentMedicalReviewAddedEventConsumer(
|
|||||||
subjectName, // 受试者 {3}
|
subjectName, // 受试者 {3}
|
||||||
taskInfo.TaskBlindName, // 访视 {4}
|
taskInfo.TaskBlindName, // 访视 {4}
|
||||||
dictionValue[0], // 任务类型 {5}
|
dictionValue[0], // 任务类型 {5}
|
||||||
//dictionValue[1], // 阅片人是否同意 {6}
|
//dictionValue[1], // 阅片人是否同意 {6}
|
||||||
dictionValue[2], // 审核状态 {6}
|
dictionValue[2], // 审核状态 {6}
|
||||||
dictionValue[3], // 是否加急 {7}
|
dictionValue[3], // 是否加急 {7}
|
||||||
_systemEmailConfig.SiteUrl // 链接 {8}
|
_systemEmailConfig.SiteUrl // 链接 {8}
|
||||||
@@ -116,13 +126,12 @@ public class UrgentMedicalReviewAddedEventConsumer(
|
|||||||
return (topicStr, htmlBodyStr);
|
return (topicStr, htmlBodyStr);
|
||||||
};
|
};
|
||||||
|
|
||||||
await CommonEmailHelper.GetEmailSubejctAndHtmlInfoAndBuildAsync(_emailNoticeConfigrepository,
|
await CommonEmailHelper.GetTrialEmailSubejctAndHtmlInfoAndBuildAsync(trialEmailConfig, messageToSend, emailConfigFunc);
|
||||||
|
|
||||||
context.Message.IsPD ? EmailBusinessScenario.PDVerification_MedicalQC : EmailBusinessScenario.EligibilityVerification_MedicalQC,
|
await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig);
|
||||||
|
|
||||||
messageToSend, emailConfigFunc);
|
}
|
||||||
|
|
||||||
await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -135,7 +144,7 @@ public class UrgentIRRepliedMedicalReviewConsumer(
|
|||||||
IRepository<ReadingQuestionCriterionTrial> _readingQuestionCriterionTrialRepository,
|
IRepository<ReadingQuestionCriterionTrial> _readingQuestionCriterionTrialRepository,
|
||||||
IRepository<VisitTask> _visitTaskRepository,
|
IRepository<VisitTask> _visitTaskRepository,
|
||||||
IRepository<Dictionary> _dictionaryRepository,
|
IRepository<Dictionary> _dictionaryRepository,
|
||||||
IRepository<EmailNoticeConfig> _emailNoticeConfigrepository,
|
IRepository<TrialEmailNoticeConfig> _trialEmailNoticeConfigrepository,
|
||||||
IOptionsMonitor<SystemEmailSendConfig> systemEmailConfig) : IConsumer<UrgentIRRepliedMedicalReview>
|
IOptionsMonitor<SystemEmailSendConfig> systemEmailConfig) : IConsumer<UrgentIRRepliedMedicalReview>
|
||||||
{
|
{
|
||||||
private readonly SystemEmailSendConfig _systemEmailConfig = systemEmailConfig.CurrentValue;
|
private readonly SystemEmailSendConfig _systemEmailConfig = systemEmailConfig.CurrentValue;
|
||||||
@@ -151,79 +160,85 @@ public class UrgentIRRepliedMedicalReviewConsumer(
|
|||||||
|
|
||||||
var medicalReview = await _taskMedicalReviewRepository.Where(x => x.Id == medicalReviewId).Include(x => x.VisitTask).Include(x => x.MedicalManagerUser).FirstOrDefaultAsync();
|
var medicalReview = await _taskMedicalReviewRepository.Where(x => x.Id == medicalReviewId).Include(x => x.VisitTask).Include(x => x.MedicalManagerUser).FirstOrDefaultAsync();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (medicalReview.MedicalManagerUserId == null)
|
if (medicalReview.MedicalManagerUserId == null)
|
||||||
{
|
{
|
||||||
Console.WriteLine("MIMId为空 ID" + medicalReviewId);
|
Console.WriteLine("MIMId为空 ID" + medicalReviewId);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var criterion = await _readingQuestionCriterionTrialRepository.FirstOrDefaultAsync(x => x.Id == medicalReview.VisitTask.TrialReadingCriterionId);
|
var trialId = medicalReview.TrialId;
|
||||||
var userinfo = await _userRoleRepository.Where(x => x.Id == medicalReview.MedicalManagerUserId).FirstOrDefaultAsync();
|
|
||||||
|
|
||||||
var taskInfo = await _visitTaskRepository.Where(x => x.Id == medicalReview.VisitTaskId).Include(x => x.SourceSubjectVisit).Include(x => x.ReadModule).Include(x => x.Subject).FirstNotNullAsync();
|
var scenario = context.Message.IsPD ? EmailBusinessScenario.PDVerification_ExpeditedMedicalQCResponse : EmailBusinessScenario.EligibilityVerification_ExpeditedMedicalQCResponse;
|
||||||
|
|
||||||
|
var trialEmailConfig = _trialEmailNoticeConfigrepository.Where(t => t.TrialId == trialId && t.BusinessScenarioEnum == scenario && t.IsAutoSend && t.IsEnable).FirstOrDefault();
|
||||||
|
|
||||||
var visitid = taskInfo.SourceSubjectVisit == null ? taskInfo.ReadModule.SubjectVisitId : taskInfo.SourceSubjectVisitId;
|
if (trialEmailConfig != null)
|
||||||
|
|
||||||
|
|
||||||
var subjectVisit = await _subjectVisitRepository.Where(x => x.Id == visitid).FirstOrDefaultAsync();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var messageToSend = new MimeMessage();
|
|
||||||
//发件地址
|
|
||||||
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
|
|
||||||
messageToSend.To.Add(new MailboxAddress(String.Empty, userinfo.EMail));
|
|
||||||
|
|
||||||
var trialInfo = await _trialRepository.FirstOrDefaultAsync(t => t.Id == medicalReview.TrialId);
|
|
||||||
var companyName = isEn_US ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
|
|
||||||
|
|
||||||
|
|
||||||
var dictionValue = await CommonEmailHelper.TranslationDictionary(new TranslationDictionaryDto()
|
|
||||||
{
|
{
|
||||||
|
|
||||||
DictionaryRepository = _dictionaryRepository,
|
|
||||||
IsEn_US = isEn_US,
|
|
||||||
|
var criterion = await _readingQuestionCriterionTrialRepository.FirstOrDefaultAsync(x => x.Id == medicalReview.VisitTask.TrialReadingCriterionId);
|
||||||
|
var userinfo = await _userRoleRepository.Where(x => x.Id == medicalReview.MedicalManagerUserId).FirstOrDefaultAsync();
|
||||||
|
|
||||||
|
var taskInfo = await _visitTaskRepository.Where(x => x.Id == medicalReview.VisitTaskId).Include(x => x.SourceSubjectVisit).Include(x => x.ReadModule).Include(x => x.Subject).FirstNotNullAsync();
|
||||||
|
|
||||||
|
|
||||||
DictionaryList = new List<DictionaryDto>()
|
var visitid = taskInfo.SourceSubjectVisit == null ? taskInfo.ReadModule.SubjectVisitId : taskInfo.SourceSubjectVisitId;
|
||||||
|
|
||||||
|
|
||||||
|
var subjectVisit = await _subjectVisitRepository.Where(x => x.Id == visitid).FirstOrDefaultAsync();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var messageToSend = new MimeMessage();
|
||||||
|
//发件地址
|
||||||
|
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
|
||||||
|
messageToSend.To.Add(new MailboxAddress(String.Empty, userinfo.EMail));
|
||||||
|
|
||||||
|
var trialInfo = await _trialRepository.FirstOrDefaultAsync(t => t.Id == medicalReview.TrialId);
|
||||||
|
var companyName = isEn_US ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
|
||||||
|
|
||||||
|
|
||||||
|
var dictionValue = await CommonEmailHelper.TranslationDictionary(new TranslationDictionaryDto()
|
||||||
|
{
|
||||||
|
|
||||||
|
DictionaryRepository = _dictionaryRepository,
|
||||||
|
IsEn_US = isEn_US,
|
||||||
|
|
||||||
|
|
||||||
|
DictionaryList = new List<DictionaryDto>()
|
||||||
{
|
{
|
||||||
new DictionaryDto (){DictionaryCode= "ReadingCategory",EnumValue=taskInfo.ReadingCategory.GetEnumInt(), },
|
new DictionaryDto (){DictionaryCode= "ReadingCategory",EnumValue=taskInfo.ReadingCategory.GetEnumInt(), },
|
||||||
new DictionaryDto (){DictionaryCode= "MedicalReviewDoctorUserIdea",EnumValue=medicalReview.DoctorUserIdeaEnum.GetEnumInt(), },
|
new DictionaryDto (){DictionaryCode= "MedicalReviewDoctorUserIdea",EnumValue=medicalReview.DoctorUserIdeaEnum.GetEnumInt(), },
|
||||||
new DictionaryDto (){DictionaryCode= "MedicalReviewAuditState",EnumValue=medicalReview.AuditState.GetEnumInt(), },
|
new DictionaryDto (){DictionaryCode= "MedicalReviewAuditState",EnumValue=medicalReview.AuditState.GetEnumInt(), },
|
||||||
new DictionaryDto (){DictionaryCode= "YesOrNo",EnumValue=taskInfo.IsUrgent.ToString().ToLower(), }
|
new DictionaryDto (){DictionaryCode= "YesOrNo",EnumValue=taskInfo.IsUrgent.ToString().ToLower(), }
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
|
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
|
||||||
{
|
{
|
||||||
var subjectCode = taskInfo.BlindSubjectCode.IsNullOrEmpty() ? taskInfo.Subject.Code : taskInfo.BlindSubjectCode;
|
var subjectCode = taskInfo.BlindSubjectCode.IsNullOrEmpty() ? taskInfo.Subject.Code : taskInfo.BlindSubjectCode;
|
||||||
var topicStr = string.Format(input.topicStr, trialInfo.ResearchProgramNo, subjectCode, taskInfo.TaskBlindName);
|
var topicStr = string.Format(input.topicStr, trialInfo.ResearchProgramNo, subjectCode, taskInfo.TaskBlindName);
|
||||||
var htmlBodyStr = string.Format(
|
var htmlBodyStr = string.Format(
|
||||||
CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr),
|
CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr),
|
||||||
userinfo.FullName, // 用户名 {0}
|
userinfo.FullName, // 用户名 {0}
|
||||||
trialInfo.ExperimentName, // 项目 {1}
|
trialInfo.ExperimentName, // 项目 {1}
|
||||||
criterion.CriterionName, // 阅片标准 {2}
|
criterion.CriterionName, // 阅片标准 {2}
|
||||||
subjectCode, // 受试者 {3}
|
subjectCode, // 受试者 {3}
|
||||||
taskInfo.TaskBlindName, // 访视 {4}
|
taskInfo.TaskBlindName, // 访视 {4}
|
||||||
dictionValue[0], // 任务类型 {5}
|
dictionValue[0], // 任务类型 {5}
|
||||||
dictionValue[1], // 阅片人是否同意 {6}
|
dictionValue[1], // 阅片人是否同意 {6}
|
||||||
dictionValue[2], // 审核状态 {7}
|
dictionValue[2], // 审核状态 {7}
|
||||||
dictionValue[3], // 是否加急 {8}
|
dictionValue[3], // 是否加急 {8}
|
||||||
_systemEmailConfig.SiteUrl // 链接 {9}
|
_systemEmailConfig.SiteUrl // 链接 {9}
|
||||||
);
|
);
|
||||||
|
|
||||||
return (topicStr, htmlBodyStr);
|
return (topicStr, htmlBodyStr);
|
||||||
};
|
};
|
||||||
|
await CommonEmailHelper.GetTrialEmailSubejctAndHtmlInfoAndBuildAsync(trialEmailConfig, messageToSend, emailConfigFunc);
|
||||||
|
|
||||||
await CommonEmailHelper.GetEmailSubejctAndHtmlInfoAndBuildAsync(_emailNoticeConfigrepository,
|
await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig);
|
||||||
|
}
|
||||||
|
|
||||||
context.Message.IsPD ? EmailBusinessScenario.PDVerification_ExpeditedMedicalQCResponse : EmailBusinessScenario.EligibilityVerification_ExpeditedMedicalQCResponse,
|
|
||||||
|
|
||||||
messageToSend, emailConfigFunc);
|
|
||||||
|
|
||||||
await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -238,7 +253,7 @@ public class UrgentMIMRepliedMedicalReviewConsumer(
|
|||||||
IRepository<ReadingQuestionCriterionTrial> _readingQuestionCriterionTrialRepository,
|
IRepository<ReadingQuestionCriterionTrial> _readingQuestionCriterionTrialRepository,
|
||||||
IRepository<VisitTask> _visitTaskRepository,
|
IRepository<VisitTask> _visitTaskRepository,
|
||||||
IRepository<Dictionary> _dictionaryRepository,
|
IRepository<Dictionary> _dictionaryRepository,
|
||||||
IRepository<EmailNoticeConfig> _emailNoticeConfigrepository,
|
IRepository<TrialEmailNoticeConfig> _trialEmailNoticeConfigrepository,
|
||||||
IOptionsMonitor<SystemEmailSendConfig> systemEmailConfig) : IConsumer<UrgentMIMRepliedMedicalReview>
|
IOptionsMonitor<SystemEmailSendConfig> systemEmailConfig) : IConsumer<UrgentMIMRepliedMedicalReview>
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -254,91 +269,93 @@ public class UrgentMIMRepliedMedicalReviewConsumer(
|
|||||||
Console.WriteLine("发送(022) 【加急医学反馈】邮件!!!");
|
Console.WriteLine("发送(022) 【加急医学反馈】邮件!!!");
|
||||||
var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;
|
var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;
|
||||||
|
|
||||||
|
|
||||||
var medicalReviewId = context.Message.MedicalReviewId;
|
var medicalReviewId = context.Message.MedicalReviewId;
|
||||||
|
|
||||||
var medicalReview = await _taskMedicalReviewRepository.Where(x => x.Id == medicalReviewId).Include(x => x.VisitTask).Include(x => x.MedicalManagerUser).FirstOrDefaultAsync();
|
var medicalReview = await _taskMedicalReviewRepository.Where(x => x.Id == medicalReviewId).Include(x => x.VisitTask).Include(x => x.MedicalManagerUser).FirstOrDefaultAsync();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (medicalReview.MedicalManagerUserId == null)
|
if (medicalReview.MedicalManagerUserId == null)
|
||||||
{
|
{
|
||||||
Console.WriteLine("MIMId为空 ID" + medicalReviewId);
|
Console.WriteLine("MIMId为空 ID" + medicalReviewId);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
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 trialId = medicalReview.TrialId;
|
||||||
|
|
||||||
|
var scenario = EmailBusinessScenario.ExpeditedMedicalQCToIR;
|
||||||
|
|
||||||
|
var trialEmailConfig = _trialEmailNoticeConfigrepository.Where(t => t.TrialId == trialId && t.BusinessScenarioEnum == scenario && t.IsAutoSend && t.IsEnable).FirstOrDefault();
|
||||||
|
|
||||||
var visitid = taskInfo.SourceSubjectVisit == null ? taskInfo.ReadModule.SubjectVisitId : taskInfo.SourceSubjectVisitId;
|
if (trialEmailConfig != null)
|
||||||
|
|
||||||
|
|
||||||
var subjectVisit = await _subjectVisitRepository.Where(x => x.Id == visitid).FirstOrDefaultAsync();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var messageToSend = new MimeMessage();
|
|
||||||
//发件地址
|
|
||||||
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
|
|
||||||
messageToSend.To.Add(new MailboxAddress(String.Empty, userinfo.EMail));
|
|
||||||
|
|
||||||
var trialInfo = await _trialRepository.FirstOrDefaultAsync(t => t.Id == medicalReview.TrialId);
|
|
||||||
var companyName = isEn_US ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
|
|
||||||
|
|
||||||
|
|
||||||
var dictionValue = await CommonEmailHelper.TranslationDictionary(new TranslationDictionaryDto()
|
|
||||||
{
|
{
|
||||||
|
|
||||||
DictionaryRepository = _dictionaryRepository,
|
|
||||||
IsEn_US = isEn_US,
|
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();
|
||||||
|
|
||||||
|
|
||||||
DictionaryList = new List<DictionaryDto>()
|
|
||||||
|
|
||||||
|
var visitid = taskInfo.SourceSubjectVisit == null ? taskInfo.ReadModule.SubjectVisitId : taskInfo.SourceSubjectVisitId;
|
||||||
|
|
||||||
|
|
||||||
|
var subjectVisit = await _subjectVisitRepository.Where(x => x.Id == visitid).FirstOrDefaultAsync();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var messageToSend = new MimeMessage();
|
||||||
|
//发件地址
|
||||||
|
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
|
||||||
|
messageToSend.To.Add(new MailboxAddress(String.Empty, userinfo.EMail));
|
||||||
|
|
||||||
|
var trialInfo = await _trialRepository.FirstOrDefaultAsync(t => t.Id == medicalReview.TrialId);
|
||||||
|
var companyName = isEn_US ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
|
||||||
|
|
||||||
|
|
||||||
|
var dictionValue = await CommonEmailHelper.TranslationDictionary(new TranslationDictionaryDto()
|
||||||
|
{
|
||||||
|
|
||||||
|
DictionaryRepository = _dictionaryRepository,
|
||||||
|
IsEn_US = isEn_US,
|
||||||
|
|
||||||
|
|
||||||
|
DictionaryList = new List<DictionaryDto>()
|
||||||
{
|
{
|
||||||
new DictionaryDto (){DictionaryCode= "ReadingCategory",EnumValue=taskInfo.ReadingCategory.GetEnumInt(), },
|
new DictionaryDto (){DictionaryCode= "ReadingCategory",EnumValue=taskInfo.ReadingCategory.GetEnumInt(), },
|
||||||
new DictionaryDto (){DictionaryCode= "IsPass",EnumValue=medicalReview.IsHaveQuestion.ToString().ToLower(), },// 审核结论
|
new DictionaryDto (){DictionaryCode= "IsPass",EnumValue=medicalReview.IsHaveQuestion.ToString().ToLower(), },// 审核结论
|
||||||
new DictionaryDto (){DictionaryCode= "AuditAdvice",EnumValue=medicalReview.AuditAdviceEnum.GetEnumInt(), },// 审核建议
|
new DictionaryDto (){DictionaryCode= "AuditAdvice",EnumValue=medicalReview.AuditAdviceEnum.GetEnumInt(), },// 审核建议
|
||||||
new DictionaryDto (){DictionaryCode= "YesOrNo",EnumValue=taskInfo.IsUrgent.ToString().ToLower(), }, //是否加急
|
new DictionaryDto (){DictionaryCode= "YesOrNo",EnumValue=taskInfo.IsUrgent.ToString().ToLower(), }, //是否加急
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
|
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
|
||||||
{
|
{
|
||||||
var subjectCode = taskInfo.BlindSubjectCode.IsNullOrEmpty() ? taskInfo.Subject.Code : taskInfo.BlindSubjectCode;
|
var subjectCode = taskInfo.BlindSubjectCode.IsNullOrEmpty() ? taskInfo.Subject.Code : taskInfo.BlindSubjectCode;
|
||||||
var topicStr = string.Format(input.topicStr, trialInfo.ResearchProgramNo, subjectCode, taskInfo.TaskBlindName);
|
var topicStr = string.Format(input.topicStr, trialInfo.ResearchProgramNo, subjectCode, taskInfo.TaskBlindName);
|
||||||
var htmlBodyStr = string.Format(
|
var htmlBodyStr = string.Format(
|
||||||
CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr),
|
CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr),
|
||||||
userinfo.FullName, // 用户名 {0}
|
userinfo.FullName, // 用户名 {0}
|
||||||
trialInfo.ExperimentName, // 项目 {1}
|
trialInfo.ExperimentName, // 项目 {1}
|
||||||
subjectCode, // 受试者 {2}
|
subjectCode, // 受试者 {2}
|
||||||
taskInfo.TaskBlindName, // 访视 {3}
|
taskInfo.TaskBlindName, // 访视 {3}
|
||||||
criterion.CriterionName, // 阅片标准 {4}
|
criterion.CriterionName, // 阅片标准 {4}
|
||||||
dictionValue[0], // 任务类型 {5}
|
dictionValue[0], // 任务类型 {5}
|
||||||
dictionValue[1], // 审核结论 {6}
|
dictionValue[1], // 审核结论 {6}
|
||||||
dictionValue[2], // 医学审核建议 {7}
|
dictionValue[2], // 医学审核建议 {7}
|
||||||
dictionValue[3], // 是否加急 {8}
|
dictionValue[3], // 是否加急 {8}
|
||||||
|
|
||||||
_systemEmailConfig.SiteUrl // 链接 {9}
|
_systemEmailConfig.SiteUrl // 链接 {9}
|
||||||
);
|
);
|
||||||
|
|
||||||
return (topicStr, htmlBodyStr);
|
return (topicStr, htmlBodyStr);
|
||||||
};
|
};
|
||||||
|
|
||||||
await CommonEmailHelper.GetEmailSubejctAndHtmlInfoAndBuildAsync(_emailNoticeConfigrepository,
|
await CommonEmailHelper.GetTrialEmailSubejctAndHtmlInfoAndBuildAsync(trialEmailConfig, messageToSend, emailConfigFunc);
|
||||||
|
|
||||||
EmailBusinessScenario.ExpeditedMedicalQCToIR,
|
await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig);
|
||||||
|
}
|
||||||
messageToSend, emailConfigFunc);
|
|
||||||
|
|
||||||
await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -354,7 +371,7 @@ public class UrgentIRApplyedReReadingConsumer(
|
|||||||
IRepository<ReadingQuestionCriterionTrial> _readingQuestionCriterionTrialRepository,
|
IRepository<ReadingQuestionCriterionTrial> _readingQuestionCriterionTrialRepository,
|
||||||
IRepository<VisitTask> _visitTaskRepository,
|
IRepository<VisitTask> _visitTaskRepository,
|
||||||
IRepository<Dictionary> _dictionaryRepository,
|
IRepository<Dictionary> _dictionaryRepository,
|
||||||
IRepository<EmailNoticeConfig> _emailNoticeConfigrepository,
|
IRepository<TrialEmailNoticeConfig> _trialEmailNoticeConfigrepository,
|
||||||
IOptionsMonitor<SystemEmailSendConfig> systemEmailConfig) : IConsumer<UrgentApplyedReReading>
|
IOptionsMonitor<SystemEmailSendConfig> systemEmailConfig) : IConsumer<UrgentApplyedReReading>
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -367,82 +384,90 @@ public class UrgentIRApplyedReReadingConsumer(
|
|||||||
var visitTaskId = context.Message.VisitTaskId;
|
var visitTaskId = context.Message.VisitTaskId;
|
||||||
|
|
||||||
var taskInfo = await _visitTaskRepository.Where(x => x.Id == visitTaskId).Include(x => x.SourceSubjectVisit).Include(x => x.ReadModule).Include(x => x.Subject).FirstNotNullAsync();
|
var taskInfo = await _visitTaskRepository.Where(x => x.Id == visitTaskId).Include(x => x.SourceSubjectVisit).Include(x => x.ReadModule).Include(x => x.Subject).FirstNotNullAsync();
|
||||||
var criterion = await _readingQuestionCriterionTrialRepository.FirstOrDefaultAsync(x => x.Id == taskInfo.TrialReadingCriterionId);
|
|
||||||
|
|
||||||
|
|
||||||
var doctorInfo = await _userRoleRepository.Where(x => x.Id == taskInfo.DoctorUserId).FirstOrDefaultAsync();
|
var trialId=taskInfo.TrialId;
|
||||||
|
|
||||||
var trialUser = await _trialUseRoleRepository.Where(x => x.TrialId == taskInfo.TrialId).Include(x => x.UserRole).Select(x=>x.UserRole).ToListAsync();
|
var scenario = context.Message.ReReadingApplyState == ReReadingApplyState.TrialGroupHaveApplyed ? EmailBusinessScenario.ReReadFromPMApproval : EmailBusinessScenario.ReReadFromIRApproval;
|
||||||
|
|
||||||
var userinfoList = trialUser.Where(x => x.UserTypeEnum == UserTypeEnum.ProjectManager||x.UserTypeEnum==UserTypeEnum.APM).ToList();
|
var trialEmailConfig = _trialEmailNoticeConfigrepository.Where(t => t.TrialId == trialId && t.BusinessScenarioEnum == scenario && t.IsAutoSend && t.IsEnable).FirstOrDefault();
|
||||||
if (context.Message.ReReadingApplyState == ReReadingApplyState.TrialGroupHaveApplyed)
|
|
||||||
|
if (trialEmailConfig != null)
|
||||||
{
|
{
|
||||||
userinfoList = trialUser.Where(x => x.UserTypeEnum == UserTypeEnum.CPM || x.UserTypeEnum == UserTypeEnum.SPM).ToList();
|
|
||||||
}
|
|
||||||
|
|
||||||
var visitid = taskInfo.SourceSubjectVisit == null ? taskInfo.ReadModule.SubjectVisitId : taskInfo.SourceSubjectVisitId;
|
|
||||||
|
var criterion = await _readingQuestionCriterionTrialRepository.FirstOrDefaultAsync(x => x.Id == taskInfo.TrialReadingCriterionId);
|
||||||
|
|
||||||
|
|
||||||
var subjectVisit = await _subjectVisitRepository.Where(x => x.Id == visitid).FirstOrDefaultAsync();
|
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();
|
||||||
|
|
||||||
foreach (var userinfo in userinfoList)
|
var userinfoList = trialUserList.Where(x => x.UserTypeEnum == UserTypeEnum.ProjectManager || x.UserTypeEnum == UserTypeEnum.APM).ToList();
|
||||||
{
|
if (context.Message.ReReadingApplyState == ReReadingApplyState.TrialGroupHaveApplyed)
|
||||||
var messageToSend = new MimeMessage();
|
|
||||||
//发件地址
|
|
||||||
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
|
|
||||||
messageToSend.To.Add(new MailboxAddress(String.Empty, userinfo.EMail));
|
|
||||||
|
|
||||||
var trialInfo = await _trialRepository.FirstOrDefaultAsync(t => t.Id == taskInfo.TrialId);
|
|
||||||
var companyName = isEn_US ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
|
|
||||||
|
|
||||||
|
|
||||||
var dictionValue = await CommonEmailHelper.TranslationDictionary(new TranslationDictionaryDto()
|
|
||||||
{
|
{
|
||||||
|
userinfoList = trialUserList.Where(x => x.UserTypeEnum == UserTypeEnum.CPM || x.UserTypeEnum == UserTypeEnum.SPM).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
DictionaryRepository = _dictionaryRepository,
|
var visitid = taskInfo.SourceSubjectVisit == null ? taskInfo.ReadModule.SubjectVisitId : taskInfo.SourceSubjectVisitId;
|
||||||
IsEn_US = isEn_US,
|
|
||||||
DictionaryList = new List<DictionaryDto>()
|
|
||||||
|
var subjectVisit = await _subjectVisitRepository.Where(x => x.Id == visitid).FirstOrDefaultAsync();
|
||||||
|
|
||||||
|
|
||||||
|
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 trialInfo = await _trialRepository.FirstOrDefaultAsync(t => t.Id == taskInfo.TrialId);
|
||||||
|
var companyName = isEn_US ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
|
||||||
|
|
||||||
|
|
||||||
|
var dictionValue = await CommonEmailHelper.TranslationDictionary(new TranslationDictionaryDto()
|
||||||
|
{
|
||||||
|
|
||||||
|
DictionaryRepository = _dictionaryRepository,
|
||||||
|
IsEn_US = isEn_US,
|
||||||
|
DictionaryList = new List<DictionaryDto>()
|
||||||
{
|
{
|
||||||
new DictionaryDto (){DictionaryCode= "ReadingCategory",EnumValue=taskInfo.ReadingCategory.GetEnumInt(), }, //任务类型
|
new DictionaryDto (){DictionaryCode= "ReadingCategory",EnumValue=taskInfo.ReadingCategory.GetEnumInt(), }, //任务类型
|
||||||
new DictionaryDto (){DictionaryCode= "RequestReReadingResult",EnumValue="0", }, //审批结果 都是待审批
|
new DictionaryDto (){DictionaryCode= "RequestReReadingResult",EnumValue="0", }, //审批结果 都是待审批
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
|
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
|
||||||
{
|
{
|
||||||
var subjectCode = taskInfo.BlindSubjectCode.IsNullOrEmpty() ? taskInfo.Subject.Code : taskInfo.BlindSubjectCode;
|
var subjectCode = taskInfo.BlindSubjectCode.IsNullOrEmpty() ? taskInfo.Subject.Code : taskInfo.BlindSubjectCode;
|
||||||
var topicStr = string.Format(input.topicStr, trialInfo.ResearchProgramNo, subjectCode, taskInfo.TaskBlindName);
|
var topicStr = string.Format(input.topicStr, trialInfo.ResearchProgramNo, subjectCode, taskInfo.TaskBlindName);
|
||||||
var htmlBodyStr = string.Format(
|
var htmlBodyStr = string.Format(
|
||||||
CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr),
|
CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr),
|
||||||
userinfo.FullName, // 用户名 {0}
|
userinfo.FullName, // 用户名 {0}
|
||||||
trialInfo.ExperimentName, // 项目 {1}
|
trialInfo.ExperimentName, // 项目 {1}
|
||||||
subjectCode, // 受试者 {2}
|
subjectCode, // 受试者 {2}
|
||||||
taskInfo.TaskBlindName, // 访视 {3}
|
taskInfo.TaskBlindName, // 访视 {3}
|
||||||
dictionValue[0], // 任务类型 {4}
|
dictionValue[0], // 任务类型 {4}
|
||||||
doctorInfo.FullName, // 阅片人 {5}
|
doctorInfo.FullName, // 阅片人 {5}
|
||||||
criterion.CriterionName, // 阅片标准 {6}
|
criterion.CriterionName, // 阅片标准 {6}
|
||||||
dictionValue[1], // 审批结果 {7}
|
dictionValue[1], // 审批结果 {7}
|
||||||
_systemEmailConfig.SiteUrl // 链接 {8}
|
_systemEmailConfig.SiteUrl // 链接 {8}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
return (topicStr, htmlBodyStr);
|
return (topicStr, htmlBodyStr);
|
||||||
};
|
};
|
||||||
|
|
||||||
await CommonEmailHelper.GetEmailSubejctAndHtmlInfoAndBuildAsync(_emailNoticeConfigrepository,
|
await CommonEmailHelper.GetTrialEmailSubejctAndHtmlInfoAndBuildAsync(trialEmailConfig, messageToSend, emailConfigFunc);
|
||||||
|
|
||||||
context.Message.ReReadingApplyState == ReReadingApplyState.TrialGroupHaveApplyed? EmailBusinessScenario.ReReadFromPMApproval: EmailBusinessScenario.ReReadFromIRApproval,
|
await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig);
|
||||||
|
}
|
||||||
messageToSend, emailConfigFunc);
|
|
||||||
|
|
||||||
await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ using System.Threading.Tasks;
|
|||||||
namespace IRaCIS.Core.Application.MassTransit.Consumer;
|
namespace IRaCIS.Core.Application.MassTransit.Consumer;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 用户提交 发送邮件 通知SPM 或者PM
|
/// 用户提交 发送邮件 通知SPM 或者PM 项目默认邮件,不用添加到项目中,直接发送的
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class UserSiteSurveySubmitedEventConsumer(
|
public class UserSiteSurveySubmitedEventConsumer(
|
||||||
IRepository<Trial> _trialRepository,
|
IRepository<Trial> _trialRepository,
|
||||||
@@ -47,75 +47,83 @@ public class UserSiteSurveySubmitedEventConsumer(
|
|||||||
|
|
||||||
var trialId = siteSurveyInfo.TrialId;
|
var trialId = siteSurveyInfo.TrialId;
|
||||||
|
|
||||||
var trialUserList = await _trialUserRoleRepository.Where(t => t.TrialId == siteSurveyInfo.TrialId)
|
|
||||||
.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();
|
|
||||||
|
|
||||||
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 (sPMOrCPMList.Count > 0)
|
|
||||||
{
|
|
||||||
foreach (var user in sPMOrCPMList)
|
|
||||||
{
|
|
||||||
messageToSend.To.Add(new MailboxAddress(user.FullName, user.EMail));
|
|
||||||
}
|
|
||||||
|
|
||||||
toUserName = string.Join('、', sPMOrCPMList.Select(t => t.FullName));
|
|
||||||
|
|
||||||
foreach (var user in pmAndAPMList)
|
|
||||||
{
|
|
||||||
messageToSend.Cc.Add(new MailboxAddress(user.FullName, user.EMail));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
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 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);
|
|
||||||
};
|
|
||||||
|
|
||||||
var scenario = _trialSiteSurveyRepository.Where(t => t.Id != trialSiteSurveyId && t.TrialId == siteSurveyInfo.TrialId && t.TrialSiteId == siteSurveyInfo.TrialSiteId).IgnoreQueryFilters().Any() ?
|
var scenario = _trialSiteSurveyRepository.Where(t => t.Id != trialSiteSurveyId && t.TrialId == siteSurveyInfo.TrialId && t.TrialSiteId == siteSurveyInfo.TrialSiteId).IgnoreQueryFilters().Any() ?
|
||||||
EmailBusinessScenario.Approval_UpdateSiteSurvey : EmailBusinessScenario.Approval_SubmitSiteSurvey;
|
EmailBusinessScenario.Approval_UpdateSiteSurvey : EmailBusinessScenario.Approval_SubmitSiteSurvey;
|
||||||
|
|
||||||
await CommonEmailHelper.GetEmailSubejctAndHtmlInfoAndBuildAsync(_emailNoticeConfigrepository, scenario, messageToSend, emailConfigFunc);
|
|
||||||
|
|
||||||
await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig);
|
var emailConfig = _emailNoticeConfigrepository.Where(t => t.BusinessScenarioEnum == scenario && t.IsAutoSend && t.IsEnable).FirstOrDefault();
|
||||||
|
|
||||||
|
if (emailConfig != null)
|
||||||
|
{
|
||||||
|
|
||||||
|
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();
|
||||||
|
|
||||||
|
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 (sPMOrCPMList.Count > 0)
|
||||||
|
{
|
||||||
|
foreach (var user in sPMOrCPMList)
|
||||||
|
{
|
||||||
|
messageToSend.To.Add(new MailboxAddress(user.FullName, user.EMail));
|
||||||
|
}
|
||||||
|
|
||||||
|
toUserName = string.Join('、', sPMOrCPMList.Select(t => t.FullName));
|
||||||
|
|
||||||
|
foreach (var user in pmAndAPMList)
|
||||||
|
{
|
||||||
|
messageToSend.Cc.Add(new MailboxAddress(user.FullName, user.EMail));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
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 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, _systemEmailConfig);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -143,55 +151,65 @@ public class SiteSurveySPMSubmitedEventConsumer(
|
|||||||
|
|
||||||
var trialId = siteSurveyInfo.TrialId;
|
var trialId = siteSurveyInfo.TrialId;
|
||||||
|
|
||||||
var messageToSend = new MimeMessage();
|
var scenario = EmailBusinessScenario.Approval_SubmitSiteSurvey;
|
||||||
|
|
||||||
var trialUserList = _trialUserRoleRepository.Where(t => t.TrialId == trialId)
|
var emailConfig = _emailNoticeConfigrepository.Where(t => t.BusinessScenarioEnum == scenario && t.IsAutoSend && t.IsEnable).FirstOrDefault();
|
||||||
.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();
|
if (emailConfig != null)
|
||||||
var pmAndAPMList = trialUserList.Where(t => t.UserTypeEnum == UserTypeEnum.ProjectManager || t.UserTypeEnum == UserTypeEnum.APM).ToList();
|
|
||||||
|
|
||||||
var toUserName = string.Empty;
|
|
||||||
|
|
||||||
foreach (var item in pmAndAPMList)
|
|
||||||
{
|
{
|
||||||
messageToSend.To.Add(new MailboxAddress(item.FullName, item.EMail));
|
var messageToSend = new MimeMessage();
|
||||||
|
|
||||||
toUserName = string.Join('、', pmAndAPMList.Select(t => t.FullName));
|
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)
|
||||||
|
{
|
||||||
|
messageToSend.To.Add(new MailboxAddress(item.FullName, item.EMail));
|
||||||
|
|
||||||
|
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, _systemEmailConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
//发件地址
|
|
||||||
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(_emailNoticeConfigrepository, EmailBusinessScenario.Approval_SubmitSiteSurvey, messageToSend, emailConfigFunc);
|
|
||||||
|
|
||||||
await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -204,7 +222,7 @@ public class SiteSurverRejectedEventConsumer(
|
|||||||
IRepository<Trial> _trialRepository,
|
IRepository<Trial> _trialRepository,
|
||||||
IRepository<TrialSite> _trialSiteRepository,
|
IRepository<TrialSite> _trialSiteRepository,
|
||||||
IRepository<TrialSiteSurvey> _trialSiteSurveyRepository,
|
IRepository<TrialSiteSurvey> _trialSiteSurveyRepository,
|
||||||
IRepository<EmailNoticeConfig> _emailNoticeConfigrepository,
|
IRepository<EmailNoticeConfig> _emailNoticeConfigrepository,
|
||||||
IOptionsMonitor<SystemEmailSendConfig> systemEmailConfig
|
IOptionsMonitor<SystemEmailSendConfig> systemEmailConfig
|
||||||
) : IConsumer<SiteSurverRejectedEvent>
|
) : IConsumer<SiteSurverRejectedEvent>
|
||||||
{
|
{
|
||||||
@@ -216,83 +234,95 @@ public class SiteSurverRejectedEventConsumer(
|
|||||||
|
|
||||||
var trialSiteSurveyId = context.Message.TrialSiteSurveyId;
|
var trialSiteSurveyId = context.Message.TrialSiteSurveyId;
|
||||||
|
|
||||||
var siteSurveyInfo = _trialSiteSurveyRepository.Where(t => t.Id == trialSiteSurveyId).FirstOrDefault().IfNullThrowException();
|
var siteSurveyInfo = _trialSiteSurveyRepository.Where(t => t.Id == trialSiteSurveyId ,ignoreQueryFilters:true).FirstOrDefault().IfNullThrowException();
|
||||||
|
|
||||||
var trialId = siteSurveyInfo.TrialId;
|
var trialId = siteSurveyInfo.TrialId;
|
||||||
|
|
||||||
var messageToSend = new MimeMessage();
|
var scenario = EmailBusinessScenario.SiteSurveyReject;
|
||||||
|
|
||||||
var toUserName = siteSurveyInfo.UserName;
|
var emailConfig = _emailNoticeConfigrepository.Where(t => t.BusinessScenarioEnum == scenario && t.IsAutoSend && t.IsEnable).FirstOrDefault();
|
||||||
|
|
||||||
if (context.Message.IsHaveSPMOrCPM)
|
if (emailConfig != null)
|
||||||
{
|
{
|
||||||
//PM 驳回到SPM
|
|
||||||
if (siteSurveyInfo.State == TrialSiteSurveyEnum.CRCSubmitted)
|
|
||||||
|
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)
|
|
||||||
.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();
|
|
||||||
|
|
||||||
|
|
||||||
foreach (var user in sPMOrCPMList)
|
|
||||||
{
|
{
|
||||||
messageToSend.To.Add(new MailboxAddress(user.FullName, user.EMail));
|
//var user = await _userRoleRepository.FirstOrDefaultAsync(t => t.Id == siteSurveyInfo.PreliminaryUserId);
|
||||||
|
|
||||||
|
//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 }).ToList();
|
||||||
|
|
||||||
|
|
||||||
|
foreach (var user in sPMOrCPMList)
|
||||||
|
{
|
||||||
|
messageToSend.To.Add(new MailboxAddress(user.FullName, user.EMail));
|
||||||
|
}
|
||||||
|
|
||||||
|
toUserName = string.Join('、', sPMOrCPMList.Select(t => t.FullName));
|
||||||
|
|
||||||
|
}
|
||||||
|
//SPM 驳回到CRC
|
||||||
|
else if (siteSurveyInfo.State == TrialSiteSurveyEnum.ToSubmit)
|
||||||
|
{
|
||||||
|
messageToSend.To.Add(new MailboxAddress(toUserName, siteSurveyInfo.Email));
|
||||||
}
|
}
|
||||||
|
|
||||||
toUserName = string.Join('、', sPMOrCPMList.Select(t => t.FullName));
|
|
||||||
|
|
||||||
}
|
}
|
||||||
//SPM 驳回到CRC
|
else
|
||||||
else if (siteSurveyInfo.State == TrialSiteSurveyEnum.ToSubmit)
|
|
||||||
{
|
{
|
||||||
messageToSend.To.Add(new MailboxAddress(toUserName, siteSurveyInfo.Email));
|
//没有SPM PM驳回到CRC
|
||||||
|
|
||||||
|
messageToSend.To.Add(new MailboxAddress(String.Empty, siteSurveyInfo.Email));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
//发件地址
|
||||||
else
|
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
|
||||||
{
|
|
||||||
//没有SPM PM驳回到CRC
|
|
||||||
|
|
||||||
messageToSend.To.Add(new MailboxAddress(String.Empty, siteSurveyInfo.Email));
|
|
||||||
}
|
|
||||||
|
|
||||||
//发件地址
|
|
||||||
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
|
|
||||||
|
|
||||||
|
|
||||||
var trialInfo = await _trialRepository.FirstOrDefaultAsync(t => t.Id == 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 siteInfo = await _trialSiteRepository.FirstOrDefaultAsync(t => t.TrialId == trialId && t.Id == siteSurveyInfo.TrialSiteId, true);
|
||||||
|
|
||||||
|
|
||||||
var companyName = 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 =>
|
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
|
||||||
{
|
{
|
||||||
var topicStr = string.Format(input.topicStr, trialInfo.ResearchProgramNo);
|
var topicStr = string.Format(input.topicStr, companyName,trialInfo.ResearchProgramNo);
|
||||||
var htmlBodyStr = string.Format(CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr),
|
var htmlBodyStr = string.Format(CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr),
|
||||||
toUserName,
|
toUserName,
|
||||||
trialInfo.TrialCode,
|
trialInfo.TrialCode,
|
||||||
trialInfo.ResearchProgramNo,
|
trialInfo.ResearchProgramNo,
|
||||||
trialInfo.ExperimentName,
|
trialInfo.ExperimentName,
|
||||||
siteInfo.TrialSiteCode,
|
|
||||||
siteInfo.TrialSiteAliasName,
|
|
||||||
siteSurveyInfo.LatestBackReason,
|
|
||||||
_systemEmailConfig.SiteUrl,
|
|
||||||
(siteSurveyInfo.State == TrialSiteSurveyEnum.ToSubmit ? "inline - block" : "none")
|
|
||||||
);
|
|
||||||
|
|
||||||
return (topicStr, htmlBodyStr);
|
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, _systemEmailConfig);
|
||||||
|
}
|
||||||
|
|
||||||
await CommonEmailHelper.GetEmailSubejctAndHtmlInfoAndBuildAsync(_emailNoticeConfigrepository, EmailBusinessScenario.SiteSurveyReject, messageToSend, emailConfigFunc);
|
|
||||||
|
|
||||||
await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,13 +24,13 @@ namespace IRaCIS.Core.Application.MassTransit.Consumer;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class CRCSubmitedAndQCToAuditEventConsumer(
|
public class CRCSubmitedAndQCToAuditEventConsumer(
|
||||||
IRepository<UserRole> _userRoleRepository,
|
IRepository<UserRole> _userRoleRepository,
|
||||||
IRepository<TrialUserRole> _trialUseRoleRepository,
|
IRepository<TrialUserRole> _trialUseRoleRepository,
|
||||||
IRepository<SubjectVisit> _subjectVisitRepository,
|
IRepository<SubjectVisit> _subjectVisitRepository,
|
||||||
IRepository<Trial> _trialRepository,
|
IRepository<Trial> _trialRepository,
|
||||||
IRepository<ReadingQuestionCriterionTrial> _readingQuestionCriterionTrialRepository,
|
IRepository<ReadingQuestionCriterionTrial> _readingQuestionCriterionTrialRepository,
|
||||||
IRepository<VisitTask> _visitTaskRepository,
|
IRepository<VisitTask> _visitTaskRepository,
|
||||||
IRepository<Dictionary> _dictionaryRepository,
|
IRepository<Dictionary> _dictionaryRepository,
|
||||||
IRepository<EmailNoticeConfig> _emailNoticeConfigrepository,
|
IRepository<TrialEmailNoticeConfig> _trialEmailNoticeConfigrepository,
|
||||||
IOptionsMonitor<SystemEmailSendConfig> systemEmailConfig) : IConsumer<CRCSubmitedAndQCToAuditEvent>
|
IOptionsMonitor<SystemEmailSendConfig> systemEmailConfig) : IConsumer<CRCSubmitedAndQCToAuditEvent>
|
||||||
{
|
{
|
||||||
private readonly SystemEmailSendConfig _systemEmailConfig = systemEmailConfig.CurrentValue;
|
private readonly SystemEmailSendConfig _systemEmailConfig = systemEmailConfig.CurrentValue;
|
||||||
@@ -41,46 +41,55 @@ public class CRCSubmitedAndQCToAuditEventConsumer(
|
|||||||
|
|
||||||
var subjectVisitId = context.Message.SubjectVisitId;
|
var subjectVisitId = context.Message.SubjectVisitId;
|
||||||
|
|
||||||
var subjectVisit = await _subjectVisitRepository.Where(x => x.Id == subjectVisitId).Include(x => x.Subject).FirstOrDefaultAsync();
|
var subjectVisit = await _subjectVisitRepository.Where(x => x.Id == subjectVisitId).Include(x => x.Subject).FirstNotNullAsync();
|
||||||
|
|
||||||
var trialUser = await _trialUseRoleRepository.Where(x => x.TrialId == subjectVisit.TrialId).Include(x => x.UserRole).Select(x => x.UserRole).ToListAsync();
|
var trialId = subjectVisit.TrialId;
|
||||||
|
|
||||||
var userinfoList = trialUser.Where(x => x.UserTypeEnum == UserTypeEnum.IQC).ToList();
|
var scenario = context.Message.IsPd ? EmailBusinessScenario.PDVerification_PendingImageQCClaim : EmailBusinessScenario.EligibilityVerification_PendingClaim;
|
||||||
|
|
||||||
|
var trialEmailConfig = _trialEmailNoticeConfigrepository.Where(t => t.TrialId == trialId && t.BusinessScenarioEnum == scenario && t.IsAutoSend && t.IsEnable).FirstOrDefault();
|
||||||
|
|
||||||
var pmandAPm = trialUser.Where(x => x.UserTypeEnum == UserTypeEnum.APM || x.UserTypeEnum == UserTypeEnum.ProjectManager).ToList();
|
if (trialEmailConfig != null)
|
||||||
|
|
||||||
var trialInfo = await _trialRepository.FirstOrDefaultAsync(t => t.Id == subjectVisit.TrialId);
|
|
||||||
|
|
||||||
var auditStateCode = "AuditStatePE";
|
|
||||||
|
|
||||||
if (trialInfo.QCProcessEnum == TrialQCProcess.DoubleAudit)
|
|
||||||
{
|
|
||||||
auditStateCode = "AuditStateRC";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var dictionValue = await CommonEmailHelper.TranslationDictionary(new TranslationDictionaryDto()
|
|
||||||
{
|
{
|
||||||
|
|
||||||
DictionaryRepository = _dictionaryRepository,
|
var trialUserList = await _trialUseRoleRepository.Where(x => x.TrialId == subjectVisit.TrialId && x.TrialUser.IsDeleted == false).Include(x => x.UserRole).Select(x => x.UserRole).ToListAsync();
|
||||||
IsEn_US = isEn_US,
|
|
||||||
DictionaryList = new List<DictionaryDto>()
|
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)
|
||||||
|
{
|
||||||
|
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(), }, //审核状态
|
new DictionaryDto (){DictionaryCode= auditStateCode,EnumValue=subjectVisit.AuditState.GetEnumInt(), }, //审核状态
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
var messageToSend = new MimeMessage();
|
var messageToSend = new MimeMessage();
|
||||||
//发件地址
|
//发件地址
|
||||||
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
|
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
|
||||||
|
|
||||||
|
|
||||||
foreach (var userinfo in userinfoList)
|
foreach (var userinfo in userinfoList)
|
||||||
{
|
{
|
||||||
messageToSend.To.Add(new MailboxAddress(String.Empty, userinfo.EMail));
|
messageToSend.To.Add(new MailboxAddress(String.Empty, userinfo.EMail));
|
||||||
}
|
}
|
||||||
|
|
||||||
var userNames = userinfoList.Select(x => x.FullName).ToList();
|
var userNames = userinfoList.Select(x => x.FullName).ToList();
|
||||||
@@ -111,14 +120,11 @@ public class CRCSubmitedAndQCToAuditEventConsumer(
|
|||||||
return (topicStr, htmlBodyStr);
|
return (topicStr, htmlBodyStr);
|
||||||
};
|
};
|
||||||
|
|
||||||
await CommonEmailHelper.GetEmailSubejctAndHtmlInfoAndBuildAsync(_emailNoticeConfigrepository,
|
await CommonEmailHelper.GetTrialEmailSubejctAndHtmlInfoAndBuildAsync(trialEmailConfig, messageToSend, emailConfigFunc);
|
||||||
|
|
||||||
context.Message.IsPd ? EmailBusinessScenario.PDVerification_PendingImageQCClaim : EmailBusinessScenario.EligibilityVerification_PendingClaim,
|
|
||||||
|
|
||||||
messageToSend, emailConfigFunc);
|
|
||||||
|
|
||||||
await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig);
|
await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -134,7 +140,7 @@ public class CRCRepliedQCChallengeEventConsumer(
|
|||||||
IRepository<QCChallenge> _qCChallengeRepository,
|
IRepository<QCChallenge> _qCChallengeRepository,
|
||||||
IRepository<QCChallengeDialog> _qCChallengeDialogRepository,
|
IRepository<QCChallengeDialog> _qCChallengeDialogRepository,
|
||||||
IRepository<Dictionary> _dictionaryRepository,
|
IRepository<Dictionary> _dictionaryRepository,
|
||||||
IRepository<EmailNoticeConfig> _emailNoticeConfigrepository,
|
IRepository<TrialEmailNoticeConfig> _trialEmailNoticeConfigrepository,
|
||||||
IOptionsMonitor<SystemEmailSendConfig> systemEmailConfig) : IConsumer<CRCRepliedQCChallengeEvent>
|
IOptionsMonitor<SystemEmailSendConfig> systemEmailConfig) : IConsumer<CRCRepliedQCChallengeEvent>
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -148,74 +154,75 @@ public class CRCRepliedQCChallengeEventConsumer(
|
|||||||
|
|
||||||
var subjectVisit = await _subjectVisitRepository.Where(x => x.Id == subjectVisitId).Include(x => x.Subject).Include(x => x.CurrentActionUser).FirstNotNullAsync();
|
var subjectVisit = await _subjectVisitRepository.Where(x => x.Id == subjectVisitId).Include(x => x.Subject).Include(x => x.CurrentActionUser).FirstNotNullAsync();
|
||||||
|
|
||||||
|
var trialId = subjectVisit.TrialId;
|
||||||
|
|
||||||
var qCChallengeDialog = await _qCChallengeDialogRepository.Where(x => x.Id == context.Message.QCChallengeDialogId).Include(x => x.QCChallenge).FirstNotNullAsync();
|
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 trialUser = await _trialUseRoleRepository.Where(x => x.TrialId == subjectVisit.TrialId).Include(x => x.UserRole).Select(x => x.UserRole).ToListAsync();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var userinfoList = trialUser.Where(x => x.UserTypeEnum == UserTypeEnum.IQC).ToList();
|
|
||||||
var pmandAPm = trialUser.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 messageToSend = new MimeMessage();
|
|
||||||
//发件地址
|
|
||||||
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
|
|
||||||
messageToSend.To.Add(new MailboxAddress(String.Empty, userinfo.EMail));
|
|
||||||
|
|
||||||
foreach (var pm in pmandAPm)
|
|
||||||
{
|
|
||||||
messageToSend.Cc.Add(new MailboxAddress(String.Empty, pm.EMail));
|
|
||||||
}
|
|
||||||
var companyName = isEn_US ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
|
|
||||||
|
|
||||||
|
|
||||||
var dictionValue = await CommonEmailHelper.TranslationDictionary(new TranslationDictionaryDto()
|
|
||||||
{
|
{
|
||||||
|
|
||||||
DictionaryRepository = _dictionaryRepository,
|
|
||||||
IsEn_US = isEn_US,
|
var qCChallengeDialog = await _qCChallengeDialogRepository.Where(x => x.Id == context.Message.QCChallengeDialogId).Include(x => x.QCChallenge).FirstNotNullAsync();
|
||||||
DictionaryList = new List<DictionaryDto>()
|
|
||||||
|
|
||||||
|
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 messageToSend = new MimeMessage();
|
||||||
|
//发件地址
|
||||||
|
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
|
||||||
|
messageToSend.To.Add(new MailboxAddress(String.Empty, userinfo.EMail));
|
||||||
|
|
||||||
|
foreach (var pm in pmandAPm)
|
||||||
|
{
|
||||||
|
messageToSend.Cc.Add(new MailboxAddress(String.Empty, pm.EMail));
|
||||||
|
}
|
||||||
|
var companyName = isEn_US ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
|
||||||
|
|
||||||
|
|
||||||
|
var dictionValue = await CommonEmailHelper.TranslationDictionary(new TranslationDictionaryDto()
|
||||||
|
{
|
||||||
|
|
||||||
|
DictionaryRepository = _dictionaryRepository,
|
||||||
|
IsEn_US = isEn_US,
|
||||||
|
DictionaryList = new List<DictionaryDto>()
|
||||||
{
|
{
|
||||||
new DictionaryDto (){DictionaryCode= "YesOrNo",EnumValue=qCChallengeDialog.QCChallenge.IsClosed.ToString().ToLower(), }, //是否关闭
|
new DictionaryDto (){DictionaryCode= "YesOrNo",EnumValue=qCChallengeDialog.QCChallenge.IsClosed.ToString().ToLower(), }, //是否关闭
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
|
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
|
||||||
{
|
{
|
||||||
var subjectCode = subjectVisit.Subject.Code;
|
var subjectCode = subjectVisit.Subject.Code;
|
||||||
var topicStr = string.Format(input.topicStr, trialInfo.ResearchProgramNo, subjectCode, subjectVisit.VisitName);
|
var topicStr = string.Format(input.topicStr, trialInfo.ResearchProgramNo, subjectCode, subjectVisit.VisitName);
|
||||||
var htmlBodyStr = string.Format(
|
var htmlBodyStr = string.Format(
|
||||||
CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr),
|
CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr),
|
||||||
userinfo.FullName, // 用户名 {0}
|
userinfo.FullName, // 用户名 {0}
|
||||||
trialInfo.ExperimentName, // 项目 {1}
|
trialInfo.ExperimentName, // 项目 {1}
|
||||||
subjectCode, // 受试者 {2}
|
subjectCode, // 受试者 {2}
|
||||||
subjectVisit.VisitName, // 访视 {3}
|
subjectVisit.VisitName, // 访视 {3}
|
||||||
dictionValue[0], // 是否关闭 {4}
|
dictionValue[0], // 是否关闭 {4}
|
||||||
qCChallengeDialog.TalkContent, // 质疑内容{5}
|
qCChallengeDialog.TalkContent, // 质疑内容{5}
|
||||||
_systemEmailConfig.SiteUrl // 链接 {6}
|
_systemEmailConfig.SiteUrl // 链接 {6}
|
||||||
);
|
);
|
||||||
|
|
||||||
return (topicStr, htmlBodyStr);
|
return (topicStr, htmlBodyStr);
|
||||||
};
|
};
|
||||||
|
await CommonEmailHelper.GetTrialEmailSubejctAndHtmlInfoAndBuildAsync(trialEmailConfig, messageToSend, emailConfigFunc);
|
||||||
|
|
||||||
await CommonEmailHelper.GetEmailSubejctAndHtmlInfoAndBuildAsync(_emailNoticeConfigrepository,
|
await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig);
|
||||||
|
}
|
||||||
context.Message.IsPd ? EmailBusinessScenario.PDVerification_UnderQCQuery : EmailBusinessScenario.EligibilityVerification_Pending,
|
|
||||||
|
|
||||||
messageToSend, emailConfigFunc);
|
|
||||||
|
|
||||||
await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -231,7 +238,7 @@ public class QCRepliedQCChallengeEventConsumer(
|
|||||||
IRepository<QCChallenge> _qCChallengeRepository,
|
IRepository<QCChallenge> _qCChallengeRepository,
|
||||||
IRepository<QCChallengeDialog> _qCChallengeDialogRepository,
|
IRepository<QCChallengeDialog> _qCChallengeDialogRepository,
|
||||||
IRepository<Dictionary> _dictionaryRepository,
|
IRepository<Dictionary> _dictionaryRepository,
|
||||||
IRepository<EmailNoticeConfig> _emailNoticeConfigrepository,
|
IRepository<TrialEmailNoticeConfig> _trialEmailNoticeConfigrepository,
|
||||||
IOptionsMonitor<SystemEmailSendConfig> systemEmailConfig) : IConsumer<QCRepliedQCChallengeEvent>
|
IOptionsMonitor<SystemEmailSendConfig> systemEmailConfig) : IConsumer<QCRepliedQCChallengeEvent>
|
||||||
{
|
{
|
||||||
private readonly SystemEmailSendConfig _systemEmailConfig = systemEmailConfig.CurrentValue;
|
private readonly SystemEmailSendConfig _systemEmailConfig = systemEmailConfig.CurrentValue;
|
||||||
@@ -240,90 +247,100 @@ public class QCRepliedQCChallengeEventConsumer(
|
|||||||
Console.WriteLine("发送(014,015) 【 QC回复 质控质疑,通知CRC】邮件!!!");
|
Console.WriteLine("发送(014,015) 【 QC回复 质控质疑,通知CRC】邮件!!!");
|
||||||
var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;
|
var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;
|
||||||
|
|
||||||
string talkContent = string.Empty;
|
|
||||||
var isclose = false;
|
|
||||||
if (context.Message.QCChallengeDialogId != null)
|
|
||||||
{
|
|
||||||
var qCChallengeDialog = await _qCChallengeDialogRepository.Where(x => x.Id == context.Message.QCChallengeDialogId.Value).Include(x => x.QCChallenge).FirstNotNullAsync();
|
|
||||||
talkContent = qCChallengeDialog.TalkContent;
|
|
||||||
isclose = qCChallengeDialog.QCChallenge.IsClosed;
|
|
||||||
}
|
|
||||||
else if(context.Message.QCChallengeId != null)
|
|
||||||
{
|
|
||||||
var qCChallenge = await _qCChallengeRepository.Where(x => x.Id == context.Message.QCChallengeId.Value).FirstNotNullAsync();
|
|
||||||
talkContent = qCChallenge.Content;
|
|
||||||
isclose = qCChallenge.IsClosed;
|
|
||||||
}
|
|
||||||
|
|
||||||
var subjectVisitId = context.Message.SubjectVisitId;
|
var subjectVisitId = context.Message.SubjectVisitId;
|
||||||
|
|
||||||
var subjectVisit = await _subjectVisitRepository.Where(x => x.Id == subjectVisitId).Include(x => x.Subject).FirstNotNullAsync();
|
var subjectVisit = await _subjectVisitRepository.Where(x => x.Id == subjectVisitId).Include(x => x.Subject).FirstNotNullAsync();
|
||||||
|
|
||||||
var trialUser = await _trialUseRoleRepository.Where(x => x.TrialId == subjectVisit.TrialId).Include(x => x.UserRole).Select(x => x.UserRole).ToListAsync();
|
var trialId = subjectVisit.TrialId;
|
||||||
|
|
||||||
var userinfoList = trialUser.Where(x => x.UserTypeEnum == UserTypeEnum.ClinicalResearchCoordinator).ToList();
|
var scenario = context.Message.IsPd ? EmailBusinessScenario.PDVerification_ImageQuery : EmailBusinessScenario.EligibilityVerification_ImageQuery;
|
||||||
|
|
||||||
var craInfo = trialUser.Where(x => x.UserTypeEnum == UserTypeEnum.CRA).FirstOrDefault();
|
var trialEmailConfig = _trialEmailNoticeConfigrepository.Where(t => t.TrialId == trialId && t.BusinessScenarioEnum == scenario && t.IsAutoSend && t.IsEnable).FirstOrDefault();
|
||||||
|
|
||||||
var trialInfo = await _trialRepository.FirstOrDefaultAsync(t => t.Id == subjectVisit.TrialId);
|
if (trialEmailConfig != null)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var dictionValue = await CommonEmailHelper.TranslationDictionary(new TranslationDictionaryDto()
|
|
||||||
{
|
{
|
||||||
|
|
||||||
DictionaryRepository = _dictionaryRepository,
|
|
||||||
IsEn_US = isEn_US,
|
string talkContent = string.Empty;
|
||||||
DictionaryList = new List<DictionaryDto>()
|
var isclose = false;
|
||||||
|
if (context.Message.QCChallengeDialogId != null)
|
||||||
|
{
|
||||||
|
var qCChallengeDialog = await _qCChallengeDialogRepository.Where(x => x.Id == context.Message.QCChallengeDialogId.Value).Include(x => x.QCChallenge).FirstNotNullAsync();
|
||||||
|
talkContent = qCChallengeDialog.TalkContent;
|
||||||
|
isclose = qCChallengeDialog.QCChallenge.IsClosed;
|
||||||
|
}
|
||||||
|
else if (context.Message.QCChallengeId != null)
|
||||||
|
{
|
||||||
|
var qCChallenge = await _qCChallengeRepository.Where(x => x.Id == context.Message.QCChallengeId.Value).FirstNotNullAsync();
|
||||||
|
talkContent = qCChallenge.Content;
|
||||||
|
isclose = qCChallenge.IsClosed;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
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 trialInfo = await _trialRepository.FirstOrDefaultAsync(t => t.Id == subjectVisit.TrialId);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
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(), }, //是否关闭
|
new DictionaryDto (){DictionaryCode= "YesOrNo",EnumValue=isclose.ToString().ToLower(), }, //是否关闭
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
foreach (var userinfo in userinfoList)
|
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));
|
|
||||||
if (craInfo != null)
|
|
||||||
{
|
{
|
||||||
messageToSend.Cc.Add(new MailboxAddress(String.Empty, craInfo.EMail));
|
var messageToSend = new MimeMessage();
|
||||||
|
//发件地址
|
||||||
|
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
|
||||||
|
messageToSend.To.Add(new MailboxAddress(String.Empty, userinfo.EMail));
|
||||||
|
if (craInfo != null)
|
||||||
|
{
|
||||||
|
messageToSend.Cc.Add(new MailboxAddress(String.Empty, craInfo.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}
|
||||||
|
trialInfo.ExperimentName, // 项目 {1}
|
||||||
|
subjectCode, // 受试者 {2}
|
||||||
|
subjectVisit.VisitName, // 访视 {3}
|
||||||
|
dictionValue[0], // 质疑是否关闭 {4}
|
||||||
|
talkContent, // 质疑内容 {5}
|
||||||
|
_systemEmailConfig.SiteUrl // 链接 {65}
|
||||||
|
);
|
||||||
|
|
||||||
|
return (topicStr, htmlBodyStr);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
await CommonEmailHelper.GetTrialEmailSubejctAndHtmlInfoAndBuildAsync(trialEmailConfig, messageToSend, emailConfigFunc);
|
||||||
|
|
||||||
|
await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
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}
|
|
||||||
trialInfo.ExperimentName, // 项目 {1}
|
|
||||||
subjectCode, // 受试者 {2}
|
|
||||||
subjectVisit.VisitName, // 访视 {3}
|
|
||||||
dictionValue[0], // 质疑是否关闭 {4}
|
|
||||||
talkContent, // 质疑内容 {5}
|
|
||||||
_systemEmailConfig.SiteUrl // 链接 {65}
|
|
||||||
);
|
|
||||||
|
|
||||||
return (topicStr, htmlBodyStr);
|
|
||||||
};
|
|
||||||
|
|
||||||
await CommonEmailHelper.GetEmailSubejctAndHtmlInfoAndBuildAsync(_emailNoticeConfigrepository,
|
|
||||||
|
|
||||||
context.Message.IsPd ? EmailBusinessScenario.PDVerification_ImageQuery : EmailBusinessScenario.EligibilityVerification_ImageQuery,
|
|
||||||
|
|
||||||
messageToSend, emailConfigFunc);
|
|
||||||
|
|
||||||
await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -340,7 +357,7 @@ public class CRCRepliedCheckChallengeEventConsumer(
|
|||||||
IRepository<QCChallenge> _qCChallengeRepository,
|
IRepository<QCChallenge> _qCChallengeRepository,
|
||||||
IRepository<QCChallengeDialog> _qCChallengeDialogRepository,
|
IRepository<QCChallengeDialog> _qCChallengeDialogRepository,
|
||||||
IRepository<Dictionary> _dictionaryRepository,
|
IRepository<Dictionary> _dictionaryRepository,
|
||||||
IRepository<EmailNoticeConfig> _emailNoticeConfigrepository,
|
IRepository<TrialEmailNoticeConfig> _trialEmailNoticeConfigrepository,
|
||||||
IOptionsMonitor<SystemEmailSendConfig> systemEmailConfig) : IConsumer<CRCRepliedCheckChallengeEvent>
|
IOptionsMonitor<SystemEmailSendConfig> systemEmailConfig) : IConsumer<CRCRepliedCheckChallengeEvent>
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -350,70 +367,80 @@ public class CRCRepliedCheckChallengeEventConsumer(
|
|||||||
Console.WriteLine("发送(019,020) 【 CRC 回复一致性核查质疑 通知PM】邮件!!!");
|
Console.WriteLine("发送(019,020) 【 CRC 回复一致性核查质疑 通知PM】邮件!!!");
|
||||||
var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;
|
var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var subjectVisitId = context.Message.SubjectVisitId;
|
var subjectVisitId = context.Message.SubjectVisitId;
|
||||||
|
|
||||||
var subjectVisit = await _subjectVisitRepository.Where(x => x.Id == subjectVisitId).Include(x => x.Subject).FirstNotNullAsync();
|
var subjectVisit = await _subjectVisitRepository.Where(x => x.Id == subjectVisitId).Include(x => x.Subject).FirstNotNullAsync();
|
||||||
|
|
||||||
var trialUser = await _trialUseRoleRepository.Where(x => x.TrialId == subjectVisit.TrialId).Include(x => x.UserRole).Select(x => x.UserRole).ToListAsync();
|
var trialId = subjectVisit.TrialId;
|
||||||
|
|
||||||
var userinfoList = trialUser.Where(x => x.UserTypeEnum == UserTypeEnum.APM || x.UserTypeEnum == UserTypeEnum.ProjectManager).ToList();
|
var scenario = context.Message.IsPd ? EmailBusinessScenario.PDVerification_UnderDRForPMOrAPM : EmailBusinessScenario.EligibilityVerification_UnderDRForPMOrAPM;
|
||||||
|
|
||||||
|
var trialEmailConfig = _trialEmailNoticeConfigrepository.Where(t => t.TrialId == trialId && t.BusinessScenarioEnum == scenario && t.IsAutoSend && t.IsEnable).FirstOrDefault();
|
||||||
|
|
||||||
var trialInfo = await _trialRepository.FirstOrDefaultAsync(t => t.Id == subjectVisit.TrialId);
|
if (trialEmailConfig != null)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var dictionValue = await CommonEmailHelper.TranslationDictionary(new TranslationDictionaryDto()
|
|
||||||
{
|
{
|
||||||
|
|
||||||
DictionaryRepository = _dictionaryRepository,
|
|
||||||
IsEn_US = isEn_US,
|
var trialUserList = await _trialUseRoleRepository.Where(x => x.TrialId == subjectVisit.TrialId && x.TrialUser.IsDeleted == false).Include(x => x.UserRole).Select(x => x.UserRole).ToListAsync();
|
||||||
DictionaryList = new List<DictionaryDto>()
|
|
||||||
|
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()
|
||||||
|
{
|
||||||
|
|
||||||
|
DictionaryRepository = _dictionaryRepository,
|
||||||
|
IsEn_US = isEn_US,
|
||||||
|
DictionaryList = new List<DictionaryDto>()
|
||||||
{
|
{
|
||||||
new DictionaryDto (){DictionaryCode= "CheckState",EnumValue=subjectVisit.CheckState.GetEnumInt(), }, //审核状态
|
new DictionaryDto (){DictionaryCode= "CheckState",EnumValue=subjectVisit.CheckState.GetEnumInt(), }, //审核状态
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
foreach (var userinfo in userinfoList)
|
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 companyName = isEn_US ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
|
|
||||||
{
|
{
|
||||||
var subjectCode = subjectVisit.Subject.Code;
|
var messageToSend = new MimeMessage();
|
||||||
var topicStr = string.Format(input.topicStr, trialInfo.ResearchProgramNo, subjectCode, subjectVisit.VisitName);
|
//发件地址
|
||||||
var htmlBodyStr = string.Format(
|
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
|
||||||
CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr),
|
messageToSend.To.Add(new MailboxAddress(String.Empty, userinfo.EMail));
|
||||||
userinfo.FullName, // 用户名 {0}
|
|
||||||
trialInfo.ExperimentName, // 项目 {1}
|
|
||||||
subjectCode, // 受试者 {2}
|
|
||||||
subjectVisit.VisitName, // 访视 {3}
|
|
||||||
dictionValue[0], // 核查状态 {4}
|
|
||||||
_systemEmailConfig.SiteUrl // 链接 {5}
|
|
||||||
);
|
|
||||||
|
|
||||||
return (topicStr, htmlBodyStr);
|
|
||||||
};
|
|
||||||
|
|
||||||
await CommonEmailHelper.GetEmailSubejctAndHtmlInfoAndBuildAsync(_emailNoticeConfigrepository,
|
var companyName = isEn_US ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
|
||||||
|
|
||||||
context.Message.IsPd ? EmailBusinessScenario.PDVerification_UnderDRForPMOrAPM : EmailBusinessScenario.EligibilityVerification_UnderDRForPMOrAPM,
|
|
||||||
|
|
||||||
messageToSend, emailConfigFunc);
|
|
||||||
|
|
||||||
await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig);
|
|
||||||
|
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}
|
||||||
|
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, _systemEmailConfig);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -432,7 +459,7 @@ public class PMRepliedCheckChallengeEventConsumer(
|
|||||||
IRepository<CheckChallengeDialog> _checkChallengeDialogRepository,
|
IRepository<CheckChallengeDialog> _checkChallengeDialogRepository,
|
||||||
IRepository<QCChallengeDialog> _qCChallengeDialogRepository,
|
IRepository<QCChallengeDialog> _qCChallengeDialogRepository,
|
||||||
IRepository<Dictionary> _dictionaryRepository,
|
IRepository<Dictionary> _dictionaryRepository,
|
||||||
IRepository<EmailNoticeConfig> _emailNoticeConfigrepository,
|
IRepository<TrialEmailNoticeConfig> _trialEmailNoticeConfigrepository,
|
||||||
IOptionsMonitor<SystemEmailSendConfig> systemEmailConfig) : IConsumer<PMRepliedCheckChallengeEvent>
|
IOptionsMonitor<SystemEmailSendConfig> systemEmailConfig) : IConsumer<PMRepliedCheckChallengeEvent>
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -441,80 +468,89 @@ public class PMRepliedCheckChallengeEventConsumer(
|
|||||||
{
|
{
|
||||||
Console.WriteLine("发送(016,017) 【 PM 一致性核查 通知CRC】邮件!!!");
|
Console.WriteLine("发送(016,017) 【 PM 一致性核查 通知CRC】邮件!!!");
|
||||||
var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;
|
var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;
|
||||||
var checkChallengeDialog = await _checkChallengeDialogRepository.Where(x => x.Id == context.Message.CheckChallengeDialogId).FirstNotNullAsync();
|
|
||||||
var subjectVisitId = context.Message.SubjectVisitId;
|
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).FirstNotNullAsync();
|
||||||
|
|
||||||
var trialUser = await _trialUseRoleRepository.Where(x => x.TrialId == subjectVisit.TrialId).Include(x => x.UserRole).Select(x => x.UserRole).ToListAsync();
|
var trialId = subjectVisit.TrialId;
|
||||||
|
|
||||||
var userinfoList = trialUser.Where(x => x.UserTypeEnum == UserTypeEnum.ClinicalResearchCoordinator).ToList();
|
|
||||||
|
|
||||||
var craInfo = trialUser.Where(x => x.UserTypeEnum == UserTypeEnum.CRA).FirstOrDefault();
|
var scenario = context.Message.IsPd ? EmailBusinessScenario.PDVerification_UnderDR : EmailBusinessScenario.EligibilityVerification_UnderDR;
|
||||||
|
|
||||||
var trialInfo = await _trialRepository.FirstOrDefaultAsync(t => t.Id == subjectVisit.TrialId);
|
var trialEmailConfig = _trialEmailNoticeConfigrepository.Where(t => t.TrialId == trialId && t.BusinessScenarioEnum == scenario && t.IsAutoSend && t.IsEnable).FirstOrDefault();
|
||||||
|
|
||||||
|
if (trialEmailConfig != null)
|
||||||
List<string> modalities = new List<string>();
|
|
||||||
modalities =subjectVisit.NoneDicomStudyList.Select(t => t.Modality)
|
|
||||||
.Union(subjectVisit.StudyList.Select(k => k.ModalityForEdit)).ToList();
|
|
||||||
|
|
||||||
var dictionValue = await CommonEmailHelper.TranslationDictionary(new TranslationDictionaryDto()
|
|
||||||
{
|
{
|
||||||
|
|
||||||
DictionaryRepository = _dictionaryRepository,
|
var checkChallengeDialog = await _checkChallengeDialogRepository.Where(x => x.Id == context.Message.CheckChallengeDialogId).FirstNotNullAsync();
|
||||||
IsEn_US = isEn_US,
|
|
||||||
DictionaryList = new List<DictionaryDto>()
|
|
||||||
|
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 trialInfo = await _trialRepository.FirstOrDefaultAsync(t => t.Id == subjectVisit.TrialId);
|
||||||
|
|
||||||
|
|
||||||
|
List<string> modalities = new List<string>();
|
||||||
|
modalities = subjectVisit.NoneDicomStudyList.Select(t => t.Modality)
|
||||||
|
.Union(subjectVisit.StudyList.Select(k => k.ModalityForEdit)).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(), }, //核查状态
|
new DictionaryDto (){DictionaryCode= "CheckState",EnumValue=subjectVisit.CheckState.GetEnumInt(), }, //核查状态
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
foreach (var userinfo in userinfoList)
|
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));
|
|
||||||
if (craInfo != null)
|
|
||||||
{
|
{
|
||||||
messageToSend.Cc.Add(new MailboxAddress(String.Empty, craInfo.EMail));
|
var messageToSend = new MimeMessage();
|
||||||
|
//发件地址
|
||||||
|
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
|
||||||
|
messageToSend.To.Add(new MailboxAddress(String.Empty, userinfo.EMail));
|
||||||
|
if (craInfo != null)
|
||||||
|
{
|
||||||
|
messageToSend.Cc.Add(new MailboxAddress(String.Empty, craInfo.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}
|
||||||
|
trialInfo.ExperimentName, // 项目 {1}
|
||||||
|
|
||||||
|
subjectCode, // 受试者 {2}
|
||||||
|
subjectVisit.VisitName, // 访视 {3}
|
||||||
|
string.Join(',', modalities), // 检查类型 {4}
|
||||||
|
dictionValue[0], // 核查状态 {5}
|
||||||
|
checkChallengeDialog.TalkContent,// 质疑内容{6}
|
||||||
|
_systemEmailConfig.SiteUrl // 链接 {7}
|
||||||
|
);
|
||||||
|
|
||||||
|
return (topicStr, htmlBodyStr);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
await CommonEmailHelper.GetTrialEmailSubejctAndHtmlInfoAndBuildAsync(trialEmailConfig, messageToSend, emailConfigFunc);
|
||||||
|
|
||||||
|
await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
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}
|
|
||||||
trialInfo.ExperimentName, // 项目 {1}
|
|
||||||
|
|
||||||
subjectCode, // 受试者 {2}
|
|
||||||
subjectVisit.VisitName, // 访视 {3}
|
|
||||||
string.Join(',', modalities), // 检查类型 {4}
|
|
||||||
dictionValue[0], // 核查状态 {5}
|
|
||||||
checkChallengeDialog.TalkContent,// 质疑内容{6}
|
|
||||||
_systemEmailConfig.SiteUrl // 链接 {7}
|
|
||||||
);
|
|
||||||
|
|
||||||
return (topicStr, htmlBodyStr);
|
|
||||||
};
|
|
||||||
|
|
||||||
await CommonEmailHelper.GetEmailSubejctAndHtmlInfoAndBuildAsync(_emailNoticeConfigrepository,
|
|
||||||
|
|
||||||
context.Message.IsPd ? EmailBusinessScenario.PDVerification_UnderDR : EmailBusinessScenario.EligibilityVerification_UnderDR,
|
|
||||||
|
|
||||||
messageToSend, emailConfigFunc);
|
|
||||||
|
|
||||||
await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -531,7 +567,7 @@ public class CheckStateChangedToAuditEventConsumer(
|
|||||||
IRepository<QCChallenge> _qCChallengeRepository,
|
IRepository<QCChallenge> _qCChallengeRepository,
|
||||||
IRepository<QCChallengeDialog> _qCChallengeDialogRepository,
|
IRepository<QCChallengeDialog> _qCChallengeDialogRepository,
|
||||||
IRepository<Dictionary> _dictionaryRepository,
|
IRepository<Dictionary> _dictionaryRepository,
|
||||||
IRepository<EmailNoticeConfig> _emailNoticeConfigrepository,
|
IRepository<TrialEmailNoticeConfig> _trialEmailNoticeConfigrepository,
|
||||||
IOptionsMonitor<SystemEmailSendConfig> systemEmailConfig) : IConsumer<CheckStateChangedToAuditEvent>
|
IOptionsMonitor<SystemEmailSendConfig> systemEmailConfig) : IConsumer<CheckStateChangedToAuditEvent>
|
||||||
{
|
{
|
||||||
private readonly SystemEmailSendConfig _systemEmailConfig = systemEmailConfig.CurrentValue;
|
private readonly SystemEmailSendConfig _systemEmailConfig = systemEmailConfig.CurrentValue;
|
||||||
@@ -540,70 +576,80 @@ public class CheckStateChangedToAuditEventConsumer(
|
|||||||
Console.WriteLine("发送(018,030) 【通知PM 进行一致性核查】邮件!!!");
|
Console.WriteLine("发送(018,030) 【通知PM 进行一致性核查】邮件!!!");
|
||||||
var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;
|
var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;
|
||||||
|
|
||||||
|
|
||||||
var subjectVisitId = context.Message.SubjectVisitId;
|
var subjectVisitId = context.Message.SubjectVisitId;
|
||||||
|
|
||||||
var subjectVisit = await _subjectVisitRepository.Where(x => x.Id == subjectVisitId).Include(x => x.Subject).FirstNotNullAsync();
|
var subjectVisit = await _subjectVisitRepository.Where(x => x.Id == subjectVisitId).Include(x => x.Subject).FirstNotNullAsync();
|
||||||
|
|
||||||
var trialUser = await _trialUseRoleRepository.Where(x => x.TrialId == subjectVisit.TrialId).Include(x => x.UserRole).Select(x => x.UserRole).ToListAsync();
|
var trialId = subjectVisit.TrialId;
|
||||||
|
|
||||||
var userinfoList = trialUser.Where(x => x.UserTypeEnum == UserTypeEnum.APM || x.UserTypeEnum == UserTypeEnum.ProjectManager).ToList();
|
var scenario = context.Message.IsPd ? EmailBusinessScenario.PDVerification_DR : EmailBusinessScenario.EligibilityVerification_DR;
|
||||||
|
|
||||||
|
var trialEmailConfig = _trialEmailNoticeConfigrepository.Where(t => t.TrialId == trialId && t.BusinessScenarioEnum == scenario && t.IsAutoSend && t.IsEnable).FirstOrDefault();
|
||||||
|
|
||||||
var trialInfo = await _trialRepository.FirstOrDefaultAsync(t => t.Id == subjectVisit.TrialId);
|
if (trialEmailConfig != null)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var dictionValue = await CommonEmailHelper.TranslationDictionary(new TranslationDictionaryDto()
|
|
||||||
{
|
{
|
||||||
|
|
||||||
DictionaryRepository = _dictionaryRepository,
|
|
||||||
IsEn_US = isEn_US,
|
|
||||||
DictionaryList = new List<DictionaryDto>()
|
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.APM || x.UserTypeEnum == UserTypeEnum.ProjectManager).ToList();
|
||||||
|
|
||||||
|
|
||||||
|
var trialInfo = await _trialRepository.FirstOrDefaultAsync(t => t.Id == subjectVisit.TrialId);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
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(), }, //审核状态
|
new DictionaryDto (){DictionaryCode= "CheckState",EnumValue=subjectVisit.CheckState.GetEnumInt(), }, //审核状态
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
foreach (var userinfo in userinfoList)
|
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 companyName = isEn_US ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
|
|
||||||
{
|
{
|
||||||
var subjectCode = subjectVisit.Subject.Code;
|
var messageToSend = new MimeMessage();
|
||||||
var topicStr = string.Format(input.topicStr, trialInfo.ResearchProgramNo, subjectCode, subjectVisit.VisitName);
|
//发件地址
|
||||||
var htmlBodyStr = string.Format(
|
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
|
||||||
CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr),
|
messageToSend.To.Add(new MailboxAddress(String.Empty, userinfo.EMail));
|
||||||
userinfo.FullName, // 姓名 {0}
|
|
||||||
trialInfo.ExperimentName, // 项目 {1}
|
|
||||||
subjectCode, // 受试者 {2}
|
|
||||||
subjectVisit.VisitName, // 访视 {3}
|
|
||||||
dictionValue[0], // 核查状态 {4}
|
|
||||||
_systemEmailConfig.SiteUrl // 链接 {5}
|
|
||||||
);
|
|
||||||
|
|
||||||
return (topicStr, htmlBodyStr);
|
|
||||||
};
|
|
||||||
|
|
||||||
await CommonEmailHelper.GetEmailSubejctAndHtmlInfoAndBuildAsync(_emailNoticeConfigrepository,
|
var companyName = isEn_US ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
|
||||||
|
|
||||||
context.Message.IsPd ? EmailBusinessScenario.PDVerification_DR : EmailBusinessScenario.EligibilityVerification_DR,
|
|
||||||
|
|
||||||
messageToSend, emailConfigFunc);
|
|
||||||
|
|
||||||
await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig);
|
|
||||||
|
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}
|
||||||
|
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, _systemEmailConfig);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -619,7 +665,7 @@ public class QCClaimTaskEventConsumer(
|
|||||||
IRepository<QCChallenge> _qCChallengeRepository,
|
IRepository<QCChallenge> _qCChallengeRepository,
|
||||||
IRepository<QCChallengeDialog> _qCChallengeDialogRepository,
|
IRepository<QCChallengeDialog> _qCChallengeDialogRepository,
|
||||||
IRepository<Dictionary> _dictionaryRepository,
|
IRepository<Dictionary> _dictionaryRepository,
|
||||||
IRepository<EmailNoticeConfig> _emailNoticeConfigrepository,
|
IRepository<TrialEmailNoticeConfig> _trialEmailNoticeConfigrepository,
|
||||||
IOptionsMonitor<SystemEmailSendConfig> systemEmailConfig) : IConsumer<QCClaimTaskEvent>
|
IOptionsMonitor<SystemEmailSendConfig> systemEmailConfig) : IConsumer<QCClaimTaskEvent>
|
||||||
{
|
{
|
||||||
private readonly SystemEmailSendConfig _systemEmailConfig = systemEmailConfig.CurrentValue;
|
private readonly SystemEmailSendConfig _systemEmailConfig = systemEmailConfig.CurrentValue;
|
||||||
@@ -628,87 +674,90 @@ public class QCClaimTaskEventConsumer(
|
|||||||
Console.WriteLine("发送(Code007,008) 【QC 领取了质控任务】邮件!!!");
|
Console.WriteLine("发送(Code007,008) 【QC 领取了质控任务】邮件!!!");
|
||||||
var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;
|
var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var subjectVisitId = context.Message.SubjectVisitId;
|
var subjectVisitId = context.Message.SubjectVisitId;
|
||||||
|
|
||||||
var subjectVisit = await _subjectVisitRepository.Where(x => x.Id == subjectVisitId).Include(x => x.Subject).Include(x => x.CurrentActionUser).FirstNotNullAsync();
|
var subjectVisit = await _subjectVisitRepository.Where(x => x.Id == subjectVisitId).Include(x => x.Subject).Include(x => x.CurrentActionUser).FirstNotNullAsync();
|
||||||
|
|
||||||
|
var trialId = subjectVisit.TrialId;
|
||||||
|
|
||||||
var subjectVisitList = await _subjectVisitRepository.Where(x => x.CurrentActionUserId == context.Message.CurrentActionUserId && x.TrialId == subjectVisit.TrialId).Include(x => x.Subject).ToListAsync();
|
var scenario = context.Message.IsPd ? EmailBusinessScenario.PDVerification_PendingImageQC : EmailBusinessScenario.EligibilityVerification_PendingImageQC;
|
||||||
|
|
||||||
|
var trialEmailConfig = _trialEmailNoticeConfigrepository.Where(t => t.TrialId == trialId && t.BusinessScenarioEnum == scenario && t.IsAutoSend && t.IsEnable).FirstOrDefault();
|
||||||
|
|
||||||
|
if (trialEmailConfig != null)
|
||||||
|
|
||||||
var trialUser = await _trialUseRoleRepository.Where(x => x.TrialId == subjectVisit.TrialId).Include(x => x.UserRole).Select(x => x.UserRole).ToListAsync();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var pmandAPm = trialUser.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 messageToSend = new MimeMessage();
|
|
||||||
//发件地址
|
|
||||||
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
|
|
||||||
messageToSend.To.Add(new MailboxAddress(String.Empty, userinfo.EMail));
|
|
||||||
|
|
||||||
foreach (var pm in pmandAPm)
|
|
||||||
{
|
{
|
||||||
messageToSend.Cc.Add(new MailboxAddress(String.Empty, pm.EMail));
|
|
||||||
}
|
|
||||||
var companyName = isEn_US ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
|
|
||||||
|
|
||||||
var auditStateCode = "AuditStatePE";
|
|
||||||
|
|
||||||
if (trialInfo.QCProcessEnum == TrialQCProcess.DoubleAudit)
|
var subjectVisitList = await _subjectVisitRepository.Where(x => x.CurrentActionUserId == context.Message.CurrentActionUserId && x.TrialId == subjectVisit.TrialId).Include(x => x.Subject).ToListAsync();
|
||||||
{
|
|
||||||
auditStateCode = "AuditStateRC";
|
|
||||||
}
|
|
||||||
|
|
||||||
var dictionValue = await CommonEmailHelper.TranslationDictionary(new TranslationDictionaryDto()
|
|
||||||
{
|
var trialUserList = await _trialUseRoleRepository.Where(x => x.TrialId == subjectVisit.TrialId && x.TrialUser.IsDeleted == false).Include(x => x.UserRole).Select(x => x.UserRole).ToListAsync();
|
||||||
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 trialInfo = await _trialRepository.FirstOrDefaultAsync(t => t.Id == subjectVisit.TrialId);
|
||||||
|
|
||||||
|
|
||||||
|
var userinfo = subjectVisit.CurrentActionUser;
|
||||||
|
|
||||||
|
var messageToSend = new MimeMessage();
|
||||||
|
//发件地址
|
||||||
|
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
|
||||||
|
messageToSend.To.Add(new MailboxAddress(String.Empty, userinfo.EMail));
|
||||||
|
|
||||||
|
foreach (var pm in pmandAPm)
|
||||||
|
{
|
||||||
|
messageToSend.Cc.Add(new MailboxAddress(String.Empty, pm.EMail));
|
||||||
|
}
|
||||||
|
var companyName = isEn_US ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
|
||||||
|
|
||||||
|
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(), }, //审核状态
|
new DictionaryDto (){DictionaryCode= auditStateCode,EnumValue=subjectVisit.AuditState.GetEnumInt(), }, //审核状态
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
var subjectcodes = subjectVisitList.Select(x => x.Subject.Code).Distinct().ToList();
|
var subjectcodes = subjectVisitList.Select(x => x.Subject.Code).Distinct().ToList();
|
||||||
var visitnames = subjectVisitList.Select(x => x.VisitName).Distinct().ToList();
|
var visitnames = subjectVisitList.Select(x => x.VisitName).Distinct().ToList();
|
||||||
|
|
||||||
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
|
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
|
||||||
{
|
{
|
||||||
var subjectCode = subjectVisit.Subject.Code;
|
var subjectCode = subjectVisit.Subject.Code;
|
||||||
var topicStr = string.Format(input.topicStr, trialInfo.ResearchProgramNo, subjectCode, subjectVisit.VisitName);
|
var topicStr = string.Format(input.topicStr, trialInfo.ResearchProgramNo, subjectCode, subjectVisit.VisitName);
|
||||||
var htmlBodyStr = string.Format(
|
var htmlBodyStr = string.Format(
|
||||||
CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr),
|
CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr),
|
||||||
userinfo.FullName, // 用户名 {0}
|
userinfo.FullName, // 用户名 {0}
|
||||||
trialInfo.ExperimentName, // 项目 {1}
|
trialInfo.ExperimentName, // 项目 {1}
|
||||||
string.Join(',', subjectcodes), // 受试者 {2}
|
string.Join(',', subjectcodes), // 受试者 {2}
|
||||||
string.Join(',', visitnames), // 访视 {3}
|
string.Join(',', visitnames), // 访视 {3}
|
||||||
dictionValue[0], // 审核状态 {4}
|
dictionValue[0], // 审核状态 {4}
|
||||||
|
|
||||||
_systemEmailConfig.SiteUrl // 链接 {5}
|
|
||||||
);
|
|
||||||
|
|
||||||
return (topicStr, htmlBodyStr);
|
_systemEmailConfig.SiteUrl // 链接 {5}
|
||||||
};
|
);
|
||||||
|
|
||||||
await CommonEmailHelper.GetEmailSubejctAndHtmlInfoAndBuildAsync(_emailNoticeConfigrepository,
|
return (topicStr, htmlBodyStr);
|
||||||
|
};
|
||||||
|
|
||||||
context.Message.IsPd ? EmailBusinessScenario.PDVerification_PendingImageQC : EmailBusinessScenario.EligibilityVerification_PendingImageQC,
|
|
||||||
|
|
||||||
messageToSend, emailConfigFunc);
|
await CommonEmailHelper.GetTrialEmailSubejctAndHtmlInfoAndBuildAsync(trialEmailConfig, messageToSend, emailConfigFunc);
|
||||||
|
|
||||||
await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig);
|
await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using DocumentFormat.OpenXml;
|
using DocumentFormat.OpenXml;
|
||||||
|
using DocumentFormat.OpenXml.Spreadsheet;
|
||||||
using IRaCIS.Application.Contracts;
|
using IRaCIS.Application.Contracts;
|
||||||
using IRaCIS.Core.Application.Contracts;
|
using IRaCIS.Core.Application.Contracts;
|
||||||
using IRaCIS.Core.Application.Helper;
|
using IRaCIS.Core.Application.Helper;
|
||||||
@@ -27,7 +28,7 @@ namespace IRaCIS.Core.Application.MassTransit.Recurring
|
|||||||
IRepository<VisitTask> _visitTaskRepository,
|
IRepository<VisitTask> _visitTaskRepository,
|
||||||
IRepository<Dictionary> _dictionaryRepository,
|
IRepository<Dictionary> _dictionaryRepository,
|
||||||
IRepository<TrialUserRole> _trialUserRoleRepository,
|
IRepository<TrialUserRole> _trialUserRoleRepository,
|
||||||
IRepository<EmailNoticeConfig> _emailNoticeConfigrepository,
|
IRepository<TrialEmailNoticeConfig> _trialEmailNoticeConfigrepository,
|
||||||
IOptionsMonitor<SystemEmailSendConfig> systemEmailConfig) : IConsumer<UrgentIRUnReadTaskRecurringEvent>
|
IOptionsMonitor<SystemEmailSendConfig> systemEmailConfig) : IConsumer<UrgentIRUnReadTaskRecurringEvent>
|
||||||
{
|
{
|
||||||
private readonly SystemEmailSendConfig _systemEmailConfig = systemEmailConfig.CurrentValue;
|
private readonly SystemEmailSendConfig _systemEmailConfig = systemEmailConfig.CurrentValue;
|
||||||
@@ -35,144 +36,151 @@ namespace IRaCIS.Core.Application.MassTransit.Recurring
|
|||||||
public async Task Consume(ConsumeContext<UrgentIRUnReadTaskRecurringEvent> context)
|
public async Task Consume(ConsumeContext<UrgentIRUnReadTaskRecurringEvent> context)
|
||||||
{
|
{
|
||||||
var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;
|
var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;
|
||||||
|
|
||||||
var trialId = context.Message.TrialId;
|
var trialId = context.Message.TrialId;
|
||||||
|
|
||||||
var dictionValue = await CommonEmailHelper.TranslationDictionary(new TranslationDictionaryDto()
|
var scenario = EmailBusinessScenario.ExpeditedReading;
|
||||||
|
var trialEmailConfig = _trialEmailNoticeConfigrepository.Where(t => t.TrialId == trialId && t.BusinessScenarioEnum == scenario && t.IsAutoSend && t.IsEnable).FirstOrDefault();
|
||||||
|
|
||||||
|
if (trialEmailConfig != null)
|
||||||
{
|
{
|
||||||
DictionaryRepository = _dictionaryRepository,
|
|
||||||
IsEn_US = isEn_US,
|
|
||||||
DictionaryList = new List<DictionaryDto>()
|
var dictionValue = await CommonEmailHelper.TranslationDictionary(new TranslationDictionaryDto()
|
||||||
|
{
|
||||||
|
DictionaryRepository = _dictionaryRepository,
|
||||||
|
IsEn_US = isEn_US,
|
||||||
|
DictionaryList = new List<DictionaryDto>()
|
||||||
{
|
{
|
||||||
new DictionaryDto (){DictionaryCode= "YesOrNo",EnumValue="true" }
|
new DictionaryDto (){DictionaryCode= "YesOrNo",EnumValue="true" }
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
//找到该项目所有的IR 并且有加急 和Pd 未读的任务
|
//找到该项目所有的IR 并且有加急 和Pd 未读的任务
|
||||||
|
|
||||||
Expression<Func<VisitTask, bool>> comonTaskFilter = t => t.TrialId == trialId && t.TaskState == TaskState.Effect && t.ReadingTaskState != ReadingTaskState.HaveSigned && t.TaskAllocationState == TaskAllocationState.Allocated;
|
Expression<Func<VisitTask, bool>> comonTaskFilter = t => t.TrialId == trialId && t.TaskState == TaskState.Effect && t.ReadingTaskState != ReadingTaskState.HaveSigned && t.TaskAllocationState == TaskAllocationState.Allocated;
|
||||||
|
|
||||||
var trialUserList = _trialUserRoleRepository.Where(t => t.TrialId == trialId && t.TrialUser.JoinTime != null).Select(t => new
|
var trialUserList = _trialUserRoleRepository.Where(t => t.TrialId == trialId && t.TrialUser.JoinTime != null).Select(t => new
|
||||||
{
|
|
||||||
t.UserId,
|
|
||||||
t.UserRole.FullName,
|
|
||||||
t.UserRole.IdentityUser.EMail,
|
|
||||||
t.UserRole.IdentityUser.UserName,
|
|
||||||
t.Trial.TrialCode,
|
|
||||||
t.Trial.ResearchProgramNo
|
|
||||||
//TrialReadingCriterionList = t.Trial.TrialReadingCriterionList.Select(t => new { t.CriterionName, TrialReadingCriterionId = t.Id }).ToList()
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
foreach (var trialUser in trialUserList)
|
|
||||||
{
|
|
||||||
|
|
||||||
var userId = trialUser.UserId;
|
|
||||||
|
|
||||||
var doctorCriterionList = await _trialReadingCriterionRepository.Where(t => t.IsSigned && t.IsConfirm && t.TrialId == trialId && t.Trial.TrialUserRoleList.Any(t => t.UserId == userId))
|
|
||||||
.Select(c => new
|
|
||||||
{
|
|
||||||
|
|
||||||
TrialReadingCriterionId = c.Id,
|
|
||||||
CriterionName = c.CriterionName,
|
|
||||||
|
|
||||||
UnReadList = c.VisitTaskList.Where(t => t.ExpetidEmailNoticeTime == null) //没有被通知
|
|
||||||
.Where(t => t.DoctorUserId == userId && t.ReadingTaskState != ReadingTaskState.HaveSigned && t.TaskState == TaskState.Effect)
|
|
||||||
// 前序 不存在 未一致性核查未通过的
|
|
||||||
.Where(t => !t.Subject.SubjectVisitList.Any(sv => sv.CheckState != CheckStateEnum.CVPassed && t.VisitTaskNum > sv.VisitNum))
|
|
||||||
//前序 不存在 未生成任务的访视
|
|
||||||
.Where(t => c.IsAutoCreate == false ? !t.Subject.SubjectCriteriaEvaluationVisitFilterList.Where(d => d.TrialReadingCriterionId == t.TrialReadingCriterionId).Any(f => f.IsGeneratedTask == false && t.VisitTaskNum > f.SubjectVisit.VisitNum) : true)
|
|
||||||
|
|
||||||
.Where(y => y.IsFrontTaskNeedSignButNotSign == false && (y.IsNeedClinicalDataSign == false || y.IsClinicalDataSign == true))
|
|
||||||
|
|
||||||
.Where(t => t.SourceSubjectVisit.PDState == PDStateEnum.PDProgress || t.SourceSubjectVisit.IsEnrollmentConfirm ||
|
|
||||||
t.ReadModule.SubjectVisit.PDState == PDStateEnum.PDProgress || t.ReadModule.SubjectVisit.IsEnrollmentConfirm)
|
|
||||||
.Select(c => new
|
|
||||||
{
|
|
||||||
SubejctCode = c.IsAnalysisCreate ? c.BlindSubjectCode : c.Subject.Code,
|
|
||||||
c.TaskBlindName,
|
|
||||||
c.TaskName,
|
|
||||||
VisitTaskId = c.Id
|
|
||||||
}).ToList()
|
|
||||||
|
|
||||||
}).ToListAsync();
|
|
||||||
|
|
||||||
|
|
||||||
var toTalUnreadCount = doctorCriterionList.SelectMany(t => t.UnReadList).Count();
|
|
||||||
|
|
||||||
if (toTalUnreadCount > 0)
|
|
||||||
{
|
{
|
||||||
var messageToSend = new MimeMessage();
|
t.UserId,
|
||||||
|
t.UserRole.FullName,
|
||||||
|
t.UserRole.IdentityUser.EMail,
|
||||||
|
t.UserRole.IdentityUser.UserName,
|
||||||
|
t.Trial.TrialCode,
|
||||||
|
t.Trial.ResearchProgramNo
|
||||||
|
//TrialReadingCriterionList = t.Trial.TrialReadingCriterionList.Select(t => new { t.CriterionName, TrialReadingCriterionId = t.Id }).ToList()
|
||||||
|
});
|
||||||
|
|
||||||
//发件地址
|
|
||||||
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
|
|
||||||
messageToSend.To.Add(new MailboxAddress(trialUser.FullName, trialUser.EMail));
|
|
||||||
|
|
||||||
var companyName = isEn_US ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
|
foreach (var trialUser in trialUserList)
|
||||||
|
{
|
||||||
|
|
||||||
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
|
var userId = trialUser.UserId;
|
||||||
|
|
||||||
|
var doctorCriterionList = await _trialReadingCriterionRepository.Where(t => t.IsSigned && t.IsConfirm && t.TrialId == trialId && t.Trial.TrialUserRoleList.Any(t => t.UserId == userId))
|
||||||
|
.Select(c => new
|
||||||
|
{
|
||||||
|
|
||||||
|
TrialReadingCriterionId = c.Id,
|
||||||
|
CriterionName = c.CriterionName,
|
||||||
|
|
||||||
|
UnReadList = c.VisitTaskList.Where(t => t.ExpetidEmailNoticeTime == null) //没有被通知
|
||||||
|
.Where(t => t.DoctorUserId == userId && t.ReadingTaskState != ReadingTaskState.HaveSigned && t.TaskState == TaskState.Effect)
|
||||||
|
// 前序 不存在 未一致性核查未通过的
|
||||||
|
.Where(t => !t.Subject.SubjectVisitList.Any(sv => sv.CheckState != CheckStateEnum.CVPassed && t.VisitTaskNum > sv.VisitNum))
|
||||||
|
//前序 不存在 未生成任务的访视
|
||||||
|
.Where(t => c.IsAutoCreate == false ? !t.Subject.SubjectCriteriaEvaluationVisitFilterList.Where(d => d.TrialReadingCriterionId == t.TrialReadingCriterionId).Any(f => f.IsGeneratedTask == false && t.VisitTaskNum > f.SubjectVisit.VisitNum) : true)
|
||||||
|
|
||||||
|
.Where(y => y.IsFrontTaskNeedSignButNotSign == false && (y.IsNeedClinicalDataSign == false || y.IsClinicalDataSign == true))
|
||||||
|
|
||||||
|
.Where(t => t.SourceSubjectVisit.PDState == PDStateEnum.PDProgress || t.SourceSubjectVisit.IsEnrollmentConfirm ||
|
||||||
|
t.ReadModule.SubjectVisit.PDState == PDStateEnum.PDProgress || t.ReadModule.SubjectVisit.IsEnrollmentConfirm)
|
||||||
|
.Select(c => new
|
||||||
|
{
|
||||||
|
SubejctCode = c.IsAnalysisCreate ? c.BlindSubjectCode : c.Subject.Code,
|
||||||
|
c.TaskBlindName,
|
||||||
|
c.TaskName,
|
||||||
|
VisitTaskId = c.Id
|
||||||
|
}).ToList()
|
||||||
|
|
||||||
|
}).ToListAsync();
|
||||||
|
|
||||||
|
|
||||||
|
var toTalUnreadCount = doctorCriterionList.SelectMany(t => t.UnReadList).Count();
|
||||||
|
|
||||||
|
if (toTalUnreadCount > 0)
|
||||||
{
|
{
|
||||||
var topicStr = string.Format(input.topicStr, trialUser.ResearchProgramNo);
|
var messageToSend = new MimeMessage();
|
||||||
|
|
||||||
var template = input.htmlBodyStr;
|
//发件地址
|
||||||
|
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
|
||||||
|
messageToSend.To.Add(new MailboxAddress(trialUser.FullName, trialUser.EMail));
|
||||||
|
|
||||||
//正则提取循环的部分 {%for%}(.*?){%end for%}
|
var companyName = isEn_US ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
|
||||||
string pattern = @"{%for%}(.*?){%end for%}";
|
|
||||||
var match = Regex.Match(template, pattern, RegexOptions.Singleline);
|
|
||||||
|
|
||||||
string criteriaTemplate = match.Groups[1].Value; // 提取循环模板
|
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
|
||||||
|
|
||||||
// 构建循环内容
|
|
||||||
string criteriaDetails = "";
|
|
||||||
foreach (var criteria in doctorCriterionList)
|
|
||||||
{
|
{
|
||||||
if (criteria.UnReadList.Count() > 0)
|
var topicStr = string.Format(input.topicStr, trialUser.ResearchProgramNo);
|
||||||
|
|
||||||
|
var template = input.htmlBodyStr;
|
||||||
|
|
||||||
|
//正则提取循环的部分 {%for%}(.*?){%end for%}
|
||||||
|
string pattern = @"{%for%}(.*?){%end for%}";
|
||||||
|
var match = Regex.Match(template, pattern, RegexOptions.Singleline);
|
||||||
|
|
||||||
|
string criteriaTemplate = match.Groups[1].Value; // 提取循环模板
|
||||||
|
|
||||||
|
// 构建循环内容
|
||||||
|
string criteriaDetails = "";
|
||||||
|
foreach (var criteria in doctorCriterionList)
|
||||||
{
|
{
|
||||||
criteriaDetails += string.Format(criteriaTemplate, criteria.CriterionName, criteria.UnReadList.Select(t => t.SubejctCode).Distinct().Count(), criteria.UnReadList.Count());
|
if (criteria.UnReadList.Count() > 0)
|
||||||
|
{
|
||||||
|
criteriaDetails += string.Format(criteriaTemplate, criteria.CriterionName, criteria.UnReadList.Select(t => t.SubejctCode).Distinct().Count(), criteria.UnReadList.Count());
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// 用循环内容替换原始模板中的循环部分
|
// 用循环内容替换原始模板中的循环部分
|
||||||
string emailContent = template.Replace(criteriaTemplate, criteriaDetails).Replace("{%for%}", "").Replace("{%end for%}", "");
|
string emailContent = template.Replace(criteriaTemplate, criteriaDetails).Replace("{%for%}", "").Replace("{%end for%}", "");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var htmlBodyStr = string.Format(CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, emailContent),
|
var htmlBodyStr = string.Format(CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, emailContent),
|
||||||
trialUser.FullName,
|
trialUser.FullName,
|
||||||
|
|
||||||
DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
|
DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
|
||||||
toTalUnreadCount,
|
toTalUnreadCount,
|
||||||
|
|
||||||
trialUser.ResearchProgramNo,
|
trialUser.ResearchProgramNo,
|
||||||
dictionValue[0],
|
dictionValue[0],
|
||||||
_systemEmailConfig.SiteUrl
|
_systemEmailConfig.SiteUrl
|
||||||
);
|
);
|
||||||
|
|
||||||
return (topicStr, htmlBodyStr);
|
return (topicStr, htmlBodyStr);
|
||||||
};
|
};
|
||||||
|
|
||||||
await CommonEmailHelper.GetEmailSubejctAndHtmlInfoAndBuildAsync(_emailNoticeConfigrepository, EmailBusinessScenario.ExpeditedReading, messageToSend, emailConfigFunc);
|
await CommonEmailHelper.GetTrialEmailSubejctAndHtmlInfoAndBuildAsync(trialEmailConfig, messageToSend, emailConfigFunc);
|
||||||
|
|
||||||
await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig);
|
await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig);
|
||||||
|
|
||||||
//处理标记已通知的任务
|
//处理标记已通知的任务
|
||||||
|
|
||||||
|
var visitTaskIdList = doctorCriterionList.Where(t => t.UnReadList.Count() > 0).SelectMany(t => t.UnReadList.Select(u => u.VisitTaskId)).ToList();
|
||||||
|
|
||||||
|
await _visitTaskRepository.BatchUpdateNoTrackingAsync(t => visitTaskIdList.Contains(t.Id), u => new VisitTask() { ExpetidEmailNoticeTime = DateTime.Now });
|
||||||
|
}
|
||||||
|
|
||||||
var visitTaskIdList = doctorCriterionList.Where(t => t.UnReadList.Count() > 0).SelectMany(t => t.UnReadList.Select(u => u.VisitTaskId)).ToList();
|
|
||||||
|
|
||||||
await _visitTaskRepository.BatchUpdateNoTrackingAsync(t => visitTaskIdList.Contains(t.Id), u => new VisitTask() { ExpetidEmailNoticeTime = DateTime.Now });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,4 +37,24 @@ public class UrgentIRUnReadTaskRecurringEvent : DomainEvent
|
|||||||
public Guid TrialId { get; set; }
|
public Guid TrialId { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 定时提醒
|
||||||
|
/// </summary>
|
||||||
|
public class SystemDocumentErverDayEvent : DomainEvent
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public class SystemDocumentPublishEvent : DomainEvent
|
||||||
|
{
|
||||||
|
public List<Guid> Ids { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 新增的需要发送邮件的用户角色ID列表
|
||||||
|
/// 如果为null或空,则发送给所有相关角色
|
||||||
|
/// </summary>
|
||||||
|
public List<Guid> NewUserTypeIds { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,277 @@
|
|||||||
|
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 MassTransit;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
|
using MimeKit;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reactive.Joins;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace IRaCIS.Core.Application.MassTransit.Recurring
|
||||||
|
{
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 定时过期提醒
|
||||||
|
/// </summary>
|
||||||
|
public class SystemDocumentErverDayEventConsumer(
|
||||||
|
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<SystemDocumentErverDayEvent>
|
||||||
|
{
|
||||||
|
private readonly SystemEmailSendConfig _systemEmailConfig = systemEmailConfig.CurrentValue;
|
||||||
|
|
||||||
|
public async Task Consume(ConsumeContext<SystemDocumentErverDayEvent> context)
|
||||||
|
{
|
||||||
|
|
||||||
|
DateTime now = DateTime.Now;
|
||||||
|
Console.WriteLine("发送定时过期提醒");
|
||||||
|
var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;
|
||||||
|
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)))
|
||||||
|
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()
|
||||||
|
{
|
||||||
|
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,
|
||||||
|
ConfirmTime = confirm.ConfirmTime,
|
||||||
|
UserCreateTime = identityUser.CreateTime,
|
||||||
|
CurrentStaffTrainDays = sysDoc.CurrentStaffTrainDays,
|
||||||
|
NewStaffTrainDays = sysDoc.NewStaffTrainDays,
|
||||||
|
RealName = identityUser.FullName,
|
||||||
|
UserName = identityUser.UserName,
|
||||||
|
|
||||||
|
|
||||||
|
IsNeedSendEmial = identityUser.IsZhiZhun || (!identityUser.IsZhiZhun && sysDoc.DocUserSignType == DocUserSignType.InnerAndOuter),
|
||||||
|
FullFilePath = sysDoc.Path
|
||||||
|
};
|
||||||
|
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)
|
||||||
|
.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)
|
||||||
|
{
|
||||||
|
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(String.Empty, 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)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <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)
|
||||||
|
{
|
||||||
|
var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;
|
||||||
|
|
||||||
|
// 记录是否只发送给新增角色的日志
|
||||||
|
if (context.Message.NewUserTypeIds != null && context.Message.NewUserTypeIds.Any())
|
||||||
|
{
|
||||||
|
Console.WriteLine($"只发送给新增的角色,角色数量: {context.Message.NewUserTypeIds.Count}");
|
||||||
|
}
|
||||||
|
// 构建查询
|
||||||
|
IQueryable<UnionDocumentWithConfirmInfoView> systemDocQuery;
|
||||||
|
|
||||||
|
if (context.Message.NewUserTypeIds != null && context.Message.NewUserTypeIds.Any())
|
||||||
|
{
|
||||||
|
// 只查询新增角色的用户
|
||||||
|
systemDocQuery =
|
||||||
|
from sysDoc in _systemDocumentRepository.AsQueryable(false).Where(x => context.Message.Ids.Contains(x.Id))
|
||||||
|
from identityUser in _identityUserRepository.AsQueryable(false)
|
||||||
|
.Where(t => t.Status == UserStateEnum.Enable &&
|
||||||
|
t.UserRoleList.Where(t => t.IsUserRoleDisabled == false)
|
||||||
|
.Any(t => context.Message.NewUserTypeIds.Contains(t.UserTypeId) &&
|
||||||
|
sysDoc.NeedConfirmedUserTypeList.AsQueryable().Any(c => c.NeedConfirmUserTypeId == t.UserTypeId)))
|
||||||
|
select new UnionDocumentWithConfirmInfoView()
|
||||||
|
{
|
||||||
|
IsSystemDoc = true,
|
||||||
|
Id = sysDoc.Id,
|
||||||
|
CreateTime = sysDoc.CreateTime,
|
||||||
|
IsDeleted = sysDoc.IsDeleted,
|
||||||
|
SignViewMinimumMinutes = sysDoc.SignViewMinimumMinutes,
|
||||||
|
Name = sysDoc.Name,
|
||||||
|
Path = sysDoc.Path,
|
||||||
|
FileTypeId = sysDoc.FileTypeId,
|
||||||
|
UpdateTime = sysDoc.UpdateTime,
|
||||||
|
ConfirmUserId = identityUser.Id,
|
||||||
|
RealName = identityUser.FullName,
|
||||||
|
UserName = identityUser.UserName,
|
||||||
|
IsNeedSendEmial = identityUser.IsZhiZhun || (!identityUser.IsZhiZhun && sysDoc.DocUserSignType == DocUserSignType.InnerAndOuter),
|
||||||
|
FullFilePath = sysDoc.Path
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 查询所有相关角色的用户
|
||||||
|
systemDocQuery =
|
||||||
|
from sysDoc in _systemDocumentRepository.AsQueryable(false).Where(x => context.Message.Ids.Contains(x.Id))
|
||||||
|
from identityUser in _identityUserRepository.AsQueryable(false)
|
||||||
|
.Where(t => t.Status == UserStateEnum.Enable &&
|
||||||
|
t.UserRoleList.Where(t => t.IsUserRoleDisabled == false)
|
||||||
|
.Any(t => sysDoc.NeedConfirmedUserTypeList.AsQueryable().Any(c => c.NeedConfirmUserTypeId == t.UserTypeId)))
|
||||||
|
select new UnionDocumentWithConfirmInfoView()
|
||||||
|
{
|
||||||
|
IsSystemDoc = true,
|
||||||
|
Id = sysDoc.Id,
|
||||||
|
CreateTime = sysDoc.CreateTime,
|
||||||
|
IsDeleted = sysDoc.IsDeleted,
|
||||||
|
SignViewMinimumMinutes = sysDoc.SignViewMinimumMinutes,
|
||||||
|
Name = sysDoc.Name,
|
||||||
|
Path = sysDoc.Path,
|
||||||
|
FileTypeId = sysDoc.FileTypeId,
|
||||||
|
UpdateTime = sysDoc.UpdateTime,
|
||||||
|
ConfirmUserId = identityUser.Id,
|
||||||
|
RealName = identityUser.FullName,
|
||||||
|
UserName = identityUser.UserName,
|
||||||
|
IsNeedSendEmial = identityUser.IsZhiZhun || (!identityUser.IsZhiZhun && sysDoc.DocUserSignType == DocUserSignType.InnerAndOuter),
|
||||||
|
FullFilePath = sysDoc.Path
|
||||||
|
};
|
||||||
|
}
|
||||||
|
var datalist = await systemDocQuery.IgnoreQueryFilters().Where(x => x.IsNeedSendEmial).ToListAsync();
|
||||||
|
|
||||||
|
var confirmUserIdList = datalist.Select(t => t.ConfirmUserId).Distinct().ToList();
|
||||||
|
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(String.Empty, 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_EffectiveNotification;
|
||||||
|
|
||||||
|
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);
|
||||||
|
msg += "发送成功";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
msg += "发送失败";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Console.WriteLine(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -214,6 +214,8 @@ namespace IRaCIS.Core.Application.ViewModel
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public bool IsManualGeneration { get; set; }
|
public bool IsManualGeneration { get; set; }
|
||||||
//public bool IsAfterConvertedTask { get; set; }
|
//public bool IsAfterConvertedTask { get; set; }
|
||||||
|
|
||||||
|
public string PMBackReason { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -339,6 +341,16 @@ namespace IRaCIS.Core.Application.ViewModel
|
|||||||
|
|
||||||
public int UrgentCount { get; set; }
|
public int UrgentCount { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否存在未处理的反馈
|
||||||
|
/// </summary>
|
||||||
|
public bool IsExistUnprocessedFeedback
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return UnReadCanReadTaskList.Any(t => t.IsExistUnprocessedFeedback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public List<IRUnreadTaskView> UnReadCanReadTaskList { get; set; } = new List<IRUnreadTaskView>();
|
public List<IRUnreadTaskView> UnReadCanReadTaskList { get; set; } = new List<IRUnreadTaskView>();
|
||||||
|
|
||||||
@@ -355,6 +367,11 @@ namespace IRaCIS.Core.Application.ViewModel
|
|||||||
/// 是否是一致性分析产生
|
/// 是否是一致性分析产生
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool IsAnalysisCreate { get; set; }
|
public bool IsAnalysisCreate { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否存在未处理的反馈
|
||||||
|
/// </summary>
|
||||||
|
public bool IsExistUnprocessedFeedback { get; set; }
|
||||||
|
|
||||||
public bool IsUrgent { get; set; }
|
public bool IsUrgent { get; set; }
|
||||||
|
|
||||||
|
|||||||
@@ -4,10 +4,12 @@
|
|||||||
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
|
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
|
|
||||||
|
using DocumentFormat.OpenXml.Spreadsheet;
|
||||||
using IRaCIS.Core.Application.Contracts;
|
using IRaCIS.Core.Application.Contracts;
|
||||||
using IRaCIS.Core.Application.Filter;
|
using IRaCIS.Core.Application.Filter;
|
||||||
using IRaCIS.Core.Application.Interfaces;
|
using IRaCIS.Core.Application.Interfaces;
|
||||||
using IRaCIS.Core.Application.ViewModel;
|
using IRaCIS.Core.Application.ViewModel;
|
||||||
|
using IRaCIS.Core.Domain.Models;
|
||||||
using IRaCIS.Core.Domain.Share;
|
using IRaCIS.Core.Domain.Share;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
|
|||||||
@@ -1055,6 +1055,7 @@ public class VisitTaskService(IRepository<VisitTask> _visitTaskRepository,
|
|||||||
ReadingCategory = u.ReadingCategory,
|
ReadingCategory = u.ReadingCategory,
|
||||||
IsAnalysisCreate = u.IsAnalysisCreate,
|
IsAnalysisCreate = u.IsAnalysisCreate,
|
||||||
ArmEnum = u.ArmEnum,
|
ArmEnum = u.ArmEnum,
|
||||||
|
IsExistUnprocessedFeedback=u.UserFeedBackList.Any(t => t.State ==0),
|
||||||
TrialReadingCriterionId = u.TrialReadingCriterionId,
|
TrialReadingCriterionId = u.TrialReadingCriterionId,
|
||||||
IsNeedClinicalDataSign = u.IsNeedClinicalDataSign,
|
IsNeedClinicalDataSign = u.IsNeedClinicalDataSign,
|
||||||
IsClinicalDataSign = u.IsClinicalDataSign,
|
IsClinicalDataSign = u.IsClinicalDataSign,
|
||||||
@@ -1085,6 +1086,7 @@ public class VisitTaskService(IRepository<VisitTask> _visitTaskRepository,
|
|||||||
ReadingCategory = u.ReadingCategory,
|
ReadingCategory = u.ReadingCategory,
|
||||||
IsAnalysisCreate = u.IsAnalysisCreate,
|
IsAnalysisCreate = u.IsAnalysisCreate,
|
||||||
ArmEnum = u.ArmEnum,
|
ArmEnum = u.ArmEnum,
|
||||||
|
IsExistUnprocessedFeedback = u.UserFeedBackList.Any(t => t.State == 0),
|
||||||
TrialReadingCriterionId = u.TrialReadingCriterionId,
|
TrialReadingCriterionId = u.TrialReadingCriterionId,
|
||||||
IsNeedClinicalDataSign = u.IsNeedClinicalDataSign,
|
IsNeedClinicalDataSign = u.IsNeedClinicalDataSign,
|
||||||
IsClinicalDataSign = u.IsClinicalDataSign,
|
IsClinicalDataSign = u.IsClinicalDataSign,
|
||||||
@@ -1194,6 +1196,7 @@ public class VisitTaskService(IRepository<VisitTask> _visitTaskRepository,
|
|||||||
ReadingCategory = u.ReadingCategory,
|
ReadingCategory = u.ReadingCategory,
|
||||||
IsAnalysisCreate = u.IsAnalysisCreate,
|
IsAnalysisCreate = u.IsAnalysisCreate,
|
||||||
ArmEnum = u.ArmEnum,
|
ArmEnum = u.ArmEnum,
|
||||||
|
IsExistUnprocessedFeedback = u.UserFeedBackList.Any(t => t.State == 0),
|
||||||
TrialReadingCriterionId = u.TrialReadingCriterionId,
|
TrialReadingCriterionId = u.TrialReadingCriterionId,
|
||||||
IsNeedClinicalDataSign = u.IsNeedClinicalDataSign,
|
IsNeedClinicalDataSign = u.IsNeedClinicalDataSign,
|
||||||
IsClinicalDataSign = u.IsClinicalDataSign,
|
IsClinicalDataSign = u.IsClinicalDataSign,
|
||||||
@@ -2200,6 +2203,7 @@ public class VisitTaskService(IRepository<VisitTask> _visitTaskRepository,
|
|||||||
{
|
{
|
||||||
item.Id = Guid.Empty;
|
item.Id = Guid.Empty;
|
||||||
item.VisitTaskId = newTask.Id;
|
item.VisitTaskId = newTask.Id;
|
||||||
|
item.MeasureData = item.MeasureData.Replace(origenalTask.Id.ToString(), newTask.Id.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
_ = _readingCustomTagRepository.AddRangeAsync(readingCustomTagList).Result;
|
_ = _readingCustomTagRepository.AddRangeAsync(readingCustomTagList).Result;
|
||||||
@@ -2213,6 +2217,7 @@ public class VisitTaskService(IRepository<VisitTask> _visitTaskRepository,
|
|||||||
{
|
{
|
||||||
item.Id = Guid.Empty;
|
item.Id = Guid.Empty;
|
||||||
item.VisitTaskId = newTask.Id;
|
item.VisitTaskId = newTask.Id;
|
||||||
|
|
||||||
}
|
}
|
||||||
_ = _readingTaskQuestionAnswerRepository.AddRangeAsync(readingTaskQuestionAnswerList).Result;
|
_ = _readingTaskQuestionAnswerRepository.AddRangeAsync(readingTaskQuestionAnswerList).Result;
|
||||||
|
|
||||||
@@ -2224,6 +2229,8 @@ public class VisitTaskService(IRepository<VisitTask> _visitTaskRepository,
|
|||||||
item.Id = Guid.Empty;
|
item.Id = Guid.Empty;
|
||||||
item.FristAddTaskId = item.VisitTaskId == item.FristAddTaskId ? newTask.Id : item.FristAddTaskId;
|
item.FristAddTaskId = item.VisitTaskId == item.FristAddTaskId ? newTask.Id : item.FristAddTaskId;
|
||||||
item.VisitTaskId = newTask.Id;
|
item.VisitTaskId = newTask.Id;
|
||||||
|
|
||||||
|
item.MeasureData = item.MeasureData.Replace(origenalTask.Id.ToString(), newTask.Id.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -2250,6 +2257,7 @@ public class VisitTaskService(IRepository<VisitTask> _visitTaskRepository,
|
|||||||
//默认值是当前任务添加的
|
//默认值是当前任务添加的
|
||||||
item.FristAddTaskId = originalVisitTaskId == originalFristAddTaskId ? newTask.Id : item.FristAddTaskId;
|
item.FristAddTaskId = originalVisitTaskId == originalFristAddTaskId ? newTask.Id : item.FristAddTaskId;
|
||||||
|
|
||||||
|
item.MeasureData = item.MeasureData.Replace(origenalTask.Id.ToString(), newTask.Id.ToString());
|
||||||
|
|
||||||
foreach (var item2 in item.LesionAnswerList)
|
foreach (var item2 in item.LesionAnswerList)
|
||||||
{
|
{
|
||||||
@@ -2273,11 +2281,11 @@ public class VisitTaskService(IRepository<VisitTask> _visitTaskRepository,
|
|||||||
/// PM 设置任务 退回
|
/// PM 设置任务 退回
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpPut("{trialId:guid}/{taskId:guid}")]
|
[HttpPut("{trialId:guid}/{taskId:guid}/{pmBackReason}")]
|
||||||
[UnitOfWork]
|
[UnitOfWork]
|
||||||
[TrialGlobalLimit("AfterStopCannNotOpt")]
|
[TrialGlobalLimit("AfterStopCannNotOpt")]
|
||||||
|
|
||||||
public async Task<IResponseOutput> PMSetTaskBack(Guid trialId, Guid taskId)
|
public async Task<IResponseOutput> PMSetTaskBack(Guid trialId, Guid taskId,string pmBackReason)
|
||||||
{
|
{
|
||||||
|
|
||||||
//var trialConfig = (await _trialRepository.Where(t => t.Id == trialId).Select(t => new { TrialId = t.Id, t.IsReadingTaskViewInOrder, t.ReadingType }).FirstOrDefaultAsync()).IfNullThrowException();
|
//var trialConfig = (await _trialRepository.Where(t => t.Id == trialId).Select(t => new { TrialId = t.Id, t.IsReadingTaskViewInOrder, t.ReadingType }).FirstOrDefaultAsync()).IfNullThrowException();
|
||||||
@@ -2338,7 +2346,6 @@ public class VisitTaskService(IRepository<VisitTask> _visitTaskRepository,
|
|||||||
|
|
||||||
#region 有序 无序公用流程
|
#region 有序 无序公用流程
|
||||||
|
|
||||||
|
|
||||||
//执行类似一致性核查回退流程 回退访视到影像上传流程
|
//执行类似一致性核查回退流程 回退访视到影像上传流程
|
||||||
await VisitBackAsync(task.SourceSubjectVisitId);
|
await VisitBackAsync(task.SourceSubjectVisitId);
|
||||||
|
|
||||||
@@ -2455,6 +2462,9 @@ public class VisitTaskService(IRepository<VisitTask> _visitTaskRepository,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var trackTask = await _visitTaskRepository.FindAsync(task.Id);
|
||||||
|
trackTask.PMBackReason = pmBackReason;
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -2669,8 +2679,9 @@ public class VisitTaskService(IRepository<VisitTask> _visitTaskRepository,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//默认影响的都是该标准的任务
|
//默认影响的都是该标准的任务
|
||||||
filterExpression = filterExpression.And(t => t.TrialReadingCriterionId == filterObj.TrialReadingCriterionId);
|
filterExpression = filterExpression.And(t => t.TrialReadingCriterionId == filterObj.TrialReadingCriterionId);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -96,6 +96,8 @@ namespace IRaCIS.Core.Application.ViewModel
|
|||||||
|
|
||||||
public int State { get; set; }
|
public int State { get; set; }
|
||||||
|
|
||||||
|
public Guid? PublishLogId { get; set; }
|
||||||
|
|
||||||
public List<BatchAddInternationalizationDto> AddList { get; set; }
|
public List<BatchAddInternationalizationDto> AddList { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -112,6 +114,8 @@ namespace IRaCIS.Core.Application.ViewModel
|
|||||||
|
|
||||||
public int? State { get; set; }
|
public int? State { get; set; }
|
||||||
|
|
||||||
|
public int InternationalizationType { get; set; }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class BatchAddInternationalizationDto : BatchInternationalizationDto
|
public class BatchAddInternationalizationDto : BatchInternationalizationDto
|
||||||
@@ -121,6 +125,9 @@ namespace IRaCIS.Core.Application.ViewModel
|
|||||||
|
|
||||||
public class InternationalizationSimpleDto : BatchInternationalizationDto
|
public class InternationalizationSimpleDto : BatchInternationalizationDto
|
||||||
{
|
{
|
||||||
|
public string Version { get; set; }
|
||||||
|
|
||||||
|
public DateTime CreateTime { get; set; }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,8 +4,10 @@
|
|||||||
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
|
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
|
|
||||||
|
using IRaCIS.Core.Application.Helper;
|
||||||
using IRaCIS.Core.Domain.Share;
|
using IRaCIS.Core.Domain.Share;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using NPOI.SS.Formula.Functions;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
namespace IRaCIS.Core.Application.Contracts
|
namespace IRaCIS.Core.Application.Contracts
|
||||||
@@ -44,12 +46,20 @@ namespace IRaCIS.Core.Application.Contracts
|
|||||||
{
|
{
|
||||||
var verifyExp1 = new EntityVerifyExp<EmailNoticeConfig>()
|
var verifyExp1 = new EntityVerifyExp<EmailNoticeConfig>()
|
||||||
{
|
{
|
||||||
VerifyExp = t => t.BusinessScenarioEnum == addOrEditEmailNoticeConfig.BusinessScenarioEnum && t.CriterionTypeEnum== addOrEditEmailNoticeConfig.CriterionTypeEnum,
|
VerifyExp = t => t.BusinessScenarioEnum == addOrEditEmailNoticeConfig.BusinessScenarioEnum && t.CriterionTypeEnum == addOrEditEmailNoticeConfig.CriterionTypeEnum,
|
||||||
|
|
||||||
VerifyMsg = _localizer["EmailNoticeConfig_RepeatEmailScenario"]
|
VerifyMsg = _localizer["EmailNoticeConfig_RepeatEmailScenario"]
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var verifyExp2 = new EntityVerifyExp<EmailNoticeConfig>()
|
||||||
|
{
|
||||||
|
VerifyExp = t => t.Code == addOrEditEmailNoticeConfig.Code && t.IsDistinguishCriteria == addOrEditEmailNoticeConfig.IsDistinguishCriteria && t.SystemLevel == addOrEditEmailNoticeConfig.SystemLevel,
|
||||||
|
|
||||||
|
VerifyMsg = _localizer["EmailNoticeConfig_RepeatCode"]
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
// 匹配所有占位符的正则表达式,允许包含空格的占位符
|
// 匹配所有占位符的正则表达式,允许包含空格的占位符
|
||||||
var regex = new Regex(@"\{\s*\d+\s*\}");
|
var regex = new Regex(@"\{\s*\d+\s*\}");
|
||||||
|
|
||||||
@@ -61,10 +71,14 @@ namespace IRaCIS.Core.Application.Contracts
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var entity = new EmailNoticeConfig() { };
|
||||||
|
|
||||||
if (addOrEditEmailNoticeConfig.Id == null)
|
if (addOrEditEmailNoticeConfig.Id == null)
|
||||||
{
|
{
|
||||||
|
|
||||||
var entity = _mapper.Map<EmailNoticeConfig>(addOrEditEmailNoticeConfig);
|
entity = _mapper.Map<EmailNoticeConfig>(addOrEditEmailNoticeConfig);
|
||||||
|
|
||||||
|
|
||||||
foreach (var item in addOrEditEmailNoticeConfig.ToUserTypeList)
|
foreach (var item in addOrEditEmailNoticeConfig.ToUserTypeList)
|
||||||
@@ -80,9 +94,9 @@ namespace IRaCIS.Core.Application.Contracts
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
await _emailNoticeConfigrepository.AddAsync(entity, true, verifyExp1);
|
await _emailNoticeConfigrepository.AddAsync(entity, true, verifyExp1, verifyExp2);
|
||||||
|
|
||||||
|
|
||||||
return ResponseOutput.Ok(entity.Id.ToString());
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -103,14 +117,32 @@ namespace IRaCIS.Core.Application.Contracts
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
var entity = await _emailNoticeConfigrepository.UpdateFromDTOAsync(addOrEditEmailNoticeConfig, true, false, verifyExp1);
|
entity = await _emailNoticeConfigrepository.UpdateFromDTOAsync(addOrEditEmailNoticeConfig, true, false, verifyExp1, verifyExp2);
|
||||||
|
|
||||||
|
|
||||||
return ResponseOutput.Ok(entity.Id.ToString());
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (entity.EmailCron != string.Empty)
|
||||||
|
{
|
||||||
|
var jobId = $"{entity.Id}_({entity.BusinessScenarioEnum})";
|
||||||
|
|
||||||
|
//有的job 可能编辑控制直接不发,需要移除已存在的
|
||||||
|
HangfireJobHelper.RemoveCronJob(jobId);
|
||||||
|
|
||||||
|
if (entity.IsAutoSend && entity.IsEnable)
|
||||||
|
{
|
||||||
|
HangfireJobHelper.AddOrUpdateSystemCronJob(jobId, entity.BusinessScenarioEnum, entity.EmailCron);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return ResponseOutput.Ok(entity.Id.ToString());
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ using IRaCIS.Application.Interfaces;
|
|||||||
using IRaCIS.Core.API._ServiceExtensions.NewtonsoftJson;
|
using IRaCIS.Core.API._ServiceExtensions.NewtonsoftJson;
|
||||||
using IRaCIS.Core.Application.Contracts;
|
using IRaCIS.Core.Application.Contracts;
|
||||||
using IRaCIS.Core.Application.Contracts.DTO;
|
using IRaCIS.Core.Application.Contracts.DTO;
|
||||||
|
using IRaCIS.Core.Application.Service.Reading.Dto;
|
||||||
using IRaCIS.Core.Application.ViewModel;
|
using IRaCIS.Core.Application.ViewModel;
|
||||||
using IRaCIS.Core.Domain.Models;
|
using IRaCIS.Core.Domain.Models;
|
||||||
using IRaCIS.Core.Domain.Share;
|
using IRaCIS.Core.Domain.Share;
|
||||||
@@ -81,7 +82,7 @@ namespace IRaCIS.Core.Application.Service.Common
|
|||||||
|
|
||||||
.WhereIf(param.IsDeleted != null, t => t.IsDeleted == param.IsDeleted)
|
.WhereIf(param.IsDeleted != null, t => t.IsDeleted == param.IsDeleted)
|
||||||
.WhereIf(!string.IsNullOrWhiteSpace(param.OrganizationName),
|
.WhereIf(!string.IsNullOrWhiteSpace(param.OrganizationName),
|
||||||
t => t.UserRole.OrganizationName.Contains(param.OrganizationName))
|
t => t.UserRole.IdentityUser.OrganizationName.Contains(param.OrganizationName))
|
||||||
.WhereIf(!string.IsNullOrWhiteSpace(param.UserRealName),
|
.WhereIf(!string.IsNullOrWhiteSpace(param.UserRealName),
|
||||||
t => (t.UserRole.FullName).Contains(param.UserRealName))
|
t => (t.UserRole.FullName).Contains(param.UserRealName))
|
||||||
.Select(t => new TrialMaintenanceDTO()
|
.Select(t => new TrialMaintenanceDTO()
|
||||||
@@ -349,6 +350,114 @@ namespace IRaCIS.Core.Application.Service.Common
|
|||||||
|
|
||||||
#region 导表查询
|
#region 导表查询
|
||||||
|
|
||||||
|
///getSysDocumentConfirmList 系统文档培训查询
|
||||||
|
///
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<IActionResult> GetSysDocumentConfirmList_Export(SystemDocQuery inQuery,
|
||||||
|
[FromServices] IRepository<SystemDocument> _systemDocumentRepository,
|
||||||
|
[FromServices] IRepository<IdentityUser> _identityUserRepository,
|
||||||
|
[FromServices] IDictionaryService _dictionaryService)
|
||||||
|
{
|
||||||
|
var systemDocQuery =
|
||||||
|
from sysDoc in _systemDocumentRepository.AsQueryable(false)
|
||||||
|
.Where(t => inQuery.UserTypeId != null ? t.NeedConfirmedUserTypeList.Any(t => t.NeedConfirmUserTypeId == inQuery.UserTypeId) : true)
|
||||||
|
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)))
|
||||||
|
.Where(t => inQuery.UserId != null ? t.Id == inQuery.UserId : true)
|
||||||
|
.Where(t => inQuery.UserTypeId != null ? t.UserRoleList.Any(t => t.UserTypeId == inQuery.UserTypeId && t.IsUserRoleDisabled == false) : true)
|
||||||
|
join confirm in _systemDocConfirmedUserRepository.Where() on new { ConfirmUserId = identityUser.Id, SystemDocumentId = sysDoc.Id } equals new { confirm.ConfirmUserId, confirm.SystemDocumentId } into cc
|
||||||
|
from confirm in cc.DefaultIfEmpty()
|
||||||
|
select new TrainingRecordExportDTO()
|
||||||
|
{
|
||||||
|
IsSystemDoc = true,
|
||||||
|
Id = sysDoc.Id,
|
||||||
|
CreateTime = sysDoc.CreateTime,
|
||||||
|
IsDeleted = sysDoc.IsDeleted,
|
||||||
|
Name = sysDoc.Name,
|
||||||
|
FileType = _userInfo.IsEn_Us ? sysDoc.FileType.Value : sysDoc.FileType.ValueCN,
|
||||||
|
FileTypeId = sysDoc.FileTypeId,
|
||||||
|
//IsConfirmed = confirm.ConfirmTime != null,
|
||||||
|
|
||||||
|
ConfirmUserId = identityUser.Id,
|
||||||
|
ConfirmTime = confirm.ConfirmTime,
|
||||||
|
|
||||||
|
RealName = identityUser.FullName,
|
||||||
|
UserName = identityUser.UserName,
|
||||||
|
|
||||||
|
|
||||||
|
//UpdateTime = sysDoc.UpdateTime,
|
||||||
|
//SignViewMinimumMinutes = sysDoc.SignViewMinimumMinutes,
|
||||||
|
//UserTypeId = trialUser.UserRole.UserTypeId,
|
||||||
|
//UserTypeShortName = trialUser.UserRole.UserTypeRole.UserTypeShortName,
|
||||||
|
//Path = sysDoc.Path,
|
||||||
|
//FullFilePath = sysDoc.Path
|
||||||
|
};
|
||||||
|
|
||||||
|
var unionQuery = systemDocQuery.IgnoreQueryFilters().Where(t => !(t.IsDeleted == true && t.ConfirmTime == null))
|
||||||
|
.WhereIf(!string.IsNullOrEmpty(inQuery.Name), t => t.Name.Contains(inQuery.Name))
|
||||||
|
.WhereIf(inQuery.FileTypeId != null, t => t.FileTypeId == inQuery.FileTypeId)
|
||||||
|
.WhereIf(inQuery.IsConfirmed == true, t => t.ConfirmTime != null)
|
||||||
|
.WhereIf(inQuery.IsConfirmed == false, t => t.ConfirmTime == null)
|
||||||
|
.WhereIf(inQuery.StartConfirmTime != null, t => t.ConfirmTime >= inQuery.StartConfirmTime.Value)
|
||||||
|
.WhereIf(inQuery.EndConfirmTime != null, t => t.ConfirmTime <= inQuery.EndConfirmTime.Value)
|
||||||
|
.WhereIf(inQuery.BeginCreateTime != null, t => t.CreateTime >= inQuery.BeginCreateTime)
|
||||||
|
.WhereIf(inQuery.EndCreateTime != null, t => t.CreateTime <= inQuery.EndCreateTime)
|
||||||
|
.WhereIf(!string.IsNullOrEmpty(inQuery.UserName), t => t.UserName.Contains(inQuery.UserName))
|
||||||
|
.WhereIf(inQuery.IsDeleted != null, t => t.IsDeleted == inQuery.IsDeleted);
|
||||||
|
|
||||||
|
var list = await unionQuery.SortToListAsync(inQuery);
|
||||||
|
|
||||||
|
#region 处理文档 需要签署的角色类型 和每个人的角色信息
|
||||||
|
|
||||||
|
var trialDocIdList = list.Where(t => t.IsSystemDoc == false).Select(t => t.Id).ToList();
|
||||||
|
|
||||||
|
var sysDocIdList = list.Where(t => t.IsSystemDoc == true).Select(t => t.Id).ToList();
|
||||||
|
|
||||||
|
var identityUserIdList = list.Select(t => t.ConfirmUserId).Distinct().ToList();
|
||||||
|
|
||||||
|
|
||||||
|
var sysDocUserTypeList = _systemDocNeedConfirmedUserTypeRepository.Where(t => sysDocIdList.Contains(t.SystemDocumentId)).Select(t => new { t.SystemDocumentId, t.UserTypeRole.UserTypeShortName }).ToList();
|
||||||
|
|
||||||
|
var identityUserUserTypeList = _identityUserRepository.Where(t => identityUserIdList.Contains(t.Id)).IgnoreQueryFilters().Select(t => new { IdentityUserId = t.Id, UserTypeList = t.UserRoleList.Where(t => t.IsUserRoleDisabled == false).Select(c => c.UserTypeRole.UserTypeShortName).ToList() });
|
||||||
|
|
||||||
|
//Concat 不能用导航属性
|
||||||
|
var sysids = list.Where(t => t.IsSystemDoc == true).Select(t => t.Id).ToList();
|
||||||
|
|
||||||
|
//var sysDataList = await _systemDocumentRepository.Where(x => sysids.Contains(x.Id)).Include(x => x.SystemDocumentAttachmentList).ToListAsync();
|
||||||
|
|
||||||
|
foreach (var item in list)
|
||||||
|
{
|
||||||
|
|
||||||
|
//if (sysDataList.Any(y => y.Id == item.Id))
|
||||||
|
//{
|
||||||
|
// item.AttachmentCount = sysDataList.Where(y => y.Id == item.Id).Select(x => x.SystemDocumentAttachmentList.Where(z => !z.OffLine).Count()).FirstOrDefault();
|
||||||
|
//}
|
||||||
|
|
||||||
|
if (item.IsSystemDoc)
|
||||||
|
{
|
||||||
|
item.DocNeedSignUserTypeList = sysDocUserTypeList.Where(t => t.SystemDocumentId == item.Id).Select(t => t.UserTypeShortName).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
item.IdentityUserTypeList = identityUserUserTypeList.Where(t => t.IdentityUserId == item.ConfirmUserId).SelectMany(c => c.UserTypeList).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
var exportInfo = new ExcelExportInfo();
|
||||||
|
|
||||||
|
exportInfo.List = list;
|
||||||
|
exportInfo.CurrentTime = ExportExcelConverterDate.DateTimeInternationalToString(DateTime.Now, _userInfo.TimeZoneId);
|
||||||
|
exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(list, _userInfo.TimeZoneId);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return await ExcelExportHelper.DataExportAsync(StaticData.Export.CommonTrainingRecordList_Export, exportInfo, $"{exportInfo.ResearchProgramNo}", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(TrainingRecordExportDTO));
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// getDocumentConfirmList 培训记录导出--new
|
/// getDocumentConfirmList 培训记录导出--new
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -1549,8 +1658,8 @@ namespace IRaCIS.Core.Application.Service.Common
|
|||||||
{
|
{
|
||||||
var emailNoticeConfigQueryable = _emailNoticeConfigrepository
|
var emailNoticeConfigQueryable = _emailNoticeConfigrepository
|
||||||
//.WhereIf(inQuery.SystemLevel == null, t => t.SystemLevel == SysEmailLevel.not_sys)
|
//.WhereIf(inQuery.SystemLevel == null, t => t.SystemLevel == SysEmailLevel.not_sys)
|
||||||
//.WhereIf(inQuery.SystemLevel != null, t => t.SystemLevel == inQuery.SystemLevel)
|
.WhereIf(inQuery.SystemLevel != null, t => t.SystemLevel == inQuery.SystemLevel)
|
||||||
//.WhereIf(inQuery.IsDistinguishCriteria != null, t => t.IsDistinguishCriteria == inQuery.IsDistinguishCriteria)
|
.WhereIf(inQuery.IsDistinguishCriteria != null, t => t.IsDistinguishCriteria == inQuery.IsDistinguishCriteria)
|
||||||
.WhereIf(inQuery.CriterionTypeEnum != null, t => t.CriterionTypeEnum == inQuery.CriterionTypeEnum)
|
.WhereIf(inQuery.CriterionTypeEnum != null, t => t.CriterionTypeEnum == inQuery.CriterionTypeEnum)
|
||||||
.WhereIf(inQuery.BusinessScenarioEnum != null, t => t.BusinessScenarioEnum == inQuery.BusinessScenarioEnum)
|
.WhereIf(inQuery.BusinessScenarioEnum != null, t => t.BusinessScenarioEnum == inQuery.BusinessScenarioEnum)
|
||||||
.WhereIf(inQuery.IsReturnRequired != null, t => t.IsReturnRequired == inQuery.IsReturnRequired)
|
.WhereIf(inQuery.IsReturnRequired != null, t => t.IsReturnRequired == inQuery.IsReturnRequired)
|
||||||
@@ -1613,8 +1722,52 @@ namespace IRaCIS.Core.Application.Service.Common
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<T> DealOncologyResult<T>(IRepository<ReadingOncologyTaskInfo> _oncologyRepository, bool isOncology, List<T> list) where T : CommonEvaluationExport
|
||||||
|
{
|
||||||
|
if (isOncology)
|
||||||
|
{
|
||||||
|
|
||||||
|
var subjectIdList = list.Select(t => t.SubjectId).Distinct().ToList();
|
||||||
|
|
||||||
|
//已阅片完的肿瘤学结果
|
||||||
|
var oncologyResultList = _oncologyRepository.Where(t => subjectIdList.Contains(t.OncologyVisitTask.SubjectId)
|
||||||
|
&& t.OncologyVisitTask.IsAnalysisCreate == false && t.OncologyVisitTask.ReadingTaskState == ReadingTaskState.HaveSigned && t.OncologyVisitTask.TaskState == TaskState.Effect)
|
||||||
|
|
||||||
|
.Select(t => new { t.OncologyVisitTask.SubjectId, OncologyVisitTaskNum = t.OncologyVisitTask.VisitTaskNum, OncologyUserName = t.OncologyVisitTask.DoctorUser.UserName, t.VisitTask.VisitTaskNum, t.VisitTaskId, t.EvaluationReason, t.EvaluationResult })
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
foreach (var subjectOncologyResult in oncologyResultList.GroupBy(t => t.SubjectId))
|
||||||
|
{
|
||||||
|
//最后已完成的肿瘤学任务号
|
||||||
|
var lastOncologyVisitTaskNum = subjectOncologyResult.OrderByDescending(t => t.OncologyVisitTaskNum).FirstOrDefault().OncologyVisitTaskNum;
|
||||||
|
|
||||||
|
//需要填充的肿瘤学结果
|
||||||
|
var subjectOncologyList = subjectOncologyResult.Where(t => t.OncologyVisitTaskNum == lastOncologyVisitTaskNum).ToList();
|
||||||
|
|
||||||
|
|
||||||
|
foreach (var subjectOncology in subjectOncologyList)
|
||||||
|
{
|
||||||
|
|
||||||
|
foreach (var item in list)
|
||||||
|
{
|
||||||
|
if (item.SubjectId == subjectOncology.SubjectId && item.VisitTaskNum == subjectOncology.VisitTaskNum)
|
||||||
|
{
|
||||||
|
item.OncologyReason = subjectOncology.EvaluationReason;
|
||||||
|
item.OncologyResult = subjectOncology.EvaluationResult;
|
||||||
|
item.OncologyUserName = subjectOncology.OncologyUserName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
public List<T> DealJudgeMark<T>(ArbitrationRule arbitrationRule, bool isGlobalReading, IEnumerable<T> list) where T : CommonEvaluationExport
|
public List<T> DealJudgeMark<T>(ArbitrationRule arbitrationRule, bool isGlobalReading, IEnumerable<T> list) where T : CommonEvaluationExport
|
||||||
{
|
{
|
||||||
//处理访视任务的裁判标记
|
//处理访视任务的裁判标记
|
||||||
@@ -2172,12 +2325,13 @@ namespace IRaCIS.Core.Application.Service.Common
|
|||||||
[FromServices] IDictionaryService _dictionaryService,
|
[FromServices] IDictionaryService _dictionaryService,
|
||||||
[FromServices] IRepository<ReadingQuestionTrial> _trialReadingQuestionRepository,
|
[FromServices] IRepository<ReadingQuestionTrial> _trialReadingQuestionRepository,
|
||||||
[FromServices] IRepository<ReadingTableQuestionTrial> _trialReadingTableQuestionRepository,
|
[FromServices] IRepository<ReadingTableQuestionTrial> _trialReadingTableQuestionRepository,
|
||||||
|
[FromServices] IRepository<ReadingOncologyTaskInfo> _oncologyRepository,
|
||||||
[FromServices] IRepository<Trial> _trialRepository)
|
[FromServices] IRepository<Trial> _trialRepository)
|
||||||
{
|
{
|
||||||
var trialId = inQuery.TrialId;
|
var trialId = inQuery.TrialId;
|
||||||
var trialReadingCriterionId = inQuery.TrialReadingCriterionId;
|
var trialReadingCriterionId = inQuery.TrialReadingCriterionId;
|
||||||
//每次查询必须是单标准的
|
//每次查询必须是单标准的
|
||||||
var criterion = await _readingQuestionCriterionTrialRepository.Where(t => t.Id == inQuery.TrialReadingCriterionId).Select(t => new { t.CriterionType, t.CriterionGroup, t.IsGlobalReading, t.IsArbitrationReading, t.CriterionName, t.ArbitrationRule }).FirstNotNullAsync();
|
var criterion = await _readingQuestionCriterionTrialRepository.Where(t => t.Id == inQuery.TrialReadingCriterionId).Select(t => new { t.CriterionType, t.CriterionGroup, t.IsGlobalReading, t.IsArbitrationReading, t.IsOncologyReading, t.CriterionName, t.ArbitrationRule }).FirstNotNullAsync();
|
||||||
|
|
||||||
|
|
||||||
var query = _visitTaskRepository.Where(t => t.TrialId == inQuery.TrialId && t.IsAnalysisCreate == false && (t.TaskState == TaskState.Effect || t.TaskState == TaskState.Freeze))
|
var query = _visitTaskRepository.Where(t => t.TrialId == inQuery.TrialId && t.IsAnalysisCreate == false && (t.TaskState == TaskState.Effect || t.TaskState == TaskState.Freeze))
|
||||||
@@ -2218,6 +2372,16 @@ namespace IRaCIS.Core.Application.Service.Common
|
|||||||
//仲裁阅片 才有裁判阅片明细表 同时要把模板里面的三列给去掉
|
//仲裁阅片 才有裁判阅片明细表 同时要把模板里面的三列给去掉
|
||||||
removeColumnIndexList = new List<int>() { 6, 7, 8 };
|
removeColumnIndexList = new List<int>() { 6, 7, 8 };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//阅片结果表 和阅片结果明细表 没有肿瘤学的时候需要移除肿瘤学三个字段
|
||||||
|
|
||||||
|
if (!criterion.IsOncologyReading)
|
||||||
|
{
|
||||||
|
if (inQuery.ReadingExportType == ExportResult.TableOfAssessmentResults || inQuery.ReadingExportType == ExportResult.DetailedTableOfAssessmentResults)
|
||||||
|
{
|
||||||
|
removeColumnIndexList = removeColumnIndexList.Union(new List<int>() { 9, 10, 11 }).ToList();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var export_Template = StaticData.Export.CommonReading_Export;
|
var export_Template = StaticData.Export.CommonReading_Export;
|
||||||
@@ -2400,7 +2564,7 @@ namespace IRaCIS.Core.Application.Service.Common
|
|||||||
{
|
{
|
||||||
Id = Guid.Empty,
|
Id = Guid.Empty,
|
||||||
Name = (t.QuestionType == QuestionType.ExistDisease || t.QuestionType == QuestionType.Tumor) ? (_userInfo.IsEn_Us ? "Overall Response" : "整体肿瘤评估") : t.QuestionName
|
Name = (t.QuestionType == QuestionType.ExistDisease || t.QuestionType == QuestionType.Tumor) ? (_userInfo.IsEn_Us ? "Overall Response" : "整体肿瘤评估") : t.QuestionName
|
||||||
}).ToList();
|
}).Distinct().ToList();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -2413,7 +2577,7 @@ namespace IRaCIS.Core.Application.Service.Common
|
|||||||
{
|
{
|
||||||
Id = Guid.Empty,
|
Id = Guid.Empty,
|
||||||
Name = (t.QuestionType == QuestionType.ExistDisease || t.QuestionType == QuestionType.ImgOncology) ? (_userInfo.IsEn_Us ? "Overall Response" : "整体肿瘤评估") : t.QuestionName
|
Name = (t.QuestionType == QuestionType.ExistDisease || t.QuestionType == QuestionType.ImgOncology) ? (_userInfo.IsEn_Us ? "Overall Response" : "整体肿瘤评估") : t.QuestionName
|
||||||
}).ToList();
|
}).Distinct().ToList();
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (criterion.CriterionType == CriterionType.PCWG3)
|
else if (criterion.CriterionType == CriterionType.PCWG3)
|
||||||
@@ -2422,7 +2586,7 @@ namespace IRaCIS.Core.Application.Service.Common
|
|||||||
{
|
{
|
||||||
Id = Guid.Empty,
|
Id = Guid.Empty,
|
||||||
Name = t.QuestionName
|
Name = t.QuestionName
|
||||||
}).ToList();
|
}).Distinct().ToList();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2636,7 +2800,7 @@ namespace IRaCIS.Core.Application.Service.Common
|
|||||||
|
|
||||||
addLessionInfoList.Add(new CommonQuesionInfo() { QuestionId = Guid.Empty, QuestionName = _userInfo.IsEn_Us ? "Table Name" : "表格名称", QuestionValue = firstLessionAnser.TableName });
|
addLessionInfoList.Add(new CommonQuesionInfo() { QuestionId = Guid.Empty, QuestionName = _userInfo.IsEn_Us ? "Table Name" : "表格名称", QuestionValue = firstLessionAnser.TableName });
|
||||||
|
|
||||||
var dynamicPartialLessionInfoList = lession.LessionAnswerList.Select(t => new CommonQuesionInfo() { QuestionId=t.TableQuesionId, QuestionName = t.TableName + "_" + t.QuestionName, QuestionValue = t.QuestionValue, TranslateDicName = t.TranslateDicName, CDISCCode = t.CDISCCode });
|
var dynamicPartialLessionInfoList = lession.LessionAnswerList.Select(t => new CommonQuesionInfo() { QuestionId = t.TableQuesionId, QuestionName = t.TableName + "_" + t.QuestionName, QuestionValue = t.QuestionValue, TranslateDicName = t.TranslateDicName, CDISCCode = t.CDISCCode });
|
||||||
|
|
||||||
//有三部分组成 外层问题+ 固定列表格名称 + 动态的表格问题
|
//有三部分组成 外层问题+ 固定列表格名称 + 动态的表格问题
|
||||||
dynamicLessionInfoList = item.QuestionAnswerList.Union(addLessionInfoList).Union(dynamicPartialLessionInfoList).ToList();
|
dynamicLessionInfoList = item.QuestionAnswerList.Union(addLessionInfoList).Union(dynamicPartialLessionInfoList).ToList();
|
||||||
@@ -2678,7 +2842,7 @@ namespace IRaCIS.Core.Application.Service.Common
|
|||||||
{
|
{
|
||||||
AutoColumnTitleRowIndex = 2,
|
AutoColumnTitleRowIndex = 2,
|
||||||
AutoColumnStartIndex = 6,
|
AutoColumnStartIndex = 6,
|
||||||
TempalteLastColumnIndex = 8,
|
TempalteLastColumnIndex = 11,
|
||||||
DynamicItemDicName = "TranslateDicName",
|
DynamicItemDicName = "TranslateDicName",
|
||||||
DynamicItemValueName = "QuestionValue",
|
DynamicItemValueName = "QuestionValue",
|
||||||
DynamicItemTitleName = "QuestionName",
|
DynamicItemTitleName = "QuestionName",
|
||||||
@@ -2731,7 +2895,8 @@ namespace IRaCIS.Core.Application.Service.Common
|
|||||||
|
|
||||||
#region 最终导出参数处理
|
#region 最终导出参数处理
|
||||||
|
|
||||||
if (inQuery.ReadingExportType == ExportResult.DetailedTableOfAdjudicationResults)
|
//裁判阅片明细表
|
||||||
|
if (export_Template == StaticData.Export.CommonJudgeReadingDetail_Export)
|
||||||
{
|
{
|
||||||
//R1 R2 两个人的访视都阅片完成了才可以,去除只有一个人阅片完成的访视
|
//R1 R2 两个人的访视都阅片完成了才可以,去除只有一个人阅片完成的访视
|
||||||
//找到只有一个人阅片的受试者 和访视
|
//找到只有一个人阅片的受试者 和访视
|
||||||
@@ -2747,7 +2912,10 @@ namespace IRaCIS.Core.Application.Service.Common
|
|||||||
//处理裁判标记
|
//处理裁判标记
|
||||||
list = DealJudgeMark(criterion.ArbitrationRule, criterion.IsGlobalReading, list);
|
list = DealJudgeMark(criterion.ArbitrationRule, criterion.IsGlobalReading, list);
|
||||||
|
|
||||||
//裁判阅片明细表
|
//处理肿瘤学结果
|
||||||
|
list = DealOncologyResult(_oncologyRepository, criterion.IsOncologyReading, list);
|
||||||
|
|
||||||
|
//裁判阅片明细表 处理完标记后处理
|
||||||
if (export_Template == StaticData.Export.CommonJudgeReadingDetail_Export)
|
if (export_Template == StaticData.Export.CommonJudgeReadingDetail_Export)
|
||||||
{
|
{
|
||||||
//裁判产生标记为空的数据过滤掉
|
//裁判产生标记为空的数据过滤掉
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ namespace IRaCIS.Core.Application.Service
|
|||||||
#region DTO
|
#region DTO
|
||||||
public class DoctorDownloadInfo
|
public class DoctorDownloadInfo
|
||||||
{
|
{
|
||||||
public Guid Id { get; set; }
|
public Guid? Id { get; set; }
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
public string ReviewerCode { get; set; }
|
public string ReviewerCode { get; set; }
|
||||||
|
|
||||||
@@ -111,7 +111,7 @@ namespace IRaCIS.Core.Application.Service
|
|||||||
{
|
{
|
||||||
public int Language { get; set; }
|
public int Language { get; set; }
|
||||||
|
|
||||||
public List<Guid> DoctorIdList { get; set; }
|
public List<Guid?> DoctorIdList { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class GetDoctoreAttachPathCommand
|
public class GetDoctoreAttachPathCommand
|
||||||
|
|||||||
@@ -45,6 +45,11 @@ namespace IRaCIS.Core.Application.Service
|
|||||||
ValueCN = t.ValueCN,
|
ValueCN = t.ValueCN,
|
||||||
FrontType = t.FrontType,
|
FrontType = t.FrontType,
|
||||||
Description = t.Description,
|
Description = t.Description,
|
||||||
|
Module = t.Module,
|
||||||
|
State = t.State,
|
||||||
|
Version = t.PublishLog.Version,
|
||||||
|
CreateTime = t.CreateTime,
|
||||||
|
InternationalizationType = t.InternationalizationType
|
||||||
}).ToListAsync();
|
}).ToListAsync();
|
||||||
|
|
||||||
await _fusionCache.SetAsync<List<InternationalizationSimpleDto>>(CacheKeys.FrontInternational, list, TimeSpan.FromDays(1));
|
await _fusionCache.SetAsync<List<InternationalizationSimpleDto>>(CacheKeys.FrontInternational, list, TimeSpan.FromDays(1));
|
||||||
@@ -55,7 +60,7 @@ namespace IRaCIS.Core.Application.Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 前端批量提交,后端判断不存在就添加,存在就更新
|
/// 前端批量提交,后端查询判断不存在就添加,存在就更新 (这里提交接口也能提交后端的标识,对后端标识进行更新)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[AllowAnonymous]
|
[AllowAnonymous]
|
||||||
@@ -65,7 +70,7 @@ namespace IRaCIS.Core.Application.Service
|
|||||||
|
|
||||||
foreach (var item in batchList)
|
foreach (var item in batchList)
|
||||||
{
|
{
|
||||||
var find = await _internationalizationRepository.FirstOrDefaultAsync(t => t.Code == item.Code && t.Description == item.Description && t.InternationalizationType == 0);
|
var find = await _internationalizationRepository.FirstOrDefaultAsync(t => t.Code == item.Code && t.InternationalizationType == item.InternationalizationType);
|
||||||
|
|
||||||
if (find != null)
|
if (find != null)
|
||||||
{
|
{
|
||||||
@@ -77,7 +82,7 @@ namespace IRaCIS.Core.Application.Service
|
|||||||
var frontState = item.State == null ? 0 : (int)item.State;
|
var frontState = item.State == null ? 0 : (int)item.State;
|
||||||
|
|
||||||
var mapItem = _mapper.Map<Internationalization>(item);
|
var mapItem = _mapper.Map<Internationalization>(item);
|
||||||
mapItem.InternationalizationType = 0;
|
//mapItem.InternationalizationType = 0;
|
||||||
|
|
||||||
// 0 是预翻译 1是已确认 2是后端废弃
|
// 0 是预翻译 1是已确认 2是后端废弃
|
||||||
mapItem.State = frontState;
|
mapItem.State = frontState;
|
||||||
@@ -138,6 +143,7 @@ namespace IRaCIS.Core.Application.Service
|
|||||||
|
|
||||||
mapItem.InternationalizationType = batchAdd.InternationalizationType;
|
mapItem.InternationalizationType = batchAdd.InternationalizationType;
|
||||||
mapItem.State = batchAdd.State;
|
mapItem.State = batchAdd.State;
|
||||||
|
mapItem.PublishLogId = batchAdd.PublishLogId;
|
||||||
|
|
||||||
var verifyExp1 = new EntityVerifyExp<Internationalization>()
|
var verifyExp1 = new EntityVerifyExp<Internationalization>()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -583,6 +583,8 @@ namespace IRaCIS.Core.Application.Service
|
|||||||
saveItem.IsTestUser = true;
|
saveItem.IsTestUser = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
saveItem.UserCeateSource = UserCeateSource.ReviewerSelect;
|
||||||
|
saveItem.TrialId = trialId;
|
||||||
|
|
||||||
saveItem.Code = _identityUserRepository.Select(t => t.Code).DefaultIfEmpty().Max() + 1;
|
saveItem.Code = _identityUserRepository.Select(t => t.Code).DefaultIfEmpty().Max() + 1;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
using IRaCIS.Application.Contracts;
|
using IRaCIS.Application.Contracts;
|
||||||
using IRaCIS.Application.Interfaces;
|
using IRaCIS.Application.Interfaces;
|
||||||
|
using IRaCIS.Core.Application.Helper;
|
||||||
|
using IRaCIS.Core.Application.ViewModel;
|
||||||
|
using IRaCIS.Core.Infrastructure.Extention;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Panda.DynamicWebApi.Attributes;
|
using Panda.DynamicWebApi.Attributes;
|
||||||
|
|
||||||
@@ -9,7 +12,11 @@ namespace IRaCIS.Core.Application.Service
|
|||||||
/// 医生文档关联关系维护
|
/// 医生文档关联关系维护
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[ApiExplorerSettings(GroupName = "Reviewer")]
|
[ApiExplorerSettings(GroupName = "Reviewer")]
|
||||||
public class AttachmentService(IRepository<Attachment> _attachmentrepository, IRepository<Doctor> _doctorrepository, IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer) : BaseService, IAttachmentService
|
public class AttachmentService(IRepository<Attachment> _attachmentrepository,
|
||||||
|
IRepository<Dictionary> _dictionaryRepository,
|
||||||
|
IRepository<Enroll> _enrollRepository,
|
||||||
|
IOSSService _oSSService,
|
||||||
|
IRepository<Doctor> _doctorrepository, IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer) : BaseService, IAttachmentService
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
@@ -89,6 +96,150 @@ namespace IRaCIS.Core.Application.Service
|
|||||||
return attachmentList;
|
return attachmentList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取项目医生附件
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="inDto"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<PageOutput<AttachmentDTO>> GetTrialAttachments(GetTrialAttachmentsInDto inDto)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var dicList=await _dictionaryRepository.Where(x => x.Parent.Code == "CertificateFileType").Select(x=>x.Code).ToListAsync();
|
||||||
|
|
||||||
|
var attachmentList = await _attachmentrepository
|
||||||
|
.Where(a =>a.Doctor.EnrollList.Any(x=>x.TrialId == inDto.TrialId && x.EnrollStatus >= EnrollStatus.InviteIntoGroup)|| a.TrialId == inDto.TrialId)
|
||||||
|
.WhereIf(inDto.DoctorId!=null,x=>x.DoctorId==inDto.DoctorId)
|
||||||
|
.WhereIf(inDto.IsAuthorizedView != null, x => x.IsAuthorizedView == inDto.IsAuthorizedView)
|
||||||
|
.WhereIf(inDto.Type.IsNotNullOrEmpty(), x => x.Type == inDto.Type)
|
||||||
|
.WhereIf(inDto.FileName.IsNotNullOrEmpty(), x => inDto.FileName.Contains(x.FileName))
|
||||||
|
|
||||||
|
.Where(a => dicList.Contains(a.Type)||a.Type==string.Empty)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.ProjectTo<AttachmentDTO>(_mapper.ConfigurationProvider, new { TrialId = inDto.TrialId }).ToPagedListAsync(inDto);
|
||||||
|
|
||||||
|
|
||||||
|
return attachmentList;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取医生列表
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="inDto"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<List<GetTrialDoctorListOutDto>> GetTrialDoctorList(GetTrialDoctorSelectInDto inDto)
|
||||||
|
{
|
||||||
|
var result= await _enrollRepository.Where(x => x.TrialId == inDto.TrialId && x.EnrollStatus >= EnrollStatus.InviteIntoGroup).Select(x => x.Doctor)
|
||||||
|
|
||||||
|
.ProjectTo<GetTrialDoctorListOutDto>(_mapper.ConfigurationProvider).OrderBy(x=>x.BlindName).ToListAsync();
|
||||||
|
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 修改稽查状态
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="inDto"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<IResponseOutput> SetAuthorizedView(SetAttachmentAuthorizedView inDto)
|
||||||
|
{
|
||||||
|
await _attachmentrepository.UpdatePartialFromQueryAsync(x => inDto.Ids.Contains(x.Id), x => new Attachment() { IsAuthorizedView = inDto.IsAuthorizedView });
|
||||||
|
|
||||||
|
await _attachmentrepository.SaveChangesAsync();
|
||||||
|
return ResponseOutput.Ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 删除
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="id"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<IResponseOutput> DeleteAttachment(DeleteAttachment inDto)
|
||||||
|
{
|
||||||
|
var success = await _attachmentrepository.DeleteFromQueryAsync(t => inDto.Ids.Contains(t.Id));
|
||||||
|
await _attachmentrepository.SaveChangesAsync();
|
||||||
|
return ResponseOutput.Ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 上传项目医生
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="attachmentList"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<IEnumerable<AttachmentDTO>> SaveTrialAttachments(IEnumerable<AttachmentDTO> attachmentList)
|
||||||
|
{
|
||||||
|
|
||||||
|
foreach (var item in attachmentList)
|
||||||
|
{
|
||||||
|
if (item.DoctorId != null)
|
||||||
|
{
|
||||||
|
await _attachmentrepository.BatchDeleteNoTrackingAsync(a => a.DoctorId == item.DoctorId && a.Type == item.Type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var attachments = _mapper.Map<IEnumerable<Attachment>>(attachmentList).ToList();
|
||||||
|
var newAttachment = attachments.Where(t => t.Id == Guid.Empty);
|
||||||
|
await _attachmentrepository.AddRangeAsync(newAttachment);
|
||||||
|
await _attachmentrepository.SaveChangesAsync();
|
||||||
|
|
||||||
|
var list = _mapper.Map<IEnumerable<AttachmentDTO>>(attachments).ToList();
|
||||||
|
|
||||||
|
list.ForEach(t => t.FullPath = t.Path + "?access_token=" + _userInfo.UserToken);
|
||||||
|
|
||||||
|
return list;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 更新医生资质
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="attachment"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<IResponseOutput> UpdateTrialAttachments(AttachmentDTO attachment)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (!attachment.Path.Contains(attachment.DoctorId.ToString()))
|
||||||
|
{
|
||||||
|
var attachmentData= await _attachmentrepository.Where(a => a.Id == attachment.Id).FirstNotNullAsync();
|
||||||
|
|
||||||
|
var fileName= attachmentData.Path.Split("/").Last();
|
||||||
|
|
||||||
|
|
||||||
|
attachment.Path = $"/systemData/reviewe/{attachment.Type}/{attachment.DoctorId}/{fileName}";
|
||||||
|
|
||||||
|
await _oSSService.MoveObject(attachmentData.Path, attachment.Path);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (attachment.DoctorId != null)
|
||||||
|
{
|
||||||
|
await _attachmentrepository.DeleteFromQueryAsync(a =>a.Id!=attachment.Id&& a.DoctorId == attachment.DoctorId && a.Type == attachment.Type);
|
||||||
|
}
|
||||||
|
|
||||||
|
attachment.UpdateTime = DateTime.Now;
|
||||||
|
await _attachmentrepository.UpdateFromDTOAsync(attachment);
|
||||||
|
|
||||||
|
await _attachmentrepository.SaveChangesAsync();
|
||||||
|
return ResponseOutput.Ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[NonDynamicMethod]
|
[NonDynamicMethod]
|
||||||
public async Task<AttachmentDTO> GetDetailById(Guid attachmentId)
|
public async Task<AttachmentDTO> GetDetailById(Guid attachmentId)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2,19 +2,80 @@
|
|||||||
{
|
{
|
||||||
public class AttachmentDTO
|
public class AttachmentDTO
|
||||||
{
|
{
|
||||||
public Guid Id { get; set; }
|
public Guid? Id { get; set; }
|
||||||
public Guid DoctorId { get; set; }
|
public Guid? DoctorId { get; set; }
|
||||||
public bool IsOfficial { get; set; }
|
public bool IsOfficial { get; set; }
|
||||||
public string Type { get; set; } = string.Empty;
|
public string Type { get; set; } = string.Empty;
|
||||||
public string Path { get; set; } = string.Empty;
|
public string Path { get; set; } = string.Empty;
|
||||||
public string FullPath { get; set; } = string.Empty;
|
public string FullPath { get; set; } = string.Empty;
|
||||||
public string FileName { get; set; } = string.Empty;
|
public string FileName { get; set; } = string.Empty;
|
||||||
public DateTime? CreateTime { get; set; }
|
public DateTime? CreateTime { get; set; }
|
||||||
|
|
||||||
|
public DateTime? UpdateTime { get; set; }
|
||||||
public int Language { get; set; }
|
public int Language { get; set; }
|
||||||
|
|
||||||
public bool ReUpload { get; set; } = false;
|
public bool ReUpload { get; set; } = false;
|
||||||
|
|
||||||
|
public Guid? TrialId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否授权
|
||||||
|
/// </summary>
|
||||||
|
|
||||||
|
public bool IsAuthorizedView { get; set; } = false;
|
||||||
|
|
||||||
|
public string BlindName { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public string BlindNameCN { get; set; } = string.Empty;
|
||||||
|
public string ChineseName { get; set; } = string.Empty;
|
||||||
|
public string FirstName { get; set; } = string.Empty;
|
||||||
|
public string FullName => LastName + " / " + FirstName;
|
||||||
|
public string LastName { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public string UserName { get; set; } = string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class SetAttachmentAuthorizedView
|
||||||
|
{
|
||||||
|
public List<Guid> Ids { get; set; }
|
||||||
|
|
||||||
|
public bool IsAuthorizedView { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class DeleteAttachment
|
||||||
|
{
|
||||||
|
public List<Guid> Ids { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class GetTrialDoctorSelectInDto
|
||||||
|
{
|
||||||
|
public Guid TrialId { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class GetTrialDoctorListOutDto
|
||||||
|
{
|
||||||
|
public Guid Id { get; set; }
|
||||||
|
public string BlindName { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public string BlindNameCN { get; set; } = string.Empty;
|
||||||
|
public string ChineseName { get; set; } = string.Empty;
|
||||||
|
public string FirstName { get; set; } = string.Empty;
|
||||||
|
public string FullName => LastName + " / " + FirstName;
|
||||||
|
public string LastName { get; set; } = string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class GetTrialAttachmentsInDto:PageInput
|
||||||
|
{
|
||||||
|
public Guid TrialId { get; set; }
|
||||||
|
|
||||||
|
public string? Type { get; set; }
|
||||||
|
|
||||||
|
public Guid? DoctorId { get; set; }
|
||||||
|
|
||||||
|
public string? FileName { get; set; }
|
||||||
|
|
||||||
|
public bool? IsAuthorizedView { get; set; }
|
||||||
|
}
|
||||||
public class ReviewerAckDTO
|
public class ReviewerAckDTO
|
||||||
{
|
{
|
||||||
public Guid Id { get; set; }
|
public Guid Id { get; set; }
|
||||||
|
|||||||
@@ -169,6 +169,16 @@ namespace IRaCIS.Application.Contracts
|
|||||||
public class ReviewerConfirmationQueryDTO : PageInput
|
public class ReviewerConfirmationQueryDTO : PageInput
|
||||||
{
|
{
|
||||||
public Guid TrialId { get; set; } = Guid.Empty;
|
public Guid TrialId { get; set; } = Guid.Empty;
|
||||||
|
|
||||||
|
public DateTime? OptStartTime{ get; set; }
|
||||||
|
|
||||||
|
public DateTime? OptEndTime { get; set; }
|
||||||
|
|
||||||
|
public string? Code { get; set; }
|
||||||
|
|
||||||
|
public UserTypeEnum? UserTypeEnum { get; set; }
|
||||||
|
|
||||||
|
public string? OptUserName { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class SelectionReviewerDTO : DoctorDTO
|
public class SelectionReviewerDTO : DoctorDTO
|
||||||
@@ -194,14 +204,48 @@ namespace IRaCIS.Application.Contracts
|
|||||||
|
|
||||||
public string City { get; set; } = string.Empty;
|
public string City { get; set; } = string.Empty;
|
||||||
public string HospitalName { get; set; } = string.Empty;
|
public string HospitalName { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public string HospitalNameCN { get; set; } = string.Empty;
|
||||||
public string Country { get; set; } = string.Empty;
|
public string Country { get; set; } = string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public class GetTrialDoctorListInDto : PageInput
|
||||||
|
{
|
||||||
|
public Guid TrialId { get; set; } = Guid.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 亚专业
|
||||||
|
/// </summary>
|
||||||
|
public Guid? SubspecialityId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 专业
|
||||||
|
/// </summary>
|
||||||
|
public Guid? SpecialityId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 机构
|
||||||
|
/// </summary>
|
||||||
|
public Guid? HospitalId { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TrialDoctorInfo : ConfirmationReviewerDTO
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public List<string> SubspecialityList => DictionaryList.Where(t => t.ParentCode == StaticData.Subspeciality).OrderBy(t => t.ShowOrder).Select(t => t.Value).ToList();
|
||||||
|
|
||||||
|
public List<string> SubspecialityCNList => DictionaryList.Where(t => t.ParentCode == StaticData.Subspeciality).OrderBy(t => t.ShowOrder).Select(t => t.ValueCN).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
public class ConfirmationReviewerDTO : DoctorOptDTO
|
public class ConfirmationReviewerDTO : DoctorOptDTO
|
||||||
{
|
{
|
||||||
public int DoctorTrialState { get; set; }
|
public int DoctorTrialState { get; set; }
|
||||||
public string OptUserName { get; set; } = string.Empty;
|
public string OptUserName { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public UserTypeEnum? UserTypeEnum { get; set; }
|
||||||
public DateTime? OptTime { get; set; }
|
public DateTime? OptTime { get; set; }
|
||||||
public string? OptTimeStr => OptTime?.ToString("yyyy-MM-dd HH:mm:ss");
|
public string? OptTimeStr => OptTime?.ToString("yyyy-MM-dd HH:mm:ss");
|
||||||
|
|
||||||
@@ -223,6 +267,8 @@ namespace IRaCIS.Application.Contracts
|
|||||||
public List<Guid> SubspecialityIds => DictionaryList.Where(t => t.ParentCode == StaticData.Subspeciality).OrderBy(t => t.ShowOrder).Select(t => t.Id).ToList();
|
public List<Guid> SubspecialityIds => DictionaryList.Where(t => t.ParentCode == StaticData.Subspeciality).OrderBy(t => t.ShowOrder).Select(t => t.Id).ToList();
|
||||||
|
|
||||||
public Guid? HospitalId { get; set; }
|
public Guid? HospitalId { get; set; }
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -235,6 +281,10 @@ namespace IRaCIS.Application.Contracts
|
|||||||
public string OptUserName { get; set; } = String.Empty;
|
public string OptUserName { get; set; } = String.Empty;
|
||||||
public DateTime? OptTime { get; set; }
|
public DateTime? OptTime { get; set; }
|
||||||
|
|
||||||
|
public int OptUserType { get; set; }
|
||||||
|
|
||||||
|
public UserTypeEnum UserTypeEnum { get; set; }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@@ -523,6 +573,8 @@ namespace IRaCIS.Application.Contracts
|
|||||||
{
|
{
|
||||||
public string BlindName { get; set; }
|
public string BlindName { get; set; }
|
||||||
|
|
||||||
|
public bool IsHaveAccount { get; set; } = false;
|
||||||
|
|
||||||
public string BlindNameCN { get; set; } = string.Empty;
|
public string BlindNameCN { get; set; } = string.Empty;
|
||||||
|
|
||||||
public List<DicView> DoctorDicViewDtos = new List<DicView>();
|
public List<DicView> DoctorDicViewDtos = new List<DicView>();
|
||||||
|
|||||||
@@ -243,11 +243,137 @@ namespace IRaCIS.Core.Application.Service
|
|||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
|
#region 连表查询
|
||||||
|
//var query = from enroll in _enrollRepository.Where(x => x.TrialId == inQuery.TrialId && x.EnrollStatus >= EnrollStatus.InviteIntoGroup)
|
||||||
|
// join enrollDetail in _enrollDetailRepository.Where(x => x.TrialId == inQuery.TrialId && x.EnrollStatus >= EnrollStatus.InviteIntoGroup) on new { enroll.DoctorId, enroll.EnrollStatus } equals new { enrollDetail.DoctorId, enrollDetail.EnrollStatus } into enrollDetailtemp
|
||||||
|
// from leftenrollDetail in enrollDetailtemp.DefaultIfEmpty()
|
||||||
|
// select new ConfirmationReviewerDTO()
|
||||||
|
// {
|
||||||
|
// DoctorTrialState = (int)leftenrollDetail.EnrollStatus,
|
||||||
|
// OptTime = leftenrollDetail.CreateTime,
|
||||||
|
// UserTypeEnum = leftenrollDetail.CreateUserRole.UserTypeEnum,
|
||||||
|
// OptUserName = leftenrollDetail.CreateUserRole.UserName,
|
||||||
|
// SubmmitTime = leftenrollDetail.CreateTime,
|
||||||
|
// SubmmitUserName = leftenrollDetail.CreateUserRole.UserName,
|
||||||
|
// //BlindName= enroll.BlindName,
|
||||||
|
// //BlindNameCN= enroll.BlindNameCN,
|
||||||
|
// SpecialityId = enroll.Doctor.SpecialityId,
|
||||||
|
// SpecialityCN = enroll.Doctor.Speciality.ValueCN,
|
||||||
|
// Speciality = enroll.Doctor.Speciality.Value,
|
||||||
|
// //SpecialityOther=enroll.Doctor.Speciality.SpecialityOther,
|
||||||
|
// //SpecialityOtherCN= enroll.Doctor.Speciality.SpecialityOtherCN,
|
||||||
|
// DictionaryList = enroll.Doctor.DoctorDicRelationList.Where(t => t.KeyName == StaticData.ReadingType || t.KeyName == StaticData.Subspeciality).Select(t => t.Dictionary).OrderBy(t => t.ShowOrder).Select(x => new DicView()
|
||||||
|
// {
|
||||||
|
// Id = x.Id,
|
||||||
|
// ParentCode = x.Parent.Code,
|
||||||
|
// ShowOrder = x.ShowOrder,
|
||||||
|
// Value = x.Value,
|
||||||
|
// ValueCN = x.ValueCN
|
||||||
|
// }).ToList(),
|
||||||
|
|
||||||
|
// //HospitalId= enroll.BlindName
|
||||||
|
|
||||||
|
// Id = enroll.Doctor.Id,
|
||||||
|
// Code = enroll.DoctorUser.UserName,
|
||||||
|
// //FirstName=enroll.FirstName,
|
||||||
|
// //LastName = enroll.LastName,
|
||||||
|
// //ChineseName = enroll.ChineseName,
|
||||||
|
// //City = enroll.City,
|
||||||
|
// //HospitalName = enroll.HospitalName,
|
||||||
|
// //Country = enroll.Country,
|
||||||
|
// };
|
||||||
|
|
||||||
|
|
||||||
|
//var result = await query
|
||||||
|
// .WhereIf(inQuery.OptStartTime != null, x => x.OptTime >= inQuery.OptStartTime)
|
||||||
|
// .WhereIf(inQuery.OptEndTime != null, x => x.OptTime <= inQuery.OptEndTime)
|
||||||
|
// .WhereIf(inQuery.UserTypeEnum != null, x => x.UserTypeEnum == inQuery.UserTypeEnum)
|
||||||
|
// .WhereIf(inQuery.Code.IsNotNullOrEmpty(), x => x.Code.Contains(inQuery.Code))
|
||||||
|
|
||||||
|
// .WhereIf(inQuery.OptUserName.IsNotNullOrEmpty(), x => x.OptUserName.Contains(inQuery.OptUserName))
|
||||||
|
// .ToPagedListAsync(inQuery);
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region 查询第一个
|
||||||
|
|
||||||
|
// 这里这样写的原因是因为 要取最新的入组详情 然后还要根据时间筛选 入组信息
|
||||||
|
var query = _enrollDetailRepository
|
||||||
|
.Where(x => x.TrialId == inQuery.TrialId && x.EnrollStatus >= EnrollStatus.InviteIntoGroup);
|
||||||
|
var enrollStateList = await query
|
||||||
|
.ProjectTo<DoctorStateModelDTO>(_mapper.ConfigurationProvider).ToListAsync();
|
||||||
|
enrollStateList = enrollStateList.GroupBy(e => e.DoctorId)
|
||||||
|
.Select(g => g.OrderByDescending(e => e.OptTime).FirstOrDefault()).ToList();
|
||||||
|
|
||||||
|
enrollStateList = enrollStateList
|
||||||
|
.WhereIf(inQuery.OptStartTime != null, x => x.OptTime >= inQuery.OptStartTime)
|
||||||
|
.WhereIf(inQuery.OptEndTime != null, x => x.OptTime <= inQuery.OptEndTime)
|
||||||
|
.WhereIf(inQuery.UserTypeEnum != null, x => x.UserTypeEnum == inQuery.UserTypeEnum)
|
||||||
|
.ToList();
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var doctorids = enrollStateList.Select(x => x.DoctorId).ToList();
|
||||||
|
|
||||||
|
|
||||||
var doctorQuery = _enrollRepository.Where(x => x.TrialId == inQuery.TrialId && x.EnrollStatus >= EnrollStatus.InviteIntoGroup)
|
var doctorQuery = _enrollRepository.Where(x => x.TrialId == inQuery.TrialId && x.EnrollStatus >= EnrollStatus.InviteIntoGroup)
|
||||||
.ProjectTo<ConfirmationReviewerDTO>(_mapper.ConfigurationProvider);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.WhereIf(inQuery.OptStartTime != null || inQuery.OptEndTime != null || inQuery.UserTypeEnum != null, x => doctorids.Contains(x.DoctorId))
|
||||||
|
.ProjectTo<ConfirmationReviewerDTO>(_mapper.ConfigurationProvider)
|
||||||
|
.WhereIf(inQuery.Code.IsNotNullOrEmpty(), x => x.Code.Contains(inQuery.Code))
|
||||||
|
|
||||||
|
.WhereIf(inQuery.OptUserName.IsNotNullOrEmpty(), x => x.OptUserName.Contains(inQuery.OptUserName));
|
||||||
|
|
||||||
var doctorPageList = await doctorQuery.ToPagedListAsync(inQuery);
|
var doctorPageList = await doctorQuery.ToPagedListAsync(inQuery);
|
||||||
|
|
||||||
|
|
||||||
|
doctorPageList.CurrentPageData.ToList().ForEach(u =>
|
||||||
|
{
|
||||||
|
u.DoctorTrialState = (int)EnrollStatus.InviteIntoGroup;
|
||||||
|
var opt = enrollStateList.OrderByDescending(x=>x.OptTime).FirstOrDefault(t => t.DoctorId == u.Id);
|
||||||
|
if (opt != null)
|
||||||
|
{
|
||||||
|
u.DoctorTrialState = opt.IntoGroupState;
|
||||||
|
u.OptTime = opt.OptTime;
|
||||||
|
u.UserTypeEnum = opt.UserTypeEnum;
|
||||||
|
u.OptUserName = opt.OptUserName;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return doctorPageList;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取项目下医生列表
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="inQuery"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<PageOutput<TrialDoctorInfo>> GetTrialDoctorList(
|
||||||
|
GetTrialDoctorListInDto inQuery)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
var doctorQuery = _enrollRepository.Where(x => x.TrialId == inQuery.TrialId && x.EnrollStatus == EnrollStatus.ConfirmIntoGroup)
|
||||||
|
|
||||||
|
.ProjectTo<TrialDoctorInfo>(_mapper.ConfigurationProvider);
|
||||||
|
|
||||||
|
var doctorPageList = await doctorQuery
|
||||||
|
.WhereIf(inQuery.HospitalId!=null,x=>x.HospitalId==inQuery.HospitalId.Value)
|
||||||
|
.WhereIf(inQuery.SpecialityId != null, x => x.SpecialityId == inQuery.SpecialityId.Value)
|
||||||
|
.WhereIf(inQuery.SubspecialityId != null, x => x.DictionaryList.Any(x=>x.Id==inQuery.SubspecialityId.Value))
|
||||||
|
.ToPagedListAsync(inQuery);
|
||||||
|
|
||||||
var enrollStateList = await _enrollDetailRepository.Where(x => x.TrialId == inQuery.TrialId && x.EnrollStatus > EnrollStatus.InviteIntoGroup)
|
var enrollStateList = await _enrollDetailRepository.Where(x => x.TrialId == inQuery.TrialId && x.EnrollStatus > EnrollStatus.InviteIntoGroup)
|
||||||
.ProjectTo<DoctorStateModelDTO>(_mapper.ConfigurationProvider).ToListAsync();
|
.ProjectTo<DoctorStateModelDTO>(_mapper.ConfigurationProvider).ToListAsync();
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using DocumentFormat.OpenXml.Office2019.Excel.ThreadedComments;
|
using DocumentFormat.OpenXml.Office2019.Excel.ThreadedComments;
|
||||||
|
using DocumentFormat.OpenXml.Spreadsheet;
|
||||||
using IRaCIS.Application.Contracts;
|
using IRaCIS.Application.Contracts;
|
||||||
using IRaCIS.Application.Interfaces;
|
using IRaCIS.Application.Interfaces;
|
||||||
using IRaCIS.Core.Application.Helper;
|
using IRaCIS.Core.Application.Helper;
|
||||||
@@ -17,6 +18,7 @@ namespace IRaCIS.Core.Application.Service
|
|||||||
IRepository<DoctorDictionary> _doctorDictionaryRepository,
|
IRepository<DoctorDictionary> _doctorDictionaryRepository,
|
||||||
IRepository<DoctorSummarize> _doctorSummarizeRepository,
|
IRepository<DoctorSummarize> _doctorSummarizeRepository,
|
||||||
IRepository<Enroll> _enrollRepository,
|
IRepository<Enroll> _enrollRepository,
|
||||||
|
IRepository<UserRole> _userRoleRepository,
|
||||||
IRepository<Hospital> _hospitalRepository,
|
IRepository<Hospital> _hospitalRepository,
|
||||||
IRepository<Dictionary> _dictionaryRepository,
|
IRepository<Dictionary> _dictionaryRepository,
|
||||||
IRepository<Attachment> _attachmentRepository,
|
IRepository<Attachment> _attachmentRepository,
|
||||||
@@ -230,9 +232,9 @@ namespace IRaCIS.Core.Application.Service
|
|||||||
/// <param name="inDto"></param>
|
/// <param name="inDto"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
public async Task<(DoctorSummarize,bool)> AddOrUpdateGneralSituation(SummarizeInfoDto inDto)
|
public async Task<(DoctorSummarize, bool)> AddOrUpdateGneralSituation(SummarizeInfoDto inDto)
|
||||||
{
|
{
|
||||||
if (inDto.TrialId != null&&inDto.Id==null)
|
if (inDto.TrialId != null && inDto.Id == null)
|
||||||
{
|
{
|
||||||
var systemCount = await _doctorSummarizeRepository.Where(x => x.DoctorId == inDto.DoctorId && x.TrialId == null).CountAsync();
|
var systemCount = await _doctorSummarizeRepository.Where(x => x.DoctorId == inDto.DoctorId && x.TrialId == null).CountAsync();
|
||||||
if (systemCount == 0)
|
if (systemCount == 0)
|
||||||
@@ -241,7 +243,7 @@ namespace IRaCIS.Core.Application.Service
|
|||||||
var dictionery = await _dictionaryRepository.Where(x => x.Parent.Code == "Indication" && x.Code == trialinfo.IndicationEnum.ToString()).FirstNotNullAsync();
|
var dictionery = await _dictionaryRepository.Where(x => x.Parent.Code == "Indication" && x.Code == trialinfo.IndicationEnum.ToString()).FirstNotNullAsync();
|
||||||
inDto.IndicationEn = dictionery.Value;
|
inDto.IndicationEn = dictionery.Value;
|
||||||
inDto.Indication = dictionery.ValueCN;
|
inDto.Indication = dictionery.ValueCN;
|
||||||
var system= inDto.Clone();
|
var system = inDto.Clone();
|
||||||
system.TrialId = null;
|
system.TrialId = null;
|
||||||
system.IsMain = true;
|
system.IsMain = true;
|
||||||
await _doctorSummarizeRepository.InsertOrUpdateAsync(system, true);
|
await _doctorSummarizeRepository.InsertOrUpdateAsync(system, true);
|
||||||
@@ -254,7 +256,7 @@ namespace IRaCIS.Core.Application.Service
|
|||||||
if (systemCount == 0)
|
if (systemCount == 0)
|
||||||
{
|
{
|
||||||
inDto.IsMain = true;
|
inDto.IsMain = true;
|
||||||
|
|
||||||
}
|
}
|
||||||
if (inDto.Indication.IsNullOrEmpty() && inDto.IndicationEn.IsNullOrEmpty())
|
if (inDto.Indication.IsNullOrEmpty() && inDto.IndicationEn.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
@@ -262,19 +264,19 @@ namespace IRaCIS.Core.Application.Service
|
|||||||
inDto.IndicationEn = "Default";
|
inDto.IndicationEn = "Default";
|
||||||
}
|
}
|
||||||
var exists = await _doctorSummarizeRepository
|
var exists = await _doctorSummarizeRepository
|
||||||
.Where(x=> x.IndicationEn!=string.Empty && x.Indication!=string.Empty)
|
.Where(x => x.IndicationEn != string.Empty && x.Indication != string.Empty)
|
||||||
.Where( x => x.IndicationEn == inDto.IndicationEn|| x.Indication == inDto.Indication)
|
.Where(x => x.IndicationEn == inDto.IndicationEn || x.Indication == inDto.Indication)
|
||||||
|
|
||||||
.AnyAsync(x => x.DoctorId == inDto.DoctorId && x.TrialId == null&&x.Id!=inDto.Id);
|
.AnyAsync(x => x.DoctorId == inDto.DoctorId && x.TrialId == null && x.Id != inDto.Id);
|
||||||
if (exists)
|
if (exists)
|
||||||
{
|
{
|
||||||
throw new BusinessValidationFailedException(_localizer["DoctorSummarize_repeat"]);
|
throw new BusinessValidationFailedException(_localizer["DoctorSummarize_repeat"]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (inDto.TrialId != null && inDto.SaveSummarizeInfoType!= SaveSummarizeInfo.SaveSelf)
|
|
||||||
|
if (inDto.TrialId != null && inDto.SaveSummarizeInfoType != SaveSummarizeInfo.SaveSelf)
|
||||||
{
|
{
|
||||||
switch (inDto.SaveSummarizeInfoType)
|
switch (inDto.SaveSummarizeInfoType)
|
||||||
{
|
{
|
||||||
@@ -312,16 +314,16 @@ namespace IRaCIS.Core.Application.Service
|
|||||||
if (inDto.TrialId == null && inDto.IsMain)
|
if (inDto.TrialId == null && inDto.IsMain)
|
||||||
{
|
{
|
||||||
|
|
||||||
await _doctorSummarizeRepository.BatchUpdateNoTrackingAsync(x => x.DoctorId == inDto.DoctorId && x.TrialId == null,
|
await _doctorSummarizeRepository.BatchUpdateNoTrackingAsync(x => x.DoctorId == inDto.DoctorId && x.TrialId == null,
|
||||||
x => new DoctorSummarize()
|
x => new DoctorSummarize()
|
||||||
{
|
{
|
||||||
IsMain = false
|
IsMain = false
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
var entity = await _doctorSummarizeRepository.InsertOrUpdateAsync(inDto, true);
|
var entity = await _doctorSummarizeRepository.InsertOrUpdateAsync(inDto, true);
|
||||||
return (entity,true);
|
return (entity, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -332,7 +334,7 @@ namespace IRaCIS.Core.Application.Service
|
|||||||
[HttpPost]
|
[HttpPost]
|
||||||
public async Task<bool> DeleteSummarizeInfo(DeleteSummarizeInfoInDto inDto)
|
public async Task<bool> DeleteSummarizeInfo(DeleteSummarizeInfoInDto inDto)
|
||||||
{
|
{
|
||||||
var result = await _doctorSummarizeRepository.DeleteFromQueryAsync(x=>x.Id==inDto.Id);
|
var result = await _doctorSummarizeRepository.DeleteFromQueryAsync(x => x.Id == inDto.Id);
|
||||||
return await _doctorSummarizeRepository.SaveChangesAsync();
|
return await _doctorSummarizeRepository.SaveChangesAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -344,7 +346,7 @@ namespace IRaCIS.Core.Application.Service
|
|||||||
[HttpPost]
|
[HttpPost]
|
||||||
public async Task<UpdateGneralSituationDto> GetSummarizeInfo(GetSummarizeInfoInDto inDto)
|
public async Task<UpdateGneralSituationDto> GetSummarizeInfo(GetSummarizeInfoInDto inDto)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (inDto.TrialId != null)
|
if (inDto.TrialId != null)
|
||||||
{
|
{
|
||||||
var doctorInfo = await trialExperienceService.GetTrialDoctorInfo(new GetTrialDoctorInfoInDto()
|
var doctorInfo = await trialExperienceService.GetTrialDoctorInfo(new GetTrialDoctorInfoInDto()
|
||||||
@@ -356,8 +358,9 @@ namespace IRaCIS.Core.Application.Service
|
|||||||
}
|
}
|
||||||
var result = await _doctorSummarizeRepository.Where(t => t.DoctorId == inDto.DoctorId && t.TrialId == inDto.TrialId)
|
var result = await _doctorSummarizeRepository.Where(t => t.DoctorId == inDto.DoctorId && t.TrialId == inDto.TrialId)
|
||||||
.ProjectTo<SummarizeInfoDto>(_mapper.ConfigurationProvider).ToListAsync();
|
.ProjectTo<SummarizeInfoDto>(_mapper.ConfigurationProvider).ToListAsync();
|
||||||
return new UpdateGneralSituationDto() {
|
return new UpdateGneralSituationDto()
|
||||||
SummarizeList= result
|
{
|
||||||
|
SummarizeList = result
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -377,30 +380,36 @@ namespace IRaCIS.Core.Application.Service
|
|||||||
messageToSend.To.Add(new MailboxAddress(String.Empty, item));
|
messageToSend.To.Add(new MailboxAddress(String.Empty, item));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
|
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
|
||||||
{
|
{
|
||||||
;
|
;
|
||||||
var topicStr = string.Format(input.topicStr,string.Empty);
|
var topicStr = string.Format(input.topicStr, string.Empty);
|
||||||
var htmlBodyStr = string.Format(
|
var htmlBodyStr = string.Format(
|
||||||
|
|
||||||
|
|
||||||
CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr),
|
CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr),
|
||||||
_systemEmailConfig.SiteUrl.Replace("login",string.Empty)+inDto.Url
|
_systemEmailConfig.SiteUrl.Replace("login", string.Empty) + inDto.Url
|
||||||
);
|
);
|
||||||
|
|
||||||
return (topicStr, htmlBodyStr);
|
return (topicStr, htmlBodyStr);
|
||||||
};
|
};
|
||||||
|
|
||||||
await CommonEmailHelper.GetEmailSubejctAndHtmlInfoAndBuildAsync(_emailNoticeConfigrepository,
|
|
||||||
|
|
||||||
EmailBusinessScenario.Reviewer_CV_Collection,
|
var scenario = EmailBusinessScenario.Reviewer_CV_Collection;
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
messageToSend, emailConfigFunc);
|
|
||||||
|
|
||||||
await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -490,7 +499,7 @@ namespace IRaCIS.Core.Application.Service
|
|||||||
|
|
||||||
var doctorBasicInfo = (await _doctorRepository.Where(t => t.Id == doctorId)
|
var doctorBasicInfo = (await _doctorRepository.Where(t => t.Id == doctorId)
|
||||||
.ProjectTo<DoctorBasicInfoDTO>(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException();
|
.ProjectTo<DoctorBasicInfoDTO>(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException();
|
||||||
|
doctorBasicInfo.IsHaveAccount = await _userRoleRepository.AnyAsync(x => x.DoctorId == doctorId);
|
||||||
return doctorBasicInfo;
|
return doctorBasicInfo;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ namespace IRaCIS.Core.Application.Service
|
|||||||
{
|
{
|
||||||
var isEn_Us = false;
|
var isEn_Us = false;
|
||||||
|
|
||||||
|
Guid TrialId = Guid.Empty;
|
||||||
|
|
||||||
// 从 DateTime 映射到 DateOnly
|
// 从 DateTime 映射到 DateOnly
|
||||||
CreateMap<DateTime, DateOnly>().ConvertUsing(dt => DateOnly.FromDateTime(dt));
|
CreateMap<DateTime, DateOnly>().ConvertUsing(dt => DateOnly.FromDateTime(dt));
|
||||||
|
|
||||||
@@ -70,7 +72,15 @@ namespace IRaCIS.Core.Application.Service
|
|||||||
CreateMap<Postgraduate, PostgraduateViewModel>();
|
CreateMap<Postgraduate, PostgraduateViewModel>();
|
||||||
// .ForMember(t => t.Hospital, c => c.MapFrom(d => d.HospitalEnt.HospitalName))
|
// .ForMember(t => t.Hospital, c => c.MapFrom(d => d.HospitalEnt.HospitalName))
|
||||||
//.ForMember(t => t.HospitalCN, c => c.MapFrom(d => d.HospitalEnt.HospitalNameCN));
|
//.ForMember(t => t.HospitalCN, c => c.MapFrom(d => d.HospitalEnt.HospitalNameCN));
|
||||||
CreateMap<Attachment, AttachmentDTO>();
|
CreateMap<Attachment, AttachmentDTO>()
|
||||||
|
.ForMember(d => d.BlindName, u => u.MapFrom(t => t.Doctor.BlindName))
|
||||||
|
.ForMember(d => d.BlindNameCN, u => u.MapFrom(t => t.Doctor.BlindNameCN))
|
||||||
|
.ForMember(d => d.ChineseName, u => u.MapFrom(t => t.Doctor.ChineseName))
|
||||||
|
.ForMember(d => d.FirstName, u => u.MapFrom(t => t.Doctor.FirstName))
|
||||||
|
.ForMember(d => d.LastName, u => u.MapFrom(t => t.Doctor.LastName))
|
||||||
|
.ForMember(d => d.UserName, u => u.MapFrom(t => t.Doctor.EnrollList.Where(y=>y.TrialId== TrialId).Select(x=>x.DoctorUser.UserName).First()))
|
||||||
|
;
|
||||||
|
CreateMap<Doctor, GetTrialDoctorListOutDto>();
|
||||||
CreateMap<Doctor, ResumeConfirmDTO>();
|
CreateMap<Doctor, ResumeConfirmDTO>();
|
||||||
|
|
||||||
CreateMap<Doctor, DoctorSelectDTO>();
|
CreateMap<Doctor, DoctorSelectDTO>();
|
||||||
@@ -178,16 +188,30 @@ namespace IRaCIS.Core.Application.Service
|
|||||||
CreateMap<Hospital, EmploymentDTO>();
|
CreateMap<Hospital, EmploymentDTO>();
|
||||||
|
|
||||||
CreateMap<EnrollDetail, DoctorStateModelDTO>()
|
CreateMap<EnrollDetail, DoctorStateModelDTO>()
|
||||||
|
.ForMember(d => d.UserTypeEnum, u => u.MapFrom(s => s.CreateUserRole.UserTypeEnum))
|
||||||
.ForMember(d => d.IntoGroupState, u => u.MapFrom(s => s.EnrollStatus))
|
.ForMember(d => d.IntoGroupState, u => u.MapFrom(s => s.EnrollStatus))
|
||||||
.ForMember(d => d.OptTime, u => u.MapFrom(s => s.CreateTime))
|
.ForMember(d => d.OptTime, u => u.MapFrom(s => s.CreateTime))
|
||||||
.ForMember(d => d.OptUserName, u => u.MapFrom(s => s.CreateUserRole.IdentityUser.UserName));
|
.ForMember(d => d.OptUserName, u => u.MapFrom(s => s.CreateUserRole.IdentityUser.UserName));
|
||||||
|
|
||||||
|
|
||||||
|
CreateMap<Enroll, TrialDoctorInfo>().IncludeMembers(t => t.Doctor, t => t.Doctor.Hospital)
|
||||||
|
.ForMember(o => o.DictionaryList, t => t.MapFrom(u => u.Doctor.DoctorDicRelationList.Where(t => t.KeyName == StaticData.ReadingType || t.KeyName == StaticData.Subspeciality).Select(t => t.Dictionary).OrderBy(t => t.ShowOrder)))
|
||||||
|
.ForMember(d => d.Speciality, u => u.MapFrom(s => s.Doctor.Speciality.Value))
|
||||||
|
.ForMember(d => d.SpecialityCN, u => u.MapFrom(s => s.Doctor.Speciality.ValueCN))
|
||||||
|
.ForMember(d => d.Id, u => u.MapFrom(s => s.Doctor.Id))
|
||||||
|
.ForMember(d => d.Code, u => u.MapFrom(s => s.DoctorUser.UserName));
|
||||||
|
|
||||||
|
CreateMap<Doctor, TrialDoctorInfo>();
|
||||||
|
CreateMap<Hospital, TrialDoctorInfo>();
|
||||||
|
|
||||||
CreateMap<Enroll, ConfirmationReviewerDTO>().IncludeMembers(t => t.Doctor, t => t.Doctor.Hospital)
|
CreateMap<Enroll, ConfirmationReviewerDTO>().IncludeMembers(t => t.Doctor, t => t.Doctor.Hospital)
|
||||||
.ForMember(o => o.DictionaryList, t => t.MapFrom(u => u.Doctor.DoctorDicRelationList.Where(t => t.KeyName == StaticData.ReadingType || t.KeyName == StaticData.Subspeciality).Select(t => t.Dictionary).OrderBy(t => t.ShowOrder)))
|
.ForMember(o => o.DictionaryList, t => t.MapFrom(u => u.Doctor.DoctorDicRelationList.Where(t => t.KeyName == StaticData.ReadingType || t.KeyName == StaticData.Subspeciality).Select(t => t.Dictionary).OrderBy(t => t.ShowOrder)))
|
||||||
.ForMember(d => d.Speciality, u => u.MapFrom(s => s.Doctor.Speciality.Value))
|
.ForMember(d => d.Speciality, u => u.MapFrom(s => s.Doctor.Speciality.Value))
|
||||||
.ForMember(d => d.SpecialityCN, u => u.MapFrom(s => s.Doctor.Speciality.ValueCN))
|
.ForMember(d => d.SpecialityCN, u => u.MapFrom(s => s.Doctor.Speciality.ValueCN))
|
||||||
.ForMember(d => d.Id, u => u.MapFrom(s => s.Doctor.Id))
|
.ForMember(d => d.Id, u => u.MapFrom(s => s.Doctor.Id))
|
||||||
.ForMember(d => d.Code, u => u.MapFrom(s => s.DoctorUser.UserName))
|
.ForMember(d => d.Code, u => u.MapFrom(s => s.DoctorUser.UserName))
|
||||||
|
.ForMember(d => d.HospitalName, u => u.MapFrom(s => s.Doctor.HospitalName))
|
||||||
|
.ForMember(d => d.HospitalNameCN, u => u.MapFrom(s => s.Doctor.HospitalNameCN))
|
||||||
;
|
;
|
||||||
CreateMap<Doctor, ConfirmationReviewerDTO>();
|
CreateMap<Doctor, ConfirmationReviewerDTO>();
|
||||||
CreateMap<Hospital, ConfirmationReviewerDTO>();
|
CreateMap<Hospital, ConfirmationReviewerDTO>();
|
||||||
|
|||||||
@@ -0,0 +1,585 @@
|
|||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
// 此代码由liquid模板自动生成 byzhouhang 20240909
|
||||||
|
// 生成时间 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;
|
||||||
|
namespace IRaCIS.Core.Application.Service;
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 稽查文档
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
[ApiExplorerSettings(GroupName = "FileRecord")]
|
||||||
|
public class AuditDocumentService(IRepository<AuditDocument> _auditDocumentRepository,
|
||||||
|
IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer): BaseService
|
||||||
|
{
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取稽查文档
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="inQuery"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<PageOutput<AuditDocumentView>> GetAuditDocumentList(AuditDocumentQuery inQuery)
|
||||||
|
{
|
||||||
|
var auditDocumentQueryable = _auditDocumentRepository
|
||||||
|
.ProjectTo<AuditDocumentView>(_mapper.ConfigurationProvider);
|
||||||
|
var pageList = await auditDocumentQueryable.ToPagedListAsync(inQuery);
|
||||||
|
|
||||||
|
return pageList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 修改稽查文档
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="inDto"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<IResponseOutput> UpdateAuditDocument(AuditDocumentUpdateDto inDto)
|
||||||
|
{
|
||||||
|
AuditDocumentAddOrEdit addOrEdit = _mapper.Map<AuditDocumentAddOrEdit>(inDto);
|
||||||
|
addOrEdit.IsUpdate = true;
|
||||||
|
|
||||||
|
var result= await AddOrUpdateAuditDocument(addOrEdit);
|
||||||
|
|
||||||
|
return ResponseOutput.Ok(result.Id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 新增文件夹
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="inDto"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
/// <exception cref="BusinessValidationFailedException"></exception>
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<IResponseOutput> AddFolder(AuditDocumentAddOrEdit inDto)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (await _auditDocumentRepository.AnyAsync(x => x.Name == inDto.Name && x.AuditDocumentTypeEnum == inDto.AuditDocumentTypeEnum && x.ParentId == inDto.ParentId))
|
||||||
|
{
|
||||||
|
throw new BusinessValidationFailedException(_localizer["AuditDocument_CanNotAddFolder"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<AuditDocumentAddOrEdit> auditDocumentAddOrEdits = new List<AuditDocumentAddOrEdit>();
|
||||||
|
|
||||||
|
auditDocumentAddOrEdits.Add(inDto);
|
||||||
|
var result= await AddAuditDocument(auditDocumentAddOrEdits);
|
||||||
|
return ResponseOutput.Ok(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 新增稽查文档
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="inDto"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<IResponseOutput> AddAuditDocument(List<AuditDocumentAddOrEdit> inDto)
|
||||||
|
{
|
||||||
|
List<Guid> resultData = new List<Guid>();
|
||||||
|
inDto.ForEach(x => x.IsUpdate = false);
|
||||||
|
await addData(inDto);
|
||||||
|
|
||||||
|
async Task addData(List<AuditDocumentAddOrEdit> data)
|
||||||
|
{
|
||||||
|
foreach(var item in data)
|
||||||
|
{
|
||||||
|
var result= await AddOrUpdateAuditDocument(item);
|
||||||
|
|
||||||
|
resultData.Add(result.Id);
|
||||||
|
item.Children.ForEach(x => {
|
||||||
|
x.ParentId = result.Id;
|
||||||
|
x.IsUpdate = false;
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
if (item.Children.Count() > 0)
|
||||||
|
{
|
||||||
|
await addData(item.Children);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ResponseOutput.Ok(resultData);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 通用方法
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="inDto"></param>
|
||||||
|
private async Task<AuditDocument> AddOrUpdateAuditDocument(AuditDocumentAddOrEdit inDto)
|
||||||
|
{
|
||||||
|
|
||||||
|
var alikeData = await _auditDocumentRepository.Where(x =>x.Id!=inDto.Id&& x.ParentId == inDto.ParentId&&x.Name==inDto.Name&&x.AuditDocumentTypeEnum==inDto.AuditDocumentTypeEnum).FirstOrDefaultAsync();
|
||||||
|
if (alikeData != null)
|
||||||
|
{
|
||||||
|
if (inDto.AuditDocumentTypeEnum == AuditDocumentType.Folder)
|
||||||
|
{
|
||||||
|
if (inDto.IsUpdate)
|
||||||
|
{
|
||||||
|
throw new BusinessValidationFailedException(_localizer["AuditDocument_CanNotAddFolder"]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return alikeData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var entityData = await _auditDocumentRepository.InsertOrUpdateAsync(inDto, true);
|
||||||
|
var historicalVersionIds = await _auditDocumentRepository.Where(x => x.MainFileId == alikeData.Id).OrderBy(x => x.Version).Select(x => x.Id).ToListAsync();
|
||||||
|
historicalVersionIds.Add(alikeData.Id);
|
||||||
|
int num = 1;
|
||||||
|
|
||||||
|
foreach (var item in historicalVersionIds)
|
||||||
|
{
|
||||||
|
await _auditDocumentRepository.UpdatePartialFromQueryAsync(item, x => new AuditDocument()
|
||||||
|
{
|
||||||
|
MainFileId = entityData.Id,
|
||||||
|
ParentId = null,
|
||||||
|
Version = num,
|
||||||
|
AuditDocumentTypeEnum = AuditDocumentType.HistoricalVersion
|
||||||
|
},true);
|
||||||
|
num++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return entityData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var entity = await _auditDocumentRepository.InsertOrUpdateAsync(inDto, true);
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取面包屑导航
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="inDto"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<List<AuditDocumentUpdateDto>> GetBreadcrumbData(GetBreadcrumbDataInDto inDto)
|
||||||
|
{
|
||||||
|
List<AuditDocumentUpdateDto> result=new List<AuditDocumentUpdateDto>();
|
||||||
|
|
||||||
|
await findParent(result, inDto.Id);
|
||||||
|
async Task findParent(List<AuditDocumentUpdateDto> datas, Guid id)
|
||||||
|
{
|
||||||
|
var data= await _auditDocumentRepository.Where(x => x.Id == id).ProjectTo<AuditDocumentUpdateDto>(_mapper.ConfigurationProvider).FirstNotNullAsync();
|
||||||
|
datas.Add(data);
|
||||||
|
if (data.ParentId != null)
|
||||||
|
{
|
||||||
|
await findParent(datas, data.ParentId.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
result.Reverse();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取文件树形结构 (传Id 根节点就是自己)
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="inDto"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<PageOutput<AuditDocumentData>> GetAuditDocumentData(GetAuditDocumentDataInDto inDto)
|
||||||
|
{
|
||||||
|
|
||||||
|
var defalutSortArray = new string[] { nameof(AuditDocumentData.AuditDocumentTypeEnum), nameof(AuditDocumentData.Name) };
|
||||||
|
if (inDto.SortField.IsNotNullOrEmpty())
|
||||||
|
{
|
||||||
|
defalutSortArray = new string[] { nameof(AuditDocumentData.AuditDocumentTypeEnum), inDto.SortField + (inDto.Asc ? " asc" : " desc") };
|
||||||
|
inDto.SortField = string.Empty;
|
||||||
|
}
|
||||||
|
// 新取出来排序 然后再找子项
|
||||||
|
var data= (await _auditDocumentRepository
|
||||||
|
.Where(x=>x.AuditDocumentTypeEnum!=AuditDocumentType.HistoricalVersion)
|
||||||
|
.WhereIf(inDto.IsAuthorization!=null,x=>x.IsAuthorization==inDto.IsAuthorization)
|
||||||
|
.ProjectTo<AuditDocumentData>(_mapper.ConfigurationProvider).ToPagedListAsync(new PageInput() {
|
||||||
|
PageIndex=1,
|
||||||
|
PageSize=999999,
|
||||||
|
}, defalutSortArray) ).CurrentPageData.ToList();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (inDto.Name.IsNotNullOrEmpty())
|
||||||
|
{
|
||||||
|
List<Guid> findIds = new List<Guid>();
|
||||||
|
var findData = data.Where(x => x.Name.Contains(inDto.Name)).Select(x => x.Id.Value).ToList();
|
||||||
|
GetParentId(findIds, findData, data);
|
||||||
|
findIds.AddRange(findData);
|
||||||
|
|
||||||
|
data = data.Where(x => findIds.Distinct().Contains(x.Id.Value)).ToList();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var query = data
|
||||||
|
.WhereIf(inDto.SelfId != null, x => inDto.SelfId == x.Id)
|
||||||
|
.WhereIf(inDto.Id != null, x => inDto.Id == x.ParentId)
|
||||||
|
.WhereIf(inDto.Id == null&& inDto.SelfId == null, x => x.ParentId == null);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PageOutput<AuditDocumentData> result = new PageOutput<AuditDocumentData>()
|
||||||
|
{
|
||||||
|
PageIndex = inDto.PageIndex,
|
||||||
|
PageSize = inDto.PageSize,
|
||||||
|
TotalCount = query.Count(),
|
||||||
|
};
|
||||||
|
var root = query
|
||||||
|
.Skip(inDto.PageSize * (inDto.PageIndex - 1)).Take(inDto.PageSize).ToList();
|
||||||
|
|
||||||
|
var historicalVersionList = await _auditDocumentRepository
|
||||||
|
.Where(x => x.AuditDocumentTypeEnum == AuditDocumentType.HistoricalVersion).ProjectTo<AuditDocumentData>(_mapper.ConfigurationProvider).ToListAsync();
|
||||||
|
|
||||||
|
foreach (var item in root)
|
||||||
|
{
|
||||||
|
GetChildren(item, data, historicalVersionList);
|
||||||
|
|
||||||
|
}
|
||||||
|
result.CurrentPageData = root;
|
||||||
|
return result;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GetParentId(List<Guid> parentIds, List<Guid> ids, List<AuditDocumentData> dataList)
|
||||||
|
{
|
||||||
|
var parentid = dataList.Where(x => ids.Contains(x.Id.Value) && x.ParentId != null).Select(x => x.ParentId.Value).ToList();
|
||||||
|
|
||||||
|
if (parentid.Count() > 0)
|
||||||
|
{
|
||||||
|
parentIds.AddRange(parentid);
|
||||||
|
|
||||||
|
GetParentId(parentIds, parentid, dataList);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GetChildren(AuditDocumentData item, List<AuditDocumentData> dataList, List<AuditDocumentData> historyList)
|
||||||
|
{
|
||||||
|
item.Children = dataList.Where(x => x.ParentId == item.Id).ToList();
|
||||||
|
item.HistoricalVersionsCount= historyList.Where(x => x.MainFileId == item.Id).Count();
|
||||||
|
foreach (var x in item.Children)
|
||||||
|
{
|
||||||
|
GetChildren(x, dataList, historyList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 删除稽查文档
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="inDto"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<IResponseOutput> DeleteAuditDocument(DeleteAuditDocumentInDto inDto)
|
||||||
|
{
|
||||||
|
var data = await _auditDocumentRepository.Select(x => new DeleteAudit (){
|
||||||
|
Id=x.Id,
|
||||||
|
ParentId= x.ParentId,
|
||||||
|
MainFileId= x.MainFileId
|
||||||
|
}).ToListAsync();
|
||||||
|
|
||||||
|
List<Guid> DeleteId= inDto.Ids;
|
||||||
|
|
||||||
|
finId(inDto.Ids, data);
|
||||||
|
|
||||||
|
void finId(List<Guid> deletids, List<DeleteAudit> deletes)
|
||||||
|
{
|
||||||
|
DeleteId.AddRange(deletids);
|
||||||
|
|
||||||
|
var temp = deletes.Where(x =>(x.ParentId!=null&& deletids.Contains(x.ParentId.Value))||(x.MainFileId!=null&& deletids.Contains(x.MainFileId.Value))).Select(x => x.Id).ToList();
|
||||||
|
if (temp.Count() > 0)
|
||||||
|
{
|
||||||
|
finId(temp, deletes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DeleteId = DeleteId.Distinct().ToList();
|
||||||
|
var mainFileId=await _auditDocumentRepository.Where(x => DeleteId.Contains(x.Id)&&x.MainFileId!=null).Select(x => x.MainFileId).Distinct().ToListAsync();
|
||||||
|
var success = await _auditDocumentRepository.DeleteFromQueryAsync(t => DeleteId.Distinct().Contains(t.Id), true);
|
||||||
|
|
||||||
|
foreach (var item in mainFileId)
|
||||||
|
{
|
||||||
|
var historicalVersionList = await _auditDocumentRepository.Where(x => x.MainFileId == item).OrderBy(x=>x.Version).ToListAsync();
|
||||||
|
|
||||||
|
var num = 1;
|
||||||
|
foreach (var historical in historicalVersionList)
|
||||||
|
{
|
||||||
|
await _auditDocumentRepository.UpdatePartialFromQueryAsync(historical.Id, x => new AuditDocument()
|
||||||
|
{
|
||||||
|
Version = num,
|
||||||
|
}, true);
|
||||||
|
num++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return ResponseOutput.Ok();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 移动文件或者文件夹 到其他文件夹
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<IResponseOutput> MovieFileOrFolder(MovieFileOrFolderInDto inDto)
|
||||||
|
{
|
||||||
|
|
||||||
|
var data = await _auditDocumentRepository.Select(x => new DeleteAudit()
|
||||||
|
{
|
||||||
|
Id = x.Id,
|
||||||
|
ParentId = x.ParentId,
|
||||||
|
AuditDocumentTypeEnum = x.AuditDocumentTypeEnum,
|
||||||
|
MainFileId = x.MainFileId
|
||||||
|
}).ToListAsync();
|
||||||
|
|
||||||
|
foreach (var id in inDto.Ids)
|
||||||
|
{
|
||||||
|
var file = data.Where(x => x.Id == id).FirstOrDefault();
|
||||||
|
if (file.AuditDocumentTypeEnum == AuditDocumentType.Folder)
|
||||||
|
{
|
||||||
|
if (finChild(new List<Guid> { id }, inDto.ParentId, data))
|
||||||
|
{
|
||||||
|
throw new BusinessValidationFailedException(_localizer["AuditDocument_CanNotMove"]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool finChild(List<Guid> ids, Guid ChildId, List<DeleteAudit> data)
|
||||||
|
{
|
||||||
|
var child = data.Where(x => x.ParentId != null && ids.Contains(x.ParentId.Value)).ToList();
|
||||||
|
if (child.Count() == 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if (child.Any(x => x.Id == ChildId))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var newids = child.Select(x => x.Id).ToList();
|
||||||
|
|
||||||
|
return finChild(newids, ChildId, data);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var id in inDto.Ids)
|
||||||
|
{
|
||||||
|
await _auditDocumentRepository.UpdatePartialFromQueryAsync(id, x => new AuditDocument()
|
||||||
|
{
|
||||||
|
ParentId = inDto.ParentId
|
||||||
|
});
|
||||||
|
|
||||||
|
await _auditDocumentRepository.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
return ResponseOutput.Ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 复制文件或者文件夹
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="inDto"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<IResponseOutput> CopyFileOrFolder(MovieFileOrFolderInDto inDto)
|
||||||
|
{
|
||||||
|
|
||||||
|
foreach (var item in inDto.Ids)
|
||||||
|
{
|
||||||
|
var data = (await GetAuditDocumentData(new GetAuditDocumentDataInDto()
|
||||||
|
{
|
||||||
|
SelfId =item,
|
||||||
|
|
||||||
|
PageIndex=1,
|
||||||
|
PageSize= 1000
|
||||||
|
})).CurrentPageData;
|
||||||
|
|
||||||
|
List<AuditDocumentAddOrEdit> auditDocumentAddOrEdits = _mapper.Map<List<AuditDocumentAddOrEdit>>(data);
|
||||||
|
auditDocumentAddOrEdits.ForEach(x => {
|
||||||
|
x.IsUpdate = false;
|
||||||
|
x.Id = null;
|
||||||
|
x.ParentId = inDto.ParentId;
|
||||||
|
});
|
||||||
|
await addData(auditDocumentAddOrEdits);
|
||||||
|
}
|
||||||
|
|
||||||
|
async Task addData(List<AuditDocumentAddOrEdit> data)
|
||||||
|
{
|
||||||
|
foreach (var item in data)
|
||||||
|
{
|
||||||
|
item.Id = null;
|
||||||
|
var result = await AddOrUpdateAuditDocument(item);
|
||||||
|
|
||||||
|
item.Children.ForEach(x => {
|
||||||
|
x.ParentId = result.Id;
|
||||||
|
x.IsUpdate = false;
|
||||||
|
x.Id = null;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (item.Children.Count() > 0)
|
||||||
|
{
|
||||||
|
await addData(item.Children);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ResponseOutput.Ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取历史版本
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="inDto"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<List<HistoricalVersionDto>> GetHistoricalVersion(GetHistoricalVersionInDto inDto)
|
||||||
|
{
|
||||||
|
|
||||||
|
List< HistoricalVersionDto > result=new List<HistoricalVersionDto>();
|
||||||
|
|
||||||
|
result = await _auditDocumentRepository.Where(x => x.MainFileId == inDto.Id).ProjectTo<HistoricalVersionDto>(_mapper.ConfigurationProvider).OrderByDescending(x => x.Version).ToListAsync();
|
||||||
|
var currentData = await _auditDocumentRepository.Where(x => x.Id == inDto.Id).ProjectTo<HistoricalVersionDto>(_mapper.ConfigurationProvider).FirstNotNullAsync();
|
||||||
|
currentData.IsCurrentVersion = true;
|
||||||
|
|
||||||
|
result.Insert(0, currentData);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 把历史版本设置为当前版本
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<IResponseOutput> SetCurrentVersion(SetCurrentVersionInDto inDto)
|
||||||
|
{
|
||||||
|
var file = await _auditDocumentRepository.Where(x => x.Id == inDto.Id).FirstNotNullAsync();
|
||||||
|
if (file.AuditDocumentTypeEnum != AuditDocumentType.HistoricalVersion)
|
||||||
|
{
|
||||||
|
throw new BusinessValidationFailedException(_localizer["AuditDocument_CanNotSetCurrentVersion"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
var mainFile = await _auditDocumentRepository.Where(x => x.Id == file.MainFileId).FirstNotNullAsync();
|
||||||
|
|
||||||
|
var historicalVersionIds= await _auditDocumentRepository.Where(x => x.MainFileId == mainFile.Id&&x.Id!=inDto.Id).OrderBy(x=>x.Version).Select(x=>x.Id).ToListAsync();
|
||||||
|
|
||||||
|
historicalVersionIds.Add(mainFile.Id);
|
||||||
|
await _auditDocumentRepository.UpdatePartialFromQueryAsync(inDto.Id, x => new AuditDocument() {
|
||||||
|
MainFileId=null,
|
||||||
|
ParentId= mainFile.ParentId,
|
||||||
|
AuditDocumentTypeEnum=AuditDocumentType.File,
|
||||||
|
});
|
||||||
|
|
||||||
|
int num = 1;
|
||||||
|
foreach (var item in historicalVersionIds)
|
||||||
|
{
|
||||||
|
await _auditDocumentRepository.UpdatePartialFromQueryAsync(item, x => new AuditDocument()
|
||||||
|
{
|
||||||
|
MainFileId = inDto.Id,
|
||||||
|
ParentId = null,
|
||||||
|
Version=num,
|
||||||
|
AuditDocumentTypeEnum= AuditDocumentType.HistoricalVersion
|
||||||
|
});
|
||||||
|
num++;
|
||||||
|
}
|
||||||
|
|
||||||
|
await _auditDocumentRepository.SaveChangesAsync();
|
||||||
|
|
||||||
|
|
||||||
|
return ResponseOutput.Ok();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设置是否授权
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="inDto"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<IResponseOutput> SetIsAuthorization(SetIsAuthorizationInDto inDto)
|
||||||
|
{
|
||||||
|
var data = await _auditDocumentRepository.Select(x => new DeleteAudit()
|
||||||
|
{
|
||||||
|
Id = x.Id,
|
||||||
|
ParentId = x.ParentId,
|
||||||
|
MainFileId = x.MainFileId
|
||||||
|
}).ToListAsync();
|
||||||
|
|
||||||
|
List<Guid> allid = new List<Guid>();
|
||||||
|
findChild(allid, inDto.Ids, data);
|
||||||
|
if (inDto.IsAuthorization)
|
||||||
|
{
|
||||||
|
findParent(allid, inDto.Ids, data);
|
||||||
|
}
|
||||||
|
allid= allid.Distinct().ToList();
|
||||||
|
await _auditDocumentRepository.UpdatePartialFromQueryAsync(t => allid.Contains(t.Id), x => new AuditDocument() {
|
||||||
|
|
||||||
|
IsAuthorization = inDto.IsAuthorization
|
||||||
|
});
|
||||||
|
await _auditDocumentRepository.SaveChangesAsync();
|
||||||
|
return ResponseOutput.Ok();
|
||||||
|
|
||||||
|
void findParent(List<Guid> allId, List<Guid> current, List<DeleteAudit> data)
|
||||||
|
{
|
||||||
|
allId.AddRange(current);
|
||||||
|
var parent = data.Where(x => current.Contains(x.Id)).Select(x => x.ParentId).Where(x=>x!=null).Select(x=>(Guid)x).ToList();
|
||||||
|
|
||||||
|
if (parent.Count() > 0)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
findParent(allId, parent, data);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void findChild(List<Guid> allId,List<Guid> current, List<DeleteAudit> data)
|
||||||
|
{
|
||||||
|
allId.AddRange(current);
|
||||||
|
|
||||||
|
var child = data.Where(x =>(x.ParentId!=null&& current.Contains(x.ParentId.Value))||(x.MainFileId!=null&¤t.Contains(x.MainFileId.Value))).Select(x => x.Id).ToList();
|
||||||
|
if (child.Count() > 0)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
findChild(allId, child, data);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,167 @@
|
|||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
// 此代码由liquid模板自动生成 byzhouhang 20240909
|
||||||
|
// 生成时间 2025-03-27 06:13:37Z
|
||||||
|
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
using System;
|
||||||
|
using IRaCIS.Core.Domain.Share;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
namespace IRaCIS.Core.Application.ViewModel;
|
||||||
|
|
||||||
|
public class DeleteAudit
|
||||||
|
{
|
||||||
|
public Guid Id { get; set; }
|
||||||
|
|
||||||
|
public AuditDocumentType AuditDocumentTypeEnum { get; set; }
|
||||||
|
public Guid? ParentId { get; set; }
|
||||||
|
|
||||||
|
public Guid? MainFileId { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class DeleteAuditDocumentInDto
|
||||||
|
{
|
||||||
|
public List<Guid> Ids { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class GetAuditDocumentDataInDto:PageInput
|
||||||
|
{
|
||||||
|
public Guid? Id { get; set; }
|
||||||
|
|
||||||
|
public Guid? SelfId { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
public bool? IsAuthorization { get; set; }
|
||||||
|
|
||||||
|
public string Name { get; set; } = string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class GetAuditDocumentDataOutDto
|
||||||
|
{
|
||||||
|
public List<AuditDocumentData> Data { get; set; } = new List<AuditDocumentData> { };
|
||||||
|
}
|
||||||
|
|
||||||
|
public class AuditDocumentData : AuditDocumentUpdateDto
|
||||||
|
{
|
||||||
|
public DateTime CreateTime { get; set; }
|
||||||
|
|
||||||
|
public DateTime UpdateTime { get; set; }
|
||||||
|
|
||||||
|
public Guid? MainFileId { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
public int? Version { get; set; }
|
||||||
|
|
||||||
|
public int HistoricalVersionsCount { get; set; }
|
||||||
|
public List<AuditDocumentData> Children { get; set; }=new List<AuditDocumentData> (){ };
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class AuditDocumentView : AuditDocumentAddOrEdit
|
||||||
|
{
|
||||||
|
|
||||||
|
public DateTime CreateTime { get; set; }
|
||||||
|
|
||||||
|
public DateTime UpdateTime { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class SetIsAuthorizationInDto
|
||||||
|
{
|
||||||
|
public List<Guid> Ids { get; set; }
|
||||||
|
|
||||||
|
public bool IsAuthorization { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class SetCurrentVersionInDto
|
||||||
|
{
|
||||||
|
public Guid Id { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class GetHistoricalVersionInDto
|
||||||
|
{
|
||||||
|
public Guid Id { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class GetHistoricalVersionOutDto
|
||||||
|
{
|
||||||
|
public AuditDocumentData CurrentData { get; set; }
|
||||||
|
public List<AuditDocumentData> HistoricalVersionList { get; set; } = new List<AuditDocumentData> { };
|
||||||
|
}
|
||||||
|
|
||||||
|
public class MovieFileOrFolderInDto
|
||||||
|
{
|
||||||
|
public List<Guid> Ids { get; set; }
|
||||||
|
|
||||||
|
public Guid ParentId { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class HistoricalVersionDto: AuditDocumentUpdateDto
|
||||||
|
{
|
||||||
|
public bool IsCurrentVersion { get; set; } = false;
|
||||||
|
|
||||||
|
public int? Version { get; set; }
|
||||||
|
|
||||||
|
public DateTime CreateTime { get; set; }
|
||||||
|
|
||||||
|
public DateTime UpdateTime { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class AuditDocumentUpdateDto
|
||||||
|
{
|
||||||
|
public Guid? Id { get; set; }
|
||||||
|
|
||||||
|
public AuditDocumentType AuditDocumentTypeEnum { get; set; }
|
||||||
|
|
||||||
|
public string? FileFormat { get; set; }
|
||||||
|
|
||||||
|
public string? FilePath { get; set; }
|
||||||
|
|
||||||
|
public decimal? FileSize { get; set; }
|
||||||
|
|
||||||
|
public bool IsAuthorization { get; set; }
|
||||||
|
|
||||||
|
// public Guid? MainFileId { get; set; }
|
||||||
|
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
public Guid? ParentId { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class GetBreadcrumbDataInDto
|
||||||
|
{
|
||||||
|
public Guid Id { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class AuditDocumentAddOrEdit: AuditDocumentUpdateDto
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
public List<AuditDocumentAddOrEdit> Children { get; set; }=new List<AuditDocumentAddOrEdit>() { };
|
||||||
|
|
||||||
|
public bool IsUpdate { get; set; } = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class AuditDocumentQuery:PageInput
|
||||||
|
{
|
||||||
|
public AuditDocumentType? AuditDocumentTypeEnum { get; set; }
|
||||||
|
|
||||||
|
public string? FileFormat { get; set; }
|
||||||
|
|
||||||
|
public string? FilePath { get; set; }
|
||||||
|
|
||||||
|
public decimal? FileSize { get; set; }
|
||||||
|
|
||||||
|
public bool? IsAuthorization { get; set; }
|
||||||
|
|
||||||
|
public Guid? MainFileId { get; set; }
|
||||||
|
|
||||||
|
public string? Name { get; set; }
|
||||||
|
|
||||||
|
public Guid? ParentId { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
// 此代码由liquid模板自动生成 byzhouhang 20240909
|
||||||
|
// 生成时间 2025-02-21 07:47:30Z
|
||||||
|
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
using System;
|
||||||
|
using IRaCIS.Core.Domain.Share;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
namespace IRaCIS.Core.Application.ViewModel;
|
||||||
|
|
||||||
|
public class SysFileTypeView : SysFileTypeAddOrEdit
|
||||||
|
{
|
||||||
|
|
||||||
|
public DateTime CreateTime { get; set; }
|
||||||
|
|
||||||
|
public DateTime UpdateTime { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public class SysFileTypeAddOrEdit
|
||||||
|
{
|
||||||
|
public Guid? Id { get; set; }
|
||||||
|
|
||||||
|
public ArchiveType ArchiveTypeEnum { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 文档类型
|
||||||
|
/// </summary>
|
||||||
|
public SysTemplateType SysTemplateTypeEnum { get; set; }
|
||||||
|
|
||||||
|
public bool IsConfirmRecord { get; set; }
|
||||||
|
|
||||||
|
public bool IsEnable { get; set; }
|
||||||
|
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
public string NameCN { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 显示顺序
|
||||||
|
/// </summary>
|
||||||
|
public int ShowOrder { get; set; }
|
||||||
|
|
||||||
|
public SubIdentification SubIdentificationEnum { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class SysFileTypeQuery : PageInput
|
||||||
|
{
|
||||||
|
public ArchiveType? ArchiveTypeEnum { get; set; }
|
||||||
|
|
||||||
|
public SysTemplateType? SysTemplateTypeEnum { get; set; }
|
||||||
|
|
||||||
|
public bool? IsConfirmRecord { get; set; }
|
||||||
|
|
||||||
|
public bool? IsEnable { get; set; }
|
||||||
|
|
||||||
|
public string? Name { get; set; }
|
||||||
|
|
||||||
|
public string? NameCN { get; set; }
|
||||||
|
|
||||||
|
public SubIdentification? SubIdentificationEnum { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -8,6 +8,51 @@ using System.ComponentModel.DataAnnotations;
|
|||||||
|
|
||||||
namespace IRaCIS.Core.Application.Contracts
|
namespace IRaCIS.Core.Application.Contracts
|
||||||
{
|
{
|
||||||
|
public class SystemDocumentAttachmentView : SystemDocumentAttachmentAddOrEdit
|
||||||
|
{
|
||||||
|
|
||||||
|
public DateTime CreateTime { get; set; }
|
||||||
|
|
||||||
|
public DateTime UpdateTime { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public class SystemDocumentAttachmentAddOrEdit
|
||||||
|
{
|
||||||
|
public Guid? Id { get; set; }
|
||||||
|
|
||||||
|
public string FileFormat { get; set; }
|
||||||
|
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
public string FileName { get; set; }
|
||||||
|
|
||||||
|
public string FilePath { get; set; }
|
||||||
|
|
||||||
|
public decimal? FileSize { get; set; }
|
||||||
|
|
||||||
|
public bool OffLine { get; set; }
|
||||||
|
|
||||||
|
public Guid SystemDocumentId { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class SystemDocumentAttachmentQuery : PageInput
|
||||||
|
{
|
||||||
|
public string? FileFormat { get; set; }
|
||||||
|
|
||||||
|
public string? FileName { get; set; }
|
||||||
|
|
||||||
|
public string? FilePath { get; set; }
|
||||||
|
|
||||||
|
public decimal? FileSize { get; set; }
|
||||||
|
|
||||||
|
public bool? OffLine { get; set; }
|
||||||
|
|
||||||
|
public Guid? SystemDocumentId { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary> SystemDocumentView 列表视图模型 </summary>
|
/// <summary> SystemDocumentView 列表视图模型 </summary>
|
||||||
public class SystemDocumentView : SystemDocumentAddOrEdit
|
public class SystemDocumentView : SystemDocumentAddOrEdit
|
||||||
{
|
{
|
||||||
@@ -17,6 +62,8 @@ namespace IRaCIS.Core.Application.Contracts
|
|||||||
|
|
||||||
public string FileType { get; set; } = string.Empty;
|
public string FileType { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public int AttachmentCount { get; set; }
|
||||||
|
|
||||||
public List<NeedConfirmedUserTypeView> NeedConfirmedUserTypeList { get; set; } = new List<NeedConfirmedUserTypeView>();
|
public List<NeedConfirmedUserTypeView> NeedConfirmedUserTypeList { get; set; } = new List<NeedConfirmedUserTypeView>();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,6 +93,10 @@ namespace IRaCIS.Core.Application.Contracts
|
|||||||
public class UnionDocumentWithConfirmInfoView : UnionDocumentView
|
public class UnionDocumentWithConfirmInfoView : UnionDocumentView
|
||||||
{
|
{
|
||||||
|
|
||||||
|
public bool IsNeedSendEmial { get; set; }
|
||||||
|
public DateTime UserCreateTime { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public DateTime? ConfirmTime { get; set; }
|
public DateTime? ConfirmTime { get; set; }
|
||||||
|
|
||||||
@@ -58,6 +109,28 @@ namespace IRaCIS.Core.Application.Contracts
|
|||||||
public string RealName { get; set; } = string.Empty;
|
public string RealName { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
|
||||||
|
public int AttachmentCount { get; set; }
|
||||||
|
|
||||||
|
public DateTime? SuggestFinishTime
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
|
||||||
|
if (this.CreateTime > this.UserCreateTime && this.CurrentStaffTrainDays != null)
|
||||||
|
{
|
||||||
|
return DateTime.Parse(this.CreateTime.AddDays(this.CurrentStaffTrainDays.Value).ToString("yyyy-MM-dd")+" 22:00:00");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.CreateTime < this.UserCreateTime && this.NewStaffTrainDays != null)
|
||||||
|
{
|
||||||
|
return DateTime.Parse(this.UserCreateTime.AddDays(this.NewStaffTrainDays.Value).ToString("yyyy-MM-dd") + " 22:00:00");
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public string DocTypeCode { get; set; }
|
public string DocTypeCode { get; set; }
|
||||||
|
|
||||||
public List<string> UserConfirmedUserTypeList => (DocNeedSignUserTypeList != null && IdentityUserTypeList != null) ? IdentityUserTypeList.Intersect(DocNeedSignUserTypeList).ToList() : new List<string>();
|
public List<string> UserConfirmedUserTypeList => (DocNeedSignUserTypeList != null && IdentityUserTypeList != null) ? IdentityUserTypeList.Intersect(DocNeedSignUserTypeList).ToList() : new List<string>();
|
||||||
@@ -119,6 +192,15 @@ namespace IRaCIS.Core.Application.Contracts
|
|||||||
public bool IsSigned { get; set; }
|
public bool IsSigned { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
public Guid? UserTypeId { get; set; }
|
||||||
|
|
||||||
|
public DocUserSignType? DocUserSignType { get; set; }
|
||||||
|
|
||||||
|
public DateTime? BeginCreateTime { get; set; }
|
||||||
|
|
||||||
|
public DateTime? EndCreateTime { get; set; }
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class GetNextUnSignDocumentInDto
|
public class GetNextUnSignDocumentInDto
|
||||||
@@ -170,6 +252,47 @@ namespace IRaCIS.Core.Application.Contracts
|
|||||||
public string SignText { get; set; } = string.Empty;
|
public string SignText { get; set; } = string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public class SystemDocQuery : PageInput
|
||||||
|
{
|
||||||
|
public Guid? FileTypeId { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
public string Name { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public bool? IsSign { get; set; }
|
||||||
|
|
||||||
|
public Guid? UserTypeId { get; set; }
|
||||||
|
public Guid? UserId { get; set; }
|
||||||
|
|
||||||
|
public bool? IsConfirmed { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 课时状态
|
||||||
|
/// </summary>
|
||||||
|
public bool? IsDeleted { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 用户名
|
||||||
|
/// </summary>
|
||||||
|
public string? UserName { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 开始时间
|
||||||
|
/// </summary>
|
||||||
|
public DateTime? StartConfirmTime { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 结束时间
|
||||||
|
/// </summary>
|
||||||
|
public DateTime? EndConfirmTime { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
public DateTime? BeginCreateTime { get; set; }
|
||||||
|
|
||||||
|
public DateTime? EndCreateTime { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
public class DocumentTrialUnionQuery : TrialUserDocUnionQuery
|
public class DocumentTrialUnionQuery : TrialUserDocUnionQuery
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -178,7 +301,29 @@ namespace IRaCIS.Core.Application.Contracts
|
|||||||
|
|
||||||
public bool? IsConfirmed { get; set; }
|
public bool? IsConfirmed { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 课时状态
|
||||||
|
/// </summary>
|
||||||
public bool? IsDeleted { get; set; }
|
public bool? IsDeleted { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 用户名
|
||||||
|
/// </summary>
|
||||||
|
public string? UserName { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 开始时间
|
||||||
|
/// </summary>
|
||||||
|
public DateTime? StartConfirmTime { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 结束时间
|
||||||
|
/// </summary>
|
||||||
|
public DateTime? EndConfirmTime { get; set; }
|
||||||
|
|
||||||
|
public DateTime? BeginCreateTime { get; set; }
|
||||||
|
|
||||||
|
public DateTime? EndCreateTime { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
///<summary> SystemDocumentAddOrEdit 列表查询参数模型</summary>
|
///<summary> SystemDocumentAddOrEdit 列表查询参数模型</summary>
|
||||||
@@ -195,6 +340,29 @@ namespace IRaCIS.Core.Application.Contracts
|
|||||||
|
|
||||||
public DocUserSignType DocUserSignType { get; set; }
|
public DocUserSignType DocUserSignType { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 现有员工培训天数
|
||||||
|
/// </summary>
|
||||||
|
public int? CurrentStaffTrainDays { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 新员工培训天数
|
||||||
|
/// </summary>
|
||||||
|
public int? NewStaffTrainDays { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否发布
|
||||||
|
/// </summary>
|
||||||
|
|
||||||
|
public bool IsPublish { get; set; } = false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public class PublishSystemDocumentInDto
|
||||||
|
{
|
||||||
|
public List<Guid> Ids { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class AddOrEditSystemDocument : SystemDocumentAddOrEdit
|
public class AddOrEditSystemDocument : SystemDocumentAddOrEdit
|
||||||
|
|||||||
@@ -0,0 +1,153 @@
|
|||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
// 此代码由liquid模板自动生成 byzhouhang 20240909
|
||||||
|
// 生成时间 2025-02-21 07:47:30Z
|
||||||
|
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
using System;
|
||||||
|
using IRaCIS.Core.Domain.Share;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.Reflection.Metadata;
|
||||||
|
namespace IRaCIS.Core.Application.ViewModel;
|
||||||
|
|
||||||
|
public class TrialFileTypeView : TrialFileTypeAddOrEdit
|
||||||
|
{
|
||||||
|
|
||||||
|
public DateTime CreateTime { get; set; }
|
||||||
|
|
||||||
|
public DateTime UpdateTime { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class GetTrialFileTypeDataOutDto
|
||||||
|
{
|
||||||
|
public List<TrialFileTypeData> TrialFileTypeDataList { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TrialFileTypeData
|
||||||
|
{
|
||||||
|
public ArchiveType ArchiveTypeEnum { get; set; }
|
||||||
|
|
||||||
|
public List<TrialFileTypeView> TrialFileTypeList { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public class GetTrialFileTypeFileInDto
|
||||||
|
{
|
||||||
|
public Guid TrialFileTypeId { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class UploadTrialFileTypeFileInDto
|
||||||
|
{
|
||||||
|
public Guid TrialFileTypeId { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 文件
|
||||||
|
/// </summary>
|
||||||
|
public TrialFileDto? FileRecord { get; set; }
|
||||||
|
}
|
||||||
|
public class SetAuthorizedViewInDto
|
||||||
|
{
|
||||||
|
public Guid Id { get; set; }
|
||||||
|
|
||||||
|
public bool IsEnable { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class GetTrialFileTypeDataInDto
|
||||||
|
{
|
||||||
|
public Guid TrialId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否启用
|
||||||
|
/// </summary>
|
||||||
|
public bool IsEnable { get; set; } = false;
|
||||||
|
}
|
||||||
|
public class CopySystemFileTypeToTrialInDto
|
||||||
|
{
|
||||||
|
public Guid TrialId { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TrialFileTypeSelectView
|
||||||
|
{
|
||||||
|
public Guid Id { get; set; }
|
||||||
|
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
public bool IsEnable { get; set; }
|
||||||
|
|
||||||
|
public bool IsSelfDefine { get; set; }
|
||||||
|
|
||||||
|
public ArchiveType ArchiveTypeEnum { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public class TrialFileTypeAddOrEdit
|
||||||
|
{
|
||||||
|
public Guid? Id { get; set; }
|
||||||
|
|
||||||
|
public ArchiveType ArchiveTypeEnum { get; set; }
|
||||||
|
|
||||||
|
public DateOnly? FirstFinalDate { get; set; }
|
||||||
|
|
||||||
|
public bool IsConfirmRecord { get; set; }
|
||||||
|
|
||||||
|
public bool IsEnable { get; set; }
|
||||||
|
|
||||||
|
public bool IsSelfDefine { get; set; }
|
||||||
|
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
public string NameCN { get; set; }
|
||||||
|
|
||||||
|
public SubIdentification SubIdentificationEnum { get; set; }
|
||||||
|
|
||||||
|
public Guid? SysFileTypeId { get; set; }
|
||||||
|
|
||||||
|
public Guid TrialId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 显示顺序
|
||||||
|
/// </summary>
|
||||||
|
public int ShowOrder { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TrialFileTypeQuery : PageInput
|
||||||
|
{
|
||||||
|
public ArchiveType? ArchiveTypeEnum { get; set; }
|
||||||
|
|
||||||
|
public DateOnly? FirstFinalDate { get; set; }
|
||||||
|
|
||||||
|
public bool? IsConfirmRecord { get; set; }
|
||||||
|
|
||||||
|
public bool? IsEnable { get; set; }
|
||||||
|
|
||||||
|
public bool? IsSelfDefine { get; set; }
|
||||||
|
|
||||||
|
public string? Name { get; set; }
|
||||||
|
|
||||||
|
public string? NameCN { get; set; }
|
||||||
|
|
||||||
|
public SubIdentification? SubIdentificationEnum { get; set; }
|
||||||
|
|
||||||
|
[NotDefault]
|
||||||
|
public Guid TrialId { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public class TrialFileTypeSelectQuery
|
||||||
|
{
|
||||||
|
[NotDefault]
|
||||||
|
public Guid TrialId { get; set; }
|
||||||
|
|
||||||
|
public bool? IsEnable { get; set; }
|
||||||
|
|
||||||
|
public bool? IsSelfDefine { get; set; }
|
||||||
|
|
||||||
|
public ArchiveType? ArchiveTypeEnum { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,115 @@
|
|||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
// 此代码由liquid模板自动生成 byzhouhang 20240909
|
||||||
|
// 生成时间 2025-02-21 07:47:30Z
|
||||||
|
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
using System;
|
||||||
|
using IRaCIS.Core.Domain.Share;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
namespace IRaCIS.Core.Application.ViewModel;
|
||||||
|
|
||||||
|
public class TrialFinalRecordView : TrialFinalRecordAddOrEdit
|
||||||
|
{
|
||||||
|
|
||||||
|
public DateTime CreateTime { get; set; }
|
||||||
|
|
||||||
|
public DateTime UpdateTime { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class DeleteTrialNormalRecordListInDto
|
||||||
|
{
|
||||||
|
public List<Guid> Ids { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class AuthorizedTrialFinalRecordInDto
|
||||||
|
{
|
||||||
|
public List<Guid> Ids { get; set; }
|
||||||
|
|
||||||
|
public bool IsAuthorizedView { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TrialFinalRecordAddOrEdit
|
||||||
|
{
|
||||||
|
public Guid? Id { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public bool IsAuthorizedView { get; set; }
|
||||||
|
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public int State { get; set; }
|
||||||
|
|
||||||
|
public Guid TrialFileTypeId { get; set; }
|
||||||
|
|
||||||
|
public Guid TrialId { get; set; }
|
||||||
|
|
||||||
|
public string Version { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 定稿PDF
|
||||||
|
/// </summary>
|
||||||
|
public TrialFileDto? PDFFileRecord { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 定稿Word
|
||||||
|
/// </summary>
|
||||||
|
|
||||||
|
public TrialFileDto? WordFileRecord { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 签名页
|
||||||
|
/// </summary>
|
||||||
|
|
||||||
|
public TrialFileDto? SignFileRecord { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 历史记录
|
||||||
|
/// </summary>
|
||||||
|
|
||||||
|
public TrialFileDto? HistoryFileRecord { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public class TrialFileDto
|
||||||
|
{
|
||||||
|
public Guid TrialFileTypeId { get; set; }
|
||||||
|
|
||||||
|
public string FileName { get; set; }
|
||||||
|
|
||||||
|
public string FilePath { get; set; }
|
||||||
|
|
||||||
|
public string FileSize { get; set; }
|
||||||
|
|
||||||
|
public string FileFormat { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TrialFinalRecordQuery : PageInput
|
||||||
|
{
|
||||||
|
public Guid? HistoryFileRecordId { get; set; }
|
||||||
|
|
||||||
|
public bool? IsAuthorizedView { get; set; }
|
||||||
|
|
||||||
|
public string? Name { get; set; }
|
||||||
|
|
||||||
|
[NotDefault]
|
||||||
|
public Guid TrialFileTypeId { get; set; }
|
||||||
|
|
||||||
|
public Guid? TrialId { get; set; }
|
||||||
|
|
||||||
|
public string? Version { get; set; }
|
||||||
|
|
||||||
|
public Guid? WordFileRecordId { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
// 此代码由liquid模板自动生成 byzhouhang 20240909
|
||||||
|
// 生成时间 2025-02-21 07:47:30Z
|
||||||
|
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
using System;
|
||||||
|
using IRaCIS.Core.Domain.Share;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
namespace IRaCIS.Core.Application.ViewModel;
|
||||||
|
|
||||||
|
public class TrialNormalRecordView : TrialNormalRecordAddOrEdit
|
||||||
|
{
|
||||||
|
|
||||||
|
public DateTime CreateTime { get; set; }
|
||||||
|
|
||||||
|
public DateTime UpdateTime { get; set; }
|
||||||
|
|
||||||
|
public string FileName { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class BatchAddTrialNormalRecordInDto
|
||||||
|
{
|
||||||
|
public List<TrialNormalRecordAddOrEdit> TrialNormalRecordList { get; set; }
|
||||||
|
}
|
||||||
|
public class TrialNormalRecordAddOrEdit
|
||||||
|
{
|
||||||
|
public Guid? Id { get; set; }
|
||||||
|
|
||||||
|
public bool IsAuthorizedView { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
public int State { get; set; }
|
||||||
|
|
||||||
|
public TrialFileDto? TrialFileRecord { get; set; }
|
||||||
|
|
||||||
|
public TrialFileDto? HistoryFileRecord { get; set; }
|
||||||
|
|
||||||
|
public Guid TrialFileTypeId { get; set; }
|
||||||
|
|
||||||
|
public Guid TrialId { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TrialNormalRecordQuery : PageInput
|
||||||
|
{
|
||||||
|
public bool? IsAuthorizedView { get; set; }
|
||||||
|
|
||||||
|
public int? State { get; set; }
|
||||||
|
|
||||||
|
public string? FileName { get; set; }
|
||||||
|
|
||||||
|
public Guid? TrialFileTypeId { get; set; }
|
||||||
|
|
||||||
|
public Guid? TrialId { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
// 此代码由liquid模板自动生成 byzhouhang 20240909
|
||||||
|
// 生成时间 2025-02-21 07:47:30Z
|
||||||
|
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
using System;
|
||||||
|
using IRaCIS.Core.Domain.Share;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
namespace IRaCIS.Core.Application.ViewModel;
|
||||||
|
|
||||||
|
public class TrialTrianingRecordView : TrialTrianingRecordAddOrEdit
|
||||||
|
{
|
||||||
|
|
||||||
|
public DateTime CreateTime { get; set; }
|
||||||
|
|
||||||
|
public DateTime UpdateTime { get; set; }
|
||||||
|
|
||||||
|
public string FileName { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class BatchAddTTrianingRecordInDto
|
||||||
|
{
|
||||||
|
public List<TrialTrianingRecordAddOrEdit> TrianingRecordList { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TrialTrianingRecordAddOrEdit
|
||||||
|
{
|
||||||
|
public Guid? Id { get; set; }
|
||||||
|
|
||||||
|
public bool IsAuthorizedView { get; set; }
|
||||||
|
|
||||||
|
public string Note { get; set; }=string.Empty;
|
||||||
|
|
||||||
|
public int? State { get; set; }
|
||||||
|
|
||||||
|
public TrialFileDto? TrialFileRecord { get; set; }
|
||||||
|
|
||||||
|
public TrialFileDto? HistoryFileRecord { get; set; }
|
||||||
|
|
||||||
|
public Guid TrialFileTypeId { get; set; }
|
||||||
|
|
||||||
|
public Guid TrialId { get; set; }
|
||||||
|
|
||||||
|
public int? TrianingCount { get; set; }
|
||||||
|
|
||||||
|
public DateOnly? TrianingDate { get; set; }
|
||||||
|
|
||||||
|
public string? TrianingState { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TrialTrianingRecordQuery : PageInput
|
||||||
|
{
|
||||||
|
public bool? IsAuthorizedView { get; set; }
|
||||||
|
|
||||||
|
public string? FileName { get; set; }
|
||||||
|
|
||||||
|
public Guid? TrialFileTypeId { get; set; }
|
||||||
|
|
||||||
|
public Guid? TrialId { get; set; }
|
||||||
|
|
||||||
|
public int? TrianingCount { get; set; }
|
||||||
|
|
||||||
|
public DateOnly? TrianingDateStartTime { get; set; }
|
||||||
|
|
||||||
|
public DateOnly? TrianingDateEndTime { get; set; }
|
||||||
|
|
||||||
|
public DateTime? UpdateStartTime { get; set; }
|
||||||
|
|
||||||
|
public DateTime? UpdateEndTime { get; set; }
|
||||||
|
|
||||||
|
public string? TrianingState { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
// 此代码由liquid模板自动生成 byzhouhang 20240909
|
||||||
|
// 生成时间 2025-02-21 07:47:30Z
|
||||||
|
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
using System;
|
||||||
|
using IRaCIS.Core.Infrastructure.Extention;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using IRaCIS.Core.Application.ViewModel;
|
||||||
|
namespace IRaCIS.Core.Application.Interfaces;
|
||||||
|
|
||||||
|
public interface ISysFileTypeService
|
||||||
|
{
|
||||||
|
|
||||||
|
Task<PageOutput<SysFileTypeView>> GetSysFileTypeList(SysFileTypeQuery inQuery);
|
||||||
|
|
||||||
|
Task<IResponseOutput> AddOrUpdateSysFileType(SysFileTypeAddOrEdit addOrEditSysFileType);
|
||||||
|
|
||||||
|
Task<IResponseOutput> DeleteSysFileType(Guid sysFileTypeId);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -27,6 +27,13 @@ namespace IRaCIS.Core.Application.Contracts
|
|||||||
Task<PageOutput<UnionDocumentWithConfirmInfoView>> getWaitSignSysDocList(SystemDocumentQuery querySystemDocument);
|
Task<PageOutput<UnionDocumentWithConfirmInfoView>> getWaitSignSysDocList(SystemDocumentQuery querySystemDocument);
|
||||||
|
|
||||||
|
|
||||||
|
Task<PageOutput<SystemDocumentAttachmentView>> GetSystemDocumentAttachmentList(SystemDocumentAttachmentQuery inQuery);
|
||||||
|
|
||||||
|
Task<IResponseOutput> AddOrUpdateSystemDocumentAttachment(SystemDocumentAttachmentAddOrEdit addOrEditSystemDocumentAttachment);
|
||||||
|
|
||||||
|
Task<IResponseOutput> DeleteSystemDocumentAttachment(Guid systemDocumentAttachmentId);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
// 此代码由liquid模板自动生成 byzhouhang 20240909
|
||||||
|
// 生成时间 2025-02-21 07:47:30Z
|
||||||
|
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
using System;
|
||||||
|
using IRaCIS.Core.Infrastructure.Extention;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using IRaCIS.Core.Application.ViewModel;
|
||||||
|
namespace IRaCIS.Core.Application.Interfaces;
|
||||||
|
|
||||||
|
public interface ITrialFileTypeService
|
||||||
|
{
|
||||||
|
|
||||||
|
Task<PageOutput<TrialFileTypeView>> GetTrialFileTypeList(TrialFileTypeQuery inQuery);
|
||||||
|
|
||||||
|
Task<IResponseOutput> AddOrUpdateTrialFileType(TrialFileTypeAddOrEdit addOrEditTrialFileType);
|
||||||
|
|
||||||
|
Task<IResponseOutput> DeleteTrialFileType(Guid trialFileTypeId);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
// 此代码由liquid模板自动生成 byzhouhang 20240909
|
||||||
|
// 生成时间 2025-02-21 07:47:30Z
|
||||||
|
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
using System;
|
||||||
|
using IRaCIS.Core.Infrastructure.Extention;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using IRaCIS.Core.Application.ViewModel;
|
||||||
|
namespace IRaCIS.Core.Application.Interfaces;
|
||||||
|
|
||||||
|
public interface ITrialFinalRecordService
|
||||||
|
{
|
||||||
|
|
||||||
|
Task<PageOutput<TrialFinalRecordView>> GetTrialFinalRecordList(TrialFinalRecordQuery inQuery);
|
||||||
|
|
||||||
|
Task<IResponseOutput> AddOrUpdateTrialFinalRecord(TrialFinalRecordAddOrEdit addOrEditTrialFinalRecord);
|
||||||
|
|
||||||
|
Task<IResponseOutput> DeleteTrialFinalRecord(Guid trialFinalRecordId);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
// 此代码由liquid模板自动生成 byzhouhang 20240909
|
||||||
|
// 生成时间 2025-02-21 07:47:30Z
|
||||||
|
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
using System;
|
||||||
|
using IRaCIS.Core.Infrastructure.Extention;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using IRaCIS.Core.Application.ViewModel;
|
||||||
|
namespace IRaCIS.Core.Application.Interfaces;
|
||||||
|
|
||||||
|
public interface ITrialNormalRecordService
|
||||||
|
{
|
||||||
|
|
||||||
|
Task<PageOutput<TrialNormalRecordView>> GetTrialNormalRecordList(TrialNormalRecordQuery inQuery);
|
||||||
|
|
||||||
|
Task<IResponseOutput> AddOrUpdateTrialNormalRecord(TrialNormalRecordAddOrEdit addOrEditTrialNormalRecord);
|
||||||
|
|
||||||
|
Task<IResponseOutput> DeleteTrialNormalRecord(Guid trialNormalRecordId);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
// 此代码由liquid模板自动生成 byzhouhang 20240909
|
||||||
|
// 生成时间 2025-02-21 07:47:30Z
|
||||||
|
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
using System;
|
||||||
|
using IRaCIS.Core.Infrastructure.Extention;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using IRaCIS.Core.Application.ViewModel;
|
||||||
|
namespace IRaCIS.Core.Application.Interfaces;
|
||||||
|
|
||||||
|
public interface ITrialTrianingRecordService
|
||||||
|
{
|
||||||
|
|
||||||
|
Task<PageOutput<TrialTrianingRecordView>> GetTrialTrianingRecordList(TrialTrianingRecordQuery inQuery);
|
||||||
|
|
||||||
|
Task<IResponseOutput> AddOrUpdateTrialTrianingRecord(TrialTrianingRecordAddOrEdit addOrEditTrialTrianingRecord);
|
||||||
|
|
||||||
|
Task<IResponseOutput> DeleteTrialTrianingRecord(Guid trialTrianingRecordId);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,88 @@
|
|||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
// 此代码由liquid模板自动生成 byzhouhang 20240909
|
||||||
|
// 生成时间 2025-02-21 07:47:24Z
|
||||||
|
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
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;
|
||||||
|
namespace IRaCIS.Core.Application.Service;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 系统文件类型
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="_sysFileTypeRepository"></param>
|
||||||
|
/// <param name="_mapper"></param>
|
||||||
|
/// <param name="_userInfo"></param>
|
||||||
|
/// <param name="_localizer"></param>
|
||||||
|
[ApiExplorerSettings(GroupName = "FileRecord")]
|
||||||
|
|
||||||
|
public class SysFileTypeService(IRepository<SysFileType> _sysFileTypeRepository, IRepository<TrialFileType> _trialFileTypeRepository,
|
||||||
|
IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer) : BaseService, ISysFileTypeService
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<PageOutput<SysFileTypeView>> GetSysFileTypeList(SysFileTypeQuery inQuery)
|
||||||
|
{
|
||||||
|
|
||||||
|
var sysFileTypeQueryable = _sysFileTypeRepository
|
||||||
|
.WhereIf(inQuery.ArchiveTypeEnum != null, t => t.ArchiveTypeEnum == inQuery.ArchiveTypeEnum)
|
||||||
|
.WhereIf(inQuery.SysTemplateTypeEnum != null, t => t.SysTemplateTypeEnum == inQuery.SysTemplateTypeEnum)
|
||||||
|
.WhereIf(inQuery.IsConfirmRecord != null, t => t.IsConfirmRecord == inQuery.IsConfirmRecord)
|
||||||
|
.WhereIf(inQuery.SubIdentificationEnum != null, t => t.SubIdentificationEnum == inQuery.SubIdentificationEnum)
|
||||||
|
.WhereIf(inQuery.IsEnable != null, t => t.IsEnable == inQuery.IsEnable)
|
||||||
|
.WhereIf(inQuery.Name.IsNotNullOrEmpty(), t => t.Name.Contains(inQuery.Name))
|
||||||
|
.WhereIf(inQuery.NameCN.IsNotNullOrEmpty(), t => t.NameCN.Contains(inQuery.NameCN))
|
||||||
|
.ProjectTo<SysFileTypeView>(_mapper.ConfigurationProvider);
|
||||||
|
|
||||||
|
var defalutSortArray = new string[] { nameof(SysFileTypeView.ArchiveTypeEnum), nameof(SysFileTypeView.ShowOrder)};
|
||||||
|
|
||||||
|
var pageList = await sysFileTypeQueryable.ToPagedListAsync(inQuery, defalutSortArray);
|
||||||
|
|
||||||
|
return pageList;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public async Task<IResponseOutput> AddOrUpdateSysFileType(SysFileTypeAddOrEdit addOrEditSysFileType)
|
||||||
|
{
|
||||||
|
var verifyExp = new EntityVerifyExp<SysFileType>()
|
||||||
|
{
|
||||||
|
VerifyExp = u => u.IsEnable == addOrEditSysFileType.IsEnable && (u.Name == addOrEditSysFileType.Name || u.NameCN == addOrEditSysFileType.NameCN),
|
||||||
|
|
||||||
|
// "当前类型启用的文件类型名称重复"
|
||||||
|
VerifyMsg = _localizer["SysFileType_NameRepeat"],
|
||||||
|
|
||||||
|
IsVerify = addOrEditSysFileType.IsEnable == false
|
||||||
|
};
|
||||||
|
|
||||||
|
var entity = await _sysFileTypeRepository.InsertOrUpdateAsync(addOrEditSysFileType, true, verifyExp);
|
||||||
|
|
||||||
|
//启用的才进行更新
|
||||||
|
if (addOrEditSysFileType.Id != null && addOrEditSysFileType.IsEnable)
|
||||||
|
{
|
||||||
|
await _trialFileTypeRepository.BatchUpdateNoTrackingAsync(t => t.SysFileTypeId == addOrEditSysFileType.Id, u => new TrialFileType() { Name = addOrEditSysFileType.Name, NameCN = addOrEditSysFileType.NameCN,ShowOrder=addOrEditSysFileType.ShowOrder });
|
||||||
|
}
|
||||||
|
|
||||||
|
return ResponseOutput.Ok(entity.Id.ToString());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[HttpDelete("{sysFileTypeId:guid}")]
|
||||||
|
public async Task<IResponseOutput> DeleteSysFileType(Guid sysFileTypeId)
|
||||||
|
{
|
||||||
|
var success = await _sysFileTypeRepository.DeleteFromQueryAsync(t => t.Id == sysFileTypeId, true);
|
||||||
|
return ResponseOutput.Ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,27 +1,82 @@
|
|||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
// 此代码由T4模板自动生成 byzhouhang 20210918
|
// 此代码由T4模板自动生成 byzhouhang 20210918
|
||||||
// 生成时间 2022-01-05 09:17:03
|
// 生成时间 2022-01-05 09:17:03
|
||||||
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
|
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
|
|
||||||
using IRaCIS.Core.Application.Contracts;
|
using IRaCIS.Core.Application.Contracts;
|
||||||
|
using IRaCIS.Core.Domain.Models;
|
||||||
|
using IRaCIS.Core.Domain;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using UserRole = IRaCIS.Core.Domain.Models.UserRole;
|
using UserRole = IRaCIS.Core.Domain.Models.UserRole;
|
||||||
|
using IRaCIS.Core.Application.MassTransit.Consumer;
|
||||||
|
using MassTransit.Mediator;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
namespace IRaCIS.Core.Application.Services
|
namespace IRaCIS.Core.Application.Services
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// SystemDocumentService
|
/// SystemDocumentService
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[ApiExplorerSettings(GroupName = "Trial")]
|
[ApiExplorerSettings(GroupName = "Trial")]
|
||||||
public class SystemDocumentService(IRepository<SystemDocument> _systemDocumentRepository,
|
public class SystemDocumentService(IRepository<SystemDocument> _systemDocumentRepository,
|
||||||
IRepository<UserRole> _userRoleRepository,
|
IRepository<UserRole> _userRoleRepository,
|
||||||
|
IScopedMediator _mediatorScoped,
|
||||||
|
IRepository<SystemDocumentAttachment> _systemDocumentAttachmentRepository,
|
||||||
IRepository<IdentityUser> _identityUserRepository,
|
IRepository<IdentityUser> _identityUserRepository,
|
||||||
|
IServiceScopeFactory serviceScopeFactory,
|
||||||
IRepository<SystemDocConfirmedIdentityUser> _systemDocConfirmedUserRepository, IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer) : BaseService, ISystemDocumentService
|
IRepository<SystemDocConfirmedIdentityUser> _systemDocConfirmedUserRepository, IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer) : BaseService, ISystemDocumentService
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取系统文档附件
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="inQuery"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<PageOutput<SystemDocumentAttachmentView>> GetSystemDocumentAttachmentList(SystemDocumentAttachmentQuery inQuery)
|
||||||
|
{
|
||||||
|
|
||||||
|
var systemDocumentAttachmentQueryable = _systemDocumentAttachmentRepository
|
||||||
|
.WhereIf(inQuery.SystemDocumentId != null, t => t.SystemDocumentId == inQuery.SystemDocumentId)
|
||||||
|
.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);
|
||||||
|
|
||||||
|
return pageList;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 新增或编辑系统文档附件
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="addOrEditSystemDocumentAttachment"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task<IResponseOutput> AddOrUpdateSystemDocumentAttachment(SystemDocumentAttachmentAddOrEdit addOrEditSystemDocumentAttachment)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var entity = await _systemDocumentAttachmentRepository.InsertOrUpdateAsync(addOrEditSystemDocumentAttachment, true);
|
||||||
|
|
||||||
|
return ResponseOutput.Ok(entity.Id.ToString());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 删除系统文档附件
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="systemDocumentAttachmentId"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpDelete("{systemDocumentAttachmentId:guid}")]
|
||||||
|
public async Task<IResponseOutput> DeleteSystemDocumentAttachment(Guid systemDocumentAttachmentId)
|
||||||
|
{
|
||||||
|
var success = await _systemDocumentAttachmentRepository.DeleteFromQueryAsync(t => t.Id == systemDocumentAttachmentId, true);
|
||||||
|
return ResponseOutput.Ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -35,7 +90,11 @@ namespace IRaCIS.Core.Application.Services
|
|||||||
var systemDocumentQueryable = _systemDocumentRepository.AsQueryable(true)
|
var systemDocumentQueryable = _systemDocumentRepository.AsQueryable(true)
|
||||||
.WhereIf(!string.IsNullOrEmpty(inQuery.Name), t => t.Name.Contains(inQuery.Name))
|
.WhereIf(!string.IsNullOrEmpty(inQuery.Name), t => t.Name.Contains(inQuery.Name))
|
||||||
.WhereIf(inQuery.FileTypeId != null, t => t.FileTypeId == inQuery.FileTypeId)
|
.WhereIf(inQuery.FileTypeId != null, t => t.FileTypeId == inQuery.FileTypeId)
|
||||||
.WhereIf(inQuery.IsDeleted != null, t => t.IsDeleted == inQuery.IsDeleted)
|
.WhereIf(inQuery.DocUserSignType != null, t => t.DocUserSignType == inQuery.DocUserSignType)
|
||||||
|
.WhereIf(inQuery.BeginCreateTime != null, t => t.CreateTime >= inQuery.BeginCreateTime)
|
||||||
|
.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)
|
||||||
.ProjectTo<SystemDocumentView>(_mapper.ConfigurationProvider, new { isEn_Us = _userInfo.IsEn_Us, userId = _userInfo.UserRoleId });
|
.ProjectTo<SystemDocumentView>(_mapper.ConfigurationProvider, new { isEn_Us = _userInfo.IsEn_Us, userId = _userInfo.UserRoleId });
|
||||||
|
|
||||||
return await systemDocumentQueryable.ToPagedListAsync(inQuery);
|
return await systemDocumentQueryable.ToPagedListAsync(inQuery);
|
||||||
@@ -71,6 +130,11 @@ namespace IRaCIS.Core.Application.Services
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 保存修改前的状态和需要确认的用户类型列表
|
||||||
|
bool beforeIsPublish = document.IsPublish;
|
||||||
|
bool beforeIsDeleted = document.IsDeleted;
|
||||||
|
var beforeUserTypeIds = document.NeedConfirmedUserTypeList.Select(x => x.NeedConfirmUserTypeId).ToList();
|
||||||
|
|
||||||
_mapper.Map(addOrEditSystemDocument, document);
|
_mapper.Map(addOrEditSystemDocument, document);
|
||||||
|
|
||||||
#region 之前区分路径文件夹 现在不区分废弃
|
#region 之前区分路径文件夹 现在不区分废弃
|
||||||
@@ -94,9 +158,39 @@ namespace IRaCIS.Core.Application.Services
|
|||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
var success = await _systemDocumentRepository.SaveChangesAsync();
|
var success = await _systemDocumentRepository.SaveChangesAsync();
|
||||||
|
|
||||||
|
// 检查是否需要发送邮件给新增的角色
|
||||||
|
if (beforeIsPublish && document.IsPublish && !beforeIsDeleted && !document.IsDeleted)
|
||||||
|
{
|
||||||
|
// 找出新增的用户角色ID
|
||||||
|
var newUserTypeIds = addOrEditSystemDocument.NeedConfirmedUserTypeIdList
|
||||||
|
.Where(id => !beforeUserTypeIds.Contains(id))
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
if (newUserTypeIds.Any()&& newUserTypeIds.Count()>0)
|
||||||
|
{
|
||||||
|
// 发送邮件给新增的角色
|
||||||
|
Console.WriteLine("开始 发送系统文档更新邮件给新增角色");
|
||||||
|
Console.WriteLine(string.Join(",", newUserTypeIds));
|
||||||
|
|
||||||
|
Task.Run(async () =>
|
||||||
|
{
|
||||||
|
// 创建独立作用域
|
||||||
|
using (var scope = serviceScopeFactory.CreateScope())
|
||||||
|
{
|
||||||
|
// 从新作用域解析服务
|
||||||
|
var mediator = scope.ServiceProvider.GetRequiredService<IMediator>();
|
||||||
|
// 只发送给新增的角色
|
||||||
|
await mediator.Publish(new SystemDocumentPublishEvent {
|
||||||
|
Ids = new List<Guid> { document.Id },
|
||||||
|
NewUserTypeIds = newUserTypeIds
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return ResponseOutput.Ok(document.Id.ToString());
|
return ResponseOutput.Ok(document.Id.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,6 +198,51 @@ namespace IRaCIS.Core.Application.Services
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 发布系统文档
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<IResponseOutput> PublishSystemDocument(PublishSystemDocumentInDto inDto)
|
||||||
|
{
|
||||||
|
await _systemDocumentRepository.BatchUpdateNoTrackingAsync(x => inDto.Ids.Contains(x.Id), x => new SystemDocument()
|
||||||
|
{
|
||||||
|
IsPublish = true,
|
||||||
|
IsDeleted = false,
|
||||||
|
});
|
||||||
|
|
||||||
|
Console.WriteLine("开始 发布系统文档");
|
||||||
|
|
||||||
|
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>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<IResponseOutput> OutLineSystemDocument(PublishSystemDocumentInDto inDto)
|
||||||
|
{
|
||||||
|
await _systemDocumentRepository.UpdatePartialFromQueryAsync(x => inDto.Ids.Contains(x.Id), x => new SystemDocument()
|
||||||
|
{
|
||||||
|
IsDeleted = true,
|
||||||
|
});
|
||||||
|
var result = await _systemDocumentRepository.SaveChangesAsync();
|
||||||
|
return ResponseOutput.Result(result);
|
||||||
|
}
|
||||||
|
|
||||||
[HttpDelete("{systemDocumentId:guid}")]
|
[HttpDelete("{systemDocumentId:guid}")]
|
||||||
public async Task<IResponseOutput> AbandonSystemDocumentAsync(Guid systemDocumentId)
|
public async Task<IResponseOutput> AbandonSystemDocumentAsync(Guid systemDocumentId)
|
||||||
{
|
{
|
||||||
@@ -160,9 +299,12 @@ namespace IRaCIS.Core.Application.Services
|
|||||||
|
|
||||||
select new UnionDocumentWithConfirmInfoView()
|
select new UnionDocumentWithConfirmInfoView()
|
||||||
{
|
{
|
||||||
|
AttachmentCount=sysDoc.SystemDocumentAttachmentList.Where(z=>!z.OffLine).Count(),
|
||||||
IsSystemDoc = true,
|
IsSystemDoc = true,
|
||||||
|
CurrentStaffTrainDays=sysDoc.CurrentStaffTrainDays,
|
||||||
|
NewStaffTrainDays = sysDoc.NewStaffTrainDays,
|
||||||
Id = sysDoc.Id,
|
Id = sysDoc.Id,
|
||||||
|
UserCreateTime= user.CreateTime,
|
||||||
CreateTime = sysDoc.CreateTime,
|
CreateTime = sysDoc.CreateTime,
|
||||||
IsDeleted = sysDoc.IsDeleted,
|
IsDeleted = sysDoc.IsDeleted,
|
||||||
SignViewMinimumMinutes = sysDoc.SignViewMinimumMinutes,
|
SignViewMinimumMinutes = sysDoc.SignViewMinimumMinutes,
|
||||||
@@ -178,18 +320,18 @@ namespace IRaCIS.Core.Application.Services
|
|||||||
RealName = user.FullName,
|
RealName = user.FullName,
|
||||||
UserName = user.UserName,
|
UserName = user.UserName,
|
||||||
|
|
||||||
DocTypeCode=sysDoc.FileType.Code
|
DocTypeCode = sysDoc.FileType.Code
|
||||||
|
|
||||||
//UserTypeId = user.UserTypeId,
|
//UserTypeId = user.UserTypeId,
|
||||||
//UserTypeShortName = user.UserTypeRole.UserTypeShortName
|
//UserTypeShortName = user.UserTypeRole.UserTypeShortName
|
||||||
};
|
};
|
||||||
|
|
||||||
var list = await query
|
var list = await query
|
||||||
//过滤掉删除的,并且没有签名的
|
//过滤掉删除的,并且没有签名的
|
||||||
.Where(t => !(t.IsDeleted == true && t.ConfirmTime == null))
|
.Where(t => !(t.IsDeleted == true && t.ConfirmTime == null))
|
||||||
.WhereIf(inQuery.IsSigned == true, t => t.ConfirmTime != null)
|
.WhereIf(inQuery.IsSigned == true, t => t.ConfirmTime != null)
|
||||||
.WhereIf(inQuery.IsSigned == false, t => t.ConfirmTime == null)
|
.WhereIf(inQuery.IsSigned == false, t => t.ConfirmTime == null)
|
||||||
.ToPagedListAsync(inQuery,nameof(UnionDocumentWithConfirmInfoView.DocTypeCode));
|
.ToPagedListAsync(inQuery, nameof(UnionDocumentWithConfirmInfoView.DocTypeCode));
|
||||||
|
|
||||||
|
|
||||||
return list;
|
return list;
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ using IRaCIS.Core.Application.Contracts;
|
|||||||
using IRaCIS.Core.Application.Filter;
|
using IRaCIS.Core.Application.Filter;
|
||||||
using IRaCIS.Core.Domain.Models;
|
using IRaCIS.Core.Domain.Models;
|
||||||
using IRaCIS.Core.Domain.Share;
|
using IRaCIS.Core.Domain.Share;
|
||||||
|
using Microsoft.AspNetCore.Identity;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using NPOI.SS.Formula.Functions;
|
using NPOI.SS.Formula.Functions;
|
||||||
@@ -29,6 +30,7 @@ namespace IRaCIS.Core.Application.Services
|
|||||||
IRepository<SystemDocument> _systemDocumentRepository,
|
IRepository<SystemDocument> _systemDocumentRepository,
|
||||||
IRepository<TrialIdentityUser> _trialIdentityUserRepository,
|
IRepository<TrialIdentityUser> _trialIdentityUserRepository,
|
||||||
IRepository<TrialUserRole> _trialUserRoleRepository,
|
IRepository<TrialUserRole> _trialUserRoleRepository,
|
||||||
|
IRepository<IdentityUser> _identityUserRepository,
|
||||||
IRepository<TrialDocConfirmedIdentityUser> _trialDocConfirmedUserRepository,
|
IRepository<TrialDocConfirmedIdentityUser> _trialDocConfirmedUserRepository,
|
||||||
IRepository<ReadingQuestionCriterionTrial> _readingQuestionCriterionTrialRepository, IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer) : BaseService, ITrialDocumentService
|
IRepository<ReadingQuestionCriterionTrial> _readingQuestionCriterionTrialRepository, IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer) : BaseService, ITrialDocumentService
|
||||||
{
|
{
|
||||||
@@ -241,7 +243,6 @@ namespace IRaCIS.Core.Application.Services
|
|||||||
select new UnionDocumentWithConfirmInfoView()
|
select new UnionDocumentWithConfirmInfoView()
|
||||||
{
|
{
|
||||||
IsSystemDoc = true,
|
IsSystemDoc = true,
|
||||||
|
|
||||||
Id = sysDoc.Id,
|
Id = sysDoc.Id,
|
||||||
CreateTime = sysDoc.CreateTime,
|
CreateTime = sysDoc.CreateTime,
|
||||||
IsDeleted = sysDoc.IsDeleted,
|
IsDeleted = sysDoc.IsDeleted,
|
||||||
@@ -409,6 +410,21 @@ namespace IRaCIS.Core.Application.Services
|
|||||||
|
|
||||||
|
|
||||||
var result = await unionQuery.ToPagedListAsync(inQuery);
|
var result = await unionQuery.ToPagedListAsync(inQuery);
|
||||||
|
|
||||||
|
//Concat 不能用导航属性
|
||||||
|
var sysids = result.CurrentPageData.Where(t => t.IsSystemDoc == true).Select(t => t.Id).ToList();
|
||||||
|
|
||||||
|
var sysDataList = await _systemDocumentRepository.Where(x => sysids.Contains(x.Id)).Include(x => x.SystemDocumentAttachmentList).ToListAsync();
|
||||||
|
result.CurrentPageData.ForEach(x =>
|
||||||
|
{
|
||||||
|
if (sysDataList.Any(y => y.Id == x.Id))
|
||||||
|
{
|
||||||
|
x.AttachmentCount = sysDataList.Where(y => y.Id == x.Id).Select(x => x.SystemDocumentAttachmentList.Where(z => !z.OffLine).Count()).FirstOrDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region 临时方案
|
#region 临时方案
|
||||||
@@ -474,11 +490,11 @@ namespace IRaCIS.Core.Application.Services
|
|||||||
from trialDoc in _trialDocumentRepository.AsQueryable(false).Where(t => t.TrialId == inQuery.TrialId)
|
from trialDoc in _trialDocumentRepository.AsQueryable(false).Where(t => t.TrialId == inQuery.TrialId)
|
||||||
.Where(t => inQuery.UserTypeId != null ? t.NeedConfirmedUserTypeList.Any(t => t.NeedConfirmUserTypeId == inQuery.UserTypeId) : true)
|
.Where(t => inQuery.UserTypeId != null ? t.NeedConfirmedUserTypeList.Any(t => t.NeedConfirmUserTypeId == inQuery.UserTypeId) : true)
|
||||||
from trialUser in _trialIdentityUserRepository.AsQueryable(false).Where(t => t.TrialId == inQuery.TrialId
|
from trialUser in _trialIdentityUserRepository.AsQueryable(false).Where(t => t.TrialId == inQuery.TrialId
|
||||||
&& t.TrialUserRoleList.AsQueryable().Any(t => trialDoc.NeedConfirmedUserTypeList.Any(c => c.NeedConfirmUserTypeId == t.UserRole.UserTypeId))
|
&& t.TrialUserRoleList.AsQueryable().Any(t => trialDoc.NeedConfirmedUserTypeList.Any(c => c.NeedConfirmUserTypeId == t.UserRole.UserTypeId))
|
||||||
)
|
)
|
||||||
.Where(t => inQuery.UserId != null ? t.IdentityUserId == inQuery.UserId : true)
|
.Where(t => inQuery.UserId != null ? t.IdentityUserId == inQuery.UserId : true)
|
||||||
.Where(t => inQuery.UserTypeId != null ? t.TrialUserRoleList.Any(t => t.UserRole.UserTypeId == inQuery.UserTypeId) : true)
|
.Where(t => inQuery.UserTypeId != null ? t.TrialUserRoleList.Any(t => t.UserRole.UserTypeId == inQuery.UserTypeId) : true)
|
||||||
|
|
||||||
|
|
||||||
join confirm in _trialDocConfirmedUserRepository.Where(t => t.TrialDocument.TrialId == inQuery.TrialId) on
|
join confirm in _trialDocConfirmedUserRepository.Where(t => t.TrialDocument.TrialId == inQuery.TrialId) on
|
||||||
new { trialUser.IdentityUserId, TrialDocumentId = trialDoc.Id } equals new { IdentityUserId = confirm.ConfirmUserId, confirm.TrialDocumentId } into cc
|
new { trialUser.IdentityUserId, TrialDocumentId = trialDoc.Id } equals new { IdentityUserId = confirm.ConfirmUserId, confirm.TrialDocumentId } into cc
|
||||||
@@ -557,10 +573,27 @@ namespace IRaCIS.Core.Application.Services
|
|||||||
.WhereIf(inQuery.FileTypeId != null, t => t.FileTypeId == inQuery.FileTypeId)
|
.WhereIf(inQuery.FileTypeId != null, t => t.FileTypeId == inQuery.FileTypeId)
|
||||||
.WhereIf(inQuery.IsConfirmed == true, t => t.ConfirmTime != null)
|
.WhereIf(inQuery.IsConfirmed == true, t => t.ConfirmTime != null)
|
||||||
.WhereIf(inQuery.IsConfirmed == false, t => t.ConfirmTime == null)
|
.WhereIf(inQuery.IsConfirmed == false, t => t.ConfirmTime == null)
|
||||||
|
.WhereIf(inQuery.StartConfirmTime != null, t => t.ConfirmTime >= inQuery.StartConfirmTime.Value)
|
||||||
|
.WhereIf(inQuery.EndConfirmTime != null, t => t.ConfirmTime <= inQuery.EndConfirmTime.Value)
|
||||||
|
.WhereIf(inQuery.BeginCreateTime != null, t => t.CreateTime >= inQuery.BeginCreateTime)
|
||||||
|
.WhereIf(inQuery.EndCreateTime != null, t => t.CreateTime <= inQuery.EndCreateTime)
|
||||||
|
.WhereIf(!string.IsNullOrEmpty(inQuery.UserName), t => t.UserName.Contains(inQuery.UserName))
|
||||||
.WhereIf(inQuery.IsDeleted != null, t => t.IsDeleted == inQuery.IsDeleted);
|
.WhereIf(inQuery.IsDeleted != null, t => t.IsDeleted == inQuery.IsDeleted);
|
||||||
|
|
||||||
var result = await unionQuery.ToPagedListAsync(inQuery);
|
var result = await unionQuery.ToPagedListAsync(inQuery);
|
||||||
|
|
||||||
|
//Concat 不能用导航属性
|
||||||
|
var sysids = result.CurrentPageData.Where(t => t.IsSystemDoc == true).Select(t => t.Id).ToList();
|
||||||
|
|
||||||
|
var sysDataList = await _systemDocumentRepository.Where(x => sysids.Contains(x.Id)).Include(x => x.SystemDocumentAttachmentList).ToListAsync();
|
||||||
|
result.CurrentPageData.ForEach(x =>
|
||||||
|
{
|
||||||
|
if (sysDataList.Any(y => y.Id == x.Id))
|
||||||
|
{
|
||||||
|
x.AttachmentCount = sysDataList.Where(y => y.Id == x.Id).Select(x => x.SystemDocumentAttachmentList.Where(z => !z.OffLine).Count()).FirstOrDefault();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
#region 处理文档 需要签署的角色类型 和每个人的角色信息
|
#region 处理文档 需要签署的角色类型 和每个人的角色信息
|
||||||
|
|
||||||
var trialDocIdList = result.CurrentPageData.Where(t => t.IsSystemDoc == false).Select(t => t.Id).ToList();
|
var trialDocIdList = result.CurrentPageData.Where(t => t.IsSystemDoc == false).Select(t => t.Id).ToList();
|
||||||
@@ -746,6 +779,112 @@ namespace IRaCIS.Core.Application.Services
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取系统签署文档签署人下拉框
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task<IResponseOutput> GetSysDocSignUserList()
|
||||||
|
{
|
||||||
|
var list = _systemDocConfirmedUserRepository.Where(t => t.ConfirmTime != null).Select(t => new { t.ConfirmUserId, t.ConfirmUser.UserName, t.ConfirmUser.FullName }).Distinct().ToList();
|
||||||
|
|
||||||
|
return ResponseOutput.Ok(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<IResponseOutput<PageOutput<UnionDocumentWithConfirmInfoView>>> GetSysDocumentConfirmList(SystemDocQuery inQuery)
|
||||||
|
{
|
||||||
|
|
||||||
|
var isInternal = _userInfo.IsZhiZhun;
|
||||||
|
|
||||||
|
var systemDocQuery =
|
||||||
|
from sysDoc in _systemDocumentRepository.AsQueryable(false)
|
||||||
|
.Where(t => inQuery.UserTypeId != null ? t.NeedConfirmedUserTypeList.Any(t => t.NeedConfirmUserTypeId == inQuery.UserTypeId) : true)
|
||||||
|
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)))
|
||||||
|
.Where(t => inQuery.UserId != null ? t.Id == inQuery.UserId : true)
|
||||||
|
.Where(t => inQuery.UserTypeId != null ? t.UserRoleList.Any(t => t.UserTypeId == inQuery.UserTypeId && t.IsUserRoleDisabled == false) : true)
|
||||||
|
join confirm in _systemDocConfirmedUserRepository.Where() on new { ConfirmUserId = identityUser.Id, SystemDocumentId = sysDoc.Id } equals new { confirm.ConfirmUserId, confirm.SystemDocumentId } into cc
|
||||||
|
from confirm in cc.DefaultIfEmpty()
|
||||||
|
select new UnionDocumentWithConfirmInfoView()
|
||||||
|
{
|
||||||
|
IsSystemDoc = true,
|
||||||
|
Id = sysDoc.Id,
|
||||||
|
CreateTime = sysDoc.CreateTime,
|
||||||
|
IsDeleted = sysDoc.IsDeleted,
|
||||||
|
SignViewMinimumMinutes = sysDoc.SignViewMinimumMinutes,
|
||||||
|
Name = sysDoc.Name,
|
||||||
|
Path = sysDoc.Path,
|
||||||
|
FileType = _userInfo.IsEn_Us ? sysDoc.FileType.Value : sysDoc.FileType.ValueCN,
|
||||||
|
FileTypeId = sysDoc.FileTypeId,
|
||||||
|
UpdateTime = sysDoc.UpdateTime,
|
||||||
|
//IsConfirmed = confirm.ConfirmTime != null,
|
||||||
|
|
||||||
|
ConfirmUserId = identityUser.Id,
|
||||||
|
ConfirmTime = confirm.ConfirmTime,
|
||||||
|
|
||||||
|
RealName = identityUser.FullName,
|
||||||
|
UserName = identityUser.UserName,
|
||||||
|
|
||||||
|
//UserTypeId = trialUser.UserRole.UserTypeId,
|
||||||
|
//UserTypeShortName = trialUser.UserRole.UserTypeRole.UserTypeShortName,
|
||||||
|
|
||||||
|
FullFilePath = sysDoc.Path
|
||||||
|
};
|
||||||
|
|
||||||
|
var unionQuery = systemDocQuery.IgnoreQueryFilters().Where(t => !(t.IsDeleted == true && t.ConfirmTime == null))
|
||||||
|
.WhereIf(!string.IsNullOrEmpty(inQuery.Name), t => t.Name.Contains(inQuery.Name))
|
||||||
|
.WhereIf(inQuery.FileTypeId != null, t => t.FileTypeId == inQuery.FileTypeId)
|
||||||
|
.WhereIf(inQuery.IsConfirmed == true, t => t.ConfirmTime != null)
|
||||||
|
.WhereIf(inQuery.IsConfirmed == false, t => t.ConfirmTime == null)
|
||||||
|
.WhereIf(inQuery.StartConfirmTime != null, t => t.ConfirmTime >= inQuery.StartConfirmTime.Value)
|
||||||
|
.WhereIf(inQuery.EndConfirmTime != null, t => t.ConfirmTime <= inQuery.EndConfirmTime.Value)
|
||||||
|
.WhereIf(inQuery.BeginCreateTime != null, t => t.CreateTime >= inQuery.BeginCreateTime)
|
||||||
|
.WhereIf(inQuery.EndCreateTime != null, t => t.CreateTime <= inQuery.EndCreateTime)
|
||||||
|
.WhereIf(!string.IsNullOrEmpty(inQuery.UserName), t => t.UserName.Contains(inQuery.UserName))
|
||||||
|
.WhereIf(inQuery.IsDeleted != null, t => t.IsDeleted == inQuery.IsDeleted)
|
||||||
|
.WhereIf(isInternal == false, t => t.ConfirmTime != null);
|
||||||
|
|
||||||
|
var result = await unionQuery.ToPagedListAsync(inQuery);
|
||||||
|
|
||||||
|
#region 处理文档 需要签署的角色类型 和每个人的角色信息
|
||||||
|
|
||||||
|
var trialDocIdList = result.CurrentPageData.Where(t => t.IsSystemDoc == false).Select(t => t.Id).ToList();
|
||||||
|
|
||||||
|
var sysDocIdList = result.CurrentPageData.Where(t => t.IsSystemDoc == true).Select(t => t.Id).ToList();
|
||||||
|
|
||||||
|
var identityUserIdList = result.CurrentPageData.Select(t => t.ConfirmUserId).Distinct().ToList();
|
||||||
|
|
||||||
|
|
||||||
|
var sysDocUserTypeList = _systemDocNeedConfirmedUserTypeRepository.Where(t => sysDocIdList.Contains(t.SystemDocumentId)).Select(t => new { t.SystemDocumentId, t.UserTypeRole.UserTypeShortName }).ToList();
|
||||||
|
|
||||||
|
var identityUserUserTypeList = _identityUserRepository.Where(t => identityUserIdList.Contains(t.Id)).IgnoreQueryFilters().Select(t => new { IdentityUserId = t.Id, UserTypeList = t.UserRoleList.Where(t => t.IsUserRoleDisabled == false).Select(c => c.UserTypeRole.UserTypeShortName).ToList() });
|
||||||
|
|
||||||
|
//Concat 不能用导航属性
|
||||||
|
var sysids = result.CurrentPageData.Where(t => t.IsSystemDoc == true).Select(t => t.Id).ToList();
|
||||||
|
|
||||||
|
var sysDataList = await _systemDocumentRepository.Where(x => sysids.Contains(x.Id)).Include(x => x.SystemDocumentAttachmentList).ToListAsync();
|
||||||
|
|
||||||
|
foreach (var item in result.CurrentPageData)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (sysDataList.Any(y => y.Id == item.Id))
|
||||||
|
{
|
||||||
|
item.AttachmentCount = sysDataList.Where(y => y.Id == item.Id).Select(x => x.SystemDocumentAttachmentList.Where(z => !z.OffLine).Count()).FirstOrDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item.IsSystemDoc)
|
||||||
|
{
|
||||||
|
item.DocNeedSignUserTypeList = sysDocUserTypeList.Where(t => t.SystemDocumentId == item.Id).Select(t => t.UserTypeShortName).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
item.IdentityUserTypeList = identityUserUserTypeList.Where(t => t.IdentityUserId == item.ConfirmUserId).SelectMany(c => c.UserTypeList).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
return ResponseOutput.Ok(result);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 项目下面的参与用户下拉
|
/// 项目下面的参与用户下拉
|
||||||
|
|||||||
@@ -0,0 +1,243 @@
|
|||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
// 此代码由liquid模板自动生成 byzhouhang 20240909
|
||||||
|
// 生成时间 2025-02-21 07:47:30Z
|
||||||
|
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
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 MassTransit;
|
||||||
|
using IRaCIS.Core.Infrastructure;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
|
namespace IRaCIS.Core.Application.Service;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 项目文件类型
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="_trialFileTypeRepository"></param>
|
||||||
|
/// <param name="_mapper"></param>
|
||||||
|
/// <param name="_userInfo"></param>
|
||||||
|
/// <param name="_localizer"></param>
|
||||||
|
[ApiExplorerSettings(GroupName = "FileRecord")]
|
||||||
|
public class TrialFileTypeService(IRepository<TrialFileType> _trialFileTypeRepository,
|
||||||
|
IOptionsMonitor<ServiceVerifyConfigOption> _verifyConfig,
|
||||||
|
IRepository<TrialFile> _trialFileRepository,
|
||||||
|
IRepository<SysFileType> _sysFileTypeRepository,
|
||||||
|
IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer) : BaseService, ITrialFileTypeService
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<PageOutput<TrialFileTypeView>> GetTrialFileTypeList(TrialFileTypeQuery inQuery)
|
||||||
|
{
|
||||||
|
|
||||||
|
var trialFileTypeQueryable = _trialFileTypeRepository
|
||||||
|
.Where(t => t.TrialId == inQuery.TrialId)
|
||||||
|
|
||||||
|
.WhereIf(inQuery.ArchiveTypeEnum != null, t => t.ArchiveTypeEnum == inQuery.ArchiveTypeEnum)
|
||||||
|
.WhereIf(inQuery.IsConfirmRecord != null, t => t.IsConfirmRecord == inQuery.IsConfirmRecord)
|
||||||
|
.WhereIf(inQuery.SubIdentificationEnum != null, t => t.SubIdentificationEnum == inQuery.SubIdentificationEnum)
|
||||||
|
.WhereIf(inQuery.IsEnable != null, t => t.IsEnable == inQuery.IsEnable)
|
||||||
|
.WhereIf(inQuery.Name.IsNotNullOrEmpty(), t => t.Name.Contains(inQuery.Name))
|
||||||
|
.WhereIf(inQuery.NameCN.IsNotNullOrEmpty(), t => t.NameCN.Contains(inQuery.NameCN))
|
||||||
|
|
||||||
|
.WhereIf(inQuery.IsSelfDefine != null, t => t.IsSelfDefine == inQuery.IsSelfDefine)
|
||||||
|
.ProjectTo<TrialFileTypeView>(_mapper.ConfigurationProvider);
|
||||||
|
|
||||||
|
var pageList = await trialFileTypeQueryable.ToPagedListAsync(inQuery);
|
||||||
|
|
||||||
|
return pageList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取项目文件类型下拉框
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="inQuery"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task<List<TrialFileTypeSelectView>> GetTrialFileTypeSelectList(TrialFileTypeSelectQuery inQuery)
|
||||||
|
{
|
||||||
|
var list = _trialFileTypeRepository
|
||||||
|
.Where(t => t.TrialId == inQuery.TrialId)
|
||||||
|
.WhereIf(inQuery.ArchiveTypeEnum != null, t => t.ArchiveTypeEnum == inQuery.ArchiveTypeEnum)
|
||||||
|
.WhereIf(inQuery.IsSelfDefine != null, t => t.IsSelfDefine == inQuery.IsSelfDefine)
|
||||||
|
.WhereIf(inQuery.IsEnable != null, t => t.IsEnable == inQuery.IsEnable)
|
||||||
|
.Select(t => new TrialFileTypeSelectView()
|
||||||
|
{
|
||||||
|
Id = t.Id,
|
||||||
|
IsEnable = t.IsEnable,
|
||||||
|
Name = _userInfo.IsEn_Us ? t.Name : t.NameCN,
|
||||||
|
IsSelfDefine = t.IsSelfDefine,
|
||||||
|
ArchiveTypeEnum = t.ArchiveTypeEnum,
|
||||||
|
}).ToList();
|
||||||
|
|
||||||
|
return list;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public async Task<IResponseOutput> AddOrUpdateTrialFileType(TrialFileTypeAddOrEdit addOrEditTrialFileType)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (await _trialFileTypeRepository.AnyAsync(u => u.TrialId == addOrEditTrialFileType.TrialId && u.Id != addOrEditTrialFileType.Id && u.IsEnable == addOrEditTrialFileType.IsEnable && (u.Name == addOrEditTrialFileType.Name || u.NameCN == addOrEditTrialFileType.NameCN)))
|
||||||
|
{
|
||||||
|
throw new BusinessValidationFailedException(_localizer["TrialFileType_NameRepeat"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
var entity = await _trialFileTypeRepository.InsertOrUpdateAsync(addOrEditTrialFileType, true);
|
||||||
|
|
||||||
|
|
||||||
|
return ResponseOutput.Ok(entity.Id.ToString());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[HttpDelete("{trialFileTypeId:guid}")]
|
||||||
|
public async Task<IResponseOutput> DeleteTrialFileType(Guid trialFileTypeId)
|
||||||
|
{
|
||||||
|
var success = await _trialFileTypeRepository.DeleteFromQueryAsync(t => t.Id == trialFileTypeId, true);
|
||||||
|
return ResponseOutput.Ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 复制系统数据到项目
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="inDto"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task<IResponseOutput> CopySystemFileTypeToTrial(CopySystemFileTypeToTrialInDto inDto)
|
||||||
|
{
|
||||||
|
if (!(await _trialFileTypeRepository.AnyAsync(x => x.TrialId == inDto.TrialId)))
|
||||||
|
{
|
||||||
|
var trialFileTypeList = await _sysFileTypeRepository
|
||||||
|
.Where(x=>x.SysTemplateTypeEnum== _verifyConfig.CurrentValue.TemplateType|| x.SysTemplateTypeEnum==SysTemplateType.Both)
|
||||||
|
.ProjectTo<TrialFileType>(_mapper.ConfigurationProvider)
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
trialFileTypeList.ForEach(x => {
|
||||||
|
x.TrialId = inDto.TrialId;
|
||||||
|
x.Id = NewId.NextGuid();
|
||||||
|
});
|
||||||
|
|
||||||
|
await _trialFileTypeRepository.AddRangeAsync(trialFileTypeList, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ResponseOutput.Ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取项目文件类型数据
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="inDto"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<GetTrialFileTypeDataOutDto> GetTrialFileTypeData(GetTrialFileTypeDataInDto inDto)
|
||||||
|
{
|
||||||
|
await this.CopySystemFileTypeToTrial(new CopySystemFileTypeToTrialInDto()
|
||||||
|
{
|
||||||
|
TrialId = inDto.TrialId
|
||||||
|
});
|
||||||
|
var trialFileTypeList = await _trialFileTypeRepository.Where(x => x.TrialId == inDto.TrialId)
|
||||||
|
.WhereIf(inDto.IsEnable, x => x.IsEnable)
|
||||||
|
.OrderBy(x => x.ShowOrder)
|
||||||
|
.ProjectTo<TrialFileTypeView>(_mapper.ConfigurationProvider)
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
List<TrialFileTypeData> result = new List<TrialFileTypeData>();
|
||||||
|
foreach (ArchiveType type in Enum.GetValues(typeof(ArchiveType)))
|
||||||
|
{
|
||||||
|
result.Add(new TrialFileTypeData()
|
||||||
|
{
|
||||||
|
ArchiveTypeEnum = type,
|
||||||
|
TrialFileTypeList = trialFileTypeList.Where(x => x.ArchiveTypeEnum == type).OrderBy(x => x.SysFileTypeId == null).ThenBy(x => x.ShowOrder).ToList()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return new GetTrialFileTypeDataOutDto() { TrialFileTypeDataList = result };
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 修改授权状态
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="inDto"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<IResponseOutput> SetAuthorizedView(SetAuthorizedViewInDto inDto)
|
||||||
|
{
|
||||||
|
await _trialFileTypeRepository.UpdatePartialFromQueryAsync(x => x.Id == inDto.Id, x => new TrialFileType() { IsEnable = inDto.IsEnable }, true);
|
||||||
|
return ResponseOutput.Ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 上传同意入项记录
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="inDto"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<IResponseOutput> UploadTrialFileTypeFile(UploadTrialFileTypeFileInDto inDto)
|
||||||
|
{
|
||||||
|
var trialFileType = await _trialFileTypeRepository.Where(x => x.Id == inDto.TrialFileTypeId).FirstNotNullAsync();
|
||||||
|
|
||||||
|
if (trialFileType.FileRecordId != null)
|
||||||
|
{
|
||||||
|
await _trialFileRepository.BatchDeleteNoTrackingAsync(x => x.Id == trialFileType.FileRecordId);
|
||||||
|
}
|
||||||
|
|
||||||
|
inDto.FileRecord.TrialFileTypeId = inDto.TrialFileTypeId;
|
||||||
|
var entity = await _trialFileRepository.InsertFromDTOAsync(inDto.FileRecord, true);
|
||||||
|
await _trialFileTypeRepository.UpdatePartialFromQueryAsync(x => x.Id == inDto.TrialFileTypeId, x => new TrialFileType()
|
||||||
|
{
|
||||||
|
|
||||||
|
FileRecordId = entity.Id
|
||||||
|
});
|
||||||
|
await _trialFileTypeRepository.SaveChangesAsync();
|
||||||
|
return ResponseOutput.Ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取入项记录
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="inDto"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<TrialFileDto> GetTrialFileTypeFile(GetTrialFileTypeFileInDto inDto)
|
||||||
|
{
|
||||||
|
var trialFileType = await _trialFileTypeRepository.Where(x => x.Id == inDto.TrialFileTypeId).FirstNotNullAsync();
|
||||||
|
if (trialFileType.FileRecordId == null)
|
||||||
|
{
|
||||||
|
return new TrialFileDto() { };
|
||||||
|
}
|
||||||
|
var file = await _trialFileRepository.Where(x => x.Id == trialFileType.FileRecordId).ProjectTo<TrialFileDto>(_mapper.ConfigurationProvider).FirstNotNullAsync();
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 删除入项记录
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="trialFileTypeId"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<IResponseOutput> DeleteTrialTypeFile(Guid trialFileTypeId)
|
||||||
|
{
|
||||||
|
var trialFileType = await _trialFileTypeRepository.Where(x => x.Id == trialFileTypeId).FirstNotNullAsync();
|
||||||
|
|
||||||
|
await _trialFileRepository.DeleteFromQueryAsync(x => x.Id == trialFileType.FileRecordId, true);
|
||||||
|
await _trialFileTypeRepository.UpdatePartialFromQueryAsync(x => x.Id == trialFileTypeId, x => new TrialFileType() { FileRecordId = null }, true);
|
||||||
|
return ResponseOutput.Ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,119 @@
|
|||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
// 此代码由liquid模板自动生成 byzhouhang 20240909
|
||||||
|
// 生成时间 2025-02-21 07:47:30Z
|
||||||
|
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
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 IRaCIS.Core.Infrastructure;
|
||||||
|
namespace IRaCIS.Core.Application.Service;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 项目定稿记录
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="_trialFinalRecordRepository"></param>
|
||||||
|
/// <param name="_mapper"></param>
|
||||||
|
/// <param name="_userInfo"></param>
|
||||||
|
/// <param name="_localizer"></param>
|
||||||
|
[ApiExplorerSettings(GroupName = "FileRecord")]
|
||||||
|
public class TrialFinalRecordService(IRepository<TrialFinalRecord> _trialFinalRecordRepository,
|
||||||
|
IRepository<TrialFile> _trialFileRepository,
|
||||||
|
IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer) : BaseService, ITrialFinalRecordService
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<PageOutput<TrialFinalRecordView>> GetTrialFinalRecordList(TrialFinalRecordQuery inDto)
|
||||||
|
{
|
||||||
|
|
||||||
|
var trialFinalRecordQueryable = _trialFinalRecordRepository
|
||||||
|
.Where(x=>x.TrialFileTypeId==inDto.TrialFileTypeId)
|
||||||
|
.WhereIf(inDto.Name.IsNotNullOrEmpty(),x=>x.Name.Contains(inDto.Name))
|
||||||
|
.WhereIf(inDto.Version.IsNotNullOrEmpty(), x => x.Version.Contains(inDto.Version))
|
||||||
|
.WhereIf(inDto.IsAuthorizedView!=null, x => x.IsAuthorizedView==inDto.IsAuthorizedView)
|
||||||
|
// .Include(x=>x.PDFFileRecord).Include(x => x.WordFileRecord).Include(x => x.SignFileRecord).Include(x => x.HistoryFileRecord)
|
||||||
|
.ProjectTo<TrialFinalRecordView>(_mapper.ConfigurationProvider);
|
||||||
|
|
||||||
|
var pageList = await trialFinalRecordQueryable.ToPagedListAsync(inDto);
|
||||||
|
|
||||||
|
return pageList;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 新增或者修改文档
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="inDto"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task<IResponseOutput> AddOrUpdateTrialFinalRecord(TrialFinalRecordAddOrEdit inDto)
|
||||||
|
{
|
||||||
|
// 在此处拷贝automapper 映射
|
||||||
|
if (inDto.PDFFileRecord != null) inDto.PDFFileRecord.TrialFileTypeId = inDto.TrialFileTypeId;
|
||||||
|
if (inDto.WordFileRecord != null) inDto.WordFileRecord.TrialFileTypeId = inDto.TrialFileTypeId;
|
||||||
|
if (inDto.SignFileRecord != null) inDto.SignFileRecord.TrialFileTypeId = inDto.TrialFileTypeId;
|
||||||
|
if (inDto.HistoryFileRecord != null) inDto.HistoryFileRecord.TrialFileTypeId = inDto.TrialFileTypeId;
|
||||||
|
|
||||||
|
|
||||||
|
if (await _trialFinalRecordRepository.AnyAsync(x => x.Id != inDto.Id && x.TrialFileTypeId == inDto.TrialFileTypeId && x.Name == inDto.Name && x.Version == inDto.Version))
|
||||||
|
{
|
||||||
|
throw new BusinessValidationFailedException(_localizer["TrialFinalRecord_NameRepeat"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inDto.Id != null)
|
||||||
|
{
|
||||||
|
var trialFinalRecord = await _trialFinalRecordRepository.Where(x => x.Id == inDto.Id.Value).FirstNotNullAsync();
|
||||||
|
|
||||||
|
List<Guid?> ids= new List<Guid?>() {
|
||||||
|
trialFinalRecord.WordFileRecordId,
|
||||||
|
trialFinalRecord.PDFFileRecordId,
|
||||||
|
trialFinalRecord.SignFileRecordId,
|
||||||
|
trialFinalRecord.HistoryFileRecordId
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
var fileIds = ids.Where(x => x != null).Select(x => (Guid)x).ToList();
|
||||||
|
await _trialFileRepository.BatchDeleteNoTrackingAsync(x => fileIds.Contains(x.Id));
|
||||||
|
}
|
||||||
|
var entity = await _trialFinalRecordRepository.InsertOrUpdateAsync(inDto, true);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return ResponseOutput.Ok(entity.Id.ToString());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 授权文档
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="inDto"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task<IResponseOutput> AuthorizedTrialFinalRecord(AuthorizedTrialFinalRecordInDto inDto)
|
||||||
|
{
|
||||||
|
await _trialFinalRecordRepository.UpdatePartialFromQueryAsync(t =>inDto.Ids.Contains(t.Id), t => new TrialFinalRecord() { IsAuthorizedView = inDto.IsAuthorizedView });
|
||||||
|
await _trialFinalRecordRepository.SaveChangesAsync();
|
||||||
|
return ResponseOutput.Ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 删除文档
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="trialFinalRecordId"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpDelete("{trialFinalRecordId:guid}")]
|
||||||
|
public async Task<IResponseOutput> DeleteTrialFinalRecord(Guid trialFinalRecordId)
|
||||||
|
{
|
||||||
|
var success = await _trialFinalRecordRepository.DeleteFromQueryAsync(t => t.Id == trialFinalRecordId, true);
|
||||||
|
return ResponseOutput.Ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,130 @@
|
|||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
// 此代码由liquid模板自动生成 byzhouhang 20240909
|
||||||
|
// 生成时间 2025-02-21 07:47:30Z
|
||||||
|
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
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;
|
||||||
|
namespace IRaCIS.Core.Application.Service;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 项目-一般文件记录
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="_trialNormalRecordRepository"></param>
|
||||||
|
/// <param name="_mapper"></param>
|
||||||
|
/// <param name="_userInfo"></param>
|
||||||
|
/// <param name="_localizer"></param>
|
||||||
|
[ApiExplorerSettings(GroupName = "FileRecord")]
|
||||||
|
public class TrialNormalRecordService(IRepository<TrialNormalRecord> _trialNormalRecordRepository,
|
||||||
|
IRepository<TrialFile> _trialFileRepository,
|
||||||
|
IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer) : BaseService, ITrialNormalRecordService
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<PageOutput<TrialNormalRecordView>> GetTrialNormalRecordList(TrialNormalRecordQuery inDto)
|
||||||
|
{
|
||||||
|
|
||||||
|
var trialNormalRecordQueryable = _trialNormalRecordRepository
|
||||||
|
.Where(x => x.TrialFileTypeId == inDto.TrialFileTypeId)
|
||||||
|
.WhereIf(inDto.IsAuthorizedView != null, x => x.IsAuthorizedView == inDto.IsAuthorizedView)
|
||||||
|
.WhereIf(inDto.FileName.IsNotNullOrEmpty(), x => x.TrialFileRecord.FileName.Contains(inDto.FileName))
|
||||||
|
.ProjectTo<TrialNormalRecordView>(_mapper.ConfigurationProvider);
|
||||||
|
|
||||||
|
var pageList = await trialNormalRecordQueryable.ToPagedListAsync(inDto);
|
||||||
|
|
||||||
|
return pageList;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public async Task<IResponseOutput> AddOrUpdateTrialNormalRecord(TrialNormalRecordAddOrEdit inDto)
|
||||||
|
{
|
||||||
|
if (inDto.TrialFileRecord != null) inDto.TrialFileRecord.TrialFileTypeId = inDto.TrialFileTypeId;
|
||||||
|
if (inDto.HistoryFileRecord != null) inDto.HistoryFileRecord.TrialFileTypeId = inDto.TrialFileTypeId;
|
||||||
|
|
||||||
|
|
||||||
|
if (inDto.Id != null)
|
||||||
|
{
|
||||||
|
var trialFinalRecord = await _trialNormalRecordRepository.Where(x => x.Id == inDto.Id.Value).FirstNotNullAsync();
|
||||||
|
|
||||||
|
List<Guid?> ids = new List<Guid?>() {
|
||||||
|
trialFinalRecord.TrialFileRecordId,
|
||||||
|
trialFinalRecord.HistoryFileRecordId,
|
||||||
|
};
|
||||||
|
|
||||||
|
var fileIds = ids.Where(x => x != null).Select(x => (Guid)x).ToList();
|
||||||
|
await _trialFileRepository.BatchDeleteNoTrackingAsync(x => fileIds.Contains(x.Id));
|
||||||
|
}
|
||||||
|
|
||||||
|
var entity = await _trialNormalRecordRepository.InsertOrUpdateAsync(inDto, true);
|
||||||
|
|
||||||
|
|
||||||
|
return ResponseOutput.Ok(entity.Id.ToString());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 批量新增一般文件记录
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="inDto"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<IResponseOutput> BatchAddTrialNormalRecord(BatchAddTrialNormalRecordInDto inDto)
|
||||||
|
{
|
||||||
|
foreach (var item in inDto.TrialNormalRecordList)
|
||||||
|
{
|
||||||
|
if (item.TrialFileRecord != null) item.TrialFileRecord.TrialFileTypeId = item.TrialFileTypeId;
|
||||||
|
if (item.HistoryFileRecord != null) item.HistoryFileRecord.TrialFileTypeId = item.TrialFileTypeId;
|
||||||
|
|
||||||
|
var entity = await _trialNormalRecordRepository.InsertFromDTOAsync(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
var result= await _trialNormalRecordRepository.SaveChangesAsync();
|
||||||
|
return ResponseOutput.Ok(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 授权文档
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="inDto"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task<IResponseOutput> AuthorizedTTrialNormalRecord(AuthorizedTrialFinalRecordInDto inDto)
|
||||||
|
{
|
||||||
|
await _trialNormalRecordRepository.UpdatePartialFromQueryAsync(t => inDto.Ids.Contains(t.Id), t => new TrialNormalRecord() { IsAuthorizedView = inDto.IsAuthorizedView });
|
||||||
|
await _trialNormalRecordRepository.SaveChangesAsync();
|
||||||
|
return ResponseOutput.Ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[HttpDelete("{trialNormalRecordId:guid}")]
|
||||||
|
public async Task<IResponseOutput> DeleteTrialNormalRecord(Guid trialNormalRecordId)
|
||||||
|
{
|
||||||
|
var success = await _trialNormalRecordRepository.DeleteFromQueryAsync(t => t.Id == trialNormalRecordId, true);
|
||||||
|
return ResponseOutput.Ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 批量删除一般文件记录
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="inDto"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<IResponseOutput> DeleteTrialNormalRecordList(DeleteTrialNormalRecordListInDto inDto)
|
||||||
|
{
|
||||||
|
var success = await _trialNormalRecordRepository.DeleteFromQueryAsync(t => inDto.Ids.Contains(t.Id), true);
|
||||||
|
return ResponseOutput.Ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,140 @@
|
|||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
// 此代码由liquid模板自动生成 byzhouhang 20240909
|
||||||
|
// 生成时间 2025-02-21 07:47:30Z
|
||||||
|
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
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;
|
||||||
|
namespace IRaCIS.Core.Application.Service;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 项目-培训记录
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="_trialTrianingRecordRepository"></param>
|
||||||
|
/// <param name="_mapper"></param>
|
||||||
|
/// <param name="_userInfo"></param>
|
||||||
|
/// <param name="_localizer"></param>
|
||||||
|
[ApiExplorerSettings(GroupName = "FileRecord")]
|
||||||
|
public class TrialTrianingRecordService(IRepository<
|
||||||
|
TrialTrianingRecord> _trialTrianingRecordRepository,
|
||||||
|
IRepository<TrialFile> _trialFileRepository,
|
||||||
|
IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer) : BaseService, ITrialTrianingRecordService
|
||||||
|
{
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取培训记录列表
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="inDto"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<PageOutput<TrialTrianingRecordView>> GetTrialTrianingRecordList(TrialTrianingRecordQuery inDto)
|
||||||
|
{
|
||||||
|
|
||||||
|
var trialTrianingRecordQueryable = _trialTrianingRecordRepository
|
||||||
|
.Where(x => x.TrialFileTypeId == inDto.TrialFileTypeId)
|
||||||
|
.WhereIf(inDto.IsAuthorizedView != null, x => x.IsAuthorizedView == inDto.IsAuthorizedView)
|
||||||
|
.WhereIf(inDto.FileName.IsNotNullOrEmpty(), x => x.TrialFileRecord.FileName.Contains(inDto.FileName))
|
||||||
|
.WhereIf(inDto.TrianingDateStartTime != null, x => x.TrianingDate >= inDto.TrianingDateStartTime)
|
||||||
|
.WhereIf(inDto.TrianingDateEndTime != null, x => x.TrianingDate <= inDto.TrianingDateEndTime)
|
||||||
|
.WhereIf(inDto.UpdateStartTime != null, x => x.UpdateTime >= inDto.UpdateStartTime)
|
||||||
|
.WhereIf(inDto.UpdateEndTime != null, x => x.UpdateTime < inDto.UpdateEndTime.Value.AddDays(1))
|
||||||
|
.ProjectTo<TrialTrianingRecordView>(_mapper.ConfigurationProvider);
|
||||||
|
|
||||||
|
var pageList = await trialTrianingRecordQueryable.ToPagedListAsync(inDto);
|
||||||
|
|
||||||
|
return pageList;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public async Task<IResponseOutput> AddOrUpdateTrialTrianingRecord(TrialTrianingRecordAddOrEdit inDto)
|
||||||
|
{
|
||||||
|
// 在此处拷贝automapper 映射
|
||||||
|
|
||||||
|
|
||||||
|
if (inDto.TrialFileRecord != null) inDto.TrialFileRecord.TrialFileTypeId = inDto.TrialFileTypeId;
|
||||||
|
if (inDto.HistoryFileRecord != null) inDto.HistoryFileRecord.TrialFileTypeId = inDto.TrialFileTypeId;
|
||||||
|
|
||||||
|
|
||||||
|
if (inDto.Id != null)
|
||||||
|
{
|
||||||
|
var trialFinalRecord = await _trialTrianingRecordRepository.Where(x => x.Id == inDto.Id.Value).FirstNotNullAsync();
|
||||||
|
|
||||||
|
List<Guid?> ids = new List<Guid?>() {
|
||||||
|
trialFinalRecord.TrialFileRecordId,
|
||||||
|
trialFinalRecord.HistoryFileRecordId,
|
||||||
|
};
|
||||||
|
|
||||||
|
var fileIds = ids.Where(x => x != null).Select(x => (Guid)x).ToList();
|
||||||
|
await _trialFileRepository.BatchDeleteNoTrackingAsync(x => fileIds.Contains(x.Id));
|
||||||
|
}
|
||||||
|
var entity = await _trialTrianingRecordRepository.InsertOrUpdateAsync(inDto, true);
|
||||||
|
|
||||||
|
return ResponseOutput.Ok(entity.Id.ToString());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 批量新增培训记录
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="inDto"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<IResponseOutput> BatchAddTrialTrianingRecord(BatchAddTTrianingRecordInDto inDto)
|
||||||
|
{
|
||||||
|
foreach (var item in inDto.TrianingRecordList)
|
||||||
|
{
|
||||||
|
if (item.TrialFileRecord != null) item.TrialFileRecord.TrialFileTypeId = item.TrialFileTypeId;
|
||||||
|
if (item.HistoryFileRecord != null) item.HistoryFileRecord.TrialFileTypeId = item.TrialFileTypeId;
|
||||||
|
|
||||||
|
var entity = await _trialTrianingRecordRepository.InsertFromDTOAsync(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
var result = await _trialTrianingRecordRepository.SaveChangesAsync();
|
||||||
|
return ResponseOutput.Ok(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 授权文档
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="inDto"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<IResponseOutput> AuthorizedTrialTrianingRecord(AuthorizedTrialFinalRecordInDto inDto)
|
||||||
|
{
|
||||||
|
await _trialTrianingRecordRepository.UpdatePartialFromQueryAsync(t => inDto.Ids.Contains(t.Id), t => new TrialTrianingRecord() { IsAuthorizedView = inDto.IsAuthorizedView });
|
||||||
|
await _trialTrianingRecordRepository.SaveChangesAsync();
|
||||||
|
return ResponseOutput.Ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpDelete("{trialTrianingRecordId:guid}")]
|
||||||
|
public async Task<IResponseOutput> DeleteTrialTrianingRecord(Guid trialTrianingRecordId)
|
||||||
|
{
|
||||||
|
var success = await _trialTrianingRecordRepository.DeleteFromQueryAsync(t => t.Id == trialTrianingRecordId, true);
|
||||||
|
return ResponseOutput.Ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 批量删除培训记录
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="inDto"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<IResponseOutput> DeleteTrialTrianingRecordList(DeleteTrialNormalRecordListInDto inDto)
|
||||||
|
{
|
||||||
|
var success = await _trialTrianingRecordRepository.DeleteFromQueryAsync(t => inDto.Ids.Contains(t.Id), true);
|
||||||
|
return ResponseOutput.Ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -3,6 +3,7 @@ using AutoMapper.EquivalencyExpression;
|
|||||||
using IRaCIS.Application.Contracts;
|
using IRaCIS.Application.Contracts;
|
||||||
using IRaCIS.Core.Application.Contracts;
|
using IRaCIS.Core.Application.Contracts;
|
||||||
using IRaCIS.Core.Application.ViewModel;
|
using IRaCIS.Core.Application.ViewModel;
|
||||||
|
using IRaCIS.Core.Infrastructure.Extention;
|
||||||
|
|
||||||
namespace IRaCIS.Core.Application.Service
|
namespace IRaCIS.Core.Application.Service
|
||||||
{
|
{
|
||||||
@@ -14,10 +15,30 @@ namespace IRaCIS.Core.Application.Service
|
|||||||
var userId = Guid.Empty;
|
var userId = Guid.Empty;
|
||||||
var isEn_Us = false;
|
var isEn_Us = false;
|
||||||
|
|
||||||
|
// 在此处拷贝automapper 映射
|
||||||
|
|
||||||
|
CreateMap<SystemDocumentAttachment, SystemDocumentAttachmentView>();
|
||||||
|
CreateMap<SystemDocumentAttachment, SystemDocumentAttachmentAddOrEdit>().ReverseMap();
|
||||||
|
|
||||||
|
CreateMap<AuditDocumentData, AuditDocumentAddOrEdit>();
|
||||||
|
//CreateMap<List<AuditDocumentData>, List<AuditDocumentAddOrEdit>>();
|
||||||
|
CreateMap<AuditDocument, AuditDocumentView>();
|
||||||
|
CreateMap<AuditDocument, AuditDocumentUpdateDto>();
|
||||||
|
CreateMap<AuditDocument, HistoricalVersionDto>();
|
||||||
|
CreateMap<AuditDocumentUpdateDto, AuditDocumentAddOrEdit>();
|
||||||
|
CreateMap<AuditDocument, AuditDocumentData>();
|
||||||
|
CreateMap<AuditDocument, AuditDocumentAddOrEdit>().ReverseMap();
|
||||||
CreateMap<SystemDocument, SystemDocumentView>()
|
CreateMap<SystemDocument, SystemDocumentView>()
|
||||||
|
.ForMember(d => d.AttachmentCount, u => u.MapFrom(s => s.SystemDocumentAttachmentList.Count()))
|
||||||
.ForMember(d => d.FileType, u => u.MapFrom(s => isEn_Us ? s.FileType.Value : s.FileType.ValueCN))
|
.ForMember(d => d.FileType, u => u.MapFrom(s => isEn_Us ? s.FileType.Value : s.FileType.ValueCN))
|
||||||
.ForMember(d => d.FullFilePath, u => u.MapFrom(s => s.Path));
|
.ForMember(d => d.FullFilePath, u => u.MapFrom(s => s.Path));
|
||||||
|
|
||||||
|
|
||||||
|
CreateMap<SysFileType, TrialFileType>()
|
||||||
|
.ForMember(d => d.SysFileTypeId, u => u.MapFrom(s => s.Id))
|
||||||
|
.ForMember(d => d.IsSelfDefine, u => u.MapFrom(s => false))
|
||||||
|
.ForMember(dest => dest.CreateUserRole, opt => opt.Ignore());
|
||||||
|
|
||||||
CreateMap<TrialDocument, TrialDocumentView>()
|
CreateMap<TrialDocument, TrialDocumentView>()
|
||||||
.ForMember(d => d.FileType, u => u.MapFrom(s => isEn_Us ? s.FileType.Value : s.FileType.ValueCN))
|
.ForMember(d => d.FileType, u => u.MapFrom(s => isEn_Us ? s.FileType.Value : s.FileType.ValueCN))
|
||||||
.ForMember(d => d.IsSomeUserSigned, u => u.MapFrom(s => s.TrialDocConfirmedUserList.Any(t => t.ConfirmTime != null)))
|
.ForMember(d => d.IsSomeUserSigned, u => u.MapFrom(s => s.TrialDocConfirmedUserList.Any(t => t.ConfirmTime != null)))
|
||||||
@@ -51,6 +72,9 @@ namespace IRaCIS.Core.Application.Service
|
|||||||
|
|
||||||
CreateMap<TrialUserRole, TrialDocumentUserConfirmView>();
|
CreateMap<TrialUserRole, TrialDocumentUserConfirmView>();
|
||||||
|
|
||||||
|
CreateMap<TrialFileDto, TrialFile>();
|
||||||
|
CreateMap<TrialFile, TrialFileDto>();
|
||||||
|
|
||||||
CreateMap<BatchAddTrialEmailNoticeConfig, TrialEmailNoticeConfig>();
|
CreateMap<BatchAddTrialEmailNoticeConfig, TrialEmailNoticeConfig>();
|
||||||
|
|
||||||
CreateMap<TrialSelectEmailNoticeConfigView, BatchAddTrialEmailNoticeConfig > ();
|
CreateMap<TrialSelectEmailNoticeConfigView, BatchAddTrialEmailNoticeConfig > ();
|
||||||
@@ -87,6 +111,33 @@ namespace IRaCIS.Core.Application.Service
|
|||||||
|
|
||||||
CreateMap<TrialEmailNoticeUser, EmailUserInfoDto>();
|
CreateMap<TrialEmailNoticeUser, EmailUserInfoDto>();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
CreateMap<SysFileType, SysFileTypeView>();
|
||||||
|
CreateMap<SysFileType, SysFileTypeAddOrEdit>().ReverseMap();
|
||||||
|
|
||||||
|
CreateMap<TrialFileType, TrialFileTypeView>();
|
||||||
|
|
||||||
|
CreateMap<TrialFileType, TrialFileTypeAddOrEdit>().ReverseMap();
|
||||||
|
|
||||||
|
CreateMap<TrialFinalRecord, TrialFinalRecordView>();
|
||||||
|
CreateMap<TrialFinalRecordAddOrEdit, TrialFinalRecord>();
|
||||||
|
//.ForMember(d => d.HistoryFileRecord.TrialFileTypeId, c => c.MapFrom(t => t.TrialFileTypeId))
|
||||||
|
//.ForMember(d => d.SignFileRecord.TrialFileTypeId, c => c.MapFrom(t => t.TrialFileTypeId))
|
||||||
|
//.ForMember(d => d.WordFileRecord.TrialFileTypeId, c => c.MapFrom(t => t.TrialFileTypeId))
|
||||||
|
//.ForMember(d => d.PDFFileRecord.TrialFileTypeId, c => c.MapFrom(t => t.TrialFileTypeId));
|
||||||
|
|
||||||
|
CreateMap<TrialNormalRecord, TrialNormalRecordView>()
|
||||||
|
.ForMember(d => d.FileName, c => c.MapFrom(t => t.TrialFileRecord.FileName));
|
||||||
|
CreateMap<TrialNormalRecord, TrialNormalRecordAddOrEdit>().ReverseMap();
|
||||||
|
|
||||||
|
CreateMap<TrialTrianingRecord, TrialTrianingRecordView>()
|
||||||
|
.ForMember(d => d.FileName, c => c.MapFrom(t => t.TrialFileRecord.FileName));
|
||||||
|
CreateMap<TrialTrianingRecord, TrialTrianingRecordAddOrEdit>().ReverseMap();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
|||||||
IRepository<NoneDicomStudyFile> _noneDicomStudyFileReposiotry,
|
IRepository<NoneDicomStudyFile> _noneDicomStudyFileReposiotry,
|
||||||
IDistributedLockProvider _distributedLockProvider,
|
IDistributedLockProvider _distributedLockProvider,
|
||||||
IRepository<TrialImageDownload> _trialImageDownloadRepository,
|
IRepository<TrialImageDownload> _trialImageDownloadRepository,
|
||||||
IRepository<Subject> _subjectRepository,
|
IRepository<Subject> _subjectRepository,
|
||||||
IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer, IFusionCache _fusionCache) : BaseService, IDownloadAndUploadService
|
IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer, IFusionCache _fusionCache) : BaseService, IDownloadAndUploadService
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -257,7 +257,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[TrialGlobalLimit( "AfterStopCannNotOpt" )]
|
[TrialGlobalLimit("AfterStopCannNotOpt")]
|
||||||
|
|
||||||
public async Task<IResponseOutput> PreArchiveDicomStudy(PriArchiveTaskStudyCommand preArchiveStudyCommand)
|
public async Task<IResponseOutput> PreArchiveDicomStudy(PriArchiveTaskStudyCommand preArchiveStudyCommand)
|
||||||
{
|
{
|
||||||
@@ -356,7 +356,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[TrialGlobalLimit( "AfterStopCannNotOpt" )]
|
[TrialGlobalLimit("AfterStopCannNotOpt")]
|
||||||
public async Task<IResponseOutput> AddOrUpdateArchiveTaskStudy(TaskArchiveStudyCommand incommand)
|
public async Task<IResponseOutput> AddOrUpdateArchiveTaskStudy(TaskArchiveStudyCommand incommand)
|
||||||
{
|
{
|
||||||
#region 获取该subject 已生成任务的访视的检查
|
#region 获取该subject 已生成任务的访视的检查
|
||||||
@@ -620,12 +620,25 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
|||||||
{
|
{
|
||||||
if (dicomStudyId == null)
|
if (dicomStudyId == null)
|
||||||
{
|
{
|
||||||
|
var deleteStudyPathList = await _taskInstanceRepository.Where(t => t.VisitTaskId == visitTaskId).GroupBy(t => t.StudyId).Select(g => g.First().Path).ToListAsync();
|
||||||
|
|
||||||
|
foreach (var fisrtPath in deleteStudyPathList)
|
||||||
|
{
|
||||||
|
var prefix = fisrtPath.Substring(1, fisrtPath.LastIndexOf('/') - 1);
|
||||||
|
await _oSSService.DeleteFromPrefix(prefix, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
await _taskStudyRepository.DeleteFromQueryAsync(t => t.VisitTaskId == visitTaskId);
|
await _taskStudyRepository.DeleteFromQueryAsync(t => t.VisitTaskId == visitTaskId);
|
||||||
await _taskSeriesRepository.BatchDeleteNoTrackingAsync(t => t.VisitTaskId == visitTaskId);
|
await _taskSeriesRepository.BatchDeleteNoTrackingAsync(t => t.VisitTaskId == visitTaskId);
|
||||||
await _taskInstanceRepository.BatchDeleteNoTrackingAsync(t => t.VisitTaskId == visitTaskId);
|
await _taskInstanceRepository.BatchDeleteNoTrackingAsync(t => t.VisitTaskId == visitTaskId);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
var fisrtPath = await _taskInstanceRepository.Where(t => t.VisitTaskId == visitTaskId && t.StudyId == dicomStudyId).Select(t => t.Path).FirstOrDefaultAsync();
|
||||||
|
var prefix = fisrtPath.Substring(1, fisrtPath.LastIndexOf('/') - 1);
|
||||||
|
await _oSSService.DeleteFromPrefix(prefix, true);
|
||||||
|
|
||||||
await _taskStudyRepository.DeleteFromQueryAsync(t => t.VisitTaskId == visitTaskId && t.Id == dicomStudyId);
|
await _taskStudyRepository.DeleteFromQueryAsync(t => t.VisitTaskId == visitTaskId && t.Id == dicomStudyId);
|
||||||
await _taskSeriesRepository.BatchDeleteNoTrackingAsync(t => t.VisitTaskId == visitTaskId && t.Id == dicomStudyId);
|
await _taskSeriesRepository.BatchDeleteNoTrackingAsync(t => t.VisitTaskId == visitTaskId && t.Id == dicomStudyId);
|
||||||
await _taskInstanceRepository.BatchDeleteNoTrackingAsync(t => t.VisitTaskId == visitTaskId && t.Id == dicomStudyId);
|
await _taskInstanceRepository.BatchDeleteNoTrackingAsync(t => t.VisitTaskId == visitTaskId && t.Id == dicomStudyId);
|
||||||
@@ -689,7 +702,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
|||||||
SubjectCode = u.IsSelfAnalysis == true ? u.BlindSubjectCode : u.Subject.Code,
|
SubjectCode = u.IsSelfAnalysis == true ? u.BlindSubjectCode : u.Subject.Code,
|
||||||
TaskBlindName = u.TaskBlindName,
|
TaskBlindName = u.TaskBlindName,
|
||||||
TaskName = u.TaskName,
|
TaskName = u.TaskName,
|
||||||
ReadingTaskState=u.ReadingTaskState,
|
ReadingTaskState = u.ReadingTaskState,
|
||||||
SourceSubjectVisitId = u.SourceSubjectVisitId,
|
SourceSubjectVisitId = u.SourceSubjectVisitId,
|
||||||
VisitTaskId = u.Id,
|
VisitTaskId = u.Id,
|
||||||
|
|
||||||
@@ -761,9 +774,9 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
|||||||
select new
|
select new
|
||||||
{
|
{
|
||||||
TrialId = sv.TrialId,
|
TrialId = sv.TrialId,
|
||||||
SubjectId=sv.SubjectId,
|
SubjectId = sv.SubjectId,
|
||||||
SubjectCode = sv.Subject.Code,
|
SubjectCode = sv.Subject.Code,
|
||||||
TrialSiteCode=sv.TrialSite.TrialSiteCode,
|
TrialSiteCode = sv.TrialSite.TrialSiteCode,
|
||||||
VisitName = sv.VisitName,
|
VisitName = sv.VisitName,
|
||||||
|
|
||||||
StudyList = sv.StudyList.Where(t => isQueryDicom ? inQuery.DicomStudyIdList.Contains(t.Id) : false)
|
StudyList = sv.StudyList.Where(t => isQueryDicom ? inQuery.DicomStudyIdList.Contains(t.Id) : false)
|
||||||
@@ -971,7 +984,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
|||||||
|
|
||||||
var subjectVisitIdList = inQuery.SubjectVisitTaskList.Select(t => t.SubjectVisitId).ToList();
|
var subjectVisitIdList = inQuery.SubjectVisitTaskList.Select(t => t.SubjectVisitId).ToList();
|
||||||
|
|
||||||
var trialSiteCode = _visitTaskRepository.Where(t => t.Id == taskIdList.FirstOrDefault()).Select(t => t.IsAnalysisCreate ? t.BlindTrialSiteCode : t.Subject.TrialSite.TrialSiteCode).FirstOrDefault()??string.Empty;
|
var trialSiteCode = _visitTaskRepository.Where(t => t.Id == taskIdList.FirstOrDefault()).Select(t => t.IsAnalysisCreate ? t.BlindTrialSiteCode : t.Subject.TrialSite.TrialSiteCode).FirstOrDefault() ?? string.Empty;
|
||||||
|
|
||||||
var query = from sv in _subjectRepository.Where(t => t.Id == inQuery.SubjectId).SelectMany(t => t.SubjectVisitList.Where(t => subjectVisitIdList.Contains(t.Id)))
|
var query = from sv in _subjectRepository.Where(t => t.Id == inQuery.SubjectId).SelectMany(t => t.SubjectVisitList.Where(t => subjectVisitIdList.Contains(t.Id)))
|
||||||
//一致性分析,导致查询出来两条数据
|
//一致性分析,导致查询出来两条数据
|
||||||
@@ -1032,9 +1045,9 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
|||||||
{
|
{
|
||||||
Id = NewId.NextSequentialGuid(),
|
Id = NewId.NextSequentialGuid(),
|
||||||
TrialId = info.TrialId,
|
TrialId = info.TrialId,
|
||||||
SubjectId=inQuery.SubjectId,
|
SubjectId = inQuery.SubjectId,
|
||||||
SubjectCode = inQuery.SubjectCode,
|
SubjectCode = inQuery.SubjectCode,
|
||||||
TrialSiteCode= trialSiteCode,
|
TrialSiteCode = trialSiteCode,
|
||||||
IP = _userInfo.IP,
|
IP = _userInfo.IP,
|
||||||
DownloadStartTime = DateTime.Now,
|
DownloadStartTime = DateTime.Now,
|
||||||
IsSuccess = false,
|
IsSuccess = false,
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ using IRaCIS.Core.Domain.Models;
|
|||||||
using IRaCIS.Core.Domain.Share;
|
using IRaCIS.Core.Domain.Share;
|
||||||
using Medallion.Threading;
|
using Medallion.Threading;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using NPOI.SS.Formula.Functions;
|
||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
namespace IRaCIS.Core.Application.Contracts
|
namespace IRaCIS.Core.Application.Contracts
|
||||||
@@ -28,33 +29,49 @@ namespace IRaCIS.Core.Application.Contracts
|
|||||||
|
|
||||||
|
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
public async Task<List<NoneDicomStudyView>> GetNoneDicomStudyList(
|
public async Task<IResponseOutput<List<NoneDicomStudyView>>> GetNoneDicomStudyList(
|
||||||
[FromQuery, NotDefault] Guid subjectVisitId,
|
[FromQuery, NotDefault] Guid subjectVisitId,
|
||||||
[FromQuery] Guid? nonedicomStudyId,
|
[FromQuery] Guid? nonedicomStudyId,
|
||||||
[FromQuery] bool isFilterZip,
|
[FromQuery] bool isFilterZip,
|
||||||
[FromQuery] Guid? visitTaskId)
|
[FromQuery] Guid? visitTaskId,
|
||||||
|
[FromQuery] bool isReading)
|
||||||
{
|
{
|
||||||
|
var qcAuditState = await _subjectVisitRepository.Where(s => s.Id == subjectVisitId).Select(t => t.AuditState).FirstOrDefaultAsync();
|
||||||
|
|
||||||
|
//质控过程中,因为会修改统计数字,但是此时其他人看,应该看到完整的影像
|
||||||
|
var isQCFinished = qcAuditState == AuditStateEnum.QCPassed;
|
||||||
|
|
||||||
|
//质控过程中并且不是IQC时,可以看到删除的(不需要忽略过滤器) 质控中iqc 也需要看到删除的
|
||||||
|
var isViewDelete = !isQCFinished;
|
||||||
|
|
||||||
IQueryable<NoneDicomStudyView> noneDicomStudyQueryable = default;
|
IQueryable<NoneDicomStudyView> noneDicomStudyQueryable = default;
|
||||||
if (visitTaskId == null)
|
if (visitTaskId == null)
|
||||||
{
|
{
|
||||||
noneDicomStudyQueryable = _noneDicomStudyRepository.Where(t => t.SubjectVisitId == subjectVisitId).WhereIf(nonedicomStudyId != null, t => t.Id == nonedicomStudyId)
|
//质控过程中,需要忽略过滤质控设置删除的检查,以及设置删除的文件,质控通过后才
|
||||||
|
noneDicomStudyQueryable = _noneDicomStudyRepository.Where(t => t.SubjectVisitId == subjectVisitId, ignoreQueryFilters: isViewDelete)
|
||||||
|
.WhereIf(nonedicomStudyId != null, t => t.Id == nonedicomStudyId)
|
||||||
|
.WhereIf(isReading, t => t.IsReading && t.IsDeleted==false)
|
||||||
|
|
||||||
.ProjectTo<NoneDicomStudyView>(_mapper.ConfigurationProvider, new { isFilterZip = isFilterZip });
|
|
||||||
|
.ProjectTo<NoneDicomStudyView>(_mapper.ConfigurationProvider, new { isFilterZip = isFilterZip, isReading= isReading });
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var taskinfo = await _visitTaskRepository.Where(x => x.Id == visitTaskId).Select(t => new { t.BlindSubjectCode, t.TrialReadingCriterionId, t.TrialReadingCriterion.IsImageFilter, t.TrialReadingCriterion.CriterionModalitys }).FirstNotNullAsync();
|
var taskinfo = await _visitTaskRepository.Where(x => x.Id == visitTaskId).Select(t => new { t.BlindSubjectCode, t.TrialReadingCriterionId, t.TrialReadingCriterion.IsImageFilter, t.TrialReadingCriterion.CriterionModalitys }).FirstNotNullAsync();
|
||||||
|
|
||||||
|
|
||||||
noneDicomStudyQueryable = _noneDicomStudyRepository.Where(t => t.TaskNoneDicomFileList.Any(t => t.VisitTaskId == visitTaskId))
|
noneDicomStudyQueryable = _noneDicomStudyRepository.Where(t => t.TaskNoneDicomFileList.Any(t => t.VisitTaskId == visitTaskId), ignoreQueryFilters: isViewDelete)
|
||||||
|
.WhereIf(isReading, t => t.IsReading && t.IsDeleted == false)
|
||||||
.Where(t => taskinfo.IsImageFilter ? ("|" + taskinfo.CriterionModalitys + "|").Contains("|" + t.Modality + "|") : true)
|
.Where(t => taskinfo.IsImageFilter ? ("|" + taskinfo.CriterionModalitys + "|").Contains("|" + t.Modality + "|") : true)
|
||||||
.WhereIf(nonedicomStudyId != null, t => t.Id == nonedicomStudyId)
|
.WhereIf(nonedicomStudyId != null, t => t.Id == nonedicomStudyId)
|
||||||
.ProjectTo<TaskDicomStudyView>(_mapper.ConfigurationProvider, new { isFilterZip = isFilterZip, visiTaskId = visitTaskId });
|
.ProjectTo<TaskDicomStudyView>(_mapper.ConfigurationProvider, new { isFilterZip = isFilterZip, visiTaskId = visitTaskId, isReading = isReading });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return await noneDicomStudyQueryable.ToListAsync();
|
var list = await noneDicomStudyQueryable.OrderBy(x => x.ImageDate).ThenBy(x => x.CreateTime).ToListAsync();
|
||||||
|
|
||||||
|
var config = await _subjectVisitRepository.Where(t => t.Id == subjectVisitId).Select(t => new { t.Trial.ImageFormatList, t.Trial.StudyNameList, t.Trial.IsShowStudyName, AuditState = qcAuditState }).FirstOrDefaultAsync();
|
||||||
|
return ResponseOutput.Ok(list, config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -83,10 +100,12 @@ namespace IRaCIS.Core.Application.Contracts
|
|||||||
//默认会是0
|
//默认会是0
|
||||||
var code = await _noneDicomStudyRepository.Where(t => t.TrialId == addOrEditNoneDicomStudy.TrialId).Select(x => x.Code).DefaultIfEmpty().MaxAsync();
|
var code = await _noneDicomStudyRepository.Where(t => t.TrialId == addOrEditNoneDicomStudy.TrialId).Select(x => x.Code).DefaultIfEmpty().MaxAsync();
|
||||||
|
|
||||||
addOrEditNoneDicomStudy.Code = code + 1;
|
|
||||||
|
|
||||||
optEntity = await _noneDicomStudyRepository.InsertFromDTOAsync(addOrEditNoneDicomStudy);
|
optEntity = await _noneDicomStudyRepository.InsertFromDTOAsync(addOrEditNoneDicomStudy);
|
||||||
|
|
||||||
|
optEntity.Code = code + 1;
|
||||||
|
|
||||||
|
|
||||||
optEntity.StudyCode = AppSettings.GetCodeStr(optEntity.Code, nameof(NoneDicomStudy));
|
optEntity.StudyCode = AppSettings.GetCodeStr(optEntity.Code, nameof(NoneDicomStudy));
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -118,9 +137,9 @@ namespace IRaCIS.Core.Application.Contracts
|
|||||||
|
|
||||||
await _qCCommon.VerifyIsCRCSubmmitAsync(_subjectVisitRepository, _userInfo, subjectVisitId);
|
await _qCCommon.VerifyIsCRCSubmmitAsync(_subjectVisitRepository, _userInfo, subjectVisitId);
|
||||||
|
|
||||||
await _noneDicomStudyRepository.DeleteFromQueryAsync(noneDicomStudyId);
|
await _noneDicomStudyRepository.DeleteFromQueryAsync(noneDicomStudyId,ignoreQueryFilter:true);
|
||||||
|
|
||||||
await _noneDicomStudyFileRepository.DeleteFromQueryAsync(t => t.NoneDicomStudyId == noneDicomStudyId);
|
await _noneDicomStudyFileRepository.DeleteFromQueryAsync(t => t.NoneDicomStudyId == noneDicomStudyId, ignoreQueryFilter: true);
|
||||||
|
|
||||||
//确认需求 不删除
|
//确认需求 不删除
|
||||||
//await _studyMonitorRepository.BatchDeleteNoTrackingAsync(t => t.StudyId == noneDicomStudyId);
|
//await _studyMonitorRepository.BatchDeleteNoTrackingAsync(t => t.StudyId == noneDicomStudyId);
|
||||||
@@ -138,13 +157,13 @@ namespace IRaCIS.Core.Application.Contracts
|
|||||||
//提交了 但是IQC同意的时候 是可以删除的 | 普通提交后也不能删除
|
//提交了 但是IQC同意的时候 是可以删除的 | 普通提交后也不能删除
|
||||||
await _qCCommon.VerifyIsCRCSubmmitAsync(_subjectVisitRepository, _userInfo, subjectVisitId);
|
await _qCCommon.VerifyIsCRCSubmmitAsync(_subjectVisitRepository, _userInfo, subjectVisitId);
|
||||||
|
|
||||||
var noneDicomStudyFile = await _noneDicomStudyFileRepository.FirstOrDefaultAsync(t => t.Id == noneDicomStudyFileId);
|
var noneDicomStudyFile = await _noneDicomStudyFileRepository.FirstOrDefaultAsync(t => t.Id == noneDicomStudyFileId, true);
|
||||||
|
|
||||||
var success = await _noneDicomStudyFileRepository.DeleteAsync(noneDicomStudyFile, true);
|
var success = await _noneDicomStudyFileRepository.DeleteAsync(noneDicomStudyFile,true);
|
||||||
|
|
||||||
//维护文件数量数字
|
//维护文件数量数字
|
||||||
var noneDicomStudy = await _noneDicomStudyRepository.FirstOrDefaultAsync(t => t.Id == noneDicomStudyFile.NoneDicomStudyId);
|
var noneDicomStudy = await _noneDicomStudyRepository.FirstOrDefaultAsync(t => t.Id == noneDicomStudyFile.NoneDicomStudyId,true);
|
||||||
noneDicomStudy.FileCount = await _noneDicomStudyFileRepository.CountAsync(t => t.NoneDicomStudyId == noneDicomStudyFile.NoneDicomStudyId);
|
noneDicomStudy.FileCount = await _noneDicomStudyFileRepository.CountAsync(t => t.NoneDicomStudyId == noneDicomStudyFile.NoneDicomStudyId,true);
|
||||||
await _noneDicomStudyRepository.SaveChangesAsync();
|
await _noneDicomStudyRepository.SaveChangesAsync();
|
||||||
|
|
||||||
return ResponseOutput.Ok();
|
return ResponseOutput.Ok();
|
||||||
@@ -158,18 +177,35 @@ namespace IRaCIS.Core.Application.Contracts
|
|||||||
[HttpGet("{noneDicomStudyId:guid}")]
|
[HttpGet("{noneDicomStudyId:guid}")]
|
||||||
public async Task<List<NoneDicomStudyFileView>> GetNoneDicomStudyFileList(Guid noneDicomStudyId)
|
public async Task<List<NoneDicomStudyFileView>> GetNoneDicomStudyFileList(Guid noneDicomStudyId)
|
||||||
{
|
{
|
||||||
return await _noneDicomStudyFileRepository.Where(t => t.NoneDicomStudyId == noneDicomStudyId)
|
var qcAuditState = await _noneDicomStudyFileRepository.Where(t => t.NoneDicomStudyId == noneDicomStudyId).Select(t => t.NoneDicomStudy.SubjectVisit.AuditState).FirstOrDefaultAsync();
|
||||||
|
|
||||||
|
//质控过程中,因为会修改统计数字,但是此时其他人看,应该看到完整的影像
|
||||||
|
var isQCFinished = qcAuditState == AuditStateEnum.QCPassed;
|
||||||
|
|
||||||
|
//质控过程中并且不是IQC时,可以看到删除的(不需要忽略过滤器)
|
||||||
|
var isViewDelete = !isQCFinished;
|
||||||
|
|
||||||
|
return await _noneDicomStudyFileRepository.Where(t => t.NoneDicomStudyId == noneDicomStudyId, ignoreQueryFilters: isViewDelete)
|
||||||
.ProjectTo<NoneDicomStudyFileView>(_mapper.ConfigurationProvider).OrderBy(t => t.CreateTime).ToListAsync();
|
.ProjectTo<NoneDicomStudyFileView>(_mapper.ConfigurationProvider).OrderBy(t => t.CreateTime).ToListAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet("{subjectVisitId:guid}")]
|
[HttpGet("{subjectVisitId:guid}")]
|
||||||
public async Task<List<NoneDicomStudyFileView>> GetVisitNoneDicomStudyFileList(Guid subjectVisitId)
|
public async Task<List<NoneDicomStudyFileView>> GetVisitNoneDicomStudyFileList(Guid subjectVisitId)
|
||||||
{
|
{
|
||||||
return await _noneDicomStudyFileRepository.Where(t => t.NoneDicomStudy.SubjectVisitId == subjectVisitId)
|
var qcAuditState = await _subjectVisitRepository.Where(s => s.Id == subjectVisitId).Select(t => t.AuditState).FirstOrDefaultAsync();
|
||||||
|
|
||||||
|
//质控过程中,因为会修改统计数字,但是此时其他人看,应该看到完整的影像
|
||||||
|
var isQCFinished = qcAuditState == AuditStateEnum.QCPassed;
|
||||||
|
|
||||||
|
//质控过程中并且不是IQC时, 不需要忽略过滤器+质控设置删除的
|
||||||
|
var isViewDelete = !isQCFinished;
|
||||||
|
|
||||||
|
return await _noneDicomStudyFileRepository.Where(t => t.NoneDicomStudy.SubjectVisitId == subjectVisitId, ignoreQueryFilters: isViewDelete)
|
||||||
.ProjectTo<NoneDicomStudyFileView>(_mapper.ConfigurationProvider).ToListAsync();
|
.ProjectTo<NoneDicomStudyFileView>(_mapper.ConfigurationProvider).ToListAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -845,7 +845,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
var verifyStudyInfo = _dicomStudyRepository.Where(t => t.TrialId == trialId && t.Id == expectStudyId).ProjectTo<VerifyStudyDto>(_mapper.ConfigurationProvider).FirstOrDefault();
|
var verifyStudyInfo = _dicomStudyRepository.Where(t => t.TrialId == trialId && t.Id == expectStudyId,false,true).ProjectTo<VerifyStudyDto>(_mapper.ConfigurationProvider).FirstOrDefault();
|
||||||
result.StudyInfo = verifyStudyInfo;
|
result.StudyInfo = verifyStudyInfo;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
|
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
using IRaCIS.Core.Domain.Share;
|
using IRaCIS.Core.Domain.Share;
|
||||||
|
using Newtonsoft.Json;
|
||||||
namespace IRaCIS.Core.Application.ViewModel
|
namespace IRaCIS.Core.Application.ViewModel
|
||||||
{
|
{
|
||||||
/// <summary> UserLogView 列表视图模型 </summary>
|
/// <summary> UserLogView 列表视图模型 </summary>
|
||||||
@@ -13,7 +14,7 @@ namespace IRaCIS.Core.Application.ViewModel
|
|||||||
public string IP { get; set; }
|
public string IP { get; set; }
|
||||||
|
|
||||||
public string ActionUserType { get; set; }
|
public string ActionUserType { get; set; }
|
||||||
public int OptType { get; set; }
|
public UserOptType OptType { get; set; }
|
||||||
|
|
||||||
public string? ActionUserName { get; set; }
|
public string? ActionUserName { get; set; }
|
||||||
|
|
||||||
@@ -26,10 +27,14 @@ namespace IRaCIS.Core.Application.ViewModel
|
|||||||
|
|
||||||
public bool IsLoginUncommonly { get; set; }
|
public bool IsLoginUncommonly { get; set; }
|
||||||
|
|
||||||
|
public bool IsIgnoreUncommonly { get; set; }
|
||||||
|
|
||||||
public string JsonObj { get; set; }
|
public string JsonObj { get; set; }
|
||||||
|
|
||||||
public string IPRegion { get; set; }
|
public string IPRegion { get; set; }
|
||||||
|
|
||||||
|
[JsonIgnore]
|
||||||
|
public UserLogJsonObj UserObj => JsonObj.IsNotNullOrEmpty() ? JsonConvert.DeserializeObject<UserLogJsonObj>(JsonObj) :new UserLogJsonObj();
|
||||||
}
|
}
|
||||||
|
|
||||||
public class SendMfaCommand
|
public class SendMfaCommand
|
||||||
@@ -39,17 +44,26 @@ namespace IRaCIS.Core.Application.ViewModel
|
|||||||
public UserMFAType MFAType { get; set; } = UserMFAType.Login;
|
public UserMFAType MFAType { get; set; } = UserMFAType.Login;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class SetIsIgnoreUncommonlyInDto
|
||||||
|
{
|
||||||
|
public Guid Id { get; set; }
|
||||||
|
|
||||||
|
public bool IsIgnoreUncommonly { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
///<summary>UserLogQuery 列表查询参数模型</summary>
|
///<summary>UserLogQuery 列表查询参数模型</summary>
|
||||||
public class UserLogQuery : PageInput
|
public class UserLogQuery : PageInput
|
||||||
{
|
{
|
||||||
public Guid? TrialId { get; set; }
|
public Guid? TrialId { get; set; }
|
||||||
|
|
||||||
public UserOptType? OptType { get; set; }
|
public List<UserOptType>? OptTypeList { get; set; }
|
||||||
|
|
||||||
|
|
||||||
public string? IP { get; set; }
|
public string? IP { get; set; }
|
||||||
|
|
||||||
public string? LoginFaildName { get; set; }
|
public string? LoginFaildName { get; set; }
|
||||||
|
|
||||||
|
|
||||||
public string? LoginUserName { get; set; }
|
public string? LoginUserName { get; set; }
|
||||||
|
|
||||||
public DateTime? BeginDate { get; set; }
|
public DateTime? BeginDate { get; set; }
|
||||||
|
|||||||
@@ -311,6 +311,8 @@ namespace IRaCIS.Application.Contracts
|
|||||||
public DateTime? BeginLastChangePassWordTime { get; set; }
|
public DateTime? BeginLastChangePassWordTime { get; set; }
|
||||||
|
|
||||||
public DateTime? EndLastChangePassWordTime { get; set; }
|
public DateTime? EndLastChangePassWordTime { get; set; }
|
||||||
|
|
||||||
|
public UserCeateSource? UserCeateSource { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class UserRoleInfoDTO
|
public class UserRoleInfoDTO
|
||||||
@@ -336,6 +338,18 @@ namespace IRaCIS.Application.Contracts
|
|||||||
public DateTime? LastChangePassWordTime { get; set; }
|
public DateTime? LastChangePassWordTime { get; set; }
|
||||||
|
|
||||||
public List<IdentityUserTypeDTO> UserRoleList { get; set; }
|
public List<IdentityUserTypeDTO> UserRoleList { get; set; }
|
||||||
|
|
||||||
|
#region 用户来源
|
||||||
|
|
||||||
|
public UserCeateSource UserCeateSource { get; set; }
|
||||||
|
|
||||||
|
public Guid? TrialId { get; set; }
|
||||||
|
|
||||||
|
public string TrialCode { get; set; }
|
||||||
|
|
||||||
|
public string ResearchProgramNo { get; set; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ namespace IRaCIS.Core.Application.Contracts
|
|||||||
public string PermissionStr { get; set; } = string.Empty;
|
public string PermissionStr { get; set; } = string.Empty;
|
||||||
public int Order { get; set; }
|
public int Order { get; set; }
|
||||||
|
|
||||||
|
public bool IsEnable { get; set; }
|
||||||
|
|
||||||
public List<Guid> UserTypeGroupIdList { get; set; } = new List<Guid>();
|
public List<Guid> UserTypeGroupIdList { get; set; } = new List<Guid>();
|
||||||
|
|
||||||
@@ -93,6 +93,16 @@ namespace IRaCIS.Core.Application.Contracts
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public class UserTypeSelectDto
|
||||||
|
{
|
||||||
|
public bool IsDeleted { get; set; }
|
||||||
|
public Guid UserTypeId { get; set; }
|
||||||
|
public string UserTypeShortName { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public DateTime CreateTime { get; set; }
|
||||||
|
public DateTime UpdateTime { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
public class UserTypeSimpleDTO
|
public class UserTypeSimpleDTO
|
||||||
{
|
{
|
||||||
public Guid Id { get; set; }
|
public Guid Id { get; set; }
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ namespace IRaCIS.Core.Application.Service
|
|||||||
//Task<IResponseOutput> DeleteUser(Guid userId);
|
//Task<IResponseOutput> DeleteUser(Guid userId);
|
||||||
//Task<UserDetailDTO> GetUser(Guid id);
|
//Task<UserDetailDTO> GetUser(Guid id);
|
||||||
Task<PageOutput<UserListDTO>> GetUserList(UserListQueryDTO param);
|
Task<PageOutput<UserListDTO>> GetUserList(UserListQueryDTO param);
|
||||||
Task<IResponseOutput<LoginReturnDTO>> Login(string userName, string password);
|
//Task<IResponseOutput<LoginReturnDTO>> Login(string userName, string password);
|
||||||
Task<IResponseOutput> VerifyMFACodeAsync(string Code);
|
Task<IResponseOutput> VerifyMFACodeAsync(string Code);
|
||||||
|
|
||||||
Task<IResponseOutput> SendMFAEmail(SendMfaCommand sendMfa);
|
Task<IResponseOutput> SendMFAEmail(SendMfaCommand sendMfa);
|
||||||
|
|||||||
@@ -87,6 +87,8 @@ namespace IRaCIS.Core.Application.Service
|
|||||||
addOrEditUserFeedBack.TrialSiteId = info.TrialSiteId;
|
addOrEditUserFeedBack.TrialSiteId = info.TrialSiteId;
|
||||||
addOrEditUserFeedBack.SubjectVisitId = info.SourceSubjectVisitId;
|
addOrEditUserFeedBack.SubjectVisitId = info.SourceSubjectVisitId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addOrEditUserFeedBack.State = 0;//设置解决后IR 更新反馈自动变为未解决
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (addOrEditUserFeedBack.SubjectVisitId != null)
|
else if (addOrEditUserFeedBack.SubjectVisitId != null)
|
||||||
|
|||||||
@@ -334,14 +334,21 @@ namespace IRaCIS.Core.Application.Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
////查找改邮箱或者手机的用户
|
////查找改邮箱或者手机的用户
|
||||||
var exist = await _identityUserRepository.AnyAsync(t => t.EMail == email && t.Status == UserStateEnum.Enable);
|
var existUser = await _identityUserRepository.Where(t => t.EMail == email && t.Status == UserStateEnum.Enable).FirstOrDefaultAsync();
|
||||||
|
|
||||||
if (!exist)
|
if (existUser == null)
|
||||||
{
|
{
|
||||||
//---邮箱错误。
|
//---邮箱错误。
|
||||||
return ResponseOutput.NotOk(_localizer["User_EmailError"]);
|
return ResponseOutput.NotOk(_localizer["User_EmailError"]);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (existUser.IsFirstAdd && existUser.UserName.IsNullOrEmpty())
|
||||||
|
{
|
||||||
|
return ResponseOutput.NotOk(_localizer["User_Notinitialized"]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//验证码 6位
|
//验证码 6位
|
||||||
@@ -414,6 +421,7 @@ namespace IRaCIS.Core.Application.Service
|
|||||||
await _identityUserRepository.UpdatePartialFromQueryAsync(t => t.Id == identityUserId, u => new IdentityUser()
|
await _identityUserRepository.UpdatePartialFromQueryAsync(t => t.Id == identityUserId, u => new IdentityUser()
|
||||||
{
|
{
|
||||||
Password = newPwd,
|
Password = newPwd,
|
||||||
|
LastChangePassWordTime = DateTime.Now,
|
||||||
IsFirstAdd = false
|
IsFirstAdd = false
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -459,6 +467,7 @@ namespace IRaCIS.Core.Application.Service
|
|||||||
var success = await _identityUserRepository.BatchUpdateNoTrackingAsync(t => t.Id == _userInfo.IdentityUserId, u => new IdentityUser()
|
var success = await _identityUserRepository.BatchUpdateNoTrackingAsync(t => t.Id == _userInfo.IdentityUserId, u => new IdentityUser()
|
||||||
{
|
{
|
||||||
Password = editPwModel.NewPassWord,
|
Password = editPwModel.NewPassWord,
|
||||||
|
LastChangePassWordTime = DateTime.Now,
|
||||||
IsFirstAdd = false
|
IsFirstAdd = false
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -501,10 +510,11 @@ namespace IRaCIS.Core.Application.Service
|
|||||||
.WhereIf(inQuery.EndLastLoginTime != null, t => t.LastLoginTime <= inQuery.EndLastLoginTime)
|
.WhereIf(inQuery.EndLastLoginTime != null, t => t.LastLoginTime <= inQuery.EndLastLoginTime)
|
||||||
.WhereIf(inQuery.BeginLastChangePassWordTime != null, t => t.LastChangePassWordTime >= inQuery.BeginLastChangePassWordTime)
|
.WhereIf(inQuery.BeginLastChangePassWordTime != null, t => t.LastChangePassWordTime >= inQuery.BeginLastChangePassWordTime)
|
||||||
.WhereIf(inQuery.EndLastChangePassWordTime != null, t => t.LastChangePassWordTime <= inQuery.EndLastChangePassWordTime)
|
.WhereIf(inQuery.EndLastChangePassWordTime != null, t => t.LastChangePassWordTime <= inQuery.EndLastChangePassWordTime)
|
||||||
.WhereIf(inQuery.UserType != null, t => t.UserRoleList.Any(t => t.UserTypeId == inQuery.UserType))
|
.WhereIf(inQuery.UserType != null, t => t.UserRoleList.Any(t => t.UserTypeId == inQuery.UserType && t.IsUserRoleDisabled==false))
|
||||||
.WhereIf(inQuery.UserState != null, t => t.Status == inQuery.UserState)
|
.WhereIf(inQuery.UserState != null, t => t.Status == inQuery.UserState)
|
||||||
.WhereIf(inQuery.IsTestUser != null, t => t.IsTestUser == inQuery.IsTestUser)
|
.WhereIf(inQuery.IsTestUser != null, t => t.IsTestUser == inQuery.IsTestUser)
|
||||||
.WhereIf(inQuery.IsZhiZhun != null, t => t.IsZhiZhun == inQuery.IsZhiZhun)
|
.WhereIf(inQuery.IsZhiZhun != null, t => t.IsZhiZhun == inQuery.IsZhiZhun)
|
||||||
|
.WhereIf(inQuery.UserCeateSource != null, t => t.UserCeateSource == inQuery.UserCeateSource)
|
||||||
.ProjectTo<UserListDTO>(_mapper.ConfigurationProvider);
|
.ProjectTo<UserListDTO>(_mapper.ConfigurationProvider);
|
||||||
|
|
||||||
return await userQueryable.ToPagedListAsync(inQuery);
|
return await userQueryable.ToPagedListAsync(inQuery);
|
||||||
@@ -525,7 +535,7 @@ namespace IRaCIS.Core.Application.Service
|
|||||||
|
|
||||||
if (user != null)
|
if (user != null)
|
||||||
{
|
{
|
||||||
user.AccountList = await _userRoleRepository.Where(t => t.IdentityUserId == identityUserId).ProjectTo<UserAccountInfo>(_mapper.ConfigurationProvider).ToListAsync();
|
user.AccountList = await _userRoleRepository.Where(t => t.IdentityUserId == identityUserId).ProjectTo<UserAccountInfo>(_mapper.ConfigurationProvider).OrderBy(t => t.UserTypeShortName).ToListAsync();
|
||||||
|
|
||||||
}
|
}
|
||||||
return user;
|
return user;
|
||||||
@@ -570,7 +580,7 @@ namespace IRaCIS.Core.Application.Service
|
|||||||
saveItem.OrganizationName = organizationName;
|
saveItem.OrganizationName = organizationName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
saveItem.UserCeateSource = UserCeateSource.AdminCreate;
|
||||||
saveItem.Password = MD5Helper.Md5(IRCEmailPasswordHelper.GenerateRandomPassword(10));
|
saveItem.Password = MD5Helper.Md5(IRCEmailPasswordHelper.GenerateRandomPassword(10));
|
||||||
|
|
||||||
var addRoleList = new List<UserRole>();
|
var addRoleList = new List<UserRole>();
|
||||||
@@ -817,7 +827,7 @@ namespace IRaCIS.Core.Application.Service
|
|||||||
{
|
{
|
||||||
//删除验证码历史记录
|
//删除验证码历史记录
|
||||||
await _verificationCodeRepository.BatchDeleteNoTrackingAsync(t => t.Id == verificationRecord.Id);
|
await _verificationCodeRepository.BatchDeleteNoTrackingAsync(t => t.Id == verificationRecord.Id);
|
||||||
await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, ActionUserName = _userInfo.UserName, TargetIdentityUserId = identityUserId, OptType = UserOptType.MFALogin }, true);
|
await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, ActionUserName = _userInfo.UserName, ActionIdentityUserId = identityUserId, OptType = UserOptType.MFALogin }, true);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -826,114 +836,15 @@ namespace IRaCIS.Core.Application.Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 用户登陆
|
/// 设置是否忽略异地登录
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="userName"></param>
|
/// <param name="inDto"></param>
|
||||||
/// <param name="password"></param>
|
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[NonDynamicMethod]
|
[HttpPost]
|
||||||
public async Task<IResponseOutput<LoginReturnDTO>> Login(string userName, string password)
|
public async Task<IResponseOutput> SetIsIgnoreUncommonly(SetIsIgnoreUncommonlyInDto inDto)
|
||||||
{
|
{
|
||||||
|
await _userLogRepository.UpdatePartialFromQueryAsync(inDto.Id, x => new UserLog() { IsIgnoreUncommonly = inDto.IsIgnoreUncommonly }, true);
|
||||||
int maxFailures = _verifyConfig.CurrentValue.LoginMaxFailCount;
|
return ResponseOutput.Ok();
|
||||||
int lockoutMinutes = _verifyConfig.CurrentValue.LoginFailLockMinutes;
|
|
||||||
|
|
||||||
// 生成缓存键
|
|
||||||
string cacheKey = CacheKeys.UserLoginError(userName);
|
|
||||||
|
|
||||||
// 从缓存中获取登录失败次数
|
|
||||||
int? failCount = await _fusionCache.GetOrDefaultAsync<int?>(cacheKey);
|
|
||||||
|
|
||||||
if (failCount == null)
|
|
||||||
{
|
|
||||||
failCount = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//每次登录 都重置缓存时间
|
|
||||||
await _fusionCache.SetAsync<int?>(cacheKey, failCount, TimeSpan.FromMinutes(lockoutMinutes));
|
|
||||||
|
|
||||||
|
|
||||||
if (failCount >= maxFailures)
|
|
||||||
{
|
|
||||||
//await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, LoginUserId = Guid.Empty, OptUserId = Guid.Empty, LoginFaildName = userName, LoginPassword = password, OptType = UserOptType.AccountLocked }, true);
|
|
||||||
|
|
||||||
//$"密码连续错误{maxFailures}次,当前账号已被限制登录,请等待 {lockoutMinutes} 分钟后再试。"
|
|
||||||
throw new BusinessValidationFailedException(_localizer["User_ErrorLimit", maxFailures, lockoutMinutes]);
|
|
||||||
}
|
|
||||||
|
|
||||||
var userLoginReturnModel = new LoginReturnDTO();
|
|
||||||
|
|
||||||
|
|
||||||
var loginUser = await _userRoleRepository.Where(u => u.UserName.Equals(userName) && u.Password == password).ProjectTo<UserBasicInfo>(_mapper.ConfigurationProvider).FirstOrDefaultAsync();
|
|
||||||
|
|
||||||
if (loginUser == null)
|
|
||||||
{
|
|
||||||
|
|
||||||
//错误次数累加
|
|
||||||
failCount++;
|
|
||||||
await _fusionCache.SetAsync(cacheKey, failCount, TimeSpan.FromMinutes(lockoutMinutes));
|
|
||||||
|
|
||||||
var errorPwdUserId = await _identityUserRepository.Where(u => u.UserName == userName).Select(t => t.Id).FirstOrDefaultAsync();
|
|
||||||
|
|
||||||
//await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, LoginUserId = errorPwdUserId, OptUserId = errorPwdUserId, LoginFaildName = userName, LoginPassword = password, OptType = UserOptType.AccountOrPasswordError }, true);
|
|
||||||
|
|
||||||
return ResponseOutput.NotOk(_localizer["User_CheckNameOrPw"], new LoginReturnDTO());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (loginUser.Status == 0)
|
|
||||||
{
|
|
||||||
//await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, LoginUserId = loginUser.IdentityUserId, OptUserId = loginUser.IdentityUserId, LoginFaildName = userName, OptType = UserOptType.LoginLockedAccount }, true);
|
|
||||||
|
|
||||||
//---该用户已经被禁用。
|
|
||||||
return ResponseOutput.NotOk(_localizer["User_Disabled"], new LoginReturnDTO());
|
|
||||||
}
|
|
||||||
|
|
||||||
//登录成功 清除缓存
|
|
||||||
await _fusionCache.SetAsync(cacheKey, 0, TimeSpan.FromMinutes(lockoutMinutes));
|
|
||||||
var ipinfo = _searcher.Search(_userInfo.IP);
|
|
||||||
|
|
||||||
var iPRegion = string.Join('|', ipinfo.Split('|').TakeLast(3));
|
|
||||||
|
|
||||||
if (loginUser.LastLoginIP != string.Empty)
|
|
||||||
{
|
|
||||||
// 与上一次IP不一致
|
|
||||||
if (loginUser.LastLoginIP != iPRegion)
|
|
||||||
{
|
|
||||||
loginUser.LoginState = 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//超过90天没修改密码
|
|
||||||
if (_verifyConfig.CurrentValue.IsNeedChangePassWord && loginUser.LastChangePassWordTime != null && DateTime.Now.AddDays(-_verifyConfig.CurrentValue.ChangePassWordDays) > loginUser.LastChangePassWordTime.Value)
|
|
||||||
{
|
|
||||||
loginUser.NeedChangePassWord = true;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, LoginUserId = loginUser.IdentityUserId, OptUserId = loginUser.IdentityUserId, OptType = UserOptType.Login }, true);
|
|
||||||
|
|
||||||
userLoginReturnModel.BasicInfo = loginUser;
|
|
||||||
|
|
||||||
if (loginUser.LastChangePassWordTime == null)
|
|
||||||
{
|
|
||||||
await _identityUserRepository.BatchUpdateNoTrackingAsync(x => x.Id == loginUser.IdentityUserId, x => new IdentityUser()
|
|
||||||
{
|
|
||||||
LastChangePassWordTime = DateTime.Now
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
await _identityUserRepository.BatchUpdateNoTrackingAsync(x => x.Id == loginUser.IdentityUserId, x => new IdentityUser()
|
|
||||||
{
|
|
||||||
LastLoginIP = iPRegion,
|
|
||||||
LastLoginTime = DateTime.Now
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
return ResponseOutput.Ok(userLoginReturnModel);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
@@ -949,10 +860,11 @@ namespace IRaCIS.Core.Application.Service
|
|||||||
.WhereIf(inQuery.TargetIdentityUserId != null, t => t.TargetIdentityUserId == inQuery.TargetIdentityUserId)
|
.WhereIf(inQuery.TargetIdentityUserId != null, t => t.TargetIdentityUserId == inQuery.TargetIdentityUserId)
|
||||||
.WhereIf(inQuery.TrialId != null, t => t.ActionIdentityUser.UserTrialList.Any(c => c.TrialId == inQuery.TrialId) || t.TargetIdentityUser.UserTrialList.Any(c => c.TrialId == inQuery.TrialId))
|
.WhereIf(inQuery.TrialId != null, t => t.ActionIdentityUser.UserTrialList.Any(c => c.TrialId == inQuery.TrialId) || t.TargetIdentityUser.UserTrialList.Any(c => c.TrialId == inQuery.TrialId))
|
||||||
.WhereIf(trialCreateTime != null, t => t.CreateTime >= trialCreateTime)
|
.WhereIf(trialCreateTime != null, t => t.CreateTime >= trialCreateTime)
|
||||||
.WhereIf(inQuery.OptType != null, t => t.OptType == inQuery.OptType)
|
.WhereIf(inQuery.OptTypeList != null && inQuery.OptTypeList.Count > 0, t => inQuery.OptTypeList.Contains(t.OptType))
|
||||||
.WhereIf(inQuery.BeginDate != null, t => t.CreateTime >= inQuery.BeginDate)
|
.WhereIf(inQuery.BeginDate != null, t => t.CreateTime >= inQuery.BeginDate)
|
||||||
.WhereIf(inQuery.EndDate != null, t => t.CreateTime <= inQuery.EndDate)
|
.WhereIf(inQuery.EndDate != null, t => t.CreateTime <= inQuery.EndDate)
|
||||||
.WhereIf(inQuery.IsLoginUncommonly != null, t => t.IsLoginUncommonly == inQuery.IsLoginUncommonly)
|
.WhereIf(inQuery.IsLoginUncommonly != null , t => t.IsLoginUncommonly== inQuery.IsLoginUncommonly)
|
||||||
|
|
||||||
.WhereIf(!string.IsNullOrEmpty(inQuery.LoginUserName), t => t.ActionUserName.Contains(inQuery.LoginUserName!))
|
.WhereIf(!string.IsNullOrEmpty(inQuery.LoginUserName), t => t.ActionUserName.Contains(inQuery.LoginUserName!))
|
||||||
.WhereIf(!string.IsNullOrEmpty(inQuery.LoginFaildName), t => t.ActionUserName.Contains(inQuery.LoginFaildName!))
|
.WhereIf(!string.IsNullOrEmpty(inQuery.LoginFaildName), t => t.ActionUserName.Contains(inQuery.LoginFaildName!))
|
||||||
.WhereIf(!string.IsNullOrEmpty(inQuery.IP), t => t.IP.Contains(inQuery.IP!))
|
.WhereIf(!string.IsNullOrEmpty(inQuery.IP), t => t.IP.Contains(inQuery.IP!))
|
||||||
@@ -963,6 +875,17 @@ namespace IRaCIS.Core.Application.Service
|
|||||||
|
|
||||||
var pageList = await userLogQueryable.ToPagedListAsync(inQuery);
|
var pageList = await userLogQueryable.ToPagedListAsync(inQuery);
|
||||||
|
|
||||||
|
|
||||||
|
//项目创建账户的时候,没有用户名,但是目标用户Id 有值,导致查询出来有名字,所以在此单独处理下
|
||||||
|
|
||||||
|
foreach (var item in pageList.CurrentPageData)
|
||||||
|
{
|
||||||
|
if (item.OptType == UserOptType.AddUser)
|
||||||
|
{
|
||||||
|
item.TargetIdentityUserName = item.UserObj.UserName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return pageList;
|
return pageList;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -999,7 +922,7 @@ namespace IRaCIS.Core.Application.Service
|
|||||||
var password = loginDto.Password;
|
var password = loginDto.Password;
|
||||||
|
|
||||||
var emailConfig = _emailConfig.CurrentValue;
|
var emailConfig = _emailConfig.CurrentValue;
|
||||||
var companyInfo = new SystemEmailSendConfigView() { CompanyName = emailConfig.CompanyName, CompanyNameCN = emailConfig.CompanyNameCN, CompanyShortName = emailConfig.CompanyShortName, CompanyShortNameCN = emailConfig.CompanyShortNameCN };
|
var companyInfo = new SystemEmailSendConfigView() { CompanyName = emailConfig.CompanyName, CompanyNameCN = emailConfig.CompanyNameCN, CompanyShortName = emailConfig.CompanyShortName, CompanyShortNameCN = emailConfig.CompanyShortNameCN,SystemShortName=emailConfig.SystemShortName };
|
||||||
|
|
||||||
|
|
||||||
int maxFailures = _verifyConfig.CurrentValue.LoginMaxFailCount;
|
int maxFailures = _verifyConfig.CurrentValue.LoginMaxFailCount;
|
||||||
@@ -1033,9 +956,9 @@ namespace IRaCIS.Core.Application.Service
|
|||||||
var userLoginReturnModel = new IRCLoginReturnDTO();
|
var userLoginReturnModel = new IRCLoginReturnDTO();
|
||||||
|
|
||||||
|
|
||||||
var loginUser = await _identityUserRepository.Where(u => u.UserName.Equals(userName) && u.Password == password).ProjectTo<UserBasicInfo>(_mapper.ConfigurationProvider).FirstOrDefaultAsync();
|
var loginUser = await _identityUserRepository.Where(u => (u.UserName.Equals(userName) || u.EMail.Equals(userName)) && u.Password == password).ProjectTo<UserBasicInfo>(_mapper.ConfigurationProvider).FirstOrDefaultAsync();
|
||||||
|
|
||||||
var existUserLoginInfo = await _identityUserRepository.Where(u => u.UserName == userName).Select(t => new { t.LastLoginIP, t.LastChangePassWordTime, t.Id }).FirstOrDefaultAsync();
|
var existUserLoginInfo = await _identityUserRepository.Where(u => u.UserName == userName || u.EMail == userName).Select(t => new { t.LastLoginIP, t.LastChangePassWordTime, t.Id }).FirstOrDefaultAsync();
|
||||||
|
|
||||||
var isExistAccount = existUserLoginInfo != null;
|
var isExistAccount = existUserLoginInfo != null;
|
||||||
|
|
||||||
@@ -1046,42 +969,49 @@ namespace IRaCIS.Core.Application.Service
|
|||||||
//账号在系统存在
|
//账号在系统存在
|
||||||
if (isExistAccount || loginUser != null)
|
if (isExistAccount || loginUser != null)
|
||||||
{
|
{
|
||||||
var ipinfo = _searcher.Search(_userInfo.IP);
|
//var ipinfo = _searcher.Search(_userInfo.IP);
|
||||||
|
|
||||||
var iPRegion = string.Join('|', ipinfo.Split('|').TakeLast(3));
|
//var iPRegion = string.Join('|', ipinfo.Split('|').TakeLast(3));
|
||||||
|
|
||||||
string SplitAndConcatenate(string input)
|
//string SplitAndConcatenate(string input)
|
||||||
|
//{
|
||||||
|
// string[] parts = input.Split('|');
|
||||||
|
// return parts.Length >= 3 ? parts[0] + parts[1] : string.Join("", parts);
|
||||||
|
//}
|
||||||
|
|
||||||
|
var iPRegion = IPCityHelper.GetCityResponse(_userInfo.IP);
|
||||||
|
|
||||||
|
//设置本次登录的IP
|
||||||
|
await _identityUserRepository.BatchUpdateNoTrackingAsync(x => x.Id == existUserLoginInfo.Id, x => new IdentityUser()
|
||||||
{
|
{
|
||||||
string[] parts = input.Split('|');
|
LastLoginIP = iPRegion,
|
||||||
return parts.Length >= 3 ? parts[0] + parts[1] : string.Join("", parts);
|
LastLoginTime = DateTime.Now
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
//超过90天没修改密码
|
||||||
|
|
||||||
|
if (loginUser!= null&&_verifyConfig.CurrentValue.IsNeedChangePassWord && loginUser.LastChangePassWordTime != null && DateTime.Now.AddDays(-_verifyConfig.CurrentValue.ChangePassWordDays) > loginUser.LastChangePassWordTime.Value)
|
||||||
|
{
|
||||||
|
loginUser.NeedChangePassWord = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (existUserLoginInfo.LastLoginIP != string.Empty)
|
if (existUserLoginInfo.LastLoginIP != string.Empty)
|
||||||
{
|
{
|
||||||
// 与上一次区域不一致
|
// 与上一次区域不一致
|
||||||
if (SplitAndConcatenate(existUserLoginInfo.LastLoginIP) != SplitAndConcatenate(iPRegion))
|
//if (SplitAndConcatenate(existUserLoginInfo.LastLoginIP) != SplitAndConcatenate(iPRegion))
|
||||||
|
if (existUserLoginInfo.LastLoginIP != iPRegion)
|
||||||
{
|
{
|
||||||
|
|
||||||
isLoginUncommonly = true;
|
isLoginUncommonly = true;
|
||||||
|
|
||||||
//设置上次登录的IP
|
|
||||||
await _identityUserRepository.BatchUpdateNoTrackingAsync(x => x.Id == existUserLoginInfo.Id, x => new IdentityUser()
|
|
||||||
{
|
|
||||||
LastLoginIP = iPRegion,
|
|
||||||
LastLoginTime = DateTime.Now
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
if (loginUser != null)
|
if (loginUser != null)
|
||||||
{
|
{
|
||||||
//异地登录
|
//异地登录
|
||||||
loginUser.LoginState = 2;
|
loginUser.LoginState = 2;
|
||||||
|
|
||||||
//超过90天没修改密码
|
|
||||||
if (_verifyConfig.CurrentValue.IsNeedChangePassWord && loginUser.LastChangePassWordTime != null && DateTime.Now.AddDays(-_verifyConfig.CurrentValue.ChangePassWordDays) > loginUser.LastChangePassWordTime.Value)
|
|
||||||
{
|
|
||||||
loginUser.NeedChangePassWord = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1105,13 +1035,10 @@ namespace IRaCIS.Core.Application.Service
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//登录成功的,才会算异地登录
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (loginUser.Status == 0)
|
if (loginUser.Status == 0)
|
||||||
{
|
{
|
||||||
await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, ActionIdentityUserId = loginUser.IdentityUserId, ActionUserName = userName, OptType = UserOptType.LoginLockedAccount, IsLoginUncommonly = isLoginUncommonly }, true);
|
await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, ActionIdentityUserId = loginUser.IdentityUserId, ActionUserName = loginUser.UserName, OptType = UserOptType.LoginLockedAccount, IsLoginUncommonly = isLoginUncommonly }, true);
|
||||||
|
|
||||||
//---该用户已经被禁用。
|
//---该用户已经被禁用。
|
||||||
return ResponseOutput.NotOk(_localizer["User_Disabled"], new IRCLoginReturnDTO());
|
return ResponseOutput.NotOk(_localizer["User_Disabled"], new IRCLoginReturnDTO());
|
||||||
@@ -1121,7 +1048,7 @@ namespace IRaCIS.Core.Application.Service
|
|||||||
await _fusionCache.SetAsync(cacheKey, 0, TimeSpan.FromMinutes(lockoutMinutes));
|
await _fusionCache.SetAsync(cacheKey, 0, TimeSpan.FromMinutes(lockoutMinutes));
|
||||||
|
|
||||||
|
|
||||||
await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, ActionIdentityUserId = loginUser.IdentityUserId, OptType = UserOptType.Login, IsLoginUncommonly = isLoginUncommonly }, true);
|
await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, ActionIdentityUserId = loginUser.IdentityUserId, ActionUserName = loginUser.UserName, OptType = UserOptType.Login, IsLoginUncommonly = isLoginUncommonly }, true);
|
||||||
|
|
||||||
userLoginReturnModel.BasicInfo = loginUser;
|
userLoginReturnModel.BasicInfo = loginUser;
|
||||||
|
|
||||||
@@ -1177,7 +1104,7 @@ namespace IRaCIS.Core.Application.Service
|
|||||||
await _fusionCache.SetAsync(CacheKeys.UserAutoLoginOut(identityUserId), DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), TimeSpan.FromMinutes(_verifyConfig.CurrentValue.AutoLoginOutMinutes));
|
await _fusionCache.SetAsync(CacheKeys.UserAutoLoginOut(identityUserId), DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), TimeSpan.FromMinutes(_verifyConfig.CurrentValue.AutoLoginOutMinutes));
|
||||||
|
|
||||||
|
|
||||||
userLoginReturnModel.BasicInfo.AccountList = await _userRoleRepository.Where(t => t.IdentityUserId == identityUserId).ProjectTo<UserAccountInfo>(_mapper.ConfigurationProvider).ToListAsync();
|
userLoginReturnModel.BasicInfo.AccountList = await _userRoleRepository.Where(t => t.IdentityUserId == identityUserId).ProjectTo<UserAccountInfo>(_mapper.ConfigurationProvider).OrderBy(t => t.UserTypeShortName).ToListAsync();
|
||||||
userLoginReturnModel.CompanyInfo = companyInfo;
|
userLoginReturnModel.CompanyInfo = companyInfo;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ namespace IRaCIS.Core.Application.Contracts
|
|||||||
{
|
{
|
||||||
|
|
||||||
var userTypeRoleQueryable = _userTypeRepository
|
var userTypeRoleQueryable = _userTypeRepository
|
||||||
|
.WhereIf(_userInfo.UserTypeEnumInt != (int)UserTypeEnum.SuperAdmin, t => t.IsEnable == true)
|
||||||
.WhereIf(!string.IsNullOrWhiteSpace(userTypeQuery.SearchFilter), t => t.Description.Contains(userTypeQuery.SearchFilter!) || t.UserTypeName.Contains(userTypeQuery.SearchFilter!) || t.UserTypeShortName.Contains(userTypeQuery.SearchFilter!))
|
.WhereIf(!string.IsNullOrWhiteSpace(userTypeQuery.SearchFilter), t => t.Description.Contains(userTypeQuery.SearchFilter!) || t.UserTypeName.Contains(userTypeQuery.SearchFilter!) || t.UserTypeShortName.Contains(userTypeQuery.SearchFilter!))
|
||||||
|
|
||||||
.WhereIf(userTypeQuery.GroupId != null, t => t.UserTypeGroupList.Any(t => t.DictionaryId == userTypeQuery.GroupId))
|
.WhereIf(userTypeQuery.GroupId != null, t => t.UserTypeGroupList.Any(t => t.DictionaryId == userTypeQuery.GroupId))
|
||||||
@@ -140,7 +141,7 @@ namespace IRaCIS.Core.Application.Contracts
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
var query = _userTypeRepository.Where(x => x.UserTypeEnum != UserTypeEnum.SuperAdmin)
|
var query = _userTypeRepository.Where(x => x.UserTypeEnum != UserTypeEnum.SuperAdmin && x.IsEnable==true)
|
||||||
.WhereIf(userTypeSelectEnum != UserTypeSelectEnum.None, t => userTypeEnums.Contains(t.UserTypeEnum))
|
.WhereIf(userTypeSelectEnum != UserTypeSelectEnum.None, t => userTypeEnums.Contains(t.UserTypeEnum))
|
||||||
.OrderBy(t => t.UserTypeShortName).ProjectTo<TrialUserType>(_mapper.ConfigurationProvider);
|
.OrderBy(t => t.UserTypeShortName).ProjectTo<TrialUserType>(_mapper.ConfigurationProvider);
|
||||||
|
|
||||||
@@ -158,7 +159,8 @@ namespace IRaCIS.Core.Application.Contracts
|
|||||||
public async Task<List<TrialUserType>> GetTrialUserTypeList()
|
public async Task<List<TrialUserType>> GetTrialUserTypeList()
|
||||||
{
|
{
|
||||||
//排除其他组的用户
|
//排除其他组的用户
|
||||||
var query = _userTypeRepository.Where(x => x.UserTypeEnum != UserTypeEnum.SuperAdmin)
|
var query = _userTypeRepository
|
||||||
|
.Where(x => x.UserTypeEnum != UserTypeEnum.SuperAdmin && x.IsEnable==true)
|
||||||
.Where(t => !t.UserTypeGroupList.Any(t => t.Group.Code == "3"))
|
.Where(t => !t.UserTypeGroupList.Any(t => t.Group.Code == "3"))
|
||||||
.OrderBy(t => t.UserTypeShortName).ProjectTo<TrialUserType>(_mapper.ConfigurationProvider);
|
.OrderBy(t => t.UserTypeShortName).ProjectTo<TrialUserType>(_mapper.ConfigurationProvider);
|
||||||
|
|
||||||
|
|||||||
@@ -152,7 +152,9 @@ namespace IRaCIS.Core.Application.Service
|
|||||||
|
|
||||||
CreateMap<IdentityUser, UserBasicInfo>()
|
CreateMap<IdentityUser, UserBasicInfo>()
|
||||||
.ForMember(d => d.IdentityUserId, c => c.MapFrom(t => t.Id));
|
.ForMember(d => d.IdentityUserId, c => c.MapFrom(t => t.Id));
|
||||||
CreateMap<IdentityUser, UserListDTO>();
|
CreateMap<IdentityUser, UserListDTO>()
|
||||||
|
.ForMember(d => d.TrialCode, u => u.MapFrom(s => s.Trial.TrialCode))
|
||||||
|
.ForMember(d => d.ResearchProgramNo, u => u.MapFrom(s => s.Trial.ResearchProgramNo));
|
||||||
|
|
||||||
CreateMap<UserAddUserType, UserRole>().ReverseMap();
|
CreateMap<UserAddUserType, UserRole>().ReverseMap();
|
||||||
|
|
||||||
@@ -172,7 +174,7 @@ namespace IRaCIS.Core.Application.Service
|
|||||||
CreateMap<UpdateTrialUserCommand, TrialIdentityUser>();
|
CreateMap<UpdateTrialUserCommand, TrialIdentityUser>();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,14 +6,9 @@
|
|||||||
namespace IRaCIS.Core.Application.Contracts
|
namespace IRaCIS.Core.Application.Contracts
|
||||||
{
|
{
|
||||||
/// <summary> NoneDicomStudyFileView 列表视图模型 </summary>
|
/// <summary> NoneDicomStudyFileView 列表视图模型 </summary>
|
||||||
public class NoneDicomStudyFileView
|
public class NoneDicomStudyFileView: NoneDicomStudyFileAddOrEdit
|
||||||
{
|
{
|
||||||
public Guid Id { get; set; }
|
|
||||||
public string Path { get; set; } = string.Empty;
|
|
||||||
public string FileName { get; set; } = string.Empty;
|
|
||||||
public DateTime CreateTime { get; set; }
|
|
||||||
public Guid CreateUserId { get; set; }
|
|
||||||
public Guid NoneDicomStudyId { get; set; }
|
|
||||||
|
|
||||||
public long? FileSize { get; set; }
|
public long? FileSize { get; set; }
|
||||||
|
|
||||||
@@ -21,7 +16,9 @@ namespace IRaCIS.Core.Application.Contracts
|
|||||||
|
|
||||||
public string FileType { get; set; }
|
public string FileType { get; set; }
|
||||||
|
|
||||||
|
public bool IsReading { get; set; }
|
||||||
|
|
||||||
|
public bool IsDeleted { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -33,24 +30,9 @@ namespace IRaCIS.Core.Application.Contracts
|
|||||||
public string AuditInfo { get; set; } = string.Empty;
|
public string AuditInfo { get; set; } = string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class NoneDicomStudyAndFile
|
|
||||||
{
|
|
||||||
public string NoneDicomStudyCode { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
public List<NoneDicomStudyFileView> NoneDicomStudyFileList { get; set; } = new List<NoneDicomStudyFileView>();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
///<summary>NoneDicomStudyFileQuery 列表查询参数模型</summary>
|
|
||||||
public class NoneDicomStudyFileQuery
|
|
||||||
{
|
|
||||||
///<summary> Path</summary>
|
|
||||||
public string Path { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
///<summary> FileName</summary>
|
|
||||||
public string FileName { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
///<summary> NoneDicomStudyFileAddOrEdit 列表查询参数模型</summary>
|
///<summary> NoneDicomStudyFileAddOrEdit 列表查询参数模型</summary>
|
||||||
public class NoneDicomStudyFileAddOrEdit
|
public class NoneDicomStudyFileAddOrEdit
|
||||||
|
|||||||
@@ -8,19 +8,25 @@ namespace IRaCIS.Core.Application.Contracts
|
|||||||
/// <summary> NoneDicomStudyView 列表视图模型 </summary>
|
/// <summary> NoneDicomStudyView 列表视图模型 </summary>
|
||||||
public class NoneDicomStudyView : NoneDicomStudyAddOrEdit
|
public class NoneDicomStudyView : NoneDicomStudyAddOrEdit
|
||||||
{
|
{
|
||||||
|
public DateTime CreateTime { get; set; }
|
||||||
public DateTime UpdateTime { get; set; }
|
public DateTime UpdateTime { get; set; }
|
||||||
public string CodeView { get; set; }
|
public string CodeView { get; set; }
|
||||||
|
|
||||||
public int FileCount { get; set; }
|
public int FileCount { get; set; }
|
||||||
|
|
||||||
|
public bool IsCriticalSequence { get; set; } = false;
|
||||||
|
|
||||||
|
|
||||||
public List<NoneDicomStudyFileView> NoneDicomStudyFileList { get; set; } = new List<NoneDicomStudyFileView>();
|
public List<NoneDicomStudyFileView> NoneDicomStudyFileList { get; set; } = new List<NoneDicomStudyFileView>();
|
||||||
|
|
||||||
|
|
||||||
|
public bool IsReading { get; set; }
|
||||||
|
|
||||||
|
public bool IsDeleted { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class TaskDicomStudyView : NoneDicomStudyView
|
public class TaskDicomStudyView : NoneDicomStudyView
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///<summary>NoneDicomStudyQuery 列表查询参数模型</summary>
|
///<summary>NoneDicomStudyQuery 列表查询参数模型</summary>
|
||||||
@@ -51,8 +57,7 @@ namespace IRaCIS.Core.Application.Contracts
|
|||||||
public DateTime ImageDate { get; set; }
|
public DateTime ImageDate { get; set; }
|
||||||
public string Description { get; set; } = string.Empty;
|
public string Description { get; set; } = string.Empty;
|
||||||
|
|
||||||
public int Code { get; set; }
|
public string StudyName { get; set; }
|
||||||
|
|
||||||
|
|
||||||
public string VideoName { get; set; } = string.Empty;
|
public string VideoName { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ namespace IRaCIS.Core.Application.Contracts.DTO
|
|||||||
|
|
||||||
public int Type { get; set; }
|
public int Type { get; set; }
|
||||||
|
|
||||||
|
public string StudyName { get; set; } = String.Empty;
|
||||||
|
|
||||||
public string Modality { get; set; } = String.Empty;
|
public string Modality { get; set; } = String.Empty;
|
||||||
|
|
||||||
public string BodyPart { get; set; } = String.Empty;
|
public string BodyPart { get; set; } = String.Empty;
|
||||||
@@ -353,8 +355,13 @@ namespace IRaCIS.Core.Application.Contracts.DTO
|
|||||||
|
|
||||||
public int? NotClosedChallengeCount { get; set; }
|
public int? NotClosedChallengeCount { get; set; }
|
||||||
|
|
||||||
|
public List<StudyName> StudyNameList { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
public List<string> ImageFormatList { get; set; }
|
||||||
|
|
||||||
|
public bool IsShowStudyName { get; set; } = false;
|
||||||
|
|
||||||
}
|
}
|
||||||
public class QAStudyInfoDTO
|
public class QAStudyInfoDTO
|
||||||
{
|
{
|
||||||
@@ -382,10 +389,15 @@ namespace IRaCIS.Core.Application.Contracts.DTO
|
|||||||
public DateTime? StudyTime { get; set; }
|
public DateTime? StudyTime { get; set; }
|
||||||
|
|
||||||
public DateTime? UploadedTime { get; set; }
|
public DateTime? UploadedTime { get; set; }
|
||||||
|
|
||||||
|
public DateTime UpdateTime { get; set; }
|
||||||
|
|
||||||
public string BodyPartExamined { get; set; } = String.Empty;
|
public string BodyPartExamined { get; set; } = String.Empty;
|
||||||
|
|
||||||
public string BodyPartForEdit { get; set; } = String.Empty;
|
public string BodyPartForEdit { get; set; } = String.Empty;
|
||||||
|
|
||||||
|
public string StudyName { get; set; } = string.Empty;
|
||||||
|
|
||||||
public string ModalityForEdit { get; set; } = string.Empty;
|
public string ModalityForEdit { get; set; } = string.Empty;
|
||||||
|
|
||||||
public bool IsHaveUploadFailed { get; set; }
|
public bool IsHaveUploadFailed { get; set; }
|
||||||
@@ -422,6 +434,8 @@ namespace IRaCIS.Core.Application.Contracts.DTO
|
|||||||
//public Guid[] InstanceList = new Guid[0];
|
//public Guid[] InstanceList = new Guid[0];
|
||||||
//public List<string> InstancePathList = new List<string>();
|
//public List<string> InstancePathList = new List<string>();
|
||||||
|
|
||||||
|
public DateTime UpdateTime { get; set; }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,36 @@ using System.ComponentModel.DataAnnotations.Schema;
|
|||||||
namespace IRaCIS.Core.Application.Contracts
|
namespace IRaCIS.Core.Application.Contracts
|
||||||
{
|
{
|
||||||
|
|
||||||
|
public class ImageBackQueryDto : PageInput
|
||||||
|
{
|
||||||
|
[NotDefault]
|
||||||
|
public Guid TrialId { get; set; }
|
||||||
|
|
||||||
|
public Guid? TrialSiteId { get; set; }
|
||||||
|
|
||||||
|
public string? SubjectCode { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public Guid? CreateUserId { get; set; }
|
||||||
|
|
||||||
|
public string? VisitName { get; set; }
|
||||||
|
|
||||||
|
public ImageBackApplyEnum? ApplyUserRole { get; set; }
|
||||||
|
|
||||||
|
public DateTime? ApplyBeginTime { get; set; }
|
||||||
|
|
||||||
|
public DateTime? ApplyEndTime { get; set; }
|
||||||
|
|
||||||
|
public ImageBackStateEnum? ImageBackState { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
public DateTime? AuditBeginTime { get; set; }
|
||||||
|
|
||||||
|
public DateTime? AuditEndTime { get; set; }
|
||||||
|
|
||||||
|
public string[]? VisitPlanArray { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public class CRCVisitSearchDTO : PageInput
|
public class CRCVisitSearchDTO : PageInput
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -81,6 +111,11 @@ namespace IRaCIS.Core.Application.Contracts
|
|||||||
public Guid? SubjectId { get; set; }
|
public Guid? SubjectId { get; set; }
|
||||||
|
|
||||||
public Guid? VisitId { get; set; }
|
public Guid? VisitId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否领取了
|
||||||
|
/// </summary>
|
||||||
|
public bool IsReceived { get; set; } = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class CRCRequestToQCCommand
|
public class CRCRequestToQCCommand
|
||||||
@@ -161,6 +196,13 @@ namespace IRaCIS.Core.Application.Contracts
|
|||||||
[Comment("阅片任务产生之前 采集影像")]
|
[Comment("阅片任务产生之前 采集影像")]
|
||||||
public CollectImagesType CollectImagesEnum { get; set; }
|
public CollectImagesType CollectImagesEnum { get; set; }
|
||||||
|
|
||||||
|
public List<StudyName> StudyNameList { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
public List<string> ImageFormatList { get; set; }
|
||||||
|
|
||||||
|
public bool IsShowStudyName { get; set; } = false;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1211,6 +1253,8 @@ namespace IRaCIS.Core.Application.Contracts
|
|||||||
|
|
||||||
public Guid Id { get; set; }
|
public Guid Id { get; set; }
|
||||||
|
|
||||||
|
public Guid SubjectId { get; set; }
|
||||||
|
|
||||||
public Guid? DoctorUserId { get; set; }
|
public Guid? DoctorUserId { get; set; }
|
||||||
|
|
||||||
public string TaskName { get; set; }
|
public string TaskName { get; set; }
|
||||||
@@ -1265,6 +1309,17 @@ namespace IRaCIS.Core.Application.Contracts
|
|||||||
public DateTime? SignTime { get; set; }
|
public DateTime? SignTime { get; set; }
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region 肿瘤学结果
|
||||||
|
|
||||||
|
[DictionaryTranslateAttribute("OncologyAssessType")]
|
||||||
|
public string OncologyResult { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public string OncologyReason { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public string OncologyUserName { get; set; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
public class CommonLessionExport : CommonEvaluationExport
|
public class CommonLessionExport : CommonEvaluationExport
|
||||||
@@ -1662,6 +1717,50 @@ namespace IRaCIS.Core.Application.Contracts
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
public class ImageBackViewModel
|
||||||
|
{
|
||||||
|
public Guid Id { get; set; }
|
||||||
|
|
||||||
|
public DateTime CreateTime { get; set; }
|
||||||
|
|
||||||
|
public string CreateUserName { get; set; }
|
||||||
|
|
||||||
|
public string CreateUserFullName { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
public DateTime? AuditTime { get; set; }
|
||||||
|
public Guid SubjectVisitId { get; set; }
|
||||||
|
|
||||||
|
public ImageBackApplyEnum ApplyUserRole { get; set; }
|
||||||
|
|
||||||
|
public ImageBackStateEnum ImageBackState { get; set; }
|
||||||
|
|
||||||
|
public DateTime? SubmitTime { get; set; }
|
||||||
|
|
||||||
|
public bool IsUrgent { get; set; }
|
||||||
|
|
||||||
|
public string VisitName { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public DateTime? EarliestScanDate { get; set; }
|
||||||
|
public DateTime? LatestScanDate { get; set; }
|
||||||
|
public decimal VisitNum { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public string SubjectCode { get; set; } = String.Empty;
|
||||||
|
|
||||||
|
public String TrialSiteCode { get; set; } = String.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 申请原因
|
||||||
|
/// </summary>
|
||||||
|
public string ApplyReason { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 结果备注
|
||||||
|
/// </summary>
|
||||||
|
public string ResultRemark { get; set; } = string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public class QCCRCVisitViewModel : QCVisitBasicListViewModel
|
public class QCCRCVisitViewModel : QCVisitBasicListViewModel
|
||||||
@@ -2083,6 +2182,8 @@ namespace IRaCIS.Core.Application.Contracts
|
|||||||
public DateTime? ReviewAuditTime { get; set; }
|
public DateTime? ReviewAuditTime { get; set; }
|
||||||
public DateTime? PreliminaryAuditTime { get; set; }
|
public DateTime? PreliminaryAuditTime { get; set; }
|
||||||
|
|
||||||
|
public bool IsImageBackApplying { get; set; }
|
||||||
|
|
||||||
|
|
||||||
public DateTime? AuditTime => QCProcessEnum == TrialQCProcess.SingleAudit ? PreliminaryAuditTime : (QCProcessEnum == TrialQCProcess.DoubleAudit ? ReviewAuditTime : null);
|
public DateTime? AuditTime => QCProcessEnum == TrialQCProcess.SingleAudit ? PreliminaryAuditTime : (QCProcessEnum == TrialQCProcess.DoubleAudit ? ReviewAuditTime : null);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -121,6 +121,41 @@ namespace IRaCIS.Core.Application.Service
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return svExpression;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Expression<Func<SubjectVisitImageBackRecord, bool>> GetSubjectVisitImageBackRecordFilter(string[]? VisitPlanArray)
|
||||||
|
{
|
||||||
|
Expression<Func<SubjectVisitImageBackRecord, bool>> svExpression = x => true;
|
||||||
|
|
||||||
|
bool isNeedVisitSearch = VisitPlanArray != null && VisitPlanArray?.Length > 0;
|
||||||
|
|
||||||
|
if (isNeedVisitSearch)
|
||||||
|
{
|
||||||
|
var inPlanArray = VisitPlanArray!.Where(t => !t.Contains('.')).Select(t => decimal.Parse(t)).ToArray();
|
||||||
|
var isSelectOutPlan = VisitPlanArray!.Any(t => t.Contains('.'));
|
||||||
|
|
||||||
|
|
||||||
|
if (inPlanArray.Length > 0)
|
||||||
|
{
|
||||||
|
svExpression = svExpression.And(t => inPlanArray.Contains(t.SubjectVisit.VisitNum));
|
||||||
|
|
||||||
|
if (isSelectOutPlan)
|
||||||
|
{
|
||||||
|
svExpression = svExpression.Or(t => t.SubjectVisit.InPlan == false);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (isSelectOutPlan)
|
||||||
|
{
|
||||||
|
svExpression = t => t.SubjectVisit.InPlan == false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return svExpression;
|
return svExpression;
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
using IRaCIS.Core.Application.Contracts;
|
using IRaCIS.Core.Application.Contracts;
|
||||||
using IRaCIS.Core.Application.Contracts.DTO;
|
using IRaCIS.Core.Application.Contracts.DTO;
|
||||||
using IRaCIS.Core.Application.Service.Reading.Dto;
|
using IRaCIS.Core.Application.Service.Reading.Dto;
|
||||||
|
using IRaCIS.Core.Application.ViewModel;
|
||||||
using IRaCIS.Core.Domain.Share;
|
using IRaCIS.Core.Domain.Share;
|
||||||
using IRaCIS.Core.Infrastructure;
|
using IRaCIS.Core.Infrastructure;
|
||||||
|
using IRaCIS.Core.Infrastructure.Extention;
|
||||||
using MassTransit.Initializers;
|
using MassTransit.Initializers;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
@@ -21,10 +23,47 @@ namespace IRaCIS.Core.Application.Image.QA
|
|||||||
IRepository<DicomSeries> _dicomSeriesRepository,
|
IRepository<DicomSeries> _dicomSeriesRepository,
|
||||||
IRepository<NoneDicomStudy> _noneDicomStudyRepository,
|
IRepository<NoneDicomStudy> _noneDicomStudyRepository,
|
||||||
IRepository<QCChallenge> _qcChallengeRepository,
|
IRepository<QCChallenge> _qcChallengeRepository,
|
||||||
|
IRepository<SubjectVisitImageBackRecord> _subjectVisitImageBackRecordReposiotry,
|
||||||
IReadingImageTaskService _IReadingImageTaskService, IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer) : BaseService, IQCListService
|
IReadingImageTaskService _IReadingImageTaskService, IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer) : BaseService, IQCListService
|
||||||
{
|
{
|
||||||
|
|
||||||
|
#region CRC IQC 直接申请回退影像流程
|
||||||
|
|
||||||
|
public async Task<IResponseOutput> GetImageBackApplyUserList(Guid trialId)
|
||||||
|
{
|
||||||
|
var list = _subjectVisitImageBackRecordReposiotry.Where(t => t.SubjectVisit.TrialId == trialId).Select(t => new { t.CreateUserId, t.CreateUserRole.UserName, t.CreateUserRole.FullName }).Distinct().ToList();
|
||||||
|
|
||||||
|
return ResponseOutput.Ok(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<IResponseOutput<PageOutput<ImageBackViewModel>>> GetImageBackList(ImageBackQueryDto inQuery)
|
||||||
|
{
|
||||||
|
var svExpression = QCCommon.GetSubjectVisitImageBackRecordFilter(inQuery.VisitPlanArray);
|
||||||
|
|
||||||
|
var query = _subjectVisitImageBackRecordReposiotry.Where(t => t.SubjectVisit.TrialId == inQuery.TrialId)
|
||||||
|
.WhereIf(inQuery.TrialSiteId != null, t => t.SubjectVisit.TrialSiteId == inQuery.TrialSiteId)
|
||||||
|
.WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => t.SubjectVisit.Subject.Code.Contains(inQuery.SubjectCode))
|
||||||
|
.WhereIf(!string.IsNullOrEmpty(inQuery.VisitName), t => t.SubjectVisit.VisitName.Contains(inQuery.VisitName))
|
||||||
|
.WhereIf(inQuery.VisitPlanArray != null && inQuery.VisitPlanArray?.Length > 0, svExpression)
|
||||||
|
.WhereIf(inQuery.CreateUserId != null, t => t.CreateUserId == inQuery.CreateUserId)
|
||||||
|
.WhereIf(inQuery.ApplyUserRole != null, t => t.ApplyUserRole == inQuery.ApplyUserRole)
|
||||||
|
.WhereIf(inQuery.ApplyBeginTime != null, t => t.CreateTime >= inQuery.ApplyBeginTime)
|
||||||
|
.WhereIf(inQuery.ApplyEndTime != null, t => t.CreateTime <= inQuery.ApplyEndTime)
|
||||||
|
.WhereIf(inQuery.ImageBackState != null, t => t.ImageBackState == inQuery.ImageBackState)
|
||||||
|
.WhereIf(inQuery.AuditBeginTime != null, t => t.AuditTime >= inQuery.AuditBeginTime)
|
||||||
|
.WhereIf(inQuery.AuditEndTime != null, t => t.AuditTime <= inQuery.AuditEndTime)
|
||||||
|
.ProjectTo<ImageBackViewModel>(_mapper.ConfigurationProvider);
|
||||||
|
|
||||||
|
var defalutSortArray = new string[] { nameof(ImageBackViewModel.IsUrgent) + " desc", nameof(ImageBackViewModel.SubjectCode), nameof(ImageBackViewModel.VisitNum) };
|
||||||
|
var pageList = await query.ToPagedListAsync(inQuery, defalutSortArray);
|
||||||
|
|
||||||
|
return ResponseOutput.Ok(pageList);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -279,7 +318,7 @@ namespace IRaCIS.Core.Application.Image.QA
|
|||||||
/// <param name="inQuery"></param>
|
/// <param name="inQuery"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
public async Task<(PageOutput<QCCheckWithModalityView>, TrialSubjectAndSVConfig)> GetConsistencyVerificationList(CheckQuery inQuery)
|
public async Task<IResponseOutput<PageOutput<QCCheckWithModalityView>>> GetConsistencyVerificationList(CheckQuery inQuery)
|
||||||
{
|
{
|
||||||
|
|
||||||
var svExpression = QCCommon.GetSubjectVisitFilter(inQuery.VisitPlanArray);
|
var svExpression = QCCommon.GetSubjectVisitFilter(inQuery.VisitPlanArray);
|
||||||
@@ -294,9 +333,14 @@ namespace IRaCIS.Core.Application.Image.QA
|
|||||||
.WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA, t => t.TrialSite.CRCUserList.Any(t => t.UserId == _userInfo.UserRoleId))//CRC 过滤负责的site
|
.WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA, t => t.TrialSite.CRCUserList.Any(t => t.UserId == _userInfo.UserRoleId))//CRC 过滤负责的site
|
||||||
.ProjectTo<QCCheckWithModalityView>(_mapper.ConfigurationProvider);
|
.ProjectTo<QCCheckWithModalityView>(_mapper.ConfigurationProvider);
|
||||||
|
|
||||||
var pageList = await query.ToPagedListAsync(inQuery);
|
|
||||||
|
var defalutSortArray = new string[] { nameof(QCCheckWithModalityView.CheckState), nameof(QCCheckWithModalityView.IsUrgent), nameof(QCCheckWithModalityView.SubjectCode), nameof(QCCheckWithModalityView.VisitNum) };
|
||||||
|
|
||||||
|
var pageList = await query.ToPagedListAsync(inQuery, defalutSortArray);
|
||||||
|
|
||||||
var config = await _trialRepository.Where(t => t.Id == inQuery.TrialId).ProjectTo<TrialSubjectAndSVConfig>(_mapper.ConfigurationProvider).FirstOrDefaultAsync().IfNullThrowException();
|
var config = await _trialRepository.Where(t => t.Id == inQuery.TrialId).ProjectTo<TrialSubjectAndSVConfig>(_mapper.ConfigurationProvider).FirstOrDefaultAsync().IfNullThrowException();
|
||||||
return (pageList, config);
|
|
||||||
|
return ResponseOutput.Ok(pageList, config);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -374,7 +418,7 @@ namespace IRaCIS.Core.Application.Image.QA
|
|||||||
ExistsManual = (await _IReadingImageTaskService.GetManualList(new GetManualListInDto() { TrialId = sv.TrialId })).Count() > 0,
|
ExistsManual = (await _IReadingImageTaskService.GetManualList(new GetManualListInDto() { TrialId = sv.TrialId })).Count() > 0,
|
||||||
SeriesList = temp.SeriesList,
|
SeriesList = temp.SeriesList,
|
||||||
RelationInfo = await GetVisitQCSubjectInfo(subjectVisitId),
|
RelationInfo = await GetVisitQCSubjectInfo(subjectVisitId),
|
||||||
NoneDicomStudyList = await _noneDicomStudyRepository.Where(t => t.SubjectVisitId == subjectVisitId).ProjectTo<NoneDicomStudyView>(_mapper.ConfigurationProvider).ToListAsync(),
|
NoneDicomStudyList = await _noneDicomStudyRepository.Where(t => t.SubjectVisitId == subjectVisitId, ignoreQueryFilters: true).ProjectTo<NoneDicomStudyView>(_mapper.ConfigurationProvider).ToListAsync(),
|
||||||
SubjectClinicalData = await _subjectVisitRepository.Where(t => t.Id == subjectVisitId)
|
SubjectClinicalData = await _subjectVisitRepository.Where(t => t.Id == subjectVisitId)
|
||||||
.ProjectTo<SubjectClinicalDataDto>(_mapper.ConfigurationProvider, new { subjectVisitId = subjectVisitId, token = _userInfo.UserToken }).FirstOrDefaultAsync()
|
.ProjectTo<SubjectClinicalDataDto>(_mapper.ConfigurationProvider, new { subjectVisitId = subjectVisitId, token = _userInfo.UserToken }).FirstOrDefaultAsync()
|
||||||
};
|
};
|
||||||
@@ -404,7 +448,7 @@ namespace IRaCIS.Core.Application.Image.QA
|
|||||||
TypeValue = data.TypeValue
|
TypeValue = data.TypeValue
|
||||||
}).OrderBy(t => t.ShowOrder).ToListAsync();
|
}).OrderBy(t => t.ShowOrder).ToListAsync();
|
||||||
|
|
||||||
var result = questionAnswerlist.Where(x => x.ParentId == null).OrderBy(t=>t.ShowOrder).ToList();
|
var result = questionAnswerlist.Where(x => x.ParentId == null).OrderBy(t => t.ShowOrder).ToList();
|
||||||
result.ForEach(x =>
|
result.ForEach(x =>
|
||||||
{
|
{
|
||||||
GetQuestionChild(x, questionAnswerlist);
|
GetQuestionChild(x, questionAnswerlist);
|
||||||
@@ -528,7 +572,7 @@ namespace IRaCIS.Core.Application.Image.QA
|
|||||||
|
|
||||||
var visit = await _subjectVisitRepository.Where(x => x.Id == subjectVisitId).FirstNotNullAsync();
|
var visit = await _subjectVisitRepository.Where(x => x.Id == subjectVisitId).FirstNotNullAsync();
|
||||||
|
|
||||||
var list = await _dicomStudyRepository.Where(s => s.SubjectVisitId == subjectVisitId).IgnoreQueryFilters().ProjectTo<QAStudyInfoDTO>(_mapper.ConfigurationProvider,new { isNeedStat= isNeedStat }).OrderBy(t => t.StudyCode).ToListAsync();
|
var list = await _dicomStudyRepository.Where(s => s.SubjectVisitId == subjectVisitId).IgnoreQueryFilters().ProjectTo<QAStudyInfoDTO>(_mapper.ConfigurationProvider, new { isNeedStat = isNeedStat }).OrderBy(t => t.StudyCode).ToListAsync();
|
||||||
|
|
||||||
|
|
||||||
var config = await _subjectVisitRepository.Where(t => t.Id == subjectVisitId).Select(t => t.Trial).ProjectTo<TrialSubjectAndSVConfig>(_mapper.ConfigurationProvider).FirstOrDefaultAsync().IfNullThrowException();
|
var config = await _subjectVisitRepository.Where(t => t.Id == subjectVisitId).Select(t => t.Trial).ProjectTo<TrialSubjectAndSVConfig>(_mapper.ConfigurationProvider).FirstOrDefaultAsync().IfNullThrowException();
|
||||||
|
|||||||
@@ -3,12 +3,14 @@ using IRaCIS.Core.Application.Contracts.DTO;
|
|||||||
using IRaCIS.Core.Application.Filter;
|
using IRaCIS.Core.Application.Filter;
|
||||||
using IRaCIS.Core.Application.Helper;
|
using IRaCIS.Core.Application.Helper;
|
||||||
using IRaCIS.Core.Application.Service.Inspection.DTO;
|
using IRaCIS.Core.Application.Service.Inspection.DTO;
|
||||||
|
using IRaCIS.Core.Domain.Models;
|
||||||
using IRaCIS.Core.Domain.Share;
|
using IRaCIS.Core.Domain.Share;
|
||||||
using IRaCIS.Core.Infrastructure;
|
using IRaCIS.Core.Infrastructure;
|
||||||
using Medallion.Threading;
|
using Medallion.Threading;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
using Org.BouncyCastle.Asn1.Cmp;
|
||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.Data;
|
using System.Data;
|
||||||
|
|
||||||
@@ -33,8 +35,13 @@ namespace IRaCIS.Core.Application.Image.QA
|
|||||||
IRepository<ReadModule> _readModuleRepository,
|
IRepository<ReadModule> _readModuleRepository,
|
||||||
IRepository<DicomInstance> _dicomInstanceRepository,
|
IRepository<DicomInstance> _dicomInstanceRepository,
|
||||||
IRepository<TrialQCQuestionAnswer> _trialQCQuestionAnswerRepository,
|
IRepository<TrialQCQuestionAnswer> _trialQCQuestionAnswerRepository,
|
||||||
|
IRepository<NoneDicomStudy> _noneDicomStudyRepository,
|
||||||
|
IRepository<NoneDicomStudyFile> _noneDicomStudyFileRepository,
|
||||||
IRepository<ReadingQuestionCriterionTrial> _readingQuestionCriterionTrialRepository,
|
IRepository<ReadingQuestionCriterionTrial> _readingQuestionCriterionTrialRepository,
|
||||||
IDistributedLockProvider _distributedLockProvider, IReadingClinicalDataService _readingClinicalDataService,
|
IDistributedLockProvider _distributedLockProvider, IReadingClinicalDataService _readingClinicalDataService,
|
||||||
|
IOSSService _oSSService,
|
||||||
|
IRepository<ReadingClinicalData> _readingClinicalDataReposiotry,
|
||||||
|
IRepository<SubjectVisitImageBackRecord> _subjectVisitImageBackRecordReposiotry,
|
||||||
IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer, IWebHostEnvironment _hostEnvironment) : BaseService, IQCOperationService
|
IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer, IWebHostEnvironment _hostEnvironment) : BaseService, IQCOperationService
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -236,6 +243,185 @@ namespace IRaCIS.Core.Application.Image.QA
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region CRC IQC 申请退回
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// CRC IQC 申请影像回退
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="subjectVisitId"></param>
|
||||||
|
/// <param name="ApplyReason"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
/// <exception cref="BusinessValidationFailedException"></exception>
|
||||||
|
[HttpPut]
|
||||||
|
public async Task<IResponseOutput> RequestImageBack(Guid subjectVisitId, string ApplyReason)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (_subjectVisitRepository.Any(t => t.Id == subjectVisitId && t.QCChallengeList.Any(t => t.IsClosed == false)))
|
||||||
|
{
|
||||||
|
//有未关闭的质疑,不允许在此申请影像回退
|
||||||
|
throw new BusinessValidationFailedException(_localizer["QCOperation_HaveNotClosedQCChanllenge"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_subjectVisitRepository.Any(t => t.Id == subjectVisitId && !t.VisitTaskList.Any(u => u.TaskState == TaskState.Effect) && t.SubmitState == SubmitStateEnum.Submitted))
|
||||||
|
{
|
||||||
|
//已提交、未生成任务的才允许申请
|
||||||
|
throw new BusinessValidationFailedException(_localizer["QCOperation_ShouldBeforeCheckPassed"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (_subjectVisitImageBackRecordReposiotry.Any(t => t.SubjectVisitId == subjectVisitId && t.ImageBackState == ImageBackStateEnum.None))
|
||||||
|
{
|
||||||
|
//已经有在申请的影像回退记录
|
||||||
|
throw new BusinessValidationFailedException(_localizer["QCOperation_HaveApplyedImageBack"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_qcChallengeRepository.Any(t => t.SubjectVisitId == subjectVisitId && t.IsClosed == false && t.ReuploadEnum == QCChanllengeReuploadEnum.CRCRequestReupload))
|
||||||
|
{
|
||||||
|
throw new BusinessValidationFailedException(_localizer["QCOperation_SomeOneHaveApplyedImageBack"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var sv = (await _subjectVisitRepository.FirstOrDefaultAsync(t => t.Id == subjectVisitId)).IfNullThrowException();
|
||||||
|
|
||||||
|
if (sv.RequestBackState == RequestBackStateEnum.CRC_RequestBack)
|
||||||
|
{
|
||||||
|
// 该访视已在其他途径申请影像回退中,不允许申请
|
||||||
|
throw new BusinessValidationFailedException(_localizer["QCOperation_SomeOneHaveApplyedImageBack"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
var newRecord = new SubjectVisitImageBackRecord() { SubjectVisitId = subjectVisitId, ApplyReason = ApplyReason, SubmitTime = sv.SubmitTime, EarliestScanDate = sv.EarliestScanDate, LatestScanDate = sv.LatestScanDate };
|
||||||
|
|
||||||
|
if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator)
|
||||||
|
{
|
||||||
|
|
||||||
|
newRecord.ApplyUserRole = ImageBackApplyEnum.CRCRequestBack;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.IQC)
|
||||||
|
{
|
||||||
|
newRecord.ApplyUserRole = ImageBackApplyEnum.IQCRequestBack;
|
||||||
|
}
|
||||||
|
|
||||||
|
await _subjectVisitImageBackRecordReposiotry.AddAsync(newRecord, true);
|
||||||
|
|
||||||
|
return ResponseOutput.Ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// PM 审核CRC IQC 申请影像回退
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="iamgeBackRecordId"></param>
|
||||||
|
/// <param name="isAgree"></param>
|
||||||
|
/// <param name="resultRemark"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
/// <exception cref="BusinessValidationFailedException"></exception>
|
||||||
|
[HttpPut]
|
||||||
|
public async Task<IResponseOutput> AuditImageBack(Guid iamgeBackRecordId, bool isAgree, string? resultRemark)
|
||||||
|
{
|
||||||
|
var backRecord = (await _subjectVisitImageBackRecordReposiotry.FirstOrDefaultAsync(t => t.Id == iamgeBackRecordId)).IfNullThrowException();
|
||||||
|
|
||||||
|
var sv = (await _subjectVisitRepository.FirstOrDefaultAsync(t => t.Id == backRecord.SubjectVisitId)).IfNullThrowException();
|
||||||
|
|
||||||
|
var subjectVisitId = backRecord.SubjectVisitId;
|
||||||
|
|
||||||
|
if (backRecord.ApplyUserRole != ImageBackApplyEnum.CRCRequestBack && backRecord.ApplyUserRole != ImageBackApplyEnum.IQCRequestBack)
|
||||||
|
{
|
||||||
|
//当前访视状态不在影像申请回退状态,不允许审核通过
|
||||||
|
throw new BusinessValidationFailedException(_localizer["QCOperation_NotInRequestImageBackState"]);
|
||||||
|
}
|
||||||
|
if (isAgree)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (_subjectVisitRepository.Any(t => t.Id == subjectVisitId && t.QCChallengeList.Any(t => t.IsClosed == false)))
|
||||||
|
{
|
||||||
|
//有未关闭的质疑,不允许同意影像回退
|
||||||
|
throw new BusinessValidationFailedException(_localizer["QCOperation_HaveNotClosedQCChanllenge"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (sv.SubmitState == SubmitStateEnum.Submitted && _subjectVisitRepository.Any(t => t.Id == backRecord.SubjectVisitId && !t.VisitTaskList.Any(u => u.TaskState == TaskState.Effect)))
|
||||||
|
{
|
||||||
|
backRecord.ImageBackState = ImageBackStateEnum.PMAgreeBack;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//已提交未生成任务的才允许申请
|
||||||
|
throw new BusinessValidationFailedException(_localizer["QCOperation_ShouldBeforeCheckPassed"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#region 回退处理
|
||||||
|
//需要重新产生任务
|
||||||
|
sv.IsVisitTaskGenerated = false;
|
||||||
|
sv.IsPMBackOrReReading = true;
|
||||||
|
|
||||||
|
sv.AuditState = AuditStateEnum.None;
|
||||||
|
sv.SubmitState = SubmitStateEnum.ToSubmit;
|
||||||
|
sv.ReadingStatus = ReadingStatusEnum.ImageNotSubmit;
|
||||||
|
|
||||||
|
//回退后,回退状态恢复
|
||||||
|
sv.RequestBackState = RequestBackStateEnum.NotRequest;
|
||||||
|
sv.IsCheckBack = false;
|
||||||
|
sv.CheckBackTime = null;
|
||||||
|
sv.CheckState = CheckStateEnum.None;
|
||||||
|
sv.CheckChallengeState = CheckChanllengeTypeEnum.None;
|
||||||
|
|
||||||
|
sv.SVENDTC = null;
|
||||||
|
sv.SVSTDTC = null;
|
||||||
|
|
||||||
|
sv.PreliminaryAuditTime = null;
|
||||||
|
sv.SubmitTime = null;
|
||||||
|
sv.ReviewAuditTime = null;
|
||||||
|
sv.CurrentActionUserExpireTime = null;
|
||||||
|
|
||||||
|
|
||||||
|
sv.IsTake = false;
|
||||||
|
sv.CurrentActionUserId = null;
|
||||||
|
sv.PreliminaryAuditUserId = null;
|
||||||
|
sv.ReviewAuditUserId = null;
|
||||||
|
|
||||||
|
|
||||||
|
if (sv.IsBaseLine)
|
||||||
|
{
|
||||||
|
await _readingClinicalDataReposiotry.UpdatePartialFromQueryAsync(t => t.ReadingId == sv.Id && (t.ClinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.Subject || t.ClinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.SubjectVisit), c => new ReadingClinicalData() { IsSign = false, ReadingClinicalDataState = ReadingClinicalDataStatus.HaveUploaded });
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await _readingClinicalDataReposiotry.UpdatePartialFromQueryAsync(t => t.ReadingId == sv.Id && t.ClinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.SubjectVisit, c => new ReadingClinicalData()
|
||||||
|
{
|
||||||
|
IsSign = false,
|
||||||
|
ReadingClinicalDataState = ReadingClinicalDataStatus.HaveUploaded,
|
||||||
|
IsBlind = null,
|
||||||
|
IsComplete = null
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
await _trialQCQuestionAnswerRepository.BatchDeleteNoTrackingAsync(t => t.SubjectVisitId == subjectVisitId);
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
backRecord.ImageBackState = ImageBackStateEnum.PMNotAgreeBack;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
backRecord.AuditTime = DateTime.Now;
|
||||||
|
backRecord.ResultRemark = resultRemark ?? string.Empty;
|
||||||
|
await _subjectVisitRepository.SaveChangesAsync();
|
||||||
|
|
||||||
|
return ResponseOutput.Ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
#region 一致性核查
|
#region 一致性核查
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -264,7 +450,7 @@ namespace IRaCIS.Core.Application.Image.QA
|
|||||||
sv.CheckChallengeState = CheckChanllengeTypeEnum.CRCWaitPMReply;
|
sv.CheckChallengeState = CheckChanllengeTypeEnum.CRCWaitPMReply;
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ProjectManager || _userInfo.UserTypeEnumInt != (int)UserTypeEnum.APM)
|
else if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ProjectManager || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.APM)
|
||||||
{
|
{
|
||||||
sv.CheckChallengeState = CheckChanllengeTypeEnum.PMWaitCRCReply;
|
sv.CheckChallengeState = CheckChanllengeTypeEnum.PMWaitCRCReply;
|
||||||
}
|
}
|
||||||
@@ -380,6 +566,20 @@ namespace IRaCIS.Core.Application.Image.QA
|
|||||||
return ResponseOutput.NotOk(_localizer["QCOperation_Cannotback"]);
|
return ResponseOutput.NotOk(_localizer["QCOperation_Cannotback"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (await _subjectVisitRepository.Where(t => t.Id == subjectVisitId).AnyAsync(t => t.SubjectVisitImageBackRecordList.Any(t => t.ImageBackState == ImageBackStateEnum.None)))
|
||||||
|
{
|
||||||
|
// 该访视已在其他途径申请影像回退中,不允许申请
|
||||||
|
throw new BusinessValidationFailedException(_localizer["QCOperation_SomeOneHaveApplyedImageBack"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sv.RequestBackState == RequestBackStateEnum.CRC_RequestBack)
|
||||||
|
{
|
||||||
|
// 该访视已在其他途径申请影像回退中,不允许申请
|
||||||
|
throw new BusinessValidationFailedException(_localizer["QCOperation_SomeOneHaveApplyedImageBack"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
var QCChallengeId = await _qcChallengeRepository.Where(x => x.SubjectVisitId == subjectVisitId).Select(x => x.Id).FirstOrDefaultAsync();
|
var QCChallengeId = await _qcChallengeRepository.Where(x => x.SubjectVisitId == subjectVisitId).Select(x => x.Id).FirstOrDefaultAsync();
|
||||||
|
|
||||||
await _checkChallengeDialogRepository.AddAsync(new CheckChallengeDialog()
|
await _checkChallengeDialogRepository.AddAsync(new CheckChallengeDialog()
|
||||||
@@ -391,7 +591,7 @@ namespace IRaCIS.Core.Application.Image.QA
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
if (sv.RequestBackState == RequestBackStateEnum.NotRequest || sv.RequestBackState == RequestBackStateEnum.PM_NotAgree)
|
if (sv.RequestBackState != RequestBackStateEnum.CRC_RequestBack)
|
||||||
{
|
{
|
||||||
sv.RequestBackState = RequestBackStateEnum.CRC_RequestBack;
|
sv.RequestBackState = RequestBackStateEnum.CRC_RequestBack;
|
||||||
|
|
||||||
@@ -465,16 +665,14 @@ namespace IRaCIS.Core.Application.Image.QA
|
|||||||
return ResponseOutput.NotOk(_localizer["QCOperation_CannotRollback"]);
|
return ResponseOutput.NotOk(_localizer["QCOperation_CannotRollback"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
//sv.CheckChallengeState = (int)CheckChanllengeTypeEnum.None;
|
sv.RequestBackState = RequestBackStateEnum.PM_AgressBack;
|
||||||
//sv.CheckState = CheckStateEnum.None;
|
|
||||||
//sv.ChallengeState = (int)ChallengeStateEnum.No;
|
|
||||||
|
|
||||||
sv.AuditState = AuditStateEnum.None;
|
sv.AuditState = AuditStateEnum.None;
|
||||||
sv.SubmitState = SubmitStateEnum.ToSubmit;
|
sv.SubmitState = SubmitStateEnum.ToSubmit;
|
||||||
sv.ReadingStatus = ReadingStatusEnum.ImageNotSubmit;
|
sv.ReadingStatus = ReadingStatusEnum.ImageNotSubmit;
|
||||||
|
|
||||||
//回退后,回退状态恢复
|
//回退后,回退状态恢复
|
||||||
sv.RequestBackState = RequestBackStateEnum.NotRequest;
|
|
||||||
sv.IsCheckBack = true;
|
sv.IsCheckBack = true;
|
||||||
sv.CheckBackTime = DateTime.Now;
|
sv.CheckBackTime = DateTime.Now;
|
||||||
sv.CheckState = CheckStateEnum.None;
|
sv.CheckState = CheckStateEnum.None;
|
||||||
@@ -697,13 +895,6 @@ namespace IRaCIS.Core.Application.Image.QA
|
|||||||
|
|
||||||
study.InstanceCount = study.InstanceCount - 1;
|
study.InstanceCount = study.InstanceCount - 1;
|
||||||
|
|
||||||
////删除到最后一个instance
|
|
||||||
//if (series.InstanceCount == 0)
|
|
||||||
//{
|
|
||||||
// series.IsDeleted = true;
|
|
||||||
//}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (state == 5)
|
else if (state == 5)
|
||||||
@@ -717,7 +908,7 @@ namespace IRaCIS.Core.Application.Image.QA
|
|||||||
var study = (await _dicomStudyRepository.Where(t => t.Id == series.StudyId, true).IgnoreQueryFilters().FirstOrDefaultAsync()).IfNullThrowException();
|
var study = (await _dicomStudyRepository.Where(t => t.Id == series.StudyId, true).IgnoreQueryFilters().FirstOrDefaultAsync()).IfNullThrowException();
|
||||||
|
|
||||||
study.InstanceCount = study.InstanceCount + 1;
|
study.InstanceCount = study.InstanceCount + 1;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -725,7 +916,73 @@ namespace IRaCIS.Core.Application.Image.QA
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 1、设置为不读片,2 设置为读片(取消 先前设置为不读片) 4 设置为删除(数据库记录软删除) 5 恢复为未删除
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="subjectVisitId"></param>
|
||||||
|
/// <param name="noneDicomStudyId"></param>
|
||||||
|
/// <param name="noneDicomStudyFileId"></param>
|
||||||
|
/// <param name="state"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPut]
|
||||||
|
[TrialGlobalLimit("AfterStopCannNotOpt")]
|
||||||
|
public async Task<IResponseOutput> SetNodicomStudyState(Guid subjectVisitId, Guid noneDicomStudyId, Guid? noneDicomStudyFileId, int state)
|
||||||
|
{
|
||||||
|
await VerifyIsCanQCAsync(null, subjectVisitId);
|
||||||
|
|
||||||
|
//设置检查
|
||||||
|
if (noneDicomStudyFileId == null)
|
||||||
|
{
|
||||||
|
|
||||||
|
var noneDicomStudy = (await _noneDicomStudyRepository.Where(t => t.Id == noneDicomStudyId, true).IgnoreQueryFilters().FirstOrDefaultAsync()).IfNullThrowException();
|
||||||
|
|
||||||
|
|
||||||
|
if (state == 1)
|
||||||
|
{
|
||||||
|
noneDicomStudy.IsReading = false;
|
||||||
|
}
|
||||||
|
else if (state == 2)
|
||||||
|
{
|
||||||
|
noneDicomStudy.IsReading = true;
|
||||||
|
}
|
||||||
|
else if (state == 4)
|
||||||
|
{
|
||||||
|
noneDicomStudy.IsDeleted = true;
|
||||||
|
}
|
||||||
|
else if (state == 5)
|
||||||
|
{
|
||||||
|
noneDicomStudy.IsDeleted = false;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//设置检查下面的文件
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var noneDicomStudyFile = (await _noneDicomStudyFileRepository.Where(t => t.Id == noneDicomStudyFileId, true).IgnoreQueryFilters().FirstOrDefaultAsync()).IfNullThrowException();
|
||||||
|
|
||||||
|
|
||||||
|
if (state == 1)
|
||||||
|
{
|
||||||
|
noneDicomStudyFile.IsReading = false;
|
||||||
|
}
|
||||||
|
else if (state == 2)
|
||||||
|
{
|
||||||
|
noneDicomStudyFile.IsReading = true;
|
||||||
|
}
|
||||||
|
else if (state == 4)
|
||||||
|
{
|
||||||
|
noneDicomStudyFile.IsDeleted = true;
|
||||||
|
}
|
||||||
|
else if (state == 5)
|
||||||
|
{
|
||||||
|
noneDicomStudyFile.IsDeleted = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await _noneDicomStudyRepository.SaveChangesAsync();
|
||||||
|
|
||||||
|
return ResponseOutput.Ok();
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///type 1 :study 2: series 3:非dicom QC修改检查部位和 拍片类型
|
///type 1 :study 2: series 3:非dicom QC修改检查部位和 拍片类型
|
||||||
@@ -756,12 +1013,14 @@ namespace IRaCIS.Core.Application.Image.QA
|
|||||||
{
|
{
|
||||||
|
|
||||||
var studyId = updateModalityCommand.Id;
|
var studyId = updateModalityCommand.Id;
|
||||||
var study = (await _dicomStudyRepository.FirstOrDefaultAsync(t => t.Id == studyId)).IfNullThrowException();
|
var study = (await _dicomStudyRepository.FirstOrDefaultAsync(t => t.Id == studyId, true)).IfNullThrowException();
|
||||||
|
|
||||||
|
|
||||||
study.BodyPartForEdit = updateModalityCommand.BodyPart;
|
study.BodyPartForEdit = updateModalityCommand.BodyPart;
|
||||||
|
|
||||||
study.ModalityForEdit = updateModalityCommand.Modality;
|
study.ModalityForEdit = updateModalityCommand.Modality;
|
||||||
|
study.StudyName = updateModalityCommand.StudyName;
|
||||||
|
|
||||||
|
|
||||||
await _dicomSeriesRepository.BatchUpdateNoTrackingAsync(t => t.StudyId == studyId, r => new DicomSeries() { BodyPartForEdit = updateModalityCommand.BodyPart });
|
await _dicomSeriesRepository.BatchUpdateNoTrackingAsync(t => t.StudyId == studyId, r => new DicomSeries() { BodyPartForEdit = updateModalityCommand.BodyPart });
|
||||||
}
|
}
|
||||||
@@ -826,7 +1085,7 @@ namespace IRaCIS.Core.Application.Image.QA
|
|||||||
//---CRC已经提交,不允许删除。
|
//---CRC已经提交,不允许删除。
|
||||||
return ResponseOutput.NotOk(_localizer["QCOperation_CrcNoDelete"]);
|
return ResponseOutput.NotOk(_localizer["QCOperation_CrcNoDelete"]);
|
||||||
}
|
}
|
||||||
var waitDeleteStudyList = await _dicomStudyRepository.Where(x => ids.Contains(x.Id)).ToListAsync();
|
var waitDeleteStudyList = await _dicomStudyRepository.Where(x => ids.Contains(x.Id), false, true).ToListAsync();
|
||||||
|
|
||||||
foreach (var study in waitDeleteStudyList)
|
foreach (var study in waitDeleteStudyList)
|
||||||
{
|
{
|
||||||
@@ -835,33 +1094,22 @@ namespace IRaCIS.Core.Application.Image.QA
|
|||||||
|
|
||||||
await _dicomStudyRepository.DeleteAsync(study);
|
await _dicomStudyRepository.DeleteAsync(study);
|
||||||
|
|
||||||
|
var fisrtPath = await _dicomInstanceRepository.Where(t => t.StudyId == id).Select(t => t.Path).FirstOrDefaultAsync();
|
||||||
|
|
||||||
|
|
||||||
var succeess2 = await _dicomInstanceRepository.BatchDeleteNoTrackingAsync(t => t.StudyId == id);
|
var succeess2 = await _dicomInstanceRepository.BatchDeleteNoTrackingAsync(t => t.StudyId == id);
|
||||||
var success3 = await _dicomSeriesrepository.BatchDeleteNoTrackingAsync(t => t.StudyId == id);
|
var success3 = await _dicomSeriesrepository.BatchDeleteNoTrackingAsync(t => t.StudyId == id);
|
||||||
|
|
||||||
await _scpStudyRepository.BatchUpdateNoTrackingAsync(t => t.Id == id, u => new SCPStudy() { SubjectVisitId = null });
|
await _scpStudyRepository.BatchUpdateNoTrackingAsync(t => t.Id == id, u => new SCPStudy() { SubjectVisitId = null });
|
||||||
|
|
||||||
|
if (fisrtPath.IsNotNullOrEmpty())
|
||||||
|
{
|
||||||
|
var prefix = fisrtPath.Substring(1, fisrtPath.LastIndexOf('/') - 1);
|
||||||
|
|
||||||
|
await _oSSService.DeleteFromPrefix(prefix, false);
|
||||||
|
await _oSSService.DeleteFromPrefix(prefix, true);
|
||||||
|
|
||||||
//var success3 = await _dicomSeriesrepository.DeleteFromQueryAsync(t => t.StudyId == id, true);
|
}
|
||||||
//var success4 = await _repository.BatchDeleteAsync<StudyMonitor>(t => t.StudyId == id);
|
|
||||||
|
|
||||||
//删除 物理文件
|
|
||||||
|
|
||||||
//var instancePathList = await _dicomInstanceRepository.Where(t => t.StudyId == id)
|
|
||||||
// .Select(t => t.Path).ToListAsync();
|
|
||||||
|
|
||||||
//instancePathList.ForEach(path =>
|
|
||||||
//{
|
|
||||||
|
|
||||||
// var physicalPath = FileStoreHelper.GetPhysicalFilePath(_hostEnvironment, path);
|
|
||||||
|
|
||||||
// if (System.IO.File.Exists(physicalPath))
|
|
||||||
// {
|
|
||||||
// File.Delete(physicalPath);
|
|
||||||
// }
|
|
||||||
//});
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -950,7 +1198,7 @@ namespace IRaCIS.Core.Application.Image.QA
|
|||||||
{
|
{
|
||||||
var nextIQCQuality = await this.GetNextIQCQuality(inDto);
|
var nextIQCQuality = await this.GetNextIQCQuality(inDto);
|
||||||
|
|
||||||
if (nextIQCQuality.VisitId != null)
|
if (nextIQCQuality.VisitId != null && nextIQCQuality.IsReceived == false)
|
||||||
{
|
{
|
||||||
var visit = await _subjectVisitRepository.Where(x => x.Id == nextIQCQuality.VisitId).FirstNotNullAsync();
|
var visit = await _subjectVisitRepository.Where(x => x.Id == nextIQCQuality.VisitId).FirstNotNullAsync();
|
||||||
if (!visit.IsTake)
|
if (!visit.IsTake)
|
||||||
@@ -978,6 +1226,22 @@ namespace IRaCIS.Core.Application.Image.QA
|
|||||||
.FirstOrDefaultAsync(t => t.TrialId == inDto.TrialId)
|
.FirstOrDefaultAsync(t => t.TrialId == inDto.TrialId)
|
||||||
.IfNullThrowException();
|
.IfNullThrowException();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var currentActionList = await _subjectVisitRepository.Where(x => x.TrialId == inDto.TrialId && x.CurrentActionUserId == _userInfo.UserRoleId).OrderByDescending(x => x.IsUrgent)
|
||||||
|
.ThenBy(x => x.Subject.Code).ThenBy(x => x.VisitNum).ToListAsync();
|
||||||
|
|
||||||
|
if (currentActionList.Count() > 0)
|
||||||
|
{
|
||||||
|
return new GetNextIQCQualityOutDto()
|
||||||
|
{
|
||||||
|
IsReceived = true,
|
||||||
|
SubjectId = currentActionList[0].SubjectId,
|
||||||
|
VisitId = currentActionList[0].Id,
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
SubjectVisit? subjectVisit = null;
|
SubjectVisit? subjectVisit = null;
|
||||||
List<SubjectVisit>? visitList = null;
|
List<SubjectVisit>? visitList = null;
|
||||||
switch (trialConfig.QCProcessEnum)
|
switch (trialConfig.QCProcessEnum)
|
||||||
@@ -986,7 +1250,9 @@ namespace IRaCIS.Core.Application.Image.QA
|
|||||||
return new GetNextIQCQualityOutDto() { };
|
return new GetNextIQCQualityOutDto() { };
|
||||||
break;
|
break;
|
||||||
case TrialQCProcess.SingleAudit:
|
case TrialQCProcess.SingleAudit:
|
||||||
visitList = await _subjectVisitRepository.Where(x => x.SubmitState == SubmitStateEnum.Submitted
|
visitList = await _subjectVisitRepository
|
||||||
|
.Where(x => !x.SubjectVisitImageBackRecordList.Any(t => t.ImageBackState == ImageBackStateEnum.None))
|
||||||
|
.Where(x => x.SubmitState == SubmitStateEnum.Submitted
|
||||||
&& x.TrialId == inDto.TrialId && x.PreliminaryAuditUserId != _userInfo.UserRoleId && (x.CurrentActionUserId == _userInfo.UserRoleId || (x.AuditState != AuditStateEnum.PrimaryQCPassed && !x.IsTake)))
|
&& x.TrialId == inDto.TrialId && x.PreliminaryAuditUserId != _userInfo.UserRoleId && (x.CurrentActionUserId == _userInfo.UserRoleId || (x.AuditState != AuditStateEnum.PrimaryQCPassed && !x.IsTake)))
|
||||||
.Where(x => x.QCChallengeList.Count() == 0 || x.QCChallengeList.Where(y => !y.IsClosed).OrderByDescending(x => x.CreateTime).FirstOrDefault().CreateUserId != _userInfo.UserRoleId)
|
.Where(x => x.QCChallengeList.Count() == 0 || x.QCChallengeList.Where(y => !y.IsClosed).OrderByDescending(x => x.CreateTime).FirstOrDefault().CreateUserId != _userInfo.UserRoleId)
|
||||||
.Include(x => x.Subject).ToListAsync();
|
.Include(x => x.Subject).ToListAsync();
|
||||||
@@ -1020,7 +1286,9 @@ namespace IRaCIS.Core.Application.Image.QA
|
|||||||
break;
|
break;
|
||||||
case TrialQCProcess.DoubleAudit:
|
case TrialQCProcess.DoubleAudit:
|
||||||
|
|
||||||
visitList = await _subjectVisitRepository.Where(x => x.SubmitState == SubmitStateEnum.Submitted && x.TrialId == inDto.TrialId &&
|
visitList = await _subjectVisitRepository
|
||||||
|
.Where(x => !x.SubjectVisitImageBackRecordList.Any(t => t.ImageBackState == ImageBackStateEnum.None))
|
||||||
|
.Where(x => x.SubmitState == SubmitStateEnum.Submitted && x.TrialId == inDto.TrialId &&
|
||||||
((x.CurrentActionUserId == _userInfo.UserRoleId) || (!x.IsTake && x.AuditState != AuditStateEnum.QCPassed && (x.PreliminaryAuditUserId != _userInfo.UserRoleId)))
|
((x.CurrentActionUserId == _userInfo.UserRoleId) || (!x.IsTake && x.AuditState != AuditStateEnum.QCPassed && (x.PreliminaryAuditUserId != _userInfo.UserRoleId)))
|
||||||
)
|
)
|
||||||
.Where(x => x.QCChallengeList.Count() == 0 || x.QCChallengeList.Where(y => !y.IsClosed).OrderByDescending(x => x.CreateTime).FirstOrDefault().CreateUserId != _userInfo.UserRoleId)
|
.Where(x => x.QCChallengeList.Count() == 0 || x.QCChallengeList.Where(y => !y.IsClosed).OrderByDescending(x => x.CreateTime).FirstOrDefault().CreateUserId != _userInfo.UserRoleId)
|
||||||
@@ -1094,6 +1362,11 @@ namespace IRaCIS.Core.Application.Image.QA
|
|||||||
return ResponseOutput.NotOk(_localizer["QCOperation_QCConfigFirst"], ApiResponseCodeEnum.NeedTips);
|
return ResponseOutput.NotOk(_localizer["QCOperation_QCConfigFirst"], ApiResponseCodeEnum.NeedTips);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_subjectVisitImageBackRecordReposiotry.Any(t => t.SubjectVisitId == subjectVisitId && t.ImageBackState == ImageBackStateEnum.None))
|
||||||
|
{
|
||||||
|
//已申请的影像回退,不能领取
|
||||||
|
throw new BusinessValidationFailedException(_localizer["QCOperation_HaveApplyedImageBackCanNotObtain"]);
|
||||||
|
}
|
||||||
|
|
||||||
//if (await _subjectVisitRepository.AnyAsync(t => t.IsTake &&
|
//if (await _subjectVisitRepository.AnyAsync(t => t.IsTake &&
|
||||||
// t.SubjectId != dbSubjectVisit.SubjectId &&
|
// t.SubjectId != dbSubjectVisit.SubjectId &&
|
||||||
@@ -1611,8 +1884,11 @@ namespace IRaCIS.Core.Application.Image.QA
|
|||||||
|
|
||||||
|
|
||||||
//删除 软删除的物理文件
|
//删除 软删除的物理文件
|
||||||
var instancePathList = await _dicomInstanceRepository.Where(t => t.DicomSerie.IsDeleted && t.SubjectVisitId == subjectVisitId)
|
var instancePathList = await _dicomInstanceRepository.Where(t => (t.DicomSerie.IsDeleted || t.IsDeleted) && t.SubjectVisitId == subjectVisitId, false, true)
|
||||||
.Select(t => t.Path).ToListAsync();
|
.Select(t => t.Path).ToListAsync();
|
||||||
|
var noneDicomFileList = await _noneDicomStudyFileRepository.Where(t => (t.NoneDicomStudy.IsDeleted || t.IsDeleted) && t.NoneDicomStudy.SubjectVisitId == subjectVisitId, false, true)
|
||||||
|
.Select(t => t.Path).ToListAsync();
|
||||||
|
|
||||||
|
|
||||||
//维护统一状态
|
//维护统一状态
|
||||||
dbSubjectVisit.ReadingStatus = ReadingStatusEnum.ConsistencyCheck;
|
dbSubjectVisit.ReadingStatus = ReadingStatusEnum.ConsistencyCheck;
|
||||||
@@ -1650,17 +1926,16 @@ namespace IRaCIS.Core.Application.Image.QA
|
|||||||
dbSubjectVisit.ReadingStatus = trialConfig.IsImageConsistencyVerification ? ReadingStatusEnum.ConsistencyCheck : ReadingStatusEnum.TaskAllocate;
|
dbSubjectVisit.ReadingStatus = trialConfig.IsImageConsistencyVerification ? ReadingStatusEnum.ConsistencyCheck : ReadingStatusEnum.TaskAllocate;
|
||||||
|
|
||||||
//删除影像
|
//删除影像
|
||||||
instancePathList.ForEach(path =>
|
await _dicomStudyRepository.BatchDeleteNoTrackingAsync(t => t.IsDeleted && t.SubjectVisitId == subjectVisitId);
|
||||||
{
|
await _dicomInstanceRepository.BatchDeleteNoTrackingAsync(t => (t.DicomSerie.IsDeleted || t.IsDeleted) && t.SubjectVisitId == subjectVisitId);
|
||||||
|
await _dicomSeriesRepository.BatchDeleteNoTrackingAsync(t => t.IsDeleted && t.SubjectVisitId == subjectVisitId);
|
||||||
|
|
||||||
var physicalPath = FileStoreHelper.GetPhysicalFilePath(_hostEnvironment, path);
|
await _noneDicomStudyFileRepository.BatchDeleteNoTrackingAsync(t => (t.NoneDicomStudy.IsDeleted || t.IsDeleted) && t.NoneDicomStudy.SubjectVisitId == subjectVisitId);
|
||||||
|
await _noneDicomStudyRepository.BatchDeleteNoTrackingAsync(t => t.IsDeleted && t.SubjectVisitId == subjectVisitId);
|
||||||
|
await _oSSService.DeleteObjects(instancePathList.Select(t => t.TrimStart('/')).ToList());
|
||||||
|
await _oSSService.DeleteObjects(noneDicomFileList.Select(t => t.TrimStart('/')).ToList());
|
||||||
|
|
||||||
if (System.IO.File.Exists(physicalPath))
|
|
||||||
{
|
|
||||||
File.Delete(physicalPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1714,18 +1989,14 @@ namespace IRaCIS.Core.Application.Image.QA
|
|||||||
dbSubjectVisit.ReadingStatus = trialConfig.IsImageConsistencyVerification ? ReadingStatusEnum.ConsistencyCheck : ReadingStatusEnum.TaskAllocate;
|
dbSubjectVisit.ReadingStatus = trialConfig.IsImageConsistencyVerification ? ReadingStatusEnum.ConsistencyCheck : ReadingStatusEnum.TaskAllocate;
|
||||||
|
|
||||||
//删除影像
|
//删除影像
|
||||||
instancePathList.ForEach(path =>
|
await _dicomStudyRepository.BatchDeleteNoTrackingAsync(t => t.IsDeleted && t.SubjectVisitId == subjectVisitId);
|
||||||
{
|
await _dicomInstanceRepository.BatchDeleteNoTrackingAsync(t => (t.DicomSerie.IsDeleted || t.IsDeleted) && t.SubjectVisitId == subjectVisitId);
|
||||||
|
await _dicomSeriesRepository.BatchDeleteNoTrackingAsync(t => t.IsDeleted && t.SubjectVisitId == subjectVisitId);
|
||||||
var physicalPath = FileStoreHelper.GetPhysicalFilePath(_hostEnvironment, path);
|
|
||||||
|
|
||||||
if (System.IO.File.Exists(physicalPath))
|
|
||||||
{
|
|
||||||
File.Delete(physicalPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
|
await _noneDicomStudyFileRepository.BatchDeleteNoTrackingAsync(t => (t.NoneDicomStudy.IsDeleted || t.IsDeleted) && t.NoneDicomStudy.SubjectVisitId == subjectVisitId);
|
||||||
|
await _noneDicomStudyRepository.BatchDeleteNoTrackingAsync(t => t.IsDeleted && t.SubjectVisitId == subjectVisitId);
|
||||||
|
await _oSSService.DeleteObjects(instancePathList.Select(t => t.TrimStart('/')).ToList());
|
||||||
|
await _oSSService.DeleteObjects(noneDicomFileList.Select(t => t.TrimStart('/')).ToList());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -2067,6 +2338,19 @@ namespace IRaCIS.Core.Application.Image.QA
|
|||||||
{
|
{
|
||||||
var qcChallenge = (await _qcChallengeRepository.FirstOrDefaultAsync(t => t.Id == qcChallengeId)).IfNullThrowException();
|
var qcChallenge = (await _qcChallengeRepository.FirstOrDefaultAsync(t => t.Id == qcChallengeId)).IfNullThrowException();
|
||||||
|
|
||||||
|
var sv = (await _subjectVisitRepository.FirstOrDefaultAsync(t => t.Id == qcChallenge.SubjectVisitId)).IfNullThrowException();
|
||||||
|
|
||||||
|
if (await _subjectVisitRepository.Where(t => t.Id == sv.Id).AnyAsync(t => t.SubjectVisitImageBackRecordList.Any(t => t.ImageBackState == ImageBackStateEnum.None)))
|
||||||
|
{
|
||||||
|
// 该访视已在其他途径申请影像回退中,不允许申请
|
||||||
|
throw new BusinessValidationFailedException(_localizer["QCOperation_SomeOneHaveApplyedImageBack"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sv.RequestBackState == RequestBackStateEnum.CRC_RequestBack)
|
||||||
|
{
|
||||||
|
// 该访视已在其他途径申请影像回退中,不允许申请
|
||||||
|
throw new BusinessValidationFailedException(_localizer["QCOperation_SomeOneHaveApplyedImageBack"]);
|
||||||
|
}
|
||||||
|
|
||||||
if (qcChallenge.ReuploadEnum != QCChanllengeReuploadEnum.None && qcChallenge.ReuploadEnum != QCChanllengeReuploadEnum.CRCReuploaded)
|
if (qcChallenge.ReuploadEnum != QCChanllengeReuploadEnum.None && qcChallenge.ReuploadEnum != QCChanllengeReuploadEnum.CRCReuploaded)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ using IRaCIS.Core.Application.Contracts.DTO;
|
|||||||
using IRaCIS.Core.Application.MassTransit.Command;
|
using IRaCIS.Core.Application.MassTransit.Command;
|
||||||
using IRaCIS.Core.Application.ViewModel;
|
using IRaCIS.Core.Application.ViewModel;
|
||||||
using IRaCIS.Core.Domain.Share;
|
using IRaCIS.Core.Domain.Share;
|
||||||
|
using NPOI.SS.Formula.Functions;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
namespace IRaCIS.Core.Application.Service
|
namespace IRaCIS.Core.Application.Service
|
||||||
@@ -401,6 +402,10 @@ namespace IRaCIS.Core.Application.Service
|
|||||||
|
|
||||||
bool isFilterZip = false;
|
bool isFilterZip = false;
|
||||||
|
|
||||||
|
bool isIgnoreDelete = false;
|
||||||
|
|
||||||
|
bool isReading = false;
|
||||||
|
|
||||||
|
|
||||||
string token = string.Empty;
|
string token = string.Empty;
|
||||||
//一致性核查
|
//一致性核查
|
||||||
@@ -523,6 +528,7 @@ namespace IRaCIS.Core.Application.Service
|
|||||||
|| t.ReadingClinicalDataList.Any(x => x.ClinicalDataTrialSet.UploadRole == Domain.Share.UploadRole.CRC && x.ReadingClinicalDataPDFList.Count > 0)
|
|| t.ReadingClinicalDataList.Any(x => x.ClinicalDataTrialSet.UploadRole == Domain.Share.UploadRole.CRC && x.ReadingClinicalDataPDFList.Count > 0)
|
||||||
|| t.PreviousSurgeryList.Any()))
|
|| t.PreviousSurgeryList.Any()))
|
||||||
.ForMember(d => d.DicomStudyCount, u => u.MapFrom(t => t.StudyList.Count()))
|
.ForMember(d => d.DicomStudyCount, u => u.MapFrom(t => t.StudyList.Count()))
|
||||||
|
.ForMember(d => d.IsImageBackApplying, u => u.MapFrom(t => t.SubjectVisitImageBackRecordList.Any(c => c.ImageBackState == ImageBackStateEnum.None)))
|
||||||
.ForMember(d => d.NoneDicomStudyCount, u => u.MapFrom(t => t.NoneDicomStudyList.Count(t => t.NoneDicomFileList.Any())));
|
.ForMember(d => d.NoneDicomStudyCount, u => u.MapFrom(t => t.NoneDicomStudyList.Count(t => t.NoneDicomFileList.Any())));
|
||||||
|
|
||||||
//CRC 上传列表
|
//CRC 上传列表
|
||||||
@@ -537,10 +543,12 @@ namespace IRaCIS.Core.Application.Service
|
|||||||
.ForMember(d => d.MedicalNo, u => u.MapFrom(s => s.Subject.MedicalNo))
|
.ForMember(d => d.MedicalNo, u => u.MapFrom(s => s.Subject.MedicalNo))
|
||||||
.ForMember(d => d.Sex, u => u.MapFrom(s => s.Subject.Sex))
|
.ForMember(d => d.Sex, u => u.MapFrom(s => s.Subject.Sex))
|
||||||
.ForMember(d => d.Age, u => u.MapFrom(t => t.Subject.Age))
|
.ForMember(d => d.Age, u => u.MapFrom(t => t.Subject.Age))
|
||||||
.ForMember(d => d.IsHaveClinicalData, u => u.MapFrom(t => t.PreviousHistoryList.Any() || t.PreviousOtherList.Any()
|
.ForMember(d => d.IsHaveClinicalData,
|
||||||
|| t.Subject.ClinicalFormList.Any(x => x.ClinicalDataTrialSet.UploadRole == UploadRole.CRC && x.ReadingId == t.Id)
|
u => u.MapFrom(t => t.PreviousHistoryList.Any() ||
|
||||||
|| t.ReadingClinicalDataList.Any(x => x.ClinicalDataTrialSet.UploadRole == Domain.Share.UploadRole.CRC && x.ReadingClinicalDataPDFList.Count > 0)
|
t.PreviousOtherList.Any() ||
|
||||||
|| t.PreviousSurgeryList.Any()))
|
t.Subject.ClinicalFormList.Any(x => x.ClinicalDataTrialSet.UploadRole == UploadRole.CRC && x.ReadingId == t.Id) ||
|
||||||
|
t.ReadingClinicalDataList.Any(x => x.ClinicalDataTrialSet.UploadRole == Domain.Share.UploadRole.CRC && x.ReadingClinicalDataPDFList.Count > 0) ||
|
||||||
|
t.PreviousSurgeryList.Any()))
|
||||||
|
|
||||||
.ForMember(d => d.IsHaveUploadFailed, u => u.MapFrom(t => t.StudyList.SelectMany(c => c.DicomStudyMonitorList).Any(h => h.FailedFileCount > 0)))
|
.ForMember(d => d.IsHaveUploadFailed, u => u.MapFrom(t => t.StudyList.SelectMany(c => c.DicomStudyMonitorList).Any(h => h.FailedFileCount > 0)))
|
||||||
|
|
||||||
@@ -548,6 +556,7 @@ namespace IRaCIS.Core.Application.Service
|
|||||||
//.ForMember(d => d.VisitNum, u => u.MapFrom(t => t.InPlan ? t.VisitStage.VisitNum : t.VisitNum))
|
//.ForMember(d => d.VisitNum, u => u.MapFrom(t => t.InPlan ? t.VisitStage.VisitNum : t.VisitNum))
|
||||||
//.ForMember(d => d.VisitDay, u => u.MapFrom(t => t.InPlan ? t.VisitStage.VisitDay : t.VisitDay))
|
//.ForMember(d => d.VisitDay, u => u.MapFrom(t => t.InPlan ? t.VisitStage.VisitDay : t.VisitDay))
|
||||||
.ForMember(d => d.DicomStudyCount, u => u.MapFrom(t => t.StudyList.Count()))
|
.ForMember(d => d.DicomStudyCount, u => u.MapFrom(t => t.StudyList.Count()))
|
||||||
|
.ForMember(d => d.IsImageBackApplying, u => u.MapFrom(t => t.SubjectVisitImageBackRecordList.Any(c => c.ImageBackState == ImageBackStateEnum.None)))
|
||||||
.ForMember(d => d.NoneDicomStudyCount, u => u.MapFrom(t => t.NoneDicomStudyList.Count(t => t.NoneDicomFileList.Any())));
|
.ForMember(d => d.NoneDicomStudyCount, u => u.MapFrom(t => t.NoneDicomStudyList.Count(t => t.NoneDicomFileList.Any())));
|
||||||
//.ForMember(d => d.StudyCount, u => u.MapFrom(s => s.StudyList.Count()));
|
//.ForMember(d => d.StudyCount, u => u.MapFrom(s => s.StudyList.Count()));
|
||||||
CreateMap<Subject, QCCRCVisitViewModel>();
|
CreateMap<Subject, QCCRCVisitViewModel>();
|
||||||
@@ -588,7 +597,10 @@ namespace IRaCIS.Core.Application.Service
|
|||||||
.ForMember(d => d.SubjectFirstGiveMedicineTime, u => u.MapFrom(s => s.Subject.FirstGiveMedicineTime))
|
.ForMember(d => d.SubjectFirstGiveMedicineTime, u => u.MapFrom(s => s.Subject.FirstGiveMedicineTime))
|
||||||
.ForMember(d => d.SiteName, u => u.MapFrom(s => s.TrialSite.TrialSiteName))
|
.ForMember(d => d.SiteName, u => u.MapFrom(s => s.TrialSite.TrialSiteName))
|
||||||
.ForMember(d => d.TotalChallengeCount, u => u.MapFrom(s => s.QCChallengeList.Count()))
|
.ForMember(d => d.TotalChallengeCount, u => u.MapFrom(s => s.QCChallengeList.Count()))
|
||||||
.ForMember(d => d.NotClosedChallengeCount, u => u.MapFrom(s => s.QCChallengeList.Count(c => c.IsClosed == false)));
|
.ForMember(d => d.NotClosedChallengeCount, u => u.MapFrom(s => s.QCChallengeList.Count(c => c.IsClosed == false)))
|
||||||
|
.ForMember(d => d.IsShowStudyName, u => u.MapFrom(s => s.Trial.IsShowStudyName))
|
||||||
|
.ForMember(d => d.StudyNameList, u => u.MapFrom(s => s.Trial.StudyNameList))
|
||||||
|
.ForMember(d => d.ImageFormatList, u => u.MapFrom(s => s.Trial.ImageFormatList));
|
||||||
|
|
||||||
|
|
||||||
CreateMap<Subject, QARelationInfo>(MemberList.None);
|
CreateMap<Subject, QARelationInfo>(MemberList.None);
|
||||||
@@ -715,16 +727,28 @@ namespace IRaCIS.Core.Application.Service
|
|||||||
.ForMember(d => d.FullFilePath, u => u.MapFrom(s => s.Path));
|
.ForMember(d => d.FullFilePath, u => u.MapFrom(s => s.Path));
|
||||||
|
|
||||||
CreateMap<NoneDicomStudy, NoneDicomStudyView>()
|
CreateMap<NoneDicomStudy, NoneDicomStudyView>()
|
||||||
.ForMember(d => d.NoneDicomStudyFileList, u => u.MapFrom(s => isFilterZip ? s.NoneDicomFileList.Where(t => !t.FileType.Contains(StaticData.FileType.Zip)).OrderBy(t => t.CreateTime).ThenBy(t => t.FileName) : s.NoneDicomFileList.OrderBy(t => t.CreateTime).ThenBy(t => t.FileName)))
|
.ForMember(d => d.NoneDicomStudyFileList, u => u.MapFrom(s =>
|
||||||
|
s.NoneDicomFileList.Where(t => isFilterZip ? !t.FileType.Contains(StaticData.FileType.Zip) : true).Where(t => isReading ? t.IsReading && t.IsDeleted == false : true).OrderBy(t => t.CreateTime).ThenBy(t => t.FileName)))
|
||||||
.ForMember(d => d.CodeView, u => u.MapFrom(s => s.StudyCode));
|
.ForMember(d => d.CodeView, u => u.MapFrom(s => s.StudyCode));
|
||||||
|
|
||||||
Guid? visiTaskId = null;
|
Guid? visiTaskId = null;
|
||||||
CreateMap<NoneDicomStudy, TaskDicomStudyView>()
|
CreateMap<NoneDicomStudy, TaskDicomStudyView>()
|
||||||
.ForMember(d => d.NoneDicomStudyFileList, u => u.MapFrom(s => isFilterZip ?
|
.ForMember(d => d.NoneDicomStudyFileList, u => u.MapFrom(s =>
|
||||||
s.TaskNoneDicomFileList.Where(t => visiTaskId != null ? t.VisitTaskId == visiTaskId : true).Where(t => !t.FileType.Contains(StaticData.FileType.Zip)).OrderBy(t => t.CreateTime).ThenBy(t => t.FileName)
|
s.TaskNoneDicomFileList.Where(t => visiTaskId != null ? t.VisitTaskId == visiTaskId : true).Where(t => isFilterZip ? !t.FileType.Contains(StaticData.FileType.Zip) : true)
|
||||||
: s.TaskNoneDicomFileList.Where(t => visiTaskId != null ? t.VisitTaskId == visiTaskId : true).OrderBy(t => t.CreateTime).ThenBy(t => t.FileName)))
|
.Where(t => isReading ? t.IsReading && t.IsDeleted == false : true)
|
||||||
|
.OrderBy(t => t.CreateTime).ThenBy(t => t.FileName)))
|
||||||
.ForMember(d => d.CodeView, u => u.MapFrom(s => s.StudyCode));
|
.ForMember(d => d.CodeView, u => u.MapFrom(s => s.StudyCode));
|
||||||
|
|
||||||
|
|
||||||
|
CreateMap<SubjectVisitImageBackRecord, ImageBackViewModel>()
|
||||||
|
.ForMember(d => d.SubjectCode, u => u.MapFrom(s => s.SubjectVisit.Subject.Code))
|
||||||
|
.ForMember(d => d.VisitNum, u => u.MapFrom(t => t.SubjectVisit.VisitNum))
|
||||||
|
.ForMember(d => d.TrialSiteCode, u => u.MapFrom(s => s.SubjectVisit.TrialSite.TrialSiteCode))
|
||||||
|
.ForMember(d => d.VisitName, u => u.MapFrom(s => s.SubjectVisit.VisitName))
|
||||||
|
.ForMember(d => d.IsUrgent, u => u.MapFrom(s => s.SubjectVisit.IsUrgent))
|
||||||
|
.ForMember(d => d.CreateUserName, u => u.MapFrom(s => s.CreateUserRole.UserName))
|
||||||
|
.ForMember(d => d.CreateUserFullName, u => u.MapFrom(s => s.CreateUserRole.FullName));
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -407,6 +407,7 @@ namespace IRaCIS.Core.Application.Service
|
|||||||
{
|
{
|
||||||
if (await _readModuleRepository.AnyAsync(x => x.SubjectId == inDto.SubjectId && x.SubjectVisit.LatestScanDate <= clinicalForm.CheckDate && x.IsCRCConfirm))
|
if (await _readModuleRepository.AnyAsync(x => x.SubjectId == inDto.SubjectId && x.SubjectVisit.LatestScanDate <= clinicalForm.CheckDate && x.IsCRCConfirm))
|
||||||
{
|
{
|
||||||
|
|
||||||
throw new BusinessValidationFailedException(_localizer["ClinicalAnswer_unableToAddOrUpdate", clinicalForm.CheckDate.Value.ToString("yyyy-MM-dd")]);
|
throw new BusinessValidationFailedException(_localizer["ClinicalAnswer_unableToAddOrUpdate", clinicalForm.CheckDate.Value.ToString("yyyy-MM-dd")]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -372,6 +372,8 @@ namespace IRaCIS.Core.Application.Service
|
|||||||
ClinicalDataSetEnName = x.ClinicalDataSetEnName,
|
ClinicalDataSetEnName = x.ClinicalDataSetEnName,
|
||||||
UploadRole = x.UploadRole,
|
UploadRole = x.UploadRole,
|
||||||
FileName = x.FileName,
|
FileName = x.FileName,
|
||||||
|
EnFileName = x.EnFileName,
|
||||||
|
EnPath = x.EnPath,
|
||||||
Path = x.Path,
|
Path = x.Path,
|
||||||
TrialId = trialId,
|
TrialId = trialId,
|
||||||
IsApply = x.IsApply,
|
IsApply = x.IsApply,
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user