refactor: 界面优化和使用sse替换websocket
This commit is contained in:
@@ -59,58 +59,40 @@ export function clearTokens(): void {
|
||||
Storage.remove(REFRESH_TOKEN_KEY);
|
||||
}
|
||||
|
||||
function getCurrentPagePath(): string {
|
||||
const pages = getCurrentPages();
|
||||
if (pages.length === 0) return "/pages/index/index";
|
||||
|
||||
const currentPage = pages[pages.length - 1];
|
||||
const route = currentPage.route || "";
|
||||
const options = (currentPage as any).options || {};
|
||||
|
||||
const query = Object.entries(options)
|
||||
.map(([key, value]) => `${key}=${value}`)
|
||||
.join("&");
|
||||
|
||||
return query ? `/${route}?${query}` : `/${route}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查用户登录状态,未登录则跳转到登录页面
|
||||
* @param silent 是否静默检查,不跳转登录页面
|
||||
* @returns 返回用户是否已登录
|
||||
*/
|
||||
export function checkLogin(silent: boolean = false): boolean {
|
||||
const accessToken = getAccessToken();
|
||||
if (getAccessToken()) return true;
|
||||
|
||||
// 检查 token 是否存在
|
||||
const isLoggedIn = !!accessToken;
|
||||
|
||||
if (!isLoggedIn && !silent) {
|
||||
try {
|
||||
// 获取当前页面路径
|
||||
let currentPagePath = "/pages/index/index"; // 默认路径
|
||||
|
||||
const pages = getCurrentPages();
|
||||
if (pages && pages.length > 0) {
|
||||
const currentPage = pages[pages.length - 1];
|
||||
if (currentPage && currentPage.route) {
|
||||
currentPagePath = `/${currentPage.route}`;
|
||||
|
||||
// 处理页面参数 - 使用类型断言
|
||||
const pageOptions = (currentPage as any).options;
|
||||
if (pageOptions && Object.keys(pageOptions).length > 0) {
|
||||
const params = new URLSearchParams(pageOptions as Record<string, string>);
|
||||
currentPagePath += `?${params.toString()}`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 跳转到登录页面
|
||||
uni.navigateTo({
|
||||
url: `/pages/login/index?redirect=${encodeURIComponent(currentPagePath)}`,
|
||||
fail: (error) => {
|
||||
console.error("跳转登录页面失败:", error);
|
||||
// 如果 navigateTo 失败,尝试使用 reLaunch
|
||||
uni.reLaunch({
|
||||
url: "/pages/login/index",
|
||||
});
|
||||
},
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("检查登录状态时发生错误:", error);
|
||||
// 发生错误时,尝试直接跳转到登录页
|
||||
uni.reLaunch({
|
||||
url: "/pages/login/index",
|
||||
});
|
||||
}
|
||||
if (!silent) {
|
||||
const redirect = encodeURIComponent(getCurrentPagePath());
|
||||
uni.navigateTo({
|
||||
url: `/pages/login/index?redirect=${redirect}`,
|
||||
fail: () => {
|
||||
uni.reLaunch({ url: "/pages/login/index" });
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
return isLoggedIn;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
18
src/utils/format.ts
Normal file
18
src/utils/format.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
export function formatBytes(size: number): string {
|
||||
if (size < 1024) {
|
||||
return size + "B";
|
||||
} else if (size < 1024 * 1024) {
|
||||
return (size / 1024).toFixed(2) + "KB";
|
||||
} else {
|
||||
return (size / 1024 / 1024).toFixed(2) + "MB";
|
||||
}
|
||||
}
|
||||
|
||||
export function formatNumber(num: number): string {
|
||||
if (num >= 10000) {
|
||||
return (num / 10000).toFixed(1) + "w";
|
||||
} else if (num >= 1000) {
|
||||
return (num / 1000).toFixed(1) + "k";
|
||||
}
|
||||
return String(num);
|
||||
}
|
||||
@@ -1,155 +1,42 @@
|
||||
import { useUserStore } from "@/store";
|
||||
import { ROLE_ROOT, PERM_ALL } from "@/constants";
|
||||
|
||||
/**
|
||||
* 检查是否拥有指定权限
|
||||
*
|
||||
* @param permission 权限标识,支持字符串或字符串数组(满足其一即可)
|
||||
* @returns 是否拥有权限
|
||||
*
|
||||
* @example
|
||||
* hasPermission('sys:user:create') // 检查单个权限
|
||||
* hasPermission(['sys:user:create', 'sys:user:update']) // 满足其一即可
|
||||
*/
|
||||
export function hasPermission(permission: string | string[]): boolean {
|
||||
// 参数校验
|
||||
if (!permission) {
|
||||
console.warn("[Permission] 需要提供权限标识");
|
||||
return false;
|
||||
}
|
||||
type AccessType = "perm" | "role";
|
||||
type CheckMode = "some" | "every";
|
||||
|
||||
// 标准化为数组
|
||||
const permissions = Array.isArray(permission) ? permission : [permission];
|
||||
function checkAccess(type: AccessType, keys: string | string[], mode: CheckMode = "some"): boolean {
|
||||
if (!keys) return false;
|
||||
|
||||
// 空数组校验
|
||||
if (permissions.length === 0) {
|
||||
console.warn("[Permission] 权限标识数组不能为空");
|
||||
return false;
|
||||
}
|
||||
const keyArray = Array.isArray(keys) ? keys : [keys];
|
||||
if (keyArray.length === 0) return false;
|
||||
|
||||
const userStore = useUserStore();
|
||||
const userInfo = userStore.userInfo;
|
||||
|
||||
// 未登录或无用户信息
|
||||
if (!userInfo) {
|
||||
return false;
|
||||
}
|
||||
const userInfo = useUserStore().userInfo;
|
||||
if (!userInfo) return false;
|
||||
|
||||
const { roles = [], perms = [] } = userInfo;
|
||||
|
||||
// 超级管理员拥有所有权限
|
||||
if (roles.includes(ROLE_ROOT)) {
|
||||
return true;
|
||||
}
|
||||
if (roles.includes(ROLE_ROOT)) return true;
|
||||
|
||||
// 检查是否包含全部权限标识
|
||||
if (permissions.includes(PERM_ALL)) {
|
||||
return true;
|
||||
}
|
||||
if (type === "perm" && keyArray.includes(PERM_ALL)) return true;
|
||||
|
||||
// 检查权限:满足其一即可
|
||||
return permissions.some((perm) => perms.includes(perm));
|
||||
const userKeys = type === "perm" ? perms : roles;
|
||||
if (!userKeys || userKeys.length === 0) return false;
|
||||
|
||||
return keyArray[mode]((key) => userKeys.includes(key));
|
||||
}
|
||||
|
||||
export function hasPermission(perm: string | string[]): boolean {
|
||||
return checkAccess("perm", perm, "some");
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否拥有指定角色
|
||||
*
|
||||
* @param role 角色标识,支持字符串或字符串数组(满足其一即可)
|
||||
* @returns 是否拥有角色
|
||||
*
|
||||
* @example
|
||||
* hasRole('ADMIN') // 检查单个角色
|
||||
* hasRole(['ADMIN', 'TEST']) // 满足其一即可
|
||||
*/
|
||||
export function hasRole(role: string | string[]): boolean {
|
||||
// 参数校验
|
||||
if (!role) {
|
||||
console.warn("[Permission] 需要提供角色标识");
|
||||
return false;
|
||||
}
|
||||
|
||||
// 标准化为数组
|
||||
const roles = Array.isArray(role) ? role : [role];
|
||||
|
||||
// 空数组校验
|
||||
if (roles.length === 0) {
|
||||
console.warn("[Permission] 角色标识数组不能为空");
|
||||
return false;
|
||||
}
|
||||
|
||||
const userStore = useUserStore();
|
||||
const userInfo = userStore.userInfo;
|
||||
|
||||
// 未登录或无用户信息
|
||||
if (!userInfo) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const userRoles = userInfo.roles || [];
|
||||
|
||||
// 超级管理员拥有所有角色
|
||||
if (userRoles.includes(ROLE_ROOT)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// 检查角色:满足其一即可
|
||||
return roles.some((r) => userRoles.includes(r));
|
||||
return checkAccess("role", role, "some");
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否拥有所有指定权限(且关系)
|
||||
*
|
||||
* @param permissions 权限标识数组
|
||||
* @returns 是否拥有所有权限
|
||||
*/
|
||||
export function hasAllPermissions(permissions: string[]): boolean {
|
||||
if (!permissions || permissions.length === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const userStore = useUserStore();
|
||||
const userInfo = userStore.userInfo;
|
||||
|
||||
if (!userInfo) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const { roles = [], perms = [] } = userInfo;
|
||||
|
||||
// 超级管理员拥有所有权限
|
||||
if (roles.includes(ROLE_ROOT)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// 检查权限:必须全部满足
|
||||
return permissions.every((perm) => perms.includes(perm));
|
||||
export function hasAllPermissions(perms: string | string[]): boolean {
|
||||
return checkAccess("perm", perms, "every");
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否拥有所有指定角色(且关系)
|
||||
*
|
||||
* @param roles 角色标识数组
|
||||
* @returns 是否拥有所有角色
|
||||
*/
|
||||
export function hasAllRoles(roles: string[]): boolean {
|
||||
if (!roles || roles.length === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const userStore = useUserStore();
|
||||
const userInfo = userStore.userInfo;
|
||||
|
||||
if (!userInfo) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const userRoles = userInfo.roles || [];
|
||||
|
||||
// 超级管理员拥有所有角色
|
||||
if (userRoles.includes(ROLE_ROOT)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// 检查角色:必须全部满足
|
||||
return roles.every((role) => userRoles.includes(role));
|
||||
export function hasAllRoles(roles: string | string[]): boolean {
|
||||
return checkAccess("role", roles, "every");
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { getAccessToken, clearTokens } from "./auth";
|
||||
import { getAccessToken, clearTokens } from "./auth";
|
||||
import { ApiCode } from "@/enums/api-code-enum";
|
||||
|
||||
// 401 跳转防抖锁,避免并发请求多次跳转登录页
|
||||
let isRedirecting401 = false;
|
||||
@@ -92,7 +93,7 @@ function request<T = any>(options: RequestOptions): Promise<T> {
|
||||
|
||||
// HTTP 成功:校验业务码
|
||||
if (res.statusCode >= 200 && res.statusCode < 300) {
|
||||
if (!serverCode || serverCode === "00000") {
|
||||
if (!serverCode || serverCode === ApiCode.SUCCESS) {
|
||||
resolve(res.data.data);
|
||||
} else {
|
||||
reject(new RequestError(serverMsg || "请求失败", res.statusCode, serverCode));
|
||||
|
||||
Reference in New Issue
Block a user