mirror of
https://github.com/soybeanjs/soybean-admin.git
synced 2025-09-17 17:26:38 +08:00
refactor(projects): remove enum
This commit is contained in:
parent
44b544745d
commit
21d5214247
10
.eslintrc.js
10
.eslintrc.js
@ -38,6 +38,11 @@ module.exports = {
|
||||
group: 'external',
|
||||
position: 'before'
|
||||
},
|
||||
{
|
||||
pattern: '@/constants',
|
||||
group: 'internal',
|
||||
position: 'before'
|
||||
},
|
||||
{
|
||||
pattern: '@/config',
|
||||
group: 'internal',
|
||||
@ -48,11 +53,6 @@ module.exports = {
|
||||
group: 'internal',
|
||||
position: 'before'
|
||||
},
|
||||
{
|
||||
pattern: '@/enum',
|
||||
group: 'internal',
|
||||
position: 'before'
|
||||
},
|
||||
{
|
||||
pattern: '@/plugins',
|
||||
group: 'internal',
|
||||
|
@ -3,7 +3,7 @@ import { breakpointsTailwind, useBreakpoints } from '@vueuse/core';
|
||||
import { useAppStore, useThemeStore } from '@/store';
|
||||
|
||||
type LayoutMode = 'vertical' | 'horizontal';
|
||||
type LayoutHeaderProps = Record<EnumType.ThemeLayoutMode, App.GlobalHeaderProps>;
|
||||
type LayoutHeaderProps = Record<UnionKey.ThemeLayoutMode, App.GlobalHeaderProps>;
|
||||
|
||||
export function useBasicLayout() {
|
||||
const app = useAppStore();
|
||||
|
@ -42,8 +42,8 @@ export function useRouterPush(inSetup = true) {
|
||||
* @param loginModule - 展示的登录模块
|
||||
* @param redirectUrl - 重定向地址(登录成功后跳转的地址),默认undefined表示取当前地址为重定向地址
|
||||
*/
|
||||
function toLogin(loginModule?: EnumType.LoginModuleKey, redirectUrl?: string) {
|
||||
const module: EnumType.LoginModuleKey = loginModule || 'pwd-login';
|
||||
function toLogin(loginModule?: UnionKey.LoginModule, redirectUrl?: string) {
|
||||
const module: UnionKey.LoginModule = loginModule || 'pwd-login';
|
||||
const routeLocation: RouteLocationRaw = {
|
||||
name: routeName('login'),
|
||||
params: { module }
|
||||
@ -57,7 +57,7 @@ export function useRouterPush(inSetup = true) {
|
||||
* 登录页切换其他模块
|
||||
* @param module - 切换后的登录模块
|
||||
*/
|
||||
function toLoginModule(module: EnumType.LoginModuleKey) {
|
||||
function toLoginModule(module: UnionKey.LoginModule) {
|
||||
const { query } = route.value;
|
||||
routerPush({ name: routeName('login'), params: { module }, query });
|
||||
}
|
||||
|
@ -1,10 +1,30 @@
|
||||
export const loginModuleLabels: Record<UnionKey.LoginModule, string> = {
|
||||
'pwd-login': '账密登录',
|
||||
'code-login': '手机验证码登录',
|
||||
register: '注册',
|
||||
'reset-pwd': '重置密码',
|
||||
'bind-wechat': '微信绑定'
|
||||
};
|
||||
|
||||
export const userRoleLabels: Record<Auth.RoleType, string> = {
|
||||
super: '超级管理员',
|
||||
admin: '管理员',
|
||||
user: '普通用户'
|
||||
};
|
||||
|
||||
export const userRoleOptions: Common.OptionWithKey<Auth.RoleType>[] = [
|
||||
{ value: 'super', label: userRoleLabels.super },
|
||||
{ value: 'admin', label: userRoleLabels.admin },
|
||||
{ value: 'user', label: userRoleLabels.user }
|
||||
];
|
||||
|
||||
/** 用户性别 */
|
||||
export const genderLabels: Record<UserManagement.GenderKey, string> = {
|
||||
0: '女',
|
||||
1: '男'
|
||||
};
|
||||
|
||||
export const genderOptions: { value: UserManagement.GenderKey; label: string }[] = [
|
||||
export const genderOptions: Common.OptionWithKey<UserManagement.GenderKey>[] = [
|
||||
{ value: '0', label: genderLabels['0'] },
|
||||
{ value: '1', label: genderLabels['1'] }
|
||||
];
|
||||
@ -17,7 +37,7 @@ export const userStatusLabels: Record<UserManagement.UserStatusKey, string> = {
|
||||
4: '软删除'
|
||||
};
|
||||
|
||||
export const userStatusOptions: { value: UserManagement.UserStatusKey; label: string }[] = [
|
||||
export const userStatusOptions: Common.OptionWithKey<UserManagement.UserStatusKey>[] = [
|
||||
{ value: '1', label: userStatusLabels['1'] },
|
||||
{ value: '2', label: userStatusLabels['2'] },
|
||||
{ value: '3', label: userStatusLabels['3'] },
|
||||
|
18
src/constants/common.ts
Normal file
18
src/constants/common.ts
Normal file
@ -0,0 +1,18 @@
|
||||
export const dataTypeLabels: { [K in TypeUtil.DataTypeStringKey]: TypeUtil.DataTypeString<K> } = {
|
||||
string: '[object String]',
|
||||
number: '[object Number]',
|
||||
boolean: '[object Boolean]',
|
||||
null: '[object Null]',
|
||||
undefined: '[object Undefined]',
|
||||
symbol: '[object Symbol]',
|
||||
bigInt: '[object BigInt]',
|
||||
object: '[object Object]',
|
||||
function: '[object Function]',
|
||||
array: '[object Array]',
|
||||
date: '[object Date]',
|
||||
regExp: '[object RegExp]',
|
||||
promise: '[object Promise]',
|
||||
set: '[object Set]',
|
||||
map: '[object Map]',
|
||||
file: '[object File]'
|
||||
};
|
@ -1 +1,3 @@
|
||||
export * from './common';
|
||||
export * from './system';
|
||||
export * from './business';
|
||||
|
98
src/constants/system.ts
Normal file
98
src/constants/system.ts
Normal file
@ -0,0 +1,98 @@
|
||||
export const themeLayoutModeLabels: Record<UnionKey.ThemeLayoutMode, string> = {
|
||||
vertical: '左侧菜单模式',
|
||||
horizontal: '顶部菜单模式',
|
||||
'vertical-mix': '左侧菜单混合模式',
|
||||
'horizontal-mix': '顶部菜单混合模式'
|
||||
};
|
||||
|
||||
export const themeLayoutModeOptions: Common.OptionWithKey<UnionKey.ThemeLayoutMode>[] = [
|
||||
{
|
||||
value: 'vertical',
|
||||
label: themeLayoutModeLabels.vertical
|
||||
},
|
||||
{
|
||||
value: 'horizontal',
|
||||
label: themeLayoutModeLabels.horizontal
|
||||
},
|
||||
{
|
||||
value: 'vertical-mix',
|
||||
label: themeLayoutModeLabels['vertical-mix']
|
||||
},
|
||||
{
|
||||
value: 'horizontal-mix',
|
||||
label: themeLayoutModeLabels['horizontal-mix']
|
||||
}
|
||||
];
|
||||
|
||||
export const themeTabModeLabels: Record<UnionKey.ThemeTabMode, string> = {
|
||||
chrome: '谷歌风格',
|
||||
button: '按钮风格'
|
||||
};
|
||||
|
||||
export const themeTabModeOptions: Common.OptionWithKey<UnionKey.ThemeTabMode>[] = [
|
||||
{
|
||||
value: 'chrome',
|
||||
label: themeTabModeLabels.chrome
|
||||
},
|
||||
{
|
||||
value: 'button',
|
||||
label: themeTabModeLabels.button
|
||||
}
|
||||
];
|
||||
|
||||
export const themeHorizontalMenuPositionLabels: Record<UnionKey.ThemeHorizontalMenuPosition, string> = {
|
||||
'flex-start': '居左',
|
||||
center: '居中',
|
||||
'flex-end': '居右'
|
||||
};
|
||||
|
||||
export const themeHorizontalMenuPositionOptions: Common.OptionWithKey<UnionKey.ThemeHorizontalMenuPosition>[] = [
|
||||
{
|
||||
value: 'flex-start',
|
||||
label: themeHorizontalMenuPositionLabels['flex-start']
|
||||
},
|
||||
{
|
||||
value: 'center',
|
||||
label: themeHorizontalMenuPositionLabels.center
|
||||
},
|
||||
{
|
||||
value: 'flex-end',
|
||||
label: themeHorizontalMenuPositionLabels['flex-end']
|
||||
}
|
||||
];
|
||||
|
||||
export const themeAnimateModeLabels: Record<UnionKey.ThemeAnimateMode, string> = {
|
||||
'zoom-fade': '渐变',
|
||||
'zoom-out': '闪现',
|
||||
'fade-slide': '滑动',
|
||||
fade: '消退',
|
||||
'fade-bottom': '底部消退',
|
||||
'fade-scale': '缩放消退'
|
||||
};
|
||||
|
||||
export const themeAnimateModeOptions: Common.OptionWithKey<UnionKey.ThemeAnimateMode>[] = [
|
||||
{
|
||||
value: 'zoom-fade',
|
||||
label: themeAnimateModeLabels['zoom-fade']
|
||||
},
|
||||
{
|
||||
value: 'zoom-out',
|
||||
label: themeAnimateModeLabels['zoom-out']
|
||||
},
|
||||
{
|
||||
value: 'fade-slide',
|
||||
label: themeAnimateModeLabels['fade-slide']
|
||||
},
|
||||
{
|
||||
value: 'fade',
|
||||
label: themeAnimateModeLabels.fade
|
||||
},
|
||||
{
|
||||
value: 'fade-bottom',
|
||||
label: themeAnimateModeLabels['fade-bottom']
|
||||
},
|
||||
{
|
||||
value: 'fade-scale',
|
||||
label: themeAnimateModeLabels['fade-scale']
|
||||
}
|
||||
];
|
@ -1,15 +0,0 @@
|
||||
/** 用户角色 */
|
||||
export enum EnumUserRole {
|
||||
super = '超级管理员',
|
||||
admin = '管理员',
|
||||
user = '普通用户'
|
||||
}
|
||||
|
||||
/** 登录模块 */
|
||||
export enum EnumLoginModule {
|
||||
'pwd-login' = '账密登录',
|
||||
'code-login' = '手机验证码登录',
|
||||
'register' = '注册',
|
||||
'reset-pwd' = '重置密码',
|
||||
'bind-wechat' = '微信绑定'
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
/** http请求头的content-type类型 */
|
||||
export enum EnumContentType {
|
||||
json = 'application/json',
|
||||
formUrlencoded = 'application/x-www-form-urlencoded',
|
||||
formData = 'multipart/form-data'
|
||||
}
|
||||
|
||||
/** 数据类型 */
|
||||
export enum EnumDataType {
|
||||
number = '[object Number]',
|
||||
string = '[object String]',
|
||||
boolean = '[object Boolean]',
|
||||
null = '[object Null]',
|
||||
undefined = '[object Undefined]',
|
||||
object = '[object Object]',
|
||||
array = '[object Array]',
|
||||
function = '[object Function]',
|
||||
date = '[object Date]',
|
||||
regexp = '[object RegExp]',
|
||||
promise = '[object Promise]',
|
||||
set = '[object Set]',
|
||||
map = '[object Map]',
|
||||
file = '[object File]'
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
export * from './common';
|
||||
export * from './system';
|
||||
export * from './business';
|
@ -1,36 +0,0 @@
|
||||
/** 布局组件的名称 */
|
||||
export enum EnumLayoutComponentName {
|
||||
basic = 'basic-layout',
|
||||
blank = 'blank-layout'
|
||||
}
|
||||
|
||||
/** 布局模式 */
|
||||
export enum EnumThemeLayoutMode {
|
||||
'vertical' = '左侧菜单模式',
|
||||
'horizontal' = '顶部菜单模式',
|
||||
'vertical-mix' = '左侧菜单混合模式',
|
||||
'horizontal-mix' = '顶部菜单混合模式'
|
||||
}
|
||||
|
||||
/** 多页签风格 */
|
||||
export enum EnumThemeTabMode {
|
||||
'chrome' = '谷歌风格',
|
||||
'button' = '按钮风格'
|
||||
}
|
||||
|
||||
/** 水平模式的菜单位置 */
|
||||
export enum EnumThemeHorizontalMenuPosition {
|
||||
'flex-start' = '居左',
|
||||
'center' = '居中',
|
||||
'flex-end' = '居右'
|
||||
}
|
||||
|
||||
/** 过渡动画类型 */
|
||||
export enum EnumThemeAnimateMode {
|
||||
'zoom-fade' = '渐变',
|
||||
'zoom-out' = '闪现',
|
||||
'fade-slide' = '滑动',
|
||||
'fade' = '消退',
|
||||
'fade-bottom' = '底部消退',
|
||||
'fade-scale' = '缩放消退'
|
||||
}
|
@ -18,15 +18,14 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
import type { PopoverPlacement } from 'naive-ui';
|
||||
import type { EnumThemeLayoutMode } from '@/enum';
|
||||
|
||||
defineOptions({ name: 'LayoutCheckbox' });
|
||||
|
||||
interface Props {
|
||||
/** 布局模式 */
|
||||
mode: EnumType.ThemeLayoutMode;
|
||||
mode: UnionKey.ThemeLayoutMode;
|
||||
/** 布局模式文本 */
|
||||
label: EnumThemeLayoutMode;
|
||||
label: string;
|
||||
/** 选中状态 */
|
||||
checked: boolean;
|
||||
}
|
||||
@ -34,7 +33,7 @@ interface Props {
|
||||
const props = defineProps<Props>();
|
||||
|
||||
type LayoutConfig = Record<
|
||||
EnumType.ThemeLayoutMode,
|
||||
UnionKey.ThemeLayoutMode,
|
||||
{
|
||||
placement: PopoverPlacement;
|
||||
menuClass: string;
|
||||
|
@ -18,7 +18,7 @@ export const constantRoutes: AuthRoute.Route[] = [
|
||||
path: '/login',
|
||||
component: 'self',
|
||||
props: route => {
|
||||
const moduleType = (route.params.module as EnumType.LoginModuleKey) || 'pwd-login';
|
||||
const moduleType = (route.params.module as UnionKey.LoginModule) || 'pwd-login';
|
||||
return {
|
||||
module: moduleType
|
||||
};
|
||||
|
@ -46,7 +46,7 @@ export default class CustomAxiosInstance {
|
||||
const handleConfig = { ...config };
|
||||
if (handleConfig.headers) {
|
||||
// 数据转换
|
||||
const contentType = handleConfig.headers['Content-Type'] as string;
|
||||
const contentType = handleConfig.headers['Content-Type'] as UnionKey.ContentType;
|
||||
handleConfig.data = await transformRequestData(handleConfig.data, contentType);
|
||||
// 设置token
|
||||
handleConfig.headers.Authorization = localStg.get('token') || '';
|
||||
|
@ -1,4 +1,9 @@
|
||||
import { EnumThemeAnimateMode, EnumThemeHorizontalMenuPosition, EnumThemeLayoutMode, EnumThemeTabMode } from '@/enum';
|
||||
import {
|
||||
themeLayoutModeOptions,
|
||||
themeTabModeOptions,
|
||||
themeHorizontalMenuPositionOptions,
|
||||
themeAnimateModeOptions
|
||||
} from '@/constants';
|
||||
import jsonSetting from './theme.json';
|
||||
|
||||
const themeColorList = [
|
||||
@ -34,12 +39,7 @@ const defaultThemeSetting: Theme.Setting = {
|
||||
layout: {
|
||||
minWidth: 900,
|
||||
mode: 'vertical',
|
||||
modeList: [
|
||||
{ value: 'vertical', label: EnumThemeLayoutMode.vertical },
|
||||
{ value: 'vertical-mix', label: EnumThemeLayoutMode['vertical-mix'] },
|
||||
{ value: 'horizontal', label: EnumThemeLayoutMode.horizontal },
|
||||
{ value: 'horizontal-mix', label: EnumThemeLayoutMode['horizontal-mix'] }
|
||||
]
|
||||
modeList: themeLayoutModeOptions
|
||||
},
|
||||
themeColor: themeColorList[0],
|
||||
themeColorList,
|
||||
@ -64,10 +64,7 @@ const defaultThemeSetting: Theme.Setting = {
|
||||
visible: true,
|
||||
height: 44,
|
||||
mode: 'chrome',
|
||||
modeList: [
|
||||
{ value: 'chrome', label: EnumThemeTabMode.chrome },
|
||||
{ value: 'button', label: EnumThemeTabMode.button }
|
||||
],
|
||||
modeList: themeTabModeOptions,
|
||||
isCache: true
|
||||
},
|
||||
sider: {
|
||||
@ -80,11 +77,7 @@ const defaultThemeSetting: Theme.Setting = {
|
||||
},
|
||||
menu: {
|
||||
horizontalPosition: 'flex-start',
|
||||
horizontalPositionList: [
|
||||
{ value: 'flex-start', label: EnumThemeHorizontalMenuPosition['flex-start'] },
|
||||
{ value: 'center', label: EnumThemeHorizontalMenuPosition.center },
|
||||
{ value: 'flex-end', label: EnumThemeHorizontalMenuPosition['flex-end'] }
|
||||
]
|
||||
horizontalPositionList: themeHorizontalMenuPositionOptions
|
||||
},
|
||||
footer: {
|
||||
fixed: false,
|
||||
@ -94,14 +87,7 @@ const defaultThemeSetting: Theme.Setting = {
|
||||
page: {
|
||||
animate: true,
|
||||
animateMode: 'fade-slide',
|
||||
animateModeList: [
|
||||
{ value: 'fade-slide', label: EnumThemeAnimateMode['fade-slide'] },
|
||||
{ value: 'fade', label: EnumThemeAnimateMode.fade },
|
||||
{ value: 'fade-bottom', label: EnumThemeAnimateMode['fade-bottom'] },
|
||||
{ value: 'fade-scale', label: EnumThemeAnimateMode['fade-scale'] },
|
||||
{ value: 'zoom-fade', label: EnumThemeAnimateMode['zoom-fade'] },
|
||||
{ value: 'zoom-out', label: EnumThemeAnimateMode['zoom-out'] }
|
||||
]
|
||||
animateModeList: themeAnimateModeOptions
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -58,7 +58,7 @@ export const useThemeStore = defineStore('theme-store', {
|
||||
this.layout.minWidth = minWidth;
|
||||
},
|
||||
/** 设置布局模式 */
|
||||
setLayoutMode(mode: EnumType.ThemeLayoutMode) {
|
||||
setLayoutMode(mode: UnionKey.ThemeLayoutMode) {
|
||||
this.layout.mode = mode;
|
||||
},
|
||||
/** 设置侧边栏反转色 */
|
||||
@ -106,7 +106,7 @@ export const useThemeStore = defineStore('theme-store', {
|
||||
}
|
||||
},
|
||||
/** 设置多页签风格 */
|
||||
setTabMode(mode: EnumType.ThemeTabMode) {
|
||||
setTabMode(mode: UnionKey.ThemeTabMode) {
|
||||
this.tab.mode = mode;
|
||||
},
|
||||
/** 设置多页签缓存 */
|
||||
@ -138,7 +138,7 @@ export const useThemeStore = defineStore('theme-store', {
|
||||
this.sider.mixChildMenuWidth = width;
|
||||
},
|
||||
/** 设置水平模式的菜单的位置 */
|
||||
setHorizontalMenuPosition(position: EnumType.ThemeHorizontalMenuPosition) {
|
||||
setHorizontalMenuPosition(position: UnionKey.ThemeHorizontalMenuPosition) {
|
||||
this.menu.horizontalPosition = position;
|
||||
},
|
||||
/** 设置底部是否固定 */
|
||||
@ -158,7 +158,7 @@ export const useThemeStore = defineStore('theme-store', {
|
||||
this.page.animate = animate;
|
||||
},
|
||||
/** 设置页面过渡动画类型 */
|
||||
setPageAnimateMode(mode: EnumType.ThemeAnimateMode) {
|
||||
setPageAnimateMode(mode: UnionKey.ThemeAnimateMode) {
|
||||
this.page.animateMode = mode;
|
||||
}
|
||||
}
|
||||
|
3
src/typings/business.d.ts
vendored
3
src/typings/business.d.ts
vendored
@ -5,9 +5,8 @@ declare namespace Auth {
|
||||
* - super: 超级管理员(该权限具有所有路由数据)
|
||||
* - admin: 管理员
|
||||
* - user: 用户
|
||||
* - custom: 自定义角色
|
||||
*/
|
||||
type RoleType = keyof typeof import('@/enum').EnumUserRole;
|
||||
type RoleType = 'super' | 'admin' | 'user';
|
||||
|
||||
/** 用户信息 */
|
||||
interface UserInfo {
|
||||
|
3
src/typings/global.d.ts
vendored
3
src/typings/global.d.ts
vendored
@ -12,6 +12,9 @@ declare namespace Common {
|
||||
* [状态, 为true时执行的回调函数]
|
||||
*/
|
||||
type StrategyAction = [boolean, () => void];
|
||||
|
||||
/** 选项数据 */
|
||||
type OptionWithKey<K> = { value: K; label: string };
|
||||
}
|
||||
|
||||
/** 构建时间 */
|
||||
|
57
src/typings/system.d.ts
vendored
57
src/typings/system.d.ts
vendored
@ -1,24 +1,3 @@
|
||||
/** 枚举的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 {
|
||||
/**
|
||||
@ -143,13 +122,9 @@ declare namespace Theme {
|
||||
/** 最小宽度 */
|
||||
minWidth: number;
|
||||
/** 布局模式 */
|
||||
mode: EnumType.ThemeLayoutMode;
|
||||
mode: UnionKey.ThemeLayoutMode;
|
||||
/** 布局模式列表 */
|
||||
modeList: LayoutModeList[];
|
||||
}
|
||||
interface LayoutModeList {
|
||||
value: EnumType.ThemeLayoutMode;
|
||||
label: import('@/enum').EnumThemeLayoutMode;
|
||||
modeList: Common.OptionWithKey<UnionKey.ThemeLayoutMode>[];
|
||||
}
|
||||
|
||||
/** 其他主题颜色 */
|
||||
@ -188,19 +163,13 @@ declare namespace Theme {
|
||||
/** 多页签高度 */
|
||||
height: number;
|
||||
/** 多页签风格 */
|
||||
mode: EnumType.ThemeTabMode;
|
||||
mode: UnionKey.ThemeTabMode;
|
||||
/** 多页签风格列表 */
|
||||
modeList: ThemeTabModeList[];
|
||||
modeList: Common.OptionWithKey<UnionKey.ThemeTabMode>[];
|
||||
/** 开启多页签缓存 */
|
||||
isCache: boolean;
|
||||
}
|
||||
|
||||
/** 多页签风格列表 */
|
||||
interface ThemeTabModeList {
|
||||
value: EnumType.ThemeTabMode;
|
||||
label: import('@/enum').EnumThemeTabMode;
|
||||
}
|
||||
|
||||
/** 侧边栏样式 */
|
||||
interface Sider {
|
||||
/** 侧边栏反转色 */
|
||||
@ -220,14 +189,9 @@ declare namespace Theme {
|
||||
/** 菜单样式 */
|
||||
interface Menu {
|
||||
/** 水平模式的菜单的位置 */
|
||||
horizontalPosition: EnumType.ThemeHorizontalMenuPosition;
|
||||
horizontalPosition: UnionKey.ThemeHorizontalMenuPosition;
|
||||
/** 水平模式的菜单的位置列表 */
|
||||
horizontalPositionList: HorizontalMenuPositionList[];
|
||||
}
|
||||
/** 水平模式的菜单的位置列表 */
|
||||
interface HorizontalMenuPositionList {
|
||||
value: EnumType.ThemeHorizontalMenuPosition;
|
||||
label: import('@/enum').EnumThemeHorizontalMenuPosition;
|
||||
horizontalPositionList: Common.OptionWithKey<UnionKey.ThemeHorizontalMenuPosition>[];
|
||||
}
|
||||
|
||||
/** 底部样式 */
|
||||
@ -245,14 +209,9 @@ declare namespace Theme {
|
||||
/** 页面是否开启动画 */
|
||||
animate: boolean;
|
||||
/** 动画类型 */
|
||||
animateMode: EnumType.ThemeAnimateMode;
|
||||
animateMode: UnionKey.ThemeAnimateMode;
|
||||
/** 动画类型列表 */
|
||||
animateModeList: AnimateModeList[];
|
||||
}
|
||||
/** 动画类型列表 */
|
||||
interface AnimateModeList {
|
||||
value: EnumType.ThemeAnimateMode;
|
||||
label: import('@/enum').EnumThemeAnimateMode;
|
||||
animateModeList: Common.OptionWithKey<UnionKey.ThemeAnimateMode>[];
|
||||
}
|
||||
}
|
||||
|
||||
|
56
src/typings/union-key.d.ts
vendored
Normal file
56
src/typings/union-key.d.ts
vendored
Normal file
@ -0,0 +1,56 @@
|
||||
declare namespace UnionKey {
|
||||
/** http请求头的content-type类型 */
|
||||
type ContentType = 'application/json' | 'application/x-www-form-urlencoded' | 'multipart/form-data';
|
||||
|
||||
/**
|
||||
* 登录模块
|
||||
* - pwd-login: 账密登录
|
||||
* - code-login: 手机验证码登录
|
||||
* - register: 注册
|
||||
* - reset-pwd: 重置密码
|
||||
* - bind-wechat: 微信绑定
|
||||
*/
|
||||
type LoginModule = 'pwd-login' | 'code-login' | 'register' | 'reset-pwd' | 'bind-wechat';
|
||||
|
||||
/**
|
||||
* 布局模式
|
||||
* - vertical: 左侧菜单模式
|
||||
* - horizontal: 顶部菜单模式
|
||||
* - vertical-mix: 左侧菜单混合模式
|
||||
* - horizontal-mix: 顶部菜单混合模式
|
||||
*/
|
||||
type ThemeLayoutMode = 'vertical' | 'horizontal' | 'vertical-mix' | 'horizontal-mix';
|
||||
|
||||
/**
|
||||
* 多页签风格
|
||||
* - chrome: 谷歌风格
|
||||
* - button: 按钮风格
|
||||
*/
|
||||
type ThemeTabMode = 'chrome' | 'button';
|
||||
|
||||
/**
|
||||
* 水平模式的菜单位置
|
||||
* - flex-start: 居左
|
||||
* - center: 居中
|
||||
* - flex-end: 居右
|
||||
*/
|
||||
type ThemeHorizontalMenuPosition = 'flex-start' | 'center' | 'flex-end';
|
||||
|
||||
/**
|
||||
* 过渡动画类型
|
||||
* - zoom-fade: 渐变
|
||||
* - zoom-out: 闪现
|
||||
* - fade-slide: 滑动
|
||||
* - fade: 消退
|
||||
* - fade-bottom: 底部消退
|
||||
* - fade-scale: 缩放消退
|
||||
*/
|
||||
type ThemeAnimateMode = 'zoom-fade' | 'zoom-out' | 'fade-slide' | 'fade' | 'fade-bottom' | 'fade-scale';
|
||||
|
||||
/**
|
||||
* 布局组件的名称
|
||||
* - basic 基础布局
|
||||
* - blank 空白布局
|
||||
*/
|
||||
type LayoutComponentName = 'basic' | 'blank';
|
||||
}
|
25
src/typings/utils.d.ts
vendored
25
src/typings/utils.d.ts
vendored
@ -1,9 +1,30 @@
|
||||
declare namespace TypeUtil {
|
||||
type Noop = (...args: any) => any;
|
||||
|
||||
type UnionInclude<T, K extends keyof T> = K extends keyof T ? true : false;
|
||||
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 GetFunArgs<F extends Noop> = F extends (...args: infer P) => any ? P : never;
|
||||
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] };
|
||||
|
||||
|
@ -1,57 +1,69 @@
|
||||
import { EnumDataType } from '@/enum';
|
||||
import { dataTypeLabels } from '@/constants';
|
||||
|
||||
export function isNumber<T extends number>(data: T | unknown): data is T {
|
||||
return Object.prototype.toString.call(data) === EnumDataType.number;
|
||||
function getDataTypeString<K extends TypeUtil.DataTypeStringKey>(value: unknown) {
|
||||
return Object.prototype.toString.call(value) as TypeUtil.DataTypeString<K>;
|
||||
}
|
||||
|
||||
export function isString<T extends string>(data: T | unknown): data is T {
|
||||
return Object.prototype.toString.call(data) === EnumDataType.string;
|
||||
export function isNumber<T extends number>(value: T | unknown): value is T {
|
||||
return getDataTypeString(value) === dataTypeLabels.number;
|
||||
}
|
||||
|
||||
export function isBoolean<T extends boolean>(data: T | unknown): data is T {
|
||||
return Object.prototype.toString.call(data) === EnumDataType.boolean;
|
||||
export function isString<T extends string>(value: T | unknown): value is T {
|
||||
return getDataTypeString(value) === dataTypeLabels.string;
|
||||
}
|
||||
|
||||
export function isNull<T extends null>(data: T | unknown): data is T {
|
||||
return Object.prototype.toString.call(data) === EnumDataType.null;
|
||||
export function isBoolean<T extends boolean>(value: T | unknown): value is T {
|
||||
return getDataTypeString(value) === dataTypeLabels.boolean;
|
||||
}
|
||||
|
||||
export function isUndefined<T extends undefined>(data: T | unknown): data is T {
|
||||
return Object.prototype.toString.call(data) === EnumDataType.undefined;
|
||||
export function isNull<T extends null>(value: T | unknown): value is T {
|
||||
return getDataTypeString(value) === dataTypeLabels.null;
|
||||
}
|
||||
|
||||
export function isObject<T extends Record<string, any>>(data: T | unknown): data is T {
|
||||
return Object.prototype.toString.call(data) === EnumDataType.object;
|
||||
export function isUndefined<T extends undefined>(value: T | unknown): value is T {
|
||||
return getDataTypeString(value) === dataTypeLabels.undefined;
|
||||
}
|
||||
|
||||
export function isArray<T extends any[]>(data: T | unknown): data is T {
|
||||
return Object.prototype.toString.call(data) === EnumDataType.array;
|
||||
export function isSymbol<T extends symbol>(value: T | unknown): value is T {
|
||||
return getDataTypeString(value) === dataTypeLabels.symbol;
|
||||
}
|
||||
|
||||
export function isFunction<T extends (...args: any[]) => any | void | never>(data: T | unknown): data is T {
|
||||
return Object.prototype.toString.call(data) === EnumDataType.function;
|
||||
export function isBigInt<T extends bigint>(value: T | unknown): value is T {
|
||||
return getDataTypeString(value) === dataTypeLabels.bigInt;
|
||||
}
|
||||
|
||||
export function isDate<T extends Date>(data: T | unknown): data is T {
|
||||
return Object.prototype.toString.call(data) === EnumDataType.date;
|
||||
export function isObject<T extends Record<string, any>>(value: T | unknown): value is T {
|
||||
return getDataTypeString(value) === dataTypeLabels.object;
|
||||
}
|
||||
|
||||
export function isRegExp<T extends RegExp>(data: T | unknown): data is T {
|
||||
return Object.prototype.toString.call(data) === EnumDataType.regexp;
|
||||
export function isArray<T extends any[]>(value: T | unknown): value is T {
|
||||
return getDataTypeString(value) === dataTypeLabels.array;
|
||||
}
|
||||
|
||||
export function isPromise<T extends Promise<any>>(data: T | unknown): data is T {
|
||||
return Object.prototype.toString.call(data) === EnumDataType.promise;
|
||||
export function isFunction<T extends (...args: any[]) => any | void>(value: T | unknown): value is T {
|
||||
return getDataTypeString(value) === dataTypeLabels.function;
|
||||
}
|
||||
|
||||
export function isSet<T extends Set<any>>(data: T | unknown): data is T {
|
||||
return Object.prototype.toString.call(data) === EnumDataType.set;
|
||||
export function isDate<T extends Date>(value: T | unknown): value is T {
|
||||
return getDataTypeString(value) === dataTypeLabels.date;
|
||||
}
|
||||
|
||||
export function isMap<T extends Map<any, any>>(data: T | unknown): data is T {
|
||||
return Object.prototype.toString.call(data) === EnumDataType.map;
|
||||
export function isRegExp<T extends RegExp>(value: T | unknown): value is T {
|
||||
return getDataTypeString(value) === dataTypeLabels.regExp;
|
||||
}
|
||||
|
||||
export function isFile<T extends File>(data: T | unknown): data is T {
|
||||
return Object.prototype.toString.call(data) === EnumDataType.file;
|
||||
export function isPromise<T extends Promise<any>>(value: T | unknown): value is T {
|
||||
return getDataTypeString(value) === dataTypeLabels.promise;
|
||||
}
|
||||
|
||||
export function isSet<T extends Set<any>>(value: T | unknown): value is T {
|
||||
return getDataTypeString(value) === dataTypeLabels.set;
|
||||
}
|
||||
|
||||
export function isMap<T extends Map<any, any>>(value: T | unknown): value is T {
|
||||
return getDataTypeString(value) === dataTypeLabels.map;
|
||||
}
|
||||
|
||||
export function isFile<T extends File>(value: T | unknown): value is T {
|
||||
return getDataTypeString(value) === dataTypeLabels.file;
|
||||
}
|
||||
|
@ -9,13 +9,13 @@ interface ModuleComponent {
|
||||
default: RouteComponent;
|
||||
}
|
||||
|
||||
type LayoutComponent = Record<EnumType.LayoutComponentName, Lazy<ModuleComponent>>;
|
||||
type LayoutComponent = Record<UnionKey.LayoutComponentName, Lazy<ModuleComponent>>;
|
||||
|
||||
/**
|
||||
* 获取布局的vue文件(懒加载的方式)
|
||||
* @param layoutType - 布局类型
|
||||
*/
|
||||
export function getLayoutComponent(layoutType: EnumType.LayoutComponentName) {
|
||||
export function getLayoutComponent(layoutType: UnionKey.LayoutComponentName) {
|
||||
const layoutComponent: LayoutComponent = {
|
||||
basic: BasicLayout,
|
||||
blank: BlankLayout
|
||||
|
@ -1,5 +1,5 @@
|
||||
/** 获取登录页面模块的动态路由的正则 */
|
||||
export function getLoginModuleRegExp() {
|
||||
const modules: EnumType.LoginModuleKey[] = ['pwd-login', 'code-login', 'register', 'reset-pwd', 'bind-wechat'];
|
||||
const modules: UnionKey.LoginModule[] = ['pwd-login', 'code-login', 'register', 'reset-pwd', 'bind-wechat'];
|
||||
return modules.join('|');
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ export async function handleServiceResult<T = any>(error: Service.RequestError |
|
||||
/** 请求结果的适配器:用于接收适配器函数和请求结果 */
|
||||
export function adapter<T extends Service.ServiceAdapter>(
|
||||
adapterFun: T,
|
||||
...args: Service.MultiRequestResult<TypeUtil.GetFunArgs<T>>
|
||||
...args: Service.MultiRequestResult<Parameters<T>>
|
||||
): Service.RequestResult<ReturnType<T>> {
|
||||
let result: Service.RequestResult | undefined;
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
import qs from 'qs';
|
||||
import FormData from 'form-data';
|
||||
import { EnumContentType } from '@/enum';
|
||||
import { isArray, isFile } from '../common';
|
||||
|
||||
/**
|
||||
@ -8,15 +7,15 @@ import { isArray, isFile } from '../common';
|
||||
* @param requestData - 请求数据
|
||||
* @param contentType - 请求头的Content-Type
|
||||
*/
|
||||
export async function transformRequestData(requestData: any, contentType?: string) {
|
||||
export async function transformRequestData(requestData: any, contentType?: UnionKey.ContentType) {
|
||||
// application/json类型不处理
|
||||
let data = requestData;
|
||||
// form类型转换
|
||||
if (contentType === EnumContentType.formUrlencoded) {
|
||||
if (contentType === 'application/x-www-form-urlencoded') {
|
||||
data = qs.stringify(requestData);
|
||||
}
|
||||
// form-data类型转换
|
||||
if (contentType === EnumContentType.formData) {
|
||||
if (contentType === 'multipart/form-data') {
|
||||
data = await handleFormData(requestData);
|
||||
}
|
||||
|
||||
|
@ -23,11 +23,11 @@
|
||||
</n-button>
|
||||
<div class="flex-y-center justify-between">
|
||||
<n-button class="flex-1" :block="true" @click="toLoginModule('code-login')">
|
||||
{{ EnumLoginModule['code-login'] }}
|
||||
{{ loginModuleLabels['code-login'] }}
|
||||
</n-button>
|
||||
<div class="w-12px"></div>
|
||||
<n-button class="flex-1" :block="true" @click="toLoginModule('register')">
|
||||
{{ EnumLoginModule.register }}
|
||||
{{ loginModuleLabels.register }}
|
||||
</n-button>
|
||||
</div>
|
||||
</n-space>
|
||||
@ -38,7 +38,7 @@
|
||||
<script setup lang="ts">
|
||||
import { reactive, ref } from 'vue';
|
||||
import type { FormInst, FormRules } from 'naive-ui';
|
||||
import { EnumLoginModule } from '@/enum';
|
||||
import { loginModuleLabels } from '@/constants';
|
||||
import { useAuthStore } from '@/store';
|
||||
import { useRouterPush } from '@/composables';
|
||||
import { formRules } from '@/utils';
|
||||
|
@ -28,7 +28,7 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
import type { Component } from 'vue';
|
||||
import { EnumLoginModule } from '@/enum';
|
||||
import { loginModuleLabels } from '@/constants';
|
||||
import { useThemeStore } from '@/store';
|
||||
import { useAppInfo } from '@/composables';
|
||||
import { getColorPalette, mixColor } from '@/utils';
|
||||
@ -36,7 +36,7 @@ import { BindWechat, CodeLogin, LoginBg, PwdLogin, Register, ResetPwd } from './
|
||||
|
||||
interface Props {
|
||||
/** 登录模块分类 */
|
||||
module: EnumType.LoginModuleKey;
|
||||
module: UnionKey.LoginModule;
|
||||
}
|
||||
|
||||
const props = defineProps<Props>();
|
||||
@ -45,17 +45,17 @@ const theme = useThemeStore();
|
||||
const { title } = useAppInfo();
|
||||
|
||||
interface LoginModule {
|
||||
key: EnumType.LoginModuleKey;
|
||||
label: EnumLoginModule;
|
||||
key: UnionKey.LoginModule;
|
||||
label: string;
|
||||
component: Component;
|
||||
}
|
||||
|
||||
const modules: LoginModule[] = [
|
||||
{ key: 'pwd-login', label: EnumLoginModule['pwd-login'], component: PwdLogin },
|
||||
{ key: 'code-login', label: EnumLoginModule['code-login'], component: CodeLogin },
|
||||
{ key: 'register', label: EnumLoginModule.register, component: Register },
|
||||
{ key: 'reset-pwd', label: EnumLoginModule['reset-pwd'], component: ResetPwd },
|
||||
{ key: 'bind-wechat', label: EnumLoginModule['bind-wechat'], component: BindWechat }
|
||||
{ key: 'pwd-login', label: loginModuleLabels['pwd-login'], component: PwdLogin },
|
||||
{ key: 'code-login', label: loginModuleLabels['code-login'], component: CodeLogin },
|
||||
{ key: 'register', label: loginModuleLabels.register, component: Register },
|
||||
{ key: 'reset-pwd', label: loginModuleLabels['reset-pwd'], component: ResetPwd },
|
||||
{ key: 'bind-wechat', label: loginModuleLabels['bind-wechat'], component: BindWechat }
|
||||
];
|
||||
|
||||
const activeModule = computed(() => {
|
||||
|
@ -34,7 +34,7 @@
|
||||
<script setup lang="ts">
|
||||
import { watch } from 'vue';
|
||||
import type { SelectOption } from 'naive-ui';
|
||||
import { EnumUserRole } from '@/enum';
|
||||
import { userRoleOptions } from '@/constants';
|
||||
import { useAppStore, useAuthStore } from '@/store';
|
||||
import { usePermission } from '@/composables';
|
||||
|
||||
@ -42,18 +42,7 @@ const app = useAppStore();
|
||||
const auth = useAuthStore();
|
||||
const { hasPermission } = usePermission();
|
||||
|
||||
interface RoleList {
|
||||
label: string;
|
||||
value: keyof typeof EnumUserRole;
|
||||
}
|
||||
|
||||
const roleList: RoleList[] = [
|
||||
{ label: EnumUserRole.super, value: 'super' },
|
||||
{ label: EnumUserRole.admin, value: 'admin' },
|
||||
{ label: EnumUserRole.user, value: 'user' }
|
||||
];
|
||||
|
||||
const options: SelectOption[] = roleList as unknown as SelectOption[];
|
||||
const options: SelectOption[] = userRoleOptions;
|
||||
|
||||
watch(
|
||||
() => auth.userInfo.userRole,
|
||||
|
@ -34,8 +34,8 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, reactive, watch } from 'vue';
|
||||
import type { FormInst, FormItemRule } from 'naive-ui';
|
||||
import { formRules, createRequiredFormRule } from '@/utils';
|
||||
import { genderOptions, userStatusOptions } from '@/constants';
|
||||
import { formRules, createRequiredFormRule } from '@/utils';
|
||||
|
||||
export interface Props {
|
||||
/** 弹窗可见性 */
|
||||
|
@ -33,9 +33,9 @@ import { reactive, ref } from 'vue';
|
||||
import type { Ref } from 'vue';
|
||||
import { NButton, NPopconfirm, NSpace, NTag } from 'naive-ui';
|
||||
import type { DataTableColumns, PaginationProps } from 'naive-ui';
|
||||
import { genderLabels, userStatusLabels } from '@/constants';
|
||||
import { fetchUserList } from '@/service';
|
||||
import { useBoolean, useLoading } from '@/hooks';
|
||||
import { genderLabels, userStatusLabels } from '@/constants';
|
||||
import TableActionModal from './components/table-action-modal.vue';
|
||||
import type { ModalType } from './components/table-action-modal.vue';
|
||||
import ColumnSetting from './components/column-setting.vue';
|
||||
|
Loading…
Reference in New Issue
Block a user