Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing Details

IRC_NewDev
he 2024-09-19 17:48:54 +08:00
commit 01ade2d62f
148 changed files with 7411 additions and 6171 deletions

View File

@ -7,8 +7,12 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="AlibabaCloud.SDK.Sts20150401" Version="1.1.4" />
<PackageReference Include="Aliyun.OSS.SDK.NetCore" Version="2.14.1" />
<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.SqlServer" Version="1.0.5" />
<PackageReference Include="fo-dicom" Version="5.1.3" />

View File

@ -176,6 +176,13 @@ namespace IRaCIS.Core.SCP.Service
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();
}
@ -236,11 +243,11 @@ namespace IRaCIS.Core.SCP.Service
//奇怪的bug 上传的时候用王捷修改的影像会关闭重新连接导致检查id 丢失,然后状态不一致
if (exception == null)
{
var _studyRepository = _serviceProvider.GetService<IRepository<SCPStudy>>();
//将检查设置为传输结束
await _studyRepository.BatchUpdateNoTrackingAsync(t => _SCPStudyIdList.Contains(t.Id), u => new SCPStudy() { IsUploadFinished = true });
//var _studyRepository = _serviceProvider.GetService<IRepository<SCPStudy>>();
////将检查设置为传输结束
//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}");

View File

@ -14,48 +14,75 @@ 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 IRaCIS.Core.Infrastructure.NewtonsoftJson;
using Amazon.Runtime;
using Amazon.SecurityToken;
using Amazon.SecurityToken.Model;
using Amazon;
using Amazon.S3;
using Amazon.S3.Model;
using MassTransit;
using AlibabaCloud.SDK.Sts20150401;
namespace IRaCIS.Core.SCP
{
#region 绑定和返回模型
[LowerCamelCaseJson]
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 string EndPoint { get; set; }
public bool UseSSL { get; set; }
public string AccessKeyId { get; set; }
public string RoleArn { get; set; }
public string SecretAccessKey { get; set; }
public string BucketName { 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 RegionId { get; set; }
public string AccessKeyId { get; set; }
public string AccessKeySecret { get; set; }
public string internalEndpoint { get; set; }
public string InternalEndpoint { get; set; }
public string endPoint { get; set; }
public string bucketName { get; set; }
public string EndPoint { get; set; }
public string BucketName { get; set; }
public string roleArn { get; set; }
public string RoleArn { get; set; }
public string Region { get; set; }
public string ViewEndpoint { get; set; }
public int DurationSeconds { 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; }
@ -66,27 +93,46 @@ namespace IRaCIS.Core.SCP
{
public string ObjectStoreUse { get; set; }
public AliyunOSSOptions AliyunOSS { get; set; }
public AliyunOSSTempToken AliyunOSS { get; set; }
public MinIOOptions MinIO { get; set; }
public AWSOptions AWS { get; set; }
public AWSTempToken AWS { get; set; }
}
[LowerCamelCaseJson]
public class AliyunOSSTempToken
{
public string AccessKeyId { get; set; }
public string AccessKeySecret { get; set; }
public string SecurityToken { get; set; }
public string Expiration { get; set; }
public string EndPoint { get; set; }
public string BucketName { get; set; }
public string Region { get; set; }
public string BucketName { 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
{
@ -95,6 +141,10 @@ namespace IRaCIS.Core.SCP
AWS = 2,
}
#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);
@ -106,6 +156,9 @@ namespace IRaCIS.Core.SCP
public Task<string> GetSignedUrl(string ossRelativePath);
public Task DeleteFromPrefix(string prefix);
public Task<ObjectStoreDTO> GetObjectStoreTempToken();
}
@ -113,10 +166,16 @@ namespace IRaCIS.Core.SCP
{
public ObjectStoreServiceOptions ObjectStoreServiceOptions { get; set; }
private AliyunOSSTempToken AliyunOSSTempToken { get; set; }
private AWSTempToken AWSTempToken { get; set; }
public OSSService(IOptionsMonitor<ObjectStoreServiceOptions> options)
{
ObjectStoreServiceOptions = options.CurrentValue;
GetObjectStoreTempToken().GetAwaiter().GetResult();
}
/// <summary>
@ -130,8 +189,6 @@ namespace IRaCIS.Core.SCP
public async Task<string> UploadToOSSAsync(Stream fileStream, string oosFolderPath, string fileRealName, bool isFileNameAddGuid = true)
{
var ossRelativePath = isFileNameAddGuid ? $"{oosFolderPath}/{Guid.NewGuid()}_{fileRealName}" : $"{oosFolderPath}/{fileRealName}";
//var ossRelativePath = $"{oosFolderPath}/{Guid.NewGuid()}_{fileRealName}";
//var ossRelativePath = oosFolderPath + "/" + fileRealName;
try
{
@ -148,12 +205,12 @@ namespace IRaCIS.Core.SCP
{
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")
@ -161,12 +218,12 @@ namespace IRaCIS.Core.SCP
var minIOConfig = ObjectStoreServiceOptions.MinIO;
var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.endPoint}:{minIOConfig.port}")
.WithCredentials(minIOConfig.accessKey, minIOConfig.secretKey).WithSSL(minIOConfig.useSSL)
var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.EndPoint}:{minIOConfig.Port}")
.WithCredentials(minIOConfig.AccessKeyId, minIOConfig.SecretAccessKey).WithSSL(minIOConfig.UseSSL)
.Build();
var putObjectArgs = new PutObjectArgs()
.WithBucket(minIOConfig.bucketName)
.WithBucket(minIOConfig.BucketName)
.WithObject(ossRelativePath)
.WithStreamData(memoryStream)
.WithObjectSize(memoryStream.Length);
@ -175,20 +232,29 @@ namespace IRaCIS.Core.SCP
}
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()
.WithBucket(minIOConfig.bucketName)
.WithObject(ossRelativePath)
.WithStreamData(memoryStream)
.WithObjectSize(memoryStream.Length);
//提供awsEndPoint域名进行访问配置
var clientConfig = new AmazonS3Config
{
RegionEndpoint = RegionEndpoint.USEast1,
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
{
@ -216,6 +282,7 @@ namespace IRaCIS.Core.SCP
/// </summary>
/// <param name="localFilePath"></param>
/// <param name="oosFolderPath"></param>
/// <param name="isFileNameAddGuid"></param>
/// <returns></returns>
/// <exception cref="BusinessValidationFailedException"></exception>
public async Task<string> UploadToOSSAsync(string localFilePath, string oosFolderPath, bool isFileNameAddGuid = true)
@ -225,17 +292,14 @@ namespace IRaCIS.Core.SCP
var ossRelativePath = isFileNameAddGuid ? $"{oosFolderPath}/{Guid.NewGuid()}_{localFileName}" : $"{oosFolderPath}/{localFileName}";
//var ossRelativePath = oosFolderPath + "/" + localFileName;
if (ObjectStoreServiceOptions.ObjectStoreUse == "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")
@ -243,12 +307,12 @@ namespace IRaCIS.Core.SCP
var minIOConfig = ObjectStoreServiceOptions.MinIO;
var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.endPoint}:{minIOConfig.port}")
.WithCredentials(minIOConfig.accessKey, minIOConfig.secretKey).WithSSL(minIOConfig.useSSL)
var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.EndPoint}:{minIOConfig.Port}")
.WithCredentials(minIOConfig.AccessKeyId, minIOConfig.SecretAccessKey).WithSSL(minIOConfig.UseSSL)
.Build();
var putObjectArgs = new PutObjectArgs()
.WithBucket(minIOConfig.bucketName)
.WithBucket(minIOConfig.BucketName)
.WithObject(ossRelativePath)
.WithFileName(localFilePath);
@ -256,19 +320,29 @@ namespace IRaCIS.Core.SCP
}
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}")
.WithCredentials(minIOConfig.accessKey, minIOConfig.secretKey).WithSSL(minIOConfig.useSSL)
.Build();
//提供awsEndPoint域名进行访问配置
var clientConfig = new AmazonS3Config
{
RegionEndpoint = RegionEndpoint.USEast1,
UseHttp = true,
};
var putObjectArgs = new PutObjectArgs()
.WithBucket(minIOConfig.bucketName)
.WithObject(ossRelativePath)
.WithFileName(localFilePath);
var amazonS3Client = new AmazonS3Client(credentials, clientConfig);
var putObjectRequest = new Amazon.S3.Model.PutObjectRequest()
{
BucketName = awsConfig.BucketName,
FilePath = localFilePath,
Key = ossRelativePath,
};
await amazonS3Client.PutObjectAsync(putObjectRequest);
await minioClient.PutObjectAsync(putObjectArgs);
}
else
{
@ -291,10 +365,10 @@ namespace IRaCIS.Core.SCP
{
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))
@ -308,12 +382,12 @@ namespace IRaCIS.Core.SCP
{
var minIOConfig = ObjectStoreServiceOptions.MinIO;
var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.endPoint}:{minIOConfig.port}")
.WithCredentials(minIOConfig.accessKey, minIOConfig.secretKey).WithSSL(minIOConfig.useSSL)
var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.EndPoint}:{minIOConfig.Port}")
.WithCredentials(minIOConfig.AccessKeyId, minIOConfig.SecretAccessKey).WithSSL(minIOConfig.UseSSL)
.Build();
var getObjectArgs = new GetObjectArgs()
.WithBucket(minIOConfig.bucketName)
.WithBucket(minIOConfig.BucketName)
.WithObject(ossRelativePath)
.WithFile(localFilePath);
@ -322,18 +396,30 @@ namespace IRaCIS.Core.SCP
}
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();
// 提供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 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
{
@ -363,10 +449,10 @@ namespace IRaCIS.Core.SCP
{
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。
var req = new GeneratePresignedUriRequest(aliConfig.bucketName, ossRelativePath, SignHttpMethod.Get)
var req = new GeneratePresignedUriRequest(aliConfig.BucketName, ossRelativePath, SignHttpMethod.Get)
{
// 设置签名URL过期时间默认值为3600秒。
Expiration = DateTime.Now.AddHours(1),
@ -380,13 +466,13 @@ namespace IRaCIS.Core.SCP
{
var minIOConfig = ObjectStoreServiceOptions.MinIO;
var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.endPoint}:{minIOConfig.port}")
.WithCredentials(minIOConfig.accessKey, minIOConfig.secretKey).WithSSL(minIOConfig.useSSL)
var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.EndPoint}:{minIOConfig.Port}")
.WithCredentials(minIOConfig.AccessKeyId, minIOConfig.SecretAccessKey).WithSSL(minIOConfig.UseSSL)
.Build();
var args = new PresignedGetObjectArgs()
.WithBucket(minIOConfig.bucketName)
.WithBucket(minIOConfig.BucketName)
.WithObject(ossRelativePath)
.WithExpiry(3600)
/*.WithHeaders(reqParams)*/;
@ -403,18 +489,27 @@ namespace IRaCIS.Core.SCP
}
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()
.WithBucket(minIOConfig.bucketName)
.WithObject(ossRelativePath)
.WithExpiry(3600);
// 提供awsAccessKeyId和awsSecretAccessKey构造凭证
var credentials = new SessionAWSCredentials(AWSTempToken.AccessKeyId, AWSTempToken.SecretAccessKey, AWSTempToken.SessionToken);
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);
@ -435,8 +530,248 @@ namespace IRaCIS.Core.SCP
}
}
/// <summary>
/// 删除某个目录的文件
/// </summary>
/// <param name="prefix"></param>
/// <returns></returns>
public async Task DeleteFromPrefix(string prefix)
{
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 async Task<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 = 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,
};
AWSTempToken = tempToken;
return new ObjectStoreDTO() { ObjectStoreUse = ObjectStoreServiceOptions.ObjectStoreUse, AWS = tempToken };
}
else
{
throw new BusinessValidationFailedException("未定义的存储介质类型");
}
}
}
}

View File

@ -9,15 +9,16 @@
"ObjectStoreService": {
"ObjectStoreUse": "AliyunOSS",
"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-store",
"roleArn": "acs:ram::1899121822495495:role/oss-upload",
"viewEndpoint": "https://zy-irc-cache.oss-cn-shanghai.aliyuncs.com",
"region": "oss-cn-shanghai"
"RegionId": "cn-shanghai",
"InternalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com",
"EndPoint": "https://oss-cn-shanghai.aliyuncs.com",
"AccessKeyId": "LTAI5tNRTsqL6aWmHkDmTwoH",
"AccessKeySecret": "7mtGz3qrYWI6JMMBZiLeC119VWicZH",
"RoleArn": "acs:ram::1899121822495495:role/irc-oss-access",
"BucketName": "zy-irc-store",
"ViewEndpoint": "https://zy-irc-cache.oss-cn-shanghai.aliyuncs.com",
"Region": "oss-cn-shanghai",
"DurationSeconds": 7200
}
},

View File

@ -9,15 +9,16 @@
"ObjectStoreService": {
"ObjectStoreUse": "AliyunOSS",
"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"
"RegionId": "cn-shanghai",
"InternalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com",
"EndPoint": "https://oss-cn-shanghai.aliyuncs.com",
"AccessKeyId": "LTAI5tRRZehUp2V9pyTPtAJm",
"AccessKeySecret": "FLizxkHsMm4CGYHtkV8E3PNJJZU7oV",
"RoleArn": "acs:ram::1899121822495495:role/dev-oss-access",
"BucketName": "zy-irc-test-store",
"ViewEndpoint": "https://zy-irc-test-store.oss-cn-shanghai.aliyuncs.com",
"Region": "oss-cn-shanghai",
"DurationSeconds": 7200
},
"MinIO": {
@ -28,16 +29,8 @@
"secretKey": "TzgvyA3zGXMUnpilJNUlyMYHfosl1hBMl6lxPmjy",
"bucketName": "hir-test",
"viewEndpoint": "http://106.14.89.110:9001/hir-test/"
},
"AWS": {
"endPoint": "s3.us-east-1.amazonaws.com",
"useSSL": false,
"accessKey": "AKIAZQ3DRSOHFPJJ6FEU",
"secretKey": "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",
"bucketName": "ei-irc-test-store",
"viewEndpoint": "https://ei-irc-test-store.s3.amazonaws.com/"
}
},
"ConnectionStrings": {

View File

@ -9,12 +9,15 @@
"ObjectStoreService": {
"ObjectStoreUse": "AWS",
"AWS": {
"endPoint": "s3.us-east-1.amazonaws.com",
"useSSL": true,
"accessKey": "AKIAW3MEAFJX5P32P6NA",
"secretKey": "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",
"bucketName": "ei-med-s3-lili-store",
"viewEndpoint": "https://ei-med-s3-lili-store.s3.amazonaws.com/"
"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": "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",
"BucketName": "ei-med-s3-lili-uat-store",
"ViewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com/",
"DurationSeconds": 7200
}
},
"ConnectionStrings": {

View File

@ -9,17 +9,20 @@
"ObjectStoreService": {
"ObjectStoreUse": "AWS",
"AWS": {
"endPoint": "s3.us-east-1.amazonaws.com",
"useSSL": true,
"accessKey": "AKIAW3MEAFJXUO6XYFYN",
"secretKey": "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",
"bucketName": "ei-med-s3-lili-uat-store",
"viewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com/"
"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": "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",
"BucketName": "ei-med-s3-lili-uat-store",
"ViewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com/",
"DurationSeconds": 7200
}
},
"ConnectionStrings": {
"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"
"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": [

View File

@ -9,15 +9,16 @@
"ObjectStoreService": {
"ObjectStoreUse": "AliyunOSS",
"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-uat-store",
"roleArn": "acs:ram::1899121822495495:role/oss-upload",
"viewEndpoint": "https://zy-irc-uat-store.oss-cn-shanghai.aliyuncs.com",
"region": "oss-cn-shanghai"
"RegionId": "cn-shanghai",
"InternalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com",
"EndPoint": "https://oss-cn-shanghai.aliyuncs.com",
"AccessKeyId": "LTAI5tRRZehUp2V9pyTPtAJm",
"AccessKeySecret": "FLizxkHsMm4CGYHtkV8E3PNJJZU7oV",
"RoleArn": "acs:ram::1899121822495495:role/dev-oss-access",
"BucketName": "zy-irc-uat-store",
"ViewEndpoint": "https://zy-irc-uat-store.oss-cn-shanghai.aliyuncs.com",
"Region": "oss-cn-shanghai",
"DurationSeconds": 7200
}
},
"ConnectionStrings": {

View File

@ -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; }
}
}
}

View File

@ -37,6 +37,7 @@ using Amazon.SecurityToken.Model;
using Amazon.SecurityToken;
using Amazon;
using AssumeRoleRequest = Amazon.SecurityToken.Model.AssumeRoleRequest;
using AutoMapper;
namespace IRaCIS.Api.Controllers
{
@ -109,8 +110,12 @@ namespace IRaCIS.Api.Controllers
[FromServices] ITokenService _tokenService,
[FromServices] IReadingImageTaskService readingImageTaskService,
[FromServices] IOptionsMonitor<ServiceVerifyConfigOption> _verifyConfig,
[FromServices] IOptionsMonitor<SystemEmailSendConfig> _emailConfig,
[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
if (loginUser.UserId != null && _verifyConfig.CurrentValue.OpenLoginMFA)
@ -143,10 +148,11 @@ namespace IRaCIS.Api.Controllers
// 验证阅片休息时间
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);
}
@ -274,6 +280,8 @@ namespace IRaCIS.Api.Controllers
}
}
returnModel.Data.CompanyInfo = companyInfo;
return returnModel;
}
@ -283,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")]
@ -312,7 +326,7 @@ namespace IRaCIS.Api.Controllers
var result = await _oSSService.GetObjectStoreTempToken();
result.AWS =await GetAWSTemToken(options.CurrentValue);
result.AWS = await GetAWSTemToken(options.CurrentValue);
return ResponseOutput.Ok(result);

View File

@ -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>

View File

@ -96,6 +96,12 @@
<Folder Include="Properties\PublishProfiles\" />
</ItemGroup>
<ItemGroup>
<Content Update="appsettings.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ProjectExtensions>
<VisualStudio>
<UserProperties properties_4launchsettings_1json__JsonSchema="" />

View File

@ -29,7 +29,7 @@
<param name="doctorId"></param>
<returns></returns>
</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.Application.Services.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.Application.Services.IMailVerificationService)">
<summary> 系统用户登录接口[New] </summary>
</member>
<member name="M:IRaCIS.Core.API.Controllers.Special.FinancialChangeController.AddOrUpdateTrialInspection(IRaCIS.Core.Application.Service.Inspection.DTO.DataInspectionDto{IRaCIS.Application.Contracts.TrialCommand})">
@ -375,11 +375,6 @@
<param name="memberSerialization">序列化成员</param>
<returns></returns>
</member>
<member name="T:TimeZoneAdjustmentMiddleware">
<summary>
废弃,没用
</summary>
</member>
<member name="T:ZhaoXi._001.NET5Demo.Practice.WebApi.Utility.Jwt.CustomHSJWTService">
<summary>
对称可逆加密

View File

@ -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);
}
}

View File

