一、公用js

utils/system.js

const SYSTEM_INFO = uni.getSystemInfoSync(); // 获取系统设备的信息

// 状态栏高度
export const getStatusBarHeight = ()=> SYSTEM_INFO.statusBarHeight || 15;

// 标题栏高度  =  胶囊buttom的高度 + 上下边距
export const getTitleBarHeight = ()=>{
    if(uni.getMenuButtonBoundingClientRect){ // 判断是否有胶囊按钮
        // height=胶囊buttom的高度  top值为胶囊buttom的头部到顶的距离,单位为px
        let {top,height} = uni.getMenuButtonBoundingClientRect();
        // 整个胶囊的高度 = height(胶囊buttom的高度) +  (top - getStatusBarHeight())(胶囊buttom和状态栏的上边距)*2
        return height + (top - getStatusBarHeight())*2        
    }else{
        return 40;
    }
}

// 导航栏高度
export const  getNavBarHeight = ()=> getStatusBarHeight()+getTitleBarHeight();

// 获取抖音 左侧图标距离左边距离
export const getLeftIconLeft = ()=> {
    // #ifdef MP-TOUTIAO
        // 获取抖音小程序信息  tt为头条的意思 leftIcon:左上角logo的位置信息
        let {leftIcon:{left,width}}  = tt.getCustomButtonBoundingClientRect(); 
        // 计算 左上角logo的占的宽度
        return left+ parseInt(width);
    // #endif

    // #ifndef MP-TOUTIAO
        return 0  //不是抖音时返回0
    // #endif    
}

公用头部信息

home-head/home-head.vue

<template>
    <view class="homeHead">
        <!-- 状态栏 -->
        <view class="statusBar" :style="{height:getStatusBarHeight()+'px'}"></view>
        <!-- 标题栏 胶囊高度-->
        <view class="titleBar" :style="{height:getTitleBarHeight()+'px'}">{{getStatusBarHeight()}}--{{getTitleBarHeight()}}今日份鸡汤送达喽~~</view>
        <!-- 内容高度 -->
        <view class="content">
            <view class="time">
                <view class="left">
                    <uni-dateformat :date="Date.now()" format="dd"></uni-dateformat>
                </view>
                <view class="right">
                    <view class="year">
                        <uni-dateformat :date="Date.now()" format="yyyy年MM月"></uni-dateformat>
                    </view>
                    <view class="week">{{getCurrentDayOfWeek()}}</view>
                </view>
            </view>
            <view class="pic">
                <image src="../../static/images/headPic.png" mode="heightFix"></image>
            </view>
        </view>
    </view>
</template>

<script setup>
import {getStatusBarHeight,getTitleBarHeight} from "@/utils/system.js"
import {getCurrentDayOfWeek} from "@/utils/tools.js"
</script>

