商家楼层装修

This commit is contained in:
lemon橪
2022-03-03 11:26:50 +08:00
parent 403ae0a963
commit 378ac39315
110 changed files with 9853 additions and 290 deletions

View File

@@ -0,0 +1,164 @@
<template>
<div class="model-view">
<div class="model-view-content">
<div class="content">
<div class="wap-title">首页</div>
<div class="draggable">
<!-- 全屏 -->
<div class="full-shadow" v-if="type == 'full'">
<img :src="advertising[0].img" alt="" />
</div>
</div>
</div>
</div>
<div class="model-config">
<div class="decorate">
<div class="decorate-title">全屏广告</div>
<div class="decorate-list">
<div
class="decorate-item"
v-for="(item, index) in advertising"
:key="index"
>
<div class="decorate-item-title">
<div>设置</div>
</div>
<div class="decorate-item-box">
<!-- 选择照片 -->
<div class="decorate-view">
<div class="decorate-view-title">选择图片</div>
<div>
<img class="show-image" :src="item.img" alt />
<input
type="file"
class="hidden-input"
@change="changeFile(item, index)"
ref="files"
:id="'files' + index"
/>
<div class="tips">
建议尺寸
<span>{{ item.size }}</span>
</div>
</div>
<div class="selectBtn">
<Button
size="small"
@click="handleClickFile(item, index)"
ghost
type="primary"
>选择照片</Button
>
</div>
</div>
<!-- 选择连接 -->
<div class="decorate-view">
<div class="decorate-view-title">选择图片</div>
<div>
<Button
ghost
type="primary"
size="small"
@click="clickLink(item)"
>选择链接</Button
>
</div>
</div>
</div>
</div>
</div>
<!-- <Button type="primary" @click="addDecorate()" ghost>添加</Button> -->
<liliDialog ref="liliDialog" :types="linkType"></liliDialog>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
type: "full", // 是否全屏
//全屏广告
advertising: [
{
img:
"https://st-gdx.dancf.com/gaodingx/0/uxms/design/20200903-182035-5e87.png?x-oss-process=image/resize,w_932/interlace,1,image/format,webp",
size: "750*1624",
},
],
linkType: "", // 选择类型
};
},
methods: {
// 点击链接
clickLink(item) {
this.$refs.liliDialog.open('link')
},
//点击图片解析成base64
changeFile(item, index) {
const file = document.getElementById("files" + index).files[0];
if (file == void 0) return false;
const reader = new FileReader();
reader.readAsDataURL(file);
this.$nextTick((res) => {
reader.onload = (e) => {
item.img = e.target.result;
};
});
},
// 点击选择照片
handleClickFile(item, index) {
document.getElementById("files" + index).click();
},
},
};
</script>
<style scoped lang="scss">
@import "./style.scss";
@import "./decorate.scss";
.decorate-radio {
margin: 10px 0;
}
.window-shadow,
.full-shadow {
display: flex;
position: absolute;
top: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.2);
left: 0;
align-items: center;
justify-content: center;
}
.window-shadow {
> img {
width: 306px;
height: 418px;
}
}
.full-shadow {
> img {
width: 100%;
height: 100%;
}
}
.draggable {
position: relative;
}
.btn-item {
> img {
margin: 4px 0;
border-radius: 50%;
width: 30px;
height: 30px;
}
}
</style>

View File

@@ -0,0 +1,159 @@
<template>
<div class="model-view">
<div class="model-view-content">
<div class="content">
<div class="wap-title">首页</div>
<div class="draggable">
<!-- 弹窗广告 -->
<div class="window-shadow">
<img :src="advertising[0].img" alt="" />
</div>
</div>
</div>
</div>
<div class="model-config">
<div class="decorate">
<div class="decorate-title">弹窗广告</div>
<div class="decorate-list">
<div
class="decorate-item"
v-for="(item, index) in advertising"
:key="index"
>
<div class="decorate-item-title">
<div>设置</div>
</div>
<div class="decorate-item-box">
<!-- 选择照片 -->
<div class="decorate-view">
<div class="decorate-view-title">选择图片</div>
<div>
<img class="show-image" :src="item.img" alt />
<input
type="file"
class="hidden-input"
@change="changeFile(item, index)"
ref="files"
:id="'files' + index"
/>
<div class="tips">
建议尺寸
<span>{{ item.size }}</span>
</div>
</div>
<div class="selectBtn">
<Button
size="small"
@click="handleClickFile(item, index)"
ghost
type="primary"
>选择照片</Button
>
</div>
</div>
<!-- 选择连接 -->
<div class="decorate-view">
<div class="decorate-view-title">选择图片</div>
<div>
<Button
ghost
type="primary"
size="small"
@click="clickLink(item)"
>选择链接</Button
>
</div>
</div>
</div>
</div>
</div>
<liliDialog ref="liliDialog" :types="linkType"></liliDialog>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
type: "full", // 展示方式
//全屏广告
advertising: [
{
img:
"https://shopro-1253949872.file.myqcloud.com/uploads/20200704/9136ecddcddf6607184fab689207e7e3.png",
size: "612*836",
},
],
linkType: "", // 选择类型
};
},
methods: {
// 点击链接
clickLink(item) {
this.$refs.liliDialog.open('link')
},
//点击图片解析成base64
changeFile(item, index) {
const file = document.getElementById("files" + index).files[0];
if (file == void 0) return false;
const reader = new FileReader();
reader.readAsDataURL(file);
this.$nextTick((res) => {
reader.onload = (e) => {
item.img = e.target.result;
};
});
},
// 点击选择照片
handleClickFile(item, index) {
document.getElementById("files" + index).click();
},
},
};
</script>
<style scoped lang="scss">
@import "./style.scss";
@import "./decorate.scss";
.decorate-radio {
margin: 10px 0;
}
.window-shadow,
.full-shadow {
display: flex;
position: absolute;
top: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.2);
left: 0;
align-items: center;
justify-content: center;
}
.window-shadow {
> img {
width: 306px;
height: 418px;
}
}
.full-shadow {
> img {
width: 100%;
height: 100%;
}
}
.draggable {
position: relative;
}
.btn-item {
> img {
margin: 4px 0;
border-radius: 50%;
width: 30px;
height: 30px;
}
}
</style>

View File

