Compare commits
416 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 431d2e7a97 | |||
| 7caac94d97 | |||
| ceedafb6b9 | |||
| 04e7cd5463 | |||
| ba37700812 | |||
| cdadad9ec5 | |||
| 795e128ef9 | |||
| 658f9c7c40 | |||
| 5bce1cafa3 | |||
| f539496f9f | |||
| fac077d2b7 | |||
| 874c8718b1 | |||
| fea009bf0c | |||
| 5ae837ac19 | |||
| eb55fafbc3 | |||
| 88893c9825 | |||
| c6a18aa18a | |||
| 8829723c19 | |||
| 8768fe0437 | |||
| cb7098830c | |||
| c69c139e00 | |||
| acb7e798e0 | |||
| 63d7bd5607 | |||
| 99e3610be6 | |||
| 50712aefc6 | |||
| d5d728fea6 | |||
| 9e71732061 | |||
| c24adcd09c | |||
| 0da842871c | |||
| 03702477d6 | |||
| e4a36f4689 | |||
| cb6271daef | |||
| 11fa028cd4 | |||
| 5a1a710d5a | |||
| e9e4b45823 | |||
| 7693c72802 | |||
| 1bacc222be | |||
| c5355e976f | |||
| 95a84bb330 | |||
| 6a60e4696b | |||
| 7ff77554ff | |||
| ba23950cd5 | |||
| 8ec2c676f1 | |||
| b183622e13 | |||
| cd9f7f8812 | |||
| 513d773be3 | |||
| cf24583974 | |||
| f5fbf96772 | |||
| 8dc2301184 | |||
| 7e135367b2 | |||
| 8626a6b453 | |||
| 870dda49dd | |||
| 171b8bac34 | |||
| 7c19ecc3f4 | |||
| 3e375ea6d1 | |||
| 416a94e302 | |||
| 7760b0736e | |||
| aba7dfdec9 | |||
| 1dabadfba4 | |||
| b8f5f32596 | |||
| b6459d2f9f | |||
| dded4f2d7c | |||
| fadb7a9d0e | |||
| 55f261b080 | |||
| ccf154e5e5 | |||
| 069ee25d18 | |||
| 64fd39ceb4 | |||
| 19cf8c7559 | |||
| 3c0199cebd | |||
| 62965e5aa5 | |||
| 654fb7116b | |||
| da6746beea | |||
| 2461646d5f | |||
| 02db483119 | |||
| b5e756ffa3 | |||
| f3c29d3530 | |||
| f2d9c6fe38 | |||
| 0d4d984135 | |||
| f9c155a378 | |||
| a9a67c1db2 | |||
| 3d6d64175b | |||
| 45c74694f2 | |||
| 033c47435f | |||
| ea48967492 | |||
| 8ec35d90fb | |||
| 53f3bb5d6d | |||
| e6628e952f | |||
| 1b26ed1b65 | |||
| d0018a3ec3 | |||
| a423c7c73a | |||
| 8eacc969ed | |||
| 33b02be6ed | |||
| 9834335767 | |||
| d4d5ed0d9a | |||
| 3fc7b72a45 | |||
| e525965d89 | |||
| af988e7276 | |||
| 627f3bf4a9 | |||
| aca261ace2 | |||
| 328a8549c6 | |||
| ff71e925ca | |||
| f46bbea98e | |||
| 1d5c274e38 | |||
| e32195c322 | |||
| 935b498ab5 | |||
| 21925f6d88 | |||
| 54b75dd3d5 | |||
| 7ed54e3be3 | |||
| 3a3184a5ac | |||
| 41153e42d6 | |||
| 3ca9be0a29 | |||
| 6c5f669ab6 | |||
| 282ba96c61 | |||
| fe80604331 | |||
| 19fdd02429 | |||
| c2f72d677f | |||
| 6713fff0e7 | |||
| ff8fa94341 | |||
| 82f2185825 | |||
| 5fdf9e0606 | |||
| cf9823c682 | |||
| 73e7ed11b1 | |||
| 9adab8cef1 | |||
| 3d382635cc | |||
| e389c1e581 | |||
| 1a3ebe1fc4 | |||
| fb6f12903e | |||
| 1da4fbe23b | |||
| 4d206ebf9d | |||
| 9c4ada3e66 | |||
| 0bc0421ee3 | |||
| a79aebe772 | |||
| d3ff114b6d | |||
| 50a45e2260 | |||
| 8090668650 | |||
| d27b4af793 | |||
| b097ca1db3 | |||
| 609742c914 | |||
| 79d76dcbaf | |||
| 721ab8dfd3 | |||
| b2d90005f8 | |||
| c58d880e28 | |||
| 183fc6143f | |||
| 9a71e1fa0f | |||
| 5977ab34e9 | |||
| c71b58e0e9 | |||
| 1fcb871de2 | |||
| d7a76bc110 | |||
| 78b76da7ed | |||
| a6c04d8fbb | |||
| 303cb54e7a | |||
| 92e1a3f90b | |||
| 8c51ae350c | |||
| 91fa8e75e1 | |||
| 893bdaf0f2 | |||
| 7051e68c09 | |||
| e9bb71f5c9 | |||
| 3ee0c2ccc7 | |||
| 40c8a51a31 | |||
| d3e3ed79ba | |||
| 83d3a547d1 | |||
| 3d428af85b | |||
| c5b8743064 | |||
| 69d390da81 | |||
| ae0f601727 | |||
| d509bc1649 | |||
| 23ffe2b143 | |||
| 718ddefe97 | |||
| 7524d39213 | |||
| 7e705ccf37 | |||
| 7fc2de5eb3 | |||
| b90f5f2d85 | |||
| 97b28fd920 | |||
| 3bdd5af113 | |||
| 6dcfbb8717 | |||
| 103d4b42a3 | |||
| fc30cb39ee | |||
| 115017197b | |||
| 32931e155c | |||
| 0a1ce59670 | |||
| 42e4fe59ec | |||
| 19f4385055 | |||
| d789c48004 | |||
| 32427f0f0c | |||
| 01ade2d62f | |||
| cec038fb92 | |||
| b5d117f6fa | |||
| b98df9dae8 | |||
| 4e7ce826c8 | |||
| 7df247d5e7 | |||
| fb067534e7 | |||
| de274e00d6 | |||
| 3501f2acdf | |||
| 2dd86652f3 | |||
| bf39613789 | |||
| a64cec987d | |||
| 5b2b5fead9 | |||
| 0216665d5b | |||
| f1fadebfba | |||
| 19b647fb4a | |||
| 65e47d9918 | |||
| ab68a63bdd | |||
| 5990477fdc | |||
| 961ca49f76 | |||
| 581e412106 | |||
| 3813158b00 | |||
| 010fdf6e2c | |||
| f7c669a7d7 | |||
| 68dc09d969 | |||
| a6a6765d9b | |||
| 5931a67825 | |||
| f26441719f | |||
| 67a930a208 | |||
| f189f9f361 | |||
| b6d0791f18 | |||
| 7285a9d672 | |||
| c3daa75e0e | |||
| 564ac4d931 | |||
| e065e44ab0 | |||
| bbc737811a | |||
| d507e625c6 | |||
| e997cb2a8f | |||
| bfa2d8afce | |||
| 3840627ce7 | |||
| 8fed969bec | |||
| d50091ed6b | |||
| 86864ae575 | |||
| 0fdcc7c56e | |||
| 849f48db25 | |||
| b31821848d | |||
| e5be375308 | |||
| 095db5786b | |||
| dcfe28d950 | |||
| f9f3a1422f | |||
| 8dcd1f2f56 | |||
| 7d39bf43fe | |||
| 8b8b52e0cc | |||
| 0cdc489278 | |||
| d4cef1148b | |||
| 40d4806f22 | |||
| 48427f2740 | |||
| a3296a1ab9 | |||
| 7404fabcda | |||
| 29842f484b | |||
| daac69c0d1 | |||
| 603f6e095c | |||
| c9b1e5f92a | |||
| 6fd9bd94df | |||
| fd6673c339 | |||
| 6fe4aa60d4 | |||
| df1665307a | |||
| 1ccb31fcf2 | |||
| 55f98d735e | |||
| 4642e4e00e | |||
| c6d74309f4 | |||
| 2abada285b | |||
| d600862fb0 | |||
| 4048be622f | |||
| eec0156fe7 | |||
| 85d1930730 | |||
| 7420fdeda5 | |||
| 4e2eb7b0a0 | |||
| 68e87a6c0e | |||
| 19f9af8af8 | |||
| 34faaaf231 | |||
| 136a9e54ca | |||
| 5b63e58c1d | |||
| 70c381831d | |||
| 2bf562d027 | |||
| c7e3403cae | |||
| 2f41c21f75 | |||
| 1688392216 | |||
| 6a1a56f0bc | |||
| 0f495a4568 | |||
| 81abcf39fc | |||
| 247b11cec4 | |||
| 21ded0d466 | |||
| 36c354c8f0 | |||
| cb6f93ec0a | |||
| da8812868c | |||
| 14ec78a2fd | |||
| eccb5dc562 | |||
| c11ff02a82 | |||
| b9b095a19c | |||
| 8678c3602f | |||
| 510a35e2b4 | |||
| 5e1ec1ffb2 | |||
| 3f38cf25c5 | |||
| b32225b8bb | |||
| ecbc27fbb8 | |||
| d3f13e844d | |||
| 405454f71f | |||
| f7dd5117a0 | |||
| 60330fbd93 | |||
| 6b7542b11f | |||
| e012384dfa | |||
| 2aa63a6132 | |||
| e12935d9aa | |||
| 21cb074469 | |||
| 204cb19d96 | |||
| 238fde7d01 | |||
| b59b46f938 | |||
| 0fbfe6c0e1 | |||
| 31e2aa24b8 | |||
| 5b52a3e67f | |||
| bb5844a8e8 | |||
| bc5956ed66 | |||
| 624d89563c | |||
| f6bcff7e13 | |||
| 36acbc1df8 | |||
| ca9ce6e4c5 | |||
| 08edc735e9 | |||
| 5b420a453b | |||
| 6a6411dfb8 | |||
| 360bcd6bfe | |||
| 16107dc8a9 | |||
| 578281b707 | |||
| 3730d955dd | |||
| 3dbf329a31 | |||
| afa2b50951 | |||
| b219e4a055 | |||
| 6e38f3f3df | |||
| 34370a36af | |||
| 1dfb27f08e | |||
| 3bf616667e | |||
| 15a3fd17df | |||
| 092a9c2dc6 | |||
| 6e1bf8265f | |||
| d4389e5c35 | |||
| d30b1853de | |||
| 532d7d155b | |||
| 9cff6b9c87 | |||
| e5f8b3dc71 | |||
| 8ac2de3434 | |||
| 74501c3584 | |||
| 757ccc3eb6 | |||
| 36fb3f2d53 | |||
| 8092b0680b | |||
| 42de7737cb | |||
| 273d2a4b88 | |||
| fe4b48f4bc | |||
| 444d3c3a59 | |||
| c8596c6815 | |||
| e2dd4b2466 | |||
| 429ca4dd6d | |||
| 55e0624dc6 | |||
| fff6ef5fe2 | |||
| 2127c47d00 | |||
| 564477b728 | |||
| c7e80401e1 | |||
| 7fee1abdb5 | |||
| 243fae4b19 | |||
| 6e2a58c3d7 | |||
| 2d864de128 | |||
| bee09217a2 | |||
| bd0e039e7a | |||
| f1423fba4f | |||
| c439e1bb42 | |||
| 6a17c2a9a8 | |||
| 0b987f937d | |||
| cd62a8741a | |||
| 67a8f10b03 | |||
| 27749ec3cd | |||
| 19220a1cbd | |||
| f4df76cccd | |||
| 6c443ca089 | |||
| 68be1d8583 | |||
| a965cf429f | |||
| c1c5add001 | |||
| a8049f2a60 | |||
| 9d01b557ce | |||
| 89b3bc94a2 | |||
| 7a7fde5fc0 | |||
| 632712cfee | |||
| 98be30449f | |||
| a7db67adb6 | |||
| c6fdae8879 | |||
| f925f8969a | |||
| f1601e7017 | |||
| caf5946b9e | |||
| 7dce99e045 | |||
| 0e59617691 | |||
| f0f688a1a3 | |||
| 753941204f | |||
| 6fd239cf70 | |||
| a8f6594142 | |||
| 0d5d5105ce | |||
| c078d496be | |||
| bceffcad6a | |||
| ccbf1f0544 | |||
| e5a8a06bbb | |||
| af1d85e65c | |||
| 7ace6c3593 | |||
| b3e0cf8ec1 | |||
| 4f77d1bfb3 | |||
| 72e54fe0d9 | |||
| 735083999e | |||
| 006a5729d6 | |||
| e4c3521b04 | |||
| dd13eddfe3 | |||
| 706cb888c8 | |||
| bfe5379206 | |||
| 2ffd1a2520 | |||
| 784e453eaa | |||
| 084b3d8822 | |||
| c03fd57c25 | |||
| 34d5f809ee | |||
| fd0d91faa4 | |||
| 2450602227 | |||
| 48ea90ce97 | |||
| 640ebdb835 | |||
| 5d59d729d7 | |||
| afadc5e2be | |||
| dc3c3f7557 | |||
| 61cbfe231d | |||
| 9ee2dd477e |
@@ -3,7 +3,7 @@ using Microsoft.AspNetCore.Mvc;
|
|||||||
using IRaCIS.Core.Domain.Share;
|
using IRaCIS.Core.Domain.Share;
|
||||||
using IRaCIS.Core.Infrastructure.Extention;
|
using IRaCIS.Core.Infrastructure.Extention;
|
||||||
|
|
||||||
namespace IRaCIS.Application.Services.BusinessFilter
|
namespace IRaCIS.Core.Application.Service.BusinessFilter
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 统一返回前端数据包装,之前在控制器包装,现在修改为动态Api 在ResultFilter这里包装,减少重复冗余代码
|
/// 统一返回前端数据包装,之前在控制器包装,现在修改为动态Api 在ResultFilter这里包装,减少重复冗余代码
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ using System.Linq;
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using IRaCIS.Core.Domain.Models;
|
using IRaCIS.Core.Domain.Models;
|
||||||
using IRaCIS.Core.Domain.Share;
|
using IRaCIS.Core.Domain.Share;
|
||||||
using IRaCIS.Application.Services;
|
using IRaCIS.Core.Application.Service;
|
||||||
using AutoMapper;
|
using AutoMapper;
|
||||||
using IRaCIS.Core.SCP.Service;
|
using IRaCIS.Core.SCP.Service;
|
||||||
|
|
||||||
|
|||||||
@@ -7,8 +7,11 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Aliyun.OSS.SDK.NetCore" Version="2.14.1" />
|
<PackageReference Include="AlibabaCloud.SDK.Sts20150401" Version="1.1.4" />
|
||||||
<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="AWSSDK.S3" Version="3.7.402.7" />
|
||||||
|
<PackageReference Include="AWSSDK.SecurityToken" Version="3.7.400.16" />
|
||||||
<PackageReference Include="DistributedLock.Core" Version="1.0.7" />
|
<PackageReference Include="DistributedLock.Core" Version="1.0.7" />
|
||||||
<PackageReference Include="DistributedLock.SqlServer" Version="1.0.5" />
|
<PackageReference Include="DistributedLock.SqlServer" Version="1.0.5" />
|
||||||
<PackageReference Include="fo-dicom" Version="5.1.3" />
|
<PackageReference Include="fo-dicom" Version="5.1.3" />
|
||||||
|
|||||||
@@ -113,6 +113,11 @@ builder.Services.AddAutoMapper(automapper =>
|
|||||||
//EF ORM QueryWithNoLock
|
//EF ORM QueryWithNoLock
|
||||||
builder.Services.AddEFSetup(_configuration);
|
builder.Services.AddEFSetup(_configuration);
|
||||||
|
|
||||||
|
builder.Services.AddMediator(cfg =>
|
||||||
|
{
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
//转发头设置 获取真实IP
|
//转发头设置 获取真实IP
|
||||||
builder.Services.Configure<ForwardedHeadersOptions>(options =>
|
builder.Services.Configure<ForwardedHeadersOptions>(options =>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
using AutoMapper;
|
using AutoMapper;
|
||||||
using IRaCIS.Application.Services.BusinessFilter;
|
using IRaCIS.Core.Application.Service.BusinessFilter;
|
||||||
using IRaCIS.Core.Infra.EFCore;
|
using IRaCIS.Core.Infra.EFCore;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
|
|||||||
@@ -176,6 +176,13 @@ namespace IRaCIS.Core.SCP.Service
|
|||||||
|
|
||||||
await _SCPImageUploadRepository.AddAsync(_upload, true);
|
await _SCPImageUploadRepository.AddAsync(_upload, true);
|
||||||
|
|
||||||
|
|
||||||
|
var _studyRepository = _serviceProvider.GetService<IRepository<SCPStudy>>();
|
||||||
|
//将检查设置为传输结束
|
||||||
|
await _studyRepository.BatchUpdateNoTrackingAsync(t => _SCPStudyIdList.Contains(t.Id), u => new SCPStudy() { IsUploadFinished = true });
|
||||||
|
|
||||||
|
await _studyRepository.SaveChangesAndClearAllTrackingAsync();
|
||||||
|
|
||||||
await SendAssociationReleaseResponseAsync();
|
await SendAssociationReleaseResponseAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -236,11 +243,11 @@ namespace IRaCIS.Core.SCP.Service
|
|||||||
//奇怪的bug 上传的时候,用王捷修改的影像,会关闭,重新连接,导致检查id 丢失,然后状态不一致
|
//奇怪的bug 上传的时候,用王捷修改的影像,会关闭,重新连接,导致检查id 丢失,然后状态不一致
|
||||||
if (exception == null)
|
if (exception == null)
|
||||||
{
|
{
|
||||||
var _studyRepository = _serviceProvider.GetService<IRepository<SCPStudy>>();
|
//var _studyRepository = _serviceProvider.GetService<IRepository<SCPStudy>>();
|
||||||
//将检查设置为传输结束
|
////将检查设置为传输结束
|
||||||
await _studyRepository.BatchUpdateNoTrackingAsync(t => _SCPStudyIdList.Contains(t.Id), u => new SCPStudy() { IsUploadFinished = true });
|
//await _studyRepository.BatchUpdateNoTrackingAsync(t => _SCPStudyIdList.Contains(t.Id), u => new SCPStudy() { IsUploadFinished = true });
|
||||||
|
|
||||||
await _studyRepository.SaveChangesAndClearAllTrackingAsync();
|
//await _studyRepository.SaveChangesAndClearAllTrackingAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.Logger.Warning($"连接关闭 {exception?.Message} {exception?.InnerException?.Message}");
|
Log.Logger.Warning($"连接关闭 {exception?.Message} {exception?.InnerException?.Message}");
|
||||||
|
|||||||
+473
-145
@@ -1,102 +1,139 @@
|
|||||||
using Aliyun.OSS;
|
using AlibabaCloud.SDK.Sts20150401;
|
||||||
|
using Aliyun.OSS;
|
||||||
|
using Amazon;
|
||||||
|
using Amazon.Runtime;
|
||||||
|
using Amazon.S3;
|
||||||
|
using Amazon.S3.Model;
|
||||||
|
using Amazon.SecurityToken;
|
||||||
|
using Amazon.SecurityToken.Model;
|
||||||
using IRaCIS.Core.Infrastructure;
|
using IRaCIS.Core.Infrastructure;
|
||||||
using Microsoft.Extensions.Hosting;
|
using IRaCIS.Core.Infrastructure.NewtonsoftJson;
|
||||||
|
using MassTransit;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using Minio.DataModel.Args;
|
|
||||||
using Minio;
|
using Minio;
|
||||||
using SharpCompress.Common;
|
using Minio.DataModel.Args;
|
||||||
using System;
|
using System.Reactive.Linq;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Drawing;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Security.AccessControl;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace IRaCIS.Core.SCP
|
namespace IRaCIS.Core.SCP;
|
||||||
|
|
||||||
|
#region 绑定和返回模型
|
||||||
|
|
||||||
|
[LowerCamelCaseJson]
|
||||||
|
public class MinIOOptions : AWSOptions
|
||||||
{
|
{
|
||||||
public class MinIOOptions : AWSOptions
|
public int Port { get; set; }
|
||||||
{
|
|
||||||
public int port { get; set; }
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class AWSOptions
|
|
||||||
{
|
|
||||||
public string endPoint { get; set; }
|
|
||||||
public bool useSSL { get; set; }
|
|
||||||
public string accessKey { get; set; }
|
|
||||||
public string secretKey { get; set; }
|
|
||||||
public string bucketName { get; set; }
|
|
||||||
public string viewEndpoint { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public class AliyunOSSOptions
|
public class AWSOptions
|
||||||
{
|
{
|
||||||
public string regionId { get; set; }
|
public string EndPoint { get; set; }
|
||||||
public string accessKeyId { get; set; }
|
public bool UseSSL { get; set; }
|
||||||
public string accessKeySecret { get; set; }
|
|
||||||
|
|
||||||
public string internalEndpoint { get; set; }
|
|
||||||
|
|
||||||
public string endPoint { get; set; }
|
|
||||||
public string bucketName { get; set; }
|
|
||||||
|
|
||||||
public string roleArn { get; set; }
|
|
||||||
|
|
||||||
public string region { get; set; }
|
|
||||||
|
|
||||||
public string viewEndpoint { get; set; }
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ObjectStoreServiceOptions
|
|
||||||
{
|
|
||||||
public string ObjectStoreUse { get; set; }
|
|
||||||
public AliyunOSSOptions AliyunOSS { get; set; }
|
|
||||||
public MinIOOptions MinIO { get; set; }
|
|
||||||
|
|
||||||
public AWSOptions AWS { get; set; }
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ObjectStoreDTO
|
|
||||||
{
|
|
||||||
public string ObjectStoreUse { get; set; }
|
|
||||||
|
|
||||||
public AliyunOSSOptions AliyunOSS { get; set; }
|
|
||||||
|
|
||||||
public MinIOOptions MinIO { get; set; }
|
|
||||||
|
|
||||||
public AWSOptions AWS { get; set; }
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public class AliyunOSSTempToken
|
|
||||||
{
|
|
||||||
public string AccessKeyId { get; set; }
|
public string AccessKeyId { get; set; }
|
||||||
public string AccessKeySecret { get; set; }
|
public string RoleArn { get; set; }
|
||||||
public string SecurityToken { get; set; }
|
public string SecretAccessKey { get; set; }
|
||||||
public string Expiration { get; set; }
|
|
||||||
|
|
||||||
public string Region { get; set; }
|
|
||||||
public string BucketName { get; set; }
|
public string BucketName { get; set; }
|
||||||
public string ViewEndpoint { get; set; }
|
public string ViewEndpoint { get; set; }
|
||||||
}
|
public int DurationSeconds { get; set; }
|
||||||
|
public string Region { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class AliyunOSSOptions
|
||||||
|
{
|
||||||
|
public string RegionId { get; set; }
|
||||||
|
public string AccessKeyId { get; set; }
|
||||||
|
public string AccessKeySecret { get; set; }
|
||||||
|
|
||||||
|
public string InternalEndpoint { get; set; }
|
||||||
|
|
||||||
|
public string EndPoint { get; set; }
|
||||||
|
public string BucketName { get; set; }
|
||||||
|
|
||||||
|
public string RoleArn { get; set; }
|
||||||
|
|
||||||
|
public string Region { get; set; }
|
||||||
|
|
||||||
|
public string ViewEndpoint { get; set; }
|
||||||
|
|
||||||
|
public int DurationSeconds { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public enum ObjectStoreUse
|
}
|
||||||
{
|
|
||||||
|
public class ObjectStoreServiceOptions
|
||||||
|
{
|
||||||
|
public string ObjectStoreUse { get; set; }
|
||||||
|
|
||||||
|
public AliyunOSSOptions AliyunOSS { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
public MinIOOptions MinIO { get; set; }
|
||||||
|
|
||||||
|
public AWSOptions AWS { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ObjectStoreDTO
|
||||||
|
{
|
||||||
|
public string ObjectStoreUse { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
public AliyunOSSTempToken AliyunOSS { get; set; }
|
||||||
|
|
||||||
|
public MinIOOptions MinIO { get; set; }
|
||||||
|
|
||||||
|
public AWSTempToken AWS { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[LowerCamelCaseJson]
|
||||||
|
public class AliyunOSSTempToken
|
||||||
|
{
|
||||||
|
public string AccessKeyId { get; set; }
|
||||||
|
public string AccessKeySecret { get; set; }
|
||||||
|
|
||||||
|
public string EndPoint { get; set; }
|
||||||
|
public string BucketName { get; set; }
|
||||||
|
|
||||||
|
public string Region { get; set; }
|
||||||
|
|
||||||
|
public string ViewEndpoint { get; set; }
|
||||||
|
|
||||||
|
public string SecurityToken { get; set; }
|
||||||
|
public DateTime Expiration { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[LowerCamelCaseJson]
|
||||||
|
public class AWSTempToken
|
||||||
|
{
|
||||||
|
public string Region { get; set; }
|
||||||
|
public string SessionToken { get; set; }
|
||||||
|
public string EndPoint { get; set; }
|
||||||
|
public string AccessKeyId { get; set; }
|
||||||
|
public string SecretAccessKey { get; set; }
|
||||||
|
public string BucketName { get; set; }
|
||||||
|
public string ViewEndpoint { get; set; }
|
||||||
|
public DateTime Expiration { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum ObjectStoreUse
|
||||||
|
{
|
||||||
AliyunOSS = 0,
|
AliyunOSS = 0,
|
||||||
MinIO = 1,
|
MinIO = 1,
|
||||||
AWS = 2,
|
AWS = 2,
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface IOSSService
|
#endregion
|
||||||
{
|
|
||||||
|
// aws 参考链接 https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/dotnetv3/S3/S3_Basics
|
||||||
|
|
||||||
|
public interface IOSSService
|
||||||
|
{
|
||||||
public Task<string> UploadToOSSAsync(Stream fileStream, string oosFolderPath, string fileRealName, bool isFileNameAddGuid = true);
|
public Task<string> UploadToOSSAsync(Stream fileStream, string oosFolderPath, string fileRealName, bool isFileNameAddGuid = true);
|
||||||
public Task<string> UploadToOSSAsync(string localFilePath, string oosFolderPath, bool isFileNameAddGuid = true);
|
public Task<string> UploadToOSSAsync(string localFilePath, string oosFolderPath, bool isFileNameAddGuid = true);
|
||||||
|
|
||||||
@@ -106,19 +143,29 @@ namespace IRaCIS.Core.SCP
|
|||||||
|
|
||||||
public Task<string> GetSignedUrl(string ossRelativePath);
|
public Task<string> GetSignedUrl(string ossRelativePath);
|
||||||
|
|
||||||
}
|
public Task DeleteFromPrefix(string prefix);
|
||||||
|
|
||||||
|
public ObjectStoreDTO GetObjectStoreTempToken();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public class OSSService : IOSSService
|
public class OSSService : IOSSService
|
||||||
{
|
{
|
||||||
public ObjectStoreServiceOptions ObjectStoreServiceOptions { get; set; }
|
public ObjectStoreServiceOptions ObjectStoreServiceOptions { get; set; }
|
||||||
|
|
||||||
|
private AliyunOSSTempToken AliyunOSSTempToken { get; set; }
|
||||||
|
|
||||||
|
private AWSTempToken AWSTempToken { get; set; }
|
||||||
|
|
||||||
|
|
||||||
public OSSService(IOptionsMonitor<ObjectStoreServiceOptions> options)
|
public OSSService(IOptionsMonitor<ObjectStoreServiceOptions> options)
|
||||||
{
|
{
|
||||||
ObjectStoreServiceOptions = options.CurrentValue;
|
ObjectStoreServiceOptions = options.CurrentValue;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// oosFolderPath 不要 "/ "开头 应该: TempFolder/ChildFolder
|
/// oosFolderPath 不要 "/ "开头 应该: TempFolder/ChildFolder
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -129,9 +176,9 @@ namespace IRaCIS.Core.SCP
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public async Task<string> UploadToOSSAsync(Stream fileStream, string oosFolderPath, string fileRealName, bool isFileNameAddGuid = true)
|
public async Task<string> UploadToOSSAsync(Stream fileStream, string oosFolderPath, string fileRealName, bool isFileNameAddGuid = true)
|
||||||
{
|
{
|
||||||
|
GetObjectStoreTempToken();
|
||||||
|
|
||||||
var ossRelativePath = isFileNameAddGuid ? $"{oosFolderPath}/{Guid.NewGuid()}_{fileRealName}" : $"{oosFolderPath}/{fileRealName}";
|
var ossRelativePath = isFileNameAddGuid ? $"{oosFolderPath}/{Guid.NewGuid()}_{fileRealName}" : $"{oosFolderPath}/{fileRealName}";
|
||||||
//var ossRelativePath = $"{oosFolderPath}/{Guid.NewGuid()}_{fileRealName}";
|
|
||||||
//var ossRelativePath = oosFolderPath + "/" + fileRealName;
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -148,12 +195,12 @@ namespace IRaCIS.Core.SCP
|
|||||||
{
|
{
|
||||||
var aliConfig = ObjectStoreServiceOptions.AliyunOSS;
|
var aliConfig = ObjectStoreServiceOptions.AliyunOSS;
|
||||||
|
|
||||||
var _ossClient = new OssClient(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? aliConfig.endPoint : aliConfig.internalEndpoint, aliConfig.accessKeyId, aliConfig.accessKeySecret);
|
var _ossClient = new OssClient(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? aliConfig.EndPoint : aliConfig.InternalEndpoint, AliyunOSSTempToken.AccessKeyId, AliyunOSSTempToken.AccessKeySecret, AliyunOSSTempToken.SecurityToken);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// 上传文件
|
// 上传文件
|
||||||
var result = _ossClient.PutObject(aliConfig.bucketName, ossRelativePath, memoryStream);
|
var result = _ossClient.PutObject(aliConfig.BucketName, ossRelativePath, memoryStream);
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (ObjectStoreServiceOptions.ObjectStoreUse == "MinIO")
|
else if (ObjectStoreServiceOptions.ObjectStoreUse == "MinIO")
|
||||||
@@ -161,12 +208,12 @@ namespace IRaCIS.Core.SCP
|
|||||||
var minIOConfig = ObjectStoreServiceOptions.MinIO;
|
var minIOConfig = ObjectStoreServiceOptions.MinIO;
|
||||||
|
|
||||||
|
|
||||||
var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.endPoint}:{minIOConfig.port}")
|
var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.EndPoint}:{minIOConfig.Port}")
|
||||||
.WithCredentials(minIOConfig.accessKey, minIOConfig.secretKey).WithSSL(minIOConfig.useSSL)
|
.WithCredentials(minIOConfig.AccessKeyId, minIOConfig.SecretAccessKey).WithSSL(minIOConfig.UseSSL)
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
var putObjectArgs = new PutObjectArgs()
|
var putObjectArgs = new PutObjectArgs()
|
||||||
.WithBucket(minIOConfig.bucketName)
|
.WithBucket(minIOConfig.BucketName)
|
||||||
.WithObject(ossRelativePath)
|
.WithObject(ossRelativePath)
|
||||||
.WithStreamData(memoryStream)
|
.WithStreamData(memoryStream)
|
||||||
.WithObjectSize(memoryStream.Length);
|
.WithObjectSize(memoryStream.Length);
|
||||||
@@ -175,20 +222,29 @@ namespace IRaCIS.Core.SCP
|
|||||||
}
|
}
|
||||||
else if (ObjectStoreServiceOptions.ObjectStoreUse == "AWS")
|
else if (ObjectStoreServiceOptions.ObjectStoreUse == "AWS")
|
||||||
{
|
{
|
||||||
var minIOConfig = ObjectStoreServiceOptions.AWS;
|
var awsConfig = ObjectStoreServiceOptions.AWS;
|
||||||
|
|
||||||
|
var credentials = new SessionAWSCredentials(AWSTempToken.AccessKeyId, AWSTempToken.SecretAccessKey, AWSTempToken.SessionToken);
|
||||||
|
|
||||||
|
|
||||||
var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.endPoint}")
|
|
||||||
.WithCredentials(minIOConfig.accessKey, minIOConfig.secretKey).WithSSL(minIOConfig.useSSL)
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
var putObjectArgs = new PutObjectArgs()
|
//提供awsEndPoint(域名)进行访问配置
|
||||||
.WithBucket(minIOConfig.bucketName)
|
var clientConfig = new AmazonS3Config
|
||||||
.WithObject(ossRelativePath)
|
{
|
||||||
.WithStreamData(memoryStream)
|
RegionEndpoint = RegionEndpoint.USEast1,
|
||||||
.WithObjectSize(memoryStream.Length);
|
UseHttp = true,
|
||||||
|
};
|
||||||
|
|
||||||
await minioClient.PutObjectAsync(putObjectArgs);
|
var amazonS3Client = new AmazonS3Client(credentials, clientConfig);
|
||||||
|
|
||||||
|
var putObjectRequest = new Amazon.S3.Model.PutObjectRequest()
|
||||||
|
{
|
||||||
|
BucketName = awsConfig.BucketName,
|
||||||
|
InputStream = memoryStream,
|
||||||
|
Key = ossRelativePath,
|
||||||
|
};
|
||||||
|
|
||||||
|
await amazonS3Client.PutObjectAsync(putObjectRequest);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -216,26 +272,26 @@ namespace IRaCIS.Core.SCP
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="localFilePath"></param>
|
/// <param name="localFilePath"></param>
|
||||||
/// <param name="oosFolderPath"></param>
|
/// <param name="oosFolderPath"></param>
|
||||||
|
/// <param name="isFileNameAddGuid"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
/// <exception cref="BusinessValidationFailedException"></exception>
|
/// <exception cref="BusinessValidationFailedException"></exception>
|
||||||
public async Task<string> UploadToOSSAsync(string localFilePath, string oosFolderPath, bool isFileNameAddGuid = true)
|
public async Task<string> UploadToOSSAsync(string localFilePath, string oosFolderPath, bool isFileNameAddGuid = true)
|
||||||
{
|
{
|
||||||
|
GetObjectStoreTempToken();
|
||||||
|
|
||||||
var localFileName = Path.GetFileName(localFilePath);
|
var localFileName = Path.GetFileName(localFilePath);
|
||||||
|
|
||||||
var ossRelativePath = isFileNameAddGuid ? $"{oosFolderPath}/{Guid.NewGuid()}_{localFileName}" : $"{oosFolderPath}/{localFileName}";
|
var ossRelativePath = isFileNameAddGuid ? $"{oosFolderPath}/{Guid.NewGuid()}_{localFileName}" : $"{oosFolderPath}/{localFileName}";
|
||||||
|
|
||||||
|
|
||||||
//var ossRelativePath = oosFolderPath + "/" + localFileName;
|
|
||||||
|
|
||||||
|
|
||||||
if (ObjectStoreServiceOptions.ObjectStoreUse == "AliyunOSS")
|
if (ObjectStoreServiceOptions.ObjectStoreUse == "AliyunOSS")
|
||||||
{
|
{
|
||||||
var aliConfig = ObjectStoreServiceOptions.AliyunOSS;
|
var aliConfig = ObjectStoreServiceOptions.AliyunOSS;
|
||||||
|
|
||||||
var _ossClient = new OssClient(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? aliConfig.endPoint : aliConfig.internalEndpoint, aliConfig.accessKeyId, aliConfig.accessKeySecret);
|
var _ossClient = new OssClient(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? aliConfig.EndPoint : aliConfig.InternalEndpoint, AliyunOSSTempToken.AccessKeyId, AliyunOSSTempToken.AccessKeySecret, AliyunOSSTempToken.SecurityToken);
|
||||||
|
|
||||||
// 上传文件
|
// 上传文件
|
||||||
var result = _ossClient.PutObject(aliConfig.bucketName, ossRelativePath, localFilePath);
|
var result = _ossClient.PutObject(aliConfig.BucketName, ossRelativePath, localFilePath);
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (ObjectStoreServiceOptions.ObjectStoreUse == "MinIO")
|
else if (ObjectStoreServiceOptions.ObjectStoreUse == "MinIO")
|
||||||
@@ -243,12 +299,12 @@ namespace IRaCIS.Core.SCP
|
|||||||
var minIOConfig = ObjectStoreServiceOptions.MinIO;
|
var minIOConfig = ObjectStoreServiceOptions.MinIO;
|
||||||
|
|
||||||
|
|
||||||
var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.endPoint}:{minIOConfig.port}")
|
var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.EndPoint}:{minIOConfig.Port}")
|
||||||
.WithCredentials(minIOConfig.accessKey, minIOConfig.secretKey).WithSSL(minIOConfig.useSSL)
|
.WithCredentials(minIOConfig.AccessKeyId, minIOConfig.SecretAccessKey).WithSSL(minIOConfig.UseSSL)
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
var putObjectArgs = new PutObjectArgs()
|
var putObjectArgs = new PutObjectArgs()
|
||||||
.WithBucket(minIOConfig.bucketName)
|
.WithBucket(minIOConfig.BucketName)
|
||||||
.WithObject(ossRelativePath)
|
.WithObject(ossRelativePath)
|
||||||
.WithFileName(localFilePath);
|
.WithFileName(localFilePath);
|
||||||
|
|
||||||
@@ -256,19 +312,29 @@ namespace IRaCIS.Core.SCP
|
|||||||
}
|
}
|
||||||
else if (ObjectStoreServiceOptions.ObjectStoreUse == "AWS")
|
else if (ObjectStoreServiceOptions.ObjectStoreUse == "AWS")
|
||||||
{
|
{
|
||||||
var minIOConfig = ObjectStoreServiceOptions.AWS;
|
var awsConfig = ObjectStoreServiceOptions.AWS;
|
||||||
|
|
||||||
|
// 提供awsAccessKeyId和awsSecretAccessKey构造凭证
|
||||||
|
var credentials = new SessionAWSCredentials(AWSTempToken.AccessKeyId, AWSTempToken.SecretAccessKey, AWSTempToken.SessionToken);
|
||||||
|
|
||||||
var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.endPoint}")
|
//提供awsEndPoint(域名)进行访问配置
|
||||||
.WithCredentials(minIOConfig.accessKey, minIOConfig.secretKey).WithSSL(minIOConfig.useSSL)
|
var clientConfig = new AmazonS3Config
|
||||||
.Build();
|
{
|
||||||
|
RegionEndpoint = RegionEndpoint.USEast1,
|
||||||
|
UseHttp = true,
|
||||||
|
};
|
||||||
|
|
||||||
var putObjectArgs = new PutObjectArgs()
|
var amazonS3Client = new AmazonS3Client(credentials, clientConfig);
|
||||||
.WithBucket(minIOConfig.bucketName)
|
|
||||||
.WithObject(ossRelativePath)
|
var putObjectRequest = new Amazon.S3.Model.PutObjectRequest()
|
||||||
.WithFileName(localFilePath);
|
{
|
||||||
|
BucketName = awsConfig.BucketName,
|
||||||
|
FilePath = localFilePath,
|
||||||
|
Key = ossRelativePath,
|
||||||
|
};
|
||||||
|
|
||||||
|
await amazonS3Client.PutObjectAsync(putObjectRequest);
|
||||||
|
|
||||||
await minioClient.PutObjectAsync(putObjectArgs);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -281,6 +347,7 @@ namespace IRaCIS.Core.SCP
|
|||||||
|
|
||||||
public async Task DownLoadFromOSSAsync(string ossRelativePath, string localFilePath)
|
public async Task DownLoadFromOSSAsync(string ossRelativePath, string localFilePath)
|
||||||
{
|
{
|
||||||
|
GetObjectStoreTempToken();
|
||||||
|
|
||||||
ossRelativePath = ossRelativePath.TrimStart('/');
|
ossRelativePath = ossRelativePath.TrimStart('/');
|
||||||
try
|
try
|
||||||
@@ -291,10 +358,10 @@ namespace IRaCIS.Core.SCP
|
|||||||
{
|
{
|
||||||
var aliConfig = ObjectStoreServiceOptions.AliyunOSS;
|
var aliConfig = ObjectStoreServiceOptions.AliyunOSS;
|
||||||
|
|
||||||
var _ossClient = new OssClient(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? aliConfig.endPoint : aliConfig.internalEndpoint, aliConfig.accessKeyId, aliConfig.accessKeySecret);
|
var _ossClient = new OssClient(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? aliConfig.EndPoint : aliConfig.InternalEndpoint, AliyunOSSTempToken.AccessKeyId, AliyunOSSTempToken.AccessKeySecret, AliyunOSSTempToken.SecurityToken);
|
||||||
|
|
||||||
// 上传文件
|
// 上传文件
|
||||||
var result = _ossClient.GetObject(aliConfig.bucketName, ossRelativePath);
|
var result = _ossClient.GetObject(aliConfig.BucketName, ossRelativePath);
|
||||||
|
|
||||||
// 将下载的文件流保存到本地文件
|
// 将下载的文件流保存到本地文件
|
||||||
using (var fs = File.OpenWrite(localFilePath))
|
using (var fs = File.OpenWrite(localFilePath))
|
||||||
@@ -308,12 +375,12 @@ namespace IRaCIS.Core.SCP
|
|||||||
{
|
{
|
||||||
var minIOConfig = ObjectStoreServiceOptions.MinIO;
|
var minIOConfig = ObjectStoreServiceOptions.MinIO;
|
||||||
|
|
||||||
var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.endPoint}:{minIOConfig.port}")
|
var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.EndPoint}:{minIOConfig.Port}")
|
||||||
.WithCredentials(minIOConfig.accessKey, minIOConfig.secretKey).WithSSL(minIOConfig.useSSL)
|
.WithCredentials(minIOConfig.AccessKeyId, minIOConfig.SecretAccessKey).WithSSL(minIOConfig.UseSSL)
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
var getObjectArgs = new GetObjectArgs()
|
var getObjectArgs = new GetObjectArgs()
|
||||||
.WithBucket(minIOConfig.bucketName)
|
.WithBucket(minIOConfig.BucketName)
|
||||||
.WithObject(ossRelativePath)
|
.WithObject(ossRelativePath)
|
||||||
.WithFile(localFilePath);
|
.WithFile(localFilePath);
|
||||||
|
|
||||||
@@ -322,18 +389,30 @@ namespace IRaCIS.Core.SCP
|
|||||||
}
|
}
|
||||||
else if (ObjectStoreServiceOptions.ObjectStoreUse == "AWS")
|
else if (ObjectStoreServiceOptions.ObjectStoreUse == "AWS")
|
||||||
{
|
{
|
||||||
var minIOConfig = ObjectStoreServiceOptions.AWS;
|
var awsConfig = ObjectStoreServiceOptions.AWS;
|
||||||
|
|
||||||
var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.endPoint}")
|
// 提供awsAccessKeyId和awsSecretAccessKey构造凭证
|
||||||
.WithCredentials(minIOConfig.accessKey, minIOConfig.secretKey).WithSSL(minIOConfig.useSSL)
|
var credentials = new SessionAWSCredentials(AWSTempToken.AccessKeyId, AWSTempToken.SecretAccessKey, AWSTempToken.SessionToken);
|
||||||
.Build();
|
|
||||||
|
//提供awsEndPoint(域名)进行访问配置
|
||||||
|
var clientConfig = new AmazonS3Config
|
||||||
|
{
|
||||||
|
RegionEndpoint = RegionEndpoint.USEast1,
|
||||||
|
UseHttp = true,
|
||||||
|
};
|
||||||
|
|
||||||
|
var amazonS3Client = new AmazonS3Client(credentials, clientConfig);
|
||||||
|
|
||||||
|
var getObjectArgs = new Amazon.S3.Model.GetObjectRequest()
|
||||||
|
{
|
||||||
|
BucketName = awsConfig.BucketName,
|
||||||
|
Key = ossRelativePath,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
await (await amazonS3Client.GetObjectAsync(getObjectArgs)).WriteResponseStreamToFileAsync(localFilePath, true, CancellationToken.None);
|
||||||
|
|
||||||
var getObjectArgs = new GetObjectArgs()
|
|
||||||
.WithBucket(minIOConfig.bucketName)
|
|
||||||
.WithObject(ossRelativePath)
|
|
||||||
.WithFile(localFilePath);
|
|
||||||
|
|
||||||
await minioClient.GetObjectAsync(getObjectArgs);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -354,6 +433,8 @@ namespace IRaCIS.Core.SCP
|
|||||||
|
|
||||||
public async Task<string> GetSignedUrl(string ossRelativePath)
|
public async Task<string> GetSignedUrl(string ossRelativePath)
|
||||||
{
|
{
|
||||||
|
GetObjectStoreTempToken();
|
||||||
|
|
||||||
ossRelativePath = ossRelativePath.TrimStart('/');
|
ossRelativePath = ossRelativePath.TrimStart('/');
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -363,10 +444,10 @@ namespace IRaCIS.Core.SCP
|
|||||||
{
|
{
|
||||||
var aliConfig = ObjectStoreServiceOptions.AliyunOSS;
|
var aliConfig = ObjectStoreServiceOptions.AliyunOSS;
|
||||||
|
|
||||||
var _ossClient = new OssClient(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? aliConfig.endPoint : aliConfig.internalEndpoint, aliConfig.accessKeyId, aliConfig.accessKeySecret);
|
var _ossClient = new OssClient(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? aliConfig.EndPoint : aliConfig.InternalEndpoint, AliyunOSSTempToken.AccessKeyId, AliyunOSSTempToken.AccessKeySecret, AliyunOSSTempToken.SecurityToken);
|
||||||
|
|
||||||
// 生成签名URL。
|
// 生成签名URL。
|
||||||
var req = new GeneratePresignedUriRequest(aliConfig.bucketName, ossRelativePath, SignHttpMethod.Get)
|
var req = new GeneratePresignedUriRequest(aliConfig.BucketName, ossRelativePath, SignHttpMethod.Get)
|
||||||
{
|
{
|
||||||
// 设置签名URL过期时间,默认值为3600秒。
|
// 设置签名URL过期时间,默认值为3600秒。
|
||||||
Expiration = DateTime.Now.AddHours(1),
|
Expiration = DateTime.Now.AddHours(1),
|
||||||
@@ -380,13 +461,13 @@ namespace IRaCIS.Core.SCP
|
|||||||
{
|
{
|
||||||
var minIOConfig = ObjectStoreServiceOptions.MinIO;
|
var minIOConfig = ObjectStoreServiceOptions.MinIO;
|
||||||
|
|
||||||
var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.endPoint}:{minIOConfig.port}")
|
var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.EndPoint}:{minIOConfig.Port}")
|
||||||
.WithCredentials(minIOConfig.accessKey, minIOConfig.secretKey).WithSSL(minIOConfig.useSSL)
|
.WithCredentials(minIOConfig.AccessKeyId, minIOConfig.SecretAccessKey).WithSSL(minIOConfig.UseSSL)
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
|
|
||||||
var args = new PresignedGetObjectArgs()
|
var args = new PresignedGetObjectArgs()
|
||||||
.WithBucket(minIOConfig.bucketName)
|
.WithBucket(minIOConfig.BucketName)
|
||||||
.WithObject(ossRelativePath)
|
.WithObject(ossRelativePath)
|
||||||
.WithExpiry(3600)
|
.WithExpiry(3600)
|
||||||
/*.WithHeaders(reqParams)*/;
|
/*.WithHeaders(reqParams)*/;
|
||||||
@@ -403,18 +484,27 @@ namespace IRaCIS.Core.SCP
|
|||||||
}
|
}
|
||||||
else if (ObjectStoreServiceOptions.ObjectStoreUse == "AWS")
|
else if (ObjectStoreServiceOptions.ObjectStoreUse == "AWS")
|
||||||
{
|
{
|
||||||
var minIOConfig = ObjectStoreServiceOptions.AWS;
|
var awsConfig = ObjectStoreServiceOptions.AWS;
|
||||||
|
|
||||||
var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.endPoint}")
|
|
||||||
.WithCredentials(minIOConfig.accessKey, minIOConfig.secretKey).WithSSL(minIOConfig.useSSL)
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
var args = new PresignedGetObjectArgs()
|
// 提供awsAccessKeyId和awsSecretAccessKey构造凭证
|
||||||
.WithBucket(minIOConfig.bucketName)
|
var credentials = new SessionAWSCredentials(AWSTempToken.AccessKeyId, AWSTempToken.SecretAccessKey, AWSTempToken.SessionToken);
|
||||||
.WithObject(ossRelativePath)
|
|
||||||
.WithExpiry(3600);
|
|
||||||
|
|
||||||
var presignedUrl = await minioClient.PresignedGetObjectAsync(args);
|
//提供awsEndPoint(域名)进行访问配置
|
||||||
|
var clientConfig = new AmazonS3Config
|
||||||
|
{
|
||||||
|
RegionEndpoint = RegionEndpoint.USEast1,
|
||||||
|
UseHttp = true,
|
||||||
|
};
|
||||||
|
|
||||||
|
var amazonS3Client = new AmazonS3Client(credentials, clientConfig);
|
||||||
|
|
||||||
|
var presignedUrl = await amazonS3Client.GetPreSignedURLAsync(new GetPreSignedUrlRequest()
|
||||||
|
{
|
||||||
|
BucketName = awsConfig.BucketName,
|
||||||
|
Key = ossRelativePath,
|
||||||
|
Expires = DateTime.UtcNow.AddMinutes(120)
|
||||||
|
});
|
||||||
|
|
||||||
Uri uri = new Uri(presignedUrl);
|
Uri uri = new Uri(presignedUrl);
|
||||||
|
|
||||||
@@ -435,8 +525,246 @@ namespace IRaCIS.Core.SCP
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 删除某个目录的文件
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="prefix"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task DeleteFromPrefix(string prefix)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ObjectListing objectListing = null;
|
||||||
|
string nextMarker = null;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
// 使用 prefix 模拟目录结构,设置 MaxKeys 和 NextMarker
|
||||||
|
objectListing = _ossClient.ListObjects(new Aliyun.OSS.ListObjectsRequest(aliConfig.BucketName)
|
||||||
|
{
|
||||||
|
Prefix = prefix,
|
||||||
|
MaxKeys = 1000,
|
||||||
|
Marker = nextMarker
|
||||||
|
});
|
||||||
|
|
||||||
|
List<string> keys = objectListing.ObjectSummaries.Select(t => t.Key).ToList();
|
||||||
|
|
||||||
|
// 删除获取到的文件
|
||||||
|
if (keys.Count > 0)
|
||||||
|
{
|
||||||
|
_ossClient.DeleteObjects(new Aliyun.OSS.DeleteObjectsRequest(aliConfig.BucketName, keys, false));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置 NextMarker 以获取下一页的数据
|
||||||
|
nextMarker = objectListing.NextMarker;
|
||||||
|
|
||||||
|
} while (objectListing.IsTruncated);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"Error: {ex.Message}");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
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 listArgs = new ListObjectsArgs().WithBucket(minIOConfig.BucketName).WithPrefix(prefix).WithRecursive(true);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 创建一个空列表用于存储对象键
|
||||||
|
var objects = new List<string>();
|
||||||
|
|
||||||
|
// 使用 await foreach 来异步迭代对象列表
|
||||||
|
await foreach (var item in minioClient.ListObjectsEnumAsync(listArgs))
|
||||||
|
{
|
||||||
|
objects.Add(item.Key);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (objects.Count > 0)
|
||||||
|
{
|
||||||
|
var objArgs = new RemoveObjectsArgs()
|
||||||
|
.WithBucket(minIOConfig.BucketName)
|
||||||
|
.WithObjects(objects);
|
||||||
|
|
||||||
|
// 删除对象
|
||||||
|
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);
|
||||||
|
|
||||||
|
// 列出指定前缀下的所有对象
|
||||||
|
var listObjectsRequest = new ListObjectsV2Request
|
||||||
|
{
|
||||||
|
BucketName = awsConfig.BucketName,
|
||||||
|
Prefix = prefix
|
||||||
|
};
|
||||||
|
|
||||||
|
var listObjectsResponse = await amazonS3Client.ListObjectsV2Async(listObjectsRequest);
|
||||||
|
|
||||||
|
if (listObjectsResponse.S3Objects.Count > 0)
|
||||||
|
{
|
||||||
|
// 准备删除请求
|
||||||
|
var deleteObjectsRequest = new Amazon.S3.Model.DeleteObjectsRequest
|
||||||
|
{
|
||||||
|
BucketName = awsConfig.BucketName,
|
||||||
|
Objects = new List<KeyVersion>()
|
||||||
|
};
|
||||||
|
|
||||||
|
foreach (var s3Object in listObjectsResponse.S3Objects)
|
||||||
|
{
|
||||||
|
deleteObjectsRequest.Objects.Add(new KeyVersion
|
||||||
|
{
|
||||||
|
Key = s3Object.Key
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 批量删除对象
|
||||||
|
var deleteObjectsResponse = await amazonS3Client.DeleteObjectsAsync(deleteObjectsRequest);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new BusinessValidationFailedException("未定义的存储介质类型");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public ObjectStoreDTO GetObjectStoreTempToken()
|
||||||
|
{
|
||||||
|
|
||||||
|
var ossOptions = ObjectStoreServiceOptions.AliyunOSS;
|
||||||
|
|
||||||
|
if (ObjectStoreServiceOptions.ObjectStoreUse == "AliyunOSS")
|
||||||
|
{
|
||||||
|
var client = new Client(new AlibabaCloud.OpenApiClient.Models.Config()
|
||||||
|
{
|
||||||
|
AccessKeyId = ossOptions.AccessKeyId,
|
||||||
|
AccessKeySecret = ossOptions.AccessKeySecret,
|
||||||
|
//AccessKeyId = "LTAI5tJV76pYX5yPg1N9QVE8",
|
||||||
|
//AccessKeySecret = "roRNLa9YG1of4pYruJGCNKBXEWTAWa",
|
||||||
|
|
||||||
|
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,
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
AliyunOSSTempToken = tempToken;
|
||||||
|
|
||||||
|
return new ObjectStoreDTO() { ObjectStoreUse = ObjectStoreServiceOptions.ObjectStoreUse, AliyunOSS = tempToken };
|
||||||
|
}
|
||||||
|
else if (ObjectStoreServiceOptions.ObjectStoreUse == "MinIO")
|
||||||
|
{
|
||||||
|
return new ObjectStoreDTO() { ObjectStoreUse = ObjectStoreServiceOptions.ObjectStoreUse, MinIO = ObjectStoreServiceOptions.MinIO };
|
||||||
|
}
|
||||||
|
else if (ObjectStoreServiceOptions.ObjectStoreUse == "AWS")
|
||||||
|
{
|
||||||
|
var awsOptions = ObjectStoreServiceOptions.AWS;
|
||||||
|
|
||||||
|
//aws 临时凭证
|
||||||
|
// 创建 STS 客户端
|
||||||
|
var stsClient = new AmazonSecurityTokenServiceClient(awsOptions.AccessKeyId, awsOptions.SecretAccessKey);
|
||||||
|
|
||||||
|
// 使用 AssumeRole 请求临时凭证
|
||||||
|
var assumeRoleRequest = new AssumeRoleRequest
|
||||||
|
{
|
||||||
|
|
||||||
|
RoleArn = awsOptions.RoleArn, // 角色 ARN
|
||||||
|
RoleSessionName = $"session-name-{NewId.NextGuid()}",
|
||||||
|
DurationSeconds = awsOptions.DurationSeconds // 临时凭证有效期
|
||||||
|
};
|
||||||
|
|
||||||
|
var assumeRoleResponse = stsClient.AssumeRoleAsync(assumeRoleRequest).Result;
|
||||||
|
|
||||||
|
var credentials = assumeRoleResponse.Credentials;
|
||||||
|
|
||||||
|
var tempToken = new AWSTempToken()
|
||||||
|
{
|
||||||
|
AccessKeyId = credentials.AccessKeyId,
|
||||||
|
SecretAccessKey = credentials.SecretAccessKey,
|
||||||
|
SessionToken = credentials.SessionToken,
|
||||||
|
Expiration = credentials.Expiration,
|
||||||
|
Region = awsOptions.Region,
|
||||||
|
BucketName = awsOptions.BucketName,
|
||||||
|
EndPoint = awsOptions.EndPoint,
|
||||||
|
ViewEndpoint = awsOptions.ViewEndpoint,
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
AWSTempToken = tempToken;
|
||||||
|
return new ObjectStoreDTO() { ObjectStoreUse = ObjectStoreServiceOptions.ObjectStoreUse, AWS = tempToken };
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new BusinessValidationFailedException("未定义的存储介质类型");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,23 +9,16 @@
|
|||||||
"ObjectStoreService": {
|
"ObjectStoreService": {
|
||||||
"ObjectStoreUse": "AliyunOSS",
|
"ObjectStoreUse": "AliyunOSS",
|
||||||
"AliyunOSS": {
|
"AliyunOSS": {
|
||||||
"regionId": "cn-shanghai",
|
"RegionId": "cn-shanghai",
|
||||||
"internalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com",
|
"InternalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com",
|
||||||
"endpoint": "https://oss-cn-shanghai.aliyuncs.com",
|
"EndPoint": "https://oss-cn-shanghai.aliyuncs.com",
|
||||||
"accessKeyId": "LTAI5tKvzs7ed3UfSpNk3xwQ",
|
"AccessKeyId": "LTAI5tNRTsqL6aWmHkDmTwoH",
|
||||||
"accessKeySecret": "zTIceGEShlZDGnLrCFfIGFE7TXVRio",
|
"AccessKeySecret": "7mtGz3qrYWI6JMMBZiLeC119VWicZH",
|
||||||
"bucketName": "zy-irc-store",
|
"RoleArn": "acs:ram::1899121822495495:role/irc-oss-access",
|
||||||
"roleArn": "acs:ram::1899121822495495:role/oss-upload",
|
"BucketName": "zy-irc-store",
|
||||||
"viewEndpoint": "https://zy-irc-cache.oss-cn-shanghai.aliyuncs.com",
|
"ViewEndpoint": "https://zy-irc-cache.oss-cn-shanghai.aliyuncs.com",
|
||||||
"region": "oss-cn-shanghai"
|
"Region": "oss-cn-shanghai",
|
||||||
},
|
"DurationSeconds": 7200
|
||||||
"MinIO": {
|
|
||||||
"endpoint": "http://192.168.3.68",
|
|
||||||
"port": "8001",
|
|
||||||
"useSSL": false,
|
|
||||||
"accessKey": "IDFkwEpWej0b4DtiuThL",
|
|
||||||
"secretKey": "Lhuu83yMhVwu7c1SnjvGY6lq74jzpYqifK6Qtj4h",
|
|
||||||
"bucketName": "test"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -9,15 +9,16 @@
|
|||||||
"ObjectStoreService": {
|
"ObjectStoreService": {
|
||||||
"ObjectStoreUse": "AliyunOSS",
|
"ObjectStoreUse": "AliyunOSS",
|
||||||
"AliyunOSS": {
|
"AliyunOSS": {
|
||||||
"regionId": "cn-shanghai",
|
"RegionId": "cn-shanghai",
|
||||||
"internalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com",
|
"InternalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com",
|
||||||
"endPoint": "https://oss-cn-shanghai.aliyuncs.com",
|
"EndPoint": "https://oss-cn-shanghai.aliyuncs.com",
|
||||||
"accessKeyId": "LTAI5tKvzs7ed3UfSpNk3xwQ",
|
"AccessKeyId": "LTAI5tRRZehUp2V9pyTPtAJm",
|
||||||
"accessKeySecret": "zTIceGEShlZDGnLrCFfIGFE7TXVRio",
|
"AccessKeySecret": "FLizxkHsMm4CGYHtkV8E3PNJJZU7oV",
|
||||||
"bucketName": "zy-irc-test-store",
|
"RoleArn": "acs:ram::1899121822495495:role/dev-oss-access",
|
||||||
"roleArn": "acs:ram::1899121822495495:role/oss-upload",
|
"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",
|
||||||
"region": "oss-cn-shanghai"
|
"Region": "oss-cn-shanghai",
|
||||||
|
"DurationSeconds": 7200
|
||||||
},
|
},
|
||||||
|
|
||||||
"MinIO": {
|
"MinIO": {
|
||||||
@@ -28,53 +29,20 @@
|
|||||||
"secretKey": "TzgvyA3zGXMUnpilJNUlyMYHfosl1hBMl6lxPmjy",
|
"secretKey": "TzgvyA3zGXMUnpilJNUlyMYHfosl1hBMl6lxPmjy",
|
||||||
"bucketName": "hir-test",
|
"bucketName": "hir-test",
|
||||||
"viewEndpoint": "http://106.14.89.110:9001/hir-test/"
|
"viewEndpoint": "http://106.14.89.110:9001/hir-test/"
|
||||||
},
|
|
||||||
|
|
||||||
"AWS": {
|
|
||||||
"endPoint": "s3.us-east-1.amazonaws.com",
|
|
||||||
"useSSL": false,
|
|
||||||
"accessKey": "AKIAZQ3DRSOHFPJJ6FEU",
|
|
||||||
"secretKey": "l+yjtvV7Z4jiwm/7xCYv30UeUj/SvuqqYzAwjJHf",
|
|
||||||
"bucketName": "ei-irc-test-store",
|
|
||||||
"viewEndpoint": "https://ei-irc-test-store.s3.amazonaws.com/"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
"ConnectionStrings": {
|
"ConnectionStrings": {
|
||||||
"RemoteNew": "Server=106.14.89.110,1435;Database=Test_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
|
"RemoteNew": "Server=106.14.89.110,1435;Database=Test_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
|
||||||
"Hangfire": "Server=106.14.89.110,1435;Database=Test_IRC_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true"
|
"Hangfire": "Server=106.14.89.110,1435;Database=Test_IRC_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true"
|
||||||
},
|
},
|
||||||
"BasicSystemConfig": {
|
|
||||||
|
|
||||||
"OpenUserComplexPassword": false,
|
|
||||||
|
|
||||||
"OpenSignDocumentBeforeWork": false,
|
|
||||||
|
|
||||||
"OpenTrialRelationDelete": true,
|
|
||||||
|
|
||||||
"OpenLoginLimit": false,
|
|
||||||
"LoginMaxFailCount": 5,
|
|
||||||
|
|
||||||
"LoginFailLockMinutes": 30
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
"SystemEmailSendConfig": {
|
|
||||||
"Port": 465,
|
|
||||||
"Host": "smtp.qiye.aliyun.com",
|
|
||||||
"FromEmail": "test-study@extimaging.com",
|
|
||||||
"FromName": "Test_Study",
|
|
||||||
"AuthorizationCode": "zhanying123",
|
|
||||||
|
|
||||||
"SiteUrl": "http://study.test.extimaging.com/login"
|
|
||||||
},
|
|
||||||
"DicomSCPServiceConfig": {
|
"DicomSCPServiceConfig": {
|
||||||
"CalledAEList": [
|
"CalledAEList": [
|
||||||
"STORESCP",
|
"STORESCP"
|
||||||
"Value1",
|
|
||||||
"Value2",
|
|
||||||
"Value3"
|
|
||||||
],
|
],
|
||||||
"ServerPort": 11112
|
"ServerPort": 11112
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
{
|
||||||
|
"Logging": {
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Information",
|
||||||
|
"Microsoft": "Warning",
|
||||||
|
"Microsoft.Hosting.Lifetime": "Information"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ObjectStoreService": {
|
||||||
|
"ObjectStoreUse": "AWS",
|
||||||
|
"AWS": {
|
||||||
|
"Region": "us-east-1",
|
||||||
|
"EndPoint": "s3.us-east-1.amazonaws.com",
|
||||||
|
"UseSSL": true,
|
||||||
|
"RoleArn": "arn:aws:iam::471112624751:role/lili_s3_access",
|
||||||
|
"AccessKeyId": "AKIAW3MEAFJXZ2TZK7GM",
|
||||||
|
"SecretAccessKey": "9MLQCQ1HifEVW1gf068zBRAOb4wNnfrOkvBVByth",
|
||||||
|
"BucketName": "ei-med-s3-lili-store",
|
||||||
|
"ViewEndpoint": "https://ei-med-s3-lili-store.s3.amazonaws.com",
|
||||||
|
"DurationSeconds": 7200
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ConnectionStrings": {
|
||||||
|
"RemoteNew": "Server=us-prod-mssql-service,1433;Database=US_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
|
||||||
|
"Hangfire": "Server=us-prod-mssql-service,1433;Database=US_IRC_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true"
|
||||||
|
},
|
||||||
|
"DicomSCPServiceConfig": {
|
||||||
|
"CalledAEList": [
|
||||||
|
"STORESCP"
|
||||||
|
],
|
||||||
|
"ServerPort": 11112
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
{
|
||||||
|
"Logging": {
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Information",
|
||||||
|
"Microsoft": "Warning",
|
||||||
|
"Microsoft.Hosting.Lifetime": "Information"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ObjectStoreService": {
|
||||||
|
"ObjectStoreUse": "AWS",
|
||||||
|
"AWS": {
|
||||||
|
"Region": "us-east-1",
|
||||||
|
"EndPoint": "s3.us-east-1.amazonaws.com",
|
||||||
|
"UseSSL": true,
|
||||||
|
"RoleArn": "arn:aws:iam::471112624751:role/uat_s3_access",
|
||||||
|
"AccessKeyId": "AKIAW3MEAFJX7IPXISP4",
|
||||||
|
"SecretAccessKey": "Pgrg3le5jPxZQ7MR1yYNS30J0XRyJeKVyIIjElXc",
|
||||||
|
"BucketName": "ei-med-s3-lili-uat-store",
|
||||||
|
"ViewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com/",
|
||||||
|
"DurationSeconds": 7200
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ConnectionStrings": {
|
||||||
|
"RemoteNew": "Server=us-mssql-service,1433;Database=US_Uat_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
|
||||||
|
"Hangfire": "Server=us-mssql-service,1433;Database=US_Uat_IRC_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true"
|
||||||
|
},
|
||||||
|
"DicomSCPServiceConfig": {
|
||||||
|
"CalledAEList": [
|
||||||
|
"STORESCP"
|
||||||
|
],
|
||||||
|
"ServerPort": 11112
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -9,59 +9,27 @@
|
|||||||
"ObjectStoreService": {
|
"ObjectStoreService": {
|
||||||
"ObjectStoreUse": "AliyunOSS",
|
"ObjectStoreUse": "AliyunOSS",
|
||||||
"AliyunOSS": {
|
"AliyunOSS": {
|
||||||
"regionId": "cn-shanghai",
|
"RegionId": "cn-shanghai",
|
||||||
"internalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com",
|
"InternalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com",
|
||||||
"endpoint": "https://oss-cn-shanghai.aliyuncs.com",
|
"EndPoint": "https://oss-cn-shanghai.aliyuncs.com",
|
||||||
"accessKeyId": "LTAI5tKvzs7ed3UfSpNk3xwQ",
|
"AccessKeyId": "LTAI5tRRZehUp2V9pyTPtAJm",
|
||||||
"accessKeySecret": "zTIceGEShlZDGnLrCFfIGFE7TXVRio",
|
"AccessKeySecret": "FLizxkHsMm4CGYHtkV8E3PNJJZU7oV",
|
||||||
"bucketName": "zy-irc-uat-store",
|
"RoleArn": "acs:ram::1899121822495495:role/dev-oss-access",
|
||||||
"roleArn": "acs:ram::1899121822495495:role/oss-upload",
|
"BucketName": "zy-irc-uat-store",
|
||||||
"viewEndpoint": "https://zy-irc-uat-store.oss-cn-shanghai.aliyuncs.com",
|
"ViewEndpoint": "https://zy-irc-uat-store.oss-cn-shanghai.aliyuncs.com",
|
||||||
"region": "oss-cn-shanghai"
|
"Region": "oss-cn-shanghai",
|
||||||
},
|
"DurationSeconds": 7200
|
||||||
|
|
||||||
"AWS": {
|
|
||||||
"endPoint": "s3.us-east-1.amazonaws.com",
|
|
||||||
"useSSL": false,
|
|
||||||
"accessKey": "AKIAZQ3DRSOHFPJJ6FEU",
|
|
||||||
"secretKey": "l+yjtvV7Z4jiwm/7xCYv30UeUj/SvuqqYzAwjJHf",
|
|
||||||
"bucketName": "ei-irc-test-store",
|
|
||||||
"viewEndpoint": "https://ei-irc-test-store.s3.amazonaws.com/"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ConnectionStrings": {
|
"ConnectionStrings": {
|
||||||
"RemoteNew": "Server=47.117.164.182,1434;Database=Uat_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
|
"RemoteNew": "Server=47.117.164.182,1434;Database=Uat_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
|
||||||
"Hangfire": "Server=47.117.164.182,1434;Database=Uat_IRC.Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true"
|
"Hangfire": "Server=47.117.164.182,1434;Database=Uat_IRC.Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true"
|
||||||
},
|
},
|
||||||
"BasicSystemConfig": {
|
|
||||||
|
|
||||||
"OpenUserComplexPassword": false,
|
|
||||||
|
|
||||||
"OpenSignDocumentBeforeWork": false,
|
|
||||||
|
|
||||||
"OpenTrialRelationDelete": true,
|
|
||||||
|
|
||||||
"OpenLoginLimit": false,
|
|
||||||
"LoginMaxFailCount": 5,
|
|
||||||
|
|
||||||
"LoginFailLockMinutes": 30
|
|
||||||
},
|
|
||||||
|
|
||||||
"SystemEmailSendConfig": {
|
|
||||||
"Port": 465,
|
|
||||||
"Host": "smtp.qiye.aliyun.com",
|
|
||||||
"FromEmail": "uat-study@extimaging.com",
|
|
||||||
"FromName": "Uat_Study",
|
|
||||||
"AuthorizationCode": "zhanying123",
|
|
||||||
"SiteUrl": "http://study.uat.extimaging.com/login"
|
|
||||||
},
|
|
||||||
"DicomSCPServiceConfig": {
|
"DicomSCPServiceConfig": {
|
||||||
"CalledAEList": [
|
"CalledAEList": [
|
||||||
"STORESCP",
|
"STORESCP"
|
||||||
"Value1",
|
|
||||||
"Value2",
|
|
||||||
"Value3"
|
|
||||||
],
|
],
|
||||||
"ServerPort": 11112
|
"ServerPort": 11112
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -17,7 +17,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IRaCIS.Core.Infra.EFCore",
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IRaCIS.Core.Infrastructure", "IRaCIS.Core.Infrastructure\IRaCIS.Core.Infrastructure.csproj", "{07EED0F8-08E6-46F3-ACBE-17BC1391BD4C}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IRaCIS.Core.Infrastructure", "IRaCIS.Core.Infrastructure\IRaCIS.Core.Infrastructure.csproj", "{07EED0F8-08E6-46F3-ACBE-17BC1391BD4C}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IRC.Core.SCP", "IRC.Core.SCP\IRC.Core.SCP.csproj", "{ECD08F47-DC1A-484E-BB91-6CDDC8823CC5}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IRC.Core.SCP", "IRC.Core.SCP\IRC.Core.SCP.csproj", "{ECD08F47-DC1A-484E-BB91-6CDDC8823CC5}"
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
|||||||
@@ -1,99 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.ComponentModel.DataAnnotations;
|
|
||||||
using System.Linq;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
|
|
||||||
namespace EFSaving.Concurrency
|
|
||||||
{
|
|
||||||
public class Sample
|
|
||||||
{
|
|
||||||
public static void Run()
|
|
||||||
{
|
|
||||||
// Ensure database is created and has a person in it
|
|
||||||
using (var setupContext = new PersonContext())
|
|
||||||
{
|
|
||||||
setupContext.Database.EnsureDeleted();
|
|
||||||
setupContext.Database.EnsureCreated();
|
|
||||||
|
|
||||||
setupContext.People.Add(new Person { FirstName = "John", LastName = "Doe" });
|
|
||||||
setupContext.SaveChanges();
|
|
||||||
}
|
|
||||||
|
|
||||||
#region ConcurrencyHandlingCode
|
|
||||||
using var context = new PersonContext();
|
|
||||||
// Fetch a person from database and change phone number
|
|
||||||
var person = context.People.Single(p => p.PersonId == 1);
|
|
||||||
person.PhoneNumber = "555-555-5555";
|
|
||||||
|
|
||||||
// Change the person's name in the database to simulate a concurrency conflict
|
|
||||||
context.Database.ExecuteSqlRaw(
|
|
||||||
"UPDATE dbo.People SET FirstName = 'Jane' WHERE PersonId = 1");
|
|
||||||
|
|
||||||
var saved = false;
|
|
||||||
while (!saved)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// Attempt to save changes to the database
|
|
||||||
context.SaveChanges();
|
|
||||||
saved = true;
|
|
||||||
}
|
|
||||||
catch (DbUpdateConcurrencyException ex)
|
|
||||||
{
|
|
||||||
foreach (var entry in ex.Entries)
|
|
||||||
{
|
|
||||||
if (entry.Entity is Person)
|
|
||||||
{
|
|
||||||
var proposedValues = entry.CurrentValues;
|
|
||||||
var databaseValues = entry.GetDatabaseValues();
|
|
||||||
|
|
||||||
foreach (var property in proposedValues.Properties)
|
|
||||||
{
|
|
||||||
var proposedValue = proposedValues[property];
|
|
||||||
var databaseValue = databaseValues[property];
|
|
||||||
|
|
||||||
// TODO: decide which value should be written to database
|
|
||||||
// proposedValues[property] = <value to be saved>;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Refresh original values to bypass next concurrency check
|
|
||||||
entry.OriginalValues.SetValues(databaseValues);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new NotSupportedException(
|
|
||||||
"Don't know how to handle concurrency conflicts for "
|
|
||||||
+ entry.Metadata.Name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
|
|
||||||
public class PersonContext : DbContext
|
|
||||||
{
|
|
||||||
public DbSet<Person> People { get; set; }
|
|
||||||
|
|
||||||
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
|
||||||
{
|
|
||||||
// Requires NuGet package Microsoft.EntityFrameworkCore.SqlServer
|
|
||||||
optionsBuilder.UseSqlServer(
|
|
||||||
@"Server=(localdb)\mssqllocaldb;Database=EFSaving.Concurrency;Trusted_Connection=True");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class Person
|
|
||||||
{
|
|
||||||
public int PersonId { get; set; }
|
|
||||||
|
|
||||||
[ConcurrencyCheck]
|
|
||||||
public string FirstName { get; set; }
|
|
||||||
|
|
||||||
[ConcurrencyCheck]
|
|
||||||
public string LastName { get; set; }
|
|
||||||
|
|
||||||
public string PhoneNumber { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -14,7 +14,7 @@ using System.Text;
|
|||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using IRaCIS.Core.Application.Interfaces;
|
using IRaCIS.Core.Application.Interfaces;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using IRaCIS.Application.Services;
|
using IRaCIS.Core.Application.Service;
|
||||||
using IRaCIS.Core.Infra.EFCore;
|
using IRaCIS.Core.Infra.EFCore;
|
||||||
using IRaCIS.Core.Domain.Models;
|
using IRaCIS.Core.Domain.Models;
|
||||||
using IRaCIS.Core.Infrastructure;
|
using IRaCIS.Core.Infrastructure;
|
||||||
@@ -37,6 +37,7 @@ using Amazon.SecurityToken.Model;
|
|||||||
using Amazon.SecurityToken;
|
using Amazon.SecurityToken;
|
||||||
using Amazon;
|
using Amazon;
|
||||||
using AssumeRoleRequest = Amazon.SecurityToken.Model.AssumeRoleRequest;
|
using AssumeRoleRequest = Amazon.SecurityToken.Model.AssumeRoleRequest;
|
||||||
|
using AutoMapper;
|
||||||
|
|
||||||
namespace IRaCIS.Api.Controllers
|
namespace IRaCIS.Api.Controllers
|
||||||
{
|
{
|
||||||
@@ -109,8 +110,12 @@ namespace IRaCIS.Api.Controllers
|
|||||||
[FromServices] ITokenService _tokenService,
|
[FromServices] ITokenService _tokenService,
|
||||||
[FromServices] IReadingImageTaskService readingImageTaskService,
|
[FromServices] IReadingImageTaskService readingImageTaskService,
|
||||||
[FromServices] IOptionsMonitor<ServiceVerifyConfigOption> _verifyConfig,
|
[FromServices] IOptionsMonitor<ServiceVerifyConfigOption> _verifyConfig,
|
||||||
|
[FromServices] IOptionsMonitor<SystemEmailSendConfig> _emailConfig,
|
||||||
|
|
||||||
[FromServices] IMailVerificationService _mailVerificationService)
|
[FromServices] IMailVerificationService _mailVerificationService)
|
||||||
{
|
{
|
||||||
|
var emailConfig = _emailConfig.CurrentValue;
|
||||||
|
var companyInfo = new SystemEmailSendConfigView() { CompanyName = emailConfig.CompanyName, CompanyNameCN = emailConfig.CompanyNameCN, CompanyShortName = emailConfig.CompanyShortName, CompanyShortNameCN = emailConfig.CompanyShortNameCN };
|
||||||
|
|
||||||
//MFA 邮箱验证 前端传递用户Id 和MFACode
|
//MFA 邮箱验证 前端传递用户Id 和MFACode
|
||||||
if (loginUser.UserId != null && _verifyConfig.CurrentValue.OpenLoginMFA)
|
if (loginUser.UserId != null && _verifyConfig.CurrentValue.OpenLoginMFA)
|
||||||
@@ -143,10 +148,11 @@ namespace IRaCIS.Api.Controllers
|
|||||||
// 验证阅片休息时间
|
// 验证阅片休息时间
|
||||||
await readingImageTaskService.ResetReadingRestTime(userId);
|
await readingImageTaskService.ResetReadingRestTime(userId);
|
||||||
|
|
||||||
await _fusionCache.SetAsync(userId.ToString(), loginReturn.JWTStr, TimeSpan.FromDays(7));
|
await _fusionCache.SetAsync(CacheKeys.UserToken(userId), loginReturn.JWTStr, TimeSpan.FromDays(7));
|
||||||
|
|
||||||
await _fusionCache.SetAsync($"{userId.ToString()}_Online", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), TimeSpan.FromMinutes(_verifyConfig.CurrentValue.AutoLoginOutMinutes));
|
await _fusionCache.SetAsync(CacheKeys.UserAutoLoginOut(userId), DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), TimeSpan.FromMinutes(_verifyConfig.CurrentValue.AutoLoginOutMinutes));
|
||||||
|
|
||||||
|
loginReturn.CompanyInfo = companyInfo;
|
||||||
return ResponseOutput.Ok(loginReturn);
|
return ResponseOutput.Ok(loginReturn);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -221,9 +227,9 @@ namespace IRaCIS.Api.Controllers
|
|||||||
|
|
||||||
if (_verifyConfig.CurrentValue.OpenLoginMFA)
|
if (_verifyConfig.CurrentValue.OpenLoginMFA)
|
||||||
{
|
{
|
||||||
//发版屏蔽
|
|
||||||
|
|
||||||
//returnModel.Data.JWTStr = _tokenService.GetToken(IRaCISClaims.Create(returnModel.Data.BasicInfo));
|
|
||||||
|
|
||||||
|
|
||||||
//MFA 发送邮件
|
//MFA 发送邮件
|
||||||
|
|
||||||
@@ -231,13 +237,23 @@ namespace IRaCIS.Api.Controllers
|
|||||||
|
|
||||||
var email = returnModel.Data.BasicInfo.EMail;
|
var email = returnModel.Data.BasicInfo.EMail;
|
||||||
|
|
||||||
var hiddenEmail = EmailMaskHelper.MaskEmail(email);
|
var hiddenEmail = IRCEmailPasswordHelper.MaskEmail(email);
|
||||||
|
|
||||||
returnModel.Data.BasicInfo.EMail = hiddenEmail;
|
returnModel.Data.BasicInfo.EMail = hiddenEmail;
|
||||||
|
|
||||||
|
//修改密码
|
||||||
|
if (returnModel.Data.BasicInfo.IsFirstAdd || returnModel.Data.BasicInfo.LoginState == 1)
|
||||||
|
{
|
||||||
|
returnModel.Data.JWTStr = _tokenService.GetToken(IRaCISClaims.Create(returnModel.Data.BasicInfo));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//正常登录才发送邮件
|
||||||
await _userService.SendMFAEmail(userId);
|
await _userService.SendMFAEmail(userId);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
returnModel.Data.JWTStr = _tokenService.GetToken(IRaCISClaims.Create(returnModel.Data.BasicInfo));
|
returnModel.Data.JWTStr = _tokenService.GetToken(IRaCISClaims.Create(returnModel.Data.BasicInfo));
|
||||||
@@ -264,6 +280,8 @@ namespace IRaCIS.Api.Controllers
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
returnModel.Data.CompanyInfo = companyInfo;
|
||||||
return returnModel;
|
return returnModel;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -273,8 +291,14 @@ namespace IRaCIS.Api.Controllers
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[AllowAnonymous]
|
||||||
|
[HttpGet, Route("user/getPublicKey")]
|
||||||
|
public IResponseOutput GetPublicKey([FromServices] IOptionsMonitor<IRCEncreptOption> _IRCEncreptOption)
|
||||||
|
{
|
||||||
|
//var pemPublicKey = Encoding.UTF8.GetString(Convert.FromBase64String(_IRCEncreptOption.CurrentValue.Base64RSAPublicKey));
|
||||||
|
|
||||||
|
return ResponseOutput.Ok(_IRCEncreptOption.CurrentValue.Base64RSAPublicKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
[HttpGet, Route("imageShare/ShareImage")]
|
[HttpGet, Route("imageShare/ShareImage")]
|
||||||
@@ -297,100 +321,14 @@ namespace IRaCIS.Api.Controllers
|
|||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet("user/GetObjectStoreToken")]
|
[HttpGet("user/GetObjectStoreToken")]
|
||||||
public async Task<IResponseOutput> GetObjectStoreTokenAsync([FromServices] IOptionsMonitor<ObjectStoreServiceOptions> options)
|
public async Task<IResponseOutput> GetObjectStoreTokenAsync([FromServices] IOptionsMonitor<ObjectStoreServiceOptions> options, [FromServices] IOSSService _oSSService)
|
||||||
{
|
|
||||||
var serviceOption = options.CurrentValue;
|
|
||||||
|
|
||||||
if (Enum.TryParse<ObjectStoreUse>(serviceOption.ObjectStoreUse, out var parsedEnum) && parsedEnum == ObjectStoreUse.AliyunOSS)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
var ossOptions = serviceOption.AliyunOSS;
|
var result = _oSSService.GetObjectStoreTempToken();
|
||||||
|
|
||||||
var client = new Client(new AlibabaCloud.OpenApiClient.Models.Config()
|
//result.AWS = await GetAWSTemToken(options.CurrentValue);
|
||||||
{
|
|
||||||
AccessKeyId = ossOptions.AccessKeyId,
|
|
||||||
AccessKeySecret = ossOptions.AccessKeySecret,
|
|
||||||
//AccessKeyId = "LTAI5tJV76pYX5yPg1N9QVE8",
|
|
||||||
//AccessKeySecret = "roRNLa9YG1of4pYruJGCNKBXEWTAWa",
|
|
||||||
|
|
||||||
Endpoint = "sts.cn-hangzhou.aliyuncs.com"
|
return ResponseOutput.Ok(result);
|
||||||
});
|
|
||||||
|
|
||||||
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 = credentials.Expiration,
|
|
||||||
SecurityToken = credentials.SecurityToken,
|
|
||||||
|
|
||||||
|
|
||||||
Region = ossOptions.Region,
|
|
||||||
BucketName = ossOptions.BucketName,
|
|
||||||
EndPoint = ossOptions.EndPoint,
|
|
||||||
ViewEndpoint = ossOptions.ViewEndpoint,
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
var awstempToken = await GetAWSTemToken(serviceOption);
|
|
||||||
|
|
||||||
return ResponseOutput.Ok(new ObjectStoreDTO() { ObjectStoreUse = serviceOption.ObjectStoreUse, AliyunOSS = tempToken,AWS= awstempToken });
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
else if (Enum.TryParse<ObjectStoreUse>(serviceOption.ObjectStoreUse, out var parsedValue) && parsedValue == ObjectStoreUse.MinIO)
|
|
||||||
{
|
|
||||||
return ResponseOutput.Ok(new ObjectStoreDTO() { ObjectStoreUse = serviceOption.ObjectStoreUse, MinIO = serviceOption.MinIO});
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var awsOptions = serviceOption.AWS;
|
|
||||||
|
|
||||||
//aws 临时凭证
|
|
||||||
// 创建 STS 客户端
|
|
||||||
var stsClient = new AmazonSecurityTokenServiceClient(awsOptions.AccessKeyId, awsOptions.SecretAccessKey);
|
|
||||||
|
|
||||||
// 使用 AssumeRole 请求临时凭证
|
|
||||||
var assumeRoleRequest = new AssumeRoleRequest
|
|
||||||
{
|
|
||||||
|
|
||||||
RoleArn = awsOptions.RoleArn, // 角色 ARN
|
|
||||||
RoleSessionName = $"session-name-{NewId.NextGuid()}",
|
|
||||||
DurationSeconds = awsOptions.DurationSeconds // 临时凭证有效期
|
|
||||||
};
|
|
||||||
|
|
||||||
var assumeRoleResponse = await stsClient.AssumeRoleAsync(assumeRoleRequest);
|
|
||||||
|
|
||||||
var credentials = assumeRoleResponse.Credentials;
|
|
||||||
|
|
||||||
var tempToken = new AWSTempToken()
|
|
||||||
{
|
|
||||||
AccessKeyId = credentials.AccessKeyId,
|
|
||||||
SecretAccessKey = credentials.SecretAccessKey,
|
|
||||||
SessionToken= credentials.SessionToken,
|
|
||||||
Expiration=credentials.Expiration,
|
|
||||||
Region=awsOptions.Region,
|
|
||||||
|
|
||||||
BucketName = awsOptions.BucketName,
|
|
||||||
EndPoint = awsOptions.EndPoint,
|
|
||||||
ViewEndpoint = awsOptions.ViewEndpoint,
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return ResponseOutput.Ok(new ObjectStoreDTO() { ObjectStoreUse = serviceOption.ObjectStoreUse, MinIO = serviceOption.MinIO, AWS = tempToken });
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ using IRaCIS.Core.Application.Filter;
|
|||||||
using IRaCIS.Core.Infrastructure.Extention;
|
using IRaCIS.Core.Infrastructure.Extention;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using IRaCIS.Application.Services;
|
using IRaCIS.Core.Application.Service;
|
||||||
using IRaCIS.Core.Application.Service.Inspection.DTO;
|
using IRaCIS.Core.Application.Service.Inspection.DTO;
|
||||||
using IRaCIS.Core.Infra.EFCore;
|
using IRaCIS.Core.Infra.EFCore;
|
||||||
using IRaCIS.Core.Domain.Models;
|
using IRaCIS.Core.Domain.Models;
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ using Newtonsoft.Json;
|
|||||||
using SharpCompress.Archives;
|
using SharpCompress.Archives;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.Data;
|
using System.Data;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
@@ -237,33 +238,7 @@ namespace IRaCIS.Core.API.Controllers
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
[HttpPost, Route("Study/PreArchiveStudy")]
|
|
||||||
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
|
|
||||||
public async Task<IResponseOutput> PreArchiveStudy(PreArchiveStudyCommand preArchiveStudyCommand,
|
|
||||||
[FromServices] IStudyService _studyService,
|
|
||||||
[FromServices] IRepository<StudyMonitor> _studyMonitorRepository)
|
|
||||||
{
|
|
||||||
|
|
||||||
var savedInfo = _studyService.GetSaveToDicomInfo(preArchiveStudyCommand.SubjectVisitId);
|
|
||||||
|
|
||||||
var studyMonitor = new StudyMonitor()
|
|
||||||
{
|
|
||||||
TrialId = savedInfo.TrialId,
|
|
||||||
SubjectId = savedInfo.SubjectId,
|
|
||||||
SubjectVisitId = savedInfo.SubjectVisitId,
|
|
||||||
|
|
||||||
IsSuccess = false,
|
|
||||||
UploadStartTime = DateTime.Now,
|
|
||||||
IsDicom = preArchiveStudyCommand.IsDicom,
|
|
||||||
IP = _userInfo.IP
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
var addEntity = await _studyMonitorRepository.AddAsync(studyMonitor, true);
|
|
||||||
|
|
||||||
return ResponseOutput.Ok(addEntity.Id);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>Dicom 归档</summary>
|
/// <summary>Dicom 归档</summary>
|
||||||
@@ -271,7 +246,7 @@ namespace IRaCIS.Core.API.Controllers
|
|||||||
[DisableFormValueModelBinding]
|
[DisableFormValueModelBinding]
|
||||||
[DisableRequestSizeLimit]
|
[DisableRequestSizeLimit]
|
||||||
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
|
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
|
||||||
public async Task<IResponseOutput> ArchiveStudyNew( Guid trialId, Guid subjectVisitId, string studyInstanceUid, Guid? abandonStudyId, Guid studyMonitorId,
|
public async Task<IResponseOutput> ArchiveStudyNew(Guid trialId, Guid subjectVisitId, string studyInstanceUid, Guid? abandonStudyId, Guid studyMonitorId,
|
||||||
[FromServices] ILogger<UploadDownLoadController> _logger,
|
[FromServices] ILogger<UploadDownLoadController> _logger,
|
||||||
[FromServices] IStudyService _studyService,
|
[FromServices] IStudyService _studyService,
|
||||||
[FromServices] IHubContext<UploadHub, IUploadClient> _uploadHub,
|
[FromServices] IHubContext<UploadHub, IUploadClient> _uploadHub,
|
||||||
@@ -419,12 +394,26 @@ namespace IRaCIS.Core.API.Controllers
|
|||||||
|
|
||||||
public class UploadNoneDicomFileCommand
|
public class UploadNoneDicomFileCommand
|
||||||
{
|
{
|
||||||
public Guid TrialId { get; set; }
|
[NotDefault]
|
||||||
public Guid SubjectVisitId { get; set; }
|
public Guid SubjectVisitId { get; set; }
|
||||||
public Guid NoneDicomStudyId { get; set; }
|
|
||||||
|
|
||||||
|
[NotDefault]
|
||||||
public Guid StudyMonitorId { get; set; }
|
public Guid StudyMonitorId { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
public Guid? NoneDicomStudyId { get; set; }
|
||||||
|
|
||||||
|
//IR 上传的时候跟任务绑定
|
||||||
|
public Guid? VisitTaskId { get; set; }
|
||||||
|
|
||||||
|
public string RecordPath { get; set; }
|
||||||
|
|
||||||
|
public int FailedFileCount { get; set; }
|
||||||
|
|
||||||
|
public long FileSize { get; set; }
|
||||||
|
|
||||||
|
|
||||||
public List<OSSFileDTO> UploadedFileList { get; set; } = new List<OSSFileDTO>();
|
public List<OSSFileDTO> UploadedFileList { get; set; } = new List<OSSFileDTO>();
|
||||||
|
|
||||||
|
|
||||||
@@ -438,6 +427,41 @@ namespace IRaCIS.Core.API.Controllers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 非dicom 上传预上传接口
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="preArchiveStudyCommand"></param>
|
||||||
|
/// <param name="_studyService"></param>
|
||||||
|
/// <param name="_studyMonitorRepository"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost, Route("Study/PreArchiveStudy")]
|
||||||
|
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
|
||||||
|
public async Task<IResponseOutput> PreArchiveStudy(PreArchiveStudyCommand preArchiveStudyCommand,
|
||||||
|
[FromServices] IStudyService _studyService,
|
||||||
|
[FromServices] IRepository<StudyMonitor> _studyMonitorRepository)
|
||||||
|
{
|
||||||
|
|
||||||
|
var savedInfo = _studyService.GetSaveToDicomInfo(preArchiveStudyCommand.SubjectVisitId);
|
||||||
|
|
||||||
|
var studyMonitor = new StudyMonitor()
|
||||||
|
{
|
||||||
|
TrialId = savedInfo.TrialId,
|
||||||
|
SubjectId = savedInfo.SubjectId,
|
||||||
|
SubjectVisitId = savedInfo.SubjectVisitId,
|
||||||
|
|
||||||
|
IsSuccess = false,
|
||||||
|
UploadStartTime = DateTime.Now,
|
||||||
|
FileCount=preArchiveStudyCommand.FileCount,
|
||||||
|
IsDicom = preArchiveStudyCommand.IsDicom,
|
||||||
|
IP = _userInfo.IP
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
var addEntity = await _studyMonitorRepository.AddAsync(studyMonitor, true);
|
||||||
|
|
||||||
|
return ResponseOutput.Ok(addEntity.Id);
|
||||||
|
|
||||||
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 上传非Dicom 文件 支持压缩包 多文件上传
|
/// 上传非Dicom 文件 支持压缩包 多文件上传
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -470,24 +494,37 @@ namespace IRaCIS.Core.API.Controllers
|
|||||||
|
|
||||||
foreach (var item in incommand.UploadedFileList)
|
foreach (var item in incommand.UploadedFileList)
|
||||||
{
|
{
|
||||||
await _noneDicomStudyFileRepository.AddAsync(new NoneDicomStudyFile() { FileName = item.FileName, Path = item.FilePath, NoneDicomStudyId = noneDicomStudyId,FileType=item.FileType,FileSize=item.FileFize });
|
//如果是跟任务绑,那么NoneDicomStudyId 设置为空,不影响之前的检查,同时设置 OriginNoneDicomStudyId 保证关系
|
||||||
|
|
||||||
|
if (incommand.VisitTaskId != null && incommand.VisitTaskId != Guid.Empty)
|
||||||
|
{
|
||||||
|
await _noneDicomStudyFileRepository.AddAsync(new NoneDicomStudyFile() { FileName = item.FileName, Path = item.FilePath, OriginNoneDicomStudyId = noneDicomStudyId.Value, VisitTaskId = incommand.VisitTaskId, FileType = item.FileType, FileSize = item.FileFize });
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await _noneDicomStudyFileRepository.AddAsync(new NoneDicomStudyFile() { FileName = item.FileName, Path = item.FilePath, NoneDicomStudyId = noneDicomStudyId.Value, FileType = item.FileType, FileSize = item.FileFize });
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
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));
|
||||||
|
|
||||||
noneDicomStudy.FileCount = noneDicomStudy.FileCount + incommand.UploadedFileList.Count;
|
noneDicomStudy.FileCount = noneDicomStudy.FileCount + (incommand.VisitTaskId != null ? 0 : incommand.UploadedFileList.Count);
|
||||||
|
|
||||||
studyMonitor.FileCount = incommand.UploadedFileList.Count;
|
studyMonitor.RecordPath = incommand.RecordPath;
|
||||||
|
studyMonitor.FailedFileCount = incommand.FailedFileCount;
|
||||||
|
studyMonitor.IsSuccess = incommand.FailedFileCount == 0;
|
||||||
studyMonitor.FileSize = incommand.UploadedFileList.Sum(t => t.FileFize);
|
studyMonitor.FileSize = incommand.UploadedFileList.Sum(t => t.FileFize);
|
||||||
studyMonitor.IsDicom = false;
|
studyMonitor.IsDicom = false;
|
||||||
studyMonitor.IsDicomReUpload = false;
|
studyMonitor.IsDicomReUpload = false;
|
||||||
studyMonitor.StudyId = noneDicomStudyId;
|
studyMonitor.StudyId = noneDicomStudyId.Value;
|
||||||
studyMonitor.StudyCode = noneDicomStudy.StudyCode;
|
studyMonitor.StudyCode = noneDicomStudy.StudyCode;
|
||||||
studyMonitor.ArchiveFinishedTime = DateTime.Now;
|
studyMonitor.ArchiveFinishedTime = DateTime.Now;
|
||||||
studyMonitor.IP = _userInfo.IP;
|
studyMonitor.IP = _userInfo.IP;
|
||||||
studyMonitor.IsSuccess = true;
|
|
||||||
|
|
||||||
await _noneDicomStudyRepository.SaveChangesAsync();
|
await _noneDicomStudyRepository.SaveChangesAsync();
|
||||||
|
|
||||||
@@ -955,7 +992,7 @@ namespace IRaCIS.Core.API.Controllers
|
|||||||
}
|
}
|
||||||
//处理好 用户类型 和用户类型枚举
|
//处理好 用户类型 和用户类型枚举
|
||||||
var sysUserTypeList = _usertypeRepository.Where(t => t.UserTypeEnum == UserTypeEnum.CRA || t.UserTypeEnum == UserTypeEnum.ClinicalResearchCoordinator).Select(t => new { UserTypeId = t.Id, t.UserTypeEnum }).ToList();
|
var sysUserTypeList = _usertypeRepository.Where(t => t.UserTypeEnum == UserTypeEnum.CRA || t.UserTypeEnum == UserTypeEnum.ClinicalResearchCoordinator).Select(t => new { UserTypeId = t.Id, t.UserTypeEnum }).ToList();
|
||||||
var siteList = _trialSiteRepository.Where(t => t.TrialId == trialId && siteCodeList.Contains(t.TrialSiteCode)).Select(t => new { t.TrialSiteCode, TrialSiteId= t.Id }).ToList();
|
var siteList = _trialSiteRepository.Where(t => t.TrialId == trialId && siteCodeList.Contains(t.TrialSiteCode)).Select(t => new { t.TrialSiteCode, TrialSiteId = t.Id }).ToList();
|
||||||
|
|
||||||
foreach (var item in excelList)
|
foreach (var item in excelList)
|
||||||
{
|
{
|
||||||
@@ -979,9 +1016,9 @@ namespace IRaCIS.Core.API.Controllers
|
|||||||
item.TrialSiteId = siteList.FirstOrDefault(t => t.TrialSiteCode.ToUpper() == item.TrialSiteCode.ToUpper()).TrialSiteId;
|
item.TrialSiteId = siteList.FirstOrDefault(t => t.TrialSiteCode.ToUpper() == item.TrialSiteCode.ToUpper()).TrialSiteId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var list = excelList.Where(t => t.UserTypeEnum == UserTypeEnum.ClinicalResearchCoordinator || t.UserTypeEnum == UserTypeEnum.CRA).ToList();
|
||||||
|
|
||||||
|
await _trialSiteSurveyService.ImportGenerateAccountAndJoinTrialAsync(trialId, baseUrl, routeUrl, list);
|
||||||
await _trialSiteSurveyService.ImportGenerateAccountAndJoinTrialAsync(trialId, baseUrl, routeUrl, excelList.ToList());
|
|
||||||
|
|
||||||
return ResponseOutput.Ok();
|
return ResponseOutput.Ok();
|
||||||
|
|
||||||
|
|||||||
@@ -1,107 +0,0 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
|
||||||
<SignAssembly>false</SignAssembly>
|
|
||||||
<UserSecretsId>354572d4-9e15-4099-807c-63a2d29ff9f2</UserSecretsId>
|
|
||||||
<LangVersion>default</LangVersion>
|
|
||||||
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
|
||||||
<DocumentationFile>.\IRaCIS.Core.API.xml</DocumentationFile>
|
|
||||||
<NoWarn>1701;1702;1591;</NoWarn>
|
|
||||||
<OutputPath>..\bin\</OutputPath>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
|
||||||
<DocumentationFile>bin\Release\IRaCIS.Core.API.xml</DocumentationFile>
|
|
||||||
<OutputPath>bin\Release\</OutputPath>
|
|
||||||
<NoWarn>1701;1702;1591</NoWarn>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<Compile Remove="Controllers\ReviewerApi\**" />
|
|
||||||
<Compile Remove="UploadFile\**" />
|
|
||||||
<Content Remove="Controllers\ReviewerApi\**" />
|
|
||||||
<Content Remove="UploadFile\**" />
|
|
||||||
<EmbeddedResource Remove="Controllers\ReviewerApi\**" />
|
|
||||||
<EmbeddedResource Remove="UploadFile\**" />
|
|
||||||
<None Remove="Controllers\ReviewerApi\**" />
|
|
||||||
<None Remove="UploadFile\**" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<Content Remove="web.config" />
|
|
||||||
<Content Remove="wwwroot\swagger\ui\abp.js" />
|
|
||||||
<Content Remove="wwwroot\swagger\ui\abp.swagger.js" />
|
|
||||||
<Content Remove="wwwroot\swagger\ui\Index.html" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<None Remove=".preview.jpg" />
|
|
||||||
<None Remove="GrpcToken.proto" />
|
|
||||||
<None Remove="IRaCIS.Core.API.xml" />
|
|
||||||
<None Remove="Protos\GrpcToken.proto" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<ApplicationDefinition Include="GrpcToken.proto" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<EmbeddedResource Include="wwwroot\swagger\ui\abp.js" />
|
|
||||||
<EmbeddedResource Include="wwwroot\swagger\ui\abp.swagger.js" />
|
|
||||||
<EmbeddedResource Include="wwwroot\swagger\ui\Index.html" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<Protobuf Include="Protos\GrpcToken.proto">
|
|
||||||
<GrpcServices>Client</GrpcServices>
|
|
||||||
</Protobuf>
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="AspNetCoreRateLimit" Version="4.0.1" />
|
|
||||||
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="7.2.0" />
|
|
||||||
<PackageReference Include="EasyCaching.InMemory" Version="1.4.1" />
|
|
||||||
<PackageReference Include="EasyCaching.Interceptor.Castle" Version="1.4.1" />
|
|
||||||
<PackageReference Include="Google.Protobuf" Version="3.19.1" />
|
|
||||||
<PackageReference Include="Grpc.Net.Client" Version="2.41.0" />
|
|
||||||
<PackageReference Include="Grpc.Tools" Version="2.42.0">
|
|
||||||
<PrivateAssets>all</PrivateAssets>
|
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
|
||||||
</PackageReference>
|
|
||||||
<PackageReference Include="Hangfire.Tags.SqlServer" Version="1.8.0" />
|
|
||||||
<PackageReference Include="Invio.Extensions.Authentication.JwtBearer" Version="2.0.1" />
|
|
||||||
<PackageReference Include="LogDashboard" Version="1.4.8" />
|
|
||||||
<PackageReference Include="MediatR.Extensions.Microsoft.DependencyInjection" Version="9.0.0" />
|
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="6.0.1" />
|
|
||||||
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="6.0.0" />
|
|
||||||
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.14.0" />
|
|
||||||
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="6.0.1" />
|
|
||||||
<PackageReference Include="Serilog.AspNetCore" Version="4.1.0" />
|
|
||||||
<PackageReference Include="Serilog.Enrichers.ClientInfo" Version="1.1.4" />
|
|
||||||
<PackageReference Include="Serilog.Sinks.Email" Version="2.4.0" />
|
|
||||||
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="..\IRaCIS.Core.Application\IRaCIS.Core.Application.csproj" />
|
|
||||||
<ProjectReference Include="..\IRaCIS.Core.Infra.EFCore\IRaCIS.Core.Infra.EFCore.csproj" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<Folder Include="Properties\PublishProfiles\" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<Content Update="NLog.config">
|
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ProjectExtensions><VisualStudio><UserProperties anonymizetagsetting_1json__JsonSchema="http://json.schemastore.org/jovo-language-model" /></VisualStudio></ProjectExtensions>
|
|
||||||
|
|
||||||
|
|
||||||
</Project>
|
|
||||||
@@ -43,7 +43,7 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ApplicationDefinition Include="GrpcToken.proto" />
|
<ApplicationDefinition Include="GrpcToken.proto" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<EmbeddedResource Include="wwwroot\swagger\ui\abp.js">
|
<EmbeddedResource Include="wwwroot\swagger\ui\abp.js">
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
@@ -61,10 +61,13 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="AlibabaCloud.SDK.Sts20150401" Version="1.1.4" />
|
|
||||||
<PackageReference Include="AspNetCoreRateLimit" Version="5.0.0" />
|
<PackageReference Include="AspNetCoreRateLimit" Version="5.0.0" />
|
||||||
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="10.0.0" />
|
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="10.0.0" />
|
||||||
<PackageReference Include="AWSSDK.SecurityToken" Version="3.7.400.13" />
|
|
||||||
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.8">
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
</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.14" />
|
||||||
<PackageReference Include="Hangfire.Dashboard.BasicAuthorization" Version="1.0.2" />
|
<PackageReference Include="Hangfire.Dashboard.BasicAuthorization" Version="1.0.2" />
|
||||||
@@ -89,68 +92,21 @@
|
|||||||
<None Include="..\.editorconfig" Link=".editorconfig" />
|
<None Include="..\.editorconfig" Link=".editorconfig" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<Content Update="wwwroot\EmailTemplate\AdminAddUser_US.html">
|
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Update="wwwroot\EmailTemplate\AdminResetUser_US.html">
|
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Update="wwwroot\EmailTemplate\AdminResetUser.html">
|
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Update="wwwroot\EmailTemplate\SubjectEnrollConfirmOrPDProgress_US.html">
|
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Update="wwwroot\EmailTemplate\TrialDoctorExistJoin_US.html">
|
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Update="wwwroot\EmailTemplate\TrialDoctorFirstJoin.html">
|
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Update="wwwroot\EmailTemplate\TrialSiteSurveyReject.html">
|
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Update="wwwroot\EmailTemplate\TrialSiteSurveyReject_US.html">
|
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Update="wwwroot\EmailTemplate\TrialDoctorExistJoin.html">
|
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Update="wwwroot\EmailTemplate\TrialUserExistJoin_US.html">
|
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Update="wwwroot\EmailTemplate\TrialUserExistJoin.html">
|
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Update="wwwroot\EmailTemplate\AdminAddUser.html">
|
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Update="wwwroot\EmailTemplate\TrialDoctorFirstJoin_US.html">
|
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Update="wwwroot\EmailTemplate\SubjectEnrollConfirmOrPDProgress.html">
|
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Update="wwwroot\EmailTemplate\TrialUserFirstJoin_US.html">
|
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Update="wwwroot\EmailTemplate\UserOptCommon_US.html">
|
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Update="wwwroot\EmailTemplate\UserOptCommon.html">
|
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Update="wwwroot\EmailTemplate\TrialUserFirstJoin.html">
|
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Folder Include="Properties\PublishProfiles\" />
|
<Folder Include="Properties\PublishProfiles\" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ProjectExtensions><VisualStudio><UserProperties properties_4launchsettings_1json__JsonSchema="" /></VisualStudio></ProjectExtensions>
|
<ItemGroup>
|
||||||
|
<Content Update="appsettings.json">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ProjectExtensions>
|
||||||
|
<VisualStudio>
|
||||||
|
<UserProperties properties_4launchsettings_1json__JsonSchema="" />
|
||||||
|
</VisualStudio>
|
||||||
|
</ProjectExtensions>
|
||||||
|
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -29,7 +29,7 @@
|
|||||||
<param name="doctorId"></param>
|
<param name="doctorId"></param>
|
||||||
<returns></returns>
|
<returns></returns>
|
||||||
</member>
|
</member>
|
||||||
<member name="M:IRaCIS.Api.Controllers.ExtraController.Login(IRaCIS.Application.Contracts.UserLoginDTO,ZiggyCreatures.Caching.Fusion.IFusionCache,IRaCIS.Application.Services.IUserService,IRaCIS.Core.Application.Auth.ITokenService,IRaCIS.Core.Application.Contracts.IReadingImageTaskService,Microsoft.Extensions.Options.IOptionsMonitor{IRaCIS.Core.Domain.Share.ServiceVerifyConfigOption},IRaCIS.Application.Services.IMailVerificationService)">
|
<member name="M:IRaCIS.Api.Controllers.ExtraController.Login(IRaCIS.Application.Contracts.UserLoginDTO,ZiggyCreatures.Caching.Fusion.IFusionCache,IRaCIS.Core.Application.Service.IUserService,IRaCIS.Core.Application.Auth.ITokenService,IRaCIS.Core.Application.Contracts.IReadingImageTaskService,Microsoft.Extensions.Options.IOptionsMonitor{IRaCIS.Core.Domain.Share.ServiceVerifyConfigOption},Microsoft.Extensions.Options.IOptionsMonitor{IRaCIS.Core.Domain.Share.SystemEmailSendConfig},IRaCIS.Core.Application.Service.IMailVerificationService)">
|
||||||
<summary> 系统用户登录接口[New] </summary>
|
<summary> 系统用户登录接口[New] </summary>
|
||||||
</member>
|
</member>
|
||||||
<member name="M:IRaCIS.Core.API.Controllers.Special.FinancialChangeController.AddOrUpdateTrialInspection(IRaCIS.Core.Application.Service.Inspection.DTO.DataInspectionDto{IRaCIS.Application.Contracts.TrialCommand})">
|
<member name="M:IRaCIS.Core.API.Controllers.Special.FinancialChangeController.AddOrUpdateTrialInspection(IRaCIS.Core.Application.Service.Inspection.DTO.DataInspectionDto{IRaCIS.Application.Contracts.TrialCommand})">
|
||||||
@@ -41,7 +41,7 @@
|
|||||||
<param name="param"></param>
|
<param name="param"></param>
|
||||||
<returns>新记录Id</returns>
|
<returns>新记录Id</returns>
|
||||||
</member>
|
</member>
|
||||||
<member name="M:IRaCIS.Core.API.Controllers.Special.FinancialChangeController.WorkLoadAddOrUpdate(IRaCIS.Application.Services.IDoctorWorkloadService,IRaCIS.Application.Contracts.WorkloadCommand)">
|
<member name="M:IRaCIS.Core.API.Controllers.Special.FinancialChangeController.WorkLoadAddOrUpdate(IRaCIS.Core.Application.Service.IDoctorWorkloadService,IRaCIS.Application.Contracts.WorkloadCommand)">
|
||||||
<summary>
|
<summary>
|
||||||
添加或更新工作量[AUTH]
|
添加或更新工作量[AUTH]
|
||||||
</summary>
|
</summary>
|
||||||
@@ -281,6 +281,15 @@
|
|||||||
<member name="M:IRaCIS.Core.API.Controllers.StudyController.ArchiveStudyNew(System.Guid,System.Guid,System.String,System.Nullable{System.Guid},System.Guid,Microsoft.Extensions.Logging.ILogger{IRaCIS.Core.API.Controllers.UploadDownLoadController},IRaCIS.Core.Application.Contracts.IStudyService,Microsoft.AspNetCore.SignalR.IHubContext{IRaCIS.Core.API.UploadHub,IRaCIS.Core.API.IUploadClient},IRaCIS.Core.Application.Contracts.Dicom.IDicomArchiveService,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.StudyMonitor})">
|
<member name="M:IRaCIS.Core.API.Controllers.StudyController.ArchiveStudyNew(System.Guid,System.Guid,System.String,System.Nullable{System.Guid},System.Guid,Microsoft.Extensions.Logging.ILogger{IRaCIS.Core.API.Controllers.UploadDownLoadController},IRaCIS.Core.Application.Contracts.IStudyService,Microsoft.AspNetCore.SignalR.IHubContext{IRaCIS.Core.API.UploadHub,IRaCIS.Core.API.IUploadClient},IRaCIS.Core.Application.Contracts.Dicom.IDicomArchiveService,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.StudyMonitor})">
|
||||||
<summary>Dicom 归档</summary>
|
<summary>Dicom 归档</summary>
|
||||||
</member>
|
</member>
|
||||||
|
<member name="M:IRaCIS.Core.API.Controllers.StudyController.PreArchiveStudy(IRaCIS.Core.Application.Contracts.PreArchiveStudyCommand,IRaCIS.Core.Application.Contracts.IStudyService,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.StudyMonitor})">
|
||||||
|
<summary>
|
||||||
|
非dicom 上传预上传接口
|
||||||
|
</summary>
|
||||||
|
<param name="preArchiveStudyCommand"></param>
|
||||||
|
<param name="_studyService"></param>
|
||||||
|
<param name="_studyMonitorRepository"></param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
<member name="M:IRaCIS.Core.API.Controllers.StudyController.UploadNoneDicomFile(IRaCIS.Core.API.Controllers.StudyController.UploadNoneDicomFileCommand,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.NoneDicomStudy},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.StudyMonitor},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.NoneDicomStudyFile})">
|
<member name="M:IRaCIS.Core.API.Controllers.StudyController.UploadNoneDicomFile(IRaCIS.Core.API.Controllers.StudyController.UploadNoneDicomFileCommand,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.NoneDicomStudy},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.StudyMonitor},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.NoneDicomStudyFile})">
|
||||||
<summary>
|
<summary>
|
||||||
上传非Dicom 文件 支持压缩包 多文件上传
|
上传非Dicom 文件 支持压缩包 多文件上传
|
||||||
@@ -366,11 +375,6 @@
|
|||||||
<param name="memberSerialization">序列化成员</param>
|
<param name="memberSerialization">序列化成员</param>
|
||||||
<returns></returns>
|
<returns></returns>
|
||||||
</member>
|
</member>
|
||||||
<member name="T:TimeZoneAdjustmentMiddleware">
|
|
||||||
<summary>
|
|
||||||
废弃,没用
|
|
||||||
</summary>
|
|
||||||
</member>
|
|
||||||
<member name="T:ZhaoXi._001.NET5Demo.Practice.WebApi.Utility.Jwt.CustomHSJWTService">
|
<member name="T:ZhaoXi._001.NET5Demo.Practice.WebApi.Utility.Jwt.CustomHSJWTService">
|
||||||
<summary>
|
<summary>
|
||||||
对称可逆加密
|
对称可逆加密
|
||||||
|
|||||||
@@ -1,118 +0,0 @@
|
|||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
using Microsoft.Extensions.Primitives;
|
|
||||||
using Newtonsoft.Json;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 废弃,没用
|
|
||||||
/// </summary>
|
|
||||||
public class TimeZoneAdjustmentMiddleware
|
|
||||||
{
|
|
||||||
private readonly RequestDelegate _next;
|
|
||||||
|
|
||||||
public TimeZoneAdjustmentMiddleware(RequestDelegate next)
|
|
||||||
{
|
|
||||||
_next = next;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task Invoke(HttpContext context)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrEmpty(context.Request.ContentType))
|
|
||||||
{
|
|
||||||
// 请求没有内容体,可能是一个没有请求体的请求,比如 GET 请求
|
|
||||||
await _next(context);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
var timeZoneId = "Asia/Shanghai"; // 客户端默认时区
|
|
||||||
|
|
||||||
var timeZoneIdHeaderValue = context.Request.Headers["TimeZoneId"];
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(timeZoneIdHeaderValue))
|
|
||||||
{
|
|
||||||
timeZoneId = timeZoneIdHeaderValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
var timeZone = TimeZoneInfo.FindSystemTimeZoneById(timeZoneId);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// 处理 JSON 请求体中的时间字段
|
|
||||||
if (context.Request.ContentType.StartsWith("application/json"))
|
|
||||||
{
|
|
||||||
var requestBody = await new StreamReader(context.Request.Body).ReadToEndAsync();
|
|
||||||
|
|
||||||
// 使用 JSON.NET 或 System.Text.Json 解析 JSON 请求体
|
|
||||||
// 假设请求体中有一个名为 "dateTime" 的时间字段
|
|
||||||
dynamic jsonData = JsonConvert.DeserializeObject(requestBody);
|
|
||||||
|
|
||||||
if (jsonData.dateTime != null)
|
|
||||||
{
|
|
||||||
if (DateTime.TryParse((string)jsonData.dateTime, out DateTime dateTime))
|
|
||||||
{
|
|
||||||
// 将 JSON 请求体中的时间字段转换为服务器时区的时间
|
|
||||||
var serverTime = TimeZoneInfo.ConvertTime(dateTime, timeZone);
|
|
||||||
jsonData.dateTime = serverTime;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 将修改后的 JSON 请求体重新写入请求流中
|
|
||||||
var jsonBytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(jsonData));
|
|
||||||
context.Request.Body = new MemoryStream(jsonBytes);
|
|
||||||
context.Request.ContentLength = jsonBytes.Length;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// 处理 URL 表单参数
|
|
||||||
var modifiedQuery = new Dictionary<string, StringValues>();
|
|
||||||
|
|
||||||
foreach (var key in context.Request.Query.Keys)
|
|
||||||
{
|
|
||||||
if (DateTime.TryParse(context.Request.Query[key], out DateTime dateTime))
|
|
||||||
{
|
|
||||||
// 将 URL 表单参数中的时间转换为服务器时区的时间
|
|
||||||
var serverTime = TimeZoneInfo.ConvertTime(dateTime, timeZone);
|
|
||||||
modifiedQuery[key] = new StringValues(serverTime.ToString());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
modifiedQuery[key] = context.Request.Query[key];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
context.Request.Query = new QueryCollection(modifiedQuery);
|
|
||||||
|
|
||||||
// 处理Form请求体中的参数
|
|
||||||
if (context.Request.HasFormContentType)
|
|
||||||
{
|
|
||||||
var modifiedForm = new Dictionary<string, StringValues>();
|
|
||||||
|
|
||||||
foreach (var key in context.Request.Form.Keys)
|
|
||||||
{
|
|
||||||
if (DateTime.TryParse(context.Request.Form[key], out DateTime dateTime))
|
|
||||||
{
|
|
||||||
// 将请求体中的时间转换为服务器时区的时间
|
|
||||||
var serverTime = TimeZoneInfo.ConvertTime(dateTime, timeZone);
|
|
||||||
modifiedForm[key] = new StringValues(serverTime.ToString());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
modifiedForm[key] = context.Request.Form[key];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var newFormCollection = new FormCollection(modifiedForm);
|
|
||||||
|
|
||||||
// 将新的表单集合设置回请求对象
|
|
||||||
context.Request.Form = newFormCollection;
|
|
||||||
}
|
|
||||||
|
|
||||||
await _next(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -20,7 +20,7 @@ using Microsoft.AspNetCore.SignalR;
|
|||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using IRaCIS.Core.Application.Filter;
|
using IRaCIS.Core.Application.Filter;
|
||||||
using Microsoft.AspNetCore.HttpOverrides;
|
using Microsoft.AspNetCore.HttpOverrides;
|
||||||
using IRaCIS.Application.Services.BackGroundJob;
|
using IRaCIS.Core.Application.Service.BackGroundJob;
|
||||||
using LogDashboard;
|
using LogDashboard;
|
||||||
using FellowOakDicom.Network;
|
using FellowOakDicom.Network;
|
||||||
using IRaCIS.Core.Application.Service.ImageAndDoc;
|
using IRaCIS.Core.Application.Service.ImageAndDoc;
|
||||||
@@ -33,6 +33,8 @@ using Newtonsoft.Json;
|
|||||||
using Microsoft.AspNetCore.Diagnostics;
|
using Microsoft.AspNetCore.Diagnostics;
|
||||||
using IRaCIS.Core.Application.MassTransit.Command;
|
using IRaCIS.Core.Application.MassTransit.Command;
|
||||||
using IRaCIS.Core.Application.MassTransit.Consumer;
|
using IRaCIS.Core.Application.MassTransit.Consumer;
|
||||||
|
using DocumentFormat.OpenXml.InkML;
|
||||||
|
using IRaCIS.Core.Domain;
|
||||||
|
|
||||||
AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true);
|
AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true);
|
||||||
AppContext.SetSwitch("Npgsql.DisableDateTimeInfinityConversions", true);
|
AppContext.SetSwitch("Npgsql.DisableDateTimeInfinityConversions", true);
|
||||||
@@ -110,7 +112,7 @@ builder.Services.AddControllers(options =>
|
|||||||
options.Filters.Add<ModelActionFilter>();
|
options.Filters.Add<ModelActionFilter>();
|
||||||
options.Filters.Add<ProjectExceptionFilter>();
|
options.Filters.Add<ProjectExceptionFilter>();
|
||||||
options.Filters.Add<UnitOfWorkFilter>();
|
options.Filters.Add<UnitOfWorkFilter>();
|
||||||
options.Filters.Add<EncreptApiResultFilter>(10);
|
//options.Filters.Add<EncreptApiResultFilter>(10);
|
||||||
options.Filters.Add<LimitUserRequestAuthorization>();
|
options.Filters.Add<LimitUserRequestAuthorization>();
|
||||||
|
|
||||||
|
|
||||||
@@ -121,16 +123,18 @@ builder.Services.AddOptions().Configure<SystemEmailSendConfig>(_configuration.Ge
|
|||||||
builder.Services.AddOptions().Configure<ServiceVerifyConfigOption>(_configuration.GetSection("BasicSystemConfig"));
|
builder.Services.AddOptions().Configure<ServiceVerifyConfigOption>(_configuration.GetSection("BasicSystemConfig"));
|
||||||
builder.Services.AddOptions().Configure<AliyunOSSOptions>(_configuration.GetSection("AliyunOSS"));
|
builder.Services.AddOptions().Configure<AliyunOSSOptions>(_configuration.GetSection("AliyunOSS"));
|
||||||
builder.Services.AddOptions().Configure<ObjectStoreServiceOptions>(_configuration.GetSection("ObjectStoreService"));
|
builder.Services.AddOptions().Configure<ObjectStoreServiceOptions>(_configuration.GetSection("ObjectStoreService"));
|
||||||
builder.Services.AddOptions().Configure<EncreptResponseOption>(_configuration.GetSection("EncrypteResponseConfig"));
|
builder.Services.AddOptions().Configure<IRCEncreptOption>(_configuration.GetSection("EncrypteResponseConfig"));
|
||||||
builder.Services.AddOptions().Configure<SystemPacsConfig>(_configuration.GetSection("SystemPacsConfig"));
|
builder.Services.AddOptions().Configure<SystemPacsConfig>(_configuration.GetSection("SystemPacsConfig"));
|
||||||
|
|
||||||
|
builder.Services.Configure<IRaCISBasicConfigOption>(_configuration.GetSection("IRaCISBasicConfig"));
|
||||||
|
|
||||||
|
|
||||||
//动态WebApi + UnifiedApiResultFilter 省掉控制器代码
|
//动态WebApi + UnifiedApiResultFilter 省掉控制器代码
|
||||||
builder.Services.AddDynamicWebApiSetup();
|
builder.Services.AddDynamicWebApiSetup();
|
||||||
//AutoMapper
|
//AutoMapper
|
||||||
builder.Services.AddAutoMapperSetup();
|
builder.Services.AddAutoMapperSetup();
|
||||||
//EF ORM QueryWithNoLock
|
//EF ORM QueryWithNoLock
|
||||||
builder.Services.AddEFSetup(_configuration,enviromentName);
|
builder.Services.AddEFSetup(_configuration, enviromentName);
|
||||||
//Http 响应压缩
|
//Http 响应压缩
|
||||||
builder.Services.AddResponseCompressionSetup();
|
builder.Services.AddResponseCompressionSetup();
|
||||||
//Swagger Api 文档
|
//Swagger Api 文档
|
||||||
@@ -143,15 +147,30 @@ builder.Services.AddJWTAuthSetup(_configuration);
|
|||||||
|
|
||||||
#region MassTransit
|
#region MassTransit
|
||||||
//masstransit组件 也支持MediatR 中介者模式,但是支持分布式,考虑后续,所以在次替代MediatR
|
//masstransit组件 也支持MediatR 中介者模式,但是支持分布式,考虑后续,所以在次替代MediatR
|
||||||
|
//参考链接:https://masstransit.io/documentation/concepts/mediator#scoped-mediator
|
||||||
builder.Services.AddMediator(cfg =>
|
builder.Services.AddMediator(cfg =>
|
||||||
{
|
{
|
||||||
cfg.AddConsumer<ConsistencyCheckConsumer>();
|
cfg.AddConsumer<ConsistencyCheckConsumer>();
|
||||||
|
cfg.AddConsumer<AddSubjectTriggerConsumer>();
|
||||||
|
cfg.AddConsumer<AddSubjectTriggerConsumer2>();
|
||||||
|
//cfg.ConfigureMediator((context, cfg) => cfg.UseHttpContextScopeFilter(context));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
//添加 MassTransit 和 InMemory 传输
|
||||||
builder.Services.AddMassTransit(cfg =>
|
builder.Services.AddMassTransit(cfg =>
|
||||||
{
|
{
|
||||||
cfg.UsingInMemory();
|
// 注册消费者
|
||||||
|
cfg.AddConsumer<AddSubjectTriggerConsumer>(); // 替换为你的消费者类
|
||||||
|
cfg.AddConsumer<AddSubjectTriggerConsumer2>();
|
||||||
|
|
||||||
|
// 使用 InMemory 作为消息传递机制
|
||||||
|
cfg.UsingInMemory((context, cfg) =>
|
||||||
|
{
|
||||||
|
// 这里可以进行额外的配置
|
||||||
|
cfg.ConfigureEndpoints(context); // 自动配置所有消费者的端点
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
@@ -193,6 +212,7 @@ builder.Services.AddSingleton<ISearcher>(new Searcher(CachePolicy.Content, Path.
|
|||||||
//builder.Services.AddExceptionHandler<GlobalExceptionHandler>();
|
//builder.Services.AddExceptionHandler<GlobalExceptionHandler>();
|
||||||
//builder.Services.AddProblemDetails();
|
//builder.Services.AddProblemDetails();
|
||||||
|
|
||||||
|
|
||||||
#region 历史废弃配置
|
#region 历史废弃配置
|
||||||
//builder.Services.AddMemoryCache();
|
//builder.Services.AddMemoryCache();
|
||||||
////上传限制 配置
|
////上传限制 配置
|
||||||
@@ -215,6 +235,7 @@ var env = app.Environment;
|
|||||||
|
|
||||||
#region 配置中间件
|
#region 配置中间件
|
||||||
|
|
||||||
|
app.UseMiddleware<EncryptionRequestMiddleware>();
|
||||||
|
|
||||||
// Configure the HTTP request pipeline.
|
// Configure the HTTP request pipeline.
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
using Hangfire;
|
using Hangfire;
|
||||||
using Hangfire.Dashboard;
|
using Hangfire.Dashboard;
|
||||||
using Hangfire.Dashboard.BasicAuthorization;
|
using Hangfire.Dashboard.BasicAuthorization;
|
||||||
using IRaCIS.Application.Services.BackGroundJob;
|
using IRaCIS.Core.Application.Service.BackGroundJob;
|
||||||
using IRaCIS.Core.API.Filter;
|
using IRaCIS.Core.API.Filter;
|
||||||
using IRaCIS.Core.Application.Helper;
|
using IRaCIS.Core.Application.Helper;
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ namespace IRaCIS.Core.API
|
|||||||
|
|
||||||
// 全局忽略 DomainEvents 属性
|
// 全局忽略 DomainEvents 属性
|
||||||
automapper.AddGlobalIgnore(nameof(Entity.DomainEvents));
|
automapper.AddGlobalIgnore(nameof(Entity.DomainEvents));
|
||||||
|
automapper.AddGlobalIgnore(nameof(Entity.DomainCommands));
|
||||||
|
|
||||||
#region 会使 IncludeMembers 失效 不能全局使用
|
#region 会使 IncludeMembers 失效 不能全局使用
|
||||||
//mapping an EntityFramework Core DbContext-object.
|
//mapping an EntityFramework Core DbContext-object.
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ using System.Linq;
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using IRaCIS.Core.Domain.Models;
|
using IRaCIS.Core.Domain.Models;
|
||||||
using IRaCIS.Core.Domain.Share;
|
using IRaCIS.Core.Domain.Share;
|
||||||
using IRaCIS.Application.Services;
|
using IRaCIS.Core.Application.Service;
|
||||||
using IRaCIS.Application.Interfaces;
|
using IRaCIS.Application.Interfaces;
|
||||||
using AutoMapper;
|
using AutoMapper;
|
||||||
|
|
||||||
|
|||||||
@@ -8,9 +8,11 @@ using Medallion.Threading;
|
|||||||
using Medallion.Threading.SqlServer;
|
using Medallion.Threading.SqlServer;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.EntityFrameworkCore.Diagnostics;
|
using Microsoft.EntityFrameworkCore.Diagnostics;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
using StackExchange.Redis;
|
using StackExchange.Redis;
|
||||||
|
|
||||||
namespace IRaCIS.Core.API
|
namespace IRaCIS.Core.API
|
||||||
@@ -46,10 +48,11 @@ namespace IRaCIS.Core.API
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
options.UseSqlServer(configuration.GetSection("ConnectionStrings:RemoteNew").Value, contextOptionsBuilder => contextOptionsBuilder.EnableRetryOnFailure());
|
options.UseSqlServer(configuration.GetSection("ConnectionStrings:RemoteNew").Value, contextOptionsBuilder => contextOptionsBuilder.EnableRetryOnFailure());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//迁移的时候,不生成外键
|
||||||
|
options.ReplaceService<IMigrationsSqlGenerator, NoForeignKeyMigrationsSqlGenerator>();
|
||||||
|
|
||||||
|
|
||||||
options.UseLoggerFactory(logFactory);
|
options.UseLoggerFactory(logFactory);
|
||||||
@@ -72,18 +75,15 @@ namespace IRaCIS.Core.API
|
|||||||
|
|
||||||
options.UseTriggers(triggerOptions =>
|
options.UseTriggers(triggerOptions =>
|
||||||
{
|
{
|
||||||
triggerOptions.AddTrigger<AddSubjectTrigger>();
|
triggerOptions.AddTrigger<SubjectTrigger>();
|
||||||
triggerOptions.AddTrigger<ChallengeStateTrigger>();
|
triggerOptions.AddTrigger<ChallengeStateTrigger>();
|
||||||
triggerOptions.AddTrigger<SubjectStateTrigger>();
|
|
||||||
triggerOptions.AddTrigger<AddCRCCliniaclDataTrigger>();
|
|
||||||
triggerOptions.AddTrigger<SubjectVisitCheckPassedTrigger>();
|
|
||||||
triggerOptions.AddTrigger<SubjectVisitFinalVisitTrigger>();
|
|
||||||
triggerOptions.AddTrigger<SubjectVisitTrigger>();
|
triggerOptions.AddTrigger<SubjectVisitTrigger>();
|
||||||
|
triggerOptions.AddTrigger<SubjectVisitScanDateTrigger>();
|
||||||
triggerOptions.AddTrigger<TrialCriterionSignTrigger>();
|
triggerOptions.AddTrigger<TrialCriterionSignTrigger>();
|
||||||
triggerOptions.AddTrigger<TableQuestionRowTrigger>();
|
triggerOptions.AddTrigger<TableQuestionRowTrigger>();
|
||||||
//triggerOptions.AddTrigger<AddlTrialUserTrigger>();
|
//triggerOptions.AddTrigger<AddlTrialUserTrigger>();
|
||||||
triggerOptions.AddTrigger<VisitTaskIsFrontTaskNeedSignButNotSignTrigger>();
|
triggerOptions.AddTrigger<VisitTaskIsFrontTaskNeedSignButNotSignTrigger>();
|
||||||
triggerOptions.AddTrigger<VisitTaskIbeforeTrigger>();
|
triggerOptions.AddTrigger<JudgeVisitTaskTrigger>();
|
||||||
|
|
||||||
triggerOptions.AddTrigger<UserLogTrigger>();
|
triggerOptions.AddTrigger<UserLogTrigger>();
|
||||||
|
|
||||||
|
|||||||
@@ -35,7 +35,9 @@ namespace IRaCIS.Core.API
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Default or English date format
|
// Default or English date format
|
||||||
_dateFormat = "MM/dd/yyyy HH:mm:ss";
|
//_dateFormat = "MM/dd/yyyy HH:mm:ss";
|
||||||
|
|
||||||
|
_dateFormat = "yyyy-MM-dd HH:mm:ss";
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|||||||
@@ -13,15 +13,16 @@
|
|||||||
"ObjectStoreService": {
|
"ObjectStoreService": {
|
||||||
"ObjectStoreUse": "AliyunOSS",
|
"ObjectStoreUse": "AliyunOSS",
|
||||||
"AliyunOSS": {
|
"AliyunOSS": {
|
||||||
"regionId": "cn-shanghai",
|
"RegionId": "cn-shanghai",
|
||||||
"internalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com",
|
"InternalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com",
|
||||||
"endpoint": "https://oss-cn-shanghai.aliyuncs.com",
|
"EndPoint": "https://oss-cn-shanghai.aliyuncs.com",
|
||||||
"accessKeyId": "LTAI5tKvzs7ed3UfSpNk3xwQ",
|
"AccessKeyId": "LTAI5tNRTsqL6aWmHkDmTwoH",
|
||||||
"accessKeySecret": "zTIceGEShlZDGnLrCFfIGFE7TXVRio",
|
"AccessKeySecret": "7mtGz3qrYWI6JMMBZiLeC119VWicZH",
|
||||||
"bucketName": "zy-irc-store",
|
"RoleArn": "acs:ram::1899121822495495:role/irc-oss-access",
|
||||||
"roleArn": "acs:ram::1899121822495495:role/oss-upload",
|
"BucketName": "zy-irc-store",
|
||||||
"viewEndpoint": "https://zy-irc-cache.oss-cn-shanghai.aliyuncs.com",
|
"ViewEndpoint": "https://zy-irc-cache.oss-cn-shanghai.aliyuncs.com",
|
||||||
"region": "oss-cn-shanghai"
|
"Region": "oss-cn-shanghai",
|
||||||
|
"DurationSeconds": 7200
|
||||||
},
|
},
|
||||||
"MinIO": {
|
"MinIO": {
|
||||||
"endpoint": "http://192.168.3.68",
|
"endpoint": "http://192.168.3.68",
|
||||||
@@ -63,7 +64,8 @@
|
|||||||
"CompanyName": "Extensive Imaging",
|
"CompanyName": "Extensive Imaging",
|
||||||
"CompanyNameCN": "上海展影医疗科技有限公司",
|
"CompanyNameCN": "上海展影医疗科技有限公司",
|
||||||
"CompanyShortName": "Extensive Imaging",
|
"CompanyShortName": "Extensive Imaging",
|
||||||
"CompanyShortNameCN": "展影医疗"
|
"CompanyShortNameCN": "展影医疗",
|
||||||
|
"IsEnv_US": false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -15,15 +15,16 @@
|
|||||||
"ObjectStoreService": {
|
"ObjectStoreService": {
|
||||||
"ObjectStoreUse": "AliyunOSS",
|
"ObjectStoreUse": "AliyunOSS",
|
||||||
"AliyunOSS": {
|
"AliyunOSS": {
|
||||||
"regionId": "cn-shanghai",
|
"RegionId": "cn-shanghai",
|
||||||
"internalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com",
|
"InternalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com",
|
||||||
"endpoint": "https://oss-cn-shanghai.aliyuncs.com",
|
"EndPoint": "https://oss-cn-shanghai.aliyuncs.com",
|
||||||
"accessKeyId": "LTAI5tKvzs7ed3UfSpNk3xwQ",
|
"AccessKeyId": "LTAI5tNRTsqL6aWmHkDmTwoH",
|
||||||
"accessKeySecret": "zTIceGEShlZDGnLrCFfIGFE7TXVRio",
|
"AccessKeySecret": "7mtGz3qrYWI6JMMBZiLeC119VWicZH",
|
||||||
"bucketName": "zy-irc-store",
|
"RoleArn": "acs:ram::1899121822495495:role/irc-oss-access",
|
||||||
"roleArn": "acs:ram::1899121822495495:role/oss-upload",
|
"BucketName": "zy-irc-store",
|
||||||
"viewEndpoint": "https://zy-irc-cache.oss-cn-shanghai.aliyuncs.com",
|
"ViewEndpoint": "https://zy-irc-cache.oss-cn-shanghai.aliyuncs.com",
|
||||||
"region": "oss-cn-shanghai"
|
"Region": "oss-cn-shanghai",
|
||||||
|
"DurationSeconds": 7200
|
||||||
},
|
},
|
||||||
"MinIO": {
|
"MinIO": {
|
||||||
"endpoint": "http://192.168.3.68",
|
"endpoint": "http://192.168.3.68",
|
||||||
@@ -67,7 +68,8 @@
|
|||||||
"CompanyName": "Extensive Imaging",
|
"CompanyName": "Extensive Imaging",
|
||||||
"CompanyNameCN": "上海展影医疗科技有限公司",
|
"CompanyNameCN": "上海展影医疗科技有限公司",
|
||||||
"CompanyShortName": "Extensive Imaging",
|
"CompanyShortName": "Extensive Imaging",
|
||||||
"CompanyShortNameCN": "展影医疗"
|
"CompanyShortNameCN": "展影医疗",
|
||||||
|
"IsEnv_US": false
|
||||||
},
|
},
|
||||||
"SystemPacsConfig": {
|
"SystemPacsConfig": {
|
||||||
"Port": "11113",
|
"Port": "11113",
|
||||||
|
|||||||
@@ -19,10 +19,10 @@
|
|||||||
"RegionId": "cn-shanghai",
|
"RegionId": "cn-shanghai",
|
||||||
"InternalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com",
|
"InternalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com",
|
||||||
"EndPoint": "https://oss-cn-shanghai.aliyuncs.com",
|
"EndPoint": "https://oss-cn-shanghai.aliyuncs.com",
|
||||||
"AccessKeyId": "LTAI5tJV76pYX5yPg1N9QVE8",
|
"AccessKeyId": "LTAI5tRRZehUp2V9pyTPtAJm",
|
||||||
"AccessKeySecret": "roRNLa9YG1of4pYruJGCNKBXEWTAWa",
|
"AccessKeySecret": "FLizxkHsMm4CGYHtkV8E3PNJJZU7oV",
|
||||||
|
"RoleArn": "acs:ram::1899121822495495:role/dev-oss-access",
|
||||||
"BucketName": "zy-irc-test-store",
|
"BucketName": "zy-irc-test-store",
|
||||||
"RoleArn": "acs:ram::1899121822495495:role/webdirect",
|
|
||||||
"ViewEndpoint": "https://zy-irc-test-store.oss-cn-shanghai.aliyuncs.com",
|
"ViewEndpoint": "https://zy-irc-test-store.oss-cn-shanghai.aliyuncs.com",
|
||||||
"Region": "oss-cn-shanghai",
|
"Region": "oss-cn-shanghai",
|
||||||
"DurationSeconds": 7200
|
"DurationSeconds": 7200
|
||||||
@@ -40,11 +40,11 @@
|
|||||||
"Region": "us-east-1",
|
"Region": "us-east-1",
|
||||||
"EndPoint": "s3.us-east-1.amazonaws.com",
|
"EndPoint": "s3.us-east-1.amazonaws.com",
|
||||||
"UseSSL": true,
|
"UseSSL": true,
|
||||||
"RoleArn": "arn:aws:iam::471112624751:role/sts_s3_upload",
|
"RoleArn": "arn:aws:iam::471112624751:role/uat_s3_access",
|
||||||
"AccessKeyId": "AKIAW3MEAFJXWRCGSX5Z",
|
"AccessKeyId": "AKIAW3MEAFJX7IPXISP4",
|
||||||
"SecretAccessKey": "miais4jQGSd37A+TfBEP11AQM5u/CvotSmznJd8k",
|
"SecretAccessKey": "Pgrg3le5jPxZQ7MR1yYNS30J0XRyJeKVyIIjElXc",
|
||||||
"BucketName": "ei-med-s3-lili-uat-store",
|
"BucketName": "ei-med-s3-lili-uat-store",
|
||||||
"ViewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com/",
|
"ViewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com",
|
||||||
"DurationSeconds": 7200
|
"DurationSeconds": 7200
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -88,7 +88,8 @@
|
|||||||
"CompanyName": "Extensive Imaging",
|
"CompanyName": "Extensive Imaging",
|
||||||
"CompanyNameCN": "上海展影医疗科技有限公司",
|
"CompanyNameCN": "上海展影医疗科技有限公司",
|
||||||
"CompanyShortName": "Extensive Imaging",
|
"CompanyShortName": "Extensive Imaging",
|
||||||
"CompanyShortNameCN": "展影医疗"
|
"CompanyShortNameCN": "展影医疗",
|
||||||
|
"IsEnv_US": false
|
||||||
},
|
},
|
||||||
|
|
||||||
"SystemPacsConfig": {
|
"SystemPacsConfig": {
|
||||||
|
|||||||
@@ -15,18 +15,6 @@
|
|||||||
|
|
||||||
"ObjectStoreService": {
|
"ObjectStoreService": {
|
||||||
"ObjectStoreUse": "AWS",
|
"ObjectStoreUse": "AWS",
|
||||||
"AliyunOSS": {
|
|
||||||
"regionId": "cn-shanghai",
|
|
||||||
"internalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com",
|
|
||||||
"endPoint": "https://oss-cn-shanghai.aliyuncs.com",
|
|
||||||
"accessKeyId": "",
|
|
||||||
"accessKeySecret": "",
|
|
||||||
"bucketName": "zy-irc-test-store",
|
|
||||||
"roleArn": "acs:ram::1899121822495495:role/oss-upload",
|
|
||||||
"viewEndpoint": "https://zy-irc-test-store.oss-cn-shanghai.aliyuncs.com",
|
|
||||||
"region": "oss-cn-shanghai"
|
|
||||||
},
|
|
||||||
|
|
||||||
"MinIO": {
|
"MinIO": {
|
||||||
"endPoint": "44.210.231.169",
|
"endPoint": "44.210.231.169",
|
||||||
"port": "9001",
|
"port": "9001",
|
||||||
@@ -38,12 +26,15 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
"AWS": {
|
"AWS": {
|
||||||
"endPoint": "s3.us-east-1.amazonaws.com",
|
"Region": "us-east-1",
|
||||||
"useSSL": true,
|
"EndPoint": "s3.us-east-1.amazonaws.com",
|
||||||
"accessKey": "AKIAW3MEAFJX5P32P6NA",
|
"UseSSL": true,
|
||||||
"secretKey": "soKfYlzZE11Zi4RyTjXp0myXN0U3U+ka8rT49+B/",
|
"RoleArn": "arn:aws:iam::471112624751:role/lili_s3_access",
|
||||||
"bucketName": "ei-med-s3-lili-store",
|
"AccessKeyId": "AKIAW3MEAFJXZ2TZK7GM",
|
||||||
"viewEndpoint": "https://ei-med-s3-lili-store.s3.amazonaws.com/"
|
"SecretAccessKey": "9MLQCQ1HifEVW1gf068zBRAOb4wNnfrOkvBVByth",
|
||||||
|
"BucketName": "ei-med-s3-lili-store",
|
||||||
|
"ViewEndpoint": "https://ei-med-s3-lili-store.s3.amazonaws.com",
|
||||||
|
"DurationSeconds": 7200
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"BasicSystemConfig": {
|
"BasicSystemConfig": {
|
||||||
@@ -82,7 +73,13 @@
|
|||||||
"CompanyNameCN": "上海展影医疗科技有限公司",
|
"CompanyNameCN": "上海展影医疗科技有限公司",
|
||||||
"CompanyShortName": "Elevate Imaging",
|
"CompanyShortName": "Elevate Imaging",
|
||||||
"CompanyShortNameCN": "展影医疗",
|
"CompanyShortNameCN": "展影医疗",
|
||||||
"SiteUrl": "https://lili.elevateimaging.ai/login"
|
"SiteUrl": "https://lili.elevateimaging.ai/login",
|
||||||
|
"IsEnv_US": true
|
||||||
|
},
|
||||||
|
|
||||||
|
"SystemPacsConfig": {
|
||||||
|
"Port": "104",
|
||||||
|
"IP": "44.210.231.169"
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,19 +13,7 @@
|
|||||||
|
|
||||||
"ObjectStoreService": {
|
"ObjectStoreService": {
|
||||||
|
|
||||||
"ObjectStoreUse": "MinIO",
|
"ObjectStoreUse": "AWS",
|
||||||
"AliyunOSS": {
|
|
||||||
"regionId": "cn-shanghai",
|
|
||||||
"internalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com",
|
|
||||||
"endPoint": "https://oss-cn-shanghai.aliyuncs.com",
|
|
||||||
"accessKeyId": "LTAI5tKvzs7ed3UfSpNk3xwQ",
|
|
||||||
"accessKeySecret": "zTIceGEShlZDGnLrCFfIGFE7TXVRio",
|
|
||||||
"bucketName": "zy-irc-test-store",
|
|
||||||
"roleArn": "acs:ram::1899121822495495:role/oss-upload",
|
|
||||||
"viewEndpoint": "https://zy-irc-test-store.oss-cn-shanghai.aliyuncs.com",
|
|
||||||
"region": "oss-cn-shanghai"
|
|
||||||
},
|
|
||||||
|
|
||||||
"MinIO": {
|
"MinIO": {
|
||||||
//"endPoint": "hir-oss.uat.extimaging.com",
|
//"endPoint": "hir-oss.uat.extimaging.com",
|
||||||
//"port": "443",
|
//"port": "443",
|
||||||
@@ -44,23 +32,26 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
"AWS": {
|
"AWS": {
|
||||||
"endPoint": "s3.us-east-1.amazonaws.com",
|
"Region": "us-east-1",
|
||||||
"useSSL": true,
|
"EndPoint": "s3.us-east-1.amazonaws.com",
|
||||||
"accessKey": "AKIAZQ3DRSOHFPJJ6FEU",
|
"UseSSL": true,
|
||||||
"secretKey": "l+yjtvV7Z4jiwm/7xCYv30UeUj/SvuqqYzAwjJHf",
|
"RoleArn": "arn:aws:iam::471112624751:role/uat_s3_access",
|
||||||
"bucketName": "ei-irc-test-store",
|
"AccessKeyId": "AKIAW3MEAFJX7IPXISP4",
|
||||||
"viewEndpoint": "https://ei-irc-test-store.s3.amazonaws.com/"
|
"SecretAccessKey": "Pgrg3le5jPxZQ7MR1yYNS30J0XRyJeKVyIIjElXc",
|
||||||
|
"BucketName": "ei-med-s3-lili-uat-store",
|
||||||
|
"ViewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com",
|
||||||
|
"DurationSeconds": 7200
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"BasicSystemConfig": {
|
"BasicSystemConfig": {
|
||||||
|
|
||||||
"OpenUserComplexPassword": false,
|
"OpenUserComplexPassword": true,
|
||||||
|
|
||||||
"OpenSignDocumentBeforeWork": false,
|
"OpenSignDocumentBeforeWork": true,
|
||||||
|
|
||||||
"OpenTrialRelationDelete": true,
|
"OpenTrialRelationDelete": true,
|
||||||
|
|
||||||
"OpenLoginLimit": false,
|
"OpenLoginLimit": true,
|
||||||
|
|
||||||
"LoginMaxFailCount": 5,
|
"LoginMaxFailCount": 5,
|
||||||
|
|
||||||
@@ -72,7 +63,9 @@
|
|||||||
"ReadingRestTimeMin": 10,
|
"ReadingRestTimeMin": 10,
|
||||||
"IsNeedChangePassWord": true,
|
"IsNeedChangePassWord": true,
|
||||||
|
|
||||||
"ChangePassWordDays": 90
|
"ChangePassWordDays": 90,
|
||||||
|
|
||||||
|
"OpenLoginMFA": true
|
||||||
},
|
},
|
||||||
|
|
||||||
"SystemEmailSendConfig": {
|
"SystemEmailSendConfig": {
|
||||||
@@ -88,7 +81,13 @@
|
|||||||
"CompanyNameCN": "上海展影医疗科技有限公司",
|
"CompanyNameCN": "上海展影医疗科技有限公司",
|
||||||
"CompanyShortName": "Elevate Imaging",
|
"CompanyShortName": "Elevate Imaging",
|
||||||
"CompanyShortNameCN": "展影医疗",
|
"CompanyShortNameCN": "展影医疗",
|
||||||
"SiteUrl": "https://lili.test.elevateimaging.ai/login"
|
"SiteUrl": "https://lili.test.elevateimaging.ai/login",
|
||||||
|
"IsEnv_US": true
|
||||||
|
},
|
||||||
|
|
||||||
|
"SystemPacsConfig": {
|
||||||
|
"Port": "104",
|
||||||
|
"IP": "3.226.182.187"
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,11 +7,11 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ConnectionStrings": {
|
"ConnectionStrings": {
|
||||||
"RemoteNew": "Server=us-mssql-service,1433;Database=US_Uat_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
|
//"RemoteNew": "Server=us-mssql-service,1433;Database=US_Uat_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
|
||||||
"Hangfire": "Server=us-mssql-service,1433;Database=US_Uat_IRC_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true"
|
//"Hangfire": "Server=us-mssql-service,1433;Database=US_Uat_IRC_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true"
|
||||||
|
|
||||||
//"RemoteNew": "Server=3.226.182.187,1435;Database=US_Uat_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
|
"RemoteNew": "Server=3.226.182.187,1435;Database=US_Uat_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
|
||||||
//"Hangfire": "Server=3.226.182.187,1435;Database=US_Uat_IRC_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true"
|
"Hangfire": "Server=3.226.182.187,1435;Database=US_Uat_IRC_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true"
|
||||||
},
|
},
|
||||||
|
|
||||||
"ObjectStoreService": {
|
"ObjectStoreService": {
|
||||||
@@ -36,19 +36,22 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
"AWS": {
|
"AWS": {
|
||||||
"endPoint": "s3.us-east-1.amazonaws.com",
|
"Region": "us-east-1",
|
||||||
"useSSL": true,
|
"EndPoint": "s3.us-east-1.amazonaws.com",
|
||||||
"accessKey": "AKIAW3MEAFJXUO6XYFYN",
|
"UseSSL": true,
|
||||||
"secretKey": "AeX5r4xHQH7tNJlTTFVv5/zBXie1Kj+mAayKrukp",
|
"RoleArn": "arn:aws:iam::471112624751:role/uat_s3_access",
|
||||||
"bucketName": "ei-med-s3-lili-uat-store",
|
"AccessKeyId": "AKIAW3MEAFJX7IPXISP4",
|
||||||
"viewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com/"
|
"SecretAccessKey": "Pgrg3le5jPxZQ7MR1yYNS30J0XRyJeKVyIIjElXc",
|
||||||
|
"BucketName": "ei-med-s3-lili-uat-store",
|
||||||
|
"ViewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com/",
|
||||||
|
"DurationSeconds": 7200
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"BasicSystemConfig": {
|
"BasicSystemConfig": {
|
||||||
|
|
||||||
"OpenUserComplexPassword": false,
|
"OpenUserComplexPassword": true,
|
||||||
|
|
||||||
"OpenSignDocumentBeforeWork": false,
|
"OpenSignDocumentBeforeWork": true,
|
||||||
|
|
||||||
"OpenTrialRelationDelete": true,
|
"OpenTrialRelationDelete": true,
|
||||||
|
|
||||||
@@ -66,7 +69,7 @@
|
|||||||
|
|
||||||
"ChangePassWordDays": 90,
|
"ChangePassWordDays": 90,
|
||||||
|
|
||||||
"OpenLoginMFA": true
|
"OpenLoginMFA": false
|
||||||
},
|
},
|
||||||
|
|
||||||
"SystemEmailSendConfig": {
|
"SystemEmailSendConfig": {
|
||||||
@@ -82,7 +85,13 @@
|
|||||||
"CompanyNameCN": "上海展影医疗科技有限公司",
|
"CompanyNameCN": "上海展影医疗科技有限公司",
|
||||||
"CompanyShortName": "Elevate Imaging",
|
"CompanyShortName": "Elevate Imaging",
|
||||||
"CompanyShortNameCN": "展影医疗",
|
"CompanyShortNameCN": "展影医疗",
|
||||||
"SiteUrl": "https://lili.test.elevateimaging.ai/login"
|
"SiteUrl": "https://lili.test.elevateimaging.ai/login",
|
||||||
|
"IsEnv_US": true
|
||||||
|
},
|
||||||
|
|
||||||
|
"SystemPacsConfig": {
|
||||||
|
"Port": "104",
|
||||||
|
"IP": "3.226.182.187"
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,15 +15,16 @@
|
|||||||
"ObjectStoreUse": "AliyunOSS",
|
"ObjectStoreUse": "AliyunOSS",
|
||||||
|
|
||||||
"AliyunOSS": {
|
"AliyunOSS": {
|
||||||
"regionId": "cn-shanghai",
|
"RegionId": "cn-shanghai",
|
||||||
"internalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com",
|
"InternalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com",
|
||||||
"endpoint": "https://oss-cn-shanghai.aliyuncs.com",
|
"EndPoint": "https://oss-cn-shanghai.aliyuncs.com",
|
||||||
"accessKeyId": "LTAI5tKvzs7ed3UfSpNk3xwQ",
|
"AccessKeyId": "LTAI5tRRZehUp2V9pyTPtAJm",
|
||||||
"accessKeySecret": "zTIceGEShlZDGnLrCFfIGFE7TXVRio",
|
"AccessKeySecret": "FLizxkHsMm4CGYHtkV8E3PNJJZU7oV",
|
||||||
"bucketName": "zy-irc-uat-store",
|
"RoleArn": "acs:ram::1899121822495495:role/dev-oss-access",
|
||||||
"roleArn": "acs:ram::1899121822495495:role/oss-upload",
|
"BucketName": "zy-irc-uat-store",
|
||||||
"viewEndpoint": "https://zy-irc-uat-store.oss-cn-shanghai.aliyuncs.com",
|
"ViewEndpoint": "https://zy-irc-uat-store.oss-cn-shanghai.aliyuncs.com",
|
||||||
"region": "oss-cn-shanghai"
|
"Region": "oss-cn-shanghai",
|
||||||
|
"DurationSeconds": 7200
|
||||||
},
|
},
|
||||||
|
|
||||||
"MinIO": {
|
"MinIO": {
|
||||||
@@ -38,6 +39,17 @@
|
|||||||
"secretKey": "DzMaU2L4OXl90uytwOmDXF2encN0Jf4Nxu2XkYqQ",
|
"secretKey": "DzMaU2L4OXl90uytwOmDXF2encN0Jf4Nxu2XkYqQ",
|
||||||
"bucketName": "irc-uat"
|
"bucketName": "irc-uat"
|
||||||
|
|
||||||
|
},
|
||||||
|
"AWS": {
|
||||||
|
"Region": "us-east-1",
|
||||||
|
"EndPoint": "s3.us-east-1.amazonaws.com",
|
||||||
|
"UseSSL": true,
|
||||||
|
"RoleArn": "arn:aws:iam::471112624751:role/sts_s3_upload",
|
||||||
|
"AccessKeyId": "AKIAW3MEAFJXWRCGSX5Z",
|
||||||
|
"SecretAccessKey": "miais4jQGSd37A+TfBEP11AQM5u/CvotSmznJd8k",
|
||||||
|
"BucketName": "ei-med-s3-lili-uat-store",
|
||||||
|
"ViewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com/",
|
||||||
|
"DurationSeconds": 7200
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -74,7 +86,8 @@
|
|||||||
"CompanyName": "Extensive Imaging",
|
"CompanyName": "Extensive Imaging",
|
||||||
"CompanyNameCN": "上海展影医疗科技有限公司",
|
"CompanyNameCN": "上海展影医疗科技有限公司",
|
||||||
"CompanyShortName": "Extensive Imaging",
|
"CompanyShortName": "Extensive Imaging",
|
||||||
"CompanyShortNameCN": "展影医疗"
|
"CompanyShortNameCN": "展影医疗",
|
||||||
|
"IsEnv_US": false
|
||||||
},
|
},
|
||||||
|
|
||||||
"SystemPacsConfig": {
|
"SystemPacsConfig": {
|
||||||
|
|||||||
@@ -43,40 +43,6 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"easycaching": {
|
|
||||||
"inmemory": {
|
|
||||||
"MaxRdSecond": 120,
|
|
||||||
"EnableLogging": false,
|
|
||||||
"LockMs": 5000,
|
|
||||||
"SleepMs": 300,
|
|
||||||
"DBConfig": {
|
|
||||||
"SizeLimit": 10000,
|
|
||||||
"ExpirationScanFrequency": 60,
|
|
||||||
"EnableReadDeepClone": true,
|
|
||||||
"EnableWriteDeepClone": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"redis": {
|
|
||||||
"MaxRdSecond": 120,
|
|
||||||
"EnableLogging": false,
|
|
||||||
"LockMs": 5000,
|
|
||||||
"SleepMs": 300,
|
|
||||||
"dbconfig": {
|
|
||||||
"Password": "xc@123456",
|
|
||||||
"IsSsl": false,
|
|
||||||
"SslHost": null,
|
|
||||||
"ConnectionTimeout": 5000,
|
|
||||||
"AllowAdmin": true,
|
|
||||||
"Endpoints": [
|
|
||||||
{
|
|
||||||
"Host": "47.117.164.182",
|
|
||||||
"Port": 6379
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"Database": 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"IRaCISImageStore": {
|
"IRaCISImageStore": {
|
||||||
"SwitchingMode": "RemainingDiskCapacity",
|
"SwitchingMode": "RemainingDiskCapacity",
|
||||||
"SwitchingRatio": 80,
|
"SwitchingRatio": 80,
|
||||||
@@ -88,13 +54,15 @@
|
|||||||
"QCChallengeCodePrefix": "Q",
|
"QCChallengeCodePrefix": "Q",
|
||||||
"NoneDicomStudyCodePrefix": "NST",
|
"NoneDicomStudyCodePrefix": "NST",
|
||||||
"DicomStudyCodePrefix": "ST",
|
"DicomStudyCodePrefix": "ST",
|
||||||
|
"TaskStudyCodePrefix": "P-ST",
|
||||||
"SystemSiteCodePrefix": "S",
|
"SystemSiteCodePrefix": "S",
|
||||||
"DefaultPassword": "123456",
|
"DefaultPassword": "123456",
|
||||||
"ImageShareExpireDays": 10
|
"ImageShareExpireDays": 10
|
||||||
},
|
},
|
||||||
|
|
||||||
"EncrypteResponseConfig": {
|
"EncrypteResponseConfig": {
|
||||||
"IsEnable": true,
|
"Base64RSAPublicKey": "LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0NCk1JSUJJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBTUlJQkNnS0NBUUVBaHp3T1hYTWYyaEFkS1ZoWHczYUYNCmNaT3QycE1lcmdEaFVrOUdQK2s4VDBrUjFTRVlGVGtzNlkzaEVvL0dRTExqMHZFYVV3bTNhSFNuTTl5NmdLRWoNCmY5cTN6dkoyZzRSQjE4Z0UrTnNWWi9DMkVRZ3k5OWFiWGc5TitGREVlT0NmSjlSRTJPV3JBQ2s0V0RPbFFUdXYNCnhvR2JmcnkwVElSaFBrOGtuYkFmVkZ1and1VXJGblpJZ0ExYXhKZVZ6aDhwcmV1SEgreW1jdHp6NVo4V1pSV3kNCi9ISURHUy90dkg2NUMra2l6cUxRYUpKNHYwODMrRGpaVTBmNzNCdkk5eWt1dW1saXFzY1pvU2preDFOUFJwSkUNCkFtMVFNQ0hMRCtFdzlHT2Vsc2Mwa1ZxdjdaeEF1TkFrMkZuUURNRk1BUmZuUFd0aGVhOGZYVTJsMW9ROWs3WDcNCmN3SURBUUFCDQotLS0tLUVORCBQVUJMSUMgS0VZLS0tLS0NCg==",
|
||||||
|
"Base64RSAPrivateKey": "LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQ0KTUlJRW9nSUJBQUtDQVFFQWh6d09YWE1mMmhBZEtWaFh3M2FGY1pPdDJwTWVyZ0RoVWs5R1ArazhUMGtSMVNFWQ0KRlRrczZZM2hFby9HUUxMajB2RWFVd20zYUhTbk05eTZnS0VqZjlxM3p2SjJnNFJCMThnRStOc1ZaL0MyRVFneQ0KOTlhYlhnOU4rRkRFZU9DZko5UkUyT1dyQUNrNFdET2xRVHV2eG9HYmZyeTBUSVJoUGs4a25iQWZWRnVqd3VVcg0KRm5aSWdBMWF4SmVWemg4cHJldUhIK3ltY3R6ejVaOFdaUld5L0hJREdTL3R2SDY1QytraXpxTFFhSko0djA4Mw0KK0RqWlUwZjczQnZJOXlrdXVtbGlxc2Nab1Nqa3gxTlBScEpFQW0xUU1DSExEK0V3OUdPZWxzYzBrVnF2N1p4QQ0KdU5BazJGblFETUZNQVJmblBXdGhlYThmWFUybDFvUTlrN1g3Y3dJREFRQUJBb0lCQUNDRFoxNi9XWWFYZmpOZA0KQ29pemU2VFJZU2llVzI5eFJic0ExVDV6YUcwVmY4U1NsdFF2Y1dWYmw2UGJUa3BxMkF4MHJDUVB2M2xOSm8vNA0KL3h3QzRlS1E1c1ZLRlFWTXJIbmhISlRxTTJ6UWVpMkJINlBuaEdZcVh0QVhOdzFxejhrSEoyQlFZM3IvN2d5Qw0KcWpZVFVCRDFRem5HeThCanlXOXVIcnNNeDVPRHRRZWxBM3B1TFd1bXZNb3Z1L2JhaDZvTGtOSHY4b0VTdzhGSQ0KTllyTUtscHhFTjZaWUdwSTl2VTZnYUhuTmhEa2ExTHlvUnZ5NnA2dTRLR0FsRTc1VXk4T0dsdncydU5uay9sdg0KSEMyYnY5TnlCRGJpSFNDY0MyK1JXUXMrN0tNWFlwYnBvTVFCR0hqV01GRHVBODFaUCs1TWYxUm9yQUpRNGxrRw0KQnRDQThva0NnWUVBeWY4alBjcFIvQ3dJNU5MYnlwb3ZUWEFHVkFKMmtWRlJVUC9HT2ZOMkFyYWMvL20wdDJ5NA0KemNYVkJZc0pJeHkvVWYxRTFJNFg3VFg3V3NBNGxVNGlPTkwzTnN4dDBEbk1PV2tKUlBPZlF1bW1JaWw5QVRiYQ0KTnRVWFNlTmRoUFFGMGlCb21acFFJYWpSN1RmUnVBbzR6dmpTLzkzeXZZY0lIWU1zM0tjR00ya0NnWUVBcTJPbg0KZlp0RmhLTElGanVlRzRrNklGTWdjbytEUUh5TTFWSUp5Tk05K1o2TEgybzI5eDJCaSs2Qm82M2NKUjQ2STZncQ0KNWUrSTBvdzZRYmNQeTZUNHFSQ0o3Ujd6MllkdEw4eXdJTkNYS3U0cC9qaFNqNWJ1TzFJWlI3ZStSV29CakNtUQ0KWFd0ZVBCbldqWVlLdVRCazROc2FXV09GTXg1QndKdUp2MjBnQ0hzQ2dZQlV4QnFYM1lWV0cyeUlDZXh1TXhIUw0KbjBZb2p2Z090MTgyYkg5VTVsUUpnM1NTL3NqVmlHeHMvYTROSzNGa0tMWW93KzNVZk9TUmlPdTRBNTQ3R1pURw0KMzlFYVQrTnRWRFBkaTdSMkdQNG1hRUp0WjVlcm9NY2w1M3BrYVdOZlhiL3JrK29STzI2UkVYVTI1UXUrL1pzbA0KVDhuTDBlb0JtdDdPODdNcHpYV09zUUtCZ0ZxVGFQSGx2RUNUY3FEbFV2S0VmRmFXOTkvelhrOFhRNnA5RjdTdA0KaHVSRDJJeDZxcC9BVlRWcGo5Tzd6MHRDaFVGUTM1THpHMkVDUU10My9uNEdLbS9XMEwyakRRWWFIeWNTeXNZYw0KMXJjV2ROVG9XU0dQaDBtTVl0WFhFbFJHNkpoMVl0a3NJL29wUVkwN21MRTBGU3dNUHdtY29jbFpKVEN3UW9VTA0KRzlHL0FvR0FWM25kcWcydnUyR0x4TlRUbm1UTWRJNFB3UzBmN0V4VnVNUnRicGZyOWhKNzlDakVNTGFXQ1FsNg0KeE43TElMTnArNVQwQW1DZVBqcitkbnJkRUNidFZPTDFybDc3Z0krRkwzaVVqYmZmMVZqa0N3M0x6K3cyb1FFdA0KbGE4aTZrL1NRK01iYkRPaWRJOVczdlN6MmlJRlZobWJiK1Q2SlZwakxqNjlkblM3eUxZPQ0KLS0tLS1FTkQgUlNBIFBSSVZBVEUgS0VZLS0tLS0NCg==",
|
||||||
|
"IsResponseEncreptEnable": true,
|
||||||
"ApiPathList": [
|
"ApiPathList": [
|
||||||
"/test/get"
|
"/test/get"
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1,40 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang='en'>
|
|
||||||
<head>
|
|
||||||
<meta charset='UTF-8'>
|
|
||||||
<title>Title</title>
|
|
||||||
</head>
|
|
||||||
<body style='font-family: 微软雅黑;padding: 0;margin: 0;'>
|
|
||||||
<div style='padding-left: 40px;background: #f6f6f6'>
|
|
||||||
<div style='padding-top: 20px;'>
|
|
||||||
<div style='line-height: 40px;font-size: 18px'>
|
|
||||||
尊敬的 {0} ,您好:
|
|
||||||
</div>
|
|
||||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
|
||||||
{company abbreviation}为您添加了账户,账户信息如下:
|
|
||||||
</div>
|
|
||||||
<span style="color: #00D1B2"></span>
|
|
||||||
<div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;'>
|
|
||||||
<div>
|
|
||||||
用户名: {1}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
角色: {2}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
首次登陆前,请通过该链接修改您的账户信息:
|
|
||||||
<a href='{3}' style='margin-left:1px;font-size:14px;text-decoration: none;display: inline-block;color:#00D1B2;border-radius: 5px;line-height: 40px;text-align: center;'>
|
|
||||||
初始化账号信息
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
|
||||||
<div>祝您顺利!</div>
|
|
||||||
<div style="font-size: 14px;">{company}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang='en'>
|
|
||||||
<head>
|
|
||||||
<meta charset='UTF-8'>
|
|
||||||
<title>Title</title>
|
|
||||||
</head>
|
|
||||||
<body style='font-family: 微软雅黑;padding: 0;margin: 0;'>
|
|
||||||
<div style='padding-left: 40px;background: #f6f6f6'>
|
|
||||||
<div style='padding-top: 20px;'>
|
|
||||||
<div style='line-height: 40px;font-size: 18px'>
|
|
||||||
Dear {0} ,
|
|
||||||
</div>
|
|
||||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
|
||||||
{company abbreviation} has created an account for you. The account information is as follows:
|
|
||||||
</div>
|
|
||||||
<span style="color: #00D1B2"></span>
|
|
||||||
<div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;'>
|
|
||||||
<div>
|
|
||||||
User ID: {1}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
Role: {2}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
Before logging in for the first time, please modify the account information through this link:
|
|
||||||
<a href='{3}' style='margin-left:1px;font-size:14px;text-decoration: none;display: inline-block;color:#00D1B2;border-radius: 5px;line-height: 40px;text-align: center;'>
|
|
||||||
Initialize account information
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
|
||||||
<div>Best regards,</div>
|
|
||||||
<div style="font-size: 14px;">{company}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang='en'>
|
|
||||||
<head>
|
|
||||||
<meta charset='UTF-8'>
|
|
||||||
<title>Title</title>
|
|
||||||
</head>
|
|
||||||
<body style='font-family: 微软雅黑;padding: 0;margin: 0;'>
|
|
||||||
<div style='padding-left: 40px;background: #f6f6f6'>
|
|
||||||
<div style='padding-top: 20px;'>
|
|
||||||
<div style='line-height: 40px;font-size: 18px'>
|
|
||||||
尊敬的 {0} ,您好:
|
|
||||||
</div>
|
|
||||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
|
||||||
{company abbreviation}将您的账户密码已重置,账户信息如下:
|
|
||||||
</div>
|
|
||||||
<span style="color: #00D1B2"></span>
|
|
||||||
<div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;'>
|
|
||||||
<div>
|
|
||||||
用户名: {1}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
角色: {2}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
密码: {3}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
|
||||||
<div>祝您顺利!</div>
|
|
||||||
<div style="font-size: 14px;">{company}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang='en'>
|
|
||||||
<head>
|
|
||||||
<meta charset='UTF-8'>
|
|
||||||
<title>Title</title>
|
|
||||||
</head>
|
|
||||||
<body style='font-family: 微软雅黑;padding: 0;margin: 0;'>
|
|
||||||
<div style='padding-left: 40px;background: #f6f6f6'>
|
|
||||||
<div style='padding-top: 20px;'>
|
|
||||||
<div style='line-height: 40px;font-size: 18px'>
|
|
||||||
Dear {0} ,
|
|
||||||
</div>
|
|
||||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
|
||||||
{company abbreviation} has reset your account password, and the account information is as follows:
|
|
||||||
</div>
|
|
||||||
<span style="color: #00D1B2"></span>
|
|
||||||
<div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;'>
|
|
||||||
<div>
|
|
||||||
User ID: {1}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
Role: {2}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
Password: {3}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
|
||||||
<div>Best regards,</div>
|
|
||||||
<div style="font-size: 14px;">{company}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang='en'>
|
|
||||||
<head>
|
|
||||||
<meta charset='UTF-8'>
|
|
||||||
<title>Title</title>
|
|
||||||
</head>
|
|
||||||
<body style='font-family: 微软雅黑;padding: 0;margin: 0;'>
|
|
||||||
<div style='padding-left: 40px;background: #f6f6f6'>
|
|
||||||
<div style='padding-top: 20px;'>
|
|
||||||
<div style='line-height: 40px;font-size: 18px'>
|
|
||||||
您好:
|
|
||||||
</div>
|
|
||||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
|
||||||
感谢您使用展影云平台。
|
|
||||||
</div>
|
|
||||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
|
||||||
{0}。
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
|
||||||
<div>祝您顺利!</div>
|
|
||||||
<div style="font-size: 14px;">{company}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang='en'>
|
|
||||||
<head>
|
|
||||||
<meta charset='UTF-8'>
|
|
||||||
<title>Title</title>
|
|
||||||
</head>
|
|
||||||
<body style='font-family: 微软雅黑;padding: 0;margin: 0;'>
|
|
||||||
<div style='padding-left: 40px;background: #f6f6f6'>
|
|
||||||
<div style='padding-top: 20px;'>
|
|
||||||
<div style='line-height: 40px;font-size: 18px'>
|
|
||||||
Dear:
|
|
||||||
</div>
|
|
||||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
|
||||||
Thank you for using {company abbreviation} Cloud System.
|
|
||||||
</div>
|
|
||||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
|
||||||
{0}。
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
|
||||||
<div>Best regards,</div>
|
|
||||||
<div style="font-size: 14px;">{company}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang='en'>
|
|
||||||
<head>
|
|
||||||
<meta charset='UTF-8'>
|
|
||||||
<title>Title</title>
|
|
||||||
</head>
|
|
||||||
<body style='font-family: 微软雅黑;padding: 0;margin: 0;'>
|
|
||||||
<div style='padding-left: 40px;background: #f6f6f6'>
|
|
||||||
<div style='padding-top: 20px;'>
|
|
||||||
<div style='line-height: 40px;font-size: 18px'>
|
|
||||||
尊敬的 {0} ,您好:
|
|
||||||
</div>
|
|
||||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
|
||||||
{company abbreviation}作为 [{1} (试验方案号:{2 })] 项目的供应商,诚邀您参加该项目阅片相关工作。
|
|
||||||
</div>
|
|
||||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
|
||||||
该项目采用电子化工作流,系统及您的账号信息如下:
|
|
||||||
</div>
|
|
||||||
<span style="color: #00D1B2"></span>
|
|
||||||
<div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;'>
|
|
||||||
<div>
|
|
||||||
项目编号: {3}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
试验方案号: {2}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
试验名称: {1}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
用户名: {4}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
角色: {5}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
系统登录地址:
|
|
||||||
<a href='{6}' style='margin-left:1px;font-size:14px;text-decoration: none;display: inline-block;color:#00D1B2;border-radius: 5px;line-height: 40px;text-align: center;'>
|
|
||||||
点击跳转
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
|
||||||
<div>祝您顺利!</div>
|
|
||||||
<div style="font-size: 14px;">{company}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -1,52 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang='en'>
|
|
||||||
<head>
|
|
||||||
<meta charset='UTF-8'>
|
|
||||||
<title>Title</title>
|
|
||||||
</head>
|
|
||||||
<body style='font-family: 微软雅黑;padding: 0;margin: 0;'>
|
|
||||||
<div style='padding-left: 40px;background: #f6f6f6'>
|
|
||||||
<div style='padding-top: 20px;'>
|
|
||||||
<div style='line-height: 40px;font-size: 18px'>
|
|
||||||
Dear {0},
|
|
||||||
</div>
|
|
||||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;font-size: 16px'>
|
|
||||||
{company abbreviation} invites you to participate in the IRC work of a trial ({1} , {2}).
|
|
||||||
</div>
|
|
||||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
|
||||||
Your account information is as follows:
|
|
||||||
</div>
|
|
||||||
<span style="color: #00D1B2"></span>
|
|
||||||
<div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;'>
|
|
||||||
<div>
|
|
||||||
Trial ID: {3}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
Protocol ID: {2}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
Study Name: {1}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
User ID: {4}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
Role: {5}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
Login URL:
|
|
||||||
<a href='{6}' style='margin-left:1px;font-size:14px;text-decoration: none;display: inline-block;color:#00D1B2;border-radius: 5px;line-height: 40px;text-align: center;'>
|
|
||||||
Click to login
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
|
||||||
<div>Best regards,</div>
|
|
||||||
<div style="font-size: 14px;">{company}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -1,52 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang='en'>
|
|
||||||
<head>
|
|
||||||
<meta charset='UTF-8'>
|
|
||||||
<title>Title</title>
|
|
||||||
</head>
|
|
||||||
<body style='font-family: 微软雅黑;padding: 0;margin: 0;'>
|
|
||||||
<div style='padding-left: 40px;background: #f6f6f6'>
|
|
||||||
<div style='padding-top: 20px;'>
|
|
||||||
<div style='line-height: 40px;font-size: 18px'>
|
|
||||||
尊敬的 {0} ,您好:
|
|
||||||
</div>
|
|
||||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
|
||||||
{company abbreviation}作为 [{1} (试验方案号:{2 })] 项目的IRC供应商,诚邀您参加该项目IRC阅片相关工作,欢迎您提供指导和建议,非常感谢!
|
|
||||||
</div>
|
|
||||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
|
||||||
该项目采用电子化工作流,系统及您的账号信息如下:
|
|
||||||
</div>
|
|
||||||
<span style="color: #00D1B2"></span>
|
|
||||||
<div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;'>
|
|
||||||
<div>
|
|
||||||
项目编号: {3}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
试验方案号: {2}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
试验名称: {1}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
用户名: {4}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
角色: {5}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
首次登陆前,请通过该链接修改您的账户信息:
|
|
||||||
<a href='{6}' style='margin-left:1px;font-size:14px;text-decoration: none;display: inline-block;color:#00D1B2;border-radius: 5px;line-height: 40px;text-align: center;'>
|
|
||||||
初始化账号信息
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
|
||||||
<div>祝您顺利!</div>
|
|
||||||
<div style="font-size: 14px;">{company}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -1,52 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang='en'>
|
|
||||||
<head>
|
|
||||||
<meta charset='UTF-8'>
|
|
||||||
<title>Title</title>
|
|
||||||
</head>
|
|
||||||
<body style='font-family: 微软雅黑;padding: 0;margin: 0;'>
|
|
||||||
<div style='padding-left: 40px;background: #f6f6f6'>
|
|
||||||
<div style='padding-top: 20px;'>
|
|
||||||
<div style='line-height: 40px;font-size: 18px'>
|
|
||||||
Dear {0},
|
|
||||||
</div>
|
|
||||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
|
||||||
{company abbreviation} invites you to participate in the IRC work of a trial ({1}, {2}).
|
|
||||||
</div>
|
|
||||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
|
||||||
Your account information is as follows:
|
|
||||||
</div>
|
|
||||||
<span style="color: #00D1B2"></span>
|
|
||||||
<div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;'>
|
|
||||||
<div>
|
|
||||||
Trial ID: {3}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
Protocol ID: {2}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
Study Name: {1}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
User ID: {4}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
Role: {5}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
Before logging in for the first time, please modify the account information through this link:
|
|
||||||
<a href='{6}' style='margin-left:1px;font-size:14px;text-decoration: none;display: inline-block;color:#00D1B2;border-radius: 5px;line-height: 40px;text-align: center;'>
|
|
||||||
Initialize account information
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
|
||||||
<div>Best regards,</div>
|
|
||||||
<div style="font-size: 14px;">{company}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang='en'>
|
|
||||||
<head>
|
|
||||||
<meta charset='UTF-8'>
|
|
||||||
<title>Title</title>
|
|
||||||
</head>
|
|
||||||
<body style='font-family: 微软雅黑;padding: 0;margin: 0;'>
|
|
||||||
<div style='padding-left: 40px;background: #f6f6f6'>
|
|
||||||
<div style='padding-top: 20px;'>
|
|
||||||
<div style='line-height: 40px;font-size: 18px'>
|
|
||||||
尊敬的 {0} ,您好:
|
|
||||||
</div>
|
|
||||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
|
||||||
您填写的中心调研表被驳回,详细信息如下:
|
|
||||||
</div>
|
|
||||||
<span style="color: #00D1B2"></span>
|
|
||||||
<div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;'>
|
|
||||||
<div>
|
|
||||||
项目编号: {1}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
试验方案号: {2}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
试验名称: {3}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
中心编号: {4}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
中心名称: {5}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
驳回原因: {6}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<a href='{7}' style='margin-left:60px;font-size:14px;padding: 10px;text-decoration: none;display:{8} ;height: 40px;width: 140px;background: #00D1B2;color:#fff;border-radius: 5px;line-height: 40px;text-align: center;margin-bottom: 100px;'>
|
|
||||||
登陆并查看
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
|
||||||
<div>祝您顺利!</div>
|
|
||||||
<div style="font-size: 14px;">{company}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang='en'>
|
|
||||||
<head>
|
|
||||||
<meta charset='UTF-8'>
|
|
||||||
<title>Title</title>
|
|
||||||
</head>
|
|
||||||
<body style='font-family: 微软雅黑;padding: 0;margin: 0;'>
|
|
||||||
<div style='padding-left: 40px;background: #f6f6f6'>
|
|
||||||
<div style='padding-top: 20px;'>
|
|
||||||
<div style='line-height: 40px;font-size: 18px'>
|
|
||||||
Dear {0} ,
|
|
||||||
</div>
|
|
||||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
|
||||||
The site survey form you filled in has been rejected. The details are as follows:
|
|
||||||
</div>
|
|
||||||
<span style="color: #00D1B2"></span>
|
|
||||||
<div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;'>
|
|
||||||
<div>
|
|
||||||
Trial ID: {1}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
Protocol ID: {2}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
Study Name: {3}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
Site ID: {4}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
Site name: {5}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
Reason for rejection: {6}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<a href='{7}' style='margin-left:60px;font-size:14px;padding: 10px;text-decoration: none;display:{8} ;height: 40px;width: 140px;background: #00D1B2;color:#fff;border-radius: 5px;line-height: 40px;text-align: center;margin-bottom: 100px;'>
|
|
||||||
Login and view
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
|
||||||
<div>Best regards,</div>
|
|
||||||
<div style="font-size: 14px;">{company}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -1,52 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang='en'>
|
|
||||||
<head>
|
|
||||||
<meta charset='UTF-8'>
|
|
||||||
<title>Title</title>
|
|
||||||
</head>
|
|
||||||
<body style='font-family: 微软雅黑;padding: 0;margin: 0;'>
|
|
||||||
<div style='padding-left: 40px;background: #f6f6f6'>
|
|
||||||
<div style='padding-top: 20px;'>
|
|
||||||
<div style='line-height: 40px;font-size: 18px'>
|
|
||||||
尊敬的 {0} ,您好:
|
|
||||||
</div>
|
|
||||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
|
||||||
{company abbreviation}作为 [{1} (试验方案号:{2 })] 项目的供应商,诚邀您参加该项目相关工作,欢迎您提供指导和建议,非常感谢!
|
|
||||||
</div>
|
|
||||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
|
||||||
该项目采用电子化工作流,系统及您的账号信息如下:
|
|
||||||
</div>
|
|
||||||
<span style="color: #00D1B2"></span>
|
|
||||||
<div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;'>
|
|
||||||
<div>
|
|
||||||
项目编号: {3}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
试验方案号: {2}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
试验名称: {1}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
用户名: {4}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
角色: {5}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
系统登录地址:
|
|
||||||
<a href='{6}' style='margin-left:5px;font-size:14px;text-decoration: none;display: inline-block;color:#00D1B2;border-radius: 5px;line-height: 40px;text-align: center;'>
|
|
||||||
点击跳转
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
|
||||||
<div>祝您顺利!</div>
|
|
||||||
<div style="font-size: 14px;">{company}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -1,52 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang='en'>
|
|
||||||
<head>
|
|
||||||
<meta charset='UTF-8'>
|
|
||||||
<title>Title</title>
|
|
||||||
</head>
|
|
||||||
<body style='font-family: 微软雅黑;padding: 0;margin: 0;'>
|
|
||||||
<div style='padding-left: 40px;background: #f6f6f6'>
|
|
||||||
<div style='padding-top: 20px;'>
|
|
||||||
<div style='line-height: 40px;font-size: 18px'>
|
|
||||||
Dear {0},
|
|
||||||
</div>
|
|
||||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;font-size: 16px'>
|
|
||||||
{company abbreviation} invites you to participate in the IRC work of a trial ({1}, {2}).
|
|
||||||
</div>
|
|
||||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
|
||||||
Your account information is as follows:
|
|
||||||
</div>
|
|
||||||
<span style="color: #00D1B2"></span>
|
|
||||||
<div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;'>
|
|
||||||
<div>
|
|
||||||
Trial ID: {3}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
Protocol ID: {2}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
Study Name: {1}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
User ID: {4}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
Role: {5}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
Login URL:
|
|
||||||
<a href='{6}' style='margin-left:1px;font-size:14px;text-decoration: none;display: inline-block;color:#00D1B2;border-radius: 5px;line-height: 40px;text-align: center;'>
|
|
||||||
Click to login
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
|
||||||
<div>Best regards,</div>
|
|
||||||
<div style="font-size: 14px;">{company}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -1,52 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang='en'>
|
|
||||||
<head>
|
|
||||||
<meta charset='UTF-8'>
|
|
||||||
<title>Title</title>
|
|
||||||
</head>
|
|
||||||
<body style='font-family: 微软雅黑;padding: 0;margin: 0;'>
|
|
||||||
<div style='padding-left: 40px;background: #f6f6f6'>
|
|
||||||
<div style='padding-top: 20px;'>
|
|
||||||
<div style='line-height: 40px;font-size: 18px'>
|
|
||||||
尊敬的 {0} ,您好:
|
|
||||||
</div>
|
|
||||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
|
||||||
{company abbreviation}作为 [{1} (试验方案号:{2 })] 项目的IRC供应商,诚邀您参加该项目IRC相关工作,欢迎您提供指导和建议,非常感谢!
|
|
||||||
</div>
|
|
||||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
|
||||||
该项目采用电子化工作流,系统及您的账号信息如下:
|
|
||||||
</div>
|
|
||||||
<span style="color: #00D1B2"></span>
|
|
||||||
<div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;'>
|
|
||||||
<div>
|
|
||||||
项目编号: {3}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
试验方案号: {2}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
试验名称: {1}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
用户名: {4}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
角色: {5}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
首次登陆前,请通过该链接修改您的账户信息:
|
|
||||||
<a href='{6}' style='margin-left:1px;font-size:14px;text-decoration: none;display: inline-block;color:#00D1B2;border-radius: 5px;line-height: 40px;text-align: center;'>
|
|
||||||
初始化账号信息
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
|
||||||
<div>祝您顺利!</div>
|
|
||||||
<div style="font-size: 14px;">{company}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -1,52 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang='en'>
|
|
||||||
<head>
|
|
||||||
<meta charset='UTF-8'>
|
|
||||||
<title>Title</title>
|
|
||||||
</head>
|
|
||||||
<body style='font-family: 微软雅黑;padding: 0;margin: 0;'>
|
|
||||||
<div style='padding-left: 40px;background: #f6f6f6'>
|
|
||||||
<div style='padding-top: 20px;'>
|
|
||||||
<div style='line-height: 40px;font-size: 18px'>
|
|
||||||
Dear {0},
|
|
||||||
</div>
|
|
||||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
|
||||||
{company abbreviation} invites you to participate in the IRC work of a trial ({1}, {2}).
|
|
||||||
</div>
|
|
||||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
|
||||||
Your account information is as follows:
|
|
||||||
</div>
|
|
||||||
<span style="color: #00D1B2"></span>
|
|
||||||
<div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;'>
|
|
||||||
<div>
|
|
||||||
Trial ID: {3}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
Protocol ID: {2}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
Study Name: {1}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
User ID: {4}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
Role: {5}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
Before logging in for the first time, please modify the account information through this link:
|
|
||||||
<a href='{6}' style='margin-left:1px;font-size:14px;text-decoration: none;display: inline-block;color:#00D1B2;border-radius: 5px;line-height: 40px;text-align: center;'>
|
|
||||||
Initialize the account information
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
|
||||||
<div>Best regards,</div>
|
|
||||||
<div style="font-size: 14px;">{company}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang='en'>
|
|
||||||
<head>
|
|
||||||
<meta charset='UTF-8'>
|
|
||||||
<title>Title</title>
|
|
||||||
</head>
|
|
||||||
<body style='font-family: 微软雅黑;padding: 0;margin: 0;'>
|
|
||||||
<div style='padding-left: 40px;background: #f6f6f6'>
|
|
||||||
<div style='padding-top: 20px;'>
|
|
||||||
<div style='line-height: 40px;font-size: 18px'>
|
|
||||||
{0}您好,
|
|
||||||
</div>
|
|
||||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
|
||||||
感谢您使用展影云平台。
|
|
||||||
</div>
|
|
||||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
|
||||||
{1},验证码是: <span style="font-weight:bold">{2}</span>。
|
|
||||||
</div>
|
|
||||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
|
||||||
请在3分钟内输入该验证码,进行后续操作
|
|
||||||
</div>
|
|
||||||
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
|
||||||
<div>祝您顺利!</div>
|
|
||||||
<div style="font-size: 14px;">{company}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang='en'>
|
|
||||||
<head>
|
|
||||||
<meta charset='UTF-8'>
|
|
||||||
<title>Title</title>
|
|
||||||
</head>
|
|
||||||
<body style='font-family: 微软雅黑;padding: 0;margin: 0;'>
|
|
||||||
<div style='padding-left: 40px;background: #f6f6f6'>
|
|
||||||
<div style='padding-top: 20px;'>
|
|
||||||
<div style='line-height: 40px;font-size: 18px'>
|
|
||||||
Dear {0},
|
|
||||||
</div>
|
|
||||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
|
||||||
{1}
|
|
||||||
</div>
|
|
||||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
|
||||||
The verification code is <span style="font-weight:bold">{2}</span>.
|
|
||||||
</div>
|
|
||||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
|
||||||
This code will expire in 3 minutes.
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
|
||||||
<div>Best regards,</div>
|
|
||||||
<div style="font-size: 14px;">{company}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -31,9 +31,9 @@ namespace IRaCIS.Core.Application.Auth
|
|||||||
Id = user.Id,
|
Id = user.Id,
|
||||||
FullName = user.UserName,
|
FullName = user.UserName,
|
||||||
RealName = user.RealName,
|
RealName = user.RealName,
|
||||||
UserTypeEnum=user.UserTypeEnum,
|
UserTypeEnum = user.UserTypeEnum,
|
||||||
UserTypeId=user.UserTypeId,
|
UserTypeId = user.UserTypeId,
|
||||||
IsTestUser=user.IsTestUser,
|
IsTestUser = user.IsTestUser,
|
||||||
Code = user.Code,
|
Code = user.Code,
|
||||||
PermissionStr = user.PermissionStr,
|
PermissionStr = user.PermissionStr,
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,4 @@
|
|||||||
using System;
|
namespace IRaCIS.Core.Application.Auth
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace IRaCIS.Core.Application.Auth
|
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
using System.Collections.Generic;
|
using Microsoft.IdentityModel.Tokens;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Microsoft.IdentityModel.Tokens;
|
|
||||||
|
|
||||||
namespace IRaCIS.Core.Application.Auth
|
namespace IRaCIS.Core.Application.Auth
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
using System.IdentityModel.Tokens.Jwt;
|
using IRaCIS.Core.Domain.Share;
|
||||||
using System.Security.Claims;
|
|
||||||
using IRaCIS.Core.Domain.Share;
|
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
|
using System.IdentityModel.Tokens.Jwt;
|
||||||
|
using System.Security.Claims;
|
||||||
|
|
||||||
namespace IRaCIS.Core.Application.Auth
|
namespace IRaCIS.Core.Application.Auth
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,16 +1,10 @@
|
|||||||
using Hangfire;
|
using Hangfire;
|
||||||
using Hangfire.Storage;
|
using Hangfire.Storage;
|
||||||
using IRaCIS.Core.Application.Helper;
|
using IRaCIS.Core.Application.Helper;
|
||||||
using IRaCIS.Core.Application.Service;
|
|
||||||
using IRaCIS.Core.Domain.Share;
|
using IRaCIS.Core.Domain.Share;
|
||||||
using IRaCIS.Core.Infrastructure;
|
|
||||||
using Microsoft.Extensions.Configuration;
|
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Newtonsoft.Json;
|
|
||||||
using SharpCompress.Common;
|
|
||||||
using ZiggyCreatures.Caching.Fusion;
|
|
||||||
|
|
||||||
namespace IRaCIS.Application.Services.BackGroundJob
|
namespace IRaCIS.Core.Application.Service.BackGroundJob
|
||||||
{
|
{
|
||||||
|
|
||||||
public interface IIRaCISHangfireJob
|
public interface IIRaCISHangfireJob
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
using IRaCIS.Core.Infra.EFCore;
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
|
|
||||||
namespace IRaCIS.Core.Application.BackGroundJob
|
namespace IRaCIS.Core.Application.BackGroundJob
|
||||||
{
|
{
|
||||||
public interface IObtainTaskAutoCancelJob
|
public interface IObtainTaskAutoCancelJob
|
||||||
{
|
{
|
||||||
Task CancelQCObtaion(Guid subjectVisitId,DateTime startTime);
|
Task CancelQCObtaion(Guid subjectVisitId, DateTime startTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ObtainTaskAutoCancelJob : IObtainTaskAutoCancelJob
|
public class ObtainTaskAutoCancelJob : IObtainTaskAutoCancelJob
|
||||||
@@ -30,7 +29,7 @@ namespace IRaCIS.Core.Application.BackGroundJob
|
|||||||
|
|
||||||
var success = await _subjectVisitRepository.SaveChangesAsync();
|
var success = await _subjectVisitRepository.SaveChangesAsync();
|
||||||
|
|
||||||
_logger.LogWarning($"任务建立时间:{startTime} 取消时间:{DateTime.Now} 取消 受试者访视:{ subjectVisitId }success:{success}");
|
_logger.LogWarning($"任务建立时间:{startTime} 取消时间:{DateTime.Now} 取消 受试者访视:{subjectVisitId}success:{success}");
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,17 +1,16 @@
|
|||||||
using AutoMapper;
|
using AutoMapper;
|
||||||
using IRaCIS.Application.Services.BusinessFilter;
|
using IRaCIS.Core.Application.Service.BusinessFilter;
|
||||||
using IRaCIS.Core.Infra.EFCore;
|
using IRaCIS.Core.Domain.Share;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.Extensions.Localization;
|
using Microsoft.Extensions.Localization;
|
||||||
using Panda.DynamicWebApi;
|
using Panda.DynamicWebApi;
|
||||||
using Panda.DynamicWebApi.Attributes;
|
using Panda.DynamicWebApi.Attributes;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using IRaCIS.Core.Domain.Share;
|
|
||||||
using Microsoft.AspNetCore.Mvc;
|
|
||||||
using ZiggyCreatures.Caching.Fusion;
|
using ZiggyCreatures.Caching.Fusion;
|
||||||
|
|
||||||
namespace IRaCIS.Core.Application
|
namespace IRaCIS.Core.Application.Service
|
||||||
{
|
{
|
||||||
|
|
||||||
#pragma warning disable CS8618
|
#pragma warning disable CS8618
|
||||||
|
|||||||
@@ -1,71 +0,0 @@
|
|||||||
using IRaCIS.Core.Domain.Share;
|
|
||||||
using Microsoft.AspNetCore.Mvc;
|
|
||||||
using Microsoft.AspNetCore.Mvc.Filters;
|
|
||||||
using Microsoft.Extensions.Options;
|
|
||||||
using Newtonsoft.Json;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace IRaCIS.Core.Application.BusinessFilter
|
|
||||||
{
|
|
||||||
public class EncreptApiResultFilter : IAsyncResultFilter
|
|
||||||
{
|
|
||||||
|
|
||||||
private readonly IOptionsMonitor<EncreptResponseOption> _encreptResponseMonitor;
|
|
||||||
|
|
||||||
public EncreptApiResultFilter(IOptionsMonitor<EncreptResponseOption> encreptResponseMonitor)
|
|
||||||
{
|
|
||||||
_encreptResponseMonitor = encreptResponseMonitor;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task OnResultExecutionAsync(ResultExecutingContext context, ResultExecutionDelegate next)
|
|
||||||
{
|
|
||||||
|
|
||||||
if(_encreptResponseMonitor.CurrentValue.IsEnable)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (context.Result is ObjectResult objectResult)
|
|
||||||
{
|
|
||||||
var statusCode = objectResult.StatusCode ?? context.HttpContext.Response.StatusCode;
|
|
||||||
|
|
||||||
var objectValue = objectResult.Value;
|
|
||||||
|
|
||||||
|
|
||||||
if (objectValue is IResponseOutput)
|
|
||||||
{
|
|
||||||
var responseOutput = objectValue as IResponseOutput<object>;
|
|
||||||
|
|
||||||
var path = context.HttpContext?.Request.Path.Value?.ToLower();
|
|
||||||
|
|
||||||
|
|
||||||
if(!string.IsNullOrEmpty(path) && path.Length>5 && _encreptResponseMonitor.CurrentValue.ApiPathList.Contains(path.ToLower()))
|
|
||||||
{
|
|
||||||
|
|
||||||
if(responseOutput.IsSuccess)
|
|
||||||
{
|
|
||||||
responseOutput.Code = ApiResponseCodeEnum.ResultEncrepted;
|
|
||||||
responseOutput.Data = JsonConvert.SerializeObject(Convert.ToBase64String(Encoding.UTF8.GetBytes(responseOutput.Data.ToString())));
|
|
||||||
|
|
||||||
objectResult.Value = responseOutput;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
await next.Invoke();
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
using IRaCIS.Core.Domain.Share;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.AspNetCore.Mvc.Filters;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace IRaCIS.Core.Application.BusinessFilter;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 测试加密API 返回的结果
|
||||||
|
/// </summary>
|
||||||
|
public class EncreptApiResultFilter : IAsyncResultFilter
|
||||||
|
{
|
||||||
|
private readonly IOptionsMonitor<IRCEncreptOption> _encreptResponseMonitor;
|
||||||
|
|
||||||
|
public EncreptApiResultFilter(IOptionsMonitor<IRCEncreptOption> encreptResponseMonitor)
|
||||||
|
{
|
||||||
|
_encreptResponseMonitor = encreptResponseMonitor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task OnResultExecutionAsync(ResultExecutingContext context, ResultExecutionDelegate next)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (_encreptResponseMonitor.CurrentValue.IsResponseEncreptEnable)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (context.Result is ObjectResult objectResult)
|
||||||
|
{
|
||||||
|
var statusCode = objectResult.StatusCode ?? context.HttpContext.Response.StatusCode;
|
||||||
|
|
||||||
|
var objectValue = objectResult.Value;
|
||||||
|
|
||||||
|
|
||||||
|
if (objectValue is IResponseOutput)
|
||||||
|
{
|
||||||
|
var responseOutput = objectValue as IResponseOutput<object>;
|
||||||
|
|
||||||
|
var path = context.HttpContext?.Request.Path.Value?.ToLower();
|
||||||
|
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(path) && path.Length > 5 && _encreptResponseMonitor.CurrentValue.ApiPathList.Contains(path.ToLower()))
|
||||||
|
{
|
||||||
|
|
||||||
|
if (responseOutput.IsSuccess)
|
||||||
|
{
|
||||||
|
responseOutput.Code = ApiResponseCodeEnum.ResultEncrepted;
|
||||||
|
responseOutput.Data = JsonConvert.SerializeObject(Convert.ToBase64String(Encoding.UTF8.GetBytes(responseOutput.Data.ToString())));
|
||||||
|
|
||||||
|
objectResult.Value = responseOutput;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
await next.Invoke();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,130 @@
|
|||||||
|
using IRaCIS.Core.Domain.Share;
|
||||||
|
using IRaCIS.Core.Infrastructure.Encryption;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace IRaCIS.Core.Application.BusinessFilter;
|
||||||
|
|
||||||
|
public class EncryptionRequestMiddleware
|
||||||
|
{
|
||||||
|
private readonly RequestDelegate _next;
|
||||||
|
|
||||||
|
private readonly IRCEncreptOption _IRCEncreptOption;
|
||||||
|
|
||||||
|
public EncryptionRequestMiddleware(RequestDelegate next, IOptionsMonitor<IRCEncreptOption> encreptResponseMonitor)
|
||||||
|
{
|
||||||
|
_next = next;
|
||||||
|
|
||||||
|
_IRCEncreptOption = encreptResponseMonitor.CurrentValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task InvokeAsync(HttpContext context)
|
||||||
|
{
|
||||||
|
//模拟前端已经设置该请求头
|
||||||
|
//context.Request.Headers["X-Encrypted-Key"] = "hW8JuJocBzIPWSHURUnYJMZ0l68g6uP9rEdMho8ioFO8amD6GIH+R6RIX5jVFzOwO+lmgBi+4gaVJGGkWJMTcoDTfzzzT1EmfPV+UhFLE9HWvCkEXmDOLE9xCHrbG8TrR1I9+Qd3cvo9HLmrQ58n13cJsM82FBw+reUgiWeklPCkEWM9br2qc9VkCp6gKzimTldNTWBezV86S6j3qHbZpVZm0atdDtGb+zSC9LLA3+oHQwRLJAAGSOAi8CUiRmIQsygRd824wBndkaH2ImEeRjBMs7PqCeK3KsoDp13yHdj2AE751gsfNzf4SF547UPf72m0F2/rBFgrSNy+Jz0T9w==";
|
||||||
|
|
||||||
|
// 检查请求头中是否包含加密的对称密钥
|
||||||
|
if (context.Request.Headers.ContainsKey("X-Encrypted-Key"))
|
||||||
|
{
|
||||||
|
|
||||||
|
var encryptedSymmetricKeyStr = context.Request.Headers["X-Encrypted-Key"].ToString();
|
||||||
|
|
||||||
|
var pemSecretKey = Encoding.UTF8.GetString(Convert.FromBase64String(_IRCEncreptOption.Base64RSAPrivateKey));
|
||||||
|
|
||||||
|
// 使用私钥解密对称密钥
|
||||||
|
var decryptedSymmetricKey = RSAEncryption.Decrypt(pemSecretKey, encryptedSymmetricKeyStr);
|
||||||
|
|
||||||
|
|
||||||
|
#region 处理路径传递参数
|
||||||
|
|
||||||
|
// 处理路径参数解密
|
||||||
|
var path = context.Request.Path.Value;
|
||||||
|
|
||||||
|
// 假设加密的参数在路径中,按照顺序解密路径中的每个部分
|
||||||
|
var pathSegments = path.Split('/', StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
for (int i = 2; i < pathSegments.Length; i++)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(pathSegments[i]))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var decryptedSegment = AesEncryption.Decrypt(pathSegments[i], decryptedSymmetricKey);
|
||||||
|
pathSegments[i] = decryptedSegment;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// 如果不能解密该部分,保持原值
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 将解密后的路径重新拼接并设置到请求的Path
|
||||||
|
context.Request.Path = "/" + string.Join("/", pathSegments);
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region 处理url 传递参数
|
||||||
|
|
||||||
|
// 处理 URL 查询参数的解密
|
||||||
|
var queryParams = context.Request.Query.ToDictionary(kvp => kvp.Key, kvp => kvp.Value.ToString());
|
||||||
|
var decryptedQueryParams = new Dictionary<string, string>();
|
||||||
|
|
||||||
|
foreach (var param in queryParams)
|
||||||
|
{
|
||||||
|
var encryptedValue = param.Value;
|
||||||
|
var decryptedValue = AesEncryption.Decrypt(encryptedValue, decryptedSymmetricKey);
|
||||||
|
decryptedQueryParams[param.Key] = decryptedValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构造解密后的查询字符串
|
||||||
|
var decryptedQueryString = new QueryString("?" + string.Join("&", decryptedQueryParams.Select(kvp => $"{kvp.Key}={kvp.Value}")));
|
||||||
|
context.Request.QueryString = decryptedQueryString;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region 处理body传参
|
||||||
|
|
||||||
|
// 读取并解密请求体中的JSON数据
|
||||||
|
context.Request.EnableBuffering();
|
||||||
|
using (var reader = new StreamReader(context.Request.Body, Encoding.UTF8, leaveOpen: true))
|
||||||
|
{
|
||||||
|
var encryptedBody = await reader.ReadToEndAsync();
|
||||||
|
context.Request.Body.Position = 0;
|
||||||
|
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(encryptedBody))
|
||||||
|
{
|
||||||
|
// 尝试解析为JObject
|
||||||
|
var encryptedJson = JObject.Parse(encryptedBody);
|
||||||
|
var decryptedJson = new JObject();
|
||||||
|
|
||||||
|
// 解密每个字段的值
|
||||||
|
foreach (var property in encryptedJson.Properties())
|
||||||
|
{
|
||||||
|
var encryptedValue = property.Value.ToString();
|
||||||
|
var decryptedValue = AesEncryption.Decrypt(encryptedValue, decryptedSymmetricKey);
|
||||||
|
decryptedJson[property.Name] = decryptedValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 将解密后的JSON对象转换回字符串,并替换原始请求体
|
||||||
|
var decryptedBody = decryptedJson.ToString();
|
||||||
|
var bodyStream = new MemoryStream(Encoding.UTF8.GetBytes(decryptedBody));
|
||||||
|
context.Request.Body = bodyStream;
|
||||||
|
context.Request.ContentLength = bodyStream.Length;
|
||||||
|
bodyStream.Seek(0, SeekOrigin.Begin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
// 调用下一个中间件
|
||||||
|
await _next(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,22 +1,16 @@
|
|||||||
using Microsoft.AspNetCore.Diagnostics;
|
using Microsoft.AspNetCore.Diagnostics;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Newtonsoft.Json;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
|
|
||||||
namespace IRaCIS.Core.Application.BusinessFilter
|
namespace IRaCIS.Core.Application.BusinessFilter;
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 不生效,不知道为啥
|
||||||
|
/// </summary>
|
||||||
|
public class GlobalExceptionHandler : IExceptionHandler
|
||||||
{
|
{
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 不生效,不知道为啥
|
|
||||||
/// </summary>
|
|
||||||
public class GlobalExceptionHandler : IExceptionHandler
|
|
||||||
{
|
|
||||||
private readonly ILogger<GlobalExceptionHandler> _logger;
|
private readonly ILogger<GlobalExceptionHandler> _logger;
|
||||||
public GlobalExceptionHandler(ILogger<GlobalExceptionHandler> logger)
|
public GlobalExceptionHandler(ILogger<GlobalExceptionHandler> logger)
|
||||||
{
|
{
|
||||||
@@ -46,5 +40,4 @@ namespace IRaCIS.Core.Application.BusinessFilter
|
|||||||
// return true to signal that this exception is handled
|
// return true to signal that this exception is handled
|
||||||
return ValueTask.FromResult(false);
|
return ValueTask.FromResult(false);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,11 @@
|
|||||||
using IRaCIS.Core.Application.Helper;
|
using IRaCIS.Core.Application.Helper;
|
||||||
using IRaCIS.Core.Domain.Share;
|
using IRaCIS.Core.Domain.Share;
|
||||||
using Microsoft.AspNetCore.Authentication;
|
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.AspNetCore.Mvc.Filters;
|
using Microsoft.AspNetCore.Mvc.Filters;
|
||||||
using Microsoft.Extensions.Localization;
|
using Microsoft.Extensions.Localization;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using Newtonsoft.Json;
|
|
||||||
using ZiggyCreatures.Caching.Fusion;
|
using ZiggyCreatures.Caching.Fusion;
|
||||||
|
|
||||||
namespace IRaCIS.Core.Application.Filter;
|
namespace IRaCIS.Core.Application.Filter;
|
||||||
@@ -25,7 +23,7 @@ public class LimitUserRequestAuthorization : IAsyncAuthorizationFilter
|
|||||||
|
|
||||||
private readonly IOptionsMonitor<ServiceVerifyConfigOption> _verifyConfig;
|
private readonly IOptionsMonitor<ServiceVerifyConfigOption> _verifyConfig;
|
||||||
|
|
||||||
public LimitUserRequestAuthorization(IFusionCache fusionCache, IUserInfo userInfo, IStringLocalizer localizer ,IOptionsMonitor<ServiceVerifyConfigOption> verifyConfig)
|
public LimitUserRequestAuthorization(IFusionCache fusionCache, IUserInfo userInfo, IStringLocalizer localizer, IOptionsMonitor<ServiceVerifyConfigOption> verifyConfig)
|
||||||
{
|
{
|
||||||
_fusionCache = fusionCache;
|
_fusionCache = fusionCache;
|
||||||
_userInfo = userInfo;
|
_userInfo = userInfo;
|
||||||
|
|||||||
@@ -1,16 +1,15 @@
|
|||||||
using IRaCIS.Core.Infrastructure.Extention;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
|
||||||
using Microsoft.AspNetCore.Mvc.Filters;
|
using Microsoft.AspNetCore.Mvc.Filters;
|
||||||
using Microsoft.Extensions.Localization;
|
using Microsoft.Extensions.Localization;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
|
||||||
namespace IRaCIS.Core.Application.Filter
|
namespace IRaCIS.Core.Application.Filter;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public class ModelActionFilter : ActionFilterAttribute, IActionFilter
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
public class ModelActionFilter : ActionFilterAttribute, IActionFilter
|
|
||||||
{
|
|
||||||
public IStringLocalizer _localizer;
|
public IStringLocalizer _localizer;
|
||||||
public ModelActionFilter(IStringLocalizer localizer)
|
public ModelActionFilter(IStringLocalizer localizer)
|
||||||
{
|
{
|
||||||
@@ -29,9 +28,7 @@ namespace IRaCIS.Core.Application.Filter
|
|||||||
.ToArray();
|
.ToArray();
|
||||||
|
|
||||||
//---提供给接口的参数无效。
|
//---提供给接口的参数无效。
|
||||||
context.Result = new JsonResult(ResponseOutput.NotOk(_localizer["ModelAction_InvalidAPIParameter"] + JsonConvert.SerializeObject( validationErrors)));
|
context.Result = new JsonResult(ResponseOutput.NotOk(_localizer["ModelAction_InvalidAPIParameter"] + JsonConvert.SerializeObject(validationErrors)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,13 @@
|
|||||||
using System;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.Mvc.Filters;
|
using Microsoft.AspNetCore.Mvc.Filters;
|
||||||
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
||||||
|
|
||||||
namespace IRaCIS.Core.Application.Filter
|
namespace IRaCIS.Core.Application.Filter;
|
||||||
|
|
||||||
|
#region snippet_DisableFormValueModelBindingAttribute
|
||||||
|
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
|
||||||
|
public class DisableFormValueModelBindingAttribute : Attribute, IResourceFilter
|
||||||
{
|
{
|
||||||
#region snippet_DisableFormValueModelBindingAttribute
|
|
||||||
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
|
|
||||||
public class DisableFormValueModelBindingAttribute : Attribute, IResourceFilter
|
|
||||||
{
|
|
||||||
public void OnResourceExecuting(ResourceExecutingContext context)
|
public void OnResourceExecuting(ResourceExecutingContext context)
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -23,6 +22,5 @@ namespace IRaCIS.Core.Application.Filter
|
|||||||
public void OnResourceExecuted(ResourceExecutedContext context)
|
public void OnResourceExecuted(ResourceExecutedContext context)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
}
|
}
|
||||||
|
#endregion
|
||||||
|
|||||||
@@ -1,15 +1,14 @@
|
|||||||
using IRaCIS.Core.Domain.Share;
|
using IRaCIS.Core.Domain.Share;
|
||||||
using IRaCIS.Core.Infrastructure;
|
using IRaCIS.Core.Infrastructure;
|
||||||
using IRaCIS.Core.Infrastructure.Extention;
|
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.AspNetCore.Mvc.Filters;
|
using Microsoft.AspNetCore.Mvc.Filters;
|
||||||
using Microsoft.Extensions.Localization;
|
using Microsoft.Extensions.Localization;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
namespace IRaCIS.Core.Application.Filter
|
namespace IRaCIS.Core.Application.Filter;
|
||||||
|
|
||||||
|
public class ProjectExceptionFilter : Attribute, IExceptionFilter
|
||||||
{
|
{
|
||||||
public class ProjectExceptionFilter : Attribute, IExceptionFilter
|
|
||||||
{
|
|
||||||
private readonly ILogger<ProjectExceptionFilter> _logger;
|
private readonly ILogger<ProjectExceptionFilter> _logger;
|
||||||
|
|
||||||
public IStringLocalizer _localizer;
|
public IStringLocalizer _localizer;
|
||||||
@@ -73,5 +72,4 @@ namespace IRaCIS.Core.Application.Filter
|
|||||||
//继续
|
//继续
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,13 +8,13 @@ using System.Text.RegularExpressions;
|
|||||||
using ZiggyCreatures.Caching.Fusion;
|
using ZiggyCreatures.Caching.Fusion;
|
||||||
using static IRaCIS.Core.Domain.Share.StaticData;
|
using static IRaCIS.Core.Domain.Share.StaticData;
|
||||||
|
|
||||||
namespace IRaCIS.Core.Application.Filter
|
namespace IRaCIS.Core.Application.Filter;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 主要为了 处理项目结束 锁库,不允许操作
|
||||||
|
/// </summary>
|
||||||
|
public class TrialResourceFilter : Attribute, IAsyncResourceFilter
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// 主要为了 处理项目结束 锁库,不允许操作
|
|
||||||
/// </summary>
|
|
||||||
public class TrialResourceFilter : Attribute, IAsyncResourceFilter
|
|
||||||
{
|
|
||||||
private readonly IUserInfo _userInfo;
|
private readonly IUserInfo _userInfo;
|
||||||
private readonly IFusionCache _fusionCache;
|
private readonly IFusionCache _fusionCache;
|
||||||
public IStringLocalizer _localizer;
|
public IStringLocalizer _localizer;
|
||||||
@@ -41,6 +41,17 @@ namespace IRaCIS.Core.Application.Filter
|
|||||||
// var typeFilter = context.ActionDescriptor.EndpointMetadata.Where(t => t.GetType() == typeof(TypeFilterAttribute)).Select(t => (TypeFilterAttribute)t).ToList().FirstOrDefault();
|
// var typeFilter = context.ActionDescriptor.EndpointMetadata.Where(t => t.GetType() == typeof(TypeFilterAttribute)).Select(t => (TypeFilterAttribute)t).ToList().FirstOrDefault();
|
||||||
//var _trialOptList= typeFilter.Arguments.Select(t => t.ToString()).ToList();
|
//var _trialOptList= typeFilter.Arguments.Select(t => t.ToString()).ToList();
|
||||||
|
|
||||||
|
// 获取当前请求的 Host 信息
|
||||||
|
var requestHost = context.HttpContext.Request.Host;
|
||||||
|
|
||||||
|
// 检查请求是否来自 localhost:6100
|
||||||
|
if (requestHost.Host == "localhost" && (requestHost.Port == 6100|| requestHost.Port==3305))
|
||||||
|
{
|
||||||
|
await next.Invoke();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
#region 处理新的用户类型,不能操作项目相关接口
|
#region 处理新的用户类型,不能操作项目相关接口
|
||||||
|
|
||||||
// 后期列举出具体的类型,其他任何用户类型,都不允许操作
|
// 后期列举出具体的类型,其他任何用户类型,都不允许操作
|
||||||
@@ -123,14 +134,19 @@ namespace IRaCIS.Core.Application.Filter
|
|||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(trialStatusStr))
|
if (string.IsNullOrWhiteSpace(trialStatusStr))
|
||||||
{
|
{
|
||||||
|
|
||||||
//数据库 检查该项目Id不对
|
//数据库 检查该项目Id不对
|
||||||
context.Result = new JsonResult(ResponseOutput.NotOk(_localizer["TrialResource_ReferTrialIdFailed"]));
|
context.Result = new JsonResult(ResponseOutput.NotOk(_localizer["TrialResource_ReferTrialIdFailed"]));
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//---正则取请求Refer 中trialId 失败,请联系开发人员核查
|
//---正则取请求Refer 中trialId 失败,请联系开发人员核查
|
||||||
context.Result = new JsonResult(ResponseOutput.NotOk(_localizer["TrialResource_ReferTrialIdFailed"]));
|
context.Result = new JsonResult(ResponseOutput.NotOk(_localizer["TrialResource_ReferTrialIdFailed"]));
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//使用字符串取 如果是swagger 可能有时取的不对 因为空格的原因
|
//使用字符串取 如果是swagger 可能有时取的不对 因为空格的原因
|
||||||
@@ -176,6 +192,5 @@ namespace IRaCIS.Core.Application.Filter
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
using Microsoft.AspNetCore.Mvc.Filters;
|
using IRaCIS.Core.Domain.Share;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using IRaCIS.Core.Domain.Share;
|
using Microsoft.AspNetCore.Mvc.Filters;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
namespace IRaCIS.Application.Services.BusinessFilter
|
namespace IRaCIS.Core.Application.Service.BusinessFilter;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 统一返回前端数据包装,之前在控制器包装,现在修改为动态Api 在ResultFilter这里包装,减少重复冗余代码
|
||||||
|
/// by zhouhang 2021.09.12 周末
|
||||||
|
/// </summary>
|
||||||
|
public class UnifiedApiResultFilter : Attribute, IAsyncResultFilter
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// 统一返回前端数据包装,之前在控制器包装,现在修改为动态Api 在ResultFilter这里包装,减少重复冗余代码
|
|
||||||
/// by zhouhang 2021.09.12 周末
|
|
||||||
/// </summary>
|
|
||||||
public class UnifiedApiResultFilter : Attribute, IAsyncResultFilter
|
|
||||||
{
|
|
||||||
private readonly ILogger _logger;
|
private readonly ILogger _logger;
|
||||||
|
|
||||||
public UnifiedApiResultFilter(ILogger<UnifiedApiResultFilter> logger)
|
public UnifiedApiResultFilter(ILogger<UnifiedApiResultFilter> logger)
|
||||||
@@ -119,5 +119,4 @@ namespace IRaCIS.Application.Services.BusinessFilter
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,164 @@
|
|||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
|
using Microsoft.Extensions.Configuration.Json;
|
||||||
|
using System.ComponentModel;
|
||||||
|
|
||||||
|
namespace IRaCIS.Core.Domain.Share;
|
||||||
|
|
||||||
|
[Description("多环境 配置环境实体")]
|
||||||
|
public class ServiceVerifyConfigOption
|
||||||
|
{
|
||||||
|
public bool OpenUserComplexPassword { get; set; }
|
||||||
|
|
||||||
|
public bool OpenSignDocumentBeforeWork { get; set; }
|
||||||
|
|
||||||
|
public bool OpenTrialRelationDelete { get; set; }
|
||||||
|
|
||||||
|
public bool OpenLoginLimit { get; set; }
|
||||||
|
|
||||||
|
public int LoginMaxFailCount { get; set; }
|
||||||
|
|
||||||
|
public int LoginFailLockMinutes { get; set; }
|
||||||
|
|
||||||
|
public int AutoLoginOutMinutes { get; set; }
|
||||||
|
|
||||||
|
public bool OpenLoginMFA { get; set; }
|
||||||
|
|
||||||
|
[Description("连续阅片时间 (min)")]
|
||||||
|
public int ContinuousReadingTimeMin { get; set; }
|
||||||
|
|
||||||
|
[Description("休息时间 (min)")]
|
||||||
|
public int ReadingRestTimeMin { get; set; }
|
||||||
|
[Description("是否需要修改密码")]
|
||||||
|
public bool IsNeedChangePassWord { get; set; }
|
||||||
|
|
||||||
|
[Description("修改密码的天数")]
|
||||||
|
public int ChangePassWordDays { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class SystemEmailSendConfig
|
||||||
|
{
|
||||||
|
public int Port { get; set; }
|
||||||
|
|
||||||
|
public string Host { get; set; } = string.Empty;
|
||||||
|
public string FromEmail { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public string FromName { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public string AuthorizationCode { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public string SiteUrl { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public string OrganizationName { get; set; } = string.Empty;
|
||||||
|
public string OrganizationNameCN { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public string CompanyName { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public string CompanyNameCN { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public string CompanyShortName { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public string CompanyShortNameCN { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public bool IsEnv_US { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class SystemEmailSendConfigView
|
||||||
|
{
|
||||||
|
public string CompanyName { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public string CompanyNameCN { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public string CompanyShortName { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public string CompanyShortNameCN { get; set; } = string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class SystemPacsConfig
|
||||||
|
{
|
||||||
|
public int Port { get; set; }
|
||||||
|
|
||||||
|
public string IP { get; set; } = string.Empty;
|
||||||
|
}
|
||||||
|
public class IRCEncreptOption
|
||||||
|
{
|
||||||
|
public string Base64RSAPublicKey { get; set; }
|
||||||
|
|
||||||
|
public string Base64RSAPrivateKey { get; set; }
|
||||||
|
public bool IsResponseEncreptEnable { get; set; }
|
||||||
|
|
||||||
|
public List<string> ApiPathList { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class IRaCISBasicConfigOption
|
||||||
|
{
|
||||||
|
public string DoctorCodePrefix { get; set; }
|
||||||
|
public string UserCodePrefix { get; set; }
|
||||||
|
public string QCChallengeCodePrefix { get; set; }
|
||||||
|
public string DicomStudyCodePrefix { get; set; }
|
||||||
|
public string TaskStudyCodePrefix { get; set; }
|
||||||
|
public string NoneDicomStudyCodePrefix { get; set; }
|
||||||
|
public int ImageShareExpireDays { get; set; }
|
||||||
|
public string SystemSiteCodePrefix { get; set; }
|
||||||
|
public string BlindTaskPrefix { get; set; }
|
||||||
|
public string DefaultPassword { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
[Description("项目基础配置规则")]
|
||||||
|
public static class AppSettings
|
||||||
|
{
|
||||||
|
|
||||||
|
public static IRaCISBasicConfigOption IRaCISBasicConfig { get; set; }
|
||||||
|
|
||||||
|
static AppSettings()
|
||||||
|
{
|
||||||
|
var configuration = new ConfigurationBuilder()
|
||||||
|
.Add(new JsonConfigurationSource
|
||||||
|
{
|
||||||
|
Path = "appsettings.json",
|
||||||
|
ReloadOnChange = true
|
||||||
|
})
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
// 手动绑定配置
|
||||||
|
var appSettings = new IRaCISBasicConfigOption();
|
||||||
|
configuration.GetSection("IRaCISBasicConfig").Bind(appSettings);
|
||||||
|
|
||||||
|
IRaCISBasicConfig = appSettings;
|
||||||
|
}
|
||||||
|
//获取实体编码字符串
|
||||||
|
public static string GetCodeStr(int codeInt, string typeStr)
|
||||||
|
{
|
||||||
|
switch (typeStr)
|
||||||
|
{
|
||||||
|
case nameof(Doctor):
|
||||||
|
return IRaCISBasicConfig.DoctorCodePrefix + codeInt.ToString("D4");
|
||||||
|
|
||||||
|
case nameof(User):
|
||||||
|
return IRaCISBasicConfig.UserCodePrefix + codeInt.ToString("D4");
|
||||||
|
|
||||||
|
case nameof(QCChallenge):
|
||||||
|
return IRaCISBasicConfig.QCChallengeCodePrefix + codeInt.ToString("D5");
|
||||||
|
|
||||||
|
case nameof(NoneDicomStudy):
|
||||||
|
return IRaCISBasicConfig.NoneDicomStudyCodePrefix + codeInt.ToString("D5");
|
||||||
|
|
||||||
|
case nameof(DicomStudy):
|
||||||
|
return IRaCISBasicConfig.DicomStudyCodePrefix + codeInt.ToString("D5");
|
||||||
|
|
||||||
|
case nameof(TaskStudy):
|
||||||
|
return IRaCISBasicConfig.TaskStudyCodePrefix + codeInt.ToString("D5");
|
||||||
|
|
||||||
|
case nameof(VisitTask):
|
||||||
|
return "W" + codeInt.ToString("D5");
|
||||||
|
|
||||||
|
case nameof(Site):
|
||||||
|
return IRaCISBasicConfig.SystemSiteCodePrefix + codeInt.ToString("D4");
|
||||||
|
|
||||||
|
default:
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
global using AutoMapper.QueryableExtensions;
|
||||||
|
global using IRaCIS.Core.Application.Service;
|
||||||
|
global using IRaCIS.Core.Domain.Models;
|
||||||
|
global using IRaCIS.Core.Infra.EFCore;
|
||||||
|
global using IRaCIS.Core.Infrastructure.Extention;
|
||||||
|
global using Microsoft.EntityFrameworkCore;
|
||||||
|
global using System.Linq.Expressions;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,9 +1,4 @@
|
|||||||
using IRaCIS.Core.Domain.Share;
|
using IRaCIS.Core.Domain.Share;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace IRaCIS.Core.Application.Helper
|
namespace IRaCIS.Core.Application.Helper
|
||||||
{
|
{
|
||||||
@@ -19,9 +14,9 @@ namespace IRaCIS.Core.Application.Helper
|
|||||||
|
|
||||||
|
|
||||||
//是否翻译依赖其他属性
|
//是否翻译依赖其他属性
|
||||||
public bool IsTranslateDenpendOtherProperty =>!string.IsNullOrWhiteSpace(DependPropertyName);
|
public bool IsTranslateDenpendOtherProperty => !string.IsNullOrWhiteSpace(DependPropertyName);
|
||||||
|
|
||||||
public string DependPropertyName { get; set; }=string.Empty;
|
public string DependPropertyName { get; set; } = string.Empty;
|
||||||
|
|
||||||
public string DependPropertyValueStr { get; set; } = string.Empty;
|
public string DependPropertyValueStr { get; set; } = string.Empty;
|
||||||
|
|
||||||
@@ -33,7 +28,7 @@ namespace IRaCIS.Core.Application.Helper
|
|||||||
}
|
}
|
||||||
|
|
||||||
//针对不同的标准 翻译的字典不一样
|
//针对不同的标准 翻译的字典不一样
|
||||||
public DictionaryTranslateAttribute(string dicParentCode, CriterionType criterionType )
|
public DictionaryTranslateAttribute(string dicParentCode, CriterionType criterionType)
|
||||||
{
|
{
|
||||||
DicParentCode = dicParentCode;
|
DicParentCode = dicParentCode;
|
||||||
|
|
||||||
@@ -42,7 +37,7 @@ namespace IRaCIS.Core.Application.Helper
|
|||||||
|
|
||||||
//针对业务某个属性的值 不一样 用的翻译字典不一样
|
//针对业务某个属性的值 不一样 用的翻译字典不一样
|
||||||
|
|
||||||
public DictionaryTranslateAttribute(string dicParentCode,string dependPropertyName, string dependPropertyValueStr)
|
public DictionaryTranslateAttribute(string dicParentCode, string dependPropertyName, string dependPropertyValueStr)
|
||||||
{
|
{
|
||||||
DicParentCode = dicParentCode;
|
DicParentCode = dicParentCode;
|
||||||
|
|
||||||
|
|||||||
@@ -1,27 +1,24 @@
|
|||||||
using IRaCIS.Core.Domain.Models;
|
namespace IRaCIS.Core.Application.Helper;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace IRaCIS.Core.Application.Helper
|
|
||||||
|
public static class CacheKeys
|
||||||
{
|
{
|
||||||
|
//项目缓存
|
||||||
public static class CacheKeys
|
|
||||||
{
|
|
||||||
public static string Trial(string trialIdStr) => $"TrialId:{trialIdStr}";
|
public static string Trial(string trialIdStr) => $"TrialId:{trialIdStr}";
|
||||||
|
|
||||||
|
//检查编号递增锁
|
||||||
public static string TrialStudyMaxCode(Guid trialId) => $"TrialStudyMaxCode:{trialId}";
|
public static string TrialStudyMaxCode(Guid trialId) => $"TrialStudyMaxCode:{trialId}";
|
||||||
|
|
||||||
public static string TrialStudyUidUploading(Guid trialId, string studyUid) => $"TrialStudyUid:{trialId}_{studyUid}";
|
public static string TrialStudyUidUploading(Guid trialId, string studyUid) => $"TrialStudyUid:{trialId}_{studyUid}";
|
||||||
|
//CRC上传影像提交锁key
|
||||||
public static string TrialStudyUidDBLock(Guid trialId, string studyUid) => $"TrialStudyUidDBLock:{trialId}_{studyUid}";
|
public static string TrialStudyUidDBLock(Guid trialId, string studyUid) => $"TrialStudyUidDBLock:{trialId}_{studyUid}";
|
||||||
|
|
||||||
|
public static string TrialTaskStudyUidUploading(Guid trialId, Guid visiTaskId, string studyUid) => $"TrialStudyUid:{trialId}_{visiTaskId}_{studyUid}";
|
||||||
|
//影像后处理上传提交锁key
|
||||||
|
public static string TrialTaskStudyUidDBLock(Guid trialId, Guid visiTaskId, string studyUid) => $"TrialTaskStudyUidDBLock:{trialId}_{visiTaskId}_{studyUid}";
|
||||||
|
//系统匿名化
|
||||||
public static string SystemAnonymization => $"SystemAnonymization";
|
public static string SystemAnonymization => $"SystemAnonymization";
|
||||||
|
//前端国际化
|
||||||
public static string FrontInternational => $"FrontInternationalList";
|
public static string FrontInternational => $"FrontInternationalList";
|
||||||
|
|
||||||
//登录挤账号
|
//登录挤账号
|
||||||
@@ -30,8 +27,6 @@ namespace IRaCIS.Core.Application.Helper
|
|||||||
//超时没请求接口自动退出
|
//超时没请求接口自动退出
|
||||||
public static string UserAutoLoginOut(Guid userId) => $"UserAutoLoginOut:{userId}";
|
public static string UserAutoLoginOut(Guid userId) => $"UserAutoLoginOut:{userId}";
|
||||||
|
|
||||||
// 你可以为其他实体和模块定义更多的键
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 跳过阅片
|
/// 跳过阅片
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -54,10 +49,10 @@ namespace IRaCIS.Core.Application.Helper
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static string StartRestTime(Guid userId) => $"{userId}StartRestTime";
|
public static string StartRestTime(Guid userId) => $"{userId}StartRestTime";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class CacheHelper
|
public static class CacheHelper
|
||||||
{
|
{
|
||||||
public static async Task<string?> GetTrialStatusAsync(Guid trialId, IRepository<Trial> _trialRepository)
|
public static async Task<string?> GetTrialStatusAsync(Guid trialId, IRepository<Trial> _trialRepository)
|
||||||
{
|
{
|
||||||
var statusStr = await _trialRepository.Where(t => t.Id == trialId, ignoreQueryFilters: true).Select(t => t.TrialStatusStr).FirstOrDefaultAsync();
|
var statusStr = await _trialRepository.Where(t => t.Id == trialId, ignoreQueryFilters: true).Select(t => t.TrialStatusStr).FirstOrDefaultAsync();
|
||||||
@@ -71,5 +66,4 @@ namespace IRaCIS.Core.Application.Helper
|
|||||||
|
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,44 +0,0 @@
|
|||||||
using NPOI.SS.Formula.Functions;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace IRaCIS.Core.Application.Helper
|
|
||||||
{
|
|
||||||
public static class EmailMaskHelper
|
|
||||||
{
|
|
||||||
|
|
||||||
//显示位数:3分之2的位数,向上取整
|
|
||||||
//取哪几个个值:最后一位和前面几位
|
|
||||||
//其他:3个***。
|
|
||||||
//比如:hlj23@126.com
|
|
||||||
//为:hlj***3@126.com
|
|
||||||
|
|
||||||
//he@126.com
|
|
||||||
//为:h*** e@126.com
|
|
||||||
|
|
||||||
public static string MaskEmail(string email)
|
|
||||||
{
|
|
||||||
|
|
||||||
// 找到 "@" 符号的位置
|
|
||||||
int atIndex = email.IndexOf('@');
|
|
||||||
|
|
||||||
string visiblePartBefore = email.Substring(0, atIndex);
|
|
||||||
|
|
||||||
string afterAt = email.Substring(atIndex + 1);
|
|
||||||
|
|
||||||
int visibleLength = (int)Math.Ceiling((double)visiblePartBefore.Length * 2 / 3);
|
|
||||||
|
|
||||||
// 替换中间两位字符为星号
|
|
||||||
string hiddenPartBeforeAt = visiblePartBefore.Substring(0, visibleLength - 1) + "***" + visiblePartBefore.Last();
|
|
||||||
|
|
||||||
|
|
||||||
// 组合隐藏和可见部分
|
|
||||||
string hiddenEmail = hiddenPartBeforeAt + "@" + afterAt;
|
|
||||||
|
|
||||||
return hiddenEmail;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,29 +1,37 @@
|
|||||||
using DocumentFormat.OpenXml.Drawing.Diagrams;
|
using IRaCIS.Application.Contracts;
|
||||||
using DocumentFormat.OpenXml.Spreadsheet;
|
|
||||||
using DocumentFormat.OpenXml.Wordprocessing;
|
|
||||||
using IRaCIS.Application.Contracts;
|
|
||||||
using IRaCIS.Application.Interfaces;
|
using IRaCIS.Application.Interfaces;
|
||||||
using IRaCIS.Core.API._ServiceExtensions.NewtonsoftJson;
|
using IRaCIS.Core.API._ServiceExtensions.NewtonsoftJson;
|
||||||
using IRaCIS.Core.Application.Helper;
|
using IRaCIS.Core.Application.Helper;
|
||||||
using IRaCIS.Core.Domain.Share;
|
using IRaCIS.Core.Domain.Share;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.Extensions.Hosting;
|
||||||
using MiniExcelLibs;
|
using MiniExcelLibs;
|
||||||
using MiniExcelLibs.OpenXml;
|
using MiniExcelLibs.OpenXml;
|
||||||
using Newtonsoft.Json;
|
|
||||||
using Newtonsoft.Json.Linq;
|
|
||||||
using NPOI.HSSF.UserModel;
|
using NPOI.HSSF.UserModel;
|
||||||
|
using NPOI.SS.Formula.Functions;
|
||||||
|
using NPOI.SS.UserModel;
|
||||||
using NPOI.XSSF.UserModel;
|
using NPOI.XSSF.UserModel;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.ComponentModel;
|
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.IO;
|
|
||||||
|
|
||||||
namespace IRaCIS.Core.Application.Service;
|
namespace IRaCIS.Core.Application.Service;
|
||||||
|
|
||||||
public static class ExcelExportHelper
|
public static class ExcelExportHelper
|
||||||
{
|
{
|
||||||
//MiniExcel_Export
|
//MiniExcel_Export
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="code"></param>
|
||||||
|
/// <param name="data"></param>
|
||||||
|
/// <param name="exportFileNamePrefix">文件名前缀</param>
|
||||||
|
/// <param name="_commonDocumentRepository"></param>
|
||||||
|
/// <param name="_hostEnvironment"></param>
|
||||||
|
/// <param name="_dictionaryService"></param>
|
||||||
|
/// <param name="translateType"></param>
|
||||||
|
/// <param name="criterionType"></param>
|
||||||
|
/// <returns></returns>
|
||||||
public static async Task<IActionResult> DataExportAsync(string code, ExcelExportInfo data, string exportFileNamePrefix, IRepository<CommonDocument> _commonDocumentRepository, IWebHostEnvironment _hostEnvironment, IDictionaryService? _dictionaryService = null, Type? translateType = null, CriterionType? criterionType = null)
|
public static async Task<IActionResult> DataExportAsync(string code, ExcelExportInfo data, string exportFileNamePrefix, IRepository<CommonDocument> _commonDocumentRepository, IWebHostEnvironment _hostEnvironment, IDictionaryService? _dictionaryService = null, Type? translateType = null, CriterionType? criterionType = null)
|
||||||
{
|
{
|
||||||
var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;
|
var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;
|
||||||
@@ -68,7 +76,7 @@ public static class ExcelExportHelper
|
|||||||
{
|
{
|
||||||
if (DateTime.TryParse(itemValuePair.Value?.ToString(), out DateTime result))
|
if (DateTime.TryParse(itemValuePair.Value?.ToString(), out DateTime result))
|
||||||
{
|
{
|
||||||
itemDic[itemValuePair.Key] = ExportExcelConverterDate.DateTimeInternationalToString(result );
|
itemDic[itemValuePair.Key] = ExportExcelConverterDate.DateTimeInternationalToString(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -348,6 +356,85 @@ public static class ExcelExportHelper
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 导出文件模板
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="inDto"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static async Task<FileResult> ExportTemplateAsync(ExportTemplateServiceDto inDto)
|
||||||
|
{
|
||||||
|
var (physicalPath, fileName) = await FileStoreHelper.GetCommonDocPhysicalFilePathAsync(inDto.hostEnvironment, inDto.commonDocumentRepository, inDto.TemplateCode);
|
||||||
|
|
||||||
|
|
||||||
|
//模板路径
|
||||||
|
var tplPath = physicalPath;
|
||||||
|
|
||||||
|
#region 根据中英文 删除模板sheet
|
||||||
|
|
||||||
|
// 打开模板文件
|
||||||
|
var templateFile = new FileStream(tplPath, FileMode.Open, FileAccess.Read);
|
||||||
|
|
||||||
|
// 获取文件流
|
||||||
|
var templateStream = new MemoryStream();
|
||||||
|
templateFile.CopyTo(templateStream);
|
||||||
|
templateStream.Seek(0, SeekOrigin.Begin);
|
||||||
|
|
||||||
|
var workbook = new XSSFWorkbook(templateStream);
|
||||||
|
|
||||||
|
int sheetCount = workbook.NumberOfSheets;
|
||||||
|
|
||||||
|
if (sheetCount == 2)
|
||||||
|
{
|
||||||
|
if (inDto.IsEnglish)
|
||||||
|
{
|
||||||
|
workbook.RemoveSheetAt(0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
workbook.RemoveSheetAt(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
ISheet sheet = workbook.GetSheetAt(0); // 获取第一个工作表
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
for (int i = 0; i < sheet.LastRowNum + 1; i++)
|
||||||
|
{
|
||||||
|
IRow row = sheet.GetRow(i);
|
||||||
|
for (int j = 0; j < sheet.LastRowNum; j++)
|
||||||
|
{
|
||||||
|
ICell cell = row.GetCell(j);
|
||||||
|
foreach (var property in inDto.Data.GetType().GetProperties())
|
||||||
|
{
|
||||||
|
var value = property.GetValue(inDto.Data);
|
||||||
|
if (cell!=null&&cell.ToString() == "{{" + property.Name + "}}")
|
||||||
|
{
|
||||||
|
sheet.GetRow(i).GetCell(j).SetCellValue(value.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var memoryStream2 = new MemoryStream();
|
||||||
|
workbook.Write(memoryStream2, true);
|
||||||
|
|
||||||
|
memoryStream2.Seek(0, SeekOrigin.Begin);
|
||||||
|
|
||||||
|
templateStream = memoryStream2;
|
||||||
|
|
||||||
|
|
||||||
|
return new FileStreamResult(templateStream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
|
||||||
|
{
|
||||||
|
FileDownloadName = $"{(string.IsNullOrEmpty(inDto.ExportFileName) ? "" : inDto.ExportFileName + "_")}{Path.GetFileNameWithoutExtension(fileName)}_{DateTime.Now.ToString("yyyyMMddHHmmss")}.xlsx"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,14 +1,9 @@
|
|||||||
using System;
|
using System.Diagnostics;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace IRaCIS.Core.Application.Helper
|
namespace IRaCIS.Core.Application.Helper;
|
||||||
|
|
||||||
|
public class FileConvertHelper
|
||||||
{
|
{
|
||||||
public class FileConvertHelper
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
static public void ConvertWordToPdf(string inputWordFilePath, string outputPdfDir)
|
static public void ConvertWordToPdf(string inputWordFilePath, string outputPdfDir)
|
||||||
@@ -35,5 +30,4 @@ namespace IRaCIS.Core.Application.Helper
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,7 @@
|
|||||||
|
using IRaCIS.Core.Domain.Share;
|
||||||
|
|
||||||
using Aliyun.OSS;
|
|
||||||
using IRaCIS.Core.Domain.Share;
|
|
||||||
using IRaCIS.Core.Infrastructure;
|
using IRaCIS.Core.Infrastructure;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.Extensions.Hosting;
|
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using System.Configuration;
|
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
@@ -16,7 +11,7 @@ public static class FileStoreHelper
|
|||||||
{
|
{
|
||||||
|
|
||||||
//处理文件名 压缩包,或者目录类的 会带上相对路径
|
//处理文件名 压缩包,或者目录类的 会带上相对路径
|
||||||
public static (string TrustedFileNameForFileStorage, string RealName) GetStoreFileName(string fileName,bool isChangeToPdfFormat=false)
|
public static (string TrustedFileNameForFileStorage, string RealName) GetStoreFileName(string fileName, bool isChangeToPdfFormat = false)
|
||||||
{
|
{
|
||||||
|
|
||||||
//带目录层级,需要后端处理前端的路径
|
//带目录层级,需要后端处理前端的路径
|
||||||
@@ -41,14 +36,14 @@ public static class FileStoreHelper
|
|||||||
|
|
||||||
var trustedFileNameForFileStorage = string.Empty;
|
var trustedFileNameForFileStorage = string.Empty;
|
||||||
|
|
||||||
if (isChangeToPdfFormat==false)
|
if (isChangeToPdfFormat == false)
|
||||||
{
|
{
|
||||||
trustedFileNameForFileStorage= Guid.NewGuid().ToString() + fileName;
|
trustedFileNameForFileStorage = Guid.NewGuid().ToString() + fileName;
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
trustedFileNameForFileStorage=Guid.NewGuid().ToString() + Path.GetFileNameWithoutExtension(fileName) + ".pdf";
|
trustedFileNameForFileStorage = Guid.NewGuid().ToString() + Path.GetFileNameWithoutExtension(fileName) + ".pdf";
|
||||||
}
|
}
|
||||||
|
|
||||||
return (trustedFileNameForFileStorage, fileName);
|
return (trustedFileNameForFileStorage, fileName);
|
||||||
@@ -136,7 +131,7 @@ public static class FileStoreHelper
|
|||||||
{
|
{
|
||||||
var doc = await _commonDocumentRepository.FirstOrDefaultAsync(t => t.Code == code);
|
var doc = await _commonDocumentRepository.FirstOrDefaultAsync(t => t.Code == code);
|
||||||
|
|
||||||
var isEn_US = CultureInfo.CurrentCulture.Name!= StaticData.CultureInfo.zh_CN;
|
var isEn_US = CultureInfo.CurrentCulture.Name != StaticData.CultureInfo.zh_CN;
|
||||||
if (doc == null)
|
if (doc == null)
|
||||||
{
|
{
|
||||||
//---数据库没有找到对应的数据模板文件,请联系系统运维人员。
|
//---数据库没有找到对应的数据模板文件,请联系系统运维人员。
|
||||||
@@ -151,7 +146,7 @@ public static class FileStoreHelper
|
|||||||
throw new BusinessValidationFailedException(StaticData.International("FileStore_TemplateFileStoragePathInvalid"));
|
throw new BusinessValidationFailedException(StaticData.International("FileStore_TemplateFileStoragePathInvalid"));
|
||||||
}
|
}
|
||||||
|
|
||||||
return (filePath, isEn_US? doc.Name.Trim('/'): doc.NameCN.Trim('/'));
|
return (filePath, isEn_US ? doc.Name.Trim('/') : doc.NameCN.Trim('/'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -202,7 +197,7 @@ public static class FileStoreHelper
|
|||||||
|
|
||||||
// 获取 入组确认 PD 进展发送邮件Word|PDF 存放路径
|
// 获取 入组确认 PD 进展发送邮件Word|PDF 存放路径
|
||||||
|
|
||||||
public static (string PhysicalPath, string RelativePath, string FileRealName) GetSubjectEnrollConfirmOrPDEmailPath(IWebHostEnvironment _hostEnvironment, string fileName, Guid trialId, Guid trialSiteId, Guid subjectId,bool isChangeToPdfFormat=false)
|
public static (string PhysicalPath, string RelativePath, string FileRealName) GetSubjectEnrollConfirmOrPDEmailPath(IWebHostEnvironment _hostEnvironment, string fileName, Guid trialId, Guid trialSiteId, Guid subjectId, bool isChangeToPdfFormat = false)
|
||||||
{
|
{
|
||||||
var rootPath = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment);
|
var rootPath = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment);
|
||||||
|
|
||||||
@@ -221,7 +216,7 @@ public static class FileStoreHelper
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static string GetSubjectVisitDicomFolderPhysicalPath(IWebHostEnvironment _hostEnvironment,Guid trialId, Guid siteId, Guid subjectId, Guid subjectVisitId)
|
public static string GetSubjectVisitDicomFolderPhysicalPath(IWebHostEnvironment _hostEnvironment, Guid trialId, Guid siteId, Guid subjectId, Guid subjectVisitId)
|
||||||
{
|
{
|
||||||
var rootPath = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment);
|
var rootPath = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment);
|
||||||
|
|
||||||
@@ -233,7 +228,7 @@ public static class FileStoreHelper
|
|||||||
#region 切换存储前
|
#region 切换存储前
|
||||||
//var rootPath = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment);
|
//var rootPath = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment);
|
||||||
#endregion
|
#endregion
|
||||||
var rootPath = Path.Combine(FileStoreHelper.GetBestStoreDisk(_hostEnvironment), StaticData.Folder.IRaCISDataFolder) ;
|
var rootPath = Path.Combine(FileStoreHelper.GetBestStoreDisk(_hostEnvironment), StaticData.Folder.IRaCISDataFolder);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -246,7 +241,7 @@ public static class FileStoreHelper
|
|||||||
Directory.CreateDirectory(path);
|
Directory.CreateDirectory(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
var physicalPath = Path.Combine(path, instanceId.ToString() );
|
var physicalPath = Path.Combine(path, instanceId.ToString());
|
||||||
|
|
||||||
var relativePath = $"/{StaticData.Folder.IRaCISDataFolder}/{StaticData.Folder.TrialDataFolder}/{trialId}/{subjectId}/{subjectVisitId}/{StaticData.Folder.DicomFolder}/{studyId}/{instanceId}";
|
var relativePath = $"/{StaticData.Folder.IRaCISDataFolder}/{StaticData.Folder.TrialDataFolder}/{trialId}/{subjectId}/{subjectVisitId}/{StaticData.Folder.DicomFolder}/{studyId}/{instanceId}";
|
||||||
|
|
||||||
@@ -260,7 +255,7 @@ public static class FileStoreHelper
|
|||||||
public static string GetBestStoreDisk(IWebHostEnvironment _hostEnvironment)
|
public static string GetBestStoreDisk(IWebHostEnvironment _hostEnvironment)
|
||||||
{
|
{
|
||||||
|
|
||||||
var json = File.ReadAllText( Path.Combine(_hostEnvironment.ContentRootPath, "appsettings.json"));
|
var json = File.ReadAllText(Path.Combine(_hostEnvironment.ContentRootPath, "appsettings.json"));
|
||||||
|
|
||||||
JObject jsonObject = (JObject.Parse(json, new JsonLoadSettings() { CommentHandling = CommentHandling.Load })).IfNullThrowException();
|
JObject jsonObject = (JObject.Parse(json, new JsonLoadSettings() { CommentHandling = CommentHandling.Load })).IfNullThrowException();
|
||||||
|
|
||||||
|
|||||||
@@ -1,15 +1,5 @@
|
|||||||
using Hangfire;
|
using Hangfire;
|
||||||
using IRaCIS.Core.Application.Service;
|
|
||||||
using IRaCIS.Core.Domain.Share;
|
using IRaCIS.Core.Domain.Share;
|
||||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
|
||||||
using NPOI.SS.Formula.Functions;
|
|
||||||
using System;
|
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Linq.Expressions;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace IRaCIS.Core.Application.Helper
|
namespace IRaCIS.Core.Application.Helper
|
||||||
{
|
{
|
||||||
@@ -65,7 +55,7 @@ namespace IRaCIS.Core.Application.Helper
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static void AddOrUpdateTrialCronJob (string jobId, Guid trialId, EmailBusinessScenario businessScenario, string emailCron)
|
public static void AddOrUpdateTrialCronJob(string jobId, Guid trialId, EmailBusinessScenario businessScenario, string emailCron)
|
||||||
{
|
{
|
||||||
|
|
||||||
switch (businessScenario)
|
switch (businessScenario)
|
||||||
|
|||||||
@@ -1,16 +1,11 @@
|
|||||||
using RestSharp;
|
using RestSharp;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace IRaCIS.Core.Application.Helper
|
namespace IRaCIS.Core.Application.Helper;
|
||||||
|
|
||||||
|
|
||||||
|
#region 对接模型
|
||||||
|
public class HolidayCalendar
|
||||||
{
|
{
|
||||||
|
|
||||||
#region 对接模型
|
|
||||||
public class HolidayCalendar
|
|
||||||
{
|
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
public string Version { get; set; }
|
public string Version { get; set; }
|
||||||
public string Generated { get; set; }
|
public string Generated { get; set; }
|
||||||
@@ -18,10 +13,10 @@ namespace IRaCIS.Core.Application.Helper
|
|||||||
public string Author { get; set; }
|
public string Author { get; set; }
|
||||||
public string URL { get; set; }
|
public string URL { get; set; }
|
||||||
public Dictionary<string, List<HolidayYear>> Years { get; set; }
|
public Dictionary<string, List<HolidayYear>> Years { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class HolidayYear
|
public class HolidayYear
|
||||||
{
|
{
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
public DateTime StartDate { get; set; }
|
public DateTime StartDate { get; set; }
|
||||||
public DateTime EndDate { get; set; }
|
public DateTime EndDate { get; set; }
|
||||||
@@ -29,14 +24,14 @@ namespace IRaCIS.Core.Application.Helper
|
|||||||
public List<DateTime> CompDays { get; set; }
|
public List<DateTime> CompDays { get; set; }
|
||||||
public string URL { get; set; }
|
public string URL { get; set; }
|
||||||
public string Memo { get; set; }
|
public string Memo { get; set; }
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public class HolidayHelper
|
public class HolidayHelper
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// github 链接:https://github.com/lanceliao/china-holiday-calender?tab=readme-ov-file
|
/// github 链接:https://github.com/lanceliao/china-holiday-calender?tab=readme-ov-file
|
||||||
/// 接口请求参考文档:https://www.koudingke.cn/docs/zh-Hans/net-lib-docs/latest/RestSharp/Usage/Usage
|
/// 接口请求参考文档:https://www.koudingke.cn/docs/zh-Hans/net-lib-docs/latest/RestSharp/Usage/Usage
|
||||||
@@ -107,5 +102,4 @@ namespace IRaCIS.Core.Application.Helper
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,77 @@
|
|||||||
|
namespace IRaCIS.Core.Application.Helper;
|
||||||
|
|
||||||
|
public static class IRCEmailPasswordHelper
|
||||||
|
{
|
||||||
|
private static readonly Random Random = new Random();
|
||||||
|
|
||||||
|
//显示位数:3分之2的位数,向上取整
|
||||||
|
//取哪几个个值:最后一位和前面几位
|
||||||
|
//其他:3个***。
|
||||||
|
//比如:hlj23@126.com
|
||||||
|
//为:hlj***3@126.com
|
||||||
|
|
||||||
|
//he@126.com
|
||||||
|
//为:h*** e@126.com
|
||||||
|
|
||||||
|
public static string MaskEmail(string email)
|
||||||
|
{
|
||||||
|
|
||||||
|
// 找到 "@" 符号的位置
|
||||||
|
int atIndex = email.IndexOf('@');
|
||||||
|
|
||||||
|
string visiblePartBefore = email.Substring(0, atIndex);
|
||||||
|
|
||||||
|
string afterAt = email.Substring(atIndex + 1);
|
||||||
|
|
||||||
|
int visibleLength = (int)Math.Ceiling((double)visiblePartBefore.Length * 2 / 3);
|
||||||
|
|
||||||
|
// 替换中间两位字符为星号
|
||||||
|
string hiddenPartBeforeAt = visiblePartBefore.Substring(0, visibleLength - 1) + "***" + visiblePartBefore.Last();
|
||||||
|
|
||||||
|
|
||||||
|
// 组合隐藏和可见部分
|
||||||
|
string hiddenEmail = hiddenPartBeforeAt + "@" + afterAt;
|
||||||
|
|
||||||
|
return hiddenEmail;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 密码必须包含:1)8 – 32 个字符;2)至少1个数字;3) 至少1个大写字母;4)至少1个小写字母;5)至少1个特殊字符 (~!-@#$%^&*_+?)
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static string GenerateRandomPassword(int length)
|
||||||
|
{
|
||||||
|
// 必须包含的字符组
|
||||||
|
const string numbers = "0123456789";
|
||||||
|
const string upperCaseLetters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||||
|
const string lowerCaseLetters = "abcdefghijklmnopqrstuvwxyz";
|
||||||
|
const string specialCharacters = "~!-@#$%^&*_+?";
|
||||||
|
|
||||||
|
// 随机选择至少一个字符
|
||||||
|
char[] requiredCharacters =
|
||||||
|
{
|
||||||
|
numbers[Random.Next(numbers.Length)],
|
||||||
|
upperCaseLetters[Random.Next(upperCaseLetters.Length)],
|
||||||
|
lowerCaseLetters[Random.Next(lowerCaseLetters.Length)],
|
||||||
|
specialCharacters[Random.Next(specialCharacters.Length)]
|
||||||
|
};
|
||||||
|
|
||||||
|
// 构建剩余的字符集,用于填充密码的其余部分
|
||||||
|
string allCharacters = numbers + upperCaseLetters + lowerCaseLetters + specialCharacters;
|
||||||
|
|
||||||
|
// 确保密码长度满足用户要求
|
||||||
|
char[] password = new char[length];
|
||||||
|
|
||||||
|
// 将必须包含的字符放入密码中
|
||||||
|
requiredCharacters.CopyTo(password, 0);
|
||||||
|
|
||||||
|
// 填充剩余的字符
|
||||||
|
for (int i = requiredCharacters.Length; i < length; i++)
|
||||||
|
{
|
||||||
|
password[i] = allCharacters[Random.Next(allCharacters.Length)];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 随机打乱密码字符顺序
|
||||||
|
return new string(password.OrderBy(_ => Random.Next()).ToArray());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,10 +1,8 @@
|
|||||||
|
|
||||||
using FellowOakDicom.Imaging;
|
using FellowOakDicom.Imaging;
|
||||||
using SixLabors.ImageSharp.Formats.Jpeg;
|
|
||||||
using SixLabors.ImageSharp;
|
using SixLabors.ImageSharp;
|
||||||
|
using SixLabors.ImageSharp.Formats.Jpeg;
|
||||||
using SixLabors.ImageSharp.Processing;
|
using SixLabors.ImageSharp.Processing;
|
||||||
using System.Security.Cryptography;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace IRaCIS.Core.Application.Helper;
|
namespace IRaCIS.Core.Application.Helper;
|
||||||
|
|
||||||
|
|||||||
@@ -4,17 +4,11 @@ using IRaCIS.Core.Infrastructure;
|
|||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using static IRaCIS.Core.Application.Service.Common.SystemMonitor;
|
|
||||||
|
|
||||||
namespace IRaCIS.Core.Application.Helper
|
namespace IRaCIS.Core.Application.Helper;
|
||||||
|
|
||||||
|
public static class InternationalizationHelper
|
||||||
{
|
{
|
||||||
public static class InternationalizationHelper
|
|
||||||
{
|
|
||||||
public static string JsonFileFolder = Path.Combine(AppContext.BaseDirectory, StaticData.Folder.Resources);
|
public static string JsonFileFolder = Path.Combine(AppContext.BaseDirectory, StaticData.Folder.Resources);
|
||||||
|
|
||||||
public static FileSystemWatcher FileSystemWatcher_US { get; set; }
|
public static FileSystemWatcher FileSystemWatcher_US { get; set; }
|
||||||
@@ -74,7 +68,7 @@ namespace IRaCIS.Core.Application.Helper
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task AddOrUpdateJsonKeyValueAsync(string key, string value, string valueCN,string description)
|
public static async Task AddOrUpdateJsonKeyValueAsync(string key, string value, string valueCN, string description)
|
||||||
{
|
{
|
||||||
|
|
||||||
VerifyFolder();
|
VerifyFolder();
|
||||||
@@ -210,5 +204,4 @@ namespace IRaCIS.Core.Application.Helper
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,44 +1,34 @@
|
|||||||
using Aliyun.OSS;
|
using AlibabaCloud.SDK.Sts20150401;
|
||||||
using IRaCIS.Core.Infrastructure;
|
using Aliyun.OSS;
|
||||||
using Microsoft.Extensions.Hosting;
|
using Amazon;
|
||||||
using Microsoft.Extensions.Options;
|
|
||||||
using Minio.DataModel.Args;
|
|
||||||
using Minio;
|
|
||||||
using SharpCompress.Common;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Drawing;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Security.AccessControl;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using System.Text.Json.Serialization;
|
|
||||||
using Minio.ApiEndpoints;
|
|
||||||
using System.Reactive.Linq;
|
|
||||||
using IRaCIS.Core.Domain.Share;
|
|
||||||
using static MassTransit.ValidationResultExtensions;
|
|
||||||
using IRaCIS.Core.Infrastructure.NewtonsoftJson;
|
|
||||||
using Amazon.Runtime;
|
using Amazon.Runtime;
|
||||||
using Amazon.S3;
|
using Amazon.S3;
|
||||||
using Amazon.S3.Model;
|
using Amazon.S3.Model;
|
||||||
using MassTransit.Caching.Internals;
|
using Amazon.SecurityToken;
|
||||||
|
using Amazon.SecurityToken.Model;
|
||||||
|
using IRaCIS.Core.Infrastructure;
|
||||||
|
using IRaCIS.Core.Infrastructure.NewtonsoftJson;
|
||||||
|
using MassTransit;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
|
using Minio;
|
||||||
|
using Minio.DataModel.Args;
|
||||||
|
using System.Reactive.Linq;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace IRaCIS.Core.Application.Helper
|
namespace IRaCIS.Core.Application.Helper;
|
||||||
|
|
||||||
|
#region 绑定和返回模型
|
||||||
|
|
||||||
|
[LowerCamelCaseJson]
|
||||||
|
public class MinIOOptions : AWSOptions
|
||||||
{
|
{
|
||||||
#region 绑定和返回模型
|
|
||||||
|
|
||||||
[LowerCamelCaseJson]
|
|
||||||
public class MinIOOptions : AWSOptions
|
|
||||||
{
|
|
||||||
public int Port { get; set; }
|
public int Port { get; set; }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public class AWSOptions
|
public class AWSOptions
|
||||||
{
|
{
|
||||||
public string EndPoint { get; set; }
|
public string EndPoint { get; set; }
|
||||||
public bool UseSSL { get; set; }
|
public bool UseSSL { get; set; }
|
||||||
public string AccessKeyId { get; set; }
|
public string AccessKeyId { get; set; }
|
||||||
@@ -48,10 +38,10 @@ namespace IRaCIS.Core.Application.Helper
|
|||||||
public string ViewEndpoint { get; set; }
|
public string ViewEndpoint { get; set; }
|
||||||
public int DurationSeconds { get; set; }
|
public int DurationSeconds { get; set; }
|
||||||
public string Region { get; set; }
|
public string Region { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class AliyunOSSOptions
|
public class AliyunOSSOptions
|
||||||
{
|
{
|
||||||
public string RegionId { get; set; }
|
public string RegionId { get; set; }
|
||||||
public string AccessKeyId { get; set; }
|
public string AccessKeyId { get; set; }
|
||||||
public string AccessKeySecret { get; set; }
|
public string AccessKeySecret { get; set; }
|
||||||
@@ -71,10 +61,10 @@ namespace IRaCIS.Core.Application.Helper
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ObjectStoreServiceOptions
|
public class ObjectStoreServiceOptions
|
||||||
{
|
{
|
||||||
public string ObjectStoreUse { get; set; }
|
public string ObjectStoreUse { get; set; }
|
||||||
|
|
||||||
public AliyunOSSOptions AliyunOSS { get; set; }
|
public AliyunOSSOptions AliyunOSS { get; set; }
|
||||||
@@ -84,10 +74,10 @@ namespace IRaCIS.Core.Application.Helper
|
|||||||
|
|
||||||
public AWSOptions AWS { get; set; }
|
public AWSOptions AWS { get; set; }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ObjectStoreDTO
|
public class ObjectStoreDTO
|
||||||
{
|
{
|
||||||
public string ObjectStoreUse { get; set; }
|
public string ObjectStoreUse { get; set; }
|
||||||
|
|
||||||
|
|
||||||
@@ -97,34 +87,30 @@ namespace IRaCIS.Core.Application.Helper
|
|||||||
|
|
||||||
public AWSTempToken AWS { get; set; }
|
public AWSTempToken AWS { get; set; }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[LowerCamelCaseJson]
|
[LowerCamelCaseJson]
|
||||||
public class AliyunOSSTempToken
|
public class AliyunOSSTempToken
|
||||||
{
|
{
|
||||||
public string AccessKeyId { get; set; }
|
public string AccessKeyId { get; set; }
|
||||||
public string AccessKeySecret { get; set; }
|
public string AccessKeySecret { get; set; }
|
||||||
|
|
||||||
|
|
||||||
public string EndPoint { get; set; }
|
public string EndPoint { get; set; }
|
||||||
public string BucketName { get; set; }
|
public string BucketName { get; set; }
|
||||||
|
|
||||||
|
|
||||||
public string Region { get; set; }
|
public string Region { get; set; }
|
||||||
|
|
||||||
public string ViewEndpoint { get; set; }
|
public string ViewEndpoint { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public string SecurityToken { get; set; }
|
public string SecurityToken { get; set; }
|
||||||
public string Expiration { get; set; }
|
public DateTime Expiration { get; set; }
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[LowerCamelCaseJson]
|
[LowerCamelCaseJson]
|
||||||
public class AWSTempToken
|
public class AWSTempToken
|
||||||
{
|
{
|
||||||
public string Region { get; set; }
|
public string Region { get; set; }
|
||||||
public string SessionToken { get; set; }
|
public string SessionToken { get; set; }
|
||||||
public string EndPoint { get; set; }
|
public string EndPoint { get; set; }
|
||||||
@@ -133,21 +119,21 @@ namespace IRaCIS.Core.Application.Helper
|
|||||||
public string BucketName { get; set; }
|
public string BucketName { get; set; }
|
||||||
public string ViewEndpoint { get; set; }
|
public string ViewEndpoint { get; set; }
|
||||||
public DateTime Expiration { get; set; }
|
public DateTime Expiration { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum ObjectStoreUse
|
public enum ObjectStoreUse
|
||||||
{
|
{
|
||||||
AliyunOSS = 0,
|
AliyunOSS = 0,
|
||||||
MinIO = 1,
|
MinIO = 1,
|
||||||
AWS = 2,
|
AWS = 2,
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
// aws 参考链接 https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/dotnetv3/S3/S3_Basics
|
// aws 参考链接 https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/dotnetv3/S3/S3_Basics
|
||||||
|
|
||||||
public interface IOSSService
|
public interface IOSSService
|
||||||
{
|
{
|
||||||
public Task<string> UploadToOSSAsync(Stream fileStream, string oosFolderPath, string fileRealName, bool isFileNameAddGuid = true);
|
public Task<string> UploadToOSSAsync(Stream fileStream, string oosFolderPath, string fileRealName, bool isFileNameAddGuid = true);
|
||||||
public Task<string> UploadToOSSAsync(string localFilePath, string oosFolderPath, bool isFileNameAddGuid = true);
|
public Task<string> UploadToOSSAsync(string localFilePath, string oosFolderPath, bool isFileNameAddGuid = true);
|
||||||
|
|
||||||
@@ -158,19 +144,28 @@ namespace IRaCIS.Core.Application.Helper
|
|||||||
public Task<string> GetSignedUrl(string ossRelativePath);
|
public Task<string> GetSignedUrl(string ossRelativePath);
|
||||||
|
|
||||||
public Task DeleteFromPrefix(string prefix);
|
public Task DeleteFromPrefix(string prefix);
|
||||||
}
|
|
||||||
|
public ObjectStoreDTO GetObjectStoreTempToken();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public class OSSService : IOSSService
|
public class OSSService : IOSSService
|
||||||
{
|
{
|
||||||
public ObjectStoreServiceOptions ObjectStoreServiceOptions { get; set; }
|
public ObjectStoreServiceOptions ObjectStoreServiceOptions { get; set; }
|
||||||
|
|
||||||
|
private AliyunOSSTempToken AliyunOSSTempToken { get; set; }
|
||||||
|
|
||||||
|
private AWSTempToken AWSTempToken { get; set; }
|
||||||
|
|
||||||
|
|
||||||
public OSSService(IOptionsMonitor<ObjectStoreServiceOptions> options)
|
public OSSService(IOptionsMonitor<ObjectStoreServiceOptions> options)
|
||||||
{
|
{
|
||||||
ObjectStoreServiceOptions = options.CurrentValue;
|
ObjectStoreServiceOptions = options.CurrentValue;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// oosFolderPath 不要 "/ "开头 应该: TempFolder/ChildFolder
|
/// oosFolderPath 不要 "/ "开头 应该: TempFolder/ChildFolder
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -181,6 +176,8 @@ namespace IRaCIS.Core.Application.Helper
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public async Task<string> UploadToOSSAsync(Stream fileStream, string oosFolderPath, string fileRealName, bool isFileNameAddGuid = true)
|
public async Task<string> UploadToOSSAsync(Stream fileStream, string oosFolderPath, string fileRealName, bool isFileNameAddGuid = true)
|
||||||
{
|
{
|
||||||
|
GetObjectStoreTempToken();
|
||||||
|
|
||||||
var ossRelativePath = isFileNameAddGuid ? $"{oosFolderPath}/{Guid.NewGuid()}_{fileRealName}" : $"{oosFolderPath}/{fileRealName}";
|
var ossRelativePath = isFileNameAddGuid ? $"{oosFolderPath}/{Guid.NewGuid()}_{fileRealName}" : $"{oosFolderPath}/{fileRealName}";
|
||||||
|
|
||||||
try
|
try
|
||||||
@@ -198,7 +195,7 @@ namespace IRaCIS.Core.Application.Helper
|
|||||||
{
|
{
|
||||||
var aliConfig = ObjectStoreServiceOptions.AliyunOSS;
|
var aliConfig = ObjectStoreServiceOptions.AliyunOSS;
|
||||||
|
|
||||||
var _ossClient = new OssClient(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? aliConfig.EndPoint : aliConfig.InternalEndpoint, aliConfig.AccessKeyId, aliConfig.AccessKeySecret);
|
var _ossClient = new OssClient(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? aliConfig.EndPoint : aliConfig.InternalEndpoint, AliyunOSSTempToken.AccessKeyId, AliyunOSSTempToken.AccessKeySecret, AliyunOSSTempToken.SecurityToken);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -227,13 +224,15 @@ namespace IRaCIS.Core.Application.Helper
|
|||||||
{
|
{
|
||||||
var awsConfig = ObjectStoreServiceOptions.AWS;
|
var awsConfig = ObjectStoreServiceOptions.AWS;
|
||||||
|
|
||||||
// 提供awsAccessKeyId和awsSecretAccessKey构造凭证
|
var credentials = new SessionAWSCredentials(AWSTempToken.AccessKeyId, AWSTempToken.SecretAccessKey, AWSTempToken.SessionToken);
|
||||||
var credentials = new BasicAWSCredentials(awsConfig.AccessKeyId, awsConfig.SecretAccessKey);
|
|
||||||
|
|
||||||
|
|
||||||
//提供awsEndPoint(域名)进行访问配置
|
//提供awsEndPoint(域名)进行访问配置
|
||||||
var clientConfig = new AmazonS3Config
|
var clientConfig = new AmazonS3Config
|
||||||
{
|
{
|
||||||
ServiceURL = awsConfig.EndPoint
|
RegionEndpoint = RegionEndpoint.USEast1,
|
||||||
|
UseHttp = true,
|
||||||
};
|
};
|
||||||
|
|
||||||
var amazonS3Client = new AmazonS3Client(credentials, clientConfig);
|
var amazonS3Client = new AmazonS3Client(credentials, clientConfig);
|
||||||
@@ -278,6 +277,8 @@ namespace IRaCIS.Core.Application.Helper
|
|||||||
/// <exception cref="BusinessValidationFailedException"></exception>
|
/// <exception cref="BusinessValidationFailedException"></exception>
|
||||||
public async Task<string> UploadToOSSAsync(string localFilePath, string oosFolderPath, bool isFileNameAddGuid = true)
|
public async Task<string> UploadToOSSAsync(string localFilePath, string oosFolderPath, bool isFileNameAddGuid = true)
|
||||||
{
|
{
|
||||||
|
GetObjectStoreTempToken();
|
||||||
|
|
||||||
var localFileName = Path.GetFileName(localFilePath);
|
var localFileName = Path.GetFileName(localFilePath);
|
||||||
|
|
||||||
var ossRelativePath = isFileNameAddGuid ? $"{oosFolderPath}/{Guid.NewGuid()}_{localFileName}" : $"{oosFolderPath}/{localFileName}";
|
var ossRelativePath = isFileNameAddGuid ? $"{oosFolderPath}/{Guid.NewGuid()}_{localFileName}" : $"{oosFolderPath}/{localFileName}";
|
||||||
@@ -287,7 +288,7 @@ namespace IRaCIS.Core.Application.Helper
|
|||||||
{
|
{
|
||||||
var aliConfig = ObjectStoreServiceOptions.AliyunOSS;
|
var aliConfig = ObjectStoreServiceOptions.AliyunOSS;
|
||||||
|
|
||||||
var _ossClient = new OssClient(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? aliConfig.EndPoint : aliConfig.InternalEndpoint, aliConfig.AccessKeyId, aliConfig.AccessKeySecret);
|
var _ossClient = new OssClient(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? aliConfig.EndPoint : aliConfig.InternalEndpoint, AliyunOSSTempToken.AccessKeyId, AliyunOSSTempToken.AccessKeySecret, AliyunOSSTempToken.SecurityToken);
|
||||||
|
|
||||||
// 上传文件
|
// 上传文件
|
||||||
var result = _ossClient.PutObject(aliConfig.BucketName, ossRelativePath, localFilePath);
|
var result = _ossClient.PutObject(aliConfig.BucketName, ossRelativePath, localFilePath);
|
||||||
@@ -314,12 +315,13 @@ namespace IRaCIS.Core.Application.Helper
|
|||||||
var awsConfig = ObjectStoreServiceOptions.AWS;
|
var awsConfig = ObjectStoreServiceOptions.AWS;
|
||||||
|
|
||||||
// 提供awsAccessKeyId和awsSecretAccessKey构造凭证
|
// 提供awsAccessKeyId和awsSecretAccessKey构造凭证
|
||||||
var credentials = new BasicAWSCredentials(awsConfig.AccessKeyId, awsConfig.SecretAccessKey);
|
var credentials = new SessionAWSCredentials(AWSTempToken.AccessKeyId, AWSTempToken.SecretAccessKey, AWSTempToken.SessionToken);
|
||||||
|
|
||||||
//提供awsEndPoint(域名)进行访问配置
|
//提供awsEndPoint(域名)进行访问配置
|
||||||
var clientConfig = new AmazonS3Config
|
var clientConfig = new AmazonS3Config
|
||||||
{
|
{
|
||||||
ServiceURL = awsConfig.EndPoint
|
RegionEndpoint = RegionEndpoint.USEast1,
|
||||||
|
UseHttp = true,
|
||||||
};
|
};
|
||||||
|
|
||||||
var amazonS3Client = new AmazonS3Client(credentials, clientConfig);
|
var amazonS3Client = new AmazonS3Client(credentials, clientConfig);
|
||||||
@@ -345,6 +347,7 @@ namespace IRaCIS.Core.Application.Helper
|
|||||||
|
|
||||||
public async Task DownLoadFromOSSAsync(string ossRelativePath, string localFilePath)
|
public async Task DownLoadFromOSSAsync(string ossRelativePath, string localFilePath)
|
||||||
{
|
{
|
||||||
|
GetObjectStoreTempToken();
|
||||||
|
|
||||||
ossRelativePath = ossRelativePath.TrimStart('/');
|
ossRelativePath = ossRelativePath.TrimStart('/');
|
||||||
try
|
try
|
||||||
@@ -355,7 +358,7 @@ namespace IRaCIS.Core.Application.Helper
|
|||||||
{
|
{
|
||||||
var aliConfig = ObjectStoreServiceOptions.AliyunOSS;
|
var aliConfig = ObjectStoreServiceOptions.AliyunOSS;
|
||||||
|
|
||||||
var _ossClient = new OssClient(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? aliConfig.EndPoint : aliConfig.InternalEndpoint, aliConfig.AccessKeyId, aliConfig.AccessKeySecret);
|
var _ossClient = new OssClient(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? aliConfig.EndPoint : aliConfig.InternalEndpoint, AliyunOSSTempToken.AccessKeyId, AliyunOSSTempToken.AccessKeySecret, AliyunOSSTempToken.SecurityToken);
|
||||||
|
|
||||||
// 上传文件
|
// 上传文件
|
||||||
var result = _ossClient.GetObject(aliConfig.BucketName, ossRelativePath);
|
var result = _ossClient.GetObject(aliConfig.BucketName, ossRelativePath);
|
||||||
@@ -389,12 +392,13 @@ namespace IRaCIS.Core.Application.Helper
|
|||||||
var awsConfig = ObjectStoreServiceOptions.AWS;
|
var awsConfig = ObjectStoreServiceOptions.AWS;
|
||||||
|
|
||||||
// 提供awsAccessKeyId和awsSecretAccessKey构造凭证
|
// 提供awsAccessKeyId和awsSecretAccessKey构造凭证
|
||||||
var credentials = new BasicAWSCredentials(awsConfig.AccessKeyId, awsConfig.SecretAccessKey);
|
var credentials = new SessionAWSCredentials(AWSTempToken.AccessKeyId, AWSTempToken.SecretAccessKey, AWSTempToken.SessionToken);
|
||||||
|
|
||||||
//提供awsEndPoint(域名)进行访问配置
|
//提供awsEndPoint(域名)进行访问配置
|
||||||
var clientConfig = new AmazonS3Config
|
var clientConfig = new AmazonS3Config
|
||||||
{
|
{
|
||||||
ServiceURL = awsConfig.EndPoint
|
RegionEndpoint = RegionEndpoint.USEast1,
|
||||||
|
UseHttp = true,
|
||||||
};
|
};
|
||||||
|
|
||||||
var amazonS3Client = new AmazonS3Client(credentials, clientConfig);
|
var amazonS3Client = new AmazonS3Client(credentials, clientConfig);
|
||||||
@@ -429,6 +433,8 @@ namespace IRaCIS.Core.Application.Helper
|
|||||||
|
|
||||||
public async Task<string> GetSignedUrl(string ossRelativePath)
|
public async Task<string> GetSignedUrl(string ossRelativePath)
|
||||||
{
|
{
|
||||||
|
GetObjectStoreTempToken();
|
||||||
|
|
||||||
ossRelativePath = ossRelativePath.TrimStart('/');
|
ossRelativePath = ossRelativePath.TrimStart('/');
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -438,7 +444,7 @@ namespace IRaCIS.Core.Application.Helper
|
|||||||
{
|
{
|
||||||
var aliConfig = ObjectStoreServiceOptions.AliyunOSS;
|
var aliConfig = ObjectStoreServiceOptions.AliyunOSS;
|
||||||
|
|
||||||
var _ossClient = new OssClient(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? aliConfig.EndPoint : aliConfig.InternalEndpoint, aliConfig.AccessKeyId, aliConfig.AccessKeySecret);
|
var _ossClient = new OssClient(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? aliConfig.EndPoint : aliConfig.InternalEndpoint, AliyunOSSTempToken.AccessKeyId, AliyunOSSTempToken.AccessKeySecret, AliyunOSSTempToken.SecurityToken);
|
||||||
|
|
||||||
// 生成签名URL。
|
// 生成签名URL。
|
||||||
var req = new GeneratePresignedUriRequest(aliConfig.BucketName, ossRelativePath, SignHttpMethod.Get)
|
var req = new GeneratePresignedUriRequest(aliConfig.BucketName, ossRelativePath, SignHttpMethod.Get)
|
||||||
@@ -478,18 +484,27 @@ namespace IRaCIS.Core.Application.Helper
|
|||||||
}
|
}
|
||||||
else if (ObjectStoreServiceOptions.ObjectStoreUse == "AWS")
|
else if (ObjectStoreServiceOptions.ObjectStoreUse == "AWS")
|
||||||
{
|
{
|
||||||
var minIOConfig = ObjectStoreServiceOptions.AWS;
|
var awsConfig = ObjectStoreServiceOptions.AWS;
|
||||||
|
|
||||||
var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.EndPoint}")
|
|
||||||
.WithCredentials(minIOConfig.AccessKeyId, minIOConfig.SecretAccessKey).WithSSL(minIOConfig.UseSSL)
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
var args = new PresignedGetObjectArgs()
|
// 提供awsAccessKeyId和awsSecretAccessKey构造凭证
|
||||||
.WithBucket(minIOConfig.BucketName)
|
var credentials = new SessionAWSCredentials(AWSTempToken.AccessKeyId, AWSTempToken.SecretAccessKey, AWSTempToken.SessionToken);
|
||||||
.WithObject(ossRelativePath)
|
|
||||||
.WithExpiry(3600);
|
|
||||||
|
|
||||||
var presignedUrl = await minioClient.PresignedGetObjectAsync(args);
|
//提供awsEndPoint(域名)进行访问配置
|
||||||
|
var clientConfig = new AmazonS3Config
|
||||||
|
{
|
||||||
|
RegionEndpoint = RegionEndpoint.USEast1,
|
||||||
|
UseHttp = true,
|
||||||
|
};
|
||||||
|
|
||||||
|
var amazonS3Client = new AmazonS3Client(credentials, clientConfig);
|
||||||
|
|
||||||
|
var presignedUrl = await amazonS3Client.GetPreSignedURLAsync(new GetPreSignedUrlRequest()
|
||||||
|
{
|
||||||
|
BucketName = awsConfig.BucketName,
|
||||||
|
Key = ossRelativePath,
|
||||||
|
Expires = DateTime.UtcNow.AddMinutes(120)
|
||||||
|
});
|
||||||
|
|
||||||
Uri uri = new Uri(presignedUrl);
|
Uri uri = new Uri(presignedUrl);
|
||||||
|
|
||||||
@@ -518,11 +533,13 @@ namespace IRaCIS.Core.Application.Helper
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public async Task DeleteFromPrefix(string prefix)
|
public async Task DeleteFromPrefix(string prefix)
|
||||||
{
|
{
|
||||||
|
GetObjectStoreTempToken();
|
||||||
|
|
||||||
if (ObjectStoreServiceOptions.ObjectStoreUse == "AliyunOSS")
|
if (ObjectStoreServiceOptions.ObjectStoreUse == "AliyunOSS")
|
||||||
{
|
{
|
||||||
var aliConfig = ObjectStoreServiceOptions.AliyunOSS;
|
var aliConfig = ObjectStoreServiceOptions.AliyunOSS;
|
||||||
|
|
||||||
var _ossClient = new OssClient(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? aliConfig.EndPoint : aliConfig.InternalEndpoint, aliConfig.AccessKeyId, aliConfig.AccessKeySecret);
|
var _ossClient = new OssClient(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? aliConfig.EndPoint : aliConfig.InternalEndpoint, AliyunOSSTempToken.AccessKeyId, AliyunOSSTempToken.AccessKeySecret, AliyunOSSTempToken.SecurityToken);
|
||||||
|
|
||||||
|
|
||||||
try
|
try
|
||||||
@@ -603,12 +620,13 @@ namespace IRaCIS.Core.Application.Helper
|
|||||||
|
|
||||||
|
|
||||||
// 提供awsAccessKeyId和awsSecretAccessKey构造凭证
|
// 提供awsAccessKeyId和awsSecretAccessKey构造凭证
|
||||||
var credentials = new BasicAWSCredentials(awsConfig.AccessKeyId, awsConfig.SecretAccessKey);
|
var credentials = new SessionAWSCredentials(AWSTempToken.AccessKeyId, AWSTempToken.SecretAccessKey, AWSTempToken.SessionToken);
|
||||||
|
|
||||||
//提供awsEndPoint(域名)进行访问配置
|
//提供awsEndPoint(域名)进行访问配置
|
||||||
var clientConfig = new AmazonS3Config
|
var clientConfig = new AmazonS3Config
|
||||||
{
|
{
|
||||||
ServiceURL = awsConfig.EndPoint
|
RegionEndpoint = RegionEndpoint.USEast1,
|
||||||
|
UseHttp = true,
|
||||||
};
|
};
|
||||||
|
|
||||||
var amazonS3Client = new AmazonS3Client(credentials, clientConfig);
|
var amazonS3Client = new AmazonS3Client(credentials, clientConfig);
|
||||||
@@ -651,7 +669,102 @@ namespace IRaCIS.Core.Application.Helper
|
|||||||
throw new BusinessValidationFailedException("未定义的存储介质类型");
|
throw new BusinessValidationFailedException("未定义的存储介质类型");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public ObjectStoreDTO GetObjectStoreTempToken()
|
||||||
|
{
|
||||||
|
|
||||||
|
var ossOptions = ObjectStoreServiceOptions.AliyunOSS;
|
||||||
|
|
||||||
|
if (ObjectStoreServiceOptions.ObjectStoreUse == "AliyunOSS")
|
||||||
|
{
|
||||||
|
var client = new Client(new AlibabaCloud.OpenApiClient.Models.Config()
|
||||||
|
{
|
||||||
|
AccessKeyId = ossOptions.AccessKeyId,
|
||||||
|
AccessKeySecret = ossOptions.AccessKeySecret,
|
||||||
|
//AccessKeyId = "LTAI5tJV76pYX5yPg1N9QVE8",
|
||||||
|
//AccessKeySecret = "roRNLa9YG1of4pYruJGCNKBXEWTAWa",
|
||||||
|
|
||||||
|
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,
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
AliyunOSSTempToken = tempToken;
|
||||||
|
|
||||||
|
return new ObjectStoreDTO() { ObjectStoreUse = ObjectStoreServiceOptions.ObjectStoreUse, AliyunOSS = tempToken };
|
||||||
|
}
|
||||||
|
else if (ObjectStoreServiceOptions.ObjectStoreUse == "MinIO")
|
||||||
|
{
|
||||||
|
return new ObjectStoreDTO() { ObjectStoreUse = ObjectStoreServiceOptions.ObjectStoreUse, MinIO = ObjectStoreServiceOptions.MinIO };
|
||||||
|
}
|
||||||
|
else if (ObjectStoreServiceOptions.ObjectStoreUse == "AWS")
|
||||||
|
{
|
||||||
|
var awsOptions = ObjectStoreServiceOptions.AWS;
|
||||||
|
|
||||||
|
//aws 临时凭证
|
||||||
|
// 创建 STS 客户端
|
||||||
|
var stsClient = new AmazonSecurityTokenServiceClient(awsOptions.AccessKeyId, awsOptions.SecretAccessKey);
|
||||||
|
|
||||||
|
// 使用 AssumeRole 请求临时凭证
|
||||||
|
var assumeRoleRequest = new AssumeRoleRequest
|
||||||
|
{
|
||||||
|
|
||||||
|
RoleArn = awsOptions.RoleArn, // 角色 ARN
|
||||||
|
RoleSessionName = $"session-name-{NewId.NextGuid()}",
|
||||||
|
DurationSeconds = awsOptions.DurationSeconds // 临时凭证有效期
|
||||||
|
};
|
||||||
|
|
||||||
|
var assumeRoleResponse = stsClient.AssumeRoleAsync(assumeRoleRequest).Result;
|
||||||
|
|
||||||
|
var credentials = assumeRoleResponse.Credentials;
|
||||||
|
|
||||||
|
var tempToken = new AWSTempToken()
|
||||||
|
{
|
||||||
|
AccessKeyId = credentials.AccessKeyId,
|
||||||
|
SecretAccessKey = credentials.SecretAccessKey,
|
||||||
|
SessionToken = credentials.SessionToken,
|
||||||
|
Expiration = credentials.Expiration,
|
||||||
|
Region = awsOptions.Region,
|
||||||
|
BucketName = awsOptions.BucketName,
|
||||||
|
EndPoint = awsOptions.EndPoint,
|
||||||
|
ViewEndpoint = awsOptions.ViewEndpoint,
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
AWSTempToken = tempToken;
|
||||||
|
return new ObjectStoreDTO() { ObjectStoreUse = ObjectStoreServiceOptions.ObjectStoreUse, AWS = tempToken };
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new BusinessValidationFailedException("未定义的存储介质类型");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,97 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Org.BouncyCastle.Crypto;
|
|
||||||
using Org.BouncyCastle.Crypto.Encodings;
|
|
||||||
using Org.BouncyCastle.Crypto.Engines;
|
|
||||||
using Org.BouncyCastle.Crypto.Generators;
|
|
||||||
using Org.BouncyCastle.OpenSsl;
|
|
||||||
using Org.BouncyCastle.Security;
|
|
||||||
|
|
||||||
namespace IRaCIS.Core.Application.Helper
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// https://www.cnblogs.com/NBDWDYS2214143926/p/13329231.html
|
|
||||||
/// </summary>
|
|
||||||
public class RSAHelper
|
|
||||||
{
|
|
||||||
|
|
||||||
public static AsymmetricCipherKeyPair GenerateRSAKeyPair(int keySize)
|
|
||||||
{
|
|
||||||
var keyGenerationParameters = new KeyGenerationParameters(new SecureRandom(), keySize);
|
|
||||||
var keyPairGenerator = new RsaKeyPairGenerator();
|
|
||||||
keyPairGenerator.Init(keyGenerationParameters);
|
|
||||||
return keyPairGenerator.GenerateKeyPair();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string ExportPublicKey(AsymmetricKeyParameter publicKey)
|
|
||||||
{
|
|
||||||
using (StringWriter sw = new StringWriter())
|
|
||||||
{
|
|
||||||
PemWriter pw = new PemWriter(sw);
|
|
||||||
pw.WriteObject(publicKey);
|
|
||||||
pw.Writer.Flush();
|
|
||||||
return sw.ToString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string ExportPrivateKey(AsymmetricKeyParameter privateKey)
|
|
||||||
{
|
|
||||||
using (StringWriter sw = new StringWriter())
|
|
||||||
{
|
|
||||||
PemWriter pw = new PemWriter(sw);
|
|
||||||
pw.WriteObject(privateKey);
|
|
||||||
pw.Writer.Flush();
|
|
||||||
return sw.ToString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// RSA解密
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="privateKey">私钥</param>
|
|
||||||
/// <param name="decryptstring">待解密的字符串(Base64)</param>
|
|
||||||
/// <returns>解密后的字符串</returns>
|
|
||||||
public static string Decrypt(string privateKey, string decryptstring)
|
|
||||||
{
|
|
||||||
using (TextReader reader = new StringReader(privateKey))
|
|
||||||
{
|
|
||||||
dynamic key = new PemReader(reader).ReadObject();
|
|
||||||
var rsaDecrypt = new Pkcs1Encoding(new RsaEngine());
|
|
||||||
if (key is AsymmetricKeyParameter)
|
|
||||||
{
|
|
||||||
key = (AsymmetricKeyParameter)key;
|
|
||||||
}
|
|
||||||
else if (key is AsymmetricCipherKeyPair)
|
|
||||||
{
|
|
||||||
key = ((AsymmetricCipherKeyPair)key).Private;
|
|
||||||
}
|
|
||||||
rsaDecrypt.Init(false, key); //这里加密是true;解密是false
|
|
||||||
|
|
||||||
byte[] entData = Convert.FromBase64String(decryptstring);
|
|
||||||
entData = rsaDecrypt.ProcessBlock(entData, 0, entData.Length);
|
|
||||||
return Encoding.UTF8.GetString(entData);
|
|
||||||
}
|
|
||||||
}/// <summary>
|
|
||||||
|
|
||||||
/// 加密
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="publicKey">公钥</param>
|
|
||||||
/// <param name="encryptstring">待加密的字符串</param>
|
|
||||||
/// <returns>加密后的Base64</returns>
|
|
||||||
public static string Encrypt(string publicKey, string encryptstring)
|
|
||||||
{
|
|
||||||
using (TextReader reader = new StringReader(publicKey))
|
|
||||||
{
|
|
||||||
AsymmetricKeyParameter key = new PemReader(reader).ReadObject() as AsymmetricKeyParameter;
|
|
||||||
Pkcs1Encoding pkcs1 = new Pkcs1Encoding(new RsaEngine());
|
|
||||||
pkcs1.Init(true, key);//加密是true;解密是false;
|
|
||||||
byte[] entData = Encoding.UTF8.GetBytes(encryptstring);
|
|
||||||
entData = pkcs1.ProcessBlock(entData, 0, entData.Length);
|
|
||||||
return Convert.ToBase64String(entData);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,9 +1,7 @@
|
|||||||
using DocumentFormat.OpenXml.Spreadsheet;
|
using IRaCIS.Core.Domain.Share;
|
||||||
using IRaCIS.Core.Domain.Share;
|
|
||||||
using MailKit;
|
using MailKit;
|
||||||
using MailKit.Security;
|
using MailKit.Security;
|
||||||
using MimeKit;
|
using MimeKit;
|
||||||
using NPOI.HPSF;
|
|
||||||
|
|
||||||
|
|
||||||
namespace IRaCIS.Core.Application.Helper;
|
namespace IRaCIS.Core.Application.Helper;
|
||||||
@@ -44,7 +42,7 @@ public static class SendEmailHelper
|
|||||||
{
|
{
|
||||||
|
|
||||||
//---邮件发送失败,您进行的操作未能成功,请检查邮箱或联系维护人员
|
//---邮件发送失败,您进行的操作未能成功,请检查邮箱或联系维护人员
|
||||||
throw new Exception(StaticData.International("SendEmail_SendFail"),new Exception(ex.Message));
|
throw new Exception(StaticData.International("SendEmail_SendFail"), new Exception(ex.Message));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,21 +1,16 @@
|
|||||||
using IRaCIS.Core.Domain.Share;
|
using IRaCIS.Core.Domain.Share;
|
||||||
using NPOI.XWPF.UserModel;
|
using NPOI.XWPF.UserModel;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Xceed.Document.NET;
|
using Xceed.Document.NET;
|
||||||
using Xceed.Words.NET;
|
using Xceed.Words.NET;
|
||||||
|
|
||||||
namespace IRaCIS.Core.Application.Helper
|
namespace IRaCIS.Core.Application.Helper;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 利用DocX 库 处理word国际化模板
|
||||||
|
/// </summary>
|
||||||
|
public static class WordTempleteHelper
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// 利用DocX 库 处理word国际化模板
|
|
||||||
/// </summary>
|
|
||||||
public static class WordTempleteHelper
|
|
||||||
{
|
|
||||||
public static void DocX_GetInternationalTempleteStream(string filePath, Stream memoryStream)
|
public static void DocX_GetInternationalTempleteStream(string filePath, Stream memoryStream)
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -97,5 +92,4 @@ namespace IRaCIS.Core.Application.Helper
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,21 +19,6 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
|
|
||||||
<Using Include="IRaCIS.Core.Application;" />
|
|
||||||
<Using Include="AutoMapper.QueryableExtensions;" />
|
|
||||||
<Using Include="Microsoft.EntityFrameworkCore;" />
|
|
||||||
<Using Include="IRaCIS.Core.Domain.Models;" />
|
|
||||||
<Using Include="IRaCIS.Core.Infrastructure.Extention;" />
|
|
||||||
<Using Include="IRaCIS.Core.Infra.EFCore;" />
|
|
||||||
|
|
||||||
<!-- Global using -->
|
|
||||||
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Remove="WebAppConfig.cs" />
|
<Compile Remove="WebAppConfig.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
@@ -58,8 +43,10 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<PackageReference Include="AlibabaCloud.SDK.Sts20150401" Version="1.1.4" />
|
||||||
|
<PackageReference Include="AWSSDK.SecurityToken" Version="3.7.400.16" />
|
||||||
<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.402.4" />
|
<PackageReference Include="AWSSDK.S3" Version="3.7.402.7" />
|
||||||
<PackageReference Include="DocX" Version="3.0.1" />
|
<PackageReference Include="DocX" Version="3.0.1" />
|
||||||
<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.14" />
|
||||||
@@ -71,8 +58,8 @@
|
|||||||
<PackageReference Include="fo-dicom.Imaging.ImageSharp" Version="5.1.3" />
|
<PackageReference Include="fo-dicom.Imaging.ImageSharp" Version="5.1.3" />
|
||||||
<PackageReference Include="fo-dicom.Codecs" Version="5.14.5" />
|
<PackageReference Include="fo-dicom.Codecs" Version="5.14.5" />
|
||||||
<PackageReference Include="IP2Region.Net" Version="2.0.2" />
|
<PackageReference Include="IP2Region.Net" Version="2.0.2" />
|
||||||
<PackageReference Include="MailKit" Version="4.2.0" />
|
<PackageReference Include="MailKit" Version="4.7.1.1" />
|
||||||
<PackageReference Include="MimeKit" Version="4.2.0" />
|
<PackageReference Include="MimeKit" Version="4.7.1" />
|
||||||
<PackageReference Include="MiniExcel" Version="1.34.1" />
|
<PackageReference Include="MiniExcel" Version="1.34.1" />
|
||||||
<PackageReference Include="Minio" Version="6.0.3" />
|
<PackageReference Include="Minio" Version="6.0.3" />
|
||||||
<PackageReference Include="MiniWord" Version="0.8.0" />
|
<PackageReference Include="MiniWord" Version="0.8.0" />
|
||||||
@@ -84,7 +71,6 @@
|
|||||||
<PackageReference Include="RestSharp" Version="112.0.0" />
|
<PackageReference Include="RestSharp" Version="112.0.0" />
|
||||||
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.5" />
|
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.5" />
|
||||||
<PackageReference Include="Swashbuckle.AspNetCore.Filters" Version="8.0.2" />
|
<PackageReference Include="Swashbuckle.AspNetCore.Filters" Version="8.0.2" />
|
||||||
<PackageReference Include="MassTransit.AspNetCore" Version="7.3.1" />
|
|
||||||
<PackageReference Include="ZiggyCreatures.FusionCache" Version="1.3.0" />
|
<PackageReference Include="ZiggyCreatures.FusionCache" Version="1.3.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
@@ -98,4 +84,8 @@
|
|||||||
</None>
|
</None>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="Triggers\TempAbandon\" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,10 +1,5 @@
|
|||||||
using MiniExcelLibs.Attributes;
|
using MiniExcelLibs.Attributes;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace IRaCIS.Core.Application.MassTransit.Command
|
namespace IRaCIS.Core.Application.MassTransit.Command
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
|
||||||
|
|
||||||
|
using AutoMapper;
|
||||||
|
using IP2Region.Net.Abstractions;
|
||||||
|
using IRaCIS.Core.Domain;
|
||||||
|
using IRaCIS.Core.Domain.Models;
|
||||||
|
using MassTransit;
|
||||||
|
|
||||||
|
namespace IRaCIS.Core.Application.MassTransit.Consumer;
|
||||||
|
|
||||||
|
|
||||||
|
//国家|区域|省份|城市|ISP 缺省的地域信息默认是0
|
||||||
|
//0|0|0|内网IP|内网IP
|
||||||
|
// 中国|0|湖北省|武汉市|电信
|
||||||
|
public class AddUserLogTriggerConsumer(ISearcher _searcher) : IConsumer<AddUserLogTriggerCommand>
|
||||||
|
{
|
||||||
|
public async Task Consume(ConsumeContext<AddUserLogTriggerCommand> context)
|
||||||
|
{
|
||||||
|
var userLog = context.Message.UserLog;
|
||||||
|
|
||||||
|
var ipinfo = _searcher.Search(userLog.IP);
|
||||||
|
|
||||||
|
userLog.IPRegion = string.Join('|', ipinfo.Split('|').TakeLast(3));
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,12 +5,7 @@ using IRaCIS.Core.Domain.Share;
|
|||||||
using MassTransit;
|
using MassTransit;
|
||||||
using Microsoft.Extensions.Localization;
|
using Microsoft.Extensions.Localization;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Linq.Expressions;
|
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace IRaCIS.Core.Application.MassTransit.Consumer
|
namespace IRaCIS.Core.Application.MassTransit.Consumer
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,101 @@
|
|||||||
|
|
||||||
|
|
||||||
|
using AutoMapper;
|
||||||
|
using IRaCIS.Core.Domain;
|
||||||
|
using MassTransit;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
|
namespace IRaCIS.Core.Application.MassTransit.Consumer;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 添加Subject 触发添加访视 不能代替 Trigger,稽查BatchId 不一致
|
||||||
|
/// 因为消费者这里的数据库上下文 和消息发送者上下文不是同一个,相当于两个独立的事务
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="_subjectVisitRepository"></param>
|
||||||
|
/// <param name="_visitStageRepository"></param>
|
||||||
|
/// <param name="_trialRepository"></param>
|
||||||
|
/// <param name="_mapper"></param>
|
||||||
|
public class AddSubjectTriggerConsumer(IRepository<SubjectVisit> _subjectVisitRepository,
|
||||||
|
|
||||||
|
IRepository<VisitStage> _visitStageRepository,
|
||||||
|
IRepository<Trial> _trialRepository,
|
||||||
|
IMapper _mapper) : IConsumer<AddSubjectTriggerCommand>
|
||||||
|
{
|
||||||
|
public async Task Consume(ConsumeContext<AddSubjectTriggerCommand> context)
|
||||||
|
{
|
||||||
|
var addSubjectEvent = context.Message;
|
||||||
|
|
||||||
|
|
||||||
|
{
|
||||||
|
Console.WriteLine(_visitStageRepository._dbContext.GetHashCode());
|
||||||
|
|
||||||
|
Console.WriteLine("两个 DbContext 不是同一个实例");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//添加受试者的时候,获取访视计划列表,添加到受试者访视表。
|
||||||
|
var visitPlanList = await _visitStageRepository.Where(t => t.TrialId == addSubjectEvent.TrialId && t.IsConfirmed).ToListAsync();
|
||||||
|
|
||||||
|
var svList = _mapper.Map<List<SubjectVisit>>(visitPlanList);
|
||||||
|
|
||||||
|
var IsEnrollementQualificationConfirm = await _trialRepository.Where(t => t.Id == addSubjectEvent.TrialId).Select(u => u.IsEnrollementQualificationConfirm).FirstOrDefaultAsync();
|
||||||
|
|
||||||
|
svList.ForEach(t =>
|
||||||
|
{
|
||||||
|
t.SubjectId = addSubjectEvent.SubjectId;
|
||||||
|
t.TrialId = addSubjectEvent.TrialId;
|
||||||
|
t.TrialSiteId = addSubjectEvent.TrialSiteId;
|
||||||
|
t.IsEnrollmentConfirm = t.IsBaseLine ? IsEnrollementQualificationConfirm : false;
|
||||||
|
t.Id = NewId.NextGuid();
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
await _subjectVisitRepository.AddRangeAsync(svList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class AddSubjectTriggerConsumer2(IRepository<SubjectVisit> _subjectVisitRepository,
|
||||||
|
|
||||||
|
IRepository<VisitStage> _visitStageRepository,
|
||||||
|
IRepository<Trial> _trialRepository,
|
||||||
|
IMapper _mapper) : IConsumer<AddSubjectTriggerCommand2>
|
||||||
|
{
|
||||||
|
public async Task Consume(ConsumeContext<AddSubjectTriggerCommand2> context)
|
||||||
|
{
|
||||||
|
var addSubjectEvent = context.Message;
|
||||||
|
|
||||||
|
|
||||||
|
{
|
||||||
|
Console.WriteLine(_visitStageRepository._dbContext.GetHashCode());
|
||||||
|
|
||||||
|
Console.WriteLine("两个 DbContext 不是同一个实例");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//添加受试者的时候,获取访视计划列表,添加到受试者访视表。
|
||||||
|
var visitPlanList = await _visitStageRepository.Where(t => t.TrialId == addSubjectEvent.TrialId && t.IsConfirmed).ToListAsync();
|
||||||
|
|
||||||
|
var svList = _mapper.Map<List<SubjectVisit>>(visitPlanList);
|
||||||
|
|
||||||
|
var IsEnrollementQualificationConfirm = await _trialRepository.Where(t => t.Id == addSubjectEvent.TrialId).Select(u => u.IsEnrollementQualificationConfirm).FirstOrDefaultAsync();
|
||||||
|
|
||||||
|
svList.ForEach(t =>
|
||||||
|
{
|
||||||
|
t.SubjectId = addSubjectEvent.SubjectId;
|
||||||
|
t.TrialId = addSubjectEvent.TrialId;
|
||||||
|
t.TrialSiteId = addSubjectEvent.TrialSiteId;
|
||||||
|
t.IsEnrollmentConfirm = t.IsBaseLine ? IsEnrollementQualificationConfirm : false;
|
||||||
|
t.Id = NewId.NextGuid();
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
await _subjectVisitRepository.AddRangeAsync(svList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
+83
@@ -0,0 +1,83 @@
|
|||||||
|
|
||||||
|
|
||||||
|
using IRaCIS.Core.Application.MassTransit.Consumer;
|
||||||
|
using MassTransit;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
|
namespace IRaCIS.Core.Application.MassTransit.Consumer;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 参考链接:https://github.com/MassTransit/MassTransit/discussions/2498
|
||||||
|
/// </summary>
|
||||||
|
public static class MediatorHttpContextScopeFilterExtensions
|
||||||
|
{
|
||||||
|
public static void UseHttpContextScopeFilter(this IMediatorConfigurator configurator, IServiceProvider serviceProvider)
|
||||||
|
{
|
||||||
|
var filter = new HttpContextScopeFilter(serviceProvider.GetRequiredService<IHttpContextAccessor>());
|
||||||
|
|
||||||
|
configurator.ConfigurePublish(x => x.UseFilter(filter));
|
||||||
|
configurator.ConfigureSend(x => x.UseFilter(filter));
|
||||||
|
configurator.UseFilter(filter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class HttpContextScopeFilter :
|
||||||
|
IFilter<PublishContext>,
|
||||||
|
IFilter<SendContext>,
|
||||||
|
IFilter<ConsumeContext>
|
||||||
|
{
|
||||||
|
private readonly IHttpContextAccessor _httpContextAccessor;
|
||||||
|
|
||||||
|
public HttpContextScopeFilter(IHttpContextAccessor httpContextAccessor)
|
||||||
|
{
|
||||||
|
_httpContextAccessor = httpContextAccessor;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddPayload(PipeContext context)
|
||||||
|
{
|
||||||
|
if (_httpContextAccessor.HttpContext == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var serviceProvider = _httpContextAccessor.HttpContext.RequestServices;
|
||||||
|
context.GetOrAddPayload(() => serviceProvider);
|
||||||
|
context.GetOrAddPayload<IServiceScope>(() => new NoopScope(serviceProvider));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task Send(PublishContext context, IPipe<PublishContext> next)
|
||||||
|
{
|
||||||
|
AddPayload(context);
|
||||||
|
return next.Send(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task Send(SendContext context, IPipe<SendContext> next)
|
||||||
|
{
|
||||||
|
AddPayload(context);
|
||||||
|
return next.Send(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task Send(ConsumeContext context, IPipe<ConsumeContext> next)
|
||||||
|
{
|
||||||
|
AddPayload(context);
|
||||||
|
return next.Send(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Probe(ProbeContext context)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
private class NoopScope :
|
||||||
|
IServiceScope
|
||||||
|
{
|
||||||
|
public NoopScope(IServiceProvider serviceProvider)
|
||||||
|
{
|
||||||
|
ServiceProvider = serviceProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public IServiceProvider ServiceProvider { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,12 +3,10 @@
|
|||||||
// 生成时间 2022-06-07 13:16:33
|
// 生成时间 2022-06-07 13:16:33
|
||||||
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
|
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
using System;
|
|
||||||
using IRaCIS.Core.Domain.Share;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.ComponentModel.DataAnnotations;
|
|
||||||
using IRaCIS.Application.Contracts;
|
using IRaCIS.Application.Contracts;
|
||||||
|
using IRaCIS.Core.Domain.Share;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
namespace IRaCIS.Core.Application.ViewModel
|
namespace IRaCIS.Core.Application.ViewModel
|
||||||
{
|
{
|
||||||
@@ -112,7 +110,8 @@ namespace IRaCIS.Core.Application.ViewModel
|
|||||||
public List<CriterionReadingCategory> CriterionCategoryList =>
|
public List<CriterionReadingCategory> CriterionCategoryList =>
|
||||||
|
|
||||||
TrialReadingCriterionList.Select(t =>
|
TrialReadingCriterionList.Select(t =>
|
||||||
new CriterionReadingCategory() {
|
new CriterionReadingCategory()
|
||||||
|
{
|
||||||
EnrollId = EnrollId,
|
EnrollId = EnrollId,
|
||||||
TrialReadingCriterionId = t.TrialReadingCriterionId,
|
TrialReadingCriterionId = t.TrialReadingCriterionId,
|
||||||
ReadingCategorys = CriterionReadingCategoryList.Where(c => c.TrialReadingCriterionId == t.TrialReadingCriterionId).Select(t => t.ReadingCategory).OrderBy(c => c).ToList()
|
ReadingCategorys = CriterionReadingCategoryList.Where(c => c.TrialReadingCriterionId == t.TrialReadingCriterionId).Select(t => t.ReadingCategory).OrderBy(c => c).ToList()
|
||||||
|
|||||||
@@ -3,9 +3,7 @@
|
|||||||
// 生成时间 2022-07-01 15:33:01
|
// 生成时间 2022-07-01 15:33:01
|
||||||
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
|
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
using System;
|
|
||||||
using IRaCIS.Core.Domain.Share;
|
using IRaCIS.Core.Domain.Share;
|
||||||
using System.Collections.Generic;
|
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
@@ -81,7 +79,7 @@ namespace IRaCIS.Core.Application.ViewModel
|
|||||||
public Guid DoctorUserId { get; set; }
|
public Guid DoctorUserId { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ConsistentConfirmGenerateCommand: SelfConsistentSimpleQuery
|
public class ConsistentConfirmGenerateCommand : SelfConsistentSimpleQuery
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
@@ -104,7 +102,7 @@ namespace IRaCIS.Core.Application.ViewModel
|
|||||||
public bool IsAutoAllocateGenerateTask { get; set; }
|
public bool IsAutoAllocateGenerateTask { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class DoctorSelfConsistentSubjectView: ConsistentCommonView
|
public class DoctorSelfConsistentSubjectView : ConsistentCommonView
|
||||||
{
|
{
|
||||||
public string FirstGlobalVisitName { get; set; } = string.Empty;
|
public string FirstGlobalVisitName { get; set; } = string.Empty;
|
||||||
public string? BlindSubjectCode { get; set; }
|
public string? BlindSubjectCode { get; set; }
|
||||||
@@ -130,14 +128,14 @@ namespace IRaCIS.Core.Application.ViewModel
|
|||||||
public int? ValidVisitCount { get; set; }
|
public int? ValidVisitCount { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class DoctorGroupConsistentSubjectView: ConsistentCommonView
|
public class DoctorGroupConsistentSubjectView : ConsistentCommonView
|
||||||
{
|
{
|
||||||
|
|
||||||
public List<VisitTaskGroupSimpleDTO> SubjectTaskVisitList => VisitTaskList.GroupBy(t => new { t.SubjectId, t.VisitTaskNum }).Where(g => g.Count() == 2).Select(g => g.First()).OrderBy(t=>t.VisitTaskNum).ToList();
|
public List<VisitTaskGroupSimpleDTO> SubjectTaskVisitList => VisitTaskList.GroupBy(t => new { t.SubjectId, t.VisitTaskNum }).Where(g => g.Count() == 2).Select(g => g.First()).OrderBy(t => t.VisitTaskNum).ToList();
|
||||||
|
|
||||||
public List<VisitTaskGroupSimpleDTO> VisitTaskList { get; set; } = new List<VisitTaskGroupSimpleDTO>();
|
public List<VisitTaskGroupSimpleDTO> VisitTaskList { get; set; } = new List<VisitTaskGroupSimpleDTO>();
|
||||||
|
|
||||||
public List<UserSimpleInfo> DoctorUserList { get; set; }=new List<UserSimpleInfo>();
|
public List<UserSimpleInfo> DoctorUserList { get; set; } = new List<UserSimpleInfo>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public class VisitTaskGroupSimpleDTO
|
public class VisitTaskGroupSimpleDTO
|
||||||
@@ -175,7 +173,7 @@ namespace IRaCIS.Core.Application.ViewModel
|
|||||||
public bool IsClinicalDataSign { get; set; }
|
public bool IsClinicalDataSign { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class VisitTaskSimpleDTO :VisitTaskGroupSimpleDTO
|
public class VisitTaskSimpleDTO : VisitTaskGroupSimpleDTO
|
||||||
{
|
{
|
||||||
public Guid? Id { get; set; }
|
public Guid? Id { get; set; }
|
||||||
|
|
||||||
@@ -316,7 +314,7 @@ namespace IRaCIS.Core.Application.ViewModel
|
|||||||
public string VirtualSiteCode { get; set; }
|
public string VirtualSiteCode { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class UpdateTrialSiteCodeCommandView: UpdateTrialSiteCodeCommand
|
public class UpdateTrialSiteCodeCommandView : UpdateTrialSiteCodeCommand
|
||||||
{
|
{
|
||||||
public DateTime Creatime { get; set; }
|
public DateTime Creatime { get; set; }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,11 +3,8 @@
|
|||||||
// 生成时间 2022-06-29 13:36:46
|
// 生成时间 2022-06-29 13:36:46
|
||||||
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
|
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
using System;
|
|
||||||
using IRaCIS.Core.Domain.Share;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.ComponentModel.DataAnnotations;
|
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
namespace IRaCIS.Core.Application.ViewModel
|
namespace IRaCIS.Core.Application.ViewModel
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -3,9 +3,7 @@
|
|||||||
// 生成时间 2022-06-29 10:59:50
|
// 生成时间 2022-06-29 10:59:50
|
||||||
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
|
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
using System;
|
|
||||||
using IRaCIS.Core.Domain.Share;
|
using IRaCIS.Core.Domain.Share;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
namespace IRaCIS.Core.Application.ViewModel
|
namespace IRaCIS.Core.Application.ViewModel
|
||||||
|
|||||||
@@ -3,11 +3,9 @@
|
|||||||
// 生成时间 2022-06-07 14:10:54
|
// 生成时间 2022-06-07 14:10:54
|
||||||
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
|
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
using System;
|
|
||||||
using IRaCIS.Core.Domain.Share;
|
using IRaCIS.Core.Domain.Share;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.ComponentModel.DataAnnotations;
|
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
namespace IRaCIS.Core.Application.ViewModel
|
namespace IRaCIS.Core.Application.ViewModel
|
||||||
{
|
{
|
||||||
@@ -163,7 +161,7 @@ namespace IRaCIS.Core.Application.ViewModel
|
|||||||
|
|
||||||
public bool IsCanEditUrgentState { get; set; }
|
public bool IsCanEditUrgentState { get; set; }
|
||||||
|
|
||||||
public DateTime? FirstReadingTime { get;set; }
|
public DateTime? FirstReadingTime { get; set; }
|
||||||
|
|
||||||
public string ReadingDuration
|
public string ReadingDuration
|
||||||
{
|
{
|
||||||
@@ -221,7 +219,6 @@ namespace IRaCIS.Core.Application.ViewModel
|
|||||||
|
|
||||||
public class AnalysisTaskView : ReadingTaskView
|
public class AnalysisTaskView : ReadingTaskView
|
||||||
{
|
{
|
||||||
public bool? IsSelfAnalysis { get; set; }
|
|
||||||
|
|
||||||
public int ConsistentClinicalDataCount { get; set; } = 0;
|
public int ConsistentClinicalDataCount { get; set; } = 0;
|
||||||
|
|
||||||
@@ -298,6 +295,8 @@ namespace IRaCIS.Core.Application.ViewModel
|
|||||||
|
|
||||||
public bool IsUrgent => UnReadCanReadTaskList.Any(t => t.IsUrgent);
|
public bool IsUrgent => UnReadCanReadTaskList.Any(t => t.IsUrgent);
|
||||||
|
|
||||||
|
public bool IsSubjectJudge => UnReadCanReadTaskList.All(t => t.ReadingCategory == ReadingCategory.Judge);
|
||||||
|
|
||||||
public int UnReadTaskCount { get; set; }
|
public int UnReadTaskCount { get; set; }
|
||||||
|
|
||||||
public int UnReadCanReadTaskCount { get; set; }
|
public int UnReadCanReadTaskCount { get; set; }
|
||||||
@@ -317,7 +316,7 @@ namespace IRaCIS.Core.Application.ViewModel
|
|||||||
if (this.SuggesteFinishedTime != null)
|
if (this.SuggesteFinishedTime != null)
|
||||||
{
|
{
|
||||||
var date = DateTime.Now;
|
var date = DateTime.Now;
|
||||||
var timeSpan = SuggesteFinishedTime.Value- date;
|
var timeSpan = SuggesteFinishedTime.Value - date;
|
||||||
if (timeSpan.TotalDays <= 2)
|
if (timeSpan.TotalDays <= 2)
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
@@ -340,10 +339,8 @@ namespace IRaCIS.Core.Application.ViewModel
|
|||||||
|
|
||||||
public int UrgentCount { get; set; }
|
public int UrgentCount { get; set; }
|
||||||
|
|
||||||
// public int UrgentCount => UnReadCanReadTaskList.Count(t => t.IsUrgent);
|
|
||||||
|
|
||||||
public List<IRUnreadTaskView> UnReadCanReadTaskList { get; set; } = new List<IRUnreadTaskView>();
|
public List<IRUnreadTaskView> UnReadCanReadTaskList { get; set; } = new List<IRUnreadTaskView>();
|
||||||
// public List<IRUnreadTaskView> UnReadCanReadTaskList => UnReadTaskList.Where(y => y.IsFrontTaskNeedSignButNotSign == false && (y.IsNeedClinicalDataSign == false || y.IsClinicalDataSign == true)).ToList();
|
|
||||||
|
|
||||||
public List<IRUnreadTaskView> UnReadTaskList { get; set; } = new List<IRUnreadTaskView>();
|
public List<IRUnreadTaskView> UnReadTaskList { get; set; } = new List<IRUnreadTaskView>();
|
||||||
}
|
}
|
||||||
@@ -392,7 +389,7 @@ namespace IRaCIS.Core.Application.ViewModel
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public class GetReadingIQueryableInDto:PageInput
|
public class GetReadingIQueryableInDto : PageInput
|
||||||
{
|
{
|
||||||
public Guid TrialId { get; set; }
|
public Guid TrialId { get; set; }
|
||||||
|
|
||||||
@@ -554,7 +551,7 @@ namespace IRaCIS.Core.Application.ViewModel
|
|||||||
|
|
||||||
public int? SubjectAllocateState { get; set; }
|
public int? SubjectAllocateState { get; set; }
|
||||||
|
|
||||||
public List<Arm> ArmList { get; set; }=new List<Arm>() { };
|
public List<Arm> ArmList { get; set; } = new List<Arm>() { };
|
||||||
|
|
||||||
[NotDefault]
|
[NotDefault]
|
||||||
public Guid TrialReadingCriterionId { get; set; }
|
public Guid TrialReadingCriterionId { get; set; }
|
||||||
@@ -602,9 +599,9 @@ namespace IRaCIS.Core.Application.ViewModel
|
|||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public List<SubjectUserView> DoctorUserList { get; set; }
|
public List<SubjectUserView> DoctorUserList { get; set; }
|
||||||
|
|
||||||
public List<SubjectUserView> PreviousDoctorUserList => DoctorUserList.Where(t => t.OrignalSubjectUserId != null).ToList();
|
public List<SubjectUserView> PreviousDoctorUserList => DoctorUserList.Where(t => t.ReplacedSubjectUserId != null).ToList();
|
||||||
|
|
||||||
public List<SubjectUserView> NowDoctorUserList => DoctorUserList.Where(t => t.OrignalSubjectUserId == null).ToList();
|
public List<SubjectUserView> NowDoctorUserList => DoctorUserList.Where(t => t.ReplacedSubjectUserId == null).ToList();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -622,7 +619,7 @@ namespace IRaCIS.Core.Application.ViewModel
|
|||||||
public bool IsConfirmed { get; set; }
|
public bool IsConfirmed { get; set; }
|
||||||
|
|
||||||
//该属性有值 说明该医生被替换了 分配的时候 要过滤掉
|
//该属性有值 说明该医生被替换了 分配的时候 要过滤掉
|
||||||
public Guid? OrignalSubjectUserId { get; set; }
|
public Guid? ReplacedSubjectUserId { get; set; }
|
||||||
|
|
||||||
public UserSimpleInfo DoctorUser { get; set; }
|
public UserSimpleInfo DoctorUser { get; set; }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,9 @@
|
|||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
using IRaCIS.Application.Contracts;
|
||||||
using IRaCIS.Core.Application.ViewModel;
|
using IRaCIS.Core.Application.ViewModel;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
namespace IRaCIS.Core.Application.Service
|
namespace IRaCIS.Core.Application.Service
|
||||||
{
|
{
|
||||||
@@ -18,6 +20,13 @@ namespace IRaCIS.Core.Application.Service
|
|||||||
|
|
||||||
Task AddConvertedTask(Guid taskId);
|
Task AddConvertedTask(Guid taskId);
|
||||||
|
|
||||||
Task BaseCritrionGenerateVisitTask(Guid trialId, Guid confirmedTrialReadingCriterionId,bool? isManualSelectVisit=null,List<Guid>? subjectVisitIdList=null);
|
/// <summary>
|
||||||
|
/// 导出
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="inDto"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<FileResult> ExportTemplateAsync(ExportTemplateAsyncDto inDto);
|
||||||
|
|
||||||
|
Task BaseCritrionGenerateVisitTask(Guid trialId, Guid confirmedTrialReadingCriterionId, bool? isManualSelectVisit = null, List<Guid>? subjectVisitIdList = null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user