Compare commits

...

28 Commits

Author SHA1 Message Date
xiaoxian521
069131a9c8 release: update 6.1.0 2025-07-31 12:07:32 +08:00
xiaoxian521
be4c4a00ec chore: update 2025-07-31 10:57:18 +08:00
xiaoxian521
9fcf54c360 chore: 升级@pureadmin/table兼容最新版element-plus 2025-07-30 16:54:55 +08:00
xiaoxian521
185a5b710a fix: 修复标签页-关闭左侧标签页关闭异常问题 2025-07-24 12:14:03 +08:00
xiaoxian521
baabe42b84 chore: 升级至vite7,更新依赖,相关兼容处理 2025-07-07 13:44:35 +08:00
xiaoxian521
2799cfd8cf chore(deps): update 2025-06-09 16:50:22 +08:00
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
184 changed files with 3917 additions and 3444 deletions

2
.nvmrc
View File

@@ -1 +1 @@
v22.14.0 v22.17.1

View File

@@ -1,8 +1,54 @@
# 6.1.0 (2025-07-31)
### ✔️ Refactor
- Upgrade to `vite7`, update dependencies, and related compatibility processing
### 🐞 Bug fixes
- Fixed a flickering issue in the `ReSegmented` segmented controller component when switching between light and dark styles
- Fixed an issue where `resetRouter` did not clear all routing data
- Fixed an issue where closing the left tab in the tabs window did not work properly
### 🍏 Perf
- Optimized navigation styles
- Upgraded `@pureadmin/table` to be compatible with all `el-table` APIs in the latest `element-plus` version.
# 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) # 5.9.0 (2024-12-10)
### ✔Refactor ### ✔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/max/), it is strongly recommended to upgrade. Subsequent Max version users will enjoy a more modern, beautiful and highly customized theme color - 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) - 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 ### 🎫Feat

View File

@@ -1,8 +1,54 @@
# 6.1.0 (2025-07-31)
### ✔️ Refactor
- Upgrade to `vite7`, update dependencies, and related compatibility processing
### 🐞 Bug fixes
- Fixed a flickering issue in the `ReSegmented` segmented controller component when switching between light and dark styles
- Fixed an issue where `resetRouter` did not clear all routing data
- Fixed an issue where closing the left tab in the tabs window did not work properly
### 🍏 Perf
- Optimized navigation styles
- Upgraded `@pureadmin/table` to be compatible with all `el-table` APIs in the latest `element-plus` version.
# 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) # 5.9.0 (2024-12-10)
### ✔Refactor ### ✔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/max/), it is strongly recommended to upgrade. Subsequent Max version users will enjoy a more modern, beautiful and highly customized theme color - 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) - 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 ### 🎫Feat

View File

@@ -1,8 +1,54 @@
# 6.1.0 (2025-07-31)
### ✔️ Refactor
- 升级至`vite7`,更新依赖,相关兼容处理
### 🐞 Bug fixes
- 修复`ReSegmented`分段控制器组件在浅色和深色整体风格切换时的闪烁问题
- 修复`resetRouter`未清空全部路由数据问题
- 修复标签页-关闭左侧标签页关闭异常问题
### 🍏 Perf
- 优化导航样式
- 升级`@pureadmin/table`兼容最新版`element-plus``el-table`的所有`API`
# 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) # 5.9.0 (2024-12-10)
### ✔️ Refactor ### ✔️ 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/max/) 的用户平台强烈建议升级,后续`Max版本用户`会享有一套更现代、美观且自定义程度高的主题色 - 升级`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) - 使用 [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 ### 🎫 Feat

View File

