This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
## Context
|
||||
|
||||
- 仓库当前没有归档的 `openspec/specs/`,既有变更统一使用 `## ADDED Requirements` 的 delta,本次沿用。
|
||||
- OCR 能力由 `POST /api/admin/agent-recharges/payment-voucher-ocr` 提供,语义为「凭证图片对象键 → `external_transaction_no` 预填」,员工代收款核销申请直接复用,不新增后端接口。
|
||||
- 注册接口 `POST /api/c/v1/agent-distribution-registrations` 契约中的 `shop_code` 仍为必填,改为前端生成后提交。
|
||||
|
||||
## Goals / Non-Goals
|
||||
|
||||
- Goals: 注册者自主填写店铺信息、店铺编号自动生成、用户名长度校验、免登录页不被存储检查登出、H5 可滚动;两处付款凭证支持上传后自动识别并保留手动识别。
|
||||
- Non-Goals: 不新增或修改后端接口契约;不做店铺编号前端唯一性保证(由后端唯一性校验兜底);不改变 OCR 结果只预填交易流水号的约束。
|
||||
|
||||
## Decisions
|
||||
|
||||
- Decision: 店铺编号生成规则为 `S` + `yyyyMMddHHmmss` + 3 位随机数,长度不超过后端字段上限(50)。
|
||||
- Rationale: 时间戳 + 随机数在客户端生成后碰撞概率低,且保持可读性;唯一性最终由后端校验。
|
||||
- Decision: 核销申请复用代理充值的 OCR 接口 `POST /api/admin/agent-recharges/payment-voucher-ocr`。
|
||||
- Rationale: 该接口本质是通用凭证识别,仅返回交易流水号;避免为同一能力重复定义接口。
|
||||
- Decision: 自动识别以「凭证上传成功」为触发点,取首个已上传凭证对象键,并用 `ocrLoading` 防重复触发;手动按钮逻辑不变。
|
||||
- Rationale: 首个凭证即用户主凭证,与手动识别取键规则一致,避免自动/手动结果不一致。
|
||||
- Decision: 存储兼容性检查在免登录路由上直接跳过,不执行登出。
|
||||
- Rationale: 全新浏览器无任何本地存储时,`validateStorageData()` 会判定需要重新登录并跳转登录页,破坏免登录页。
|
||||
|
||||
## Risks / Trade-offs
|
||||
|
||||
- 前端生成店铺编号可能撞号 → 采用时间戳 + 随机,后端唯一性校验兜底。
|
||||
- 复用 `agent-recharges` 路径的 OCR 接口语义略有偏差 → 接口本身为通用凭证识别,后续若后端提供独立接口可平滑替换。
|
||||
- 上传后自动识别会多一次网络请求 → 仅上传成功时触发一次,识别期间 loading 且禁止重复触发。
|
||||
|
||||
## Open Questions
|
||||
|
||||
- 无。
|
||||
@@ -0,0 +1,26 @@
|
||||
# Change: 代理注册表单调整与付款凭证上传后自动识别
|
||||
|
||||
## Why
|
||||
|
||||
代理扫码注册页当前把上级店铺的店铺名称与店铺编号从二维码 URL 带入并锁定,注册者无法填写自己的店铺信息;用户名缺少最小长度校验;未登录访问注册页时会被本地存储兼容性检查强制登出并跳转登录页;H5 下页面无法纵向滚动,超出内容不可见。同时,线下代充与员工代收款核销申请虽已支持人工识别付款凭证,但需要上传后再手动点击,且核销申请弹窗尚未提供该能力。
|
||||
|
||||
## What Changes
|
||||
|
||||
- 代理扫码注册页:店铺名称改为注册者自行填写;店铺编号由前端生成后随注册请求提交,二维码 URL 不再携带 `shop_name` / `shop_code`。
|
||||
- 代理扫码注册页:用户名校验长度必须大于 2 个字符。
|
||||
- 修复未登录访问代理注册页被跳转登录页的问题(存储兼容性检查不得对免登录页执行登出)。
|
||||
- 修复代理注册页 H5 内容超出视口后无法纵向滚动的问题。
|
||||
- 员工代收款「创建核销申请」弹窗:新增付款凭证「识别凭证」能力,并把付款凭证字段移动到外部交易流水号上方。
|
||||
- 线下代充与核销申请:付款凭证上传成功后自动识别一次交易流水号,同时保留手动「识别凭证」按钮。
|
||||
|
||||
## Impact
|
||||
|
||||
- Affected specs: `agent-distribution-registration`、`employee-collection`、`agent-recharge`
|
||||
- Affected code:
|
||||
- `src/views/agent-registration/index.vue`
|
||||
- `src/views/shop-management/detail/index.vue`
|
||||
- `src/utils/storage/storage.ts`
|
||||
- `src/assets/styles/app.scss`
|
||||
- `src/views/finance/employee-collection/applications/components/ApplicationFormDialog.vue`
|
||||
- `src/views/finance/agent-recharge/index.vue`
|
||||
- `src/components/business/VoucherUpload.vue`(如需新增上传成功事件)
|
||||
@@ -0,0 +1,38 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: 代理注册店铺信息填写与店铺编号生成
|
||||
|
||||
代理注册页 SHALL 由注册者自行填写店铺名称;店铺编号 SHALL 由前端生成并随注册请求提交为 `shop_code`;注册页 MUST NOT 从二维码 URL 带入或锁定店铺名称与店铺编号。
|
||||
|
||||
#### Scenario: 扫码进入注册页
|
||||
|
||||
- **GIVEN** 用户通过店铺分销二维码进入注册页,URL 携带 `distribution_code`
|
||||
- **WHEN** 页面初始化
|
||||
- **THEN** 店铺名称输入框 MUST 为空且可编辑
|
||||
- **AND** 店铺编号 MUST NOT 由 URL 预填或锁定
|
||||
- **AND** 分销码 MUST 由 URL 带入并锁定
|
||||
|
||||
#### Scenario: 提交注册生成店铺编号
|
||||
|
||||
- **GIVEN** 注册者已填写店铺名称与其他必填项
|
||||
- **WHEN** 其提交注册
|
||||
- **THEN** 请求体 MUST 携带前端生成的 `shop_code`
|
||||
- **AND** `shop_code` MUST 非空
|
||||
- **AND** MUST NOT 因店铺编号为空阻止提交
|
||||
|
||||
#### Scenario: 店铺名称必填
|
||||
|
||||
- **GIVEN** 注册者未填写店铺名称
|
||||
- **WHEN** 其提交注册
|
||||
- **THEN** 前端 MUST 阻止提交并提示填写店铺名称
|
||||
|
||||
### Requirement: 代理注册用户名长度校验
|
||||
|
||||
代理注册页用户名 SHALL 至少包含 3 个字符;不满足时前端 MUST 阻止提交并提示。
|
||||
|
||||
#### Scenario: 用户名长度不足
|
||||
|
||||
- **GIVEN** 注册者输入的用户名长度为 1 或 2
|
||||
- **WHEN** 其提交注册
|
||||
- **THEN** 前端 MUST 阻止提交
|
||||
- **AND** MUST 提示用户名长度必须大于 2 个字符
|
||||
@@ -0,0 +1,26 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: 线下代充付款凭证上传后自动识别
|
||||
|
||||
线下代充弹窗 SHALL 在支付凭证上传成功后自动识别一次交易流水号,同时保留手动「识别凭证」按钮;自动识别失败 MUST NOT 阻断提交,且 MUST 只预填 `external_transaction_no`。
|
||||
|
||||
#### Scenario: 上传支付凭证后自动识别
|
||||
|
||||
- **GIVEN** 线下代充弹窗已选择支付凭证
|
||||
- **WHEN** 凭证上传成功
|
||||
- **THEN** 前端 MUST 自动调用 `POST /api/admin/agent-recharges/payment-voucher-ocr`
|
||||
- **AND** 识别成功时 MUST 将返回的 `external_transaction_no` 预填入交易流水号输入框
|
||||
|
||||
#### Scenario: 保留手动识别
|
||||
|
||||
- **GIVEN** 支付凭证已上传
|
||||
- **WHEN** 用户点击「识别凭证」
|
||||
- **THEN** 前端 MUST 支持手动触发识别
|
||||
|
||||
#### Scenario: 自动识别失败不阻断
|
||||
|
||||
- **GIVEN** 自动识别返回失败或超时
|
||||
- **WHEN** 识别结束
|
||||
- **THEN** 前端 MUST NOT 阻断用户手动填写与提交
|
||||
- **AND** MUST NOT 清空用户已填写内容
|
||||
- **AND** MUST 只预填 `external_transaction_no`,不得预填金额、付款人、付款时间或备注
|
||||
@@ -0,0 +1,44 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: 核销申请付款凭证识别
|
||||
|
||||
创建核销申请弹窗 SHALL 将付款凭证字段置于外部交易流水号字段上方,并 SHALL 支持上传付款凭证后自动识别交易流水号预填,同时保留手动「识别凭证」按钮;识别结果 MUST 只作预填且保持可编辑,识别失败 MUST NOT 阻断提交或清空已填内容。
|
||||
|
||||
#### Scenario: 上传凭证后自动识别
|
||||
|
||||
- **GIVEN** 用户在创建核销申请弹窗上传付款凭证
|
||||
- **WHEN** 凭证上传成功
|
||||
- **THEN** 前端 MUST 自动调用付款凭证识别接口
|
||||
- **AND** 识别成功时 MUST 将返回的 `external_transaction_no` 预填入交易流水号输入框
|
||||
|
||||
#### Scenario: 手动识别
|
||||
|
||||
- **GIVEN** 付款凭证已上传
|
||||
- **WHEN** 用户点击「识别凭证」
|
||||
- **THEN** 前端 MUST 调用识别接口并预填交易流水号
|
||||
|
||||
#### Scenario: 识别失败不阻断
|
||||
|
||||
- **GIVEN** 识别接口返回失败或超时
|
||||
- **WHEN** 自动或手动识别结束
|
||||
- **THEN** 前端 MUST 只展示提示
|
||||
- **AND** MUST NOT 清空已填写的交易流水号
|
||||
- **AND** MUST NOT 阻止用户提交
|
||||
|
||||
#### Scenario: 字段顺序
|
||||
|
||||
- **GIVEN** 用户打开创建核销申请弹窗
|
||||
- **WHEN** 表单渲染
|
||||
- **THEN** 付款凭证字段 MUST 位于外部交易流水号字段之上
|
||||
|
||||
### Requirement: 核销申请凭证识别接口契约
|
||||
|
||||
核销申请付款凭证识别 SHALL 复用 `POST /api/admin/agent-recharges/payment-voucher-ocr`,请求体 `{ payment_voucher_key }`,响应取 `external_transaction_no`;请求超时 MUST NOT 低于 30 秒,请求期间 MUST 展示 loading 并防止重复触发。
|
||||
|
||||
#### Scenario: 识别请求契约
|
||||
|
||||
- **GIVEN** 已上传至少 1 个付款凭证
|
||||
- **WHEN** 前端发起识别
|
||||
- **THEN** 请求体 MUST 为 `{ payment_voucher_key }`,取首个已上传凭证对象键
|
||||
- **AND** 响应 MUST 只用于预填 `external_transaction_no`
|
||||
- **AND** 请求超时 MUST NOT 低于 30 秒
|
||||
@@ -0,0 +1,27 @@
|
||||
## 1. 代理注册页表单调整
|
||||
|
||||
- [x] 1.1 店铺名称改为注册者自行填写,移除从 URL 带入与锁定逻辑(`src/views/agent-registration/index.vue`)
|
||||
- [x] 1.2 店铺编号由前端生成后提交为 `shop_code`,移除 URL 带入、锁定与输入框
|
||||
- [x] 1.3 用户名增加「长度必须大于 2 个字符」校验规则与提示
|
||||
- [x] 1.4 店铺详情页注册二维码 URL 移除 `shop_name`、`shop_code` 查询参数(`src/views/shop-management/detail/index.vue`)
|
||||
|
||||
## 2. 代理注册页缺陷修复
|
||||
|
||||
- [x] 2.1 修复未登录访问注册页被跳转登录页:存储兼容性检查排除免登录路由(`src/utils/storage/storage.ts`)
|
||||
- [x] 2.2 修复 H5 页面溢出后无法纵向滚动(`src/views/agent-registration/index.vue` / `src/assets/styles/app.scss`)
|
||||
|
||||
## 3. 核销申请付款凭证识别
|
||||
|
||||
- [x] 3.1 将付款凭证字段移动到外部交易流水号字段上方(`ApplicationFormDialog.vue`)
|
||||
- [x] 3.2 新增付款凭证「识别凭证」按钮与 OCR 调用,复用 `POST /api/admin/agent-recharges/payment-voucher-ocr`
|
||||
- [x] 3.3 付款凭证上传成功后自动识别一次,保留手动识别
|
||||
- [x] 3.4 识别期间展示 loading,失败只提示且不清空已填内容、不阻断提交
|
||||
|
||||
## 4. 线下代充上传后自动识别
|
||||
|
||||
- [x] 4.1 支付凭证上传成功后自动触发一次识别,保留手动「识别凭证」按钮(`src/views/finance/agent-recharge/index.vue`)
|
||||
|
||||
## 5. 验证
|
||||
|
||||
- [x] 5.1 运行 `eslint`、`vue-tsc --noEmit`、`vite build --mode production` 均通过
|
||||
- [x] 5.2 运行 `openspec validate update-agent-registration-and-voucher-recognition --strict` 通过
|
||||
Reference in New Issue
Block a user