feat(projects): 重构项目的TS类型架构,去除interface文件夹

This commit is contained in:
Soybean 2022-03-12 17:45:37 +08:00
parent 75de2b0604
commit 8191490f39
58 changed files with 400 additions and 461 deletions

View File

@ -171,6 +171,7 @@ module.exports = {
ignores: ['index'],
},
],
'@typescript-eslint/ban-types': [
'error',
{
@ -182,6 +183,12 @@ module.exports = {
},
},
],
'@typescript-eslint/no-empty-interface': [
'error',
{
allowSingleExtends: true,
},
],
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-shadow': 'error',
'@typescript-eslint/no-unused-vars': ['warn', { ignoreRestSiblings: true, varsIgnorePattern: '^_' }],

View File

@ -1,8 +1,7 @@
import { computed } from 'vue';
import { useAppStore, useThemeStore } from '@/store';
import type { ThemeLayoutMode, GlobalHeaderProps } from '@/interface';
type LayoutHeaderProps = Record<ThemeLayoutMode, GlobalHeaderProps>;
type LayoutHeaderProps = Record<EnumType.ThemeLayoutMode, GlobalHeaderProps>;
export function useBasicLayout() {
const app = useAppStore();

View File

@ -1,7 +1,6 @@
import { useRouter } from 'vue-router';
import type { RouteLocationRaw } from 'vue-router';
import { router as globalRouter, routeName } from '@/router';
import type { LoginModuleKey } from '@/interface';
/**
*
@ -43,8 +42,8 @@ export function useRouterPush(inSetup = true) {
* @param loginModule -
* @param redirectUrl - (),undefined表示取当前地址为重定向地址
*/
function toLogin(loginModule?: LoginModuleKey, redirectUrl?: string) {
const module: LoginModuleKey = loginModule || 'pwd-login';
function toLogin(loginModule?: EnumType.LoginModuleKey, redirectUrl?: string) {
const module: EnumType.LoginModuleKey = loginModule || 'pwd-login';
const routeLocation: RouteLocationRaw = {
name: routeName('login'),
params: { module },
@ -58,7 +57,7 @@ export function useRouterPush(inSetup = true) {
*
* @param module -
*/
function toLoginModule(module: LoginModuleKey) {
function toLoginModule(module: EnumType.LoginModuleKey) {
const { query } = route.value;
routerPush({ name: routeName('login'), params: { module }, query });
}

View File

@ -1,9 +1,3 @@
/** 布局组件的名称 */
export enum EnumLayoutComponentName {
basic = 'basic-layout',
blank = 'blank-layout',
}
/** 登录模块 */
export enum EnumLoginModule {
'pwd-login' = '账密登录',

View File

@ -1 +0,0 @@
export {};

35
src/enum/common.ts Normal file
View File

@ -0,0 +1,35 @@
/** http请求头的content-type类型 */
export enum EnumContentType {
json = 'application/json',
formUrlencoded = 'application/x-www-form-urlencoded',
formData = 'multipart/form-data',
}
/** 缓存的key */
export enum EnumStorageKey {
/** 主题颜色 */
'theme-color' = '__THEME_COLOR__',
/** 用户token */
'token' = '__TOKEN__',
/** 用户刷新token */
'refresh-koken' = '__REFRESH_TOKEN__',
/** 用户信息 */
'user-info' = '__USER_INFO__',
/** 多页签路由信息 */
'tab-routes' = '__TAB_ROUTES__',
}
/** 数据类型 */
export enum EnumDataType {
number = '[object Number]',
string = '[object String]',
boolean = '[object Boolean]',
null = '[object Null]',
undefined = '[object Undefined]',
object = '[object Object]',
array = '[object Array]',
date = '[object Date]',
regexp = '[object RegExp]',
set = '[object Set]',
map = '[object Map]',
}

View File

@ -1,5 +0,0 @@
export * from './typeof';
export * from './storage';
export * from './service';
export * from './system';
export * from './theme';

View File

@ -1,6 +0,0 @@
/** http请求头的content-type类型 */
export enum ContentType {
json = 'application/json',
formUrlencoded = 'application/x-www-form-urlencoded',
formData = 'multipart/form-data',
}

View File

@ -1,12 +0,0 @@
export enum EnumStorageKey {
/** 主题颜色 */
'theme-color' = '__THEME_COLOR__',
/** 用户token */
'token' = '__TOKEN__',
/** 用户刷新token */
'refresh-koken' = '__REFRESH_TOKEN__',
/** 用户信息 */
'user-info' = '__USER_INFO__',
/** 多页签路由信息 */
'tab-routes' = '__TAB_ROUTES__',
}

View File

@ -1,14 +0,0 @@
/** 数据类型 */
export enum EnumDataType {
number = '[object Number]',
string = '[object String]',
boolean = '[object Boolean]',
null = '[object Null]',
undefined = '[object Undefined]',
object = '[object Object]',
array = '[object Array]',
date = '[object Date]',
regexp = '[object RegExp]',
set = '[object Set]',
map = '[object Map]',
}

View File

@ -1 +1,3 @@
export * from './common';
export * from './system';
export * from './business';

View File

@ -1,3 +1,9 @@
/** 布局组件的名称 */
export enum EnumLayoutComponentName {
basic = 'basic-layout',
blank = 'blank-layout',
}
/** 布局模式 */
export enum EnumThemeLayoutMode {
'vertical' = '左侧菜单模式',

View File

@ -1,26 +0,0 @@
import type {
EnumLayoutComponentName,
EnumThemeLayoutMode,
EnumThemeTabMode,
EnumThemeHorizontalMenuPosition,
EnumThemeAnimateMode,
EnumLoginModule,
} from '@/enum';
/** 布局组件名称 */
export type LayoutComponentName = keyof typeof EnumLayoutComponentName;
/** 布局模式 */
export type ThemeLayoutMode = keyof typeof EnumThemeLayoutMode;
/** 多页签风格 */
export type ThemeTabMode = keyof typeof EnumThemeTabMode;
/** 水平模式的菜单位置 */
export type ThemeHorizontalMenuPosition = keyof typeof EnumThemeHorizontalMenuPosition;
/** 过渡动画 */
export type ThemeAnimateMode = keyof typeof EnumThemeAnimateMode;
/** 登录模块 */
export type LoginModuleKey = keyof typeof EnumLoginModule;

View File

@ -1,5 +0,0 @@
import type BScroll from '@better-scroll/core';
export interface ExposeBetterScroll {
instance: BScroll;
}

View File

@ -1,5 +0,0 @@
export * from './enum';
export * from './theme';
export * from './system';
export * from './expose';
export * from './layout';

View File

@ -1,9 +0,0 @@
/** 全局头部属性 */
export interface GlobalHeaderProps {
/** 显示logo */
showLogo: boolean;
/** 显示头部菜单 */
showHeaderMenu: boolean;
/** 显示菜单折叠按钮 */
showMenuCollape: boolean;
}

View File

@ -1,35 +0,0 @@
import type { VNodeChild } from 'vue';
import type { RouteLocationNormalizedLoaded } from 'vue-router';
import type { DropdownOption } from 'naive-ui';
/** 菜单项配置 */
export type GlobalMenuOption = {
key: string;
label: string;
routeName: string;
routePath: string;
icon?: () => VNodeChild;
children?: GlobalMenuOption[];
};
/** 面包屑 */
export type GlobalBreadcrumb = DropdownOption & {
key: string;
label: string;
disabled: boolean;
routeName: string;
hasChildren: boolean;
children?: GlobalBreadcrumb[];
};
/** 多页签Tab的路由 */
export interface GlobalTabRoute extends Pick<RouteLocationNormalizedLoaded, 'name' | 'path' | 'meta'> {
/** 滚动的位置 */
scrollPosition: {
left: number;
top: number;
};
}
/** 搜索的菜单 */
export type SearchMenu = AuthRoute.Route;

View File

@ -1,150 +0,0 @@
import type {
EnumThemeLayoutMode,
EnumThemeTabMode,
EnumThemeHorizontalMenuPosition,
EnumThemeAnimateMode,
} from '@/enum';
import type { ThemeLayoutMode, ThemeTabMode, ThemeHorizontalMenuPosition, ThemeAnimateMode } from './enum';
/** 主题相关类型 */
export interface ThemeSetting {
/** 暗黑模式 */
darkMode: boolean;
/** 布局样式 */
layout: ThemeLayout;
/** 主题颜色 */
themeColor: string;
/** 主题颜色列表 */
themeColorList: string[];
/** 其他颜色 */
otherColor: ThemeOtherColor;
/** 是否自定义info的颜色(默认取比主题色深一级的颜色) */
isCustomizeInfoColor: boolean;
/** 固定头部和多页签 */
fixedHeaderAndTab: boolean;
/** 显示重载按钮 */
showReload: boolean;
/** 头部样式 */
header: ThemeHeader;
/** 标多页签样式 */
tab: ThemeTab;
/** 侧边栏样式 */
sider: ThemeSider;
/** 菜单样式 */
menu: ThemeMenu;
/** 底部样式 */
footer: ThemeFooter;
/** 页面样式 */
page: ThemePage;
}
/** 布局样式 */
interface ThemeLayout {
/** 最小宽度 */
minWidth: number;
/** 布局模式 */
mode: ThemeLayoutMode;
/** 布局模式列表 */
modeList: ThemeLayoutModeList[];
}
interface ThemeLayoutModeList {
value: ThemeLayoutMode;
label: EnumThemeLayoutMode;
}
/** 其他主题颜色 */
interface ThemeOtherColor {
/** 信息 */
info: string;
/** 成功 */
success: string;
/** 警告 */
warning: string;
/** 错误 */
error: string;
}
/** 头部样式 */
interface ThemeHeader {
/** 头部高度 */
height: number;
/** 面包屑样式 */
crumb: ThemeCrumb;
}
/** 面包屑样式 */
interface ThemeCrumb {
/** 面包屑可见 */
visible: boolean;
/** 显示图标 */
showIcon: boolean;
}
/** 标多页签样式 */
export interface ThemeTab {
/** 多页签可见 */
visible: boolean;
/** 多页签高度 */
height: number;
/** 多页签风格 */
mode: ThemeTabMode;
/** 多页签风格列表 */
modeList: ThemeTabModeList[];
/** 开启多页签缓存 */
isCache: boolean;
}
/** 多页签风格列表 */
interface ThemeTabModeList {
value: ThemeTabMode;
label: EnumThemeTabMode;
}
/** 侧边栏样式 */
interface ThemeSider {
/** 侧边栏宽度 */
width: number;
/** 侧边栏折叠时的宽度 */
collapsedWidth: number;
/** vertical-mix模式下侧边栏宽度 */
mixWidth: number;
/** vertical-mix模式下侧边栏折叠时的宽度 */
mixCollapsedWidth: number;
/** vertical-mix模式下侧边栏的子菜单的宽度 */
mixChildMenuWidth: number;
}
/** 菜单样式 */
interface ThemeMenu {
/** 水平模式的菜单的位置 */
horizontalPosition: ThemeHorizontalMenuPosition;
/** 水平模式的菜单的位置列表 */
horizontalPositionList: ThemeHorizontalMenuPositionList[];
}
/** 水平模式的菜单的位置列表 */
interface ThemeHorizontalMenuPositionList {
value: ThemeHorizontalMenuPosition;
label: EnumThemeHorizontalMenuPosition;
}
/** 底部样式 */
interface ThemeFooter {
/** 是否固定底部 */
fixed: boolean;
/** 底部高度 */
height: number;
}
/** 页面样式 */
interface ThemePage {
/** 页面是否开启动画 */
animate: boolean;
/** 动画类型 */
animateMode: ThemeAnimateMode;
/** 动画类型列表 */
animateModeList: ThemeAnimateModeList[];
}
/** 动画类型列表 */
interface ThemeAnimateModeList {
value: ThemeAnimateMode;
label: EnumThemeAnimateMode;
}

View File

@ -32,7 +32,6 @@ import { routePath } from '@/router';
import { useThemeStore, useRouteStore } from '@/store';
import { useRouterPush } from '@/composables';
import { getBreadcrumbByRouteKey } from '@/utils';
import type { GlobalMenuOption } from '@/interface';
const route = useRoute();
const theme = useThemeStore();

View File

@ -8,7 +8,6 @@ import { useRoute } from 'vue-router';
import type { MenuOption } from 'naive-ui';
import { useRouteStore } from '@/store';
import { useRouterPush } from '@/composables';
import type { GlobalMenuOption } from '@/interface';
const route = useRoute();
const routeStore = useRouteStore();

View File

@ -21,7 +21,6 @@
<script setup lang="ts">
import { DarkModeContainer } from '@/components';
import { useThemeStore } from '@/store';
import type { GlobalHeaderProps } from '@/interface';
import GlobalLogo from '../GlobalLogo/index.vue';
import GlobalSearch from '../GlobalSearch/index.vue';
import {

View File

@ -28,7 +28,6 @@ import { ref, shallowRef, computed, watch, nextTick } from 'vue';
import { useRouter } from 'vue-router';
import { useDebounceFn, onKeyStroke } from '@vueuse/core';
import { useRouteStore } from '@/store';
import type { SearchMenu } from '@/interface';
import SearchResult from './SearchResult.vue';
import SearchFooter from './SearchFooter.vue';
@ -50,7 +49,7 @@ const routeStore = useRouteStore();
const keyword = ref('');
const activePath = ref('');
const resultOptions = shallowRef<SearchMenu[]>([]);
const resultOptions = shallowRef<AuthRoute.Route[]>([]);
const inputRef = ref<HTMLInputElement>();
const handleSearch = useDebounceFn(search, 300);

View File

@ -24,11 +24,10 @@
import { computed } from 'vue';
import { Icon } from '@iconify/vue';
import { useThemeStore } from '@/store';
import type { SearchMenu } from '@/interface';
interface Props {
value: string;
options: SearchMenu[];
options: AuthRoute.Route[];
}
interface Emits {
@ -52,7 +51,7 @@ const active = computed({
});
/** 鼠标移入 */
async function handleMouse(item: SearchMenu) {
async function handleMouse(item: AuthRoute.Route) {
active.value = item.path;
}

View File

@ -36,7 +36,6 @@ import { DarkModeContainer } from '@/components';
import { useAppStore, useThemeStore } from '@/store';
import { useAppInfo, useRouterPush } from '@/composables';
import { getActiveKeyPathsOfMenus } from '@/utils';
import type { GlobalMenuOption } from '@/interface';
interface Props {
/** 菜单抽屉可见性 */

View File

@ -28,7 +28,6 @@ import { useAppStore, useThemeStore, useRouteStore } from '@/store';
import { useRouterPush } from '@/composables';
import { useBoolean } from '@/hooks';
import { GlobalLogo } from '@/layouts/common';
import type { GlobalMenuOption } from '@/interface';
import { MixMenuDetail, MixMenuDrawer, MixMenuCollapse } from './components';
const route = useRoute();

View File

@ -21,7 +21,6 @@ import type { MenuOption } from 'naive-ui';
import { useAppStore, useThemeStore, useRouteStore } from '@/store';
import { useRouterPush } from '@/composables';
import { getActiveKeyPathsOfMenus } from '@/utils';
import type { GlobalMenuOption } from '@/interface';
const route = useRoute();
const app = useAppStore();

View File

@ -16,7 +16,6 @@ import { useElementBounding } from '@vueuse/core';
import { DarkModeContainer, BetterScroll } from '@/components';
import { useThemeStore, useTabStore } from '@/store';
import { useDeviceInfo } from '@/composables';
import type { ExposeBetterScroll } from '@/interface';
import { TabDetail, ReloadButton } from './components';
const route = useRoute();
@ -27,7 +26,7 @@ const deviceInfo = useDeviceInfo();
const bsWrapper = ref<HTMLElement>();
const { width: bsWrapperWidth, left: bsWrapperLeft } = useElementBounding(bsWrapper);
const bsScroll = ref<ExposeBetterScroll>();
const bsScroll = ref<Expose.BetterScroll>();
const canClick = Boolean(deviceInfo.device.type);

View File

@ -19,11 +19,10 @@
import { computed } from 'vue';
import type { FollowerPlacement } from 'vueuc';
import type { EnumThemeLayoutMode } from '@/enum';
import type { ThemeLayoutMode } from '@/interface';
interface Props {
/** 布局模式 */
mode: ThemeLayoutMode;
mode: EnumType.ThemeLayoutMode;
/** 布局模式文本 */
label: EnumThemeLayoutMode;
/** 选中状态 */
@ -33,7 +32,7 @@ interface Props {
const props = defineProps<Props>();
type LayoutConfig = Record<
ThemeLayoutMode,
EnumType.ThemeLayoutMode,
{
placement: FollowerPlacement;
menuClass: string;

View File

@ -1,5 +1,4 @@
import { getLoginModuleRegExp } from '@/utils';
import type { LoginModuleKey } from '@/interface';
/** 固定的路由 */
export const constantRoutes: AuthRoute.Route[] = [
@ -16,7 +15,7 @@ export const constantRoutes: AuthRoute.Route[] = [
path: '/login',
component: 'self',
props: (route) => {
const moduleType = (route.params.module as LoginModuleKey) || 'pwd-login';
const moduleType = (route.params.module as EnumType.LoginModuleKey) || 'pwd-login';
return {
module: moduleType,
};

View File

@ -1,5 +1,4 @@
import { EnumThemeLayoutMode, EnumThemeTabMode, EnumThemeHorizontalMenuPosition, EnumThemeAnimateMode } from '@/enum';
import type { ThemeSetting } from '@/interface';
import jsonSetting from './theme.json';
const themeColorList = [
@ -29,7 +28,7 @@ const themeColorList = [
'#546e7a',
];
const defaultThemeSetting: ThemeSetting = {
const defaultThemeSetting: Theme.Setting = {
darkMode: false,
layout: {
minWidth: 900,
@ -102,4 +101,4 @@ const defaultThemeSetting: ThemeSetting = {
},
};
export const themeSetting = (jsonSetting as ThemeSetting) || defaultThemeSetting;
export const themeSetting = (jsonSetting as Theme.Setting) || defaultThemeSetting;

View File

@ -8,7 +8,6 @@ import {
transformAuthRoutesToSearchMenus,
getCacheRoutes,
} from '@/utils';
import type { GlobalMenuOption, SearchMenu } from '@/interface';
import { useTabStore } from '../tab';
interface RouteState {
@ -19,7 +18,7 @@ interface RouteState {
/** 菜单 */
menus: GlobalMenuOption[];
/** 搜索的菜单 */
searchMenus: SearchMenu[];
searchMenus: AuthRoute.Route[];
/** 缓存的路由名称 */
cacheRoutes: string[];
}

View File

@ -1,5 +1,4 @@
import type { RouteRecordNormalized, RouteLocationNormalizedLoaded } from 'vue-router';
import type { GlobalTabRoute } from '@/interface';
/**
* vue路由获取tab路由

View File

@ -2,7 +2,6 @@ import type { Router, RouteLocationNormalizedLoaded } from 'vue-router';
import { defineStore } from 'pinia';
import { useRouterPush } from '@/composables';
import { getTabRoutes } from '@/utils';
import type { GlobalTabRoute } from '@/interface';
import { useThemeStore } from '../theme';
import { getTabRouteByVueRoute, isInTabRoutes, getIndexInTabRoutes } from './helpers';

View File

@ -1,15 +1,8 @@
import { defineStore } from 'pinia';
import { darkTheme } from 'naive-ui';
import type {
ThemeSetting,
ThemeLayoutMode,
ThemeTabMode,
ThemeHorizontalMenuPosition,
ThemeAnimateMode,
} from '@/interface';
import { getThemeSettings, getNaiveThemeOverrides, addThemeCssVarsToHtml } from './helpers';
type ThemeState = ThemeSetting;
type ThemeState = Theme.Setting;
export const useThemeStore = defineStore('theme-store', {
state: (): ThemeState => getThemeSettings(),
@ -45,7 +38,7 @@ export const useThemeStore = defineStore('theme-store', {
this.layout.minWidth = minWidth;
},
/** 设置布局模式 */
setLayoutMode(mode: ThemeLayoutMode) {
setLayoutMode(mode: EnumType.ThemeLayoutMode) {
this.layout.mode = mode;
},
/** 设置系统主题颜色 */
@ -85,7 +78,7 @@ export const useThemeStore = defineStore('theme-store', {
}
},
/** 设置多页签风格 */
setTabMode(mode: ThemeTabMode) {
setTabMode(mode: EnumType.ThemeTabMode) {
this.tab.mode = mode;
},
/** 设置多页签缓存 */
@ -117,7 +110,7 @@ export const useThemeStore = defineStore('theme-store', {
this.sider.mixChildMenuWidth = width;
},
/** 设置水平模式的菜单的位置 */
setHorizontalMenuPosition(posiiton: ThemeHorizontalMenuPosition) {
setHorizontalMenuPosition(posiiton: EnumType.ThemeHorizontalMenuPosition) {
this.menu.horizontalPosition = posiiton;
},
/** 设置底部是否固定 */
@ -133,7 +126,7 @@ export const useThemeStore = defineStore('theme-store', {
this.page.animate = animate;
},
/** 设置页面过渡动画类型 */
setPageAnimateMode(mode: ThemeAnimateMode) {
setPageAnimateMode(mode: EnumType.ThemeAnimateMode) {
this.page.animateMode = mode;
},
},

23
src/typings/api.d.ts vendored Normal file
View File

@ -0,0 +1,23 @@
// 后端接口返回的数据类型
/** 后端返回的用户权益相关类型 */
declare namespace ApiAuth {
/** 返回的token和刷新token */
interface Token {
token: string;
refreshToken: string;
}
/** 返回的用户信息 */
type UserInfo = Auth.UserInfo;
}
/** 后端返回的路由相关类型 */
declare namespace ApiRoute {
/** 后端返回的路由数据类型 */
interface Route {
/** 动态路由 */
routes: AuthRoute.Route[];
/** 路由首页对应的key */
home: AuthRoute.RouteKey;
}
}

View File

@ -1,10 +0,0 @@
/** 后端返回的用户权益相关类型 */
declare namespace ApiAuth {
/** 返回的token和刷新token */
interface Token {
token: string;
refreshToken: string;
}
/** 返回的用户信息 */
type UserInfo = Auth.UserInfo;
}

View File

@ -1,10 +0,0 @@
/** 后端返回的路由相关类型 */
declare namespace ApiRoute {
/** 后端返回的路由数据类型 */
interface Route {
/** 动态路由 */
routes: AuthRoute.Route[];
/** 路由首页对应的key */
home: AuthRoute.RouteKey;
}
}

View File

@ -1,8 +0,0 @@
/** 通用类型 */
declare namespace Common {
/**
*
* [, true时执行的回调函数]
*/
type StrategyAction = [boolean, () => void];
}

View File

@ -1,2 +0,0 @@
/** 构建时间 */
declare const PROJECT_BUILD_TIME: string;

View File

@ -1,7 +0,0 @@
import 'vue-router';
declare module 'vue-router' {
interface RouteMeta extends AuthRoute.RouteMeta {
title: string;
}
}

View File

@ -1,66 +0,0 @@
/** 请求的相关类型 */
declare namespace Service {
/**
* - test:测试环境
* - prod:正式环境 */
type HttpEnv = 'test' | 'prod';
/**
*
* - axios: axios错误, ,
* - http: 请求成功200
* - backend: 请求成功200
*/
type RequestErrorType = 'axios' | 'http' | 'backend';
/** 请求错误 */
interface RequestError {
/** 请求服务的错误类型 */
type: RequestErrorType;
/** 错误码 */
code: string | number;
/** 错误信息 */
msg: string;
}
/** 后端接口返回的数据结构配置 */
interface BackendResultConfig {
/** 表示后端请求状态码的属性字段 */
codeKey: string;
/** 表示后端请求数据的属性字段 */
dataKey: string;
/** 表示后端消息的属性字段 */
msgKey: string;
/** 后端业务上定义的成功请求的状态 */
successCode: number | string;
}
/** 自定义的请求成功结果 */
interface SuccessResult<T = any> {
/** 请求错误 */
error: null;
/** 请求数据 */
data: T;
}
/** 自定义的请求失败结果 */
interface FailedResult {
/** 请求错误 */
error: RequestError;
/** 请求数据 */
data: null;
}
/** 自定义的请求结果 */
type RequestResult<T = any> = SuccessResult<T> | FailedResult;
/** mock示例接口类型后端接口返回的数据的类型 */
interface MockServiceResult<T = any> {
/** 状态码 */
code: string | number;
/** 接口数据 */
data: T;
/** 接口消息 */
message: string;
}
}

View File

@ -1,15 +0,0 @@
import type {
LoadingBarProviderInst,
DialogProviderInst,
MessageProviderInst,
NotificationProviderInst,
} from 'naive-ui';
declare global {
interface Window {
$loadingBar?: LoadingBarProviderInst;
$dialog?: DialogProviderInst;
$message?: MessageProviderInst;
$notification?: NotificationProviderInst;
}
}

6
src/typings/expose.d.ts vendored Normal file
View File

@ -0,0 +1,6 @@
/** vue 的defineExpose导出的类型 */
declare namespace Expose {
interface BetterScroll {
instance: import('@better-scroll/core');
}
}

18
src/typings/global.d.ts vendored Normal file
View File

@ -0,0 +1,18 @@
interface Window {
$loadingBar?: import('naive-ui').LoadingBarProviderInst;
$dialog?: import('naive-ui').DialogProviderInst;
$message?: import('naive-ui').MessageProviderInst;
$notification?: import('naive-ui').NotificationProviderInst;
}
/** 通用类型 */
declare namespace Common {
/**
*
* [, true时执行的回调函数]
*/
type StrategyAction = [boolean, () => void];
}
/** 构建时间 */
declare const PROJECT_BUILD_TIME: string;

5
src/typings/router.d.ts vendored Normal file
View File

@ -0,0 +1,5 @@
import 'vue-router';
declare module 'vue-router' {
interface RouteMeta extends AuthRoute.RouteMeta {}
}

271
src/typings/system.d.ts vendored Normal file
View File

@ -0,0 +1,271 @@
/** 枚举的key类型 */
declare namespace EnumType {
/** 布局组件名称 */
type LayoutComponentName = keyof typeof import('@/enum').EnumLayoutComponentName;
/** 布局模式 */
type ThemeLayoutMode = keyof typeof import('@/enum').EnumThemeLayoutMode;
/** 多页签风格 */
type ThemeTabMode = keyof typeof import('@/enum').EnumThemeTabMode;
/** 水平模式的菜单位置 */
type ThemeHorizontalMenuPosition = keyof typeof import('@/enum').EnumThemeHorizontalMenuPosition;
/** 过渡动画 */
type ThemeAnimateMode = keyof typeof import('@/enum').EnumThemeAnimateMode;
/** 登录模块 */
type LoginModuleKey = keyof typeof import('@/enum').EnumLoginModule;
}
/** 请求的相关类型 */
declare namespace Service {
/**
* - test:测试环境
* - prod:正式环境 */
type HttpEnv = 'test' | 'prod';
/**
*
* - axios: axios错误, ,
* - http: 请求成功200
* - backend: 请求成功200
*/
type RequestErrorType = 'axios' | 'http' | 'backend';
/** 请求错误 */
interface RequestError {
/** 请求服务的错误类型 */
type: RequestErrorType;
/** 错误码 */
code: string | number;
/** 错误信息 */
msg: string;
}
/** 后端接口返回的数据结构配置 */
interface BackendResultConfig {
/** 表示后端请求状态码的属性字段 */
codeKey: string;
/** 表示后端请求数据的属性字段 */
dataKey: string;
/** 表示后端消息的属性字段 */
msgKey: string;
/** 后端业务上定义的成功请求的状态 */
successCode: number | string;
}
/** 自定义的请求成功结果 */
interface SuccessResult<T = any> {
/** 请求错误 */
error: null;
/** 请求数据 */
data: T;
}
/** 自定义的请求失败结果 */
interface FailedResult {
/** 请求错误 */
error: RequestError;
/** 请求数据 */
data: null;
}
/** 自定义的请求结果 */
type RequestResult<T = any> = SuccessResult<T> | FailedResult;
/** mock示例接口类型后端接口返回的数据的类型 */
interface MockServiceResult<T = any> {
/** 状态码 */
code: string | number;
/** 接口数据 */
data: T;
/** 接口消息 */
message: string;
}
}
/** 主题相关类型 */
declare namespace Theme {
/** 主题配置 */
interface Setting {
/** 暗黑模式 */
darkMode: boolean;
/** 布局样式 */
layout: Layout;
/** 主题颜色 */
themeColor: string;
/** 主题颜色列表 */
themeColorList: string[];
/** 其他颜色 */
otherColor: OtherColor;
/** 是否自定义info的颜色(默认取比主题色深一级的颜色) */
isCustomizeInfoColor: boolean;
/** 固定头部和多页签 */
fixedHeaderAndTab: boolean;
/** 显示重载按钮 */
showReload: boolean;
/** 头部样式 */
header: Header;
/** 标多页签样式 */
tab: Tab;
/** 侧边栏样式 */
sider: Sider;
/** 菜单样式 */
menu: Menu;
/** 底部样式 */
footer: Footer;
/** 页面样式 */
page: Page;
}
/** 布局样式 */
interface Layout {
/** 最小宽度 */
minWidth: number;
/** 布局模式 */
mode: EnumType.ThemeLayoutMode;
/** 布局模式列表 */
modeList: LayoutModeList[];
}
interface LayoutModeList {
value: EnumType.ThemeLayoutMode;
label: import('@/enum').EnumThemeLayoutMode;
}
/** 其他主题颜色 */
interface OtherColor {
/** 信息 */
info: string;
/** 成功 */
success: string;
/** 警告 */
warning: string;
/** 错误 */
error: string;
}
/** 头部样式 */
interface Header {
/** 头部高度 */
height: number;
/** 面包屑样式 */
crumb: Crumb;
}
/** 面包屑样式 */
interface Crumb {
/** 面包屑可见 */
visible: boolean;
/** 显示图标 */
showIcon: boolean;
}
/** 标多页签样式 */
export interface Tab {
/** 多页签可见 */
visible: boolean;
/** 多页签高度 */
height: number;
/** 多页签风格 */
mode: EnumType.ThemeTabMode;
/** 多页签风格列表 */
modeList: ThemeTabModeList[];
/** 开启多页签缓存 */
isCache: boolean;
}
/** 多页签风格列表 */
interface ThemeTabModeList {
value: EnumType.ThemeTabMode;
label: import('@/enum').EnumThemeTabMode;
}
/** 侧边栏样式 */
interface Sider {
/** 侧边栏宽度 */
width: number;
/** 侧边栏折叠时的宽度 */
collapsedWidth: number;
/** vertical-mix模式下侧边栏宽度 */
mixWidth: number;
/** vertical-mix模式下侧边栏折叠时的宽度 */
mixCollapsedWidth: number;
/** vertical-mix模式下侧边栏的子菜单的宽度 */
mixChildMenuWidth: number;
}
/** 菜单样式 */
interface Menu {
/** 水平模式的菜单的位置 */
horizontalPosition: HorizontalMenuPosition;
/** 水平模式的菜单的位置列表 */
horizontalPositionList: HorizontalMenuPositionList[];
}
/** 水平模式的菜单的位置列表 */
interface HorizontalMenuPositionList {
value: EnumType.ThemeHorizontalMenuPosition;
label: import('@/enum').EnumThemeHorizontalMenuPosition;
}
/** 底部样式 */
interface Footer {
/** 是否固定底部 */
fixed: boolean;
/** 底部高度 */
height: number;
}
/** 页面样式 */
interface Page {
/** 页面是否开启动画 */
animate: boolean;
/** 动画类型 */
animateMode: EnumType.ThemeAnimateMode;
/** 动画类型列表 */
animateModeList: AnimateModeList[];
}
/** 动画类型列表 */
interface AnimateModeList {
value: EnumType.ThemeAnimateMode;
label: import('@/enum').EnumThemeAnimateMode;
}
}
/** 全局头部属性 */
interface GlobalHeaderProps {
/** 显示logo */
showLogo: boolean;
/** 显示头部菜单 */
showHeaderMenu: boolean;
/** 显示菜单折叠按钮 */
showMenuCollape: boolean;
}
/** 菜单项配置 */
type GlobalMenuOption = {
key: string;
label: string;
routeName: string;
routePath: string;
icon?: () => import('vue').VNodeChild;
children?: GlobalMenuOption[];
};
/** 面包屑 */
type GlobalBreadcrumb = import('naive-ui').DropdownOption & {
key: string;
label: string;
disabled: boolean;
routeName: string;
hasChildren: boolean;
children?: GlobalBreadcrumb[];
};
/** 多页签Tab的路由 */
interface GlobalTabRoute extends Pick<import('vue-router').RouteLocationNormalizedLoaded, 'name' | 'path' | 'meta'> {
/** 滚动的位置 */
scrollPosition: {
left: number;
top: number;
};
}

View File

@ -1,5 +1,3 @@
import type { GlobalMenuOption, GlobalBreadcrumb } from '@/interface';
/**
*
* @param activeKey - key

View File

@ -2,15 +2,14 @@ import type { Component } from 'vue';
import { EnumLayoutComponentName } from '@/enum';
import { BasicLayout, BlankLayout } from '@/layouts';
import { views } from '@/views';
import type { LayoutComponentName } from '@/interface';
type LayoutComponent = Record<LayoutComponentName, () => Promise<Component>>;
type LayoutComponent = Record<EnumType.LayoutComponentName, () => Promise<Component>>;
/**
* vue文件()
* @param layoutType -
*/
export function getLayoutComponent(layoutType: LayoutComponentName) {
export function getLayoutComponent(layoutType: EnumType.LayoutComponentName) {
const layoutComponent: LayoutComponent = {
basic: BasicLayout,
blank: BlankLayout,

View File

@ -1,4 +1,3 @@
import type { GlobalMenuOption } from '@/interface';
import { iconifyRender } from '../common';
/** 路由不转换菜单 */

View File

@ -1,7 +1,5 @@
import type { LoginModuleKey } from '@/interface';
/** 获取登录页面模块的动态路由的正则 */
export function getLoginModuleRegExp() {
const modules: LoginModuleKey[] = ['pwd-login', 'code-login', 'register', 'reset-pwd', 'bind-wechat'];
const modules: EnumType.LoginModuleKey[] = ['pwd-login', 'code-login', 'register', 'reset-pwd', 'bind-wechat'];
return modules.join('|');
}

View File

@ -1,5 +1,4 @@
import { EnumStorageKey } from '@/enum';
import type { GlobalTabRoute } from '@/interface';
import { setLocal, getLocal } from '../storage';
/** 缓存多页签数据 */

View File

@ -1,6 +1,6 @@
import qs from 'qs';
import FormData from 'form-data';
import { ContentType } from '@/enum';
import { EnumContentType } from '@/enum';
import { isArray } from '../common';
/**
@ -12,11 +12,11 @@ export async function transformRequestData(requestData: any, contentType?: strin
// application/json类型不处理
let data = requestData;
// form类型转换
if (contentType === ContentType.formUrlencoded) {
if (contentType === EnumContentType.formUrlencoded) {
data = qs.stringify(requestData);
}
// form-data类型转换
if (contentType === ContentType.formData) {
if (contentType === EnumContentType.formData) {
const key = Object.keys(requestData)[0];
const file = requestData.data[key];
data = await transformFile(file, key);

View File

@ -30,13 +30,3 @@ export const icons = [
'ic:baseline-filter-9',
'ic:baseline-filter-9-plus',
];
// const assetsSvg = import.meta.glob('../../../assets/svg/*.svg');
// const PATH_PREFFIX = '../../../assets/svg/';
// const SUFFIX = '.svg';
// const CUSTOM_ICONIFY_PREFFIX = 'custom-';
// export const svgIcons = Object.keys(assetsSvg).map(key => {
// const svgKey = key.replace(PATH_PREFFIX, '').replace(SUFFIX, '');
// return CUSTOM_ICONIFY_PREFFIX + svgKey;
// });

View File

@ -35,16 +35,15 @@ import { SystemLogo, DarkModeSwitch } from '@/components';
import { useThemeStore } from '@/store';
import { useAppInfo } from '@/composables';
import { getColorPalette, mixColor } from '@/utils';
import type { LoginModuleKey } from '@/interface';
import { LoginBg, PwdLogin, CodeLogin, Register, ResetPwd, BindWechat } from './components';
interface Props {
/** 登录模块分类 */
module: LoginModuleKey;
module: EnumType.LoginModuleKey;
}
interface LoginModule {
key: LoginModuleKey;
key: EnumType.LoginModuleKey;
label: EnumLoginModule;
component: Component;
}