# 注册页 Welcome Pack 功能迁移 创建日期:2026-10-09 更新日期:2026-10-14 状态:注册 UI 已迁移,已接入游客查询 / 报单与站内 Paystack V2 弹窗;真实后端、订单确认和支付待联调。 第 1~6 节描述当前源码,第 7 节保留最初迁移时的验证记录,第 8 节说明本次文档核对范围。早期会员报单、删除订单、成功倒计时等行为不能继续作为当前游客注册页的实现说明。 ## 1. 授权与边界 **初始授权**:用户要求将 `src/views/user/welcome-pack.vue` 的功能迁入新注册 UI,旧页不动、优先使用 Element UI。当前入口为 `src/ui-refactor/views/signup/SignupPage.vue`。 **后续实现**:按后续需求接入游客专用接口、固定国家 / 语言选项,并调整游客支付流程;API 方法仍在 `src/api/user.js`,旧会员接口与旧页保留。本次只更新 `docs/`,不修改代码、接口或配置。 [用户提供的注册参考页](https://wangcongwang.github.io/waterng/signup.html)、截图及本地 `water1009 v1/water/signup.html` 用于分组、卡片、商品排列和视觉参考。参考中的脚本、模拟会员、商品数据、校验与支付行为不构成业务需求,也未引入生产代码。 ## 2. 组件与数据流 | 文件 | 职责 | |---|---| | [SignupPage.vue](../../src/ui-refactor/views/signup/SignupPage.vue) | 组织八个表单分组、商品事件和提交状态;Sign in 返回登录并保留查询参数 | | [welcomePackRegistration.js](../../src/ui-refactor/views/signup/components/welcomePackRegistration.js) | 维护游客草稿、查询、选择、计价、提交及支付状态,调用既有 API 和工具 | | [SignupProducts.vue](../../src/ui-refactor/views/signup/components/SignupProducts.vue) | 通过 props 展示商品、数量、选择和汇总,发出 `toggle`、`quantity`、`details` 事件 | | [SignupDialogs.vue](../../src/ui-refactor/views/signup/components/SignupDialogs.vue) | 商品详情和支付弹窗;展示只读邮箱与金额,转发取消、支付回调、错误和关闭详情事件 | | [GuestPaystack.js](../../src/ui-refactor/views/signup/components/GuestPaystack.js) | 局部继承 `vue-paystack`,加载 V2 SDK,以服务端 `accessCode` 恢复交易 | | [UiSectionCard.vue](../../src/components/ui/UiSectionCard.vue) | 共享分组卡片,复用 Element Card,透传属性、事件与插槽 | | [signup.spec.js](../../tests/unit/ui-refactor/signup.spec.js) | 游客接口、草稿标识、计价、提交校验、订单复用和支付回调的回归用例 | | [guestPaystack.spec.js](../../tests/unit/ui-refactor/guestPaystack.spec.js) | V2 SDK 加载、accessCode 恢复、取消重开、错误和回调的回归用例 | **已确认**:未通过 `extends` 或直接挂载旧 SFC 复用页面,因为旧页包含未限定作用域的表格、Tabs、Radio 样式,直接导入会污染新页面。独立业务快照避免加载这些样式,也遵守旧文件保持不动的约束。 **维护边界**:旧会员报单与新游客注册已使用不同接口和支付流程,不能把其中一份逻辑整体覆盖到另一份。计价等兼容规则需对照维护;当前没有新增统一认证缓存或改造旧页。 ## 3. 页面与组件复用 | 分组 | 字段与行为 | Element UI | |---|---|---| | Basic Information | 国家、语言、会员编号、等级、报单中心编号;保留编号只读与中心禁用条件 | Form、FormItem、Row、Col、Select、Input | | Products | 真实接口商品、图片、编号、销售价、市场价、BV、详情、选择与数量、汇总 | Card、Image、Tag、Button、InputNumber、Empty | | Network Information | 推荐人和实际推荐人均必填、可修改;邀请链接的 `ref` 默认填入两项;更改推荐人清空原实际推荐人;查询姓名仍写入状态,当前没有姓名展示控件 | Input | | Personal Information | 姓名、手机、邮箱、登录 / 支付密码、收件人和收件电话 | Input;沿用当前字段绑定与 maxlength,不将早期密码显隐记录当成当前配置 | | Delivery Method | 原 `express` / `pickup` 值及地址禁用行为 | RadioGroup、Radio | | Address Details | 原地区级联值、详细地址、城市、LGA | Cascader、Input、Textarea | | Bank Information | 银行、账户姓名、账号;虽未出现在参考截图中,仍保留旧页功能 | Select、Input | | Payment Information | 后端支付方式、现金余额与 Paystack 提示;提交后打开支付确认弹窗 | RadioGroup、Radio、Alert、Dialog、Button | - 继续使用已实现的 Hero、页脚与路由 meta;本轮不改公共外壳。 - 桌面表单两列、手机一列;商品采用 Element 栅格:≥1200px 三列、768–1199px 两列、小屏一列。 - 国家固定为 Nigeria,语言为中文 / English,选项 ID 保持字符串。进入页面不请求列表或自动加载报单;选择国家后设为该国家的默认 English,再请求游客草稿。商品与业务配置仍来自真实接口,不添加参考商品或假提交。 - 卡片、输入、选择、数量、单选、加载、提示和弹窗均采用现有 Element UI。 - Save 和商品添加按钮使用现有 Element UI `button-variant` Sass mixin,仅传入深蓝色,沿用其悬停、焦点、按下与禁用状态算法;不加载第二套主题或手写控件行为。 - 页面样式限定在 `.ng-public-layout` 与 scoped 样式;当前支付关闭不再使用删除订单确认框。 - 当前 Language、Order Level、Bank Name 的 `for` 与选择框 `id` 配对,用于标签关联,不能仅因业务代码未引用而判定无用。此前已移除未使用的表单 ref、两段注释展示代码及五项未读取的旧表单默认状态;提交 payload 中的银行地区、配送地区和 `location` 字段仍保留。 ## 4. 当前业务契约 以当前源码为准;旧计价与字段兼容规则继续保留,游客身份和支付按后续需求调整。 1. 国家 / 语言来自页面私有固定选项,不请求 `getCountries` / `getLanguages`,不依赖 Vuex 列表缓存,不修改全局当前语言。 2. 国家变化调用 `GET /v1/user/guest-dec?countryId=...`;读取 `data.draft`,会员编号来自 `draft.insertUserName`,币种优先 `draft.currency`,无值时回退首个商品的 `CODE`。支付方式优先 `payList`,兼容旧 `sellType[0].sell_type`。 3. 推荐人使用 `GET /v1/user/guest-full-info`,参数 `userName`;实际推荐人使用 `GET /v1/user/guest-inspect-network`,参数 `recommenderName` / `recommenderActualName`;姓名读取 `data.REAL_NAME`。这些方法放在 `src/api/user.js`,不影响旧会员查询方法。 4. 商品提交仍使用 `goodsId` 与 `goodsNum` 数组,`decWay: '2'`、`decType: 'normal'`、`location: 1`。 5. 汇总与余额校验使用 **MARKET_PRICE × 数量**;销售价仍展示。BV 与含税金额继续调用原算法,没有按截图改成销售价计价。 6. 保留原等级、中心编号、商品和现金余额校验;根据用户明确需求新增推荐人 / 实际推荐人必填检查,空值和纯空格阻止创建订单。不从参考页面引入额外密码、邮箱或用户名规则,后端反馈继续使用既有请求及提示机制。 7. 提交使用 `POST /v1/user/guest-dec`。在原业务字段之外,将 `draftId` 与 `accessToken` 放在请求体最外层,不嵌套为 `draft`。两项缺失时阻止提交;草稿只保存在页面内存,不写入会员缓存。 8. 提交响应按 `response.data || response` 读取订单,包含 `orderSn`、`amount`、`currency`、`reference`、`accessCode` 等支付信息;缺少 `accessCode` 或 `reference` 时显示错误。`authorizationUrl` 即使返回,当前也不用于整页跳转。 9. 当前支付由 `GuestPaystack` 加载 `https://js.paystack.co/v2/inline.js`,调用 `resumeTransaction(accessCode)`。金额用于展示,不由前端重新创建交易或按旧流程乘 100 初始化扣款;交易金额与币种由服务端交易决定。 10. 关闭弹窗仅隐藏,不删除订单。每次有效点击 Continue Payment 都重新校验当前表单并调用 `POST /v1/user/guest-dec`,成功后使用本次返回的支付信息打开弹窗;请求中阻止重复点击,失败或缺少交易标识时不打开旧支付信息。是否复用已有后台订单由接口决定。SDK 内仍防止重复打开,支付回调的 `reference` 必须与最新订单一致;随后停留注册页等待确认,不跳转 `/shop/member-order`,也没有成功倒计时。 11. `paymentComplete` 后按钮显示 Payment submitted 并禁用;这只表示前端收到了匹配回调,不代表服务端已确认注册或付款成功。 邀请链接形如 `/#/login?ref=会员ID`,登录页 Register 已透传查询参数。注册页创建时读取单个字符串 `ref`,去掉首尾空格后同时作为 `form.recUserName` 和 `form.conUserName` 的默认值;没有有效 `ref` 时留空,不猜测推荐人。初始化不触发推荐人查询或其他接口,也不反复覆盖手动修改;两项始终可编辑。手动更改推荐人仍会清空实际推荐人,需要重新填写并确认关系。Save 和 Continue Payment 都传递用户当前填写的两项。 ## 5. 新 UI 必需的适配 - 商品表格选择改为卡片按钮。页面将按钮与数量事件交给原 `handleSelectionChange` / `handleInputNumber`,不重新计算金额。 - 原表格在数据替换时清空勾选;新卡片显式清空选择和汇总,避免国家改变后提交旧列表商品。 - 提前声明 `countryId`、`languageId`、空商品数组等,保持 Vue 2 响应式初始化正常。 - 原默认选中支付列表第二项;保留该优先级,仅在单项或空列表时回退,避免读取不存在的第二项导致界面异常。 - 支付弹窗为 420px 的白色圆角容器,展示 Paystack Payment、说明、只读邮箱、带币种与千分位的金额条,以及整行 Continue to Paystack 按钮;邮箱来自 `form.email`,金额和币种来自当前订单。 - 旧 `vue-paystack` 的 V1 路径不能恢复当前服务端交易,新页通过局部继承组件使用 V2;不修改依赖或旧会员页面。组件原生按钮隐藏,由 Element 按钮调用 `payWithPaystack()`。 - 支付取消不删除订单;再次点击页面的 Continue Payment 重新请求接口获取支付信息,弹窗内 Continue to Paystack 使用本次返回的 accessCode。SDK 加载 / 交易错误继续转发至页面提示;当前没有订单删除、订单页导航或成功倒计时。 - 保留现有密码默认值与 maxlength,不在文档更新中新增业务校验或改写控件。 上述适配仅发生在新注册页,不回写旧实现。 ## 6. 待确认事项与原有行为 | 项目 | 已确认事实 / 待确认 | |---|---| | 匿名接口 | **已接入、待联调**:游客专用 GET / POST 和推荐人接口已由前端调用;服务端匿名授权、草稿有效期与异常响应仍需在授权环境验证 | | 支付完成 | **已确认**:匹配回调后留在注册页等待订单确认;前端没有服务端确认查询或独立完成页,不能把 SDK 回调当成最终付款凭证 | | 配送参数 | **已确认**:旧页提交参数没有 `way` 字段;本轮保持同一 payload。UI 切换仍改变地址禁用状态,没有擅自增加接口字段 | | 密码初始值 | **已确认**:当前仍有预设登录 / 支付密码;当前控件未配置 `type="password"` 或 `show-password`。清空默认值、调整控件及新增校验均未在本次文档任务中实施 | | 计价 | **已确认**:显示销售价与市场价,实际汇总和提交前余额校验仍按市场价计算;是否调整价格规则不属于本轮 UI 改造 | | 支付环境 | **待确认**:真实 accessCode、SDK、后端订单确认与扣款;本次未进行真实支付 | | 支付方式响应 | **待确认**:页面仍展示后端支付方式,但当前提交响应统一要求 `accessCode` / `reference`;其他方式能否返回同样契约需联调 | | 缺少配置 | **已确认**:国家 / 语言是固定选项,等级、地区、银行、商品和支付方式仍来自接口;商品空列表显示空状态 | ## 7. 原始迁移验证记录(2026-10-09) 以下结果来自最初迁移阶段,当时仍使用会员报单接口、删除订单和倒计时。它们不证明当前游客接口与 V2 支付已通过同样验证;历史命令中的旧目录也不再是当前文件位置。 - 定向 lint 覆盖公共组件、私有 JS 和新增测试:0 error / 0 warning;不修改 lint 配置。`.eslintignore` 的 `public` 会误匹配新目录,因此显式使用 `--no-ignore`。 - Jest 定向运行 `signup.spec.js`:5 项通过,涵盖计价、原有守卫、提交字段 / Paystack 订单映射、取消失败及计时器释放。 - AST 对比:13 个业务方法与旧页相同;提交 payload 完全相同;提交流程仅对数字 / 字符串 `isDec` 使用等价的显式转换。 - Vue 2.7 `vue/compiler-sfc` 编译三个新模板通过;生产构建使用当前工具链输出到临时目录,退出码 0,保留原资源体积和浏览器数据库过期提示。 - Chromium 加载生产构建,25 组交互检查通过:匿名初始化、原校验、国家 / 语言 / 等级、商品选择与数量、汇总、商品详情、推荐人、配送、支付参数、取消确认 / 删除、提交失败、余额不足、回调 / 订单导航、支付列表边界、中心禁用、切换国家重置、刷新、返回 / 历史与查询参数。 - 覆盖 320、375、768、1024、1440、2560px、320×400 短视口、长商品 / 支付名称、键盘添加和数量上下键、库存上限、输入标签与内置密码显隐;没有页面运行异常或正文横向溢出。 - 独立页面先采样未加载公共样式的登录页,再经 Register 进入注册并返回;在一致的焦点 / 鼠标状态下,登录卡片、输入框与两个按钮的几何位置和样式一致。键盘触发 Register 不发起登录请求。 - 测试图片和商品数据仅由隔离浏览器拦截返回,生产代码没有固定商品或会员。所有测试请求与 Paystack SDK 均被拦截,没有真实注册、登录或扣款。 - 本轮开始时文件哈希基线核对:既有文件中仅新注册页与公共布局说明发生变化;旧 Welcome Pack、登录、路由、守卫、API、Store 均未变化。额外核对被 Git 忽略的三个 `.env` 和 `package-lock.json`,与此前基线一致。Windows CRLF 下按 `cr-at-eol` 执行差异空白检查通过,没有改写 Git 配置或其他文件的换行。 真实后端联调和真实支付没有验证,不能据此声称匿名注册业务已上线。 ## 8. 文档核对记录(2026-10-14) 此前文档更新对照注册页、私有业务模块、支付组件、API 封装和两份回归测试更新说明,检查了相对链接与文件范围;该轮未运行 Jest、lint、构建、浏览器或后端请求,不能将测试文件存在当作测试通过。后续邀请链接功能的实现与验证另见第 9 节;真实订单确认与支付仍需授权环境验证。 ## 9. 邀请链接默认值与必填(2026-10-14) - 修改注册页、私有业务模块与相关测试,新增 `ref` 的一次性默认填充、两项可编辑 / 必填标记,以及创建订单前的空值 / 纯空格拦截;接口路径和 payload 字段未改变。 - `signup.spec.js` 与 `guestPaystack.spec.js` 共 40 项测试通过,覆盖有效 / 空 / 重复 ref、手动修改、两项缺失和空白拦截、最终推荐人参数提交及原支付回归。 - 定向 lint 为 0 error,保留 Country 标签既有的 2 条空格格式 warning;注册页模板编译通过。 - Chromium 加载当前本地开发服务,验证邀请链接经登录 Register 的 query 传递、两项默认值、编辑、必填标记、刷新、空值提示与无 ref 的全新入口。所有 API 请求均在隔离浏览器内拦截,未创建真实订单或触发支付。 - 本轮未运行生产构建;真实推荐关系校验、注册成功与支付仍需授权环境联调。 ## 10. 继续支付每次重新请求(2026-10-14) - 根据用户要求,移除 `onSubmit` 中检测到旧 accessCode 就直接打开弹窗的分支。页面的 Continue Payment 每次都经过原表单校验,再调用 `createGuestDec`;弹窗内的 Continue to Paystack 仍负责打开当前交易的收银台,商品展示组件不承载提交逻辑。 - 保留请求中防重复提交与已收到支付回调后的禁用行为;返回信息完整后才更新支付信息并打开弹窗,失败时提示并解除 loading,不使用旧交易信息打开弹窗。 - 先运行新回归用例确认旧逻辑下 4 项失败,再修改实现;两份支付 / 注册测试合计 43 项通过,覆盖连续请求、最新表单、请求并发、失败、不完整响应和原表单校验。定向 lint 为 0 error / 0 warning。 - Chromium 在本地开发服务验证两次 Continue Payment 均发送 POST、使用最新邮箱 / 商品数量并展示本次返回金额;第三次模拟失败时弹窗保持关闭。API 和 SDK 均拦截替换,没有创建真实订单或触发真实支付。 - 本轮未运行生产构建或真实后端联调,后台订单复用策略仍由接口决定;未提交或推送 Git。