feat: 项目结构重构优化
This commit is contained in:
@@ -8,11 +8,11 @@ export function setupStore(app: App<Element>) {
|
||||
app.use(store);
|
||||
}
|
||||
|
||||
export * from "./modules/app-store";
|
||||
export * from "./modules/permission-store";
|
||||
export * from "./modules/settings-store";
|
||||
export * from "./modules/tags-view-store";
|
||||
export * from "./modules/user-store";
|
||||
export * from "./modules/dict-store";
|
||||
export * from "./modules/tenant-store";
|
||||
export * from "./modules/app";
|
||||
export * from "./modules/permission";
|
||||
export * from "./modules/settings";
|
||||
export * from "./modules/tags-view";
|
||||
export * from "./modules/user";
|
||||
export * from "./modules/dict";
|
||||
export * from "./modules/tenant";
|
||||
export { store };
|
||||
|
||||
@@ -1,85 +1,54 @@
|
||||
import { defaultSettings } from "@/settings";
|
||||
|
||||
// 导入 Element Plus 中英文语言包
|
||||
import zhCn from "element-plus/es/locale/lang/zh-cn";
|
||||
import en from "element-plus/es/locale/lang/en";
|
||||
import { store } from "@/store";
|
||||
import { DeviceEnum, SidebarStatus } from "@/enums";
|
||||
import { STORAGE_KEYS } from "@/constants";
|
||||
import { defaults } from "@/settings";
|
||||
|
||||
export const useAppStore = defineStore("app", () => {
|
||||
// 设备类型
|
||||
const device = useStorage(STORAGE_KEYS.DEVICE, DeviceEnum.DESKTOP);
|
||||
// 布局大小
|
||||
const size = useStorage(STORAGE_KEYS.SIZE, defaultSettings.size);
|
||||
// 语言
|
||||
const language = useStorage(STORAGE_KEYS.LANGUAGE, defaultSettings.language);
|
||||
// 侧边栏状态
|
||||
const size = useStorage(STORAGE_KEYS.SIZE, defaults.size);
|
||||
const language = useStorage(STORAGE_KEYS.LANGUAGE, defaults.language);
|
||||
const sidebarStatus = useStorage(STORAGE_KEYS.SIDEBAR_STATUS, SidebarStatus.CLOSED);
|
||||
const sidebar = reactive({
|
||||
opened: sidebarStatus.value === SidebarStatus.OPENED,
|
||||
withoutAnimation: false,
|
||||
});
|
||||
|
||||
// 顶部菜单激活路径
|
||||
const activeTopMenuPath = useStorage(STORAGE_KEYS.ACTIVE_TOP_MENU_PATH, "");
|
||||
|
||||
/**
|
||||
* 根据语言标识读取对应的语言包
|
||||
*/
|
||||
const locale = computed(() => {
|
||||
if (language?.value == "en") {
|
||||
return en;
|
||||
} else {
|
||||
return zhCn;
|
||||
}
|
||||
});
|
||||
const locale = computed(() => (language?.value === "en" ? en : zhCn));
|
||||
|
||||
// 切换侧边栏
|
||||
function toggleSidebar() {
|
||||
sidebar.opened = !sidebar.opened;
|
||||
sidebarStatus.value = sidebar.opened ? SidebarStatus.OPENED : SidebarStatus.CLOSED;
|
||||
}
|
||||
|
||||
// 关闭侧边栏
|
||||
function closeSideBar() {
|
||||
sidebar.opened = false;
|
||||
sidebarStatus.value = SidebarStatus.CLOSED;
|
||||
}
|
||||
|
||||
// 打开侧边栏
|
||||
function openSideBar() {
|
||||
sidebar.opened = true;
|
||||
sidebarStatus.value = SidebarStatus.OPENED;
|
||||
}
|
||||
|
||||
// 切换设备
|
||||
function toggleDevice(val: string) {
|
||||
device.value = val;
|
||||
}
|
||||
|
||||
/**
|
||||
* 改变布局大小
|
||||
*
|
||||
* @param val 布局大小 default | small | large
|
||||
*/
|
||||
function changeSize(val: string) {
|
||||
size.value = val;
|
||||
}
|
||||
/**
|
||||
* 切换语言
|
||||
*
|
||||
* @param val
|
||||
*/
|
||||
|
||||
function changeLanguage(val: string) {
|
||||
language.value = val;
|
||||
}
|
||||
/**
|
||||
* 混合模式顶部切换
|
||||
*/
|
||||
|
||||
function activeTopMenu(val: string) {
|
||||
activeTopMenuPath.value = val;
|
||||
}
|
||||
|
||||
return {
|
||||
device,
|
||||
sidebar,
|
||||
@@ -97,11 +66,6 @@ export const useAppStore = defineStore("app", () => {
|
||||
};
|
||||
});
|
||||
|
||||
/**
|
||||
* 用于在组件外部(如在Pinia Store 中)使用 Pinia 提供的 store 实例。
|
||||
* 官方文档解释了如何在组件外部使用 Pinia Store:
|
||||
* https://pinia.vuejs.org/core-concepts/outside-component-usage.html#using-a-store-outside-of-a-component
|
||||
*/
|
||||
export function useAppStoreHook() {
|
||||
return useAppStore(store);
|
||||
}
|
||||
@@ -3,7 +3,8 @@ import { constantRoutes } from "@/router";
|
||||
import { store } from "@/store";
|
||||
import router from "@/router";
|
||||
|
||||
import MenuAPI, { type RouteVO } from "@/api/system/menu";
|
||||
import MenuAPI from "@/api/system/menu";
|
||||
import { RouteVo } from "@/types";
|
||||
const modules = import.meta.glob("../../views/**/**.vue");
|
||||
const Layout = () => import("../../layouts/index.vue");
|
||||
|
||||
@@ -68,7 +69,7 @@ export const usePermissionStore = defineStore("permission", () => {
|
||||
* 转换后端路由数据为Vue Router配置
|
||||
* 处理组件路径映射和Layout层级嵌套
|
||||
*/
|
||||
const transformRoutes = (routes: RouteVO[], isTopLevel: boolean = true): RouteRecordRaw[] => {
|
||||
const transformRoutes = (routes: RouteVo[], isTopLevel: boolean = true): RouteRecordRaw[] => {
|
||||
return routes.map((route) => {
|
||||
const { component, children, ...args } = route;
|
||||
|
||||
@@ -1,176 +0,0 @@
|
||||
import { defaultSettings } from "@/settings";
|
||||
import { SidebarColor, ThemeMode } from "@/enums";
|
||||
import type { LayoutMode } from "@/enums";
|
||||
import { applyTheme, generateThemeColors, toggleDarkMode, toggleSidebarColor } from "@/utils/theme";
|
||||
import { STORAGE_KEYS } from "@/constants";
|
||||
|
||||
// 🎯 设置项类型定义
|
||||
interface SettingsState {
|
||||
// 界面显示设置
|
||||
settingsVisible: boolean;
|
||||
showTagsView: boolean;
|
||||
showAppLogo: boolean;
|
||||
showWatermark: boolean;
|
||||
enableAiAssistant: boolean;
|
||||
|
||||
// 布局设置
|
||||
layout: LayoutMode;
|
||||
sidebarColorScheme: string;
|
||||
|
||||
// 主题设置
|
||||
theme: ThemeMode;
|
||||
themeColor: string;
|
||||
}
|
||||
|
||||
// 🎯 可变更的设置项类型
|
||||
type MutableSetting = Exclude<keyof SettingsState, "settingsVisible">;
|
||||
type SettingValue<K extends MutableSetting> = SettingsState[K];
|
||||
|
||||
export const useSettingsStore = defineStore("setting", () => {
|
||||
// 设置面板可见性
|
||||
const settingsVisible = ref<boolean>(false);
|
||||
|
||||
// 是否显示标签页视图
|
||||
const showTagsView = useStorage<boolean>(
|
||||
STORAGE_KEYS.SHOW_TAGS_VIEW,
|
||||
defaultSettings.showTagsView
|
||||
);
|
||||
|
||||
// 是否显示应用Logo
|
||||
const showAppLogo = useStorage<boolean>(STORAGE_KEYS.SHOW_APP_LOGO, defaultSettings.showAppLogo);
|
||||
|
||||
// 是否显示水印
|
||||
const showWatermark = useStorage<boolean>(
|
||||
STORAGE_KEYS.SHOW_WATERMARK,
|
||||
defaultSettings.showWatermark
|
||||
);
|
||||
|
||||
// 是否启用 AI 助手
|
||||
const enableAiAssistant = useStorage<boolean>(
|
||||
STORAGE_KEYS.ENABLE_AI_ASSISTANT,
|
||||
defaultSettings.enableAiAssistant
|
||||
);
|
||||
|
||||
// 侧边栏配色方案
|
||||
const sidebarColorScheme = useStorage<string>(
|
||||
STORAGE_KEYS.SIDEBAR_COLOR_SCHEME,
|
||||
defaultSettings.sidebarColorScheme
|
||||
);
|
||||
|
||||
// 布局模式
|
||||
const layout = useStorage<LayoutMode>(STORAGE_KEYS.LAYOUT, defaultSettings.layout as LayoutMode);
|
||||
|
||||
// 主题颜色
|
||||
const themeColor = useStorage<string>(STORAGE_KEYS.THEME_COLOR, defaultSettings.themeColor);
|
||||
|
||||
// 主题模式(亮色/暗色)
|
||||
const theme = useStorage<ThemeMode>(STORAGE_KEYS.THEME, defaultSettings.theme);
|
||||
|
||||
// 设置项映射,用于统一管理
|
||||
const settingsMap = {
|
||||
showTagsView,
|
||||
showAppLogo,
|
||||
showWatermark,
|
||||
enableAiAssistant,
|
||||
sidebarColorScheme,
|
||||
layout,
|
||||
} as const;
|
||||
|
||||
// 监听主题变化,自动应用样式
|
||||
watch(
|
||||
[theme, themeColor],
|
||||
([newTheme, newThemeColor]: [ThemeMode, string]) => {
|
||||
toggleDarkMode(newTheme === ThemeMode.DARK);
|
||||
const colors = generateThemeColors(newThemeColor, newTheme);
|
||||
applyTheme(colors);
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
|
||||
// 监听侧边栏配色变化
|
||||
watch(
|
||||
[sidebarColorScheme],
|
||||
([newSidebarColorScheme]) => {
|
||||
toggleSidebarColor(newSidebarColorScheme === SidebarColor.CLASSIC_BLUE);
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
|
||||
// 通用设置更新方法
|
||||
function updateSetting<K extends keyof typeof settingsMap>(key: K, value: SettingValue<K>): void {
|
||||
const setting = settingsMap[key];
|
||||
if (setting) {
|
||||
(setting as Ref<any>).value = value;
|
||||
}
|
||||
}
|
||||
|
||||
// 主题更新方法
|
||||
function updateTheme(newTheme: ThemeMode): void {
|
||||
theme.value = newTheme;
|
||||
}
|
||||
|
||||
function updateThemeColor(newColor: string): void {
|
||||
themeColor.value = newColor;
|
||||
}
|
||||
|
||||
function updateSidebarColorScheme(newScheme: string): void {
|
||||
sidebarColorScheme.value = newScheme;
|
||||
}
|
||||
|
||||
function updateLayout(newLayout: LayoutMode): void {
|
||||
layout.value = newLayout;
|
||||
}
|
||||
|
||||
// 设置面板控制
|
||||
function toggleSettingsPanel(): void {
|
||||
settingsVisible.value = !settingsVisible.value;
|
||||
}
|
||||
|
||||
function showSettingsPanel(): void {
|
||||
settingsVisible.value = true;
|
||||
}
|
||||
|
||||
function hideSettingsPanel(): void {
|
||||
settingsVisible.value = false;
|
||||
}
|
||||
|
||||
// 重置所有设置
|
||||
function resetSettings(): void {
|
||||
showTagsView.value = defaultSettings.showTagsView;
|
||||
showAppLogo.value = defaultSettings.showAppLogo;
|
||||
showWatermark.value = defaultSettings.showWatermark;
|
||||
enableAiAssistant.value = defaultSettings.enableAiAssistant;
|
||||
sidebarColorScheme.value = defaultSettings.sidebarColorScheme;
|
||||
layout.value = defaultSettings.layout as LayoutMode;
|
||||
themeColor.value = defaultSettings.themeColor;
|
||||
theme.value = defaultSettings.theme;
|
||||
}
|
||||
|
||||
return {
|
||||
// 状态
|
||||
settingsVisible,
|
||||
showTagsView,
|
||||
showAppLogo,
|
||||
showWatermark,
|
||||
enableAiAssistant,
|
||||
sidebarColorScheme,
|
||||
layout,
|
||||
themeColor,
|
||||
theme,
|
||||
|
||||
// 更新方法
|
||||
updateSetting,
|
||||
updateTheme,
|
||||
updateThemeColor,
|
||||
updateSidebarColorScheme,
|
||||
updateLayout,
|
||||
|
||||
// 面板控制
|
||||
toggleSettingsPanel,
|
||||
showSettingsPanel,
|
||||
hideSettingsPanel,
|
||||
|
||||
// 重置功能
|
||||
resetSettings,
|
||||
};
|
||||
});
|
||||
93
src/store/modules/settings.ts
Normal file
93
src/store/modules/settings.ts
Normal file
@@ -0,0 +1,93 @@
|
||||
import { SidebarColor, ThemeMode } from "@/enums";
|
||||
import type { LayoutMode } from "@/enums";
|
||||
import { applyTheme, generateThemeColors, toggleDarkMode, toggleSidebarColor } from "@/utils/theme";
|
||||
import { STORAGE_KEYS } from "@/constants";
|
||||
import { appConfig, defaults } from "@/settings";
|
||||
|
||||
export const useSettingsStore = defineStore("setting", () => {
|
||||
// 界面显示
|
||||
const settingsVisible = ref(false);
|
||||
const showTagsView = useStorage(STORAGE_KEYS.SHOW_TAGS_VIEW, defaults.showTagsView);
|
||||
const showAppLogo = useStorage(STORAGE_KEYS.SHOW_APP_LOGO, defaults.showAppLogo);
|
||||
const showWatermark = useStorage(STORAGE_KEYS.SHOW_WATERMARK, defaults.showWatermark);
|
||||
|
||||
// 布局
|
||||
const layout = useStorage<LayoutMode>(STORAGE_KEYS.LAYOUT, defaults.layout as LayoutMode);
|
||||
const sidebarColorScheme = useStorage(
|
||||
STORAGE_KEYS.SIDEBAR_COLOR_SCHEME,
|
||||
defaults.sidebarColorScheme
|
||||
);
|
||||
|
||||
// 主题
|
||||
const theme = useStorage<ThemeMode>(STORAGE_KEYS.THEME, defaults.theme);
|
||||
const themeColor = useStorage(STORAGE_KEYS.THEME_COLOR, defaults.themeColor);
|
||||
|
||||
// 特殊模式
|
||||
const grayMode = useStorage(STORAGE_KEYS.GRAY_MODE, false);
|
||||
const colorWeak = useStorage(STORAGE_KEYS.COLOR_WEAK, false);
|
||||
|
||||
// AI 助手:系统级 && 用户级
|
||||
const userEnableAi = useStorage(STORAGE_KEYS.ENABLE_AI_ASSISTANT, false);
|
||||
const enableAiAssistant = computed(() => appConfig.aiEnabled && userEnableAi.value);
|
||||
|
||||
// 主题变化监听
|
||||
watch(
|
||||
[theme, themeColor],
|
||||
([t, c]: [ThemeMode, string]) => {
|
||||
toggleDarkMode(t === ThemeMode.DARK);
|
||||
applyTheme(generateThemeColors(c, t));
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
|
||||
watch(sidebarColorScheme, (v) => toggleSidebarColor(v === SidebarColor.CLASSIC_BLUE), {
|
||||
immediate: true,
|
||||
});
|
||||
|
||||
// 灰色模式监听
|
||||
watch(
|
||||
grayMode,
|
||||
(v) => {
|
||||
document.documentElement.style.filter = v ? "grayscale(100%)" : "";
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
|
||||
// 色弱模式监听
|
||||
watch(
|
||||
colorWeak,
|
||||
(v) => {
|
||||
document.documentElement.classList.toggle("color-weak", v);
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
|
||||
function resetSettings() {
|
||||
showTagsView.value = defaults.showTagsView;
|
||||
showAppLogo.value = defaults.showAppLogo;
|
||||
showWatermark.value = defaults.showWatermark;
|
||||
userEnableAi.value = false;
|
||||
grayMode.value = false;
|
||||
colorWeak.value = false;
|
||||
sidebarColorScheme.value = defaults.sidebarColorScheme;
|
||||
layout.value = defaults.layout as LayoutMode;
|
||||
themeColor.value = defaults.themeColor;
|
||||
theme.value = defaults.theme;
|
||||
}
|
||||
|
||||
return {
|
||||
settingsVisible,
|
||||
showTagsView,
|
||||
showAppLogo,
|
||||
showWatermark,
|
||||
enableAiAssistant,
|
||||
userEnableAi,
|
||||
grayMode,
|
||||
colorWeak,
|
||||
sidebarColorScheme,
|
||||
layout,
|
||||
themeColor,
|
||||
theme,
|
||||
resetSettings,
|
||||
};
|
||||
});
|
||||
@@ -2,13 +2,13 @@ import { store } from "@/store";
|
||||
|
||||
import AuthAPI from "@/api/auth";
|
||||
import UserAPI from "@/api/system/user";
|
||||
import type { LoginRequest } from "@/types/api";
|
||||
import type { LoginRequest, UserInfo } from "@/types/api";
|
||||
|
||||
import { AuthStorage } from "@/utils/auth";
|
||||
import { usePermissionStoreHook } from "@/store/modules/permission-store";
|
||||
import { useDictStoreHook } from "@/store/modules/dict-store";
|
||||
import { usePermissionStoreHook } from "@/store/modules/permission";
|
||||
import { useDictStoreHook } from "@/store/modules/dict";
|
||||
import { useTagsViewStore } from "@/store";
|
||||
import { cleanupWebSocket } from "@/utils/websocket";
|
||||
import { cleanupWebSocket } from "@/composables";
|
||||
|
||||
export const useUserStore = defineStore("user", () => {
|
||||
// 用户信息
|
||||
Reference in New Issue
Block a user