@ -111,7 +111,7 @@ builder.Services.AddControllers(options =>
options.Filters.Add<ModelActionFilter>();
options.Filters.Add<ProjectExceptionFilter>();
options.Filters.Add<UnitOfWorkFilter>();
options.Filters.Add<EncreptApiResultFilter>(10);
//options.Filters.Add<EncreptApiResultFilter>(10);
options.Filters.Add<LimitUserRequestAuthorization>();
@ -122,7 +122,7 @@ builder.Services.AddOptions().Configure<SystemEmailSendConfig>(_configuration.Ge
builder.Services.AddOptions().Configure<ServiceVerifyConfigOption>(_configuration.GetSection("BasicSystemConfig"));
builder.Services.AddOptions().Configure<AliyunOSSOptions>(_configuration.GetSection("AliyunOSS"));
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.Configure<IRaCISBasicConfigOption>(_configuration.GetSection("IRaCISBasicConfig"));
@ -218,6 +218,7 @@ var env = app.Environment;
#region 配置中间件
app.UseMiddleware<EncryptionRequestMiddleware>();
// Configure the HTTP request pipeline.

View File

@ -8,9 +8,11 @@ using Medallion.Threading;
using Medallion.Threading.SqlServer;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using StackExchange.Redis;
namespace IRaCIS.Core.API
@ -46,10 +48,11 @@ namespace IRaCIS.Core.API
else
{
options.UseSqlServer(configuration.GetSection("ConnectionStrings:RemoteNew").Value, contextOptionsBuilder => contextOptionsBuilder.EnableRetryOnFailure());
}
//迁移的时候,不生成外键
options.ReplaceService<IMigrationsSqlGenerator, NoForeignKeyMigrationsSqlGenerator>();
options.UseLoggerFactory(logFactory);

View File

@ -35,7 +35,9 @@ namespace IRaCIS.Core.API
else
{
// 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

View File

@ -13,15 +13,16 @@
"ObjectStoreService": {
"ObjectStoreUse": "AliyunOSS",
"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-store",
"roleArn": "acs:ram::1899121822495495:role/oss-upload",
"viewEndpoint": "https://zy-irc-cache.oss-cn-shanghai.aliyuncs.com",
"region": "oss-cn-shanghai"
"RegionId": "cn-shanghai",
"InternalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com",
"EndPoint": "https://oss-cn-shanghai.aliyuncs.com",
"AccessKeyId": "LTAI5tNRTsqL6aWmHkDmTwoH",
"AccessKeySecret": "7mtGz3qrYWI6JMMBZiLeC119VWicZH",
"RoleArn": "acs:ram::1899121822495495:role/irc-oss-access",
"BucketName": "zy-irc-store",
"ViewEndpoint": "https://zy-irc-cache.oss-cn-shanghai.aliyuncs.com",
"Region": "oss-cn-shanghai",
"DurationSeconds": 7200
},
"MinIO": {
"endpoint": "http://192.168.3.68",

View File

@ -15,15 +15,16 @@
"ObjectStoreService": {
"ObjectStoreUse": "AliyunOSS",
"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-store",
"roleArn": "acs:ram::1899121822495495:role/oss-upload",
"viewEndpoint": "https://zy-irc-cache.oss-cn-shanghai.aliyuncs.com",
"region": "oss-cn-shanghai"
"RegionId": "cn-shanghai",
"InternalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com",
"EndPoint": "https://oss-cn-shanghai.aliyuncs.com",
"AccessKeyId": "LTAI5tNRTsqL6aWmHkDmTwoH",
"AccessKeySecret": "7mtGz3qrYWI6JMMBZiLeC119VWicZH",
"RoleArn": "acs:ram::1899121822495495:role/irc-oss-access",
"BucketName": "zy-irc-store",
"ViewEndpoint": "https://zy-irc-cache.oss-cn-shanghai.aliyuncs.com",
"Region": "oss-cn-shanghai",
"DurationSeconds": 7200
},
"MinIO": {
"endpoint": "http://192.168.3.68",

View File

@ -19,10 +19,10 @@
"RegionId": "cn-shanghai",
"InternalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com",
"EndPoint": "https://oss-cn-shanghai.aliyuncs.com",
"AccessKeyId": "LTAI5tJV76pYX5yPg1N9QVE8",
"AccessKeySecret": "roRNLa9YG1of4pYruJGCNKBXEWTAWa",
"AccessKeyId": "LTAI5tRRZehUp2V9pyTPtAJm",
"AccessKeySecret": "FLizxkHsMm4CGYHtkV8E3PNJJZU7oV",
"RoleArn": "acs:ram::1899121822495495:role/dev-oss-access",
"BucketName": "zy-irc-test-store",
"RoleArn": "acs:ram::1899121822495495:role/webdirect",
"ViewEndpoint": "https://zy-irc-test-store.oss-cn-shanghai.aliyuncs.com",
"Region": "oss-cn-shanghai",
"DurationSeconds": 7200
@ -40,11 +40,11 @@
"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": "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",
"RoleArn": "arn:aws:iam::471112624751:role/uat_s3_access",
"AccessKeyId": "AKIAW3MEAFJX7IPXISP4",
"SecretAccessKey": "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",
"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
}
},

View File

@ -15,18 +15,6 @@
"ObjectStoreService": {
"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": {
"endPoint": "44.210.231.169",
"port": "9001",
@ -38,12 +26,15 @@
},
"AWS": {
"endPoint": "s3.us-east-1.amazonaws.com",
"useSSL": true,
"accessKey": "AKIAW3MEAFJX5P32P6NA",
"secretKey": "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",
"bucketName": "ei-med-s3-lili-store",
"viewEndpoint": "https://ei-med-s3-lili-store.s3.amazonaws.com/"
"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": "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",
"BucketName": "ei-med-s3-lili-uat-store",
"ViewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com",
"DurationSeconds": 7200
}
},
"BasicSystemConfig": {
@ -86,7 +77,7 @@
},
"SystemPacsConfig": {
"Port": "11113",
"Port": "104",
"IP": "44.210.231.169"
}

View File

@ -13,19 +13,7 @@
"ObjectStoreService": {
"ObjectStoreUse": "MinIO",
"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"
},
"ObjectStoreUse": "AWS",
"MinIO": {
//"endPoint": "hir-oss.uat.extimaging.com",
//"port": "443",
@ -44,23 +32,26 @@
},
"AWS": {
"endPoint": "s3.us-east-1.amazonaws.com",
"useSSL": true,
"accessKey": "AKIAZQ3DRSOHFPJJ6FEU",
"secretKey": "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",
"bucketName": "ei-irc-test-store",
"viewEndpoint": "https://ei-irc-test-store.s3.amazonaws.com/"
"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": "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",
"BucketName": "ei-med-s3-lili-uat-store",
"ViewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com",
"DurationSeconds": 7200
}
},
"BasicSystemConfig": {
"OpenUserComplexPassword": false,
"OpenUserComplexPassword": true,
"OpenSignDocumentBeforeWork": false,
"OpenSignDocumentBeforeWork": true,
"OpenTrialRelationDelete": true,
"OpenLoginLimit": false,
"OpenLoginLimit": true,
"LoginMaxFailCount": 5,
@ -72,7 +63,9 @@
"ReadingRestTimeMin": 10,
"IsNeedChangePassWord": true,
"ChangePassWordDays": 90
"ChangePassWordDays": 90,
"OpenLoginMFA": true
},
"SystemEmailSendConfig": {
@ -92,8 +85,8 @@
},
"SystemPacsConfig": {
"Port": "11113",
"IP": "3.226.182.187,1435"
"Port": "104",
"IP": "3.226.182.187"
}
}

View File

@ -7,11 +7,11 @@
}
},
"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"
//"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"
//"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"
"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"
},
"ObjectStoreService": {
@ -36,19 +36,22 @@
},
"AWS": {
"endPoint": "s3.us-east-1.amazonaws.com",
"useSSL": true,
"accessKey": "AKIAW3MEAFJXUO6XYFYN",
"secretKey": "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",
"bucketName": "ei-med-s3-lili-uat-store",
"viewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com/"
"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": "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",
"BucketName": "ei-med-s3-lili-uat-store",
"ViewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com/",
"DurationSeconds": 7200
}
},
"BasicSystemConfig": {
"OpenUserComplexPassword": false,
"OpenUserComplexPassword": true,
"OpenSignDocumentBeforeWork": false,
"OpenSignDocumentBeforeWork": true,
"OpenTrialRelationDelete": true,
@ -66,7 +69,7 @@
"ChangePassWordDays": 90,
"OpenLoginMFA": true
"OpenLoginMFA": false
},
"SystemEmailSendConfig": {
@ -86,8 +89,8 @@
},
"SystemPacsConfig": {
"Port": "11113",
"IP": "3.226.182.187,1435"
"Port": "104",
"IP": "3.226.182.187"
}
}

View File

@ -18,10 +18,10 @@
"RegionId": "cn-shanghai",
"InternalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com",
"EndPoint": "https://oss-cn-shanghai.aliyuncs.com",
"AccessKeyId": "LTAI5tJV76pYX5yPg1N9QVE8",
"AccessKeySecret": "roRNLa9YG1of4pYruJGCNKBXEWTAWa",
"AccessKeyId": "LTAI5tRRZehUp2V9pyTPtAJm",
"AccessKeySecret": "FLizxkHsMm4CGYHtkV8E3PNJJZU7oV",
"RoleArn": "acs:ram::1899121822495495:role/dev-oss-access",
"BucketName": "zy-irc-uat-store",
"RoleArn": "acs:ram::1899121822495495:role/webdirect",
"ViewEndpoint": "https://zy-irc-uat-store.oss-cn-shanghai.aliyuncs.com",
"Region": "oss-cn-shanghai",
"DurationSeconds": 7200

View File

@ -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": {
"SwitchingMode": "RemainingDiskCapacity",
"SwitchingRatio": 80,
@ -93,9 +59,10 @@
"DefaultPassword": "123456",
"ImageShareExpireDays": 10
},
"EncrypteResponseConfig": {
"IsEnable": true,
"Base64RSAPublicKey": "LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0NCk1JSUJJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBTUlJQkNnS0NBUUVBaHp3T1hYTWYyaEFkS1ZoWHczYUYNCmNaT3QycE1lcmdEaFVrOUdQK2s4VDBrUjFTRVlGVGtzNlkzaEVvL0dRTExqMHZFYVV3bTNhSFNuTTl5NmdLRWoNCmY5cTN6dkoyZzRSQjE4Z0UrTnNWWi9DMkVRZ3k5OWFiWGc5TitGREVlT0NmSjlSRTJPV3JBQ2s0V0RPbFFUdXYNCnhvR2JmcnkwVElSaFBrOGtuYkFmVkZ1and1VXJGblpJZ0ExYXhKZVZ6aDhwcmV1SEgreW1jdHp6NVo4V1pSV3kNCi9ISURHUy90dkg2NUMra2l6cUxRYUpKNHYwODMrRGpaVTBmNzNCdkk5eWt1dW1saXFzY1pvU2preDFOUFJwSkUNCkFtMVFNQ0hMRCtFdzlHT2Vsc2Mwa1ZxdjdaeEF1TkFrMkZuUURNRk1BUmZuUFd0aGVhOGZYVTJsMW9ROWs3WDcNCmN3SURBUUFCDQotLS0tLUVORCBQVUJMSUMgS0VZLS0tLS0NCg==",
"Base64RSAPrivateKey": "LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQ0KTUlJRW9nSUJBQUtDQVFFQWh6d09YWE1mMmhBZEtWaFh3M2FGY1pPdDJwTWVyZ0RoVWs5R1ArazhUMGtSMVNFWQ0KRlRrczZZM2hFby9HUUxMajB2RWFVd20zYUhTbk05eTZnS0VqZjlxM3p2SjJnNFJCMThnRStOc1ZaL0MyRVFneQ0KOTlhYlhnOU4rRkRFZU9DZko5UkUyT1dyQUNrNFdET2xRVHV2eG9HYmZyeTBUSVJoUGs4a25iQWZWRnVqd3VVcg0KRm5aSWdBMWF4SmVWemg4cHJldUhIK3ltY3R6ejVaOFdaUld5L0hJREdTL3R2SDY1QytraXpxTFFhSko0djA4Mw0KK0RqWlUwZjczQnZJOXlrdXVtbGlxc2Nab1Nqa3gxTlBScEpFQW0xUU1DSExEK0V3OUdPZWxzYzBrVnF2N1p4QQ0KdU5BazJGblFETUZNQVJmblBXdGhlYThmWFUybDFvUTlrN1g3Y3dJREFRQUJBb0lCQUNDRFoxNi9XWWFYZmpOZA0KQ29pemU2VFJZU2llVzI5eFJic0ExVDV6YUcwVmY4U1NsdFF2Y1dWYmw2UGJUa3BxMkF4MHJDUVB2M2xOSm8vNA0KL3h3QzRlS1E1c1ZLRlFWTXJIbmhISlRxTTJ6UWVpMkJINlBuaEdZcVh0QVhOdzFxejhrSEoyQlFZM3IvN2d5Qw0KcWpZVFVCRDFRem5HeThCanlXOXVIcnNNeDVPRHRRZWxBM3B1TFd1bXZNb3Z1L2JhaDZvTGtOSHY4b0VTdzhGSQ0KTllyTUtscHhFTjZaWUdwSTl2VTZnYUhuTmhEa2ExTHlvUnZ5NnA2dTRLR0FsRTc1VXk4T0dsdncydU5uay9sdg0KSEMyYnY5TnlCRGJpSFNDY0MyK1JXUXMrN0tNWFlwYnBvTVFCR0hqV01GRHVBODFaUCs1TWYxUm9yQUpRNGxrRw0KQnRDQThva0NnWUVBeWY4alBjcFIvQ3dJNU5MYnlwb3ZUWEFHVkFKMmtWRlJVUC9HT2ZOMkFyYWMvL20wdDJ5NA0KemNYVkJZc0pJeHkvVWYxRTFJNFg3VFg3V3NBNGxVNGlPTkwzTnN4dDBEbk1PV2tKUlBPZlF1bW1JaWw5QVRiYQ0KTnRVWFNlTmRoUFFGMGlCb21acFFJYWpSN1RmUnVBbzR6dmpTLzkzeXZZY0lIWU1zM0tjR00ya0NnWUVBcTJPbg0KZlp0RmhLTElGanVlRzRrNklGTWdjbytEUUh5TTFWSUp5Tk05K1o2TEgybzI5eDJCaSs2Qm82M2NKUjQ2STZncQ0KNWUrSTBvdzZRYmNQeTZUNHFSQ0o3Ujd6MllkdEw4eXdJTkNYS3U0cC9qaFNqNWJ1TzFJWlI3ZStSV29CakNtUQ0KWFd0ZVBCbldqWVlLdVRCazROc2FXV09GTXg1QndKdUp2MjBnQ0hzQ2dZQlV4QnFYM1lWV0cyeUlDZXh1TXhIUw0KbjBZb2p2Z090MTgyYkg5VTVsUUpnM1NTL3NqVmlHeHMvYTROSzNGa0tMWW93KzNVZk9TUmlPdTRBNTQ3R1pURw0KMzlFYVQrTnRWRFBkaTdSMkdQNG1hRUp0WjVlcm9NY2w1M3BrYVdOZlhiL3JrK29STzI2UkVYVTI1UXUrL1pzbA0KVDhuTDBlb0JtdDdPODdNcHpYV09zUUtCZ0ZxVGFQSGx2RUNUY3FEbFV2S0VmRmFXOTkvelhrOFhRNnA5RjdTdA0KaHVSRDJJeDZxcC9BVlRWcGo5Tzd6MHRDaFVGUTM1THpHMkVDUU10My9uNEdLbS9XMEwyakRRWWFIeWNTeXNZYw0KMXJjV2ROVG9XU0dQaDBtTVl0WFhFbFJHNkpoMVl0a3NJL29wUVkwN21MRTBGU3dNUHdtY29jbFpKVEN3UW9VTA0KRzlHL0FvR0FWM25kcWcydnUyR0x4TlRUbm1UTWRJNFB3UzBmN0V4VnVNUnRicGZyOWhKNzlDakVNTGFXQ1FsNg0KeE43TElMTnArNVQwQW1DZVBqcitkbnJkRUNidFZPTDFybDc3Z0krRkwzaVVqYmZmMVZqa0N3M0x6K3cyb1FFdA0KbGE4aTZrL1NRK01iYkRPaWRJOVczdlN6MmlJRlZobWJiK1Q2SlZwakxqNjlkblM3eUxZPQ0KLS0tLS1FTkQgUlNBIFBSSVZBVEUgS0VZLS0tLS0NCg==",
"IsResponseEncreptEnable": true,
"ApiPathList": [
"/test/get"
]

View File

@ -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();
}
}
}

View File

@ -0,0 +1,91 @@
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Paddings;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Crypto;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Org.BouncyCastle.Crypto.Modes;
namespace IRaCIS.Core.Application.BusinessFilter;
public class AesEncryption
{
// AES 加密(不带 IV
public static string Encrypt(string plainText, string key)
{
var keyBytes = Encoding.UTF8.GetBytes(key);
// 使用 AES 引擎 + PKCS7 填充
var engine = new AesEngine();
var blockCipher = new PaddedBufferedBlockCipher(engine, new Pkcs7Padding());
blockCipher.Init(true, new KeyParameter(keyBytes)); // true 表示加密
var inputBytes = Encoding.UTF8.GetBytes(plainText);
var encryptedBytes = ProcessCipher(blockCipher, inputBytes);
// 返回 Base64 编码的加密字符串
return Convert.ToBase64String(encryptedBytes);
}
// AES 解密(不带 IV
public static string Decrypt(string encryptedText, string key)
{
var keyBytes = Encoding.UTF8.GetBytes(key);
var cipherBytes = Convert.FromBase64String(encryptedText);
// 使用 AES 引擎 + PKCS7 填充
var engine = new AesEngine();
var blockCipher = new PaddedBufferedBlockCipher(engine, new Pkcs7Padding());
blockCipher.Init(false, new KeyParameter(keyBytes)); // false 表示解密
var decryptedBytes = ProcessCipher(blockCipher, cipherBytes);
return Encoding.UTF8.GetString(decryptedBytes);
}
// AES 加密(带 IV
public static string Encrypt(string plainText, string key, string iv)
{
var keyBytes = Encoding.UTF8.GetBytes(key);
var ivBytes = Encoding.UTF8.GetBytes(iv);
// 使用 AES 引擎 + PKCS7 填充 + CBC 模式
var engine = new AesEngine();
var blockCipher = new PaddedBufferedBlockCipher(new CbcBlockCipher(engine), new Pkcs7Padding());
blockCipher.Init(true, new ParametersWithIV(new KeyParameter(keyBytes), ivBytes)); // true 表示加密
var inputBytes = Encoding.UTF8.GetBytes(plainText);
var encryptedBytes = ProcessCipher(blockCipher, inputBytes);
// 返回 Base64 编码的加密字符串
return Convert.ToBase64String(encryptedBytes);
}
// AES 解密(带 IV
public static string Decrypt(string encryptedText, string key, string iv)
{
var keyBytes = Encoding.UTF8.GetBytes(key);
var ivBytes = Encoding.UTF8.GetBytes(iv);
var cipherBytes = Convert.FromBase64String(encryptedText);
// 使用 AES 引擎 + PKCS7 填充 + CBC 模式
var engine = new AesEngine();
var blockCipher = new PaddedBufferedBlockCipher(new CbcBlockCipher(engine), new Pkcs7Padding());
blockCipher.Init(false, new ParametersWithIV(new KeyParameter(keyBytes), ivBytes)); // false 表示解密
var decryptedBytes = ProcessCipher(blockCipher, cipherBytes);
return Encoding.UTF8.GetString(decryptedBytes);
}
// 处理加密/解密数据
private static byte[] ProcessCipher(IBufferedCipher cipher, byte[] input)
{
var output = new byte[cipher.GetOutputSize(input.Length)];
int length = cipher.ProcessBytes(input, 0, input.Length, output, 0);
length += cipher.DoFinal(output, length);
Array.Resize(ref output, length); // 调整输出数组大小以适应实际数据长度
return output;
}
}

View File

@ -0,0 +1,64 @@
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;
/// <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();
}
}

View File

@ -0,0 +1,134 @@
using DocumentFormat.OpenXml.InkML;
using IRaCIS.Core.Domain.Share;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Options;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace IRaCIS.Core.Application.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);
}
}

View File

@ -0,0 +1,96 @@
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.BusinessFilter;
/// <summary>
/// https://www.cnblogs.com/NBDWDYS2214143926/p/13329231.html
/// </summary>
public class RSAEncryption
{
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);
}
}
}

View File

@ -28,6 +28,7 @@ using MassTransit;
using AlibabaCloud.SDK.Sts20150401;
using Amazon.SecurityToken;
using Amazon.SecurityToken.Model;
using Amazon;
namespace IRaCIS.Core.Application.Helper
{
@ -235,13 +236,15 @@ namespace IRaCIS.Core.Application.Helper
{
var awsConfig = ObjectStoreServiceOptions.AWS;
// 提供awsAccessKeyId和awsSecretAccessKey构造凭证
var credentials = new BasicAWSCredentials(AWSTempToken.AccessKeyId, AWSTempToken.SecretAccessKey);
var credentials = new SessionAWSCredentials( AWSTempToken.AccessKeyId, AWSTempToken.SecretAccessKey, AWSTempToken.SessionToken);
//提供awsEndPoint域名进行访问配置
var clientConfig = new AmazonS3Config
{
ServiceURL = awsConfig.EndPoint
RegionEndpoint = RegionEndpoint.USEast1,
UseHttp =true,
};
var amazonS3Client = new AmazonS3Client(credentials, clientConfig);
@ -322,12 +325,13 @@ namespace IRaCIS.Core.Application.Helper
var awsConfig = ObjectStoreServiceOptions.AWS;
// 提供awsAccessKeyId和awsSecretAccessKey构造凭证
var credentials = new BasicAWSCredentials(AWSTempToken.AccessKeyId, AWSTempToken.SecretAccessKey);
var credentials = new SessionAWSCredentials(AWSTempToken.AccessKeyId, AWSTempToken.SecretAccessKey, AWSTempToken.SessionToken);
//提供awsEndPoint域名进行访问配置
var clientConfig = new AmazonS3Config
{
ServiceURL = awsConfig.EndPoint
RegionEndpoint = RegionEndpoint.USEast1,
UseHttp = true,
};
var amazonS3Client = new AmazonS3Client(credentials, clientConfig);
@ -397,12 +401,13 @@ namespace IRaCIS.Core.Application.Helper
var awsConfig = ObjectStoreServiceOptions.AWS;
// 提供awsAccessKeyId和awsSecretAccessKey构造凭证
var credentials = new BasicAWSCredentials(AWSTempToken.AccessKeyId, AWSTempToken.SecretAccessKey);
var credentials = new SessionAWSCredentials(AWSTempToken.AccessKeyId, AWSTempToken.SecretAccessKey, AWSTempToken.SessionToken);
//提供awsEndPoint域名进行访问配置
var clientConfig = new AmazonS3Config
{
ServiceURL = awsConfig.EndPoint
RegionEndpoint = RegionEndpoint.USEast1,
UseHttp = true,
};
var amazonS3Client = new AmazonS3Client(credentials, clientConfig);
@ -490,12 +495,13 @@ namespace IRaCIS.Core.Application.Helper
// 提供awsAccessKeyId和awsSecretAccessKey构造凭证
var credentials = new BasicAWSCredentials(AWSTempToken.AccessKeyId, AWSTempToken.SecretAccessKey);
var credentials = new SessionAWSCredentials(AWSTempToken.AccessKeyId, AWSTempToken.SecretAccessKey, AWSTempToken.SessionToken);
//提供awsEndPoint域名进行访问配置
var clientConfig = new AmazonS3Config
{
ServiceURL = awsConfig.EndPoint
RegionEndpoint = RegionEndpoint.USEast1,
UseHttp = true,
};
var amazonS3Client = new AmazonS3Client(credentials, clientConfig);
@ -619,12 +625,13 @@ namespace IRaCIS.Core.Application.Helper
// 提供awsAccessKeyId和awsSecretAccessKey构造凭证
var credentials = new BasicAWSCredentials(AWSTempToken.AccessKeyId, AWSTempToken.SecretAccessKey);
var credentials = new SessionAWSCredentials(AWSTempToken.AccessKeyId, AWSTempToken.SecretAccessKey, AWSTempToken.SessionToken);
//提供awsEndPoint域名进行访问配置
var clientConfig = new AmazonS3Config
{
ServiceURL = awsConfig.EndPoint
RegionEndpoint = RegionEndpoint.USEast1,
UseHttp = true,
};
var amazonS3Client = new AmazonS3Client(credentials, clientConfig);

View File

@ -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);
}
}
}
}

View File

@ -62,6 +62,7 @@
<PackageReference Include="AWSSDK.SecurityToken" Version="3.7.400.16" />
<PackageReference Include="Aliyun.OSS.SDK.NetCore" Version="2.14.1" />
<PackageReference Include="AWSSDK.S3" Version="3.7.402.7" />
<PackageReference Include="BouncyCastle.Cryptography" Version="2.4.0" />
<PackageReference Include="DocX" Version="3.0.1" />
<PackageReference Include="FreeSpire.Doc" Version="12.2.0" />
<PackageReference Include="Hangfire.Core" Version="1.8.14" />

View File

