提交 4ff6b73c 作者: vben

perf: optimize settingDrawer code

上级 5832ee66
...@@ -4,6 +4,10 @@ ...@@ -4,6 +4,10 @@
- 表单项的`componentsProps`支持函数类型 - 表单项的`componentsProps`支持函数类型
### ⚡ Performance Improvements
- 优化 settingDrawer 代码
### 🐛 Bug Fixes ### 🐛 Bug Fixes
- 修复多个富文本编辑器只显示一个 - 修复多个富文本编辑器只显示一个
......
...@@ -30,8 +30,7 @@ ...@@ -30,8 +30,7 @@
.app-loading { .app-loading {
width: 100%; width: 100%;
height: 100%; height: 100%;
background: #f0f2f5;
/* background: #f0f2f5; */
} }
.app-loading .app-loading-wrap { .app-loading .app-loading-wrap {
......
...@@ -11,7 +11,7 @@ const demoList = (() => { ...@@ -11,7 +11,7 @@ const demoList = (() => {
address: '@city()', address: '@city()',
name: '@cname()', name: '@cname()',
'no|100000-10000000': 100000, 'no|100000-10000000': 100000,
'status|1': ['正常', '启用', '停用'], 'status|1': ['normal', 'enable', 'disable'],
}); });
} }
return result; return result;
......
import { defHttp } from '/@/utils/http/axios'; import { defHttp } from '/@/utils/http/axios';
enum Api { enum Api {
// 该地址不存在 // The address does not exist
Error = '/error', Error = '/error',
} }
/** /**
* @description: 触发ajax错误 * @description: Trigger ajax error
*/ */
export function fireErrorApi() { export function fireErrorApi() {
return defHttp.request({ return defHttp.request({
......
import { BasicPageParams, BasicFetchResult } from '/@/api/model/baseModel'; import { BasicPageParams, BasicFetchResult } from '/@/api/model/baseModel';
/** /**
* @description: 请求列表接口参数 * @description: Request list interface parameters
*/ */
export type DemoParams = BasicPageParams; export type DemoParams = BasicPageParams;
...@@ -15,6 +15,6 @@ export interface DemoListItem { ...@@ -15,6 +15,6 @@ export interface DemoListItem {
} }
/** /**
* @description: 请求列表返回值 * @description: Request list return value
*/ */
export type DemoListGetResultModel = BasicFetchResult<DemoListItem>; export type DemoListGetResultModel = BasicFetchResult<DemoListItem>;
...@@ -6,7 +6,7 @@ enum Api { ...@@ -6,7 +6,7 @@ enum Api {
} }
/** /**
* @description: 获取示例列表值 * @description: Get sample list value
*/ */
export function demoListApi(params: DemoParams) { export function demoListApi(params: DemoParams) {
return defHttp.request<DemoListGetResultModel>({ return defHttp.request<DemoListGetResultModel>({
......
...@@ -89,7 +89,6 @@ export type ComponentType = ...@@ -89,7 +89,6 @@ export type ComponentType =
| 'InputNumber' | 'InputNumber'
| 'InputCountDown' | 'InputCountDown'
| 'Select' | 'Select'
| 'DictSelect'
| 'SelectOptGroup' | 'SelectOptGroup'
| 'SelectOption' | 'SelectOption'
| 'TreeSelect' | 'TreeSelect'
......
...@@ -52,7 +52,8 @@ export default defineComponent({ ...@@ -52,7 +52,8 @@ export default defineComponent({
toRef(props, 'items'), toRef(props, 'items'),
toRef(props, 'flatItems'), toRef(props, 'flatItems'),
toRef(props, 'isAppMenu'), toRef(props, 'isAppMenu'),
toRef(props, 'mode') toRef(props, 'mode'),
toRef(props, 'accordion')
); );
const getOpenKeys = computed(() => { const getOpenKeys = computed(() => {
......
...@@ -58,6 +58,10 @@ export const basicProps = { ...@@ -58,6 +58,10 @@ export const basicProps = {
type: Boolean as PropType<boolean>, type: Boolean as PropType<boolean>,
default: false, default: false,
}, },
accordion: {
type: Boolean as PropType<boolean>,
default: true,
},
beforeClickFn: { beforeClickFn: {
type: Function as PropType<Fn>, type: Function as PropType<Fn>,
default: null, default: null,
......
...@@ -6,21 +6,31 @@ import type { Ref } from 'vue'; ...@@ -6,21 +6,31 @@ import type { Ref } from 'vue';
import { unref } from 'vue'; import { unref } from 'vue';
import { menuStore } from '/@/store/modules/menu'; import { menuStore } from '/@/store/modules/menu';
import { getAllParentPath } from '/@/utils/helper/menuHelper'; import { getAllParentPath } from '/@/utils/helper/menuHelper';
import { es6Unique } from '/@/utils';
export function useOpenKeys( export function useOpenKeys(
menuState: MenuState, menuState: MenuState,
menus: Ref<MenuType[]>, menus: Ref<MenuType[]>,
flatMenusRef: Ref<MenuType[]>, flatMenusRef: Ref<MenuType[]>,
isAppMenu: Ref<boolean>, isAppMenu: Ref<boolean>,
mode: Ref<MenuModeEnum> mode: Ref<MenuModeEnum>,
accordion: Ref<boolean>
) { ) {
/** /**
* @description:设置展开 * @description:设置展开
*/ */
function setOpenKeys(menu: MenuType) { function setOpenKeys(menu: MenuType) {
const flatMenus = unref(flatMenusRef); const flatMenus = unref(flatMenusRef);
menuState.openKeys = getAllParentPath(flatMenus, menu.path); if (!unref(accordion)) {
menuState.openKeys = es6Unique([
...menuState.openKeys,
...getAllParentPath(flatMenus, menu.path),
]);
} else {
menuState.openKeys = getAllParentPath(flatMenus, menu.path);
}
} }
/** /**
* @description: 重置值 * @description: 重置值
*/ */
...@@ -30,7 +40,7 @@ export function useOpenKeys( ...@@ -30,7 +40,7 @@ export function useOpenKeys(
} }
function handleOpenChange(openKeys: string[]) { function handleOpenChange(openKeys: string[]) {
if (unref(mode) === MenuModeEnum.HORIZONTAL) { if (unref(mode) === MenuModeEnum.HORIZONTAL || !unref(accordion)) {
menuState.openKeys = openKeys; menuState.openKeys = openKeys;
} else { } else {
const rootSubMenuKeys: string[] = []; const rootSubMenuKeys: string[] = [];
......
...@@ -2,11 +2,8 @@ import { defineComponent } from 'vue'; ...@@ -2,11 +2,8 @@ import { defineComponent } from 'vue';
import { Layout } from 'ant-design-vue'; import { Layout } from 'ant-design-vue';
import { RouterView } from 'vue-router'; import { RouterView } from 'vue-router';
// hooks
import { ContentEnum } from '/@/enums/appEnum'; import { ContentEnum } from '/@/enums/appEnum';
import { appStore } from '/@/store/modules/app'; import { appStore } from '/@/store/modules/app';
// import PageLayout from '/@/layouts/page/index';
export default defineComponent({ export default defineComponent({
name: 'DefaultLayoutContent', name: 'DefaultLayoutContent',
setup() { setup() {
...@@ -17,7 +14,6 @@ export default defineComponent({ ...@@ -17,7 +14,6 @@ export default defineComponent({
return ( return (
<Layout.Content class={`layout-content ${wrapClass} `}> <Layout.Content class={`layout-content ${wrapClass} `}>
{() => <RouterView />} {() => <RouterView />}
{/* <PageLayout class={`layout-content ${wrapClass} `} /> */}
</Layout.Content> </Layout.Content>
); );
}; };
......
...@@ -55,27 +55,25 @@ export default defineComponent({ ...@@ -55,27 +55,25 @@ export default defineComponent({
}, },
}, },
setup(props) { setup(props) {
// Menu array
const menusRef = ref<Menu[]>([]); const menusRef = ref<Menu[]>([]);
// flat menu array
const flatMenusRef = ref<Menu[]>([]); const flatMenusRef = ref<Menu[]>([]);
const { currentRoute, push } = useRouter(); const { currentRoute, push } = useRouter();
// const { addTab } = useTabs();
// get app config
const getProjectConfigRef = computed(() => { const getProjectConfigRef = computed(() => {
return appStore.getProjectConfig; return appStore.getProjectConfig;
}); });
// get is Horizontal
const getIsHorizontalRef = computed(() => { const getIsHorizontalRef = computed(() => {
return unref(getProjectConfigRef).menuSetting.mode === MenuModeEnum.HORIZONTAL; return unref(getProjectConfigRef).menuSetting.mode === MenuModeEnum.HORIZONTAL;
}); });
const [throttleHandleSplitLeftMenu] = useThrottle(handleSplitLeftMenu, 50); const [throttleHandleSplitLeftMenu] = useThrottle(handleSplitLeftMenu, 50);
// watch( // Route change split menu
// () => menuStore.getCurrentTopSplitMenuPathState,
// async (parentPath: string) => {
// throttleHandleSplitLeftMenu(parentPath);
// }
// );
watch( watch(
[() => unref(currentRoute).path, () => props.splitType], [() => unref(currentRoute).path, () => props.splitType],
async ([path, splitType]: [string, MenuSplitTyeEnum]) => { async ([path, splitType]: [string, MenuSplitTyeEnum]) => {
...@@ -88,23 +86,26 @@ export default defineComponent({ ...@@ -88,23 +86,26 @@ export default defineComponent({
} }
); );
// Menu changes
watch( watch(
[() => permissionStore.getLastBuildMenuTimeState, permissionStore.getBackMenuListState], [() => permissionStore.getLastBuildMenuTimeState, () => permissionStore.getBackMenuListState],
() => { () => {
genMenus(); genMenus();
} }
); );
// split Menu changes
watch([() => appStore.getProjectConfig.menuSetting.split], () => { watch([() => appStore.getProjectConfig.menuSetting.split], () => {
if (props.splitType !== MenuSplitTyeEnum.LEFT && !unref(getIsHorizontalRef)) return; if (props.splitType !== MenuSplitTyeEnum.LEFT && !unref(getIsHorizontalRef)) return;
genMenus(); genMenus();
}); });
// Handle left menu split
async function handleSplitLeftMenu(parentPath: string) { async function handleSplitLeftMenu(parentPath: string) {
const isSplitMenu = unref(getProjectConfigRef).menuSetting.split; const isSplitMenu = unref(getProjectConfigRef).menuSetting.split;
if (!isSplitMenu) return; if (!isSplitMenu) return;
const { splitType } = props; const { splitType } = props;
// 菜单分割模式-left // spilt mode left
if (splitType === MenuSplitTyeEnum.LEFT) { if (splitType === MenuSplitTyeEnum.LEFT) {
const children = await getChildrenMenus(parentPath); const children = await getChildrenMenus(parentPath);
if (!children) { if (!children) {
...@@ -128,11 +129,11 @@ export default defineComponent({ ...@@ -128,11 +129,11 @@ export default defineComponent({
} }
} }
// get menus
async function genMenus() { async function genMenus() {
const isSplitMenu = unref(getProjectConfigRef).menuSetting.split; const isSplitMenu = unref(getProjectConfigRef).menuSetting.split;
// 普通模式 // normal mode
const { splitType } = props; const { splitType } = props;
if (splitType === MenuSplitTyeEnum.NONE || !isSplitMenu) { if (splitType === MenuSplitTyeEnum.NONE || !isSplitMenu) {
flatMenusRef.value = await getFlatMenus(); flatMenusRef.value = await getFlatMenus();
...@@ -140,7 +141,7 @@ export default defineComponent({ ...@@ -140,7 +141,7 @@ export default defineComponent({
return; return;
} }
// 菜单分割模式-top // split-top
if (splitType === MenuSplitTyeEnum.TOP) { if (splitType === MenuSplitTyeEnum.TOP) {
const parentPath = await getCurrentParentPath(unref(currentRoute).path); const parentPath = await getCurrentParentPath(unref(currentRoute).path);
menuStore.commitCurrentTopSplitMenuPathState(parentPath); menuStore.commitCurrentTopSplitMenuPathState(parentPath);
...@@ -156,12 +157,11 @@ export default defineComponent({ ...@@ -156,12 +157,11 @@ export default defineComponent({
const { path } = menu; const { path } = menu;
if (path) { if (path) {
const { splitType } = props; const { splitType } = props;
// 菜单分割模式-top // split mode top
if (splitType === MenuSplitTyeEnum.TOP) { if (splitType === MenuSplitTyeEnum.TOP) {
menuStore.commitCurrentTopSplitMenuPathState(path); menuStore.commitCurrentTopSplitMenuPathState(path);
} }
push(path); push(path);
// addTab(path as PageEnum, true);
} }
} }
...@@ -205,6 +205,7 @@ export default defineComponent({ ...@@ -205,6 +205,7 @@ export default defineComponent({
collapsed, collapsed,
collapsedShowTitle, collapsedShowTitle,
collapsedShowSearch, collapsedShowSearch,
accordion,
}, },
} = unref(getProjectConfigRef); } = unref(getProjectConfigRef);
...@@ -227,6 +228,7 @@ export default defineComponent({ ...@@ -227,6 +228,7 @@ export default defineComponent({
onClickSearchInput={handleClickSearchInput} onClickSearchInput={handleClickSearchInput}
appendClass={props.splitType === MenuSplitTyeEnum.TOP} appendClass={props.splitType === MenuSplitTyeEnum.TOP}
isTop={props.isTop} isTop={props.isTop}
accordion={accordion}
> >
{{ {{
header: () => header: () =>
......
...@@ -4,9 +4,6 @@ import { Layout } from 'ant-design-vue'; ...@@ -4,9 +4,6 @@ import { Layout } from 'ant-design-vue';
import LayoutTrigger from './LayoutTrigger'; import LayoutTrigger from './LayoutTrigger';
import { menuStore } from '/@/store/modules/menu'; import { menuStore } from '/@/store/modules/menu';
// import darkMiniIMg from '/@/assets/images/sidebar/dark-mini.png';
// import lightMiniImg from '/@/assets/images/sidebar/light-mini.png';
// import lightImg from '/@/assets/images/sidebar/light.png';
import { appStore } from '/@/store/modules/app'; import { appStore } from '/@/store/modules/app';
import { MenuModeEnum, MenuSplitTyeEnum, TriggerEnum } from '/@/enums/menuEnum'; import { MenuModeEnum, MenuSplitTyeEnum, TriggerEnum } from '/@/enums/menuEnum';
import { SIDE_BAR_MINI_WIDTH, SIDE_BAR_SHOW_TIT_MINI_WIDTH } from '/@/enums/appEnum'; import { SIDE_BAR_MINI_WIDTH, SIDE_BAR_SHOW_TIT_MINI_WIDTH } from '/@/enums/appEnum';
...@@ -44,7 +41,7 @@ export default defineComponent({ ...@@ -44,7 +41,7 @@ export default defineComponent({
initRef.value = true; initRef.value = true;
} }
// 菜单区域拖拽 - 鼠标移动 // Menu area drag and drop-mouse movement
function handleMouseMove(ele: any, wrap: any, clientX: number) { function handleMouseMove(ele: any, wrap: any, clientX: number) {
document.onmousemove = function (innerE) { document.onmousemove = function (innerE) {
let iT = ele.left + ((innerE || event).clientX - clientX); let iT = ele.left + ((innerE || event).clientX - clientX);
...@@ -98,7 +95,6 @@ export default defineComponent({ ...@@ -98,7 +95,6 @@ export default defineComponent({
const side = unref(sideRef); const side = unref(sideRef);
const wrap = (side || {}).$el; const wrap = (side || {}).$el;
// const eleWidth = 6;
ele && ele &&
(ele.onmousedown = (e: any) => { (ele.onmousedown = (e: any) => {
menuStore.commitDragStartState(true); menuStore.commitDragStartState(true);
......
...@@ -19,12 +19,11 @@ import './index.less'; ...@@ -19,12 +19,11 @@ import './index.less';
export default defineComponent({ export default defineComponent({
name: 'DefaultLayout', name: 'DefaultLayout',
setup() { setup() {
// ! 在这里才注册全局组件 // ! Only register global components here
// ! 可以减少首屏代码体积 // ! Can reduce the size of the first screen code
// default layout是在登录后才加载的。所以不会打包到首屏去 // default layout It is loaded after login. So it won’t be packaged to the first screen
registerGlobComp(); registerGlobComp();
// 获取项目配置
const { getFullContent } = useFullContent(); const { getFullContent } = useFullContent();
const getProjectConfigRef = computed(() => { const getProjectConfigRef = computed(() => {
...@@ -56,8 +55,6 @@ export default defineComponent({ ...@@ -56,8 +55,6 @@ export default defineComponent({
return split || (show && mode !== MenuModeEnum.HORIZONTAL && !unref(getFullContent)); return split || (show && mode !== MenuModeEnum.HORIZONTAL && !unref(getFullContent));
}); });
// Get project configuration
// const { getFullContent } = useFullContent(currentRoute);
function getTarget(): any { function getTarget(): any {
const { const {
headerSetting: { fixed }, headerSetting: { fixed },
......
import { ContentEnum, RouterTransitionEnum } from '/@/enums/appEnum';
import { MenuThemeEnum, TopMenuAlignEnum, TriggerEnum } from '/@/enums/menuEnum';
export enum HandlerEnum {
CHANGE_LAYOUT,
// menu
MENU_HAS_DRAG,
MENU_ACCORDION,
MENU_TRIGGER,
MENU_TOP_ALIGN,
MENU_COLLAPSED,
MENU_COLLAPSED_SHOW_TITLE,
MENU_WIDTH,
MENU_SHOW_SIDEBAR,
MENU_THEME,
MENU_SPLIT,
MENU_SHOW_SEARCH,
// header
HEADER_SHOW,
HEADER_THEME,
HEADER_FIXED,
TABS_SHOW_QUICK,
TABS_SHOW,
TABS_SHOW_ICON,
OPEN_PAGE_LOADING,
OPEN_ROUTE_TRANSITION,
ROUTER_TRANSITION,
LOCK_TIME,
FULL_CONTENT,
CONTENT_MODE,
SHOW_BREADCRUMB,
SHOW_BREADCRUMB_ICON,
GRAY_MODE,
COLOR_WEAK,
SHOW_LOGO,
}
export const themeOptions = [
{
value: MenuThemeEnum.LIGHT,
label: '亮色',
},
{
value: MenuThemeEnum.DARK,
label: '暗色',
},
];
export const contentModeOptions = [
{
value: ContentEnum.FULL,
label: '流式',
},
{
value: ContentEnum.FIXED,
label: '定宽',
},
];
export const topMenuAlignOptions = [
{
value: TopMenuAlignEnum.CENTER,
label: '居中',
},
{
value: TopMenuAlignEnum.START,
label: '居左',
},
{
value: TopMenuAlignEnum.END,
label: '居右',
},
];
export const menuTriggerOptions = [
{
value: TriggerEnum.NONE,
label: '不显示',
},
{
value: TriggerEnum.FOOTER,
label: '底部',
},
{
value: TriggerEnum.HEADER,
label: '顶部',
},
];
export const routerTransitionOptions = [
RouterTransitionEnum.ZOOM_FADE,
RouterTransitionEnum.FADE,
RouterTransitionEnum.ZOOM_OUT,
RouterTransitionEnum.FADE_SIDE,
RouterTransitionEnum.FADE_BOTTOM,
].map((item) => {
return {
label: item,
value: item,
};
});
import { HandlerEnum } from './const';
import { MenuThemeEnum, MenuTypeEnum } from '/@/enums/menuEnum';
import { updateColorWeak, updateGrayMode } from '/@/setup/theme';
import { appStore } from '/@/store/modules/app';
import { ProjectConfig } from '/@/types/config';
export function baseHandler(event: HandlerEnum, value: any) {
const config = handler(event, value);
appStore.commitProjectConfigState(config);
}
export function handler(event: HandlerEnum, value: any): DeepPartial<ProjectConfig> {
switch (event) {
case HandlerEnum.CHANGE_LAYOUT:
const { mode, type, split } = value;
const splitOpt = split === undefined ? { split } : {};
let headerSetting = {};
if (type === MenuTypeEnum.TOP_MENU) {
headerSetting = {
theme: MenuThemeEnum.DARK,
};
}
return {
menuSetting: {
mode,
type,
collapsed: false,
show: true,
...splitOpt,
},
headerSetting,
};
case HandlerEnum.MENU_HAS_DRAG:
return {
menuSetting: {
hasDrag: value,
},
};
case HandlerEnum.MENU_ACCORDION:
return {
menuSetting: {
accordion: value,
},
};
case HandlerEnum.MENU_TRIGGER:
return {
menuSetting: {
trigger: value,
},
};
case HandlerEnum.MENU_TOP_ALIGN:
return {
menuSetting: {
topMenuAlign: value,
},
};
case HandlerEnum.MENU_COLLAPSED:
return {
menuSetting: {
collapsed: value,
},
};
case HandlerEnum.MENU_WIDTH:
return {
menuSetting: {
menuWidth: value,
},
};
case HandlerEnum.MENU_COLLAPSED_SHOW_TITLE:
return {
menuSetting: {
collapsedShowTitle: value,
},
};
case HandlerEnum.MENU_SHOW_SIDEBAR:
return {
menuSetting: {
show: value,
},
};
case HandlerEnum.MENU_THEME:
return {
menuSetting: {
theme: value,
},
};
case HandlerEnum.MENU_SPLIT:
return {
menuSetting: {
split: value,
},
};
case HandlerEnum.MENU_SHOW_SEARCH:
return {
menuSetting: {
showSearch: value,
},
};
case HandlerEnum.OPEN_PAGE_LOADING:
return {
openPageLoading: value,
};
case HandlerEnum.OPEN_ROUTE_TRANSITION:
return {
openRouterTransition: value,
};
case HandlerEnum.ROUTER_TRANSITION:
return {
routerTransition: value,
};
case HandlerEnum.LOCK_TIME:
return {
lockTime: value,
};
case HandlerEnum.FULL_CONTENT:
return {
fullContent: value,
};
case HandlerEnum.CONTENT_MODE:
return {
contentMode: value,
};
case HandlerEnum.SHOW_BREADCRUMB:
return {
showBreadCrumb: value,
};
case HandlerEnum.SHOW_BREADCRUMB_ICON:
return {
showBreadCrumbIcon: value,
};
case HandlerEnum.GRAY_MODE:
updateGrayMode(value);
return {
grayMode: value,
};
case HandlerEnum.COLOR_WEAK:
updateColorWeak(value);
return {
colorWeak: value,
};
case HandlerEnum.SHOW_LOGO:
return {
showLogo: value,
};
case HandlerEnum.TABS_SHOW_QUICK:
return {
multiTabsSetting: {
showQuick: value,
},
};
case HandlerEnum.TABS_SHOW_QUICK:
return {
multiTabsSetting: {
showIcon: value,
},
};
case HandlerEnum.TABS_SHOW:
return {
multiTabsSetting: {
show: value,
},
};
case HandlerEnum.HEADER_THEME:
return {
headerSetting: {
theme: value,
},
};
case HandlerEnum.HEADER_FIXED:
return {
headerSetting: {
fixed: value,
},
};
case HandlerEnum.HEADER_SHOW:
return {
headerSetting: {
show: value,
},
};
default:
return {};
}
}
...@@ -74,6 +74,8 @@ const setting: ProjectConfig = { ...@@ -74,6 +74,8 @@ const setting: ProjectConfig = {
collapsedShowSearch: false, collapsedShowSearch: false,
// 折叠触发器的位置 // 折叠触发器的位置
trigger: TriggerEnum.HEADER, trigger: TriggerEnum.HEADER,
// 开启手风琴模式,只显示一个菜单
accordion: true,
}, },
// 消息配置 // 消息配置
messageSetting: { messageSetting: {
......
...@@ -24,6 +24,7 @@ export interface MenuSetting { ...@@ -24,6 +24,7 @@ export interface MenuSetting {
topMenuAlign: 'start' | 'center' | 'end'; topMenuAlign: 'start' | 'center' | 'end';
collapsedShowSearch: boolean; collapsedShowSearch: boolean;
trigger: TriggerEnum; trigger: TriggerEnum;
accordion: boolean;
} }
export interface MultiTabsSetting { export interface MultiTabsSetting {
......
...@@ -30,12 +30,16 @@ declare type Indexable<T = any> = { ...@@ -30,12 +30,16 @@ declare type Indexable<T = any> = {
declare type Hash<T> = Indexable<T>; declare type Hash<T> = Indexable<T>;
// declare type DeepPartial<T> = {
// [P in keyof T]?: T[P] extends (infer U)[]
// ? RecursivePartial<U>[]
// : T[P] extends object
// ? RecursivePartial<T[P]>
// : T[P];
// };
declare type DeepPartial<T> = { declare type DeepPartial<T> = {
[P in keyof T]?: T[P] extends (infer U)[] [P in keyof T]?: DeepPartial<T[P]>;
? RecursivePartial<U>[]
: T[P] extends object
? RecursivePartial<T[P]>
: T[P];
}; };
declare type SelectOptions = { declare type SelectOptions = {
......
...@@ -42,7 +42,7 @@ export function useThemeMode(mode: ThemeModeEnum) { ...@@ -42,7 +42,7 @@ export function useThemeMode(mode: ThemeModeEnum) {
}; };
} }
// 初始化项目配置 // Initial project configuration
export function useInitAppConfigStore() { export function useInitAppConfigStore() {
let projCfg: ProjectConfig = getLocal(PROJ_CFG_KEY) as ProjectConfig; let projCfg: ProjectConfig = getLocal(PROJ_CFG_KEY) as ProjectConfig;
if (!projCfg) { if (!projCfg) {
...@@ -78,12 +78,12 @@ export function useConfigProvider() { ...@@ -78,12 +78,12 @@ export function useConfigProvider() {
}; };
} }
// 初始化网络监听 // Initialize network monitoring
export function useListenerNetWork() { export function useListenerNetWork() {
const { listenNetWork } = appStore.getProjectConfig; const { listenNetWork } = appStore.getProjectConfig;
if (!listenNetWork) return; if (!listenNetWork) return;
const { replace } = useRouter(); const { replace } = useRouter();
// 检测网络状态 // Check network status
useNetWork({ useNetWork({
onLineFn: () => { onLineFn: () => {
replace(PageEnum.BASE_HOME); replace(PageEnum.BASE_HOME);
......
<template> <template>
<div class="analysis p-4"> <div class="analysis p-4">
<Row class="pl-2"> <a-row class="pl-2">
<template v-for="item in growCardList" :key="item.title"> <template v-for="item in growCardList" :key="item.title">
<ACol :sm="24" :md="12" :lg="6"> <ACol :sm="24" :md="12" :lg="6">
<GrowCard :info="item" /> <GrowCard :info="item" />
</ACol> </ACol>
</template> </template>
</Row> </a-row>
<Row> <a-row>
<ACol :md="24" :lg="17" class="my-3"> <a-col :md="24" :lg="17" class="my-3">
<CollapseContainer class="mr-3" title="产品成交额" :canExpan="false"> <CollapseContainer class="mr-3" title="产品成交额" :canExpan="false">
<AnalysisLine /> <AnalysisLine />
</CollapseContainer> </CollapseContainer>
<Row class="mt-3"> <a-row class="mt-3">
<ACol :md="24" :lg="12" class="product-total"> <a-col :md="24" :lg="12" class="product-total">
<CollapseContainer class="mr-3" title="产品成交额" :canExpan="false"> <CollapseContainer class="mr-3" title="产品成交额" :canExpan="false">
<AnalysisPie /> <AnalysisPie />
</CollapseContainer> </CollapseContainer>
</ACol> </a-col>
<ACol :md="24" :lg="12"> <a-col :md="24" :lg="12">
<CollapseContainer class="mr-3" title="用户来源" :canExpan="false"> <CollapseContainer class="mr-3" title="用户来源" :canExpan="false">
<AnalysisBar /> <AnalysisBar />
</CollapseContainer> </CollapseContainer>
</ACol> </a-col>
</Row> </a-row>
</ACol> </a-col>
<ACol :md="24" :lg="7"> <a-col :md="24" :lg="7">
<CollapseContainer class="mt-3" title="项目进度" :canExpan="false"> <CollapseContainer class="mt-3" title="项目进度" :canExpan="false">
<template v-for="item in taskList" :key="item.title"> <template v-for="item in taskList" :key="item.title">
<TaskCard :info="item" /> <TaskCard :info="item" />
</template> </template>
</CollapseContainer> </CollapseContainer>
</ACol> </a-col>
</Row> </a-row>
<Row> <a-row>
<FlowAnalysis /> <FlowAnalysis />
</Row> </a-row>
</div> </div>
</template> </template>
<script lang="ts"> <script lang="ts">
...@@ -48,14 +48,11 @@ ...@@ -48,14 +48,11 @@
import AnalysisBar from './components/AnalysisBar.vue'; import AnalysisBar from './components/AnalysisBar.vue';
import TaskCard from './components/TaskCard.vue'; import TaskCard from './components/TaskCard.vue';
import FlowAnalysis from './components/FlowAnalysis'; import FlowAnalysis from './components/FlowAnalysis';
import { Row, Col } from 'ant-design-vue';
import { CollapseContainer } from '/@/components/Container/index'; import { CollapseContainer } from '/@/components/Container/index';
import { growCardList, taskList } from './data'; import { growCardList, taskList } from './data';
export default defineComponent({ export default defineComponent({
components: { components: {
Row,
ACol: Col,
GrowCard, GrowCard,
CollapseContainer, CollapseContainer,
TrendLine, TrendLine,
......
<template> <template>
<Row class="workbench p-4" :gutter="12"> <a-row class="workbench p-4" :gutter="12">
<Col :md="24" :lg="17"> <a-col :md="24" :lg="17">
<ProdTotal class="mb-3" /> <ProdTotal class="mb-3" />
<TodoList class="mb-3" /> <TodoList class="mb-3" />
<NewsList class="mb-3" /> <NewsList class="mb-3" />
</Col> </a-col>
<Col :md="24" :lg="7"> <a-col :md="24" :lg="7">
<img src="/@/assets/images/dashboard/wokb/wokb.png" class="workbench__wokb-img mb-3" /> <img src="/@/assets/images/dashboard/wokb/wokb.png" class="workbench__wokb-img mb-3" />
<ShortCuts class="mb-3" /> <ShortCuts class="mb-3" />
<Week class="mb-3" /> <Week class="mb-3" />
</Col> </a-col>
</Row> </a-row>
</template> </template>
<script lang="ts"> <script lang="ts">
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import { Row, Col } from 'ant-design-vue';
import ProdTotal from './components/ProdTotal.vue'; import ProdTotal from './components/ProdTotal.vue';
import TodoList from './components/TodoList.vue'; import TodoList from './components/TodoList.vue';
import Week from './components/Week.vue'; import Week from './components/Week.vue';
...@@ -22,7 +21,7 @@ ...@@ -22,7 +21,7 @@
import ShortCuts from './components/ShortCuts.vue'; import ShortCuts from './components/ShortCuts.vue';
export default defineComponent({ export default defineComponent({
components: { Row, Col, ProdTotal, TodoList, Week, ShortCuts, NewsList }, components: { ProdTotal, TodoList, Week, ShortCuts, NewsList },
setup() { setup() {
return {}; return {};
}, },
......
...@@ -168,7 +168,7 @@ ...@@ -168,7 +168,7 @@
display: none; display: none;
height: 100%; height: 100%;
background: url(../../../assets/images/login/login-in.png) no-repeat; background: url(../../../assets/images/login/login-in.png) no-repeat;
background-position: 50% 30%; background-position: 30% 30%;
background-size: 80% 80%; background-size: 80% 80%;
.respond-to(xlarge, { display: block;}); .respond-to(xlarge, { display: block;});
...@@ -194,9 +194,9 @@ ...@@ -194,9 +194,9 @@
align-items: center; align-items: center;
.respond-to(large, { .respond-to(large, {
width: 600px; width: 600px;
right: calc(50% - 300px); right: calc(50% - 270px);
}); });
.respond-to(xlarge, { width: 600px; right:0}); .respond-to(xlarge, { width: 540px; right:0});
} }
&__content { &__content {
......
...@@ -34,7 +34,7 @@ const viteConfig: UserConfig = { ...@@ -34,7 +34,7 @@ const viteConfig: UserConfig = {
* @default 'index.html' * @default 'index.html'
*/ */
// TODO build error // TODO build error
// entry: './public/index.html', // entry: 'public/index.html',
/** /**
* port * port
* @default '3000' * @default '3000'
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论