mirror of
https://github.com/certd/certd.git
synced 2026-05-15 12:37:30 +08:00
🔱: [client] sync upgrade with 21 commits [trident-sync]
Update README.md
This commit is contained in:
@@ -0,0 +1,436 @@
|
||||
import { defineStore } from "pinia";
|
||||
import { cloneDeep, get, uniq } from "lodash-es";
|
||||
import router from "/src/router";
|
||||
import { frameworkRoutes } from "/src/router/resolve";
|
||||
// @ts-ignore
|
||||
import { LocalStorage } from "/src/utils/util.storage";
|
||||
import { useUserStore } from "/src/store/modules/user";
|
||||
const OPENED_CACHE_KEY = "TABS_OPENED";
|
||||
|
||||
interface PageState {
|
||||
// 可以在多页 tab 模式下显示的页面
|
||||
pool: Array<any>;
|
||||
// 当前显示的多页面列表
|
||||
opened: Array<any>;
|
||||
// 已经加载多标签页数据 https://github.com/d2-projects/d2-admin/issues/201
|
||||
openedLoaded: boolean;
|
||||
// 当前页面
|
||||
current: "";
|
||||
// 需要缓存的页面 name
|
||||
keepAlive: Array<any>;
|
||||
inited: boolean;
|
||||
}
|
||||
// 判定是否需要缓存
|
||||
const isKeepAlive = (data) => get(data, "meta.cache", false);
|
||||
|
||||
export const usePageStore = defineStore({
|
||||
id: "app.page",
|
||||
state: (): PageState => ({
|
||||
// 可以在多页 tab 模式下显示的页面
|
||||
pool: [],
|
||||
// 当前显示的多页面列表
|
||||
opened: [
|
||||
{
|
||||
name: "index",
|
||||
fullPath: "/index",
|
||||
meta: {
|
||||
title: "首页",
|
||||
auth: false
|
||||
}
|
||||
}
|
||||
],
|
||||
// 已经加载多标签页数据 https://github.com/d2-projects/d2-admin/issues/201
|
||||
openedLoaded: false,
|
||||
// 当前页面
|
||||
current: "",
|
||||
// 需要缓存的页面 name
|
||||
keepAlive: [],
|
||||
inited: false
|
||||
}),
|
||||
getters: {
|
||||
getOpened() {
|
||||
// @ts-ignore
|
||||
return this.opened;
|
||||
},
|
||||
getCurrent(): string {
|
||||
return this.current;
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
/**
|
||||
* @description 确认已经加载多标签页数据 https://github.com/d2-projects/d2-admin/issues/201
|
||||
* @param {Object} context
|
||||
*/
|
||||
async isLoaded() {
|
||||
if (this.openedLoaded) {
|
||||
return true;
|
||||
}
|
||||
return new Promise((resolve) => {
|
||||
const timer = setInterval(() => {
|
||||
if (this.openedLoaded) {
|
||||
resolve(clearInterval(timer));
|
||||
}
|
||||
}, 10);
|
||||
});
|
||||
},
|
||||
/**
|
||||
* @class opened
|
||||
* @description 从持久化数据载入标签页列表
|
||||
* @param {Object} context
|
||||
*/
|
||||
async openedLoad() {
|
||||
// store 赋值
|
||||
const value = LocalStorage.get(this.getStorageKey());
|
||||
if (value == null) {
|
||||
return;
|
||||
}
|
||||
// 在处理函数中进行数据优化 过滤掉现在已经失效的页签或者已经改变了信息的页签
|
||||
// 以 fullPath 字段为准
|
||||
// 如果页面过多的话可能需要优化算法
|
||||
// valid 有效列表 1, 1, 0, 1 => 有效, 有效, 失效, 有效
|
||||
const valid: Array<number> = [];
|
||||
// 处理数据
|
||||
this.opened = value
|
||||
.map((opened) => {
|
||||
// 忽略首页
|
||||
if (opened.fullPath === "/index") {
|
||||
valid.push(1);
|
||||
return opened;
|
||||
}
|
||||
// 尝试在所有的支持多标签页的页面里找到 name 匹配的页面
|
||||
const find = this.pool.find((item) => item.name === opened.name);
|
||||
// 记录有效或无效信息
|
||||
valid.push(find ? 1 : 0);
|
||||
// 返回合并后的数据 新的覆盖旧的
|
||||
// 新的数据中一般不会携带 params 和 query, 所以旧的参数会留存
|
||||
return Object.assign({}, opened, find);
|
||||
})
|
||||
.filter((opened, index) => valid[index] === 1);
|
||||
// 标记已经加载多标签页数据 https://github.com/d2-projects/d2-admin/issues/201
|
||||
this.openedLoaded = true;
|
||||
// 根据 opened 数据生成缓存设置
|
||||
this.keepAliveRefresh();
|
||||
},
|
||||
|
||||
getStorageKey() {
|
||||
const userStore = useUserStore();
|
||||
const userId = userStore.getUserInfo?.id ?? "anonymous";
|
||||
return OPENED_CACHE_KEY + ":" + userId;
|
||||
},
|
||||
/**
|
||||
* 将 opened 属性赋值并持久化 在这之前请先确保已经更新了 state.opened
|
||||
* @param {Object} context
|
||||
*/
|
||||
async opened2db() {
|
||||
// 设置数据
|
||||
|
||||
LocalStorage.set(this.getStorageKey(), this.opened);
|
||||
},
|
||||
/**
|
||||
* @class opened
|
||||
* @description 更新页面列表上的某一项
|
||||
* @param {Object} context
|
||||
* @param {Object} payload { index, params, query, fullPath } 路由信息
|
||||
*/
|
||||
async openedUpdate({ index, params, query, fullPath }) {
|
||||
// 更新页面列表某一项
|
||||
const page = this.opened[index];
|
||||
page.params = params || page.params;
|
||||
page.query = query || page.query;
|
||||
page.fullPath = fullPath || page.fullPath;
|
||||
this.opened.splice(index, 1, page);
|
||||
// 持久化
|
||||
await this.opened2db();
|
||||
},
|
||||
/**
|
||||
* @class opened
|
||||
* @description 重排页面列表上的某一项
|
||||
* @param {Object} context
|
||||
* @param {Object} payload { oldIndex, newIndex } 位置信息
|
||||
*/
|
||||
async openedSort({ oldIndex, newIndex }) {
|
||||
// 重排页面列表某一项
|
||||
const page = this.opened[oldIndex];
|
||||
this.opened.splice(oldIndex, 1);
|
||||
this.opened.splice(newIndex, 0, page);
|
||||
// 持久化
|
||||
await this.opened2db();
|
||||
},
|
||||
/**
|
||||
* @class opened
|
||||
* @description 新增一个 tag (打开一个页面)
|
||||
* @param {Object} context
|
||||
* @param {Object} payload new tag info
|
||||
*/
|
||||
async add({ tag, params, query, fullPath }) {
|
||||
// 设置新的 tag 在新打开一个以前没打开过的页面时使用
|
||||
const newTag = tag;
|
||||
newTag.params = params || newTag.params;
|
||||
newTag.query = query || newTag.query;
|
||||
newTag.fullPath = fullPath || newTag.fullPath;
|
||||
// 添加进当前显示的页面数组
|
||||
this.opened.push(newTag);
|
||||
// 如果这个页面需要缓存 将其添加到缓存设置
|
||||
if (isKeepAlive(newTag)) {
|
||||
this.keepAlivePush(tag.name);
|
||||
}
|
||||
// 持久化
|
||||
await this.opened2db();
|
||||
},
|
||||
/**
|
||||
* @class current
|
||||
* @description 打开一个新的页面
|
||||
* @param {Object} context
|
||||
* @param {Object} payload 从路由钩子的 to 对象上获取 { name, params, query, fullPath, meta } 路由信息
|
||||
*/
|
||||
async open({ name, params, query, fullPath, meta }) {
|
||||
// 已经打开的页面
|
||||
const opened = this.opened;
|
||||
// 判断此页面是否已经打开 并且记录位置
|
||||
let pageOpendIndex = 0;
|
||||
const pageOpend = opened.find((page, index) => {
|
||||
const same = page.fullPath === fullPath;
|
||||
pageOpendIndex = same ? index : pageOpendIndex;
|
||||
return same;
|
||||
});
|
||||
if (pageOpend) {
|
||||
// 页面以前打开过
|
||||
await this.openedUpdate({
|
||||
index: pageOpendIndex,
|
||||
params,
|
||||
query,
|
||||
fullPath
|
||||
});
|
||||
} else {
|
||||
// 页面以前没有打开过
|
||||
const page = this.pool.find((t) => t.name === name);
|
||||
// 如果这里没有找到 page 代表这个路由虽然在框架内 但是不参与标签页显示
|
||||
if (page) {
|
||||
this.add({
|
||||
tag: Object.assign({}, page),
|
||||
params,
|
||||
query,
|
||||
fullPath
|
||||
});
|
||||
}
|
||||
}
|
||||
// 如果这个页面需要缓存 将其添加到缓存设置
|
||||
if (isKeepAlive({ meta })) {
|
||||
this.keepAlivePush(name);
|
||||
}
|
||||
// 设置当前的页面
|
||||
this.currentSet(fullPath);
|
||||
},
|
||||
/**
|
||||
* @class opened
|
||||
* @description 关闭一个 tag (关闭一个页面)
|
||||
* @param {Object} context
|
||||
* @param {Object} payload { tagName: 要关闭的标签名字 }
|
||||
*/
|
||||
async close({ tagName }) {
|
||||
// 预定下个新页面
|
||||
let newPage = {};
|
||||
const isCurrent = this.current === tagName;
|
||||
// 如果关闭的页面就是当前显示的页面
|
||||
if (isCurrent) {
|
||||
// 去找一个新的页面
|
||||
const len = this.opened.length;
|
||||
for (let i = 0; i < len; i++) {
|
||||
if (this.opened[i].fullPath === tagName) {
|
||||
newPage = i < len - 1 ? this.opened[i + 1] : this.opened[i - 1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// 找到这个页面在已经打开的数据里是第几个
|
||||
const index = this.opened.findIndex((page) => page.fullPath === tagName);
|
||||
if (index >= 0) {
|
||||
// 如果这个页面是缓存的页面 将其在缓存设置中删除
|
||||
this.keepAliveRemove(this.opened[index].name);
|
||||
// 更新数据 删除关闭的页面
|
||||
this.opened.splice(index, 1);
|
||||
}
|
||||
// 持久化
|
||||
await this.opened2db();
|
||||
// 决定最后停留的页面
|
||||
if (isCurrent) {
|
||||
// @ts-ignore
|
||||
const { name = "index", params = {}, query = {} } = newPage;
|
||||
const routerObj = { name, params, query };
|
||||
await router.push(routerObj);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* @class opened
|
||||
* @description 关闭当前标签左边的标签
|
||||
* @param opts
|
||||
*/
|
||||
async closeLeft(opts = {}) {
|
||||
await this.closeByCondition({
|
||||
condition({ i, currentIndex }) {
|
||||
return i >= currentIndex;
|
||||
},
|
||||
...opts
|
||||
});
|
||||
},
|
||||
/**
|
||||
* @class opened
|
||||
* @description 关闭当前标签右边的标签
|
||||
* @param opts
|
||||
*/
|
||||
async closeRight(opts = {}) {
|
||||
await this.closeByCondition({
|
||||
condition({ i, currentIndex }) {
|
||||
return currentIndex >= i;
|
||||
},
|
||||
...opts
|
||||
});
|
||||
},
|
||||
/**
|
||||
* @class opened
|
||||
* @description 关闭当前标签右边的标签
|
||||
* @param opts
|
||||
*/
|
||||
async closeByCondition(opts = {}) {
|
||||
// @ts-ignore
|
||||
const { pageSelect, condition } = opts;
|
||||
const pageAim = pageSelect || this.current;
|
||||
let currentIndex = 0;
|
||||
this.opened.forEach((page, index) => {
|
||||
if (page.fullPath === pageAim) currentIndex = index;
|
||||
});
|
||||
// 删除打开的页面 并在缓存设置中删除
|
||||
for (let i = this.opened.length - 1; i >= 0; i--) {
|
||||
if (this.opened[i].name === "index" || condition({ i, currentIndex })) {
|
||||
continue;
|
||||
}
|
||||
this.keepAliveRemove(this.opened[i].name);
|
||||
this.opened.splice(i, 1);
|
||||
}
|
||||
// 持久化
|
||||
await this.opened2db();
|
||||
// 设置当前的页面
|
||||
this.current = pageAim;
|
||||
// @ts-ignore
|
||||
if (router.currentRoute.fullPath !== pageAim) await router.push(pageAim);
|
||||
},
|
||||
/**
|
||||
* @class opened
|
||||
* @description 关闭当前激活之外的 tag
|
||||
* @param opts
|
||||
*/
|
||||
async closeOther(opts = {}) {
|
||||
await this.closeByCondition({
|
||||
condition({ i, currentIndex }) {
|
||||
return currentIndex === i;
|
||||
},
|
||||
...opts
|
||||
});
|
||||
},
|
||||
/**
|
||||
* @class opened
|
||||
* @description 关闭所有 tag
|
||||
* @param {Object} context
|
||||
*/
|
||||
async closeAll() {
|
||||
// 删除打开的页面 并在缓存设置中删除
|
||||
for (let i = this.opened.length - 1; i >= 0; i--) {
|
||||
if (this.opened[i].name === "index") {
|
||||
continue;
|
||||
}
|
||||
|
||||
this.keepAliveRemove(this.opened[i].name);
|
||||
this.opened.splice(i, 1);
|
||||
}
|
||||
// 持久化
|
||||
await this.opened2db();
|
||||
// 关闭所有的标签页后需要判断一次现在是不是在首页
|
||||
// @ts-ignore
|
||||
if (router.currentRoute.name !== "index") {
|
||||
await router.push({ name: "index" });
|
||||
}
|
||||
},
|
||||
/**
|
||||
* @class keepAlive
|
||||
* @description 从已经打开的页面记录中更新需要缓存的页面记录
|
||||
* @param {Object} state state
|
||||
*/
|
||||
keepAliveRefresh() {
|
||||
this.keepAlive = this.opened.filter((item) => isKeepAlive(item)).map((e) => e.name);
|
||||
console.log("keep alive:", this.keepAlive);
|
||||
},
|
||||
/**
|
||||
* @description 删除一个页面的缓存设置
|
||||
* @param {Object} state state
|
||||
* @param {String} name name
|
||||
*/
|
||||
keepAliveRemove(name) {
|
||||
const list = cloneDeep(this.keepAlive);
|
||||
const index = list.findIndex((item) => item === name);
|
||||
if (index !== -1) {
|
||||
list.splice(index, 1);
|
||||
this.keepAlive = list;
|
||||
}
|
||||
},
|
||||
/**
|
||||
* @description 增加一个页面的缓存设置
|
||||
* @param {Object} state state
|
||||
* @param {String} name name
|
||||
*/
|
||||
keepAlivePush(name) {
|
||||
const keep = cloneDeep(this.keepAlive);
|
||||
keep.push(name);
|
||||
this.keepAlive = uniq(keep);
|
||||
},
|
||||
/**
|
||||
* @description 清空页面缓存设置
|
||||
* @param {Object} state state
|
||||
*/
|
||||
keepAliveClean() {
|
||||
this.keepAlive = [];
|
||||
},
|
||||
/**
|
||||
* @class current
|
||||
* @description 设置当前激活的页面 fullPath
|
||||
* @param {Object} state state
|
||||
* @param {String} fullPath new fullPath
|
||||
*/
|
||||
currentSet(fullPath) {
|
||||
this.current = fullPath;
|
||||
},
|
||||
/**
|
||||
* @class pool
|
||||
* @description 保存 pool (候选池)
|
||||
* @param {Object} state state
|
||||
* @param {Array} routes routes
|
||||
*/
|
||||
async init(routes) {
|
||||
if (this.inited) {
|
||||
return;
|
||||
}
|
||||
this.inited = true;
|
||||
if (routes == null) {
|
||||
//不能用全部的routes,只能是framework内的
|
||||
routes = frameworkRoutes;
|
||||
}
|
||||
|
||||
const pool = [];
|
||||
const push = function (routes) {
|
||||
routes.forEach((route) => {
|
||||
if (route.children && route.children.length > 0) {
|
||||
push(route.children);
|
||||
} else {
|
||||
if (!route.hidden) {
|
||||
const { meta, name, path } = route;
|
||||
// @ts-ignore
|
||||
pool.push({ meta, name, path });
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
push(routes);
|
||||
this.pool = pool;
|
||||
await this.openedLoad();
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,127 @@
|
||||
import { defineStore } from "pinia";
|
||||
// @ts-ignore
|
||||
import { frameworkMenus, headerMenus, filterMenus, findMenus } from "/src/router/resolve";
|
||||
import _ from "lodash-es";
|
||||
import { mitter } from "/src/utils/util.mitt";
|
||||
//监听注销事件
|
||||
mitter.on("app.logout", () => {
|
||||
const resourceStore = useResourceStore();
|
||||
resourceStore.clear();
|
||||
});
|
||||
|
||||
interface ResourceState {
|
||||
frameworkMenus: Array<any>;
|
||||
headerMenus: Array<any>;
|
||||
asideMenus: Array<any>;
|
||||
fixedAsideMenus: Array<any>;
|
||||
inited: boolean;
|
||||
currentAsidePath: string;
|
||||
}
|
||||
|
||||
export const useResourceStore = defineStore({
|
||||
id: "app.resource",
|
||||
state: (): ResourceState => ({
|
||||
// user info
|
||||
frameworkMenus: [],
|
||||
headerMenus: [],
|
||||
asideMenus: [],
|
||||
fixedAsideMenus: [],
|
||||
inited: false,
|
||||
currentAsidePath: ""
|
||||
}),
|
||||
getters: {
|
||||
getAsideMenus() {
|
||||
return this.asideMenus;
|
||||
},
|
||||
getHeaderMenus() {
|
||||
return this.headerMenus;
|
||||
},
|
||||
getFrameworkMenus() {
|
||||
return this.frameworkMenus;
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
clear() {
|
||||
this.inited = false;
|
||||
},
|
||||
/**
|
||||
* 初始化资源
|
||||
*/
|
||||
init() {
|
||||
if (this.inited) {
|
||||
return;
|
||||
}
|
||||
this.inited = true;
|
||||
|
||||
const showMenus = _.cloneDeep(frameworkMenus[0].children);
|
||||
this.frameworkMenus = filterMenus(showMenus, (item) => {
|
||||
return item?.meta?.showOnHeader !== false;
|
||||
});
|
||||
|
||||
this.fixedAsideMenus = findMenus(showMenus, (item) => {
|
||||
return item?.meta?.fixedAside === true;
|
||||
});
|
||||
this.headerMenus = headerMenus;
|
||||
this.setAsideMenu();
|
||||
},
|
||||
setAsideMenu(topMenu?) {
|
||||
if (this.frameworkMenus.length === 0) {
|
||||
return;
|
||||
}
|
||||
if (topMenu == null) {
|
||||
topMenu = this.frameworkMenus[0];
|
||||
}
|
||||
const asideMenus = topMenu?.children || [];
|
||||
this.asideMenus = [...this.fixedAsideMenus, ...asideMenus];
|
||||
},
|
||||
setAsideMenuByCurrentRoute(matched) {
|
||||
const menuHeader = this.frameworkMenus;
|
||||
if (matched?.length <= 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
function findFromTree(tree, find) {
|
||||
const results: Array<any> = [];
|
||||
for (const item of tree) {
|
||||
if (find(item)) {
|
||||
results.push(item);
|
||||
return results;
|
||||
}
|
||||
if (item.children && item.children.length > 0) {
|
||||
const found = findFromTree(item.children, find);
|
||||
if (found) {
|
||||
results.push(item);
|
||||
return results.concat(found);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
const matchedPath = matched[1].path;
|
||||
const _side = findFromTree(menuHeader, (menu) => menu.path === matchedPath);
|
||||
if (_side?.length > 0) {
|
||||
if (this.currentAsidePath === _side[0]) {
|
||||
return;
|
||||
}
|
||||
this.currentAsidePath = _side[0];
|
||||
this.setAsideMenu(_side[0]);
|
||||
}
|
||||
},
|
||||
filterByPermission(permissions) {
|
||||
this.frameworkMenus = this.filterChildrenByPermission(this.frameworkMenus, permissions);
|
||||
},
|
||||
filterChildrenByPermission(list, permissions) {
|
||||
const menus = list.filter((item) => {
|
||||
if (item?.meta?.permission) {
|
||||
return permissions.includes(item.meta.permission);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
for (const menu of menus) {
|
||||
if (menu.children && menu.children.length > 0) {
|
||||
menu.children = this.filterChildrenByPermission(menu.children, permissions);
|
||||
}
|
||||
}
|
||||
return menus;
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,63 @@
|
||||
import { defineStore } from "pinia";
|
||||
// @ts-ignore
|
||||
import { LocalStorage } from "/src/utils/util.storage";
|
||||
// import { replaceStyleVariables } from "vite-plugin-theme/es/client";
|
||||
|
||||
// import { getThemeColors, generateColors } from "/src/../build/theme-colors";
|
||||
//
|
||||
// import { mixLighten, mixDarken, tinycolor } from "vite-plugin-theme/es/colorUtils";
|
||||
|
||||
// export async function changeTheme(color?: string) {
|
||||
// if (color == null) {
|
||||
// return;
|
||||
// }
|
||||
// const colors = generateColors({
|
||||
// mixDarken,
|
||||
// mixLighten,
|
||||
// tinycolor,
|
||||
// color
|
||||
// });
|
||||
//
|
||||
// return await replaceStyleVariables({
|
||||
// colorVariables: [...getThemeColors(color), ...colors]
|
||||
// });
|
||||
// }
|
||||
|
||||
interface SettingState {
|
||||
theme: any;
|
||||
}
|
||||
|
||||
const SETTING_THEME_KEY = "SETTING_THEME";
|
||||
export const useSettingStore = defineStore({
|
||||
id: "app.setting",
|
||||
state: (): SettingState => ({
|
||||
// user info
|
||||
theme: null
|
||||
}),
|
||||
getters: {
|
||||
getTheme(): any {
|
||||
return this.theme || LocalStorage.get(SETTING_THEME_KEY) || {};
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
persistTheme() {
|
||||
LocalStorage.set(SETTING_THEME_KEY, this.getTheme);
|
||||
},
|
||||
async setTheme(theme?: Object) {
|
||||
if (theme == null) {
|
||||
theme = this.getTheme;
|
||||
}
|
||||
this.theme = theme;
|
||||
this.persistTheme();
|
||||
// await changeTheme(this.theme.primaryColor);
|
||||
},
|
||||
async setPrimaryColor(color) {
|
||||
const theme = this.theme;
|
||||
theme.primaryColor = color;
|
||||
await this.setTheme();
|
||||
},
|
||||
async init() {
|
||||
await this.setTheme(this.getTheme);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,106 @@
|
||||
import { defineStore } from "pinia";
|
||||
import { store } from "../index";
|
||||
import router from "../../router";
|
||||
// @ts-ignore
|
||||
import { LocalStorage } from "/src/utils/util.storage";
|
||||
// @ts-ignore
|
||||
import * as UserApi from "/src/api/modules/api.user";
|
||||
// @ts-ignore
|
||||
import { LoginReq, UserInfoRes } from "/@/api/modules/api.user";
|
||||
import { Modal } from "ant-design-vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
|
||||
import { mitter } from "/src/utils/util.mitt";
|
||||
|
||||
interface UserState {
|
||||
userInfo: Nullable<UserInfoRes>;
|
||||
token?: string;
|
||||
}
|
||||
|
||||
const USER_INFO_KEY = "USER_INFO";
|
||||
const TOKEN_KEY = "TOKEN";
|
||||
export const useUserStore = defineStore({
|
||||
id: "app.user",
|
||||
state: (): UserState => ({
|
||||
// user info
|
||||
userInfo: null,
|
||||
// token
|
||||
token: undefined
|
||||
}),
|
||||
getters: {
|
||||
getUserInfo(): UserInfoRes {
|
||||
return this.userInfo || LocalStorage.get(USER_INFO_KEY) || {};
|
||||
},
|
||||
getToken(): string {
|
||||
return this.token || LocalStorage.get(TOKEN_KEY);
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
setToken(info: string, expire: number) {
|
||||
this.token = info;
|
||||
LocalStorage.set(TOKEN_KEY, this.token, expire);
|
||||
},
|
||||
setUserInfo(info: UserInfoRes) {
|
||||
this.userInfo = info;
|
||||
LocalStorage.set(USER_INFO_KEY, info);
|
||||
},
|
||||
resetState() {
|
||||
this.userInfo = null;
|
||||
this.token = "";
|
||||
LocalStorage.remove(TOKEN_KEY);
|
||||
LocalStorage.remove(USER_INFO_KEY);
|
||||
},
|
||||
/**
|
||||
* @description: login
|
||||
*/
|
||||
async login(params: LoginReq): Promise<any> {
|
||||
try {
|
||||
const data = await UserApi.login(params);
|
||||
const { token, expire } = data;
|
||||
|
||||
// save token
|
||||
this.setToken(token, expire);
|
||||
// get user info
|
||||
const userInfo = await this.getUserInfoAction();
|
||||
await router.replace("/");
|
||||
mitter.emit("app.login", { userInfo, token: data });
|
||||
return userInfo;
|
||||
} catch (error) {
|
||||
return null;
|
||||
}
|
||||
},
|
||||
async getUserInfoAction(): Promise<UserInfoRes> {
|
||||
const userInfo = await UserApi.mine();
|
||||
this.setUserInfo(userInfo);
|
||||
return userInfo;
|
||||
},
|
||||
/**
|
||||
* @description: logout
|
||||
*/
|
||||
logout(goLogin = true) {
|
||||
this.resetState();
|
||||
goLogin && router.push("/login");
|
||||
mitter.emit("app.logout");
|
||||
},
|
||||
|
||||
/**
|
||||
* @description: Confirm before logging out
|
||||
*/
|
||||
confirmLoginOut() {
|
||||
const { t } = useI18n();
|
||||
Modal.config({
|
||||
iconType: "warning",
|
||||
title: t("app.login.logoutTip"),
|
||||
content: t("app.login.logoutMessage"),
|
||||
onOk: async () => {
|
||||
await this.logout(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Need to be used outside the setup
|
||||
export function useUserStoreWidthOut() {
|
||||
return useUserStore(store);
|
||||
}
|
||||
Reference in New Issue
Block a user