@ -29,6 +29,25 @@
签名
</summary>
</member>
<member name="T:IRaCIS.Core.Application.BusinessFilter.EncreptApiResultFilter">
<summary>
测试加密API 返回的结果
</summary>
</member>
<member name="T:IRaCIS.Core.Application.BusinessFilter.RSAEncryption">
<summary>
https://www.cnblogs.com/NBDWDYS2214143926/p/13329231.html
</summary>
</member>
<member name="M:IRaCIS.Core.Application.BusinessFilter.RSAEncryption.Decrypt(System.String,System.String)">
<summary>
RSA解密
</summary>
<param name="privateKey">私钥</param>
<param name="decryptstring">待解密的字符串(Base64)</param>
<returns>解密后的字符串</returns>
</member>
<!-- Badly formed XML comment ignored for member "M:IRaCIS.Core.Application.BusinessFilter.RSAEncryption.Encrypt(System.String,System.String)" -->
<member name="T:IRaCIS.Core.Application.BusinessFilter.GlobalExceptionHandler">
<summary>
不生效,不知道为啥
@ -102,20 +121,6 @@
<param name="prefix"></param>
<returns></returns>
</member>
<member name="T:IRaCIS.Core.Application.Helper.RSAHelper">
<summary>
https://www.cnblogs.com/NBDWDYS2214143926/p/13329231.html
</summary>
</member>
<member name="M:IRaCIS.Core.Application.Helper.RSAHelper.Decrypt(System.String,System.String)">
<summary>
RSA解密
</summary>
<param name="privateKey">私钥</param>
<param name="decryptstring">待解密的字符串(Base64)</param>
<returns>解密后的字符串</returns>
</member>
<!-- Badly formed XML comment ignored for member "M:IRaCIS.Core.Application.Helper.RSAHelper.Encrypt(System.String,System.String)" -->
<member name="T:IRaCIS.Core.Application.Helper.WordTempleteHelper">
<summary>
利用DocX 库 处理word国际化模板
@ -902,7 +907,7 @@
TrialEmailNoticeConfigService
</summary>
</member>
<member name="M:IRaCIS.Core.Application.Service.TrialEmailNoticeConfigService.#ctor(IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TrialEmailNoticeConfig},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TrialEmailBlackUser},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.EmailNoticeConfig},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Trial},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TaskMedicalReview},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingGlobalTaskInfo},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.VisitTask},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TrialUser},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TrialEmailNoticeUser},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Subject},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadModule},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingTableQuestionAnswer},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.SubjectVisit},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingTaskQuestionAnswer},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingQuestionCriterionTrial},IRaCIS.Core.Application.Service.IEmailSendService)">
<member name="M:IRaCIS.Core.Application.Service.TrialEmailNoticeConfigService.#ctor(IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TrialEmailNoticeConfig},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TrialEmailBlackUser},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.EmailNoticeConfig},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Trial},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TaskMedicalReview},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingGlobalTaskInfo},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.VisitTask},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TrialUser},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TrialEmailNoticeUser},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Subject},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadModule},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingTableQuestionAnswer},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.SubjectVisit},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingTaskQuestionAnswer},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingQuestionCriterionTrial},Microsoft.Extensions.Options.IOptionsMonitor{IRaCIS.Core.Domain.Share.SystemEmailSendConfig},IRaCIS.Core.Application.Service.IEmailSendService)">
<summary>
TrialEmailNoticeConfigService
</summary>
@ -1371,7 +1376,7 @@
</summary>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Service.FrontAuditConfigService.GetDialogList(IRaCIS.Core.Infra.EFCore.Common.Dto.AccessToDialogueInDto)">
<member name="M:IRaCIS.Core.Application.Service.FrontAuditConfigService.GetDialogList(IRaCIS.Core.Application.ViewModel.AccessToDialogueInDto)">
<summary>
获取查询对象
</summary>
@ -1384,7 +1389,7 @@
</summary>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Service.FrontAuditConfigService.CopyFrontAuditConfigItem(IRaCIS.Core.Infra.EFCore.Common.Dto.CopyFrontAuditConfigItemDto)">
<member name="M:IRaCIS.Core.Application.Service.FrontAuditConfigService.CopyFrontAuditConfigItem(IRaCIS.Core.Application.ViewModel.CopyFrontAuditConfigItemDto)">
<summary>
复制配置项及其子项
</summary>
@ -1398,14 +1403,14 @@
<param name="data">数据集</param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Service.FrontAuditConfigService.SetInspectionEnumValue(IRaCIS.Core.Infra.EFCore.Common.Dto.SetInspectionEnumValueDto)">
<member name="M:IRaCIS.Core.Application.Service.FrontAuditConfigService.SetInspectionEnumValue(IRaCIS.Core.Application.ViewModel.SetInspectionEnumValueDto)">
<summary>
翻译稽查数据
</summary>
<param name="dto"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Service.FrontAuditConfigService.SetInspectionEnumValueDataList(IRaCIS.Core.Infra.EFCore.Common.Dto.SetInspectionEnumValueDto,System.Guid)">
<member name="M:IRaCIS.Core.Application.Service.FrontAuditConfigService.SetInspectionEnumValueDataList(IRaCIS.Core.Application.ViewModel.SetInspectionEnumValueDto,System.Guid)">
<summary>
翻译稽查数据
</summary>
@ -10812,9 +10817,6 @@
<member name="P:IRaCIS.Core.Application.ViewModel.BatchAddTrialEmailNoticeConfig.BusinessLevelEnum">
<summary> 业务层级 /// </summary>
</member>
<member name="P:IRaCIS.Core.Application.ViewModel.BatchAddTrialEmailNoticeConfig.EmailTypeEnum">
<summary> 邮件类型 /// </summary>
</member>
<member name="P:IRaCIS.Core.Application.ViewModel.BatchAddTrialEmailNoticeConfig.EmailUrgentEnum">
<summary> 邮件加急类型 /// </summary>
</member>
@ -10839,6 +10841,21 @@
<member name="T:IRaCIS.Core.Application.ViewModel.SystemAnonymizationAddOrEdit">
<summary> SystemAnonymizationAddOrEdit 列表查询参数模型</summary>
</member>
<member name="F:IRaCIS.Core.Application.ViewModel.AccessToDialogueEnum.Question">
<summary>
质疑
</summary>
</member>
<member name="F:IRaCIS.Core.Application.ViewModel.AccessToDialogueEnum.Consistency">
<summary>
一致性核查
</summary>
</member>
<member name="T:IRaCIS.Core.Application.ViewModel.CopyFrontAuditConfigItemDto">
<summary>
复制
</summary>
</member>
<member name="T:IRaCIS.Core.Application.ViewModel.SystemNoticeView">
<summary> SystemNoticeView 列表视图模型 </summary>
</member>
@ -11774,9 +11791,6 @@
<member name="P:IRaCIS.Core.Application.Contracts.EmailNoticeConfigAddOrEdit.BusinessLevelEnum">
<summary> 业务层级 /// </summary>
</member>
<member name="P:IRaCIS.Core.Application.Contracts.EmailNoticeConfigAddOrEdit.EmailTypeEnum">
<summary> 邮件类型 /// </summary>
</member>
<member name="P:IRaCIS.Core.Application.Contracts.EmailNoticeConfigAddOrEdit.EmailUrgentEnum">
<summary> 邮件加急类型 /// </summary>
</member>
@ -11847,7 +11861,7 @@
NoneDicomStudyService
</summary>
</member>
<member name="M:IRaCIS.Core.Application.Contracts.NoneDicomStudyService.#ctor(IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.NoneDicomStudy},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.NoneDicomStudyFile},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Trial},Medallion.Threading.IDistributedLockProvider,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.SubjectVisit},IRaCIS.Core.Application.Service.QCCommon)">
<member name="M:IRaCIS.Core.Application.Contracts.NoneDicomStudyService.#ctor(IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.NoneDicomStudy},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.NoneDicomStudyFile},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Trial},Medallion.Threading.IDistributedLockProvider,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.SubjectVisit},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.VisitTask},IRaCIS.Core.Application.Service.QCCommon)">
<summary>
NoneDicomStudyService
</summary>

View File

@ -27,13 +27,13 @@ namespace IRaCIS.Core.Application.Service
{
/// <summary>
/// 获取计划列表 医生带阅片类型
/// </summary>
/// <param name="trialId"></param>
/// <returns></returns>
public async Task<(List<TaskAllocationRuleDTO>,object)> GetDoctorPlanAllocationRuleList(Guid trialId)
public async Task<IResponseOutput<List<TaskAllocationRuleDTO>>> GetDoctorPlanAllocationRuleList(Guid trialId)
{
var list = await _taskAllocationRuleRepository.Where(t => t.TrialId == trialId).ProjectTo<TaskAllocationRuleDTO>(_mapper.ConfigurationProvider).ToListAsync();
@ -41,7 +41,7 @@ namespace IRaCIS.Core.Application.Service
//所有标准都是一样 后台只返回任意一个标准的就好了
var trialTaskConfig = await _readingQuestionCriterionTrialRepository.Where(t => t.TrialId == trialId && t.IsConfirm).ProjectTo<TrialTaskConfigView>(_mapper.ConfigurationProvider).FirstNotNullAsync();
return (list, trialTaskConfig);
return ResponseOutput.Ok(list, trialTaskConfig);
}
@ -103,9 +103,9 @@ namespace IRaCIS.Core.Application.Service
// return ResponseOutput.Ok();
//}
public async Task<List<SubjectCancelDoctorView>> GetSubjectCancelDoctorHistoryList(Guid subjectId,Guid trialReadingCriterionId)
public async Task<List<SubjectCancelDoctorView>> GetSubjectCancelDoctorHistoryList(Guid subjectId, Guid trialReadingCriterionId)
{
var list = await _subjectCanceDoctorRepository.Where(t => t.SubjectId == subjectId && t.TrialReadingCriterionId==trialReadingCriterionId).ProjectTo<SubjectCancelDoctorView>(_mapper.ConfigurationProvider).ToListAsync();
var list = await _subjectCanceDoctorRepository.Where(t => t.SubjectId == subjectId && t.TrialReadingCriterionId == trialReadingCriterionId).ProjectTo<SubjectCancelDoctorView>(_mapper.ConfigurationProvider).ToListAsync();
return list;
}
@ -139,7 +139,7 @@ namespace IRaCIS.Core.Application.Service
};
return await query.ToListAsync();
return await query.ToListAsync();
}
@ -150,8 +150,8 @@ namespace IRaCIS.Core.Application.Service
var query = from allocationRule in _taskAllocationRuleRepository.Where(t => t.TrialId == selectQuery.TrialId && t.IsEnable)
.WhereIf(selectQuery.ReadingCategory != null && selectQuery.TrialReadingCriterionId == null, t => t.Enroll.EnrollReadingCategoryList.Any(t => t.ReadingCategory == selectQuery.ReadingCategory))
.WhereIf(selectQuery.TrialReadingCriterionId != null && selectQuery.ReadingCategory == null, t => t.Enroll.EnrollReadingCategoryList.Any(t => t.TrialReadingCriterionId == selectQuery.TrialReadingCriterionId))
.WhereIf(selectQuery.TrialReadingCriterionId != null && selectQuery.ReadingCategory !=null,
t => t.Enroll.EnrollReadingCategoryList.Any(t => t.TrialReadingCriterionId == selectQuery.TrialReadingCriterionId && t.ReadingCategory==selectQuery.ReadingCategory))
.WhereIf(selectQuery.TrialReadingCriterionId != null && selectQuery.ReadingCategory != null,
t => t.Enroll.EnrollReadingCategoryList.Any(t => t.TrialReadingCriterionId == selectQuery.TrialReadingCriterionId && t.ReadingCategory == selectQuery.ReadingCategory))
join user in _userRepository.AsQueryable() on allocationRule.DoctorUserId equals user.Id
select new TrialDoctorUserSelectView()
{
@ -162,12 +162,12 @@ namespace IRaCIS.Core.Application.Service
UserName = user.UserName,
UserTypeEnum = user.UserTypeRole.UserTypeEnum,
ReadingCategoryList = selectQuery.TrialReadingCriterionId == null ?
allocationRule.Enroll.EnrollReadingCategoryList.Where(t=> (selectQuery.ReadingCategory == null ?true: t.ReadingCategory == selectQuery.ReadingCategory) ).Select(t => t.ReadingCategory).OrderBy(t => t).ToList() :
ReadingCategoryList = selectQuery.TrialReadingCriterionId == null ?
allocationRule.Enroll.EnrollReadingCategoryList.Where(t => (selectQuery.ReadingCategory == null ? true : t.ReadingCategory == selectQuery.ReadingCategory)).Select(t => t.ReadingCategory).OrderBy(t => t).ToList() :
allocationRule.Enroll.EnrollReadingCategoryList
.Where(t => t.TrialReadingCriterionId == selectQuery.TrialReadingCriterionId && (selectQuery.ReadingCategory == null?true : t.ReadingCategory == selectQuery.ReadingCategory) )
.Where(t => t.TrialReadingCriterionId == selectQuery.TrialReadingCriterionId && (selectQuery.ReadingCategory == null ? true : t.ReadingCategory == selectQuery.ReadingCategory))
.Select(t => t.ReadingCategory).OrderBy(t => t).ToList()
};

View File

@ -96,7 +96,7 @@ namespace IRaCIS.Core.Application.Service
.WhereIf(inQuery.EndSignTime != null, t => t.SignTime <= inQuery.EndSignTime)
.ProjectTo<AnalysisTaskView>(_mapper.ConfigurationProvider);
var defalutSortArray = new string[] { nameof(VisitTask.IsUrgent) + " desc", nameof(VisitTask.SubjectId), nameof(VisitTask.VisitTaskNum) };
var defalutSortArray = new string[] { nameof(AnalysisTaskView.IsUrgent) + " desc", nameof(AnalysisTaskView.SubjectCode), nameof(AnalysisTaskView.VisitTaskNum) };
var pageList = await visitTaskQueryable.ToPagedListAsync(inQuery, defalutSortArray);
#region 统计一致性分析临床数据数量

View File

