# 企业入驻 × e签宝 功能分析 > 文档基于 `hyapi-server` 与 `hyapi-consoleweb` 代码梳理,最后更新:2026-07-13 ## 1. 功能概述 企业入驻是独立的**认证域(certification)**,通过自研 Go SDK(`internal/shared/esign`)对接 e签宝 OpenAPI,引导企业用户完成: 1. 填写并提交企业信息(含人工审核) 2. e签宝机构实名认证 3. 基于模板生成合作协议并电子签署 4. 入驻完成(激活钱包、API 用户等) **核心实现文件:** | 层级 | 路径 | |------|------| | 业务编排 | `internal/application/certification/certification_application_service_impl.go` | | 状态机实体 | `internal/domains/certification/entities/certification.go` | | e签宝 SDK | `internal/shared/esign/` | | HTTP 路由 | `internal/infrastructure/http/routes/certification_routes.go` | | 前端主流程 | `hyapi-consoleweb/src/pages/certification/` | --- ## 2. 涉及数据表 表结构通过 GORM `AutoMigrate` 自动创建(`internal/app/app.go`),无独立 SQL migration。 ### 2.1 认证域(核心) #### `certifications` — 认证主表(聚合根) 每个用户最多一条认证记录(`user_id` 唯一),贯穿全流程并存储 e签宝 关键 ID/链接。 | 字段 | 类型 | 说明 | |------|------|------| | `id` | varchar(64) | 认证申请 ID | | `user_id` | varchar(36) | 用户 ID(唯一) | | `status` | varchar(50) | 认证状态(见第 3 节) | | `info_submitted_at` | datetime | 企业信息审核通过时间 | | `enterprise_verified_at` | datetime | e签宝 企业认证完成时间 | | `contract_applied_at` | datetime | 申请签署时间 | | `contract_signed_at` | datetime | 签署完成时间 | | `completed_at` | datetime | 入驻完成时间 | | `contract_file_created_at` | datetime | 合同文件生成时间(用于 50 分钟过期判断) | | `auth_flow_id` | varchar(500) | e签宝 企业认证流程 ID | | `auth_url` | varchar(500) | e签宝 企业认证页面链接 | | `contract_code` | varchar(100) | 合作协议编号(如 `HYDATA-20260713-R123456`) | | `contract_file_id` | varchar(500) | e签宝 合同文件 ID | | `esign_flow_id` | varchar(500) | e签宝 签署流程 ID | | `contract_url` | varchar(500) | 合同预览/下载 URL | | `contract_sign_url` | varchar(500) | 合同签署链接 | | `failure_reason` / `failure_message` | varchar/text | 失败原因与详情 | | `retry_count` | int | 重试次数(上限 3) | | `last_transition_*` | — | 状态转换审计字段 | #### `enterprise_info_submit_records` — 企业信息提交与人工审核 用户每次提交企业信息时写入,承载审核材料与审核结果。 | 字段分组 | 主要字段 | 说明 | |----------|----------|------| | 企业四要素 | `company_name`、`unified_social_code`、`legal_person_*`、`enterprise_address` | 企业基本信息 | | 授权代表 | `authorized_rep_name/id/phone`、`authorized_rep_id_image_urls` | 授权代表信息(身份证图片为 JSON 数组) | | 资质材料 | `business_license_image_url`、`office_place_image_urls`、`api_usage`、`scenario_attachment_urls` | 营业执照、办公场地、业务场景说明及附件 | | 前置校验 | `status` | `submitted` / `verified` / `failed`(西部数据三真等) | | 人工审核 | `manual_review_status` | `pending` / `approved` / `rejected` | | 审核人 | `manual_reviewer_id`、`manual_review_remark`、`manual_reviewed_at` | 管理员审核信息 | #### `esign_contract_generate_records` — 合同生成记录 | 字段 | 说明 | |------|------| | `certification_id`、`user_id` | 关联认证与用户 | | `template_id` | e签宝 模板 ID | | `contract_file_id`、`contract_url`、`contract_name` | 生成结果 | | `status` | `success` / `failed` | | `fill_time` | 填单时间 | #### `esign_contract_sign_records` — 合同签署记录 | 字段 | 说明 | |------|------| | `esign_flow_id`、`contract_file_id` | e签宝 流程与文件 | | `sign_url`、`sign_short_url` | 签署链接 | | `signed_file_url` | 已签署文件 URL | | `status` | `pending` / `signing` / `success` / `failed` / `expired` | | `signer_name/phone/id_card` | 签署人信息 | | `request_at`、`signed_at`、`expired_at` | 时间戳(默认 7 天过期) | ### 2.2 用户域(认证完成后写入) #### `enterprise_infos` — 已认证企业信息 认证通过后从提交记录同步,供充值、开票、API 调用等使用;与用户一对一。 | 字段 | 说明 | |------|------| | `user_id` | 用户 ID(唯一索引) | | `company_name` | 企业名称 | | `unified_social_code` | 统一社会信用代码 | | `legal_person_name/id/phone` | 法人信息 | | `enterprise_address` | 企业地址 | #### `contract_infos` — 已签署合同 签署完成后写入,一个企业可有多份合同。 | 字段 | 说明 | |------|------| | `enterprise_info_id`、`user_id` | 关联企业与用户 | | `contract_code` | 合同编号(唯一) | | `contract_name` | 合同名称 | | `contract_type` | `cooperation`(入驻)/ `resign`(补签) | | `contract_file_id` | e签宝 文件 ID | | `contract_file_url` | 七牛云永久存储链接 | ### 2.3 入驻完成后关联表(非 e签宝 直接写入,但属完成动作) | 表名 | 说明 | |------|------| | `wallets` | 创建用户钱包 | | `api_users` | 创建 API 调用身份 | | `users` | 标记用户已完成认证(`CompleteCertification`) | --- ## 3. 认证状态机 ``` pending └─► info_pending_review(提交企业信息,等待人工审核) ├─► info_rejected(审核拒绝 / e签宝 认证失败) └─► info_submitted(审核通过,持有 auth_url) └─► enterprise_verified(e签宝 机构实名成功,已生成合同) └─► contract_applied(已申请签署,持有 contract_sign_url) ├─► contract_signed ──► completed(入驻完成) ├─► contract_rejected(拒签,可重试) └─► contract_expired(超时,可重试) ``` | 状态值 | 中文 | 进度 | 用户操作 | |--------|------|------|----------| | `pending` | 待认证 | 0% | 填写企业信息 | | `info_pending_review` | 企业信息待审核 | 15% | 等待管理员 | | `info_submitted` | 已提交企业信息 | 25% | 完成 e签宝 企业认证 | | `enterprise_verified` | 已企业认证 | 50% | 申请签署合同 | | `contract_applied` | 已申请签署 | 75% | 在 iframe 中签署 | | `contract_signed` | 已签署合同 | 100% | 等待系统处理 | | `completed` | 认证完成 | 100% | 可使用全部功能 | | `info_rejected` | 企业信息被拒绝 | — | 修正后重新提交 | | `contract_rejected` | 合同被拒签 | — | 重新申请 | | `contract_expired` | 合同签署超时 | — | 重新申请 | --- ## 4. 主要业务流程 ### 4.1 流程总览 ```mermaid flowchart TD A[用户注册/登录] --> B[POST /enterprise-info 提交企业信息] B --> C[短信验证 + 西部数据三真校验] C --> D[状态: info_pending_review] D --> E{管理员审核} E -->|拒绝| F[info_rejected] E -->|通过| G[调用 e签宝 /v3/org-auth-url] G --> H[状态: info_submitted
写入 auth_url] H --> I[iframe 完成机构实名] I --> J{确认方式} J -->|回调 AUTH_PASS| K[enterprise_verified] J -->|轮询 GET /details 或 POST /confirm-auth| K K --> L[模板填单生成合同 PDF] L --> M[POST /apply-contract 申请签署] M --> N[状态: contract_applied] N --> O[iframe 签署合同] O --> P{确认方式} P -->|POST /confirm-sign 轮询| Q[contract_signed → completed] Q --> R[下载已签文件 → 七牛 → contract_infos] R --> S[创建钱包 + API 用户] ``` ### 4.2 步骤一:提交企业信息 **接口:** `POST /api/v1/certifications/enterprise-info`(JWT + 日限流) **处理逻辑(`SubmitEnterpriseInfo`):** 1. 防重复:若已有 `info_pending_review` 记录则拒绝重复提交 2. 短信验证码校验(场景 `SMSSceneCertification`) 3. 统一社会信用代码唯一性检查(`enterprise_infos` + `enterprise_info_submit_records`) 4. 字段格式校验 + **西部数据三真**(`ValidateWithWestdex`) 5. 写入 `enterprise_info_submit_records`(状态 `verified`) 6. 认证状态转为 `info_pending_review` 7. 企业微信通知管理员待审核 > **此阶段不调用 e签宝。** **辅助接口:** - `POST /ocr/business-license` — 营业执照 OCR - `POST /upload` — 认证材料上传七牛云 ### 4.3 步骤二:管理员人工审核 **接口:** - `GET /api/v1/certifications/admin/submit-records` — 列表 - `GET /api/v1/certifications/admin/submit-records/:id` — 详情 - `POST /api/v1/certifications/admin/submit-records/:id/approve` — 通过 - `POST /api/v1/certifications/admin/submit-records/:id/reject` — 拒绝 **审核通过(`AdminApproveSubmitRecord`):** 1. 调用 `esignClient.GenerateEnterpriseAuth()` → e签宝 `POST /v3/org-auth-url` 2. 若企业已在 e签宝 实名(错误含「已实名」),则 `QueryOrgIdentityInfo` 后直接 `completeEnterpriseVerification` 3. 否则状态 → `info_submitted`,写入 `auth_flow_id`、`auth_url` 4. 提交记录 `manual_review_status` → `approved` **经办人信息:** 当前使用**法人**作为 e签宝 经办人(`TransactorName = LegalPersonName`),未使用授权代表字段。 ### 4.4 步骤三:e签宝 企业实名认证 **前端:** `EnterpriseVerify.vue` 通过 iframe 加载 `metadata.auth_url` **完成确认(双路径):** | 路径 | 触发 | 处理 | |------|------|------| | 服务端回调 | `POST /api/v1/certifications/callbacks/esign`,`action=AUTH_PASS` 且 `authType=ORG` | `HandleEsignCallback` → `completeEnterpriseVerification` | | 前端轮询 | `GET /details` 或 `POST /confirm-auth` | 查询 `GET /v3/organizations/identity-info`,`realnameStatus==1` 时推进 | **Redirect:** 用户完成后跳转 `auth.redirect_url`(如 `/certification/callback/auth`),`IframeCallback.vue` 通过 `postMessage` 通知父页面刷新状态。 **`completeEnterpriseVerification` 动作:** 1. 状态 → `enterprise_verified` 2. 企业信息写入 `enterprise_infos` 3. 调用 `FillTemplate` 填控件生成合同(见 4.5) 4. 保存 `contract_file_id`、`contract_url`、`contract_code` ### 4.5 步骤四:生成合作协议 **e签宝 API:** `POST /v3/files/create-by-doc-template` **模板控件映射:** | 控件 key | 填入内容 | |----------|----------| | `jfqym` / `jfqym2` | 企业名称 | | `jfsqdb` | 授权代表姓名(无则用法人的) | | `jftyshxydm` | 统一社会信用代码 | | `jflxdz` | 企业地址 | | `xybh` | 协议编号 | | `qsrq1` / `qsrq2` / `qsrq3` | 签署日期 | **合同编号规则:** `HYDATA-YYYYMMDD-R{6位随机数}`(R = 入驻) **过期策略:** 合同文件生成后 **50 分钟**过期,`GET /details` 时会自动重新生成(`IsContractFileNeedUpdate`)。 ### 4.6 步骤五:申请并签署合同 **接口:** `POST /api/v1/certifications/apply-contract` **前置条件:** 状态为 `enterprise_verified` **处理逻辑:** 1. `CreateSignFlow` → `POST /v3/sign-flow/create-by-file`(甲方手动签 + 乙方自动盖章) 2. `GetSignURL` → `POST /v3/sign-flow/{id}/sign-url` 3. 状态 → `contract_applied`,保存 `esign_flow_id`、`contract_sign_url` **签署确认:** - 前端 iframe 加载 `contract_sign_url`,完成后 redirect 到 `sign.redirect_url` - `POST /confirm-sign` 或 `GET /details` 轮询 `QuerySignFlowDetail` **签署状态码(业务使用):** | SignFlowStatus | 含义 | 系统动作 | |----------------|------|----------| | `2` | 签署完成 | → `contract_signed` → `completed` | | `7` | 拒签 | → `contract_rejected` | | `5` | 过期 | → `contract_expired` | | 其他 | 签署中 | 继续轮询 | ### 4.7 步骤六:入驻完成 **`handleContractAfterSignComplete`:** 1. `DownloadSignedFile` 从 e签宝 下载已签 PDF 2. 上传七牛云获取永久 URL 3. 写入 `contract_infos` 4. `completeUserActivationWithoutContract`: - 创建 `wallets` - 创建 `api_users` - 用户域标记认证完成 - 企业微信通知「企业认证成功」 --- ## 5. API 端点汇总 ### 5.1 本系统 REST API 前缀:`/api/v1/certifications` | 方法 | 路径 | 认证 | 说明 | |------|------|------|------| | GET | `/details` | JWT | 获取/创建认证详情,自动同步 e签宝 状态 | | POST | `/enterprise-info` | JWT + 日限流 | 提交企业信息 | | POST | `/ocr/business-license` | JWT | 营业执照 OCR | | POST | `/upload` | JWT | 认证材料上传 | | POST | `/confirm-auth` | JWT | 轮询确认企业实名 | | POST | `/apply-contract` | JWT | 申请合同签署 | | POST | `/confirm-sign` | JWT | 轮询确认签署状态 | | POST | `/callbacks/esign` | 无 | e签宝 服务端回调 | | GET | `` | JWT 管理员 | 认证列表 | | POST | `/admin/complete-without-contract` | 管理员 | 跳过合同直接完成认证 | | POST | `/admin/transition-status` | 管理员 | 手动变更状态 | | GET/POST | `/admin/submit-records[...]` | 管理员 | 提交记录 CRUD + 审核 | ### 5.2 e签宝 OpenAPI(SDK 封装) | 方法 | 路径 | 用途 | |------|------|------| | POST | `/v3/org-auth-url` | 获取机构认证页面链接 | | GET | `/v3/organizations/identity-info` | 查询机构是否已实名 | | POST | `/v3/files/create-by-doc-template` | 模板填单生成 PDF | | POST | `/v3/sign-flow/create-by-file` | 创建签署流程 | | POST | `/v3/sign-flow/{id}/sign-url` | 获取签署链接 | | GET | `/v3/sign-flow/{id}/detail` | 查询签署状态 | | GET | `/v3/sign-flow/{id}/file-download-url` | 下载已签署文件 | ### 5.3 前端路由 | 路由 | 说明 | |------|------| | `/profile/certification` | 企业入驻主流程(5 步) | | `/certification/callback/auth` | e签宝 认证完成 redirect | | `/certification/callback/sign` | e签宝 签署完成 redirect | | `/admin/certification-reviews` | 管理端审核列表 | --- ## 6. e签宝 配置项 配置文件:`config.yaml` / `configs/env.{development,production}.yaml` ```yaml esign: app_id: "..." # 应用 ID app_secret: "..." # 应用密钥(API 签名) server_url: "..." # 沙箱: https://smlopenapi.esign.cn # 生产: https://openapi.esign.cn template_id: "..." # 合作协议模板 ID contract: name: "海宇数据-合作协议" expire_days: 7 # 签署链接有效期(天) retry_count: 3 auth: org_auth_modes: ["PSN_MOBILE3"] default_auth_mode: "PSN_MOBILE3" psn_auth_modes: ["PSN_MOBILE3", "PSN_IDCARD"] willingness_auth_modes: ["CODE_SMS"] redirect_url: "https://console.haiyudata.com/certification/callback/auth" sign: auto_finish: true sign_field_style: 1 client_type: "ALL" redirect_url: "https://console.haiyudata.com/certification/callback/sign" ``` Go 结构:`config.EsignConfig` → 注入为 `esign.Config`(`container.go`)。 --- ## 7. 架构与代码组织 ``` hyapi-server/ ├── internal/ │ ├── application/certification/ # 应用服务(主业务编排) │ ├── domains/certification/ # 领域模型、状态机、枚举 │ ├── domains/user/entities/ # enterprise_infos, contract_infos │ ├── infrastructure/ │ │ ├── http/handlers/certification_handler.go │ │ ├── http/routes/certification_routes.go │ │ └── database/repositories/certification/ │ └── shared/esign/ # e签宝 SDK │ ├── client.go # 统一入口 │ ├── orgauth_service.go # 机构认证 │ ├── org_identity.go # 实名查询 │ ├── template_service.go # 模板填单 │ ├── signflow_service.go # 签署流程 │ └── fileops_service.go # 文件下载/状态查询 hyapi-consoleweb/ └── src/pages/certification/ ├── index.vue # 主流程容器 ├── IframeCallback.vue # e签宝 redirect 回调 └── components/ ├── EnterpriseInfo.vue # 填写企业信息 ├── ManualReviewPending.vue # 人工审核等待 ├── EnterpriseVerify.vue # e签宝 认证 iframe ├── ContractPreview.vue / ContractSign.vue └── CertificationComplete.vue ``` --- ## 8. 注意事项与已知问题 1. **回调验签未启用** `HandleEsignCallback` 中 `esign.VerifySignature` 已被注释,生产环境存在安全风险。 2. **遗留代码未接入** `internal/infrastructure/external/esign/certification_esign_service.go` 为模拟实现,未注册到 DI;`CertificationWorkflowOrchestrator` 部分方法为 stub。 3. **双路径状态同步** 企业认证支持「e签宝 回调」与「前端轮询」两条路径;合同签署主要依赖 `confirm-sign` / `GET /details` 主动查询,回调仅处理 `AUTH_PASS`。 4. **经办人默认法人** 生成认证链接时经办人使用法人信息,授权代表字段仅用于合同模板 `jfsqdb` 控件。 5. **签署状态码注释不一致** SDK 注释与业务代码对 `SignFlowStatus` 的含义存在差异,排查问题时以 `checkAndUpdateSignStatus` 中的判断为准(`2`=成功,`7`=拒签,`5`=过期)。 6. **与 API 实名产品无关** `IVYZSQ0E` / `IVYZFO5K` 等数据 API 的身份证实名校验属于 API 调用产品,与本入驻流程无关。 --- ## 9. 入驻完成后的系统能力 认证状态为 `completed` 后,用户可使用: - 钱包充值(`Wallet.vue`) - 开票申请(`Invoice.vue`) - API 调用(需 `api_users`) - IP 白名单等需认证页面(`useCertification` / `CertificationBanner` 检查 `isCertified`)