Merge remote-tracking branch 'yudao/master' into dev-to-dev
This commit is contained in:
commit
0b06f36aa2
10
.vscode/extensions.json
vendored
10
.vscode/extensions.json
vendored
@ -1,15 +1,19 @@
|
|||||||
{
|
{
|
||||||
"recommendations": [
|
"recommendations": [
|
||||||
"voorjaar.windicss-intellisense",
|
"christian-kohler.path-intellisense",
|
||||||
"vscode-icons-team.vscode-icons",
|
"vscode-icons-team.vscode-icons",
|
||||||
"davidanson.vscode-markdownlint",
|
"davidanson.vscode-markdownlint",
|
||||||
"stylelint.vscode-stylelint",
|
"stylelint.vscode-stylelint",
|
||||||
"dbaeumer.vscode-eslint",
|
"dbaeumer.vscode-eslint",
|
||||||
"esbenp.prettier-vscode",
|
"esbenp.prettier-vscode",
|
||||||
"vue.volar",
|
"mrmlnc.vscode-less",
|
||||||
"lokalise.i18n-ally",
|
"lokalise.i18n-ally",
|
||||||
|
"redhat.vscode-yaml",
|
||||||
|
"csstools.postcss",
|
||||||
"mikestead.dotenv",
|
"mikestead.dotenv",
|
||||||
"eamodio.gitlens",
|
"eamodio.gitlens",
|
||||||
"antfu.iconify"
|
"antfu.iconify",
|
||||||
|
"antfu.unocss",
|
||||||
|
"Vue.volar"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
16
.vscode/settings.json
vendored
16
.vscode/settings.json
vendored
@ -102,14 +102,12 @@
|
|||||||
"i18n-ally.displayLanguage": "zh-CN",
|
"i18n-ally.displayLanguage": "zh-CN",
|
||||||
"i18n-ally.enabledFrameworks": ["vue", "react"],
|
"i18n-ally.enabledFrameworks": ["vue", "react"],
|
||||||
"cSpell.words": [
|
"cSpell.words": [
|
||||||
"vben",
|
"xingyu",
|
||||||
"windicss",
|
"yudao",
|
||||||
"tailwind",
|
"unocss",
|
||||||
"browserslist",
|
"browserslist",
|
||||||
"tailwindcss",
|
|
||||||
"esnext",
|
"esnext",
|
||||||
"antv",
|
"unplugin",
|
||||||
"tinymce",
|
|
||||||
"qrcode",
|
"qrcode",
|
||||||
"sider",
|
"sider",
|
||||||
"pinia",
|
"pinia",
|
||||||
@ -123,8 +121,9 @@
|
|||||||
"codemirror",
|
"codemirror",
|
||||||
"iconify",
|
"iconify",
|
||||||
"commitlint",
|
"commitlint",
|
||||||
"vditor",
|
"videojs",
|
||||||
"echarts",
|
"echarts",
|
||||||
|
"wangeditor",
|
||||||
"cropperjs",
|
"cropperjs",
|
||||||
"logicflow",
|
"logicflow",
|
||||||
"vueuse",
|
"vueuse",
|
||||||
@ -132,8 +131,7 @@
|
|||||||
"lintstagedrc",
|
"lintstagedrc",
|
||||||
"brotli",
|
"brotli",
|
||||||
"sider",
|
"sider",
|
||||||
"pnpm",
|
"pnpm"
|
||||||
"antd"
|
|
||||||
],
|
],
|
||||||
"vetur.format.scriptInitialIndent": true,
|
"vetur.format.scriptInitialIndent": true,
|
||||||
"vetur.format.styleInitialIndent": true,
|
"vetur.format.styleInitialIndent": true,
|
||||||
|
30
README.md
30
README.md
@ -24,7 +24,7 @@
|
|||||||
* 改换 saas,自动引入等功能
|
* 改换 saas,自动引入等功能
|
||||||
* 使用 Element Plus 免费开源的中后台模版,具备如下特性:
|
* 使用 Element Plus 免费开源的中后台模版,具备如下特性:
|
||||||
|
|
||||||
![首页](preview/home.png)
|
![首页](public/home.png)
|
||||||
|
|
||||||
* **最新技术栈**:使用 Vue3、Vite4 等前端前沿技术开发
|
* **最新技术栈**:使用 Vue3、Vite4 等前端前沿技术开发
|
||||||
* **TypeScript**: 应用程序级 JavaScript 的语言
|
* **TypeScript**: 应用程序级 JavaScript 的语言
|
||||||
@ -39,15 +39,15 @@
|
|||||||
| 框架 | 说明 | 版本 |
|
| 框架 | 说明 | 版本 |
|
||||||
|----------------------------------------------------------------------|------------------|--------|
|
|----------------------------------------------------------------------|------------------|--------|
|
||||||
| [Vue](https://staging-cn.vuejs.org/) | Vue 框架 | 3.3.4 |
|
| [Vue](https://staging-cn.vuejs.org/) | Vue 框架 | 3.3.4 |
|
||||||
| [Vite](https://cn.vitejs.dev//) | 开发与构建工具 | 4.3.9 |
|
| [Vite](https://cn.vitejs.dev//) | 开发与构建工具 | 4.4.7 |
|
||||||
| [Element Plus](https://element-plus.org/zh-CN/) | Element Plus | 2.3.7 |
|
| [Element Plus](https://element-plus.org/zh-CN/) | Element Plus | 2.3.8 |
|
||||||
| [TypeScript](https://www.typescriptlang.org/docs/) | JavaScript 的超集 | 5.0.4 |
|
| [TypeScript](https://www.typescriptlang.org/docs/) | JavaScript 的超集 | 5.1.6 |
|
||||||
| [pinia](https://pinia.vuejs.org/) | Vue 存储库 替代 vuex5 | 2.1.4 |
|
| [pinia](https://pinia.vuejs.org/) | Vue 存储库 替代 vuex5 | 2.1.6 |
|
||||||
| [vueuse](https://vueuse.org/) | 常用工具集 | 10.2.0 |
|
| [vueuse](https://vueuse.org/) | 常用工具集 | 10.2.1 |
|
||||||
| [vue-i18n](https://kazupon.github.io/vue-i18n/zh/introduction.html/) | 国际化 | 9.2.2 |
|
| [vue-i18n](https://kazupon.github.io/vue-i18n/zh/introduction.html/) | 国际化 | 9.2.2 |
|
||||||
| [vue-router](https://router.vuejs.org/) | Vue 路由 | 4.2.1 |
|
| [vue-router](https://router.vuejs.org/) | Vue 路由 | 4.2.4 |
|
||||||
| [windicss](https://cn.windicss.org/) | 下一代工具优先的 CSS 框架 | 3.5.6 |
|
| [unocss](https://uno.antfu.me/) | 原子 css | 0.54.0 |
|
||||||
| [iconify](https://icon-sets.iconify.design/) | 在线图标库 | 3.1.0 |
|
| [iconify](https://icon-sets.iconify.design/) | 在线图标库 | 3.1.1 |
|
||||||
| [wangeditor](https://www.wangeditor.com/) | 富文本编辑器 | 5.1.23 |
|
| [wangeditor](https://www.wangeditor.com/) | 富文本编辑器 | 5.1.23 |
|
||||||
|
|
||||||
## 开发工具
|
## 开发工具
|
||||||
@ -56,14 +56,14 @@
|
|||||||
|
|
||||||
| 插件名 | 功能 |
|
| 插件名 | 功能 |
|
||||||
|-------------------------------|--------------------------|
|
|-------------------------------|--------------------------|
|
||||||
| TypeScript Vue Plugin (Volar) | 用于 TypeScript 的 Vue 插件 |
|
| TypeScript Vue Plugin (Volar) | 用于 TypeScript 的 Vue 插件 |
|
||||||
| Vue Language Features (Volar) | Vue3.0 语法支持 |
|
| Vue Language Features (Volar) | Vue3.0 语法支持 |
|
||||||
| WindiCSS IntelliSense | 自动完成、语法突出显示、代码折叠和构建等高级功能 |
|
| unocss | unocss for vscode |
|
||||||
| Iconify IntelliSense | Iconify 预览和搜索 |
|
| Iconify IntelliSense | Iconify 预览和搜索 |
|
||||||
| i18n Ally | 国际化智能提示 |
|
| i18n Ally | 国际化智能提示 |
|
||||||
| Stylelint | Css 格式化 |
|
| Stylelint | Css 格式化 |
|
||||||
| Prettier | 代码格式化 |
|
| Prettier | 代码格式化 |
|
||||||
| ESLint | 脚本代码检查 |
|
| ESLint | 脚本代码检查 |
|
||||||
| DotENV | env 文件高亮 |
|
| DotENV | env 文件高亮 |
|
||||||
|
|
||||||
## 内置功能
|
## 内置功能
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import { resolve } from 'path'
|
import { resolve } from 'path'
|
||||||
import Vue from '@vitejs/plugin-vue'
|
import Vue from '@vitejs/plugin-vue'
|
||||||
import VueJsx from '@vitejs/plugin-vue-jsx'
|
import VueJsx from '@vitejs/plugin-vue-jsx'
|
||||||
import WindiCSS from 'vite-plugin-windicss'
|
|
||||||
import progress from 'vite-plugin-progress'
|
import progress from 'vite-plugin-progress'
|
||||||
import EslintPlugin from 'vite-plugin-eslint'
|
import EslintPlugin from 'vite-plugin-eslint'
|
||||||
import PurgeIcons from 'vite-plugin-purge-icons'
|
import PurgeIcons from 'vite-plugin-purge-icons'
|
||||||
@ -15,6 +14,7 @@ import viteCompression from 'vite-plugin-compression'
|
|||||||
import topLevelAwait from 'vite-plugin-top-level-await'
|
import topLevelAwait from 'vite-plugin-top-level-await'
|
||||||
import VueI18nPlugin from '@intlify/unplugin-vue-i18n/vite'
|
import VueI18nPlugin from '@intlify/unplugin-vue-i18n/vite'
|
||||||
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'
|
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'
|
||||||
|
import UnoCSS from 'unocss/vite'
|
||||||
|
|
||||||
export function createVitePlugins() {
|
export function createVitePlugins() {
|
||||||
const root = process.cwd()
|
const root = process.cwd()
|
||||||
@ -27,7 +27,7 @@ export function createVitePlugins() {
|
|||||||
return [
|
return [
|
||||||
Vue(),
|
Vue(),
|
||||||
VueJsx(),
|
VueJsx(),
|
||||||
WindiCSS(),
|
UnoCSS(),
|
||||||
progress(),
|
progress(),
|
||||||
PurgeIcons(),
|
PurgeIcons(),
|
||||||
ElementPlus({}),
|
ElementPlus({}),
|
||||||
|
@ -8,7 +8,7 @@ const include = [
|
|||||||
'pinia',
|
'pinia',
|
||||||
'dayjs',
|
'dayjs',
|
||||||
'qrcode',
|
'qrcode',
|
||||||
'windicss',
|
'unocss',
|
||||||
'vue-router',
|
'vue-router',
|
||||||
'vue-types',
|
'vue-types',
|
||||||
'vue-i18n',
|
'vue-i18n',
|
||||||
|
91
package.json
91
package.json
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "yudao-ui-admin-vue3",
|
"name": "yudao-ui-admin-vue3",
|
||||||
"version": "1.7.3-snapshot",
|
"version": "1.8.0-snapshot",
|
||||||
"description": "基于vue3、vite4、element-plus、typesScript",
|
"description": "基于vue3、vite4、element-plus、typesScript",
|
||||||
"author": "xingyu",
|
"author": "xingyu",
|
||||||
"private": false,
|
"private": false,
|
||||||
@ -32,12 +32,12 @@
|
|||||||
"@element-plus/icons-vue": "^2.1.0",
|
"@element-plus/icons-vue": "^2.1.0",
|
||||||
"@form-create/designer": "^3.1.0",
|
"@form-create/designer": "^3.1.0",
|
||||||
"@form-create/element-ui": "^3.1.17",
|
"@form-create/element-ui": "^3.1.17",
|
||||||
"@iconify/iconify": "^3.1.0",
|
"@iconify/iconify": "^3.1.1",
|
||||||
"@videojs-player/vue": "^1.0.0",
|
"@videojs-player/vue": "^1.0.0",
|
||||||
"@vueuse/core": "^10.2.0",
|
"@vueuse/core": "^10.2.1",
|
||||||
"@wangeditor/editor": "^5.1.23",
|
"@wangeditor/editor": "^5.1.23",
|
||||||
"@wangeditor/editor-for-vue": "^5.1.10",
|
"@wangeditor/editor-for-vue": "^5.1.10",
|
||||||
"@zxcvbn-ts/core": "^3.0.2",
|
"@zxcvbn-ts/core": "^3.0.3",
|
||||||
"animate.css": "^4.1.1",
|
"animate.css": "^4.1.1",
|
||||||
"axios": "^1.4.0",
|
"axios": "^1.4.0",
|
||||||
"benz-amr-recorder": "^1.1.5",
|
"benz-amr-recorder": "^1.1.5",
|
||||||
@ -45,79 +45,82 @@
|
|||||||
"camunda-bpmn-moddle": "^7.0.1",
|
"camunda-bpmn-moddle": "^7.0.1",
|
||||||
"cropperjs": "^1.5.13",
|
"cropperjs": "^1.5.13",
|
||||||
"crypto-js": "^4.1.1",
|
"crypto-js": "^4.1.1",
|
||||||
"dayjs": "^1.11.8",
|
"dayjs": "^1.11.9",
|
||||||
"diagram-js": "^11.6.0",
|
"diagram-js": "^11.6.0",
|
||||||
"echarts": "^5.4.2",
|
"echarts": "^5.4.3",
|
||||||
"echarts-wordcloud": "^2.1.0",
|
"echarts-wordcloud": "^2.1.0",
|
||||||
"element-plus": "2.3.7",
|
"element-plus": "2.3.8",
|
||||||
"fast-xml-parser": "^4.2.4",
|
"fast-xml-parser": "^4.2.6",
|
||||||
"highlight.js": "^11.8.0",
|
"highlight.js": "^11.8.0",
|
||||||
"intro.js": "^7.0.1",
|
"intro.js": "^7.0.1",
|
||||||
"jsencrypt": "^3.3.2",
|
"jsencrypt": "^3.3.2",
|
||||||
"lodash-es": "^4.17.21",
|
"lodash-es": "^4.17.21",
|
||||||
"min-dash": "^4.1.1",
|
"min-dash": "^4.1.1",
|
||||||
"mitt": "^3.0.0",
|
"mitt": "^3.0.1",
|
||||||
"nprogress": "^0.2.0",
|
"nprogress": "^0.2.0",
|
||||||
"pinia": "^2.1.4",
|
"pinia": "^2.1.6",
|
||||||
"qrcode": "^1.5.3",
|
"qrcode": "^1.5.3",
|
||||||
"qs": "^6.11.2",
|
"qs": "^6.11.2",
|
||||||
"steady-xml": "^0.1.0",
|
"steady-xml": "^0.1.0",
|
||||||
"url": "^0.11.1",
|
"url": "^0.11.1",
|
||||||
"video.js": "^8.3.0",
|
"video.js": "^7.21.5",
|
||||||
"vue": "3.3.4",
|
"vue": "3.3.4",
|
||||||
"vue-dompurify-html": "^4.1.4",
|
"vue-dompurify-html": "^4.1.4",
|
||||||
"vue-i18n": "9.2.2",
|
"vue-i18n": "9.2.2",
|
||||||
"vue-router": "^4.2.2",
|
"vue-router": "^4.2.4",
|
||||||
"vue-types": "^5.0.4",
|
"vue-types": "^5.1.1",
|
||||||
"vuedraggable": "^4.1.0",
|
"vuedraggable": "^4.1.0",
|
||||||
"web-storage-cache": "^1.1.1",
|
"web-storage-cache": "^1.1.1",
|
||||||
"xml-js": "^1.6.11"
|
"xml-js": "^1.6.11"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@commitlint/cli": "^17.6.5",
|
"@commitlint/cli": "^17.6.7",
|
||||||
"@commitlint/config-conventional": "^17.6.5",
|
"@commitlint/config-conventional": "^17.6.7",
|
||||||
"@iconify/json": "^2.2.80",
|
"@iconify/json": "^2.2.95",
|
||||||
"@intlify/unplugin-vue-i18n": "^0.11.0",
|
"@intlify/unplugin-vue-i18n": "^0.12.2",
|
||||||
"@purge-icons/generated": "^0.9.0",
|
"@purge-icons/generated": "^0.9.0",
|
||||||
"@types/intro.js": "^5.1.1",
|
"@types/intro.js": "^5.1.1",
|
||||||
"@types/lodash-es": "^4.17.7",
|
"@types/lodash-es": "^4.17.8",
|
||||||
"@types/node": "^20.3.1",
|
"@types/node": "^20.4.0",
|
||||||
"@types/nprogress": "^0.2.0",
|
"@types/nprogress": "^0.2.0",
|
||||||
"@types/qrcode": "^1.5.0",
|
"@types/qrcode": "^1.5.1",
|
||||||
"@types/qs": "^6.9.7",
|
"@types/qs": "^6.9.7",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.59.11",
|
"@typescript-eslint/eslint-plugin": "^6.2.0",
|
||||||
"@typescript-eslint/parser": "^5.59.11",
|
"@typescript-eslint/parser": "^6.2.0",
|
||||||
"@vitejs/plugin-legacy": "^4.0.4",
|
"@unocss/transformer-variant-group": "^0.51.4",
|
||||||
|
"@vitejs/plugin-legacy": "^4.1.1",
|
||||||
"@vitejs/plugin-vue": "^4.2.3",
|
"@vitejs/plugin-vue": "^4.2.3",
|
||||||
"@vitejs/plugin-vue-jsx": "^3.0.1",
|
"@vitejs/plugin-vue-jsx": "^3.0.1",
|
||||||
|
"@vue-macros/volar": "^0.12.3",
|
||||||
"autoprefixer": "^10.4.14",
|
"autoprefixer": "^10.4.14",
|
||||||
"bpmn-js": "^8.9.0",
|
"bpmn-js": "^8.9.0",
|
||||||
"bpmn-js-properties-panel": "^0.46.0",
|
"bpmn-js-properties-panel": "^0.46.0",
|
||||||
"consola": "^3.1.0",
|
"consola": "^3.2.3",
|
||||||
"eslint": "^8.43.0",
|
"eslint": "^8.46.0",
|
||||||
"eslint-config-prettier": "^8.8.0",
|
"eslint-config-prettier": "^8.9.0",
|
||||||
"eslint-define-config": "^1.21.0",
|
"eslint-define-config": "^1.21.0",
|
||||||
"eslint-plugin-prettier": "^4.2.1",
|
"eslint-plugin-prettier": "^5.0.0",
|
||||||
"eslint-plugin-vue": "^9.15.0",
|
"eslint-plugin-vue": "^9.15.1",
|
||||||
"lint-staged": "^13.2.2",
|
"lint-staged": "^13.2.3",
|
||||||
"postcss": "^8.4.24",
|
"postcss": "^8.4.27",
|
||||||
"postcss-html": "^1.5.0",
|
"postcss-html": "^1.5.0",
|
||||||
"postcss-scss": "^4.0.6",
|
"postcss-scss": "^4.0.6",
|
||||||
"prettier": "^2.8.8",
|
"prettier": "^3.0.0",
|
||||||
"rimraf": "^5.0.1",
|
"rimraf": "^5.0.1",
|
||||||
"rollup": "^3.25.1",
|
"rollup": "^3.27.0",
|
||||||
"sass": "^1.63.5",
|
"sass": "^1.64.1",
|
||||||
"stylelint": "^15.8.0",
|
"stylelint": "^15.10.2",
|
||||||
"stylelint-config-recommended": "^12.0.0",
|
"stylelint-config-recommended": "^13.0.0",
|
||||||
"stylelint-config-recommended-vue": "^1.4.0",
|
"stylelint-config-recommended-vue": "^1.5.0",
|
||||||
"stylelint-config-standard": "^33.0.0",
|
"stylelint-config-standard": "^34.0.0",
|
||||||
"stylelint-order": "^6.0.3",
|
"stylelint-order": "^6.0.3",
|
||||||
"terser": "^5.18.1",
|
"terser": "^5.19.2",
|
||||||
"typescript": "5.0.4",
|
"typescript": "5.1.6",
|
||||||
"unplugin-auto-import": "^0.16.4",
|
"unocss": "^0.54.0",
|
||||||
"unplugin-element-plus": "^0.7.1",
|
"unplugin-auto-import": "^0.16.6",
|
||||||
|
"unplugin-element-plus": "^0.7.2",
|
||||||
"unplugin-vue-components": "^0.25.1",
|
"unplugin-vue-components": "^0.25.1",
|
||||||
"vite": "4.3.9",
|
"vite": "4.4.7",
|
||||||
"vite-plugin-compression": "^0.5.1",
|
"vite-plugin-compression": "^0.5.1",
|
||||||
"vite-plugin-ejs": "^1.6.4",
|
"vite-plugin-ejs": "^1.6.4",
|
||||||
"vite-plugin-eslint": "^1.8.1",
|
"vite-plugin-eslint": "^1.8.1",
|
||||||
@ -125,9 +128,7 @@
|
|||||||
"vite-plugin-purge-icons": "^0.9.2",
|
"vite-plugin-purge-icons": "^0.9.2",
|
||||||
"vite-plugin-svg-icons": "^2.0.1",
|
"vite-plugin-svg-icons": "^2.0.1",
|
||||||
"vite-plugin-top-level-await": "^1.3.1",
|
"vite-plugin-top-level-await": "^1.3.1",
|
||||||
"vite-plugin-windicss": "^1.9.0",
|
"vue-tsc": "^1.8.8"
|
||||||
"vue-tsc": "^1.8.1",
|
|
||||||
"windicss": "^3.5.6"
|
|
||||||
},
|
},
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"repository": {
|
"repository": {
|
||||||
|
0
preview/home.png → public/home.png
Executable file → Normal file
0
preview/home.png → public/home.png
Executable file → Normal file
Before Width: | Height: | Size: 73 KiB After Width: | Height: | Size: 73 KiB |
@ -37,11 +37,6 @@ export const getInfo = () => {
|
|||||||
return request.get({ url: '/system/auth/get-permission-info' })
|
return request.get({ url: '/system/auth/get-permission-info' })
|
||||||
}
|
}
|
||||||
|
|
||||||
// 路由
|
|
||||||
export const getAsyncRoutes = () => {
|
|
||||||
return request.get({ url: '/system/auth/list-menus' })
|
|
||||||
}
|
|
||||||
|
|
||||||
//获取登录验证码
|
//获取登录验证码
|
||||||
export const sendSmsCode = (data: SmsCodeVO) => {
|
export const sendSmsCode = (data: SmsCodeVO) => {
|
||||||
return request.post({ url: '/system/auth/send-sms-code', data })
|
return request.post({ url: '/system/auth/send-sms-code', data })
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
import request from '@/config/axios'
|
import request from '@/config/axios'
|
||||||
import { Sku, Spu } from '@/api/mall/product/spu'
|
import { Sku, Spu } from '@/api/mall/product/spu'
|
||||||
|
|
||||||
|
// TODO @puhui999: combinationActivity.ts
|
||||||
|
|
||||||
export interface CombinationActivityVO {
|
export interface CombinationActivityVO {
|
||||||
id?: number
|
id?: number
|
||||||
name?: string
|
name?: string
|
||||||
|
@ -28,7 +28,7 @@ onMounted(() => {
|
|||||||
<div
|
<div
|
||||||
:class="[
|
:class="[
|
||||||
`${prefixCls}-header`,
|
`${prefixCls}-header`,
|
||||||
'flex border-bottom-1 h-50px items-center text-center pr-10px'
|
'flex b-b-1 h-50px items-center text-center bg-white pr-10px'
|
||||||
]"
|
]"
|
||||||
>
|
>
|
||||||
<div :class="[`${prefixCls}-header__back`, 'flex pl-10px pr-10px ']">
|
<div :class="[`${prefixCls}-header__back`, 'flex pl-10px pr-10px ']">
|
||||||
|
@ -222,7 +222,9 @@ $prefix-cls: #{$namespace}-cropper-am;
|
|||||||
transparent 75%,
|
transparent 75%,
|
||||||
rgb(0 0 0 / 25%) 0
|
rgb(0 0 0 / 25%) 0
|
||||||
);
|
);
|
||||||
background-position: 0 0, 12px 12px;
|
background-position:
|
||||||
|
0 0,
|
||||||
|
12px 12px;
|
||||||
background-size: 24px 24px;
|
background-size: 24px 24px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,14 +71,14 @@ const toggleClick = () => {
|
|||||||
<div
|
<div
|
||||||
:class="[
|
:class="[
|
||||||
prefixCls,
|
prefixCls,
|
||||||
'bg-[var(--el-color-white)] dark:(bg-[var(--el-bg-color)] border-[var(--el-border-color)] border-1px)'
|
'bg-[var(--el-color-white)] dark:bg-[var(--el-bg-color)] dark:border-[var(--el-border-color)] dark:border-1px'
|
||||||
]"
|
]"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
v-if="title"
|
v-if="title"
|
||||||
:class="[
|
:class="[
|
||||||
`${prefixCls}-header`,
|
`${prefixCls}-header`,
|
||||||
'h-50px flex justify-between items-center border-bottom-1 border-solid border-[var(--tags-view-border-color)] px-10px cursor-pointer dark:border-[var(--el-border-color)]'
|
'h-50px flex justify-between items-center b-b-1 border-solid border-[var(--el-border-color)] px-10px cursor-pointer dark:border-[var(--el-border-color)]'
|
||||||
]"
|
]"
|
||||||
@click="toggleClick"
|
@click="toggleClick"
|
||||||
>
|
>
|
||||||
|
@ -99,13 +99,19 @@ const dialogStyle = computed(() => {
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
.#{$elNamespace}-dialog__header {
|
.#{$elNamespace}-dialog {
|
||||||
margin-right: 0 !important;
|
&__header {
|
||||||
border-bottom: 1px solid var(--tags-view-border-color);
|
margin-right: 0 !important;
|
||||||
}
|
border-bottom: 1px solid var(--el-border-color);
|
||||||
|
}
|
||||||
|
|
||||||
.#{$elNamespace}-dialog__footer {
|
&__body {
|
||||||
border-top: 1px solid var(--tags-view-border-color);
|
padding: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__footer {
|
||||||
|
border-top: 1px solid var(--el-border-color);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.is-hover {
|
.is-hover {
|
||||||
@ -113,14 +119,4 @@ const dialogStyle = computed(() => {
|
|||||||
color: var(--el-color-primary) !important;
|
color: var(--el-color-primary) !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.dark {
|
|
||||||
.#{$elNamespace}-dialog__header {
|
|
||||||
border-bottom: 1px solid var(--el-border-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
.#{$elNamespace}-dialog__footer {
|
|
||||||
border-top: 1px solid var(--el-border-color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
@ -164,7 +164,6 @@ const handleChange = (editor: IDomEditor) => {
|
|||||||
// 组件销毁时,及时销毁编辑器
|
// 组件销毁时,及时销毁编辑器
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
const editor = unref(editorRef.value)
|
const editor = unref(editorRef.value)
|
||||||
if (editor === null) return
|
|
||||||
|
|
||||||
// 销毁,并移除 editor
|
// 销毁,并移除 editor
|
||||||
editor?.destroy()
|
editor?.destroy()
|
||||||
@ -181,12 +180,12 @@ defineExpose({
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="border-1 border-solid border-[var(--tags-view-border-color)] z-99">
|
<div class="border-1 border-solid border-[var(--el-border-color)] z-99">
|
||||||
<!-- 工具栏 -->
|
<!-- 工具栏 -->
|
||||||
<Toolbar
|
<Toolbar
|
||||||
:editor="editorRef"
|
:editor="editorRef"
|
||||||
:editorId="editorId"
|
:editorId="editorId"
|
||||||
class="border-bottom-1 border-solid border-[var(--tags-view-border-color)]"
|
class="border-0 b-b-1 border-solid border-[var(--el-border-color)]"
|
||||||
/>
|
/>
|
||||||
<!-- 编辑器 -->
|
<!-- 编辑器 -->
|
||||||
<Editor
|
<Editor
|
||||||
|
@ -114,7 +114,9 @@ $prefix-cls: #{$namespace}-input-password;
|
|||||||
height: inherit;
|
height: inherit;
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
border-radius: inherit;
|
border-radius: inherit;
|
||||||
transition: width 0.5s ease-in-out, background 0.25s;
|
transition:
|
||||||
|
width 0.5s ease-in-out,
|
||||||
|
background 0.25s;
|
||||||
|
|
||||||
&[data-score='0'] {
|
&[data-score='0'] {
|
||||||
width: 20%;
|
width: 20%;
|
||||||
|
@ -109,22 +109,22 @@ const elementBusinessObject = ref<any>({}) // 元素 businessObject 镜像,提
|
|||||||
const conditionFormVisible = ref(false) // 流转条件设置
|
const conditionFormVisible = ref(false) // 流转条件设置
|
||||||
const formVisible = ref(false) // 表单配置
|
const formVisible = ref(false) // 表单配置
|
||||||
const bpmnElement = ref()
|
const bpmnElement = ref()
|
||||||
const timer = ref()
|
|
||||||
provide('prefix', props.prefix)
|
provide('prefix', props.prefix)
|
||||||
provide('width', props.width)
|
provide('width', props.width)
|
||||||
const bpmnInstances = () => (window as any)?.bpmnInstances
|
const bpmnInstances = () => (window as any)?.bpmnInstances
|
||||||
const initModels = () => {
|
|
||||||
// console.log(props, 'props')
|
// 监听 props.bpmnModeler 然后 initModels
|
||||||
// console.log(props.bpmnModeler, 'sakdjjaskdsajdkasdjkadsjk')
|
const unwatchBpmn = watch(
|
||||||
// 初始化 modeler 以及其他 moddle
|
() => props.bpmnModeler,
|
||||||
// nextTick(() => {
|
() => {
|
||||||
if (!props.bpmnModeler) {
|
|
||||||
// 避免加载时 流程图 并未加载完成
|
// 避免加载时 流程图 并未加载完成
|
||||||
timer.value = setTimeout(() => initModels(), 10)
|
if (!props.bpmnModeler) {
|
||||||
return
|
console.log('缺少props.bpmnModeler')
|
||||||
}
|
return
|
||||||
if (timer.value) {
|
}
|
||||||
clearTimeout(timer.value)
|
|
||||||
|
console.log('props.bpmnModeler 有值了!!!')
|
||||||
const w = window as any
|
const w = window as any
|
||||||
w.bpmnInstances = {
|
w.bpmnInstances = {
|
||||||
modeler: props.bpmnModeler,
|
modeler: props.bpmnModeler,
|
||||||
@ -137,12 +137,16 @@ const initModels = () => {
|
|||||||
replace: props.bpmnModeler.get('replace'),
|
replace: props.bpmnModeler.get('replace'),
|
||||||
selection: props.bpmnModeler.get('selection')
|
selection: props.bpmnModeler.get('selection')
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
console.log(bpmnInstances(), 'window.bpmnInstances')
|
console.log(bpmnInstances(), 'window.bpmnInstances')
|
||||||
getActiveElement()
|
getActiveElement()
|
||||||
// })
|
unwatchBpmn()
|
||||||
}
|
},
|
||||||
|
{
|
||||||
|
immediate: true
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
const getActiveElement = () => {
|
const getActiveElement = () => {
|
||||||
// 初始第一个选中元素 bpmn:Process
|
// 初始第一个选中元素 bpmn:Process
|
||||||
initFormOnChanged(null)
|
initFormOnChanged(null)
|
||||||
@ -190,11 +194,7 @@ const initFormOnChanged = (element) => {
|
|||||||
)
|
)
|
||||||
formVisible.value = elementType.value === 'UserTask' || elementType.value === 'StartEvent'
|
formVisible.value = elementType.value === 'UserTask' || elementType.value === 'StartEvent'
|
||||||
}
|
}
|
||||||
onMounted(() => {
|
|
||||||
setTimeout(() => {
|
|
||||||
initModels()
|
|
||||||
}, 100)
|
|
||||||
})
|
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
const w = window as any
|
const w = window as any
|
||||||
w.bpmnInstances = null
|
w.bpmnInstances = null
|
||||||
|
@ -136,9 +136,7 @@ export const useTable = <T = any>(config?: UseTableConfig<T>) => {
|
|||||||
})
|
})
|
||||||
if (res) {
|
if (res) {
|
||||||
tableObject.tableList = (res as unknown as ResponseType).list
|
tableObject.tableList = (res as unknown as ResponseType).list
|
||||||
if ((res as unknown as ResponseType).total) {
|
tableObject.total = (res as unknown as ResponseType).total ?? 0
|
||||||
tableObject.total = (res as unknown as ResponseType).total as unknown as number
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
setProps: async (props: TableProps = {}) => {
|
setProps: async (props: TableProps = {}) => {
|
||||||
|
@ -18,26 +18,33 @@ const tagsViewStore = useTagsViewStore()
|
|||||||
const getCaches = computed((): string[] => {
|
const getCaches = computed((): string[] => {
|
||||||
return tagsViewStore.getCachedViews
|
return tagsViewStore.getCachedViews
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const tagsView = computed(() => appStore.getTagsView)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<section
|
<section
|
||||||
:class="[
|
:class="[
|
||||||
'p-[var(--app-content-padding)] w-[100%] bg-[var(--app-content-bg-color)] dark:bg-[var(--el-bg-color)]',
|
'p-[var(--app-content-padding)] w-[calc(100%-var(--app-content-padding)-var(--app-content-padding))] bg-[var(--app-content-bg-color)] dark:bg-[var(--el-bg-color)]',
|
||||||
{
|
{
|
||||||
'!min-h-[calc(100%-var(--app-footer-height))]':
|
'!min-h-[calc(100%-var(--app-content-padding)-var(--app-content-padding)-var(--app-footer-height))]':
|
||||||
((fixedHeader && (layout === 'classic' || layout === 'topLeft')) || layout === 'top') &&
|
(fixedHeader &&
|
||||||
footer,
|
(layout === 'classic' || layout === 'topLeft' || layout === 'top') &&
|
||||||
|
footer) ||
|
||||||
|
(!tagsView && layout === 'top' && footer),
|
||||||
|
'!min-h-[calc(100%-var(--app-content-padding)-var(--app-content-padding)-var(--app-footer-height)-var(--tags-view-height))]':
|
||||||
|
tagsView && layout === 'top' && footer,
|
||||||
|
|
||||||
'!min-h-[calc(100%-var(--tags-view-height)-var(--top-tool-height)-var(--app-footer-height))]':
|
'!min-h-[calc(100%-var(--tags-view-height)-var(--app-content-padding)-var(--app-content-padding)-var(--top-tool-height)-var(--app-footer-height))]':
|
||||||
!fixedHeader && layout === 'classic' && footer,
|
!fixedHeader && layout === 'classic' && footer,
|
||||||
|
|
||||||
'!min-h-[calc(100%-var(--tags-view-height)-var(--app-footer-height))]':
|
'!min-h-[calc(100%-var(--tags-view-height)-var(--app-content-padding)-var(--app-content-padding)-var(--app-footer-height))]':
|
||||||
!fixedHeader && (layout === 'topLeft' || layout === 'top') && footer,
|
!fixedHeader && layout === 'topLeft' && footer,
|
||||||
|
|
||||||
'!min-h-[calc(100%-var(--top-tool-height))]': fixedHeader && layout === 'cutMenu' && footer,
|
'!min-h-[calc(100%-var(--top-tool-height)-var(--app-content-padding)-var(--app-content-padding))]':
|
||||||
|
fixedHeader && layout === 'cutMenu' && footer,
|
||||||
|
|
||||||
'!min-h-[calc(100%-var(--top-tool-height)-var(--tags-view-height))]':
|
'!min-h-[calc(100%-var(--top-tool-height)-var(--app-content-padding)-var(--app-content-padding)-var(--tags-view-height))]':
|
||||||
!fixedHeader && layout === 'cutMenu' && footer
|
!fixedHeader && layout === 'cutMenu' && footer
|
||||||
}
|
}
|
||||||
]"
|
]"
|
||||||
|
@ -38,7 +38,7 @@ const setLang = (lang: LocaleType) => {
|
|||||||
:class="$attrs.class"
|
:class="$attrs.class"
|
||||||
:color="color"
|
:color="color"
|
||||||
:size="18"
|
:size="18"
|
||||||
class="cursor-pointer"
|
class="cursor-pointer !p-0"
|
||||||
icon="ion:language-sharp"
|
icon="ion:language-sharp"
|
||||||
/>
|
/>
|
||||||
<template #dropdown>
|
<template #dropdown>
|
||||||
|
@ -62,8 +62,7 @@ watch(
|
|||||||
:class="[
|
:class="[
|
||||||
prefixCls,
|
prefixCls,
|
||||||
layout !== 'classic' ? `${prefixCls}__Top` : '',
|
layout !== 'classic' ? `${prefixCls}__Top` : '',
|
||||||
'flex !h-[var(--logo-height)] items-center cursor-pointer justify-center relative',
|
'flex !h-[var(--logo-height)] items-center cursor-pointer pl-8px relative decoration-none overflow-hidden'
|
||||||
'dark:bg-[var(--el-bg-color)]'
|
|
||||||
]"
|
]"
|
||||||
to="/"
|
to="/"
|
||||||
>
|
>
|
||||||
|
@ -138,15 +138,6 @@ $prefix-cls: #{$namespace}-menu;
|
|||||||
position: relative;
|
position: relative;
|
||||||
transition: width var(--transition-time-02);
|
transition: width var(--transition-time-02);
|
||||||
|
|
||||||
&:after {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
right: 0;
|
|
||||||
height: 100%;
|
|
||||||
border-left: 1px solid var(--left-menu-border-color);
|
|
||||||
content: '';
|
|
||||||
}
|
|
||||||
|
|
||||||
:deep(.#{$elNamespace}-menu) {
|
:deep(.#{$elNamespace}-menu) {
|
||||||
width: 100% !important;
|
width: 100% !important;
|
||||||
border-right: none;
|
border-right: none;
|
||||||
|
@ -35,9 +35,12 @@ onMounted(() => {
|
|||||||
// 首次加载小红点
|
// 首次加载小红点
|
||||||
getUnreadCount()
|
getUnreadCount()
|
||||||
// 轮询刷新小红点
|
// 轮询刷新小红点
|
||||||
setInterval(() => {
|
setInterval(
|
||||||
getUnreadCount()
|
() => {
|
||||||
}, 1000 * 60 * 2)
|
getUnreadCount()
|
||||||
|
},
|
||||||
|
1000 * 60 * 2
|
||||||
|
)
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
|
@ -44,7 +44,6 @@ const setHeaderTheme = (color: string) => {
|
|||||||
setCssVar('--top-header-bg-color', color)
|
setCssVar('--top-header-bg-color', color)
|
||||||
setCssVar('--top-header-text-color', textColor)
|
setCssVar('--top-header-text-color', textColor)
|
||||||
setCssVar('--top-header-hover-color', textHoverColor)
|
setCssVar('--top-header-hover-color', textHoverColor)
|
||||||
setCssVar('--top-tool-border-color', topToolBorderColor)
|
|
||||||
appStore.setTheme({
|
appStore.setTheme({
|
||||||
topHeaderBgColor: color,
|
topHeaderBgColor: color,
|
||||||
topHeaderTextColor: textColor,
|
topHeaderTextColor: textColor,
|
||||||
|
@ -139,7 +139,7 @@ export default defineComponent({
|
|||||||
id={`${variables.namespace}-menu`}
|
id={`${variables.namespace}-menu`}
|
||||||
class={[
|
class={[
|
||||||
prefixCls,
|
prefixCls,
|
||||||
'relative bg-[var(--left-menu-bg-color)] top-1px z-3000',
|
'relative bg-[var(--left-menu-bg-color)] top-1px z-3000 layout-border__right',
|
||||||
{
|
{
|
||||||
'w-[var(--tab-menu-max-width)]': !unref(collapse),
|
'w-[var(--tab-menu-max-width)]': !unref(collapse),
|
||||||
'w-[var(--tab-menu-min-width)]': unref(collapse)
|
'w-[var(--tab-menu-min-width)]': unref(collapse)
|
||||||
@ -195,7 +195,7 @@ export default defineComponent({
|
|||||||
</div>
|
</div>
|
||||||
<Menu
|
<Menu
|
||||||
class={[
|
class={[
|
||||||
'!absolute top-0 border-left-1 border-solid border-[var(--left-menu-bg-light-color)]',
|
'!absolute top-0',
|
||||||
{
|
{
|
||||||
'!left-[var(--tab-menu-min-width)]': unref(collapse),
|
'!left-[var(--tab-menu-min-width)]': unref(collapse),
|
||||||
'!left-[var(--tab-menu-max-width)]': !unref(collapse),
|
'!left-[var(--tab-menu-max-width)]': !unref(collapse),
|
||||||
@ -217,16 +217,6 @@ $prefix-cls: #{$namespace}-tab-menu;
|
|||||||
.#{$prefix-cls} {
|
.#{$prefix-cls} {
|
||||||
transition: all var(--transition-time-02);
|
transition: all var(--transition-time-02);
|
||||||
|
|
||||||
&::after {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
right: 0;
|
|
||||||
width: 1px;
|
|
||||||
height: 100%;
|
|
||||||
border-left: 1px solid var(--left-menu-border-color);
|
|
||||||
content: '';
|
|
||||||
}
|
|
||||||
|
|
||||||
&__item {
|
&__item {
|
||||||
color: var(--left-menu-text-color);
|
color: var(--left-menu-text-color);
|
||||||
transition: all var(--transition-time-02);
|
transition: all var(--transition-time-02);
|
||||||
@ -240,7 +230,6 @@ $prefix-cls: #{$namespace}-tab-menu;
|
|||||||
&--collapse {
|
&--collapse {
|
||||||
color: var(--left-menu-text-color);
|
color: var(--left-menu-text-color);
|
||||||
background-color: var(--left-menu-bg-light-color);
|
background-color: var(--left-menu-bg-light-color);
|
||||||
border-top: 1px solid var(--left-menu-border-color);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.is-active {
|
.is-active {
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
import { onMounted, watch, computed, unref, ref, nextTick } from 'vue'
|
||||||
|
import { useRouter } from 'vue-router'
|
||||||
import type { RouteLocationNormalizedLoaded, RouterLinkProps } from 'vue-router'
|
import type { RouteLocationNormalizedLoaded, RouterLinkProps } from 'vue-router'
|
||||||
import { usePermissionStore } from '@/store/modules/permission'
|
import { usePermissionStore } from '@/store/modules/permission'
|
||||||
import { useTagsViewStore } from '@/store/modules/tagsView'
|
import { useTagsViewStore } from '@/store/modules/tagsView'
|
||||||
import { useAppStore } from '@/store/modules/app'
|
import { useAppStore } from '@/store/modules/app'
|
||||||
|
import { useI18n } from '@/hooks/web/useI18n'
|
||||||
import { filterAffixTags } from './helper'
|
import { filterAffixTags } from './helper'
|
||||||
import { ContextMenu, ContextMenuExpose } from '@/layout/components/ContextMenu'
|
import { ContextMenu, ContextMenuExpose } from '@/layout/components/ContextMenu'
|
||||||
import { useDesign } from '@/hooks/web/useDesign'
|
import { useDesign } from '@/hooks/web/useDesign'
|
||||||
|
import { useTemplateRefsList } from '@vueuse/core'
|
||||||
import { ElScrollbar } from 'element-plus'
|
import { ElScrollbar } from 'element-plus'
|
||||||
import { useScrollTo } from '@/hooks/event/useScrollTo'
|
import { useScrollTo } from '@/hooks/event/useScrollTo'
|
||||||
import { useTemplateRefsList } from '@vueuse/core'
|
|
||||||
|
|
||||||
defineOptions({ name: 'TagsView' })
|
|
||||||
|
|
||||||
const { getPrefixCls } = useDesign()
|
const { getPrefixCls } = useDesign()
|
||||||
|
|
||||||
@ -35,6 +35,8 @@ const appStore = useAppStore()
|
|||||||
|
|
||||||
const tagsViewIcon = computed(() => appStore.getTagsViewIcon)
|
const tagsViewIcon = computed(() => appStore.getTagsViewIcon)
|
||||||
|
|
||||||
|
const isDark = computed(() => appStore.getIsDark)
|
||||||
|
|
||||||
// 初始化tag
|
// 初始化tag
|
||||||
const initTags = () => {
|
const initTags = () => {
|
||||||
affixTagArr.value = filterAffixTags(unref(routers))
|
affixTagArr.value = filterAffixTags(unref(routers))
|
||||||
@ -73,7 +75,7 @@ const closeAllTags = () => {
|
|||||||
toLastView()
|
toLastView()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 关闭其他
|
// 关闭其它
|
||||||
const closeOthersTags = () => {
|
const closeOthersTags = () => {
|
||||||
tagsViewStore.delOthersViews(unref(selectedTag) as RouteLocationNormalizedLoaded)
|
tagsViewStore.delOthersViews(unref(selectedTag) as RouteLocationNormalizedLoaded)
|
||||||
}
|
}
|
||||||
@ -128,6 +130,7 @@ const moveToCurrentTag = async () => {
|
|||||||
if (v.fullPath !== unref(currentRoute).fullPath) {
|
if (v.fullPath !== unref(currentRoute).fullPath) {
|
||||||
tagsViewStore.updateVisitedView(unref(currentRoute))
|
tagsViewStore.updateVisitedView(unref(currentRoute))
|
||||||
}
|
}
|
||||||
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -263,29 +266,21 @@ watch(
|
|||||||
class="flex w-full relative bg-[#fff] dark:bg-[var(--el-bg-color)]"
|
class="flex w-full relative bg-[#fff] dark:bg-[var(--el-bg-color)]"
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
:class="`${prefixCls}__tool`"
|
:class="`${prefixCls}__tool ${prefixCls}__tool--first`"
|
||||||
class="w-[var(--tags-view-height)] h-[var(--tags-view-height)] cursor-pointer"
|
class="w-[var(--tags-view-height)] h-[var(--tags-view-height)] flex items-center justify-center cursor-pointer"
|
||||||
@click="move(-200)"
|
@click="move(-200)"
|
||||||
>
|
>
|
||||||
<Icon
|
<Icon
|
||||||
:color="appStore.getIsDark ? 'var(--el-text-color-regular)' : '#333'"
|
|
||||||
icon="ep:d-arrow-left"
|
icon="ep:d-arrow-left"
|
||||||
|
color="var(--el-text-color-placeholder)"
|
||||||
|
:hover-color="isDark ? '#fff' : 'var(--el-color-black)'"
|
||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
<div class="overflow-hidden flex-1">
|
<div class="overflow-hidden flex-1">
|
||||||
<ElScrollbar ref="scrollbarRef" class="h-full" @scroll="scroll">
|
<ElScrollbar ref="scrollbarRef" class="h-full" @scroll="scroll">
|
||||||
<div class="flex h-full">
|
<div class="flex h-full">
|
||||||
<ContextMenu
|
<ContextMenu
|
||||||
v-for="item in visitedViews"
|
|
||||||
:key="item.fullPath"
|
|
||||||
:ref="itemRefs.set"
|
:ref="itemRefs.set"
|
||||||
:class="[
|
|
||||||
`${prefixCls}__item`,
|
|
||||||
item?.meta?.affix ? `${prefixCls}__item--affix` : '',
|
|
||||||
{
|
|
||||||
'is-active': isActive(item)
|
|
||||||
}
|
|
||||||
]"
|
|
||||||
:schema="[
|
:schema="[
|
||||||
{
|
{
|
||||||
icon: 'ep:refresh',
|
icon: 'ep:refresh',
|
||||||
@ -343,14 +338,23 @@ watch(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
]"
|
]"
|
||||||
|
v-for="item in visitedViews"
|
||||||
|
:key="item.fullPath"
|
||||||
:tag-item="item"
|
:tag-item="item"
|
||||||
|
:class="[
|
||||||
|
`${prefixCls}__item`,
|
||||||
|
item?.meta?.affix ? `${prefixCls}__item--affix` : '',
|
||||||
|
{
|
||||||
|
'is-active': isActive(item)
|
||||||
|
}
|
||||||
|
]"
|
||||||
@visible-change="visibleChange"
|
@visible-change="visibleChange"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<router-link :ref="tagLinksRefs.set" v-slot="{ navigate }" :to="{ ...item }" custom>
|
<router-link :ref="tagLinksRefs.set" :to="{ ...item }" custom v-slot="{ navigate }">
|
||||||
<div
|
<div
|
||||||
class="h-full flex justify-center items-center whitespace-nowrap pl-15px"
|
|
||||||
@click="navigate"
|
@click="navigate"
|
||||||
|
class="h-full flex justify-center items-center whitespace-nowrap pl-15px"
|
||||||
>
|
>
|
||||||
<Icon
|
<Icon
|
||||||
v-if="
|
v-if="
|
||||||
@ -366,9 +370,9 @@ watch(
|
|||||||
{{ t(item?.meta?.title as string) }}
|
{{ t(item?.meta?.title as string) }}
|
||||||
<Icon
|
<Icon
|
||||||
:class="`${prefixCls}__item--close`"
|
:class="`${prefixCls}__item--close`"
|
||||||
:size="12"
|
|
||||||
color="#333"
|
color="#333"
|
||||||
icon="ep:close"
|
icon="ep:close"
|
||||||
|
:size="12"
|
||||||
@click.prevent.stop="closeSelectedTag(item)"
|
@click.prevent.stop="closeSelectedTag(item)"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@ -380,25 +384,28 @@ watch(
|
|||||||
</div>
|
</div>
|
||||||
<span
|
<span
|
||||||
:class="`${prefixCls}__tool`"
|
:class="`${prefixCls}__tool`"
|
||||||
class="w-[var(--tags-view-height)] h-[var(--tags-view-height)] text-center leading-[var(--tags-view-height)] cursor-pointer"
|
class="w-[var(--tags-view-height)] h-[var(--tags-view-height)] flex items-center justify-center cursor-pointer"
|
||||||
@click="move(200)"
|
@click="move(200)"
|
||||||
>
|
>
|
||||||
<Icon
|
<Icon
|
||||||
:color="appStore.getIsDark ? 'var(--el-text-color-regular)' : '#333'"
|
|
||||||
icon="ep:d-arrow-right"
|
icon="ep:d-arrow-right"
|
||||||
|
color="var(--el-text-color-placeholder)"
|
||||||
|
:hover-color="isDark ? '#fff' : 'var(--el-color-black)'"
|
||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span
|
||||||
:class="`${prefixCls}__tool`"
|
:class="`${prefixCls}__tool`"
|
||||||
class="w-[var(--tags-view-height)] h-[var(--tags-view-height)] text-center leading-[var(--tags-view-height)] cursor-pointer"
|
class="w-[var(--tags-view-height)] h-[var(--tags-view-height)] flex items-center justify-center cursor-pointer"
|
||||||
@click="refreshSelectedTag(selectedTag)"
|
@click="refreshSelectedTag(selectedTag)"
|
||||||
>
|
>
|
||||||
<Icon
|
<Icon
|
||||||
:color="appStore.getIsDark ? 'var(--el-text-color-regular)' : '#333'"
|
|
||||||
icon="ep:refresh-right"
|
icon="ep:refresh-right"
|
||||||
|
color="var(--el-text-color-placeholder)"
|
||||||
|
:hover-color="isDark ? '#fff' : 'var(--el-color-black)'"
|
||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
<ContextMenu
|
<ContextMenu
|
||||||
|
trigger="click"
|
||||||
:schema="[
|
:schema="[
|
||||||
{
|
{
|
||||||
icon: 'ep:refresh',
|
icon: 'ep:refresh',
|
||||||
@ -410,7 +417,7 @@ watch(
|
|||||||
{
|
{
|
||||||
icon: 'ep:close',
|
icon: 'ep:close',
|
||||||
label: t('common.closeTab'),
|
label: t('common.closeTab'),
|
||||||
disabled: !!visitedViews?.length && selectedTag?.meta.affix,
|
disabled: !!visitedViews?.length && selectedTag?.meta.affix,
|
||||||
command: () => {
|
command: () => {
|
||||||
closeSelectedTag(selectedTag!)
|
closeSelectedTag(selectedTag!)
|
||||||
}
|
}
|
||||||
@ -450,15 +457,15 @@ watch(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
]"
|
]"
|
||||||
trigger="click"
|
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
:class="`${prefixCls}__tool`"
|
:class="`${prefixCls}__tool`"
|
||||||
class="w-[var(--tags-view-height)] h-[var(--tags-view-height)] text-center leading-[var(--tags-view-height)] cursor-pointer block"
|
class="w-[var(--tags-view-height)] h-[var(--tags-view-height)] flex items-center justify-center cursor-pointer block"
|
||||||
>
|
>
|
||||||
<Icon
|
<Icon
|
||||||
:color="appStore.getIsDark ? 'var(--el-text-color-regular)' : '#333'"
|
|
||||||
icon="ep:menu"
|
icon="ep:menu"
|
||||||
|
color="var(--el-text-color-placeholder)"
|
||||||
|
:hover-color="isDark ? '#fff' : 'var(--el-color-black)'"
|
||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
</ContextMenu>
|
</ContextMenu>
|
||||||
@ -475,47 +482,49 @@ $prefix-cls: #{$namespace}-tags-view;
|
|||||||
|
|
||||||
&__tool {
|
&__tool {
|
||||||
position: relative;
|
position: relative;
|
||||||
display: inline-flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
|
|
||||||
&:hover {
|
&::before {
|
||||||
:deep(span) {
|
|
||||||
color: var(--el-color-black) !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&::after {
|
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 1px;
|
top: 1px;
|
||||||
left: 0;
|
left: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: calc(100% - 1px);
|
height: calc(100% - 1px);
|
||||||
border-right: 1px solid var(--tags-view-border-color);
|
border-left: 1px solid var(--el-border-color);
|
||||||
border-left: 1px solid var(--tags-view-border-color);
|
|
||||||
content: '';
|
content: '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&--first {
|
||||||
|
&::before {
|
||||||
|
position: absolute;
|
||||||
|
top: 1px;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: calc(100% - 1px);
|
||||||
|
border-right: 1px solid var(--el-border-color);
|
||||||
|
border-left: none;
|
||||||
|
content: '';
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&__item {
|
&__item {
|
||||||
position: relative;
|
position: relative;
|
||||||
top: 2px;
|
top: 2px;
|
||||||
height: calc(100% - 4px);
|
height: calc(100% - 6px);
|
||||||
padding-right: 16px;
|
padding-right: 25px;
|
||||||
margin-left: 4px;
|
margin-left: 4px;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
border-radius: 3px;
|
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
border: 1px solid #d9d9d9;
|
border: 1px solid #d9d9d9;
|
||||||
|
border-radius: 2px;
|
||||||
|
|
||||||
&--close {
|
&--close {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 50%;
|
top: 50%;
|
||||||
right: 3px;
|
right: 5px;
|
||||||
display: none;
|
display: none;
|
||||||
transform: translate(0, -50%);
|
transform: translate(0, -50%);
|
||||||
}
|
}
|
||||||
|
|
||||||
&:not(.#{$prefix-cls}__item--affix):hover {
|
&:not(.#{$prefix-cls}__item--affix):hover {
|
||||||
.#{$prefix-cls}__item--close {
|
.#{$prefix-cls}__item--close {
|
||||||
display: block;
|
display: block;
|
||||||
@ -533,7 +542,6 @@ $prefix-cls: #{$namespace}-tags-view;
|
|||||||
color: var(--el-color-white);
|
color: var(--el-color-white);
|
||||||
background-color: var(--el-color-primary);
|
background-color: var(--el-color-primary);
|
||||||
border: 1px solid var(--el-color-primary);
|
border: 1px solid var(--el-color-primary);
|
||||||
|
|
||||||
.#{$prefix-cls}__item--close {
|
.#{$prefix-cls}__item--close {
|
||||||
:deep(span) {
|
:deep(span) {
|
||||||
color: var(--el-color-white) !important;
|
color: var(--el-color-white) !important;
|
||||||
@ -545,26 +553,14 @@ $prefix-cls: #{$namespace}-tags-view;
|
|||||||
.dark {
|
.dark {
|
||||||
.#{$prefix-cls} {
|
.#{$prefix-cls} {
|
||||||
&__tool {
|
&__tool {
|
||||||
&:hover {
|
&--first {
|
||||||
:deep(span) {
|
&::after {
|
||||||
color: #fff !important;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&::after {
|
|
||||||
border-right: 1px solid var(--el-border-color);
|
|
||||||
border-left: 1px solid var(--el-border-color);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&__item {
|
&__item {
|
||||||
position: relative;
|
|
||||||
top: 2px;
|
|
||||||
height: calc(100% - 4px);
|
|
||||||
padding-right: 16px;
|
|
||||||
font-size: 12px;
|
|
||||||
border-radius: 3px;
|
|
||||||
cursor: pointer;
|
|
||||||
border: 1px solid var(--el-border-color);
|
border: 1px solid var(--el-border-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -577,7 +573,7 @@ $prefix-cls: #{$namespace}-tags-view;
|
|||||||
&__item.is-active {
|
&__item.is-active {
|
||||||
color: var(--el-color-white);
|
color: var(--el-color-white);
|
||||||
background-color: var(--el-color-primary);
|
background-color: var(--el-color-primary);
|
||||||
|
border: 1px solid var(--el-color-primary);
|
||||||
.#{$prefix-cls}__item--close {
|
.#{$prefix-cls}__item--close {
|
||||||
:deep(span) {
|
:deep(span) {
|
||||||
color: var(--el-color-white) !important;
|
color: var(--el-color-white) !important;
|
||||||
|
@ -52,28 +52,28 @@ export default defineComponent({
|
|||||||
{layout.value !== 'top' ? (
|
{layout.value !== 'top' ? (
|
||||||
<div class="h-full flex items-center">
|
<div class="h-full flex items-center">
|
||||||
{hamburger.value && layout.value !== 'cutMenu' ? (
|
{hamburger.value && layout.value !== 'cutMenu' ? (
|
||||||
<Collapse class="hover-trigger" color="var(--top-header-text-color)"></Collapse>
|
<Collapse class="custom-hover" color="var(--top-header-text-color)"></Collapse>
|
||||||
) : undefined}
|
) : undefined}
|
||||||
{breadcrumb.value ? <Breadcrumb class="<md:hidden"></Breadcrumb> : undefined}
|
{breadcrumb.value ? <Breadcrumb class="lt-md:hidden"></Breadcrumb> : undefined}
|
||||||
</div>
|
</div>
|
||||||
) : undefined}
|
) : undefined}
|
||||||
<div class="h-full flex items-center">
|
<div class="h-full flex items-center">
|
||||||
{screenfull.value ? (
|
{screenfull.value ? (
|
||||||
<Screenfull class="hover-trigger" color="var(--top-header-text-color)"></Screenfull>
|
<Screenfull class="custom-hover" color="var(--top-header-text-color)"></Screenfull>
|
||||||
) : undefined}
|
) : undefined}
|
||||||
{size.value ? (
|
{size.value ? (
|
||||||
<SizeDropdown class="hover-trigger" color="var(--top-header-text-color)"></SizeDropdown>
|
<SizeDropdown class="custom-hover" color="var(--top-header-text-color)"></SizeDropdown>
|
||||||
) : undefined}
|
) : undefined}
|
||||||
{locale.value ? (
|
{locale.value ? (
|
||||||
<LocaleDropdown
|
<LocaleDropdown
|
||||||
class="hover-trigger"
|
class="custom-hover"
|
||||||
color="var(--top-header-text-color)"
|
color="var(--top-header-text-color)"
|
||||||
></LocaleDropdown>
|
></LocaleDropdown>
|
||||||
) : undefined}
|
) : undefined}
|
||||||
{message.value ? (
|
{message.value ? (
|
||||||
<Message class="hover-trigger" color="var(--top-header-text-color)"></Message>
|
<Message class="custom-hover" color="var(--top-header-text-color)"></Message>
|
||||||
) : undefined}
|
) : undefined}
|
||||||
<UserInfo class="hover-trigger"></UserInfo>
|
<UserInfo></UserInfo>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
@ -51,7 +51,7 @@ const toDocument = () => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<ElDropdown :class="prefixCls" trigger="click">
|
<ElDropdown class="custom-hover" :class="prefixCls" trigger="click">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<img :src="avatar" alt="" class="w-[calc(var(--logo-height)-25px)] rounded-[50%]" />
|
<img :src="avatar" alt="" class="w-[calc(var(--logo-height)-25px)] rounded-[50%]" />
|
||||||
<span class="<lg:hidden text-14px pl-[5px] text-[var(--top-header-text-color)]">
|
<span class="<lg:hidden text-14px pl-[5px] text-[var(--top-header-text-color)]">
|
||||||
|
@ -39,11 +39,16 @@ export const useRenderLayout = () => {
|
|||||||
const renderClassic = () => {
|
const renderClassic = () => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div class={['absolute top-0 left-0 h-full', { '!fixed z-3000': mobile.value }]}>
|
<div
|
||||||
|
class={[
|
||||||
|
'absolute top-0 left-0 h-full layout-border__right',
|
||||||
|
{ '!fixed z-3000': mobile.value }
|
||||||
|
]}
|
||||||
|
>
|
||||||
{logo.value ? (
|
{logo.value ? (
|
||||||
<Logo
|
<Logo
|
||||||
class={[
|
class={[
|
||||||
'bg-[var(--left-menu-bg-color)] border-bottom-1 border-solid border-[var(--logo-border-color)] dark:border-[var(--el-border-color)]',
|
'bg-[var(--left-menu-bg-color)] relative',
|
||||||
{
|
{
|
||||||
'!pl-0': mobile.value && collapse.value,
|
'!pl-0': mobile.value && collapse.value,
|
||||||
'w-[var(--left-menu-min-width)]': appStore.getCollapse,
|
'w-[var(--left-menu-min-width)]': appStore.getCollapse,
|
||||||
@ -83,19 +88,26 @@ export const useRenderLayout = () => {
|
|||||||
class={[
|
class={[
|
||||||
{
|
{
|
||||||
'fixed top-0 left-0 z-10': fixedHeader.value,
|
'fixed top-0 left-0 z-10': fixedHeader.value,
|
||||||
'w-[calc(100%-var(--left-menu-min-width))] left-[var(--left-menu-min-width)]':
|
'w-[calc(100%-var(--left-menu-min-width))] !left-[var(--left-menu-min-width)]':
|
||||||
collapse.value && fixedHeader.value && !mobile.value,
|
collapse.value && fixedHeader.value && !mobile.value,
|
||||||
'w-[calc(100%-var(--left-menu-max-width))] left-[var(--left-menu-max-width)]':
|
'w-[calc(100%-var(--left-menu-max-width))] !left-[var(--left-menu-max-width)]':
|
||||||
!collapse.value && fixedHeader.value && !mobile.value,
|
!collapse.value && fixedHeader.value && !mobile.value,
|
||||||
'!w-full !left-0': mobile.value
|
'!w-full !left-0': mobile.value
|
||||||
}
|
}
|
||||||
]}
|
]}
|
||||||
style="transition: all var(--transition-time-02);"
|
style="transition: all var(--transition-time-02);"
|
||||||
>
|
>
|
||||||
<ToolHeader class="border-bottom-1 border-solid border-[var(--top-tool-border-color)] bg-[var(--top-header-bg-color)] dark:border-[var(--el-border-color)]"></ToolHeader>
|
<ToolHeader
|
||||||
|
class={[
|
||||||
|
'bg-[var(--top-header-bg-color)]',
|
||||||
|
{
|
||||||
|
'layout-border__bottom': !tagsView.value
|
||||||
|
}
|
||||||
|
]}
|
||||||
|
></ToolHeader>
|
||||||
|
|
||||||
{tagsView.value ? (
|
{tagsView.value ? (
|
||||||
<TagsView class="border-bottom-1 border-top-1 border-solid border-[var(--tags-view-border-color)] dark:border-[var(--el-border-color)]"></TagsView>
|
<TagsView class="layout-border__bottom layout-border__top"></TagsView>
|
||||||
) : undefined}
|
) : undefined}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -109,13 +121,13 @@ export const useRenderLayout = () => {
|
|||||||
const renderTopLeft = () => {
|
const renderTopLeft = () => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div class="flex items-center bg-[var(--top-header-bg-color)] border-bottom-1 border-solid border-[var(--top-tool-border-color)] dark:border-[var(--el-border-color)]">
|
<div class="flex items-center bg-[var(--top-header-bg-color)] relative layout-border__bottom dark:bg-[var(--el-bg-color)]">
|
||||||
{logo.value ? <Logo class="hover-trigger !pr-15px"></Logo> : undefined}
|
{logo.value ? <Logo class="custom-hover"></Logo> : undefined}
|
||||||
|
|
||||||
<ToolHeader class="flex-1"></ToolHeader>
|
<ToolHeader class="flex-1"></ToolHeader>
|
||||||
</div>
|
</div>
|
||||||
<div class="absolute top-[var(--logo-height)+1px] left-0 w-full h-[calc(100%-1px-var(--logo-height))] flex">
|
<div class="absolute top-[var(--logo-height)+1px] left-0 w-full h-[calc(100%-1px-var(--logo-height))] flex">
|
||||||
<Menu class="!h-full"></Menu>
|
<Menu class="!h-full relative layout-border__right"></Menu>
|
||||||
<div
|
<div
|
||||||
class={[
|
class={[
|
||||||
`${prefixCls}-content`,
|
`${prefixCls}-content`,
|
||||||
@ -142,12 +154,12 @@ export const useRenderLayout = () => {
|
|||||||
{tagsView.value ? (
|
{tagsView.value ? (
|
||||||
<TagsView
|
<TagsView
|
||||||
class={[
|
class={[
|
||||||
'border-bottom-1 border-top-1 border-solid border-[var(--tags-view-border-color)] dark:border-[var(--el-border-color)]',
|
'layout-border__bottom absolute',
|
||||||
{
|
{
|
||||||
'!fixed top-0 left-0 z-10': fixedHeader.value,
|
'!fixed top-0 left-0 z-10': fixedHeader.value,
|
||||||
'w-[calc(100%-var(--left-menu-min-width))] left-[var(--left-menu-min-width)] mt-[var(--logo-height)]':
|
'w-[calc(100%-var(--left-menu-min-width))] !left-[var(--left-menu-min-width)] mt-[calc(var(--logo-height)+1px)]':
|
||||||
collapse.value && fixedHeader.value,
|
collapse.value && fixedHeader.value,
|
||||||
'w-[calc(100%-var(--left-menu-max-width))] left-[var(--left-menu-max-width)] mt-[var(--logo-height)]':
|
'w-[calc(100%-var(--left-menu-max-width))] !left-[var(--left-menu-max-width)] mt-[calc(var(--logo-height)+1px)]':
|
||||||
!collapse.value && fixedHeader.value
|
!collapse.value && fixedHeader.value
|
||||||
}
|
}
|
||||||
]}
|
]}
|
||||||
@ -166,12 +178,28 @@ export const useRenderLayout = () => {
|
|||||||
const renderTop = () => {
|
const renderTop = () => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div class="flex items-center justify-between bg-[var(--top-header-bg-color)] border-bottom-1 border-solid border-[var(--top-tool-border-color)] dark:border-[var(--el-border-color)]">
|
<div
|
||||||
{logo.value ? <Logo class="hover-trigger"></Logo> : undefined}
|
class={[
|
||||||
|
'flex items-center justify-between bg-[var(--top-header-bg-color)] relative',
|
||||||
|
{
|
||||||
|
'layout-border__bottom': !tagsView.value
|
||||||
|
}
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
{logo.value ? <Logo class="custom-hover"></Logo> : undefined}
|
||||||
<Menu class="flex-1 px-10px h-[var(--top-tool-height)]"></Menu>
|
<Menu class="flex-1 px-10px h-[var(--top-tool-height)]"></Menu>
|
||||||
<ToolHeader></ToolHeader>
|
<ToolHeader></ToolHeader>
|
||||||
</div>
|
</div>
|
||||||
<div class={[`${prefixCls}-content`, 'h-full w-full']}>
|
<div
|
||||||
|
class={[
|
||||||
|
`${prefixCls}-content`,
|
||||||
|
'w-full',
|
||||||
|
{
|
||||||
|
'h-[calc(100%-var(--app-footer-height))]': !fixedHeader.value,
|
||||||
|
'h-[calc(100%-var(--tags-view-height)-var(--app-footer-height))]': fixedHeader.value
|
||||||
|
}
|
||||||
|
]}
|
||||||
|
>
|
||||||
<ElScrollbar
|
<ElScrollbar
|
||||||
v-loading={pageLoading.value}
|
v-loading={pageLoading.value}
|
||||||
class={[
|
class={[
|
||||||
@ -186,9 +214,9 @@ export const useRenderLayout = () => {
|
|||||||
{tagsView.value ? (
|
{tagsView.value ? (
|
||||||
<TagsView
|
<TagsView
|
||||||
class={[
|
class={[
|
||||||
'border-bottom-1 border-top-1 border-solid border-[var(--tags-view-border-color)] dark:border-[var(--el-border-color)]',
|
'layout-border__bottom layout-border__top relative',
|
||||||
{
|
{
|
||||||
'!fixed w-full top-[var(--top-tool-height)] left-0': fixedHeader.value
|
'!fixed w-full top-[calc(var(--top-tool-height)+1px)] left-0': fixedHeader.value
|
||||||
}
|
}
|
||||||
]}
|
]}
|
||||||
style="transition: width var(--transition-time-02), left var(--transition-time-02);"
|
style="transition: width var(--transition-time-02), left var(--transition-time-02);"
|
||||||
@ -205,12 +233,12 @@ export const useRenderLayout = () => {
|
|||||||
const renderCutMenu = () => {
|
const renderCutMenu = () => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div class="flex items-center bg-[var(--top-header-bg-color)] border-bottom-1 border-solid border-[var(--top-tool-border-color)] dark:border-[var(--el-border-color)]">
|
<div class="flex items-center bg-[var(--top-header-bg-color)] relative layout-border__bottom">
|
||||||
{logo.value ? <Logo class="hover-trigger !pr-15px"></Logo> : undefined}
|
{logo.value ? <Logo class="custom-hover !pr-15px"></Logo> : undefined}
|
||||||
|
|
||||||
<ToolHeader class="flex-1"></ToolHeader>
|
<ToolHeader class="flex-1"></ToolHeader>
|
||||||
</div>
|
</div>
|
||||||
<div class="absolute top-[var(--logo-height)] left-0 w-full h-[calc(100%-var(--logo-height))] flex">
|
<div class="absolute top-[var(--logo-height)] left-0 w-[calc(100%-2px)] h-[calc(100%-var(--logo-height))] flex">
|
||||||
<TabMenu></TabMenu>
|
<TabMenu></TabMenu>
|
||||||
<div
|
<div
|
||||||
class={[
|
class={[
|
||||||
@ -242,18 +270,18 @@ export const useRenderLayout = () => {
|
|||||||
{tagsView.value ? (
|
{tagsView.value ? (
|
||||||
<TagsView
|
<TagsView
|
||||||
class={[
|
class={[
|
||||||
'border-bottom-1 border-top-1 border-solid border-[var(--tags-view-border-color)] dark:border-[var(--el-border-color)]',
|
'relative layout-border__bottom layout-border__top',
|
||||||
{
|
{
|
||||||
'!fixed top-0 left-0 z-10': fixedHeader.value,
|
'!fixed top-0 left-0 z-10': fixedHeader.value,
|
||||||
'w-[calc(100%-var(--tab-menu-min-width))] left-[var(--tab-menu-min-width)] mt-[var(--logo-height)]':
|
'w-[calc(100%-var(--tab-menu-min-width))] !left-[var(--tab-menu-min-width)] mt-[var(--logo-height)]':
|
||||||
collapse.value && fixedHeader.value,
|
collapse.value && fixedHeader.value,
|
||||||
'w-[calc(100%-var(--tab-menu-max-width))] left-[var(--tab-menu-max-width)] mt-[var(--logo-height)]':
|
'w-[calc(100%-var(--tab-menu-max-width))] !left-[var(--tab-menu-max-width)] mt-[var(--logo-height)]':
|
||||||
!collapse.value && fixedHeader.value,
|
!collapse.value && fixedHeader.value,
|
||||||
'!fixed top-0 left-[var(--tab-menu-min-width)+var(--left-menu-max-width)] z-10':
|
'!fixed top-0 !left-[var(--tab-menu-min-width)+var(--left-menu-max-width)] z-10':
|
||||||
fixedHeader.value && fixedMenu.value,
|
fixedHeader.value && fixedMenu.value,
|
||||||
'w-[calc(100%-var(--tab-menu-min-width)-var(--left-menu-max-width))] left-[var(--tab-menu-min-width)+var(--left-menu-max-width)] mt-[var(--logo-height)]':
|
'w-[calc(100%-var(--tab-menu-min-width)-var(--left-menu-max-width))] !left-[var(--tab-menu-min-width)+var(--left-menu-max-width)] mt-[var(--logo-height)]':
|
||||||
collapse.value && fixedHeader.value && fixedMenu.value,
|
collapse.value && fixedHeader.value && fixedMenu.value,
|
||||||
'w-[calc(100%-var(--tab-menu-max-width)-var(--left-menu-max-width))] left-[var(--tab-menu-max-width)+var(--left-menu-max-width)] mt-[var(--logo-height)]':
|
'w-[calc(100%-var(--tab-menu-max-width)-var(--left-menu-max-width))] !left-[var(--tab-menu-max-width)+var(--left-menu-max-width)] mt-[var(--logo-height)]':
|
||||||
!collapse.value && fixedHeader.value && fixedMenu.value
|
!collapse.value && fixedHeader.value && fixedMenu.value
|
||||||
}
|
}
|
||||||
]}
|
]}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// 引入windi css
|
// 引入unocss css
|
||||||
import '@/plugins/windi.css'
|
import '@/plugins/unocss'
|
||||||
|
|
||||||
// 导入全局的svg图标
|
// 导入全局的svg图标
|
||||||
import '@/plugins/svgIcon'
|
import '@/plugins/svgIcon'
|
||||||
|
1
src/plugins/unocss/index.ts
Normal file
1
src/plugins/unocss/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
import 'virtual:uno.css'
|
@ -1,3 +0,0 @@
|
|||||||
import 'virtual:windi.css'
|
|
||||||
|
|
||||||
import 'virtual:windi-devtools'
|
|
@ -3,7 +3,6 @@ import { store } from '../index'
|
|||||||
import { cloneDeep } from 'lodash-es'
|
import { cloneDeep } from 'lodash-es'
|
||||||
import remainingRouter from '@/router/modules/remaining'
|
import remainingRouter from '@/router/modules/remaining'
|
||||||
import { generateRoute, flatMultiLevelRoutes } from '@/utils/routerHelper'
|
import { generateRoute, flatMultiLevelRoutes } from '@/utils/routerHelper'
|
||||||
import { getAsyncRoutes } from '@/api/login'
|
|
||||||
import { CACHE_KEY, useCache } from '@/hooks/web/useCache'
|
import { CACHE_KEY, useCache } from '@/hooks/web/useCache'
|
||||||
|
|
||||||
const { wsCache } = useCache()
|
const { wsCache } = useCache()
|
||||||
@ -34,12 +33,10 @@ export const usePermissionStore = defineStore('permission', {
|
|||||||
actions: {
|
actions: {
|
||||||
async generateRoutes(): Promise<unknown> {
|
async generateRoutes(): Promise<unknown> {
|
||||||
return new Promise<void>(async (resolve) => {
|
return new Promise<void>(async (resolve) => {
|
||||||
|
// 获得菜单列表,它在登录的时候,setUserInfoAction 方法中已经进行获取
|
||||||
let res: AppCustomRouteRecordRaw[]
|
let res: AppCustomRouteRecordRaw[]
|
||||||
if (wsCache.get(CACHE_KEY.ROLE_ROUTERS)) {
|
if (wsCache.get(CACHE_KEY.ROLE_ROUTERS)) {
|
||||||
res = wsCache.get(CACHE_KEY.ROLE_ROUTERS) as AppCustomRouteRecordRaw[]
|
res = wsCache.get(CACHE_KEY.ROLE_ROUTERS) as AppCustomRouteRecordRaw[]
|
||||||
} else {
|
|
||||||
res = await getAsyncRoutes()
|
|
||||||
wsCache.set(CACHE_KEY.ROLE_ROUTERS, res)
|
|
||||||
}
|
}
|
||||||
const routerMap: AppRouteRecordRaw[] = generateRoute(res as AppCustomRouteRecordRaw[])
|
const routerMap: AppRouteRecordRaw[] = generateRoute(res as AppCustomRouteRecordRaw[])
|
||||||
// 动态路由,404一定要放到最后面
|
// 动态路由,404一定要放到最后面
|
||||||
|
@ -58,6 +58,7 @@ export const useUserStore = defineStore('admin-user', {
|
|||||||
this.user = userInfo.user
|
this.user = userInfo.user
|
||||||
this.isSetUser = true
|
this.isSetUser = true
|
||||||
wsCache.set(CACHE_KEY.USER, userInfo)
|
wsCache.set(CACHE_KEY.USER, userInfo)
|
||||||
|
wsCache.set(CACHE_KEY.ROLE_ROUTERS, userInfo.menus)
|
||||||
},
|
},
|
||||||
async loginOut() {
|
async loginOut() {
|
||||||
await loginOut()
|
await loginOut()
|
||||||
|
@ -23,7 +23,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
& .peg {
|
& .peg {
|
||||||
box-shadow: 0 0 10px var(--el-color-primary), 0 0 5px var(--el-color-primary) !important;
|
box-shadow:
|
||||||
|
0 0 10px var(--el-color-primary),
|
||||||
|
0 0 5px var(--el-color-primary) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
& .spinner-icon {
|
& .spinner-icon {
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
:root {
|
:root {
|
||||||
--dark-bg-color: #293146;
|
--login-bg-color: #293146;
|
||||||
|
|
||||||
/* left menu start */
|
|
||||||
--left-menu-border-color: '#eee';
|
|
||||||
|
|
||||||
--left-menu-max-width: 200px;
|
--left-menu-max-width: 200px;
|
||||||
|
|
||||||
@ -25,8 +22,6 @@
|
|||||||
--logo-height: 50px;
|
--logo-height: 50px;
|
||||||
|
|
||||||
--logo-title-text-color: #fff;
|
--logo-title-text-color: #fff;
|
||||||
|
|
||||||
--logo-border-color: 'inherit';
|
|
||||||
/* logo end */
|
/* logo end */
|
||||||
|
|
||||||
/* header start */
|
/* header start */
|
||||||
@ -40,11 +35,7 @@
|
|||||||
|
|
||||||
--top-tool-p-x: 0;
|
--top-tool-p-x: 0;
|
||||||
|
|
||||||
--top-tool-border-color: #eee;
|
|
||||||
|
|
||||||
--tags-view-height: 35px;
|
--tags-view-height: 35px;
|
||||||
|
|
||||||
--tags-view-border-color: #eee;
|
|
||||||
/* header start */
|
/* header start */
|
||||||
|
|
||||||
/* tab menu start */
|
/* tab menu start */
|
||||||
@ -53,8 +44,6 @@
|
|||||||
--tab-menu-min-width: 30px;
|
--tab-menu-min-width: 30px;
|
||||||
|
|
||||||
--tab-menu-collapse-height: 36px;
|
--tab-menu-collapse-height: 36px;
|
||||||
|
|
||||||
--tab-menu-border-color: #eee;
|
|
||||||
/* tab menu end */
|
/* tab menu end */
|
||||||
|
|
||||||
--app-content-padding: 20px;
|
--app-content-padding: 20px;
|
||||||
@ -66,6 +55,10 @@
|
|||||||
--transition-time-02: 0.2s;
|
--transition-time-02: 0.2s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.dark {
|
||||||
|
--app-content-bg-color: var(--el-bg-color);
|
||||||
|
}
|
||||||
|
|
||||||
html,
|
html,
|
||||||
body {
|
body {
|
||||||
-webkit-font-smoothing: antialiased;
|
-webkit-font-smoothing: antialiased;
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<img :src="avatar" alt="" class="w-70px h-70px rounded-[50%] mr-20px" />
|
<img :src="avatar" alt="" class="w-70px h-70px rounded-[50%] mr-20px" />
|
||||||
<div>
|
<div>
|
||||||
<div class="text-20px text-700">
|
<div class="text-20px">
|
||||||
{{ t('workplace.welcome') }} {{ username }} {{ t('workplace.happyDay') }}
|
{{ t('workplace.welcome') }} {{ username }} {{ t('workplace.happyDay') }}
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-10px text-14px text-gray-500">
|
<div class="mt-10px text-14px text-gray-500">
|
||||||
@ -17,7 +17,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :xl="12" :lg="12" :md="12" :sm="24" :xs="24">
|
<el-col :xl="12" :lg="12" :md="12" :sm="24" :xs="24">
|
||||||
<div class="flex h-70px items-center justify-end <sm:mt-10px">
|
<div class="flex h-70px items-center justify-end lt-sm:mt-10px">
|
||||||
<div class="px-8px text-right">
|
<div class="px-8px text-right">
|
||||||
<div class="text-14px text-gray-400 mb-20px">{{ t('workplace.project') }}</div>
|
<div class="text-14px text-gray-400 mb-20px">{{ t('workplace.project') }}</div>
|
||||||
<CountTo
|
<CountTo
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
:class="prefixCls"
|
:class="prefixCls"
|
||||||
class="h-[100%] relative <xl:bg-v-dark <sm:px-10px <xl:px-10px <md:px-10px"
|
class="h-[100%] relative lt-xl:bg-[var(--login-bg-color)] lt-sm:px-10px lt-xl:px-10px lt-md:px-10px"
|
||||||
>
|
>
|
||||||
<div class="relative h-full flex mx-auto">
|
<div class="relative h-full flex mx-auto">
|
||||||
<div
|
<div
|
||||||
:class="`${prefixCls}__left flex-1 bg-gray-500 bg-opacity-20 relative p-30px <xl:hidden`"
|
:class="`${prefixCls}__left flex-1 bg-gray-500 bg-opacity-20 relative p-30px lt-xl:hidden`"
|
||||||
>
|
>
|
||||||
<!-- 左上角的 logo + 系统标题 -->
|
<!-- 左上角的 logo + 系统标题 -->
|
||||||
<div class="flex items-center relative text-white">
|
<div class="flex items-center relative text-white">
|
||||||
@ -27,33 +27,35 @@
|
|||||||
</TransitionGroup>
|
</TransitionGroup>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex-1 p-30px <sm:p-10px dark:bg-v-dark relative">
|
<div class="flex-1 p-30px lt-sm:p-10px dark:bg-[var(--login-bg-color)] relative">
|
||||||
<!-- 右上角的主题、语言选择 -->
|
<!-- 右上角的主题、语言选择 -->
|
||||||
<div class="flex justify-between items-center text-white @2xl:justify-end @xl:justify-end">
|
<div
|
||||||
<div class="flex items-center @2xl:hidden @xl:hidden">
|
class="flex justify-between items-center text-white at-2xl:justify-end at-xl:justify-end"
|
||||||
|
>
|
||||||
|
<div class="flex items-center at-2xl:hidden at-xl:hidden">
|
||||||
<img alt="" class="w-48px h-48px mr-10px" src="@/assets/imgs/logo.png" />
|
<img alt="" class="w-48px h-48px mr-10px" src="@/assets/imgs/logo.png" />
|
||||||
<span class="text-20px font-bold">{{ underlineToHump(appStore.getTitle) }}</span>
|
<span class="text-20px font-bold">{{ underlineToHump(appStore.getTitle) }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex justify-end items-center space-x-10px">
|
<div class="flex justify-end items-center space-x-10px">
|
||||||
<ThemeSwitch />
|
<ThemeSwitch />
|
||||||
<LocaleDropdown class="<xl:text-white dark:text-white" />
|
<LocaleDropdown class="lt-xl:text-white dark:text-white" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- 右边的登录界面 -->
|
<!-- 右边的登录界面 -->
|
||||||
<Transition appear enter-active-class="animate__animated animate__bounceInRight">
|
<Transition appear enter-active-class="animate__animated animate__bounceInRight">
|
||||||
<div
|
<div
|
||||||
class="h-full flex items-center m-auto w-[100%] @2xl:max-w-500px @xl:max-w-500px @md:max-w-500px @lg:max-w-500px"
|
class="h-full flex items-center m-auto w-[100%] at-2xl:max-w-500px at-xl:max-w-500px at-md:max-w-500px at-lg:max-w-500px"
|
||||||
>
|
>
|
||||||
<!-- 账号登录 -->
|
<!-- 账号登录 -->
|
||||||
<LoginForm class="p-20px h-auto m-auto <xl:(rounded-3xl light:bg-white)" />
|
<LoginForm class="p-20px h-auto m-auto lt-xl:(rounded-3xl light:bg-white)" />
|
||||||
<!-- 手机登录 -->
|
<!-- 手机登录 -->
|
||||||
<MobileForm class="p-20px h-auto m-auto <xl:(rounded-3xl light:bg-white)" />
|
<MobileForm class="p-20px h-auto m-auto lt-xl:(rounded-3xl light:bg-white)" />
|
||||||
<!-- 二维码登录 -->
|
<!-- 二维码登录 -->
|
||||||
<QrCodeForm class="p-20px h-auto m-auto <xl:(rounded-3xl light:bg-white)" />
|
<QrCodeForm class="p-20px h-auto m-auto lt-xl:(rounded-3xl light:bg-white)" />
|
||||||
<!-- 注册 -->
|
<!-- 注册 -->
|
||||||
<RegisterForm class="p-20px h-auto m-auto <xl:(rounded-3xl light:bg-white)" />
|
<RegisterForm class="p-20px h-auto m-auto lt-xl:(rounded-3xl light:bg-white)" />
|
||||||
<!-- 三方登录 -->
|
<!-- 三方登录 -->
|
||||||
<SSOLoginVue class="p-20px h-auto m-auto <xl:(rounded-3xl light:bg-white)" />
|
<SSOLoginVue class="p-20px h-auto m-auto lt-xl:(rounded-3xl light:bg-white)" />
|
||||||
</div>
|
</div>
|
||||||
</Transition>
|
</Transition>
|
||||||
</div>
|
</div>
|
||||||
@ -82,6 +84,8 @@ const prefixCls = getPrefixCls('login')
|
|||||||
$prefix-cls: #{$namespace}-login;
|
$prefix-cls: #{$namespace}-login;
|
||||||
|
|
||||||
.#{$prefix-cls} {
|
.#{$prefix-cls} {
|
||||||
|
overflow: auto;
|
||||||
|
|
||||||
&__left {
|
&__left {
|
||||||
&::before {
|
&::before {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
label-width="120px"
|
label-width="120px"
|
||||||
size="large"
|
size="large"
|
||||||
>
|
>
|
||||||
<el-row style="maring-left: -10px; maring-right: -10px">
|
<el-row style="margin-left: -10px; margin-right: -10px">
|
||||||
<el-col :span="24" style="padding-left: 10px; padding-right: 10px">
|
<el-col :span="24" style="padding-left: 10px; padding-right: 10px">
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<LoginFormTitle style="width: 100%" />
|
<LoginFormTitle style="width: 100%" />
|
||||||
|
@ -185,12 +185,17 @@ const signIn = async () => {
|
|||||||
await getTenantId()
|
await getTenantId()
|
||||||
const data = await validForm()
|
const data = await validForm()
|
||||||
if (!data) return
|
if (!data) return
|
||||||
|
ElLoading.service({
|
||||||
|
lock: true,
|
||||||
|
text: '正在加载系统中...',
|
||||||
|
background: 'rgba(0, 0, 0, 0.7)'
|
||||||
|
})
|
||||||
loginLoading.value = true
|
loginLoading.value = true
|
||||||
smsVO.loginSms.mobile = loginData.loginForm.mobileNumber
|
smsVO.loginSms.mobile = loginData.loginForm.mobileNumber
|
||||||
smsVO.loginSms.code = loginData.loginForm.code
|
smsVO.loginSms.code = loginData.loginForm.code
|
||||||
await smsLogin(smsVO.loginSms)
|
await smsLogin(smsVO.loginSms)
|
||||||
.then(async (res) => {
|
.then(async (res) => {
|
||||||
setToken(res?.token)
|
setToken(res)
|
||||||
if (!redirect.value) {
|
if (!redirect.value) {
|
||||||
redirect.value = '/'
|
redirect.value = '/'
|
||||||
}
|
}
|
||||||
@ -199,6 +204,10 @@ const signIn = async () => {
|
|||||||
.catch(() => {})
|
.catch(() => {})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
loginLoading.value = false
|
loginLoading.value = false
|
||||||
|
setTimeout(() => {
|
||||||
|
const loadingInstance = ElLoading.service()
|
||||||
|
loadingInstance.close()
|
||||||
|
}, 400)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-row v-show="getShow" style="maring-left: -10px; maring-right: -10px">
|
<el-row v-show="getShow" style="margin-left: -10px; margin-right: -10px">
|
||||||
<el-col :span="24" style="padding-left: 10px; padding-right: 10px">
|
<el-col :span="24" style="padding-left: 10px; padding-right: 10px">
|
||||||
<LoginFormTitle style="width: 100%" />
|
<LoginFormTitle style="width: 100%" />
|
||||||
</el-col>
|
</el-col>
|
||||||
|
@ -55,7 +55,14 @@ const client = ref({
|
|||||||
name: '',
|
name: '',
|
||||||
logo: ''
|
logo: ''
|
||||||
})
|
})
|
||||||
const queryParams = reactive({
|
interface queryType {
|
||||||
|
responseType: string
|
||||||
|
clientId: string
|
||||||
|
redirectUri: string
|
||||||
|
state: string
|
||||||
|
scopes: string[]
|
||||||
|
}
|
||||||
|
const queryParams = reactive<queryType>({
|
||||||
// URL 上的 client_id、scope 等参数
|
// URL 上的 client_id、scope 等参数
|
||||||
responseType: '',
|
responseType: '',
|
||||||
clientId: '',
|
clientId: '',
|
||||||
@ -64,7 +71,10 @@ const queryParams = reactive({
|
|||||||
scopes: [] // 优先从 query 参数获取;如果未传递,从后端获取
|
scopes: [] // 优先从 query 参数获取;如果未传递,从后端获取
|
||||||
})
|
})
|
||||||
const ssoVisible = computed(() => unref(getLoginState) === LoginStateEnum.SSO) // 是否展示 SSO 登录的表单
|
const ssoVisible = computed(() => unref(getLoginState) === LoginStateEnum.SSO) // 是否展示 SSO 登录的表单
|
||||||
const formData = reactive({
|
interface formType {
|
||||||
|
scopes: string[]
|
||||||
|
}
|
||||||
|
const formData = reactive<formType>({
|
||||||
scopes: [] // 已选中的 scope 数组
|
scopes: [] // 已选中的 scope 数组
|
||||||
})
|
})
|
||||||
const formLoading = ref(false) // 表单是否提交中
|
const formLoading = ref(false) // 表单是否提交中
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
</el-button>
|
</el-button>
|
||||||
<el-scrollbar height="580">
|
<el-scrollbar height="580">
|
||||||
<div>
|
<div>
|
||||||
<pre><code class="hljs" v-html="highlightedCode(formData)"></code></pre>
|
<pre><code class="hljs" v-dompurify-html="highlightedCode(formData)"></code></pre>
|
||||||
</div>
|
</div>
|
||||||
</el-scrollbar>
|
</el-scrollbar>
|
||||||
</div>
|
</div>
|
||||||
@ -39,6 +39,7 @@ import hljs from 'highlight.js' // 导入代码高亮文件
|
|||||||
import 'highlight.js/styles/github.css' // 导入代码高亮样式
|
import 'highlight.js/styles/github.css' // 导入代码高亮样式
|
||||||
import xml from 'highlight.js/lib/languages/java'
|
import xml from 'highlight.js/lib/languages/java'
|
||||||
import json from 'highlight.js/lib/languages/json'
|
import json from 'highlight.js/lib/languages/json'
|
||||||
|
import formCreate from '@form-create/element-ui'
|
||||||
|
|
||||||
const { t } = useI18n() // 国际化
|
const { t } = useI18n() // 国际化
|
||||||
const message = useMessage() // 消息
|
const message = useMessage() // 消息
|
||||||
|
@ -106,7 +106,7 @@
|
|||||||
<el-button
|
<el-button
|
||||||
type="danger"
|
type="danger"
|
||||||
link
|
link
|
||||||
@click="handleDelete(scope.row)"
|
@click="handleDelete(scope.row.id)"
|
||||||
v-hasPermi="['infra:job:delete']"
|
v-hasPermi="['infra:job:delete']"
|
||||||
>
|
>
|
||||||
删除
|
删除
|
||||||
|
@ -443,14 +443,15 @@ const generateTableData = (propertyList: any[]) => {
|
|||||||
*/
|
*/
|
||||||
const validateData = (propertyList: any[]) => {
|
const validateData = (propertyList: any[]) => {
|
||||||
const skuPropertyIds: number[] = []
|
const skuPropertyIds: number[] = []
|
||||||
formData.value!.skus!.forEach((sku) =>
|
formData.value!.skus!.forEach(
|
||||||
sku.properties
|
(sku) =>
|
||||||
?.map((property) => property.propertyId)
|
sku.properties
|
||||||
?.forEach((propertyId) => {
|
?.map((property) => property.propertyId)
|
||||||
if (skuPropertyIds.indexOf(propertyId!) === -1) {
|
?.forEach((propertyId) => {
|
||||||
skuPropertyIds.push(propertyId!)
|
if (skuPropertyIds.indexOf(propertyId!) === -1) {
|
||||||
}
|
skuPropertyIds.push(propertyId!)
|
||||||
})
|
}
|
||||||
|
})
|
||||||
)
|
)
|
||||||
const propertyIds = propertyList.map((item) => item.id)
|
const propertyIds = propertyList.map((item) => item.id)
|
||||||
return skuPropertyIds.length === propertyIds.length
|
return skuPropertyIds.length === propertyIds.length
|
||||||
|
@ -134,11 +134,7 @@ const open = async (type: string, id?: number) => {
|
|||||||
const data = (await CombinationActivityApi.getCombinationActivity(
|
const data = (await CombinationActivityApi.getCombinationActivity(
|
||||||
id
|
id
|
||||||
)) as CombinationActivityApi.CombinationActivityVO
|
)) as CombinationActivityApi.CombinationActivityVO
|
||||||
await getSpuDetails(
|
await getSpuDetails(data.spuId!, data.products?.map((sku) => sku.skuId), data.products)
|
||||||
data.spuId!,
|
|
||||||
data.products?.map((sku) => sku.skuId),
|
|
||||||
data.products
|
|
||||||
)
|
|
||||||
formRef.value.setValues(data)
|
formRef.value.setValues(data)
|
||||||
} finally {
|
} finally {
|
||||||
formLoading.value = false
|
formLoading.value = false
|
||||||
|
@ -98,9 +98,10 @@ const handleDelete = (id: number) => {
|
|||||||
tableMethods.delList(id, false)
|
tableMethods.delList(id, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO @puhui999:要不还是使用原生的 element plus 做。感觉 crud schema 复杂界面,做起来麻烦
|
||||||
/** 初始化 **/
|
/** 初始化 **/
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
/*
|
/**
|
||||||
TODO
|
TODO
|
||||||
后面准备封装成一个函数来操作 tableColumns 重新排列:比如说需求是表单上商品选择是在后面的而列表展示的时候需要调到位置。
|
后面准备封装成一个函数来操作 tableColumns 重新排列:比如说需求是表单上商品选择是在后面的而列表展示的时候需要调到位置。
|
||||||
封装效果支持批量操作,给出 field 和需要插入的位置,例:[{field:'spuId',index: 1}] 效果为把 field 为 spuId 的 column 移动到第一个位置
|
封装效果支持批量操作,给出 field 和需要插入的位置,例:[{field:'spuId',index: 1}] 效果为把 field 为 spuId 的 column 移动到第一个位置
|
||||||
|
@ -50,8 +50,10 @@ const spuData = ref<Spu[]>([]) // spu 详情数据列表
|
|||||||
const skuListRef = ref() // 商品属性列表Ref
|
const skuListRef = ref() // 商品属性列表Ref
|
||||||
const spuPropertyList = ref<SpuProperty<T>[]>([]) // spuId 对应的 sku 的属性列表
|
const spuPropertyList = ref<SpuProperty<T>[]>([]) // spuId 对应的 sku 的属性列表
|
||||||
const expandRowKeys = ref<number[]>() // 控制展开行需要设置 row-key 属性才能使用,该属性为展开行的 keys 数组。
|
const expandRowKeys = ref<number[]>() // 控制展开行需要设置 row-key 属性才能使用,该属性为展开行的 keys 数组。
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取所有 sku 活动配置
|
* 获取所有 sku 活动配置
|
||||||
|
*
|
||||||
* @param extendedAttribute 在 sku 上扩展的属性,例:秒杀活动 sku 扩展属性 productConfig 请参考 seckillActivity.ts
|
* @param extendedAttribute 在 sku 上扩展的属性,例:秒杀活动 sku 扩展属性 productConfig 请参考 seckillActivity.ts
|
||||||
*/
|
*/
|
||||||
const getSkuConfigs = (extendedAttribute: string) => {
|
const getSkuConfigs = (extendedAttribute: string) => {
|
||||||
|
@ -144,11 +144,7 @@ const open = async (type: string, id?: number) => {
|
|||||||
const data = (await SeckillActivityApi.getSeckillActivity(
|
const data = (await SeckillActivityApi.getSeckillActivity(
|
||||||
id
|
id
|
||||||
)) as SeckillActivityApi.SeckillActivityVO
|
)) as SeckillActivityApi.SeckillActivityVO
|
||||||
await getSpuDetails(
|
await getSpuDetails(data.spuId!, data.products?.map((sku) => sku.skuId), data.products)
|
||||||
data.spuId!,
|
|
||||||
data.products?.map((sku) => sku.skuId),
|
|
||||||
data.products
|
|
||||||
)
|
|
||||||
formRef.value.setValues(data)
|
formRef.value.setValues(data)
|
||||||
} finally {
|
} finally {
|
||||||
formLoading.value = false
|
formLoading.value = false
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
<el-select class="!w-280px" v-model="queryParams.status" clearable placeholder="全部">
|
<el-select class="!w-280px" v-model="queryParams.status" clearable placeholder="全部">
|
||||||
<el-option
|
<el-option
|
||||||
v-for="dict in getStrDictOptions(DICT_TYPE.TRADE_ORDER_STATUS)"
|
v-for="dict in getStrDictOptions(DICT_TYPE.TRADE_ORDER_STATUS)"
|
||||||
:key="(dict.value as string)"
|
:key="dict.value as string"
|
||||||
:label="dict.label"
|
:label="dict.label"
|
||||||
:value="dict.value"
|
:value="dict.value"
|
||||||
/>
|
/>
|
||||||
@ -27,7 +27,7 @@
|
|||||||
>
|
>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="dict in getStrDictOptions(DICT_TYPE.PAY_CHANNEL_CODE_TYPE)"
|
v-for="dict in getStrDictOptions(DICT_TYPE.PAY_CHANNEL_CODE_TYPE)"
|
||||||
:key="(dict.value as string)"
|
:key="dict.value as string"
|
||||||
:label="dict.label"
|
:label="dict.label"
|
||||||
:value="dict.value"
|
:value="dict.value"
|
||||||
/>
|
/>
|
||||||
@ -48,7 +48,7 @@
|
|||||||
<el-select class="!w-280px" v-model="queryParams.terminal" clearable placeholder="全部">
|
<el-select class="!w-280px" v-model="queryParams.terminal" clearable placeholder="全部">
|
||||||
<el-option
|
<el-option
|
||||||
v-for="dict in getStrDictOptions(DICT_TYPE.TERMINAL)"
|
v-for="dict in getStrDictOptions(DICT_TYPE.TERMINAL)"
|
||||||
:key="(dict.value as string)"
|
:key="dict.value as string"
|
||||||
:label="dict.label"
|
:label="dict.label"
|
||||||
:value="dict.value"
|
:value="dict.value"
|
||||||
/>
|
/>
|
||||||
@ -58,7 +58,7 @@
|
|||||||
<el-select class="!w-280px" v-model="queryParams.type" clearable placeholder="全部">
|
<el-select class="!w-280px" v-model="queryParams.type" clearable placeholder="全部">
|
||||||
<el-option
|
<el-option
|
||||||
v-for="dict in getStrDictOptions(DICT_TYPE.TRADE_ORDER_TYPE)"
|
v-for="dict in getStrDictOptions(DICT_TYPE.TRADE_ORDER_TYPE)"
|
||||||
:key="(dict.value as string)"
|
:key="dict.value as string"
|
||||||
:label="dict.label"
|
:label="dict.label"
|
||||||
:value="dict.value"
|
:value="dict.value"
|
||||||
/>
|
/>
|
||||||
|
@ -90,8 +90,19 @@
|
|||||||
padding: 15px;
|
padding: 15px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
font-family: Segoe UI, Lucida Grande, Helvetica, Arial, Microsoft YaHei, FreeSans, Arimo,
|
font-family:
|
||||||
Droid Sans, wenquanyi micro hei, Hiragino Sans GB, Hiragino Sans GB W3, FontAwesome,
|
Segoe UI,
|
||||||
|
Lucida Grande,
|
||||||
|
Helvetica,
|
||||||
|
Arial,
|
||||||
|
Microsoft YaHei,
|
||||||
|
FreeSans,
|
||||||
|
Arimo,
|
||||||
|
Droid Sans,
|
||||||
|
wenquanyi micro hei,
|
||||||
|
Hiragino Sans GB,
|
||||||
|
Hiragino Sans GB W3,
|
||||||
|
FontAwesome,
|
||||||
sans-serif;
|
sans-serif;
|
||||||
color: #333;
|
color: #333;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
@ -99,7 +110,16 @@
|
|||||||
|
|
||||||
blockquote {
|
blockquote {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-family: Georgia, Times New Roman, Times, Kai, Kaiti SC, KaiTi, BiauKai, FontAwesome, serif;
|
font-family:
|
||||||
|
Georgia,
|
||||||
|
Times New Roman,
|
||||||
|
Times,
|
||||||
|
Kai,
|
||||||
|
Kaiti SC,
|
||||||
|
KaiTi,
|
||||||
|
BiauKai,
|
||||||
|
FontAwesome,
|
||||||
|
serif;
|
||||||
padding: 1px 0 1px 15px;
|
padding: 1px 0 1px 15px;
|
||||||
border-left: 4px solid #ddd;
|
border-left: 4px solid #ddd;
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
"resolveJsonModule": true,
|
"resolveJsonModule": true,
|
||||||
"esModuleInterop": true,
|
"esModuleInterop": true,
|
||||||
"lib": ["esnext", "dom"],
|
"lib": ["esnext", "dom"],
|
||||||
"baseUrl": ".",
|
"baseUrl": "./",
|
||||||
"allowJs": true,
|
"allowJs": true,
|
||||||
"forceConsistentCasingInFileNames": true,
|
"forceConsistentCasingInFileNames": true,
|
||||||
"allowSyntheticDefaultImports": true,
|
"allowSyntheticDefaultImports": true,
|
||||||
@ -36,7 +36,7 @@
|
|||||||
"typeRoots": ["./node_modules/@types/", "./types"]
|
"typeRoots": ["./node_modules/@types/", "./types"]
|
||||||
},
|
},
|
||||||
"include": [
|
"include": [
|
||||||
"src/**/*",
|
"src",
|
||||||
"types/**/*.d.ts",
|
"types/**/*.d.ts",
|
||||||
"src/types/auto-imports.d.ts",
|
"src/types/auto-imports.d.ts",
|
||||||
"src/types/auto-components.d.ts"
|
"src/types/auto-components.d.ts"
|
||||||
|
105
uno.config.ts
Normal file
105
uno.config.ts
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
import { defineConfig, toEscapedSelector as e, presetUno } from 'unocss'
|
||||||
|
import transformerVariantGroup from '@unocss/transformer-variant-group'
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
// ...UnoCSS options
|
||||||
|
rules: [
|
||||||
|
[
|
||||||
|
/^custom-hover$/,
|
||||||
|
([], { rawSelector }) => {
|
||||||
|
const selector = e(rawSelector)
|
||||||
|
return `
|
||||||
|
${selector} {
|
||||||
|
display: flex;
|
||||||
|
height: 100%;
|
||||||
|
padding: 1px 10px 0;
|
||||||
|
cursor: pointer;
|
||||||
|
align-items: center;
|
||||||
|
transition: background var(--transition-time-02);
|
||||||
|
}
|
||||||
|
/* you can have multiple rules */
|
||||||
|
${selector}:hover {
|
||||||
|
background-color: var(--top-header-hover-color);
|
||||||
|
}
|
||||||
|
.dark ${selector}:hover {
|
||||||
|
background-color: var(--el-bg-color-overlay);
|
||||||
|
}
|
||||||
|
`
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
/^layout-border__left$/,
|
||||||
|
([], { rawSelector }) => {
|
||||||
|
const selector = e(rawSelector)
|
||||||
|
return `
|
||||||
|
${selector}:before {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 1px;
|
||||||
|
height: 100%;
|
||||||
|
background-color: var(--el-border-color);
|
||||||
|
z-index: 3;
|
||||||
|
}
|
||||||
|
`
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
/^layout-border__right$/,
|
||||||
|
([], { rawSelector }) => {
|
||||||
|
const selector = e(rawSelector)
|
||||||
|
return `
|
||||||
|
${selector}:after {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
width: 1px;
|
||||||
|
height: 100%;
|
||||||
|
background-color: var(--el-border-color);
|
||||||
|
z-index: 3;
|
||||||
|
}
|
||||||
|
`
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
/^layout-border__top$/,
|
||||||
|
([], { rawSelector }) => {
|
||||||
|
const selector = e(rawSelector)
|
||||||
|
return `
|
||||||
|
${selector}:before {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 1px;
|
||||||
|
background-color: var(--el-border-color);
|
||||||
|
z-index: 3;
|
||||||
|
}
|
||||||
|
`
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
/^layout-border__bottom$/,
|
||||||
|
([], { rawSelector }) => {
|
||||||
|
const selector = e(rawSelector)
|
||||||
|
return `
|
||||||
|
${selector}:after {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 1px;
|
||||||
|
background-color: var(--el-border-color);
|
||||||
|
z-index: 3;
|
||||||
|
}
|
||||||
|
`
|
||||||
|
}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
presets: [presetUno({ dark: 'class', attributify: false })],
|
||||||
|
transformers: [transformerVariantGroup()]
|
||||||
|
})
|
@ -1,61 +0,0 @@
|
|||||||
import { defineConfig } from 'vite-plugin-windicss'
|
|
||||||
import plugin from 'windicss/plugin'
|
|
||||||
|
|
||||||
function range(size, startAt = 1) {
|
|
||||||
return Array.from(Array(size).keys()).map((i) => i + startAt)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default defineConfig({
|
|
||||||
extract: {
|
|
||||||
include: ['src/**/*.{vue,html,jsx,tsx}'],
|
|
||||||
exclude: ['node_modules', '.git']
|
|
||||||
},
|
|
||||||
darkMode: 'class',
|
|
||||||
attributify: false,
|
|
||||||
theme: {
|
|
||||||
extend: {
|
|
||||||
backgroundColor: {
|
|
||||||
// 暗黑背景色
|
|
||||||
'v-dark': 'var(--dark-bg-color)'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
plugins: [
|
|
||||||
plugin(({ addComponents }) => {
|
|
||||||
const obj = {}
|
|
||||||
range(50).map((i) => {
|
|
||||||
obj[`.border-top-${i}`] = {
|
|
||||||
borderTopWidth: `${i}px`
|
|
||||||
}
|
|
||||||
obj[`.border-left-${i}`] = {
|
|
||||||
borderLeftWidth: `${i}px`
|
|
||||||
}
|
|
||||||
obj[`.border-right-${i}`] = {
|
|
||||||
borderRightWidth: `${i}px`
|
|
||||||
}
|
|
||||||
obj[`.border-bottom-${i}`] = {
|
|
||||||
borderBottomWidth: `${i}px`
|
|
||||||
}
|
|
||||||
})
|
|
||||||
addComponents({
|
|
||||||
'.hover-trigger': {
|
|
||||||
display: 'flex',
|
|
||||||
height: '100%',
|
|
||||||
padding: '1px 10px 0',
|
|
||||||
cursor: 'pointer',
|
|
||||||
alignItems: 'center',
|
|
||||||
transition: 'background var(--transition-time-02)',
|
|
||||||
'&:hover': {
|
|
||||||
backgroundColor: 'var(--top-header-hover-color)'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'.dark .hover-trigger': {
|
|
||||||
'&:hover': {
|
|
||||||
backgroundColor: 'var(--el-bg-color-overlay)'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
...obj
|
|
||||||
})
|
|
||||||
})
|
|
||||||
]
|
|
||||||
})
|
|
Loading…
Reference in New Issue
Block a user