mirror of
https://github.com/soybeanjs/soybean-admin.git
synced 2025-09-22 11:36:37 +08:00
refactor(projects): new storage system [新的本地数据存储系统]
This commit is contained in:
parent
7a58035514
commit
971915948b
@ -16,9 +16,8 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { EnumStorageKey } from '@/enum';
|
|
||||||
import { useAppInfo } from '@/composables';
|
import { useAppInfo } from '@/composables';
|
||||||
import { getLocal } from '@/utils';
|
import { localStg } from '@/utils';
|
||||||
|
|
||||||
const { title } = useAppInfo();
|
const { title } = useAppInfo();
|
||||||
|
|
||||||
@ -31,7 +30,7 @@ const lodingClasses = [
|
|||||||
|
|
||||||
function addThemeColorCssVars() {
|
function addThemeColorCssVars() {
|
||||||
const defaultColor = '#1890ff';
|
const defaultColor = '#1890ff';
|
||||||
const themeColor = getLocal(EnumStorageKey['theme-color']) || defaultColor;
|
const themeColor = localStg.get('themeColor') || defaultColor;
|
||||||
const cssVars = `--primary-color: ${themeColor}`;
|
const cssVars = `--primary-color: ${themeColor}`;
|
||||||
document.documentElement.style.cssText = cssVars;
|
document.documentElement.style.cssText = cssVars;
|
||||||
}
|
}
|
||||||
|
@ -5,22 +5,6 @@ export enum EnumContentType {
|
|||||||
formData = 'multipart/form-data'
|
formData = 'multipart/form-data'
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 缓存的key */
|
|
||||||
export enum EnumStorageKey {
|
|
||||||
/** 主题颜色 */
|
|
||||||
'theme-color' = '__THEME_COLOR__',
|
|
||||||
/** 用户token */
|
|
||||||
'token' = '__TOKEN__',
|
|
||||||
/** 用户刷新token */
|
|
||||||
'refresh-token' = '__REFRESH_TOKEN__',
|
|
||||||
/** 用户信息 */
|
|
||||||
'user-info' = '__USER_INFO__',
|
|
||||||
/** 主题配置 */
|
|
||||||
'theme-settings' = '__THEME_SETTINGS__',
|
|
||||||
/** 多页签路由信息 */
|
|
||||||
'multi-tab-routes' = '__MULTI_TAB_ROUTES__'
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 数据类型 */
|
/** 数据类型 */
|
||||||
export enum EnumDataType {
|
export enum EnumDataType {
|
||||||
number = '[object Number]',
|
number = '[object Number]',
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import type { NavigationGuardNext, RouteLocationNormalized } from 'vue-router';
|
import type { NavigationGuardNext, RouteLocationNormalized } from 'vue-router';
|
||||||
import { routeName } from '@/router';
|
import { routeName } from '@/router';
|
||||||
import { useRouteStore } from '@/store';
|
import { useRouteStore } from '@/store';
|
||||||
import { getToken } from '@/utils';
|
import { localStg } from '@/utils';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 动态路由
|
* 动态路由
|
||||||
@ -12,7 +12,7 @@ export async function createDynamicRouteGuard(
|
|||||||
next: NavigationGuardNext
|
next: NavigationGuardNext
|
||||||
) {
|
) {
|
||||||
const route = useRouteStore();
|
const route = useRouteStore();
|
||||||
const isLogin = Boolean(getToken());
|
const isLogin = Boolean(localStg.get('token'));
|
||||||
|
|
||||||
// 初始化权限路由
|
// 初始化权限路由
|
||||||
if (!route.isInitAuthRoute) {
|
if (!route.isInitAuthRoute) {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import type { NavigationGuardNext, RouteLocationNormalized } from 'vue-router';
|
import type { NavigationGuardNext, RouteLocationNormalized } from 'vue-router';
|
||||||
import { routeName } from '@/router';
|
import { routeName } from '@/router';
|
||||||
import { useAuthStore } from '@/store';
|
import { useAuthStore } from '@/store';
|
||||||
import { exeStrategyActions, getToken } from '@/utils';
|
import { exeStrategyActions, localStg } from '@/utils';
|
||||||
import { createDynamicRouteGuard } from './dynamic';
|
import { createDynamicRouteGuard } from './dynamic';
|
||||||
|
|
||||||
/** 处理路由页面的权限 */
|
/** 处理路由页面的权限 */
|
||||||
@ -22,7 +22,7 @@ export async function createPermissionGuard(
|
|||||||
}
|
}
|
||||||
|
|
||||||
const auth = useAuthStore();
|
const auth = useAuthStore();
|
||||||
const isLogin = Boolean(getToken());
|
const isLogin = Boolean(localStg.get('token'));
|
||||||
const permissions = to.meta.permissions || [];
|
const permissions = to.meta.permissions || [];
|
||||||
const needLogin = Boolean(to.meta?.requiresAuth) || Boolean(permissions.length);
|
const needLogin = Boolean(to.meta?.requiresAuth) || Boolean(permissions.length);
|
||||||
const hasPermission = !permissions.length || permissions.includes(auth.userInfo.userRole);
|
const hasPermission = !permissions.length || permissions.includes(auth.userInfo.userRole);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import type { AxiosRequestConfig } from 'axios';
|
import type { AxiosRequestConfig } from 'axios';
|
||||||
import { useAuthStore } from '@/store';
|
import { useAuthStore } from '@/store';
|
||||||
import { getRefreshToken, setRefreshToken, setToken } from '@/utils';
|
import { localStg } from '@/utils';
|
||||||
import { fetchUpdateToken } from '../api';
|
import { fetchUpdateToken } from '../api';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -9,11 +9,12 @@ import { fetchUpdateToken } from '../api';
|
|||||||
*/
|
*/
|
||||||
export async function handleRefreshToken(axiosConfig: AxiosRequestConfig) {
|
export async function handleRefreshToken(axiosConfig: AxiosRequestConfig) {
|
||||||
const { resetAuthStore } = useAuthStore();
|
const { resetAuthStore } = useAuthStore();
|
||||||
const refreshToken = getRefreshToken();
|
const refreshToken = localStg.get('refreshToken') || '';
|
||||||
const { data } = await fetchUpdateToken(refreshToken);
|
const { data } = await fetchUpdateToken(refreshToken);
|
||||||
if (data) {
|
if (data) {
|
||||||
setToken(data.token);
|
localStg.set('token', data.token);
|
||||||
setRefreshToken(data.refreshToken);
|
localStg.set('refreshToken', data.refreshToken);
|
||||||
|
|
||||||
const config = { ...axiosConfig };
|
const config = { ...axiosConfig };
|
||||||
if (config.headers) {
|
if (config.headers) {
|
||||||
config.headers.Authorization = data.token;
|
config.headers.Authorization = data.token;
|
||||||
|
@ -2,7 +2,7 @@ import axios from 'axios';
|
|||||||
import type { AxiosError, AxiosInstance, AxiosRequestConfig } from 'axios';
|
import type { AxiosError, AxiosInstance, AxiosRequestConfig } from 'axios';
|
||||||
import { REFRESH_TOKEN_CODE } from '@/config';
|
import { REFRESH_TOKEN_CODE } from '@/config';
|
||||||
import {
|
import {
|
||||||
getToken,
|
localStg,
|
||||||
handleAxiosError,
|
handleAxiosError,
|
||||||
handleBackendError,
|
handleBackendError,
|
||||||
handleResponseError,
|
handleResponseError,
|
||||||
@ -49,7 +49,7 @@ export default class CustomAxiosInstance {
|
|||||||
const contentType = handleConfig.headers['Content-Type'] as string;
|
const contentType = handleConfig.headers['Content-Type'] as string;
|
||||||
handleConfig.data = await transformRequestData(handleConfig.data, contentType);
|
handleConfig.data = await transformRequestData(handleConfig.data, contentType);
|
||||||
// 设置token
|
// 设置token
|
||||||
handleConfig.headers.Authorization = getToken();
|
handleConfig.headers.Authorization = localStg.get('token') || '';
|
||||||
}
|
}
|
||||||
return handleConfig;
|
return handleConfig;
|
||||||
},
|
},
|
||||||
|
25
src/store/modules/auth/helpers.ts
Normal file
25
src/store/modules/auth/helpers.ts
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import { localStg } from '@/utils';
|
||||||
|
|
||||||
|
/** 获取token */
|
||||||
|
export function getToken() {
|
||||||
|
return localStg.get('token') || '';
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 获取用户信息 */
|
||||||
|
export function getUserInfo() {
|
||||||
|
const emptyInfo: Auth.UserInfo = {
|
||||||
|
userId: '',
|
||||||
|
userName: '',
|
||||||
|
userRole: 'user'
|
||||||
|
};
|
||||||
|
const userInfo: Auth.UserInfo = localStg.get('userInfo') || emptyInfo;
|
||||||
|
|
||||||
|
return userInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 去除用户相关缓存 */
|
||||||
|
export function clearAuthStorage() {
|
||||||
|
localStg.remove('token');
|
||||||
|
localStg.remove('refreshToken');
|
||||||
|
localStg.remove('userInfo');
|
||||||
|
}
|
@ -3,9 +3,10 @@ import { defineStore } from 'pinia';
|
|||||||
import { router } from '@/router';
|
import { router } from '@/router';
|
||||||
import { fetchLogin, fetchUserInfo } from '@/service';
|
import { fetchLogin, fetchUserInfo } from '@/service';
|
||||||
import { useRouterPush } from '@/composables';
|
import { useRouterPush } from '@/composables';
|
||||||
import { clearAuthStorage, getToken, getUserInfo, setRefreshToken, setToken, setUserInfo } from '@/utils';
|
import { localStg } from '@/utils';
|
||||||
import { useTabStore } from '../tab';
|
import { useTabStore } from '../tab';
|
||||||
import { useRouteStore } from '../route';
|
import { useRouteStore } from '../route';
|
||||||
|
import { getToken, getUserInfo, clearAuthStorage } from './helpers';
|
||||||
|
|
||||||
interface AuthState {
|
interface AuthState {
|
||||||
/** 用户信息 */
|
/** 用户信息 */
|
||||||
@ -81,14 +82,14 @@ export const useAuthStore = defineStore('auth-store', {
|
|||||||
|
|
||||||
// 先把token存储到缓存中(后面接口的请求头需要token)
|
// 先把token存储到缓存中(后面接口的请求头需要token)
|
||||||
const { token, refreshToken } = backendToken;
|
const { token, refreshToken } = backendToken;
|
||||||
setToken(token);
|
localStg.set('token', token);
|
||||||
setRefreshToken(refreshToken);
|
localStg.set('refreshToken', refreshToken);
|
||||||
|
|
||||||
// 获取用户信息
|
// 获取用户信息
|
||||||
const { data } = await fetchUserInfo();
|
const { data } = await fetchUserInfo();
|
||||||
if (data) {
|
if (data) {
|
||||||
// 成功后把用户信息存储到缓存中
|
// 成功后把用户信息存储到缓存中
|
||||||
setUserInfo(data);
|
localStg.set('userInfo', data);
|
||||||
|
|
||||||
// 更新状态
|
// 更新状态
|
||||||
this.userInfo = data;
|
this.userInfo = data;
|
||||||
|
@ -2,10 +2,10 @@ import { defineStore } from 'pinia';
|
|||||||
import { ROOT_ROUTE, constantRoutes, router, routes as staticRoutes } from '@/router';
|
import { ROOT_ROUTE, constantRoutes, router, routes as staticRoutes } from '@/router';
|
||||||
import { fetchUserRoutes } from '@/service';
|
import { fetchUserRoutes } from '@/service';
|
||||||
import {
|
import {
|
||||||
|
localStg,
|
||||||
filterAuthRoutesByUserPermission,
|
filterAuthRoutesByUserPermission,
|
||||||
getCacheRoutes,
|
getCacheRoutes,
|
||||||
getConstantRouteNames,
|
getConstantRouteNames,
|
||||||
getUserInfo,
|
|
||||||
transformAuthRouteToVueRoutes,
|
transformAuthRouteToVueRoutes,
|
||||||
transformAuthRouteToVueRoute,
|
transformAuthRouteToVueRoute,
|
||||||
transformAuthRouteToMenu,
|
transformAuthRouteToMenu,
|
||||||
@ -106,7 +106,12 @@ export const useRouteStore = defineStore('route-store', {
|
|||||||
},
|
},
|
||||||
/** 初始化动态路由 */
|
/** 初始化动态路由 */
|
||||||
async initDynamicRoute() {
|
async initDynamicRoute() {
|
||||||
const { userId } = getUserInfo();
|
const { userId } = localStg.get('userInfo') || {};
|
||||||
|
|
||||||
|
if (!userId) {
|
||||||
|
throw new Error('userId 不能为空!');
|
||||||
|
}
|
||||||
|
|
||||||
const { data } = await fetchUserRoutes(userId);
|
const { data } = await fetchUserRoutes(userId);
|
||||||
if (data) {
|
if (data) {
|
||||||
this.routeHomeName = data.home;
|
this.routeHomeName = data.home;
|
||||||
@ -123,9 +128,6 @@ export const useRouteStore = defineStore('route-store', {
|
|||||||
/** 初始化权限路由 */
|
/** 初始化权限路由 */
|
||||||
async initAuthRoute() {
|
async initAuthRoute() {
|
||||||
const { initHomeTab } = useTabStore();
|
const { initHomeTab } = useTabStore();
|
||||||
const { userId } = getUserInfo();
|
|
||||||
|
|
||||||
if (!userId) return;
|
|
||||||
|
|
||||||
const isDynamicRoute = this.authRouteMode === 'dynamic';
|
const isDynamicRoute = this.authRouteMode === 'dynamic';
|
||||||
if (isDynamicRoute) {
|
if (isDynamicRoute) {
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import type { RouteLocationNormalizedLoaded, RouteRecordNormalized } from 'vue-router';
|
import type { RouteLocationNormalizedLoaded, RouteRecordNormalized } from 'vue-router';
|
||||||
import { EnumStorageKey } from '@/enum';
|
import { localStg } from '@/utils';
|
||||||
import { getLocal, setLocal } from '@/utils';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据vue路由获取tab路由
|
* 根据vue路由获取tab路由
|
||||||
@ -58,15 +57,10 @@ function hasFullPath(
|
|||||||
return Boolean((route as RouteLocationNormalizedLoaded).fullPath);
|
return Boolean((route as RouteLocationNormalizedLoaded).fullPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 缓存多页签数据 */
|
|
||||||
export function setTabRoutes(data: App.GlobalTabRoute[]) {
|
|
||||||
setLocal(EnumStorageKey['multi-tab-routes'], data);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 获取缓存的多页签数据 */
|
/** 获取缓存的多页签数据 */
|
||||||
export function getTabRoutes() {
|
export function getTabRoutes() {
|
||||||
const routes: App.GlobalTabRoute[] = [];
|
const routes: App.GlobalTabRoute[] = [];
|
||||||
const data = getLocal<App.GlobalTabRoute[]>(EnumStorageKey['multi-tab-routes']);
|
const data = localStg.get('multiTabRoutes');
|
||||||
if (data) {
|
if (data) {
|
||||||
const defaultTabRoutes = data.map(item => ({
|
const defaultTabRoutes = data.map(item => ({
|
||||||
...item,
|
...item,
|
||||||
@ -82,5 +76,5 @@ export function getTabRoutes() {
|
|||||||
|
|
||||||
/** 清空多页签数据 */
|
/** 清空多页签数据 */
|
||||||
export function clearTabRoutes() {
|
export function clearTabRoutes() {
|
||||||
setTabRoutes([]);
|
localStg.set('multiTabRoutes', []);
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import type { RouteLocationNormalizedLoaded, Router } from 'vue-router';
|
import type { RouteLocationNormalizedLoaded, Router } from 'vue-router';
|
||||||
import { defineStore } from 'pinia';
|
import { defineStore } from 'pinia';
|
||||||
import { useRouterPush } from '@/composables';
|
import { useRouterPush } from '@/composables';
|
||||||
|
import { localStg } from '@/utils';
|
||||||
import { useThemeStore } from '../theme';
|
import { useThemeStore } from '../theme';
|
||||||
import {
|
import {
|
||||||
clearTabRoutes,
|
clearTabRoutes,
|
||||||
@ -8,8 +9,7 @@ import {
|
|||||||
getIndexInTabRoutesByRouteName,
|
getIndexInTabRoutesByRouteName,
|
||||||
getTabRouteByVueRoute,
|
getTabRouteByVueRoute,
|
||||||
getTabRoutes,
|
getTabRoutes,
|
||||||
isInTabRoutes,
|
isInTabRoutes
|
||||||
setTabRoutes
|
|
||||||
} from './helpers';
|
} from './helpers';
|
||||||
|
|
||||||
interface TabState {
|
interface TabState {
|
||||||
@ -52,7 +52,7 @@ export const useTabStore = defineStore('tab-store', {
|
|||||||
},
|
},
|
||||||
/** 缓存页签路由数据 */
|
/** 缓存页签路由数据 */
|
||||||
cacheTabRoutes() {
|
cacheTabRoutes() {
|
||||||
setTabRoutes(this.tabs);
|
localStg.set('multiTabRoutes', this.tabs);
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* 设置当前路由对应的页签为激活状态
|
* 设置当前路由对应的页签为激活状态
|
||||||
|
@ -1,19 +1,18 @@
|
|||||||
import type { GlobalThemeOverrides } from 'naive-ui';
|
import type { GlobalThemeOverrides } from 'naive-ui';
|
||||||
import { cloneDeep } from 'lodash-es';
|
import { cloneDeep } from 'lodash-es';
|
||||||
import { themeSetting } from '@/settings';
|
import { themeSetting } from '@/settings';
|
||||||
import { EnumStorageKey } from '@/enum';
|
import { localStg, addColorAlpha, getColorPalette } from '@/utils';
|
||||||
import { addColorAlpha, getColorPalette, getLocal, getThemeColor, removeLocal, setLocal } from '@/utils';
|
|
||||||
|
|
||||||
/** 初始化主题配置 */
|
/** 初始化主题配置 */
|
||||||
export function initThemeSettings() {
|
export function initThemeSettings() {
|
||||||
const isProd = import.meta.env.PROD;
|
const isProd = import.meta.env.PROD;
|
||||||
// 生产环境才缓存主题配置,本地开发实时调整配置更改配置的json
|
// 生产环境才缓存主题配置,本地开发实时调整配置更改配置的json
|
||||||
const storageSettings = getThemeSettings();
|
const storageSettings = localStg.get('themeSettings');
|
||||||
if (isProd && storageSettings) {
|
if (isProd && storageSettings) {
|
||||||
return storageSettings;
|
return storageSettings;
|
||||||
}
|
}
|
||||||
|
|
||||||
const themeColor = getThemeColor() || themeSetting.themeColor;
|
const themeColor = localStg.get('themeColor') || themeSetting.themeColor;
|
||||||
const info = themeSetting.isCustomizeInfoColor ? themeSetting.otherColor.info : getColorPalette(themeColor, 7);
|
const info = themeSetting.isCustomizeInfoColor ? themeSetting.otherColor.info : getColorPalette(themeColor, 7);
|
||||||
const otherColor = { ...themeSetting.otherColor, info };
|
const otherColor = { ...themeSetting.otherColor, info };
|
||||||
const setting = cloneDeep({ ...themeSetting, themeColor, otherColor });
|
const setting = cloneDeep({ ...themeSetting, themeColor, otherColor });
|
||||||
@ -78,18 +77,3 @@ export function getNaiveThemeOverrides(colors: Record<ColorType, string>): Globa
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 获取缓存中的主题配置 */
|
|
||||||
function getThemeSettings() {
|
|
||||||
return getLocal<Theme.Setting>(EnumStorageKey['theme-settings']);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 获取缓存中的主题配置 */
|
|
||||||
export function setThemeSettings(settings: Theme.Setting) {
|
|
||||||
return setLocal(EnumStorageKey['theme-settings'], settings);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 清除缓存配置 */
|
|
||||||
export function clearThemeSettings() {
|
|
||||||
removeLocal(EnumStorageKey['theme-settings']);
|
|
||||||
}
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { defineStore } from 'pinia';
|
import { defineStore } from 'pinia';
|
||||||
import { darkTheme } from 'naive-ui';
|
import { darkTheme } from 'naive-ui';
|
||||||
import { clearThemeSettings, getNaiveThemeOverrides, initThemeSettings, setThemeSettings } from './helpers';
|
import { localStg } from '@/utils';
|
||||||
|
import { getNaiveThemeOverrides, initThemeSettings } from './helpers';
|
||||||
|
|
||||||
type ThemeState = Theme.Setting;
|
type ThemeState = Theme.Setting;
|
||||||
|
|
||||||
@ -24,14 +25,14 @@ export const useThemeStore = defineStore('theme-store', {
|
|||||||
actions: {
|
actions: {
|
||||||
/** 重置theme状态 */
|
/** 重置theme状态 */
|
||||||
resetThemeStore() {
|
resetThemeStore() {
|
||||||
clearThemeSettings();
|
localStg.remove('themeSettings');
|
||||||
this.$reset();
|
this.$reset();
|
||||||
},
|
},
|
||||||
/** 缓存主题配置 */
|
/** 缓存主题配置 */
|
||||||
cacheThemeSettings() {
|
cacheThemeSettings() {
|
||||||
const isProd = import.meta.env.PROD;
|
const isProd = import.meta.env.PROD;
|
||||||
if (isProd) {
|
if (isProd) {
|
||||||
setThemeSettings(this.$state);
|
localStg.set('themeSettings', this.$state);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
/** 设置暗黑模式 */
|
/** 设置暗黑模式 */
|
||||||
|
@ -3,7 +3,7 @@ import { useOsTheme } from 'naive-ui';
|
|||||||
import type { GlobalThemeOverrides } from 'naive-ui';
|
import type { GlobalThemeOverrides } from 'naive-ui';
|
||||||
import { useElementSize } from '@vueuse/core';
|
import { useElementSize } from '@vueuse/core';
|
||||||
import { kebabCase } from 'lodash-es';
|
import { kebabCase } from 'lodash-es';
|
||||||
import { setThemeColor } from '@/utils';
|
import { localStg } from '@/utils';
|
||||||
import { useThemeStore } from '../modules';
|
import { useThemeStore } from '../modules';
|
||||||
|
|
||||||
/** 订阅theme store */
|
/** 订阅theme store */
|
||||||
@ -17,7 +17,7 @@ export default function subscribeThemeStore() {
|
|||||||
const stopThemeColor = watch(
|
const stopThemeColor = watch(
|
||||||
() => theme.themeColor,
|
() => theme.themeColor,
|
||||||
newValue => {
|
newValue => {
|
||||||
setThemeColor(newValue);
|
localStg.set('themeColor', newValue);
|
||||||
},
|
},
|
||||||
{ immediate: true }
|
{ immediate: true }
|
||||||
);
|
);
|
||||||
|
22
src/typings/storage.d.ts
vendored
Normal file
22
src/typings/storage.d.ts
vendored
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
declare namespace StorageInterface {
|
||||||
|
/** localStorage的存储数据的类型 */
|
||||||
|
interface Session {
|
||||||
|
demoKey: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** localStorage的存储数据的类型 */
|
||||||
|
interface Local {
|
||||||
|
/** 主题颜色 */
|
||||||
|
themeColor: string;
|
||||||
|
/** 用户token */
|
||||||
|
token: string;
|
||||||
|
/** 用户刷新token */
|
||||||
|
refreshToken: string;
|
||||||
|
/** 用户信息 */
|
||||||
|
userInfo: Auth.UserInfo;
|
||||||
|
/** 主题配置 */
|
||||||
|
themeSettings: Theme.Setting;
|
||||||
|
/** 多页签路由信息 */
|
||||||
|
multiTabRoutes: App.GlobalTabRoute[];
|
||||||
|
}
|
||||||
|
}
|
@ -1 +0,0 @@
|
|||||||
export * from './user';
|
|
@ -1,60 +0,0 @@
|
|||||||
import { EnumStorageKey } from '@/enum';
|
|
||||||
import { getLocal, removeLocal, setLocal } from '../storage';
|
|
||||||
|
|
||||||
/** 设置token */
|
|
||||||
export function setToken(token: string) {
|
|
||||||
setLocal(EnumStorageKey.token, token);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 获取token */
|
|
||||||
export function getToken() {
|
|
||||||
return getLocal<string>(EnumStorageKey.token) || '';
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 去除token */
|
|
||||||
export function removeToken() {
|
|
||||||
removeLocal(EnumStorageKey.token);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 获取refresh token */
|
|
||||||
export function getRefreshToken() {
|
|
||||||
return getLocal<string>(EnumStorageKey['refresh-token']) || '';
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 设置refresh token */
|
|
||||||
export function setRefreshToken(token: string) {
|
|
||||||
setLocal(EnumStorageKey['refresh-token'], token);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 去除refresh token */
|
|
||||||
export function removeRefreshToken() {
|
|
||||||
removeLocal(EnumStorageKey['refresh-token']);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 获取用户信息 */
|
|
||||||
export function getUserInfo() {
|
|
||||||
const emptyInfo: Auth.UserInfo = {
|
|
||||||
userId: '',
|
|
||||||
userName: '',
|
|
||||||
userRole: 'user'
|
|
||||||
};
|
|
||||||
const userInfo: Auth.UserInfo = getLocal<Auth.UserInfo>(EnumStorageKey['user-info']) || emptyInfo;
|
|
||||||
return userInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 设置用户信息 */
|
|
||||||
export function setUserInfo(userInfo: Auth.UserInfo) {
|
|
||||||
setLocal(EnumStorageKey['user-info'], userInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 去除用户信息 */
|
|
||||||
export function removeUserInfo() {
|
|
||||||
removeLocal(EnumStorageKey['user-info']);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 去除用户相关缓存 */
|
|
||||||
export function clearAuthStorage() {
|
|
||||||
removeToken();
|
|
||||||
removeRefreshToken();
|
|
||||||
removeUserInfo();
|
|
||||||
}
|
|
@ -1,6 +1,4 @@
|
|||||||
export * from './typeof';
|
export * from './typeof';
|
||||||
export * from './color';
|
export * from './color';
|
||||||
export * from './number';
|
export * from './number';
|
||||||
export * from './object';
|
|
||||||
export * from './pattern';
|
export * from './pattern';
|
||||||
export * from './theme';
|
|
||||||
|
@ -1,4 +0,0 @@
|
|||||||
/** 设置对象数据 */
|
|
||||||
export function objectAssign<T extends Record<string, any>>(target: T, source: Partial<T>) {
|
|
||||||
Object.assign(target, source);
|
|
||||||
}
|
|
@ -1,16 +0,0 @@
|
|||||||
import { EnumStorageKey } from '@/enum';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 缓存主题颜色
|
|
||||||
* @param color
|
|
||||||
*/
|
|
||||||
export function setThemeColor(color: string) {
|
|
||||||
window.localStorage.setItem(EnumStorageKey['theme-color'], color);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取缓存的主题颜色
|
|
||||||
*/
|
|
||||||
export function getThemeColor() {
|
|
||||||
return window.localStorage.getItem(EnumStorageKey['theme-color']);
|
|
||||||
}
|
|
@ -1,6 +1,5 @@
|
|||||||
export * from './common';
|
export * from './common';
|
||||||
export * from './storage';
|
export * from './storage';
|
||||||
export * from './service';
|
export * from './service';
|
||||||
export * from './auth';
|
|
||||||
export * from './router';
|
export * from './router';
|
||||||
export * from './form';
|
export * from './form';
|
||||||
|
@ -1,45 +1,57 @@
|
|||||||
import { decrypto, encrypto } from '../crypto';
|
import { decrypto, encrypto } from '../crypto';
|
||||||
|
interface StorageData<T> {
|
||||||
interface StorageData {
|
value: T;
|
||||||
value: unknown;
|
|
||||||
expire: number | null;
|
expire: number | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 默认缓存期限为7天 */
|
function createLocalStorage<T extends StorageInterface.Local = StorageInterface.Local>() {
|
||||||
const DEFAULT_CACHE_TIME = 60 * 60 * 24 * 7;
|
/** 默认缓存期限为7天 */
|
||||||
|
const DEFAULT_CACHE_TIME = 60 * 60 * 24 * 7;
|
||||||
|
|
||||||
export function setLocal(key: string, value: unknown, expire: number | null = DEFAULT_CACHE_TIME) {
|
function set<K extends keyof T>(key: K, value: T[K], expire: number | null = DEFAULT_CACHE_TIME) {
|
||||||
const storageData: StorageData = { value, expire: expire !== null ? new Date().getTime() + expire * 1000 : null };
|
const storageData: StorageData<T[K]> = {
|
||||||
const json = encrypto(storageData);
|
value,
|
||||||
window.localStorage.setItem(key, json);
|
expire: expire !== null ? new Date().getTime() + expire * 1000 : null
|
||||||
}
|
};
|
||||||
|
const json = encrypto(storageData);
|
||||||
|
window.localStorage.setItem(key as string, json);
|
||||||
|
}
|
||||||
|
|
||||||
export function getLocal<T>(key: string) {
|
function get<K extends keyof T>(key: K) {
|
||||||
const json = window.localStorage.getItem(key);
|
const json = window.localStorage.getItem(key as string);
|
||||||
if (json) {
|
if (json) {
|
||||||
let storageData: StorageData | null = null;
|
let storageData: StorageData<T[K]> | null = null;
|
||||||
try {
|
try {
|
||||||
storageData = decrypto(json);
|
storageData = decrypto(json);
|
||||||
} catch {
|
} catch {
|
||||||
// 防止解析失败
|
// 防止解析失败
|
||||||
}
|
|
||||||
if (storageData) {
|
|
||||||
const { value, expire } = storageData;
|
|
||||||
// 在有效期内直接返回
|
|
||||||
if (expire === null || expire >= Date.now()) {
|
|
||||||
return value as T;
|
|
||||||
}
|
}
|
||||||
|
if (storageData) {
|
||||||
|
const { value, expire } = storageData;
|
||||||
|
// 在有效期内直接返回
|
||||||
|
if (expire === null || expire >= Date.now()) {
|
||||||
|
return value as T[K];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
remove(key);
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
removeLocal(key);
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return null;
|
|
||||||
|
function remove(key: keyof T) {
|
||||||
|
window.localStorage.removeItem(key as string);
|
||||||
|
}
|
||||||
|
function clear() {
|
||||||
|
window.localStorage.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
set,
|
||||||
|
get,
|
||||||
|
remove,
|
||||||
|
clear
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function removeLocal(key: string) {
|
export const localStg = createLocalStorage();
|
||||||
window.localStorage.removeItem(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function clearLocal() {
|
|
||||||
window.localStorage.clear();
|
|
||||||
}
|
|
||||||
|
@ -25,3 +25,37 @@ export function removeSession(key: string) {
|
|||||||
export function clearSession() {
|
export function clearSession() {
|
||||||
window.sessionStorage.clear();
|
window.sessionStorage.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function createSessionStorage<T extends StorageInterface.Session = StorageInterface.Session>() {
|
||||||
|
function set<K extends keyof T>(key: K, value: T[K]) {
|
||||||
|
const json = encrypto(value);
|
||||||
|
sessionStorage.setItem(key as string, json);
|
||||||
|
}
|
||||||
|
function get<K extends keyof T>(key: K) {
|
||||||
|
const json = sessionStorage.getItem(key as string);
|
||||||
|
let data: T[K] | null = null;
|
||||||
|
if (json) {
|
||||||
|
try {
|
||||||
|
data = decrypto(json);
|
||||||
|
} catch {
|
||||||
|
// 防止解析失败
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
function remove(key: keyof T) {
|
||||||
|
window.sessionStorage.removeItem(key as string);
|
||||||
|
}
|
||||||
|
function clear() {
|
||||||
|
window.sessionStorage.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
set,
|
||||||
|
get,
|
||||||
|
remove,
|
||||||
|
clear
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export const sessionStg = createSessionStorage();
|
||||||
|
Loading…
Reference in New Issue
Block a user