feat(uniapp_v2): 二开功能迁移与小程序主包优化

- 从 uniapp 迁移 HJF 页面、API、组件及用户/订单相关改动
- queue、assets 使用独立分包以降低主包体积
- 修复首页单根节点与支付结果页 v-if 链
- 关闭 HjfDemoPanel 全局注册;uniNoticeBar 注释 $getAppWebview 避免 __webviewId__ 报错
- 配置域名与 manifest 应用名称;cache/store 防御性处理

Made-with: Cursor
This commit is contained in:
apple
2026-03-26 12:16:01 +08:00
parent c84aeda062
commit 8e17762510
742 changed files with 184117 additions and 0 deletions

View File

@@ -0,0 +1,184 @@
<template>
<view :style="colorStyle">
<view class="px-20">
<view class="order_card bg--w111-fff rd-24rpx pt-32 pb-32 pl-24 pr-24"
v-for="(item, index) in bargain" :key="index">
<view class="flex-between-center">
<text class="fs-28 lh-40rpx">{{item.add_time}}</text>
<text class="font-color fs-26" v-if="item.status === 1">活动进行中</text>
<text class="font-color fs-26" v-else-if="item.status === 3">砍价成功</text>
<text class="font-color fs-26" v-else>活动已结束</text>
</view>
<view class="flex-between-center mt-26">
<easy-loadimage
:image-src="item.image"
width="136rpx"
height="136rpx"
borderRadius="16rpx"></easy-loadimage>
<view class="flex-1 pl-20">
<view class="w-504 line2 fs-28 lh-40rpx">{{item.title}}</view>
<view class="flex items-baseline mt-20">
<text class="fs-24 text--w111-999">已砍至</text>
<baseMoney :money="item.residue_price" symbolSize="20" integerSize="32" decimalSize="20" weight></baseMoney>
</view>
</view>
</view>
<view class="pt-24 bt mt-32 flex-between-center">
<view class="flex-y-center fs-24" v-if="item.status === 1">
<text class="pr-12 text--w111-999">剩余:</text>
<count-down
justify-left="justify-content:left"
:is-day="true"
tip-text=" "
day-text=" "
hour-text=""
minute-text=""
second-text=""
dotColor="#999"
:datatime="item.datatime"></count-down>
</view>
<text class="pr-12 text--w111-999 fs-24" v-if="item.status === 2">活动已结束</text>
<text class="pr-12 text--w111-999 fs-24" v-if="item.status === 3">砍价已成功</text>
<view class="flex">
<view class="btn w-154 h-56 rd-30rpx flex-center fs-24 border_ccc"
v-if="item.status === 1"
@tap="getBargainUserCancel(item.bargain_id)"
>取消活动</view>
<view class="btn w-154 h-56 rd-30rpx flex-center fs-24 bg-color text--w111-fff"
v-if="item.status === 1"
@tap="goDetail(item.bargain_id)"
>{{item.pay_status ? '立即付款' : '继续砍价'}}</view>
<view class="btn w-154 h-56 rd-30rpx flex-center fs-24 bg-color text--w111-fff"
v-if="[2,3].includes(item.status)" @tap="goPage('/pages/activity/goods_bargain/index')">重开一个</view>
</view>
</view>
</view>
<Loading :loaded="status" :loading="loadingList"></Loading>
</view>
<view class="px-20 mt-20" v-if="!bargain.length">
<emptyPage title="暂无砍价记录~" src="/statics/images/noOrder.gif"></emptyPage>
</view>
<home></home>
</view>
</template>
<script>
import CountDown from "@/components/countDown";
import emptyPage from '@/components/emptyPage.vue'
import {
getBargainUserList,
getBargainUserCancel
} from "@/api/activity";
import { getUserInfo } from '@/api/user.js';
import Loading from "@/components/Loading";
import colors from "@/mixins/color";
export default {
name: "BargainRecord",
components: {
CountDown,
Loading,
emptyPage,
},
props: {},
mixins: [colors],
data: function() {
return {
bargain: [],
status: false, //砍价列表是否获取完成 false 未完成 true 完成
loadingList: false, //当前接口是否请求完成 false 完成 true 未完成
page: 1, //页码
limit: 20, //数量
userInfo: {}
};
},
onLoad: function() {
this.getBargainUserList();
this.getUserInfo();
},
onShow(){
uni.removeStorageSync('form_type_cart');
},
methods: {
goDetail: function(id) {
uni.navigateTo({
url: `/pages/activity/goods_bargain_details/index?id=${id}&spid=${this.userInfo.uid}`
})
},
getBargainUserList: function() {
var that = this;
if (that.loadingList) return;
if (that.status) return;
getBargainUserList({
page: that.page,
limit: that.limit
})
.then(res => {
that.status = res.data.length < that.limit;
that.bargain.push.apply(that.bargain, res.data);
that.page++;
that.loadingList = false;
})
.catch(res => {
that.$util.Tips({
title: res
})
});
},
getBargainUserCancel: function(bargainId) {
var that = this;
getBargainUserCancel({
bargainId: bargainId
})
.then(res => {
that.status = false;
that.loadingList = false;
that.page = 1;
that.bargain = [];
that.getBargainUserList();
that.$util.Tips({
title: res.msg
})
})
.catch(res => {
that.$util.Tips({
title: res
})
});
},
/**
* 获取个人用户信息
*/
getUserInfo: function() {
let that = this;
getUserInfo().then(res => {
that.userInfo = res.data;
});
},
goPage(url){
uni.navigateTo({
url
})
}
},
onReachBottom() {
this.getBargainUserList();
},
onPageScroll(object) {
uni.$emit('scroll');
},
};
</script>
<style lang="scss">
.order_card{
margin-top:20rpx;
}
.border_ccc {
border: 1rpx solid #ccc;
}
.bt{
border-top: 1rpx solid #eee;
}
.btn ~ .btn{
margin-left: 16rpx;
}
</style>

View File

