修改底层请求逻辑,封装请求方法
This commit is contained in:
@@ -0,0 +1,251 @@
|
||||
# Axios 公共请求层重构 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:** 删除现有 `fetch` 请求实现,以本地 Axios 浏览器版和 `utils/AxiosRequestUtil.js` 替换为唯一公共请求层,页面业务 JS 不再依赖或实现底层网络请求。
|
||||
|
||||
**Architecture:** `utils/axios.js` 是固定版本的第三方浏览器依赖;`utils/AxiosRequestUtil.js` 负责 Axios 实例、请求头、token、参数、响应解包和错误转换;`utils/ApiClient.js` 负责所有 PC 接口契约与 token 生命周期。所有页面在页面业务脚本前加载三个 utils 文件,旧 `utils/RequestUtil.js` 和 `public/js/api-client.js` 被删除且不保留兼容入口。
|
||||
|
||||
**Tech Stack:** Axios 1.7.9 浏览器非压缩构建、原生 JavaScript、Node `assert` 测试、PowerShell 静态扫描。
|
||||
|
||||
## Global Constraints
|
||||
|
||||
- 计划创建时间:2026-07-10 09:27:30 +08:00。
|
||||
- `utils` 只存通用依赖和公共请求封装;`public/js` 只存页面业务脚本,不存 API 客户端或底层请求实现。
|
||||
- 不保留 `fetch`、`fetchImpl`、`root.fetch`、`RequestUtil`、`public/js/api-client.js` 或旧脚本引用;不做 Axios/fetch 双实现兼容。
|
||||
- Axios 使用本地 `utils/axios.js`,页面运行时不依赖 CDN。
|
||||
- 普通 JSON 请求传对象给 Axios;文件上传传 `FormData`;不手写 JSON 字符串。
|
||||
- 每个请求都带 `clientid`;有 token 且 `auth !== false` 时带 `Authorization: Bearer <token>`。
|
||||
- PC-014 在本重构完成后重新执行,重构前的复核结论不作为最终证据。
|
||||
|
||||
---
|
||||
|
||||
### Task 0: 收敛环境配置职责
|
||||
|
||||
**Files:**
|
||||
- Modify: `config.js`
|
||||
- Modify: `tests/config.test.js`
|
||||
- Modify: `utils/ApiClient.js`
|
||||
|
||||
**Interfaces:**
|
||||
- Produces: `GenealogyConfig.getEnvironment()`,只返回 `development` 或 `production`。
|
||||
- Produces: `GenealogyConfig.getApiBaseUrl()`,只返回当前环境的接口基础地址。
|
||||
- Produces: `GenealogyConfig.getConfig()`,只返回 `{ environment, apiBaseUrl }`。
|
||||
- Consumes: `ApiClient` 自己定义 PC `clientId`、`tenantId`、token key 和 token header。
|
||||
|
||||
- [x] **Step 1: 写配置职责失败测试**
|
||||
|
||||
```js
|
||||
assert.deepStrictEqual(config.getConfig(), {
|
||||
environment: 'development',
|
||||
apiBaseUrl: 'http://test-genealogy-api.ddxcjp.cn'
|
||||
});
|
||||
assert.strictEqual(config.getClientId, undefined);
|
||||
assert.strictEqual(config.getTenantId, undefined);
|
||||
assert.strictEqual(config.getTokenKey, undefined);
|
||||
```
|
||||
|
||||
- [x] **Step 2: 运行测试确认旧配置职责过宽**
|
||||
|
||||
Run: `node tests\\config.test.js`
|
||||
|
||||
Expected: FAIL,旧配置仍暴露 clientId、tenantId、token key 或 token header。
|
||||
|
||||
- [x] **Step 3: 重写 config.js 为环境和域名唯一入口**
|
||||
|
||||
```js
|
||||
var environments = {
|
||||
development: { apiBaseUrl: 'http://test-genealogy-api.ddxcjp.cn' },
|
||||
production: { apiBaseUrl: 'http://test-genealogy-api.ddxcjp.cn' }
|
||||
};
|
||||
|
||||
function getConfig() {
|
||||
return {
|
||||
environment: getEnvironment(),
|
||||
apiBaseUrl: getApiBaseUrl()
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
- [x] **Step 4: 将 PC 身份和 token 常量保留在 ApiClient**
|
||||
|
||||
```js
|
||||
var DEFAULT_CLIENT_ID = 'ced7e5f0498645c6ec642dcf450b036f';
|
||||
var DEFAULT_TENANT_ID = '000000';
|
||||
var DEFAULT_TOKEN_KEY = 'genealogy_auth_token';
|
||||
var DEFAULT_TOKEN_HEADER_NAME = 'Authorization';
|
||||
```
|
||||
|
||||
补充约束:`ApiClient` 不定义接口基础地址;必须由根目录 `config.js` 的 `apiBaseUrl` 或调用方显式 `baseUrl` 提供。
|
||||
|
||||
- [x] **Step 5: 运行配置与 API 客户端测试**
|
||||
|
||||
Run: `node tests\\config.test.js; node tests\\api-client.test.js; node --check config.js; node --check utils\\ApiClient.js`
|
||||
|
||||
Expected: 所有命令通过。
|
||||
|
||||
### Task 1: 锁定 Axios 请求契约的失败测试
|
||||
|
||||
**Files:**
|
||||
- Modify: `tests/utils.test.js`
|
||||
- Modify: `tests/api-client.test.js`
|
||||
|
||||
**Interfaces:**
|
||||
- Produces: `AxiosRequestUtil.createRequester(options)`。
|
||||
- Consumes: `options.axiosInstance`,该对象实现 `request(config)`。
|
||||
- Produces: `request(method, path, { query, body, headers, auth })`,向 Axios 传入 `{ method, url, params, data, headers }`。
|
||||
|
||||
- [x] **Step 1: 把工具测试改为 Axios 假实例**
|
||||
|
||||
```js
|
||||
const axiosCalls = [];
|
||||
const requester = AxiosRequestUtil.createRequester({
|
||||
baseUrl: 'https://api.example.test',
|
||||
clientId: 'pc-client',
|
||||
getToken: () => 'token-x',
|
||||
axiosInstance: {
|
||||
request: async (config) => {
|
||||
axiosCalls.push(config);
|
||||
return { status: 200, data: { code: 200, data: { ok: true } } };
|
||||
}
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
- [x] **Step 2: 运行测试确认因旧 fetch 契约失败**
|
||||
|
||||
Run: `node tests\\utils.test.js; node tests\\api-client.test.js`
|
||||
|
||||
Expected: FAIL,提示缺少 `AxiosRequestUtil` 或仍使用 `fetchImpl`。
|
||||
|
||||
### Task 2: 创建 Axios 工具层并删除 fetch 工具层
|
||||
|
||||
**Files:**
|
||||
- Create: `utils/axios.js`
|
||||
- Create: `utils/AxiosRequestUtil.js`
|
||||
- Create: `utils/ApiClient.js`
|
||||
- Delete: `utils/RequestUtil.js`
|
||||
- Delete: `public/js/api-client.js`
|
||||
|
||||
**Interfaces:**
|
||||
- `AxiosRequestUtil.createRequester(options)` 只接受 Axios 实例,不接受 `fetchImpl`。
|
||||
- `GenealogyApi.createClient(options)` 由 `utils/ApiClient.js` 提供,只接受 `axiosInstance` 测试注入;生产环境读取 `window.axios`。
|
||||
|
||||
- [x] **Step 1: 下载固定 Axios 非压缩浏览器构建**
|
||||
|
||||
Run: `curl.exe --fail --location https://cdn.jsdelivr.net/npm/axios@1.7.9/dist/axios.js --output utils\\axios.js`
|
||||
|
||||
Expected: `utils/axios.js` 存在且首行包含 Axios 版本信息。
|
||||
|
||||
- [x] **Step 2: 实现 AxiosRequestUtil 最小请求流程**
|
||||
|
||||
```js
|
||||
var response = await axiosInstance.request({
|
||||
method: method.toLowerCase(),
|
||||
url: path,
|
||||
params: requestOptions.query,
|
||||
data: requestOptions.body,
|
||||
headers: headers
|
||||
});
|
||||
|
||||
return unwrapResponse(response.data);
|
||||
```
|
||||
|
||||
- [x] **Step 3: 从零实现 utils/ApiClient.js 并只依赖 AxiosRequestUtil**
|
||||
|
||||
```js
|
||||
var requestUtil = getAxiosRequestUtil();
|
||||
var requester = requestUtil.createRequester({
|
||||
baseUrl: baseUrl,
|
||||
clientId: clientId,
|
||||
getToken: getToken,
|
||||
axiosInstance: settings.axiosInstance || root.axios
|
||||
});
|
||||
```
|
||||
|
||||
- [x] **Step 4: 删除旧 fetch 请求文件和旧公共 API 文件**
|
||||
|
||||
Run: `Remove-Item -LiteralPath utils\\RequestUtil.js; Remove-Item -LiteralPath public\\js\\api-client.js`
|
||||
|
||||
Expected: 两个文件不存在,后续扫描无 `RequestUtil`、`fetchImpl`、`root.fetch`、`fetch(` 或 `public/js/api-client.js` 匹配。
|
||||
|
||||
- [x] **Step 5: 运行工具和 API 客户端测试**
|
||||
|
||||
Run: `node tests\\utils.test.js; node tests\\api-client.test.js; node --check utils\\AxiosRequestUtil.js; node --check utils\\ApiClient.js`
|
||||
|
||||
Expected: 所有命令通过。
|
||||
|
||||
### Task 3: 更新页面公共脚本顺序
|
||||
|
||||
**Files:**
|
||||
- Modify: 所有根目录中加载 `public/js/api-client.js` 或 `utils/ApiClient.js` 的 HTML 页面。
|
||||
- Test: `tests/auth-page-structure.test.js`
|
||||
- Test: `tests/api-script-order.test.js`
|
||||
|
||||
- [x] **Step 1: 以自动发现的脚本顺序测试锁定页面依赖**
|
||||
|
||||
```js
|
||||
assert.strictEqual(pages.length, 45);
|
||||
assert.ok(axiosIndex < axiosRequestUtilIndex);
|
||||
assert.ok(axiosRequestUtilIndex < apiClientIndex);
|
||||
assert.strictEqual(html.includes('utils/RequestUtil.js'), false);
|
||||
```
|
||||
|
||||
- [x] **Step 2: 运行测试确认旧脚本顺序不满足新契约**
|
||||
|
||||
Run: `node tests\\auth-page-structure.test.js`
|
||||
|
||||
Expected: FAIL,仍有页面加载旧 API 客户端或未加载 Axios 和 AxiosRequestUtil。
|
||||
|
||||
- [x] **Step 3: 逐页替换公共脚本引用**
|
||||
|
||||
```html
|
||||
<script src="utils/axios.js"></script>
|
||||
<script src="utils/AxiosRequestUtil.js"></script>
|
||||
<script src="utils/ApiClient.js"></script>
|
||||
```
|
||||
|
||||
- [x] **Step 4: 运行结构测试和静态扫描**
|
||||
|
||||
Run: `node tests\\auth-page-structure.test.js; rg -n "utils/RequestUtil\\.js|public/js/api-client\\.js|fetchImpl|root\\.fetch|fetch\\(" --glob "!public/tac/**" --glob "!utils/axios.js" .`
|
||||
|
||||
Expected: 测试通过,旧请求层标识无匹配。
|
||||
|
||||
### Task 4: 重跑 PC 复核并更新记录
|
||||
|
||||
**Files:**
|
||||
- Modify: `docs/pc-api-page-integration-tracker-2026-07-09.md`
|
||||
- Modify: `docs/superpowers/plans/2026-07-10-axios-request-layer-refactor.md`
|
||||
- Modify: `docs/superpowers/plans/2026-07-10-pc-tracker-reverification.md`
|
||||
|
||||
- [x] **Step 1: 运行所有 Node 测试与语法检查**
|
||||
|
||||
Run: `Get-ChildItem -Path tests -Filter *.test.js | Sort-Object Name | ForEach-Object { node $_.FullName }; node --check utils\\AxiosRequestUtil.js; node --check utils\\ApiClient.js; git diff --check`
|
||||
|
||||
Expected: 所有测试通过,语法检查和差异检查无错误。
|
||||
|
||||
- [x] **Step 2: 执行 PC-014 复核命令并记录外部网关状态**
|
||||
|
||||
Run: `curl.exe -I --max-time 15 http://test-genealogy-api.ddxcjp.cn/captcha/require`
|
||||
|
||||
Expected: 记录当次结果;仅本地验证通过的项标为“本地复核通过”,网关不可用时标注“外部环境待验证”。
|
||||
|
||||
- [x] **Step 3: 写入完成时间和清理结论**
|
||||
|
||||
Record: Axios 文件来源、删除的 `fetch` 文件、页面脚本替换范围、所有验证命令及结果。
|
||||
|
||||
## 自检
|
||||
|
||||
- 所有底层网络调用都从 `utils/AxiosRequestUtil.js` 发起。
|
||||
- `public/js` 中不含 `fetch`、Axios 实例创建或请求头拼装。
|
||||
- 所有页面在页面业务脚本前加载 `utils/axios.js`、`utils/AxiosRequestUtil.js` 和 `utils/ApiClient.js`。
|
||||
- `utils/RequestUtil.js`、`public/js/api-client.js`、`fetchImpl`、`root.fetch` 和旧页面脚本引用均不存在。
|
||||
|
||||
## 完成记录
|
||||
|
||||
- 完成时间:2026-07-10 10:10:56 +08:00。
|
||||
- Axios 来源:`axios@1.7.9/dist/axios.js` 的本地非压缩浏览器构建,存放于 `utils/axios.js`。
|
||||
- 请求契约:所有 PC 请求均由 `utils/AxiosRequestUtil.js` 通过 `axios.request` 发起;`utils/ApiClient.js` 仅封装 PC 接口和 token 生命周期。
|
||||
- 配置边界:根目录 `config.js` 是接口基础地址唯一来源;`ApiClient` 不再保存 `DEFAULT_BASE_URL`。
|
||||
- 页面范围:45 个加载接口客户端的 HTML 页面已统一脚本顺序;旧 `utils/RequestUtil.js` 和 `public/js/api-client.js` 已删除。
|
||||
- 验证:全量 Node 测试、语法检查、45 页脚本顺序检查、旧 fetch/旧脚本扫描和 `git diff --check` 均通过。
|
||||
@@ -0,0 +1,150 @@
|
||||
# PC 接口对接记录全量复核 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:** 重新验证 `pc-api-page-integration-tracker-2026-07-09.md` 中 PC-000 至 PC-013 的完成状态,并以当前代码、当前 PC YAML 和本次命令结果修正记录。
|
||||
|
||||
**Architecture:** `genealogy-pc-openapi.yaml` 的 `paths` 是接口范围唯一来源;代码和 HTML 是当前实现来源;Node 测试、语法检查和静态扫描是可重复验证来源。无法由前端离线验证的测试网关可用性明确标记为“外部环境待验证”,不将其当作页面对接完成证据。
|
||||
|
||||
**Tech Stack:** OpenAPI YAML、原生 JavaScript、Node `assert` 测试、PowerShell 静态扫描、Git 差异检查。
|
||||
|
||||
## Global Constraints
|
||||
|
||||
- 计划创建时间:2026-07-10 09:20:38 +08:00。
|
||||
- 范围仅限追踪表中状态为“已完成”或“已修正”的 PC-000 至 PC-013;不新增业务接口或页面功能。
|
||||
- 复核时不采用旧 APP 路径,不以历史测试文字代替当前命令结果。
|
||||
- 每个结论必须记录命令、结果、时间和证据边界;证据不足必须改为“复核失败/待修正”或“外部环境待验证”。
|
||||
- 仅在记录与事实不一致时修改文档;不改无关业务代码。
|
||||
|
||||
---
|
||||
|
||||
### Task 1: 复核契约和配置项
|
||||
|
||||
**Files:**
|
||||
- Modify: `docs/pc-api-page-integration-tracker-2026-07-09.md`
|
||||
- Read: `genealogy-pc-openapi.yaml`
|
||||
- Read: `config.js`
|
||||
- Read: `public/js/api-client.js`
|
||||
- Test: `tests/config.test.js`
|
||||
- Test: `tests/api-client.test.js`
|
||||
|
||||
**Covers:** PC-000、PC-001、PC-007、PC-010。
|
||||
|
||||
- [x] **Step 1: 核对 YAML 路径与客户端配置**
|
||||
|
||||
Run: `rg -n "^ /captcha/|^ /auth/code:|^ /genealogy/pc/auth/|^ /genealogy/pc/files/|^ /genealogy/region/" genealogy-pc-openapi.yaml; rg -n "test-genealogy-api|ced7e5f0498645c6ec642dcf450b036f|web_pc" config.js public/js/api-client.js`
|
||||
|
||||
Expected: 当前 YAML 只包含验证码、PC 认证、PC 文件、地区路径;代码使用当前 PC clientId 和开发环境 HTTP 基础地址。
|
||||
|
||||
- [x] **Step 2: 运行配置与 API 客户端测试**
|
||||
|
||||
Run: `node tests\\config.test.js; node tests\\api-client.test.js; node --check config.js; node --check public\\js\\api-client.js`
|
||||
|
||||
Expected: 四条命令均通过。
|
||||
|
||||
### Task 2: 复核通用工具与未覆盖业务降级
|
||||
|
||||
**Files:**
|
||||
- Modify: `docs/pc-api-page-integration-tracker-2026-07-09.md`
|
||||
- Read: `utils/StorageUtil.js`
|
||||
- Read: `utils/FormUtil.js`
|
||||
- Read: `utils/RequestUtil.js`
|
||||
- Read: `public/js/api-client.js`
|
||||
- Test: `tests/utils.test.js`
|
||||
- Test: `tests/api-client.test.js`
|
||||
|
||||
**Covers:** PC-002、PC-008。
|
||||
|
||||
- [x] **Step 1: 运行工具和 API 降级测试**
|
||||
|
||||
Run: `node tests\\utils.test.js; node tests\\api-client.test.js; rg -n "/genealogy/app/" public\\js\\api-client.js`
|
||||
|
||||
Expected: 两个测试通过,旧 `/genealogy/app/` 请求路径无匹配结果。
|
||||
|
||||
- [x] **Step 2: 核对未覆盖业务的错误边界**
|
||||
|
||||
Run: `rg -n "PC_API_NOT_AVAILABLE" public\\js\\api-client.js`
|
||||
|
||||
Expected: 未被 YAML `paths` 覆盖的业务方法统一受控失败,不生成旧 APP 网络请求。
|
||||
|
||||
### Task 3: 复核认证、验证码与资料页面
|
||||
|
||||
**Files:**
|
||||
- Modify: `docs/pc-api-page-integration-tracker-2026-07-09.md`
|
||||
- Read: `login.html`
|
||||
- Read: `register.html`
|
||||
- Read: `forgot-password.html`
|
||||
- Read: `public/js/auth-pages.js`
|
||||
- Read: `public/js/captcha-pages.js`
|
||||
- Read: `utils/MessageUtil.js`
|
||||
- Test: `tests/auth-pages.test.js`
|
||||
- Test: `tests/captcha-pages.test.js`
|
||||
- Test: `tests/auth-page-structure.test.js`
|
||||
- Test: `tests/auth-message.test.js`
|
||||
- Test: `tests/profile-pages.test.js`
|
||||
- Test: `tests/security-pages.test.js`
|
||||
|
||||
**Covers:** PC-003、PC-009、PC-011、PC-012、PC-013。
|
||||
|
||||
- [x] **Step 1: 检查认证场景、接口路径、TAC 挂载和 layui 提示**
|
||||
|
||||
Run: `rg -n "WEB_H5_LOGIN|WEB_H5_REGISTER|WEB_H5_FORGOT_PASSWORD|captcha-modal.css|auth-captcha-modal|MessageUtil|layer.msg" login.html register.html forgot-password.html public\\js\\auth-pages.js public\\js\\captcha-pages.js utils\\MessageUtil.js`
|
||||
|
||||
Expected: 三张认证页分别使用正确场景;验证码使用页面级挂载点;提示由 `MessageUtil`/layui 提供。
|
||||
|
||||
- [x] **Step 2: 运行认证和验证码测试**
|
||||
|
||||
Run: `node tests\\auth-pages.test.js; node tests\\captcha-pages.test.js; node tests\\auth-page-structure.test.js; node tests\\auth-message.test.js; node tests\\profile-pages.test.js; node tests\\security-pages.test.js; node --check public\\js\\auth-pages.js; node --check public\\js\\captcha-pages.js; node --check utils\\MessageUtil.js`
|
||||
|
||||
Expected: 所有测试和语法检查通过。
|
||||
|
||||
- [x] **Step 3: 记录网关外部依赖边界**
|
||||
|
||||
Run: `curl.exe -I --max-time 15 http://test-genealogy-api.ddxcjp.cn/captcha/require`
|
||||
|
||||
Expected: 仅记录当次 HTTP 结果;无论结果如何,不将测试网关可用性视为前端实现的通过或失败。
|
||||
|
||||
### Task 4: 复核文件与地区公共能力
|
||||
|
||||
**Files:**
|
||||
- Modify: `docs/pc-api-page-integration-tracker-2026-07-09.md`
|
||||
- Read: `public/js/upload-pages.js`
|
||||
- Read: `public/js/region-pages.js`
|
||||
- Test: `tests/upload-pages.test.js`
|
||||
- Test: `tests/region-pages.test.js`
|
||||
|
||||
**Covers:** PC-004、PC-005、PC-006。
|
||||
|
||||
- [x] **Step 1: 运行文件和地区测试**
|
||||
|
||||
Run: `node tests\\upload-pages.test.js; node tests\\region-pages.test.js; node --check public\\js\\upload-pages.js; node --check public\\js\\region-pages.js`
|
||||
|
||||
Expected: 所有测试和语法检查通过。
|
||||
|
||||
- [x] **Step 2: 扫描旧路径与页面覆盖边界**
|
||||
|
||||
Run: `rg -n "/genealogy/app/files|/genealogy/app/region" public\\js; rg -n "PC_API_NOT_AVAILABLE" public\\js\\api-client.js`
|
||||
|
||||
Expected: 文件、地区旧 APP 路径无匹配;业务页面覆盖边界仍由 `PC_API_NOT_AVAILABLE` 保护。
|
||||
|
||||
### Task 5: 全量验证与追踪表修正
|
||||
|
||||
**Files:**
|
||||
- Modify: `docs/pc-api-page-integration-tracker-2026-07-09.md`
|
||||
- Modify: `docs/superpowers/plans/2026-07-10-pc-tracker-reverification.md`
|
||||
|
||||
- [x] **Step 1: 运行全量测试和差异检查**
|
||||
|
||||
Run: `Get-ChildItem -Path tests -Filter *.test.js | Sort-Object Name | ForEach-Object { node $_.FullName }; git diff --check`
|
||||
|
||||
Expected: 所有测试通过,差异检查无空白错误。
|
||||
|
||||
- [x] **Step 2: 写入复核矩阵和最终状态**
|
||||
|
||||
Record: PC-000 至 PC-013 每项的本次复核时间、验证命令、结论和外部环境边界;任何不一致项从“已完成”改为“待修正”。
|
||||
|
||||
## 自检
|
||||
|
||||
- 覆盖范围:PC-000 至 PC-013 的所有“已完成/已修正”项均被归入一个复核任务。
|
||||
- 来源一致性:接口范围只引用 `genealogy-pc-openapi.yaml` 的 `paths`,不引用旧 APP 文档。
|
||||
- 状态规则:只有当前命令和当前代码同时支持的结论才能保留“已完成”。
|
||||
@@ -0,0 +1,84 @@
|
||||
# TAC 默认层调用纠正实施计划
|
||||
|
||||
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||||
|
||||
**目标:** 在不写任何验证码 CSS、也不修改 TAC 第三方文件的前提下,将 TAC 挂载到 Layui 默认弹层中,不再渲染到认证页底部。
|
||||
|
||||
**架构:** `auth-pages.js` 仍在表单提交时调用 `CaptchaPages.ensureToken`;`captcha-pages.js` 通过已加载的 `layui.layer.open` 创建默认容器,将该容器传给 `CaptchaConfig.bindEl`,然后原样调用 `new TAC(config)`。TAC 继续根据后端下发的 `captchaType` 自己选择滑块、旋转、拼图、文字点击或禁用态。
|
||||
|
||||
**技术栈:** Layui 内置 `layer`、`public/tac/css/tac.css`、`public/tac/js/tac.min.js`、原生 JavaScript、Node `assert` 测试。
|
||||
|
||||
## 全局约束
|
||||
|
||||
- 计划创建时间:2026-07-10 10:38:10 +08:00。
|
||||
- 不修改 `public/tac/css/tac.css`、`public/tac/js/tac.min.js` 或 Layui 第三方文件。
|
||||
- 不创建或注入任何验证码 CSS;不传 `bgUrl`、`logoUrl`、尺寸、皮肤等 TAC 视觉配置。
|
||||
- 只使用 Layui 默认 `layer.open` 作为弹层容器,TAC 的内部外观完全由其自带文件负责。
|
||||
- 只修改认证三页、验证码适配、对应测试和记录。
|
||||
|
||||
---
|
||||
|
||||
### 任务 1:锁定正确的弹层挂载契约
|
||||
|
||||
**文件:**
|
||||
- 修改:`tests/auth-page-structure.test.js`
|
||||
- 修改:`tests/captcha-pages.test.js`
|
||||
|
||||
- [x] **步骤 1:写页面结构失败测试。**
|
||||
|
||||
断言 `login.html`、`register.html`、`forgot-password.html` 不再保留 `[data-captcha-box]` 静态挂载点,且 `public/layui/layui.js` 在 `captcha-pages.js` 前加载。
|
||||
|
||||
- [x] **步骤 2:写验证码适配失败测试。**
|
||||
|
||||
断言适配层调用 `root.layui.layer.open`、在结束时调用 `root.layui.layer.close`,仍只调用 `new root.TAC(config)`,不存在自定义验证码视觉标识。
|
||||
|
||||
- [x] **步骤 3:运行测试并确认当前底部挂载实现失败。**
|
||||
|
||||
运行:`node tests\auth-page-structure.test.js; node tests\captcha-pages.test.js`
|
||||
|
||||
预期:因静态 `[data-captcha-box]` 与缺少 `layer.open` 而失败。
|
||||
|
||||
### 任务 2:使用 Layui 默认层承载 TAC
|
||||
|
||||
**文件:**
|
||||
- 修改:`login.html`
|
||||
- 修改:`register.html`
|
||||
- 修改:`forgot-password.html`
|
||||
- 修改:`public/js/captcha-pages.js`
|
||||
|
||||
- [x] **步骤 1:删除三页静态 `[data-captcha-box]`。**
|
||||
|
||||
- [x] **步骤 2:在 `captcha-pages.js` 创建无样式的 DOM 容器,并以 `layui.layer.open({ type: 1, content: mount })` 打开默认弹层。**
|
||||
|
||||
- [x] **步骤 3:将该 DOM 容器作为 `CaptchaConfig.bindEl`,并保持 `new TAC(config)` 原样调用。**
|
||||
|
||||
- [x] **步骤 4:在 TAC 成功、关闭、初始化异常和 Promise 异常时销毁 TAC 并关闭对应 Layui 层。**
|
||||
|
||||
- [x] **步骤 5:运行聚焦测试和语法检查。**
|
||||
|
||||
运行:`node tests\auth-page-structure.test.js; node tests\captcha-pages.test.js; node --check public\js\captcha-pages.js`
|
||||
|
||||
预期:全部通过。
|
||||
|
||||
### 任务 3:全量验证和记录
|
||||
|
||||
**文件:**
|
||||
- 修改:`docs/pc-api-page-integration-tracker-2026-07-09.md`
|
||||
- 修改:`docs/superpowers/plans/2026-07-10-tac-layer-call-correction.md`
|
||||
|
||||
- [x] **步骤 1:运行全量 Node 测试、静态扫描和差异检查。**
|
||||
|
||||
运行:`Get-ChildItem -Path tests -Filter *.test.js | Sort-Object Name | ForEach-Object { node $_.FullName }; rg -n "data-captcha-box|auth-captcha-modal|captcha-modal.css|bgUrl|logoUrl" login.html register.html forgot-password.html public\css public\js; git diff --check`
|
||||
|
||||
预期:测试和差异检查通过;认证页中不再有静态验证码挂载点或自定义视觉标识。
|
||||
|
||||
- [x] **步骤 2:记录完成时间、TAC 功能边界和浏览器实测边界。**
|
||||
|
||||
## 完成记录
|
||||
|
||||
- 完成时间:2026-07-10 10:44:11 +08:00。
|
||||
- 根因:TAC 的 `init()` 只向 `CaptchaConfig.bindEl` 追加组件;原先静态挂载点位于 `body` 末尾,移除定位样式后自然渲染在页面底部。
|
||||
- 修改:删除三页静态 `[data-captcha-box]`;验证码适配层使用 Layui 默认 `layer.open` 创建临时容器并传给 `bindEl`;成功、TAC 关闭、初始化异常与 Promise 异常都会清空容器并关闭同一层。
|
||||
- TAC 边界:保留原生 `new TAC(config)`、原生样式、原生刷新和后端类型分发;不传视觉配置,不写验证码 CSS,不改动任何 `public/tac` 文件。
|
||||
- 验证:失败测试已复现底部挂载;聚焦测试、全量 Node 测试、`node --check public/js/captcha-pages.js` 和 `git diff --check` 均通过。
|
||||
- 浏览器边界:未在真实测试网关完成一次有效轨迹验证;仍需在浏览器点击注册后确认 Layui 默认层居中显示及后端 `validToken` 返回。
|
||||
@@ -0,0 +1,23 @@
|
||||
# 2026-07-10 TAC 弹层居中修复计划
|
||||
|
||||
- 计划编号:PC-020
|
||||
- 开始时间:2026-07-10 11:11:05 +08:00
|
||||
- 页面范围:`login.html`、`register.html`、`forgot-password.html`
|
||||
- 接口范围:`/captcha/require`、`/captcha/challenge`、`/captcha/verify`
|
||||
- 约束:不修改 `public/tac`,不新增验证码自定义样式,不传 TAC 视觉配置,只调整 Layui 弹层调用参数。
|
||||
|
||||
## 根因
|
||||
|
||||
Layui 打开页面层时,`content` 里的验证码挂载点还是空节点;TAC 后续异步创建自己的 `#tianai-captcha-parent`,该原生外层尺寸是 `318px * 318px`。Layui 已经按空内容完成定位,所以最终验证码窗口会偏离预期位置。
|
||||
|
||||
## 执行清单
|
||||
|
||||
1. [x] 写失败测试:要求验证码弹层通过 Layui `area` 预留 `318px * 318px`,并保持默认居中。
|
||||
2. [x] 修改 `captcha-pages.js`:只给 `layer.open` 增加 TAC 原生尺寸和默认居中参数。
|
||||
3. [x] 运行焦点测试、结构测试、语法检查和空白检查。
|
||||
4. [x] 将完成结果同步回 `pc-api-page-integration-tracker-2026-07-09.md`。
|
||||
|
||||
## 验证记录
|
||||
|
||||
- 2026-07-10 11:11:05 +08:00:`node tests\captcha-pages.test.js` 已按预期失败,失败点为 `layerOptions.area` 缺失。
|
||||
- 2026-07-10 11:14:31 +08:00:修复后 `node tests\captcha-pages.test.js`、`node tests\auth-page-structure.test.js`、`node --check public\js\captcha-pages.js` 均通过;`git diff --check` 无空白错误,仅有既有 LF/CRLF 换行提示。
|
||||
@@ -0,0 +1,72 @@
|
||||
# TAC Layui 实际挂载点修复实施计划
|
||||
|
||||
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||||
|
||||
**目标:** 修复 Layui 遮罩已显示、验证码接口已返回 200,但 TAC 验证窗口仍不显示的问题。
|
||||
|
||||
**架构:** `CaptchaPages.createCaptchaLayer` 使用 Layui `layer.open` 的字符串 `content` 创建弹层内部真实挂载节点;弹层创建完成后再从 `document` 查询该实际节点,并把它交给 `CaptchaConfig.bindEl`。这样 Layui 负责弹层,TAC 挂到已经进入页面的真实 DOM。
|
||||
|
||||
**技术栈:** Layui 2.11.5、TAC 原生 CSS/JS、原生 JavaScript、Node `assert` 测试。
|
||||
|
||||
## 全局约束
|
||||
|
||||
- 计划创建时间:2026-07-10 10:59:52 +08:00。
|
||||
- 不修改 `public/tac/css/tac.css`、`public/tac/js/tac.min.js` 或 Layui 第三方文件。
|
||||
- 不新增验证码自定义 CSS,不注入样式,不传 TAC 视觉配置。
|
||||
- 保留 `auth-pages.js -> CaptchaPages.ensureToken -> TAC` 调用链,只修正弹层挂载点。
|
||||
|
||||
---
|
||||
|
||||
### 任务 1:复现“遮罩有但实际挂载点不可见”
|
||||
|
||||
**文件:**
|
||||
- 修改:`tests/captcha-pages.test.js`
|
||||
|
||||
- [x] **步骤 1:写失败测试**
|
||||
|
||||
断言 `layer.open` 的 `content` 是包含唯一 `data-captcha-layer-box` 的字符串;`createCaptchaLayer` 必须在弹层打开后从 `document.querySelector` 取到实际挂载节点并返回。
|
||||
|
||||
- [x] **步骤 2:运行失败测试**
|
||||
|
||||
运行:`node tests\captcha-pages.test.js`
|
||||
|
||||
预期:失败,当前实现仍返回打开前创建的原生 DOM。
|
||||
|
||||
### 任务 2:修正实际挂载点
|
||||
|
||||
**文件:**
|
||||
- 修改:`public/js/captcha-pages.js`
|
||||
|
||||
- [x] **步骤 1:最小实现**
|
||||
|
||||
增加内部自增 ID,用字符串内容创建 `<div data-captcha-layer-box="..."></div>`;`layer.open` 后查询该节点并作为 `box` 返回。
|
||||
|
||||
- [x] **步骤 2:运行聚焦测试**
|
||||
|
||||
运行:`node tests\captcha-pages.test.js; node --check public\js\captcha-pages.js`
|
||||
|
||||
预期:全部通过。
|
||||
|
||||
### 任务 3:记录和回归
|
||||
|
||||
**文件:**
|
||||
- 修改:`docs/pc-api-page-integration-tracker-2026-07-09.md`
|
||||
- 修改:`docs/superpowers/plans/2026-07-10-tac-layer-real-mount-fix.md`
|
||||
|
||||
- [x] **步骤 1:补充 PC-019 记录**
|
||||
|
||||
记录用户浏览器复现现象、根因、修正方式、验证命令。
|
||||
|
||||
- [x] **步骤 2:最终验证**
|
||||
|
||||
运行:`node tests\auth-page-structure.test.js; node tests\captcha-pages.test.js; node --check public\js\captcha-pages.js; git diff --check`
|
||||
|
||||
预期:全部通过;`git diff --check` 仅允许 Git 行尾提示,不允许空白错误。
|
||||
|
||||
## 完成记录
|
||||
|
||||
- 完成时间:2026-07-10 11:04:18 +08:00。
|
||||
- 根因:PC-018 只让 `layer.open` 不再因 `.parents()` 报错,但仍把打开前创建的临时 DOM 返回给 TAC;真实浏览器里 Layui 遮罩已出现,`/captcha/challenge` 也返回 200,但 TAC 没有挂到可见弹层内容区。
|
||||
- 修复:`layer.open` 使用字符串 `content` 创建弹层内部真实节点,随后通过 `document.querySelector('[data-captcha-layer-box="..."]')` 获取实际挂载点并交给 `CaptchaConfig.bindEl`。
|
||||
- 约束:未修改 `public/tac`,未新增验证码 CSS,未传 TAC 视觉配置。
|
||||
- 验证:失败测试已先复现;修复后 `node tests\captcha-pages.test.js` 和 `node --check public\js\captcha-pages.js` 通过。最终回归记录见 `docs/pc-api-page-integration-tracker-2026-07-09.md` 的 PC-019。
|
||||
@@ -0,0 +1,71 @@
|
||||
# TAC Layui content 契约修复实施计划
|
||||
|
||||
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||||
|
||||
**目标:** 修复认证页点击后只出现 `d.parents is not a function` 提示、TAC 弹层不显示的问题。
|
||||
|
||||
**架构:** `CaptchaPages.createCaptchaLayer` 继续只负责创建 Layui 默认弹层容器,不写验证码样式、不改 TAC 文件。Layui `layer.open` 的 `content` 使用 Layui/jQuery 包装对象满足弹层内部 `.parents()` 契约,TAC `bindEl` 继续使用对应的真实 DOM 节点。
|
||||
|
||||
**技术栈:** Layui 2.11.5、TAC 原生 CSS/JS、原生 JavaScript、Node `assert` 测试。
|
||||
|
||||
## 全局约束
|
||||
|
||||
- 计划创建时间:2026-07-10 10:50:06 +08:00。
|
||||
- 不修改 `public/tac/css/tac.css`、`public/tac/js/tac.min.js` 或 Layui 第三方文件。
|
||||
- 不新增验证码自定义 CSS,不注入样式,不传 TAC 视觉配置。
|
||||
- 只修正 Layui 弹层 content 契约、对应测试和记录文档。
|
||||
|
||||
---
|
||||
|
||||
### 任务 1:复现 Layui content 契约错误
|
||||
|
||||
**文件:**
|
||||
- 修改:`tests/captcha-pages.test.js`
|
||||
|
||||
- [x] **步骤 1:写失败测试**
|
||||
|
||||
断言 `createCaptchaLayer` 传给 `layui.layer.open` 的 `content` 必须是包装对象,包装对象需要保留真实 DOM 节点,并具备 `.parents()` 方法。
|
||||
|
||||
- [x] **步骤 2:运行失败测试**
|
||||
|
||||
运行:`node tests\captcha-pages.test.js`
|
||||
|
||||
预期:失败,当前实现把原生 DOM 直接传给 `content`。
|
||||
|
||||
### 任务 2:修正 createCaptchaLayer
|
||||
|
||||
**文件:**
|
||||
- 修改:`public/js/captcha-pages.js`
|
||||
|
||||
- [x] **步骤 1:最小实现**
|
||||
|
||||
在 `createCaptchaLayer` 内用 `root.layui.$ || root.$ || root.jQuery` 包装真实 DOM 节点;`layer.open({ content })` 使用包装对象;返回值中的 `box` 仍为真实 DOM,供 TAC `bindEl` 使用。
|
||||
|
||||
- [x] **步骤 2:运行聚焦测试**
|
||||
|
||||
运行:`node tests\captcha-pages.test.js; node --check public\js\captcha-pages.js`
|
||||
|
||||
预期:全部通过。
|
||||
|
||||
### 任务 3:记录和回归
|
||||
|
||||
**文件:**
|
||||
- 修改:`docs/pc-api-page-integration-tracker-2026-07-09.md`
|
||||
- 修改:`docs/superpowers/plans/2026-07-10-tac-layui-content-contract-fix.md`
|
||||
|
||||
- [x] **步骤 1:补充 PC-018 完成记录**
|
||||
|
||||
记录根因、修改文件、验证命令和结果。
|
||||
|
||||
- [x] **步骤 2:运行最终验证**
|
||||
|
||||
运行:`node tests\auth-page-structure.test.js; node tests\captcha-pages.test.js; node --check public\js\captcha-pages.js; git diff --check`
|
||||
|
||||
预期:全部通过;`git diff --check` 仅允许 Git 行尾提示,不允许空白错误。
|
||||
|
||||
## 完成记录
|
||||
|
||||
- 完成时间:2026-07-10 10:54:03 +08:00。
|
||||
- 根因:Layui 2.11.5 的 `layer.open` 在处理 DOM 内容时会调用 `.parents()`;原实现将原生 DOM 节点直接传给 `content`,导致浏览器报 `d.parents is not a function`,弹层创建中断。
|
||||
- 修复:`createCaptchaLayer` 使用 `layui.$`、`$` 或 `jQuery` 包装临时 DOM 后传给 `layer.open({ content })`,同时继续把真实 DOM 节点传给 `CaptchaConfig.bindEl`。
|
||||
- 验证:失败测试已先复现;修复后 `node tests\captcha-pages.test.js` 和 `node --check public\js\captcha-pages.js` 通过。最终回归记录见 `docs/pc-api-page-integration-tracker-2026-07-09.md` 的 PC-018。
|
||||
@@ -0,0 +1,150 @@
|
||||
# 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 可用性问题仍需后端或网关处理;该前端修复保证取消或异常后不残留页面遮罩。
|
||||
@@ -0,0 +1,85 @@
|
||||
# TAC 原生样式调用清理实施计划
|
||||
|
||||
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||||
|
||||
**目标:** 登录、注册、找回密码页面只调用 `public/tac` 自带的验证码组件和样式,不再追加任何验证码视觉样式或视觉配置。
|
||||
|
||||
**架构:** 页面保留一个无 class 的 `[data-captcha-box]` 挂载点;`captcha-pages.js` 只负责验证码接口参数和成功、取消、异常后的 DOM 清理;TAC 的外观完全由 `public/tac/css/tac.css` 与 `tac.min.js` 决定。
|
||||
|
||||
**技术栈:** 原生 JavaScript、TAC 本地组件、Node `assert` 测试。
|
||||
|
||||
## 全局约束
|
||||
|
||||
- 计划创建时间:2026-07-10 10:19:46 +08:00。
|
||||
- 不修改 `public/tac/css/tac.css` 或 `public/tac/js/tac.min.js`。
|
||||
- 不为验证码新增、覆盖或注入 CSS;不向 `new TAC` 传入 `bgUrl`、`logoUrl` 等视觉配置。
|
||||
- 仅修改登录、注册、找回密码三页及其验证码适配、测试和记录。
|
||||
|
||||
---
|
||||
|
||||
### 任务 1:用测试锁定原生 TAC 调用边界
|
||||
|
||||
**文件:**
|
||||
- 修改:`tests/auth-page-structure.test.js`
|
||||
- 修改:`tests/captcha-pages.test.js`
|
||||
|
||||
- [x] **步骤 1:将页面结构测试改为禁止自定义验证码 CSS 与容器 class。**
|
||||
|
||||
断言三页加载 `public/tac/css/tac.css`,不加载 `public/css/captcha-modal.css`,且 `[data-captcha-box]` 不含 `auth-captcha-modal` class。
|
||||
|
||||
- [x] **步骤 2:将组件测试改为要求原生构造调用。**
|
||||
|
||||
断言 `captcha-pages.js` 中不存在 `bgUrl`、`logoUrl` 与 `.auth-captcha-modal` 视觉控制。
|
||||
|
||||
- [x] **步骤 3:运行测试并确认当前实现失败。**
|
||||
|
||||
运行:`node tests\auth-page-structure.test.js; node tests\captcha-pages.test.js`
|
||||
|
||||
预期:因当前自定义验证码 CSS、容器 class 和 TAC 视觉配置而失败。
|
||||
|
||||
### 任务 2:删除自定义验证码视觉层
|
||||
|
||||
**文件:**
|
||||
- 修改:`login.html`
|
||||
- 修改:`register.html`
|
||||
- 修改:`forgot-password.html`
|
||||
- 修改:`public/css/public.css`
|
||||
- 删除:`public/css/captcha-modal.css`
|
||||
- 修改:`public/js/captcha-pages.js`
|
||||
|
||||
- [x] **步骤 1:删除三页对 `captcha-modal.css` 的引用,并将挂载点改为无 class 的 `data-captcha-box`。**
|
||||
|
||||
- [x] **步骤 2:删除 `public.css` 中 `.auth-captcha-modal` 及其 TAC 尺寸限制规则。**
|
||||
|
||||
- [x] **步骤 3:删除 `captcha-modal.css`。**
|
||||
|
||||
- [x] **步骤 4:将 `new TAC(config, { ... })` 改为 `new TAC(config)`,并将挂载点查询、打开和关闭逻辑改为无视觉状态的 DOM 清理。**
|
||||
|
||||
- [x] **步骤 5:运行两项聚焦测试并确认通过。**
|
||||
|
||||
运行:`node tests\auth-page-structure.test.js; node tests\captcha-pages.test.js; node --check public\js\captcha-pages.js`
|
||||
|
||||
预期:全部通过。
|
||||
|
||||
### 任务 3:全量验证并记录
|
||||
|
||||
**文件:**
|
||||
- 修改:`docs/pc-api-page-integration-tracker-2026-07-09.md`
|
||||
- 修改:`docs/superpowers/plans/2026-07-10-tac-native-style-cleanup.md`
|
||||
|
||||
- [x] **步骤 1:运行全量 Node 测试、验证码样式静态扫描和差异检查。**
|
||||
|
||||
运行:`Get-ChildItem -Path tests -Filter *.test.js | Sort-Object Name | ForEach-Object { node $_.FullName }; rg -n "captcha-modal.css|auth-captcha-modal|bgUrl|logoUrl" login.html register.html forgot-password.html public\css public\js; git diff --check`
|
||||
|
||||
预期:测试与差异检查通过;扫描没有自定义验证码视觉标识。
|
||||
|
||||
- [x] **步骤 2:记录完成时间、修改范围、验证结果和外部验证码实测边界。**
|
||||
|
||||
## 完成记录
|
||||
|
||||
- 完成时间:2026-07-10 10:32:20 +08:00。
|
||||
- 删除 `public/css/captcha-modal.css`,并从 `public/css/public.css` 删除 35 行 `.auth-captcha-box`、`.auth-captcha-modal` 和 TAC 尺寸限制规则。
|
||||
- 三个认证页仅加载 `public/tac/css/tac.css`,无 class 的 `[data-captcha-box]` 只作为 TAC 挂载点。
|
||||
- `captcha-pages.js` 现在只执行 `new TAC(config)`;不再传入 `bgUrl`、`logoUrl` 或切换任何视觉 class。成功、取消、初始化异常后仍清空 TAC 第三方 DOM。
|
||||
- 验证:聚焦结构/验证码测试、全量 Node 测试、`node --check public/js/captcha-pages.js`、自定义样式标识扫描和 `git diff --check` 均通过。
|
||||
- 外部边界:尚未用有效验证码轨迹完成真实服务端验证;`/captcha/verify` 的尺寸校验问题仍需以后端挑战响应原始尺寸为准单独处理。
|
||||
Reference in New Issue
Block a user