Browse Source

feat(登录状态): 添加未登录状态下的UI显示及逻辑处理

在多个页面中添加了未登录状态下的UI显示,包括登录提示和登录按钮。同时,优化了登录状态下的数据加载逻辑,确保只有在用户登录后才会请求相关数据。提升了用户体验和代码的可维护性。
pull/4/head
前端-胡立永 3 weeks ago
parent
commit
dd67108434
4 changed files with 406 additions and 316 deletions
  1. +46
    -5
      pages/index/center.vue
  2. +50
    -7
      pages/index/order.vue
  3. +129
    -131
      pages_order/order/orderDetail.vue
  4. +181
    -173
      pages_order/order/verifyOrder.vue

+ 46
- 5
pages/index/center.vue View File

@ -2,7 +2,14 @@
<view class="page"> <view class="page">
<view class="flex flex-column header"> <view class="flex flex-column header">
<view class="flex flex-column user">
<!-- 未登录显示 -->
<view v-if="!isLogin" class="flex flex-column no-login">
<view class="no-login-text">登录后查看个人信息</view>
<button class="no-login-btn" @click="$utils.toLogin">立即登录</button>
</view>
<!-- 登录后显示用户信息 -->
<view v-else class="flex flex-column user">
<image class="user-avatar" :src="userInfo.headImage" mode="aspectFill"></image> <image class="user-avatar" :src="userInfo.headImage" mode="aspectFill"></image>
<view class="user-name">{{ userInfo.nickName }}</view> <view class="user-name">{{ userInfo.nickName }}</view>
</view> </view>
@ -63,7 +70,7 @@
</view> </view>
</view> </view>
<!-- todo: check -> @click="$utils.navigateTo('/pages_order/mine/withdraw') -->
<!-- 账户信息 - 登录后显示 -->
<view class="card flex account"> <view class="card flex account">
<view class="flex flex-column"> <view class="flex flex-column">
<view class="account-value">{{ riceInfo.balance || 0 }}<text class="account-unit"></text></view> <view class="account-value">{{ riceInfo.balance || 0 }}<text class="account-unit"></text></view>
@ -171,14 +178,19 @@
isMerchants() { isMerchants() {
return this.userInfo.isMerchants === '1' return this.userInfo.isMerchants === '1'
}, },
isLogin() {
return this.userInfo && this.userInfo.id
}
}, },
data() { data() {
return { return {
} }
}, },
onShow() { onShow() {
this.$store.commit('getUserInfo')
this.$store.commit('getRiceInfo')
if(this.isLogin){
this.$store.commit('getUserInfo')
this.$store.commit('getRiceInfo')
}
}, },
methods: { methods: {
clickNo() { clickNo() {
@ -209,7 +221,9 @@
// //
console.log('扫码结果:', res.result); console.log('扫码结果:', res.result);
this.$fetch('overOrder', res.result).then(() => {
this.$fetch('overOrder', {
orderId : res.result
}).then(() => {
uni.showToast({ uni.showToast({
title: '核销成功', title: '核销成功',
icon: 'none' icon: 'none'
@ -258,6 +272,33 @@
text-align: center; text-align: center;
} }
} }
.no-login {
margin-top: 123rpx;
align-items: center;
&-img {
width: 115rpx;
height: auto;
margin-bottom: 20rpx;
}
&-text {
color: #FFFFFF;
font-size: 28rpx;
margin-bottom: 40rpx;
}
&-btn {
padding: 16rpx 60rpx;
background-color: #FFFFFF;
color: #84A73F;
font-size: 28rpx;
font-weight: bold;
border-radius: 40rpx;
box-shadow: 0 4rpx 8rpx rgba(0, 0, 0, 0.1);
}
}
.member { .member {
width: calc(100vw - 13rpx*2); width: calc(100vw - 13rpx*2);


+ 50
- 7
pages/index/order.vue View File

@ -30,8 +30,15 @@
:current="current" :current="current"
@click="clickTabs"></uv-tabs> @click="clickTabs"></uv-tabs>
</view> </view>
<!-- 未登录显示 -->
<view v-if="!isLogin" class="no-login">
<image class="no-login-img" src="@/static/image/center/icon-member-center.png" mode="widthFix"></image>
<view class="no-login-text">登录后查看您的订单</view>
<button class="no-login-btn" @click="$utils.toLogin">立即登录</button>
</view>
<view class="list">
<view v-if="isLogin" class="list">
<orderCard class="list-item" v-for="item in list" :data="item" :key="item.id" @done="getData"></orderCard> <orderCard class="list-item" v-for="item in list" :data="item" :key="item.id" @done="getData"></orderCard>
</view> </view>
@ -41,10 +48,6 @@
<script> <script>
import orderCard from '@/components/order/orderCard.vue' import orderCard from '@/components/order/orderCard.vue'
import {
mapGetters
} from 'vuex'
import mixinsList from '@/mixins/list.js' import mixinsList from '@/mixins/list.js'
import mixinsOrder from '@/mixins/order.js' import mixinsOrder from '@/mixins/order.js'
import tabber from '@/components/base/tabbar.vue' import tabber from '@/components/base/tabbar.vue'
@ -55,7 +58,11 @@
orderCard, orderCard,
tabber, tabber,
}, },
computed: {},
computed: {
isLogin() {
return this.userInfo && this.userInfo.id
}
},
data() { data() {
return { return {
tabs: [{ tabs: [{
@ -75,7 +82,13 @@
}, },
], ],
current: 0, current: 0,
mixinsListApi: 'queryOrderList',
mixinsListApi: '',
}
},
onShow() {
if (this.isLogin) {
this.mixinsListApi = 'queryOrderList'
this.getData()
} }
}, },
methods: { methods: {
@ -124,4 +137,34 @@
} }
} }
} }
.no-login {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 100rpx 0;
background-color: #FFFFFF;
&-img {
width: 120rpx;
height: auto;
margin-bottom: 20rpx;
}
&-text {
font-size: 28rpx;
color: #666666;
margin-bottom: 40rpx;
}
&-btn {
padding: 16rpx 60rpx;
background-image: linear-gradient(to right, #84A73F, #D8FF8F);
color: #fff;
font-size: 28rpx;
border-radius: 40rpx;
box-shadow: 0 4rpx 8rpx rgba(0, 0, 0, 0.1);
}
}
</style> </style>

+ 129
- 131
pages_order/order/orderDetail.vue View File

@ -1,139 +1,137 @@
<template> <template>
<view class="page">
<navbar title="订单详情" leftClick @leftClick="$utils.navigateBack" color="#fff" />
<view class="page-content">
<view class="page-label">订单详情</view>
<!-- 商品详情 -->
<productCard :data="orderDetail.massageItem" size="medium" :readonly="true"></productCard>
<view class="info">
<view class="info-header">订单信息</view>
<view class="info-content">
<view class="flex info-row">
<text>实付款</text>
<text class="price"><text class="price-unit">¥</text>{{ orderDetail.amount }}</text>
</view>
<view class="flex info-row">
<text>订单号</text>
<text>{{ orderDetail.id }}</text>
</view>
<view class="flex info-row">
<text>付款时间</text>
<text>{{ orderDetail.payTime }}</text>
</view>
<view class="flex info-row">
<text>核销时间</text>
<text>{{ orderDetail.validTime }}</text>
</view>
</view>
</view>
</view>
</view>
<view class="page">
<navbar title="订单详情" leftClick @leftClick="$utils.navigateBack" color="#fff" />
<view class="page-content">
<view class="page-label">订单详情</view>
<!-- 商品详情 -->
<productCard :data="orderDetail.massageItem" size="medium" :readonly="true"></productCard>
<view class="info">
<view class="info-header">订单信息</view>
<view class="info-content">
<view class="flex info-row">
<text>实付款</text>
<text class="price"><text class="price-unit">¥</text>{{ orderDetail.amount }}</text>
</view>
<view class="flex info-row">
<text>订单号</text>
<text>{{ orderDetail.id }}</text>
</view>
<view class="flex info-row">
<text>付款时间</text>
<text>{{ orderDetail.payTime }}</text>
</view>
<view class="flex info-row">
<text>核销时间</text>
<text>{{ orderDetail.validTime }}</text>
</view>
</view>
</view>
</view>
</view>
</template> </template>
<script> <script>
import productCard from '@/components/product/productCard.vue'
import {
mapState
} from 'vuex'
export default {
components: {
productCard
},
computed: {},
data() {
return {
id: null,
orderDetail: {},
}
},
onLoad(args) {
this.id = args.id
this.fetchOrderDetail()
},
onPullDownRefresh() {
this.fetchOrderDetail()
},
methods: {
async fetchOrderDetail() {
try {
this.orderDetail = await this.$fetch('queryOrderById', { id: this.id })
} catch (err) {
}
uni.stopPullDownRefresh()
},
}
}
import productCard from '@/components/product/productCard.vue'
import {
mapState
} from 'vuex'
export default {
components: {
productCard
},
computed: {},
data() {
return {
id: null,
orderDetail: {},
}
},
onLoad(args) {
this.id = args.id
this.fetchOrderDetail()
},
onPullDownRefresh() {
this.fetchOrderDetail()
},
methods: {
async fetchOrderDetail() {
try {
this.orderDetail = await this.$fetch('queryOrderById', { id: this.id })
} catch (err) {
}
uni.stopPullDownRefresh()
},
}
}
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
.page {
height: 100vh;
background-color: #FFFFFF;
/deep/ .nav-bar__view {
background-image: linear-gradient(#84A73F, #D8FF8F);
}
/deep/ .product-card__view {
padding: 19rpx 7rpx 28rpx 7rpx !important;
}
&-content {
padding: 35rpx 46rpx;
}
&-label {
color: #000000;
font-size: 28rpx;
padding-left: 11rpx;
position: relative;
margin-left: 7rpx;
&:before {
content: ' ';
width: 5rpx;
height: 40rpx;
background-image: linear-gradient(#84A73F, #D8FF8F);
border-radius: 3rpx;
position: absolute;
left: 0;
}
}
}
.info {
padding: 30rpx 7rpx;
border-top: 1px dashed #707070;
color: #999999;
font-size: 22rpx;
&-header {
color: #000000;
font-size: 28rpx;
}
&-row {
justify-content: space-between;
margin-top: 23rpx;
}
.price {
color: #000000;
&-unit {
font-size: 14rpx;
}
}
}
.page {
height: 100vh;
background-color: #FFFFFF;
/deep/ .nav-bar__view {
background-image: linear-gradient(#84A73F, #D8FF8F);
}
/deep/ .product-card__view {
padding: 19rpx 7rpx 28rpx 7rpx !important;
}
&-content {
padding: 35rpx 46rpx;
}
&-label {
color: #000000;
font-size: 28rpx;
padding-left: 11rpx;
position: relative;
margin-left: 7rpx;
&:before {
content: ' ';
width: 5rpx;
height: 40rpx;
background-image: linear-gradient(#84A73F, #D8FF8F);
border-radius: 3rpx;
position: absolute;
left: 0;
}
}
}
.info {
padding: 30rpx 7rpx;
border-top: 1px dashed #707070;
color: #999999;
font-size: 22rpx;
&-header {
color: #000000;
font-size: 28rpx;
}
&-row {
justify-content: space-between;
margin-top: 23rpx;
}
.price {
color: #000000;
&-unit {
font-size: 14rpx;
}
}
}
</style> </style>

+ 181
- 173
pages_order/order/verifyOrder.vue View File

@ -1,56 +1,62 @@
<template> <template>
<view class="page">
<view class="page">
<navbar title="核销详情" leftClick @leftClick="$utils.navigateBack" color="#fff" /> <navbar title="核销详情" leftClick @leftClick="$utils.navigateBack" color="#fff" />
<view class="flex page-header">
<image class="icon" src="@/pages_order/static/verifyOrder/icon-clock.png" mode="widthFix"></image>
<text>待核销</text>
</view>
<view class="page-content">
<!-- 商品详情 -->
<productCard :data="orderDetail.massageItem" size="medium" :readonly="true"></productCard>
<view class="card rights" v-if="orderDetail.rights && orderDetail.rights.length">
<view class="flex rights-item" v-for="item in orderDetail.rights" :key="item">
<image class="rights-icon" src="@/pages_order/static/verifyOrder/icon-checked.png" mode="widthFix"></image>
<text>{{ item }}</text>
</view>
</view>
<view class="card info">
<view class="info-header">核销信息</view>
<view class="flex flex-column info-content">
<image class="info-qr" :src="orderDetail.qrCodeImgUrl" mode="widthFix"></image>
<view class="info-no">{{ `订单号:${orderDetail.id}` }}</view>
<view class="info-desc">{{ `有效时间:${orderDetail.startTime}${orderDetail.endTime}` }}</view>
</view>
</view>
</view>
<view class="flex page-header">
<image class="icon" src="@/pages_order/static/verifyOrder/icon-clock.png" mode="widthFix"></image>
<text>待核销</text>
</view>
<view class="page-content">
<!-- 商品详情 -->
<productCard :data="orderDetail.massageItem" size="medium" :readonly="true"></productCard>
<view class="card rights" v-if="orderDetail.rights && orderDetail.rights.length">
<view class="flex rights-item" v-for="item in orderDetail.rights" :key="item">
<image class="rights-icon" src="@/pages_order/static/verifyOrder/icon-checked.png" mode="widthFix">
</image>
<text>{{ item }}</text>
</view>
</view>
<view class="card info">
<view class="info-header">核销信息</view>
<view class="flex flex-column info-content">
<!-- <image class="info-qr" :src="orderDetail.qrCodeImgUrl" mode="widthFix"></image> -->
<view class="" style="margin: 20rpx;">
<uv-qrcode ref="qrcode" size="300rpx" :value="orderDetail.id"></uv-qrcode>
</view>
<view class="info-no">{{ `订单号:${orderDetail.id}` }}</view>
<view class="info-desc">{{ `有效时间:${orderDetail.startTime}${orderDetail.endTime}` }}</view>
</view>
</view>
</view>
<!-- 下单 --> <!-- 下单 -->
<view class="flex bar"> <view class="flex bar">
<button plain class="btn btn-plain" @click="overOrder">核销</button>
<button plain class="btn btn-plain" @click="onRefund">申请退款</button>
<button plain class="btn" @click="onBuyAgain">再次购买</button>
<button plain class="btn btn-plain" @click="overOrder">核销</button>
<button plain class="btn btn-plain" @click="onRefund">申请退款</button>
<button plain class="btn" @click="onBuyAgain">再次购买</button>
</view> </view>
</view>
</view>
</template> </template>
<script> <script>
import productCard from '@/components/product/productCard.vue' import productCard from '@/components/product/productCard.vue'
export default {
components: {
productCard,
},
export default {
components: {
productCard,
},
data() { data() {
return { return {
orderDetail: {},
}
},
orderDetail: {},
}
},
onLoad(args) { onLoad(args) {
this.id = args.id this.id = args.id
this.fetchOrderDetail() this.fetchOrderDetail()
@ -58,11 +64,13 @@
onPullDownRefresh() { onPullDownRefresh() {
this.fetchOrderDetail() this.fetchOrderDetail()
}, },
methods: {
methods: {
async fetchOrderDetail() { async fetchOrderDetail() {
try { try {
this.orderDetail = await this.$fetch('queryOrderById', { id: this.id })
this.orderDetail = await this.$fetch('queryOrderById', {
id: this.id
})
} catch (err) { } catch (err) {
@ -70,48 +78,48 @@
uni.stopPullDownRefresh() uni.stopPullDownRefresh()
}, },
overOrder(){
uni.showModal({
title: '确认核销订单吗?',
success : e => {
if(e.confirm){
this.$api('overOrder', {
orderId : this.orderDetail.id,
}, res => {
this.$emit('done')
//
uni.navigateBack()
})
}
}
})
},
onRefund() {
// todo
uni.showModal({
title: '确认申请订单退款嘛?',
success : e => {
if(e.confirm){
this.$api('rollbackOrder', {
orderId : this.orderDetail.id,
}, res => {
this.$emit('done')
})
}
}
})
},
onBuyAgain() {
// todo: check
this.$utils.navigateTo(`/pages_order/product/productDetail?id=${this.orderDetail.massageItem.id}`)
},
},
}
overOrder() {
uni.showModal({
title: '确认核销订单吗?',
success: e => {
if (e.confirm) {
this.$api('overOrder', {
orderId: this.orderDetail.id,
}, res => {
this.$emit('done')
//
uni.navigateBack()
})
}
}
})
},
onRefund() {
// todo
uni.showModal({
title: '确认申请订单退款嘛?',
success: e => {
if (e.confirm) {
this.$api('rollbackOrder', {
orderId: this.orderDetail.id,
}, res => {
this.$emit('done')
})
}
}
})
},
onBuyAgain() {
// todo: check
this.$utils.navigateTo(`/pages_order/product/productDetail?id=${this.orderDetail.massageItem.id}`)
},
},
}
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
$bar-height: 132rpx;
$bar-height: 132rpx;
.page { .page {
background-color: #F5F5F5; background-color: #F5F5F5;
@ -120,69 +128,69 @@
background-image: linear-gradient(#84A73F, #D8FF8F); background-image: linear-gradient(#84A73F, #D8FF8F);
} }
&-header {
color: #000000;
font-size: 28rpx;
margin-top: 24rpx;
.icon {
width: 30rpx;
height: auto;
margin-right: 17rpx;
}
}
&-content {
padding: 11rpx 13rpx;
}
}
.rights {
margin-top: 15rpx;
padding: 23rpx 48rpx;
color: #000000;
font-size: 28rpx;
&-item {
margin-right: 70rpx;
display: inline-flex;
}
&-icon {
width: 30rpx;
height: auto;
margin-right: 12rpx;
}
}
.info {
margin-top: 19rpx;
padding: 25rpx 41rpx 51rpx 41rpx;
font-size: 28rpx;
&-header {
color: #000000;
padding: 0 0 16rpx 7rpx;
border-bottom: 1rpx dashed #C7C7C7;
}
&-qr {
width: 279rpx;
height: auto;
margin-top: 57rpx;
}
&-no {
color: #84A73F;
margin-top: 16rpx;
}
&-desc {
color: #999999;
font-size: 22rpx;
margin-top: 65rpx;
}
}
&-header {
color: #000000;
font-size: 28rpx;
margin-top: 24rpx;
.icon {
width: 30rpx;
height: auto;
margin-right: 17rpx;
}
}
&-content {
padding: 11rpx 13rpx;
}
}
.rights {
margin-top: 15rpx;
padding: 23rpx 48rpx;
color: #000000;
font-size: 28rpx;
&-item {
margin-right: 70rpx;
display: inline-flex;
}
&-icon {
width: 30rpx;
height: auto;
margin-right: 12rpx;
}
}
.info {
margin-top: 19rpx;
padding: 25rpx 41rpx 51rpx 41rpx;
font-size: 28rpx;
&-header {
color: #000000;
padding: 0 0 16rpx 7rpx;
border-bottom: 1rpx dashed #C7C7C7;
}
&-qr {
width: 279rpx;
height: auto;
margin-top: 57rpx;
}
&-no {
color: #84A73F;
margin-top: 16rpx;
}
&-desc {
color: #999999;
font-size: 22rpx;
margin-top: 65rpx;
}
}
.bar { .bar {
@ -194,37 +202,37 @@
padding-bottom: env(safe-area-inset-bottom); padding-bottom: env(safe-area-inset-bottom);
background-color: $uni-fg-color; background-color: $uni-fg-color;
justify-content: flex-end;
justify-content: flex-end;
} }
.btn {
display: inline-block;
width: auto;
height: auto;
padding: 24rpx 50rpx;
box-sizing: border-box;
border: none;
border-radius: 44rpx;
margin: 0;
font-size: 28rpx;
line-height: 1;
color: #FFFFFF;
background-image: linear-gradient(to right, #84A73F, #D8FF8F);
& + & {
margin-left: 39rpx;
}
&:last-child {
margin-right: 54rpx;
}
&-plain {
border: 2rpx solid #999999;
color: #999999;
background: none;
}
}
.btn {
display: inline-block;
width: auto;
height: auto;
padding: 24rpx 50rpx;
box-sizing: border-box;
border: none;
border-radius: 44rpx;
margin: 0;
font-size: 28rpx;
line-height: 1;
color: #FFFFFF;
background-image: linear-gradient(to right, #84A73F, #D8FF8F);
&+& {
margin-left: 39rpx;
}
&:last-child {
margin-right: 54rpx;
}
&-plain {
border: 2rpx solid #999999;
color: #999999;
background: none;
}
}
</style> </style>

Loading…
Cancel
Save