Commit 1000f997 authored by 郝聪敏's avatar 郝聪敏

featuer: 优化页面;新增uuid

parent 6c8fa9a3
import { Controller, Context } from 'egg';
import { trim, omitBy } from 'lodash';
import { v1 as uuidv1 } from 'uuid';
export default class EditorController extends Controller {
......@@ -13,18 +14,21 @@ export default class EditorController extends Controller {
public async save(ctx: Context) {
const pageInfo = ctx.request.body;
const result = await ctx.model.PageInfo.create(pageInfo);
const result = await ctx.model.PageInfo.create({ ...pageInfo, uuid: uuidv1().replace(/-/g, '')});
ctx.body = ctx.helper.ok(result);
}
public async update(ctx: Context) {
const pageInfo = ctx.request.body;
const result = await ctx.model.PageInfo.update(pageInfo, {where: { id: +pageInfo.id }});
if (!pageInfo.uuid) {
pageInfo.uuid = uuidv1().replace(/-/g, '');
}
const result = await ctx.model.PageInfo.update(pageInfo, {where: { uuid: pageInfo.uuid }});
ctx.body = ctx.helper.ok(result);
}
public async get(ctx: Context) {
const pageInfo = await ctx.model.PageInfo.findOne({where: { id: +ctx.params.pageId }});
const pageInfo = await ctx.model.PageInfo.findOne({where: { uuid: ctx.params.uuid }});
ctx.body = ctx.helper.ok(pageInfo);
}
......
......@@ -35,6 +35,18 @@ export class PageInfo extends Model<PageInfo> {
})
pageDescribe: string;
@Column({
field: 'page_keywords',
type: DataType.STRING(255)
})
pageKeywords: string;
@Column({
field: 'uuid',
type: DataType.UUID
})
uuid: string;
@Column({
type: DataType.INTEGER(1)
})
......
......@@ -13,7 +13,7 @@ export default (application: Application) => {
router.post('/editor/update', controller.editor.update);
router.get('/editor/get/list', controller.editor.getList);
router.get('/editor/get/template', controller.editor.getTemplateList);
router.get('/editor/get/:pageId', controller.editor.get);
router.get('/editor/get/:uuid', controller.editor.get);
router.delete('/editor/:pageId', controller.editor.delete);
router.get('/editor/login', controller.editor.login);
router.get('/editor', controller.editor.home);
......
const protocol = EASY_ENV_IS_BROWSER ? window.location.protocol : 'http';
export default {
// apiHost: `http://localhost:7002/`,
apiHost: `http://localhost:7001/`,
// apiHost: `http://192.168.28.199:7001/`,
apiHost: 'https://quantum-blocks-vcc2.liangkebang.net/',
// apiHost: 'https://quantum-blocks-vcc2.liangkebang.net/',
h5Host: 'https://quantum-h5-vcc2.liangkebang.net/',
qiniuHost: `https://appsync.lkbang.net/`,
shenceUrl: `${protocol}//bn.xyqb.com/sa?project=default`,
......
......@@ -10,7 +10,6 @@ import config from '@/config';
@Component({ components: { Upload }, name: 'BasicPageForm' })
export default class DynamicForm extends Vue {
@Getter('pageInfo') pageData;
@Getter('pageId') pageId;
@Prop(Boolean) value;
showPopup: boolean = false;
......@@ -23,8 +22,8 @@ export default class DynamicForm extends Vue {
@Watch('pageData', { immediate: true })
onPageDataChange(newVal) {
const { pageName, pageDescribe, coverImage, isPublish, isTemplate } = this.pageData;
this.formCustom = { pageName, pageDescribe, coverImage, isPublish: !!isPublish, isTemplate: !!isTemplate };
const { pageName, pageDescribe, pageKeywords, coverImage, isPublish, isTemplate } = this.pageData;
this.formCustom = { pageName, pageDescribe, pageKeywords, coverImage, isPublish: !!isPublish, isTemplate: !!isTemplate };
}
@Watch('value')
......@@ -46,6 +45,11 @@ export default class DynamicForm extends Vue {
this.$emit('input', val);
}
preview() {
this.formCustom.pageName = this.formCustom.pageName ?? '未命名';
this.handleSubmit('preview');
}
async createCoverImage() {
try {
const imgName = btoa(`coverImage-${uuidv4().substr(0, 8)}`);
......
......@@ -7,11 +7,14 @@
<FormItem label="页面描述" prop="pageDescribe">
<Input v-model="formCustom.pageDescribe" type="textarea" placeholder="请输入页面描述" :rows="3"></Input>
</FormItem>
<FormItem label="页面关键字" prop="pageKeywords">
<Input v-model="formCustom.pageKeywords" type="textarea" placeholder="请输入页面关键字" :rows="3"></Input>
</FormItem>
<FormItem label="是否发布" prop="isPublish">
<Checkbox v-model="formCustom.isPublish"></Checkbox>
<i-switch v-model="formCustom.isPublish"></i-switch>
</FormItem>
<FormItem label="是否模板" prop="isTemplate" v-if="formCustom.isPublish">
<Checkbox v-model="formCustom.isTemplate"></Checkbox>
<FormItem label="设为模板" prop="isTemplate" v-if="formCustom.isPublish">
<i-switch v-model="formCustom.isTemplate"></i-switch>
</FormItem>
</Form>
<div slot="footer">
......
<template>
<div class="dynamic">
<Row v-for="(arr, index) in eleConfig" :key="index" class="dynamic-row" type="flex" justify="space-between">
<Col span="10" v-for="config in arr" :key="config.eleName+index">
<Col span="11" v-for="config in arr" :key="config.eleName+index">
<Card draggable="true" @dragend.native="dragend" @dragstart.native="dragstart($event, config.eleName)">
<p slot="title">{{ config.title }}</p>
<div class="dynamic-row-card">
<img
src="http://activitystatic.q-gp.com/low_code.jpg"
src="https://activitystatic.q-gp.com/%E5%95%86%E5%93%81%402x.png"
/>
</div>
</Card>
......@@ -17,11 +17,10 @@
<script lang="ts" src="./index.ts"></script>
<style lang="less">
.dynamic {
margin-top: 10px;
&-row {
margin-bottom: 10px;
margin-bottom: 8px;
p {
text-align: center;
text-align: left;
}
&-card {
......@@ -42,6 +41,11 @@
&-body {
padding: 10px;
}
&:hover {
box-shadow: 0 0.026667rem 0.16rem rgba(240, 242, 245, 20%);
border-color: #2d8cf0 !important;
}
}
}
}
......
......@@ -39,7 +39,7 @@ export default class DashBoard extends Mixins(ContextMenuMixin, GoodsTabsMixin,
@Action('getPageDate') getPageDate;
@Action('getTemplateList') getTemplateList;
@Action('setTemplateInfo') setTemplateInfo;
@Getter('pageId') pageId;
@Getter('uuid') uuid;
@Getter('pageData') pageData;
@State(state => state.editor.gridLayout.draggable) draggable;
@State(state => state.editor.gridLayout.rowHeight) rowHeight;
......@@ -87,17 +87,21 @@ export default class DashBoard extends Mixins(ContextMenuMixin, GoodsTabsMixin,
} else {
this.pageData.elements.sort((a, b) => a.point.y - b.point.y);
const pageData = this.handleGoodsTabs();
const { pageName, pageDescribe, coverImage, isPublish, isTemplate } = pageConfig;
const pageInfo = { page: JSON.stringify(pageData), author: user?.account, isPublish, pageName, pageDescribe, coverImage, isTemplate };
if (+this.pageId) { pageInfo.id = this.pageId; }
const { pageName, pageDescribe, pageKeywords, coverImage, isPublish, isTemplate } = pageConfig;
const pageInfo = { page: JSON.stringify(pageData), author: user?.account, isPublish, pageName, pageDescribe, pageKeywords, coverImage, isTemplate };
if (this.uuid) { pageInfo.uuid = this.uuid; }
await this.savePageData({ pageInfo, pageData: this.pageData });
this.showSubmitPopup = false;
if (type === 'preview') {
window.open(`${config.h5Host}activity/${this.pageId}`);
window.open(`${config.h5Host}activity/${this.uuid}`);
}
}
}
async preview() {
this.$refs.basicPageForm.preview();
}
exit() {
this.$router.back();
}
......
<template>
<Row class="dashboard">
<!-- <Row class="dashboard-header" type="flex" align="middle">
<Col span="8">
<h3>低代码开发平台</h3>
</Col>
<Col span="6">
<Row type="flex" justify="end">
<Col span="7" @click.native="save()">
<Icon type="ionic"></Icon>
<span>保存</span>
</Col>
<Col span="7" @click.native="exit">
<Icon type="monitor"></Icon>
<span>返回</span>
</Col>
</Row>
</Col>
</Row> -->
<Row class="dashboard-header" type="flex" align="middle">
<Col span="20" offset="2">
<Button @click="preview()">预览</Button>
<Button type="primary" @click="save()">保存</Button>
</Col>
<Col span="2">
<Button @click="exit">取消</Button>
</Col>
</Row>
<Row class="dashboard-container">
<Col class="dashboard-container-left" span="6">
<Menu class="Dc-left-menu" active-name="1" @on-select="selectMaterial">
<MenuItem name="1">
<Icon type="ios-paper"></Icon>
<Icon type="android-apps"></Icon>
<span>基础库</span>
</MenuItem>
<MenuItem name="2">
<Icon type="ios-people"></Icon>
<Icon type="android-apps"></Icon>
<span>业务库</span>
</MenuItem>
<MenuItem name="3">
<Icon type="stats-bars"></Icon>
<Icon type="android-apps"></Icon>
<span>模版</span>
</MenuItem>
</Menu>
<div class="Dc-left-content">
<div v-show="activeName === '1'">
<h2>基础库</h2>
<dynamic-component :data="resources.basicComponents" @dragstart="dragstart" @dragend="dragend"></dynamic-component>
</div>
<div v-show="activeName === '2'">
<h2>业务库</h2>
<dynamic-component :data="resources.businessComponents" @dragstart="dragstart" @dragend="dragend"></dynamic-component>
</div>
<div v-show="activeName === '3'">
<h2>模板</h2>
<dynamic-component :data="templateList" @dragstart="dragstart" @dragend="dragend"></dynamic-component>
</div>
</div>
......@@ -48,7 +40,7 @@
<Col class="dashboard-container-middle" span="18">
<Row class="Dc-middle-row">
<Col :span="isCollapsed ? 24 : 16" class="Dc-middle-container" @click.native="toggle(true)">
<Row type="flex" justify="center" class="Dcm-container-header">
<!-- <Row type="flex" justify="center" class="Dcm-container-header">
<Col span="4" @click.native="save()">
<Icon type="ionic"></Icon>
<span>保存</span>
......@@ -57,7 +49,7 @@
<Icon type="monitor"></Icon>
<span>返回</span>
</Col>
</Row>
</Row> -->
<div :class="[{'Dcm-container-panel_in': isDragIn, 'Dcm-container-panel_draging': isDraging}, 'Dcm-container-panel']" @dragover.prevent @dragenter="dragenter" @dragover="dragover"
@dragleave="dragleave" @drop="drops">
<grid-layout
......@@ -90,7 +82,7 @@
</div>
</Col>
<Col span="8" :class="[{'Dcm-sider_none': isCollapsed}, 'Dc-middle-sider']">
<Tabs class="Dc-middle-editing" type="card">
<Tabs class="Dc-middle-editing">
<TabPane label="组件设置">
<dynamic-form @modProps="modProps" @resizedChildEvent="resizedChildEvent"></dynamic-form>
</TabPane>
......@@ -103,7 +95,7 @@
</Row>
</Col>
</Row>
<BasicPageForm v-model="showSubmitPopup" @submit="save" />
<BasicPageForm ref="basicPageForm" v-model="showSubmitPopup" @submit="save" />
</Row>
</template>
<style lang="less" scoped>
......@@ -124,22 +116,42 @@
box-shadow: 0 2px 3px 0 hsla(0,0%,39.2%,.06);
font-size: 16px;
z-index: 901;
.ivu-col {
text-align: center;
button {
width: 100px;
&:nth-child(2) {
margin-left: 40px;
}
}
}
}
&-container {
height: 100%;
height: calc(100% - 48px);
&-left {
display: flex !important;
height: 100%;
.Dc-left-menu {
height: 100%;
width: 65px !important;
i {
font-size: 18px !important;
}
width: 77px !important;
.ivu-menu-item {
padding-left: 0;
padding-right: 0;
display: flex;
flex-direction: column;
align-items: center;
i {
font-size: 18px !important;
}
span {
font-size: 14px;
line-height: 22px;
}
}
}
.Dc-left-content {
flex: 1;
padding: 10px;
padding: 8px;
background: #fff;
overflow-y: scroll;
}
......
......@@ -96,7 +96,7 @@ export default {
on: {
click: () => {
console.log(params);
this.$router.push(`/detail/${params.row.id}`);
this.$router.push(`/detail/${params.row.uuid}`);
},
},
},
......
......@@ -119,7 +119,7 @@ export default {
on: {
click: () => {
console.log(params);
this.$router.push(`/detail/${params.row.id}`);
this.$router.push(`/detail/${params.row.uuid}`);
},
},
},
......
......@@ -106,7 +106,7 @@ export default {
},
on: {
click: () => {
this.$router.push({ name: 'detail', params: { templateId: params.row.id } });
this.$router.push({ name: 'detail', params: { templateId: params.row.uuid } });
},
},
},
......
......@@ -31,6 +31,9 @@ export default class EditorModule implements Module<EditorState, RootState> {
pageId(state) {
return state.pageInfo.id;
},
uuid(state) {
return state.pageInfo.uuid;
},
pageInfo(state) {
return state.pageInfo;
}
......@@ -39,7 +42,7 @@ export default class EditorModule implements Module<EditorState, RootState> {
actions: ActionTree<EditorState, RootState> = {
// pageInfo: 处理过的页面数据 - activity, pageData: 未处理的数据 - editor
async savePageData({ commit }, { pageInfo, pageData}) {
if (pageInfo.id) {
if (pageInfo.uuid) {
await api.updatePage(pageInfo);
commit(SET_PAGE_INFO, { ...pageInfo, page: pageData });
} else {
......
......@@ -47,6 +47,10 @@ export interface PageInfo {
coverImage?: string;
isTemplate?: number;
isPublish?: number | boolean;
pageName?: string;
pageDescribe?: string;
pageKeyords?: string;
uuid?: string;
}
export const defaultState = {
......@@ -56,8 +60,11 @@ export const defaultState = {
id: 0,
pageName: '',
pageDescribe: '',
pageKeyords: '',
coverImage: 'http://activitystatic.q-gp.com/low_code.jpg',
isPublish: false,
isTemplate: false,
uuid: '',
page: {
commonStyle: {
backgroundColor: '#f7f8fa',
......
......@@ -8,6 +8,7 @@
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, minimal-ui">
<link rel="shortcut icon" href="/favicon.ico" type="image/x-icon" />
<link href="https://cdn.bootcss.com/iview/2.9.0/styles/iview.css" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="https://activitystatic.lkbang.net/swiper/4.5.1/css/swiper.min.css">
<style>
html {
font-size: 37.5Px !important;
......@@ -24,5 +25,9 @@
<script src="https://cdn.bootcss.com/vue/2.6.12/vue.js"></script>
<script src="https://cdn.bootcss.com/iview/2.9.0/iview.min.js"></script>
<script src="https://cdn.bootcss.com/vue-router/3.0.1/vue-router.min.js"></script>
<script src="https://activitystatic.lkbang.net/vuex/3.4.0/vuex.min.js"></script>
<script src="https://activitystatic.lkbang.net/sa-sdk-javascript/1.15.16/sensorsdata.min.js"></script>
<script src="https://activitystatic.lkbang.net/swiper/4.5.1/swiper.min.js"></script>
<script src="https://cdn.bootcss.com/axios/0.19.2/axios.min.js"></script>
</body>
</html>
\ No newline at end of file
......@@ -1479,9 +1479,9 @@
}
},
"@qg/citrus-ui": {
"version": "0.0.18",
"resolved": "http://npmprivate.quantgroups.com/@qg%2fcitrus-ui/-/citrus-ui-0.0.18.tgz",
"integrity": "sha512-yqMmQzYiJzWRx5rH61iMI/Yc5FpZLELtfYLOhA/ry2/jeLzDeJ743Ri9dTcB9iSyJJe4njOcBl0xSBIdhPN2jw==",
"version": "0.0.21",
"resolved": "http://npmprivate.quantgroups.com/@qg%2fcitrus-ui/-/citrus-ui-0.0.21.tgz",
"integrity": "sha512-um+tQJJ+3R4qZ3IjZ8bNtnkaNqtnHypihbagNNKKkm3iS9XuL77MFzjX+SrXMCJlU1i3/aXBdLOokeKZc9FOoQ==",
"requires": {
"@better-scroll/core": "^2.1.1",
"@qg/cherry-ui": "^2.18.72",
......@@ -22420,15 +22420,6 @@
"resolved": "http://npmprivate.quantgroups.com/vue/-/vue-2.6.12.tgz",
"integrity": "sha512-uhmLFETqPPNyuLLbsKz6ioJ4q7AZHzD8ZVFNATNyICSZouqP2Sz0rotWQC8UNBF6VGSCs5abnKJoStA6JbCbfg=="
},
"vue-awesome-swiper": {
"version": "3.1.3",
"resolved": "http://npmprivate.quantgroups.com/vue-awesome-swiper/-/vue-awesome-swiper-3.1.3.tgz",
"integrity": "sha512-E7suzkyApO8vNZbgdEnjSmnpsmQZyRvSVXJ7sey3XYwKPOkLhH3+GnHroBw+5PZIQXvWBwdCeQsPG1xQ1r1Rhg==",
"requires": {
"object-assign": "^4.1.1",
"swiper": "^4.0.7"
}
},
"vue-class-component": {
"version": "6.3.2",
"resolved": "http://npmprivate.quantgroups.com/vue-class-component/-/vue-class-component-6.3.2.tgz",
......
......@@ -167,8 +167,12 @@ module.exports = {
},
externals: {
'vue': 'Vue',
'vue-router': 'VueRouter',
'iview': 'iview',
'vue-router': 'VueRouter'
'vuex': 'Vuex',
'axios': 'axios',
'sa-sdk-javascript': 'sensorsDataAnalytic201505',
'swiper': 'Swiper',
},
devtool:'source-map',
customize(webpackConfig){
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment