This commit is contained in:
weicw
2021-07-29 16:17:26 +08:00
commit a6eb6f83d1
127 changed files with 60792 additions and 0 deletions

4
src/store/getters.js Normal file
View File

@@ -0,0 +1,4 @@
export default {
user: state => state.user,
theme: state => state.theme
}

18
src/store/index.js Normal file
View File

@@ -0,0 +1,18 @@
/**
* vuex状态管理
*/
import {createStore} from 'vuex';
import getters from './getters';
import user from './modules/user';
import theme from './modules/theme';
export default createStore({
state: {},
mutations: {},
actions: {},
modules: {
user,
theme
},
getters
});

454
src/store/modules/theme.js Normal file
View File

@@ -0,0 +1,454 @@
/**
* 主题状态管理
*/
import {changeColor} from 'ele-admin-pro/packages/style/util.js';
import setting from '@/config/setting';
// 不需要本地缓存的state
const NO_CACHE_STATE = [
'collapse',
'tabs',
'homeComponents',
'keepAliveInclude',
'keepAliveExclude',
'tabKeepAlive',
'screenWidth',
'screenHeight'
];
/**
* 读取缓存的配置
* @param keyName 缓存的键名
* @returns {Object}
*/
function getCacheSetting(keyName) {
let cache = {};
try {
const value = localStorage.getItem(keyName);
if (value) {
const temp = JSON.parse(value);
if (typeof temp === 'object') {
cache = temp;
}
}
} catch (e) {
console.error(e);
}
return cache;
}
/**
* 缓存配置
* @param keyName 缓存的键名
* @param key 缓存的配置名
* @param value 缓存的配置名对应的值
*/
function cacheSetting(keyName, key, value) {
if (NO_CACHE_STATE.includes(key)) {
return;
}
const cache = getCacheSetting(keyName);
if (cache[key] !== value) {
cache[key] = value;
localStorage.setItem(keyName, JSON.stringify(cache));
}
}
/**
* 检查state值以兼容旧版本
* @param key
* @param value
* @returns
*/
function checkStateValue(key, value) {
if (typeof value === 'number') {
if (key === 'sideStyle') {
return ['light', 'dark'][value < 2 ? value : 1];
}
if (key === 'headStyle') {
return ['light', 'dark', 'primary'][value < 3 ? value : 2];
}
if (key === 'tabStyle') {
return ['default', 'dot', 'card'][value < 3 ? value : 2];
}
if (key === 'layoutStyle') {
return ['side', 'top', 'mix'][value < 3 ? value : 2];
}
}
return value;
}
/**
* 获取state
* @param setting 默认配置
* @returns {Object}
*/
function getState(setting) {
const state = {
// 侧边栏风格: light(亮色), dark(暗色)
sideStyle: 'dark',
// 顶栏风格: light(亮色), dark(暗色), primary(主色)
headStyle: 'light',
// 标签页风格: default(默认), dot(圆点), card(卡片)
tabStyle: 'default',
// 布局风格: side(默认), top(顶栏菜单), mix(混合菜单)
layoutStyle: 'side',
// 侧边栏菜单风格: default(默认), mix(双排菜单)
sideMenuStyle: 'default',
// 是否固定侧栏
fixedSidebar: true,
// 是否固定顶栏
fixedHeader: false,
// 是否固定主体
fixedBody: false,
// 内容区域宽度铺满
bodyFull: true,
// 是否开启多标签
showTabs: true,
// logo是否自适应宽度
logoAutoSize: false,
// 侧栏是否多彩图标
colorfulIcon: false,
// 侧边栏是否只保持一个子菜单展开
sideUniqueOpen: true,
// 是否开启页脚
showFooter: true,
// 是否是色弱模式
weakMode: false,
// 是否是暗黑模式
darkMode: false,
// 主题色
color: null,
// 是否折叠侧边栏
collapse: false,
// 当前打开的选项卡
tabs: [],
// 主页的组件
homeComponents: [],
// 需要keep-alive的组件
keepAliveInclude: [],
// 不需要keep-alive的组件
keepAliveExclude: [],
// 开启多页签是否缓存组件
tabKeepAlive: true,
// 屏幕宽度
screenWidth: document.documentElement.clientWidth || document.body.clientWidth,
// 屏幕高度
screenHeight: document.documentElement.clientHeight || document.body.clientHeight
};
// 读取缓存的配置及默认配置
for (let key in state) {
if (!Object.prototype.hasOwnProperty.call(state, key)) {
continue;
}
const cache = getCacheSetting(setting.themeStoreName);
if (cache[key] !== undefined) {
state[key] = checkStateValue(key, cache[key]);
} else if (setting[key] !== undefined) {
state[key] = checkStateValue(key, setting[key]);
}
}
// 恢复色弱模式
if (state.weakMode) {
changeWeakMode(true);
}
// 恢复上次主题色
if (state.color || state.darkMode) {
window.addEventListener('load', () => {
doChangeTheme(state.color, state.darkMode).catch((e) => {
console.error(e);
});
});
}
return state;
}
/**
* 切换主题
* @param value 主题
* @param dark 是否是暗黑模式
* @returns {Promise<>}
*/
function doChangeTheme(value, dark) {
return new Promise((resolve, reject) => {
try {
changeColor(value, dark);
resolve();
} catch (e) {
reject(e);
}
});
}
/**
* 开关色弱模式
* @param weakMode 是否开启色弱模式
*/
function changeWeakMode(weakMode) {
const weakClass = 'ele-admin-weak';
if (weakMode) {
document.body.classList.add(weakClass);
} else {
document.body.classList.remove(weakClass);
}
}
/**
* 获取需要keep-alive的组件
* @param tabs 页签数据
* @param homeComponents 主页组件
* @returns {any[]}
*/
function getKeepAliveInclude(tabs, homeComponents) {
const components = new Set();
if (tabs) {
tabs.forEach((t) => {
if (t && t.components && t.components.length) {
t.components.forEach((c) => {
if (typeof c === 'string' && c) {
components.add(c);
}
});
}
});
}
if (homeComponents) {
homeComponents.forEach((c) => {
components.add(c);
});
}
return Array.from(components);
}
export default {
namespaced: true,
state: getState(setting),
mutations: {
// 修改state值
SET: function (state, obj) {
state[obj.key] = obj.value;
// 缓存修改的配置
cacheSetting(setting.themeStoreName, obj.key, obj.value);
},
// 更新keepAliveInclude
UPDATE_KEEP_ALIVE_INCLUDE: function (state) {
if (state.showTabs && state.tabKeepAlive) {
state.keepAliveInclude = getKeepAliveInclude(state.tabs, state.homeComponents);
} else {
state.keepAliveInclude = [];
}
}
},
actions: {
/**
* 修改配置
* @param {commit}
* @param obj
*/
set({commit}, obj) {
commit('SET', obj);
if (obj.key === 'showTabs' || obj.key === 'tabKeepAlive') {
commit('UPDATE_KEEP_ALIVE_INCLUDE');
}
},
/**
* 切换配置(boolean类型的配置)
* @param {commit, state}
* @param key 配置名称
*/
toggle({commit, state}, key) {
commit('SET', {key: key, value: !state[key]});
},
/**
* 切换主题色
* @param {commit, state}
* @param value 颜色值
* @returns {Promise<>}
*/
setColor({commit, state}, value) {
return new Promise((resolve, reject) => {
doChangeTheme(value, state.darkMode).then(() => {
commit('SET', {key: 'color', value: value});
return resolve();
}).catch((e) => {
reject(e);
});
});
},
/**
* 切换暗黑模式
* @param {commit, state}
* @param value 是否开启暗黑模式
* @returns {Promise<>}
*/
setDarkMode({commit, state}, value) {
return new Promise((resolve, reject) => {
doChangeTheme(state.color, value).then(() => {
commit('SET', {key: 'darkMode', value: value});
return resolve();
}).catch((e) => {
reject(e);
});
});
},
/**
* 切换色弱模式
* @param {commit}
* @param value 是否开启色弱模式
* @returns {Promise<>}
*/
setWeakMode({commit}, value) {
return new Promise((resolve) => {
changeWeakMode(value);
commit('SET', {key: 'weakMode', value: value});
resolve();
});
},
/**
* 添加tab
* @param {commit, state}
* @param obj {{key: String, path: String, fullPath: String, title: String}}
*/
tabAdd({commit, state}, obj) {
if (!obj.key) {
obj.key = obj.fullPath || obj.path;
}
const i = state.tabs.findIndex((d) => d.key === obj.key);
if (i === -1) {
commit('SET', {key: 'tabs', value: state.tabs.concat([obj])});
} else if (obj.fullPath !== state.tabs[i].fullPath) {
commit('SET', {key: 'tabs', value: state.tabs.slice(0, i).concat([obj]).concat(state.tabs.slice(i + 1))});
}
commit('UPDATE_KEEP_ALIVE_INCLUDE');
},
/**
* 移除指定tab
* @param commit
* @param state
* @param key {String}
* @returns {Promise<Object>}
*/
tabRemove({commit, state}, key) {
return new Promise((resolve) => {
let index = -1, lastIndex = -1, lastPath, last;
for (let i = 0; i < state.tabs.length; i++) {
if (state.tabs[i].key === key || state.tabs[i].fullPath === key) {
index = i;
break;
}
lastIndex = i;
last = state.tabs[i];
lastPath = last.fullPath;
}
commit('SET', {key: 'tabs', value: state.tabs.filter((d, i) => i !== index)});
commit('UPDATE_KEEP_ALIVE_INCLUDE');
resolve({lastIndex: lastIndex, lastPath: lastPath, last: last});
});
},
/**
* 移除所有tab
* @param commit
*/
tabRemoveAll({commit}) {
commit('SET', {key: 'tabs', value: []});
commit('UPDATE_KEEP_ALIVE_INCLUDE');
},
/**
* 移除左侧tab
* @param commit
* @param state
* @param key {String}
*/
tabRemoveLeft({commit, state}, key) {
for (let i = 0; i < state.tabs.length; i++) {
if (state.tabs[i].key === key) {
commit('SET', {key: 'tabs', value: state.tabs.slice(i)});
commit('UPDATE_KEEP_ALIVE_INCLUDE');
break;
}
}
},
/**
* 移除右侧tab
* @param commit
* @param state
* @param key {String}
*/
tabRemoveRight({commit, state}, key) {
for (let i = 0; i < state.tabs.length; i++) {
if (state.tabs[i].key === key) {
commit('SET', {key: 'tabs', value: state.tabs.slice(0, i + 1)});
commit('UPDATE_KEEP_ALIVE_INCLUDE');
break;
}
}
},
/**
* 移除其他tab
* @param commit
* @param state
* @param key {String}
*/
tabRemoveOther({commit, state}, key) {
commit('SET', {key: 'tabs', value: state.tabs.filter((d) => d.key === key)});
commit('UPDATE_KEEP_ALIVE_INCLUDE');
},
/**
* 修改指定tab
* @param commit
* @param state
* @param obj {{path: String, title: String, fullPath: String, closable: Boolean}}
*/
tabSetTitle({commit, state}, obj) {
let i = -1;
if (obj.fullPath) {
i = state.tabs.findIndex((d) => d.fullPath === obj.fullPath);
} else if (obj.path) {
i = state.tabs.findIndex((d) => d.path === obj.path);
}
if (i !== -1) {
const data = Object.assign({}, state.tabs[i]);
if (typeof obj.title === 'string' && obj.title) {
data.title = obj.title;
}
if (typeof obj.closable === 'boolean') {
data.closable = obj.closable;
}
const tabs = state.tabs.slice(0, i).concat([data]).concat(state.tabs.slice(i + 1));
commit('SET', {key: 'tabs', value: tabs});
}
},
/**
* 设置主页的组件名称
* @param {commit, state}
* @param components {Array}
*/
setHomeComponents({commit}, components) {
commit('SET', {key: 'homeComponents', value: components});
commit('UPDATE_KEEP_ALIVE_INCLUDE');
},
/**
* 设置不需要keep-alive的组件
* @param commit
* @param value {Array}
*/
setKeepAliveExclude({commit}, value) {
commit('SET', {key: 'keepAliveExclude', value: value});
},
/**
* 更新屏幕尺寸
* @param {commit, state}
*/
updateScreen({commit, state}) {
const w = document.documentElement.clientWidth || document.body.clientWidth,
h = document.documentElement.clientHeight || document.body.clientHeight;
if (w !== state.screenWidth) {
commit('SET', {key: 'screenWidth', value: w});
}
if (h !== state.screenHeight) {
commit('SET', {key: 'screenHeight', value: h});
}
}
}
};