@@ -0,0 +1,570 @@
import * as API_Other from "@/api/other";
// 获取楼层装修信息
export function initData(id) {
API_Other.getHomeData(id).then(res => {
homeData = res;
});
}
export let homeData = {};
/**
* drawer:true 广告右侧打开抽屉中显示
* ad_drawer:true 活动魔方右侧显示
* notAdd: true 没有添加按钮
* notLink: true 没有连接功能
* notImg: true 没有选择图片功能
* close:true 右侧关闭按钮
*/
export const modelData = [
{
type: "carousel",
name: "图片轮播",
img: "md-image",
notTitle: false,
close: true,
options: {
list: [
{
img: "https://i.loli.net/2020/12/05/fKH4CwImpbuD5Xj.png",
url: "",
link: "",
size: "750*350"
},
{
img: "https://i.loli.net/2020/12/05/12kleCgrSLfKoQs.png",
url: "",
link: "",
size: "750*350"
},
{
img: "https://i.loli.net/2021/05/14/ZlzcCdnpejtN9gL.png",
url: "",
link: "",
size: "750*350"
}
]
}
},
{
type: "leftOneRightTwo",
name: "左一右二",
notAdd: true,
drawer: true,
view: "tpl_ad_list",
img: "md-image",
options: {
list: [
{
img: "https://i.loli.net/2021/05/14/dtNvI5UxchXn8gz.png",
url: "",
link: "",
size: "335*335"
},
{
img: "https://i.loli.net/2021/05/14/kdB3AE9ay4c1SnN.png",
url: "",
link: "",
size: "335*177"
},
{
img: "https://i.loli.net/2021/05/14/FmDr9ksiXeEqYLU.png",
url: "",
link: "",
size: "335*177"
}
]
}
},
{
type: "title",
name: "标题栏",
img: "md-image",
notAdd: true,
notLink: true,
notImg: true,
options: {
list: [
{
title: "标题",
color: "#000000"
}
]
}
},
{
type: "leftTwoRightOne",
name: "左二右一",
notAdd: true,
drawer: true,
img: "md-image",
options: {
list: [
{
img: "https://i.loli.net/2021/05/14/kdB3AE9ay4c1SnN.png",
url: "",
link: "",
size: "335*177"
},
{
img: "https://i.loli.net/2021/05/14/FmDr9ksiXeEqYLU.png",
url: "",
link: "",
size: "335*177"
},
{
img: "https://i.loli.net/2021/05/14/dtNvI5UxchXn8gz.png",
url: "",
link: "",
size: "335*335"
}
]
}
},
{
type: "flexThree",
name: "三列单行",
drawer: true,
notAdd: true,
img: "md-image",
options: {
list: [
{
img: "https://i.loli.net/2021/05/14/dtNvI5UxchXn8gz.png",
url: "",
link: "",
size: "226*226 (1:1)"
},
{
img: "https://i.loli.net/2021/05/14/dtNvI5UxchXn8gz.png",
url: "",
link: "",
size: "226*226 (1:1)"
},
{
img: "https://i.loli.net/2021/05/14/dtNvI5UxchXn8gz.png",
url: "",
link: "",
size: "226*226 (1:1)"
}
]
}
},
{
type: "flexOne",
name: "一张大图",
drawer: true,
notAdd: true,
img: "md-image",
options: {
list: [
{
img: "https://i.loli.net/2020/12/05/8wSNWbnqujDh6HL.png",
url: "",
link: "",
size: "750*280"
}
]
}
},
{
type: "flexTwo",
name: "两张横图",
drawer: true,
notAdd: true,
img: "md-image",
options: {
list: [
{
img: "https://i.loli.net/2021/05/14/dtNvI5UxchXn8gz.png",
url: "",
link: "",
size: "335*220"
},
{
img: "https://i.loli.net/2021/05/14/dtNvI5UxchXn8gz.png",
url: "",
link: "",
size: "335*220"
}
]
}
},
{
type: "topOneBottomTwo",
name: "上一下二",
drawer: true,
notAdd: true,
img: "md-image",
options: {
list: [
{
img: "https://i.loli.net/2021/05/14/dtNvI5UxchXn8gz.png",
url: "",
link: "",
size: "710*170"
},
{
img: "https://i.loli.net/2021/05/14/dtNvI5UxchXn8gz.png",
url: "",
link: "",
size: "335*170"
},
{
img: "https://i.loli.net/2021/05/14/dtNvI5UxchXn8gz.png",
url: "",
link: "",
size: "335*170"
}
]
}
},
{
type: "topTwoBottomOne",
name: "上二下一",
drawer: true,
notAdd: true,
img: "md-image",
options: {
list: [
{
img: "https://i.loli.net/2021/05/14/dtNvI5UxchXn8gz.png",
url: "",
link: "",
size: "335*170"
},
{
img: "https://i.loli.net/2021/05/14/dtNvI5UxchXn8gz.png",
url: "",
link: "",
size: "335*170"
},
{
img: "https://i.loli.net/2021/05/14/dtNvI5UxchXn8gz.png",
url: "",
link: "",
size: "710*170"
}
]
}
},
{
type: "flexFive",
name: "五列单行",
drawer: true,
notAdd: true,
img: "md-image",
options: {
list: [
{
img: "https://picsum.photos/id/127/200/200",
url: "",
link: "",
size: "75*751:1"
},
{
img: "https://i.loli.net/2021/05/14/dtNvI5UxchXn8gz.png",
url: "",
link: "",
size: "75*751:1"
},
{
img: "https://i.loli.net/2021/05/14/dtNvI5UxchXn8gz.png",
url: "",
link: "",
size: "75*751:1"
},
{
img: "https://i.loli.net/2021/05/14/dtNvI5UxchXn8gz.png",
url: "",
link: "",
size: "75*751:1"
},
{
img: "https://i.loli.net/2021/05/14/dtNvI5UxchXn8gz.png",
url: "",
link: "",
size: "75*751:1"
}
]
}
},
{
type: "flexFour",
name: "四列单行",
drawer: true,
notAdd: true,
img: "md-image",
options: {
list: [
{
img: "https://i.loli.net/2021/05/14/dtNvI5UxchXn8gz.png",
url: "",
link: "",
size: "88*881:1"
},
{
img: "https://i.loli.net/2021/05/14/dtNvI5UxchXn8gz.png",
url: "",
link: "",
size: "88*881:1"
},
{
img: "https://i.loli.net/2021/05/14/dtNvI5UxchXn8gz.png",
url: "",
link: "",
size: "88*881:1"
},
{
img: "https://i.loli.net/2021/05/14/dtNvI5UxchXn8gz.png",
url: "",
link: "",
size: "88*881:1"
}
]
}
},
{
type: "textPicture",
name: "文字图片",
drawer: true,
notAdd: true,
img: "md-image",
options: {
list: [
{
img: "https://i.loli.net/2021/05/14/dtNvI5UxchXn8gz.png",
url: "",
link: "",
title: "文字",
size: "88*881:1"
},
{
img: "https://i.loli.net/2021/05/14/dtNvI5UxchXn8gz.png",
url: "",
link: "",
title: "文字",
size: "88*881:1"
},
{
img: "https://i.loli.net/2021/05/14/dtNvI5UxchXn8gz.png",
url: "",
link: "",
title: "文字",
size: "88*881:1"
},
{
img: "https://i.loli.net/2021/05/14/dtNvI5UxchXn8gz.png",
url: "",
link: "",
title: "文字",
size: "88*881:1"
}
]
}
},
{
type: "tpl_ad_list",
name: "广告魔方",
img: "md-image",
options: {
list: [
{
bg_img: "",
name: "",
url: ""
}
]
}
},
{
type: "menu",
name: "宫格导航",
img: "md-image",
close: true,
options: {
list: [
{
img: "https://i.loli.net/2020/12/05/SoGAv7gYybuWzED.png",
url: "",
link: "",
title: "标题",
size: "88*88 (1:1)"
},
{
img: "https://i.loli.net/2020/12/05/JXR5K3sbIeENjqH.png",
url: "",
link: "",
title: "标题",
size: "88*88 (1:1)"
},
{
img: "https://i.loli.net/2020/12/05/KlZfnCFIdEV231Y.png",
url: "",
link: "",
title: "标题",
size: "88*88 (1:1)"
},
{
img: "https://i.loli.net/2020/12/05/GfmMyN2wrUVIlci.png",
url: "",
link: "",
title: "标题",
size: "88*88 (1:1)"
},
{
img: "https://i.loli.net/2020/12/05/eznDa3iNby5FkYL.png",
url: "",
link: "",
title: "标题",
size: "88*88 (1:1)"
}
]
}
},
{
type: "search",
name: "搜索",
img: "md-image",
notAdd: true,
notLink: true,
notImg: true,
options: {
list: [
{
title: "搜索"
}
]
}
},
{
type: "goods",
name: "商品分类",
img: "md-image",
notAdd: true,
notLink: true,
notImg: true,
options: {
list: [
{
/**
* 2021/12/9
* 新增索引index判断商品归属分类
* 之前代码没有配置index也不会收到印象
* 新建的楼层将采用索引判断分类
*/
titleWay: [
{
title: "精选",
desc: "电子推荐",
___index:0,
},
{
title: "实惠",
desc: "便宜好货",
___index:1,
},
{
title: "进口",
desc: "国际自营",
___index:2,
},
{
title: "推荐",
desc: "喂奶推荐",
___index:3,
}
],
listWay: [
{
img: "https://i.loli.net/2021/05/14/KTLSrOVJmEdX12A.png",
price: "120",
title:
" 微软 (Microsoft) Xbox 无线控制器/手柄 湛蓝色 | 3.5mm耳机接口蓝牙连接 Xbox主机电脑平板通用",
type: "精选",
___index:0
},
{
img: "https://i.loli.net/2020/12/05/c9mptI5Pg8qJ6ny.png",
title:
"宏碁(acer) DP高清线1.2版 2K*4KDisplayPort公对公接线笔记本电脑显卡连接显示器视频线1.5米",
price: "190",
type: "精选",
___index:0
},
]
}
]
}
}
// TODO 第一版本隐藏暂无此功能
// {
// notAdd: true,
// notImg: true,
// type: "joinGroup",
// name: "拼团活动",
// img: "md-image",
// options: {
// list: [
// {
// title: "测试拼团"
// }
// ]
// }
// },
// {
// notAdd: true,
// notImg: true,
// type: "integral",
// name: "积分活动",
// img: "md-image",
// options: {
// list: [
// {
// title: "测试积分"
// }
// ]
// }
// },
// {
// notAdd: true,
// notImg: true,
// type: "spike",
// name: "秒杀活动",
// img: "md-image",
// options: {
// list: [
// {
// title: "测试秒杀"
// }
// ]
// }
// },
// {
// notAdd: true,
// notImg: true,
// type: "group",
// name: "团购活动",
// img: "md-image",
// options: {
// list: [
// {
// title: "测试团购"
// }
// ]
// }
// }
];