@@ -0,0 +1,445 @@
<template>
<view :style="colorStyle">
<view class="w-full h-400 relative z-10" :style="{'height': (186 + sysHeight) * 2 + 'rpx', 'background' : headerBg}">
<NavBar titleText="领券中心"
textSize="34rpx"
:bagColor="pageScrollStatus ? 'var(--view-theme)' : 'transparent'"
iconColor="#ffffff"
textColor="#ffffff"
showBack></NavBar>
<view class="abs-box flex-col">
<image src="../static/get_coupon_text.png" class="w-184 h-46"></image>
<text class="fs-24 lh-34rpx text--w111-fff pt-20">天天来领券优惠看的见</text>
</view>
</view>
<view class="relative rd-t-40rpx bg--w111-f5f5f5 w-full content">
<view class="_box flex-between-center text--w111-666 fs-30 lh-42rpx"
:class="pageScrollStatus ? '' : 'rd-t-40rpx'"
:style="{'top': (38 + sysHeight) * 2 + 'rpx'}">
<text :class="current == 0 ? 'font-num fw-500' : ''" @tap="changeTab(0)">默认排序</text>
<view class="flex-y-center" @tap="changeTab(1)">
<text :class="current == 1 ? 'font-num fw-500' : ''">最新</text>
<text v-show="params.timeOrder == 'desc'" class="iconfont icon-ic_down2 fs-14 ml-6 font-num"></text>
<text v-show="params.timeOrder == 'asc'" class="iconfont icon-ic_up2 fs-14 ml-6 font-num"></text>
<text v-show="params.timeOrder == ''" class="iconfont icon-ic_down2 fs-14 ml-6"></text>
<!-- timeOrder -->
</view>
<view class="flex-y-center" @tap="changeTab(2)">
<text :class="current == 2 ? 'font-num fw-500' : ''">价值</text>
<text v-show="params.priceOrder == 'desc'" class="iconfont icon-ic_down2 fs-14 ml-6 font-num"></text>
<text v-show="params.priceOrder == 'asc'" class="iconfont icon-ic_up2 fs-14 ml-6 font-num"></text>
<text v-show="params.priceOrder == ''" class="iconfont icon-ic_down2 fs-14 ml-6"></text>
</view>
<view class="flex-y-center" @tap="showDrop = !showDrop">
<text class="menu_line"></text>
<text>筛选</text>
<text class="iconfont icon-ic_sort pl-8"></text>
</view>
<view class="drop-box bg--w111-f5f5f5" v-if="showDrop">
<scroll-view scroll-x="true" class="white-nowrap vertical-middle w-full" show-scrollbar="false">
<view class="inline-block h-52 rd-28rpx px-28 lh-52rpx text-center fs-24 bg--w111-fff mr-24"
v-for="(item, index) in navList" :key="index"
:class="params.type === item.type ? 'active-tab' : ''"
@tap="setType(item.type)">{{item.name}}</view>
</scroll-view>
</view>
</view>
<view class="px-20" v-if="couponsList.length">
<view class="relative card-item" v-for="(item,index) in couponsList" :key="index">
<view class="card w-full h-200 bg--w111-fff rd-24rpx p-20 flex justify-between"
:class="{svip: item.category == 2}">
<text class="pr-8 svip-cup" v-if="item.category == 2">svip</text>
<view class="flex">
<easy-loadimage
mode="aspectFit"
:image-src="item.products[0].image"
width="160rpx"
height="160rpx"
borderRadius="16rpx" v-if="item.products[0] && item.products[0].image"></easy-loadimage>
<view class="w-160 h-160 rd-16rpx flex-center fs-22 text--w111-999" v-else>暂无商品</view>
<view class="w-338 pl-24">
<view class="w-286 h-72 lh-36rpx line2 fw-500" :class="item.is_use ? 'text--w111-ccc' : ''">
{{item.title}}</view>
<view class="fs-20 lh-28rpx mt-8" :class="item.is_use ? 'text--w111-ccc' : 'text--w111-666'"
v-if="item.coupon_time">领取后{{item.coupon_time}}天内可用</view>
<view class="fs-20 lh-28rpx mt-8" :class="item.is_use ? 'text--w111-ccc' : 'text--w111-666'"
v-else>{{ item.start_time ? item.start_time + '-' : '' }}{{ item.end_time }}</view>
<view class="flex-y-center fs-20 text--w111-999 lh-28rpx mt-20">
<text>{{item.type | typeFilter}}</text>
<view v-show="item.rule" @tap="toggleRule(item)">
<text class="pl-8"> | 查看用券规则</text>
<text class="iconfont icon-ic_downarrow fs-20 ml-4"></text>
</view>
</view>
</view>
</view>
<view class="flex-1 flex-col flex-center">
<baseMoney
:money="item.coupon_price"
symbolSize="28"
integerSize="44"
decimalSize="28"
:color="item.is_use ? '#cccccc' : item.receive_type === 4 ? '#333' : 'var(--view-theme)'"
isCoupon
v-if="item.coupon_type==1"></baseMoney>
<view v-else class="fs-44 SemiBold"
:style="{color: item.is_use ? '#cccccc' : item.receive_type === 4 ? '#333' : 'var(--view-theme)'}"
>{{ parseFloat(item.coupon_price) / 10 }} <text class="pingfang fs-28 pl-4"></text></view>
<text class="fs-20 lh-28rpx mt-8"
:class="item.is_use ? 'text--w111-ccc' : 'font-num'" v-show="item.use_min_price == 0">无门槛券</text>
<text class="fs-20 lh-28rpx mt-8"
:class="item.is_use ? 'text--w111-ccc' : 'font-num'" v-show="item.use_min_price != 0">{{item.use_min_price}}可用</text>
<view class="w-128 h-48 rd-30rpx flex-center fs-20 bg-hui text--w111-fff mt-16" v-if="item.is_use == true">已领取</view>
<view class="w-128 h-48 rd-30rpx flex-center fs-20 bg-hui text--w111-fff mt-16" v-else-if="item.is_use == 2">已领完</view>
<view class="w-128 h-48 rd-30rpx flex-center fs-20 bg-gradient text--w111-fff mt-16" v-else
@tap="getCoupon(item, index)">立即领取</view>
</view>
</view>
<view class="rule-desc" v-html="item.rule" v-show="item.ruleShow"></view>
</view>
</view>
<view class='loadingicon flex-center' v-if="couponsList.length">
<text class='loading iconfont icon-jiazai' :hidden='loading==false'></text>{{loadTitle}}
</view>
<view class="px-20" v-if="!couponsList.length">
<emptyPage title="暂无优惠券,去看点别的吧~" src="/statics/images/noCoupon.gif"></emptyPage>
</view>
</view>
<view class="mask" v-if="showDrop" @tap="showDrop = false"></view>
<home></home>
</view>
</template>
<script>
let sysHeight = uni.getWindowInfo().statusBarHeight;
import { getCoupons, setCouponReceive } from '@/api/api.js';
import emptyPage from '@/components/emptyPage.vue';
import NavBar from "@/components/NavBar.vue"
import { toLogin } from '@/libs/login.js';
import { mapGetters } from "vuex";
import colors from '@/mixins/color.js';
import {HTTP_REQUEST_URL} from '@/config/app';
export default {
mixins:[colors],
components:{ emptyPage, NavBar },
data() {
return {
sysHeight:sysHeight,
couponsList: [],
loading: false,
loadend: false,
loadTitle: '加载更多', //提示语
params:{
page: 1,
limit: 20,
type: '',
defaultOrder: 1,
timeOrder: '',
priceOrder: ''
},
isAuto: false, //没有授权的不会自动授权
isShowAuth: false, //是否隐藏授权
navList: [
{name: '全部',type: ''},
{name: '快过期',type: -1},
{name: '通用券',type: 0},
{name: '品类券',type: 1},
{name: '商品券',type: 2},
{name: '品牌券',type: 3},
],
count: 0,
imgHost:HTTP_REQUEST_URL,
pageScrollStatus:false,
showDrop: false,
current:0,
price: 0,
};
},
watch: {
isLogin: {
handler: function(newV, oldV) {
if (newV) {
this.getUseCoupons();
}
},
deep: true
},
},
computed:{
...mapGetters(['isLogin']),
headerBg(){
return 'url('+this.imgHost+'/statics/images/get_coupon_bg.png'+')' + 'no-repeat center center/100% 100%, linear-gradient(90deg, var(--view-gradient) 0%, var(--view-theme) 100%)'
}
},
filters:{
typeFilter(val){
let obj = {
0: '通用券',
1: '品类券',
2: '商品券',
3: '品牌券',
};
return obj[val]
}
},
onPageScroll(object) {
if (object.scrollTop > 130) {
this.pageScrollStatus = true;
} else if (object.scrollTop < 130) {
this.pageScrollStatus = false;
}
uni.$emit('scroll');
},
onLoad() {
if (this.isLogin) {
this.getUseCoupons();
} else {
toLogin()
}
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom() {
this.getUseCoupons();
},
//#ifdef MP
onShareAppMessage() {
let that = this;
return {
title: '领券中心',
path: '/pages/activity/coupon/index?spid=' + that.$store.state.app.uid,
// desc: ''
};
},
//分享到朋友圈
onShareTimeline: function() {
let that = this;
return {
title: '领券中心',
path: '/pages/activity/coupon/index?spid=' + + that.$store.state.app.uid,
// desc: ''
};
},
//#endif
methods: {
changeTab(val){
this.current = val;
if(val == 0){
this.params.defaultOrder = 1;
this.params.timeOrder = '';
this.params.priceOrder = '';
}else if(val == 1){
if(this.params.timeOrder == '') {
this.params.timeOrder = 'asc'
}else if (this.params.timeOrder == 'asc'){
this.params.timeOrder = 'desc'
}else if(this.params.timeOrder == 'desc'){
this.params.timeOrder = ''
}
this.params.defaultOrder = '';
this.params.priceOrder = '';
} else if(val == 2){
if(this.params.priceOrder == '') {
this.params.priceOrder = 'asc'
}else if (this.params.priceOrder == 'asc'){
this.params.priceOrder = 'desc'
}else if(this.params.priceOrder == 'desc'){
this.params.priceOrder = ''
}
this.params.defaultOrder = '';
this.params.timeOrder = '';
}
this.couponsList = [];
this.loadend = false;
this.loading = false;
this.params.page = 1;
this.getUseCoupons();
},
toggleRule(item){
item.ruleShow = !item.ruleShow
},
backPage(){
uni.navigateBack()
},
goDetails(item){
uni.navigateTo({
url: '/pages/goods_details/index?id=' + item.id
})
},
getCoupon: function(item, index) {
let that = this;
let list = that.couponsList;
//领取优惠券
setCouponReceive(item.id).then(function(res) {
if(res.data.receive_count >= item.receive_limit){
list[index].is_use = true;
}
that.$set(that, 'couponsList', list);
that.$util.Tips({
title: '领取成功'
});
}).catch(error => {
return that.$util.Tips({
title: error
});
})
},
/**
* 获取领取优惠券列表
*/
getUseCoupons: function() {
let that = this
if (this.loadend) return false;
if (this.loading) return false;
that.loading = true;
that.loadTitle = '加载更多';
getCoupons(this.params).then(res => {
let list = res.data.list,
loadend = list.length < that.params.limit,
countIndex = [];
list.map(item=>{
this.$set(item,'ruleShow',false);
})
let couponsList = that.$util.SplitArray(list, that.couponsList);
that.$set(that, 'couponsList', couponsList);
that.loadend = loadend;
that.loading = false;
that.loadTitle = loadend ? '没有更多内容啦~' : '加载更多';
that.params.page++;
}).catch(err => {
that.loading = false;
that.loadTitle = '加载更多';
});
},
setType(type) {
if (this.params.type !== type) {
this.params.type = type;
}else{
this.params.type = '';
}
this.params.page = 1;
this.couponsList = [];
this.loadend = false;
this.showDrop = false;
this.getUseCoupons();
}
}
};
</script>
<style scoped lang="scss">
.abs-box{
width: 264rpx;
position: absolute;
left: 48rpx;
bottom: 80rpx;
}
.content{
top: -44rpx;
}
.menu_line {
width: 1rpx;
height: 26rpx;
background: #ccc;
margin: 0 32rpx 0 20rpx;
}
._box{
padding: 28rpx 32rpx;
background: #f5f5f5;
position: sticky;
z-index: 99;
}
.drop-box{
width: 100%;
// height: 102rpx;
position: absolute;
left: 0;
top: 94rpx;
border-radius: 0 0 40rpx 40rpx;
z-index: 199;
padding: 10rpx 32rpx 24rpx;
}
.active-tab{
background: var(--view-minorColorT);
color: var(--view-theme);
border: 1px solid var(--view-theme);
}
.svip .font-num{
color: #333333 !important;
}
.svip .bg-gradient{
background: linear-gradient(90deg, #584834 0%, #32302D 100%);
color: #FACC7D;
}
.bg-hui{
color: #ffffff !important;
background: #cccccc !important;
}
.indent{
text-indent: 60rpx;
}
.card{
background-image:
radial-gradient(circle at 500rpx top, #f5f5f5, #f5f5f5 10rpx, transparent 11rpx),
radial-gradient(circle at 500rpx bottom, #f5f5f5, #f5f5f5 10rpx, transparent 11rpx);
position: relative;
&:before{
content: '';
position: absolute;
left: 500rpx;
top: 16rpx;
height: 168rpx;
border-left: 2px dotted #ddd;
}
.name {
width: 286rpx;
height: 80rpx;
line-height: 40rpx;
color: #333;
font-weight: 500;
font-size: 28rpx;
}
.type-tag{
display: inline-block;
background: var(--view-minorColorT);
color: var(--view-theme);
border-radius: 14rpx;
padding: 2rpx 10rpx;
font-size: 20rpx;
margin-right: 8rpx;
vertical-align: middle;
}
}
.card-item ~ .card-item{
margin-top: 20rpx;
}
.rule-desc{
margin-top: -16rpx;
padding: 40rpx 24rpx 24rpx;
white-space: pre-wrap;
font-size: 20rpx;
line-height: 28rpx;
background: linear-gradient(180deg, #F7F7F7 0%, #FFFFFF 100%);
border-radius: 0 0 24rpx 24rpx;
color: #999;
}
.SemiBold{
font-family: 'SemiBold'
}
.pingfang{
font-family: PingFang SC, PingFang SC;
}
.svip-cup{
position: absolute;
left: 0;
top: 0;
border-radius: 20rpx 0 20rpx 0;
background-color: #FFD700;
color: #fff;
font-size: 24rpx;
padding-left: 10rpx;
z-index: 1;
}
</style>

View File

@@ -0,0 +1,91 @@
<template>
<view class="container">
<view class="bg-card" :style="{backgroundImage:headerBg}"></view>
<view class="bg--w111-fff rd-24rpx form-card">
<!-- <view class="fs-30 fw-500 lh-42rpx text-center">卡券兑换</view> -->
<view class="w-full bg--w111-f9f9f9 rd-12rpx pl-24 mt-38">
<input type="text" v-model="cardForm.card_number" placeholder="请输入卡号"
placeholder-class="fs-30 text--w111-b3b3b3" class="w-full h-88 fs-30 lh-42rpx" />
</view>
<view class="w-full bg--w111-f9f9f9 rd-12rpx pl-24 mt-32">
<input type="text" v-model="cardForm.card_pwd" placeholder="请输入密码"
placeholder-class="fs-30 text--w111-b3b3b3" class="w-full h-88 fs-30 lh-42rpx" />
</view>
<button class="w-full h-88 rd-44rpx flex-center text--w111-fff bg-btn fs-28 mt-54" :disabled="disabled" @tap="exchangeConfirm">立即验证</button>
</view>
</view>
</template>
<script>
import { giftCardGetInfoApi } from "@/api/activity.js";
import { HTTP_REQUEST_URL } from '@/config/app';
import { mapState, mapGetters } from 'vuex';
import { toLogin } from '@/libs/login.js';
export default {
name: "",
data(){
return {
cardForm:{
card_number:"",
card_pwd: ""
},
disabled: false
}
},
computed:{
...mapGetters(['isLogin']),
headerBg(){
return 'url('+ HTTP_REQUEST_URL +'/statics/images/activity/gift_bg.png'+')'
}
},
onLoad() {
},
methods:{
exchangeConfirm(){
if(this.isLogin){
giftCardGetInfoApi(this.cardForm).then(res=>{
this.disabled = false;
uni.navigateTo({
url: "/pages/activity/giftCard/info?card_number=" + this.cardForm.card_number + '&card_pwd=' + this.cardForm.card_pwd
})
}).catch(err=>{
this.disabled = false;
return this.$util.Tips({
title: err
})
})
}else{
toLogin();
}
}
}
}
</script>
<style>
.form-card uni-button[disabled] {
background: #cccccc;
color: #fff;
}
.container{
height: 100vh;
background: #FFEED8;
}
.bg-card{
height: 648rpx;
background-size: 100% 648rpx;
background-repeat: no-repeat;
}
.form-card{
width: 670rpx;
height: 532rpx;
position: fixed;
top: 392rpx;
left: 42rpx;
z-index: 10;
padding: 40rpx 40rpx 60rpx;
}
.bg-btn{
background: linear-gradient( 90deg, #FF7931 0%, #E93323 100%);
}
</style>

View File

@@ -0,0 +1,274 @@
<template>
<view>
<view class="p-20">
<view class="relative">
<image class="w-full h-400 rd-24rpx block" mode="aspectFill" :src="cardInfo.cover_image"></image>
<view class="gift-badge px-14 rd-40rpx flex-center z-10">
<text class="iconfont icon-ic_card3 fs-32 text-yellow" v-show="cardInfo.type == 1"></text>
<text class="iconfont icon-ic_gift2 fs-32 text-red" v-show="cardInfo.type == 2"></text>
<text class="fs-24 pl-8" v-show="cardInfo.type == 1">{{cardInfo.balance}}元礼品卡</text>
<text class="fs-24 pl-8" v-show="cardInfo.type == 2">兑换卡</text>
</view>
</view>
<view class="w-full bg--w111-fff rd-16rpx px-24 mt-20" v-if="cardInfo.type == 2">
<view class="flex-between-center pt-32">
<view class="fs-28">可兑换商品
<text class="fs-24 text--w111-999 pl-12" v-if="cardInfo.exchange_type == 1">该兑换卡可兑换以下商品</text>
<text class="fs-24 text--w111-999 pl-12" v-else>任选 <text class="Regular text-red">{{ cardInfo.gift_num }}</text> 件兑换</text>
</view>
<text class="fs-28" v-if="cardInfo.exchange_type == 2">
<text class="text-red">{{ totalLimitNum }}</text> /{{cardInfo.gift_num}}
</text>
</view>
<view class="pb-32 product-box">
<view class="mt-24 flex" v-for="(item, index) in cardInfo.product" :key="index">
<image class="block w-200 h-200 rd-16rpx" :src="item.image"></image>
<view class="flex-1 h-200 flex-col justify-between pl-20">
<view>
<view class="w-444 line2 fs-28 h-80 lh-40rpx">{{ item.store_name }}</view>
<view class="inline-block max-w-444 h-38 lh-38rpx mt-8 bg--w111-f5f5f5 text--w111-999 rd-20rpx px-12 fs-22 line1">
{{ item.suk }}
</view>
</view>
<view class="flex-between-center">
<baseMoney :money="item.price"
symbolSize="24"
integerSize="36"
decimalSize="24"
color="#e93323"
weight></baseMoney>
<text class='Regular fs-28' v-if="cardInfo.exchange_type == 1">x{{ item.limit_num }}</text>
<view class="flex-y-center" v-else>
<button class="w-44 h-44 flex-center"
:disabled="item.limit_num <= 0"
@click="decreaseLimitNum(index)">
<text class="iconfont icon-ic_Reduce fs-24"></text>
</button>
<view class='w-88 h-44 text-center lh-44rpx bg--w111-f5f5f5'>{{ item.limit_num }}</view>
<button class="w-44 h-44 flex-center"
:disabled="totalLimitNum >= cardInfo.gift_num"
@click="increaseLimitNum(index)">
<text class="iconfont icon-ic_increase fs-24"></text>
</button>
</view>
</view>
</view>
</view>
</view>
</view>
<view class="w-full bg--w111-fff rd-16rpx p-24 mt-20 fs-28 lh-42rpx">
<view class="pb-20" v-if="cardInfo.type == 1">储值金额<text class="fs-26 text--w111-666 pl-16">¥{{cardInfo.balance}}</text></view>
<view>有效期至<text class="fs-26 text--w111-666 pl-16">{{ cardInfo.valid_type == 1 ? '永久有效' : cardInfo.fixed_time[1] }}</text></view>
</view>
<view class="w-full bg--w111-fff rd-16rpx px-24 mt-20">
<view class="fs-28 pt-32">使用须知</view>
<view class="pt-12 fs-26 text--w111-666 lh-36rpx space-line pb-32">{{ cardInfo.instructions }}</view>
</view>
<view class="w-full bg--w111-fff rd-16rpx px-24 mt-20">
<view class="fs-28 pt-32">礼品卡详情</view>
<view class="pt-12 fs-26 text--w111-666 lh-36rpx space-line pb-32" v-html="cardInfo.description"></view>
</view>
<view class="h-200"></view>
</view>
<view class="fixed-lb w-full pb-safe bg--w111-fff z-99">
<view class="w-full h-108 flex-between-center px-20">
<button class="btn-box w-full h-72 rd-40rpx flex-center fs-26 text--w111-fff"
:disabled="disabled"
@tap="exchangeGift">确认兑换</button>
</view>
</view>
<uni-popup ref="popup">
<view class="">
<view class="gift_pop bg--w111-fff relative">
<image class="header-pic" :src="imgHost + '/statics/images/activity/gift_open_pic.png'"></image>
<view class="success-text">
<view class="text-center text-red fs-34 fw-500 lh-48rpx">成功到账</view>
<view class="text-center fs-26 lh-36rpx pt-24">{{cardInfo.balance}}元已储值到您的账户中</view>
<view class="flex-x-center mt-54">
<view class="btn-box w-280 h-80 rd-40rpx flex-center fs-28 text--w111-fff" @tap="toMoney">去看看</view>
</view>
</view>
</view>
<view class="flex-center mt-94">
<text class="iconfont icon-ic_close1 text--w111-fff fs-50" @tap="closeGift"></text>
</view>
</view>
</uni-popup>
</view>
</template>
<script>
import { giftCardGetInfoApi, giftCardReceiveApi } from "@/api/activity.js";
import { HTTP_REQUEST_URL } from '@/config/app';
export default{
name:"",
data(){
return {
cardForm:{
card_number:"",
card_pwd: ""
},
cardInfo: {
id: "", //自增ID
name: "", //礼品卡名称
fixed_time: [],
type: 1, //礼品卡类型 1-储值卡 2-兑换卡
batch_id: "", //关联卡密
total_num: 1, //总数量
instructions: "", //使用说明
cover_image: "", //封面图
valid_type: 1, //有效期类型 1-永久有效 2-固定时间
status: 1, //礼品卡状态 0-禁用 1-启用
balance: 0, //储值金额
exchange_type: 1, //'兑换商品类型 1-固定商品打包 2-任选N件商品'
gift_num: 1, //兑换商品数量
description: "",
product: [], //兑换商品
},
disabled: false,
imgHost: HTTP_REQUEST_URL,
}
},
computed: {
totalLimitNum() {
return this.cardInfo.product.reduce((sum, item) => sum + item.limit_num, 0);
}
},
onLoad(options) {
this.cardForm.card_number = options.card_number;
this.cardForm.card_pwd = options.card_pwd;
if(options.card_number && options.card_pwd){
this.getInfo();
}
},
methods:{
getInfo(){
giftCardGetInfoApi(this.cardForm).then(res=>{
this.cardInfo = res.data;
this.cardInfo.description = res.data.description.replace(/<img/gi, '<img style="max-width: 100%;display:block;"');
uni.setNavigationBarTitle({
title: options.type == 1 ? '兑换礼金' : '兑换礼品'
})
}).catch(err=>{
return this.$util.Tips({
title: err
})
})
},
exchangeGift(){
if(this.cardInfo.exchange_type == 2){
if(this.totalLimitNum != this.cardInfo.gift_num) {
return this.$util.Tips({
title: "请检查兑换数量"
})
}
let product = this.cardInfo.product.
filter(item => item.limit_num !== 0).map(item=>{
return {
product_id: item.product_id,
limit_num: item.limit_num || 0,
unique: item.unique,
}
});
this.$set(this.cardForm,'product',product);
}
this.disabled = true;
giftCardReceiveApi(this.cardForm).then(res=>{
this.disabled = false;
if(this.cardInfo.type == 1){
this.$refs.popup.open();
}else{
let cardId = res.data.map(item=> item.cartId).join(",");
uni.navigateTo({
url: "/pages/goods/order_confirm/index?cartId=" + cardId + "&new=1"
})
}
}).catch(err=>{
this.disabled = false;
return this.$util.Tips({
title: err
})
})
},
toMoney(){
this.$refs.popup.close();
uni.redirectTo({
url: "/pages/users/user_bill/index?type=2"
})
},
closeGift(){
this.$refs.popup.close();
},
increaseLimitNum(index) {
if (this.totalLimitNum < this.cardInfo.gift_num) {
this.cardInfo.product[index].limit_num += 1;
}
},
decreaseLimitNum(index) {
if (this.cardInfo.product[index].limit_num > 0) {
this.cardInfo.product[index].limit_num -= 1;
}
}
}
}
</script>
<style lang="scss">
.product-box uni-button[disabled], .product-box button[disabled]{
background-color: #fff;
}
.fixed-lb uni-button[disabled], .fixed-lb button[disabled] {
background: #cccccc;
color: #fff;
}
.gift-badge{
position: absolute;
top: 24rpx;
left: 24rpx;
height: 46rpx;
background: rgba(255,255,255,0.8);
backdrop-filter: blur(8rpx)
}
.b-d{
border: 1rpx solid #DDDDDD;
}
.btn-box{
background: linear-gradient( 90deg, #E93323 0%, #FF7931 100%);
}
.max-w-444{
max-width: 444rpx;
}
.gift_pop{
width: 480rpx;
height: 500rpx;
border-radius: 48rpx;
.header-pic{
width: 480rpx;
height: 364rpx;
position: absolute;
top: -72rpx;
left: 0;
}
.success-text{
position: absolute;
top: 180rpx;
left: 0;
width: 480rpx;
.text-red{
color: #E93323;
}
}
}
.mt-94{
margin-top: 94rpx;
}
.fs-50{
font-size: 50rpx;
}
.text-red{
color: #e93323;
}
.text-yellow{
color: #FF7700;
}
</style>

View File

@@ -0,0 +1,257 @@
<template>
<!-- 砍价列表模块 -->
<view class="box">
<view class='bargain-list'>
<view class='header' :style="'background-image: url('+imgHost+'/statics/images/bargain-list-bg.png);'">
<NavBar titleText=" "
textSize="34rpx"
bagColor="transparent"
iconColor="#ffffff"
textColor="#ffffff"
showBack></NavBar>
</view>
<view class='list' v-if="bargainList.length">
<block v-for="(item,index) in bargainList" :key="index">
<view class='item flex justify-between relative'
@tap="openSubscribe('/pages/activity/goods_bargain_details/index?id='+ item.id +'&spid='+ userInfo.uid)">
<easy-loadimage
mode="aspectFit"
:image-src="item.image"
width="240rpx"
height="240rpx"
borderRadius="20rpx"></easy-loadimage>
<view class='w-410 fs-28 flex-col justify-between'>
<view>
<view class='w-410 lh-40rpx line2'>
<text v-if="item.brand_name" class="brand-tag">{{ item.brand_name }}</text>
{{item.title}}</view>
<view class='fs-22 fw-500 mt-8 red'>
<text class='iconfont icon-ic_fire fs-22 mr-8'></text>
{{item.people}}人正在参与
</view>
</view>
<view class="flex-between-center">
<view>
<view class='flex items-baseline red'>
<text class="fs-22 lh-30rpx fw-500">最低: </text>
<baseMoney :money="item.min_price" symbolSize="24" integerSize="40" decimalSize="24" incolor="#E93323" weight></baseMoney>
</view>
<view class="otPrice">{{item.price}}</view>
</view>
<view class='cutBnt w-144 h-56 rd-30rpx flex-center fs-24 text--w111-fff'>参与砍价</view>
</view>
</view>
</view>
</block>
</view>
<view class="list no-goods" v-if="!bargainList.length && !loading">
<image :src="imgHost + '/statics/images/noActivity.gif'" mode=""></image>
<text class="fs-26 text--w111-999 pt-16">暂无砍价商品去看看其他商品吧</text>
</view>
</view>
</view>
</template>
<script>
let app = getApp();
import { HTTP_REQUEST_URL } from '@/config/app';
import { getBargainList } from '@/api/activity.js';
import { openBargainSubscribe } from '@/utils/SubscribeMessage.js';
import { getUserInfo } from '@/api/user.js';
import { toLogin } from '@/libs/login.js';
import { mapGetters } from "vuex";
import emptyPage from '@/components/emptyPage.vue';
import NavBar from "@/components/NavBar.vue"
export default {
data() {
return {
bargainList: [],
page: 1,
limit: 20,
loading: false,
loadend: false,
userInfo: {},
isAuto: false, //没有授权的不会自动授权
isShowAuth: false, //是否隐藏授权
imgHost:HTTP_REQUEST_URL,
// #ifdef MP
getHeight: this.$util.getWXStatusHeight()
// #endif
};
},
components:{ emptyPage, NavBar },
computed: mapGetters(['isLogin']),
watch: {
isLogin: {
handler: function(newV, oldV) {
if (newV) {
// #ifndef MP
this.getUserInfo();
// #endif
}
},
deep: true
}
},
onLoad: function(options) {
this.getBargainList();
if (this.isLogin) {
this.getUserInfo();
}
},
onShow(){
uni.removeStorageSync('form_type_cart');
},
onPageScroll(object) {
uni.$emit('scroll');
},
methods: {
// 授权关闭
authColse: function(e) {
this.isShowAuth = e
},
goarrow(){
uni.navigateBack()
},
/*
* 获取用户信息
*/
getUserInfo: function() {
let that = this;
getUserInfo().then(res => {
that.$set(that, 'userInfo', res.data);
});
},
openSubscribe: function(e) {
if(this.isLogin){
let page = e;
// #ifndef MP
uni.navigateTo({
url: page
});
// #endif
// #ifdef MP
uni.showLoading({
title: '正在加载',
})
openBargainSubscribe().then(res => {
uni.hideLoading();
uni.navigateTo({
url: page,
});
}).catch((err) => {
uni.hideLoading();
});
// #endif
}else{
toLogin()
}
},
getBargainList: function() {
let that = this;
if (that.loadend) return;
if (that.loading) return;
that.loading = true;
getBargainList({
page: that.page,
limit: that.limit
}).then(function(res) {
that.$set(that, 'bargainList', that.bargainList.concat(res.data));
that.$set(that, 'page', that.page + 1);
that.$set(that, 'loadend', that.limit > res.data.length);
that.$set(that, 'loading', false);
}).catch(res => {
that.loading = false;
});
},
},
onReachBottom: function() {
this.getBargainList();
},
//#ifdef MP
onShareAppMessage() {
let that = this;
return {
title: '砍价列表',
path: '/pages/activity/goods_bargain/index?spid=' + that.$store.state.app.uid,
imageUrl: HTTP_REQUEST_URL+'/statics/images/bargain-list-bg.png',
// desc: ''
};
},
//分享到朋友圈
onShareTimeline: function() {
let that = this;
return {
title: '砍价列表',
path: '/pages/activity/goods_bargain/index?spid=' + + that.$store.state.app.uid,
imageUrl: HTTP_REQUEST_URL+'/statics/images/bargain-list-bg.png',
// desc: ''
};
}
//#endif
}
</script>
<style lang="scss">
.no-goods{
text-align: center;
padding-bottom: 60rpx!important;
color: #999;
image{
width: 440rpx;
height: 360rpx;
margin: 40rpx auto 0 auto;
display: block;
}
}
.bargain-list .header {
background-repeat: no-repeat;
background-size: 100% 100%;
width: 750rpx;
height: 926rpx;
padding-top: 55rpx;
box-sizing: border-box;
.iconfont{
color: #fff;
font-size: 40rpx;
margin-left: 15rpx;
}
}
.bargain-list .list {
background-color: #fff;
border-radius: 24rpx;
margin: -510rpx 20rpx 66rpx 20rpx;
padding: 32rpx 20rpx;
}
.brand-tag{
background-color: #e93323 !important;
}
.item~.item{
margin-top: 40rpx;
}
.red{
color: #E93323;
}
.otPrice{
font-size: 26rpx;
font-family: Regular;
color: #999;
text-decoration: line-through;
margin-top: 4rpx;
}
.cutBnt {
background: linear-gradient(90deg, #FF7931 0%, #E93323 100%);
}
.bargain-list .list .load {
font-size: 24rpx;
height: 85rpx;
text-align: center;
line-height: 85rpx;
}
</style>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,266 @@
<template>
<view>
<view class="w-full bg-top relative" :style="{backgroundImage:headerBg}">
<NavBar titleText="拼团活动"
textSize="34rpx"
:isScrolling="pageScrollStatus"
:iconColor="pageScrollStatus ? '#333333' : '#ffffff'"
:textColor="pageScrollStatus ? '#333333' : '#ffffff'"
showBack></NavBar>
</view>
<view class="relative rd-t-40rpx bg--w111-f5f5f5 w-full content">
<view class="" v-if="combinationList.length">
<view class="pt-32 pl-20 pr-20">
<view class="card w-full bg--w111-fff rd-24rpx p-20 flex"
v-for="(item,index) in combinationList" :key="index"
@tap="openSubcribe(item)">
<easy-loadimage
mode="aspectFit"
:image-src="item.image"
width="240rpx"
height="240rpx"
borderRadius="20rpx"></easy-loadimage>
<view class="flex-1 h-240 pl-20 flex-col justify-between">
<view class="w-full">
<view class="w-full fs-28 lh-40rpx line2">
<text v-if="item.brand_name" class="brand-tag">{{ item.brand_name }}</text>
{{item.title}}</view>
<view class="flex fs-20 mt-14">
<view class="tuan-num text--w111-fff flex-center">{{item.people}}人团</view>
<view class="complete font-red flex-center">已拼{{item.pink_count}}</view>
</view>
</view>
<view class="w-full flex-between-center">
<view>
<view class="flex items-baseline">
<text class="fs-22 lh-30rpx font-red fw-500">拼团价:</text>
<baseMoney :money="item.price" symbolSize="24" integerSize="40" decimalSize="24" color="#e93323" weight></baseMoney>
</view>
<view class="text-line text--w111-999 fs-22 lh-30rpx mt-12">¥{{item.product_price}}</view>
</view>
<view class="w-144 h-56 rd-30rpx flex-center fs-24 bg-red text--w111-fff" v-if="item.stock > 0 && item.quota > 0">参与拼团</view>
<view class="w-144 h-56 rd-30rpx flex-center fs-24 bg-gray text--w111-fff" v-else>参与拼团</view>
</view>
</view>
</view>
</view>
</view>
<view class="p-20" v-if="!combinationList.length">
<emptyPage title="暂无拼团商品,去看看其他商品吧~" src="/statics/images/noActivity.gif"></emptyPage>
</view>
</view>
</view>
</template>
<script>
import {
getCombinationList,
getCombinationBannerList,
getPink
} from '@/api/activity.js';
import { openPinkSubscribe } from '@/utils/SubscribeMessage.js';
import {
HTTP_REQUEST_URL
} from '@/config/app';
import emptyPage from '@/components/emptyPage.vue';
import NavBar from "@/components/NavBar.vue"
let app = getApp();
export default {
data() {
return {
pinkPeople: [],
pinkCount: 0,
bannerList: [],
circular: true,
autoplay: true,
interval: 3000,
duration: 500,
combinationList: [],
limit: 10,
page: 1,
loading: false,
loadend: false,
isBanner: false,
pageScrollStatus:false,
}
},
components:{ emptyPage, NavBar },
computed:{
headerBg(){
return 'url('+ HTTP_REQUEST_URL +'/statics/images/product/combination_header.png'+')'
}
},
onPageScroll(object) {
if (object.scrollTop > 130) {
this.pageScrollStatus = true;
} else if (object.scrollTop < 130) {
this.pageScrollStatus = false;
}
uni.$emit('scroll');
},
onLoad() {
uni.setNavigationBarTitle({
title: "拼团列表"
})
this.getCombinationList();
this.getBannerList();
this.getPink();
},
onShow() {
uni.removeStorageSync('form_type_cart');
},
methods: {
getPink: function() {
getPink({
type: 2
}).then(res => {
this.pinkPeople = res.data.avatars;
this.pinkCount = res.data.pink_count;
})
},
getBannerList: function() {
getCombinationBannerList().then(res => {
this.bannerList = res.data;
this.isBanner = true;
})
},
goDetail(item) {
let url = item.link;
this.$util.JumpPath(url);
},
openSubcribe: function(item) {
let page = item;
// #ifndef MP
uni.navigateTo({
url: `/pages/activity/goods_details/index?id=${item.id}&type=3`
});
// #endif
// #ifdef MP
uni.showLoading({
title: '正在加载',
})
openPinkSubscribe().then(res => {
uni.hideLoading();
uni.navigateTo({
url: `/pages/activity/goods_details/index?id=${item.id}&type=3`
});
}).catch(() => {
uni.hideLoading();
});
// #endif
},
getCombinationList: function() {
var that = this;
if (that.loadend) return;
if (that.loading) return;
var data = {
page: that.page,
limit: that.limit
};
this.loading = true
getCombinationList(data).then(function(res) {
var combinationList = that.combinationList;
var limit = that.limit;
that.page++;
that.loadend = limit > res.data.length;
that.combinationList = combinationList.concat(res.data);
that.page = that.data.page;
that.loading = false;
}).catch(() => {
that.loading = false
})
},
backPage(){
uni.navigateBack()
}
},
onReachBottom: function() {
this.getCombinationList();
},
//#ifdef MP
onShareAppMessage() {
let that = this;
return {
title: '拼团列表',
path: '/pages/activity/goods_combination/index?spid=' + that.$store.state.app.uid,
imageUrl: HTTP_REQUEST_URL+'/statics/images/product/combination_header.png',
// desc: ''
};
},
//分享到朋友圈
onShareTimeline: function() {
let that = this;
return {
title: '拼团列表',
path: '/pages/activity/goods_combination/index?spid=' + + that.$store.state.app.uid,
imageUrl: HTTP_REQUEST_URL+'/statics/images/product/combination_header.png',
// desc: ''
};
}
//#endif
}
</script>
<style lang="scss">
.h-470{
height: 470rpx;;
}
.w-624{
width: 624rpx;
}
.active-tab{
width: 132rpx;
height: 52rpx;
background: #FFF8E4;
color: #F85517;
border-radius: 30rpx;
font-weight: 500;
display: flex;
justify-content: center;
align-items: center;
}
.bg-top{
height: 547rpx;
background-size: 100% 100%;
background-repeat: no-repeat;
}
.content{
top: -80rpx;
}
._box{
padding: 40rpx 20rpx 32rpx;
background: #f5f5f5;
position: sticky;
z-index: 99;
}
.font-red{
color: #e93323;
}
.bg-red{
background-color: #e93323;
}
.bg-gray{
background-color: #ccc;
}
.con_border{
border: 1px solid #e93323;
}
.card ~ .card{
margin-top: 20rpx;
}
.tuan-num{
width: 70rpx;
height: 32rpx;
background: #E93323;
border-radius: 8rpx 0 0 8rpx;
}
.complete{
width: 110rpx;
height: 32rpx;
background: rgba(233, 51, 35, 0.1);
border-radius: 0 8rpx 8rpx 0;
}
.brand-tag{
background-color: #e93323 !important;
}
</style>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,437 @@
<template>
<!-- 限时秒杀模块 -->
<view :style="colorStyle">
<!-- #ifdef H5 -->
<view class="w-full bg-top h-604 relative" :style="{backgroundImage:headerBg}">
<!-- #endif -->
<!-- #ifndef H5 -->
<view class="w-full bg-top relative" :style="{backgroundImage:headerBg,height: (sysHeight + 262) * 2 + 'rpx'}">
<!-- #endif -->
<view class="fixed-lt w-full z-20"
:class="pageScrollStatus ? 'sticky' : ''"
:style="{'padding-top': sysHeight + 'px','background': pageScrollStatus ? '#e93323' : 'transparent'}">
<view class="w-full px-20 pl-20 h-80 flex-between-center">
<text class="iconfont icon-ic_leftarrow fs-40 text--w111-fff" @click="goPage(3)"></text>
<text class="fs-34 fw-500 text--w111-fff">{{pageScrollStatus ? '限时秒杀' : ''}}</text>
<text></text>
</view>
</view>
</view>
<view class="relative w-full content">
<view class="_box h-106 flex-y-center"
:class="pageScrollStatus ? '' : 'rd-t-24rpx'"
:style="{'top': 50 + sysHeight + 'px'}">
<scroll-view scroll-x="true" scroll-with-animation class="white-nowrap vertical-middle w-full relative z-10"
:class="{'sel1':active == 0,'sel-last': timeList.length > 4 && active == timeList.length - 1}"
show-scrollbar="false">
<view class="scroll-item"
v-for="(item,index) in timeList" :key='index'
:class="active == index ? 'active-card' : ''"
:style="{'background-image': active == index ? navActiveBg : ''}"
@tap='settimeList(item,index)'>
<view class="flex-col flex-center z-10 relative t-22">
<text class="SemiBold fs-40 lh-40rpx"
:class="active == index ? 'text--w111-333':'text--w111-fff'">{{item.time}}</text>
<text class="inline-block h-36 lh-34rpx fs-24"
:class="active == index ? 'red-tag':'text--w111-fff'">{{item.state}}</text>
</view>
</view>
</scroll-view>
<view class="abs-lb w-full"
:style="{'background': pageScrollStatus ? '#e93323' : 'rgba(245,245,245,0.2)','height': pageScrollStatus ? '130rpx' : '96rpx'}"></view>
</view>
<view class="bg--w111-f5f5f5 pt-32 pl-20 pr-20 relative" >
<view class="card w-full bg--w111-fff rd-24rpx p-20 flex" v-for="(item,index) in seckillList" :key="index"
@tap='goDetails(item)'>
<view class="w-240 h-240">
<easy-loadimage
mode="aspectFit"
:image-src="item.image"
:border-src="item.activity_image"
width="240rpx"
height="240rpx"
borderRadius="20rpx"></easy-loadimage>
</view>
<view class="flex-1 pl-20 flex-col justify-between">
<view class="w-full">
<view class="w-410 fs-28 lh-40rpx line2">
<text v-if="item.brand_name" class="brand-tag">{{ item.brand_name }}</text>
{{item.title}}</view>
<view class="w-410 flex items-end flex-wrap mt-12" v-if="item.store_label.length">
<BaseTag
:text="label.label_name"
:color="label.color"
:background="label.bg_color"
:borderColor="label.border_color"
:circle="label.border_color ? true : false"
:imgSrc="label.icon"
v-for="(label, idx) in item.store_label" :key="idx"></BaseTag>
</view>
</view>
<view class="flex items-baseline">
<text class="fs-22 lh-30rpx text-primary pr-8">秒杀价:</text>
<baseMoney :money="item.price" symbolSize="24" integerSize="40" decimalSize="24" color="#E93323" weight></baseMoney>
<text class="fs-22 lh-30rpx text--w111-999 pl-16 text-line">¥{{item.ot_price}}</text>
</view>
<view class="w-full progress-box flex-between-center" v-if="status == 1">
<view class="flex-y-center">
<view class="progress ml-16">
<view class="active" :style="'width:'+item.percent+'%;'"></view>
</view>
<text class="fs-22 text-primary pl-8">已抢{{item.percent}}%</text>
</view>
<view class="qiang"></view>
</view>
<view class="w-full yuyue-box flex-between-center" v-else-if="status == 2">
<view class="flex-y-center fs-22 pl-16">活动即将开始</view>
<view class="yuyue"></view>
</view>
<view class="w-full over-box flex-between-center" v-else>
<view class="flex-y-center fs-22 pl-16">活动已结束</view>
<view class="over"></view>
</view>
</view>
</view>
<view class="abs-lt cir" v-show="active > 0"></view>
</view>
<view class="bg--w111-f5f5f5 p-20" v-if="!seckillList.length && !pageloading">
<emptyPage title="暂无秒杀商品,去看看其他商品吧~" src="/statics/images/noActivity.gif"></emptyPage>
</view>
</view>
</view>
</template>
<script>
let sysHeight = uni.getWindowInfo().statusBarHeight;
import { getSeckillIndexTime, getSeckillList } from '@/api/activity.js';
import colors from '@/mixins/color.js'
import {HTTP_REQUEST_URL} from '@/config/app';
import emptyPage from '@/components/emptyPage.vue';
export default {
components: {
emptyPage
},
mixins:[colors],
data() {
return {
sysHeight:sysHeight,
topImage: '',
seckillList: [],
timeList: [],
active: 5,
scrollLeft: 0,
interval: 0,
status: 1,
countDownHour: "00",
countDownMinute: "00",
countDownSecond: "00",
page: 1,
limit: 8,
loading: false,
loadend: false,
pageloading: false,
intoindex:'',
imgHost:HTTP_REQUEST_URL,
pageScrollStatus: false
}
},
computed:{
headerBg(){
return 'url('+this.imgHost+'/statics/images/product/seckill_header.png'+')'
},
navActiveLeft(){
if(this.active == 0){
return 0
} else if(this.active == 1){
return '134rpx'
} else {
return 154 * this.active + 'rpx'
}
},
navActiveBg(){
if(this.active == 0){
return 'url('+this.imgHost+'/statics/images/product/seckill_header_icon1.png'+')'
}else{
return 'url('+this.imgHost+'/statics/images/product/seckill_header_icon2.png'+')'
}
}
},
onPageScroll(object) {
if (object.scrollTop > 200) {
this.pageScrollStatus = true;
} else if (object.scrollTop < 200) {
this.pageScrollStatus = false;
}
uni.$emit('scroll');
},
onLoad() {
this.getSeckillConfig();
},
onShow(){
uni.removeStorageSync('form_type_cart');
},
methods: {
getSeckillConfig: function() {
let that = this;
getSeckillIndexTime().then(res => {
that.topImage = res.data.lovely;
that.timeList = res.data.seckillTime;
that.active = res.data.seckillTimeIndex > -1 ? res.data.seckillTimeIndex : 0 ;
that.$nextTick(()=>{
that.intoindex = 'sort'+res.data.seckillTimeIndex > -1 ? res.data.seckillTimeIndex : 0
})
if (that.timeList.length) {
that.scrollLeft = (that.active - 1.37) * 100
setTimeout(function() {
that.loading = true
}, 2000);
that.seckillList = [],
that.page = 1
that.status = that.timeList[that.active].status
that.getSeckillList();
}
});
},
getSeckillList: function() {
var that = this;
var data = {
page: that.page,
limit: that.limit
};
if (that.loadend) return;
if (that.pageloading) return;
this.pageloading = true
getSeckillList(that.timeList[that.active].id, data).then(res => {
var seckillList = res.data;
var loadend = seckillList.length < that.limit;
that.page++;
that.seckillList = that.seckillList.concat(seckillList),
that.page = that.page;
that.pageloading = false;
that.loadend = loadend;
}).catch(err => {
that.pageloading = false
});
},
settimeList: function(item, index) {
var that = this;
this.active = index
if (that.interval) {
clearInterval(that.interval);
that.interval = null
}
that.interval = 0,
that.countDownHour = "00";
that.countDownMinute = "00";
that.countDownSecond = "00";
that.status = that.timeList[that.active].status;
that.loadend = false;
that.page = 1;
that.seckillList = [];
// wxh.time(e.currentTarget.dataset.stop, that);
that.getSeckillList();
},
goDetails(item){
uni.navigateTo({
url: '/pages/activity/goods_details/index?id=' + item.id + '&type=1&time_id=' + this.timeList[this.active].id
})
},
goPage(type, url){
if(type == 1){
uni.navigateTo({
url
})
}else if(type == 2){
uni.switchTab({
url
})
}else if(type == 3){
uni.navigateBack();
}
}
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function() {
this.getSeckillList();
},
//#ifdef MP
onShareAppMessage() {
let that = this;
return {
title: '秒杀列表',
path: '/pages/activity/goods_seckill/index?spid=' + that.$store.state.app.uid,
imageUrl: HTTP_REQUEST_URL+'/statics/images/product/seckill_header.png',
// desc: ''
};
},
//分享到朋友圈
onShareTimeline: function() {
let that = this;
return {
title: '秒杀列表',
path: '/pages/activity/goods_seckill/index?spid=' + + that.$store.state.app.uid,
imageUrl: HTTP_REQUEST_URL+'/statics/images/product/seckill_header.png',
// desc: ''
};
}
//#endif
}
</script>
<style lang="scss">
.bg-top{
background-size: 100% 100%;
background-repeat: no-repeat;
}
.sticky{
&:after{
content:'';
width:100%;
height: 20px;
background-color: #E93323;
position: absolute;
left: 0;
bottom: -20rpx;
}
}
.content{
top: -114rpx;
}
._box{
position: sticky;
z-index: 99;
}
.card ~ .card{
margin-top: 20rpx;
}
.w-21-p111-{
width: 21%;
}
.max-w-96{
max-width: 96rpx;
}
.fq{
background-color: #E93323;
color: #fff;
}
.text-primary{
color: #E93323;;
}
.text-line{
text-decoration: line-through;
}
.progress-box{
height: 64rpx;
background-color: rgba(233, 51, 35, 0.05);
border-radius: 16rpx;
}
.progress{
width:160rpx;
height: 18rpx;
border-radius: 10rpx;
background-color: rgba(233, 51, 35, 0.2);
.active{
height: 18rpx;
border-radius: 10rpx;
background: linear-gradient(90deg, #FF7931 0%, #E93323 100%);
}
}
.qiang{
width:112rpx;
height: 64rpx;
background-image: url('../static/qiang.png');
background-size: cover;
}
.yuyue-box{
height: 64rpx;
background-color: #FFF1E5;
border-radius: 16rpx;
color: #FF7D00;
}
.yuyue{
width:140rpx;
height: 64rpx;
background-image: url('../static/yuyue.png');
background-size: cover;
}
.over-box{
height: 64rpx;
background-color: rgba(233, 51, 35, 0.05);
border-radius: 16rpx;
color: rgba(233, 51, 35, 0.60);
}
.over{
width:140rpx;
height: 64rpx;
background-image: url('../static/over.png');
background-size: cover;
}
.sel1 .scroll-item{
right: 30rpx;
}
.sel-last {
/deep/.uni-scroll-view{
margin-right: -10rpx;
}
.scroll-item{
// left: 40rpx;
// left: 32rpx;
}
.active-card{
width: 180rpx;
padding-left: 10px;
.relative{
width: 160rpx;
}
}
}
.scroll-item{
display: inline-block;
height: 96rpx;
width: 21%;
position: relative;
bottom: 0;
}
.active-card{
width:234rpx;
height: 106rpx;
background-size: cover;
z-index: 99;
}
.t-22{
top: 22rpx;
}
.red-tag{
display: inline-block;
padding: 0 12rpx;
height: 36rpx;
border-radius: 18rpx;
text-align: center;
line-height: 36rpx;
background-color: #E93323;
font-size: 22rpx;
color: #fff;
}
.cir{
width: 24rpx;
height: 24rpx;
background-color: #ED593E;
&:after{
content: '';
width: 24rpx;
height: 24rpx;
position: absolute;
left: 0;
top: 0;
border-top-left-radius: 100%; /* 左上角为半径大小的弧形 */
background-color: #f5f5f5;
}
}
.brand-tag{
background-color: #e93323 !important;
}
</style>

View File

@@ -0,0 +1,334 @@
<template>
<view>
<!-- #ifdef H5 -->
<view class="bg-top h-644" :style="{'background-image' : headerBg}">
<!-- #endif -->
<!-- #ifndef H5 -->
<view class="bg-top" :style="{'height': 282 + sysHeight + 'px', 'background-image' : headerBg}">
<!-- #endif -->
<NavBar titleText="新人礼"
textSize="34rpx"
:isScrolling="pageScrollStatus"
:iconColor="pageScrollStatus ? '#333333' : '#ffffff'"
:textColor="pageScrollStatus ? '#333333' : '#ffffff'"
showBack></NavBar>
<view class="rule-btn px-12 flex-center fs-24 text--w111-fff z-999"
:style="{top: 110 + sysHeight + 'px'}"
@tap="goAgree">新人礼规则</view>
</view>
<view class="px-20">
<view class="bg--w111-fff rd-24rpx pt-32 pr-24 pb-32 pl-24 relative top200"
v-if="info.register_give_coupon ? info.register_give_coupon.length : false">
<view class="flex-center">
<image src="../static/new_person_star.png" class="star"></image>
<text class="fs-32 lh-44rpx fw-500 px-16">新人优惠券</text>
<image src="../static/new_person_star.png" class="star star-right"></image>
</view>
<view class="grid-column-3 grid-gap-38rpx mt-36">
<view class="coupon-item flex-col flex-between-center"
v-for="(item,index) in showMore ? info.register_give_coupon : info.register_give_coupon.slice(0,6)" :key="index">
<view class="flex-col flex-center">
<baseMoney :money="item.coupon_price" symbolSize="28" integerSize="44"
decimalSize="28" color="#e93323" weight v-if="item.coupon_type==1"></baseMoney>
<view v-else class="font-red fs-32 flex-y-center"><text class="SemiBold fs-44">{{parseFloat(item.coupon_price)/10}}</text></view>
<text class="fs-20 lh-28rpx font-red pt-6">{{item.applicable_type | typeFilter}}</text>
</view>
<view class="fs-24 lh-34rpx text--w111-fff" v-if="item.use_min_price > 0">{{item.use_min_price}}可用</view>
<view class="fs-24 lh-34rpx text--w111-fff" v-else>无门槛</view>
</view>
</view>
<view class="w-full mt-24 flex-center fs-24 text--w111-999"
v-if="info.register_give_coupon.length > 6" @tap="showMoreChange">
<text>{{showMore ? '点击收起' : '点击展开'}}</text>
<text class="iconfont fs-24" :class="showMore ? 'icon-ic_uparrow' : 'icon-ic_downarrow'"></text>
</view>
<view class="w-full h-88 rd-44rpx flex-center bg-jianbian text--w111-fff fs-28 mt-32"
@tap="goPage('/pages/users/user_coupon/index',1)">查看优惠券</view>
</view>
<view class="bg--w111-fff rd-24rpx pt-32 pr-24 pl-24 relative top200 mt-20">
<view class="flex-center">
<image src="../static/new_person_star.png" class="star"></image>
<text class="fs-32 lh-44rpx fw-500 px-16">新人福利</text>
<image src="../static/new_person_star.png" class="star star-right"></image>
</view>
<view class="mt-10">
<view class="cell flex-between-center py-32" v-if="info.register_give_integral > 0">
<view class="flex-y-center">
<image :src="imgHost + '/statics/images/newcomer/integral_icon.png'" class="w-72 h-72"></image>
<view class="flex-col ml-24">
<text class="fs-28 fw-500 lh-40rpx">新人赠送积分</text>
<text class="fs-22 text--w111-999 lh-30rpx pt-6">新人即可获得{{info.register_give_integral}}积分</text>
</view>
</view>
<view class="w-120 h-56 rd-28rpx flex-center bg-jianbian text--w111-fff fs-24"
@tap="goPage('/pages/users/user_integral/index',1)">去查看</view>
</view>
<view class="cell flex-between-center py-32" v-if="info.register_give_money > 0">
<view class="flex-y-center">
<image :src="imgHost + '/statics/images/newcomer/money_icon.png'" class="w-72 h-72"></image>
<view class="flex-col ml-24">
<text class="fs-28 fw-500 lh-40rpx">新人赠送余额</text>
<text class="fs-22 text--w111-999 lh-30rpx pt-6">新人即可获得{{info.register_give_money}}余额</text>
</view>
</view>
<view class="w-120 h-56 rd-28rpx flex-center bg-jianbian text--w111-fff fs-24"
@tap="goPage('/pages/users/user_money/index',1)">去查看</view>
</view>
<view class="cell flex-between-center py-32" v-if="info.first_order_status">
<view class="flex-y-center">
<image :src="imgHost + '/statics/images/newcomer/coupon_icon.png'" class="w-72 h-72"></image>
<view class="flex-col ml-24">
<text class="fs-28 fw-500 lh-40rpx">新人下单享首单优惠</text>
<text class="fs-22 text--w111-999 lh-30rpx pt-6">首次下单享{{parseFloat(info.first_order_discount)/10 || 10}}折优惠哦</text>
</view>
</view>
<view class="w-120 h-56 rd-28rpx flex-center bg-jianbian text--w111-fff fs-24"
@tap="goPage('/pages/goods/goods_list/index',1)">去查看</view>
</view>
</view>
</view>
<view class="bg--w111-fff rd-24rpx pt-32 pr-24 pb-32 pl-24 relative top200 mt-20"
v-if="newList.length">
<view class="flex-center">
<image src="../static/new_person_star.png" class="star"></image>
<text class="fs-32 lh-44rpx fw-500 px-16">新人商品专区</text>
<image src="../static/new_person_star.png" class="star star-right"></image>
</view>
<view class="grid-column-3 grid-gap-20rpx mt-36">
<view class="" v-for="(item,index) in newList" :key="index"
@click="goPage(`/pages/activity/goods_details/index?id=${item.id}&type=7`,1)">
<image class="w-full h-210 rd-16rpx" :src="item.image" mode="aspectFit"></image>
<view class="w-full line2 fs-28 lh-40rpx fw-500 mt-24 mb-14">{{item.store_name}}</view>
<baseMoney :money="item.price" symbolSize="24" integerSize="40"
decimalSize="24" color="#e93323" weight></baseMoney>
</view>
</view>
</view>
</view>
<base-drawer mode="bottom" :visible="showDrawer" background-color="transparent" mask maskClosable @close="goAgree">
<view class="w-full bg--w111-fff rd-t-40rpx py-32 relative">
<view class="text-center fs-32 text--w111-333 fw-500">新人礼规则</view>
<view class="close flex-center" @tap='goAgree'>
<text class="iconfont icon-ic_close fs-24 text--w111-999"></text>
</view>
<view class="mt-48 px-32 scroll-content">
<!-- #ifdef MP-WEIXIN -->
<rich-text :nodes="rule"></rich-text>
<!-- #endif -->
<!-- #ifdef H5 || APP-PLUS -->
<view v-html="rule"></view>
<!-- #endif -->
</view>
<view class="mx-20 pb-safe">
<view class="mt-52 h-72 flex-center rd-36px bg-red fs-26 text--w111-fff" @click="goAgree">我知道了</view>
</view>
</view>
</base-drawer>
</view>
</template>
<script>
let sysHeight = uni.getWindowInfo().statusBarHeight;
import countDown from '@/components/countDown';
import baseDrawer from '@/components/tui-drawer/tui-drawer.vue';
import NavBar from "@/components/NavBar.vue"
import {
newcomerInfo,
newcomerList
} from '@/api/activity.js';
import { getUserAgreement } from "@/api/user.js"
import { toLogin } from '@/libs/login.js';
import { mapGetters } from "vuex";
import {HTTP_REQUEST_URL} from '@/config/app';
export default {
components: {
countDown,
NavBar,
baseDrawer
},
data() {
return {
sysHeight:sysHeight,
imgHost:HTTP_REQUEST_URL,
info: {
// register_give_coupon:[
// {coupon_price: 20,type:1,coupon_type:1},
// {coupon_price: 20,type:1,coupon_type:1},
// {coupon_price: 20,type:1,coupon_type:1},
// ]
},
newList:[],
loading: false,
loadend: false,
loadTitle: '加载更多',
page: 1,
limit: 9,
showMore: false,
pageScrollStatus:false,
rule:'',
showDrawer:false
};
},
filters:{
typeFilter(val){
let obj = {
0: '通用券',
1: '品类券',
2: '商品券',
3: '品牌券',
};
return obj[val]
}
},
watch: {
isLogin: {
handler: function(newV, oldV) {
if (newV) {
this.getNewcomerInfo();
this.productList();
}
},
deep: true
},
},
computed:{
...mapGetters(['isLogin']),
headerBg(){
return 'url('+this.imgHost+'/statics/images/newcomer/header.png'+')'
}
},
onLoad() {
if (this.isLogin) {
this.getNewcomerInfo();
this.productList();
this.getAgreeContent();
} else {
toLogin()
}
},
onPageScroll(object) {
if (object.scrollTop > 80) {
this.pageScrollStatus = true;
} else if (object.scrollTop < 80) {
this.pageScrollStatus = false;
}
},
methods: {
goAgree(){
this.showDrawer = !this.showDrawer;
},
getAgreeContent(){
getUserAgreement('newcomer_agreement').then((res) => {
this.rule = res.data.content;
})
.catch((err) => {
that.$util.Tips({
title: err.msg
});
});
},
getNewcomerInfo() {
newcomerInfo().then(res => {
res.data.last_time = parseInt(res.data.last_time);
this.info = res.data;
}).catch(err => {
this.$util.Tips({
title: err
});
})
},
productList() {
let that = this;
if (that.loading) return;
if (that.loadend) return;
that.loading = true;
that.loadTitle = '';
newcomerList({
page: that.page,
limit: that.limit
}).then(res=>{
let list = res.data;
let loadend = list.length < that.limit;
that.newList = that.$util.SplitArray(list, that.newList);
that.$set(that, 'newList', that.newList);
that.loadend = loadend;
that.loadTitle = loadend ? '没有更多内容啦~' : '加载更多';
that.page = that.page + 1;
that.loading = false;
}).catch(err=>{
that.loading = false;
that.loadTitle = '加载更多';
this.$util.Tips({
title: err
});
})
},
goPage(url, type){
if(type == 1){
uni.navigateTo({
url
})
}else if(type == 3){
uni.navigateBack()
}
},
showMoreChange(){
this.showMore = !this.showMore;
}
},
onReachBottom() {
this.productList();
}
}
</script>
<style lang="scss">
/deep/ .navbar{
z-index: 90;
}
.bg-top{
background-size: cover;
}
.rule-btn{
height: 48rpx;
background: rgba(0,0,0,0.3);
border-radius: 24rpx 0 0 24rpx;
position: fixed;
right: 0;
z-index: 20;
}
.close{
position: absolute;
right: 32rpx;
top: 36rpx;
width: 36rpx;
height: 36rpx;
border-radius: 50%;
background-color: #eee;
}
.top200{
top: -200rpx;
}
.star{
width: 54rpx;
height: 24rpx;
}
.star-right{
display: block;
transform: scaleX(-1);
}
.coupon-item{
height: 186rpx;
padding: 20rpx 0 18rpx;
background-image: url('../static/coupon_item_bg.png');
background-size: cover;
}
.font-red{
color: #E93323;
}
.bg-jianbian{
background: linear-gradient(90deg, #FF7931 0%, #E93323 100%);
}
.cell ~ .cell{
border-top: 1px solid #eee;
}
</style>

View File

@@ -0,0 +1,513 @@
<template>
<view :style="colorStyle">
<NavBar titleText="积分商城"
textSize="34rpx"
bagColor="linear-gradient(90deg, var(--view-theme) 0%, var(--view-gradient) 100%)"
iconColor="#ffffff"
textColor="#ffffff"
showBack></NavBar>
<view class="header">
<view class="headerBg">
<view class="pictrue">
<image src="../static/mall03.png"></image>
</view>
<view class="num">当前积分{{integral}}</view>
</view>
<navigator hover-class='none' url='/pages/goods/order_list/index?type=4' class="record acea-row row-center-wrapper">兑换记录</navigator>
</view>
<view class="nav acea-row row-middle row-around">
<navigator hover-class='none' url='/pages/users/user_integral/index' class="item">
<view class="pictrue">
<image src="../static/mall05.png"></image>
</view>
<view>我的积分</view>
</navigator>
<view class="line"></view>
<navigator hover-class='none' url='/pages/users/user_sgin/index' class="item">
<view class="pictrue">
<image src="../static/mall04.png"></image>
</view>
<view>每日签到</view>
</navigator>
<view class="line"></view>
<navigator hover-class='none' url='/pages/goods/lottery/grids/index?type=1' class="item">
<view class="pictrue">
<image src="../static/mall02.png"></image>
</view>
<view>积分抽奖</view>
</navigator>
</view>
<view class="hot" v-if="goodList.length">
<view class="title">热门推荐</view>
<scroll-view scroll-x="true" class="scroll">
<view class="scroll-item" v-for="(item,index) in goodList" :key="index" @click="goGoodsDetail(item)">
<view class="pictrue">
<image :src='item.image' mode="aspectFit"></image>
</view>
<view class="name line1">{{item.title}}</view>
<view class="info">已有{{item.sales}}人兑换</view>
<view class="price-box acea-row row-middle">
<view class="acea-row row-middle" v-if="parseFloat(item.integral)">
<image src="../static/mall05.png"></image>
<text class="font-num">{{ item.integral }}</text>
</view>
<text v-if="parseFloat(item.integral) && parseFloat(item.price)">+</text>
<text v-if="parseFloat(item.price)">
<text class="font-num">{{ item.price }}</text>
<text class="fs-22"></text>
</text>
</view>
</view>
</scroll-view>
</view>
<view class="body">
<view class="body-title">
<scroll-view scroll-x="true" class="scroll">
<view class="item" :class="index == current?'on':''"
v-for="(item, index) in navList" :key="index"
@click="navTap(item,index)">{{item.value}}{{index?'积分':''}}</view>
</scroll-view>
</view>
<view class="product-list" v-if="integralGood.length">
<view class="product-item" v-for="(item, index) in integralGood" :key="index"
@click="goGoodsDetail(item)">
<easy-loadimage
mode="aspectFit"
:image-src="item.image"
width="314rpx"
height="314rpx"
borderRadius="20rpx 20rpx 0 0"></easy-loadimage>
<view class="info">
<view class="title line1">
<text v-if="item.brand_name" class="brand-tag">{{ item.brand_name }}</text>
{{ item.title }}</view>
<view class="sales">已有{{item.sales}}人兑换</view>
<view class="price-box acea-row row-middle">
<view class="acea-row row-middle" v-if="parseFloat(item.integral)">
<image src="../static/mall05.png"></image>
<text class="font-num">{{ item.integral }}</text>
</view>
<text v-if="parseFloat(item.integral) && parseFloat(item.price)">+</text>
<text v-if="parseFloat(item.price)">
<text class="font-num">{{ item.price }}</text>
<text class="fs-22"></text>
</text>
</view>
</view>
</view>
</view>
<view v-else class="no-goods">
<emptyPage title="暂无商品,去看看别的吧~" src="/statics/images/noActivity.gif"></emptyPage>
</view>
</view>
</view>
</template>
<script>
let sysHeight = uni.getWindowInfo().statusBarHeight;
import {
toLogin
} from '@/libs/login.js';
import {
mapGetters
} from 'vuex';
import {
getStoreIntegral,
getIntegralCategory,
getStoreIntegralList
} from '@/api/activity.js'
import {
goShopDetail
} from '@/libs/order.js';
import colors from "@/mixins/color";
import {HTTP_REQUEST_URL} from '@/config/app';
import emptyPage from '@/components/emptyPage.vue';
import NavBar from "@/components/NavBar.vue"
export default {
components: { emptyPage, NavBar },
mixins: [colors],
data() {
return {
sysHeight,
// #ifdef MP
getHeight: this.$util.getWXStatusHeight(),
// #endif
goodList: [],
navList: [],
current: 0,
where: {
range: '',
page: 1,
limit: 10,
},
integralGood: [],
imgHost: HTTP_REQUEST_URL,
loadend: false,
loading: false,
loadTitle: '加载更多',
integral: 0,
pageScrollStatus:false,
}
},
computed: mapGetters(['isLogin']),
onLoad() {
this.integralCategory();
this.storeIntegralList();
if (this.isLogin) {
this.getStoreIntegral();
} else {
toLogin();
}
},
watch: {
isLogin: {
handler: function(newV, oldV) {
if (newV == true) {
this.getStoreIntegral();
}
},
deep: true
},
},
onShow(){
uni.removeStorageSync('form_type_cart');
},
onPageScroll(object) {
if (object.scrollTop > 130) {
this.pageScrollStatus = true;
} else if (object.scrollTop < 130) {
this.pageScrollStatus = false;
}
uni.$emit('scroll');
},
methods: {
integralCategory(){
getIntegralCategory().then(res=>{
let data = res.data;
data.unshift({
value:'全部'
})
this.navList = data;
}).catch(err=>{
return this.$util.Tips({
title: err
});
})
},
navTap(item,index){
if (this.current === index) return;
this.current = index;
this.where.range = item.value;
this.where.page = 1;
this.loadend = false;
this.$set(this, 'integralGood', []);
this.storeIntegralList();
},
storeIntegralList(){
if (this.loadend) return;
if (this.loading) return;
this.loading = true;
getStoreIntegralList(this.where).then(res=>{
let list = res.data;
let limit = this.where.limit;
this.where.page++;
this.loadend = limit > list.length;
this.integralGood = this.integralGood.concat(list);
this.loading = false;
this.loadTitle = loadend ? '没有更多内容啦~' : '加载更多';
}).catch(err=>{
this.loading = false;
this.loadTitle = '加载更多';
return this.$util.Tips({
title: err
});
})
},
goarrow(){
uni.navigateBack()
},
getStoreIntegral() {
getStoreIntegral().then(res => {
this.goodList = res.data.list;
this.integral = res.data.integral;
})
},
// 去商品详情
goGoodsDetail(item) {
uni.navigateTo({
url: `/pages/activity/goods_details/index?id=${item.id}&type=4`
});
}
},
onReachBottom() {
this.storeIntegralList();
},
//#ifdef MP
onShareAppMessage() {
let that = this;
return {
title: '积分商城',
path: '/pages/activity/points_mall/index?spid=' + that.$store.state.app.uid,
// desc: ''
};
},
//分享到朋友圈
onShareTimeline: function() {
let that = this;
return {
title: '积分商城',
path: '/pages/activity/points_mall/index?spid=' + + that.$store.state.app.uid,
// desc: ''
};
}
//#endif
}
</script>
<style lang="scss" scoped>
page{
padding-bottom: 40rpx;
}
.accountTitle{
background: linear-gradient(90deg, var(--view-theme) 0%, var(--view-gradient) 100%);
position: fixed;
left:0;
top:0;
width: 100%;
z-index: 99;
.sysTitle{
width: 100%;
position: relative;
font-weight: 500;
color: #fff;
font-size: 30rpx;
.iconfont{
position: absolute;
font-size: 36rpx;
left:11rpx;
width: 60rpx;
}
}
}
.header{
width: 100%;
height: 400rpx;
background: linear-gradient(90deg, var(--view-theme) 0%, var(--view-gradient) 100%);
position: relative;
.record{
width: 124rpx;
height: 48rpx;
background-color: rgba(51, 51, 51, 0.2);
border-radius: 50rpx 0 0 50rpx;
font-weight: 400;
color: #FFFFFF;
font-size: 24rpx;
position: absolute;
right: 0;
top:36rpx;
}
&::after{
position: absolute;
content: '';
width: 100%;
height: 105rpx;
background: linear-gradient(180deg, rgba(233,51,35,0) 0%, var(--view-minorColorT) 50%, #F5F5F5 100%);
}
.headerBg{
background-image: url('../static/mall01.png');
background-repeat: no-repeat;
background-size: 100% 100%;
width: 689rpx;
height: 298rpx;
margin: 0 auto;
padding-top: 88rpx;
.pictrue{
width: 345rpx;
height: 76rpx;
image{
width: 100%;
height: 100%;
}
}
.num{
font-size: 26rpx;
font-weight: 400;
color: rgba(255,255,255,0.6);
margin: 4rpx 0 0 12rpx;
}
}
}
.hot{
background-color: #fff;
width: 710rpx;
border-radius: 24rpx;
margin: 20rpx auto 0 auto;
padding: 32rpx 0 20rpx 32rpx;
.title{
font-weight: 600;
color: #333333;
font-size: 32rpx;
}
.scroll{
white-space: nowrap;
margin-top: 26rpx;
.scroll-item{
display: inline-block;
width: 224rpx;
margin-right: 20rpx;
vertical-align: top;
.pictrue{
width: 100%;
height: 224rpx;
image{
width: 100%;
height: 100%;
border-radius: 20rpx;
}
}
.name{
font-weight: 400;
color: #333333;
font-size: 26rpx;
margin-top: 16rpx;
}
.info{
color: #999999;
font-size: 22rpx;
margin-top: 8rpx;
}
.price-box{
font-size: 24rpx;
font-weight: 500;
margin-top: 10rpx;
color: #666;
image{
width: 31rpx;
height: 31rpx;
margin-right: 8rpx;
}
}
}
}
}
.nav{
width: 710rpx;
height: 184rpx;
background-color: #fff;
border-radius: 30rpx;
margin: -150rpx auto 0 auto;
position: relative;
.item{
font-size: 26rpx;
font-weight: 400;
color: #333333;
text-align: center;
width: 30%;
.pictrue{
width: 61rpx;
height: 61rpx;
margin: 0 auto 16rpx auto;
image{
width: 100%;
height: 100%;
}
}
}
.line{
width: 1px;
height: 70rpx;
background-color: #F3F3F3;
}
}
.body {
background-color: #fff;
width: 710rpx;
margin: 20rpx auto 0 auto;
border-radius: 24rpx;
padding-bottom: 20rpx;
.body-title {
padding-left: 32rpx;
.scroll{
white-space: nowrap;
.item{
display: inline-block;
margin-right: 60rpx;
padding: 34rpx 0 38rpx 0;
font-size: 28rpx;
font-weight: 400;
&.on{
font-weight: 500;
color: var(--view-theme);
position: relative;
font-size: 30rpx;
&::after{
position: absolute;
content: '';
width: 36rpx;
height: 30rpx;
border: 2px solid var(--view-theme);
border-left: 2px solid transparent !important;
border-top: 2px solid transparent !important;
border-right: 2px solid transparent !important;
border-radius: 50%;
left:50%;
bottom: 22rpx;
margin-left: -24rpx;
}
}
}
}
}
.product-list {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
padding: 0 32rpx;
.product-item {
position: relative;
width: 314rpx;
background: #fff;
border-radius: 10rpx;
margin-bottom: 20rpx;
.info {
margin-top: 20rpx;
.title {
font-size: 28rpx;
}
.price-box{
font-size: 24rpx;
font-weight: 500;
margin-top: 10rpx;
color: #666;
image{
width: 31rpx;
height: 31rpx;
margin-right: 8rpx;
}
}
.sales {
font-size: 24rpx;
color: #999999;
margin-top: 8rpx;
}
}
}
}
}
</style>

View File

@@ -0,0 +1,264 @@
<template>
<view>
<view class="w-full bg-top h-518 relative" :style="{backgroundImage:headerBg}">
<NavBar titleText="预售"
textSize="34rpx"
:isScrolling="pageScrollStatus"
:iconColor="pageScrollStatus ? '#333333' : '#ffffff'"
:textColor="pageScrollStatus ? '#333333' : '#ffffff'"
showBack></NavBar>
</view>
<view class="px-20">
<view class="bg--w111-fff rd-16rpx relative " style="top: -24rpx;">
<view class="w-full h-112 bg-primary-light nav-bg" :style="{backgroundImage:navBg}">
<view class="w-full flex-between-center pt-22 pl-76 pr-76">
<text class="fs-26 text--w111-666 lh-36rpx"
v-for="(item, index) in timeList" :key="index"
:class="active == index? 'active':''"
@tap="settimeList(item.key)">{{item.name}}</text>
</view>
</view>
<view class="w-full pl-20 pr-20 pb-40" v-if="presellList.length">
<view class="w-full flex justify-between pro-item"
v-for="(item,index) in presellList" :key="index"
@tap="goDetails(item)">
<easy-loadimage
:image-src="item.image"
width="240rpx"
height="240rpx"
borderRadius="16rpx"></easy-loadimage>
<view class="flex-1 flex-col justify-between pl-20">
<view class="w-full">
<view class="w-full fs-28 h-80 lh-40rpx line2">
<text v-if="item.brand_name" class="brand-tag">{{ item.brand_name }}</text>
{{item.store_name}}</view>
<view class="w-full flex items-end flex-wrap mt-16" v-if="item.store_label.length">
<BaseTag
:text="label.label_name"
:color="label.color"
:background="label.bg_color"
:borderColor="label.border_color"
:circle="label.border_color ? true : false"
:imgSrc="label.icon"
v-for="(label, idx) in item.store_label" :key="idx"></BaseTag>
</view>
</view>
<view class="flex w-full h-68 rd-8rpx btn-bg relative" :class="active == 2 ? 'opacity' : ''">
<view class="flex-y-center pl-20 fs-22 btn-left ">
<baseMoney
:money="item.price"
symbolSize="26"
integerSize="40"
decimalSize="26"
weight
preFix="预售:"
preFixSize="22"
textColor="#e93323"
color="#e93323"></baseMoney>
</view>
<image src="../static/yushou1.png" class="btn-right" v-if="active == 0"></image>
<image src="../static/yushou2.png" class="btn-right" v-else-if="active == 1"></image>
<image src="../static/yushou3.png" class="btn-right" v-else="active == 2"></image>
</view>
</view>
</view>
</view>
<view class='px-20' v-else>
<emptyPage title="暂无预售商品,去看看其他商品吧~" src="/statics/images/noActivity.gif"></emptyPage>
</view>
</view>
</view>
</view>
</template>
<script>
let sysHeight = uni.getWindowInfo().statusBarHeight;
import { getAdvancellList } from '@/api/activity';
import {HTTP_REQUEST_URL} from '@/config/app';
import emptyPage from '@/components/emptyPage.vue';
import NavBar from "@/components/NavBar.vue"
export default {
name: "presell",
components:{ emptyPage, NavBar },
data() {
return {
sysHeight:sysHeight,
presellList: [],
timeList: [
{name: '未开始',key: 0},
{name: '正在进行',key: 1},
{name: '已结束',key: 2},
],
active: 1,
page: 1,
limit: 8,
loading: false,
loadend: false,
loadTitle: '加载更多',
picUrl: '', //头部图片
imgHost:HTTP_REQUEST_URL,
pageScrollStatus:false,
}
},
computed:{
headerBg(){
return 'url('+this.imgHost+'/statics/images/product/product_presale_header.png'+')'
},
navBg(){
return 'url('+this.imgHost+'/statics/images/product/presell-bg-' + this.active +'.png'+')'
}
},
onPageScroll(object) {
if (object.scrollTop > 130) {
this.pageScrollStatus = true;
} else if (object.scrollTop < 130) {
this.pageScrollStatus = false;
}
uni.$emit('scroll');
},
onLoad() {
this.getPresellProductList();
},
onShow(){
uni.removeStorageSync('form_type_cart');
},
methods: {
getPresellProductList: function() {
let that = this;
let data = {
page: that.page,
limit: that.limit,
time_type: that.active + 1
};
if (that.loading) return;
if (that.loadend) return;
that.loading = true;
that.loadTitle = '';
getAdvancellList(data).then(res => {
let list = res.data.list;
let loadend = list.length < that.limit;
that.presellList = that.$util.SplitArray(list, that.presellList);
that.$set(that, 'presellList', that.presellList);
that.loadend = loadend;
that.loadTitle = loadend ? '没有更多内容啦~' : '加载更多';
that.page = that.page + 1;
that.loading = false;
}).catch(err => {
that.loading = false;
that.loadTitle = '加载更多';
});
},
settimeList(key) {
let that = this;
that.active = key;
that.loadend = false;
that.page = 1;
that.presellList = [];
that.getPresellProductList();
},
goDetails(item) {
uni.navigateTo({
url: `/pages/activity/goods_details/index?id=${item.id}&type=6`
})
},
goBack(){
uni.navigateBack()
}
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function() {
this.getPresellProductList();
},
//#ifdef MP
onShareAppMessage() {
let that = this;
return {
title: '尖货预售',
path: '/pages/activity/presell/index?spid=' + that.$store.state.app.uid,
imageUrl: HTTP_REQUEST_URL+'/statics/images/product/product_presale_header.png',
// desc: ''
};
},
//分享到朋友圈
onShareTimeline: function() {
let that = this;
return {
title: '尖货预售',
path: '/pages/activity/presell/index?spid=' + + that.$store.state.app.uid,
imageUrl: HTTP_REQUEST_URL+'/statics/images/product/product_presale_header.png',
// desc: ''
};
}
//#endif
}
</script>
<style>
page{
background: linear-gradient(270deg, #6D4ADC 0%, #7033D7 98%);
}
</style>
<style lang="scss">
.bg-top{
background-size: 100% 100%;
background-repeat: no-repeat;
}
.bg-primary-light{
background-color: rgba(109, 74, 220, 0.1);
}
.nav-bg{
background-size: 100% 100%;
background-repeat: no-repeat;
}
.active{
font-size: 32rpx;
font-weight: 500;
line-height: 44rpx;
color: #7033D7;
}
.btn-bg{
background: rgba(233, 51, 35, 0.1);
}
.btn-left{
flex: 1;
border-radius: 8rpx 0 0 8rpx;
}
.btn-right{
width: 180rpx;
height: 68rpx;
}
.shandian{
width: 42rpx;
height: 68rpx;
position: absolute;
transform: scale(1.1);
left: 56%;
top: 1px;
}
.pro-item ~ .pro-item{
margin-top: 32rpx;
}
.border-label {
display: inline-flex;
display: flex;
align-items: center;
flex-wrap: nowrap;
height: 26rpx;
padding: 0 6rpx;
border: 1rpx solid #e93323;
border-radius: 6rpx;
font-size: 18rpx;
color: #e93323;
}
/deep/ .empty-box{
width: 100%;
height: 280px;
}
.opacity{
opacity: 0.5;
}
.brand-tag{
background-color: #e93323 !important;
}
</style>

Binary file not shown.

After

Width:  |  Height:  |  Size: 466 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 438 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 145 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB