Files
jiapu/docs/superpowers/plans/2026-07-10-tac-modal-cleanup.md
T

151 lines
5.3 KiB
Markdown

# TAC 验证弹窗遮罩清理 Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** 在 TAC 验证被取消、初始化异常或接口失败时,主动关闭认证页遮罩并清空残留的验证码 DOM。
**Architecture:** `public/js/captcha-pages.js` 作为验证码弹窗生命周期的唯一拥有者,新增打开和关闭挂载容器的函数。由于原 `public.css` 不是 UTF-8,无法使用补丁安全编辑,`public/css/captcha-modal.css` 作为新增公共样式文件只根据 `is-active` 类决定遮罩显示;三张认证页继续复用同一个页面级挂载点。
**Tech Stack:** 原生 JavaScript、Node `assert` 测试、layui 提示、TAC `public/tac/js/tac.min.js`
## Global Constraints
- 计划创建时间:2026-07-10 09:10:03 +08:00。
- 仅修改 TAC 遮罩生命周期,不修改 `public/tac/js/tac.min.js`,不改变后端验证码类型选择。
- 新增或修改的 JS、CSS 注释使用中文;样式只写入 CSS 文件。
- 失败提示继续使用 `MessageUtil`/layui,禁止回退到浏览器原生 `alert`
- 503/CORS 是服务端或跨域环境可用性问题;本任务只保证前端失败后不遗留遮罩。
---
### Task 1: 用例锁定与生命周期工具
**Files:**
- Modify: `tests/captcha-pages.test.js`
- Modify: `public/js/captcha-pages.js`
**Interfaces:**
- Produces: `openCaptchaBox(box)`,清空旧内容、激活容器、设置 `aria-hidden="false"`
- Produces: `closeCaptchaBox(box)`,清空内容、取消激活、设置 `aria-hidden="true"`
- [x] **Step 1: 写失败测试**
```js
CaptchaPages.openCaptchaBox(box);
assert.strictEqual(box.classList.contains('is-active'), true);
assert.strictEqual(box.attributes['aria-hidden'], 'false');
CaptchaPages.closeCaptchaBox(box);
assert.strictEqual(box.classList.contains('is-active'), false);
assert.strictEqual(box.attributes['aria-hidden'], 'true');
assert.strictEqual(box.innerHTML, '');
```
- [x] **Step 2: 运行失败测试**
Run: `node tests\\captcha-pages.test.js`
Expected: FAIL,提示 `openCaptchaBox is not a function`
- [x] **Step 3: 实现最小生命周期函数**
```js
function openCaptchaBox(box) {
if (!box) return;
box.innerHTML = '';
box.classList.add('is-active');
box.setAttribute('aria-hidden', 'false');
}
function closeCaptchaBox(box) {
if (!box) return;
box.innerHTML = '';
box.classList.remove('is-active');
box.setAttribute('aria-hidden', 'true');
}
```
- [x] **Step 4: 将关闭函数接入 TAC 成功、取消、初始化异常和 Promise 捕获路径**
```js
if (captchaInstance && captchaInstance.destroyWindow) captchaInstance.destroyWindow();
closeCaptchaBox(box);
```
- [x] **Step 5: 运行单元测试与语法检查**
Run: `node tests\\captcha-pages.test.js; node --check public\\js\\captcha-pages.js`
Expected: 两条命令均通过。
### Task 2: CSS 显示状态收口
**Files:**
- Create: `public/css/captcha-modal.css`
- Modify: `login.html`
- Modify: `register.html`
- Modify: `forgot-password.html`
- Test: `tests/auth-page-structure.test.js`
**Interfaces:**
- Consumes: `.auth-captcha-modal.is-active`
- Produces: 默认隐藏、激活后显示的页面级遮罩。
- [x] **Step 1: 写失败结构测试**
```js
assert.ok(publicCss.includes('.auth-captcha-modal.is-active'));
assert.ok(publicCss.includes('display: none;'));
```
- [x] **Step 2: 运行失败测试**
Run: `node tests\\auth-page-structure.test.js`
Expected: FAIL,缺少 `.auth-captcha-modal.is-active` 规则。
- [x] **Step 3: 实现 CSS 状态规则**
```css
.auth-captcha-modal {
display: none;
}
.auth-captcha-modal.is-active {
display: grid;
}
```
- [x] **Step 4: 运行结构测试**
Run: `node tests\\auth-page-structure.test.js`
Expected: PASS。
### Task 3: 全量验证与记录
**Files:**
- Modify: `docs/pc-api-page-integration-tracker-2026-07-09.md`
- Modify: `docs/superpowers/plans/2026-07-10-tac-modal-cleanup.md`
- [x] **Step 1: 运行验证码相关和全量 Node 测试**
Run: `Get-ChildItem -Path tests -Filter *.test.js | Sort-Object Name | ForEach-Object { node $_.FullName }`
Expected: 所有测试通过。
- [x] **Step 2: 记录完成时间、修改文件和验证结果**
```markdown
- [x] 完成时间:YYYY-MM-DD HH:mm:ss +08:00
- [x] 验证:相关测试、语法检查、全量 Node 测试均通过。
```
## 自检
- 需求覆盖:取消后遮罩清理、失败后遮罩清理、成功后遮罩清理、CSS 显示状态和回归测试均有对应任务。
- 占位扫描:无 `TODO``TBD` 或未定义接口。
- 接口一致性:JS 导出名、测试调用名和 CSS 类名统一为 `openCaptchaBox``closeCaptchaBox``is-active`
## 完成记录
- 完成时间:2026-07-10 09:15:55 +08:00。
- 修改文件:`public/js/captcha-pages.js``public/css/captcha-modal.css``login.html``register.html``forgot-password.html``tests/captcha-pages.test.js``tests/auth-page-structure.test.js`
- 验证:`node tests\\captcha-pages.test.js``node tests\\auth-page-structure.test.js``node --check public\\js\\captcha-pages.js` 和全量 `tests/*.test.js` 均通过。
- 已知边界:测试域名的 503、CORS 或 TLS 可用性问题仍需后端或网关处理;该前端修复保证取消或异常后不残留页面遮罩。