Commit 4eb6501d authored by 郭志伟's avatar 郭志伟

Merge branch 'feat/1.2.2' into 'master'

Feat/1.2.2

See merge request !22
parents d9af2c09 e9a8411b
...@@ -44,6 +44,12 @@ export default { ...@@ -44,6 +44,12 @@ export default {
accessToken: true accessToken: true
}); });
}, },
// 商品管理-商品标签列表_分页
labelPage(params) {
return http.post(`${config.opapiHost}/kdspOp/api/kdsp/activity/activity-goods/label-info/list-page`, params, {
accessToken: true
});
},
// todo: 对外接口需提供x-auth-token // todo: 对外接口需提供x-auth-token
// 购物车-添加商品 // 购物车-添加商品
addShopCart(params) { addShopCart(params) {
...@@ -57,52 +63,6 @@ export default { ...@@ -57,52 +63,6 @@ export default {
// 商品组或专题查询 // 商品组或专题查询
getGoods(params) { getGoods(params) {
return http.post(`${config.kdspHost}/api/kdsp/activity/activity-goods-special/skus`, params); return http.post(`${config.kdspHost}/api/kdsp/activity/activity-goods-special/skus`, params);
// return {
// skus: [
// {
// skuNo: '100014565800',
// skuName: '【自营】【自营】小米手机 陶瓷黑 8GB+128GB 官方标配',
// skuUrl: 'https://img14.360buyimg.com/n0/jfs/t1/141986/32/5318/98164/5f3236baE713fd239/5f2746db41f3e9c0.jpg',
// salePrice: 2.85,
// marketPrice: 293
// },
// {
// skuNo: '100014565820',
// skuName: '【自营】[自营][自营]0',
// skuUrl: 'https://img14.360buyimg.com/n0/jfs/t1/141986/32/5318/98164/5f3236baE713fd239/5f2746db41f3e9c0.jpg',
// salePrice: 264,
// marketPrice: 300
// },
// {
// skuNo: '100014565820',
// skuName: '【自营】[自营][自营]0',
// skuUrl: 'https://img14.360buyimg.com/n0/jfs/t1/141986/32/5318/98164/5f3236baE713fd239/5f2746db41f3e9c0.jpg',
// salePrice: 264,
// marketPrice: 300
// },
// {
// skuNo: '100014565800',
// skuName: '【自营】【自营】小米手机 陶瓷黑 8GB+128GB 官方标配',
// skuUrl: 'https://img14.360buyimg.com/n0/jfs/t1/141986/32/5318/98164/5f3236baE713fd239/5f2746db41f3e9c0.jpg',
// salePrice: 2.85,
// marketPrice: 293
// },
// {
// skuNo: '100014565820',
// skuName: '【自营】[自营][自营]0',
// skuUrl: 'https://img14.360buyimg.com/n0/jfs/t1/141986/32/5318/98164/5f3236baE713fd239/5f2746db41f3e9c0.jpg',
// salePrice: 264,
// marketPrice: 300
// },
// {
// skuNo: '100014565820',
// skuName: '【自营】[自营][自营]0',
// skuUrl: 'https://img14.360buyimg.com/n0/jfs/t1/141986/32/5318/98164/5f3236baE713fd239/5f2746db41f3e9c0.jpg',
// salePrice: 264,
// marketPrice: 300
// }
// ]
// };
}, },
// 根据id查询优惠券列表 // 根据id查询优惠券列表
getCoupons(params) { getCoupons(params) {
...@@ -113,78 +73,6 @@ export default { ...@@ -113,78 +73,6 @@ export default {
'x-auth-token': '7386386a-3a78-41f9-8584-14933823bf20' 'x-auth-token': '7386386a-3a78-41f9-8584-14933823bf20'
} }
}); });
// return {
// coupons: [
// {
// id: 1,
// pickupId: 1,
// name: '3C数码会场',
// startDate: '2021-02-22',
// endDate: '2021-02-22',
// faceValue: 100,
// limitAmount: 300,
// limitDesc: '满300减100',
// couponCategory: 1,
// iconUrl: 'in esse',
// description: 'officia do',
// status: 19667180,
// navUrl: 'exercitation est',
// pickupAble: false,
// publishCountFinished: false
// },
// {
// id: 2,
// pickupId: 1,
// name: '3C数码会场',
// startDate: '2021-02-22',
// endDate: '2021-02-22',
// faceValue: 100,
// limitAmount: 300,
// limitDesc: '满300减100',
// couponCategory: 1,
// iconUrl: 'oc',
// description: 'minim dolore tempor',
// status: 63205995,
// navUrl: 'cupidat',
// pickupAble: true,
// publishCountFinished: false
// },
// {
// id: 3,
// pickupId: 1,
// name: '3C数码会场',
// startDate: '2021-02-22',
// endDate: '2021-02-22',
// faceValue: 100,
// limitAmount: 300,
// limitDesc: '满300减100',
// couponCategory: 1,
// iconUrl: 'eu fugiat commodo voluptate exercitation',
// description: 'nisi',
// status: 43999314,
// navUrl: 'commodo in reprehenderit',
// pickupAble: false,
// publishCountFinished: true
// },
// {
// id: 4,
// pickupId: 1,
// name: '3C数码会场',
// startDate: '2021-02-22',
// endDate: '2021-02-22',
// faceValue: 100,
// limitAmount: 300,
// limitDesc: '满300减100',
// couponCategory: 1,
// iconUrl: 'eu fugiat commodo voluptate exercitation',
// description: 'nisi',
// status: 43999314,
// navUrl: 'commodo in reprehenderit',
// pickupAble: false,
// publishCountFinished: true
// }
// ]
// };
}, },
// 领取优惠券 // 领取优惠券
pickupCoupon(params) { pickupCoupon(params) {
......
const protocol = EASY_ENV_IS_BROWSER ? window.location.protocol : 'http'; const protocol = EASY_ENV_IS_BROWSER ? window.location.protocol : 'http';
export default { export default {
apiHost: `http://localhost:7001/`, apiHost: `http://localhost:7002/`,
// apiHost: `http://192.168.28.199:7001/`, // apiHost: `http://192.168.28.199:7001/`,
// apiHost: 'https://quantum-blocks-vcc2.liangkebang.net/', // apiHost: 'https://quantum-blocks-test1.liangkebang.net/',
h5Host: 'https://quantum-h5-vcc2.liangkebang.net', h5Host: 'https://quantum-h5-test1.liangkebang.net',
qiniuHost: `https://appsync.lkbang.net`, qiniuHost: `https://appsync.lkbang.net`,
shenceUrl: `${protocol}//bn.xyqb.com/sa?project=default`, shenceUrl: `${protocol}//bn.xyqb.com/sa?project=default`,
opapiHost: `https://opapi-vcc2.liangkebang.net`, opapiHost: `https://opapi-test1.liangkebang.net`,
qiniuUpHost: `${protocol}//up-z0.qiniup.com`, qiniuUpHost: `${protocol}//up-z0.qiniup.com`,
// kdspHost: 'https://kdsp-api-vcc2.liangkebang.net', // kdspHost: 'https://kdsp-api-test1.liangkebang.net',
kdspHost: 'https://talos-vcc2.liangkebang.net' kdspHost: 'https://talos-test1.liangkebang.net'
}; };
\ No newline at end of file
...@@ -50,7 +50,7 @@ ...@@ -50,7 +50,7 @@
goods: { goods: {
type: Object, type: Object,
default: () => ({ default: () => ({
type: 'goodsGroup', type: 'goods',
ids: [] ids: []
}) })
}, },
...@@ -87,7 +87,7 @@ ...@@ -87,7 +87,7 @@
handler: async function (newVal) { handler: async function (newVal) {
if (newVal.ids.length) { if (newVal.ids.length) {
let records = []; let records = [];
if(newVal.type === 'goodsGroup') { if(newVal.type === 'goodsSpecial') {
({ skus: records } = await operationApi.getGoods({ specialId: newVal.ids[0] })); ({ skus: records } = await operationApi.getGoods({ specialId: newVal.ids[0] }));
} else if (newVal.type === 'goods') { } else if (newVal.type === 'goods') {
({ skus: records } = await operationApi.getGoods({ skus: newVal.ids })); ({ skus: records } = await operationApi.getGoods({ skus: newVal.ids }));
...@@ -119,17 +119,20 @@ ...@@ -119,17 +119,20 @@
<style lang="less" scoped> <style lang="less" scoped>
.container { .container {
margin: 0 12px; margin: 0 12px;
.goods { .goods {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
justify-content: space-between; justify-content: space-between;
padding: 4px; padding: 4px;
font-size: 0; font-size: 0;
&-item { &-item {
border-radius: 8px; border-radius: 8px;
background: #fff; background: #fff;
margin-bottom: 4px; margin-bottom: 4px;
overflow: hidden; overflow: hidden;
&-title { &-title {
height: 36px; height: 36px;
font-size: 12px; font-size: 12px;
...@@ -140,39 +143,46 @@ ...@@ -140,39 +143,46 @@
-webkit-box-orient: vertical; -webkit-box-orient: vertical;
text-align: left; text-align: left;
} }
&-bottom { &-bottom {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
.Gi-bottom-left { .Gi-bottom-left {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
p { p {
max-width: 55px; max-width: 55px;
overflow: hidden; overflow: hidden;
white-space: nowrap; white-space: nowrap;
text-overflow: ellipsis; text-overflow: ellipsis;
text-align: left; text-align: left;
&:first-child { &:first-child {
font-size: 15px; font-size: 15px;
color: #EC3333; color: #ec3333;
} }
&:last-child { &:last-child {
font-size: 13px; font-size: 13px;
color: #999999; color: #999;
text-decoration:line-through; text-decoration: line-through;
} }
} }
} }
.Gi-bottom-right { .Gi-bottom-right {
width: 30px; width: 30px;
height: 30px; height: 30px;
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
background: #FFF3F3; background: #fff3f3;
border-radius: 50%; border-radius: 50%;
/deep/ .cr-image { /deep/ .cr-image {
width: 18px !important; width: 18px !important;
height: 18px !important; height: 18px !important;
...@@ -183,16 +193,19 @@ ...@@ -183,16 +193,19 @@
&_one { &_one {
display: flex; display: flex;
width: 100%; width: 100%;
.goods-item-img { .goods-item-img {
width: 112px !important; width: 112px !important;
height: 109px !important; height: 109px !important;
} }
&-right { &-right {
padding: 6px 8px; padding: 6px 8px;
flex: 1; flex: 1;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: space-between; justify-content: space-between;
.Gi-bottom-left { .Gi-bottom-left {
margin-right: 10px; margin-right: 10px;
flex: 1; flex: 1;
...@@ -200,6 +213,7 @@ ...@@ -200,6 +213,7 @@
justify-content: space-around; justify-content: space-around;
flex-direction: row; flex-direction: row;
align-items: flex-end; align-items: flex-end;
p { p {
max-width: 55px; max-width: 55px;
overflow: hidden; overflow: hidden;
...@@ -219,13 +233,16 @@ ...@@ -219,13 +233,16 @@
&_two { &_two {
width: 49%; width: 49%;
.goods-item-img { .goods-item-img {
width: 100% !important; width: 100% !important;
height: 180px !important; height: 180px !important;
} }
.goods-item-title { .goods-item-title {
margin: 8px 8px; margin: 8px 8px;
} }
.goods-item-bottom { .goods-item-bottom {
margin: 0 8px 6px; margin: 0 8px 6px;
} }
...@@ -233,15 +250,19 @@ ...@@ -233,15 +250,19 @@
&_three { &_three {
width: 32%; width: 32%;
.goods-item-img { .goods-item-img {
width: 100% !important; width: 100% !important;
height: 117px !important; height: 117px !important;
} }
.goods-item-title { .goods-item-title {
margin: 8px 4px; margin: 8px 4px;
} }
.goods-item-bottom { .goods-item-bottom {
margin: 0 4px 6px; margin: 0 4px 6px;
.goods-item-bottom { .goods-item-bottom {
} }
...@@ -251,7 +272,6 @@ ...@@ -251,7 +272,6 @@
&_empty { &_empty {
height: 0; height: 0;
} }
} }
} }
} }
......
...@@ -68,7 +68,7 @@ export default class DynamicForm extends Vue { ...@@ -68,7 +68,7 @@ export default class DynamicForm extends Vue {
changeStyle(type) { changeStyle(type) {
const gridEle = document.querySelector('.vue-grid-layout'); const gridEle = document.querySelector('.vue-grid-layout');
gridEle.childNodes.forEach(v => { gridEle.childNodes.forEach(v => {
if (v.classList.contains('vue-grid-item') && !v.classList.contains('vue-grid-placeholder')) { if (v.classList && v.classList.contains('vue-grid-item') && !v.classList.contains('vue-grid-placeholder')) {
if (type === 'forward') { if (type === 'forward') {
const transform = getStyle(v, 'transform'); const transform = getStyle(v, 'transform');
const transformY = transform.split('(')[1].split(')')[0].split(',')[5]; const transformY = transform.split('(')[1].split(')')[0].split(',')[5];
......
<template> <template>
<div class="color-selector"> <div class="color-selector">
<Input class="color-selector-input" v-model="color" placeholder="请输入" @input="change"></Input> <Input class="color-selector-input" v-model="color" placeholder="请输入" @input="change"></Input>
<ColorPicker placement="bottom-end" v-model="color" @on-active-change="change($event)" @on-change="change($event)" /> <ColorPicker placement="bottom-end" v-model="color" alpha @on-active-change="change($event)" @on-change="change($event)" />
</div> </div>
</template> </template>
<script> <script>
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
}, },
data() { data() {
return { return {
color: this.value, color: this.value || '',
} }
}, },
created() { created() {
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
&-input { &-input {
width: 100px !important; width: 100px !important;
flex-basis: 100px !important; flex-basis: 100px !important;
......
...@@ -19,10 +19,12 @@ ...@@ -19,10 +19,12 @@
<script> <script>
import ComponentSelect from '../ComponentSelect/index.vue'; import ComponentSelect from '../ComponentSelect/index.vue';
import Upload from '../Upload/index.vue'; import Upload from '../Upload/index.vue';
import ColorSelector from '../ColorSelector/index.vue';
export default { export default {
components: { components: {
ComponentSelect, ComponentSelect,
Upload Upload,
ColorSelector
}, },
props: { props: {
value: { value: {
...@@ -88,8 +90,17 @@ ...@@ -88,8 +90,17 @@
/deep/ .ivu-card { /deep/ .ivu-card {
margin-bottom: 16px; margin-bottom: 16px;
.ivu-form { .ivu-form {
.ivu-form-item {
display: flex;
margin-bottom: 12px;
}
.ivu-form-item-label { .ivu-form-item-label {
text-align: left; text-align: left;
width: 60px !important;
font-size: 12px;
}
.ivu-form-item-content {
flex: 1 !important;
} }
} }
......
const groupColumns = function() {
return [
{
type: 'selection',
width: 60,
hideSearch: true
},
{
title: '标签ID',
key: 'id',
formType: 'input'
},
{
title: '标签名称',
key: 'labelName',
formType: 'input'
},
{
title: '商品数量',
key: 'skuNum',
hideSearch: true
},
{
title: '品类数量',
key: 'cidNum',
hideSearch: true
},
{
title: '创建时间',
key: 'createdAt',
hideSearch: true,
}
];
};
export default groupColumns;
\ No newline at end of file
import {Component, Prop, Watch, Vue} from 'vue-property-decorator'; import {Component, Prop, Watch, Vue} from 'vue-property-decorator';
import TableModal from '../TableModal/index.vue'; import TableModal from '../TableModal/index.vue';
import goodsColumn from './columns/goods.column'; import goodsColumn from './columns/goods.column';
import goodsGroupColumn from './columns/goodsGroup.column'; import goodsSpecialColumn from './columns/goodsSpecial.column';
import goodsLabelColumn from './columns/goodsLabel.column';
import { cloneDeep } from 'lodash'; import { cloneDeep } from 'lodash';
import operationApi from '@api/operation.api'; import operationApi from '@api/operation.api';
...@@ -25,12 +26,20 @@ export default class GoodsTableModal extends Vue { ...@@ -25,12 +26,20 @@ export default class GoodsTableModal extends Vue {
query: this.query query: this.query
}, },
{ {
title: '选择商品组', title: '选择商品标签',
type: 'goodsLabel',
key: 'id',
multiple: false,
columns: goodsLabelColumn.call(this),
query: this.queryLabel
},
{
title: '选择商品专题',
type: 'goodsGroup', type: 'goodsGroup',
key: 'id', key: 'id',
multiple: false, multiple: false,
columns: goodsGroupColumn.call(this), columns: goodsSpecialColumn.call(this),
query: this.queryGroup query: this.querySpecial
} }
]; ];
...@@ -65,7 +74,7 @@ export default class GoodsTableModal extends Vue { ...@@ -65,7 +74,7 @@ export default class GoodsTableModal extends Vue {
const res = await operationApi.categoryQuery(); const res = await operationApi.categoryQuery();
return recursionData(res.level1List || []); return recursionData(res.level1List || []);
}, },
async queryGroup(data) { async querySpecial(data) {
const { records, total } = await operationApi.specialPage(data); const { records, total } = await operationApi.specialPage(data);
const selections = this.templates?.ids ? this.templates.ids : this.goods.ids; const selections = this.templates?.ids ? this.templates.ids : this.goods.ids;
console.log('query', selections, this.templates.ids); console.log('query', selections, this.templates.ids);
...@@ -75,5 +84,16 @@ export default class GoodsTableModal extends Vue { ...@@ -75,5 +84,16 @@ export default class GoodsTableModal extends Vue {
} }
}); });
return { data: records || [], total }; return { data: records || [], total };
},
async queryLabel(data) {
const { records, total } = await operationApi.labelPage(data);
const selections = this.templates?.ids ? this.templates.ids : this.goods.ids;
console.log('query', selections, this.templates.ids);
records?.forEach(record => {
if (selections.some(v => v === record.id)) {
record._checked = true;
}
});
return { data: records || [], total };
} }
} }
\ No newline at end of file
...@@ -17,16 +17,17 @@ ...@@ -17,16 +17,17 @@
@on-ok="ok" @on-ok="ok"
@on-cancel="cancel" @on-cancel="cancel"
class="table-modal-popup" class="table-modal-popup"
:class="{ 'has-menu': table.length > 1 }"
:title="editText('choose')"> :title="editText('choose')">
<div class="Tm-popup-body" v-if="modal"> <div class="Tm-popup-body" v-if="modal">
<Menu v-if="table.length > 1" width="90px" :active-name="activeName" @on-select="menuChange"> <Menu v-if="table.length > 1" width="110px" :active-name="activeName" @on-select="menuChange">
<MenuItem :name="index" :key="index" v-for="(item, index) in table"> <MenuItem :name="index" :key="index" v-for="(item, index) in table">
<span>{{item.title}}</span> <span>{{item.title}}</span>
</MenuItem> </MenuItem>
</Menu> </Menu>
<div class="Tmp-body-content"> <div class="Tmp-body-content">
<template v-for="(item, index) in table"> <template v-for="(item, index) in table">
<div v-show="activeName === index" > <div v-show="activeName === index">
<QGTable <QGTable
:ref="`qgTable${index}`" :ref="`qgTable${index}`"
:columns="item.columns" :columns="item.columns"
...@@ -48,19 +49,22 @@ ...@@ -48,19 +49,22 @@
<style lang="less" scoped> <style lang="less" scoped>
.table-modal { .table-modal {
&-card { &-card {
/deep/ .ivu-card-head{ /deep/ .ivu-card-head {
background: #f0f2f5; background: #f0f2f5;
} }
/deep/ .ivu-form { /deep/ .ivu-form {
.ivu-form-item-label { .ivu-form-item-label {
width: 100px !important; width: 100px !important;
text-align: left; text-align: left;
} }
} }
.Fl-card-title { .Fl-card-title {
text-align: right; text-align: right;
} }
} }
&-popup { &-popup {
/deep/ .tableComStyle { /deep/ .tableComStyle {
min-height: 0; min-height: 0;
...@@ -69,17 +73,38 @@ ...@@ -69,17 +73,38 @@
// overflow: scroll; // overflow: scroll;
// } // }
} }
.Tm-popup-body { .Tm-popup-body {
display: flex; display: flex;
.Tmp-body-content { .Tmp-body-content {
flex: 1; flex: 1;
} }
/deep/ .ivu-menu-item { /deep/ .ivu-menu-item {
text-align: center; text-align: center;
padding: 10px 0; padding: 10px 0;
justify-content: center; justify-content: center;
} }
} }
&.has-menu {
/deep/ .ivu-modal-body {
padding: 0;
.tableComStyle {
padding: 0;
.tableStyle {
margin-top: 0;
}
}
.tableGroupStyle {
margin-top: 1px;
}
}
}
} }
} }
</style> </style>
\ No newline at end of file
...@@ -2,7 +2,9 @@ ...@@ -2,7 +2,9 @@
<div> <div>
<div class="upload"> <div class="upload">
<div class="upload-img" v-if="img"> <div class="upload-img" v-if="img">
<img :src="img"> <img :src="img" v-if="isUrl">
<cr-icon :type="img" class="upload-img-none-icon" v-else />
<!-- <Icon type="image" size="20" class="upload-img-none-icon"></Icon> -->
<div class="upload-img-cover"> <div class="upload-img-cover">
<Icon type="ios-trash-outline" @click.native="handleRemove()"></Icon> <Icon type="ios-trash-outline" @click.native="handleRemove()"></Icon>
</div> </div>
...@@ -14,7 +16,7 @@ ...@@ -14,7 +16,7 @@
</div> </div>
</div> </div>
</div> </div>
<Input v-model="img"></Input> <Input v-model="img" @input="handleImgUrlChange"></Input>
</div> </div>
</template> </template>
<script> <script>
...@@ -35,12 +37,31 @@ ...@@ -35,12 +37,31 @@
img: this.value img: this.value
} }
}, },
computed: {
containerId() {
return `container_${this.id}`;
},
isUrl() {
return /(https|http):\/\//gi.test(this.img);
}
},
watch: {
value: {
handler(newVal) {
this.img = newVal;
},
immediate: true
}
},
methods: { methods: {
handleRemove () { handleRemove () {
this.img = ''; this.img = '';
this.$emit('input', this.img); this.$emit('input', this.img);
this.$emit('change', this.img); this.$emit('change', this.img);
}, },
handleImgUrlChange() {
this.$emit('input', this.img);
},
uploadQiniu() { uploadQiniu() {
var uploader = Qiniu.uploader({ var uploader = Qiniu.uploader({
runtimes: 'html5', // 上传模式,依次退化 runtimes: 'html5', // 上传模式,依次退化
...@@ -92,19 +113,7 @@ ...@@ -92,19 +113,7 @@
}); });
}, },
}, },
computed: {
containerId() {
return `container_${this.id}`;
}
},
watch: {
value: {
handler(newVal) {
this.img = newVal;
},
immediate: true
}
},
mounted () { mounted () {
this.uploadQiniu(); this.uploadQiniu();
} }
...@@ -132,12 +141,25 @@ ...@@ -132,12 +141,25 @@
position: relative; position: relative;
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2); box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
margin-right: 4px; margin-right: 4px;
z-index: 1;
img { img {
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
&-none-icon {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
background: #fff;
z-index: 1;
line-height: 58px;
border: 1px solid #dddee1;
}
&-cover { &-cover {
display: none; display: none;
position: absolute; position: absolute;
...@@ -146,7 +168,7 @@ ...@@ -146,7 +168,7 @@
left: 0; left: 0;
right: 0; right: 0;
background: rgba(0, 0, 0, 0.6); background: rgba(0, 0, 0, 0.6);
z-index: 3;
i { i {
margin: 0 2px; margin: 0 2px;
color: #fff; color: #fff;
......
...@@ -7,9 +7,10 @@ import ColorSelector from '../DynamicForm/component/ColorSelector/index.vue'; ...@@ -7,9 +7,10 @@ import ColorSelector from '../DynamicForm/component/ColorSelector/index.vue';
import BaseSelect from '../DynamicForm/component/BaseSelect/index.vue'; import BaseSelect from '../DynamicForm/component/BaseSelect/index.vue';
import Textarea from '../DynamicForm/component/Textarea/index.vue'; import Textarea from '../DynamicForm/component/Textarea/index.vue';
import Number from '../DynamicForm/component/Number/index.vue'; import Number from '../DynamicForm/component/Number/index.vue';
import FormList from '../DynamicForm/component/FormList/index.vue';
import { resizeDiv, getStyle } from '@/service/utils.service'; import { resizeDiv, getStyle } from '@/service/utils.service';
@Component({ components: { Upload, ColorSelector, BaseSelect, Textarea, Number }, name: 'DynamicForm' }) @Component({ components: { Upload, ColorSelector, BaseSelect, Textarea, Number, FormList }, name: 'DynamicForm' })
export default class DynamicPageForm extends Mixins(ContextMenuMixin) { export default class DynamicPageForm extends Mixins(ContextMenuMixin) {
@Getter('pageData') pageData; @Getter('pageData') pageData;
...@@ -30,11 +31,59 @@ export default class DynamicPageForm extends Mixins(ContextMenuMixin) { ...@@ -30,11 +31,59 @@ export default class DynamicPageForm extends Mixins(ContextMenuMixin) {
]; ];
propsSchame: object[] = [ propsSchame: object[] = [
{
key: 'showPageBottomTip',
name: '底部提示',
type: 'checkbox'
},
{
key: 'pageBottomTxt',
name: '提示文案',
type: 'Input'
},
{
key: 'pageBottomColor',
name: '提示颜色',
type: 'ColorSelector'
},
{ {
key: 'showBackTop', key: 'showBackTop',
name: '返回顶部', name: '返回顶部',
type: 'checkbox' type: 'checkbox'
},
{
key: 'btAttachVal',
name: '添加按钮',
desc: '添加按钮',
type: 'FormList',
formControl: [
{
key: 'name',
name: '名称',
type: 'text'
},
{
key: 'url',
name: '链接',
type: 'text'
},
{
key: 'icon',
name: '图片',
type: 'Upload'
},
{
key: 'color',
name: '文字颜色',
type: 'ColorSelector'
},
{
key: 'background',
name: '背景颜色',
type: 'ColorSelector'
} }
]
},
]; ];
@Watch('pageData', { immediate: true, deep: true }) @Watch('pageData', { immediate: true, deep: true })
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
<h3>基础属性</h3> <h3>基础属性</h3>
<template v-for="(item, index) in propsSchame"> <template v-for="(item, index) in propsSchame">
<FormItem class="Df-component-formitem" :label="item.name" > <FormItem class="Df-component-formitem" :label="item.name" >
<component :is="item.type" :options="item.options" v-model="propsForm[item.key]" /> <component :is="item.type" :options="item.options" v-model="propsForm[item.key]" :formControl="item.formControl" />
</FormItem> </FormItem>
</template> </template>
</Form> </Form>
......
<template>
<div class="Pb-container" :style="bgColor">
<span class="Pb-text" :style="style">{{ txt }}</span>
</div>
</template>
<script>
import { mapGetters } from 'vuex';
export default {
name: 'PageBottomTip',
computed: {
...mapGetters(['pageData']),
txt() {
return this.pageData.props.pageBottomTxt;
},
style() {
return {
color: this.pageData.props.pageBottomColor
};
},
// TODO 这样不太好
bgColor() {
return {
'backgroundColor': this.pageData.commonStyle.backgroundColor
};
}
}
}
</script>
<style lang="less">
.Pb {
&-container {
height: 60px;
width: 100%;
text-align: center;
display: flex;
align-items: center;
justify-content: center;
}
&-text {
font-size: 14px;
color: #333;
}
}
</style>
\ No newline at end of file
...@@ -3,8 +3,9 @@ import { Getter, Action, State, Mutation } from 'vuex-class'; ...@@ -3,8 +3,9 @@ import { Getter, Action, State, Mutation } from 'vuex-class';
import type { PageInfo, Page, GridLayout } from '@store/modules/editor/state'; import type { PageInfo, Page, GridLayout } from '@store/modules/editor/state';
import TransformStyleMixin from '@page/mixins/transformStyle.mixin'; import TransformStyleMixin from '@page/mixins/transformStyle.mixin';
import FreedomContainer from '@editor/component/FreedomContainer/index.vue'; import FreedomContainer from '@editor/component/FreedomContainer/index.vue';
import PageBottomTip from './component/PageBottomTip/index.vue';
@Component({ components: { FreedomContainer }, name: 'OperationPanel' }) @Component({ components: { FreedomContainer, PageBottomTip }, name: 'OperationPanel' })
export default class OperationPanel extends Mixins(TransformStyleMixin) { export default class OperationPanel extends Mixins(TransformStyleMixin) {
@Getter('pageData') pageData; @Getter('pageData') pageData;
@State(state => state.editor.gridLayout) gridLayout?: GridLayout; @State(state => state.editor.gridLayout) gridLayout?: GridLayout;
...@@ -14,10 +15,34 @@ export default class OperationPanel extends Mixins(TransformStyleMixin) { ...@@ -14,10 +15,34 @@ export default class OperationPanel extends Mixins(TransformStyleMixin) {
@Prop(Boolean) isDraging; @Prop(Boolean) isDraging;
@Prop(Boolean) isDragIn; @Prop(Boolean) isDragIn;
bottomInfo: object = {
x: 0,
y: 0,
w: 375,
h: 60,
i: 'page-bottom-top'
};
get layout() { get layout() {
return this.pageData.elements.map(v => v.point); return this.pageData.elements.map(v => v.point);
} }
// @Watch('layout', { deep: true })
// onLayoutChange(val) {
// const lastGridItemPoint = val[val.length - 1];
// if (lastGridItemPoint && lastGridItemPoint.w) {
// this.bottomInfo = {
// x: 0,
// y: 0,
// w: 375,
// h: 60,
// i: 'page-bottom-top'
// };
// if (lastGridItemPoint.w > this.bottomInfo.w) { this.bottomInfo.w = lastGridItemPoint.w; }
// this.bottomInfo.y = this.bottomInfo.y + lastGridItemPoint.y + lastGridItemPoint.h;
// }
// }
@Emit('update:isDragIn') @Emit('update:isDragIn')
dragenter() { dragenter() {
return true; return true;
...@@ -62,4 +87,25 @@ export default class OperationPanel extends Mixins(TransformStyleMixin) { ...@@ -62,4 +87,25 @@ export default class OperationPanel extends Mixins(TransformStyleMixin) {
toggle(val) { toggle(val) {
// //
} }
layoutUpdatedEvent() {
this.$nextTick(() => {
let layoutSorted = JSON.parse(JSON.stringify(this.layout));
layoutSorted = layoutSorted.sort((prev, cur) => {
return cur.y - prev.y;
});
const lastGridItemPoint = layoutSorted[0];
if (lastGridItemPoint && lastGridItemPoint.w) {
this.bottomInfo = {
x: 0,
y: 0,
w: 375,
h: 60,
i: 'page-bottom-top'
};
if (lastGridItemPoint.w > this.bottomInfo.w) { this.bottomInfo.w = lastGridItemPoint.w; }
this.bottomInfo.y = this.bottomInfo.y + lastGridItemPoint.y + lastGridItemPoint.h;
}
});
}
} }
\ No newline at end of file
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
:use-css-transforms="true" :use-css-transforms="true"
:style="transformStyle(pageData.commonStyle)" :style="transformStyle(pageData.commonStyle)"
@click.native.stop="toggle(false)" @click.native.stop="toggle(false)"
@layout-updated="layoutUpdatedEvent"
> >
<grid-item @click.native.stop="handleElementClick(index, null)" v-for="(item, index) in pageData.elements" <grid-item @click.native.stop="handleElementClick(index, null)" v-for="(item, index) in pageData.elements"
:x="item.point.x" :x="item.point.x"
...@@ -28,13 +29,25 @@ ...@@ -28,13 +29,25 @@
:class="{'Dcmcp-item_selected': curEleIndex === index && curChildIndex === null}"> :class="{'Dcmcp-item_selected': curEleIndex === index && curChildIndex === null}">
<component ref="container" :id="item.id" class="Dcmcp-item-com" @handleElementClick="handleElementClick" :containerIndex="index" :childItem="item" :is="item.name" :key="index" v-bind="item.props"></component> <component ref="container" :id="item.id" class="Dcmcp-item-com" @handleElementClick="handleElementClick" :containerIndex="index" :childItem="item" :is="item.name" :key="index" v-bind="item.props"></component>
</grid-item> </grid-item>
<grid-item
v-if="pageData.props.showPageBottomTip"
:x="bottomInfo.x"
:y="bottomInfo.y"
:w="bottomInfo.w"
:h="bottomInfo.h"
:i="bottomInfo.i"
:static="true"
:key="bottomInfo.i + pageData.elements.length"
>
<page-bottom-tip />
</grid-item>
</grid-layout> </grid-layout>
</div> </div>
</template> </template>
<script lang="ts" src="./index.ts"></script> <script lang="ts" src="./index.ts"></script>
<style lang="less" scoped> <style lang="less" scoped>
.border() { .border() {
&:before { &::before {
position: absolute; position: absolute;
content: ''; content: '';
border: 3px solid #2d8cf0 !important; border: 3px solid #2d8cf0 !important;
...@@ -42,9 +55,10 @@ ...@@ -42,9 +55,10 @@
height: 100%; height: 100%;
top: 0; top: 0;
left: 0; left: 0;
z-index: 1 z-index: 1;
} }
} }
.Dcm-container-panel { .Dcm-container-panel {
margin: 30px auto; margin: 30px auto;
width: 375px; width: 375px;
...@@ -52,16 +66,18 @@ ...@@ -52,16 +66,18 @@
min-height: 667px; min-height: 667px;
overflow-y: scroll; overflow-y: scroll;
background-color: rgb(244, 244, 244); background-color: rgb(244, 244, 244);
box-shadow: 2px 0px 10px rgba(0, 0, 0, 0.2); box-shadow: 2px 0 10px rgba(0, 0, 0, 0.2);
/deep/ .vue-grid-layout { /deep/ .vue-grid-layout {
min-height: 667px; min-height: 667px;
.vue-grid-item { .vue-grid-item {
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
overflow: hidden; overflow: hidden;
&:after { &::after {
position: absolute; position: absolute;
top: 0; top: 0;
left: 0; left: 0;
...@@ -74,20 +90,24 @@ ...@@ -74,20 +90,24 @@
&:hover { &:hover {
.border(); .border();
} }
.vue-resizable-handle { .vue-resizable-handle {
z-index: 10000; z-index: 10000;
} }
} }
.Dcmcp-item_selected { .Dcmcp-item_selected {
.border(); .border();
} }
} }
&_draging { &_draging {
.Dcmcp-item-com { .Dcmcp-item-com {
* { * {
pointer-events: none; pointer-events: none;
} }
} }
opacity: 0.7; opacity: 0.7;
} }
} }
......
...@@ -59,5 +59,6 @@ export default class AutoSaveMixin extends Vue { ...@@ -59,5 +59,6 @@ export default class AutoSaveMixin extends Vue {
cancel() { cancel() {
// console.log('cancel'); // console.log('cancel');
this.hasCompared = true; this.hasCompared = true;
localStorage.remove(`${this.account}-${this.pageInfo.id}`);
} }
} }
\ No newline at end of file
...@@ -37,7 +37,7 @@ export default class ContextMenuMixin extends Vue { ...@@ -37,7 +37,7 @@ export default class ContextMenuMixin extends Vue {
const elements = this.pageData.elements[this.curEleIndex]; const elements = this.pageData.elements[this.curEleIndex];
const component = document.getElementById(elements.id); const component = document.getElementById(elements.id);
const height = component ? getStyle(component, 'height') : 0; const height = component ? getStyle(component, 'height') : 0;
// console.log('adjustHeight', height); console.log('adjustHeight', height);
this.updatePageInfo({ containerIndex: this.curEleIndex, data: { ...elements, point: { ...elements.point, h: Math.ceil(+height || elements.point.h) } } }); this.updatePageInfo({ containerIndex: this.curEleIndex, data: { ...elements, point: { ...elements.point, h: Math.ceil(+height || elements.point.h) } } });
} }
} }
\ No newline at end of file
...@@ -13,6 +13,7 @@ export default class TransformStyleMixin extends Vue { ...@@ -13,6 +13,7 @@ export default class TransformStyleMixin extends Vue {
if (!styleObj) { return style; } if (!styleObj) { return style; }
for (const key of Object.keys(styleObj)) { for (const key of Object.keys(styleObj)) {
if ( typeof styleObj[key] === 'number') { if ( typeof styleObj[key] === 'number') {
if (key === 'height') { styleObj[key] = Math.ceil(styleObj[key]); }
style[key] = `${(styleObj[key] / 37.5).toFixed(2)}rem`; style[key] = `${(styleObj[key] / 37.5).toFixed(2)}rem`;
} else { } else {
style[key] = styleObj[key]?.includes('px') ? `${(+(styleObj[key].slice(0, -2)) / 37.5).toFixed(2)}rem` : styleObj[key]; style[key] = styleObj[key]?.includes('px') ? `${(+(styleObj[key].slice(0, -2)) / 37.5).toFixed(2)}rem` : styleObj[key];
......
...@@ -82,7 +82,19 @@ export const defaultState = { ...@@ -82,7 +82,19 @@ export const defaultState = {
backgroundImage: '' backgroundImage: ''
}, },
props: { props: {
showPageBottomTip: true,
pageBottomTxt: '没有更多啦~',
pageBottomColor: '#fff',
showBackTop: true, showBackTop: true,
btAttachVal: [
{
name: '购物车',
icon: 'shopping-cart-o',
url: 'xyqb://shoppingCartTab',
color: '#333',
background: '#fff'
}
],
}, },
elements: [], elements: [],
} }
......
...@@ -26,18 +26,18 @@ export default (appInfo: EggAppConfig) => { ...@@ -26,18 +26,18 @@ export default (appInfo: EggAppConfig) => {
dialect: 'mysql', dialect: 'mysql',
username: 'qa', username: 'qa',
password: 'qatest', password: 'qatest',
host: '172.17.5.9', host: '172.17.5.5',
port: 31024, port: 31548,
database: 'low_code', database: 'low_code',
};; };
exports.redis = { exports.redis = {
default: { default: {
keyPrefix: appInfo.name + ':', keyPrefix: appInfo.name + ':',
}, },
client: { client: {
port: 31565, // Redis port port: 31400, // Redis port
host: '172.17.5.13', // Redis host host: '172.17.5.17', // Redis host
password: '', password: '',
db: 0 db: 0
} }
...@@ -45,7 +45,7 @@ export default (appInfo: EggAppConfig) => { ...@@ -45,7 +45,7 @@ export default (appInfo: EggAppConfig) => {
exports.webpack = { exports.webpack = {
webpackConfigList: getWebpackConfig(), webpackConfigList: getWebpackConfig(),
browser: 'http://localhost:7001/editor/list' browser: 'http://localhost:7002/editor/list'
}; };
return exports; return exports;
......
...@@ -1491,9 +1491,9 @@ ...@@ -1491,9 +1491,9 @@
"integrity": "sha512-uOCUKu5mvX3PWee+7ZFXQSNIR1V5SN2JVE2yANmW9/wQOgpEct291gXGok8VMw0009HlTWB4JATURPwyOP2DFg==" "integrity": "sha512-uOCUKu5mvX3PWee+7ZFXQSNIR1V5SN2JVE2yANmW9/wQOgpEct291gXGok8VMw0009HlTWB4JATURPwyOP2DFg=="
}, },
"@qg/cherry-ui": { "@qg/cherry-ui": {
"version": "2.20.20", "version": "2.21.1",
"resolved": "http://npmprivate.quantgroups.com/@qg%2fcherry-ui/-/cherry-ui-2.20.20.tgz", "resolved": "http://npmprivate.quantgroups.com/@qg%2fcherry-ui/-/cherry-ui-2.21.1.tgz",
"integrity": "sha512-gTSydwNq6lhMgBvYzGMO8cfM+45JN8LNaTAvPobjyUNJ+bY6JFM4kE7ZZeRs9gUsaVRhDOY15U8SUP7GgvxouA==", "integrity": "sha512-OQ9njfH6cs6FaNqPb7W+hEe/yftpdLXyjGXo2g4IwY7o/9Z5EH6Bn6B5X6dFGOka7LSyXyWRSfZzX0upIIpDFw==",
"requires": { "requires": {
"@popperjs/core": "^2.5.4", "@popperjs/core": "^2.5.4",
"vue-lazyload": "^1.3.3", "vue-lazyload": "^1.3.3",
...@@ -1501,12 +1501,12 @@ ...@@ -1501,12 +1501,12 @@
} }
}, },
"@qg/citrus-ui": { "@qg/citrus-ui": {
"version": "0.1.14", "version": "0.2.1",
"resolved": "http://npmprivate.quantgroups.com/@qg%2fcitrus-ui/-/citrus-ui-0.1.14.tgz", "resolved": "http://npmprivate.quantgroups.com/@qg%2fcitrus-ui/-/citrus-ui-0.2.1.tgz",
"integrity": "sha512-88AJuAsBMugnMFkGA60S1quAH7UEh6iNjTqvq/hbQjV5UUSxksdAgdcF0+7ASSPb8aqek4XV2fdRrvC+YBtQxA==", "integrity": "sha512-HuN8iQ3oZujUR/v039rOHlSrg4UphQYowCYA1zdHnReldR7ZDzyFamxMz2vUR7iUmlOIlD4yBt8nEERpX+X7TQ==",
"requires": { "requires": {
"@better-scroll/core": "^2.1.1", "@better-scroll/core": "^2.1.1",
"@qg/cherry-ui": "^2.20.20", "@qg/cherry-ui": "^2.21.1",
"@qg/js-bridge": "^1.1.11", "@qg/js-bridge": "^1.1.11",
"axios": "^0.21.1", "axios": "^0.21.1",
"intersection-observer": "^0.12.0", "intersection-observer": "^0.12.0",
...@@ -20135,11 +20135,11 @@ ...@@ -20135,11 +20135,11 @@
"integrity": "sha1-8z/pz7Urv9UgqhgyO8ZdsRCht2w=" "integrity": "sha1-8z/pz7Urv9UgqhgyO8ZdsRCht2w="
}, },
"rollup": { "rollup": {
"version": "2.51.1", "version": "2.52.3",
"resolved": "http://npmprivate.quantgroups.com/rollup/-/rollup-2.51.1.tgz", "resolved": "http://npmprivate.quantgroups.com/rollup/-/rollup-2.52.3.tgz",
"integrity": "sha512-8xfDbAtBleXotb6qKEHWuo/jkn94a9dVqGc7Rwl3sqspCVlnCfbRek7ldhCARSi7h32H0xR4QThm1t9zHN+3uw==", "integrity": "sha512-QF3Sju8Kl2z0osI4unyOLyUudyhOMK6G0AeqJWgfiyigqLAlnNrfBcDWDx+f1cqn+JU2iIYVkDrgQ6/KtwEfrg==",
"requires": { "requires": {
"fsevents": "~2.3.1" "fsevents": "~2.3.2"
} }
}, },
"run-async": { "run-async": {
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
"test": "cross-env NODE_ENV=production EGG_SERVER_ENV=sit DEBUG=apollo APOLLO_CLUSTER=k8s NAMESPACE=qa2 egg-scripts start --port 80 --workers 1", "test": "cross-env NODE_ENV=production EGG_SERVER_ENV=sit DEBUG=apollo APOLLO_CLUSTER=k8s NAMESPACE=qa2 egg-scripts start --port 80 --workers 1",
"stop": "egg-scripts stop", "stop": "egg-scripts stop",
"backend": "nohup egg-scripts start --port 7001 --workers 4", "backend": "nohup egg-scripts start --port 7001 --workers 4",
"dev": "egg-bin dev -r egg-ts-helper/register", "dev": "egg-bin dev -r egg-ts-helper/register --port 7002",
"debug": "egg-bin debug -r egg-ts-helper/register", "debug": "egg-bin debug -r egg-ts-helper/register",
"apollo": "node bin/apollo.js", "apollo": "node bin/apollo.js",
"build": "easy build --devtool", "build": "easy build --devtool",
...@@ -26,8 +26,8 @@ ...@@ -26,8 +26,8 @@
"@easy-team/easywebpack-vue": "^4.0.0", "@easy-team/easywebpack-vue": "^4.0.0",
"@hubcarl/json-typescript-mapper": "^2.0.0", "@hubcarl/json-typescript-mapper": "^2.0.0",
"@qg/apollo-nodejs": "^2.1.2", "@qg/apollo-nodejs": "^2.1.2",
"@qg/cherry-ui": "2.20.20", "@qg/cherry-ui": "2.21.1",
"@qg/citrus-ui": "0.1.14", "@qg/citrus-ui": "0.2.1",
"@riophae/vue-treeselect": "^0.4.0", "@riophae/vue-treeselect": "^0.4.0",
"@types/lodash": "^4.14.117", "@types/lodash": "^4.14.117",
"@types/node": "^10.12.0", "@types/node": "^10.12.0",
......
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