alipay-emulator/pages/balance/index.vue

529 lines
10 KiB
Vue

<template>
<view class="container" :style="{ height: data.windowHeight + 'px' }">
<view class="bg-container"></view>
<NavBar class="nav-bar" isRightIcon title="" :bgColor="data.navBar.bgColor" :buttonGroup="buttonGroup"
@button-click="clickTitlePopupButton">
<template v-slot:left>
<view class="nav-bar-left">
<image class="nav-icon" src="/static/image/nav-bar/back-white.png" mode=""></image>
<text class="nav-text">余额</text>
</view>
</template>
<template v-slot:right>
<view class="nav-bar-right mr-1">
<image class="nav-icon" src="/static/image/nav-bar/more-white.png" mode=""></image>
</view>
</template>
</NavBar>
<scroll-view class="scroll-view" :style="{ height: (data.windowHeight - 44 - data.statusBarHeight) + 'px' }"
scroll-y="true">
<view class="h100 w100 flex-between" style="flex-direction: column;">
<view class="main-container w100 flex-1">
<view class="background-container" :style="{ 'padding-top': '36rpx' }">
<view class="balance-box">
<view class="top-box">
<image class="img" src="/static/image/balance/safe-icon-blue.png" mode=""></image>
<text class="text">资金安全有保障</text>
<image class="img" src="/static/image/balance/right-blue.png" mode=""></image>
</view>
<view class="balance-title flex-cneter">
<text>可用余额()</text>
<image class="img" src="/static/image/balance/eye.png" mode=""></image>
</view>
<view class="balance flex-cneter">
<text class="text alipay-font">{{ Number(balance).toFixed(2) }}</text>
</view>
<view class="button-group">
<view class="flex-1 btn-box">
<view class="left btn flex-cneter">
<text class="text">提现</text>
</view>
</view>
<view class="flex-1 btn-box">
<view class="right btn flex-cneter">
<text class="text">充值</text>
</view>
</view>
</view>
</view>
</view>
<view class="menu-box">
<view class="item" v-for="item in menuList">
<image class="menu-icon" :src="`/static/image/balance/menu-icon/${item.imgLabel}.png`"
mode="">
</image>
<text class="icon-name">{{ item.name }}</text>
</view>
</view>
<view class="balance-change-detail-list">
<view class="title-box">
<view class="text font-w500" style="font-weight: 500;">余额变动明细</view>
<view class="title-right">
<text class="text">全部</text>
<image class="right-icon" src="/static/image/common/right-grey.png" mode=""></image>
</view>
</view>
<view class="item">
<BalanceList :list="changeDetailList" />
</view>
</view>
</view>
<view class="footer-box">
<view class="blue-text">我的客服</view>
<view class="footer-text">余额升级服务由支付宝和网商银行提供</view>
</view>
</view>
</scroll-view>
</view>
<!-- 输入框示例 -->
<uni-popup ref="inputDialog" type="dialog">
<uni-popup-dialog before-close mode="input" title="修改余额" @confirm="dialogInputConfirm"
@close="dialogInputCancle">
<uni-easyinput type="digit" v-model="data.balance" focus placeholder="请输入余额"></uni-easyinput>
</uni-popup-dialog>
</uni-popup>
</template>
<script setup>
import NavBar from '@/components/nav-bar/nav-bar'
import BalanceList from '@/components/balance-list/balance-list.vue'
import {
util,
deviceUtil
} from '@/utils/common';
import {
storage
} from '@/utils/storage';
import {
reactive,
ref,
onMounted,
watch,
toRefs
} from 'vue'
import {
onLoad,
onShow
} from '@dcloudio/uni-app'
// 导入状态管理
import {
useStore,
} from '@/store'
// 获取store
const {
store
} = useStore()
const inputDialog = ref(null)
const menuList = [{
imgLabel: "zhuanzhang",
name: "转账"
}, {
imgLabel: "yinhangka",
name: "银行卡"
}, {
imgLabel: "qinqingka",
name: "亲情卡"
}, {
imgLabel: "xiaohebao",
name: "小荷包"
}, {
imgLabel: "zhuanyongjin",
name: "专用金"
}]
const buttonGroup = [{
name: "编辑模式",
click: () => {
console.log("编辑模式")
}
},
{
name: "修改余额",
click: () => {
console.log("修改余额")
data.balance = Number(data.balance).toFixed(2)
inputDialog.value.open()
}
},
{
name: "快捷入口管理",
click: () => {
console.log("快捷入口管理")
}
}, {
name: "账单列表",
click: () => {
util.goPage("/pages/bill/bill-list/bill-list")
}
}
]
const data = reactive({
navBar: {
bgColor: "#00000000"
},
statusBarHeight: 0,
balance: 0,
windowHeight: 0,
changeDetailList: [{
time: "2023-08-15 10:00:00",
type: "充值",
money: "1000.00",
isAdd: true,
name: "充值",
balance: 1000.00,
imgUrl: "https://picsum.photos/200/200?random=1"
}, {
time: "2023-08-15 10:00:00",
type: "充值",
money: "1000.00",
isAdd: false,
name: "充值",
balance: 1000.00,
imgUrl: "https://picsum.photos/200/200?random=1"
}, {
time: "2023-08-15 10:00:00",
type: "充值",
money: "1000.00",
isAdd: true,
name: "充值",
balance: 1000.00,
imgUrl: "https://picsum.photos/200/200?random=1"
}]
})
let {
balance,
changeDetailList
} = toRefs(data)
onLoad(async () => {
// 初始获取状态栏高度和屏幕高度
updateStatusBarHeight()
data.windowHeight = await deviceUtil.getWindowHeight()
// 从缓存读取余额
const cachedBalance = storage.get('balance')
if (cachedBalance !== null) {
data.balance = cachedBalance
}
})
onShow(() => {
util.setAndroidSystemBarColor('#F0F3F8')
})
onMounted(() => {
// 组件挂载后再次获取,确保信息已更新
updateStatusBarHeight()
})
// 更新状态栏高度
const updateStatusBarHeight = () => {
uni.getSystemInfo({
success: (res) => {
data.statusBarHeight = res.statusBarHeight || 0
console.log('直接获取状态栏高度:', data.statusBarHeight)
}
})
}
// 监听store中系统信息的变化
watch(() => store.systemInfo, (newVal) => {
if (newVal && newVal.statusBarHeight !== undefined) {
data.statusBarHeight = newVal.statusBarHeight
console.log('监听状态管理变化,更新状态栏高度:', data.statusBarHeight)
}
}, {
deep: true
})
// 点击标题弹出按钮
const clickTitlePopupButton = (button) => {
button.click()
}
/**
* 输入框确认事件
*/
const dialogInputConfirm = () => {
if (data.balance > 999999999) {
uni.showToast({
title: '余额不能超过999999999',
icon: 'none'
})
data.balance = 999999999.00
}
storage.set('balance', data.balance)
inputDialog.value.close()
}
/**
* 点击关闭输入框弹窗
*/
const dialogInputCancle = () => {
data.balance = storage.get('balance')
inputDialog.value.close()
}
</script>
<style>
/* 直接在页面导入公共样式 */
@import '../../common/main.css';
</style>
<style scoped>
.container {
background-color: #F0F3F8;
overflow: hidden;
}
.scroll-view {
display: flex;
flex-direction: column;
justify-content: space-between;
background-color: transparent;
}
.bg-container {
position: absolute;
/* z-index: -1; */
width: 100%;
height: 600rpx;
background: linear-gradient(181deg, #1E76FE 0%, rgba(30, 118, 254, 0.74) 39%, rgba(240, 243, 248, 0.84) 90%, #F0F3F8 100%);
}
.flex-cneter {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
}
.flex-1 {
flex: 1;
}
.nav-bar {
position: absolute;
width: 100%;
}
.nav-bar-left {
display: flex;
flex-direction: row;
align-items: center;
}
.nav-icon {
width: 24px;
height: 24px;
}
.nav-text {
font-size: 18px;
margin-right: 4px;
color: #FFFFFF;
height: 24px;
line-height: 24px;
}
::v-deep .uni-navbar__header-btns-left {
flex: 1;
}
::v-deep .uni-navbar__header-btns-right {
flex: 1;
}
.background-container {
padding: 12px;
padding-bottom: 0;
padding-top: 62px;
}
.balance-box {
background-color: #FFFFFF;
border-radius: 12px;
padding-bottom: 20px;
}
.top-box {
background-color: #E3EFFF;
border-radius: 12px 12px 0 0;
text-align: center;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
padding: 6px;
}
.top-box>.text {
color: #2977E6;
font-size: 12px;
}
.top-box>.img {
width: 14px;
height: 14px;
}
.balance-title {
margin-top: 20px;
}
.balance-title>.img {
width: 16px;
height: 16px;
margin-left: 4px;
}
.balance-title>.text {
font-size: 14px;
color: #1A1A1A;
}
.balance {
margin-top: 21px;
}
.balance>.text {
color: #1A1A1A;
font-size: 40px;
font-weight: 500;
line-height: 32px;
}
.button-group {
margin: 0 12px;
margin-top: 60px;
display: flex;
flex-direction: row;
align-items: center;
/* box-sizing: border-box; */
}
.btn-box {
display: flex;
align-items: center;
justify-content: center;
}
.btn {
border-radius: 24px;
height: 49px;
width: 150px;
font-size: 18px;
}
.btn>.text {
color: #1A1A1A;
}
.left {
border: 1px solid #E2E2E2;
color: #1A1A1A;
}
.right {
color: #fff;
background-color: #1777FF;
}
.right>.text {
color: #fff;
}
.menu-box {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
margin-top: 8px;
border-radius: 12px;
background-color: #FFFFFF;
padding: 20px;
margin-left: 12px;
margin-right: 12px;
}
.item {
display: flex;
flex-direction: column;
align-items: center;
}
.menu-icon {
width: 48rpx;
height: 48rpx;
}
.icon-name {
font-size: 24rpx;
color: var(--text-color);
margin-top: 8px;
}
.balance-change-detail-list {
border-radius: 12px;
margin-top: 8px;
margin-left: 12px;
margin-right: 12px;
background-color: #FFFFFF;
}
.title-box {
display: flex;
flex-direction: row;
padding: 13px 12px;
justify-content: space-between;
box-shadow: 0 0.3px 0 0 #F0F0EE;
}
.title-box>.text {
font-size: 14px;
color: var(--text-color);
}
.title-right {
display: flex;
align-items: center;
flex-direction: row;
}
.title-right>.text {
font-size: 14px;
color: var(--text-color);
}
.right-icon {
width: 10px;
height: 10px;
margin-left: 5px;
}
.footer-box {
margin-top: 18px;
text-align: center;
margin-bottom: 17px;
}
.blue-text {
color: #507295;
}
.footer-text {
font-size: 13px;
color: var(--footer-text-color);
margin-top: 18px;
}
</style>