Skip to content

Commit

Permalink
refactor(projects): 细节完善
Browse files Browse the repository at this point in the history
  • Loading branch information
honghuangdc committed Jan 23, 2022
1 parent b61b0ce commit 651e58d
Show file tree
Hide file tree
Showing 14 changed files with 1,022 additions and 160 deletions.
2 changes: 1 addition & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ module.exports = {
'@typescript-eslint/no-explicit-any': 0,
'@typescript-eslint/no-inferrable-types': 0,
'@typescript-eslint/no-non-null-assertion': 'off',
'@typescript-eslint/no-unused-vars': ['warn', { ignoreRestSiblings: true }],
'@typescript-eslint/no-unused-vars': ['warn', { ignoreRestSiblings: true, varsIgnorePattern: 'Ignored' }],
'@typescript-eslint/no-use-before-define': ['error', { classes: true, functions: false, typedefs: false }],
'@typescript-eslint/no-var-requires': 'off'
}
Expand Down
57 changes: 48 additions & 9 deletions mock/api/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,16 +90,42 @@ const routes: AuthRoute.Route[] = [
}
},
{
name: 'about',
path: '/about',
component: 'self',
name: 'component',
path: '/component',
component: 'basic',
children: [
{
name: 'component_button',
path: '/component/button',
component: 'self',
meta: {
title: '按钮',
requiresAuth: true
}
},
{
name: 'component_card',
path: '/component/card',
component: 'self',
meta: {
title: '卡片',
requiresAuth: true
}
},
{
name: 'component_table',
path: '/component/table',
component: 'self',
meta: {
title: '表格',
requiresAuth: true
}
}
],
meta: {
title: '关于',
requiresAuth: true,
singleLayout: 'basic',
permissions: ['super', 'admin', 'test'],
icon: 'fluent:book-information-24-regular',
order: 7
title: '组件示例',
icon: 'fluent:app-store-24-regular',
order: 4
}
},
{
Expand Down Expand Up @@ -190,6 +216,19 @@ const routes: AuthRoute.Route[] = [
icon: 'carbon:menu',
order: 6
}
},
{
name: 'about',
path: '/about',
component: 'self',
meta: {
title: '关于',
requiresAuth: true,
singleLayout: 'basic',
permissions: ['super', 'admin', 'test'],
icon: 'fluent:book-information-24-regular',
order: 7
}
}
];

Expand Down
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
"@types/qs": "^6.9.7",
"@typescript-eslint/eslint-plugin": "^5.10.0",
"@typescript-eslint/parser": "^5.10.0",
"@vitejs/plugin-vue": "^2.0.1",
"@vitejs/plugin-vue": "^2.1.0",
"@vue/eslint-config-prettier": "^7.0.0",
"@vue/eslint-config-typescript": "^10.0.0",
"commitizen": "^4.2.4",
Expand All @@ -64,7 +64,7 @@
"eslint-plugin-prettier": "^4.0.0",
"eslint-plugin-vue": "^8.3.0",
"husky": "^7.0.4",
"lint-staged": "^12.2.2",
"lint-staged": "^12.3.1",
"mockjs": "^1.1.0",
"patch-package": "^6.4.7",
"postinstall-postinstall": "^2.1.0",
Expand All @@ -78,7 +78,7 @@
"vite-plugin-html": "^2.1.2",
"vite-plugin-mock": "^2.9.6",
"vite-plugin-windicss": "^1.6.3",
"vue-tsc": "^0.30.6",
"vue-tsc": "^0.31.1",
"vueuc": "^0.4.23",
"windicss": "^3.4.3"
}
Expand Down
231 changes: 112 additions & 119 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

97 changes: 97 additions & 0 deletions src/components/business/LoadingEmptyWrapper/index.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
<template>
<div v-if="reloadFlag" class="relative">
<slot></slot>
<div v-show="showPlaceholder" class="absolute-lt w-full h-full" :class="placeholderClass">
<div v-show="loading" class="absolute-center">
<n-spin :show="true" :size="loadingSize" />
</div>
<div v-show="isEmpty" class="absolute-center">
<div class="relative" :class="emptyNetworkClass">
<svg-empty-data class="text-primary" />
<p class="absolute-lb w-full text-center">{{ emptyDesc }}</p>
</div>
</div>
<div v-show="!network" class="absolute-center">
<div
class="relative"
:class="[{ 'cursor-pointer': showNetworkReload }, emptyNetworkClass]"
@click="handleReload"
>
<svg-network-error class="text-primary" />
<p class="absolute-lb w-full text-center">{{ networkErrorDesc }}</p>
</div>
</div>
</div>
</div>
</template>

