shop-h5/src/views/sale/index.vue

335 lines
12 KiB
Vue
Executable File
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<div class="relative z-10 w-screen h-screen main pb-4">
<div @click="back" class="absolute z-10 top-30px left-30px rounded-1/2 w-62px h-62px bg-[#4A4A4A] flex justify-center items-center">
<img class="w-32px h-29px" src="@/assets/imgs/bgo.png" alt="" />
</div>
<div class="absolute z-0 bgi-light w-220px h-400px top-40px right-30px"> </div>
<div
v-if="false"
@click="handleShareWechat"
class="absolute z-10 top-30px right-30px rounded-1/2 w-62px h-62px bg-[#4A4A4A] flex justify-center items-center"
>
<img class="w-32px h-29px" src="@/assets/imgs/sale/fenx@2x.png" alt="" />
</div>
<div class="bgi-top w-80% h-230px w-450px absolute top-124px left-30px z-0"> </div>
<div class="box-border w-full mx-auto bg-cover pt-428px pb-46px px-30px main bg-black">
<div
v-for="item in list"
:key="item.id"
class="relative w-690px p-30px box-border mb-30px rounded-30px border-[#453c32] border-solid border-2"
>
<img class="absolute left-[-8px] top-[-6px] w-98px h-98px text-[#FFF0D7]" :src="item.tagImg" alt="" />
<div class="flex flex-col items-center">
<span class="text-38px">{{ item.title }}</span>
<p class="text-26px mt-10px"
>{{ item.receiveDate }}<span class="ml-20px">{{ item.receiveTime }}</span></p
>
</div>
<div class="mt-50px mb-40px text-28px">
活动规则:{{ item.activityRules }}
<p>{{ item.activityDec }}</p>
</div>
<div
class="flex items-center justify-between overflow-hidden rounded-md bg-beijing pr-16px pl-8px h-184px"
:class="(item.nums <= 0 || item.verifState) && 'grayscale'"
>
<img :src="item.giftImage" alt="" class="h-184px mt-[-6px] object-contain" />
<div class="flex items-center justify-between flex-1 pl-2">
<div class="text-36px leading-40px text-[#090909]">
<p class="leading-44px">{{ item.giftName }}</p>
<!-- <p v-if="item.id === 1" class="text-20px leading-36px">{{ item.subRemark }}</p> -->
<p class="text-20px leading-36px">剩余:{{ item.nums }}份</p>
</div>
<div
v-if="item.nums > 0 && !item.verifState"
@click="handleClick(item)"
class="bg-white hover:bg-light-600 overflow-hidden cursor-pointer text-[#090909] text-26px rounded-26px h-52px w-140px leading-46px text-center"
>
{{ !item.state ? '我要报名' : '去核销' }}
</div>
</div>
<div>
<img
v-if="item.nums <= 0 && !item.verifState"
src="@/assets/imgs/sale/lingwan.png"
alt=""
class="w-166px object-contain mr-[-18px]"
/>
<img v-if="item.verifState" src="@/assets/imgs/sale/hexiao.png" alt="" class="w-166px object-contain mr-[-18px]" />
</div>
</div>
</div>
<div v-if="false" class="relative w-690px p-30px box-border mb-30px rounded-30px border-[#453c32] border-solid border-2">
<img class="absolute left-[-8px] top-[-6px] w-98px h-98px text-[#FFF0D7]" src="@/assets/imgs/sale/huod2@2x.png" alt="" />
<div class="flex flex-col items-center">
<span class="text-38px">私飨岁末会聚丨包厢用餐即享350份精致礼遇!</span>
<p class="text-26px mt-10px"
>2023/12/1-2024/1/1
<span v-if="false" class="ml-20px">每日11:00-18:00</span>
</p>
</div>
<div class="mt-50px mb-40px text-28px">
活动规则在SWFC指定餐厅晚市每日1700以后预订包厢并到店消费满1,000元可凭餐厅盖章的消费小票及支付凭证至2F综合咨询台每日2200前领取
“Rever足浴SPA礼盒”一份。礼品共350份每人每天限领一份。
<p>礼物发放以线下发放为准,先到先得领完为止。</p>
</div>
<div class="flex items-center justify-between overflow-hidden rounded-md bg-beijing pr-20px pl-8px h-184px">
<img src="@/assets/imgs/sale/lihe@2x.png" alt="" class="object-contain h-184px" />
<div class="text-36px leading-40px text-[#090909]">
<p class="leading-44px">Rever足浴SPA礼盒</p>
<p class="text-20px leading-36px">剩余222份</p>
</div>
<div
@click="handleClick"
class="bg-white hover:bg-light-600 overflow-hidden cursor-pointer text-[#090909] text-26px rounded-26px h-52px w-140px leading-46px text-center"
>
我要报名
</div>
</div>
</div>
<img class="object-contain w-690px mt-80px" src="@/assets/imgs/sale/logohj.png" alt="" />
</div>
</div>
<nut-overlay v-model:visible="show" :overlay-style="overlayStyle" :close-on-click-overlay="false" :z-index="50" lock-scroll>
<div class="flex items-center justify-center w-full h-full">
<div class="relative bg-tbj h-576px w-560px">
<!-- <IconFont class="text-60px w-60px h-60px absolute right-20px top-[-28px] text-light-800" name="close"></IconFont> -->
<div @click.prevent="closeOverlay" class="p-30px absolute right-[-10px] top-[-58px] rounded-1/2">
<img class="object-cover overflow-hidden bg-gray-400 w-58px h-58px rounded-1/2" src="@/assets/imgs/sale/cha@2x.png" alt="" />
<img
v-if="selItem.giftImage && !iptShow"
:src="selItem.giftImage"
alt=""
class="absolute h-214px object-contain bottom-[-440px] left-[-226%]"
:class="selItem.id === 2 && 'left-[-236%]'"
/>
<div
@click.stop
class="absolute right-[56%] top-150px h-190px w-450px pb-10px pt-6px box-border flex flex-col justify-between items-center"
>
<div class="text-36px leading bg-text"> {{ isSuccess ? '核销成功' : '报名成功' }} </div>
<div class="text-60px leading mt-[-4px] bg-text"> {{ selItem.giftName }} </div>
<!-- <div class="text-30px leading bg-text"> {{ isSuccess ? '' : selItem.activityRules }} </div> -->
<div class="text-30px leading bg-text"> 线 </div>
</div>
<div
v-if="iptShow"
@click.stop
class="absolute box-border right-[80px] top-[380px] h-76px w-415px rounded-10px bg-#FADDC0 overflow-hidden"
>
<nut-input
ref="iptRef"
:formatter="formatter"
format-trigger="onChange"
v-model="checkCode"
:border="false"
max-length="20"
placeholder="请输入核销码"
/>
</div>
<div
v-if="!isSuccess"
@click.prevent="handleIptShow"
class="absolute overflow-hidden text-center text-black top-520px right-150px rounded-32px h-65px w-290px leading-55px text-32px bg-btn"
>
{{ iptShow ? '立即核销' : '去核销' }}
</div>
</div>
</div>
</div>
</nut-overlay>
</template>
<script lang="ts" setup>
import { ref, nextTick, watch } from 'vue';
import { useRouter } from 'vue-router';
import { handleWxRedict, getQueryString } from '@/utils/util';
import shareWechat from '@/utils/wxH5Share';
import { getWxMpRequest, queryCoupon, queryVerification, queryCouponLog } from '@/api';
import { showToast } from '@nutui/nutui';
const { back, replace } = useRouter();
const urlCode = ref(getQueryString('code'));
const token = ref<string>(localStorage.getItem('token') || '');
const show = ref(false);
const iptShow = ref(!!sessionStorage.getItem('selId'));
const isSuccess = ref(false);
const iptRef = ref<HTMLInputElement>();
const checkCode = ref(''); // 核销码
const userInfo = ref<any>(localStorage.getItem('user') ? JSON.parse(localStorage.getItem('user') || '') || {} : {}); // 用户信息
const formatter = (value) => value.replace(/[^a-zA-Z0-9]/g, '');
const selId = ref<string>(sessionStorage.getItem('selId') || ''); // 已经领取的优惠券记录id
const overlayStyle = ref({
// backgroundColor: 'rgba(0, 0, 0, .6)',
});
const selItem = ref<any>({});
const list = ref<any>([]);
list.value = [];
const handleClick = async (item: any) => {
// if (!token.value) return (location.href = handleWxRedict());
// state 领取状态true已领取false未领取
// if (item.state) {
selId.value = item.id;
selItem.value = item;
show.value = true;
isSuccess.value = false;
iptShow.value = false;
// iptShow.value = true;
return;
// }
const { result, code } = await queryCouponLog({ id: item.id, openId: userInfo.value.openid });
if (code === 200) {
selId.value = result.id;
sessionStorage.setItem('selId', selId.value);
selItem.value = item;
show.value = true;
isSuccess.value = false;
iptShow.value = false; /////
}
};
const closeOverlay = () => {
show.value = false;
};
const handleIptShow = async (e: Event) => {
e.preventDefault();
e.stopPropagation();
return showToast.text('请联系工作人员进行核销!', {
duration: 3000,
});
if (iptShow.value) {
if (!checkCode.value.trim())
return showToast.text('请输入核销码', {
duration: 1000,
});
try {
const req = { id: selItem.value.id, checkCode: checkCode.value, openId: userInfo.value.openid };
const { code } = await queryVerification(req);
if (code === 200) {
checkCode.value = '';
iptShow.value = false;
isSuccess.value = true;
}
} catch (error) {
showToast.text('核销码不正确!');
}
// show.value = false;
// showToast.success('核销成功', {
// duration: 2000,
// });
return;
}
iptShow.value = true;
nextTick(() => {
iptRef.value?.focus();
});
};
const handleShareWechat = () => {
// if (token.value) {
return shareWechat(
'SWFC寻味环球 共飨美馔',
'',
`${window.location.origin}`,
'https://huanqiuzhongxin.oss-cn-shanghai.aliyuncs.com/shipin/logo.png',
);
// window.location.origin
// } else location.href = handleWxRedict();
};
const getCoupon = async () => {
const { result } = await queryCoupon({ openId: userInfo.value?.openid });
if (result) {
list.value = result.records;
}
};
const init = async () => {
if (urlCode.value) {
const { result }: any = await getWxMpRequest({ code: urlCode.value });
if (result?.accessToken) {
token.value = result.accessToken;
localStorage.setItem('token', token.value);
if (result.user) {
localStorage.setItem('user', result.user);
try {
userInfo.value = JSON.parse(result.user);
} catch (e) {}
replace('/sale');
}
} else {
showToast.fail('获取token失败');
localStorage.removeItem('code');
replace('/sale');
}
} else {
const user = localStorage.getItem('user');
if (user) {
userInfo.value = JSON.parse(user);
}
}
getCoupon();
};
init();
handleShareWechat();
watch(show, (val) => {
if (val) {
checkCode.value = '';
} else {
getCoupon();
setTimeout(() => {
selId.value && (iptShow.value = true);
}, 200);
}
});
</script>
<style lang="scss" scoped>
.bgi-top {
background: url('@/assets/imgs/sale/fulyh.png') no-repeat;
background-size: contain;
}
.bg-beijing {
background: url('@/assets/imgs/sale/qbeij.png') no-repeat;
background-size: contain;
}
.bg-tbj {
background: url('@/assets/imgs/sale/tbj.png') no-repeat;
background-size: contain;
}
.bg-btn {
background: linear-gradient(to left, #eac89a, #ffe3cb);
}
.bg-text {
background: linear-gradient(to left, #e1c691, #fcf4dc, #e0c693);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
.nut-input {
box-sizing: border-box;
padding: 10px 8px;
line-height: 54px;
background-color: transparent;
}
:deep {
.input-text {
font-size: 32px;
line-height: 54px;
}
.nut-toast-text {
font-size: 32px;
}
.nut-input-box input {
color: #000;
padding-left: 14px;
}
}
</style>