Skip to content

Commit

Permalink
feature(createTemplate): 创建模版重构
Browse files Browse the repository at this point in the history
  • Loading branch information
Hacker233 committed Sep 29, 2024
1 parent 014af04 commit 8d503ed
Show file tree
Hide file tree
Showing 10 changed files with 263 additions and 18 deletions.
13 changes: 13 additions & 0 deletions src/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,24 @@ declare module '@vue/runtime-core' {
DateFormItem: typeof import('./components/DateFormItem/DateFormItem.vue')['default']
Editor: typeof import('./components/packages/components/editor/editor.vue')['default']
EduBackgroundCom: typeof import('./components/ModelComs/EduBackgroundCom.vue')['default']
ElAlert: typeof import('element-plus/es')['ElAlert']
ElAvatar: typeof import('element-plus/es')['ElAvatar']
ElBacktop: typeof import('element-plus/es')['ElBacktop']
ElButton: typeof import('element-plus/es')['ElButton']
ElCarousel: typeof import('element-plus/es')['ElCarousel']
ElCarouselItem: typeof import('element-plus/es')['ElCarouselItem']
ElCheckbox: typeof import('element-plus/es')['ElCheckbox']
ElCollapse: typeof import('element-plus/es')['ElCollapse']
ElCollapseItem: typeof import('element-plus/es')['ElCollapseItem']
ElConfigProvider: typeof import('element-plus/es')['ElConfigProvider']
ElDatePicker: typeof import('element-plus/es')['ElDatePicker']
ElDialog: typeof import('element-plus/es')['ElDialog']
ElDivider: typeof import('element-plus/es')['ElDivider']
ElDrawer: typeof import('element-plus/es')['ElDrawer']
ElDropdown: typeof import('element-plus/es')['ElDropdown']
ElDropdownItem: typeof import('element-plus/es')['ElDropdownItem']
ElDropdownMenu: typeof import('element-plus/es')['ElDropdownMenu']
ElEmpty: typeof import('element-plus/es')['ElEmpty']
ElForm: typeof import('element-plus/es')['ElForm']
ElFormItem: typeof import('element-plus/es')['ElFormItem']
ElIcon: typeof import('element-plus/es')['ElIcon']
Expand All @@ -43,11 +51,16 @@ declare module '@vue/runtime-core' {
ElInputNumber: typeof import('element-plus/es')['ElInputNumber']
ElMenu: typeof import('element-plus/es')['ElMenu']
ElMenuItem: typeof import('element-plus/es')['ElMenuItem']
ElOption: typeof import('element-plus/es')['ElOption']
ElPagination: typeof import('element-plus/es')['ElPagination']
ElPopover: typeof import('element-plus/es')['ElPopover']
ElProgress: typeof import('element-plus/es')['ElProgress']
ElRadio: typeof import('element-plus/es')['ElRadio']
ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup']
ElRate: typeof import('element-plus/es')['ElRate']
ElScrollbar: typeof import('element-plus/es')['ElScrollbar']
ElSelect: typeof import('element-plus/es')['ElSelect']
ElSelectV2: typeof import('element-plus/es')['ElSelectV2']
ElSkeleton: typeof import('element-plus/es')['ElSkeleton']
ElSkeletonItem: typeof import('element-plus/es')['ElSkeletonItem']
ElSlider: typeof import('element-plus/es')['ElSlider']
Expand Down
26 changes: 26 additions & 0 deletions src/store/createTemplate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { defineStore } from 'pinia';
import { cloneDeep } from 'lodash';
import { HJNewSchema } from '@/views/createTemplate/designer/schema/template';
import { IHJNewSchema, IModule } from '@/views/createTemplate/types/IHJNewSchema';

// 创建在线制作模版store
export const useCreateTemplateStore = defineStore('createTemplate', () => {
const resume_json = cloneDeep(HJNewSchema); // 简历数据
const HJNewJsonStore = ref<IHJNewSchema>(resume_json);
function changeResumeJsonData(obj: IHJNewSchema) {
HJNewJsonStore.value = cloneDeep(obj);
}
function pushComponent(data: IModule) {
HJNewJsonStore.value.componentsTree.push(data);
}
function resetResumeJson() {
HJNewJsonStore.value = cloneDeep(HJNewSchema);
}

return {
HJNewJsonStore,
changeResumeJsonData,
pushComponent,
resetResumeJson
};
});
3 changes: 3 additions & 0 deletions src/store/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { useLegoJsonStore, useLegoSelectWidgetStore, useUndoAndRedoStore } from
import { useIndexMenuStore } from './menu';
import { useWebsiteConfigStore } from './websiteConfig';
import { useMembershipStore } from './membership';
import { useCreateTemplateStore } from './createTemplate';

export interface IAppStore {
useLoadingStore: ReturnType<typeof useLoadingStore>;
Expand All @@ -24,6 +25,7 @@ export interface IAppStore {
useIndexMenuStore: ReturnType<typeof useIndexMenuStore>;
useWebsiteConfigStore: ReturnType<typeof useWebsiteConfigStore>;
useMembershipStore: ReturnType<typeof useMembershipStore>;
useCreateTemplateStore: ReturnType<typeof useCreateTemplateStore>;
}

const appStore: IAppStore = {} as IAppStore;
Expand All @@ -45,6 +47,7 @@ export const registerStore = () => {
appStore.useIndexMenuStore = useIndexMenuStore();
appStore.useWebsiteConfigStore = useWebsiteConfigStore();
appStore.useMembershipStore = useMembershipStore();
appStore.useCreateTemplateStore = useCreateTemplateStore();
// 重写reset方法
initResetFun(appStore);
};
Expand Down
97 changes: 97 additions & 0 deletions src/views/createTemplate/designer/components/ModuleSelect.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
<!-- 模块选择 -->
<template>
<div class="module-select">
<div class="left-title" @click="selectNone">
<span>模块</span>
<span>选择</span>
</div>
<c-scrollbar trigger="hover" style="height: calc(100vh - 110px)">
<ul>
<li
v-for="(val, key, index) in MATERIAL_JSON"
:key="index"
:class="[{ active: currentKey === key }]"
@click="selectModel(val, key as string)"
>
<svg-icon :icon-name="modelOfIcon[key]" color="#2cbd99" size="25px"></svg-icon>
<p>{{ modelOfTitle[key] }}</p>
</li>
</ul>
</c-scrollbar>
</div>
</template>
<script setup lang="ts">
import { MATERIAL_JSON } from '@/schema/materialList';
import modelOfTitle from '@/dictionary/modelOfTitle';
import modelOfIcon from '@/dictionary/modelOfIcon';
import modelCategory from '@/dictionary/modelOfTitle';

// 点击模块选择
const currentKey = ref<string>('');
const currentTitle = ref<string>('物料组件');
let cptList = ref<Array<any>>([]);
const selectModel = (val: Array<any>, key: string) => {
currentTitle.value = modelCategory[key];
currentKey.value = key;
cptList.value = val;
console.log('cptList', cptList);
};

// 重置模块
const selectNone = () => {
currentKey.value = '';
};
</script>
<style lang="scss" scoped>
.module-select {
width: 75px;
border-right: 1px solid #eee;
.left-title {
width: 100%;
height: 60px;
display: flex;
flex-direction: column;
justify-content: space-evenly;
align-items: center;
border-top: 1px solid #eee;
border-bottom: 1px solid #eee;
color: #2cbd99;
box-sizing: border-box;
user-select: none;
cursor: pointer;
span {
font-size: 17px;
font-weight: 600;
font-family: cursive;
}
}
ul {
width: 100%;
height: calc(100vh - 110px);
li {
list-style: none;
width: 100%;
height: 60px;
display: flex;
flex-direction: column;
justify-content: space-evenly;
align-items: center;
border-bottom: 1px solid #eee;
cursor: pointer;
transition: all 0.3s;
user-select: none;
&:hover {
background-color: rgba(#2cbd99, 0.2);
}
p {
font-size: 12px;
color: #2cbd99;
transform: scale(0.9);
}
}
.active {
background-color: rgba(#2cbd99, 0.2);
}
}
}
</style>
16 changes: 16 additions & 0 deletions src/views/createTemplate/designer/components/NavBar.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<!-- 创建模版页导航栏 -->
<template>
<div class="nav-bar-box"> </div>
</template>
<style lang="scss" scoped>
.nav-bar-box {
width: 100%;
height: 50px;
background-color: #fff;
box-shadow: 0 5px 21px 0 rgb(78 78 78 / 5%);
flex-shrink: 0;
position: sticky;
top: 0;
z-index: 10;
}
</style>
70 changes: 68 additions & 2 deletions src/views/createTemplate/designer/index.vue
Original file line number Diff line number Diff line change
@@ -1,10 +1,76 @@
<template>
<div class="create-template-box"></div>
<div class="create-template-box">
<!-- 导航栏 -->
<nav-bar></nav-bar>
<!-- 内容区容器 -->
<div class="content-wrapper">
<!-- 左侧物料区 -->
<div class="module-left">
<!-- 模块选择 -->
<module-select></module-select>
</div>
<!-- 中间设计区 -->
<div class="design-center">
<!-- 页面渲染 -->
<component :is="pageComponents[pageComponent]" :style="HJNewJsonStore.css"></component>
</div>
<!-- 右侧属性面板区 -->
<div class="prop-right"></div>
</div>
</div>
</template>
<script lang="ts" setup></script>
<script lang="ts" setup>
import NavBar from './components/NavBar.vue';
import ModuleSelect from './components/ModuleSelect.vue';
import { storeToRefs } from 'pinia';
import appStore from '@/store';
import pageComponents from './utils/registerPages';
// 初始化JSON数据
const { HJNewJsonStore } = storeToRefs(appStore.useCreateTemplateStore);
// 返回page组件
const pageComponent = computed(() => {
if (HJNewJsonStore.value.props.page) {
return HJNewJsonStore.value.props.page;
} else {
return 'CommonPage';
}
});
console.log('pageComponents', pageComponents);
</script>
<style lang="scss" scoped>
.create-template-box {
width: 100%;
height: 100vh;
display: flex;
flex-direction: column;
position: relative;
.content-wrapper {
width: 100%;
flex: 1;
display: flex;
.module-left {
height: 100%;
width: 400px;
background-color: #fff;
// box-shadow: 0 1px 4px rgba(0, 0, 0, 0.16);
}
.design-center {
height: calc(100vh - 50px);
flex: 1;
padding: 20px 0;
display: flex;
flex-direction: column;
align-items: center;
overflow: auto;
}
.prop-right {
height: 100%;
min-width: 400px;
background-color: #fff;
// box-shadow: -1px 0 4px rgba(0, 0, 0, 0.16);
}
}
}
</style>
24 changes: 23 additions & 1 deletion src/views/createTemplate/designer/pages/CommonPage.vue
Original file line number Diff line number Diff line change
@@ -1,3 +1,25 @@
<template>
<div class="page-box"> </div>
<div class="page-box" :style="style"> </div>
</template>
<script setup lang="ts">
const props = defineProps<{
style: any;
}>();
const style = computed(() => {
return {
width: `${props.style.width}px`,
minHeight: `${props.style.height}px`,
background: props.style.background || '#ffffff',
opacity: props.style.opacity,
backgroundImage: props.style.backgroundImage || '',
fontFamily: props.style.fontFamily || ''
};
});
</script>
<style lang="scss" scoped>
.page-box {
width: 820px;
min-height: 1160px;
}
</style>
3 changes: 3 additions & 0 deletions src/views/createTemplate/designer/schema/template.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ export const HJNewSchema: IHJNewSchema = {
componentsTree: [], // 描述组件/区块/模板的组件树
i18n: {}, // 国际化语料库
constants: {}, // 全局常量
props: {
pageName: ''
},
css: {
width: 820,
height: 1160,
Expand Down
9 changes: 9 additions & 0 deletions src/views/createTemplate/designer/utils/registerPages.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// 注册页面组件

import CommonPage from '../pages/CommonPage.vue';

// 定义属性组件列表
const pageComponents: any = {
CommonPage
};
export default pageComponents;
20 changes: 5 additions & 15 deletions src/views/createTemplate/types/IHJNewSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ interface IHJNewSchema {
componentsTree: Array<any>; // 描述组件/区块/模板的组件树
i18n: any; // 国际化语料库
constants: any; // 全局常量
props: any; // 自定义的属性
css: {
width: number;
height: number;
Expand All @@ -21,15 +22,14 @@ interface IHJNewSchema {
dataSource: any; // 全局范围的公共数据源
}

// 组件JSON格式
interface IWidget {
interface IModule {
id: string; // 组件唯一性id
componentName: string; // 组件名
commentType: string; // 组件类型
commentType: ''; // 组件类型
icon: string; // 组件icon
title: string; // 组件中文名称
description: string; // 组件描述信息
screenShot: {
screenShot?: {
src: string;
width: string;
height: string;
Expand All @@ -41,15 +41,5 @@ interface IWidget {
css: any; // 组件样式
dataSource: any; // 组件单独数据
customProps?: any; // 自定义属性字段
children?: [];
}

// 某一个组件分类格式
interface IWidgetTab {
title: string;
category: string;
icon: string;
dataSource: any; // 该分类下公用数据源
list: Array<IWidget>;
}
export { IHJNewSchema, IWidget, IWidgetTab };
export { IHJNewSchema, IModule };

0 comments on commit 8d503ed

Please sign in to comment.