refactor: store 目录扁平化重构为 stores(Pinia 推荐结构)

This commit is contained in:
Ray.Hao
2026-04-20 13:53:10 +08:00
parent f669e6951b
commit 33bde0eaf8
46 changed files with 71 additions and 72 deletions

View File

@@ -13,7 +13,7 @@
</template>
<script setup lang="ts">
import { useAppStore, useSettingsStore } from "@/store";
import { useAppStore, useSettingsStore } from "@/stores";
import { appConfig } from "@/settings";
import { ThemeMode, ComponentSize } from "@/enums";

View File

@@ -4,7 +4,7 @@
import { ref, onMounted, onBeforeUnmount, toRaw } from "vue";
import { RouteRecordRaw, LocationQueryRaw } from "vue-router";
import router from "@/router";
import { usePermissionStore } from "@/store";
import { usePermissionStore } from "@/stores";
import { isExternal } from "@/utils";
/** 搜索项类型 */

View File

@@ -42,7 +42,7 @@
</template>
<script setup lang="ts">
import { useDictStore } from "@/store";
import { useDictStore } from "@/stores";
const dictStore = useDictStore();

View File

@@ -8,7 +8,7 @@
</template>
<script setup lang="ts">
import { useDictStore } from "@/store";
import { useDictStore } from "@/stores";
const props = defineProps({
code: String, // 字典编码

View File

@@ -5,7 +5,7 @@
</template>
<script setup lang="ts">
import { useSettingsStore } from "@/store";
import { useSettingsStore } from "@/stores";
import { ThemeMode, SidebarColor, LayoutMode } from "@/enums/settings";
defineProps({

View File

@@ -17,7 +17,7 @@
</template>
<script setup lang="ts">
import { useAppStore } from "@/store/modules/app";
import { useAppStore } from "@/stores/app";
import { LanguageEnum } from "@/enums/settings";
defineProps({

View File

@@ -23,7 +23,7 @@
<script setup lang="ts">
import { ComponentSize } from "@/enums/settings";
import { useAppStore } from "@/store/modules/app";
import { useAppStore } from "@/stores/app";
const { t } = useI18n();
const sizeOptions = computed(() => {

View File

@@ -28,7 +28,7 @@
<script setup lang="ts">
import { computed } from "vue";
import { ArrowDown } from "@element-plus/icons-vue";
import { useTenantStoreHook } from "@/store/modules/tenant";
import { useTenantStoreHook } from "@/stores/tenant";
const emit = defineEmits<{
(e: "change", tenantId: number): void;

View File

@@ -21,7 +21,7 @@
</el-dropdown>
</template>
<script setup lang="ts">
import { useSettingsStore } from "@/store";
import { useSettingsStore } from "@/stores";
import { ThemeMode } from "@/enums";
import { Moon, Sunny, Monitor } from "@element-plus/icons-vue";

View File

@@ -1,4 +1,4 @@
import { useDictStoreHook } from "@/store/modules/dict";
import { useDictStoreHook } from "@/stores/dict";
import { useSse } from "./useSse";
export interface DictChangeMessage {

View File

@@ -1,6 +1,6 @@
import type { Directive, DirectiveBinding } from "vue";
import { useUserStore } from "@/store";
import { useUserStore } from "@/stores";
import { ROLE_ROOT } from "@/constants";
/**

View File

@@ -1,6 +1,6 @@
import type { App } from "vue";
import { createI18n } from "vue-i18n";
import { useAppStoreHook } from "@/store/modules/app";
import { useAppStoreHook } from "@/stores/app";
// 本地语言包
import enLocale from "./package/en.json";
import zhCnLocale from "./package/zh-cn.json";

View File

@@ -74,7 +74,7 @@
import type { LocationQueryRaw, RouteRecordRaw } from "vue-router";
import { useWindowSize } from "@vueuse/core";
import { useLayout } from "./useLayout";
import { useAppStore, usePermissionStore, useSettingsStore } from "@/store";
import { useAppStore, usePermissionStore, useSettingsStore } from "@/stores";
import { isExternal } from "@/utils/index";
import { translateRouteTitle } from "@/lang/utils";
import { SidebarColor } from "@/enums/settings";

View File

@@ -26,7 +26,7 @@
<script setup lang="ts">
import { useWindowSize } from "@vueuse/core";
import { useLayout } from "./useLayout";
import { usePermissionStore } from "@/store";
import { usePermissionStore } from "@/stores";
import BaseLayout from "./BaseLayout.vue";
import LayoutLogo from "./components/LayoutLogo.vue";
import LayoutSidebar from "./components/LayoutSidebar.vue";

View File

@@ -19,7 +19,7 @@
<script setup lang="ts">
import { type RouteLocationNormalized } from "vue-router";
import { useSettingsStore, useTagsViewStore } from "@/store";
import { useSettingsStore, useTagsViewStore } from "@/stores";
import variables from "@/styles/variables.module.scss";
import Error404 from "@/views/error/404.vue";

View File

@@ -14,7 +14,7 @@
</template>
<script setup lang="ts">
import { useAppStore } from "@/store";
import { useAppStore } from "@/stores";
import Hamburger from "@/components/Hamburger/index.vue";
import Breadcrumb from "@/components/Breadcrumb/index.vue";

View File

@@ -167,7 +167,7 @@ import { DocumentCopy, RefreshLeft, Check } from "@element-plus/icons-vue";
const { t } = useI18n();
import { LayoutMode, PageSwitchingAnimationOptions, SidebarColor, ThemeMode } from "@/enums";
import { useSettingsStore } from "@/store";
import { useSettingsStore } from "@/stores";
import { themeColorPresets } from "@/settings";
// 页面切换动画选项

View File

@@ -30,7 +30,7 @@ import path from "path-browserify";
import type { MenuInstance } from "element-plus";
import type { RouteRecordRaw } from "vue-router";
import { SidebarColor } from "@/enums/settings";
import { useSettingsStore, useAppStore } from "@/store";
import { useSettingsStore, useAppStore } from "@/stores";
import { isExternal } from "@/utils/index";
import LayoutSidebarItem from "./LayoutSidebarItem.vue";
import variables from "@/styles/variables.module.scss";

View File

@@ -71,7 +71,7 @@
import { useRoute, useRouter, type RouteRecordRaw } from "vue-router";
import { resolve } from "path-browserify";
import { translateRouteTitle } from "@/lang/utils";
import { usePermissionStore, useTagsViewStore } from "@/store";
import { usePermissionStore, useTagsViewStore } from "@/stores";
interface ContextMenu {
visible: boolean;

View File

@@ -71,7 +71,7 @@ import { useI18n } from "vue-i18n";
import { useRoute, useRouter } from "vue-router";
import { defaults } from "@/settings";
import { DeviceEnum, SidebarColor, ThemeMode, LayoutMode } from "@/enums/settings";
import { useAppStore, useSettingsStore, useUserStore } from "@/store";
import { useAppStore, useSettingsStore, useUserStore } from "@/stores";
// 导入子组件
import CommandPalette from "@/components/CommandPalette/index.vue";
@@ -80,7 +80,7 @@ import SizeSelect from "@/components/SizeSelect/index.vue";
import LangSelect from "@/components/LangSelect/index.vue";
import NoticeDropdown from "@/components/NoticeDropdown/index.vue";
import TenantSwitcher from "@/components/TenantSwitcher/index.vue";
import { useTenantStoreHook } from "@/store/modules/tenant";
import { useTenantStoreHook } from "@/stores/tenant";
const { t } = useI18n();
const appStore = useAppStore();

View File

@@ -5,7 +5,7 @@
*/
import { useRoute } from "vue-router";
import { useWindowSize } from "@vueuse/core";
import { useAppStore, usePermissionStore, useSettingsStore } from "@/store";
import { useAppStore, usePermissionStore, useSettingsStore } from "@/stores";
import { DeviceEnum } from "@/enums/settings";
import { defaults } from "@/settings";

View File

@@ -20,7 +20,7 @@ import "animate.css";
import { setupDirective } from "@/directives";
import { setupI18n } from "@/lang";
import { setupRouter } from "@/router";
import { setupStore } from "@/store";
import { setupStore } from "@/stores";
// ===== 全局组件 =====
import * as ElementPlusIcons from "@element-plus/icons-vue";

View File

@@ -1,8 +1,8 @@
import type { RouteRecordRaw } from "vue-router";
import NProgress from "@/plugins/nprogress";
import router from "@/router";
import { usePermissionStore, useUserStore } from "@/store";
import { useTenantStoreHook } from "@/store/modules/tenant";
import { usePermissionStore, useUserStore } from "@/stores";
import { useTenantStoreHook } from "@/stores/tenant";
import { isTenantEnabled } from "@/utils/tenant";
import { addRecentMenu } from "@/composables/useRecentMenus";

View File

@@ -1,18 +0,0 @@
import type { App } from "vue";
import { createPinia } from "pinia";
const store = createPinia();
// 全局注册 store
export function setupStore(app: App<Element>) {
app.use(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 };

View File

@@ -1,6 +1,6 @@
import zhCn from "element-plus/es/locale/lang/zh-cn";
import en from "element-plus/es/locale/lang/en";
import { store } from "@/store";
import { store } from "@/stores";
import { DeviceEnum, SidebarStatus } from "@/enums";
import { STORAGE_KEYS } from "@/constants";
import { defaults } from "@/settings";

View File

@@ -1,4 +1,4 @@
import { store } from "@/store";
import { store } from "@/stores";
import DictAPI from "@/api/system/dict";
import type { DictItemOption } from "@/api/system/dict";
import { STORAGE_KEYS } from "@/constants";

17
src/stores/index.ts Normal file
View File

@@ -0,0 +1,17 @@
import type { App } from "vue";
import { createPinia } from "pinia";
const store = createPinia();
export function setupStore(app: App<Element>) {
app.use(store);
}
export * from "./app";
export * from "./dict";
export * from "./permission";
export * from "./settings";
export * from "./tags-view";
export * from "./tenant";
export * from "./user";
export { store };

View File

@@ -1,13 +1,13 @@
import type { RouteRecordRaw } from "vue-router";
import { constantRoutes } from "@/router";
import { store } from "@/store";
import { store } from "@/stores";
import router from "@/router";
import { useUserStoreHook } from "@/store/modules/user";
import { useUserStoreHook } from "@/stores/user";
import MenuAPI from "@/api/system/menu";
import type { RouteItem } from "@/api/system/menu";
const modules = import.meta.glob("../../views/**/**.vue");
const Layout = () => import("../../layouts/index.vue");
const modules = import.meta.glob("../views/**/**.vue");
const Layout = () => import("../layouts/index.vue");
function resolveViewComponent(componentPath: string) {
const normalized = componentPath
@@ -15,9 +15,9 @@ function resolveViewComponent(componentPath: string) {
.replace(/^\/+/, "")
.replace(/\.vue$/i, "");
return (
modules[`../../views/${normalized}.vue`] ||
modules[`../../views/${normalized}/index.vue`] ||
modules[`../../views/error/404.vue`]
modules[`../views/${normalized}.vue`] ||
modules[`../views/${normalized}/index.vue`] ||
modules[`../views/error/404.vue`]
);
}

View File

@@ -1,4 +1,4 @@
import { store } from "@/store";
import { store } from "@/stores";
import TenantAPI from "@/api/system/tenant";
import type { TenantInfo } from "@/api/system/tenant";
import { STORAGE_KEYS } from "@/constants";

View File

@@ -1,4 +1,4 @@
import { store } from "@/store";
import { store } from "@/stores";
import AuthAPI from "@/api/auth";
import UserAPI from "@/api/system/user";
@@ -6,9 +6,9 @@ import type { LoginRequest } from "@/api/auth";
import type { UserInfo } from "@/api/system/user";
import { AuthStorage } from "@/utils/auth";
import { usePermissionStoreHook } from "@/store/modules/permission";
import { useDictStoreHook } from "@/store/modules/dict";
import { useTagsViewStore } from "@/store";
import { usePermissionStoreHook } from "@/stores/permission";
import { useDictStoreHook } from "@/stores/dict";
import { useTagsViewStore } from "@/stores";
import { cleanupSseServices } from "@/composables";
export const useUserStore = defineStore("user", () => {

View File

@@ -1,6 +1,6 @@
import { Storage } from "./storage";
import { STORAGE_KEYS, ROLE_ROOT } from "@/constants";
import { useUserStoreHook } from "@/store/modules/user";
import { useUserStoreHook } from "@/stores/user";
import router from "@/router";
// 负责本地凭证与偏好的读写

View File

@@ -1,8 +1,8 @@
import axios, { type InternalAxiosRequestConfig, type AxiosResponse } from "axios";
import qs from "qs";
import { ApiCodeEnum } from "@/enums/api";
import { useUserStoreHook } from "@/store/modules/user";
import { usePermissionStoreHook } from "@/store/modules/permission";
import { useUserStoreHook } from "@/stores/user";
import { usePermissionStoreHook } from "@/stores/permission";
import { AuthStorage, redirectToLogin } from "@/utils/auth";
// 记录已重试的请求,防止无限循环

View File

@@ -384,7 +384,7 @@ import { ref } from "vue";
import { useRouter } from "vue-router";
import LogAPI from "@/api/system/log";
import type { VisitOverviewDetail, VisitTrendDetail } from "@/api/system/log";
import { useUserStore } from "@/store/modules/user";
import { useUserStore } from "@/stores/user";
import { formatGrowthRate } from "@/utils";
import { useTransition, useDateFormat } from "@vueuse/core";
import { Clock, Menu } from "@element-plus/icons-vue";

View File

@@ -79,7 +79,7 @@ import RoleAPI from "@/api/system/role";
import type { UserForm, UserQueryParams, UserItem } from "@/api/system/user";
import type { IObject, IModalConfig, IContentConfig, ISearchConfig } from "@/components/CURD/types";
import { DeviceEnum } from "@/enums/settings";
import { useAppStore } from "@/store";
import { useAppStore } from "@/stores";
import usePage from "@/components/CURD/usePage";
defineOptions({

View File

@@ -2,7 +2,7 @@ import UserAPI from "@/api/system/user";
import type { UserForm } from "@/api/system/user";
import type { IModalConfig } from "@/components/CURD/types";
import { DeviceEnum } from "@/enums/settings";
import { useAppStore } from "@/store";
import { useAppStore } from "@/stores";
import { deptArr, roleArr } from "./options";
const modalConfig: IModalConfig<UserForm> = {

View File

@@ -1,6 +1,6 @@
import type { IModalConfig } from "@/components/CURD/types";
import { DeviceEnum } from "@/enums/settings";
import { useAppStore } from "@/store";
import { useAppStore } from "@/stores";
const modalConfig: IModalConfig = {
permPrefix: "sys:user",

View File

@@ -140,7 +140,7 @@
</template>
<script setup lang="ts">
import { useDictStoreHook } from "@/store/modules/dict";
import { useDictStoreHook } from "@/stores/dict";
import { useDateFormat } from "@vueuse/core";
import DictAPI from "@/api/system/dict";
import type { DictItemForm } from "@/api/system/dict";

View File

@@ -1,6 +1,6 @@
import router from "@/router";
import { ElButton } from "element-plus";
import { useTagsViewStore } from "@/store";
import { useTagsViewStore } from "@/stores";
export default defineComponent({
name: "ToDetail",

View File

@@ -24,7 +24,7 @@
<script setup lang="ts">
import selectConfig from "./config/select";
import { useDictStore } from "@/store";
import { useDictStore } from "@/stores";
const dictStore = useDictStore();
interface IUser {
id: string;

View File

@@ -120,7 +120,7 @@ import type { FormInstance } from "element-plus";
import AuthAPI from "@/api/auth";
import type { LoginRequest } from "@/api/auth";
import router from "@/router";
import { useUserStore } from "@/store";
import { useUserStore } from "@/stores";
import { AuthStorage } from "@/utils/auth";
const { t } = useI18n();

View File

@@ -311,7 +311,7 @@ import type {
import { computed, onBeforeUnmount, onMounted, reactive, ref } from "vue";
import FileAPI from "@/api/file";
import { useUserStoreHook } from "@/store";
import { useUserStoreHook } from "@/stores";
import { redirectToLogin } from "@/utils/auth";
import {

View File

@@ -357,7 +357,7 @@
</template>
<script setup lang="ts">
import { useAppStore } from "@/store/modules/app";
import { useAppStore } from "@/stores/app";
import { DeviceEnum } from "@/enums/settings";
import MenuAPI from "@/api/system/menu";
import type { MenuQueryParams, MenuForm, MenuItem } from "@/api/system/menu";

View File

@@ -229,7 +229,7 @@
</template>
<script setup lang="ts">
import { useAppStore } from "@/store/modules/app";
import { useAppStore } from "@/stores/app";
import { DeviceEnum } from "@/enums/settings";
import RoleAPI from "@/api/system/role";

View File

@@ -249,7 +249,7 @@ import { downloadFile } from "@/utils";
import UserAPI from "@/api/system/user";
import DeptAPI from "@/api/system/dept";
import RoleAPI from "@/api/system/role";
import { useUserStore, useAppStore } from "@/store";
import { useUserStore, useAppStore } from "@/stores";
import { DeviceEnum, DialogMode, CommonStatus } from "@/enums";
import { useTableSelection } from "@/composables";
import UserDeptTree from "./components/UserDeptTree.vue";