1. 新增国际化规范文档 `i18n-rules.md`,详细说明项目国际化的规范、key 命名、使用方式等 2. 新增登录页面搬迁文档 `login-page-migration.md`,记录登录页搬迁的步骤、依赖和验证清单 3. 修复生产主数据路由文件中多余的尾随字符
16 KiB
登录页面搬迁文档
搬迁源:
D:\code\company\SCTMES_MES_V5\vue-app
搬迁目标:d:\code\mes\mes-ui
状态:⏳ 待审阅,审阅通过后执行搬迁
一、文件清单与依赖关系
登录页面 index.vue
│
├── ① 页面自身
├── ② 依赖的 Store 模块
├── ③ 依赖的 API 文件
├── ④ 依赖的静态资源(图片)
├── ⑤ 依赖的 i18n 语言包
├── ⑥ 依赖的 CSS 公共样式(% placeholder)
├── ⑦ 依赖的工具库
└── ⑧ 路由中已有框架(无需搬迁本文件)
二、需要搬迁的文件
2.1 页面核心文件
| 文件 | 旧路径 | 新目标路径 | 说明 |
|---|---|---|---|
| 登录页面 | src/views/system_settings/system_monitoring/system/login/index.vue |
覆盖 src/views/system/login/index.vue |
新项目已有一个简易占位页面,需用旧项目的完整页面替换 |
旧路径嵌套很深:
system_settings/system_monitoring/system/login/。
新项目按对照表命名为简化的system/login/,保持一致的命名风格。
2.2 Store 模块(Vuex)
| 文件 | 旧路径 | 新目标路径 | 说明 |
|---|---|---|---|
| account | src/store/modules/d2admin/modules/account.js |
src/store/modules/d2admin/modules/account.js |
核心:含 login 和 logout action |
| user | src/store/modules/d2admin/modules/user.js |
src/store/modules/d2admin/modules/user.js |
account.login 中调用 d2admin/user/set,新项目已存在 |
account.js的loginaction 依赖链:
login()→loginAdminUser()API → 写 cookie(token/uuid) →dispatch(d2admin/user/set)→dispatch(load)
load()→ 依次加载 user/theme/transition/page/menu/size/color
account.js 依赖的其它模块(新项目已存在,不需搬迁):
| 模块 | 路径 | 状态 |
|---|---|---|
| user | src/store/modules/d2admin/modules/user.js |
✅ 已有 |
| theme | src/store/modules/d2admin/modules/theme.js |
✅ 已有 |
| transition | src/store/modules/d2admin/modules/transition.js |
✅ 已有 |
| page | src/store/modules/d2admin/modules/page.js |
✅ 已有 |
| menu | src/store/modules/d2admin/modules/menu.js |
✅ 已有 |
| size | src/store/modules/d2admin/modules/size.js |
✅ 已有 |
| color | src/store/modules/d2admin/modules/color.js |
✅ 已有 |
| db | src/store/modules/d2admin/modules/db.js |
✅ 已有 |
2.3 API 文件
| 文件 | 旧路径 | 新目标路径 | 说明 |
|---|---|---|---|
| 登录/注销 API | src/api/login.js |
src/api/auth.js |
含 loginAdminUser() 和 logoutAdminUser() |
注意:旧项目
login.js中 import 了@/plugin/axios/request,这是旧项目的 axios 封装。
新项目使用@/api/_service中的request,搬迁时需替换 import 路径。
2.4 静态资源(图片)
| 文件 | 旧路径 | 新目标路径 | 说明 |
|---|---|---|---|
| 登录页 Logo | public/image/logo/sc_logo.png |
public/image/logo/sc_logo.png |
登录表单上方的 Logo |
旧项目
public/image/logo/目录下共有 9 个文件,但登录页面只用sc_logo.png。
根据需要可按需搬其他 logo 文件。新项目原有src/views/system/login/image/logo@2x.png,搬迁后可删除。
2.5 i18n 语言包
i18n key 前缀:page.system_settings.system_monitoring.system.login
| key | 中文 | 英文 |
|---|---|---|
time_is_most_precious |
时间是一切财富中最宝贵的财富 | Time is the most precious of all wealth |
username |
用户名 | Username |
password |
密码 | Password |
login |
登录 | Login |
quick_select_user |
快速选择用户 | Quick Select User |
please_enter_username |
请输入用户名 | Please enter username |
please_enter_password |
请输入密码 | Please enter password |
please_enter_code |
请输入验证码 | Please enter captcha |
dev_version |
开发版本 | Development Version |
test_version |
测试版本 | Test Version |
form_validation_failed |
表单校验失败,请检查 | Form validation failed |
搬迁操作:
- 在
src/locales/zh-chs.json的page.system.system_monitoring下新增:
"login": {
"time_is_most_precious": "时间是一切财富中最宝贵的财富",
"username": "用户名",
"password": "密码",
"login": "登录",
"quick_select_user": "快速选择用户",
"please_enter_username": "请输入用户名",
"please_enter_password": "请输入密码",
"please_enter_code": "请输入验证码",
"dev_version": "开发版本",
"test_version": "测试版本",
"form_validation_failed": "表单校验失败,请检查"
}
- 在
src/locales/en.json中对应添加英文翻译。
2.6 CSS 公共样式(依赖但不在页面内)
页面中使用了 SCSS 的 %placeholder 选择器:
| placeholder | 作用 | 定义位置 |
|---|---|---|
%unable-select |
禁止用户选中 + 鼠标变手形 | src/assets/style/public.scss |
%full |
绝对定位填满父元素 | src/assets/style/public.scss |
%flex-center-col |
flex 垂直水平居中 | src/assets/style/public.scss |
$color-text-normal |
文字颜色变量 | src/assets/style/unit/color.scss |
$color-primary |
主色变量 | src/assets/style/unit/color.scss |
$color-bg |
背景色变量 | src/assets/style/unit/color.scss |
✅ 这些在新项目中已存在(通过
additionalData全局注入),不需要额外搬迁。
2.7 工具/插件依赖(新项目已有,不需搬迁)
| 依赖 | 旧路径 | 新项目状态 |
|---|---|---|
util.cookies |
src/libs/util.cookies.js → src/libs/util.js |
✅ 已有 |
localeMixin |
src/locales/mixin.js |
✅ 已有 |
dayjs |
npm 包 | ✅ 已有(package.json 中) |
$baseUrl |
Vue.prototype.$baseUrl = process.env.BASE_URL |
✅ 已在 plugin/d2admin/index.js 注册 |
vuex mapActions |
npm 包 | ✅ 已有 |
2.8 路由(新项目已配置,不需搬迁)
旧路由:
{
path: '/login',
name: 'login',
component: _import('system_settings/system_monitoring/system/login')
}
新项目路由已在 routes.js 的 frameOut 中配置:
{
path: '/login',
name: 'login',
component: _import('system/login')
}
✅ 新路由已指向
system/login,对应的src/views/system/login/index.vue需要替换为旧页面内容。
三、搬迁执行步骤
| 步骤 | 操作 | 文件 |
|---|---|---|
| 1 | 拷贝登录 API(替换 import 为 @/api/_service) |
src/api/login.js → src/api/auth.js |
| 2 | 拷贝 account Store(替换 API 引用路径) | src/store/modules/d2admin/modules/account.js |
| 3 | 拷贝 Logo 图片 | public/image/logo/sc_logo.png |
| 4 | 更新登录页面(替换 import 路径 + i18n key + logo 路径) | src/views/system/login/index.vue |
| 5 | 添加 i18n 语言包 | src/locales/zh-chs.json / en.json |
| 6 | 验证:pnpm serve 启动 → 访问 /login 测试登录流程 |
四、页面中需要修改的内容
登录页面 index.vue 从旧项目拷贝后,需改以下几处:
4.1 import 路径修正
- import { mapActions } from 'vuex'
- import util from '@/libs/util'
- import localeMixin from '@/locales/mixin.js'
+ // 这些在新项目中路径一致,无需修改
+ // util.cookies、localeMixin、mapActions 均同上
注意:旧页面 mixins 中引用了
localeMixin(切换语言),新项目中此 mixin 在src/locales/mixin.js已存在,不需动。
4.2 Logo 图片路径
- <img class="page-login--logo" :src="`${$baseUrl}image/logo/sc_logo.png`">
+ <img class="page-login--logo" src="/image/logo/sc_logo.png">
新项目中
$baseUrl同样已注册,两种写法均可。建议用绝对路径/image/logo/sc_logo.png更直观。
4.3 i18n key 修正
旧页面使用的 key 前缀为 page.system_settings.system_monitoring.system.login.xxx,在新项目中统一简化为 page.system.login.xxx,或按新项目目录结构调整。
建议调整为更简洁的 key:
| 旧 key(太长) | 新 key(建议) |
|---|---|
page.system_settings.system_monitoring.system.login.username |
page.system.login.username |
page.system_settings.system_monitoring.system.login.password |
page.system.login.password |
五、不涉及的依赖(记录说明)
| 依赖 | 原因 |
|---|---|
@/libs/websocket.js |
登录页面本身不 import websocket,但 account.js 的 logout action 中引用。新项目如不需 websocket,注释掉即可 |
@/api/modules/sys.user.api.js |
旧 account.login 只调 login.js API,不涉及此文件 |
public/image/logo/ 其他 png |
登录页只用 sc_logo.png,其余 logo 按需搬迁 |
登录流程完整流程图
正向流程:用户登录
sequenceDiagram
participant User as 用户
participant LoginPage as Login 页面
participant VUEX as Store account
participant API as 后端 POST /login
participant Cookie as Cookie
participant Router as router.beforeEach
participant Home as 首页
User->>LoginPage: 输入用户名密码,点击登录
LoginPage->>LoginPage: el-form.validate 校验表单
alt 校验失败
LoginPage-->>User: message.error 表单校验失败
else 校验通过
LoginPage->>VUEX: dispatch login { username, password }
VUEX->>API: loginAdminUser
alt 登录失败 401 或密码错误
API-->>VUEX: throw Error
VUEX->>VUEX: remove token 和 uuid
VUEX-->>LoginPage: Promise rejected
LoginPage-->>User: message.error
else 登录成功
API-->>VUEX: token 和 userInfo
VUEX->>Cookie: 写入 token / uuid 有效期365天
VUEX->>VUEX: localStorage.setItem user_id
VUEX->>VUEX: dispatch user/set
VUEX->>VUEX: dispatch load 加载持久化配置
Note over VUEX: load按序加载: user theme transition page menu size color sourceData
VUEX-->>LoginPage: Promise resolved
LoginPage->>Router: router.replace redirect or /
Router->>Router: beforeEach 检查 token
Router-->>Home: 鉴权通过,跳转目标页
end
end
反向流程:用户注销
sequenceDiagram
participant User as 用户
participant Header as 顶栏用户菜单
participant VUEX as Store account
participant API as 后端 POST /logout
participant Cookie as Cookie
participant WS as WebSocket
participant LoginPage as Login 页面
User->>Header: 点击注销
Header->>VUEX: dispatch logout { confirm: true }
VUEX->>User: confirm 确定要注销吗
alt 取消
User-->>VUEX: 取消
else 确认
VUEX->>VUEX: Loading 遮罩
VUEX->>WS: closeSock 断开 WebSocket
VUEX->>API: logoutAdminUser
API-->>VUEX: 服务端清除 session
VUEX->>VUEX: dispatch db/set 清空 sourceData
VUEX->>VUEX: dispatch user/set 清空用户信息
VUEX->>Cookie: remove token / uuid / set block true
VUEX->>VUEX: Loading 关闭
VUEX->>LoginPage: router.push { name: login }
LoginPage-->>User: 返回登录页面
end
路由守卫鉴权流程(分三种情况)
情况 A:无 Token → 跳转登录页
flowchart TD
A["用户访问 URL"] --> B{"路由需要 auth?"}
B -->|是| C["Cookie.get(token)"]
C -->|"token 为空"| D["重定向到 /login?redirect=原地址"]
D --> E["用户在登录页输入账号密码"]
E --> F["登录成功"]
F --> G["router.replace 回到目标页"]
G --> H["进入首页"]
情况 B:有 Token → 恢复会话
flowchart TD
A["用户访问 URL,Cookie 中已有 token"] --> B{"路由需要 auth?"}
B -->|是| C["Cookie.get(token)"]
C -->|"token 有效"| D["next 放行"]
D --> E["框架渲染 header-aside 布局"]
E --> F["d2admin/page/isLoaded"]
F --> G["d2admin/size/isLoaded"]
G --> H["页面正常加载"]
style C fill:#f9f,stroke:#333
style D fill:#9f9,stroke:#333
style H fill:#9f9,stroke:#333
情况 C:Token 有效但后端已过期 → API 层拦截
flowchart TD
A["页面加载后调用业务 API"] --> B["axios 请求携带 Authorization header"]
B --> C{"后端 code === 401?"}
C -->|否| D["正常返回数据"]
C -->|"是 401"| E["axios 响应拦截器 catch 401"]
E --> F["清除 Cookie(token / uuid)"]
F --> G["Message.error 请重新登录"]
G --> H["router.push /login"]
style C fill:#f96,stroke:#333
style H fill:#f96,stroke:#333
已有 Token 时的完整恢复时序
sequenceDiagram
participant User as 用户
participant Browser as 浏览器
participant Router as router.beforeEach
participant Cookie as Cookie
participant Store as Vuex Store
participant DB as Local DB lowdb
participant Layout as Layout
participant Page as 目标页面
User->>Browser: 打开网页
Browser->>Router: beforeEnter 触发
Router->>Store: dispatch page/isLoaded
Router->>Store: dispatch size/isLoaded
Router->>Cookie: get token
Cookie-->>Router: token = eyJ...
Router->>Router: next 放行
Router->>Layout: 渲染 header-aside
Layout->>Store: menu 加载侧边栏
Store->>DB: get sys.menu.asideCollapse
DB-->>Store: 上次展开收起状态
Layout->>Store: theme 加载主题
Store->>DB: get sys.theme.activeName
DB-->>Store: 上次选择的主题
Layout->>Store: page 加载多标签页
Store->>DB: get sys.page.opened
DB-->>Store: 上次打开的标签页列表
Layout->>Page: 目标页面渲染完成
Page-->>User: 首页正常显示,主题侧栏标签页全部恢复
对比:首次登录 vs 已有 Token
| 维度 | 首次登录(无 Token) | 已有 Token 恢复 |
|---|---|---|
| 入口 | /login 登录页 |
任意页面 URL |
| 路由守卫 | 拦下 → 重定向 /login | 放行 |
| 用户操作 | 输入用户名密码 | 无需操作 |
account/login |
✅ 触发 | ❌ 不触发 |
account/load() |
✅ 触发(写入 DB) | ❌ 不触发 |
page/isLoaded |
触发(首次无缓存) | 触发(从 DB 恢复) |
size/isLoaded |
触发 | 触发 |
| 主题/侧栏/标签页 | 从登录后 load() 写入 | 从 lowdb 读取上次状态 |
| Cookie | 新建 token / uuid | 复用已有 token |
整体状态流转
stateDiagram-v2
[*] --> 未登录: 首次访问
[*] --> 已登录: 已有 token,恢复会话
未登录 --> 登录页面: 路由守卫拦下
登录页面 --> 提交中: 输入账号密码,点击登录
提交中 --> 登录成功: API 返回 token
提交中 --> 登录失败: API 报错 / 401
登录失败 --> 登录页面: 清除 cookie,允许重试
登录成功 --> 已登录: 写入 cookie + load() 加载配置
已登录 --> 已登录: 页面刷新(token 仍有效,Router + DB 恢复)
已登录 --> 未登录: API 返回 401,被强制退出
已登录 --> 注销中: 点击注销
注销中 --> 已登录: 取消确认
注销中 --> 未登录: 确认 → logout API → 清 cookie → 跳 /login
六、搬迁后验证清单
pnpm lint无报错pnpm serve启动成功- 访问
http://localhost:8081/login能看到完整登录页面 - 输入正确的用户名密码能登录并跳转首页
- 中文/英文切换按钮文字正确
- 登录失败有表单校验提示
- 浏览器 Cookie 中有
token和uuid