signup-welcome-pack.md 17 KB

注册页 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/,不修改代码、接口或配置。

用户提供的注册参考页、截图及本地 water1009 v1/water/signup.html 用于分组、卡片、商品排列和视觉参考。参考中的脚本、模拟会员、商品数据、校验与支付行为不构成业务需求,也未引入生产代码。

2. 组件与数据流

文件 职责
SignupPage.vue 组织八个表单分组、商品事件和提交状态;Sign in 返回登录并保留查询参数
welcomePackRegistration.js 维护游客草稿、查询、选择、计价、提交及支付状态,调用既有 API 和工具
SignupProducts.vue 通过 props 展示商品、数量、选择和汇总,发出 toggle、quantity、details 事件
SignupDialogs.vue 商品详情和支付弹窗;展示只读邮箱与金额,转发取消、支付回调、错误和关闭详情事件
GuestPaystack.js 局部继承 vue-paystack,加载 V2 SDK,以服务端 accessCode 恢复交易
UiSectionCard.vue 共享分组卡片,复用 Element Card,透传属性、事件与插槽
signup.spec.js 游客接口、草稿标识、计价、提交校验、订单复用和支付回调的回归用例
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。