@@ -31,18 +31,10 @@ The simplified version is based on the shelf extracted from [vue-pure-admin](htt
[Click me to view vue-pure-admin documentation](https://pure-admin.cn/) [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) [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://pure-admin.cn/pages/service/) [Click me for details](https://pure-admin.cn/pages/service/)
## `js` version
[Click me to view js version](https://pure-admin.cn/pages/js/)
## `max` version
[Click me to view the max version](https://pure-admin.cn/pages/max/)
## Tauri ## Tauri
[Click Watch Tauri](https://github.com/pure-admin/tauri-pure-admin) [Click Watch Tauri](https://github.com/pure-admin/tauri-pure-admin)
@@ -192,6 +184,7 @@ Thank you very much for your in-depth understanding of the source code and your
| [edgexie](https://github.com/edgexie) | [code](https://github.com/pure-admin/vue-pure-admin/commits?author=edgexie) | | [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) | | [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) | | [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 ## Git Contribution submission specification

View File

@@ -32,18 +32,10 @@
[点我查看 vue-pure-admin 文档](https://pure-admin.cn/) [点我查看 vue-pure-admin 文档](https://pure-admin.cn/)
[点我查看 @pureadmin/utils 文档](https://pure-admin-utils.netlify.app) [点我查看 @pureadmin/utils 文档](https://pure-admin-utils.netlify.app)
## 优质服务、软件外包、赞助支持 ## 高级服务
[点我查看详情](https://pure-admin.cn/pages/service/) [点我查看详情](https://pure-admin.cn/pages/service/)
## `js` 版本
[点我查看 js 版本](https://pure-admin.cn/pages/js/)
## `max` 版本
[点我查看 max 版本](https://pure-admin.cn/pages/max/)
## `Tauri` 版本 ## `Tauri` 版本
[点我查看 Tauri 版本](https://github.com/pure-admin/tauri-pure-admin) [点我查看 Tauri 版本](https://github.com/pure-admin/tauri-pure-admin)
@@ -193,6 +185,7 @@ docker run -dp 8080:80 --name pure-admin vue-pure-admin
| [edgexie](https://github.com/edgexie) | [代码](https://github.com/pure-admin/vue-pure-admin/commits?author=edgexie) | | [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) | | [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) | | [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` 贡献提交规范 ## `Git` 贡献提交规范

View File

@@ -57,8 +57,8 @@ const include = [
/** /**
* 在预构建中强制排除的依赖项 * 在预构建中强制排除的依赖项
* 温馨提示:所有以 `@iconify-icons/` 开头引入的的本地图标模块,都应该加入到下面的 `exclude` 里,因为平台推荐的使用方式是哪里需要哪里引入而且都是单个的引入,不需要预构建,直接让浏览器加载就好 * 温馨提示:平台推荐的使用方式是哪里需要哪里引入而且都是单个的引入,不需要预构建,直接让浏览器加载就好
*/ */
const exclude = ["@iconify-icons/ep", "@iconify-icons/ri"]; const exclude = ["@iconify/json"];
export { include, exclude }; export { include, exclude };

View File

@@ -3,8 +3,10 @@ import vue from "@vitejs/plugin-vue";
import { pathResolve } from "./utils"; import { pathResolve } from "./utils";
import { viteBuildInfo } from "./info"; import { viteBuildInfo } from "./info";
import svgLoader from "vite-svg-loader"; import svgLoader from "vite-svg-loader";
import Icons from "unplugin-icons/vite";
import type { PluginOption } from "vite"; import type { PluginOption } from "vite";
import vueJsx from "@vitejs/plugin-vue-jsx"; import vueJsx from "@vitejs/plugin-vue-jsx";
import tailwindcss from "@tailwindcss/vite";
import { configCompressPlugin } from "./compress"; import { configCompressPlugin } from "./compress";
import removeNoMatch from "vite-plugin-router-warn"; import removeNoMatch from "vite-plugin-router-warn";
import { visualizer } from "rollup-plugin-visualizer"; import { visualizer } from "rollup-plugin-visualizer";
@@ -19,6 +21,7 @@ export function getPluginsList(
): PluginOption[] { ): PluginOption[] {
const lifecycle = process.env.npm_lifecycle_event; const lifecycle = process.env.npm_lifecycle_event;
return [ return [
tailwindcss(),
vue({ vue({
template: { template: {
compilerOptions: { compilerOptions: {
@@ -57,6 +60,11 @@ export function getPluginsList(
}), }),
// svg组件化支持 // svg组件化支持
svgLoader(), svgLoader(),
// 自动按需加载图标
Icons({
compiler: "vue3",
scale: 1
}),
VITE_CDN ? cdn : null, VITE_CDN ? cdn : null,
configCompressPlugin(VITE_COMPRESSION), configCompressPlugin(VITE_COMPRESSION),
// 线上环境删除console // 线上环境删除console

View File

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

View File

@@ -25,7 +25,7 @@ export default defineFakeRoute([
url: "/mine-logs", url: "/mine-logs",
method: "get", method: "get",
response: () => { response: () => {
let list = [ const list = [
{ {
id: 1, id: 1,
ip: faker.internet.ipv4(), ip: faker.internet.ipv4(),

View File

@@ -1,6 +1,6 @@
{ {
"name": "vue-pure-admin", "name": "vue-pure-admin",
"version": "5.9.0", "version": "6.1.0",
"private": true, "private": true,
"type": "module", "type": "module",
"scripts": { "scripts": {
@@ -48,142 +48,141 @@
}, },
"dependencies": { "dependencies": {
"@amap/amap-jsapi-loader": "^1.0.1", "@amap/amap-jsapi-loader": "^1.0.1",
"@howdyjs/mouse-menu": "^2.1.6", "@howdyjs/mouse-menu": "^2.1.7",
"@infectoone/vue-ganttastic": "^2.3.2", "@infectoone/vue-ganttastic": "^2.3.2",
"@logicflow/core": "^1.2.28", "@logicflow/core": "^1.2.28",
"@logicflow/extension": "^1.2.28", "@logicflow/extension": "^1.2.28",
"@pureadmin/descriptions": "^1.2.1", "@pureadmin/descriptions": "^1.2.1",
"@pureadmin/table": "^3.2.1", "@pureadmin/table": "^3.3.0",
"@pureadmin/utils": "^2.5.0", "@pureadmin/utils": "^2.6.2",
"@vue-flow/background": "^1.3.2", "@vue-flow/background": "^1.3.2",
"@vue-flow/core": "^1.42.1", "@vue-flow/core": "^1.45.0",
"@vueuse/core": "^12.5.0", "@vueuse/core": "^13.6.0",
"@vueuse/motion": "^2.2.6", "@vueuse/motion": "^3.0.3",
"@wangeditor/editor": "^5.1.23", "@wangeditor/editor": "^5.1.23",
"@wangeditor/editor-for-vue": "^5.1.12", "@wangeditor/editor-for-vue": "^5.1.12",
"@zxcvbn-ts/core": "^3.0.4", "@zxcvbn-ts/core": "^3.0.4",
"animate.css": "^4.1.1", "animate.css": "^4.1.1",
"axios": "^1.7.9", "axios": "^1.11.0",
"china-area-data": "^5.0.1", "china-area-data": "^5.0.1",
"codemirror": "^5.65.18", "codemirror": "^5.65.19",
"codemirror-editor-vue3": "^2.8.0", "codemirror-editor-vue3": "^2.8.0",
"cropperjs": "^1.6.2", "cropperjs": "^1.6.2",
"dayjs": "^1.11.13", "dayjs": "^1.11.13",
"deep-chat": "^2.1.1", "deep-chat": "^2.2.2",
"echarts": "^5.6.0", "echarts": "^5.6.0",
"el-table-infinite-scroll": "^3.0.6", "el-table-infinite-scroll": "^3.0.6",
"element-plus": "^2.9.4", "element-plus": "^2.10.4",
"highlight.js": "^11.11.1", "highlight.js": "^11.11.1",
"intro.js": "^7.2.0", "intro.js": "^7.2.0",
"js-cookie": "^3.0.5", "js-cookie": "^3.0.5",
"jsbarcode": "^3.11.6", "jsbarcode": "^3.12.1",
"localforage": "^1.10.0", "localforage": "^1.10.0",
"mint-filter": "^4.0.3", "mint-filter": "^4.0.3",
"mitt": "^3.0.1", "mitt": "^3.0.1",
"mqtt": "4.3.7", "mqtt": "4.3.7",
"nprogress": "^0.2.0", "nprogress": "^0.2.0",
"path-browserify": "^1.0.1", "path-browserify": "^1.0.1",
"pinia": "^3.0.1", "pinia": "^3.0.3",
"pinyin-pro": "^3.26.0", "pinyin-pro": "^3.26.0",
"plus-pro-components": "^0.1.20", "plus-pro-components": "^0.1.26",
"qrcode": "^1.5.4", "qrcode": "^1.5.4",
"qs": "^6.14.0", "qs": "^6.14.0",
"responsive-storage": "^2.2.0", "responsive-storage": "^2.2.0",
"sortablejs": "^1.15.6", "sortablejs": "^1.15.6",
"swiper": "^11.2.3", "swiper": "^11.2.10",
"typeit": "^8.8.7", "typeit": "^8.8.7",
"v-contextmenu": "^3.2.0", "v-contextmenu": "^3.2.0",
"v3-infinite-loading": "^1.3.2", "v3-infinite-loading": "^1.3.2",
"vditor": "^3.10.9", "vditor": "^3.11.1",
"version-rocket": "^1.7.4", "version-rocket": "^1.7.4",
"vue": "^3.5.13", "vue": "^3.5.18",
"vue-i18n": "^11.1.1", "vue-i18n": "^11.1.11",
"vue-json-pretty": "^2.4.0", "vue-json-pretty": "^2.5.0",
"vue-pdf-embed": "^2.1.2", "vue-pdf-embed": "^2.1.3",
"vue-router": "^4.5.0", "vue-router": "^4.5.1",
"vue-tippy": "^6.6.0", "vue-tippy": "^6.7.1",
"vue-types": "^5.1.3", "vue-types": "^6.0.0",
"vue-virtual-scroller": "2.0.0-beta.8", "vue-virtual-scroller": "2.0.0-beta.8",
"vue-waterfall-plugin-next": "^2.6.5", "vue-waterfall-plugin-next": "^2.6.7",
"vue3-danmaku": "^1.6.1", "vue3-danmaku": "^1.6.6",
"vue3-puzzle-vcode": "^1.1.7", "vue3-puzzle-vcode": "^1.1.7",
"vuedraggable": "^4.1.0", "vuedraggable": "^4.1.0",
"vxe-table": "4.6.25", "vxe-table": "4.6.25",
"wavesurfer.js": "^7.9.1", "wavesurfer.js": "^7.10.1",
"xgplayer": "^3.0.20", "xgplayer": "^3.0.22",
"xlsx": "^0.18.5" "xlsx": "^0.18.5"
}, },
"devDependencies": { "devDependencies": {
"@commitlint/cli": "^19.7.1", "@commitlint/cli": "^19.8.1",
"@commitlint/config-conventional": "^19.7.1", "@commitlint/config-conventional": "^19.8.1",
"@commitlint/types": "^19.5.0", "@commitlint/types": "^19.8.1",
"@eslint/js": "^9.20.0", "@eslint/js": "^9.32.0",
"@faker-js/faker": "^9.5.0", "@faker-js/faker": "^9.9.0",
"@iconify-icons/ep": "^1.2.12", "@iconify/json": "^2.2.364",
"@iconify-icons/ri": "^1.2.10",
"@iconify/vue": "4.2.0", "@iconify/vue": "4.2.0",
"@intlify/unplugin-vue-i18n": "^6.0.3", "@intlify/unplugin-vue-i18n": "^6.0.8",
"@types/codemirror": "^5.60.15", "@tailwindcss/vite": "^4.1.11",
"@types/dagre": "^0.7.52", "@types/codemirror": "^5.60.16",
"@types/dagre": "^0.7.53",
"@types/intro.js": "^5.1.5", "@types/intro.js": "^5.1.5",
"@types/js-cookie": "^3.0.6", "@types/js-cookie": "^3.0.6",
"@types/node": "^20.17.19", "@types/node": "^20.19.9",
"@types/nprogress": "^0.2.3", "@types/nprogress": "^0.2.3",
"@types/path-browserify": "^1.0.3", "@types/path-browserify": "^1.0.3",
"@types/qrcode": "^1.5.5", "@types/qrcode": "^1.5.5",
"@types/qs": "^6.9.18", "@types/qs": "^6.14.0",
"@types/sortablejs": "^1.15.8", "@types/sortablejs": "^1.15.8",
"@typescript-eslint/eslint-plugin": "^8.24.0", "@vitejs/plugin-vue": "^6.0.1",
"@typescript-eslint/parser": "^8.24.0", "@vitejs/plugin-vue-jsx": "^5.0.1",
"@vitejs/plugin-vue": "^5.2.1",
"@vitejs/plugin-vue-jsx": "^4.1.1",
"autoprefixer": "^10.4.20",
"boxen": "^8.0.1", "boxen": "^8.0.1",
"code-inspector-plugin": "^0.20.0", "code-inspector-plugin": "^1.0.3",
"cssnano": "^7.0.6", "cssnano": "^7.1.0",
"dagre": "^0.8.5", "dagre": "^0.8.5",
"eslint": "^9.20.1", "eslint": "^9.32.0",
"eslint-config-prettier": "^10.0.1", "eslint-config-prettier": "^10.1.8",
"eslint-define-config": "^2.1.0", "eslint-plugin-prettier": "^5.5.3",
"eslint-plugin-prettier": "^5.2.3", "eslint-plugin-vue": "^10.3.0",
"eslint-plugin-vue": "^9.32.0",
"gradient-string": "^3.0.0", "gradient-string": "^3.0.0",
"husky": "^9.1.7", "husky": "^9.1.7",
"lint-staged": "^15.4.3", "lint-staged": "^16.1.2",
"postcss": "^8.5.2", "postcss": "^8.5.6",
"postcss-html": "^1.8.0", "postcss-html": "^1.8.0",
"postcss-import": "^16.1.0", "postcss-load-config": "^6.0.1",
"postcss-scss": "^4.0.9", "postcss-scss": "^4.0.9",
"prettier": "^3.5.1", "prettier": "^3.6.2",
"rimraf": "^6.0.1", "rimraf": "^6.0.1",
"rollup-plugin-visualizer": "^5.14.0", "rollup-plugin-visualizer": "^6.0.3",
"sass": "^1.85.0", "sass": "^1.89.2",
"stylelint": "^16.14.1", "stylelint": "^16.23.0",
"stylelint-config-recess-order": "^6.0.0", "stylelint-config-recess-order": "^7.1.0",
"stylelint-config-recommended-vue": "^1.6.0", "stylelint-config-recommended-vue": "^1.6.1",
"stylelint-config-standard-scss": "^14.0.0", "stylelint-config-standard-scss": "^14.0.0",
"stylelint-prettier": "^5.0.3", "stylelint-prettier": "^5.0.3",
"svgo": "^3.3.2", "svgo": "^4.0.0",
"tailwindcss": "3.4.17", "tailwindcss": "^4.1.11",
"typescript": "^5.7.3", "typescript": "^5.8.3",
"vite": "^6.1.0", "typescript-eslint": "^8.38.0",
"unplugin-icons": "^22.2.0",
"vite": "^7.0.6",
"vite-plugin-cdn-import": "^1.0.1", "vite-plugin-cdn-import": "^1.0.1",
"vite-plugin-compression": "^0.5.1", "vite-plugin-compression": "^0.5.1",
"vite-plugin-fake-server": "^2.2.0", "vite-plugin-fake-server": "^2.2.0",
"vite-plugin-remove-console": "^2.2.0", "vite-plugin-remove-console": "^2.2.0",
"vite-plugin-router-warn": "^1.0.0", "vite-plugin-router-warn": "^1.0.0",
"vite-svg-loader": "^5.1.0", "vite-svg-loader": "^5.1.0",
"vue-eslint-parser": "^9.4.3", "vue-eslint-parser": "^10.2.0",
"vue-tsc": "^2.2.0" "vue-tsc": "^3.0.4"
}, },
"engines": { "engines": {
"node": "^18.18.0 || ^20.9.0 || >=22.0.0", "node": "^20.19.0 || >=22.12.0",
"pnpm": ">=9" "pnpm": ">=9"
}, },
"pnpm": { "pnpm": {
"allowedDeprecatedVersions": { "allowedDeprecatedVersions": {
"are-we-there-yet": "*", "are-we-there-yet": "*",
"sourcemap-codec": "*", "sourcemap-codec": "*",
"lodash.isequal": "*",
"domexception": "*", "domexception": "*",
"w3c-hr-time": "*", "w3c-hr-time": "*",
"inflight": "*", "inflight": "*",
@@ -194,11 +193,6 @@
"abab": "*", "abab": "*",
"glob": "*" "glob": "*"
}, },
"peerDependencyRules": {
"allowedVersions": {
"eslint": "9"
}
},
"onlyBuiltDependencies": [ "onlyBuiltDependencies": [
"@parcel/watcher", "@parcel/watcher",
"core-js", "core-js",
@@ -206,6 +200,10 @@
"esbuild", "esbuild",
"typeit", "typeit",
"vue-demi" "vue-demi"
],
"ignoredBuiltDependencies": [
"@tailwindcss/oxide",
"vue3-danmaku"
] ]
} }
} }

5528
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} */ /** @type {import('postcss-load-config').Config} */
export default { export default {
plugins: { plugins: {
"postcss-import": {},
"tailwindcss/nesting": {},
tailwindcss: {},
autoprefixer: {},
...(process.env.NODE_ENV === "production" ? { cssnano: {} } : {}) ...(process.env.NODE_ENV === "production" ? { cssnano: {} } : {})
} }
}; };

View File

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

File diff suppressed because one or more lines are too long

View File

@@ -95,7 +95,7 @@ function onMouseleave() {
:view-style="{ overflow: 'hidden' }" :view-style="{ overflow: 'hidden' }"
class="border-t border-[#e5e7eb]" class="border-t border-[#e5e7eb]"
> >
<ul class="flex flex-wrap justify-around mb-1"> <ul class="flex flex-wrap justify-around mb-1!">
<li <li
v-for="(animate, index) in animatesList" v-for="(animate, index) in animatesList"
:key="index" :key="index"

View File

@@ -119,7 +119,7 @@ export default defineComponent({
"p-[6px]", "p-[6px]",
"h-[30px]", "h-[30px]",
"w-[30px]", "w-[30px]",
"outline-none", "outline-hidden",
"rounded-[4px]", "rounded-[4px]",
"cursor-pointer", "cursor-pointer",
"hover:bg-[rgba(0,0,0,0.06)]" "hover:bg-[rgba(0,0,0,0.06)]"

View File

@@ -8,8 +8,8 @@ import {
} from "./index"; } from "./index";
import { ref, computed } from "vue"; import { ref, computed } from "vue";
import { isFunction } from "@pureadmin/utils"; import { isFunction } from "@pureadmin/utils";
import Fullscreen from "@iconify-icons/ri/fullscreen-fill"; import Fullscreen from "~icons/ri/fullscreen-fill";
import ExitFullscreen from "@iconify-icons/ri/fullscreen-exit-fill"; import ExitFullscreen from "~icons/ri/fullscreen-exit-fill";
defineOptions({ defineOptions({
name: "ReDialog" name: "ReDialog"
@@ -79,7 +79,7 @@ const fullscreenClass = computed(() => {
"el-dialog__close", "el-dialog__close",
"-translate-x-2", "-translate-x-2",
"cursor-pointer", "cursor-pointer",
"hover:!text-[red]" "hover:text-[red]!"
]; ];
}); });

View File

@@ -3,7 +3,7 @@ import { ref, unref, onMounted } from "vue";
import { LogicFlow } from "@logicflow/core"; import { LogicFlow } from "@logicflow/core";
interface Props { interface Props {
lf: LogicFlow; lf?: LogicFlow;
catTurboData?: boolean; catTurboData?: boolean;
} }
@@ -114,7 +114,8 @@ onMounted(() => {
:style="{ :style="{
cursor: item.disabled === false ? 'pointer' : 'not-allowed', cursor: item.disabled === false ? 'pointer' : 'not-allowed',
color: item.disabled === false ? '' : '#00000040', color: item.disabled === false ? '' : '#00000040',
background: 'transparent' background: 'transparent',
border: 'none'
}" }"
@click="onControl(item, key)" @click="onControl(item, key)"
> >

View File

@@ -9,8 +9,8 @@ type nodeListType = {
}; };
interface Props { interface Props {
lf: LogicFlow; lf?: LogicFlow;
nodeList: Array<nodeListType>; nodeList?: Array<nodeListType>;
} }
const props = withDefaults(defineProps<Props>(), { const props = withDefaults(defineProps<Props>(), {

View File

@@ -23,9 +23,9 @@
function h() { function h() {
n || ((n = !0), o()); n || ((n = !0), o());
} }
(t = function () { ((t = function () {
var c, t, e, o; var c, t, e, o;
((o = document.createElement("div")).innerHTML = i), (((o = document.createElement("div")).innerHTML = i),
(i = null), (i = null),
(e = o.getElementsByTagName("svg")[0]) && (e = o.getElementsByTagName("svg")[0]) &&
((e.style.position = "absolute"), ((e.style.position = "absolute"),
@@ -35,13 +35,13 @@
(c = e), (c = e),
(t = document.body).firstChild (t = document.body).firstChild
? ((o = c), (e = t.firstChild).parentNode.insertBefore(o, e)) ? ((o = c), (e = t.firstChild).parentNode.insertBefore(o, e))
: t.appendChild(c)); : t.appendChild(c)));
}), }),
document.addEventListener document.addEventListener
? ~["complete", "loaded", "interactive"].indexOf(document.readyState) ? ~["complete", "loaded", "interactive"].indexOf(document.readyState)
? setTimeout(t, 0) ? setTimeout(t, 0)
: ((e = function () { : ((e = function () {
document.removeEventListener("DOMContentLoaded", e, !1), t(); (document.removeEventListener("DOMContentLoaded", e, !1), t());
}), }),
document.addEventListener("DOMContentLoaded", e, !1)) document.addEventListener("DOMContentLoaded", e, !1))
: document.attachEvent && : document.attachEvent &&
@@ -58,5 +58,5 @@
})(), })(),
(a.onreadystatechange = function () { (a.onreadystatechange = function () {
"complete" == a.readyState && ((a.onreadystatechange = null), h()); "complete" == a.readyState && ((a.onreadystatechange = null), h());
})); })));
})(window); })(window);

View File

@@ -2,7 +2,7 @@
import { IconJson } from "@/components/ReIcon/data"; import { IconJson } from "@/components/ReIcon/data";
import { cloneDeep, isAllEmpty } from "@pureadmin/utils"; import { cloneDeep, isAllEmpty } from "@pureadmin/utils";
import { ref, computed, CSSProperties, watch } from "vue"; 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; type ParameterCSSProperties = (item?: string) => CSSProperties | undefined;
@@ -158,7 +158,7 @@ watch(
:name="pane.name" :name="pane.name"
> >
<el-scrollbar height="220px"> <el-scrollbar height="220px">
<ul class="flex flex-wrap px-2 ml-2"> <ul class="flex flex-wrap px-2! ml-2!">
<li <li
v-for="(item, key) in pageList" v-for="(item, key) in pageList"
:key="key" :key="key"
@@ -198,7 +198,7 @@ watch(
@current-change="onCurrentChange" @current-change="onCurrentChange"
/> />
<el-button <el-button
class="justify-end mr-2 ml-2" class="justify-end mx-2!"
type="danger" type="danger"
size="small" size="small"
text text

View File

@@ -1,6 +1,6 @@
import type { iconType } from "./types"; import type { iconType } from "./types";
import { h, defineComponent, type Component } from "vue"; import { h, defineComponent, type Component } from "vue";
import { IconifyIconOnline, IconifyIconOffline, FontIcon } from "../index"; import { FontIcon, IconifyIconOnline, IconifyIconOffline } from "../index";
/** /**
* 支持 `iconfont`、自定义 `svg` 以及 `iconify` 中所有的图标 * 支持 `iconfont`、自定义 `svg` 以及 `iconify` 中所有的图标
@@ -49,10 +49,12 @@ export function useRenderIcon(icon: any, attrs?: iconType): Component {
return defineComponent({ return defineComponent({
name: "Icon", name: "Icon",
render() { render() {
const IconifyIcon = if (!icon) return;
icon && icon.includes(":") ? IconifyIconOnline : IconifyIconOffline; const IconifyIcon = icon.includes(":")
? IconifyIconOnline
: IconifyIconOffline;
return h(IconifyIcon, { return h(IconifyIcon, {
icon: icon, icon,
...attrs ...attrs
}); });
} }

View File

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

View File

@@ -1,70 +1,87 @@
// 这里存放本地图标,在 src/layout/index.vue 文件中加载,避免在首启动加载 // 这里存放本地图标,在 src/layout/index.vue 文件中加载,避免在首启动加载
import { getSvgInfo } from "@pureadmin/utils";
import { addIcon } from "@iconify/vue/dist/offline"; 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 添加即可渲染菜单图标 // 本地菜单图标,后端在路由的 icon 中返回对应的图标字符串并且前端在此处使用 addIcon 添加即可渲染菜单图标
// @iconify-icons/ep icons.forEach(([name, icon]) => {
import Menu from "@iconify-icons/ep/menu"; addIcon(name as string, getSvgInfo(icon as string));
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 MindMap from "@iconify-icons/ri/mind-map";
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:mind-map", MindMap);
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);

View File

@@ -18,8 +18,8 @@ import {
getKeyList getKeyList
} from "@pureadmin/utils"; } from "@pureadmin/utils";
import Fullscreen from "@iconify-icons/ri/fullscreen-fill"; import Fullscreen from "~icons/ri/fullscreen-fill";
import ExitFullscreen from "@iconify-icons/ri/fullscreen-exit-fill"; import ExitFullscreen from "~icons/ri/fullscreen-exit-fill";
import DragIcon from "@/assets/table-bar/drag.svg?component"; import DragIcon from "@/assets/table-bar/drag.svg?component";
import ExpandIcon from "@/assets/table-bar/expand.svg?component"; import ExpandIcon from "@/assets/table-bar/expand.svg?component";
import RefreshIcon from "@/assets/table-bar/refresh.svg?component"; import RefreshIcon from "@/assets/table-bar/refresh.svg?component";
@@ -87,9 +87,9 @@ export default defineComponent({
"text-black", "text-black",
"dark:text-white", "dark:text-white",
"duration-100", "duration-100",
"hover:!text-primary", "hover:text-primary!",
"cursor-pointer", "cursor-pointer",
"outline-none" "outline-hidden"
]; ];
}); });
@@ -255,12 +255,12 @@ export default defineComponent({
<div <div
{...attrs} {...attrs}
class={[ class={[
"w-[99/100]", "w-full",
"px-2", "px-2",
"pb-2", "pb-2",
"bg-bg_color", "bg-bg_color",
isFullscreen.value isFullscreen.value
? ["!w-full", "!h-full", "z-[2002]", "fixed", "inset-0"] ? ["h-full!", "z-2002", "fixed", "inset-0"]
: "mt-2" : "mt-2"
]} ]}
> >
@@ -317,7 +317,7 @@ export default defineComponent({
> >
<div class={[topClass.value]}> <div class={[topClass.value]}>
<el-checkbox <el-checkbox
class="!-mr-1" class="-mr-1!"
label="列展示" label="列展示"
v-model={checkAll.value} v-model={checkAll.value}
indeterminate={isIndeterminate.value} indeterminate={isIndeterminate.value}
@@ -347,8 +347,8 @@ export default defineComponent({
class={[ class={[
"drag-btn w-[16px] mr-2", "drag-btn w-[16px] mr-2",
isFixedColumn(item) isFixedColumn(item)
? "!cursor-no-drop" ? "cursor-no-drop!"
: "!cursor-grab" : "cursor-grab!"
]} ]}
onMouseenter={(event: { onMouseenter={(event: {
preventDefault: () => void; preventDefault: () => void;

View File

@@ -11,7 +11,7 @@ import "./index.scss";
import propTypes from "@/utils/propTypes"; import propTypes from "@/utils/propTypes";
import { isString, cloneDeep } from "@pureadmin/utils"; import { isString, cloneDeep } from "@pureadmin/utils";
import QRCode, { type QRCodeRenderersOptions } from "qrcode"; import QRCode, { type QRCodeRenderersOptions } from "qrcode";
import RefreshRight from "@iconify-icons/ep/refresh-right"; import RefreshRight from "~icons/ep/refresh-right";
interface QrcodeLogo { interface QrcodeLogo {
src?: string; src?: string;

View File

@@ -60,12 +60,15 @@ export function copyObj() {
copyIsArray, copyIsArray,
clone, clone,
i = 1, i = 1,
// eslint-disable-next-line prefer-rest-params
target = arguments[0] || {}, // 使用||运算符排除隐式强制类型转换为false的数据类型 target = arguments[0] || {}, // 使用||运算符排除隐式强制类型转换为false的数据类型
deep = false, deep = false,
// eslint-disable-next-line prefer-const
len = arguments.length; len = arguments.length;
if (typeof target === "boolean") { if (typeof target === "boolean") {
deep = target; deep = target;
// eslint-disable-next-line prefer-rest-params
target = arguments[1] || {}; target = arguments[1] || {};
i++; i++;
} }
@@ -79,6 +82,7 @@ export function copyObj() {
for (; i < len; i++) { for (; i < len; i++) {
//所以如果源对象中数据类型为Undefined或Null那么就会跳过本次循环接着循环下一个源对象 //所以如果源对象中数据类型为Undefined或Null那么就会跳过本次循环接着循环下一个源对象
// eslint-disable-next-line prefer-rest-params
if ((options = arguments[i]) != null) { if ((options = arguments[i]) != null) {
// 如果遇到源对象的数据类型为Boolean, Number for in循环会被跳过不执行for in循环// src用于判断target对象是否存在name属性 // 如果遇到源对象的数据类型为Boolean, Number for in循环会被跳过不执行for in循环// src用于判断target对象是否存在name属性
for (name in options) { for (name in options) {

View File

@@ -98,7 +98,6 @@
overflow: hidden; overflow: hidden;
white-space: nowrap; white-space: nowrap;
text-overflow: ellipsis; text-overflow: ellipsis;
transition: 0.1s;
} }
.pure-segmented-group { .pure-segmented-group {

View File

@@ -33,10 +33,10 @@
} }
l(); l();
} }
(t = function () { ((t = function () {
var e, var e,
t = document.createElement("div"); t = document.createElement("div");
(t.innerHTML = i), ((t.innerHTML = i),
(i = null), (i = null),
(t = t.getElementsByTagName("svg")[0]) && (t = t.getElementsByTagName("svg")[0]) &&
((t.style.position = "absolute"), ((t.style.position = "absolute"),
@@ -44,13 +44,15 @@
(t.style.height = 0), (t.style.height = 0),
(t.style.overflow = "hidden"), (t.style.overflow = "hidden"),
(t = t), (t = t),
(e = document.body).firstChild ? m(t, e.firstChild) : e.appendChild(t)); (e = document.body).firstChild
? m(t, e.firstChild)
: e.appendChild(t)));
}), }),
document.addEventListener document.addEventListener
? ~["complete", "loaded", "interactive"].indexOf(document.readyState) ? ~["complete", "loaded", "interactive"].indexOf(document.readyState)
? setTimeout(t, 0) ? setTimeout(t, 0)
: ((n = function () { : ((n = function () {
document.removeEventListener("DOMContentLoaded", n, !1), t(); (document.removeEventListener("DOMContentLoaded", n, !1), t());
}), }),
document.addEventListener("DOMContentLoaded", n, !1)) document.addEventListener("DOMContentLoaded", n, !1))
: document.attachEvent && : document.attachEvent &&
@@ -60,5 +62,5 @@
a(), a(),
(o.onreadystatechange = function () { (o.onreadystatechange = function () {
"complete" == o.readyState && ((o.onreadystatechange = null), l()); "complete" == o.readyState && ((o.onreadystatechange = null), l());
})); })));
})(window); })(window);

View File

@@ -12,8 +12,8 @@ import {
getCurrentInstance getCurrentInstance
} from "vue"; } from "vue";
import Fullscreen from "@iconify-icons/ri/fullscreen-fill"; import Fullscreen from "~icons/ri/fullscreen-fill";
import ExitFullscreen from "@iconify-icons/ri/fullscreen-exit-fill"; import ExitFullscreen from "~icons/ri/fullscreen-exit-fill";
import DragIcon from "@/assets/table-bar/drag.svg?component"; import DragIcon from "@/assets/table-bar/drag.svg?component";
import ExpandIcon from "@/assets/table-bar/expand.svg?component"; import ExpandIcon from "@/assets/table-bar/expand.svg?component";
import RefreshIcon from "@/assets/table-bar/refresh.svg?component"; import RefreshIcon from "@/assets/table-bar/refresh.svg?component";
@@ -80,9 +80,9 @@ export default defineComponent({
"text-black", "text-black",
"dark:text-white", "dark:text-white",
"duration-100", "duration-100",
"hover:!text-primary", "hover:text-primary!",
"cursor-pointer", "cursor-pointer",
"outline-none" "outline-hidden"
]; ];
}); });
@@ -248,12 +248,12 @@ export default defineComponent({
<div <div
{...attrs} {...attrs}
class={[ class={[
"w-[99/100]", "w-full",
"px-2", "px-2",
"pb-2", "pb-2",
"bg-bg_color", "bg-bg_color",
isFullscreen.value isFullscreen.value
? ["!w-full", "!h-full", "z-[2002]", "fixed", "inset-0"] ? ["h-full!", "z-2002", "fixed", "inset-0"]
: "mt-2" : "mt-2"
]} ]}
> >
@@ -310,7 +310,7 @@ export default defineComponent({
> >
<div class={[topClass.value]}> <div class={[topClass.value]}>
<el-checkbox <el-checkbox
class="!-mr-1" class="-mr-1!"
label="列展示" label="列展示"
v-model={checkAll.value} v-model={checkAll.value}
indeterminate={isIndeterminate.value} indeterminate={isIndeterminate.value}
@@ -340,8 +340,8 @@ export default defineComponent({
class={[ class={[
"drag-btn w-[16px] mr-2", "drag-btn w-[16px] mr-2",
isFixedColumn(item) isFixedColumn(item)
? "!cursor-no-drop" ? "cursor-no-drop!"
: "!cursor-grab" : "cursor-grab!"
]} ]}
onMouseenter={(event: { onMouseenter={(event: {
preventDefault: () => void; preventDefault: () => void;

View File

@@ -13,10 +13,10 @@ $ripple-animation-visible-opacity: 0.25 !default;
z-index: 0; z-index: 0;
width: 100%; width: 100%;
height: 100%; height: 100%;
contain: strict;
overflow: hidden; overflow: hidden;
pointer-events: none; pointer-events: none;
border-radius: inherit; border-radius: inherit;
contain: strict;
} }
&__animation { &__animation {

View File

@@ -32,8 +32,8 @@ const calculate = (
const offset = el.getBoundingClientRect(); const offset = el.getBoundingClientRect();
// 获取点击位置距离 el 的垂直和水平距离 // 获取点击位置距离 el 的垂直和水平距离
let localX = e.clientX - offset.left; const localX = e.clientX - offset.left;
let localY = e.clientY - offset.top; const localY = e.clientY - offset.top;
let radius = 0; let radius = 0;
let scale = 0.3; let scale = 0.3;

View File

@@ -10,7 +10,7 @@ const TITLE = getConfig("Title");
> >
Copyright © 2020-present Copyright © 2020-present
<a <a
class="hover:text-primary" class="hover:text-primary!"
href="https://github.com/pure-admin" href="https://github.com/pure-admin"
target="_blank" target="_blank"
> >

View File

@@ -9,10 +9,10 @@ import LaySidebarBreadCrumb from "../lay-sidebar/components/SidebarBreadCrumb.vu
import LaySidebarTopCollapse from "../lay-sidebar/components/SidebarTopCollapse.vue"; import LaySidebarTopCollapse from "../lay-sidebar/components/SidebarTopCollapse.vue";
import GlobalizationIcon from "@/assets/svg/globalization.svg?component"; import GlobalizationIcon from "@/assets/svg/globalization.svg?component";
import AccountSettingsIcon from "@iconify-icons/ri/user-settings-line"; import AccountSettingsIcon from "~icons/ri/user-settings-line";
import LogoutCircleRLine from "@iconify-icons/ri/logout-circle-r-line"; import LogoutCircleRLine from "~icons/ri/logout-circle-r-line";
import Setting from "@iconify-icons/ri/settings-3-line"; import Setting from "~icons/ri/settings-3-line";
import Check from "@iconify-icons/ep/check"; import Check from "~icons/ep/check";
const { const {
layout, layout,
@@ -33,7 +33,7 @@ const { t, locale, translationCh, translationEn } = useTranslationLang();
</script> </script>
<template> <template>
<div class="navbar bg-[#fff] shadow-sm shadow-[rgba(0,21,41,0.08)]"> <div class="navbar bg-[#fff] shadow-xs shadow-[rgba(0,21,41,0.08)]">
<LaySidebarTopCollapse <LaySidebarTopCollapse
v-if="device === 'mobile'" v-if="device === 'mobile'"
class="hamburger-container" class="hamburger-container"
@@ -54,13 +54,13 @@ const { t, locale, translationCh, translationEn } = useTranslationLang();
<!-- 国际化 --> <!-- 国际化 -->
<el-dropdown id="header-translation" trigger="click"> <el-dropdown id="header-translation" trigger="click">
<GlobalizationIcon <GlobalizationIcon
class="navbar-bg-hover w-[40px] h-[48px] p-[11px] cursor-pointer outline-none" class="navbar-bg-hover w-[40px] h-[48px] p-[11px] cursor-pointer outline-hidden"
/> />
<template #dropdown> <template #dropdown>
<el-dropdown-menu class="translation"> <el-dropdown-menu class="translation">
<el-dropdown-item <el-dropdown-item
:style="getDropdownItemStyle(locale, 'zh')" :style="getDropdownItemStyle(locale, 'zh')"
:class="['dark:!text-white', getDropdownItemClass(locale, 'zh')]" :class="['dark:text-white!', getDropdownItemClass(locale, 'zh')]"
@click="translationCh" @click="translationCh"
> >
<IconifyIconOffline <IconifyIconOffline
@@ -72,7 +72,7 @@ const { t, locale, translationCh, translationEn } = useTranslationLang();
</el-dropdown-item> </el-dropdown-item>
<el-dropdown-item <el-dropdown-item
:style="getDropdownItemStyle(locale, 'en')" :style="getDropdownItemStyle(locale, 'en')"
:class="['dark:!text-white', getDropdownItemClass(locale, 'en')]" :class="['dark:text-white!', getDropdownItemClass(locale, 'en')]"
@click="translationEn" @click="translationEn"
> >
<span v-show="locale === 'en'" class="check-en"> <span v-show="locale === 'en'" class="check-en">

View File

@@ -49,7 +49,7 @@ function hoverDescription(event, description) {
<template> <template>
<div <div
class="notice-container border-b-[1px] border-solid border-[#f0f0f0] dark:border-[#303030]" class="notice-container border-0 border-b-[1px] border-solid border-[#f0f0f0] dark:border-[#303030]"
> >
<el-avatar <el-avatar
v-if="noticeItem.avatar" v-if="noticeItem.avatar"

View File

@@ -3,7 +3,7 @@ import { useI18n } from "vue-i18n";
import { ref, computed } from "vue"; import { ref, computed } from "vue";
import { noticesData } from "./data"; import { noticesData } from "./data";
import NoticeList from "./components/NoticeList.vue"; import NoticeList from "./components/NoticeList.vue";
import BellIcon from "@iconify-icons/ep/bell"; import BellIcon from "~icons/ep/bell";
const { t } = useI18n(); const { t } = useI18n();
const noticesNum = ref(0); const noticesNum = ref(0);

View File

@@ -4,7 +4,7 @@ import { emitter } from "@/utils/mitt";
import { onClickOutside } from "@vueuse/core"; import { onClickOutside } from "@vueuse/core";
import { ref, computed, onMounted, onBeforeUnmount } from "vue"; import { ref, computed, onMounted, onBeforeUnmount } from "vue";
import { useDataThemeChange } from "@/layout/hooks/useDataThemeChange"; import { useDataThemeChange } from "@/layout/hooks/useDataThemeChange";
import CloseIcon from "@iconify-icons/ep/close"; import CloseIcon from "~icons/ep/close";
const target = ref(null); const target = ref(null);
const show = ref<Boolean>(false); const show = ref<Boolean>(false);
@@ -16,7 +16,7 @@ const iconClass = computed(() => {
"flex", "flex",
"justify-center", "justify-center",
"items-center", "items-center",
"outline-none", "outline-hidden",
"rounded-[4px]", "rounded-[4px]",
"cursor-pointer", "cursor-pointer",
"transition-colors", "transition-colors",
@@ -51,7 +51,7 @@ onBeforeUnmount(() => {
<div class="right-panel-background" /> <div class="right-panel-background" />
<div ref="target" class="right-panel bg-bg_color"> <div ref="target" class="right-panel bg-bg_color">
<div <div
class="project-configuration border-b-[1px] border-solid border-[var(--pure-border-color)]" class="project-configuration border-0 border-b-[1px] border-solid border-[var(--pure-border-color)]"
> >
<h4 class="dark:text-white"> <h4 class="dark:text-white">
{{ t("panel.pureSystemSet") }} {{ t("panel.pureSystemSet") }}
@@ -78,7 +78,7 @@ onBeforeUnmount(() => {
</el-scrollbar> </el-scrollbar>
<div <div
class="flex justify-end p-3 border-t-[1px] border-solid border-[var(--pure-border-color)]" class="flex justify-end p-3 border-0 border-t-[1px] border-solid border-[var(--pure-border-color)]"
> >
<el-button <el-button
v-tippy="{ v-tippy="{

View File

@@ -3,10 +3,10 @@ import { useI18n } from "vue-i18n";
import { useNav } from "@/layout/hooks/useNav"; import { useNav } from "@/layout/hooks/useNav";
import MdiKeyboardEsc from "@/assets/svg/keyboard_esc.svg?component"; import MdiKeyboardEsc from "@/assets/svg/keyboard_esc.svg?component";
import EnterOutlined from "@/assets/svg/enter_outlined.svg?component"; import EnterOutlined from "@/assets/svg/enter_outlined.svg?component";
import ArrowUpLine from "@iconify-icons/ri/arrow-up-line"; import ArrowUpLine from "~icons/ri/arrow-up-line";
import ArrowDownLine from "@iconify-icons/ri/arrow-down-line"; import ArrowDownLine from "~icons/ri/arrow-down-line";
withDefaults(defineProps<{ total: number }>(), { withDefaults(defineProps<{ total?: number }>(), {
total: 0 total: 0
}); });

View File

@@ -2,8 +2,8 @@
import type { optionsItem } from "../types"; import type { optionsItem } from "../types";
import { transformI18n } from "@/plugins/i18n"; import { transformI18n } from "@/plugins/i18n";
import { useRenderIcon } from "@/components/ReIcon/src/hooks"; import { useRenderIcon } from "@/components/ReIcon/src/hooks";
import StarIcon from "@iconify-icons/ep/star"; import StarIcon from "~icons/ep/star";
import CloseIcon from "@iconify-icons/ep/close"; import CloseIcon from "~icons/ep/close";
interface Props { interface Props {
item: optionsItem; item: optionsItem;

View File

@@ -6,14 +6,14 @@ import { useRouter } from "vue-router";
import SearchResult from "./SearchResult.vue"; import SearchResult from "./SearchResult.vue";
import SearchFooter from "./SearchFooter.vue"; import SearchFooter from "./SearchFooter.vue";
import { useNav } from "@/layout/hooks/useNav"; import { useNav } from "@/layout/hooks/useNav";
import { transformI18n } from "@/plugins/i18n";
import SearchHistory from "./SearchHistory.vue"; import SearchHistory from "./SearchHistory.vue";
import { transformI18n, $t } from "@/plugins/i18n";
import type { optionsItem, dragItem } from "../types"; import type { optionsItem, dragItem } from "../types";
import { ref, computed, shallowRef, watch } from "vue"; import { ref, computed, shallowRef, watch } from "vue";
import { useDebounceFn, onKeyStroke } from "@vueuse/core"; import { useDebounceFn, onKeyStroke } from "@vueuse/core";
import { usePermissionStoreHook } from "@/store/modules/permission"; import { usePermissionStoreHook } from "@/store/modules/permission";
import { cloneDeep, isAllEmpty, storageLocal } from "@pureadmin/utils"; import { cloneDeep, isAllEmpty, storageLocal } from "@pureadmin/utils";
import SearchIcon from "@iconify-icons/ri/search-line"; import SearchIcon from "~icons/ri/search-line";
interface Props { interface Props {
/** 弹窗显隐 */ /** 弹窗显隐 */

View File

@@ -14,7 +14,7 @@ function handleSearch() {
class="search-container w-[40px] h-[48px] flex-c cursor-pointer navbar-bg-hover" class="search-container w-[40px] h-[48px] flex-c cursor-pointer navbar-bg-hover"
@click="handleSearch" @click="handleSearch"
> >
<IconifyIconOffline icon="ri:search-line" /> <IconifyIconOffline icon="ri/search-line" />
</div> </div>
<SearchModal v-model:value="show" /> <SearchModal v-model:value="show" />
</div> </div>

View File

@@ -19,9 +19,9 @@ import Segmented, { type OptionsType } from "@/components/ReSegmented";
import { useDataThemeChange } from "@/layout/hooks/useDataThemeChange"; import { useDataThemeChange } from "@/layout/hooks/useDataThemeChange";
import { useDark, useGlobal, debounce, isNumber } from "@pureadmin/utils"; import { useDark, useGlobal, debounce, isNumber } from "@pureadmin/utils";
import Check from "@iconify-icons/ep/check"; import Check from "~icons/ep/check";
import LeftArrow from "@iconify-icons/ri/arrow-left-s-line"; import LeftArrow from "~icons/ri/arrow-left-s-line?width=20&height=20";
import RightArrow from "@iconify-icons/ri/arrow-right-s-line"; import RightArrow from "~icons/ri/arrow-right-s-line?width=20&height=20";
import DayIcon from "@/assets/svg/day.svg?component"; import DayIcon from "@/assets/svg/day.svg?component";
import DarkIcon from "@/assets/svg/dark.svg?component"; import DarkIcon from "@/assets/svg/dark.svg?component";
import SystemIcon from "@/assets/svg/system.svg?component"; import SystemIcon from "@/assets/svg/system.svg?component";
@@ -189,7 +189,7 @@ const getThemeColor = computed(() => {
}); });
const pClass = computed(() => { const pClass = computed(() => {
return ["mb-[12px]", "font-medium", "text-sm", "dark:text-white"]; return ["mb-[12px]!", "font-medium", "text-sm", "dark:text-white"];
}); });
const themeOptions = computed<Array<OptionsType>>(() => { const themeOptions = computed<Array<OptionsType>>(() => {
@@ -335,7 +335,7 @@ onUnmounted(() => removeMatchMedia);
" "
/> />
<p :class="['mt-5', pClass]">{{ t("panel.pureThemeColor") }}</p> <p :class="['mt-5!', pClass]">{{ t("panel.pureThemeColor") }}</p>
<ul class="theme-color"> <ul class="theme-color">
<li <li
v-for="(item, index) in themeColors" v-for="(item, index) in themeColors"
@@ -354,7 +354,7 @@ onUnmounted(() => removeMatchMedia);
</li> </li>
</ul> </ul>
<p :class="['mt-5', pClass]">{{ t("panel.pureLayoutModel") }}</p> <p :class="['mt-5!', pClass]">{{ t("panel.pureLayoutModel") }}</p>
<ul class="pure-theme"> <ul class="pure-theme">
<li <li
ref="verticalRef" ref="verticalRef"
@@ -397,7 +397,7 @@ onUnmounted(() => removeMatchMedia);
</ul> </ul>
<span v-if="useAppStoreHook().getViewportWidth > 1280"> <span v-if="useAppStoreHook().getViewportWidth > 1280">
<p :class="['mt-5', pClass]">{{ t("panel.pureStretch") }}</p> <p :class="['mt-5!', pClass]">{{ t("panel.pureStretch") }}</p>
<Segmented <Segmented
resize resize
class="mb-2 select-none" class="mb-2 select-none"
@@ -426,21 +426,19 @@ onUnmounted(() => removeMatchMedia);
> >
<IconifyIconOffline <IconifyIconOffline
:icon="settings.stretch ? RightArrow : LeftArrow" :icon="settings.stretch ? RightArrow : LeftArrow"
height="20"
/> />
<div <div
class="flex-grow border-b border-dashed" class="grow border-0 border-b border-dashed"
style="border-color: var(--el-color-primary)" style="border-color: var(--el-color-primary)"
/> />
<IconifyIconOffline <IconifyIconOffline
:icon="settings.stretch ? LeftArrow : RightArrow" :icon="settings.stretch ? LeftArrow : RightArrow"
height="20"
/> />
</div> </div>
</button> </button>
</span> </span>
<p :class="['mt-4', pClass]">{{ t("panel.pureTagsStyle") }}</p> <p :class="['mt-4!', pClass]">{{ t("panel.pureTagsStyle") }}</p>
<Segmented <Segmented
resize resize
class="select-none" class="select-none"
@@ -449,7 +447,7 @@ onUnmounted(() => removeMatchMedia);
@change="onChange" @change="onChange"
/> />
<p class="mt-5 font-medium text-sm dark:text-white"> <p class="mt-5! font-medium text-sm dark:text-white">
{{ t("panel.pureInterfaceDisplay") }} {{ t("panel.pureInterfaceDisplay") }}
</p> </p>
<ul class="setting"> <ul class="setting">

View File

@@ -12,10 +12,10 @@ import LaySidebarItem from "../lay-sidebar/components/SidebarItem.vue";
import LaySidebarFullScreen from "../lay-sidebar/components/SidebarFullScreen.vue"; import LaySidebarFullScreen from "../lay-sidebar/components/SidebarFullScreen.vue";
import GlobalizationIcon from "@/assets/svg/globalization.svg?component"; import GlobalizationIcon from "@/assets/svg/globalization.svg?component";
import AccountSettingsIcon from "@iconify-icons/ri/user-settings-line"; import AccountSettingsIcon from "~icons/ri/user-settings-line";
import LogoutCircleRLine from "@iconify-icons/ri/logout-circle-r-line"; import LogoutCircleRLine from "~icons/ri/logout-circle-r-line";
import Setting from "@iconify-icons/ri/settings-3-line"; import Setting from "~icons/ri/settings-3-line";
import Check from "@iconify-icons/ep/check"; import Check from "~icons/ep/check";
const menuRef = ref(); const menuRef = ref();
const showLogo = ref( const showLogo = ref(
@@ -84,13 +84,13 @@ onMounted(() => {
<!-- 国际化 --> <!-- 国际化 -->
<el-dropdown id="header-translation" trigger="click"> <el-dropdown id="header-translation" trigger="click">
<GlobalizationIcon <GlobalizationIcon
class="navbar-bg-hover w-[40px] h-[48px] p-[11px] cursor-pointer outline-none" class="navbar-bg-hover w-[40px] h-[48px] p-[11px] cursor-pointer outline-hidden"
/> />
<template #dropdown> <template #dropdown>
<el-dropdown-menu class="translation"> <el-dropdown-menu class="translation">
<el-dropdown-item <el-dropdown-item
:style="getDropdownItemStyle(locale, 'zh')" :style="getDropdownItemStyle(locale, 'zh')"
:class="['dark:!text-white', getDropdownItemClass(locale, 'zh')]" :class="['dark:text-white!', getDropdownItemClass(locale, 'zh')]"
@click="translationCh" @click="translationCh"
> >
<span v-show="locale === 'zh'" class="check-zh"> <span v-show="locale === 'zh'" class="check-zh">
@@ -100,7 +100,7 @@ onMounted(() => {
</el-dropdown-item> </el-dropdown-item>
<el-dropdown-item <el-dropdown-item
:style="getDropdownItemStyle(locale, 'en')" :style="getDropdownItemStyle(locale, 'en')"
:class="['dark:!text-white', getDropdownItemClass(locale, 'en')]" :class="['dark:text-white!', getDropdownItemClass(locale, 'en')]"
@click="translationEn" @click="translationEn"
> >
<span v-show="locale === 'en'" class="check-en"> <span v-show="locale === 'en'" class="check-en">

View File

@@ -13,10 +13,10 @@ import LaySidebarExtraIcon from "../lay-sidebar/components/SidebarExtraIcon.vue"
import LaySidebarFullScreen from "../lay-sidebar/components/SidebarFullScreen.vue"; import LaySidebarFullScreen from "../lay-sidebar/components/SidebarFullScreen.vue";
import GlobalizationIcon from "@/assets/svg/globalization.svg?component"; import GlobalizationIcon from "@/assets/svg/globalization.svg?component";
import AccountSettingsIcon from "@iconify-icons/ri/user-settings-line"; import AccountSettingsIcon from "~icons/ri/user-settings-line";
import LogoutCircleRLine from "@iconify-icons/ri/logout-circle-r-line"; import LogoutCircleRLine from "~icons/ri/logout-circle-r-line";
import Setting from "@iconify-icons/ri/settings-3-line"; import Setting from "~icons/ri/settings-3-line";
import Check from "@iconify-icons/ep/check"; import Check from "~icons/ep/check";
const menuRef = ref(); const menuRef = ref();
const defaultActive = ref(null); const defaultActive = ref(null);
@@ -105,13 +105,13 @@ watch(
<!-- 国际化 --> <!-- 国际化 -->
<el-dropdown id="header-translation" trigger="click"> <el-dropdown id="header-translation" trigger="click">
<GlobalizationIcon <GlobalizationIcon
class="navbar-bg-hover w-[40px] h-[48px] p-[11px] cursor-pointer outline-none" class="navbar-bg-hover w-[40px] h-[48px] p-[11px] cursor-pointer outline-hidden"
/> />
<template #dropdown> <template #dropdown>
<el-dropdown-menu class="translation"> <el-dropdown-menu class="translation">
<el-dropdown-item <el-dropdown-item
:style="getDropdownItemStyle(locale, 'zh')" :style="getDropdownItemStyle(locale, 'zh')"
:class="['dark:!text-white', getDropdownItemClass(locale, 'zh')]" :class="['dark:text-white!', getDropdownItemClass(locale, 'zh')]"
@click="translationCh" @click="translationCh"
> >
<span v-show="locale === 'zh'" class="check-zh"> <span v-show="locale === 'zh'" class="check-zh">
@@ -121,7 +121,7 @@ watch(
</el-dropdown-item> </el-dropdown-item>
<el-dropdown-item <el-dropdown-item
:style="getDropdownItemStyle(locale, 'en')" :style="getDropdownItemStyle(locale, 'en')"
:class="['dark:!text-white', getDropdownItemClass(locale, 'en')]" :class="['dark:text-white!', getDropdownItemClass(locale, 'en')]"
@click="translationEn" @click="translationEn"
> >
<span v-show="locale === 'en'" class="check-en"> <span v-show="locale === 'en'" class="check-en">

View File

@@ -105,12 +105,12 @@ watch(
</script> </script>
<template> <template>
<el-breadcrumb class="!leading-[50px] select-none" separator="/"> <el-breadcrumb class="leading-[50px]! select-none" separator="/">
<transition-group name="breadcrumb"> <transition-group name="breadcrumb">
<el-breadcrumb-item <el-breadcrumb-item
v-for="item in levelList" v-for="item in levelList"
:key="item.path" :key="item.path"
class="!inline !items-stretch" class="inline! items-stretch!"
> >
<a @click.prevent="handleLink(item)"> <a @click.prevent="handleLink(item)">
{{ transformI18n(item.meta.title) }} {{ transformI18n(item.meta.title) }}

View File

@@ -4,10 +4,10 @@ import { useI18n } from "vue-i18n";
import { useGlobal } from "@pureadmin/utils"; import { useGlobal } from "@pureadmin/utils";
import { useNav } from "@/layout/hooks/useNav"; import { useNav } from "@/layout/hooks/useNav";
import ArrowLeft from "@iconify-icons/ri/arrow-left-double-fill"; import ArrowLeft from "~icons/ri/arrow-left-double-fill";
interface Props { interface Props {
isActive: boolean; isActive?: boolean;
} }
withDefaults(defineProps<Props>(), { withDefaults(defineProps<Props>(), {

View File

@@ -17,10 +17,10 @@ import {
useAttrs useAttrs
} from "vue"; } from "vue";
import ArrowUp from "@iconify-icons/ep/arrow-up-bold"; import ArrowUp from "~icons/ep/arrow-up-bold";
import EpArrowDown from "@iconify-icons/ep/arrow-down-bold"; import EpArrowDown from "~icons/ep/arrow-down-bold";
import ArrowLeft from "@iconify-icons/ep/arrow-left-bold"; import ArrowLeft from "~icons/ep/arrow-left-bold";
import ArrowRight from "@iconify-icons/ep/arrow-right-bold"; import ArrowRight from "~icons/ep/arrow-right-bold";
const attrs = useAttrs(); const attrs = useAttrs();
const { layout, isCollapse, tooltipEffect, getDivStyle } = useNav(); const { layout, isCollapse, tooltipEffect, getDivStyle } = useNav();
@@ -61,6 +61,21 @@ const getSubMenuIconStyle = computed((): CSSProperties => {
}; };
}); });
const textClass = computed(() => {
const item = props.item;
const baseClass = "w-full! text-inherit!";
if (
layout.value !== "horizontal" &&
isCollapse.value &&
!toRaw(item.meta.icon) &&
((layout.value === "vertical" && item.parentId === null) ||
(layout.value === "mix" && item.pathList.length === 2))
) {
return `${baseClass} min-w-[54px]! text-center! px-3!`;
}
return baseClass;
});
const expandCloseIcon = computed(() => { const expandCloseIcon = computed(() => {
if (!getConfig()?.MenuArrowIconNoTransition) return ""; if (!getConfig()?.MenuArrowIconNoTransition) return "";
return { return {
@@ -144,7 +159,7 @@ function resolvePath(routePath) {
item?.pathList?.length === 2) item?.pathList?.length === 2)
" "
truncated truncated
class="!w-full !pl-4 !text-inherit" class="w-full! px-3! min-w-[54px]! text-center! text-inherit!"
> >
{{ transformI18n(onlyOneChild.meta.title) }} {{ transformI18n(onlyOneChild.meta.title) }}
</el-text> </el-text>
@@ -156,7 +171,7 @@ function resolvePath(routePath) {
offset: [0, -10], offset: [0, -10],
theme: tooltipEffect theme: tooltipEffect
}" }"
class="!w-full !text-inherit" class="w-full! text-inherit!"
> >
{{ transformI18n(onlyOneChild.meta.title) }} {{ transformI18n(onlyOneChild.meta.title) }}
</ReText> </ReText>
@@ -195,15 +210,7 @@ function resolvePath(routePath) {
offset: [0, -10], offset: [0, -10],
theme: tooltipEffect theme: tooltipEffect
}" }"
:class="{ :class="textClass"
'!w-full': true,
'!text-inherit': true,
'!pl-4':
layout !== 'horizontal' &&
isCollapse &&
!toRaw(item.meta.icon) &&
item.parentId === null
}"
> >
{{ transformI18n(item.meta.title) }} {{ transformI18n(item.meta.title) }}
</ReText> </ReText>

View File

@@ -4,10 +4,10 @@ import { useI18n } from "vue-i18n";
import { useGlobal } from "@pureadmin/utils"; import { useGlobal } from "@pureadmin/utils";
import { useNav } from "@/layout/hooks/useNav"; import { useNav } from "@/layout/hooks/useNav";
import MenuFold from "@iconify-icons/ri/menu-fold-fill"; import MenuFold from "~icons/ri/menu-fold-fill";
interface Props { interface Props {
isActive: boolean; isActive?: boolean;
} }
withDefaults(defineProps<Props>(), { withDefaults(defineProps<Props>(), {
@@ -23,7 +23,7 @@ const iconClass = computed(() => {
"mb-1", "mb-1",
"w-[16px]", "w-[16px]",
"h-[16px]", "h-[16px]",
"inline-block", "inline-block!",
"align-middle", "align-middle",
"cursor-pointer", "cursor-pointer",
"duration-[100ms]" "duration-[100ms]"

View File

@@ -1,10 +1,10 @@
<script setup lang="ts"> <script setup lang="ts">
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
import MenuFold from "@iconify-icons/ri/menu-fold-fill"; import MenuFold from "~icons/ri/menu-fold-fill";
import MenuUnfold from "@iconify-icons/ri/menu-unfold-fill"; import MenuUnfold from "~icons/ri/menu-unfold-fill";
interface Props { interface Props {
isActive: boolean; isActive?: boolean;
} }
withDefaults(defineProps<Props>(), { withDefaults(defineProps<Props>(), {
@@ -32,7 +32,7 @@ const toggleClick = () => {
> >
<IconifyIconOffline <IconifyIconOffline
:icon="isActive ? MenuFold : MenuUnfold" :icon="isActive ? MenuFold : MenuUnfold"
class="inline-block align-middle hover:text-primary dark:hover:!text-white" class="inline-block! align-middle hover:text-primary dark:hover:text-white!"
/> />
</div> </div>
</template> </template>

View File

@@ -18,11 +18,11 @@ import {
useResizeObserver useResizeObserver
} from "@pureadmin/utils"; } from "@pureadmin/utils";
import ExitFullscreen from "@iconify-icons/ri/fullscreen-exit-fill"; import ExitFullscreen from "~icons/ri/fullscreen-exit-fill";
import Fullscreen from "@iconify-icons/ri/fullscreen-fill"; import Fullscreen from "~icons/ri/fullscreen-fill";
import ArrowDown from "@iconify-icons/ri/arrow-down-s-line"; import ArrowDown from "~icons/ri/arrow-down-s-line";
import ArrowRightSLine from "@iconify-icons/ri/arrow-right-s-line"; import ArrowRightSLine from "~icons/ri/arrow-right-s-line";
import ArrowLeftSLine from "@iconify-icons/ri/arrow-left-s-line"; import ArrowLeftSLine from "~icons/ri/arrow-left-s-line";
const { const {
Close, Close,
@@ -254,7 +254,7 @@ function deleteDynamicTag(obj: any, current: any, tag?: string) {
if (tag === "other") { if (tag === "other") {
spliceRoute(1, 1, true); spliceRoute(1, 1, true);
} else if (tag === "left") { } else if (tag === "left") {
spliceRoute(fixedTags.length, valueIndex - 1, true); spliceRoute(fixedTags.length, valueIndex - fixedTags.length);
} else if (tag === "right") { } else if (tag === "right") {
spliceRoute(valueIndex + 1, multiTags.value.length); spliceRoute(valueIndex + 1, multiTags.value.length);
} else { } else {
@@ -589,7 +589,7 @@ onBeforeUnmount(() => {
> >
<template v-if="showModel !== 'chrome'"> <template v-if="showModel !== 'chrome'">
<span <span
class="tag-title dark:!text-text_color_primary dark:hover:!text-primary" class="tag-title dark:text-text_color_primary! dark:hover:text-primary!"
> >
{{ transformI18n(item.meta.title) }} {{ transformI18n(item.meta.title) }}
</span> </span>

View File

@@ -14,8 +14,8 @@ import { useUserStoreHook } from "@/store/modules/user";
import { useGlobal, isAllEmpty } from "@pureadmin/utils"; import { useGlobal, isAllEmpty } from "@pureadmin/utils";
import { useEpThemeStoreHook } from "@/store/modules/epTheme"; import { useEpThemeStoreHook } from "@/store/modules/epTheme";
import { usePermissionStoreHook } from "@/store/modules/permission"; import { usePermissionStoreHook } from "@/store/modules/permission";
import ExitFullscreen from "@iconify-icons/ri/fullscreen-exit-fill"; import ExitFullscreen from "~icons/ri/fullscreen-exit-fill";
import Fullscreen from "@iconify-icons/ri/fullscreen-fill"; import Fullscreen from "~icons/ri/fullscreen-fill";
const errorInfo = const errorInfo =
"The current routing configuration is incorrect, please check the configuration"; "The current routing configuration is incorrect, please check the configuration";
@@ -64,7 +64,7 @@ export function useNav() {
const getDropdownItemClass = computed(() => { const getDropdownItemClass = computed(() => {
return (locale, t) => { return (locale, t) => {
return locale === t ? "" : "dark:hover:!text-primary"; return locale === t ? "" : "dark:hover:text-primary!";
}; };
}); });

View File

@@ -21,13 +21,13 @@ import {
hasClass hasClass
} from "@pureadmin/utils"; } from "@pureadmin/utils";
import Fullscreen from "@iconify-icons/ri/fullscreen-fill"; import Fullscreen from "~icons/ri/fullscreen-fill";
import CloseAllTags from "@iconify-icons/ri/subtract-line"; import CloseAllTags from "~icons/ri/subtract-line";
import CloseOtherTags from "@iconify-icons/ri/text-spacing"; import CloseOtherTags from "~icons/ri/text-spacing";
import CloseRightTags from "@iconify-icons/ri/text-direction-l"; import CloseRightTags from "~icons/ri/text-direction-l";
import CloseLeftTags from "@iconify-icons/ri/text-direction-r"; import CloseLeftTags from "~icons/ri/text-direction-r";
import RefreshRight from "@iconify-icons/ep/refresh-right"; import RefreshRight from "~icons/ep/refresh-right";
import Close from "@iconify-icons/ep/close"; import Close from "~icons/ep/close";
export function useTags() { export function useTags() {
const route = useRoute(); const route = useRoute();

View File

@@ -1,4 +1,4 @@
import type { IconifyIcon } from "@iconify/vue"; import type { FunctionalComponent } from "vue";
const { VITE_HIDE_HOME } = import.meta.env; const { VITE_HIDE_HOME } = import.meta.env;
export const routerArrays: Array<RouteConfigs> = export const routerArrays: Array<RouteConfigs> =
@@ -8,7 +8,7 @@ export const routerArrays: Array<RouteConfigs> =
path: "/welcome", path: "/welcome",
meta: { meta: {
title: "menus.pureHome", title: "menus.pureHome",
icon: "ep:home-filled" icon: "ep/home-filled"
} }
} }
] ]
@@ -16,7 +16,7 @@ export const routerArrays: Array<RouteConfigs> =
export type routeMetaType = { export type routeMetaType = {
title?: string; title?: string;
icon?: string | IconifyIcon; icon?: string | FunctionalComponent;
showLink?: boolean; showLink?: boolean;
savedPosition?: boolean; savedPosition?: boolean;
auths?: Array<string>; auths?: Array<string>;
@@ -36,7 +36,7 @@ export type multiTagsType = {
}; };
export type tagsViewsType = { export type tagsViewsType = {
icon: string | IconifyIcon; icon: string | FunctionalComponent;
text: string; text: string;
divided: boolean; divided: boolean;
disabled: boolean; disabled: boolean;

View File

@@ -10,7 +10,7 @@ import zhLocale from "element-plus/es/locale/lang/zh-cn";
const siphonI18n = (function () { const siphonI18n = (function () {
// 仅初始化一次国际化配置 // 仅初始化一次国际化配置
let cache = Object.fromEntries( const cache = Object.fromEntries(
Object.entries( Object.entries(
import.meta.glob("../../locales/*.y(a)?ml", { eager: true }) import.meta.glob("../../locales/*.y(a)?ml", { eager: true })
).map(([key, value]: any) => { ).map(([key, value]: any) => {

View File

@@ -7,7 +7,13 @@ import { buildHierarchyTree } from "@/utils/tree";
import remainingRouter from "./modules/remaining"; import remainingRouter from "./modules/remaining";
import { useMultiTagsStoreHook } from "@/store/modules/multiTags"; import { useMultiTagsStoreHook } from "@/store/modules/multiTags";
import { usePermissionStoreHook } from "@/store/modules/permission"; import { usePermissionStoreHook } from "@/store/modules/permission";
import { isUrl, openLink, storageLocal, isAllEmpty } from "@pureadmin/utils"; import {
isUrl,
openLink,
cloneDeep,
isAllEmpty,
storageLocal
} from "@pureadmin/utils";
import { import {
ascending, ascending,
getTopMenu, getTopMenu,
@@ -21,9 +27,9 @@ import {
} from "./utils"; } from "./utils";
import { import {
type Router, type Router,
createRouter,
type RouteRecordRaw, type RouteRecordRaw,
type RouteComponent type RouteComponent,
createRouter
} from "vue-router"; } from "vue-router";
import { import {
type DataInfo, type DataInfo,
@@ -55,6 +61,9 @@ export const constantRoutes: Array<RouteRecordRaw> = formatTwoStageRoutes(
formatFlatteningRoutes(buildHierarchyTree(ascending(routes.flat(Infinity)))) formatFlatteningRoutes(buildHierarchyTree(ascending(routes.flat(Infinity))))
); );
/** 初始的静态路由,用于退出登录时重置路由 */
const initConstantRoutes: Array<RouteRecordRaw> = cloneDeep(constantRoutes);
/** 用于渲染菜单,保持原始层级 */ /** 用于渲染菜单,保持原始层级 */
export const constantMenus: Array<RouteComponent> = ascending( export const constantMenus: Array<RouteComponent> = ascending(
routes.flat(Infinity) routes.flat(Infinity)
@@ -87,17 +96,13 @@ export const router: Router = createRouter({
/** 重置路由 */ /** 重置路由 */
export function resetRouter() { export function resetRouter() {
router.getRoutes().forEach(route => { router.clearRoutes();
const { name, meta } = route; for (const route of initConstantRoutes.concat(...(remainingRouter as any))) {
if (name && router.hasRoute(name) && meta?.backstage) { router.addRoute(route);
router.removeRoute(name);
router.options.routes = formatTwoStageRoutes(
formatFlatteningRoutes(
buildHierarchyTree(ascending(routes.flat(Infinity)))
)
);
} }
}); router.options.routes = formatTwoStageRoutes(
formatFlatteningRoutes(buildHierarchyTree(ascending(routes.flat(Infinity))))
);
usePermissionStoreHook().clearAllCachePage(); usePermissionStoreHook().clearAllCachePage();
} }

View File

@@ -5,7 +5,7 @@ export default {
path: "/able", path: "/able",
redirect: "/able/watermark", redirect: "/able/watermark",
meta: { meta: {
icon: "ri:ubuntu-fill", icon: "ri/ubuntu-fill",
title: $t("menus.pureAble"), title: $t("menus.pureAble"),
rank: able rank: able
}, },

View File

@@ -5,7 +5,7 @@ export default {
path: "/about", path: "/about",
redirect: "/about/index", redirect: "/about/index",
meta: { meta: {
icon: "ri:file-info-line", icon: "ri/file-info-line",
title: $t("menus.pureAbout"), title: $t("menus.pureAbout"),
rank: about rank: about
}, },

View File

@@ -6,7 +6,7 @@ export default {
path: "/board", path: "/board",
redirect: "/board/index", redirect: "/board/index",
meta: { meta: {
icon: "ri:artboard-line", icon: "ri/artboard-line",
title: $t("menus.pureBoard"), title: $t("menus.pureBoard"),
rank: board rank: board
}, },

View File

@@ -4,7 +4,7 @@ export default {
path: "/chatai", path: "/chatai",
redirect: "/chatai/index", redirect: "/chatai/index",
meta: { meta: {
icon: "ri:chat-search-line", icon: "ri/chat-search-line",
title: "chat-ai", title: "chat-ai",
rank: chatai rank: chatai
}, },

View File

@@ -5,7 +5,7 @@ export default {
path: "/codemirror", path: "/codemirror",
redirect: "/codemirror/index", redirect: "/codemirror/index",
meta: { meta: {
icon: "ri:code-box-line", icon: "ri/code-box-line",
title: $t("menus.pureCodeMirror"), title: $t("menus.pureCodeMirror"),
rank: codemirror rank: codemirror
}, },

View File

@@ -5,7 +5,7 @@ export default {
path: "/components", path: "/components",
redirect: "/components/dialog", redirect: "/components/dialog",
meta: { meta: {
icon: "ep:menu", icon: "ep/menu",
title: $t("menus.pureComponents"), title: $t("menus.pureComponents"),
rank: components rank: components
}, },

View File

@@ -5,7 +5,7 @@ export default {
path: "/editor", path: "/editor",
redirect: "/editor/index", redirect: "/editor/index",
meta: { meta: {
icon: "ep:edit", icon: "ep/edit",
title: $t("menus.pureEditor"), title: $t("menus.pureEditor"),
rank: editor rank: editor
}, },

View File

@@ -5,7 +5,7 @@ export default {
path: "/error", path: "/error",
redirect: "/error/403", redirect: "/error/403",
meta: { meta: {
icon: "ri:information-line", icon: "ri/information-line",
// showLink: false, // showLink: false,
title: $t("menus.pureAbnormal"), title: $t("menus.pureAbnormal"),
rank: error rank: error

View File

@@ -5,7 +5,7 @@ export default {
path: "/flow-chart", path: "/flow-chart",
redirect: "/flow-chart/index", redirect: "/flow-chart/index",
meta: { meta: {
icon: "ep:set-up", icon: "ep/set-up",
title: $t("menus.pureFlowChart"), title: $t("menus.pureFlowChart"),
rank: flowchart rank: flowchart
}, },

View File

@@ -5,7 +5,7 @@ export default {
path: "/form", path: "/form",
redirect: "/form/index", redirect: "/form/index",
meta: { meta: {
icon: "ri:edit-box-line", icon: "ri/edit-box-line",
title: $t("menus.pureSchemaForm"), title: $t("menus.pureSchemaForm"),
rank: form rank: form
}, },

View File

@@ -6,7 +6,7 @@ export default {
path: "/form-design", path: "/form-design",
redirect: "/form-design/index", redirect: "/form-design/index",
meta: { meta: {
icon: "ri:terminal-window-line", icon: "ri/terminal-window-line",
title: $t("menus.pureFormDesign"), title: $t("menus.pureFormDesign"),
rank: formdesign rank: formdesign
}, },

View File

@@ -5,7 +5,7 @@ export default {
path: "/ganttastic", path: "/ganttastic",
redirect: "/ganttastic/index", redirect: "/ganttastic/index",
meta: { meta: {
icon: "ri:bar-chart-horizontal-line", icon: "ri/bar-chart-horizontal-line",
title: $t("menus.pureGanttastic"), title: $t("menus.pureGanttastic"),
rank: ganttastic rank: ganttastic
}, },

View File

@@ -5,7 +5,7 @@ export default {
path: "/guide", path: "/guide",
redirect: "/guide/index", redirect: "/guide/index",
meta: { meta: {
icon: "ep:guide", icon: "ep/guide",
title: $t("menus.pureGuide"), title: $t("menus.pureGuide"),
rank: guide rank: guide
}, },

View File

@@ -9,7 +9,7 @@ export default {
component: Layout, component: Layout,
redirect: "/welcome", redirect: "/welcome",
meta: { meta: {
icon: "ep:home-filled", icon: "ep/home-filled",
title: $t("menus.pureHome"), title: $t("menus.pureHome"),
rank: home rank: home
}, },

View File

@@ -5,7 +5,7 @@ export default {
path: "/list", path: "/list",
redirect: "/list/card", redirect: "/list/card",
meta: { meta: {
icon: "ri:list-check", icon: "ri/list-check",
title: $t("menus.pureList"), title: $t("menus.pureList"),
rank: list rank: list
}, },
@@ -15,7 +15,7 @@ export default {
name: "CardList", name: "CardList",
component: () => import("@/views/list/card/index.vue"), component: () => import("@/views/list/card/index.vue"),
meta: { meta: {
icon: "ri:bank-card-line", icon: "ri/bank-card-line",
title: $t("menus.pureCardList"), title: $t("menus.pureCardList"),
showParent: true showParent: true
} }

View File

@@ -5,7 +5,7 @@ export default {
path: "/markdown", path: "/markdown",
redirect: "/markdown/index", redirect: "/markdown/index",
meta: { meta: {
icon: "ri:markdown-line", icon: "ri/markdown-line",
title: $t("menus.pureMarkdown"), title: $t("menus.pureMarkdown"),
rank: markdown rank: markdown
}, },

View File

@@ -6,7 +6,7 @@ export default {
path: "/mind-map", path: "/mind-map",
redirect: "/mind-map/index", redirect: "/mind-map/index",
meta: { meta: {
icon: "ri:mind-map", icon: "ri/mind-map",
title: $t("menus.pureMindMap"), title: $t("menus.pureMindMap"),
rank: mind rank: mind
}, },

View File

@@ -6,7 +6,7 @@ export default {
redirect: "/nested/menu1/menu1-1", redirect: "/nested/menu1/menu1-1",
meta: { meta: {
title: $t("menus.pureMenus"), title: $t("menus.pureMenus"),
icon: "ep:histogram", icon: "ep/histogram",
rank: nested rank: nested
}, },
children: [ children: [

View File

@@ -5,7 +5,7 @@ export default {
path: "/ppt", path: "/ppt",
redirect: "/ppt/index", redirect: "/ppt/index",
meta: { meta: {
icon: "ri:file-ppt-2-line", icon: "ri/file-ppt-2-line",
title: "PPT", title: "PPT",
rank: ppt rank: ppt
}, },

View File

@@ -5,7 +5,7 @@ export default {
path: "/result", path: "/result",
redirect: "/result/success", redirect: "/result/success",
meta: { meta: {
icon: "ri:checkbox-circle-line", icon: "ri/checkbox-circle-line",
title: $t("menus.pureResult"), title: $t("menus.pureResult"),
rank: result rank: result
}, },

View File

@@ -5,7 +5,7 @@ export default {
path: "/table", path: "/table",
redirect: "/table/index", redirect: "/table/index",
meta: { meta: {
icon: "ri:table-line", icon: "ri/table-line",
title: $t("menus.pureTable"), title: $t("menus.pureTable"),
rank: table rank: table
}, },

View File

@@ -4,7 +4,7 @@ export default {
path: "/vue-flow", path: "/vue-flow",
redirect: "/vue-flow/index", redirect: "/vue-flow/index",
meta: { meta: {
icon: "ep:set-up", icon: "ep/set-up",
title: "vue-flow", title: "vue-flow",
rank: vueflow rank: vueflow
}, },

View File

@@ -172,6 +172,8 @@ function handleAsyncRoutes(routeList) {
const flattenRouters: any = router const flattenRouters: any = router
.getRoutes() .getRoutes()
.find(n => n.path === "/"); .find(n => n.path === "/");
// 保持router.options.routes[0].children与path为"/"的children一致防止数据不一致导致异常
flattenRouters.children = router.options.routes[0].children;
router.addRoute(flattenRouters); router.addRoute(flattenRouters);
} }
} }

View File

@@ -1,12 +1,3 @@
*,
::before,
::after {
box-sizing: border-box;
border-color: currentColor;
border-style: solid;
border-width: 0;
}
#app { #app {
width: 100%; width: 100%;
height: 100%; height: 100%;

View File

@@ -666,6 +666,10 @@ body[layout="horizontal"] {
@include merge-style($sideBarWidth); @include merge-style($sideBarWidth);
.el-menu {
--el-menu-hover-text-color: var(--pure-theme-menu-text) !important;
}
.fixed-header, .fixed-header,
.main-container { .main-container {
transition: none !important; transition: none !important;
@@ -687,6 +691,7 @@ body[layout="mix"] {
.el-menu { .el-menu {
--el-menu-hover-bg-color: transparent !important; --el-menu-hover-bg-color: transparent !important;
--el-menu-hover-text-color: var(--pure-theme-menu-text) !important;
} }
.hideSidebar { .hideSidebar {

View File

@@ -1,21 +1,46 @@
@tailwind base; @layer theme, base, components, utilities;
@tailwind components; @import "tailwindcss/theme.css" layer(theme);
@tailwind utilities; @import "tailwindcss/utilities.css" layer(utilities);
@layer components { @custom-variant dark (&:is(.dark *));
.flex-c {
@theme {
--color-bg_color: var(--el-bg-color);
--color-primary: var(--el-color-primary);
--color-text_color_primary: var(--el-text-color-primary);
--color-text_color_regular: var(--el-text-color-regular);
}
/*
The default border color has changed to `currentColor` in Tailwind CSS v4,
so we've added these compatibility styles to make sure everything still
looks the same as it did with Tailwind CSS v3.
If we ever want to remove these styles, we need to add an explicit border
color utility to any element that depends on these defaults.
*/
@layer base {
*,
::after,
::before,
::backdrop,
::file-selector-button {
border-color: var(--color-gray-200, currentColor);
}
}
@utility flex-c {
@apply flex justify-center items-center; @apply flex justify-center items-center;
} }
.flex-ac { @utility flex-ac {
@apply flex justify-around items-center; @apply flex justify-around items-center;
} }
.flex-bc { @utility flex-bc {
@apply flex justify-between items-center; @apply flex justify-between items-center;
} }
.navbar-bg-hover { @utility navbar-bg-hover {
@apply dark:text-white dark:hover:!bg-[#242424]; @apply dark:text-white dark:hover:bg-[#242424]!;
}
} }

View File

@@ -8,6 +8,8 @@ type messageTypes = "info" | "success" | "warning" | "error";
interface MessageParams { interface MessageParams {
/** 消息类型,可选 `info` 、`success` 、`warning` 、`error` ,默认 `info` */ /** 消息类型,可选 `info` 、`success` 、`warning` 、`error` ,默认 `info` */
type?: messageTypes; type?: messageTypes;
/** 是否纯色,默认 `false` */
plain?: boolean;
/** 自定义图标,该属性会覆盖 `type` 的图标 */ /** 自定义图标,该属性会覆盖 `type` 的图标 */
icon?: any; icon?: any;
/** 是否将 `message` 属性作为 `HTML` 片段处理,默认 `false` */ /** 是否将 `message` 属性作为 `HTML` 片段处理,默认 `false` */
@@ -18,14 +20,14 @@ interface MessageParams {
duration?: number; duration?: number;
/** 是否显示关闭按钮,默认值 `false` */ /** 是否显示关闭按钮,默认值 `false` */
showClose?: boolean; showClose?: boolean;
/** 文字是否居中,默认 `false` */ /** `Message` 距离窗口顶部的偏移量,默认 `16` */
center?: boolean;
/** `Message` 距离窗口顶部的偏移量,默认 `20` */
offset?: number; offset?: number;
/** 设置组件的根元素,默认 `document.body` */ /** 设置组件的根元素,默认 `document.body` */
appendTo?: string | HTMLElement; appendTo?: string | HTMLElement;
/** 合并内容相同的消息,不支持 `VNode` 类型的消息,默认值 `false` */ /** 合并内容相同的消息,不支持 `VNode` 类型的消息,默认值 `false` */
grouping?: boolean; grouping?: boolean;
/** 重复次数,类似于 `Badge` 。当和 `grouping` 属性一起使用时作为初始数量使用,默认值 `1` */
repeatNum?: number;
/** 关闭时的回调函数, 参数为被关闭的 `message` 实例 */ /** 关闭时的回调函数, 参数为被关闭的 `message` 实例 */
onClose?: Function | null; onClose?: Function | null;
} }
@@ -48,28 +50,30 @@ const message = (
const { const {
icon, icon,
type = "info", type = "info",
plain = false,
dangerouslyUseHTMLString = false, dangerouslyUseHTMLString = false,
customClass = "antd", customClass = "antd",
duration = 2000, duration = 2000,
showClose = false, showClose = false,
center = false, offset = 16,
offset = 20,
appendTo = document.body, appendTo = document.body,
grouping = false, grouping = false,
repeatNum = 1,
onClose onClose
} = params; } = params;
return ElMessage({ return ElMessage({
message, message,
type,
icon, icon,
type,
plain,
dangerouslyUseHTMLString, dangerouslyUseHTMLString,
duration, duration,
showClose, showClose,
center,
offset, offset,
appendTo, appendTo,
grouping, grouping,
repeatNum,
// 全局搜 pure-message 即可知道该类的样式位置 // 全局搜 pure-message 即可知道该类的样式位置
customClass: customClass === "antd" ? "pure-message" : "", customClass: customClass === "antd" ? "pure-message" : "",
onClose: () => (isFunction(onClose) ? onClose() : null) onClose: () => (isFunction(onClose) ? onClose() : null)

View File

@@ -140,8 +140,10 @@ Print.prototype = {
"position:absolute;width:0;height:0;top:-10px;left:-10px;" "position:absolute;width:0;height:0;top:-10px;left:-10px;"
); );
// eslint-disable-next-line prefer-const
w = f.contentWindow || f.contentDocument; w = f.contentWindow || f.contentDocument;
// eslint-disable-next-line prefer-const
doc = f.contentDocument || f.contentWindow.document; doc = f.contentDocument || f.contentWindow.document;
doc.open(); doc.open();
doc.write(content); doc.write(content);

View File

@@ -76,7 +76,7 @@ function onReset() {
immediate: true, immediate: true,
timeout: 1000 timeout: 1000
}" }"
class="!w-[200px]" class="w-[200px]!"
clearable clearable
@clear="onInput" @clear="onInput"
/> />
@@ -86,7 +86,7 @@ function onReset() {
<el-input <el-input
v-model="searchTwo" v-model="searchTwo"
v-optimize="{ event: 'input', fn: onInputTwo, timeout: 400 }" v-optimize="{ event: 'input', fn: onInputTwo, timeout: 400 }"
class="!w-[200px]" class="w-[200px]!"
clearable clearable
/> />
</div> </div>
@@ -100,7 +100,7 @@ function onReset() {
timeout: 400, timeout: 400,
params: { name: '小明', sex: '男' } params: { name: '小明', sex: '男' }
}" }"
class="!w-[200px]" class="w-[200px]!"
clearable clearable
/> />
</div> </div>
@@ -112,7 +112,7 @@ function onReset() {
<el-input <el-input
v-model="searchFour" v-model="searchFour"
v-optimize:throttle="{ event: 'input', fn: onInputFour, timeout: 1000 }" v-optimize:throttle="{ event: 'input', fn: onInputFour, timeout: 1000 }"
class="!w-[200px]" class="w-[200px]!"
clearable clearable
/> />
</div> </div>
@@ -125,7 +125,7 @@ function onReset() {
fn: onInputFive, fn: onInputFive,
params: { name: '小明', sex: '男' } params: { name: '小明', sex: '男' }
}" }"
class="!w-[200px]" class="w-[200px]!"
clearable clearable
/> />
</div> </div>
@@ -134,7 +134,7 @@ function onReset() {
<div class="mb-2"> <div class="mb-2">
文本复制指令(双击输入框内容即可复制) 文本复制指令(双击输入框内容即可复制)
<el-input v-model="searchSix" v-copy="searchSix" class="!w-[200px]" /> <el-input v-model="searchSix" v-copy="searchSix" class="w-[200px]!" />
</div> </div>
<div> <div>
文本复制指令(自定义触发事件,单击复制) 文本复制指令(自定义触发事件,单击复制)

View File

@@ -51,7 +51,9 @@ const load = () => {
代码位置 src/views/able/infinite-scroll.vue 代码位置 src/views/able/infinite-scroll.vue
</el-link> </el-link>
</template> </template>
<p class="mb-2">{{ isBottom ? "已加载全部页" : `加载到第 ${page}` }}</p> <div class="mb-2">
{{ isBottom ? "已加载全部页" : `加载到第 ${page}` }}
</div>
<el-table <el-table
v-el-table-infinite-scroll="load" v-el-table-infinite-scroll="load"
border border

View File

@@ -7,7 +7,7 @@ import { useRenderIcon } from "@/components/ReIcon/src/hooks";
import { extractPathList, deleteChildren } from "@/utils/tree"; import { extractPathList, deleteChildren } from "@/utils/tree";
import { usePermissionStoreHook } from "@/store/modules/permission"; import { usePermissionStoreHook } from "@/store/modules/permission";
import type { TreeNode } from "element-plus/es/components/tree-v2/src/types"; import type { TreeNode } from "element-plus/es/components/tree-v2/src/types";
import NodeTree from "@iconify-icons/ri/node-tree"; import NodeTree from "~icons/ri/node-tree";
defineOptions({ defineOptions({
name: "MenuTree" name: "MenuTree"

View File

@@ -194,7 +194,7 @@ onUnmounted(() => {
基于 基于
<el-link <el-link
type="primary" type="primary"
:underline="false" underline="never"
href="https://github.com/mqttjs/MQTT.js" href="https://github.com/mqttjs/MQTT.js"
target="_blank" target="_blank"
> >
@@ -203,7 +203,7 @@ onUnmounted(() => {
免费的公共MQTT代理 免费的公共MQTT代理
<el-link <el-link
type="primary" type="primary"
:underline="false" underline="never"
href="broker.emqx.io" href="broker.emqx.io"
target="_blank" target="_blank"
> >

View File

@@ -21,8 +21,8 @@ defineOptions({
</div> </div>
</template> </template>
<p v-html="html('带 音 调')" /> <p v-html="html('带 音 调')" />
<p class="mt-2" v-html="html('不 带 音 调', { toneType: 'none' })" /> <p class="mt-2!" v-html="html('不 带 音 调', { toneType: 'none' })" />
<p class="mt-2 custom" v-html="html('自 定 义 样 式')" /> <p class="mt-2! custom" v-html="html('自 定 义 样 式')" />
</el-card> </el-card>
</template> </template>

View File

@@ -83,7 +83,7 @@ const tableData: User[] = [
<span class="font-medium">打印功能报表图表图片</span> <span class="font-medium">打印功能报表图表图片</span>
<el-select <el-select
v-model="value" v-model="value"
class="!w-[100px] mr-2" class="w-[100px]! mr-2"
placeholder="Select" placeholder="Select"
size="small" size="small"
> >

View File

@@ -45,6 +45,6 @@ function onInput() {
</el-tag> </el-tag>
</div> </div>
<el-input v-model="modelValue" @input="onInput" /> <el-input v-model="modelValue" @input="onInput" />
<p class="mt-2">{{ modelValue }}</p> <p class="mt-2!">{{ modelValue }}</p>
</el-card> </el-card>
</template> </template>

View File

@@ -2,7 +2,7 @@
import { onMounted } from "vue"; import { onMounted } from "vue";
import { deviceDetection } from "@pureadmin/utils"; import { deviceDetection } from "@pureadmin/utils";
import { useRenderIcon } from "@/components/ReIcon/src/hooks"; import { useRenderIcon } from "@/components/ReIcon/src/hooks";
import VideoPlay from "@iconify-icons/ep/video-play"; import VideoPlay from "~icons/ep/video-play";
import Player from "xgplayer"; import Player from "xgplayer";
import "xgplayer/dist/index.min.css"; import "xgplayer/dist/index.min.css";

View File

@@ -53,7 +53,7 @@ onBeforeUnmount(() => {
代码位置 src/views/able/watermark.vue 代码位置 src/views/able/watermark.vue
</el-link> </el-link>
</template> </template>
<el-space wrap class="!mb-2"> <el-space wrap class="mb-2!">
<span> 请输入要创建水印的值</span> <span> 请输入要创建水印的值</span>
<el-input v-model="value" class="mr-4" style="width: 200px" clearable /> <el-input v-model="value" class="mr-4" style="width: 200px" clearable />
<span>请选择要创建水印的颜色</span> <span>请选择要创建水印的颜色</span>

View File

@@ -103,13 +103,13 @@ onBeforeUnmount(() => {
</template> </template>
<div <div
v-loading="loading" v-loading="loading"
class="w-8/12 !m-auto !mt-[20px]" class="w-8/12 m-auto! mt-[20px]!"
element-loading-background="transparent" element-loading-background="transparent"
> >
<div ref="wavesurferRef" /> <div ref="wavesurferRef" />
<div v-show="totalTime" class="flex justify-between"> <div v-show="totalTime" class="flex justify-between">
<span class="text-[#81888f]">00:00</span> <span class="text-[#81888f]">00:00</span>
<h1 class="text-4xl mt-2">{{ curTime }}</h1> <h1 class="text-4xl mt-2!">{{ curTime }}</h1>
<span class="text-[#81888f]">{{ totalTime }}</span> <span class="text-[#81888f]">{{ totalTime }}</span>
</div> </div>
<div v-show="totalTime" class="flex mt-2 w-[180px] justify-around m-auto"> <div v-show="totalTime" class="flex mt-2 w-[180px] justify-around m-auto">

View File

@@ -7,7 +7,7 @@ export function useColumns() {
minWidth: 100, minWidth: 100,
cellRenderer: () => { cellRenderer: () => {
return ( return (
<el-tag size="large" class="!text-base"> <el-tag size="large" class="text-base!">
{version} {version}
</el-tag> </el-tag>
); );
@@ -18,7 +18,7 @@ export function useColumns() {
minWidth: 120, minWidth: 120,
cellRenderer: () => { cellRenderer: () => {
return ( return (
<el-tag size="large" class="!text-base"> <el-tag size="large" class="text-base!">
{lastBuildTime} {lastBuildTime}
</el-tag> </el-tag>
); );
@@ -29,7 +29,7 @@ export function useColumns() {
minWidth: 140, minWidth: 140,
cellRenderer: () => { cellRenderer: () => {
return ( return (
<el-tag size="large" class="!text-base"> <el-tag size="large" class="text-base!">
{engines.node} {engines.node}
</el-tag> </el-tag>
); );
@@ -40,7 +40,7 @@ export function useColumns() {
minWidth: 140, minWidth: 140,
cellRenderer: () => { cellRenderer: () => {
return ( return (
<el-tag size="large" class="!text-base"> <el-tag size="large" class="text-base!">
{engines.pnpm} {engines.pnpm}
</el-tag> </el-tag>
); );

View File

@@ -43,7 +43,7 @@ function onClick(item) {
deviceDetection() ? 'max-w-[100%]' : 'max-w-[70%]' deviceDetection() ? 'max-w-[100%]' : 'max-w-[70%]'
]" ]"
> >
<h3 class="my-8">账户管理</h3> <h3 class="my-8!">账户管理</h3>
<div v-for="(item, index) in list" :key="index"> <div v-for="(item, index) in list" :key="index">
<div class="flex items-center"> <div class="flex items-center">
<div class="flex-1"> <div class="flex-1">

View File

@@ -38,7 +38,7 @@ function onChange(val, item) {
deviceDetection() ? 'max-w-[100%]' : 'max-w-[70%]' deviceDetection() ? 'max-w-[100%]' : 'max-w-[70%]'
]" ]"
> >
<h3 class="my-8">偏好设置</h3> <h3 class="my-8!">偏好设置</h3>
<div v-for="(item, index) in list" :key="index"> <div v-for="(item, index) in list" :key="index">
<div class="flex items-center"> <div class="flex items-center">
<div class="flex-1"> <div class="flex-1">

View File

@@ -6,7 +6,7 @@ import { type UserInfo, getMine } from "@/api/user";
import type { FormInstance, FormRules } from "element-plus"; import type { FormInstance, FormRules } from "element-plus";
import ReCropperPreview from "@/components/ReCropperPreview"; import ReCropperPreview from "@/components/ReCropperPreview";
import { createFormData, deviceDetection } from "@pureadmin/utils"; import { createFormData, deviceDetection } from "@pureadmin/utils";
import uploadLine from "@iconify-icons/ri/upload-line"; import uploadLine from "~icons/ri/upload-line";
defineOptions({ defineOptions({
name: "Profile" name: "Profile"
@@ -110,7 +110,7 @@ getMine().then(res => {
deviceDetection() ? 'max-w-[100%]' : 'max-w-[70%]' deviceDetection() ? 'max-w-[100%]' : 'max-w-[70%]'
]" ]"
> >
<h3 class="my-8">个人信息</h3> <h3 class="my-8!">个人信息</h3>
<el-form <el-form
ref="userInfoFormRef" ref="userInfoFormRef"
label-position="top" label-position="top"
@@ -128,7 +128,7 @@ getMine().then(res => {
:show-file-list="false" :show-file-list="false"
:on-change="onChange" :on-change="onChange"
> >
<el-button plain class="ml-4"> <el-button plain class="ml-4!">
<IconifyIconOffline :icon="uploadLine" /> <IconifyIconOffline :icon="uploadLine" />
<span class="ml-2">更新头像</span> <span class="ml-2">更新头像</span>
</el-button> </el-button>

View File

@@ -78,7 +78,7 @@ onMounted(() => {
deviceDetection() ? 'max-w-[100%]' : 'max-w-[70%]' deviceDetection() ? 'max-w-[100%]' : 'max-w-[70%]'
]" ]"
> >
<h3 class="my-8">安全日志</h3> <h3 class="my-8!">安全日志</h3>
<pure-table <pure-table
row-key="id" row-key="id"
table-layout="auto" table-layout="auto"

View File

@@ -11,11 +11,11 @@ import AccountManagement from "./components/AccountManagement.vue";
import { useDataThemeChange } from "@/layout/hooks/useDataThemeChange"; import { useDataThemeChange } from "@/layout/hooks/useDataThemeChange";
import LaySidebarTopCollapse from "@/layout/components/lay-sidebar/components/SidebarTopCollapse.vue"; import LaySidebarTopCollapse from "@/layout/components/lay-sidebar/components/SidebarTopCollapse.vue";
import leftLine from "@iconify-icons/ri/arrow-left-s-line"; import leftLine from "~icons/ri/arrow-left-s-line";
import ProfileIcon from "@iconify-icons/ri/user-3-line"; import ProfileIcon from "~icons/ri/user-3-line";
import PreferencesIcon from "@iconify-icons/ri/settings-3-line"; import PreferencesIcon from "~icons/ri/settings-3-line";
import SecurityLogIcon from "@iconify-icons/ri/window-line"; import SecurityLogIcon from "~icons/ri/window-line";
import AccountManagementIcon from "@iconify-icons/ri/profile-line"; import AccountManagementIcon from "~icons/ri/profile-line";
defineOptions({ defineOptions({
name: "AccountSettings" name: "AccountSettings"
@@ -70,26 +70,28 @@ getMine().then(res => {
<el-container class="h-full"> <el-container class="h-full">
<el-aside <el-aside
v-if="isOpen" v-if="isOpen"
class="pure-account-settings overflow-hidden px-2 dark:!bg-[var(--el-bg-color)] border-r-[1px] border-[var(--pure-border-color)]" class="pure-account-settings overflow-hidden px-2 dark:bg-(--el-bg-color)! border-r-[1px] border-[var(--pure-border-color)]"
:width="deviceDetection() ? '180px' : '240px'" :width="deviceDetection() ? '180px' : '240px'"
> >
<el-menu :default-active="witchPane" class="pure-account-settings-menu"> <el-menu :default-active="witchPane" class="pure-account-settings-menu">
<el-menu-item <div
class="hover:!transition-all hover:!duration-200 hover:!text-base !h-[50px]" class="h-[50px]! text-[var(--pure-theme-menu-text)] cursor-pointer text-sm transition-all duration-300 ease-in-out hover:scale-105 will-change-transform transform-gpu origin-center hover:text-base! hover:text-[var(--pure-theme-menu-title-hover)]!"
@click="router.go(-1)" @click="router.go(-1)"
> >
<div class="flex items-center"> <div
class="h-full flex items-center px-[var(--el-menu-base-level-padding)]"
>
<IconifyIconOffline :icon="leftLine" /> <IconifyIconOffline :icon="leftLine" />
<span class="ml-2">返回</span> <span class="ml-2">返回</span>
</div> </div>
</el-menu-item> </div>
<div class="flex items-center ml-8 mt-4 mb-4"> <div class="flex items-center ml-8 mt-4 mb-4">
<el-avatar :size="48" :src="userInfo.avatar" /> <el-avatar :size="48" :src="userInfo.avatar" />
<div class="ml-4 flex flex-col max-w-[130px]"> <div class="ml-4 flex flex-col max-w-[130px]">
<ReText class="font-bold !self-baseline"> <ReText class="font-bold self-baseline!">
{{ userInfo.nickname }} {{ userInfo.nickname }}
</ReText> </ReText>
<ReText class="!self-baseline" type="info"> <ReText class="self-baseline!" type="info">
{{ userInfo.username }} {{ userInfo.username }}
</ReText> </ReText>
</div> </div>

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