feat(projects): 1.0 beta

This commit is contained in:
Soybean
2023-11-17 08:45:00 +08:00
parent 1ea4817f6a
commit e918a2c0f5
499 changed files with 15918 additions and 24708 deletions

81
src/typings/api.d.ts vendored
View File

@ -1,52 +1,39 @@
// 后端接口返回的数据类型
/**
* namespace Api
* @description all backend api type
*/
declare namespace Api {
/**
* namespace Auth
* @description backend api module: "auth"
*/
namespace Auth {
interface LoginToken {
token: string;
refreshToken: string;
}
/** 后端返回的用户权益相关类型 */
declare namespace ApiAuth {
/** 返回的token和刷新token */
interface Token {
token: string;
refreshToken: string;
interface UserInfo {
userId: string;
userName: string;
roles: string[];
}
}
/** 返回的用户信息 */
type UserInfo = Auth.UserInfo;
}
/** 后端返回的路由相关类型 */
declare namespace ApiRoute {
/** 后端返回的路由数据类型 */
interface Route {
/** 动态路由 */
routes: AuthRoute.Route[];
/** 路由首页对应的key */
home: AuthRoute.AllRouteKey;
}
}
declare namespace ApiUserManagement {
interface User {
/** 用户id */
id: string;
/** 用户名 */
userName: string | null;
/** 用户年龄 */
age: number | null;
/**
* 用户性别
* - 0: 女
* - 1: 男
*/
gender: '0' | '1' | null;
/** 用户手机号码 */
phone: string;
/** 用户邮箱 */
email: string | null;
/**
* 用户状态
* - 1: 启用
* - 2: 禁用
* - 3: 冻结
* - 4: 软删除
*/
userStatus: '1' | '2' | '3' | '4' | null;
/**
* namespace Route
* @description backend api module: "route"
*/
namespace Route {
type ElegantConstRoute = import('@elegant-router/types').ElegantConstRoute;
interface MenuRoute extends ElegantConstRoute {
id: string;
}
interface UserRoute {
routes: MenuRoute[];
home: import('@elegant-router/types').LastLevelRouteKey;
}
}
}

563
src/typings/app.d.ts vendored Normal file
View File

@ -0,0 +1,563 @@
/**
* the global namespace for the app
*/
declare namespace App {
/**
* theme namespace
*/
namespace Theme {
type ColorPaletteNumber = import('@sa/color-palette').ColorPaletteNumber;
/**
* theme token
*/
type ThemeToken = {
colors: ThemeTokenColor;
boxShadow: {
header: string;
sider: string;
tab: string;
};
};
/**
* theme setting
*/
interface ThemeSetting {
/**
* theme scheme
*/
themeScheme: UnionKey.ThemeScheme;
/**
* theme color
*/
themeColor: string;
/**
* other color
*/
otherColor: OtherColor;
/**
* whether info color is followed by the primary color
*/
isInfoFollowPrimary: boolean;
/**
* layout
*/
layout: {
/**
* layout mode
*/
mode: UnionKey.ThemeLayoutMode;
/**
* scroll mode
*/
scrollMode: UnionKey.ThemeScrollMode;
};
/**
* page
*/
page: {
/**
* whether to show the page transition
*/
animate: boolean;
/**
* page animate mode
*/
animateMode: UnionKey.ThemePageAnimateMode;
};
/**
* header
*/
header: {
/**
* header height
*/
height: number;
/**
* header breadcrumb
*/
breadcrumb: {
/**
* whether to show the breadcrumb
*/
visible: boolean;
/**
* whether to show the breadcrumb icon
*/
showIcon: boolean;
};
};
/**
* tab
*/
tab: {
/**
* whether to show the tab
*/
visible: boolean;
/**
* whether to cache the tab
* @description if cache, the tabs will get from the local storage when the page is refreshed
*/
cache: boolean;
/**
* tab height
*/
height: number;
/**
* tab mode
*/
mode: UnionKey.ThemeTabMode;
};
/**
* fixed header and tab
*/
fixedHeaderAndTab: boolean;
/**
* sider
*/
sider: {
/**
* inverted sider
*/
inverted: boolean;
/**
* sider width
*/
width: number;
/**
* collapsed sider width
*/
collapsedWidth: number;
/**
* sider width when the layout is 'vertical-mix' or 'horizontal-mix'
*/
mixWidth: number;
/**
* collapsed sider width when the layout is 'vertical-mix' or 'horizontal-mix'
*/
mixCollapsedWidth: number;
/**
* child menu width when the layout is 'vertical-mix' or 'horizontal-mix'
*/
mixChildMenuWidth: number;
};
/**
* footer
*/
footer: {
/**
* whether to show the footer
*/
visible: boolean;
/**
* whether fixed the footer
*/
fixed: boolean;
/**
* footer height
*/
height: number;
/**
* whether float the footer to the right when the layout is 'horizontal-mix'
*/
right: boolean;
};
}
interface OtherColor {
info: string;
success: string;
warning: string;
error: string;
}
interface ThemeColor extends OtherColor {
primary: string;
}
type ThemeColorKey = keyof ThemeColor;
type ThemePaletteColor = {
[key in ThemeColorKey | `${ThemeColorKey}-${ColorPaletteNumber}`]: string;
};
type BaseToken = Record<string, Record<string, string>>;
interface ThemeTokenColor extends ThemePaletteColor {
nprogress: string;
container: string;
layout: string;
inverted: string;
base_text: string;
[key: string]: string;
}
}
/**
* global namespace
*/
namespace Global {
type VNode = import('vue').VNode;
type RouteLocationNormalizedLoaded = import('vue-router').RouteLocationNormalizedLoaded;
type RouteKey = import('@elegant-router/types').RouteKey;
type RouteMap = import('@elegant-router/types').RouteMap;
type RoutePath = import('@elegant-router/types').RoutePath;
type LastLevelRouteKey = import('@elegant-router/types').LastLevelRouteKey;
/**
* the global header props
*/
interface HeaderProps {
/**
* whether to show the logo
*/
showLogo?: boolean;
/**
* whether to show the menu toggler
*/
showMenuToggler?: boolean;
/**
* whether to show the menu
*/
showMenu?: boolean;
}
/**
* the global menu
*/
interface Menu {
/**
* the menu key
* @description equal to the route key
*/
key: string;
/**
* the menu label
*/
label: string;
/**
* the menu i18n key
*/
i18nKey?: I18n.I18nKey;
/**
* the route key
*/
routeKey: RouteKey;
/**
* the route path
*/
routePath: RoutePath;
/**
* the menu icon
*/
icon?: () => VNode;
/**
* the menu children
*/
children?: Menu[];
}
type Breadcrumb = Omit<Menu, 'children'> & {
options?: Breadcrumb[];
};
/**
* tab route
*/
type TabRoute = Pick<RouteLocationNormalizedLoaded, 'name' | 'path' | 'meta'> &
Partial<Pick<RouteLocationNormalizedLoaded, 'fullPath' | 'query'>>;
/**
* the global tab
*/
type Tab = {
/**
* the tab id
*/
id: string;
/**
* the tab label
*/
label: string;
/**
* the new tab label
* @description if set, the tab label will be replaced by this value
*/
newLabel?: string;
/**
* the tab route key
*/
routeKey: LastLevelRouteKey;
/**
* the tab route path
*/
routePath: RouteMap[LastLevelRouteKey];
/**
* the tab route full path
*/
fullPath: string;
/**
* the tab fixed index
*/
fixedIndex?: number;
/**
* tab icon
* @description iconify icon
*/
icon?: string;
/**
* tab local icon
* @description local icon
*/
localIcon?: string;
/**
* i18n key
*/
i18nKey?: I18n.I18nKey;
};
/**
* form rule
*/
type FormRule = import('naive-ui').FormItemRule;
/**
* the global dropdown key
*/
type DropdownKey = 'closeCurrent' | 'closeOther' | 'closeLeft' | 'closeRight' | 'closeAll';
}
/**
* i18n namespace
* @description locales type
*/
namespace I18n {
type RouteKey = import('@elegant-router/types').RouteKey;
type LangType = 'en-US' | 'zh-CN';
type LangOption = {
label: string;
key: LangType;
};
type I18nRouteKey = Exclude<RouteKey, 'root' | 'not-found'>;
type FormMsg = {
required: string;
invalid: string;
};
type Schema = {
system: {
title: string;
};
common: {
tip: string;
add: string;
addSuccess: string;
edit: string;
editSuccess: string;
delete: string;
deleteSuccess: string;
batchDelete: string;
confirm: string;
cancel: string;
pleaseCheckValue: string;
action: string;
backToHome: string;
lookForward: string;
userCenter: string;
logout: string;
logoutConfirm: string;
};
theme: {
themeSchema: { title: string } & Record<UnionKey.ThemeScheme, string>;
layoutMode: { title: string } & Record<UnionKey.ThemeLayoutMode, string>;
themeColor: {
title: string;
followPrimary: string;
} & Theme.ThemeColor;
scrollMode: { title: string } & Record<UnionKey.ThemeScrollMode, string>;
page: {
animate: string;
mode: { title: string } & Record<UnionKey.ThemePageAnimateMode, string>;
};
fixedHeaderAndTab: string;
header: {
height: string;
breadcrumb: {
visible: string;
showIcon: string;
};
};
tab: {
visible: string;
cache: string;
height: string;
mode: { title: string } & Record<UnionKey.ThemeTabMode, string>;
};
sider: {
inverted: string;
width: string;
collapsedWidth: string;
mixWidth: string;
mixCollapsedWidth: string;
mixChildMenuWidth: string;
};
footer: {
visible: string;
fixed: string;
height: string;
right: string;
};
themeDrawerTitle: string;
pageFunTitle: string;
configOperation: {
copyConfig: string;
copySuccessMsg: string;
resetConfig: string;
resetSuccessMsg: string;
};
};
route: Record<I18nRouteKey, string>;
page: {
login: {
common: {
loginOrRegister: string;
userNamePlaceholder: string;
phonePlaceholder: string;
codePlaceholder: string;
passwordPlaceholder: string;
confirmPasswordPlaceholder: string;
codeLogin: string;
confirm: string;
back: string;
validateSuccess: string;
loginSuccess: string;
welcomeBack: string;
};
pwdLogin: {
title: string;
rememberMe: string;
forgetPassword: string;
register: string;
otherAccountLogin: string;
otherLoginMode: string;
superAdmin: string;
admin: string;
user: string;
};
codeLogin: {
title: string;
getCode: string;
imageCodePlaceholder: string;
};
register: {
title: string;
agreement: string;
protocol: string;
policy: string;
};
resetPwd: {
title: string;
};
bindWeChat: {
title: string;
};
};
};
form: {
userName: FormMsg;
phone: FormMsg;
pwd: FormMsg;
code: FormMsg;
email: FormMsg;
};
dropdown: Record<Global.DropdownKey, string>;
icon: {
themeConfig: string;
themeSchema: string;
lang: string;
fullscreen: string;
fullscreenExit: string;
reload: string;
collapse: string;
expand: string;
pin: string;
unpin: string;
};
};
type GetI18nKey<T extends Record<string, unknown>, K extends keyof T = keyof T> = K extends string
? T[K] extends Record<string, unknown>
? `${K}.${GetI18nKey<T[K]>}`
: K
: never;
type I18nKey = GetI18nKey<Schema>;
type TranslateOptions<Locales extends string> = import('vue-i18n').TranslateOptions<Locales>;
interface $T {
(key: I18nKey): string;
(key: I18nKey, plural: number, options?: TranslateOptions<LangType>): string;
(key: I18nKey, defaultMsg: string, options?: TranslateOptions<I18nKey>): string;
(key: I18nKey, list: unknown[], options?: TranslateOptions<I18nKey>): string;
(key: I18nKey, list: unknown[], plural: number): string;
(key: I18nKey, list: unknown[], defaultMsg: string): string;
(key: I18nKey, named: Record<string, unknown>, options?: TranslateOptions<LangType>): string;
(key: I18nKey, named: Record<string, unknown>, plural: number): string;
(key: I18nKey, named: Record<string, unknown>, defaultMsg: string): string;
}
}
/**
* service namespace
*/
namespace Service {
/**
* the backend service env type
*/
type EnvType = 'dev' | 'test' | 'prod';
/**
* the backend service config
*/
interface ServiceConfig {
/**
* the backend service base url
*/
baseURL: string;
/**
* other backend service base url map
*/
otherBaseURL: Record<string, string>;
}
/**
* the backend service config map
*/
type ServiceConfigMap = Record<EnvType, ServiceConfig>;
/**
* the backend service response data
*/
type Response<T = unknown> = {
/**
* the backend service response code
*/
code: string;
/**
* the backend service response message
*/
message: string;
/**
* the backend service response data
*/
data: T;
};
}
}

View File

@ -1,45 +0,0 @@
/** 用户相关模块 */
declare namespace Auth {
/**
* 用户角色类型(前端静态路由用角色类型进行路由权限的控制)
* - super: 超级管理员(该权限具有所有路由数据)
* - admin: 管理员
* - user: 用户
*/
type RoleType = 'super' | 'admin' | 'user';
/** 用户信息 */
interface UserInfo {
/** 用户id */
userId: string;
/** 用户名 */
userName: string;
/** 用户角色类型 */
userRole: RoleType;
}
}
declare namespace UserManagement {
interface User extends ApiUserManagement.User {
/** 序号 */
index: number;
/** 表格的keyid */
key: string;
}
/**
* 用户性别
* - 0: 女
* - 1: 男
*/
type GenderKey = NonNullable<User['gender']>;
/**
* 用户状态
* - 1: 启用
* - 2: 禁用
* - 3: 冻结
* - 4: 软删除
*/
type UserStatusKey = NonNullable<User['userStatus']>;
}

27
src/typings/common.d.ts vendored Normal file
View File

@ -0,0 +1,27 @@
/**
* the common type namespace
*/
declare namespace Common {
/**
* the strategic pattern
*/
interface StrategicPattern {
/**
* the condition
*/
condition: boolean;
/**
* if the condition is true, then call the action function
*/
callback: () => void;
}
/**
* the option type
* @property value: the option value
* @property label: the option label
*/
type Option<K> = { value: K; label: string };
type YesOrNo = 'Y' | 'N';
}

59
src/typings/components.d.ts vendored Normal file
View File

@ -0,0 +1,59 @@
/* eslint-disable */
/* prettier-ignore */
// @ts-nocheck
// Generated by unplugin-vue-components
// Read more: https://github.com/vuejs/core/pull/3399
export {}
declare module 'vue' {
export interface GlobalComponents {
AppLoading: typeof import('./../components/common/app-loading.vue')['default']
AppProvider: typeof import('./../components/common/app-provider.vue')['default']
BetterScroll: typeof import('./../components/custom/better-scroll.vue')['default']
ButtonIcon: typeof import('./../components/custom/button-icon.vue')['default']
DarkModeContainer: typeof import('./../components/common/dark-mode-container.vue')['default']
ExceptionBase: typeof import('./../components/common/exception-base.vue')['default']
FullScreen: typeof import('./../components/common/full-screen.vue')['default']
IconAntDesignReloadOutlined: typeof import('~icons/ant-design/reload-outlined')['default']
IconGridiconsFullscreen: typeof import('~icons/gridicons/fullscreen')['default']
IconGridiconsFullscreenExit: typeof import('~icons/gridicons/fullscreen-exit')['default']
IconLocalLogo: typeof import('~icons/local/logo')['default']
LangSwitch: typeof import('./../components/common/lang-switch.vue')['default']
LookForward: typeof import('./../components/custom/look-forward.vue')['default']
MenuToggler: typeof import('./../components/common/menu-toggler.vue')['default']
NBreadcrumb: typeof import('naive-ui')['NBreadcrumb']
NBreadcrumbItem: typeof import('naive-ui')['NBreadcrumbItem']
NButton: typeof import('naive-ui')['NButton']
NCalendar: typeof import('naive-ui')['NCalendar']
NCard: typeof import('naive-ui')['NCard']
NCheckbox: typeof import('naive-ui')['NCheckbox']
NDialogProvider: typeof import('naive-ui')['NDialogProvider']
NDivider: typeof import('naive-ui')['NDivider']
NDrawer: typeof import('naive-ui')['NDrawer']
NDrawerContent: typeof import('naive-ui')['NDrawerContent']
NDropdown: typeof import('naive-ui')['NDropdown']
NForm: typeof import('naive-ui')['NForm']
NFormItem: typeof import('naive-ui')['NFormItem']
NInput: typeof import('naive-ui')['NInput']
NInputNumber: typeof import('naive-ui')['NInputNumber']
NInputPassword: typeof import('naive-ui')['NInputPassword']
NLoadingBarProvider: typeof import('naive-ui')['NLoadingBarProvider']
NMenu: typeof import('naive-ui')['NMenu']
NMessageProvider: typeof import('naive-ui')['NMessageProvider']
NNotificationProvider: typeof import('naive-ui')['NNotificationProvider']
NSelect: typeof import('naive-ui')['NSelect']
NSpace: typeof import('naive-ui')['NSpace']
NSwitch: typeof import('naive-ui')['NSwitch']
NTab: typeof import('naive-ui')['NTab']
NTabs: typeof import('naive-ui')['NTabs']
NTooltip: typeof import('naive-ui')['NTooltip']
PinToggler: typeof import('./../components/common/pin-toggler.vue')['default']
ReloadButton: typeof import('./../components/common/reload-button.vue')['default']
RouterLink: typeof import('vue-router')['RouterLink']
RouterView: typeof import('vue-router')['RouterView']
SvgIcon: typeof import('./../components/custom/svg-icon.vue')['default']
SystemLogo: typeof import('./../components/common/system-logo.vue')['default']
ThemeSchemaSwitch: typeof import('./../components/common/theme-schema-switch.vue')['default']
WaveBg: typeof import('./../components/custom/wave-bg.vue')['default']
}
}

259
src/typings/elegant-router.d.ts vendored Normal file
View File

@ -0,0 +1,259 @@
/* eslint-disable */
/* prettier-ignore */
// Generated by elegant-router
// Read more: https://github.com/soybeanjs/elegant-router
declare module "@elegant-router/types" {
type ElegantConstRoute = import('@elegant-router/vue').ElegantConstRoute;
/**
* route layout
*/
export type RouteLayout = "base" | "blank";
/**
* route map
*/
export type RouteMap = {
"root": "/";
"not-found": "/:pathMatch(.*)*";
"403": "/403";
"404": "/404";
"500": "/500";
"home": "/home";
"login": "/login/:module(pwd-login|code-login|register|reset-pwd|bind-wechat)?";
"manage": "/manage";
"manage_role": "/manage/role";
"manage_route": "/manage/route";
"manage_user": "/manage/user";
"manage_user-detail": "/manage/user-detail/:id";
"multi-menu": "/multi-menu";
"multi-menu_first": "/multi-menu/first";
"multi-menu_first_child": "/multi-menu/first/child";
"multi-menu_second": "/multi-menu/second";
"multi-menu_second_child": "/multi-menu/second/child";
"multi-menu_second_child_home": "/multi-menu/second/child/home";
"user-center": "/user-center";
};
/**
* route key
*/
export type RouteKey = keyof RouteMap;
/**
* route path
*/
export type RoutePath = RouteMap[RouteKey];
/**
* custom route key
*/
export type CustomRouteKey = Extract<
RouteKey,
| "root"
| "not-found"
>;
/**
* the generated route key
*/
export type GeneratedRouteKey = Exclude<RouteKey, CustomRouteKey>;
/**
* the first level route key, which contain the layout of the route
*/
export type FirstLevelRouteKey = Extract<
RouteKey,
| "403"
| "404"
| "500"
| "home"
| "login"
| "manage"
| "multi-menu"
| "user-center"
>;
/**
* the custom first level route key
*/
export type CustomFirstLevelRouteKey = Extract<
CustomRouteKey,
| "root"
| "not-found"
>;
/**
* the last level route key, which has the page file
*/
export type LastLevelRouteKey = Extract<
RouteKey,
| "403"
| "404"
| "500"
| "login"
| "home"
| "manage_role"
| "manage_route"
| "manage_user-detail"
| "manage_user"
| "multi-menu_first_child"
| "multi-menu_second_child_home"
| "user-center"
>;
/**
* the custom last level route key
*/
export type CustomLastLevelRouteKey = Extract<
CustomRouteKey,
| "root"
| "not-found"
>;
/**
* the single level route key
*/
export type SingleLevelRouteKey = FirstLevelRouteKey & LastLevelRouteKey;
/**
* the custom single level route key
*/
export type CustomSingleLevelRouteKey = CustomFirstLevelRouteKey & CustomLastLevelRouteKey;
/**
* the first level route key, but not the single level
*/
export type FirstLevelRouteNotSingleKey = Exclude<FirstLevelRouteKey, SingleLevelRouteKey>;
/**
* the custom first level route key, but not the single level
*/
export type CustomFirstLevelRouteNotSingleKey = Exclude<CustomFirstLevelRouteKey, CustomSingleLevelRouteKey>;
/**
* the center level route key
*/
export type CenterLevelRouteKey = Exclude<GeneratedRouteKey, FirstLevelRouteKey | LastLevelRouteKey>;
/**
* the custom center level route key
*/
export type CustomCenterLevelRouteKey = Exclude<CustomRouteKey, CustomFirstLevelRouteKey | CustomLastLevelRouteKey>;
/**
* the center level route key
*/
type GetChildRouteKey<K extends RouteKey, T extends RouteKey = RouteKey> = T extends `${K}_${infer R}`
? R extends `${string}_${string}`
? never
: T
: never;
/**
* the single level route
*/
type SingleLevelRoute<K extends SingleLevelRouteKey = SingleLevelRouteKey> = K extends string
? Omit<ElegantConstRoute, 'children'> & {
name: K;
path: RouteMap[K];
component: `layout.${RouteLayout}$view.${K}`;
}
: never;
/**
* the last level route
*/
type LastLevelRoute<K extends GeneratedRouteKey> = K extends LastLevelRouteKey
? Omit<ElegantConstRoute, 'children'> & {
name: K;
path: RouteMap[K];
component: `view.${K}`;
}
: never;
/**
* the center level route
*/
type CenterLevelRoute<K extends GeneratedRouteKey> = K extends CenterLevelRouteKey
? Omit<ElegantConstRoute, 'component'> & {
name: K;
path: RouteMap[K];
children: (CenterLevelRoute<GetChildRouteKey<K>> | LastLevelRoute<GetChildRouteKey<K>>)[];
}
: never;
/**
* the multi level route
*/
type MultiLevelRoute<K extends FirstLevelRouteNotSingleKey = FirstLevelRouteNotSingleKey> = K extends string
? ElegantConstRoute & {
name: K;
path: RouteMap[K];
component: `layout.${RouteLayout}`;
children: (CenterLevelRoute<GetChildRouteKey<K>> | LastLevelRoute<GetChildRouteKey<K>>)[];
}
: never;
/**
* the custom first level route
*/
type CustomSingleLevelRoute<K extends CustomFirstLevelRouteKey = CustomFirstLevelRouteKey> = K extends string
? Omit<ElegantConstRoute, 'children'> & {
name: K;
path: RouteMap[K];
component?: `layout.${RouteLayout}$view.${LastLevelRouteKey}`;
}
: never;
/**
* the custom last level route
*/
type CustomLastLevelRoute<K extends CustomRouteKey> = K extends CustomLastLevelRouteKey
? Omit<ElegantConstRoute, 'children'> & {
name: K;
path: RouteMap[K];
component?: `view.${LastLevelRouteKey}`;
}
: never;
/**
* the custom center level route
*/
type CustomCenterLevelRoute<K extends CustomRouteKey> = K extends CustomCenterLevelRouteKey
? Omit<ElegantConstRoute, 'component'> & {
name: K;
path: RouteMap[K];
children: (CustomCenterLevelRoute<GetChildRouteKey<K>> | CustomLastLevelRoute<GetChildRouteKey<K>>)[];
}
: never;
/**
* the custom multi level route
*/
type CustomMultiLevelRoute<K extends CustomFirstLevelRouteNotSingleKey = CustomFirstLevelRouteNotSingleKey> =
K extends string
? ElegantConstRoute & {
name: K;
path: RouteMap[K];
component: `layout.${RouteLayout}`;
children: (CustomCenterLevelRoute<GetChildRouteKey<K>> | CustomLastLevelRoute<K>)[];
}
: never;
/**
* the custom route
*/
type CustomRoute = CustomSingleLevelRoute | CustomMultiLevelRoute;
/**
* the generated route
*/
type GeneratedRoute = SingleLevelRoute | MultiLevelRoute;
/**
* the elegant route
*/
type ElegantRoute = GeneratedRoute | CustomRoute;
}

137
src/typings/env.d.ts vendored
View File

@ -1,77 +1,76 @@
/**
*后台服务的环境类型
* - dev: 后台开发环境
* - test: 后台测试环境
* - prod: 后台生产环境
* namespace Env
* @description it is used to declare the type of the import.meta object
*/
type ServiceEnvType = 'dev' | 'test' | 'prod';
/** 后台服务的环境配置 */
interface ServiceEnvConfig {
/** 请求地址 */
url: string;
}
interface ServiceEnvConfigWithProxyPattern extends ServiceEnvConfig {
declare namespace Env {
/**
* 匹配路径的正则字符串
* - 用于拦截地址转发代理(任意以 /开头 + 字符串, 单个/不起作用)
* - 和后端请求地址的前缀无关
* - 有多个后端请求实例时,需要创建不同的值
* the router history mode
*/
proxyPattern: '/proxy-pattern';
}
type RouterHistoryMode = 'hash' | 'history' | 'memory';
interface ImportMetaEnv {
/** 项目基本地址 */
readonly VITE_BASE_URL: string;
/** 项目名称 */
readonly VITE_APP_NAME: string;
/** 项目标题 */
readonly VITE_APP_TITLE: string;
/** 项目描述 */
readonly VITE_APP_DESC: string;
/**
* 权限路由模式:
* - static - 前端声明的静态
* - dynamic - 后端返回的动态
* interface for import.meta
*/
readonly VITE_AUTH_ROUTE_MODE: 'static' | 'dynamic';
/** 路由首页的路径 */
readonly VITE_ROUTE_HOME_PATH: AuthRoute.RoutePath;
/** iconify图标作为组件的前缀 */
readonly VITE_ICON_PREFIX: string;
/**
* 本地SVG图标作为组件的前缀, 请注意一定要包含 VITE_ICON_PREFIX
* - 格式 {VITE_ICON_PREFIX}-{本地图标集合名称}
* - 例如icon-local
*/
readonly VITE_ICON_LOCAL_PREFIX: string;
/** 后端服务的环境类型 */
readonly VITE_SERVICE_ENV?: ServiceEnvType;
/** 开启请求代理 */
readonly VITE_HTTP_PROXY?: 'Y' | 'N';
/** 是否开启打包文件大小结果分析 */
readonly VITE_VISUALIZER?: 'Y' | 'N';
/** 是否开启打包压缩 */
readonly VITE_COMPRESS?: 'Y' | 'N';
/** 压缩算法类型 */
readonly VITE_COMPRESS_TYPE?: 'gzip' | 'brotliCompress' | 'deflate' | 'deflateRaw';
/** 是否应用pwa */
readonly VITE_PWA?: 'Y' | 'N';
/**
* 是否开启生产模式下的mock
* @description 生产模式下会拦截XHR导致无法获取response不使用mock请求时设置为N
*/
readonly VITE_PROD_MOCK?: 'Y' | 'N';
/** hash路由模式 */
readonly VITE_HASH_ROUTE?: 'Y' | 'N';
/** 是否应用自动生成路由的插件 */
readonly VITE_SOYBEAN_ROUTE_PLUGIN?: 'Y' | 'N';
/** 是否是部署的vercel */
readonly VITE_VERCEL?: 'Y' | 'N';
}
interface ImportMeta {
readonly env: ImportMetaEnv;
interface ImportMeta extends ImportMetaEnv {
/**
* the base url of the application
*/
readonly VITE_BASE_URL: string;
/**
* the title of the application
*/
readonly VITE_APP_TITLE: string;
/**
* the description of the application
*/
readonly VITE_APP_DESC: string;
/**
* the router history mode
*/
readonly VITE_ROUTER_HISTORY_MODE?: RouterHistoryMode;
/**
* the prefix of the iconify icon
*/
readonly VITE_ICON_PREFIX: 'icon';
/**
* the prefix of the local icon
* @description this prefix is start with the icon prefix
*/
readonly VITE_ICON_LOCAL_PREFIX: 'local-icon';
/**
* whether to enable the http proxy
* @description only valid in the development environment
*/
readonly VITE_HTTP_PROXY?: Common.YesOrNo;
/**
* the back service env
*/
readonly VITE_SERVICE_ENV?: App.Service.EnvType;
/**
* the auth route mode
* - static: the auth routes is generated in front-end
* - dynamic: the auth routes is generated in back-end
*/
readonly VITE_AUTH_ROUTE_MODE: 'static' | 'dynamic';
/**
* the home route key
* @description it only has effect when the auth route mode is static, if the route mode is dynamic, the home route key is defined in the back-end
*/
readonly VITE_ROUTE_HOME: import('@elegant-router/types').LastLevelRouteKey;
/**
* default menu icon if menu icon is not set
* @description iconify icon name
*/
readonly VITE_MENU_ICON: string;
/**
* whether to build with sourcemap
*/
readonly VITE_SOURCE_MAP?: Common.YesOrNo;
/**
* iconify api provider url
* @description if the project is deployed in intranet, you can set the api provider url to the local iconify server
* @link https://docs.iconify.design/api/providers.html
*/
readonly VITE_ICONIFY_URL?: string;
}
}

View File

@ -1,11 +0,0 @@
/** vue 的defineExpose导出的类型 */
declare namespace Expose {
interface BetterScroll {
instance: import('@better-scroll/core').BScrollInstance;
}
interface ImageVerify {
/** 获取图片验证码 */
getImgCode(): void;
}
}

View File

@ -1,7 +1,23 @@
interface Window {
/**
* NProgress instance
*/
NProgress?: import('nprogress').NProgress;
/**
* loading bar instance
*/
$loadingBar?: import('naive-ui').LoadingBarProviderInst;
/**
* dialog instance
*/
$dialog?: import('naive-ui').DialogProviderInst;
/**
* message instance
*/
$message?: import('naive-ui').MessageProviderInst;
/**
* notification instance
*/
$notification?: import('naive-ui').NotificationProviderInst;
}
@ -13,17 +29,11 @@ interface Document {
startViewTransition?: (callback: () => Promise<void> | void) => ViewTransition;
}
/** 通用类型 */
declare namespace Common {
/**
* 策略模式
* [状态, 为true时执行的回调函数]
*/
type StrategyAction = [boolean, () => void];
/** 选项数据 */
type OptionWithKey<K> = { value: K; label: string };
interface ImportMeta {
readonly env: Env.ImportMeta;
}
/** 构建时间 */
declare const PROJECT_BUILD_TIME: string;
/**
* build time of the project
*/
declare const BUILD_TIME: string;

View File

@ -1,3 +0,0 @@
declare namespace NaiveUI {
type ThemeColor = 'default' | 'error' | 'primary' | 'info' | 'success' | 'warning';
}

View File

@ -1,9 +0,0 @@
/// <reference types="@amap/amap-jsapi-types" />
/// <reference types="bmapgl" />
declare namespace BMap {
class Map extends BMapGL.Map {}
class Point extends BMapGL.Point {}
}
declare const TMap: any;

View File

@ -1,124 +0,0 @@
declare namespace PageRoute {
/**
* the root route key
* @translate 根路由
*/
type RootRouteKey = 'root';
/**
* the not found route, which catch the invalid route path
* @translate 未找到路由(捕获无效路径的路由)
*/
type NotFoundRouteKey = 'not-found';
/**
* the route key
* @translate 页面路由
*/
type RouteKey =
| '403'
| '404'
| '500'
| 'constant-page'
| 'login'
| 'not-found'
| 'about'
| 'auth-demo'
| 'auth-demo_permission'
| 'auth-demo_super'
| 'component'
| 'component_button'
| 'component_card'
| 'component_table'
| 'dashboard'
| 'dashboard_analysis'
| 'dashboard_workbench'
| 'document'
| 'document_naive'
| 'document_project-link'
| 'document_project'
| 'document_vite'
| 'document_vue'
| 'exception'
| 'exception_403'
| 'exception_404'
| 'exception_500'
| 'function'
| 'function_tab-detail'
| 'function_tab-multi-detail'
| 'function_tab'
| 'function_websocket'
| 'management'
| 'management_auth'
| 'management_role'
| 'management_route'
| 'management_user'
| 'multi-menu'
| 'multi-menu_first'
| 'multi-menu_first_second-new'
| 'multi-menu_first_second-new_third'
| 'multi-menu_first_second'
| 'plugin'
| 'plugin_charts'
| 'plugin_charts_antv'
| 'plugin_charts_echarts'
| 'plugin_copy'
| 'plugin_editor'
| 'plugin_editor_markdown'
| 'plugin_editor_quill'
| 'plugin_icon'
| 'plugin_map'
| 'plugin_print'
| 'plugin_swiper'
| 'plugin_video';
/**
* last degree route key, which has the page file
* @translate 最后一级路由(该级路有对应的页面文件)
*/
type LastDegreeRouteKey = Extract<
RouteKey,
| '403'
| '404'
| '500'
| 'constant-page'
| 'login'
| 'not-found'
| 'about'
| 'auth-demo_permission'
| 'auth-demo_super'
| 'component_button'
| 'component_card'
| 'component_table'
| 'dashboard_analysis'
| 'dashboard_workbench'
| 'document_naive'
| 'document_project-link'
| 'document_project'
| 'document_vite'
| 'document_vue'
| 'exception_403'
| 'exception_404'
| 'exception_500'
| 'function_tab-detail'
| 'function_tab-multi-detail'
| 'function_tab'
| 'function_websocket'
| 'management_auth'
| 'management_role'
| 'management_route'
| 'management_user'
| 'multi-menu_first_second-new_third'
| 'multi-menu_first_second'
| 'plugin_charts_antv'
| 'plugin_charts_echarts'
| 'plugin_copy'
| 'plugin_editor_markdown'
| 'plugin_editor_quill'
| 'plugin_icon'
| 'plugin_map'
| 'plugin_print'
| 'plugin_swiper'
| 'plugin_video'
>;
}

151
src/typings/route.d.ts vendored
View File

@ -1,151 +0,0 @@
declare namespace AuthRoute {
/** 根路由路径 */
type RootRoutePath = '/';
/** 捕获无效路由的路由路径 */
type NotFoundRoutePath = '/:pathMatch(.*)*';
type RootRouteKey = PageRoute.RootRouteKey;
type NotFoundRouteKey = PageRoute.NotFoundRouteKey;
type RouteKey = PageRoute.RouteKey;
type LastDegreeRouteKey = PageRoute.LastDegreeRouteKey;
type AllRouteKey = RouteKey | RootRouteKey | NotFoundRouteKey;
/** 路由路径 */
type RoutePath<K extends AllRouteKey = AllRouteKey> = AuthRouteUtils.GetRoutePath<K>;
/**
* 路由的组件
* - basic - 基础布局,具有公共部分的布局
* - blank - 空白布局
* - multi - 多级路由布局(三级路由或三级以上时,除第一级路由和最后一级路由,其余的采用该布局)
* - self - 作为子路由,使用自身的布局(作为最后一级路由,没有子路由)
*/
type RouteComponentType = 'basic' | 'blank' | 'multi' | 'self';
/** 路由描述 */
interface RouteMeta<K extends AuthRoute.RoutePath> {
/** 路由标题(可用来作document.title或者菜单的名称) */
title: string;
/** 用来支持多国语言 如果i18nTitle和title同时存在优先使用i18nTitle */
i18nTitle?: I18nType.I18nKey;
/** 路由的动态路径(需要动态路径的页面需要将path添加进范型参数) */
dynamicPath?: AuthRouteUtils.GetDynamicPath<K>;
/** 作为单级路由的父级路由布局组件 */
singleLayout?: Extract<RouteComponentType, 'basic' | 'blank'>;
/** 需要登录权限 */
requiresAuth?: boolean;
/**
* 哪些类型的用户有权限才能访问的路由(空的话则表示不需要权限)
* @description 后端动态路由数据不需要该属性,直接由后端根据用户角色返回对应权限的路由数据
*/
permissions?: Auth.RoleType[];
/** 缓存页面 */
keepAlive?: boolean;
/** 菜单和面包屑对应的图标 */
icon?: string;
/** 使用本地svg作为的菜单和面包屑对应的图标(assets/svg-icon文件夹的的svg文件名) */
localIcon?: string;
/** 是否在菜单中隐藏(一些列表、表格的详情页面需要通过参数跳转,所以不能显示在菜单中) */
hide?: boolean;
/** 外链链接 */
href?: string;
/** 是否支持多个tab页签(默认一个即相同name的路由会被替换) */
multiTab?: boolean;
/** 路由顺序,可用于菜单的排序 */
order?: number;
/** 当前路由需要选中的菜单项(用于跳转至不在左侧菜单显示的路由且需要高亮某个菜单的情况) */
activeMenu?: RouteKey;
/** 表示是否是多级路由的中间级路由(用于转换路由数据时筛选多级路由的标识,定义路由时不用填写) */
multi?: boolean;
/** 是否固定在tab卡不可关闭 */
affix?: boolean;
}
type Route<K extends AllRouteKey = AllRouteKey> = K extends AllRouteKey
? {
/** 路由名称(路由唯一标识) */
name: K;
/** 路由路径 */
path: AuthRouteUtils.GetRoutePath<K>;
/** 路由重定向 */
redirect?: AuthRouteUtils.GetRoutePath;
/**
* 路由组件
* - basic: 基础布局,具有公共部分的布局
* - blank: 空白布局
* - multi: 多级路由布局(三级路由或三级以上时,除第一级路由和最后一级路由,其余的采用该布局)
* - self: 作为子路由,使用自身的布局(作为最后一级路由,没有子路由)
*/
component?: RouteComponentType;
/** 子路由 */
children?: Route[];
/** 路由描述 */
meta: RouteMeta<RoutePath<K>>;
} & Omit<import('vue-router').RouteRecordRaw, 'name' | 'path' | 'redirect' | 'component' | 'children' | 'meta'>
: never;
/** 前端导入的路由模块 */
type RouteModule = Record<string, { default: Route }>;
}
declare namespace AuthRouteUtils {
/** 路由key层级分割符 */
type RouteKeySplitMark = '_';
/** 路由path层级分割符 */
type RoutePathSplitMark = '/';
/** 空白字符串 */
type BlankString = '';
/** key转换成path */
type KeyToPath<K extends string> = K extends `${infer _Left}${RouteKeySplitMark}${RouteKeySplitMark}${infer _Right}`
? never
: K extends `${infer Left}${RouteKeySplitMark}${infer Right}`
? Left extends BlankString
? never
: Right extends BlankString
? never
: KeyToPath<`${Left}${RoutePathSplitMark}${Right}`>
: `${RoutePathSplitMark}${K}`;
/** 根据路由key获取路由路径 */
type GetRoutePath<K extends AuthRoute.AllRouteKey = AuthRoute.AllRouteKey> = K extends AuthRoute.AllRouteKey
? K extends AuthRoute.RootRouteKey
? AuthRoute.RootRoutePath
: K extends AuthRoute.NotFoundRouteKey
? AuthRoute.NotFoundRoutePath
: KeyToPath<K>
: never;
/** 获取一级路由(有子路由的一级路由和没有子路由的路由) */
type GetFirstDegreeRouteKey<K extends AuthRoute.RouteKey = AuthRoute.RouteKey> =
K extends `${infer _Left}${RouteKeySplitMark}${infer _Right}` ? never : K;
/** 获取有子路由的一级路由 */
type GetFirstDegreeRouteKeyWithChildren<K extends AuthRoute.RouteKey = AuthRoute.RouteKey> =
K extends `${infer Left}${RouteKeySplitMark}${infer _Right}` ? Left : never;
/** 单级路由的key (单级路由需要添加一个父级路由用于应用布局组件) */
type SingleRouteKey = Exclude<
GetFirstDegreeRouteKey,
GetFirstDegreeRouteKeyWithChildren | AuthRoute.RootRouteKey | AuthRoute.NotFoundRouteKey
>;
/** 单独路由父级路由key */
type SingleRouteParentKey = `${SingleRouteKey}-parent`;
/** 单独路由父级路由path */
type SingleRouteParentPath = KeyToPath<SingleRouteParentKey>;
/** 获取路由动态路径 */
type GetDynamicPath<P extends AuthRoute.RoutePath> =
| `${P}/:${string}`
| `${P}/:${string}(${string})`
| `${P}/:${string}(${string})?`;
}

View File

@ -1,5 +1,66 @@
import 'vue-router';
declare module 'vue-router' {
interface RouteMeta extends AuthRoute.RouteMeta<AuthRoute.RoutePath> {}
interface RouteMeta {
/**
* title of the route
* @description it can be used in document title
*/
title: string;
/**
* i18n key of the route
* @description it's used in i18n, if it is set, the title will be ignored
*/
i18nKey?: App.I18n.I18nKey;
/**
* roles of the route
* @description route can be accessed if the current user has at least one of the roles
*/
roles?: string[];
/**
* whether to cache the route
*/
keepAlive?: boolean;
/**
* is constant route
* @description does not need to login, and the route is defined in the front-end
*/
constant?: boolean;
/**
* iconify icon
* @description it can be used in the menu or breadcrumb
*/
icon?: string;
/**
* local icon
* @description in "src/assets/svg-icon", if it is set, the icon will be ignored
*/
localIcon?: string;
/**
* router order
*/
order?: number;
/**
* the outer link of the route
*/
href?: string;
/**
* whether to hide the route in the menu
*/
hideInMenu?: boolean;
/**
* the menu key will be activated when entering the route
* @description the route is not in the menu
* @example the route is "user_detail", if it is set to "user_list", the menu "user_list" will be activated
*/
activeMenu?: import('@elegant-router/types').LastLevelRouteKey;
/**
* by default, the same route path will use one tab, if set to true, it will use multiple tabs
*/
multiTab?: boolean;
/**
* if set, the route will be fixed in tabs, and the value is the order of fixed tabs
*/
fixedIndexInTab?: number;
}
}

View File

@ -1,23 +1,51 @@
declare namespace StorageInterface {
/** localStorage的存储数据的类型 */
/**
* the storage namespace
*/
declare namespace StorageType {
interface Session {
/** 主题颜色 */
/**
* the theme color
*/
themeColor: string;
/** 主题配置 */
themeSettings: Theme.Setting;
// /**
// * the theme settings
// */
// themeSettings: App.Theme.ThemeSetting;
}
/** localStorage的存储数据的类型 */
interface Local {
/** 用户token */
/**
* the i18n language
*/
lang: App.I18n.LangType;
/**
* the token
*/
token: string;
/** 用户刷新token */
/**
* the refresh token
*/
refreshToken: string;
/** 用户信息 */
userInfo: Auth.UserInfo;
/** 多页签路由信息 */
multiTabRoutes: App.GlobalTabRoute[];
/** 本地语言缓存 */
lang: I18nType.LangType;
/**
* the user info
*/
userInfo: Api.Auth.UserInfo;
/**
* the theme color
*/
themeColor: string;
/**
* the theme settings
*/
themeSettings: App.Theme.ThemeSetting;
/**
* the override theme flags
* @description the value is the build time of the project
*/
overrideThemeFlag: string;
/**
* the global tabs
*/
globalTabs: App.Global.Tab[];
}
}

View File

@ -1,534 +0,0 @@
/** 请求的相关类型 */
declare namespace Service {
/**
* 请求的错误类型:
* - axios: axios错误网络错误, 请求超时, 默认的兜底错误
* - http: 请求成功响应的http状态码非200的错误
* - backend: 请求成功响应的http状态码为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;
/** 多个请求数据结果 */
type MultiRequestResult<T extends any[]> = T extends [infer First, ...infer Rest]
? [First] extends [any]
? Rest extends any[]
? [Service.RequestResult<First>, ...MultiRequestResult<Rest>]
: [Service.RequestResult<First>]
: Rest extends any[]
? MultiRequestResult<Rest>
: []
: [];
/** 请求结果的适配器函数 */
type ServiceAdapter<T = any, A extends any[] = any> = (...args: A) => T;
/** mock示例接口类型后端接口返回的数据的类型 */
interface MockServiceResult<T = any> {
/** 状态码 */
code: string | number;
/** 接口数据 */
data: T;
/** 接口消息 */
message: string;
}
/** mock的响应option */
interface MockOption {
url: Record<string, any>;
body: Record<string, any>;
query: Record<string, any>;
headers: Record<string, any>;
}
}
/** 主题相关类型 */
declare namespace Theme {
/** 主题配置 */
interface Setting {
/** 暗黑模式 */
darkMode: boolean;
/** 是否自动跟随系统主题 */
followSystemTheme: boolean;
/** 自定义暗黑动画过渡 */
isCustomizeDarkModeTransition: boolean;
/** 布局样式 */
layout: Layout;
/** 滚动模式 */
scrollMode: UnionKey.ThemeScrollMode;
/** 滚动模式列表 */
scrollModeList: Common.OptionWithKey<UnionKey.ThemeScrollMode>[];
/** 主题颜色 */
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: UnionKey.ThemeLayoutMode;
/** 布局模式列表 */
modeList: Common.OptionWithKey<UnionKey.ThemeLayoutMode>[];
}
/** 其他主题颜色 */
interface OtherColor {
/** 信息 */
info: string;
/** 成功 */
success: string;
/** 警告 */
warning: string;
/** 错误 */
error: string;
}
/** 头部样式 */
interface Header {
/** 头部反转色 */
inverted: boolean;
/** 头部高度 */
height: number;
/** 面包屑样式 */
crumb: Crumb;
}
/** 面包屑样式 */
interface Crumb {
/** 面包屑可见 */
visible: boolean;
/** 显示图标 */
showIcon: boolean;
}
/** 标多页签样式 */
export interface Tab {
/** 多页签可见 */
visible: boolean;
/** 多页签高度 */
height: number;
/** 多页签风格 */
mode: UnionKey.ThemeTabMode;
/** 多页签风格列表 */
modeList: Common.OptionWithKey<UnionKey.ThemeTabMode>[];
/** 开启多页签缓存 */
isCache: boolean;
}
/** 侧边栏样式 */
interface Sider {
/** 侧边栏反转色 */
inverted: boolean;
/** 侧边栏宽度 */
width: number;
/** 侧边栏折叠时的宽度 */
collapsedWidth: number;
/** vertical-mix模式下侧边栏宽度 */
mixWidth: number;
/** vertical-mix模式下侧边栏折叠时的宽度 */
mixCollapsedWidth: number;
/** vertical-mix模式下侧边栏的子菜单的宽度 */
mixChildMenuWidth: number;
}
/** 菜单样式 */
interface Menu {
/** 水平模式的菜单的位置 */
horizontalPosition: UnionKey.ThemeHorizontalMenuPosition;
/** 水平模式的菜单的位置列表 */
horizontalPositionList: Common.OptionWithKey<UnionKey.ThemeHorizontalMenuPosition>[];
}
/** 底部样式 */
interface Footer {
/* 底部是否可见 */
visible: boolean;
/** 是否固定底部 */
fixed: boolean;
/** 底部是否居右(顶部混合菜单模式有效) */
right: boolean;
/** 底部高度 */
height: number;
/** 底部反转色 */
inverted: boolean;
}
/** 页面样式 */
interface Page {
/** 页面是否开启动画 */
animate: boolean;
/** 动画类型 */
animateMode: UnionKey.ThemeAnimateMode;
/** 动画类型列表 */
animateModeList: Common.OptionWithKey<UnionKey.ThemeAnimateMode>[];
}
}
declare namespace App {
/** 全局头部属性 */
interface GlobalHeaderProps {
/** 显示logo */
showLogo: boolean;
/** 显示头部菜单 */
showHeaderMenu: boolean;
/** 显示菜单折叠按钮 */
showMenuCollapse: boolean;
}
/** 菜单项配置 */
type GlobalMenuOption = import('naive-ui').MenuOption & {
key: string;
label: string;
routeName: string;
routePath: string;
icon?: () => import('vue').VNodeChild;
children?: GlobalMenuOption[];
i18nTitle?: I18nType.I18nKey;
};
/** 面包屑 */
type GlobalBreadcrumb = Omit<import('naive-ui').DropdownOption, 'icon'> & {
key: string;
label: string;
disabled: boolean;
routeName: string;
hasChildren: boolean;
icon?: import('vue').Component;
i18nTitle?: I18nType.I18nKey;
options?: (import('naive-ui/es/dropdown/src/interface').DropdownMixedOption & { i18nTitle?: I18nType.I18nKey })[];
};
/** 多页签Tab的路由 */
interface GlobalTabRoute
extends Pick<import('vue-router').RouteLocationNormalizedLoaded, 'name' | 'fullPath' | 'meta'> {
/** 滚动的位置 */
scrollPosition: {
left: number;
top: number;
};
}
interface MessageTab {
/** tab的key */
key: number;
/** tab名称 */
name: string;
/** badge类型 */
badgeProps?: import('naive-ui').BadgeProps;
/** 消息数据 */
list: MessageList[];
}
interface MessageList {
/** 数据唯一值 */
id: number;
/** 头像 */
avatar?: string;
/** 消息icon */
icon?: string;
svgIcon?: string;
/** 消息标题 */
title: string;
/** 消息发送时间 */
date?: string;
/** 消息是否已读 */
isRead?: boolean;
/** 消息描述 */
description?: string;
/** 标签名称 */
tagTitle?: string;
/** 标签props */
tagProps?: import('naive-ui').TagProps;
}
}
declare namespace I18nType {
type LangType = 'en' | 'zh-CN' | 'km-KH';
type Schema = {
system: {
title: string;
};
common: {
add: string;
addSuccess: string;
edit: string;
editSuccess: string;
delete: string;
deleteSuccess: string;
batchDelete: string;
confirm: string;
cancel: string;
pleaseCheckValue: string;
action: string;
};
routes: {
dashboard: {
_value: string;
analysis: string;
workbench: string;
};
document: {
_value: string;
vue: string;
vite: string;
naive: string;
project: string;
'project-link': string;
};
component: {
_value: string;
button: string;
card: string;
table: string;
};
plugin: {
_value: string;
charts: {
_value: string;
antv: string;
echarts: string;
};
copy: string;
editor: {
_value: string;
markdown: string;
quill: string;
};
icon: string;
map: string;
print: string;
swiper: string;
video: string;
};
'auth-demo': {
_value: string;
permission: string;
super: string;
};
function: {
_value: string;
tab: string;
};
exception: {
_value: string;
'403': string;
'404': string;
'500': string;
};
'multi-menu': {
_value: string;
first: {
_value: string;
second: string;
'second-new': {
_value: string;
third: string;
};
};
};
management: {
_value: string;
auth: string;
role: string;
route: string;
user: string;
};
about: string;
};
layout: {
settingDrawer: {
title: string;
themeModeTitle: string;
darkMode: string;
layoutModelTitle: string;
systemThemeTitle: string;
pageFunctionsTitle: string;
pageViewTitle: string;
followSystemTheme: string;
isCustomizeDarkModeTransition: string;
scrollMode: string;
scrollModeList: {
wrapper: string;
content: string;
};
fixedHeaderAndTab: string;
header: {
inverted: string;
height: string;
crumb: {
visible: string;
icon: string;
};
};
tab: {
visible: string;
height: string;
modeList: {
mode: string;
chrome: string;
button: string;
};
isCache: string;
};
sider: {
inverted: string;
width: string;
mixWidth: string;
};
menu: {
horizontalPosition: string;
horizontalPositionList: {
flexStart: string;
center: string;
flexEnd: string;
};
};
footer: {
inverted: string;
visible: string;
fixed: string;
right: string;
};
page: {
animate: string;
animateMode: string;
animateModeList: {
zoomFade: string;
zoomOut: string;
fadeSlide: string;
fade: string;
fadeBottom: string;
fadeScale: string;
};
};
systemTheme: {
moreColors: string;
};
themeConfiguration: {
title: string;
copy: string;
reset: string;
resetSuccess: string;
operateSuccess: string;
copySuccess: string;
confirmCopy: string;
};
};
};
page: {
login: {
common: {
userNamePlaceholder: string;
phonePlaceholder: string;
codePlaceholder: string;
passwordPlaceholder: string;
confirmPasswordPlaceholder: string;
codeLogin: string;
confirm: string;
back: string;
validateSuccess: string;
loginSuccess: string;
welcomeBack: string;
};
pwdLogin: {
title: string;
rememberMe: string;
forgetPassword: string;
register: string;
otherAccountLogin: string;
otherLoginMode: string;
superAdmin: string;
admin: string;
user: string;
};
codeLogin: {
title: string;
getCode: string;
imageCodePlaceholder: string;
};
register: {
title: string;
agreement: string;
protocol: string;
policy: string;
};
resetPwd: {
title: string;
};
bindWeChat: {
title: string;
};
};
};
};
type GetI18nKey<T extends Record<string, unknown>, K extends keyof T = keyof T> = K extends string
? T[K] extends Record<string, unknown>
? `${K}.${GetI18nKey<T[K]>}`
: K
: never;
type I18nKey = GetI18nKey<Schema>;
}

View File

@ -1,63 +1,153 @@
/**
* the union key namespace
*/
declare namespace UnionKey {
/** http请求头的content-type类型 */
type ContentType = 'application/json' | 'application/x-www-form-urlencoded' | 'multipart/form-data';
/**
* 布局组件的名称
* - basic 基础布局
* - blank 空白布局
*/
type LayoutComponentType = 'basic' | 'blank';
/**
* 登录模块
* - pwd-login: 账密登录
* - code-login: 手机验证码登录
* - register: 注册
* - reset-pwd: 重置密码
* - bind-wechat: 微信绑定
* the login module
* - pwd-login: password login
* - code-login: phone code login
* - register: register
* - reset-pwd: reset password
* - bind-wechat: bind wechat
*/
type LoginModule = 'pwd-login' | 'code-login' | 'register' | 'reset-pwd' | 'bind-wechat';
/**
* 布局模式
* - vertical: 左侧菜单模式
* - horizontal: 顶部菜单模式
* - vertical-mix: 左侧菜单混合模式
* - horizontal-mix: 顶部菜单混合模式
* theme scheme
*/
type ThemeScheme = 'light' | 'dark' | 'auto';
/**
* the layout mode
* - vertical: the vertical menu in left
* - horizontal: the horizontal menu in top
* - vertical-mix: two vertical mixed menus in left
* - horizontal-mix: the vertical menu in left and horizontal menu in top
*/
type ThemeLayoutMode = 'vertical' | 'horizontal' | 'vertical-mix' | 'horizontal-mix';
/**
* 内容溢出时的出现滚动条的方式
* - wrapper 布局组件最外层的元素出现滚动条
* - content 主体内容组件出现滚动条
* the scroll mode when content overflow
* - wrapper the wrapper component's root element overflow
* - content the content component overflow
*/
type ThemeScrollMode = 'wrapper' | 'content';
type ThemeScrollMode = import('@sa/materials').LayoutScrollMode;
/**
* 多页签风格
* - chrome: 谷歌风格
* - button: 按钮风格
* page animate mode
*/
type ThemeTabMode = 'chrome' | 'button';
type ThemePageAnimateMode = 'fade' | 'fade-slide' | 'fade-bottom' | 'fade-scale' | 'zoom-fade' | 'zoom-out' | 'none';
/**
* 水平模式的菜单位置
* - flex-start: 居左
* - center: 居中
* - flex-end: 居右
* tab mode
* - chrome: chrome style
* - button: button style
*/
type ThemeHorizontalMenuPosition = 'flex-start' | 'center' | 'flex-end';
type ThemeTabMode = import('@sa/materials').PageTabMode;
/**
* 过渡动画类型
* - zoom-fade: 渐变
* - zoom-out: 闪现
* - fade-slide: 滑动
* - fade: 消退
* - fade-bottom: 底部消退
* - fade-scale: 缩放消退
* unocss animate key
*/
type ThemeAnimateMode = 'zoom-fade' | 'zoom-out' | 'fade-slide' | 'fade' | 'fade-bottom' | 'fade-scale';
type UnoCssAnimateKey =
| 'pulse'
| 'bounce'
| 'spin'
| 'ping'
| 'bounce-alt'
| 'flash'
| 'pulse-alt'
| 'rubber-band'
| 'shake-x'
| 'shake-y'
| 'head-shake'
| 'swing'
| 'tada'
| 'wobble'
| 'jello'
| 'heart-beat'
| 'hinge'
| 'jack-in-the-box'
| 'light-speed-in-left'
| 'light-speed-in-right'
| 'light-speed-out-left'
| 'light-speed-out-right'
| 'flip'
| 'flip-in-x'
| 'flip-in-y'
| 'flip-out-x'
| 'flip-out-y'
| 'rotate-in'
| 'rotate-in-down-left'
| 'rotate-in-down-right'
| 'rotate-in-up-left'
| 'rotate-in-up-right'
| 'rotate-out'
| 'rotate-out-down-left'
| 'rotate-out-down-right'
| 'rotate-out-up-left'
| 'rotate-out-up-right'
| 'roll-in'
| 'roll-out'
| 'zoom-in'
| 'zoom-in-down'
| 'zoom-in-left'
| 'zoom-in-right'
| 'zoom-in-up'
| 'zoom-out'
| 'zoom-out-down'
| 'zoom-out-left'
| 'zoom-out-right'
| 'zoom-out-up'
| 'bounce-in'
| 'bounce-in-down'
| 'bounce-in-left'
| 'bounce-in-right'
| 'bounce-in-up'
| 'bounce-out'
| 'bounce-out-down'
| 'bounce-out-left'
| 'bounce-out-right'
| 'bounce-out-up'
| 'slide-in-down'
| 'slide-in-left'
| 'slide-in-right'
| 'slide-in-up'
| 'slide-out-down'
| 'slide-out-left'
| 'slide-out-right'
| 'slide-out-up'
| 'fade-in'
| 'fade-in-down'
| 'fade-in-down-big'
| 'fade-in-left'
| 'fade-in-left-big'
| 'fade-in-right'
| 'fade-in-right-big'
| 'fade-in-up'
| 'fade-in-up-big'
| 'fade-in-top-left'
| 'fade-in-top-right'
| 'fade-in-bottom-left'
| 'fade-in-bottom-right'
| 'fade-out'
| 'fade-out-down'
| 'fade-out-down-big'
| 'fade-out-left'
| 'fade-out-left-big'
| 'fade-out-right'
| 'fade-out-right-big'
| 'fade-out-up'
| 'fade-out-up-big'
| 'fade-out-top-left'
| 'fade-out-top-right'
| 'fade-out-bottom-left'
| 'fade-out-bottom-right'
| 'back-in-up'
| 'back-in-down'
| 'back-in-right'
| 'back-in-left'
| 'back-out-up'
| 'back-out-down'
| 'back-out-right'
| 'back-out-left';
}

View File

@ -1,44 +0,0 @@
declare namespace TypeUtil {
type Noop = (...args: any) => any;
interface DataType {
number: number;
string: string;
boolean: boolean;
null: null;
undefined: undefined;
symbol: symbol;
bigInt: bigint;
object: Record<string, any>;
array: Array<any>;
function: (...args: any[]) => any | void;
date: Date;
regExp: RegExp;
promise: Promise<any>;
set: Set<any>;
map: Map<any, any>;
file: File;
}
type DataTypeStringKey = keyof DataType;
type DataTypeString<T extends DataTypeStringKey = DataTypeStringKey> = `[object ${Capitalize<T>}]`;
type UnionInclude<T, K extends keyof T> = K extends keyof T ? true : false;
type Writable<T> = { [K in keyof T]: T[K] };
type FirstOfArray<T extends any[]> = T extends [infer First, ...infer _Rest] ? First : never;
type LastOfArray<T extends any[]> = T extends [...infer _Rest, infer Last] ? Last : never;
// union to tuple
type Union2IntersectionFn<T> = (T extends unknown ? (k: () => T) => void : never) extends (k: infer R) => void
? R
: never;
type GetUnionLast<U> = Union2IntersectionFn<U> extends () => infer I ? I : never;
type UnionToTuple<T, R extends any[] = []> = [T] extends [never]
? R
: UnionToTuple<Exclude<T, GetUnionLast<T>>, [GetUnionLast<T>, ...R]>;
}