first
This commit is contained in:
73
src/stores/adminInfo.ts
Normal file
73
src/stores/adminInfo.ts
Normal file
@@ -0,0 +1,73 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import { ADMIN_INFO } from '@/stores/constant/cacheKey'
|
||||
import type { AdminInfo } from '@/stores/interface'
|
||||
|
||||
export const useAdminInfo = defineStore('adminInfo', {
|
||||
state: (): AdminInfo => {
|
||||
return {
|
||||
access_token: '',
|
||||
token_type: '',
|
||||
refresh_token: '',
|
||||
expires_in: 0,
|
||||
scope: '',
|
||||
nickname: '',
|
||||
userType: 0,
|
||||
deptIndex: '',
|
||||
userIndex: '',
|
||||
client_id: '',
|
||||
headSculpture: '',
|
||||
jti: '',
|
||||
name: '',
|
||||
deptId: '',
|
||||
phone: '',
|
||||
email: '',
|
||||
limitIpStart: '',
|
||||
limitIpEnd: '',
|
||||
limitTime: '',
|
||||
casualUser: 0,
|
||||
type: 0,
|
||||
smsNotice: 0,
|
||||
emailNotice: 0,
|
||||
role: [],
|
||||
devCode: '',
|
||||
id: '',
|
||||
loginName: '',
|
||||
state: 0,
|
||||
registerTime: '',
|
||||
loginTime: '',
|
||||
deptName: '',
|
||||
areaId: '',
|
||||
areaName: '',
|
||||
deptLevel: 0,
|
||||
roleList: [],
|
||||
roleCode: []
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
dataFill(state: AdminInfo) {
|
||||
this.$state = { ...this.$state, ...state }
|
||||
},
|
||||
removeToken() {
|
||||
this.access_token = ''
|
||||
this.refresh_token = ''
|
||||
},
|
||||
setToken(token: string, type: 'auth' | 'refresh') {
|
||||
const field = type == 'auth' ? 'token' : 'refresh_token'
|
||||
this[field] = token
|
||||
},
|
||||
getToken(type: 'auth' | 'refresh' = 'auth') {
|
||||
if (type === 'auth') {
|
||||
if (this.token_type && this.access_token) {
|
||||
return this.token_type + ' ' + this.access_token
|
||||
} else {
|
||||
return ''
|
||||
}
|
||||
} else {
|
||||
return this.refresh_token
|
||||
}
|
||||
}
|
||||
},
|
||||
persist: {
|
||||
key: ADMIN_INFO
|
||||
}
|
||||
})
|
||||
128
src/stores/config.ts
Normal file
128
src/stores/config.ts
Normal file
@@ -0,0 +1,128 @@
|
||||
import { reactive } from 'vue'
|
||||
import { defineStore } from 'pinia'
|
||||
import { STORE_CONFIG } from '@/stores/constant/cacheKey'
|
||||
import type { Layout } from '@/stores/interface'
|
||||
|
||||
export const useConfig = defineStore(
|
||||
'config',
|
||||
() => {
|
||||
const layout: Layout = reactive({
|
||||
/* 全局 */
|
||||
showDrawer: false,
|
||||
// 是否收缩布局(小屏设备)
|
||||
shrink: false,
|
||||
// 后台布局方式,可选值<Default|Classic|Streamline|Double>
|
||||
layoutMode: 'Classic',
|
||||
// 后台主页面切换动画,可选值<slide-right|slide-left|el-fade-in-linear|el-fade-in|el-zoom-in-center|el-zoom-in-top|el-zoom-in-bottom>
|
||||
mainAnimation: 'slide-right',
|
||||
// 是否暗黑模式
|
||||
isDark: false,
|
||||
elementUiPrimary: ['#002B6A', '#002B6A'],
|
||||
tableHeaderBackground: ['#F3F6F9', '#F3F6F9'],
|
||||
tableHeaderColor: ['#111', '#fff'],
|
||||
tableCurrent: ['#F3F6F9', '#F3F6F9'],
|
||||
/* 侧边菜单 */
|
||||
// 侧边菜单背景色
|
||||
menuBackground: ['#002B6A', '#1d1e1f'],
|
||||
// 侧边菜单文字颜色
|
||||
menuColor: ['#FFFFFF', '#CFD3DC'],
|
||||
// 侧边菜单激活项背景色
|
||||
menuActiveBackground: ['#002255', '#1d1e1f'],
|
||||
// 侧边菜单激活项文字色
|
||||
menuActiveColor: ['#409eff', '#3375b9'],
|
||||
// 侧边菜单顶栏背景色
|
||||
menuTopBarBackground: ['#002B6A', '#1d1e1f'],
|
||||
// 侧边菜单宽度(展开时),单位px
|
||||
menuWidth: 260,
|
||||
// 侧边菜单项默认图标
|
||||
menuDefaultIcon: 'fa fa-circle-o',
|
||||
// 是否水平折叠收起菜单
|
||||
menuCollapse: false,
|
||||
// 是否只保持一个子菜单的展开(手风琴)
|
||||
menuUniqueOpened: false,
|
||||
// 显示菜单栏顶栏(LOGO)
|
||||
menuShowTopBar: true,
|
||||
|
||||
/* 顶栏 */
|
||||
// 顶栏文字色
|
||||
headerBarTabColor: ['#FFFFFF', '#CFD3DC'],
|
||||
// // 顶栏激活项背景色
|
||||
headerBarTabActiveBackground: ['#ffffff', '#1d1e1f'],
|
||||
// 顶栏激活项文字色
|
||||
headerBarTabActiveColor: ['#000000', '#409EFF'],
|
||||
// 顶栏背景色
|
||||
headerBarBackground: ['#002B6A', '#1d1e1f'],
|
||||
// 顶栏悬停时背景色
|
||||
headerBarHoverBackground: ['#f5f5f5', '#18222c']
|
||||
})
|
||||
|
||||
const lang = reactive({
|
||||
// 默认语言,可选值<zh-cn|en>
|
||||
defaultLang: 'zh-cn',
|
||||
// 当在默认语言包找不到翻译时,继续在 fallbackLang 语言包内查找翻译
|
||||
fallbackLang: 'zh-cn',
|
||||
// 支持的语言列表
|
||||
langArray: [
|
||||
{ name: 'zh-cn', value: '中文简体' },
|
||||
{ name: 'en', value: 'English' }
|
||||
]
|
||||
})
|
||||
|
||||
function menuWidth() {
|
||||
if (layout.shrink) {
|
||||
return layout.menuCollapse ? '0px' : layout.menuWidth + 'px'
|
||||
}
|
||||
// 菜单是否折叠
|
||||
return layout.menuCollapse ? '64px' : layout.menuWidth + 'px'
|
||||
}
|
||||
|
||||
function setLang(val: string) {
|
||||
lang.defaultLang = val
|
||||
}
|
||||
|
||||
function onSetLayoutColor(data = layout.layoutMode) {
|
||||
// 切换布局时,如果是为默认配色方案,对菜单激活背景色重新赋值
|
||||
const tempValue = layout.isDark
|
||||
? { idx: 1, color: '#1d1e1f', newColor: '#141414' }
|
||||
: { idx: 0, color: '#ffffff', newColor: '#f5f5f5' }
|
||||
if (
|
||||
data == 'Classic' &&
|
||||
layout.headerBarBackground[tempValue.idx] == tempValue.color &&
|
||||
layout.headerBarTabActiveBackground[tempValue.idx] == tempValue.color
|
||||
) {
|
||||
layout.headerBarTabActiveBackground[tempValue.idx] = tempValue.newColor
|
||||
} else if (
|
||||
data == 'Default' &&
|
||||
layout.headerBarBackground[tempValue.idx] == tempValue.color &&
|
||||
layout.headerBarTabActiveBackground[tempValue.idx] == tempValue.newColor
|
||||
) {
|
||||
layout.headerBarTabActiveBackground[tempValue.idx] = tempValue.color
|
||||
}
|
||||
}
|
||||
|
||||
function setLayoutMode(data: string) {
|
||||
layout.layoutMode = data
|
||||
onSetLayoutColor(data)
|
||||
}
|
||||
|
||||
const setLayout = (name: keyof Layout, value: any) => {
|
||||
layout[name] = value as never
|
||||
}
|
||||
|
||||
const getColorVal = function (name: keyof Layout): string {
|
||||
const colors = layout[name] as string[]
|
||||
if (layout.isDark) {
|
||||
return colors[1]
|
||||
} else {
|
||||
return colors[0]
|
||||
}
|
||||
}
|
||||
|
||||
return { layout, lang, menuWidth, setLang, setLayoutMode, setLayout, getColorVal, onSetLayoutColor }
|
||||
},
|
||||
{
|
||||
persist: {
|
||||
key: STORE_CONFIG
|
||||
}
|
||||
}
|
||||
)
|
||||
14
src/stores/constant/cacheKey.ts
Normal file
14
src/stores/constant/cacheKey.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
/**
|
||||
* 本地缓存Key
|
||||
*/
|
||||
|
||||
// 管理员资料
|
||||
export const ADMIN_INFO = 'adminInfo'
|
||||
|
||||
// WEB端布局配置
|
||||
export const STORE_CONFIG = 'storeConfig'
|
||||
|
||||
// 后台标签页
|
||||
export const STORE_TAB_VIEW_CONFIG = 'storeTabViewConfig'
|
||||
// 字典
|
||||
export const DICT_DATA = 'dictData'
|
||||
32
src/stores/dictData.ts
Normal file
32
src/stores/dictData.ts
Normal file
@@ -0,0 +1,32 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import { DICT_DATA } from '@/stores/constant/cacheKey'
|
||||
import type { DictData, BasicDictData } from '@/stores/interface/index'
|
||||
import { reactive } from 'vue'
|
||||
|
||||
export const useDictData = defineStore(
|
||||
'dictData',
|
||||
() => {
|
||||
const state: DictData = reactive({
|
||||
basic: [],
|
||||
area: []
|
||||
// 其他接口获取的字典,比如区域
|
||||
})
|
||||
const getBasicData = (code: string, arr?: string[]) => {
|
||||
let list = []
|
||||
list = state.basic.filter(item => item.code === code)[0]?.children || []
|
||||
if (arr) {
|
||||
list = list.filter(item => !arr.includes(item.code))
|
||||
}
|
||||
return list
|
||||
}
|
||||
return {
|
||||
state,
|
||||
getBasicData
|
||||
}
|
||||
},
|
||||
{
|
||||
persist: {
|
||||
key: DICT_DATA
|
||||
}
|
||||
}
|
||||
)
|
||||
7
src/stores/index.ts
Normal file
7
src/stores/index.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import { createPinia } from 'pinia'
|
||||
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
|
||||
|
||||
const pinia = createPinia()
|
||||
pinia.use(piniaPluginPersistedstate)
|
||||
|
||||
export default pinia
|
||||
91
src/stores/interface/index.ts
Normal file
91
src/stores/interface/index.ts
Normal file
@@ -0,0 +1,91 @@
|
||||
// 变量名对应含义请在 /stores/* 里边找
|
||||
import type { RouteRecordRaw, RouteLocationNormalized } from 'vue-router'
|
||||
|
||||
export interface Layout {
|
||||
showDrawer: boolean
|
||||
shrink: boolean
|
||||
layoutMode: string
|
||||
mainAnimation: string
|
||||
isDark: boolean
|
||||
menuWidth: number
|
||||
menuDefaultIcon: string
|
||||
menuCollapse: boolean
|
||||
menuUniqueOpened: boolean
|
||||
menuShowTopBar: boolean
|
||||
elementUiPrimary: string[]
|
||||
tableHeaderBackground: string[]
|
||||
tableHeaderColor: string[]
|
||||
tableCurrent: string[]
|
||||
menuBackground: string[]
|
||||
menuColor: string[]
|
||||
menuActiveBackground: string[]
|
||||
menuActiveColor: string[]
|
||||
menuTopBarBackground: string[]
|
||||
headerBarTabColor: string[]
|
||||
headerBarBackground: string[]
|
||||
headerBarHoverBackground: string[]
|
||||
headerBarTabActiveBackground: string[]
|
||||
headerBarTabActiveColor: string[]
|
||||
}
|
||||
|
||||
export interface NavTabs {
|
||||
activeIndex: number
|
||||
activeRoute: RouteLocationNormalized | null
|
||||
tabsView: RouteLocationNormalized[]
|
||||
tabFullScreen: boolean
|
||||
tabsViewRoutes: RouteRecordRaw[]
|
||||
authNode: Map<string, string[]>
|
||||
}
|
||||
|
||||
export interface AdminInfo {
|
||||
access_token: string
|
||||
token_type: string
|
||||
refresh_token: string
|
||||
expires_in: number
|
||||
scope: string
|
||||
nickname: string
|
||||
userType: number
|
||||
deptIndex: string
|
||||
userIndex: string
|
||||
client_id: string
|
||||
headSculpture: any
|
||||
jti: string
|
||||
name: string
|
||||
deptId: string
|
||||
phone: string
|
||||
email: string
|
||||
limitIpStart: string
|
||||
limitIpEnd: string
|
||||
limitTime: string
|
||||
casualUser: number
|
||||
type: number
|
||||
smsNotice: number
|
||||
emailNotice: number
|
||||
role: string[]
|
||||
devCode: any
|
||||
id: string
|
||||
loginName: string
|
||||
state: number
|
||||
registerTime: string
|
||||
loginTime: string
|
||||
deptName: string
|
||||
areaId: string
|
||||
areaName: string
|
||||
deptLevel: number
|
||||
roleList: string[]
|
||||
roleCode: string[]
|
||||
}
|
||||
|
||||
export interface DictData {
|
||||
basic: BasicDictData[]
|
||||
area: BasicDictData[]
|
||||
}
|
||||
|
||||
export interface BasicDictData {
|
||||
name: string
|
||||
id: string
|
||||
code: string
|
||||
value: null
|
||||
sort: number | null
|
||||
children?: BasicDictData[]
|
||||
}
|
||||
108
src/stores/navTabs.ts
Normal file
108
src/stores/navTabs.ts
Normal file
@@ -0,0 +1,108 @@
|
||||
import { reactive } from 'vue'
|
||||
import { defineStore } from 'pinia'
|
||||
import { STORE_TAB_VIEW_CONFIG } from '@/stores/constant/cacheKey'
|
||||
import type { NavTabs } from '@/stores/interface/index'
|
||||
import type { RouteLocationNormalized, RouteRecordRaw } from 'vue-router'
|
||||
import { adminBaseRoutePath } from '@/router/static'
|
||||
|
||||
export const useNavTabs = defineStore(
|
||||
'navTabs',
|
||||
() => {
|
||||
const state: NavTabs = reactive({
|
||||
// 激活tab的index
|
||||
activeIndex: 0,
|
||||
// 激活的tab
|
||||
activeRoute: null,
|
||||
// tab列表
|
||||
tabsView: [],
|
||||
// 当前tab是否全屏
|
||||
tabFullScreen: false,
|
||||
// 从后台加载到的菜单路由列表
|
||||
tabsViewRoutes: [],
|
||||
// 按钮权限节点
|
||||
authNode: new Map(),
|
||||
})
|
||||
|
||||
function addTab(route: RouteLocationNormalized) {
|
||||
if (!route.meta.addtab) return
|
||||
for (const key in state.tabsView) {
|
||||
if (state.tabsView[key].path === route.path) {
|
||||
state.tabsView[key].params = route.params ? route.params : state.tabsView[key].params
|
||||
state.tabsView[key].query = route.query ? route.query : state.tabsView[key].query
|
||||
return
|
||||
}
|
||||
}
|
||||
state.tabsView.push(route)
|
||||
}
|
||||
|
||||
function closeTab(route: RouteLocationNormalized) {
|
||||
state.tabsView.map((v, k) => {
|
||||
if (v.path == route.path) {
|
||||
state.tabsView.splice(k, 1)
|
||||
return
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭多个标签
|
||||
* @param retainMenu 需要保留的标签,否则关闭全部标签
|
||||
*/
|
||||
const closeTabs = (retainMenu: RouteLocationNormalized | false = false) => {
|
||||
if (retainMenu) {
|
||||
state.tabsView = [retainMenu]
|
||||
} else {
|
||||
state.tabsView = []
|
||||
}
|
||||
}
|
||||
|
||||
const setActiveRoute = (route: RouteLocationNormalized): void => {
|
||||
const currentRouteIndex: number = state.tabsView.findIndex((item: RouteLocationNormalized) => {
|
||||
return item.path === route.path
|
||||
})
|
||||
if (currentRouteIndex === -1) return
|
||||
state.activeRoute = route
|
||||
state.activeIndex = currentRouteIndex
|
||||
}
|
||||
|
||||
const setTabsViewRoutes = (data: RouteRecordRaw[]): void => {
|
||||
state.tabsViewRoutes = encodeRoutesURI(data)
|
||||
}
|
||||
|
||||
const setAuthNode = (key: string, data: string[]) => {
|
||||
state.authNode.set(key, data)
|
||||
}
|
||||
|
||||
const fillAuthNode = (data: Map<string, string[]>) => {
|
||||
state.authNode = data
|
||||
}
|
||||
|
||||
const setFullScreen = (fullScreen: boolean): void => {
|
||||
state.tabFullScreen = fullScreen
|
||||
}
|
||||
|
||||
return { state, addTab, closeTab, closeTabs, setActiveRoute, setTabsViewRoutes, setAuthNode, fillAuthNode, setFullScreen }
|
||||
},
|
||||
{
|
||||
persist: {
|
||||
key: STORE_TAB_VIEW_CONFIG,
|
||||
paths: ['state.tabFullScreen'],
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
/**
|
||||
* 对iframe的url进行编码
|
||||
*/
|
||||
function encodeRoutesURI(data: RouteRecordRaw[]) {
|
||||
data.forEach((item) => {
|
||||
if (item.meta?.menu_type == 'iframe') {
|
||||
item.path = adminBaseRoutePath + '/iframe/' + encodeURIComponent(item.path)
|
||||
}
|
||||
|
||||
if (item.children && item.children.length) {
|
||||
item.children = encodeRoutesURI(item.children)
|
||||
}
|
||||
})
|
||||
return data
|
||||
}
|
||||
Reference in New Issue
Block a user