@ -66,7 +66,7 @@ namespace IRaCIS.Core.Application.Service
.WhereIf(inQuery.EndAuditSignTime != null, t => t.AuditSignTime <= inQuery.EndAuditSignTime)
.ProjectTo<TaskMedicalReviewView>(_mapper.ConfigurationProvider);
var defalutSortArray = new string[] { nameof(TaskMedicalReviewView.AuditState), nameof(TaskMedicalReviewView.SubjectId), nameof(TaskMedicalReviewView.ArmEnum) , nameof(TaskMedicalReviewView.VisitTaskNum) };
var defalutSortArray = new string[] { nameof(TaskMedicalReviewView.AuditState), nameof(TaskMedicalReviewView.SubjectCode), nameof(TaskMedicalReviewView.ArmEnum) , nameof(TaskMedicalReviewView.VisitTaskNum) };
var pageList = await taskMedicalReviewQueryable.ToPagedListAsync(inQuery, defalutSortArray);
return pageList;
@ -102,7 +102,7 @@ namespace IRaCIS.Core.Application.Service
.WhereIf(inQuery.EndSignTime != null, t => t.SignTime < inQuery.EndSignTime)
.ProjectTo<GenerateMedicalReviewTaskView>(_mapper.ConfigurationProvider);
var defalutSortArray = new string[] { nameof(GenerateMedicalReviewTaskView.IsUrgent) + " desc", nameof(GenerateMedicalReviewTaskView.SubjectId) };
var defalutSortArray = new string[] { nameof(GenerateMedicalReviewTaskView.IsUrgent) + " desc", nameof(GenerateMedicalReviewTaskView.SubjectCode) };
var pageList = await visitTaskQueryable.ToPagedListAsync(inQuery, defalutSortArray);
@ -239,7 +239,7 @@ namespace IRaCIS.Core.Application.Service
.ProjectTo<TaskMedicalReviewView>(_mapper.ConfigurationProvider);
var defalutSortArray = new string[] { nameof(TaskMedicalReviewView.SubjectId), nameof(TaskMedicalReviewView.ArmEnum), nameof(TaskMedicalReviewView.VisitTaskNum) };
var defalutSortArray = new string[] { nameof(TaskMedicalReviewView.SubjectCode), nameof(TaskMedicalReviewView.ArmEnum), nameof(TaskMedicalReviewView.VisitTaskNum) };
var pageList = await taskMedicalReviewQueryable.ToPagedListAsync(inQuery, defalutSortArray);
return ResponseOutput.Ok(pageList, new

File diff suppressed because it is too large Load Diff

View File

@ -136,7 +136,6 @@ namespace IRaCIS.Application.Contracts
public Guid? ParentId { get; set; }
public string ParentCode { get; set; } = string.Empty;
public int? ParentChildCodeEnum { get; set; }
public string ChildGroup { get; set; } = string.Empty;

View File

@ -96,8 +96,6 @@ namespace IRaCIS.Core.Application.Contracts
/// <summary> 业务层级 /// </summary>
public int BusinessLevelEnum { get; set; }
/// <summary> 邮件类型 /// </summary>
public int EmailTypeEnum { get; set; }
/// <summary> 邮件加急类型 /// </summary>
public int EmailUrgentEnum { get; set; }

View File

@ -7,7 +7,7 @@ using System;
using IRaCIS.Core.Domain.Share;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using IRaCIS.Core.Infra.EFCore.Common.Dto;
using IRaCIS.Core.Infra.EFCore.Common;
namespace IRaCIS.Core.Application.ViewModel
{

View File

@ -407,7 +407,6 @@ namespace IRaCIS.Application.Services
ChildGroup = x.Dictionary.ChildGroup,
Code = x.Dictionary.Code,
DataTypeEnum = x.Dictionary.DataTypeEnum,
ParentChildCodeEnum = x.Dictionary.Parent.ChildCodeEnum,
ShowOrder = x.Dictionary.ShowOrder,
ParentCode = x.ParentCode,
CrterionDictionaryGroup = x.CrterionDictionaryGroup,
@ -427,7 +426,6 @@ namespace IRaCIS.Application.Services
ChildGroup = x.Dictionary.ChildGroup,
Code = x.Dictionary.Code,
DataTypeEnum = x.Dictionary.DataTypeEnum,
ParentChildCodeEnum = x.Dictionary.Parent.ChildCodeEnum,
ShowOrder = x.Dictionary.ShowOrder,
ParentCode = x.ParentCode,
CrterionDictionaryGroup = x.CrterionDictionaryGroup,
@ -521,7 +519,6 @@ namespace IRaCIS.Application.Services
Code = x.Dictionary.Code,
Description = x.Dictionary.Description,
DataTypeEnum = x.Dictionary.DataTypeEnum,
ParentChildCodeEnum = x.Dictionary.Parent.ChildCodeEnum,
ShowOrder = x.Dictionary.ShowOrder,
ParentCode = x.ParentCode,
Id = x.DictionaryId,
@ -565,7 +562,6 @@ namespace IRaCIS.Application.Services
Code = x.Dictionary.Code,
Description = x.Dictionary.Description,
DataTypeEnum = x.Dictionary.DataTypeEnum,
ParentChildCodeEnum = x.Dictionary.Parent.ChildCodeEnum,
ShowOrder = x.Dictionary.ShowOrder,
ParentCode = x.ParentCode,
Id = x.DictionaryId,

View File

@ -52,12 +52,12 @@ namespace IRaCIS.Core.Application.Service
CreateMap<AddBasicDicChild, Dictionary>();
CreateMap<Dictionary, BasicDicSelectCopy>()
.ForMember(o => o.ParentChildCodeEnum, t => t.MapFrom(u => u.Parent.ChildCodeEnum))
//.ForMember(o => o.ParentChildCodeEnum, t => t.MapFrom(u => u.Parent.ChildCodeEnum))
.ForMember(o => o.Value, t => t.MapFrom(u => isEn_Us ? u.Value : u.ValueCN))
.ForMember(o => o.ParentCode, t => t.MapFrom(u => u.Parent.Code));
CreateMap<Dictionary, BasicDicSelect>()
.ForMember(o => o.ParentChildCodeEnum, t => t.MapFrom(u => u.Parent.ChildCodeEnum))
//.ForMember(o => o.ParentChildCodeEnum, t => t.MapFrom(u => u.Parent.ChildCodeEnum))
.ForMember(o => o.ParentCode, t => t.MapFrom(u => u.Parent.Code));
var token = "";

View File

@ -617,7 +617,6 @@ namespace IRaCIS.Application.Contracts
public List<Guid> SubspecialityIds { get; set; } = new List<Guid>();
public Guid Id { get; set; }
public string OtherSkills { get; set; } = string.Empty;
public string ReadingTypeOther { get; set; } = string.Empty;
public string ReadingTypeOtherCN { get; set; } = string.Empty;

View File

@ -105,7 +105,7 @@ namespace IRaCIS.Core.Application.Contracts
public class SystemDocumentQuery : PageInput
{
public bool? IsDeleted { get; set; }
public Guid? SystemDocumentId { get; set; }
public Guid? FileTypeId { get; set; }

View File

@ -160,8 +160,6 @@ namespace IRaCIS.Core.Application.ViewModel
/// <summary> 业务层级 /// </summary>
public int BusinessLevelEnum { get; set; }
/// <summary> 邮件类型 /// </summary>
public int EmailTypeEnum { get; set; }
/// <summary> 邮件加急类型 /// </summary>
public int EmailUrgentEnum { get; set; }

View File

@ -16,10 +16,10 @@ namespace IRaCIS.Core.Application.Contracts
Task<IResponseOutput> UserAbandonDoc(Guid documentId, bool isSystemDoc);
Task<IResponseOutput> AddOrUpdateTrialDocument(AddOrEditTrialDocument addOrEditTrialDocument);
Task<IResponseOutput> DeleteTrialDocument(Guid trialDocumentId, Guid trialId);
Task<(PageOutput<UnionDocumentWithConfirmInfoView>, object)> GetDocumentConfirmList(DocumentTrialUnionQuery querySystemDocument);
//Task<IResponseOutput<PageOutput<UnionDocumentWithConfirmInfoView>>> GetDocumentConfirmList(DocumentTrialUnionQuery querySystemDocument);
Task<PageOutput<TrialDocumentView>> GetTrialDocumentList(TrialDocumentQuery queryTrialDocument);
Task<IResponseOutput<PageOutput<UnionDocumentWithConfirmInfoView>> > GetUserDocumentList(TrialUserDocUnionQuery querySystemDocument);
Task<IResponseOutput<PageOutput<UnionDocumentWithConfirmInfoView>>> GetUserDocumentList(TrialUserDocUnionQuery querySystemDocument);
Task<IResponseOutput> SetFirstViewDocumentTime(Guid documentId, bool isSystemDoc);
Task<IResponseOutput> UserConfirm(UserConfirmCommand userConfirmCommand);
Task<List<TrialUserDto>> GetTrialUserSelect(Guid trialId);

View File

@ -36,7 +36,8 @@ namespace IRaCIS.Core.Application.Services
var systemDocumentQueryable = _systemDocumentRepository.AsQueryable(true)
.WhereIf(!string.IsNullOrEmpty(inQuery.Name), t => t.Name.Contains(inQuery.Name))
.WhereIf(inQuery.FileTypeId != null, t => t.FileTypeId == inQuery.FileTypeId)
.ProjectTo<SystemDocumentView>(_mapper.ConfigurationProvider, new { token = _userInfo.UserToken, userId = _userInfo.Id });
.WhereIf(inQuery.IsDeleted != null, t => t.IsDeleted == inQuery.IsDeleted)
.ProjectTo<SystemDocumentView>(_mapper.ConfigurationProvider, new { isEn_Us = _userInfo.IsEn_Us, userId = _userInfo.Id });
return await systemDocumentQueryable.ToPagedListAsync(inQuery);
}

View File

@ -224,8 +224,7 @@ namespace IRaCIS.Core.Application.Services
var trialInfo = await ( _trialRepository.Where(t => t.Id == inQuery.TrialId, ignoreQueryFilters: true).Select(t => new { t.TrialFinishedTime, t.TrialStatusStr }).FirstNotNullAsync());
//系统文档查询
var systemDocumentQueryable = from needConfirmedUserType in _systemDocNeedConfirmedUserTypeRepository.Where(t => t.NeedConfirmUserTypeId == _userInfo.UserTypeId)
//.Where(u => u.UserTypeRole.UserList.SelectMany(cc => cc.UserTrials.Where(t => t.TrialId == querySystemDocument.TrialId)).Any(e => e.Trial.TrialFinishedTime < u.SystemDocument.CreateTime))
var systemDocumentQueryable = from needConfirmedUserType in _systemDocNeedConfirmedUserTypeRepository.Where(t => t.NeedConfirmUserTypeId == _userInfo.UserTypeId,ignoreQueryFilters:true)
.WhereIf(trialInfo.TrialFinishedTime != null, u => u.SystemDocument.CreateTime < trialInfo.TrialFinishedTime)
.WhereIf(!_userInfo.IsAdmin, t => t.SystemDocument.IsDeleted == false || (t.SystemDocument.IsDeleted == true && t.SystemDocument.SystemDocConfirmedUserList.Any(t => t.ConfirmUserId == _userInfo.Id)))
@ -356,7 +355,7 @@ namespace IRaCIS.Core.Application.Services
/// <param name="inQuery"></param>
/// <returns></returns>
[HttpPost]
public async Task<(PageOutput<UnionDocumentWithConfirmInfoView>, object)> GetDocumentConfirmList(DocumentTrialUnionQuery inQuery)
public async Task<IResponseOutput< PageOutput<UnionDocumentWithConfirmInfoView>>> GetDocumentConfirmList(DocumentTrialUnionQuery inQuery)
{
@ -393,7 +392,7 @@ namespace IRaCIS.Core.Application.Services
#endregion
var trialInfo = (await _trialRepository.Where(t => t.Id == inQuery.TrialId).Select(t => new { t.TrialFinishedTime, t.TrialStatusStr }).FirstNotNullAsync());
var trialInfo = (await _trialRepository.Where(t => t.Id == inQuery.TrialId,ignoreQueryFilters:true).Select(t => new { t.TrialFinishedTime, t.TrialStatusStr }).FirstNotNullAsync());
var trialDocQuery = from trialDocumentNeedConfirmedUserType in _trialDocNeedConfirmedUserTypeRepository.Where(t => t.TrialDocument.TrialId == inQuery.TrialId)
join trialUser in _trialUserRepository.Where(t => t.TrialId == inQuery.TrialId)
@ -465,7 +464,7 @@ namespace IRaCIS.Core.Application.Services
FullFilePath = needConfirmEdUserType.SystemDocument.Path
};
var unionQuery = trialDocQuery.Union(systemDocQuery)
var unionQuery = trialDocQuery.Union(systemDocQuery).IgnoreQueryFilters().Where(t=>!(t.IsDeleted == true && t.ConfirmUserId == null))
.WhereIf(!string.IsNullOrEmpty(inQuery.Name), t => t.Name.Contains(inQuery.Name))
.WhereIf(inQuery.FileTypeId != null, t => t.FileTypeId == inQuery.FileTypeId)
.WhereIf(inQuery.IsConfirmed == true, t => t.ConfirmTime != null)
@ -486,7 +485,7 @@ namespace IRaCIS.Core.Application.Services
.CountAsync();
return (result, new { NeedSignCount = needSignTrialDocCount + needSignSystemDocCount, NeedSignTrialDocCount = needSignTrialDocCount, NeedSignSystemDocCount = needSignSystemDocCount, TrialStatusStr = trialInfo.TrialStatusStr });
return ResponseOutput.Ok (result, new { NeedSignCount = needSignTrialDocCount + needSignSystemDocCount, NeedSignTrialDocCount = needSignTrialDocCount, NeedSignSystemDocCount = needSignSystemDocCount, TrialStatusStr = trialInfo.TrialStatusStr });
}

View File

@ -27,6 +27,7 @@ using System.Runtime.InteropServices;
using SharpCompress.Common;
using DocumentFormat.OpenXml.Bibliography;
using System.Linq.Dynamic.Core;
using Microsoft.Extensions.Options;
namespace IRaCIS.Core.Application.Service
{
@ -50,6 +51,7 @@ namespace IRaCIS.Core.Application.Service
IRepository<SubjectVisit> _subjectVisitRepository,
IRepository<ReadingTaskQuestionAnswer> _readingTaskQuestionAnswerRepository,
IRepository<ReadingQuestionCriterionTrial> _readingQuestionCriterionTrialRepository,
IOptionsMonitor<SystemEmailSendConfig> _systemEmailSendConfig,
IEmailSendService _emailSendService) : BaseService, ITrialEmailNoticeConfigService
{

View File

@ -4,6 +4,8 @@ using IRaCIS.Application.Contracts;
using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Domain.Share;
using System.Globalization;
namespace IRaCIS.Core.Application.Service
{
@ -13,10 +15,10 @@ namespace IRaCIS.Core.Application.Service
{
var userId = Guid.Empty;
var token = string.Empty;
var isEn_Us = false;
CreateMap<SystemDocument, SystemDocumentView>()
.ForMember(d => d.FileType, u => u.MapFrom(s => s.FileType.Value))
.ForMember(d => d.FileType, u => u.MapFrom(s => isEn_Us ? s.FileType.Value: s.FileType.ValueCN))
.ForMember(d => d.FullFilePath, u => u.MapFrom(s => s.Path));
CreateMap<TrialDocument, TrialDocumentView>()

View File

@ -382,7 +382,7 @@ namespace IRaCIS.Core.Application.Contracts
public string HtmlPath { get; set; } = string.Empty;
public long FileSize { get; set; }
public long FileSize { get; set; }
}
public class CRCUploadTaskQuery
@ -578,7 +578,7 @@ namespace IRaCIS.Core.Application.Contracts
}
public class TrialIamgeDownQuery:PageInput
public class TrialIamgeDownQuery : PageInput
{
[NotDefault]
public Guid TrialId { get; set; }
@ -595,6 +595,8 @@ namespace IRaCIS.Core.Application.Contracts
public DateTime? DownloadEndTime { get; set; }
public string? IP { get; set; }
public string? Name { get; set; }
}
public class SubjectVisitTaskInfo

View File

@ -65,8 +65,10 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
/// <returns></returns>
public async Task<IResponseOutput> SubejctRandomReadingTaskNameDeal(Guid subjectId, Guid trialReadingCriterionId)
{
//subject 随机阅片 才处理任务编号
if (_visitTaskRepository.Any(t => t.SubjectId == subjectId && t.TrialReadingCriterionId == trialReadingCriterionId && t.TrialReadingCriterion.IsReadingTaskViewInOrder == ReadingOrder.SubjectRandom))
//subject 随机阅片 或者无序 有上传 才处理任务编号
if (_visitTaskRepository.Any(t => t.SubjectId == subjectId && t.TrialReadingCriterionId == trialReadingCriterionId &&
(t.TrialReadingCriterion.IsReadingTaskViewInOrder == ReadingOrder.SubjectRandom ||
(t.TrialReadingCriterion.IsReadingTaskViewInOrder == ReadingOrder.Random && t.TrialReadingCriterion.ImageUploadEnum != ReadingImageUpload.None))))
{
//找到 非一致性分析,未签名,状态正常的 并且任务名称是TimePoint的 任务
var needDealTaskList = await _visitTaskRepository.Where(t => t.SubjectId == subjectId && t.TrialReadingCriterionId == trialReadingCriterionId && t.IsAnalysisCreate == false && t.DoctorUserId == _userInfo.Id
@ -135,7 +137,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
CriterionModalitys = u.TrialReadingCriterion.CriterionModalitys,
SubjectCode = u.IsSelfAnalysis == true ? u.BlindSubjectCode : u.Subject.Code,
SubjectCode = u.IsAnalysisCreate == true ? u.BlindSubjectCode : u.Subject.Code,
TaskBlindName = u.TaskBlindName,
TaskName = u.TaskName,
@ -183,6 +185,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
var list = await query.Where(t => t.SubjectCode == inQuery.SubjectCode).ToListAsync();
return ResponseOutput.Ok(list);
}
@ -753,12 +756,18 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
[HttpPost]
public async Task<List<SubjectCRCImageUploadedStudyDto>> GetSubjectImageDownloadSelectList(IRReadingDownloadQuery inQuery)
{
//要根据标准阅片顺序,确定是否查询单个任务的,还是查询所有的
var criterionInfo= await _readingQuestionCriterionTrialRepository.Where(t => t.Id == inQuery.TrialReadingCriterionId)
.Select(t => new { t.IsReadingTaskViewInOrder }).FirstNotNullAsync();
var doctorUserId = _userInfo.Id;
var isAnalysisCreate = false;
//医学审核查看下载按钮,这个时候需要知道医生
if (inQuery.VisitTaskId != null && inQuery.VisitTaskId != Guid.Empty)
if (inQuery.VisitTaskId != null )
{
var info = await _visitTaskRepository.Where(t => t.Id == inQuery.VisitTaskId).Select(t => new { t.DoctorUserId, t.IsAnalysisCreate }).FirstNotNullAsync();
@ -768,6 +777,8 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
var query = _visitTaskRepository.Where(t => t.SubjectId == inQuery.SubjectId && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId
&& t.SourceSubjectVisitId != null && t.DoctorUserId == doctorUserId && t.TaskState == TaskState.Effect)
//满足 有序或者随机只看到当前任务的dicom 非dicom检查
.WhereIf(criterionInfo.IsReadingTaskViewInOrder!=ReadingOrder.SubjectRandom && inQuery.VisitTaskId != null,t=>t.Id==inQuery.VisitTaskId)
.ProjectTo<SubjectCRCImageUploadedDto>(_mapper.ConfigurationProvider);
//这里过滤是否是一致性分析的
@ -837,7 +848,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
public async Task<IResponseOutput> GetIRReadingDownloadStudyInfo(IRDownloadQuery inQuery)
{
var info = await _readingQuestionCriterionTrialRepository.Where(t => t.Id == inQuery.TrialReadingCriterionId)
.Select(t => new { t.IsImageFilter, t.CriterionModalitys, t.TrialId }).FirstNotNullAsync();
.Select(t => new { t.IsImageFilter, t.CriterionModalitys, t.TrialId,t.IsReadingTaskViewInOrder }).FirstNotNullAsync();
var isQueryDicom = inQuery.DicomStudyIdList.Count > 0;
var isQueryNoneDicom = inQuery.NoneDicomStudyIdList.Count > 0;
@ -908,7 +919,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
Id = NewId.NextSequentialGuid(),
TrialId = info.TrialId,
SubjectCode = inQuery.SubjectCode,
IP=_userInfo.IP,
IP = _userInfo.IP,
DownloadStartTime = DateTime.Now,
IsSuccess = false,
ImageType = imageType,
@ -920,8 +931,9 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
) ?? 0
};
await _trialImageDownloadRepository.AddAsync(preDownloadInfo,true);
return ResponseOutput.Ok(result, preDownloadInfo.Id);
await _trialImageDownloadRepository.AddAsync(preDownloadInfo, true);
return ResponseOutput.Ok(result, new { PreDownloadId= preDownloadInfo.Id,info.IsReadingTaskViewInOrder } );
}
/// <summary>
@ -996,6 +1008,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
var query = _trialImageDownloadRepository.Where(t => t.TrialId == inQuery.TrialId)
.WhereIf(inQuery.SubjectCode.IsNotNullOrEmpty(), t => t.SubjectCode.Contains(inQuery.SubjectCode))
.WhereIf(inQuery.IP.IsNotNullOrEmpty(), t => t.IP.Contains(inQuery.IP))
.WhereIf(inQuery.Name.IsNotNullOrEmpty(), t => t.CreateUser.UserName.Contains(inQuery.Name) || t.CreateUser.FullName.Contains(inQuery.Name))
.WhereIf(inQuery.ImageType != null, t => t.ImageType == inQuery.ImageType)
.WhereIf(inQuery.UserType != null, t => t.CreateUser.UserTypeEnum == inQuery.UserType)
.WhereIf(inQuery.IsSuccess != null, t => t.IsSuccess == inQuery.IsSuccess)

View File

@ -9,6 +9,7 @@ using System.ComponentModel.DataAnnotations;
using IRaCIS.Core.Application.Service;
using IRaCIS.Core.Domain.Share;
using Medallion.Threading;
using IRaCIS.Core.Application.Service.Reading.Dto;
namespace IRaCIS.Core.Application.Contracts
{
@ -22,6 +23,7 @@ namespace IRaCIS.Core.Application.Contracts
IRepository<Trial> _trialRepository,
IDistributedLockProvider _distributedLockProvider,
IRepository<SubjectVisit> _subjectVisitRepository,
IRepository<VisitTask> _visitTaskRepository,
QCCommon _qCCommon) : BaseService, INoneDicomStudyService
{
@ -40,12 +42,16 @@ namespace IRaCIS.Core.Application.Contracts
{
noneDicomStudyQueryable = _noneDicomStudyRepository.Where(t => t.SubjectVisitId == subjectVisitId).WhereIf(nonedicomStudyId != null, t => t.Id == nonedicomStudyId)
.ProjectTo<NoneDicomStudyView>(_mapper.ConfigurationProvider, new { isFilterZip = isFilterZip});
.ProjectTo<NoneDicomStudyView>(_mapper.ConfigurationProvider, new { isFilterZip = isFilterZip });
}
else
{
var taskinfo = await _visitTaskRepository.Where(x => x.Id == visitTaskId).Select(t => new { t.BlindSubjectCode, t.TrialReadingCriterionId, t.TrialReadingCriterion.IsImageFilter, t.TrialReadingCriterion.CriterionModalitys }).FirstNotNullAsync();
noneDicomStudyQueryable = _noneDicomStudyRepository.Where(t => t.TaskNoneDicomFileList.Any(t => t.VisitTaskId == visitTaskId))
.WhereIf(nonedicomStudyId != null, t => t.Id == nonedicomStudyId)
.Where(t => taskinfo.IsImageFilter ? ("|" + taskinfo.CriterionModalitys + "|").Contains("|" + t.Modality + "|") : true)
.WhereIf(nonedicomStudyId != null, t => t.Id == nonedicomStudyId)
.ProjectTo<TaskDicomStudyView>(_mapper.ConfigurationProvider, new { isFilterZip = isFilterZip, visiTaskId = visitTaskId });
}

View File

@ -130,7 +130,7 @@ namespace IRaCIS.Core.Application.Service
.ForMember(d => d.VisitTaskId, u => u.MapFrom(s => s.Id))
.ForMember(d => d.IsImageFilter, u => u.MapFrom(s => s.TrialReadingCriterion.IsImageFilter))
.ForMember(d => d.CriterionModalitys, u => u.MapFrom(s => s.TrialReadingCriterion.CriterionModalitys))
.ForMember(d => d.SubjectCode, u => u.MapFrom(u => u.IsSelfAnalysis == true ? u.BlindSubjectCode : u.Subject.Code));
.ForMember(d => d.SubjectCode, u => u.MapFrom(u => u.IsAnalysisCreate == true ? u.BlindSubjectCode : u.Subject.Code));
CreateMap<DicomStudy, DicomStudyBasicInfo>();
CreateMap<NoneDicomStudy, NoneDicomStudyBasicInfo>();
@ -138,7 +138,7 @@ namespace IRaCIS.Core.Application.Service
.ForMember(d => d.VisitTaskId, u => u.MapFrom(s => s.Id))
.ForMember(d => d.IsImageFilter, u => u.MapFrom(s => s.TrialReadingCriterion.IsImageFilter))
.ForMember(d => d.CriterionModalitys, u => u.MapFrom(s => s.TrialReadingCriterion.CriterionModalitys))
.ForMember(d => d.SubjectCode, u => u.MapFrom(u => u.IsSelfAnalysis == true ? u.BlindSubjectCode : u.Subject.Code))
.ForMember(d => d.SubjectCode, u => u.MapFrom(u => u.IsAnalysisCreate == true ? u.BlindSubjectCode : u.Subject.Code))
.ForMember(d => d.DicomStudyList, u => u.MapFrom(s => s.SourceSubjectVisit.StudyList))
.ForMember(d => d.NoneDicomStudyList, u => u.MapFrom(s => s.SourceSubjectVisit.NoneDicomStudyList))
;

View File

@ -0,0 +1,73 @@
using IRaCIS.Core.Domain.Share;
using System.ComponentModel.DataAnnotations;
namespace IRaCIS.Core.Application.ViewModel;
public class DateDto
{
public string Code { get; set; }
public string DateType { get; set; }
public string Identification { get; set; }
}
public class SetInspectionEnumValueDto
{
[NotDefault]
public Guid TrialId { get; set; }
[NotDefault]
public List<Guid> AuditDataIds { get; set; }
}
public class AccessToDialogueInDto
{
public Guid Id { get; set; }
public AccessToDialogueEnum Type { get; set; }
public DateTime Createtime { get; set; }
}
public class AccessToDialogueOutDto
{
public string CreateUserName { get; set; }
public string TalkContent { get; set; }
public DateTime CreateTime { get; set; }
public bool IsTitle { get; set; }
}
public enum AccessToDialogueEnum
{
/// <summary>
/// ÖÊÒÉ
/// </summary>
Question = 0,
/// <summary>
/// Ò»ÖÂÐԺ˲é
/// </summary>
Consistency = 1,
}
/// <summary>
/// ¸´ÖÆ
/// </summary>
public class CopyFrontAuditConfigItemDto
{
public Guid ParentId { get; set; }
public Guid ChildId { get; set; }
}

View File

@ -8,7 +8,6 @@ using Microsoft.AspNetCore.Mvc;
using IRaCIS.Core.Application.Interfaces;
using IRaCIS.Core.Application.ViewModel;
using MassTransit;
using IRaCIS.Core.Infra.EFCore.Common.Dto;
using Microsoft.Data.SqlClient;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
@ -19,6 +18,7 @@ using IRaCIS.Application.Contracts;
using IRaCIS.Core.Infrastructure.Extention;
using Microsoft.EntityFrameworkCore;
using Npgsql;
using IRaCIS.Core.Infra.EFCore.Common;
namespace IRaCIS.Core.Application.Service
{

View File

@ -135,8 +135,8 @@ namespace IRaCIS.Core.Application.Service.Inspection
//UserLastName = leftuser.LastName,
ExperimentName = leftrial.ExperimentName,
SubjectCode = leftvisttask.BlindSubjectCode.IsNullOrEmpty()? leftsubject.Code: leftvisttask.BlindSubjectCode,
//SubjectCode = leftvisttask.BlindSubjectCode.IsNullOrEmpty()? leftsubject.Code: leftvisttask.BlindSubjectCode,
SubjectCode = leftvisttask.IsAnalysisCreate? leftvisttask.BlindSubjectCode: leftsubject.Code ,
SiteCode = lefttrialSite.TrialSiteCode,
ResearchProgramNo = leftrial.ResearchProgramNo,

View File

@ -32,6 +32,8 @@ namespace IRaCIS.Application.Contracts
public bool IsMFA { get; set; } = false;
public SystemEmailSendConfigView CompanyInfo { get; set; }
}
public class UserBasicInfo

View File

@ -66,6 +66,8 @@ namespace IRaCIS.Core.Application.Service
var result = await _userFeedBackRepository.WhereIf(inQuery.Id == null, t => t.VisitTaskId == inQuery.VisitTaskId)
.WhereIf(inQuery.VisitTaskId == null, t => t.Id == inQuery.Id).ProjectTo<UserFeedBackView>(_mapper.ConfigurationProvider).FirstOrDefaultAsync();
return ResponseOutput.Ok(result);
}

View File

@ -135,7 +135,9 @@ namespace IRaCIS.Core.Application.Service
.ForMember(d => d.SubjectVisitName, c => c.MapFrom(t => t.SubjectVisit.VisitName))
.ForMember(d => d.FeedBackUserName, c => c.MapFrom(t => t.CreateUser.UserName))
.ForMember(d => d.FeedBackFullName, c => c.MapFrom(t => t.CreateUser.FullName))
.ForMember(d => d.UserTypeEnum, c => c.MapFrom(t => t.CreateUser.UserTypeEnum));
.ForMember(d => d.UserTypeEnum, c => c.MapFrom(t => t.CreateUser.UserTypeEnum))
.ForMember(d => d.ScreenshotList, c => c.MapFrom(t => t.FeedBackScreenshotList))
;
CreateMap<UserFeedBackAddOrEdit, UserFeedBack>().ReverseMap();
}

View File

@ -62,7 +62,7 @@ namespace IRaCIS.Core.Application.Image.QA
.ProjectTo<QCCRCVisitViewModel>(_mapper.ConfigurationProvider);
var defalutSortArray = new string[] { nameof(SubjectVisit.IsUrgent) + " desc", nameof(SubjectVisit.SubjectId), nameof(SubjectVisit.VisitNum) };
var defalutSortArray = new string[] { nameof(QCCRCVisitViewModel.IsUrgent) + " desc", nameof(QCCRCVisitViewModel.SubjectCode), nameof(QCCRCVisitViewModel.VisitNum) };
var pageList = await query.ToPagedListAsync(inQuery, defalutSortArray);
var config = await _trialRepository.Where(t => t.Id == inQuery.TrialId).ProjectTo<TrialSubjectAndSVConfig>(_mapper.ConfigurationProvider).FirstOrDefaultAsync().IfNullThrowException();
@ -157,7 +157,7 @@ namespace IRaCIS.Core.Application.Image.QA
.WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA, t => t.SubjectVisit.TrialSite.CRCUserList.Any(t => t.UserId == _userInfo.Id))
.ProjectTo<QCCRCChallengeViewModel>(_mapper.ConfigurationProvider);
var pageList = await query.ToPagedListAsync(inQuery, new string[] { "IsUrgent desc", "CreateTime asc" });
var pageList = await query.ToPagedListAsync(inQuery, new string[] { nameof(QCCRCChallengeViewModel.IsUrgent)+ " desc", nameof(QCCRCChallengeViewModel.CreateTime)});
var config = await _trialRepository.Where(t => t.Id == inQuery.TrialId).ProjectTo<TrialSubjectAndSVConfig>(_mapper.ConfigurationProvider).FirstOrDefaultAsync().IfNullThrowException();
return ResponseOutput.Ok (pageList, config);
@ -195,7 +195,7 @@ namespace IRaCIS.Core.Application.Image.QA
.WhereIf(inQuery.IsOverTime != null && inQuery.IsOverTime == false, t => t.IsClosed ? t.ClosedTime < t.DeadlineTime : DateTime.Now < t.DeadlineTime)
.ProjectTo<QCCRCChallengeViewModel>(_mapper.ConfigurationProvider);
var pageList = await query.ToPagedListAsync(inQuery, new string[] { "IsUrgent desc", "IsClosed asc" });
var pageList = await query.ToPagedListAsync(inQuery, new string[] { nameof(QCCRCChallengeViewModel.IsUrgent) + " desc", nameof(QCCRCChallengeViewModel.CreateTime) });
var config = await _trialRepository.Where(t => t.Id == inQuery.TrialId).ProjectTo<TrialSubjectAndSVConfig>(_mapper.ConfigurationProvider).FirstOrDefaultAsync().IfNullThrowException();
return (pageList, config);
@ -233,9 +233,9 @@ namespace IRaCIS.Core.Application.Image.QA
var svExpression = QCCommon.GetSubjectVisitFilter(inQuery.VisitPlanArray);
var query = _subjectVisitRepository.Where(x => x.TrialId == inQuery.TrialId)
.WhereIf(inQuery.VisitId != null, t => t.Id == inQuery.VisitId)
.WhereIf(inQuery.CurrentActionUserId != null, t => t.CurrentActionUserId == inQuery.CurrentActionUserId)
.WhereIf(inQuery.ChallengeState != null, t => t.ChallengeState == inQuery.ChallengeState)
.WhereIf(inQuery.VisitId != null, t => t.Id == inQuery.VisitId)
.WhereIf(inQuery.CurrentActionUserId != null, t => t.CurrentActionUserId == inQuery.CurrentActionUserId)
.WhereIf(inQuery.ChallengeState != null, t => t.ChallengeState == inQuery.ChallengeState)
.WhereIf(inQuery.TrialSiteId != null, t => t.TrialSiteId == inQuery.TrialSiteId)
.WhereIf(inQuery.SubjectId != null, t => t.Subject.Id == inQuery.SubjectId)
.WhereIf(!string.IsNullOrEmpty(inQuery.SubjectInfo), t => /*t.Subject.FirstName.Contains(subjectInfo) || t.Subject.LastName.Contains(subjectInfo) ||*/ t.Subject.Code.Contains(inQuery.SubjectInfo))
@ -260,7 +260,7 @@ namespace IRaCIS.Core.Application.Image.QA
//.WhereIf(visitSearchDTO.ChallengeState != null, t => t.ChallengeState == visitSearchDTO.ChallengeState)
.ProjectTo<QCVisitViewModel>(_mapper.ConfigurationProvider);
var defalutSortArray = new string[] { nameof(QCVisitViewModel.IsUrgent) + " desc", nameof(QCVisitViewModel.SubjectId), nameof(QCVisitViewModel.VisitNum) };
var defalutSortArray = new string[] { nameof(QCVisitViewModel.IsUrgent) + " desc", nameof(QCVisitViewModel.SubjectCode), nameof(QCVisitViewModel.VisitNum) };
//var defalutSortArray = new string[] { nameof(SubjectVisit.IsUrgent) + " desc", nameof(QCVisitViewModel.AuditState) +" asc" };
var pageList = await query.ToPagedListAsync(inQuery, defalutSortArray);
@ -638,8 +638,9 @@ namespace IRaCIS.Core.Application.Image.QA
public async Task<List<SubjectVisitSelectItem>> GetSubjectVisitSelectList(Guid subjectId)
{
var maxNum = await _visitTaskRepository.Where(t => t.SubjectId == subjectId && t.TaskState == TaskState.Effect && t.SignTime != null && t.TrialReadingCriterion.IsReadingTaskViewInOrder == ReadingOrder.InOrder).MaxAsync(x => (decimal?)x.VisitTaskNum)??0;
//var maxNum = await _visitTaskRepository.Where(t => t.SubjectId == subjectId && t.TaskState == TaskState.Effect && t.SignTime != null && t.TrialReadingCriterion.IsReadingTaskViewInOrder == ReadingOrder.InOrder).MaxAsync(x => (decimal?)x.VisitTaskNum)??0;
var maxNum=await _subjectVisitRepository.Where(t=>t.SubjectId == subjectId && t.SubmitState==SubmitStateEnum.Submitted).MaxAsync(x => (decimal?)x.VisitNum) ?? 0;
return await _subjectVisitRepository.Where(t => t.SubjectId == subjectId&&t.VisitNum>= maxNum).OrderBy(T => T.VisitNum).ProjectTo<SubjectVisitSelectItem>(_mapper.ConfigurationProvider).ToListAsync();
}

View File

@ -486,11 +486,14 @@ namespace IRaCIS.Core.Application.Service
// 临床数据上传 路径拼接返回
CreateMap<PreviousHistory, PreviousHistoryView>()
.ForMember(d => d.FullFilePath, u => u.MapFrom(s => s.Path + "?access_token=" + token));
.ForMember(d => d.CreateUser, u => u.MapFrom(s => s.CreateUser.FullName))
.ForMember(d => d.FullFilePath, u => u.MapFrom(s => s.Path ));
CreateMap<PreviousOther, PreviousOtherView>()
.ForMember(d => d.FullFilePath, u => u.MapFrom(s => s.Path + "?access_token=" + token));
.ForMember(d => d.CreateUser, u => u.MapFrom(s => s.CreateUser.FullName))
.ForMember(d => d.FullFilePath, u => u.MapFrom(s => s.Path ));
CreateMap<PreviousSurgery, PreviousSurgeryView>()
.ForMember(d => d.FullFilePath, u => u.MapFrom(s => s.Path + "?access_token=" + token));
.ForMember(d => d.CreateUser, u => u.MapFrom(s => s.CreateUser.FullName))
.ForMember(d => d.FullFilePath, u => u.MapFrom(s => s.Path ));

View File

@ -361,7 +361,7 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
public Guid? ClinicalFormId { get; set; }
public string PicturePath { get; set; } = string.Empty;
public string? PicturePath { get; set; }
public Guid SubjectId { get; set; }

View File

@ -306,8 +306,8 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
public decimal FristAddTaskNum { get; set; }
public string OtherMeasureData { get; set; } = string.Empty;
public string MeasureData { get; set; } = string.Empty;
public string? OtherMeasureData { get; set; }
public string? MeasureData { get; set; }
public List<TableQuestionInfo> TableQuestionList { get; set; } = new List<TableQuestionInfo>();
}

View File

@ -91,7 +91,7 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
public bool IsCanEditPosition { get; set; } = false;
public string BlindName { get; set; } = string.Empty;
public string BlindName { get; set; }
public Guid? RowId { get; set; }
@ -114,12 +114,12 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
/// <summary>
/// 类型值
/// </summary>
public string TypeValue { get; set; }
public string? TypeValue { get; set; }
/// <summary>
/// 序号标记
/// </summary>
public string OrderMark { get; set; } = string.Empty;
public string? OrderMark { get; set; }
/// <summary>
/// 数值类型
@ -129,7 +129,7 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
/// <summary>
/// 自定义单位
/// </summary>
public string CustomUnit { get; set; } = string.Empty;
public string? CustomUnit { get; set; }
/// <summary>
/// 单位
@ -140,7 +140,7 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
public ReportLayType ReportLayType { get; set; } = ReportLayType.Group;
public string ReportMark { get; set; } = string.Empty;
public string? ReportMark { get; set; }
/// <summary>
/// 高亮问题的答案
@ -310,7 +310,7 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
{
public Guid RowId { get; set; }
public string OrderMarkName { get; set; }
public string? OrderMarkName { get; set; }
public Guid? OrganInfoId { get; set; }
@ -500,7 +500,7 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
/// <summary>
/// MeasureData
/// </summary>
public string MeasureData { get; set; }
public string? MeasureData { get; set; }
/// <summary>
/// CreateTime
@ -613,7 +613,7 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
{
public Guid Id { get; set; }
public string Answer { get; set; }
public string Answer { get; set; } = string.Empty;
}
public class DicomReadingQuestionAnswer : ReadingQuestionTrial
{
@ -683,7 +683,7 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
/// <summary>
/// 标记工具
/// </summary>
public string MarkTool { get; set; } = string.Empty;
public string? MarkTool { get; set; }
/// <summary>
/// TrialId
@ -738,7 +738,7 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
/// <summary>
/// MeasureData
/// </summary>
public string MeasureData { get; set; } = string.Empty;
public string? MeasureData { get; set; }
/// <summary>
/// 是否是当前任务添加
@ -757,14 +757,14 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
/// </summary>
public Guid? MergeRowId { get; set; }
public string BlindName { get; set; } = string.Empty;
public string? BlindName { get; set; }
public string OrderMark { get; set; } = string.Empty;
public string? OrderMark { get; set; }
/// <summary>
/// 截图地址
/// </summary>
public string PicturePath { get; set; } = string.Empty;
public string? PicturePath { get; set; }
/// <summary>
/// 第一次添加的任务ID
@ -800,11 +800,11 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
/// <summary>
/// 来自于哪个标记
/// </summary>
public string FromMark { get; set; } = string.Empty;
public string? FromMark { get; set; }
public string ReportMark { get; set; } = string.Empty;
public string? ReportMark { get; set; }
public string RowMark { get; set; } = string.Empty;
public string? RowMark { get; set; }
}
@ -1000,13 +1000,13 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
/// <summary>
/// 序号标记
/// </summary>
public string OrderMark { get; set; } = string.Empty;
public string? OrderMark { get; set; }
public string OrderMarkName { get; set; } = string.Empty;
public string? OrderMarkName { get; set; }
public string FromMark { get; set; } = string.Empty;
public string? FromMark { get; set; }
/// <summary>
/// 病灶类型
@ -1059,7 +1059,7 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
/// <summary>
/// RowIndex
/// </summary>
public string RowIndex { get; set; }
public string? RowIndex { get; set; }
/// <summary>
/// RowIndex
@ -1072,7 +1072,7 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
/// </summary>
public bool IsDicomReading { get; set; } = true;
public string BlindName { get; set; } = string.Empty;
public string? BlindName { get; set; }
/// <summary>
@ -1093,10 +1093,10 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
/// <summary>
/// MeasureData
/// </summary>
public string MeasureData { get; set; }
public string? MeasureData { get; set; }
public string OtherMeasureData { get; set; }
public string? OtherMeasureData { get; set; }
public int ShowOrder { get; set; }
@ -1119,9 +1119,9 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
/// </summary>
public Guid? OtherStudyId { get; set; }
public string OtherMarkTool { get; set; }
public string? OtherMarkTool { get; set; }
public string OtherPicturePath { get; set; }
public string? OtherPicturePath { get; set; }
public int? OtherNumberOfFrames { get; set; }
@ -1165,12 +1165,12 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
/// <summary>
/// MarkTool
/// </summary>
public string MarkTool { get; set; } = string.Empty;
public string? MarkTool { get; set; }
/// <summary>
/// PicturePath
/// </summary>
public string PicturePath { get; set; } = string.Empty;
public string? PicturePath { get; set; }
/// <summary>
/// NumberOfFrames
@ -1180,14 +1180,14 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
/// <summary>
/// MeasureData
/// </summary>
public string MeasureData { get; set; } = string.Empty;
public string? MeasureData { get; set; }
public Guid? FirstAddTaskId { get; set; }
public QuestionType? QuestionType { get; set; }
public string OrderMarkName { get; set; } = string.Empty;
public string? OrderMarkName { get; set; }
/// <summary>
@ -1205,12 +1205,12 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
/// </summary>
public Guid? OtherStudyId { get; set; }
public string OtherMarkTool { get; set; }
public string? OtherMarkTool { get; set; }
public string OtherPicturePath { get; set; }
public string? OtherPicturePath { get; set; }
public int? OtherNumberOfFrames { get; set; }
public string OtherMeasureData { get; set; } = string.Empty;
public string? OtherMeasureData { get; set; }
}
public class GetReadingQuestionAndAnswerInDto
{
@ -2171,14 +2171,14 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
/// <summary>
/// 标记工具
/// </summary>
public string MarkTool { get; set; } = string.Empty;
public string? MarkTool { get; set; }
public decimal RowIndex { get; set; }
/// <summary>
/// 截图地址
/// </summary>
public string PicturePath { get; set; } = string.Empty;
public string? PicturePath { get; set; }
/// <summary>
/// 任务Id
@ -2190,9 +2190,9 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
/// </summary>
public Guid TrialId { get; set; }
public string MeasureData { get; set; } = string.Empty;
public string? MeasureData { get; set; }
public string OtherMeasureData { get; set; } = string.Empty;
public string? OtherMeasureData { get; set; }
public Guid? SeriesId { get; set; }
@ -2238,9 +2238,9 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
/// </summary>
public Guid? OtherStudyId { get; set; }
public string OtherMarkTool { get; set; } = string.Empty;
public string? OtherMarkTool { get; set; }
public string OtherPicturePath { get; set; } = string.Empty;
public string? OtherPicturePath { get; set; }
public int? OtherNumberOfFrames { get; set; }

View File

@ -7,6 +7,7 @@ using IRaCIS.Core.Application.Contracts;
using MassTransit;
using IRaCIS.Core.Application.Filter;
using IRaCIS.Core.Domain.Models;
using DocumentFormat.OpenXml.EMMA;
namespace IRaCIS.Application.Services
{
@ -89,20 +90,22 @@ namespace IRaCIS.Application.Services
var taskinfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisistTaskId).Select(t => new { t.BlindSubjectCode, t.TrialReadingCriterionId, t.TrialReadingCriterion.IsImageFilter, t.TrialReadingCriterion.CriterionModalitys }).FirstNotNullAsync();
IQueryable<NoneDicomStudyView> noneDicomStudyQueryable = default;
if (inDto.VisistTaskId == null)
{
noneDicomStudyQueryable = _noneDicomStudyRepository
.Where(t => visitIds.Contains(t.SubjectVisitId) && t.NoneDicomFileList.Any(t => !t.FileType.Contains(StaticData.FileType.Zip)))
.WhereIf(taskinfo.IsImageFilter == true, t => taskinfo.CriterionModalitys.Contains(t.Modality))
.ProjectTo<NoneDicomStudyView>(_mapper.ConfigurationProvider, new { isFilterZip = true });
}
else
noneDicomStudyQueryable = _noneDicomStudyRepository
.Where(t => visitIds.Contains(t.SubjectVisitId) && t.NoneDicomFileList.Any(t => !t.FileType.Contains(StaticData.FileType.Zip)))
.WhereIf(taskinfo.IsImageFilter == true, t => taskinfo.CriterionModalitys.Contains(t.Modality))
.ProjectTo<NoneDicomStudyView>(_mapper.ConfigurationProvider, new { isFilterZip = true });
if (inDto.VisistTaskId != null && _noneDicomStudyFileSystem.Any(t => t.VisitTaskId == inDto.VisistTaskId))
{
noneDicomStudyQueryable = _noneDicomStudyRepository.Where(t => t.TaskNoneDicomFileList.Any(t => t.VisitTaskId == inDto.VisistTaskId))
.Where(t => visitIds.Contains(t.SubjectVisitId))
.Where(t => taskinfo.IsImageFilter ? ("|" + taskinfo.CriterionModalitys + "|").Contains("|" + t.Modality + "|") : true)
.Where(t => visitIds.Contains(t.SubjectVisitId))
.ProjectTo<TaskDicomStudyView>(_mapper.ConfigurationProvider, new { isFilterZip = true, visiTaskId = inDto.VisistTaskId });
}
List<NoneDicomStudyView> result = await noneDicomStudyQueryable.ToListAsync();

View File

@ -605,7 +605,7 @@ namespace IRaCIS.Application.Services
//只有阅片期有
CutOffVisitId = rm.SubjectVisit.Id,
CutOffVisitName = rm.SubjectVisit.VisitName,
ReadingSetType = null,
ReadingSetType = rm.ReadingSetType,
//之前视图返回的null 应该是没用的?
ReadModuleId = rm.Id,

View File

@ -68,7 +68,10 @@ namespace IRaCIS.Core.Application.Service
#endregion
CreateMap<VisitTask, VisitTaskDto>();
CreateMap<SubmitTableQuestionInDto, ReadingTableAnswerRowInfo>().ForMember(dest => dest.CreateUser, opt => opt.Ignore());
CreateMap<SubmitTableQuestionInDto, ReadingTableAnswerRowInfo>()
.ForMember(dest => dest.CreateUser, opt => opt.Ignore())
.ForAllMembers(opts => opts.Condition((src, dest, srcMember) => srcMember != null));
CreateMap<ShortcutKey, DefaultShortcutKeyView>();
CreateMap<TrialDataFromSystem, ReadingMedicineTrialQuestion>().ForMember(dest => dest.CreateUser, opt => opt.Ignore());

View File

@ -190,9 +190,9 @@ namespace IRaCIS.Core.Application.Contracts
TrialSiteSurvey? currentEntity = null;
var userList = await _trialSiteUserRepository.Where(t => t.TrialId == userInfo.TrialId && t.TrialSiteId == userInfo.TrialSiteId, false, true).ProjectTo<TrialSiteUserSurvey>(_mapper.ConfigurationProvider).ToListAsync();
//普通登录
if (userInfo.IsUpdate == false)
{

View File

@ -36,7 +36,8 @@ namespace IRaCIS.Core.Application.AutoMapper
.ForMember(d => d.IsGenerateAccount, u => u.MapFrom(c => true))
.ForMember(d => d.IsGenerateSuccess, u => u.MapFrom(c => true))
.ForMember(d => d.SystemUserId, u => u.MapFrom(c => c.UserId))
.ForMember(d => d.IsJoin, u => u.MapFrom(c => !c.IsDeleted));
.ForMember(d => d.IsJoin, u => u.MapFrom(c => !c.IsDeleted))
.ForMember(d => d.CreateUser, u => u.Ignore());
//列表

View File

@ -10,6 +10,7 @@ using Microsoft.AspNetCore.Authorization;
using IRaCIS.Core.Application.Auth;
using IRaCIS.Core.Application.Contracts;
using DocumentFormat.OpenXml.Office2010.ExcelAc;
using IRaCIS.Core.Domain.Models;
namespace IRaCIS.Application.Services
{
@ -67,7 +68,7 @@ namespace IRaCIS.Application.Services
.WhereIf(inQuery.UserTypeId != null, t => t.User.UserTypeId == inQuery.UserTypeId)
.WhereIf(!string.IsNullOrWhiteSpace(inQuery.UserRealName), t => (t.User.FullName).Contains(inQuery.UserRealName))
.WhereIf(!string.IsNullOrWhiteSpace(inQuery.OrganizationName), t => t.User.OrganizationName.Contains(inQuery.OrganizationName))
.ProjectTo<AssginSiteCRCListDTO>(_mapper.ConfigurationProvider);
.ProjectTo<AssginSiteCRCListDTO>(_mapper.ConfigurationProvider,new { trialSiteId =inQuery.TrialSiteId});
return await query.ToPagedListAsync(inQuery);

View File

@ -31,8 +31,9 @@ namespace IRaCIS.Application.Services
IRepository<VisitStage> _visitStageRepository,
IRepository<TrialPaymentPrice> _trialPaymentPriceRepository,
IRepository<TrialDictionary> _trialDictionaryRepository,
IRepository<TrialBodyPart> _trialBodyPartRepository,
IOptionsMonitor<ServiceVerifyConfigOption> _verifyConfig) : BaseService, ITrialService
IRepository<TrialBodyPart> _trialBodyPartRepository,
IOptionsMonitor<ServiceVerifyConfigOption> _verifyConfig
) : BaseService, ITrialService
{

View File

@ -139,8 +139,8 @@ namespace IRaCIS.Application.Services
var query = _patientRepository.Where(t => t.TrialId == inQuery.TrialId)
.WhereIf(!string.IsNullOrWhiteSpace(inQuery.PatientIdStr), t => t.PatientIdStr.Contains(inQuery.PatientIdStr))
.WhereIf(!string.IsNullOrWhiteSpace(inQuery.PatientName), t => t.PatientName.Contains(inQuery.PatientName))
.WhereIf(!string.IsNullOrWhiteSpace(inQuery.SubejctCode), t => t.Subject.Code.Contains(inQuery.SubejctCode))
.WhereIf(!string.IsNullOrWhiteSpace(inQuery.TrialSiteKeyInfo), t => t.TrialSite.TrialSiteCode.Contains(inQuery.TrialSiteKeyInfo)
.WhereIf(!string.IsNullOrWhiteSpace(inQuery.SubejctCode), t => t.Subject.Code.Contains(inQuery.SubejctCode))
.WhereIf(!string.IsNullOrWhiteSpace(inQuery.TrialSiteKeyInfo), t => t.TrialSite.TrialSiteCode.Contains(inQuery.TrialSiteKeyInfo)
|| t.TrialSite.TrialSiteAliasName.Contains(inQuery.TrialSiteKeyInfo) || t.TrialSite.TrialSiteName.Contains(inQuery.TrialSiteKeyInfo))
.WhereIf(!string.IsNullOrWhiteSpace(inQuery.CallingAE), t => t.SCPStudyList.Any(t => t.CallingAE == inQuery.CallingAE))
.WhereIf(!string.IsNullOrWhiteSpace(inQuery.CalledAE), t => t.SCPStudyList.Any(t => t.CalledAE == inQuery.CalledAE))

View File

@ -2,6 +2,7 @@
using IRaCIS.Application.Contracts;
using IRaCIS.Core.Application.Service.WorkLoad.DTO;
using IRaCIS.Core.Domain.Models;
using static IRaCIS.Application.Services.TestService;
namespace IRaCIS.Core.Application.Service
{
@ -17,7 +18,9 @@ namespace IRaCIS.Core.Application.Service
CreateMap<SetCriterionJoinJoinAnalysisCommand, EnrollReadingCriterion>().ReverseMap();
CreateMap<TestModel, TestModel2>()
.ForAllMembers(opts => opts.Condition((src, dest, srcMember) => srcMember != null));
}
}

View File

@ -3,6 +3,7 @@ using DocumentFormat.OpenXml.Drawing.Charts;
using DocumentFormat.OpenXml.Wordprocessing;
using IP2Region.Net.XDB;
using IRaCIS.Application.Contracts;
using IRaCIS.Core.Application.BusinessFilter;
using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Helper;
using IRaCIS.Core.Application.Service;
@ -67,7 +68,7 @@ namespace IRaCIS.Application.Services
public async Task<IResponseOutput> DeleteConsistentDate(Guid trialReadingCriterionId,
[FromServices] IRepository<TaskConsistentRule> _taskConsistentRuleRepository,
[FromServices] IRepository<ReadingConsistentClinicalDataPDF> _readingConsistentClinicalDataPDFRepository,
[FromServices] IRepository<ReadingConsistentClinicalData> _readingConsistentClinicalDataRepository
[FromServices] IRepository<ReadingConsistentClinicalData> _readingConsistentClinicalDataRepository
)
{
@ -78,29 +79,24 @@ namespace IRaCIS.Application.Services
await _visitTaskRepository.BatchDeleteNoTrackingAsync(t => t.TrialReadingCriterionId == trialReadingCriterionId && t.IsAnalysisCreate == true);
await _readingConsistentClinicalDataPDFRepository.BatchDeleteNoTrackingAsync(t => consistentSubjectIdList.Contains(t.ReadingConsistentClinicalData.SubjectId));
await _readingConsistentClinicalDataRepository.BatchDeleteNoTrackingAsync(t => consistentSubjectIdList.Contains(t.SubjectId));
await _readingConsistentClinicalDataRepository.SaveChangesAsync();
return ResponseOutput.Ok();
}
public async Task<IResponseOutput> DeleteOSSDate([FromServices] IOSSService _oSSService, [FromServices] IWebHostEnvironment _hostEnvironment)
public async Task<IResponseOutput> DeleteOSSDate(string rootFolder,
[FromServices] IOSSService _oSSService, [FromServices] IWebHostEnvironment _hostEnvironment)
{
var deleteIdList = _trialRepository.Where(t => t.IsDeleted == true, false, true).Select(t => t.Id).ToList();
//var deleteIdList = _trialRepository.Where(t => t.IsDeleted == true, false, true).Select(t => t.Id).ToList();
//foreach (var deleteId in deleteIdList)
//{
// await _oSSService.DeleteFromPrefix($"{deleteId}");
//}
await _oSSService.DeleteFromPrefix($"01000000-0a00-0242-0d73-08dcac46a4bf");
await _oSSService.DeleteFromPrefix($"{rootFolder}");
return ResponseOutput.Ok();
}
@ -110,18 +106,32 @@ namespace IRaCIS.Application.Services
{
public Guid TestId { get; set; }
public string TestName { get; set; }
public string? TestName { get; set; }
}
public class TestModel2
{
public Guid TestId { get; set; }
public string TestName { get; set; }
}
public async Task<IResponseOutput> TestJson()
{
var model1 = new TestModel() { TestId = NewId.NextSequentialGuid(), TestName = null };
var model2 = new TestModel2() { TestId = NewId.NextSequentialGuid(), TestName = "test2" };
var model4 = _mapper.Map(model1, model2);
await _trialBodyPartRepository.FirstOrDefaultAsync();
await _trialBodyPartRepository.Where(t=>t.Trial.Id==Guid.Empty).FirstOrDefaultAsync();
await _trialBodyPartRepository.Where(t => t.Trial.Id == Guid.Empty).FirstOrDefaultAsync();
return ResponseOutput.Ok(new TestModel(), IRCEmailPasswordHelper.GenerateRandomPassword(10));
}
@ -235,33 +245,107 @@ namespace IRaCIS.Application.Services
return ResponseOutput.Ok();
}
[UnitOfWork]
public async Task<string> Get()
public class TestEncrept
{
public string Name { get; set; }
public string Code { get; set; }
}
public IResponseOutput TestEncreptTest(TestEncrept testModel)
{
return ResponseOutput.Ok(testModel);
}
//etx5EzcF9XWA6ICzQB5ywEEextuhmUwaHM2TmyyCC8Q=
[HttpPut("{name}/{code}")]
public IResponseOutput TestEncreptTest2(string name, string code)
{
return ResponseOutput.Ok($"name:{name} Code: {code}");
}
public IResponseOutput TestEncreptTest3(string name, string Code)
{
return ResponseOutput.Ok($"name:{name} Code: {Code}");
}
[UnitOfWork]
public async Task<string> Get([FromServices] IOptionsMonitor<IRCEncreptOption> _encreptResponseMonitor)
{
var _IRCEncreptOption = _encreptResponseMonitor.CurrentValue;
var publicKey = Encoding.UTF8.GetString(Convert.FromBase64String(_IRCEncreptOption.Base64RSAPublicKey));
var privateKey = Encoding.UTF8.GetString(Convert.FromBase64String(_IRCEncreptOption.Base64RSAPrivateKey));
Console.WriteLine(RSAEncryption.Encrypt(publicKey, MD5Helper.Md5("123456")));
string plainText = "Hello, BouncyCastle!";
string key = "12345678901234567890123456789012"; // AES 密钥长度应为 16 字节128 位)
string iv = "your-iv-12345678"; // IV 长度为 16 字节
Console.WriteLine($"原始文本: {plainText}");
// 加密
string encrypted = AesEncryption.Encrypt(plainText, key, iv);
Console.WriteLine($"加密后的数据: {encrypted}");
// 解密
string decrypted = AesEncryption.Decrypt(encrypted, key, iv);
Console.WriteLine($"解密后的数据: {decrypted}");
Console.WriteLine($"原始文本: {plainText}");
// 加密
string encrypte = AesEncryption.Encrypt(plainText, key);
Console.WriteLine($"加密后的数据: {encrypte}");
// 解密
string decrypte = AesEncryption.Decrypt(encrypte, key);
Console.WriteLine($"解密后的数据: {decrypte}");
//// Generate RSA keys
//var keyPair = RSAEncryption.GenerateRSAKeyPair(2048);
//// Export the public and private keys to PEM format
//string publicKey = RSAEncryption.ExportPublicKey(keyPair.Public);
//string privateKey = RSAEncryption.ExportPrivateKey(keyPair.Private);
//Console.WriteLine("Public Key:");
//Console.WriteLine(publicKey);
//Console.WriteLine($"{Convert.ToBase64String(Encoding.UTF8.GetBytes(publicKey))}");
//Console.WriteLine("\nPrivate Key:");
//Console.WriteLine(privateKey);
//Console.WriteLine($"{Convert.ToBase64String(Encoding.UTF8.GetBytes(privateKey))}");
// Generate RSA keys
var keyPair = RSAHelper.GenerateRSAKeyPair(2048);
// Export the public and private keys to PEM format
string publicKey = RSAHelper.ExportPublicKey(keyPair.Public);
string privateKey = RSAHelper.ExportPrivateKey(keyPair.Private);
Console.WriteLine("Public Key:");
Console.WriteLine(publicKey);
Console.WriteLine("\nPrivate Key:");
Console.WriteLine(privateKey);
Console.WriteLine("encrept sys Key:");
Console.WriteLine($"\n{RSAEncryption.Encrypt(publicKey, key)}");
// Data to encrypt
string dataToEncrypt = "Hello, RSA!";
Console.WriteLine("\nOriginal Data: " + dataToEncrypt);
// Encrypt the data
var encryptedData = RSAHelper.Encrypt(publicKey, dataToEncrypt);
var encryptedData = RSAEncryption.Encrypt(publicKey, dataToEncrypt);
Console.WriteLine("\nEncrypted Data: " + encryptedData);
// Decrypt the data
string decryptedData = RSAHelper.Decrypt(privateKey, encryptedData);
string decryptedData = RSAEncryption.Decrypt(privateKey, encryptedData);
Console.WriteLine("\nDecrypted Data: " + decryptedData);

View File

@ -1,61 +0,0 @@
//--------------------------------------------------------------------
// 此代码由T4模板自动生成 byzhouhang 20210918
// 生成时间 2022-06-07 14:09:29
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
using System;
using IRaCIS.Core.Domain.Share;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Collections.Generic;
namespace IRaCIS.Core.Domain.Models
{
///<summary>
///是否需要拆表
///</summary>
[Table("SubjectTaskCategory")]
public class SubjectTaskCategory : BaseAddAuditEntity
{
#region 导航属性
[JsonIgnore]
[ForeignKey("SouceReadModuleId")]
public ReadModule ReadModule { get; set; }
[JsonIgnore]
[ForeignKey("SourceSubjectVisitId")]
public SubjectVisit SubjectVisit { get; set; }
[JsonIgnore]
public Subject Subject { get; set; }
#endregion
public Guid TrialId { get; set; }
public string TaskName { get; set; } = string.Empty;
public string TaskBlindName { get; set; } = string.Empty;
//任务来源访视Id 方便回更访视读片状态
public Guid? SourceSubjectVisitId { get; set; }
public Guid? SouceReadModuleId { get; set; }
public ReadingCategory ReadingCategory { get; set; }
public Guid SubjectId { get; set; }
}
}

View File

@ -116,18 +116,6 @@ namespace IRaCIS.Core.Domain.Models
public User CreateUser { get; set; }
}
public abstract class BaseAddAuditEntityWithUserName : Entity, IAuditAddWithUserName
{
public string CreateUser { get; set; } = string.Empty;
public Guid CreateUserId { get; set; }
public DateTime CreateTime { get; set; }
}
public abstract class BaseAuditUpdateEntity : Entity, IAuditUpdate
{
public Guid UpdateUserId { get; set; }

View File

@ -7,32 +7,32 @@ using System;
using IRaCIS.Core.Domain.Share;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace IRaCIS.Core.Domain.Models
using Microsoft.EntityFrameworkCore;
namespace IRaCIS.Core.Domain.Models;
[Comment("数据上传 | 数据导出 | 邮件附件 文件记录表 (需要同步)")]
[Table("CommonDocument")]
public class CommonDocument : BaseFullDeleteAuditEntity
{
///<summary>
///CommonDocument
///</summary>
[Table("CommonDocument")]
public class CommonDocument : BaseFullDeleteAuditEntity
{
[Comment(" 业务场景")]
public EmailBusinessScenario BusinessScenarioEnum { get; set; }
public string Code { get; set; } = String.Empty;
public string Code { get; set; } = null!;
[Comment(" 系统标准枚举")]
public CriterionType? CriterionTypeEnum { get; set; }
public string Name { get; set; } = String.Empty;
public string Description { get; set; } = null!;
public string NameCN { get; set; } = string.Empty;
[Comment(" 类型-上传|导出|邮件附件")]
public CommonDocumentFileType FileTypeEnum { get; set; }
public string Path { get; set; } = String.Empty;
public string Name { get; set; } = null!;
public string NameCN { get; set; } = null!;
public string Description { get; set; } = String.Empty;
public CriterionType? CriterionTypeEnum { get; set; }
public CommonDocumentFileType FileTypeEnum { get; set; }
public EmailBusinessScenario BusinessScenarioEnum { get; set; }
}
public string Path { get; set; } = null!;
}

View File

@ -1,61 +1,63 @@
using IRaCIS.Core.Domain.Share;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace IRaCIS.Core.Domain.Models
namespace IRaCIS.Core.Domain.Models;
[Comment("后台 - 字典表(需要同步)")]
[Table("Dictionary")]
public partial class Dictionary : BaseFullAuditEntity
{
[Table("Dictionary")]
public partial class Dictionary : BaseFullAuditEntity
{
#region µ¼º½ÊôÐÔ
[JsonIgnore]
public List<DoctorDictionary> DoctorDicRelationList { get; set; } = new List<DoctorDictionary>();
#region 导航属性
[JsonIgnore]
public List<DoctorDictionary> DoctorDicRelationList { get; set; } = new List<DoctorDictionary>();
[JsonIgnore]
[ForeignKey("ConfigTypeId")]
public Dictionary ConfigDictionary { get; set; }
[JsonIgnore]
[ForeignKey("ConfigTypeId")]
public Dictionary ConfigDictionary { get; set; }
[JsonIgnore]
[ForeignKey("ParentId")]
public Dictionary Parent { get; set; }
[JsonIgnore]
public List<Dictionary> ChildList { get; set; } = new List<Dictionary>();
[JsonIgnore]
[ForeignKey("ParentId")]
public Dictionary Parent { get; set; }
[JsonIgnore]
public List<Dictionary> ChildList { get; set; } = new List<Dictionary>();
#endregion
#endregion
public string ChildGroup { get; set; } = string.Empty;
[StringLength(400)]
public string ChildGroup { get; set; } = null!;
public int ChildCodeEnum { get; set; }
public string Code { get; set; } = null!;
public DicDataTypeEnum DataTypeEnum { get; set; }
public Guid? ConfigTypeId { get; set; }
[Comment(" 字典类型- 枚举|bool|下拉框")]
public DicDataTypeEnum DataTypeEnum { get; set; }
[Column("Value")]
public string Value { get; set; } = string.Empty;
[StringLength(512)]
public string Description { get; set; } = null!;
[Column("ValueCN")]
public string ValueCN { get; set; } = string.Empty;
[Comment(" 是否字典类型配置")]
public bool IsConfig { get; set; }
public bool IsEnable { get; set; }
[StringLength(512)]
public string Description { get; set; } = string.Empty;
public Guid? ParentId { get; set; }
public int ShowOrder { get; set; }
public int ShowOrder { get; set; }
public string Code { get; set; } = string.Empty;
[StringLength(400)]
public string Value { get; set; } = null!;
public Guid? ParentId { get; set; }
public bool IsEnable { get; set; }
public Guid? ConfigTypeId { get; set; }
[StringLength(400)]
public string ValueCN { get; set; } = null!;
}
}

View File

@ -39,9 +39,6 @@ namespace IRaCIS.Core.Domain.Models
/// <summary> 业务层级 /// </summary>
public int BusinessLevelEnum { get; set; }
/// <summary> 邮件类型 /// </summary>
public int EmailTypeEnum { get; set; }
/// <summary> 邮件加急类型 /// </summary>
public int EmailUrgentEnum { get; set; }

View File

@ -9,215 +9,213 @@ using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Collections.Generic;
namespace IRaCIS.Core.Domain.Models
namespace IRaCIS.Core.Domain.Models;
///<summary>
///FrontAuditConfig
///</summary>
[Table("FrontAuditConfig")]
public class FrontAuditConfig : BaseFullAuditEntity
{
///<summary>
///FrontAuditConfig
///</summary>
[Table("FrontAuditConfig")]
public class FrontAuditConfig : BaseFullAuditEntity
{
#region 导航属性
#region 导航属性
#endregion
public string Value { get; set; } = String.Empty;
#endregion
public string Value { get; set; } = String.Empty;
public string ValueCN { get; set; } = String.Empty;
public string ValueCN { get; set; } = String.Empty;
public string Description { get; set; } = String.Empty;
public string Description { get; set; } = String.Empty;
public string DescriptionCN { get; set; } = String.Empty;
public string DescriptionCN { get; set; } = String.Empty;
/// <summary>
/// 是否有签名
/// </summary>
public bool IsHaveSign { get; set; }
/// <summary>
/// 是否有签名
/// </summary>
public bool IsHaveSign { get; set; }
/// <summary>
/// 是否有原因
/// </summary>
public bool IsHaveReason { get; set; }
/// <summary>
/// 是否有原因
/// </summary>
public bool IsHaveReason { get; set; }
/// <summary>
/// 是否完成
/// </summary>
public bool IsFinish { get; set; }
/// <summary>
/// 是否完成
/// </summary>
public bool IsFinish { get; set; }
/// <summary>
/// 是否加入计划
/// </summary>
public bool IsJoinPlan { get; set; }
/// <summary>
/// 是否加入计划
/// </summary>
public bool IsJoinPlan { get; set; }
/// <summary>
/// 标识
/// </summary>
public string Identification { get; set; } = string.Empty;
/// <summary>
/// 标识
/// </summary>
public string Identification { get; set; } = string.Empty;
public Guid? ParentId { get; set; }
public Guid? ParentId { get; set; }
public bool IsEnable { get; set; }
public bool IsEnable { get; set; }
public int Sort { get; set; }
public int Sort { get; set; }
public Guid? ModuleTypeId { get; set; }
public Guid? ModuleTypeId { get; set; }
public Guid? ObjectTypeId { get; set; }
public Guid? OptTypeId { get; set; }
public Guid? ObjectTypeId { get; set; }
public Guid? OptTypeId { get; set; }
public Guid? ChildrenTypeId { get; set; }
public Guid? ChildrenTypeId { get; set; }
public int IsShowParent { get; set; }
public int IsShowParent { get; set; }
public string InterfaceName { get; set; } = String.Empty;
public string InterfaceName { get; set; } = String.Empty;
//前端使用 C M
public string ConfigType { get; set; } = String.Empty;
//前端使用 C M
public string ConfigType { get; set; } = String.Empty;
//翻译的字段名 这里有可能是一个数组名 那么具体的翻译字段名就不是这个了
public string Code { get; set; } = String.Empty;
//翻译的字段名 这里有可能是一个数组名 那么具体的翻译字段名就不是这个了
public string Code { get; set; } = String.Empty;
/// <summary>
/// 字段的英文值
/// </summary>
public string CodeEn { get; set; } = string.Empty;
/// <summary>
/// 字段的英文值
/// </summary>
public string CodeEn { get; set; } = string.Empty;
//前端渲染数组 数组名 和数组值
public string ChildDataLabel { get; set; } = String.Empty;
//前端渲染数组 数组名 和数组值
public string ChildDataLabel { get; set; } = String.Empty;
/// <summary>
/// 前端渲染数组 数组名 和数组值 英文名称
/// </summary>
public string ChildDataEnLabel { get; set; } = string.Empty;
public string ChildDataValue { get; set; } = String.Empty;
/// <summary>
/// 前端渲染数组 数组名 和数组值 英文名称
/// </summary>
public string ChildDataEnLabel { get; set; } = string.Empty;
public string ChildDataValue { get; set; } = String.Empty;
/// <summary>
/// 翻译的字典名(单个字段翻译的时候)
/// </summary>
/// <summary>
/// 翻译的字典名(单个字段翻译的时候)
/// </summary>
public string DictionaryCode { get; set; } = String.Empty;
public string DictionaryCode { get; set; } = String.Empty;
/// <summary>
/// 前端展示类型 Router ArrayTable
/// </summary>
/// <summary>
/// 前端展示类型 Router ArrayTable
/// </summary>
public string DataType { get; set; } = String.Empty;
public string DataType { get; set; } = String.Empty;
// 后端翻译的类型 对应前端界面 "",Dictionary,Date
public string EnumType { get; set; } = String.Empty;
// 后端翻译的类型 对应前端界面 "" Dictionary Date
public string EnumType { get; set; } = String.Empty;
/// <summary>
/// 翻译的类型 FrontAudit 的描述 可能是Id Code
/// </summary>
public string DictionaryType { get; set; } = String.Empty;
/// <summary>
/// 翻译的类型 FrontAudit 的描述 可能是Id Code
/// </summary>
public string DictionaryType { get; set; } = String.Empty;
/// <summary>
/// 后端翻译的 日期类型
/// </summary>
/// <summary>
/// 后端翻译的 日期类型
/// </summary>
public string DateType { get; set; } = String.Empty;
public string DateType { get; set; } = String.Empty;
/// <summary> 字典表 </summary>
public string ForeignKeyTableName { get; set; } = String.Empty;
/// <summary> 字典表 </summary>
public string ForeignKeyTableName { get; set; } = String.Empty;
/// <summary> 字典Value </summary>
public string ForeignKeyValue { get; set; } = String.Empty;
/// <summary> 字典Value </summary>
public string ForeignKeyValue { get; set; } = String.Empty;
/// <summary> 字典 </summary>
public string ForeignKeyText { get; set; } = String.Empty;
/// <summary> 字典 </summary>
public string ForeignKeyText { get; set; } = String.Empty;
/// <summary>
/// 英文的翻译
/// </summary>
public string ForeignKeyEnText { get; set; } = string.Empty;
/// <summary>
/// 英文的翻译
/// </summary>
public string ForeignKeyEnText { get; set; } = string.Empty;
public string TableConfigJsonStr { get; set; } = String.Empty;
public string TableConfigJsonStr { get; set; } = String.Empty;
public string UrlConfigJsonStr { get; set; } = String.Empty;
public string UrlConfigJsonStr { get; set; } = String.Empty;
#region 废弃
//未知是否有用
public bool IsConfig { get; set; }
/// <summary>
/// 是否为特殊类型
/// </summary>
public bool IsSpecialType { get; set; }
public string DictionaryKey { get; set; } = string.Empty;
#region 废弃
//未知是否有用
public bool IsConfig { get; set; }
/// <summary>
/// 是否为特殊类型
/// </summary>
public bool IsSpecialType { get; set; }
public string DictionaryKey { get; set; } = string.Empty;
public bool IsShowByTrialConfig { get; set; }
public string TrialConfigRelyFieldName { get; set; } = string.Empty;
public bool IsShowByTrialConfig { get; set; }
public string TrialConfigRelyFieldName { get; set; } = string.Empty;
#endregion
}
public class UrlConfig
{
public bool IsRoute { get; set; }
public string RoutePath { get; set; } = string.Empty;
public bool IsHaveParameters { get; set; }
public List<ParameterConfig> ParameterList { get; set; } = new List<ParameterConfig>();
public class ParameterConfig
{
public string UrlParameterName { get; set; } = String.Empty;
public string UrlParameterValueName { get; set; } = String.Empty;
}
}
public class TableConfig
{
public bool IsList { get; set; }
public string ListName { get; set; } = String.Empty;
public bool IsFixedColumn { get; set; }
public string FixedColumnName { get; set; } = String.Empty;
public string FixedColumnEnName { get; set; } = String.Empty;
public string ColumnName { get; set; } = String.Empty;
public string ColumnValue { get; set; } = String.Empty;
public bool IsMerge { get; set; }
public string MergeColumnName { get; set; } = String.Empty;
public string MergeColumnEnName { get; set; } = String.Empty;
public string ColumnEnName { get; set; } = String.Empty;
public bool IsPicture { get; set; }
public bool IsNeedTransalate { get; set; }
public string TranslateDictionaryName { get; set; } = String.Empty;
public bool IsDynamicTranslate { get; set; }
}
#endregion
}
public class UrlConfig
{
public bool IsRoute { get; set; }
public string RoutePath { get; set; } = string.Empty;
public bool IsHaveParameters { get; set; }
public List<ParameterConfig> ParameterList { get; set; } = new List<ParameterConfig>();
public class ParameterConfig
{
public string UrlParameterName { get; set; } = String.Empty;
public string UrlParameterValueName { get; set; } = String.Empty;
}
}
public class TableConfig
{
public bool IsList { get; set; }
public string ListName { get; set; } = String.Empty;
public bool IsFixedColumn { get; set; }
public string FixedColumnName { get; set; } = String.Empty;
public string FixedColumnEnName { get; set; } = String.Empty;
public string ColumnName { get; set; } = String.Empty;
public string ColumnValue { get; set; } = String.Empty;
public bool IsMerge { get; set; }
public string MergeColumnName { get; set; } = String.Empty;
public string MergeColumnEnName { get; set; } = String.Empty;
public string ColumnEnName { get; set; } = String.Empty;
public bool IsPicture { get; set; }
public bool IsNeedTransalate { get; set; }
public string TranslateDictionaryName { get; set; } = String.Empty;
public bool IsDynamicTranslate { get; set; }
}

View File

@ -1,78 +1,89 @@
namespace System.ComponentModel.DataAnnotations
namespace System.ComponentModel.DataAnnotations;
[AttributeUsage(
AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter,
AllowMultiple = false)]
public class GuidNotEmptyAttribute : ValidationAttribute
{
[AttributeUsage(
AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter,
AllowMultiple = false)]
public class GuidNotEmptyAttribute : ValidationAttribute
public const string DefaultErrorMessage = "The {0} field must not be empty";
public GuidNotEmptyAttribute() : base(DefaultErrorMessage) { }
public override bool IsValid(object value)
{
public const string DefaultErrorMessage = "The {0} field must not be empty";
public GuidNotEmptyAttribute() : base(DefaultErrorMessage) { }
public override bool IsValid(object value)
//NotEmpty doesn't necessarily mean required
if (value is null)
{
//NotEmpty doesn't necessarily mean required
if (value is null)
{
return true;
}
switch (value)
{
case Guid guid:
return guid != Guid.Empty;
default:
return true;
}
}
}
public class NotDefaultAttribute : ValidationAttribute
{
public const string DefaultErrorMessage = "The {0} field is is not passed or not set a valid value";
public NotDefaultAttribute() : base(DefaultErrorMessage) { }
public override bool IsValid(object value)
{
//NotDefault doesn't necessarily mean required
if (value is null)
{
return true;
}
var type = value.GetType();
if (type.IsValueType)
{
var defaultValue = Activator.CreateInstance(type);
return !value.Equals(defaultValue);
}
// non-null ref type
return true;
}
}
public class CanConvertToTimeAttribute : ValidationAttribute
{
public const string DefaultErrorMessage = "The {0} field is is not a valid DateTime value";
public CanConvertToTimeAttribute() : base(DefaultErrorMessage) { }
public override bool IsValid(object value)
switch (value)
{
if (value is null)
{
return false;
}
if (DateTime.TryParse(value.ToString(), out _) == true)
{
case Guid guid:
return guid != Guid.Empty;
default:
return true;
}
else
{
return false;
}
}
}
}
public class NotDefaultAttribute : ValidationAttribute
{
public const string DefaultErrorMessage = "The {0} field is is not passed or not set a valid value";
public NotDefaultAttribute() : base(DefaultErrorMessage) { }
public override bool IsValid(object value)
{
//NotDefault doesn't necessarily mean required
if (value is null)
{
return true;
}
var type = value.GetType();
if (type.IsValueType)
{
var defaultValue = Activator.CreateInstance(type);
return !value.Equals(defaultValue);
}
// non-null ref type
return true;
}
}
public class CanConvertToTimeAttribute : ValidationAttribute
{
public const string DefaultErrorMessage = "The {0} field is is not a valid DateTime value";
public CanConvertToTimeAttribute() : base(DefaultErrorMessage) { }
public override bool IsValid(object value)
{
if (value is null)
{
return false;
}
if (DateTime.TryParse(value.ToString(), out _) == true)
{
return true;
}
else
{
return false;
}
}
}
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
public class DecimalPrecisionAttribute : Attribute
{
public int Precision { get; }
public int Scale { get; }
public DecimalPrecisionAttribute(int precision, int scale)
{
Precision = precision;
Scale = scale;
}
}

View File

@ -1,37 +1,49 @@
using Microsoft.EntityFrameworkCore;
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace IRaCIS.Core.Domain.Models
namespace IRaCIS.Core.Domain.Models;
//public enum AttachmentType
//{
// Avatar=1,//头像
// Resume=2,//简历
// GCP=3,//GCP证书
// MedicalLicence=4,//医师资格证
// PracticeCertificate=5,//执业资格证
// LargeEquipmentWorkingCertificate=6,//大型器械上岗证
// HighestDegreeCertificate=7//最高学历证书
//}
[Comment("医生 - 简历|证书 文档表")]
[Table("Attachment")]
public class Attachment : BaseAddAuditEntity
{
//public enum AttachmentType
//{
// Avatar=1,//头像
// Resume=2,//简历
// GCP=3,//GCP证书
// MedicalLicence=4,//医师资格证
// PracticeCertificate=5,//执业资格证
// LargeEquipmentWorkingCertificate=6,//大型器械上岗证
// HighestDegreeCertificate=7//最高学历证书
//}
[Table("Attachment")]
public partial class Attachment : BaseAddAuditEntity
{
[JsonIgnore]
public Doctor Doctor { get; set; }
[JsonIgnore]
public Doctor Doctor { get; set; }
public Guid DoctorId { get; set; }
public string Type { get; set; } = string.Empty;
public bool IsOfficial { get; set; } = false;
public string Path { get; set; } = string.Empty;
public string Code { get; set; } = string.Empty;
public DateTime? ExpiryDate { get; set; }
public string FileName { get; set; } = string.Empty;
[Comment(" 编码")]
[StringLength(400)]
public string Code { get; set; } = null!;
//language=1 中文, 2为英文
public int Language { get; set; } = 0;
public Guid DoctorId { get; set; }
//public Guid CreateUserId { get; set; } = Guid.Empty;
//public DateTime? CreateTime { get; set; }
}
[Comment(" 过期时间")]
public DateTime? ExpiryDate { get; set; }
public string FileName { get; set; } = null!;
[Comment(" 是否正式简历")]
public bool IsOfficial { get; set; }
[Comment(" 1 中文 2为英文")]
public int Language { get; set; }
[StringLength(512)]
public string Path { get; set; } = null!;
[Comment(" 文件类型名")]
[StringLength(400)]
public string Type { get; set; } = null!;
}

View File

@ -1,186 +1,194 @@
using IRaCIS.Core.Domain.Share;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace IRaCIS.Core.Domain.Models
namespace IRaCIS.Core.Domain.Models;
[Comment("医生 - 基础信息表")]
[Table("Doctor")]
public class Doctor : BaseFullAuditEntity
{
[Table("Doctor")]
public partial class Doctor : BaseFullAuditEntity
{
#region 导航属性
#region 导航属性
//导航属性
[JsonIgnore]
public List<DoctorDictionary> DoctorDicRelationList { get; set; } = new List<DoctorDictionary>();
[JsonIgnore]
public List<TrialExperienceCriteria> TrialExperienceCriteriaList { get; set; }
//导航属性
[JsonIgnore]
public List<DoctorDictionary> DoctorDicRelationList { get; set; } = new List<DoctorDictionary>();
[JsonIgnore]
public List<TrialExperienceCriteria> TrialExperienceCriteriaList { get; set; }
[JsonIgnore]
public List<Enroll> EnrollList { get; set; }
[JsonIgnore]
public List<Enroll> EnrollList { get; set; }
[JsonIgnore]
[ForeignKey("HospitalId")]
public Hospital Hospital { get; set; }
[JsonIgnore]
[ForeignKey("SpecialityId")]
public virtual Dictionary Speciality { get; set; }
[JsonIgnore]
[ForeignKey("DepartmentId")]
public virtual Dictionary Department { get; set; }
[JsonIgnore]
[ForeignKey("HospitalId")]
public Hospital Hospital { get; set; }
[JsonIgnore]
[ForeignKey("SpecialityId")]
public virtual Dictionary Speciality { get; set; }
[JsonIgnore]
[ForeignKey("DepartmentId")]
public virtual Dictionary Department { get; set; }
[JsonIgnore]
[ForeignKey("RankId")]
public virtual Dictionary Rank { get; set; }
[JsonIgnore]
[ForeignKey("RankId")]
public virtual Dictionary Rank { get; set; }
[JsonIgnore]
[ForeignKey("PositionId")]
public virtual Dictionary Position { get; set; }
[JsonIgnore]
public List<Attachment> AttachmentList { get; set; }
[JsonIgnore]
public List<DoctorCriterionFile> CriterionFileList { get; set; }
[JsonIgnore]
[ForeignKey("PositionId")]
public virtual Dictionary Position { get; set; }
[JsonIgnore]
public List<Attachment> AttachmentList { get; set; }
[JsonIgnore]
public List<DoctorCriterionFile> CriterionFileList { get; set; }
[JsonIgnore]
public User User { get; set; }
#endregion
[JsonIgnore]
public User User { get; set; }
#endregion
public bool AcceptingNewTrial { get; set; }
public string ReviewerCode { get; set; } = string.Empty;
public bool ActivelyReading { get; set; }
public int Code { get; set; }
[MaxLength]
public string? AdminComment { get; set; }
[StringLength(100)]
public string Phone { get; set; } = string.Empty;
public DateTime? AuditTime { get; set; }
public Guid AuditUserId { get; set; }
[StringLength(100)]
public string Password { get; set; } = string.Empty;
public string BlindName { get; set; } = null!;
public string BlindNameCN { get; set; } = null!;
[StringLength(50)]
public string ChineseName { get; set; } = string.Empty;
[MaxLength]
public string? BlindPublications { get; set; }
[StringLength(100)]
public string FirstName { get; set; } = string.Empty;
[StringLength(400)]
public string ChineseName { get; set; } = null!;
public int Code { get; set; }
[StringLength(100)]
public string LastName { get; set; } = string.Empty;
public ContractorStatusEnum CooperateStatus { get; set; } = ContractorStatusEnum.Noncooperation;
[NotMapped]
public string FullName => LastName + " / " + FirstName;
public Guid DepartmentId { get; set; }
public int Sex { get; set; }
[StringLength(400)]
public string DepartmentOther { get; set; } = null!;
[StringLength(400)]
public string DepartmentOtherCN { get; set; } = null!;
[StringLength(100)]
public string EMail { get; set; } = string.Empty;
[StringLength(400)]
public string EMail { get; set; } = null!;
[StringLength(400)]
public string FirstName { get; set; } = null!;
[StringLength(100)]
public string WeChat { get; set; } = string.Empty;
public int GCP { get; set; }
public Guid GCPId { get; set; }
[StringLength(1000)]
public string Introduction { get; set; } = string.Empty;
public Guid HospitalId { get; set; }
public Guid? DepartmentId { get; set; } = Guid.Empty;
public string HospitalOther { get; set; } = null!;
public string HospitalOtherCN { get; set; } = null!;
[StringLength(100)]
public string DepartmentOther { get; set; } = string.Empty;
[StringLength(2000)]
public string Introduction { get; set; } = null!;
public Guid? PhysicianId { get; set; }
public string Physician { get; set; } = string.Empty;
public string PhysicianCN { get; set; } = string.Empty;
public bool IsVirtual { get; set; }
public Guid? RankId { get; set; } = Guid.Empty;
public DateTime? LastLoginTime { get; set; }
[StringLength(400)]
public string LastName { get; set; } = null!;
[StringLength(100)]
public string RankOther { get; set; } = string.Empty;
public int Nation { get; set; }
public Guid? PositionId { get; set; } = Guid.Empty;
public Guid OrganizationId { get; set; }
[StringLength(100)]
public string PositionOther { get; set; } = string.Empty;
[MaxLength]
public string? OtherClinicalExperience { get; set; }
// 是否可空 意味着 左连接 否则 一直是内连接
public Guid? HospitalId { get; set; } = Guid.Empty;
[MaxLength]
public string? OtherClinicalExperienceCN { get; set; }
[StringLength(200)]
public string HospitalOther { get; set; } = string.Empty;
[StringLength(400)]
public string Password { get; set; } = null!;
[StringLength(100)]
public string ReadingTypeOther { get; set; } = string.Empty;
[StringLength(400)]
public string Phone { get; set; } = null!;
public string PhotoPath { get; set; } = null!;
[StringLength(100)]
public string SubspecialityOther { get; set; } = string.Empty;
public string Physician { get; set; } = null!;
public int GCP { get; set; }
public string PhysicianCN { get; set; } = null!;
public Guid? GCPId { get; set; } = Guid.Empty;
public Guid? PhysicianId { get; set; }
public Guid OrganizationId { get; set; } = Guid.Empty;
public Guid? PositionId { get; set; }
public string OtherClinicalExperience { get; set; } = string.Empty;
public string OtherClinicalExperienceCN { get; set; } = string.Empty;
[StringLength(400)]
public string PositionOther { get; set; } = null!;
public ContractorStatusEnum CooperateStatus { get; set; } = ContractorStatusEnum.Noncooperation;
[StringLength(400)]
public string PositionOtherCN { get; set; } = null!;
public ResumeStatusEnum ResumeStatus { get; set; } = ResumeStatusEnum.Failed;
public Guid RankId { get; set; }
[StringLength(400)]
public string RankOther { get; set; } = null!;
[StringLength(400)]
public string RankOtherCN { get; set; } = null!;
[StringLength(512)]
public string PhotoPath { get; set; } = string.Empty;
[StringLength(400)]
public string ReadingTypeOther { get; set; } = null!;
[StringLength(512)]
public string ResumePath { get; set; } = string.Empty;
public Guid? SpecialityId { get; set; } = Guid.Empty;
[StringLength(400)]
public string ReadingTypeOtherCN { get; set; } = null!;
public string SpecialityOther { get; set; } = string.Empty;
[StringLength(512)]
public string ResumePath { get; set; } = null!;
public string AdminComment { get; set; } = string.Empty;
public ResumeStatusEnum ResumeStatus { get; set; } = ResumeStatusEnum.Failed;
public ReviewerInformationConfirmStatus ReviewStatus { get; set; } = ReviewerInformationConfirmStatus.ConfirmRefuse;
[StringLength(400)]
public string ReviewerCode { get; set; } = null!;
public bool AcceptingNewTrial { get; set; } = false;
public bool ActivelyReading { get; set; } = false;
public ReviewerInformationConfirmStatus ReviewStatus { get; set; } = ReviewerInformationConfirmStatus.ConfirmRefuse;
public DateTime? LastLoginTime { get; set; }
public int Sex { get; set; }
public Guid AuditUserId { get; set; } = Guid.Empty;
public Guid SpecialityId { get; set; }
public DateTime? AuditTime { get; set; }
[StringLength(400)]
public string SpecialityOther { get; set; } = null!;
public int Nation { get; set; } = 0; // 支付类型0-代表中国医生CN1-代表美国医生US
[StringLength(400)]
public string SpecialityOtherCN { get; set; } = null!;
[StringLength(400)]
public string SubspecialityOther { get; set; } = null!;
public string ReadingTypeOtherCN { get; set; } = string.Empty;
public string HospitalOtherCN { get; set; } = string.Empty;
public string PositionOtherCN { get; set; } = string.Empty;
public string RankOtherCN { get; set; } = string.Empty;
public string DepartmentOtherCN { get; set; } = string.Empty;
public string SubspecialityOtherCN { get; set; } = string.Empty;
public string SpecialityOtherCN { get; set; } = string.Empty;
[StringLength(400)]
public string SubspecialityOtherCN { get; set; } = null!;
[StringLength(400)]
public string WeChat { get; set; } = null!;
public bool IsVirtual { get; set; }
[NotMapped]
public string FullName => LastName + " / " + FirstName;
public string BlindName { get; set; } = string.Empty;
public string BlindNameCN { get; set; } = string.Empty;
public string BlindPublications { get; set; } = string.Empty;
}
}

View File

@ -7,64 +7,43 @@ using System;
using IRaCIS.Core.Domain.Share;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace IRaCIS.Core.Domain.Models
using Microsoft.EntityFrameworkCore;
namespace IRaCIS.Core.Domain.Models;
[Comment("医生 - 项目标准签名文档")]
[Table("DoctorCriterionFile")]
public class DoctorCriterionFile : BaseAddAuditEntity
{
///<summary>
///DoctorCriterionFile
///</summary>
[Table("DoctorCriterionFile")]
public class DoctorCriterionFile :BaseAddAuditEntity
{
#region 导航属性
[JsonIgnore]
[ForeignKey("DoctorId")]
public Doctor Doctor { get; set; }
#endregion
/// <summary>
/// 文件名称
/// </summary>
public string FileName { get; set; } = string.Empty;
#region 导航属性
[JsonIgnore]
[ForeignKey("DoctorId")]
public Doctor Doctor { get; set; }
#endregion
/// <summary>
/// 文件路径
/// </summary>
public string FilePath { get; set; } = string.Empty;
public string CriterionName { get; set; } = null!;
/// <summary>
/// 标准类型
/// </summary>
public CriterionType CriterionType { get; set; }
/// <summary>
/// 医生Id
/// </summary>
public Guid DoctorId { get; set; }
/// <summary>
/// 备注
/// </summary>
public string Remark { get; set; } = string.Empty;
[Comment("标准类型")]
public CriterionType CriterionType { get; set; }
/// <summary>
/// 文件类型
/// </summary>
public CriterionFileType FileType { get; set; }
public Guid DoctorId { get; set; }
[StringLength(400)]
public string FileName { get; set; } = null!;
[StringLength(4000)]
public string FilePath { get; set; } = null!;
public CriterionFileType FileType { get; set; }
public bool IsEnable { get; set; }
public string Remark { get; set; } = null!;
public Guid? TrialId { get; set; }
public Guid? TrialReadingCriterionId { get; set; }
}
/// <summary>
/// 是否启用
/// </summary>
public bool IsEnable { get; set; } = true;
public string CriterionName { get; set; } = string.Empty;
public Guid? TrialReadingCriterionId { get; set; }
public Guid? TrialId { get; set; }
}
}

View File

@ -62,8 +62,6 @@ namespace IRaCIS.Core.Domain.Models
/// <summary> 业务层级 /// </summary>
public int BusinessLevelEnum { get; set; }
/// <summary> 邮件类型 /// </summary>
public int EmailTypeEnum { get; set; }
/// <summary> 邮件加急类型 /// </summary>
public int EmailUrgentEnum { get; set; }

View File

@ -1,58 +1,85 @@
using System;
using Microsoft.EntityFrameworkCore;
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace IRaCIS.Core.Domain.Models
namespace IRaCIS.Core.Domain.Models;
[Comment("归档 - Instance表")]
[Table("DicomInstance")]
public class DicomInstance : BaseFullAuditEntity, IEntitySeqId
{
[Table("DicomInstance")]
public class DicomInstance : BaseFullAuditEntity, IEntitySeqId
{
#region 导航属性
[JsonIgnore]
[ForeignKey("SeriesId")]
public DicomSeries DicomSerie { get; set; }
#region 导航属性
[JsonIgnore]
[ForeignKey("SeriesId")]
public DicomSeries DicomSerie { get; set; }
[JsonIgnore]
[ForeignKey("StudyId")]
public DicomStudy DicomStudy { get; set; }
#endregion
[JsonIgnore]
[ForeignKey("StudyId")]
public DicomStudy DicomStudy { get; set; }
#endregion
public bool Anonymize { get; set; }
public bool CPIStatus { get; set; }
public long? FileSize { get; set; }
[StringLength(500)]
public string FrameOfReferenceUID { get; set; } = null!;
[StringLength(512)]
public string HtmlPath { get; set; } = null!;
public int ImageColumns { get; set; }
public int ImageRows { get; set; }
[StringLength(400)]
public string ImagerPixelSpacing { get; set; } = null!;
public int InstanceNumber { get; set; }
public DateTime? InstanceTime { get; set; }
public int NumberOfFrames { get; set; }
[MaxLength]
[Unicode(false)]
public string Path { get; set; } = null!;
public Guid SeqId { get; set; }
public Guid StudyId { get; set; }
public Guid SeriesId { get; set; }
public string StudyInstanceUid { get; set; } = String.Empty;
public string SeriesInstanceUid { get; set; } = String.Empty;
public string SopInstanceUid { get; set; } = String.Empty;
public int InstanceNumber { get; set; }
public DateTime? InstanceTime { get; set; }
public bool CPIStatus { get; set; }
public int ImageRows { get; set; }
public int ImageColumns { get; set; }
public int SliceLocation { get; set; }
[StringLength(400)]
public string PixelSpacing { get; set; } = null!;
public Guid SeqId { get; set; }
public string SliceThickness { get; set; } = String.Empty;
public int NumberOfFrames { get; set; }
public string PixelSpacing { get; set; } = String.Empty;
public Guid SeriesId { get; set; }
public string ImagerPixelSpacing { get; set; } = String.Empty;
public string FrameOfReferenceUID { get; set; } = String.Empty;
public string WindowCenter { get; set; } = String.Empty;
public string WindowWidth { get; set; } = String.Empty;
public string SeriesInstanceUid { get; set; } = null!;
public int SliceLocation { get; set; }
public Guid TrialId { get; set; }
[StringLength(400)]
public string SliceThickness { get; set; } = null!;
public Guid SubjectId { get; set; }
public Guid SubjectVisitId { get; set; }
public bool Anonymize { get; set; }
public string Path { get; set; } = String.Empty;
public string SopInstanceUid { get; set; } = null!;
public string HtmlPath { get; set; } = string.Empty;
public Guid StudyId { get; set; }
public long? FileSize { get; set; }
public string StudyInstanceUid { get; set; } = null!;
}
public Guid SubjectId { get; set; }
public Guid SubjectVisitId { get; set; }
public Guid TrialId { get; set; }
[StringLength(400)]
public string WindowCenter { get; set; } = null!;
[StringLength(400)]
public string WindowWidth { get; set; } = null!;
}

View File

@ -1,62 +1,79 @@
using System;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace IRaCIS.Core.Domain.Models
namespace IRaCIS.Core.Domain.Models;
[Comment("归档 - 序列表")]
public partial class DicomSeries : BaseFullDeleteAuditEntity, IEntitySeqId
{
[Table("DicomSeries")]
public class DicomSeries : BaseFullDeleteAuditEntity, IEntitySeqId
{
#region 导航属性
[JsonIgnore]
[ForeignKey("StudyId")]
public DicomStudy DicomStudy { get; set; }
#region 导航属性
[JsonIgnore]
[ForeignKey("StudyId")]
public DicomStudy DicomStudy { get; set; }
[JsonIgnore]
public List<DicomInstance> DicomInstanceList { get; set; }
[JsonIgnore]
public List<DicomInstance> DicomInstanceList { get; set; }
[JsonIgnore]
public List<SubjectCriteriaEvaluationVisitStudyFilter> SubjectCriteriaEvaluationVisitStudyFilterList { get; set; }
#endregion
[JsonIgnore]
public List<SubjectCriteriaEvaluationVisitStudyFilter> SubjectCriteriaEvaluationVisitStudyFilterList { get; set; }
#endregion
public string AcquisitionNumber { get; set; } = null!;
public string AcquisitionTime { get; set; } = null!;
public Guid SeqId { get; set; }
public Guid StudyId { get; set; }
public string StudyInstanceUid { get; set; }=string.Empty;
public string SeriesInstanceUid { get; set; } = string.Empty;
public int SeriesNumber { get; set; }
public DateTime? SeriesTime { get; set; }
public string Modality { get; set; } = string.Empty;
public string Description { get; set; } = string.Empty;
public int InstanceCount { get; set; }
public string SliceThickness { get; set; } = string.Empty;
public string BodyPartExamined { get; set; } = null!;
public string ImagePositionPatient { get; set; } = string.Empty;
public string ImageOrientationPatient { get; set; } = string.Empty;
public string BodyPartExamined { get; set; } = string.Empty;
public string SequenceName { get; set; } = string.Empty;
public string ProtocolName { get; set; } = string.Empty;
public string ImagerPixelSpacing { get; set; } = string.Empty;
public string BodyPartForEdit { get; set; } = null!;
public string AcquisitionTime { get; set; } = string.Empty;
public string AcquisitionNumber { get; set; } = string.Empty;
public string TriggerTime { get; set; } = string.Empty;
[StringLength(500)]
public string Description { get; set; } = null!;
public Guid TrialId { get; set; }
public string ImageOrientationPatient { get; set; } = null!;
public Guid SubjectId { get; set; }
public Guid SubjectVisitId { get; set; }
public string ImagePositionPatient { get; set; } = null!;
[StringLength(1600)]
public string ImageResizePath { get; set; } = null!;
public string BodyPartForEdit { get; set; } = string.Empty;
public string ImagerPixelSpacing { get; set; } = null!;
public bool IsReading { get; set; } = true;
public int InstanceCount { get; set; }
public string ImageResizePath { get; set; }=string.Empty;
public bool IsReading { get; set; } = true;
public Guid? VisitTaskId { get; set; }
public string Modality { get; set; } = null!;
}
[StringLength(500)]
public string ProtocolName { get; set; } = null!;
public Guid SeqId { get; set; }
public string SequenceName { get; set; } = null!;
public string SeriesInstanceUid { get; set; } = null!;
public int SeriesNumber { get; set; }
public DateTime? SeriesTime { get; set; }
public string SliceThickness { get; set; } = null!;
public Guid StudyId { get; set; }
public string StudyInstanceUid { get; set; } = null!;
public Guid SubjectId { get; set; }
public Guid SubjectVisitId { get; set; }
public Guid TrialId { get; set; }
public string TriggerTime { get; set; } = null!;
public Guid? VisitTaskId { get; set; }
}

View File

@ -1,4 +1,5 @@
using System;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
@ -36,58 +37,75 @@ namespace IRaCIS.Core.Domain.Models
#endregion
public string AccessionNumber { get; set; } = null!;
public string AcquisitionNumber { get; set; } = null!;
public string AcquisitionTime { get; set; } = null!;
[StringLength(512)]
public string BodyPartExamined { get; set; } = null!;
public string BodyPartForEdit { get; set; } = null!;
public int Code { get; set; }
[StringLength(1000)]
public string Description { get; set; } = null!;
public int InstanceCount { get; set; }
[StringLength(400)]
public string InstitutionName { get; set; } = null!;
public bool IsDoubleReview { get; set; }
public bool IsFromPACS { get; set; }
public string Modalities { get; set; } = null!;
public string ModalityForEdit { get; set; } = null!;
public string PatientAge { get; set; } = null!;
public string PatientBirthDate { get; set; } = null!;
public string PatientId { get; set; } = null!;
public string PatientName { get; set; } = null!;
public string PatientSex { get; set; } = null!;
[Comment(" 序列Id 避免内存移动")]
public Guid SeqId { get; set; }
public Guid TrialId { get; set; }
public int SeriesCount { get; set; }
[StringLength(400)]
public string StudyCode { get; set; } = null!;
[Comment(" DicomTag.StudyID")]
public string StudyId { get; set; } = null!;
[StringLength(500)]
public string StudyInstanceUid { get; set; } = null!;
public DateTime? StudyTime { get; set; }
public Guid SubjectId { get; set; }
public Guid SubjectVisitId { get; set; }
public int Code { get; set; } = 0;
public Guid TrialId { get; set; }
public string StudyCode { get; set; } = string.Empty;
public string TriggerTime { get; set; } = null!;
public string StudyInstanceUid { get; set; } = string.Empty;
public DateTime? StudyTime { get; set; }
public string Modalities { get; set; } = string.Empty;
[Comment(" 上传时间")]
public DateTime? UploadedTime { get; set; }
public string Description { get; set; } = string.Empty;
public int SeriesCount { get; set; } = 0;
public int InstanceCount { get; set; } = 0;
public string Uploader { get; set; } = null!;
public string InstitutionName { get; set; } = string.Empty;
public string PatientId { get; set; } = string.Empty;
public string PatientName { get; set; } = string.Empty;
public string PatientAge { get; set; } = string.Empty;
public string PatientSex { get; set; } = string.Empty;
public string StudyId { get; set; } = string.Empty;
public string AccessionNumber { get; set; } = string.Empty;
public string PatientBirthDate { get; set; } = string.Empty;
public string AcquisitionTime { get; set; } = string.Empty;
public string AcquisitionNumber { get; set; } = string.Empty;
public string TriggerTime { get; set; } = string.Empty;
public string BodyPartExamined { get; set; } = string.Empty;
public string BodyPartForEdit { get; set; } = string.Empty;
public string ModalityForEdit { get; set; } = string.Empty;
//0 未知 1 单重 2 双重
public bool IsDoubleReview { get; set; }
public bool IsFromPACS { get; set; }
}

View File

@ -1,22 +1,30 @@
using Microsoft.EntityFrameworkCore;
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace IRaCIS.Core.Domain.Models
namespace IRaCIS.Core.Domain.Models;
[Comment("机构 - CRO")]
[Table("CROCompany")]
public class CRO : BaseFullAuditEntity
{
[Table("CROCompany")]
public partial class CRO : BaseFullAuditEntity
{
#region µ¼º½ÊôÐÔ
#region 导航属性
#endregion
public string CROName { get; set; } = string.Empty;
public string CRONameCN { get; set; } = string.Empty;
public string CROCode { get; set; } = string.Empty;
#endregion
public string CROCode { get; set; } = null!;
public bool IsTrialLevel { get; set; }
[StringLength(1000)]
public string CROName { get; set; } = null!;
[StringLength(1000)]
public string CRONameCN { get; set; } = null!;
public Guid? TrialId { get; set; }
}
[Comment(" 是否是项目级别")]
public bool IsTrialLevel { get; set; }
public Guid? TrialId { get; set; }
}

View File

@ -1,29 +1,36 @@
using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Domain.Share;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Text;
namespace IRaCIS.Core.Domain.Models
namespace IRaCIS.Core.Domain.Models;
[Comment("一致性核查 - 对话记录表")]
[Table("CheckChallengeDialog")]
public class CheckChallengeDialog : BaseAddAuditEntity
{
public class CheckChallengeDialog : BaseAddAuditEntity
{
#region 导航属性
[JsonIgnore]
public SubjectVisit SubjectVisit { get; set; }
#endregion
#region 导航属性
[JsonIgnore]
public SubjectVisit SubjectVisit { get; set; }
#endregion
public string TalkContent { get; set; } = string.Empty;
public Guid SubjectVisitId { get; set; }
[Comment(" CRC是否需要回复 前端使用")]
public bool? IsCRCNeedReply { get; set; }
[Comment(" 核查的检查信息Json")]
[MaxLength]
public string ParamInfo { get; set; } = null!;
public UserTypeEnum UserTypeEnum { get; set; }
public Guid SubjectVisitId { get; set; }
public bool? IsCRCNeedReply { get; set; }
[MaxLength]
public string TalkContent { get; set; } = null!;
[Comment(" 核查过程中的操作用户类型")]
public UserTypeEnum UserTypeEnum { get; set; }
public string ParamInfo { get; set; } = string.Empty;
}
}

View File

@ -12,7 +12,7 @@ namespace IRaCIS.Core.Domain.Models
///PreviousHistory
///</summary>
[Table("PreviousHistory")]
public class PreviousHistory : BaseAddAuditEntityWithUserName
public class PreviousHistory : BaseAddAuditEntity
{
#region 导航属性
[JsonIgnore]

View File

@ -12,7 +12,7 @@ namespace IRaCIS.Core.Domain.Models
///PreviousOther
///</summary>
[Table("PreviousOther")]
public class PreviousOther : BaseAddAuditEntityWithUserName
public class PreviousOther : BaseAddAuditEntity
{
#region 导航属性

View File

@ -12,7 +12,7 @@ namespace IRaCIS.Core.Domain.Models
///PreviousSurgery
///</summary>
[Table("PreviousSurgery")]
public class PreviousSurgery : BaseAddAuditEntityWithUserName
public class PreviousSurgery : BaseAddAuditEntity
{
#region 导航属性

View File

@ -1,91 +1,54 @@
using IRaCIS.Core.Domain.Share;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
namespace IRaCIS.Core.Domain.Models
namespace IRaCIS.Core.Domain.Models;
[Comment("系统 - 临床数据配置")]
[Table("ClinicalDataSystemSet")]
public class ClinicalDataSystemSet : BaseAddAuditEntity
{
///<summary>
/// 临床资料系统配置
///</summary>
[Table("ClinicalDataSystemSet")]
public class ClinicalDataSystemSet : BaseAddAuditEntity
{
#region 导航属性
#region 导航属性
#endregion
[NotMapped]
public List<int> CriterionEnumList => CriterionEnumListStr.Split('|', StringSplitOptions.RemoveEmptyEntries).Where(t => !string.IsNullOrEmpty(t) && int.TryParse(t.Trim(), out var s)).Select(t => int.Parse(t.Trim())).ToList();
/// <summary>
/// 枚举(字典里面取的)
/// </summary>
public int ClinicalDataSetEnum { get; set; }
#endregion
/// <summary>
/// 名称
/// </summary>
public string ClinicalDataSetName { get; set; } = string.Empty;
public ClinicalLevel ClinicalDataLevel { get; set; }
/// <summary>
/// 是否应用
/// </summary>
public bool IsApply { get; set; } = false;
[StringLength(400)]
public string ClinicalDataSetEnName { get; set; } = null!;
/// <summary>
/// 英文名称
/// </summary>
public string ClinicalDataSetEnName { get; set; } = string.Empty;
[Comment(" 枚举(字典里面取的)")]
public int ClinicalDataSetEnum { get; set; }
/// <summary>
/// 临床级别
/// </summary>
public ClinicalLevel ClinicalDataLevel { get; set; }
public string ClinicalDataSetName { get; set; } = null!;
/// <summary>
/// 上传方式
/// </summary>
public ClinicalUploadType ClinicalUploadType { get; set; }
/// <summary>
/// 是否启用
/// </summary>
public bool IsEnable { get; set; }
/// <summary>
/// 上传角色
/// </summary>
public UploadRole UploadRole { get; set; }
/// <summary>
/// 模板文件名称
/// </summary>
public string FileName { get; set; } = string.Empty;
/// <summary>
/// 文件路径
/// </summary>
public string Path { get; set; } = string.Empty;
public string CriterionEnumListStr { get; set; } = String.Empty;
[NotMapped]
public List<int> CriterionEnumList => CriterionEnumListStr.Split('|', StringSplitOptions.RemoveEmptyEntries).Where(t => !string.IsNullOrEmpty(t) && int.TryParse(t.Trim(), out var s)).Select(t => int.Parse(t.Trim())).ToList();
//public List<SystemClinicalDataCriterion> SystemClinicalDataCriterionList { get; set; } = new List<SystemClinicalDataCriterion>();
}
[Comment("上传方式")]
public ClinicalUploadType ClinicalUploadType { get; set; }
[StringLength(512)]
public string CriterionEnumListStr { get; set; } = null!;
[StringLength(400)]
public string FileName { get; set; } = null!;
[Comment("是否应用")]
public bool IsApply { get; set; }
public bool IsEnable { get; set; }
[StringLength(4000)]
public string Path { get; set; } = null!;
public UploadRole UploadRole { get; set; }
}

View File

@ -6,105 +6,65 @@ using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Collections.Generic;
using System.Linq;
using Microsoft.EntityFrameworkCore;
namespace IRaCIS.Core.Domain.Models
namespace IRaCIS.Core.Domain.Models;
[Comment("项目 - 临床数据适应标准配置")]
[Table("ClinicalDataTrialSet")]
public class ClinicalDataTrialSet : BaseAddAuditEntity
{
///<summary>
/// 临床资料项目配置
///</summary>
[Table("ClinicalDataTrialSet")]
public class ClinicalDataTrialSet : BaseAddAuditEntity
{
#region 导航属性
#region 导航属性
[JsonIgnore]
public List<ReadingClinicalData> ReadingClinicalDataList { get; set; }
[JsonIgnore]
public List<ReadingClinicalData> ReadingClinicalDataList { get; set; }
[JsonIgnore]
[ForeignKey("TrialId")]
public Trial Trial { get; set; }
[JsonIgnore]
[ForeignKey("TrialId")]
public Trial Trial { get; set; }
[JsonIgnore]
public List<TrialClinicalDataSetCriterion> TrialClinicalDataSetCriteriaList { get; set; }
[JsonIgnore]
public List<TrialClinicalDataSetCriterion> TrialClinicalDataSetCriteriaList { get; set; }
[JsonIgnore]
public List<TrialClinicalQuestion> TrialClinicalQuestionList { get; set; }
[JsonIgnore]
[ForeignKey("SystemClinicalDataSetId")]
public ClinicalDataSystemSet? ClinicalDataSystemSet { get; set; }
#endregion
[JsonIgnore]
public List<TrialClinicalQuestion> TrialClinicalQuestionList { get; set; }
[JsonIgnore]
[ForeignKey("SystemClinicalDataSetId")]
public ClinicalDataSystemSet? ClinicalDataSystemSet { get; set; }
#endregion
public Guid TrialId { get; set; }
[Comment("临床级别")]
public ClinicalLevel ClinicalDataLevel { get; set; }
/// <summary>
/// 名称
/// </summary>
public string ClinicalDataSetName { get; set; }=string.Empty;
[StringLength(400)]
public string ClinicalDataSetEnName { get; set; } = null!;
/// <summary>
/// 英文名称
/// </summary>
public string ClinicalDataSetEnName { get; set; } = string.Empty;
public string ClinicalDataSetName { get; set; } = null!;
/// <summary>
/// 临床级别
/// </summary>
public ClinicalLevel ClinicalDataLevel { get; set; }
[Comment("上传方式")]
public ClinicalUploadType ClinicalUploadType { get; set; }
[StringLength(512)]
public string CriterionEnumListStr { get; set; } = null!;
/// <summary>
/// 上传方式
/// </summary>
public ClinicalUploadType ClinicalUploadType { get; set; }
[StringLength(400)]
public string FileName { get; set; } = null!;
[Comment("是否应用")]
public bool IsApply { get; set; }
/// <summary>
/// 系统的ClinicalDataSetId
/// </summary>
public Guid? SystemClinicalDataSetId { get; set; }
/// <summary>
/// SystemClinicalDataSetId
/// </summary>
/// <summary>
/// 是否确认
/// </summary>
public bool IsConfirm { get; set; }
/// <summary>
/// 是否应用
/// </summary>
public bool IsApply { get; set; } = false;
/// <summary>
/// 上传角色
/// </summary>
public UploadRole UploadRole { get; set; }
/// <summary>
/// 模板文件名称
/// </summary>
public string FileName { get; set; } = string.Empty;
/// <summary>
/// 文件路径
/// </summary>
public string Path { get; set; } = string.Empty;
public string CriterionEnumListStr { get; set; } = String.Empty;
public List<int> CriterionEnumList => CriterionEnumListStr.Split('|', StringSplitOptions.RemoveEmptyEntries).Where(t => !string.IsNullOrEmpty(t) && int.TryParse(t.Trim(), out var s)).Select(t => int.Parse(t.Trim())).ToList();
}
public bool IsConfirm { get; set; }
[StringLength(4000)]
public string Path { get; set; } = null!;
public Guid? SystemClinicalDataSetId { get; set; }
public Guid TrialId { get; set; }
public UploadRole UploadRole { get; set; }
public List<int> CriterionEnumList => CriterionEnumListStr.Split('|', StringSplitOptions.RemoveEmptyEntries).Where(t => !string.IsNullOrEmpty(t) && int.TryParse(t.Trim(), out var s)).Select(t => int.Parse(t.Trim())).ToList();
}

View File

@ -7,37 +7,31 @@ using System;
using IRaCIS.Core.Domain.Share;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace IRaCIS.Core.Domain.Models
using Microsoft.EntityFrameworkCore;
namespace IRaCIS.Core.Domain.Models;
[Comment("受试者 - 临床表单表格问题行记录")]
[Table("ClinicalAnswerRowInfo")]
public class ClinicalAnswerRowInfo : BaseAddAuditEntity
{
///<summary>
///ClinicalAnswerRowInfo
///</summary>
[Table("ClinicalAnswerRowInfo")]
public class ClinicalAnswerRowInfo : BaseAddAuditEntity
{
#region 导航属性
#region 导航属性
#endregion
[Comment(" 表单Id")]
public Guid ClinicalFormId { get; set; }
[Comment(" 问题Id")]
public Guid QuestionId { get; set; }
public int RowIndex { get; set; }
[Comment(" 受试者Id")]
public Guid SubjectId { get; set; }
}
#endregion
public Guid SubjectId { get; set; }
/// <summary>
/// 表单Id
/// </summary>
public Guid ClinicalFormId { get; set; }
/// <summary>
/// 问题Id
/// </summary>
public Guid QuestionId { get; set; }
/// <summary>
/// RowIndex
/// </summary>
public int RowIndex { get; set; }
}
}

View File

@ -7,50 +7,42 @@ using System;
using IRaCIS.Core.Domain.Share;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace IRaCIS.Core.Domain.Models
using Microsoft.EntityFrameworkCore;
namespace IRaCIS.Core.Domain.Models;
[Comment("受试者 - 临床表单")]
[Table("ClinicalForm")]
public class ClinicalForm : BaseAddAuditEntity
{
///<summary>
///ClinicalForm
///</summary>
[Table("ClinicalForm")]
public class ClinicalForm : BaseAddAuditEntity
{
#region 导航属性
[JsonIgnore]
[ForeignKey("ClinicalDataTrialSetId")]
public ClinicalDataTrialSet ClinicalDataTrialSet { get; set; }
#region 导航属性
[JsonIgnore]
[ForeignKey("ClinicalDataTrialSetId")]
public ClinicalDataTrialSet ClinicalDataTrialSet { get; set; }
[JsonIgnore]
[ForeignKey("SubjectId")]
public Subject Subject { get; set; }
#endregion
[JsonIgnore]
[ForeignKey("SubjectId")]
public Subject Subject { get; set; }
#endregion
public Guid SubjectId { get; set; }
[Comment(" 检查日期")]
public DateTime? CheckDate { get; set; }
public Guid ClinicalDataTrialSetId { get; set; }
[Comment(" 截图地址")]
[StringLength(4000)]
public string PicturePath { get; set; } = null!;
public Guid? ReadingId { get; set; }
[Comment(" 受试者Id")]
public Guid SubjectId { get; set; }
public Guid TrialId { get; set; }
public Guid? VisitId { get; set; }
}
public Guid TrialId { get; set; }
/// <summary>
/// 检查日期
/// </summary>
public DateTime? CheckDate { get; set; }
/// <summary>
/// 截图地址
/// </summary>
public string PicturePath { get; set; } = string.Empty;
public Guid ClinicalDataTrialSetId { get; set; }
/// <summary>
/// VisitId
/// </summary>
public Guid? ReadingId { get; set; }
}
}

View File

@ -7,42 +7,36 @@ using System;
using IRaCIS.Core.Domain.Share;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace IRaCIS.Core.Domain.Models
using Microsoft.EntityFrameworkCore;
namespace IRaCIS.Core.Domain.Models;
[Comment("受试者 - 临床表单问题答案")]
[Table("ClinicalQuestionAnswer")]
public class ClinicalQuestionAnswer : BaseAddAuditEntity
{
///<summary>
///ClinicalQuestionAnswer
///</summary>
[Table("ClinicalQuestionAnswer")]
public class ClinicalQuestionAnswer : BaseAddAuditEntity
{
#region 导航属性
#region 导航属性
[JsonIgnore]
[ForeignKey("ClinicalFormId")]
public ClinicalForm ClinicalForm { get; set; }
#endregion
[JsonIgnore]
[ForeignKey("ClinicalFormId")]
public ClinicalForm ClinicalForm { get; set; }
#endregion
public Guid SubjectId { get; set; }
/// <summary>
/// 表单Id
/// </summary>
public Guid ClinicalFormId { get; set; }
[StringLength(4000)]
public string Answer { get; set; } = null!;
/// <summary>
/// 问题Id
/// </summary>
public Guid QuestionId { get; set; }
public Guid ClinicalDataTrialSetId { get; set; }
public string Answer { get; set; } = string.Empty;
[Comment(" 表单Id")]
public Guid ClinicalFormId { get; set; }
public Guid ClinicalDataTrialSetId { get; set; }
[Comment(" 问题Id")]
public Guid QuestionId { get; set; }
[Comment(" 受试者Id")]
public Guid SubjectId { get; set; }
}
}
}

Some files were not shown because too many files have changed in this diff Show More