AML/docs/justsolutionsWeb/api-calls.md

152 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# justsolutionsWeb — 后端 API 调用清单
> 本文档整理 `justsolutionsWeb`Angular 16`justsolutions-web` v1.2.0)前端对后端 API 的全部调用。
> 统计基于源码静态分析(`src/app` 下所有 `*.ts`)。
## 1. 调用架构概览
所有业务 API 调用都收口在统一的 **`HttpService`**`src/app/services/http.service.ts`
- **基地址**:请求时把相对路径拼到 `environment.apis.url` 之后,即 `environment.apis.url + request.url`
- **鉴权**:自动从 `localStorage``sessionStorage` 读取 `aml_access_token`,存在时加上请求头 `Authorization: Bearer <token>`
- **请求模型**:统一使用 `Http.Request<T>``src/app/models/http.ts`),字段含 `method` / `url` / `body` / `params` / `headers` / `responseType` 等。
> 例外:支付跳转直接 `location.href` 重定向到 QFPay 外部网关(见第 6 节),不经过 `HttpService`。
### 1.1 环境与基地址配置
| 环境文件 | `apis.url`API 基地址) | `apis.amlUrl`AML 门户来源) | `apis.test` |
|----------|--------------------------|-------------------------------|-------------|
| `environment.ts`(本地默认) | `https://api-aml.iconsz.com` | `https://aml.iconsz.com` | `true` |
| `environment.dev.ts` | `https://api-aml.iconsz.com` | `https://aml.iconsz.com` | `true` |
| `environment.prod.ts` | `https://api.justsolutions.ai` | `https://aml.justsolutions.ai` | `false` |
- `apis.amlUrl`:仅用于 `plans` 页面与父窗口AML 门户 iframe 宿主)之间的 `postMessage` 通信,并非 HTTP 端点。
- `apis.test`:为 `true` 时支付金额固定写死为 `10`(分),用于测试支付(见第 6 节)。
## 2. 调用清单(按端点汇总)
| # | 方法 | 端点(相对 `apis.url` | 用途 | 前端方法 | 所在文件 |
|---|------|--------------------------|------|----------|----------|
| 1 | POST | `/connect/token?__tenant=2C` | OAuth 取 access token | `getToken()` | `modules/aml-query/services/aml-query.service.ts` |
| 2 | GET | `/api/aml/ConsumerPortal/GetPrice/{inputCode}` | 查询消费者查询价格 | `getPrice()` | `modules/aml-query/services/aml-query.service.ts` |
| 3 | POST | `/api/amlPortal/customer/CreateFeedback` | 提交联系表单反馈 | `sendContactEmailAndReturnFeedback()` | `modules/contact/services/contact.service.ts` |
| 4 | POST | `/api/aml/emailQueue/CreateEmailQueue` | 发送通知邮件(管理员 + 用户回执两次调用) | `sendContactEmail()` / `sendContactByReturnEmail()` | `modules/contact/services/contact.service.ts` |
| 5 | POST | `/api/amlPortal/plan/portal/GetPlanList` | 获取套餐列表(基础/jQ/加人/KYC | `getAllPlanList()` | `modules/plans/services/plan.service.ts` |
| 6 | POST | `/api/amlPortal/Order/portal/GetEditionList` | 获取系统定义的 edition所属行业列表 | `getEditionList()` | `modules/plans/services/plan.service.ts` |
| 7 | POST | `/api/amlPortal/Order/getCategoryByTypes` | 获取国家/地区列表(`typeCodes: ['COUNTRY']` | `getCountryList()` | `modules/plans/services/plan.service.ts` |
| 8 | GET | `/api/identity/users/SearchUserByCodeAndType/{userCode}/true` | 校验优惠码/代理商是否存在 | `getAgentor()` | `modules/plans/services/plan.service.ts` |
| 9 | POST | `/api/amlPortal/Order/portal/queryRenewableTenant` | 查询可续费租户 | `queryTenant()` | `modules/plans/services/plan.service.ts` |
| 10 | POST | `/api/amlPortal/Order/portal/ExistsByOrganizationBRCI` | 校验商业登记号(BR)/公司编号(CI)是否已存在 | `checkBRCI()` | `modules/plans/services/plan.service.ts` |
| 11 | POST | `/api/amlPortal/customer/portal/CheckEmailExists/{email}` | 校验管理员邮箱是否已存在 | `checkEmailExist()` | `modules/plans/services/plan.service.ts` |
| 12 | POST | `/api/amlPortal/Order/portal/CreateOrder` | 新租户下单 | `createOrder()` | `modules/plans/services/plan.service.ts` |
| 13 | POST | `/api/amlPortal/Order/portal/TenantRenewal` | 租户续费下单 | `tenantRenewal()` | `modules/plans/services/plan.service.ts` |
| 14 | POST | `/api/amlPortal/Order/portal/PaymentWebhook` | 支付完成回调(作为 `notify_url` 传给 QFPay由 QFPay 服务端回调,**非前端直接调用** | — | `modules/plans/pages/tabs/plan4/plan4.component.ts` |
## 3. 鉴权OAuth Token
**端点 1** — `POST /connect/token?__tenant=2C`
- 位置:`AmlQueryService`。在该服务 **构造函数中自动触发**:当 `localStorage``aml_access_token` 时,调用 `getToken()` 并把返回的 `access_token` 写入 `localStorage`
- 请求头:`Content-Type: application/x-www-form-urlencoded`
- Body`x-www-form-urlencoded`,硬编码凭证):
| 字段 | 值 |
|------|-----|
| `grant_type` | `password` |
| `response_type` | `token` |
| `username` | `customer1` |
| `password` | `1qaz@WSX` |
| `scope` | `FX` |
| `client_id` | `customer1_client` |
| `client_secret` | `1qaz@WSX` |
> ⚠️ 用户名/密码/client secret 以明文硬编码在前端源码中(`aml-query.service.ts:47-51`),属于公开网站内置的固定访客凭证。
## 4. AML 查询模块aml-query
**端点 2** — `GET /api/aml/ConsumerPortal/GetPrice/{inputCode}`
- 调用方:`aml-query-layout.component.ts``ngOnInit` 时以 `getPrice('E')` 拉取价格)。
- 价格的真正计算逻辑在 `AmlQueryService.calculatePrice()`(本地计算,不走接口)。
> 备注:`aml-query/pages/result/result.component.ts`(评估报告页)当前使用 **本地 mock 数据 / `Math.random()`** 生成风险评估结果PDF 下载指向 `assets/sample-report.pdf``apiIntegration()` 弹窗里的 `api.credit-risk.example.com` 等仅为示例文案,**不是真实后端调用**。
## 5. 联系我们模块contact
调用方:`contact/pages/contact/contact.component.ts` 提交表单时触发。
- **端点 3** `POST /api/amlPortal/customer/CreateFeedback`:保存反馈记录。
- Body`CreateFeedbackParam``companyName`、`customerName`、`customerEmail`、`typeOfQuery`、`message`、`userHost`、`destEmail`、`emailSubject`、`emailBody`。
- **端点 4** `POST /api/aml/emailQueue/CreateEmailQueue`:进入邮件发送队列,被调用 **两次**
- `sendContactEmail()` → 通知管理员(收件人 `environment.email.contact`)。
- `sendContactByReturnEmail()` → 给提交者发送回执邮件(收件人为用户填写邮箱)。
- Body`CreateEmailQueueParam``subject`、`to`、`body`(HTML)、`businessType: 2100`、`businessId: ''`。
## 6. 套餐与下单模块plans / Order
`PlanService` 集中了套餐查询、校验与下单接口。各端点的页面调用关系:
| 端点 | 调用页面 |
|------|----------|
| `getAllPlanList()`(端点 5 | `plans.component.ts`(进入套餐页 / 收到父窗口 `postMessage` 后) |
| `getEditionList()`(端点 6 | `plans.component.ts`、`plan3.component.ts` |
| `getCountryList()`(端点 7 | `plans.component.ts`、`plan3.component.ts` |
| `getAgentor()`(端点 8 | `plan3.component.ts`(输入优惠码校验) |
| `queryTenant()`(端点 9 | `plan1.component.ts`、`plan3.component.ts`(续费选租户) |
| `checkBRCI()`(端点 10 | `plan3.component.ts` |
| `checkEmailExist()`(端点 11 | `plan1.component.ts`、`plan3.component.ts` |
| `createOrder()`(端点 12 | `plan4.component.ts``type === 'new'` |
| `tenantRenewal()`(端点 13 | `plan4.component.ts``type === 'renew'` |
关键请求体:
- **`getAllPlanList`**`GetPlanListParam``pageIndex: 0`、`pageSize: 9999`、`tag1List: ['B','jQ','j','AdlU','KYC']`、`tag2List`/`tag3List`(由调用方传入)、`agentUserId`。
- **`getCountryList`**`{ typeCodes: ['COUNTRY'] }`。
- **`checkBRCI`**:通过 `params``br` / `ci`query string
- **`createOrder`**`CreateOrderParam``planList[]``planId`/`planDetailId`/`pcs`)、`tenantName`、`tenantAdminEmail`、`jurisdiction`、`organizationBR`、`organizationCI`、`organizationReference`、`contactPerson`、`companyAddress`、`phone`、`effectiveStartTime`、`agentorId`、`isOfflinePayment: false`、`isAgentBehalf`。
- **`tenantRenewal`**`TenantRenewalParam``targetTenantID`、`planList[]`、`agentorId`、`tenantAdminEmail`、`isOfflinePayment: false`、`isAgentBehalf`。
### 6.1 支付跳转QFPay 外部网关,不经过 HttpService
位置:`plan4.component.ts` 的 `payFn()`。下单成功(`createOrder`/`tenantRenewal` 返回 `code === 0`)后:
- 若订单 `paymentStatus === 200``txamt === 0` → 直接跳转 `plans-plus/payment-success`
- 否则通过 `location.href` 重定向到 QFPay 收银台:
`https://openapi-hk.qfapi.com/checkstand/#/?<参数>&sign=<sha256>`
主要参数:
| 参数 | 值 |
|------|-----|
| `appcode` | `environment.qfpay.appcode`(固定值) |
| `goods_name` | 下单返回的 `planName` |
| `out_trade_no` | 下单返回的 `orderCode` |
| `paysource` | `remotepay_checkout` |
| `return_url` | `{baseUrl}/plans-plus/payment-success` |
| `failed_url` | `{baseUrl}/plans-plus/payment-failure` |
| `notify_url` | `{apis.url}/api/amlPortal/Order/portal/PaymentWebhook`(端点 14QFPay 服务端回调后端) |
| `txamt` | `apis.test ? 10 : planPrice * 100`(单位:分) |
| `txcurrcd` | `HKD` |
| `sign` | `sha256(<排序后的参数串> + api_key)` |
## 7. 端点前缀分布
| 前缀 | 含义 | 涉及端点 |
|------|------|----------|
| `/connect/*` | OpenIddict/IdentityServer OAuth | 端点 1 |
| `/api/aml/*` | AML 主模块(消费者查询、邮件队列) | 端点 2、4 |
| `/api/amlPortal/*` | AML 门户模块(客户、套餐、订单) | 端点 3、5、6、7、9、10、11、12、13、14 |
| `/api/identity/*` | ABP Identity用户 | 端点 8 |
## 8. 速查(按调用次序的典型流程)
- **应用启动**`AmlQueryService` 构造 → 端点 1 取 token。
- **AML 查询页加载**:端点 2 取价格。
- **联系页提交**:端点 3 + 端点 4×2
- **套餐购买流程**
1. 进入套餐页:端点 5、6、7。
2. 填写租户/续费信息:端点 8优惠码、9租户、10BR/CI、11邮箱
3. 确认下单:端点 12新购或 13续费
4. 跳转 QFPay 支付 → 支付完成后 QFPay 回调端点 14。