我的页面
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
# 我的账户页面
|
||||
|
||||
## 页面描述
|
||||
这是一个100%还原的"我的账户"页面,包含以下功能:
|
||||
|
||||
### 主要功能
|
||||
1. **状态栏显示** - 显示时间、网络状态、电池等信息
|
||||
2. **头部导航** - 包含返回按钮和页面标题
|
||||
3. **账户余额展示** - 显示用户头像和账户余额
|
||||
4. **操作选项** - 提现和账单明细功能
|
||||
|
||||
### 页面结构
|
||||
- `status-bar` - 状态栏区域
|
||||
- `header` - 头部导航区域
|
||||
- `account-summary` - 账户余额展示区域
|
||||
- `action-items` - 操作选项列表
|
||||
- `bottom-indicator` - 底部指示器
|
||||
|
||||
### 样式特点
|
||||
- 使用深红色/棕色渐变背景 (#8B2316 到 #A0522D)
|
||||
- 圆形头像设计
|
||||
- 白色操作卡片
|
||||
- 响应式交互效果
|
||||
|
||||
### 使用方法
|
||||
1. 在 `pages.json` 中已配置路由
|
||||
2. 从其他页面通过 `uni.navigateTo` 跳转
|
||||
3. 支持返回上一页功能
|
||||
|
||||
### 技术实现
|
||||
- 使用 Vue 3 Composition API
|
||||
- SCSS 样式预处理器
|
||||
- uni-app 框架
|
||||
- 响应式设计
|
||||
|
||||
### 注意事项
|
||||
- 头像图片路径:`/static/new_man_big.png`
|
||||
- 页面标题:我的账户
|
||||
- 导航样式:自定义导航栏
|
||||
@@ -0,0 +1,278 @@
|
||||
<template>
|
||||
<view class="bill-details-page">
|
||||
<!-- 顶部导航栏 -->
|
||||
<uni-nav-bar
|
||||
left-icon="left"
|
||||
title="账单明细"
|
||||
@clickLeft="goBack"
|
||||
fixed
|
||||
color="#8B2316"
|
||||
height="140rpx"
|
||||
:border="false"
|
||||
backgroundColor="#eeeeee"
|
||||
></uni-nav-bar>
|
||||
|
||||
<!-- 表格头部 -->
|
||||
<view class="table-header">
|
||||
<view class="header-cell business-type">业务类型</view>
|
||||
<view class="header-cell user">用户</view>
|
||||
<view class="header-cell date-amount">
|
||||
<text class="date-label">日期</text>
|
||||
<text class="amount-label">金额</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 交易记录列表 -->
|
||||
<scroll-view
|
||||
class="transaction-list"
|
||||
scroll-y
|
||||
refresher-enabled
|
||||
@refresherrefresh="onRefresh"
|
||||
:refresher-triggered="refreshing"
|
||||
@scrolltolower="onLoadMore"
|
||||
:lower-threshold="100"
|
||||
>
|
||||
<view class="transaction-item" v-for="(item, index) in orderList" :key="item.id">
|
||||
<view class="cell business-type">{{ item.typeName }}</view>
|
||||
<view class="cell user">{{ item.userName }}</view>
|
||||
<view class="cell date-amount">
|
||||
<text class="date">{{ formatDate(item.createTime) }}</text>
|
||||
<text class="amount" :class="item.accountStr < 0 ? 'negative' : 'positive'">{{ item.accountStr }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 加载更多提示 -->
|
||||
<view v-if="loading" class="loading-more">
|
||||
<text>加载中...</text>
|
||||
</view>
|
||||
|
||||
<!-- 空数据状态 -->
|
||||
<view v-if="!loading && orderList.length === 0" class="empty-state">
|
||||
<text>暂无交易记录</text>
|
||||
</view>
|
||||
|
||||
<!-- 没有更多数据提示 -->
|
||||
<view v-if="isLastPage && orderList.length > 0" class="no-more">
|
||||
<text>没有更多数据了</text>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
import api from '@/api/api.js'
|
||||
|
||||
// 响应式数据
|
||||
const orderList = ref([])
|
||||
const loading = ref(false)
|
||||
const refreshing = ref(false)
|
||||
const page = ref(1)
|
||||
const total = ref(0)
|
||||
const isFirstPage = ref(true)
|
||||
const isLastPage = ref(false)
|
||||
|
||||
// 获取订单列表
|
||||
const getOrderList = async (isRefresh = false) => {
|
||||
if (loading.value) return
|
||||
|
||||
loading.value = true
|
||||
|
||||
try {
|
||||
const res = await api.getOrderList({
|
||||
page: page.value,
|
||||
})
|
||||
|
||||
console.log('订单列表:', res)
|
||||
|
||||
if (res && res.code === 200 && res.data) {
|
||||
const { list, total: totalCount, isFirstPage: firstPage, isLastPage: lastPage } = res.data
|
||||
|
||||
if (isRefresh) {
|
||||
orderList.value = []
|
||||
}
|
||||
|
||||
// 处理订单数据
|
||||
const processedList = list.map(item => ({
|
||||
id: item.trade_no,
|
||||
typeName: item.type_name,
|
||||
userName: item.user_name,
|
||||
createTime: item.create_time,
|
||||
accountStr: item.accountstr,
|
||||
payChannel: item.pay_channel,
|
||||
orderType: item.order_type,
|
||||
status: item.status
|
||||
}))
|
||||
|
||||
orderList.value.push(...processedList)
|
||||
total.value = totalCount
|
||||
isFirstPage.value = firstPage
|
||||
isLastPage.value = lastPage
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取订单列表失败:', error)
|
||||
uni.showToast({
|
||||
title: '获取数据失败',
|
||||
icon: 'none'
|
||||
})
|
||||
} finally {
|
||||
loading.value = false
|
||||
refreshing.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 刷新数据
|
||||
const onRefresh = () => {
|
||||
refreshing.value = true
|
||||
page.value = 1
|
||||
isLastPage.value = false
|
||||
getOrderList(true)
|
||||
}
|
||||
|
||||
// 加载更多
|
||||
const onLoadMore = () => {
|
||||
if (loading.value || isLastPage.value) return
|
||||
|
||||
page.value++
|
||||
getOrderList()
|
||||
}
|
||||
|
||||
// 格式化日期
|
||||
const formatDate = (dateStr) => {
|
||||
if (!dateStr) return ''
|
||||
const date = new Date(dateStr)
|
||||
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 goBack = () => {
|
||||
uni.navigateBack()
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getOrderList()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.bill-details-page {
|
||||
background-color: #f5f5f5;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 加载状态和空数据状态样式
|
||||
.loading-more, .no-more, .empty-state {
|
||||
text-align: center;
|
||||
padding: 30rpx;
|
||||
color: #999999;
|
||||
font-size: 26rpx;
|
||||
}
|
||||
|
||||
.empty-state {
|
||||
padding: 100rpx 30rpx;
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 表格头部样式
|
||||
.table-header {
|
||||
background-color: #e0e0e0;
|
||||
display: flex;
|
||||
padding: 20rpx 30rpx;
|
||||
margin-top: 170rpx; /* 为固定导航栏留出空间 */
|
||||
border-bottom: 1rpx solid #ccc;
|
||||
|
||||
.header-cell {
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
font-weight: 500;
|
||||
|
||||
&.business-type {
|
||||
flex: 1;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
&.user {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
&.date-amount {
|
||||
flex: 1;
|
||||
text-align: right;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-end;
|
||||
|
||||
.date-label {
|
||||
font-size: 24rpx;
|
||||
margin-bottom: 4rpx;
|
||||
}
|
||||
|
||||
.amount-label {
|
||||
font-size: 24rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 交易记录列表样式
|
||||
.transaction-list {
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
.transaction-item {
|
||||
background-color: #f8f8f8;
|
||||
display: flex;
|
||||
padding: 20rpx 30rpx;
|
||||
border-bottom: 1rpx solid #e5e5e5;
|
||||
|
||||
.cell {
|
||||
font-size: 26rpx;
|
||||
|
||||
&.business-type {
|
||||
flex: 1;
|
||||
text-align: left;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
&.user {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
color: #ff0000;
|
||||
}
|
||||
|
||||
&.date-amount {
|
||||
flex: 1;
|
||||
text-align: right;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-end;
|
||||
|
||||
.date {
|
||||
font-size: 24rpx;
|
||||
color: #666;
|
||||
margin-bottom: 4rpx;
|
||||
}
|
||||
|
||||
.amount {
|
||||
font-size: 24rpx;
|
||||
|
||||
&.positive {
|
||||
color: #ff0000;
|
||||
}
|
||||
|
||||
&.negative {
|
||||
color: #666;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,284 @@
|
||||
<template>
|
||||
<view class="my-account-page">
|
||||
<!-- 顶部导航栏 -->
|
||||
<uni-nav-bar
|
||||
left-icon="left"
|
||||
title="我的账户"
|
||||
@clickLeft="goBack"
|
||||
fixed
|
||||
color="#8B2316"
|
||||
height="140rpx"
|
||||
:border="false"
|
||||
backgroundColor="#eeeeee"
|
||||
></uni-nav-bar>
|
||||
|
||||
<!-- 账户余额区域 -->
|
||||
<view class="account-summary">
|
||||
<view class="profile-section">
|
||||
<image class="profile-avatar" :src="avatar" mode="aspectFill"></image>
|
||||
</view>
|
||||
<text class="balance-label">账户余额(元)</text>
|
||||
<text class="balance-amount">{{ (accountBalance/100).toFixed(2) }}</text>
|
||||
|
||||
<!-- 账户信息详情 -->
|
||||
<view class="account-details">
|
||||
<view class="detail-item">
|
||||
<text class="detail-label">单次提现限额</text>
|
||||
<text class="detail-value">{{ (withdrawalBalanceMaxOnce/100).toFixed(2) }}元</text>
|
||||
</view>
|
||||
<view class="detail-item">
|
||||
<text class="detail-label">提现手续费</text>
|
||||
<text class="detail-value">{{ (withdrawalBalanceFee/100).toFixed(2) }}元</text>
|
||||
</view>
|
||||
<view class="detail-item">
|
||||
<text class="detail-label">最低提现金额</text>
|
||||
<text class="detail-value">{{ (lessWithdrawalBalance/100).toFixed(2) }}元</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 操作选项 -->
|
||||
<view class="action-items">
|
||||
<view class="action-item" @click="handleWithdrawal">
|
||||
<view class="action-icon withdrawal-icon">
|
||||
<text class="icon-text">💰</text>
|
||||
</view>
|
||||
<view class="action-content">
|
||||
<text class="action-title">提现</text>
|
||||
<text class="action-subtitle">提现金额不得少于{{ (lessWithdrawalBalance/100).toFixed(2) }}元</text>
|
||||
</view>
|
||||
<text class="action-arrow">></text>
|
||||
</view>
|
||||
|
||||
<view class="action-item" @click="handleBillDetails">
|
||||
<view class="action-icon bill-icon">
|
||||
<text class="icon-text">📋</text>
|
||||
</view>
|
||||
<view class="action-content">
|
||||
<text class="action-title">账单明细</text>
|
||||
</view>
|
||||
<text class="action-arrow">></text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 底部指示器 -->
|
||||
<view class="bottom-indicator"></view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
import api from '@/api/api.js'
|
||||
import docUrl from '@/utils/docUrl'
|
||||
// 响应式数据
|
||||
const accountBalance = ref(0)
|
||||
const withdrawalBalanceMaxOnce = ref(0)
|
||||
const withdrawalBalanceFee = ref(0)
|
||||
const lessWithdrawalBalance = ref(0)
|
||||
const avatar = ref('')
|
||||
|
||||
onMounted(() => {
|
||||
getMyAccount()
|
||||
|
||||
let userInfo= uni.getStorageSync('userInfo')
|
||||
avatar.value = docUrl+userInfo.photo
|
||||
})
|
||||
|
||||
// 方法
|
||||
const goBack = () => {
|
||||
uni.navigateBack()
|
||||
}
|
||||
|
||||
const handleWithdrawal = () => {
|
||||
uni.showToast({
|
||||
title: '提现功能开发中',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
|
||||
const handleBillDetails = () => {
|
||||
uni.navigateTo({
|
||||
url: '/pages_app/myAccount/billDetails'
|
||||
})
|
||||
}
|
||||
|
||||
const getMyAccount = async () => {
|
||||
const res = await api.getMyAccount({})
|
||||
console.log(res)
|
||||
if (res && res.code === 200 && res.data) {
|
||||
accountBalance.value = res.data.balance
|
||||
withdrawalBalanceMaxOnce.value = res.data.withdrawalBalanceMaxOnce
|
||||
withdrawalBalanceFee.value = res.data.withdrawalBalanceFee
|
||||
lessWithdrawalBalance.value = res.data.lessWithdrawalBalance
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.my-account-page {
|
||||
background-color: #f5f5f5;
|
||||
min-height: 100vh;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
// 账户余额区域样式
|
||||
.account-summary {
|
||||
background: linear-gradient(135deg, #8B2316, #A0522D);
|
||||
margin: 30rpx;
|
||||
border-radius: 20rpx;
|
||||
padding: 60rpx 40rpx;
|
||||
text-align: center;
|
||||
box-shadow: 0 8rpx 24rpx rgba(139, 35, 22, 0.3);
|
||||
position: relative;
|
||||
|
||||
.profile-section {
|
||||
margin-bottom: 40rpx;
|
||||
|
||||
.profile-avatar {
|
||||
width: 120rpx;
|
||||
height: 120rpx;
|
||||
border-radius: 60rpx;
|
||||
border: 4rpx solid rgba(255, 255, 255, 0.3);
|
||||
object-fit: cover;
|
||||
}
|
||||
}
|
||||
|
||||
.balance-label {
|
||||
display: block;
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
font-size: 28rpx;
|
||||
margin-bottom: 20rpx;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.balance-amount {
|
||||
display: block;
|
||||
color: #ffffff;
|
||||
font-size: 72rpx;
|
||||
font-weight: bold;
|
||||
text-shadow: 0 2rpx 4rpx rgba(0, 0, 0, 0.2);
|
||||
letter-spacing: 2rpx;
|
||||
margin-bottom: 40rpx;
|
||||
}
|
||||
|
||||
// 账户信息详情样式
|
||||
.account-details {
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
border-radius: 16rpx;
|
||||
padding: 30rpx;
|
||||
margin-top: 20rpx;
|
||||
|
||||
.detail-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 20rpx;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.detail-label {
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
font-size: 24rpx;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.detail-value {
|
||||
color: #ffffff;
|
||||
font-size: 26rpx;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 操作选项样式
|
||||
.action-items {
|
||||
background-color: #ffffff;
|
||||
margin: 0 30rpx;
|
||||
border-radius: 20rpx;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.08);
|
||||
|
||||
.action-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 40rpx 30rpx;
|
||||
border-bottom: 1rpx solid #f0f0f0;
|
||||
transition: background-color 0.2s ease;
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
&:active {
|
||||
background-color: #f8f8f8;
|
||||
}
|
||||
|
||||
.action-icon {
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
border-radius: 30rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-right: 30rpx;
|
||||
background-color: #f8f8f8;
|
||||
|
||||
.icon-text {
|
||||
font-size: 32rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.withdrawal-icon {
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
.bill-icon {
|
||||
background-color: #fff8e1;
|
||||
}
|
||||
|
||||
.action-content {
|
||||
flex: 1;
|
||||
|
||||
.action-title {
|
||||
display: block;
|
||||
font-size: 32rpx;
|
||||
color: #333;
|
||||
font-weight: 500;
|
||||
margin-bottom: 8rpx;
|
||||
}
|
||||
|
||||
.action-subtitle {
|
||||
display: block;
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
line-height: 1.4;
|
||||
font-weight: 400;
|
||||
}
|
||||
}
|
||||
|
||||
.action-arrow {
|
||||
font-size: 32rpx;
|
||||
color: #ccc;
|
||||
font-weight: bold;
|
||||
margin-left: 20rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 底部指示器
|
||||
.bottom-indicator {
|
||||
position: fixed;
|
||||
bottom: 20rpx;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
width: 120rpx;
|
||||
height: 6rpx;
|
||||
background-color: #e0e0e0;
|
||||
border-radius: 3rpx;
|
||||
opacity: 0.6;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user