no message

This commit is contained in:
hajimi
2026-06-11 12:15:29 +08:00
parent 10ebe39c30
commit 96efa1d905
5859 changed files with 815501 additions and 5 deletions
+24
View File
@@ -0,0 +1,24 @@
<template>
<page-meta :page-style="$theme.pageStyle">
<!-- #ifndef H5 -->
<navigation-bar
:front-color="$theme.navColor"
:background-color="$theme.navBgColor"
/>
<!-- #endif -->
</page-meta>
<view class="h-screen flex flex-col justify-center items-center">
<view>
<u-empty text="对不起,您访问的页面不存在" mode="data"></u-empty>
</view>
<view class="w-full px-[100rpx] mt-[40rpx]">
<router-navigate
class="bg-primary rounded-full text-btn-text leading-[80rpx] text-center"
to="/"
nav-type="reLaunch"
>
返回首页
</router-navigate>
</view>
</view>
</template>
@@ -0,0 +1,108 @@
<template>
<page-meta :page-style="$theme.pageStyle">
<!-- #ifndef H5 -->
<navigation-bar :front-color="$theme.navColor" :background-color="$theme.navBgColor" />
<!-- #endif -->
</page-meta>
<z-paging ref="paging" v-model="dataList" @query="queryList" :show-loading-more-when-reload="true">
<view class="points-log">
<view class="p-[20rpx]">
<view
class="bg-primary rounded-[14rpx] flex items-center justify-between pl-[44rpx] py-[54rpx] text-white">
<view>
<view class="text-sm">当前积分</view>
<view class="text-[60rpx]">{{ userPoints }}</view>
</view>
<navigator url="/packages/pages/points_products/points_products" hover-class="none">
<view class="text-primary px-[30rpx] py-[15rpx] bg-white rounded-l-full">
去购买
</view>
</navigator>
</view>
</view>
<u-tabs :list="tabList" :is-scroll="false" v-model="current" activeColor="var(--color-primary)"
@change="changeType"></u-tabs>
<view class="pt-2.5">
<view v-for="item in dataList" :key="item.id"
class="bg-white border-solid border-b border-0 border-light px-[26rpx] py-[24rpx]">
<view class="flex justify-between">
<view class="mr-2">{{ item.type_desc }}</view>
<view class="text-lg" :class="{
'text-primary': item.action == 1
}">
{{ item.change_amount_desc }}
</view>
</view>
<view v-if="item.remark" class="text-sm text-muted mt-1">{{ item.remark }}</view>
<view class="text-sm text-muted mr-1">{{ item.create_time }}</view>
</view>
</view>
</view>
</z-paging>
</template>
<script lang="ts" setup>
import { ref, shallowRef } from 'vue'
import { accountLog } from '@/api/user'
import { onShow } from '@dcloudio/uni-app'
import request from '@/utils/request'
const tabList = ref([
{
name: '全部',
type: ''
},
{
name: '收入',
type: 1
},
{
name: '支出',
type: 2
}
])
const paging = shallowRef()
const dataList = ref<any[]>([])
const current = ref(0)
const changeType = (index: number) => {
current.value = index
paging.value.reload()
}
const queryList = async (pageNo: number, pageSize: number) => {
try {
const action = tabList.value[current.value].type
const data = await accountLog({
action,
type: 'up',
page_no: pageNo,
page_size: pageSize
})
paging.value.complete(data.lists)
} catch (error) {
paging.value.complete(false)
}
}
const userPoints = ref(0)
const fetchUserPoints = async () => {
try {
const res: any = await request.get(
{ url: '/community/userStats' },
{ isTransformResponse: false }
)
if (res?.code === 1 && res.data) {
userPoints.value = res.data.user_points || 0
}
} catch (e) {
// 静默
}
}
onShow(() => {
fetchUserPoints()
})
</script>
<style lang="scss" scoped></style>
@@ -0,0 +1,96 @@
<template>
<view class="points-order">
<view class="card">
<view class="title">确认订单</view>
<view class="product">
<view>
<view class="name">{{ orderInfo.name }}</view>
<view class="desc">到账积分{{ orderInfo.points }}</view>
</view>
<view class="amount">{{ orderInfo.amount }}</view>
</view>
</view>
<view class="submit">
<u-button :loading="loading" type="primary" shape="circle" @click="submitOrder">提交订单</u-button>
</view>
</view>
</template>
<script setup lang="ts">
import { onLoad } from '@dcloudio/uni-app'
import { reactive, ref } from 'vue'
import { pointsPreOrder, pointsCreateOrder } from '@/api/points'
const productId = ref(0)
const loading = ref(false)
const orderInfo = reactive({
product_id: 0,
name: '',
points: 0,
amount: '0.00'
})
const getPreOrder = async () => {
const data = await pointsPreOrder({ product_id: productId.value })
Object.assign(orderInfo, data)
}
const submitOrder = async () => {
loading.value = true
try {
const data = await pointsCreateOrder({ product_id: productId.value })
uni.redirectTo({
url: `/packages/pages/points_order_detail/points_order_detail?order_id=${data.order_id}`
})
} finally {
loading.value = false
}
}
onLoad((options: any) => {
productId.value = Number(options.product_id || 0)
getPreOrder()
})
</script>
<style lang="scss" scoped>
.points-order {
min-height: 100vh;
padding: 24rpx;
background: #f5f5f5;
}
.card {
padding: 32rpx;
background: #fff;
border-radius: 18rpx;
}
.title {
font-size: 34rpx;
font-weight: 700;
color: #222;
}
.product {
margin-top: 30rpx;
display: flex;
align-items: center;
justify-content: space-between;
}
.name {
font-size: 32rpx;
color: #222;
font-weight: 600;
}
.desc {
margin-top: 10rpx;
font-size: 24rpx;
color: #999;
}
.amount {
font-size: 36rpx;
color: #185dff;
font-weight: 700;
}
.submit {
margin-top: 40rpx;
}
</style>
@@ -0,0 +1,124 @@
<template>
<view class="points-detail">
<view class="card">
<view class="status">{{ order.pay_status_text }}</view>
<view class="row">
<text>订单编号</text>
<text>{{ order.sn }}</text>
</view>
<view class="row">
<text>积分套餐</text>
<text>{{ order.product_name }}</text>
</view>
<view class="row">
<text>到账积分</text>
<text>{{ order.points }}</text>
</view>
<view class="row">
<text>支付金额</text>
<text class="amount">{{ order.order_amount }}</text>
</view>
<view v-if="order.pay_time" class="row">
<text>支付时间</text>
<text>{{ order.pay_time }}</text>
</view>
</view>
<view v-if="order.pay_status === 0" class="pay-card">
<view class="pay-title">请选择支付方式</view>
<view class="pay-tips">支持支付宝微信支付使用币支付入口预留中</view>
<u-button type="primary" shape="circle" @click="payState.showPay = true">立即支付</u-button>
</view>
<payment v-model:show="payState.showPay" v-model:show-check="payState.showCheck" :order-id="orderId"
from="points_order" :redirect="payState.redirect" @success="handlePaySuccess" @fail="handlePayFail" />
</view>
</template>
<script setup lang="ts">
import { onLoad, onShow } from '@dcloudio/uni-app'
import { reactive, ref } from 'vue'
import { pointsOrderDetail } from '@/api/points'
const orderId = ref(0)
const order = reactive<any>({})
const payState = reactive({
showPay: false,
showCheck: false,
redirect: '/packages/pages/points_order_detail/points_order_detail'
})
const getDetail = async () => {
const data = await pointsOrderDetail({ order_id: orderId.value })
Object.assign(order, data)
}
const handlePaySuccess = async () => {
payState.showPay = false
payState.showCheck = false
await getDetail()
uni.$u.toast('支付成功')
}
const handlePayFail = () => {
uni.$u.toast('支付失败')
}
onLoad((options: any) => {
orderId.value = Number(options.order_id || 0)
payState.redirect = `/packages/pages/points_order_detail/points_order_detail?order_id=${orderId.value}`
})
onShow(() => {
if (orderId.value) getDetail()
})
</script>
<style lang="scss" scoped>
.points-detail {
min-height: 100vh;
padding: 24rpx;
background: #f5f5f5;
}
.card,
.pay-card {
padding: 32rpx;
background: #fff;
border-radius: 18rpx;
}
.status {
margin-bottom: 24rpx;
font-size: 36rpx;
font-weight: 700;
color: #185dff;
}
.row {
display: flex;
align-items: center;
justify-content: space-between;
padding: 20rpx 0;
font-size: 26rpx;
color: #666;
border-bottom: 1rpx solid #f2f2f2;
}
.row:last-child {
border-bottom: 0;
}
.amount {
color: #185dff;
font-weight: 700;
}
.pay-card {
margin-top: 24rpx;
}
.pay-title {
font-size: 30rpx;
font-weight: 700;
color: #222;
}
.pay-tips {
margin: 12rpx 0 28rpx;
font-size: 24rpx;
color: #999;
}
</style>
@@ -0,0 +1,352 @@
<template>
<view class="pp">
<!-- 顶部积分 -->
<view class="pp-header">
<view class="pp-header__row">
<text class="pp-header__label">当前积分</text>
<text class="pp-header__value">{{ userPoints }}</text>
</view>
</view>
<!-- 步骤1: 选择积分套餐 (两列网格) -->
<view class="pp-section">
<view class="pp-section__title">选择积分套餐</view>
<view class="pp-grid">
<view v-for="item in products" :key="item.id" class="pp-grid__item"
:class="{ 'pp-grid__item--active': selectedId === item.id }" @tap="selectProduct(item)">
<text class="pp-grid__points">{{ item.points }}</text>
<text class="pp-grid__unit">积分</text>
<text class="pp-grid__price">{{ item.amount }}</text>
<view v-if="selectedId === item.id" class="pp-grid__check">
<u-icon name="checkbox-mark" color="#fff" size="20" />
</view>
</view>
</view>
</view>
<!-- 步骤2: 订单确认信息选择商品后显示 -->
<view v-if="selectedProduct" class="pp-section">
<view class="pp-section__title">订单确认</view>
<view class="pp-confirm">
<view class="pp-confirm__row">
<text class="pp-confirm__label">商品名称</text>
<text class="pp-confirm__value">{{ selectedProduct.name }}</text>
</view>
<view class="pp-confirm__row">
<text class="pp-confirm__label">积分数量</text>
<text class="pp-confirm__value">{{ selectedProduct.points }} 积分</text>
</view>
<view class="pp-confirm__row">
<text class="pp-confirm__label">支付金额</text>
<text class="pp-confirm__value pp-confirm__value--price">{{ selectedProduct.amount }}</text>
</view>
<view class="pp-confirm__row">
<text class="pp-confirm__label">充值账号</text>
<text class="pp-confirm__value">{{ userInfo.nickname }} (ID: {{ userInfo.sn }})</text>
</view>
</view>
</view>
<view v-if="!products.length && !loading" class="pp-empty">
<text>暂无积分套餐</text>
</view>
<!-- 底部按钮 -->
<view v-if="selectedId" class="pp-bottom">
<view class="pp-bottom__left">
<text class="pp-bottom__total">{{ selectedProduct?.amount || '0.00' }}</text>
</view>
<view class="pp-bottom__btn" :class="{ 'pp-bottom__btn--disabled': submitting }" @tap="handleSubmit">
<text v-if="!submitting">确认支付</text>
<u-loading v-else color="#fff" size="36" />
</view>
</view>
<!-- 支付组件 -->
<payment v-model:show="payState.show" v-model:showCheck="payState.showCheck" :orderId="payState.orderId"
:from="payState.from" redirect="/packages/pages/points_order_detail/points_order_detail"
@success="onPaySuccess" @close="onPayClose" />
</view>
</template>
<script setup lang="ts">
import { onShow } from '@dcloudio/uni-app'
import { ref, reactive, computed } from 'vue'
import { useUserStore } from '@/stores/user'
import { storeToRefs } from 'pinia'
import { pointsProducts, pointsCreateOrder } from '@/api/points'
import request from '@/utils/request'
const userStore = useUserStore()
const { userInfo } = storeToRefs(userStore)
const products = ref<any[]>([])
const userPoints = ref(0)
const loading = ref(false)
const selectedId = ref(0)
const submitting = ref(false)
const payState = reactive({
show: false,
showCheck: false,
orderId: 0,
from: 'points_order'
})
const selectedProduct = computed(() => {
return products.value.find((p: any) => p.id === selectedId.value) || null
})
const fetchProducts = async () => {
loading.value = true
try {
const data = await pointsProducts()
products.value = data || []
} finally {
loading.value = false
}
}
const fetchUserPoints = async () => {
try {
const res: any = await request.get(
{ url: '/community/userStats' },
{ isTransformResponse: false }
)
if (res?.code === 1 && res.data) {
userPoints.value = res.data.user_points || 0
}
} catch (e) {
// 静默
}
}
const selectProduct = (item: any) => {
if (selectedId.value === item.id) return
selectedId.value = item.id
}
const handleSubmit = async () => {
if (!selectedProduct.value || submitting.value) return
submitting.value = true
try {
const orderRes = await pointsCreateOrder({
product_id: selectedProduct.value.id
})
payState.orderId = orderRes.order_id
payState.from = orderRes.from
payState.show = true
} catch (e: any) {
uni.$u.toast(e?.msg || '下单失败')
} finally {
submitting.value = false
}
}
const onPaySuccess = () => {
uni.$u.toast('支付成功')
fetchUserPoints()
uni.redirectTo({
url: `/packages/pages/points_order_detail/points_order_detail?order_id=${payState.orderId}`
})
}
const onPayClose = () => {
if (payState.orderId) {
uni.navigateTo({
url: `/packages/pages/points_order_detail/points_order_detail?order_id=${payState.orderId}`
})
}
}
onShow(() => {
fetchProducts()
fetchUserPoints()
userStore.getUser()
selectedId.value = 0
payState.show = false
payState.orderId = 0
})
</script>
<style lang="scss" scoped>
.pp {
min-height: 100vh;
background: #f5f5f5;
padding-bottom: calc(120rpx + env(safe-area-inset-bottom));
}
.pp-header {
background: linear-gradient(170deg, #185dff, #4d82ff);
padding: 40rpx 32rpx 48rpx;
&__row {
display: flex;
align-items: baseline;
gap: 12rpx;
}
&__label {
font-size: 28rpx;
color: rgba(255, 255, 255, 0.8);
}
&__value {
font-size: 56rpx;
font-weight: 700;
color: #fff;
}
}
.pp-section {
margin: 24rpx;
background: #fff;
border-radius: 20rpx;
padding: 28rpx;
&__title {
font-size: 30rpx;
font-weight: 600;
color: #222;
margin-bottom: 24rpx;
}
}
/* 两列网格 */
.pp-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 20rpx;
}
.pp-grid__item {
position: relative;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
background: #f7f8fa;
border-radius: 16rpx;
padding: 32rpx 16rpx;
border: 3rpx solid transparent;
transition: all 0.2s;
&--active {
border-color: #185dff;
background: #eef3ff;
}
}
.pp-grid__points {
font-size: 42rpx;
font-weight: 700;
color: #222;
line-height: 1;
}
.pp-grid__unit {
font-size: 24rpx;
color: #999;
margin-top: 8rpx;
}
.pp-grid__price {
font-size: 28rpx;
font-weight: 600;
color: #185dff;
margin-top: 12rpx;
}
.pp-grid__check {
position: absolute;
top: -2rpx;
right: -2rpx;
width: 48rpx;
height: 48rpx;
background: #185dff;
border-radius: 0 16rpx 0 16rpx;
display: flex;
align-items: center;
justify-content: center;
z-index: 1;
}
/* 订单确认 */
.pp-confirm {
background: #f7f8fa;
border-radius: 12rpx;
padding: 20rpx 24rpx;
&__row {
display: flex;
justify-content: space-between;
align-items: center;
padding: 14rpx 0;
}
&__label {
font-size: 26rpx;
color: #999;
}
&__value {
font-size: 26rpx;
color: #333;
&--price {
font-size: 32rpx;
font-weight: 700;
color: #185dff;
}
}
}
.pp-empty {
text-align: center;
padding: 120rpx 0;
color: #999;
font-size: 28rpx;
}
/* 底部栏 */
.pp-bottom {
position: fixed;
left: 0;
right: 0;
bottom: 0;
background: #fff;
display: flex;
align-items: center;
justify-content: space-between;
padding: 16rpx 32rpx;
padding-bottom: calc(16rpx + env(safe-area-inset-bottom));
box-shadow: 0 -2rpx 16rpx rgba(0, 0, 0, 0.06);
&__left {
flex: 1;
}
&__total {
font-size: 40rpx;
font-weight: 700;
color: #185dff;
}
&__btn {
background: #185dff;
color: #fff;
font-size: 30rpx;
font-weight: 500;
padding: 20rpx 64rpx;
border-radius: 44rpx;
display: flex;
align-items: center;
justify-content: center;
min-width: 220rpx;
&--disabled {
opacity: 0.5;
}
}
}
</style>
@@ -0,0 +1,109 @@
<template>
<page-meta :page-style="$theme.pageStyle">
<!-- #ifndef H5 -->
<navigation-bar
:front-color="$theme.navColor"
:background-color="$theme.navBgColor"
/>
<!-- #endif -->
</page-meta>
<view class="recharge p-[20rpx]">
<view class="bg-white rounded-[14rpx] p-[40rpx]">
<view class="text-content">充值金额</view>
<view class="border-0 border-b border-solid border-light">
<input
v-model="money"
class="text-[60rpx] h-[60rpx] py-[24rpx]"
placeholder="0.00"
type="digit"
/>
</view>
<view class="mt-[20rpx] text-xs text-muted">
当前可用余额
<text class="text-primary"> {{ wallet.user_money }}</text>
</view>
</view>
<view class="mt-[40rpx]">
<u-button :loading="isLock" type="primary" shape="circle" @click="rechargeLock">
立即充值
</u-button>
</view>
<view class="flex justify-center m-[60rpx]">
<navigator url="/packages/pages/recharge_record/recharge_record" hover-class="none">
<text class="text-content text-sm">充值记录</text>
</navigator>
</view>
<payment
v-model:show="payState.showPay"
v-model:show-check="payState.showCheck"
:order-id="payState.orderId"
:from="payState.from"
:redirect="payState.redirect"
@success="handlePaySuccess"
@fail="handlePayFail"
/>
</view>
</template>
<script lang="ts" setup>
import { recharge, rechargeConfig } from '@/api/recharge'
import { useLockFn } from '@/hooks/useLockFn'
import { onLoad, onShow } from '@dcloudio/uni-app'
import { reactive, ref } from 'vue'
const money = ref('')
const payState = reactive({
orderId: '',
from: '',
showPay: false,
showCheck: false,
redirect: '/packages/pages/recharge/recharge'
})
const wallet = reactive({
user_money: '',
min_amount: 0
})
const { isLock, lockFn: rechargeLock } = useLockFn(async () => {
const minNum = wallet.min_amount
if (!money.value) return uni.$u.toast('请输入充值金额')
if (minNum == 0 && Number(money.value) == minNum) {
return uni.$u.toast(`充值金额必须大于0`)
}
if (Number(money.value) < minNum) return uni.$u.toast(`最低充值金额${minNum}`)
const data = await recharge({
money: money.value
})
payState.orderId = data.order_id
payState.from = data.from
payState.showPay = true
})
const handlePaySuccess = async () => {
payState.showPay = false
payState.showCheck = false
uni.navigateTo({
url: `/pages/payment_result/payment_result?id=${payState.orderId}&from=${payState.from}`
})
}
const handlePayFail = async () => {
uni.$u.toast('支付失败')
}
const getWallet = async () => {
const data = await rechargeConfig()
Object.assign(wallet, data)
}
onLoad((options: any) => {
// h5支付用于弹起手动确认支付弹窗
if (options?.checkPay) {
payState.orderId = options.id
payState.from = options.from
payState.showCheck = true
}
})
onShow(() => {
getWallet()
})
</script>
@@ -0,0 +1,52 @@
<template>
<page-meta :page-style="$theme.pageStyle">
<!-- #ifndef H5 -->
<navigation-bar
:front-color="$theme.navColor"
:background-color="$theme.navBgColor"
/>
<!-- #endif -->
</page-meta>
<z-paging
ref="paging"
v-model="dataList"
@query="queryList"
:show-loading-more-when-reload="true"
>
<view class="pt-2.5">
<view
v-for="item in dataList"
:key="item.id"
class="bg-white border-solid border-b border-0 border-light px-[26rpx] py-[24rpx]"
>
<view class="flex justify-between">
<view class="mr-2">{{ item.tips }}</view>
<view class="text-lg text-primary"> +{{ item.order_amount }} </view>
</view>
<view class="text-sm text-muted mr-1">{{ item.create_time }}</view>
</view>
</view>
</z-paging>
</template>
<script lang="ts" setup>
import { ref, shallowRef } from 'vue'
import { rechargeRecord } from '@/api/recharge'
const paging = shallowRef()
const dataList = ref<any[]>([])
const queryList = async (pageNo: number, pageSize: number) => {
try {
const data = await rechargeRecord({
page_no: pageNo,
page_size: pageSize
})
paging.value.complete(data.lists)
} catch (error) {
paging.value.complete(false)
}
}
</script>
<style lang="scss" scoped></style>
@@ -0,0 +1,199 @@
<template>
<page-meta page-style="background-color: #005fff">
<!-- #ifndef H5 -->
<navigation-bar front-color="#ffffff" background-color="#005fff" />
<!-- #endif -->
</page-meta>
<z-paging ref="paging" v-model="dataList" @query="queryList" :show-loading-more-when-reload="true">
<view class="user-wallet">
<view class="wallet-header">
<view class="wallet-header__card">
<view class="wallet-header__label">钱包余额</view>
<view class="wallet-header__amount">{{ wallet.user_money || '0.00' }}</view>
<view class="wallet-header__row">
<view class="wallet-header__item">
<text class="wallet-header__item-label">总收益</text>
<text class="wallet-header__item-value">{{ wallet.total_income || '0.00' }}</text>
</view>
<view class="wallet-header__item">
<text class="wallet-header__item-label">佣金比例</text>
<text class="wallet-header__item-value">{{ wallet.commission_rate || '0' }}%</text>
</view>
</view>
</view>
</view>
<view class="wallet-card">
<view class="wallet-tabs">
<view v-for="(tab, idx) in tabList" :key="idx" class="wallet-tabs__item"
:class="{ 'wallet-tabs__item--active': current === idx }" @tap="changeType(idx)">
<text>{{ tab.name }}</text>
</view>
</view>
<view v-for="item in dataList" :key="item.id"
class="border-solid border-b border-0 border-light px-[26rpx] py-[24rpx]">
<view class="flex justify-between items-start">
<view>
<view class="text-[28rpx] font-medium">{{ item.type_desc }}</view>
<view class="text-[24rpx] text-muted mt-[6rpx]">{{ item.create_time }}</view>
</view>
<view class="text-right">
<view class="text-[32rpx] font-bold"
:class="item.action == 1 ? 'text-primary' : 'text-[#333]'">
{{ item.change_amount_desc }}
</view>
<view v-if="item.left_amount !== undefined" class="text-[22rpx] text-muted mt-[4rpx]">
剩余 {{ item.left_amount }}
</view>
</view>
</view>
</view>
</view>
</view>
</z-paging>
</template>
<script lang="ts" setup>
import { ref, shallowRef } from 'vue'
import { accountLog } from '@/api/user'
import { rechargeConfig } from '@/api/recharge'
import { onShow } from '@dcloudio/uni-app'
const tabList = ref([
{
name: '全部',
type: ''
},
{
name: '收入',
type: 1
},
{
name: '支出',
type: 2
}
])
const paging = shallowRef()
const dataList = ref<any[]>([])
const current = ref(0)
const changeType = (index: number) => {
current.value = index
paging.value.reload()
}
const queryList = async (pageNo: number, pageSize: number) => {
try {
const action = tabList.value[current.value].type
const data = await accountLog({
action,
type: 'um',
page_no: pageNo,
page_size: pageSize
})
paging.value.complete(data.lists)
} catch (error) {
paging.value.complete(false)
}
}
const wallet = ref<any>({})
const getWallet = async () => {
wallet.value = await rechargeConfig()
}
onShow(() => {
getWallet()
})
</script>
<style lang="scss" scoped>
.user-wallet {
background: #f5f5f5;
min-height: 100vh;
}
.wallet-header {
background: linear-gradient(to bottom, #005fff 60%, #f5f5f5 60%);
padding: 20rpx 40rpx 0rpx;
&__card {
background: #fff;
border-radius: 20rpx;
padding: 10rpx 32rpx 0;
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.06);
}
&__label {
font-size: 24rpx;
color: #999;
}
&__amount {
font-size: 64rpx;
font-weight: 700;
color: #222;
margin-top: 8rpx;
}
&__row {
display: flex;
gap: 48rpx;
margin-top: 28rpx;
padding: 28rpx 0;
border-top: 1rpx solid #f0f0f0;
}
&__item {
display: flex;
flex-direction: column;
}
&__item-label {
font-size: 22rpx;
color: #999;
}
&__item-value {
font-size: 32rpx;
font-weight: 600;
color: #222;
margin-top: 4rpx;
}
}
.wallet-card {
margin: 20rpx 40rpx 0;
background: #fff;
border-radius: 20rpx;
overflow: hidden;
}
.wallet-tabs {
display: flex;
border-bottom: 1rpx solid #f0f0f0;
&__item {
flex: 1;
text-align: center;
padding: 24rpx 0;
font-size: 28rpx;
color: #999;
position: relative;
transition: all 0.2s;
&--active {
color: #0053d8;
font-weight: 600;
&::after {
content: '';
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 4rpx;
background: #0053d8;
}
}
}
}
</style>
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB