ContractLifecycle 域统一了电子合同(eSign)的创建、查询、提交审批、通过/拒绝、归档与取消能力。法大大和契约锁两家供应商共享同一个 IContractService 接口,但鉴权机制差异显著:法大大用 AppId + AppSecret 换 Bearer token,契约锁用 MD5 签名头。
域结构
Bitzsoft.Integrations.ContractLifecycle ← 抽象层├── Bitzsoft.Integrations.ContractLifecycle.Fadada ← 法大大(AppId+AppSecret → Bearer)├── Bitzsoft.Integrations.ContractLifecycle.Qiyuesuo ← 契约锁(MD5 签名头)└── Bitzsoft.Integrations.ContractLifecycle.All ← 聚合包标准三层包模式。
统一接口(8 方法)
IContractService 围绕”合同(Contract)“这一核心概念组织,共 8 个方法:
public interface IContractService{ string ProviderName { get; }
// 合同生命周期 Task<ContractInfo> CreateContractAsync(CreateContractRequest request, CancellationToken cancellationToken = default); Task<ContractInfo> GetContractAsync(string contractId, CancellationToken cancellationToken = default); Task SubmitContractAsync(string contractId, CancellationToken cancellationToken = default); Task ApproveContractAsync(string contractId, CancellationToken cancellationToken = default); Task RejectContractAsync(string contractId, string? reason = null, CancellationToken cancellationToken = default); Task ArchiveContractAsync(string contractId, CancellationToken cancellationToken = default); Task CancelContractAsync(string contractId, CancellationToken cancellationToken = default); Task<List<ContractInfo>> ListContractsAsync(ListContractsRequest request, CancellationToken cancellationToken = default);}创建与查询返回 ContractInfo,状态流转操作(提交/审批/拒绝/归档/取消)为无返回 Task,失败抛 ContractException。ContractInfo.Status 反映合同在供应商侧的当前状态。
鉴权模型
两家供应商使用截然不同的鉴权机制:
| 供应商 | 鉴权机制 | Token/签名 注入 | 成功判断 |
|---|---|---|---|
| 法大大 | AppId + AppSecret 换 Bearer token | Authorization: Bearer {token} 头 | 业务码校验 |
| 契约锁 | AppKey + AppSecret 计算 MD5 签名 | 签名头(X-Qys-Sign 等) | 业务码校验 |
供应商清单
| 供应商 | Provider ID | API 基地址 | Stability | DI 方法 |
|---|---|---|---|---|
| 法大大 | fadada | openapi.fadada.com | Preview | AddFadadaContract() |
| 契约锁 | qiyuesuo | openapi.qiyuesuo.com | Preview | AddQiyuesuoContract() |
两家是国内主流电子合同与电子签章服务商,均覆盖完整合同生命周期。
注册
单厂商
// ① 法大大(AppId+AppSecret → Bearer)builder.Services.AddFadadaContract(builder.Configuration.GetSection("ContractLifecycle:Fadada"));
// ② 契约锁(MD5 签名头)builder.Services.AddQiyuesuoContract(builder.Configuration.GetSection("ContractLifecycle:Qiyuesuo"));全量聚合
builder.Services.AddBitzsoftContractLifecycleAll(builder.Configuration, "ContractLifecycle");按配置节存在性自动注册,appsettings.json 只需写出启用的供应商:
{ "ContractLifecycle": { "Fadada": { "AppId": "...", "AppSecret": "...", "BaseUrl": "https://openapi.fadada.com" }, "Qiyuesuo": { "AppKey": "...", "AppSecret": "...", "BaseUrl": "https://openapi.qiyuesuo.com" } }}消费
创建并提交合同
public class ContractFlowService(IIntegrationProviderResolver<IContractService> providers){ public async Task<ContractInfo> DraftAndSubmitAsync(string vendor, string title, string templateId, Dictionary<string, string> fields) { var contract = providers.GetRequired(vendor); // "fadada" / "qiyuesuo"
// ① 创建合同(基于模板填充) var info = await contract.CreateContractAsync(new CreateContractRequest { Title = title, TemplateId = templateId, TemplateFields = fields, });
// ② 提交审批流 await contract.SubmitContractAsync(info.ContractId); return info; }}审批与归档
// 审批通过await contract.ApproveContractAsync(contractId);
// 拒绝并附理由await contract.RejectContractAsync(contractId, reason: "条款需修订");
// 流程结束后归档await contract.ArchiveContractAsync(contractId);查询与取消
// 查询单份合同状态var detail = await contract.GetContractAsync(contractId);// detail.Status: Draft / Pending / Approved / Rejected / Archived / Cancelled
// 作废未完成的合同await contract.CancelContractAsync(contractId);多厂商路由
public class ContractRouter(IIntegrationProviderResolver<IContractService> providers){ public async Task<ContractInfo> GetAsync(string source, string contractId) { var contract = providers.GetRequired(source); // "fadada" / "qiyuesuo" return await contract.GetContractAsync(contractId); }}