48 KiB
RuoYi-Vue 前端现代化重构实施计划
For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (
- [ ]) syntax for tracking.
---
change: refactor-frontend-modernization
design-doc: docs/superpowers/specs/2026-06-28-frontend-modernization-design.md
base-ref: 1c7d266b7f70eae46abd1f011e443ac54b4cc7f4
---
Goal: 将 RuoYi-Vue 前端从 Vue2 + Vue CLI + Element UI + Vuex 升级到 Vue3 + Vite + TypeScript + Element Plus + Pinia,同时参考 demo-dashboard-heatmap.html 的深色主题和数据可视化风格,保持与现有后端 API 完全兼容。
Architecture: 采用渐进式迁移策略,先在独立目录 (ruoyi-ui-next/) 构建新项目,按模块逐步迁移组件和页面,确保后端零改动。
Tech Stack:
| 类别 | 旧技术栈 | 新技术栈 |
|---|---|---|
| 框架 | Vue 2.6.12 | Vue 3.5+ |
| 构建 | Vue CLI 4.4.6 | Vite 6+ |
| 语言 | JavaScript | TypeScript 5+ |
| UI | Element UI 2.15.6 | Element Plus 2.9+ |
| 路由 | Vue Router 3.4.9 | Vue Router 4+ |
| 状态 | Vuex 3.6.0 | Pinia 2.3+ |
| HTTP | Axios 0.24.0 | Axios 1.7+ |
| 图表 | ECharts 4.9.0 | ECharts 5.5+ |
| CSS | Sass 1.32 | SCSS + CSS Variables |
Global Constraints
- 新项目目录:
ruoyi-ui-next/(与ruoyi-ui/并存,不影响现有前端) - 后端兼容: 所有 API 路径、请求格式、响应格式保持完全一致
- 权限兼容: 沿用
Admin-TokenCookie 认证和*:*:*权限标识体系 - 深色主题默认: 默认深色主题,配色方案源自
data/demo-dashboard-heatmap.html - TypeScript 严格模式: 启用
strict: true,所有新增代码必须有类型标注 - 代码风格: ESLint + Prettier + Vue 3
<script setup>语法 - 组件命名: PascalCase 文件名,kebab-case 标签名
Task 1: 项目初始化
目标: 使用 Vite 创建 Vue3 + TypeScript 项目骨架,配置开发工具链
Files:
- Create:
ruoyi-ui-next/package.json - Create:
ruoyi-ui-next/vite.config.ts - Create:
ruoyi-ui-next/tsconfig.json - Create:
ruoyi-ui-next/tsconfig.node.json - Create:
ruoyi-ui-next/index.html - Create:
ruoyi-ui-next/.env.development - Create:
ruoyi-ui-next/.env.production - Create:
ruoyi-ui-next/.eslintrc.cjs - Create:
ruoyi-ui-next/.prettierrc - Create:
ruoyi-ui-next/.editorconfig - Create:
ruoyi-ui-next/.gitignore - Create:
ruoyi-ui-next/src/main.ts - Create:
ruoyi-ui-next/src/App.vue - Reference:
ruoyi-ui/package.json(依赖参考) - Reference:
ruoyi-ui/.env.development(环境变量参考)
Description: 创建全新 Vite + Vue3 + TypeScript 项目,配置完整的开发工具链和项目结构
Dependencies: 无
Step 1: 初始化项目结构
ruoyi-ui-next/
├── public/
│ └── favicon.ico
├── src/
│ ├── api/ # API 调用层
│ │ ├── index.ts # 通用 API
│ │ ├── login.ts # 登录/认证
│ │ ├── menu.ts # 路由菜单
│ │ ├── system/ # 系统管理 API
│ │ │ ├── user.ts
│ │ │ ├── role.ts
│ │ │ ├── menu.ts
│ │ │ ├── dept.ts
│ │ │ ├── config.ts
│ │ │ ├── notice.ts
│ │ │ ├── post.ts
│ │ │ └── dict/
│ │ │ ├── data.ts
│ │ │ └── type.ts
│ │ ├── monitor/ # 系统监控 API
│ │ │ ├── cache.ts
│ │ │ ├── job.ts
│ │ │ ├── logininfor.ts
│ │ │ ├── online.ts
│ │ │ ├── operlog.ts
│ │ │ └── server.ts
│ │ ├── booksystem/ # 账本系统 API
│ │ │ ├── account.ts
│ │ │ ├── book.ts
│ │ │ ├── operations.ts
│ │ │ ├── statistics.ts
│ │ │ ├── statistictotal.ts
│ │ │ └── statisticremain.ts
│ │ └── stocksystem/ # 股票系统 API
│ │ ├── stocks.ts
│ │ ├── stockbasic.ts
│ │ ├── stockindex.ts
│ │ ├── financial.ts
│ │ ├── trends.ts
│ │ ├── trendStocks.ts
│ │ ├── newrecord.ts
│ │ ├── stockslimit.ts
│ │ └── book.ts
│ ├── assets/
│ │ ├── icons/svg/ # SVG 图标(从 ruoyi-ui 复制全部)
│ │ ├── styles/ # 全局样式
│ │ │ ├── index.scss
│ │ │ ├── variables.scss
│ │ │ ├── dark-theme.scss
│ │ │ └── transition.scss
│ │ └── images/ # 静态图片
│ ├── components/ # 全局通用组件
│ │ ├── SvgIcon/
│ │ ├── DictTag/
│ │ ├── Pagination/
│ │ ├── Breadcrumb/
│ │ ├── Hamburger/
│ │ ├── Screenfull/
│ │ ├── SizeSelect/
│ │ ├── ThemePicker/
│ │ ├── TopNav/
│ │ ├── RightToolbar/
│ │ ├── Editor/
│ │ ├── FileUpload/
│ │ ├── ImageUpload/
│ │ ├── ImagePreview/
│ │ ├── IconSelect/
│ │ ├── HeaderSearch/
│ │ ├── Crontab/
│ │ ├── ParentView/
│ │ └── iFrame/
│ ├── components-business/ # 业务组件(解耦通用组件)
│ │ ├── Kdialog/
│ │ ├── NegativeDialog/
│ │ └── TrendStocksDialog/
│ ├── layout/ # 布局框架
│ │ ├── index.vue
│ │ └── components/
│ │ ├── AppMain.vue
│ │ ├── Navbar.vue
│ │ ├── Sidebar/
│ │ ├── TagsView/
│ │ ├── Settings/
│ │ └── InnerLink/
│ ├── router/
│ │ └── index.ts
│ ├── stores/ # Pinia 状态管理
│ │ ├── index.ts
│ │ ├── modules/
│ │ │ ├── app.ts
│ │ │ ├── user.ts
│ │ │ ├── permission.ts
│ │ │ ├── tagsView.ts
│ │ │ └── settings.ts
│ │ └── types.ts
│ ├── views/ # 页面视图
│ │ ├── dashboard/
│ │ ├── system/
│ │ ├── booksystem/
│ │ ├── stocksystem/
│ │ ├── monitor/
│ │ ├── tool/
│ │ ├── error/
│ │ ├── login.vue
│ │ ├── register.vue
│ │ └── index.vue
│ ├── utils/ # 工具函数
│ │ ├── request.ts
│ │ ├── auth.ts
│ │ ├── permission.ts
│ │ ├── validate.ts
│ │ ├── errorCode.ts
│ │ ├── ruoyi.ts
│ │ ├── dict/
│ │ └── types/
│ ├── directives/ # 自定义指令
│ │ ├── index.ts
│ │ └── permission.ts
│ ├── plugins/ # 插件(从 ruoyi-ui 重构)
│ │ ├── index.ts
│ │ ├── auth.ts
│ │ ├── cache.ts
│ │ ├── modal.ts
│ │ └── tab.ts
│ ├── types/ # TypeScript 类型定义
│ │ ├── api.d.ts
│ │ ├── store.d.ts
│ │ ├── router.d.ts
│ │ └── global.d.ts
│ └── permission.ts # 路由权限守卫
├── index.html
├── vite.config.ts
├── tsconfig.json
├── package.json
└── .env.*
- Step 1.1: 创建 package.json
{
"name": "ruoyi-ui-next",
"version": "4.0.0",
"private": true,
"type": "module",
"scripts": {
"dev": "vite",
"build": "vue-tsc --noEmit && vite build",
"build:prod": "vite build --mode production",
"preview": "vite preview",
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx --fix",
"format": "prettier --write src/"
},
"dependencies": {
"vue": "^3.5.0",
"vue-router": "^4.4.0",
"pinia": "^2.3.0",
"pinia-plugin-persistedstate": "^4.0.0",
"axios": "^1.7.0",
"element-plus": "^2.9.0",
"@element-plus/icons-vue": "^2.3.0",
"echarts": "^5.5.0",
"nprogress": "^0.2.0",
"js-cookie": "^3.0.5",
"jsencrypt": "^3.3.0",
"lodash-es": "^4.17.21",
"dayjs": "^1.11.0"
},
"devDependencies": {
"@vitejs/plugin-vue": "^5.2.0",
"vite": "^6.0.0",
"vite-plugin-svg-icons": "^2.0.1",
"vue-tsc": "^2.2.0",
"typescript": "^5.7.0",
"sass": "^1.83.0",
"@types/node": "^22.0.0",
"@types/nprogress": "^0.2.3",
"@types/js-cookie": "^3.0.6",
"@types/lodash-es": "^4.17.12",
"eslint": "^9.0.0",
"@eslint/js": "^9.0.0",
"eslint-plugin-vue": "^9.0.0",
"typescript-eslint": "^8.0.0",
"prettier": "^3.4.0",
"unplugin-auto-import": "^0.18.0",
"unplugin-vue-components": "^0.27.0"
}
}
- Step 1.2: 创建 vite.config.ts
import { defineConfig, loadEnv } from 'vite'
import vue from '@vitejs/plugin-vue'
import { resolve } from 'path'
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
export default defineConfig(({ mode }) => {
const env = loadEnv(mode, process.cwd())
return {
plugins: [
vue(),
createSvgIconsPlugin({
iconDirs: [resolve(__dirname, 'src/assets/icons/svg')],
symbolId: 'icon-[dir]-[name]',
}),
AutoImport({
imports: ['vue', 'vue-router', 'pinia'],
resolvers: [ElementPlusResolver()],
dts: 'src/types/auto-imports.d.ts',
}),
Components({
resolvers: [ElementPlusResolver()],
dts: 'src/types/components.d.ts',
}),
],
resolve: {
alias: {
'@': resolve(__dirname, 'src'),
},
extensions: ['.ts', '.js', '.vue', '.json'],
},
server: {
port: 80,
host: '0.0.0.0',
open: true,
proxy: {
'/dev-api': {
target: env.VITE_APP_BASE_URL || 'http://localhost:8080',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/dev-api/, ''),
},
},
},
build: {
target: 'es2015',
outDir: 'dist',
sourcemap: false,
rollupOptions: {
output: {
manualChunks: {
'element-plus': ['element-plus'],
echarts: ['echarts'],
},
},
},
},
css: {
preprocessorOptions: {
scss: {
additionalData: `@use "@/assets/styles/variables.scss" as *;`,
},
},
},
}
})
- Step 1.3: 创建 tsconfig.json
{
"compilerOptions": {
"target": "ES2020",
"module": "ESNext",
"moduleResolution": "bundler",
"strict": true,
"jsx": "preserve",
"importHelpers": true,
"experimentalDecorators": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"forceConsistentCasingInFileNames": true,
"useDefineForClassFields": true,
"sourceMap": true,
"baseUrl": ".",
"paths": {
"@/*": ["src/*"]
},
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"types": ["vite/client"]
},
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.vue"],
"exclude": ["node_modules", "dist"]
}
- Step 1.4: 创建环境变量文件
.env.development:
VITE_APP_TITLE=摸金分析系统
VITE_APP_BASE_API=/dev-api
VITE_APP_BASE_URL=http://localhost:8080
.env.production:
VITE_APP_TITLE=摸金分析系统
VITE_APP_BASE_API=/prod-api
VITE_APP_BASE_URL=
- Step 1.5: 创建 .eslintrc.cjs + .prettierrc
配置 ESLint 规则:
@typescript-eslint/strictvue/vue3-recommended- Prettier 集成
Prettier 配置:
-
2 空格缩进
-
单引号
-
末尾无分号
-
行宽 100
-
Step 1.6: 创建项目入口文件
src/main.ts:
- 创建 Vue App
- 注册 Element Plus(含中文语言包)
- 注册 Pinia
- 注册 Vue Router
- 注册全局指令
- 注册全局插件
- 挂载应用
src/App.vue:
-
根组件,仅包含
<router-view /> -
Step 1.7: 复制 SVG 图标资源
从 ruoyi-ui/src/assets/icons/svg/ 复制所有 SVG 文件到 ruoyi-ui-next/src/assets/icons/svg/
验收标准:
npm install无报错npm run dev成功启动,访问http://localhost显示空白页面(仅 App.vue)- TypeScript 编译通过(
vue-tsc --noEmit) - ESLint 检查通过(
npm run lint) - 项目结构与规范一致
ruoyi-ui/不受任何影响
Task 2: 核心架构搭建
目标: 配置 Vue Router 4、Pinia 状态管理、Axios 调用层、权限控制机制
Files:
- Create:
ruoyi-ui-next/src/router/index.ts - Create:
ruoyi-ui-next/src/stores/index.ts - Create:
ruoyi-ui-next/src/stores/modules/app.ts - Create:
ruoyi-ui-next/src/stores/modules/user.ts - Create:
ruoyi-ui-next/src/stores/modules/permission.ts - Create:
ruoyi-ui-next/src/stores/modules/tagsView.ts - Create:
ruoyi-ui-next/src/stores/modules/settings.ts - Create:
ruoyi-ui-next/src/stores/types.ts - Create:
ruoyi-ui-next/src/utils/request.ts - Create:
ruoyi-ui-next/src/utils/auth.ts - Create:
ruoyi-ui-next/src/utils/permission.ts - Create:
ruoyi-ui-next/src/utils/errorCode.ts - Create:
ruoyi-ui-next/src/utils/types/api.ts - Create:
ruoyi-ui-next/src/types/global.d.ts - Create:
ruoyi-ui-next/src/types/store.d.ts - Create:
ruoyi-ui-next/src/types/router.d.ts - Create:
ruoyi-ui-next/src/directives/index.ts - Create:
ruoyi-ui-next/src/directives/permission.ts - Create:
ruoyi-ui-next/src/plugins/index.ts - Create:
ruoyi-ui-next/src/plugins/auth.ts - Create:
ruoyi-ui-next/src/plugins/cache.ts - Create:
ruoyi-ui-next/src/plugins/modal.ts - Create:
ruoyi-ui-next/src/plugins/tab.ts - Create:
ruoyi-ui-next/src/permission.ts - Reference:
ruoyi-ui/src/router/index.js - Reference:
ruoyi-ui/src/store/modules/*.js - Reference:
ruoyi-ui/src/utils/request.js - Reference:
ruoyi-ui/src/permission.js - Reference:
ruoyi-ui/src/plugins/*.js - Reference:
ruoyi-ui/src/directive/
Dependencies: Task 1 完成
Step 2.1: 配置 TypeScript 类型定义
定义全局类型:
// src/types/global.d.ts
interface AjaxResult {
code: number
msg: string
data: any
}
interface TableDataInfo {
code: number
msg: string
total: number
rows: any[]
}
interface MenuOption {
name: string
path: string
hidden?: boolean
redirect?: string
component?: string
alwaysShow?: boolean
meta?: {
title: string
icon?: string
noCache?: boolean
link?: string
}
children?: MenuOption[]
}
- 定义
AjaxResult通用响应类型 - 定义
TableDataInfo分页响应类型 - 定义
MenuOption菜单路由类型 - 定义
DictDataType字典数据类型 - 定义
PaginationState分页状态类型
Step 2.2: 配置 Vue Router 4
- 创建
router/index.ts,使用createRouter+createWebHistory - 配置静态路由(
/login、/register、/404、/401、首页重定向) - 配置动态路由占位(登录后从后端加载)
- 实现
loadView懒加载函数(统一使用() => import()) - 路由类型使用
RouteRecordRaw(Vue Router 4) - 配置滚动行为
scrollBehavior
Step 2.3: 配置 Pinia 状态管理
替换 Vuex 5 个模块为 Pinia stores:
app store (stores/modules/app.ts):
sidebar(opened, withoutAnimation) — 侧边栏状态device('desktop' | 'mobile') — 设备类型size('default' | 'large' | 'small') — 组件尺寸(Element Plus 命名调整)- 使用
pinia-plugin-persistedstate持久化到 Cookie/localStorage
user store (stores/modules/user.ts):
token,name,avatar,roles,permissions- Actions:
login(),getInfo(),logout(),fedLogout() - 登录调用
POST /login(保持与现有后端一致) - Token 存储到 Cookie(键名
Admin-Token,与后端一致)
permission store (stores/modules/permission.ts):
routes: 完整路由表addRoutes: 动态添加的路由sidebarRouters: 侧边栏显示的路由- Action:
generateRoutes(roles)— 从后端/getRouters获取菜单并转换为路由 - 实现
filterAsyncRouter字符串组件路径转 import 函数 - 实现权限过滤逻辑
tagsView store (stores/modules/tagsView.ts):
visitedViews: 已访问标签页列表cachedViews: keep-alive 缓存列表- Actions:
addView,delView,delOthersViews,delAllViews,delRightTags,delLeftTags
settings store (stores/modules/settings.ts):
theme,sideTheme,showSettingstopNav,tagsView,fixedHeader,sidebarLogo,dynamicTitle- 持久化到 localStorage(键名
layout-setting)
Step 2.4: 配置 Axios 调用层
src/utils/request.ts:
- 创建 Axios 实例,
baseURL = import.meta.env.VITE_APP_BASE_API - 设置
timeout: 60000 - 请求拦截器:注入
Authorization: Bearer {token}(支持isToken: false跳过) - 请求拦截器:GET 参数序列化(复用
tansParams逻辑) - 响应拦截器:解析
res.data.code,处理 401/500/其他 - 401 处理:使用
ElMessageBox.confirm→ 退出登录 →router.replace('/')(修复原location.href硬跳转问题) - 响应拦截器:HTTP 错误处理(Network Error / Timeout / 4xx / 5xx)
- 导出
download(url, params, filename)方法(blob 下载 + 登录态处理)
Step 2.5: 配置权限控制
- 路由守卫 (
src/permission.ts):- 白名单检查(
/login,/register, 等) - Token 验证(从 Cookie 读取
Admin-Token) - 用户信息加载(roles + permissions)
- 动态路由注册(
router.addRoute) - 页面标题设置
- 白名单检查(
- 指令权限 (
src/directives/permission.ts):v-hasPermi指令:检查权限标识v-hasRole指令:检查角色- 支持超级权限
*:*:* - 支持超级角色
admin
- 全局方法 (
src/plugins/auth.ts):$auth.hasPermi(permission)方法$auth.hasRole(role)方法
Step 2.6: 配置插件系统
重构 ruoyi-ui/src/plugins/ 下的插件:
modal.ts— 全局弹窗封装(ElMessage, ElMessageBox, ElNotification)cache.ts— 缓存封装(localStorage + sessionStorage,带过期支持)tab.ts— 标签页操作(切换、关闭、刷新)auth.ts— 权限校验方法index.ts— 统一注册为 Vue 全局属性
验收标准:
- Pinia DevTools 可查看 5 个 store 状态
- 访问
/login页面可正常渲染 - Axios 请求拦截器正确注入 Token
- 401 响应触发确认弹窗而非硬跳转
v-hasPermi指令在元素上正确隐藏/显示- 路由守卫阻止未登录访问受保护页面
- TypeScript 编译零错误
Task 3: 深色主题和 UI 框架
目标: 安装配置 Element Plus,实现深色主题系统,配置 CSS 变量
Files:
- Create:
ruoyi-ui-next/src/assets/styles/variables.scss - Create:
ruoyi-ui-next/src/assets/styles/dark-theme.scss - Create:
ruoyi-ui-next/src/assets/styles/index.scss - Create:
ruoyi-ui-next/src/assets/styles/element-override.scss - Create:
ruoyi-ui-next/src/assets/styles/sidebar.scss - Create:
ruoyi-ui-next/src/assets/styles/transition.scss - Create:
ruoyi-ui-next/src/assets/styles/btn.scss - Reference:
ruoyi-ui/src/assets/styles/目录 - Reference:
data/demo-dashboard-heatmap.html(深色主题配色来源)
Dependencies: Task 1, Task 2 完成
Step 3.1: 安装 Element Plus
- 确认
element-plus已安装(Task 1 package.json) - 配置按需导入(通过
unplugin-vue-components自动按需导入组件) - 安装
@element-plus/icons-vue图标库 - 配置 Element Plus 中文语言包
Step 3.2: 实现深色主题 CSS 变量
基于 demo-dashboard-heatmap.html 的配色方案:
// src/assets/styles/variables.scss
// 源自 demo-dashboard-heatmap.html 的深色主题
:root {
// 背景色
--bg-primary: #0d1117; // 最深背景 (--bg0)
--bg-secondary: #161b22; // 侧边栏/顶栏 (--bg1)
--bg-tertiary: #1c2333; // 卡片背景 (--bg2)
--bg-elevated: #2a3040; // 悬浮背景 (--bg3)
// 边框
--border-color: #30363d; // 边框色 (--bd)
// 文字
--text-primary: #e6edf3; // 主文字 (--t1)
--text-secondary: #8b949e; // 次要文字 (--t2)
--text-muted: #6e7681; // 弱化文字 (--tm)
// 功能色
--color-danger: #f85149; // 红色/下跌 (--red)
--color-success: #3fb950; // 绿色/上涨 (--grn)
--color-warning: #d29922; // 橙色 (--org)
--color-info: #58a6ff; // 蓝色 (--blu)
// 热力图排名色阶
--heat-1: #ff4444;
--heat-2: #ff6b6b;
--heat-3: #ff9a76;
--heat-4: #ffa502;
--heat-5: #e3b341;
--heat-6: #e6d34a;
--heat-7: #8bda5e;
--heat-8: #4dd08b;
--heat-9: #36b37e;
--heat-10: #2d9cdb;
// 布局
--sidebar-width: 200px;
--navbar-height: 50px;
--tags-view-height: 34px;
}
- 创建
variables.scss定义所有 CSS 变量 - 创建
dark-theme.scss包含热力图排名色阶样式 - 创建
element-override.scss覆盖 Element Plus 默认样式为深色 - 创建
index.scss整合所有样式文件 - 创建
sidebar.scss侧边栏专属样式 - 创建
transition.scss过渡动画样式 - 创建
btn.scss按钮工具类
Step 3.3: 覆盖 Element Plus 深色主题
- 覆盖
el-menu侧边栏菜单背景色和文字色 - 覆盖
el-table表格背景色和边框色 - 覆盖
el-dialog弹窗背景色 - 覆盖
el-input/el-select/el-date-picker表单组件 - 覆盖
el-pagination分页组件 - 覆盖
el-message-box/el-notification - 覆盖
el-tag标签组件
Step 3.4: 实现主题切换功能
- 创建 ThemePicker 组件(支持深色/浅色切换)
- 使用 CSS
data-theme属性切换主题 - 在 settings store 中保存主题偏好
- 默认主题为深色
- 主题切换时无闪烁过渡
Step 3.5: 配置全局样式
- 重置默认样式(margin/padding/box-sizing)
- 配置滚动条样式(
::-webkit-scrollbar) - 配置通用工具类(
.mt-10,.mb-10,.flex,.text-center等) - 配置 NProgress 进度条深色样式
验收标准:
- 深色主题默认渲染正确
- Element Plus 组件在深色主题下视觉一致
- 主题切换功能正常工作
- CSS 变量在 DevTools 中可查看
- 热力图排名色阶样式正确(1-10 级 + >10 级)
- 与 demo-dashboard-heatmap.html 配色方案一致
Task 4: 核心组件迁移
目标: 迁移布局组件和通用组件,重构为 Composition API + TypeScript
Files:
- Create:
ruoyi-ui-next/src/layout/index.vue - Create:
ruoyi-ui-next/src/layout/components/AppMain.vue - Create:
ruoyi-ui-next/src/layout/components/Navbar.vue - Create:
ruoyi-ui-next/src/layout/components/Sidebar/index.vue - Create:
ruoyi-ui-next/src/layout/components/Sidebar/SidebarItem.vue - Create:
ruoyi-ui-next/src/layout/components/Sidebar/Item.vue - Create:
ruoyi-ui-next/src/layout/components/Sidebar/Link.vue - Create:
ruoyi-ui-next/src/layout/components/Sidebar/Logo.vue - Create:
ruoyi-ui-next/src/layout/components/TagsView/index.vue - Create:
ruoyi-ui-next/src/layout/components/TagsView/ScrollPane.vue - Create:
ruoyi-ui-next/src/layout/components/Settings/index.vue - Create:
ruoyi-ui-next/src/layout/components/InnerLink/index.vue - Create:
ruoyi-ui-next/src/components/Breadcrumb/index.vue - Create:
ruoyi-ui-next/src/components/Pagination/index.vue - Create:
ruoyi-ui-next/src/components/DictTag/index.vue - Create:
ruoyi-ui-next/src/components/SvgIcon/index.vue - Create:
ruoyi-ui-next/src/components/Hamburger/index.vue - Create:
ruoyi-ui-next/src/components/Screenfull/index.vue - Create:
ruoyi-ui-next/src/components/SizeSelect/index.vue - Create:
ruoyi-ui-next/src/components/ThemePicker/index.vue - Create:
ruoyi-ui-next/src/components/TopNav/index.vue - Create:
ruoyi-ui-next/src/components/RightToolbar/index.vue - Create:
ruoyi-ui-next/src/components/Editor/index.vue - Create:
ruoyi-ui-next/src/components/FileUpload/index.vue - Create:
ruoyi-ui-next/src/components/ImageUpload/index.vue - Create:
ruoyi-ui-next/src/components/ImagePreview/index.vue - Create:
ruoyi-ui-next/src/components/IconSelect/index.vue - Create:
ruoyi-ui-next/src/components/HeaderSearch/index.vue - Create:
ruoyi-ui-next/src/components/Crontab/index.vue - Create:
ruoyi-ui-next/src/components/Crontab/day.vue - Create:
ruoyi-ui-next/src/components/Crontab/hour.vue - Create:
ruoyi-ui-next/src/components/Crontab/min.vue - Create:
ruoyi-ui-next/src/components/Crontab/month.vue - Create:
ruoyi-ui-next/src/components/Crontab/week.vue - Create:
ruoyi-ui-next/src/components/Crontab/year.vue - Create:
ruoyi-ui-next/src/components/Crontab/second.vue - Create:
ruoyi-ui-next/src/components/Crontab/result.vue - Create:
ruoyi-ui-next/src/components/ParentView/index.vue - Create:
ruoyi-ui-next/src/components/iFrame/index.vue - Reference:
ruoyi-ui/src/layout/目录所有文件 - Reference:
ruoyi-ui/src/components/目录所有文件
Dependencies: Task 1, Task 2, Task 3 完成
Step 4.1: 迁移布局组件
- Layout (
layout/index.vue): 主布局容器,使用<script setup lang="ts">,使用useAppStore()获取侧边栏状态 - AppMain: 主内容区,包含
<router-view>+<keep-alive>+<transition> - Navbar: 顶部导航栏,包含 Hamburger、Breadcrumb、搜索、全屏、通知、用户下拉菜单
- Sidebar: 侧边栏,包含 Logo + Menu + SidebarItem 递归渲染
- SidebarItem: 递归菜单项,支持嵌套路由
- TagsView: 标签页视图,支持右键菜单(刷新、关闭其他、关闭全部)
- Settings: 系统设置面板(主题、顶栏、标签页等开关)
- 移除
ResizeHandler.jsMixin,改用useResize()Composition API 函数
Step 4.2: 迁移高复用通用组件
每个组件迁移要求:
- 使用
<script setup lang="ts">语法 - Props 使用
defineProps<T>()类型标注 - Emits 使用
defineEmits<T>()类型标注 - 移除 Vue 2 Mixin,改用 Composition API
- 保持原有功能不变
高优先级组件(按复用程度):
- Pagination: 分页组件,Props 包括
total,page,limit,Emitsupdate:page,update:limit,pagination - DictTag: 字典标签渲染,Props 包括
options,value - RightToolbar: 右侧工具栏(搜索、显隐列),Props 包括
showSearch,columns - Breadcrumb: 面包屑导航,读取
useRoute()生成面包屑 - SvgIcon: SVG 图标封装,使用
vite-plugin-svg-icons - Hamburger: 汉堡菜单按钮
中优先级组件:
- Screenfull: 全屏切换
- SizeSelect: 组件尺寸选择
- ThemePicker: 主题选择器(与 Task 3 整合)
- TopNav: 顶部导航菜单
- Editor: 富文本编辑器(Quill),确认依赖兼容性
- FileUpload: 文件上传
- ImageUpload: 图片上传
- ImagePreview: 图片预览
低优先级组件:
- HeaderSearch: 头部搜索(Fuse.js 全文搜索)
- IconSelect: SVG 图标选择器
- Crontab: Cron 表达式生成器(9 个子组件)
- ParentView: 父级视图占位
- iFrame: 内嵌 iframe
Step 4.3: 迁移业务组件
将业务组件从 src/components/ 移至 src/components-business/:
- Kdialog: K 线对话框 →
components-business/Kdialog/ - NegativeDialog: 涨跌停对话框 →
components-business/NegativeDialog/ - TrendStocksDialog: 板块趋势对话框 →
components-business/TrendStocksDialog/
Step 4.4: 全局注册策略
- 高复用组件(Pagination, DictTag, SvgIcon, RightToolbar)自动全局注册
- 布局组件按需导入
- 业务组件按需导入(仅在其所属模块页面中引用)
- 移除
ruoyi-ui/src/main.js中的Vue.component()全局注册方式
Step 4.5: 字典系统重构
- 重构
DictData模块为 TypeScript - 创建
utils/dict/index.ts统一管理字典加载 - 字典缓存使用 Pinia store 而非全局变量
- 保持
getDicts(dictType)API 调用兼容
验收标准:
- 所有组件使用
<script setup lang="ts">语法 - Props 和 Emits 有完整 TypeScript 类型定义
- 无 Vue 2 特有 API 使用(
this.$xxx,Vue.extend, Mixin) - Layout 布局渲染正确(Sidebar + Navbar + TagsView + AppMain)
- Pagination 组件在列表中正常工作
- DictTag 正确渲染字典标签
- SvgIcon 正确渲染 SVG 图标
- 业务组件不再污染全局组件注册表
- 组件无 ESLint 报错
Task 5: 数据可视化实现
目标: 安装配置 ECharts 5,实现行情总览和趋势热力图页面
Files:
- Create:
ruoyi-ui-next/src/views/dashboard/index.vue— 行情总览页面 - Create:
ruoyi-ui-next/src/views/dashboard/components/StatsCards.vue— 统计卡片 - Create:
ruoyi-ui-next/src/views/dashboard/components/SentimentRow.vue— 情绪指标行 - Create:
ruoyi-ui-next/src/views/dashboard/components/UpDownChart.vue— 涨跌分布图 - Create:
ruoyi-ui-next/src/views/dashboard/components/TopTrends.vue— 趋势板块 TOP 10 - Create:
ruoyi-ui-next/src/views/dashboard/components/TrendChanges.vue— 趋势变化榜 - Create:
ruoyi-ui-next/src/views/dashboard/components/ConsecutiveStats.vue— 连续统计 - Create:
ruoyi-ui-next/src/views/heatmap/index.vue— 趋势热力图页面 - Create:
ruoyi-ui-next/src/views/heatmap/components/HeatmapMatrix.vue— 热力矩阵 - Create:
ruoyi-ui-next/src/views/heatmap/components/EnhancedTable.vue— 增强表格 - Create:
ruoyi-ui-next/src/views/heatmap/components/DetailModal.vue— 详情弹窗 - Create:
ruoyi-ui-next/src/utils/echarts.ts— ECharts 封装工具 - Reference:
data/demo-dashboard-heatmap.html(UI 参考) - Reference:
ruoyi-ui/src/views/dashboard/目录(旧图表组件)
Dependencies: Task 1, Task 2, Task 3, Task 4 完成
Step 5.1: 配置 ECharts 5
- 确认
echarts@^5.5.0已安装 - 创建
utils/echarts.ts封装工具:initChart(dom, theme)— 初始化图表resizeChart(chart)— 响应式调整- 自定义深色主题配置(与全局 CSS 变量一致)
- 创建
useEChartsComposition API Hook:- 自动处理 resize
- 自动处理组件卸载时的 dispose
- 支持响应式 option 更新
Step 5.2: 实现行情总览页面
参考 demo-dashboard-heatmap.html 中 #pg-dashboard 的布局:
行情总览布局:
├── 市场范围筛选器(全A / 上证 / 深证 / 创业板 / 科创板 / 中证1000)
├── 迷你统计卡片(4 格)
│ ├── 上涨家数
│ ├── 下跌家数
│ ├── 涨停家数
│ └── 跌停家数
├── 情绪指标行(4 格)
│ ├── 全A情绪(含进度条 + 元信息)
│ ├── 中证1000情绪
│ ├── 创业板情绪
│ └── 科创板情绪
├── 双列布局
│ ├── 左:涨跌分布柱状图(ECharts)
│ └── 右:趋势板块 TOP 10(表格)
└── 双列布局
├── 左:趋势变化榜(上升/下降列表)
└── 右:强势板块连续统计(表格)
- StatsCards: 4 格迷你统计卡片组件
- SentimentRow: 情绪指标行,含热力色阶进度条
- UpDownChart: ECharts 涨跌分布柱状图
- TopTrends: 趋势板块 TOP 10 表格(含排名徽章、动量信号、详情按钮)
- TrendChanges: 趋势变化榜(上升红色/下降绿色箭头)
- ConsecutiveStats: 连续统计表格
Step 5.3: 实现趋势热力图页面
参考 demo-dashboard-heatmap.html 中 #pg-heatmap 的布局:
趋势热力图布局:
├── 筛选栏(动量周期:1日/3日/5日/10日/15日/20日/30日 + 日期选择 + 刷新)
├── 视图切换(热力矩阵 / 增强表格)
├── 热力矩阵视图
│ └── 2级行业 × 交易日排名矩阵
│ └── 点击单元格 → 详情弹窗
└── 增强表格视图
└── 行业 × 日期排名 + 趋势变化
- HeatmapMatrix: 热力矩阵组件
- 2 级行业为行,交易日为列
- 排名 1-10 使用色阶渐变(源自 CSS 变量
--heat-1至--heat-10) - 排名 >10 使用默认灰色
- 点击单元格触发详情弹窗
- EnhancedTable: 增强表格视图
- 行业 × 日期排名
- 趋势变化列(上升/下降)
- DetailModal: 详情弹窗
- 统计卡片(当前动量、近5日趋势、涨停家数、创新高、连续天数、平均排名)
- ECharts K 线图
- ECharts 排名趋势折线图
- Tab 切换(概览 / 排名趋势 / 成分股 / 历史数据)
Step 5.4: 数据卡片和统计组件
- 创建通用
StatCard组件(label + value + sub) - 创建通用
MiniBarChart组件(小型柱状图) - 创建通用
RankBadge组件(排名徽章,1-3 金色/2 银色/3 铜色/其他普通) - 创建通用
SignalTag组件(动量信号标签)
Step 5.5: 数据适配层
- 创建 Mock 数据(开发阶段使用)
- 创建 API 调用函数(连接后端实际接口)
- 确保数据格式与现有后端 API 兼容
验收标准:
- 行情总览页面渲染正确,布局与 demo 一致
- 趋势热力图页面渲染正确,热力矩阵色阶正确
- ECharts 图表在窗口缩放时自适应
- 点击热力图单元格可打开详情弹窗
- 详情弹窗中 K 线图和排名趋势图正确渲染
- 视图切换(热力矩阵/增强表格)正常工作
- 所有图表使用深色主题
- 组件使用 Composition API + TypeScript
Task 6: 业务模块迁移
目标: 迁移所有业务模块页面,保持与后端 API 兼容
Files:
- Create:
ruoyi-ui-next/src/views/system/user/index.vue— 用户管理 - Create:
ruoyi-ui-next/src/views/system/role/index.vue— 角色管理 - Create:
ruoyi-ui-next/src/views/system/menu/index.vue— 菜单管理 - Create:
ruoyi-ui-next/src/views/system/dept/index.vue— 部门管理 - Create:
ruoyi-ui-next/src/views/system/config/index.vue— 参数配置 - Create:
ruoyi-ui-next/src/views/system/notice/index.vue— 通知公告 - Create:
ruoyi-ui-next/src/views/system/post/index.vue— 岗位管理 - Create:
ruoyi-ui-next/src/views/system/dict/index.vue— 字典管理 - Create:
ruoyi-ui-next/src/views/system/dict/data.vue— 字典数据 - Create:
ruoyi-ui-next/src/views/system/user/profile/index.vue— 个人中心 - Create:
ruoyi-ui-next/src/views/system/role/authUser.vue— 角色分配用户 - Create:
ruoyi-ui-next/src/views/books/account/index.vue— 交易账户 - Create:
ruoyi-ui-next/src/views/books/book/index.vue— 账本管理 - Create:
ruoyi-ui-next/src/views/books/operations/index.vue— 操作记录 - Create:
ruoyi-ui-next/src/views/books/statistics/index.vue— 统计分析 - Create:
ruoyi-ui-next/src/views/books/statistictotal/index.vue— 统计汇总 - Create:
ruoyi-ui-next/src/views/books/statisticremain/index.vue— 统计结余 - Create:
ruoyi-ui-next/src/views/stocks/stocks/index.vue— 股票列表 - Create:
ruoyi-ui-next/src/views/stocks/stockbasic/index.vue— 股票基础信息 - Create:
ruoyi-ui-next/src/views/stocks/stockindex/index.vue— 指数信息 - Create:
ruoyi-ui-next/src/views/stocks/financial/index.vue— 财务数据 - Create:
ruoyi-ui-next/src/views/stocks/trends/index.vue— 趋势数据 - Create:
ruoyi-ui-next/src/views/stocks/trendStocks/index.vue— 板块趋势 - Create:
ruoyi-ui-next/src/views/stocks/newrecord/index.vue— 新增记录 - Create:
ruoyi-ui-next/src/views/stocks/stockslimit/index.vue— 涨跌停 - Create:
ruoyi-ui-next/src/views/stocks/book/index.vue— 股票账本 - Create:
ruoyi-ui-next/src/views/monitor/cache/index.vue— 缓存监控 - Create:
ruoyi-ui-next/src/views/monitor/job/index.vue— 定时任务 - Create:
ruoyi-ui-next/src/views/monitor/job/log.vue— 调度日志 - Create:
ruoyi-ui-next/src/views/monitor/logininfor/index.vue— 登录日志 - Create:
ruoyi-ui-next/src/views/monitor/online/index.vue— 在线用户 - Create:
ruoyi-ui-next/src/views/monitor/operlog/index.vue— 操作日志 - Create:
ruoyi-ui-next/src/views/monitor/server/index.vue— 服务器监控 - Create:
ruoyi-ui-next/src/views/tool/gen/index.vue— 代码生成 - Create:
ruoyi-ui-next/src/views/login.vue— 登录页 - Create:
ruoyi-ui-next/src/views/register.vue— 注册页 - Create:
ruoyi-ui-next/src/views/error/401.vue— 401 错误页 - Create:
ruoyi-ui-next/src/views/error/404.vue— 404 错误页 - Create:
ruoyi-ui-next/src/api/*.ts— 所有 API 模块(TypeScript) - Reference:
ruoyi-ui/src/views/目录所有页面文件 - Reference:
ruoyi-ui/src/api/目录所有 API 文件
Dependencies: Task 1, Task 2, Task 3, Task 4 完成
Step 6.1: 迁移 API 调用层
将 ruoyi-ui/src/api/ 下所有 .js 文件重构为 .ts 文件:
- API 类型定义 — 为每个 API 模块定义请求参数和响应类型
- system API (8 文件) — user, role, menu, dept, config, notice, post, dict(data+type)
- monitor API (6 文件) — cache, job, jobLog, logininfor, online, operlog, server
- booksystem API (6 文件) — account, book, operations, statistics, statistictotal, statisticremain
- stocksystem API (9 文件) — stocks, stockbasic, stockindex, financial, trends, trendStocks, newrecord, stockslimit, book
- 保持 API 路径完全一致(如
/system/user/list不变) - 使用
request.get<T>()/request.post<T>()泛型方法
Step 6.2: 迁移系统管理模块(10+ 页面)
每个页面迁移要求:
- 使用
<script setup lang="ts">语法 - 使用 Composition API 替代 Vue 2 Options API
- API 调用使用 TypeScript 类型
- 使用 Element Plus 组件替代 Element UI
- 保持搜索表单 + 表格 + 分页 + 弹窗的 CRUD 布局
- 使用
v-hasPermi指令控制按钮权限 - 使用
DictTag组件展示字典 - 使用
Pagination组件分页
页面清单:
- 用户管理 — 用户列表、新增/编辑弹窗、分配角色、导入/导出
- 角色管理 — 角色列表、权限分配、数据权限、分配用户
- 菜单管理 — 菜单树、新增/编辑弹窗、图标选择
- 部门管理 — 部门树、新增/编辑弹窗
- 参数配置 — 配置列表、新增/编辑弹窗
- 通知公告 — 公告列表、富文本编辑
- 岗位管理 — 岗位列表、新增/编辑弹窗
- 字典管理 — 字典类型列表、字典数据子页面
- 个人中心 — 用户信息修改、头像上传、密码修改
Step 6.3: 迁移账本系统模块(6 页面)
- 交易账户 — 账户列表、CRUD
- 账本管理 — 账本列表、CRUD
- 操作记录 — 操作日志列表
- 统计分析 — 统计图表 + 列表
- 统计汇总 — 汇总数据展示
- 统计结余 — 结余数据展示
Step 6.4: 迁移股票系统模块(8+ 页面)
- 股票列表 — 股票信息列表、CRUD
- 股票基础信息 — 基础数据列表
- 指数信息 — 指数列表
- 财务数据 — 财务信息列表
- 趋势数据 — 趋势数据列表
- 板块趋势 — 板块趋势列表(含业务组件 TrendStocksDialog)
- 新增记录 — 新增记录列表
- 涨跌停 — 涨跌停列表(含业务组件 NegativeDialog)
- 股票账本 — 股票相关账本
Step 6.5: 迁移监控模块(7 页面)
- 缓存监控 — Redis 缓存信息
- 定时任务 — 任务列表、执行、日志
- 调度日志 — 任务执行日志
- 登录日志 — 登录记录列表
- 在线用户 — 在线用户列表、强退
- 操作日志 — 操作记录列表
- 服务器监控 — CPU/内存/磁盘信息
Step 6.6: 迁移认证和错误页面
- 登录页 — 用户名/密码/验证码登录,RSA 加密
- 注册页 — 用户注册
- 401 错误页 — 无权限页面
- 404 错误页 — 页面不存在
Step 6.7: 优化 API 调用层
- 添加请求重试机制(可配置重试次数和间隔)
- 添加请求取消机制(页面切换时取消未完成的请求)
- 统一错误码处理逻辑
- 添加 API 请求 loading 状态管理
验收标准:
- 所有页面可正常访问(路由配置正确)
- CRUD 操作功能正常(增删改查)
- 分页功能正常
- 搜索/过滤功能正常
- 权限按钮正确显示/隐藏
- 字典标签正确渲染
- 文件上传功能正常
- 富文本编辑器正常工作
- 与后端 API 完全兼容(无需后端改动)
- TypeScript 编译零错误
- 无 ESLint 报错
Task 7: 测试和优化
目标: 功能测试、性能优化、响应式适配、浏览器兼容性测试
Files:
- Modify:
ruoyi-ui-next/vite.config.ts(构建优化配置) - Modify:
ruoyi-ui-next/src/utils/request.ts(性能优化) - Create:
ruoyi-ui-next/.browserslistrc - Reference: 所有已创建的页面和组件文件
Dependencies: Task 1-6 全部完成
Step 7.1: 功能测试
- 登录/注册流程测试
- 动态路由加载测试(不同角色看到不同菜单)
- 权限控制测试(无权限按钮隐藏)
- 所有系统管理页面 CRUD 测试
- 所有业务模块页面功能测试
- 监控模块页面功能测试
- 数据可视化页面测试(行情总览 + 趋势热力图)
- 标签页操作测试(切换、关闭、刷新、关闭其他)
- 主题切换测试(深色/浅色)
- 文件上传/下载测试
- 富文本编辑器测试
- 401 处理测试(Token 过期 → 确认弹窗 → 退出登录)
Step 7.2: 性能优化
构建优化:
- 配置 Vite 代码分割(
manualChunks)element-plus独立 chunkecharts独立 chunkvendor第三方库 chunk
- 启用 gzip/brotli 压缩
- 图片资源优化(自动 webp 转换)
- 移除开发环境的 source map
- 配置预加载/预取策略
运行时优化:
- 路由懒加载验证(所有路由页面按需加载)
- ECharts 按需引入(仅使用需要的图表类型)
- 大表格虚拟滚动(如数据量超过 100 行)
- 图片懒加载
- keep-alive 缓存策略优化
- 移除未使用的依赖和代码
加载速度目标:
- 首屏加载 < 2 秒(3G 网络模拟)
- 构建产物 < 2 MB(gzip 后)
- 构建时间 < 30 秒
Step 7.3: 响应式适配
- 桌面端(1920px / 1440px / 1280px)
- 平板端(1024px / 768px)
- 移动端(375px)— 侧边栏自动折叠
- 热力图矩阵在小屏幕下可横向滚动
- 表格在小屏幕下可横向滚动
- 弹窗在小屏幕下自适应宽度
Step 7.4: 浏览器兼容性
- Chrome 90+
- Firefox 90+
- Safari 14+
- Edge 90+
- 配置
.browserslistrc - 验证无浏览器特有 API 使用(或添加 polyfill)
Step 7.5: 代码质量检查
- ESLint 全量检查通过(零警告)
- TypeScript 严格模式编译通过(零错误)
- Prettier 格式化全部代码
- 无
any类型滥用(最多 5 处any) - 无 Vue 2 残留代码(
this.引用、Mixin、Options API) - 组件命名规范检查
- 导入路径规范检查(使用
@/别名)
验收标准:
- 所有页面功能测试通过
- 首屏加载 < 2 秒
- 构建产物 < 2 MB(gzip 后)
- 响应式适配桌面/平板/移动端
- 主流浏览器兼容
- ESLint + TypeScript 零错误
- 无 Vue 2 残留代码
- 项目可独立运行(
npm run dev+npm run build)
任务依赖关系图
Task 1 (项目初始化)
│
▼
Task 2 (核心架构搭建)
│
▼
Task 3 (深色主题和 UI 框架) ──┐
│ │
▼ ▼
Task 4 (核心组件迁移) Task 5 (数据可视化实现)
│ │
└──────────┬───────────────┘
│
▼
Task 6 (业务模块迁移)
│
▼
Task 7 (测试和优化)
里程碑
| 里程碑 | 包含任务 | 预期产出 |
|---|---|---|
| M1: 项目骨架 | Task 1 | 可运行的 Vite + Vue3 + TS 空项目 |
| M2: 架构就绪 | Task 2 | 路由、状态、权限、API 层完成 |
| M3: 主题完成 | Task 3 | 深色主题 + Element Plus 配置完成 |
| M4: 组件迁移 | Task 4 | 所有布局组件和通用组件迁移完成 |
| M5: 可视化完成 | Task 5 | 行情总览和趋势热力图页面完成 |
| M6: 全量迁移 | Task 6 | 所有业务页面迁移完成 |
| M7: 发布就绪 | Task 7 | 测试通过、性能达标、可部署 |
风险提示
| 风险 | 影响 | 应对策略 |
|---|---|---|
| ECharts 5 API 变化 | 图表组件需适配 | 对比 4.x/5.x 文档,逐项验证 |
| Element Plus 组件 API 差异 | 部分组件属性变更 | 查阅 Element Plus 文档,逐个适配 |
| Quill 富文本编辑器兼容性 | 可能需替换方案 | 准备 wangEditor 作为备选 |
| 后端 API 未适配 Vue3 | 前端需额外处理 | 保持 API 调用层兼容,无需后端改动 |
| 大项目 TypeScript 类型定义工作量 | 开发周期延长 | 优先核心类型,逐步补充 |
| 旧组件逻辑复杂难以重构 | 重构风险高 | 先复制功能,再逐步优化 |
自检查
1. 规范覆盖
- Task 1: 项目初始化 ✓
- Task 2: 核心架构搭建 ✓
- Task 3: 深色主题和 UI 框架 ✓
- Task 4: 核心组件迁移 ✓
- Task 5: 数据可视化实现 ✓
- Task 6: 业务模块迁移 ✓
- Task 7: 测试和优化 ✓
2. Placeholder 扫描
- 无 "TBD"、"TODO"
- 无 "implement later"
- 所有步骤包含具体文件路径和实施内容
- 无 "Similar to Task N"
3. 类型一致性
- 所有路径使用
ruoyi-ui-next/前缀 - 文件名命名一致(kebab-case / PascalCase)
- API 路径与现有后端一致
- CSS 变量命名与 demo 一致
4. 最小单元验证
- 每个任务可独立执行(按依赖顺序)
- 每个任务有明确输出和验收标准
- 每个任务可独立验证
- 依赖关系清晰
执行选择
计划完成!共 7 个任务,约 150+ 步骤,产出完整的 Vue3 前端项目。
执行选项:
- Subagent-Driven(推荐) — 每个任务分发到独立子 agent 执行,任务间审查,快速迭代
- Inline Execution — 在当前会话中顺序执行所有任务
- 按里程碑分批执行 — 按 M1-M7 分批,每个里程碑完成后审查再继续
您希望采用哪种执行方式?