第一次提交
This commit is contained in:
123
components/page/diyComponents/article/index.vue
Executable file
123
components/page/diyComponents/article/index.vue
Executable file
@@ -0,0 +1,123 @@
|
||||
<template>
|
||||
<!-- 文章组 -->
|
||||
<view class="diy-article">
|
||||
<view class="article-item" :class="[`show-type__${item.show_type}`]" v-for="(item, index) in dataList" :key="index"
|
||||
@click="onTargetDetail(item.article_id)">
|
||||
<!-- 小图模式 -->
|
||||
<block v-if="item.show_type == 10">
|
||||
<view class="article-item__left flex-box">
|
||||
<view class="article-item__title">
|
||||
<text class="twoline-hide">{{ item.title }}</text>
|
||||
</view>
|
||||
<view class="article-item__footer m-top10">
|
||||
<text class="article-views f-24 col-8">{{ item.show_views }}次浏览</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="article-item__image">
|
||||
<image class="image" mode="widthFix" :src="item.image_url"></image>
|
||||
</view>
|
||||
</block>
|
||||
<!-- 大图模式 -->
|
||||
<block v-if="item.show_type == 20">
|
||||
<view class="article-item__title">
|
||||
<text class="twoline-hide">{{ item.title }}</text>
|
||||
</view>
|
||||
<view class="article-item__image m-top20">
|
||||
<image class="image" mode="widthFix" :src="item.image_url"></image>
|
||||
</view>
|
||||
<view class="article-item__footer m-top10">
|
||||
<text class="article-views f-24 col-8">{{ item.show_views }}次浏览</text>
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "Article",
|
||||
/**
|
||||
* 组件的属性列表
|
||||
* 用于组件自定义设置
|
||||
*/
|
||||
props: {
|
||||
itemIndex: String,
|
||||
params: Object,
|
||||
dataList: Array
|
||||
},
|
||||
|
||||
/**
|
||||
* 组件的方法列表
|
||||
* 更新属性和数据的方法与更新页面数据的方法类似
|
||||
*/
|
||||
methods: {
|
||||
|
||||
/**
|
||||
* 跳转文章详情页
|
||||
*/
|
||||
onTargetDetail(id) {
|
||||
uni.navigateTo({
|
||||
url: '/pages/article/detail?articleId=' + id
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.diy-article {
|
||||
background: #f7f7f7;
|
||||
|
||||
.article-item {
|
||||
margin-bottom: 20rpx;
|
||||
padding: 30rpx;
|
||||
background: #fff;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.article-item__title {
|
||||
max-height: 74rpx;
|
||||
font-size: 28rpx;
|
||||
line-height: 38rpx;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.article-item__image .image {
|
||||
display: block;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
/* 小图模式 */
|
||||
|
||||
.show-type__10 {
|
||||
display: flex;
|
||||
|
||||
.article-item__left {
|
||||
padding-right: 20rpx;
|
||||
}
|
||||
|
||||
.article-item__title {
|
||||
// min-height: 72rpx;
|
||||
}
|
||||
|
||||
.article-item__image .image {
|
||||
width: 240rpx;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* 大图模式 */
|
||||
|
||||
.show-type__20 .article-item__image .image {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
166
components/page/diyComponents/banner/index.vue
Executable file
166
components/page/diyComponents/banner/index.vue
Executable file
@@ -0,0 +1,166 @@
|
||||
<template>
|
||||
<view class="diy-banner" :style="{ height: `${imgHeights[imgCurrent]}px` }">
|
||||
<!-- 图片轮播 -->
|
||||
<swiper
|
||||
:autoplay="autoplay"
|
||||
class="swiper-box"
|
||||
:duration="duration"
|
||||
:circular="true"
|
||||
:interval="itemStyle.interval * 1000"
|
||||
@change="_bindChange"
|
||||
>
|
||||
<swiper-item v-for="(dataItem, index) in dataList" :key="index">
|
||||
<image mode="widthFix" class="slide-image" :src="dataItem.imgUrl" @click="onLink(dataItem.link)" @load="_imagesHeight" />
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
<!-- 指示点 -->
|
||||
<view class="indicator-dots" :class="itemStyle.btnShape">
|
||||
<view
|
||||
class="dots-item"
|
||||
:class="{ active: imgCurrent == index }"
|
||||
:style="{ backgroundColor: itemStyle.btnColor }"
|
||||
v-for="(dataItem, index) in dataList"
|
||||
:key="index"
|
||||
></view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import mixin from '../mixin';
|
||||
|
||||
export default {
|
||||
name: 'Banner',
|
||||
|
||||
/**
|
||||
* 组件的属性列表
|
||||
* 用于组件自定义设置
|
||||
*/
|
||||
props: {
|
||||
itemIndex: String,
|
||||
itemStyle: Object,
|
||||
params: Object,
|
||||
dataList: Array
|
||||
},
|
||||
|
||||
mixins: [mixin],
|
||||
|
||||
/**
|
||||
* 私有数据,组件的初始数据
|
||||
* 可用于模版渲染
|
||||
*/
|
||||
data() {
|
||||
return {
|
||||
windowWidth: 750,
|
||||
indicatorDots: false, // 是否显示面板指示点
|
||||
autoplay: true, // 是否自动切换
|
||||
duration: 800, // 滑动动画时长
|
||||
imgHeights: [], // 图片的高度
|
||||
imgCurrent: 0 // 当前banne所在滑块指针
|
||||
};
|
||||
},
|
||||
|
||||
created() {
|
||||
const app = this;
|
||||
uni.getSystemInfo({
|
||||
success({ windowWidth }) {
|
||||
app.windowWidth = windowWidth > 750 ? 750 : windowWidth;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 组件的方法列表
|
||||
* 更新属性和数据的方法与更新页面数据的方法类似
|
||||
*/
|
||||
methods: {
|
||||
/**
|
||||
* 计算图片高度
|
||||
*/
|
||||
_imagesHeight({ detail }) {
|
||||
const app = this;
|
||||
// 获取图片真实宽度
|
||||
const { width, height } = detail;
|
||||
// 宽高比
|
||||
const ratio = width / height;
|
||||
// 计算的高度值
|
||||
const viewHeight = app.windowWidth / ratio;
|
||||
// 把每一张图片的高度记录到数组里
|
||||
app.imgHeights.push(viewHeight);
|
||||
},
|
||||
|
||||
/**
|
||||
* 记录当前指针
|
||||
*/
|
||||
_bindChange(e) {
|
||||
this.imgCurrent = e.detail.current;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.diy-banner {
|
||||
position: relative;
|
||||
|
||||
// swiper组件
|
||||
.swiper-box {
|
||||
height: 100%;
|
||||
|
||||
.slide-image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 0 auto;
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
/* 指示点 */
|
||||
.indicator-dots {
|
||||
width: 100%;
|
||||
height: 28rpx;
|
||||
padding: 0 20rpx;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 20rpx;
|
||||
opacity: 0.8;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
|
||||
.dots-item {
|
||||
width: 16rpx;
|
||||
height: 16rpx;
|
||||
margin-right: 8rpx;
|
||||
background-color: #fff;
|
||||
|
||||
&:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
&.active {
|
||||
background-color: #313131 !important;
|
||||
}
|
||||
}
|
||||
|
||||
// 圆形
|
||||
&.round .dots-item {
|
||||
width: 16rpx;
|
||||
height: 16rpx;
|
||||
border-radius: 20rpx;
|
||||
}
|
||||
|
||||
// 正方形
|
||||
&.square .dots-item {
|
||||
width: 16rpx;
|
||||
height: 16rpx;
|
||||
}
|
||||
|
||||
// 长方形
|
||||
&.rectangle .dots-item {
|
||||
width: 22rpx;
|
||||
height: 14rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
184
components/page/diyComponents/bargain/index.vue
Executable file
184
components/page/diyComponents/bargain/index.vue
Executable file
@@ -0,0 +1,184 @@
|
||||
<template>
|
||||
<!-- 砍价商品组 -->
|
||||
<view class="diy-bargain" :style="{ background: itemStyle.background }">
|
||||
<view class="goods-item" v-for="(goods, idx) in dataList" :key="idx" @click="handleNavDetail(goods)">
|
||||
<!-- 商品图片 -->
|
||||
<view class="goods-image">
|
||||
<image class="image" :src="goods.goods_image"></image>
|
||||
</view>
|
||||
<view class="goods-info">
|
||||
<!-- 商品名称 -->
|
||||
<view v-if="inArray('goodsName', itemStyle.show)" class="goods-name">
|
||||
<text class="twoline-hide">{{ goods.goods_name }}</text>
|
||||
</view>
|
||||
<!-- 参与的用户头像 -->
|
||||
<view v-if="inArray('peoples', itemStyle.show) && goods.helpsCount" class="peoples">
|
||||
<view class="user-list">
|
||||
<view v-for="(help, hidx) in goods.helpList" :key="hidx" class="user-item-avatar">
|
||||
<avatar-image :url="help.user.avatar_url" :width="32" />
|
||||
</view>
|
||||
</view>
|
||||
<view class="people__text">
|
||||
<text>{{ goods.helpsCount }}人正在砍价</text>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 商品原价 -->
|
||||
<view v-if="inArray('originalPrice', itemStyle.show)" class="goods-price">
|
||||
<text>¥{{ goods.original_price }}</text>
|
||||
</view>
|
||||
<!-- 砍价低价 -->
|
||||
<view v-if="inArray('floorPrice', itemStyle.show)" class="floor-price">
|
||||
<text class="small">最低¥</text>
|
||||
<text class="big">{{ goods.floor_price }}</text>
|
||||
</view>
|
||||
<!-- 操作按钮 -->
|
||||
<view class="opt-touch">
|
||||
<view class="touch-btn">
|
||||
<text>立即参加</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import AvatarImage from '@/components/avatar-image'
|
||||
import { inArray } from '@/utils/util'
|
||||
import mixin from '../mixin'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
AvatarImage
|
||||
},
|
||||
|
||||
/**
|
||||
* 组件的属性列表
|
||||
* 用于组件自定义设置
|
||||
*/
|
||||
props: {
|
||||
itemIndex: String,
|
||||
itemStyle: Object,
|
||||
params: Object,
|
||||
dataList: Array
|
||||
},
|
||||
|
||||
data() {
|
||||
return { inArray }
|
||||
},
|
||||
|
||||
mixins: [mixin],
|
||||
|
||||
/**
|
||||
* 组件的方法列表
|
||||
* 更新属性和数据的方法与更新页面数据的方法类似
|
||||
*/
|
||||
methods: {
|
||||
|
||||
// 跳转到砍价商品详情
|
||||
handleNavDetail(item) {
|
||||
this.$navTo('pages/bargain/goods/index', { activeId: item.active_id, goodsId: item.goods_id })
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
// diy-砍价商品组
|
||||
.diy-bargain {
|
||||
|
||||
.goods-item {
|
||||
display: flex;
|
||||
margin-bottom: 20rpx;
|
||||
background: #fff;
|
||||
padding: 20rpx 16rpx;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.goods-item .goods-image .image {
|
||||
display: block;
|
||||
width: 220rpx;
|
||||
height: 220rpx;
|
||||
}
|
||||
|
||||
.goods-item .goods-info {
|
||||
width: 498rpx;
|
||||
padding-top: 4rpx;
|
||||
margin-left: 14rpx;
|
||||
position: relative;
|
||||
|
||||
.goods-name {
|
||||
font-size: 28rpx;
|
||||
min-height: 60rpx;
|
||||
}
|
||||
}
|
||||
|
||||
// 正在参与的用户
|
||||
.peoples {
|
||||
display: flex;
|
||||
margin-top: 14rpx;
|
||||
|
||||
.user-list {
|
||||
display: flex;
|
||||
margin-right: 10rpx;
|
||||
|
||||
.user-item-avatar {
|
||||
margin-left: -8rpx;
|
||||
|
||||
&:first-child {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.people__text {
|
||||
font-size: 24rpx;
|
||||
color: #818181;
|
||||
}
|
||||
}
|
||||
|
||||
// 商品原价
|
||||
.goods-price {
|
||||
margin-top: 14rpx;
|
||||
color: #818181;
|
||||
font-size: 24rpx;
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
// 砍价底价
|
||||
.floor-price {
|
||||
color: $main-bg;
|
||||
|
||||
.small {
|
||||
font-size: 24rpx;
|
||||
}
|
||||
|
||||
.big {
|
||||
font-size: 24rpx;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 立即参加按钮
|
||||
.opt-touch {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
right: 10rpx;
|
||||
|
||||
.touch-btn {
|
||||
color: #fff;
|
||||
font-size: 28rpx;
|
||||
background: #d3a975;
|
||||
border-radius: 30rpx;
|
||||
padding: 10rpx 28rpx;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
</style>
|
||||
31
components/page/diyComponents/blank/index.vue
Executable file
31
components/page/diyComponents/blank/index.vue
Executable file
@@ -0,0 +1,31 @@
|
||||
<template>
|
||||
<!-- 辅助空白 -->
|
||||
<view class="diy-blank" :style="{ height: `${itemStyle.height}px`, background: itemStyle.background }">
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
|
||||
/**
|
||||
* 组件的属性列表
|
||||
* 用于组件自定义设置
|
||||
*/
|
||||
props: {
|
||||
itemStyle: Object
|
||||
},
|
||||
|
||||
/**
|
||||
* 组件的方法列表
|
||||
* 更新属性和数据的方法与更新页面数据的方法类似
|
||||
*/
|
||||
methods: {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
</style>
|
||||
199
components/page/diyComponents/coupon/index.vue
Executable file
199
components/page/diyComponents/coupon/index.vue
Executable file
@@ -0,0 +1,199 @@
|
||||
<template>
|
||||
<!-- 优惠券组 -->
|
||||
<view v-if="couponList.length" class="diy-coupon" :style="{ padding: `${itemStyle.paddingTop}px 0`, background: itemStyle.background }">
|
||||
<scroll-view :scroll-x="true">
|
||||
<view class="coupon-wrapper">
|
||||
<view class="coupon-item" :class="{ disable: !dataItem.state.value }" v-for="(dataItem, index) in couponList" :key="index"
|
||||
:style="{ marginRight: `${itemStyle.marginRight}px` }">
|
||||
<text class="before" :style="{ background: itemStyle.background }"></text>
|
||||
<view class="left-content" :style="{ background: itemStyle.couponBgColor }">
|
||||
<view class="content-top">
|
||||
<block v-if="dataItem.coupon_type == 10">
|
||||
<text class="unit">¥</text>
|
||||
<text class="price">{{ dataItem.reduce_price }}</text>
|
||||
</block>
|
||||
<text v-if="dataItem.coupon_type == 20" class="price">{{ dataItem.discount }}折</text>
|
||||
</view>
|
||||
<view class="content-bottom">
|
||||
<text class="f-22">满{{ dataItem.min_price }}元可用</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="right-receive" :style="{ background: itemStyle.receiveBgColor }" @click="handleReceive(index, dataItem)">
|
||||
<block v-if="dataItem.state.value">
|
||||
<text>立即</text>
|
||||
<text>领取</text>
|
||||
</block>
|
||||
<text v-else>{{ dataItem.state.text }}</text>
|
||||
</block>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import mixin from '../mixin'
|
||||
import * as MyCouponApi from '@/api/myCoupon'
|
||||
import { cloneObj } from '@/utils/util'
|
||||
|
||||
export default {
|
||||
|
||||
/**
|
||||
* 组件的属性列表
|
||||
* 用于组件自定义设置
|
||||
*/
|
||||
props: {
|
||||
itemIndex: String,
|
||||
itemStyle: Object,
|
||||
params: Object,
|
||||
dataList: Array
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
// 优惠券列表
|
||||
couponList: [],
|
||||
// 防止重复提交
|
||||
disable: false
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
// 这里监听dataList并写入到data中, 因为领取事件不能直接修改props中的属性
|
||||
dataList: {
|
||||
handler(data) {
|
||||
this.couponList = cloneObj(data)
|
||||
// console.log(this.couponList)
|
||||
},
|
||||
immediate: true,
|
||||
deep: true
|
||||
}
|
||||
},
|
||||
|
||||
mixins: [mixin],
|
||||
|
||||
/**
|
||||
* 组件的方法列表
|
||||
* 更新属性和数据的方法与更新页面数据的方法类似
|
||||
*/
|
||||
methods: {
|
||||
|
||||
// 立即领取事件
|
||||
handleReceive(index, item) {
|
||||
const app = this
|
||||
if (app.disable || !item.state.value) {
|
||||
return
|
||||
}
|
||||
app.disable = true
|
||||
MyCouponApi.receive(item.coupon_id, {}, { load: false })
|
||||
.then(result => {
|
||||
// 显示领取成功提示
|
||||
app.$success(result.message)
|
||||
// 将优惠券设置为已领取
|
||||
app.setReceived(index, item)
|
||||
})
|
||||
.finally(() => app.disable = false)
|
||||
},
|
||||
|
||||
// 将优惠券设置为已领取
|
||||
setReceived(index, item) {
|
||||
const app = this
|
||||
app.$set(app.couponList, index, {
|
||||
...item,
|
||||
state: { value: 0, text: '已领取' }
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.diy-coupon {
|
||||
|
||||
.coupon-wrapper {
|
||||
display: flex;
|
||||
width: max-content;
|
||||
height: 130rpx;
|
||||
padding: 0 24rpx;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.coupon-item {
|
||||
flex-shrink: 0;
|
||||
width: 300rpx;
|
||||
height: 130rpx;
|
||||
position: relative;
|
||||
color: #fff;
|
||||
overflow: hidden;
|
||||
box-sizing: border-box;
|
||||
margin-right: 40rpx;
|
||||
display: flex;
|
||||
|
||||
&:last-child {
|
||||
margin-right: 0 !important;
|
||||
}
|
||||
|
||||
&.disable {
|
||||
.left-content {
|
||||
background: linear-gradient(-113deg, #bdbdbd, #a2a1a2) !important;
|
||||
}
|
||||
|
||||
.right-receive {
|
||||
background-color: #949494 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
width: 32rpx;
|
||||
height: 32rpx;
|
||||
top: 45%;
|
||||
left: -16rpx;
|
||||
transform: translateY(-50%);
|
||||
border-radius: 80%;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.left-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
width: 70%;
|
||||
height: 100%;
|
||||
background-color: #E5004F;
|
||||
font-size: 24rpx;
|
||||
|
||||
.content-top {
|
||||
.unit {
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.price {
|
||||
font-size: 44rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.right-receive {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 30%;
|
||||
height: 100%;
|
||||
background-color: #4e4e4e;
|
||||
text-align: center;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
39
components/page/diyComponents/empty.vue
Executable file
39
components/page/diyComponents/empty.vue
Executable file
@@ -0,0 +1,39 @@
|
||||
<template>
|
||||
<view class="diy-123123">
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import mixin from '../mixin'
|
||||
|
||||
export default {
|
||||
|
||||
/**
|
||||
* 组件的属性列表
|
||||
* 用于组件自定义设置
|
||||
*/
|
||||
props: {
|
||||
itemIndex: String,
|
||||
itemStyle: Object,
|
||||
params: Object,
|
||||
dataList: Array
|
||||
},
|
||||
|
||||
mixins: [mixin],
|
||||
|
||||
/**
|
||||
* 组件的方法列表
|
||||
* 更新属性和数据的方法与更新页面数据的方法类似
|
||||
*/
|
||||
methods: {
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
</style>
|
||||
257
components/page/diyComponents/goods/index.vue
Executable file
257
components/page/diyComponents/goods/index.vue
Executable file
@@ -0,0 +1,257 @@
|
||||
<template>
|
||||
<!-- 商品组 -->
|
||||
<view class="diy-goods" :style="{ background: itemStyle.background }">
|
||||
<view class="goods-list" :class="[`display__${itemStyle.display}`, `column__${itemStyle.column}`]">
|
||||
<scroll-view :scroll-x="itemStyle.display === 'slide'">
|
||||
<view class="goods-item" v-for="(dataItem, index) in dataList" :key="index" @click="onTargetGoods(dataItem.goods_id)">
|
||||
|
||||
<!-- 单列商品 -->
|
||||
<block v-if="itemStyle.column === 1">
|
||||
<view class="dis-flex">
|
||||
<!-- 商品图片 -->
|
||||
<view class="goods-item_left">
|
||||
<image class="image" :src="dataItem.goods_image"></image>
|
||||
</view>
|
||||
<view class="goods-item_right">
|
||||
<!-- 商品名称 -->
|
||||
<view v-if="itemStyle.show.includes('goodsName')" class="goods-name">
|
||||
<text class="twoline-hide">{{ dataItem.goods_name }}</text>
|
||||
</view>
|
||||
<view class="goods-item_desc">
|
||||
<!-- 商品卖点 -->
|
||||
<view v-if="itemStyle.show.includes('sellingPoint')" class="desc-selling_point dis-flex">
|
||||
<text class="oneline-hide">{{ dataItem.selling_point }}</text>
|
||||
</view>
|
||||
<!-- 商品销量 -->
|
||||
<view v-if="itemStyle.show.includes('goodsSales')" class="desc-goods_sales dis-flex">
|
||||
<text>已售{{ dataItem.goods_sales }}件</text>
|
||||
</view>
|
||||
<!-- 商品价格 -->
|
||||
<view class="desc_footer">
|
||||
<text v-if="itemStyle.show.includes('goodsPrice')" class="price_x">¥{{ dataItem.goods_price_min }}</text>
|
||||
<text class="price_y col-9"
|
||||
v-if="itemStyle.show.includes('linePrice') && dataItem.line_price_min > 0">¥{{ dataItem.line_price_min }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
<!-- 多列商品 -->
|
||||
<block v-else>
|
||||
<!-- 商品图片 -->
|
||||
<view class="goods-image">
|
||||
<image class="image" mode="aspectFill" :src="dataItem.goods_image"></image>
|
||||
</view>
|
||||
<view class="detail">
|
||||
<!-- 商品标题 -->
|
||||
<view v-if="itemStyle.show.includes('goodsName')" class="goods-name twoline-hide">
|
||||
<text class="twoline-hide">{{ dataItem.goods_name }}</text>
|
||||
</view>
|
||||
<!-- 商品价格 -->
|
||||
<view class="detail-price oneline-hide">
|
||||
<text v-if="itemStyle.show.includes('goodsPrice')" class="goods-price f-30 col-m">¥{{ dataItem.goods_price_min }}</text>
|
||||
<text v-if="itemStyle.show.includes('linePrice') && dataItem.line_price_min > 0"
|
||||
class="line-price col-9 f-24">¥{{ dataItem.line_price_min }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "Goods",
|
||||
/**
|
||||
* 组件的属性列表
|
||||
* 用于组件自定义设置
|
||||
*/
|
||||
props: {
|
||||
itemIndex: String,
|
||||
itemStyle: Object,
|
||||
params: Object,
|
||||
dataList: Array
|
||||
},
|
||||
|
||||
/**
|
||||
* 组件的方法列表
|
||||
* 更新属性和数据的方法与更新页面数据的方法类似
|
||||
*/
|
||||
methods: {
|
||||
|
||||
/**
|
||||
* 跳转商品详情页
|
||||
*/
|
||||
onTargetGoods(goodsId) {
|
||||
this.$navTo(`pages/goods/detail`, { goodsId })
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.diy-goods {
|
||||
.goods-list {
|
||||
padding: 4rpx;
|
||||
box-sizing: border-box;
|
||||
|
||||
.goods-item {
|
||||
box-sizing: border-box;
|
||||
padding: 6rpx;
|
||||
|
||||
.goods-image {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 0;
|
||||
padding-bottom: 100%;
|
||||
overflow: hidden;
|
||||
background: #fff;
|
||||
|
||||
&:after {
|
||||
content: '';
|
||||
display: block;
|
||||
margin-top: 100%;
|
||||
}
|
||||
|
||||
.image {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
-o-object-fit: cover;
|
||||
object-fit: cover;
|
||||
}
|
||||
}
|
||||
|
||||
.detail {
|
||||
padding: 8rpx;
|
||||
background: #fff;
|
||||
|
||||
.goods-name {
|
||||
min-height: 68rpx;
|
||||
line-height: 1.3;
|
||||
white-space: normal;
|
||||
color: #484848;
|
||||
font-size: 26rpx;
|
||||
margin-bottom: 4rpx;
|
||||
}
|
||||
|
||||
.detail-price {
|
||||
.goods-price {
|
||||
margin-right: 8rpx;
|
||||
}
|
||||
|
||||
.line-price {
|
||||
text-decoration: line-through;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.display__slide {
|
||||
white-space: nowrap;
|
||||
font-size: 0;
|
||||
|
||||
.goods-item {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
|
||||
&.display__list {
|
||||
.goods-item {
|
||||
float: left;
|
||||
}
|
||||
}
|
||||
|
||||
&.column__2 {
|
||||
.goods-item {
|
||||
width: 50%;
|
||||
}
|
||||
}
|
||||
|
||||
&.column__3 {
|
||||
.goods-item {
|
||||
width: 33.33333%;
|
||||
}
|
||||
}
|
||||
|
||||
&.column__1 {
|
||||
.goods-item {
|
||||
width: 100%;
|
||||
height: 280rpx;
|
||||
margin-bottom: 12rpx;
|
||||
padding: 20rpx;
|
||||
box-sizing: border-box;
|
||||
background: #fff;
|
||||
line-height: 1.6;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.goods-item_left {
|
||||
display: flex;
|
||||
width: 40%;
|
||||
background: #fff;
|
||||
align-items: center;
|
||||
|
||||
.image {
|
||||
display: block;
|
||||
width: 240rpx;
|
||||
height: 240rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.goods-item_right {
|
||||
position: relative;
|
||||
width: 60%;
|
||||
|
||||
.goods-name {
|
||||
margin-top: 20rpx;
|
||||
min-height: 68rpx;
|
||||
line-height: 1.3;
|
||||
white-space: normal;
|
||||
color: #484848;
|
||||
font-size: 26rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.goods-item_desc {
|
||||
margin-top: 8rpx;
|
||||
}
|
||||
|
||||
.desc-selling_point {
|
||||
width: 400rpx;
|
||||
font-size: 24rpx;
|
||||
color: #e49a3d;
|
||||
}
|
||||
|
||||
.desc-goods_sales {
|
||||
color: #999;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
|
||||
.desc_footer {
|
||||
font-size: 24rpx;
|
||||
|
||||
.price_x {
|
||||
margin-right: 16rpx;
|
||||
color: $main-bg;
|
||||
font-size: 30rpx;
|
||||
}
|
||||
|
||||
.price_y {
|
||||
text-decoration: line-through;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
212
components/page/diyComponents/groupon/index.vue
Executable file
212
components/page/diyComponents/groupon/index.vue
Executable file
@@ -0,0 +1,212 @@
|
||||
<template>
|
||||
<!-- 拼团商品组 -->
|
||||
<view class="diy-groupon" :style="{ background: itemStyle.background, padding: `${itemStyle.paddingY * 2}rpx ${itemStyle.paddingX * 2}rpx` }">
|
||||
<view class="goods-item--container" v-for="(goods, idx) in dataList" :key="idx" :style="{ marginBottom: `${itemStyle.itemMargin * 2}rpx` }">
|
||||
<view class="goods-item" @click="onTargetGoods(goods)" :class="[`display-${itemStyle.display}`, `border-${itemStyle.itemBorderRadius}`]">
|
||||
<!-- 商品图片 -->
|
||||
<view class="goods-item_left">
|
||||
<view v-if="goods.active_type != ActiveTypeEnum.NORMAL.value" class="label">
|
||||
<text>{{ ActiveTypeEnum[goods.active_type].name2 }}</text>
|
||||
</view>
|
||||
<image class="image" :src="goods.goods_image"></image>
|
||||
</view>
|
||||
<view class="goods-item_right">
|
||||
<!-- 商品标题 -->
|
||||
<view v-if="inArray('goodsName', itemStyle.show)" class="goods-name">
|
||||
<text class="twoline-hide">{{ goods.goods_name }}</text>
|
||||
</view>
|
||||
<!-- 商品信息 -->
|
||||
<view class="goods-item_desc">
|
||||
<view class="desc_situation">
|
||||
<u-tag v-if="inArray('peoples', itemStyle.show)" class="people" :color="appTheme.mainBg" :border-color="appTheme.mainBg"
|
||||
:text="`${goods.show_people}人团`" type="error" size="mini" mode="plain" />
|
||||
<u-tag v-if="inArray('activeSales', itemStyle.show) && goods.active_sales" :color="appTheme.mainBg" :border-color="tagBorderColor"
|
||||
:bg-color="tagBackgroundColor" :text="`已团${goods.active_sales}件`" type="error" size="mini" />
|
||||
</view>
|
||||
<view class="desc_footer">
|
||||
<view class="item-prices oneline-hide">
|
||||
<text v-if="inArray('grouponPrice', itemStyle.show)" class="price_x">¥{{ goods.groupon_price }}</text>
|
||||
<text v-if="inArray('grouponPrice', itemStyle.show)" class="price_y cl-9">¥{{ goods.original_price }}</text>
|
||||
</view>
|
||||
<view v-if="inArray('button', itemStyle.show)" class="settlement">去拼团</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { inArray } from '@/utils/util'
|
||||
import { hex2rgba } from '@/utils/color'
|
||||
import mixin from '../mixin'
|
||||
import { ActiveTypeEnum } from '@/common/enum/groupon'
|
||||
|
||||
export default {
|
||||
components: {},
|
||||
mixins: [mixin],
|
||||
props: {
|
||||
itemIndex: String,
|
||||
itemStyle: Object,
|
||||
params: Object,
|
||||
dataList: Array
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
inArray,
|
||||
ActiveTypeEnum
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
// 标签背景色
|
||||
tagBackgroundColor() {
|
||||
return hex2rgba(this.appTheme.mainBg, 0.1)
|
||||
},
|
||||
// 标签边框颜色
|
||||
tagBorderColor() {
|
||||
return hex2rgba(this.appTheme.mainBg, 0.6)
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 组件的方法列表
|
||||
* 更新属性和数据的方法与更新页面数据的方法类似
|
||||
*/
|
||||
methods: {
|
||||
|
||||
// 跳转到拼团商品详情
|
||||
onTargetGoods(item) {
|
||||
this.$navTo('pages/groupon/goods/index', { grouponGoodsId: item.groupon_goods_id })
|
||||
},
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.diy-groupon {
|
||||
|
||||
.goods-item--container {
|
||||
margin-bottom: 20rpx;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.goods-item {
|
||||
padding: 28rpx 24rpx;
|
||||
display: flex;
|
||||
background: #fff;
|
||||
box-sizing: border-box;
|
||||
|
||||
&.display-card {
|
||||
box-shadow: 0 4rpx 10rpx rgba(0, 0, 0, 0.07);
|
||||
}
|
||||
|
||||
&.border-round {
|
||||
border-radius: 14rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.goods-item_left {
|
||||
position: relative;
|
||||
background: #fff;
|
||||
margin-right: 20rpx;
|
||||
|
||||
.label {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 1;
|
||||
background: linear-gradient(to right, #ffa600, #f5b914);
|
||||
color: #fff;
|
||||
font-size: 24rpx;
|
||||
padding: 6rpx 8rpx;
|
||||
border-radius: 8rpx;
|
||||
}
|
||||
|
||||
.image {
|
||||
display: block;
|
||||
width: 220rpx;
|
||||
height: 220rpx;
|
||||
border-radius: 10rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.goods-item_right {
|
||||
position: relative;
|
||||
flex: 1;
|
||||
|
||||
.goods-name {
|
||||
display: block;
|
||||
width: 100%;
|
||||
min-height: 68rpx;
|
||||
font-size: 28rpx;
|
||||
line-height: 1.3;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.goods-item_desc {
|
||||
margin-top: 20rpx;
|
||||
|
||||
.desc_situation {
|
||||
font-size: 26rpx;
|
||||
line-height: 1.3;
|
||||
color: $main-bg;
|
||||
margin-top: 20rpx;
|
||||
}
|
||||
|
||||
.people {
|
||||
margin-right: 14rpx;
|
||||
}
|
||||
|
||||
.desc_footer {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
position: absolute;
|
||||
right: 0rpx;
|
||||
bottom: 0rpx;
|
||||
min-height: 44rpx;
|
||||
|
||||
.item-status {
|
||||
color: $main-bg;
|
||||
}
|
||||
|
||||
.item-prices {
|
||||
padding-right: 6rpx;
|
||||
|
||||
.price_x {
|
||||
margin-right: 14rpx;
|
||||
color: $main-bg;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.price_y {
|
||||
color: #999;
|
||||
text-decoration: line-through;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.settlement {
|
||||
padding: 0 30rpx;
|
||||
line-height: 56rpx;
|
||||
text-align: center;
|
||||
font-size: 28rpx;
|
||||
border-radius: 40rpx;
|
||||
color: #fff;
|
||||
background: $main-bg;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
36
components/page/diyComponents/guide/index.vue
Executable file
36
components/page/diyComponents/guide/index.vue
Executable file
@@ -0,0 +1,36 @@
|
||||
<template>
|
||||
<!-- 辅助线 -->
|
||||
<view class="diy-guide" :style="{ padding: `${itemStyle.paddingTop}px 0`, background: itemStyle.background }">
|
||||
<view class="line" :style="{ borderTop: `${itemStyle.lineHeight}px ${itemStyle.lineStyle} ${itemStyle.lineColor}` }">
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
|
||||
/**
|
||||
* 组件的属性列表
|
||||
* 用于组件自定义设置
|
||||
*/
|
||||
props: {
|
||||
itemStyle: Object
|
||||
},
|
||||
|
||||
/**
|
||||
* 组件的方法列表
|
||||
* 更新属性和数据的方法与更新页面数据的方法类似
|
||||
*/
|
||||
methods: {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.diy-guide .line {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
67
components/page/diyComponents/hotZone/index.vue
Executable file
67
components/page/diyComponents/hotZone/index.vue
Executable file
@@ -0,0 +1,67 @@
|
||||
<template>
|
||||
<!-- 热区 -->
|
||||
<view class="diy-hotZone"
|
||||
:style="{ paddingBottom: `${itemStyle.paddingTop * 2}rpx`, background: itemStyle.background }">
|
||||
<view class="bg-image" :style="{ padding: `${itemStyle.paddingTop * 2}rpx ${itemStyle.paddingLeft * 2}rpx 0` }">
|
||||
<image class="image" :src="data.imgUrl" mode="widthFix"></image>
|
||||
</view>
|
||||
<view class="zone-item" v-for="(item, index) in data.maps" :key="index"
|
||||
:style="{ width: `${item.width}rpx`, height: `${item.height}rpx`, left: `${item.left}rpx`, top: `${item.top}rpx` }"
|
||||
@click="onLink(item.link)">
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import mixin from '../mixin'
|
||||
|
||||
export default {
|
||||
name: "Images",
|
||||
|
||||
/**
|
||||
* 组件的属性列表
|
||||
* 用于组件自定义设置
|
||||
*/
|
||||
props: {
|
||||
itemIndex: String,
|
||||
itemStyle: Object,
|
||||
params: Object,
|
||||
data: Object
|
||||
},
|
||||
|
||||
mixins: [mixin],
|
||||
|
||||
/**
|
||||
* 组件的方法列表
|
||||
* 更新属性和数据的方法与更新页面数据的方法类似
|
||||
*/
|
||||
methods: {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.diy-hotZone {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.bg-image {
|
||||
width: 100%;
|
||||
z-index: 1;
|
||||
|
||||
.image {
|
||||
display: block;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.zone-item {
|
||||
position: absolute;
|
||||
z-index: 2;
|
||||
// background-color: red;
|
||||
}
|
||||
</style>
|
||||
47
components/page/diyComponents/image/index.vue
Executable file
47
components/page/diyComponents/image/index.vue
Executable file
@@ -0,0 +1,47 @@
|
||||
<template>
|
||||
<!-- 单图组 -->
|
||||
<view class="diy-imageSingle" :style="{ paddingBottom: `${itemStyle.paddingTop * 2}rpx`, background: itemStyle.background }">
|
||||
<view class="item-image" v-for="(dataItem, index) in dataList" :key="index" :style="{ padding: `${itemStyle.paddingTop * 2}rpx ${itemStyle.paddingLeft * 2}rpx 0` }">
|
||||
<view class="nav-to" @click="onLink(dataItem.link)">
|
||||
<image class="image" :src="dataItem.imgUrl" mode="widthFix"></image>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import mixin from '../mixin'
|
||||
|
||||
export default {
|
||||
name: "Images",
|
||||
|
||||
/**
|
||||
* 组件的属性列表
|
||||
* 用于组件自定义设置
|
||||
*/
|
||||
props: {
|
||||
itemIndex: String,
|
||||
itemStyle: Object,
|
||||
params: Object,
|
||||
dataList: Array
|
||||
},
|
||||
|
||||
mixins: [mixin],
|
||||
|
||||
/**
|
||||
* 组件的方法列表
|
||||
* 更新属性和数据的方法与更新页面数据的方法类似
|
||||
*/
|
||||
methods: {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.diy-imageSingle .item-image .image {
|
||||
display: block;
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
55
components/page/diyComponents/mixin.js
Executable file
55
components/page/diyComponents/mixin.js
Executable file
@@ -0,0 +1,55 @@
|
||||
import { urlDecode } from '@/utils/util'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {}
|
||||
},
|
||||
methods: {
|
||||
|
||||
/**
|
||||
* link对象点击事件
|
||||
* 支持tabBar页面
|
||||
*/
|
||||
onLink(linkObj) {
|
||||
if (!linkObj) return false
|
||||
// 跳转到指定页面
|
||||
if (linkObj.type === 'PAGE') {
|
||||
this.$navTo(linkObj.param.path, linkObj.param.query)
|
||||
}
|
||||
// 跳转到自定义路径
|
||||
if (linkObj.type === 'CUSTOM') {
|
||||
this.$navTo(linkObj.param.path, urlDecode(linkObj.param.queryStr))
|
||||
}
|
||||
// 跳转到微信小程序
|
||||
// #ifdef MP-WEIXIN
|
||||
if (linkObj.type === 'MP-WEIXIN') {
|
||||
uni.navigateToMiniProgram({
|
||||
appId: linkObj.param.appId,
|
||||
path: linkObj.param.path
|
||||
})
|
||||
}
|
||||
// #endif
|
||||
// 跳转到H5外部链接
|
||||
if (linkObj.type === 'URL') {
|
||||
// #ifdef H5
|
||||
window.open(linkObj.param.url)
|
||||
// #endif
|
||||
// #ifdef APP-PLUS
|
||||
plus.runtime.openWeb(linkObj.param.url)
|
||||
// #endif
|
||||
// #ifdef MP
|
||||
uni.setClipboardData({
|
||||
data: linkObj.param.url,
|
||||
success: () =>
|
||||
uni.showToast({
|
||||
icon: 'none',
|
||||
title: '链接已复制'
|
||||
})
|
||||
})
|
||||
// #endif
|
||||
}
|
||||
return true
|
||||
}
|
||||
},
|
||||
|
||||
}
|
||||
87
components/page/diyComponents/navBar/index.vue
Executable file
87
components/page/diyComponents/navBar/index.vue
Executable file
@@ -0,0 +1,87 @@
|
||||
<template>
|
||||
<!-- 导航组 -->
|
||||
<view class="diy-navBar" :style="{ background: itemStyle.background, color: itemStyle.textColor }">
|
||||
<view class="data-list" :class="[`avg-sm-${itemStyle.rowsNum}`]">
|
||||
<view class="item-nav" v-for="(dataItem, index) in dataList" :key="index">
|
||||
<view class="nav-to" @click="onLink(dataItem.link)">
|
||||
<view class="item-image">
|
||||
<image class="image" mode="widthFix" :src="dataItem.imgUrl"></image>
|
||||
</view>
|
||||
<view class="item-text oneline-hide">{{ dataItem.text }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import mixin from '../mixin'
|
||||
|
||||
export default {
|
||||
name: "NavBar",
|
||||
/**
|
||||
* 组件的属性列表
|
||||
* 用于组件自定义设置
|
||||
*/
|
||||
props: {
|
||||
itemIndex: String,
|
||||
itemStyle: Object,
|
||||
params: Object,
|
||||
dataList: Array
|
||||
},
|
||||
|
||||
mixins: [mixin],
|
||||
|
||||
/**
|
||||
* 组件的方法列表
|
||||
* 更新属性和数据的方法与更新页面数据的方法类似
|
||||
*/
|
||||
methods: {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.diy-navBar .data-list::after {
|
||||
clear: both;
|
||||
content: " ";
|
||||
display: table;
|
||||
}
|
||||
|
||||
.item-nav {
|
||||
float: left;
|
||||
margin: 10px 0;
|
||||
text-align: center;
|
||||
|
||||
.item-text {
|
||||
font-size: 26rpx;
|
||||
}
|
||||
|
||||
.item-image {
|
||||
margin-bottom: 4px;
|
||||
font-size: 0;
|
||||
}
|
||||
|
||||
.item-image .image {
|
||||
width: 88rpx;
|
||||
height: 88rpx;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* 分列布局 */
|
||||
|
||||
.diy-navBar .avg-sm-3>.item-nav {
|
||||
width: 33.33333333%;
|
||||
}
|
||||
|
||||
.diy-navBar .avg-sm-4>.item-nav {
|
||||
width: 25%;
|
||||
}
|
||||
|
||||
.diy-navBar .avg-sm-5>.item-nav {
|
||||
width: 20%;
|
||||
}
|
||||
</style>
|
||||
40
components/page/diyComponents/notice/index.vue
Executable file
40
components/page/diyComponents/notice/index.vue
Executable file
@@ -0,0 +1,40 @@
|
||||
<template>
|
||||
<!-- 店铺公告 -->
|
||||
<view class="diy-notice" :style="{ paddingTop: `${itemStyle.paddingTop}px`, paddingBottom: `${itemStyle.paddingTop}px` }"
|
||||
@click="onLink(params.link)">
|
||||
<u-notice-bar padding="10rpx 24rpx" :volume-icon="params.showIcon" :autoplay="params.scrollable"
|
||||
:bg-color="itemStyle.background" :color="itemStyle.textColor" :list="[params.text]"></u-notice-bar>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import mixin from '../mixin'
|
||||
|
||||
export default {
|
||||
|
||||
/**
|
||||
* 组件的属性列表
|
||||
* 用于组件自定义设置
|
||||
*/
|
||||
props: {
|
||||
itemStyle: Object,
|
||||
params: Object
|
||||
},
|
||||
|
||||
mixins: [mixin],
|
||||
|
||||
/**
|
||||
* 组件的方法列表
|
||||
* 更新属性和数据的方法与更新页面数据的方法类似
|
||||
*/
|
||||
methods: {
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
</style>
|
||||
37
components/page/diyComponents/officialAccount/index.vue
Executable file
37
components/page/diyComponents/officialAccount/index.vue
Executable file
@@ -0,0 +1,37 @@
|
||||
<template>
|
||||
<!-- 关注公众号 -->
|
||||
<view class="diy-officialAccount">
|
||||
<official-account></official-account>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import mixin from '../mixin'
|
||||
|
||||
export default {
|
||||
|
||||
/**
|
||||
* 组件的属性列表
|
||||
* 用于组件自定义设置
|
||||
*/
|
||||
props: {
|
||||
itemIndex: String
|
||||
},
|
||||
|
||||
mixins: [mixin],
|
||||
|
||||
/**
|
||||
* 组件的方法列表
|
||||
* 更新属性和数据的方法与更新页面数据的方法类似
|
||||
*/
|
||||
methods: {
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
</style>
|
||||
33
components/page/diyComponents/richText/index.vue
Executable file
33
components/page/diyComponents/richText/index.vue
Executable file
@@ -0,0 +1,33 @@
|
||||
<template>
|
||||
<!-- 富文本 -->
|
||||
<view class="diy-richText"
|
||||
:style="{ padding: `${itemStyle.paddingTop}px ${itemStyle.paddingLeft}px`, background: itemStyle.background }">
|
||||
<mp-html :content="params.content" />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
/**
|
||||
* 组件的属性列表
|
||||
* 用于组件自定义设置
|
||||
*/
|
||||
props: {
|
||||
itemStyle: Object,
|
||||
params: Object
|
||||
},
|
||||
/**
|
||||
* 组件的方法列表
|
||||
* 更新属性和数据的方法与更新页面数据的方法类似
|
||||
*/
|
||||
methods: {
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.diy-richText {
|
||||
font-size: 28rpx;
|
||||
}
|
||||
</style>
|
||||
76
components/page/diyComponents/search/index.vue
Executable file
76
components/page/diyComponents/search/index.vue
Executable file
@@ -0,0 +1,76 @@
|
||||
<template>
|
||||
<!-- 搜索框 -->
|
||||
<view class="diy-search">
|
||||
<view class="inner" :class="itemStyle.searchStyle" @click="onTargetSearch">
|
||||
<view class="search-input" :style="{ textAlign: itemStyle.textAlign }">
|
||||
<text class="search-icon iconfont icon-search"></text>
|
||||
<text> {{ params.placeholder }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
|
||||
/**
|
||||
* 组件的属性列表
|
||||
* 用于组件自定义设置
|
||||
*/
|
||||
props: {
|
||||
itemIndex: String,
|
||||
itemStyle: Object,
|
||||
params: Object
|
||||
},
|
||||
|
||||
/**
|
||||
* 组件的方法列表
|
||||
* 更新属性和数据的方法与更新页面数据的方法类似
|
||||
*/
|
||||
methods: {
|
||||
|
||||
/**
|
||||
* 跳转到搜索页面
|
||||
*/
|
||||
onTargetSearch() {
|
||||
this.$navTo('pages/search/index')
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.diy-search {
|
||||
background: #f1f1f2;
|
||||
padding: 20rpx 20rpx;
|
||||
font-size: 26rpx;
|
||||
}
|
||||
|
||||
.inner {
|
||||
height: 60rpx;
|
||||
background: #fff;
|
||||
overflow: hidden;
|
||||
|
||||
&.radius {
|
||||
border-radius: 10rpx;
|
||||
}
|
||||
|
||||
&.round {
|
||||
border-radius: 60rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.search-input {
|
||||
height: 60rpx;
|
||||
color: #999;
|
||||
padding: 0 20rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.search-icon {
|
||||
margin-right: 8rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
90
components/page/diyComponents/service/index.vue
Executable file
90
components/page/diyComponents/service/index.vue
Executable file
@@ -0,0 +1,90 @@
|
||||
<template>
|
||||
<!-- 在线客服 -->
|
||||
<view v-if="isShow" class="diy-service" :style="{ '--right': `${right}px`, '--bottom': `${bottom}px` }">
|
||||
<!-- 拨打电话 -->
|
||||
<block v-if="params.type === 'phone'">
|
||||
<view class="service-icon" @click="onMakePhoneCall">
|
||||
<image class="image" :src="params.image"></image>
|
||||
</view>
|
||||
</block>
|
||||
<!-- 在线聊天 -->
|
||||
<block v-else-if="params.type == 'chat'">
|
||||
<customer-btn>
|
||||
<view class="service-icon">
|
||||
<image class="image" :src="params.image"></image>
|
||||
</view>
|
||||
</customer-btn>
|
||||
</block>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import CustomerBtn from '@/components/customer-btn'
|
||||
import { rpx2px } from '@/utils/util'
|
||||
import SettingModel from '@/common/model/Setting'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
CustomerBtn
|
||||
},
|
||||
props: {
|
||||
itemStyle: Object,
|
||||
params: Object
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isShow: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
right() {
|
||||
return rpx2px(2 * this.itemStyle.right)
|
||||
},
|
||||
bottom() {
|
||||
return rpx2px(2 * this.itemStyle.bottom)
|
||||
}
|
||||
},
|
||||
async created() {
|
||||
if (this.params.type === 'chat') {
|
||||
this.isShow = await SettingModel.isShowCustomerBtn()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
||||
/**
|
||||
* 点击拨打电话
|
||||
*/
|
||||
onMakePhoneCall(e) {
|
||||
uni.makePhoneCall({
|
||||
phoneNumber: this.params.tel
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.diy-service {
|
||||
position: fixed;
|
||||
z-index: 999;
|
||||
right: calc(var(--window-right) + var(--right));
|
||||
// 设置ios刘海屏底部横线安全区域
|
||||
bottom: calc(constant(safe-area-inset-bottom) + var(--window-bottom) + var(--bottom));
|
||||
bottom: calc(env(safe-area-inset-bottom) + var(--window-bottom) + var(--bottom));
|
||||
|
||||
.service-icon {
|
||||
padding: 10rpx;
|
||||
|
||||
.image {
|
||||
display: block;
|
||||
width: 90rpx;
|
||||
height: 90rpx;
|
||||
border-radius: 50%;
|
||||
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
251
components/page/diyComponents/sharp/index.vue
Executable file
251
components/page/diyComponents/sharp/index.vue
Executable file
@@ -0,0 +1,251 @@
|
||||
<template>
|
||||
<!-- 整点秒杀 -->
|
||||
<view v-if="data.goodsList.data && data.goodsList.data.length" class="diy-sharp" :style="{ background: itemStyle.background }">
|
||||
<!-- 秒杀会场信息 -->
|
||||
<view class="sharp-top" @click="handleNavMore()">
|
||||
<view class="sharp-top--left">
|
||||
<view class="sharp-modular">
|
||||
<text class="iconfont icon-miaosha-b"></text>
|
||||
<text class="modular-name">限时秒杀</text>
|
||||
</view>
|
||||
<view class="sharp-active-status">
|
||||
<text>{{ data.active.sharp_modular_text }}</text>
|
||||
</view>
|
||||
<!-- 倒计时 -->
|
||||
<view v-if="data.active.status == GoodsStatusEnum.STATE_BEGIN.value" class="active-count-down">
|
||||
<count-down :date="data.active.count_down_time" separator="colon" theme="custom" />
|
||||
</view>
|
||||
</view>
|
||||
<view class="sharp-top--right">
|
||||
<view class="sharp-more">
|
||||
<text class="sharp-more-text">更多</text>
|
||||
<text class="sharp-more-arrow iconfont icon-arrow-right"></text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 商品列表 -->
|
||||
<view class="goods-list display__list clearfix" :class="[`column__${itemStyle.column}`]">
|
||||
<view class="goods-item" v-for="(goods, idx) in data.goodsList.data" :key="idx"
|
||||
@click="handleNavDetail(goods.sharp_goods_id)">
|
||||
<!-- 单列商品 -->
|
||||
<block v-if="itemStyle.column == 1">
|
||||
</block>
|
||||
<!-- 两列三列 -->
|
||||
<block v-else>
|
||||
<!-- 商品图片 -->
|
||||
<view class="goods-image">
|
||||
<image class="image" mode="aspectFill" :src="goods.goods_image"></image>
|
||||
</view>
|
||||
<view class="detail">
|
||||
<!-- 商品标题 -->
|
||||
<view v-if="inArray('goodsName', itemStyle.show)" class="goods-name">
|
||||
<text class="twoline-hide"> {{ goods.goods_name }}</text>
|
||||
</view>
|
||||
<!-- 商品价格 -->
|
||||
<view class="detail-price">
|
||||
<text v-if="inArray('seckillPrice', itemStyle.show)" class="goods-price c-red">
|
||||
<text class="small-unit">¥</text>
|
||||
<text>{{ goods.seckill_price_min }}</text>
|
||||
</text>
|
||||
<text v-if="inArray('originalPrice', itemStyle.show) && goods.original_price > 0"
|
||||
class="line-price">¥{{ goods.original_price }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { inArray } from '@/utils/util'
|
||||
import CountDown from '@/components/countdown'
|
||||
import { ActiveStatusEnum, GoodsStatusEnum } from '@/common/enum/sharp'
|
||||
import mixin from '../mixin'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
CountDown
|
||||
},
|
||||
|
||||
/**
|
||||
* 组件的属性列表
|
||||
* 用于组件自定义设置
|
||||
*/
|
||||
props: {
|
||||
itemIndex: String,
|
||||
itemStyle: Object,
|
||||
params: Object,
|
||||
data: Object
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
// 枚举类
|
||||
ActiveStatusEnum,
|
||||
GoodsStatusEnum,
|
||||
// 公共函数
|
||||
inArray
|
||||
}
|
||||
},
|
||||
|
||||
mixins: [mixin],
|
||||
|
||||
/**
|
||||
* 组件的方法列表
|
||||
* 更新属性和数据的方法与更新页面数据的方法类似
|
||||
*/
|
||||
methods: {
|
||||
|
||||
// 跳转到秒杀会场页
|
||||
handleNavMore() {
|
||||
this.$navTo('pages/sharp/index')
|
||||
},
|
||||
|
||||
// 跳转到秒杀商品详情页
|
||||
handleNavDetail(sharpGoodsId) {
|
||||
const { data } = this
|
||||
this.$navTo('pages/sharp/goods/index', {
|
||||
activeTimeId: data.active.active_time_id,
|
||||
sharpGoodsId
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
// diy-秒杀商品组
|
||||
.diy-sharp {
|
||||
|
||||
.sharp-top {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.sharp-top--left {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.sharp-modular {
|
||||
font-size: 28rpx;
|
||||
color: #fff;
|
||||
background: #FB571D;
|
||||
padding: 10rpx 30rpx 10rpx 24rpx;
|
||||
border-bottom-right-radius: 30rpx;
|
||||
border-top-right-radius: 30rpx;
|
||||
|
||||
.modular-name {
|
||||
margin-left: 10rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.sharp-active-status {
|
||||
color: #616161;
|
||||
font-size: 28rpx;
|
||||
margin-left: 20rpx;
|
||||
margin-right: 16rpx;
|
||||
}
|
||||
|
||||
// 更多
|
||||
.sharp-more {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-right: 24rpx;
|
||||
color: #616161;
|
||||
font-size: 26rpx;
|
||||
|
||||
.sharp-more-arrow {
|
||||
font-size: 24rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 商品列表
|
||||
.goods-list {
|
||||
padding: 4rpx;
|
||||
|
||||
&.display__list {
|
||||
.goods-item {
|
||||
float: left;
|
||||
}
|
||||
}
|
||||
|
||||
&.column__2 {
|
||||
.goods-item {
|
||||
width: 50%;
|
||||
}
|
||||
}
|
||||
|
||||
&.column__3 {
|
||||
.goods-item {
|
||||
width: 33.33333%;
|
||||
}
|
||||
}
|
||||
|
||||
.goods-item {
|
||||
padding: 6rpx;
|
||||
|
||||
.goods-image {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 0;
|
||||
padding-bottom: 100%;
|
||||
overflow: hidden;
|
||||
background: #fff;
|
||||
|
||||
&:after {
|
||||
content: '';
|
||||
display: block;
|
||||
margin-top: 100%;
|
||||
}
|
||||
|
||||
.image {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
object-fit: cover;
|
||||
}
|
||||
}
|
||||
|
||||
.detail {
|
||||
padding: 4rpx;
|
||||
background: #fff;
|
||||
|
||||
.goods-name {
|
||||
font-size: 26rpx;
|
||||
min-height: 68rpx;
|
||||
line-height: 1.3;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.detail-price {
|
||||
line-height: 40rpx;
|
||||
|
||||
.goods-price {
|
||||
color: red;
|
||||
font-size: 30rpx;
|
||||
margin-right: 8rpx;
|
||||
}
|
||||
|
||||
.line-price {
|
||||
font-size: 24rpx;
|
||||
text-decoration: line-through;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
|
||||
.small-unit {
|
||||
font-size: 26rpx;
|
||||
margin-right: 4rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
97
components/page/diyComponents/shop/index.vue
Executable file
97
components/page/diyComponents/shop/index.vue
Executable file
@@ -0,0 +1,97 @@
|
||||
<template>
|
||||
<!-- 门店列表 -->
|
||||
<view class="diy-shop">
|
||||
<view class="shop-item dis-flex flex-y-center" v-for="(dataItem, index) in dataList" :key="index"
|
||||
@click="handleNavDetail(dataItem.shop_id)">
|
||||
<view class="shop-item__logo">
|
||||
<image class="image" :src="dataItem.logo_url"></image>
|
||||
</view>
|
||||
<view class="shop-item__content">
|
||||
<view class="shop-item__title">
|
||||
<span>{{ dataItem.shop_name }}</span>
|
||||
</view>
|
||||
<view class="shop-item__address oneline-hide">
|
||||
<span>门店地址:{{ dataItem.region.province }}{{ dataItem.region.city }}{{ dataItem.region.region }}{{ dataItem.address }}</span>
|
||||
</view>
|
||||
<view class="shop-item__phone">
|
||||
<span>联系电话:{{ dataItem.phone }}</span>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import mixin from '../mixin'
|
||||
|
||||
export default {
|
||||
|
||||
/**
|
||||
* 组件的属性列表
|
||||
* 用于组件自定义设置
|
||||
*/
|
||||
props: {
|
||||
itemIndex: String,
|
||||
itemStyle: Object,
|
||||
params: Object,
|
||||
dataList: Array
|
||||
},
|
||||
|
||||
mixins: [mixin],
|
||||
|
||||
/**
|
||||
* 组件的方法列表
|
||||
* 更新属性和数据的方法与更新页面数据的方法类似
|
||||
*/
|
||||
methods: {
|
||||
|
||||
// 跳转到门店详情页
|
||||
handleNavDetail(shopId) {
|
||||
this.$navTo('pages/shop/detail', { shopId })
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.shop-item {
|
||||
padding: 16rpx 30rpx;
|
||||
min-height: 180rpx;
|
||||
font-size: 26rpx;
|
||||
line-height: 1.5;
|
||||
border-bottom: 1rpx solid #eee;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.shop-item__logo {
|
||||
margin-right: 30rpx;
|
||||
|
||||
.image {
|
||||
display: block;
|
||||
width: 130rpx;
|
||||
height: 130rpx;
|
||||
border-radius: 50%;
|
||||
border: 1px solid rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
}
|
||||
|
||||
.shop-item__content {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.shop-item__title {
|
||||
font-size: 28rpx;
|
||||
color: #535353;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.shop-item__address,
|
||||
.shop-item__phone {
|
||||
color: #919396;
|
||||
}
|
||||
|
||||
.shop-item__address {
|
||||
width: 520rpx;
|
||||
}
|
||||
</style>
|
||||
102
components/page/diyComponents/special/index.vue
Executable file
102
components/page/diyComponents/special/index.vue
Executable file
@@ -0,0 +1,102 @@
|
||||
<template>
|
||||
<!-- 头条快报 -->
|
||||
<view class="diy-special" :style="{ padding: `${itemStyle.paddingTop}px 0`, background: itemStyle.background }">
|
||||
<view class="special-left" @click="handleNavMore()">
|
||||
<image class="image" mode="widthFix" :src="params.image" />
|
||||
</view>
|
||||
<div class="special-content" :class="[`display_${params.display}`]">
|
||||
<swiper :autoplay="true" :interval="1500" :duration="800" :circular="true" :vertical="true"
|
||||
:display-multiple-items="itemStyle.display">
|
||||
<swiper-item v-for="(dataItm, idx) in dataList" :key="idx">
|
||||
<view class="content-item oneline-hide" @click="handleNavDetail(dataItm.article_id)">
|
||||
<text :style="{ color: itemStyle.textColor }">{{ dataItm.title }}</text>
|
||||
</view>
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
</div>
|
||||
<div class="special-more" @click="handleNavMore()">
|
||||
<text class="iconfont icon-arrow-right"></text>
|
||||
</div>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import mixin from '../mixin'
|
||||
|
||||
export default {
|
||||
|
||||
/**
|
||||
* 组件的属性列表
|
||||
* 用于组件自定义设置
|
||||
*/
|
||||
props: {
|
||||
itemIndex: String,
|
||||
itemStyle: Object,
|
||||
params: Object,
|
||||
dataList: Array
|
||||
},
|
||||
|
||||
mixins: [mixin],
|
||||
|
||||
/**
|
||||
* 组件的方法列表
|
||||
* 更新属性和数据的方法与更新页面数据的方法类似
|
||||
*/
|
||||
methods: {
|
||||
|
||||
// 跳转到文章详情页
|
||||
handleNavDetail(articleId) {
|
||||
this.$navTo('pages/article/detail', { articleId })
|
||||
},
|
||||
|
||||
// 跳转到更多
|
||||
handleNavMore() {
|
||||
this.$navTo('pages/article/index')
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
// diy-头条快报
|
||||
.diy-special {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
line-height: normal;
|
||||
|
||||
.special-left {
|
||||
padding: 10rpx 20rpx;
|
||||
|
||||
.image {
|
||||
display: block;
|
||||
width: 140rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.special-content {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
|
||||
.content-item {
|
||||
padding: 4rpx 0;
|
||||
font-size: 13px;
|
||||
color: #141414;
|
||||
}
|
||||
|
||||
&.display_1 {
|
||||
height: 44rpx;
|
||||
}
|
||||
|
||||
&.display_2 {
|
||||
height: 88rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.special-more {
|
||||
padding: 24rpx 20rpx;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
38
components/page/diyComponents/video/index.vue
Executable file
38
components/page/diyComponents/video/index.vue
Executable file
@@ -0,0 +1,38 @@
|
||||
<template>
|
||||
<!-- 视频组 -->
|
||||
<view class="diy-video" :style="{ padding: `${itemStyle.paddingTop}px 0` }">
|
||||
<video class="video" :style="{ height: `${itemStyle.height}px` }" :src="params.videoUrl" :poster="params.poster"
|
||||
:autoplay="params.autoplay == 1" controls></video>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'Videos',
|
||||
/**
|
||||
* 组件的属性列表
|
||||
* 用于组件自定义设置
|
||||
*/
|
||||
props: {
|
||||
itemIndex: String,
|
||||
itemStyle: Object,
|
||||
params: Object
|
||||
},
|
||||
|
||||
/**
|
||||
* 组件的方法列表
|
||||
* 更新属性和数据的方法与更新页面数据的方法类似
|
||||
*/
|
||||
methods: {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.diy-video .video {
|
||||
width: 100%;
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
171
components/page/diyComponents/window/index.vue
Executable file
171
components/page/diyComponents/window/index.vue
Executable file
@@ -0,0 +1,171 @@
|
||||
<template>
|
||||
<!-- 图片橱窗 -->
|
||||
<view class="diy-window" :style="{ background: itemStyle.background, padding: `${itemStyle.paddingTop}px ${itemStyle.paddingLeft}px` }">
|
||||
<!-- matrix -->
|
||||
<view v-if="itemStyle.layout > -1" class="data-list" :class="[`avg-sm-${itemStyle.layout}`]">
|
||||
<view v-for="(dataItem, index) in dataList" :key="index" class="data-item" :style="{ padding: `${itemStyle.paddingTop}px ${itemStyle.paddingLeft}px` }">
|
||||
<view class="item-image" @click="onLink(dataItem.link)">
|
||||
<image class="image" mode="widthFix" :src="dataItem.imgUrl"></image>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- display -->
|
||||
<view v-else class="display">
|
||||
<view class="display-left" :style="{ padding: `${itemStyle.paddingTop}px ${itemStyle.paddingLeft}px` }">
|
||||
<image class="image" @click="onLink(dataList[0].link)" :src="dataList[0].imgUrl"></image>
|
||||
</view>
|
||||
<view class="display-right">
|
||||
<view v-if="dataList.length >= 2 " class="display-right1" :style="{ padding: `${itemStyle.paddingTop}px ${itemStyle.paddingLeft}px` }">
|
||||
<image class="image" @click="onLink(dataList[1].link)" :src="dataList[1].imgUrl"></image>
|
||||
</view>
|
||||
<view class="display-right2">
|
||||
<view v-if="dataList.length >= 3 " class="left" :style="{ padding: `${itemStyle.paddingTop}px ${itemStyle.paddingLeft}px` }">
|
||||
<image class="image" @click="onLink(dataList[2].link)" :src="dataList[2].imgUrl"></image>
|
||||
</view>
|
||||
<view v-if="dataList.length >= 4 " class="right" :style="{ padding: `${itemStyle.paddingTop}px ${itemStyle.paddingLeft}px` }">
|
||||
<image class="image" @click="onLink(dataList[3].link)" :src="dataList[3].imgUrl"></image>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import mixin from '../mixin'
|
||||
export default {
|
||||
name: "Window",
|
||||
|
||||
/**
|
||||
* 组件的属性列表
|
||||
* 用于组件自定义设置
|
||||
*/
|
||||
props: {
|
||||
itemIndex: String,
|
||||
itemStyle: Object,
|
||||
params: Object,
|
||||
dataList: Array
|
||||
},
|
||||
|
||||
mixins: [mixin],
|
||||
|
||||
/**
|
||||
* 组件的方法列表
|
||||
* 更新属性和数据的方法与更新页面数据的方法类似
|
||||
*/
|
||||
methods: {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.diy-window .data-list::after {
|
||||
clear: both;
|
||||
content: " ";
|
||||
display: table;
|
||||
}
|
||||
|
||||
.diy-window .data-list .data-item {
|
||||
float: left;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.diy-window .data-list .image {
|
||||
display: block;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* 分列布局 */
|
||||
|
||||
.diy-window .avg-sm-2>.data-item {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.diy-window .avg-sm-3>.data-item {
|
||||
width: 33.33333333%;
|
||||
}
|
||||
|
||||
.diy-window .avg-sm-4>.data-item {
|
||||
width: 25%;
|
||||
}
|
||||
|
||||
.diy-window .avg-sm-5>.data-item {
|
||||
width: 20%;
|
||||
}
|
||||
|
||||
/* 橱窗样式 */
|
||||
|
||||
.diy-window {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.diy-window .display {
|
||||
height: 0;
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
padding-bottom: 50%;
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.diy-window .display .image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.diy-window .display .display-left {
|
||||
width: 50%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.diy-window .display .display-right {
|
||||
width: 50%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 50%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.diy-window .display .display-right1 {
|
||||
width: 100%;
|
||||
height: 50%;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
box-sizing: border-box;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.diy-window .display .display-right2 {
|
||||
width: 100%;
|
||||
height: 50%;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.diy-window .display .display-right2 .left {
|
||||
width: 50%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.diy-window .display .display-right2 .right {
|
||||
width: 50%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 50%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
</style>
|
||||
156
components/page/index.vue
Executable file
156
components/page/index.vue
Executable file
@@ -0,0 +1,156 @@
|
||||
<template>
|
||||
<view class="page-items">
|
||||
<block v-for="(item, index) in items" :key="index">
|
||||
<!-- 搜索框 -->
|
||||
<block v-if="item.type === 'search'">
|
||||
<Search :itemStyle="item.style" :params="item.params" />
|
||||
</block>
|
||||
<!-- 图片组 -->
|
||||
<block v-if="item.type === 'image'">
|
||||
<Images :itemStyle="item.style" :params="item.params" :dataList="item.data" />
|
||||
</block>
|
||||
<!-- 轮播图 -->
|
||||
<block v-if="item.type === 'banner'">
|
||||
<Banner :itemStyle="item.style" :params="item.params" :dataList="item.data" />
|
||||
</block>
|
||||
<!-- 图片橱窗 -->
|
||||
<block v-if="item.type === 'window'">
|
||||
<Window :itemStyle="item.style" :params="item.params" :dataList="item.data" />
|
||||
</block>
|
||||
<!-- 视频 -->
|
||||
<block v-if="item.type === 'video'">
|
||||
<Videos :itemStyle="item.style" :params="item.params" />
|
||||
</block>
|
||||
<!-- 文章组 -->
|
||||
<block v-if="item.type === 'article'">
|
||||
<Article :params="item.params" :dataList="item.data" />
|
||||
</block>
|
||||
<!-- 店铺公告 -->
|
||||
<block v-if="item.type === 'notice'">
|
||||
<Notice :itemStyle="item.style" :params="item.params" />
|
||||
</block>
|
||||
<!-- 导航 -->
|
||||
<block v-if="item.type === 'navBar'">
|
||||
<NavBar :itemStyle="item.style" :params="item.params" :dataList="item.data" />
|
||||
</block>
|
||||
<!-- 商品 -->
|
||||
<block v-if="item.type === 'goods'">
|
||||
<Goods :itemStyle="item.style" :params="item.params" :dataList="item.data" />
|
||||
</block>
|
||||
<!-- 在线客服 -->
|
||||
<block v-if="item.type === 'service'">
|
||||
<Service :itemStyle="item.style" :params="item.params" />
|
||||
</block>
|
||||
<!-- 辅助空白 -->
|
||||
<block v-if="item.type === 'blank'">
|
||||
<Blank :itemStyle="item.style" />
|
||||
</block>
|
||||
<!-- 辅助线 -->
|
||||
<block v-if="item.type === 'guide'">
|
||||
<Guide :itemStyle="item.style" />
|
||||
</block>
|
||||
<!-- 富文本 -->
|
||||
<block v-if="item.type === 'richText'">
|
||||
<RichText :itemStyle="item.style" :params="item.params" />
|
||||
</block>
|
||||
<!-- 头条快报 -->
|
||||
<block v-if="item.type === 'special'">
|
||||
<Special :itemStyle="item.style" :params="item.params" :dataList="item.data" />
|
||||
</block>
|
||||
<!-- 关注公众号 -->
|
||||
<block v-if="item.type === 'officialAccount'">
|
||||
<DiyOfficialAccount />
|
||||
</block>
|
||||
<!-- 线下门店 -->
|
||||
<block v-if="item.type === 'shop'">
|
||||
<Shop :itemStyle="item.style" :params="item.params" :dataList="item.data" />
|
||||
</block>
|
||||
<!-- 优惠券 -->
|
||||
<block v-if="item.type === 'coupon'">
|
||||
<Coupon :itemStyle="item.style" :params="item.params" :dataList="item.data" />
|
||||
</block>
|
||||
<!-- 砍价商品 -->
|
||||
<block v-if="item.type === 'bargain'">
|
||||
<Bargain :itemStyle="item.style" :params="item.params" :dataList="item.data" />
|
||||
</block>
|
||||
<!-- 整点秒杀 -->
|
||||
<block v-if="item.type === 'sharp'">
|
||||
<Sharp :itemStyle="item.style" :params="item.params" :data="item.data" />
|
||||
</block>
|
||||
<!-- 拼团商品 -->
|
||||
<block v-if="item.type === 'groupon'">
|
||||
<Groupon :itemStyle="item.style" :params="item.params" :dataList="item.data" />
|
||||
</block>
|
||||
<!-- 图片组 -->
|
||||
<block v-if="item.type === 'hotZone'">
|
||||
<HotZone :itemStyle="item.style" :params="item.params" :data="item.data" />
|
||||
</block>
|
||||
</block>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Search from './diyComponents/search'
|
||||
import Images from './diyComponents/image'
|
||||
import Banner from './diyComponents/banner'
|
||||
import Window from './diyComponents/window'
|
||||
import HotZone from './diyComponents/hotZone'
|
||||
import Videos from './diyComponents/video'
|
||||
import Article from './diyComponents/article'
|
||||
import Notice from './diyComponents/notice'
|
||||
import NavBar from './diyComponents/navBar'
|
||||
import Goods from './diyComponents/goods'
|
||||
import Service from './diyComponents/service'
|
||||
import Blank from './diyComponents/blank'
|
||||
import Guide from './diyComponents/guide'
|
||||
import RichText from './diyComponents/richText'
|
||||
import Special from './diyComponents/special'
|
||||
import DiyOfficialAccount from './diyComponents/officialAccount'
|
||||
import Shop from './diyComponents/shop'
|
||||
import Coupon from './diyComponents/coupon'
|
||||
import Bargain from './diyComponents/bargain'
|
||||
import Sharp from './diyComponents/sharp'
|
||||
import Groupon from './diyComponents/groupon'
|
||||
|
||||
export default {
|
||||
name: "Page",
|
||||
components: {
|
||||
Search,
|
||||
Images,
|
||||
Banner,
|
||||
Window,
|
||||
HotZone,
|
||||
Videos,
|
||||
Article,
|
||||
Notice,
|
||||
NavBar,
|
||||
Goods,
|
||||
Service,
|
||||
Blank,
|
||||
Guide,
|
||||
RichText,
|
||||
Special,
|
||||
DiyOfficialAccount,
|
||||
Shop,
|
||||
Coupon,
|
||||
Bargain,
|
||||
Sharp,
|
||||
Groupon
|
||||
},
|
||||
/**
|
||||
* 组件的属性列表
|
||||
* 用于组件自定义设置
|
||||
*/
|
||||
props: {
|
||||
items: {
|
||||
type: Array,
|
||||
default () {
|
||||
return []
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style lang="scss">
|
||||
// 组件样式
|
||||
</style>
|
||||
Reference in New Issue
Block a user