# 汇吉采「标书购买」功能实现方案评估(template-07) > 目标:评估 template-07 如何支持「供应商注册 → 筛选发售中的标书项目 → 填联系人/邮箱 → 扫码付费 → 售出标书」。 > 阶段:**仅评估,未改动任何代码**。 > 后端选型已另出专文《汇吉采-标书购买-后端选型评估.md》确定:**在 cms-api(cms-java-code)内新增标书业务包,复用其 shop 订单 + payment 微信扫码支付底座**。下文早期"website-admin Java 后端"提法统一更正为 **cms-api(cms-java-code,即自研 SaaS 后端)**。 ## 0. 一句话结论 标书购买 = **前端流程页(本模板)** + **后端账号/订单/支付(cms-api,即 cms-java-code / 自研 SaaS 后端)**,二者必须配合才能闭环。 本仓库是**纯前端官网 SaaS 模板**,本身没有供应商账号、订单、支付能力,所以这部分**必须后端排期**,前端无法独立演示完整业务闭环。 但有三个已有资产可大幅复用,降低工作量: 1. `BuyDocument.vue` + `index.vue` 的 routeMap `buy` 钩子(为「标书购买」预留的入口位,当前未激活)。 2. `ProductList / ProductDetail` 模块(列表/筛选/分页/详情/价格)—— 标书项目列表可复用其结构。 3. 你 Java 后端已有的 `WxNativePayController`(微信扫码支付)+ 本模板的 `ContactForm` 表单校验链路。 --- ## 1. 现状盘点(已查代码确认) | 项 | 现状 | 证据 | |---|---|---| | 架构 | 纯前端 Nuxt SaaS 模板,业务数据经 `server/api/*` 代理到外部后台 `modulesApiBase` | `server/utils/app.ts`、`server/api/product/list.get.ts` 等 baseURL=modulesApiBase | | 注册/登录 | **无**任何用户/会员/供应商账号体系 | grep `login/register/auth/member/order/payment` 在 app/ 无真实命中 | | 订单/支付 | **无** | server/api 下无 order/payment 端点 | | 表单 | 仅有「留言表单」`/api/form/submit` → cms-contact-lead(含手机号校验、滑块验证码、频率/去重) | `server/api/form/submit.post.ts` | | 标书入口钩子 | `template-07/pages/index.vue` 的 routeMap 有 `buy → BuyDocument.vue`,但 `BuyDocument.vue` 是占位 stub("sdfsdfsdsdfbuy---"),且**当前无 Nuxt 路由名匹配 `buy`**,访问 `/buy` 会落进 `[slug].vue` 渲染 Page,不会命中 BuyDocument | `index.vue:24`、`BuyDocument.vue`、`app/pages/` 无 buy 路由 | | 续费付费雏形 | `renewal` 路由 = `app/pages/renewal.vue` 加载 `components.Renewal`(空白布局),点击「立即续费」跳 `/api/subscription/renew` 到后台 | `app/pages/renewal.vue`、`Renewal.vue` | **关键推论**:`buy` 入口的激活方式应**完全照搬 `renewal` 的模式**——在 `app/pages/` 新增 `buy.vue`,加载 `components.BuyDocument`(参照 `renewal.vue` 加载 `Renewal`)。这样无需改 `useTemplate` 核心,仅把 BuyDocument 从占位 stub 改成真正的购买流程页即可。 --- ## 2. 需求拆解 → 前后端职责 | 需求 | 前端(本模板改造) | 后端(cms-api / cms-java-code,复用 shop+payment 底座) | |---|---|---| | ① 供应商注册后才可购买 | 注册页 + 登录页 + 登录态管理(`useSupplier` composable,Token 存 cookie)+ **购买入口权限门控** | 供应商账号体系:注册、登录、会话/Token、企业信息(公司名、统一信用代码、联系人)、"已注册/已认证"状态 | | ② 筛选正在发售上架的项目 | 标书项目列表页(状态=发售中筛选、关键词、分类下拉)+ 详情页(售价、招标编号、发售起止、购买按钮) | `tender` 标书数据模型 + 状态字段(onsale/ended)+ 按 `status/category/keyword` 查询接口 | | ③ 填联系人/邮箱 | 购买表单:姓名、电话、邮箱、公司(**复用 `ContactForm` 的手机号校验 + 滑块验证码**) | 订单创建接口(绑定 项目 + 供应商 + 联系人信息) | | ④ 扫码付费售出标书 | 支付页:展示微信二维码 + **轮询订单状态** + 支付成功后展示「下载标书」/「已发送至邮箱」 | 微信 Native 支付下单(返回 `code_url`)、异步回调 `notify`、支付成功后标记订单、交付标书(下载链接 / 发邮件) | --- ## 3. 关键决策点(需你拍板) ### D1. 标书项目数据如何建模 - **方案 A:复用现有 `product` 模块** —— 把标书当一种 product,加自定义字段(招标编号、发售起止、标书状态)。改动最小,但 product 语义被污染,且"发售中"筛选需后端额外给状态字段。 - **方案 B(推荐):新增独立 `tender` 模块** —— 仿照 article/product/case,后端新增 tender 实体,前端新增 `TenderList / TenderDetail`,注册进 routeMap + `useTemplate` 可选组件。语义清晰、可扩展(后续接购买记录、电子发票)。列表/筛选/详情 UI 可大量复制 ProductList/ProductDetail 代码。工作量中等。 ### D2. 供应商账号体系(已确认可复用,非从零新建) - 选型评估已查实:cms-api(cms-java-code)的 `shop` 模块**已有完整用户/会员体系**(`ShopUser`、登录态、`JwtAuthenticationFilter`、下单要求 `loginUser != null`)。标书购买无需从零造账号体系,**直接复用现有用户体系 + 加 `supplier` 角色/字段**即可。 - 建议注册方式:手机号 + 短信验证码,或账号密码;企业信息:公司名、统一社会信用代码、联系人。 - **请确认**:供应商是复用 shop 会员表(加角色/字段),还是新建独立 `supplier` 表?建议前者,省一套登录态。 ### D3. 支付渠道 - "扫码付费" → **微信 Native 支付(扫码支付)** 最契合,你后端已有 `WxNativePayController`,直接复用,风险最低。 - 备选:支付宝当面付(同为二维码)。建议先微信。 - 需确认:商户号、`notify_url` 公网回调域名、费率。 ### D4. 标书交付方式 - 支付成功后建议**双通道**:① 页面直接出「下载标书」按钮(限时 / 登录态保护);② 同步发邮件到步骤③填写的邮箱。文件走现有 `server/api/file` 上传/下载通道。 - 可选:后台「我的购买记录」页,便于供应商复取下架前的标书。 ### D5. 权限门控放哪 - 在 `buy` 入口(导航「购买标书」)加门控:未登录 → 引导注册/登录;已登录 → 进入标书列表。复用现成 routeMap `buy` 钩子(把 `BuyDocument.vue` 改成购买流程页)。 --- ## 4. 推荐落地架构(端到端流程) ``` [供应商访问] │ 未登录? ├─ 是 → /register 或 /login(后端 supplier 表)──┐ │ │ └─ 否 ─────────────────────────────────────────┘ │ ▼ /buy (BuyDocument 改为购买流程壳,照搬 renewal 激活方式) │ ▼ 标书项目列表(后端 tender 接口,status=onsale + 分类/关键词筛选) │ 选一个 ▼ 标书详情(售价、招标编号、发售起止)→ 点「购买」 │ ▼ 填写联系人/邮箱(复用 ContactForm 校验)→ 调后端「创建订单」 │ ▼ 后端调微信下单 → 返回 code_url → 前端渲染二维码 │ ▲ │ 用户微信扫码支付 │ 轮询订单状态 ▼ │ 微信异步通知 notify → 订单置「已支付」─────┘ │ ▼ 支付成功页:展示「下载标书」+ 后端发邮件到供应商邮箱 │ ▼ (可选)我的购买记录 ``` **多租户**:标书/订单需带 `tenantId` 隔离。本模板已有 tenant 中间件(`server/middleware/tenant.ts`),后端直接复用即可。 --- ## 5. 工作量与分期(评估,未写代码) - **P0 后端(必须,最先排期)** - supplier 账号体系(注册/登录/会话) - tender 标书数据模型 + 列表/详情/筛选接口 - order 订单 + 微信支付下单 + 异步回调 + 标书交付 - 工作量取决于 D2(是否复用已有会员体系)。 - **P0 前端** - `app/pages/buy.vue`(激活入口,照搬 renewal) - `BuyDocument.vue` 改为购买流程页(列表 + 详情 + 表单 + 支付二维码 + 结果) - `register.vue` / `login.vue` + `useSupplier` 登录态 composable + 权限门控 - **P1(上线后增强)** - 我的购买记录、邮件模板、后台标书上架审核(若标书需审核后发售)。 --- ## 6. 风险 / 阻塞 1. **最大阻塞**:本模板无后端账号/订单/支付,标书购买必须 cms-api 后端排期(虽有 shop/payment 底座,仍需新增 `tender` 业务包与流程编排),前端无法独立演示完整闭环。 2. **CMS 写入 token 不稳定**:汇吉采落地清单已记录 cms-api 写接口偶发 401(`JWT signature does not match`)。建议标书走**独立 tender 业务接口**,而非 CMS 内容接口,规避此问题。 3. **微信回调需公网域名**:本地开发用内网穿透或微信沙箱。 4. **权限边界**:供应商仅能买"发售中"的标书,后端下单时需校验项目状态,防止前端绕过筛选取已截止项目。 --- ## 7. 建议的下一步 1. 确认 **D1–D5** 决策,尤其 **后端选型(已在《后端选型评估》中定:在 cms-api 新增,复用 shop/payment)**、**D2(供应商复用 shop 会员体系)** 和 **D3(微信商户号是否就绪)**。 2. 决策明确后,我可进入下一阶段产出(仍先评估、不写功能代码): - 标书购买流程图(已附于第 4 节) - 前端页面清单与路由映射 - 后端接口清单(供你排期) 3. 全部对齐后再开始写代码。