Compare commits

..

148 Commits
v5.2.0 ... main

Author SHA1 Message Date
xiaoxian521
d9a4ab8f86 chore(deps): update 2025-05-31 12:41:54 +08:00
xiaoxian521
bd5ab754ca docs: update README 2025-05-27 15:39:09 +08:00
xiaoxian521
2f2749e644 perf: 优化代码 2025-05-16 12:08:46 +08:00
xiaoxian521
b61d7b359f chore: 升级依赖,相关兼容处理 2025-05-15 10:11:22 +08:00
xiaoxian521
99f070190c chore(deps): update 2025-05-03 10:20:21 +08:00
xiaoxian521
891ad9d6a2 chore: fix typo 2025-04-21 13:37:04 +08:00
xiaoxian521
22ee607aea docs: 新增一位特别代码贡献者[tinysimple](https://github.com/tinysimple) 2025-04-21 12:38:22 +08:00
tinyThing
8255f9063b
fix: 修复resetRouter未清空全部路由数据 (#1208) 2025-04-21 12:29:38 +08:00
xiaoxian521
59319aac8b chore: 升级element-plus至最新版,相关兼容处理 2025-04-19 13:25:01 +08:00
xiaoxian521
6be410a03c chore: update 2025-04-18 14:25:53 +08:00
xiaoxian521
1730ecf4ce perf: 优化导航样式 2025-04-17 14:40:07 +08:00
xiaoxian521
51c3ac8631 fix: 修复ReSegmented分段控制器组件在浅色和深色整体风格切换时的闪烁问题 2025-04-14 16:34:17 +08:00
xiaoxian521
08b7b1b641 style: update 2025-04-14 10:50:46 +08:00
xiaoxian521
1daf83cf9d release: update 6.0.0 2025-04-10 09:53:09 +08:00
xiaoxian521
a8ca71ae61 chore: update 2025-04-10 09:15:53 +08:00
xiaoming
e08626d443
refactor: 升级tailwindcssv4版本,带来更快的构建速度、更简化的安装和配置、提供专属vite插件 (#1203) 2025-04-09 19:09:45 +08:00
xiaoxian521
583feae7b7 chore: 更新eslint相关依赖并作兼容处理 2025-04-09 05:49:15 +08:00
xiaoxian521
92cfa9763b fix: 修复组件-瀑布流无限滚动示例中失效的链接 2025-04-07 16:33:26 +08:00
xiaoxian521
881366c78b chore: 更新vue-flow,相关兼容处理 2025-04-06 16:51:05 +08:00
xiaoxian521
f5cc6d2ff4 fix: 修复重构图标后的错误用法 2025-04-02 14:35:39 +08:00
xiaoxian521
4db365038c refactor: 删除已弃用的依赖包eslint-define-config,升级eslint至最新版本,相关兼容处理 2025-03-28 09:40:51 +08:00
xiaoming
a9ee9ebcf9
refactor: 重构图标模块,使用@iconify/json替换不再维护更新的@iconify-icons/*依赖,优化使用体验,确保图标库可持续更新并支持Tree-shaking (#1202)
refactor: 重构图标模块,使用`@iconify/json`替换不再维护更新的`@iconify-icons/*`依赖,优化使用体验,确保图标库可持续更新并支持`Tree-shaking`
2025-03-25 09:18:20 +08:00
xiaoxian521
b004c224c2 feat: 添加Ai聊天组件示例 2025-03-11 09:45:03 +08:00
xiaoxian521
399d3b2987 chore: 升级依赖,相关兼容处理 2025-02-14 11:25:38 +08:00
xiaoxian521
b87eb6fd0a chore: 升级依赖 2025-01-15 12:10:39 +08:00
xiaoxian521
a0246e31df feat: 添加tagOnClick标签切换全局公共事件 2025-01-09 16:20:31 +08:00
xiaoxian521
e1cd14a946 chore: 升级依赖,相关兼容处理(主要是typescriptvue-tsc升级最新版) 2025-01-09 15:55:45 +08:00
xiaoxian521
02380f69e1 chore: 优化src/style/dark.scss语法 2025-01-07 17:21:00 +08:00
可能
5208272456
chore: 优化登录传参 (#1197) 2025-01-06 14:30:43 +08:00
xiaoming
551292078e
fix: 修复aria-hidden报错 (#1192) 2025-01-04 02:19:38 +08:00
XiaoYue
79cd159154
chore: 使用keydown替换keypresskeypress事件已弃用 (#1195) 2024-12-27 09:55:28 +08:00
xiaoming
6d26300181
feat: 添加代码编辑器示例 (#1194) 2024-12-24 09:14:43 +08:00
xiaoming
0dd6665b2a
feat: 添加Markdown示例 (#1193) 2024-12-23 13:57:37 +08:00
xiaoxian521
bbdd44a917 feat: 添加滑块示例 2024-12-19 17:29:45 +08:00
xiaoxian521
f8690a0b73 fix: 修复使用this语法时无法显示代码提示的问题并更新pinia相关语法 2024-12-15 23:29:37 +08:00
xiaoxian521
b843eda26f style: update 2024-12-14 11:20:45 +08:00
xiaoxian521
1b48bc8049 release: update 5.9.0 2024-12-10 14:36:47 +08:00
xiaoming
21ff69b10e
refactor: 升级vitev6版本,升级sass至最新版,重构主题写法,弃用@pureadmin/theme (#1188)
* refactor: 升级`vite`至`v6`版本,升级`sass`至最新版,重构主题写法,删除`@pureadmin/theme`
2024-12-10 14:10:47 +08:00
xiaoxian521
66f5d6d423 refactor: 使用code-inspector-plugin替换vite-plugin-vue-inspector 2024-11-04 12:54:20 +08:00
xiaoxian521
fd9ad7eb21 chore: 固定sass版本至v1.79.6,待稳定后再升级 2024-10-23 11:28:09 +08:00
xiaoxian521
a0618c01ba chore: 升级依赖,相关兼容处理 2024-10-12 09:46:44 +08:00
xiaoxian521
7a3c1ab3cd docs: 更新特别代码贡献名单 2024-09-25 16:57:19 +08:00
Mer
5032a75221
feat: 新增函数式抽屉组件 (#1183)
* feat: 函数式抽屉组件

* feat: 添加ReDrawer demo

* fix: 组件ReDrawer 增加按钮loading等功能
2024-09-25 16:49:12 +08:00
xiaoxian521
384c789fc0 perf: 优化用户管理左侧部门树的布局 2024-09-24 11:52:16 +08:00
xiaoxian521
281675bdaf fix: 修复在菜单、部门管理中,表格展开后启用或关闭全屏功能时,表格高度未自动适应的问题 2024-09-24 08:42:46 +08:00
xiaoxian521
0004f1318c feat: pure-table添加动态表头示例 2024-09-23 14:45:02 +08:00
xiaoxian521
ab39864ef4 chore: 升级i18n相关依赖,相关兼容处理 2024-09-21 16:05:02 +08:00
xiaoxian521
4e14ab22ba chore: 升级依赖,相关兼容处理 2024-09-21 12:09:41 +08:00
xiaoxian521
cd21f1e050 release: update 5.8.0 2024-08-19 13:53:33 +08:00
xiaoxian521
5fbb664da7 chore: 升级依赖,element-plus最新版兼容处理 2024-08-12 14:51:34 +08:00
xiaoming
244ab7f990
feat: 新增第二种按钮权限指令(根据登录接口返回的permissions字段进行判断) (#1177)
* feat: 新增第二种按钮权限指令(根据登录接口返回的`permissions`字段进行判断)
2024-08-12 13:32:04 +08:00
xiaoxian521
96152ed134 feat: ReDialog组件的确定按钮提供关闭按钮动画closeLoading功能 2024-08-05 13:15:10 +08:00
xiaoxian521
37ab40f188 feat: VxeTableBar组件添加全屏和退出全屏功能 2024-08-03 15:13:20 +08:00
xiaoxian521
91ae63a8c5 feat: PureTableBar组件添加全屏和退出全屏功能 2024-08-03 14:39:21 +08:00
xiaoxian521
6d7e92fed1 feat: 函数式弹框ReDialog添加点击确认按钮后是否开启loading加载动画功能 2024-07-30 14:56:47 +08:00
xiaoxian521
0706f37254 fix: 修复顶部菜单模式下logo不可隐藏的问题 2024-07-29 10:52:12 +08:00
xiaoxian521
8a9695cf7c chore(deps): update 2024-07-29 09:49:38 +08:00
xiaoxian521
d395c9c6ba chore(deps): update 2024-07-21 17:09:05 +08:00
xiaoxian521
3dec3c002f perf: 优化系统管理-角色管理的权限功能样式 2024-07-04 11:14:22 +08:00
xiaoxian521
bae1122e58 feat: 添加vite-plugin-checker插件,更严格的类型和eslint校验 2024-07-03 11:31:37 +08:00
xiaoxian521
37e9d8a1ac chore: 升级依赖,相关兼容处理 2024-07-02 20:57:35 +08:00
sea
dea9664677
perf: 手机端层级展示 (#1169) 2024-07-02 15:30:27 +08:00
sea
775d7a2d32
perf: 优化登录页 (#1168) 2024-06-27 09:55:47 +08:00
xiaoxian521
13e7a13e9d chore(deps): update 2024-06-14 14:01:18 +08:00
xiaoxian521
47afa9209e fix: 修复配置路由属性fixedTagfalse后当前标签页不可关闭的问题 2024-06-12 14:56:09 +08:00
xiaoxian521
933ced4ac4 docs: update 2024-06-11 22:28:57 +08:00
Fifteen
8816e61e3a
chore: update plugins/elementPlus.ts (#1164) 2024-06-07 10:38:19 +08:00
sea
edf82ea727
feat: 添加开发环境代码调试vite-plugin-vue-inspector插件,提升开发体验 (#1162) 2024-06-06 17:32:25 +08:00
sea
a75cf8394e
types: 优化自定义指令的类型提示 (#1161) 2024-06-06 16:26:32 +08:00
xiaoxian521
33a89834d7 release: update 5.7.0 2024-06-04 16:21:22 +08:00
xiaoxian521
649aab9c7d docs: 更新特别代码贡献名单 2024-06-04 13:49:52 +08:00
way
7a6ee58e6d
feat: 添加谷歌风格的页签 (#1160) 2024-06-04 13:44:47 +08:00
xiaoxian521
b402a8924f docs: update 2024-06-01 06:33:55 +08:00
xiaoxian521
9a5523d1c7 chore: 更新依赖,建议升级vue-pdf-embed至最新版 2024-05-31 14:30:00 +08:00
xiaoxian521
1e6d0283c9 docs: update 2024-05-29 11:06:01 +08:00
xiaoxian521
a8377f8d45 fix: 修复在火狐浏览器中菜单折叠后,文字超出未隐藏的问题 2024-05-28 12:19:18 +08:00
xiaoxian521
cd653c83f0 chore: 升级依赖,相关兼容处理 2024-05-28 10:16:09 +08:00
xiaoxian521
643b36fc42 docs: update README 2024-05-28 00:04:35 +08:00
RosyCloudsLee
17ed4d640d
types: update 2024-05-21 09:36:14 +08:00
xiaoxian521
613d20fc1b release: update 5.6.0 2024-05-14 09:55:45 +08:00
xiaoxian521
8934499349 chore(deps): update 2024-05-14 09:32:40 +08:00
xiaoxian521
bb86962186 chore: 升级pnpmv9版本,相关兼容处理 2024-05-13 22:45:19 +08:00
xiaoxian521
30f598dfa5 chore: update 2024-05-09 21:43:20 +08:00
xiaoxian521
de00537fdd chore(deps): update 2024-05-09 10:37:19 +08:00
Fifteen
5238ee7ad9
perf: 优化ReSegmented组件 (#1137) 2024-05-08 17:41:04 +08:00
一万
3ca9a7b5bc
fix: 修复点击外链会跳转两次的问题 (#1133) 2024-05-08 15:59:32 +08:00
xiaoxian521
fae4924102 release: update 5.5.0 2024-05-07 09:09:35 +08:00
xiaoxian521
295240f2a3 chore(deps): update 2024-05-06 16:21:14 +08:00
xiaoxian521
1d9f1cf465 docs: 更换文档站和完整版预览站地址 2024-05-03 00:00:35 +08:00
xiaoxian521
a56061ac81 chore: 更新依赖,相关兼容处理 2024-05-02 22:39:18 +08:00
xiaoxian521
d24f334a81 ci: add pages.yml 2024-05-02 21:45:57 +08:00
xiaoming
cc7726e1c2
feat: 新组件ReVxeTableBar搭配vxe-table使用 (#1087) 2024-05-02 21:34:16 +08:00
xiaoming
b8159a0d73
refactor: 重构layout文件命名规范,更易读 (#1110) 2024-04-30 22:27:54 +08:00
一万
2f9bc7e187
fix: 修复函数式弹窗点击取消按钮,延时关闭无效问题 (#1112) 2024-04-26 15:20:54 +08:00
Nexpro
d6f487a48c
chore: revise typo (#1103) 2024-04-26 10:59:48 +08:00
xiaoxian521
75dc3b6216 chore(deps): update 2024-04-25 11:40:17 +08:00
xiaoxian521
4be7db4944 chore: update 2024-04-24 16:25:12 +08:00
xiaoxian521
884cf92640 chore(deps): update 2024-04-24 11:19:51 +08:00
苗大
fb0c092a2c
style: update 2024-04-23 11:35:11 +08:00
xiaoxian521
1ce0038c13 chore: update 2024-04-23 10:26:26 +08:00
xiaoxian521
88d804df89 chore: update 2024-04-22 13:09:32 +08:00
xiaoxian521
efe0c83e4f chore: 升级依赖,相关兼容处理 2024-04-22 12:27:53 +08:00
shuTwT
ada3e80c7e
perf: 优化账号设置-头像上传功能 2024-04-19 10:52:39 +08:00
xiaoxian521
d203222acf release: update 5.4.0 2024-04-18 15:34:36 +08:00
xiaoxian521
07ad01ebee style: update 2024-04-18 13:47:13 +08:00
xiaoxian521
ed71fe708d chore: update 2024-04-18 12:20:08 +08:00
xiaoxian521
29b06c5285 chore(deps): update 2024-04-17 18:37:45 +08:00
fangcy
9ad00d97ee
fix: 修复调用刷新token接口时,refreshToken参数为空的问题 2024-04-17 18:17:39 +08:00
xiaoming
a402d33b89
perf: 框架核心代码国际化全量覆盖(仅需处理业务代码国际化即可) (#1082) 2024-04-17 15:41:37 +08:00
xiaoxian521
d1d2bcaa11 feat: 添加全局配置MaxTagsLevel属性,可设置打开标签页最大数 2024-04-16 19:34:57 +08:00
xiaoxian521
abd042afe8 types: 优src/utils/http文件中postget工具函数的类型 2024-04-16 14:01:36 +08:00
xiaoxian521
cd42dbf188 chore: 移除非必要的cloc工具依赖包,它使用GPL开源许可证具有争议性 2024-04-16 11:59:11 +08:00
xiaoxian521
4cbf9056b1 perf: 简化store文件中导出和导入用法 2024-04-16 11:49:15 +08:00
xiaoxian521
5d3a9dff46 fix: 修复账户设置页面,刷新后字体颜色未生效的问题 2024-04-15 17:52:51 +08:00
xiaoxian521
dbb05f4166 fix: 修复三级菜单向左折叠后图标显示样式问题 2024-04-15 16:25:01 +08:00
xiaoxian521
ea36e260e2 fix: 修复当一个页面存在多个RePureTableBar组件,列无法正常拖动问题 2024-04-15 12:52:01 +08:00
xiaoxian521
a5b57908ec perf: 优化请求白名单逻辑,兼容更多场景 2024-04-15 11:40:15 +08:00
xiaoxian521
699b174f95 perf: 优化获取顶级菜单逻辑 2024-04-15 11:15:57 +08:00
xiaoxian521
0934c97413 chore: 升级eslint9,相关兼容处理 2024-04-13 11:21:06 +08:00
xiaoxian521
0dc979eec0 chore(deps): update 2024-04-13 09:37:18 +08:00
xiaoxian521
7ed0e8f89f docs: 更新特别代码贡献名单 2024-04-12 21:34:45 +08:00
EchoByte
332678ba88
feat: 添加账户设置功能页面且兼容移动端 (#1022) 2024-04-12 16:20:33 +08:00
xiaoming
296db3789b
feat: 路由添加可配置的fixedTag属性,作用为当前菜单名称是否固定显示在标签页且不可关闭 (#1047) 2024-04-09 17:07:05 +08:00
xiaoxian521
c0a1b918aa feat: pure-table添加headerSlot自定义表头插槽用法示例 2024-04-06 12:25:13 +08:00
xiaoxian521
bf874276f3 chore(deps): update 2024-04-06 10:44:08 +08:00
hb0730
f120467fc8
feat: 函数式弹框ReDialog添加Popconfirm气泡确认框 (#1046) 2024-04-04 22:14:24 +08:00
xiaoxian521
8d2ef1f644 perf: 优化登录接口 2024-04-04 15:23:02 +08:00
hb0730
fcd0fc9d65
workflow: update node-version (#1051) 2024-04-03 12:23:16 +08:00
xiaoxian521
d685a18b9e feat: 添加思维导图示例 2024-03-31 14:38:15 +08:00
hb0730
e0f52fc379
feat: 分段控制器组件添加全局禁用属性disabled (#1043)
* feat: segmented component global disabled
2024-03-31 12:37:10 +08:00
xiaoxian521
53e3e601fb chore: 升级依赖,相关兼容处理 2024-03-30 23:45:56 +08:00
xiaoxian521
adc82644cb chore(deps): update 2024-03-29 20:17:51 +08:00
xiaoxian521
ee89a864db chore(deps): update 2024-03-29 10:11:06 +08:00
Fifteen
75fad304e7
chore: revise typo (#1039) 2024-03-29 10:06:35 +08:00
xiaoxian521
48d90af81b release: update 5.3.0 2024-03-28 23:28:29 +08:00
xiaoxian521
b1fccc06d8 docs: update 2024-03-28 22:56:41 +08:00
xiaoming
fbacf8e85e
refactor: 重构国际化文件命名规范以及演示页加上代码位置提示 (#1034)
* refactor: 重构国际化文件命名规范以及演示页加上代码位置提示
2024-03-27 10:21:15 +08:00
xiaoxian521
52103ab52d feat: RePureTableBar组件搭配pure-admin-table支持表头国际化切换 2024-03-26 16:07:35 +08:00
ZM25XC
bc1da0b759
perf: 优化用户管理-裁剪图片上传功能 (#1027)
* perf: 优化用户管理-裁剪图片上传功能
2024-03-25 14:57:10 +08:00
EchoByte
e38610ff67
chore: update mqtt v4 (#1024)
* fix: change mqtt to version 4
2024-03-24 20:59:46 +08:00
EchoByte
69bc6602d0
feat: 添加MQTT示例 (#1021)
* feat: add mqtt client demo use mqtt.js and emqx broker
2024-03-24 19:31:19 +08:00
xiaoxian521
eeb09a8da2 docs: 更新特别代码贡献名单 2024-03-24 14:02:03 +08:00
Fifteen
f486ba60a0
feat: ReSegmented分段控制器新增size属性,以便适配不同的场景 (#1016)
* feat: `ReSegmented`分段控制器新增`size`属性,以便适配不同的场景
2024-03-24 13:55:44 +08:00
xiaoxian521
4f44f72a2c feat: 添加WordExcel预览示例 2024-03-23 15:28:42 +08:00
xiaoxian521
51ef3647fc perf: 当浏览器窗口的可视区域小于或等于1280时隐藏页宽 2024-03-23 08:19:37 +08:00
xiaoxian521
97f167825d chore: update 2024-03-23 00:38:16 +08:00
Pan Zhou Dan
c53b7bec0a
types: update global-components.d (#1015) 2024-03-22 23:55:36 +08:00
Pan Zhou Dan
135cfe0693
chore: update plugins/elementPlus.ts (#1014)
* chore: update `plugins/elementPlus.ts`
2024-03-22 22:57:36 +08:00
405 changed files with 18675 additions and 10065 deletions

View File

@ -1,13 +0,0 @@
public
dist
*.d.ts
/src/assets
package.json
eslint.config.js
.prettierrc.js
commitlint.config.js
postcss.config.js
tailwind.config.ts
stylelint.config.js
src/components/ReSplitPane/iconfont
src/components/ReFlowChart/src/assets/iconfont

View File

@ -32,7 +32,7 @@ body:
label: 验证 (Verify)
description: 在提交问题之前,请确保您执行以下操作 (Before submitting an issue, please ensure you do the following)
options:
- label: 是否仔细阅读过 [文档](https://yiming_chang.gitee.io/pure-admin-doc/) (Have you read [documentation](https://yiming_chang.gitee.io/pure-admin-doc/) carefully)
- label: 是否仔细阅读过 [文档](https://pure-admin.cn/) (Have you read [documentation](https://pure-admin.cn/) carefully)
required: true
- label: 检查是否存在相同或类似的问题 [issues](https://github.com/pure-admin/vue-pure-admin/issues) (Check for the same or similar [issues](https://github.com/pure-admin/vue-pure-admin/issues))
required: true

View File

@ -13,18 +13,18 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Install Node.js
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
node-version: 18
node-version: 20
- uses: pnpm/action-setup@v2
- uses: pnpm/action-setup@v3
name: Install pnpm
id: pnpm-install
with:
version: 8.6.10
version: 9
run_install: false
- name: Get pnpm store directory
@ -33,7 +33,7 @@ jobs:
run: |
echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
- uses: actions/cache@v3
- uses: actions/cache@v4
name: Setup pnpm cache
with:
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}

42
.github/workflows/pages.yml vendored Normal file
View File

@ -0,0 +1,42 @@
name: Build and Deploy
permissions:
contents: write
on:
push:
branches:
- pages
jobs:
deploy:
concurrency: ci-${{ github.ref }}
runs-on: ubuntu-latest
steps:
- name: Checkout 🛎️
uses: actions/checkout@v4
- name: Install Node.js
uses: actions/setup-node@v4
with:
node-version: 20
registry-url: https://registry.npmjs.com/
- uses: pnpm/action-setup@v3
name: Install pnpm
id: pnpm-install
with:
version: 9
run_install: false
- name: Deploy 🔧
run: |
pnpm install --no-frozen-lockfile
sed -i "s#VITE_PUBLIC_PATH = /#VITE_PUBLIC_PATH = /vue-pure-admin/#g" $(pwd)/.env.production
pnpm build
cd dist
touch README.md .nojekyll
- name: Deploy 🚀
uses: JamesIves/github-pages-deploy-action@v4
with:
folder: dist
clean: true

View File

@ -3,7 +3,7 @@
"prettier --cache --ignore-unknown --write",
"eslint --cache --fix"
],
"{!(package)*.json,*.code-snippets,.!({browserslist,nvm})*rc}": [
"{!(package)*.json,*.code-snippets,.!({browserslist,npm,nvm})*rc}": [
"prettier --cache --write--parser json"
],
"package.json": ["prettier --cache --write"],

5
.npmrc
View File

@ -1,3 +1,4 @@
shell-emulator=true
shamefully-hoist=true
strict-peer-dependencies=false
shell-emulator=true
enable-pre-post-scripts=false
strict-peer-dependencies=false

2
.nvmrc
View File

@ -1 +1 @@
v20.11.1
v22.15.1

View File

@ -1,6 +1,7 @@
{
"recommendations": [
"christian-kohler.path-intellisense",
"warmthsea.vscode-custom-code-color",
"vscode-icons-team.vscode-icons",
"davidanson.vscode-markdownlint",
"ms-azuretools.vscode-docker",

33
.vscode/settings.json vendored
View File

@ -31,9 +31,34 @@
"i18n-ally.keystyle": "nested",
"i18n-ally.sortKeys": true,
"i18n-ally.namespace": true,
"i18n-ally.enabledParsers": ["yaml", "js"],
"i18n-ally.enabledParsers": [
"yaml",
"js"
],
"i18n-ally.sourceLanguage": "en",
"i18n-ally.displayLanguage": "zh-CN",
"i18n-ally.enabledFrameworks": ["vue"],
"iconify.excludes": ["el"]
}
"i18n-ally.enabledFrameworks": [
"vue"
],
"iconify.excludes": [
"el"
],
"vsmqtt.brokerProfiles": [
{
"name": "broker.emqx.io",
"host": "broker.emqx.io/mqtt",
"port": 1883,
"clientId": "vsmqtt_client_db34"
}
],
"vscodeCustomCodeColor.highlightValue": [
"v-loading",
"v-auth",
"v-copy",
"v-longpress",
"v-optimize",
"v-perms",
"v-ripple"
],
"vscodeCustomCodeColor.highlightValueColor": "#b392f0",
}

View File

@ -1,6 +1,173 @@
# 6.0.0 (2025-04-10)
### ✔️ Refactor
- Refactor the icon module, use `@iconify/json` to replace the `@iconify-icons/*` dependency that is no longer maintained and updated, optimize the user experience, ensure that the icon library can be continuously updated and support `Tree-shaking`
- Upgrade `tailwindcss` to `v4` version, bringing faster build speed, simpler installation and configuration, and providing a dedicated `vite` plug-in
### 🎫 Feat
- Add `Ai` chat component example
- Add `tagOnClick` tag to switch global public events
- Add code editor example
- Add `Markdown` example
- Add slider example
### 🐞 Bug fixes
- Fix `aria-hidden` error
- Fix the problem that code hints cannot be displayed when using `this` syntax and update `pinia` related syntax
### 🍏 Perf
- Fix broken links in the waterfall infinite scrolling example
- Update `vue-flow`, related compatibility processing
- Delete the deprecated dependency package `eslint-define-config`, upgrade `eslint` to the latest version, related compatibility processing
- Optimize `src/style/dark.scss` syntax
- Optimize login parameter transfer
- Use `keydown` to replace `keypress`, the `keypress` event has been deprecated
# 5.9.0 (2024-12-10)
### ✔Refactor
- Upgrade `vite` to `v6` version, upgrade `sass` to the latest version, reconstruct the theme writing method, and deprecate [@pureadmin/theme](https://www.npmjs.com/package/@pureadmin/theme) , click to view [Related optimization point details](https://github.com/pure-admin/vue-pure-admin/pull/1188#issue-2630095115). For users who have the [Max version](https://pure-admin.cn/pages/service/#max-%E7%89%88%E6%9C%AC), it is strongly recommended to upgrade. Subsequent Max version users will enjoy a more modern, beautiful and highly customized theme color
- Use [code-inspector-plugin](https://www.npmjs.com/package/code-inspector-plugin) to replace [vite-plugin-vue-inspector](https://www.npmjs.com/package/vite-plugin-vue-inspector)
### 🎫Feat
- Added `ReDrawer` component
- `pure-table` adds dynamic table header example
### 🐞 Bug fixes
- Fixed an issue where the height of the table does not automatically adapt when the full screen function is enabled or disabled after the table is expanded in the menu and department management
### 🍏Perf
- Optimize the layout of the department tree on the left side of user management
# 5.8.0 (2024-08-19)
### 🎫 Feat
- Added a second button permission command (judged based on the `permissions` field returned by the login interface)
- Functional pop-up box `ReDialog` adds whether to enable the `loading` loading animation function after clicking the confirmation button
- `PureTableBar` component adds full screen and exit full screen functions
- `VxeTableBar` component adds full screen and exit full screen functions
- The OK button of the `ReDialog` component provides the close button animation `closeLoading` function
- Add development environment code debugging `vite-plugin-vue-inspector` plug-in to improve development experience
- Added `vite-plugin-checker` plugin for stricter type and `eslint` verification
### 🐞 Bug fixes
- Fixed the problem that the current tab cannot be closed after configuring the routing attribute `fixedTag` to `false`
- Fixed the issue where `logo` cannot be hidden in top menu mode
### 🍏 Perf
- Optimize type hints for custom instructions
- Optimize the press enter login function on the login page
- Optimize the mask level of the left menu on the mobile side
- Optimize system management-permission function style of role management
- Upgraded dependencies, compatible with the latest version of `element-plus`
# 5.7.0 (2024-06-04)
### 🎫 Feat
- Add Google style tabs
### 🐞 Bug fixes
- Fixed the issue where the text exceeds and is not hidden after the menu is folded in Firefox browser
# 5.6.0 (2024-05-14)
### ✔️ Refactor
- Upgrade `pnpm` to `v9` version, requiring `pnpm` version `>=9`
### 🐞 Bug fixes
- Fixed the issue where clicking on an external link would jump twice
### 🍏 Perf
- Optimize `ReSegmented` component
# 5.5.0 (2024-05-07)
### 📄 Docs
The addresses of the document site and full version preview site have been changed!
- The latest document site address: https://pure-admin.cn
- The latest full version preview site address: https://pure-admin.github.io/vue-pure-admin
### ✔️ Refactor
- Reconstruct the `layout` file naming convention to make it more readable
### 🎫 Feat
- Add new component `ReVxeTableBar` to be used with `vxe-table`
### 🐞 Bug fixes
- Fixed the issue where the background color is white when `FixedHeader` is set to `false` in dark mode
- Fixed the problem of delayed closing of functional pop-up window `ReDialog` when clicking the cancel button
### 🍏 Perf
- Optimize account settings-avatar upload function
# 5.4.0 (2024-04-18)
### 🎫 Feat
- Add global disabled attribute `disabled` to `ReSegmented` component
- Added mind map examples
- Functional pop-up box `ReDialog` adds `Popconfirm` bubble confirmation box
- `pure-table` adds `headerSlot` custom header slot usage example
- The route adds a configurable `fixedTag` attribute, which determines whether the current menu name is fixedly displayed on the tab and cannot be closed.
- Added account setting function page and compatible with mobile terminals
- Upgrade `eslint9` and related compatibility processing
- Added global configuration `MaxTagsLevel` property to set the maximum number of open tabs
- Full coverage of the internationalization of the core code of the framework (only the internationalization of the business code needs to be processed)
### 🐞 Bug fixes
- Fixed the issue where columns cannot be dragged normally when there are multiple `RePureTableBar` components on a page
- Fixed the problem of icon display style after the third-level menu is folded to the left
- Fixed the issue where the font color does not take effect after refreshing the account settings page
- Fixed the issue where the `refreshToken` parameter is empty when calling the refresh `token` interface
### 🍏 Perf
- Optimize login interface
- Optimize the logic of obtaining the top menu
- Optimize request whitelist logic and be compatible with more scenarios
- Simplified export and import usage in `store` files
- Removed unnecessary `cloc` tool dependency package, which uses the `GPL` open source license and is controversial
- Optimize the types of `post` and `get` utility functions in `src/utils/http` files
# 5.3.0 (2024-03-28)
### ✔️ Refactor
- Reconstruct internationalized file naming conventions and demo pages with code location hints
### 🎫 Feat
- Add `MQTT` example
- Added `docx` and `excel` file preview examples
- The `ReSegmented` segmented controller has a new `size` attribute, which can set three sizes
- The `RePureTableBar` component and `pure-admin-table` support international switching of table headers
# 5.2.0 (2024-03-22)
### ✔️ refactor
### ✔️ Refactor
- Place the full screen button at the top to make it visible and easy to operate
@ -36,7 +203,7 @@
# 5.1.0 (2024-03-02)
### ✔️ refactor
### ✔️ Refactor
- Reconstruct the tab page `UI` to make it more convenient to click the close button
@ -58,7 +225,7 @@
Totally `ESM` version
### ✔️ refactor
### ✔️ Refactor
- Upgrade `vite` to `v5` version, specify `node` version `>18.18.0`, `pnpm` version `>=8.6.10`
- Use [vite-plugin-fake-server](https://www.npmjs.com/package/vite-plugin-fake-server) to replace [vite-plugin-mock](https://www.npmjs.com/package/vite-plugin-mock), use [@faker-js/faker](https://www.npmjs.com/package/@faker-js/faker) to replace [mockjs](https://www.npmjs.com/package/mockjs)
@ -149,7 +316,7 @@ Totally `ESM` version
# 4.5.0 (2023-06-26)
### ✔️ refactor
### ✔️ Refactor
- Refactor image crop `ReCropper` component, add more useful functions
@ -262,7 +429,7 @@ Totally `ESM` version
[View 4.0.0 version optimization details](https://github.com/pure-admin/vue-pure-admin/issues/428#issuecomment-1422191158)
### ✔️ refactor
### ✔️ Refactor
- Use `css` pseudo-class `before` to refactor the activation background of the menu, similar to [ant.design-menu](https://ant.design/components/menu-cn#components-menu-demo-inline-collapsed)
@ -333,10 +500,10 @@ Totally `ESM` version
# 3.9.5 (2022-12-13)
### ✔️ refactor
### ✔️ Refactor
- completely removed `lodash` and its related libraries
[Click here to see Why Removed? How to integrate it yourself? ](https://yiming_chang.gitee.io/pure-admin-doc/pages/FAQ/#%E5%B9%B3%E5%8F%B0%E5%9C%A8-v3-9-5-%E7 %89%88%E6%9C%AC%E5%AE%8C%E5%85%A8%E7%A7%BB%E9%99%A4%E4%BA%86-lodash-%E5%92%8C% E5%85%B6%E7%9B%B8%E5%85%B3%E5%BA%93-%E4%B8%BA%E4%BB%80%E4%B9%88%E7%A7%BB%E9 %99%A4-%E5%A6%82%E4%BD%95%E8%87%AA%E8%A1%8C%E9%9B%86%E6%88%90)
[Click here to see Why Removed? How to integrate it yourself? ](https://pure-admin.cn/pages/FAQ/#%E5%B9%B3%E5%8F%B0%E5%9C%A8-v3-9-5-%E7%89%88%E6%9C%AC%E5%AE%8C%E5%85%A8%E7%A7%BB%E9%99%A4%E4%BA%86-lodash-%E5%92%8C%E5%85%B6%E7%9B%B8%E5%85%B3%E5%BA%93-%E4%B8%BA%E4%BB%80%E4%B9%88%E7%A7%BB%E9%99%A4-%E5%A6%82%E4%BD%95%E8%87%AA%E8%A1%8C%E9%9B%86%E6%88%90)
### 🎫 Feat
@ -353,10 +520,10 @@ Totally `ESM` version
# 3.9.4 (2022-12-05)
### ✔️ refactor
### ✔️ Refactor
- Completely removed `vxe-table`, after removal, the overall package size of the full version is reduced by `1.82MB`, and the initial startup time is basically the same as the lite version 🐮
[Click here to see Why Removed? How to integrate it yourself?](https://yiming_chang.gitee.io/pure-admin-doc/pages/FAQ/#%E5%B9%B3%E5%8F%B0%E5%9C%A8-v3-9-4-%E7%89%88%E6%9C%AC%E5%AE%8C%E5%85%A8%E7%A7%BB%E9%99%A4%E4%BA%86-vxe-table-%E4%B8%BA%E4%BB%80%E4%B9%88%E7%A7%BB%E9%99%A4-%E5%A6%82%E4%BD%95%E8%87%AA%E8%A1%8C%E9%9B%86%E6%88%90)
[Click here to see Why Removed? How to integrate it yourself?](https://pure-admin.cn/pages/FAQ/#%E5%B9%B3%E5%8F%B0%E5%9C%A8-v3-9-4-%E7%89%88%E6%9C%AC%E5%AE%8C%E5%85%A8%E7%A7%BB%E9%99%A4%E4%BA%86-vxe-table-%E4%B8%BA%E4%BB%80%E4%B9%88%E7%A7%BB%E9%99%A4-%E5%A6%82%E4%BD%95%E8%87%AA%E8%A1%8C%E9%9B%86%E6%88%90)
### 🎫 Feat
@ -462,13 +629,13 @@ Totally `ESM` version
# 3.7.0 (2022-11-21)
### ✔️ refactor
### ✔️ Refactor
- Replace `driver.js` with `intro.js`
### 🎫 Feat
- Add front-end single sign-on, test address https://yiming_chang.gitee.io/vue-pure-admin/#/pure-table/index?username=sso&roles=admin&accessToken=eyJhbGciOiJIUzUxMiJ9.admin
- Add front-end single sign-on, test address https://pure-admin.github.io/vue-pure-admin/#/pure-table/index?username=sso&roles=admin&accessToken=eyJhbGciOiJIUzUxMiJ9.admin
- Add more examples for [@pureadmin/table](https://github.com/pure-admin/pure-admin-table) and `element-plus` [table](https://element-plus.org /zh-CN/component/table.html) example remains the same
- Rich watermark function page (supports customizing various colors, shadows, text, additional attributes, setting undeletable watermarks and setting watermarks for specified elements)
- Optimize the menu, add `MenuArrowIconNoTransition` global configuration, configure it in `public/platform-config.json`, for the left menu mode, the menu expansion can be set `MenuArrowIconNoTransition: true` to solve
@ -513,7 +680,7 @@ Totally `ESM` version
# 3.6.2 (2022-10-27)
### ✔️ refactor
### ✔️ Refactor
- Replace `/@/` alias with `@/` alias
@ -541,7 +708,7 @@ Totally `ESM` version
- Add typewriter component `demo`
- Added `json` editor `demo`
### ✔️ refactor
### ✔️ Refactor
- Refactor the permission module, adopt the most commonly used `RBAC` (Role-Based Access List): role-based permission control (User -> Role -> Permission), and update the page permission and button permission `demo` example, button Permissions support three operation modes (judging permissions in component mode, judging permissions in function mode, and judging permissions in instruction mode)
@ -567,9 +734,9 @@ Totally `ESM` version
- Add `element-plus` seamless scrolling `Table` page demo
- Open `vscode` bracket pair guide
### ✔️ refactor
### ✔️ Refactor
- Replace `unocss` with `tailwindcss`, add `tailwindcss` [documentation](https://yiming_chang.gitee.io/pure-admin-doc/pages/tailwindcss/)
- Replace `unocss` with `tailwindcss`, add `tailwindcss` [documentation](https://pure-admin.cn/pages/tailwindcss/)
### 🐞 Bug fixes
@ -617,7 +784,7 @@ Totally `ESM` version
- Added export `excel` page demo
- Added blank page demo without `Layout`
### ✔️ refactor
### ✔️ Refactor
- Refactored the theme color to adapt to `element-plus` dark mode (also solved the problem that the same element `css` in `3.3.0` and earlier versions was overwritten many times, resulting in poor style debugging)
- Refactored route reset function
@ -653,7 +820,7 @@ Totally `ESM` version
- Added pre-release packaging mode
- Add [hooks] to close a tag (https://github.com/pure-admin/vue-pure-admin/commit/5e8723a031923e79f507e5a17151d3bd88a51523)
### ✔️ refactor
### ✔️ Refactor
- Refactored the landing page to be more inclined to the actual business scenario
- Use `unocss` instead of `windicss`, `unocss` has better performance in development environment, no memory leaks, and `api` is compatible with `windicss`
@ -732,7 +899,7 @@ Totally `ESM` version
- Added `WindiCSS` support
- Add online environment remove console plugin `vite-plugin-remove-console`
### ✔️ refactor
### ✔️ Refactor
- Replace `@element-plus/icons-vue` with `@iconify-icons/ep`

View File

@ -1,6 +1,173 @@
# 6.0.0 (2025-04-10)
### ✔️ Refactor
- Refactor the icon module, use `@iconify/json` to replace the `@iconify-icons/*` dependency that is no longer maintained and updated, optimize the user experience, ensure that the icon library can be continuously updated and support `Tree-shaking`
- Upgrade `tailwindcss` to `v4` version, bringing faster build speed, simpler installation and configuration, and providing a dedicated `vite` plug-in
### 🎫 Feat
- Add `Ai` chat component example
- Add `tagOnClick` tag to switch global public events
- Add code editor example
- Add `Markdown` example
- Add slider example
### 🐞 Bug fixes
- Fix `aria-hidden` error
- Fix the problem that code hints cannot be displayed when using `this` syntax and update `pinia` related syntax
### 🍏 Perf
- Fix broken links in the waterfall infinite scrolling example
- Update `vue-flow`, related compatibility processing
- Delete the deprecated dependency package `eslint-define-config`, upgrade `eslint` to the latest version, related compatibility processing
- Optimize `src/style/dark.scss` syntax
- Optimize login parameter transfer
- Use `keydown` to replace `keypress`, the `keypress` event has been deprecated
# 5.9.0 (2024-12-10)
### ✔Refactor
- Upgrade `vite` to `v6` version, upgrade `sass` to the latest version, reconstruct the theme writing method, and deprecate [@pureadmin/theme](https://www.npmjs.com/package/@pureadmin/theme) , click to view [Related optimization point details](https://github.com/pure-admin/vue-pure-admin/pull/1188#issue-2630095115). For users who have the [Max version](https://pure-admin.cn/pages/service/#max-%E7%89%88%E6%9C%AC), it is strongly recommended to upgrade. Subsequent Max version users will enjoy a more modern, beautiful and highly customized theme color
- Use [code-inspector-plugin](https://www.npmjs.com/package/code-inspector-plugin) to replace [vite-plugin-vue-inspector](https://www.npmjs.com/package/vite-plugin-vue-inspector)
### 🎫Feat
- Added `ReDrawer` component
- `pure-table` adds dynamic table header example
### 🐞 Bug fixes
- Fixed an issue where the height of the table does not automatically adapt when the full screen function is enabled or disabled after the table is expanded in the menu and department management
### 🍏Perf
- Optimize the layout of the department tree on the left side of user management
# 5.8.0 (2024-08-19)
### 🎫 Feat
- Added a second button permission command (judged based on the `permissions` field returned by the login interface)
- Functional pop-up box `ReDialog` adds whether to enable the `loading` loading animation function after clicking the confirmation button
- `PureTableBar` component adds full screen and exit full screen functions
- `VxeTableBar` component adds full screen and exit full screen functions
- The OK button of the `ReDialog` component provides the close button animation `closeLoading` function
- Add development environment code debugging `vite-plugin-vue-inspector` plug-in to improve development experience
- Added `vite-plugin-checker` plugin for stricter type and `eslint` verification
### 🐞 Bug fixes
- Fixed the problem that the current tab cannot be closed after configuring the routing attribute `fixedTag` to `false`
- Fixed the issue where `logo` cannot be hidden in top menu mode
### 🍏 Perf
- Optimize type hints for custom instructions
- Optimize the press enter login function on the login page
- Optimize the mask level of the left menu on the mobile side
- Optimize system management-permission function style of role management
- Upgraded dependencies, compatible with the latest version of `element-plus`
# 5.7.0 (2024-06-04)
### 🎫 Feat
- Add Google style tabs
### 🐞 Bug fixes
- Fixed the issue where the text exceeds and is not hidden after the menu is folded in Firefox browser
# 5.6.0 (2024-05-14)
### ✔️ Refactor
- Upgrade `pnpm` to `v9` version, requiring `pnpm` version `>=9`
### 🐞 Bug fixes
- Fixed the issue where clicking on an external link would jump twice
### 🍏 Perf
- Optimize `ReSegmented` component
# 5.5.0 (2024-05-07)
### 📄 Docs
The addresses of the document site and full version preview site have been changed!
- The latest document site address: https://pure-admin.cn
- The latest full version preview site address: https://pure-admin.github.io/vue-pure-admin
### ✔️ Refactor
- Reconstruct the `layout` file naming convention to make it more readable
### 🎫 Feat
- Add new component `ReVxeTableBar` to be used with `vxe-table`
### 🐞 Bug fixes
- Fixed the issue where the background color is white when `FixedHeader` is set to `false` in dark mode
- Fixed the problem of delayed closing of functional pop-up window `ReDialog` when clicking the cancel button
### 🍏 Perf
- Optimize account settings-avatar upload function
# 5.4.0 (2024-04-18)
### 🎫 Feat
- Add global disabled attribute `disabled` to `ReSegmented` component
- Added mind map examples
- Functional pop-up box `ReDialog` adds `Popconfirm` bubble confirmation box
- `pure-table` adds `headerSlot` custom header slot usage example
- The route adds a configurable `fixedTag` attribute, which determines whether the current menu name is fixedly displayed on the tab and cannot be closed.
- Added account setting function page and compatible with mobile terminals
- Upgrade `eslint9` and related compatibility processing
- Added global configuration `MaxTagsLevel` property to set the maximum number of open tabs
- Full coverage of the internationalization of the core code of the framework (only the internationalization of the business code needs to be processed)
### 🐞 Bug fixes
- Fixed the issue where columns cannot be dragged normally when there are multiple `RePureTableBar` components on a page
- Fixed the problem of icon display style after the third-level menu is folded to the left
- Fixed the issue where the font color does not take effect after refreshing the account settings page
- Fixed the issue where the `refreshToken` parameter is empty when calling the refresh `token` interface
### 🍏 Perf
- Optimize login interface
- Optimize the logic of obtaining the top menu
- Optimize request whitelist logic and be compatible with more scenarios
- Simplified export and import usage in `store` files
- Removed unnecessary `cloc` tool dependency package, which uses the `GPL` open source license and is controversial
- Optimize the types of `post` and `get` utility functions in `src/utils/http` files
# 5.3.0 (2024-03-28)
### ✔️ Refactor
- Reconstruct internationalized file naming conventions and demo pages with code location hints
### 🎫 Feat
- Add `MQTT` example
- Added `docx` and `excel` file preview examples
- The `ReSegmented` segmented controller has a new `size` attribute, which can set three sizes
- The `RePureTableBar` component and `pure-admin-table` support international switching of table headers
# 5.2.0 (2024-03-22)
### ✔️ refactor
### ✔️ Refactor
- Place the full screen button at the top to make it visible and easy to operate
@ -36,7 +203,7 @@
# 5.1.0 (2024-03-02)
### ✔️ refactor
### ✔️ Refactor
- Reconstruct the tab page `UI` to make it more convenient to click the close button
@ -58,7 +225,7 @@
Totally `ESM` version
### ✔️ refactor
### ✔️ Refactor
- Upgrade `vite` to `v5` version, specify `node` version `>18.18.0`, `pnpm` version `>=8.6.10`
- Use [vite-plugin-fake-server](https://www.npmjs.com/package/vite-plugin-fake-server) to replace [vite-plugin-mock](https://www.npmjs.com/package/vite-plugin-mock), use [@faker-js/faker](https://www.npmjs.com/package/@faker-js/faker) to replace [mockjs](https://www.npmjs.com/package/mockjs)
@ -149,7 +316,7 @@ Totally `ESM` version
# 4.5.0 (2023-06-26)
### ✔️ refactor
### ✔️ Refactor
- Refactor image crop `ReCropper` component, add more useful functions
@ -262,7 +429,7 @@ Totally `ESM` version
[View 4.0.0 version optimization details](https://github.com/pure-admin/vue-pure-admin/issues/428#issuecomment-1422191158)
### ✔️ refactor
### ✔️ Refactor
- Use `css` pseudo-class `before` to refactor the activation background of the menu, similar to [ant.design-menu](https://ant.design/components/menu-cn#components-menu-demo-inline-collapsed)
@ -333,10 +500,10 @@ Totally `ESM` version
# 3.9.5 (2022-12-13)
### ✔️ refactor
### ✔️ Refactor
- completely removed `lodash` and its related libraries
[Click here to see Why Removed? How to integrate it yourself? ](https://yiming_chang.gitee.io/pure-admin-doc/pages/FAQ/#%E5%B9%B3%E5%8F%B0%E5%9C%A8-v3-9-5-%E7 %89%88%E6%9C%AC%E5%AE%8C%E5%85%A8%E7%A7%BB%E9%99%A4%E4%BA%86-lodash-%E5%92%8C% E5%85%B6%E7%9B%B8%E5%85%B3%E5%BA%93-%E4%B8%BA%E4%BB%80%E4%B9%88%E7%A7%BB%E9 %99%A4-%E5%A6%82%E4%BD%95%E8%87%AA%E8%A1%8C%E9%9B%86%E6%88%90)
[Click here to see Why Removed? How to integrate it yourself? ](https://pure-admin.cn/pages/FAQ/#%E5%B9%B3%E5%8F%B0%E5%9C%A8-v3-9-5-%E7%89%88%E6%9C%AC%E5%AE%8C%E5%85%A8%E7%A7%BB%E9%99%A4%E4%BA%86-lodash-%E5%92%8C%E5%85%B6%E7%9B%B8%E5%85%B3%E5%BA%93-%E4%B8%BA%E4%BB%80%E4%B9%88%E7%A7%BB%E9%99%A4-%E5%A6%82%E4%BD%95%E8%87%AA%E8%A1%8C%E9%9B%86%E6%88%90)
### 🎫 Feat
@ -353,10 +520,10 @@ Totally `ESM` version
# 3.9.4 (2022-12-05)
### ✔️ refactor
### ✔️ Refactor
- Completely removed `vxe-table`, after removal, the overall package size of the full version is reduced by `1.82MB`, and the initial startup time is basically the same as the lite version 🐮
[Click here to see Why Removed? How to integrate it yourself?](https://yiming_chang.gitee.io/pure-admin-doc/pages/FAQ/#%E5%B9%B3%E5%8F%B0%E5%9C%A8-v3-9-4-%E7%89%88%E6%9C%AC%E5%AE%8C%E5%85%A8%E7%A7%BB%E9%99%A4%E4%BA%86-vxe-table-%E4%B8%BA%E4%BB%80%E4%B9%88%E7%A7%BB%E9%99%A4-%E5%A6%82%E4%BD%95%E8%87%AA%E8%A1%8C%E9%9B%86%E6%88%90)
[Click here to see Why Removed? How to integrate it yourself?](https://pure-admin.cn/pages/FAQ/#%E5%B9%B3%E5%8F%B0%E5%9C%A8-v3-9-4-%E7%89%88%E6%9C%AC%E5%AE%8C%E5%85%A8%E7%A7%BB%E9%99%A4%E4%BA%86-vxe-table-%E4%B8%BA%E4%BB%80%E4%B9%88%E7%A7%BB%E9%99%A4-%E5%A6%82%E4%BD%95%E8%87%AA%E8%A1%8C%E9%9B%86%E6%88%90)
### 🎫 Feat
@ -462,13 +629,13 @@ Totally `ESM` version
# 3.7.0 (2022-11-21)
### ✔️ refactor
### ✔️ Refactor
- Replace `driver.js` with `intro.js`
### 🎫 Feat
- Add front-end single sign-on, test address https://yiming_chang.gitee.io/vue-pure-admin/#/pure-table/index?username=sso&roles=admin&accessToken=eyJhbGciOiJIUzUxMiJ9.admin
- Add front-end single sign-on, test address https://pure-admin.github.io/vue-pure-admin/#/pure-table/index?username=sso&roles=admin&accessToken=eyJhbGciOiJIUzUxMiJ9.admin
- Add more examples for [@pureadmin/table](https://github.com/pure-admin/pure-admin-table) and `element-plus` [table](https://element-plus.org /zh-CN/component/table.html) example remains the same
- Rich watermark function page (supports customizing various colors, shadows, text, additional attributes, setting undeletable watermarks and setting watermarks for specified elements)
- Optimize the menu, add `MenuArrowIconNoTransition` global configuration, configure it in `public/platform-config.json`, for the left menu mode, the menu expansion can be set `MenuArrowIconNoTransition: true` to solve
@ -513,7 +680,7 @@ Totally `ESM` version
# 3.6.2 (2022-10-27)
### ✔️ refactor
### ✔️ Refactor
- Replace `/@/` alias with `@/` alias
@ -541,7 +708,7 @@ Totally `ESM` version
- Add typewriter component `demo`
- Added `json` editor `demo`
### ✔️ refactor
### ✔️ Refactor
- Refactor the permission module, adopt the most commonly used `RBAC` (Role-Based Access List): role-based permission control (User -> Role -> Permission), and update the page permission and button permission `demo` example, button Permissions support three operation modes (judging permissions in component mode, judging permissions in function mode, and judging permissions in instruction mode)
@ -567,9 +734,9 @@ Totally `ESM` version
- Add `element-plus` seamless scrolling `Table` page demo
- Open `vscode` bracket pair guide
### ✔️ refactor
### ✔️ Refactor
- Replace `unocss` with `tailwindcss`, add `tailwindcss` [documentation](https://yiming_chang.gitee.io/pure-admin-doc/pages/tailwindcss/)
- Replace `unocss` with `tailwindcss`, add `tailwindcss` [documentation](https://pure-admin.cn/pages/tailwindcss/)
### 🐞 Bug fixes
@ -617,7 +784,7 @@ Totally `ESM` version
- Added export `excel` page demo
- Added blank page demo without `Layout`
### ✔️ refactor
### ✔️ Refactor
- Refactored the theme color to adapt to `element-plus` dark mode (also solved the problem that the same element `css` in `3.3.0` and earlier versions was overwritten many times, resulting in poor style debugging)
- Refactored route reset function
@ -653,7 +820,7 @@ Totally `ESM` version
- Added pre-release packaging mode
- Add [hooks] to close a tag (https://github.com/pure-admin/vue-pure-admin/commit/5e8723a031923e79f507e5a17151d3bd88a51523)
### ✔️ refactor
### ✔️ Refactor
- Refactored the landing page to be more inclined to the actual business scenario
- Use `unocss` instead of `windicss`, `unocss` has better performance in development environment, no memory leaks, and `api` is compatible with `windicss`
@ -732,7 +899,7 @@ Totally `ESM` version
- Added `WindiCSS` support
- Add online environment remove console plugin `vite-plugin-remove-console`
### ✔️ refactor
### ✔️ Refactor
- Replace `@element-plus/icons-vue` with `@iconify-icons/ep`

View File

@ -1,6 +1,173 @@
# 6.0.0 (2025-04-10)
### ✔️ Refactor
- 重构图标模块,使用`@iconify/json`替换不再维护更新的`@iconify-icons/*`依赖,优化使用体验,确保图标库可持续更新并支持`Tree-shaking`
- 升级`tailwindcss``v4`版本,带来更快的构建速度、更简化的安装和配置、提供专属`vite`插件
### 🎫 Feat
- 添加`Ai`聊天组件示例
- 添加`tagOnClick`标签切换全局公共事件
- 添加代码编辑器示例
- 添加`Markdown`示例
- 添加滑块示例
### 🐞 Bug fixes
- 修复`aria-hidden`报错
- 修复使用`this`语法时无法显示代码提示的问题并更新`pinia`相关语法
### 🍏 Perf
- 修复组件-瀑布流无限滚动示例中失效的链接
- 更新`vue-flow`,相关兼容处理
- 删除已弃用的依赖包`eslint-define-config`,升级`eslint`至最新版本,相关兼容处理
- 优化`src/style/dark.scss`语法
- 优化登录传参
- 使用`keydown`替换`keypress``keypress`事件已弃用
# 5.9.0 (2024-12-10)
### ✔️ Refactor
- 升级`vite``v6`版本,升级`sass`至最新版,重构主题写法,弃用 [@pureadmin/theme](https://www.npmjs.com/package/@pureadmin/theme),点击查看 [相关优化点细节](https://github.com/pure-admin/vue-pure-admin/pull/1188#issue-2630095115)。对于拥有 [Max版本](https://pure-admin.cn/pages/service/#max-%E7%89%88%E6%9C%AC) 的用户平台强烈建议升级,后续`Max版本用户`会享有一套更现代、美观且自定义程度高的主题色
- 使用 [code-inspector-plugin](https://www.npmjs.com/package/code-inspector-plugin) 替换 [vite-plugin-vue-inspector](https://www.npmjs.com/package/vite-plugin-vue-inspector)
### 🎫 Feat
- 新增函数式抽屉组件
- `pure-table`添加动态表头示例
### 🐞 Bug fixes
- 修复在菜单、部门管理中,表格展开后启用或关闭全屏功能时,表格高度未自动适应的问题
### 🍏 Perf
- 优化用户管理左侧部门树的布局
# 5.8.0 (2024-08-19)
### 🎫 Feat
- 新增第二种按钮权限指令(根据登录接口返回的`permissions`字段进行判断)
- 函数式弹框`ReDialog`添加点击确认按钮后是否开启`loading`加载动画功能
- `PureTableBar`组件添加全屏和退出全屏功能
- `VxeTableBar`组件添加全屏和退出全屏功能
- `ReDialog`组件的确定按钮提供关闭按钮动画`closeLoading`功能
- 添加开发环境代码调试`vite-plugin-vue-inspector`插件,提升开发体验
- 添加`vite-plugin-checker`插件,更严格的类型和`eslint`校验
### 🐞 Bug fixes
- 修复配置路由属性`fixedTag``false`后当前标签页不可关闭的问题
- 修复顶部菜单模式下`logo`不可隐藏的问题
### 🍏 Perf
- 优化自定义指令的类型提示
- 优化登录页回车登录功能
- 优化移动端左侧菜单遮罩层级
- 优化系统管理-角色管理的权限功能样式
- 升级依赖,`element-plus`最新版兼容处理
# 5.7.0 (2024-06-04)
### 🎫 Feat
- 添加谷歌风格的页签
### 🐞 Bug fixes
- 修复在火狐浏览器中菜单折叠后,文字超出未隐藏的问题
# 5.6.0 (2024-05-14)
### ✔️ Refactor
- 升级`pnpm``v9`版本,规定`pnpm`版本`>=9`
### 🐞 Bug fixes
- 修复点击外链会跳转两次的问题
### 🍏 Perf
- 优化`ReSegmented`组件
# 5.5.0 (2024-05-07)
### 📄 Docs
文档站和完整版预览站地址更换!
- 最新文档站地址https://pure-admin.cn
- 最新完整版预览站地址https://pure-admin.github.io/vue-pure-admin
### ✔️ Refactor
- 重构`layout`文件命名规范,更易读
### 🎫 Feat
- 添加新组件`ReVxeTableBar`搭配`vxe-table`使用
### 🐞 Bug fixes
- 修复深色模式下设置`FixedHeader``false`时,背景色为白色的问题
- 修复函数式弹窗`ReDialog`点击取消按钮,延时关闭无效问题
### 🍏 Perf
- 优化账号设置-头像上传功能
# 5.4.0 (2024-04-18)
### 🎫 Feat
- 分段控制器组件添加全局禁用属性`disabled`
- 添加思维导图示例
- 函数式弹框`ReDialog`添加`Popconfirm`气泡确认框
- `pure-table`添加`headerSlot`自定义表头插槽用法示例
- 路由添加可配置的`fixedTag`属性,作用为当前菜单名称是否固定显示在标签页且不可关闭
- 添加账户设置功能页面且兼容移动端
- 升级`eslint9`,相关兼容处理
- 添加全局配置`MaxTagsLevel`属性,可设置打开标签页最大数
- 框架核心代码国际化全量覆盖(仅需处理业务代码国际化即可)
### 🐞 Bug fixes
- 修复当一个页面存在多个`RePureTableBar`组件,列无法正常拖动问题
- 修复三级菜单向左折叠后图标显示样式问题
- 修复账户设置页面,刷新后字体颜色未生效的问题
- 修复调用刷新`token`接口时,`refreshToken`参数为空的问题
### 🍏 Perf
- 优化登录接口
- 优化获取顶级菜单逻辑
- 优化请求白名单逻辑,兼容更多场景
- 简化`store`文件中导出和导入用法
- 移除非必要的`cloc`工具依赖包,它使用`GPL`开源许可证具有争议性
- 优化`src/utils/http`文件中`post``get`工具函数的类型
# 5.3.0 (2024-03-28)
### ✔️ Refactor
- 重构国际化文件命名规范以及演示页加上代码位置提示
### 🎫 Feat
- 添加`MQTT`示例
- 添加`docx``excel`文件预览示例
- `ReSegmented`分段控制器新增`size`属性,可设置三种尺寸
- `RePureTableBar`组件搭配`pure-admin-table`支持表头国际化切换
# 5.2.0 (2024-03-22)
### ✔️ refactor
### ✔️ Refactor
- 将全屏按钮置于顶部,使其显眼且易于操作
@ -28,7 +195,7 @@
- 修复`windwos`下点击注册页面会出现滚动条问题
- 修复`windows`下页面切换,内容区会出现滚动条问题
- 修复`pure-table`带状态表格在深色整体风格下状态样式消失的问题
- 修复项目配置中开启灰色模式和深色整体风格,刷新页面整体风格异常
- 修复系统配置中开启灰色模式和深色整体风格,刷新页面整体风格异常
### 🍏 Perf
@ -36,7 +203,7 @@
# 5.1.0 (2024-03-02)
### ✔️ refactor
### ✔️ Refactor
- 重构标签页`UI`,点击关闭按钮更方便
@ -58,7 +225,7 @@
全面`ESM`版本
### ✔️ refactor
### ✔️ Refactor
- 升级`vite``v5`版本,规定`node`版本`>18.18.0``pnpm`版本`>=8.6.10`
- 使用 [vite-plugin-fake-server](https://www.npmjs.com/package/vite-plugin-fake-server) 替换 [vite-plugin-mock](https://www.npmjs.com/package/vite-plugin-mock),使用 [@faker-js/faker](https://www.npmjs.com/package/@faker-js/faker) 替换 [mockjs](https://www.npmjs.com/package/mockjs)
@ -71,7 +238,7 @@
- 所有`search`搜索图标统一替换为`@iconify-icons/ri/search-line`它比较常用将其放入全局离线图标中
- 移除`iframe`在暗模式下的滤镜效果
- 带来更美观精致的首页
- 更干净整洁的项目配置右侧弹出面板
- 更干净整洁的系统配置右侧弹出面板
- 重构关于页面,整体更紧致,关键信息更突出
### 🎫 Feat
@ -149,7 +316,7 @@
# 4.5.0 (2023-06-26)
### ✔️ refactor
### ✔️ Refactor
- 重构图片裁剪 `ReCropper` 组件,添加更多实用功能
@ -261,7 +428,7 @@
[查看 4.0.0 版本优化细节](https://github.com/pure-admin/vue-pure-admin/issues/428#issuecomment-1422191158)
### ✔️ refactor
### ✔️ Refactor
- 采用 `css` 伪类 `before` 写法重构菜单的激活背景,类似于 [ant.design-menu](https://ant.design/components/menu-cn#components-menu-demo-inline-collapsed)
@ -332,10 +499,10 @@
# 3.9.5 (2022-12-13)
### ✔️ refactor
### ✔️ Refactor
- 完全移除了 `lodash` 和其相关库
[点击此处查看为什么移除?如何自行集成?](https://yiming_chang.gitee.io/pure-admin-doc/pages/FAQ/#%E5%B9%B3%E5%8F%B0%E5%9C%A8-v3-9-5-%E7%89%88%E6%9C%AC%E5%AE%8C%E5%85%A8%E7%A7%BB%E9%99%A4%E4%BA%86-lodash-%E5%92%8C%E5%85%B6%E7%9B%B8%E5%85%B3%E5%BA%93-%E4%B8%BA%E4%BB%80%E4%B9%88%E7%A7%BB%E9%99%A4-%E5%A6%82%E4%BD%95%E8%87%AA%E8%A1%8C%E9%9B%86%E6%88%90)
[点击此处查看为什么移除?如何自行集成?](https://pure-admin.cn/pages/FAQ/#%E5%B9%B3%E5%8F%B0%E5%9C%A8-v3-9-5-%E7%89%88%E6%9C%AC%E5%AE%8C%E5%85%A8%E7%A7%BB%E9%99%A4%E4%BA%86-lodash-%E5%92%8C%E5%85%B6%E7%9B%B8%E5%85%B3%E5%BA%93-%E4%B8%BA%E4%BB%80%E4%B9%88%E7%A7%BB%E9%99%A4-%E5%A6%82%E4%BD%95%E8%87%AA%E8%A1%8C%E9%9B%86%E6%88%90)
### 🎫 Feat
@ -352,10 +519,10 @@
# 3.9.4 (2022-12-05)
### ✔️ refactor
### ✔️ Refactor
- 完全移除了 `vxe-table`,移除后,完整版整体打包大小减少 `1.82MB`,首启动时长基本和精简版持平 🐮
[点击此处查看为什么移除?如何自行集成?](https://yiming_chang.gitee.io/pure-admin-doc/pages/FAQ/#%E5%B9%B3%E5%8F%B0%E5%9C%A8-v3-9-4-%E7%89%88%E6%9C%AC%E5%AE%8C%E5%85%A8%E7%A7%BB%E9%99%A4%E4%BA%86-vxe-table-%E4%B8%BA%E4%BB%80%E4%B9%88%E7%A7%BB%E9%99%A4-%E5%A6%82%E4%BD%95%E8%87%AA%E8%A1%8C%E9%9B%86%E6%88%90)
[点击此处查看为什么移除?如何自行集成?](https://pure-admin.cn/pages/FAQ/#%E5%B9%B3%E5%8F%B0%E5%9C%A8-v3-9-4-%E7%89%88%E6%9C%AC%E5%AE%8C%E5%85%A8%E7%A7%BB%E9%99%A4%E4%BA%86-vxe-table-%E4%B8%BA%E4%BB%80%E4%B9%88%E7%A7%BB%E9%99%A4-%E5%A6%82%E4%BD%95%E8%87%AA%E8%A1%8C%E9%9B%86%E6%88%90)
### 🎫 Feat
@ -461,13 +628,13 @@
# 3.7.0 (2022-11-21)
### ✔️ refactor
### ✔️ Refactor
- 使用 `intro.js` 替换 `driver.js`
### 🎫 Feat
- 添加前端单点登录,测试地址 https://yiming_chang.gitee.io/vue-pure-admin/#/pure-table/index?username=sso&roles=admin&accessToken=eyJhbGciOiJIUzUxMiJ9.admin
- 添加前端单点登录,测试地址 https://pure-admin.github.io/vue-pure-admin/#/pure-table/index?username=sso&roles=admin&accessToken=eyJhbGciOiJIUzUxMiJ9.admin
- 为 [@pureadmin/table](https://github.com/pure-admin/pure-admin-table) 添加更多的示例和 `element-plus` 的 [table](https://element-plus.org/zh-CN/component/table.html) 示例保持一致
- 丰富水印功能页面(支持自定义各种颜色、阴影、文字、额外属性、设置不可删除水印以及给指定元素设置水印)
- 优化菜单,添加 `MenuArrowIconNoTransition` 全局配置,在 `public/platform-config.json` 中配置即可,对于出现左侧菜单模式,菜单展开卡顿的可设置 `MenuArrowIconNoTransition: true` 即可解决
@ -512,7 +679,7 @@
# 3.6.2 (2022-10-27)
### ✔️ refactor
### ✔️ Refactor
- 使用`@/`别名替换`/@/`别名
@ -540,7 +707,7 @@
- 添加打字机组件`demo`
- 添加`json`编辑器`demo`
### ✔️ refactor
### ✔️ Refactor
- 重构权限模块,采用目前最常用的`RBAC`Role-Based Access List: 基于角色的权限控制( 用户 -> 角色 -> 权限 ),并更新页面权限和按钮权限`demo`示例,按钮权限支持三种操作模式(组件方式判断权限、函数方式判断权限、指令方式判断权限)
@ -566,9 +733,9 @@
- 添加 `element-plus` 无缝滚动 `Table` 页面 demo
- 开启 `vscode` 括号对指南
### ✔️ refactor
### ✔️ Refactor
- 使用 `tailwindcss` 替换 `unocss`,新增 `tailwindcss` [使用文档](https://yiming_chang.gitee.io/pure-admin-doc/pages/tailwindcss/)
- 使用 `tailwindcss` 替换 `unocss`,新增 `tailwindcss` [使用文档](https://pure-admin.cn/pages/tailwindcss/)
### 🐞 Bug fixes
@ -616,7 +783,7 @@
- 添加导出 `excel` 页面 demo
- 添加无 `Layout` 的空白页面 demo
### ✔️ refactor
### ✔️ Refactor
- 重构主题色,适配 `element-plus` 暗黑模式(同时也解决了 `3.3.0` 及更低版本中同样的元素 `css` 被多次覆盖,导致样式不好调试的问题)
- 重构路由重置功能
@ -652,7 +819,7 @@
- 添加预发布打包模式
- 添加关闭某个标签的[hooks](https://github.com/pure-admin/vue-pure-admin/commit/5e8723a031923e79f507e5a17151d3bd88a51523)
### ✔️ refactor
### ✔️ Refactor
- 重构登录页,更偏向实际业务场景
- 使用`unocss`替换`windicss``unocss`开发环境下性能更好,没有内存泄露,而且`api`使用上兼容`windicss`
@ -731,7 +898,7 @@
- 添加 `WindiCSS` 支持
- 添加线上环境删 console 插件`vite-plugin-remove-console`
### ✔️ refactor
### ✔️ Refactor
- 使用`@iconify-icons/ep`替换`@element-plus/icons-vue`

View File

@ -1,8 +1,8 @@
FROM node:18-alpine as build-stage
FROM node:20-alpine as build-stage
WORKDIR /app
RUN corepack enable
RUN corepack prepare pnpm@8.6.10 --activate
RUN corepack prepare pnpm@latest --activate
RUN npm config set registry https://registry.npmmirror.com

View File

@ -10,11 +10,9 @@
`vue-pure-admin` is an open source, free and out-of-the-box middle and backend management system template. Completely adopts `ECMAScript` module (`ESM`) specifications to write and organize code, using the latest `Vue3`, `Vite`, `Element-Plus`, `TypeScript`, `Pinia`, `Tailwindcss` and other mainstream technologies develop
## Sponsors
## R&D philosophy
<a class="logo" href="https://ai-tools.cn/resume/start" target="_blank" rel="sponsored noopener">
<img src="./public/sponsors/aitools.svg" alt="aitools">
</a>
Seek innovation in stability and see the future in technology
## Thin version (offering non-internationalized and internationalized versions)
@ -23,19 +21,19 @@ The simplified version is based on the shelf extracted from [vue-pure-admin](htt
[Click to view the non-internationalized version](https://github.com/pure-admin/pure-admin-thin)
[Click to view Internationalization version](https://github.com/pure-admin/pure-admin-thin/tree/i18n)
## Supporting Video
## Supporting video
[Click Watch Tutorial](https://www.bilibili.com/video/BV1kg411v7QT)
[Click Watch UI Design](https://www.bilibili.com/video/BV17g411T7rq)
[Click me to view UI design](https://www.bilibili.com/video/BV17g411T7rq)
[Click me to view the rapid development tutorial](https://www.bilibili.com/video/BV1kg411v7QT)
## Docs
## Nanny-level documents
[View vue-pure-admin documentation](https://yiming_chang.gitee.io/pure-admin-doc)
[View @pureadmin/utils documentation](https://pure-admin-utils.netlify.app)
[Click me to view vue-pure-admin documentation](https://pure-admin.cn/)
[Click me to view @pureadmin/utils documentation](https://pure-admin-utils.netlify.app)
## Quality service, software outsourcing, sponsorship support
## Premium service
[Click me for details](https://yiming_chang.gitee.io/pure-admin-doc/pages/service/)
[Click me for details](https://pure-admin.cn/pages/service/)
## Tauri
@ -47,7 +45,7 @@ The simplified version is based on the shelf extracted from [vue-pure-admin](htt
## Preview
[preview station](https://yiming_chang.gitee.io/vue-pure-admin)
[preview station](https://pure-admin.github.io/vue-pure-admin)
`PC`
@ -176,12 +174,17 @@ Thank you very much for your in-depth understanding of the source code and your
| **Contributor** | **SpecificCode** |
| :---------------------------------------------: | :------------------------------------------------------------------------------: |
| [hb0730](https://github.com/hb0730) | [代码](https://github.com/pure-admin/vue-pure-admin/commits?author=hb0730) |
| [o-cc](https://github.com/o-cc) | [代码](https://github.com/pure-admin/vue-pure-admin/commits?author=o-cc) |
| [yj-liuzepeng](https://github.com/yj-liuzepeng) | [代码](https://github.com/pure-admin/vue-pure-admin/commits?author=yj-liuzepeng) |
| [skyline523](https://github.com/skyline523) | [代码](https://github.com/pure-admin/vue-pure-admin/commits?author=skyline523) |
| [shark-lajiao](https://github.com/shark-lajiao) | [代码](https://github.com/pure-admin/vue-pure-admin/commits?author=shark-lajiao) |
| [WitMiao](https://github.com/WitMiao) | [代码](https://github.com/pure-admin/vue-pure-admin/commits?author=WitMiao) |
| [hb0730](https://github.com/hb0730) | [code](https://github.com/pure-admin/vue-pure-admin/commits?author=hb0730) |
| [o-cc](https://github.com/o-cc) | [code](https://github.com/pure-admin/vue-pure-admin/commits?author=o-cc) |
| [yj-liuzepeng](https://github.com/yj-liuzepeng) | [code](https://github.com/pure-admin/vue-pure-admin/commits?author=yj-liuzepeng) |
| [skyline523](https://github.com/skyline523) | [code](https://github.com/pure-admin/vue-pure-admin/commits?author=skyline523) |
| [shark-lajiao](https://github.com/shark-lajiao) | [code](https://github.com/pure-admin/vue-pure-admin/commits?author=shark-lajiao) |
| [WitMiao](https://github.com/WitMiao) | [code](https://github.com/pure-admin/vue-pure-admin/commits?author=WitMiao) |
| [QFifteen](https://github.com/QFifteen) | [code](https://github.com/pure-admin/vue-pure-admin/commits?author=QFifteen) |
| [edgexie](https://github.com/edgexie) | [code](https://github.com/pure-admin/vue-pure-admin/commits?author=edgexie) |
| [way-jm](https://github.com/way-jm) | [code](https://github.com/pure-admin/vue-pure-admin/commits?author=way-jm) |
| [simple-hui](https://github.com/simple-hui) | [code](https://github.com/pure-admin/vue-pure-admin/commits?author=simple-hui) |
| [tinysimple](https://github.com/tinysimple) | [code](https://github.com/pure-admin/vue-pure-admin/commits?author=tinysimple) |
## Git Contribution submission specification

View File

@ -11,11 +11,9 @@
`vue-pure-admin` 是一款开源免费且开箱即用的中后台管理系统模版。完全采用 `ECMAScript` 模块(`ESM`)规范来编写和组织代码,使用了最新的 `Vue3`
`Vite``Element-Plus``TypeScript``Pinia``Tailwindcss` 等主流技术开发
## 赞助商
## 研发理念
<a class="logo" href="https://ai-tools.cn/resume/start" target="_blank" rel="sponsored noopener">
<img src="./public/sponsors/aitools.svg" alt="aitools">
</a>
稳定中求创新,技术中见未来
## 精简版本(实际项目开发请用精简版本,提供 `非国际化``国际化` 两个版本选择)
@ -26,17 +24,17 @@
## 配套视频
[点我查看快速开发教程](https://www.bilibili.com/video/BV1kg411v7QT)
[点我查看 UI 设计](https://www.bilibili.com/video/BV17g411T7rq)
[点我查看 UI 设计](https://www.bilibili.com/video/BV17g411T7rq)
[点我查看快速开发教程](https://www.bilibili.com/video/BV1kg411v7QT)
## 配套保姆级文档
[点我查看 vue-pure-admin 文档](https://yiming_chang.gitee.io/pure-admin-doc)
[点我查看 vue-pure-admin 文档](https://pure-admin.cn/)
[点我查看 @pureadmin/utils 文档](https://pure-admin-utils.netlify.app)
## 优质服务、软件外包、赞助支持
## 高级服务
[点我查看详情](https://yiming_chang.gitee.io/pure-admin-doc/pages/service/)
[点我查看详情](https://pure-admin.cn/pages/service/)
## `Tauri` 版本
@ -48,7 +46,7 @@
## 预览
[点我查看预览](https://yiming_chang.gitee.io/vue-pure-admin)
[点我查看预览](https://pure-admin.github.io/vue-pure-admin)
`PC`
@ -183,6 +181,11 @@ docker run -dp 8080:80 --name pure-admin vue-pure-admin
| [skyline523](https://github.com/skyline523) | [代码](https://github.com/pure-admin/vue-pure-admin/commits?author=skyline523) |
| [shark-lajiao](https://github.com/shark-lajiao) | [代码](https://github.com/pure-admin/vue-pure-admin/commits?author=shark-lajiao) |
| [WitMiao](https://github.com/WitMiao) | [代码](https://github.com/pure-admin/vue-pure-admin/commits?author=WitMiao) |
| [QFifteen](https://github.com/QFifteen) | [代码](https://github.com/pure-admin/vue-pure-admin/commits?author=QFifteen) |
| [edgexie](https://github.com/edgexie) | [代码](https://github.com/pure-admin/vue-pure-admin/commits?author=edgexie) |
| [way-jm](https://github.com/way-jm) | [代码](https://github.com/pure-admin/vue-pure-admin/commits?author=way-jm) |
| [simple-hui](https://github.com/simple-hui) | [代码](https://github.com/pure-admin/vue-pure-admin/commits?author=simple-hui) |
| [tinysimple](https://github.com/tinysimple) | [代码](https://github.com/pure-admin/vue-pure-admin/commits?author=tinysimple) |
## `Git` 贡献提交规范

View File

@ -1,13 +1,13 @@
import type { Plugin } from "vite";
import gradient from "gradient-string";
import { getPackageSize } from "./utils";
import dayjs, { type Dayjs } from "dayjs";
import duration from "dayjs/plugin/duration";
import gradientString from "gradient-string";
import boxen, { type Options as BoxenOptions } from "boxen";
dayjs.extend(duration);
const welcomeMessage = gradientString("cyan", "magenta").multiline(
`您好! 欢迎使用 pure-admin 开源项目\n我们为您精心准备了下面两个贴心的保姆级文档\nhttps://yiming_chang.gitee.io/pure-admin-doc\nhttps://pure-admin-utils.netlify.app`
const welcomeMessage = gradient(["cyan", "magenta"]).multiline(
`您好! 欢迎使用 pure-admin 开源项目\n我们为您精心准备了下面两个贴心的保姆级文档\nhttps://pure-admin.cn\nhttps://pure-admin-utils.netlify.app`
);
const boxenOptions: BoxenOptions = {
@ -41,7 +41,7 @@ export function viteBuildInfo(): Plugin {
callback: (size: string) => {
console.log(
boxen(
gradientString("cyan", "magenta").multiline(
gradient(["cyan", "magenta"]).multiline(
`🎉 恭喜打包完成(总用时${dayjs
.duration(endTime.diff(startTime))
.format("mm分ss秒")}${size}`

View File

@ -11,21 +11,25 @@ const include = [
"dayjs",
"axios",
"pinia",
"vditor",
"typeit",
"swiper",
"qrcode",
"intro.js",
"vue-i18n",
"deep-chat",
"vxe-table",
"vue-types",
"js-cookie",
"vue-tippy",
"cropperjs",
"jsbarcode",
"codemirror",
"pinyin-pro",
"sortablejs",
"swiper/vue",
"mint-filter",
"highlight.js",
"@vueuse/core",
"vue3-danmaku",
"v-contextmenu",
@ -42,6 +46,7 @@ const include = [
"@howdyjs/mouse-menu",
"@logicflow/extension",
"vue-virtual-scroller",
"codemirror-editor-vue3",
"@amap/amap-jsapi-loader",
"el-table-infinite-scroll",
"vue-waterfall-plugin-next",
@ -52,12 +57,8 @@ const include = [
/**
*
* `@iconify-icons/` `exclude` 使
* 使
*/
const exclude = [
"@iconify-icons/ep",
"@iconify-icons/ri",
"@pureadmin/theme/dist/browser-utils"
];
const exclude = ["@iconify/json"];
export { include, exclude };

View File

@ -3,15 +3,16 @@ import vue from "@vitejs/plugin-vue";
import { pathResolve } from "./utils";
import { viteBuildInfo } from "./info";
import svgLoader from "vite-svg-loader";
import Icons from "unplugin-icons/vite";
import type { PluginOption } from "vite";
import vueJsx from "@vitejs/plugin-vue-jsx";
import tailwindcss from "@tailwindcss/vite";
import { configCompressPlugin } from "./compress";
import removeNoMatch from "vite-plugin-router-warn";
import { visualizer } from "rollup-plugin-visualizer";
import removeConsole from "vite-plugin-remove-console";
import { themePreprocessorPlugin } from "@pureadmin/theme";
import VueI18nPlugin from "@intlify/unplugin-vue-i18n/vite";
import { genScssMultipleScopeVars } from "../src/layout/theme";
import { codeInspectorPlugin } from "code-inspector-plugin";
import { vitePluginFakeServer } from "vite-plugin-fake-server";
export function getPluginsList(
@ -20,14 +21,29 @@ export function getPluginsList(
): PluginOption[] {
const lifecycle = process.env.npm_lifecycle_event;
return [
vue(),
tailwindcss(),
vue({
template: {
compilerOptions: {
isCustomElement: tag => tag === "deep-chat"
}
}
}),
// jsx、tsx语法支持
vueJsx(),
VueI18nPlugin({
runtimeOnly: true,
compositionOnly: true,
include: [pathResolve("../locales/**")]
}),
/**
* DOM IDE
* Mac Option + Shift
* Windows Alt + Shift
* https://inspector.fe-dev.cn/guide/start.html
*/
codeInspectorPlugin({
bundler: "vite",
hideConsole: true
}),
viteBuildInfo(),
/**
* vue-router动态路由警告No match found for location with path
@ -42,15 +58,13 @@ export function getPluginsList(
infixName: false,
enableProd: true
}),
// 自定义主题
themePreprocessorPlugin({
scss: {
multipleScopeVars: genScssMultipleScopeVars(),
extract: true
}
}),
// svg组件化支持
svgLoader(),
// 自动按需加载图标
Icons({
compiler: "vue3",
scale: 1
}),
VITE_CDN ? cdn : null,
configCompressPlugin(VITE_COMPRESSION),
// 线上环境删除console

View File

@ -48,7 +48,7 @@ const __APP_INFO__ = {
};
/** 处理环境变量 */
const warpperEnv = (envConf: Recordable): ViteEnv => {
const wrapperEnv = (envConf: Recordable): ViteEnv => {
// 默认值
const ret: ViteEnv = {
VITE_PORT: 8848,
@ -107,4 +107,4 @@ const getPackageSize = options => {
});
};
export { root, pathResolve, alias, __APP_INFO__, warpperEnv, getPackageSize };
export { root, pathResolve, alias, __APP_INFO__, wrapperEnv, getPackageSize };

View File

@ -1,19 +1,25 @@
import js from "@eslint/js";
import tseslint from "typescript-eslint";
import pluginVue from "eslint-plugin-vue";
import * as parserVue from "vue-eslint-parser";
import configPrettier from "eslint-config-prettier";
import pluginPrettier from "eslint-plugin-prettier";
import { defineFlatConfig } from "eslint-define-config";
import * as parserTypeScript from "@typescript-eslint/parser";
import pluginTypeScript from "@typescript-eslint/eslint-plugin";
import { defineConfig, globalIgnores } from "eslint/config";
export default defineFlatConfig([
export default defineConfig([
globalIgnores([
"**/.*",
"dist/*",
"*.d.ts",
"public/*",
"src/assets/**",
"src/**/iconfont/**"
]),
{
...js.configs.recommended,
ignores: ["src/assets/**", "src/**/iconfont/**"],
languageOptions: {
globals: {
// index.d.ts
// types/index.d.ts
RefType: "readonly",
EmitType: "readonly",
TargetContext: "readonly",
@ -66,26 +72,18 @@ export default defineFlatConfig([
]
}
},
{
...tseslint.config({
extends: [...tseslint.configs.recommended],
files: ["**/*.?([cm])ts", "**/*.?([cm])tsx"],
languageOptions: {
parser: parserTypeScript,
parserOptions: {
sourceType: "module"
}
},
plugins: {
"@typescript-eslint": pluginTypeScript
},
rules: {
...pluginTypeScript.configs.strict.rules,
"@typescript-eslint/ban-types": "off",
"@typescript-eslint/no-redeclare": "error",
"@typescript-eslint/ban-ts-comment": "off",
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/prefer-as-const": "warn",
"@typescript-eslint/no-empty-function": "off",
"@typescript-eslint/no-non-null-assertion": "off",
"@typescript-eslint/no-unused-expressions": "off",
"@typescript-eslint/no-unsafe-function-type": "off",
"@typescript-eslint/no-import-type-side-effects": "error",
"@typescript-eslint/explicit-module-boundary-types": "off",
"@typescript-eslint/consistent-type-imports": [
@ -104,20 +102,20 @@ export default defineFlatConfig([
}
]
}
},
}),
{
files: ["**/*.d.ts"],
rules: {
"eslint-comments/no-unlimited-disable": "off",
"import/no-duplicates": "off",
"no-restricted-syntax": "off",
"unused-imports/no-unused-vars": "off"
}
},
{
files: ["**/*.?([cm])js"],
rules: {
"@typescript-eslint/no-require-imports": "off",
"@typescript-eslint/no-var-requires": "off"
"@typescript-eslint/no-require-imports": "off"
}
},
{
@ -138,18 +136,19 @@ export default defineFlatConfig([
jsx: true
},
extraFileExtensions: [".vue"],
parser: "@typescript-eslint/parser",
parser: tseslint.parser,
sourceType: "module"
}
},
plugins: {
"@typescript-eslint": tseslint.plugin,
vue: pluginVue
},
processor: pluginVue.processors[".vue"],
rules: {
...pluginVue.configs.base.rules,
...pluginVue.configs["vue3-essential"].rules,
...pluginVue.configs["vue3-recommended"].rules,
...pluginVue.configs.essential.rules,
...pluginVue.configs.recommended.rules,
"no-undef": "off",
"no-unused-vars": "off",
"vue/no-v-html": "off",

View File

@ -10,9 +10,6 @@
/>
<title>vue-pure-admin</title>
<link rel="icon" href="/favicon.ico" />
<script>
window.process = {};
</script>
</head>
<body>

View File

@ -1,184 +1,240 @@
buttons:
hsLoginOut: LoginOut
hsfullscreen: FullScreen
hsexitfullscreen: ExitFullscreen
hsrefreshRoute: RefreshRoute
hslogin: Login
hsadd: Add
hsmark: Mark/Cancel
hssave: Save
hssearch: Search
hsexpendAll: Expand All
hscollapseAll: Collapse All
hssystemSet: Open ProjectConfig
hsdelete: Delete
hsreload: Reload
hscloseCurrentTab: Close CurrentTab
hscloseLeftTabs: Close LeftTabs
hscloseRightTabs: Close RightTabs
hscloseOtherTabs: Close OtherTabs
hscloseAllTabs: Close AllTabs
hswholeFullScreen: FullScreen
hswholeExitFullScreen: ExitFull
hscontentFullScreen: Content FullScreen
hscontentExitFullScreen: Content ExitFullScreen
pureAccountSettings: Account
pureLoginOut: LoginOut
pureLogin: Login
pureOpenSystemSet: Open System Configs
pureReload: Reload
pureCloseCurrentTab: Close CurrentTab
pureCloseLeftTabs: Close LeftTabs
pureCloseRightTabs: Close RightTabs
pureCloseOtherTabs: Close OtherTabs
pureCloseAllTabs: Close AllTabs
pureContentFullScreen: Content FullScreen
pureContentExitFullScreen: Content ExitFullScreen
pureClickCollapse: Collapse
pureClickExpand: Expand
pureConfirm: Confirm
pureSwitch: Switch
pureClose: Close
pureBackTop: BackTop
pureOpenText: Open
pureCloseText: Close
search:
pureTotal: Total
pureHistory: History
pureCollect: Collect
pureDragSort: Drag Sort
pureEmpty: Empty
purePlaceholder: Search Menu
panel:
pureSystemSet: System Configs
pureCloseSystemSet: Close System Configs
pureClearCacheAndToLogin: Clear cache and return to login page
pureClearCache: Clear Cache
pureOverallStyle: Overall Style
pureOverallStyleLight: Light
pureOverallStyleLightTip: Set sail freshly and light up the comfortable work interface
pureOverallStyleDark: Dark
pureOverallStyleDarkTip: Moonlight Overture, indulge in the tranquility and elegance of the night
pureOverallStyleSystem: Auto
pureOverallStyleSystemTip: Synchronize time, the interface naturally responds to morning and dusk
pureThemeColor: Theme Color
pureLayoutModel: Layout Model
pureVerticalTip: The menu on the left is familiar and friendly
pureHorizontalTip: Top menu, concise overview
pureMixTip: Mixed menu, flexible
pureStretch: Stretch Page
pureStretchFixed: Fixed
pureStretchFixedTip: Compact pages make it easy to find the information you need
pureStretchCustom: Custom
pureStretchCustomTip: Minimum 1280, maximum 1600
pureTagsStyle: Tags Style
pureTagsStyleSmart: Smart
pureTagsStyleSmartTip: Smart tags add fun and brilliance
pureTagsStyleCard: Card
pureTagsStyleCardTip: Card tags for efficient browsing
pureTagsStyleChrome: Chrome
pureTagsStyleChromeTip: Chrome style is classic and elegant
pureInterfaceDisplay: Interface Display
pureGreyModel: Grey Model
pureWeakModel: Weak Model
pureHiddenTags: Hidden Tags
pureHiddenFooter: Hidden Footer
pureMultiTagsCache: MultiTags Cache
menus:
hshome: Home
hslogin: Login
hsempty: Empty Page
hstable: Table
hssysManagement: System Manage
hsUser: User Manage
hsRole: Role Manage
hsSystemMenu: Menu Manage
hsDept: Dept Manage
hssysMonitor: System Monitor
hsOnlineUser: Online User
hsLoginLog: Login Log
hsOperationLog: Operation Log
hsSystemLog: System Log
hseditor: Editor
hsabnormal: Abnormal Page
hsfourZeroFour: "404"
hsfourZeroOne: "403"
hsFive: "500"
hscomponents: Components
hsdialog: Dialog
hsmessage: Message Tips
hsvideo: Video
hssegmented: Segmented
hswaterfall: Waterfall
hsmap: Map
hsdraggable: Draggable
hssplitPane: Split Pane
hsText: Text Ellipsis
hsElButton: Button
hsbutton: Button Animation
hsCheckButton: Check Button
hscropping: Picture Cropping
hsanimatecss: AnimateCss Selector
hscountTo: Digital Animation
hsselector: Scope Selector
hsflowChart: Flow Chart
hsseamless: Seamless Scroll
hscontextmenu: Context Menu
hstypeit: Typeit
hsjsoneditor: JSON Editor
hsColorPicker: Color Picker
hsDatePicker: Date Picker
hsDateTimePicker: DateTimePicker
hsTimePicker: TimePicker
hsTag: Tag
hsStatistic: Statistic
hsCollapse: Collapse
hsGanttastic: Gantt Chart
hsProgress: Progress
hsUpload: File Upload
hsCheckCard: CheckCard
hsmenus: MultiLevel Menu
hsmenu1: Menu1
hsmenu1-1: Menu1-1
hsmenu1-2: Menu1-2
hsmenu1-2-1: Menu1-2-1
hsmenu1-2-2: Menu1-2-2
hsmenu1-3: Menu1-3
hsmenu2: Menu2
permission: Permission Manage
permissionPage: Page Permission
permissionButton: Button Permission
hstabs: Tabs Operate
hsguide: Guide
hsAble: Able
hsMenuTree: Menu Tree
hsVideoFrame: Video Frame Capture
hsWavesurfer: Audio Visualization
hsRipple: Ripple
hsOptimize: Debounce、Throttle、Copy、Longpress Directives
hsVerify: Captcha
hsWatermark: Water Mark
hsPrint: Print
hsDownload: Download
hsExternalPage: External Page
hsExternalDoc: Docs External
hsEmbeddedDoc: Docs Embedded
externalLink: Vue-Pure-Admin
pureutilsLink: Pure-Admin-Utils
hsEpDocument: Element-Plus
hsTailwindcssDocument: Tailwindcss
hsVueDocument: Vue3
hsViteDocument: Vite
hsPiniaDocument: Pinia
hsRouterDocument: Vue-Router
hsAbout: About
hsResult: Result Page
hsSuccess: Success Page
hsFail: Fail Page
hsIconSelect: Icon Select
hsTimeline: Time Line
hsLineTree: LineTree
hsList: List Page
hsListCard: Card List Page
hsDebounce: Debounce & Throttle
hsFormDesign: Form Design
hsBarcode: Barcode
hsQrcode: Qrcode
hsCascader: Area Cascader
hsSwiper: Swiper Plugin
hsVirtualList: Virtual List
hsPdf: PDF Preview
hsExcel: Export Excel
hsInfiniteScroll: Table Infinite Scroll
hsSensitive: Sensitive Filter
hsPinyin: PinYin
hsdanmaku: Danmaku
hsSchemaForm: Form
hsPureTableBase: Base Usage
hsPureTableHigh: High Usage
hsPureTableEdit: Edit Usage
hsVxeTable: Virtual Usage
hsboard: Paint Board
hsMenuoverflow: Menu Overflow Show Tooltip Text
hsChildMenuoverflow: Child Menu Overflow Show Tooltip Text
pureHome: Home
pureLogin: Login
pureEmpty: Empty Page
pureTable: Table
pureSysManagement: System Manage
pureUser: User Manage
pureRole: Role Manage
pureSystemMenu: Menu Manage
pureDept: Dept Manage
pureSysMonitor: System Monitor
pureOnlineUser: Online User
pureLoginLog: Login Log
pureOperationLog: Operation Log
pureSystemLog: System Log
pureCodeMirror: CodeMirror
pureMarkdown: Markdown
pureEditor: Editor
pureAbnormal: Abnormal Page
pureFourZeroFour: "404"
pureFourZeroOne: "403"
pureFive: "500"
pureComponents: Components
pureDialog: Dialog
pureDrawer: Drawer
pureMessage: Message Tips
pureVideo: Video
pureSegmented: Segmented
pureWaterfall: Waterfall
pureMap: Map
pureDraggable: Draggable
pureSplitPane: Split Pane
pureText: Text Ellipsis
pureSlider: Slider
pureElButton: Button
pureButton: Button Animation
pureCheckButton: Check Button
pureCropping: Picture Cropping
pureAnimatecss: AnimateCss Selector
pureCountTo: Digital Animation
pureSelector: Scope Selector
pureFlowChart: Flow Chart
pureSeamless: Seamless Scroll
pureContextmenu: Context Menu
pureTypeit: Typeit
pureJsonEditor: JSON Editor
pureColorPicker: Color Picker
pureDatePicker: Date Picker
pureDateTimePicker: DateTimePicker
pureTimePicker: TimePicker
pureTag: Tag
pureStatistic: Statistic
pureCollapse: Collapse
pureGanttastic: Gantt Chart
pureProgress: Progress
pureUpload: File Upload
pureCheckCard: CheckCard
pureMenus: MultiLevel Menu
pureMenu1: Menu1
pureMenu1-1: Menu1-1
pureMenu1-2: Menu1-2
pureMenu1-2-1: Menu1-2-1
pureMenu1-2-2: Menu1-2-2
pureMenu1-3: Menu1-3
pureMenu2: Menu2
purePermission: Permission Manage
purePermissionPage: Page Permission
purePermissionButton: Button Permission
purePermissionButtonRouter: Route return button permission
purePermissionButtonLogin: Login interface return button permission
pureTabs: Tabs Operate
pureGuide: Guide
pureAble: Able
pureMenuTree: Menu Tree
pureVideoFrame: Video Frame Capture
pureWavesurfer: Audio Visualization
pureRipple: Ripple
pureMqtt: Mqtt Client
pureOptimize: Debounce、Throttle、Copy、Longpress Directives
pureVerify: Captcha
pureWatermark: Water Mark
purePrint: Print
pureDownload: Download
pureExternalPage: External Page
pureExternalDoc: Docs External
pureEmbeddedDoc: Docs Embedded
pureExternalLink: Vue-Pure-Admin
pureUtilsLink: Pure-Admin-Utils
pureColorHuntDoc: ColorHunt
pureUiGradients: UiGradients
pureEpDoc: Element-Plus
pureTailwindcssDoc: Tailwindcss
pureVueDoc: Vue3
pureViteDoc: Vite
purePiniaDoc: Pinia
pureRouterDoc: Vue-Router
pureAbout: About
pureResult: Result Page
pureSuccess: Success Page
pureFail: Fail Page
pureIconSelect: Icon Select
pureTimeline: Time Line
pureLineTree: LineTree
pureList: List Page
pureCardList: Card List Page
pureDebounce: Debounce & Throttle
pureFormDesign: Form Design
pureBarcode: Barcode
pureQrcode: Qrcode
pureCascader: Area Cascader
pureSwiper: Swiper Plugin
pureVirtualList: Virtual List
purePdf: PDF Preview
pureExcel: Export Excel
pureInfiniteScroll: Table Infinite Scroll
pureSensitive: Sensitive Filter
purePinyin: PinYin
pureDanmaku: Danmaku
pureSchemaForm: Form
pureTableBase: Base Usage
pureTableHigh: High Usage
pureTableEdit: Edit Usage
pureVxeTable: Virtual Usage
pureBoard: Paint Board
pureMindMap: Mind Map
pureMenuOverflow: Menu Overflow Show Tooltip Text
pureChildMenuOverflow: Child Menu Overflow Show Tooltip Text
status:
hsLoad: Loading...
pureLoad: Loading...
pureMessage: Message
pureNotify: Notify
pureTodo: Todo
pureNoMessage: No Message
pureNoNotify: No Notify
pureNoTodo: No Todo
login:
username: Username
password: Password
verifyCode: VerifyCode
remember: days no need to login
rememberInfo: After checking and logging in, will automatically log in to the system without entering your username and password within the specified number of days.
sure: Sure Password
forget: Forget Password?
login: Login
thirdLogin: Third Login
phoneLogin: Phone Login
qRCodeLogin: QRCode Login
register: Register
weChatLogin: WeChat Login
alipayLogin: Alipay Login
qqLogin: QQ Login
weiboLogin: Weibo Login
phone: Phone
smsVerifyCode: SMS VerifyCode
back: Back
test: Mock Test
tip: After scanning the code, click "Confirm" to complete the login
definite: Definite
loginSuccess: Login Success
registerSuccess: Regist Success
tickPrivacy: Please tick Privacy Policy
readAccept: I have read it carefully and accept
privacyPolicy: Privacy Policy
getVerifyCode: Get VerifyCode
info: Seconds
usernameReg: Please enter username
passwordReg: Please enter password
verifyCodeReg: Please enter verify code
verifyCodeCorrectReg: Please enter correct verify code
verifyCodeSixReg: Please enter a 6-digit verify code
phoneReg: Please enter the phone
phoneCorrectReg: Please enter the correct phone number format
passwordRuleReg: The password format should be any combination of 8-18 digits
passwordSureReg: Please enter confirm password
passwordDifferentReg: The two passwords do not match!
passwordUpdateReg: Password has been updated
pureUsername: Username
purePassword: Password
pureVerifyCode: VerifyCode
pureRemember: days no need to login
pureRememberInfo: After checking and logging in, will automatically log in to the system without entering your username and password within the specified number of days.
pureSure: Sure Password
pureForget: Forget Password?
pureLogin: Login
pureThirdLogin: Third Login
purePhoneLogin: Phone Login
pureQRCodeLogin: QRCode Login
pureRegister: Register
pureWeChatLogin: WeChat Login
pureAlipayLogin: Alipay Login
pureQQLogin: QQ Login
pureWeiBoLogin: Weibo Login
purePhone: Phone
pureSmsVerifyCode: SMS VerifyCode
pureBack: Back
pureTest: Mock Test
pureTip: After scanning the code, click "Confirm" to complete the login
pureDefinite: Definite
pureLoginSuccess: Login Success
pureLoginFail: Login Fail
pureRegisterSuccess: Regist Success
pureTickPrivacy: Please tick Privacy Policy
pureReadAccept: I have read it carefully and accept
purePrivacyPolicy: Privacy Policy
pureGetVerifyCode: Get VerifyCode
pureInfo: Seconds
pureUsernameReg: Please enter username
purePassWordReg: Please enter password
pureVerifyCodeReg: Please enter verify code
pureVerifyCodeCorrectReg: Please enter correct verify code
pureVerifyCodeSixReg: Please enter a 6-digit verify code
purePhoneReg: Please enter the phone
purePhoneCorrectReg: Please enter the correct phone number format
purePassWordRuleReg: The password format should be any combination of 8-18 digits
purePassWordSureReg: Please enter confirm password
purePassWordDifferentReg: The two passwords do not match!
purePassWordUpdateReg: Password has been updated

View File

@ -1,184 +1,240 @@
buttons:
hsLoginOut: 退出系统
hsfullscreen: 全屏
hsexitfullscreen: 退出全屏
hsrefreshRoute: 刷新路由
hslogin: 登录
hsadd: 新增
hsmark: 标记/取消
hssave: 保存
hssearch: 搜索
hsexpendAll: 全部展开
hscollapseAll: 全部折叠
hssystemSet: 打开项目配置
hsdelete: 删除
hsreload: 重新加载
hscloseCurrentTab: 关闭当前标签页
hscloseLeftTabs: 关闭左侧标签页
hscloseRightTabs: 关闭右侧标签页
hscloseOtherTabs: 关闭其他标签页
hscloseAllTabs: 关闭全部标签页
hswholeFullScreen: 全屏
hswholeExitFullScreen: 退出全屏
hscontentFullScreen: 内容区全屏
hscontentExitFullScreen: 内容区退出全屏
pureAccountSettings: 账户设置
pureLoginOut: 退出系统
pureLogin: 登录
pureOpenSystemSet: 打开系统配置
pureReload: 重新加载
pureCloseCurrentTab: 关闭当前标签页
pureCloseLeftTabs: 关闭左侧标签页
pureCloseRightTabs: 关闭右侧标签页
pureCloseOtherTabs: 关闭其他标签页
pureCloseAllTabs: 关闭全部标签页
pureContentFullScreen: 内容区全屏
pureContentExitFullScreen: 内容区退出全屏
pureClickCollapse: 点击折叠
pureClickExpand: 点击展开
pureConfirm: 确认
pureSwitch: 切换
pureClose: 关闭
pureBackTop: 回到顶部
pureOpenText:
pureCloseText:
search:
pureTotal:
pureHistory: 搜索历史
pureCollect: 收藏
pureDragSort: (可拖拽排序)
pureEmpty: 暂无搜索结果
purePlaceholder: 搜索菜单(支持拼音搜索)
panel:
pureSystemSet: 系统配置
pureCloseSystemSet: 关闭配置
pureClearCacheAndToLogin: 清空缓存并返回登录页
pureClearCache: 清空缓存
pureOverallStyle: 整体风格
pureOverallStyleLight: 浅色
pureOverallStyleLightTip: 清新启航,点亮舒适的工作界面
pureOverallStyleDark: 深色
pureOverallStyleDarkTip: 月光序曲,沉醉于夜的静谧雅致
pureOverallStyleSystem: 自动
pureOverallStyleSystemTip: 同步时光,界面随晨昏自然呼应
pureThemeColor: 主题色
pureLayoutModel: 导航模式
pureVerticalTip: 左侧菜单,亲切熟悉
pureHorizontalTip: 顶部菜单,简洁概览
pureMixTip: 混合菜单,灵活多变
pureStretch: 页宽
pureStretchFixed: 固定
pureStretchFixedTip: 紧凑页面,轻松找到所需信息
pureStretchCustom: 自定义
pureStretchCustomTip: 最小1280、最大1600
pureTagsStyle: 页签风格
pureTagsStyleSmart: 灵动
pureTagsStyleSmartTip: 灵动标签,添趣生辉
pureTagsStyleCard: 卡片
pureTagsStyleCardTip: 卡片标签,高效浏览
pureTagsStyleChrome: 谷歌
pureTagsStyleChromeTip: 谷歌风格,经典美观
pureInterfaceDisplay: 界面显示
pureGreyModel: 灰色模式
pureWeakModel: 色弱模式
pureHiddenTags: 隐藏标签页
pureHiddenFooter: 隐藏页脚
pureMultiTagsCache: 页签持久化
menus:
hshome: 首页
hslogin: 登录
hsempty: 无Layout页
hstable: 表格
hssysManagement: 系统管理
hsUser: 用户管理
hsRole: 角色管理
hsSystemMenu: 菜单管理
hsDept: 部门管理
hssysMonitor: 系统监控
hsOnlineUser: 在线用户
hsLoginLog: 登录日志
hsOperationLog: 操作日志
hsSystemLog: 系统日志
hseditor: 编辑器
hsabnormal: 异常页面
hsfourZeroFour: "404"
hsfourZeroOne: "403"
hsFive: "500"
hscomponents: 组件
hsdialog: 函数式弹框
hsmessage: 消息提示
hsvideo: 视频
hssegmented: 分段控制器
hswaterfall: 瀑布流无限滚动
hsmap: 地图
hsdraggable: 拖拽
hssplitPane: 切割面板
hsText: 文本省略
hsElButton: 按钮
hsCheckButton: 可选按钮
hsbutton: 按钮动效
hscropping: 图片裁剪
hsanimatecss: animate.css选择器
hscountTo: 数字动画
hsselector: 范围选择器
hsflowChart: 流程图
hsseamless: 无缝滚动
hscontextmenu: 右键菜单
hstypeit: 打字机
hsjsoneditor: JSON编辑器
hsColorPicker: 颜色选择器
hsDatePicker: 日期选择器
hsDateTimePicker: 日期时间选择器
hsTimePicker: 时间选择器
hsTag: 标签
hsStatistic: 统计组件
hsCollapse: 折叠面板
hsGanttastic: 甘特图
hsProgress: 进度条
hsUpload: 文件上传
hsCheckCard: 多选卡片
hsmenus: 多级菜单
hsmenu1: 菜单1
hsmenu1-1: 菜单1-1
hsmenu1-2: 菜单1-2
hsmenu1-2-1: 菜单1-2-1
hsmenu1-2-2: 菜单1-2-2
hsmenu1-3: 菜单1-3
hsmenu2: 菜单2
permission: 权限管理
permissionPage: 页面权限
permissionButton: 按钮权限
hstabs: 标签页操作
hsguide: 引导页
hsAble: 功能
hsMenuTree: 菜单树结构
hsVideoFrame: 视频帧截取-wasm版
hsWavesurfer: 音频可视化
hsRipple: 波纹(Ripple)
hsOptimize: 防抖、截流、复制、长按指令
hsVerify: 图形验证码
hsWatermark: 水印
hsPrint: 打印
hsDownload: 下载
hsExternalPage: 外部页面
hsExternalDoc: 文档外链
hsEmbeddedDoc: 文档内嵌
externalLink: vue-pure-admin
pureutilsLink: pure-admin-utils
hsEpDocument: element-plus
hsTailwindcssDocument: tailwindcss
hsVueDocument: vue3
hsViteDocument: vite
hsPiniaDocument: pinia
hsRouterDocument: vue-router
hsAbout: 关于
hsResult: 结果页面
hsSuccess: 成功页面
hsFail: 失败页面
hsIconSelect: 图标选择器
hsTimeline: 时间线
hsLineTree: 树形连接线
hsList: 列表页面
hsListCard: 卡片列表页
hsDebounce: 防抖节流
hsFormDesign: 表单设计器
hsBarcode: 条形码
hsQrcode: 二维码
hsCascader: 区域级联选择器
hsSwiper: Swiper插件
hsVirtualList: 虚拟列表
hsPdf: PDF预览
hsExcel: 导出Excel
hsInfiniteScroll: 表格无限滚动
hsSensitive: 敏感词过滤
hsPinyin: 汉语拼音
hsdanmaku: 弹幕
hsSchemaForm: 表单
hsPureTableBase: 基础用法
hsPureTableHigh: 高级用法
hsPureTableEdit: 可编辑用法
hsVxeTable: 虚拟滚动
hsboard: 艺术画板
hsMenuoverflow: 目录超出显示 Tooltip 文字提示
hsChildMenuoverflow: 菜单超出显示 Tooltip 文字提示
pureHome: 首页
pureLogin: 登录
pureEmpty: 无Layout页
pureTable: 表格
pureSysManagement: 系统管理
pureUser: 用户管理
pureRole: 角色管理
pureSystemMenu: 菜单管理
pureDept: 部门管理
pureSysMonitor: 系统监控
pureOnlineUser: 在线用户
pureLoginLog: 登录日志
pureOperationLog: 操作日志
pureSystemLog: 系统日志
pureCodeMirror: 代码编辑器
pureMarkdown: Markdown
pureEditor: 编辑器
pureAbnormal: 异常页面
pureFourZeroFour: "404"
pureFourZeroOne: "403"
pureFive: "500"
pureComponents: 组件
pureDialog: 函数式弹框
pureDrawer: 函数式抽屉
pureMessage: 消息提示
pureVideo: 视频
pureSegmented: 分段控制器
pureWaterfall: 瀑布流无限滚动
pureMap: 地图
pureDraggable: 拖拽
pureSplitPane: 切割面板
pureText: 文本省略
pureSlider: 滑块
pureElButton: 按钮
pureCheckButton: 可选按钮
pureButton: 按钮动效
pureCropping: 图片裁剪
pureAnimatecss: animate.css选择器
pureCountTo: 数字动画
pureSelector: 范围选择器
pureFlowChart: 流程图
pureSeamless: 无缝滚动
pureContextmenu: 右键菜单
pureTypeit: 打字机
pureJsonEditor: JSON编辑器
pureColorPicker: 颜色选择器
pureDatePicker: 日期选择器
pureDateTimePicker: 日期时间选择器
pureTimePicker: 时间选择器
pureTag: 标签
pureStatistic: 统计组件
pureCollapse: 折叠面板
pureGanttastic: 甘特图
pureProgress: 进度条
pureUpload: 文件上传
pureCheckCard: 多选卡片
pureMenus: 多级菜单
pureMenu1: 菜单1
pureMenu1-1: 菜单1-1
pureMenu1-2: 菜单1-2
pureMenu1-2-1: 菜单1-2-1
pureMenu1-2-2: 菜单1-2-2
pureMenu1-3: 菜单1-3
pureMenu2: 菜单二
purePermission: 权限管理
purePermissionPage: 页面权限
purePermissionButton: 按钮权限
purePermissionButtonRouter: 路由返回按钮权限
purePermissionButtonLogin: 登录接口返回按钮权限
pureTabs: 标签页操作
pureGuide: 引导页
pureAble: 功能
pureMenuTree: 菜单树结构
pureVideoFrame: 视频帧截取-wasm版
pureWavesurfer: 音频可视化
pureRipple: 波纹(Ripple)
pureMqtt: MQTT客户端(mqtt)
pureOptimize: 防抖、截流、复制、长按指令
pureVerify: 图形验证码
pureWatermark: 水印
purePrint: 打印
pureDownload: 下载
pureExternalPage: 外部页面
pureExternalDoc: 文档外链
pureEmbeddedDoc: 文档内嵌
pureExternalLink: vue-pure-admin
pureUtilsLink: pure-admin-utils
pureColorHuntDoc: 调色板
pureUiGradients: 渐变色
pureEpDoc: element-plus
pureTailwindcssDoc: tailwindcss
pureVueDoc: vue3
pureViteDoc: vite
purePiniaDoc: pinia
pureRouterDoc: vue-router
pureAbout: 关于
pureResult: 结果页面
pureSuccess: 成功页面
pureFail: 失败页面
pureIconSelect: 图标选择器
pureTimeline: 时间线
pureLineTree: 树形连接线
pureList: 列表页面
pureCardList: 卡片列表页
pureDebounce: 防抖节流
pureFormDesign: 表单设计器
pureBarcode: 条形码
pureQrcode: 二维码
pureCascader: 区域级联选择器
pureSwiper: Swiper插件
pureVirtualList: 虚拟列表
purePdf: PDF预览
pureExcel: 导出Excel
pureInfiniteScroll: 表格无限滚动
pureSensitive: 敏感词过滤
purePinyin: 汉语拼音
pureDanmaku: 弹幕
pureSchemaForm: 表单
pureTableBase: 基础用法
pureTableHigh: 高级用法
pureTableEdit: 可编辑用法
pureVxeTable: 虚拟滚动
pureBoard: 艺术画板
pureMindMap: 思维导图
pureMenuOverflow: 目录超出显示 Tooltip 文字提示
pureChildMenuOverflow: 菜单超出显示 Tooltip 文字提示
status:
hsLoad: 加载中...
pureLoad: 加载中...
pureMessage: 消息
pureNotify: 通知
pureTodo: 待办
pureNoMessage: 暂无消息
pureNoNotify: 暂无通知
pureNoTodo: 暂无待办
login:
username: 账号
password: 密码
verifyCode: 验证码
remember: 天内免登录
rememberInfo: 勾选并登录后,规定天数内无需输入用户名和密码会自动登入系统
sure: 确认密码
forget: 忘记密码?
login: 登录
thirdLogin: 第三方登录
phoneLogin: 手机登录
qRCodeLogin: 二维码登录
register: 注册
weChatLogin: 微信登录
alipayLogin: 支付宝登录
qqLogin: QQ登录
weiboLogin: 微博登录
phone: 手机号码
smsVerifyCode: 短信验证码
back: 返回
test: 模拟测试
tip: 扫码后点击"确认",即可完成登录
definite: 确定
loginSuccess: 登录成功
registerSuccess: 注册成功
tickPrivacy: 请勾选隐私政策
readAccept: 我已仔细阅读并接受
privacyPolicy: 《隐私政策》
getVerifyCode: 获取验证码
info: 秒后重新获取
usernameReg: 请输入账号
passwordReg: 请输入密码
verifyCodeReg: 请输入验证码
verifyCodeCorrectReg: 请输入正确的验证码
verifyCodeSixReg: 请输入6位数字验证码
phoneReg: 请输入手机号码
phoneCorrectReg: 请输入正确的手机号码格式
passwordRuleReg: 密码格式应为8-18位数字、字母、符号的任意两种组合
passwordSureReg: 请输入确认密码
passwordDifferentReg: 两次密码不一致!
passwordUpdateReg: 修改密码成功
pureUsername: 账号
purePassword: 密码
pureVerifyCode: 验证码
pureRemember: 天内免登录
pureRememberInfo: 勾选并登录后,规定天数内无需输入用户名和密码会自动登入系统
pureSure: 确认密码
pureForget: 忘记密码?
pureLogin: 登录
pureThirdLogin: 第三方登录
purePhoneLogin: 手机登录
pureQRCodeLogin: 二维码登录
pureRegister: 注册
pureWeChatLogin: 微信登录
pureAlipayLogin: 支付宝登录
pureQQLogin: QQ登录
pureWeiBoLogin: 微博登录
purePhone: 手机号码
pureSmsVerifyCode: 短信验证码
pureBack: 返回
pureTest: 模拟测试
pureTip: 扫码后点击"确认",即可完成登录
pureDefinite: 确定
pureLoginSuccess: 登录成功
pureLoginFail: 登录失败
pureRegisterSuccess: 注册成功
pureTickPrivacy: 请勾选隐私政策
pureReadAccept: 我已仔细阅读并接受
purePrivacyPolicy: 《隐私政策》
pureGetVerifyCode: 获取验证码
pureInfo: 秒后重新获取
pureUsernameReg: 请输入账号
purePassWordReg: 请输入密码
pureVerifyCodeReg: 请输入验证码
pureVerifyCodeCorrectReg: 请输入正确的验证码
pureVerifyCodeSixReg: 请输入6位数字验证码
purePhoneReg: 请输入手机号码
purePhoneCorrectReg: 请输入正确的手机号码格式
purePassWordRuleReg: 密码格式应为8-18位数字、字母、符号的任意两种组合
purePassWordSureReg: 请输入确认密码
purePassWordDifferentReg: 两次密码不一致!
purePassWordUpdateReg: 修改密码成功

View File

@ -12,7 +12,7 @@ const systemManagementRouter = {
path: "/system",
meta: {
icon: "ri:settings-3-line",
title: "menus.hssysManagement",
title: "menus.pureSysManagement",
rank: system
},
children: [
@ -21,7 +21,7 @@ const systemManagementRouter = {
name: "SystemUser",
meta: {
icon: "ri:admin-line",
title: "menus.hsUser",
title: "menus.pureUser",
roles: ["admin"]
}
},
@ -30,7 +30,7 @@ const systemManagementRouter = {
name: "SystemRole",
meta: {
icon: "ri:admin-fill",
title: "menus.hsRole",
title: "menus.pureRole",
roles: ["admin"]
}
},
@ -39,7 +39,7 @@ const systemManagementRouter = {
name: "SystemMenu",
meta: {
icon: "ep:menu",
title: "menus.hsSystemMenu",
title: "menus.pureSystemMenu",
roles: ["admin"]
}
},
@ -48,7 +48,7 @@ const systemManagementRouter = {
name: "SystemDept",
meta: {
icon: "ri:git-branch-line",
title: "menus.hsDept",
title: "menus.pureDept",
roles: ["admin"]
}
}
@ -59,7 +59,7 @@ const systemMonitorRouter = {
path: "/monitor",
meta: {
icon: "ep:monitor",
title: "menus.hssysMonitor",
title: "menus.pureSysMonitor",
rank: monitor
},
children: [
@ -69,7 +69,7 @@ const systemMonitorRouter = {
name: "OnlineUser",
meta: {
icon: "ri:user-voice-line",
title: "menus.hsOnlineUser",
title: "menus.pureOnlineUser",
roles: ["admin"]
}
},
@ -79,7 +79,7 @@ const systemMonitorRouter = {
name: "LoginLog",
meta: {
icon: "ri:window-line",
title: "menus.hsLoginLog",
title: "menus.pureLoginLog",
roles: ["admin"]
}
},
@ -89,7 +89,7 @@ const systemMonitorRouter = {
name: "OperationLog",
meta: {
icon: "ri:history-fill",
title: "menus.hsOperationLog",
title: "menus.pureOperationLog",
roles: ["admin"]
}
},
@ -99,7 +99,7 @@ const systemMonitorRouter = {
name: "SystemLog",
meta: {
icon: "ri:file-search-line",
title: "menus.hsSystemLog",
title: "menus.pureSystemLog",
roles: ["admin"]
}
}
@ -109,7 +109,7 @@ const systemMonitorRouter = {
const permissionRouter = {
path: "/permission",
meta: {
title: "menus.permission",
title: "menus.purePermission",
icon: "ep:lollipop",
rank: permission
},
@ -118,22 +118,39 @@ const permissionRouter = {
path: "/permission/page/index",
name: "PermissionPage",
meta: {
title: "menus.permissionPage",
title: "menus.purePermissionPage",
roles: ["admin", "common"]
}
},
{
path: "/permission/button/index",
name: "PermissionButton",
path: "/permission/button",
meta: {
title: "menus.permissionButton",
roles: ["admin", "common"],
auths: [
"permission:btn:add",
"permission:btn:edit",
"permission:btn:delete"
]
}
title: "menus.purePermissionButton",
roles: ["admin", "common"]
},
children: [
{
path: "/permission/button/router",
component: "permission/button/index",
name: "PermissionButtonRouter",
meta: {
title: "menus.purePermissionButtonRouter",
auths: [
"permission:btn:add",
"permission:btn:edit",
"permission:btn:delete"
]
}
},
{
path: "/permission/button/login",
component: "permission/button/perms",
name: "PermissionButtonLogin",
meta: {
title: "menus.purePermissionButtonLogin"
}
}
]
}
]
};
@ -142,45 +159,41 @@ const frameRouter = {
path: "/iframe",
meta: {
icon: "ri:links-fill",
title: "menus.hsExternalPage",
title: "menus.pureExternalPage",
rank: frame
},
children: [
{
path: "/iframe/external",
path: "/iframe/embedded",
meta: {
title: "menus.hsExternalDoc"
title: "menus.pureEmbeddedDoc"
},
children: [
{
path: "/external",
name: "https://yiming_chang.gitee.io/pure-admin-doc",
path: "/iframe/colorhunt",
name: "FrameColorHunt",
meta: {
title: "menus.externalLink",
title: "menus.pureColorHuntDoc",
frameSrc: "https://colorhunt.co/",
keepAlive: true,
roles: ["admin", "common"]
}
},
{
path: "/pureutilsLink",
name: "https://pure-admin-utils.netlify.app/",
path: "/iframe/uigradients",
name: "FrameUiGradients",
meta: {
title: "menus.pureutilsLink",
title: "menus.pureUiGradients",
frameSrc: "https://uigradients.com/",
keepAlive: true,
roles: ["admin", "common"]
}
}
]
},
{
path: "/iframe/embedded",
meta: {
title: "menus.hsEmbeddedDoc"
},
children: [
},
{
path: "/iframe/ep",
name: "FrameEp",
meta: {
title: "menus.hsEpDocument",
title: "menus.pureEpDoc",
frameSrc: "https://element-plus.org/zh-CN/",
keepAlive: true,
roles: ["admin", "common"]
@ -190,7 +203,7 @@ const frameRouter = {
path: "/iframe/tailwindcss",
name: "FrameTailwindcss",
meta: {
title: "menus.hsTailwindcssDocument",
title: "menus.pureTailwindcssDoc",
frameSrc: "https://tailwindcss.com/docs/installation",
keepAlive: true,
roles: ["admin", "common"]
@ -200,7 +213,7 @@ const frameRouter = {
path: "/iframe/vue3",
name: "FrameVue",
meta: {
title: "menus.hsVueDocument",
title: "menus.pureVueDoc",
frameSrc: "https://cn.vuejs.org/",
keepAlive: true,
roles: ["admin", "common"]
@ -210,7 +223,7 @@ const frameRouter = {
path: "/iframe/vite",
name: "FrameVite",
meta: {
title: "menus.hsViteDocument",
title: "menus.pureViteDoc",
frameSrc: "https://cn.vitejs.dev/",
keepAlive: true,
roles: ["admin", "common"]
@ -220,7 +233,7 @@ const frameRouter = {
path: "/iframe/pinia",
name: "FramePinia",
meta: {
title: "menus.hsPiniaDocument",
title: "menus.purePiniaDoc",
frameSrc: "https://pinia.vuejs.org/zh/index.html",
keepAlive: true,
roles: ["admin", "common"]
@ -230,13 +243,37 @@ const frameRouter = {
path: "/iframe/vue-router",
name: "FrameRouter",
meta: {
title: "menus.hsRouterDocument",
title: "menus.pureRouterDoc",
frameSrc: "https://router.vuejs.org/zh/",
keepAlive: true,
roles: ["admin", "common"]
}
}
]
},
{
path: "/iframe/external",
meta: {
title: "menus.pureExternalDoc"
},
children: [
{
path: "/external",
name: "https://pure-admin.cn/",
meta: {
title: "menus.pureExternalLink",
roles: ["admin", "common"]
}
},
{
path: "/pureUtilsLink",
name: "https://pure-admin-utils.netlify.app/",
meta: {
title: "menus.pureUtilsLink",
roles: ["admin", "common"]
}
}
]
}
]
};
@ -245,7 +282,7 @@ const tabsRouter = {
path: "/tabs",
meta: {
icon: "ri:bookmark-2-line",
title: "menus.hstabs",
title: "menus.pureTabs",
rank: tabs
},
children: [
@ -253,7 +290,7 @@ const tabsRouter = {
path: "/tabs/index",
name: "Tabs",
meta: {
title: "menus.hstabs",
title: "menus.pureTabs",
roles: ["admin", "common"]
}
},

View File

@ -10,9 +10,13 @@ export default defineFakeRoute([
return {
success: true,
data: {
avatar: "https://avatars.githubusercontent.com/u/44761321",
username: "admin",
nickname: "小铭",
// 一个用户可能有多个角色
roles: ["admin"],
// 按钮级别权限
permissions: ["*:*:*"],
accessToken: "eyJhbGciOiJIUzUxMiJ9.admin",
refreshToken: "eyJhbGciOiJIUzUxMiJ9.adminRefresh",
expires: "2030/10/30 00:00:00"
@ -22,9 +26,11 @@ export default defineFakeRoute([
return {
success: true,
data: {
avatar: "https://avatars.githubusercontent.com/u/52823142",
username: "common",
// 一个用户可能有多个角色
nickname: "小林",
roles: ["common"],
permissions: ["permission:btn:add", "permission:btn:edit"],
accessToken: "eyJhbGciOiJIUzUxMiJ9.common",
refreshToken: "eyJhbGciOiJIUzUxMiJ9.commonRefresh",
expires: "2030/10/30 00:00:00"

59
mock/mine.ts Normal file
View File

@ -0,0 +1,59 @@
import { defineFakeRoute } from "vite-plugin-fake-server/client";
import { faker } from "@faker-js/faker/locale/zh_CN";
export default defineFakeRoute([
// 账户设置-个人信息
{
url: "/mine",
method: "get",
response: () => {
return {
success: true,
data: {
avatar: "https://avatars.githubusercontent.com/u/44761321",
username: "admin",
nickname: "小铭",
email: "pureadmin@163.com",
phone: "15888886789",
description: "一个热爱开源的前端工程师"
}
};
}
},
// 账户设置-个人安全日志
{
url: "/mine-logs",
method: "get",
response: () => {
const list = [
{
id: 1,
ip: faker.internet.ipv4(),
address: "中国河南省信阳市",
system: "macOS",
browser: "Chrome",
summary: "账户登录", // 详情
operatingTime: new Date() // 时间
},
{
id: 2,
ip: faker.internet.ipv4(),
address: "中国广东省深圳市",
system: "Windows",
browser: "Firefox",
summary: "绑定了手机号码",
operatingTime: new Date().setDate(new Date().getDate() - 1)
}
];
return {
success: true,
data: {
list,
total: list.length, // 总条目数
pageSize: 10, // 每页显示条目个数
currentPage: 1 // 当前页数
}
};
}
}
]);

View File

@ -9,9 +9,9 @@ export default defineFakeRoute([
response: ({ body }) => {
let list = [
{
username: "admin",
nickname: "admin",
avatar: "https://avatars.githubusercontent.com/u/44761321",
username: "admin",
nickname: "小铭",
phone: "15888886789",
email: faker.internet.email(),
sex: 0,
@ -27,9 +27,9 @@ export default defineFakeRoute([
createTime: 1605456000000
},
{
username: "common",
nickname: "common",
avatar: "https://avatars.githubusercontent.com/u/52823142",
username: "common",
nickname: "小林",
phone: "18288882345",
email: faker.internet.email(),
sex: 1,
@ -153,86 +153,86 @@ export default defineFakeRoute([
parentId: 0,
id: 100,
menuType: 0, // 菜单类型0代表菜单、1代表iframe、2代表外链、3代表按钮
title: "menus.hsExternalPage"
title: "menus.pureExternalPage"
},
{
parentId: 100,
id: 101,
menuType: 0,
title: "menus.hsExternalDoc"
title: "menus.pureExternalDoc"
},
{
parentId: 101,
id: 102,
menuType: 2,
title: "menus.externalLink"
title: "menus.pureExternalLink"
},
{
parentId: 101,
id: 103,
menuType: 2,
title: "menus.pureutilsLink"
title: "menus.pureUtilsLink"
},
{
parentId: 100,
id: 104,
menuType: 1,
title: "menus.hsEmbeddedDoc"
title: "menus.pureEmbeddedDoc"
},
{
parentId: 104,
id: 105,
menuType: 1,
title: "menus.hsEpDocument"
title: "menus.pureEpDoc"
},
{
parentId: 104,
id: 106,
menuType: 1,
title: "menus.hsTailwindcssDocument"
title: "menus.pureTailwindcssDoc"
},
{
parentId: 104,
id: 107,
menuType: 1,
title: "menus.hsVueDocument"
title: "menus.pureVueDoc"
},
{
parentId: 104,
id: 108,
menuType: 1,
title: "menus.hsViteDocument"
title: "menus.pureViteDoc"
},
{
parentId: 104,
id: 109,
menuType: 1,
title: "menus.hsPiniaDocument"
title: "menus.purePiniaDoc"
},
{
parentId: 104,
id: 110,
menuType: 1,
title: "menus.hsRouterDocument"
title: "menus.pureRouterDoc"
},
// 权限管理
{
parentId: 0,
id: 200,
menuType: 0,
title: "menus.permission"
title: "menus.purePermission"
},
{
parentId: 200,
id: 201,
menuType: 0,
title: "menus.permissionPage"
title: "menus.purePermissionPage"
},
{
parentId: 200,
id: 202,
menuType: 0,
title: "menus.permissionButton"
title: "menus.purePermissionButton"
},
{
parentId: 202,
@ -257,75 +257,75 @@ export default defineFakeRoute([
parentId: 0,
id: 300,
menuType: 0,
title: "menus.hssysManagement"
title: "menus.pureSysManagement"
},
{
parentId: 300,
id: 301,
menuType: 0,
title: "menus.hsUser"
title: "menus.pureUser"
},
{
parentId: 300,
id: 302,
menuType: 0,
title: "menus.hsRole"
title: "menus.pureRole"
},
{
parentId: 300,
id: 303,
menuType: 0,
title: "menus.hsSystemMenu"
title: "menus.pureSystemMenu"
},
{
parentId: 300,
id: 304,
menuType: 0,
title: "menus.hsDept"
title: "menus.pureDept"
},
// 系统监控
{
parentId: 0,
id: 400,
menuType: 0,
title: "menus.hssysMonitor"
title: "menus.pureSysMonitor"
},
{
parentId: 400,
id: 401,
menuType: 0,
title: "menus.hsOnlineUser"
title: "menus.pureOnlineUser"
},
{
parentId: 400,
id: 402,
menuType: 0,
title: "menus.hsLoginLog"
title: "menus.pureLoginLog"
},
{
parentId: 400,
id: 403,
menuType: 0,
title: "menus.hsOperationLog"
title: "menus.pureOperationLog"
},
{
parentId: 400,
id: 404,
menuType: 0,
title: "menus.hsSystemLog"
title: "menus.pureSystemLog"
},
// 标签页操作
{
parentId: 0,
id: 500,
menuType: 0,
title: "menus.hstabs"
title: "menus.pureTabs"
},
{
parentId: 500,
id: 501,
menuType: 0,
title: "menus.hstabs"
title: "menus.pureTabs"
},
{
parentId: 500,
@ -381,7 +381,7 @@ export default defineFakeRoute([
parentId: 0,
id: 100,
menuType: 0, // 菜单类型0代表菜单、1代表iframe、2代表外链、3代表按钮
title: "menus.hsExternalPage",
title: "menus.pureExternalPage",
name: "PureIframe",
path: "/iframe",
component: "",
@ -397,6 +397,7 @@ export default defineFakeRoute([
frameLoading: true,
keepAlive: false,
hiddenTag: false,
fixedTag: false,
showLink: true,
showParent: false
},
@ -404,7 +405,7 @@ export default defineFakeRoute([
parentId: 100,
id: 101,
menuType: 0,
title: "menus.hsExternalDoc",
title: "menus.pureExternalDoc",
name: "PureIframeExternal",
path: "/iframe/external",
component: "",
@ -420,6 +421,7 @@ export default defineFakeRoute([
frameLoading: true,
keepAlive: false,
hiddenTag: false,
fixedTag: false,
showLink: true,
showParent: false
},
@ -427,8 +429,8 @@ export default defineFakeRoute([
parentId: 101,
id: 102,
menuType: 2,
title: "menus.externalLink",
name: "https://yiming_chang.gitee.io/pure-admin-doc",
title: "menus.pureExternalLink",
name: "https://pure-admin.cn/",
path: "/external",
component: "",
rank: null,
@ -443,6 +445,7 @@ export default defineFakeRoute([
frameLoading: true,
keepAlive: false,
hiddenTag: false,
fixedTag: false,
showLink: true,
showParent: false
},
@ -450,9 +453,9 @@ export default defineFakeRoute([
parentId: 101,
id: 103,
menuType: 2,
title: "menus.pureutilsLink",
title: "menus.pureUtilsLink",
name: "https://pure-admin-utils.netlify.app/",
path: "/pureutilsLink",
path: "/pureUtilsLink",
component: "",
rank: null,
redirect: "",
@ -466,6 +469,7 @@ export default defineFakeRoute([
frameLoading: true,
keepAlive: false,
hiddenTag: false,
fixedTag: false,
showLink: true,
showParent: false
},
@ -473,7 +477,7 @@ export default defineFakeRoute([
parentId: 100,
id: 104,
menuType: 1,
title: "menus.hsEmbeddedDoc",
title: "menus.pureEmbeddedDoc",
name: "PureIframeEmbedded",
path: "/iframe/embedded",
component: "",
@ -489,6 +493,7 @@ export default defineFakeRoute([
frameLoading: true,
keepAlive: false,
hiddenTag: false,
fixedTag: false,
showLink: true,
showParent: false
},
@ -496,7 +501,7 @@ export default defineFakeRoute([
parentId: 104,
id: 105,
menuType: 1,
title: "menus.hsEpDocument",
title: "menus.pureEpDoc",
name: "FrameEp",
path: "/iframe/ep",
component: "",
@ -512,6 +517,7 @@ export default defineFakeRoute([
frameLoading: true,
keepAlive: true,
hiddenTag: false,
fixedTag: false,
showLink: true,
showParent: false
},
@ -519,7 +525,7 @@ export default defineFakeRoute([
parentId: 104,
id: 106,
menuType: 1,
title: "menus.hsTailwindcssDocument",
title: "menus.pureTailwindcssDoc",
name: "FrameTailwindcss",
path: "/iframe/tailwindcss",
component: "",
@ -535,6 +541,7 @@ export default defineFakeRoute([
frameLoading: true,
keepAlive: true,
hiddenTag: false,
fixedTag: false,
showLink: true,
showParent: false
},
@ -542,7 +549,7 @@ export default defineFakeRoute([
parentId: 104,
id: 107,
menuType: 1,
title: "menus.hsVueDocument",
title: "menus.pureVueDoc",
name: "FrameVue",
path: "/iframe/vue3",
component: "",
@ -558,6 +565,7 @@ export default defineFakeRoute([
frameLoading: true,
keepAlive: true,
hiddenTag: false,
fixedTag: false,
showLink: true,
showParent: false
},
@ -565,7 +573,7 @@ export default defineFakeRoute([
parentId: 104,
id: 108,
menuType: 1,
title: "menus.hsViteDocument",
title: "menus.pureViteDoc",
name: "FrameVite",
path: "/iframe/vite",
component: "",
@ -581,6 +589,7 @@ export default defineFakeRoute([
frameLoading: true,
keepAlive: true,
hiddenTag: false,
fixedTag: false,
showLink: true,
showParent: false
},
@ -588,7 +597,7 @@ export default defineFakeRoute([
parentId: 104,
id: 109,
menuType: 1,
title: "menus.hsPiniaDocument",
title: "menus.purePiniaDoc",
name: "FramePinia",
path: "/iframe/pinia",
component: "",
@ -604,6 +613,7 @@ export default defineFakeRoute([
frameLoading: true,
keepAlive: true,
hiddenTag: false,
fixedTag: false,
showLink: true,
showParent: false
},
@ -611,7 +621,7 @@ export default defineFakeRoute([
parentId: 104,
id: 110,
menuType: 1,
title: "menus.hsRouterDocument",
title: "menus.pureRouterDoc",
name: "FrameRouter",
path: "/iframe/vue-router",
component: "",
@ -627,6 +637,7 @@ export default defineFakeRoute([
frameLoading: true,
keepAlive: true,
hiddenTag: false,
fixedTag: false,
showLink: true,
showParent: false
},
@ -635,7 +646,7 @@ export default defineFakeRoute([
parentId: 0,
id: 200,
menuType: 0,
title: "menus.permission",
title: "menus.purePermission",
name: "PurePermission",
path: "/permission",
component: "",
@ -651,6 +662,7 @@ export default defineFakeRoute([
frameLoading: true,
keepAlive: false,
hiddenTag: false,
fixedTag: false,
showLink: true,
showParent: false
},
@ -658,7 +670,7 @@ export default defineFakeRoute([
parentId: 200,
id: 201,
menuType: 0,
title: "menus.permissionPage",
title: "menus.purePermissionPage",
name: "PermissionPage",
path: "/permission/page/index",
component: "",
@ -674,6 +686,7 @@ export default defineFakeRoute([
frameLoading: true,
keepAlive: false,
hiddenTag: false,
fixedTag: false,
showLink: true,
showParent: false
},
@ -681,9 +694,9 @@ export default defineFakeRoute([
parentId: 200,
id: 202,
menuType: 0,
title: "menus.permissionButton",
title: "menus.purePermissionButton",
name: "PermissionButton",
path: "/permission/button/index",
path: "/permission/button",
component: "",
rank: null,
redirect: "",
@ -697,12 +710,37 @@ export default defineFakeRoute([
frameLoading: true,
keepAlive: false,
hiddenTag: false,
fixedTag: false,
showLink: true,
showParent: false
},
{
parentId: 202,
id: 203,
menuType: 0,
title: "menus.purePermissionButtonRouter",
name: "PermissionButtonRouter",
path: "/permission/button/router",
component: "permission/button/index",
rank: null,
redirect: "",
icon: "",
extraIcon: "",
enterTransition: "",
leaveTransition: "",
activePath: "",
auths: "",
frameSrc: "",
frameLoading: true,
keepAlive: false,
hiddenTag: false,
fixedTag: false,
showLink: true,
showParent: false
},
{
parentId: 203,
id: 210,
menuType: 3,
title: "添加",
name: "",
@ -720,12 +758,13 @@ export default defineFakeRoute([
frameLoading: true,
keepAlive: false,
hiddenTag: false,
fixedTag: false,
showLink: true,
showParent: false
},
{
parentId: 202,
id: 204,
parentId: 203,
id: 211,
menuType: 3,
title: "修改",
name: "",
@ -743,12 +782,13 @@ export default defineFakeRoute([
frameLoading: true,
keepAlive: false,
hiddenTag: false,
fixedTag: false,
showLink: true,
showParent: false
},
{
parentId: 202,
id: 205,
parentId: 203,
id: 212,
menuType: 3,
title: "删除",
name: "",
@ -766,6 +806,103 @@ export default defineFakeRoute([
frameLoading: true,
keepAlive: false,
hiddenTag: false,
fixedTag: false,
showLink: true,
showParent: false
},
{
parentId: 202,
id: 204,
menuType: 0,
title: "menus.purePermissionButtonLogin",
name: "PermissionButtonLogin",
path: "/permission/button/login",
component: "permission/button/perms",
rank: null,
redirect: "",
icon: "",
extraIcon: "",
enterTransition: "",
leaveTransition: "",
activePath: "",
auths: "",
frameSrc: "",
frameLoading: true,
keepAlive: false,
hiddenTag: false,
fixedTag: false,
showLink: true,
showParent: false
},
{
parentId: 204,
id: 220,
menuType: 3,
title: "添加",
name: "",
path: "",
component: "",
rank: null,
redirect: "",
icon: "",
extraIcon: "",
enterTransition: "",
leaveTransition: "",
activePath: "",
auths: "permission:btn:add",
frameSrc: "",
frameLoading: true,
keepAlive: false,
hiddenTag: false,
fixedTag: false,
showLink: true,
showParent: false
},
{
parentId: 204,
id: 221,
menuType: 3,
title: "修改",
name: "",
path: "",
component: "",
rank: null,
redirect: "",
icon: "",
extraIcon: "",
enterTransition: "",
leaveTransition: "",
activePath: "",
auths: "permission:btn:edit",
frameSrc: "",
frameLoading: true,
keepAlive: false,
hiddenTag: false,
fixedTag: false,
showLink: true,
showParent: false
},
{
parentId: 204,
id: 222,
menuType: 3,
title: "删除",
name: "",
path: "",
component: "",
rank: null,
redirect: "",
icon: "",
extraIcon: "",
enterTransition: "",
leaveTransition: "",
activePath: "",
auths: "permission:btn:delete",
frameSrc: "",
frameLoading: true,
keepAlive: false,
hiddenTag: false,
fixedTag: false,
showLink: true,
showParent: false
},
@ -774,7 +911,7 @@ export default defineFakeRoute([
parentId: 0,
id: 300,
menuType: 0,
title: "menus.hssysManagement",
title: "menus.pureSysManagement",
name: "PureSystem",
path: "/system",
component: "",
@ -790,6 +927,7 @@ export default defineFakeRoute([
frameLoading: true,
keepAlive: false,
hiddenTag: false,
fixedTag: false,
showLink: true,
showParent: false
},
@ -797,7 +935,7 @@ export default defineFakeRoute([
parentId: 300,
id: 301,
menuType: 0,
title: "menus.hsUser",
title: "menus.pureUser",
name: "SystemUser",
path: "/system/user/index",
component: "",
@ -813,6 +951,7 @@ export default defineFakeRoute([
frameLoading: true,
keepAlive: false,
hiddenTag: false,
fixedTag: false,
showLink: true,
showParent: false
},
@ -820,7 +959,7 @@ export default defineFakeRoute([
parentId: 300,
id: 302,
menuType: 0,
title: "menus.hsRole",
title: "menus.pureRole",
name: "SystemRole",
path: "/system/role/index",
component: "",
@ -836,6 +975,7 @@ export default defineFakeRoute([
frameLoading: true,
keepAlive: false,
hiddenTag: false,
fixedTag: false,
showLink: true,
showParent: false
},
@ -843,7 +983,7 @@ export default defineFakeRoute([
parentId: 300,
id: 303,
menuType: 0,
title: "menus.hsSystemMenu",
title: "menus.pureSystemMenu",
name: "SystemMenu",
path: "/system/menu/index",
component: "",
@ -859,6 +999,7 @@ export default defineFakeRoute([
frameLoading: true,
keepAlive: false,
hiddenTag: false,
fixedTag: false,
showLink: true,
showParent: false
},
@ -866,7 +1007,7 @@ export default defineFakeRoute([
parentId: 300,
id: 304,
menuType: 0,
title: "menus.hsDept",
title: "menus.pureDept",
name: "SystemDept",
path: "/system/dept/index",
component: "",
@ -882,6 +1023,7 @@ export default defineFakeRoute([
frameLoading: true,
keepAlive: false,
hiddenTag: false,
fixedTag: false,
showLink: true,
showParent: false
},
@ -890,7 +1032,7 @@ export default defineFakeRoute([
parentId: 0,
id: 400,
menuType: 0,
title: "menus.hssysMonitor",
title: "menus.pureSysMonitor",
name: "PureMonitor",
path: "/monitor",
component: "",
@ -906,6 +1048,7 @@ export default defineFakeRoute([
frameLoading: true,
keepAlive: false,
hiddenTag: false,
fixedTag: false,
showLink: true,
showParent: false
},
@ -913,7 +1056,7 @@ export default defineFakeRoute([
parentId: 400,
id: 401,
menuType: 0,
title: "menus.hsOnlineUser",
title: "menus.pureOnlineUser",
name: "OnlineUser",
path: "/monitor/online-user",
component: "monitor/online/index",
@ -929,6 +1072,7 @@ export default defineFakeRoute([
frameLoading: true,
keepAlive: false,
hiddenTag: false,
fixedTag: false,
showLink: true,
showParent: false
},
@ -936,7 +1080,7 @@ export default defineFakeRoute([
parentId: 400,
id: 402,
menuType: 0,
title: "menus.hsLoginLog",
title: "menus.pureLoginLog",
name: "LoginLog",
path: "/monitor/login-logs",
component: "monitor/logs/login/index",
@ -952,6 +1096,7 @@ export default defineFakeRoute([
frameLoading: true,
keepAlive: false,
hiddenTag: false,
fixedTag: false,
showLink: true,
showParent: false
},
@ -959,7 +1104,7 @@ export default defineFakeRoute([
parentId: 400,
id: 403,
menuType: 0,
title: "menus.hsOperationLog",
title: "menus.pureOperationLog",
name: "OperationLog",
path: "/monitor/operation-logs",
component: "monitor/logs/operation/index",
@ -975,6 +1120,7 @@ export default defineFakeRoute([
frameLoading: true,
keepAlive: false,
hiddenTag: false,
fixedTag: false,
showLink: true,
showParent: false
},
@ -982,7 +1128,7 @@ export default defineFakeRoute([
parentId: 400,
id: 404,
menuType: 0,
title: "menus.hsSystemLog",
title: "menus.pureSystemLog",
name: "SystemLog",
path: "/monitor/system-logs",
component: "monitor/logs/system/index",
@ -998,6 +1144,7 @@ export default defineFakeRoute([
frameLoading: true,
keepAlive: false,
hiddenTag: false,
fixedTag: false,
showLink: true,
showParent: false
},
@ -1006,7 +1153,7 @@ export default defineFakeRoute([
parentId: 0,
id: 500,
menuType: 0,
title: "menus.hstabs",
title: "menus.pureTabs",
name: "PureTabs",
path: "/tabs",
component: "",
@ -1022,6 +1169,7 @@ export default defineFakeRoute([
frameLoading: true,
keepAlive: false,
hiddenTag: false,
fixedTag: false,
showLink: true,
showParent: false
},
@ -1029,7 +1177,7 @@ export default defineFakeRoute([
parentId: 500,
id: 501,
menuType: 0,
title: "menus.hstabs",
title: "menus.pureTabs",
name: "Tabs",
path: "/tabs/index",
component: "",
@ -1045,6 +1193,7 @@ export default defineFakeRoute([
frameLoading: true,
keepAlive: false,
hiddenTag: false,
fixedTag: false,
showLink: true,
showParent: false
},
@ -1068,6 +1217,7 @@ export default defineFakeRoute([
frameLoading: true,
keepAlive: false,
hiddenTag: false,
fixedTag: false,
showLink: false,
showParent: false
},
@ -1091,6 +1241,7 @@ export default defineFakeRoute([
frameLoading: true,
keepAlive: false,
hiddenTag: false,
fixedTag: false,
showLink: false,
showParent: false
}
@ -1456,7 +1607,7 @@ export default defineFakeRoute([
parentId: 0,
id: 400,
menuType: 0,
title: "menus.hssysMonitor",
title: "menus.pureSysMonitor",
name: "PureMonitor",
path: "/monitor",
component: "",
@ -1472,6 +1623,7 @@ export default defineFakeRoute([
frameLoading: true,
keepAlive: false,
hiddenTag: false,
fixedTag: false,
showLink: true,
showParent: false
},
@ -1479,7 +1631,7 @@ export default defineFakeRoute([
parentId: 400,
id: 401,
menuType: 0,
title: "menus.hsOnlineUser",
title: "menus.pureOnlineUser",
name: "OnlineUser",
path: "/monitor/online-user",
component: "monitor/online/index",
@ -1495,6 +1647,7 @@ export default defineFakeRoute([
frameLoading: true,
keepAlive: false,
hiddenTag: false,
fixedTag: false,
showLink: true,
showParent: false
},
@ -1502,7 +1655,7 @@ export default defineFakeRoute([
parentId: 400,
id: 402,
menuType: 0,
title: "menus.hsLoginLog",
title: "menus.pureLoginLog",
name: "LoginLog",
path: "/monitor/login-logs",
component: "monitor/logs/login/index",
@ -1518,6 +1671,7 @@ export default defineFakeRoute([
frameLoading: true,
keepAlive: false,
hiddenTag: false,
fixedTag: false,
showLink: true,
showParent: false
},
@ -1525,7 +1679,7 @@ export default defineFakeRoute([
parentId: 400,
id: 403,
menuType: 0,
title: "menus.hsOperationLog",
title: "menus.pureOperationLog",
name: "OperationLog",
path: "/monitor/operation-logs",
component: "monitor/logs/operation/index",
@ -1541,6 +1695,7 @@ export default defineFakeRoute([
frameLoading: true,
keepAlive: false,
hiddenTag: false,
fixedTag: false,
showLink: true,
showParent: false
},
@ -1548,7 +1703,7 @@ export default defineFakeRoute([
parentId: 400,
id: 404,
menuType: 0,
title: "menus.hsSystemLog",
title: "menus.pureSystemLog",
name: "SystemLog",
path: "/monitor/system-logs",
component: "monitor/logs/system/index",
@ -1564,6 +1719,7 @@ export default defineFakeRoute([
frameLoading: true,
keepAlive: false,
hiddenTag: false,
fixedTag: false,
showLink: true,
showParent: false
}

View File

@ -1,6 +1,6 @@
{
"name": "vue-pure-admin",
"version": "5.2.0",
"version": "6.0.0",
"private": true,
"type": "module",
"scripts": {
@ -13,7 +13,6 @@
"preview:build": "pnpm build && vite preview",
"typecheck": "tsc --noEmit && vue-tsc --noEmit --skipLibCheck",
"svgo": "svgo -f . -r",
"cloc": "NODE_OPTIONS=--max-old-space-size=4096 cloc . --exclude-dir=node_modules --exclude-lang=YAML",
"clean:cache": "rimraf .eslintcache && rimraf pnpm-lock.yaml && rimraf node_modules && pnpm store prune && pnpm install",
"lint:eslint": "eslint --cache --max-warnings 0 \"{src,mock,build}/**/*.{vue,js,ts,tsx}\" --fix",
"lint:prettier": "prettier --write \"src/**/*.{js,ts,json,tsx,css,scss,vue,html,md}\"",
@ -49,140 +48,161 @@
},
"dependencies": {
"@amap/amap-jsapi-loader": "^1.0.1",
"@howdyjs/mouse-menu": "^2.1.3",
"@infectoone/vue-ganttastic": "^2.3.1",
"@logicflow/core": "^1.2.23",
"@logicflow/extension": "^1.2.23",
"@howdyjs/mouse-menu": "^2.1.7",
"@infectoone/vue-ganttastic": "^2.3.2",
"@logicflow/core": "^1.2.28",
"@logicflow/extension": "^1.2.28",
"@pureadmin/descriptions": "^1.2.1",
"@pureadmin/table": "^3.1.2",
"@pureadmin/utils": "^2.4.7",
"@vue-flow/background": "^1.3.0",
"@vue-flow/core": "^1.33.4",
"@vueuse/core": "^10.9.0",
"@vueuse/motion": "^2.1.0",
"@pureadmin/table": "^3.2.1",
"@pureadmin/utils": "^2.6.1",
"@vue-flow/background": "^1.3.2",
"@vue-flow/core": "^1.44.0",
"@vueuse/core": "^13.3.0",
"@vueuse/motion": "^3.0.3",
"@wangeditor/editor": "^5.1.23",
"@wangeditor/editor-for-vue": "^5.1.12",
"@zxcvbn-ts/core": "^3.0.4",
"animate.css": "^4.1.1",
"axios": "^1.6.8",
"axios": "^1.9.0",
"china-area-data": "^5.0.1",
"cropperjs": "^1.6.1",
"dayjs": "^1.11.10",
"echarts": "^5.5.0",
"el-table-infinite-scroll": "^3.0.3",
"element-plus": "^2.6.1",
"codemirror": "^5.65.19",
"codemirror-editor-vue3": "^2.8.0",
"cropperjs": "^1.6.2",
"dayjs": "^1.11.13",
"deep-chat": "^2.2.1",
"echarts": "^5.6.0",
"el-table-infinite-scroll": "^3.0.6",
"element-plus": "^2.9.11",
"highlight.js": "^11.11.1",
"intro.js": "^7.2.0",
"js-cookie": "^3.0.5",
"jsbarcode": "^3.11.6",
"localforage": "^1.10.0",
"mint-filter": "^4.0.3",
"mitt": "^3.0.1",
"mqtt": "4.3.7",
"nprogress": "^0.2.0",
"path": "^0.12.7",
"pinia": "^2.1.7",
"pinyin-pro": "^3.19.6",
"plus-pro-components": "^0.0.5",
"qrcode": "^1.5.3",
"qs": "^6.12.0",
"path-browserify": "^1.0.1",
"pinia": "^3.0.2",
"pinyin-pro": "^3.26.0",
"plus-pro-components": "^0.1.23",
"qrcode": "^1.5.4",
"qs": "^6.14.0",
"responsive-storage": "^2.2.0",
"sortablejs": "^1.15.2",
"swiper": "^11.0.7",
"typeit": "^8.8.3",
"sortablejs": "^1.15.6",
"swiper": "^11.2.8",
"typeit": "^8.8.7",
"v-contextmenu": "^3.2.0",
"v3-infinite-loading": "^1.3.1",
"version-rocket": "^1.7.1",
"vue": "^3.4.21",
"vue-i18n": "^9.10.2",
"v3-infinite-loading": "^1.3.2",
"vditor": "^3.11.1",
"version-rocket": "^1.7.4",
"vue": "^3.5.16",
"vue-i18n": "^11.1.5",
"vue-json-pretty": "^2.4.0",
"vue-pdf-embed": "^2.0.3",
"vue-router": "^4.3.0",
"vue-tippy": "^6.4.1",
"vue-types": "^5.1.1",
"vue-pdf-embed": "^2.1.2",
"vue-router": "^4.5.1",
"vue-tippy": "^6.7.1",
"vue-types": "^6.0.0",
"vue-virtual-scroller": "2.0.0-beta.8",
"vue-waterfall-plugin-next": "^2.4.3",
"vue3-danmaku": "^1.6.0",
"vue-waterfall-plugin-next": "^2.6.5",
"vue3-danmaku": "^1.6.1",
"vue3-puzzle-vcode": "^1.1.7",
"vuedraggable": "^4.1.0",
"vxe-table": "^4.5.21",
"wavesurfer.js": "^7.7.5",
"xgplayer": "^3.0.14",
"vxe-table": "4.6.25",
"wavesurfer.js": "^7.9.5",
"xgplayer": "^3.0.22",
"xlsx": "^0.18.5"
},
"devDependencies": {
"@commitlint/cli": "^19.2.1",
"@commitlint/config-conventional": "^19.1.0",
"@commitlint/types": "^19.0.3",
"@eslint/js": "^8.57.0",
"@faker-js/faker": "^8.4.1",
"@iconify-icons/ep": "^1.2.12",
"@iconify-icons/ri": "^1.2.10",
"@iconify/vue": "^4.1.1",
"@intlify/unplugin-vue-i18n": "^2.0.0",
"@pureadmin/theme": "^3.2.0",
"@commitlint/cli": "^19.8.1",
"@commitlint/config-conventional": "^19.8.1",
"@commitlint/types": "^19.8.1",
"@eslint/js": "^9.28.0",
"@faker-js/faker": "^9.8.0",
"@iconify/json": "^2.2.343",
"@iconify/vue": "4.2.0",
"@intlify/unplugin-vue-i18n": "^6.0.8",
"@tailwindcss/vite": "^4.1.8",
"@types/codemirror": "^5.60.16",
"@types/dagre": "^0.7.52",
"@types/gradient-string": "^1.1.5",
"@types/intro.js": "^5.1.5",
"@types/js-cookie": "^3.0.6",
"@types/node": "^20.11.30",
"@types/node": "^20.17.57",
"@types/nprogress": "^0.2.3",
"@types/path-browserify": "^1.0.3",
"@types/qrcode": "^1.5.5",
"@types/qs": "^6.9.14",
"@types/qs": "^6.14.0",
"@types/sortablejs": "^1.15.8",
"@typescript-eslint/eslint-plugin": "^7.3.1",
"@typescript-eslint/parser": "^7.3.1",
"@vitejs/plugin-vue": "^5.0.4",
"@vitejs/plugin-vue-jsx": "^3.1.0",
"autoprefixer": "^10.4.19",
"boxen": "^7.1.1",
"cloc": "^2.11.0",
"cssnano": "^6.1.1",
"@vitejs/plugin-vue": "^5.2.4",
"@vitejs/plugin-vue-jsx": "^4.2.0",
"boxen": "^8.0.1",
"code-inspector-plugin": "^0.20.12",
"cssnano": "^7.0.7",
"dagre": "^0.8.5",
"eslint": "^8.57.0",
"eslint-config-prettier": "^9.1.0",
"eslint-define-config": "^2.1.0",
"eslint-plugin-prettier": "^5.1.3",
"eslint-plugin-vue": "^9.23.0",
"gradient-string": "^2.0.2",
"husky": "^9.0.11",
"lint-staged": "^15.2.2",
"postcss": "^8.4.38",
"postcss-html": "^1.6.0",
"postcss-import": "^16.1.0",
"eslint": "^9.28.0",
"eslint-config-prettier": "^10.1.5",
"eslint-plugin-prettier": "^5.4.1",
"eslint-plugin-vue": "^10.1.0",
"gradient-string": "^3.0.0",
"husky": "^9.1.7",
"lint-staged": "^15.5.2",
"postcss": "^8.5.4",
"postcss-html": "^1.8.0",
"postcss-load-config": "^6.0.1",
"postcss-scss": "^4.0.9",
"prettier": "^3.2.5",
"rimraf": "^5.0.5",
"rollup-plugin-visualizer": "^5.12.0",
"sass": "^1.72.0",
"stylelint": "^16.2.1",
"stylelint-config-recess-order": "^5.0.0",
"stylelint-config-recommended-vue": "^1.5.0",
"stylelint-config-standard-scss": "^13.0.0",
"stylelint-prettier": "^5.0.0",
"svgo": "^3.2.0",
"tailwindcss": "^3.4.1",
"typescript": "^5.4.3",
"vite": "^5.2.2",
"vite-plugin-cdn-import": "^0.3.5",
"prettier": "^3.5.3",
"rimraf": "^6.0.1",
"rollup-plugin-visualizer": "^5.14.0",
"sass": "^1.89.1",
"stylelint": "^16.20.0",
"stylelint-config-recess-order": "^6.0.0",
"stylelint-config-recommended-vue": "^1.6.0",
"stylelint-config-standard-scss": "^14.0.0",
"stylelint-prettier": "^5.0.3",
"svgo": "^3.3.2",
"tailwindcss": "^4.1.8",
"typescript": "^5.8.3",
"typescript-eslint": "^8.33.0",
"unplugin-icons": "^22.1.0",
"vite": "^6.3.5",
"vite-plugin-cdn-import": "^1.0.1",
"vite-plugin-compression": "^0.5.1",
"vite-plugin-fake-server": "^2.1.1",
"vite-plugin-fake-server": "^2.2.0",
"vite-plugin-remove-console": "^2.2.0",
"vite-plugin-router-warn": "^1.0.0",
"vite-svg-loader": "^5.1.0",
"vue-eslint-parser": "^9.4.2",
"vue-tsc": "^1.8.27"
"vue-eslint-parser": "^10.1.3",
"vue-tsc": "^2.2.10"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0",
"pnpm": ">=8.6.10"
"node": "^18.18.0 || ^20.9.0 || >=22.0.0",
"pnpm": ">=9"
},
"packageManager": "pnpm@8.6.10",
"pnpm": {
"allowedDeprecatedVersions": {
"are-we-there-yet": "*",
"sourcemap-codec": "*",
"lodash.isequal": "*",
"domexception": "*",
"w3c-hr-time": "*",
"inflight": "*",
"npmlog": "*",
"rimraf": "*",
"stable": "*",
"abab": "*"
}
"gauge": "*",
"abab": "*",
"glob": "*"
},
"onlyBuiltDependencies": [
"@parcel/watcher",
"core-js",
"es5-ext",
"esbuild",
"typeit",
"vue-demi"
],
"ignoredBuiltDependencies": [
"@tailwindcss/oxide"
]
}
}

15515
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@ -3,10 +3,6 @@
/** @type {import('postcss-load-config').Config} */
export default {
plugins: {
"postcss-import": {},
"tailwindcss/nesting": {},
tailwindcss: {},
autoprefixer: {},
...(process.env.NODE_ENV === "production" ? { cssnano: {} } : {})
}
};

View File

@ -1,5 +1,5 @@
{
"Version": "5.2.0",
"Version": "6.0.0",
"Title": "PureAdmin",
"FixedHeader": true,
"HiddenSideBar": false,

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 80 KiB

View File

@ -2,6 +2,7 @@
<el-config-provider :locale="currentLocale">
<router-view />
<ReDialog />
<ReDrawer />
</el-config-provider>
</template>
@ -10,16 +11,18 @@ import { defineComponent } from "vue";
import { checkVersion } from "version-rocket";
import { ElConfigProvider } from "element-plus";
import { ReDialog } from "@/components/ReDialog";
import en from "element-plus/dist/locale/en.mjs";
import zhCn from "element-plus/dist/locale/zh-cn.mjs";
import plusEn from "plus-pro-components/locale/en.mjs";
import plusZhCn from "plus-pro-components/locale/zh-cn.mjs";
import { ReDrawer } from "@/components/ReDrawer";
import en from "element-plus/es/locale/lang/en";
import zhCn from "element-plus/es/locale/lang/zh-cn";
import plusEn from "plus-pro-components/es/locale/lang/en";
import plusZhCn from "plus-pro-components/es/locale/lang/zh-cn";
export default defineComponent({
name: "app",
components: {
[ElConfigProvider.name]: ElConfigProvider,
ReDialog
ReDialog,
ReDrawer
},
computed: {
currentLocale() {

View File

@ -3,10 +3,16 @@ import { http } from "@/utils/http";
export type UserResult = {
success: boolean;
data: {
/** 头像 */
avatar: string;
/** 用户名 */
username: string;
/** 当前登陆用户的角色 */
/** 昵称 */
nickname: string;
/** 当前登录用户的角色 */
roles: Array<string>;
/** 按钮级别权限 */
permissions: Array<string>;
/** `token` */
accessToken: string;
/** 用于调用刷新`accessToken`的接口时所需的`token` */
@ -28,12 +34,56 @@ export type RefreshTokenResult = {
};
};
export type UserInfo = {
/** 头像 */
avatar: string;
/** 用户名 */
username: string;
/** 昵称 */
nickname: string;
/** 邮箱 */
email: string;
/** 联系电话 */
phone: string;
/** 简介 */
description: string;
};
export type UserInfoResult = {
success: boolean;
data: UserInfo;
};
type ResultTable = {
success: boolean;
data?: {
/** 列表数据 */
list: Array<any>;
/** 总条目数 */
total?: number;
/** 每页显示条目个数 */
pageSize?: number;
/** 当前页数 */
currentPage?: number;
};
};
/** 登录 */
export const getLogin = (data?: object) => {
return http.request<UserResult>("post", "/login", { data });
};
/** 刷新token */
/** 刷新`token` */
export const refreshTokenApi = (data?: object) => {
return http.request<RefreshTokenResult>("post", "/refresh-token", { data });
};
/** 账户设置-个人信息 */
export const getMine = (data?: object) => {
return http.request<UserInfoResult>("get", "/mine", { data });
};
/** 账户设置-个人安全日志 */
export const getMineLogs = (data?: object) => {
return http.request<ResultTable>("get", "/mine-logs", { data });
};

View File

@ -28,8 +28,7 @@
c = document.createElement("div");
(c.innerHTML = e._iconfont_svg_string_2208059),
(c = c.getElementsByTagName("svg")[0]) &&
(c.setAttribute("aria-hidden", "true"),
(c.style.position = "absolute"),
((c.style.position = "absolute"),
(c.style.width = 0),
(c.style.height = 0),
(c.style.overflow = "hidden"),

View File

@ -1 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" aria-hidden="true" class="iconify iconify--ant-design" viewBox="0 0 1024 1024"><path fill="currentColor" d="M864 170h-60c-4.4 0-8 3.6-8 8v518H310v-73c0-6.7-7.8-10.5-13-6.3l-141.9 112a8 8 0 0 0 0 12.6l141.9 112c5.3 4.2 13 .4 13-6.3v-75h498c35.3 0 64-28.7 64-64V178c0-4.4-3.6-8-8-8"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" class="iconify iconify--ant-design" viewBox="0 0 1024 1024"><path fill="currentColor" d="M864 170h-60c-4.4 0-8 3.6-8 8v518H310v-73c0-6.7-7.8-10.5-13-6.3l-141.9 112a8 8 0 0 0 0 12.6l141.9 112c5.3 4.2 13 .4 13-6.3v-75h498c35.3 0 64-28.7 64-64V178c0-4.4-3.6-8-8-8"/></svg>

Before

Width:  |  Height:  |  Size: 351 B

After

Width:  |  Height:  |  Size: 332 B

View File

@ -1 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" aria-hidden="true" class="re-screen" color="#00000073" viewBox="0 0 16 16"><path fill="currentColor" d="M3.5 4H1V3h2V1h1v2.5zM13 3V1h-1v2.5l.5.5H15V3zm-1 9.5V15h1v-2h2v-1h-2.5zM1 12v1h2v2h1v-2.5l-.5-.5zm11-1.5-.5.5h-7l-.5-.5v-5l.5-.5h7l.5.5zM10 7H6v2h4z"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" class="re-screen" color="#00000073" viewBox="0 0 16 16"><path fill="currentColor" d="M3.5 4H1V3h2V1h1v2.5zM13 3V1h-1v2.5l.5.5H15V3zm-1 9.5V15h1v-2h2v-1h-2.5zM1 12v1h2v2h1v-2.5l-.5-.5zm11-1.5-.5.5h-7l-.5-.5v-5l.5-.5h7l.5.5zM10 7H6v2h4z"/></svg>

Before

Width:  |  Height:  |  Size: 327 B

After

Width:  |  Height:  |  Size: 308 B

View File

@ -1 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" aria-hidden="true" class="re-screen" color="#00000073" viewBox="0 0 16 16"><path fill="currentColor" d="M3 12h10V4H3zm2-6h6v4H5zM2 6H1V2.5l.5-.5H5v1H2zm13-3.5V6h-1V3h-3V2h3.5zM14 10h1v3.5l-.5.5H11v-1h3zM2 13h3v1H1.5l-.5-.5V10h1z"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" class="re-screen" color="#00000073" viewBox="0 0 16 16"><path fill="currentColor" d="M3 12h10V4H3zm2-6h6v4H5zM2 6H1V2.5l.5-.5H5v1H2zm13-3.5V6h-1V3h-3V2h3.5zM14 10h1v3.5l-.5.5H11v-1h3zM2 13h3v1H1.5l-.5-.5V10h1z"/></svg>

Before

Width:  |  Height:  |  Size: 302 B

After

Width:  |  Height:  |  Size: 283 B

View File

@ -1 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" aria-hidden="true" class="globalization" viewBox="0 0 512 512"><path fill="currentColor" d="m478.33 433.6-90-218a22 22 0 0 0-40.67 0l-90 218a22 22 0 1 0 40.67 16.79L316.66 406h102.67l18.33 44.39A22 22 0 0 0 458 464a22 22 0 0 0 20.32-30.4zM334.83 362 368 281.65 401.17 362zm-66.99-19.08a22 22 0 0 0-4.89-30.7c-.2-.15-15-11.13-36.49-34.73 39.65-53.68 62.11-114.75 71.27-143.49H330a22 22 0 0 0 0-44H214V70a22 22 0 0 0-44 0v20H54a22 22 0 0 0 0 44h197.25c-9.52 26.95-27.05 69.5-53.79 108.36-31.41-41.68-43.08-68.65-43.17-68.87a22 22 0 0 0-40.58 17c.58 1.38 14.55 34.23 52.86 83.93.92 1.19 1.83 2.35 2.74 3.51-39.24 44.35-77.74 71.86-93.85 80.74a22 22 0 1 0 21.07 38.63c2.16-1.18 48.6-26.89 101.63-85.59 22.52 24.08 38 35.44 38.93 36.1a22 22 0 0 0 30.75-4.9z"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" class="globalization" viewBox="0 0 512 512"><path fill="currentColor" d="m478.33 433.6-90-218a22 22 0 0 0-40.67 0l-90 218a22 22 0 1 0 40.67 16.79L316.66 406h102.67l18.33 44.39A22 22 0 0 0 458 464a22 22 0 0 0 20.32-30.4zM334.83 362 368 281.65 401.17 362zm-66.99-19.08a22 22 0 0 0-4.89-30.7c-.2-.15-15-11.13-36.49-34.73 39.65-53.68 62.11-114.75 71.27-143.49H330a22 22 0 0 0 0-44H214V70a22 22 0 0 0-44 0v20H54a22 22 0 0 0 0 44h197.25c-9.52 26.95-27.05 69.5-53.79 108.36-31.41-41.68-43.08-68.65-43.17-68.87a22 22 0 0 0-40.58 17c.58 1.38 14.55 34.23 52.86 83.93.92 1.19 1.83 2.35 2.74 3.51-39.24 44.35-77.74 71.86-93.85 80.74a22 22 0 1 0 21.07 38.63c2.16-1.18 48.6-26.89 101.63-85.59 22.52 24.08 38 35.44 38.93 36.1a22 22 0 0 0 30.75-4.9z"/></svg>

Before

Width:  |  Height:  |  Size: 826 B

After

Width:  |  Height:  |  Size: 807 B

View File

@ -1 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" aria-hidden="true" class="iconify iconify--mdi" viewBox="0 0 24 24"><path fill="currentColor" d="M1 7h6v2H3v2h4v2H3v2h4v2H1zm10 0h4v2h-4v2h2a2 2 0 0 1 2 2v2c0 1.11-.89 2-2 2H9v-2h4v-2h-2a2 2 0 0 1-2-2V9c0-1.1.9-2 2-2m8 0h2a2 2 0 0 1 2 2v1h-2V9h-2v6h2v-1h2v1c0 1.11-.89 2-2 2h-2a2 2 0 0 1-2-2V9c0-1.1.9-2 2-2"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" class="iconify iconify--mdi" viewBox="0 0 24 24"><path fill="currentColor" d="M1 7h6v2H3v2h4v2H3v2h4v2H1zm10 0h4v2h-4v2h2a2 2 0 0 1 2 2v2c0 1.11-.89 2-2 2H9v-2h4v-2h-2a2 2 0 0 1-2-2V9c0-1.1.9-2 2-2m8 0h2a2 2 0 0 1 2 2v1h-2V9h-2v6h2v-1h2v1c0 1.11-.89 2-2 2h-2a2 2 0 0 1-2-2V9c0-1.1.9-2 2-2"/></svg>

Before

Width:  |  Height:  |  Size: 379 B

After

Width:  |  Height:  |  Size: 360 B

View File

Before

Width:  |  Height:  |  Size: 439 B

After

Width:  |  Height:  |  Size: 439 B

View File

@ -0,0 +1 @@
<svg width="32" height="32" fill="currentColor" data-icon="holder" viewBox="64 64 896 896"><path d="M300 276.5a56 56 0 1 0 56-97 56 56 0 0 0-56 97m0 284a56 56 0 1 0 56-97 56 56 0 0 0-56 97M640 228a56 56 0 1 0 112 0 56 56 0 0 0-112 0m0 284a56 56 0 1 0 112 0 56 56 0 0 0-112 0M300 844.5a56 56 0 1 0 56-97 56 56 0 0 0-56 97M640 796a56 56 0 1 0 112 0 56 56 0 0 0-112 0"/></svg>

After

Width:  |  Height:  |  Size: 373 B

View File

Before

Width:  |  Height:  |  Size: 161 B

After

Width:  |  Height:  |  Size: 161 B

View File

Before

Width:  |  Height:  |  Size: 235 B

After

Width:  |  Height:  |  Size: 235 B

View File

Before

Width:  |  Height:  |  Size: 840 B

After

Width:  |  Height:  |  Size: 840 B

View File

@ -1,5 +1,5 @@
import reAnimateSelector from "./src/index.vue";
import { withInstall } from "@pureadmin/utils";
import reAnimateSelector from "./src/index.vue";
/** [animate.css](https://animate.style/) 选择器组件 */
export const ReAnimateSelector = withInstall(reAnimateSelector);

View File

@ -7,7 +7,7 @@ defineOptions({
name: "ReAnimateSelector"
});
const props = defineProps({
defineProps({
placeholder: {
type: String,
default: "请选择动画"
@ -81,7 +81,7 @@ function onMouseleave() {
<el-select
clearable
filterable
:placeholder="props.placeholder"
:placeholder="placeholder"
popper-class="pure-animate-popper"
:model-value="inputValue"
:filter-method="filterMethod"
@ -95,7 +95,7 @@ function onMouseleave() {
:view-style="{ overflow: 'hidden' }"
class="border-t border-[#e5e7eb]"
>
<ul class="flex flex-wrap justify-around mb-1">
<ul class="flex flex-wrap justify-around mb-1!">
<li
v-for="(animate, index) in animatesList"
:key="index"

View File

@ -1,5 +1,5 @@
import reBarcode from "./src/index.vue";
import { withInstall } from "@pureadmin/utils";
import reBarcode from "./src/index.vue";
/** 条形码组件 */
export const ReBarcode = withInstall(reBarcode);

View File

@ -1,10 +1,10 @@
import {
defineComponent,
reactive,
computed,
watch,
unref,
computed,
reactive,
onMounted,
unref
defineComponent
} from "vue";
import { countToProps } from "./props";
import { isNumber } from "@pureadmin/utils";
@ -61,7 +61,7 @@ export default defineComponent({
state.rAF = requestAnimationFrame(count);
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars,no-unused-vars
// eslint-disable-next-line @typescript-eslint/no-unused-vars
function pauseResume() {
if (state.paused) {
resume();
@ -83,7 +83,7 @@ export default defineComponent({
requestAnimationFrame(count);
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars,no-unused-vars
// eslint-disable-next-line @typescript-eslint/no-unused-vars
function reset() {
state.startTime = null;
cancelAnimationFrame(state.rAF);

View File

@ -1,5 +1,6 @@
import type { PropType } from "vue";
import propTypes from "@/utils/propTypes";
export const countToProps = {
startVal: propTypes.number.def(0),
endVal: propTypes.number.def(2020),

View File

@ -1,9 +1,9 @@
import "./rebound.css";
import {
defineComponent,
ref,
unref,
onBeforeMount,
defineComponent,
onBeforeUnmount
} from "vue";
import { reboundProps } from "./props";

View File

@ -1,5 +1,6 @@
import type { PropType } from "vue";
import propTypes from "@/utils/propTypes";
export const reboundProps = {
delay: propTypes.number.def(1),
blur: propTypes.number.def(2),

View File

@ -6,10 +6,10 @@ import { useEventListener } from "@vueuse/core";
import { longpress } from "@/directives/longpress";
import { useTippy, directive as tippy } from "vue-tippy";
import {
type PropType,
ref,
unref,
computed,
type PropType,
onMounted,
onUnmounted,
defineComponent
@ -119,7 +119,7 @@ export default defineComponent({
"p-[6px]",
"h-[30px]",
"w-[30px]",
"outline-none",
"outline-hidden",
"rounded-[4px]",
"cursor-pointer",
"hover:bg-[rgba(0,0,0,0.06)]"

View File

@ -0,0 +1,7 @@
import reCropperPreview from "./src/index.vue";
import { withInstall } from "@pureadmin/utils";
/** 图片裁剪预览组件 */
export const ReCropperPreview = withInstall(reCropperPreview);
export default ReCropperPreview;

View File

@ -3,7 +3,11 @@ import { ref } from "vue";
import ReCropper from "@/components/ReCropper";
import { formatBytes } from "@pureadmin/utils";
const props = defineProps({
defineOptions({
name: "ReCropperPreview"
});
defineProps({
imgSrc: String
});
@ -40,7 +44,7 @@ defineExpose({ hidePopover });
<div class="w-[18vw]">
<ReCropper
ref="refCropper"
:src="props.imgSrc"
:src="imgSrc"
circled
@cropper="onCropper"
@readied="showPopover = true"

View File

@ -29,9 +29,11 @@ const addDialog = (options: DialogOptions) => {
const closeDialog = (options: DialogOptions, index: number, args?: any) => {
dialogStore.value[index].visible = false;
options.closeCallBack && options.closeCallBack({ options, index, args });
const closeDelay = options?.closeDelay ?? 200;
useTimeoutFn(() => {
dialogStore.value.splice(index, 1);
}, 200);
}, closeDelay);
};
/**
@ -51,8 +53,8 @@ const closeAllDialog = () => {
/** 使`addDialog`
* https://github.com/pure-admin/vue-pure-admin/blob/main/src/App.vue#L4
* https://github.com/pure-admin/vue-pure-admin/blob/main/src/App.vue#L13
* https://github.com/pure-admin/vue-pure-admin/blob/main/src/App.vue#L20
* https://github.com/pure-admin/vue-pure-admin/blob/main/src/App.vue#L12
* https://github.com/pure-admin/vue-pure-admin/blob/main/src/App.vue#L22
*/
const ReDialog = withInstall(reDialog);

View File

@ -1,16 +1,21 @@
<script setup lang="ts">
import {
closeDialog,
dialogStore,
type EventType,
type ButtonProps,
type DialogOptions
type DialogOptions,
closeDialog,
dialogStore
} from "./index";
import { ref, computed } from "vue";
import { isFunction } from "@pureadmin/utils";
import Fullscreen from "@iconify-icons/ri/fullscreen-fill";
import ExitFullscreen from "@iconify-icons/ri/fullscreen-exit-fill";
import Fullscreen from "~icons/ri/fullscreen-fill";
import ExitFullscreen from "~icons/ri/fullscreen-exit-fill";
defineOptions({
name: "ReDialog"
});
const sureBtnMap = ref({});
const fullscreen = ref(false);
const footerButtons = computed(() => {
@ -37,11 +42,28 @@ const footerButtons = computed(() => {
type: "primary",
text: true,
bg: true,
popconfirm: options?.popconfirm,
btnClick: ({ dialog: { options, index } }) => {
const done = () =>
if (options?.sureBtnLoading) {
sureBtnMap.value[index] = Object.assign(
{},
sureBtnMap.value[index],
{
loading: true
}
);
}
const closeLoading = () => {
if (options?.sureBtnLoading) {
sureBtnMap.value[index].loading = false;
}
};
const done = () => {
closeLoading();
closeDialog(options, index, { command: "sure" });
};
if (options?.beforeSure && isFunction(options?.beforeSure)) {
options.beforeSure(done, { options, index });
options.beforeSure(done, { options, index, closeLoading });
} else {
done();
}
@ -57,7 +79,7 @@ const fullscreenClass = computed(() => {
"el-dialog__close",
"-translate-x-2",
"cursor-pointer",
"hover:!text-[red]"
"hover:text-[red]!"
];
});
@ -149,19 +171,35 @@ function handleClose(
<component :is="options?.footerRenderer({ options, index })" />
</template>
<span v-else>
<el-button
v-for="(btn, key) in footerButtons(options)"
:key="key"
v-bind="btn"
@click="
btn.btnClick({
dialog: { options, index },
button: { btn, index: key }
})
"
>
{{ btn?.label }}
</el-button>
<template v-for="(btn, key) in footerButtons(options)" :key="key">
<el-popconfirm
v-if="btn.popconfirm"
v-bind="btn.popconfirm"
@confirm="
btn.btnClick({
dialog: { options, index },
button: { btn, index: key }
})
"
>
<template #reference>
<el-button v-bind="btn">{{ btn?.label }}</el-button>
</template>
</el-popconfirm>
<el-button
v-else
v-bind="btn"
:loading="key === 1 && sureBtnMap[index]?.loading"
@click="
btn.btnClick({
dialog: { options, index },
button: { btn, index: key }
})
"
>
{{ btn?.label }}
</el-button>
</template>
</span>
</template>
</el-dialog>

View File

@ -11,6 +11,13 @@ type ArgsType = {
/** `cancel` 点击取消按钮、`sure` 点击确定按钮、`close` 点击右上角关闭按钮或空白页或按下了esc键 */
command: "cancel" | "sure" | "close";
};
type ButtonType =
| "primary"
| "success"
| "warning"
| "danger"
| "info"
| "text";
/** https://element-plus.org/zh-CN/component/dialog.html#attributes */
type DialogProps = {
@ -58,6 +65,34 @@ type DialogProps = {
destroyOnClose?: boolean;
};
//element-plus.org/zh-CN/component/popconfirm.html#attributes
type Popconfirm = {
/** 标题 */
title?: string;
/** 确定按钮文字 */
confirmButtonText?: string;
/** 取消按钮文字 */
cancelButtonText?: string;
/** 确定按钮类型,默认 `primary` */
confirmButtonType?: ButtonType;
/** 取消按钮类型,默认 `text` */
cancelButtonType?: ButtonType;
/** 自定义图标,默认 `QuestionFilled` */
icon?: string | Component;
/** `Icon` 颜色,默认 `#f90` */
iconColor?: string;
/** 是否隐藏 `Icon`,默认 `false` */
hideIcon?: boolean;
/** 关闭时的延迟,默认 `200` */
hideAfter?: number;
/** 是否将 `popover` 的下拉列表插入至 `body` 元素,默认 `true` */
teleported?: boolean;
/** 当 `popover` 组件长时间不触发且 `persistent` 属性设置为 `false` 时, `popover` 将会被删除,默认 `false` */
persistent?: boolean;
/** 弹层宽度,最小宽度 `150px`,默认 `150` */
width?: string | number;
};
type BtnClickDialog = {
options?: DialogOptions;
index?: number;
@ -86,6 +121,8 @@ type ButtonProps = {
round?: boolean;
/** 是否为圆形按钮,默认 `false` */
circle?: boolean;
/** 确定按钮的 `Popconfirm` 气泡确认框相关配置 */
popconfirm?: Popconfirm;
/** 是否为加载中状态,默认 `false` */
loading?: boolean;
/** 自定义加载中状态图标组件 */
@ -123,6 +160,10 @@ interface DialogOptions extends DialogProps {
props?: any;
/** 是否隐藏 `Dialog` 按钮操作区的内容 */
hideFooter?: boolean;
/** 确定按钮的 `Popconfirm` 气泡确认框相关配置 */
popconfirm?: Popconfirm;
/** 点击确定按钮后是否开启 `loading` 加载动画 */
sureBtnLoading?: boolean;
/**
* @description
* @see {@link https://element-plus.org/zh-CN/component/dialog.html#%E8%87%AA%E5%AE%9A%E4%B9%89%E5%A4%B4%E9%83%A8}
@ -220,10 +261,13 @@ interface DialogOptions extends DialogProps {
done: Function,
{
options,
index
index,
closeLoading
}: {
options: DialogOptions;
index: number;
/** 关闭确定按钮的 `loading` 加载动画 */
closeLoading: Function;
}
) => void;
}

View File

@ -0,0 +1,64 @@
import { ref } from "vue";
import reDrawer from "./index.vue";
import { useTimeoutFn } from "@vueuse/core";
import { withInstall } from "@pureadmin/utils";
import type {
EventType,
ArgsType,
DrawerProps,
DrawerOptions,
ButtonProps
} from "./type";
const drawerStore = ref<Array<DrawerOptions>>([]);
/** 打开抽屉 */
const addDrawer = (options: DrawerOptions) => {
const open = () =>
drawerStore.value.push(Object.assign(options, { visible: true }));
if (options?.openDelay) {
useTimeoutFn(() => {
open();
}, options.openDelay);
} else {
open();
}
};
/** 关闭抽屉 */
const closeDrawer = (options: DrawerOptions, index: number, args?: any) => {
drawerStore.value[index].visible = false;
options.closeCallBack && options.closeCallBack({ options, index, args });
const closeDelay = options?.closeDelay ?? 200;
useTimeoutFn(() => {
drawerStore.value.splice(index, 1);
}, closeDelay);
};
/**
* @description
* @param value
* @param key `title`
* @param index `0``index`
*/
const updateDrawer = (value: any, key = "title", index = 0) => {
drawerStore.value[index][key] = value;
};
/** 关闭所有弹框 */
const closeAllDrawer = () => {
drawerStore.value = [];
};
const ReDrawer = withInstall(reDrawer);
export type { EventType, ArgsType, DrawerOptions, DrawerProps, ButtonProps };
export {
ReDrawer,
drawerStore,
addDrawer,
closeDrawer,
updateDrawer,
closeAllDrawer
};

View File

@ -0,0 +1,169 @@
<script setup lang="ts">
import {
type EventType,
type ButtonProps,
type DrawerOptions,
closeDrawer,
drawerStore
} from "./index";
import { computed, ref } from "vue";
import { isFunction } from "@pureadmin/utils";
defineOptions({
name: "ReDrawer"
});
const sureBtnMap = ref({});
const footerButtons = computed(() => {
return (options: DrawerOptions) => {
return options?.footerButtons?.length > 0
? options.footerButtons
: ([
{
label: "取消",
text: true,
bg: true,
btnClick: ({ drawer: { options, index } }) => {
const done = () =>
closeDrawer(options, index, { command: "cancel" });
if (options?.beforeCancel && isFunction(options?.beforeCancel)) {
options.beforeCancel(done, { options, index });
} else {
done();
}
}
},
{
label: "确定",
type: "primary",
text: true,
bg: true,
popConfirm: options?.popConfirm,
btnClick: ({ drawer: { options, index } }) => {
if (options?.sureBtnLoading) {
sureBtnMap.value[index] = Object.assign(
{},
sureBtnMap.value[index],
{
loading: true
}
);
}
const closeLoading = () => {
if (options?.sureBtnLoading) {
sureBtnMap.value[index].loading = false;
}
};
const done = () => {
closeLoading();
closeDrawer(options, index, { command: "sure" });
};
if (options?.beforeSure && isFunction(options?.beforeSure)) {
options.beforeSure(done, { options, index, closeLoading });
} else {
done();
}
}
}
] as Array<ButtonProps>);
};
});
function eventsCallBack(
event: EventType,
options: DrawerOptions,
index: number
) {
if (options?.[event] && isFunction(options?.[event])) {
return options?.[event]({ options, index });
}
}
/**
*
* @param {DrawerOptions} options - 包含抽屉相关配置的对象
* @param {number} index - 抽屉的索引
* @param {Object} args - 传递给关闭抽屉操作的参数对象默认为 { command: 'close' }
* @returns {void} 这个函数不返回任何值
*/
function handleClose(
options: DrawerOptions,
index: number,
args = { command: "close" }
) {
closeDrawer(options, index, args);
eventsCallBack("close", options, index);
}
</script>
<template>
<el-drawer
v-for="(options, index) in drawerStore"
:key="index"
v-bind="options"
v-model="options.visible"
class="pure-drawer"
:append-to-body="!!options?.appendToBody"
:append-to="options?.appendTo ? options.appendTo : 'body'"
:destroy-on-close="!!options?.destroyOnClose"
:lock-scroll="!!options?.lockScroll"
@closed="handleClose(options, index)"
@opened="eventsCallBack('open', options, index)"
@open-auto-focus="eventsCallBack('openAutoFocus', options, index)"
@close-auto-focus="eventsCallBack('closeAutoFocus', options, index)"
>
<!-- header -->
<template
v-if="options?.headerRenderer"
#header="{ close, titleId, titleClass }"
>
<component
:is="options?.headerRenderer({ close, titleId, titleClass })"
/>
</template>
<!-- body -->
<component
v-bind="options?.props"
:is="options.contentRenderer({ options, index })"
@close="args => handleClose(options, index, args)"
/>
<!-- footer -->
<template v-if="!options?.hideFooter" #footer>
<template v-if="options?.footerRenderer">
<component :is="options?.footerRenderer({ options, index })" />
</template>
<span v-else>
<template v-for="(btn, key) in footerButtons(options)" :key="key">
<el-popconfirm
v-if="btn.popConfirm"
v-bind="btn.popConfirm"
@confirm="
btn.btnClick({
drawer: { options, index },
button: { btn, index: key }
})
"
>
<template #reference>
<el-button v-bind="btn">{{ btn?.label }}</el-button>
</template>
</el-popconfirm>
<el-button
v-else
v-bind="btn"
:loading="key === 1 && sureBtnMap[index]?.loading"
@click="
btn.btnClick({
drawer: { options, index },
button: { btn, index: key }
})
"
>
{{ btn?.label }}
</el-button>
</template>
</span>
</template>
</el-drawer>
</template>

View File

@ -0,0 +1,262 @@
import type { CSSProperties, VNode, Component } from "vue";
type DoneFn = (cancel?: boolean) => void;
type EventType = "open" | "close" | "openAutoFocus" | "closeAutoFocus";
type ArgsType = {
/** `cancel` 点击取消按钮、`sure` 点击确定按钮、`close` 点击右上角关闭按钮或空白页或按下了 `esc` 键 */
command: "cancel" | "sure" | "close";
};
type ButtonType =
| "primary"
| "success"
| "warning"
| "danger"
| "info"
| "text";
type DrawerProps = {
/** `Drawer` 的显示与隐藏 */
visible?: boolean;
/** `Drawer` 自身是否插入至 `body` 元素上。嵌套的 `Drawer` 必须指定该属性并赋值为 `true`,默认 `false` */
appendToBody?: boolean;
/** 挂载到哪个 `DOM` 元素 将覆盖 `appendToBody` */
appendTo?: string;
/** 是否在 `Drawer` 出现时将 `body` 滚动锁定,默认 `true` */
lockScroll?: boolean;
/** 关闭前的回调,会暂停 `Drawer` 的关闭 回调函数内执行 `done` 参数方法的时候才是真正关闭对话框的时候 */
beforeClose?: (done: DoneFn) => void;
/** 是否可以通过点击 `modal` 关闭 `Drawer` ,默认 `true` */
closeOnClickModal?: boolean;
/** 是否可以通过按下 `ESC` 关闭 `Drawer` ,默认 `true` */
closeOnPressEscape?: boolean;
/** 是否显示关闭按钮,默认 `true` */
showClose?: boolean;
/** `Drawer` 打开的延时时间,单位毫秒,默认 `0` */
openDelay?: number;
/** `Drawer` 关闭的延时时间,单位毫秒,默认 `0` */
closeDelay?: number;
/** `Drawer` 自定义类名 */
class?: string;
/** `Drawer` 的自定义样式 */
style?: CSSProperties;
/** 控制是否在关闭 `Drawer` 之后将子元素全部销毁,默认 `false` */
destroyOnClose?: boolean;
/** 是否需要遮罩层,默认 `true` */
modal?: boolean;
/** `Drawer` 打开的方向,默认 `rtl` */
direction?: "rtl" | "ltr" | "ttb" | "btt";
/** `Drawer` 窗体的大小, 当使用 `number` 类型时, 以像素为单位, 当使用 `string` 类型时, 请传入 `'x%'`, 否则便会以 `number` 类型解释 */
size?: string | number;
/** `Drawer` 的标题 */
title?: string;
/** 控制是否显示 `header` 栏, 默认为 `true`, 当此项为 `false` 时, `title attribute` 和 `title slot` 均不生效 */
withHeader?: boolean;
/** 遮罩层的自定义类名 */
modalClass?: string;
/** 设置 `z-index` */
zIndex?: number;
/** `header` 的 `aria-level` 属性,默认 `2` */
headerAriaLevel?: string;
};
//element-plus.org/zh-CN/component/popConfirm.html#attributes
type PopConfirm = {
/** 标题 */
title?: string;
/** 确认按钮文字 */
confirmButtonText?: string;
/** 取消按钮文字 */
cancelButtonText?: string;
/** 确认按钮类型,默认 `primary` */
confirmButtonType?: ButtonType;
/** 取消按钮类型,默认 `text` */
cancelButtonType?: ButtonType;
/** 自定义图标,默认 `QuestionFilled` */
icon?: string | Component;
/** `Icon` 颜色,默认 `#f90` */
iconColor?: string;
/** 是否隐藏 `Icon`,默认 `false` */
hideIcon?: boolean;
/** 关闭时的延迟,默认 `200` */
hideAfter?: number;
/** 是否将 `popover` 的下拉列表插入至 `body` 元素,默认 `true` */
teleported?: boolean;
/** 当 `popover` 组件长时间不触发且 `persistent` 属性设置为 `false` 时, `popover` 将会被删除,默认 `false` */
persistent?: boolean;
/** 弹层宽度,最小宽度 `150px`,默认 `150` */
width?: string | number;
};
type BtnClickDrawer = {
options?: DrawerOptions;
index?: number;
};
type BtnClickButton = {
btn?: ButtonProps;
index?: number;
};
/** https://element-plus.org/zh-CN/component/button.html#button-attributes */
type ButtonProps = {
/** 按钮文字 */
label: string;
/** 按钮尺寸 */
size?: "large" | "default" | "small";
/** 按钮类型 */
type?: "primary" | "success" | "warning" | "danger" | "info";
/** 是否为朴素按钮,默认 `false` */
plain?: boolean;
/** 是否为文字按钮,默认 `false` */
text?: boolean;
/** 是否显示文字按钮背景颜色,默认 `false` */
bg?: boolean;
/** 是否为链接按钮,默认 `false` */
link?: boolean;
/** 是否为圆角按钮,默认 `false` */
round?: boolean;
/** 是否为圆形按钮,默认 `false` */
circle?: boolean;
/** 确认按钮的 `PopConfirm` 气泡确认框相关配置 */
popConfirm?: PopConfirm;
/** 是否为加载中状态,默认 `false` */
loading?: boolean;
/** 自定义加载中状态图标组件 */
loadingIcon?: string | Component;
/** 按钮是否为禁用状态,默认 `false` */
disabled?: boolean;
/** 图标组件 */
icon?: string | Component;
/** 是否开启原生 `autofocus` 属性,默认 `false` */
autofocus?: boolean;
/** 原生 `type` 属性,默认 `button` */
nativeType?: "button" | "submit" | "reset";
/** 自动在两个中文字符之间插入空格 */
autoInsertSpace?: boolean;
/** 自定义按钮颜色, 并自动计算 `hover` 和 `active` 触发后的颜色 */
color?: string;
/** `dark` 模式, 意味着自动设置 `color` 为 `dark` 模式的颜色,默认 `false` */
dark?: boolean;
/** 自定义元素标签 */
tag?: string | Component;
/** 点击按钮后触发的回调 */
btnClick?: ({
drawer,
button
}: {
/** 当前 `Drawer` 信息 */
drawer: BtnClickDrawer;
/** 当前 `button` 信息 */
button: BtnClickButton;
}) => void;
};
interface DrawerOptions extends DrawerProps {
/** 内容区组件的 `props`,可通过 `defineProps` 接收 */
props?: any;
/** 是否隐藏 `Drawer` 按钮操作区的内容 */
hideFooter?: boolean;
/** 确认按钮的 `PopConfirm` 气泡确认框相关配置 */
popConfirm?: PopConfirm;
/** 点击确定按钮后是否开启 `loading` 加载动画 */
sureBtnLoading?: boolean;
/**
* @description
* @see {@link https://element-plus.org/zh-CN/component/drawer.html#%E6%8F%92%E6%A7%BD}
*/
headerRenderer?: ({
close,
titleId,
titleClass
}: {
close: Function;
titleId: string;
titleClass: string;
}) => VNode | Component;
/** 自定义内容渲染器 */
contentRenderer?: ({
options,
index
}: {
options: DrawerOptions;
index: number;
}) => VNode | Component;
/** 自定义按钮操作区的内容渲染器,会覆盖`footerButtons`以及默认的 `取消` 和 `确定` 按钮 */
footerRenderer?: ({
options,
index
}: {
options: DrawerOptions;
index: number;
}) => VNode | Component;
/** 自定义底部按钮操作 */
footerButtons?: Array<ButtonProps>;
/** `Drawer` 打开后的回调 */
open?: ({
options,
index
}: {
options: DrawerOptions;
index: number;
}) => void;
/** `Drawer` 关闭后的回调只有点击右上角关闭按钮或空白页或按下了esc键关闭页面时才会触发 */
close?: ({
options,
index
}: {
options: DrawerOptions;
index: number;
}) => void;
/** `Drawer` 关闭后的回调。 `args` 返回的 `command` 值解析:`cancel` 点击取消按钮、`sure` 点击确定按钮、`close` 点击右上角关闭按钮或空白页或按下了esc键 */
closeCallBack?: ({
options,
index,
args
}: {
options: DrawerOptions;
index: number;
args: any;
}) => void;
/** 输入焦点聚焦在 `Drawer` 内容时的回调 */
openAutoFocus?: ({
options,
index
}: {
options: DrawerOptions;
index: number;
}) => void;
/** 输入焦点从 `Drawer` 内容失焦时的回调 */
closeAutoFocus?: ({
options,
index
}: {
options: DrawerOptions;
index: number;
}) => void;
/** 点击底部取消按钮的回调,会暂停 `Drawer` 的关闭. 回调函数内执行 `done` 参数方法的时候才是真正关闭对话框的时候 */
beforeCancel?: (
done: Function,
{
options,
index
}: {
options: DrawerOptions;
index: number;
}
) => void;
/** 点击底部确定按钮的回调,会暂停 `Drawer` 的关闭. 回调函数内执行 `done` 参数方法的时候才是真正关闭对话框的时候 */
beforeSure?: (
done: Function,
{
options,
index,
closeLoading
}: {
options: DrawerOptions;
index: number;
closeLoading: Function;
}
) => void;
}
export type { ButtonProps, DrawerOptions, ArgsType, DrawerProps, EventType };

View File

@ -1,5 +1,5 @@
import "./index.css";
import { h, defineComponent, type Component } from "vue";
import { type Component, h, defineComponent } from "vue";
export interface attrsType {
width?: string;

View File

@ -1,6 +1,6 @@
import { defineComponent, ref } from "vue";
import propTypes from "@/utils/propTypes";
import "./filpper.css";
import propTypes from "@/utils/propTypes";
import { defineComponent, ref } from "vue";
const props = {
// front paper text

View File

@ -1,6 +1,10 @@
<script setup lang="ts">
import { ref, unref, nextTick, onUnmounted } from "vue";
import flippers from "./filpper";
import { ref, unref, nextTick, onUnmounted } from "vue";
defineOptions({
name: "ReFlop"
});
const timer = ref(null);
const flipObjs = ref([]);

View File

@ -3,7 +3,7 @@ import { ref, unref, onMounted } from "vue";
import { LogicFlow } from "@logicflow/core";
interface Props {
lf: LogicFlow;
lf?: LogicFlow;
catTurboData?: boolean;
}
@ -105,27 +105,25 @@ onMounted(() => {
@mouseenter.prevent="onEnter(key)"
@mouseleave.prevent="focusIndex = -1"
>
<el-tooltip
:content="item.text"
:visible="focusIndex === key"
placement="right"
<button
:ref="'controlButton' + key"
v-tippy="{
content: item.text
}"
:disabled="item.disabled"
:style="{
cursor: item.disabled === false ? 'pointer' : 'not-allowed',
color: item.disabled === false ? '' : '#00000040',
background: 'transparent',
border: 'none'
}"
@click="onControl(item, key)"
>
<button
:ref="'controlButton' + key"
:disabled="item.disabled"
:style="{
cursor: item.disabled === false ? 'pointer' : 'not-allowed',
color: item.disabled === false ? '' : '#00000040',
background: 'transparent'
}"
@click="onControl(item, key)"
>
<span
:class="'iconfont ' + item.icon"
:style="{ fontSize: `${item.size}px` }"
/>
</button>
</el-tooltip>
<span
:class="'iconfont ' + item.icon"
:style="{ fontSize: `${item.size}px` }"
/>
</button>
</li>
</ul>
</div>

View File

@ -2,7 +2,7 @@
import VueJsonPretty from "vue-json-pretty";
import "vue-json-pretty/lib/styles.css";
const props = defineProps({
defineProps({
graphData: Object
});
</script>
@ -12,6 +12,6 @@ const props = defineProps({
:path="'res'"
:deep="3"
:showLength="true"
:data="props.graphData"
:data="graphData"
/>
</template>

View File

@ -9,8 +9,8 @@ type nodeListType = {
};
interface Props {
lf: LogicFlow;
nodeList: Array<nodeListType>;
lf?: LogicFlow;
nodeList?: Array<nodeListType>;
}
const props = withDefaults(defineProps<Props>(), {
@ -35,7 +35,7 @@ const nodeDragNode = item => {
<!-- 左侧bpmn元素选择器 -->
<div class="node-panel">
<div
v-for="item in props.nodeList"
v-for="item in nodeList"
:key="item.text"
class="node-item dark:text-bg_color"
@mousedown="nodeDragNode(item)"

View File

@ -28,8 +28,7 @@
((o = document.createElement("div")).innerHTML = i),
(i = null),
(e = o.getElementsByTagName("svg")[0]) &&
(e.setAttribute("aria-hidden", "true"),
(e.style.position = "absolute"),
((e.style.position = "absolute"),
(e.style.width = 0),
(e.style.height = 0),
(e.style.overflow = "hidden"),

View File

@ -2,7 +2,7 @@
import { IconJson } from "@/components/ReIcon/data";
import { cloneDeep, isAllEmpty } from "@pureadmin/utils";
import { ref, computed, CSSProperties, watch } from "vue";
import Search from "@iconify-icons/ri/search-eye-line";
import Search from "~icons/ri/search-eye-line";
type ParameterCSSProperties = (item?: string) => CSSProperties | undefined;
@ -158,7 +158,7 @@ watch(
:name="pane.name"
>
<el-scrollbar height="220px">
<ul class="flex flex-wrap px-2 ml-2">
<ul class="flex flex-wrap px-2! ml-2!">
<li
v-for="(item, key) in pageList"
:key="key"
@ -194,11 +194,11 @@ watch(
:pager-count="5"
layout="pager"
background
small
size="small"
@current-change="onCurrentChange"
/>
<el-button
class="justify-end mr-2 ml-2"
class="justify-end mx-2!"
type="danger"
size="small"
text
@ -219,8 +219,8 @@ watch(
&:hover {
color: var(--el-color-primary);
border-color: var(--el-color-primary);
transition: all 0.4s;
transform: scaleX(1.05);
transition: all 0.4s;
}
}

View File

@ -1,10 +1,10 @@
import type { iconType } from "./types";
import { h, defineComponent, type Component } from "vue";
import { IconifyIconOnline, IconifyIconOffline, FontIcon } from "../index";
import { FontIcon, IconifyIconOnline, IconifyIconOffline } from "../index";
/**
* `iconfont` `svg` `iconify`
* @see {@link https://yiming_chang.gitee.io/pure-admin-doc/pages/icon/}
* @see {@link https://pure-admin.cn/pages/icon/}
* @param icon
* @param attrs iconType
* @returns Component
@ -49,10 +49,12 @@ export function useRenderIcon(icon: any, attrs?: iconType): Component {
return defineComponent({
name: "Icon",
render() {
const IconifyIcon =
icon && icon.includes(":") ? IconifyIconOnline : IconifyIconOffline;
if (!icon) return;
const IconifyIcon = icon.includes(":")
? IconifyIconOnline
: IconifyIconOffline;
return h(IconifyIcon, {
icon: icon,
icon,
...attrs
});
}

View File

@ -27,8 +27,7 @@ export default defineComponent({
return h(
"svg",
{
class: "icon-svg",
"aria-hidden": true
class: "icon-svg"
},
{
default: () => [

View File

@ -13,18 +13,35 @@ export default defineComponent({
render() {
if (typeof this.icon === "object") addIcon(this.icon, this.icon);
const attrs = this.$attrs;
return h(
IconifyIcon,
{
icon: this.icon,
style: attrs?.style
? Object.assign(attrs.style, { outline: "none" })
: { outline: "none" },
...attrs
},
{
default: () => []
}
);
if (typeof this.icon === "string") {
return h(
IconifyIcon,
{
icon: this.icon,
"aria-hidden": false,
style: attrs?.style
? Object.assign(attrs.style, { outline: "none" })
: { outline: "none" },
...attrs
},
{
default: () => []
}
);
} else {
return h(
this.icon,
{
"aria-hidden": false,
style: attrs?.style
? Object.assign(attrs.style, { outline: "none" })
: { outline: "none" },
...attrs
},
{
default: () => []
}
);
}
}
});

View File

@ -17,6 +17,7 @@ export default defineComponent({
IconifyIcon,
{
icon: `${this.icon}`,
"aria-hidden": false,
style: attrs?.style
? Object.assign(attrs.style, { outline: "none" })
: { outline: "none" },

View File

@ -1,68 +1,87 @@
// 这里存放本地图标,在 src/layout/index.vue 文件中加载,避免在首启动加载
import { getSvgInfo } from "@pureadmin/utils";
import { addIcon } from "@iconify/vue/dist/offline";
// https://icon-sets.iconify.design/ep/?keyword=ep
import EpMenu from "~icons/ep/menu?raw";
import EpEdit from "~icons/ep/edit?raw";
import EpGuide from "~icons/ep/guide?raw";
import EpSetUp from "~icons/ep/set-up?raw";
import EpMonitor from "~icons/ep/monitor?raw";
import EpLollipop from "~icons/ep/lollipop?raw";
import EpHistogram from "~icons/ep/histogram?raw";
import EpHomeFilled from "~icons/ep/home-filled?raw";
// https://icon-sets.iconify.design/ri/?keyword=ri
import RiMindMap from "~icons/ri/mind-map?raw";
import RiAdminFill from "~icons/ri/admin-fill?raw";
import RiTableLine from "~icons/ri/table-line?raw";
import RiLinksFill from "~icons/ri/links-fill?raw";
import RiAdminLine from "~icons/ri/admin-line?raw";
import RiListCheck from "~icons/ri/list-check?raw";
import RiSearchLine from "~icons/ri/search-line?raw";
import RiWindowLine from "~icons/ri/window-line?raw";
import RiUbuntuFill from "~icons/ri/ubuntu-fill?raw";
import RiHistoryFill from "~icons/ri/history-fill?raw";
import RiEditBoxLine from "~icons/ri/edit-box-line?raw";
import RiCodeBoxLine from "~icons/ri/code-box-line?raw";
import RiArtboardLine from "~icons/ri/artboard-line?raw";
import RiMarkdownLine from "~icons/ri/markdown-line?raw";
import RiFileInfoLine from "~icons/ri/file-info-line?raw";
import RiBankCardLine from "~icons/ri/bank-card-line?raw";
import RiFilePpt2Line from "~icons/ri/file-ppt-2-line?raw";
import RiGitBranchLine from "~icons/ri/git-branch-line?raw";
import RiSettings3Line from "~icons/ri/settings-3-line?raw";
import RiUserVoiceLine from "~icons/ri/user-voice-line?raw";
import RiBookmark2Line from "~icons/ri/bookmark-2-line?raw";
import RiFileSearchLine from "~icons/ri/file-search-line?raw";
import RiChatSearchLine from "~icons/ri/chat-search-line?raw";
import RiInformationLine from "~icons/ri/information-line?raw";
import RiTerminalWindowLine from "~icons/ri/terminal-window-line?raw";
import RiCheckboxCircleLine from "~icons/ri/checkbox-circle-line?raw";
import RiBarChartHorizontalLine from "~icons/ri/bar-chart-horizontal-line?raw";
const icons = [
// Element Plus Icon: https://github.com/element-plus/element-plus-icons
["ep/menu", EpMenu],
["ep/edit", EpEdit],
["ep/guide", EpGuide],
["ep/set-up", EpSetUp],
["ep/monitor", EpMonitor],
["ep/lollipop", EpLollipop],
["ep/histogram", EpHistogram],
["ep/home-filled", EpHomeFilled],
// Remix Icon: https://github.com/Remix-Design/RemixIcon
["ri/mind-map", RiMindMap],
["ri/admin-fill", RiAdminFill],
["ri/table-line", RiTableLine],
["ri/links-fill", RiLinksFill],
["ri/admin-line", RiAdminLine],
["ri/list-check", RiListCheck],
["ri/search-line", RiSearchLine],
["ri/window-line", RiWindowLine],
["ri/ubuntu-fill", RiUbuntuFill],
["ri/history-fill", RiHistoryFill],
["ri/edit-box-line", RiEditBoxLine],
["ri/code-box-line", RiCodeBoxLine],
["ri/artboard-line", RiArtboardLine],
["ri/markdown-line", RiMarkdownLine],
["ri/file-info-line", RiFileInfoLine],
["ri/bank-card-line", RiBankCardLine],
["ri/file-ppt-2-line", RiFilePpt2Line],
["ri/git-branch-line", RiGitBranchLine],
["ri/settings-3-line", RiSettings3Line],
["ri/user-voice-line", RiUserVoiceLine],
["ri/bookmark-2-line", RiBookmark2Line],
["ri/file-search-line", RiFileSearchLine],
["ri/chat-search-line", RiChatSearchLine],
["ri/information-line", RiInformationLine],
["ri/terminal-window-line", RiTerminalWindowLine],
["ri/checkbox-circle-line", RiCheckboxCircleLine],
["ri/bar-chart-horizontal-line", RiBarChartHorizontalLine]
];
// 本地菜单图标,后端在路由的 icon 中返回对应的图标字符串并且前端在此处使用 addIcon 添加即可渲染菜单图标
// @iconify-icons/ep
import Menu from "@iconify-icons/ep/menu";
import Edit from "@iconify-icons/ep/edit";
import SetUp from "@iconify-icons/ep/set-up";
import Guide from "@iconify-icons/ep/guide";
import Monitor from "@iconify-icons/ep/monitor";
import Lollipop from "@iconify-icons/ep/lollipop";
import Histogram from "@iconify-icons/ep/histogram";
import HomeFilled from "@iconify-icons/ep/home-filled";
addIcon("ep:menu", Menu);
addIcon("ep:edit", Edit);
addIcon("ep:set-up", SetUp);
addIcon("ep:guide", Guide);
addIcon("ep:monitor", Monitor);
addIcon("ep:lollipop", Lollipop);
addIcon("ep:histogram", Histogram);
addIcon("ep:home-filled", HomeFilled);
// @iconify-icons/ri
import Tag from "@iconify-icons/ri/bookmark-2-line";
import Ppt from "@iconify-icons/ri/file-ppt-2-line";
import Card from "@iconify-icons/ri/bank-card-line";
import Role from "@iconify-icons/ri/admin-fill";
import Info from "@iconify-icons/ri/file-info-line";
import Dept from "@iconify-icons/ri/git-branch-line";
import Table from "@iconify-icons/ri/table-line";
import Links from "@iconify-icons/ri/links-fill";
import Search from "@iconify-icons/ri/search-line";
import FlUser from "@iconify-icons/ri/admin-line";
import Setting from "@iconify-icons/ri/settings-3-line";
import BarChart from "@iconify-icons/ri/bar-chart-horizontal-line";
import LoginLog from "@iconify-icons/ri/window-line";
import Artboard from "@iconify-icons/ri/artboard-line";
import SystemLog from "@iconify-icons/ri/file-search-line";
import ListCheck from "@iconify-icons/ri/list-check";
import UbuntuFill from "@iconify-icons/ri/ubuntu-fill";
import OnlineUser from "@iconify-icons/ri/user-voice-line";
import EditBoxLine from "@iconify-icons/ri/edit-box-line";
import OperationLog from "@iconify-icons/ri/history-fill";
import InformationLine from "@iconify-icons/ri/information-line";
import TerminalWindowLine from "@iconify-icons/ri/terminal-window-line";
import CheckboxCircleLine from "@iconify-icons/ri/checkbox-circle-line";
addIcon("ri:bookmark-2-line", Tag);
addIcon("ri:file-ppt-2-line", Ppt);
addIcon("ri:bank-card-line", Card);
addIcon("ri:admin-fill", Role);
addIcon("ri:file-info-line", Info);
addIcon("ri:git-branch-line", Dept);
addIcon("ri:links-fill", Links);
addIcon("ri:table-line", Table);
addIcon("ri:search-line", Search);
addIcon("ri:admin-line", FlUser);
addIcon("ri:settings-3-line", Setting);
addIcon("ri:bar-chart-horizontal-line", BarChart);
addIcon("ri:window-line", LoginLog);
addIcon("ri:file-search-line", SystemLog);
addIcon("ri:artboard-line", Artboard);
addIcon("ri:list-check", ListCheck);
addIcon("ri:ubuntu-fill", UbuntuFill);
addIcon("ri:user-voice-line", OnlineUser);
addIcon("ri:edit-box-line", EditBoxLine);
addIcon("ri:history-fill", OperationLog);
addIcon("ri:information-line", InformationLine);
addIcon("ri:terminal-window-line", TerminalWindowLine);
addIcon("ri:checkbox-circle-line", CheckboxCircleLine);
icons.forEach(([name, icon]) => {
addIcon(name as string, getSvgInfo(icon as string));
});

View File

@ -0,0 +1,5 @@
import perms from "./src/perms";
const Perms = perms;
export { Perms };

View File

@ -0,0 +1,20 @@
import { defineComponent, Fragment } from "vue";
import { hasPerms } from "@/utils/auth";
export default defineComponent({
name: "Perms",
props: {
value: {
type: undefined,
default: []
}
},
setup(props, { slots }) {
return () => {
if (!slots) return null;
return hasPerms(props.value) ? (
<Fragment>{slots.default?.()}</Fragment>
) : null;
};
}
});

View File

@ -1,5 +1,15 @@
import Sortable from "sortablejs";
import { transformI18n } from "@/plugins/i18n";
import { useEpThemeStoreHook } from "@/store/modules/epTheme";
import { defineComponent, ref, computed, type PropType, nextTick } from "vue";
import {
type PropType,
ref,
unref,
computed,
nextTick,
defineComponent,
getCurrentInstance
} from "vue";
import {
delay,
cloneDeep,
@ -8,12 +18,13 @@ import {
getKeyList
} from "@pureadmin/utils";
import Sortable from "sortablejs";
import DragIcon from "./svg/drag.svg?component";
import ExpandIcon from "./svg/expand.svg?component";
import RefreshIcon from "./svg/refresh.svg?component";
import SettingIcon from "./svg/settings.svg?component";
import CollapseIcon from "./svg/collapse.svg?component";
import Fullscreen from "~icons/ri/fullscreen-fill";
import ExitFullscreen from "~icons/ri/fullscreen-exit-fill";
import DragIcon from "@/assets/table-bar/drag.svg?component";
import ExpandIcon from "@/assets/table-bar/expand.svg?component";
import RefreshIcon from "@/assets/table-bar/refresh.svg?component";
import SettingIcon from "@/assets/table-bar/settings.svg?component";
import CollapseIcon from "@/assets/table-bar/collapse.svg?component";
const props = {
/** 头部最左边的标题 */
@ -33,18 +44,24 @@ const props = {
isExpandAll: {
type: Boolean,
default: true
},
tableKey: {
type: [String, Number] as PropType<string | number>,
default: "0"
}
};
export default defineComponent({
name: "PureTableBar",
props,
emits: ["refresh"],
emits: ["refresh", "fullscreen"],
setup(props, { emit, slots, attrs }) {
const size = ref("default");
const loading = ref(false);
const checkAll = ref(true);
const isFullscreen = ref(false);
const isIndeterminate = ref(false);
const instance = getCurrentInstance()!;
const isExpandAll = ref(props.isExpandAll);
const filterColumns = cloneDeep(props?.columns).filter(column =>
isBoolean(column?.hide)
@ -70,9 +87,9 @@ export default defineComponent({
"text-black",
"dark:text-white",
"duration-100",
"hover:!text-primary",
"hover:text-primary!",
"cursor-pointer",
"outline-none"
"outline-hidden"
];
});
@ -100,6 +117,11 @@ export default defineComponent({
toggleRowExpansionAll(props.tableRef.data, isExpandAll.value);
}
function onFullscreen() {
isFullscreen.value = !isFullscreen.value;
emit("fullscreen", isFullscreen.value);
}
function toggleRowExpansionAll(data, isExpansion) {
data.forEach(item => {
props.tableRef.toggleRowExpansion(item, isExpansion);
@ -118,6 +140,7 @@ export default defineComponent({
}
function handleCheckedColumnsChange(value: string[]) {
checkedColumns.value = value;
const checkedCount = value.length;
checkAll.value = checkedCount === checkColumnList.length;
isIndeterminate.value =
@ -125,7 +148,9 @@ export default defineComponent({
}
function handleCheckColumnListChange(val: boolean, label: string) {
dynamicColumns.value.filter(item => item.label === label)[0].hide = !val;
dynamicColumns.value.filter(
item => transformI18n(item.label) === transformI18n(label)
)[0].hide = !val;
}
async function onReset() {
@ -166,9 +191,9 @@ export default defineComponent({
const rowDrop = (event: { preventDefault: () => void }) => {
event.preventDefault();
nextTick(() => {
const wrapper: HTMLElement = document.querySelector(
".el-checkbox-group>div"
);
const wrapper: HTMLElement = (
instance?.proxy?.$refs[`GroupRef${unref(props.tableKey)}`] as any
).$el.firstElementChild;
Sortable.create(wrapper, {
animation: 300,
handle: ".drag-btn",
@ -198,7 +223,9 @@ export default defineComponent({
};
const isFixedColumn = (label: string) => {
return dynamicColumns.value.filter(item => item.label === label)[0].fixed
return dynamicColumns.value.filter(
item => transformI18n(item.label) === transformI18n(label)
)[0].fixed
? true
: false;
};
@ -225,7 +252,18 @@ export default defineComponent({
return () => (
<>
<div {...attrs} class="w-[99/100] mt-2 px-2 pb-2 bg-bg_color">
<div
{...attrs}
class={[
"w-full",
"px-2",
"pb-2",
"bg-bg_color",
isFullscreen.value
? ["h-full!", "z-2002", "fixed", "inset-0"]
: "mt-2"
]}
>
<div class="flex justify-between w-full h-[60px] p-4">
{slots?.title ? (
slots.title()
@ -279,7 +317,7 @@ export default defineComponent({
>
<div class={[topClass.value]}>
<el-checkbox
class="!-mr-1"
class="-mr-1!"
label="列展示"
v-model={checkAll.value}
indeterminate={isIndeterminate.value}
@ -293,7 +331,8 @@ export default defineComponent({
<div class="pt-[6px] pl-[11px]">
<el-scrollbar max-height="36vh">
<el-checkbox-group
v-model={checkedColumns.value}
ref={`GroupRef${unref(props.tableKey)}`}
modelValue={checkedColumns.value}
onChange={value => handleCheckedColumnsChange(value)}
>
<el-space
@ -301,32 +340,33 @@ export default defineComponent({
alignment="flex-start"
size={0}
>
{checkColumnList.map(item => {
{checkColumnList.map((item, index) => {
return (
<div class="flex items-center">
<DragIcon
class={[
"drag-btn w-[16px] mr-2",
isFixedColumn(item)
? "!cursor-no-drop"
: "!cursor-grab"
? "cursor-no-drop!"
: "cursor-grab!"
]}
onMouseenter={(event: {
preventDefault: () => void;
}) => rowDrop(event)}
/>
<el-checkbox
key={item}
key={index}
label={item}
value={item}
onChange={value =>
handleCheckColumnListChange(value, item)
}
>
<span
title={item}
title={transformI18n(item)}
class="inline-block w-[120px] truncate hover:text-text_color_primary"
>
{item}
{transformI18n(item)}
</span>
</el-checkbox>
</div>
@ -337,6 +377,14 @@ export default defineComponent({
</el-scrollbar>
</div>
</el-popover>
<el-divider direction="vertical" />
<iconifyIconOffline
class={["w-[16px]", iconClass.value]}
icon={isFullscreen.value ? ExitFullscreen : Fullscreen}
v-tippy={isFullscreen.value ? "退出全屏" : "全屏"}
onClick={() => onFullscreen()}
/>
</div>
</div>
{slots.default({

View File

@ -1 +0,0 @@
<svg width="32" height="32" fill="currentColor" aria-hidden="true" data-icon="holder" viewBox="64 64 896 896"><path d="M300 276.5a56 56 0 1 0 56-97 56 56 0 0 0-56 97m0 284a56 56 0 1 0 56-97 56 56 0 0 0-56 97M640 228a56 56 0 1 0 112 0 56 56 0 0 0-112 0m0 284a56 56 0 1 0 112 0 56 56 0 0 0-112 0M300 844.5a56 56 0 1 0 56-97 56 56 0 0 0-56 97M640 796a56 56 0 1 0 112 0 56 56 0 0 0-112 0"/></svg>

Before

Width:  |  Height:  |  Size: 392 B

View File

@ -1,17 +1,17 @@
import {
type PropType,
ref,
unref,
watch,
nextTick,
computed,
type PropType,
defineComponent
} from "vue";
import "./index.scss";
import propTypes from "@/utils/propTypes";
import { isString, cloneDeep } from "@pureadmin/utils";
import QRCode, { type QRCodeRenderersOptions } from "qrcode";
import RefreshRight from "@iconify-icons/ep/refresh-right";
import RefreshRight from "~icons/ep/refresh-right";
interface QrcodeLogo {
src?: string;

View File

@ -1,6 +1,12 @@
<script setup lang="ts">
import { computed, ref, unref, nextTick } from "vue";
import type { CSSProperties, PropType } from "vue";
import {
type PropType,
type CSSProperties,
ref,
unref,
nextTick,
computed
} from "vue";
import {
tryOnMounted,
tryOnUnmounted,
@ -301,7 +307,7 @@ function touchMove(e) {
function touchEnd() {
if (!unref(canTouchScroll)) return;
// eslint-disable-next-line prefer-const
let timer: any;
const direction = unref(options).direction;
delay.value = 50;
@ -496,7 +502,7 @@ defineExpose({
</script>
<template>
<div :ref="'wrap' + props.classOption['key']">
<div :ref="'wrap' + classOption['key']">
<div
v-if="navigation"
:style="leftSwitch"
@ -514,7 +520,7 @@ defineExpose({
<slot name="right-switch" />
</div>
<div
:ref="'realBox' + props.classOption['key']"
:ref="'realBox' + classOption['key']"
:style="pos"
@mouseenter="enter"
@mouseleave="leave"
@ -523,7 +529,7 @@ defineExpose({
@touchend="touchEnd"
@mousewheel.passive="wheel"
>
<div :ref="'slotList' + props.classOption['key']" :style="float">
<div :ref="'slotList' + classOption['key']" :style="float">
<slot />
</div>
<div :style="float" v-html="copyHtml" />

View File

@ -67,6 +67,7 @@ export function copyObj() {
len = arguments.length;
if (typeof target === "boolean") {
deep = target;
// eslint-disable-next-line prefer-rest-params
target = arguments[1] || {};
i++;
@ -80,6 +81,7 @@ export function copyObj() {
}
for (; i < len; i++) {
//所以如果源对象中数据类型为Undefined或Null那么就会跳过本次循环接着循环下一个源对象
// eslint-disable-next-line prefer-rest-params
if ((options = arguments[i]) != null) {
// 如果遇到源对象的数据类型为Boolean, Number for in循环会被跳过不执行for in循环// src用于判断target对象是否存在name属性

View File

@ -1,11 +1,20 @@
.pure-segmented {
--pure-control-padding-horizontal: 12px;
--pure-control-padding-horizontal-sm: 8px;
--pure-segmented-track-padding: 2px;
--pure-segmented-line-width: 1px;
--pure-segmented-border-radius-small: 4px;
--pure-segmented-border-radius-base: 6px;
--pure-segmented-border-radius-large: 8px;
box-sizing: border-box;
display: inline-block;
padding: 2px;
font-size: 14px;
padding: var(--pure-segmented-track-padding);
font-size: var(--el-font-size-base);
color: rgba(0, 0, 0, 0.65);
background-color: rgb(0 0 0 / 4%);
border-radius: 2px;
border-radius: var(--pure-segmented-border-radius-base);
}
.pure-segmented-block {
@ -23,6 +32,74 @@
text-overflow: ellipsis;
}
/* small */
.pure-segmented.pure-segmented--small {
border-radius: var(--pure-segmented-border-radius-small);
}
.pure-segmented.pure-segmented--small .pure-segmented-item {
border-radius: var(--el-border-radius-small);
}
.pure-segmented.pure-segmented--small .pure-segmented-item > div {
min-height: calc(
var(--el-component-size-small) - var(--pure-segmented-track-padding) * 2
);
line-height: calc(
var(--el-component-size-small) - var(--pure-segmented-track-padding) * 2
);
padding: 0
calc(
var(--pure-control-padding-horizontal-sm) -
var(--pure-segmented-line-width)
);
}
/* large */
.pure-segmented.pure-segmented--large {
border-radius: var(--pure-segmented-border-radius-large);
}
.pure-segmented.pure-segmented--large .pure-segmented-item {
border-radius: calc(
var(--el-border-radius-base) + var(--el-border-radius-small)
);
}
.pure-segmented.pure-segmented--large .pure-segmented-item > div {
min-height: calc(
var(--el-component-size-large) - var(--pure-segmented-track-padding) * 2
);
line-height: calc(
var(--el-component-size-large) - var(--pure-segmented-track-padding) * 2
);
padding: 0
calc(
var(--pure-control-padding-horizontal) - var(--pure-segmented-line-width)
);
font-size: var(--el-font-size-medium);
}
/* default */
.pure-segmented-item {
position: relative;
text-align: center;
cursor: pointer;
border-radius: var(--el-border-radius-base);
transition: all 0.1s cubic-bezier(0.645, 0.045, 0.355, 1);
}
.pure-segmented .pure-segmented-item > div {
min-height: calc(
var(--el-component-size) - var(--pure-segmented-track-padding) * 2
);
line-height: calc(
var(--el-component-size) - var(--pure-segmented-track-padding) * 2
);
padding: 0
calc(
var(--pure-control-padding-horizontal) - var(--pure-segmented-line-width)
);
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.pure-segmented-group {
position: relative;
display: flex;
@ -52,23 +129,6 @@
will-change: transform, width;
}
.pure-segmented-item {
position: relative;
text-align: center;
cursor: pointer;
border-radius: 4px;
transition: all 0.1s cubic-bezier(0.645, 0.045, 0.355, 1);
}
.pure-segmented-item > div {
min-height: 28px;
line-height: 28px;
padding: 0 11px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.pure-segmented-item > input {
position: absolute;
inset-block-start: 0;

View File

@ -1,5 +1,14 @@
import "./index.css";
import type { OptionsType } from "./type";
import { useRenderIcon } from "@/components/ReIcon/src/hooks";
import {
useDark,
isNumber,
isFunction,
useResizeObserver
} from "@pureadmin/utils";
import {
type PropType,
h,
ref,
toRef,
@ -8,14 +17,6 @@ import {
defineComponent,
getCurrentInstance
} from "vue";
import type { OptionsType } from "./type";
import { useRenderIcon } from "@/components/ReIcon/src/hooks";
import {
isFunction,
isNumber,
useDark,
useResizeObserver
} from "@pureadmin/utils";
const props = {
options: {
@ -32,6 +33,20 @@ const props = {
block: {
type: Boolean,
default: false
},
/** 控件尺寸 */
size: {
type: String as PropType<"small" | "default" | "large">
},
/** 是否全局禁用,默认 `false` */
disabled: {
type: Boolean,
default: false
},
/** 当内容发生变化时,设置 `resize` 可使其自适应容器位置 */
resize: {
type: Boolean,
default: false
}
};
@ -52,7 +67,7 @@ export default defineComponent({
: ref(0);
function handleChange({ option, index }, event: Event) {
if (option.disabled) return;
if (props.disabled || option.disabled) return;
event.preventDefault();
isNumber(props.modelValue)
? emit("update:modelValue", index)
@ -62,6 +77,7 @@ export default defineComponent({
}
function handleMouseenter({ option, index }, event: Event) {
if (props.disabled) return;
event.preventDefault();
curMouseActive.value = index;
if (option.disabled || curIndex.value === index) {
@ -74,6 +90,7 @@ export default defineComponent({
}
function handleMouseleave(_, event: Event) {
if (props.disabled) return;
event.preventDefault();
curMouseActive.value = -1;
}
@ -81,13 +98,14 @@ export default defineComponent({
function handleInit(index = curIndex.value) {
nextTick(() => {
const curLabelRef = instance?.proxy?.$refs[`labelRef${index}`] as ElRef;
if (!curLabelRef) return;
width.value = curLabelRef.clientWidth;
translateX.value = curLabelRef.offsetLeft;
initStatus.value = true;
});
}
if (props.block) {
function handleResizeInit() {
useResizeObserver(".pure-segmented", () => {
nextTick(() => {
handleInit(curIndex.value);
@ -95,6 +113,8 @@ export default defineComponent({
});
}
(props.block || props.resize) && handleResizeInit();
watch(
() => curIndex.value,
index => {
@ -103,11 +123,14 @@ export default defineComponent({
});
},
{
deep: true,
immediate: true
}
);
watch(() => props.size, handleResizeInit, {
immediate: true
});
const rendLabel = () => {
return props.options.map((option, index) => {
return (
@ -115,14 +138,16 @@ export default defineComponent({
ref={`labelRef${index}`}
class={[
"pure-segmented-item",
option?.disabled && "pure-segmented-item-disabled"
(props.disabled || option?.disabled) &&
"pure-segmented-item-disabled"
]}
style={{
background:
curMouseActive.value === index ? segmentedItembg.value : "",
color:
!option.disabled &&
(curIndex.value === index || curMouseActive.value === index)
color: props.disabled
? null
: !option.disabled &&
(curIndex.value === index || curMouseActive.value === index)
? isDark.value
? "rgba(255, 255, 255, 0.85)"
: "rgba(0,0,0,.88)"
@ -167,7 +192,12 @@ export default defineComponent({
return () => (
<div
class={["pure-segmented", props.block ? "pure-segmented-block" : ""]}
class={{
"pure-segmented": true,
"pure-segmented-block": props.block,
"pure-segmented--large": props.size === "large",
"pure-segmented--small": props.size === "small"
}}
>
<div class="pure-segmented-group">
<div

View File

@ -6,7 +6,7 @@ export interface OptionsType {
label?: string | (() => VNode | Component);
/**
* @description `useRenderIcon`
* @see {@link https://yiming_chang.gitee.io/pure-admin-doc/pages/icon/#%E9%80%9A%E7%94%A8%E5%9B%BE%E6%A0%87-userendericon-hooks }
* @see {@link https://pure-admin.cn/pages/icon/#%E9%80%9A%E7%94%A8%E5%9B%BE%E6%A0%87-userendericon-hooks }
*/
icon?: string | Component;
/** 图标属性、样式配置 */

View File

@ -1,13 +1,13 @@
import "./index.css";
import {
defineComponent,
unref,
computed,
nextTick,
onBeforeMount,
getCurrentInstance,
unref
defineComponent,
getCurrentInstance
} from "vue";
import { addClass, removeClass, toggleClass } from "@pureadmin/utils";
import "./index.css";
const stayClass = "stay"; //鼠标点击
const activeClass = "hs-on"; //鼠标移动上去

View File

@ -39,12 +39,10 @@
(t.innerHTML = i),
(i = null),
(t = t.getElementsByTagName("svg")[0]) &&
(t.setAttribute("aria-hidden", "true"),
(t.style.position = "absolute"),
((t.style.position = "absolute"),
(t.style.width = 0),
(t.style.height = 0),
(t.style.overflow = "hidden"),
// eslint-disable-next-line no-self-assign
(t = t),
(e = document.body).firstChild ? m(t, e.firstChild) : e.appendChild(t));
}),

View File

@ -1,6 +1,6 @@
import { defineComponent, ref, unref, computed, type PropType } from "vue";
import resizer from "./resizer";
import "./index.css";
import resizer from "./resizer";
import { type PropType, defineComponent, ref, unref, computed } from "vue";
export interface ContextProps {
minPercent: number;

View File

@ -1,5 +1,5 @@
import { computed, unref, defineComponent } from "vue";
import "./resizer.css";
import { computed, unref, defineComponent } from "vue";
export default defineComponent({
name: "Resizer",

View File

@ -1,6 +1,10 @@
<script lang="ts" setup>
import { h, onMounted, ref, useSlots } from "vue";
import { useTippy, type TippyOptions } from "vue-tippy";
<script setup lang="ts">
import { h, onMounted, ref } from "vue";
import { type TippyOptions, type TippyContent, useTippy } from "vue-tippy";
defineOptions({
name: "ReText"
});
const props = defineProps({
//
@ -13,7 +17,10 @@ const props = defineProps({
}
});
const $slots = useSlots();
const slots = defineSlots<{
content: () => TippyContent;
default: () => any;
}>();
const textRef = ref();
const tippyFunc = ref();
@ -29,7 +36,7 @@ const isTextEllipsis = (el: HTMLElement) => {
};
const getTippyProps = () => ({
content: h($slots.content || $slots.default),
content: h(slots.content || slots.default),
...props.tippyProps
});

View File

@ -1,8 +1,7 @@
// 参考https://www.npmjs.com/package/element-tree-line (主要是替换需要通过函数传参的方式去注册组件并添加更好的类型支持并移除this.$scopedSlots在3.x中,将所有this.$scopedSlots替换为this.$slots)
import { isFunction } from "@pureadmin/utils";
import { h, defineComponent } from "vue";
import type { PropType } from "vue";
import "./index.scss";
import { isFunction } from "@pureadmin/utils";
import { type PropType, h, defineComponent } from "vue";
import type {
TreeNode,
TreeData,
@ -91,9 +90,9 @@ export default defineComponent({
];
// 取得每一层的当前节点是不是在当前层级列表的最后一个
const lastnodeArr = [];
let currentNode = this.node;
let currentNode: any = this.node;
while (currentNode) {
let parentNode = currentNode.parent;
let parentNode: any = currentNode.parent;
// 兼容element-plus的 el-tree-v2 (Virtualized Tree 虚拟树)
if (currentNode.level === 1 && !currentNode.parent) {
// el-tree-v2的第一层node是没有parent的必需 treeData 创建一个parent

View File

@ -1,6 +1,6 @@
import type { El } from "typeit/dist/types";
import TypeIt, { type Options as TypeItOptions } from "typeit";
import { ref, defineComponent, onMounted, type PropType } from "vue";
import { type PropType, ref, defineComponent, onMounted } from "vue";
// 打字机效果组件(配置项详情请查阅 https://www.typeitjs.com/docs/vanilla/usage#options
export default defineComponent({

View File

@ -0,0 +1,5 @@
import vxeTableBar from "./src/bar";
import { withInstall } from "@pureadmin/utils";
/** 配合 `vxe-table` 实现快速便捷的表格操作 */
export const VxeTableBar = withInstall(vxeTableBar);

View File

@ -0,0 +1,389 @@
import Sortable from "sortablejs";
import { transformI18n } from "@/plugins/i18n";
import { useEpThemeStoreHook } from "@/store/modules/epTheme";
import { delay, cloneDeep, getKeyList } from "@pureadmin/utils";
import {
type PropType,
ref,
unref,
computed,
nextTick,
defineComponent,
getCurrentInstance
} from "vue";
import Fullscreen from "~icons/ri/fullscreen-fill";
import ExitFullscreen from "~icons/ri/fullscreen-exit-fill";
import DragIcon from "@/assets/table-bar/drag.svg?component";
import ExpandIcon from "@/assets/table-bar/expand.svg?component";
import RefreshIcon from "@/assets/table-bar/refresh.svg?component";
import SettingIcon from "@/assets/table-bar/settings.svg?component";
import CollapseIcon from "@/assets/table-bar/collapse.svg?component";
const props = {
/** 头部最左边的标题 */
title: {
type: String,
default: "列表"
},
vxeTableRef: {
type: Object as PropType<any>
},
/** 需要展示的列 */
columns: {
type: Array as PropType<any>,
default: () => []
},
/** 是否为树列表 */
tree: {
type: Boolean,
default: false
},
isExpandAll: {
type: Boolean,
default: true
},
tableKey: {
type: [String, Number] as PropType<string | number>,
default: "0"
}
};
export default defineComponent({
name: "VxeTableBar",
props,
emits: ["refresh", "fullscreen"],
setup(props, { emit, slots, attrs }) {
const size = ref("small");
const loading = ref(false);
const checkAll = ref(true);
const isFullscreen = ref(false);
const isIndeterminate = ref(false);
const instance = getCurrentInstance()!;
const isExpandAll = ref(props.isExpandAll);
let checkColumnList = getKeyList(cloneDeep(props?.columns), "title");
const checkedColumns = ref(getKeyList(cloneDeep(props?.columns), "title"));
const dynamicColumns = ref(cloneDeep(props?.columns));
const getDropdownItemStyle = computed(() => {
return s => {
return {
background:
s === size.value ? useEpThemeStoreHook().epThemeColor : "",
color: s === size.value ? "#fff" : "var(--el-text-color-primary)"
};
};
});
const iconClass = computed(() => {
return [
"text-black",
"dark:text-white",
"duration-100",
"hover:text-primary!",
"cursor-pointer",
"outline-hidden"
];
});
const topClass = computed(() => {
return [
"flex",
"justify-between",
"pt-[3px]",
"px-[11px]",
"border-b-[1px]",
"border-solid",
"border-[#dcdfe6]",
"dark:border-[#303030]"
];
});
function onReFresh() {
loading.value = true;
emit("refresh");
delay(500).then(() => (loading.value = false));
}
function onExpand() {
isExpandAll.value = !isExpandAll.value;
isExpandAll.value
? props.vxeTableRef.setAllTreeExpand(true)
: props.vxeTableRef.clearTreeExpand();
props.vxeTableRef.refreshColumn();
}
function onFullscreen() {
isFullscreen.value = !isFullscreen.value;
emit("fullscreen", isFullscreen.value);
}
function reloadColumn() {
const curCheckedColumns = cloneDeep(dynamicColumns.value).filter(item =>
checkedColumns.value.includes(item.title)
);
props.vxeTableRef.reloadColumn(curCheckedColumns);
}
function handleCheckAllChange(val: boolean) {
checkedColumns.value = val ? checkColumnList : [];
isIndeterminate.value = false;
reloadColumn();
}
function handleCheckedColumnsChange(value: string[]) {
checkedColumns.value = value;
const checkedCount = value.length;
checkAll.value = checkedCount === checkColumnList.length;
isIndeterminate.value =
checkedCount > 0 && checkedCount < checkColumnList.length;
}
async function onReset() {
checkAll.value = true;
isIndeterminate.value = false;
dynamicColumns.value = cloneDeep(props?.columns);
checkColumnList = [];
checkColumnList = await getKeyList(cloneDeep(props?.columns), "title");
checkedColumns.value = getKeyList(cloneDeep(props?.columns), "title");
props.vxeTableRef.refreshColumn();
}
function changeSize(curSize: string) {
size.value = curSize;
props.vxeTableRef.refreshColumn();
}
const dropdown = {
dropdown: () => (
<el-dropdown-menu class="translation">
<el-dropdown-item
style={getDropdownItemStyle.value("medium")}
onClick={() => changeSize("medium")}
>
</el-dropdown-item>
<el-dropdown-item
style={getDropdownItemStyle.value("small")}
onClick={() => changeSize("small")}
>
</el-dropdown-item>
<el-dropdown-item
style={getDropdownItemStyle.value("mini")}
onClick={() => changeSize("mini")}
>
</el-dropdown-item>
</el-dropdown-menu>
)
};
/** 列展示拖拽排序 */
const rowDrop = (event: { preventDefault: () => void }) => {
event.preventDefault();
nextTick(() => {
const wrapper: HTMLElement = (
instance?.proxy?.$refs[`VxeGroupRef${unref(props.tableKey)}`] as any
).$el.firstElementChild;
Sortable.create(wrapper, {
animation: 300,
handle: ".drag-btn",
onEnd: ({ newIndex, oldIndex, item }) => {
const targetThElem = item;
const wrapperElem = targetThElem.parentNode as HTMLElement;
const oldColumn = dynamicColumns.value[oldIndex];
const newColumn = dynamicColumns.value[newIndex];
if (oldColumn?.fixed || newColumn?.fixed) {
// 当前列存在fixed属性 则不可拖拽
const oldThElem = wrapperElem.children[oldIndex] as HTMLElement;
if (newIndex > oldIndex) {
wrapperElem.insertBefore(targetThElem, oldThElem);
} else {
wrapperElem.insertBefore(
targetThElem,
oldThElem ? oldThElem.nextElementSibling : oldThElem
);
}
return;
}
const currentRow = dynamicColumns.value.splice(oldIndex, 1)[0];
dynamicColumns.value.splice(newIndex, 0, currentRow);
reloadColumn();
}
});
});
};
const isFixedColumn = (title: string) => {
return dynamicColumns.value.filter(
item => transformI18n(item.title) === transformI18n(title)
)[0].fixed
? true
: false;
};
const rendTippyProps = (content: string) => {
// https://vue-tippy.netlify.app/props
return {
content,
offset: [0, 18],
duration: [300, 0],
followCursor: true,
hideOnClick: "toggle"
};
};
const reference = {
reference: () => (
<SettingIcon
class={["w-[16px]", iconClass.value]}
v-tippy={rendTippyProps("列设置")}
/>
)
};
return () => (
<>
<div
{...attrs}
class={[
"w-full",
"px-2",
"pb-2",
"bg-bg_color",
isFullscreen.value
? ["h-full!", "z-2002", "fixed", "inset-0"]
: "mt-2"
]}
>
<div class="flex justify-between w-full h-[60px] p-4">
{slots?.title ? (
slots.title()
) : (
<p class="font-bold truncate">{props.title}</p>
)}
<div class="flex items-center justify-around">
{slots?.buttons ? (
<div class="flex mr-4">{slots.buttons()}</div>
) : null}
{props.tree ? (
<>
<ExpandIcon
class={["w-[16px]", iconClass.value]}
style={{
transform: isExpandAll.value ? "none" : "rotate(-90deg)"
}}
v-tippy={rendTippyProps(
isExpandAll.value ? "折叠" : "展开"
)}
onClick={() => onExpand()}
/>
<el-divider direction="vertical" />
</>
) : null}
<RefreshIcon
class={[
"w-[16px]",
iconClass.value,
loading.value ? "animate-spin" : ""
]}
v-tippy={rendTippyProps("刷新")}
onClick={() => onReFresh()}
/>
<el-divider direction="vertical" />
<el-dropdown
v-slots={dropdown}
trigger="click"
v-tippy={rendTippyProps("密度")}
>
<CollapseIcon class={["w-[16px]", iconClass.value]} />
</el-dropdown>
<el-divider direction="vertical" />
<el-popover
v-slots={reference}
placement="bottom-start"
popper-style={{ padding: 0 }}
width="200"
trigger="click"
>
<div class={[topClass.value]}>
<el-checkbox
class="-mr-1!"
label="列展示"
v-model={checkAll.value}
indeterminate={isIndeterminate.value}
onChange={value => handleCheckAllChange(value)}
/>
<el-button type="primary" link onClick={() => onReset()}>
</el-button>
</div>
<div class="pt-[6px] pl-[11px]">
<el-scrollbar max-height="36vh">
<el-checkbox-group
ref={`VxeGroupRef${unref(props.tableKey)}`}
modelValue={checkedColumns.value}
onChange={value => handleCheckedColumnsChange(value)}
>
<el-space
direction="vertical"
alignment="flex-start"
size={0}
>
{checkColumnList.map((item, index) => {
return (
<div class="flex items-center">
<DragIcon
class={[
"drag-btn w-[16px] mr-2",
isFixedColumn(item)
? "cursor-no-drop!"
: "cursor-grab!"
]}
onMouseenter={(event: {
preventDefault: () => void;
}) => rowDrop(event)}
/>
<el-checkbox
key={index}
label={item}
value={item}
onChange={reloadColumn}
>
<span
title={transformI18n(item)}
class="inline-block w-[120px] truncate hover:text-text_color_primary"
>
{transformI18n(item)}
</span>
</el-checkbox>
</div>
);
})}
</el-space>
</el-checkbox-group>
</el-scrollbar>
</div>
</el-popover>
<el-divider direction="vertical" />
<iconifyIconOffline
class={["w-[16px]", iconClass.value]}
icon={isFullscreen.value ? ExitFullscreen : Fullscreen}
v-tippy={isFullscreen.value ? "退出全屏" : "全屏"}
onClick={() => onFullscreen()}
/>
</div>
</div>
{slots.default({
size: size.value,
dynamicColumns: dynamicColumns.value
})}
</div>
</>
);
}
});

View File

@ -1,5 +1,5 @@
import type { App } from "vue";
import axios from "axios";
import type { App } from "vue";
let config: object = {};
const { VITE_PUBLIC_PATH } = import.meta.env;
@ -35,7 +35,7 @@ export const getPlatformConfig = async (app: App): Promise<undefined> => {
})
.then(({ data: config }) => {
let $config = app.config.globalProperties.$config;
// 自动注入项目配置
// 自动注入系统配置
if (app && $config && typeof config === "object") {
$config = Object.assign($config, config);
app.config.globalProperties.$config = $config;

View File

@ -2,7 +2,7 @@ import { hasAuth } from "@/router/utils";
import type { Directive, DirectiveBinding } from "vue";
export const auth: Directive = {
mounted(el: HTMLElement, binding: DirectiveBinding) {
mounted(el: HTMLElement, binding: DirectiveBinding<string | Array<string>>) {
const { value } = binding;
if (value) {
!hasAuth(value) && el.parentNode?.removeChild(el);

View File

@ -3,13 +3,13 @@ import { useEventListener } from "@vueuse/core";
import { copyTextToClipboard } from "@pureadmin/utils";
import type { Directive, DirectiveBinding } from "vue";
interface CopyEl extends HTMLElement {
export interface CopyEl extends HTMLElement {
copyValue: string;
}
/** 文本复制指令(默认双击复制) */
export const copy: Directive = {
mounted(el: CopyEl, binding: DirectiveBinding) {
mounted(el: CopyEl, binding: DirectiveBinding<string>) {
const { value } = binding;
if (value) {
el.copyValue = value;

View File

@ -2,4 +2,5 @@ export * from "./auth";
export * from "./copy";
export * from "./longpress";
export * from "./optimize";
export * from "./perms";
export * from "./ripple";

View File

@ -3,7 +3,7 @@ import type { Directive, DirectiveBinding } from "vue";
import { subBefore, subAfter, isFunction } from "@pureadmin/utils";
export const longpress: Directive = {
mounted(el: HTMLElement, binding: DirectiveBinding) {
mounted(el: HTMLElement, binding: DirectiveBinding<Function>) {
const cb = binding.value;
if (cb && isFunction(cb)) {
let timer = null;

View File

@ -1,16 +1,29 @@
import {
isFunction,
isObject,
isArray,
throttle,
debounce,
throttle
isObject,
isFunction
} from "@pureadmin/utils";
import { useEventListener } from "@vueuse/core";
import type { Directive, DirectiveBinding } from "vue";
export interface OptimizeOptions {
/** 事件名 */
event: string;
/** 事件触发的方法 */
fn: (...params: any) => any;
/** 是否立即执行 */
immediate?: boolean;
/** 防抖或节流的延迟时间(防抖默认:`200`毫秒、节流默认:`1000`毫秒) */
timeout?: number;
/** 传递的参数 */
params?: any;
}
/** 防抖v-optimize或v-optimize:debounce、节流v-optimize:throttle指令 */
export const optimize: Directive = {
mounted(el: HTMLElement, binding: DirectiveBinding) {
mounted(el: HTMLElement, binding: DirectiveBinding<OptimizeOptions>) {
const { value } = binding;
const optimizeType = binding.arg ?? "debounce";
const type = ["debounce", "throttle"].find(t => t === optimizeType);

View File

@ -0,0 +1,15 @@
import { hasPerms } from "@/utils/auth";
import type { Directive, DirectiveBinding } from "vue";
export const perms: Directive = {
mounted(el: HTMLElement, binding: DirectiveBinding<string | Array<string>>) {
const { value } = binding;
if (value) {
!hasPerms(value) && el.parentNode?.removeChild(el);
} else {
throw new Error(
"[Directive: perms]: need perms! Like v-perms=\"['btn.add','btn.edit']\""
);
}
}
};

Some files were not shown because too many files have changed in this diff Show More