From 829760d5191dec57dbbc1c8d5168121a1216f191 Mon Sep 17 00:00:00 2001 From: dx <1242347652@qq.com> Date: Mon, 12 May 2025 10:33:57 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8C=BB=E4=BF=9D=E5=85=A5=E5=8F=A3=E6=96=B9?= =?UTF-8?q?=E6=B3=95=E6=B5=8B=E8=AF=95=E7=89=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- NugetTest/rezero.db | Bin 0 -> 356352 bytes ReZero.sln | 6 + YbTest/Models/Insurance/InsuranceRequest.cs | 110 +++++++++ YbTest/Models/Insurance/InsuranceResponse.cs | 24 ++ YbTest/Models/MedicalTransactionSystem.cs | 155 +++++++++++++ YbTest/Program.cs | 26 +++ YbTest/Properties/launchSettings.json | 38 ++++ .../IInsuranceBusinessService.cs | 17 ++ YbTest/Services/MedicalInsuranceService.cs | 210 ++++++++++++++++++ YbTest/YbTest.csproj | 14 ++ YbTest/appsettings.Development.json | 9 + YbTest/appsettings.json | 9 + 12 files changed, 618 insertions(+) create mode 100644 NugetTest/rezero.db create mode 100644 YbTest/Models/Insurance/InsuranceRequest.cs create mode 100644 YbTest/Models/Insurance/InsuranceResponse.cs create mode 100644 YbTest/Models/MedicalTransactionSystem.cs create mode 100644 YbTest/Program.cs create mode 100644 YbTest/Properties/launchSettings.json create mode 100644 YbTest/Services/InsuranceBusinessServices/IInsuranceBusinessService.cs create mode 100644 YbTest/Services/MedicalInsuranceService.cs create mode 100644 YbTest/YbTest.csproj create mode 100644 YbTest/appsettings.Development.json create mode 100644 YbTest/appsettings.json diff --git a/NugetTest/rezero.db b/NugetTest/rezero.db new file mode 100644 index 0000000000000000000000000000000000000000..1d14aaaa765b1e37dab858d8e40672dd41282549 GIT binary patch literal 356352 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 O*-WXKJR{=&H~;@RRf|pl literal 0 HcmV?d00001 diff --git a/ReZero.sln b/ReZero.sln index fc9ce5b..30e3226 100644 --- a/ReZero.sln +++ b/ReZero.sln @@ -17,6 +17,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DemoTest", "DemoTest", "{10 EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DependencyInjectionTest", "DependencyInjectionTest\DependencyInjectionTest.csproj", "{E7355DEA-E652-4C6A-960C-CECF4B4EB673}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "YbTest", "YbTest\YbTest.csproj", "{0E79520C-8BBF-4B4E-9BAB-79E4B913162F}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -43,6 +45,10 @@ Global {E7355DEA-E652-4C6A-960C-CECF4B4EB673}.Debug|Any CPU.Build.0 = Debug|Any CPU {E7355DEA-E652-4C6A-960C-CECF4B4EB673}.Release|Any CPU.ActiveCfg = Release|Any CPU {E7355DEA-E652-4C6A-960C-CECF4B4EB673}.Release|Any CPU.Build.0 = Release|Any CPU + {0E79520C-8BBF-4B4E-9BAB-79E4B913162F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0E79520C-8BBF-4B4E-9BAB-79E4B913162F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0E79520C-8BBF-4B4E-9BAB-79E4B913162F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0E79520C-8BBF-4B4E-9BAB-79E4B913162F}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/YbTest/Models/Insurance/InsuranceRequest.cs b/YbTest/Models/Insurance/InsuranceRequest.cs new file mode 100644 index 0000000..6d49f22 --- /dev/null +++ b/YbTest/Models/Insurance/InsuranceRequest.cs @@ -0,0 +1,110 @@ +using System.ComponentModel.DataAnnotations; + +namespace YbTest.Models.Insurance +{ + public class InsuranceRequest + { + /// + /// 交易类型代码 + /// [必填] 固定4位数字,参考医保业务代码表 + /// 示例:1101(人员信息查询) + /// + [Required, StringLength(4)] + public string Infno { get; set; } + + /// + /// 交易流水号 + /// [必填] 30位复合格式:机构编号(12位)+yyyyMMddHHmmss(14位)+4位序列号 + /// 示例:H44123456202308141023001234 + /// + [Required, StringLength(30)] + public string MsgId { get; set; } + + /// + /// 参保地区行政区划代码 + /// [必填] 6位数字,参考最新医保区划代码 + /// 示例:440305(南山区) + /// + [Required, StringLength(6)] + public string MdtrtareaAdmvs { get; set; } + + /// + /// 参保地行政区划代码 + /// [条件必填] 6位数字,异地就医时必填 + /// 示例:440306(宝安区) + /// + [StringLength(6)] + public string InsuplcAdmdvs { get; set; } + + [Required, StringLength(10)] + public string RecerSysCode { get; set; } + + [StringLength(100)] + public string DevNo { get; set; } + + [StringLength(2000)] + public string DevSafeInfo { get; set; } + + [StringLength(1024)] + public string Cainfo { get; set; } + + [StringLength(10)] + public string Signtype { get; set; } + + [Required, StringLength(6)] + public string Infver { get; set; } + + /// + /// 操作员类型 + /// [必填] 1-医保经办人 2-医院工作人员 3-参保人 + /// + [Required] + public int OpterType { get; set; } + + /// + /// 操作员账号 + /// [必填] 30位医保经办人账号(区域编码+工作人员编号) + /// 示例:4403052021000123 + /// + [Required, StringLength(30)] + public string Opter { get; set; } + + /// + /// 操作员姓名 + /// [必填] 50位中文实名,与医保系统登记信息一致 + /// 示例:张三 + /// + [Required, StringLength(50)] + public string OpterName { get; set; } + + /// + /// 交易时间 + /// [必填] ISO 8601格式:yyyy-MM-ddTHH:mm:ss + /// 示例:2023-08-14T15:30:00 + /// + [Required] + public DateTime InfTime { get; set; } + + /// + /// 定点医疗机构编号 + /// [必填] 12位医保标准编码 + /// 示例:H441234567890 + /// + [Required, StringLength(12)] + public string FixmedinsCode { get; set; } + + /// + /// 定点医疗机构名称 + /// [必填] 20位中文标准名称 + /// 示例:深圳市人民医院 + /// + [Required, StringLength(20)] + public string FixmedinsName { get; set; } + + [StringLength(30)] + public string SignNo { get; set; } + + [Required, StringLength(40000)] + public string Input { get; set; } + } +} \ No newline at end of file diff --git a/YbTest/Models/Insurance/InsuranceResponse.cs b/YbTest/Models/Insurance/InsuranceResponse.cs new file mode 100644 index 0000000..4121f15 --- /dev/null +++ b/YbTest/Models/Insurance/InsuranceResponse.cs @@ -0,0 +1,24 @@ +using System; + +namespace YbTest.Models.Insurance +{ + public class Response + { + public ResponseHeader Header { get; set; } + public string Body { get; set; } + public string Signature { get; set; } + } + + public class ResponseHeader + { + public string Version { get; set; } + public string SenderCode { get; set; } + public string ReceiverCode { get; set; } + public string MsgId { get; set; } + public string InfTime { get; set; } + public string ResultCode { get; set; } + public string ResultMsg { get; set; } + public string SignatureAlgorithm { get; set; } + public string EncryptionAlgorithm { get; set; } + } +} \ No newline at end of file diff --git a/YbTest/Models/MedicalTransactionSystem.cs b/YbTest/Models/MedicalTransactionSystem.cs new file mode 100644 index 0000000..cf15b23 --- /dev/null +++ b/YbTest/Models/MedicalTransactionSystem.cs @@ -0,0 +1,155 @@ +using System.ComponentModel.DataAnnotations.Schema; +using System.ComponentModel.DataAnnotations; + +namespace YbTest.Models +{ + public class MedicalTransactionSystem + { + + /// + /// 医保交易业务对象(入参) + /// + public class MedicalTransaction + { + /// + /// 交易编号(详见接口列表) + /// + [Required] + [StringLength(4)] + public string Infno { get; set; } + + /// + /// 发送方报文ID(主键) + /// 格式:定点医药机构编号(12)+时间(14)+顺序号(4) + /// + [Key] + [StringLength(30)] + [RegularExpression(@"^\d{12}\d{14}\d{4}$", ErrorMessage = "报文ID格式无效")] + public string MsgId { get; set; } + + /// + /// 就医地医保区划 + /// + [Required] + [StringLength(6)] + public string MdtrtareaAdmvs { get; set; } + + /// + /// 参保地医保区划(人员编号存在时必填) + /// + [StringLength(6)] + public string InsuplcAdmdvs { get; set; } + + /// + /// 接收方系统代码 + /// + [Required] + [StringLength(10)] + public string RecerSysCode { get; set; } + + /// + /// 设备编号 + /// + [StringLength(100)] + public string DevNo { get; set; } + + /// + /// 设备安全信息(JSON/XML格式) + /// + [Column(TypeName = "text")] + public string DevSafeInfo { get; set; } + + /// + /// 数字签名信息(安全管理码) + /// + [Column(TypeName = "text")] + public string Cainfo { get; set; } + + /// + /// 签名类型 + /// + [StringLength(10)] + public SignType Signtype { get; set; } + + /// + /// 接口版本号 + /// + [Required] + [StringLength(6)] + public string Infver { get; set; } + + /// + /// 经办人类别 + /// + [Required] + public OperatorType OpterType { get; set; } + + /// + /// 经办人/终端编号 + /// + [Required] + [StringLength(30)] + public string Opter { get; set; } + + /// + /// 经办人姓名/终端名称 + /// + [Required] + [StringLength(50)] + public string OpterName { get; set; } + + /// + /// 交易时间 + /// + [Required] + public DateTime InfTime { get; set; } + + /// + /// 定点医药机构编号 + /// + [Required] + [StringLength(12)] + public string FixmedinsCode { get; set; } + + /// + /// 定点医药机构名称 + /// + [Required] + [StringLength(20)] + public string FixmedinsName { get; set; } + + /// + /// 交易签到流水号(来自9001交易) + /// + [StringLength(30)] + public string SignNo { get; set; } + + /// + /// 交易输入(.NET对象序列化) + /// + [Required] + [Column(TypeName = "text")] + public string Input { get; set; } + } + + /// + /// 签名类型枚举 + /// + public enum SignType + { + SM2, + SM3 + } + + /// + /// 经办人类别枚举 + /// + public enum OperatorType + { + 经办人 = 1, + 自助终端 = 2, + 移动终端 = 3 + } + + } +} diff --git a/YbTest/Program.cs b/YbTest/Program.cs new file mode 100644 index 0000000..017b164 --- /dev/null +++ b/YbTest/Program.cs @@ -0,0 +1,26 @@ + +var builder = WebApplication.CreateBuilder(args); + +// Add services to the container. +builder.Services.AddRazorPages(); + +var app = builder.Build(); + +// Configure the HTTP request pipeline. +if (!app.Environment.IsDevelopment()) +{ + app.UseExceptionHandler("/Error"); + // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. + app.UseHsts(); +} + +app.UseHttpsRedirection(); +app.UseStaticFiles(); + +app.UseRouting(); + +app.UseAuthorization(); + +app.MapRazorPages(); + +app.Run(); diff --git a/YbTest/Properties/launchSettings.json b/YbTest/Properties/launchSettings.json new file mode 100644 index 0000000..2c9ea18 --- /dev/null +++ b/YbTest/Properties/launchSettings.json @@ -0,0 +1,38 @@ +{ + "$schema": "http://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:22272", + "sslPort": 44362 + } + }, + "profiles": { + "http": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "applicationUrl": "http://localhost:5283", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "applicationUrl": "https://localhost:7083;http://localhost:5283", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/YbTest/Services/InsuranceBusinessServices/IInsuranceBusinessService.cs b/YbTest/Services/InsuranceBusinessServices/IInsuranceBusinessService.cs new file mode 100644 index 0000000..900965a --- /dev/null +++ b/YbTest/Services/InsuranceBusinessServices/IInsuranceBusinessService.cs @@ -0,0 +1,17 @@ +using YbTest.Models.Insurance; + + +namespace YbTest.Services.InsuranceBusinessServices; + +public interface IInsuranceBusinessService +{ + /// + /// 执行医保业务请求 + /// + Response Execute(InsuranceRequest request); + + /// + /// 业务校验方法 + /// + void ValidateBusinessRule(InsuranceRequest request); +} \ No newline at end of file diff --git a/YbTest/Services/MedicalInsuranceService.cs b/YbTest/Services/MedicalInsuranceService.cs new file mode 100644 index 0000000..5114015 --- /dev/null +++ b/YbTest/Services/MedicalInsuranceService.cs @@ -0,0 +1,210 @@ +using System.Text; +using System.Text.RegularExpressions; +using System.ComponentModel.DataAnnotations; +using YbTest.Models.Insurance; +using YbTest.Services.InsuranceBusinessServices; +using System.Collections.Concurrent; +using System.Security.Cryptography; +using System.Text.Json; + +namespace YbTest.Services +{ + public class MedicalInsuranceService + { + private readonly ConcurrentDictionary _serviceCache = new(); + + public void ValidateRequest(InsuranceRequest request) + { + if (string.IsNullOrEmpty(request.MsgId)) + throw new ValidationException("报文ID不能为空"); + + if (string.IsNullOrEmpty(request.MdtrtareaAdmvs)) + throw new ValidationException("就医地医保区划不能为空"); + + if (string.IsNullOrEmpty(request.RecerSysCode)) + throw new ValidationException("接收方系统代码不能为空"); + + if (string.IsNullOrEmpty(request.Infver)) + throw new ValidationException("接口版本号不能为空"); + if (string.IsNullOrEmpty(request.OpterType.ToString())) + throw new ValidationException("经办人类别不能为空"); + if (string.IsNullOrEmpty(request.Opter)) + throw new ValidationException("经办人不能为空"); + + if (string.IsNullOrEmpty(request.OpterName)) + throw new ValidationException("经办人姓名不能为空"); + + // 假设 request.InfTime 现在是 DateTime 类型,将其转换为字符串进行判断 + if (string.IsNullOrEmpty(request.InfTime.ToString("yyyyMMddHHmmss"))) + throw new ValidationException("交易时间不能为空"); + if (string.IsNullOrEmpty(request.FixmedinsCode)) + throw new ValidationException("定点医药机构编号不能为空"); + + if (string.IsNullOrEmpty(request.FixmedinsName)) + throw new ValidationException("定点医药机构名称不能为空"); + } + + public IInsuranceBusinessService GetServiceByInfoNo(string infoNo) + { + return _serviceCache.GetOrAdd(infoNo, key => key switch + { + // "1101" => new PersonInfoService(), + // "2101" => new RegistrationService(), + // "2201" => new PreSettlementService(), + // _ => throw new BusinessException($"未知的交易编号: {key}") + }); + } + + //入口方法 + public Response ProcessRequest(InsuranceRequest request) + { + ValidateRequest(request); + ValidateParameterFormat(request); + VerifySignature(request); + + var service = GetServiceByInfoNo(request.Infno); + var result = service.Execute(request); + + return new Response + { + Header = GenerateResponseHeader(request), + Body = EncryptData(result), + Signature = GenerateSignature(result) + }; + } + + // 新增参数格式验证 + public static void ValidateParameterFormat(InsuranceRequest request) + { + // 增强msgid格式校验 + if (!Regex.IsMatch(request.MsgId, @"^\d{12}\d{14}\d{4}$")) + throw new ValidationException("报文ID格式必须为12位机构编号+14位时间+4位流水号"); + + // 条件必填验证 + if (!string.IsNullOrEmpty(request.Input) && string.IsNullOrEmpty(request.InsuplcAdmdvs)) + throw new ValidationException("当交易输入包含人员编号时,参保地医保区划为必填项"); + + // 版本号格式校验 + if (!Regex.IsMatch(request.Infver, @"^V\d+\.\d+$")) + throw new ValidationException("接口版本号格式应为VX.X"); + + // 签名类型校验 + if (!string.IsNullOrEmpty(request.Signtype) && !new[] { "SM2", "SM3" }.Contains(request.Signtype)) + throw new ValidationException("签名类型只支持SM2/SM3"); + + // 由于 request.InfTime 是 DateTime 类型,先将其转换为指定格式的字符串再进行正则匹配 + if (!Regex.IsMatch(request.InfTime.ToString("yyyyMMddHHmmss"), @"^\d{14}$")) + throw new ValidationException("交易时间格式必须为yyyyMMddHHmmss"); + + if (request.OpterName?.Length > 50) + throw new ValidationException("经办人姓名不能超过50个字符"); + } + + // 增强版响应头生成 + public static ResponseHeader GenerateResponseHeader(InsuranceRequest request) + { + return new ResponseHeader + { + Version = "1.0", + // 由于 _config 不存在,这里假设添加一个默认值,实际使用时需要根据业务逻辑修改 + SenderCode = "DefaultInstitutionCode", + ReceiverCode = request.FixmedinsCode, + MsgId = Guid.NewGuid().ToString("N").ToUpper(), + InfTime = DateTime.Now.ToString("yyyyMMddHHmmss"), + ResultCode = "1000", + ResultMsg = "处理成功", + SignatureAlgorithm = "HMAC-SHA256", + EncryptionAlgorithm = "AES-256-GCM" + }; + } + + // 完整签名验证流程 + public static void VerifySignature(InsuranceRequest request) + { + var rawData = $"{request.MsgId}{request.InfTime}{request.FixmedinsCode}"; + + + var hmac = new HMACSHA256(Encoding.UTF8.GetBytes("DefaultSignKey")); + var computedSignature = hmac.ComputeHash(Encoding.UTF8.GetBytes(rawData)); + + // 由于 InsuranceRequest 未包含 Signature 的定义,这里假设添加一个默认空字符串处理 + if (!computedSignature.SequenceEqual(Convert.FromBase64String(""))) + // 由于 SecurityException 可能未找到,使用更通用的 InvalidOperationException 替代 + throw new InvalidOperationException("数字签名验证失败"); + } + + // 医保系统通信模块 + public async Task CallInsuranceSystem(string endpoint, object payload) + { + // 由于 _httpClientFactory 不存在,使用新创建的 HttpClient 实例替代 + using var client = new HttpClient(); + // 由于 _config 不存在,暂时使用一个默认的 API Key,实际使用时需根据业务逻辑修改 + client.DefaultRequestHeaders.Add("X-Medicare-API-Key", "DefaultApiKey"); + + var content = new StringContent( + // 引入 System.Text.Json 命名空间以使用 JsonSerializer + + System.Text.Json.JsonSerializer.Serialize(payload), + Encoding.UTF8, + "application/json"); + + var response = await client.PostAsync(endpoint, content); + response.EnsureSuccessStatusCode(); + + return await response.Content.ReadFromJsonAsync(); + } + + public static string EncryptData(object data) + { + var json = JsonSerializer.Serialize(data); + // 由于 AesUtility 不存在,使用 .NET 内置的 AES 加密实现 + + + // 定义一个临时的 AES 加密方法 + static string EncryptWithAes(string plainText, string key) + { + byte[] encrypted; + using var aesAlg = Aes.Create(); + { + aesAlg.Key = Encoding.UTF8.GetBytes(key); + aesAlg.GenerateIV(); + + ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV); + + using (MemoryStream msEncrypt = new MemoryStream()) + { + using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write)) + { + using (StreamWriter swEncrypt = new StreamWriter(csEncrypt)) + { + swEncrypt.Write(plainText); + } + encrypted = msEncrypt.ToArray(); + } + } + + // 将 IV 和加密后的数据拼接,以方便后续解密 + byte[] combinedIvCt = new byte[aesAlg.IV.Length + encrypted.Length]; + Array.Copy(aesAlg.IV, 0, combinedIvCt, 0, aesAlg.IV.Length); + Array.Copy(encrypted, 0, combinedIvCt, aesAlg.IV.Length, encrypted.Length); + + return Convert.ToBase64String(combinedIvCt); + } + } + + // 由于 _config 不存在,使用一个默认的加密密钥替代,实际使用时需根据业务逻辑修改 + return EncryptWithAes(json, "DefaultEncryptionKey"); + } + + public static string GenerateSignature(object data) + { + var json = JsonSerializer.Serialize(data); + // 由于 HMACSHA256.HashData 没有单参数重载,需要创建 HMACSHA256 实例来计算哈希值 + using var hmac = new HMACSHA256(); + { + byte[] hashBytes = hmac.ComputeHash(Encoding.UTF8.GetBytes(json)); + return Convert.ToBase64String(hashBytes); + } + } + } +} diff --git a/YbTest/YbTest.csproj b/YbTest/YbTest.csproj new file mode 100644 index 0000000..075d1bc --- /dev/null +++ b/YbTest/YbTest.csproj @@ -0,0 +1,14 @@ + + + + net8.0 + enable + enable + + + + + + + + diff --git a/YbTest/appsettings.Development.json b/YbTest/appsettings.Development.json new file mode 100644 index 0000000..770d3e9 --- /dev/null +++ b/YbTest/appsettings.Development.json @@ -0,0 +1,9 @@ +{ + "DetailedErrors": true, + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/YbTest/appsettings.json b/YbTest/appsettings.json new file mode 100644 index 0000000..10f68b8 --- /dev/null +++ b/YbTest/appsettings.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*" +}