docs: add comments to the src/routes & src/store & src/utils directory
This commit is contained in:
@@ -1,11 +1,22 @@
|
||||
/*
|
||||
* @Description:
|
||||
* @Version: 0.0.1
|
||||
* @Author: yujiangping
|
||||
* @Date: 2026-01-05 17:22:23
|
||||
* @LastEditors: yujiangping
|
||||
* @LastEditTime: 2026-01-15 21:02:43
|
||||
* @Author: ZhaoYing
|
||||
* @Date: 2026-02-02 16:33:22
|
||||
* @Last Modified by: ZhaoYing
|
||||
* @Last Modified time: 2026-02-02 16:33:22
|
||||
*/
|
||||
/**
|
||||
* Locale Store
|
||||
*
|
||||
* Manages internationalization (i18n) and localization with:
|
||||
* - Language switching (English/Chinese)
|
||||
* - Timezone management
|
||||
* - Ant Design locale configuration
|
||||
* - Custom Tour component translations
|
||||
* - Day.js timezone support
|
||||
*
|
||||
* @store
|
||||
*/
|
||||
|
||||
import { create } from 'zustand'
|
||||
import enUS from 'antd/locale/en_US';
|
||||
import zhCN from 'antd/locale/zh_CN';
|
||||
@@ -14,13 +25,12 @@ import dayjs from 'dayjs'
|
||||
import timezone from 'dayjs/plugin/timezone';
|
||||
import utc from 'dayjs/plugin/utc';
|
||||
import i18n from '@/i18n';
|
||||
import { timezoneToAntdLocaleMap } from '@/utils/timezones';
|
||||
|
||||
// 扩展dayjs插件
|
||||
/** Extend dayjs with timezone plugins */
|
||||
dayjs.extend(utc);
|
||||
dayjs.extend(timezone);
|
||||
|
||||
// 自定义中文 locale,修改 Tour 组件的按钮文字
|
||||
/** Custom Chinese locale with modified Tour component button text */
|
||||
const customZhCN: Locale = {
|
||||
...zhCN,
|
||||
Tour: {
|
||||
@@ -31,7 +41,7 @@ const customZhCN: Locale = {
|
||||
},
|
||||
};
|
||||
|
||||
// 自定义英文 locale,修改 Tour 组件的按钮文字
|
||||
/** Custom English locale with modified Tour component button text */
|
||||
const customEnUS: Locale = {
|
||||
...enUS,
|
||||
Tour: {
|
||||
@@ -43,19 +53,27 @@ const customEnUS: Locale = {
|
||||
};
|
||||
|
||||
|
||||
/** Internationalization state interface */
|
||||
interface I18nState {
|
||||
/** Current language code */
|
||||
language: string;
|
||||
/** Ant Design locale object */
|
||||
locale: Locale;
|
||||
/** Current timezone */
|
||||
timeZone: string;
|
||||
/** Change application language */
|
||||
changeLanguage: (language: string) => void;
|
||||
/** Change timezone (triggers page reload) */
|
||||
changeTimeZone: (timeZone: string) => void;
|
||||
}
|
||||
|
||||
/** Initialize from localStorage or use defaults */
|
||||
const initialTimeZone = localStorage.getItem('timeZone') || 'Asia/Shanghai'
|
||||
const initialLanguage = localStorage.getItem('language') || 'en'
|
||||
const initialLocale = initialLanguage === 'en' ? customEnUS : customZhCN
|
||||
i18n.changeLanguage(initialLanguage)
|
||||
|
||||
/** Internationalization store */
|
||||
export const useI18n = create<I18nState>((set, get) => ({
|
||||
language: initialLanguage,
|
||||
locale: initialLocale,
|
||||
@@ -68,8 +86,9 @@ export const useI18n = create<I18nState>((set, get) => ({
|
||||
changeTimeZone: (timeZone: string) => {
|
||||
const { timeZone: lastTimeZone } = get()
|
||||
set({ timeZone })
|
||||
/** Reload page if timezone changed */
|
||||
if (lastTimeZone !== timeZone) {
|
||||
window.location.reload()
|
||||
}
|
||||
},
|
||||
}))
|
||||
}))
|
||||
|
||||
@@ -1,6 +1,26 @@
|
||||
/*
|
||||
* @Author: ZhaoYing
|
||||
* @Date: 2026-02-02 16:33:34
|
||||
* @Last Modified by: ZhaoYing
|
||||
* @Last Modified time: 2026-02-02 16:33:34
|
||||
*/
|
||||
/**
|
||||
* Menu Store
|
||||
*
|
||||
* Manages application menu and breadcrumb navigation with:
|
||||
* - Menu loading from JSON configuration
|
||||
* - Sidebar collapse state
|
||||
* - Breadcrumb generation from menu paths
|
||||
* - Custom breadcrumb support
|
||||
* - Separate menu contexts (space/manage)
|
||||
*
|
||||
* @store
|
||||
*/
|
||||
|
||||
import { create } from 'zustand'
|
||||
import AllMenus from './menu.json'
|
||||
|
||||
/** Menu item interface */
|
||||
export interface MenuItem {
|
||||
id: number;
|
||||
parent: number;
|
||||
@@ -22,20 +42,32 @@ export interface MenuItem {
|
||||
master?: string | null;
|
||||
disposable?: boolean;
|
||||
appSystem?: string | null;
|
||||
subs: MenuItem[] | null;
|
||||
subs?: MenuItem[] | null;
|
||||
onClick?: (e?: React.MouseEvent) => void | boolean;
|
||||
}
|
||||
|
||||
/** Menu state interface */
|
||||
interface MenuState {
|
||||
/** Sidebar collapsed state */
|
||||
collapsed: boolean;
|
||||
/** Toggle sidebar collapse */
|
||||
toggleSider: () => void;
|
||||
/** All menus by context */
|
||||
allMenus: Record<'space' | 'manage', MenuItem[]>;
|
||||
/** All breadcrumbs by context */
|
||||
allBreadcrumbs: Record<'space' | 'manage' | string, MenuItem[]>;
|
||||
/** Load menus for specific context */
|
||||
loadMenus: (source: 'space' | 'manage') => void;
|
||||
/** Update breadcrumbs based on key path */
|
||||
updateBreadcrumbs: (keyPath: string[], source: 'space' | 'manage') => void;
|
||||
/** Set custom breadcrumbs */
|
||||
setCustomBreadcrumbs: (breadcrumbs: MenuItem[], source: string) => void;
|
||||
}
|
||||
|
||||
/** Initialize breadcrumbs from localStorage */
|
||||
const initBreadcrumbs = localStorage.getItem('breadcrumbs') || '[]'
|
||||
|
||||
/** Menu store */
|
||||
export const useMenu = create<MenuState>((set, get) => ({
|
||||
collapsed: localStorage.getItem('collapsed') === 'true',
|
||||
allMenus: {
|
||||
@@ -61,7 +93,7 @@ export const useMenu = create<MenuState>((set, get) => ({
|
||||
console.log('updateBreadcrumbs paths:', paths);
|
||||
|
||||
if (paths.length === 3) {
|
||||
// 三级菜单:[subSubPath, subId, menuId]
|
||||
/** Three-level menu: [subSubPath, subId, menuId] */
|
||||
const menuId = paths[2];
|
||||
const subId = paths[1];
|
||||
const subSubPath = paths[0];
|
||||
@@ -81,7 +113,7 @@ export const useMenu = create<MenuState>((set, get) => ({
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 原有逻辑处理一级和二级菜单
|
||||
/** Original logic for one-level and two-level menus */
|
||||
const matchedMenu: MenuItem | undefined = menus.find(menu => menu.path === paths[paths.length - 1] || `${menu.id}` === paths[1]);
|
||||
|
||||
if (matchedMenu) {
|
||||
@@ -107,4 +139,4 @@ export const useMenu = create<MenuState>((set, get) => ({
|
||||
set({ allBreadcrumbs })
|
||||
localStorage.setItem('breadcrumbs', JSON.stringify(allBreadcrumbs))
|
||||
},
|
||||
}))
|
||||
}))
|
||||
|
||||
@@ -1,3 +1,22 @@
|
||||
/*
|
||||
* @Author: ZhaoYing
|
||||
* @Date: 2026-02-02 16:33:54
|
||||
* @Last Modified by: ZhaoYing
|
||||
* @Last Modified time: 2026-02-02 16:33:54
|
||||
*/
|
||||
/**
|
||||
* User Store
|
||||
*
|
||||
* Manages user authentication and profile with:
|
||||
* - User information storage
|
||||
* - Login/logout functionality
|
||||
* - Token management (access & refresh)
|
||||
* - Workspace storage type
|
||||
* - Navigation guards for workspace access
|
||||
*
|
||||
* @store
|
||||
*/
|
||||
|
||||
import { create } from 'zustand'
|
||||
import { clearAuthData } from '@/utils/auth';
|
||||
import type { User } from '@/views/UserManagement/types'
|
||||
@@ -5,6 +24,7 @@ import { getUsers, refreshToken, logout } from '@/api/user'
|
||||
import { getWorkspaceStorageType } from '@/api/workspaces';
|
||||
import { cookieUtils } from '@/utils/request'
|
||||
|
||||
/** Login information interface */
|
||||
export interface LoginInfo {
|
||||
access_token: string;
|
||||
expires_at: string;
|
||||
@@ -12,24 +32,37 @@ export interface LoginInfo {
|
||||
refresh_token: string;
|
||||
token_type: 'bearer'
|
||||
}
|
||||
|
||||
/** User state interface */
|
||||
export interface UserState {
|
||||
/** Current user information */
|
||||
user: User;
|
||||
/** Login token information */
|
||||
loginInfo: LoginInfo;
|
||||
/** Workspace storage type */
|
||||
storageType: string | null;
|
||||
/** Update login information */
|
||||
updateLoginInfo: (values: LoginInfo) => void;
|
||||
/** Get user information */
|
||||
getUserInfo: (flag?: boolean) => void;
|
||||
/** Clear user information */
|
||||
clearUserInfo: () => void;
|
||||
/** Logout user */
|
||||
logout: () => void;
|
||||
/** Get workspace storage type */
|
||||
getStorageType: () => void;
|
||||
/** Check and redirect if workspace not set */
|
||||
checkJump: () => void;
|
||||
}
|
||||
|
||||
/** Pages that don't require workspace */
|
||||
export const whitePage = [
|
||||
'/conversation',
|
||||
'/login',
|
||||
'/invite-register'
|
||||
]
|
||||
|
||||
/** User store */
|
||||
export const useUser = create<UserState>((set, get) => ({
|
||||
user: localStorage.getItem('user') ? JSON.parse(localStorage.getItem('user') || '{}') as User : {} as User,
|
||||
loginInfo: {} as LoginInfo,
|
||||
@@ -101,9 +134,10 @@ export const useUser = create<UserState>((set, get) => ({
|
||||
const localUser = JSON.parse(localStorage.getItem('user') || '{}') as User;
|
||||
const hash = window.location.hash;
|
||||
|
||||
/** Redirect to index if user has no workspace and not on whitelist page */
|
||||
if (localUser.id && (!localUser.current_workspace_id || localUser.current_workspace_id === '') && !whitePage.find(vo => hash.includes(vo))) {
|
||||
console.log('whitePage', whitePage.find(vo => hash.includes(vo)))
|
||||
window.location.href = '/#/index'
|
||||
}
|
||||
},
|
||||
}))
|
||||
}))
|
||||
|
||||
Reference in New Issue
Block a user