commit
16294ca927
22 changed files with 1814 additions and 0 deletions
@ -0,0 +1,54 @@ |
|||||||
|
# 编译输出目录 |
||||||
|
[Dd]ebug/ |
||||||
|
[Rr]elease/ |
||||||
|
bin/ |
||||||
|
obj/ |
||||||
|
|
||||||
|
# .NET 生成文件 |
||||||
|
*.cs.user |
||||||
|
*.csproj.user |
||||||
|
*.suo |
||||||
|
*.user |
||||||
|
*.userosscache |
||||||
|
*.sln.docstates |
||||||
|
|
||||||
|
# Visual Studio |
||||||
|
.vs/ |
||||||
|
*.swp |
||||||
|
*.vspx |
||||||
|
*.vspscc |
||||||
|
*.vssscc |
||||||
|
_ReSharper*/ |
||||||
|
*.ReSharper* |
||||||
|
|
||||||
|
# Rider / JetBrains |
||||||
|
.idea/ |
||||||
|
*.iml |
||||||
|
*.iws |
||||||
|
*.xml |
||||||
|
|
||||||
|
# VS Code |
||||||
|
.vscode/ |
||||||
|
*.code-workspace |
||||||
|
|
||||||
|
# 日志 |
||||||
|
logs/ |
||||||
|
*.log |
||||||
|
|
||||||
|
# 临时文件 |
||||||
|
*.tmp |
||||||
|
*.temp |
||||||
|
|
||||||
|
# 操作系统文件 |
||||||
|
.DS_Store |
||||||
|
Thumbs.db |
||||||
|
|
||||||
|
# dotnet tools 本地安装 |
||||||
|
.dotnet/ |
||||||
|
|
||||||
|
# NuGet |
||||||
|
*.nupkg |
||||||
|
.nuget/ |
||||||
|
|
||||||
|
# 测试覆盖率 |
||||||
|
coverage/ |
||||||
@ -0,0 +1,23 @@ |
|||||||
|
<Project Sdk="Microsoft.NET.Sdk.Web"> |
||||||
|
|
||||||
|
<PropertyGroup> |
||||||
|
<TargetFramework>netcoreapp3.1</TargetFramework> |
||||||
|
<RootNamespace>CA_Platform_Linker</RootNamespace> |
||||||
|
</PropertyGroup> |
||||||
|
|
||||||
|
<ItemGroup> |
||||||
|
<PackageReference Include="Microsoft.Data.SqlClient" Version="5.1.5" /> |
||||||
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" /> |
||||||
|
<PackageReference Include="NLog" Version="4.7.15" /> |
||||||
|
<PackageReference Include="NLog.Web.AspNetCore" Version="4.9.3" /> |
||||||
|
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" /> |
||||||
|
</ItemGroup> |
||||||
|
|
||||||
|
<ItemGroup> |
||||||
|
<Content Update="nlog.config"> |
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory> |
||||||
|
</Content> |
||||||
|
</ItemGroup> |
||||||
|
|
||||||
|
|
||||||
|
</Project> |
||||||
@ -0,0 +1,230 @@ |
|||||||
|
using CA_Platform_Linker.Models.Coss; |
||||||
|
using CA_Platform_Linker.Models.DTO; |
||||||
|
using CA_Platform_Linker.Services.Interfaces; |
||||||
|
using CA_Platform_Linker.Tools; |
||||||
|
using Microsoft.AspNetCore.Mvc; |
||||||
|
using System; |
||||||
|
using System.Threading.Tasks; |
||||||
|
|
||||||
|
namespace CA_Platform_Linker.Controllers |
||||||
|
{ |
||||||
|
[Route("[controller]/[action]")]
|
||||||
|
[ApiController] |
||||||
|
public class ClientController : ControllerBase |
||||||
|
{ |
||||||
|
private readonly IClientService _clientService; |
||||||
|
|
||||||
|
public ClientController(IClientService clientService) |
||||||
|
{ |
||||||
|
_clientService = clientService; |
||||||
|
} |
||||||
|
|
||||||
|
[HttpPost] |
||||||
|
public async Task<IActionResult> Login([FromQuery] string clientType = "LIS") |
||||||
|
{ |
||||||
|
try |
||||||
|
{ |
||||||
|
|
||||||
|
var result = await _clientService.StartAutoSignAsync(clientType, 3600 * 24); |
||||||
|
LogHelper.Log.Info(result.ToString()); |
||||||
|
if (result.status == "200") |
||||||
|
{ |
||||||
|
return Ok(new ApiLoginResponse |
||||||
|
{ |
||||||
|
Success = true, |
||||||
|
Message = "二维码生成成功,请扫码登录", |
||||||
|
SignDataId = result.data.signDataId, |
||||||
|
QrCode = result.data.qrCode |
||||||
|
}); |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
return BadRequest(new ApiLoginResponse |
||||||
|
{ |
||||||
|
Success = false, |
||||||
|
Message = $"二维码生成失败: {result.message}" |
||||||
|
}); |
||||||
|
} |
||||||
|
} |
||||||
|
catch (Exception ex) |
||||||
|
{ |
||||||
|
LogHelper.Log.Error($"二维码生成失败: {ex.Message}"); |
||||||
|
return BadRequest(new ApiLoginResponse |
||||||
|
{ |
||||||
|
Success = false, |
||||||
|
Message = $"二维码生成失败: {ex.Message}" |
||||||
|
}); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
[HttpPost] |
||||||
|
public async Task<IActionResult> AddSignJob([FromBody] ApiSignRequest request, [FromQuery] string clientType = "LIS") |
||||||
|
{ |
||||||
|
return BadRequest(new ApiSignResponse |
||||||
|
{ |
||||||
|
Success = false, |
||||||
|
Message = "接口已停用,请使用 AutoSign 接口" |
||||||
|
}); |
||||||
|
|
||||||
|
try |
||||||
|
{ |
||||||
|
var result = await _clientService.AddSignJobAsync( |
||||||
|
clientType, |
||||||
|
request.Title, |
||||||
|
request.Data, |
||||||
|
request.UserId, |
||||||
|
request.Algo, |
||||||
|
request.ExpiryDate |
||||||
|
); |
||||||
|
|
||||||
|
if (result.status == "200") |
||||||
|
{ |
||||||
|
return Ok(new ApiSignResponse |
||||||
|
{ |
||||||
|
Success = true, |
||||||
|
Message = "添加签名任务成功", |
||||||
|
SignDataId = result.data.signDataId, |
||||||
|
QrCode = result.data.qrCode |
||||||
|
}); |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
return BadRequest(new ApiSignResponse |
||||||
|
{ |
||||||
|
Success = false, |
||||||
|
Message = $"添加签名任务失败: {result.message}" |
||||||
|
}); |
||||||
|
} |
||||||
|
} |
||||||
|
catch (Exception ex) |
||||||
|
{ |
||||||
|
LogHelper.Log.Error($"添加签名任务失败: {ex.Message}"); |
||||||
|
return BadRequest(new ApiSignResponse |
||||||
|
{ |
||||||
|
Success = false, |
||||||
|
Message = $"添加签名任务失败: {ex.Message}" |
||||||
|
}); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
[HttpPost] |
||||||
|
public async Task<IActionResult> AutoSign([FromBody] ApiAutoSignRequest request, [FromQuery] string clientType = "LIS", [FromQuery] int clientOper = 0) |
||||||
|
{ |
||||||
|
try |
||||||
|
{ |
||||||
|
if (clientOper < 0 || clientOper > 99) |
||||||
|
{ |
||||||
|
return BadRequest(new ApiAutoSignResponse |
||||||
|
{ |
||||||
|
Success = false, |
||||||
|
Message = "clientOper 参数值必须在 0-99 范围内" |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
var result = await _clientService.AutoSignAsync( |
||||||
|
clientType, |
||||||
|
request.UserId, |
||||||
|
request.SignToken, |
||||||
|
request.Data, |
||||||
|
request.Algo, |
||||||
|
request.ExpiryDate, |
||||||
|
request.MZNum, |
||||||
|
request.ZYNum, |
||||||
|
request.SignID, |
||||||
|
clientOper |
||||||
|
); |
||||||
|
|
||||||
|
if (result.status == "200") |
||||||
|
{ |
||||||
|
return Ok(new ApiAutoSignResponse |
||||||
|
{ |
||||||
|
Success = true, |
||||||
|
Message = "自动签名成功", |
||||||
|
SignResult = result.data.signResult, |
||||||
|
SignCert = result.data.signCert, |
||||||
|
SignDataId = result.data.signDataId |
||||||
|
}); |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
LogHelper.Log.Error($"自动签名失败: {result.message}"); |
||||||
|
return BadRequest(new ApiAutoSignResponse |
||||||
|
{ |
||||||
|
Success = false, |
||||||
|
Message = $"自动签名失败: {result.message}" |
||||||
|
}); |
||||||
|
} |
||||||
|
} |
||||||
|
catch (Exception ex) |
||||||
|
{ |
||||||
|
LogHelper.Log.Error($"自动签名失败: {ex.Message}"); |
||||||
|
return BadRequest(new ApiAutoSignResponse |
||||||
|
{ |
||||||
|
Success = false, |
||||||
|
Message = $"自动签名失败: {ex.Message}" |
||||||
|
}); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
[HttpPost] |
||||||
|
public async Task<IActionResult> GetSignResult([FromBody] ApiGetSignResultRequest request, [FromQuery] string clientType = "LIS") |
||||||
|
{ |
||||||
|
try |
||||||
|
{ |
||||||
|
var result = await _clientService.GetSignResultAsync(clientType, request.SignDataId); |
||||||
|
|
||||||
|
if (result.status == "200") |
||||||
|
{ |
||||||
|
string message = "查询中"; |
||||||
|
bool isLoginSuccess = false; |
||||||
|
|
||||||
|
if (result.data.jobStatus == "FINISH") |
||||||
|
{ |
||||||
|
message = "登录成功"; |
||||||
|
isLoginSuccess = true; |
||||||
|
} |
||||||
|
else if (result.data.jobStatus == "PROCESSING") |
||||||
|
{ |
||||||
|
message = "等待扫码"; |
||||||
|
} |
||||||
|
else if (result.data.jobStatus == "FAIL") |
||||||
|
{ |
||||||
|
message = "签名失败"; |
||||||
|
} |
||||||
|
else if (result.data.jobStatus == "TIMEOUT") |
||||||
|
{ |
||||||
|
message = "登录超时"; |
||||||
|
} |
||||||
|
|
||||||
|
return Ok(new ApiGetSignResultResponse |
||||||
|
{ |
||||||
|
Success = true, |
||||||
|
Message = message, |
||||||
|
JobStatus = result.data.jobStatus, |
||||||
|
SignResult = result.data.signResult, |
||||||
|
SignCert = result.data.signCert, |
||||||
|
UserId = result.data.msspId, |
||||||
|
IsLoginSuccess = isLoginSuccess |
||||||
|
}); |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
return BadRequest(new ApiGetSignResultResponse |
||||||
|
{ |
||||||
|
Success = false, |
||||||
|
Message = $"获取签名结果失败: {result.message}" |
||||||
|
}); |
||||||
|
} |
||||||
|
} |
||||||
|
catch (Exception ex) |
||||||
|
{ |
||||||
|
LogHelper.Log.Error($"获取签名结果失败: {ex.Message}"); |
||||||
|
return BadRequest(new ApiGetSignResultResponse |
||||||
|
{ |
||||||
|
Success = false, |
||||||
|
Message = $"获取签名结果失败: {ex.Message}" |
||||||
|
}); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,78 @@ |
|||||||
|
using System; |
||||||
|
using System.Collections.Generic; |
||||||
|
using System.Linq; |
||||||
|
using System.Threading.Tasks; |
||||||
|
|
||||||
|
namespace CA_Platform_Linker.Models.Coss |
||||||
|
{ |
||||||
|
public class CossBaseRequest |
||||||
|
{ |
||||||
|
public string version { get; set; } |
||||||
|
public string appId { get; set; } |
||||||
|
public string signAlgo { get; set; } |
||||||
|
public string signature { get; set; } |
||||||
|
} |
||||||
|
|
||||||
|
public class CossResponse<T> |
||||||
|
{ |
||||||
|
public string status { get; set; } |
||||||
|
public string message { get; set; } |
||||||
|
public T data { get; set; } |
||||||
|
} |
||||||
|
|
||||||
|
public class CossResultData |
||||||
|
{ |
||||||
|
public string signDataId { get; set; } |
||||||
|
public string qrCode { get; set; } |
||||||
|
public string jobStatus { get; set; } |
||||||
|
public string msspId { get; set; } |
||||||
|
public string signCert { get; set; } |
||||||
|
public string signResult { get; set; } |
||||||
|
public string image { get; set; } |
||||||
|
public string tsResp { get; set; } |
||||||
|
} |
||||||
|
|
||||||
|
public class StartAutoSignRequest : CossBaseRequest |
||||||
|
{ |
||||||
|
public string timeRegion { get; set; } |
||||||
|
} |
||||||
|
|
||||||
|
public class AddSignJobRequest : CossBaseRequest |
||||||
|
{ |
||||||
|
public string title { get; set; } |
||||||
|
public string userId { get; set; } |
||||||
|
public string dataType { get; set; } |
||||||
|
public string algo { get; set; } |
||||||
|
public string description { get; set; } |
||||||
|
public string data { get; set; } |
||||||
|
public string expiryDate { get; set; } |
||||||
|
} |
||||||
|
|
||||||
|
public class AutoSignRequest : CossBaseRequest |
||||||
|
{ |
||||||
|
public string userId { get; set; } |
||||||
|
public string title { get; set; } |
||||||
|
public string dataType { get; set; } |
||||||
|
public string algo { get; set; } |
||||||
|
public string description { get; set; } |
||||||
|
public string data { get; set; } |
||||||
|
public string signToken { get; set; } |
||||||
|
public string expiryDate { get; set; } |
||||||
|
} |
||||||
|
|
||||||
|
public class GetSignResultRequest : CossBaseRequest |
||||||
|
{ |
||||||
|
public string signDataId { get; set; } |
||||||
|
} |
||||||
|
|
||||||
|
public class QueryImageRequest : CossBaseRequest |
||||||
|
{ |
||||||
|
public string userId { get; set; } |
||||||
|
} |
||||||
|
|
||||||
|
public class CreateTssRequest : CossBaseRequest |
||||||
|
{ |
||||||
|
public string oriData { get; set; } |
||||||
|
public string attachCert { get; set; } |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,80 @@ |
|||||||
|
using System.ComponentModel.DataAnnotations; |
||||||
|
|
||||||
|
namespace CA_Platform_Linker.Models.DTO |
||||||
|
{ |
||||||
|
public class ApiLoginResponse |
||||||
|
{ |
||||||
|
public bool Success { get; set; } |
||||||
|
public string Message { get; set; } |
||||||
|
public string SignDataId { get; set; } |
||||||
|
public string QrCode { get; set; } |
||||||
|
} |
||||||
|
|
||||||
|
public class ApiSignRequest |
||||||
|
{ |
||||||
|
[Required(ErrorMessage = "标题不能为空")] |
||||||
|
public string Title { get; set; } |
||||||
|
|
||||||
|
[Required(ErrorMessage = "数据不能为空")] |
||||||
|
public string Data { get; set; } |
||||||
|
|
||||||
|
public string UserId { get; set; } |
||||||
|
public string Algo { get; set; } = "SM3withSM2"; |
||||||
|
public string ExpiryDate { get; set; } = "1400"; |
||||||
|
} |
||||||
|
|
||||||
|
public class ApiSignResponse |
||||||
|
{ |
||||||
|
public bool Success { get; set; } |
||||||
|
public string Message { get; set; } |
||||||
|
public string SignDataId { get; set; } |
||||||
|
public string QrCode { get; set; } |
||||||
|
public string SignResult { get; set; } |
||||||
|
public string SignCert { get; set; } |
||||||
|
} |
||||||
|
|
||||||
|
public class ApiAutoSignRequest |
||||||
|
{ |
||||||
|
[Required(ErrorMessage = "用户ID不能为空")] |
||||||
|
public string UserId { get; set; } |
||||||
|
|
||||||
|
[Required(ErrorMessage = "签名令牌不能为空")] |
||||||
|
public string SignToken { get; set; } |
||||||
|
|
||||||
|
[Required(ErrorMessage = "数据不能为空")] |
||||||
|
public string Data { get; set; } |
||||||
|
|
||||||
|
public string Algo { get; set; } = "SM3withSM2"; |
||||||
|
public string ExpiryDate { get; set; } = "1400"; |
||||||
|
|
||||||
|
public int MZNum { get; set; } = 0; |
||||||
|
public int ZYNum { get; set; } = 0; |
||||||
|
public string SignID { get; set; } = string.Empty; |
||||||
|
} |
||||||
|
|
||||||
|
public class ApiAutoSignResponse |
||||||
|
{ |
||||||
|
public bool Success { get; set; } |
||||||
|
public string Message { get; set; } |
||||||
|
public string SignResult { get; set; } |
||||||
|
public string SignCert { get; set; } |
||||||
|
public string SignDataId { get; set; } |
||||||
|
} |
||||||
|
|
||||||
|
public class ApiGetSignResultRequest |
||||||
|
{ |
||||||
|
[Required(ErrorMessage = "签名数据ID不能为空")] |
||||||
|
public string SignDataId { get; set; } |
||||||
|
} |
||||||
|
|
||||||
|
public class ApiGetSignResultResponse |
||||||
|
{ |
||||||
|
public bool Success { get; set; } |
||||||
|
public string Message { get; set; } |
||||||
|
public string JobStatus { get; set; } |
||||||
|
public string SignResult { get; set; } |
||||||
|
public string SignCert { get; set; } |
||||||
|
public string UserId { get; set; } |
||||||
|
public bool IsLoginSuccess { get; set; } |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,24 @@ |
|||||||
|
using System; |
||||||
|
|
||||||
|
namespace CA_Platform_Linker.Models |
||||||
|
{ |
||||||
|
public class SignInfo |
||||||
|
{ |
||||||
|
public long KeyNo { get; set; } |
||||||
|
public int TextType { get; set; } |
||||||
|
public int MZNum { get; set; } |
||||||
|
public int ZYNum { get; set; } |
||||||
|
public string SourceText { get; set; } |
||||||
|
public string Base64Text { get; set; } |
||||||
|
public string OperCode { get; set; } |
||||||
|
public string OperName { get; set; } |
||||||
|
public string SignDate { get; set; } |
||||||
|
public string CertID { get; set; } |
||||||
|
public string OperCert { get; set; } |
||||||
|
public string SignData { get; set; } |
||||||
|
public string TSData { get; set; } |
||||||
|
public string SignID { get; set; } |
||||||
|
public string OperType { get; set; } |
||||||
|
public int SignWay { get; set; } |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,272 @@ |
|||||||
|
# CA平台链接器服务 |
||||||
|
|
||||||
|
这是一个客户端程序和CA服务中间的信息交互服务,提供登录验证、自动签名开启和字符串签名功能。 |
||||||
|
|
||||||
|
## 功能特性 |
||||||
|
|
||||||
|
1. **登录验证** - 支持扫码登录 |
||||||
|
2. **自动签名开启** - 开启自动签名功能 |
||||||
|
3. **字符串签名** - 支持多种签名方式 |
||||||
|
4. **Base64编码/解码** - 提供数据转换工具 |
||||||
|
5. **时间戳服务** - 创建时间戳 |
||||||
|
|
||||||
|
## API接口 |
||||||
|
|
||||||
|
### 1. 登录验证 |
||||||
|
**接口**: `POST /Client/Login` |
||||||
|
|
||||||
|
**请求体**: |
||||||
|
```json |
||||||
|
{ |
||||||
|
"account": "test", |
||||||
|
"password": "123456" |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
**响应**: |
||||||
|
```json |
||||||
|
{ |
||||||
|
"success": true, |
||||||
|
"message": "登录成功,请扫码", |
||||||
|
"signDataId": "xxx", |
||||||
|
"qrCode": "xxx" |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
### 2. 添加签名任务 |
||||||
|
**接口**: `POST /Client/AddSignJob` |
||||||
|
|
||||||
|
**请求体**: |
||||||
|
```json |
||||||
|
{ |
||||||
|
"title": "测试签名", |
||||||
|
"data": "要签名的数据", |
||||||
|
"userId": "用户ID(可选)", |
||||||
|
"algo": "SM3withSM2", |
||||||
|
"expiryDate": "1400" |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
**响应**: |
||||||
|
```json |
||||||
|
{ |
||||||
|
"success": true, |
||||||
|
"message": "添加签名任务成功", |
||||||
|
"signDataId": "xxx", |
||||||
|
"qrCode": "xxx" |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
### 3. 自动签名 |
||||||
|
**接口**: `POST /Client/AutoSign` |
||||||
|
|
||||||
|
**请求体**: |
||||||
|
```json |
||||||
|
{ |
||||||
|
"userId": "用户ID", |
||||||
|
"signToken": "签名令牌", |
||||||
|
"data": "要签名的数据", |
||||||
|
"algo": "SM3withSM2", |
||||||
|
"expiryDate": "1400" |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
**响应**: |
||||||
|
```json |
||||||
|
{ |
||||||
|
"success": true, |
||||||
|
"message": "自动签名成功", |
||||||
|
"signResult": "签名结果", |
||||||
|
"signCert": "签名证书", |
||||||
|
"signDataId": "xxx" |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
### 4. 获取签名结果 |
||||||
|
**接口**: `POST /Client/GetSignResult` |
||||||
|
|
||||||
|
**请求体**: |
||||||
|
```json |
||||||
|
{ |
||||||
|
"signDataId": "签名数据ID" |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
**响应**: |
||||||
|
```json |
||||||
|
{ |
||||||
|
"success": true, |
||||||
|
"message": "获取签名结果成功", |
||||||
|
"jobStatus": "FINISH", |
||||||
|
"signResult": "签名结果", |
||||||
|
"signCert": "签名证书", |
||||||
|
"userId": "用户ID" |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
### 5. 查询签名图片 |
||||||
|
**接口**: `POST /Client/QueryImage` |
||||||
|
|
||||||
|
**请求体**: `"用户ID"` |
||||||
|
|
||||||
|
**响应**: |
||||||
|
```json |
||||||
|
{ |
||||||
|
"success": true, |
||||||
|
"message": "查询签名图片成功", |
||||||
|
"image": "base64图片数据" |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
### 6. Base64编码 |
||||||
|
**接口**: `POST /Client/Base64Encode` |
||||||
|
|
||||||
|
**请求体**: |
||||||
|
```json |
||||||
|
{ |
||||||
|
"plainText": "要编码的文本" |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
**响应**: |
||||||
|
```json |
||||||
|
{ |
||||||
|
"success": true, |
||||||
|
"message": "Base64编码成功", |
||||||
|
"base64Data": "编码后的数据" |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
### 7. Base64解码 |
||||||
|
**接口**: `POST /Client/Base64Decode` |
||||||
|
|
||||||
|
**请求体**: |
||||||
|
```json |
||||||
|
{ |
||||||
|
"base64Data": "要解码的Base64数据" |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
**响应**: |
||||||
|
```json |
||||||
|
{ |
||||||
|
"success": true, |
||||||
|
"message": "Base64解码成功", |
||||||
|
"plainText": "解码后的文本" |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
### 8. 创建时间戳 |
||||||
|
**接口**: `POST /Client/CreateTss` |
||||||
|
|
||||||
|
**请求体**: |
||||||
|
```json |
||||||
|
{ |
||||||
|
"oriData": "原文数据", |
||||||
|
"attachCert": true |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
**响应**: |
||||||
|
```json |
||||||
|
{ |
||||||
|
"success": true, |
||||||
|
"message": "创建时间戳成功", |
||||||
|
"tsResp": "时间戳响应" |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
## 配置说明 |
||||||
|
|
||||||
|
在 `appsettings.json` 中配置CA服务相关参数: |
||||||
|
|
||||||
|
```json |
||||||
|
{ |
||||||
|
"CossBaseUrl": "https://newcoss-dev.isignet.cn:10201/coss/service/v1/", |
||||||
|
"CossAppId": "APP_7B3F36A14E99410A80B37AEF332E3247", |
||||||
|
"CossSecureCode": "DLwiH46Esb8ccNTkuSSVAadNTWUfW0sc", |
||||||
|
"CossSignAlgo": "HMAC", |
||||||
|
"CossVersion": "1.0" |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
## 使用示例 |
||||||
|
|
||||||
|
### 1. 启动服务 |
||||||
|
```bash |
||||||
|
dotnet run |
||||||
|
``` |
||||||
|
|
||||||
|
### 2. 访问Swagger文档 |
||||||
|
打开浏览器访问: `http://localhost:5000/LISPlatformLinker/swagger` |
||||||
|
|
||||||
|
### 3. 调用API示例 |
||||||
|
|
||||||
|
#### 登录并获取二维码 |
||||||
|
```bash |
||||||
|
curl -X POST "http://localhost:5000/LISPlatformLinker/Client/Login" \ |
||||||
|
-H "Content-Type: application/json" \ |
||||||
|
-d '{"account":"test","password":"123456"}' |
||||||
|
``` |
||||||
|
|
||||||
|
#### 添加签名任务 |
||||||
|
```bash |
||||||
|
curl -X POST "http://localhost:5000/LISPlatformLinker/Client/AddSignJob" \ |
||||||
|
-H "Content-Type: application/json" \ |
||||||
|
-d '{"title":"测试签名","data":"Hello World","algo":"SM3withSM2"}' |
||||||
|
``` |
||||||
|
|
||||||
|
#### 自动签名 |
||||||
|
```bash |
||||||
|
curl -X POST "http://localhost:5000/LISPlatformLinker/Client/AutoSign" \ |
||||||
|
-H "Content-Type: application/json" \ |
||||||
|
-d '{"userId":"xxx","signToken":"xxx","data":"Hello World"}' |
||||||
|
``` |
||||||
|
|
||||||
|
## 项目结构 |
||||||
|
|
||||||
|
``` |
||||||
|
CA-Platform-Linker/ |
||||||
|
├── Controllers/ |
||||||
|
│ └── ClientController.cs # 客户端控制器 |
||||||
|
├── Models/ |
||||||
|
│ ├── Coss/ |
||||||
|
│ │ └── CossModels.cs # CA服务模型 |
||||||
|
│ └── DTO/ |
||||||
|
│ └── ClientDto.cs # 客户端DTO |
||||||
|
├── Services/ |
||||||
|
│ ├── Interfaces/ |
||||||
|
│ │ └── IClientService.cs # 客户端服务接口 |
||||||
|
│ └── ClientService.cs # 客户端服务实现 |
||||||
|
├── Tools/ |
||||||
|
│ ├── CossHelper.cs # CA服务帮助类 |
||||||
|
│ ├── ConfigHelper.cs # 配置帮助类 |
||||||
|
│ └── MySecurity.cs # 安全类 |
||||||
|
└── appsettings.json # 配置文件 |
||||||
|
``` |
||||||
|
|
||||||
|
## 注意事项 |
||||||
|
|
||||||
|
1. 所有接口都使用POST方法 |
||||||
|
2. 请求和响应都使用JSON格式 |
||||||
|
3. 签名数据会自动进行Base64编码 |
||||||
|
4. 需要正确配置CA服务的连接参数 |
||||||
|
5. 建议在生产环境中使用HTTPS协议 |
||||||
|
|
||||||
|
## 错误处理 |
||||||
|
|
||||||
|
所有接口都包含错误处理,当请求失败时会返回错误信息: |
||||||
|
|
||||||
|
```json |
||||||
|
{ |
||||||
|
"success": false, |
||||||
|
"message": "错误描述" |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
## 日志 |
||||||
|
|
||||||
|
使用NLog进行日志记录,日志文件位于 `logs/` 目录下: |
||||||
|
- `logs/info/` - 信息日志 |
||||||
|
- `logs/error/` - 错误日志 |
||||||
|
- `logs/debug/` - 调试日志 |
||||||
@ -0,0 +1,160 @@ |
|||||||
|
using CA_Platform_Linker.Models; |
||||||
|
using CA_Platform_Linker.Models.Coss; |
||||||
|
using CA_Platform_Linker.Services.Interfaces; |
||||||
|
using CA_Platform_Linker.Tools; |
||||||
|
using CA_Platform_Linker.Tools.Nlog; |
||||||
|
using System; |
||||||
|
using System.Collections; |
||||||
|
using System.Threading.Tasks; |
||||||
|
|
||||||
|
namespace CA_Platform_Linker.Services |
||||||
|
{ |
||||||
|
public class ClientService : IClientService |
||||||
|
{ |
||||||
|
public async Task<CossResponse<CossResultData>> StartAutoSignAsync(string clientType, int timeRegion = 3600 * 24) |
||||||
|
{ |
||||||
|
try |
||||||
|
{ |
||||||
|
Hashtable ht = CossHelper.BuildBaseHashtable(clientType); |
||||||
|
ht.Add("timeRegion", timeRegion.ToString()); |
||||||
|
return await CossHelper.PostAsync<CossResultData>("startAutoSign", ht, clientType); |
||||||
|
} |
||||||
|
catch (Exception ex) |
||||||
|
{ |
||||||
|
LogHelper.Log.Error($"开启自动签名失败: {ex.Message}"); |
||||||
|
return new CossResponse<CossResultData> |
||||||
|
{ |
||||||
|
status = "500", |
||||||
|
message = ex.Message |
||||||
|
}; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public async Task<CossResponse<CossResultData>> AddSignJobAsync(string clientType, string title, string data, string userId = "", string algo = "SM3withSM2", string expiryDate = "1400") |
||||||
|
{ |
||||||
|
try |
||||||
|
{ |
||||||
|
string base64Data = data; |
||||||
|
if (!string.IsNullOrEmpty(data)) |
||||||
|
{ |
||||||
|
base64Data = CossHelper.Base64Encode(data); |
||||||
|
} |
||||||
|
|
||||||
|
Hashtable ht = CossHelper.BuildBaseHashtable(clientType); |
||||||
|
ht.Add("title", title); |
||||||
|
ht.Add("dataType", "DATA"); |
||||||
|
ht.Add("algo", algo); |
||||||
|
ht.Add("description", clientType + "签名任务"); |
||||||
|
ht.Add("data", base64Data); |
||||||
|
ht.Add("expiryDate", expiryDate); |
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(userId)) |
||||||
|
{ |
||||||
|
ht.Add("userId", userId); |
||||||
|
} |
||||||
|
|
||||||
|
return await CossHelper.PostAsync<CossResultData>("addSignJob", ht, clientType); |
||||||
|
} |
||||||
|
catch (Exception ex) |
||||||
|
{ |
||||||
|
LogHelper.Log.Error($"添加签名任务失败: {ex.Message}"); |
||||||
|
return new CossResponse<CossResultData> |
||||||
|
{ |
||||||
|
status = "500", |
||||||
|
message = ex.Message |
||||||
|
}; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public async Task<CossResponse<CossResultData>> AutoSignAsync(string clientType, string userId, string signToken, string data, string algo = "SM3withSM2", string expiryDate = "1400", int mzNum = 0, int zyNum = 0, string signID = "", int clientOper = 0) |
||||||
|
{ |
||||||
|
try |
||||||
|
{ |
||||||
|
string base64Data = data; |
||||||
|
if (!string.IsNullOrEmpty(data)) |
||||||
|
{ |
||||||
|
base64Data = CossHelper.Base64Encode(data); |
||||||
|
} |
||||||
|
|
||||||
|
Hashtable ht = CossHelper.BuildBaseHashtable(clientType); |
||||||
|
ht.Add("userId", userId); |
||||||
|
ht.Add("title", clientType + "自动签名"); |
||||||
|
ht.Add("dataType", "DATA"); |
||||||
|
ht.Add("algo", algo); |
||||||
|
ht.Add("description", clientType + "自动签名"); |
||||||
|
ht.Add("data", base64Data); |
||||||
|
ht.Add("signToken", signToken); |
||||||
|
ht.Add("expiryDate", expiryDate); |
||||||
|
|
||||||
|
var result = await CossHelper.PostAsync<CossResultData>("autoSign", ht, clientType); |
||||||
|
|
||||||
|
if (result.status == "200") |
||||||
|
{ |
||||||
|
_ = Task.Run(() => |
||||||
|
{ |
||||||
|
try |
||||||
|
{ |
||||||
|
var clientConfig = ConfigHelper.GetCossClientConfig(clientType); |
||||||
|
var (operCode, operName) = SqlHelper.GetOperatorInfo(userId); |
||||||
|
var signInfo = new SignInfo |
||||||
|
{ |
||||||
|
TextType = clientConfig.TextType + clientOper, |
||||||
|
MZNum = mzNum, |
||||||
|
ZYNum = zyNum, |
||||||
|
SourceText = data, |
||||||
|
Base64Text = "", |
||||||
|
OperCode = operCode ?? "", |
||||||
|
OperName = operName ?? "", |
||||||
|
SignDate = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), |
||||||
|
CertID = "", |
||||||
|
OperCert = result.data.signCert, |
||||||
|
SignData = result.data.signResult, |
||||||
|
TSData = "", |
||||||
|
SignID = signID, |
||||||
|
OperType = clientType + "自动签名", |
||||||
|
SignWay = 1 |
||||||
|
}; |
||||||
|
|
||||||
|
SqlHelper.InsertSignInfo(signInfo); |
||||||
|
LogHelper.Log.Info($"签名记录已写入数据库,SignDataId: {result.data.signDataId}"); |
||||||
|
} |
||||||
|
catch (Exception ex) |
||||||
|
{ |
||||||
|
LogHelper.Log.Error($"写入签名记录失败:{ex.Message}"); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
return result; |
||||||
|
} |
||||||
|
catch (Exception ex) |
||||||
|
{ |
||||||
|
LogHelper.Log.Error($"自动签名失败: {ex.Message}"); |
||||||
|
return new CossResponse<CossResultData> |
||||||
|
{ |
||||||
|
status = "500", |
||||||
|
message = ex.Message |
||||||
|
}; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public async Task<CossResponse<CossResultData>> GetSignResultAsync(string clientType, string signDataId) |
||||||
|
{ |
||||||
|
try |
||||||
|
{ |
||||||
|
Hashtable ht = CossHelper.BuildBaseHashtable(clientType); |
||||||
|
ht.Add("signDataId", signDataId); |
||||||
|
return await CossHelper.PostAsync<CossResultData>("getSignResult", ht, clientType); |
||||||
|
} |
||||||
|
catch (Exception ex) |
||||||
|
{ |
||||||
|
LogHelper.Log.Error($"获取签名结果失败: {ex.Message}"); |
||||||
|
return new CossResponse<CossResultData> |
||||||
|
{ |
||||||
|
status = "500", |
||||||
|
message = ex.Message |
||||||
|
}; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,16 @@ |
|||||||
|
using CA_Platform_Linker.Models.Coss; |
||||||
|
using System; |
||||||
|
using System.Collections.Generic; |
||||||
|
using System.Linq; |
||||||
|
using System.Threading.Tasks; |
||||||
|
|
||||||
|
namespace CA_Platform_Linker.Services.Interfaces |
||||||
|
{ |
||||||
|
public interface IClientService |
||||||
|
{ |
||||||
|
Task<CossResponse<CossResultData>> StartAutoSignAsync(string clientType, int timeRegion = 3600 * 24); |
||||||
|
Task<CossResponse<CossResultData>> AddSignJobAsync(string clientType, string title, string data, string userId = "", string algo = "SM3withSM2", string expiryDate = "1400"); |
||||||
|
Task<CossResponse<CossResultData>> AutoSignAsync(string clientType, string userId, string signToken, string data, string algo = "SM3withSM2", string expiryDate = "1400", int mzNum = 0, int zyNum = 0, string signID = "", int clientOper = 0); |
||||||
|
Task<CossResponse<CossResultData>> GetSignResultAsync(string clientType, string signDataId); |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,86 @@ |
|||||||
|
using CA_Platform_Linker.Services; |
||||||
|
using CA_Platform_Linker.Services.Interfaces; |
||||||
|
using CA_Platform_Linker.Tools; |
||||||
|
using Microsoft.AspNetCore.Builder; |
||||||
|
using Microsoft.AspNetCore.Hosting; |
||||||
|
using Microsoft.AspNetCore.Mvc; |
||||||
|
using Microsoft.Extensions.Configuration; |
||||||
|
using Microsoft.Extensions.DependencyInjection; |
||||||
|
using Microsoft.Extensions.Hosting; |
||||||
|
using Microsoft.Extensions.Logging; |
||||||
|
using Microsoft.OpenApi.Models; |
||||||
|
using System; |
||||||
|
using System.Collections.Generic; |
||||||
|
using System.Linq; |
||||||
|
using System.Threading.Tasks; |
||||||
|
|
||||||
|
namespace CA_Platform_Linker |
||||||
|
{ |
||||||
|
public class Startup |
||||||
|
{ |
||||||
|
public Startup(IConfiguration configuration) |
||||||
|
{ |
||||||
|
Configuration = configuration; |
||||||
|
} |
||||||
|
|
||||||
|
public IConfiguration Configuration { get; } |
||||||
|
|
||||||
|
// This method gets called by the runtime. Use this method to add services to the container. |
||||||
|
public void ConfigureServices(IServiceCollection services) |
||||||
|
{ |
||||||
|
//读取配置 |
||||||
|
ConfigHelper.Initialize(Configuration); |
||||||
|
|
||||||
|
//初始化数据库连接 |
||||||
|
SqlHelper.Initialize(Configuration); |
||||||
|
|
||||||
|
services.AddControllers(); |
||||||
|
|
||||||
|
//注册服务 |
||||||
|
services.AddTransient<IClientService, ClientService>(); |
||||||
|
|
||||||
|
services.AddSwaggerGen(s => |
||||||
|
{ |
||||||
|
//标记swagger 信息(内容自定义) |
||||||
|
//V1.0.0-->SwaggerEndpoint(url,name)-->url 使用 |
||||||
|
s.SwaggerDoc("V1.0.0", new Microsoft.OpenApi.Models.OpenApiInfo |
||||||
|
{ |
||||||
|
Title = "CA平台连接服务", |
||||||
|
Version = "1.0.0", |
||||||
|
}); |
||||||
|
s.AddServer(new OpenApiServer |
||||||
|
{ |
||||||
|
Url = "/CAPlatformLinker", |
||||||
|
Description = "API全局路由" |
||||||
|
}); |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. |
||||||
|
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) |
||||||
|
{ |
||||||
|
if (env.IsDevelopment()) |
||||||
|
{ |
||||||
|
app.UseDeveloperExceptionPage(); |
||||||
|
} |
||||||
|
|
||||||
|
app.UsePathBase("/CAPlatformLinker"); |
||||||
|
|
||||||
|
app.UseSwagger(); |
||||||
|
app.UseSwaggerUI(su => |
||||||
|
{ |
||||||
|
//url中[V1.0.0]与ConfigureServices 中配置的SwaggerDoc("V1.0.0",..) 保持一致 |
||||||
|
su.SwaggerEndpoint("/swagger/V1.0.0/swagger.json", null); |
||||||
|
}); |
||||||
|
|
||||||
|
app.UseRouting(); |
||||||
|
|
||||||
|
app.UseAuthorization(); |
||||||
|
|
||||||
|
app.UseEndpoints(endpoints => |
||||||
|
{ |
||||||
|
endpoints.MapControllers(); |
||||||
|
}); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,68 @@ |
|||||||
|
using Microsoft.Extensions.Configuration; |
||||||
|
using System; |
||||||
|
using System.Collections.Generic; |
||||||
|
using System.Linq; |
||||||
|
using System.Threading.Tasks; |
||||||
|
|
||||||
|
namespace CA_Platform_Linker.Tools |
||||||
|
{ |
||||||
|
public static class ConfigHelper |
||||||
|
{ |
||||||
|
private static IConfiguration _config; |
||||||
|
|
||||||
|
public static void Initialize(IConfiguration configuration) |
||||||
|
{ |
||||||
|
_config = configuration; |
||||||
|
} |
||||||
|
|
||||||
|
// LIS数据库连接字符串 |
||||||
|
public static string ConnectionString => MySecurity.SDecryptString(_config.GetValue<string>("ConnectionString")); |
||||||
|
|
||||||
|
// 检验平台接口地址 |
||||||
|
public static string PlatformUrl => _config.GetValue<string>("PlatformUrl"); |
||||||
|
|
||||||
|
// 医疗机构代码 |
||||||
|
public static string HospitalCode => _config.GetValue<string>("HospitalCode"); |
||||||
|
|
||||||
|
// 医疗机构名称 |
||||||
|
public static string HospitalName => _config.GetValue<string>("HospitalName"); |
||||||
|
|
||||||
|
// CA服务基础配置 |
||||||
|
public static string CossBaseUrl => _config.GetValue<string>("CossBaseUrl", "http://192.168.0.148:10201/coss/service/v1/"); |
||||||
|
public static string CossSignAlgo => _config.GetValue<string>("CossSignAlgo", "HMAC"); |
||||||
|
public static string CossVersion => _config.GetValue<string>("CossVersion", "1.0"); |
||||||
|
|
||||||
|
// 获取指定客户端的配置 |
||||||
|
public static CossClientConfig GetCossClientConfig(string clientType) |
||||||
|
{ |
||||||
|
var clientsSection = _config.GetSection("CossClients"); |
||||||
|
var clientSection = clientsSection.GetSection(clientType); |
||||||
|
|
||||||
|
if (!clientSection.Exists()) |
||||||
|
{ |
||||||
|
throw new ArgumentException($"未找到客户端类型 '{clientType}' 的配置"); |
||||||
|
} |
||||||
|
|
||||||
|
return new CossClientConfig |
||||||
|
{ |
||||||
|
AppId = clientSection.GetValue<string>("AppId"), |
||||||
|
SecureCode = clientSection.GetValue<string>("SecureCode"), |
||||||
|
TextType = clientSection.GetValue<int>("TextType", 0) |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
// 获取所有支持的客户端类型 |
||||||
|
public static List<string> GetSupportedClientTypes() |
||||||
|
{ |
||||||
|
var clientsSection = _config.GetSection("CossClients"); |
||||||
|
return clientsSection.GetChildren().Select(x => x.Key).ToList(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public class CossClientConfig |
||||||
|
{ |
||||||
|
public string AppId { get; set; } |
||||||
|
public string SecureCode { get; set; } |
||||||
|
public int TextType { get; set; } |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,93 @@ |
|||||||
|
using CA_Platform_Linker.Models.Coss; |
||||||
|
using CA_Platform_Linker.Tools; |
||||||
|
using CA_Platform_Linker.Tools.Nlog; |
||||||
|
using Newtonsoft.Json; |
||||||
|
using System; |
||||||
|
using System.Collections; |
||||||
|
using System.Linq; |
||||||
|
using System.Net.Http; |
||||||
|
using System.Security.Cryptography; |
||||||
|
using System.Text; |
||||||
|
using System.Threading.Tasks; |
||||||
|
|
||||||
|
namespace CA_Platform_Linker.Tools |
||||||
|
{ |
||||||
|
public class CossHelper |
||||||
|
{ |
||||||
|
private static readonly HttpClient _httpClient = new HttpClient(); |
||||||
|
|
||||||
|
public static string GetSignature(string secret, string content) |
||||||
|
{ |
||||||
|
secret = secret ?? ""; |
||||||
|
var encoding = Encoding.UTF8; |
||||||
|
byte[] keyByte = encoding.GetBytes(secret); |
||||||
|
byte[] messageBytes = encoding.GetBytes(content); |
||||||
|
using (var hmacsha256 = new HMACSHA256(keyByte)) |
||||||
|
{ |
||||||
|
byte[] hashmessage = hmacsha256.ComputeHash(messageBytes); |
||||||
|
return Convert.ToBase64String(hashmessage); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static string GetSignatureValue(Hashtable ht, string secureCode) |
||||||
|
{ |
||||||
|
string str = ""; |
||||||
|
ArrayList akeys = new ArrayList(ht.Keys); |
||||||
|
akeys.Sort(); |
||||||
|
foreach (string key in akeys) |
||||||
|
{ |
||||||
|
str += key + "=" + ht[key] + "&"; |
||||||
|
} |
||||||
|
str = str.Substring(0, str.Length - 1); |
||||||
|
return GetSignature(secureCode, str); |
||||||
|
} |
||||||
|
|
||||||
|
public static Hashtable BuildBaseHashtable(string clientType) |
||||||
|
{ |
||||||
|
var clientConfig = ConfigHelper.GetCossClientConfig(clientType); |
||||||
|
Hashtable ht = new Hashtable(); |
||||||
|
ht.Add("version", ConfigHelper.CossVersion); |
||||||
|
ht.Add("appId", clientConfig.AppId); |
||||||
|
ht.Add("signAlgo", ConfigHelper.CossSignAlgo); |
||||||
|
return ht; |
||||||
|
} |
||||||
|
|
||||||
|
public static async Task<CossResponse<T>> PostAsync<T>(string apiName, Hashtable ht, string clientType) |
||||||
|
{ |
||||||
|
try |
||||||
|
{ |
||||||
|
var clientConfig = ConfigHelper.GetCossClientConfig(clientType); |
||||||
|
ht.Add("signature", GetSignatureValue(ht, clientConfig.SecureCode)); |
||||||
|
string strJson = JsonConvert.SerializeObject(ht); |
||||||
|
string url = ConfigHelper.CossBaseUrl + apiName; |
||||||
|
|
||||||
|
var content = new StringContent(strJson, Encoding.UTF8, "application/json"); |
||||||
|
var response = await _httpClient.PostAsync(url, content); |
||||||
|
string responseStr = await response.Content.ReadAsStringAsync(); |
||||||
|
|
||||||
|
return JsonConvert.DeserializeObject<CossResponse<T>>(responseStr); |
||||||
|
} |
||||||
|
catch (Exception ex) |
||||||
|
{ |
||||||
|
LogHelper.Log.Error($"CA服务调用失败: {ex.Message}"); |
||||||
|
return new CossResponse<T> |
||||||
|
{ |
||||||
|
status = "500", |
||||||
|
message = ex.Message |
||||||
|
}; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static string Base64Encode(string plainText) |
||||||
|
{ |
||||||
|
var plainTextBytes = Encoding.UTF8.GetBytes(plainText); |
||||||
|
return Convert.ToBase64String(plainTextBytes); |
||||||
|
} |
||||||
|
|
||||||
|
public static string Base64Decode(string base64EncodedData) |
||||||
|
{ |
||||||
|
var base64EncodedBytes = Convert.FromBase64String(base64EncodedData); |
||||||
|
return Encoding.UTF8.GetString(base64EncodedBytes); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,13 @@ |
|||||||
|
using NLog; |
||||||
|
using System; |
||||||
|
using System.Collections.Generic; |
||||||
|
using System.Linq; |
||||||
|
using System.Threading.Tasks; |
||||||
|
|
||||||
|
namespace CA_Platform_Linker.Tools |
||||||
|
{ |
||||||
|
public class LogHelper |
||||||
|
{ |
||||||
|
public static readonly NLog.Logger Log = LogManager.GetCurrentClassLogger(); |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,89 @@ |
|||||||
|
using CA_Platform_Linker.Models; |
||||||
|
using Microsoft.Data.SqlClient; |
||||||
|
using Microsoft.Extensions.Configuration; |
||||||
|
using System; |
||||||
|
|
||||||
|
namespace CA_Platform_Linker.Tools |
||||||
|
{ |
||||||
|
public static class SqlHelper |
||||||
|
{ |
||||||
|
private static string _connectionString; |
||||||
|
|
||||||
|
public static void Initialize(IConfiguration configuration) |
||||||
|
{ |
||||||
|
_connectionString = configuration.GetConnectionString("HisDB"); |
||||||
|
} |
||||||
|
|
||||||
|
public static int InsertSignInfo(SignInfo signInfo) |
||||||
|
{ |
||||||
|
if (string.IsNullOrEmpty(_connectionString)) |
||||||
|
{ |
||||||
|
throw new InvalidOperationException("数据库连接字符串未配置"); |
||||||
|
} |
||||||
|
|
||||||
|
string sql = @"INSERT INTO [DigitalSignData].[dbo].[SignInfo]
|
||||||
|
([TextType], [MZNum], [ZYNum], [SourceText], [Base64Text], |
||||||
|
[OperCode], [OperName], [SignDate], [CertID], [OperCert], |
||||||
|
[SignData], [TSData], [SignID], [OperType], [SignWay]) |
||||||
|
VALUES |
||||||
|
(@TextType, @MZNum, @ZYNum, @SourceText, @Base64Text, |
||||||
|
@OperCode, @OperName, @SignDate, @CertID, @OperCert, |
||||||
|
@SignData, @TSData, @SignID, @OperType, @SignWay)";
|
||||||
|
|
||||||
|
using (SqlConnection conn = new SqlConnection(_connectionString)) |
||||||
|
{ |
||||||
|
using (SqlCommand cmd = new SqlCommand(sql, conn)) |
||||||
|
{ |
||||||
|
cmd.Parameters.AddWithValue("@TextType", signInfo.TextType); |
||||||
|
cmd.Parameters.AddWithValue("@MZNum", signInfo.MZNum); |
||||||
|
cmd.Parameters.AddWithValue("@ZYNum", signInfo.ZYNum); |
||||||
|
cmd.Parameters.AddWithValue("@SourceText", (object)signInfo.SourceText ?? DBNull.Value); |
||||||
|
cmd.Parameters.AddWithValue("@Base64Text", (object)signInfo.Base64Text ?? DBNull.Value); |
||||||
|
cmd.Parameters.AddWithValue("@OperCode", (object)signInfo.OperCode ?? DBNull.Value); |
||||||
|
cmd.Parameters.AddWithValue("@OperName", (object)signInfo.OperName ?? DBNull.Value); |
||||||
|
cmd.Parameters.AddWithValue("@SignDate", (object)signInfo.SignDate ?? DBNull.Value); |
||||||
|
cmd.Parameters.AddWithValue("@CertID", (object)signInfo.CertID ?? DBNull.Value); |
||||||
|
cmd.Parameters.AddWithValue("@OperCert", (object)signInfo.OperCert ?? DBNull.Value); |
||||||
|
cmd.Parameters.AddWithValue("@SignData", (object)signInfo.SignData ?? DBNull.Value); |
||||||
|
cmd.Parameters.AddWithValue("@TSData", (object)signInfo.TSData ?? DBNull.Value); |
||||||
|
cmd.Parameters.AddWithValue("@SignID", (object)signInfo.SignID ?? DBNull.Value); |
||||||
|
cmd.Parameters.AddWithValue("@OperType", (object)signInfo.OperType ?? DBNull.Value); |
||||||
|
cmd.Parameters.AddWithValue("@SignWay", signInfo.SignWay); |
||||||
|
|
||||||
|
conn.Open(); |
||||||
|
return cmd.ExecuteNonQuery(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static (string operCode, string operName) GetOperatorInfo(string bjcaMsspid) |
||||||
|
{ |
||||||
|
if (string.IsNullOrEmpty(_connectionString)) |
||||||
|
{ |
||||||
|
throw new InvalidOperationException("数据库连接字符串未配置"); |
||||||
|
} |
||||||
|
|
||||||
|
string sql = @"SELECT [CODE], [NAME]
|
||||||
|
FROM [HisData].[dbo].[YSCODE] |
||||||
|
WHERE [BJCA_MSSPID] = @BJCA_MSSPID";
|
||||||
|
|
||||||
|
using (SqlConnection conn = new SqlConnection(_connectionString)) |
||||||
|
{ |
||||||
|
using (SqlCommand cmd = new SqlCommand(sql, conn)) |
||||||
|
{ |
||||||
|
cmd.Parameters.AddWithValue("@BJCA_MSSPID", bjcaMsspid); |
||||||
|
conn.Open(); |
||||||
|
using (var reader = cmd.ExecuteReader()) |
||||||
|
{ |
||||||
|
if (reader.Read()) |
||||||
|
{ |
||||||
|
return (reader["CODE"].ToString(), reader["NAME"].ToString()); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return (null, null); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,9 @@ |
|||||||
|
{ |
||||||
|
"Logging": { |
||||||
|
"LogLevel": { |
||||||
|
"Default": "Information", |
||||||
|
"Microsoft": "Warning", |
||||||
|
"Microsoft.Hosting.Lifetime": "Information" |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,38 @@ |
|||||||
|
{ |
||||||
|
"Logging": { |
||||||
|
"LogLevel": { |
||||||
|
"Default": "Information", |
||||||
|
"Microsoft": "Warning", |
||||||
|
"Microsoft.Hosting.Lifetime": "Information" |
||||||
|
} |
||||||
|
}, |
||||||
|
"AllowedHosts": "*", |
||||||
|
"ConnectionStrings": { |
||||||
|
"HisDB": "Data Source=192.168.0.222;User ID=XBDLisUser;Password=BlueFlag.Lis!@#;TrustServerCertificate=True" |
||||||
|
}, |
||||||
|
"CossBaseUrl": "http://192.168.0.148:10201/coss/service/v1/", |
||||||
|
"CossSignAlgo": "HMAC", |
||||||
|
"CossVersion": "1.0", |
||||||
|
"CossClients": { |
||||||
|
"LIS": { |
||||||
|
"AppId": "APP_E559E1B8906045D4881D74F29361F6BB", |
||||||
|
"SecureCode": "MGI0ODQ0NjYxZjg1NDgzZDhkMDNjYzI5YTM4MDA0ZDk=", |
||||||
|
"TextType": 500 |
||||||
|
}, |
||||||
|
"PEIS": { |
||||||
|
"AppId": "APP_6E254EA9538743088BD393C3D0212617", |
||||||
|
"SecureCode": "OTdhMDRkMmY1YzVmNDczY2FlZjhhOWE5NmY1OTI2MzY=", |
||||||
|
"TextType": 700 |
||||||
|
}, |
||||||
|
"Blood": { |
||||||
|
"AppId": "APP_855883154E16433EBE12B8C73822AE17", |
||||||
|
"SecureCode": "YjI1YjVkYTQ5OWMwNDYxOTkwY2MwZTUyYTkxMzc2MWU=", |
||||||
|
"TextType": 600 |
||||||
|
}, |
||||||
|
"WeChat": { |
||||||
|
"AppId": "APP_E56656ADD9DE48779F21D9FE50529E3A", |
||||||
|
"SecureCode": "OTczNzkyMWNlMzk2NGE3YjgyMTdkMzRkNzBmODllNTk=", |
||||||
|
"TextType": 800 |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
Loading…
Reference in new issue