feat:v1.4前端更新
This commit is contained in:
@@ -1,145 +0,0 @@
|
||||
<template>
|
||||
<view>
|
||||
<view class='Popup' v-if='isShowAuth'>
|
||||
<image :src='logoUrl'></image>
|
||||
<view class='title'>授权提醒</view>
|
||||
<view class='tip'>请授权头像等信息,以便为您提供更好的服务</view>
|
||||
<view class='bottom flex'>
|
||||
<view class='item' @click='close'>随便逛逛</view>
|
||||
<!-- #ifdef APP-PLUS -->
|
||||
<button class='item grant' @click="setUserInfo">去授权</button>
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef MP -->
|
||||
<button class='item grant' type="primary" open-type="getUserInfo" lang="zh_CN" @getuserinfo="setUserInfo">去授权</button>
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
</view>
|
||||
<view class='mask' v-if='isShowAuth' @click='close'></view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
const app = getApp();
|
||||
import Cache from '../utils/cache';
|
||||
import { getLogo } from '../api/public';
|
||||
import { LOGO_URL } from '../config/cache';
|
||||
import { mapGetters } from 'vuex';
|
||||
import Routine from '../libs/routine';
|
||||
|
||||
export default {
|
||||
name:'Authorize',
|
||||
props:{
|
||||
isAuto:{
|
||||
type:Boolean,
|
||||
default:true
|
||||
},
|
||||
isGoIndex:{
|
||||
type:Boolean,
|
||||
default:true
|
||||
},
|
||||
isShowAuth:{
|
||||
type:Boolean,
|
||||
default:false
|
||||
}
|
||||
},
|
||||
data(){
|
||||
return {
|
||||
logoUrl:''
|
||||
}
|
||||
},
|
||||
computed:mapGetters(['isLogin','userInfo']),
|
||||
watch:{
|
||||
isLogin(n){
|
||||
n === true && this.$emit('onLoadFun',this.userInfo);
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getLogoUrl();
|
||||
this.setAuthStatus();
|
||||
},
|
||||
methods:{
|
||||
setAuthStatus(){
|
||||
Routine.authorize().then(res=>{
|
||||
if(res.islogin === false)
|
||||
this.setUserInfo();
|
||||
else
|
||||
this.$emit('onLoadFun',this.userInfo);
|
||||
}).catch(res=>{
|
||||
if (this.isAuto)
|
||||
this.$emit('authColse',true);
|
||||
})
|
||||
},
|
||||
getUserInfo(code){
|
||||
Routine.getUserInfo().then(res=>{
|
||||
let userInfo = res.userInfo
|
||||
userInfo.code = code;
|
||||
userInfo.spread_spid = app.globalData.spid;//获取推广人ID
|
||||
userInfo.spread_code = app.globalData.code;//获取推广人分享二维码ID
|
||||
userInfo.avatar = userInfo.userInfo.avatarUrl;
|
||||
userInfo.city = userInfo.userInfo.city;
|
||||
userInfo.country = userInfo.userInfo.country;
|
||||
userInfo.nickName = userInfo.userInfo.nickName;
|
||||
userInfo.province = userInfo.userInfo.province;
|
||||
userInfo.sex = userInfo.userInfo.gender;
|
||||
Routine.authUserInfo(code,userInfo).then(res=>{
|
||||
uni.hideLoading();
|
||||
this.$emit('authColse',false);
|
||||
this.$emit('onLoadFun',this.userInfo);
|
||||
}).catch(res=>{
|
||||
uni.hideLoading();
|
||||
uni.showToast({
|
||||
title:res.message,
|
||||
icon:'none',
|
||||
duration:2000
|
||||
});
|
||||
})
|
||||
}).catch(res =>{
|
||||
uni.hideLoading();
|
||||
})
|
||||
},
|
||||
setUserInfo(){
|
||||
uni.showLoading({title:'正在登录中'});
|
||||
Routine.getCode().then(code=>{
|
||||
this.getUserInfo(code);
|
||||
}).catch(res=>{
|
||||
uni.hideLoading();
|
||||
})
|
||||
},
|
||||
getLogoUrl(){
|
||||
let that = this;
|
||||
if (Cache.has(LOGO_URL)) {
|
||||
this.logoUrl = Cache.get(LOGO_URL);
|
||||
return;
|
||||
}
|
||||
getLogo().then(res=>{
|
||||
that.logoUrl = res.data.logoUrl
|
||||
Cache.set(LOGO_URL,that.logoUrl);
|
||||
})
|
||||
},
|
||||
close(){
|
||||
let pages = getCurrentPages(), currPage = pages[pages.length - 1];
|
||||
if(this.isGoIndex){
|
||||
uni.switchTab({url:'/pages/index/index'});
|
||||
} else {
|
||||
this.$emit('authColse',false);
|
||||
}
|
||||
// if (currPage && currPage.isShowAuth != undefined){
|
||||
// currPage.isShowAuth = true;
|
||||
// }
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang='scss'>
|
||||
.Popup{width:500rpx;background-color:#fff;position:fixed;top:50%;left:50%;margin-left:-250rpx;transform:translateY(-50%);z-index:320;}
|
||||
.Popup image{width:150rpx;height:150rpx;margin:-67rpx auto 0 auto;display:block;border: 8rpx solid #fff;border-radius: 50%}
|
||||
.Popup .title{font-size:28rpx;color:#000;text-align:center;margin-top: 30rpx}
|
||||
.Popup .tip{font-size:22rpx;color:#555;padding:0 24rpx;margin-top:25rpx;}
|
||||
.Popup .bottom .item{width:50%;height:80rpx;background-color:#eeeeee;text-align:center;line-height:80rpx;font-size:24rpx;color:#666;margin-top:54rpx;}
|
||||
.Popup .bottom .item.on{width: 100%}
|
||||
.flex{display:flex;}
|
||||
.Popup .bottom .item.grant{font-size:28rpx;color:#fff;font-weight:bold;background-color:$theme-color;border-radius:0;padding:0;}
|
||||
.mask{position:fixed;top:0;right:0;left:0;bottom:0;background-color:rgba(0,0,0,0.65);z-index:310;}
|
||||
|
||||
</style>
|
||||
@@ -1,173 +0,0 @@
|
||||
<template>
|
||||
<view>
|
||||
<view class="priceChange" :class="change === true ? 'on' : ''">
|
||||
<view class="priceTitle">
|
||||
{{
|
||||
status == 0
|
||||
? orderInfo.refund_status === 1
|
||||
? "立即退款"
|
||||
: "一键改价"
|
||||
: "订单备注"
|
||||
}}
|
||||
<span class="iconfont icon-guanbi" @click="close"></span>
|
||||
</view>
|
||||
<view class="listChange" v-if="status == 0">
|
||||
<view
|
||||
class="item acea-row row-between-wrapper"
|
||||
v-if="orderInfo.refund_status === 0"
|
||||
>
|
||||
<view>商品总价(¥)</view>
|
||||
<view class="money">
|
||||
{{ orderInfo.total_price }}<span class="iconfont icon-suozi"></span>
|
||||
</view>
|
||||
</view>
|
||||
<view
|
||||
class="item acea-row row-between-wrapper"
|
||||
v-if="orderInfo.refund_status === 0"
|
||||
>
|
||||
<view>原始邮费(¥)</view>
|
||||
<view class="money">
|
||||
{{ orderInfo.pay_postage }}<span class="iconfont icon-suozi"></span>
|
||||
</view>
|
||||
</view>
|
||||
<view
|
||||
class="item acea-row row-between-wrapper"
|
||||
v-if="orderInfo.refund_status === 0"
|
||||
>
|
||||
<view>实际支付(¥)</view>
|
||||
<view class="money">
|
||||
<input
|
||||
type="text"
|
||||
v-model="price"
|
||||
:class="focus === true ? 'on' : ''"
|
||||
@focus="priceChange"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
<view
|
||||
class="item acea-row row-between-wrapper"
|
||||
v-if="orderInfo.refund_status === 1"
|
||||
>
|
||||
<view>实际支付(¥)</view>
|
||||
<view class="money">
|
||||
{{ orderInfo.pay_price }}<span class="iconfont icon-suozi"></span>
|
||||
</view>
|
||||
</view>
|
||||
<view
|
||||
class="item acea-row row-between-wrapper"
|
||||
v-if="orderInfo.refund_status === 1"
|
||||
>
|
||||
<view>退款金额(¥)</view>
|
||||
<view class="money">
|
||||
<input
|
||||
type="text"
|
||||
v-model="refund_price"
|
||||
:class="focus === true ? 'on' : ''"
|
||||
@focus="priceChange"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="listChange" v-else>
|
||||
<textarea
|
||||
:placeholder="
|
||||
orderInfo.remark ? orderInfo.remark : '请填写备注信息...'
|
||||
"
|
||||
v-model="remark"
|
||||
></textarea>
|
||||
</view>
|
||||
<view class="modify" @click="save">
|
||||
{{
|
||||
status === 1 || orderInfo.refund_status == 0 ? "立即修改" : "确认退款"
|
||||
}}
|
||||
</view>
|
||||
<view
|
||||
class="modify1"
|
||||
@click="refuse"
|
||||
v-if="orderInfo.refund_status == 1 && status == 0"
|
||||
>
|
||||
拒绝退款
|
||||
</view>
|
||||
</view>
|
||||
<view class="mask" @touchmove.prevent v-show="change === true"></view>
|
||||
</view>
|
||||
</template>
|
||||
<style>
|
||||
.priceChange{position:fixed;width:580upx;height:670upx;background-color:#fff;border-radius:10upx;top:50%;left:50%;margin-left:-290upx;margin-top:-335upx;z-index:666;transition:all 0.3s ease-in-out 0s;transform: scale(0);opacity:0;}
|
||||
.priceChange.on{opacity:1;transform: scale(1);}
|
||||
.priceChange .priceTitle{background:url("~@/static/images/pricetitle.jpg") no-repeat;background-size:100% 100%;width:100%;height:160upx;border-radius:10upx 10upx 0 0;text-align:center;font-size:40upx;color:#fff;line-height:160upx;position:relative;}
|
||||
.priceChange .priceTitle .iconfont{position:absolute;font-size:40upx;right:26upx;top:23upx;width:40upx;height:40upx;line-height:40upx;}
|
||||
.priceChange .listChange{padding:0 40upx;}
|
||||
.priceChange .listChange textarea{box-sizing: border-box;}
|
||||
.priceChange .listChange .item{height:103upx;border-bottom:1px solid #e3e3e3;font-size:32upx;color:#333;}
|
||||
.priceChange .listChange .item .money{color:#666;width:300upx;text-align:right;}
|
||||
.priceChange .listChange .item .money .iconfont{font-size:32upx;margin-left:20upx;}
|
||||
.priceChange .listChange .item .money input{width:100%;height:100%;text-align:right;color:#ccc;}
|
||||
.priceChange .listChange .item .money input.on{color:#666;}
|
||||
.priceChange .modify{font-size:32upx;color:#fff;width:490upx;height:90upx;text-align:center;line-height:90upx;border-radius:45upx;background-color:#2291f8;margin:53upx auto 0 auto;}
|
||||
.priceChange .modify1{font-size:32upx;color:#312b2b;width:490upx;height:90upx;text-align:center;line-height:90upx;border-radius:45upx;background-color:#eee;margin:30upx auto 0 auto;}
|
||||
.priceChange .listChange textarea {
|
||||
border: 1px solid #eee;
|
||||
width: 100%;
|
||||
height: 200upx;
|
||||
margin-top: 50upx;
|
||||
border-radius: 10upx;
|
||||
color: #333;
|
||||
padding: 20upx;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
export default {
|
||||
name: "PriceChange",
|
||||
components: {},
|
||||
props: {
|
||||
change: Boolean,
|
||||
orderInfo: Object,
|
||||
status: String
|
||||
},
|
||||
data: function() {
|
||||
return {
|
||||
focus: false,
|
||||
price: 0,
|
||||
refund_price: 0,
|
||||
remark: ""
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
orderInfo: function(nVal) {
|
||||
this.price = this.orderInfo.pay_price;
|
||||
this.refund_price = this.orderInfo.pay_price;
|
||||
this.remark = "";
|
||||
}
|
||||
},
|
||||
mounted: function() {
|
||||
},
|
||||
methods: {
|
||||
priceChange: function() {
|
||||
this.focus = true;
|
||||
},
|
||||
close: function() {
|
||||
this.price = this.orderInfo.pay_price;
|
||||
this.$emit("closechange", false);
|
||||
},
|
||||
save: function() {
|
||||
let that = this;
|
||||
that.$emit("savePrice", {
|
||||
price: that.price,
|
||||
refund_price: that.refund_price,
|
||||
type: 1,
|
||||
remark: that.remark
|
||||
});
|
||||
},
|
||||
refuse: function() {
|
||||
let that = this;
|
||||
that.$emit("savePrice", {
|
||||
price: that.price,
|
||||
refund_price: that.refund_price,
|
||||
type: 2,
|
||||
remark: that.remark
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
210
app/components/WaterfallsFlow/WaterfallsFlow.vue
Normal file
210
app/components/WaterfallsFlow/WaterfallsFlow.vue
Normal file
@@ -0,0 +1,210 @@
|
||||
<template>
|
||||
<view class="wf-page">
|
||||
<!-- left -->
|
||||
<view>
|
||||
<view id="left" v-if="leftList.length">
|
||||
<view v-for="(item,index) in leftList" :key="index" class="wf-item">
|
||||
<WaterfallsFlowItem :item="item" :isStore="isStore" :type="type"/>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- right -->
|
||||
<view>
|
||||
<view id="right" v-if="rightList.length">
|
||||
<view v-for="(item,index) in rightList" :key="index" class="wf-item">
|
||||
<WaterfallsFlowItem :item="item" :isStore="isStore" :type="type"/>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
import WaterfallsFlowItem from '../WaterfallsFlowItem/WaterfallsFlowItem.vue'
|
||||
export default {
|
||||
components: {
|
||||
WaterfallsFlowItem,
|
||||
},
|
||||
props: {
|
||||
// 区分从发现列表、我的主页作品进去,点进去内容列表,home从我的主页点进去
|
||||
fromTo: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
// 区分瀑布流使用子组件,1逛逛瀑布流
|
||||
fromType: {
|
||||
type: Number || String,
|
||||
default: 0
|
||||
},
|
||||
// 瀑布流列表
|
||||
wfList: {
|
||||
type: Array || String,
|
||||
require: true
|
||||
},
|
||||
updateNum: {
|
||||
type: Number,
|
||||
default: 10
|
||||
},
|
||||
type: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
isStore: {
|
||||
type: Number,
|
||||
default: 0
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
allList: [], // 全部列表
|
||||
leftList: [], // 左边列表
|
||||
rightList: [], // 右边列表
|
||||
mark: 0, // 列表标记
|
||||
boxHeight: [], // 下标0和1分别为左列和右列高度
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
// 监听列表数据变化
|
||||
wfList: {
|
||||
handler(nVal, oVal) {
|
||||
// 如果数据为空或新的列表数据少于旧的列表数据(通常为下拉刷新或切换排序或使用筛选器),初始化变量
|
||||
if (!this.wfList.length ||
|
||||
(this.wfList.length === this.updateNum && this.wfList.length <= this.allList.length)) {
|
||||
this.allList = [];
|
||||
this.leftList = [];
|
||||
this.rightList = [];
|
||||
this.boxHeight = [];
|
||||
this.mark = 0;
|
||||
}
|
||||
|
||||
// 如果列表有值,调用waterfall方法
|
||||
if (this.wfList.length) {
|
||||
this.allList = this.wfList;
|
||||
this.leftList = [];
|
||||
this.rightList = [];
|
||||
this.boxHeight = [];
|
||||
this.allList.forEach((v, i) => {
|
||||
if (this.allList.length < 3 || (this.allList.length <= 7 && this.allList.length - i >
|
||||
1) || (this.allList.length > 7 && this.allList.length - i > 2)) {
|
||||
if (i % 2) {
|
||||
this.rightList.push(v);
|
||||
} else {
|
||||
this.leftList.push(v);
|
||||
}
|
||||
}
|
||||
});
|
||||
if (this.allList.length < 3) {
|
||||
this.mark = this.allList.length + 1;
|
||||
} else if (this.allList.length <= 7) {
|
||||
this.mark = this.allList.length - 1;
|
||||
} else {
|
||||
this.mark = this.allList.length - 2;
|
||||
}
|
||||
if (this.mark < this.allList.length) {
|
||||
this.waterFall()
|
||||
}
|
||||
}
|
||||
},
|
||||
immediate: true,
|
||||
deep: true
|
||||
},
|
||||
// 监听标记,当标记发生变化,则执行下一个item排序
|
||||
mark() {
|
||||
const len = this.allList.length;
|
||||
if (this.mark < len && this.mark !== 0 && this.boxHeight.length) {
|
||||
this.waterFall();
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 瀑布流排序
|
||||
waterFall() {
|
||||
const i = this.mark;
|
||||
if (i == 0) {
|
||||
// 初始化,从左边开始插入
|
||||
this.leftList.push(this.allList[i]);
|
||||
// 更新左边列表高度
|
||||
this.getViewHeight(0);
|
||||
} else if (i == 1) {
|
||||
// 第二个item插入,默认为右边插入
|
||||
this.rightList.push(this.allList[i]);
|
||||
// 更新右边列表高度
|
||||
this.getViewHeight(1);
|
||||
} else {
|
||||
// 根据左右列表高度判断下一个item应该插入哪边
|
||||
if (!this.boxHeight.length) {
|
||||
this.rightList.length < this.leftList.length ?
|
||||
this.rightList.push(this.allList[i]) :
|
||||
this.leftList.push(this.allList[i]);
|
||||
} else {
|
||||
const leftOrRight = this.boxHeight[0] > this.boxHeight[1] ? 1 : 0;
|
||||
if (leftOrRight) {
|
||||
this.rightList.push(this.allList[i])
|
||||
} else {
|
||||
this.leftList.push(this.allList[i])
|
||||
}
|
||||
}
|
||||
// 更新插入列表高度
|
||||
this.getViewHeight();
|
||||
}
|
||||
},
|
||||
// 获取列表高度
|
||||
getViewHeight() {
|
||||
// 使用nextTick,确保页面更新结束后,再请求高度
|
||||
this.$nextTick(() => {
|
||||
setTimeout(() => {
|
||||
uni.createSelectorQuery().in(this).select('#right').boundingClientRect(res => {
|
||||
res ? this.boxHeight[1] = res.height : '';
|
||||
uni.createSelectorQuery().in(this).select('#left').boundingClientRect(
|
||||
res => {
|
||||
res ? this.boxHeight[0] = res.height : '';
|
||||
this.mark = this.mark + 1;
|
||||
}).exec();
|
||||
}).exec();
|
||||
}, 100)
|
||||
})
|
||||
},
|
||||
// item点击
|
||||
itemTap(item) {
|
||||
this.$emit('itemTap', item)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
$page-padding: 12px;
|
||||
$grid-gap: 24rpx;
|
||||
|
||||
.wf-page {
|
||||
padding: 0 20rpx;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
grid-gap: $grid-gap;
|
||||
}
|
||||
|
||||
.wf-item {
|
||||
width: calc((100vw - 2 * #{$page-padding} - #{$grid-gap}) / 2);
|
||||
padding-bottom: $grid-gap;
|
||||
//margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.wf-page1 .wf-item {
|
||||
background-color: #fff;
|
||||
border-radius: 20rpx;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
.wf-item-page {
|
||||
padding-bottom: 20rpx;
|
||||
}
|
||||
</style>
|
||||
236
app/components/WaterfallsFlowItem/WaterfallsFlowItem.vue
Normal file
236
app/components/WaterfallsFlowItem/WaterfallsFlowItem.vue
Normal file
@@ -0,0 +1,236 @@
|
||||
<template>
|
||||
<view class='list acea-row row-between-wrapper' :data-theme="theme">
|
||||
<view class='item' hover-class='none' @click="goDetail(item)">
|
||||
<view class='pictrue'>
|
||||
<easy-loadimage mode="widthFix" :image-src="item.image"></easy-loadimage>
|
||||
<view v-if="item.activityStyle" :style="{ backgroundImage: `url(${item.activityStyle})` }"
|
||||
class="border-picture"></view>
|
||||
</view>
|
||||
<view class='texts'>
|
||||
<view class='names line2'>
|
||||
{{item.storeName}}
|
||||
</view>
|
||||
<view class='money mt-20'>
|
||||
<view class="acea-row row-middle price">
|
||||
<view>
|
||||
¥<span class="num">{{item.price}}</span>
|
||||
</view>
|
||||
</view>
|
||||
<view class="sold mt-18">
|
||||
<text v-if="Math.floor(item.replyNum)>0" class="regular">{{item.replyNum}}条评论</text>
|
||||
<text v-if="item.replyNum===0">暂无评论</text>
|
||||
<text v-if="Number(item.positiveRatio)>0"
|
||||
class="m-l-8">好评{{$util.$h.Mul(item.positiveRatio, 100)}}%</text>
|
||||
|
||||
</view>
|
||||
<view class="sold">已售 {{ item.sales }} {{item.unitName}}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
import easyLoadimage from '@/components/base/easy-loadimage.vue';
|
||||
let app = getApp();
|
||||
export default {
|
||||
components: {
|
||||
easyLoadimage,
|
||||
},
|
||||
props: {
|
||||
item: {
|
||||
type: Object,
|
||||
require: true
|
||||
},
|
||||
type: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
isStore: {
|
||||
type: [String, Number],
|
||||
default: '1'
|
||||
},
|
||||
isLogin: {
|
||||
type: Boolean,
|
||||
require: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
theme: app.globalData.theme,
|
||||
//普通价格
|
||||
svipPriceStyle: {
|
||||
svipBox: {
|
||||
height: '26rpx',
|
||||
borderRadius: '60rpx 56rpx 56rpx 20rpx',
|
||||
},
|
||||
icon: {
|
||||
height: '26rpx',
|
||||
fontSize: '18rpx',
|
||||
borderRadius: '12rpx 0 12rpx 2rpx'
|
||||
},
|
||||
price: {
|
||||
fontSize: '38rpx'
|
||||
},
|
||||
svipPrice: {
|
||||
fontSize: '22rpx'
|
||||
}
|
||||
},
|
||||
//svip价格
|
||||
svipIconStyle: {
|
||||
svipBox: {
|
||||
height: '26rpx',
|
||||
borderRadius: '24rpx 40rpx 40rpx 0.4rpx',
|
||||
},
|
||||
price: {
|
||||
fontSize: '38rpx'
|
||||
},
|
||||
svipPrice: {
|
||||
fontSize: '18rpx'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 去详情页
|
||||
goDetail(item) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/goods/goods_details/index?id=${item.id}`
|
||||
})
|
||||
},
|
||||
authOpen() {
|
||||
this.$emit('authOpen');
|
||||
},
|
||||
followToggle(item) {
|
||||
this.$emit('followToggle', item);
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.tagSolid {
|
||||
margin-bottom: 4rpx;
|
||||
}
|
||||
|
||||
.merType {
|
||||
@include main_bg_color(theme);
|
||||
}
|
||||
|
||||
.list {
|
||||
.item {
|
||||
width: 100%;
|
||||
|
||||
.pictrue {
|
||||
|
||||
/deep/image,
|
||||
/deep/.easy-loadimage,
|
||||
uni-image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 20rpx 20rpx 0 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.texts {
|
||||
padding: 16rpx;
|
||||
font-size: 30rpx;
|
||||
color: #222;
|
||||
|
||||
.names {
|
||||
font-size: 28rpx;
|
||||
font-weight: 400;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.money {
|
||||
.price {
|
||||
@include price_color(theme);
|
||||
}
|
||||
|
||||
.num {
|
||||
font-size: 38rpx;
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
.y-money {
|
||||
font-size: 26rpx;
|
||||
color: #888888;
|
||||
text-decoration: line-through;
|
||||
margin-left: 14rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.company {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 26rpx;
|
||||
|
||||
.name {
|
||||
width: 210rpx;
|
||||
display: inline-block;
|
||||
color: #666 !important;
|
||||
height: auto !important;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
margin-bottom: 0 !important;
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
|
||||
.flex {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: #282828 !important;
|
||||
|
||||
.iconfont {
|
||||
font-size: 16rpx;
|
||||
margin-top: 4rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.sold {
|
||||
font-size: 22rpx;
|
||||
color: #666;
|
||||
margin-bottom: 4rpx;
|
||||
}
|
||||
|
||||
.m-l-8 {
|
||||
margin-left: 8rpx;
|
||||
}
|
||||
|
||||
.list .item .pictrue,
|
||||
.easy-loadimage,
|
||||
image,
|
||||
uni-image {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 330rpx;
|
||||
border-radius: 16rpx 16rpx 0 0;
|
||||
overflow: hidden;
|
||||
|
||||
/deep/.easy-loadimage,
|
||||
uni-image,
|
||||
image {
|
||||
height: 330rpx;
|
||||
border-radius: 16rpx 16rpx 0 0;
|
||||
}
|
||||
|
||||
margin: 0 !important;
|
||||
}
|
||||
</style>
|
||||
207
app/components/accredit/index.vue
Normal file
207
app/components/accredit/index.vue
Normal file
File diff suppressed because one or more lines are too long
@@ -1,185 +0,0 @@
|
||||
<template>
|
||||
<view>
|
||||
<view class="address-window" :class="address.address==true?'on':''">
|
||||
<view class='title'>选择地址<text class='iconfont icon-guanbi' @tap='close'></text></view>
|
||||
<view class='list'>
|
||||
<view class='item acea-row row-between-wrapper' :class='active==index?"font-color":""' v-for="(item,index) in addressList"
|
||||
@tap='tapAddress(index,item.id)' :key='index'>
|
||||
<text class='iconfont icon-ditu' :class='active==index?"font-color":""'></text>
|
||||
<view class='address'>
|
||||
<view class='name' :class='active==index?"font-color":""'>{{item.real_name}}<text class='phone'>{{item.phone}}</text></view>
|
||||
<view class='line1'>{{item.province}}{{item.city}}{{item.district}}{{item.detail}}</view>
|
||||
</view>
|
||||
<text class='iconfont icon-complete' :class='active==index?"font-color":""'></text>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 无地址 -->
|
||||
<view class='pictrue' v-if="!is_loading && !addressList.length">
|
||||
<image src='../../static/images/noAddress.png'></image>
|
||||
</view>
|
||||
<view class='addressBnt bg-color' @tap='goAddressPages'>选择其地址</view>
|
||||
</view>
|
||||
<view class='mask' catchtouchmove="true" :hidden='address.address==false' @tap='close'></view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
getAddressList
|
||||
} from '@/api/user.js';
|
||||
export default {
|
||||
props: {
|
||||
pagesUrl: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
address: {
|
||||
type: Object,
|
||||
default: function() {
|
||||
return {
|
||||
address: true,
|
||||
addressId: 0,
|
||||
};
|
||||
}
|
||||
},
|
||||
isLog: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
active: 0,
|
||||
//地址列表
|
||||
addressList: [],
|
||||
is_loading: true
|
||||
};
|
||||
},
|
||||
|
||||
methods: {
|
||||
tapAddress: function(e, addressid) {
|
||||
this.active = e;
|
||||
this.$emit('OnChangeAddress', addressid);
|
||||
},
|
||||
close: function() {
|
||||
this.$emit('changeClose');
|
||||
this.$emit('changeTextareaStatus');
|
||||
},
|
||||
goAddressPages: function() {
|
||||
this.$emit('changeClose');
|
||||
this.$emit('changeTextareaStatus');
|
||||
uni.navigateTo({
|
||||
url: this.pagesUrl
|
||||
});
|
||||
|
||||
},
|
||||
getAddressList: function() {
|
||||
let that = this;
|
||||
getAddressList({
|
||||
page: 1,
|
||||
limit: 5
|
||||
}).then(res => {
|
||||
let addressList = res.data;
|
||||
//处理默认选中项
|
||||
for (let i = 0, leng = addressList.length; i < leng; i++) {
|
||||
if (addressList[i].id == that.address.addressId) {
|
||||
that.active = i;
|
||||
}
|
||||
}
|
||||
that.$set(that, 'addressList', addressList);
|
||||
that.is_loading = false;
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.address-window {
|
||||
background-color: #fff;
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
z-index: 101;
|
||||
transform: translate3d(0, 100%, 0);
|
||||
transition: all .3s cubic-bezier(.25, .5, .5, .9);
|
||||
}
|
||||
|
||||
.address-window.on {
|
||||
transform: translate3d(0, 0, 0);
|
||||
}
|
||||
|
||||
.address-window .title {
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
height: 123rpx;
|
||||
line-height: 123rpx;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.address-window .title .iconfont {
|
||||
position: absolute;
|
||||
right: 30rpx;
|
||||
color: #8a8a8a;
|
||||
font-size: 35rpx;
|
||||
}
|
||||
|
||||
.address-window .list .item {
|
||||
margin-left: 30rpx;
|
||||
padding-right: 30rpx;
|
||||
border-bottom: 1px solid #eee;
|
||||
height: 129rpx;
|
||||
font-size: 25rpx;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.address-window .list .item .iconfont {
|
||||
font-size: 37rpx;
|
||||
color: #2c2c2c;
|
||||
}
|
||||
|
||||
.address-window .list .item .iconfont.icon-complete {
|
||||
font-size: 30rpx;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.address-window .list .item .address {
|
||||
width: 560rpx;
|
||||
}
|
||||
|
||||
.address-window .list .item .address .name {
|
||||
font-size: 28rpx;
|
||||
font-weight: bold;
|
||||
color: #282828;
|
||||
margin-bottom: 4rpx;
|
||||
}
|
||||
|
||||
.address-window .list .item .address .name .phone {
|
||||
margin-left: 18rpx;
|
||||
}
|
||||
|
||||
.address-window .addressBnt {
|
||||
font-size: 30rpx;
|
||||
font-weight: bold;
|
||||
color: #fff;
|
||||
width: 690rpx;
|
||||
height: 86rpx;
|
||||
border-radius: 43rpx;
|
||||
text-align: center;
|
||||
line-height: 86rpx;
|
||||
margin: 85rpx auto;
|
||||
}
|
||||
|
||||
.address-window .pictrue {
|
||||
width: 414rpx;
|
||||
height: 336rpx;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.address-window .pictrue image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
174
app/components/add-tips/index.vue
Normal file
174
app/components/add-tips/index.vue
Normal file
@@ -0,0 +1,174 @@
|
||||
<template>
|
||||
<!-- 小程序顶部提示 -->
|
||||
<view>
|
||||
<view class="tip_box" :class="{ anScale: isAm }" v-if="showTip"
|
||||
:style="{ top: isCustom ? boxTop + 'px' : '0px' }">
|
||||
<view class="arrow" :style="{ 'margin-right': arrowMargin + 'px', borderBottomColor: bgColor }"></view>
|
||||
<view class="container" :style="{'margin-right': cotainerMargin + 'px',backgroundColor: bgColor,borderRadius: borderR + 'px',}">
|
||||
<!-- 提示文字 -->
|
||||
<view class="tips" :style="{ color: fontObj.color, fontSize: fontObj.fontSize, fontWeight: fontObj.fontWeight }">
|
||||
{{ text }}</view>
|
||||
<view class="close" @tap="tipHidden">
|
||||
<text class="iconfont icon-cha3" v-if="closeColor"></text>
|
||||
<text class="iconfont icon-cha3" style="color:#fff;" v-else></text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
showTip: false,
|
||||
boxTop: 0,
|
||||
arrowMargin: 0,
|
||||
cotainerMargin: 0,
|
||||
screenWidth: 0,
|
||||
};
|
||||
},
|
||||
props: {
|
||||
/* 是否是自定义头部 */
|
||||
isCustom: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
/* 背景颜色 */
|
||||
bgColor: {
|
||||
type: String,
|
||||
default: "#ffffff",
|
||||
},
|
||||
/* 提示文字 */
|
||||
text: {
|
||||
type: String,
|
||||
default: "添加到我的小程序",
|
||||
},
|
||||
/* 提示文字样式 */
|
||||
fontObj: {
|
||||
type: Object,
|
||||
default: function() {
|
||||
return {
|
||||
color: "#202020",
|
||||
fontSize: "12px",
|
||||
fontWeight: "0",
|
||||
};
|
||||
},
|
||||
},
|
||||
/* 圆角大小 px*/
|
||||
borderR: {
|
||||
type: Number,
|
||||
default: 5,
|
||||
},
|
||||
/* 延时出现 */
|
||||
delay: {
|
||||
type: Number,
|
||||
default: 2000,
|
||||
},
|
||||
/* 关闭btn黑白两色 或者自行添加 */
|
||||
closeColor: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
/* 动画效果 */
|
||||
isAm: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
tipHidden: function() {
|
||||
uni.setStorageSync("my_tips_2020", "true");
|
||||
this.showTip = false;
|
||||
},
|
||||
timeOut() {
|
||||
this.tipHidden();
|
||||
this.showTip = true;
|
||||
// setTimeout(() => {
|
||||
|
||||
// setTimeout(() => {
|
||||
// this.tipHidden();
|
||||
// }, this.delay + 2000);
|
||||
// }, this.delay);
|
||||
},
|
||||
init() {
|
||||
if (uni.getStorageSync("my_tips_2020")) return;
|
||||
let rect = uni.getMenuButtonBoundingClientRect();
|
||||
let screenWidth = uni.getSystemInfoSync().screenWidth;
|
||||
this.boxTop = rect.bottom;
|
||||
this.arrowMargin = rect.width * 0.75 + 4;
|
||||
this.cotainerMargin = screenWidth - rect.right;
|
||||
this.timeOut();
|
||||
},
|
||||
},
|
||||
onReady() {
|
||||
this.init();
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@keyframes anScale {
|
||||
from {
|
||||
-webkit-transform: scale3d(0.96, 0.96, 0.96);
|
||||
transform: scale3d(0.96, 0.96, 0.96);
|
||||
}
|
||||
|
||||
50% {
|
||||
-webkit-transform: scale3d(1, 1, 1);
|
||||
transform: scale3d(1, 1, 1);
|
||||
}
|
||||
|
||||
to {
|
||||
-webkit-transform: scale3d(0.96, 0.96, 0.96);
|
||||
transform: scale3d(0.96, 0.96, 0.96);
|
||||
}
|
||||
}
|
||||
|
||||
.anScale {
|
||||
animation: anScale 1s linear infinite;
|
||||
}
|
||||
|
||||
.tip_box {
|
||||
width: 70%;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
z-index: 100;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: flex-end;
|
||||
flex-direction: column;
|
||||
|
||||
.arrow {
|
||||
width: 0;
|
||||
height: 0;
|
||||
border: 10rpx solid;
|
||||
border-color: transparent;
|
||||
}
|
||||
|
||||
.container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 16rpx 24rpx;
|
||||
|
||||
.tips {
|
||||
flex: 1;
|
||||
padding-right: 12rpx;
|
||||
}
|
||||
|
||||
.close {
|
||||
height: 30rpx;
|
||||
width: 30rpx;
|
||||
font-size: 20rpx;
|
||||
line-height: 30rpx;
|
||||
color: #999;
|
||||
.closeImg {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,193 +0,0 @@
|
||||
<template>
|
||||
<view>
|
||||
<view class="address-window" :class="address.address==true?'on':''">
|
||||
<view class='title'>选择地址<text class='iconfont icon-guanbi' @tap='close'></text></view>
|
||||
<view class='list'>
|
||||
<view class='item acea-row row-between-wrapper' :class='active==index?"font-color":""' v-for="(item,index) in addressList"
|
||||
@tap='tapAddress(index,item.id)' :key='index'>
|
||||
<text class='iconfont icon-ditu' :class='active==index?"font-color":""'></text>
|
||||
<view class='address'>
|
||||
<view class='name' :class='active==index?"font-color":""'>{{item.realName}}<text class='phone'>{{item.phone}}</text></view>
|
||||
<view class='line1'>{{item.province}}{{item.city}}{{item.district}}{{item.detail}}</view>
|
||||
</view>
|
||||
<text class='iconfont icon-complete' :class='active==index?"font-color":""'></text>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 无地址 -->
|
||||
<view class='pictrue' v-if="!is_loading && !addressList.length">
|
||||
<image src='../../static/images/noAddress.png'></image>
|
||||
</view>
|
||||
<view class='addressBnt bg-color' @tap='goAddressPages'>选择其地址</view>
|
||||
</view>
|
||||
<view class='mask' catchtouchmove="true" :hidden='address.address==false' @tap='close'></view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
getAddressList
|
||||
} from '@/api/user.js';
|
||||
export default {
|
||||
props: {
|
||||
pagesUrl: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
address: {
|
||||
type: Object,
|
||||
default: function() {
|
||||
return {
|
||||
address: true,
|
||||
addressId: 0,
|
||||
};
|
||||
}
|
||||
},
|
||||
isLog: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
active: 0,
|
||||
is_loading: true,
|
||||
addressList: []
|
||||
};
|
||||
},
|
||||
|
||||
methods: {
|
||||
tapAddress: function(e, addressid) {
|
||||
this.active = e;
|
||||
let a = {};
|
||||
for (let i = 0, leng = this.addressList.length; i < leng; i++) {
|
||||
if (this.addressList[i].id == addressid) {
|
||||
a = this.addressList[i];
|
||||
}
|
||||
}
|
||||
this.$emit('OnChangeAddress', a);
|
||||
},
|
||||
close: function() {
|
||||
this.$emit('changeClose');
|
||||
this.$emit('changeTextareaStatus');
|
||||
},
|
||||
goAddressPages: function() {
|
||||
this.$emit('changeClose');
|
||||
this.$emit('changeTextareaStatus');
|
||||
uni.navigateTo({
|
||||
url: this.pagesUrl
|
||||
});
|
||||
},
|
||||
getAddressList: function() {
|
||||
let that = this;
|
||||
getAddressList({
|
||||
page: 1,
|
||||
limit: 5
|
||||
}).then(res => {
|
||||
let addressList = res.data.list;
|
||||
that.$set(that, 'addressList', addressList);
|
||||
that.is_loading = false;
|
||||
let defaultAddress = {};
|
||||
//处理默认选中项
|
||||
if(!that.address.addressId) return;
|
||||
for (let i = 0, leng = addressList.length; i < leng; i++) {
|
||||
if (addressList[i].id == that.address.addressId) {
|
||||
that.active = i;
|
||||
defaultAddress = this.addressList[i];
|
||||
}
|
||||
}
|
||||
this.$emit('OnDefaultAddress', defaultAddress);
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.address-window {
|
||||
background-color: #fff;
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
z-index: 101;
|
||||
transform: translate3d(0, 100%, 0);
|
||||
transition: all .3s cubic-bezier(.25, .5, .5, .9);
|
||||
}
|
||||
|
||||
.address-window.on {
|
||||
transform: translate3d(0, 0, 0);
|
||||
}
|
||||
|
||||
.address-window .title {
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
height: 123rpx;
|
||||
line-height: 123rpx;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.address-window .title .iconfont {
|
||||
position: absolute;
|
||||
right: 30rpx;
|
||||
color: #8a8a8a;
|
||||
font-size: 35rpx;
|
||||
}
|
||||
|
||||
.address-window .list .item {
|
||||
margin-left: 30rpx;
|
||||
padding-right: 30rpx;
|
||||
border-bottom: 1px solid #eee;
|
||||
height: 129rpx;
|
||||
font-size: 25rpx;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.address-window .list .item .iconfont {
|
||||
font-size: 37rpx;
|
||||
color: #2c2c2c;
|
||||
}
|
||||
|
||||
.address-window .list .item .iconfont.icon-complete {
|
||||
font-size: 30rpx;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.address-window .list .item .address {
|
||||
width: 560rpx;
|
||||
}
|
||||
|
||||
.address-window .list .item .address .name {
|
||||
font-size: 28rpx;
|
||||
font-weight: bold;
|
||||
color: #282828;
|
||||
margin-bottom: 4rpx;
|
||||
}
|
||||
|
||||
.address-window .list .item .address .name .phone {
|
||||
margin-left: 18rpx;
|
||||
}
|
||||
|
||||
.address-window .addressBnt {
|
||||
font-size: 30rpx;
|
||||
font-weight: bold;
|
||||
color: #fff;
|
||||
width: 690rpx;
|
||||
height: 86rpx;
|
||||
border-radius: 43rpx;
|
||||
text-align: center;
|
||||
line-height: 86rpx;
|
||||
margin: 85rpx auto;
|
||||
}
|
||||
|
||||
.address-window .pictrue {
|
||||
width: 414rpx;
|
||||
height: 336rpx;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.address-window .pictrue image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
245
app/components/base/easy-loadimage.vue
Normal file
245
app/components/base/easy-loadimage.vue
Normal file
@@ -0,0 +1,245 @@
|
||||
<template>
|
||||
<view class="easy-loadimage" :style="[boxStyle]" :id="uid">
|
||||
<image class="origin-img" :style="[imageRadius]" :src="imageSrc" mode="scaleToFill" v-if="loadImg&&!isLoadError"
|
||||
v-show="showImg" :class="{'no-transition':!openTransition,'show-transition':showTransition&&openTransition}"
|
||||
@load="handleImgLoad" @error="handleImgError">
|
||||
</image>
|
||||
<view class="loadfail-img" v-else-if="isLoadError"
|
||||
:style="{'background-image': `url(${urlDomain}crmebimage/presets/loadfail.png) no-repeat center`}"></view>
|
||||
<view :class="['loading-img',loadingMode]" v-show="!showImg&&!isLoadError"></view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
import {
|
||||
throttle
|
||||
} from '@/utils/validate.js'
|
||||
|
||||
// 生成全局唯一id
|
||||
function generateUUID() {
|
||||
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
|
||||
let r = Math.random() * 16 | 0,
|
||||
v = c == 'x' ? r : (r & 0x3 | 0x8);
|
||||
return v.toString(16);
|
||||
})
|
||||
}
|
||||
export default {
|
||||
name: 'easyLoadimage',
|
||||
props: {
|
||||
imageSrc: {
|
||||
type: String || null,
|
||||
default () {
|
||||
return '';
|
||||
}
|
||||
},
|
||||
mode: {
|
||||
type: String,
|
||||
},
|
||||
loadingMode: {
|
||||
type: String,
|
||||
default: 'looming-gray'
|
||||
},
|
||||
openTransition: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
viewHeight: {
|
||||
type: Number,
|
||||
default () {
|
||||
return uni.getSystemInfoSync().windowHeight;
|
||||
}
|
||||
},
|
||||
width: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
height: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
borderRadius: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
radius: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
},
|
||||
data() {
|
||||
const that = this;
|
||||
return {
|
||||
urlDomain: this.$Cache.get("imgHost"),
|
||||
uid: 'uid-' + generateUUID(),
|
||||
loadImg: false,
|
||||
showImg: false,
|
||||
isLoadError: false,
|
||||
borderLoaded: 0,
|
||||
showTransition: false,
|
||||
scrollFn: throttle(function() {
|
||||
// 加载img时才执行滚动监听判断是否可加载
|
||||
if (that.loadImg || that.isLoadError) return;
|
||||
const id = that.uid
|
||||
const query = uni.createSelectorQuery().in(that);
|
||||
query.select('#' + id).boundingClientRect(data => {
|
||||
if (!data) return;
|
||||
if (data.top - that.viewHeight < 0) {
|
||||
that.loadImg = !!that.imageSrc;
|
||||
that.isLoadError = !that.loadImg;
|
||||
}
|
||||
}).exec()
|
||||
}, 200)
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
boxStyle() {
|
||||
return {
|
||||
width: this.width,
|
||||
height: this.height,
|
||||
borderRadius: this.radius * 2 + 'rpx'
|
||||
}
|
||||
},
|
||||
imageRadius() {
|
||||
if (this.radius && this.radius > 0) {
|
||||
return {
|
||||
'border-radius': this.radius * 2 + 'rpx'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
init() {
|
||||
this.$nextTick(this.onScroll)
|
||||
},
|
||||
handleBorderLoad() {
|
||||
this.borderLoaded = 1;
|
||||
},
|
||||
handleBorderError() {
|
||||
this.borderLoaded = 2;
|
||||
},
|
||||
handleImgLoad(e) {
|
||||
this.showImg = true;
|
||||
setTimeout(() => {
|
||||
this.showTransition = true
|
||||
}, 50)
|
||||
},
|
||||
handleImgError(e) {
|
||||
this.isLoadError = true;
|
||||
},
|
||||
onScroll() {
|
||||
this.scrollFn();
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.init()
|
||||
uni.$on('scroll', this.scrollFn);
|
||||
this.onScroll()
|
||||
},
|
||||
beforeDestroy() {
|
||||
uni.$off('scroll', this.scrollFn);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.easy-loadimage {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* 官方优化图片tips */
|
||||
image {
|
||||
will-change: transform;
|
||||
overflow: hidden;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
/* 渐变过渡效果处理 */
|
||||
image.origin-img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
opacity: 0.3;
|
||||
/* max-height: 360rpx; */
|
||||
/* border-radius: 14rpx;
|
||||
overflow: hidden; */
|
||||
/* min-height: 360rpx; */
|
||||
}
|
||||
|
||||
image.origin-img.show-transition {
|
||||
transition: opacity .5s;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
image.origin-img.no-transition {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
/* 加载失败、加载中的占位图样式控制 */
|
||||
.loadfail-img {
|
||||
height: 100%;
|
||||
background-size: 50%;
|
||||
}
|
||||
|
||||
.loading-img {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
/* 动态灰色若隐若现 */
|
||||
.looming-gray {
|
||||
animation: looming-gray 1s infinite linear;
|
||||
background-color: #e3e3e3;
|
||||
}
|
||||
|
||||
@keyframes looming-gray {
|
||||
0% {
|
||||
background-color: #e3e3e3aa;
|
||||
}
|
||||
|
||||
50% {
|
||||
background-color: #e3e3e3;
|
||||
}
|
||||
|
||||
100% {
|
||||
background-color: #e3e3e3aa;
|
||||
}
|
||||
}
|
||||
|
||||
/* 骨架屏1 */
|
||||
.skeleton-1 {
|
||||
background-color: #e3e3e3;
|
||||
background-image: linear-gradient(100deg, rgba(255, 255, 255, 0), rgba(255, 255, 255, 0.2) 50%, rgba(255, 255, 255, 0) 80%);
|
||||
background-size: 100rpx 100%;
|
||||
background-repeat: repeat-y;
|
||||
background-position: 0 0;
|
||||
animation: skeleton-1 .6s infinite;
|
||||
}
|
||||
|
||||
@keyframes skeleton-1 {
|
||||
to {
|
||||
background-position: 200% 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* 骨架屏2 */
|
||||
.skeleton-2 {
|
||||
background-image: linear-gradient(-90deg, #fefefe 0%, #e6e6e6 50%, #fefefe 100%);
|
||||
background-size: 400% 400%;
|
||||
background-position: 0 0;
|
||||
animation: skeleton-2 1.2s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes skeleton-2 {
|
||||
to {
|
||||
background-position: -135% 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
184
app/components/base/recommend.vue
Normal file
184
app/components/base/recommend.vue
Normal file
@@ -0,0 +1,184 @@
|
||||
<template>
|
||||
<view class='recommend'>
|
||||
<block v-if="tempArr.length">
|
||||
<view v-if="isShowTitle" class="flex-center recommend-box mt-20 mb-24">
|
||||
<image :src="`${urlDomain}crmebimage/presets/haowuzuo.png`"></image>
|
||||
<view class="f-s-32 lh-44rpx ml-4">热门推荐</view>
|
||||
<image class="ml-6" :src="`${urlDomain}crmebimage/presets/haowuyou.png`"></image>
|
||||
</view>
|
||||
<view class='recommendList borderPad' :class="isShowTitle?'':'mt30'">
|
||||
<WaterfallsFlow :wfList='tempArr' :type="1" :isStore="1">
|
||||
</WaterfallsFlow>
|
||||
</view>
|
||||
<view class='loadingicon acea-row row-center-wrapper' :hidden='loading==false'>
|
||||
<text class='loading iconfont icon-jiazai'></text>
|
||||
</view>
|
||||
<view class="mores-txt flex" v-if="goodScroll">
|
||||
<text>我是有底线的</text>
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
import {
|
||||
mapGetters
|
||||
} from "vuex";
|
||||
import animationType from '@/utils/animationType.js'
|
||||
import {
|
||||
getProductslist
|
||||
} from '@/api/store.js';
|
||||
import WaterfallsFlow from '@/components/WaterfallsFlow/WaterfallsFlow.vue';
|
||||
let app = getApp();
|
||||
export default {
|
||||
name: 'recommend',
|
||||
computed: mapGetters(['uid']),
|
||||
components: {
|
||||
WaterfallsFlow
|
||||
},
|
||||
props: {
|
||||
categoryId: {
|
||||
type: Number,
|
||||
default: function() {
|
||||
return 0;
|
||||
}
|
||||
},
|
||||
//是否显示头部
|
||||
isShowTitle: {
|
||||
type: Boolean,
|
||||
default: function() {
|
||||
return true;
|
||||
}
|
||||
},
|
||||
//是否使用本页面的请求数据
|
||||
isDefault: {
|
||||
type: Boolean,
|
||||
default: function() {
|
||||
return true;
|
||||
}
|
||||
},
|
||||
//使用的页面中调用数据传来的商品列表,isDefault为false时使用
|
||||
recommendList: {
|
||||
type: Array,
|
||||
default: function() {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
urlDomain: this.$Cache.get("imgHost"),
|
||||
theme: app.globalData.theme,
|
||||
goodScroll: false,
|
||||
params: { //精品推荐分页
|
||||
page: 1,
|
||||
limit: 10,
|
||||
cid: 0
|
||||
},
|
||||
loading: false,
|
||||
tempArr: []
|
||||
};
|
||||
},
|
||||
computed:{
|
||||
myCategoryId(){
|
||||
return this.categoryId
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
myCategoryId: function(val) { //监听props中的属性
|
||||
this.params.page = 1;
|
||||
this.tempArr = [];
|
||||
this.goodScroll = false;
|
||||
this.get_host_product()
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
if (this.isDefault) {
|
||||
this.params.page = 1;
|
||||
this.goodScroll = false;
|
||||
this.tempArr = [];
|
||||
this.get_host_product()
|
||||
} else {
|
||||
this.tempArr = this.recommendList
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* 获取我的推荐
|
||||
*/
|
||||
get_host_product: function() {
|
||||
if (this.goodScroll) return;
|
||||
this.loading = true
|
||||
this.params.cid = this.categoryId;
|
||||
getProductslist(
|
||||
this.params
|
||||
).then((res) => {
|
||||
this.$set(this.params, 'page', this.params.page + 1);
|
||||
this.goodScroll = this.params.page > res.data.totalPage;
|
||||
this.tempArr = this.tempArr.concat(res.data.list || []);
|
||||
// this.$emit('getRecommendLength', this.tempArr.length);
|
||||
this.loading = false
|
||||
}).catch(err => {
|
||||
this.loading = false
|
||||
});
|
||||
}
|
||||
},
|
||||
onReachBottom() {
|
||||
if (this.isDefault) this.get_host_product();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.recommend-box {
|
||||
image {
|
||||
width: 42rpx;
|
||||
height: 36rpx;
|
||||
}
|
||||
|
||||
view {
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
||||
.mores-txt {
|
||||
width: 100%;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 70rpx;
|
||||
color: #999;
|
||||
font-size: 24rpx;
|
||||
|
||||
.iconfont {
|
||||
margin-top: 2rpx;
|
||||
font-size: 20rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.recommend {
|
||||
.title {
|
||||
height: 120rpx;
|
||||
line-height: 120rpx;
|
||||
font-size: 32rpx;
|
||||
color: #333333;
|
||||
|
||||
.iconfont {
|
||||
font-size: 170rpx;
|
||||
color: #454545;
|
||||
}
|
||||
}
|
||||
|
||||
.name {
|
||||
margin: 0 28rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
248
app/components/base/tui-skeleton.vue
Normal file
248
app/components/base/tui-skeleton.vue
Normal file
@@ -0,0 +1,248 @@
|
||||
<template>
|
||||
<view class="tui-skeleton-cmomon tui-skeleton-box" :style="{width: winWidth+'px', height:winHeight+'px', backgroundColor:backgroundColor}">
|
||||
<view class="tui-skeleton-cmomon" v-for="(item,index) in skeletonElements" :key="index" :style="{width: item.width+'px', height:item.height+'px', left: item.left+'px', top: item.top+'px',backgroundColor: skeletonBgColor,borderRadius:getRadius(item.skeletonType,borderRadius)}"></view>
|
||||
<view class="tui-loading" :class="[getLoadingType(loadingType)]" v-if="isLoading"></view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
export default {
|
||||
name: "tuiSkeleton",
|
||||
props: {
|
||||
//选择器(外层容器)
|
||||
selector: {
|
||||
type: String,
|
||||
default: "tui-skeleton"
|
||||
},
|
||||
//外层容器背景颜色
|
||||
backgroundColor: {
|
||||
type: String,
|
||||
default: "#fff"
|
||||
},
|
||||
//骨架元素背景颜色
|
||||
skeletonBgColor: {
|
||||
type: String,
|
||||
default: "#e9e9e9"
|
||||
},
|
||||
//骨架元素类型:矩形,圆形,带圆角矩形["rect","circular","fillet"]
|
||||
//默认所有,根据页面情况进行传值
|
||||
//页面对应元素class为:tui-skeleton-rect,tui-skeleton-circular,tui-skeleton-fillet
|
||||
//如果传入的值不在下列数组中,则为自定义class值,默认按矩形渲染
|
||||
skeletonType: {
|
||||
type: Array,
|
||||
default () {
|
||||
return ["rect", "circular", "fillet"]
|
||||
}
|
||||
},
|
||||
//圆角值,skeletonType=fillet时生效
|
||||
borderRadius: {
|
||||
type: String,
|
||||
default: "16rpx"
|
||||
},
|
||||
//骨架屏预生成数据:提前生成好的数据,当传入该属性值时,则不会再次查找子节点信息
|
||||
preloadData: {
|
||||
type: Array,
|
||||
default () {
|
||||
return []
|
||||
}
|
||||
},
|
||||
//是否需要loading
|
||||
isLoading: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
//loading类型[1-10]
|
||||
loadingType: {
|
||||
type: Number,
|
||||
default: 1
|
||||
}
|
||||
},
|
||||
created() {
|
||||
const res = uni.getSystemInfoSync();
|
||||
this.winWidth = res.windowWidth;
|
||||
this.winHeight = res.windowHeight;
|
||||
//如果有预生成数据,则直接使用
|
||||
this.isPreload(true)
|
||||
},
|
||||
mounted() {
|
||||
this.$nextTick(() => {
|
||||
this.nodesRef(`.${this.selector}`).then((res) => {
|
||||
if(res && res[0]){
|
||||
this.winHeight = res[0].height + Math.abs(res[0].top)
|
||||
}
|
||||
});
|
||||
!this.isPreload() && this.selectorQuery()
|
||||
})
|
||||
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
winWidth: 375,
|
||||
winHeight: 800,
|
||||
skeletonElements: []
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
getLoadingType: function(type) {
|
||||
let value = 1
|
||||
if (type && type > 0 && type < 11) {
|
||||
value = type
|
||||
}
|
||||
return 'tui-loading-' + value
|
||||
},
|
||||
getRadius: function(type, val) {
|
||||
let radius = "0"
|
||||
if (type == "circular") {
|
||||
radius = "50%"
|
||||
} else if (type == "fillet") {
|
||||
radius = val
|
||||
}
|
||||
return radius;
|
||||
},
|
||||
isPreload(init) {
|
||||
let preloadData = this.preloadData || []
|
||||
if (preloadData.length) {
|
||||
init && (this.skeletonElements = preloadData)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
},
|
||||
async selectorQuery() {
|
||||
let skeletonType = this.skeletonType || []
|
||||
let nodes = []
|
||||
for (let item of skeletonType) {
|
||||
let className = '';
|
||||
// #ifndef MP-WEIXIN
|
||||
className = `.${item}`;
|
||||
if (~'rect_circular_fillet'.indexOf(item)) {
|
||||
className = `.${this.selector}-${item}`;
|
||||
}
|
||||
// #endif
|
||||
|
||||
// #ifdef MP-WEIXIN
|
||||
className = `.${this.selector} >>> .${item}`;
|
||||
if (~'rect_circular_fillet'.indexOf(item)) {
|
||||
className = `.${this.selector} >>> .${this.selector}-${item}`;
|
||||
}
|
||||
// #endif
|
||||
await this.nodesRef(className).then((res) => {
|
||||
res.map(d => {
|
||||
d.skeletonType = item
|
||||
})
|
||||
nodes = nodes.concat(res)
|
||||
})
|
||||
}
|
||||
this.skeletonElements = nodes
|
||||
},
|
||||
async nodesRef(className) {
|
||||
return await new Promise((resolve, reject) => {
|
||||
uni.createSelectorQuery().selectAll(className).boundingClientRect((res) => {
|
||||
if (res) {
|
||||
resolve(res);
|
||||
} else {
|
||||
reject(res)
|
||||
}
|
||||
}).exec();
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.tui-skeleton-cmomon {
|
||||
position: absolute;
|
||||
z-index: 99999;
|
||||
}
|
||||
|
||||
.tui-skeleton-box {
|
||||
left: 0;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.tui-loading {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
background: 0 0;
|
||||
border-radius: 50%;
|
||||
border: 2px solid;
|
||||
animation: tui-rotate 0.7s linear infinite;
|
||||
position: fixed;
|
||||
z-index: 999999;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
margin-left: -20rpx;
|
||||
margin-top: -20rpx;
|
||||
}
|
||||
|
||||
.tui-loading-1 {
|
||||
border-color: #e5e5e5 #e5e5e5 #e5e5e5 #5677fc;
|
||||
}
|
||||
|
||||
.tui-loading-2 {
|
||||
border-color: #e5e5e5 #e5e5e5 #e5e5e5 #8f8d8e;
|
||||
}
|
||||
|
||||
.tui-loading-3 {
|
||||
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) #fff;
|
||||
}
|
||||
|
||||
.tui-loading-4 {
|
||||
border-color: #e5e5e5 #e5e5e5 #e5e5e5 #35b06a;
|
||||
}
|
||||
|
||||
.tui-loading-5 {
|
||||
border-color: #e5e5e5 #e5e5e5 #e5e5e5 #fc872d;
|
||||
}
|
||||
|
||||
.tui-loading-6 {
|
||||
border-color: #e5e5e5 #e5e5e5 #e5e5e5 #eb0909;
|
||||
}
|
||||
|
||||
.tui-loading-7 {
|
||||
border-color: #5677fc transparent #5677fc transparent;
|
||||
}
|
||||
|
||||
.tui-loading-8 {
|
||||
border-color: #35b06a transparent #35b06a transparent;
|
||||
}
|
||||
|
||||
.tui-loading-9 {
|
||||
border-color: #fc872d transparent #fc872d transparent;
|
||||
}
|
||||
|
||||
.tui-loading-10 {
|
||||
border-color: #eb0909 transparent #eb0909 transparent;
|
||||
}
|
||||
|
||||
@-webkit-keyframes tui-rotate {
|
||||
0% {
|
||||
transform: rotate(0);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes tui-rotate {
|
||||
0% {
|
||||
transform: rotate(0);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
210
app/components/cartList/index.vue
Normal file
210
app/components/cartList/index.vue
Normal file
@@ -0,0 +1,210 @@
|
||||
<template>
|
||||
<view>
|
||||
<view class="cartList" :class="cartData.iScart?'on':''">
|
||||
<view class="title acea-row row-between-wrapper">
|
||||
<view class="name">已选商品</view>
|
||||
<view class="del acea-row row-middle" @click="subDel"><view class="iconfont icon-shanchu1"></view>清空</view>
|
||||
</view>
|
||||
<view class="list">
|
||||
<view class="item acea-row row-between-wrapper" v-for="(item,index) in cartData.cartList" :key="index">
|
||||
<view class="pictrue">
|
||||
<image :src='item.image'></image>
|
||||
<!-- <view class="mantle" v-if="!item.status || !item.attrStatus"></view> -->
|
||||
</view>
|
||||
<view class="txtPic">
|
||||
<view class="name line2" :class="item.attrStatus ?'':'on'">{{item.storeName}}</view>
|
||||
<view v-if="item.attrStatus">
|
||||
<view class="info" >{{item.suk}}</view>
|
||||
<view class="bottom acea-row row-between-wrapper">
|
||||
<view class="money">¥<text class="num">{{item.vipPrice ? item.vipPrice :item.price}}</text></view>
|
||||
<view class="cartNum acea-row row-middle">
|
||||
<view class="reduce iconfont icon-jianhao1" @click="leaveCart(index)"></view>
|
||||
<view class="num">{{item.cartNum}}</view>
|
||||
<view :class="item.cartNum >= item.stock?'on':''" class="plus iconfont icon-jiahao1" @click="joinCart(index)"></view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="noBnt" v-else-if="item.stock == 0">已售罄</view>
|
||||
<!-- <view class="delTxt acea-row row-right" v-if="!item.status || !item.attrStatus"><text @click="oneDel(item.id,index)">删除</text></view> -->
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="mask" v-if="cartData.iScart" @click="closeList"></view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props:{
|
||||
cartData: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {};
|
||||
},
|
||||
mounted(){
|
||||
},
|
||||
methods: {
|
||||
closeList(){
|
||||
this.$emit('closeList', false);
|
||||
},
|
||||
leaveCart(index){
|
||||
this.$emit('ChangeCartNumDan', false,index);
|
||||
},
|
||||
joinCart(index){
|
||||
this.$emit('ChangeCartNumDan', true,index);
|
||||
},
|
||||
subDel(){
|
||||
this.$emit('ChangeSubDel');
|
||||
},
|
||||
oneDel(id,index){
|
||||
this.$emit('ChangeOneDel',id,index);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.on {
|
||||
color: #DEDEDE !important;
|
||||
}
|
||||
.mask{
|
||||
z-index: 99;
|
||||
}
|
||||
.cartList{
|
||||
position: fixed;
|
||||
left:0;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
background-color: #fff;
|
||||
z-index:100;
|
||||
padding: 0 30rpx 100rpx 30rpx;
|
||||
box-sizing: border-box;
|
||||
border-radius:16rpx 16rpx 0 0;
|
||||
transform: translate3d(0, 100%, 0);
|
||||
transition: all .3s cubic-bezier(.25, .5, .5, .9);
|
||||
&.on{
|
||||
transform: translate3d(0, 0, 0);
|
||||
}
|
||||
.title{
|
||||
height: 108rpx;
|
||||
.name{
|
||||
font-size:28rpx;
|
||||
color: #282828;
|
||||
font-weight:bold;
|
||||
}
|
||||
.del{
|
||||
font-size: 26rpx;
|
||||
@include main_color(theme);
|
||||
.iconfont{
|
||||
margin-right: 5rpx;
|
||||
font-size: 34rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
.list{
|
||||
max-height: 720rpx;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
.item{
|
||||
margin-bottom: 40rpx;
|
||||
.pictrue{
|
||||
width: 176rpx;
|
||||
height: 176rpx;
|
||||
border-radius: 16rpx;
|
||||
position: relative;
|
||||
image{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 16rpx;
|
||||
}
|
||||
.mantle{
|
||||
position: absolute;
|
||||
top:0;
|
||||
left:0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background:rgba(255,255,255,0.65);
|
||||
border-radius:16rpx;
|
||||
}
|
||||
}
|
||||
.txtPic{
|
||||
width: 486rpx;
|
||||
.name{
|
||||
font-size:28rpx;
|
||||
color: #282828;
|
||||
&.on{
|
||||
color: #A3A3A3;
|
||||
}
|
||||
}
|
||||
.noBnt{
|
||||
width:126rpx;
|
||||
height:44rpx;
|
||||
background:rgba(242,242,242,1);
|
||||
border-radius:22rpx;
|
||||
text-align: center;
|
||||
line-height: 44rpx;
|
||||
font-size: 24rpx;
|
||||
color: #A3A3A3;
|
||||
margin-top: 10rpx;
|
||||
}
|
||||
.delTxt{
|
||||
margin-top: 48rpx;
|
||||
font-size: 24rpx;
|
||||
color: #E93323;
|
||||
text{
|
||||
width: 70rpx;
|
||||
height: 50rpx;
|
||||
text-align: center;
|
||||
line-height: 50rpx;
|
||||
}
|
||||
}
|
||||
.info{
|
||||
font-size: 23rpx;
|
||||
color: #989898;
|
||||
margin-top: 5rpx;
|
||||
}
|
||||
.bottom{
|
||||
margin-top: 11rpx;
|
||||
.money{
|
||||
font-weight:bold;
|
||||
font-size: 26rpx;
|
||||
@include price_color(theme);
|
||||
.num{
|
||||
font-size: 34rpx;
|
||||
}
|
||||
}
|
||||
.cartNum{
|
||||
font-weight:bold;
|
||||
.num{
|
||||
font-size: 34rpx;
|
||||
color: #282828;
|
||||
width: 120rpx;
|
||||
text-align: center;
|
||||
}
|
||||
.reduce{
|
||||
color: #282828;
|
||||
font-size: 24rpx;
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
text-align: center;
|
||||
line-height: 60rpx;
|
||||
}
|
||||
.plus{
|
||||
color: #282828;
|
||||
font-size: 24rpx;
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
text-align: center;
|
||||
line-height: 60rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -13,16 +13,16 @@
|
||||
<!-- <view class='item acea-row row-center-wrapper' v-for="(item,index) in coupon.list" :key='index'> -->
|
||||
<view class='item acea-row row-center-wrapper' v-for="(item,index) in coupon.list"
|
||||
@click="getCouponUser(index,item.id)" :key='index'>
|
||||
<view class='money acea-row row-column row-center-wrapper' :class='item.isUse?"moneyGray":""'>
|
||||
<view>¥<text class='num'>{{item.money?Number(item.money):''}}</text></view>
|
||||
<view class='money acea-row row-column row-center-wrapper' :class='item.isUse?"moneyGray":"main_bg"'>
|
||||
<view>¥<text class='num' :style="[{'font-size':item.money.length>=7?'42rpx':'60rpx'}]" >{{item.money?Number(item.money):''}}</text></view>
|
||||
<view class="pic-num">满{{item.minPrice}}元可用</view>
|
||||
</view>
|
||||
<view class='text'>
|
||||
<view class='condition line2'>
|
||||
<span class='line-title' :class='item.isUse?"gray":""' v-if='item.useType===1'>通用</span>
|
||||
<span class='line-title' :class='item.isUse?"gray":""'
|
||||
<span class='line-title' :class='item.isUse?"gray":"select"' v-if='item.useType===1'>通用</span>
|
||||
<span class='line-title' :class='item.isUse?"gray":"select"'
|
||||
v-else-if='item.useType===3'>品类</span>
|
||||
<span class='line-title' :class='item.isUse?"gray":""' v-else>商品</span>
|
||||
<span class='line-title' :class='item.isUse?"gray":"select"' v-else>商品</span>
|
||||
<span>{{item.name}}</span>
|
||||
</view>
|
||||
<view class='data acea-row row-between-wrapper'>
|
||||
@@ -31,14 +31,14 @@
|
||||
{{ item.useStartTimeStr&& item.useEndTimeStr ? item.useStartTimeStr + " - " + item.useEndTimeStr : ""}}
|
||||
</view>
|
||||
<view class='bnt gray' v-if="item.isUse">{{item.use_title || '已领取'}}</view>
|
||||
<view class='bnt bg-color' v-else>{{coupon.statusTile || '立即领取'}}</view>
|
||||
<view class='bnt main_bg' v-else>{{coupon.statusTile || '立即领取'}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
<!-- 无优惠券 -->
|
||||
<view class='pictrue' v-else>
|
||||
<image src='../../static/images/noCoupon.png'></image>
|
||||
<image :src="urlDomain+'crmebimage/perset/staticImg/noCoupon.png'"></image>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
@@ -70,17 +70,21 @@
|
||||
default: function() {
|
||||
return '';
|
||||
}
|
||||
},
|
||||
typeNum:{
|
||||
type:Number,
|
||||
default:0
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
type: 1
|
||||
urlDomain: this.$Cache.get("imgHost"),
|
||||
type: 1,
|
||||
};
|
||||
},
|
||||
|
||||
methods: {
|
||||
close: function() {
|
||||
this.type = 1
|
||||
this.type = this.typeNum;
|
||||
this.$emit('ChangCouponsClone');
|
||||
},
|
||||
getCouponUser: function(index, id) {
|
||||
@@ -96,6 +100,10 @@
|
||||
that.$emit('ChangCouponsUseState', index);
|
||||
that.$util.Tips({
|
||||
title: "领取成功"
|
||||
}, function(res) {
|
||||
return that.$util.Tips({
|
||||
title: res
|
||||
});
|
||||
});
|
||||
that.$emit('ChangCoupons', list[index]);
|
||||
})
|
||||
@@ -106,8 +114,8 @@
|
||||
}
|
||||
},
|
||||
setType: function(type) {
|
||||
this.type = type;
|
||||
this.$emit('tabCouponType', type);
|
||||
this.type = type;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -177,7 +185,7 @@
|
||||
width: 90rpx;
|
||||
padding: 0 10rpx;
|
||||
box-sizing: border-box;
|
||||
background: rgba(255, 247, 247, 1);
|
||||
background: #fff;
|
||||
border: 1px solid rgba(232, 51, 35, 1);
|
||||
opacity: 1;
|
||||
border-radius: 20rpx;
|
||||
@@ -212,7 +220,7 @@
|
||||
}
|
||||
|
||||
.nav .acea-row.on {
|
||||
border-bottom-color: #E93323;
|
||||
@include tab_border_bottom(theme);
|
||||
color: #282828;
|
||||
}
|
||||
|
||||
@@ -232,4 +240,12 @@
|
||||
.coupon-list .item .money {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.main_bg{
|
||||
@include main_bg_color(theme);
|
||||
}
|
||||
.select{
|
||||
@include main_color(theme);
|
||||
@include coupons_border_color(theme);
|
||||
}
|
||||
</style>
|
||||
|
||||
143
app/components/cus-previewImg/cus-previewImg.vue
Normal file
143
app/components/cus-previewImg/cus-previewImg.vue
Normal file
@@ -0,0 +1,143 @@
|
||||
<template>
|
||||
<view class="previewImg" v-if="showBox" @touchmove.stop.prevent>
|
||||
<view class="mask" @click="close">
|
||||
<swiper @change="changeSwiper" class="mask-swiper" :current="currentIndex" :circular="circular" :duration="duration">
|
||||
<swiper-item v-for="(src, i) in list" :key="i" class="flex flex-column justify-center align-center">
|
||||
<image class="mask-swiper-img" :src="src.image" mode="widthFix" />
|
||||
<view class="mask_sku">
|
||||
<text class="sku_name">{{src.suk}}</text>
|
||||
<text class="sku_price">¥{{src.price}}</text>
|
||||
</view>
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
</view>
|
||||
<view class="pagebox" v-if="list.length>0">{{ Number(currentIndex) + 1 }} / {{ list.length }}</view>
|
||||
<!-- #ifndef MP -->
|
||||
<text class="iconfont icon-fenxiang share_btn" @click="shareFriend()"></text>
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'cus-previewImg',
|
||||
props: {
|
||||
list: {
|
||||
type: Array,
|
||||
required: true,
|
||||
default: () => {
|
||||
return [];
|
||||
}
|
||||
},
|
||||
circular: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
duration: {
|
||||
type: Number,
|
||||
default: 500
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
currentIndex: 0,
|
||||
showBox: false
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
list(val) {
|
||||
// console.log('图片预览', val)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 左右切换
|
||||
changeSwiper(e) {
|
||||
this.currentIndex = e.target.current;
|
||||
this.$emit('changeSwitch',e.target.current)
|
||||
},
|
||||
open(current) {
|
||||
if (!current || !this.list.length) return;
|
||||
this.currentIndex = this.list.map((item)=>item.suk).indexOf(current);
|
||||
this.showBox = true;
|
||||
},
|
||||
close() {
|
||||
this.showBox = false;
|
||||
},
|
||||
shareFriend(){
|
||||
this.$emit('shareFriend')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@mixin full {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.previewImg {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 300;
|
||||
@include full;
|
||||
.mask {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background-color: #000;
|
||||
opacity: 1;
|
||||
z-index: 8;
|
||||
@include full;
|
||||
&-swiper {
|
||||
@include full;
|
||||
&-img {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
.pagebox{
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
bottom: 20rpx;
|
||||
z-index: 300;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
.mask_sku{
|
||||
color: #fff;
|
||||
max-width: 80%;
|
||||
z-index: 300;
|
||||
text-align: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
margin-top: 30rpx;
|
||||
.sku_name{
|
||||
font-size: 12px;
|
||||
border: 1px solid #fff;
|
||||
padding: 10rpx 30rpx 10rpx;
|
||||
border-radius: 40px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.sku_price{
|
||||
padding-top: 10px;
|
||||
}
|
||||
}
|
||||
.font12{
|
||||
font-size: 24rpx;
|
||||
}
|
||||
.share_btn{
|
||||
position: absolute;
|
||||
top:70rpx;
|
||||
right:50rpx;
|
||||
font-size: 40rpx;
|
||||
color:#fff;
|
||||
z-index: 300;
|
||||
}
|
||||
.flex-column{flex-direction: column;}
|
||||
.justify-center {justify-content: center;}
|
||||
.align-center {align-items: center;}
|
||||
</style>
|
||||
172
app/components/d_goodList/index.vue
Normal file
172
app/components/d_goodList/index.vue
Normal file
@@ -0,0 +1,172 @@
|
||||
<template>
|
||||
<view class="goodsList">
|
||||
<view class="item" v-for="(item,index) in tempArr" :key='index' @click="goDetail(item)">
|
||||
<view class="pictrue">
|
||||
<image :src="item.recommend_image" mode="aspectFill" v-if="item.recommend_image"></image>
|
||||
<image :src="item.image" mode="aspectFill" v-else></image>
|
||||
</view>
|
||||
<view class="text line2">{{item.storeName}}</view>
|
||||
<view class="bottom acea-row row-between-wrapper">
|
||||
<view class="sales acea-row row-middle">
|
||||
<view class="money" :class="item.price.length>8?'lengthStr':''"><text>¥</text>{{item.price}} <text class="item_sales">已售 {{item.sales}}</text> </view>
|
||||
<!-- <view></view> -->
|
||||
</view>
|
||||
<view v-if="item.stock>0">
|
||||
<view class="bnt" v-if="item.activity && (item.activity.type === '1' || item.activity.type === '2' || item.activity.type === '3')">立即购买</view>
|
||||
<view v-else>
|
||||
<view class="bnt" @click.stop="goCartDuo(item)">
|
||||
加入购物车
|
||||
<view class="num" v-if="item.cartNum">{{item.cartNum}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="end" v-else>已售罄</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'd_goodList',
|
||||
props: {
|
||||
dataConfig: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
},
|
||||
tempArr:{
|
||||
type: Array,
|
||||
default:[]
|
||||
},
|
||||
isLogin:{
|
||||
type: Boolean,
|
||||
default:false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
};
|
||||
},
|
||||
created() {},
|
||||
mounted() {},
|
||||
methods: {
|
||||
goDetail(item){
|
||||
this.$emit('detail',item);
|
||||
},
|
||||
goCartDuo(item){
|
||||
this.$emit('gocartduo',item);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.goodsList{
|
||||
padding: 0 30rpx;
|
||||
.item{
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
margin-bottom: 63rpx;
|
||||
.pictrue{
|
||||
width: 100%;
|
||||
height: 216rpx;
|
||||
border-radius: 16rpx;
|
||||
position: relative;
|
||||
image{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 16rpx;
|
||||
}
|
||||
}
|
||||
.text{
|
||||
font-size:30rpx;
|
||||
font-family:PingFang SC;
|
||||
font-weight:bold;
|
||||
color: #282828;
|
||||
margin: 20rpx 0;
|
||||
}
|
||||
.bottom{
|
||||
.sales{
|
||||
font-size: 22rpx;
|
||||
color: #8E8E8E;
|
||||
.money{
|
||||
font-size: 42rpx;
|
||||
font-weight: bold;
|
||||
margin-right: 18rpx;
|
||||
@include price_color(theme);
|
||||
.item_sales{
|
||||
font-size: 24rpx;
|
||||
font-family: PingFang SC;
|
||||
font-weight: 400;
|
||||
padding-left: 17rpx;
|
||||
color: #8e8e8e;
|
||||
}
|
||||
text{
|
||||
font-size: 28rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
.cart{
|
||||
height: 56rpx;
|
||||
.pictrue{
|
||||
color: #E93323;
|
||||
font-size:46rpx;
|
||||
width: 50rpx;
|
||||
height: 50rpx;
|
||||
text-align: center;
|
||||
line-height: 50rpx;
|
||||
&.icon-jiahao{
|
||||
background:linear-gradient(140deg, #FA6514 0%, #E93323 100%);
|
||||
-webkit-background-clip:text;
|
||||
-webkit-text-fill-color:transparent;
|
||||
}
|
||||
}
|
||||
.num{
|
||||
font-size: 30rpx;
|
||||
color: #282828;
|
||||
font-weight: bold;
|
||||
width: 80rpx;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
.bnt{
|
||||
padding: 0 30rpx;
|
||||
height: 56rpx;
|
||||
line-height: 56rpx;
|
||||
@include main_bg_color(theme);
|
||||
border-radius:42rpx;
|
||||
font-size: 26rpx;
|
||||
color: #fff;
|
||||
position: relative;
|
||||
.num{
|
||||
@include main_color(theme);
|
||||
@include coupons_border_color(theme);
|
||||
background: #fff;
|
||||
min-width: 12rpx;
|
||||
border-radius: 15px;
|
||||
position: absolute;
|
||||
right: -14rpx;
|
||||
top: -15rpx;
|
||||
font-size: 22rpx;
|
||||
padding: 0 10rpx;
|
||||
height: 34rpx;
|
||||
line-height: 34rpx;
|
||||
}
|
||||
}
|
||||
.end{
|
||||
padding: 0 30rpx;
|
||||
height: 56rpx;
|
||||
line-height: 56rpx;
|
||||
border-radius:42rpx;
|
||||
font-size: 26rpx;
|
||||
color: #fff;
|
||||
position: relative;
|
||||
background:rgba(203,203,203,1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.lengthStr{
|
||||
font-size: 36rpx !important;
|
||||
}
|
||||
</style>
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<view class="empty-box">
|
||||
<image src="../static/images/empty-box.png"></image>
|
||||
<image :src="urlDomain+'crmebimage/perset/staticImg/empty-box.png'"></image>
|
||||
<view class="txt">{{title}}</view>
|
||||
</view>
|
||||
</template>
|
||||
@@ -13,6 +13,11 @@
|
||||
default: '暂无记录',
|
||||
},
|
||||
},
|
||||
data(){
|
||||
return{
|
||||
urlDomain: this.$Cache.get("imgHost"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
180
app/components/f_goodList/index.vue
Normal file
180
app/components/f_goodList/index.vue
Normal file
@@ -0,0 +1,180 @@
|
||||
<template>
|
||||
<view class="goodsList">
|
||||
<view class="item acea-row row-between-wrapper" v-for="(item,index) in tempArr" :key='index' @click="goDetail(item)">
|
||||
<view class="pic">
|
||||
<image :src="item.image" mode=""></image>
|
||||
<view :style="{ backgroundImage: `url(${item.activityStyle})` }" class="border-picture"></view>
|
||||
</view>
|
||||
<view class="pictxt">
|
||||
<view class="text line2">{{item.storeName}}</view>
|
||||
<view class="bottom acea-row row-between-wrapper">
|
||||
<view class="money">
|
||||
<text class="sign">¥</text>{{item.price}}
|
||||
</view>
|
||||
<view v-if="item.stock>0">
|
||||
<view>
|
||||
<!-- 多规格 -->
|
||||
<view class="bnt" @click.stop="goCartDuo(item)">
|
||||
选规格
|
||||
<view class="num" v-if="item.cartNum">{{item.cartNum}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="bnt end" v-else>已售罄</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'd_goodList',
|
||||
props: {
|
||||
dataConfig: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
},
|
||||
tempArr:{
|
||||
type: Array,
|
||||
default:[]
|
||||
},
|
||||
isLogin:{
|
||||
type: Boolean,
|
||||
default:false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
||||
};
|
||||
},
|
||||
created() {},
|
||||
mounted() {},
|
||||
methods: {
|
||||
goDetail(item){
|
||||
this.$emit('detail',item);
|
||||
},
|
||||
goCartDuo(item){
|
||||
this.$emit('gocartduo',item);
|
||||
},
|
||||
goCartDan(item,index){
|
||||
this.$emit('gocartdan',item,index);
|
||||
},
|
||||
CartNumDes(index,item){
|
||||
this.$emit('ChangeCartNumDan', false,index,item);
|
||||
},
|
||||
CartNumAdd(index,item){
|
||||
this.$emit('ChangeCartNumDan', true,index,item);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.goodsList{
|
||||
padding: 0 30rpx;
|
||||
.item{
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
margin-bottom: 63rpx;
|
||||
.pic{
|
||||
width: 140rpx;
|
||||
height: 140rpx;
|
||||
border-radius: 10rpx;
|
||||
position: relative;
|
||||
border-radius: 22rpx;
|
||||
image{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 22rpx;
|
||||
}
|
||||
}
|
||||
.pictxt{
|
||||
width: 372rpx;
|
||||
.text{
|
||||
font-size:26rpx;
|
||||
font-family:PingFang SC;
|
||||
font-weight:500;
|
||||
color: $crmeb-font-color;
|
||||
}
|
||||
.bottom{
|
||||
margin-top: 22rpx;
|
||||
.money{
|
||||
font-size: 34rpx;
|
||||
font-weight: 800;
|
||||
width: 212rpx;
|
||||
@include price_color(theme);
|
||||
.sign{
|
||||
font-size: 24rpx;
|
||||
}
|
||||
}
|
||||
.otPrice{
|
||||
font-size: 20rpx;
|
||||
font-family: PingFang SC;
|
||||
font-weight: 400;
|
||||
line-height: 24rpx;
|
||||
padding-left: 14rpx;
|
||||
color: #999999;
|
||||
}
|
||||
.cart{
|
||||
height: 46rpx;
|
||||
.pictrue{
|
||||
color: $crmeb-theme-color;
|
||||
font-size:46rpx;
|
||||
width: 46rpx;
|
||||
height: 46rpx;
|
||||
text-align: center;
|
||||
line-height: 46rpx;
|
||||
&.icon-jiahao{
|
||||
color: $crmeb-theme-color;
|
||||
}
|
||||
}
|
||||
.num{
|
||||
font-size: 30rpx;
|
||||
color: $crmeb-font-color;
|
||||
font-weight: bold;
|
||||
width: 60rpx;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
.icon-gouwuche6{
|
||||
width: 46rpx;
|
||||
height: 46rpx;
|
||||
background-color: $crmeb-theme-color;
|
||||
border-radius: 50%;
|
||||
color: $crmeb-font-color-white;
|
||||
font-size: 30rpx;
|
||||
}
|
||||
.bnt{
|
||||
padding: 0 20rpx;
|
||||
height: 46rpx;
|
||||
line-height: 46rpx;
|
||||
@include main_bg_color(theme);
|
||||
border-radius:23rpx;
|
||||
font-size: 22rpx;
|
||||
color: $crmeb-font-color-white;
|
||||
position: relative;
|
||||
&.end{
|
||||
background:$crmeb-font-color-disable;
|
||||
}
|
||||
.num{
|
||||
min-width: 12rpx;
|
||||
@include main_color(theme);
|
||||
@include coupons_border_color(theme);
|
||||
background: #fff;
|
||||
border-radius: 15px;
|
||||
position: absolute;
|
||||
right: -13rpx;
|
||||
top: -11rpx;
|
||||
font-size: 16rpx;
|
||||
padding: 0 11rpx;
|
||||
height: 32rpx;
|
||||
line-height: 32rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -4,6 +4,7 @@
|
||||
<view @click="goDetail(item)" class='item acea-row row-between-wrapper' hover-class="none">
|
||||
<view class='pictrue'>
|
||||
<image :src='item.image'></image>
|
||||
<view :style="{ backgroundImage: `url(${item.activityStyle})` }" class="border-picture"></view>
|
||||
<span class="pictrue_log pictrue_log_class" v-if="item.activityH5 && item.activityH5.type === '1'">秒杀</span>
|
||||
<span class="pictrue_log pictrue_log_class" v-if="item.activityH5 && item.activityH5.type === '2'">砍价</span>
|
||||
<span class="pictrue_log pictrue_log_class" v-if="item.activityH5 && item.activityH5.type === '3'">拼团</span>
|
||||
@@ -11,14 +12,19 @@
|
||||
<view class='underline'>
|
||||
<view class='text'>
|
||||
<view class='line1'>{{item.storeName}}</view>
|
||||
<view class='money font-color'>¥<text class='num'>{{item.price}}</text></view>
|
||||
<view class='money'>¥<text class='num'>{{item.price}}</text></view>
|
||||
<view class='vip-money acea-row row-middle' v-if="item.vip_price && item.vip_price > 0">¥{{item.vip_price || 0}}
|
||||
<image src='../../static/images/vip.png'></image><text class='num'>已售{{Number(item.sales) + Number(item.ficti) || 0}}{{item.unitName}}</text>
|
||||
<image :src="urlDomain+'crmebimage/perset/staticImg/vip.png'"></image>
|
||||
<text class='num' v-if="status == 0">已售{{Number(item.sales) || 0}}{{item.unitName}}</text>
|
||||
<text class="num line_thr" v-if="status == 1">{{item.otPrice}}</text>
|
||||
</view>
|
||||
<view class='vip-money acea-row row-middle' v-else>
|
||||
<text class='num' v-if="status == 0">已售{{Number(item.sales)|| 0}}{{item.unitName}}</text>
|
||||
<text class="num line_thr" v-if="status == 1">¥{{item.otPrice}}</text>
|
||||
</view>
|
||||
<view class='vip-money acea-row row-middle' v-else><text class='num'>已售{{Number(item.sales) + Number(item.ficti) || 0}}{{item.unitName}}</text></view>
|
||||
</view>
|
||||
</view>
|
||||
<view class='iconfont icon-gouwuche cart-color acea-row row-center-wrapper'></view>
|
||||
<view class='iconfont icon-gengduo3'></view>
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
@@ -27,6 +33,7 @@
|
||||
<script>
|
||||
import {mapGetters} from "vuex";
|
||||
import { goShopDetail } from '@/libs/order.js'
|
||||
import animationType from '@/utils/animationType.js'
|
||||
export default {
|
||||
computed: mapGetters(['uid']),
|
||||
props: {
|
||||
@@ -43,14 +50,16 @@
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
||||
urlDomain: this.$Cache.get("imgHost"),
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
goDetail(item){
|
||||
goShopDetail(item,this.uid).then(res=>{
|
||||
uni.navigateTo({
|
||||
url:`/pages/goods_details/index?id=${item.id}`
|
||||
animationType: 'zoom-fade-out',
|
||||
animationDuration: 200,
|
||||
url:`/pages/goods/goods_details/index?id=${item.id}`
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -64,7 +73,12 @@
|
||||
position: relative;
|
||||
padding-left: 30rpx;
|
||||
}
|
||||
|
||||
.money {
|
||||
font-size: 26rpx;
|
||||
font-weight: bold;
|
||||
margin-top: 50rpx;
|
||||
@include price_color(theme);
|
||||
}
|
||||
.goodList .item .pictrue {
|
||||
width: 180rpx;
|
||||
height: 180rpx;
|
||||
@@ -101,12 +115,6 @@
|
||||
width: 489rpx;
|
||||
}
|
||||
|
||||
.goodList .item .text .money {
|
||||
font-size: 26rpx;
|
||||
font-weight: bold;
|
||||
margin-top: 50rpx;
|
||||
}
|
||||
|
||||
.goodList .item .text .money .num {
|
||||
font-size: 34rpx;
|
||||
}
|
||||
@@ -140,4 +148,7 @@
|
||||
font-size: 30rpx;
|
||||
bottom: 38rpx;
|
||||
}
|
||||
.line_thr{
|
||||
text-decoration: line-through;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
<view class="pictrue">
|
||||
<image :src="
|
||||
homeActive === true
|
||||
? '/static/images/close.gif'
|
||||
: '/static/images/open.gif'
|
||||
? `${urlDomain}crmebimage/perset/staticImg/close.gif`
|
||||
: `${urlDomain}/crmebimage/perset/staticImg/open.gif`
|
||||
"
|
||||
class="image" />
|
||||
</view>
|
||||
@@ -28,6 +28,7 @@
|
||||
props: {},
|
||||
data: function() {
|
||||
return {
|
||||
urlDomain: this.$Cache.get("imgHost"),
|
||||
top: "500"
|
||||
};
|
||||
},
|
||||
@@ -53,7 +54,7 @@
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
<style scoped lang="scss">
|
||||
.pictrueBox {
|
||||
width: 130rpx;
|
||||
height: 120rpx;
|
||||
@@ -86,7 +87,8 @@
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background: #f44939 !important;
|
||||
/* background: #f44939 !important; */
|
||||
@include main_bg_color(theme);
|
||||
}
|
||||
|
||||
.home .homeCon .iconfont {
|
||||
@@ -104,6 +106,7 @@
|
||||
}
|
||||
|
||||
.home .pictrue .image {
|
||||
@include main_bg_color(theme);
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 50%;
|
||||
|
||||
140
app/components/homeIndex/articleList.vue
Normal file
140
app/components/homeIndex/articleList.vue
Normal file
@@ -0,0 +1,140 @@
|
||||
<template>
|
||||
<!-- 文章列表 -->
|
||||
<view>
|
||||
<view class="articleList" :style="[boxStyle]" v-if="articleList.length">
|
||||
<view v-if="listStyle">
|
||||
<navigator :url='"/pages/news/news_details/index?id="+item.id' hover-class='none' :style="[itemStyle]"
|
||||
v-for="(item,index) in articleList" :key='index'
|
||||
class="item acea-row row-between-wrapper">
|
||||
<view class="pictrue">
|
||||
<easy-loadimage :image-src="item.imageInput" :radius="dataConfig.contentStyle.val"></easy-loadimage>
|
||||
</view>
|
||||
<view class="text">
|
||||
<view class="name line2" :style="[titleColor]">{{item.title}}</view>
|
||||
<view class="time" :style="[timeColor]">{{item.updateTime}}</view>
|
||||
</view>
|
||||
</navigator>
|
||||
</view>
|
||||
<view v-else>
|
||||
<navigator :url='"/pages/news/news_details/index?id="+item.id' hover-class='none'
|
||||
:style="[itemStyle]" v-for="(item,index) in articleList" :key='index'
|
||||
class="item acea-row row-between-wrapper">
|
||||
<view class="text">
|
||||
<view class="name line2" :style="[titleColor]">{{item.title}}</view>
|
||||
<view class="time" :style="[timeColor]">{{item.updateTime}}</view>
|
||||
</view>
|
||||
<view class="pictrue">
|
||||
<easy-loadimage :image-src="item.imageInput" :radius="dataConfig.contentStyle.val"></easy-loadimage>
|
||||
</view>
|
||||
</navigator>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
import easyLoadimage from '@/components/base/easy-loadimage.vue';
|
||||
export default {
|
||||
name: 'homeArticle',
|
||||
props: {
|
||||
dataConfig: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {}
|
||||
},
|
||||
components: {
|
||||
easyLoadimage
|
||||
},
|
||||
computed: {
|
||||
//布局样式
|
||||
listStyle() {
|
||||
return this.dataConfig.layoutConfig.tabVal === 0
|
||||
},
|
||||
//文章分类
|
||||
articleList() {
|
||||
return this.dataConfig.selectConfig.articleList
|
||||
},
|
||||
//最外层盒子的样式
|
||||
boxStyle() {
|
||||
return {
|
||||
borderRadius: this.dataConfig.bgStyle.val * 2 + 'rpx',
|
||||
background: `linear-gradient(${this.dataConfig.bgColor.color[0].item}, ${this.dataConfig.bgColor.color[1].item})`,
|
||||
margin: this.dataConfig.mbConfig.val * 2 + 'rpx' + ' ' + this.dataConfig.lrConfig.val * 2 + 'rpx' +
|
||||
' ' + 0,
|
||||
padding: this.dataConfig.upConfig.val * 2 + 'rpx' + ' ' + 0 + ' ' + this.dataConfig.downConfig.val *
|
||||
2 + 'rpx'
|
||||
}
|
||||
},
|
||||
//文章间距
|
||||
itemStyle() {
|
||||
return {
|
||||
'margin-bottom': this.dataConfig.contentConfig.val * 2 + 'rpx'
|
||||
}
|
||||
},
|
||||
//时间颜色
|
||||
timeColor() {
|
||||
return {
|
||||
'color': this.dataConfig.timeColor.color[0].item
|
||||
}
|
||||
},
|
||||
//标题颜色
|
||||
titleColor() {
|
||||
return {
|
||||
'color': this.dataConfig.titleColor.color[0].item
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.articleList {
|
||||
|
||||
.item {
|
||||
padding: 0 20rpx;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
|
||||
.text {
|
||||
width: 60%;
|
||||
|
||||
.name {
|
||||
font-size: 30rpx;
|
||||
color: #282828;
|
||||
height: 82rpx;
|
||||
}
|
||||
|
||||
.time {
|
||||
font-size: 30rpx;
|
||||
color: #999;
|
||||
margin-top: 40rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.pictrue {
|
||||
width: 37%;
|
||||
height: 156rpx;
|
||||
border-radius: 6rpx;
|
||||
|
||||
image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 6rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
864
app/components/homeIndex/bargain.vue
Normal file
864
app/components/homeIndex/bargain.vue
Normal file
@@ -0,0 +1,864 @@
|
||||
<template>
|
||||
<view class="groupBox" :style="[...boxPadding]" v-if="groupProductList.length">
|
||||
<view class="group" :style="[...boxStyle]">
|
||||
<view class="group-top acea-row row-middle row-between" :style="[bgImgStyle]">
|
||||
<view class="group-top-left acea-row">
|
||||
<image v-if="selectStyle == 0" :src="logoUrl" alt="" class="logo">
|
||||
<view v-else class="titleFont" :style="[...headerTitleConfig]">{{ titleConfig }}</view>
|
||||
<view class="interval" :style="[lineColor]"></view>
|
||||
<view class="num" :style="[titleColor]">低至0元免费拿</view>
|
||||
</view>
|
||||
<view class="group-top-right" :style="[headerBtnColor]" @click="toMore">
|
||||
更多
|
||||
<text class="iconfont icon-you" :style="[headerBtnColor]"></text>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 样式一 -->
|
||||
<view v-if="listStyle == 0" :style="[...boxBgStyle]" class="group-bottom">
|
||||
<view v-for="(item, index) in groupProductList" :key="index" :style="[contentConfig]">
|
||||
<view class=" acea-row row-between" @click="toGroupDetail(item.id,item.product)">
|
||||
<view class="group-bottom-left">
|
||||
<view class="img acea-row row-center row-middle">
|
||||
<easy-loadimage :image-src="item.image" width="250rpx" height="250rpx"
|
||||
:radius="dataConfig.contentStyle.val"></easy-loadimage>
|
||||
</view>
|
||||
</view>
|
||||
<view class="group-bottom-right acea-row row-column row-between">
|
||||
<view class="right-top">
|
||||
<view class="title line2" v-if="typeShow.includes(0)" :style="[nameColor]">
|
||||
{{item.title}}
|
||||
</view>
|
||||
<view class="pink acea-row" v-if="typeShow.includes(1)">
|
||||
<view class="people-box acea-row" :style="[groupTitleColor]">
|
||||
<view class="people" :style="[groupTitleColor]">
|
||||
<text class="iconfont icon-kanjiahuohua"></text>
|
||||
<text>{{item.sales}}人砍价成功</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="right-bottom acea-row row-between">
|
||||
<view class="price">
|
||||
<view class="pinkNum" v-if="typeShow.includes(2)" :style="[priceColor]"><text
|
||||
class="pinkNum-title"></text><text class="pinkNum-icon">¥</text><text
|
||||
class="pinkNum-num semiBold">{{item.minPrice}}</text>
|
||||
</view>
|
||||
<view class="num otNum regular" v-if="typeShow.includes(3)"
|
||||
:style="[originalColor]"><text class="num-title"></text><text
|
||||
class="icon-num ">¥{{item.price}}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="btnBox" v-if="groupBtnShow">
|
||||
<view class="btn" :style="[...btnColor]">参与砍价</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 样式二 -->
|
||||
<view class="group-bottom two acea-row row-between grid-list" v-if="listStyle == 1"
|
||||
:style="[...boxBgStyle]">
|
||||
<view v-for="(item, index) in groupProductList" :key="index" @click="toGroupDetail(item.id)">
|
||||
<view class="group-bottom-left">
|
||||
<view class="img acea-row row-center row-middle big-img">
|
||||
<easy-loadimage :image-src="item.image" width="324rpx" height="324rpx"
|
||||
:radius="dataConfig.contentStyle.val"></easy-loadimage>
|
||||
</view>
|
||||
</view>
|
||||
<view class="two-item">
|
||||
<view class="title acea-row">
|
||||
<text class="line1" v-if="typeShow.includes(0)" :style="[nameColor]">
|
||||
{{item.title}}
|
||||
</text>
|
||||
</view>
|
||||
<view class="two-item-bottom acea-row row-between">
|
||||
<view class="price">
|
||||
<view class="pinkNum" v-if="typeShow.includes(2)" :style="[priceColor]">
|
||||
<text class="num-icon">¥</text><text class="num semiBold">{{item.minPrice}}</text>
|
||||
</view>
|
||||
<view class="otNum regular" v-if="typeShow.includes(3)" :style="[originalColor]">
|
||||
¥{{item.price}}
|
||||
</view>
|
||||
</view>
|
||||
<view class="btnBox" v-if="groupBtnShow">
|
||||
<view class="btn" :style="[...btnColor]">去砍价</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 样式三 -->
|
||||
<view class="group-bottom three acea-row grid-three" v-if="listStyle == 2" :style="[...boxBgStyle]">
|
||||
<view v-for="(item, index) in groupProductList" :key="index" class="three-box"
|
||||
@click="toGroupDetail(item.id)">
|
||||
<view class="group-bottom-left">
|
||||
<view class="img acea-row row-center row-middle three-img">
|
||||
<easy-loadimage class="loadimage" width="100%" height="100%" :image-src="item.image"
|
||||
:radius="dataConfig.contentStyle.val"></easy-loadimage>
|
||||
</view>
|
||||
</view>
|
||||
<view class="two-item">
|
||||
<view class="title acea-row">
|
||||
<text class="line1" v-if="typeShow.includes(0)" :style="[nameColor]">
|
||||
{{item.title}}
|
||||
</text>
|
||||
</view>
|
||||
<view class="two-item-bottom">
|
||||
<view class="price">
|
||||
<view class="pinkNum line1" v-if="typeShow.includes(2)" :style="[priceColor]">
|
||||
<text class="num-icon"><text class="min-text">低至</text>¥</text><text
|
||||
:style="[{'font-size':item.minPrice.length>6?'30rpx':'36rpx'}]"
|
||||
class="num semiBold">{{item.minPrice}}</text>
|
||||
</view>
|
||||
<view class="otNum regular" v-if="typeShow.includes(3)" :style="[originalColor]">
|
||||
¥{{item.price}}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 样式四 -->
|
||||
<view class="group-bottom four acea-row " v-if="listStyle == 3" :style="[...boxBgStyle]">
|
||||
<scroll-view scroll-x="true" class="scroll_view">
|
||||
<view v-for="(item, index) in groupProductList" :key="index" class="four-item" :style="[fourStyle]"
|
||||
@click="toGroupDetail(item.id)">
|
||||
<view class="group-bottom-left">
|
||||
<view class="img acea-row row-center row-middle four-img">
|
||||
<easy-loadimage :image-src="item.image" width="214rpx" height="214rpx"
|
||||
:radius="dataConfig.contentStyle.val"></easy-loadimage>
|
||||
</view>
|
||||
</view>
|
||||
<view class="two-item">
|
||||
<view class="title acea-row" v-if="typeShow.includes(0)" :style="[nameColor]">
|
||||
<text class="line1">
|
||||
{{item.title}}
|
||||
</text>
|
||||
</view>
|
||||
<view class="two-item-bottom">
|
||||
<view class="price">
|
||||
<view class="people-size-box" v-if="typeShow.includes(1)" :style="[...peopleStyle]">
|
||||
<view class="people-size">{{item.sales}}人已砍成功</view>
|
||||
</view>
|
||||
<view class="pinkNum" v-if="typeShow.includes(2)" :style="[priceColor]">
|
||||
<text class="num-icon">¥</text><text
|
||||
class="num semiBold">{{item.minPrice}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
<emptyPage :mTop="'0'" v-if="groupProductList.length==0" title="暂无砍价商品,去看看其他商品吧~~"
|
||||
:imgSrc="urlDomain+'crmebimage/presets/noActivity.png'"></emptyPage>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
toLogin
|
||||
} from '@/libs/login.js';
|
||||
import {
|
||||
getBargainIndexApi
|
||||
} from '@/api/activity.js';
|
||||
import easyLoadimage from '@/components/base/easy-loadimage.vue';
|
||||
import emptyPage from '@/components/emptyPage.vue'
|
||||
import {
|
||||
mapGetters
|
||||
} from "vuex";
|
||||
let app = getApp();
|
||||
export default {
|
||||
name: 'homeBargain',
|
||||
components: {
|
||||
easyLoadimage,
|
||||
emptyPage
|
||||
},
|
||||
props: {
|
||||
dataConfig: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
urlDomain: this.$Cache.get("imgHost"),
|
||||
listStyle: 0,
|
||||
logoUrl: null,
|
||||
typeShow: [0, 1, 2, 3],
|
||||
groupBtnShow: true,
|
||||
selectStyle: '',
|
||||
titleConfig: '',
|
||||
selectBgImg: '',
|
||||
bgImgUrl: '',
|
||||
headerTitleStyle: 0,
|
||||
old: {
|
||||
scrollTop: 0
|
||||
},
|
||||
groupInfo: {},
|
||||
groupProductList: [],
|
||||
themeColor: this.$options.filters.filterTheme(app.globalData.theme)
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters({
|
||||
'userData': 'userInfo',
|
||||
'uid': 'uid'
|
||||
}),
|
||||
//容器样式
|
||||
//最外层盒子的样式
|
||||
boxStyle() {
|
||||
return [{
|
||||
'border-radius': this.dataConfig.bgStyle.val ? 2 * this.dataConfig.bgStyle.val + 'rpx' : '0'
|
||||
},
|
||||
{
|
||||
margin: 0 + ' ' + 2 * this.dataConfig.lrConfig.val + 'rpx' + ' ' + 0
|
||||
},
|
||||
{
|
||||
background: `linear-gradient(to right,${this.dataConfig.bgColor.color[0].item}, ${this.dataConfig.bgColor.color[1].item})`,
|
||||
},
|
||||
];
|
||||
},
|
||||
//边距
|
||||
boxPadding() {
|
||||
return [{
|
||||
padding: 2 * this.dataConfig.upConfig.val + 'rpx' + ' ' + '0rpx' + ' ' + 2 * this.dataConfig
|
||||
.downConfig.val + 'rpx',
|
||||
},
|
||||
{
|
||||
margin: 2 * this.dataConfig.mbConfig.val + 'rpx' + ' ' + 0 + ' ' + 0
|
||||
},
|
||||
]
|
||||
},
|
||||
//背景颜色
|
||||
boxBgStyle() {
|
||||
return [{
|
||||
gap: this.listStyle != 3 ? `${2*this.dataConfig.contentConfig.val}rpx` : ''
|
||||
},
|
||||
{
|
||||
background: `linear-gradient(to right,${this.dataConfig.contentBgColor.color[0].item}, ${this.dataConfig.contentBgColor.color[1].item})`,
|
||||
},
|
||||
{
|
||||
'justify-content': 'space-between',
|
||||
},
|
||||
];
|
||||
},
|
||||
fourStyle() {
|
||||
return {
|
||||
'margin-right': this.listStyle == 3 ? `${2*this.dataConfig.contentConfig.val}rpx` : ''
|
||||
}
|
||||
},
|
||||
//标题颜色
|
||||
titleColor() {
|
||||
return {
|
||||
color: this.dataConfig.titleColor.color[0].item,
|
||||
};
|
||||
},
|
||||
//头部按钮颜色
|
||||
headerBtnColor() {
|
||||
return {
|
||||
color: this.dataConfig.headerBtnColor.color[0].item,
|
||||
};
|
||||
},
|
||||
//商品名称颜色
|
||||
nameColor() {
|
||||
return {
|
||||
color: this.dataConfig.nameColor.color[0].item,
|
||||
};
|
||||
},
|
||||
//商品原价颜色
|
||||
originalColor() {
|
||||
return {
|
||||
color: this.dataConfig.originalColor.color[0].item,
|
||||
};
|
||||
},
|
||||
//砍价价格颜色
|
||||
priceColor() {
|
||||
return {
|
||||
color: this.dataConfig.themeStyleConfig.tabVal ? this.dataConfig.priceColor.color[0].item : this
|
||||
.themeColor,
|
||||
};
|
||||
},
|
||||
//标签颜色
|
||||
groupTitleColor() {
|
||||
return {
|
||||
color: this.dataConfig.themeStyleConfig.tabVal ?this.dataConfig.groupTitleColor.color[0].item: this
|
||||
.themeColor,
|
||||
};
|
||||
},
|
||||
peopleStyle() {
|
||||
return [{
|
||||
color: '#fff',
|
||||
},
|
||||
{
|
||||
background: `linear-gradient(to right,${
|
||||
this.dataConfig.themeStyleConfig.tabVal ? this.dataConfig.btnColor.color[0].item : '#FF7931'
|
||||
}, ${this.dataConfig.themeStyleConfig.tabVal? this.dataConfig.btnColor.color[1].item : this.themeColor})`,
|
||||
},
|
||||
{
|
||||
'align-self': 'baseline',
|
||||
},
|
||||
{
|
||||
'border-radius': '14rpx',
|
||||
},
|
||||
];
|
||||
},
|
||||
//已拼颜色
|
||||
groupTitleFontColor() {
|
||||
return {
|
||||
color: this.dataConfig.groupTitleColor.color[0].item,
|
||||
}
|
||||
},
|
||||
//分割线颜色
|
||||
lineColor() {
|
||||
return {
|
||||
border: `1rpx solid ${this.dataConfig.lineColor.color[0].item}`,
|
||||
};
|
||||
},
|
||||
//按钮颜色
|
||||
btnColor() {
|
||||
return [{
|
||||
background: `linear-gradient(to right,${
|
||||
this.dataConfig.themeStyleConfig.tabVal ? this.dataConfig.btnColor.color[0].item : '#FF7931'
|
||||
}, ${this.dataConfig.themeStyleConfig.tabVal ? this.dataConfig.btnColor.color[1].item : this.themeColor})`,
|
||||
},
|
||||
{
|
||||
color: this.dataConfig.btnFontColor.color[0].item,
|
||||
}
|
||||
];
|
||||
},
|
||||
//图片圆角
|
||||
contentStyle() {
|
||||
return {
|
||||
'border-radius': this.dataConfig.contentStyle.val ? 2 * this.dataConfig.contentStyle.val + 'rpx' : '0',
|
||||
};
|
||||
},
|
||||
//样式一内容边距
|
||||
contentConfig() {
|
||||
return {
|
||||
'paddingBottom': 2 * this.dataConfig.contentConfig.val + 'rpx',
|
||||
};
|
||||
},
|
||||
//背景图片
|
||||
bgImgStyle() {
|
||||
return {
|
||||
'background': this.selectBgImg == 0 ? `url(${this.bgImgUrl})` :
|
||||
`linear-gradient(to right,${this.dataConfig.bgColor.color[0].item}, ${this.dataConfig.bgColor.color[1].item})`,
|
||||
};
|
||||
},
|
||||
//标题文字格式
|
||||
headerTitleConfig() {
|
||||
return [{
|
||||
'font-weight': this.headerTitleStyle == 0 ? 600 : ''
|
||||
},
|
||||
{
|
||||
'font-style': this.headerTitleStyle == 2 ? 'italic' : 'normal'
|
||||
},
|
||||
{
|
||||
color: this.dataConfig.headerTitleColor.color[0].item,
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.setConfig()
|
||||
this.getInfo()
|
||||
},
|
||||
methods: {
|
||||
//去砍价
|
||||
toGroupDetail(id) {
|
||||
if (this.uid) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/activity/goods_bargain_details/index?id=${id}&startBargainUid=${this.uid}`
|
||||
})
|
||||
} else {
|
||||
toLogin()
|
||||
}
|
||||
},
|
||||
getInfo() {
|
||||
let that = this;
|
||||
getBargainIndexApi().then(function(res) {
|
||||
that.groupProductList = res.data.productList;
|
||||
that.groupInfo = {
|
||||
totalPeople: res.data.totalPeople,
|
||||
avatarList: res.data.avatarList
|
||||
}
|
||||
}).catch((res) => {
|
||||
return that.$util.Tips({
|
||||
title: res
|
||||
});
|
||||
})
|
||||
},
|
||||
scroll: function(e) {
|
||||
this.old.scrollTop = e.detail.scrollTop
|
||||
},
|
||||
// 更多
|
||||
toMore() {
|
||||
uni.navigateTo({
|
||||
url: '/pages/activity/goods_bargain/index'
|
||||
})
|
||||
},
|
||||
setConfig() {
|
||||
this.listStyle = this.dataConfig.tabConfig.tabVal;
|
||||
this.logoUrl = this.dataConfig.logoConfig.url;
|
||||
this.typeShow = this.dataConfig.typeConfig.activeValue;
|
||||
this.groupBtnShow = this.dataConfig.groupBtnConfig.tabVal == 0 ? true : false;
|
||||
this.selectStyle = this.dataConfig.selectStyle.tabVal;
|
||||
this.titleConfig = this.dataConfig.titleConfig.val;
|
||||
this.selectBgImg = this.dataConfig.selectBgImg.tabVal;
|
||||
this.bgImgUrl = this.dataConfig.bgImg.url;
|
||||
this.headerTitleStyle = this.dataConfig.headerTitleStyle.tabVal;
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.groupBox {
|
||||
overflow: hidden;
|
||||
|
||||
.group {
|
||||
overflow: hidden;
|
||||
|
||||
.group-top {
|
||||
width: 100%;
|
||||
height: 100rpx;
|
||||
padding: 0 24rpx;
|
||||
background-size: cover !important;
|
||||
|
||||
.group-top-left {
|
||||
align-items: center;
|
||||
|
||||
.ml10 {
|
||||
margin-top: 4rpx;
|
||||
}
|
||||
|
||||
.logo {
|
||||
width: 154rpx;
|
||||
height: 32rpx;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.interval {
|
||||
width: 0rpx;
|
||||
height: 28rpx;
|
||||
margin-left: 20rpx;
|
||||
margin-top: 4rpx;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.pinkHead {
|
||||
width: 108rpx;
|
||||
height: 36rpx;
|
||||
}
|
||||
|
||||
.num {
|
||||
height: 32rpx;
|
||||
line-height: 32rpx;
|
||||
font-size: 26rpx;
|
||||
margin-left: 16rpx;
|
||||
color: #FFFFFF;
|
||||
margin-top: 6rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.group-top-right {
|
||||
height: 32rpx;
|
||||
line-height: 32rpx;
|
||||
font-size: 24rpx;
|
||||
|
||||
.icon-xiangyou {
|
||||
font-size: 24rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.group-bottom {
|
||||
width: 100%;
|
||||
padding: 20rpx;
|
||||
|
||||
.img {
|
||||
width: 240rpx;
|
||||
// height: 240rpx;
|
||||
// background: #F3F9FF;
|
||||
|
||||
}
|
||||
|
||||
.big-img.img {
|
||||
width: 100%;
|
||||
height: 324rpx;
|
||||
}
|
||||
|
||||
.three-img.img {
|
||||
width: 100%;
|
||||
height: 210rpx;
|
||||
}
|
||||
|
||||
.loadimage {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.four-img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.group-bottom-right {
|
||||
flex: 1;
|
||||
margin-left: 20rpx;
|
||||
|
||||
.right-top {
|
||||
.title {
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.people-box {
|
||||
border-radius: 8rpx;
|
||||
}
|
||||
|
||||
.pink {
|
||||
margin-top: 16rpx;
|
||||
font-size: 22rpx;
|
||||
border-radius: 8rpx;
|
||||
|
||||
.people {
|
||||
color: #fff;
|
||||
padding: 4rpx 12rpx;
|
||||
border-radius: 8rpx;
|
||||
}
|
||||
|
||||
.groupNum {
|
||||
background-color: rgba(255, 255, 255, 0.9);
|
||||
padding: 4rpx 12rpx;
|
||||
border-radius: 0 6rpx 6rpx 0;
|
||||
margin-left: 2rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.right-bottom {
|
||||
|
||||
.price {
|
||||
|
||||
.pinkNum {
|
||||
|
||||
.pinkNum-num {
|
||||
font-size: 36rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.num {
|
||||
color: #999999;
|
||||
}
|
||||
}
|
||||
|
||||
.btnBox {
|
||||
// margin-top: 16rpx;
|
||||
font-size: 22rpx;
|
||||
display: flex;
|
||||
align-items: end;
|
||||
|
||||
.btn {
|
||||
padding: 12rpx 20rpx;
|
||||
border-radius: 50rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.group-bottom.two {
|
||||
.two-item {
|
||||
width: 100%;
|
||||
|
||||
.title {
|
||||
margin-top: 20rpx;
|
||||
|
||||
.numPink {
|
||||
color: #ffffff;
|
||||
padding: 6rpx 12rpx;
|
||||
border-radius: 4rpx;
|
||||
font-size: 22rpx;
|
||||
}
|
||||
|
||||
.line1 {
|
||||
width: 300rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.two-item-bottom {
|
||||
margin-top: 10rpx;
|
||||
|
||||
.pinkNum {
|
||||
|
||||
.num {
|
||||
font-size: 36rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.otNum {
|
||||
font-size: 26rpx;
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
.btnBox {
|
||||
margin-top: 16rpx;
|
||||
font-size: 22rpx;
|
||||
|
||||
.btn {
|
||||
padding: 12rpx 24rpx;
|
||||
border-radius: 50rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.group-bottom.three {
|
||||
.three-box {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.numPink {
|
||||
color: #ffffff;
|
||||
padding: 6rpx 12rpx;
|
||||
border-radius: 32rpx;
|
||||
font-size: 22rpx;
|
||||
z-index: 9;
|
||||
}
|
||||
|
||||
.two-item {
|
||||
width: 100%;
|
||||
|
||||
.title {
|
||||
margin-top: 20rpx;
|
||||
// width: 100%;
|
||||
|
||||
.numPink {
|
||||
color: #ffffff;
|
||||
padding: 4rpx 12rpx;
|
||||
border-radius: 32rpx;
|
||||
font-size: 22rpx;
|
||||
}
|
||||
|
||||
.line1 {
|
||||
width: 180rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.two-item-bottom {
|
||||
margin-top: 10rpx;
|
||||
|
||||
.pinkNum {
|
||||
|
||||
.num {
|
||||
width: 200rpx;
|
||||
font-size: 36rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.otNum {
|
||||
font-size: 26rpx;
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
.btnBox {
|
||||
margin-top: 16rpx;
|
||||
font-size: 22rpx;
|
||||
|
||||
.btn {
|
||||
padding: 12rpx 24rpx;
|
||||
border-radius: 50rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.group-bottom.four {
|
||||
overflow: hidden;
|
||||
flex-wrap: nowrap;
|
||||
position: relative;
|
||||
|
||||
.four-item {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.numPink {
|
||||
color: #ffffff;
|
||||
padding: 6rpx 12rpx;
|
||||
border-radius: 32rpx;
|
||||
font-size: 22rpx;
|
||||
z-index: 9;
|
||||
}
|
||||
|
||||
|
||||
.two-item {
|
||||
width: 210rpx;
|
||||
|
||||
.title {
|
||||
margin-top: 16rpx;
|
||||
|
||||
.numPink {
|
||||
color: #ffffff;
|
||||
padding: 6rpx 12rpx;
|
||||
border-radius: 32rpx;
|
||||
font-size: 22rpx;
|
||||
}
|
||||
|
||||
.line1 {
|
||||
width: 210rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.two-item-bottom {
|
||||
margin-top: 10rpx;
|
||||
|
||||
.pinkNum {
|
||||
margin-top: 12rpx;
|
||||
|
||||
.num {
|
||||
font-size: 36rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.otNum {
|
||||
font-size: 26rpx;
|
||||
}
|
||||
|
||||
.btnBox {
|
||||
margin-top: 16rpx;
|
||||
font-size: 22rpx;
|
||||
|
||||
.btn {
|
||||
padding: 12rpx 24rpx;
|
||||
border-radius: 50rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.price {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.grid-list {
|
||||
display: grid !important;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
grid-template-rows: auto;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.grid-three {
|
||||
width: 100%;
|
||||
display: grid !important;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
grid-template-rows: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.titleFont {
|
||||
font-size: 32rpx;
|
||||
}
|
||||
|
||||
.scroll_view {
|
||||
white-space: nowrap;
|
||||
|
||||
.four-item {
|
||||
display: inline-block;
|
||||
color: #999999;
|
||||
}
|
||||
}
|
||||
|
||||
.num-icon {
|
||||
font-weight: 500 !important;
|
||||
}
|
||||
|
||||
.numPink {
|
||||
background-color: rgba(255, 255, 255, 0.9);
|
||||
}
|
||||
|
||||
.numPink-box {
|
||||
border-radius: 8rpx;
|
||||
}
|
||||
|
||||
.numPink-box-special {
|
||||
position: absolute;
|
||||
left: 10rpx;
|
||||
top: 10rpx;
|
||||
border-radius: 32rpx;
|
||||
}
|
||||
|
||||
.avater-box {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: end;
|
||||
margin-top: 4rpx;
|
||||
|
||||
image {
|
||||
width: 36rpx;
|
||||
height: 36rpx;
|
||||
border-radius: 18rpx;
|
||||
}
|
||||
|
||||
.avater1 {
|
||||
margin-left: 20rpx;
|
||||
}
|
||||
|
||||
.avater2 {
|
||||
position: absolute;
|
||||
margin-left: 48rpx;
|
||||
}
|
||||
|
||||
.avater3 {
|
||||
position: absolute;
|
||||
left: 78rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.regular {
|
||||
line-height: 34rpx !important;
|
||||
font-weight: 400 !important;
|
||||
}
|
||||
|
||||
.otNum {
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
.people-size {
|
||||
font-size: 20rpx;
|
||||
padding: 4rpx 10rpx;
|
||||
}
|
||||
|
||||
.huo {
|
||||
width: 16rpx;
|
||||
height: 20rpx;
|
||||
vertical-align: baseline;
|
||||
margin-right: 4rpx;
|
||||
}
|
||||
|
||||
.icon-kanjiahuohua {
|
||||
font-size: 24rpx;
|
||||
}
|
||||
|
||||
.min-text {
|
||||
font-size: 22rpx !important;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.icon-you {
|
||||
font-size: 24rpx;
|
||||
}
|
||||
|
||||
.regular {
|
||||
line-height: 17px !important;
|
||||
}
|
||||
</style>
|
||||
45
app/components/homeIndex/blankPage.vue
Normal file
45
app/components/homeIndex/blankPage.vue
Normal file
@@ -0,0 +1,45 @@
|
||||
<template>
|
||||
<!-- 辅助空白-->
|
||||
<view>
|
||||
<view :style="[boxStyle]"></view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
export default {
|
||||
name: 'blankPage',
|
||||
props: {
|
||||
dataConfig: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
//最外层盒子的样式
|
||||
boxStyle() {
|
||||
return {
|
||||
height: this.dataConfig.heightConfig.val + 'px',
|
||||
background: `linear-gradient(${this.dataConfig.bgColor.color[0].item}, ${this.dataConfig.bgColor.color[1].item})`,
|
||||
margin: this.dataConfig.mbConfig.val * 2 + 'rpx' + ' ' + this.dataConfig.lrConfig.val * 2 + 'rpx' +
|
||||
' ' + 0,
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.blankPage {
|
||||
.bankCon {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
197
app/components/homeIndex/cateNav.vue
Normal file
197
app/components/homeIndex/cateNav.vue
Normal file
@@ -0,0 +1,197 @@
|
||||
<template>
|
||||
<!-- 商品分类 -->
|
||||
<view>
|
||||
<!-- #ifdef MP || APP-PLUS -->
|
||||
<!-- <view style="visibility: hidden;" :style="{ height: navHeight + 'rpx' }"></view> -->
|
||||
<!-- #endif -->
|
||||
<view class="navTabBox" :class="{isFixed:isFixed}" :style="[boxStyle]">
|
||||
<view class="longTab">
|
||||
<scroll-view scroll-x="true" style="white-space: nowrap; display: flex;" scroll-with-animation
|
||||
:scroll-left="tabLeft" show-scrollbar="true">
|
||||
<view class="longItem"
|
||||
:style="'color:' + (index == tabClick ? checkColor : fontColor)+';--color:'+checkColor"
|
||||
:data-index="index" :class="index===tabClick?'click':''" v-for="(item,index) in tabList"
|
||||
:key="index" :id="'id'+index" @click="longClick(index,item)">{{ item.title }}
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</view>
|
||||
<view style="height: 70rpx"></view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
let app = getApp();
|
||||
export default {
|
||||
name: 'tabNav',
|
||||
props: {
|
||||
dataConfig: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
},
|
||||
//是否固定
|
||||
isFixed: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
tabClick: 0, //导航栏被点击
|
||||
isLeft: 0, //导航栏下划线位置
|
||||
isWidth: 0, //每个导航栏占位
|
||||
mainWidth: 0,
|
||||
tabLeft: 0,
|
||||
isTop: 0,
|
||||
navHeight: 35,
|
||||
tabItem: null ,//tab选中的对象
|
||||
themeColor:this.$options.filters.filterTheme(app.globalData.theme)
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
//外部盒子
|
||||
boxStyle() {
|
||||
return {
|
||||
borderRadius: this.dataConfig.bgStyle.val * 2 + 'rpx',
|
||||
background: `linear-gradient(${this.dataConfig.bgColor.color[0].item}, ${this.dataConfig.bgColor.color[1].item})`,
|
||||
margin: 0 + ' ' + 2*this.dataConfig.lrConfig.val + 'rpx' + ' ' + 0 ,
|
||||
// padding: 2*this.dataConfig.upConfig.val + 'rpx' + ' ' + '20rpx' + ' ' + 2*this.dataConfig.downConfig.val + 'rpx' ,
|
||||
}
|
||||
},
|
||||
//标签文字颜色
|
||||
fontColor() {
|
||||
return this.dataConfig.fontColor.color[0].item
|
||||
},
|
||||
//选中颜色
|
||||
checkColor() {
|
||||
return this.dataConfig.themeStyleConfig.tabVal?this.dataConfig.checkColor.color[0].item:this.themeColor
|
||||
},
|
||||
tabList() {
|
||||
//type=0微页面,1分类,2首页
|
||||
let tabList = this.dataConfig.listConfig.list;
|
||||
tabList.unshift({
|
||||
title: '首页',
|
||||
type: 2,
|
||||
val: 0
|
||||
})
|
||||
return tabList
|
||||
},
|
||||
},
|
||||
created() {
|
||||
let that = this
|
||||
// 获取设备宽度
|
||||
uni.getSystemInfo({
|
||||
success(e) {
|
||||
//that.mainWidth = e.windowWidth
|
||||
that.isWidth = (e.windowWidth) / 5
|
||||
}
|
||||
})
|
||||
setTimeout((e) => {
|
||||
let statusHeight = uni.getSystemInfoSync().statusBarHeight;
|
||||
const query = uni.createSelectorQuery().in(this);
|
||||
query.select('.navTabBox').boundingClientRect(data => {
|
||||
that.navHeight = (data.height + statusHeight) * 2;
|
||||
}).exec();
|
||||
}, 300)
|
||||
that.$nextTick(function() {
|
||||
uni.getSystemInfo({
|
||||
success: function(res) {
|
||||
that.windowHeight = res.windowHeight;
|
||||
}
|
||||
});
|
||||
})
|
||||
// #ifdef MP || APP-PLUS
|
||||
this.isTop = (uni.getSystemInfoSync().statusBarHeight + 43) + 'px'
|
||||
// #endif
|
||||
// #ifdef H5
|
||||
this.isTop = 0
|
||||
// #endif
|
||||
},
|
||||
watch: {
|
||||
tabClick: {
|
||||
handler(newValue, oldValue) {
|
||||
if (this.tabItem) this.$emit('changeTab', newValue, this.tabItem);
|
||||
},
|
||||
immediate: true
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 导航栏点击
|
||||
longClick(index, item) {
|
||||
this.tabItem = item;
|
||||
this.tabClick = index; //设置导航点击了哪一个
|
||||
this.$nextTick(() => {
|
||||
let id = 'id' + index;
|
||||
this.tabLeft = (index - 2) * this.isWidth //设置下划线位置
|
||||
//this.$emit('changeTab', index,item);
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.navTabBox {
|
||||
width: 100%;
|
||||
height: 70rpx;
|
||||
color: rgba(255, 255, 255, 1);
|
||||
position: fixed;
|
||||
z-index: 99;
|
||||
padding: 0 20rpx;
|
||||
&.isFixed {
|
||||
z-index: 10;
|
||||
position: fixed;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
/* #ifdef H5 */
|
||||
top: 0;
|
||||
/* #endif */
|
||||
}
|
||||
|
||||
.click {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.longTab {
|
||||
.longItem {
|
||||
height: 70rpx;
|
||||
display: inline-block;
|
||||
line-height: 70rpx;
|
||||
text-align: center;
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
margin-right: 30rpx;
|
||||
&.click {
|
||||
font-weight: bold;
|
||||
font-size: 30rpx;
|
||||
position: relative;
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
width: 40rpx;
|
||||
height: 4rpx;
|
||||
background: var(--color);
|
||||
// background-color: #E93323;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
172
app/components/homeIndex/countDown.vue
Normal file
172
app/components/homeIndex/countDown.vue
Normal file
@@ -0,0 +1,172 @@
|
||||
<template>
|
||||
<!-- 时间倒计时 -->
|
||||
<view class="time" :style="justifyLeft">
|
||||
<text class="" v-if="tipText">{{ tipText }}</text>
|
||||
<text class="styleAll p6" v-if="isDay === true" :style="{background:bgColor.bgColor,color:bgColor.Color}">{{ day }}{{bgColor.isDay?'天':''}}</text>
|
||||
<text class="timeTxt" v-if="dayText" :style="{width:bgColor.timeTxtwidth,color:bgColor.bgColor}">{{ dayText }}</text>
|
||||
<text class="styleAll" :class='isCol?"timeCol":""' :style="{background:bgColor.bgColor,color:bgColor.Color,width:bgColor.width}">{{ hour }}</text>
|
||||
<text class="timeTxt" v-if="hourText" :class='isCol?"whit":""' :style="{width:bgColor.timeTxtwidth,color:bgColor.bgColor}">{{ hourText }}</text>
|
||||
<text class="styleAll" :class='isCol?"timeCol":""' :style="{background:bgColor.bgColor,color:bgColor.Color,width:bgColor.width}">{{ minute }}</text>
|
||||
<text class="timeTxt" v-if="minuteText" :class='isCol?"whit":""' :style="{width:bgColor.timeTxtwidth,color:bgColor.bgColor}">{{ minuteText }}</text>
|
||||
<text class="styleAll" :class='isCol?"timeCol":""' :style="{background:bgColor.bgColor,color:bgColor.Color,width:bgColor.width}">{{ second }}</text>
|
||||
<text class="timeTxt" v-if="secondText">{{ secondText }}</text>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
export default {
|
||||
name: "countDown",
|
||||
props: {
|
||||
justifyLeft: {
|
||||
type: String,
|
||||
default: ""
|
||||
},
|
||||
//距离开始提示文字
|
||||
tipText: {
|
||||
type: String,
|
||||
default: "倒计时"
|
||||
},
|
||||
dayText: {
|
||||
type: String,
|
||||
default: "天"
|
||||
},
|
||||
hourText: {
|
||||
type: String,
|
||||
default: "时"
|
||||
},
|
||||
minuteText: {
|
||||
type: String,
|
||||
default: "分"
|
||||
},
|
||||
secondText: {
|
||||
type: String,
|
||||
default: "秒"
|
||||
},
|
||||
datatime: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
isDay: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
isCol: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
bgColor: {
|
||||
type: Object,
|
||||
default: null
|
||||
}
|
||||
},
|
||||
data: function() {
|
||||
return {
|
||||
day: "00",
|
||||
hour: "00",
|
||||
minute: "00",
|
||||
second: "00"
|
||||
};
|
||||
},
|
||||
created: function() {
|
||||
this.show_time();
|
||||
},
|
||||
mounted: function() {},
|
||||
methods: {
|
||||
show_time: function() {
|
||||
let that = this;
|
||||
|
||||
function runTime() {
|
||||
//时间函数
|
||||
let intDiff = that.datatime - Date.parse(new Date()) / 1000; //获取数据中的时间戳的时间差;
|
||||
let day = 0,
|
||||
hour = 0,
|
||||
minute = 0,
|
||||
second = 0;
|
||||
if (intDiff > 0) {
|
||||
//转换时间
|
||||
if (that.isDay === true) {
|
||||
day = Math.floor(intDiff / (60 * 60 * 24));
|
||||
} else {
|
||||
day = 0;
|
||||
}
|
||||
hour = Math.floor(intDiff / (60 * 60)) - day * 24;
|
||||
minute = Math.floor(intDiff / 60) - day * 24 * 60 - hour * 60;
|
||||
second =
|
||||
Math.floor(intDiff) -
|
||||
day * 24 * 60 * 60 -
|
||||
hour * 60 * 60 -
|
||||
minute * 60;
|
||||
if (hour <= 9) hour = "0" + hour;
|
||||
if (minute <= 9) minute = "0" + minute;
|
||||
if (second <= 9) second = "0" + second;
|
||||
that.day = day;
|
||||
that.hour = hour;
|
||||
that.minute = minute;
|
||||
that.second = second;
|
||||
} else {
|
||||
that.day = "00";
|
||||
that.hour = "00";
|
||||
that.minute = "00";
|
||||
that.second = "00";
|
||||
}
|
||||
}
|
||||
runTime();
|
||||
setInterval(runTime, 1000);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.p6{
|
||||
padding: 0 8rpx;
|
||||
}
|
||||
.styleAll{
|
||||
/* color: #fff; */
|
||||
font-size: 24rpx;
|
||||
height: 36rpx;
|
||||
line-height: 36rpx;
|
||||
border-radius: 6rpx;
|
||||
text-align: center;
|
||||
/* padding: 0 6rpx; */
|
||||
}
|
||||
.timeTxt{
|
||||
text-align: center;
|
||||
/* width: 16rpx; */
|
||||
height: 36rpx;
|
||||
line-height: 36rpx;
|
||||
display: inline-block;
|
||||
}
|
||||
.whit{
|
||||
color: #fff !important;
|
||||
}
|
||||
.time {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.red {
|
||||
color: #fc4141;
|
||||
margin: 0 4rpx;
|
||||
}
|
||||
|
||||
.timeCol {
|
||||
/* width: 40rpx;
|
||||
height: 40rpx;
|
||||
line-height: 40rpx;
|
||||
text-align:center;
|
||||
border-radius: 6px;
|
||||
background: #fff;
|
||||
font-size: 24rpx; */
|
||||
color: #E93323;
|
||||
}
|
||||
</style>
|
||||
464
app/components/homeIndex/coupon.vue
Normal file
464
app/components/homeIndex/coupon.vue
Normal file
@@ -0,0 +1,464 @@
|
||||
<template>
|
||||
<!-- 优惠券 -->
|
||||
<view v-if="couponList.length">
|
||||
<view :style="[...boxStyle]">
|
||||
<template v-if="listStyle == 0">
|
||||
<view class="scroll_box">
|
||||
<scroll-view scroll-x="true" class="scroll_view acea-row">
|
||||
<view class="no-warp acea-row row-middle">
|
||||
<view class="couponBg acea-row row-middle style1" v-for="(item, index) in couponList" :key="index"
|
||||
:style="[...contentConfig]">
|
||||
<view class="left">
|
||||
<view :style="[...priceColorStyle]"><text class="price-icon">¥</text><text
|
||||
class="price"
|
||||
:class="item.money.length>6?'sizePrice':''">{{item.money}}</text></view>
|
||||
<view class="title" :class="item.minPrice.length>6?'sizeTitle':''">
|
||||
满{{item.minPrice}}元可用</view>
|
||||
</view>
|
||||
<view class="right" @click="getCoupon(item.isUse,item.id)">
|
||||
{{item.isUse?'已 领 取':'领 取'}}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</template>
|
||||
<template v-if="listStyle == 1">
|
||||
<view class="coupon1 acea-row row-middle">
|
||||
<scroll-view scroll-x="true" class="scroll_view">
|
||||
<view class="list acea-row row-middle">
|
||||
<view class="item" v-for="(item, index) in couponList" :key="index"
|
||||
:style="[...contentConfig]">
|
||||
<view class="money" :style="[...priceColorStyle]">
|
||||
<view :class="item.money.length>=6?'sizePrice-two':''"><text class="lable"
|
||||
:class="item.money.length>=6?'sizeLable-two':''">¥</text>{{item.money}}
|
||||
</view>
|
||||
<view class="tips">满{{item.minPrice}}可用</view>
|
||||
</view>
|
||||
<view class="sill" :style="[...btnColorStyle]" @click="getCoupon(item.isUse,item.id)">
|
||||
{{item.isUse?'已领取':'去领取'}}
|
||||
</view>
|
||||
<image src="../../static/images/newVip02.png" />
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</template>
|
||||
<template v-if="listStyle == 2">
|
||||
<view class="scroll_box">
|
||||
<scroll-view scroll-x="true" class="scroll_view acea-row">
|
||||
<view class="no-warp acea-row row-middle">
|
||||
<view class="couponBg acea-row row-middle couponBg-new" v-for="(item, index) in couponList" :key="index"
|
||||
:style="[...contentConfig]">
|
||||
<view class="left">
|
||||
<view :style="[...priceColorStyle]"><text class="price-icon">¥</text><text
|
||||
class="price"
|
||||
:class="item.money.length>6?'sizePrice':''">{{item.money}}</text></view>
|
||||
<view class="title" :class="item.minPrice.length>6?'sizeTitle':''">
|
||||
满{{item.minPrice}}元可用</view>
|
||||
</view>
|
||||
<view class="right" @click="getCoupon(item.isUse,item.id)" v-if="!item.isUse">
|
||||
立即领取
|
||||
</view>
|
||||
<view class="right" @click="getCoupon(item.isUse,item.id)" v-else>
|
||||
立即使用
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</template>
|
||||
<template v-if="listStyle == 3">
|
||||
<view class="coupon5 acea-row row-middle" :style="[...boxBg]">
|
||||
<scroll-view scroll-x="true" style="white-space: nowrap; display: flex">
|
||||
<view class="list acea-row row-middle">
|
||||
<view class="item acea-row row-middle" v-for="(item, index) in couponList" :key="index"
|
||||
:style="[...contentConfig]">
|
||||
<view class="left">
|
||||
<view :class="item.money.length>=6?'sizePrice-four':''"
|
||||
:style="[...priceColorStyle]" class="money"><text
|
||||
class="label">¥</text>{{item.money}}
|
||||
</view>
|
||||
<view class="tips">满{{item.minPrice}}可用</view>
|
||||
</view>
|
||||
<view class="right acea-row row-center">
|
||||
<view class="rightCon" @click="getCoupon(item.isUse,item.id)">
|
||||
{{item.isUse?'已 领 取':'领 取'}}
|
||||
</view>
|
||||
</view>
|
||||
<view class="roll" :style="[...boxBg]"></view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</template>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
import {
|
||||
getCoupons,
|
||||
setCouponReceive
|
||||
} from "@/api/api.js"
|
||||
let app = getApp();
|
||||
export default {
|
||||
name: 'homeCoupon',
|
||||
props: {
|
||||
dataConfig: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
urlDomain: this.$Cache.get("imgHost"),
|
||||
couponList: [],
|
||||
listStyle: 0,
|
||||
themeColor:this.$options.filters.filterTheme(app.globalData.theme)
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
//最外层盒子的样式
|
||||
boxStyle() {
|
||||
return [{
|
||||
'border-radius': 2 * this.dataConfig.bgStyle.val ? 2 * this.dataConfig.bgStyle.val + 'rpx' :
|
||||
'0'
|
||||
},
|
||||
{
|
||||
background: this.listStyle != 3 ?
|
||||
`linear-gradient(to right,${this.dataConfig.bgColor.color[0].item}, ${this.dataConfig.bgColor.color[1].item})` :
|
||||
this.dataConfig.bgColorNew.color[0].item,
|
||||
},
|
||||
{
|
||||
'margin': 2 * this.dataConfig.mbConfig.val + 'rpx' + ' ' + 2 * this.dataConfig.lrConfig.val +
|
||||
'rpx' +
|
||||
' ' + 0
|
||||
},
|
||||
{
|
||||
'padding': 2 * this.dataConfig.upConfig.val + 'rpx' + ' ' + '20rpx' + ' ' + 2 * this.dataConfig
|
||||
.downConfig
|
||||
.val + 'rpx'
|
||||
},
|
||||
];
|
||||
},
|
||||
boxBg() {
|
||||
return [{
|
||||
background: this.dataConfig.bgColorNew.color[0].item,
|
||||
}, ];
|
||||
},
|
||||
//内容边距
|
||||
contentConfig() {
|
||||
return [{
|
||||
'margin-right': this.dataConfig.contentConfig.val ? 2 * this.dataConfig.contentConfig.val +
|
||||
'rpx' : '0'
|
||||
},
|
||||
{
|
||||
'background': this.listStyle == 1 ?
|
||||
(this.dataConfig.themeStyleConfig.tabVal?this.dataConfig.itemBgColor.color[0].item:this.themeColor) : this.listStyle == 3 ?
|
||||
`linear-gradient(180deg,${this.dataConfig.btnColor.color[0].item}, ${this.dataConfig.themeStyleConfig.tabVal?this.dataConfig.btnColor.color[1].item:this.themeColor})` :
|
||||
'',
|
||||
},
|
||||
];
|
||||
},
|
||||
//优惠金额颜色
|
||||
priceColorStyle() {
|
||||
return [{
|
||||
'color': this.dataConfig.themeStyleConfig.tabVal?this.dataConfig.priceColor.color[0].item:this.themeColor
|
||||
}];
|
||||
},
|
||||
//领取按钮
|
||||
btnColorStyle() {
|
||||
return [{
|
||||
'background': `linear-gradient(90deg,${this.dataConfig.themeStyleConfig.tabVal?this.dataConfig.btnColor.color[0].item:'#FF7931'}, ${this.dataConfig.themeStyleConfig.tabVal?this.dataConfig.btnColor.color[1].item:this.themeColor})`,
|
||||
}, ];
|
||||
},
|
||||
//展示数量
|
||||
limit() {
|
||||
return this.dataConfig.numConfig.val
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.getList();
|
||||
this.setConfig()
|
||||
},
|
||||
methods: {
|
||||
getCoupon(isUse, id) {
|
||||
let that = this
|
||||
if (!isUse) {
|
||||
setCouponReceive(id).then(res => {
|
||||
that.getList();
|
||||
})
|
||||
}
|
||||
},
|
||||
setConfig(data) {
|
||||
this.listStyle = this.dataConfig.tabConfig.tabVal;
|
||||
},
|
||||
//优惠券列表
|
||||
getList() {
|
||||
getCoupons({
|
||||
page: 1,
|
||||
limit: this.limit
|
||||
}).then(res => {
|
||||
this.couponList = res.data.list;
|
||||
})
|
||||
},
|
||||
//去更多
|
||||
goPage() {
|
||||
this.$util.navigateTo(this.dataConfig.linkConfig.val ? this.dataConfig.linkConfig.val :
|
||||
'/pages/activity/couponList/index')
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.scroll_box {
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
}
|
||||
.couponBg.style1{
|
||||
width: 254rpx;
|
||||
height: 144rpx;
|
||||
background: url('../../static/images/couponBg.png');
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
.couponBg {
|
||||
background-size: contain;
|
||||
background-repeat: no-repeat;
|
||||
flex-shrink: 0;
|
||||
color: #fff;
|
||||
.left {
|
||||
width: 80%;
|
||||
text-align: center;
|
||||
|
||||
.price-icon {
|
||||
font-weight: 500;
|
||||
font-size: 30rpx;
|
||||
}
|
||||
|
||||
.price {
|
||||
font-weight: 500;
|
||||
font-size: 52rpx;
|
||||
}
|
||||
|
||||
.sizePrice {
|
||||
font-size: 38rpx !important;
|
||||
}
|
||||
|
||||
.sizeTitle {
|
||||
font-size: 20rpx !important;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-weight: 400;
|
||||
font-size: 26rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.right {
|
||||
/* #ifdef H5 */
|
||||
margin-left: 10rpx;
|
||||
/* #endif */
|
||||
font-size: 26rpx;
|
||||
text-align: center;
|
||||
writing-mode: tb-rl;
|
||||
}
|
||||
}
|
||||
.couponBg-new.couponBg {
|
||||
width: 137px;
|
||||
height: 75px;
|
||||
background: url('../../static/images/couponBg2.png') !important;
|
||||
.right {
|
||||
width: 13%;
|
||||
color: #e93323;
|
||||
font-weight: 400;
|
||||
font-size: 13px;
|
||||
}
|
||||
.title {
|
||||
color: #e93323;
|
||||
}
|
||||
.sizePrice {
|
||||
font-size: 36rpx !important;
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
}
|
||||
.coupon1 {
|
||||
flex-shrink: 0;
|
||||
overflow: hidden;
|
||||
|
||||
.list {
|
||||
margin-top: 16rpx;
|
||||
display: inline-flex;
|
||||
flex-wrap: nowrap;
|
||||
|
||||
.item {
|
||||
width: 156rpx;
|
||||
height: 152rpx;
|
||||
background: #f12a13;
|
||||
position: relative;
|
||||
border-radius: 12rpx 12rpx 30rpx 30rpx;
|
||||
|
||||
.money {
|
||||
width: 140rpx;
|
||||
height: 106rpx;
|
||||
background: #ffffff;
|
||||
border: 2rpx solid #fceae9;
|
||||
position: absolute;
|
||||
left: 9rpx;
|
||||
top: -16rpx;
|
||||
text-align: center;
|
||||
font-size: 40rpx;
|
||||
font-family: D-DIN-PRO, D-DIN-PRO;
|
||||
font-weight: 600;
|
||||
color: #e93323;
|
||||
padding-top: 6px;
|
||||
border-radius: 12rpx 12rpx 0 0;
|
||||
|
||||
.lable {
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.tips {
|
||||
font-size: 18rpx;
|
||||
color: #999999;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.sizePrice {
|
||||
// font-size: 24rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.sill {
|
||||
position: absolute;
|
||||
bottom: -2rpx;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 78rpx;
|
||||
// background: linear-gradient(90deg, #e93323 0%, #ff7931 100%);
|
||||
color: #fff;
|
||||
line-height: 92rpx;
|
||||
border-radius: 0 0 30rpx 30rpx;
|
||||
font-size: 20rpx;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
image {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
width: 156rpx;
|
||||
height: 20rpx;
|
||||
bottom: 58rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
.coupon5 {
|
||||
flex-shrink: 0;
|
||||
background: #ffffff;
|
||||
border-radius: 16rpx;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
|
||||
.list {
|
||||
flex-wrap: nowrap;
|
||||
|
||||
.item {
|
||||
flex-shrink: 0;
|
||||
width: 228rpx;
|
||||
height: 108rpx;
|
||||
border-radius: 12rpx;
|
||||
position: relative;
|
||||
|
||||
.roll {
|
||||
width: 16rpx;
|
||||
height: 16rpx;
|
||||
background: #fff;
|
||||
border-radius: 50%;
|
||||
position: absolute;
|
||||
left: -8rpx;
|
||||
}
|
||||
|
||||
.right {
|
||||
flex: 1;
|
||||
|
||||
.rightCon {
|
||||
font-size: 22rpx;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
writing-mode: tb-rl;
|
||||
}
|
||||
}
|
||||
|
||||
.left {
|
||||
width: 172rpx;
|
||||
height: 100%;
|
||||
background: linear-gradient(0deg, rgba(255, 255, 255, 0.9) 0%, rgba(255, 255, 255, 0.8) 100%);
|
||||
border-radius: 12rpx;
|
||||
text-align: center;
|
||||
color: #e93323;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
|
||||
.money {
|
||||
font-size: 42rpx;
|
||||
font-family: D-DIN-PRO, D-DIN-PRO;
|
||||
font-weight: 600;
|
||||
|
||||
.label {
|
||||
font-size: 28rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.tips {
|
||||
font-size: 22rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.no-warp {
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
|
||||
.scroll_view {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.sizePrice-two {
|
||||
font-size: 24rpx;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.sizeLable-two {
|
||||
font-size: 18rpx !important;
|
||||
}
|
||||
|
||||
.sizePrice-three {
|
||||
font-size: 32rpx !important;
|
||||
}
|
||||
|
||||
.sizePrice-three-tips {
|
||||
font-size: 22rpx !important;
|
||||
margin-left: 6rpx !important;
|
||||
}
|
||||
|
||||
.sizePrice-four {
|
||||
font-size: 30rpx !important;
|
||||
}
|
||||
</style>
|
||||
543
app/components/homeIndex/goodList.vue
Normal file
543
app/components/homeIndex/goodList.vue
Normal file
@@ -0,0 +1,543 @@
|
||||
<template>
|
||||
<!-- 商品列表 -->
|
||||
<view>
|
||||
<view v-if="tempArr.length" :style="[boxStyle]">
|
||||
<!-- 单列 -->
|
||||
<block v-if="itemStyle == 0">
|
||||
<view class="listA" :style="[gridGap]">
|
||||
<view class="item" v-for="(item, index) in tempArr" :key="index" @click="goDetail(item)">
|
||||
<view class="pictrue">
|
||||
<easy-loadimage :image-src="item.image" :radius="dataConfig.contentStyle.val">
|
||||
</easy-loadimage>
|
||||
<view v-if="item.activityStyle" :style="{ backgroundImage: `url(${item.activityStyle})` }"
|
||||
class="border-picture"></view>
|
||||
</view>
|
||||
<view class="text-info text-add">
|
||||
<view>
|
||||
<view class="title line2" :style="[titleColor]" v-if="titleShow">
|
||||
<span>{{ item.storeName }}</span>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="item.productTags && item.productTags.locationUnderTitle.length">
|
||||
<text
|
||||
v-for="items in item.productTags.locationUnderTitle.length>3?item.productTags.locationUnderTitle.slice(0,3):item.productTags.locationUnderTitle"
|
||||
:key="items.id" class="mr10 tagSolid">{{items.tagName}}</text>
|
||||
</view>
|
||||
<view class="price acea-row row-middle" :style="[priceColor]">
|
||||
<view v-if="priceShow">
|
||||
¥<span class="num semiBold">{{item.price}}</span>
|
||||
</view>
|
||||
</view>
|
||||
<view class="old-price" :style="[soldColor]" v-if="soldShow">已售
|
||||
{{ item.sales|| 0 }} {{item.unitName}}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
<!-- 两列 -->
|
||||
<block v-if="itemStyle == 1">
|
||||
<view class="listC" :style="[gridGap]">
|
||||
<view class="item" :style="[contentStyle]" v-for="(item, index) in tempArr" :key="index"
|
||||
@click="goDetail(item)">
|
||||
<view class="pictrue">
|
||||
<easy-loadimage :image-src="item.image" :radius="dataConfig.contentStyle.val">
|
||||
</easy-loadimage>
|
||||
<view v-if="item.activityStyle" :style="{ backgroundImage: `url(${item.activityStyle})` }"
|
||||
class="border-picture"></view>
|
||||
</view>
|
||||
<view class="text-info">
|
||||
<view class="title line2" :style="[titleColor]" v-if="titleShow">
|
||||
<span>{{ item.storeName }}</span>
|
||||
</view>
|
||||
<view v-if="item.productTags && item.productTags.locationUnderTitle.length">
|
||||
<text
|
||||
v-for="items in item.productTags.locationUnderTitle.length>3?item.productTags.locationUnderTitle.slice(0,3):item.productTags.locationUnderTitle"
|
||||
:key="items.id" class="mr10 tagSolid">{{items.tagName}}</text>
|
||||
</view>
|
||||
<view class="acea-row row-middle price" :style="[priceColor]">
|
||||
<view v-if="priceShow">
|
||||
¥<span class="num semiBold">{{item.price}}</span>
|
||||
</view>
|
||||
</view>
|
||||
<view class="old-price" :style="[soldColor]" v-if="soldShow">已售
|
||||
{{ item.sales|| 0 }} {{item.unitName}}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
<!-- 三列 -->
|
||||
<block v-if="itemStyle == 2">
|
||||
<view class="listB" :style="[gridGap]">
|
||||
<view class="item" v-for="(item, index) in tempArr" :key="index" @click="goDetail(item)">
|
||||
<view class="pictrue">
|
||||
<easy-loadimage :image-src="item.image" :radius="dataConfig.contentStyle.val">
|
||||
</easy-loadimage>
|
||||
<view v-if="item.activityStyle" :style="{ backgroundImage: `url(${item.activityStyle})` }"
|
||||
class="border-picture"></view>
|
||||
</view>
|
||||
<view class="text-info">
|
||||
<view class="title line2" :style="[titleColor]" v-if="titleShow">
|
||||
<span>{{ item.storeName }}</span>
|
||||
</view>
|
||||
<view v-if="item.productTags && item.productTags.locationUnderTitle.length">
|
||||
<text
|
||||
v-for="items in item.productTags.locationUnderTitle.length>3?item.productTags.locationUnderTitle.slice(0,3):item.productTags.locationUnderTitle"
|
||||
:key="items.id" class="mr10 tagSolid">{{items.tagName}}</text>
|
||||
</view>
|
||||
<view class="price" :style="[priceColor]">
|
||||
<view v-if="priceShow">
|
||||
¥<span class="num semiBold">{{item.price}}</span>
|
||||
</view>
|
||||
</view>
|
||||
<view class="old-price" v-if="soldShow" :style="[soldColor]">
|
||||
已售 {{ item.sales|| 0 }} {{ item.unitName }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
<!-- 大图 -->
|
||||
<block v-if="itemStyle == 3 && tempArr.length">
|
||||
<view class="listBig" :style="[gridGap]">
|
||||
<view class="itemBig" v-for="(item,index) in tempArr" :key="index" @click="goDetail(item)">
|
||||
<view class="img-box">
|
||||
<easy-loadimage :image-src="item.image" :radius="dataConfig.contentStyle.val">
|
||||
</easy-loadimage>
|
||||
<view v-if="item.activityStyle" :style="{ backgroundImage: `url(${item.activityStyle})` }"
|
||||
class="border-picture"></view>
|
||||
</view>
|
||||
<view class="name line2" :style="[titleColor]" v-if="titleShow">
|
||||
<span>{{item.storeName}}</span>
|
||||
</view>
|
||||
<view style="padding: 0 8px;"
|
||||
v-if="item.productTags && item.productTags.locationUnderTitle.length">
|
||||
<text
|
||||
v-for="items in item.productTags.locationUnderTitle.length>3?item.productTags.locationUnderTitle.slice(0,3):item.productTags.locationUnderTitle"
|
||||
:key="items.id" class="mr10 tagSolid">{{items.tagName}}</text>
|
||||
</view>
|
||||
<slot name="center"></slot>
|
||||
<view class="acea-row row-middle price" :style="[priceColor]">
|
||||
<view v-if="priceShow">
|
||||
¥<span class="num semiBold">{{item.price}}</span>
|
||||
</view>
|
||||
</view>
|
||||
<view class="old-price mt20" :style="[soldColor]" v-if="soldShow">已售
|
||||
{{ item.sales || 0 }} {{item.unitName}}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
<view class='loadingicon acea-row row-center-wrapper' :hidden='loading==false'>
|
||||
<text class='loading iconfont icon-jiazai'></text>
|
||||
</view>
|
||||
<!-- <view class="mores-txt" v-if="goodScroll">
|
||||
<text>我是有底线的</text>
|
||||
</view> -->
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
import {
|
||||
getProductslist,productByidsApi
|
||||
} from '@/api/store.js';
|
||||
let app = getApp();
|
||||
import easyLoadimage from '@/components/base/easy-loadimage.vue';
|
||||
export default {
|
||||
name: 'goodList',
|
||||
props: {
|
||||
dataConfig: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
},
|
||||
},
|
||||
components: {
|
||||
easyLoadimage,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
//普通价格
|
||||
svipPriceStyle: {
|
||||
svipBox: {
|
||||
height: '26rpx',
|
||||
borderRadius: '60rpx 56rpx 56rpx 20rpx',
|
||||
},
|
||||
icon: {
|
||||
height: '26rpx',
|
||||
fontSize: '18rpx',
|
||||
borderRadius: '12rpx 0 12rpx 2rpx'
|
||||
},
|
||||
price: {
|
||||
fontSize: '38rpx'
|
||||
},
|
||||
svipPrice: {
|
||||
fontSize: '22rpx'
|
||||
}
|
||||
},
|
||||
//svip价格
|
||||
svipIconStyle: {
|
||||
svipBox: {
|
||||
height: '26rpx',
|
||||
borderRadius: '24rpx 40rpx 40rpx 0.4rpx',
|
||||
},
|
||||
price: {
|
||||
fontSize: '38rpx'
|
||||
},
|
||||
svipPrice: {
|
||||
fontSize: '18rpx'
|
||||
}
|
||||
},
|
||||
tempArr: [],
|
||||
numConfig: this.dataConfig.numConfig.val, //展示多少条
|
||||
itemStyle: this.dataConfig.itemStyle.tabVal, //商品列表展示方式 单列 两列 三列
|
||||
type: this.dataConfig.tabConfig.tabVal || 0, //商品类型 0指定商品,1指定品牌,2指定分类,3指定商户
|
||||
selectId: this.dataConfig.selectConfig ? this.dataConfig.selectConfig.activeValue : [], //分类
|
||||
productIds: this.dataConfig.goodsList.ids || [],
|
||||
params: { //精品推荐分页
|
||||
page: 1,
|
||||
limit: 10,
|
||||
cid: '',
|
||||
priceOrder: '',
|
||||
salesOrder: ''
|
||||
},
|
||||
goodScroll: false,
|
||||
loading: false,
|
||||
themeColor:this.$options.filters.filterTheme(app.globalData.theme)
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
//商品名称颜色
|
||||
titleColor() {
|
||||
return {
|
||||
'color': this.dataConfig.titleColor.color[0].item,
|
||||
}
|
||||
},
|
||||
//最外层盒子的样式
|
||||
boxStyle() {
|
||||
return {
|
||||
borderRadius: this.dataConfig.bgStyle.val * 2 + 'rpx',
|
||||
background: `linear-gradient(${this.dataConfig.bgColor.color[0].item}, ${this.dataConfig.bgColor.color[1].item})`,
|
||||
margin: this.dataConfig.mbConfig.val * 2 + 'rpx' + ' ' + this.dataConfig.lrConfig.val * 2 + 'rpx' +
|
||||
' ' + 0,
|
||||
padding: this.dataConfig.upConfig.val * 2 + 'rpx' + ' ' + '16rpx' + ' ' + this.dataConfig.downConfig
|
||||
.val *
|
||||
2 + 'rpx'
|
||||
}
|
||||
},
|
||||
//图片展示样式
|
||||
gridGap() {
|
||||
return {
|
||||
'grid-gap': this.dataConfig.contentConfig.val * 2 + 'rpx'
|
||||
}
|
||||
},
|
||||
//文章图片的圆角和高度
|
||||
imgStyle() {
|
||||
return {
|
||||
'border-radius': this.dataConfig.contentStyle.val * 2 + 'rpx',
|
||||
}
|
||||
},
|
||||
//价格颜色
|
||||
priceColor() {
|
||||
return {
|
||||
'color': this.dataConfig.themeStyleConfig.tabVal?this.dataConfig.priceColor.color[0].item:this.themeColor,
|
||||
}
|
||||
},
|
||||
//已售数量
|
||||
soldColor() {
|
||||
return {
|
||||
'color': this.dataConfig.soldColor.color[0].item,
|
||||
}
|
||||
},
|
||||
//商品名称
|
||||
titleShow() {
|
||||
if (this.dataConfig.typeConfig.activeValue.includes(0)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
//价格
|
||||
priceShow() {
|
||||
if (this.dataConfig.typeConfig.activeValue.includes(1)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
//销量
|
||||
soldShow() {
|
||||
if (this.dataConfig.typeConfig.activeValue.includes(2)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
//排序,0综合,1销量,2价格
|
||||
goodsSort() {
|
||||
return this.dataConfig.goodsSort.tabVal
|
||||
},
|
||||
//内容圆角
|
||||
contentStyle() {
|
||||
return {
|
||||
'border-radius': this.dataConfig.contentStyle.val ? 2*this.dataConfig.contentStyle.val + 'rpx' : '0'
|
||||
};
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.params.page = 1;
|
||||
this.goodScroll = false;
|
||||
this.tempArr = [];
|
||||
//类型为0时,直接加载选中的商品,不为0时根据条件加载商品列表
|
||||
if (this.type > 0) {
|
||||
this.productslist();
|
||||
} else {
|
||||
this.getProList();
|
||||
}
|
||||
},
|
||||
//uniapp小程序用deep重写组件样式不生效
|
||||
options: {
|
||||
styleIsolation: 'shared'
|
||||
},
|
||||
methods: {
|
||||
//根据商品id集合查询对应商品
|
||||
getProductByids(data) {
|
||||
uni.showLoading({
|
||||
title: '加载中...'
|
||||
});
|
||||
let ids = data.map((item) => item.id).join(',');
|
||||
productByidsApi(ids).then((res) => {
|
||||
this.tempArr = res.data;
|
||||
uni.hideLoading();
|
||||
})
|
||||
.catch(res => {
|
||||
uni.hideLoading();
|
||||
});
|
||||
},
|
||||
getProList() {
|
||||
this.getProductByids(this.dataConfig.goodsList.list);
|
||||
},
|
||||
productslist() {
|
||||
if (this.goodScroll) return;
|
||||
this.loading = true
|
||||
this.params.limit = this.numConfig;
|
||||
switch (this.type) {
|
||||
case 1:
|
||||
this.params.cid = this.selectId.join(',');
|
||||
break;
|
||||
}
|
||||
|
||||
if (this.goodsSort === 0) {
|
||||
this.params.priceOrder = '';
|
||||
this.params.salesOrder = '';
|
||||
} else if (this.goodsSort === 1) {
|
||||
this.params.priceOrder = '';
|
||||
this.params.salesOrder = 'desc';
|
||||
} else {
|
||||
this.params.priceOrder = 'desc';
|
||||
this.params.salesOrder = '';
|
||||
}
|
||||
|
||||
getProductslist(this.params).then(res => {
|
||||
this.$set(this.params, 'page', this.params.page + 1);
|
||||
this.goodScroll = this.params.page > res.data.totalPage;
|
||||
this.tempArr = this.tempArr.concat(res.data.list || []);
|
||||
this.loading = false
|
||||
});
|
||||
},
|
||||
goDetail(item) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/goods/goods_details/index?id=${item.id}`
|
||||
})
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.mores-txt {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.text-add {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.listBig {
|
||||
display: grid;
|
||||
grid-template-rows: auto;
|
||||
grid-template-columns: repeat(1, 1fr);
|
||||
|
||||
.itemBig {
|
||||
width: 100%;
|
||||
|
||||
.img-box {
|
||||
width: 100%;
|
||||
height: 710rpx;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.name {
|
||||
font-size: 28rpx;
|
||||
font-weight: bold;
|
||||
margin-top: 16rpx;
|
||||
// padding: 0 8px;
|
||||
}
|
||||
|
||||
.price {
|
||||
font-weight: bold;
|
||||
font-size: 12px;
|
||||
margin-top: 10rpx;
|
||||
// padding: 0 8px;
|
||||
|
||||
.num {
|
||||
font-size: 32rpx;
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
|
||||
.old-price {
|
||||
color: #aaa;
|
||||
font-weight: normal;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.listA {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(1, 1fr);
|
||||
grid-template-rows: auto;
|
||||
width: 100%;
|
||||
|
||||
.item {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
|
||||
.pictrue {
|
||||
width: 220rpx;
|
||||
height: 220rpx;
|
||||
position: relative;
|
||||
|
||||
image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.text-info {
|
||||
margin-left: 20rpx;
|
||||
flex: 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.listB {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
grid-template-rows: auto;
|
||||
width: 100%;
|
||||
|
||||
.item {
|
||||
.pictrue {
|
||||
width: 100%;
|
||||
height: 220rpx;
|
||||
position: relative;
|
||||
|
||||
image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.text-info {
|
||||
padding-top: 14rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.listC {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
grid-template-rows: auto;
|
||||
width: 100%;
|
||||
|
||||
/deep/.origin-img,
|
||||
/deep/.easy-loadimage {
|
||||
border-bottom-left-radius: 0 !important;
|
||||
border-bottom-right-radius: 0 !important;
|
||||
}
|
||||
|
||||
.item {
|
||||
background-color: #fff;
|
||||
|
||||
.pictrue {
|
||||
width: 100%;
|
||||
height: 345rpx;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
|
||||
image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.text-info {
|
||||
padding: 14rpx 0 14rpx 14rpx;
|
||||
|
||||
.title {
|
||||
width: 300rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.text-info {
|
||||
.title {
|
||||
width: 100%;
|
||||
height: 80rpx;
|
||||
line-height: 40rpx;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.old-price {
|
||||
font-weight: normal;
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.price {
|
||||
font-size: 36rpx;
|
||||
font-weight: 550;
|
||||
|
||||
text {
|
||||
padding-bottom: 4rpx;
|
||||
font-size: 26rpx;
|
||||
font-weight: normal;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.mer_badge {
|
||||
padding: 0 4rpx;
|
||||
background-color: theme;
|
||||
color: #fff;
|
||||
font-size: 20rpx;
|
||||
display: inline-block;
|
||||
border-radius: 4rpx;
|
||||
line-height: 28rpx;
|
||||
height: 28rpx;
|
||||
}
|
||||
</style>
|
||||
787
app/components/homeIndex/group.vue
Normal file
787
app/components/homeIndex/group.vue
Normal file
@@ -0,0 +1,787 @@
|
||||
<!-- 拼团 -->
|
||||
<template>
|
||||
<view class="groupBox" v-if="groupProductList.length" :style="[...boxPadding]">
|
||||
<view class="group" :style="[...boxStyle]">
|
||||
<view class="group-top acea-row row-middle row-between" :style="[bgImgStyle]">
|
||||
<view class="group-top-left acea-row">
|
||||
<image v-if="selectStyle == 0" :src="logoUrl" alt="" class="logo">
|
||||
<view v-else class="titleFont" :style="[...headerTitleConfig]">{{ titleConfig }}</view>
|
||||
<view v-if="groupInfo.totalPeople" class="interval" :style="[lineColor]"></view>
|
||||
<view class="avater-box" v-if="groupInfo.avatarList&&groupInfo.avatarList.length">
|
||||
<image class="avater1" :src="groupInfo.avatarList[0]"></image>
|
||||
<image class="avater2" v-if="groupInfo.avatarList.length>1" :src="groupInfo.avatarList[1]"></image>
|
||||
<image class="avater3" v-if="groupInfo.avatarList.length>2" :src="groupInfo.avatarList[2]"></image>
|
||||
</view>
|
||||
<view v-if="groupInfo.totalPeople" class="num ml-num" :class="groupInfo.avatarList.length==1?'num1':groupInfo.avatarList.length==2?'num2':groupInfo.avatarList.length==3?'num3':''" :style="[titleColor]">{{groupInfo.totalPeople}}人拼团成功</view>
|
||||
</view>
|
||||
<view class="group-top-right" :style="[headerBtnColor]" @click="toMore">
|
||||
更多
|
||||
<text class="iconfont icon-you" :style="[headerBtnColor]"></text>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 样式一 -->
|
||||
<view v-if="listStyle == 0" :style="[...boxBgStyle]" class="group-bottom">
|
||||
<view v-for="(item, index) in groupProductList" :key="index" :style="[contentConfig]" >
|
||||
<view class=" acea-row row-between" @click="toGroupDetail(item.id)">
|
||||
<view class="group-bottom-left">
|
||||
<view class="img acea-row row-center row-middle" >
|
||||
<easy-loadimage :image-src="item.image" width="250rpx"
|
||||
height="250rpx" :radius="dataConfig.contentStyle.val"></easy-loadimage>
|
||||
</view>
|
||||
</view>
|
||||
<view class="group-bottom-right acea-row row-column row-between">
|
||||
<view class="right-top">
|
||||
<view class="title line2" v-if="typeShow.includes(0)" :style="[nameColor]">
|
||||
{{item.title}}
|
||||
</view>
|
||||
<view class="pink acea-row" v-if="typeShow.includes(1)">
|
||||
<view class="people-box acea-row" :style="[groupTitleColor]">
|
||||
<view class="people" :style="[groupTitleColor]">{{item.people}}人团</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="right-bottom acea-row row-between">
|
||||
<view class="price">
|
||||
<view class="pinkNum" v-if="typeShow.includes(2)" :style="[priceColor]"><text
|
||||
class="pinkNum-title">拼团价</text><text class="pinkNum-icon">¥</text><text
|
||||
class="pinkNum-num semiBold">{{item.price}}</text>
|
||||
</view>
|
||||
<view class="num" v-if="typeShow.includes(3)" :style="[originalColor]"><text
|
||||
class="num-title">单买价</text><text class="num-icon">¥</text><text
|
||||
class="icon-num regular">{{item.otPrice}}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="btnBox" v-if="groupBtnShow">
|
||||
<view class="btn" :style="[...btnColor]">去拼团</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 样式二 -->
|
||||
<view class="group-bottom two acea-row row-between grid-list" v-if="listStyle == 1"
|
||||
:style="[...boxBgStyle]">
|
||||
<view v-for="(item, index) in groupProductList" :key="index" @click="toGroupDetail(item.id)">
|
||||
<view class="group-bottom-left">
|
||||
<view class="img acea-row row-center row-middle big-img">
|
||||
<easy-loadimage :image-src="item.image" width="324rpx"
|
||||
height="324rpx" :radius="dataConfig.contentStyle.val"></easy-loadimage>
|
||||
</view>
|
||||
</view>
|
||||
<view class="two-item">
|
||||
<view class="title acea-row">
|
||||
<view :style="[groupTitleColor]" class="numPink-box">
|
||||
<view class="numPink" v-if="typeShow.includes(1)" :style="[groupTitleFontColor]">{{item.people}}人团</view>
|
||||
</view>
|
||||
<text class="line1" v-if="typeShow.includes(0)" :style="[nameColor]">
|
||||
{{item.title}}
|
||||
</text>
|
||||
</view>
|
||||
<view class="two-item-bottom acea-row row-between">
|
||||
<view class="price">
|
||||
<view class="pinkNum" v-if="typeShow.includes(2)" :style="[priceColor]">
|
||||
<text class="num-icon">¥</text><text
|
||||
class="num semiBold" >{{item.price}}</text>
|
||||
</view>
|
||||
<view class="otNum regular" v-if="typeShow.includes(3)" :style="[originalColor]">
|
||||
¥{{item.otPrice}}
|
||||
</view>
|
||||
</view>
|
||||
<view class="btnBox" v-if="groupBtnShow">
|
||||
<view class="btn" :style="[...btnColor]">去拼团</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 样式三 -->
|
||||
<view class="group-bottom three acea-row grid-three" v-if="listStyle == 2" :style="[...boxBgStyle]">
|
||||
<view v-for="(item, index) in groupProductList" :key="index" class="three-box" @click="toGroupDetail(item.id)">
|
||||
<view class="group-bottom-left">
|
||||
<view class="img acea-row row-center row-middle three-img">
|
||||
<easy-loadimage width="100%" class="loadimage"
|
||||
height="100%" :image-src="item.image" :radius="dataConfig.contentStyle.val"></easy-loadimage>
|
||||
</view>
|
||||
</view>
|
||||
<view class="two-item">
|
||||
<view class="title acea-row">
|
||||
<view :style="[groupTitleColor]" class="numPink-box numPink-box-special">
|
||||
<view class="numPink" v-if="typeShow.includes(1)" :style="[groupTitleFontColor]">{{item.people}}人团</view>
|
||||
</view>
|
||||
<text class="line1" v-if="typeShow.includes(0)" :style="[nameColor]">
|
||||
{{item.title}}
|
||||
</text>
|
||||
</view>
|
||||
<view class="two-item-bottom">
|
||||
<view class="price">
|
||||
<view class="pinkNum" v-if="typeShow.includes(2)" :style="[priceColor]">
|
||||
<text class="num-icon">¥</text><text
|
||||
class="num semiBold">{{item.price}}</text>
|
||||
</view>
|
||||
<view class="otNum regular" v-if="typeShow.includes(3)" :style="[originalColor]">
|
||||
¥{{item.otPrice}}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 样式四 -->
|
||||
<view class="group-bottom four acea-row " v-if="listStyle == 3" :style="[...boxBgStyle]">
|
||||
<scroll-view scroll-x="true" class="scroll_view">
|
||||
<view v-for="(item, index) in groupProductList" :key="index" class="four-item" :style="[fourStyle]" @click="toGroupDetail(item.id)">
|
||||
<view class="group-bottom-left">
|
||||
<view class="img acea-row row-center row-middle four-img">
|
||||
<easy-loadimage :image-src="item.image" width="240rpx"
|
||||
height="240rpx" :radius="dataConfig.contentStyle.val"></easy-loadimage>
|
||||
</view>
|
||||
</view>
|
||||
<view class="two-item">
|
||||
<view class="title acea-row" v-if="typeShow.includes(0)" :style="[nameColor]">
|
||||
<view :style="[groupTitleColor]" class="numPink-box numPink-box-special">
|
||||
<view class="numPink" v-if="typeShow.includes(1)" :style="[groupTitleFontColor]">{{item.people}}人团</view>
|
||||
</view>
|
||||
<text class="line1">
|
||||
{{item.title}}
|
||||
</text>
|
||||
</view>
|
||||
<view class="two-item-bottom">
|
||||
<view class="price">
|
||||
<view class="pinkNum" v-if="typeShow.includes(2)" :style="[priceColor]">
|
||||
<text class="num-icon">¥</text><text
|
||||
class="num semiBold">{{item.price}}</text>
|
||||
</view>
|
||||
<view class="otNum regular" v-if="typeShow.includes(3)" :style="[originalColor]">
|
||||
¥{{item.otPrice}}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
<emptyPage :mTop="'0'" v-if="groupProductList.length==0" title="暂无拼团商品,去看看其他商品吧~~" :imgSrc="urlDomain+'crmebimage/presets/noActivity.png'"></emptyPage>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {getCombinationIndexApi} from '@/api/activity.js';
|
||||
import easyLoadimage from '@/components/base/easy-loadimage.vue';
|
||||
import emptyPage from '@/components/emptyPage.vue'
|
||||
let app = getApp();
|
||||
export default {
|
||||
name: 'homeGroup',
|
||||
components: {
|
||||
easyLoadimage,
|
||||
emptyPage
|
||||
},
|
||||
props: {
|
||||
dataConfig: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
urlDomain: this.$Cache.get("imgHost"),
|
||||
listStyle: 0,
|
||||
logoUrl: null,
|
||||
typeShow: [0, 1, 2, 3],
|
||||
groupBtnShow: true,
|
||||
selectStyle: '',
|
||||
titleConfig: '',
|
||||
selectBgImg: '',
|
||||
bgImgUrl: '',
|
||||
headerTitleStyle: 0,
|
||||
old: {
|
||||
scrollTop: 0
|
||||
},
|
||||
groupInfo: {},
|
||||
groupProductList: [],
|
||||
themeColor:this.$options.filters.filterTheme(app.globalData.theme)
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
//容器样式
|
||||
//最外层盒子的样式
|
||||
boxStyle() {
|
||||
return [{
|
||||
'border-radius': this.dataConfig.bgStyle.val ? 2 * this.dataConfig.bgStyle.val + 'rpx' : '0'
|
||||
},
|
||||
{
|
||||
margin: 0 + ' ' + 2 * this.dataConfig.lrConfig.val + 'rpx' + ' ' + 0
|
||||
},
|
||||
{
|
||||
background: `linear-gradient(to right,${this.dataConfig.bgColor.color[0].item}, ${this.dataConfig.bgColor.color[1].item})`,
|
||||
},
|
||||
];
|
||||
},
|
||||
//边距
|
||||
boxPadding() {
|
||||
return [{
|
||||
padding: 2 * this.dataConfig.upConfig.val + 'rpx' + ' ' + '0rpx' + ' ' + 2 * this.dataConfig
|
||||
.downConfig.val + 'rpx',
|
||||
},
|
||||
{
|
||||
margin: 2 * this.dataConfig.mbConfig.val + 'rpx' + ' ' + 0 + ' ' + 0
|
||||
},
|
||||
]
|
||||
},
|
||||
//背景颜色
|
||||
boxBgStyle() {
|
||||
return [{
|
||||
gap: this.listStyle != 3 ? `${2*this.dataConfig.contentConfig.val}rpx` : ''
|
||||
},
|
||||
{
|
||||
background: `linear-gradient(to right,${this.dataConfig.contentBgColor.color[0].item}, ${this.dataConfig.contentBgColor.color[1].item})`,
|
||||
},
|
||||
];
|
||||
},
|
||||
fourStyle() {
|
||||
return {
|
||||
'margin-right': this.listStyle == 3 ? `${2*this.dataConfig.contentConfig.val}rpx` : ''
|
||||
}
|
||||
},
|
||||
//标题颜色
|
||||
titleColor() {
|
||||
return {
|
||||
color: this.dataConfig.titleColor.color[0].item,
|
||||
};
|
||||
},
|
||||
//头部按钮颜色
|
||||
headerBtnColor() {
|
||||
return {
|
||||
color: this.dataConfig.headerBtnColor.color[0].item,
|
||||
};
|
||||
},
|
||||
//商品名称颜色
|
||||
nameColor() {
|
||||
return {
|
||||
color: this.dataConfig.nameColor.color[0].item,
|
||||
};
|
||||
},
|
||||
//商品原价颜色
|
||||
originalColor() {
|
||||
return {
|
||||
color: this.dataConfig.originalColor.color[0].item,
|
||||
};
|
||||
},
|
||||
//拼团价格颜色
|
||||
priceColor() {
|
||||
return {
|
||||
color: this.dataConfig.themeStyleConfig.tabVal?this.dataConfig.priceColor.color[0].item:this.themeColor,
|
||||
};
|
||||
},
|
||||
//标签颜色
|
||||
groupTitleColor() {
|
||||
return {
|
||||
background: this.dataConfig.themeStyleConfig.tabVal?this.dataConfig.groupTitleColor.color[0].item:this.themeColor,
|
||||
};
|
||||
},
|
||||
//已拼颜色
|
||||
groupTitleFontColor() {
|
||||
return {
|
||||
color: this.dataConfig.themeStyleConfig.tabVal?this.dataConfig.groupTitleColor.color[0].item:this.themeColor,
|
||||
}
|
||||
},
|
||||
//分割线颜色
|
||||
lineColor() {
|
||||
return {
|
||||
border: `1rpx solid ${this.dataConfig.lineColor.color[0].item}`,
|
||||
};
|
||||
},
|
||||
//按钮颜色
|
||||
btnColor() {
|
||||
return [{
|
||||
background: `linear-gradient(to right,${this.dataConfig.themeStyleConfig.tabVal?this.dataConfig.btnColor.color[0].item:'#FF7931'}, ${this.dataConfig.themeStyleConfig.tabVal?this.dataConfig.btnColor.color[1].item:this.themeColor})`,
|
||||
},
|
||||
{
|
||||
color: this.dataConfig.btnFontColor.color[0].item,
|
||||
}
|
||||
];
|
||||
},
|
||||
//样式一内容边距
|
||||
contentConfig() {
|
||||
return {
|
||||
'paddingBottom': 2 * this.dataConfig.contentConfig.val + 'rpx',
|
||||
};
|
||||
},
|
||||
//背景图片
|
||||
bgImgStyle() {
|
||||
return {
|
||||
'background': this.selectBgImg == 0 ? `url(${this.bgImgUrl})` :
|
||||
`linear-gradient(to right,${this.dataConfig.bgColor.color[0].item}, ${this.dataConfig.bgColor.color[1].item})`,
|
||||
};
|
||||
},
|
||||
//标题文字格式
|
||||
headerTitleConfig() {
|
||||
return [{
|
||||
'font-weight': this.headerTitleStyle == 0 ? 600 : ''
|
||||
},
|
||||
{
|
||||
'font-style': this.headerTitleStyle == 2 ? 'italic' : 'normal'
|
||||
},
|
||||
{
|
||||
color: this.dataConfig.headerTitleColor.color[0].item,
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.setConfig()
|
||||
this.getInfo()
|
||||
},
|
||||
methods: {
|
||||
//去拼团
|
||||
toGroupDetail(id){
|
||||
uni.navigateTo({
|
||||
url:`/pages/activity/goods_combination_details/index?id=${id}`
|
||||
})
|
||||
},
|
||||
getInfo() {
|
||||
let that = this;
|
||||
getCombinationIndexApi().then(function(res) {
|
||||
that.groupProductList = res.data.productList;
|
||||
that.groupInfo = {totalPeople:res.data.totalPeople,avatarList:res.data.avatarList}
|
||||
}).catch((res) => {
|
||||
return that.$util.Tips({
|
||||
title: res
|
||||
});
|
||||
})
|
||||
},
|
||||
scroll: function(e) {
|
||||
this.old.scrollTop = e.detail.scrollTop
|
||||
},
|
||||
// 更多
|
||||
toMore() {
|
||||
uni.navigateTo({
|
||||
url: '/pages/activity/goods_combination/index'
|
||||
})
|
||||
},
|
||||
setConfig() {
|
||||
this.listStyle = this.dataConfig.tabConfig.tabVal;
|
||||
this.logoUrl = this.dataConfig.logoConfig.url;
|
||||
this.typeShow = this.dataConfig.typeConfig.activeValue;
|
||||
this.groupBtnShow = this.dataConfig.groupBtnConfig.tabVal == 0 ? true : false;
|
||||
this.selectStyle = this.dataConfig.selectStyle.tabVal;
|
||||
this.titleConfig = this.dataConfig.titleConfig.val;
|
||||
this.selectBgImg = this.dataConfig.selectBgImg.tabVal;
|
||||
this.bgImgUrl = this.dataConfig.bgImg.url;
|
||||
this.headerTitleStyle = this.dataConfig.headerTitleStyle.tabVal;
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.groupBox {
|
||||
overflow: hidden;
|
||||
|
||||
.group {
|
||||
overflow: hidden;
|
||||
|
||||
.group-top {
|
||||
width: 100%;
|
||||
height: 100rpx;
|
||||
padding: 0 24rpx;
|
||||
background-size: cover !important;
|
||||
.group-top-left {
|
||||
align-items: center;
|
||||
.ml10{
|
||||
margin-top: 4rpx;
|
||||
}
|
||||
.logo {
|
||||
width: 154rpx;
|
||||
height: 32rpx;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.interval {
|
||||
width: 0rpx;
|
||||
height: 28rpx;
|
||||
margin-left: 20rpx;
|
||||
margin-top: 4rpx;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.pinkHead {
|
||||
width: 108rpx;
|
||||
height: 36rpx;
|
||||
}
|
||||
|
||||
.num {
|
||||
height: 32rpx;
|
||||
line-height: 32rpx;
|
||||
font-size: 26rpx;
|
||||
margin-left: 16rpx;
|
||||
color: #FFFFFF;
|
||||
margin-top: 6rpx;
|
||||
}
|
||||
.num1{
|
||||
margin-left: 12rpx;
|
||||
}
|
||||
.num2{
|
||||
margin-left: 41rpx;
|
||||
}
|
||||
.num3{
|
||||
margin-left: 76rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.group-top-right {
|
||||
height: 32rpx;
|
||||
line-height: 32rpx;
|
||||
font-size: 24rpx;
|
||||
|
||||
.icon-xiangyou {
|
||||
font-size: 24rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.group-bottom {
|
||||
width: 100%;
|
||||
padding: 20rpx;
|
||||
|
||||
.img {
|
||||
width: 240rpx;
|
||||
// height: 240rpx;
|
||||
// background: #F3F9FF;
|
||||
|
||||
}
|
||||
|
||||
.big-img.img {
|
||||
width: 100%;
|
||||
height: 324rpx;
|
||||
}
|
||||
|
||||
.three-img.img {
|
||||
width: 100%;
|
||||
height: 210rpx;
|
||||
}
|
||||
.loadimage{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.four-img {
|
||||
width: 240rpx;
|
||||
height: 240rpx;
|
||||
}
|
||||
|
||||
.group-bottom-right {
|
||||
flex: 1;
|
||||
margin-left: 20rpx;
|
||||
|
||||
.right-top {
|
||||
.title {
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.people-box {
|
||||
border-radius: 8rpx;
|
||||
}
|
||||
|
||||
.pink {
|
||||
margin-top: 16rpx;
|
||||
font-size: 22rpx;
|
||||
border-radius: 8rpx;
|
||||
|
||||
.people {
|
||||
color: #fff;
|
||||
padding: 4rpx 16rpx;
|
||||
border-radius: 8rpx;
|
||||
}
|
||||
|
||||
.groupNum {
|
||||
background-color: rgba(255, 255, 255, 0.9);
|
||||
padding: 4rpx 12rpx;
|
||||
border-radius: 0 6rpx 6rpx 0;
|
||||
margin-left: 2rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.right-bottom {
|
||||
|
||||
.price {
|
||||
|
||||
.pinkNum {
|
||||
|
||||
.pinkNum-num {
|
||||
font-size: 36rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.num {
|
||||
color: #999999;
|
||||
}
|
||||
}
|
||||
|
||||
.btnBox {
|
||||
// margin-top: 16rpx;
|
||||
font-size: 22rpx;
|
||||
display: flex;
|
||||
align-items: end;
|
||||
.btn {
|
||||
padding: 12rpx 20rpx;
|
||||
border-radius: 50rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.group-bottom.two {
|
||||
.two-item {
|
||||
width: 100%;
|
||||
|
||||
.title {
|
||||
margin-top: 20rpx;
|
||||
|
||||
.numPink {
|
||||
color: #ffffff;
|
||||
padding: 6rpx 12rpx;
|
||||
border-radius: 4rpx;
|
||||
font-size: 22rpx;
|
||||
}
|
||||
|
||||
.line1 {
|
||||
width: 210rpx;
|
||||
margin-left: 10rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.two-item-bottom {
|
||||
margin-top: 10rpx;
|
||||
|
||||
.pinkNum {
|
||||
|
||||
.num {
|
||||
font-size: 36rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.otNum {
|
||||
font-size: 26rpx;
|
||||
color: #999999;
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
.btnBox {
|
||||
margin-top: 16rpx;
|
||||
font-size: 22rpx;
|
||||
|
||||
.btn {
|
||||
padding: 12rpx 24rpx;
|
||||
border-radius: 50rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.group-bottom.three {
|
||||
.three-box{
|
||||
position: relative;
|
||||
}
|
||||
.numPink {
|
||||
color: #ffffff;
|
||||
padding: 4rpx 12rpx;
|
||||
border-radius: 16rpx;
|
||||
font-size: 22rpx;
|
||||
// z-index: 9;
|
||||
}
|
||||
|
||||
.two-item {
|
||||
width: 100%;
|
||||
|
||||
.title {
|
||||
margin-top: 18rpx;
|
||||
// width: 100%;
|
||||
|
||||
.numPink {
|
||||
color: #ffffff;
|
||||
padding: 4rpx 12rpx;
|
||||
border-radius: 8rpx;
|
||||
font-size: 22rpx;
|
||||
}
|
||||
|
||||
.line1 {
|
||||
width: 180rpx;
|
||||
margin-left: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.two-item-bottom {
|
||||
margin-top: 10rpx;
|
||||
|
||||
.pinkNum {
|
||||
|
||||
.num {
|
||||
font-size: 36rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.otNum {
|
||||
font-size: 26rpx;
|
||||
color: #999999;
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
.btnBox {
|
||||
margin-top: 16rpx;
|
||||
font-size: 22rpx;
|
||||
|
||||
.btn {
|
||||
padding: 12rpx 24rpx;
|
||||
border-radius: 50rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.group-bottom.four {
|
||||
overflow: hidden;
|
||||
flex-wrap: nowrap;
|
||||
position: relative;
|
||||
.four-item{
|
||||
position: relative;
|
||||
}
|
||||
.numPink {
|
||||
color: #ffffff;
|
||||
padding: 6rpx 12rpx;
|
||||
border-radius: 32rpx;
|
||||
font-size: 22rpx;
|
||||
z-index: 9;
|
||||
}
|
||||
|
||||
|
||||
.two-item {
|
||||
width: 210rpx;
|
||||
|
||||
.title {
|
||||
margin-top: 18rpx;
|
||||
|
||||
.numPink {
|
||||
color: #ffffff;
|
||||
padding: 6rpx 12rpx;
|
||||
border-radius: 32rpx;
|
||||
font-size: 22rpx;
|
||||
}
|
||||
|
||||
.line1 {
|
||||
width: 210rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.two-item-bottom {
|
||||
margin-top: 10rpx;
|
||||
|
||||
.pinkNum {
|
||||
|
||||
.num {
|
||||
font-size: 36rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.otNum {
|
||||
font-size: 26rpx;
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
.btnBox {
|
||||
margin-top: 16rpx;
|
||||
font-size: 22rpx;
|
||||
|
||||
.btn {
|
||||
padding: 12rpx 24rpx;
|
||||
border-radius: 50rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.price {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.grid-list {
|
||||
display: grid !important;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
grid-template-rows: auto;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.grid-three {
|
||||
width: 100%;
|
||||
display: grid !important;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
grid-template-rows: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.titleFont {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.scroll_view {
|
||||
white-space: nowrap;
|
||||
|
||||
.four-item {
|
||||
display: inline-block;
|
||||
color: #999999;
|
||||
}
|
||||
}
|
||||
.num-icon {
|
||||
font-weight: 500 !important;
|
||||
}
|
||||
.numPink {
|
||||
background-color: rgba(255, 255, 255, 0.9);
|
||||
}
|
||||
.numPink-box {
|
||||
border-radius: 8rpx;
|
||||
}
|
||||
.numPink-box-special {
|
||||
position: absolute;
|
||||
left: 10rpx;
|
||||
top: 10rpx;
|
||||
border-radius: 32rpx;
|
||||
}
|
||||
.avater-box{
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: end;
|
||||
margin-top: 4rpx;
|
||||
image{
|
||||
width: 36rpx;
|
||||
height: 36rpx;
|
||||
border-radius: 18rpx;
|
||||
}
|
||||
.avater1{
|
||||
margin-left: 20rpx;
|
||||
}
|
||||
.avater2{
|
||||
position: absolute;
|
||||
margin-left: 48rpx;
|
||||
}
|
||||
.avater3{
|
||||
position: absolute;
|
||||
left: 78rpx;
|
||||
}
|
||||
}
|
||||
.regular{
|
||||
line-height: 34rpx !important;
|
||||
font-weight: 400 !important;
|
||||
}
|
||||
.icon-you{
|
||||
font-size: 24rpx;
|
||||
}
|
||||
</style>
|
||||
62
app/components/homeIndex/guide.vue
Normal file
62
app/components/homeIndex/guide.vue
Normal file
@@ -0,0 +1,62 @@
|
||||
<template>
|
||||
<!-- 辅助线 -->
|
||||
<view>
|
||||
<view class="lines" :style="[boxStyle]">
|
||||
<view class="item" :style="[lineStyle]"></view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
export default {
|
||||
name: 'guide',
|
||||
props: {
|
||||
dataConfig: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
//最外层盒子的样式
|
||||
boxStyle() {
|
||||
return {
|
||||
background: `linear-gradient(${this.dataConfig.bgColor.color[0].item}, ${this.dataConfig.bgColor.color[1].item})`,
|
||||
margin: this.dataConfig.mbConfig.val * 2 + 'rpx' + ' ' + this.dataConfig.lrConfig.val * 2 + 'rpx' +
|
||||
' ' + 0,
|
||||
}
|
||||
},
|
||||
//线条样式
|
||||
lineStyle() {
|
||||
return {
|
||||
borderBottomWidth: 2*this.dataConfig.heightConfig.val + 'rpx',
|
||||
borderBottomColor: this.dataConfig.lineColor.color[0].item,
|
||||
borderBottomStyle: this.dataConfig.lineStyle.list[this.dataConfig.lineStyle.tabVal].style
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.lines {
|
||||
padding: 0 20rpx;
|
||||
|
||||
.item {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
border-bottom-color: #666;
|
||||
border-bottom-width: 1px;
|
||||
border-bottom-style: dotted;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
341
app/components/homeIndex/headerSearch.vue
Normal file
341
app/components/homeIndex/headerSearch.vue
Normal file
@@ -0,0 +1,341 @@
|
||||
<template>
|
||||
<!-- 搜索框 -->
|
||||
<view>
|
||||
<view class="mp-header">
|
||||
<!-- #ifdef MP || APP-PLUS -->
|
||||
<view class="sys-head tui-skeleton" :style="{ height: `${isSmallPage?0:statusBarHeight}px` }"></view>
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef APP -->
|
||||
<view class="serch-box tui-skeleton" :style="[boxStyle]" style="height: 43px;">
|
||||
<!-- #endif -->
|
||||
<!-- #ifndef APP -->
|
||||
<view class="serch-box tui-skeleton" :style="[boxStyle]">
|
||||
<!-- #endif -->
|
||||
<view class="serch-wrapper flex">
|
||||
<view v-if="logoConfig" class="logo skeleton-rect">
|
||||
<image :src="logoUrl" mode=""></image>
|
||||
</view>
|
||||
<navigator :style="[contentStyle]" v-if="hotWords.length > 0"
|
||||
:url="'/pages/goods/goods_search/index?searchVal='+searchVal"
|
||||
:class="logoConfig&&!isSmallPage ? 'input' : logoConfig&&isSmallPage?'uninput':!logoConfig&&!isSmallPage?'uninput':'maxInput'" hover-class="none" class=" input skeleton-rect">
|
||||
<view class='swiperTxt'>
|
||||
<swiper :indicator-dots="indicatorDots" :autoplay="autoplay" :interval="interval"
|
||||
:duration="duration" vertical="true" circular="true" @change="textChange">
|
||||
<block v-for="(item,index) in hotWords" :key='index'>
|
||||
<swiper-item catchtouchmove='catchTouchMove'>
|
||||
<view class='acea-row row-between-wrapper'>
|
||||
<view class='text'>
|
||||
<view class='newsTitle line1'><text class="iconfont icon-sousuo"></text><text>{{item.val}}</text></view>
|
||||
</view>
|
||||
</view>
|
||||
</swiper-item>
|
||||
</block>
|
||||
</swiper>
|
||||
</view>
|
||||
</navigator>
|
||||
<navigator :style="[contentStyle]" hover-class="none" v-else url="/pages/goods/goods_search/index"
|
||||
:class="logoConfig&&!isSmallPage ? 'input' : logoConfig&&isSmallPage?'uninput':!logoConfig&&!isSmallPage?'uninput':'maxInput'" class="skeleton-rect">
|
||||
<text class="line1">{{placeWords}}</text>
|
||||
<text class="iconfont icon-xiazai5"></text>
|
||||
</navigator>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
<view :style="'height:'+marTop+'px;'"></view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
let app = getApp();
|
||||
export default {
|
||||
name: 'headerSerch',
|
||||
props: {
|
||||
dataConfig: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
},
|
||||
//是否为微页面
|
||||
isSmallPage: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
//是否开始滚动
|
||||
isScrolled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
statusBarHeight: app.globalData.statusBarHeight,
|
||||
indicatorDots: false,
|
||||
autoplay: true,
|
||||
duration: 500,
|
||||
marTop: 0,
|
||||
searchH: 0,
|
||||
searchVal: '',
|
||||
searchTop:0,
|
||||
searchRight:0,
|
||||
searchHeight:0,
|
||||
statusWidth:0,
|
||||
searchBoxHeight:0
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
//轮播切换时间
|
||||
interval(){
|
||||
return this.dataConfig.titleConfig.val * 1000
|
||||
},
|
||||
//判断logo图是否展示
|
||||
logoConfig() {
|
||||
return this.dataConfig.logoConfig.url && this.dataConfig.searConfig.tabVal === 1
|
||||
},
|
||||
//logo图
|
||||
logoUrl() {
|
||||
if(this.isScrolled&&this.dataConfig.logoFixConfig.url){
|
||||
return this.dataConfig.logoFixConfig.url
|
||||
}else{
|
||||
return this.dataConfig.logoConfig.url
|
||||
}
|
||||
},
|
||||
//最外层盒子的样式
|
||||
boxStyle() {
|
||||
return {
|
||||
borderRadius: this.dataConfig.bgStyle.val * 2 + 'rpx',
|
||||
background: `linear-gradient(${this.dataConfig.bgColor.color[0].item}, ${this.dataConfig.bgColor.color[1].item})`,
|
||||
margin: 0 + ' ' + this.dataConfig.lrConfig.val * 2 + 'rpx' +
|
||||
' ' + 0,
|
||||
// #ifdef MP
|
||||
height:this.searchBoxHeight + 'px',
|
||||
// #endif
|
||||
}
|
||||
},
|
||||
//搜索热词
|
||||
hotWords() {
|
||||
return this.dataConfig.hotWords.list
|
||||
},
|
||||
//内容圆角
|
||||
contentStyle() {
|
||||
return {
|
||||
borderRadius: this.dataConfig.contentStyle.val ? this.dataConfig.contentStyle.val + 'px' : '0',
|
||||
background: this.dataConfig.borderColor.color[0].item,
|
||||
color: this.dataConfig.textColor.color[0].item,
|
||||
textAlign: this.dataConfig.textPosition.list[this.dataConfig.textPosition.tabVal].style,
|
||||
// #ifdef MP
|
||||
height:this.searchHeight + 'px',
|
||||
flex:!this.isSmallPage?1:'',
|
||||
marginRight:!this.isSmallPage?(this.statusWidth + this.searchRight+'px'):'',
|
||||
// #endif
|
||||
}
|
||||
},
|
||||
//搜索提示语
|
||||
placeWords(){
|
||||
return this.dataConfig.placeWords.val;
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
// 使用nextTick,确保页面更新结束后,再请求高度
|
||||
// #ifdef MP || APP-PLUS
|
||||
this.$nextTick(() => {
|
||||
setTimeout(() => {
|
||||
// 获取小程序头部高度
|
||||
let info = uni.createSelectorQuery().in(this).select(".serch-box");
|
||||
info.boundingClientRect((data)=> {
|
||||
this.marTop = this.isSmallPage ? data.height :data.height + this.statusBarHeight
|
||||
}).exec()
|
||||
}, 100)
|
||||
})
|
||||
// #endif
|
||||
|
||||
// #ifdef MP
|
||||
const res = uni.getMenuButtonBoundingClientRect()
|
||||
const statusHeight = res.top //胶囊距离顶部
|
||||
const statusRight = res.right //胶囊右边界坐标
|
||||
const jnHeight = res.height //胶囊高度
|
||||
this.statusWidth= res.width
|
||||
this.searchTop=statusHeight-this.statusBarHeight
|
||||
this.searchHeight=jnHeight
|
||||
this.searchBoxHeight = this.searchTop*2 + jnHeight
|
||||
//搜索框宽度计算
|
||||
uni.getSystemInfo({
|
||||
success:res=>{
|
||||
this.searchRight=res.windowWidth-statusRight-this.dataConfig.lrConfig.val
|
||||
}
|
||||
})
|
||||
// #endif
|
||||
|
||||
// #ifdef H5
|
||||
this.marTop = 43
|
||||
// #endif
|
||||
},
|
||||
methods: {
|
||||
textChange(e) {
|
||||
let {
|
||||
current,
|
||||
source
|
||||
} = e.detail;
|
||||
if (source === 'autoplay' || source === 'touch') {
|
||||
this.searchVal = this.hotWords[e.detail.current]['val'];
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.ml40 {
|
||||
margin-left: 40rpx;
|
||||
}
|
||||
.sys-head{
|
||||
background: #f5f5f5;
|
||||
}
|
||||
.header {
|
||||
width: 100%;
|
||||
background: #ffffff;
|
||||
|
||||
.btn {
|
||||
position: relative;
|
||||
|
||||
.iconfont {
|
||||
font-size: 45rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.iconnum {
|
||||
min-width: 6px;
|
||||
color: #fff;
|
||||
border-radius: 15rpx;
|
||||
position: absolute;
|
||||
right: -10rpx;
|
||||
top: -10rpx;
|
||||
font-size: 10px;
|
||||
padding: 0 4px;
|
||||
}
|
||||
|
||||
.serch-wrapper {
|
||||
align-items: center;
|
||||
padding: 20rpx 24rpx 20rpx 24rpx;
|
||||
|
||||
.logo {
|
||||
width: 152rpx;
|
||||
height: 60rpx;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.swiperTxt {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
line-height: 58rpx;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.swiperTxt .text {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.swiperTxt .text .label {
|
||||
font-size: 20rpx;
|
||||
color: #ff4c48;
|
||||
width: 64rpx;
|
||||
height: 30rpx;
|
||||
border-radius: 40rpx;
|
||||
text-align: center;
|
||||
line-height: 28rpx;
|
||||
border: 2rpx solid #ff4947;
|
||||
}
|
||||
|
||||
.swiperTxt .text .newsTitle {
|
||||
// width: 300rpx;
|
||||
font-size: 24rpx;
|
||||
// text-align: center;
|
||||
/* #ifdef MP */
|
||||
// width: 260rpx !important;
|
||||
/* #endif */
|
||||
}
|
||||
|
||||
.swiperTxt swiper {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.mp-header {
|
||||
z-index: 90;
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
|
||||
.logo {
|
||||
line-height: 0;
|
||||
}
|
||||
|
||||
.serch-wrapper {
|
||||
height: 100%;
|
||||
align-items: center;
|
||||
padding: 20rpx 30rpx;
|
||||
|
||||
image {
|
||||
width: 152rpx;
|
||||
height: 60rpx;
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
|
||||
.input,
|
||||
.uninput {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
/* #ifdef MP*/
|
||||
width: 50%;
|
||||
/* #endif */
|
||||
/* #ifdef H5 || APP*/
|
||||
width: 100%;
|
||||
flex: 1;
|
||||
/* #endif */
|
||||
height: 58rpx;
|
||||
line-height: 58rpx;
|
||||
padding: 0 20rpx 0 54rpx;
|
||||
background: rgba(0, 0, 0, 0.22);
|
||||
border: 1px solid #E4E4E4;
|
||||
border-radius: 29rpx;
|
||||
color: #fff;
|
||||
font-size: 28rpx;
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
|
||||
.iconfont {
|
||||
// position: absolute;
|
||||
left: 14rpx;
|
||||
font-size: 26rpx;
|
||||
//top: 10rpx;
|
||||
}
|
||||
.line1{
|
||||
display: inline-block;
|
||||
width: 400rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.uninput {
|
||||
/* #ifdef MP */
|
||||
width: 75% ;
|
||||
/* #endif */
|
||||
/* #ifndef MP */
|
||||
width: 100%;
|
||||
/* #endif */
|
||||
}
|
||||
}
|
||||
}
|
||||
.maxInput{
|
||||
width: 100% !important;
|
||||
}
|
||||
</style>
|
||||
937
app/components/homeIndex/homeComb.vue
Normal file
937
app/components/homeIndex/homeComb.vue
Normal file
@@ -0,0 +1,937 @@
|
||||
<template>
|
||||
<!-- 组合组件 -->
|
||||
<view class="page_count tui-skeleton" :data-theme="theme">
|
||||
<!--logo-->
|
||||
<view class="bg-img" :style="{'background-image': bgColor}">
|
||||
<img :src="bgColor" alt="">
|
||||
<view class="maskBg" :style="[maskBgStyle]"></view>
|
||||
</view>
|
||||
<!--头部-->
|
||||
<view :class="{scrolled:isScrolled, 'my-main': true}" :style="{ height: myMainHeight+'px' }">
|
||||
<!--搜索-->
|
||||
<!-- #ifdef H5 -->
|
||||
<view class="header">
|
||||
<view class="serch-wrapper acea-row">
|
||||
<view v-if="logoConfig" class="logo skeleton-rect">
|
||||
<image :src="logoUrl" mode="scaleToFill"></image>
|
||||
</view>
|
||||
<navigator v-if="hotWords.length > 0" :url="'/pages/goods/goods_search/index?searchVal='+searchVal"
|
||||
:style="[searchBoxStyle]" :class="logoConfig ? 'input' : 'uninput'" hover-class="none"
|
||||
class="input">
|
||||
<view class='swiperTxt'>
|
||||
<swiper :indicator-dots="indicatorDots" :autoplay="true" :interval="interval"
|
||||
:duration="duration" vertical="true" circular="true" @change="textChange">
|
||||
<block v-for="(item,index) in hotWords" :key='index'>
|
||||
<swiper-item catchtouchmove='catchTouchMove'>
|
||||
<view class=''>
|
||||
<view class='text'>
|
||||
<view class='newsTitle line1'><text
|
||||
class="iconfont icon-sousuo"></text><text>{{item.val}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</swiper-item>
|
||||
</block>
|
||||
</swiper>
|
||||
</view>
|
||||
</navigator>
|
||||
<navigator v-else :style="[searchBoxStyle]" :class="logoConfig ? 'input' : 'uninput'"
|
||||
url="/pages/goods/goods_search/index" class="input" hover-class="none">
|
||||
<text class="iconfont icon-sousuo8"></text>
|
||||
<text class="line1">{{placeWords}}</text>
|
||||
</navigator>
|
||||
</view>
|
||||
</view>
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef MP || APP-PLUS-->
|
||||
<view class="mp-header">
|
||||
<view class="sys-head" :style="{ height: `${isSmallPage?0:statusBarHeight}px`}"></view>
|
||||
<!-- #ifdef MP -->
|
||||
<view class="serch-box" :style="{ 'margin-top': `${searchTop}px`,'height': `${searchHeight}px`}">
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef APP-PLUS -->
|
||||
<view class="serch-box" style="margin-top: 9px;margin-right: 2px;">
|
||||
<!-- #endif -->
|
||||
<view class="serch-wrapper acea-row">
|
||||
<view v-if="logoConfig" class="logo tui-skeleton-rect">
|
||||
<image :src="logoUrl" mode="scaleToFill"></image>
|
||||
</view>
|
||||
<navigator v-if="hotWords.length > 0"
|
||||
:url="'/pages/goods/goods_search/index?searchVal='+searchVal" :style="[searchBoxStyle]"
|
||||
hover-class="none" class="input" :class="logoConfig&&!isSmallPage ? 'input' : 'uninput'">
|
||||
<view class='swiperTxt'>
|
||||
<swiper :indicator-dots="indicatorDots" :autoplay="true" :interval="interval"
|
||||
:duration="duration" vertical="true" circular="true" @change="textChange">
|
||||
<block v-for="(item,index) in hotWords" :key='index'>
|
||||
<swiper-item catchtouchmove='catchTouchMove'>
|
||||
<view class='acea-row row-between-wrapper text-box'>
|
||||
<view class='text'>
|
||||
<view class='newsTitle line1'><text
|
||||
class="iconfont icon-sousuo"></text><text>{{item.val}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</swiper-item>
|
||||
</block>
|
||||
</swiper>
|
||||
</view>
|
||||
</navigator>
|
||||
<navigator v-else :style="[searchBoxStyle]" :class="logoConfig ? 'input' : 'uninput'"
|
||||
url="/pages/goods/goods_search/index" class="input" hover-class="none">
|
||||
<text class="iconfont icon-sousuo8"></text>
|
||||
<text class="line1">{{placeWords}}</text>
|
||||
</navigator>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- #endif -->
|
||||
<view v-if="tabShowConfig" class="navTabBox tabNav tui-skeletonpictrue acea-row" :style="'top:'+isTop">
|
||||
<view class="longTab">
|
||||
<scroll-view scroll-x="true" style="white-space: nowrap; display: flex;" scroll-with-animation
|
||||
:scroll-left="tabLeft" show-scrollbar="true">
|
||||
<view class="longItem" :data-index="index" v-for="(item,index) in tabList" :key="index"
|
||||
:id="'id'+index" @click="longClick(index,item)"
|
||||
:class="tabClick === index? 'navChecked':''">
|
||||
<view class="acea-row row-middle">
|
||||
<view class="name tui-skeleton-rect">{{item.title}}</view>
|
||||
<view class="underlineBox" v-if="index===tabClick">
|
||||
<!-- <view class="underline"></view> -->
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</scroll-view>
|
||||
</view>
|
||||
<view class="category">
|
||||
<text v-if="isShow" class="iconfont icon-xiangshang" @click="isShow=false"></text>
|
||||
<text v-if="!isShow" class="iconfont icon-xiangxia" @click="isShow=true"></text>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="isShow" class="navChangeBox" catchtouchmove="true" :style="'top:'+isTop">
|
||||
<view class="navChange">
|
||||
<block v-for="(item,index) in tabList" :key="index">
|
||||
<view class="titleBox">
|
||||
<text :class="tabClick === index ? 'checkColor' : 'textColor' " class="title line1"
|
||||
:id="'id'+index" @click="longClick(index,item)">{{item.title}}</text>
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
<view class="mask" @touchmove.prevent :hidden="!isShow" @click="isShow=false"></view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- banner -->
|
||||
<view class="swiperBg" :style="{ marginTop: swiperTop+'px'}">
|
||||
<view class="swiper page_swiper" v-if="navIndex === 0">
|
||||
<swiper :autoplay="true" :circular="circular" :interval="intervalBanner" :duration="duration"
|
||||
:previous-margin="swiperType==0?'30rpx':''" :next-margin="swiperType==0?'30rpx':''"
|
||||
:current="swiperCur" @change="swiperChange">
|
||||
<block v-for="(item,index) in banner" :key="index">
|
||||
<swiper-item :style="[contentStyleBanner]" :class="{ active: index == swiperCur }"
|
||||
class="scalex">
|
||||
<view @click="menusTap(item.info[1].value)"
|
||||
class='slide-navigator acea-row row-between-wrapper tui-skeleton-rect'
|
||||
:class="swiperType==0?'row-between-wrapper-1':'row-between-wrapper-2'">
|
||||
<image mode="aspectFill" :style="[contentStyleBanner]" :src="item.img"
|
||||
class="slide-image aa"></image>
|
||||
</view>
|
||||
</swiper-item>
|
||||
</block>
|
||||
</swiper>
|
||||
<view v-if="docType === 0" class="dots" :style="[dotStyle]">
|
||||
<block v-for="(item,index) in banner" :key="index">
|
||||
<view class="dot-item"
|
||||
:style="{'background-color': swiperCur === index ? (dataConfig.themeStyleConfig.tabVal?dataConfig.docColor.color[0].item:themeColor) : ''}">
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
<view v-if="docType === 1" class="dots" :style="[dotStyle]">
|
||||
<block v-for="(item,index) in banner" :key="index">
|
||||
<view class="dot"
|
||||
:style="{'background-color': swiperCur === index ? (dataConfig.themeStyleConfig.tabVal?dataConfig.docColor.color[0].item:themeColor) : ''}">
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
let app = getApp();
|
||||
import {
|
||||
goPage
|
||||
} from '@/libs/iframe.js'
|
||||
import animationType from '@/utils/animationType.js'
|
||||
export default {
|
||||
name: 'homeComb',
|
||||
props: {
|
||||
dataConfig: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
},
|
||||
//判断首页显示内容,1显示分类页和商品,0首页
|
||||
navIndex: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
//是否开始滚动
|
||||
isScrolled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
//是否为微页面
|
||||
isSmallPage: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
//页面设置信息
|
||||
bgInfo: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
myMainHeight: 0, //头部tab切换页和搜索按钮的高度和
|
||||
indicatorDots: false,
|
||||
circular: true,
|
||||
autoplay: false,
|
||||
duration: 500,
|
||||
searchH: 0,
|
||||
swiperTop: 0,
|
||||
statusBarHeight: app.globalData.statusBarHeight, //手机端头部显示时间位置的高度
|
||||
swiperCur: 0,
|
||||
showSkeleton: true,
|
||||
tabClick: 0, //导航栏被点击
|
||||
isLeft: 0, //导航栏下划线位置
|
||||
isWidth: 0, //每个导航栏占位
|
||||
mainWidth: app.globalData.mainWidth,
|
||||
theme: app.globalData.theme,
|
||||
tabLeft: 0,
|
||||
bgColor: '',
|
||||
isTop: 0,
|
||||
navHeight: 0,
|
||||
isShow: false,
|
||||
marTop: 0,
|
||||
searchVal: '',
|
||||
intervalBanner: 2500,
|
||||
themeColor:this.$options.filters.filterTheme(app.globalData.theme),
|
||||
searchTop:0,
|
||||
searchRight:0,
|
||||
searchHeight:0,
|
||||
statusWidth:0,
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
banner: {
|
||||
handler(val) {
|
||||
this.bgColor = val[0].img;
|
||||
},
|
||||
immediate: true
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
//分类是否展示,0展示,1不展示
|
||||
tabShowConfig() {
|
||||
return this.dataConfig.tabShowConfig.tabVal == 0;
|
||||
},
|
||||
//搜索提示语
|
||||
placeWords() {
|
||||
return this.dataConfig.placeWords.val;
|
||||
},
|
||||
//轮播切换时间
|
||||
interval() {
|
||||
return this.dataConfig.titleConfig.val * 1000
|
||||
},
|
||||
//指示器类型,0圆,1直,2无
|
||||
docType() {
|
||||
return this.dataConfig.docConfig.tabVal
|
||||
},
|
||||
//轮播图样式
|
||||
swiperType() {
|
||||
return this.dataConfig.swiperStyleConfig.tabVal
|
||||
},
|
||||
//搜索热词列表
|
||||
hotWords() {
|
||||
return this.dataConfig.hotWords.list
|
||||
},
|
||||
//分类选中颜色
|
||||
lineColor() {
|
||||
return {
|
||||
backgroundColor: this.dataConfig.checkColor.color[0].item
|
||||
}
|
||||
},
|
||||
maskBgStyle() {
|
||||
return {
|
||||
background: this.bgInfo.isBgColor=='1' ?
|
||||
`linear-gradient(180deg, rgba(245, 245, 245, 0) 0%, ${this.bgInfo.colorPicker} 100%)` :
|
||||
`linear-gradient(180deg, rgba(245, 245, 245, 0) 0%, #f5f5f5 100%)`,
|
||||
}
|
||||
},
|
||||
//判断logo图是否展示
|
||||
logoConfig() {
|
||||
return this.dataConfig.logoConfig.url && this.dataConfig.searConfig.tabVal === 1
|
||||
},
|
||||
//logo图
|
||||
logoUrl() {
|
||||
if (this.isScrolled && this.dataConfig.logoFixConfig.url) {
|
||||
return this.dataConfig.logoFixConfig.url
|
||||
} else {
|
||||
return this.dataConfig.logoConfig.url
|
||||
}
|
||||
},
|
||||
//标签文字颜色
|
||||
textColor() {
|
||||
return this.dataConfig.fontColor.color[0].item;
|
||||
},
|
||||
//分类列表
|
||||
tabList() {
|
||||
//type=0微页面,1分类,2首页
|
||||
let tabList = this.dataConfig.listConfig.list;
|
||||
tabList.unshift({
|
||||
title: '首页',
|
||||
type: 2,
|
||||
val: 0
|
||||
})
|
||||
return tabList
|
||||
},
|
||||
//轮播列表
|
||||
banner() {
|
||||
return this.dataConfig.swiperConfig.list
|
||||
},
|
||||
//搜索框样式
|
||||
searchBoxStyle() {
|
||||
return {
|
||||
borderRadius: this.dataConfig.contentStyle.val ? this.dataConfig.contentStyle.val + 'px' : '0',
|
||||
backgroundColor: this.dataConfig.borderColor.color[0].item,
|
||||
color: this.dataConfig.textColor.color[0].item,
|
||||
textAlign: this.dataConfig.textPosition.list[this.dataConfig.textPosition.tabVal].style,
|
||||
// #ifdef MP
|
||||
height:this.searchHeight + 'px',
|
||||
flex:!this.isSmallPage?1:'',
|
||||
marginRight:!this.isSmallPage?(this.statusWidth + this.searchRight+'px'):'',
|
||||
// #endif
|
||||
}
|
||||
},
|
||||
//指示器样式
|
||||
dotStyle() {
|
||||
return {
|
||||
padding: '0 40rpx',
|
||||
justifyContent: this.dataConfig.txtStyle.tabVal === 1 ? 'center' : this.dataConfig.txtStyle
|
||||
.tabVal === 2 ? 'flex-end' : 'flex-start'
|
||||
}
|
||||
},
|
||||
//轮播图圆角
|
||||
contentStyleBanner() {
|
||||
return {
|
||||
'borderRadius': this.dataConfig.contentStyleBanner.val ? this.dataConfig.contentStyleBanner
|
||||
.val + 'px' : '0'
|
||||
}
|
||||
},
|
||||
},
|
||||
created() {
|
||||
// #ifdef MP || APP-PLUS
|
||||
this.isTop = (this.isSmallPage ? 0 : this.statusBarHeight) + 48 + 'px' //分类的top值
|
||||
// this.tabShowConfig,true有分类,false无分类
|
||||
if (!this.tabShowConfig) {
|
||||
this.myMainHeight = (this.isSmallPage ? 0 : this.statusBarHeight) + 40 + 10; //头部tab切换页和搜索按钮的高度和,10是下边距
|
||||
} else {
|
||||
this.myMainHeight = (this.isSmallPage ? 0 : this.statusBarHeight) + 40 + 42; //头部tab切换页和搜索按钮的高度和
|
||||
}
|
||||
// #endif
|
||||
|
||||
// #ifdef MP
|
||||
const res = uni.getMenuButtonBoundingClientRect()
|
||||
const statusHeight = res.top //胶囊距离顶部
|
||||
const statusRight = res.right //胶囊右边界坐标
|
||||
const jnHeight = res.height //胶囊高度
|
||||
this.statusWidth= res.width
|
||||
this.searchTop=statusHeight-this.statusBarHeight
|
||||
this.searchHeight=jnHeight
|
||||
//搜索框宽度计算
|
||||
uni.getSystemInfo({
|
||||
success:res=>{
|
||||
this.searchRight=res.windowWidth-statusRight
|
||||
}
|
||||
})
|
||||
// #endif
|
||||
|
||||
// #ifdef H5
|
||||
this.isTop = 0
|
||||
this.myMainHeight = 'auto';
|
||||
|
||||
// #endif
|
||||
|
||||
this.isWidth = (this.mainWidth - 65) / 4;
|
||||
setTimeout((e) => {
|
||||
const query = uni.createSelectorQuery().in(this);
|
||||
query.select('.header').boundingClientRect(res => {
|
||||
if (res) this.marTop = res.height //头部的高度
|
||||
}).exec();
|
||||
|
||||
//展示与不展示分类的距离值判断
|
||||
if (!this.tabShowConfig) {
|
||||
// 不展示分类
|
||||
query.select('.swiperBg').boundingClientRect(res => {
|
||||
// #ifdef H5
|
||||
this.swiperTop = this.navHeight + this.marTop + this.statusBarHeight +
|
||||
4; //轮播图的top值
|
||||
//#endif
|
||||
// #ifndef H5
|
||||
if (this.isSmallPage) {
|
||||
this.swiperTop = this.statusBarHeight; //轮播图的top值
|
||||
} else {
|
||||
this.swiperTop = this.statusBarHeight + 48; //轮播图的top值
|
||||
}
|
||||
//#endif
|
||||
}).exec();
|
||||
} else {
|
||||
//展示分类
|
||||
query.select('.navTabBox').boundingClientRect(data => {
|
||||
this.navHeight = data.height //元素navHeight的高度
|
||||
// #ifdef H5
|
||||
this.swiperTop = this.navHeight + this.marTop + this.statusBarHeight +
|
||||
4; //轮播图的top值
|
||||
//#endif
|
||||
// #ifndef H5
|
||||
if (this.isSmallPage) {
|
||||
this.swiperTop = 85; //轮播图的top值
|
||||
} else {
|
||||
this.swiperTop = this.statusBarHeight + 85; //轮播图的top值
|
||||
}
|
||||
//#endif
|
||||
}).exec();
|
||||
}
|
||||
|
||||
}, 200)
|
||||
},
|
||||
methods: {
|
||||
//轮播图跳转
|
||||
menusTap(url) {
|
||||
this.$util.navigateTo(url);
|
||||
},
|
||||
swiperChange(e) {
|
||||
let {
|
||||
current,
|
||||
source
|
||||
} = e.detail;
|
||||
if (source === 'autoplay' || source === 'touch') {
|
||||
this.swiperCur = e.detail.current;
|
||||
this.bgColor = this.banner[e.detail.current]['img']
|
||||
}
|
||||
},
|
||||
textChange(e) {
|
||||
let {
|
||||
current,
|
||||
source
|
||||
} = e.detail;
|
||||
if (source === 'autoplay' || source === 'touch') {
|
||||
this.searchVal = this.hotWords[e.detail.current]['val']
|
||||
}
|
||||
},
|
||||
// 导航栏点击
|
||||
longClick(index, item) {
|
||||
this.tabClick = index; //设置导航点击了哪一个
|
||||
this.$nextTick(() => {
|
||||
let id = 'id' + index;
|
||||
this.tabLeft = (index - 2) * this.isWidth //设置下划线位置
|
||||
this.$emit('changeTab', index, item);
|
||||
})
|
||||
},
|
||||
parentEmit(id, index) {
|
||||
this.$emit('changeTab', id, index);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.uninput {
|
||||
/* #ifdef MP */
|
||||
width: 510rpx !important;
|
||||
/* #endif */
|
||||
/* #ifndef MP */
|
||||
width: 100% !important;
|
||||
/* #endif */
|
||||
}
|
||||
|
||||
.icon-sousuo8 {
|
||||
font-size: 15px;
|
||||
|
||||
}
|
||||
|
||||
.bgwhite {
|
||||
background-color: #fff !important;
|
||||
}
|
||||
|
||||
.mask {
|
||||
z-index: 999;
|
||||
top: 260rpx;
|
||||
}
|
||||
|
||||
.navChangeBox {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.navChange {
|
||||
background-color: #fff;
|
||||
position: absolute;
|
||||
z-index: 999999;
|
||||
width: 100%;
|
||||
border-radius: 0px 0px 16rpx 16rpx;
|
||||
padding: 24rpx 20rpx;
|
||||
display: grid;
|
||||
grid-template-rows: auto;
|
||||
grid-template-columns: repeat(5, 1fr);
|
||||
grid-column-gap: 10rpx;
|
||||
grid-row-gap: 20rpx;
|
||||
|
||||
.nobg {
|
||||
background-color: #fff !important;
|
||||
}
|
||||
|
||||
.titleBox {
|
||||
height: 58rpx;
|
||||
background: #F2F2F2;
|
||||
border-radius: 8rpx;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.title {
|
||||
margin: 0 auto;
|
||||
display: inline-block;
|
||||
width: 118rpx;
|
||||
height: 58rpx;
|
||||
line-height: 58rpx;
|
||||
text-align: center;
|
||||
|
||||
opacity: 1;
|
||||
color: #333333;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
|
||||
.titleBox:nth-child(5n) {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.titleBox:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.changed {
|
||||
border-radius: 8rpx;
|
||||
@include cate-two-btn(theme);
|
||||
@include coupons_border_color(theme);
|
||||
|
||||
.title {
|
||||
@include main_color(theme);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.row-middle {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.navTabBox {
|
||||
width: 100%;
|
||||
height: 66rpx;
|
||||
color: rgba(255, 255, 255, 1);
|
||||
position: relative;
|
||||
padding: 0 24rpx 0 24rpx;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
z-index: 9;
|
||||
|
||||
&.isFixed {
|
||||
z-index: 10;
|
||||
position: fixed;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
/* #ifdef H5 */
|
||||
top: 0;
|
||||
/* #endif */
|
||||
}
|
||||
|
||||
.click {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.longTab {
|
||||
width: 94%;
|
||||
|
||||
.longItem {
|
||||
//height: 72rpx;
|
||||
display: inline-block;
|
||||
// line-height: 52rpx;
|
||||
text-align: center;
|
||||
font-size: 28rpx;
|
||||
color: #fff;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
margin-right: 42rpx;
|
||||
|
||||
&.click {
|
||||
font-weight: bold;
|
||||
font-size: 30rpx;
|
||||
color: #fff;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.name {
|
||||
height: 48rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.underlineBox {
|
||||
margin-top: 8rpx;
|
||||
height: 3px;
|
||||
transition: .5s;
|
||||
|
||||
.underline {
|
||||
width: 33rpx;
|
||||
height: 4rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.category {
|
||||
height: 66rpx;
|
||||
line-height: 46rpx;
|
||||
z-index: 3;
|
||||
|
||||
// padding: 0 15rpx 0 25rpx;
|
||||
.iconfont {
|
||||
font-size: 24rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.swiperBg {
|
||||
z-index: 1;
|
||||
margin-top: 10rpx;
|
||||
|
||||
.colorBg {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
height: 130rpx;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.page_swiper {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
margin: 0 auto;
|
||||
border-radius: 10rpx;
|
||||
overflow: hidden;
|
||||
z-index: 8;
|
||||
padding: 0rpx 20rpx 0rpx;
|
||||
|
||||
image {
|
||||
width: 100%;
|
||||
height: 310rpx;
|
||||
margin: 0 auto;
|
||||
border-radius: 10rpx;
|
||||
}
|
||||
|
||||
.acea-row.row-between-wrapper {
|
||||
height: 310rpx;
|
||||
margin: 0 auto;
|
||||
border-radius: 10rpx;
|
||||
}
|
||||
|
||||
.acea-row.row-between-wrapper-1 {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.acea-row.row-between-wrapper-2 {
|
||||
width: 97%;
|
||||
}
|
||||
|
||||
swiper {
|
||||
width: 100%;
|
||||
display: block;
|
||||
height: 310rpx;
|
||||
|
||||
&.scalex {
|
||||
/deep/.uni-swiper-slide-frame {
|
||||
transform: translate(0, 0) !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
image {
|
||||
transform: scale(0.96);
|
||||
transition: all 0.6s ease;
|
||||
}
|
||||
|
||||
/deep/ swiper-item.active {
|
||||
image {
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
/*用来包裹所有的小圆点 */
|
||||
.dots {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
position: absolute;
|
||||
bottom: 40rpx;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.dot-item {
|
||||
width: 10rpx;
|
||||
height: 10rpx;
|
||||
background-color: rgba(255, 255, 255, .4);
|
||||
border-radius: 50%;
|
||||
margin: 0 6rpx;
|
||||
}
|
||||
|
||||
/*未选中时的小圆点样式 */
|
||||
.dot {
|
||||
width: 16rpx;
|
||||
height: 6rpx;
|
||||
border-radius: 6rpx;
|
||||
margin-right: 6rpx;
|
||||
background-color: rgba(255, 255, 255, .4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.scrolled {
|
||||
z-index: 5000;
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
background-color: #fff !important;
|
||||
color: #000 !important;
|
||||
transition: background-color .5s ease;
|
||||
|
||||
.longItem,
|
||||
.click,
|
||||
.category text {
|
||||
color: #000 !important;
|
||||
}
|
||||
|
||||
.btn .iconfont {
|
||||
color: #333 !important;
|
||||
}
|
||||
|
||||
.iconnum {
|
||||
background: #333 !important;
|
||||
}
|
||||
|
||||
.underline {
|
||||
background: #000 !important;
|
||||
}
|
||||
|
||||
.click {
|
||||
&::after {
|
||||
background-color: #fff !important;
|
||||
}
|
||||
}
|
||||
|
||||
.input,
|
||||
.uninput {
|
||||
|
||||
background-color: #eee !important;
|
||||
}
|
||||
}
|
||||
|
||||
.page_count {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
background-repeat: no-repeat;
|
||||
|
||||
|
||||
.bg-img {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
/* #ifdef MP || APP-PLUS */
|
||||
z-index: -1;
|
||||
/* #endif */
|
||||
/* #ifdef H5 */
|
||||
z-index: 0;
|
||||
/* #endif */
|
||||
z-index: 0;
|
||||
filter: blur(0);
|
||||
overflow: hidden;
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
filter: blur(30rpx);
|
||||
transform: scale(1.5);
|
||||
}
|
||||
|
||||
.maskBg {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
height: 136px;
|
||||
background: linear-gradient(180deg, rgba(245, 245, 245, 0) 0%, #f5f5f5 100%);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.my-main {
|
||||
left: 0;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
z-index: 30;
|
||||
transition: background-color .5s ease;
|
||||
}
|
||||
|
||||
.page_count {
|
||||
|
||||
.header {
|
||||
width: 100%;
|
||||
padding: 24rpx;
|
||||
|
||||
.serch-wrapper {
|
||||
align-items: center;
|
||||
|
||||
.logo {
|
||||
width: 118rpx;
|
||||
margin-right: 24rpx;
|
||||
}
|
||||
|
||||
image {
|
||||
width: 118rpx;
|
||||
height: 42rpx;
|
||||
}
|
||||
|
||||
.input {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 546rpx;
|
||||
height: 55rpx;
|
||||
padding-left: 20rpx;
|
||||
font-size: 26rpx;
|
||||
padding-right: 4rpx;
|
||||
box-sizing: border-box;
|
||||
|
||||
.iconfont {
|
||||
margin-right: 4rpx;
|
||||
font-size: 26rpx;
|
||||
color: #666666;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.tabNav {
|
||||
padding-top: 24rpx;
|
||||
}
|
||||
}
|
||||
|
||||
/* #ifdef MP || APP-PLUS */
|
||||
.mp-header {
|
||||
z-index: 999;
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
/* #ifdef H5 */
|
||||
padding-bottom: 20rpx;
|
||||
/* #endif */
|
||||
|
||||
.serch-wrapper {
|
||||
height: 100%;
|
||||
align-items: center;
|
||||
padding: 0 24rpx 0 24rpx;
|
||||
|
||||
image {
|
||||
width: 118rpx;
|
||||
height: 42rpx;
|
||||
margin-right: 30rpx;
|
||||
}
|
||||
|
||||
.input {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
/* #ifdef MP */
|
||||
width: 365rpx;
|
||||
/* #endif */
|
||||
/* #ifndef MP */
|
||||
width: 546rpx;
|
||||
/* #endif */
|
||||
/* #ifdef APP-PLUS */
|
||||
flex: 1;
|
||||
/* #endif */
|
||||
height: 50rpx;
|
||||
padding-left: 20rpx;
|
||||
font-size: 28rpx;
|
||||
box-sizing: border-box;
|
||||
|
||||
.iconfont {
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* #endif */
|
||||
.swiperTxt {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
line-height: 52rpx;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.swiperTxt .text {
|
||||
width: 100%;
|
||||
|
||||
}
|
||||
|
||||
.swiperTxt .text .label {
|
||||
font-size: 20rpx;
|
||||
color: #ff4c48;
|
||||
width: 64rpx;
|
||||
height: 30rpx;
|
||||
border-radius: 40rpx;
|
||||
text-align: center;
|
||||
line-height: 28rpx;
|
||||
border: 2rpx solid #ff4947;
|
||||
}
|
||||
|
||||
.swiperTxt .text .newsTitle {
|
||||
font-size: 24rpx;
|
||||
}
|
||||
|
||||
.swiperTxt swiper {
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.navChecked {
|
||||
font-size: 32rpx !important;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.checkColor {
|
||||
@include main_color(theme);
|
||||
}
|
||||
.text-box{
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
660
app/components/homeIndex/homeTab.vue
Normal file
660
app/components/homeIndex/homeTab.vue
Normal file
@@ -0,0 +1,660 @@
|
||||
<template>
|
||||
<!-- tab选项卡 -->
|
||||
<view class="index-product-wrapper" :style="[mbConfig]">
|
||||
<view class="nav-bd longTab" :style="[tabBgColor]">
|
||||
<scroll-view scroll-x="true" style="white-space: nowrap; display: flex" :scroll-left="tabLeft">
|
||||
<view class="longItem"
|
||||
:style="'color:' + (index == ProductNavindex ? checkColor : fontColor)+';--color:'+checkColor"
|
||||
:data-index="index" :class="index===ProductNavindex?'click':''" v-for="(item,index) in navList"
|
||||
:key="index" :id="'id'+index" @click="ProductNavTab(item, index)">{{ item.val }}
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
<view :style="[boxStyle]">
|
||||
<!-- 单列 -->
|
||||
<block v-if="itemStyle == 0">
|
||||
<view class="listA" :style="[gridGap]">
|
||||
<view class="item" v-for="(item, index) in tempArr" :key="index" @click="goDetail(item)">
|
||||
<view class="pictrue">
|
||||
<easy-loadimage :image-src="item.image"
|
||||
:radius="dataConfig.contentStyle.val"></easy-loadimage>
|
||||
<view v-if="item.activityStyle" :style="{ backgroundImage: `url(${item.activityStyle})` }" class="border-picture"></view>
|
||||
</view>
|
||||
<view class="text-info text-add">
|
||||
<view>
|
||||
<view class="title line2" :style="[titleColor]" v-if="showArr.includes(0)">
|
||||
<span>{{ item.storeName }}</span>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="item.productTags && item.productTags.locationUnderTitle.length">
|
||||
<text
|
||||
v-for="items in item.productTags.locationUnderTitle.length>3?item.productTags.locationUnderTitle.slice(0,3):item.productTags.locationUnderTitle"
|
||||
:key="items.id" class="mr10 tagSolid">{{items.tagName}}</text>
|
||||
</view>
|
||||
<view class="price acea-row row-middle" :style="[priceColor]">
|
||||
<view v-if="showArr.includes(1)">
|
||||
¥<span class="num semiBold">{{item.price}}</span>
|
||||
</view>
|
||||
</view>
|
||||
<view class="old-price" v-if="showArr.includes(2)" :style="[soldColor]">
|
||||
已售 {{ item.sales || 0 }} {{ item.unitName }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
<!-- 两列 -->
|
||||
<block v-if="itemStyle == 1">
|
||||
<view class="listC" :style="[gridGap]">
|
||||
<view class="item" :style="[contentStyle]" v-for="(item, index) in tempArr" :key="index"
|
||||
@click="goDetail(item)">
|
||||
<view class="pictrue">
|
||||
<easy-loadimage :image-src="item.image"
|
||||
:radius="dataConfig.contentStyle.val"></easy-loadimage>
|
||||
<view v-if="item.activityStyle" :style="{ backgroundImage: `url(${item.activityStyle})` }" class="border-picture"></view>
|
||||
</view>
|
||||
<view class="text-info">
|
||||
<view class="title line2" :style="[titleColor]" v-if="showArr.includes(0)">
|
||||
<span>{{ item.storeName }}</span>
|
||||
</view>
|
||||
<view v-if="item.productTags && item.productTags.locationUnderTitle.length">
|
||||
<text
|
||||
v-for="items in item.productTags.locationUnderTitle.length>3?item.productTags.locationUnderTitle.slice(0,3):item.productTags.locationUnderTitle"
|
||||
:key="items.id" class="mr10 tagSolid">{{items.tagName}}</text>
|
||||
</view>
|
||||
<view class="row-middle price" :style="[priceColor]">
|
||||
<view v-if="showArr.includes(1)">
|
||||
¥<span class="num semiBold">{{item.price}}</span>
|
||||
</view>
|
||||
<view class="old-price ml10 " v-if="showArr.includes(2)" :style="[soldColor]">
|
||||
已售 {{ item.sales || 0 }} {{ item.unitName }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
<!-- 三列 -->
|
||||
<block v-if="itemStyle == 2">
|
||||
<view class="listB" :style="[gridGap]">
|
||||
<view class="item" v-for="(item, index) in tempArr" :key="index" @click="goDetail(item)">
|
||||
<view class="pictrue">
|
||||
<easy-loadimage :image-src="item.image"
|
||||
:radius="dataConfig.contentStyle.val"></easy-loadimage>
|
||||
<view v-if="item.activityStyle" :style="{ backgroundImage: `url(${item.activityStyle})` }" class="border-picture"></view>
|
||||
</view>
|
||||
<view class="text-info">
|
||||
<view class="title line2" :style="[titleColor]" v-if="showArr.includes(0)">
|
||||
<span>{{ item.storeName }}</span>
|
||||
</view>
|
||||
<view v-if="item.productTags && item.productTags.locationUnderTitle.length">
|
||||
<text
|
||||
v-for="items in item.productTags.locationUnderTitle.length>3?item.productTags.locationUnderTitle.slice(0,3):item.productTags.locationUnderTitle"
|
||||
:key="items.id" class="mr10 tagSolid">{{items.tagName}}</text>
|
||||
</view>
|
||||
<view class="price" :style="[priceColor]">
|
||||
<view v-if="showArr.includes(1)">
|
||||
¥<span class="num semiBold">{{item.price}}</span>
|
||||
</view>
|
||||
</view>
|
||||
<view class="old-price " v-if="showArr.includes(2)" :style="[soldColor]">
|
||||
已售 {{ item.sales || 0 }} {{ item.unitName }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
<!-- 大图 -->
|
||||
<block v-if="itemStyle == 3 && tempArr.length">
|
||||
<view class="listBig" :style="[gridGap]">
|
||||
<view class="itemBig" v-for="(item,index) in tempArr" :key="index" @click="goDetail(item)">
|
||||
<view class="img-box">
|
||||
<easy-loadimage :image-src="item.image"
|
||||
:radius="dataConfig.contentStyle.val"></easy-loadimage>
|
||||
<view v-if="item.activityStyle" :style="{ backgroundImage: `url(${item.activityStyle})` }" class="border-picture"></view>
|
||||
</view>
|
||||
<view class="name line2" :style="[titleColor]" v-if="showArr.includes(0)">
|
||||
<span>{{item.storeName}}</span>
|
||||
</view>
|
||||
<view style="padding: 0 8px;"
|
||||
v-if="item.productTags && item.productTags.locationUnderTitle.length">
|
||||
<text
|
||||
v-for="items in item.productTags.locationUnderTitle.length>3?item.productTags.locationUnderTitle.slice(0,3):item.productTags.locationUnderTitle"
|
||||
:key="items.id" class="mr10 tagSolid">{{items.tagName}}</text>
|
||||
</view>
|
||||
<slot name="center"></slot>
|
||||
<view class="row-middle price" :style="[priceColor]">
|
||||
<span v-if="showArr.includes(1)">
|
||||
¥<span class="num semiBold">{{item.price}}</span>
|
||||
</span>
|
||||
<view class="old-price" v-if="showArr.includes(2)" :style="[soldColor]">
|
||||
已售 {{ item.sales || 0 }} {{ item.unitName }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
import {
|
||||
getProductslist,productByidsApi
|
||||
} from '@/api/store.js';
|
||||
let app = getApp();
|
||||
import easyLoadimage from '@/components/base/easy-loadimage.vue';
|
||||
export default {
|
||||
name: 'homeTab',
|
||||
props: {
|
||||
dataConfig: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
//普通价格
|
||||
svipPriceStyle: {
|
||||
svipBox: {
|
||||
height: '26rpx',
|
||||
borderRadius: '60rpx 56rpx 56rpx 20rpx',
|
||||
},
|
||||
icon: {
|
||||
height: '26rpx',
|
||||
fontSize: '18rpx',
|
||||
borderRadius: '12rpx 0 12rpx 2rpx'
|
||||
},
|
||||
price: {
|
||||
fontSize: '38rpx'
|
||||
},
|
||||
svipPrice: {
|
||||
fontSize: '22rpx'
|
||||
}
|
||||
},
|
||||
//svip价格
|
||||
svipIconStyle: {
|
||||
svipBox: {
|
||||
height: '26rpx',
|
||||
borderRadius: '24rpx 40rpx 40rpx 0.4rpx',
|
||||
},
|
||||
price: {
|
||||
fontSize: '38rpx'
|
||||
},
|
||||
svipPrice: {
|
||||
fontSize: '18rpx'
|
||||
}
|
||||
},
|
||||
tempArr: [],
|
||||
iSshowH: false,
|
||||
ProductNavindex: 0,
|
||||
itemStyle: 0, //样式类型
|
||||
themeColor: '#f00',
|
||||
titleConfig: 1, //标题位置
|
||||
infoColor: '#999',
|
||||
goodType: 3,
|
||||
loadend: false,
|
||||
loading: false,
|
||||
page: 1,
|
||||
isWidth: 0, //每个导航栏占位
|
||||
tabLeft: 0,
|
||||
limit: 0 ,//分页条数
|
||||
themeColor:this.$options.filters.filterTheme(app.globalData.theme)
|
||||
};
|
||||
},
|
||||
components: {
|
||||
easyLoadimage,
|
||||
},
|
||||
created() {
|
||||
let that = this
|
||||
uni.getSystemInfo({
|
||||
success(e) {
|
||||
that.isWidth = (e.windowWidth) / 5;
|
||||
}
|
||||
})
|
||||
},
|
||||
computed: {
|
||||
//标签文字颜色
|
||||
fontColor() {
|
||||
return this.dataConfig.fontColor.color[0].item
|
||||
},
|
||||
//选中颜色
|
||||
checkColor() {
|
||||
return this.dataConfig.checkThemeStyleConfig.tabVal?this.dataConfig.checkColor.color[0].item:this.themeColor
|
||||
},
|
||||
//选项卡背景颜色
|
||||
tabBgColor() {
|
||||
return {
|
||||
background: `linear-gradient(${this.dataConfig.tabBgColor.color[0].item}, ${this.dataConfig.tabBgColor.color[1].item})`,
|
||||
};
|
||||
},
|
||||
//页面间距
|
||||
mbConfig() {
|
||||
return {
|
||||
marginTop: this.dataConfig.mbConfig.val ? this.dataConfig.mbConfig.val + 'px' : 0
|
||||
}
|
||||
},
|
||||
//分类列表
|
||||
navList() {
|
||||
return this.dataConfig.tabItemConfig.list;
|
||||
},
|
||||
//最外层盒子的样式
|
||||
boxStyle() {
|
||||
return {
|
||||
borderRadius: this.dataConfig.bgStyle.val * 2 + 'rpx',
|
||||
background: `linear-gradient(${this.dataConfig.bgColor.color[0].item}, ${this.dataConfig.bgColor.color[1].item})`,
|
||||
margin: this.dataConfig.topConfig.val * 2 + 'rpx' + ' ' + this.dataConfig.lrConfig.val * 2 + 'rpx' +
|
||||
' ' + 0,
|
||||
padding: this.dataConfig.upConfig.val * 2 + 'rpx' + ' ' + 0 + ' ' + this.dataConfig.downConfig.val *
|
||||
2 + 'rpx'
|
||||
}
|
||||
},
|
||||
//商品间距
|
||||
gridGap() {
|
||||
return {
|
||||
'grid-gap': this.dataConfig.contentConfig.val * 2 + 'rpx'
|
||||
}
|
||||
},
|
||||
//图片的圆角和高度
|
||||
imgStyle() {
|
||||
return {
|
||||
'border-radius': this.dataConfig.contentStyle.val * 2 + 'rpx',
|
||||
}
|
||||
},
|
||||
//价格颜色
|
||||
priceColor() {
|
||||
return {
|
||||
'color': this.dataConfig.priceThemeStyleConfig.tabVal?this.dataConfig.priceColor.color[0].item:this.themeColor,
|
||||
}
|
||||
},
|
||||
//商品名称颜色
|
||||
titleColor() {
|
||||
return {
|
||||
'color': this.dataConfig.titleColor.color[0].item,
|
||||
}
|
||||
},
|
||||
//已售数量
|
||||
soldColor() {
|
||||
return {
|
||||
'color': this.dataConfig.soldColor.color[0].item,
|
||||
}
|
||||
},
|
||||
showArr(){
|
||||
return this.dataConfig.tabItemConfig.list[this.ProductNavindex].activeList.showContent
|
||||
},
|
||||
//商品名称
|
||||
titleShow() {
|
||||
if (this.dataConfig.typeConfig.activeValue.includes(0)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
//价格
|
||||
priceShow() {
|
||||
if (this.dataConfig.typeConfig.activeValue.includes(1)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
//销量
|
||||
soldShow() {
|
||||
if (this.dataConfig.typeConfig.activeValue.includes(2)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
//内容圆角
|
||||
contentStyle() {
|
||||
return {
|
||||
'border-radius': this.dataConfig.contentStyle.val ? this.dataConfig.contentStyle.val + 'px' : '0'
|
||||
};
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
//默认加载第一项的商品数据
|
||||
if (this.navList) {
|
||||
this.itemStyle = this.navList[0].activeList ? this.navList[0].activeList.styleType : 0;
|
||||
if (this.navList[0].activeList && this.navList[0].activeList.activeProTabIndex == 0) {
|
||||
this.getProductByids(this.navList[0].activeList.goods);
|
||||
} else {
|
||||
this.limit = this.navList[0].activeList ? this.navList[0].activeList.num : 3;
|
||||
if (this.navList[0].activeList) {
|
||||
this.getGroomList(this.navList[0].activeList);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
//uniapp小程序用deep重写组件样式不生效
|
||||
options: {
|
||||
styleIsolation: 'shared'
|
||||
},
|
||||
methods: {
|
||||
//根据商品id集合查询对应商品
|
||||
getProductByids(data) {
|
||||
if(!data.length) return;
|
||||
uni.showLoading({
|
||||
title: '加载中...'
|
||||
});
|
||||
let ids = data.map((item) => item.id).join(',');
|
||||
productByidsApi(ids).then((res) => {
|
||||
this.tempArr = res.data;
|
||||
uni.hideLoading();
|
||||
})
|
||||
.catch(res => {
|
||||
uni.hideLoading();
|
||||
});
|
||||
},
|
||||
// 选项卡切换点击事件;商品类型选择除第一个指定商品,加载商品从平台端获取数据,其余选项均请求接口加载
|
||||
changeTab(item, index) {
|
||||
this.tempArr = [];
|
||||
if (item.activeList.activeProTabIndex == 0) {
|
||||
this.getProductByids(item.activeList.goods);
|
||||
} else {
|
||||
this.page = 1;
|
||||
this.loadend = false;
|
||||
this.getGroomList(item.activeList);
|
||||
}
|
||||
},
|
||||
// 商品列表
|
||||
getGroomList(item) {
|
||||
let cid = item.activeValue; //分类id
|
||||
let goodsSort = item.goodsSort // 商品排序,0综合,1按销量,2按价格
|
||||
let priceOrder = '';
|
||||
let salesOrder = '';
|
||||
if (this.loadend) return false;
|
||||
if (this.loading) return false;
|
||||
if (goodsSort === 0) {
|
||||
priceOrder = '';
|
||||
salesOrder = '';
|
||||
} else if (goodsSort === 1) {
|
||||
priceOrder = '';
|
||||
salesOrder = 'desc';
|
||||
} else {
|
||||
priceOrder = 'desc';
|
||||
salesOrder = '';
|
||||
}
|
||||
getProductslist({
|
||||
page: this.page,
|
||||
limit: this.limit,
|
||||
cid: cid,
|
||||
priceOrder: priceOrder,
|
||||
salesOrder: salesOrder
|
||||
}).then((res) => {
|
||||
let list = res.data.list;
|
||||
this.tempArr = this.$util.SplitArray(list, this.tempArr);
|
||||
let loadend = list.length < this.limit;
|
||||
this.loadend = loadend;
|
||||
this.loading = false;
|
||||
this.page = this.page + 1;
|
||||
})
|
||||
.catch(res => {
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
// 选项卡切换
|
||||
ProductNavTab(item, index) {
|
||||
this.ProductNavindex = index;
|
||||
this.itemStyle = this.navList[index].activeList.styleType;
|
||||
this.$nextTick(() => {
|
||||
let id = 'id' + index;
|
||||
this.tabLeft = (index - 2) * this.isWidth //设置下划线位置
|
||||
})
|
||||
this.limit = item.activeList.num;
|
||||
this.changeTab(item, index);
|
||||
},
|
||||
goDetail(item) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/goods/goods_details/index?id=${item.id}`
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.longTab {
|
||||
.longItem {
|
||||
height: 70rpx;
|
||||
display: inline-block;
|
||||
line-height: 70rpx;
|
||||
text-align: center;
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
margin-right: 46rpx;
|
||||
&.click {
|
||||
font-weight: bold;
|
||||
font-size: 30rpx;
|
||||
position: relative;
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
width: 40rpx;
|
||||
height: 4rpx;
|
||||
background: var(--color);
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.index-product-wrapper {
|
||||
|
||||
&.on {
|
||||
min-height: 1500rpx;
|
||||
}
|
||||
|
||||
.nav-bd {
|
||||
height: 70rpx;
|
||||
line-height: 70rpx;
|
||||
padding-left: 20rpx;
|
||||
background: #fff;
|
||||
|
||||
.item {
|
||||
display: inline-block;
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
font-weight: 400;
|
||||
padding-right: 48rpx;
|
||||
|
||||
&.on {
|
||||
border-radius: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.text-add {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.listBig {
|
||||
display: grid;
|
||||
grid-template-rows: auto;
|
||||
grid-template-columns: repeat(1, 1fr);
|
||||
padding: 0 20rpx;
|
||||
|
||||
.itemBig {
|
||||
width: 100%;
|
||||
|
||||
.img-box {
|
||||
width: 100%;
|
||||
height: 710rpx;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.name {
|
||||
font-size: 28rpx;
|
||||
font-weight: bold;
|
||||
margin-top: 16rpx;
|
||||
// padding: 0 8px;
|
||||
}
|
||||
|
||||
.price {
|
||||
font-weight: bold;
|
||||
font-size: 12px;
|
||||
margin-top: 10rpx;
|
||||
// padding: 0 8px;
|
||||
|
||||
.num {
|
||||
font-size: 32rpx;
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
|
||||
.old-price {
|
||||
color: #aaa;
|
||||
font-weight: normal;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.listA {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(1, 1fr);
|
||||
grid-template-rows: auto;
|
||||
width: 100%;
|
||||
padding: 0 20rpx;
|
||||
|
||||
.item {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
|
||||
.pictrue {
|
||||
width: 220rpx;
|
||||
height: 220rpx;
|
||||
position: relative;
|
||||
|
||||
image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.text-info {
|
||||
margin-left: 14rpx;
|
||||
flex: 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.listB {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
grid-template-rows: auto;
|
||||
width: 100%;
|
||||
padding: 0 20rpx;
|
||||
|
||||
.item {
|
||||
.pictrue {
|
||||
width: 100%;
|
||||
height: 220rpx;
|
||||
position: relative;
|
||||
|
||||
image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.text-info {
|
||||
padding: 10rpx 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.listC {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
grid-template-rows: auto;
|
||||
width: 100%;
|
||||
padding: 0 20rpx;
|
||||
|
||||
/deep/.origin-img,
|
||||
/deep/.easy-loadimage {
|
||||
border-bottom-left-radius: 0 !important;
|
||||
border-bottom-right-radius: 0 !important;
|
||||
}
|
||||
|
||||
.item {
|
||||
background-color: #fff;
|
||||
overflow: hidden;
|
||||
|
||||
.pictrue {
|
||||
width: 100%;
|
||||
height: 345rpx;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
|
||||
image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.text-info {
|
||||
padding: 16rpx 0 16rpx 16rpx;
|
||||
|
||||
.title {
|
||||
width: 300rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.text-info {
|
||||
.title {
|
||||
width: 100%;
|
||||
height: 80rpx;
|
||||
line-height: 40rpx;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.old-price {
|
||||
font-weight: normal;
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.price {
|
||||
font-size: 36rpx;
|
||||
font-weight: 550;
|
||||
|
||||
text {
|
||||
padding-bottom: 4rpx;
|
||||
font-size: 26rpx;
|
||||
font-weight: normal;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.mer_badge {
|
||||
padding: 0 4rpx;
|
||||
background-color: theme;
|
||||
color: #fff;
|
||||
font-size: 20rpx;
|
||||
display: inline-block;
|
||||
border-radius: 4rpx;
|
||||
line-height: 28rpx;
|
||||
height: 28rpx;
|
||||
}
|
||||
</style>
|
||||
225
app/components/homeIndex/hotSpot.vue
Normal file
225
app/components/homeIndex/hotSpot.vue
Normal file
@@ -0,0 +1,225 @@
|
||||
<template>
|
||||
<!-- 热区+图片魔方 -->
|
||||
<view class="mobile-page" v-if="dataConfig" :style="[boxStyle]">
|
||||
<view class="advert">
|
||||
<!-- 单图/热区布局 -->
|
||||
<template v-if="style === 0">
|
||||
<view class="advertItem01 acea-row hotspot" v-for="(item, index) in picList" :key="index">
|
||||
<image :src="item.image" mode="widthFix" v-if="item.image" :style="[contentStyle]"
|
||||
@click="dataConfig.checkoutConfig.hotspot.length?'':goDetail(item)"></image>
|
||||
<view v-for="(item, index) in dataConfig.checkoutConfig.hotspot" :key="index" :style="{
|
||||
top: `${Number(spotIndex*item.starY)}rpx`,
|
||||
left: `${Number(spotIndex*item.starX)}rpx`,
|
||||
width: `${Number(spotIndex*item.areaWidth)}rpx`,
|
||||
height: `${Number(spotIndex*item.areaHeight)}rpx`,
|
||||
}" class="area" @click="goDetail(item)"></view>
|
||||
</view>
|
||||
</template>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
export default {
|
||||
name: 'hotSpot',
|
||||
props: {
|
||||
dataConfig: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
picList: this.dataConfig.picStyle.picList,
|
||||
style: this.dataConfig.tabConfig.tabVal,
|
||||
prConfig: this.dataConfig.lrConfig.val,
|
||||
igConfig: this.dataConfig.igConfig.val
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
//最外层盒子的样式
|
||||
boxStyle() {
|
||||
return {
|
||||
borderRadius: this.dataConfig.bgStyle.val * 2 + 'rpx',
|
||||
backgroundImage: `linear-gradient(${this.dataConfig.bgColor.color[0].item}, ${this.dataConfig.bgColor.color[1].item})`,
|
||||
margin: this.dataConfig.mbConfig.val * 2 + 'rpx' + ' ' + this.dataConfig.lrConfig.val * 2 + 'rpx' +
|
||||
' ' + 0,
|
||||
padding: this.dataConfig.upConfig.val * 2 + 'rpx' + ' ' + '0' + ' ' + this.dataConfig.downConfig.val *
|
||||
2 + 'rpx'
|
||||
}
|
||||
},
|
||||
contentStyle(){
|
||||
return{
|
||||
borderRadius: this.dataConfig.contentStyle.val * 2 + 'rpx',
|
||||
}
|
||||
},
|
||||
//伸缩系数
|
||||
spotIndex(){
|
||||
return (750-4*this.dataConfig.lrConfig.val)/456
|
||||
},
|
||||
// 两张图片 图片间距样式
|
||||
twoImgStyle() {
|
||||
return {
|
||||
width: (750 - 2 * this.igConfig - 4 * this.prConfig) / 2 + 'rpx',
|
||||
height: (750 - 2 * this.igConfig - 4 * this.prConfig) / 2 + 'rpx',
|
||||
}
|
||||
},
|
||||
// 第一种 三张图片间距样式
|
||||
thrOneImgStyle() {
|
||||
return {
|
||||
width: (750 - 4 * this.igConfig - 4 * this.prConfig) / 3 + 'rpx',
|
||||
height: (750 - 4 * this.igConfig - 4 * this.prConfig) / 3 + 'rpx',
|
||||
}
|
||||
},
|
||||
// 第一种四张图片布局
|
||||
forOneImgStyle() {
|
||||
return {
|
||||
width: (750 - 6 * this.igConfig - 4 * this.prConfig) / 4 + 'rpx',
|
||||
}
|
||||
},
|
||||
// 第二种四张图片布局
|
||||
forTwoImgStyle() {
|
||||
return {
|
||||
width: (750 - 2 * this.igConfig - 4 * this.prConfig) / 2 + 'rpx',
|
||||
height: (750 - 2 * this.igConfig - 4 * this.prConfig) / 2 + 'rpx',
|
||||
}
|
||||
},
|
||||
imgBoxStyle() {
|
||||
return {
|
||||
display: this.igConfig ? 'flex' : '',
|
||||
'justify-content': this.igConfig ? 'space-between' : ''
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
//替换安全域名
|
||||
setDomain: function(url) {
|
||||
url = url ? url.toString() : '';
|
||||
//本地调试打开,生产请注销
|
||||
if (url.indexOf("https://") > -1) return url;
|
||||
else return url.replace('http://', 'https://');
|
||||
},
|
||||
goDetail(item) {
|
||||
this.$util.navigateTo(item.link);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.mobile-page {
|
||||
.advert {
|
||||
.advertItem01 {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
.empty-box {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.advertItem02 {
|
||||
width: 100%;
|
||||
|
||||
.item {
|
||||
width: 50%;
|
||||
height: auto;
|
||||
|
||||
image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.empty-box {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.advertItem03 {
|
||||
.item {
|
||||
width: 33.3333%;
|
||||
height: auto;
|
||||
|
||||
.empty-box {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.advertItem04 {
|
||||
.item {
|
||||
width: 50%;
|
||||
height: auto;
|
||||
|
||||
.empty-box {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.pic {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.advertItem05 {
|
||||
.item {
|
||||
width: 25%;
|
||||
|
||||
.empty-box {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.advertItem06 {
|
||||
.item {
|
||||
width: 50%;
|
||||
|
||||
image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.empty-box {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.hotspot {
|
||||
position: relative;
|
||||
|
||||
.area {
|
||||
position: absolute;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
302
app/components/homeIndex/menus.vue
Normal file
302
app/components/homeIndex/menus.vue
Normal file
@@ -0,0 +1,302 @@
|
||||
<template>
|
||||
<!-- 导航组 -->
|
||||
<view v-show="menus.length" :style="[boxStyle]">
|
||||
<view v-if="isMany === 1">
|
||||
<view class="swiper">
|
||||
<swiper :interval="interval" :duration="duration" :style="'height:'+ navHigh +'px;'"
|
||||
@change='bannerfun'>
|
||||
<block>
|
||||
<swiper-item v-for="(item,indexw) in menuList" :key="indexw">
|
||||
<view class="menu acea-row" :id="'nav' + indexw" :style="[gridColumns]">
|
||||
<view :style="[titleColor]" class="item" :class="number===1?'four':number===2?'five':''"
|
||||
v-for="(itemn,indexn) in item.list" :key="indexn"
|
||||
@click="menusTap(itemn.info[1].value)">
|
||||
<view class="pictrue skeleton-radius">
|
||||
<easy-loadimage :image-src="itemn.img" :radius="dataConfig.contentStyle.val">
|
||||
</easy-loadimage>
|
||||
</view>
|
||||
<view class="menu-txt">{{ itemn.info[0].value }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</swiper-item>
|
||||
</block>
|
||||
</swiper>
|
||||
</view>
|
||||
<view class="dot acea-row row-center-wrapper" v-if="docConfig<2 && menuList.length>1">
|
||||
<view class="dot-item line_dot-item" :style="active==index?'background:'+ dotColor:''"
|
||||
v-for="(item,index) in menuList"></view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="nav oneNav" v-else>
|
||||
<scroll-view scroll-x="true" style="white-space: nowrap; display: flex" show-scrollbar="false">
|
||||
<block v-for="(item, index) in menus" :key="index">
|
||||
<view class="item" v-show="item.status" :style="[titleColor]" @click="menusTap(item.info[1].value)">
|
||||
<view class="pictrue skeleton-radius">
|
||||
<easy-loadimage :image-src="item.img" :radius="dataConfig.contentStyle.val">
|
||||
</easy-loadimage>
|
||||
</view>
|
||||
<view class="menu-txt">{{ item.info[0].value }}</view>
|
||||
</view>
|
||||
</block>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
import easyLoadimage from '@/components/base/easy-loadimage.vue';
|
||||
export default {
|
||||
name: 'menus',
|
||||
props: {
|
||||
dataConfig: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
}
|
||||
},
|
||||
components: {
|
||||
easyLoadimage
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
interval: 3000,
|
||||
duration: 500,
|
||||
menus: this.dataConfig.menuConfig.list || [],
|
||||
rowsNum: this.dataConfig.rowsNum.tabVal,
|
||||
number: this.dataConfig.number.tabVal,
|
||||
isMany: this.dataConfig.tabConfig.tabVal,
|
||||
docConfig: 0,
|
||||
dotColor: '#E93323',
|
||||
menuList: [],
|
||||
active: 0,
|
||||
navHigh: 0
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
//最外层盒子的样式
|
||||
boxStyle() {
|
||||
return {
|
||||
borderRadius: this.dataConfig.bgStyle.val * 2 + 'rpx',
|
||||
background: `linear-gradient(${this.dataConfig.bgColor.color[0].item}, ${this.dataConfig.bgColor.color[1].item})`,
|
||||
margin: this.dataConfig.mbConfig.val * 2 + 'rpx' + ' ' + this.dataConfig.lrConfig.val * 2 + 'rpx' +' ' + 0,
|
||||
padding: this.dataConfig.upConfig.val * 2 + 'rpx' + ' ' + 0 + ' ' + this.dataConfig.downConfig.val *2 + 'rpx'
|
||||
}
|
||||
},
|
||||
//分几行展示,一行展示多少个
|
||||
gridColumns() {
|
||||
if (this.dataConfig.number.tabVal == 0) {
|
||||
return {
|
||||
gridRowGap: this.dataConfig.contentConfig.val * 2 + 'rpx',
|
||||
gridTemplateColumns: 'repeat(3, 1fr)'
|
||||
}
|
||||
} else if (this.dataConfig.number.tabVal == 1) {
|
||||
return {
|
||||
gridRowGap: this.dataConfig.contentConfig.val * 2 + 'rpx',
|
||||
gridTemplateColumns: 'repeat(4, 1fr)'
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
gridRowGap: this.dataConfig.contentConfig.val * 2 + 'rpx',
|
||||
gridTemplateColumns: 'repeat(5, 1fr)'
|
||||
}
|
||||
}
|
||||
},
|
||||
//标题颜色
|
||||
titleColor() {
|
||||
return {
|
||||
'color': this.dataConfig.titleColor.color[0].item,
|
||||
}
|
||||
},
|
||||
//内容圆角
|
||||
menuStyle() {
|
||||
return {
|
||||
'border-radius': this.dataConfig.contentStyle.val + 'px'
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
if (this.rowsNum === 0) {
|
||||
if (this.number === 0) {
|
||||
this.pageNum(6)
|
||||
} else if (this.number === 1) {
|
||||
this.pageNum(8)
|
||||
} else {
|
||||
this.pageNum(10)
|
||||
}
|
||||
} else if (this.rowsNum === 1) {
|
||||
if (this.number === 0) {
|
||||
this.pageNum(9)
|
||||
} else if (this.number === 1) {
|
||||
this.pageNum(12)
|
||||
} else {
|
||||
this.pageNum(15)
|
||||
}
|
||||
} else {
|
||||
if (this.number === 0) {
|
||||
this.pageNum(12)
|
||||
} else if (this.number === 1) {
|
||||
this.pageNum(16)
|
||||
} else {
|
||||
this.pageNum(20)
|
||||
}
|
||||
}
|
||||
this.$nextTick(() => {
|
||||
if (this.menuList.length && this.isMany===1) {
|
||||
let that = this
|
||||
// #ifdef H5
|
||||
that.menuHeight()
|
||||
// #endif
|
||||
// #ifndef H5
|
||||
setTimeout(() => {
|
||||
that.menuHeight()
|
||||
}, 150)
|
||||
// #endif
|
||||
}
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
bannerfun(e) {
|
||||
this.active = e.detail.current;
|
||||
},
|
||||
menuHeight() {
|
||||
let that = this;
|
||||
const query = uni.createSelectorQuery().in(this);
|
||||
query.select('#nav0').boundingClientRect(data => {
|
||||
that.navHigh = data.height;
|
||||
}).exec();
|
||||
},
|
||||
pageNum(num) {
|
||||
let menus = this.menus.filter(item=>item.status);
|
||||
let count = Math.ceil(menus.length / num);
|
||||
let goodArray = new Array();
|
||||
for (let i = 0; i < count; i++) {
|
||||
let list = menus.slice(i * num, i * num + num);
|
||||
if (list.length)
|
||||
goodArray.push({
|
||||
list: list
|
||||
});
|
||||
}
|
||||
this.$set(this, 'menuList', goodArray);
|
||||
},
|
||||
menusTap(url) {
|
||||
this.$util.navigateTo(url);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.dot {
|
||||
width: 100%;
|
||||
margin-top: 30rpx;
|
||||
|
||||
.instruct {
|
||||
width: 50rpx;
|
||||
height: 36rpx;
|
||||
line-height: 36rpx;
|
||||
background-color: rgba(0, 0, 0, 0.8);
|
||||
color: #fff;
|
||||
border-radius: 16rpx;
|
||||
font-size: 24rpx;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.dot-item {
|
||||
width: 10rpx;
|
||||
height: 10rpx;
|
||||
background: rgba(0, 0, 0, .4);
|
||||
border-radius: 50%;
|
||||
margin: 0 4px;
|
||||
|
||||
&.line_dot-item {
|
||||
width: 20rpx;
|
||||
height: 5rpx;
|
||||
border-radius: 3rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.nav {
|
||||
.item {
|
||||
width: 160rpx;
|
||||
text-align: center;
|
||||
font-size: 24rpx;
|
||||
display: inline-block;
|
||||
|
||||
.pictrue {
|
||||
width: 90rpx;
|
||||
height: 90rpx;
|
||||
margin: 0 auto;
|
||||
|
||||
image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
&.on {
|
||||
image {
|
||||
border-radius: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.menu-txt {
|
||||
margin-top: 15rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.swiper {
|
||||
z-index: 20;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
|
||||
.menu {
|
||||
display: grid;
|
||||
grid-template-rows: auto;
|
||||
width: 100%;
|
||||
padding: 0 20rpx;
|
||||
|
||||
.item {
|
||||
.pictrue {
|
||||
width: 90rpx;
|
||||
height: 90rpx;
|
||||
margin: 0 auto;
|
||||
|
||||
image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
&.on {
|
||||
image {
|
||||
border-radius: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.menu-txt {
|
||||
text-align: center;
|
||||
font-size: 12px;
|
||||
margin-top: 14rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
swiper,
|
||||
.swiper-item {
|
||||
width: 100%;
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
187
app/components/homeIndex/news.vue
Normal file
187
app/components/homeIndex/news.vue
Normal file
@@ -0,0 +1,187 @@
|
||||
<template>
|
||||
<!-- 新闻播报 -->
|
||||
<view>
|
||||
<view v-if="itemNew.length" class='news acea-row row-middle' :style="[boxStyle]">
|
||||
<view class='pictrue skeleton-rect'>
|
||||
<image :src='logoConfig'></image>
|
||||
</view>
|
||||
<view class='swiperTxt skeleton-rect'>
|
||||
<view class="acea-row row-between-wrapper" v-if="direction" @click="moreTab(itemNew[0].chiild[1].val)">
|
||||
<uniNoticeBar scrollable="true" showGetMore="true" background-color="rgba(255,255,255,0)" :color="textColor"
|
||||
moreColor="#888" :speed='50' single="true" :text="itemNew[0].chiild[0].val"></uniNoticeBar>
|
||||
<view class="iconfont icon-xiangyou"></view>
|
||||
</view>
|
||||
<swiper v-else :indicator-dots="indicatorDots" :autoplay="autoplay" interval="2500" :duration="duration"
|
||||
vertical="true" circular="true">
|
||||
<block v-for="(item,index) in itemNew" :key='index'>
|
||||
<swiper-item catchtouchmove='catchTouchMove'>
|
||||
<view @click="moreTab(item.chiild[1].val)" class='acea-row row-between-wrapper'
|
||||
hover-class='none'>
|
||||
<view class='text acea-row row-between-wrapper' :style="[txtStyle]">
|
||||
<view class='newsTitle line1' :style="{color:textColor}">
|
||||
{{item.chiild[0].val}}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</swiper-item>
|
||||
</block>
|
||||
</swiper>
|
||||
<view v-if="!direction" class='iconfont icon-xiangyou'></view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
import uniNoticeBar from '@/components/uniNoticeBar/uni-notice-bar.vue';
|
||||
export default {
|
||||
components: {
|
||||
uniNoticeBar
|
||||
},
|
||||
name: 'news',
|
||||
props: {
|
||||
dataConfig: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
},
|
||||
isSortType: {
|
||||
type: String | Number,
|
||||
default: 0
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
indicatorDots: false,
|
||||
autoplay: true,
|
||||
duration: 500,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
//文本列表
|
||||
itemNew() {
|
||||
return this.dataConfig.listConfig.list
|
||||
},
|
||||
//图标设置
|
||||
logoConfig() {
|
||||
return this.dataConfig.logoConfig.url
|
||||
},
|
||||
//文本滚动方向
|
||||
direction() {
|
||||
return this.dataConfig.directionConfig.tabVal
|
||||
},
|
||||
//最外层盒子的样式
|
||||
boxStyle() {
|
||||
return {
|
||||
borderRadius: this.dataConfig.bgStyle.val * 2 + 'rpx',
|
||||
background: `linear-gradient(${this.dataConfig.bgColor.color[0].item}, ${this.dataConfig.bgColor.color[1].item})`,
|
||||
margin: this.dataConfig.mbConfig.val * 2 + 'rpx' + ' ' + this.dataConfig.lrConfig.val * 2 + 'rpx' +
|
||||
' ' + 0,
|
||||
padding: this.dataConfig.upConfig.val * 2 + 'rpx' + ' ' + '20rpx' + ' ' + this.dataConfig.downConfig
|
||||
.val * 2 + 'rpx',
|
||||
color: this.dataConfig.textColor.color[0].item
|
||||
}
|
||||
},
|
||||
//文字位置
|
||||
txtStyle() {
|
||||
let txtStyle = this.dataConfig.textPosition.tabVal;
|
||||
if (txtStyle == 0) {
|
||||
return {
|
||||
'text-align': 'left'
|
||||
}
|
||||
} else if (txtStyle == 1) {
|
||||
return {
|
||||
'text-align': 'center'
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
'text-align': 'right'
|
||||
}
|
||||
}
|
||||
},
|
||||
//文字颜色
|
||||
textColor() {
|
||||
return this.dataConfig.textColor.color[0].item
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
moreTab(url) {
|
||||
this.$util.navigateTo(url);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.news {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: nowrap;
|
||||
box-shadow: 0 10rpx 30rpx #f5f5f5;
|
||||
}
|
||||
|
||||
.news .pictrue {
|
||||
width: 130rpx;
|
||||
height: 36rpx;
|
||||
border-right: 1rpx solid #ddd;
|
||||
padding-right: 23rpx;
|
||||
box-sizing: content-box;
|
||||
}
|
||||
|
||||
.news .pictrue image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.news .swiperTxt {
|
||||
width: 536rpx;
|
||||
height: 78rpx;
|
||||
line-height: 78rpx;
|
||||
overflow: hidden;
|
||||
margin-left: 22rpx;
|
||||
position: relative;
|
||||
.icon-xiangyou{
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.news .swiperTxt .text {
|
||||
width: 89%;
|
||||
}
|
||||
|
||||
.news .swiperTxt .text .label {
|
||||
font-size: 20rpx;
|
||||
color: #ff4c48;
|
||||
width: 64rpx;
|
||||
height: 30rpx;
|
||||
border-radius: 40rpx;
|
||||
text-align: center;
|
||||
line-height: 28rpx;
|
||||
border: 2rpx solid #ff4947;
|
||||
}
|
||||
|
||||
.news .swiperTxt .text .newsTitle {
|
||||
width: 100%;
|
||||
font-size: 24rpx;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.news .swiperTxt .iconfont {
|
||||
font-size: 28rpx;
|
||||
color: #888;
|
||||
}
|
||||
|
||||
.news .swiperTxt swiper {
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
214
app/components/homeIndex/pageFoot.vue
Normal file
214
app/components/homeIndex/pageFoot.vue
Normal file
@@ -0,0 +1,214 @@
|
||||
<template>
|
||||
<!-- 底部导航 -->
|
||||
<view :data-theme="theme">
|
||||
<view v-if="bottomNavigationList.length">
|
||||
<view class="page-footer" id="target" :style="[isSmallPage?boxStyle:'']">
|
||||
<view :style="[bgColor]" class="acea-row row-middle row-around bg-box">
|
||||
<view class="foot-item" v-for="(item,index) in bottomNavigationList" :key="index"
|
||||
@click="goRouter(item)">
|
||||
<block v-if="item.link.split('?')[0] == activeRouter">
|
||||
<image :src="item.checked"></image>
|
||||
<view v-if="isSmallPage" class="txtchecked" :style="[checkColor]">{{item.name}}</view>
|
||||
<view v-else class="txt">{{item.name}}</view>
|
||||
</block>
|
||||
<block v-else>
|
||||
<image :src="item.unchecked"></image>
|
||||
<view class="unchecked" :style="[isSmallPage?fontColor:'']">{{item.name}}</view>
|
||||
</block>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
mapState,
|
||||
mapGetters
|
||||
} from "vuex"
|
||||
import {
|
||||
getBottomNavigationApi
|
||||
} from '@/api/api.js';
|
||||
let app = getApp();
|
||||
export default {
|
||||
name: 'pageFooter',
|
||||
props: {
|
||||
dataConfig: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
},
|
||||
isSmallPage: {
|
||||
type: Boolean,
|
||||
default: () => false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
//外部盒子
|
||||
boxStyle() {
|
||||
if (this.dataConfig) {
|
||||
return {
|
||||
borderRadius: this.dataConfig.bgStyle.val ? this.dataConfig.bgStyle.val + 'px' : '0',
|
||||
padding: '0' + ' ' + this.dataConfig.lrConfig.val + 'px' + ' ' + 0
|
||||
}
|
||||
}
|
||||
},
|
||||
bgColor() {
|
||||
return {
|
||||
background: `linear-gradient(${this.dataConfig.bgColor.color[0].item}, ${this.dataConfig.bgColor.color[1].item})`,
|
||||
}
|
||||
},
|
||||
//标签文字颜色
|
||||
fontColor() {
|
||||
if (this.dataConfig) {
|
||||
return {
|
||||
color: this.dataConfig.fontColor.color[0].item
|
||||
};
|
||||
}
|
||||
|
||||
},
|
||||
//选中颜色
|
||||
checkColor() {
|
||||
if (this.dataConfig) {
|
||||
return {
|
||||
color: this.dataConfig.themeStyleConfig.tabVal ? this.dataConfig.checkColor.color[0].item : this
|
||||
.themeColor
|
||||
};
|
||||
}
|
||||
},
|
||||
},
|
||||
created() {
|
||||
let routes = getCurrentPages(); //获取当前打开过的页面路由数组
|
||||
let curRoute = routes[routes.length - 1].route //获取当前页面路由
|
||||
this.activeRouter = '/' + curRoute;
|
||||
},
|
||||
mounted() {
|
||||
if (this.activeRouter === '/pages/activity/small_page/index') {
|
||||
this.bottomNavigationList = this.dataConfig.menuList.list;
|
||||
} else {
|
||||
this.navigationInfo();
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
theme: app.globalData.theme,
|
||||
isCustom: '',
|
||||
bottomNavigationList: [],
|
||||
activeRouter: '',
|
||||
themeColor: this.$options.filters.filterTheme(app.globalData.theme)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
navigationInfo() {
|
||||
getBottomNavigationApi().then(res => {
|
||||
let data = res.data;
|
||||
this.isCustom = data.isCustom; //是否使用自定义导航,1使用,0不使用
|
||||
this.$store.commit('BottomNavigationIsCustom', this.isCustom == 1 ? true : false);
|
||||
if (data.isCustom == 1) {
|
||||
uni.hideTabBar()
|
||||
this.bottomNavigationList = data.bottomNavigationList;
|
||||
} else {
|
||||
uni.showTabBar();
|
||||
}
|
||||
})
|
||||
},
|
||||
goRouter(item) {
|
||||
var pages = getCurrentPages();
|
||||
var page = (pages[pages.length - 1]).$page.fullPath;
|
||||
if (item.link == page) return
|
||||
if (['/pages/index/index', '/pages/order_addcart/order_addcart',
|
||||
'/pages/user/index', '/pages/discover_index/index', '/pages/goods_cate/goods_cate'
|
||||
].indexOf(item.link) > -1) {
|
||||
uni.switchTab({
|
||||
url: item.link,
|
||||
fail(err) {
|
||||
uni.redirectTo({
|
||||
url: item.link
|
||||
})
|
||||
}
|
||||
})
|
||||
} else {
|
||||
uni.navigateTo({
|
||||
url: item.link
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.overlay {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: calc(98rpx+ constant(safe-area-inset-bottom)); ///兼容 IOS<11.2/
|
||||
height: calc(98rpx + env(safe-area-inset-bottom)); ///兼容 IOS>11.2/
|
||||
}
|
||||
|
||||
.unchecked {
|
||||
color: #333;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
|
||||
.page-footer {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
z-index: 999999;
|
||||
width: 100%;
|
||||
height: calc(98rpx+ constant(safe-area-inset-bottom)); ///兼容 IOS<11.2/
|
||||
height: calc(98rpx + env(safe-area-inset-bottom)); ///兼容 IOS>11.2/
|
||||
box-sizing: border-box;
|
||||
border-top: solid 1rpx #F3F3F3;
|
||||
background-color: #fff;
|
||||
box-shadow: 0px 0px 17rpx 1rpx rgba(206, 206, 206, 0.32);
|
||||
padding-bottom: constant(safe-area-inset-bottom); ///兼容 IOS<11.2/
|
||||
padding-bottom: env(safe-area-inset-bottom); ///兼容 IOS>11.2/
|
||||
|
||||
.foot-item {
|
||||
display: flex;
|
||||
width: max-content;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
position: relative;
|
||||
|
||||
.count-num {
|
||||
position: absolute;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
top: 0rpx;
|
||||
right: -15rpx;
|
||||
color: #fff;
|
||||
font-size: 20rpx;
|
||||
background-color: #FD502F;
|
||||
border-radius: 50%;
|
||||
padding: 4rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.bg-box {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.foot-item image {
|
||||
height: 50rpx;
|
||||
width: 50rpx;
|
||||
text-align: center;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.txtchecked {
|
||||
font-size: 24rpx;
|
||||
}
|
||||
|
||||
.foot-item .txt {
|
||||
font-size: 24rpx;
|
||||
@include main-color(theme);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
194
app/components/homeIndex/pictureCube.vue
Normal file
194
app/components/homeIndex/pictureCube.vue
Normal file
@@ -0,0 +1,194 @@
|
||||
<template>
|
||||
<!-- 图片魔方 -->
|
||||
<view class="pictureCube skeleton-rect" :style="[boxStyle]" v-if="picList.length&&(imageH>0||style==3)">
|
||||
<view class="grid_box" :style="[gridColumns]" v-if="[0,1,2,4,5].includes(style)">
|
||||
<image class="center" v-for="(item,index) in picList" :key="index" @click="goDetail(item)" :src="item.image"
|
||||
:mode="item.radioVal === '0' ? 'scaleToFill' : item.radioVal === '1' ? 'aspectFit' : 'aspectFill'"
|
||||
:style="[imageStyle]"></image>
|
||||
</view>
|
||||
<view class="advertItem04" v-if="style==3" :style="[widthStyle]">
|
||||
<view class="item" @click="goDetail(picList[0])">
|
||||
<image class="img-left center" :src="picList[0].image" :style="[radiusStyle]"
|
||||
:mode="picList[0].radioVal === '0' ? 'scaleToFill' : picList[0].radioVal === '1' ? 'aspectFit' : 'aspectFill'">
|
||||
</image>
|
||||
</view>
|
||||
<view class="item item-right" :style="[gapStyle]">
|
||||
<view class="pic" @click="goDetail(picList[1])">
|
||||
<image class="img-right center" :src="picList[1].image" :style="[radiusStyle]"
|
||||
:mode="picList[1].radioVal === '0' ? 'scaleToFill' : picList[1].radioVal === '1' ? 'aspectFit' : 'aspectFill'">
|
||||
</image>
|
||||
</view>
|
||||
<view class="pic" @click="goDetail(picList[2])">
|
||||
<image class="img-right center" :src="picList[2].image" :style="[radiusStyle]"
|
||||
:mode="picList[2].radioVal === '0' ? 'scaleToFill' : picList[2].radioVal === '1' ? 'aspectFit' : 'aspectFill'">
|
||||
</image>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
export default {
|
||||
name: 'pictureCube',
|
||||
props: {
|
||||
dataConfig: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
picList: this.dataConfig.picStyle.picList,
|
||||
style: this.dataConfig.tabConfig.tabVal,
|
||||
prConfig: this.dataConfig.lrConfig.val,
|
||||
widthC: '',
|
||||
imageH: 0,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
//最外层盒子的样式
|
||||
boxStyle() {
|
||||
return {
|
||||
borderRadius: this.dataConfig.bgStyle.val * 2 + 'rpx',
|
||||
background: `linear-gradient(${this.dataConfig.bgColor.color[0].item}, ${this.dataConfig.bgColor.color[1].item})`,
|
||||
margin: this.dataConfig.mbConfig.val * 2 + 'rpx' + ' ' + this.dataConfig.lrConfig.val * 2 + 'rpx' +
|
||||
' ' + 0,
|
||||
padding: this.dataConfig.upConfig.val * 2 + 'rpx' + ' ' + '0' + ' ' + this.dataConfig.downConfig.val *
|
||||
2 + 'rpx'
|
||||
}
|
||||
},
|
||||
imageStyle() {
|
||||
return {
|
||||
height: this.imageH + 'rpx',
|
||||
'border-radius': this.dataConfig.contantStyle.val ? this.dataConfig.contantStyle.val + 'px' :
|
||||
'0'
|
||||
}
|
||||
},
|
||||
widthStyle(){
|
||||
return {width :750-this.dataConfig.lrConfig.val * 4 + 'rpx',gap: 2 * this.dataConfig.spaceConfig.val + 'rpx'}
|
||||
},
|
||||
radiusStyle(){
|
||||
return {'border-radius': this.dataConfig.contantStyle.val ? this.dataConfig.contantStyle.val + 'px' :
|
||||
'0'}
|
||||
},
|
||||
gapStyle(){
|
||||
return{gap: 2 * this.dataConfig.spaceConfig.val + 'rpx',}
|
||||
},
|
||||
//图片魔方排版
|
||||
gridColumns() {
|
||||
if ([1, 5].includes(this.dataConfig.tabConfig.tabVal)) {
|
||||
return {
|
||||
gridTemplateColumns: 'repeat(2, 1fr)',
|
||||
gap: 2 * this.dataConfig.spaceConfig.val + 'rpx',
|
||||
}
|
||||
} else if (this.dataConfig.tabConfig.tabVal == 0) {
|
||||
return {
|
||||
gridTemplateColumns: 'repeat(1, 1fr)',
|
||||
gap: 2 * this.dataConfig.spaceConfig.val + 'rpx',
|
||||
}
|
||||
} else if (this.dataConfig.tabConfig.tabVal == 2) {
|
||||
return {
|
||||
gridTemplateColumns: 'repeat(3, 1fr)',
|
||||
gap: 2 * this.dataConfig.spaceConfig.val + 'rpx',
|
||||
}
|
||||
} else if (this.dataConfig.tabConfig.tabVal == 4) {
|
||||
return {
|
||||
gridTemplateColumns: 'repeat(4, 1fr)',
|
||||
gap: 2 * this.dataConfig.spaceConfig.val + 'rpx',
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
if (this.picList.length) {
|
||||
let that = this;
|
||||
this.$nextTick((e) => {
|
||||
// 宽度
|
||||
if (this.style == 0) {
|
||||
this.widthC = 750
|
||||
} else if (this.style == 1) {
|
||||
this.widthC = 375
|
||||
} else if (this.style == 2) {
|
||||
this.widthC = 250
|
||||
} else if (this.style == 4) {
|
||||
this.widthC = 187.5
|
||||
}
|
||||
//高度计算
|
||||
if (this.style == 5) {
|
||||
that.$set(that, 'imageH', 187.5);
|
||||
} else {
|
||||
let maxHeight = 0
|
||||
this.picList.forEach((val, index) => {
|
||||
let height = val.height * ((that.widthC - that.prConfig *
|
||||
2) / val
|
||||
.width)
|
||||
if (height > maxHeight) {
|
||||
maxHeight = height
|
||||
}
|
||||
})
|
||||
that.$set(that, 'imageH', maxHeight);
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
goDetail(item) {
|
||||
this.$util.navigateTo(item.link);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.grid_box {
|
||||
display: grid;
|
||||
grid-template-rows: auto;
|
||||
|
||||
image {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.pictureCube {
|
||||
uni-image {
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.advertItem04 {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
.item-right{
|
||||
display: grid;
|
||||
grid-template-columns: repeat(1, 1fr);
|
||||
height: 375rpx;
|
||||
}
|
||||
.item{
|
||||
height: 375rpx;
|
||||
}
|
||||
.img-left{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.img-right{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
.center {
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
73
app/components/homeIndex/richTextEditor.vue
Normal file
73
app/components/homeIndex/richTextEditor.vue
Normal file
@@ -0,0 +1,73 @@
|
||||
<template>
|
||||
<!-- 富文本 -->
|
||||
<view v-if="description" :style="[boxStyle]">
|
||||
<view class="rich_text">
|
||||
<!-- #ifdef MP || APP-PLUS -->
|
||||
<mp-html :content="description" :tag-style="tagStyle" selectable="true" show-img-menu="true"/>
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef H5 -->
|
||||
<view v-html="description"></view>
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
import mpHtml from "@/uni_modules/mp-html/components/mp-html/mp-html.vue";
|
||||
export default {
|
||||
name: 'richText',
|
||||
props: {
|
||||
dataConfig: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
},
|
||||
},
|
||||
data(){
|
||||
return{
|
||||
tagStyle: {
|
||||
img: 'width:100%;display:block;',
|
||||
table: 'width:100%',
|
||||
video: 'width:100%'
|
||||
},
|
||||
}
|
||||
},
|
||||
components:{
|
||||
mpHtml
|
||||
},
|
||||
computed: {
|
||||
//最外层盒子的样式
|
||||
boxStyle() {
|
||||
return {
|
||||
borderRadius: this.dataConfig.bgStyle.val * 2 + 'rpx',
|
||||
background: `linear-gradient(${this.dataConfig.bgColor.color[0].item}, ${this.dataConfig.bgColor.color[1].item})`,
|
||||
margin: this.dataConfig.mbConfig.val * 2 + 'rpx' + ' ' + this.dataConfig.lrConfig.val * 2 + 'rpx' +
|
||||
' ' + 0,
|
||||
}
|
||||
},
|
||||
//富文本内容
|
||||
description() {
|
||||
return this.dataConfig.richText.val.replace(/<video/g, "<video style='width:100%'").replace(/\<img/gi, '<img style="max-width:100%;height:auto" ')
|
||||
.replace(/style="text-wrap: wrap;"/gi, '');
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.rich_text {
|
||||
padding: 10px;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
372
app/components/homeIndex/seckill.vue
Normal file
372
app/components/homeIndex/seckill.vue
Normal file
@@ -0,0 +1,372 @@
|
||||
<template>
|
||||
<!-- 秒杀 -->
|
||||
<view v-if="spikeList.length">
|
||||
<view class="seckill" :style="[boxStyle]" >
|
||||
<view class="bg_box" :style="[boxBgStyle]"></view>
|
||||
<view class="title acea-row row-between-wrapper">
|
||||
<view class="acea-row row-middle">
|
||||
<view class="pictrue skeleton-rect">
|
||||
<image :src="logoUrl"></image>
|
||||
</view>
|
||||
<view class="lines"></view>
|
||||
<view class="point skeleton-rect" :style="[titleColor]">{{titleText}}</view>
|
||||
</view>
|
||||
<view class="more acea-row row-center-wrapper skeleton-rect" @click="toSeckillList()">
|
||||
GO<text class="iconfont icon-you"></text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="conter" v-if="listStyle == 0">
|
||||
<scroll-view scroll-x="true" style="white-space: nowrap; vertical-align: middle;"
|
||||
show-scrollbar="false">
|
||||
<view class="itemCon" :style="[{'margin-right':itemStyle}]" v-for="(item, index) in spikeList"
|
||||
:key="index" @click="toSeckillDetail(item.id)">
|
||||
<view class="item">
|
||||
<view class="pictrue skeleton-rect">
|
||||
<easy-loadimage :image-src="item.image" :radius="dataConfig.contentStyle.val">
|
||||
</easy-loadimage>
|
||||
</view>
|
||||
<view v-show="nameShow" :style="[nameColor]" class="name line1 skeleton-rect">{{item.title}}</view>
|
||||
<view v-show="priceShow" :style="[priceColor]" class="x_money semiBold line1 skeleton-rect">¥<text
|
||||
class="num semiBold">{{item.price}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
<view class="conter_y" :style="[{'grid-gap':itemStyle}]" v-if="listStyle == 1">
|
||||
<view class="item" v-for="(item, index) in spikeList" :key="index" @click="toSeckillDetail(item.id)">
|
||||
<view class="pictrue">
|
||||
<easy-loadimage :image-src="item.image" :radius="dataConfig.contentStyle.val">
|
||||
</easy-loadimage>
|
||||
</view>
|
||||
<view class="text-info acea-row row-column row-between">
|
||||
<view v-show="nameShow">
|
||||
<view :style="[nameColor]" class="title line2">{{ item.title }}</view>
|
||||
</view>
|
||||
<view v-show="priceShow" :style="[priceColor]" class="price semiBold">
|
||||
<view>
|
||||
<text class="semiBold">¥</text>
|
||||
<text class="semiBold">{{ item.price }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
let app = getApp();
|
||||
import {
|
||||
getSeckillIndexApi
|
||||
} from '@/api/activity.js';
|
||||
import easyLoadimage from '@/components/base/easy-loadimage.vue';
|
||||
export default {
|
||||
name: 'homeSeckill',
|
||||
props: {
|
||||
dataConfig: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
},
|
||||
},
|
||||
components: {
|
||||
easyLoadimage
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
urlDomain: this.$Cache.get("imgHost"),
|
||||
spikeList: [], // 秒杀
|
||||
datatime: 0,
|
||||
status: 0,
|
||||
themeColor:this.$options.filters.filterTheme(app.globalData.theme)
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
//秒杀样式
|
||||
listStyle() {
|
||||
return this.dataConfig.tabConfig.tabVal
|
||||
},
|
||||
//最外层盒子的背景图片
|
||||
boxBgStyle() {
|
||||
return {
|
||||
borderRadius: this.dataConfig.bgStyle.val * 2 + 'rpx' + ' ' + this.dataConfig.bgStyle.val * 2 + 'rpx' +
|
||||
' ' + 0 + ' ' + 0,
|
||||
backgroundImage: `url(${this.urlDomain}crmebimage/presets/seckill_bg_pic.png),linear-gradient(${this.dataConfig.bgColor.color[0].item}, ${this.dataConfig.bgColor.color[1].item})`
|
||||
}
|
||||
},
|
||||
//最外层盒子的样式
|
||||
boxStyle() {
|
||||
return {
|
||||
borderRadius: this.dataConfig.bgStyle.val * 2 + 'rpx',
|
||||
margin: this.dataConfig.mbConfig.val * 2 + 'rpx' + ' ' + this.dataConfig.lrConfig.val * 2 + 'rpx' +
|
||||
' ' + 0,
|
||||
padding: this.dataConfig.upConfig.val * 2 + 'rpx' + ' ' + '24rpx' + ' ' + this.dataConfig.downConfig
|
||||
.val * 2 + 'rpx'
|
||||
}
|
||||
},
|
||||
//图片圆角
|
||||
itemStyle() {
|
||||
return this.dataConfig.contentConfig.val * 2 + 'rpx'
|
||||
},
|
||||
//标题图片
|
||||
logoUrl() {
|
||||
return this.dataConfig.logoConfig.url
|
||||
},
|
||||
//标题
|
||||
titleText() {
|
||||
return this.dataConfig.titleConfig.val
|
||||
},
|
||||
//标题颜色
|
||||
titleColor() {
|
||||
return {
|
||||
color: this.dataConfig.titleColor.color[0].item
|
||||
}
|
||||
},
|
||||
//名称颜色
|
||||
nameColor() {
|
||||
return {
|
||||
color: this.dataConfig.nameColor.color[0].item
|
||||
};
|
||||
},
|
||||
//价格颜色
|
||||
priceColor() {
|
||||
return {
|
||||
color: this.dataConfig.themeStyleConfig.tabVal?this.dataConfig.priceColor.color[0].item:this.themeColor
|
||||
};
|
||||
},
|
||||
//商品名称
|
||||
nameShow() {
|
||||
if (this.dataConfig.typeConfig.activeValue.indexOf(0) !== -1) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
//商品价格
|
||||
priceShow() {
|
||||
if (this.dataConfig.typeConfig.activeValue.indexOf(1) !== -1) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.getSeckillIndex();
|
||||
},
|
||||
methods: {
|
||||
getSeckillIndex() {
|
||||
getSeckillIndexApi().then(({
|
||||
data
|
||||
}) => {
|
||||
this.spikeList = [];
|
||||
this.spikeList = data ? data.productList : [];
|
||||
})
|
||||
},
|
||||
toSeckillList() {
|
||||
this.$util.navigateTo(this.dataConfig.linkConfig.val)
|
||||
},
|
||||
toSeckillDetail(id){
|
||||
uni.navigateTo({
|
||||
url:`/pages/activity/goods_seckill_details/index?id=${id}`
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.seckill {
|
||||
width: auto;
|
||||
background: #fff;
|
||||
border-radius: 14rpx;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
|
||||
.bg_box {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 256rpx;
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
border-radius: 14rpx 14rpx 0 0;
|
||||
}
|
||||
|
||||
.title {
|
||||
.pictrue {
|
||||
width: 124rpx;
|
||||
height: 32rpx;
|
||||
z-index: 9;
|
||||
|
||||
image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.lines {
|
||||
width: 1rpx;
|
||||
height: 24rpx;
|
||||
background-color: #fff;
|
||||
opacity: 0.6;
|
||||
margin-left: 16rpx;
|
||||
}
|
||||
|
||||
.point {
|
||||
font-size: 26rpx;
|
||||
color: #fff;
|
||||
margin-left: 21rpx;
|
||||
margin-right: 4rpx;
|
||||
z-index: 9;
|
||||
}
|
||||
|
||||
.styleAll {
|
||||
width: 35rpx;
|
||||
height: 35rpx;
|
||||
background-color: #2F2F2F;
|
||||
border-radius: 6rpx;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.more {
|
||||
width: 86rpx;
|
||||
height: 40rpx;
|
||||
background: linear-gradient(142deg, #FFE9CE 0%, #FFD6A7 100%);
|
||||
opacity: 1;
|
||||
border-radius: 18px;
|
||||
font-size: 22rpx;
|
||||
color: #FE960F;
|
||||
padding-left: 8rpx;
|
||||
font-weight: 800;
|
||||
z-index: 9;
|
||||
|
||||
.iconfont {
|
||||
font-size: 21rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.conter {
|
||||
border-radius: 12px;
|
||||
margin-top: 30rpx;
|
||||
|
||||
.itemCon {
|
||||
display: inline-block;
|
||||
width: 186rpx;
|
||||
|
||||
.item {
|
||||
width: 100%;
|
||||
|
||||
.pictrue {
|
||||
width: 100%;
|
||||
height: 186rpx;
|
||||
overflow: hidden;
|
||||
|
||||
image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 6rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.name {
|
||||
font-size: 26rpx;
|
||||
color: #333;
|
||||
margin-top: 8rpx;
|
||||
}
|
||||
|
||||
.y_money {
|
||||
font-size: 24rpx;
|
||||
color: #999999;
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
.x_money {
|
||||
font-size: 28rpx;
|
||||
height: 100%;
|
||||
font-weight: bold;
|
||||
margin-top: 4rpx;
|
||||
|
||||
.num {
|
||||
font-size: 28rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.money {
|
||||
margin-top: 14rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.conter_y {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(1, 1fr);
|
||||
grid-template-rows: auto;
|
||||
width: 100%;
|
||||
margin-top: 30rpx;
|
||||
|
||||
.item {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
z-index: 9;
|
||||
|
||||
.pictrue {
|
||||
width: 108px;
|
||||
height: 108px;
|
||||
|
||||
image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.text-info {
|
||||
z-index: 9;
|
||||
margin-left: 20rpx;
|
||||
flex: 1;
|
||||
|
||||
.title {
|
||||
width: 100%;
|
||||
height: 80rpx;
|
||||
line-height: 40rpx;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.old-price {
|
||||
font-weight: normal;
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.price {
|
||||
font-size: 36rpx;
|
||||
font-weight: 550;
|
||||
|
||||
text {
|
||||
padding-bottom: 4rpx;
|
||||
font-size: 26rpx;
|
||||
font-weight: normal;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.semiBold{
|
||||
font-size: 36rpx !important;
|
||||
}
|
||||
</style>
|
||||
289
app/components/homeIndex/swiperBg.vue
Normal file
289
app/components/homeIndex/swiperBg.vue
Normal file
@@ -0,0 +1,289 @@
|
||||
<template>
|
||||
<!-- 轮播图 -->
|
||||
<view class="swiperBg" :style="[boxStyle]">
|
||||
<view class="swiper page_swiper" :class="docConfig" v-if="imgUrls.length">
|
||||
<swiper :autoplay="true" :circular="true" :interval="3000" :duration="500"
|
||||
:indicator-active-color="docColor" :current="swiperCur" :previous-margin="swiperType==0?'40rpx':''" :next-margin="swiperType==0?'40rpx':''"
|
||||
@change="swiperChange">
|
||||
<block v-for="(item,index) in imgUrls" :key="index">
|
||||
<swiper-item :class="{ active: index == swiperCur }">
|
||||
<view @click="goDetail(item)" class='slide-navigator acea-row row-between-wrapper tui-skeleton-rect'>
|
||||
<image :src="item.img" mode="aspectFill" :style="[imgStyle]" class="slide-image aa"></image>
|
||||
</view>
|
||||
</swiper-item>
|
||||
</block>
|
||||
</swiper>
|
||||
<view v-if="docType === 0" class="dots" :style="[dotStyle]">
|
||||
<block v-for="(item,index) in imgUrls" :key="index">
|
||||
<view class="dot-item"
|
||||
:style="{'background-color': swiperCur === index ? (dataConfig.themeStyleConfig.tabVal?dataConfig.docColor.color[0].item:themeColor) : ''}">
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
<view v-if="docType === 1" class="dots" :style="[dotStyle]">
|
||||
<block v-for="(item,index) in imgUrls" :key="index">
|
||||
<view class="dot"
|
||||
:style="{'background-color': swiperCur === index ? (dataConfig.themeStyleConfig.tabVal?dataConfig.docColor.color[0].item:themeColor) : ''}">
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
import {
|
||||
navigatoPage
|
||||
} from "@/utils/index"
|
||||
let app = getApp();
|
||||
export default {
|
||||
name: 'swiperBg',
|
||||
props: {
|
||||
dataConfig: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
},
|
||||
merId: {}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
indicatorDots: false,
|
||||
imgUrls: [], //图片轮播数据
|
||||
txtStyle: this.dataConfig.txtStyle.type, //指示器位置
|
||||
imageH: 310,
|
||||
swiperCur: 0,
|
||||
themeColor:this.$options.filters.filterTheme(app.globalData.theme)
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
imageH(nVal, oVal) {
|
||||
let self = this
|
||||
this.imageH = nVal
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
//指示器样式
|
||||
dotStyle() {
|
||||
return {
|
||||
padding: '0 50rpx',
|
||||
justifyContent: this.dataConfig.txtStyle.tabVal === 1 ? 'center' : this.dataConfig.txtStyle
|
||||
.tabVal === 2 ? 'flex-end' : 'flex-start'
|
||||
}
|
||||
},
|
||||
//指示器类型,0圆,1直,2无
|
||||
docType() {
|
||||
return this.dataConfig.docConfig.tabVal
|
||||
},
|
||||
//轮播图样式
|
||||
swiperType(){
|
||||
return this.dataConfig.swiperStyleConfig.tabVal
|
||||
},
|
||||
//最外层盒子的样式
|
||||
boxStyle() {
|
||||
return {
|
||||
borderRadius: this.dataConfig.bgStyle.val * 2 + 'rpx',
|
||||
background: `linear-gradient(${this.dataConfig.bgColor.color[0].item}, ${this.dataConfig.bgColor.color[1].item})`,
|
||||
margin: this.dataConfig.mbConfig.val * 2 + 'rpx' + ' ' + this.dataConfig.lrConfig.val * 2 + 'rpx' +
|
||||
' ' + 0,
|
||||
padding: this.dataConfig.upConfig.val * 2 + 'rpx' + ' ' + '20rpx' + ' ' + this.dataConfig.downConfig.val *
|
||||
2 + 'rpx'
|
||||
}
|
||||
},
|
||||
//指示器颜色
|
||||
docColor() {
|
||||
return this.dataConfig.docColor.color[0].item + '!important'
|
||||
},
|
||||
//指示器样式
|
||||
docConfig() {
|
||||
if (this.dataConfig.docConfig.tabVal == 1) {
|
||||
return 'square'
|
||||
} else if (this.dataConfig.docConfig.tabVal == 2) {
|
||||
return 'nodoc'
|
||||
} else {
|
||||
return 'circular'
|
||||
}
|
||||
},
|
||||
//内容圆角
|
||||
imgStyle() {
|
||||
return {
|
||||
"border-radius": this.dataConfig.contentStyle.val * 2 + 'rpx'
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.imgUrls = this.dataConfig.swiperConfig.list
|
||||
},
|
||||
mounted() {
|
||||
let that = this;
|
||||
this.$nextTick(function() {
|
||||
uni.getImageInfo({
|
||||
src: that.setDomain(that.imgUrls[0].img),
|
||||
success: function(res) {
|
||||
that.$set(that, 'imageH', res.height);
|
||||
},
|
||||
fail: function(error) {
|
||||
that.$set(that, 'imageH', 310);
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
//替换安全域名
|
||||
setDomain: function(url) {
|
||||
url = url ? url.toString() : '';
|
||||
//本地调试打开,生产请注销
|
||||
if (url.indexOf("https://") > -1) return url;
|
||||
else return url.replace('http://', 'https://');
|
||||
},
|
||||
swiperChange(e) {
|
||||
let {
|
||||
current,
|
||||
source
|
||||
} = e.detail;
|
||||
if (source === 'autoplay' || source === 'touch') {
|
||||
this.swiperCur = e.detail.current;
|
||||
}
|
||||
},
|
||||
goDetail(url) {
|
||||
let path = url.info[1].value
|
||||
this.$util.navigateTo(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
/*用来包裹所有的小圆点 */
|
||||
.dots {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
position: absolute;
|
||||
bottom: 24rpx;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
}
|
||||
.dot-item {
|
||||
width: 10rpx;
|
||||
height: 10rpx;
|
||||
background-color: rgba(255, 255, 255, .4);
|
||||
border-radius: 50%;
|
||||
margin: 0 6rpx;
|
||||
}
|
||||
|
||||
/*未选中时的小圆点样式 */
|
||||
.dot {
|
||||
width: 16rpx;
|
||||
height: 6rpx;
|
||||
border-radius: 6rpx;
|
||||
margin-right: 6rpx;
|
||||
background-color: rgba(255, 255, 255, .4);
|
||||
}
|
||||
.swiperBg {
|
||||
position: relative;
|
||||
background: #fff;
|
||||
z-index: 1;
|
||||
|
||||
.colorBg {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
height: 130rpx;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.page_swiper {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
margin: 0 auto;
|
||||
border-radius: 10rpx;
|
||||
overflow-x: hidden;
|
||||
/* #ifdef MP */
|
||||
z-index: 20;
|
||||
|
||||
/* #endif */
|
||||
/* 设置圆角 */
|
||||
&.fillet {
|
||||
|
||||
.swiper-item,
|
||||
image,
|
||||
.acea-row.row-between-wrapper {
|
||||
border-radius: 10rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.swiper-item,
|
||||
image,
|
||||
.acea-row.row-between-wrapper {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
swiper {
|
||||
width: 100%;
|
||||
display: block;
|
||||
}
|
||||
|
||||
image {
|
||||
transform: scale(0.93);
|
||||
transition: all 0.6s ease;
|
||||
}
|
||||
|
||||
swiper-item.active {
|
||||
image {
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
// 圆形指示点
|
||||
&.circular {
|
||||
/deep/.uni-swiper-dot {
|
||||
width: 10rpx;
|
||||
height: 10rpx;
|
||||
}
|
||||
}
|
||||
|
||||
// 方形指示点
|
||||
&.square {
|
||||
/deep/.uni-swiper-dot {
|
||||
width: 20rpx;
|
||||
height: 5rpx;
|
||||
border-radius: 3rpx;
|
||||
}
|
||||
}
|
||||
|
||||
&.nodoc {
|
||||
/deep/.uni-swiper-dot {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/deep/.dot0 .uni-swiper-dots-horizontal {
|
||||
left: 10%;
|
||||
}
|
||||
|
||||
/deep/.dot1 .uni-swiper-dots-horizontal {
|
||||
left: 50%;
|
||||
}
|
||||
|
||||
/deep/.dot2 .uni-swiper-dots-horizontal {
|
||||
left: 90%;
|
||||
}
|
||||
|
||||
.item-img image {
|
||||
display: block;
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
166
app/components/homeIndex/title.vue
Normal file
166
app/components/homeIndex/title.vue
Normal file
@@ -0,0 +1,166 @@
|
||||
<template>
|
||||
<!-- 标题 -->
|
||||
<view class="title-box acea-row row-between row-middle" :style="[...boxStyle]" @click="goPage">
|
||||
<view class="acea-row row-middle" >
|
||||
<view :style="[...titleStyle]">{{ titleTxt }}</view>
|
||||
<view class="ml6" :style="[...titleFuStyle]">{{ titleFuTxt }}</view>
|
||||
</view>
|
||||
<view v-if="!selectShow" :style="[...titleRightStyle]">{{ titleRightTxt }}<text :style="[...titleRightStyle]" class="iconfont icon-xiangyou"></text></view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
export default {
|
||||
name: 'titles',
|
||||
props: {
|
||||
dataConfig: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
//最外层盒子的样式
|
||||
boxStyle() {
|
||||
return [{
|
||||
'border-radius': 2*this.dataConfig.bgTopStyle.val +
|
||||
'rpx' +
|
||||
' ' +
|
||||
2*this.dataConfig.bgTopStyle.val +
|
||||
'rpx' +
|
||||
' ' +
|
||||
2*this.dataConfig.bgDownStyle.val +
|
||||
'rpx' +
|
||||
' ' +
|
||||
2*this.dataConfig.bgDownStyle.val +
|
||||
'rpx',
|
||||
},
|
||||
{
|
||||
'background-image': this.selectStyle ?
|
||||
`linear-gradient(to right,${this.dataConfig.bgColor.color[0].item}, ${this.dataConfig.bgColor.color[1].item})` :
|
||||
`url(${this.bgImgUrl})`,
|
||||
},
|
||||
{
|
||||
margin: 2*this.dataConfig.mbConfig.val + 'rpx' + ' ' + 2*this.dataConfig.lrConfig.val + 'rpx' + ' ' +
|
||||
0
|
||||
},
|
||||
{
|
||||
padding: 2*this.dataConfig.upConfig.val + 'rpx' + ' ' + '20rpx' + ' ' + 2*this.dataConfig.downConfig
|
||||
.val + 'rpx'
|
||||
},
|
||||
];
|
||||
},
|
||||
titleStyle() {
|
||||
return [{
|
||||
'font-weight': this.dataConfig.textStyle.list[this.dataConfig.textStyle.tabVal].style,
|
||||
},
|
||||
{
|
||||
'font-style': this.dataConfig.textStyle.list[this.dataConfig.textStyle.tabVal].style
|
||||
},
|
||||
{
|
||||
fontSize: 2*this.dataConfig.fontSize.val + 'rpx',
|
||||
},
|
||||
{
|
||||
color: this.dataConfig.fontColor.color[0].item
|
||||
},
|
||||
];
|
||||
},
|
||||
titleFuStyle() {
|
||||
return [{
|
||||
fontSize: 2*this.dataConfig.fontFuSize.val + 'rpx',
|
||||
},
|
||||
{
|
||||
color: this.dataConfig.fontFuColor.color[0].item
|
||||
},
|
||||
];
|
||||
},
|
||||
titleRightStyle() {
|
||||
return [{
|
||||
fontSize: 2*this.dataConfig.fontRightSize.val + 'rpx',
|
||||
},
|
||||
{
|
||||
color: this.dataConfig.fontRightColor.color[0].item
|
||||
},
|
||||
];
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
configObj: null,
|
||||
titleTxt: '',
|
||||
titleFuTxt: '',
|
||||
titleRightTxt: '',
|
||||
link: '',
|
||||
txtPosition: '',
|
||||
txtStyle: '',
|
||||
fontSize: 0,
|
||||
mTOP: 0,
|
||||
titleColor: '',
|
||||
themeColor: '',
|
||||
prConfig: 0,
|
||||
bgStyle: 0,
|
||||
pageData: {},
|
||||
selectShow: '',
|
||||
selectStyle: '',
|
||||
bgImgUrl: '',
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.setConfig()
|
||||
},
|
||||
methods: {
|
||||
setConfig(data) {
|
||||
this.configObj = this.data;
|
||||
this.titleTxt = this.dataConfig.titleConfig.val;
|
||||
this.titleFuTxt = this.dataConfig.titleFuConfig.val;
|
||||
this.titleRightTxt = this.dataConfig.titleRightConfig.val;
|
||||
this.link = this.dataConfig.linkConfig.val;
|
||||
this.bgImgUrl = this.dataConfig.bgImg.url;
|
||||
this.selectShow = this.dataConfig.selectShow.tabVal;
|
||||
this.selectStyle = this.dataConfig.selectStyle.tabVal;
|
||||
},
|
||||
goPage() {
|
||||
this.$util.navigateTo(this.dataConfig.linkConfig.val)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.title-box{
|
||||
background-repeat: no-repeat;
|
||||
object-fit: contain;
|
||||
}
|
||||
.title {
|
||||
font-size: 32rpx;
|
||||
color: #000;
|
||||
text-align: center;
|
||||
|
||||
&.left {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
&.right {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
&.blod {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
&.italics {
|
||||
font-style: italic;
|
||||
}
|
||||
}
|
||||
.ml6 {
|
||||
margin-left: 12rpx;
|
||||
}
|
||||
</style>
|
||||
86
app/components/homeIndex/video.vue
Normal file
86
app/components/homeIndex/video.vue
Normal file
@@ -0,0 +1,86 @@
|
||||
<template>
|
||||
<view>
|
||||
<view class="diy_video acea-row row-center-wrapper" :style="[boxStyle]">
|
||||
<video :style="[contantRadius]" :src="link" :show-mute-btn="pageGesture" :poster="cover" controls :autoplay="false" loop
|
||||
objectFit="cover"></video>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
export default {
|
||||
name: 'pictureCube',
|
||||
props: {
|
||||
dataConfig: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
pageGesture: true,
|
||||
onloadCode: ''
|
||||
};
|
||||
},
|
||||
created() {
|
||||
// #ifdef APP
|
||||
this.onloadCode =
|
||||
`this.contentWindow.document.body.innerHTML = '<video style="width: 100%;height: 100%" objectFit="cover" controls="controls" loop show-mute-btn="${this.pageGesture}" poster="${this.cover}" src="${this.link}"></video>';`
|
||||
// #endif
|
||||
},
|
||||
computed: {
|
||||
//视频封面
|
||||
cover() {
|
||||
return this.dataConfig.cover.url
|
||||
},
|
||||
//视频地址
|
||||
link() {
|
||||
if (this.dataConfig.tabConfig.tabVal === 0) {
|
||||
return this.dataConfig.uploadVideo.url
|
||||
} else {
|
||||
return this.dataConfig.link.val
|
||||
}
|
||||
|
||||
},
|
||||
//最外层盒子的样式
|
||||
boxStyle() {
|
||||
return {
|
||||
borderRadius: this.dataConfig.bgStyle.val * 2 + 'rpx',
|
||||
background: `linear-gradient(${this.dataConfig.bgColor.color[0].item}, ${this.dataConfig.bgColor.color[1].item})`,
|
||||
margin: this.dataConfig.mbConfig.val * 2 + 'rpx' + ' ' + this.dataConfig.lrConfig.val * 2 + 'rpx' +
|
||||
' ' + 0,
|
||||
padding: this.dataConfig.upConfig.val * 2 + 'rpx' + ' ' + 0 + ' ' + this.dataConfig.downConfig.val *
|
||||
2 + 'rpx'
|
||||
}
|
||||
},
|
||||
contantRadius() {
|
||||
return { 'border-radius': this.dataConfig.contantStyle.val ? this.dataConfig.contantStyle.val + 'px' : '0' };
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.diy_video {
|
||||
iframe {
|
||||
border: none;
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
video {
|
||||
width: 100%;
|
||||
height: 340rpx;
|
||||
border-radius: 14rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,15 +1,28 @@
|
||||
<template>
|
||||
<view v-if="isUp">
|
||||
<view v-if="isUp" :data-theme="theme">
|
||||
<view class="mobile-bg" v-if="isShow" @click="close"></view>
|
||||
<view class="mobile-mask animated" :class="{slideInUp:isUp}" :style="{position:isPos?'fixed':'static'}">
|
||||
<view class="mobile-mask" :class="[{slideInUp:isUp},{animated:isPos}]"
|
||||
:style="{position:isPos?'fixed':'static'}">
|
||||
<view class="input-item">
|
||||
<input type="text" v-model="account" placeholder="输入手机号" />
|
||||
<view class="item">
|
||||
<input class="ipt" type="number" v-model="account" placeholder-class='placeholder'
|
||||
placeholder="输入手机号" maxlength="11" />
|
||||
</view>
|
||||
|
||||
</view>
|
||||
<view class="input-item">
|
||||
<input type="text" v-model="codeNum" placeholder="输入验证码" />
|
||||
<button class="code" :disabled="disabled" @click="code">{{text}}</button>
|
||||
<view class="item acea-row row-between-wrapper">
|
||||
<input class="ipt codeIput" type="number" v-model="codeNum" placeholder-class='placeholder'
|
||||
placeholder="输入验证码" maxlength="6" />
|
||||
<view class="line">
|
||||
|
||||
</view>
|
||||
<button class="code font-num" :disabled="disabled" @click="code">{{text}}</button>
|
||||
</view>
|
||||
</view>
|
||||
<view class="sub_btn" @click="loginBtn">
|
||||
{{(!userInfo.phone && isLogin) || (userInfo.phone && isLogin)?'立即绑定':'立即登录'}}
|
||||
</view>
|
||||
<view class="sub_btn" @click="loginBtn">{{(!userInfo.phone && isLogin) || (userInfo.phone && isLogin)?'立即绑定':'立即登录'}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
@@ -18,13 +31,14 @@
|
||||
const app = getApp();
|
||||
import sendVerifyCode from "@/mixins/SendVerifyCode";
|
||||
import Routine from '@/libs/routine';
|
||||
import {mapGetters} from "vuex";
|
||||
import {
|
||||
mapGetters
|
||||
} from "vuex";
|
||||
import {
|
||||
loginMobile,
|
||||
registerVerify,
|
||||
getCodeApi,
|
||||
getUserInfo,
|
||||
phoneSilenceAuth,
|
||||
phoneWxSilenceAuth
|
||||
} from "@/api/user";
|
||||
import {
|
||||
@@ -37,7 +51,7 @@
|
||||
const BACK_URL = "login_back_url";
|
||||
export default {
|
||||
name: 'login_mobile',
|
||||
computed: mapGetters(['userInfo','isLogin']),
|
||||
computed: mapGetters(['userInfo', 'isLogin']),
|
||||
props: {
|
||||
isUp: {
|
||||
type: Boolean,
|
||||
@@ -51,6 +65,7 @@
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
// 是否定位
|
||||
isPos: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
@@ -62,10 +77,21 @@
|
||||
platform: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
//小程序code值
|
||||
wxCode: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
// 小程序绑定手机号,isPhone其他手机号绑定
|
||||
loginConfig:{
|
||||
type: String,
|
||||
default: '',
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
theme: app.globalData.theme,
|
||||
keyCode: '',
|
||||
account: '',
|
||||
codeNum: '',
|
||||
@@ -77,7 +103,7 @@
|
||||
//this.getCode();
|
||||
},
|
||||
onLoad() {
|
||||
|
||||
|
||||
},
|
||||
methods: {
|
||||
// 获取验证码
|
||||
@@ -130,20 +156,15 @@
|
||||
title: '请输入正确的验证码'
|
||||
});
|
||||
uni.showLoading({
|
||||
title: !this.userInfo.phone && this.isLogin?'正在绑定中':'正在登录中'
|
||||
title: !this.userInfo.phone && this.isLogin ? '正在绑定中' : '正在登录中'
|
||||
});
|
||||
if (!this.userInfo.phone && this.isLogin) {
|
||||
iosBinding({
|
||||
captcha: that.codeNum,
|
||||
phone: that.account
|
||||
}).then(res => {
|
||||
that.$util.Tips({
|
||||
title: '绑定手机号成功',
|
||||
icon: 'success'
|
||||
}, {
|
||||
tab: 3
|
||||
})
|
||||
that.isApp = 1;
|
||||
that.isApp = 0;
|
||||
that.onSuccess();
|
||||
that.getUserInfo();
|
||||
}).catch(error => {
|
||||
uni.hideLoading()
|
||||
@@ -158,12 +179,20 @@
|
||||
// #ifdef H5
|
||||
type: 'public',
|
||||
// #endif
|
||||
// #ifdef MP
|
||||
type: 'routine',
|
||||
code: this.wxCode,
|
||||
// #endif
|
||||
// #ifdef APP-PLUS
|
||||
type: that.platform === 'ios' ? 'iosWx' : 'androidWx',
|
||||
// #endif
|
||||
key: that.authKey
|
||||
}).then(res => {
|
||||
that.$store.commit('LOGIN', {
|
||||
token: res.data.token
|
||||
});
|
||||
that.$store.commit("SETUID", res.data.uid);
|
||||
that.onSuccess();
|
||||
that.getUserInfo();
|
||||
}).catch(error => {
|
||||
uni.hideLoading()
|
||||
@@ -173,26 +202,35 @@
|
||||
})
|
||||
}
|
||||
},
|
||||
// #ifdef MP
|
||||
phoneSilenceAuth(code) {
|
||||
let self = this
|
||||
phoneSilenceAuth({
|
||||
code: code,
|
||||
spid: app.globalData.spid,
|
||||
spread: app.globalData.code,
|
||||
phone: this.account,
|
||||
captcha: this.codeNum
|
||||
}).then(res => {
|
||||
this.$store.commit('LOGIN', res.data.token);
|
||||
this.$store.commit("SETUID", res.data.uid);
|
||||
this.getUserInfo();
|
||||
}).catch(error => {
|
||||
self.$util.Tips({
|
||||
title: error
|
||||
})
|
||||
})
|
||||
/**
|
||||
* 登录成功后的方法
|
||||
*/
|
||||
onSuccess(){
|
||||
uni.hideLoading();
|
||||
let backUrl = this.$Cache.get(BACK_URL) || "/pages/index/index";
|
||||
// #ifdef MP
|
||||
this.$util.Tips({
|
||||
title: '绑定手机号成功'
|
||||
}, {
|
||||
tab: 4,
|
||||
url: backUrl
|
||||
});
|
||||
this.close();
|
||||
// #endif
|
||||
// #ifdef H5
|
||||
this.$emit('wechatPhone', true)
|
||||
// #endif
|
||||
// #ifdef APP-PLUS
|
||||
if (this.isApp == 0) {
|
||||
if (backUrl.indexOf('/pages/users/login/index') !== -1) {
|
||||
backUrl = '/pages/index/index';
|
||||
}
|
||||
uni.reLaunch({
|
||||
url: backUrl
|
||||
});
|
||||
}
|
||||
// #endif
|
||||
},
|
||||
// #endif
|
||||
/**
|
||||
* 获取个人用户信息
|
||||
*/
|
||||
@@ -201,25 +239,13 @@
|
||||
getUserInfo().then(res => {
|
||||
uni.hideLoading();
|
||||
that.$store.commit("UPDATE_USERINFO", res.data);
|
||||
// #ifdef MP
|
||||
that.$util.Tips({
|
||||
title: '登录成功',
|
||||
icon: 'success'
|
||||
}, {
|
||||
tab: 3
|
||||
})
|
||||
that.close()
|
||||
// #endif
|
||||
// #ifdef H5
|
||||
that.$emit('wechatPhone', true)
|
||||
// #endif
|
||||
});
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="stylus" scoped>
|
||||
<style lang="scss" scoped>
|
||||
.mobile-bg {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
@@ -239,50 +265,69 @@
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
padding: 67rpx 30rpx;
|
||||
padding: 67rpx 72rpx;
|
||||
background: #fff;
|
||||
|
||||
.input-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
height: 86rpx;
|
||||
width: 606rpx;
|
||||
height: 88rpx;
|
||||
margin-bottom: 38rpx;
|
||||
|
||||
input {
|
||||
flex: 1;
|
||||
display: block;
|
||||
.codeIput {
|
||||
width: 300rpx !important;
|
||||
}
|
||||
|
||||
.ipt {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding-left: 40rpx;
|
||||
border-radius: 43rpx;
|
||||
border: 1px solid #DCDCDC;
|
||||
font-size: 32rpx;
|
||||
}
|
||||
|
||||
.item {
|
||||
width: 100%;
|
||||
background: #F5F5F5;
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
padding: 0 32rpx 0 48rpx;
|
||||
border-radius: 45rpx;
|
||||
font-size: 28rpx;
|
||||
font-family: PingFang SC-Regular, PingFang SC;
|
||||
font-weight: 400;
|
||||
color: #333333;
|
||||
line-height: 40px;
|
||||
|
||||
.placeholder {
|
||||
color: #BBBBBB;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.line {
|
||||
width: 2rpx;
|
||||
height: 28rpx;
|
||||
background: #CCCCCC;
|
||||
}
|
||||
|
||||
.code {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 220rpx;
|
||||
height: 86rpx;
|
||||
margin-left: 30rpx;
|
||||
background: rgba(233, 51, 35, 0.05);
|
||||
background: none;
|
||||
font-size: 28rpx;
|
||||
color: $theme-color;
|
||||
@include main_color(theme);
|
||||
border-radius: 43rpx;
|
||||
|
||||
&[disabled] {
|
||||
background: rgba(0, 0, 0, 0.05);
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.sub_btn {
|
||||
width: 690rpx;
|
||||
width: 100%;
|
||||
height: 86rpx;
|
||||
line-height: 86rpx;
|
||||
margin-top: 60rpx;
|
||||
background: #E93323;
|
||||
@include main_bg_color(theme);
|
||||
border-radius: 43rpx;
|
||||
color: #fff;
|
||||
font-size: 28rpx;
|
||||
@@ -293,4 +338,4 @@
|
||||
.animated {
|
||||
animation-duration: .4s
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
@@ -5,9 +5,9 @@
|
||||
<view class="info-box">
|
||||
<image :src="logoUrl"></image>
|
||||
<view class="title">获取授权</view>
|
||||
<view class="txt">获取微信的手机号授权</view>
|
||||
<view class="txt">获取手机号授权</view>
|
||||
</view>
|
||||
<button class="sub_btn" open-type="getPhoneNumber" @getphonenumber="getphonenumber">获取微信手机号</button>
|
||||
<button class="sub_btn" open-type="getPhoneNumber" @getphonenumber="getphonenumber">获取手机号</button>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
@@ -157,4 +157,4 @@
|
||||
.animated{
|
||||
animation-duration:.4s
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
File diff suppressed because it is too large
Load Diff
298
app/components/navBar.vue
Normal file
298
app/components/navBar.vue
Normal file
@@ -0,0 +1,298 @@
|
||||
<template>
|
||||
<view>
|
||||
<view class="cart_nav" :class="isBackgroundColor?'cart_nav_color':''" :style='"height:"+navH+"rpx;"'>
|
||||
<view class='navbarCon acea-row'>
|
||||
<!-- #ifdef MP -->
|
||||
<view class="select_nav flex justify-center align-center" id="home" :style="{ top: homeTop + 'rpx' }">
|
||||
<text class="iconfont icon-fanhui2 px-20" @tap="returns"></text>
|
||||
<text v-if="productType!=='video'" class="iconfont icon-gengduo5 px-20" @tap.stop="showNav"></text>
|
||||
<text v-if="productType!=='video'" class="nav_line"></text>
|
||||
</view>
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef H5 -->
|
||||
<view id="home" class="home acea-row row-center-wrapper iconfont icon-shouye4 h5_back"
|
||||
:style="{ top: homeTop + 'rpx' }" @tap="goToHome">
|
||||
</view>
|
||||
<!-- #endif -->
|
||||
<!-- #ifndef APP-PLUS -->
|
||||
<view class="nav_title" :style="{ top: homeTop + 'rpx' }">{{navTitle}}</view>
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef H5 -->
|
||||
<view class="right_select" :style="{ top: homeTop + 'rpx' }" @tap="showNav">
|
||||
<text class="iconfont icon-gengduo2"></text>
|
||||
</view>
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
</view>
|
||||
<view class="dialog_nav" :style='"top:"+navH+"rpx;"' v-show="currentPage">
|
||||
<view class="dialog_nav_item" v-for="(item,index) in selectNavList" :key="index" @click="linkPage(item.url)">
|
||||
<text class="iconfont" :class="item.icon"></text>
|
||||
<text class="pl-20">{{item.name}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import animationType from '@/utils/animationType.js'
|
||||
import {
|
||||
mapGetters
|
||||
} from "vuex";
|
||||
let app = getApp();
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
homeTop: 20,
|
||||
navH:"",
|
||||
currentPage:false,
|
||||
selectNavList:[
|
||||
{name:'首页',icon:'icon-shouye8',url:'/pages/index/index'},
|
||||
{name:'搜索',icon:'icon-sousuo6',url:'/pages/goods/goods_search/index'},
|
||||
{name:'我的收藏',icon:'icon-shoucang3',url:'/pages/users/user_goods_collection/index'},
|
||||
{name:'个人中心',icon:'icon-gerenzhongxin1',url:'/pages/user/index'},
|
||||
]
|
||||
}
|
||||
},
|
||||
props:{
|
||||
navTitle:{
|
||||
type: String,
|
||||
default:''
|
||||
},
|
||||
isBackgroundColor: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['productType'])
|
||||
},
|
||||
created(){
|
||||
// #ifdef MP
|
||||
// 获取导航高度;
|
||||
uni.getSystemInfo({
|
||||
success: function(res) {
|
||||
app.globalData.navHeight = res.statusBarHeight * (750 / res.windowWidth) + 91;
|
||||
}
|
||||
});
|
||||
this.navH = app.globalData.navHeight;
|
||||
// #endif
|
||||
// #ifndef MP
|
||||
this.navH = 96;
|
||||
// #endif
|
||||
this.$emit('getNavH', this.navH)
|
||||
},
|
||||
onReady() {
|
||||
this.$nextTick(function() {
|
||||
// #ifdef MP
|
||||
const menuButton = uni.getMenuButtonBoundingClientRect();
|
||||
const query = uni.createSelectorQuery().in(this);
|
||||
query
|
||||
.select('#home')
|
||||
.boundingClientRect(data => {
|
||||
if(this.productType!=='video'){
|
||||
this.homeTop = menuButton.top * 2 + menuButton.height - data.height;
|
||||
}else{
|
||||
this.homeTop = 18;
|
||||
}
|
||||
|
||||
})
|
||||
.exec();
|
||||
// #endif
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
//返回首页
|
||||
goToHome(){
|
||||
uni.switchTab({
|
||||
url:'/pages/index/index'
|
||||
})
|
||||
},
|
||||
returns: function() {
|
||||
uni.navigateBack();
|
||||
},
|
||||
showNav(){
|
||||
this.currentPage = !this.currentPage;
|
||||
},
|
||||
//下拉导航页面跳转
|
||||
linkPage(url){
|
||||
if(url == '/pages/index/index' || url == '/pages/user/index'){
|
||||
uni.switchTab({
|
||||
url
|
||||
})
|
||||
}else{
|
||||
uni.navigateTo({
|
||||
animationType: animationType.type,
|
||||
animationDuration: animationType.duration,
|
||||
url
|
||||
})
|
||||
}
|
||||
this.currentPage = false
|
||||
},
|
||||
touchStart(){
|
||||
this.currentPage = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.pl-20{
|
||||
padding-left: 20rpx;
|
||||
}
|
||||
.cart_nav{
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 99;
|
||||
width: 100%;
|
||||
}
|
||||
.cart_nav_color{
|
||||
@include main_bg_color(theme);
|
||||
}
|
||||
.navbarCon {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
height: 100rpx;
|
||||
width: 100%;
|
||||
}
|
||||
.h5_back {
|
||||
color: #fff;
|
||||
position: fixed;
|
||||
left:20rpx;
|
||||
font-size: 32rpx;
|
||||
text-align: center;
|
||||
line-height: 58rpx;
|
||||
}
|
||||
.select_nav{
|
||||
border: 1px solid rgba(0, 0, 0, 0.07);
|
||||
width: 170rpx !important;
|
||||
height: 60rpx !important;
|
||||
border-radius: 33rpx;
|
||||
background: rgba(255, 255, 255, 0.6);
|
||||
color: #000;
|
||||
position: fixed;
|
||||
font-size: 18px;
|
||||
line-height: 58rpx;
|
||||
z-index: 1000;
|
||||
left: 14rpx;
|
||||
}
|
||||
.px-20{
|
||||
padding: 0 20rpx 0;
|
||||
}
|
||||
.nav_line{
|
||||
content: '';
|
||||
display: inline-block;
|
||||
width: 1px;
|
||||
height: 34rpx;
|
||||
background: #ddd;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
margin: auto;
|
||||
}
|
||||
.container_detail{
|
||||
/* #ifdef MP */
|
||||
margin-top:32rpx;
|
||||
/* #endif */
|
||||
}
|
||||
.tab_nav{
|
||||
width: 100%;
|
||||
height: 48px;
|
||||
padding:0 30rpx 0;
|
||||
}
|
||||
.nav_title{
|
||||
width: 200rpx;
|
||||
height: 58rpx;
|
||||
line-height: 58rpx;
|
||||
color: #fff;
|
||||
font-size: 36rpx;
|
||||
position: fixed;
|
||||
text-align: center;
|
||||
left: 0;
|
||||
right: 0;
|
||||
margin: auto;
|
||||
}
|
||||
.right_select{
|
||||
position: fixed;
|
||||
right: 20rpx;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
line-height: 58rpx;
|
||||
}
|
||||
.select_nav{
|
||||
width: 170rpx !important;
|
||||
height: 60rpx !important;
|
||||
border-radius: 33rpx;
|
||||
background: rgba(255, 255, 255, 0.6);
|
||||
color: #000;
|
||||
position: fixed;
|
||||
font-size: 18px;
|
||||
line-height: 58rpx;
|
||||
z-index: 1000;
|
||||
left: 14rpx;
|
||||
}
|
||||
.px-20{
|
||||
padding: 0 20rpx 0;
|
||||
}
|
||||
.justify-center{
|
||||
justify-content: center;
|
||||
}
|
||||
.align-center {
|
||||
align-items: center;
|
||||
}
|
||||
.dialog_nav{
|
||||
position: fixed;
|
||||
/* #ifdef MP */
|
||||
left: 14rpx;
|
||||
/* #endif */
|
||||
/* #ifdef H5 || APP-PLUS*/
|
||||
right: 14rpx;
|
||||
/* #endif */
|
||||
width: 240rpx;
|
||||
background: #FFFFFF;
|
||||
box-shadow: 0px 0px 16rpx rgba(0, 0, 0, 0.08);
|
||||
z-index: 999;
|
||||
border-radius: 14rpx;
|
||||
&::before{
|
||||
content: '';
|
||||
width: 0;
|
||||
height: 0;
|
||||
position: absolute;
|
||||
/* #ifdef MP */
|
||||
left: 0;
|
||||
right: 0;
|
||||
margin:auto;
|
||||
/* #endif */
|
||||
/* #ifdef H5 || APP-PLUS */
|
||||
right: 8px;
|
||||
/* #endif */
|
||||
top:-9px;
|
||||
border-bottom: 10px solid #fff;
|
||||
border-left: 10px solid transparent; /*transparent 表示透明*/
|
||||
border-right: 10px solid transparent;
|
||||
}
|
||||
}
|
||||
.dialog_nav_item{
|
||||
width: 100%;
|
||||
height: 84rpx;
|
||||
line-height: 84rpx;
|
||||
padding: 0 20rpx 0;
|
||||
box-sizing: border-box;
|
||||
border-bottom: #eee;
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
position: relative;
|
||||
.iconfont{
|
||||
font-size: 32rpx;
|
||||
}
|
||||
&::after{
|
||||
content: '';
|
||||
position: absolute;
|
||||
width:86px;
|
||||
height: 1px;
|
||||
background-color: #EEEEEE;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -13,7 +13,7 @@
|
||||
<view class='num'>x {{item.payNum ? item.payNum : item.cartNum}}</view>
|
||||
</view>
|
||||
<view class='attr line1' v-if="item.sku">{{item.sku}}</view>
|
||||
<view class='money font-color'>¥{{item.price}}</view>
|
||||
<view class='money'>¥{{item.vipPrice ? item.vipPrice : item.price}}</view>
|
||||
<view class='evaluate' v-if='item.isReply==0 && evaluate==2' @click.stop="evaluateTap(item)">评价
|
||||
</view>
|
||||
<view class='evaluate' v-else-if="item.isReply==1">已评价</view>
|
||||
@@ -79,14 +79,14 @@
|
||||
methods: {
|
||||
evaluateTap(item) {
|
||||
uni.navigateTo({
|
||||
url: "/pages/users/goods_comment_con/index?unique=" + item.attrId + "&orderId=" + this.orderId + '&id=' + this.ids
|
||||
url: "/pages/goods/goods_comment_con/index?unique=" + item.attrId + "&orderId=" + this.orderId + '&id=' + this.ids
|
||||
})
|
||||
},
|
||||
jumpCon: function(id) {
|
||||
let type = this.productType==0?'normal':'video'
|
||||
if (this.jump) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/goods_details/index?id=${id}&type=${type}`
|
||||
url: `/pages/goods/goods_details/index?id=${id}&type=${type}`
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -99,7 +99,9 @@
|
||||
background-color: #fff;
|
||||
margin-top: 15rpx;
|
||||
}
|
||||
|
||||
.money{
|
||||
@include price_color(theme);
|
||||
}
|
||||
.orderGoods .total {
|
||||
width: 100%;
|
||||
height: 86rpx;
|
||||
|
||||
150
app/components/pageFooter/index.vue
Normal file
150
app/components/pageFooter/index.vue
Normal file
@@ -0,0 +1,150 @@
|
||||
<template>
|
||||
<!-- 底部导航 -->
|
||||
<view :data-theme="theme">
|
||||
<view v-if="obj.isCustom==1">
|
||||
<view class="page-footer" id="target">
|
||||
<view class="foot-item" v-for="(item,index) in obj.bottomNavigationList" :key="index"
|
||||
@click="goRouter(item)">
|
||||
<block v-if="item.link.split('?')[0] == activeRouter">
|
||||
<image :src="item.checked"></image>
|
||||
<view class="txt">{{item.name}}</view>
|
||||
</block>
|
||||
<block v-else>
|
||||
<image :src="item.unchecked"></image>
|
||||
<view class="unchecked">{{item.name}}</view>
|
||||
</block>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
let app = getApp();
|
||||
import {
|
||||
getBottomNavigationApi
|
||||
} from '@/api/api.js'
|
||||
export default {
|
||||
props: {
|
||||
arr: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
theme: app.globalData.theme,
|
||||
obj: {},
|
||||
activeRouter: ''
|
||||
}
|
||||
},
|
||||
created() {
|
||||
let routes = getCurrentPages(); //获取当前打开过的页面路由数组
|
||||
let curRoute = routes[routes.length - 1].route //获取当前页面路由
|
||||
this.activeRouter = '/' + curRoute;
|
||||
},
|
||||
mounted() {
|
||||
this.getInit()
|
||||
},
|
||||
methods: {
|
||||
getInit() {
|
||||
getBottomNavigationApi().then((res) => {
|
||||
this.obj = res.data
|
||||
this.$store.commit('BottomNavigationIsCustom', this.obj.isCustom == 1 ? true : false);
|
||||
if (this.obj.isCustom == 1) {
|
||||
uni.hideTabBar()
|
||||
} else {
|
||||
uni.showTabBar()
|
||||
}
|
||||
})
|
||||
},
|
||||
goRouter(item) {
|
||||
var pages = getCurrentPages();
|
||||
var page = (pages[pages.length - 1]).$page.fullPath;
|
||||
if (item.link == page) return
|
||||
if (['/pages/index/index', '/pages/goods_cate/goods_cate',
|
||||
'/pages/order_addcart/order_addcart', '/pages/user/index'
|
||||
].indexOf(item.link) > -1) {
|
||||
uni.switchTab({
|
||||
url: item.link,
|
||||
fail(err) {
|
||||
uni.redirectTo({
|
||||
url: item.link
|
||||
})
|
||||
}
|
||||
})
|
||||
} else {
|
||||
uni.navigateTo({
|
||||
url: item.link
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.unchecked {
|
||||
color: #333;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
|
||||
.page-footer {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
z-index: 666;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-around;
|
||||
width: 100%;
|
||||
height: calc(98rpx+ constant(safe-area-inset-bottom)); ///兼容 IOS<11.2/
|
||||
height: calc(98rpx + env(safe-area-inset-bottom)); ///兼容 IOS>11.2/
|
||||
box-sizing: border-box;
|
||||
border-top: solid 1rpx #F3F3F3;
|
||||
background-color: #fff;
|
||||
box-shadow: 0px 0px 17rpx 1rpx rgba(206, 206, 206, 0.32);
|
||||
padding-bottom: constant(safe-area-inset-bottom); ///兼容 IOS<11.2/
|
||||
padding-bottom: env(safe-area-inset-bottom); ///兼容 IOS>11.2/
|
||||
|
||||
.foot-item {
|
||||
display: flex;
|
||||
width: max-content;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
position: relative;
|
||||
|
||||
.count-num {
|
||||
position: absolute;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
top: 0rpx;
|
||||
right: -15rpx;
|
||||
color: #fff;
|
||||
font-size: 20rpx;
|
||||
background-color: #FD502F;
|
||||
border-radius: 50%;
|
||||
padding: 4rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.foot-item image {
|
||||
height: 50rpx;
|
||||
width: 50rpx;
|
||||
text-align: center;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.txtchecked {
|
||||
font-size: 24rpx;
|
||||
}
|
||||
|
||||
.foot-item .txt {
|
||||
font-size: 24rpx;
|
||||
@include main-color(theme);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -5,7 +5,7 @@
|
||||
选择付款方式<text class="iconfont icon-guanbi" @click='close'></text>
|
||||
</view>
|
||||
<view class="item acea-row row-between-wrapper" @click='goPay(item.number || 0 , item.value)'
|
||||
v-for="(item,index) in payMode" :key="index">
|
||||
v-for="(item,index) in payMode" :key="index" v-if="item.payStatus==1">
|
||||
<view class="left acea-row row-between-wrapper">
|
||||
<view class="iconfont" :class="item.icon"></view>
|
||||
<view class="text">
|
||||
@@ -20,26 +20,21 @@
|
||||
</view>
|
||||
</view>
|
||||
<view class="mask" @click='close' v-if="pay_close"></view>
|
||||
<view class="alipaysubmit" v-html="formContent"></view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
orderPay,
|
||||
wechatOrderPay,
|
||||
wechatQueryPayResult
|
||||
wechatQueryPayResult,
|
||||
getPayConfig
|
||||
} from '@/api/order.js';
|
||||
import {
|
||||
mapGetters
|
||||
} from "vuex";
|
||||
export default {
|
||||
props: {
|
||||
payMode: {
|
||||
type: Array,
|
||||
default: function() {
|
||||
return [];
|
||||
}
|
||||
},
|
||||
pay_close: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
@@ -55,19 +50,55 @@
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
||||
formContent:'',
|
||||
payChannel:'',
|
||||
//支付方式
|
||||
payMode: [
|
||||
{
|
||||
"name": "微信支付",
|
||||
"icon": "icon-weixin2",
|
||||
value: 'weixin',
|
||||
title: '微信快捷支付',
|
||||
// #ifdef APP
|
||||
payStatus: 0,
|
||||
// #endif
|
||||
// #ifndef APP
|
||||
payStatus: 1,
|
||||
// #endif
|
||||
},
|
||||
{
|
||||
"name": "余额支付",
|
||||
"icon": "icon-yuezhifu",
|
||||
value: 'yue',
|
||||
title: '可用余额:',
|
||||
payStatus: 1,
|
||||
number: 0
|
||||
},
|
||||
],
|
||||
};
|
||||
},
|
||||
computed: mapGetters(['systemPlatform']),
|
||||
computed: mapGetters(['systemPlatform','userInfo','productType']),
|
||||
created(){
|
||||
this.payConfig();
|
||||
this.payMode[1].number = this.userInfo.nowMoney;
|
||||
},
|
||||
methods: {
|
||||
close: function() {
|
||||
this.$emit('onChangeFun', {
|
||||
action: 'payClose'
|
||||
});
|
||||
},
|
||||
payConfig(){
|
||||
getPayConfig().then(res=>{
|
||||
this.payMode[1].payStatus = res.data.yuePayStatus === "'1'" ? 1 : 0;
|
||||
// #ifndef APP
|
||||
this.payMode[0].payStatus = res.data.payWeixinOpen === "'1'" ? 1 : 0;
|
||||
// #endif
|
||||
})
|
||||
},
|
||||
goPay: function(number, paytype) {
|
||||
let that = this;
|
||||
let goPages = '/pages/order_pay_status/index?order_id=' + that.order_id;
|
||||
let goPages = '/pages/order/order_pay_status/index?order_id=' + that.order_id;
|
||||
if (!that.order_id) return that.$util.Tips({
|
||||
title: '请选择要支付的订单'
|
||||
});
|
||||
@@ -77,109 +108,38 @@
|
||||
uni.showLoading({
|
||||
title: '支付中'
|
||||
});
|
||||
wechatOrderPay({
|
||||
// #ifdef H5
|
||||
if(paytype == 'alipay'){
|
||||
that.payChannel = 'alipay';
|
||||
}else if(paytype == 'weixin' && this.$wechat.isWeixin()){
|
||||
that.payChannel = 'public';
|
||||
}else{
|
||||
that.payChannel = 'weixinh5';
|
||||
}
|
||||
// #endif
|
||||
// #ifdef APP-PLUS
|
||||
if(paytype == 'alipay'){
|
||||
that.payChannel = 'appAliPay';
|
||||
}else if(paytype == 'weixin'){
|
||||
that.payChannel = that.systemPlatform === 'ios' ? 'weixinAppIos' : 'weixinAppAndroid';
|
||||
}
|
||||
// #endif
|
||||
orderPay({
|
||||
orderNo: that.order_id,
|
||||
// #ifdef MP
|
||||
payChannel: 'routine',
|
||||
// #endif
|
||||
// #ifdef H5
|
||||
payChannel: that.$wechat.isWeixin() ? 'public' : 'weixinh5',
|
||||
// #ifndef MP
|
||||
payChannel:that.payChannel,
|
||||
// #endif
|
||||
payType: paytype
|
||||
payType: paytype,
|
||||
scene: that.productType === 'normal' ? 0 : 1177 //下单时小程序的场景值
|
||||
}).then(res => {
|
||||
let jsConfig = res.data.jsConfig;
|
||||
that.order_id = res.data.orderNo;
|
||||
switch (res.data.payType) {
|
||||
case 'weixin':
|
||||
// #ifdef MP
|
||||
uni.requestPayment({
|
||||
timeStamp: jsConfig.timeStamp,
|
||||
nonceStr: jsConfig.nonceStr,
|
||||
package: jsConfig.packages,
|
||||
signType: jsConfig.signType,
|
||||
paySign: jsConfig.paySign,
|
||||
success: function(ress) {
|
||||
uni.hideLoading();
|
||||
wechatQueryPayResult(that.order_id).then(res => {
|
||||
uni.hideLoading();
|
||||
return that.$util.Tips({
|
||||
title: "支付成功",
|
||||
icon: 'success'
|
||||
}, () => {
|
||||
that.$emit('onChangeFun', {
|
||||
action: 'pay_complete'
|
||||
});
|
||||
});
|
||||
}).cache(err => {
|
||||
uni.hideLoading();
|
||||
return that.$util.Tips({
|
||||
title: err
|
||||
});
|
||||
})
|
||||
},
|
||||
fail: function(e) {
|
||||
uni.hideLoading();
|
||||
return that.$util.Tips({
|
||||
title: '取消支付'
|
||||
}, () => {
|
||||
that.$emit('onChangeFun', {
|
||||
action: 'pay_fail'
|
||||
});
|
||||
});
|
||||
},
|
||||
complete: function(e) {
|
||||
uni.hideLoading();
|
||||
if (e.errMsg == 'requestPayment:cancel') return that.$util
|
||||
.Tips({
|
||||
title: '取消支付'
|
||||
}, () => {
|
||||
that.$emit('onChangeFun', {
|
||||
action: 'pay_fail'
|
||||
});
|
||||
});
|
||||
},
|
||||
})
|
||||
// #endif
|
||||
// #ifdef H5
|
||||
let datas = {
|
||||
timestamp: jsConfig.timeStamp,
|
||||
nonceStr: jsConfig.nonceStr,
|
||||
package: jsConfig.packages,
|
||||
signType: jsConfig.signType,
|
||||
paySign: jsConfig.paySign
|
||||
};
|
||||
that.$wechat.pay(datas).then(res => {
|
||||
if (res.errMsg == 'chooseWXPay:cancel') {
|
||||
uni.hideLoading();
|
||||
return that.$util.Tips({
|
||||
title: '支付失败'
|
||||
});
|
||||
} else {
|
||||
wechatQueryPayResult(that.order_id).then(res => {
|
||||
uni.hideLoading();
|
||||
return that.$util.Tips({
|
||||
title: "支付成功",
|
||||
icon: 'success'
|
||||
}, () => {
|
||||
that.$emit('onChangeFun', {
|
||||
action: 'pay_complete'
|
||||
});
|
||||
});
|
||||
}).cache(err => {
|
||||
uni.hideLoading();
|
||||
return that.$util.Tips({
|
||||
title: err
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
}).cache(errW => {
|
||||
uni.hideLoading();
|
||||
return that.$util.Tips({
|
||||
title: errW
|
||||
});
|
||||
})
|
||||
// #endif
|
||||
that.weixinPay(jsConfig);
|
||||
break;
|
||||
case 'yue':
|
||||
uni.hideLoading();
|
||||
@@ -205,6 +165,57 @@
|
||||
});
|
||||
});
|
||||
break;
|
||||
case 'alipay':
|
||||
//#ifdef H5
|
||||
if (this.$wechat.isWeixin()) {
|
||||
//微信公众号内支付
|
||||
} else {
|
||||
//h5支付
|
||||
uni.hideLoading();
|
||||
that.formContent = res.data.alipayRequest;
|
||||
uni.setStorage({key: 'orderNo', data:that.order_id});
|
||||
that.$nextTick(() => {
|
||||
document.forms['punchout_form'].submit();
|
||||
})
|
||||
}
|
||||
//#endif
|
||||
// #ifdef APP-PLUS
|
||||
let alipayRequest = res.data.alipayRequest;
|
||||
uni.requestPayment({
|
||||
provider: 'alipay',
|
||||
orderInfo: alipayRequest,
|
||||
success: (e) => {
|
||||
uni.showToast({
|
||||
title: "支付成功"
|
||||
})
|
||||
setTimeout(res => {
|
||||
that.$emit('onChangeFun', {
|
||||
action: 'pay_complete'
|
||||
});
|
||||
}, 2000)
|
||||
},
|
||||
fail: (e) => {
|
||||
uni.showModal({
|
||||
content: "支付失败",
|
||||
showCancel: false,
|
||||
success: function(res) {
|
||||
if (res.confirm) {
|
||||
//点击确认的操作
|
||||
that.$emit('onChangeFun', {
|
||||
action: 'pay_fail'
|
||||
});
|
||||
} else if (res.cancel) {
|
||||
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
complete: () => {
|
||||
uni.hideLoading();
|
||||
},
|
||||
});
|
||||
// #endif
|
||||
break;
|
||||
}
|
||||
}).catch(err => {
|
||||
uni.hideLoading();
|
||||
@@ -216,6 +227,145 @@
|
||||
});
|
||||
});
|
||||
})
|
||||
},
|
||||
weixinPay(jsConfig){
|
||||
let that = this;
|
||||
// #ifdef MP
|
||||
uni.requestOrderPayment({
|
||||
timeStamp: jsConfig.timeStamp,
|
||||
nonceStr: jsConfig.nonceStr,
|
||||
package: jsConfig.packages,
|
||||
signType: jsConfig.signType,
|
||||
paySign: jsConfig.paySign,
|
||||
ticket: jsConfig.ticket,
|
||||
success: function(ress) {
|
||||
uni.hideLoading();
|
||||
wechatQueryPayResult(that.order_id).then(res => {
|
||||
uni.hideLoading();
|
||||
return that.$util.Tips({
|
||||
title: "支付成功",
|
||||
icon: 'success'
|
||||
}, () => {
|
||||
that.$emit('onChangeFun', {
|
||||
action: 'pay_complete'
|
||||
});
|
||||
});
|
||||
}).catch(err => {
|
||||
uni.hideLoading();
|
||||
return that.$util.Tips({
|
||||
title: err
|
||||
});
|
||||
})
|
||||
},
|
||||
fail: function(e) {
|
||||
uni.hideLoading();
|
||||
return that.$util.Tips({
|
||||
title: '取消支付'
|
||||
}, () => {
|
||||
that.$emit('onChangeFun', {
|
||||
action: 'pay_fail'
|
||||
});
|
||||
});
|
||||
},
|
||||
complete: function(e) {
|
||||
uni.hideLoading();
|
||||
if (e.errMsg == 'requestPayment:cancel') return that.$util
|
||||
.Tips({
|
||||
title: '取消支付'
|
||||
}, () => {
|
||||
that.$emit('onChangeFun', {
|
||||
action: 'pay_fail'
|
||||
});
|
||||
});
|
||||
},
|
||||
})
|
||||
// #endif
|
||||
// #ifdef H5
|
||||
let datas = {
|
||||
timestamp: jsConfig.timeStamp,
|
||||
nonceStr: jsConfig.nonceStr,
|
||||
package: jsConfig.packages,
|
||||
signType: jsConfig.signType,
|
||||
paySign: jsConfig.paySign
|
||||
};
|
||||
that.$wechat.pay(datas).then(res => {
|
||||
if (res.errMsg == 'chooseWXPay:cancel') {
|
||||
uni.hideLoading();
|
||||
return that.$util.Tips({
|
||||
title: '支付失败'
|
||||
});
|
||||
} else {
|
||||
wechatQueryPayResult(that.order_id).then(res => {
|
||||
uni.hideLoading();
|
||||
return that.$util.Tips({
|
||||
title: "支付成功",
|
||||
icon: 'success'
|
||||
}, () => {
|
||||
that.$emit('onChangeFun', {
|
||||
action: 'pay_complete'
|
||||
});
|
||||
});
|
||||
}).catch(err => {
|
||||
uni.hideLoading();
|
||||
return that.$util.Tips({
|
||||
title: err
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
}).catch(errW => {
|
||||
uni.hideLoading();
|
||||
return that.$util.Tips({
|
||||
title: errW
|
||||
});
|
||||
})
|
||||
// #endif
|
||||
// #ifdef APP-PLUS
|
||||
uni.requestPayment({
|
||||
provider: 'wxpay',
|
||||
orderInfo: {
|
||||
"appid": jsConfig.appId, // 微信开放平台 - 应用 - AppId,注意和微信小程序、公众号 AppId 可能不一致
|
||||
"noncestr": jsConfig.nonceStr, // 随机字符串
|
||||
"package": "Sign=WXPay", // 固定值
|
||||
"partnerid": jsConfig.partnerid, // 微信支付商户号
|
||||
"prepayid": jsConfig.packages, // 统一下单订单号
|
||||
"timestamp": Number(jsConfig.timeStamp), // 时间戳(单位:秒)
|
||||
"sign": this.systemPlatform === 'ios' ? 'MD5' : jsConfig
|
||||
.paySign // 签名,这里用的 MD5 签名
|
||||
}, //订单数据 【注意微信的订单信息,键值应该全部是小写,不能采用驼峰命名】
|
||||
success: (e) => {
|
||||
uni.hideLoading();
|
||||
let url = '/pages/order/order_pay_status/index?order_id=' + that.order_id;
|
||||
uni.showToast({
|
||||
title: "支付成功"
|
||||
})
|
||||
setTimeout(res => {
|
||||
that.$emit('onChangeFun', {
|
||||
action: 'pay_complete'
|
||||
});
|
||||
}, 2000)
|
||||
},
|
||||
fail: (e) => {
|
||||
uni.hideLoading();
|
||||
uni.showModal({
|
||||
content: "支付失败",
|
||||
showCancel: false,
|
||||
success: function(res) {
|
||||
if (res.confirm) {
|
||||
that.$emit('onChangeFun', {
|
||||
action: 'pay_fail'
|
||||
});
|
||||
} else if (res.cancel) {
|
||||
console.log('用户点击取消');
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
complete: () => {
|
||||
uni.hideLoading();
|
||||
},
|
||||
});
|
||||
// #endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,34 +1,52 @@
|
||||
<template>
|
||||
<view class='product-bg'>
|
||||
<swiper :indicator-dots="indicatorDots" indicator-active-color="#e93323" :autoplay="autoplay"
|
||||
:circular="circular" :interval="interval" :duration="duration" @change="change">
|
||||
|
||||
<swiper :indicator-dots="indicatorDots" :indicator-active-color="indicatorBg" :autoplay="autoplay" :circular="circular"
|
||||
:interval="interval" :duration="duration" @change="change" v-if="isPlay">
|
||||
<!-- #ifndef APP-PLUS -->
|
||||
<swiper-item v-if="videoline">
|
||||
<view class="item">
|
||||
<view v-show="!controls" style="width:100%;height:100% ">
|
||||
<video id="myVideo" :src='videoline' objectFit="cover" controls style="width:100%;height:100% "
|
||||
show-center-play-btn show-mute-btn="true" auto-pause-if-navigate :custom-cache="false"
|
||||
:enable-progress-gesture="false" :poster="imgUrls[0]" @pause="videoPause"></video>
|
||||
show-center-play-btn show-mute-btn="true" auto-pause-if-navigate :custom-cache="false" :enable-progress-gesture="false" :poster="imgUrls[0]" @pause="videoPause"></video>
|
||||
</view>
|
||||
<view class="poster" v-show="controls">
|
||||
<image class="image" :src="imgUrls[0]"></image>
|
||||
</view>
|
||||
<view class="stop" v-show="controls" @tap="bindPause">
|
||||
<image class="image" src="../../static/images/stop.png"></image>
|
||||
<image class="image" :src="urlDomain+'crmebimage/perset/staticImg/stop.png'"></image>
|
||||
</view>
|
||||
</view>
|
||||
</swiper-item>
|
||||
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef APP-PLUS -->
|
||||
<swiper-item v-if="videoline">
|
||||
<view class="item">
|
||||
<view class="poster" v-show="controls">
|
||||
<image class="image" :src="imgUrls[0]"></image>
|
||||
</view>
|
||||
<view class="stop" v-show="controls" @tap="bindPause">
|
||||
<image class="image" :src="urlDomain+'crmebimage/perset/staticImg/stop.png'"></image>
|
||||
</view>
|
||||
</view>
|
||||
</swiper-item>
|
||||
<!-- #endif -->
|
||||
<block v-for="(item,index) in imgUrls" :key='index'>
|
||||
<swiper-item>
|
||||
<swiper-item v-if="videoline?index>=1:index>=0">
|
||||
<image :src="item" class="slide-image" />
|
||||
</swiper-item>
|
||||
</block>
|
||||
</swiper>
|
||||
<!-- #ifdef APP-PLUS -->
|
||||
<view v-if="!isPlay" style="width: 100%; height: 750rpx;">
|
||||
<video id="myVideo" :src='videoline' objectFit="cover" controls style="width:100%;height:100% "
|
||||
show-center-play-btn show-mute-btn="true" autoplay="true" auto-pause-if-navigate :custom-cache="false" :enable-progress-gesture="false" :poster="imgUrls[0]" @pause="videoPause"></video>
|
||||
</view>
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {setThemeColor} from '@/utils/setTheme.js'
|
||||
export default {
|
||||
props: {
|
||||
imgUrls: {
|
||||
@@ -44,6 +62,7 @@
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
urlDomain: this.$Cache.get("imgHost"),
|
||||
indicatorDots: true,
|
||||
circular: true,
|
||||
autoplay: true,
|
||||
@@ -52,21 +71,41 @@
|
||||
currents: "1",
|
||||
controls: true,
|
||||
isPlay:true,
|
||||
videoContext:''
|
||||
videoContext:'',
|
||||
indicatorBg:'#e93323',
|
||||
};
|
||||
},
|
||||
created(){
|
||||
let that = this;
|
||||
that.indicatorBg = setThemeColor();
|
||||
},
|
||||
mounted() {
|
||||
if(this.videoline){
|
||||
this.imgUrls.shift()
|
||||
}
|
||||
// #ifndef APP-PLUS
|
||||
this.videoContext = uni.createVideoContext('myVideo', this);
|
||||
// #endif
|
||||
},
|
||||
methods: {
|
||||
videoPause(e){
|
||||
// #ifdef APP-PLUS
|
||||
this.isPlay= true
|
||||
this.autoplay = true
|
||||
// #endif
|
||||
},
|
||||
bindPause: function() {
|
||||
|
||||
// #ifndef APP-PLUS
|
||||
this.videoContext.play();
|
||||
this.$set(this, 'controls', false)
|
||||
this.autoplay = false
|
||||
// #endif
|
||||
// #ifdef APP-PLUS
|
||||
this.isPlay= false
|
||||
this.videoContext = uni.createVideoContext('myVideo', this);
|
||||
this.videoContext.play();
|
||||
// #endif
|
||||
},
|
||||
change: function(e) {
|
||||
this.$set(this, 'currents', e.detail.current + 1);
|
||||
@@ -146,4 +185,4 @@
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
@@ -3,17 +3,26 @@
|
||||
<view class="product-window"
|
||||
:class="(attr.cartAttr === true ? 'on' : '') + ' ' + (iSbnt?'join':'') + ' ' + (iScart?'joinCart':'')">
|
||||
<view class="textpic acea-row row-between-wrapper">
|
||||
<view class="pictrue">
|
||||
<view class="pictrue" @click="showImg()">
|
||||
<image :src="attr.productSelect.image"></image>
|
||||
</view>
|
||||
<view class="text">
|
||||
<view class="line1">
|
||||
{{ attr.productSelect.storeName }}
|
||||
</view>
|
||||
<view class="money font-color">
|
||||
¥<text class="num">{{ attr.productSelect.price }}</text>
|
||||
<text class="stock" v-if='isShow'>库存: {{ attr.productSelect.stock }}</text>
|
||||
<text class='stock' v-if="limitNum">限量: {{attr.productSelect.quota}}</text>
|
||||
<view class="money">
|
||||
<view class="flex align-baseline">
|
||||
¥<text class="num">{{ attr.productSelect.price }}</text>
|
||||
<view class="flex pl-2"
|
||||
v-if="attr.productSelect.vipPrice && attr.productSelect.vipPrice > 0">
|
||||
<image :src="urlDomain+'crmebimage/perset/staticImg/vip_badge.png'" class="vip_icon"></image>
|
||||
<text class='vip_money skeleton-rect'>¥{{attr.productSelect.vipPrice}}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view>
|
||||
<text class="stock" v-if='isShow'>库存: {{ attr.productSelect.stock }}</text>
|
||||
<text class='stock' v-if="limitNum">限量: {{attr.productSelect.quota}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="iconfont icon-guanbi" @click="closeAttr"></view>
|
||||
@@ -40,27 +49,23 @@
|
||||
</view>
|
||||
<view class='item num'>
|
||||
<input type="number" v-model="attr.productSelect.cart_num"
|
||||
data-name="productSelect.cart_num"
|
||||
@input="bindCode(attr.productSelect.cart_num)"></input>
|
||||
data-name="productSelect.cart_num" @input="bindCode(attr.productSelect.cart_num)"
|
||||
maxlength="3"></input>
|
||||
</view>
|
||||
<view v-if="iSplus" class="item plus" :class="
|
||||
attr.productSelect.cart_num >= attr.productSelect.stock
|
||||
? 'on'
|
||||
: ''
|
||||
" @click="CartNumAdd">
|
||||
<view v-if="iSplus" class="item plus" :class="attr.productSelect.cart_num >= attr.productSelect.stock? 'on': ''" @click="CartNumAdd">
|
||||
+
|
||||
</view>
|
||||
<view v-else class='item plus'
|
||||
:class='(attr.productSelect.cart_num >= attr.productSelect.quota) || (attr.productSelect.cart_num >= attr.productSelect.stock) || (attr.productSelect.cart_num >= attr.productSelect.num)? "on":""'
|
||||
:class='(attr.productSelect.cart_num === onceNum) || (attr.productSelect.cart_num >= attr.productSelect.quota) || (attr.productSelect.cart_num >= attr.productSelect.stock) || (attr.productSelect.cart_num >= attr.productSelect.num)? "on":""'
|
||||
@click='CartNumAdd'>+</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="joinBnt bg-color" v-if="iSbnt && attr.productSelect.stock>0 &&attr.productSelect.quota>0"
|
||||
<view class="joinBnt bg_color" v-if="iSbnt && attr.productSelect.stock>0 &&attr.productSelect.quota>0"
|
||||
@click="goCat">我要参团</view>
|
||||
<view class="joinBnt on"
|
||||
v-else-if="(iSbnt && attr.productSelect.quota<=0)||(iSbnt &&attr.productSelect.stock<=0)">已售罄</view>
|
||||
<view class="joinBnt bg-color" v-if="iScart && attr.productSelect.stock" @click="goCat">确定</view>
|
||||
<view class="joinBnt bg_color" v-if="iScart && attr.productSelect.stock" @click="goCat">确定</view>
|
||||
<!-- <view class="joinBnt bg-color" v-if="iSbnt && attr.productSelect.stock && attr.productSelect.quota" @click="goCat">确定</view> -->
|
||||
<view class="joinBnt on" v-else-if="(iScart && !attr.productSelect.stock)">已售罄</view>
|
||||
</view>
|
||||
@@ -70,12 +75,16 @@
|
||||
|
||||
<script>
|
||||
export default {
|
||||
|
||||
props: {
|
||||
attr: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
},
|
||||
//一次最多可买几个,活动商品中使用
|
||||
onceNum: {
|
||||
type: Number,
|
||||
value: 1
|
||||
},
|
||||
limitNum: {
|
||||
type: Number,
|
||||
value: 0
|
||||
@@ -98,9 +107,11 @@
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {};
|
||||
return {
|
||||
urlDomain: this.$Cache.get("imgHost"),
|
||||
};
|
||||
},
|
||||
mounted() {},
|
||||
created() {},
|
||||
methods: {
|
||||
goCat: function() {
|
||||
this.$emit('goCat');
|
||||
@@ -128,10 +139,7 @@
|
||||
indexn: indexn
|
||||
});
|
||||
this.$set(this.attr.productAttr[indexw], 'index', this.attr.productAttr[indexw].attrValues[indexn]);
|
||||
let value = that
|
||||
.getCheckedValue()
|
||||
// .sort()
|
||||
.join(",");
|
||||
let value = that.getCheckedValue().join(",");
|
||||
that.$emit("ChangeAttr", value);
|
||||
|
||||
},
|
||||
@@ -147,7 +155,10 @@
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
},
|
||||
showImg() {
|
||||
this.$emit('getImg');
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -161,9 +172,10 @@
|
||||
background-color: #fff;
|
||||
z-index: 77;
|
||||
border-radius: 16rpx 16rpx 0 0;
|
||||
padding-bottom: 140rpx;
|
||||
padding-bottom: 100rpx;
|
||||
padding-bottom: calc(env(safe-area-inset-bottom) + 100rpx);
|
||||
transform: translate3d(0, 100%, 0);
|
||||
transition: all .3s cubic-bezier(.25, .5, .5, .9);
|
||||
transition: all .2s cubic-bezier(0, 0, .25, 1);
|
||||
}
|
||||
|
||||
.product-window.on {
|
||||
@@ -204,16 +216,18 @@
|
||||
|
||||
.product-window .textpic .text .money {
|
||||
font-size: 24rpx;
|
||||
margin-top: 40rpx;
|
||||
margin-top: 23rpx;
|
||||
@include price_color(theme);
|
||||
}
|
||||
|
||||
.product-window .textpic .text .money .num {
|
||||
font-family: PingFang SC;
|
||||
font-size: 36rpx;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.product-window .textpic .text .money .stock {
|
||||
color: #999;
|
||||
margin-left: 18rpx;
|
||||
}
|
||||
|
||||
.product-window .textpic .iconfont {
|
||||
@@ -225,7 +239,7 @@
|
||||
}
|
||||
|
||||
.product-window .rollTop {
|
||||
max-height: 500rpx;
|
||||
max-height: 62vh;
|
||||
overflow: auto;
|
||||
margin-top: 36rpx;
|
||||
}
|
||||
@@ -255,9 +269,9 @@
|
||||
}
|
||||
|
||||
.product-window .productWinList .item .listn .itemn.on {
|
||||
color: $theme-color;
|
||||
background: rgba(255, 244, 243, 1);
|
||||
border-color: $theme-color;
|
||||
@include main_color(theme);
|
||||
@include coupons_border_color(theme);
|
||||
@include cate-two-btn(theme);
|
||||
}
|
||||
|
||||
.product-window .productWinList .item .listn .itemn.limit {
|
||||
@@ -266,7 +280,8 @@
|
||||
}
|
||||
|
||||
.product-window .cart {
|
||||
margin-top: 36rpx;
|
||||
margin-top: 50rpx;
|
||||
margin-bottom: 30rpx;
|
||||
padding: 0 30rpx;
|
||||
}
|
||||
|
||||
@@ -277,7 +292,6 @@
|
||||
|
||||
.product-window .cart .carnum {
|
||||
height: 54rpx;
|
||||
margin-top: 24rpx;
|
||||
}
|
||||
|
||||
.product-window .cart .carnum view {
|
||||
@@ -337,8 +351,41 @@
|
||||
margin: 21rpx auto 0 auto;
|
||||
}
|
||||
|
||||
.align-baseline {
|
||||
align-items: baseline;
|
||||
}
|
||||
|
||||
.bg_color {
|
||||
@include main-bg_color(theme);
|
||||
}
|
||||
|
||||
.product-window .joinBnt.on {
|
||||
background-color: #bbb;
|
||||
color: #fff;
|
||||
}
|
||||
</style>
|
||||
|
||||
.align-center {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.vip_icon {
|
||||
width: 44rpx;
|
||||
height: 28rpx;
|
||||
}
|
||||
|
||||
.vip_money {
|
||||
background: #FFE7B9;
|
||||
border-radius: 4px;
|
||||
font-size: 22rpx;
|
||||
color: #333;
|
||||
line-height: 28rpx;
|
||||
text-align: center;
|
||||
padding: 0 6rpx;
|
||||
box-sizing: border-box;
|
||||
margin-left: -4rpx;
|
||||
}
|
||||
|
||||
.pl-2 {
|
||||
padding-left: 20rpx;
|
||||
}
|
||||
</style>
|
||||
@@ -1,110 +1,94 @@
|
||||
<template>
|
||||
<view class='promotionGood'>
|
||||
<block v-for="(item,index) in benefit" :key="index">
|
||||
<view class='item acea-row row-between-wrapper' @tap="goDetail(item)" hover-class="none">
|
||||
<view class='pictrue'>
|
||||
<image :src='item.image'></image>
|
||||
<span class="pictrue_log pictrue_log_class" v-if="item.activityH5 && item.activityH5.type === '1'">秒杀</span>
|
||||
<span class="pictrue_log pictrue_log_class" v-if="item.activityH5 && item.activityH5.type === '2'">砍价</span>
|
||||
<span class="pictrue_log pictrue_log_class" v-if="item.activityH5 && item.activityH5.type === '3'">拼团</span>
|
||||
</view>
|
||||
<view class='text'>
|
||||
<view class='name line1'>{{item.store_name}}</view>
|
||||
<view class='sp-money acea-row'>
|
||||
<view class='moneyCon'>促销价: ¥<text class='num'>{{item.price}}</text></view>
|
||||
</view>
|
||||
<view class='acea-row row-between-wrapper'>
|
||||
<view class='money'>日常价:¥{{item.ot_price}}</view>
|
||||
<view>仅剩:{{item.stock}}{{item.unit_name}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import {mapGetters} from "vuex";
|
||||
import { goShopDetail } from '@/libs/order.js'
|
||||
export default {
|
||||
computed: mapGetters(['uid']),
|
||||
props: {
|
||||
benefit: {
|
||||
type: Array,
|
||||
default: function() {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
goDetail(item){
|
||||
goShopDetail(item,this.uid).then(res=>{
|
||||
uni.navigateTo({
|
||||
url:`/pages/goods_details/index?id=${item.id}`
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang='scss'>
|
||||
.promotionGood {
|
||||
padding: 0 30rpx;
|
||||
}
|
||||
|
||||
.promotionGood .item {
|
||||
border-bottom: 1rpx solid #eee;
|
||||
height: 250rpx;
|
||||
}
|
||||
|
||||
.promotionGood .item .pictrue {
|
||||
position: relative;
|
||||
width: 188rpx;
|
||||
height: 188rpx;
|
||||
}
|
||||
|
||||
.promotionGood .item .pictrue image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 8rpx;
|
||||
}
|
||||
|
||||
.promotionGood .item .text {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
width: 472rpx;
|
||||
}
|
||||
|
||||
.promotionGood .item .text .name {
|
||||
font-size: 30rpx;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.promotionGood .item .text .sp-money {
|
||||
margin: 34rpx 0 20rpx 0;
|
||||
}
|
||||
|
||||
.promotionGood .item .text .sp-money .moneyCon {
|
||||
padding: 0 18rpx;
|
||||
background-color: red;
|
||||
height: 46rpx;
|
||||
line-height: 46rpx;
|
||||
background-image: linear-gradient(to right, #ff6248 0%, #ff3e1e 100%);
|
||||
font-size: 20rpx;
|
||||
color: #fff;
|
||||
border-radius: 24rpx 3rpx 24rpx 3rpx;
|
||||
}
|
||||
|
||||
.promotionGood .item .text .sp-money .moneyCon .num {
|
||||
font-size: 24rpx;
|
||||
}
|
||||
|
||||
.promotionGood .item .text .money {
|
||||
text-decoration: line-through;
|
||||
}
|
||||
</style>
|
||||
<template>
|
||||
<view class='promotionGood'>
|
||||
<block v-for="(item,index) in benefit.slice(0,6)" :key="index">
|
||||
<view class='item' @tap="goDetail(item)" hover-class="none">
|
||||
<view class='pictrue'>
|
||||
<image :src='item.image'></image>
|
||||
</view>
|
||||
<view class='money'>
|
||||
<text class="rmb">¥</text>
|
||||
<text class="price">{{item.price}}</text>
|
||||
<text class="ot-price">{{item.otPrice}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import animationType from '@/utils/animationType.js'
|
||||
export default {
|
||||
props: {
|
||||
benefit: {
|
||||
type: Array,
|
||||
default: function() {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
goDetail(item) {
|
||||
uni.navigateTo({
|
||||
animationType: animationType.type,
|
||||
animationDuration: animationType.duration,
|
||||
url: `/pages/goods/goods_details/index?id=${item.id}`
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang='scss'>
|
||||
.promotionGood {
|
||||
padding: 0 30rpx;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
padding: 15rpx 24rpx;
|
||||
|
||||
.item {
|
||||
width: 215rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
padding: 15rpx 9rpx;
|
||||
|
||||
.pictrue {
|
||||
height: 198rpx;
|
||||
border-radius: 12rpx;
|
||||
|
||||
image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 12rpx;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.money {
|
||||
font-size: 30rpx;
|
||||
margin-top: 10rpx;
|
||||
overflow:hidden;
|
||||
text-overflow:ellipsis;
|
||||
white-space:nowrap;
|
||||
.rmb {
|
||||
font-weight: bold;
|
||||
@include price_color(theme);
|
||||
font-size: 20rpx;
|
||||
}
|
||||
.price{
|
||||
@include price_color(theme);
|
||||
font-weight: bold;
|
||||
}
|
||||
.ot-price {
|
||||
color: #999;
|
||||
text-decoration: line-through;
|
||||
font-size: 20rpx;
|
||||
margin-left: 4rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,25 +6,44 @@
|
||||
<text class='iconfont icon-zhuangshixian lefticon'></text>
|
||||
</view>
|
||||
<view class='recommendList acea-row row-between-wrapper'>
|
||||
<view class='item' v-for="(item,index) in hostProduct" :key="index" hover-class='none' @tap="goDetail(item)">
|
||||
<view class='item' v-for="(item,index) in tempArr" :key="index" hover-class='none'
|
||||
@tap="goDetail(item)">
|
||||
<view class='pictrue'>
|
||||
<image :src='item.image'></image>
|
||||
<span class="pictrue_log_big pictrue_log_class" v-if="item.activityH5 && item.activityH5.type === '1'">秒杀</span>
|
||||
<span class="pictrue_log_big pictrue_log_class" v-if="item.activityH5 && item.activityH5.type === '2'">砍价</span>
|
||||
<span class="pictrue_log_big pictrue_log_class" v-if="item.activityH5 && item.activityH5.type === '3'">拼团</span>
|
||||
<view :style="{ backgroundImage: `url(${item.activityStyle})` }" class="border-picture"></view>
|
||||
<span class="pictrue_log_big pictrue_log_class"
|
||||
v-if="item.activityH5 && item.activityH5.type === '1'">秒杀</span>
|
||||
<span class="pictrue_log_big pictrue_log_class"
|
||||
v-if="item.activityH5 && item.activityH5.type === '2'">砍价</span>
|
||||
<span class="pictrue_log_big pictrue_log_class"
|
||||
v-if="item.activityH5 && item.activityH5.type === '3'">拼团</span>
|
||||
</view>
|
||||
<view class='name line1'>{{item.storeName}}</view>
|
||||
<view class='money font-color'>¥<text class='num'>{{item.price}}</text></view>
|
||||
<view class='money'>¥<text class='num'>{{item.price}}</text></view>
|
||||
</view>
|
||||
</view>
|
||||
<view class='loadingicon acea-row row-center-wrapper' :hidden='loading==false'>
|
||||
<text class='loading iconfont icon-jiazai'></text>
|
||||
</view>
|
||||
<view class="mores-txt flex" v-if="goodScroll">
|
||||
<text>我也是有底线的~</text>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {mapGetters} from "vuex";
|
||||
import { goShopDetail } from '@/libs/order.js'
|
||||
import {
|
||||
mapGetters
|
||||
} from "vuex";
|
||||
import {
|
||||
goShopDetail
|
||||
} from '@/libs/order.js'
|
||||
import animationType from '@/utils/animationType.js'
|
||||
import {
|
||||
getProductHot
|
||||
} from '@/api/store.js';
|
||||
export default {
|
||||
computed: mapGetters(['uid']),
|
||||
computed: mapGetters(['uid']),
|
||||
props: {
|
||||
hostProduct: {
|
||||
type: Array,
|
||||
@@ -33,17 +52,50 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.params.page = 1;
|
||||
this.goodScroll = false;
|
||||
this.tempArr = [];
|
||||
this.get_host_product();
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
||||
goodScroll: false,
|
||||
params: { //精品推荐分页
|
||||
page: 1,
|
||||
limit: 10
|
||||
},
|
||||
loading: false,
|
||||
tempArr: []
|
||||
};
|
||||
},
|
||||
|
||||
methods: {
|
||||
goDetail(item){
|
||||
goShopDetail(item,this.uid).then(res=>{
|
||||
/**
|
||||
* 获取我的推荐
|
||||
*/
|
||||
get_host_product: function() {
|
||||
if (this.goodScroll) return;
|
||||
this.loading = true
|
||||
getProductHot(
|
||||
this.params.page,
|
||||
this.params.limit
|
||||
).then((res) => {
|
||||
this.$set(this.params, 'page', this.params.page + 1);
|
||||
this.goodScroll = this.params.page > res.data.totalPage;
|
||||
this.tempArr = this.tempArr.concat(res.data.list || []);
|
||||
this.$emit('getRecommendLength', this.tempArr.length);
|
||||
this.loading = false
|
||||
}).catch(err => {
|
||||
this.loading = false
|
||||
});
|
||||
},
|
||||
goDetail(item) {
|
||||
goShopDetail(item, this.uid).then(res => {
|
||||
uni.navigateTo({
|
||||
url:`/pages/goods_details/index?id=${item.id}`
|
||||
animationType: animationType.type,
|
||||
animationDuration: animationType.duration,
|
||||
url: `/pages/goods/goods_details/index?id=${item.id}`
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -52,6 +104,19 @@
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.mores-txt {
|
||||
width: 100%;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 70rpx;
|
||||
color: #999;
|
||||
font-size: 24rpx;
|
||||
|
||||
.iconfont {
|
||||
margin-top: 2rpx;
|
||||
font-size: 20rpx;
|
||||
}
|
||||
}
|
||||
.recommend {
|
||||
background-color: #fff;
|
||||
}
|
||||
@@ -78,9 +143,6 @@
|
||||
|
||||
.recommend .recommendList {
|
||||
padding: 0 30rpx;
|
||||
/* #ifdef H5 */
|
||||
padding-bottom: 50rpx;
|
||||
/* #endif */
|
||||
}
|
||||
|
||||
.recommend .recommendList .item {
|
||||
@@ -106,13 +168,14 @@
|
||||
margin-top: 20rpx;
|
||||
}
|
||||
|
||||
.recommend .recommendList .item .money {
|
||||
.money {
|
||||
font-size: 20rpx;
|
||||
margin-top: 8rpx;
|
||||
font-weight: 600;
|
||||
@include price_color(theme);
|
||||
}
|
||||
|
||||
.recommend .recommendList .item .money .num {
|
||||
font-size: 28rpx;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
100
app/components/searchBox.vue
Normal file
100
app/components/searchBox.vue
Normal file
@@ -0,0 +1,100 @@
|
||||
<template>
|
||||
<view class="acea-row search-contain" :style="{'margin-top':searchTop+'px'}">
|
||||
<text class='iconfont icon-fanhui2' @click="toBack" v-if="toBackShow"></text>
|
||||
<view class='search-box acea-row row-between-wrapper' :style="[searchBoxStyle]">
|
||||
<text class='iconfont icon-sousuo2'></text>
|
||||
<input :value="searchVal" @confirm="inputSearch" type='text' confirm-type='search' name="search" placeholder='点击搜索商品' placeholder-class='placeholder' maxlength="20"></input>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
//是否展示返回按钮
|
||||
toBackShow: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
searchValue:{
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
data(){
|
||||
return{
|
||||
searchVal:'',
|
||||
searchTop:0,
|
||||
searchRight:0,
|
||||
searchHeight:0,
|
||||
statusWidth:0,
|
||||
}
|
||||
},
|
||||
watch:{
|
||||
searchValue(val){
|
||||
this.searchVal=val
|
||||
}
|
||||
},
|
||||
computed:{
|
||||
searchBoxStyle(){
|
||||
return {
|
||||
height:this.searchHeight + 'px',
|
||||
flex:1,
|
||||
marginRight:this.statusWidth + this.searchRight+'px',
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
const res = uni.getMenuButtonBoundingClientRect()
|
||||
this.searchTop=uni.getMenuButtonBoundingClientRect().top
|
||||
const statusRight = res.right //胶囊右边界坐标
|
||||
const jnHeight = res.height //胶囊高度
|
||||
this.statusWidth= res.width
|
||||
this.searchHeight=jnHeight
|
||||
//搜索框宽度计算
|
||||
uni.getSystemInfo({
|
||||
success:res=>{
|
||||
this.searchRight=res.windowWidth-statusRight
|
||||
}
|
||||
})
|
||||
},
|
||||
methods:{
|
||||
inputSearch(e){
|
||||
this.$emit('searchChange',e)
|
||||
},
|
||||
toBack(){
|
||||
uni.navigateBack()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.search-contain{
|
||||
padding: 0 20rpx 10rpx 0;
|
||||
}
|
||||
.search-box {
|
||||
margin-left: 16rpx;
|
||||
background-color: #f7f7f7;
|
||||
border-radius: 33rpx;
|
||||
padding: 0 35rpx;
|
||||
box-sizing: border-box;
|
||||
height: 66rpx;
|
||||
}
|
||||
.icon-fanhui2{
|
||||
line-height: 66rpx;
|
||||
}
|
||||
.search-box input {
|
||||
width: 85%;
|
||||
font-size: 26rpx;
|
||||
}
|
||||
|
||||
.search-box .placeholder {
|
||||
color: #bbb;
|
||||
}
|
||||
|
||||
.search-box .iconfont {
|
||||
color: #000;
|
||||
font-size: 35rpx;
|
||||
}
|
||||
</style>
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<view v-if="shareInfoStatus" class="poster-first">
|
||||
<view class="mask-share">
|
||||
<image src="/static/images/share-info.png" @click="shareInfoClose" @touchmove.stop.prevent="false"></image>
|
||||
<image :src="urlDomain+'crmebimage/perset/staticImg/share-info.png'" @click="shareInfoClose" @touchmove.stop.prevent="false"></image>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
@@ -16,7 +16,9 @@ export default {
|
||||
}
|
||||
},
|
||||
data: function() {
|
||||
return {};
|
||||
return {
|
||||
urlDomain: this.$Cache.get("imgHost"),
|
||||
};
|
||||
},
|
||||
mounted: function() {},
|
||||
methods: {
|
||||
|
||||
@@ -1,57 +1,102 @@
|
||||
<template>
|
||||
<view class='sharing-packets' :class='sharePacket.isState==true?"on":""'>
|
||||
<view class='iconfont icon-guanbi' @click="closeShare"></view>
|
||||
<view class='line'></view>
|
||||
<view class='sharing-con' @click='goShare'>
|
||||
<image src='../../static/images/red-packets.png'></image>
|
||||
<view class='text font-color'>
|
||||
<view>会员分享返</view>
|
||||
<view class='money'><text class='label'>¥</text>{{sharePacket.priceName}}</view>
|
||||
<view class='tip'>下单即返佣金</view>
|
||||
<view class='shareBut'>立即分享</view>
|
||||
<view class='sharing-packets' :style="{ top: top + 'px'}"
|
||||
:class="sharePacket.touchstart?'hide_left':'' "
|
||||
@touchmove.stop.prevent="setTouchMove" @click="handleleterClick()" v-if="!sharePacket.isState">
|
||||
<view class='sharing-con' :style="{backgroundImage:'url('+imgHost+ '/' + picBg+')'}">
|
||||
<view class='text' >
|
||||
<view class="main_color">会员分享返</view>
|
||||
<view class='money price'><text class='label'>¥</text>{{sharePacket.priceName}}</view>
|
||||
<view class='tip'>下单即返佣金</view>
|
||||
<view class='shareBut'>立即分享</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<!-- -->
|
||||
<script>
|
||||
import { getImageDomain } from '@/api/api.js'
|
||||
export default {
|
||||
|
||||
props: {
|
||||
sharePacket: {
|
||||
type: Object,
|
||||
default: function(){
|
||||
return {isState: true,priceName:''}
|
||||
}
|
||||
}
|
||||
sharePacket: {
|
||||
type: Object,
|
||||
default: function(){
|
||||
return {isState: true,priceName:'',touchstart:false}
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
||||
imgHost:'',
|
||||
picBg:'crmebimage/perset/share_tip/share_tip1.png',
|
||||
top: "260",
|
||||
};
|
||||
},
|
||||
|
||||
created(){
|
||||
let that = this;
|
||||
uni.getStorage({
|
||||
key: 'theme',
|
||||
success: function (res) {
|
||||
switch (res.data) {
|
||||
case 'theme1':
|
||||
that.picBg = 'crmebimage/perset/share_tip/share_tip1.png';
|
||||
break;
|
||||
case 'theme2':
|
||||
that.picBg = 'crmebimage/perset/share_tip/share_tip2.png';
|
||||
break;
|
||||
case 'theme3':
|
||||
that.picBg = 'crmebimage/perset/share_tip/share_tip3.png';
|
||||
break;
|
||||
case 'theme4':
|
||||
that.picBg = 'crmebimage/perset/share_tip/share_tip4.png';
|
||||
break;
|
||||
case 'theme5':
|
||||
that.picBg = 'crmebimage/perset/share_tip/share_tip5.png';
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
getImageDomain().then(res=>{
|
||||
that.$set(that,'imgHost',res.data);
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
closeShare:function(){
|
||||
this.$emit('closeChange');
|
||||
},
|
||||
goShare:function(){
|
||||
this.$emit('listenerActionSheet');
|
||||
}
|
||||
}
|
||||
goShare:function(){
|
||||
this.$emit('listenerActionSheet');
|
||||
},
|
||||
setTouchMove(e) {
|
||||
var that = this;
|
||||
if (e.touches[0].clientY < 545 && e.touches[0].clientY > 66) {
|
||||
that.top = e.touches[0].clientY
|
||||
}
|
||||
},
|
||||
handleleterClick(){
|
||||
if(this.sharePacket.touchstart){
|
||||
this.$emit('showShare',false)
|
||||
}else{
|
||||
// this.$emit('showShare',true)
|
||||
this.goShare()
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.sharing-packets{position:fixed;left:30rpx;bottom:200rpx;z-index:5;transition:all 0.3s ease-in-out 0s;opacity:1;transform: scale(1);}
|
||||
.sharing-packets.on{transform: scale(0);opacity:0;}
|
||||
.sharing-packets{
|
||||
position:fixed;left:30rpx;z-index:99;transition: all .2s linear;
|
||||
&.hide_left{
|
||||
transition: all .2s linear;left: -110rpx;
|
||||
transform: scale(.6);
|
||||
}
|
||||
}
|
||||
.sharing-packets .iconfont{width:44rpx;height:44rpx;border-radius:50%;text-align:center;line-height:44rpx;background-color:#999;font-size:20rpx;color:#fff;margin:0 auto;box-sizing:border-box;padding-left:1px;}
|
||||
.sharing-packets .line{width:2rpx;height:40rpx;background-color:#999;margin:0 auto;}
|
||||
.sharing-packets .sharing-con{width:187rpx;height:210rpx;position:relative;}
|
||||
.sharing-packets .sharing-con image{width:100%;height:100%;}
|
||||
.sharing-packets .sharing-con{width:187rpx;height:210rpx;position:relative;background-size: cover;}
|
||||
.sharing-packets .sharing-con .text{position:absolute;top:30rpx;font-size:20rpx;width:100%;text-align:center;}
|
||||
.sharing-packets .sharing-con .text .money{font-size:32rpx;font-weight:bold;margin-top:5rpx;}
|
||||
.sharing-packets .sharing-con .text .money .label{font-size:20rpx;}
|
||||
.sharing-packets .sharing-con .text .tip{font-size:18rpx;color:#999;margin-top:5rpx;}
|
||||
.sharing-packets .sharing-con .text .shareBut{font-size:22rpx;color:#fff;margin-top:18rpx;height:50rpx;line-height:50rpx;}
|
||||
.sharing-packets .sharing-con .text .shareBut{font-size:22rpx;color:#fff;margin-top:28rpx;height:50rpx;line-height:50rpx;}
|
||||
.main_color{@include main_color(theme);}
|
||||
.price{@include price_color(theme);}
|
||||
</style>
|
||||
|
||||
190
app/components/skeleton/index.vue
Normal file
190
app/components/skeleton/index.vue
Normal file
@@ -0,0 +1,190 @@
|
||||
<template>
|
||||
<view v-if="show"
|
||||
:style="{width: systemInfo.width + 'px', height: systemInfo.height + 'px', backgroundColor: bgcolor, position: 'absolute', left: 0, top: 0, zIndex: 9998}">
|
||||
<view v-for="(item,rect_idx) in skeletonRectLists" :key="rect_idx + 'rect'"
|
||||
:class="[loading == 'chiaroscuro' ? 'chiaroscuro' : '']"
|
||||
:style="{width: item.width + 'px', height: item.height + 'px', backgroundColor: 'rgb(194, 207, 214,.3)', position: 'absolute', left: item.left + 'px', top: item.top + 'px'}">
|
||||
</view>
|
||||
<view v-for="(item,circle_idx) in skeletonCircleLists" :key="circle_idx + 'circle'"
|
||||
:class="loading == 'chiaroscuro' ? 'chiaroscuro' : ''"
|
||||
:style="{width: item.width + 'px', height: item.height + 'px', backgroundColor: 'rgb(194, 207, 214,.3)', borderRadius: item.width + 'px', position: 'absolute', left: item.left + 'px', top: item.top + 'px'}">
|
||||
</view>
|
||||
<view class="spinbox" v-if="loading == 'spin'">
|
||||
<view class="spin"></view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "skeleton",
|
||||
props: {
|
||||
bgcolor: {
|
||||
type: String,
|
||||
value: '#FFF'
|
||||
},
|
||||
selector: {
|
||||
type: String,
|
||||
value: 'skeleton'
|
||||
},
|
||||
loading: {
|
||||
type: String,
|
||||
value: 'spin'
|
||||
},
|
||||
show: {
|
||||
type: Boolean,
|
||||
value: false
|
||||
},
|
||||
isNodes: {
|
||||
type: Number,
|
||||
value: false
|
||||
} //控制什么时候开始抓取元素节点,只要数值改变就重新抓取
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
loadingAni: ['spin', 'chiaroscuro'],
|
||||
systemInfo: {},
|
||||
skeletonRectLists: [],
|
||||
skeletonCircleLists: []
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
isNodes(val) {
|
||||
this.readyAction();
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.attachedAction();
|
||||
},
|
||||
methods: {
|
||||
attachedAction: function() {
|
||||
//默认的首屏宽高,防止内容闪现
|
||||
const systemInfo = uni.getSystemInfoSync();
|
||||
this.systemInfo = {
|
||||
width: systemInfo.windowWidth,
|
||||
height: systemInfo.windowHeight
|
||||
};
|
||||
this.loading = this.loadingAni.includes(this.loading) ? this.loading : 'spin';
|
||||
},
|
||||
readyAction: function() {
|
||||
const that = this;
|
||||
//绘制背景
|
||||
uni.createSelectorQuery().selectAll(`.${this.selector}`).boundingClientRect().exec(function(res) {
|
||||
if(res[0].length>0)
|
||||
that.systemInfo.height = res[0][0].height + res[0][0].top;
|
||||
});
|
||||
|
||||
//绘制矩形
|
||||
this.rectHandle();
|
||||
|
||||
//绘制圆形
|
||||
this.radiusHandle();
|
||||
},
|
||||
rectHandle: function() {
|
||||
const that = this;
|
||||
|
||||
//绘制不带样式的节点
|
||||
uni.createSelectorQuery().selectAll(`.${this.selector}-rect`).boundingClientRect().exec(function(res) {
|
||||
that.skeletonRectLists = res[0];
|
||||
});
|
||||
|
||||
},
|
||||
radiusHandle() {
|
||||
const that = this;
|
||||
|
||||
uni.createSelectorQuery().selectAll(`.${this.selector}-radius`).boundingClientRect().exec(function(res) {
|
||||
that.skeletonCircleLists = res[0];
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.spinbox {
|
||||
position: fixed;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
z-index: 9999
|
||||
}
|
||||
|
||||
.spin {
|
||||
display: inline-block;
|
||||
width: 64rpx;
|
||||
height: 64rpx;
|
||||
}
|
||||
|
||||
.spin:after {
|
||||
content: " ";
|
||||
display: block;
|
||||
width: 46rpx;
|
||||
height: 46rpx;
|
||||
margin: 1rpx;
|
||||
border-radius: 50%;
|
||||
border: 5rpx solid #409eff;
|
||||
border-color: #409eff transparent #409eff transparent;
|
||||
animation: spin 1.2s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
.chiaroscuro {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgb(194, 207, 214);
|
||||
animation-duration: 2s;
|
||||
animation-name: blink;
|
||||
animation-iteration-count: infinite;
|
||||
}
|
||||
|
||||
@keyframes blink {
|
||||
0% {
|
||||
opacity: .4;
|
||||
}
|
||||
|
||||
50% {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: .4;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes flush {
|
||||
0% {
|
||||
left: -100%;
|
||||
}
|
||||
|
||||
50% {
|
||||
left: 0;
|
||||
}
|
||||
|
||||
100% {
|
||||
left: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.shine {
|
||||
animation: flush 2s linear infinite;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
background: linear-gradient(to left,
|
||||
rgba(255, 255, 255, 0) 0%,
|
||||
rgba(255, 255, 255, .85) 50%,
|
||||
rgba(255, 255, 255, 0) 100%)
|
||||
}
|
||||
</style>
|
||||
@@ -1,197 +0,0 @@
|
||||
<template>
|
||||
<view class="navTabBox">
|
||||
<view class="longTab">
|
||||
<scroll-view scroll-x="true" style="white-space: nowrap; display: flex;" scroll-with-animation :scroll-left="tabLeft" show-scrollbar="true">
|
||||
<view class="longItem line1" :style='"width:"+isWidth+"px"' :data-index="index" :class="index===tabClick?'click':''" v-for="(item,index) in tabTitle" :key="index" :id="'id'+index" @click="longClick(index)">{{item.name}}</view>
|
||||
<view class="underlineBox" :style='"transform:translateX("+isLeft+"px);width:"+isWidth+"px"'>
|
||||
<view class="underline"></view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
<view class="child-box" v-if="tabClick>0 && tabTitle[tabClick].child?tabTitle[tabClick].child.length>0:0">
|
||||
<scroll-view scroll-x="true">
|
||||
<view class="wrapper">
|
||||
<view v-for="(item,index) in tabTitle[tabClick].child?tabTitle[tabClick].child:[]" :key="index" class="child-item" :class="{on:index == childIndex}" @click="childTab(tabClick,index)">
|
||||
<image :src="item.extra" mode="" :style="{'background-color':item.extra?'none':'#f7f7f7'}"></image>
|
||||
<view class="txt line1">{{item.name}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
<!-- <image :src="item.extra" mode="" :style="{'background-color':(item.extra&&item.extra.indexOf('https://') > -1) || (item.extra&&item.extra.indexOf('http://') > -1)?'none':'#f7f7f7'}"></image> -->
|
||||
<!-- <view class="child-box" v-if="tabClick>0 && tabTitle[tabClick].child?tabTitle[tabClick].child.length>0:0">
|
||||
<scroll-view scroll-x="true" style="white-space: nowrap; display: flex;align-items: center; height: 100%;" scroll-with-animation :scroll-left="tabLeft" show-scrollbar="false">
|
||||
<view class="wrapper">
|
||||
<view v-for="(item,index) in tabTitle[tabClick].child?tabTitle[tabClick].child:[]" :key="index" class="child-item" :class="{on:index == childIndex}" @click="childTab(tabClick,index)">
|
||||
<image :src="item.extra" mode="" :style="{'background-color':item.extra?'none':'#f7f7f7'}"></image>
|
||||
<view class="txt line1">{{item.name}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view> -->
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
getProductslist,
|
||||
getProductHot
|
||||
} from '@/api/store.js';
|
||||
export default {
|
||||
name: 'navTab',
|
||||
props: {
|
||||
tabTitle: {
|
||||
type: Array,
|
||||
default: []
|
||||
}
|
||||
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
tabClick: 0, //导航栏被点击
|
||||
isLeft: 0, //导航栏下划线位置
|
||||
isWidth: 0, //每个导航栏占位
|
||||
tabLeft:0,
|
||||
swiperIndex:0,
|
||||
childIndex:0,
|
||||
childID:0
|
||||
};
|
||||
},
|
||||
created() {
|
||||
|
||||
var that = this
|
||||
// 获取设备宽度
|
||||
uni.getSystemInfo({
|
||||
success(e) {
|
||||
that.isWidth = e.windowWidth / 5
|
||||
}
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
// 导航栏点击
|
||||
longClick(index){
|
||||
this.childIndex = 0;
|
||||
if(this.tabTitle.length>5){
|
||||
var tempIndex = index - 2;
|
||||
tempIndex = tempIndex<=0 ? 0 : tempIndex;
|
||||
this.tabLeft = (index-2) * this.isWidth //设置下划线位置
|
||||
}
|
||||
this.tabClick = index //设置导航点击了哪一个
|
||||
this.isLeft = index * this.isWidth //设置下划线位置
|
||||
let obj = {
|
||||
type:'big', //大标题
|
||||
index:index
|
||||
}
|
||||
this.parentEmit(obj)
|
||||
this.$parent.currentTab = index //设置swiper的第几页
|
||||
},
|
||||
// 导航子类点击
|
||||
childTab(tabClick,index){
|
||||
this.childIndex = index
|
||||
let obj = {
|
||||
parentIndex:tabClick,
|
||||
childIndex:index,
|
||||
type:'small' //小标题
|
||||
}
|
||||
this.parentEmit(obj)
|
||||
},
|
||||
parentEmit(data){
|
||||
this.$emit('changeTab', data);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.navTabBox {
|
||||
width: 100%;
|
||||
color: rgba(255, 255, 255, 1);
|
||||
.click {
|
||||
color: white;
|
||||
}
|
||||
.longTab {
|
||||
width: 100%;
|
||||
/* #ifdef H5 */
|
||||
padding-bottom: 20rpx;
|
||||
/* #endif */
|
||||
/* #ifdef MP */
|
||||
padding-top: 12rpx;
|
||||
padding-bottom: 12rpx;
|
||||
/* #endif */
|
||||
.longItem{
|
||||
height: 50upx;
|
||||
display: inline-block;
|
||||
line-height: 50upx;
|
||||
text-align: center;
|
||||
font-size: 30rpx;
|
||||
&.click{
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
.underlineBox {
|
||||
height: 3px;
|
||||
width: 20%;
|
||||
display: flex;
|
||||
align-content: center;
|
||||
justify-content: center;
|
||||
transition: .5s;
|
||||
.underline {
|
||||
width: 33rpx;
|
||||
height: 4rpx;
|
||||
background-color: white;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.child-box{
|
||||
width: 100%;
|
||||
position: relative;
|
||||
// height: 152rpx;
|
||||
background-color: #fff;
|
||||
/* #ifdef H5 */
|
||||
box-shadow: 0 2px 5px 1px rgba(0, 0, 0, 0.02);
|
||||
/* #endif */
|
||||
/* #ifdef MP */
|
||||
box-shadow: 0 2rpx 3rpx 1rpx #f9f9f9;
|
||||
/* #endif */
|
||||
|
||||
.wrapper{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 20rpx 0;
|
||||
background: #fff;
|
||||
/* #ifdef H5 */
|
||||
//box-shadow: 0 2px 5px 1px rgba(0, 0, 0, 0.06);
|
||||
/* #endif */
|
||||
}
|
||||
.child-item{
|
||||
flex-shrink: 0;
|
||||
width:140rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-left: 10rpx;
|
||||
image{
|
||||
width: 90rpx;
|
||||
height: 90rpx;
|
||||
border-radius: 50%;
|
||||
}
|
||||
.txt{
|
||||
font-size: 24rpx;
|
||||
color: #282828;
|
||||
text-align: center;
|
||||
margin-top: 10rpx;
|
||||
width: 100%;
|
||||
}
|
||||
&.on{
|
||||
image{
|
||||
border: 1px solid $theme-color-opacity;
|
||||
}
|
||||
.txt{
|
||||
color: $theme-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,165 +0,0 @@
|
||||
<template>
|
||||
<canvas v-if="canvasId" :id="canvasId" :canvasId="canvasId" :style="{'width':cWidth*pixelRatio+'px','height':cHeight*pixelRatio+'px', 'transform': 'scale('+(1/pixelRatio)+')','margin-left':-cWidth*(pixelRatio-1)/2+'px','margin-top':-cHeight*(pixelRatio-1)/2+'px'}"
|
||||
@touchstart="touchStart" @touchmove="touchMove" @touchend="touchEnd" @error="error">
|
||||
</canvas>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import uCharts from './u-charts.js';
|
||||
var canvases = {};
|
||||
|
||||
export default {
|
||||
props: {
|
||||
chartType: {
|
||||
required: true,
|
||||
type: String,
|
||||
default: 'column'
|
||||
},
|
||||
opts: {
|
||||
required: true,
|
||||
type: Object,
|
||||
default () {
|
||||
return null;
|
||||
},
|
||||
},
|
||||
canvasId: {
|
||||
type: String,
|
||||
default: 'u-canvas',
|
||||
},
|
||||
cWidth: {
|
||||
default: 375,
|
||||
},
|
||||
cHeight: {
|
||||
default: 250,
|
||||
},
|
||||
pixelRatio: {
|
||||
type: Number,
|
||||
default: 1,
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.init();
|
||||
},
|
||||
methods: {
|
||||
init() {
|
||||
switch (this.chartType) {
|
||||
case 'column':
|
||||
this.initColumnChart();
|
||||
break;
|
||||
case 'line':
|
||||
this.initLineChart();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
},
|
||||
initColumnChart() {
|
||||
canvases[this.canvasId] = new uCharts({
|
||||
$this: this,
|
||||
canvasId: this.canvasId,
|
||||
type: 'column',
|
||||
legend: true,
|
||||
fontSize: 11,
|
||||
background: '#FFFFFF',
|
||||
pixelRatio: this.pixelRatio,
|
||||
animation: true,
|
||||
categories: this.opts.categories,
|
||||
series: this.opts.series,
|
||||
enableScroll: true,
|
||||
xAxis: {
|
||||
disableGrid: true,
|
||||
itemCount: 4,
|
||||
scrollShow: true
|
||||
},
|
||||
yAxis: {
|
||||
//disabled:true
|
||||
},
|
||||
dataLabel: true,
|
||||
width: this.cWidth * this.pixelRatio,
|
||||
height: this.cHeight * this.pixelRatio,
|
||||
extra: {
|
||||
column: {
|
||||
type: 'group',
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
initLineChart() {
|
||||
canvases[this.canvasId] = new uCharts({
|
||||
$this: this,
|
||||
canvasId: this.canvasId,
|
||||
type: 'line',
|
||||
fontSize: 11,
|
||||
legend: true,
|
||||
dataLabel: false,
|
||||
dataPointShape: true,
|
||||
background: '#FFFFFF',
|
||||
pixelRatio: this.pixelRatio,
|
||||
categories: this.opts.categories,
|
||||
series: this.opts.series,
|
||||
animation: true,
|
||||
enableScroll: true,
|
||||
xAxis: {
|
||||
type: 'grid',
|
||||
gridColor: '#CCCCCC',
|
||||
gridType: 'dash',
|
||||
dashLength: 8,
|
||||
itemCount: 4,
|
||||
scrollShow: true
|
||||
},
|
||||
yAxis: {
|
||||
gridType: 'dash',
|
||||
gridColor: '#CCCCCC',
|
||||
dashLength: 8,
|
||||
splitNumber: 5,
|
||||
min: 10,
|
||||
max: 180,
|
||||
format: (val) => {
|
||||
return val.toFixed(0) + '元'
|
||||
}
|
||||
},
|
||||
width: this.cWidth * this.pixelRatio,
|
||||
height: this.cHeight * this.pixelRatio,
|
||||
extra: {
|
||||
line: {
|
||||
type: 'straight'
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
// 这里仅作为示例传入两个参数,cid为canvas-id,newdata为更新的数据,需要更多参数请自行修改
|
||||
changeData(cid,newdata) {
|
||||
canvases[cid].updateData({
|
||||
series: newdata.series,
|
||||
categories: newdata.categories
|
||||
});
|
||||
},
|
||||
touchStart(e) {
|
||||
canvases[this.canvasId].showToolTip(e, {
|
||||
format: function(item, category) {
|
||||
return category + ' ' + item.name + ':' + item.data
|
||||
}
|
||||
});
|
||||
canvases[this.canvasId].scrollStart(e);
|
||||
},
|
||||
touchMove(e) {
|
||||
canvases[this.canvasId].scroll(e);
|
||||
},
|
||||
touchEnd(e) {
|
||||
canvases[this.canvasId].scrollEnd(e);
|
||||
},
|
||||
error(e) {
|
||||
console.log(e)
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.charts {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
flex: 1;
|
||||
background-color: #FFFFFF;
|
||||
}
|
||||
</style>
|
||||
File diff suppressed because it is too large
Load Diff
1
app/components/ucharts/ucharts.min.js
vendored
1
app/components/ucharts/ucharts.min.js
vendored
File diff suppressed because one or more lines are too long
@@ -1,546 +0,0 @@
|
||||
/**
|
||||
* @1900-2100区间内的公历、农历互转
|
||||
* @charset UTF-8
|
||||
* @github https://github.com/jjonline/calendar.js
|
||||
* @Author Jea杨(JJonline@JJonline.Cn)
|
||||
* @Time 2014-7-21
|
||||
* @Time 2016-8-13 Fixed 2033hex、Attribution Annals
|
||||
* @Time 2016-9-25 Fixed lunar LeapMonth Param Bug
|
||||
* @Time 2017-7-24 Fixed use getTerm Func Param Error.use solar year,NOT lunar year
|
||||
* @Version 1.0.3
|
||||
* @公历转农历:calendar.solar2lunar(1987,11,01); //[you can ignore params of prefix 0]
|
||||
* @农历转公历:calendar.lunar2solar(1987,09,10); //[you can ignore params of prefix 0]
|
||||
*/
|
||||
/* eslint-disable */
|
||||
var calendar = {
|
||||
|
||||
/**
|
||||
* 农历1900-2100的润大小信息表
|
||||
* @Array Of Property
|
||||
* @return Hex
|
||||
*/
|
||||
lunarInfo: [0x04bd8, 0x04ae0, 0x0a570, 0x054d5, 0x0d260, 0x0d950, 0x16554, 0x056a0, 0x09ad0, 0x055d2, // 1900-1909
|
||||
0x04ae0, 0x0a5b6, 0x0a4d0, 0x0d250, 0x1d255, 0x0b540, 0x0d6a0, 0x0ada2, 0x095b0, 0x14977, // 1910-1919
|
||||
0x04970, 0x0a4b0, 0x0b4b5, 0x06a50, 0x06d40, 0x1ab54, 0x02b60, 0x09570, 0x052f2, 0x04970, // 1920-1929
|
||||
0x06566, 0x0d4a0, 0x0ea50, 0x06e95, 0x05ad0, 0x02b60, 0x186e3, 0x092e0, 0x1c8d7, 0x0c950, // 1930-1939
|
||||
0x0d4a0, 0x1d8a6, 0x0b550, 0x056a0, 0x1a5b4, 0x025d0, 0x092d0, 0x0d2b2, 0x0a950, 0x0b557, // 1940-1949
|
||||
0x06ca0, 0x0b550, 0x15355, 0x04da0, 0x0a5b0, 0x14573, 0x052b0, 0x0a9a8, 0x0e950, 0x06aa0, // 1950-1959
|
||||
0x0aea6, 0x0ab50, 0x04b60, 0x0aae4, 0x0a570, 0x05260, 0x0f263, 0x0d950, 0x05b57, 0x056a0, // 1960-1969
|
||||
0x096d0, 0x04dd5, 0x04ad0, 0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540, 0x0b6a0, 0x195a6, // 1970-1979
|
||||
0x095b0, 0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50, 0x06d40, 0x0af46, 0x0ab60, 0x09570, // 1980-1989
|
||||
0x04af5, 0x04970, 0x064b0, 0x074a3, 0x0ea50, 0x06b58, 0x05ac0, 0x0ab60, 0x096d5, 0x092e0, // 1990-1999
|
||||
0x0c960, 0x0d954, 0x0d4a0, 0x0da50, 0x07552, 0x056a0, 0x0abb7, 0x025d0, 0x092d0, 0x0cab5, // 2000-2009
|
||||
0x0a950, 0x0b4a0, 0x0baa4, 0x0ad50, 0x055d9, 0x04ba0, 0x0a5b0, 0x15176, 0x052b0, 0x0a930, // 2010-2019
|
||||
0x07954, 0x06aa0, 0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, 0x0a4e0, 0x0d260, 0x0ea65, 0x0d530, // 2020-2029
|
||||
0x05aa0, 0x076a3, 0x096d0, 0x04afb, 0x04ad0, 0x0a4d0, 0x1d0b6, 0x0d250, 0x0d520, 0x0dd45, // 2030-2039
|
||||
0x0b5a0, 0x056d0, 0x055b2, 0x049b0, 0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20, 0x0ada0, // 2040-2049
|
||||
/** Add By JJonline@JJonline.Cn**/
|
||||
0x14b63, 0x09370, 0x049f8, 0x04970, 0x064b0, 0x168a6, 0x0ea50, 0x06b20, 0x1a6c4, 0x0aae0, // 2050-2059
|
||||
0x0a2e0, 0x0d2e3, 0x0c960, 0x0d557, 0x0d4a0, 0x0da50, 0x05d55, 0x056a0, 0x0a6d0, 0x055d4, // 2060-2069
|
||||
0x052d0, 0x0a9b8, 0x0a950, 0x0b4a0, 0x0b6a6, 0x0ad50, 0x055a0, 0x0aba4, 0x0a5b0, 0x052b0, // 2070-2079
|
||||
0x0b273, 0x06930, 0x07337, 0x06aa0, 0x0ad50, 0x14b55, 0x04b60, 0x0a570, 0x054e4, 0x0d160, // 2080-2089
|
||||
0x0e968, 0x0d520, 0x0daa0, 0x16aa6, 0x056d0, 0x04ae0, 0x0a9d4, 0x0a2d0, 0x0d150, 0x0f252, // 2090-2099
|
||||
0x0d520], // 2100
|
||||
|
||||
/**
|
||||
* 公历每个月份的天数普通表
|
||||
* @Array Of Property
|
||||
* @return Number
|
||||
*/
|
||||
solarMonth: [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31],
|
||||
|
||||
/**
|
||||
* 天干地支之天干速查表
|
||||
* @Array Of Property trans["甲","乙","丙","丁","戊","己","庚","辛","壬","癸"]
|
||||
* @return Cn string
|
||||
*/
|
||||
Gan: ['\u7532', '\u4e59', '\u4e19', '\u4e01', '\u620a', '\u5df1', '\u5e9a', '\u8f9b', '\u58ec', '\u7678'],
|
||||
|
||||
/**
|
||||
* 天干地支之地支速查表
|
||||
* @Array Of Property
|
||||
* @trans["子","丑","寅","卯","辰","巳","午","未","申","酉","戌","亥"]
|
||||
* @return Cn string
|
||||
*/
|
||||
Zhi: ['\u5b50', '\u4e11', '\u5bc5', '\u536f', '\u8fb0', '\u5df3', '\u5348', '\u672a', '\u7533', '\u9149', '\u620c', '\u4ea5'],
|
||||
|
||||
/**
|
||||
* 天干地支之地支速查表<=>生肖
|
||||
* @Array Of Property
|
||||
* @trans["鼠","牛","虎","兔","龙","蛇","马","羊","猴","鸡","狗","猪"]
|
||||
* @return Cn string
|
||||
*/
|
||||
Animals: ['\u9f20', '\u725b', '\u864e', '\u5154', '\u9f99', '\u86c7', '\u9a6c', '\u7f8a', '\u7334', '\u9e21', '\u72d7', '\u732a'],
|
||||
|
||||
/**
|
||||
* 24节气速查表
|
||||
* @Array Of Property
|
||||
* @trans["小寒","大寒","立春","雨水","惊蛰","春分","清明","谷雨","立夏","小满","芒种","夏至","小暑","大暑","立秋","处暑","白露","秋分","寒露","霜降","立冬","小雪","大雪","冬至"]
|
||||
* @return Cn string
|
||||
*/
|
||||
solarTerm: ['\u5c0f\u5bd2', '\u5927\u5bd2', '\u7acb\u6625', '\u96e8\u6c34', '\u60ca\u86f0', '\u6625\u5206', '\u6e05\u660e', '\u8c37\u96e8', '\u7acb\u590f', '\u5c0f\u6ee1', '\u8292\u79cd', '\u590f\u81f3', '\u5c0f\u6691', '\u5927\u6691', '\u7acb\u79cb', '\u5904\u6691', '\u767d\u9732', '\u79cb\u5206', '\u5bd2\u9732', '\u971c\u964d', '\u7acb\u51ac', '\u5c0f\u96ea', '\u5927\u96ea', '\u51ac\u81f3'],
|
||||
|
||||
/**
|
||||
* 1900-2100各年的24节气日期速查表
|
||||
* @Array Of Property
|
||||
* @return 0x string For splice
|
||||
*/
|
||||
sTermInfo: ['9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf97c3598082c95f8c965cc920f',
|
||||
'97bd0b06bdb0722c965ce1cfcc920f', 'b027097bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e',
|
||||
'97bcf97c359801ec95f8c965cc920f', '97bd0b06bdb0722c965ce1cfcc920f', 'b027097bd097c36b0b6fc9274c91aa',
|
||||
'97b6b97bd19801ec9210c965cc920e', '97bcf97c359801ec95f8c965cc920f', '97bd0b06bdb0722c965ce1cfcc920f',
|
||||
'b027097bd097c36b0b6fc9274c91aa', '9778397bd19801ec9210c965cc920e', '97b6b97bd19801ec95f8c965cc920f',
|
||||
'97bd09801d98082c95f8e1cfcc920f', '97bd097bd097c36b0b6fc9210c8dc2', '9778397bd197c36c9210c9274c91aa',
|
||||
'97b6b97bd19801ec95f8c965cc920e', '97bd09801d98082c95f8e1cfcc920f', '97bd097bd097c36b0b6fc9210c8dc2',
|
||||
'9778397bd097c36c9210c9274c91aa', '97b6b97bd19801ec95f8c965cc920e', '97bcf97c3598082c95f8e1cfcc920f',
|
||||
'97bd097bd097c36b0b6fc9210c8dc2', '9778397bd097c36c9210c9274c91aa', '97b6b97bd19801ec9210c965cc920e',
|
||||
'97bcf97c3598082c95f8c965cc920f', '97bd097bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa',
|
||||
'97b6b97bd19801ec9210c965cc920e', '97bcf97c3598082c95f8c965cc920f', '97bd097bd097c35b0b6fc920fb0722',
|
||||
'9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf97c359801ec95f8c965cc920f',
|
||||
'97bd097bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e',
|
||||
'97bcf97c359801ec95f8c965cc920f', '97bd097bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa',
|
||||
'97b6b97bd19801ec9210c965cc920e', '97bcf97c359801ec95f8c965cc920f', '97bd097bd07f595b0b6fc920fb0722',
|
||||
'9778397bd097c36b0b6fc9210c8dc2', '9778397bd19801ec9210c9274c920e', '97b6b97bd19801ec95f8c965cc920f',
|
||||
'97bd07f5307f595b0b0bc920fb0722', '7f0e397bd097c36b0b6fc9210c8dc2', '9778397bd097c36c9210c9274c920e',
|
||||
'97b6b97bd19801ec95f8c965cc920f', '97bd07f5307f595b0b0bc920fb0722', '7f0e397bd097c36b0b6fc9210c8dc2',
|
||||
'9778397bd097c36c9210c9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bd07f1487f595b0b0bc920fb0722',
|
||||
'7f0e397bd097c36b0b6fc9210c8dc2', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e',
|
||||
'97bcf7f1487f595b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa',
|
||||
'97b6b97bd19801ec9210c965cc920e', '97bcf7f1487f595b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722',
|
||||
'9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf7f1487f531b0b0bb0b6fb0722',
|
||||
'7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e',
|
||||
'97bcf7f1487f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa',
|
||||
'97b6b97bd19801ec9210c9274c920e', '97bcf7f0e47f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722',
|
||||
'9778397bd097c36b0b6fc9210c91aa', '97b6b97bd197c36c9210c9274c920e', '97bcf7f0e47f531b0b0bb0b6fb0722',
|
||||
'7f0e397bd07f595b0b0bc920fb0722', '9778397bd097c36b0b6fc9210c8dc2', '9778397bd097c36c9210c9274c920e',
|
||||
'97b6b7f0e47f531b0723b0b6fb0722', '7f0e37f5307f595b0b0bc920fb0722', '7f0e397bd097c36b0b6fc9210c8dc2',
|
||||
'9778397bd097c36b0b70c9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721', '7f0e37f1487f595b0b0bb0b6fb0722',
|
||||
'7f0e397bd097c35b0b6fc9210c8dc2', '9778397bd097c36b0b6fc9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721',
|
||||
'7f0e27f1487f595b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa',
|
||||
'97b6b7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722',
|
||||
'9778397bd097c36b0b6fc9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722',
|
||||
'7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721',
|
||||
'7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', '9778397bd097c36b0b6fc9274c91aa',
|
||||
'97b6b7f0e47f531b0723b0787b0721', '7f0e27f0e47f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722',
|
||||
'9778397bd097c36b0b6fc9210c91aa', '97b6b7f0e47f149b0723b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722',
|
||||
'7f0e397bd07f595b0b0bc920fb0722', '9778397bd097c36b0b6fc9210c8dc2', '977837f0e37f149b0723b0787b0721',
|
||||
'7f07e7f0e47f531b0723b0b6fb0722', '7f0e37f5307f595b0b0bc920fb0722', '7f0e397bd097c35b0b6fc9210c8dc2',
|
||||
'977837f0e37f14998082b0787b0721', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e37f1487f595b0b0bb0b6fb0722',
|
||||
'7f0e397bd097c35b0b6fc9210c8dc2', '977837f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721',
|
||||
'7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '977837f0e37f14998082b0787b06bd',
|
||||
'7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722',
|
||||
'977837f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722',
|
||||
'7f0e397bd07f595b0b0bc920fb0722', '977837f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721',
|
||||
'7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', '977837f0e37f14998082b0787b06bd',
|
||||
'7f07e7f0e47f149b0723b0787b0721', '7f0e27f0e47f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722',
|
||||
'977837f0e37f14998082b0723b06bd', '7f07e7f0e37f149b0723b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722',
|
||||
'7f0e397bd07f595b0b0bc920fb0722', '977837f0e37f14898082b0723b02d5', '7ec967f0e37f14998082b0787b0721',
|
||||
'7f07e7f0e47f531b0723b0b6fb0722', '7f0e37f1487f595b0b0bb0b6fb0722', '7f0e37f0e37f14898082b0723b02d5',
|
||||
'7ec967f0e37f14998082b0787b0721', '7f07e7f0e47f531b0723b0b6fb0722', '7f0e37f1487f531b0b0bb0b6fb0722',
|
||||
'7f0e37f0e37f14898082b0723b02d5', '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721',
|
||||
'7f0e37f1487f531b0b0bb0b6fb0722', '7f0e37f0e37f14898082b072297c35', '7ec967f0e37f14998082b0787b06bd',
|
||||
'7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e37f0e37f14898082b072297c35',
|
||||
'7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722',
|
||||
'7f0e37f0e366aa89801eb072297c35', '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f149b0723b0787b0721',
|
||||
'7f0e27f1487f531b0b0bb0b6fb0722', '7f0e37f0e366aa89801eb072297c35', '7ec967f0e37f14998082b0723b06bd',
|
||||
'7f07e7f0e47f149b0723b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722', '7f0e37f0e366aa89801eb072297c35',
|
||||
'7ec967f0e37f14998082b0723b06bd', '7f07e7f0e37f14998083b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722',
|
||||
'7f0e37f0e366aa89801eb072297c35', '7ec967f0e37f14898082b0723b02d5', '7f07e7f0e37f14998082b0787b0721',
|
||||
'7f07e7f0e47f531b0723b0b6fb0722', '7f0e36665b66aa89801e9808297c35', '665f67f0e37f14898082b0723b02d5',
|
||||
'7ec967f0e37f14998082b0787b0721', '7f07e7f0e47f531b0723b0b6fb0722', '7f0e36665b66a449801e9808297c35',
|
||||
'665f67f0e37f14898082b0723b02d5', '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721',
|
||||
'7f0e36665b66a449801e9808297c35', '665f67f0e37f14898082b072297c35', '7ec967f0e37f14998082b0787b06bd',
|
||||
'7f07e7f0e47f531b0723b0b6fb0721', '7f0e26665b66a449801e9808297c35', '665f67f0e37f1489801eb072297c35',
|
||||
'7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722'],
|
||||
|
||||
/**
|
||||
* 数字转中文速查表
|
||||
* @Array Of Property
|
||||
* @trans ['日','一','二','三','四','五','六','七','八','九','十']
|
||||
* @return Cn string
|
||||
*/
|
||||
nStr1: ['\u65e5', '\u4e00', '\u4e8c', '\u4e09', '\u56db', '\u4e94', '\u516d', '\u4e03', '\u516b', '\u4e5d', '\u5341'],
|
||||
|
||||
/**
|
||||
* 日期转农历称呼速查表
|
||||
* @Array Of Property
|
||||
* @trans ['初','十','廿','卅']
|
||||
* @return Cn string
|
||||
*/
|
||||
nStr2: ['\u521d', '\u5341', '\u5eff', '\u5345'],
|
||||
|
||||
/**
|
||||
* 月份转农历称呼速查表
|
||||
* @Array Of Property
|
||||
* @trans ['正','一','二','三','四','五','六','七','八','九','十','冬','腊']
|
||||
* @return Cn string
|
||||
*/
|
||||
nStr3: ['\u6b63', '\u4e8c', '\u4e09', '\u56db', '\u4e94', '\u516d', '\u4e03', '\u516b', '\u4e5d', '\u5341', '\u51ac', '\u814a'],
|
||||
|
||||
/**
|
||||
* 返回农历y年一整年的总天数
|
||||
* @param lunar Year
|
||||
* @return Number
|
||||
* @eg:var count = calendar.lYearDays(1987) ;//count=387
|
||||
*/
|
||||
lYearDays: function (y) {
|
||||
var i; var sum = 348
|
||||
for (i = 0x8000; i > 0x8; i >>= 1) { sum += (this.lunarInfo[y - 1900] & i) ? 1 : 0 }
|
||||
return (sum + this.leapDays(y))
|
||||
},
|
||||
|
||||
/**
|
||||
* 返回农历y年闰月是哪个月;若y年没有闰月 则返回0
|
||||
* @param lunar Year
|
||||
* @return Number (0-12)
|
||||
* @eg:var leapMonth = calendar.leapMonth(1987) ;//leapMonth=6
|
||||
*/
|
||||
leapMonth: function (y) { // 闰字编码 \u95f0
|
||||
return (this.lunarInfo[y - 1900] & 0xf)
|
||||
},
|
||||
|
||||
/**
|
||||
* 返回农历y年闰月的天数 若该年没有闰月则返回0
|
||||
* @param lunar Year
|
||||
* @return Number (0、29、30)
|
||||
* @eg:var leapMonthDay = calendar.leapDays(1987) ;//leapMonthDay=29
|
||||
*/
|
||||
leapDays: function (y) {
|
||||
if (this.leapMonth(y)) {
|
||||
return ((this.lunarInfo[y - 1900] & 0x10000) ? 30 : 29)
|
||||
}
|
||||
return (0)
|
||||
},
|
||||
|
||||
/**
|
||||
* 返回农历y年m月(非闰月)的总天数,计算m为闰月时的天数请使用leapDays方法
|
||||
* @param lunar Year
|
||||
* @return Number (-1、29、30)
|
||||
* @eg:var MonthDay = calendar.monthDays(1987,9) ;//MonthDay=29
|
||||
*/
|
||||
monthDays: function (y, m) {
|
||||
if (m > 12 || m < 1) { return -1 }// 月份参数从1至12,参数错误返回-1
|
||||
return ((this.lunarInfo[y - 1900] & (0x10000 >> m)) ? 30 : 29)
|
||||
},
|
||||
|
||||
/**
|
||||
* 返回公历(!)y年m月的天数
|
||||
* @param solar Year
|
||||
* @return Number (-1、28、29、30、31)
|
||||
* @eg:var solarMonthDay = calendar.leapDays(1987) ;//solarMonthDay=30
|
||||
*/
|
||||
solarDays: function (y, m) {
|
||||
if (m > 12 || m < 1) { return -1 } // 若参数错误 返回-1
|
||||
var ms = m - 1
|
||||
if (ms == 1) { // 2月份的闰平规律测算后确认返回28或29
|
||||
return (((y % 4 == 0) && (y % 100 != 0) || (y % 400 == 0)) ? 29 : 28)
|
||||
} else {
|
||||
return (this.solarMonth[ms])
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 农历年份转换为干支纪年
|
||||
* @param lYear 农历年的年份数
|
||||
* @return Cn string
|
||||
*/
|
||||
toGanZhiYear: function (lYear) {
|
||||
var ganKey = (lYear - 3) % 10
|
||||
var zhiKey = (lYear - 3) % 12
|
||||
if (ganKey == 0) ganKey = 10// 如果余数为0则为最后一个天干
|
||||
if (zhiKey == 0) zhiKey = 12// 如果余数为0则为最后一个地支
|
||||
return this.Gan[ganKey - 1] + this.Zhi[zhiKey - 1]
|
||||
},
|
||||
|
||||
/**
|
||||
* 公历月、日判断所属星座
|
||||
* @param cMonth [description]
|
||||
* @param cDay [description]
|
||||
* @return Cn string
|
||||
*/
|
||||
toAstro: function (cMonth, cDay) {
|
||||
var s = '\u9b54\u7faf\u6c34\u74f6\u53cc\u9c7c\u767d\u7f8a\u91d1\u725b\u53cc\u5b50\u5de8\u87f9\u72ee\u5b50\u5904\u5973\u5929\u79e4\u5929\u874e\u5c04\u624b\u9b54\u7faf'
|
||||
var arr = [20, 19, 21, 21, 21, 22, 23, 23, 23, 23, 22, 22]
|
||||
return s.substr(cMonth * 2 - (cDay < arr[cMonth - 1] ? 2 : 0), 2) + '\u5ea7'// 座
|
||||
},
|
||||
|
||||
/**
|
||||
* 传入offset偏移量返回干支
|
||||
* @param offset 相对甲子的偏移量
|
||||
* @return Cn string
|
||||
*/
|
||||
toGanZhi: function (offset) {
|
||||
return this.Gan[offset % 10] + this.Zhi[offset % 12]
|
||||
},
|
||||
|
||||
/**
|
||||
* 传入公历(!)y年获得该年第n个节气的公历日期
|
||||
* @param y公历年(1900-2100);n二十四节气中的第几个节气(1~24);从n=1(小寒)算起
|
||||
* @return day Number
|
||||
* @eg:var _24 = calendar.getTerm(1987,3) ;//_24=4;意即1987年2月4日立春
|
||||
*/
|
||||
getTerm: function (y, n) {
|
||||
if (y < 1900 || y > 2100) { return -1 }
|
||||
if (n < 1 || n > 24) { return -1 }
|
||||
var _table = this.sTermInfo[y - 1900]
|
||||
var _info = [
|
||||
parseInt('0x' + _table.substr(0, 5)).toString(),
|
||||
parseInt('0x' + _table.substr(5, 5)).toString(),
|
||||
parseInt('0x' + _table.substr(10, 5)).toString(),
|
||||
parseInt('0x' + _table.substr(15, 5)).toString(),
|
||||
parseInt('0x' + _table.substr(20, 5)).toString(),
|
||||
parseInt('0x' + _table.substr(25, 5)).toString()
|
||||
]
|
||||
var _calday = [
|
||||
_info[0].substr(0, 1),
|
||||
_info[0].substr(1, 2),
|
||||
_info[0].substr(3, 1),
|
||||
_info[0].substr(4, 2),
|
||||
|
||||
_info[1].substr(0, 1),
|
||||
_info[1].substr(1, 2),
|
||||
_info[1].substr(3, 1),
|
||||
_info[1].substr(4, 2),
|
||||
|
||||
_info[2].substr(0, 1),
|
||||
_info[2].substr(1, 2),
|
||||
_info[2].substr(3, 1),
|
||||
_info[2].substr(4, 2),
|
||||
|
||||
_info[3].substr(0, 1),
|
||||
_info[3].substr(1, 2),
|
||||
_info[3].substr(3, 1),
|
||||
_info[3].substr(4, 2),
|
||||
|
||||
_info[4].substr(0, 1),
|
||||
_info[4].substr(1, 2),
|
||||
_info[4].substr(3, 1),
|
||||
_info[4].substr(4, 2),
|
||||
|
||||
_info[5].substr(0, 1),
|
||||
_info[5].substr(1, 2),
|
||||
_info[5].substr(3, 1),
|
||||
_info[5].substr(4, 2)
|
||||
]
|
||||
return parseInt(_calday[n - 1])
|
||||
},
|
||||
|
||||
/**
|
||||
* 传入农历数字月份返回汉语通俗表示法
|
||||
* @param lunar month
|
||||
* @return Cn string
|
||||
* @eg:var cnMonth = calendar.toChinaMonth(12) ;//cnMonth='腊月'
|
||||
*/
|
||||
toChinaMonth: function (m) { // 月 => \u6708
|
||||
if (m > 12 || m < 1) { return -1 } // 若参数错误 返回-1
|
||||
var s = this.nStr3[m - 1]
|
||||
s += '\u6708'// 加上月字
|
||||
return s
|
||||
},
|
||||
|
||||
/**
|
||||
* 传入农历日期数字返回汉字表示法
|
||||
* @param lunar day
|
||||
* @return Cn string
|
||||
* @eg:var cnDay = calendar.toChinaDay(21) ;//cnMonth='廿一'
|
||||
*/
|
||||
toChinaDay: function (d) { // 日 => \u65e5
|
||||
var s
|
||||
switch (d) {
|
||||
case 10:
|
||||
s = '\u521d\u5341'; break
|
||||
case 20:
|
||||
s = '\u4e8c\u5341'; break
|
||||
break
|
||||
case 30:
|
||||
s = '\u4e09\u5341'; break
|
||||
break
|
||||
default :
|
||||
s = this.nStr2[Math.floor(d / 10)]
|
||||
s += this.nStr1[d % 10]
|
||||
}
|
||||
return (s)
|
||||
},
|
||||
|
||||
/**
|
||||
* 年份转生肖[!仅能大致转换] => 精确划分生肖分界线是“立春”
|
||||
* @param y year
|
||||
* @return Cn string
|
||||
* @eg:var animal = calendar.getAnimal(1987) ;//animal='兔'
|
||||
*/
|
||||
getAnimal: function (y) {
|
||||
return this.Animals[(y - 4) % 12]
|
||||
},
|
||||
|
||||
/**
|
||||
* 传入阳历年月日获得详细的公历、农历object信息 <=>JSON
|
||||
* @param y solar year
|
||||
* @param m solar month
|
||||
* @param d solar day
|
||||
* @return JSON object
|
||||
* @eg:console.log(calendar.solar2lunar(1987,11,01));
|
||||
*/
|
||||
solar2lunar: function (y, m, d) { // 参数区间1900.1.31~2100.12.31
|
||||
// 年份限定、上限
|
||||
if (y < 1900 || y > 2100) {
|
||||
return -1// undefined转换为数字变为NaN
|
||||
}
|
||||
// 公历传参最下限
|
||||
if (y == 1900 && m == 1 && d < 31) {
|
||||
return -1
|
||||
}
|
||||
// 未传参 获得当天
|
||||
if (!y) {
|
||||
var objDate = new Date()
|
||||
} else {
|
||||
var objDate = new Date(y, parseInt(m) - 1, d)
|
||||
}
|
||||
var i; var leap = 0; var temp = 0
|
||||
// 修正ymd参数
|
||||
var y = objDate.getFullYear()
|
||||
var m = objDate.getMonth() + 1
|
||||
var d = objDate.getDate()
|
||||
var offset = (Date.UTC(objDate.getFullYear(), objDate.getMonth(), objDate.getDate()) - Date.UTC(1900, 0, 31)) / 86400000
|
||||
for (i = 1900; i < 2101 && offset > 0; i++) {
|
||||
temp = this.lYearDays(i)
|
||||
offset -= temp
|
||||
}
|
||||
if (offset < 0) {
|
||||
offset += temp; i--
|
||||
}
|
||||
|
||||
// 是否今天
|
||||
var isTodayObj = new Date()
|
||||
var isToday = false
|
||||
if (isTodayObj.getFullYear() == y && isTodayObj.getMonth() + 1 == m && isTodayObj.getDate() == d) {
|
||||
isToday = true
|
||||
}
|
||||
// 星期几
|
||||
var nWeek = objDate.getDay()
|
||||
var cWeek = this.nStr1[nWeek]
|
||||
// 数字表示周几顺应天朝周一开始的惯例
|
||||
if (nWeek == 0) {
|
||||
nWeek = 7
|
||||
}
|
||||
// 农历年
|
||||
var year = i
|
||||
var leap = this.leapMonth(i) // 闰哪个月
|
||||
var isLeap = false
|
||||
|
||||
// 效验闰月
|
||||
for (i = 1; i < 13 && offset > 0; i++) {
|
||||
// 闰月
|
||||
if (leap > 0 && i == (leap + 1) && isLeap == false) {
|
||||
--i
|
||||
isLeap = true; temp = this.leapDays(year) // 计算农历闰月天数
|
||||
} else {
|
||||
temp = this.monthDays(year, i)// 计算农历普通月天数
|
||||
}
|
||||
// 解除闰月
|
||||
if (isLeap == true && i == (leap + 1)) { isLeap = false }
|
||||
offset -= temp
|
||||
}
|
||||
// 闰月导致数组下标重叠取反
|
||||
if (offset == 0 && leap > 0 && i == leap + 1) {
|
||||
if (isLeap) {
|
||||
isLeap = false
|
||||
} else {
|
||||
isLeap = true; --i
|
||||
}
|
||||
}
|
||||
if (offset < 0) {
|
||||
offset += temp; --i
|
||||
}
|
||||
// 农历月
|
||||
var month = i
|
||||
// 农历日
|
||||
var day = offset + 1
|
||||
// 天干地支处理
|
||||
var sm = m - 1
|
||||
var gzY = this.toGanZhiYear(year)
|
||||
|
||||
// 当月的两个节气
|
||||
// bugfix-2017-7-24 11:03:38 use lunar Year Param `y` Not `year`
|
||||
var firstNode = this.getTerm(y, (m * 2 - 1))// 返回当月「节」为几日开始
|
||||
var secondNode = this.getTerm(y, (m * 2))// 返回当月「节」为几日开始
|
||||
|
||||
// 依据12节气修正干支月
|
||||
var gzM = this.toGanZhi((y - 1900) * 12 + m + 11)
|
||||
if (d >= firstNode) {
|
||||
gzM = this.toGanZhi((y - 1900) * 12 + m + 12)
|
||||
}
|
||||
|
||||
// 传入的日期的节气与否
|
||||
var isTerm = false
|
||||
var Term = null
|
||||
if (firstNode == d) {
|
||||
isTerm = true
|
||||
Term = this.solarTerm[m * 2 - 2]
|
||||
}
|
||||
if (secondNode == d) {
|
||||
isTerm = true
|
||||
Term = this.solarTerm[m * 2 - 1]
|
||||
}
|
||||
// 日柱 当月一日与 1900/1/1 相差天数
|
||||
var dayCyclical = Date.UTC(y, sm, 1, 0, 0, 0, 0) / 86400000 + 25567 + 10
|
||||
var gzD = this.toGanZhi(dayCyclical + d - 1)
|
||||
// 该日期所属的星座
|
||||
var astro = this.toAstro(m, d)
|
||||
|
||||
return { 'lYear': year, 'lMonth': month, 'lDay': day, 'Animal': this.getAnimal(year), 'IMonthCn': (isLeap ? '\u95f0' : '') + this.toChinaMonth(month), 'IDayCn': this.toChinaDay(day), 'cYear': y, 'cMonth': m, 'cDay': d, 'gzYear': gzY, 'gzMonth': gzM, 'gzDay': gzD, 'isToday': isToday, 'isLeap': isLeap, 'nWeek': nWeek, 'ncWeek': '\u661f\u671f' + cWeek, 'isTerm': isTerm, 'Term': Term, 'astro': astro }
|
||||
},
|
||||
|
||||
/**
|
||||
* 传入农历年月日以及传入的月份是否闰月获得详细的公历、农历object信息 <=>JSON
|
||||
* @param y lunar year
|
||||
* @param m lunar month
|
||||
* @param d lunar day
|
||||
* @param isLeapMonth lunar month is leap or not.[如果是农历闰月第四个参数赋值true即可]
|
||||
* @return JSON object
|
||||
* @eg:console.log(calendar.lunar2solar(1987,9,10));
|
||||
*/
|
||||
lunar2solar: function (y, m, d, isLeapMonth) { // 参数区间1900.1.31~2100.12.1
|
||||
var isLeapMonth = !!isLeapMonth
|
||||
var leapOffset = 0
|
||||
var leapMonth = this.leapMonth(y)
|
||||
var leapDay = this.leapDays(y)
|
||||
if (isLeapMonth && (leapMonth != m)) { return -1 }// 传参要求计算该闰月公历 但该年得出的闰月与传参的月份并不同
|
||||
if (y == 2100 && m == 12 && d > 1 || y == 1900 && m == 1 && d < 31) { return -1 }// 超出了最大极限值
|
||||
var day = this.monthDays(y, m)
|
||||
var _day = day
|
||||
// bugFix 2016-9-25
|
||||
// if month is leap, _day use leapDays method
|
||||
if (isLeapMonth) {
|
||||
_day = this.leapDays(y, m)
|
||||
}
|
||||
if (y < 1900 || y > 2100 || d > _day) { return -1 }// 参数合法性效验
|
||||
|
||||
// 计算农历的时间差
|
||||
var offset = 0
|
||||
for (var i = 1900; i < y; i++) {
|
||||
offset += this.lYearDays(i)
|
||||
}
|
||||
var leap = 0; var isAdd = false
|
||||
for (var i = 1; i < m; i++) {
|
||||
leap = this.leapMonth(y)
|
||||
if (!isAdd) { // 处理闰月
|
||||
if (leap <= i && leap > 0) {
|
||||
offset += this.leapDays(y); isAdd = true
|
||||
}
|
||||
}
|
||||
offset += this.monthDays(y, i)
|
||||
}
|
||||
// 转换闰月农历 需补充该年闰月的前一个月的时差
|
||||
if (isLeapMonth) { offset += day }
|
||||
// 1900年农历正月一日的公历时间为1900年1月30日0时0分0秒(该时间也是本农历的最开始起始点)
|
||||
var stmap = Date.UTC(1900, 1, 30, 0, 0, 0)
|
||||
var calObj = new Date((offset + d - 31) * 86400000 + stmap)
|
||||
var cY = calObj.getUTCFullYear()
|
||||
var cM = calObj.getUTCMonth() + 1
|
||||
var cD = calObj.getUTCDate()
|
||||
|
||||
return this.solar2lunar(cY, cM, cD)
|
||||
}
|
||||
}
|
||||
|
||||
export default calendar
|
||||
@@ -1,152 +0,0 @@
|
||||
<template>
|
||||
<view class="uni-calendar-item__weeks-box" :class="{
|
||||
'uni-calendar-item--disable':weeks.disable,
|
||||
'uni-calendar-item--isDay':calendar.fullDate === weeks.fullDate && weeks.isDay,
|
||||
'uni-calendar-item--checked':(calendar.fullDate === weeks.fullDate && !weeks.isDay) ,
|
||||
'uni-calendar-item--multiple': weeks.multiple
|
||||
}"
|
||||
@click="choiceDate(weeks)">
|
||||
<view class="uni-calendar-item__weeks-box-item">
|
||||
<text v-if="selected&&weeks.extraInfo" class="uni-calendar-item__weeks-box-circle"></text>
|
||||
<text class="uni-calendar-item__weeks-box-text" :class="{
|
||||
'uni-calendar-item--isDay-text': weeks.isDay,
|
||||
'uni-calendar-item--isDay':calendar.fullDate === weeks.fullDate && weeks.isDay,
|
||||
'uni-calendar-item--checked':calendar.fullDate === weeks.fullDate && !weeks.isDay,
|
||||
'uni-calendar-item--multiple': weeks.multiple,
|
||||
'uni-calendar-item--disable':weeks.disable,
|
||||
}">{{weeks.date}}</text>
|
||||
<text v-if="!lunar&&!weeks.extraInfo && weeks.isDay" class="uni-calendar-item__weeks-lunar-text" :class="{
|
||||
'uni-calendar-item--isDay-text':weeks.isDay,
|
||||
'uni-calendar-item--isDay':calendar.fullDate === weeks.fullDate && weeks.isDay,
|
||||
'uni-calendar-item--checked':calendar.fullDate === weeks.fullDate && !weeks.isDay,
|
||||
'uni-calendar-item--multiple': weeks.multiple,
|
||||
}">今天</text>
|
||||
<text v-if="lunar&&!weeks.extraInfo" class="uni-calendar-item__weeks-lunar-text" :class="{
|
||||
'uni-calendar-item--isDay-text':weeks.isDay,
|
||||
'uni-calendar-item--isDay':calendar.fullDate === weeks.fullDate && weeks.isDay,
|
||||
'uni-calendar-item--checked':calendar.fullDate === weeks.fullDate && !weeks.isDay,
|
||||
'uni-calendar-item--multiple': weeks.multiple,
|
||||
'uni-calendar-item--disable':weeks.disable,
|
||||
}">{{weeks.isDay?'今天': (weeks.lunar.IDayCn === '初一'?weeks.lunar.IMonthCn:weeks.lunar.IDayCn)}}</text>
|
||||
<text v-if="weeks.extraInfo&&weeks.extraInfo.info" class="uni-calendar-item__weeks-lunar-text" :class="{
|
||||
'uni-calendar-item--extra':weeks.extraInfo.info,
|
||||
'uni-calendar-item--isDay-text':weeks.isDay,
|
||||
'uni-calendar-item--isDay':calendar.fullDate === weeks.fullDate && weeks.isDay,
|
||||
'uni-calendar-item--checked':calendar.fullDate === weeks.fullDate && !weeks.isDay,
|
||||
'uni-calendar-item--multiple': weeks.multiple,
|
||||
'uni-calendar-item--disable':weeks.disable,
|
||||
}">{{weeks.extraInfo.info}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
weeks: {
|
||||
type: Object,
|
||||
default () {
|
||||
return {}
|
||||
}
|
||||
},
|
||||
calendar: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {}
|
||||
}
|
||||
},
|
||||
selected: {
|
||||
type: Array,
|
||||
default: () => {
|
||||
return []
|
||||
}
|
||||
},
|
||||
lunar: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
choiceDate(weeks) {
|
||||
this.$emit('change', weeks)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.uni-calendar-item__weeks-box {
|
||||
flex: 1;
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
/* #endif */
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.uni-calendar-item__weeks-box-text {
|
||||
font-size: $uni-font-size-base;
|
||||
color: $uni-text-color;
|
||||
}
|
||||
|
||||
.uni-calendar-item__weeks-lunar-text {
|
||||
font-size: $uni-font-size-sm;
|
||||
color: $uni-text-color;
|
||||
}
|
||||
|
||||
.uni-calendar-item__weeks-box-item {
|
||||
position: relative;
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
/* #endif */
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 100rpx;
|
||||
height: 100rpx;
|
||||
}
|
||||
|
||||
.uni-calendar-item__weeks-box-circle {
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
right: 5px;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 8px;
|
||||
background-color: $uni-color-error;
|
||||
|
||||
}
|
||||
|
||||
.uni-calendar-item--disable {
|
||||
background-color: rgba(249, 249, 249, $uni-opacity-disabled);
|
||||
color: $uni-text-color-disable;
|
||||
}
|
||||
|
||||
.uni-calendar-item--isDay-text {
|
||||
color: $uni-color-primary;
|
||||
}
|
||||
|
||||
.uni-calendar-item--isDay {
|
||||
background-color: $uni-color-primary;
|
||||
opacity: 0.8;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.uni-calendar-item--extra {
|
||||
color: $uni-color-error;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.uni-calendar-item--checked {
|
||||
background-color: $uni-color-primary;
|
||||
color: #fff;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.uni-calendar-item--multiple {
|
||||
background-color: $uni-color-primary;
|
||||
color: #fff;
|
||||
opacity: 0.8;
|
||||
}
|
||||
</style>
|
||||
@@ -1,434 +0,0 @@
|
||||
<template>
|
||||
<view class="uni-calendar" @touchmove.stop.prevent="clean">
|
||||
<view v-if="!insert&&show" class="uni-calendar__mask" :class="{'uni-calendar--mask-show':aniMaskShow}" @click="clean"></view>
|
||||
<view v-if="insert || show" class="uni-calendar__content" :class="{'uni-calendar--fixed':!insert,'uni-calendar--ani-show':aniMaskShow}">
|
||||
<view v-if="!insert" class="uni-calendar__header uni-calendar--fixed-top">
|
||||
<view class="uni-calendar__header-btn-box" @click="close">
|
||||
<text class="uni-calendar__header-text uni-calendar--fixed-width">取消</text>
|
||||
</view>
|
||||
<view class="uni-calendar__header-btn-box" @click="confirm">
|
||||
<text class="uni-calendar__header-text uni-calendar--fixed-width">确定</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="uni-calendar__header">
|
||||
<view class="uni-calendar__header-btn-box" @click="pre">
|
||||
<view class="uni-calendar__header-btn uni-calendar--left"></view>
|
||||
</view>
|
||||
<text class="uni-calendar__header-text">{{ (nowDate.year||'') +'年'+( nowDate.month||'') +'月'}}</text>
|
||||
<view class="uni-calendar__header-btn-box" @click="next">
|
||||
<view class="uni-calendar__header-btn uni-calendar--right"></view>
|
||||
</view>
|
||||
<text class="uni-calendar__backtoday" @click="backtoday">回到今天</text>
|
||||
</view>
|
||||
<view class="uni-calendar__box">
|
||||
<view v-if="showMonth" class="uni-calendar__box-bg">
|
||||
<text class="uni-calendar__box-bg-text">{{nowDate.month}}</text>
|
||||
</view>
|
||||
<view class="uni-calendar__weeks">
|
||||
<view class="uni-calendar__weeks-day">
|
||||
<text class="uni-calendar__weeks-day-text">日</text>
|
||||
</view>
|
||||
<view class="uni-calendar__weeks-day">
|
||||
<text class="uni-calendar__weeks-day-text">一</text>
|
||||
</view>
|
||||
<view class="uni-calendar__weeks-day">
|
||||
<text class="uni-calendar__weeks-day-text">二</text>
|
||||
</view>
|
||||
<view class="uni-calendar__weeks-day">
|
||||
<text class="uni-calendar__weeks-day-text">三</text>
|
||||
</view>
|
||||
<view class="uni-calendar__weeks-day">
|
||||
<text class="uni-calendar__weeks-day-text">四</text>
|
||||
</view>
|
||||
<view class="uni-calendar__weeks-day">
|
||||
<text class="uni-calendar__weeks-day-text">五</text>
|
||||
</view>
|
||||
<view class="uni-calendar__weeks-day">
|
||||
<text class="uni-calendar__weeks-day-text">六</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="uni-calendar__weeks" v-for="(item,weekIndex) in weeks" :key="weekIndex">
|
||||
<view class="uni-calendar__weeks-item" v-for="(weeks,weeksIndex) in item" :key="weeksIndex">
|
||||
<uni-calendar-item :weeks="weeks" :calendar="calendar" :selected="selected" :lunar="lunar" @change="choiceDate"></uni-calendar-item>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Calendar from './util.js';
|
||||
import uniCalendarItem from './uni-calendar-item.vue'
|
||||
export default {
|
||||
components: {
|
||||
uniCalendarItem
|
||||
},
|
||||
props: {
|
||||
/**
|
||||
* 当前日期
|
||||
*/
|
||||
date: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
/**
|
||||
* 打点日期
|
||||
*/
|
||||
selected: {
|
||||
type: Array,
|
||||
default () {
|
||||
return []
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 是否开启阴历日期
|
||||
*/
|
||||
lunar: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
/**
|
||||
* 开始时间
|
||||
*/
|
||||
startDate: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
/**
|
||||
* 结束时间
|
||||
*/
|
||||
endDate: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
/**
|
||||
* 范围
|
||||
*/
|
||||
range: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
/**
|
||||
* 插入
|
||||
*/
|
||||
insert: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
/**
|
||||
* 是否显示月份背景
|
||||
*/
|
||||
showMonth: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
show: false,
|
||||
weeks: [],
|
||||
calendar: {},
|
||||
nowDate: '',
|
||||
aniMaskShow: false
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
selected(newVal) {
|
||||
this.cale.setSelectInfo(this.nowDate.fullDate, newVal)
|
||||
this.weeks = this.cale.weeks
|
||||
}
|
||||
},
|
||||
created() {
|
||||
// 获取日历方法实例
|
||||
this.cale = new Calendar({
|
||||
date: this.date,
|
||||
selected: this.selected,
|
||||
startDate: this.startDate,
|
||||
endDate: this.endDate,
|
||||
range: this.range,
|
||||
})
|
||||
this.init(this.cale.date.fullDate)
|
||||
},
|
||||
methods: {
|
||||
// 取消穿透
|
||||
clean() {},
|
||||
init(date) {
|
||||
this.weeks = this.cale.weeks
|
||||
this.nowDate = this.calendar = this.cale.getInfo(date)
|
||||
},
|
||||
open() {
|
||||
this.show = true
|
||||
this.$nextTick(() => {
|
||||
setTimeout(()=>{
|
||||
this.aniMaskShow = true
|
||||
},50)
|
||||
})
|
||||
},
|
||||
close() {
|
||||
this.aniMaskShow = false
|
||||
this.$nextTick(() => {
|
||||
setTimeout(() => {
|
||||
this.show = false
|
||||
}, 300)
|
||||
})
|
||||
},
|
||||
confirm() {
|
||||
this.setEmit('confirm')
|
||||
this.close()
|
||||
},
|
||||
change() {
|
||||
if (!this.insert) return
|
||||
this.setEmit('change')
|
||||
},
|
||||
monthSwitch() {
|
||||
let {
|
||||
year,
|
||||
month
|
||||
} = this.nowDate
|
||||
this.$emit('monthSwitch', {
|
||||
year,
|
||||
month: Number(month)
|
||||
})
|
||||
},
|
||||
setEmit(name) {
|
||||
let {
|
||||
year,
|
||||
month,
|
||||
date,
|
||||
fullDate,
|
||||
lunar,
|
||||
extraInfo
|
||||
} = this.calendar
|
||||
this.$emit(name, {
|
||||
range: this.cale.multipleStatus,
|
||||
year,
|
||||
month,
|
||||
date,
|
||||
fulldate: fullDate,
|
||||
lunar,
|
||||
extraInfo: extraInfo || {}
|
||||
})
|
||||
},
|
||||
choiceDate(weeks) {
|
||||
if (weeks.disable) return
|
||||
this.calendar = weeks
|
||||
// 设置多选
|
||||
this.cale.setMultiple(this.calendar.fullDate)
|
||||
this.weeks = this.cale.weeks
|
||||
this.change()
|
||||
},
|
||||
backtoday() {
|
||||
this.cale.setDate(this.date)
|
||||
this.weeks = this.cale.weeks
|
||||
this.nowDate = this.calendar = this.cale.getInfo(this.date)
|
||||
this.change()
|
||||
},
|
||||
pre() {
|
||||
const preDate = this.cale.getDate(this.nowDate.fullDate, -1, 'month').fullDate
|
||||
this.setDate(preDate)
|
||||
this.monthSwitch()
|
||||
|
||||
},
|
||||
next() {
|
||||
const nextDate = this.cale.getDate(this.nowDate.fullDate, +1, 'month').fullDate
|
||||
this.setDate(nextDate)
|
||||
this.monthSwitch()
|
||||
},
|
||||
setDate(date) {
|
||||
this.cale.setDate(date)
|
||||
this.weeks = this.cale.weeks
|
||||
this.nowDate = this.cale.getInfo(date)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.uni-calendar {
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
/* #endif */
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.uni-calendar__mask {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background-color: $uni-bg-color-mask;
|
||||
transition-property: opacity;
|
||||
transition-duration: 0.3s;
|
||||
opacity: 0;
|
||||
/* #ifndef APP-NVUE */
|
||||
z-index: 99;
|
||||
/* #endif */
|
||||
}
|
||||
|
||||
.uni-calendar--mask-show {
|
||||
opacity: 1
|
||||
}
|
||||
|
||||
.uni-calendar--fixed {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
transition-property: transform;
|
||||
transition-duration: 0.3s;
|
||||
transform: translateY(460px);
|
||||
/* #ifndef APP-NVUE */
|
||||
z-index: 99;
|
||||
/* #endif */
|
||||
}
|
||||
|
||||
.uni-calendar--ani-show {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
.uni-calendar__content {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.uni-calendar__header {
|
||||
position: relative;
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
/* #endif */
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 50px;
|
||||
border-bottom-color: $uni-border-color;
|
||||
border-bottom-style: solid;
|
||||
border-bottom-width: 1px;
|
||||
}
|
||||
|
||||
.uni-calendar--fixed-top {
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
/* #endif */
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
border-top-color: $uni-border-color;
|
||||
border-top-style: solid;
|
||||
border-top-width: 1px;
|
||||
}
|
||||
|
||||
.uni-calendar--fixed-width {
|
||||
width: 50px;
|
||||
// padding: 0 15px;
|
||||
}
|
||||
|
||||
.uni-calendar__backtoday {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 25rpx;
|
||||
padding: 0 5px;
|
||||
padding-left: 10px;
|
||||
height: 25px;
|
||||
line-height: 25px;
|
||||
font-size: 12px;
|
||||
border-top-left-radius: 25px;
|
||||
border-bottom-left-radius: 25px;
|
||||
color: $uni-text-color;
|
||||
background-color: $uni-bg-color-hover;
|
||||
}
|
||||
|
||||
.uni-calendar__header-text {
|
||||
text-align: center;
|
||||
width: 100px;
|
||||
font-size: $uni-font-size-base;
|
||||
color: $uni-text-color;
|
||||
}
|
||||
|
||||
.uni-calendar__header-btn-box {
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
/* #endif */
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
.uni-calendar__header-btn {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
border-left-color: $uni-text-color-placeholder;
|
||||
border-left-style: solid;
|
||||
border-left-width: 2px;
|
||||
border-top-color: $uni-color-subtitle;
|
||||
border-top-style: solid;
|
||||
border-top-width: 2px;
|
||||
}
|
||||
|
||||
.uni-calendar--left {
|
||||
transform: rotate(-45deg);
|
||||
}
|
||||
|
||||
.uni-calendar--right {
|
||||
transform: rotate(135deg);
|
||||
}
|
||||
|
||||
|
||||
.uni-calendar__weeks {
|
||||
position: relative;
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
/* #endif */
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.uni-calendar__weeks-item {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.uni-calendar__weeks-day {
|
||||
flex: 1;
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
/* #endif */
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 45px;
|
||||
border-bottom-color: #F5F5F5;
|
||||
border-bottom-style: solid;
|
||||
border-bottom-width: 1px;
|
||||
}
|
||||
.uni-calendar__weeks-day-text {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.uni-calendar__box {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.uni-calendar__box-bg {
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
/* #endif */
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.uni-calendar__box-bg-text {
|
||||
font-size: 200px;
|
||||
font-weight: bold;
|
||||
color: $uni-text-color-grey;
|
||||
opacity: 0.1;
|
||||
text-align: center;
|
||||
/* #ifndef APP-NVUE */
|
||||
line-height: 1;
|
||||
/* #endif */
|
||||
}
|
||||
</style>
|
||||
@@ -1,327 +0,0 @@
|
||||
import CALENDAR from './calendar.js'
|
||||
|
||||
class Calendar {
|
||||
constructor({
|
||||
date,
|
||||
selected,
|
||||
startDate,
|
||||
endDate,
|
||||
range
|
||||
} = {}) {
|
||||
// 当前日期
|
||||
this.date = this.getDate(date) // 当前初入日期
|
||||
// 打点信息
|
||||
this.selected = selected || [];
|
||||
// 范围开始
|
||||
this.startDate = startDate
|
||||
// 范围结束
|
||||
this.endDate = endDate
|
||||
this.range = range
|
||||
// 多选状态
|
||||
this.multipleStatus = {
|
||||
before: '',
|
||||
after: '',
|
||||
data: []
|
||||
}
|
||||
// 每周日期
|
||||
this.weeks = {}
|
||||
|
||||
this._getWeek(this.date.fullDate)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取任意时间
|
||||
*/
|
||||
getDate(date, AddDayCount = 0, str = 'day') {
|
||||
if (!date) {
|
||||
date = new Date()
|
||||
}
|
||||
if (typeof date !== 'object') {
|
||||
date = date.replace(/-/g, '/')
|
||||
}
|
||||
const dd = new Date(date)
|
||||
switch (str) {
|
||||
case 'day':
|
||||
dd.setDate(dd.getDate() + AddDayCount) // 获取AddDayCount天后的日期
|
||||
break
|
||||
case 'month':
|
||||
if (dd.getDate() === 31) {
|
||||
dd.setDate(dd.getDate() + AddDayCount)
|
||||
} else {
|
||||
dd.setMonth(dd.getMonth() + AddDayCount) // 获取AddDayCount天后的日期
|
||||
}
|
||||
break
|
||||
case 'year':
|
||||
dd.setFullYear(dd.getFullYear() + AddDayCount) // 获取AddDayCount天后的日期
|
||||
break
|
||||
}
|
||||
const y = dd.getFullYear()
|
||||
const m = dd.getMonth() + 1 < 10 ? '0' + (dd.getMonth() + 1) : dd.getMonth() + 1 // 获取当前月份的日期,不足10补0
|
||||
const d = dd.getDate() < 10 ? '0' + dd.getDate() : dd.getDate() // 获取当前几号,不足10补0
|
||||
return {
|
||||
fullDate: y + '-' + m + '-' + d,
|
||||
year: y,
|
||||
month: m,
|
||||
date: d,
|
||||
day: dd.getDay()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取上月剩余天数
|
||||
*/
|
||||
_getLastMonthDays(firstDay, full) {
|
||||
let dateArr = []
|
||||
for (let i = firstDay; i > 0; i--) {
|
||||
const beforeDate = new Date(full.year, full.month - 1, -i + 1).getDate()
|
||||
dateArr.push({
|
||||
date: beforeDate,
|
||||
month: full.month - 1,
|
||||
lunar: this.getlunar(full.year, full.month - 1, beforeDate),
|
||||
disable: true
|
||||
})
|
||||
}
|
||||
return dateArr
|
||||
}
|
||||
/**
|
||||
* 获取本月天数
|
||||
*/
|
||||
_currentMonthDys(dateData, full) {
|
||||
let dateArr = []
|
||||
let fullDate = this.date.fullDate
|
||||
for (let i = 1; i <= dateData; i++) {
|
||||
let isinfo = false
|
||||
let nowDate = full.year + '-' + (full.month < 10 ?
|
||||
full.month : full.month) + '-' + (i < 10 ?
|
||||
'0' + i : i)
|
||||
// 是否今天
|
||||
let isDay = fullDate === nowDate
|
||||
// 获取打点信息
|
||||
let info = this.selected && this.selected.find((item) => {
|
||||
if (this.dateEqual(nowDate, item.date)) {
|
||||
return item
|
||||
}
|
||||
})
|
||||
|
||||
// 日期禁用
|
||||
let disableBefore = true
|
||||
let disableAfter = true
|
||||
if (this.startDate) {
|
||||
let dateCompBefore = this.dateCompare(this.startDate, fullDate)
|
||||
disableBefore = this.dateCompare(dateCompBefore ? this.startDate : fullDate, nowDate)
|
||||
}
|
||||
|
||||
if (this.endDate) {
|
||||
let dateCompAfter = this.dateCompare(fullDate, this.endDate)
|
||||
disableAfter = this.dateCompare(nowDate, dateCompAfter ? this.endDate : fullDate)
|
||||
}
|
||||
|
||||
let multiples = this.multipleStatus.data
|
||||
let checked = false
|
||||
let multiplesStatus = -1
|
||||
if (this.range) {
|
||||
if (multiples) {
|
||||
multiplesStatus = multiples.findIndex((item) => {
|
||||
return this.dateEqual(item, nowDate)
|
||||
})
|
||||
}
|
||||
if (multiplesStatus !== -1) {
|
||||
checked = true
|
||||
}
|
||||
}
|
||||
|
||||
let data = {
|
||||
fullDate: nowDate,
|
||||
year: full.year,
|
||||
date: i,
|
||||
multiple: this.range ? checked : false,
|
||||
month: full.month,
|
||||
lunar: this.getlunar(full.year, full.month, i),
|
||||
disable: !disableBefore || !disableAfter,
|
||||
isDay
|
||||
}
|
||||
if (info) {
|
||||
data.extraInfo = info
|
||||
}
|
||||
|
||||
dateArr.push(data)
|
||||
}
|
||||
return dateArr
|
||||
}
|
||||
/**
|
||||
* 获取下月天数
|
||||
*/
|
||||
_getNextMonthDays(surplus, full) {
|
||||
let dateArr = []
|
||||
for (let i = 1; i < surplus + 1; i++) {
|
||||
dateArr.push({
|
||||
date: i,
|
||||
month: Number(full.month) + 1,
|
||||
lunar: this.getlunar(full.year, Number(full.month) + 1, i),
|
||||
disable: true
|
||||
})
|
||||
}
|
||||
return dateArr
|
||||
}
|
||||
/**
|
||||
* 设置日期
|
||||
* @param {Object} date
|
||||
*/
|
||||
setDate(date) {
|
||||
this._getWeek(date)
|
||||
}
|
||||
/**
|
||||
* 获取当前日期详情
|
||||
* @param {Object} date
|
||||
*/
|
||||
getInfo(date) {
|
||||
if (!date) {
|
||||
date = new Date()
|
||||
}
|
||||
const dateInfo = this.canlender.find(item => item.fullDate === this.getDate(date).fullDate)
|
||||
return dateInfo
|
||||
}
|
||||
|
||||
/**
|
||||
* 比较时间大小
|
||||
*/
|
||||
dateCompare(startDate, endDate) {
|
||||
// 计算截止时间
|
||||
startDate = new Date(startDate.replace('-', '/').replace('-', '/'))
|
||||
// 计算详细项的截止时间
|
||||
endDate = new Date(endDate.replace('-', '/').replace('-', '/'))
|
||||
if (startDate <= endDate) {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 比较时间是否相等
|
||||
*/
|
||||
dateEqual(before, after) {
|
||||
// 计算截止时间
|
||||
before = new Date(before.replace('-', '/').replace('-', '/'))
|
||||
// 计算详细项的截止时间
|
||||
after = new Date(after.replace('-', '/').replace('-', '/'))
|
||||
if (before.getTime() - after.getTime() === 0) {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取日期范围内所有日期
|
||||
* @param {Object} begin
|
||||
* @param {Object} end
|
||||
*/
|
||||
geDateAll(begin, end) {
|
||||
var arr = []
|
||||
var ab = begin.split('-')
|
||||
var ae = end.split('-')
|
||||
var db = new Date()
|
||||
db.setFullYear(ab[0], ab[1] - 1, ab[2])
|
||||
var de = new Date()
|
||||
de.setFullYear(ae[0], ae[1] - 1, ae[2])
|
||||
var unixDb = db.getTime() - 24 * 60 * 60 * 1000
|
||||
var unixDe = de.getTime() - 24 * 60 * 60 * 1000
|
||||
for (var k = unixDb; k <= unixDe;) {
|
||||
k = k + 24 * 60 * 60 * 1000
|
||||
arr.push(this.getDate(new Date(parseInt(k))).fullDate)
|
||||
}
|
||||
return arr
|
||||
}
|
||||
/**
|
||||
* 计算阴历日期显示
|
||||
*/
|
||||
getlunar(year, month, date) {
|
||||
return CALENDAR.solar2lunar(year, month, date)
|
||||
}
|
||||
/**
|
||||
* 设置打点
|
||||
*/
|
||||
setSelectInfo(data, value) {
|
||||
this.selected = value
|
||||
this._getWeek(data)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取多选状态
|
||||
*/
|
||||
setMultiple(fullDate) {
|
||||
let {
|
||||
before,
|
||||
after
|
||||
} = this.multipleStatus
|
||||
if (!this.range) return
|
||||
if (before && after) {
|
||||
this.multipleStatus.before = ''
|
||||
this.multipleStatus.after = ''
|
||||
this.multipleStatus.data = []
|
||||
this._getWeek(fullDate)
|
||||
} else {
|
||||
if (!before) {
|
||||
this.multipleStatus.before = fullDate
|
||||
} else {
|
||||
this.multipleStatus.after = fullDate
|
||||
if (this.dateCompare(this.multipleStatus.before, this.multipleStatus.after)) {
|
||||
this.multipleStatus.data = this.geDateAll(this.multipleStatus.before, this.multipleStatus.after);
|
||||
} else {
|
||||
this.multipleStatus.data = this.geDateAll(this.multipleStatus.after, this.multipleStatus.before);
|
||||
}
|
||||
this._getWeek(fullDate)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取每周数据
|
||||
* @param {Object} dateData
|
||||
*/
|
||||
_getWeek(dateData) {
|
||||
const {
|
||||
fullDate,
|
||||
year,
|
||||
month,
|
||||
date,
|
||||
day
|
||||
} = this.getDate(dateData)
|
||||
let firstDay = new Date(year, month - 1, 1).getDay()
|
||||
let currentDay = new Date(year, month, 0).getDate()
|
||||
let dates = {
|
||||
lastMonthDays: this._getLastMonthDays(firstDay, this.getDate(dateData)), // 上个月末尾几天
|
||||
currentMonthDys: this._currentMonthDys(currentDay, this.getDate(dateData)), // 本月天数
|
||||
nextMonthDays: [], // 下个月开始几天
|
||||
weeks: []
|
||||
}
|
||||
let canlender = []
|
||||
const surplus = 42 - (dates.lastMonthDays.length + dates.currentMonthDys.length)
|
||||
dates.nextMonthDays = this._getNextMonthDays(surplus, this.getDate(dateData))
|
||||
canlender = canlender.concat(dates.lastMonthDays, dates.currentMonthDys, dates.nextMonthDays)
|
||||
let weeks = {}
|
||||
// 拼接数组 上个月开始几天 + 本月天数+ 下个月开始几天
|
||||
for (let i = 0; i < canlender.length; i++) {
|
||||
if (i % 7 === 0) {
|
||||
weeks[parseInt(i / 7)] = new Array(7)
|
||||
}
|
||||
weeks[parseInt(i / 7)][i % 7] = canlender[i]
|
||||
}
|
||||
this.canlender = canlender
|
||||
this.weeks = weeks
|
||||
}
|
||||
|
||||
//静态方法
|
||||
// static init(date) {
|
||||
// if (!this.instance) {
|
||||
// this.instance = new Calendar(date);
|
||||
// }
|
||||
// return this.instance;
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
export default Calendar
|
||||
398
app/components/uniNoticeBar/uni-notice-bar.vue
Normal file
398
app/components/uniNoticeBar/uni-notice-bar.vue
Normal file
@@ -0,0 +1,398 @@
|
||||
<template>
|
||||
<view v-if="show" class="uni-noticebar" :style="'background-color:'+backgroundColor+';'" @click="onClick">
|
||||
<!-- <uni-icons v-if="showIcon === true || showIcon === 'true'" class="uni-noticebar-icon" type="sound"
|
||||
:color="color" size="22" /> -->
|
||||
<view ref="textBox" class="uni-noticebar__content-wrapper"
|
||||
:class="{'uni-noticebar__content-wrapper--scrollable':scrollable, 'uni-noticebar__content-wrapper--single':!scrollable && (single || moreText)}">
|
||||
<view :id="elIdBox" class="uni-noticebar__content"
|
||||
:class="{'uni-noticebar__content--scrollable':scrollable, 'uni-noticebar__content--single':!scrollable && (single || moreText)}">
|
||||
<text :id="elId" ref="animationEle" class="uni-noticebar__content-text"
|
||||
:class="{'uni-noticebar__content-text--scrollable':scrollable,'uni-noticebar__content-text--single':!scrollable && (single || showGetMore)}"
|
||||
:style="{color:color, width:wrapWidth+'px', 'animationDuration': animationDuration, '-webkit-animationDuration': animationDuration ,animationPlayState: webviewHide?'paused':animationPlayState,'-webkit-animationPlayState':webviewHide?'paused':animationPlayState, animationDelay: animationDelay, '-webkit-animationDelay':animationDelay}">{{text}}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="showGetMore === true || showGetMore === 'true'" class="uni-noticebar__more uni-cursor-point"
|
||||
@click="clickMore">
|
||||
<text v-if="moreText.length > 0" :style="{ color: moreColor }" class="uni-noticebar__more-text">{{ moreText }}</text>
|
||||
<!-- <uni-icons v-else type="right" :color="moreColor" size="16" /> -->
|
||||
</view>
|
||||
<view class="uni-noticebar-close uni-cursor-point" v-if="(showClose === true || showClose === 'true') && (showGetMore === false || showGetMore === 'false')">
|
||||
<!-- <uni-icons
|
||||
type="closeempty" :color="color" size="16" @click="close" /> -->
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// #ifdef APP-NVUE
|
||||
const dom = weex.requireModule('dom');
|
||||
const animation = weex.requireModule('animation');
|
||||
// #endif
|
||||
|
||||
/**
|
||||
* NoticeBar 自定义导航栏
|
||||
* @description 通告栏组件
|
||||
* @tutorial https://ext.dcloud.net.cn/plugin?id=30
|
||||
* @property {Number} speed 文字滚动的速度,默认100px/秒
|
||||
* @property {String} text 显示文字
|
||||
* @property {String} backgroundColor 背景颜色
|
||||
* @property {String} color 文字颜色
|
||||
* @property {String} moreColor 查看更多文字的颜色
|
||||
* @property {String} moreText 设置“查看更多”的文本
|
||||
* @property {Boolean} single = [true|false] 是否单行
|
||||
* @property {Boolean} scrollable = [true|false] 是否滚动,为true时,NoticeBar为单行
|
||||
* @property {Boolean} showIcon = [true|false] 是否显示左侧喇叭图标
|
||||
* @property {Boolean} showClose = [true|false] 是否显示左侧关闭按钮
|
||||
* @property {Boolean} showGetMore = [true|false] 是否显示右侧查看更多图标,为true时,NoticeBar为单行
|
||||
* @event {Function} click 点击 NoticeBar 触发事件
|
||||
* @event {Function} close 关闭 NoticeBar 触发事件
|
||||
* @event {Function} getmore 点击”查看更多“时触发事件
|
||||
*/
|
||||
|
||||
export default {
|
||||
name: 'UniNoticeBar',
|
||||
emits: ['click', 'getmore', 'close'],
|
||||
props: {
|
||||
prConfig: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
text: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
moreText: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
backgroundColor: {
|
||||
type: String,
|
||||
default: '#FFF9EA'
|
||||
},
|
||||
speed: {
|
||||
// 默认1s滚动100px
|
||||
type: Number,
|
||||
default: 100
|
||||
},
|
||||
color: {
|
||||
type: String,
|
||||
default: '#FF9A43'
|
||||
},
|
||||
moreColor: {
|
||||
type: String,
|
||||
default: '#FF9A43'
|
||||
},
|
||||
single: {
|
||||
// 是否单行
|
||||
type: [Boolean, String],
|
||||
default: false
|
||||
},
|
||||
scrollable: {
|
||||
// 是否滚动,添加后控制单行效果取消
|
||||
type: [Boolean, String],
|
||||
default: false
|
||||
},
|
||||
showIcon: {
|
||||
// 是否显示左侧icon
|
||||
type: [Boolean, String],
|
||||
default: false
|
||||
},
|
||||
showGetMore: {
|
||||
// 是否显示右侧查看更多
|
||||
type: [Boolean, String],
|
||||
default: false
|
||||
},
|
||||
showClose: {
|
||||
// 是否显示左侧关闭按钮
|
||||
type: [Boolean, String],
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
const elId = `Uni_${Math.ceil(Math.random() * 10e5).toString(36)}`
|
||||
const elIdBox = `Uni_${Math.ceil(Math.random() * 10e5).toString(36)}`
|
||||
return {
|
||||
textWidth: 0,
|
||||
boxWidth: 0,
|
||||
wrapWidth: '',
|
||||
webviewHide: false,
|
||||
// #ifdef APP-NVUE
|
||||
stopAnimation: false,
|
||||
// #endif
|
||||
elId: elId,
|
||||
elIdBox: elIdBox,
|
||||
show: true,
|
||||
animationDuration: 'none',
|
||||
animationPlayState: 'paused',
|
||||
animationDelay: '0s'
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
// #ifdef APP-PLUS
|
||||
var pages = getCurrentPages();
|
||||
var page = pages[pages.length - 1];
|
||||
var currentWebview = page.$getAppWebview();
|
||||
currentWebview.addEventListener('hide', () => {
|
||||
this.webviewHide = true
|
||||
})
|
||||
currentWebview.addEventListener('show', () => {
|
||||
this.webviewHide = false
|
||||
})
|
||||
// #endif
|
||||
this.$nextTick(() => {
|
||||
this.initSize()
|
||||
})
|
||||
},
|
||||
// #ifdef APP-NVUE
|
||||
beforeDestroy() {
|
||||
this.stopAnimation = true
|
||||
},
|
||||
// #endif
|
||||
methods: {
|
||||
initSize() {
|
||||
if (this.scrollable) {
|
||||
// #ifndef APP-NVUE
|
||||
let query = [],
|
||||
boxWidth = 0,
|
||||
textWidth = 0;
|
||||
let textQuery = new Promise((resolve, reject) => {
|
||||
uni.createSelectorQuery()
|
||||
// #ifndef MP-ALIPAY
|
||||
.in(this)
|
||||
// #endif
|
||||
.select(`#${this.elId}`)
|
||||
.boundingClientRect()
|
||||
.exec(ret => {
|
||||
this.textWidth = ret[0].width
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
let boxQuery = new Promise((resolve, reject) => {
|
||||
uni.createSelectorQuery()
|
||||
// #ifndef MP-ALIPAY
|
||||
.in(this)
|
||||
// #endif
|
||||
.select(`#${this.elIdBox}`)
|
||||
.boundingClientRect()
|
||||
.exec(ret => {
|
||||
this.boxWidth = ret[0].width
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
query.push(textQuery)
|
||||
query.push(boxQuery)
|
||||
Promise.all(query).then(() => {
|
||||
this.animationDuration = `${this.textWidth / this.speed}s`
|
||||
this.animationDelay = `-${this.boxWidth / this.speed}s`
|
||||
setTimeout(() => {
|
||||
this.animationPlayState = 'running'
|
||||
}, 1000)
|
||||
})
|
||||
// #endif
|
||||
// #ifdef APP-NVUE
|
||||
dom.getComponentRect(this.$refs['animationEle'], (res) => {
|
||||
let winWidth = uni.getSystemInfoSync().windowWidth
|
||||
this.textWidth = res.size.width
|
||||
animation.transition(this.$refs['animationEle'], {
|
||||
styles: {
|
||||
transform: `translateX(-${winWidth}px)`
|
||||
},
|
||||
duration: 0,
|
||||
timingFunction: 'linear',
|
||||
delay: 0
|
||||
}, () => {
|
||||
if (!this.stopAnimation) {
|
||||
animation.transition(this.$refs['animationEle'], {
|
||||
styles: {
|
||||
transform: `translateX(-${this.textWidth}px)`
|
||||
},
|
||||
timingFunction: 'linear',
|
||||
duration: (this.textWidth - winWidth) / this.speed * 1000,
|
||||
delay: 1000
|
||||
}, () => {
|
||||
if (!this.stopAnimation) {
|
||||
this.loopAnimation()
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
})
|
||||
// #endif
|
||||
}
|
||||
// #ifdef APP-NVUE
|
||||
if (!this.scrollable && (this.single || this.moreText)) {
|
||||
dom.getComponentRect(this.$refs['textBox'], (res) => {
|
||||
this.wrapWidth = res.size.width
|
||||
})
|
||||
}
|
||||
// #endif
|
||||
},
|
||||
loopAnimation() {
|
||||
// #ifdef APP-NVUE
|
||||
animation.transition(this.$refs['animationEle'], {
|
||||
styles: {
|
||||
transform: `translateX(0px)`
|
||||
},
|
||||
duration: 0
|
||||
}, () => {
|
||||
if (!this.stopAnimation) {
|
||||
animation.transition(this.$refs['animationEle'], {
|
||||
styles: {
|
||||
transform: `translateX(-${this.textWidth}px)`
|
||||
},
|
||||
duration: this.textWidth / this.speed * 1000,
|
||||
timingFunction: 'linear',
|
||||
delay: 0
|
||||
}, () => {
|
||||
if (!this.stopAnimation) {
|
||||
this.loopAnimation()
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
// #endif
|
||||
},
|
||||
clickMore() {
|
||||
this.$emit('getmore')
|
||||
},
|
||||
close() {
|
||||
this.show = false;
|
||||
this.$emit('close')
|
||||
},
|
||||
onClick() {
|
||||
this.$emit('click')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.uni-noticebar {
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
/* #endif */
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
width: 460rpx;
|
||||
}
|
||||
|
||||
.uni-cursor-point {
|
||||
/* #ifdef H5 */
|
||||
cursor: pointer;
|
||||
/* #endif */
|
||||
}
|
||||
|
||||
.uni-noticebar-close {
|
||||
margin-left: 8px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.uni-noticebar-icon {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.uni-noticebar__content-wrapper {
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.uni-noticebar__content-wrapper--single {
|
||||
/* #ifndef APP-NVUE */
|
||||
line-height: 18px;
|
||||
/* #endif */
|
||||
}
|
||||
|
||||
.uni-noticebar__content-wrapper--single,
|
||||
.uni-noticebar__content-wrapper--scrollable {
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
/* #ifndef APP-NVUE */
|
||||
.uni-noticebar__content-wrapper--scrollable {
|
||||
position: relative;
|
||||
height: 18px;
|
||||
}
|
||||
|
||||
/* #endif */
|
||||
|
||||
.uni-noticebar__content--scrollable {
|
||||
/* #ifdef APP-NVUE */
|
||||
flex: 0;
|
||||
/* #endif */
|
||||
/* #ifndef APP-NVUE */
|
||||
flex: 1;
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
/* #endif */
|
||||
}
|
||||
|
||||
.uni-noticebar__content--single {
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
flex: none;
|
||||
width: 100%;
|
||||
justify-content: center;
|
||||
/* #endif */
|
||||
}
|
||||
|
||||
.uni-noticebar__content-text {
|
||||
font-size: 14px;
|
||||
line-height: 18px;
|
||||
/* #ifndef APP-NVUE */
|
||||
word-break: break-all;
|
||||
/* #endif */
|
||||
}
|
||||
|
||||
.uni-noticebar__content-text--single {
|
||||
/* #ifdef APP-NVUE */
|
||||
lines: 1;
|
||||
/* #endif */
|
||||
/* #ifndef APP-NVUE */
|
||||
display: block;
|
||||
width: 100%;
|
||||
white-space: nowrap;
|
||||
/* #endif */
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.uni-noticebar__content-text--scrollable {
|
||||
/* #ifdef APP-NVUE */
|
||||
lines: 1;
|
||||
padding-left: 750rpx;
|
||||
/* #endif */
|
||||
/* #ifndef APP-NVUE */
|
||||
position: absolute;
|
||||
display: block;
|
||||
height: 18px;
|
||||
line-height: 18px;
|
||||
white-space: nowrap;
|
||||
padding-left: 100%;
|
||||
animation: notice 10s 0s linear infinite both;
|
||||
animation-play-state: paused;
|
||||
/* #endif */
|
||||
}
|
||||
|
||||
.uni-noticebar__more {
|
||||
/* #ifndef APP-NVUE */
|
||||
display: inline-flex;
|
||||
/* #endif */
|
||||
flex-direction: row;
|
||||
flex-wrap: nowrap;
|
||||
align-items: center;
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
.uni-noticebar__more-text {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
@keyframes notice {
|
||||
100% {
|
||||
transform: translate3d(-100%, 0, 0);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,5 +1,6 @@
|
||||
<template>
|
||||
<view class="evaluateWtapper" v-if="reply.length > 0">
|
||||
<!-- v-if="reply.length>0" -->
|
||||
<view class="evaluateWtapper" v-if="reply.length>0">
|
||||
<view class="evaluateItem" v-for="(item, indexw) in reply" :key="indexw">
|
||||
<view class="pic-text acea-row">
|
||||
<view class="pictrue">
|
||||
@@ -24,7 +25,7 @@
|
||||
</view>
|
||||
</view>
|
||||
<view class="reply" v-if="item.merchantReplyContent">
|
||||
<text class="font-color">店小二</text>:{{ item.merchantReplyContent }}
|
||||
<text class="font_color">店小二</text>:{{ item.merchantReplyContent }}
|
||||
</view>
|
||||
</view>
|
||||
|
||||
@@ -38,7 +39,7 @@
|
||||
props: {
|
||||
reply: {
|
||||
type: Array,
|
||||
default: []
|
||||
default: () => []
|
||||
}
|
||||
},
|
||||
data: function() {
|
||||
@@ -148,4 +149,7 @@
|
||||
top: -14rpx;
|
||||
left: 40rpx;
|
||||
}
|
||||
.font_color{
|
||||
@include main_color(theme);
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user