92 lines
8.0 KiB
Markdown
92 lines
8.0 KiB
Markdown
# 汇吉采「标书购买」前端清单与后端接口清单
|
||
|
||
> 阶段:**编码前最终对齐**(评估已完成;独立端 `website-huijicai` 已 fork 就绪)。
|
||
> 后端落点:**cms-api(cms-java-code)**,复用其 `shop` + `payment`;前端代理预留双后端切换。
|
||
> 对应规划:`开发计划.md` 第十节(10.1.1 前端隔离策略、10.6 拍板结果)。
|
||
|
||
---
|
||
|
||
## 一、前端清单(website-huijicai 独立端)
|
||
|
||
### 1.1 页面 / 路由
|
||
|
||
| 路由 | 文件 | 说明 | 复用/新增 |
|
||
|---|---|---|---|
|
||
| `/buy` | `app/pages/buy.vue` | 标书购买流程壳入口。**照搬 `renewal.vue` 加载 `components.BuyDocument`**,无需改 `useTemplate` 核心;`index.vue` 的 routeMap `buy` 钩子已存在 | 新增(激活入口) |
|
||
| 标书列表 | `app/templates/template-07/pages/TenderList.vue` | 列表 + 状态=onsale 筛选 + 关键词 + 分类下拉,仿 `ProductList` | 新增 |
|
||
| 标书详情 | `app/templates/template-07/pages/TenderDetail.vue` | 售价 / 招标编号 / 发售起止 / 购买按钮,仿 `ProductDetail` | 新增 |
|
||
| 购买表单 | 内嵌于 `BuyDocument` 或 `TenderDetail` | 姓名/电话/邮箱/公司,**复用 `ContactForm` 手机号校验 + 滑块验证码** | 复用 |
|
||
| 支付页 | 内嵌于 `BuyDocument` 流程 | 展示后端返回的 `code_url` 二维码 + **轮询订单状态** + 支付成功展示「下载标书」/「已发邮件」 | 新增 |
|
||
| 结果页 | 内嵌于 `BuyDocument` 流程 | 支付成功/失败/超时态 | 新增 |
|
||
| `/register`、`/login` | `app/pages/register.vue`、`login.vue` | 供应商注册/登录 + 权限门控(未登录访问 `/buy` 先跳这里) | 新增(若采用账号密码) |
|
||
| (可选)我的购买记录 | `app/templates/template-07/pages/TenderOrders.vue` | 已购标书列表 + 复下载 | 新增(P1) |
|
||
|
||
> 说明:`BuyDocument.vue` 当前是占位 stub,改为购买流程壳(列表/详情/表单/支付/结果 编排)。`TenderList/TenderDetail` 需注册进 `useTemplate` 的 `optionalComponents` 列表(仿现有 Page/NewsList 写法),并在 `supportedModules` 加 `'tender'`。
|
||
|
||
### 1.2 composable / 状态
|
||
|
||
| 名称 | 职责 | 复用/新增 |
|
||
|---|---|---|
|
||
| `useSupplier` | 供应商登录态(Token 存 cookie)+ 是否登录判断 + 购买入口门控 | 新增 |
|
||
| `useTender` | 标书列表/详情/下单/订单状态查询的接口封装 | 新增 |
|
||
| 请求层 | 调 `server/api/tender/*`(见下),不直接连后端 | 新增 |
|
||
|
||
### 1.3 Server 代理层(`website-huijicai/server/api/`)
|
||
|
||
| 代理端点 | 转发目标 | 备注 |
|
||
|---|---|---|
|
||
| `server/api/tender/list.get.ts` | `tenderApiBase/tender/list` | `tenderApiBase` 可配置,默认 cms-api |
|
||
| `server/api/tender/detail.get.ts` | `tenderApiBase/tender/detail` | |
|
||
| `server/api/tender/order.post.ts` | `tenderApiBase/tender/order` | 建单+发起支付,要求登录态 |
|
||
| `server/api/tender/order/status.get.ts` | `tenderApiBase/tender/order/status` | 轮询 |
|
||
| `server/api/tender/order/download.get.ts` | `tenderApiBase/tender/order/download` | 登录态+订单校验后转发文件 |
|
||
| `server/api/payment/query.get.ts` | `tenderApiBase/payment/query` | 支付状态查询(复用现有支付查询) |
|
||
| `server/api/supplier/login.post.ts` 等 | `tenderApiBase/...` | 仅当采用账号密码注册登录时新增 |
|
||
|
||
> **双后端兼容**:所有 `tenderApiBase` 走统一 runtimeConfig(`NUXT_TENDER_API_BASE`),默认 `https://hjc-api.websoft.top/api`;若确认交易走 guilixu-java,改 env 即可,前端代码不变。租户头 `TenantId`、JWT 透传沿用现有中间件。
|
||
|
||
---
|
||
|
||
## 二、后端接口清单(cms-java-code,新增 `tender` 包)
|
||
|
||
### 2.1 实体
|
||
|
||
| 实体 | 位置 | 字段要点 | 动作 |
|
||
|---|---|---|---|
|
||
| `Tender`(新建) | `com.gxwebsoft.tender.entity` | `id, tenantId, tenderNo`(招标编号), `title, cover, price, status`(0下架/1onsale/2ended), `startSaleTime, endSaleTime, fileId/fileUrl`(标书文件), `content, sortNumber, createTime, updateTime` | 新建 |
|
||
| `ShopUser`(复用) | `com.gxwebsoft.shop.entity` | 已有 `type/phone/email/realName/companyId/certification/tenantId`;**新增 `supplierStatus`**(0非供应商/1待认证/2已认证) | 加字段 |
|
||
| `ShopOrder`(复用) | `com.gxwebsoft.shop.entity` | 已有 `type/orderNo/payStatus/orderStatus/userId/totalPrice/tenantId` 等;标书订单用 **`type=3`** | 复用 + 扩展 type |
|
||
| `TenderOrderExt`(新建,可选) | `com.gxwebsoft.tender.entity` | `orderNo, supplierId, contactName, contactPhone, contactEmail, tenderId` | 新建(存联系人/邮箱;或扩展 `PaymentWithOrderRequest`,二选一) |
|
||
|
||
### 2.2 接口
|
||
|
||
| 接口 | 方法 | 入参 | 出参 | 复用/新建 |
|
||
|---|---|---|---|---|
|
||
| 标书列表 | `GET /api/tender/list` | `status`(默认1onsale)、`category`、`keyword`、`page`、`size` | `Tender` 分页列表(不含文件下载链接) | 新建 |
|
||
| 标书详情 | `GET /api/tender/detail` | `id` | `Tender` 详情 | 新建 |
|
||
| **创建标书订单+支付** | `POST /api/tender/order` | `tenderId`、`contactName`、`contactPhone`、`contactEmail`、`quantity`(默认1) | `orderNo`、`codeUrl`(微信扫码)、`payAmount` | **新建(编排层)**:内部①校验 `status=onsale` ②组装 `PaymentWithOrderRequest`(`type=3`,`goodsId=tenderId`,`amount=price`) ③调 `paymentService.createPaymentWithOrder(要求 loginUser)` ④落 `TenderOrderExt` ⑤返回 `codeUrl` |
|
||
| 订单状态 | `GET /api/tender/order/status` | `orderNo` | `payStatus`、`orderStatus` | 新建(包装 `GET /payment/query` 或查 `ShopOrder`) |
|
||
| 下载标书 | `GET /api/tender/order/download` | `orderNo` | 文件流 / 下载链接 | 新建:校验 `payStatus=已支付` + `loginUser=下单人` → 返回 `Tender.fileUrl`(复用 file 存储) |
|
||
| 微信异步回调 | `POST /api/payment/notify/wechat`(已有) | 微信回调报文 | 成功/失败 | **复用** `PaymentNotifyController` + `WxPayNotifyService`(置 `ShopOrder.payStatus=已支付`;标书订单 type=3 同样处理,可触发"发邮件给供应商") |
|
||
| 发起支付 | `POST /api/payment/create-with-order`(已有) | `PaymentWithOrderRequest` | `codeUrl` 等 | **复用**(内部 `WechatNativeStrategy` 返回扫码 `codeUrl`) |
|
||
| 支付查询 | `GET /api/payment/query`(已有) | `orderNo` 等 | 支付状态 | **复用** |
|
||
|
||
### 2.3 必须改造 / 注意(P0 增量)
|
||
|
||
1. **`PaymentWithOrderRequest.OrderInfo.type` 当前 `@Max(2)`**,标书订单 `type=3` 会被校验拦截 → 放开到 3,并确认支付/订单状态机对 `type=3` 的处理(不应走"发货/物流"逻辑)。
|
||
2. **会员注册/登录接口缺口**(见 10.6-2):若客户要账号密码/短信注册,需新建 `SupplierAuthController`(注册/登录/发短信),并接入现有 JWT(`JwtAuthenticationFilter`)。若客户接受微信登录,则直接复用 `WxLoginController.loginByMpWxPhone`,零新增。
|
||
3. **下单强制校验 `status=onsale`**(后端):防前端绕过筛选取已截止/未发售项目。
|
||
4. **联系人/邮箱落库**:建议新建 `TenderOrderExt`,与 `ShopOrder` 通过 `orderNo` 关联;不要污染 `ShopOrder` 通用字段。
|
||
5. **标书文件存储**:复用现有 file 模块(上传/下载/权限);`Tender.fileId` 关联文件记录。
|
||
6. **租户隔离**:`Tender`、`TenderOrderExt` 全部带 `tenantId=10626`;查询自动按当前租户过滤(沿用现有多租户拦截)。
|
||
|
||
---
|
||
|
||
## 三、阻塞编码的待确认项
|
||
|
||
1. **生产拓扑最终敲定**:cms-api 单库闭环 vs guilixu-java 双后端 → 决定 `tenderApiBase` 默认值。
|
||
2. **会员登录方式**:微信登录(免新增)vs 账号密码/短信注册(需新建 `SupplierAuthController`)→ 决定 P0 是否含注册登录接口。
|
||
3. **标书交付文件**:确认复用现有 file 模块,及文件上传入口(后台上架标书时上传)。
|
||
|
||
> 三项确认后即可进入编码:后端先落 `Tender` 实体 + `tender` 包接口(复用 shop/payment),前端在 `website-huijicai` 做 `/buy` 入口 + 流程页 + `server/api` 代理。
|