249 lines
5.9 KiB
Vue
249 lines
5.9 KiB
Vue
<script setup>
|
||
import { computed, ref } from "vue";
|
||
import { onLoad } from "@dcloudio/uni-app";
|
||
import Container from "@/components/Container.vue";
|
||
import { getDeviceDetailAPI, getHomeData } from "@/apis";
|
||
|
||
const bindResult = ref({
|
||
isFirstBind: false,
|
||
expireDate: "",
|
||
});
|
||
|
||
const bindSuccessHero = computed(() =>
|
||
bindResult.value.isFirstBind
|
||
? "../../static/device-assets/device-bind-success-hero-first.png"
|
||
: "../../static/device-assets/device-bind-success-hero-nonfirst.png"
|
||
);
|
||
const bindRewardExpireDate = computed(() => bindResult.value.expireDate);
|
||
|
||
// 与会员页使用相同的到期时间格式,设备详情接口本身不提供会员有效期。
|
||
const formatVipDate = (value) => {
|
||
if (!value) return "";
|
||
const numericValue = Number(value);
|
||
const timestamp = Number.isNaN(numericValue)
|
||
? new Date(value).getTime()
|
||
: numericValue < 1000000000000
|
||
? numericValue * 1000
|
||
: numericValue;
|
||
const date = new Date(timestamp);
|
||
if (Number.isNaN(date.getTime())) return "";
|
||
const year = date.getFullYear();
|
||
const month = String(date.getMonth() + 1).padStart(2, "0");
|
||
const day = String(date.getDate()).padStart(2, "0");
|
||
return `${year}-${month}-${day}`;
|
||
};
|
||
|
||
const loadBindResult = async (deviceId) => {
|
||
if (!deviceId) return;
|
||
try {
|
||
const data = await getDeviceDetailAPI(deviceId);
|
||
if (data?.detail?.isFirstBind !== true) return;
|
||
bindResult.value.isFirstBind = true;
|
||
|
||
try {
|
||
const homeData = await getHomeData();
|
||
bindResult.value.expireDate = formatVipDate(
|
||
homeData?.user?.normalVipExpiredAt
|
||
);
|
||
} catch (error) {
|
||
console.error("获取赠送会员有效期失败", error);
|
||
}
|
||
} catch (error) {
|
||
console.error("获取设备详情失败", error);
|
||
}
|
||
};
|
||
|
||
const toFirstTryPage = () => {
|
||
uni.navigateTo({ url: "/pages/first-try" });
|
||
};
|
||
|
||
// 成功页由设备页 navigateTo 进入,优先返回上一页;页面栈异常时兜底回到设备页。
|
||
const goBackToDevicePage = () => {
|
||
const pages = getCurrentPages();
|
||
if (pages.length > 1) {
|
||
uni.navigateBack({ delta: 1 });
|
||
return;
|
||
}
|
||
uni.redirectTo({ url: "/pages/device/my-device" });
|
||
};
|
||
|
||
onLoad((options = {}) => {
|
||
bindResult.value = {
|
||
isFirstBind: false,
|
||
expireDate: "",
|
||
};
|
||
void loadBindResult(options.deviceId);
|
||
});
|
||
</script>
|
||
|
||
<template>
|
||
<view class="device-bind-success-page">
|
||
<Container
|
||
:bgType="12"
|
||
bgColor="transparent"
|
||
:onBack="goBackToDevicePage"
|
||
headerClass="bind-success-header"
|
||
:scroll="false"
|
||
:usePageScroll="true"
|
||
>
|
||
<view class="bind-success-page">
|
||
<view
|
||
class="bind-success-scene"
|
||
:class="{ 'bind-success-scene--first': bindResult.isFirstBind }"
|
||
>
|
||
<image
|
||
class="bind-success-confetti"
|
||
src="../../static/device-assets/device-bind-success-confetti.png"
|
||
mode="aspectFit"
|
||
/>
|
||
<image class="bind-success-hero" :src="bindSuccessHero" mode="aspectFit" />
|
||
<image
|
||
class="bind-success-title-image"
|
||
src="../../static/device-assets/device-bind-success-title.png"
|
||
mode="aspectFit"
|
||
/>
|
||
<view v-if="bindResult.isFirstBind" class="bind-reward-card">
|
||
<image
|
||
class="bind-reward-gift"
|
||
src="../../static/device-assets/device-bind-success-reward-gift.png"
|
||
mode="aspectFit"
|
||
/>
|
||
<text class="bind-reward-text">
|
||
新设备首次绑定礼包:
|
||
<text class="bind-reward-highlight">6个月射灵会员</text>
|
||
已自动发放至本账号<text v-if="bindRewardExpireDate">,有效期{{ bindRewardExpireDate }}</text>。
|
||
</text>
|
||
</view>
|
||
<view class="bind-success-tutorial" @click="$clickSound(toFirstTryPage)">
|
||
<text>立即查看新手教程</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</Container>
|
||
</view>
|
||
</template>
|
||
|
||
<style scoped lang="scss">
|
||
.device-bind-success-page {
|
||
position: relative;
|
||
min-height: 100vh;
|
||
background: transparent;
|
||
}
|
||
|
||
.bind-success-header {
|
||
position: relative;
|
||
z-index: 20;
|
||
pointer-events: auto;
|
||
}
|
||
|
||
/* 绑定结果页使用固定画布,背景和前景素材按蓝湖 375 x 812 画布定位。 */
|
||
.bind-success-page {
|
||
position: fixed;
|
||
top: 0;
|
||
left: 0;
|
||
z-index: 1;
|
||
width: 100%;
|
||
height: 100vh;
|
||
overflow: hidden;
|
||
pointer-events: none;
|
||
}
|
||
|
||
.bind-success-scene {
|
||
position: relative;
|
||
width: 100%;
|
||
height: 100%;
|
||
}
|
||
|
||
.bind-success-confetti,
|
||
.bind-success-hero,
|
||
.bind-success-title-image,
|
||
.bind-reward-card,
|
||
.bind-success-tutorial {
|
||
position: absolute;
|
||
}
|
||
|
||
.bind-success-confetti {
|
||
top: 488rpx;
|
||
left: 78rpx;
|
||
width: 588rpx;
|
||
height: 508rpx;
|
||
}
|
||
|
||
.bind-success-hero {
|
||
top: 568rpx;
|
||
left: 244rpx;
|
||
width: 260rpx;
|
||
height: 222rpx;
|
||
}
|
||
|
||
.bind-success-scene--first .bind-success-confetti {
|
||
top: 314rpx;
|
||
}
|
||
|
||
.bind-success-scene--first .bind-success-hero {
|
||
top: 400rpx;
|
||
}
|
||
|
||
.bind-success-title-image {
|
||
top: 828rpx;
|
||
left: 216rpx;
|
||
width: 316rpx;
|
||
height: 70rpx;
|
||
}
|
||
|
||
.bind-success-scene--first .bind-success-title-image {
|
||
top: 660rpx;
|
||
}
|
||
|
||
.bind-reward-card {
|
||
top: 768rpx;
|
||
left: 170rpx;
|
||
width: 508rpx;
|
||
height: 152rpx;
|
||
box-sizing: border-box;
|
||
padding: 16rpx 16rpx 16rpx 90rpx;
|
||
border-radius: 16rpx 64rpx 16rpx 64rpx;
|
||
background: rgba(0, 0, 0, 0.6);
|
||
}
|
||
|
||
.bind-reward-gift {
|
||
position: absolute;
|
||
top: -18rpx;
|
||
left: -100rpx;
|
||
width: 178rpx;
|
||
height: 176rpx;
|
||
}
|
||
|
||
.bind-reward-text {
|
||
display: block;
|
||
width: 380rpx;
|
||
height: 120rpx;
|
||
color: #ffffff;
|
||
font-family: PingFang SC-Regular;
|
||
font-size: 28rpx;
|
||
font-weight: normal;
|
||
line-height: 40rpx;
|
||
}
|
||
|
||
.bind-reward-highlight {
|
||
color: #ffd947;
|
||
}
|
||
|
||
.bind-success-tutorial {
|
||
top: 960rpx;
|
||
left: 195rpx;
|
||
display: flex;
|
||
width: 360rpx;
|
||
height: 70rpx;
|
||
box-sizing: border-box;
|
||
align-items: center;
|
||
justify-content: center;
|
||
border: 2rpx solid #ffd947;
|
||
border-radius: 78rpx;
|
||
color: #ffd947;
|
||
font-size: 26rpx;
|
||
line-height: 26rpx;
|
||
pointer-events: auto;
|
||
}
|
||
</style>
|