文件
shanghaipeiwan/pwuniapp/pages/user/withdraw.vue

1374 行
36 KiB
Vue

此文件含有模棱两可的 Unicode 字符

此文件含有可能会与其他字符混淆的 Unicode 字符。 如果您是想特意这样的,可以安全地忽略该警告。 使用 Escape 按钮显示他们。

<template>
<view class="withdraw-page" :class="['theme-' + currentThemeKey]" :style="navStyle">
<!-- 顶部沉浸式自定义导航栏 -->
<view class="custom-nav-bar">
<view class="nav-content">
<view class="btn-nav-back btn-active" @click="handleBack">
<image class="nav-back-icon" :src="ICONS.chevronLeft" mode="aspectFit" />
</view>
<text class="nav-title">佣金收益提现</text>
<view class="nav-right-action btn-active" @click="openRecordsDrawer">
<text class="records-link-text">提现记录</text>
</view>
</view>
</view>
<!-- 页面滚动内容区 -->
<scroll-view scroll-y class="page-scroll-body">
<!-- 卡片 1: 可提现资产流光看板 -->
<view class="balance-card">
<view class="card-bg-glow"></view>
<view class="balance-inner">
<view class="balance-title-row">
<view class="title-left">
<image class="wallet-icon-svg" :src="ICONS.wallet" mode="aspectFit" />
<text class="balance-title">可提现佣金收益 (元)</text>
</view>
<view class="safe-badge">资金安全托管</view>
</view>
<view class="amount-number-row">
<text class="currency-mark">¥</text>
<text class="amount-integer">{{ commissionParts.integer }}</text>
<text class="amount-decimal">.{{ commissionParts.decimal }}</text>
</view>
<view class="balance-stats-row">
<view class="stat-cell">
<text class="cell-label">已成功提现</text>
<text class="cell-val">¥{{ stats.totalSuccessAmount }}</text>
</view>
<view class="cell-divider"></view>
<view class="stat-cell">
<text class="cell-label">正在审核中</text>
<text class="cell-val gold">¥{{ stats.pendingAmount }}</text>
</view>
<view class="cell-divider"></view>
<view class="stat-cell">
<text class="cell-label">提现手续费</text>
<text class="cell-val green">0.00% (全免)</text>
</view>
</view>
</view>
</view>
<!-- 卡片 2: 到账渠道选择矩阵 -->
<view class="content-card">
<view class="card-section-head">
<text class="section-title">提现到账方式</text>
<text class="section-sub">支持三种主流渠道结算</text>
</view>
<view class="channel-grid">
<!-- 微信零钱 -->
<view
class="channel-item btn-active"
:class="{ active: currentChannel === 'WECHAT' }"
@click="selectChannel('WECHAT')"
>
<view class="channel-badge" v-if="currentChannel === 'WECHAT'">推荐</view>
<view class="channel-icon-wrap wechat">
<image class="channel-svg" :src="ICONS.wechat" mode="aspectFit" />
</view>
<text class="channel-name">微信零钱</text>
<text class="channel-desc">极速到账</text>
<view class="channel-select-mark" v-if="currentChannel === 'WECHAT'">
<image class="check-svg" :src="ICONS.checkCircle" mode="aspectFit" />
</view>
</view>
<!-- 支付宝 -->
<view
class="channel-item btn-active"
:class="{ active: currentChannel === 'ALIPAY' }"
@click="selectChannel('ALIPAY')"
>
<view class="channel-badge blue" v-if="currentChannel === 'ALIPAY'">大额首选</view>
<view class="channel-icon-wrap alipay">
<image class="channel-svg" :src="ICONS.alipay" mode="aspectFit" />
</view>
<text class="channel-name">支付宝</text>
<text class="channel-desc">支持大额</text>
<view class="channel-select-mark" v-if="currentChannel === 'ALIPAY'">
<image class="check-svg" :src="ICONS.checkCircle" mode="aspectFit" />
</view>
</view>
<!-- 银行卡 -->
<view
class="channel-item btn-active"
:class="{ active: currentChannel === 'BANK' }"
@click="selectChannel('BANK')"
>
<view class="channel-badge gold" v-if="currentChannel === 'BANK'">主流银行</view>
<view class="channel-icon-wrap bank">
<image class="channel-svg" :src="ICONS.bankCard" mode="aspectFit" />
</view>
<text class="channel-name">银行储蓄卡</text>
<text class="channel-desc">全国通用</text>
<view class="channel-select-mark" v-if="currentChannel === 'BANK'">
<image class="check-svg" :src="ICONS.checkCircle" mode="aspectFit" />
</view>
</view>
</view>
</view>
<!-- 卡片 3: 提现金额输入区 -->
<view class="content-card">
<view class="card-section-head">
<text class="section-title">提现金额</text>
<text class="section-rule-hint">最低满 ¥{{ minWithdrawAmount }} 起提</text>
</view>
<view class="amount-input-box">
<text class="input-currency-symbol">¥</text>
<input
class="amount-field-input"
type="digit"
v-model="withdrawAmount"
:placeholder="`请输入提现金额 (最低¥${minWithdrawAmount})`"
placeholder-class="amount-input-ph"
maxlength="10"
/>
<button class="btn-all-in btn-active" @click="handleFillAllCommission">全部提现</button>
</view>
<!-- 实时校验提示 -->
<view class="amount-tips-row">
<view v-if="isAmountExceeded" class="tip-msg error">
输入金额已超出当前可提现佣金余额 (¥{{ userCommission }})
</view>
<view v-else-if="isAmountBelowMin" class="tip-msg warning">
提现金额须满 ¥{{ minWithdrawAmount }} 元起提
</view>
<view v-else class="tip-msg normal">
单笔最高可提 ¥20,000 · 预计到账 ¥{{ displayExpectedAmount }} (平台服务费 0 元)
</view>
</view>
</view>
<!-- 卡片 4: 收款账号资料区 -->
<view class="content-card">
<view class="card-section-head">
<text class="section-title">收款账户资料</text>
<text class="section-sub">请确保实名信息完全一致</text>
</view>
<!-- 微信零钱提示卡 -->
<view v-if="currentChannel === 'WECHAT'" class="wechat-bind-notice">
<view class="notice-head">
<image class="notice-icon" :src="ICONS.wechat" mode="aspectFit" />
<text class="notice-title">自动直达当前微信零钱钱包</text>
</view>
<text class="notice-body">
系统将通过微信商户企业付款打款到您当前登录小程序的微信零钱账户中,无需额外录入卡号,提交申请后预计 1 至 24 小时内由系统自动发放。
</text>
</view>
<!-- 支付宝输入区 -->
<view v-if="currentChannel === 'ALIPAY'" class="form-inputs-wrap">
<view class="form-group">
<text class="form-label">支付宝账号</text>
<input
class="form-input"
v-model="accountForm.alipayAccount"
placeholder="请输入支付宝登录账号 / 手机号 / 邮箱"
placeholder-class="form-ph"
maxlength="50"
/>
</view>
<view class="form-group">
<text class="form-label">收款人真实姓名</text>
<input
class="form-input"
v-model="accountForm.realName"
placeholder="需与支付宝实名认证姓名严格一致"
placeholder-class="form-ph"
maxlength="20"
/>
</view>
</view>
<!-- 银行卡输入区 -->
<view v-if="currentChannel === 'BANK'" class="form-inputs-wrap">
<view class="form-group">
<text class="form-label">储蓄卡卡号</text>
<input
class="form-input"
type="number"
v-model="accountForm.bankCard"
placeholder="请输入收款人储蓄卡卡号"
placeholder-class="form-ph"
maxlength="30"
/>
</view>
<view class="form-group">
<text class="form-label">开户银行名称</text>
<input
class="form-input"
v-model="accountForm.bankName"
placeholder="例如:中国工商银行 / 招商银行 / 建设银行"
placeholder-class="form-ph"
maxlength="40"
/>
</view>
<view class="form-group">
<text class="form-label">持卡人真实姓名</text>
<input
class="form-input"
v-model="accountForm.realName"
placeholder="需与银行卡开户姓名严格一致"
placeholder-class="form-ph"
maxlength="20"
/>
</view>
</view>
</view>
<!-- 卡片 5: 温馨提示与财务规范 -->
<view class="rules-card">
<view class="rules-head">
<image class="rules-icon" :src="ICONS.shield" mode="aspectFit" />
<text class="rules-title">提现服务说明与保障</text>
</view>
<view class="rules-list">
<view class="rule-line">
<text class="dot">·</text>
<text class="text">最低提现门槛为 ¥{{ minWithdrawAmount }} 元,单笔单日提现上限最高 ¥20,000 元;</text>
</view>
<view class="rule-line">
<text class="dot">·</text>
<text class="text">每日提现申请经系统安全扫描与财务核验后打款,最快即时到账,遇节假日顺延;</text>
</view>
<view class="rule-line">
<text class="dot">·</text>
<text class="text">请仔细核对支付宝账号、银行卡号与收款人姓名,若信息有误将导致打款驳回原路退回;</text>
</view>
<view class="rule-line">
<text class="dot">·</text>
<text class="text">如有任何提现资金疑问,可随时通过个人中心联系官方在线客服快速核查排查。</text>
</view>
</view>
</view>
<!-- 底部安全垫高 -->
<view class="bottom-spacer"></view>
</scroll-view>
<!-- 底部固定提交按钮卡 -->
<view class="fixed-submit-bar">
<view class="submit-summary">
<text class="summary-label">预计实际到账:</text>
<text class="summary-amount">¥{{ displayExpectedAmount }}</text>
</view>
<button
class="btn-submit-withdraw btn-active"
:class="{ disabled: isSubmitDisabled }"
:loading="isSubmitting"
@click="handleSubmitWithdraw"
>
{{ isSubmitting ? '正在提交申请...' : '确认申请提现' }}
</button>
</view>
<!-- 提现历史审批记录抽屉弹窗 (Drawer / Modal) -->
<view class="records-modal-mask" v-if="showRecordsDrawer" @click="showRecordsDrawer = false">
<view class="records-drawer-box" @click.stop>
<view class="drawer-header">
<text class="drawer-title">提现审批记录 ({{ withdrawalsList.length }})</text>
<view class="btn-drawer-close btn-active" @click="showRecordsDrawer = false">
<image class="close-svg" :src="ICONS.close" mode="aspectFit" />
</view>
</view>
<scroll-view scroll-y class="drawer-scroll-body" v-if="withdrawalsList.length > 0">
<view v-for="rec in withdrawalsList" :key="rec.id" class="record-row-card">
<view class="rec-top">
<text class="rec-no">{{ rec.withdrawNo }}</text>
<text
class="rec-status-tag"
:class="{
pending: rec.status === '待审核',
processing: rec.status === '处理中',
success: rec.status === '已打款',
rejected: rec.status === '已驳回'
}"
>
{{ rec.status }}
</text>
</view>
<view class="rec-center">
<text class="rec-amount">¥{{ rec.amount }}</text>
<text class="rec-channel">{{ rec.channel }}</text>
</view>
<view class="rec-bottom">
<text class="rec-time">{{ rec.applyTime }}</text>
<text class="rec-reason" v-if="rec.reason">驳回理由:{{ rec.reason }}</text>
</view>
</view>
</scroll-view>
<view class="empty-drawer" v-else>
<text class="empty-txt">暂无提现申请记录</text>
</view>
</view>
</view>
</view>
</template>
<script setup>
import { ref, computed, onMounted } from 'vue';
import { onShow } from '@dcloudio/uni-app';
import { ICONS } from '@/common/icons.js';
import { getCurrentThemeKey, applyThemeToNativeUI } from '@/common/theme.js';
import { getNavBarInfo } from '@/common/nav.js';
import {
getUserProfile,
withdrawCommission,
getUserWithdrawals,
getPlatformConfigs
} from '@/common/api.js';
const currentThemeKey = ref(getCurrentThemeKey());
const navInfo = ref(getNavBarInfo());
const userCommission = ref('0.00');
const currentChannel = ref('WECHAT');
const withdrawAmount = ref('');
const isSubmitting = ref(false);
const showRecordsDrawer = ref(false);
const withdrawalsList = ref([]);
const minWithdrawAmount = ref(50);
const accountForm = ref({
alipayAccount: '',
bankCard: '',
bankName: '',
realName: ''
});
const stats = ref({
totalSuccessAmount: '0.00',
pendingAmount: '0.00'
});
const navStyle = computed(() => {
return {
'--safe-header-gap': `${navInfo.value.safeHeaderGap}px`,
'--capsule-right-space': `${navInfo.value.capsuleRightSpace}px`,
'--capsule-height': `${navInfo.value.capsuleHeight}px`
};
});
const commissionParts = computed(() => {
const parts = String(userCommission.value || '0.00').split('.');
return {
integer: parts[0] || '0',
decimal: (parts[1] || '00').slice(0, 2)
};
});
const displayExpectedAmount = computed(() => {
const num = parseFloat(withdrawAmount.value);
if (isNaN(num) || num <= 0) return '0.00';
return num.toFixed(2);
});
const isAmountExceeded = computed(() => {
const inputNum = parseFloat(withdrawAmount.value);
const maxNum = parseFloat(userCommission.value || '0');
return !isNaN(inputNum) && inputNum > maxNum;
});
const isAmountBelowMin = computed(() => {
const inputNum = parseFloat(withdrawAmount.value);
return !isNaN(inputNum) && inputNum > 0 && inputNum < minWithdrawAmount.value;
});
const isSubmitDisabled = computed(() => {
const inputNum = parseFloat(withdrawAmount.value);
if (isNaN(inputNum) || inputNum <= 0) return true;
if (inputNum < minWithdrawAmount.value) return true;
if (inputNum > parseFloat(userCommission.value || '0')) return true;
if (isSubmitting.value) return true;
return false;
});
const handleBack = () => {
const pages = getCurrentPages();
if (pages.length > 1) {
uni.navigateBack();
} else {
uni.switchTab({ url: '/pages/user/index' });
}
};
const selectChannel = (channelKey) => {
currentChannel.value = channelKey;
};
const handleFillAllCommission = () => {
const comm = parseFloat(userCommission.value || '0');
if (comm <= 0) {
uni.showToast({ title: '当前无可用提现佣金', icon: 'none' });
return;
}
withdrawAmount.value = String(comm);
};
const loadPageData = async () => {
try {
const profile = await getUserProfile(1001);
if (profile && profile.commission !== undefined) {
userCommission.value = String(profile.commission);
if (profile.nickname) {
accountForm.value.realName = profile.nickname;
}
}
} catch (_) {}
try {
const configs = await getPlatformConfigs();
if (configs?.finance_rules?.minWithdrawAmount) {
minWithdrawAmount.value = Number(configs.finance_rules.minWithdrawAmount) || 50;
}
} catch (_) {}
try {
const records = await getUserWithdrawals(1001);
if (Array.isArray(records)) {
withdrawalsList.value = records;
let successSum = 0;
let pendingSum = 0;
records.forEach(r => {
const amt = Number(r.amount || 0);
if (r.status === '已打款') successSum += amt;
if (r.status === '待审核' || r.status === '处理中') pendingSum += amt;
});
stats.value.totalSuccessAmount = successSum.toFixed(2);
stats.value.pendingAmount = pendingSum.toFixed(2);
}
} catch (_) {}
};
const openRecordsDrawer = () => {
showRecordsDrawer.value = true;
};
const handleSubmitWithdraw = async () => {
const amt = parseFloat(withdrawAmount.value);
const comm = parseFloat(userCommission.value || '0');
if (isNaN(amt) || amt <= 0) {
uni.showToast({ title: '请输入有效的提现金额', icon: 'none' });
return;
}
if (amt < minWithdrawAmount.value) {
uni.showToast({ title: `提现须满 ¥${minWithdrawAmount.value} 起提`, icon: 'none' });
return;
}
if (amt > comm) {
uni.showToast({ title: '提现金额超出可用余额', icon: 'none' });
return;
}
if (amt > 20000) {
uni.showToast({ title: '单笔提现最高 ¥20000', icon: 'none' });
return;
}
// 渠道表单必填项校验
if (currentChannel.value === 'ALIPAY') {
if (!accountForm.value.alipayAccount.trim()) {
uni.showToast({ title: '请输入支付宝账号', icon: 'none' });
return;
}
if (!accountForm.value.realName.trim()) {
uni.showToast({ title: '请输入收款人姓名', icon: 'none' });
return;
}
} else if (currentChannel.value === 'BANK') {
if (!accountForm.value.bankCard.trim()) {
uni.showToast({ title: '请输入银行卡卡号', icon: 'none' });
return;
}
if (!accountForm.value.bankName.trim()) {
uni.showToast({ title: '请输入开户行名称', icon: 'none' });
return;
}
if (!accountForm.value.realName.trim()) {
uni.showToast({ title: '请输入持卡人姓名', icon: 'none' });
return;
}
}
isSubmitting.value = true;
uni.showLoading({ title: '正在提交申请...' });
try {
const payload = {
channel: currentChannel.value,
alipayAccount: accountForm.value.alipayAccount.trim(),
bankCard: accountForm.value.bankCard.trim(),
bankName: accountForm.value.bankName.trim(),
realName: accountForm.value.realName.trim()
};
const res = await withdrawCommission(1001, amt, payload);
uni.hideLoading();
isSubmitting.value = false;
if (res && res.commission !== undefined) {
userCommission.value = String(res.commission);
} else {
userCommission.value = Math.max(0, comm - amt).toFixed(2);
}
withdrawAmount.value = '';
uni.showModal({
title: '提现申请已提交',
content: `您申请提现的 ¥${amt.toFixed(2)} 已进入财务审批通道,款项将结算至指定收款账户。`,
confirmText: '查看记录',
cancelText: '知道了',
confirmColor: '#10B981',
success: (mRes) => {
loadPageData();
if (mRes.confirm) {
showRecordsDrawer.value = true;
}
}
});
} catch (err) {
uni.hideLoading();
isSubmitting.value = false;
uni.showToast({
title: err.message || '提现申请提交失败',
icon: 'none'
});
}
};
onMounted(() => {
navInfo.value = getNavBarInfo();
currentThemeKey.value = getCurrentThemeKey();
applyThemeToNativeUI(currentThemeKey.value);
loadPageData();
});
onShow(() => {
currentThemeKey.value = getCurrentThemeKey();
applyThemeToNativeUI(currentThemeKey.value);
loadPageData();
});
</script>
<style lang="scss" scoped>
.withdraw-page {
min-height: 100vh;
background-color: #0A0F1D;
display: flex;
flex-direction: column;
box-sizing: border-box;
color: #F8FAFC;
}
/* 沉浸式自定义顶栏 */
.custom-nav-bar {
position: sticky;
top: 0;
z-index: 100;
padding-top: var(--safe-header-gap, 44px);
background: rgba(10, 15, 29, 0.92);
backdrop-filter: blur(20px);
border-bottom: 1px solid rgba(255, 255, 255, 0.05);
.nav-content {
height: var(--capsule-height, 44px);
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 calc(var(--capsule-right-space, 10px) + 8rpx) 0 24rpx;
.btn-nav-back {
width: 64rpx;
height: 64rpx;
border-radius: 50%;
background: rgba(255, 255, 255, 0.08);
display: flex;
align-items: center;
justify-content: center;
.nav-back-icon {
width: 36rpx;
height: 36rpx;
}
}
.nav-title {
font-size: 32rpx;
font-weight: 700;
color: #F8FAFC;
letter-spacing: 1rpx;
}
.nav-right-action {
padding: 10rpx 16rpx;
background: rgba(99, 102, 241, 0.12);
border: 1px solid rgba(99, 102, 241, 0.3);
border-radius: 24rpx;
.records-link-text {
font-size: 22rpx;
font-weight: 600;
color: #818CF8;
}
}
}
}
/* 页面滚动内容区 */
.page-scroll-body {
flex: 1;
padding: 24rpx 28rpx 0;
box-sizing: border-box;
}
/* 卡片 1: 资产流光看板 */
.balance-card {
position: relative;
background: linear-gradient(135deg, #1E1B4B 0%, #0F172A 100%);
border: 1px solid rgba(99, 102, 241, 0.35);
border-radius: 28rpx;
padding: 32rpx 28rpx;
margin-bottom: 24rpx;
overflow: hidden;
box-shadow: 0 12rpx 36rpx rgba(0, 0, 0, 0.35);
.card-bg-glow {
position: absolute;
top: -50rpx;
right: -50rpx;
width: 220rpx;
height: 220rpx;
border-radius: 50%;
background: radial-gradient(circle, rgba(99, 102, 241, 0.4) 0%, transparent 70%);
pointer-events: none;
}
.balance-inner {
position: relative;
z-index: 2;
.balance-title-row {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 16rpx;
.title-left {
display: flex;
align-items: center;
gap: 12rpx;
.wallet-icon-svg {
width: 36rpx;
height: 36rpx;
}
.balance-title {
font-size: 24rpx;
color: #CBD5E1;
}
}
.safe-badge {
font-size: 20rpx;
font-weight: 600;
color: #34D399;
background: rgba(16, 185, 129, 0.15);
border: 1px solid rgba(16, 185, 129, 0.3);
padding: 4rpx 14rpx;
border-radius: 20rpx;
}
}
.amount-number-row {
display: flex;
align-items: baseline;
margin-bottom: 24rpx;
.currency-mark {
font-size: 40rpx;
font-weight: 700;
color: #F59E0B;
margin-right: 8rpx;
}
.amount-integer {
font-size: 64rpx;
font-weight: 800;
color: #FFFFFF;
font-variant-numeric: tabular-nums;
line-height: 1;
}
.amount-decimal {
font-size: 36rpx;
font-weight: 700;
color: #F8FAFC;
font-variant-numeric: tabular-nums;
}
}
.balance-stats-row {
display: flex;
align-items: center;
justify-content: space-between;
background: rgba(0, 0, 0, 0.25);
border-radius: 18rpx;
padding: 16rpx 20rpx;
border: 1px solid rgba(255, 255, 255, 0.06);
.stat-cell {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
.cell-label {
font-size: 20rpx;
color: #94A3B8;
margin-bottom: 6rpx;
}
.cell-val {
font-size: 24rpx;
font-weight: 700;
color: #F8FAFC;
&.gold { color: #F59E0B; }
&.green { color: #10B981; }
}
}
.cell-divider {
width: 1px;
height: 36rpx;
background: rgba(255, 255, 255, 0.1);
}
}
}
}
/* 通用功能卡片 */
.content-card {
background: #151D30;
border: 1px solid rgba(255, 255, 255, 0.08);
border-radius: 24rpx;
padding: 28rpx;
margin-bottom: 24rpx;
.card-section-head {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 24rpx;
.section-title {
font-size: 28rpx;
font-weight: 700;
color: #F8FAFC;
}
.section-sub {
font-size: 22rpx;
color: #64748B;
}
.section-rule-hint {
font-size: 22rpx;
color: #F59E0B;
font-weight: 600;
}
}
}
/* 渠道选择九宫格 */
.channel-grid {
display: flex;
gap: 16rpx;
.channel-item {
flex: 1;
position: relative;
background: #0F172A;
border: 1.5px solid rgba(255, 255, 255, 0.08);
border-radius: 20rpx;
padding: 24rpx 12rpx;
display: flex;
flex-direction: column;
align-items: center;
transition: all 0.2s ease;
&.active {
background: rgba(16, 185, 129, 0.08);
border-color: #10B981;
box-shadow: 0 4rpx 20rpx rgba(16, 185, 129, 0.25);
}
.channel-badge {
position: absolute;
top: -12rpx;
right: 12rpx;
font-size: 18rpx;
background: #10B981;
color: #FFFFFF;
padding: 2rpx 10rpx;
border-radius: 12rpx;
font-weight: 600;
&.blue { background: #0284C7; }
&.gold { background: #D97706; }
}
.channel-icon-wrap {
width: 72rpx;
height: 72rpx;
border-radius: 20rpx;
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 12rpx;
&.wechat { background: rgba(16, 185, 129, 0.15); }
&.alipay { background: rgba(2, 132, 199, 0.15); }
&.bank { background: rgba(245, 158, 11, 0.15); }
.channel-svg {
width: 44rpx;
height: 44rpx;
}
}
.channel-name {
font-size: 24rpx;
font-weight: 700;
color: #F8FAFC;
margin-bottom: 4rpx;
}
.channel-desc {
font-size: 20rpx;
color: #64748B;
}
.channel-select-mark {
position: absolute;
bottom: 8rpx;
right: 8rpx;
.check-svg {
width: 28rpx;
height: 28rpx;
}
}
}
}
/* 提现金额大字输入框 */
.amount-input-box {
display: flex;
align-items: center;
background: #0F172A;
border: 1px solid rgba(255, 255, 255, 0.1);
border-radius: 20rpx;
padding: 0 24rpx;
height: 104rpx;
margin-bottom: 14rpx;
.input-currency-symbol {
font-size: 44rpx;
font-weight: 800;
color: #10B981;
margin-right: 16rpx;
}
.amount-field-input {
flex: 1;
font-size: 40rpx;
font-weight: 800;
color: #FFFFFF;
font-variant-numeric: tabular-nums;
}
.amount-input-ph {
font-size: 26rpx;
font-weight: 400;
color: #64748B;
}
.btn-all-in {
font-size: 24rpx;
font-weight: 700;
color: #10B981;
background: rgba(16, 185, 129, 0.15);
border: 1px solid rgba(16, 185, 129, 0.35);
padding: 8rpx 20rpx;
border-radius: 14rpx;
margin: 0;
line-height: 1.4;
}
}
.amount-tips-row {
.tip-msg {
font-size: 22rpx;
line-height: 1.4;
&.normal { color: #94A3B8; }
&.warning { color: #F59E0B; }
&.error { color: #EF4444; font-weight: 600; }
}
}
/* 账户资料录入与通知卡 */
.wechat-bind-notice {
background: rgba(16, 185, 129, 0.08);
border: 1px dashed rgba(16, 185, 129, 0.3);
border-radius: 18rpx;
padding: 22rpx 24rpx;
.notice-head {
display: flex;
align-items: center;
gap: 12rpx;
margin-bottom: 8rpx;
.notice-icon {
width: 32rpx;
height: 32rpx;
}
.notice-title {
font-size: 24rpx;
font-weight: 700;
color: #34D399;
}
}
.notice-body {
font-size: 22rpx;
color: #94A3B8;
line-height: 1.5;
}
}
.form-inputs-wrap {
display: flex;
flex-direction: column;
gap: 20rpx;
.form-group {
display: flex;
flex-direction: column;
gap: 10rpx;
.form-label {
font-size: 24rpx;
font-weight: 600;
color: #CBD5E1;
}
.form-input {
background: #0F172A;
border: 1px solid rgba(255, 255, 255, 0.1);
border-radius: 16rpx;
padding: 0 20rpx;
height: 84rpx;
font-size: 26rpx;
color: #FFFFFF;
}
.form-ph {
font-size: 24rpx;
color: #64748B;
}
}
}
/* 规范说明卡片 */
.rules-card {
background: rgba(21, 29, 48, 0.6);
border: 1px solid rgba(255, 255, 255, 0.05);
border-radius: 20rpx;
padding: 24rpx;
margin-bottom: 30rpx;
.rules-head {
display: flex;
align-items: center;
gap: 10rpx;
margin-bottom: 14rpx;
.rules-icon {
width: 28rpx;
height: 28rpx;
}
.rules-title {
font-size: 24rpx;
font-weight: 600;
color: #94A3B8;
}
}
.rules-list {
display: flex;
flex-direction: column;
gap: 10rpx;
.rule-line {
display: flex;
align-items: flex-start;
gap: 8rpx;
.dot {
font-size: 24rpx;
color: #64748B;
line-height: 1.4;
}
.text {
font-size: 22rpx;
color: #64748B;
line-height: 1.5;
flex: 1;
}
}
}
}
.bottom-spacer {
height: calc(160rpx + env(safe-area-inset-bottom));
}
/* 底部固定提交操作栏 */
.fixed-submit-bar {
position: fixed;
bottom: 0;
left: 0;
right: 0;
z-index: 100;
background: rgba(10, 15, 29, 0.95);
backdrop-filter: blur(20px);
border-top: 1px solid rgba(255, 255, 255, 0.08);
padding: 20rpx 32rpx calc(20rpx + env(safe-area-inset-bottom));
display: flex;
align-items: center;
justify-content: space-between;
gap: 24rpx;
.submit-summary {
display: flex;
flex-direction: column;
.summary-label {
font-size: 20rpx;
color: #94A3B8;
margin-bottom: 4rpx;
}
.summary-amount {
font-size: 34rpx;
font-weight: 800;
color: #10B981;
font-variant-numeric: tabular-nums;
}
}
.btn-submit-withdraw {
flex: 1;
height: 88rpx;
line-height: 88rpx;
background: linear-gradient(135deg, #10B981 0%, #059669 100%);
color: #FFFFFF;
font-size: 30rpx;
font-weight: 700;
border-radius: 44rpx;
margin: 0;
box-shadow: 0 8rpx 24rpx rgba(16, 185, 129, 0.35);
&.disabled {
opacity: 0.5;
pointer-events: none;
}
}
}
/* 提现审批记录抽屉弹窗 */
.records-modal-mask {
position: fixed;
inset: 0;
background: rgba(0, 0, 0, 0.7);
backdrop-filter: blur(8px);
z-index: 200;
display: flex;
align-items: flex-end;
.records-drawer-box {
width: 100%;
max-height: 80vh;
background: #151D30;
border-top: 1px solid rgba(255, 255, 255, 0.12);
border-radius: 36rpx 36rpx 0 0;
padding: 32rpx 32rpx calc(32rpx + env(safe-area-inset-bottom));
box-sizing: border-box;
display: flex;
flex-direction: column;
.drawer-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 24rpx;
.drawer-title {
font-size: 32rpx;
font-weight: 700;
color: #F8FAFC;
}
.btn-drawer-close {
width: 60rpx;
height: 60rpx;
border-radius: 50%;
background: rgba(255, 255, 255, 0.08);
display: flex;
align-items: center;
justify-content: center;
.close-svg {
width: 32rpx;
height: 32rpx;
}
}
}
.drawer-scroll-body {
flex: 1;
max-height: 58vh;
.record-row-card {
background: #0F172A;
border: 1px solid rgba(255, 255, 255, 0.08);
border-radius: 20rpx;
padding: 20rpx 24rpx;
margin-bottom: 16rpx;
.rec-top {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10rpx;
.rec-no {
font-size: 22rpx;
color: #64748B;
font-family: monospace;
}
.rec-status-tag {
font-size: 20rpx;
font-weight: 600;
padding: 2rpx 14rpx;
border-radius: 10rpx;
&.pending {
background: rgba(245, 158, 11, 0.15);
color: #F59E0B;
}
&.processing {
background: rgba(99, 102, 241, 0.15);
color: #818CF8;
}
&.success {
background: rgba(16, 185, 129, 0.15);
color: #10B981;
}
&.rejected {
background: rgba(239, 68, 68, 0.15);
color: #EF4444;
}
}
}
.rec-center {
display: flex;
justify-content: space-between;
align-items: baseline;
margin-bottom: 10rpx;
.rec-amount {
font-size: 34rpx;
font-weight: 800;
color: #F8FAFC;
}
.rec-channel {
font-size: 22rpx;
color: #94A3B8;
}
}
.rec-bottom {
display: flex;
justify-content: space-between;
align-items: center;
.rec-time {
font-size: 20rpx;
color: #64748B;
}
.rec-reason {
font-size: 20rpx;
color: #EF4444;
}
}
}
}
.empty-drawer {
padding: 80rpx 0;
text-align: center;
.empty-txt {
font-size: 26rpx;
color: #64748B;
}
}
}
}
/* 浅色暖阳主题定制适配 */
.theme-warm {
background-color: #F7F5F0;
color: #1C1917;
.custom-nav-bar {
background: rgba(247, 245, 240, 0.95);
border-bottom-color: #E7E2D8;
.nav-content {
.btn-nav-back {
background: #FFFFFF;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05);
}
.nav-title {
color: #1C1917;
}
.nav-right-action {
background: #FFF7ED;
border-color: rgba(234, 88, 12, 0.3);
.records-link-text {
color: #EA580C;
}
}
}
}
.balance-card {
background: linear-gradient(135deg, #FFFFFF 0%, #FFF7ED 100%);
border-color: rgba(234, 88, 12, 0.25);
box-shadow: 0 8rpx 30rpx rgba(234, 88, 12, 0.12);
.balance-inner {
.balance-title-row .title-left .balance-title {
color: #78716C;
}
.amount-number-row {
.amount-integer { color: #1C1917; }
.amount-decimal { color: #44403C; }
}
.balance-stats-row {
background: rgba(255, 255, 255, 0.8);
border-color: #F0ECE4;
.stat-cell .cell-label { color: #78716C; }
.stat-cell .cell-val { color: #1C1917; }
.cell-divider { background: #E7E2D8; }
}
}
}
.content-card {
background: #FFFFFF;
border-color: #EAE5DC;
box-shadow: 0 4rpx 20rpx rgba(28, 25, 23, 0.04);
.card-section-head .section-title {
color: #1C1917;
}
}
.channel-grid .channel-item {
background: #FAFAF9;
border-color: #E7E5E4;
&.active {
background: #FFF7ED;
border-color: #EA580C;
}
.channel-name { color: #1C1917; }
}
.amount-input-box {
background: #FAFAF9;
border-color: #E7E5E4;
.input-currency-symbol { color: #EA580C; }
.amount-field-input { color: #1C1917; }
.btn-all-in {
background: rgba(234, 88, 12, 0.12);
border-color: rgba(234, 88, 12, 0.35);
color: #EA580C;
}
}
.form-inputs-wrap .form-group {
.form-label { color: #44403C; }
.form-input {
background: #FAFAF9;
border-color: #E7E5E4;
color: #1C1917;
}
}
.fixed-submit-bar {
background: rgba(255, 255, 255, 0.95);
border-top-color: #E7E2D8;
.submit-summary .summary-amount {
color: #EA580C;
}
.btn-submit-withdraw {
background: linear-gradient(135deg, #F97316 0%, #EA580C 100%);
box-shadow: 0 8rpx 24rpx rgba(234, 88, 12, 0.35);
}
}
.records-modal-mask .records-drawer-box {
background: #FFFFFF;
border-top-color: #E7E2D8;
.drawer-header .drawer-title { color: #1C1917; }
.drawer-header .btn-drawer-close { background: #F5F5F4; }
.drawer-scroll-body .record-row-card {
background: #FAFAF9;
border-color: #E7E5E4;
.rec-center .rec-amount { color: #1C1917; }
}
}
}
</style>