shop_app/pages/user/index.vue

604 lines
15 KiB
Vue
Raw Normal View History

2025-05-08 09:16:37 +08:00
<template>
<view class="whole">
<view class="usertop" :style="{'padding': statusBarHeight + 'px 24rpx 0'}">
<image :src="user_bg + '?x-oss-process=image/format,webp'" :webp="true" class="bgImg" mode="aspectFill"></image>
<view class="title"></view>
<view class="user-top">
<view class="user-top-info" @click="toPage('/pages/user/info')">
<view class="img">
<image class="avatar" :src="avatar" mode="aspectFill"></image>
<view class="icon" mode="widthFix" :style="{backgroundImage: 'url(' + sp2 + ')'}"></view>
</view>
<view class="user-top-info-text">
<text>{{nickname}}</text>
<text class="tag">更新昵称和头像</text>
</view>
</view>
</view>
</view>
<view class="vipBox" v-if="vip_on == 1">
<view class="cont">
<view class="item item1" v-if="!userNum.is_vip">
<text>非会员</text>
<text class="btn" @click="toVip">加入会员</text>
</view>
<view class="item item2" v-else>
<view class="left">
<view class="img" :style="{backgroundImage: 'url(' + sp2 + ')'}"></view>
<view class="right">
<view class="top">
<text class="name">{{vip_name}}会员</text>
2025-06-14 10:01:48 +08:00
<view class="day" @click="toPage('/pages/vip/mine/sheng')" v-if="save_money * 100 > 0">
<text>累计节省{{save_money}}&gt;</text>
2025-05-08 09:16:37 +08:00
</view>
</view>
2025-06-14 10:01:48 +08:00
<view class="time">会员有效期至{{userNum.vip_end_time.slice(0, 10)}}
<view class="fill" v-if="showBirth" @click="toPage('/pages/mine/other/userinfo')">填写我的生日<up-icon name="arrow-right" color="#C18F3F" size="10" /></view>
</view>
2025-05-08 09:16:37 +08:00
</view>
</view>
<text class="btn" @click="toVip">会员详情</text>
</view>
</view>
</view>
<view class="vipBanner" v-if="vip_on === 1 && share_on === 1" @click="toPage('/pages/vip/share/index')">
<image src="https://ct-upimg.yx090.com/ju8hn6/shop/image/2022/07/01/T4PdI0rR7Dkt8YTy67RKMLFby1fitbGITWe58ear.png" mode="widthFix" />
</view>
<view class="contBox">
<!-- 用户订单 -->
<view class="userOrder">
<view class="title flex1" @click="toOrder('')">
<view class="tit">我的订单</view>
<view class="more flex">
<text>查看全部</text>
<up-icon name="arrow-right" color="#999" size="14"></up-icon>
</view>
</view>
<view class="itemBox">
<view class="item" v-for="(item, index) in myOrder" :key="index" @click="toOrder(item.id)">
<view class="img">
<text class="iconfont" :class="'icon-' + item.icon"></text>
</view>
<text>{{item.text}}</text>
<view class="tag" v-if="item.id === 0 && userNum.un_pay_count > 0">{{userNum.un_pay_count}}</view>
<view class="tag" v-if="item.id === 1 && userNum.un_ship_count > 0">{{userNum.un_ship_count}}</view>
<view class="tag" v-if="item.id === 3 && userNum.shiped_count > 0">{{userNum.shiped_count}}</view>
<view class="tag" v-if="item.id === 4 && userNum.un_comment_count > 0">{{userNum.un_comment_count}}</view>
<view class="tag" v-if="item.id === 11 && userNum.after_in_count > 0">{{userNum.after_in_count}}</view>
</view>
</view>
</view>
<view class="rowBox">
<view class="row flex1" @click="toPage('/pages/mine/coupon/index')">
<view class="left">
<text class="iconfont icon-youhuiquan"></text>
<text>优惠券</text>
</view>
<view class="num">
<up-badge :bgColor="tagColor" color="#fff" :value="userNum.couponCount" v-if="userNum.couponCount > 0"></up-badge>
<up-icon name="arrow-right" color="#999" size="14"></up-icon>
</view>
</view>
<view class="row flex1" @click="toPage('/pages/mine/scoreShop/index')" v-if="score_on === 1">
<view class="left">
<text class="iconfont icon-score"></text>
<text>积分中心</text>
</view>
<view class="num">
<up-icon name="arrow-right" color="#999" size="14"></up-icon>
</view>
</view>
<view class="row flex1" @click="toPage('/pages/mine/collection/index')">
<view class="left">
<text class="iconfont icon-shoucang"></text>
<text>收藏与浏览</text>
</view>
<view class="num">
<up-icon name="arrow-right" color="#999" size="14"></up-icon>
</view>
</view>
<view class="row flex1" @click="toPage('/pages/address/list/index')">
<view class="left">
<text class="iconfont icon-dizhi"></text>
<text>收货地址</text>
</view>
<view class="num">
<text v-if="userNum.address_count > 0">{{userNum.address_count}}</text>
<up-icon name="arrow-right" color="#999" size="14"></up-icon>
</view>
</view>
<view class="row flex1" @click="toPage('/pages/user/setpwd')" v-if="showSet && isIOS">
2025-05-08 09:16:37 +08:00
<view class="left">
<up-icon name="lock" color="#444" size="17"></up-icon>
<text>设置密码</text>
</view>
<view class="num">
<up-icon name="arrow-right" color="#999" size="14"></up-icon>
</view>
</view>
<view class="row flex1" @click="toPage('/pages/mine/realName/list')" v-if="show_identity === 1">
<view class="left">
<text class="iconfont icon-realname"></text>
<text>实名认证</text>
</view>
<view class="num">
<up-icon name="arrow-right" color="#999" size="14"></up-icon>
</view>
</view>
<view class="row flex1" @click="toPage('/pages/mine/aboutUs/index')">
<view class="left">
<text class="iconfont icon-about"></text>
<text>关于我们</text>
</view>
<view class="num">
<up-icon name="arrow-right" color="#999" size="14"></up-icon>
</view>
</view>
</view>
</view>
<cf-cloud></cf-cloud>
<tabbar :chooseIndex="4" :num="cartNum" :msgNum="msgNum" />
</view>
</template>
<script>
import { ref, reactive, toRefs } from 'vue'
import tabbar from '@/components/tabbar/index.vue'
import { sp2 } from '@/components/img.js'
import { get } from '@/api/request.js'
import { showToast, getShopInfo, getOldDay, getWeekStartDate, getMonthStartDate, dateTimeStr } from '@/components/common.js'
import { Style } from '@/utils/list.js'
import cfCloud from '@/components/cfCloud/index.vue'
export default {
components: { tabbar, cfCloud },
setup() {
const data = reactive({
2025-06-14 10:01:48 +08:00
showBirth: false,
2025-05-08 09:16:37 +08:00
Color: '',
priceColor: '',
tagColor: '',
cartNum: 0,
msgNum: 0,
user_bg: uni.getStorageSync('user_bg'),
sp2: sp2,
myOrder: [
{ id: 0, text: '待付款', icon: 'daifukuan' },
{ id: 1, text: '待发货', icon: 'daifahuo' },
{ id: 3, text: '待收货', icon: 'daishouhuo' },
{ id: 4, text: '待评论', icon: 'daipingjia' },
{ id: 11, text: '售后中', icon: 'shouhou' }
],
userNum: {},
show_identity: uni.getStorageSync('show_identity'),
share_on: 0,
vip_on: 0,
vip_name: '',
days: 0,
progress: 100,
count: {},
showFill: false,
score_on: 0,
statusBarHeight: 0,
showSet: false,
2025-06-14 10:01:48 +08:00
isIOS: false,
save_money: 0
2025-05-08 09:16:37 +08:00
})
const user = reactive({
nickname: '',
avatar: ''
})
const toPage = (url) => {
uni.navigateTo({ url })
}
async function getUserNum() {
let res = await get('/api/v1/user/home')
data.userNum = res.data
data.cartNum = Number(res.data.cart_count)
uni.setStorageSync('is_vip', res.data.is_vip)
uni.setStorageSync('vip_end_time', res.data.vip_end_time)
if (res.data.is_vip && res.data.vip_end_time && res.data.vip_start_time) {
let nowTime = Date.parse(new Date())
let etTime = Date.parse(new Date(res.data.vip_end_time.replace(/-/g, '/')))
let usedTime = etTime - nowTime
data.days = Math.floor(usedTime / (24 * 3600 * 1000)) + 1 // 剩余时间
let stTime = Date.parse(
new Date(res.data.vip_start_time.replace(/-/g, '/'))
)
let allTime = etTime - stTime
let days1 = Math.floor(allTime / (24 * 3600 * 1000)) // 总时间
data.progress = (data.days / days1) * 100 // 剩余进度
}
}
const toOrder = (type) => {
uni.navigateTo({ url: '/pages/order/list/index?type=' + type })
}
// 会员充值
const toVip = () => {
if(uni.getStorageSync('vip_detail_on') === 1) {
uni.navigateTo({ url: '/pages/vip/intro/index' })
} else {
uni.navigateTo({ url: '/pages/vip/mine/index' })
}
}
// 店铺详情
const getStoreInfo = async () => {
let res = await getShopInfo()
data.vip_on = res.vip_on
data.share_on = res.share_on
data.vip_name = res.vip_name
data.score_on = Number(res.score_on)
data.user_bg = res.user_background_img
}
function getUserInfo() {
get('/api/v1/user/detail').then((res) => {
data.showSet = res.data.mobile ? true : false
})
}
2025-06-14 10:01:48 +08:00
const getDetail = () => {
if(data.vip_on == 1 && data.userNum.is_vip) {
get('/api/v1/user/detail').then((res) => {
data.save_money = res.data.total_saved_money
if(!res.data.birthday) {
data.showBirth = true
} else {
data.showBirth = false
}
})
}
}
2025-05-08 09:16:37 +08:00
return {
...toRefs(data),
...toRefs(user),
toPage,
toOrder,
getUserNum,
toVip,
getStoreInfo,
2025-06-14 10:01:48 +08:00
getUserInfo,
getDetail
2025-05-08 09:16:37 +08:00
}
},
async onLoad(options) {
// await this.$onLaunched
2025-06-14 10:01:48 +08:00
2025-05-08 09:16:37 +08:00
uni.getSystemInfo({
success: (res) => {
this.statusBarHeight = res.statusBarHeight
}
})
this.getStoreInfo()
this.getUserInfo()
2025-05-08 09:16:37 +08:00
},
onShow() {
this.cartNum = Number(uni.getStorageSync('cartNum')) || 0
this.nickname = uni.getStorageSync('nickname')
this.avatar = uni.getStorageSync('avatar')
this.getUserNum()
if(uni.getStorageSync('is_default_avatar')) {
this.getShowPrivacy()
this.showFill = true
} else {
this.showFill = false
}
this.msgNum = uni.getStorageSync('msgNum') || 0
this.Color = uni.getStorageSync('theme_color')
this.priceColor = Style[uni.getStorageSync('theme_index') * 1].priceColor
this.tagColor = Style[uni.getStorageSync('theme_index') * 1].tagColor
2025-06-14 10:01:48 +08:00
setTimeout(() => {
this.getDetail()
}, 500)
2025-05-08 09:16:37 +08:00
}
}
</script>
<style lang="scss">
.flex{
display: flex;
align-items: center;
justify-content: center;
}
.flex1{
display: flex;
align-items: center;
justify-content: space-between;
}
.whole{
width: 100%;
background-color: #f5f5f5;
min-height: 100vh;
padding-bottom: 70px;
overflow: auto;
position: relative;
}
.usertop {
position: relative;
height: 350rpx;
box-sizing: border-box;
.bgImg{
position: absolute;
height: 100%;
width: 100%;
left: 0;
top: 0;
}
.title {
height: 40px;
}
.user-top {
display: flex;
justify-content: space-between;
align-items: center;
position: relative;
z-index: 1;
&-info {
display: flex;
margin: 10rpx 0 30rpx;
color: #fff;
.img {
position: relative;
width: 104rpx;
height: 104rpx;
margin-right: 40rpx;
.avatar {
border-radius: 50%;
background: #999999;
width: 100%;
height: 100%;
border: 4rpx solid #ffffff;
}
.icon {
position: absolute;
top: -20rpx;
right: -26rpx;
background-repeat: no-repeat;
background-size: 339px 306px;
background-position: -286.75px -134.75px;
height: 28px;
width: 32.5px;
}
}
&-text {
text {
display: block;
font-size: 36rpx;
}
.tag {
font-size: 28rpx;
background: rgba($color: #000000, $alpha: 0.07);
border-radius: 22px;
margin-top: 10rpx;
padding: 2rpx 15rpx;
display: inline-block;
}
}
}
}
}
.vipBox{
padding: 0 24rpx;
box-sizing: border-box;
margin-top: -62rpx;
position: relative;
z-index: 1;
.cont{
height: 124rpx;
background: url('http://ct-upimg.yx090.com/22-02-14_19_pwkznnlf.png') no-repeat;
background-size: 100% 100%;
box-sizing: border-box;
.item{
display: flex;
align-items: center;
justify-content: space-between;
height: 100%;
font-size: 28rpx;
.btn {
color: #fff;
2025-06-14 10:01:48 +08:00
width: 140rpx;
2025-05-08 09:16:37 +08:00
height: 56rpx;
text-align: center;
line-height: 56rpx;
2025-06-14 10:01:48 +08:00
background: #333;
2025-05-08 09:16:37 +08:00
border-radius: 28rpx;
2025-06-14 10:01:48 +08:00
font-size: 24rpx;
2025-05-08 09:16:37 +08:00
}
}
.item1 {
padding: 0 24rpx;
color: #553504;
}
.item2 {
width: 100%;
padding: 0 24rpx;
box-sizing: border-box;
image {
width: 40rpx;
height: 40rpx;
background-color: #fff;
border-radius: 50%;
margin-right: 10rpx;
}
.left{
display: flex;
align-items: center;
flex: 1;
.img{
width: 24px;
height: 24px;
background-color: #fff;
background-repeat: no-repeat;
background-size: 452px 408px;
background-position: -161.33px -133px;
border-radius: 50%;
margin-right: 10rpx;
}
}
.right {
flex: 1;
2025-06-14 10:01:48 +08:00
.top{
2025-05-08 09:16:37 +08:00
display: flex;
align-items: center;
2025-06-14 10:01:48 +08:00
.name{
2025-05-08 09:16:37 +08:00
font-size: 30rpx;
font-weight: bold;
color: #553504;
}
2025-06-14 10:01:48 +08:00
.day{
color: #644417;
margin-left: 20rpx;
text{
font-size: 24rpx;
font-weight: 600;
2025-05-08 09:16:37 +08:00
}
}
}
.time {
font-size: 22rpx;
color: #555555;
2025-06-14 10:01:48 +08:00
margin-top: 8rpx;
.fill{
border: 1rpx solid #C49445;
font-size: 22rpx;
line-height: 1;
border-radius: 4px;
padding: 2px 3px;
color: #C18F3F;
display: inline-block;
margin-left: 8rpx;
}
2025-05-08 09:16:37 +08:00
}
}
}
}
}
.vipBanner{
margin-top: 24rpx;
padding: 0 24rpx;
box-sizing: border-box;
image {
width: 100%;
}
}
.contBox{
padding: 0 24rpx;
box-sizing: border-box;
}
.userOrder {
background-color: #fff;
margin-top: 24rpx;
border-radius: 10rpx;
padding: 24rpx;
box-sizing: border-box;
.title{
.tit{
font-size: 30rpx;
font-weight: bold;
}
.more {
font-size: 26rpx;
color: #999;
text {
margin-right: 5rpx;
}
}
}
.itemBox{
display: flex;
text-align: center;
.item{
display: flex;
flex-direction: column;
align-items: center;
padding-top: 40rpx;
font-size: 24rpx;
color: #666;
position: relative;
width: 20%;
.img{
text-align: center;
margin-bottom: 16rpx;
.iconfont{
font-size: 28px;
color: #444;
}
}
.tag{
position: absolute;
top: 20rpx;
left: 60%;
background-color: v-bind('tagColor');
color: #fff;
font-size: 22rpx;
padding: 2px 5px;
line-height: 1;
border-radius: 8px;
}
}
&.sale{
flex-wrap: wrap;
.item{
width: 25%;
}
}
}
}
.rowBox{
background-color: #fff;
margin-top: 24rpx;
border-radius: 10rpx;
padding: 0 24rpx;
box-sizing: border-box;
.row{
height: 88rpx;
.left {
display: flex;
align-items: center;
text {
font-size: 30rpx;
margin-left: 15rpx;
}
.iconfont{
color: #444;
font-size: 17px;
}
}
.num {
font-size: 24rpx;
display: flex;
text {
color: v-bind('tagColor');
margin-right: 15rpx;
}
}
}
.row:not(:last-child) {
border-bottom: 1rpx solid #f2f2f2;
}
}
</style>