管理端楼层装修增加热区功能

master
paulGao 2022-09-06 19:45:02 +08:00
parent 55aa57d812
commit f6ff0b8a12
11 changed files with 380 additions and 95 deletions

View File

@ -8,7 +8,7 @@
width: 100%;
max-width: 100%;
height: auto;
max-height: 100%;
/* max-height: 100%; */
user-select: none;
}

View File

@ -1,17 +1,65 @@
<template>
<div ref="content" class="hz-m-wrap">
<img class="hz-u-img" :src="image" />
<ul class="hz-m-area" v-add-item>
<zone
class="hz-m-item"
v-for="(zone, index) in zones"
:key="index"
:index="index"
:setting="zone"
@delItem="removeItem($event)"
@changeInfo="changeInfo($event)"
></zone>
</ul>
<div class="hotzone-box">
<div class="hotzone-item">
<div ref="content" class="hz-m-wrap">
<img class="hz-u-img" :src="image" />
<ul class="hz-m-area" v-add-item>
<zone
class="hz-m-item"
v-for="(zone, index) in zones"
:key="index"
:index="index"
:setting="zone"
:ref="`zone${index}`"
@delItem="removeItem($event)"
@changeInfo="changeInfo($event)"
></zone>
</ul>
</div>
</div>
<div>
<div class="hotzone-add-box-body">
<div
v-for="(zone, index) in zones"
:key="index"
class="hotzone-box-item-main"
>
<div class="hotzone-box-item wes-2">
<div>{{ index + 1 }}</div>
<div @click="editZone(index)">
<div class="hotzone-box-item-text">
{{ showZoneText(zone) }}
</div>
</div>
<div class="flex">
<div class="hotzone-btn" @click="editZone(index)"></div>
&nbsp;&nbsp;&nbsp;&nbsp;
<div class="hotzone-btn" @click="delZone(index)"></div>
</div>
</div>
</div>
</div>
<div class="hotzone-add-box-footer" @click="addHotzone">
<svg
viewBox="64 64 896 896"
focusable="false"
class=""
data-icon="plus"
width="1em"
height="1em"
fill="currentColor"
aria-hidden="true"
>
<path
d="M482 152h60q8 0 8 8v704q0 8-8 8h-60q-8 0-8-8V160q0-8 8-8z"
></path>
<path
d="M176 474h672q8 0 8 8v60q0 8-8 8H176q-8 0-8-8v-60q0-8 8-8z"
></path>
</svg>
<div class="hotzone-add-box-text">添加热区</div>
</div>
</div>
</div>
</template>
@ -43,6 +91,43 @@ export default {
this.zones = this.zonesInit.concat();
},
methods: {
addHotzone() {
let perInfo = {
topPer: 0.15,
leftPer: 0.4,
widthPer: 0.2,
heightPer: 0.05,
img: "",
link: "",
type: "",
title: "",
};
this.addItem(perInfo);
},
editZone(index) {
this.$refs[`zone${index}`][0].showModalFn(index);
},
delZone(index) {
this.$refs[`zone${index}`][0].delItem(index);
},
showZoneText(zone) {
switch(zone.type) {
case 'goods':
return `商品:${zone.goodsName}`;
case "category":
return `分类:${zone.name}`;
case "shops":
return `店铺:${zone.storeName}`;
case "pages":
return `文章:${zone.title}`;
case "marketing":
return `促销活动商品:${zone.goodsName}`;
case "other":
return `${zone.title}`;
default:
return '请选择跳转链接';
}
},
changeInfo(res) {
let { info, index, zoneInfo } = res;
info = { ...zoneInfo, ...info };
@ -96,6 +181,77 @@ export default {
};
</script>
<style scoped>
<style scoped lang="scss">
@import "../assets/styles/main.css";
.hotzone-box {
display: flex;
justify-content: center;
align-items: center;
height: 468px;
> div {
margin: 6px;
padding: 12px;
border-radius: 10px;
height: 100%;
}
> div:nth-of-type(1) {
// display: flex;
width: 50%;
overflow: auto;
// justify-content: center;
background: #ededed;
}
> div:nth-of-type(2) {
width: 50%;
background: #f7f7f7;
}
}
.hotzone-add-box-body {
height: 90%;
overflow-y: auto;
}
.hotzone-box-item-main {
margin-top: 10px;
margin-bottom: 20px;
}
.hotzone-box-item {
align-items: center;
display: flex;
border-bottom: 1px solid #ededed;
font-size: 12px;
justify-content: space-between;
padding: 5px 10px 0;
width: 100%;
}
.hotzone-add-box-footer {
align-items: center;
background: #fff;
border: none;
border-radius: 5px;
color: #ff5c58;
display: flex;
height: 40px;
justify-content: center;
margin-top: 10px;
cursor: pointer;
}
.hotzone-btn {
cursor: pointer;
}
.hotzone-box-item-text {
width: 200px;
cursor: pointer;
}
.hotzone-add-box-text {
font-size: 12px;
line-height: 20px;
margin: 0 0 0 4px;
}
</style>

View File

@ -50,6 +50,7 @@
<li class="hz-u-square hz-u-square-bc" data-pointer="dealBC"></li>
<li class="hz-u-square hz-u-square-br" data-pointer="dealBR"></li>
</ul>
<Modal
v-model="showModal"
title="编辑热区"
@ -58,11 +59,7 @@
:mask="false"
ok-text="保存"
@on-ok="saveZone"
@on-cancel="
() => {
showModal = false;
}
"
@on-cancel="cancelZone"
>
<div>
<div class="hz-edit-img">
@ -70,14 +67,15 @@
</div>
<Form :model="zoneForm" :label-width="80">
<FormItem label="图片链接:">
<!-- <FormItem label="图片链接:">
<Input v-model="zoneForm.img"></Input>
<Button size="small" type="primary" @click="handleSelectImg"
>选择图片</Button
>
</FormItem>
:v-model="zoneForm.type === 'goods' ? zoneForm.goodsName : zoneForm.link"
</FormItem> -->
<FormItem label="跳转链接:">
<Input v-model="zoneForm.link"></Input>
<Input type="textarea" v-if="zoneForm.type === 'other' && zoneForm.title === ''" v-model="zoneForm.link" ></Input>
<Button size="small" type="primary" @click="handleSelectLink"
>选择链接</Button
>
@ -108,6 +106,7 @@ export default {
components: {
ossManage,
},
data() {
return {
zoneTop: "",
@ -119,6 +118,7 @@ export default {
showModal: false,
picModelFlag: false,
currentIndex: 0,
currentShowIndex: -1,
zoneForm: {
img: "",
link: "",
@ -126,10 +126,8 @@ export default {
},
};
},
props: ["index", "setting"],
mounted() {
console.log(this.setting);
this.setZoneInfo(this.setting);
},
methods: {
@ -139,9 +137,10 @@ export default {
this.zoneWidth = this.getZoneStyle(val.widthPer);
this.zoneHeight = this.getZoneStyle(val.heightPer);
this.tooSmall = val.widthPer < 0.01 && val.heightPer < 0.01;
this.zoneForm.img = val.img;
this.zoneForm.link = val.link;
this.zoneForm.type = val.type;
this.zoneForm = {
...val,
...this.zoneForm,
};
},
handlehideZone(isHide = true) {
if (this.hideZone === isHide) {
@ -162,6 +161,7 @@ export default {
showModalFn(index) {
this.showModal = true;
this.currentIndex = index;
console.log(this.zoneForm);
},
//
handleSelectImg() {
@ -183,8 +183,40 @@ export default {
selectedLink(val) {
this.zoneForm.link = this.$options.filters.formatLinkType(val);
this.zoneForm.type = val.___type;
this.zoneForm.title = val.title;
switch (val.___type) {
case "goods":
this.zoneForm.id = val.id;
this.zoneForm.goodsId = val.goodsId;
this.zoneForm.goodsName = val.goodsName;
break;
case "category":
this.zoneForm.id = val.allId;
this.zoneForm.name = val.name;
break;
case "shops":
this.zoneForm.id = val.id;
this.zoneForm.storeName = val.storeName;
break;
case "pages":
this.zoneForm.id = val.id;
this.zoneForm.___path = val.___path;
this.zoneForm.title = val.title;
break;
case "marketing":
this.zoneForm.id = val.id;
this.zoneForm.goodsId = val.goodsId;
this.zoneForm.goodsName = val.goodsName;
break;
default:
break;
}
this.changeInfo(this.zoneForm);
},
saveZone() {},
cancelZone() {
this.showModal = false;
},
delZone() {
this.delItem(this.currentIndex);
},

View File

@ -4,10 +4,10 @@ export default {
bind: function (el, binding, vnode) {
const MIN_LIMIT = _.MIN_LIMIT
el.addEventListener('mousedown', handleMouseDown,{ passive: false })
el.addEventListener('mousedown', handleMouseDown, { passive: false })
function handleMouseDown (e) {
console.log('additem', e)
function handleMouseDown(e) {
// console.log('additem', e)
e && e.preventDefault()
let itemInfo = {
@ -30,10 +30,10 @@ export default {
vnode.context.addItem(setting)// 这里去添加并发送了add通知不应该发送通知
window.addEventListener('mousemove', handleChange,{ passive: false })
window.addEventListener('mouseup', handleMouseUp,{ passive: false })
window.addEventListener('mousemove', handleChange, { passive: false })
window.addEventListener('mouseup', handleMouseUp, { passive: false })
function handleChange (e) {
function handleChange(e) {
e && e.preventDefault()
let moveX = _.getPageX(e) - preX
@ -57,7 +57,7 @@ export default {
})
}
function handleMouseUp () {
function handleMouseUp() {
let perInfo = {
topPer: _.decimalPoint(itemInfo.top / container.height),
leftPer: _.decimalPoint(itemInfo.left / container.width),
@ -66,6 +66,7 @@ export default {
img: "",
link: "",
type: "",
title: ""
}
if (vnode.context.isOverRange()) {

View File

@ -1,4 +1,4 @@
import hotzone from './components/Hotzone.vue'
import hotzone from './index.vue'
hotzone.install = (Vue) => {
Vue.component(hotzone.name, hotzone)

View File

@ -0,0 +1,69 @@
<template>
<Modal
:styles="{ top: '120px' }"
width="800"
@on-cancel="clickClose"
@on-ok="clickOK"
v-model="flag"
:mask-closable="false"
title="绘制热区"
scrollable
>
<template v-if="flag">
<hotzone
ref="hotzone"
@change="changeHotzone"
:zonesInit="res.zoneInfo"
:image="res.img"
></hotzone>
</template>
</Modal>
</template>
<script>
import hotzone from "./components/Hotzone.vue";
export default {
components: {
hotzone,
},
data() {
return {
flag: false, // modal
};
},
props: ["res"],
mounted() {},
methods: {
changeHotzone(info) {
this.$emit("changeZone", info);
},
//
clickClose() {
this.$emit("closeFlag", false);
},
//
clickOK() {
this.clickClose();
},
//
open(type, mutiple) {
this.flag = true;
},
//
close() {
this.flag = false;
},
},
};
</script>
<style scoped lang="scss">
/deep/ .ivu-modal {
overflow: hidden;
height: 650px !important;
}
/deep/ .ivu-modal-body {
width: 100%;
height: 500px;
overflow: hidden;
}
</style>

View File

@ -380,7 +380,7 @@ export default {
getPromotion(res) {
if (res.result) {
this.promotionList = res.result;
this.typeOption(Object.keys(res.result)[0]).methodsed();
Object.keys(res.result)[0] && this.typeOption(Object.keys(res.result)[0]).methodsed();
}
// if (Object.keys(res.result).length) {

View File

@ -21,11 +21,31 @@ export let homeData = {};
* close:true 右侧关闭按钮
*/
export const modelData = [
{
type: "flexOne",
name: "图片",
// drawer: true,
notAdd: true,
onlyImg: true,
img: "md-image",
options: {
list: [
{
img: "https://i.loli.net/2020/12/05/8wSNWbnqujDh6HL.png",
url: "",
link: "",
size: "750*280",
model: "link"
}
]
}
},
{
type: "carousel",
name: "图片轮播",
name: "轮播",
img: "md-image",
onlyImg: true,
// onlyImg: true,
notTitle: false,
close: true,
options: {
@ -59,7 +79,7 @@ export const modelData = [
name: "左一右二",
notAdd: true,
drawer: true,
onlyImg: true,
// onlyImg: true,
view: "tpl_ad_list",
img: "md-image",
options: {
@ -116,7 +136,7 @@ export const modelData = [
name: "左二右一",
notAdd: true,
drawer: true,
onlyImg: true,
// onlyImg: true,
img: "md-image",
options: {
list: [
@ -149,7 +169,7 @@ export const modelData = [
name: "三列单行",
drawer: true,
notAdd: true,
onlyImg: true,
// onlyImg: true,
img: "md-image",
options: {
list: [
@ -177,31 +197,12 @@ export const modelData = [
]
}
},
{
type: "flexOne",
name: "一张大图",
drawer: true,
notAdd: true,
onlyImg: true,
img: "md-image",
options: {
list: [
{
img: "https://i.loli.net/2020/12/05/8wSNWbnqujDh6HL.png",
url: "",
link: "",
size: "750*280",
model: "link"
}
]
}
},
{
type: "flexTwo",
name: "两张横图",
drawer: true,
notAdd: true,
onlyImg: true,
// onlyImg: true,
img: "md-image",
options: {
list: [
@ -227,7 +228,7 @@ export const modelData = [
name: "上一下二",
drawer: true,
notAdd: true,
onlyImg: true,
// onlyImg: true,
img: "md-image",
options: {
list: [
@ -260,7 +261,7 @@ export const modelData = [
name: "上二下一",
drawer: true,
notAdd: true,
onlyImg: true,
// onlyImg: true,
img: "md-image",
options: {
list: [
@ -293,7 +294,7 @@ export const modelData = [
name: "五列单行",
drawer: true,
notAdd: true,
onlyImg: true,
// onlyImg: true,
img: "md-image",
options: {
list: [
@ -340,7 +341,7 @@ export const modelData = [
name: "四列单行",
drawer: true,
notAdd: true,
onlyImg: true,
// onlyImg: true,
img: "md-image",
options: {
list: [

View File

@ -145,7 +145,7 @@
<div>
<img class="show-image" :src="item.img" alt />
<div class="tips">
<div class="tips" v-if="!res.onlyImg">
建议尺寸
<span>{{ item.size }}</span>
</div>
@ -302,8 +302,19 @@
<!-- 填写链接 -->
<div class="decorate-view" v-if="!res.notLink">
<div class="decorate-view" v-if="res.onlyImg">
<div class="decorate-view-title">选择模式</div>
<div>
<RadioGroup v-model="item.model" type="button">
<Radio value="link" label="link">链接</Radio>
<Radio value="hotzone" label="hotzone">热区</Radio>
</RadioGroup>
</div>
</div>
<div class="decorate-view" v-if="!res.notLink">
<div class="decorate-view-title">选择链接</div>
<div
v-if="item.url && item.url.length != 0"
class="decorate-view-link"
@ -349,34 +360,31 @@
>
</span>
</div>
<div>
<RadioGroup
@on-change="clickLink(item, index, res)"
v-model="item.model"
type="button"
<Button
ghost
size="small"
type="primary"
@click="clickLink(item, index, res)"
>
{{ item.model === "hotzone" ? "绘制热区" : "选择链接" }}</Button
>
<Radio value="link" label="link">链接</Radio>
<Radio v-if="res.onlyImg" value="hotzone" label="hotzone"
>热区</Radio
>
</RadioGroup>
</div>
</div>
<!-- 链接地址-->
<div
class="decorate-view"
v-if="item.url && item.url.url && item.url.___type == 'other'"
>
<div class="decorate-view-title">外部链接</div>
<div>
<Input v-model="item.url.url" style="width: 200px" />
<!-- 链接地址-->
<div
class="decorate-view"
v-if="item.url && item.url.url && item.url.___type == 'other'"
>
<div class="decorate-view-title">外部链接</div>
<div>
<Input v-model="item.url.url" style="width: 200px" />
</div>
</div>
</div>
<p v-if="item.url && item.url.url && item.url.___type == 'other'">
(如非同域名下则在小程序与公众号中无效)
</p>
<p v-if="item.url && item.url.url && item.url.___type == 'other'">
(如非同域名下则在小程序与公众号中无效)
</p>
</div>
</div>
</div>
</div>
@ -400,6 +408,8 @@
@selectedGoodsData="selectedGoodsData"
></liliDialog>
<hotzone ref="hotzone" @changeZone="changeZone"></hotzone>
<Modal width="1200px" v-model="picModelFlag">
<ossManage @callback="callbackSelected" ref="ossManage" />
</Modal>
@ -408,10 +418,12 @@
<script>
import ossManage from "@/views/sys/oss-manage/ossManage";
import { modelData } from "./config";
import hotzone from "@/components/hotzone";
import ways from "@/components/lili-dialog/wap.js"; //
export default {
components: {
ossManage,
hotzone,
},
data() {
return {
@ -455,6 +467,9 @@ export default {
},
//
selectedLink(val) {
delete val.selected;
delete val.intro;
delete val.mobileIntro;
this.selectedLinks.url = val;
},
//
@ -498,11 +513,23 @@ export default {
},
//
clickLink(val, index, oval) {
if (val.model === "link") {
this.selectedLinks = val;
this.selectedLinks = val;
if (val.model === "hotzone") {
if (!val.zoneInfo) {
val.zoneInfo = [];
}
this.$refs.hotzone.flag = true;
this.$refs.hotzone.res = val;
} else {
this.liliDialogFlag(false);
}
},
addZone(zoneInfo) {
this.selectedLinks.zoneInfo.push(zoneInfo);
},
changeZone(zoneInfo) {
this.selectedLinks.zoneInfo = zoneInfo;
},
//base64
changeFile(item, index) {
const file = document.getElementById("files" + index).files[0];

View File

@ -153,7 +153,7 @@ export default {
//
goback() {
this.$router.push({
path: "/wapList",
path: "/decoration/wap",
});
},

View File

@ -15,7 +15,6 @@ export default {
.flex-one{
width: 100%;
display: block;
height: 110px;
overflow: hidden;
>img{
width: 100%;