chore: 清理冗余配置、优化代码结构
- 移除 SSE 独立代理(VITE_APP_SSE_URL)及相关配置 - 删除 CHANGELOG.md,清理 .env 多余注释 - 重构 permission.ts 路由守卫,用 return 替代 next() 调用 - 优化 useSse.ts:合并重复逻辑、增加中文注释、调整重连参数 - 简化 vite.config.ts 代理和注释
This commit is contained in:
@@ -7,13 +7,10 @@ VITE_APP_BASE_API=/dev-api
|
||||
|
||||
# 接口地址
|
||||
VITE_APP_API_URL=https://api.youlai.tech # 线上
|
||||
# VITE_APP_API_URL=https://api.youlai.tech/v2 # 线上(多租户)
|
||||
# VITE_APP_API_URL=http://localhost:8000 # 本地
|
||||
|
||||
# 启用 Mock 服务(true:开启 false:关闭)
|
||||
VITE_MOCK_DEV_SERVER=false
|
||||
|
||||
|
||||
# 多租户开关(true:开启 false:关闭)
|
||||
VITE_APP_TENANT_ENABLED=false
|
||||
|
||||
|
||||
@@ -1,16 +1,8 @@
|
||||
# ============================================
|
||||
# 🌐 网络配置
|
||||
# ============================================
|
||||
# 代理前缀
|
||||
VITE_APP_BASE_API = '/prod-api'
|
||||
# 项目名称
|
||||
VITE_APP_TITLE=vue3-element-admin
|
||||
# WebSocket 端点(可选)
|
||||
#VITE_APP_WS_ENDPOINT=wss://api.youlai.tech/ws
|
||||
|
||||
# ============================================
|
||||
# 🎛️ 功能开关
|
||||
# ============================================
|
||||
# 多租户(需与后端 app.tenant.enabled 保持一致)
|
||||
# 多租户开关(true/false)
|
||||
VITE_APP_TENANT_ENABLED=true
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
npm run lint:lint-staged -- --no-stash
|
||||
npm run lint:lint-staged
|
||||
386
CHANGELOG.md
386
CHANGELOG.md
@@ -1,386 +0,0 @@
|
||||
|
||||
# 2.11.5 (2024/6/18)
|
||||
|
||||
## ✨ feat
|
||||
|
||||
- 支持后端文件导入([#142](https://github.com/youlaitech/vue3-element-admin/pull/142)) [@cshaptx4869](https://github.com/cshaptx4869)
|
||||
|
||||
|
||||
## 🐛 fix
|
||||
- vue-dev-tools 插件导致菜单路由切换卡死,暂时关闭 ([28349e](https://github.com/youlaitech/vue3-element-admin/commit/28349efe147afab36531ba148eaac3a448fe6c71)) [@haoxianrui](https://github.com/haoxianrui)
|
||||
|
||||
|
||||
|
||||
# 2.11.4 (2024/6/16)
|
||||
|
||||
## ✨ feat
|
||||
|
||||
- 操作栏增加render配置参数([#138](https://github.com/youlaitech/vue3-element-admin/pull/140)) [@cshaptx4869](https://github.com/cshaptx4869)
|
||||
- 左侧工具栏增加type配置参数([#141](https://github.com/youlaitech/vue3-element-admin/pull/141)) [@diamont1001](https://github.com/diamont1001)
|
||||
|
||||
## ♻️ refactor
|
||||
- 更换权限分配弹窗类型为 drawer 并添加父子联动开关([2d9193](https://github.com/youlaitech/vue3-element-admin/commit/2d9193c47fd224f01f82b9c0b2bbeb5e7cb33584)) [@haoxianrui](https://github.com/haoxianrui)
|
||||
|
||||
|
||||
|
||||
# 2.11.3 (2024/6/11)
|
||||
|
||||
## ✨ feat
|
||||
|
||||
- 支持默认工具栏的导入([#138](https://github.com/youlaitech/vue3-element-admin/pull/138)) [@cshaptx4869](https://github.com/cshaptx4869)
|
||||
- 添加CURD导入示例([19e7bb](https://github.com/youlaitech/vue3-element-admin/commit/eab91effd6a01d5a3d9257249c8d06aa252b3bf8)) [@cshaptx4869](https://github.com/cshaptx4869)
|
||||
|
||||
## ♻️ refactor
|
||||
- 修改导出全量数据选项文本([904fec](https://github.com/youlaitech/vue3-element-admin/commit/904fecad65217650482fcdbb10ffb7f3d27eb9ea)) [@cshaptx4869](https://github.com/cshaptx4869)
|
||||
|
||||
## 🐛 fix
|
||||
- 菜单列表未适配el-icon导致图标不显示问题修复([e72b68](https://github.com/youlaitech/vue3-element-admin/commit/e72b68337562b5a7ea24ad55bbe00023e1266b40)) [@haoxianrui](https://github.com/haoxianrui)
|
||||
|
||||
# 2.11.2 (2024/6/8)
|
||||
|
||||
## ✨ feat
|
||||
|
||||
- 支持表格远程筛选([#131](https://github.com/youlaitech/vue3-element-admin/pull/131)) [@cshaptx4869](https://github.com/cshaptx4869)
|
||||
- 支持标签输入框([#132](https://github.com/youlaitech/vue3-element-admin/pull/132)) [@cshaptx4869](https://github.com/cshaptx4869)
|
||||
- 表单项支持tips配置([#133](https://github.com/youlaitech/vue3-element-admin/pull/133)) [@cshaptx4869](https://github.com/cshaptx4869)
|
||||
- 前端导出支持全量数据([#134](https://github.com/youlaitech/vue3-element-admin/pull/134)) [@cshaptx4869](https://github.com/cshaptx4869)
|
||||
- 支持选中数据导出([#135](https://github.com/youlaitech/vue3-element-admin/pull/135)) [@cshaptx4869](https://github.com/cshaptx4869)
|
||||
- 表格默认工具栏的导出、搜索按钮增加权限点控制([883128](https://github.com/youlaitech/vue3-element-admin/commit/8831289b655f2cc086ecdababaa89f8d8a087c42)) [@cshaptx4869](https://github.com/cshaptx4869)
|
||||
- 页签title支持动态设置([23876a](https://github.com/youlaitech/vue3-element-admin/commit/23876aa396143bf77cb5c86af8d6023d9ff6555a)) [@haoxianrui](https://github.com/haoxianrui)
|
||||
|
||||
## ♻️ refactor
|
||||
- 默认工具栏支持自定义([#136](https://github.com/youlaitech/vue3-element-admin/pull/136)) [@cshaptx4869](https://github.com/cshaptx4869)
|
||||
- 未配置全量导出接口时选项隐藏([eab91ef](https://github.com/youlaitech/vue3-element-admin/commit/eab91effd6a01d5a3d9257249c8d06aa252b3bf8)) [@cshaptx4869](https://github.com/cshaptx4869)
|
||||
|
||||
## 🐛 fix
|
||||
- 修复注销登出后redirect跳转路由参数丢失([5626017](https://github.com/youlaitech/vue3-element-admin/commit/562601736731afd20bb1a5140d856f6515720159)) [@haoxianrui](https://github.com/haoxianrui)
|
||||
|
||||
# 2.11.1 (2024/6/6)
|
||||
|
||||
## ✨ feat
|
||||
|
||||
- 增加pagination、request、parseData配置参数([#119](https://github.com/youlaitech/vue3-element-admin/pull/119)) [@cshaptx4869](https://github.com/cshaptx4869)
|
||||
- 增加返回顶部功能([#120](https://github.com/youlaitech/vue3-element-admin/pull/120)) [@cshaptx4869](https://github.com/cshaptx4869)
|
||||
- 支持前端导出([#126](https://github.com/youlaitech/vue3-element-admin/pull/126)) [@cshaptx4869](https://github.com/cshaptx4869)
|
||||
|
||||
## ♻️ refactor
|
||||
- 重构布局样式(解决页面抖动问题)([#116](https://github.com/youlaitech/vue3-element-admin/pull/116)) [@cshaptx4869](https://github.com/cshaptx4869)
|
||||
- 修改CURD示例编辑弹窗尺寸([#121](https://github.com/youlaitech/vue3-element-admin/pull/121)) [@cshaptx4869](https://github.com/cshaptx4869)
|
||||
- 统一注册vue插件([#122](https://github.com/youlaitech/vue3-element-admin/pull/122)) [@cshaptx4869](https://github.com/cshaptx4869)
|
||||
- 默认主题跟随系统([#128](https://github.com/youlaitech/vue3-element-admin/pull/128)) [@cshaptx4869](https://github.com/cshaptx4869)
|
||||
- 增加"scss.lint.unknownAtRules": "ignore"代码,解决style中使用@apply提示unknow at rules@apply提示问题([Gitee#22](https://gitee.com/youlaiorg/vue3-element-admin/pulls/22)) [@zjsy521](https://gitee.com/zjsy521)
|
||||
|
||||
## 🐛 fix
|
||||
- 修复左侧布局移动端菜单弹出样式 ([#117](https://github.com/youlaitech/vue3-element-admin/pull/117)) [@cshaptx4869](https://github.com/cshaptx4869)
|
||||
|
||||
- 修复编辑后未清空id再新增菜单覆盖的问题([0e78eeb](https://github.com/youlaitech/vue3-element-admin/commit/0e78eeb75008fa8e9732b1b4e7d7a1ea345c7a1b)) [@haoxianrui](https://github.com/haoxianrui)
|
||||
- 修复水印层级问题([#123](https://github.com/youlaitech/vue3-element-admin/pull/123)) [@cshaptx4869](https://github.com/cshaptx4869)
|
||||
- 修复混合布局样式问题([#124](https://github.com/youlaitech/vue3-element-admin/pull/124)) [@cshaptx4869](https://github.com/cshaptx4869)
|
||||
- 修复关闭弹窗时没有clearValidate问题([#125](https://github.com/youlaitech/vue3-element-admin/pull/125)) [@andm31](https://github.com/andm31)
|
||||
|
||||
|
||||
|
||||
# 2.11.0 (2024/5/27)
|
||||
|
||||
## ✨ feat
|
||||
- 菜单添加路由参数设置(author by [haoxianrui](https://github.com/haoxianrui))
|
||||
- 增加列表选择组件(author by [cshaptx4869](https://github.com/cshaptx4869))
|
||||
- 增加列表选择组件使用示例(author by [cshaptx4869](https://github.com/cshaptx4869))
|
||||
- 增加defaultToolbar配置参数(author by [cshaptx4869](https://github.com/cshaptx4869))
|
||||
- 表单弹窗支持drawer模式(author by [cshaptx4869](https://github.com/cshaptx4869))
|
||||
- 表单项增加computed和watchEffect配置(author by [cshaptx4869](https://github.com/cshaptx4869))
|
||||
- 支持switch属性修改(author by [cshaptx4869](https://github.com/cshaptx4869))
|
||||
- 表单项增加文本类型支持(author by [cshaptx4869](https://github.com/cshaptx4869))
|
||||
- 列表列增加show配置项(author by [cshaptx4869](https://github.com/cshaptx4869))
|
||||
- 支持搜索表单显隐控制(author by [cshaptx4869](https://github.com/cshaptx4869))
|
||||
- 支持input属性修改(author by [cshaptx4869](https://github.com/cshaptx4869))
|
||||
- search配置新增函数能力拓展(author by [xiudaozhe](https://github.com/xiudaozhe))
|
||||
- 表格新增列设置控制(author by [haoxianrui](https://github.com/haoxianrui))
|
||||
- 搜索添加展开和收缩(author by [haoxianrui](https://github.com/haoxianrui))
|
||||
- watch函数增加配置项参数返回(author by [cshaptx4869](https://github.com/cshaptx4869))
|
||||
|
||||
## ♻️ refactor
|
||||
- 重构图标选择组件(author by [cshaptx4869](https://github.com/cshaptx4869))
|
||||
- 重构列表选择组件默认样式 (author by [cshaptx4869](https://github.com/cshaptx4869))
|
||||
- 加强对话框表单组件和列表选择组件(author by [cshaptx4869](https://github.com/cshaptx4869))
|
||||
- routeMeta增加alwaysShow字段声明(author by [cshaptx4869](https://github.com/cshaptx4869))
|
||||
- 分页组件增加溢出滚动效果(author by [cshaptx4869](https://github.com/cshaptx4869))
|
||||
- 修正登录表单的Ref类型(author by [cshaptx4869](https://github.com/cshaptx4869))
|
||||
- 点击表格刷新按钮不重置页码(author by [cshaptx4869](https://github.com/cshaptx4869))
|
||||
- 筛选列超出一定高度滚动(author by [cshaptx4869](https://github.com/cshaptx4869))
|
||||
- 优化加强initFn函数,表单项增加initFn函数(author by [cshaptx4869](https://github.com/cshaptx4869))
|
||||
- 重构watch、computed、watchEffect调用(author by [cshaptx4869](https://github.com/cshaptx4869))
|
||||
- 修改操作成功提示(author by [cshaptx4869](https://github.com/cshaptx4869))
|
||||
- PageSearch 改用card作为容器,样式改用unocss写法(author by [cshaptx4869](https://github.com/cshaptx4869))
|
||||
- 优化首页 loading 动画效果author by [haoxianrui](https://github.com/haoxianrui))
|
||||
|
||||
|
||||
## 🐛 fix
|
||||
- 路由是否始终显示不限制只有顶级目录才有的配置,开放至菜单 (author by [haoxianrui](https://github.com/haoxianrui))
|
||||
- sockjs-client 报错 global is not defined 导致开发环境无法打开 WebSocket 页面问题修复 (author by [haoxianrui](https://github.com/haoxianrui))
|
||||
- 发送用户重启密码功能,最少为6位字符(小于6位登陆时不允许的问题) (author by [dreamnyj](https://gitee.com/dreamnyj))
|
||||
- 修复系统设置面板滚动条问题(author by [cshaptx4869](https://github.com/cshaptx4869))
|
||||
- 修复表单插槽失效问题(author by [cshaptx4869](https://github.com/cshaptx4869))
|
||||
- 修改tagsview刷新丢失query问题(author by [xiudaozhe](https://github.com/xiudaozhe))
|
||||
|
||||
## 📦️ build
|
||||
- 升级 NPM 包版本至最新 (author by [haoxianrui](https://github.com/haoxianrui))
|
||||
|
||||
## ⚙️ ci
|
||||
- 规整脚本执行命令(author by [cshaptx4869](https://github.com/cshaptx4869))
|
||||
|
||||
|
||||
# 2.10.1 (2024/5/4)
|
||||
|
||||
## ♻️ refactor
|
||||
- 抽离CURD的使用部分代码为Hooks实现(author by [cshaptx4869](https://github.com/cshaptx4869))
|
||||
- 修改CURD导入权限点标识名(author by [cshaptx4869](https://github.com/cshaptx4869))
|
||||
- cURD表单字段支持watch监听(author by [cshaptx4869](https://github.com/cshaptx4869))
|
||||
- cURD表单input支持number修饰(author by [cshaptx4869](https://github.com/cshaptx4869))
|
||||
- cURD表单组件支持checkbox多选框(author by [cshaptx4869](https://github.com/cshaptx4869))
|
||||
- 优化axios响应数据TS类型提示(author by [cshaptx4869](https://github.com/cshaptx4869))
|
||||
- 修改CURD表单组件自定义类型的attrs传值(author by [cshaptx4869](https://github.com/cshaptx4869))
|
||||
- 同步重置密码按钮权限标识重命名(author by [haoxianrui](https://github.com/haoxianrui))
|
||||
- 重构API为静态方法实现模块化管理,并将types.ts重命名为model.ts用于存放接口模型定义(author by [haoxianrui](https://github.com/haoxianrui))
|
||||
|
||||
|
||||
## 🐛 fix
|
||||
- sockjs-client 报错 global is not defined 导致开发环境无法打开 WebSocket 页面问题修复 (author by [haoxianrui](https://github.com/haoxianrui))
|
||||
- 主题颜色设置覆盖暗黑模式下el-table行激活的背景色问题修复 (author by [haoxianrui](https://github.com/haoxianrui))
|
||||
- 修复因API接口调整而影响的调用页面的问题 (author by [haoxianrui](https://github.com/haoxianrui))
|
||||
|
||||
## 📦️ build
|
||||
- 升级 NPM 包版本至最新 (author by [haoxianrui](https://github.com/haoxianrui))
|
||||
|
||||
|
||||
# 2.10.0 (2024/4/26)
|
||||
## ✨ feat
|
||||
- 封装增删改查组件(author by [cshaptx4869](https://github.com/cshaptx4869))
|
||||
- 集成 vite-plugin-vue-devtools 插件(author by [Tricker39](https://github.com/Tricker39))
|
||||
- 增加CURD配置化实现(author by [cshaptx4869](https://github.com/cshaptx4869))
|
||||
|
||||
|
||||
# 2.9.3 (2024/04/14)
|
||||
## ✨ feat
|
||||
- 增加vue文件代码片段(author by [cshaptx4869](https://github.com/cshaptx4869))
|
||||
- 菜单 hover 背景色添加值全局SCSS变量进行控制(author by [haoxianrui](https://github.com/haoxianrui))
|
||||
|
||||
## ♻️ refactor
|
||||
- 加强基础国际化(author by [cshaptx4869](https://github.com/cshaptx4869))
|
||||
- 增加语言和布局大小枚举类型(author by [cshaptx4869](https://github.com/cshaptx4869))
|
||||
- 增加侧边栏状态枚举类型(author by [cshaptx4869](https://github.com/cshaptx4869))
|
||||
- 使用布局枚举替换字面量(author by [haoxianrui](https://github.com/haoxianrui))
|
||||
- 控制台使用静态数据循环渲染(author by [april](mailto:april@zen-game.cn))
|
||||
- 本地缓存的 token 变量重命名(author by [haoxianrui](https://github.com/haoxianrui))
|
||||
- 完善 Vite 环境变量类型声明(author by [haoxianrui](https://github.com/haoxianrui))
|
||||
|
||||
## 🐛 fix
|
||||
- 修复构建时提示iconComponent.name可能为undefined的报错 (author by [wangji1042](https://github.com/wangji1042))
|
||||
- 修复浏览器密码自动填充时可能存在的报错 (author by [cshaptx4869](https://github.com/cshaptx4869))
|
||||
- 修复eslint报错(author by [cshaptx4869](https://github.com/cshaptx4869))
|
||||
- 移动端下点击左侧菜单节点后关闭侧边栏(author by [haoxianrui](https://github.com/haoxianrui))
|
||||
- 添加 size 类型断言修复类型报错(author by [haoxianrui](https://github.com/haoxianrui))
|
||||
|
||||
## 📦️ build
|
||||
- husky9.x版本适配 (author by [cshaptx4869](https://github.com/cshaptx4869))
|
||||
- 升级 npm 包版本至最新(author by [haoxianrui](https://github.com/haoxianrui))
|
||||
|
||||
# 2.9.2 (2024/03/05)
|
||||
## ✨ feat
|
||||
- vscode开发扩展推荐(author by [cshaptx4869](https://github.com/cshaptx4869))
|
||||
- 完善基础增删改查Mock接口(author by [haoxianrui](https://github.com/haoxianrui))
|
||||
|
||||
## ♻️ refactor
|
||||
- 修改login密码框功能实现(author by [cshaptx4869](https://github.com/cshaptx4869))
|
||||
- 弱化页面进入动画效果(author by [cshaptx4869](https://github.com/cshaptx4869))
|
||||
- 取消推荐TypeScript Vue Plugin (author by [cshaptx4869](https://github.com/cshaptx4869))
|
||||
- 网站加载动画替换 (author by [haoxianrui](https://github.com/haoxianrui))
|
||||
- 优化主题和主题色监听,避免多个页面重复初始化 (author by [haoxianrui](https://github.com/haoxianrui))
|
||||
|
||||
## 🐛 fix
|
||||
- AppMain 高度在非固定头部不正确导致出现滚动条问题修复 (author by [haoxianrui](https://github.com/haoxianrui))
|
||||
- 修复混合模式开启固定Head时的样式问题 (author by [cshaptx4869](https://github.com/cshaptx4869))
|
||||
- 设置面板统一字体大小 (author by [cshaptx4869](https://github.com/cshaptx4869))
|
||||
|
||||
## 📦️build
|
||||
- 通过env配置控制mock服务 (author by [cshaptx4869](https://github.com/cshaptx4869))
|
||||
- 升级依赖包至最新版本 (author by [haoxianrui](https://github.com/haoxianrui))
|
||||
- 定义vite全局常量替换项目标题和版本 (author by [cshaptx4869](https://github.com/cshaptx4869))
|
||||
|
||||
# 2.9.1 (2024/02/28)
|
||||
## ♻️ refactor
|
||||
- 项目配置按钮移入navbar(author by [cshaptx4869](https://github.com/cshaptx4869))
|
||||
- 优化user数据定义(author by [cshaptx4869](https://github.com/cshaptx4869))
|
||||
- 统一设置栏的 SVG 图标风格
|
||||
|
||||
## 🐛 fix
|
||||
- 规整一些开发依赖(author by [cshaptx4869](https://github.com/cshaptx4869))
|
||||
- 修复登录页主题切换问题 (author by [cshaptx4869](https://github.com/cshaptx4869))
|
||||
|
||||
## 🚀 pref
|
||||
|
||||
- 压缩图片资源 (author by [cshaptx4869](https://github.com/cshaptx4869))
|
||||
|
||||
|
||||
# 2.9.0 (2024/02/25)
|
||||
|
||||
## ✨ feat
|
||||
- 引入 animate.css 动画库
|
||||
- 新增水印和配置
|
||||
- 动态路由菜单支持 element plus 的图标
|
||||
|
||||
## ♻️ refactor
|
||||
- Layout 布局重构和相关问题修复
|
||||
- sass 使用 @use 替代 @import 引入外部文件指令
|
||||
|
||||
## 🐛 fix
|
||||
- 修复管理页面部分弹窗无法打开问题
|
||||
- 主题颜色设置按钮 hover 等未变化问题修复
|
||||
|
||||
|
||||
# 2.8.1 (2024/01/10)
|
||||
|
||||
## ✨ feat
|
||||
- 替换 Mock 解决方案 vite-plugin-mock 为 vite-plugin-mock-dev-server 适配 Vite5
|
||||
|
||||
# 2.8.0 (2023/12/27)
|
||||
|
||||
## ⬆️ chore
|
||||
- 升级 Vite4 至 Vite5
|
||||
|
||||
# 2.7.1 (2023/12/12)
|
||||
|
||||
## ♻️ refactor
|
||||
- 将打包后的文件进行分类 (author by [ityangzhiwen](https://gitee.com/ityangzhiwen))
|
||||
|
||||
# 2.7.0 (2023/11/19)
|
||||
|
||||
## ♻️ refactor
|
||||
- 代码重构优化
|
||||
- 修改自动导入组件类型声明文件路径
|
||||
- 完善 typescript 类型
|
||||
|
||||
## 🐛 fix
|
||||
- 修复管理页面部分弹窗无法打开问题
|
||||
|
||||
|
||||
# 2.7.0 (2023/11/19)
|
||||
|
||||
## ♻️ refactor
|
||||
- 代码重构
|
||||
- 修改自动导入组件类型声明文件路径
|
||||
- 完善 typescript 类型
|
||||
|
||||
## 🐛 fix
|
||||
- 修复管理页面部分弹窗无法打开问题
|
||||
|
||||
|
||||
# 2.6.3 (2023/10/22)
|
||||
|
||||
## ✨ feat
|
||||
- 菜单管理新增目录只有一级子路由是否始终显示(alwaysShow)和路由页面是否缓存(keepAlive)的配置
|
||||
- 接口文档新增 swagger、knife4j
|
||||
- 引入和支持 tsx
|
||||
|
||||
## ♻️ refactor
|
||||
- 代码瘦身,整理并删除未使用的 svg
|
||||
- 控制台样式优化
|
||||
|
||||
## 🐛 fix
|
||||
- 菜单栏折叠和展开的图标暗黑模式显示问题修复
|
||||
|
||||
|
||||
# 2.6.2 (2023/10/11)
|
||||
|
||||
## 🐛 fix
|
||||
- 主题设置未持久化问题
|
||||
- UnoCSS 插件无智能提示
|
||||
|
||||
## ♻️ refactor
|
||||
- WebSocket 演示样式和代码优化
|
||||
- 用户管理代码重构
|
||||
|
||||
# 2.6.1 (2023/9/4)
|
||||
|
||||
## 🐛 fix
|
||||
- 导航顶部模式、混合模式样式在固定 Header 出现的样式问题修复
|
||||
- 固定 Header 没有持久化问题修复
|
||||
- 字典回显兼容 String 和 Number 类型
|
||||
|
||||
# 2.6.0 (2023/8/24)💥💥💥
|
||||
|
||||
## ✨ feat
|
||||
- 导航顶部模式、混合模式支持(author by [april-tong](https://april-tong.com/))
|
||||
- 平台文档(内嵌)(author by [april-tong](https://april-tong.com/))
|
||||
|
||||
# 2.5.0 (2023/8/8)
|
||||
|
||||
## ✨ feat
|
||||
- 新增 Mock(author by [ygcaicn](https://github.com/ygcaicn))
|
||||
- 图标 DEMO(author by [ygcaicn](https://github.com/ygcaicn))
|
||||
|
||||
## 🐛 fix
|
||||
- 字典支持 Number 类型
|
||||
|
||||
# 2.4.1 (2023/7/20)
|
||||
|
||||
## ✨ feat
|
||||
- 整合 vite-plugin-compression 插件打包优化(3.66MB → 1.58MB) (author by [april-tong](https://april-tong.com/))
|
||||
- 字典组件封装(author by [haoxr](https://juejin.cn/user/4187394044331261/posts))
|
||||
|
||||
## 🐛 fix
|
||||
- 分页组件hidden无效
|
||||
- 签名无法保存至后端
|
||||
- Git 提交 stylelint 校验部分机器报错
|
||||
|
||||
# 2.4.0 (2023/6/17)
|
||||
|
||||
## ✨ feat
|
||||
- 新增组件标签输入框(author by [april-tong](https://april-tong.com/))
|
||||
- 新增组件签名(author by [april-tong](https://april-tong.com/))
|
||||
- 新增组件表格(author by [april-tong](https://april-tong.com/))
|
||||
- Echarts 图表添加下载功能 author by [april-tong](https://april-tong.com/))
|
||||
|
||||
## ♻️ refactor
|
||||
- 限制包管理器为 pnpm 和 node 版本16+
|
||||
- 自定义组件自动导入配置
|
||||
- 搜索框样式写法优化
|
||||
|
||||
## 🐛 fix
|
||||
- 用户导入的部门回显成数字问题修复
|
||||
|
||||
## ⬆️ chore
|
||||
- element-plus 版本升级 2.3.5 → 2.3.6
|
||||
|
||||
# 2.3.1 (2023/5/21)
|
||||
|
||||
## 🔄 refactor
|
||||
- 组件示例文件名称优化
|
||||
|
||||
# 2.2.2 (2023/5/11)
|
||||
|
||||
## ✨ feat
|
||||
- 组件封装示例添加源码地址
|
||||
- 角色、菜单、部门、字段按钮添加权限控制
|
||||
|
||||
|
||||
# 2.3.0 (2023/5/12)
|
||||
|
||||
## ⬆️ chore
|
||||
- vue 版本升级 3.2.45 → 3.3.1 ([CHANGELOG](https://github.com/vuejs/core/blob/main/CHANGELOG.md))
|
||||
- vite 版本升级 4.3.1 → 4.3.5
|
||||
|
||||
## ♻️ refactor
|
||||
- 使用 vue 3.3 版本新特性 `defineOptions` 在 `setup` 定义组件名称,移除重复的 `script` 标签
|
||||
|
||||
# 2.2.2 (2023/5/11)
|
||||
|
||||
## ✨ feat
|
||||
- 用户新增提交添加 `vueUse` 的 `useDebounceFn` 函数实现按钮防抖节流
|
||||
|
||||
|
||||
# 2.2.1 (2023/4/25)
|
||||
|
||||
## 🐛 fix
|
||||
- 图标选择器组件使用 `onClickOutside` 未排除下拉弹出框元素导致无法输入搜索。
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
<img src="https://img.shields.io/badge/Vue-3.5.30-brightgreen.svg"/>
|
||||
<img src="https://img.shields.io/badge/Vite-8.0.0-green.svg"/>
|
||||
<img src="https://img.shields.io/badge/Element Plus-2.13.5-blue.svg"/>
|
||||
<img src="https://img.shields.io/badge/Element Plus-2.13.6-blue.svg"/>
|
||||
<img src="https://img.shields.io/badge/license-MIT-green.svg"/>
|
||||
|
||||
<a href="https://gitee.com/youlaiorg/vue3-element-admin" target="_blank">
|
||||
|
||||
@@ -194,7 +194,14 @@ export default [
|
||||
"@typescript-eslint/no-empty-object-type": "off",
|
||||
"@typescript-eslint/ban-ts-comment": "off",
|
||||
"@typescript-eslint/no-non-null-assertion": "off",
|
||||
"@typescript-eslint/no-unused-vars": "warn", // 降级为警告
|
||||
"@typescript-eslint/no-unused-vars": [
|
||||
"warn",
|
||||
{
|
||||
argsIgnorePattern: "^_",
|
||||
varsIgnorePattern: "^_",
|
||||
caughtErrorsIgnorePattern: "^_",
|
||||
},
|
||||
],
|
||||
"@typescript-eslint/no-unused-expressions": "warn", // 降级为警告
|
||||
"@typescript-eslint/consistent-type-imports": "off", // 关闭强制使用type import
|
||||
"@typescript-eslint/no-import-type-side-effects": "error",
|
||||
|
||||
14
package.json
14
package.json
@@ -52,10 +52,10 @@
|
||||
"@wangeditor-next/editor-for-vue": "^5.1.14",
|
||||
"animate.css": "^4.1.1",
|
||||
"axios": "^1.13.6",
|
||||
"codemirror": "^5.65.21",
|
||||
"codemirror": "^5.65.16",
|
||||
"codemirror-editor-vue3": "^2.8.0",
|
||||
"echarts": "^6.0.0",
|
||||
"element-plus": "^2.13.5",
|
||||
"element-plus": "^2.13.6",
|
||||
"exceljs": "^4.4.0",
|
||||
"lodash-es": "^4.17.23",
|
||||
"nprogress": "^0.2.0",
|
||||
@@ -82,8 +82,6 @@
|
||||
"@types/path-browserify": "^1.0.3",
|
||||
"@types/qs": "^6.15.0",
|
||||
"@types/sortablejs": "^1.15.9",
|
||||
"@typescript-eslint/eslint-plugin": "^8.57.0",
|
||||
"@typescript-eslint/parser": "^8.57.0",
|
||||
"@vitejs/plugin-vue": "^6.0.5",
|
||||
"autoprefixer": "^10.4.27",
|
||||
"commitizen": "^4.3.1",
|
||||
@@ -94,6 +92,7 @@
|
||||
"eslint-plugin-vue": "^10.8.0",
|
||||
"globals": "^17.4.0",
|
||||
"husky": "^9.1.7",
|
||||
"jiti": "^2.6.1",
|
||||
"lint-staged": "^16.4.0",
|
||||
"postcss": "^8.5.8",
|
||||
"postcss-html": "^1.8.1",
|
||||
@@ -109,13 +108,12 @@
|
||||
"stylelint-prettier": "^5.0.3",
|
||||
"terser": "^5.46.0",
|
||||
"typescript": "^5.9.3",
|
||||
"typescript-eslint": "^8.57.0",
|
||||
"typescript-eslint": "^8.57.2",
|
||||
"unocss": "^66.6.6",
|
||||
"unplugin-auto-import": "^21.0.0",
|
||||
"unplugin-vue-components": "^31.0.0",
|
||||
"unplugin-vue-components": "^32.0.0",
|
||||
"vite": "^8.0.0",
|
||||
"vite-plugin-mock-dev-server": "^2.1.0",
|
||||
"vue-eslint-parser": "^10.4.0",
|
||||
"vite-plugin-mock-dev-server": "^2.1.1",
|
||||
"vue-tsc": "^3.2.5"
|
||||
},
|
||||
"engines": {
|
||||
|
||||
2036
pnpm-lock.yaml
generated
2036
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -1,115 +1,91 @@
|
||||
import { AuthStorage } from "@/utils/auth";
|
||||
|
||||
export interface UseSseOptions {
|
||||
/** SSE 端点 URL,不传时使用环境变量拼接 */
|
||||
url?: string;
|
||||
/** 是否开启调试日志 */
|
||||
debug?: boolean;
|
||||
/** 连接超时时间,单位毫秒,默认为 10000 */
|
||||
connectionTimeout?: number;
|
||||
url?: string; // SSE 连接地址,默认走 VITE_APP_BASE_API 代理
|
||||
debug?: boolean; // 是否在控制台打印调试日志
|
||||
connectionTimeout?: number; // 连接超时时间(ms)
|
||||
/** 重连间隔基数,实际间隔 = min(基数 × 2^n, 最大间隔) */
|
||||
reconnectInterval?: number;
|
||||
maxReconnectInterval?: number; // 重连间隔上限(ms)
|
||||
maxReconnectAttempts?: number; // 最大重试次数,超过后停止重连
|
||||
}
|
||||
|
||||
type EventHandler = (data: any) => void;
|
||||
|
||||
/**
|
||||
* SSE 连接状态枚举
|
||||
*/
|
||||
export enum SseConnectionState {
|
||||
DISCONNECTED = "DISCONNECTED",
|
||||
CONNECTING = "CONNECTING",
|
||||
CONNECTED = "CONNECTED",
|
||||
DISCONNECTED = "DISCONNECTED", // 未连接
|
||||
CONNECTING = "CONNECTING", // 连接中
|
||||
CONNECTED = "CONNECTED", // 已连接
|
||||
}
|
||||
|
||||
/**
|
||||
* 全局 SSE 实例管理
|
||||
*/
|
||||
let globalInstance: ReturnType<typeof createSseConnection> | null = null;
|
||||
|
||||
/**
|
||||
* 创建 SSE 连接(内部工厂函数)
|
||||
*/
|
||||
function createSseConnection(options: UseSseOptions = {}) {
|
||||
const baseApi = import.meta.env.VITE_APP_BASE_API || "/dev-api";
|
||||
const defaultUrl = `${baseApi}/api/v1/sse/connect`;
|
||||
const baseUrl = import.meta.env.VITE_APP_BASE_API;
|
||||
const defaultUrl = `${baseUrl}/api/v1/sse/connect`;
|
||||
|
||||
const config = {
|
||||
url: options.url ?? defaultUrl,
|
||||
debug: options.debug ?? false,
|
||||
connectionTimeout: options.connectionTimeout ?? 10000,
|
||||
connectionTimeout: options.connectionTimeout ?? 10000, // 连接超时 10s
|
||||
reconnectInterval: options.reconnectInterval ?? 5000, // 首次重连等 5s,之后翻倍
|
||||
maxReconnectInterval: options.maxReconnectInterval ?? 120000, // 重连间隔最大 2min
|
||||
maxReconnectAttempts: options.maxReconnectAttempts ?? 10, // 最多重试 10 次
|
||||
};
|
||||
|
||||
const connectionState = ref<SseConnectionState>(SseConnectionState.DISCONNECTED);
|
||||
const isConnected = computed(() => connectionState.value === SseConnectionState.CONNECTED);
|
||||
|
||||
let eventSource: EventSource | null = null;
|
||||
let abortController: AbortController | null = null;
|
||||
let isManualDisconnect = false;
|
||||
let connectionTimeoutTimer: ReturnType<typeof setTimeout> | null = null;
|
||||
let reader: ReadableStreamDefaultReader<Uint8Array> | null = null;
|
||||
let isManualDisconnect = false; // 主动断开则不重连
|
||||
let reconnectTimer: ReturnType<typeof setTimeout> | null = null;
|
||||
let reconnectAttempts = 0;
|
||||
let currentReconnectInterval = config.reconnectInterval;
|
||||
|
||||
const eventHandlers = new Map<string, Set<EventHandler>>();
|
||||
|
||||
const log = config.debug ? (...args: any[]) => console.log("[SSE]", ...args) : () => {};
|
||||
const log = (...args: any[]) => console.log("[SSE]", ...args);
|
||||
const logError = (...args: any[]) => console.error("[SSE]", ...args);
|
||||
|
||||
const clearConnectionTimeout = () => {
|
||||
if (connectionTimeoutTimer) {
|
||||
clearTimeout(connectionTimeoutTimer);
|
||||
connectionTimeoutTimer = null;
|
||||
const clearTimer = (timer: typeof connectionTimeoutTimer) => {
|
||||
if (timer) {
|
||||
clearTimeout(timer);
|
||||
return null;
|
||||
}
|
||||
return timer;
|
||||
};
|
||||
|
||||
const handleOpen = () => {
|
||||
clearConnectionTimeout();
|
||||
connectionState.value = SseConnectionState.CONNECTED;
|
||||
log("SSE 连接已建立");
|
||||
};
|
||||
// 指数退避重连
|
||||
const scheduleReconnect = () => {
|
||||
if (isManualDisconnect) return;
|
||||
if (config.maxReconnectAttempts > 0 && reconnectAttempts >= config.maxReconnectAttempts) {
|
||||
log(`已达到最大重试次数 ${config.maxReconnectAttempts},停止重连`);
|
||||
return;
|
||||
}
|
||||
|
||||
const handleError = (event: Event) => {
|
||||
clearConnectionTimeout();
|
||||
connectionState.value = SseConnectionState.DISCONNECTED;
|
||||
logError("SSE 连接错误:", event);
|
||||
reconnectAttempts++;
|
||||
log(`将在 ${currentReconnectInterval}ms 后重试(${reconnectAttempts})`);
|
||||
|
||||
if (!isManualDisconnect && eventSource) {
|
||||
log("浏览器将自动重连...");
|
||||
}
|
||||
};
|
||||
|
||||
const handleMessage = (event: MessageEvent) => {
|
||||
log("收到消息:", event.data);
|
||||
const handlers = eventHandlers.get("message");
|
||||
if (handlers) {
|
||||
try {
|
||||
const data = JSON.parse(event.data);
|
||||
handlers.forEach((handler) => handler(data));
|
||||
} catch {
|
||||
handlers.forEach((handler) => handler(event.data));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleCustomEvent = (eventName: string) => (event: MessageEvent) => {
|
||||
log(`收到事件[${eventName}]:`, event.data);
|
||||
const handlers = eventHandlers.get(eventName);
|
||||
if (handlers) {
|
||||
try {
|
||||
const data = JSON.parse(event.data);
|
||||
handlers.forEach((handler) => handler(data));
|
||||
} catch {
|
||||
handlers.forEach((handler) => handler(event.data));
|
||||
}
|
||||
}
|
||||
reconnectTimer = setTimeout(() => {
|
||||
connect();
|
||||
currentReconnectInterval = Math.min(
|
||||
currentReconnectInterval * 2,
|
||||
config.maxReconnectInterval
|
||||
);
|
||||
}, currentReconnectInterval);
|
||||
};
|
||||
|
||||
const connect = () => {
|
||||
isManualDisconnect = false;
|
||||
|
||||
if (connectionState.value === SseConnectionState.CONNECTED) {
|
||||
log("SSE 已连接,跳过重复连接");
|
||||
return;
|
||||
}
|
||||
|
||||
if (connectionState.value === SseConnectionState.CONNECTING) {
|
||||
log("SSE 正在连接中,跳过重复连接");
|
||||
if (connectionState.value !== SseConnectionState.DISCONNECTED) {
|
||||
log(
|
||||
connectionState.value === SseConnectionState.CONNECTED
|
||||
? "SSE 已连接,跳过重复连接"
|
||||
: "SSE 正在连接中,跳过重复连接"
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -120,10 +96,9 @@ function createSseConnection(options: UseSseOptions = {}) {
|
||||
}
|
||||
|
||||
connectionState.value = SseConnectionState.CONNECTING;
|
||||
|
||||
// 使用 fetch + ReadableStream 替代 EventSource,支持 Authorization header
|
||||
abortController = new AbortController();
|
||||
|
||||
// 超时自动断开
|
||||
connectionTimeoutTimer = setTimeout(() => {
|
||||
if (connectionState.value === SseConnectionState.CONNECTING) {
|
||||
log("SSE 连接超时");
|
||||
@@ -131,6 +106,8 @@ function createSseConnection(options: UseSseOptions = {}) {
|
||||
}
|
||||
}, config.connectionTimeout);
|
||||
|
||||
log("正在建立 SSE 连接...");
|
||||
|
||||
fetch(config.url, {
|
||||
method: "GET",
|
||||
headers: {
|
||||
@@ -143,8 +120,10 @@ function createSseConnection(options: UseSseOptions = {}) {
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP ${response.status}`);
|
||||
}
|
||||
clearConnectionTimeout();
|
||||
connectionTimeoutTimer = clearTimer(connectionTimeoutTimer);
|
||||
connectionState.value = SseConnectionState.CONNECTED;
|
||||
reconnectAttempts = 0;
|
||||
currentReconnectInterval = config.reconnectInterval;
|
||||
log("SSE 连接已建立");
|
||||
return response.body?.getReader();
|
||||
})
|
||||
@@ -154,6 +133,7 @@ function createSseConnection(options: UseSseOptions = {}) {
|
||||
const decoder = new TextDecoder();
|
||||
let buffer = "";
|
||||
|
||||
// SSE 文本协议解析:event / data / 空行分隔
|
||||
const processChunk = ({
|
||||
done,
|
||||
value,
|
||||
@@ -166,19 +146,18 @@ function createSseConnection(options: UseSseOptions = {}) {
|
||||
|
||||
buffer += decoder.decode(value, { stream: true });
|
||||
const lines = buffer.split("\n");
|
||||
buffer = lines.pop() || ""; // 保留不完整的行
|
||||
buffer = lines.pop() || "";
|
||||
|
||||
let currentEvent = "message";
|
||||
let currentData = "";
|
||||
|
||||
for (const line of lines) {
|
||||
if (line.startsWith(":")) continue; // 注释行(心跳)
|
||||
if (line.startsWith(":")) continue;
|
||||
if (line.startsWith("event:")) {
|
||||
currentEvent = line.slice(6).trim();
|
||||
} else if (line.startsWith("data:")) {
|
||||
currentData = line.slice(5).trim();
|
||||
} else if (line === "") {
|
||||
// 空行表示事件结束
|
||||
if (currentData) {
|
||||
const handlers = eventHandlers.get(currentEvent);
|
||||
if (handlers) {
|
||||
@@ -207,18 +186,17 @@ function createSseConnection(options: UseSseOptions = {}) {
|
||||
} else {
|
||||
logError("SSE 连接错误:", err);
|
||||
connectionState.value = SseConnectionState.DISCONNECTED;
|
||||
scheduleReconnect();
|
||||
}
|
||||
});
|
||||
|
||||
log("正在建立 SSE 连接...");
|
||||
};
|
||||
|
||||
// 订阅事件,返回取消函数
|
||||
const on = (eventName: string, handler: EventHandler): (() => void) => {
|
||||
if (!eventHandlers.has(eventName)) {
|
||||
eventHandlers.set(eventName, new Set());
|
||||
}
|
||||
eventHandlers.get(eventName)!.add(handler);
|
||||
|
||||
log(`已订阅事件: ${eventName}`);
|
||||
|
||||
return () => {
|
||||
@@ -229,31 +207,23 @@ function createSseConnection(options: UseSseOptions = {}) {
|
||||
eventHandlers.delete(eventName);
|
||||
}
|
||||
}
|
||||
log(`已取消订阅事件: ${eventName}`);
|
||||
};
|
||||
};
|
||||
|
||||
// 主动断开,不会触发重连
|
||||
const disconnect = () => {
|
||||
isManualDisconnect = true;
|
||||
clearConnectionTimeout();
|
||||
|
||||
if (reader) {
|
||||
reader.cancel();
|
||||
connectionTimeoutTimer = clearTimer(connectionTimeoutTimer);
|
||||
reconnectTimer = clearTimer(reconnectTimer);
|
||||
reader?.cancel();
|
||||
reader = null;
|
||||
}
|
||||
if (abortController) {
|
||||
abortController.abort();
|
||||
abortController?.abort();
|
||||
abortController = null;
|
||||
}
|
||||
if (eventSource) {
|
||||
eventSource.close();
|
||||
eventSource = null;
|
||||
}
|
||||
|
||||
connectionState.value = SseConnectionState.DISCONNECTED;
|
||||
log("SSE 连接已断开");
|
||||
};
|
||||
|
||||
// 登出时调用,断开并释放所有资源
|
||||
const cleanup = () => {
|
||||
disconnect();
|
||||
eventHandlers.clear();
|
||||
@@ -270,9 +240,6 @@ function createSseConnection(options: UseSseOptions = {}) {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* SSE 连接组合式函数(单例模式)
|
||||
*/
|
||||
export function useSse(options: UseSseOptions = {}) {
|
||||
if (!globalInstance) {
|
||||
globalInstance = createSseConnection(options);
|
||||
@@ -280,16 +247,6 @@ export function useSse(options: UseSseOptions = {}) {
|
||||
return globalInstance;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取或创建 SSE 实例(用于外部访问)
|
||||
*/
|
||||
export function getSseInstance() {
|
||||
return globalInstance;
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理全局 SSE 实例
|
||||
*/
|
||||
export function cleanupSse() {
|
||||
if (globalInstance) {
|
||||
globalInstance.cleanup();
|
||||
|
||||
@@ -14,7 +14,7 @@ import { addRecentMenu } from "@/composables/useRecentMenus";
|
||||
export function setupPermissionGuard() {
|
||||
const whiteList = ["/login"];
|
||||
|
||||
router.beforeEach(async (to, _from, next) => {
|
||||
router.beforeEach(async (to, _from) => {
|
||||
NProgress.start();
|
||||
|
||||
try {
|
||||
@@ -23,18 +23,15 @@ export function setupPermissionGuard() {
|
||||
// 未登录处理
|
||||
if (!isLoggedIn) {
|
||||
if (whiteList.includes(to.path)) {
|
||||
next();
|
||||
} else {
|
||||
next(`/login?redirect=${encodeURIComponent(to.fullPath)}`);
|
||||
NProgress.done();
|
||||
}
|
||||
return;
|
||||
}
|
||||
NProgress.done();
|
||||
return `/login?redirect=${encodeURIComponent(to.fullPath)}`;
|
||||
}
|
||||
|
||||
// 已登录访问登录页,重定向到首页
|
||||
if (to.path === "/login") {
|
||||
next({ path: "/" });
|
||||
return;
|
||||
return { path: "/" };
|
||||
}
|
||||
|
||||
const permissionStore = usePermissionStore();
|
||||
@@ -54,14 +51,12 @@ export function setupPermissionGuard() {
|
||||
router.addRoute(route);
|
||||
});
|
||||
|
||||
next({ ...to, replace: true });
|
||||
return;
|
||||
return { ...to, replace: true };
|
||||
}
|
||||
|
||||
// 路由 404 检查
|
||||
if (to.matched.length === 0) {
|
||||
next("/404");
|
||||
return;
|
||||
return "/404";
|
||||
}
|
||||
|
||||
// 动态标题
|
||||
@@ -69,13 +64,11 @@ export function setupPermissionGuard() {
|
||||
if (title) {
|
||||
to.meta.title = title;
|
||||
}
|
||||
|
||||
next();
|
||||
} catch (error) {
|
||||
console.error("Route guard error:", error);
|
||||
await useUserStore().resetAllState();
|
||||
next("/login");
|
||||
NProgress.done();
|
||||
return "/login";
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -43,12 +43,10 @@ export default defineConfig(({ mode }: ConfigEnv): UserConfig => {
|
||||
port: +env.VITE_APP_PORT,
|
||||
open: true,
|
||||
proxy: {
|
||||
// 代理 /dev-api 的请求
|
||||
[env.VITE_APP_BASE_API]: {
|
||||
changeOrigin: true,
|
||||
// 代理目标地址:https://api.youlai.tech
|
||||
target: env.VITE_APP_API_URL,
|
||||
rewrite: (path: string) => path.replace(new RegExp("^" + env.VITE_APP_BASE_API), ""),
|
||||
rewrite: (path: string) => path.replace(new RegExp(`^${env.VITE_APP_BASE_API}`), ""),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user