<script setup lang="ts">
import { computed, watch, nextTick, onUnmounted } from 'vue';
import { NSpin } from 'naive-ui';
import { NETWORK_ERROR_MSG } from '@/config';
import { SvgEmptyData, SvgNetworkError } from '@/components';
import { useBoolean } from '@/hooks';
interface Props {
/** 是否加载 */
loading: boolean;
/** 是否为空 */
empty?: boolean;
/** 加载图标的大小 */
loadingSize?: 'small' | 'medium' | 'large';
/** 中间占位符的class */
placeholderClass?: string;
/** 空数据描述文本 */
emptyDesc?: string;
/** 空数据和网络异常占位class */
emptyNetworkClass?: string;
/** 显示网络异常的重试点击按钮 */
showNetworkReload?: boolean;
}
const props = withDefaults(defineProps<Props>(), {
loading: false,
empty: false,
loadingSize: 'medium',
placeholderClass: 'bg-white',
emptyDesc: '暂无数据',
emptyNetworkClass: 'w-320px h-320px text-16px text-[#666]',
showNetworkReload: false
});
// 网络状态
const { bool: network, setBool: setNetwork } = useBoolean(window.navigator.onLine);
const { bool: reloadFlag, setBool: setReload } = useBoolean(true);
// 数据是否为空
const isEmpty = computed(() => props.empty && !props.loading && network.value);
const showPlaceholder = computed(() => props.loading || isEmpty.value || !network.value);
const networkErrorDesc = computed(() =>
props.showNetworkReload ? `${NETWORK_ERROR_MSG}, 点击重试` : NETWORK_ERROR_MSG
);
function handleReload() {
if (!props.showNetworkReload) return;
setReload(false);
nextTick(() => {
setReload(true);
});
}
const stopHandle = watch(
() => props.loading,
newValue => {
// 结束加载判断一下网络状态
if (!newValue) {
setNetwork(window.navigator.onLine);
}
}
);
onUnmounted(() => {
stopHandle();
});
</script>
<style scoped></style>
3 changes: 2 additions & 1 deletion src/components/business/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import LoadingEmptyWrapper from './LoadingEmptyWrapper/index.vue';
import LoginAgreement from './LoginAgreement/index.vue';

