| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304 | <template>  <view>    <view class="vipBox">      <view class="avatar">        <img :src="getUserAvatar(baseInfo?.avatar, baseInfo?.sex)" alt="" class="img-box">        <image src="/static/svg/vip.svg" class="vipIcon"></image>      </view>      <view class="nameBox">        <view class="name font-weight-bold font-size-16">{{ baseInfo?.name || userInfo?.phone }}</view>        <view class="vipInfo font-size-14" v-if="remaining">          {{ pName }}          <view>将于{{ remaining }}后过期</view>        </view>      </view>    </view>    <view>      <swiper class="swiper-box" :current="current">        <swiper-item v-for="(item, index) in memberListLength" :key="index" class="swiper-items">          <view class="swiper-item" v-for="val in item" :key="val.id">            <view              class="card"              :class="{ recommend: val.recommend, vipFlag: val.my, active: val.id === chooseId}"              @tap="handleChoose(val.id)"            >              <text>{{ val.name }}</text>              <view>                <uni-icons color="#f30" type="icon-renminbi1688" size="16" custom-prefix="iconfont"></uni-icons>                <text>{{ val.price }}</text>              </view>            </view>          </view>        </swiper-item>				      </swiper>      <view v-if="typeof chooseId === 'number'" class="itemBox">        套餐权益 ( {{ list.name }} )        <uni-section          v-for="item in list.list"          :key="item.id"          class="item"          :class="{ active: item.active }"          titleColor="#774e20"          subTitleColor="#774e20"          :title="item.text"        >          <template v-slot:right>            <uni-icons color="#774e20" :type="item.active ? 'checkmarkempty' : 'closeempty'" size="20"/>          </template>        </uni-section>      </view>    </view>    <view class="pay">      <view class="pay-box">        <view class="price">          <uni-icons color="#e68735" type="icon-renminbi1688" size="16" custom-prefix="iconfont"></uni-icons>          {{ list.price }}        </view>        <view class="btn">          立刻升级        </view>        </view>    </view>  </view></template><script setup>import { ref, computed, watch } from 'vue'import { getUserAvatar } from '@/utils/avatar'import { userStore } from '@/store/user'import { getMembershipPackageList } from '@/api/vip'const useUserStore = userStore()const baseInfo = computed(() => useUserStore?.baseInfo)const userInfo = computed(() => useUserStore?.userInfo)const memberList = ref([])const recommend = ref(null)const chooseId = ref(null)const memberListLength = computed(() => {  const result = [];    for (let i = 0; i < memberList.value.length; i += 2) {        const pair = memberList.value.slice(i, i + 2)      result.push(pair)  }  return result})const pName = computed(() => {  return memberList.value.find(item => +item.id === +userInfo.value?.vipFlag)?.name})const remaining = computed(() => {  if (!userInfo.value?.vipExpireDate) return null  const diffInMs =  userInfo.value?.vipExpireDate - new Date().getTime()  const day = diffInMs / (1000 * 60 * 60 * 24)  return day < 1 ? '今天' : Math.floor(day) + '天'})const list = computed(() => {  const item = memberList.value.find(item => item.id === chooseId.value)  return item ?? {}})const current = ref(0)const handleChoose = (id) => {  chooseId.value = id}const getMemberList = async () => {  try {    const { data } = await getMembershipPackageList()    if (!data || data.length === 0) {      return    }    // memberList.value = data    let vipFlagIndex = null    const list = data.map((item, index) => {      if (+item.id === +userInfo.value?.vipFlag) {        vipFlagIndex = index // 低于当前套餐的(套餐)不展示      }      if (item.recommend) {        recommend.value = index // 推荐套餐      }      return {        ...item,        price: item.price/100,        my: vipFlagIndex === index,        list: JSON.parse(item.text),        type: 3, // 订单类型 0平台订单|1求职端订单|2招聘端订单|3会员套餐        loading: false      }    })    // 低于当前套餐的(套餐)不展示    memberList.value = vipFlagIndex ? list.slice(vipFlagIndex) : list    if ((!userInfo.value?.vipFlag || userInfo.value?.vipExpireDate - new Date().getTime() > 0 ) && typeof recommend.value === 'number') {      current.value = parseInt(recommend.value / 2)      chooseId.value = memberList.value[recommend.value]?.id    }  } catch (error) {    uni.showToast({ title: '查询数据失败,请重试', icon: 'none' })  }}getMemberList()</script><style lang="scss" scoped>.vipBox {	// color: #a18a0f;  padding: 80rpx 50rpx;  display: flex;  background: linear-gradient(121deg,#fde2c2 29.02%,#c19164 104.03%);  .avatar{    position: relative;    width: 100rpx;    height: 100rpx;    margin: 0;    .img-box {      width: 100%;      height: 100%;      border: 2rpx solid #ccc;      border-radius: 50%;      border: 1px solid gold;    }    .vipIcon {      position: absolute;      width: 50%;      height: 50%;      bottom: 0;      right: 0;      transform: translate(0, 30%);    }  }  .nameBox {    display: flex;    flex-direction: column;    justify-content: space-around;    margin-left: 30rpx;    .name {      color: #724d2b;    }    .vipInfo {      color: #572a00;    }  }}.swiper-box {  height: 200rpx;  .swiper-items {    display: grid;    grid-template-columns: 1fr 1fr;  }  .swiper-item {    display: flex;    flex-direction: column;    justify-content: center;    align-items: center;    height: 200rpx;    padding: 20rpx 10rpx;    box-sizing: border-box;    .card {      color: #774e20;      background-color: rgb(255, 251, 248);      border: 1px solid #f1b17a;      width: 100%;      height: 100%;      border-radius: 10rpx;      padding: 0 20rpx;      box-sizing: border-box;      display: flex;      justify-content: space-between;      align-items: center;      position: relative;      overflow: hidden;      &.recommend {        &::after {          content: '推荐';          position: absolute;          right: 0;          top: 0;          padding: 6rpx 10rpx;          font-size: 28rpx;          background: linear-gradient(121deg,#fde2c2 29.02%,#c19164 104.03%);        }      }      &.vipFlag {        &::before {          content: '我的套餐';          position: absolute;          left: 0;          top: 0;          padding: 6rpx 10rpx;          font-size: 28rpx;          background: linear-gradient(121deg,#fde2c2 29.02%,#c19164 104.03%);        }      }      &.active {        box-shadow: 0 0 18rpx 0 rgb(216 160 82);      }    }  }}.itemBox {  padding: 20rpx 40rpx;  .item {    // padding: 10rpx 0;    margin-top: 20rpx;    // color: rgba(119,78,32,.5);    // &.active {      color:#774e20;    // }  }}.pay {  position: sticky;  bottom: 0;  padding: 0 40rpx 50rpx 40rpx;  box-sizing: border-box;  &-box {    width: 100%;    background: linear-gradient(121deg,#fde2c2 29.02%,#c19164 104.03%);    border-radius: 180rpx 0 180rpx 0;    box-shadow: 3rpx 6rpx 10rpx 0rpx rgb(216 160 82);    display: flex;    justify-content: space-between;    align-items: center;    height: 100rpx;    .price {      padding: 0 40rpx;      font-size: 40rpx;      font-weight: 600;      color: #e68735;    }    .btn {      height: 100%;      display: flex;      align-items: center;      padding: 0 40rpx;      border: 2rpx solid #00897B;      background: #00897B;      color: #FFF;      border-radius: 180rpx 0 180rpx 0;      position: relative;      // &::after {      //   content: '';      //   position: absolute;      //   width: 50rpx;      //   height: 50rpx;      //   background: radial-gradient(top right, transparent 50%, #00897B 50%);      //   left: 0;      //   top: 0;      //   margin-left: -25rpx;      //   border-radius: 180rpx;      // }    }  }}</style>
 |