diff --git a/README.md b/README.md index 6f36105..444d5f1 100644 --- a/README.md +++ b/README.md @@ -1,104 +1,406 @@ -# apes-Authon-Web +# apes-Authon-Web — 账权管理前端 -> 纯净账权管理前端 — 从 saas-web 单体应用中剥离的账权模块前端,与后端 [apes-Authon](https://gitea.apescale.com/figmar/apes-Authon) 配合使用。 +> 从 saas-web 单体应用中剥离的纯净账权管理前端,与后端 [apes-Authon](https://gitea.apescale.com/figmar/apes-Authon) 配合使用 +> **已通过构建验证**,可独立部署 + +## 项目背景 + +本项目源自 `saas-web`(账权平台前端单体应用),经过模块耦合度分析确认账权前端页面与业务页面(溯源、过磅、灌溉等)之间仅通过路由配置和 Vuex Store 间接关联,具备独立剥离条件。本仓库是提取后的纯净账权前端代码,不包含任何业务页面逻辑。 + +### 剥离依据 + +- 账权页面(login/user/permission/customer/app)与业务页面(fei/trace/weight/tracing)之间零组件互相引用 +- 业务 API(weightApi/huobanTableApi/traceApi 等)仅被业务页面引用,账权页面不依赖 +- 动态路由通过后端菜单接口 + `require.context` 运行时注册,页面删除不影响路由框架 +- 共享层(request.js / store / layout / utils)可通过移除业务引用实现纯净化 ## 技术栈 -- Vue 2.7 + Element UI 2.15 -- Vuex 3 + Vue Router 3 -- Axios + SCSS -- Monaco Editor (AI 工具编辑器) +| 组件 | 版本 | 用途 | +|------|------|------| +| Vue | 2.7.14 | 前端框架 | +| Element UI | 2.15.14 | UI 组件库 | +| Vue Router | 3.5.4 | 路由管理 | +| Vuex | 3.1.3 | 状态管理 | +| Axios | 0.18.1 | HTTP 请求 | +| Monaco Editor | 0.30.1 | AI 工具代码编辑器 | +| marked | 4.3.0 | Markdown 渲染(AI 对话) | +| highlight.js | 11.11.1 | 代码高亮(AI 对话) | +| Sass | 1.26.8 | 样式预处理 | + +> Vue / VueRouter / Vuex / ElementUI / Axios 通过 CDN externals 引入(见 `public/index.html`),不打包进 bundle,显著减小构建体积。 ## 功能模块 -| 模块 | 页面 | 说明 | -|------|------|------| -| 登录注册 | login, register | 短信登录 + 密码登录 + SSO | -| 用户管理 | user/ | 账号列表、编辑、信息、改密、SSO 配置 | -| 客户管理 | customer/ | 客户列表、详情、编辑、员工、套餐、配额 | -| 权限管理 | permission/ | 菜单管理、权限项、角色管理 | -| 应用管理 | app/ | 应用列表、详情 | -| 系统配置 | system/ | 组织架构、操作日志、配额、套餐方案 | -| AI/LLM | system/llmModel/, system/llmAgent/, system/aiHelper/, ai/ | 模型配置、Agent 管理、工具管理、对话、日志 | -| AccessToken | customer/accessToken | API 令牌管理 | +| 模块 | 页面数 | 说明 | +|------|--------|------| +| 登录注册 | 2 | 短信验证码登录、密码登录、SSO 单点登录、用户注册 | +| 用户管理 | 5 | 账号列表、个人信息、编辑资料、修改密码、SSO 配置 | +| 客户管理 | 12 | 客户列表、详情、编辑、员工管理、套餐、配额变更、AccessToken | +| 权限管理 | 3 | 菜单管理、权限项管理、角色管理 | +| 应用管理 | 2 | 应用列表、应用详情 | +| 系统配置 | 4 | 组织架构、操作日志、配额模板、套餐方案 | +| AI/LLM 配置 | 4 | LLM 模型配置、Agent 管理、Agent 编辑/详情、AI 助手测试 | +| AI 工具管理 | 7 | 工具列表、工具编辑、技能管理、调用日志、工具日志、对话历史、AI 对话 | +| 首页 | 1 | 数据看板 | +| **合计** | **40** | | ## 项目结构 ``` apes-Authon-Web/ -├── docs/ # 方案文档 -├── public/ # 静态资源 +├── docs/ # 文档 +│ ├── apes-Authon-Web-剥离方案.md # 剥离方案(计划文档) +│ ├── apes-Authon-Web-剥离方案.html # 剥离方案(HTML 版) +│ └── 剥离历史与说明.md # 剥离执行记录与变更说明 +├── public/ # 静态资源 +│ ├── index.html # HTML 模板(含 CDN externals) +│ └── static/ # 静态文件 ├── src/ -│ ├── api/ # API 接口(19 个) -│ ├── assets/ # 图片资源 -│ ├── components/ # 公共组件(含 AI 助手) -│ ├── layout/ # 布局组件(侧栏、顶栏、标签页) -│ ├── router/ # 路由配置 -│ ├── store/ # Vuex 状态管理 -│ ├── styles/ # 全局样式 -│ ├── utils/ # 工具函数 -│ └── views/ # 页面 -│ ├── login/ # 登录 -│ ├── register/ # 注册 -│ ├── user/ # 用户管理 -│ ├── permission/ # 权限管理 -│ ├── customer/ # 客户管理 -│ ├── app/ # 应用管理 -│ ├── system/ # 系统配置 + AI/LLM 配置 -│ ├── ai/ # AI 工具管理 -│ ├── home/ # 首页看板 -│ └── 404.vue # 404 页面 +│ ├── api/ # API 接口层(19 个文件) +│ │ ├── user.js # 登录/注册/用户管理 +│ │ ├── permissionApi.js # 菜单/权限/角色 CRUD +│ │ ├── menuApi.js # 动态路由构建(require.context) +│ │ ├── customerApi.js # 客户管理 +│ │ ├── customerPackageApi.js # 客户套餐 +│ │ ├── accessTokenApi.js # API 令牌管理 +│ │ ├── appApi.js # 应用管理 +│ │ ├── organizationApi.js # 组织架构 +│ │ ├── quotaApi.js # 配额管理 +│ │ ├── packagePlanApi.js # 套餐方案 +│ │ ├── baseApi.js # 基础接口(文件上传等) +│ │ ├── llmModelApi.js # LLM 模型配置 +│ │ ├── llmAgentApi.js # LLM Agent 管理 +│ │ ├── llmAgentSkillApi.js # Agent 技能管理 +│ │ ├── llmAgentToolApi.js # Agent 工具管理 +│ │ ├── llmToolApi.js # LLM 工具管理 +│ │ ├── llmToolLogApi.js # 工具调用日志 +│ │ ├── llmConversationApi.js # 对话历史 +│ │ └── aiSkill.js # AI 技能管理 +│ ├── assets/ # 图片资源 +│ ├── components/ # 公共组件 +│ │ ├── breadcrumb.vue # 面包屑导航 +│ │ ├── tagView.vue # 标签页缓存 +│ │ ├── pageBox.vue # 页面容器 +│ │ ├── iframeView.vue # 通用 iframe(menuType 2/3/4) +│ │ ├── MarkdownContent.vue # Markdown 渲染(marked + hljs) +│ │ └── ai/ +│ │ └── ai_helper.vue # AI 助手浮窗组件 +│ ├── layout/ # 布局组件 +│ │ ├── index.vue # 主布局(侧栏 + 顶栏 + 内容区) +│ │ ├── components/ +│ │ │ ├── Sidebar/ # 侧边栏菜单 +│ │ │ ├── TagsView/ # 标签页导航 +│ │ │ └── TopHeader.vue # 顶部导航栏 +│ ├── router/ +│ │ └── index.js # 路由配置(静态路由 + 动态路由容器) +│ ├── store/ # Vuex 状态管理 +│ │ ├── index.js # Store 入口 +│ │ ├── getters.js # 全局 getters +│ │ └── modules/ +│ │ ├── user.js # 用户/客户/应用/菜单状态 +│ │ ├── tagsView.js # 标签页缓存状态 +│ │ └── settings.js # 布局设置 +│ ├── styles/ # 全局样式 +│ │ ├── index.scss # 样式入口 +│ │ ├── variables.scss # SCSS 变量 +│ │ ├── mixin.scss # 混入 +│ │ ├── sidebar.scss # 侧边栏样式 +│ │ ├── element-ui.scss # Element UI 覆写 +│ │ └── transition.scss # 过渡动画 +│ ├── utils/ # 工具函数 +│ │ ├── request.js # Axios 封装(拦截器/Token/错误处理) +│ │ ├── index.js # 通用工具函数 +│ │ ├── validate.js # 校验工具 +│ │ ├── msgUtil.js # 消息提示工具 +│ │ ├── public.js # 公共方法 +│ │ ├── constUtil.js # 常量 +│ │ ├── envUtil.js # 环境变量 +│ │ ├── autoRefresh.js # 自动刷新 +│ │ ├── uiSizeUtil.js # UI 尺寸 +│ │ └── get-page-title.js # 页面标题 +│ ├── views/ # 页面 +│ │ ├── login/ # 登录 +│ │ ├── register/ # 注册 +│ │ ├── user/ # 用户管理(5 页面) +│ │ ├── permission/ # 权限管理(3 页面) +│ │ ├── customer/ # 客户管理(12 页面) +│ │ ├── app/ # 应用管理(2 页面) +│ │ ├── system/ # 系统配置 + AI/LLM(8 页面) +│ │ ├── ai/ # AI 工具管理(7 页面) +│ │ ├── home/ # 首页看板 +│ │ ├── base/ # 基础页面(图片上传) +│ │ └── 404.vue # 404 错误页 +│ ├── App.vue # 根组件 +│ └── main.js # 应用入口 ├── package.json ├── vue.config.js -└── README.md +├── babel.config.js +├── postcss.config.js +├── jsconfig.json +└── .gitignore ``` -## 开发 +## 快速开始 + +### 环境要求 + +- Node.js >= 14(推荐 16.x / 18.x) +- npm >= 6 + +### 安装与运行 ```bash -# 安装依赖 +# 1. 克隆仓库 +git clone https://gitea.apescale.com/figmar/apes-Authon-Web.git +cd apes-Authon-Web + +# 2. 安装依赖 npm install -# 启动开发服务器 +# 3. 启动开发服务器(默认端口 8201) npm run dev -# 构建生产版本 +# 4. 构建生产版本 npm run build:prod + +# 5. 构建预发布版本 +npm run build:stage ``` +开发服务器启动后访问 `http://localhost:8201`。 + +### 代理配置 + +`vue.config.js` 中已配置开发环境代理: + +```javascript +proxy: { + '/api/user-service': { + target: 'http://localhost:8202', // 后端 apes-Authon 服务地址 + changeOrigin: true, + pathRewrite: { '^/api/user-service': '/' } + } +} +``` + +如后端地址不同,修改 `target` 即可。 + +### 部署 + +```bash +# 构建产物在 authon-web/ 目录 +npm run build:prod + +# 将 authon-web/ 部署到 Nginx / 其他 Web 服务器 +# Nginx 参考配置: +# server { +# listen 80; +# server_name your-domain.com; +# root /path/to/authon-web; +# index index.html; +# location / { try_files $uri $uri/ /index.html; } +# location /api/ { proxy_pass http://backend:8090; } +# } +``` + +> 构建输出目录为 `authon-web`(在 `vue.config.js` 的 `outputDir` 中配置)。 + +## 架构说明 + +### 路由体系 + +本项目采用 **静态路由 + 动态路由** 双层路由架构: + +**静态路由**(`router/index.js`): +- `/login` — 登录页 +- `/register` — 注册页 +- `/user/*` — 用户管理(5 个子路由) +- `/base/*` — 基础配置(图片上传、应用管理、权限管理) +- `/customer/*` — 客户管理(6 个子路由) +- `/common` — **动态路由容器**(children 初始为空) +- `/error/404` — 404 页面 +- `/` — 首页看板(重定向到 `/login`) + +**动态路由**(`menuApi.js`): +应用启动时,`main.js` 调用后端接口获取当前用户的菜单列表,`menuApi.handleMenu()` 根据菜单数据动态注册路由到 `/common` 下: + +| menuType | 处理方式 | 示例 | +|----------|----------|------| +| 1 | Vue 页面 — 通过 `require.context` 映射到 `@/views/${menu.vuePath}` | `views/user/list.vue` | +| 2 | 伙伴云 iframe — 使用 `iframeView` 组件 | 外部表单 | +| 3 | 支付 iframe — 使用 `iframeView` 组件 | 支付页面 | +| 4 | Web iframe — 使用 `iframeView` 组件 | 外部链接 | + +```javascript +// menuApi.js 核心逻辑 +handleMenu(menuList) { + menuList.forEach(menu => { + if (menu.menuType === 2 || menu.menuType === 3 || menu.menuType === 4) { + // iframe 类型:统一使用 iframeView 组件 + router.addRoute('common', { + path: typePrefix + '/' + menu.id, + component: () => import('@/components/iframeView'), + ... + }) + } + if (menu.menuType === 1) { + // Vue 页面:动态加载对应组件 + router.addRoute('common', { + path: menu.menuPath, + component: (resolve) => require([`@/views/${menu.vuePath}`], resolve), + ... + }) + } + if (menu.child) this.handleMenu(menu.child) // 递归处理子菜单 + }) +} +``` + +### 状态管理 + +Vuex Store 包含两个模块: + +**user 模块**(`store/modules/user.js`): + +| State | 说明 | +|-------|------| +| `loginUser` | 当前登录用户信息 | +| `currentCustomer` | 当前客户/企业信息 | +| `appList` | 用户可访问的应用列表 | +| `currentApp` | 当前选中应用 | +| `currentAppMenus` | 当前应用的菜单树 | +| `allAppMenus` | 所有应用的菜单映射 | +| `menuList` | 当前菜单列表 | + +**tagsView 模块**(`store/modules/tagsView.js`): +- 管理标签页的打开/关闭/缓存 + +### 请求层 + +`utils/request.js` 封装了 Axios 实例: + +- **请求拦截器**:自动注入 `token`(从 `localStorage` 读取)、`time`(时间戳)、`version`(API 版本) +- **响应拦截器**:检测 `code === 99`(未登录),自动跳转登录页(注册页除外) +- **方法封装**:`apiGet` / `apiPost` / `apiPostJson` / `apiDownloadPost` + +```javascript +// 请求拦截器自动注入 token +config.headers = { + ...config.headers, + time: new Date().getTime(), + version: '1.1', + token: localStorage.getItem('_token') || '' +} +``` + +### 启动流程 + +`main.js` 的应用启动流程: + +``` +1. 从 URL 参数读取 token(支持 SSO 跳转) → 写入 localStorage +2. 调用 getCurrentUser() → 获取用户信息 + 客户信息 +3. 调用 getMyApps() → 获取应用列表 +4. 遍历应用 → 调用 getAppMenus() → 获取每个应用的菜单 +5. menuApi.handleMenu() → 动态注册路由 +6. 匹配当前 URL → 设置当前应用和菜单 +7. 实例化 Vue 应用 +``` + +### CDN Externals 机制 + +`public/index.html` 通过 CDN `