Files
integral-shop/docs/integral-pages-coding-plan.md
scott ee0886b800 feat: 新增积分外部页面(免认证三页 + 配套基础设施)
前端:
- 新增 EmptyLayout 空壳布局(无侧边栏/导航)
- 新增 requestNoAuth Axios 实例(不注入 token)
- 新增 integralExternal 路由模块(/integral-external/*)
- permission.js 加入 whiteListPrefixes 前缀白名单跳过登录
- 新增 phoneDesensitize 手机号脱敏过滤器
- 新增三个免认证页面:
  · 积分订单页(/integral-external/order)
  · 用户积分页(/integral-external/user,手机号脱敏)
  · 用户积分明细子页(/integral-external/user/integral-detail)

后端:
- 新增 ExternalIntegralController(无 @PreAuthorize)
  · GET  /api/external/integral/order/list
  · GET  /api/external/integral/user/list
  · POST /api/external/integral/log/list
- WebSecurityConfig 加入 /api/external/integral/** permitAll

文档与工具:
- 新增 coding plan、schedule、测试报告
- 新增 start-backend.sh / start-frontend.sh 本地启动脚本
- 新增 .mvn/wrapper/maven-wrapper.properties

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 10:41:30 +08:00

627 lines
23 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 积分模块新增页面 — Coding Plan
> 版本v1.0
> 日期2026-03-30
> 范围管理后台backend-adminend新增积分订单、用户积分、用户积分明细三个独立页面
---
## 1. 需求概述
在管理后台中新增三个独立页面,用于积分业务的外部查看与运营。所有页面需跳过用户登录验证,按后端 API 最小修改原则,尽量复用现有后端接口。
| 序号 | 页面 | 参考原页面 | 说明 |
|------|------|-----------|------|
| 1 | 积分订单 | `/order/index` | 新建独立页面,展示积分相关订单 |
| 2 | 用户积分 | `/user/index` | 新建独立页面,增加 `wa_users` 相关字段 |
| 3 | 用户积分明细 | 用户管理 → 账户详情 → 积分明细 | 子页面,复用 `/admin/user/integral/list` 接口 |
---
## 2. 技术架构分析
### 2.1 技术栈
管理后台前端基于 Vue 2 + Vue CLI + Element UI + Vue Router (history mode) + Vuex + Axios。
### 2.2 现有认证机制
认证逻辑位于 `src/permission.js`,通过 `router.beforeEach` 全局守卫实现。未登录时除白名单路由外,一律重定向至 `/login`
白名单当前值:`['/login', '/auth-redirect']`
请求拦截器(`src/utils/request.js`)会在 header 中附加 `Authori-zation` token后端返回 401 时自动跳转登录页。
### 2.3 关键参考文件
| 文件 | 说明 |
|------|------|
| `src/views/order/index.vue` | 订单列表页,约 40k 行,含筛选/表格/分页/操作 |
| `src/views/user/list/index.vue` | 用户管理页,含多条件筛选、用户详情弹窗 |
| `src/views/user/integral/index.vue` | 积分日志页242 行),表格 + 搜索 + 分页 |
| `src/api/integral.js` | 积分接口:`integralListApi` → POST `/admin/user/integral/list` |
| `src/api/user.js` | 用户接口:`userListApi` → GET `/admin/user/list` |
| `src/router/modules/order.js` | 订单路由定义 |
| `src/router/modules/user.js` | 用户路由定义 |
| `src/router/index.js` | 主路由,含 `constantRoutes` 和白名单 |
| `src/permission.js` | 全局路由守卫(登录校验) |
| `src/utils/request.js` | Axios 封装token 注入 & 401 拦截 |
### 2.4 wa_users 表字段(需要在用户积分页展示)
| 字段 | 类型 | 说明 |
|------|------|------|
| `id` | int | 主键 |
| `username` | string | 用户名 |
| `nickname` | string | 昵称 |
| `mobile` | string | 手机号 |
| `money` | BigDecimal | 账户余额 |
| `selfBonus` | BigDecimal | 个人奖金 |
| `shareBonus` | BigDecimal | 分享奖金 |
| `score` | BigDecimal | 积分 |
| `level` | int | 等级 |
| `status` | int | 状态0=禁用, 1=启用) |
| `isVip` | int | VIP0=否, 1=是) |
| `isResell` | int | 可转卖0=否, 1=是) |
| `joinTime` | timestamp | 注册时间 |
| `lastTime` | timestamp | 最后登录 |
---
## 3. 整体方案设计
### 3.1 目录结构规划
```
src/
├── views/
│ └── integral-external/ # 新增:积分外部页面目录
│ ├── order/
│ │ └── index.vue # 积分订单页面
│ ├── user/
│ │ └── index.vue # 用户积分页面
│ └── user-integral-detail/
│ └── index.vue # 用户积分明细子页面
├── api/
│ └── integralExternal.js # 新增:积分外部页面 API 集合
├── router/
│ └── modules/
│ └── integralExternal.js # 新增:积分外部路由模块
└── layout/
└── EmptyLayout.vue # 新增:空白布局(无侧边栏/顶栏)
```
### 3.2 跳过登录验证方案
采用**多层级免登录**策略,确保页面完全绕过认证:
**第一层:路由白名单**
`src/permission.js``whiteList` 中添加新页面路径前缀:
```js
const whiteList = ['/login', '/auth-redirect', '/integral-external'];
```
同时修改白名单匹配逻辑,从精确匹配改为前缀匹配:
```js
// 修改前
if (whiteList.indexOf(to.path) !== -1)
// 修改后
if (whiteList.some(path => to.path.startsWith(path)))
```
**第二层:无 token 请求支持**
新建一个不注入 token、不拦截 401 的 Axios 实例 `requestNoAuth`,供外部页面 API 使用:
```js
// src/utils/requestNoAuth.js
import axios from 'axios';
import { Message } from 'element-ui';
import SettingMer from '@/utils/settingMer';
const service = axios.create({
baseURL: SettingMer.apiBaseURL,
timeout: 60000,
});
// 不注入 token不拦截 401 跳转
service.interceptors.response.use(
(response) => {
const res = response.data;
if (res.code !== 0 && res.code !== 200) {
Message({ message: res.msg || '请求失败', type: 'error' });
return Promise.reject(new Error(res.msg || '请求失败'));
}
return res.data;
},
(error) => {
Message({ message: '网络请求失败', type: 'error' });
return Promise.reject(error);
},
);
export default service;
```
**第三层:空白布局**
新建 `EmptyLayout.vue`,不包含侧边栏、顶栏和权限组件,作为外部页面的容器:
```vue
<template>
<div class="integral-external-layout">
<router-view />
</div>
</template>
```
---
## 4. 各页面详细设计
### 4.1 积分订单页面
**路由**`/integral-external/order`
**参考**`src/views/order/index.vue`
#### 功能要点
从原订单页面中提取积分订单相关的核心功能,去除权限校验(`v-hasPermi`)和管理操作(编辑、发货、退款等),保留只读展示。
#### 筛选条件
| 筛选项 | 类型 | 说明 |
|--------|------|------|
| 订单状态 | RadioGroup | 全部/未支付/未发货/待收货/交易完成 等 |
| 时间选择 | DateRangePicker | 快捷选项 + 自定义范围 |
| 订单号 | Input | 精确搜索 |
#### 表格列
| 列 | 字段 | 宽度 |
|----|------|------|
| 订单号 | `orderId` | 210 |
| 订单类型 | `orderType` | 110 |
| 收货人 | `realName` | 100 |
| 商品信息 | `productList` | 400 |
| 支付金额 | `payPrice` | 100 |
| 支付方式 | `payType` | 100 |
| 订单状态 | `status` | 100 |
| 创建时间 | `createTime` | 150 |
#### API 复用
直接复用现有订单列表接口。需确认后端是否允许无 token 调用,若不允许,需后端新增一个免认证的订单查询接口(或在已有接口上增加免认证标注)。
```js
// src/api/integralExternal.js
export function getIntegralOrderList(params) {
return requestNoAuth({
url: '/admin/order/list', // 复用原接口或后端新增免认证接口
method: 'get',
params,
});
}
```
#### 实现步骤
1. 复制 `order/index.vue` 为基础模板
2. 删除所有 `v-hasPermi` 权限指令
3. 删除操作列(编辑价格、发货、退款等按钮)
4. 删除导出功能
5. 将 API 调用替换为 `requestNoAuth` 版本
6. 简化订单类型筛选,只保留积分相关类型
7. 去除 Vuex store 依赖
---
### 4.2 用户积分页面
**路由**`/integral-external/user`
**参考**`src/views/user/list/index.vue`
#### 功能要点
基于用户列表页精简,增加 `wa_users` 表的积分/奖金相关字段展示,提供积分明细跳转入口。
#### 筛选条件
| 筛选项 | 类型 | 说明 |
|--------|------|------|
| 用户搜索 | Input | 姓名/手机号/用户名 |
| 时间选择 | DateRangePicker | 注册时间范围 |
#### 表格列
| 列 | 字段 | 来源 | 说明 |
|----|------|------|------|
| 用户ID | `uid` | CRMEB | 系统用户ID |
| 用户昵称 | `nickname` | CRMEB | — |
| 手机号 | `phone` | CRMEB | — |
| 系统积分 | `integral` | CRMEB | CRMEB 系统积分 |
| WA用户名 | `wa_username` | wa_users | WA系统用户名 |
| 账户余额 | `wa_money` | wa_users | WA账户余额 |
| 个人奖金 | `wa_selfBonus` | wa_users | 可提现奖金 |
| 分享奖金 | `wa_shareBonus` | wa_users | 推荐奖金 |
| WA积分 | `wa_score` | wa_users | WA系统积分 |
| 用户等级 | `wa_level` | wa_users | — |
| 状态 | `wa_status` | wa_users | 启用/禁用 |
| 注册时间 | `createTime` | CRMEB | — |
| 操作 | — | — | 查看积分明细 |
#### API 方案
**方案 A推荐 — 最小后端修改)**:前端分别调用用户列表接口和 WA 用户信息接口,在前端做数据合并。
```js
// 复用原用户列表
export function getUserListNoAuth(params) {
return requestNoAuth({
url: '/admin/user/list',
method: 'get',
params,
});
}
// 复用前端 WA 用户信息接口(需确认是否免认证)
export function getWaUserInfo(userId) {
return requestNoAuth({
url: '/api/front/wa/user/info',
method: 'post',
data: { userId },
});
}
```
**方案 B若后端配合**:后端新增一个聚合接口,一次性返回 CRMEB 用户 + wa_users 的合并数据。
#### 操作列
"查看积分明细" 按钮,点击后跳转至用户积分明细子页面,携带 `uid` 参数:
```js
this.$router.push({
path: '/integral-external/user/integral-detail',
query: { uid: row.uid },
});
```
#### 实现步骤
1.`user/list/index.vue` 为参考创建精简版页面
2. 删除所有权限指令、分组/标签/等级筛选、操作按钮(编辑、设为分销员等)
3. 删除 Tab 切换(全部/有效/无效用户)
4. 在表格中增加 wa_users 字段列
5. 实现前端数据合并逻辑(逐行匹配或批量查询)
6. 添加"查看积分明细"操作按钮
7. 将所有 API 替换为 `requestNoAuth` 版本
---
### 4.3 用户积分明细子页面
**路由**`/integral-external/user/integral-detail`
**参考**`src/views/user/integral/index.vue`242 行)
**后端 API**POST `/admin/user/integral/list`(复用)
#### 功能要点
该页面完整复用原积分日志页的展示逻辑,通过 URL query 参数 `uid` 锁定指定用户,隐藏"用户搜索"字段。
#### 筛选条件
| 筛选项 | 类型 | 说明 |
|--------|------|------|
| 用户ID | 隐藏字段 | 从 URL query `uid` 自动获取 |
| 时间选择 | DateRangePicker | 日期范围 |
#### 表格列(完全复用原页面)
| 列 | 字段 | 说明 |
|----|------|------|
| ID | `id` | 记录ID |
| 用户ID | `uid` | — |
| 用户昵称 | `nickName` | — |
| 标题 | `title` | 积分变动标题 |
| 积分变动 | `integral` | +/- 显示 |
| 剩余积分 | `balance` | 变动后余额 |
| 类型 | `type` | 增加(1)/扣减(2) |
| 关联类型 | `linkType` | 订单/签到/系统 |
| 状态 | `status` | 订单创建/冻结期/完成/失效 |
| 备注 | `mark` | — |
| 创建时间 | `createTime` | — |
#### API 复用
```js
export function getIntegralLogNoAuth(data) {
return requestNoAuth({
url: '/admin/user/integral/list', // 直接复用原接口
method: 'post',
data,
});
}
```
#### 页面头部信息
在表格上方展示当前用户的积分概览卡片:
```
┌──────────────────────────────────────┐
│ 用户:张三 (UID: 1001) │
│ 积分1,200 个人奖金350 │
│ [← 返回用户积分列表] │
└──────────────────────────────────────┘
```
> **字段说明**:积分取自 `eb_user` 表的 `integral` 字段(`BigDecimal`,用户剩余积分);个人奖金取自 `wa_users` 表的 `selfBonus` 字段。
#### 实现步骤
1. 复制 `user/integral/index.vue` 作为基础
2. 从 URL query 中读取 `uid`,自动注入搜索参数
3. 隐藏"用户搜索"和"用户ID"输入框(已通过 query 锁定)
4. 添加顶部用户信息概览卡片
5. 添加"返回"按钮
6. 替换 API 为 `requestNoAuth` 版本
---
## 5. 路由配置
### 5.1 新增路由模块
```js
// src/router/modules/integralExternal.js
const EmptyLayout = () => import('@/layout/EmptyLayout');
const integralExternalRouter = {
path: '/integral-external',
component: EmptyLayout,
redirect: '/integral-external/order',
hidden: true, // 不在侧边栏显示
children: [
{
path: 'order',
component: () => import('@/views/integral-external/order/index'),
name: 'IntegralExternalOrder',
meta: { title: '积分订单' },
},
{
path: 'user',
component: () => import('@/views/integral-external/user/index'),
name: 'IntegralExternalUser',
meta: { title: '用户积分' },
},
{
path: 'user/integral-detail',
component: () => import('@/views/integral-external/user-integral-detail/index'),
name: 'IntegralExternalUserDetail',
meta: { title: '用户积分明细' },
},
],
};
export default integralExternalRouter;
```
### 5.2 注册路由
`src/router/index.js` 中将新模块加入 `constantRoutes`
```js
import integralExternalRouter from './modules/integralExternal';
export const constantRoutes = [
integralExternalRouter, // 积分外部页面(免登录)
storeRouter,
orderRouter,
// ...其余路由
];
```
### 5.3 修改权限守卫
`src/permission.js` 中扩展白名单:
```js
const whiteList = ['/login', '/auth-redirect', '/integral-external'];
// 匹配逻辑改为前缀匹配
if (whiteList.some(path => to.path.startsWith(path))) {
next();
}
```
---
## 6. 后端 API 影响评估
### 6.1 可直接复用的接口
| 接口 | Method | 免认证现状 | 所需改动 |
|------|--------|-----------|---------|
| `/admin/user/integral/list` | POST | 需认证 | 需后端为外部调用新增免认证入口,或前端伪造 token |
| `/admin/user/list` | GET | 需认证 | 同上 |
| `/admin/order/list` | GET | 需认证 | 同上 |
### 6.2 推荐的后端最小改动方案
按照"最小修改原则",建议后端在现有 Controller 基础上新增一套免认证的映射路径,内部直接调用相同的 Service 方法:
```
新路径 → 复用的 Service 方法
/api/external/integral/order/list → OrderService.list()
/api/external/integral/user/list → UserService.list()(补充 wa_users 字段)
/api/external/integral/log/list → IntegralService.list()
```
只需新建一个 `ExternalIntegralController`,加 `@RestController` 免认证注解,约 50-80 行代码。
### 6.3 wa_users 字段集成
**方案 A**:后端在用户列表接口返回中直接 JOIN wa_users 表,新增字段返回。
**方案 B**:前端先拿用户列表,再批量查 wa_users 信息,前端做合并。
推荐方案 A后端改动更少前端实现更简单
---
## 7. 开发任务清单
### Phase 1基础设施预计 0.5 天)
| # | 任务 | 文件 |
|---|------|------|
| 1.1 | 创建 `EmptyLayout.vue` 空白布局 | `src/layout/EmptyLayout.vue` |
| 1.2 | 创建 `requestNoAuth.js` 免认证请求实例 | `src/utils/requestNoAuth.js` |
| 1.3 | 创建 `integralExternal.js` 路由模块 | `src/router/modules/integralExternal.js` |
| 1.4 | 注册路由到 `constantRoutes` | `src/router/index.js` |
| 1.5 | 修改 `permission.js` 白名单 | `src/permission.js` |
| 1.6 | 创建 `integralExternal.js` API 文件 | `src/api/integralExternal.js` |
### Phase 2积分订单页面预计 1 天)
| # | 任务 |
|---|------|
| 2.1 | 基于 `order/index.vue` 创建精简版积分订单页 |
| 2.2 | 去除权限校验、操作按钮、导出功能 |
| 2.3 | 接入 `requestNoAuth` 请求 |
| 2.4 | 测试筛选、分页、数据展示 |
### Phase 3用户积分页面预计 1.5 天)
| # | 任务 |
|---|------|
| 3.1 | 基于 `user/list/index.vue` 创建精简版用户积分页 |
| 3.2 | 去除高级筛选、权限、操作按钮 |
| 3.3 | 增加 wa_users 字段列(奖金、积分、余额等) |
| 3.4 | 实现数据合并逻辑(前端或后端) |
| 3.5 | 添加"查看积分明细"跳转按钮 |
| 3.6 | 测试数据展示与跳转 |
### Phase 4用户积分明细子页面预计 0.5 天)
| # | 任务 |
|---|------|
| 4.1 | 基于 `user/integral/index.vue` 创建积分明细页 |
| 4.2 | 通过 URL query 读取 uid 并锁定用户 |
| 4.3 | 添加用户积分概览卡片 |
| 4.4 | 添加返回按钮 |
| 4.5 | 接入 `requestNoAuth` 请求 |
| 4.6 | 测试分页、筛选、数据展示 |
### Phase 5联调与验收预计 0.5 天)
| # | 任务 |
|---|------|
| 5.1 | 无 token 状态下完整流程测试 |
| 5.2 | 页面间跳转逻辑验证 |
| 5.3 | 后端免认证接口联调 |
| 5.4 | 兼容性和响应式测试 |
**总计预估工时4 天**
---
## 8. 测试方案
### 8.1 免登录访问测试
| 编号 | 测试场景 | 操作步骤 | 预期结果 |
|------|---------|---------|---------|
| A-01 | 无 token 直接访问积分订单页 | 清除浏览器所有 cookie/sessionStorage直接访问 `/integral-external/order` | 页面正常加载,不跳转至 `/login` |
| A-02 | 无 token 直接访问用户积分页 | 同上,访问 `/integral-external/user` | 页面正常加载,不跳转至 `/login` |
| A-03 | 无 token 直接访问积分明细页 | 同上,访问 `/integral-external/user/integral-detail?uid=1` | 页面正常加载,不跳转至 `/login` |
| A-04 | 免登录页面不影响原有认证 | 无 token 访问 `/order/index`(原页面) | 仍然正常跳转至 `/login` |
| A-05 | 已登录用户访问免登录页面 | 管理员登录后访问 `/integral-external/order` | 页面正常加载,不受登录态影响 |
### 8.2 积分订单页面测试
| 编号 | 测试场景 | 操作步骤 | 预期结果 |
|------|---------|---------|---------|
| B-01 | 默认加载 | 进入页面 | 表格展示订单列表,分页信息正确 |
| B-02 | 按订单状态筛选 | 依次点击"未支付""未发货""交易完成"等状态 | 表格数据按状态正确过滤,数量标签更新 |
| B-03 | 按时间范围筛选 | 选择起止日期 | 仅显示时间范围内的订单 |
| B-04 | 按订单号搜索 | 输入完整订单号,点击搜索 | 精确匹配到对应订单 |
| B-05 | 重置筛选条件 | 设置筛选条件后点击重置 | 所有筛选项恢复默认,表格展示全部数据 |
| B-06 | 分页切换 | 切换页码、修改每页显示数 | 数据正确刷新,分页器状态正确 |
| B-07 | 空数据状态 | 搜索不存在的订单号 | 表格显示空状态提示,无 JS 报错 |
| B-08 | 无操作列 | 检查表格列 | 不存在编辑、发货、退款等操作按钮 |
### 8.3 用户积分页面测试
| 编号 | 测试场景 | 操作步骤 | 预期结果 |
|------|---------|---------|---------|
| C-01 | 默认加载 | 进入页面 | 用户列表正常展示,含 CRMEB 和 wa_users 字段 |
| C-02 | wa_users 字段展示 | 查看表格列 | 个人奖金(`selfBonus`)、账户余额(`money`)等 wa_users 字段正确显示 |
| C-03 | 积分字段来源验证 | 对比数据库 `eb_user.integral` 值 | 页面显示的积分与 `eb_user` 表一致 |
| C-04 | wa_users 无关联数据 | 查看无 wa_users 记录的 CRMEB 用户行 | wa_users 相关列显示 `-``0`,不报错 |
| C-05 | 用户搜索 | 输入姓名/手机号搜索 | 正确过滤,支持模糊匹配 |
| C-06 | 跳转积分明细 | 点击某用户行的"查看积分明细" | 正确跳转至 `/integral-external/user/integral-detail?uid=xxx` |
| C-07 | 分页功能 | 切换页码和每页条数 | 数据正确刷新 |
| C-08 | 无权限指令残留 | 审查页面 DOM | 不存在 `v-hasPermi` 相关的隐藏元素或报错 |
### 8.4 用户积分明细子页面测试
| 编号 | 测试场景 | 操作步骤 | 预期结果 |
|------|---------|---------|---------|
| D-01 | 带 uid 参数加载 | 访问 `?uid=1001` | 自动加载 uid=1001 的积分明细,顶部概览卡片显示用户信息 |
| D-02 | 概览卡片数据验证 | 对比数据库值 | 积分值 = `eb_user.integral`,个人奖金 = `wa_users.selfBonus` |
| D-03 | 无 uid 参数访问 | 访问不带 `?uid` 参数的页面 | 页面给出"缺少用户参数"提示,或重定向至用户积分列表 |
| D-04 | 无效 uid 访问 | 访问 `?uid=999999`(不存在的用户) | 表格为空,概览卡片显示空状态,无 JS 报错 |
| D-05 | 时间范围筛选 | 选择日期范围 | 积分明细按时间正确过滤 |
| D-06 | 积分变动显示 | 查看积分变动列 | 增加显示绿色 `+`,扣减显示红色 `-` |
| D-07 | 状态与关联类型 | 查看状态和关联类型列 | 订单创建/冻结期/完成/失效 正确渲染标签颜色;订单/签到/系统 正确显示 |
| D-08 | 返回按钮 | 点击"返回用户积分列表" | 正确跳转回 `/integral-external/user` |
| D-09 | 分页功能 | 切换页码15/30/45/60 | 数据正确刷新 |
### 8.5 接口与数据测试
| 编号 | 测试场景 | 操作步骤 | 预期结果 |
|------|---------|---------|---------|
| E-01 | 免认证接口可达性 | 无 token 调用各外部接口 | 返回 200 及正确业务数据,不返回 401 |
| E-02 | 原认证接口不受影响 | 无 token 调用原 `/admin/user/list` 等接口 | 仍返回 401 |
| E-03 | 接口仅读不写 | 尝试对免认证接口发送写操作请求 | 返回 403 或方法不允许 |
| E-04 | 大数据量分页 | 请求 limit=60数据总量 > 1000 | 分页正确,响应时间 < 3s |
| E-05 | 边界参数 | page=0、limit=-1、uid=null 等异常参数 | 接口返回友好错误信息,不产生 500 |
| E-06 | 数据脱敏验证 | 检查返回的手机号字段 | 中间 4 位做掩码处理(如 `138****8888` |
### 8.6 兼容性与 UI 测试
| 编号 | 测试场景 | 预期结果 |
|------|---------|---------|
| F-01 | Chrome 最新版 | 页面布局正常,功能正常 |
| F-02 | Firefox 最新版 | 页面布局正常,功能正常 |
| F-03 | Edge 最新版 | 页面布局正常,功能正常 |
| F-04 | 1920×1080 分辨率 | 表格列宽合理,无横向滚动条溢出 |
| F-05 | 1366×768 分辨率 | 表格可横向滚动,筛选栏自动换行 |
| F-06 | EmptyLayout 布局验证 | 页面无侧边栏、无顶部导航栏、无面包屑 |
| F-07 | 加载状态 | 数据加载中显示 loading 动画 |
### 8.7 测试执行时间规划
| 阶段 | 内容 | 预计时间 |
|------|------|---------|
| 冒烟测试 | Phase 1 基础设施完成后,验证 A-01 ~ A-05 免登录链路 | 0.5h |
| 功能测试 | 每个页面开发完成后,执行对应 B/C/D 组用例 | 每页面 1~2h |
| 接口联调测试 | 后端免认证接口就绪后,执行 E 组用例 | 1h |
| 回归测试 | 全部开发完成后,执行全量用例 | 2h |
| 兼容性测试 | 回归通过后,执行 F 组用例 | 1h |
---
## 9. 注意事项
1. **安全风险**:免登录页面直接暴露后台数据,建议后端对免认证接口做 IP 白名单或 API Key 鉴权。
2. **数据脱敏**:用户手机号等敏感字段建议做中间位掩码处理(如 `138****8888`)。
3. **接口幂等**所有免认证接口仅开放读取权限GET/查询),禁止写操作。
4. **路由隔离**:新页面使用 `EmptyLayout`,与管理后台主布局完全隔离,避免引入侧边栏/权限组件的副作用。
5. **组件依赖**:新页面可复用 Element UI 组件,但避免引入需要 Vuex store如用户信息、权限的业务组件。