样式修改
parent
bf8e1543d4
commit
f22cd3fa7e
|
|
@ -5,8 +5,30 @@ charset = utf-8
|
|||
end_of_line = lf
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
tab_width = 2
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
max_line_length = 1000
|
||||
|
||||
|
||||
[*.styl]
|
||||
ij_continuation_indent_size = 4
|
||||
ij_stylus_align_closing_brace_with_properties = false
|
||||
ij_stylus_blank_lines_around_nested_selector = 1
|
||||
ij_stylus_blank_lines_between_blocks = 1
|
||||
ij_stylus_brace_placement = 0
|
||||
ij_stylus_enforce_property_name_value_separator_on_format = false
|
||||
ij_stylus_enforce_quotes_on_format = false
|
||||
ij_stylus_hex_color_long_format = true
|
||||
ij_stylus_hex_color_lower_case = false
|
||||
ij_stylus_hex_color_short_format = false
|
||||
ij_stylus_hex_color_upper_case = true
|
||||
ij_stylus_is_property_name_value_separated_by_colon = false
|
||||
ij_stylus_keep_blank_lines_in_code = 2
|
||||
ij_stylus_keep_indents_on_empty_lines = false
|
||||
ij_stylus_keep_single_line_blocks = false
|
||||
ij_stylus_properties_order = font, font-family, font-size, font-weight, font-style, font-variant, font-size-adjust, font-stretch, line-height, position, z-index, top, right, bottom, left, display, visibility, float, clear, overflow, overflow-x, overflow-y, clip, zoom, align-content, align-items, align-self, flex, flex-flow, flex-basis, flex-direction, flex-grow, flex-shrink, flex-wrap, justify-content, order, box-sizing, width, min-width, max-width, height, min-height, max-height, margin, margin-top, margin-right, margin-bottom, margin-left, padding, padding-top, padding-right, padding-bottom, padding-left, table-layout, empty-cells, caption-side, border-spacing, border-collapse, list-style, list-style-position, list-style-type, list-style-image, content, quotes, counter-reset, counter-increment, resize, cursor, user-select, nav-index, nav-up, nav-right, nav-down, nav-left, transition, transition-delay, transition-timing-function, transition-duration, transition-property, transform, transform-origin, animation, animation-name, animation-duration, animation-play-state, animation-timing-function, animation-delay, animation-iteration-count, animation-direction, text-align, text-align-last, vertical-align, white-space, text-decoration, text-emphasis, text-emphasis-color, text-emphasis-style, text-emphasis-position, text-indent, text-justify, letter-spacing, word-spacing, text-outline, text-transform, text-wrap, text-overflow, text-overflow-ellipsis, text-overflow-mode, word-wrap, word-break, tab-size, hyphens, pointer-events, opacity, color, border, border-width, border-style, border-color, border-top, border-top-width, border-top-style, border-top-color, border-right, border-right-width, border-right-style, border-right-color, border-bottom, border-bottom-width, border-bottom-style, border-bottom-color, border-left, border-left-width, border-left-style, border-left-color, border-radius, border-top-left-radius, border-top-right-radius, border-bottom-right-radius, border-bottom-left-radius, border-image, border-image-source, border-image-slice, border-image-width, border-image-outset, border-image-repeat, outline, outline-width, outline-style, outline-color, outline-offset, background, background-color, background-image, background-repeat, background-attachment, background-position, background-position-x, background-position-y, background-clip, background-origin, background-size, box-decoration-break, box-shadow, text-shadow
|
||||
ij_stylus_space_after_colon = true
|
||||
ij_stylus_space_before_opening_brace = true
|
||||
ij_stylus_use_double_quotes = true
|
||||
ij_stylus_value_alignment = 0
|
||||
|
|
|
|||
|
|
@ -1,112 +1,102 @@
|
|||
import { defineStore } from 'pinia'
|
||||
import Evt from '@/common/utils/evt.ts'
|
||||
import Nav from '@/common/router/nav.ts'
|
||||
|
||||
const pageContextCache = new Map<string, AppTypes.PageContext>()
|
||||
|
||||
|
||||
function initCache() {
|
||||
pageContextCache.clear()
|
||||
}
|
||||
|
||||
initCache()
|
||||
import Strings from '@/common/utils/strings.ts'
|
||||
import Utils from '@/common/utils'
|
||||
import { SpecialPage } from '@/common/router/constants.ts'
|
||||
|
||||
export const useAppPageStore = defineStore('AppPage', () => {
|
||||
const keepAliveInclude = ref<string[]>([])
|
||||
const pages = ref<AppTypes.PageContext[]>([])
|
||||
const pages = Utils.resetAble(reactive<AppTypes.PageContext[]>([]))/* as Reactive<AppTypes.PageContext[]> */
|
||||
|
||||
const currentPage = ref<string>('')
|
||||
const currentPage = Utils.resetAble(reactive<AppTypes.PageContext>({
|
||||
insId: '',
|
||||
title: '',
|
||||
keepAlive: false,
|
||||
params: {},
|
||||
routeName: '',
|
||||
menuId: '',
|
||||
icon: '',
|
||||
breadcrumb: [],
|
||||
}))/* as Reactive<AppTypes.PageContext> */
|
||||
|
||||
const ctx = computed(() => {
|
||||
return pageContextCache.get(currentPage.value)!
|
||||
const keepAliveInclude = computed(() => {
|
||||
return pages.filter(it => it.keepAlive).map(it => it.routeName)
|
||||
})
|
||||
|
||||
function open(ctx_: AppTypes.PageContext) {
|
||||
currentPage.value = ctx_.insId
|
||||
if (!pageContextCache.has(ctx_.insId)) {
|
||||
pageContextCache.set(ctx_.insId, ctx_)
|
||||
}
|
||||
if (!keepAliveInclude.value.includes(ctx_.insId)) {
|
||||
keepAliveInclude.value.push(ctx_.insId)
|
||||
}
|
||||
if (!pages.value.find(it => it.insId === ctx_.insId)) {
|
||||
pages.value.push(ctx_)
|
||||
}
|
||||
function open(ctx?: AppTypes.PageContext) {
|
||||
if (
|
||||
ctx == null
|
||||
|| Strings.isBlank(ctx.insId)
|
||||
|| currentPage.insId === ctx.insId) return Promise.reject('已在当前页面')
|
||||
const page = pages.find(it => it.insId === ctx.insId)
|
||||
if (page == null) pages.push(ctx)
|
||||
currentPage.$reset(ctx)
|
||||
return Promise.resolve(ctx)
|
||||
}
|
||||
|
||||
function reopen(insId: string) {
|
||||
if (currentPage.value === insId) {
|
||||
return
|
||||
}
|
||||
const page = pageContextCache.get(insId)
|
||||
if (page) {
|
||||
currentPage.value = insId
|
||||
Nav.open(page.routeName)
|
||||
}
|
||||
const page = pages.find(it => it.insId === insId)
|
||||
return open(page)
|
||||
}
|
||||
|
||||
function closePage(insId: string) {
|
||||
pageContextCache.delete(insId)
|
||||
if (keepAliveInclude.value.includes(insId)) {
|
||||
keepAliveInclude.value = keepAliveInclude.value.splice(keepAliveInclude.value.indexOf(insId), 1)
|
||||
}
|
||||
const index = pages.value.findIndex(it => it.insId === insId)
|
||||
if (index !== -1) {
|
||||
const oldLen = pages.value.length
|
||||
pages.value = pages.value.filter(it => it.insId !== insId)
|
||||
|
||||
if (currentPage.value !== insId) {
|
||||
return
|
||||
}
|
||||
if (index === 0) {
|
||||
if (pages.value.length > 0) {
|
||||
reopen(pages.value[0]?.insId)
|
||||
} else {
|
||||
Nav.open('home')
|
||||
}
|
||||
const index = pages.findIndex(it => it.insId === insId)
|
||||
if (index < 1 || pages[index].routeName === SpecialPage.Home) return Promise.reject('不能关闭首页')
|
||||
pages.splice(index, 1)
|
||||
if (currentPage.insId !== insId) return Promise.resolve(null)
|
||||
const newLen = pages.length
|
||||
const oldLen = newLen + 1
|
||||
let page: AppTypes.PageContext | undefined
|
||||
if (index === 1) {
|
||||
page = newLen > 1 ? pages[1] : pages[0]
|
||||
} else if (index === oldLen - 1) {
|
||||
if (pages.value.length > 0) {
|
||||
reopen(pages.value[pages.value.length - 1]?.insId)
|
||||
page = pages[newLen - 1]
|
||||
} else {
|
||||
Nav.open('home')
|
||||
}
|
||||
} else {
|
||||
if (pages.value.length > 0) {
|
||||
reopen(pages.value[index]?.insId)
|
||||
} else {
|
||||
Nav.open('home')
|
||||
}
|
||||
}
|
||||
page = pages[index]
|
||||
}
|
||||
return open(page)
|
||||
}
|
||||
|
||||
function closeCurrent() {
|
||||
closePage(currentPage.value)
|
||||
return closePage(currentPage.insId)
|
||||
}
|
||||
|
||||
function closeLeft() {
|
||||
const index = pages.findIndex(it => it.insId === currentPage.insId)
|
||||
if (index < 2) return
|
||||
pages.splice(1, index - 1)
|
||||
}
|
||||
|
||||
function closeRight() {
|
||||
const index = pages.findIndex(it => it.insId === currentPage.insId)
|
||||
if (index < 0) return
|
||||
pages.splice(index + 1, pages.length - index - 1)
|
||||
}
|
||||
|
||||
function closeOther() {
|
||||
pages.value = pages.value.filter(it => it.insId === currentPage.value)
|
||||
const pageList = pages.filter(it => it.routeName === SpecialPage.Home || it.insId === currentPage.insId)
|
||||
pages.$reset(pageList)
|
||||
}
|
||||
|
||||
function closeAll() {
|
||||
pages.value = []
|
||||
Nav.open('home')
|
||||
const page = pages.find(it => it.routeName === SpecialPage.Home)!
|
||||
pages.$reset([ page ])
|
||||
return open(page)
|
||||
}
|
||||
|
||||
function $reset() {
|
||||
keepAliveInclude.value = []
|
||||
currentPage.value = ''
|
||||
initCache()
|
||||
pages.$reset()
|
||||
currentPage.$reset()
|
||||
}
|
||||
|
||||
Evt.on('logout', $reset)
|
||||
|
||||
return {
|
||||
ctx,
|
||||
reopen,
|
||||
open,
|
||||
closePage,
|
||||
closeCurrent,
|
||||
closeLeft,
|
||||
closeRight,
|
||||
closeOther,
|
||||
closeAll,
|
||||
pages,
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ const home = {
|
|||
'sn': 'menus',
|
||||
'pid': '0',
|
||||
'title': '首页',
|
||||
'icon': 'menus',
|
||||
'icon': 'home-3-line',
|
||||
'tier': 1,
|
||||
'breadcrumb': [
|
||||
'首页',
|
||||
|
|
@ -22,7 +22,8 @@ const home = {
|
|||
'routeName': 'home',
|
||||
'path': '/home',
|
||||
}
|
||||
export const reloadUserInfo = () => {
|
||||
|
||||
export function reloadUserInfo() {
|
||||
const appSettingStore = useAppSettingStore()
|
||||
const appUserStore = useAppUserStore()
|
||||
return LoginApi.my()
|
||||
|
|
@ -49,31 +50,6 @@ export const reloadUserInfo = () => {
|
|||
})
|
||||
}
|
||||
|
||||
/* export const loadUserInfo = () => {
|
||||
const appSettingStore = useAppSettingStore()
|
||||
const appUserStore = useAppUserStore()
|
||||
return LoginApi.my()
|
||||
.then(({data}) => {
|
||||
const menuTree = Utils.clone(Colls.toTree(data.menus))
|
||||
appSettingStore.$patch({
|
||||
menus: data.menus, menuTree,
|
||||
theme: data.setting?.theme ?? 'light',
|
||||
collectedMenus: data.setting?.collectedMenus ?? [],
|
||||
logo: data.setting?.logo,
|
||||
language: data.setting?.language ?? 'zh',
|
||||
})
|
||||
appUserStore.$patch({
|
||||
userId: data.id,
|
||||
nickname: data.nickname,
|
||||
avatar: data.avatar,
|
||||
tenantId: data.tenantId,
|
||||
tenantName: data.tenantName,
|
||||
bizObj: data.bizObj,
|
||||
roles: data.roles,
|
||||
})
|
||||
})
|
||||
} */
|
||||
|
||||
export function hasPermission(resSn?: string) {
|
||||
const appSettingStore = useAppSettingStore()
|
||||
const res = appSettingStore.menus.find(it => it.sn === resSn)
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ import {
|
|||
getRoutes,
|
||||
} from '@/common/router/route-config.ts'
|
||||
import { SpecialPage } from '@/common/router/constants.ts'
|
||||
import Nav from '@/common/router/nav.ts'
|
||||
|
||||
function addRoutes(routNames: string[]) {
|
||||
if (Colls.isEmpty(routNames)) return
|
||||
|
|
@ -81,7 +80,7 @@ router.beforeEach((to, from) => {
|
|||
routeName = SpecialPage.Home
|
||||
}
|
||||
setTimeout(() => {
|
||||
Nav.open(routeName)
|
||||
Evt.emit('browserReflash', routeName)
|
||||
})
|
||||
return false
|
||||
}
|
||||
|
|
@ -118,19 +117,4 @@ export function reloadRouter() {
|
|||
return true
|
||||
}
|
||||
|
||||
Evt.on('login', (_) => {
|
||||
Nav.open(SpecialPage.Home)
|
||||
})
|
||||
|
||||
Evt.on('logout', (_) => {
|
||||
const routes = router
|
||||
.getRoutes()
|
||||
.filter((it) => it.name !== SpecialPage.Main && it.name !== SpecialPage.Login && it.name !== SpecialPage.NotFound && it.name !== SpecialPage.Home)
|
||||
.map((it) => it.name as string)
|
||||
removeRoutes(routes)
|
||||
router.push({replace: true, name: SpecialPage.Login}).then(() => {
|
||||
// console.log(r)
|
||||
})
|
||||
})
|
||||
|
||||
export default router
|
||||
|
|
|
|||
|
|
@ -1,10 +1,14 @@
|
|||
import router, { reloadRouter } from '@/common/router/index.ts'
|
||||
import router, {
|
||||
reloadRouter,
|
||||
removeRoutes,
|
||||
} from '@/common/router/index.ts'
|
||||
import Evt from '@/common/utils/evt.ts'
|
||||
import { useAppSettingStore } from '@/common/app/app-setting-store.ts'
|
||||
import { useAppPageStore } from '@/common/app/app-page-store.ts'
|
||||
import { nanoid } from 'nanoid'
|
||||
import { reloadUserInfo } from '@/common/app'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import type { App } from 'vue'
|
||||
import { SpecialPage } from '@/common/router/constants.ts'
|
||||
|
||||
type Option = Partial<Pick<AppTypes.PageContext, 'params' | 'insId' | 'title'>> & Pick<AppTypes.PageContext, 'routeName'>
|
||||
|
||||
|
|
@ -13,7 +17,8 @@ type Option = Partial<Pick<AppTypes.PageContext, 'params' | 'insId' | 'title'>>
|
|||
*
|
||||
* @param option
|
||||
*/
|
||||
function open(option: string | Option) {
|
||||
|
||||
/* function open(option: string | Option) {
|
||||
let ctx: AppTypes.PageContext
|
||||
const appSettingStore = useAppSettingStore()
|
||||
if (typeof option === 'string') {
|
||||
|
|
@ -32,7 +37,7 @@ function open(option: string | Option) {
|
|||
return Promise.reject('页面不存在')
|
||||
}
|
||||
ctx = {
|
||||
insId: routeName + '_' + nanoid(),
|
||||
insId: routeName,
|
||||
title: menu.title,
|
||||
keepAlive: true,
|
||||
params: {},
|
||||
|
|
@ -41,7 +46,6 @@ function open(option: string | Option) {
|
|||
icon: menu.icon,
|
||||
breadcrumb: menu.breadcrumb,
|
||||
}
|
||||
ctx.insId = ctx.routeName
|
||||
useAppPageStore().open(ctx)
|
||||
return router.push({name: ctx.routeName, params: ctx.params})
|
||||
.then(err => {
|
||||
|
|
@ -63,7 +67,7 @@ function open(option: string | Option) {
|
|||
return Promise.reject('页面不存在')
|
||||
}
|
||||
ctx = {
|
||||
insId: routeName + '_' + nanoid(),
|
||||
insId: routeName ,
|
||||
title: menu.title,
|
||||
keepAlive: true,
|
||||
params: {},
|
||||
|
|
@ -89,7 +93,7 @@ function open(option: string | Option) {
|
|||
}
|
||||
const option_ = option as Option
|
||||
ctx = {
|
||||
insId: option_.insId ?? routeName + '_' + nanoid(),
|
||||
insId: option_.insId ?? routeName,
|
||||
title: option_.title ?? menu.title,
|
||||
routeName: routeName,
|
||||
keepAlive: true,
|
||||
|
|
@ -98,7 +102,6 @@ function open(option: string | Option) {
|
|||
icon: menu.icon,
|
||||
breadcrumb: menu.breadcrumb,
|
||||
}
|
||||
ctx.insId = ctx.routeName
|
||||
useAppPageStore().open(ctx)
|
||||
return router.push({name: ctx.routeName, params: ctx.params})
|
||||
.then(err => {
|
||||
|
|
@ -121,7 +124,7 @@ function open(option: string | Option) {
|
|||
}
|
||||
|
||||
ctx = {
|
||||
insId: option.insId ?? routeName + '_' + nanoid(),
|
||||
insId: option.insId ?? routeName,
|
||||
title: option.title ?? menu.title,
|
||||
routeName: routeName,
|
||||
keepAlive: true,
|
||||
|
|
@ -131,7 +134,6 @@ function open(option: string | Option) {
|
|||
breadcrumb: menu.breadcrumb,
|
||||
}
|
||||
}
|
||||
ctx.insId = ctx.routeName
|
||||
useAppPageStore().open(ctx)
|
||||
return router.push({name: ctx.routeName, params: ctx.params})
|
||||
.then(err => {
|
||||
|
|
@ -145,6 +147,62 @@ function open(option: string | Option) {
|
|||
.catch(err => {
|
||||
return Promise.reject(err)
|
||||
})
|
||||
} */
|
||||
|
||||
function checkRoute(option: string | Option) {
|
||||
let opt: Option
|
||||
if (typeof option === 'string') {
|
||||
opt = {
|
||||
routeName: option,
|
||||
}
|
||||
} else {
|
||||
opt = option
|
||||
}
|
||||
const appSettingStore = useAppSettingStore()
|
||||
const menu = appSettingStore.menus.find(it => it.routeName === opt.routeName)
|
||||
|
||||
if (menu == null
|
||||
|| !router.hasRoute(opt.routeName)) {
|
||||
return reloadUserInfo()
|
||||
.then(reloadRouter)
|
||||
.then(() => {
|
||||
const menu_ = appSettingStore.menus.find(it => it.routeName === opt.routeName)
|
||||
if (menu_ == null || !router.hasRoute(opt.routeName)) {
|
||||
ElMessage.error('页面不存在')
|
||||
return Promise.reject('页面不存在')
|
||||
} else {
|
||||
return {option: opt, menu: menu_}
|
||||
}
|
||||
})
|
||||
}
|
||||
return Promise.resolve({option: opt, menu})
|
||||
}
|
||||
|
||||
function jump(ctx: AppTypes.PageContext) {
|
||||
return router.push({name: ctx.routeName, params: ctx.params})
|
||||
.then(err => {
|
||||
if (err == null) {
|
||||
return Promise.resolve(ctx)
|
||||
}
|
||||
return Promise.reject(err)
|
||||
})
|
||||
}
|
||||
|
||||
function open(option: string | Option) {
|
||||
return checkRoute(option)
|
||||
.then(({option, menu}) => {
|
||||
return jump({
|
||||
insId: option.insId ?? option.routeName,
|
||||
title: option.title ?? menu.title,
|
||||
keepAlive: true,
|
||||
params: option.params ?? {},
|
||||
routeName: option.routeName,
|
||||
menuId: menu.id,
|
||||
icon: menu.icon,
|
||||
breadcrumb: menu.breadcrumb,
|
||||
})
|
||||
})
|
||||
.then(useAppPageStore().open)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -153,13 +211,86 @@ function open(option: string | Option) {
|
|||
* @param id
|
||||
*/
|
||||
function close(id: string) {
|
||||
useAppPageStore().close(id)
|
||||
Evt.emit('closePage', id)
|
||||
useAppPageStore()
|
||||
.closePage(id)
|
||||
.then(ctx => {
|
||||
if (ctx == null) return Promise.resolve(null)
|
||||
return jump(ctx)
|
||||
})
|
||||
}
|
||||
|
||||
function closeCurrent() {
|
||||
return useAppPageStore().closeCurrent()
|
||||
.then(ctx => {
|
||||
if (ctx == null) return Promise.resolve(null)
|
||||
return jump(ctx)
|
||||
})
|
||||
}
|
||||
|
||||
function closeLeft() {
|
||||
useAppPageStore().closeLeft()
|
||||
}
|
||||
|
||||
function closeRight() {
|
||||
useAppPageStore().closeRight()
|
||||
}
|
||||
|
||||
function closeOther() {
|
||||
useAppPageStore().closeOther()
|
||||
}
|
||||
|
||||
function closeAll() {
|
||||
return useAppPageStore().closeAll()
|
||||
.then(jump)
|
||||
}
|
||||
|
||||
const install = (_: App): void => {
|
||||
Evt.on('login', (_) => {
|
||||
open(SpecialPage.Home)
|
||||
})
|
||||
|
||||
Evt.on('browserReflash', (routeName: string) => {
|
||||
if (routeName === SpecialPage.Home) {
|
||||
open(routeName)
|
||||
return
|
||||
}
|
||||
checkRoute(SpecialPage.Home)
|
||||
.then(({option, menu}) => {
|
||||
useAppPageStore().open({
|
||||
insId: option.insId ?? option.routeName,
|
||||
title: option.title ?? menu.title,
|
||||
keepAlive: true,
|
||||
params: option.params ?? {},
|
||||
routeName: option.routeName,
|
||||
menuId: menu.id,
|
||||
icon: menu.icon,
|
||||
breadcrumb: menu.breadcrumb,
|
||||
})
|
||||
open(routeName)
|
||||
})
|
||||
})
|
||||
|
||||
Evt.on('logout', (_) => {
|
||||
const routes = router
|
||||
.getRoutes()
|
||||
.filter((it) => it.name !== SpecialPage.Main && it.name !== SpecialPage.Login && it.name !== SpecialPage.NotFound && it.name !== SpecialPage.Home)
|
||||
.map((it) => it.name as string)
|
||||
removeRoutes(routes)
|
||||
router.push({replace: true, name: SpecialPage.Login}).then(() => {
|
||||
// console.log(r)
|
||||
})
|
||||
})
|
||||
|
||||
}
|
||||
export default {
|
||||
open,
|
||||
close,
|
||||
closeCurrent,
|
||||
closeLeft,
|
||||
closeRight,
|
||||
closeOther,
|
||||
closeAll,
|
||||
install,
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import mitt, { type EventType } from 'mitt'
|
|||
export interface EventList extends Record<EventType, unknown> {
|
||||
login?: string
|
||||
logout?: string
|
||||
browserReflash: string
|
||||
connect_ws?: string
|
||||
disconnect_ws?: string
|
||||
openPage?: string
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
@font-face {
|
||||
font-family: "iconfont"; /* 项目名称 再昇云 */
|
||||
src: url('@/components/a-icon/iconfont.woff2?t=1768370216119') format('woff2'),
|
||||
url('@/components/a-icon/iconfont.woff?t=1768370216119') format('woff'),
|
||||
url('@/components/a-icon/iconfont.ttf?t=1768370216119') format('truetype');
|
||||
src: url('@/components/a-icon/iconfont.woff2?t=1768642091253') format('woff2'),
|
||||
url('@/components/a-icon/iconfont.woff?t=1768642091253') format('woff'),
|
||||
url('@/components/a-icon/iconfont.ttf?t=1768642091253') format('truetype');
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
|
|
@ -13,6 +13,10 @@
|
|||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.icon-home-3-line:before {
|
||||
content: "\e6b3";
|
||||
}
|
||||
|
||||
.icon-bell:before {
|
||||
content: "\e7c4";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,13 @@
|
|||
"css_prefix_text": "icon-",
|
||||
"description": "",
|
||||
"glyphs": [
|
||||
{
|
||||
"icon_id": "17102563",
|
||||
"name": "home-3-line",
|
||||
"font_class": "home-3-line",
|
||||
"unicode": "e6b3",
|
||||
"unicode_decimal": 59059
|
||||
},
|
||||
{
|
||||
"icon_id": "4766680",
|
||||
"name": "bell",
|
||||
|
|
|
|||
|
|
@ -5,6 +5,13 @@ export const icons = {
|
|||
'css_prefix_text': 'icon-',
|
||||
'description': '',
|
||||
'glyphs': [
|
||||
{
|
||||
'icon_id': '17102563',
|
||||
'name': 'home-3-line',
|
||||
'font_class': 'home-3-line',
|
||||
'unicode': 'e6b3',
|
||||
'unicode_decimal': 59059,
|
||||
},
|
||||
{
|
||||
'icon_id': '4766680',
|
||||
'name': 'bell',
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -225,10 +225,11 @@ onMounted(doSearch)
|
|||
</ElTooltip>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ElTable
|
||||
v-loading="loading"
|
||||
:data="tableData"
|
||||
:empty-text="tableProps.emptyText?? '暂无数据'"
|
||||
:row-key="tableProps.rowKey?? 'id'"
|
||||
ref="dataTable"
|
||||
:lazy="tableProps.treeLoad ==null?undefined:true"
|
||||
:load="tableProps.treeLoad?((row, expanded, resolve)=>tableProps.treeLoad!(searchForm as F, row, expanded, resolve)):undefined"
|
||||
|
|
@ -543,8 +544,6 @@ onMounted(doSearch)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.pagination {
|
||||
justify-content center
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
|
|||
// import Ws from '@/common/ws/ws.ts'
|
||||
import element from '@/common/element/element.ts'
|
||||
import router from '@/common/router'
|
||||
import Nav from '@/common/router/nav.ts'
|
||||
|
||||
createApp(App)
|
||||
.use(element)
|
||||
|
|
@ -19,4 +20,5 @@ createApp(App)
|
|||
})
|
||||
.use(createPinia().use(piniaPluginPersistedstate))
|
||||
.use(router)
|
||||
.use(Nav)
|
||||
.mount('#app')
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import {
|
|||
ElMenuItemGroup,
|
||||
ElScrollbar,
|
||||
ElSubMenu,
|
||||
type MenuInstance,
|
||||
type MenuItemRegistered,
|
||||
} from 'element-plus'
|
||||
import AIcon from '@/components/a-icon/AIcon.vue'
|
||||
|
|
@ -12,10 +13,10 @@ import styles from '@/pages/a-frame/aaside.module.styl'
|
|||
import { useAppSettingStore } from '@/common/app/app-setting-store.ts'
|
||||
import Colls from '@/common/utils/colls.ts'
|
||||
import { MenuCategory } from '@/common/app/constants.ts'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { computed } from 'vue'
|
||||
import Nav from '@/common/router/nav.ts'
|
||||
import logo from '@/assets/images/zsy.png'
|
||||
import { useAppPageStore } from '@/common/app/app-page-store.ts'
|
||||
|
||||
export interface Menu extends G.TreeNode {
|
||||
// Id
|
||||
|
|
@ -44,13 +45,15 @@ export interface Menu extends G.TreeNode {
|
|||
|
||||
export default defineComponent(
|
||||
(props) => {
|
||||
const router = useRouter()
|
||||
const appSettingStore = useAppSettingStore()
|
||||
const defaultActive = ref<any>('')
|
||||
const menuIns = useTemplateRef<MenuInstance>('menu')
|
||||
|
||||
onMounted(() => {
|
||||
const currentRouteName = router.currentRoute.value.name
|
||||
defaultActive.value = appSettingStore.menus.find(it => it.routeName === currentRouteName)?.id
|
||||
const appPageStore = useAppPageStore()
|
||||
|
||||
watch(
|
||||
() => appPageStore.currentPage.menuId,
|
||||
() => {
|
||||
menuIns.value?.updateActiveIndex(appPageStore.currentPage.menuId)
|
||||
})
|
||||
|
||||
const menuTree = computed(() => {
|
||||
|
|
@ -59,10 +62,7 @@ export default defineComponent(
|
|||
|
||||
const onMenuClick = (menuItem: MenuItemRegistered) => {
|
||||
const menu = appSettingStore.menus.find(it => it.id === menuItem.index)
|
||||
Nav.open({
|
||||
insId: menu?.routeName ?? '',
|
||||
routeName: menu?.routeName ?? '',
|
||||
})
|
||||
Nav.open(menu?.routeName ?? '')
|
||||
}
|
||||
const renderMenu = (it: Menu) => {
|
||||
let renderChildNode: (() => VNode[] | undefined) | undefined = undefined
|
||||
|
|
@ -116,12 +116,13 @@ export default defineComponent(
|
|||
|
||||
return () => (
|
||||
<>
|
||||
<div class={[ styles.aAsideTop, {[styles.aAsideTopCollapse]: props.isCollapse} ]}>
|
||||
<div class={[ styles.aAsideTop, {[styles.aAsideTopCollapse]: props.isCollapse} ]}
|
||||
onClick={() => Nav.open('home')}>
|
||||
<img alt="" src={logo}/>
|
||||
<div>再昇云</div>
|
||||
</div>
|
||||
<ElScrollbar class={styles.aScrollbar}>
|
||||
<ElMenu default-active={defaultActive.value} collapse={props.isCollapse} class={[ styles.aMenus ]}>
|
||||
<ElMenu collapse={props.isCollapse} class={[ styles.aMenus ]} ref="menu">
|
||||
{{
|
||||
default: () => menuTree.value.map(renderMenu),
|
||||
}}
|
||||
|
|
|
|||
|
|
@ -8,14 +8,15 @@
|
|||
<div v-for="(item,i) in appPageStore.pages"
|
||||
:id="item.insId"
|
||||
:key="'a-frame-header-tab'+i"
|
||||
:class="{'a-tab-item-active': item.insId === appPageStore.currentPage}"
|
||||
:class="{'a-tab-item-active': item.insId === appPageStore.currentPage.insId}"
|
||||
class="a-tab-item"
|
||||
@click="reopen(item.insId)">
|
||||
@click="Nav.open(item.routeName)">
|
||||
<div>
|
||||
<AIcon :name="item.icon as IconName"/>
|
||||
<div class="title">{{ item.title }}</div>
|
||||
</div>
|
||||
<ElButton :icon="elIcons.Close" text @click.stop="appPageStore.closePage(item.insId)"/>
|
||||
<div v-if="item.routeName === SpecialPage.Home"></div>
|
||||
<ElButton v-else :icon="elIcons.Close" text @click.stop="Nav.close(item.insId)"/>
|
||||
</div>
|
||||
</div>
|
||||
</ElScrollbar>
|
||||
|
|
@ -23,9 +24,10 @@
|
|||
<ElButton :icon="elIcons.More" text/>
|
||||
<template #dropdown>
|
||||
<ElDropdownMenu>
|
||||
<ElDropdownItem command="closeCurrent">关闭当前</ElDropdownItem>
|
||||
<ElDropdownItem command="closeOther">关闭其他</ElDropdownItem>
|
||||
<ElDropdownItem command="closeAll">关闭所有</ElDropdownItem>
|
||||
<ElDropdownItem :icon="elIcons.ArrowLeft" command="closeLeft">关闭左侧</ElDropdownItem>
|
||||
<ElDropdownItem :icon="elIcons.ArrowRight" command="closeRight">关闭右侧</ElDropdownItem>
|
||||
<ElDropdownItem :icon="elIcons.Close" command="closeOther">关闭其他</ElDropdownItem>
|
||||
<ElDropdownItem :icon="elIcons.CircleClose" command="closeAll">关闭所有</ElDropdownItem>
|
||||
</ElDropdownMenu>
|
||||
</template>
|
||||
</ElDropdown>
|
||||
|
|
@ -37,15 +39,17 @@ import { elIcons } from '@/common/element/element.ts'
|
|||
import type { IconName } from '@/components/a-icon/iconfont.ts'
|
||||
import AIcon from '@/components/a-icon/AIcon.vue'
|
||||
import type { ScrollbarInstance } from 'element-plus'
|
||||
import Nav from '@/common/router/nav.ts'
|
||||
import { SpecialPage } from '@/common/router/constants.ts'
|
||||
|
||||
const appPageStore = useAppPageStore()
|
||||
const tabsScrollbarIns = useTemplateRef<ScrollbarInstance>('tabsScrollbar')
|
||||
|
||||
watch(
|
||||
() => appPageStore.currentPage,
|
||||
() => appPageStore.currentPage.insId,
|
||||
() => {
|
||||
nextTick(() => {
|
||||
const tabItem = document.getElementById(appPageStore.currentPage)
|
||||
const tabItem = document.getElementById(appPageStore.currentPage.insId)
|
||||
if (tabItem != null) tabsScrollbarIns.value?.setScrollLeft(tabItem.offsetLeft)
|
||||
})
|
||||
})
|
||||
|
|
@ -55,7 +59,7 @@ function reopen(insId: string) {
|
|||
}
|
||||
|
||||
function handleCommand(command: 'closeCurrent' | 'closeOther' | 'closeAll') {
|
||||
appPageStore[command]()
|
||||
Nav[command]()
|
||||
}
|
||||
</script>
|
||||
<style lang="stylus" scoped>
|
||||
|
|
|
|||
|
|
@ -4,24 +4,20 @@
|
|||
display: flex;
|
||||
align-items: center;
|
||||
box-sizing border-box
|
||||
//padding 8px 8px 8px 18px;
|
||||
padding-left 18px
|
||||
//border-bottom: solid 1px var(--el-menu-border-color);
|
||||
transition all 0.333s ease-in-out
|
||||
gap 12px
|
||||
overflow hidden
|
||||
max-width 230px
|
||||
//justify-content center
|
||||
cursor pointer
|
||||
|
||||
& > img {
|
||||
height 32px
|
||||
width 32px
|
||||
//margin-left 18px
|
||||
//transition margin-left 0.333s ease-in-out
|
||||
}
|
||||
|
||||
& > div {
|
||||
color: #252f4a;
|
||||
color: #252F4A;
|
||||
font-weight: 700;
|
||||
font-size: 1.5rem;
|
||||
opacity 1
|
||||
|
|
@ -62,19 +58,20 @@
|
|||
&:global(.el-menu--collapse) {
|
||||
width: 60px;
|
||||
}
|
||||
}
|
||||
|
||||
:global(.el-menu-item):global(.is-active) {
|
||||
background-color #e8f4ff
|
||||
:global(.el-menu-item):global(.is-active) {
|
||||
background-color #E8F4FF !important
|
||||
|
||||
&::after {
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
:global(.el-menu-item) {
|
||||
position relative
|
||||
transition: background-color, color .3s ease-in-out;
|
||||
border-radius 4px
|
||||
:global(.el-menu-item) {
|
||||
position relative !important
|
||||
transition: background-color, color .3s ease-in-out !important;
|
||||
border-radius 4px !important
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
|
|
@ -83,22 +80,21 @@
|
|||
right: 0;
|
||||
width: 4px;
|
||||
height: 0;
|
||||
background-color: #1c6eff;
|
||||
background-color: #1C6EFF;
|
||||
transition height 0.3s ease-in-out
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
:global(.el-sub-menu__title),
|
||||
:global(.el-menu-item) {
|
||||
:global(.el-sub-menu__title),
|
||||
:global(.el-menu-item) {
|
||||
height: 42px !important;
|
||||
line-height: 42px !important;
|
||||
margin-left: 8px;
|
||||
margin-right: 8px;
|
||||
margin-left: 8px !important;
|
||||
margin-right: 8px !important;
|
||||
|
||||
&:hover {
|
||||
background-color: #F2F4F5 !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.a-icon {
|
||||
|
|
|
|||
|
|
@ -1,12 +0,0 @@
|
|||
# EditorConfig is awesome: https://EditorConfig.org
|
||||
|
||||
# top-most EditorConfig file
|
||||
root = true
|
||||
|
||||
[*]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
end_of_line = crlf
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = false
|
||||
insert_final_newline = false
|
||||
|
|
@ -17,15 +17,15 @@
|
|||
<ElInput v-model="searchForm.routeName" placeholder="路由名称"/>
|
||||
</ElFormItem>
|
||||
</template>
|
||||
<template #simpleSearchFormItem="{ searchForm }">
|
||||
<ElFormItem>
|
||||
<ElInput v-model="searchForm.title" placeholder="菜单名称"/>
|
||||
</ElFormItem>
|
||||
<ElFormItem>
|
||||
<ElInput v-model="searchForm.routeName" placeholder="路由名称"/>
|
||||
</ElFormItem>
|
||||
</template>
|
||||
<template #columns>
|
||||
|
||||
<!--
|
||||
:data="tableData"
|
||||
lazy
|
||||
:load="treeLoad"
|
||||
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
|
||||
@expand-change="treeLoad"
|
||||
-->
|
||||
<ElTableColumn label="图标" prop="icon" width="100">
|
||||
<template #default="scope">
|
||||
<AIcon :name="scope.row.icon"/>
|
||||
|
|
@ -61,7 +61,6 @@ import MenuApi from '@/pages/sys/menus/menu-api.ts'
|
|||
import MenuForm from '@/pages/sys/menus/MenuForm.vue'
|
||||
import Strings from '@/common/utils/strings.ts'
|
||||
import AIcon from '@/components/a-icon/AIcon.vue'
|
||||
import type { TableInstance } from 'element-plus'
|
||||
import FormPage, {
|
||||
type ActionColumnType,
|
||||
type ToolType,
|
||||
|
|
@ -69,7 +68,6 @@ import FormPage, {
|
|||
import type { ComponentExposed } from 'vue-component-type-helpers'
|
||||
|
||||
const menuFormIns = useTemplateRef<InstanceType<typeof MenuForm>>('menuForm')
|
||||
const dataTableIns = useTemplateRef<TableInstance>('dataTable')
|
||||
const formPageIns = useTemplateRef<ComponentExposed<typeof FormPage>>('formPage')
|
||||
|
||||
const actionColumn = reactive<ActionColumnType<MenuTypes.SysMenu>>({
|
||||
|
|
@ -126,7 +124,7 @@ function listAll(param: MenuTypes.SearchForm) {
|
|||
|
||||
}
|
||||
|
||||
function treeLoad(param: MenuTypes.SearchForm, row: MenuTypes.SysMenu, expanded: any, resolve: (data: MenuTypes.SysMenu[]) => void) {
|
||||
function treeLoad(param: MenuTypes.SearchForm, row: MenuTypes.SysMenu, expanded: any, resolve?: (data: MenuTypes.SysMenu[]) => void) {
|
||||
if (resolve == null && !expanded) return
|
||||
MenuApi.listAll({...param, pid: row.id})
|
||||
.then(res => {
|
||||
|
|
|
|||
Loading…
Reference in New Issue