diff --git a/src/assets/styles/element-ui.scss b/src/assets/styles/element-ui.scss index c6c402a..ebd10da 100644 --- a/src/assets/styles/element-ui.scss +++ b/src/assets/styles/element-ui.scss @@ -116,3 +116,15 @@ .el-menu--horizontal .el-sub-menu .el-sub-menu__icon-arrow { right: calc(0px - var(--el-menu-base-level-padding)) !important; } + +// 弹出搜索框 +.header-search-select { + .el-select-dropdown__item { + height: unset !important; + line-height: unset !important; + margin-bottom: 5px; + display: flex; + align-items: center; + justify-content: space-between; + } +} diff --git a/src/components/HeaderSearch/index.vue b/src/components/HeaderSearch/index.vue index 18d7fb5..b6dfe92 100644 --- a/src/components/HeaderSearch/index.vue +++ b/src/components/HeaderSearch/index.vue @@ -11,7 +11,8 @@ filterable default-first-option remote - class="header_search_select" + popper-class="header-search-select" + placement="bottom" placeholder="菜单搜索,支持标题、URL模糊查询" @change="change"> - {{ option.item.title.join(' > ') }} - {{ option.item.path }} + +
+ {{ option.item.title.join(' > ') }} +
{{ option.item.path }}
+
+
+
@@ -33,7 +39,8 @@ import Fuse from 'fuse.js' import { getNormalPath } from '@/utils/ruoyi' import { isHttp } from '@/utils/validate' import usePermissionStore from '@/store/modules/permission' - +import { findItem, color16 } from '@/utils/ruoyi' +const { proxy } = getCurrentInstance() const search = ref('') const options = ref([]) const searchPool = ref([]) @@ -108,12 +115,15 @@ function generateRoutes(routes, basePath = '', prefixTitle = []) { const p = r.path.length > 0 && r.path[0] === '/' ? r.path : '/' + r.path const data = { path: !isHttp(r.path) ? getNormalPath(basePath + p) : r.path, - title: [...prefixTitle] + title: [...prefixTitle], + icon: 'menu', + menuTitle: '' } if (r.meta && r.meta.title) { data.title = [...data.title, r.meta.title] - + data.icon = r.meta.icon + data.menuTitle = r.meta.title if (r.redirect !== 'noRedirect') { // only push the routes with title // special case: need to exclude parent router without redirect @@ -138,6 +148,28 @@ function querySearch(query) { options.value = [] } } +/** + * 添加快捷菜单 + * @param {*} item + */ +function handleLove(item) { + var arraryObjectLocal = proxy.$cache.local.getJSON('commonlyUseMenu') || [] + + var len = 12 + if (arraryObjectLocal.length >= len) { + proxy.$modal.msgError(`最多可添加${len}个常用菜单`) + return + } + let index = findItem(arraryObjectLocal, 'path', item.path) + if (index <= -1) { + arraryObjectLocal.push({ ...item, color: color16() }) + proxy.$cache.local.setJSON('commonlyUseMenu', arraryObjectLocal) + proxy.$modal.msgSuccess('添加成功') + usePermissionStore().setCommonlyUsedRoutes() + } else { + proxy.$modal.msgError('该菜单已存在') + } +} onMounted(() => { searchPool.value = generateRoutes(routes.value) @@ -178,18 +210,14 @@ watch(searchPool, (list) => { } } - .header_search_select { - height: 50px; - - :deep(.el-input__wrapper) { - height: 50px; - } - } - .search-icon { cursor: pointer; font-size: 18px; vertical-align: middle; } } +.path { + color: #ccc; + font-size: 10px; +} diff --git a/src/layout/components/Settings/index.vue b/src/layout/components/Settings/index.vue index 1dc344d..98630eb 100644 --- a/src/layout/components/Settings/index.vue +++ b/src/layout/components/Settings/index.vue @@ -31,9 +31,13 @@ --> +
{{ $t('layout.themeColor') }} - + +
@@ -329,5 +333,16 @@ defineExpose({ float: right; margin: -3px 8px 0px 0px; } + .quick-color-wrap { + display: flex; + align-items: center; + + span { + width: 15px; + height: 15px; + margin-right: 10px; + cursor: pointer; + } + } } diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js index ceb7e73..ca4bcea 100644 --- a/src/store/modules/permission.js +++ b/src/store/modules/permission.js @@ -3,6 +3,7 @@ import { getRouters } from '@/api/system/menu' import Layout from '@/layout/index' import ParentView from '@/components/ParentView' import InnerLink from '@/layout/components/InnerLink' +import cache from '@/plugins/cache' // 匹配views里面所有的.vue文件 const modules = import.meta.glob('./../../views/**/*.vue') @@ -12,7 +13,8 @@ const usePermissionStore = defineStore('permission', { routes: [], defaultRoutes: [], topbarRouters: [], - sidebarRouters: [] + sidebarRouters: [], + commonlyUsedRoutes: [] //常用路由 }), actions: { setRoutes(routes) { @@ -43,9 +45,23 @@ const usePermissionStore = defineStore('permission', { this.setSidebarRouters(constantRoutes.concat(sidebarRoutes)) this.setDefaultRoutes(sidebarRoutes) this.setTopbarRoutes(defaultRoutes) + this.setCommonlyUsedRoutes() resolve(rewriteRoutes) }) }) + }, + // 设置常用路由 + setCommonlyUsedRoutes() { + var arraryObjectLocal = cache.local.getJSON('commonlyUseMenu') || [] + this.commonlyUsedRoutes = arraryObjectLocal + }, + // 移除常用路由 + removeCommonlyUsedRoutes(item) { + var routes = this.commonlyUsedRoutes + + const fi = routes.findIndex((v) => v.path === item.path) + routes.splice(fi, 1) + cache.local.setJSON('commonlyUseMenu', routes) } } }) diff --git a/src/utils/request.js b/src/utils/request.js index 9ad156f..361296c 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -84,7 +84,7 @@ service.interceptors.response.use( } else if (message.includes('Request failed with status code 429')) { message = '请求过于频繁,请稍后再试' } else if (message.includes('Request failed with status code')) { - message = '系统接口' + message.substr(message.length - 3) + '异常' + message = '系统接口' + message.substr(message.length - 3) + '异常,请联系管理员' } ElMessage({ message: message, diff --git a/src/utils/ruoyi.js b/src/utils/ruoyi.js index 92f6e4d..54fbb5d 100644 --- a/src/utils/ruoyi.js +++ b/src/utils/ruoyi.js @@ -257,3 +257,28 @@ export function isEmpty(obj) { return false } } + +/** + * 查找对象的唯一键值对(比如id)去判断是否存在某个数据中 + * @param {*} arr 数组 + * @param {*} key 对象键值名 + * @param {*} val + * @returns + */ +export function findItem(arr, key, val) { + for (let i = 0; i < arr.length; i++) { + if (arr[i][key] == val) { + return i + } + } + return -1 +} + +export function color16() { + //十六进制颜色随机 + const r = Math.floor(Math.random() * 256) + const g = Math.floor(Math.random() * 256) + const b = Math.floor(Math.random() * 256) + const color = `#${r.toString(16)}${g.toString(16)}${b.toString(16)}` + return color +} diff --git a/src/views/components/CommonMenu/index.vue b/src/views/components/CommonMenu/index.vue index 4e23123..0264ff1 100644 --- a/src/views/components/CommonMenu/index.vue +++ b/src/views/components/CommonMenu/index.vue @@ -1,33 +1,60 @@