mirror of
https://github.com/XiaoDaiGua-Ray/ray-template.git
synced 2025-04-06 03:57:49 +08:00
v4.2.7
This commit is contained in:
parent
b05edfeaeb
commit
f6c343911e
14
CHANGELOG.md
14
CHANGELOG.md
@ -1,5 +1,19 @@
|
|||||||
# CHANGE LOG
|
# CHANGE LOG
|
||||||
|
|
||||||
|
## 4.2.7
|
||||||
|
|
||||||
|
主要是做了一些统一命名的事情,以前由于写的比较放浪形骸现在正在慢慢更改这个大问题。
|
||||||
|
|
||||||
|
### Feats
|
||||||
|
|
||||||
|
- 优化顶部操作栏的渲染逻辑,现在将更加合理的管理数据渲染图标
|
||||||
|
- 二次封装 useFullscreen 方法,如果当前环境不支持全屏则会自动弹出提示
|
||||||
|
- 重命名 utils/hook 包名为 basic
|
||||||
|
- 移除 vuedraggable 插件
|
||||||
|
- RequestCanceler 方法部分属性与方法变为私有
|
||||||
|
- 重命名 layout 包下的一些组件 name
|
||||||
|
- 升级 echarts 至 5.4.3 版本
|
||||||
|
|
||||||
## 4.2.6
|
## 4.2.6
|
||||||
|
|
||||||
### Feats
|
### Feats
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "ray-template",
|
"name": "ray-template",
|
||||||
"private": false,
|
"private": false,
|
||||||
"version": "4.2.6",
|
"version": "4.2.7",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=16.0.0",
|
"node": ">=16.0.0",
|
||||||
@ -31,7 +31,7 @@
|
|||||||
"crypto-js": "^4.1.1",
|
"crypto-js": "^4.1.1",
|
||||||
"currency.js": "^2.0.4",
|
"currency.js": "^2.0.4",
|
||||||
"dayjs": "^1.11.7",
|
"dayjs": "^1.11.7",
|
||||||
"echarts": "^5.4.0",
|
"echarts": "^5.4.3",
|
||||||
"lodash-es": "^4.17.21",
|
"lodash-es": "^4.17.21",
|
||||||
"mockjs": "1.1.0",
|
"mockjs": "1.1.0",
|
||||||
"naive-ui": "^2.35.0",
|
"naive-ui": "^2.35.0",
|
||||||
@ -42,7 +42,6 @@
|
|||||||
"vue-hooks-plus": "1.8.5",
|
"vue-hooks-plus": "1.8.5",
|
||||||
"vue-i18n": "^9.2.2",
|
"vue-i18n": "^9.2.2",
|
||||||
"vue-router": "^4.2.4",
|
"vue-router": "^4.2.4",
|
||||||
"vuedraggable": "^4.1.0",
|
|
||||||
"xlsx": "^0.18.5"
|
"xlsx": "^0.18.5"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
@ -19,14 +19,14 @@
|
|||||||
import type { AppRawRequestConfig } from '@/axios/type'
|
import type { AppRawRequestConfig } from '@/axios/type'
|
||||||
|
|
||||||
export default class RequestCanceler {
|
export default class RequestCanceler {
|
||||||
pendingRequest: Map<string, AbortController>
|
private pendingRequest: Map<string, AbortController>
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.pendingRequest = new Map<string, AbortController>()
|
this.pendingRequest = new Map<string, AbortController>()
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 是否需要加入取消请求表中 */
|
/** 是否需要加入取消请求表中 */
|
||||||
isApending(config: AppRawRequestConfig) {
|
private isApending(config: AppRawRequestConfig) {
|
||||||
return config.cancelConfig?.needCancel ?? true
|
return config.cancelConfig?.needCancel ?? true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -37,7 +37,7 @@ export default class RequestCanceler {
|
|||||||
*
|
*
|
||||||
* @remark 将当前请求 config 生成 request key
|
* @remark 将当前请求 config 生成 request key
|
||||||
*/
|
*/
|
||||||
generateRequestKey(config: AppRawRequestConfig) {
|
private generateRequestKey(config: AppRawRequestConfig) {
|
||||||
const { method, url } = config
|
const { method, url } = config
|
||||||
|
|
||||||
return [
|
return [
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import RequestCanceler from '@/axios/helper/RequestCanceler'
|
import RequestCanceler from '@/axios/helper/RequestCanceler'
|
||||||
import { getAppEnvironment } from '@use-utils/hook'
|
import { getAppEnvironment } from '@/utils/basic'
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
RequestInterceptorConfig,
|
RequestInterceptorConfig,
|
||||||
|
@ -16,7 +16,7 @@ import RIcon from '@/components/RIcon/index'
|
|||||||
|
|
||||||
import props from './props'
|
import props from './props'
|
||||||
import { AwesomeQR } from 'awesome-qr'
|
import { AwesomeQR } from 'awesome-qr'
|
||||||
import { isValueType, downloadAnyFile } from '@use-utils/hook'
|
import { isValueType, downloadAnyFile } from '@/utils/basic'
|
||||||
import { call } from '@/utils/vue/index'
|
import { call } from '@/utils/vue/index'
|
||||||
|
|
||||||
import type { QRCodeRenderResponse, GIFBuffer } from './type'
|
import type { QRCodeRenderResponse, GIFBuffer } from './type'
|
||||||
|
@ -19,7 +19,7 @@ import Print from './components/Print'
|
|||||||
|
|
||||||
import props from './props'
|
import props from './props'
|
||||||
import { call } from '@/utils/vue/index'
|
import { call } from '@/utils/vue/index'
|
||||||
import { uuid } from '@use-utils/hook'
|
import { uuid } from '@/utils/basic'
|
||||||
import config from './config'
|
import config from './config'
|
||||||
|
|
||||||
import type { DropdownOption, DataTableInst } from 'naive-ui'
|
import type { DropdownOption, DataTableInst } from 'naive-ui'
|
||||||
|
@ -13,7 +13,7 @@ import { NPopover } from 'naive-ui'
|
|||||||
import RIcon from '@/components/RIcon/index'
|
import RIcon from '@/components/RIcon/index'
|
||||||
|
|
||||||
import config from '../config'
|
import config from '../config'
|
||||||
import { useFullscreen } from 'vue-hooks-plus'
|
import { useFullscreen } from '@/hooks/web/index'
|
||||||
|
|
||||||
import type { TableProvider } from '../type'
|
import type { TableProvider } from '../type'
|
||||||
|
|
||||||
|
@ -13,5 +13,6 @@ import { useI18n, t } from './useI18n'
|
|||||||
import { useVueRouter } from '../web/useVueRouter'
|
import { useVueRouter } from '../web/useVueRouter'
|
||||||
import { useDayjs } from '../web/useDayjs'
|
import { useDayjs } from '../web/useDayjs'
|
||||||
import { useDevice } from './useDevice'
|
import { useDevice } from './useDevice'
|
||||||
|
import { useFullscreen } from './useFullscreen'
|
||||||
|
|
||||||
export { useI18n, useVueRouter, useDayjs, t, useDevice }
|
export { useI18n, useVueRouter, useDayjs, t, useDevice, useFullscreen }
|
||||||
|
40
src/hooks/web/useFullscreen.ts
Normal file
40
src/hooks/web/useFullscreen.ts
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Ray <https://github.com/XiaoDaiGua-Ray>
|
||||||
|
*
|
||||||
|
* @date 2023-10-25
|
||||||
|
*
|
||||||
|
* @workspace ray-template
|
||||||
|
*
|
||||||
|
* @remark 今天也是元气满满撸代码的一天
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { useFullscreen as hooksPlusUseFullscreen } from 'vue-hooks-plus'
|
||||||
|
|
||||||
|
import type { useFullscreen as UseFullscreen } from 'vue-hooks-plus'
|
||||||
|
|
||||||
|
type UseFullscreenParams = Parameters<typeof UseFullscreen>
|
||||||
|
|
||||||
|
export function useFullscreen(
|
||||||
|
target: UseFullscreenParams[0],
|
||||||
|
options?: UseFullscreenParams[1],
|
||||||
|
) {
|
||||||
|
const [
|
||||||
|
isFullscreen,
|
||||||
|
{ enterFullscreen, exitFullscreen, toggleFullscreen, isEnabled },
|
||||||
|
] = hooksPlusUseFullscreen(target, options)
|
||||||
|
|
||||||
|
if (!isEnabled) {
|
||||||
|
window.$message.warning('您当前环境不支持全屏模式')
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
isFullscreen,
|
||||||
|
{
|
||||||
|
enterFullscreen,
|
||||||
|
exitFullscreen,
|
||||||
|
toggleFullscreen,
|
||||||
|
isEnabled,
|
||||||
|
},
|
||||||
|
] as const
|
||||||
|
}
|
@ -23,8 +23,8 @@ import type { MenuInst } from 'naive-ui'
|
|||||||
import type { NaiveMenuOptions } from '@/types/modules/component'
|
import type { NaiveMenuOptions } from '@/types/modules/component'
|
||||||
import type { AppMenuOption } from '@/types/modules/app'
|
import type { AppMenuOption } from '@/types/modules/app'
|
||||||
|
|
||||||
const LayoutMenu = defineComponent({
|
export default defineComponent({
|
||||||
name: 'LayoutMenu',
|
name: 'AppMenu',
|
||||||
setup() {
|
setup() {
|
||||||
const menuRef = ref<MenuInst | null>(null)
|
const menuRef = ref<MenuInst | null>(null)
|
||||||
|
|
||||||
@ -114,5 +114,3 @@ const LayoutMenu = defineComponent({
|
|||||||
)
|
)
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
export default LayoutMenu
|
|
||||||
|
@ -30,7 +30,7 @@ import RIcon from '@/components/RIcon/index'
|
|||||||
import RMoreDropdown from '@/components/RMoreDropdown/index'
|
import RMoreDropdown from '@/components/RMoreDropdown/index'
|
||||||
|
|
||||||
import { useMenu, useSetting } from '@/store'
|
import { useMenu, useSetting } from '@/store'
|
||||||
import { uuid } from '@/utils/hook'
|
import { uuid } from '@/utils/basic'
|
||||||
import { hasClass } from '@/utils/element'
|
import { hasClass } from '@/utils/element'
|
||||||
import { redirectRouterToDashboard } from '@/router/helper/routerCopilot'
|
import { redirectRouterToDashboard } from '@/router/helper/routerCopilot'
|
||||||
import { ROOT_ROUTE } from '@/app-config/appConfig'
|
import { ROOT_ROUTE } from '@/app-config/appConfig'
|
||||||
@ -40,7 +40,7 @@ import type { MenuOption, ScrollbarInst } from 'naive-ui'
|
|||||||
import type { MenuTagOptions, AppMenuOption } from '@/types/modules/app'
|
import type { MenuTagOptions, AppMenuOption } from '@/types/modules/app'
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'MenuTag',
|
name: 'AppMenuTag',
|
||||||
setup(_, { expose }) {
|
setup(_, { expose }) {
|
||||||
const scrollRef = ref<ScrollbarInst | null>(null)
|
const scrollRef = ref<ScrollbarInst | null>(null)
|
||||||
|
|
||||||
@ -269,7 +269,7 @@ export default defineComponent({
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleScrollX = (type: 'left' | 'right') => {
|
const scrollX = (type: 'left' | 'right') => {
|
||||||
const el = getScrollElement()
|
const el = getScrollElement()
|
||||||
|
|
||||||
if (el) {
|
if (el) {
|
||||||
@ -438,7 +438,7 @@ export default defineComponent({
|
|||||||
menuKey,
|
menuKey,
|
||||||
handleTagClick,
|
handleTagClick,
|
||||||
moreOptions,
|
moreOptions,
|
||||||
handleScrollX,
|
scrollX,
|
||||||
scrollRef,
|
scrollRef,
|
||||||
scrollBarUUID,
|
scrollBarUUID,
|
||||||
actionDropdownSelect,
|
actionDropdownSelect,
|
||||||
@ -480,7 +480,7 @@ export default defineComponent({
|
|||||||
width="20"
|
width="20"
|
||||||
height="28"
|
height="28"
|
||||||
customClassName="menu-tag__left-arrow"
|
customClassName="menu-tag__left-arrow"
|
||||||
onClick={this.handleScrollX.bind(this, 'left')}
|
onClick={this.scrollX.bind(this, 'left')}
|
||||||
/>
|
/>
|
||||||
<NScrollbar
|
<NScrollbar
|
||||||
xScrollable
|
xScrollable
|
||||||
@ -524,7 +524,7 @@ export default defineComponent({
|
|||||||
width="20"
|
width="20"
|
||||||
height="28"
|
height="28"
|
||||||
customClassName="menu-tag__right-arrow"
|
customClassName="menu-tag__right-arrow"
|
||||||
onClick={this.handleScrollX.bind(this, 'right')}
|
onClick={this.scrollX.bind(this, 'right')}
|
||||||
/>
|
/>
|
||||||
<RMoreDropdown
|
<RMoreDropdown
|
||||||
options={this.moreOptions}
|
options={this.moreOptions}
|
||||||
|
@ -16,7 +16,7 @@ import RIcon from '@/components/RIcon/index'
|
|||||||
|
|
||||||
import { tooltipProps } from 'naive-ui'
|
import { tooltipProps } from 'naive-ui'
|
||||||
|
|
||||||
const TooltipIcon = defineComponent({
|
export default defineComponent({
|
||||||
name: 'TooltipIcon',
|
name: 'TooltipIcon',
|
||||||
props: {
|
props: {
|
||||||
...tooltipProps,
|
...tooltipProps,
|
||||||
@ -34,32 +34,38 @@ const TooltipIcon = defineComponent({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
emits: ['click'],
|
emits: ['click'],
|
||||||
setup(_, { emit }) {
|
setup(props, { emit }) {
|
||||||
const handleClick = (e?: MouseEvent) => {
|
const iconClick = (e?: MouseEvent) => {
|
||||||
emit('click', e)
|
emit('click', e)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Icon = () => (
|
||||||
|
<RIcon
|
||||||
|
name={props.iconName}
|
||||||
|
size="18"
|
||||||
|
customClassName={`tooltip-text__icon ${props.customClassName}`}
|
||||||
|
cursor="pointer"
|
||||||
|
onClick={iconClick.bind(this)}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
handleClick,
|
iconClick,
|
||||||
|
Icon,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
render() {
|
render() {
|
||||||
return (
|
const { Icon } = this
|
||||||
|
|
||||||
|
return this.tooltipText ? (
|
||||||
<NTooltip {...this.$props}>
|
<NTooltip {...this.$props}>
|
||||||
{{
|
{{
|
||||||
trigger: () => (
|
trigger: () => <Icon />,
|
||||||
<RIcon
|
|
||||||
name={this.iconName}
|
|
||||||
size="18"
|
|
||||||
customClassName={`tooltip-text__icon ${this.customClassName}`}
|
|
||||||
cursor="pointer"
|
|
||||||
onClick={this.handleClick.bind(this)}
|
|
||||||
/>
|
|
||||||
),
|
|
||||||
default: () => this.tooltipText,
|
default: () => this.tooltipText,
|
||||||
}}
|
}}
|
||||||
</NTooltip>
|
</NTooltip>
|
||||||
|
) : (
|
||||||
|
<Icon />
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
export default TooltipIcon
|
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
import { useSetting, useSignin } from '@/store'
|
import { useSetting, useSignin } from '@/store'
|
||||||
|
import { useI18n } from '@/hooks/web/index'
|
||||||
|
|
||||||
export const useAvatarOptions = () => [
|
import type { IconOptionsFC, IconOptions } from './type'
|
||||||
|
|
||||||
|
export const createAvatarOptions = () => [
|
||||||
{
|
{
|
||||||
key: 'person',
|
key: 'person',
|
||||||
label: '个人信息',
|
label: '个人信息',
|
||||||
@ -47,3 +50,71 @@ export const avatarDropdownClick = (key: string | number) => {
|
|||||||
|
|
||||||
action ? action() : window.$message.info('这个人很懒, 没做这个功能~')
|
action ? action() : window.$message.info('这个人很懒, 没做这个功能~')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const createLeftIconOptions = (opts: IconOptionsFC) => {
|
||||||
|
const { isTabletOrSmaller, reloadRouteSwitch } = opts
|
||||||
|
const { t } = useI18n()
|
||||||
|
|
||||||
|
const notTableOrSmallerOptions: IconOptions[] = [
|
||||||
|
{
|
||||||
|
name: 'reload',
|
||||||
|
size: 18,
|
||||||
|
tooltip: t('headerTooltip.Reload'),
|
||||||
|
iconClass: !reloadRouteSwitch.value ? 'ray-icon__reload--loading' : '',
|
||||||
|
eventKey: 'reload',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
const tableOrSmallerOptions: IconOptions[] = [
|
||||||
|
{
|
||||||
|
name: 'menu',
|
||||||
|
size: 18,
|
||||||
|
eventKey: 'menu',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
return isTabletOrSmaller!.value
|
||||||
|
? tableOrSmallerOptions
|
||||||
|
: notTableOrSmallerOptions
|
||||||
|
}
|
||||||
|
|
||||||
|
export const createRightIconOptions = (opts: IconOptionsFC) => {
|
||||||
|
const { isFullscreen, isTabletOrSmaller } = opts
|
||||||
|
const { t } = useI18n()
|
||||||
|
|
||||||
|
const basicOptions: IconOptions[] = [
|
||||||
|
{
|
||||||
|
name: 'fullscreen',
|
||||||
|
size: 18,
|
||||||
|
tooltip: isFullscreen.value
|
||||||
|
? t('headerTooltip.CancelFullScreen')
|
||||||
|
: t('headerTooltip.FullScreen'),
|
||||||
|
eventKey: 'screen',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'github',
|
||||||
|
size: 18,
|
||||||
|
tooltip: t('headerTooltip.Github'),
|
||||||
|
eventKey: 'github',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'setting',
|
||||||
|
size: 18,
|
||||||
|
tooltip: t('headerTooltip.Setting'),
|
||||||
|
eventKey: 'setting',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
const notTableOrSmallerOptions: IconOptions[] = [
|
||||||
|
{
|
||||||
|
name: 'search',
|
||||||
|
size: 18,
|
||||||
|
tooltip: t('headerTooltip.Search'),
|
||||||
|
eventKey: 'search',
|
||||||
|
},
|
||||||
|
...basicOptions,
|
||||||
|
]
|
||||||
|
const tableOrSmallerOptions: IconOptions[] = [...basicOptions]
|
||||||
|
|
||||||
|
return isTabletOrSmaller!.value
|
||||||
|
? tableOrSmallerOptions
|
||||||
|
: notTableOrSmallerOptions
|
||||||
|
}
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
import './index.scss'
|
import './index.scss'
|
||||||
|
|
||||||
import { NLayoutHeader, NSpace, NTooltip, NDropdown } from 'naive-ui'
|
import { NLayoutHeader, NSpace, NDropdown } from 'naive-ui'
|
||||||
import RIcon from '@/components/RIcon/index'
|
import RIcon from '@/components/RIcon/index'
|
||||||
import TootipIcon from '@/layout/components/SiderBar/components/TooltipIcon/index'
|
import TootipIcon from '@/layout/components/SiderBar/components/TooltipIcon/index'
|
||||||
import SettingDrawer from './components/SettingDrawer/index'
|
import SettingDrawer from './components/SettingDrawer/index'
|
||||||
@ -29,20 +29,22 @@ import AppAvatar from '@/app-components/app/AppAvatar/index'
|
|||||||
|
|
||||||
import { useSetting } from '@/store'
|
import { useSetting } from '@/store'
|
||||||
import { LOCAL_OPTIONS } from '@/app-config/localConfig'
|
import { LOCAL_OPTIONS } from '@/app-config/localConfig'
|
||||||
import { useAvatarOptions, avatarDropdownClick } from './hook'
|
import {
|
||||||
import { useI18n } from '@/hooks/web/index'
|
createAvatarOptions,
|
||||||
import { useFullscreen } from 'vue-hooks-plus'
|
avatarDropdownClick,
|
||||||
import { useDevice } from '@/hooks/web/index'
|
createLeftIconOptions,
|
||||||
|
createRightIconOptions,
|
||||||
|
} from './hook'
|
||||||
|
import { useDevice, useFullscreen } from '@/hooks/web/index'
|
||||||
import { globalVariableToRefs, setVariable } from '@/hooks/variable/index'
|
import { globalVariableToRefs, setVariable } from '@/hooks/variable/index'
|
||||||
|
|
||||||
import type { LeftIconOptions, IconEventMapOptions, IconEventMap } from './type'
|
import type { IconEventMapOptions, IconEventMap } from './type'
|
||||||
|
|
||||||
const SiderBar = defineComponent({
|
export default defineComponent({
|
||||||
name: 'SiderBar',
|
name: 'AppSiderBar',
|
||||||
setup() {
|
setup() {
|
||||||
const settingStore = useSetting()
|
const settingStore = useSetting()
|
||||||
|
|
||||||
const { t } = useI18n()
|
|
||||||
const { updateLocale, changeSwitcher } = settingStore
|
const { updateLocale, changeSwitcher } = settingStore
|
||||||
|
|
||||||
const [isFullscreen, { toggleFullscreen }] = useFullscreen(
|
const [isFullscreen, { toggleFullscreen }] = useFullscreen(
|
||||||
@ -62,69 +64,24 @@ const SiderBar = defineComponent({
|
|||||||
*
|
*
|
||||||
* 顶部左边操作栏
|
* 顶部左边操作栏
|
||||||
*/
|
*/
|
||||||
const leftIconOptions = computed(() => {
|
const leftIconOptions = computed(() =>
|
||||||
const options: LeftIconOptions[] = [
|
createLeftIconOptions({
|
||||||
{
|
isFullscreen,
|
||||||
name: 'reload',
|
isTabletOrSmaller,
|
||||||
size: 18,
|
reloadRouteSwitch,
|
||||||
tooltip: t('headerTooltip.Reload'),
|
}),
|
||||||
iconClass: computed(() =>
|
)
|
||||||
!reloadRouteSwitch.value ? 'ray-icon__reload--loading' : '',
|
|
||||||
),
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
if (isTabletOrSmaller.value) {
|
|
||||||
options[0] = {
|
|
||||||
name: 'menu',
|
|
||||||
size: 18,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return options
|
|
||||||
})
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* 顶部右边提示框操作栏
|
* 顶部右边提示框操作栏
|
||||||
*/
|
*/
|
||||||
const rightTooltipIconOptions = computed(() => {
|
const rightTooltipIconOptions = computed(() =>
|
||||||
const options = [
|
createRightIconOptions({
|
||||||
{
|
isFullscreen,
|
||||||
name: 'search',
|
isTabletOrSmaller,
|
||||||
size: 18,
|
reloadRouteSwitch,
|
||||||
tooltip: t('headerTooltip.Search'),
|
}),
|
||||||
eventKey: 'search',
|
)
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'fullscreen',
|
|
||||||
size: 18,
|
|
||||||
tooltip: computed(() =>
|
|
||||||
isFullscreen.value
|
|
||||||
? t('headerTooltip.CancelFullScreen')
|
|
||||||
: t('headerTooltip.FullScreen'),
|
|
||||||
),
|
|
||||||
eventKey: 'screen',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'github',
|
|
||||||
size: 18,
|
|
||||||
tooltip: t('headerTooltip.Github'),
|
|
||||||
eventKey: 'github',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'setting',
|
|
||||||
size: 18,
|
|
||||||
tooltip: t('headerTooltip.Setting'),
|
|
||||||
eventKey: 'setting',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
if (isTabletOrSmaller.value) {
|
|
||||||
options.shift()
|
|
||||||
}
|
|
||||||
|
|
||||||
return options
|
|
||||||
})
|
|
||||||
const iconEventMap: IconEventMapOptions = {
|
const iconEventMap: IconEventMapOptions = {
|
||||||
// 刷新组件重新加载,手动设置 800ms loading 时长
|
// 刷新组件重新加载,手动设置 800ms loading 时长
|
||||||
reload: () => {
|
reload: () => {
|
||||||
@ -156,24 +113,9 @@ const SiderBar = defineComponent({
|
|||||||
iconEventMap[key]?.()
|
iconEventMap[key]?.()
|
||||||
}
|
}
|
||||||
|
|
||||||
const LeftToolIcon = (props: (typeof leftIconOptions.value)[0]) => {
|
|
||||||
const { iconClass, name, size } = props
|
|
||||||
|
|
||||||
return (
|
|
||||||
<RIcon
|
|
||||||
customClassName={`${isRef(iconClass) ? iconClass.value : iconClass}`}
|
|
||||||
name={name}
|
|
||||||
size={size}
|
|
||||||
cursor="pointer"
|
|
||||||
onClick={toolIconClick.bind(this, name)}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
leftIconOptions,
|
leftIconOptions,
|
||||||
rightTooltipIconOptions,
|
rightTooltipIconOptions,
|
||||||
t,
|
|
||||||
toolIconClick,
|
toolIconClick,
|
||||||
showSettings,
|
showSettings,
|
||||||
updateLocale,
|
updateLocale,
|
||||||
@ -181,12 +123,9 @@ const SiderBar = defineComponent({
|
|||||||
drawerPlacement,
|
drawerPlacement,
|
||||||
breadcrumbSwitch,
|
breadcrumbSwitch,
|
||||||
globalSearchShown,
|
globalSearchShown,
|
||||||
LeftToolIcon,
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
render() {
|
render() {
|
||||||
const { LeftToolIcon } = this
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<NLayoutHeader class="layout-header" bordered>
|
<NLayoutHeader class="layout-header" bordered>
|
||||||
<GlobalSeach v-model:show={this.globalSearchShown} />
|
<GlobalSeach v-model:show={this.globalSearchShown} />
|
||||||
@ -200,18 +139,16 @@ const SiderBar = defineComponent({
|
|||||||
wrapItem={false}
|
wrapItem={false}
|
||||||
itemStyle={this.spaceItemStyle}
|
itemStyle={this.spaceItemStyle}
|
||||||
>
|
>
|
||||||
{this.leftIconOptions.map((curr) =>
|
{this.leftIconOptions.map((curr) => (
|
||||||
curr.tooltip ? (
|
<TootipIcon
|
||||||
<NTooltip>
|
iconName={curr.name}
|
||||||
{{
|
tooltipText={
|
||||||
trigger: () => <LeftToolIcon {...curr} />,
|
isRef(curr.tooltip) ? curr.tooltip.value : curr.tooltip
|
||||||
default: () => curr.tooltip,
|
}
|
||||||
}}
|
customClassName={curr.iconClass}
|
||||||
</NTooltip>
|
onClick={this.toolIconClick.bind(this, curr.name)}
|
||||||
) : (
|
/>
|
||||||
<LeftToolIcon {...curr} />
|
))}
|
||||||
),
|
|
||||||
)}
|
|
||||||
{this.breadcrumbSwitch ? <Breadcrumb /> : null}
|
{this.breadcrumbSwitch ? <Breadcrumb /> : null}
|
||||||
</NSpace>
|
</NSpace>
|
||||||
<NSpace
|
<NSpace
|
||||||
@ -225,6 +162,7 @@ const SiderBar = defineComponent({
|
|||||||
tooltipText={
|
tooltipText={
|
||||||
isRef(curr.tooltip) ? curr.tooltip.value : curr.tooltip
|
isRef(curr.tooltip) ? curr.tooltip.value : curr.tooltip
|
||||||
}
|
}
|
||||||
|
customClassName={curr.iconClass}
|
||||||
onClick={this.toolIconClick.bind(this, curr.name)}
|
onClick={this.toolIconClick.bind(this, curr.name)}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
@ -243,7 +181,7 @@ const SiderBar = defineComponent({
|
|||||||
/>
|
/>
|
||||||
</NDropdown>
|
</NDropdown>
|
||||||
<NDropdown
|
<NDropdown
|
||||||
options={useAvatarOptions()}
|
options={createAvatarOptions()}
|
||||||
onSelect={avatarDropdownClick.bind(this)}
|
onSelect={avatarDropdownClick.bind(this)}
|
||||||
trigger="click"
|
trigger="click"
|
||||||
>
|
>
|
||||||
@ -259,5 +197,3 @@ const SiderBar = defineComponent({
|
|||||||
)
|
)
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
export default SiderBar
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import type { DropdownOption } from 'naive-ui'
|
import type { DropdownOption } from 'naive-ui'
|
||||||
import type { ComputedRef } from 'vue'
|
import type { ComputedRef, Ref } from 'vue'
|
||||||
|
|
||||||
export interface IconEventMapOptions {
|
export interface IconEventMapOptions {
|
||||||
[propName: string]: (...args: unknown[]) => unknown
|
[propName: string]: (...args: unknown[]) => unknown
|
||||||
@ -17,14 +17,14 @@ export interface IconDropdownOptions extends UnknownObjectKey {
|
|||||||
export interface IconOptions {
|
export interface IconOptions {
|
||||||
name: string
|
name: string
|
||||||
size?: number
|
size?: number
|
||||||
tooltip?: string
|
tooltip?: ComputedRef<string> | string
|
||||||
eventKey?: string
|
eventKey?: string
|
||||||
dropdown?: IconDropdownOptions
|
dropdown?: IconDropdownOptions
|
||||||
|
iconClass?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface LeftIconOptions {
|
export interface IconOptionsFC {
|
||||||
name: string
|
isTabletOrSmaller: Ref<boolean>
|
||||||
size: number
|
isFullscreen: Ref<boolean>
|
||||||
tooltip?: string
|
reloadRouteSwitch: Ref<boolean>
|
||||||
iconClass?: ComputedRef
|
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,7 @@ import { useSetting } from '@/store'
|
|||||||
import type { GlobalThemeOverrides } from 'naive-ui'
|
import type { GlobalThemeOverrides } from 'naive-ui'
|
||||||
|
|
||||||
const ContentWrapper = defineComponent({
|
const ContentWrapper = defineComponent({
|
||||||
name: 'ContentWrapper',
|
name: 'LayoutContentWrapper',
|
||||||
setup() {
|
setup() {
|
||||||
const settingStore = useSetting()
|
const settingStore = useSetting()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
import MenuTag from '@/layout/components/MenuTag/index'
|
import MenuTag from '@/layout/components/MenuTag/index'
|
||||||
|
|
||||||
const FeatureWrapper = defineComponent({
|
const FeatureWrapper = defineComponent({
|
||||||
name: 'FeatureWrapper',
|
name: 'LayoutFeatureWrapper',
|
||||||
setup() {
|
setup() {
|
||||||
return {}
|
return {}
|
||||||
},
|
},
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
import './index.scss'
|
import './index.scss'
|
||||||
|
|
||||||
const FooterWrapper = defineComponent({
|
const FooterWrapper = defineComponent({
|
||||||
name: 'FooterWrapper',
|
name: 'LayoutFooterWrapper',
|
||||||
setup() {
|
setup() {
|
||||||
const {
|
const {
|
||||||
layout: { copyright },
|
layout: { copyright },
|
||||||
|
@ -13,7 +13,7 @@ import { NSpace } from 'naive-ui'
|
|||||||
import SiderBar from '@/layout/components/SiderBar/index'
|
import SiderBar from '@/layout/components/SiderBar/index'
|
||||||
|
|
||||||
const HeaderWrapper = defineComponent({
|
const HeaderWrapper = defineComponent({
|
||||||
name: 'HeaderWrapper',
|
name: 'LayoutHeaderWrapper',
|
||||||
setup() {
|
setup() {
|
||||||
return {}
|
return {}
|
||||||
},
|
},
|
||||||
|
@ -15,8 +15,8 @@ import type { Ref } from 'vue'
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* 动态获取 SiderBar 和 MenuTag 高度, 用于 LayoutConetent 高度实时获取与渲染
|
* 动态获取 SiderBar 和 MenuTag 高度, 用于 LayoutContent 高度实时获取与渲染
|
||||||
* 可以动态更改 MenuTag 样式后, 使得 LayoutConetent 也可以准确的获取高度
|
* 可以动态更改 MenuTag 样式后, 使得 LayoutContent 也可以准确的获取高度
|
||||||
*
|
*
|
||||||
* 基于 vueuse useElementSize 方法实现
|
* 基于 vueuse useElementSize 方法实现
|
||||||
* 不建议滥用该方法, 对页面渲染有一定的影响
|
* 不建议滥用该方法, 对页面渲染有一定的影响
|
||||||
|
@ -71,11 +71,11 @@ export const combineI18nMessages = (langs: I18nModules, prefix: string) => {
|
|||||||
|
|
||||||
/** 获取所有语言 */
|
/** 获取所有语言 */
|
||||||
export const getAppLocalMessages = async (
|
export const getAppLocalMessages = async (
|
||||||
LOCAL_OPTIONS: AppLocalesDropdownMixedOption[],
|
localOptions: AppLocalesDropdownMixedOption[],
|
||||||
) => {
|
) => {
|
||||||
const message = {} as AppCurrentAppMessages
|
const message = {} as AppCurrentAppMessages
|
||||||
|
|
||||||
for (const curr of LOCAL_OPTIONS) {
|
for (const curr of localOptions) {
|
||||||
const msg: AppLocalesModules = await import(`./lang/${curr.key}.ts`)
|
const msg: AppLocalesModules = await import(`./lang/${curr.key}.ts`)
|
||||||
const key = curr.key
|
const key = curr.key
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ import { APP_CATCH_KEY, ROOT_ROUTE } from '@/app-config/appConfig'
|
|||||||
import { redirectRouterToDashboard } from '@/router/helper/routerCopilot'
|
import { redirectRouterToDashboard } from '@/router/helper/routerCopilot'
|
||||||
import { WHITE_ROUTES } from '@/app-config/routerConfig'
|
import { WHITE_ROUTES } from '@/app-config/routerConfig'
|
||||||
import { validRole } from '@/router/helper/routerCopilot'
|
import { validRole } from '@/router/helper/routerCopilot'
|
||||||
import { isValueType } from '@/utils/hook'
|
import { isValueType } from '@/utils/basic'
|
||||||
|
|
||||||
import type { Router, RouteLocationNormalized } from 'vue-router'
|
import type { Router, RouteLocationNormalized } from 'vue-router'
|
||||||
import type { AppRouteMeta } from '@/router/type'
|
import type { AppRouteMeta } from '@/router/type'
|
||||||
|
@ -15,7 +15,7 @@ import { useSignin } from '@/store'
|
|||||||
import { useVueRouter } from '@/hooks/web/index'
|
import { useVueRouter } from '@/hooks/web/index'
|
||||||
import { ROOT_ROUTE } from '@/app-config/appConfig'
|
import { ROOT_ROUTE } from '@/app-config/appConfig'
|
||||||
import { setStorage } from '@/utils/cache'
|
import { setStorage } from '@/utils/cache'
|
||||||
import { getAppEnvironment } from '@/utils/hook'
|
import { getAppEnvironment } from '@/utils/basic'
|
||||||
|
|
||||||
import type { Router } from 'vue-router'
|
import type { Router } from 'vue-router'
|
||||||
import type { AppRouteMeta } from '@/router/type'
|
import type { AppRouteMeta } from '@/router/type'
|
||||||
|
@ -13,10 +13,9 @@
|
|||||||
|
|
||||||
import { APP_MENU_CONFIG, ROOT_ROUTE } from '@/app-config/appConfig'
|
import { APP_MENU_CONFIG, ROOT_ROUTE } from '@/app-config/appConfig'
|
||||||
import RIcon from '@/components/RIcon/index'
|
import RIcon from '@/components/RIcon/index'
|
||||||
import { isValueType } from '@/utils/hook'
|
import { isValueType } from '@/utils/basic'
|
||||||
import { getStorage, setStorage } from '@/utils/cache'
|
import { getStorage } from '@/utils/cache'
|
||||||
|
|
||||||
import type { VNode } from 'vue'
|
|
||||||
import type {
|
import type {
|
||||||
AppMenuOption,
|
AppMenuOption,
|
||||||
MenuTagOptions,
|
MenuTagOptions,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { isValueType } from '@use-utils/hook'
|
import { isValueType } from '@/utils/basic'
|
||||||
import { APP_REGEX } from '@/app-config/regexConfig'
|
import { APP_REGEX } from '@/app-config/regexConfig'
|
||||||
import { unrefElement } from '@/utils/vue/index'
|
import { unrefElement } from '@/utils/vue/index'
|
||||||
|
|
||||||
|
@ -170,7 +170,6 @@ export default function (mode: string): PluginOption[] {
|
|||||||
'vue-i18n',
|
'vue-i18n',
|
||||||
'dayjs',
|
'dayjs',
|
||||||
'echarts',
|
'echarts',
|
||||||
'vuedraggable',
|
|
||||||
'xlsx',
|
'xlsx',
|
||||||
'axios',
|
'axios',
|
||||||
'screenfull',
|
'screenfull',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user