127
src/store/modules/user.js Normal file
View File

@@ -0,0 +1,127 @@
/**
* 登录状态管理
*/
import axios from 'axios';
import setting from '@/config/setting';
import {formatMenus} from 'ele-admin-pro';
export default {
namespaced: true,
state: {
// 当前用户信息
user: setting.takeUser(),
// 当前用户权限
authorities: [],
// 当前用户角色
roles: [],
// 当前用户的菜单
menus: null
},
mutations: {
// 修改值
SET(state, obj) {
state[obj.key] = obj.value;
},
// 修改token
SET_TOKEN(state, obj) {
setting.cacheToken(obj.token, obj.remember);
state.token = obj.token;
if (!obj.token) {
state.user = {};
state.menus = null;
setting.cacheUser();
}
}
},
actions: {
/**
* 缓存token
* @param commit
* @param token {String, {token: String, remember: String}}
*/
setToken({commit}, token) {
let remember = true;
if (typeof token === 'object') {
remember = token.remember;
token = token.token;
}
commit('SET_TOKEN', {token: token, remember: remember});
},
/**
* 移除token
* @param commit
*/
removeToken({commit}) {
commit('SET_TOKEN', {});
},
/**
* 设置用户信息
* @param commit
* @param user {Object} 用户信息
*/
setUser({commit}, user) {
setting.cacheUser(user);
commit('SET', {key: 'user', value: user});
},
/**
* 设置用户权限
* @param commit
* @param authorities {Array<String>} 权限
*/
setAuthorities({commit}, authorities) {
commit('SET', {key: 'authorities', value: authorities});
},
/**
* 设置用户角色
* @param commit
* @param roles {Array<String>} 角色
*/
setRoles({commit}, roles) {
commit('SET', {key: 'roles', value: roles});
},
/**
* 设置用户菜单
* @param commit
* @param menus {Array} 菜单
*/
setMenus({commit}, menus) {
commit('SET', {key: 'menus', value: menus});
},
/**
* 获取用户菜单路由
* @param commit
* @returns {Promise} {Array}
*/
getMenus({commit}) {
return new Promise((resolve, reject) => {
if (!setting.menuUrl) {
const {menus, homePath} = formatMenus(setting.menus);
commit('SET', {key: 'menus', value: menus});
return resolve({menus: menus, home: homePath});
}
// 请求接口获取用户菜单
axios.get(setting.menuUrl).then((res) => {
const result = typeof setting.parseMenu === 'function' ? setting.parseMenu(res.data) : res.data;
// 获取用户的信息、角色、权限
if (result.user) {
setting.cacheUser(result.user);
commit('SET', {key: 'user', value: result.user});
commit('SET', {key: 'roles', value: result.user.roles});
commit('SET', {key: 'authorities', value: result.user.authorities});
}
// 获取用户的菜单
if (!result.data) {
console.error('get menus error: ', result);
return reject(new Error(result.msg));
}
// 处理菜单数据格式
const {menus, homePath} = formatMenus(result.data, setting.parseMenuItem);
commit('SET', {key: 'menus', value: menus});
resolve({menus: menus, home: homePath});
}).catch(e => {
reject(e);
});
});
}
}
}