export { LoginAgreement };
export { LoadingEmptyWrapper, LoginAgreement };
37 changes: 19 additions & 18 deletions src/typings/common/route.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,19 @@ declare namespace AuthRoute {
| 'document_vite'
| 'document_naive'
| 'document_project'
| 'component'
| 'component_button'
| 'component_card'
| 'component_table'
| 'exception'
| 'exception_403'
| 'exception_404'
| 'exception_500'
| 'multi-menu'
| 'multi-menu_first'
| 'multi-menu_first_second'
| 'multi-menu_first_second-new'
| 'multi-menu_first_second-new_third'
| 'exception'
| 'exception_403'
| 'exception_404'
| 'exception_500'
| 'about';

/** 路由的path */
Expand All @@ -55,20 +59,20 @@ declare namespace AuthRoute {
title: string;
/** 路由的动态路径 */
dynamicPath?: PathToDynamicPath<'/login'>;
/** 作为单独路由的父级路由布局组件 */
/** 作为单级路由的父级路由布局组件 */
singleLayout?: Extract<RouteComponent, 'basic' | 'blank'>;
/** 需要登录权限 */
requiresAuth?: boolean;
/** 哪些类型的用户有权限才能访问的路由 */
/** 哪些类型的用户有权限才能访问的路由(空的话则表示不需要权限) */
permissions?: Auth.RoleType[];
/** 缓存页面 */
keepAlive?: boolean;
/** 菜单和面包屑对应的图标 */
icon?: string;
/** 外链链接 */
href?: string;
/** 是否在菜单中隐藏 */
hide?: boolean;
/** 外链链接 */
href?: string;
/** 路由顺序,可用于菜单的排序 */
order?: number;
/** 表示是否是多级路由的中间级路由(用于转换路由数据时筛选多级路由的标识,定义路由时不用填写) */
Expand Down Expand Up @@ -102,14 +106,11 @@ declare namespace AuthRoute {
/** 单独一级路由的key (单独路由需要添加一个父级路由用于应用布局组件) */
type SingleRouteKey = Exclude<
GetSingleRouteKey<RouteKey>,
GetMultiRouteParentKey<RouteKey> | 'root' | 'not-found-page'
GetRouteFirstParentKey<RouteKey> | 'root' | 'not-found-page'
>;
/** 单独路由父级路由key */
type SingleRouteParentKey = `${SingleRouteKey}-parent`;

/** 单独路由path */
type SingleRoutePath = KeyToPath<SingleRouteKey>;

/** 单独路由父级路由path */
type SingleRouteParentPath = KeyToPath<SingleRouteParentKey>;

Expand All @@ -124,12 +125,12 @@ declare namespace AuthRoute {
| `${Path}/:module(${string})`
| `${Path}/:module(${string})?`;

// eslint-disable-next-line @typescript-eslint/no-unused-vars
type GetSingleRouteKey<Key extends RouteKey> = Key extends `${infer Left}${RouteSplitMark}${infer Right}`
? never
: Key;
// eslint-disable-next-line @typescript-eslint/no-unused-vars
type GetMultiRouteParentKey<Key extends RouteKey> = Key extends `${infer Left}${RouteSplitMark}${infer Right}`
/** 获取一级路由(包括有子路由的一级路由) */
type GetSingleRouteKey<Key extends RouteKey> =
Key extends `${infer IgnoredLeft}${RouteSplitMark}${infer IgnoredRight}` ? never : Key;

/** 获取子路由的一级父路由 */
type GetRouteFirstParentKey<Key extends RouteKey> = Key extends `${infer Left}${RouteSplitMark}${infer IgnoredRight}`
? Left
: never;
}
11 changes: 11 additions & 0 deletions src/utils/common/number.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,14 @@ export function transformToTimeCountDown(seconds: number) {
const second = fillZero(seconds - minuteNum * SECONDS_A_MINUTE);
return `${minute}: ${second}`;
}

/**
* 获取指定整数范围内的随机整数
* @param start - 开始范围
* @param end - 结束范围
*/
export function getRandomInterger(end: number, start: number = 0) {
const range = end - start;
const random = Math.floor(Math.random() * range + start);
return random;
}
28 changes: 19 additions & 9 deletions src/utils/router/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,12 @@ import {
DocumentVueNew,
DocumentVite,
DocumentNaive,
About,
ComponentButton,
ComponentCard,
ComponentTable,
MultiMenuFirstSecond,
MultiMenuFirstSecondNewThird
MultiMenuFirstSecondNewThird,
About
} from '@/views';
import type { LayoutComponentName } from '@/interface';

Expand All @@ -39,6 +42,7 @@ type ViewComponentKey = Exclude<
| 'dashboard'
| 'document'
| 'document_project'
| 'component'
| 'multi-menu'
| 'multi-menu_first'
| 'multi-menu_first_second-new'
Expand All @@ -63,12 +67,15 @@ export function getViewComponent(routeKey: AuthRoute.RouteKey) {
'document_vue-new',
'document_vite',
'document_naive',
'about',
'multi-menu_first_second',
'multi-menu_first_second-new_third',
'component_button',
'component_card',
'component_table',
'exception_403',
'exception_404',
'exception_500',
'multi-menu_first_second',
'multi-menu_first_second-new_third',
'about',
'not-found-page'
];

Expand All @@ -85,13 +92,16 @@ export function getViewComponent(routeKey: AuthRoute.RouteKey) {
'document_vue-new': DocumentVueNew,
document_vite: DocumentVite,
document_naive: DocumentNaive,
'multi-menu_first_second': MultiMenuFirstSecond,
'multi-menu_first_second-new_third': MultiMenuFirstSecondNewThird,
'not-found-page': NotFound,
component_button: ComponentButton,
component_card: ComponentCard,
component_table: ComponentTable,
exception_403: NoPermission,
exception_404: NotFound,
exception_500: ServiceError,
about: About
'multi-menu_first_second': MultiMenuFirstSecond,
'multi-menu_first_second-new_third': MultiMenuFirstSecondNewThird,
about: About,
'not-found-page': NotFound
};

return () => setViewComponentName(viewComponent[key], key) as Promise<Component>;
Expand Down
Loading

0 comments on commit 651e58d

Please sign in to comment.