View File

@@ -0,0 +1,117 @@
/deep/ .ivu-modal-mask,.ivu-modal-wrap{
z-index: 800;
}
.decorate-view-link{
font-size: 12px;
margin: 0 4px;
color: #999;
}
.decorate-view-style {
border: 1px solid #ededed;
background: #f7f7fa;
text-align: center;
width: 100%;
padding: 30px 0 0 0;
margin-bottom: 20px;
cursor: pointer;
> .select-style {
background: #ededed;
padding: 15px 0;
font-size: 15px;
}
}
.decorate-border {
border: 1px solid #ededed;
margin: 10px 0;
padding: 0 10px;
}
.drawer {
width: 100%;
display: flex;
flex-wrap: wrap;
> .drawer-item {
cursor: pointer;
border: 1px solid #ededed;
background: #f9f0ff;
width: 170px;
margin-right: 14px;
color: #9254de;
margin-bottom: 14px;
border-radius: 0.8em;
height: 60px;
display: flex;
align-items: center;
flex-direction: column;
justify-content: center;
}
}
.hidden-input {
display: none;
}
.decorate {
padding: 0 20px;
height: calc(100vh - 120px);
overflow-y: auto;
padding-bottom: 120px;
}
.decorate-title {
height: 50px;
line-height: 50px;
font-weight: bold;
}
.decorate-list {
overflow: hidden;
}
.decorate-view {
display: flex;
margin: 20px 0;
align-items: center;
}
.decorate-item-box {
background: #fff;
padding: 10px;
border: 1px solid #ededed;
}
.decorate-item-title {
height: 40px;
display: flex;
align-items: center;
justify-content: space-between;
line-height: 40px;
padding: 0 10px;
}
.decorate-view-title {
margin-right: 10px;
}
.decorate-item {
background: #ededed;
border-top-left-radius: 0.4em;
margin-bottom: 20px;
border-top-right-radius: 0.4em;
}
.show-image {
max-width: 50px;
}
.tips {
font-size: 12px;
color: #999;
> span {
color: $theme_color;
}
}
.selectBtn {
margin-left: 10px;
}
.bing-goods-list {
display: flex;
> .bing-goods-item {
width: 50px;
height: 50px;
> img {
width: 100%;
height: 100%;
display: block;
}
}
}

View File

@@ -0,0 +1,304 @@
<template>
<div class="decorate">
<div class="decorate-title">
{{ res.name }}
<Button
style="margin-left: 20px"
size="small"
ghost
v-if="res.type == 'tpl_ad_list' || res.type == 'tpl_activity_list' || res.drawer"
type="primary"
@click="selectStyle()"
>选择风格</Button
>
</div>
<!-- 右侧显示抽屉 -->
<Drawer title="选择风格" :closable="false" width="400" v-model="styleFlag">
<div class="drawer">
<div
class="drawer-item"
@click="clickDrawer(item, index)"
v-for="(item, index) in modelData"
:key="index"
v-if="item.drawer"
>
<img src alt />
<span>{{ item.name }}</span>
</div>
</div>
</Drawer>
<!-- 卡片集合 -->
<div
class="decorate-list"
v-if="(res.type != 'tpl_ad_list' && res.type != 'tpl_activity_list') || res.drawer"
>
<div class="decorate-item" v-for="(item, index) in res.options.list" :key="index">
<div class="decorate-item-title">
<div>卡片</div>
<Icon
@click="closeDecorate(index)"
v-if="res.close"
size="20"
color="#e1251b"
type="md-close-circle"
/>
</div>
<div class="decorate-item-box">
<div
class="decorate-border"
v-if="item.titleWay"
v-for="(title_item, title_index) in item.titleWay"
:key="title_index"
>
<div class="decorate-view">
<div class="decorate-view-title">标题{{ title_index + 1 }}</div>
<div>
<Input v-model="title_item.title" />
</div>
</div>
<div class="decorate-view">
<div class="decorate-view-title">描述</div>
<div>
<Input v-model="title_item.desc" />
</div>
</div>
<div class="decorate-view">
<div class="decorate-view-title">绑定商品</div>
<div
class="decorate-view-link"
v-if="res.options.list[0].listWay.length != 0"
>
<!-- 绑定商品选择器回调已选择的商品 -->
<div
v-if="
title_item.___index == bindGoods.___index ||
title_item.title == bindGoods.type
"
v-for="(bindGoods, bindGoodsIndex) in res.options.list[0].listWay"
:key="bindGoodsIndex"
>
{{ bindGoods.title }},
</div>
</div>
<div>
<Button @click="bindGoodsId(title_item)" size="small" ghost type="primary"
>选择商品</Button
>
</div>
</div>
</div>
<!-- 选择照片 -->
<div class="decorate-view" v-if="!res.notImg">
<div class="decorate-view-title">选择照片</div>
<div>
<img class="show-image" :src="item.img" alt />
<div class="tips">
建议尺寸
<span>{{ item.size }}</span>
</div>
</div>
<div class="selectBtn">
<Button
size="small"
@click="handleClickFile(item, index)"
ghost
type="primary"
>选择照片</Button
>
</div>
</div>
<!-- 填写标题 -->
<div class="decorate-view" v-if="item.title != void 0 && !res.notTitle">
<div class="decorate-view-title">菜单标题</div>
<div>
<Input v-model="item.title" style="width: 200px" />
</div>
</div>
<!-- 填写链接 -->
<div class="decorate-view" v-if="!res.notLink">
<div class="decorate-view-title">选择链接</div>
<div v-if="item.url.length != 0" class="decorate-view-link">
已选链接:
<span>
{{
ways.find((e) => {
return item.url.___type == e.name;
}).title
}}
-
<!-- 当选择完链接之后的商品名称 -->
<span v-if="item.url.___type == 'goods'"> {{ item.url.goodsName }}</span>
<!-- 当选择完链接之后的分类回调 -->
<span v-if="item.url.___type == 'category'"> {{ item.url.name }}</span>
<!-- 当选择完链接之后的店铺回调 -->
<span v-if="item.url.___type == 'shops'"> {{ item.url.memberName }}</span>
<!-- 当选择完链接之后的其他回调 -->
<span v-if="item.url.___type == 'other'"> {{ item.url.title }}</span>
<!-- 当选择完活动之后的其他回调 -->
<span v-if="item.url.___type == 'marketing'">
<span v-if="item.url.___promotion == 'SECKILL'"> 秒杀 </span>
<span v-if="item.url.___promotion == 'FULL_DISCOUNT'"> 满减 </span>
<span v-if="item.url.___promotion == 'PINTUAN'"> 拼团 </span>
{{ item.url.title || item.url.goodsName }}
</span>
<!-- 当选择完活动之后的其他回调 -->
<span v-if="item.url.___type == 'pages'"> {{ item.url.title }}</span>
</span>
</div>
<div>
<Button ghost size="small" type="primary" @click="clickLink(item, index)"
>选择链接</Button
>
</div>
</div>
</div>
</div>
</div>
<Button
v-if="res.type != 'tpl_ad_list' && res.type != 'tpl_activity_list' && !res.notAdd"
type="primary"
@click="addDecorate()"
ghost
>添加</Button
>
<liliDialog
ref="liliDialog"
@selectedLink="selectedLink"
@selectedGoodsData="selectedGoodsData"
></liliDialog>
<Modal width="1200px" v-model="picModelFlag">
<ossManage @callback="callbackSelected" ref="ossManage" />
</Modal>
</div>
</template>
<script>
import ossManage from "@/views/sys/oss-manage/ossManage";
import { modelData } from "./config";
import ways from "@/views/lili-dialog/wap.js"; // 选择链接的类型
export default {
components: {
ossManage,
},
data() {
return {
ways, // 选择链接的类型
picModelFlag: false, //图片选择器
linkType: "goods", // dialog弹窗口类型
styleFlag: false, //广告魔方开关
selectedLinkIndex: "", //选择链接的索引
modelData, // 装修数据
selectedGoods: "", // 已选商品
selectedLinks: "", // 已选链接
modelList: "", // 装修列表
};
},
watch: {
res: {
handler: (val) => {},
deep: true,
},
},
props: ["res"],
methods: {
// 选择风格
selectStyle() {
this.styleFlag = !this.styleFlag;
},
// 回调选择的链接
selectedLink(val) {
this.selectedLinks.url = val;
},
// 回调的商品信息
selectedGoodsData(val) {
if (!val) return false;
let data = val.map((item) => {
delete item.selected;
delete item.intro;
delete item.mobileIntro;
return {
img: item.thumbnail,
title: item.goodsName,
type: this.selectedGoods.title,
___index: this.selectedGoods.___index,
...item,
};
});
this.res.options.list[0].listWay.push(...data);
this.linkType = "";
},
// 绑定商品
bindGoodsId(val) {
this.selectedGoods = val;
this.liliDialogFlag(true);
},
// 点击抽屉
clickDrawer(item, index) {
this.$emit("handleDrawer", item);
this.styleFlag = false;
},
// 打开图片选择器
liliDialogFlag(flag) {
this.$refs.liliDialog.goodsFlag = flag;
this.$refs.liliDialog.flag = true;
},
// 点击链接赋值一个唯一值,并将当前选择的模块赋值
clickLink(val, index) {
this.selectedLinks = val;
this.liliDialogFlag(false);
},
//点击图片解析成base64
changeFile(item, index) {
const file = document.getElementById("files" + index).files[0];
if (file == void 0) return false;
const reader = new FileReader();
reader.readAsDataURL(file);
this.$nextTick((res) => {
reader.onload = (e) => {
item.img = e.target.result;
};
});
},
//添加设置
addDecorate() {
let way = {
img: "https://picsum.photos/id/264/200/200",
title: "标题",
link: "",
url: "",
size: this.res.options.list[0]?.size,
};
this.res.options.list.push(way);
},
// 图片选择器回显
callbackSelected(val) {
this.picModelFlag = false;
this.selectedGoods.img = val.url;
},
// 点击选择图片
handleClickFile(item, index) {
// this.$refs.ossManage.selectImage = true;
this.selectedGoods = item;
this.picModelFlag = true;
},
// 关闭
closeDecorate(index) {
this.$nextTick(() => {
this.res.options.list.splice(index, 1);
});
},
},
};
</script>
<style scoped lang="scss">
@import "./decorate.scss";
</style>