<style lang="scss">
.homeHead{
    // 背景色
    background:    
    radial-gradient(50% 200px at left top, #D5F8FC, transparent),
    radial-gradient(50% 200px at right top, #D3CBFC, transparent);

    .titleBar{
        display: flex;
        align-items: center; //垂直居中
        padding-left:50rpx;
        // border:1px solid #fff;
    }
    .content{
        display: flex;
        justify-content: space-between; //水平-两端对齐
        align-items: center; //垂直居中
        height: 15vh;
        // border: 1px solid #2f09ef;
        .time{
            display: flex;
            align-items: center; //垂直居中
            padding-left:50rpx;
            .left{
                font-size: 110rpx; //字体大小
                font-weight: bolder; //加粗
            }
            .right{    
                padding-left:15rpx;
                .year{
                    font-size: 30rpx;
                }
                .week{
                    font-size: 40rpx;
                    font-weight: bolder;
                }
            }
        }
        .pic{
            height: 100%;
            padding-right: 80rpx;
            image{
                width: 100%;
                height: 100%;
            }
        }
    }
}
</style>

主页

pages/index/index.vue

<template>
    <view class="homeLayout">
        <view class="head">
            <home-head></home-head>
        </view>
        <view class="body">
            <view class="swiperOut">
                <swiper vertical @change="swiperChange">
                    <swiper-item v-for="(item,index) in listData" :key="index">
                        <navigator url="/pages/detail/detail" class="content">
                            <soup-tab-group></soup-tab-group>

                            <soup-text-content maxline="5"></soup-text-content>


                        </navigator>



                        <interactive-bar></interactive-bar>
                    </swiper-item>


                    <swiper-item class="ad">
                        <view class="message">
                            <view class="title">小主,今日鸡汤已干完!</view>
                            <text class="des">每日5碗鸡汤,如果想要加餐,\n点击下方看广告按钮,可继续推送5碗,\n每日最多加餐5次。</text>
                        </view>
                        <view class="btnGroup">
                            <view class="btn">看广告刷新</view>
                            <view class="text">今日还有5次机会</view>
                        </view>
                    </swiper-item>

                </swiper>
            </view>
            <view class="progress">
                <view class="line" :style="{width:lineWidth+'%'}"></view>
            </view>
        </view>

        <uni-popup ref="usePopup" type="center" @maskClick="closeUsePopup">
            <view class="usePopup">
                <image src="../../static/images/upward.png" mode="heightFix" @click="closeUsePopup"></image>
            </view>
        </uni-popup>
    </view>
</template>

<script setup>
import { computed, ref } from 'vue';
import {onReady} from "@dcloudio/uni-app"
const listData = ref([1,2,3,4,5]);
const currentIndex = ref(0);
const usePopup =ref(null);

onReady(()=>{
    let useState = uni.getStorageSync("useState") || false;
    if(!useState) usePopup.value.open();

})

//轮播切换事件
const swiperChange = (e)=>{    
    currentIndex.value = e.detail.current
}

//进度条的宽度
const lineWidth = computed(()=>currentIndex.value/listData.value.length*100)


//点击操作的遮罩层
const closeUsePopup = ()=>{
    usePopup.value.close();
    uni.setStorageSync("useState",true);
}

</script>

<style lang="scss" scoped>
.homeLayout{
    height: 100vh;
    background: #BDE1FB;
    display: flex;
    flex-direction: column;
    .head{

    }
    .body{
        flex:1;
        background: #fff;
        border-radius: 50rpx 50rpx 0 0;//圆角,上左、右,下右,左
        overflow: hidden;
        .swiperOut{
            height: calc(100% - 8rpx);
            swiper{
                height: 100%;
                &-item{
                    .content{
                        height: calc(100% - 130rpx);                        
                        display: flex;
                        justify-content: center;
                        flex-direction: column;
                        padding:0 30rpx;





                    }

                }

                .ad{
                    background: #F8F8F8;    
                    padding:100rpx 30rpx;
                    display: flex;
                    flex-direction: column;
                    justify-content: space-between;
                    align-items: center;
                    text-align: center;
                    .message{
                        background: #fff;
                        border-radius: 30rpx;
                        padding:40rpx;

                        .title{
                            font-size: 46rpx;
                            padding-bottom:20rpx;
                            border-bottom:1px solid #eee;
                            margin-bottom: 20rpx;
                        }
                        .des{
                            font-size: 32rpx;
                            color:#555;
                            line-height: 1.8em;
                        }
                    }

                    .btnGroup{
                        font-size: 30rpx;
                        .btn{
                            width: 400rpx;
                            height: 100rpx;
                            border-radius: 100rpx;
                            background: linear-gradient(to top,#93c4ff,#b1e1ff);
                            display: flex;
                            justify-content: center;
                            align-items: center;
                            font-size: 38rpx;
                            color:#203e5f;
                            margin-bottom: 10rpx;
                        }
                        .text{
                            padding:20rpx 0;
                        }
                    }
                }

            }
        }
        .progress{
            height: 8rpx;
            width: 100%;
            background: #eee;
            .line{
                height: 100%;
                width: 0%;
                background: linear-gradient(to right,#BCE0FD,#74dbef);
            }
        }
    }
}


.usePopup{    
    padding-top:15vh;
    image{
        height: 150rpx;
        transform: translateY(100rpx);
        opacity: 0;
        animation: useanimate 1.5s infinite;
    }
}

@keyframes useanimate{
    0%{
        transform: translateY(100rpx);
        opacity: 0;
    }
    100%{
        transform: translateY(-100rpx);
        opacity: 1;
    }
}
</style>

视频地址