402 lines
8.9 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view>
<up-popup :show="sku_noe" :round="10" @close="close" :safe-area-inset-bottom="true" mode="bottom">
<div>
<div class="head">
<div class="imgs" @click="preViewImg(chooseItem.face_img)">
<image :src="chooseItem.face_img" alt="" />
</div>
<div class="tites">
<div class="jiage">
<text class="icon"></text>
<text class="number">{{chooseItem.price}}</text>
</div>
<div class="szie">
剩余<text>{{chooseItem.stock <= 0 ? 0 : chooseItem.stock}}</text>
</div>
</div>
</div>
<div class="stepper">
<div>购买数量</div>
<div>
<up-number-box
v-model="num"
disabledInput
bgColor="#f2f3f5"
:longPress="false"
@change="changeNum($event)">
</up-number-box>
</div>
</div>
<template v-if="!isNoStart">
<div class="foot_two" v-if="type == 0">
<div class="car" :class="chooseItem.stock <= 0 ? 'jin1' : ''" @click="chooseItem.stock > 0 ? hanlecart():''">
加入购物车</div>
<div class="group" :class="chooseItem.stock <= 0 ? 'jin' : ''" @click="chooseItem.stock > 0 ? hanleBuy() : ''">立即购买</div>
<!-- <button v-else class="group" :class="chooseItem.stock <= 0 ? 'jin' : ''" open-type="getPhoneNumber" @getphonenumber="getPhoneNumber($event)">立即购买</button> -->
</div>
<div v-else class="foot_noe">
<div class="group" v-if="type == 1" :class="chooseItem.stock <= 0 ? 'jin':''"
@click="chooseItem.stock > 0 ? hanlecart() : ''">加入购物车</div>
<div class="group" v-else-if="type == 2" :class="chooseItem.stock <= 0 ? 'jin' : ''"
@click="chooseItem.stock > 0 ? hanleBuy() : ''">立即购买</div>
</div>
</template>
<template v-else>
<view class="remind" :class="remind ? 'disabled' : ''" @click="remindUser">
<view v-if="!remind" class="topone">预约提醒</view>
<view v-else class="topone">已提醒</view>
<view class="bot">距开始{{days}}{{hours}}{{mins}}{{seconds}}</view>
</view>
</template>
</div>
</up-popup>
</view>
</template>
<script>
import { ref, reactive, toRefs, watch } from 'vue'
import { post } from '@/api/request.js'
import { showToast, getUserPhone } from '@/components/common.js'
import { Style } from '@/utils/list.js'
export default {
props: {
sku_noe: {
type: Boolean,
default: false,
},
type: {
type: Number,
default: 0,
},
source: {
type: String
},
SKU: {
type: Object,
default: () => {},
}
},
setup(props, { emit }) {
const data = reactive({
chooseItem: {}, // 选中规格
num: 1,
shop_goods_id: '',
remind: false,
isNoStart: false,
days: '00',
hours: '00',
mins: '00',
seconds: '00',
downFn: null,
is_authorized: uni.getStorageSync('is_authorized'),
Color: uni.getStorageSync('theme_color'),
priceColor: Style[uni.getStorageSync('theme_index') * 1].priceColor
})
watch(
() => props.SKU,
(newProps) => {
data.chooseItem = newProps
data.shop_goods_id = newProps.id
}
)
watch(() => props.sku_one, (sku_one) => {
if (sku_one && props.SKU.isNoStart == 1) {
data.isNoStart = true
data.remind = props.SKU.remind
let st = new Date(props.SKU.sold_start_time.replace(/-/g, '/'))
let nt = new Date().getTime()
if (nt - st < 0) {
setTimeIng(st - nt)
} else {
data.isNoStart = false
}
}
})
function setTimeIng(backTime) {
data.downFn = setInterval(() => {
var d = Math.floor(backTime / (1000 * 60 * 60 * 24)); //计算天数
var h = Math.floor(backTime / (1000 * 60 * 60) % 24); //计算小时数
var m = Math.floor(backTime / (1000 * 60) % 60); //计算分钟数
var s = Math.floor(backTime / 1000 % 60); //计算秒数
if (backTime < 0) {
data.days = '00'
data.hours = '00'
data.mins = '00'
data.seconds = '00'
data.isNoStart = false
clearInterval(data.downFn)
} else {
data.days = d > 9 ? d : '0' + d
data.hours = h > 9 ? h : '0' + h
data.mins = m > 9 ? m : '0' + m
data.seconds = s > 9 ? s : '0' + s
}
backTime -= 1000
}, 1000)
}
function remindUser() {
if (!data.remind) {
const tmplId = 'cnyYrkMecdOwoWdXW4DQgVa8xaB9_YdzbLbLeUGWMjE' // 这里填写你的模板ID
uni.requestSubscribeMessage({
tmplIds: [tmplId],
success(res) {
if (res[tmplId] === 'accept') {
post(`/api/v1/goods/remind/${props.SKU.id}`, {type: 0}).then((res) => {
uni.showToast({
title: '开启活动提醒活动前3分钟通知你',
icon: 'none',
})
data.remind = true
emit('remind', true)
})
} else if (res[tmplId] == 'reject') {
uni.showModal({
title: '订阅消息',
content: '您当前拒绝接受消息通知,是否去开启',
confirmText: '开启授权',
confirmColor: '#345391',
cancelText: '仍然拒绝',
cancelColor: '#999999',
success(res) {
if (res.confirm) {
uni.openSetting({
success(res) {
},
fail(err) {
}
})
} else if (res.cancel) {
}
}
})
}
},
fail(res) {
}
})
}
}
//清理数据
function close() {
data.num = 1
emit('close1', false)
}
// 预览图片
const preViewImg = (img) => {
let img_preview_suffix = uni.getStorageSync('img_preview_suffix') || ''
let imurl = img + img_preview_suffix
if(img.indexOf('.gif') >= 0 || img.indexOf('.GIF') >= 0) {
imurl = img
}
uni.previewImage({
urls: [imurl],
current: 0
})
}
const addToCart = () => {
post('/api/v1/carts', {
shop_goods_id: data.shop_goods_id,
shop_goods_sku_id: 0,
num: data.num,
shop_group_goods_id: 0,
}).then((res) => {
showToast('已加入购物车')
emit('getnum', true)
close()
}).catch((error) => {
showToast(error)
})
}
const toPay = () => {
const goods = [{
shop_goods_id: data.shop_goods_id,
shop_goods_sku_id: 0,
num: data.num,
shop_group_goods_id: 0
}]
uni.setStorageSync('shopGoods', goods)
uni.navigateTo({
url: '/pages/pay/index?type=0&source=' + props.source
})
close()
}
const hanlecart = async () => {
addToCart()
}
const hanleBuy = async () => {
toPay()
}
// 商品数量
function changeNum(e) {
data.num = e.value
}
// 授权手机号码
async function getPhoneNumber(e) {
if(e.detail.errMsg == 'getPhoneNumber:ok') {
await getUserPhone(e.detail).then((res) => {
data.is_authorized = 1
})
}
}
return {
...toRefs(data),
changeNum,
close,
preViewImg,
hanlecart,
hanleBuy,
remindUser,
setTimeIng,
getPhoneNumber
}
}
}
</script>
<style lang="scss" scoped>
.jin {
opacity: 0.6;
}
.jin1 {
border: 1px solid #aaa !important;
color: #aaa !important;
}
.foot_noe {
padding: 20rpx;
box-sizing: border-box;
font-size: 28rpx;
.group {
text-align: center;
width: 100%;
height: 80rpx;
line-height: 80rpx;
background: v-bind('Color');
color: #fff;
border-radius: 41rpx;
font-size: inherit;
}
}
.foot_two {
display: flex;
justify-content: space-around;
align-items: center;
padding: 20rpx;
box-sizing: border-box;
font-size: 28rpx;
.group {
width: 50%;
height: 70rpx;
background: v-bind('Color');
color: #fff;
border-radius: 0 70rpx 70rpx 0;
font-size: inherit;
display: flex;
justify-content: center;
align-items: center;
}
.car {
width: 50%;
height: 70rpx;
border: 1px solid v-bind('Color');
color: v-bind('Color');
border-radius: 70rpx 0 0 70rpx;
box-sizing: border-box;
display: flex;
justify-content: center;
align-items: center;
}
}
.remind {
display: flex;
flex-direction: column;
height: 80rpx;
border-radius: 80rpx;
background: #32C55A;
color: #fff;
align-items: center;
justify-content: center;
width: 94%;
margin: 0 0 10rpx 3%;
&.disabled {
opacity: 0.7;
}
.topone {
font-size: 28rpx;
}
.bot {
display: flex;
align-items: center;
color: #fff;
font-size: 22rpx;
}
}
.stepper {
display: flex;
justify-content: space-between;
padding: 35rpx 20rpx;
box-sizing: border-box;
}
.head {
display: flex;
padding: 30rpx;
box-sizing: border-box;
border-bottom: 1px solid #eee;
image {
width: 200rpx;
height: 200rpx;
}
.imgs {
margin-right: 20rpx;
}
.tites {
.szie {
color: #676767;
font-size: 28rpx;
margin-top: 20rpx;
}
.jiage {
color: v-bind('priceColor');
.icon {
font-size: 28rpx;
margin-right: 10rpx;
}
.number {
font-size: 40rpx;
}
}
}
}
</style>