View File

@@ -0,0 +1,17 @@
import index from './index.vue' //首页
import advertising from './advertising.vue' //全屏活动
import alertAdvertising from './alertAdvertising.vue' //弹窗活动
const templates = {
index,
advertising,
alertAdvertising
}
export default templates

View File

@@ -0,0 +1,213 @@
<template>
<div class="wrapper">
<!-- 拖拽栏 展示栏 -->
<div class="model-view">
<div class="model-view-menu">
<draggable
class="model-view-menu-item"
:list="modelData"
:move="handleMove"
v-bind="{
group: { name: 'model', pull: 'clone', put: false, animation: 150 },
sort: false,
ghostClass: 'ghost',
}"
>
<li
v-for="(model, index) in modelData"
v-if="!model.drawer"
:key="index"
class="model-item"
>
<img src alt />
<span>{{ model.name }}</span>
</li>
</draggable>
</div>
<div class="model-view-content">
<div class="content">
<div class="wap-title">首页</div>
<draggable
class="draggable"
group="model"
ghostClass="ghost"
@add="handleContentlAdd"
@end="handleContentlEnd"
v-model="contentData.list"
>
<div
class="list"
v-for="(element, index) in contentData.list"
:key="element.key"
>
<component
class="component"
:class="{ active: selected == index }"
@click.native="handleComponent(element, index)"
:is="templates[element.type]"
:res="element.options"
></component>
<Icon
v-if="selected == index"
@click="closeComponent(index)"
color="#e1251b"
size="25"
class="close"
type="ios-close-circle"
/>
</div>
</draggable>
</div>
</div>
<!-- 右侧栏 -->
<div class="model-config">
<decorate
@handleDrawer="handleDrawer"
v-if="decorateData"
:res="decorateData"
></decorate>
</div>
</div>
</div>
</template>
<script>
import templates from "./template/index";
import Draggable from "vuedraggable";
import { modelData } from "./config";
import decorate from "./decorate";
import * as API_Other from '@/api/other'
export default {
components: {
Draggable,
decorate,
},
data() {
return {
templates, // 模板类型
modelData, // 装修模型
qrcode: "", // 二维码
selected: 0, // 已选下标
contentData: { // 总数据
list: [],
},
decorateData: "", // 装修数据
};
},
watch: {
contentData: {
handler(val) {
this.$store.state.styleStore = val;
},
deep: true,
},
},
mounted() {
this.init();
},
methods: {
enableBindGoodsShow(){
},
// 初始化数据
init() {
if (!this.$route.query.id) return false;
API_Other.getHomeData(this.$route.query.id).then(res=>{
this.contentData = JSON.parse(res.result.pageData)
this.handleComponent( this.contentData.list[0], 0)
})
},
// 中间组件拖动,右侧数据绑定不变
handleContentlEnd(evt) {
const { newIndex } = evt;
this.handleComponent(this.contentData.list[newIndex], newIndex);
},
// 关闭楼层装修
closeComponent(index) {
this.$nextTick(() => {
this.decorateData = "";
console.log(this.contentData.list.length);
// 如果当前楼层不为一
if (this.contentData.list.length > 1) {
// 如果当前最底层 给下一层赋值
if (index - 1 == -1) {
this.handleComponent(this.contentData.list[index], index);
} else {
// 如果不是最底层给上一层赋值
this.handleComponent(this.contentData.list[index - 1], index - 1);
}
this.contentData.list.splice(index, 1);
} else {
this.contentData.list.splice(index, 1);
}
});
},
// 点击楼层装修
handleComponent(val, index) {
console.warn(val)
this.selected = index;
this.$set(this, "decorateData", val);
},
// 右侧栏回调
handleDrawer(val) {
let newIndex = this.selected;
this.decorateData = "";
this.$set(this.contentData.list, newIndex, {
...val,
options: {
...val.options,
},
// 绑定键值
model: val.type,
});
this.contentData.list = JSON.parse(JSON.stringify(this.contentData.list));
this.$set(this, "decorateData", this.contentData.list[newIndex]);
},
// 封装拖拽参数
package(val, newIndex) {
this.contentData.list[newIndex] = "";
val = JSON.parse(JSON.stringify(val));
this.$set(this.contentData.list, newIndex, {
...val,
options: {
...val.options,
},
// 绑定键值
model: val.type,
});
},
// 拖动
handleContentlAdd(evt) {
const { newIndex } = evt;
this.package(this.contentData.list[newIndex], newIndex);
this.handleComponent(this.contentData.list[newIndex], newIndex);
},
handleMove() {
return true;
},
},
};
</script>
<style scoped lang="scss">
@import "./style.scss";
</style>

View File

@@ -0,0 +1,39 @@
<template>
<div class="box">
<!-- 顶部栏 -->
<navbar @selected="selected" />
<component :is="layout[name]"></component>
</div>
</template>
<script>
import layout from "./index";
import navbar from "./navbar";
export default {
components: {
navbar,
},
data() {
return {
layout, // 装修模块
name: "index", // 装修的页面
};
},
methods: {
selected(val) { // 顶部栏点击切换
this.name = val;
}
}
};
</script>
<style scoped lang="scss">
.box {
height: calc(100vh - 120px);
width: 98%;
margin: 0 auto;
padding: 0 20px;
background: #fff;
border-radius: 0.4em;
overflow: hidden;
}
</style>

View File

@@ -0,0 +1,214 @@
<template>
<!-- 预览保存 -->
<div class="model-title">
<div>店铺装修</div>
<div class="btns">
<Button
@click="clickBtn(item)"
size="small"
v-for="(item, index) in way"
:key="index"
:type="item.selected ? 'primary' : ''"
>
{{ item.title }}
</Button>
</div>
<div class="model-title-view-btn">
<!-- TODO 后期会补全 目前版本暂无 -->
<!-- <Poptip placement="bottom" width="100">
<Button size="default" @click="creatQrCode">预览模板</Button>
<div slot="content" class="default-view-content">
<div>临时预览</div>
<div ref="qrCodeUrl"></div>
</div>
</Poptip> -->
<Button size="default" type="primary" @click="handleSpinShow">保存模板</Button>
<Modal
title="保存中"
v-model="saveDialog"
:closable="true"
:mask-closable="false"
:footer-hide="true"
>
<div v-if="progress">
<div class="model-item">
模板名称 <Input style="width: 200px" v-model="submitWay.name" />
</div>
<div class="model-item">
是否立即发布
<i-switch v-model="submitWay.pageShow">
<span slot="open"></span>
<span slot="close"></span>
</i-switch>
</div>
<Button type="primary" @click="save()">保存</Button>
</div>
<Progress v-else :percent="num" status="active" />
</Modal>
</div>
</div>
</template>
<script>
import * as API_Other from "@/api/other.js";
export default {
data() {
return {
progress: true, // 展示进度
num: 20, // 提交进度
saveDialog: false, // 加载状态
way: [
// 装修tab栏切换
{
title: "首页",
name: "index",
selected: true,
},
// {
// title: "全屏广告",
// name: "advertising",
// selected: false,
// },
// {
// title: "弹窗广告",
// name: "alertAdvertising",
// selected: false,
// },
],
submitWay: {
// 表单信息
pageShow: this.$route.query.type || false,
name: this.$route.query.name || "模板名称",
pageClientType: "H5",
},
};
},
watch: {},
mounted() {},
methods: {
clickBtn(val) {
this.way.forEach((item, index) => {
item.selected = false;
});
val.selected = true;
this.$emit("selected", val.name);
},
/**
* 加载,并保存模板
*/
handleSpinShow() {
this.saveDialog = true;
},
// 填写是否发布,模板名称之后保存
save() {
if (this.$store.state.styleStore == void 0) {
this.$Message.error("请装修楼层");
return false;
}
this.submitWay?.pageShow === true
? (this.submitWay.pageShow = "OPEN")
: (this.submitWay.pageShow = "CLOSE");
this.submitWay.pageData = JSON.stringify(this.$store.state.styleStore);
this.submitWay.pageType = "INDEX";
this.$route.query.id ? this.update() : this.submit(this.submitWay);
},
// 更新
update() {
this.progress = false;
API_Other.updateHome(this.$route.query.id, {
pageData: JSON.stringify(this.$store.state.styleStore),
name: this.submitWay.name,
pageShow: this.submitWay.pageShow,
pageType: "INDEX",
pageClientType: "H5",
})
.then((res) => {
this.num = 50;
if (res.success) {
this.num = 80;
/**制作保存成功动画¸ */
setTimeout(() => {
this.saveDialog = false;
this.$Message.success("修改成功");
this.goback();
}, 1000);
} else {
this.saveDialog = false;
this.$Message.error("修改失败,请稍后重试");
}
console.log(res);
})
.catch((error) => {});
},
// 返回查询数据页面
goback() {
this.$router.push({
path: "/shop/wapList",
});
},
// 保存
submit(submitWay) {
this.progress = false;
API_Other.setHomeSetup(submitWay)
.then((res) => {
this.num = 50;
if (res.success) {
this.num = 80;
/**制作保存成功动画¸ */
setTimeout(() => {
this.saveDialog = false;
this.$Message.success("保存成功");
this.goback();
}, 1000);
} else {
this.progress = true;
this.saveDialog = false;
this.$Message.error("保存失败,请稍后重试");
}
console.log(res);
})
.catch((error) => {});
},
},
};
</script>
<style scoped lang="scss">
.model-item {
width: 100%;
padding: 10px 0;
display: flex;
align-items: center;
> * {
margin: 0 8px;
}
}
.model-title {
height: 70px;
display: flex;
justify-content: space-between;
align-items: center;
color: #333;
font-size: 14px;
> .model-title-view-btn {
> * {
margin: 0 10px;
}
}
}
.btns {
* {
margin: 0 4px;
}
}
</style>

View File

@@ -0,0 +1,98 @@
.model-view {
display: flex;
.model-view-menu {
flex: 1.5;
min-width: 250px;
> .model-view-menu-item {
display: flex;
align-items: center;
flex-wrap: wrap;
}
}
.model-config {
flex: 2.5;
}
.model-view-content {
flex: 6;
}
.model-item {
line-height: 1.75;
font-size: 13px;
margin: 0 5px 10px 5px;
border: 1px solid #ededed;
background: #f6f6f9;
width: 70px;
height: 70px;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
}
.model-view-content {
background: #f6f6f9;
border-radius: 0.8em;
display: flex;
justify-content: flex-start;
align-items: center;
flex-direction: column;
}
.wap-title {
line-height: 44px;
text-align: center;
height: 44px;
border-bottom: 1px solid #ededed;
}
.content {
margin: 20px 0;
padding: 50px 13px;
width: 360px;
background: url("../../../assets/iPhoneX_model.png") no-repeat;
height: 780px;
background-size: 360px;
overflow: hidden;
> .component,
.draggable {
height: 590px;
overflow-y: auto;
background: #ebebeb;
}
> .draggable {
padding-bottom: 100px;
}
}
.list {
position: relative;
}
.close {
position: absolute;
right: 5px;
top: 10px;
z-index: 99;
}
.model-btn {
> * {
margin: 0 4px;
}
}
.qrCode {
width: 100px;
height: 100px;
}
.default-view-content {
text-align: center;
font-weight: bold;
line-height: 2;
/deep/ img {
margin: 0 auto;
}
}
.model-config {
overflow-y: auto;
}
.active {
box-sizing: border-box;
border: 1px solid $theme_color;
}

View File

@@ -0,0 +1,57 @@
.position-box{
position: absolute;
right: 0;
bottom: 0;
}
.join-box {
display: flex;
}
.item-price {
> span {
font-size: 15px;
font-weight: 500;
color: #e1212b;
}
}
.join-item {
flex: 1;
}
.item-img {
width: 75px;
height: 75px;
margin: 0 auto;
display: block;
}
.item-img-box {
position: relative;
}
.item-line-through {
> span {
font-size: 10px;
font-weight: 400;
text-decoration: line-through;
color: #999;
}
}
.item-position-tips {
position: absolute;
right: 0;
color: #fff;
font-size: 12px;
bottom: 0;
}
.join-title {
display: flex;
justify-content: space-between;
align-items: center;
background: #fff;
height: 50px;
> div:nth-of-type(1) {
font-size: 16px;
font-weight: bold;
}
> div:nth-of-type(2) {
font-size: 12px;
color: #999;
}
}

View File

@@ -0,0 +1,44 @@
import tpl_banner from "./tpl_banner";
import tpl_title from "./tpl_title";
import tpl_left_one_right_two from "./tpl_left_one_right_two";
import tpl_left_two_right_one from "./tpl_left_two_right_one";
import tpl_top_one_bottom_two from "./tpl_top_one_bottom_two";
import tpl_top_two_bottom_one from "./tpl_top_two_bottom_one";
import tpl_flex_one from "./tpl_flex_one";
import tpl_flex_two from "./tpl_flex_two";
import tpl_flex_three from "./tpl_flex_three";
import tpl_flex_five from "./tpl_flex_five";
import tpl_flex_four from "./tpl_flex_four";
import tpl_text_picture from "./tpl_text_picture";
import tpl_menu from "./tpl_menu";
import tpl_search from "./tpl_search";
import tpl_join_group from "./tpl_join_group";
import tpl_integral from "./tpl_integral";
import tpl_spike from "./tpl_spike";
import tpl_group from "./tpl_group";
import tpl_ad_list from "./tpl_view_list";
import tpl_activity_list from './tpl_view_list'
import tpl_goods from "./tpl_goods";
export default {
carousel: tpl_banner,
title: tpl_title,
leftOneRightTwo: tpl_left_one_right_two,
leftTwoRightOne: tpl_left_two_right_one,
topOneBottomTwo:tpl_top_one_bottom_two,
topTwoBottomOne:tpl_top_two_bottom_one,
flexThree: tpl_flex_three,
flexFive: tpl_flex_five,
flexFour: tpl_flex_four,
flexTwo: tpl_flex_two,
textPicture: tpl_text_picture,
menu: tpl_menu,
search: tpl_search,
joinGroup: tpl_join_group,
flexOne: tpl_flex_one,
goods: tpl_goods,
integral:tpl_integral,
spike:tpl_spike,
group:tpl_group,
tpl_ad_list,
tpl_activity_list
};

View File

@@ -0,0 +1,31 @@
.image-mode {
width: 100%;
height: 100%;
display: block;
padding: 1px;
}
.layout {
padding: 8px;
margin: 4px 0;
background: #fff;
}
.layout,
.view-height-75,
.view-height-150 {
overflow: hidden;
}
.view-width-100{
width: 100%;
}
.view-height-75 {
height: 75px;
}
.view-height-150 {
height: 150px;
flex: 1;
}
.view-height-85 {
height: 85px;
flex: 1;
}

View File

@@ -0,0 +1,32 @@
<template>
<div class="layout">
<Carousel class="carousel" v-if="res" autoplay :autoplay-speed="5000">
<CarouselItem v-for="(item, index) in res.list" :key="index">
<div>
<img class="image-mode" :src="item.img" />
</div>
</CarouselItem>
</Carousel>
</div>
</template>
<script>
export default {
title: "导航栏",
props: ["res"],
watch: {
res: {
handler(newValue, oldValue) {
this.$set(this,'res',newValue);
},
deep: true
}
}
};
</script>
<style lang="scss" scoped>
@import "./tpl.scss";
.carousel,
.image-mode {
height: 150px;
}
</style>

View File

@@ -0,0 +1,30 @@
<template>
<div class="layout">
<img class="image-mode" :src="res.list[0].img" alt="">
<img class="image-mode" :src="res.list[1].img" alt="">
<img class="image-mode" :src="res.list[2].img" alt="">
<img class="image-mode" :src="res.list[3].img" alt="">
<img class="image-mode" :src="res.list[4].img" alt="">
</div>
</template>
<script>
export default {
title: "五列单行图片模块",
props: ["res"],
};
</script>
<style lang="scss" scoped>
@import "./tpl.scss";
.layout {
background: #e8e8e8;
display: flex;
align-items: center;
justify-content: center;
background-size: cover;
}
img {
width: 67px !important;
}
</style>

View File

@@ -0,0 +1,33 @@
<template>
<div class="layout">
<img class="image-mode" :src="res.list[0].img" alt="">
<img class="image-mode" :src="res.list[1].img" alt="">
<img class="image-mode" :src="res.list[2].img" alt="">
<img class="image-mode" :src="res.list[3].img" alt="">
</div>
</template>
<script>
export default {
title: "四列单行图片模块",
props: ["res"],
};
</script>
<style lang="scss" scoped>
@import "./tpl.scss";
.layout {
// background: #e8e8e8;
// height: 84px;
display: flex;
padding: 0 8px;
align-items: center;
justify-content: center;
background-size: cover;
}
img{
width: 84px !important;
}
</style>

View File

@@ -0,0 +1,25 @@
<template>
<div class="layout">
<div class="flex-one">
<img :src="res.list[0].img" alt="">
</div>
</div>
</template>
<script>
export default {
props: ['res']
}
</script>
<style lang="scss" scoped>
@import './tpl.scss';
.flex-one{
width: 100%;
display: block;
height: 110px;
overflow: hidden;
>img{
width: 100%;
height: 100%;
}
}
</style>

View File

@@ -0,0 +1,29 @@
<template>
<div class="layout">
<img class="image-mode" :src="res.list[0].img" alt="">
<img class="image-mode" :src="res.list[1].img" alt="">
<img class="image-mode" :src="res.list[2].img" alt="">
</div>
</template>
<script>
export default {
title: "三列单行图片模块",
props: ["res"],
};
</script>
<style lang="scss" scoped>
@import "./tpl.scss";
.layout {
background: #e8e8e8;
height: 110px;
display: flex;
align-items: center;
justify-content: center;
background-size: cover;
}
img{
width: 111px !important;
}
</style>

View File

@@ -0,0 +1,35 @@
<template>
<div class="layout">
<div class="flex-two">
<div class="flex-item">
<img :src="res.list[0].img" alt />
</div>
<div class="flex-item">
<img :src="res.list[1].img" alt />
</div>
</div>
</div>
</template>
<script>
export default {
title: "两张横图",
props: ["res"],
};
</script>
<style lang="scss" scoped>
@import "./tpl.scss";
.flex-two {
width: 100%;
display: flex;
height: 110px;
overflow: hidden;
}
.flex-item {
width: 50%;
> img {
display: block;
max-width: 100%;
height: 100%;
}
}
</style>

View File

@@ -0,0 +1,170 @@
<template>
<div class="layout">
<div class="goods-cell-title">
<div
class="goods-item-title"
:class="{ selected: selected.index == index }"
@click="handleClickTitle(title, index)"
v-for="(title, index) in res.list[0].titleWay"
:key="index"
>
<h4>{{ title.title }}</h4>
<div>{{ title.desc }}</div>
</div>
</div>
<div class="goods-list">
<div
v-if="
item.___index != undefined
? selected.index == item.___index
: selected.val == item.type
"
class="goods-item"
v-for="(item, item_index) in res.list[0].listWay"
:key="item_index"
>
<div class="goods-img">
<Icon
size="20"
color="#e1251b"
@click="closeGoods(item, item_index)"
class="goods-icon"
type="ios-close-circle"
/>
<img :src="item.img" alt />
</div>
<div class="goods-desc">
<div class="goods-title">
{{ item.title }}
</div>
<div class="goods-bottom">
<div class="goods-price">¥{{ item.price | unitPrice }}</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
selected: {
// 已选数据
index: 0,
},
};
},
props: ["res"],
watch: {
res: {
handler(val) {
// 监听父级的值 如果有值将值赋给selected
if (val) {
this.selected.val = this.res.list[0].listWay[0].type;
}
},
immediate: true,
},
},
methods: {
// 删除商品
closeGoods(val, index) {
this.res.list[0].listWay.splice(index, 1);
},
// 切换商品列表
handleClickTitle(val, index) {
this.selected.index = index;
this.selected.val = val.title;
},
},
};
</script>
<style lang="scss" scoped>
.layout {
padding: 8px 0;
background: #e8e8e8;
}
.selected {
> h4 {
color: #000 !important;
}
> div {
font-weight: bold;
color: $theme_color !important;
}
}
.goods-cell-title {
padding: 10px;
transition: 0.35s;
display: flex;
cursor: pointer;
> .goods-item-title {
flex: 1;
text-align: center;
> h4 {
font-size: 16px;
color: #666;
}
> div {
color: #999;
font-size: 12px;
}
}
}
.goods-list {
width: 100%;
display: flex;
flex-wrap: wrap;
}
.goods-item {
width: 50%;
margin-bottom: 10px;
border-radius: 0.4em;
overflow: hidden;
}
.goods-img {
position: relative;
margin: 0 auto;
width: 158px;
height: 150px;
border-top-left-radius: 0.4em;
border-top-right-radius: 0.4em;
overflow: hidden;
> img {
width: 100%;
height: 100%;
}
}
.goods-desc {
border-bottom-left-radius: 0.4em;
border-bottom-right-radius: 0.4em;
width: 158px;
background: #fff;
padding: 4px;
margin: 0 auto;
> .goods-title {
font-size: 12px;
height: 38px;
display: -webkit-box;
font-weight: 500;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
}
> .goods-bottom {
display: flex;
> .goods-price {
line-height: 2;
color: $theme_color;
}
}
}
.goods-icon {
right: 5px;
top: 5px;
position: absolute;
}
</style>

View File

@@ -0,0 +1,39 @@
<template>
<div class="layout">
<div class="join-list">
<div class="join-title">
<div>{{ res.list[0].title }}</div>
<div>更多</div>
</div>
<div class="join-box">
<div class="join-item" v-for="item in 4" :key="item">
<div class="item-img-box">
<img
class="item-img"
src="https://picsum.photos/id/268/200/200"
alt
/>
</div>
<div class="item-price">
<span>120.00</span>
</div>
<div class="item-line-through">
<span>190.00</span>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
props: ["res"]
};
</script>
<style lang="scss" scoped>
@import "./tpl.scss";
@import './advertising.scss';
</style>

View File

@@ -0,0 +1,89 @@
<template>
<div class="layout">
<div class="join-list">
<div class="join-title">
<div>{{ res.list[0].title }}</div>
<div>更多</div>
</div>
<div class="join-box">
<div class="join-item" v-for="item in 4" :key="item">
<div class="item-img-box">
<img
class="item-img"
src="https://picsum.photos/id/268/200/200"
alt
/>
</div>
<div class="item-price">
<span>20积分</span>
</div>
<div class="item-line-through">
<span>30积分</span>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
props: ["res"]
};
</script>
<style lang="scss" scoped>
@import "./tpl.scss";
.join-box {
display: flex;
}
.item-price {
> span {
font-size: 15px;
font-weight: 500;
color: #e1212b;
}
}
.join-item {
flex: 1;
}
.item-img {
width: 75px;
height: 75px;
margin: 0 auto;
display: block;
}
.item-img-box {
position: relative;
}
.item-line-through {
> span {
font-size: 10px;
font-weight: 400;
text-decoration: line-through;
color: #999;
}
}
.item-position-tips {
position: absolute;
right: 0;
color: #fff;
font-size: 12px;
bottom: 0;
}
.join-title {
display: flex;
justify-content: space-between;
align-items: center;
background: #fff;
height: 50px;
> div:nth-of-type(1) {
font-size: 16px;
font-weight: bold;
}
> div:nth-of-type(2) {
font-size: 12px;
color: #999;
}
}
</style>

View File

@@ -0,0 +1,89 @@
<template>
<div class="layout">
<div class="join-list">
<div class="join-title">
<div>{{ res.list[0].title }}</div>
<div>更多</div>
</div>
<div class="join-box">
<div class="join-item" v-for="item in 4" :key="item">
<div class="item-img-box">
<img
class="item-img"
src="https://picsum.photos/id/268/200/200"
alt
/>
<div class="item-position-tips">2人团</div>
</div>
<div class="item-price">
<span>120.00</span>
</div>
<div class="item-line-through">
<span>120.00</span>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
props: ["res"]
};
</script>
<style lang="scss" scoped>
@import "./tpl.scss";
.join-box {
display: flex;
}
.item-price {
> span {
font-size: 15px;
font-weight: 500;
color: #e1212b;
}
}
.join-item {
flex: 1;
}
.item-img {
width: 75px;
height: 75px;
margin: 0 auto;
display: block;
}
.item-img-box {
position: relative;
}
.item-line-through {
> span {
font-size: 10px;
font-weight: 400;
text-decoration: line-through;
color: #999;
}
}
.item-position-tips {
position: absolute;
right: 0;
color: #fff;
font-size: 12px;
bottom: 0;
}
.join-title {
display: flex;
justify-content: space-between;
align-items: center;
background: #fff;
height: 50px;
> div:nth-of-type(1) {
font-size: 16px;
font-weight: bold;
}
> div:nth-of-type(2) {
font-size: 12px;
color: #999;
}
}
</style>

View File

@@ -0,0 +1,34 @@
<template>
<div class="layout">
<div class="view-height-150">
<img class="image-mode" :src="res.list[0].img" />
</div>
<div class="view-height-150">
<div class="view-height-75">
<img class="image-mode" :src="res.list[1].img" alt />
</div>
<div class="view-height-75">
<img class="image-mode" :src="res.list[2].img" alt />
</div>
</div>
</div>
</template>
<script>
export default {
title: "左一右二",
props: ["res"]
};
</script>
<style lang="scss" scoped>
@import "./tpl.scss";
.layout {
display: flex;
align-items: center;
justify-content: center;
background-size: cover;
}
</style>

View File

@@ -0,0 +1,39 @@
<template>
<div class="layout ">
<div class="view-height-150">
<div class="view-height-75">
<img class="image-mode" :src="res.list[0].img" alt />
</div>
<div class="view-height-75">
<img class="image-mode" :src="res.list[1].img" alt />
</div>
</div>
<div class="view-height-150">
<img class="image-mode" style="height:150px;" :src="res.list[2].img" />
</div>
</div>
</template>
<script>
export default {
title: "左二右一",
props: ["res"]
};
</script>
<style lang="scss" scoped>
@import "./tpl.scss";
.layout {
height: 150px;
display: flex;
align-items: center;
justify-content: center;
background-size: cover;
}
.view-height-75 {
.image-mode {
height: 75px;
}
}
</style>

View File

@@ -0,0 +1,38 @@
<template>
<div class="layout">
<div class="menu-list">
<div class="menu-item" v-for="(item,index) in res.list" :key="index">
<div>
<img class="menu-img" :src="item.img" alt="">
</div>
<div class="menu-title">{{item.title}}</div>
</div>
</div>
</div>
</template>
<script>
export default {
props:['res']
}
</script>
<style lang="scss" scoped>
@import "./tpl.scss";
.menu-list{
display: flex;
align-items: center;
flex-wrap: wrap;
>.menu-item{
text-align: center;
width: 20%;
margin:10px 0;
}
}
.menu-img{
width: 44px;
height: 44px;
}
.menu-title{
font-size: 12px;
}
</style>

View File

@@ -0,0 +1,26 @@
<template>
<div class="layout">
<div class="search">
<Icon type="ios-search" />{{res.list[0].title}}
</div>
</div>
</template>
<script>
export default {
props: ['res']
}
</script>
<style lang="scss" scoped>
@import "./tpl.scss";
.search{
height: 32px;
border-radius: 5px;
display: flex;
align-items: center;
justify-content: center;
background: #ededed;
}
.layout{
background: #fff;
}
</style>

View File

@@ -0,0 +1,39 @@
<template>
<div class="layout">
<div class="join-list">
<div class="join-title">
<div>{{ res.list[0].title }}</div>
<div>更多</div>
</div>
<div class="join-box">
<div class="join-item" v-for="item in 4" :key="item">
<div class="item-img-box">
<img
class="item-img"
src="https://picsum.photos/id/268/200/200"
alt
/>
</div>
<div class="item-price">
<span>120.00</span>
</div>
<div class="item-line-through">
<span>190.00</span>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
props: ["res"]
};
</script>
<style lang="scss" scoped>
@import "./tpl.scss";
@import './advertising.scss';
</style>

View File

@@ -0,0 +1,91 @@
<template>
<div class="layout">
<div class="view-list">
<div class="view-item">
<div class="-item-tilte">{{res.list[0].title}}</div>
<div class="-item-image">
<img :src="res.list[0].img" alt />
</div>
</div>
<div class="view-item">
<div class="-item-tilte">{{res.list[1].title}}</div>
<div class="-item-image">
<img :src="res.list[1].img" alt />
</div>
</div>
</div>
<div class="view-list">
<div class="view-item">
<div class="-item-tilte">{{res.list[2].title}}</div>
<div class="-item-image">
<img :src="res.list[2].img" alt />
</div>
</div>
<div class="view-item">
<div class="-item-tilte">{{res.list[3].title}}</div>
<div class="-item-image">
<img :src="res.list[3].img" alt />
</div>
</div>
</div>
</div>
</template>
<script>
export default {
title: "文字图片模板",
props: ["res"]
};
</script>
<style lang="scss" scoped>
@import "./tpl.scss";
.layout {
display: flex;
background: #e8e8e8;
align-items: center;
justify-content: center;
background-size: cover;
padding: 0;
}
.-item-image{
padding: 10px ;
>img{
width: 100%;
}
}
.-item-tilte {
background: #ff9f28;
height: 30px;
color: #fff;
font-size: 14px;
text-align: center;
line-height: 30px;
}
.view-list {
width: 48%;
margin: 0 auto;
display: flex;
background: #fff;
border-top-left-radius: 0.8em;
border-top-right-radius: 0.8em;
border: 1px solid #ededed;
> .view-item {
width: 50%;
}
> .view-item:nth-of-type(1) {
> .-item-tilte {
border-top-left-radius: 0.8em;
}
}
> .view-item:nth-of-type(2) {
> .-item-tilte {
border-top-right-radius: 0.8em;
}
}
}
</style>

View File

@@ -0,0 +1,43 @@
<template>
<div class="layout">
<div class="background">
<div class="title" :style="{ color: res.list[0].color }">
{{ res.list[0].title }}
</div>
</div>
</div>
</template>
<script>
export default {
title: "标题栏",
props: ["res"]
};
</script>
<style lang="scss" scoped>
@import "./tpl.scss";
.background {
background: url("../../../../assets/title.png") no-repeat;
position: absolute;
z-index: 2;
width: 100%;
height: 42px;
background-size: cover;
}
.layout {
text-align: center;
position: relative;
height: 42px;
display: flex;
align-items: center;
justify-content: center;
background: #ffffff;
}
.title {
line-height: 42px;
font-size: 15px;
font-weight: bold;
}
</style>

View File

@@ -0,0 +1,47 @@
<template>
<div class="layout">
<div class="view-width-100">
<img class="image-mode" :src="res.list[0].img" />
</div>
<div class="view-width-100">
<div class="view-height-85">
<img class="image-mode" :src="res.list[1].img" alt />
</div>
<div class="view-height-85">
<img class="image-mode" :src="res.list[2].img" alt />
</div>
</div>
</div>
</template>
<script>
export default {
title: "上一下二",
props: ["res"]
};
</script>
<style lang="scss" scoped>
@import "./tpl.scss";
.layout {
display: flex;
align-items: center;
justify-content: center;
background-size: cover;
height: 170px;
flex-direction: column;
}
img {
width: 100% !important;
height: 85px !important;
}
.view-width-100 {
padding: 1px 0;
display: flex;
height: 85px;
}
.view-height-85 {
padding: 0 1px;
width: 50%;
}
</style>

View File

@@ -0,0 +1,47 @@
<template>
<div class="layout">
<div class="view-width-100">
<div class="view-height-85">
<img class="image-mode" :src="res.list[0].img" alt />
</div>
<div class="view-height-85">
<img class="image-mode" :src="res.list[1].img" alt />
</div>
</div>
<div class="view-width-100">
<img class="image-mode" :src="res.list[2].img" />
</div>
</div>
</template>
<script>
export default {
title: "上二下一",
props: ["res"],
};
</script>
<style lang="scss" scoped>
@import "./tpl.scss";
.layout {
display: flex;
align-items: center;
justify-content: center;
background-size: cover;
height: 170px;
flex-direction: column;
}
img {
width: 100% !important;
height: 85px !important;
}
.view-width-100 {
padding: 1px 0;
display: flex;
height: 85px;
width: 100%;
}
.view-height-85 {
padding: 0 1px;
width: 50%;
}
</style>

View File

@@ -0,0 +1,13 @@
<template>
<div class="layout">请选择风格</div>
</template>
<script>
export default {
}
</script>
<style scoped lang="scss">
@import './tpl.scss';
.layout{
height: 100px;
}
</style>

View File

@@ -0,0 +1,216 @@
<template>
<div class="wrapper">
<Card class="content">
<Button type="primary" @click="handleAdd()">添加页面</Button>
<div class="list">
<Spin size="large" fix v-if="loading"></Spin>
<div class="item item-title" >
<div>页面名称</div>
<div class="item-config">
<div>状态</div>
<div>操作</div>
</div>
</div>
<div class="item" v-for="(item, index) in list" :key="index">
<div>{{ item.name || "暂无模板昵称" }}</div>
<div class="item-config">
<i-switch v-model="item.pageShow" @on-change="changeSwitch(item)">
<span slot="open"></span>
<span slot="close"></span>
</i-switch>
<Button type="info" placement="right" @click="handleEdit(item)" size="small">修改</Button>
<Poptip confirm title="删除此模板?" @on-ok="handleDel(item)" >
<Button type="error" size="small">删除</Button>
</Poptip>
</div>
</div>
<div class="no-more" v-if="list.length ==0">暂无更多模板</div>
</div>
<Page :total="total" size="small" @on-change="(val) => {params.pageNumber = val; } " :current="params.pageNumber" :page-size="params.pageSize" show-sizer :page-size-opts="[10, 20, 50]" @on-page-size-change="changePageSize"/>
</Card>
</div>
</template>
<script>
import * as API_Other from "@/api/other.js";
export default {
// components: {region},
data() {
return {
selectedIndex: 0, // 装修那个页面的下标
columns: [ // 表头
{
title: "页面名称",
key: "name",
},
{
title: "状态",
},
{
title: "操作",
key: "action",
},
],
loading: false, // 加载状态
params: { // 请求参数
pageNumber: 1,
pageSize: 10,
sort: "createTime",
order: "desc",
pageType: "INDEX",
pageClientType: "H5",
},
total: 0, // 页面数量
list: [], // 总数据
};
},
watch: {
params: {
handler(val) {
// this.pageNumber++;
this.init();
},
deep: true,
},
},
mounted() {
this.init();
},
methods: {
// 切换tab
clickType(val,index) {
this.params.pageNumber = 1
this.selectedIndex = index
this.params.pageType = val;
},
// 是否发布
changeSwitch(item) {
this.loading = true;
API_Other.releasePageHome(item.id).then((res) => {
if (res.result) {
this.loading = false;
this.$Message.success("发布成功");
this.init();
}
this.init();
this.loading = false;
});
},
// 初始化数据
init() {
this.loading = true;
API_Other.getHomeList(this.params).then((res) => {
if (!res.result) return false;
this.loading = false;
res.result.records.forEach((item) => {
if (item.pageShow == "OPEN") {
item.pageShow = true;
} else {
item.pageShow = false;
}
});
this.list = res.result.records;
console.log(this.list);
this.total = res.result.total;
});
},
// 装修楼层
handleEdit(val) {
this.$router.push({
path: "/floorList/main",
query: { id: val.id, name: val.name, type: val.pageShow },
});
},
// 添加模板
handleAdd() {
this.$router.push({
path: "/floorList/main",
});
},
// 分页 改变页数
changePageSize(v) {
this.params.pageNumber = 1;
this.params.pageSize = v;
this.init();
},
// 删除模板
handleDel(val) {
this.loading = true;
API_Other.removePageHome(val.id).then((res) => {
if (res.result) {
this.loading = false;
this.init();
this.$Message.success("删除成功");
}
this.loading = false;
});
},
},
};
</script>
<style scoped lang="scss">
.category-item {
cursor: pointer;
padding: 4px;
}
.active {
background: #ededed;
}
.item-title {
background: #d7e7f5!important;
height: 54px;
}
.no-more {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.wrapper {
background: #fff;
padding: 20px;
display: flex;
}
.category {
flex: 2;
}
.content {
flex: 8;
}
* {
margin: 5px;
}
.list {
min-height: 600px;
position: relative;
}
.item:nth-of-type(2) {
margin: 0 5px;
}
.item {
width: 100% !important;
padding: 0 4px;
display: flex;
align-items: center;
justify-content: space-between;
> .item-config {
width: 180px;
display: flex;
justify-content: space-around;
align-items: center;
}
}
.item:nth-of-type(2n+1) {
background: #f5f7fa;
}
</style>