文件
shanghaipeiwan/pwuniapp/pages/user/withdraw.vue
xcbyy 87cb6a6374 fix(miniapp): 提现/财务接口不再用 1001 演示身份,修复 403
- getUserProfile/getUserWithdrawals/getUserFinanceRecords 去掉 userId=1001 默认值,改由 normalizeUserId 解析登录身份

- withdraw.vue / withdraw-records.vue / workspace.vue 调用改为 normalizeUserId(),不再硬编码 1001

- normalizeUserId 将 1001 视为演示占位符:登录态下传 0 由 token 识别,未登录才兜底 1001

- request.js 遇 403 身份校验失败时清理错配登录态并提示重新登录(其它 403 权限拒绝不受影响)

- 登录态闸门补齐用例(108 套件/714 用例全绿)
2026-10-21 11:38:26 +08:00

1441 行
35 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>
<view class="nav-title-wrap">
<text class="nav-title">佣金收益提现</text>
</view>
<!-- 胶囊右侧对称避让占位 -->
<view class="nav-capsule-placeholder"></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="records-btn-pill btn-active" @click="openRecordsDrawer">
<image class="rec-icon" :src="ICONS.orderList" mode="aspectFit" />
<text class="rec-text">提现记录</text>
<image class="rec-arrow" :src="ICONS.chevronRight" mode="aspectFit" />
</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 channel-card">
<view class="card-section-head">
<text class="section-title">提现到账方式</text>
<view class="section-badge-green">极速免审核</view>
</view>
<view class="wechat-channel-box">
<view class="channel-icon-wrap wechat">
<image class="channel-svg" :src="ICONS.wechat" mode="aspectFit" />
</view>
<view class="channel-info-col">
<view class="channel-line-1">
<text class="channel-name">微信零钱钱包</text>
<text class="channel-tag">推荐首选</text>
</view>
<text class="channel-desc">企业付款直达当前微信零钱 · 免手续费</text>
</view>
<view class="channel-check-badge">
<image class="check-svg" :src="ICONS.checkCircle" mode="aspectFit" />
</view>
</view>
<view class="wechat-safe-notice">
<text class="notice-desc">系统将通过微信商户企业付款打款到您当前登录小程序的微信零钱账户中,无需额外录入银行卡号,提交申请后预计 1 至 24 小时内由系统自动发放至微信零钱钱包。</text>
</view>
</view>
<!-- 卡片 3: 提现金额输入区 -->
<view class="content-card amount-card">
<view class="card-section-head">
<text class="section-title">提现金额</text>
<text class="section-rule-hint">最低满 ¥{{ minWithdrawAmount }} 起提</text>
</view>
<view class="amount-input-box" :class="{ 'is-focused': isInputFocused }">
<text class="input-currency-symbol">¥</text>
<input
class="amount-field-input"
type="digit"
v-model="withdrawAmount"
placeholder="0.00"
placeholder-class="amount-input-ph"
maxlength="10"
@focus="isInputFocused = true"
@blur="isInputFocused = false"
/>
<view class="btn-all-in btn-active" @click="handleFillAllCommission">
<text class="btn-all-in-text">全部提现</text>
</view>
</view>
<!-- 实时校验提示 -->
<view class="amount-tips-row">
<view v-if="isAmountExceeded" class="tip-msg error">
<text class="tip-badge">!</text>
<text class="tip-text">输入金额已超出当前可提现佣金余额 (¥{{ userCommission }})</text>
</view>
<view v-else-if="isAmountBelowMin" class="tip-msg warning">
<text class="tip-badge">!</text>
<text class="tip-text">提现金额须满 ¥{{ minWithdrawAmount }} 元起提</text>
</view>
<view v-else class="tip-msg normal">
<text class="balance-label">可提余额</text>
<text class="balance-num">¥{{ userCommission }}</text>
<text class="dot-divider">·</text>
<text class="limit-text">单笔最高 ¥20,000</text>
<text class="dot-divider">·</text>
<text class="free-fee-badge">免收手续费</text>
</view>
</view>
</view>
<!-- 卡片 4: 温馨提示与财务规范 -->
<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>
</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 { preloadSubscribeTemplates, requestSubscribeFor } from '@/common/subscribe.js';
import {
getUserProfile,
withdrawCommission,
getUserWithdrawals,
getPlatformConfigs,
normalizeUserId
} 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 isInputFocused = ref(false);
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(normalizeUserId());
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(normalizeUserId());
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 = () => {
uni.navigateTo({
url: '/pages/user/withdraw-records'
});
};
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;
}
isSubmitting.value = true;
uni.showLoading({ title: '正在提交申请...' });
// 提现前请求一次性订阅授权(提现到账通知)
requestSubscribeFor('withdraw');
try {
const payload = {
channel: 'WECHAT'
};
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) {
uni.navigateTo({
url: '/pages/user/withdraw-records'
});
}
}
});
} 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();
preloadSubscribeTemplates();
});
onShow(() => {
currentThemeKey.value = getCurrentThemeKey();
applyThemeToNativeUI(currentThemeKey.value);
loadPageData();
});
</script>
<style lang="scss">
.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 {
position: relative;
height: var(--capsule-height, 44px);
display: flex;
align-items: center;
padding: 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;
z-index: 10;
flex-shrink: 0;
.nav-back-icon {
width: 36rpx;
height: 36rpx;
}
}
.nav-title-wrap {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
display: flex;
align-items: center;
justify-content: center;
pointer-events: none;
.nav-title {
font-size: 32rpx;
font-weight: 700;
color: #F8FAFC;
letter-spacing: 1rpx;
}
}
.nav-capsule-placeholder {
margin-left: auto;
width: var(--capsule-right-space, 96px);
height: 100%;
}
}
}
/* 页面滚动内容区 */
.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;
}
}
.records-btn-pill {
display: flex;
align-items: center;
gap: 8rpx;
padding: 8rpx 18rpx;
background: rgba(16, 185, 129, 0.12);
border: 1px solid rgba(16, 185, 129, 0.35);
border-radius: 28rpx;
transition: all 0.2s ease;
.rec-icon {
width: 24rpx;
height: 24rpx;
}
.rec-text {
font-size: 22rpx;
font-weight: 600;
color: #10B981;
letter-spacing: 0.5rpx;
}
.rec-arrow {
width: 18rpx;
height: 18rpx;
opacity: 0.7;
}
}
}
.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-card {
.section-badge-green {
font-size: 20rpx;
font-weight: 600;
color: #10B981;
background: rgba(16, 185, 129, 0.12);
border: 1px solid rgba(16, 185, 129, 0.3);
padding: 2rpx 14rpx;
border-radius: 20rpx;
}
.wechat-channel-box {
display: flex;
align-items: center;
border: 1.5px solid rgba(16, 185, 129, 0.4);
background: rgba(16, 185, 129, 0.06);
border-radius: 20rpx;
padding: 24rpx;
margin-bottom: 20rpx;
box-shadow: 0 4rpx 20rpx rgba(16, 185, 129, 0.12);
.channel-icon-wrap.wechat {
width: 80rpx;
height: 80rpx;
border-radius: 20rpx;
background: rgba(16, 185, 129, 0.18);
display: flex;
align-items: center;
justify-content: center;
margin-right: 20rpx;
flex-shrink: 0;
.channel-svg {
width: 48rpx;
height: 48rpx;
}
}
.channel-info-col {
flex: 1;
.channel-line-1 {
display: flex;
align-items: center;
gap: 12rpx;
margin-bottom: 6rpx;
.channel-name {
font-size: 30rpx;
font-weight: 700;
color: #F8FAFC;
}
.channel-tag {
font-size: 18rpx;
color: #FFFFFF;
background: linear-gradient(135deg, #10B981, #059669);
padding: 2rpx 12rpx;
border-radius: 12rpx;
font-weight: 600;
}
}
.channel-desc {
font-size: 22rpx;
color: #94A3B8;
line-height: 1.4;
display: block;
}
}
.channel-check-badge {
width: 40rpx;
height: 40rpx;
display: flex;
align-items: center;
justify-content: center;
margin-left: 16rpx;
flex-shrink: 0;
.check-svg {
width: 36rpx;
height: 36rpx;
}
}
}
.wechat-safe-notice {
background: rgba(16, 185, 129, 0.05);
border: 1px dashed rgba(16, 185, 129, 0.25);
border-radius: 16rpx;
padding: 18rpx 20rpx;
.notice-desc {
font-size: 22rpx;
color: #94A3B8;
line-height: 1.5;
display: block;
}
}
}
/* 提现金额卡片专属样式 */
.amount-card {
.card-section-head {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 24rpx;
.section-title {
font-size: 30rpx;
font-weight: 700;
color: #F8FAFC;
}
.section-rule-hint {
font-size: 22rpx;
color: #F59E0B;
font-weight: 600;
background: rgba(245, 158, 11, 0.12);
border: 1px solid rgba(245, 158, 11, 0.28);
padding: 4rpx 16rpx;
border-radius: 20rpx;
}
}
.amount-input-box {
display: flex;
flex-direction: row;
align-items: center;
background: rgba(15, 23, 42, 0.7);
border: 2rpx solid rgba(255, 255, 255, 0.1);
border-radius: 20rpx;
padding: 0 24rpx;
height: 112rpx;
box-sizing: border-box;
transition: all 0.25s ease;
&.is-focused {
border-color: #10B981;
background: rgba(16, 185, 129, 0.05);
box-shadow: 0 0 0 6rpx rgba(16, 185, 129, 0.15);
}
.input-currency-symbol {
font-size: 52rpx;
font-weight: 800;
color: #10B981;
margin-right: 16rpx;
line-height: 1;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
}
.amount-field-input {
flex: 1;
height: 80rpx;
line-height: 80rpx;
font-size: 52rpx;
font-weight: 800;
color: #F8FAFC;
font-family: -apple-system, BlinkMacSystemFont, "DIN Alternate", "Helvetica Neue", sans-serif;
font-variant-numeric: tabular-nums;
}
.amount-input-ph {
color: #64748B;
font-size: 48rpx;
font-weight: 400;
}
.btn-all-in {
display: flex;
align-items: center;
justify-content: center;
padding: 10rpx 22rpx;
background: rgba(16, 185, 129, 0.12);
border: 1px solid rgba(16, 185, 129, 0.35);
border-radius: 28rpx;
margin-left: 16rpx;
flex-shrink: 0;
transition: all 0.2s ease;
.btn-all-in-text {
font-size: 24rpx;
font-weight: 600;
color: #10B981;
letter-spacing: 0.5rpx;
line-height: 1;
}
}
}
.amount-tips-row {
margin-top: 20rpx;
.tip-msg {
display: flex;
align-items: center;
font-size: 23rpx;
line-height: 1.4;
&.error {
color: #EF4444;
.tip-badge {
display: inline-flex;
align-items: center;
justify-content: center;
width: 28rpx;
height: 28rpx;
background: #EF4444;
color: #FFFFFF;
border-radius: 50%;
font-size: 20rpx;
font-weight: 800;
margin-right: 10rpx;
line-height: 1;
}
}
&.warning {
color: #F59E0B;
.tip-badge {
display: inline-flex;
align-items: center;
justify-content: center;
width: 28rpx;
height: 28rpx;
background: #F59E0B;
color: #FFFFFF;
border-radius: 50%;
font-size: 20rpx;
font-weight: 800;
margin-right: 10rpx;
line-height: 1;
}
}
&.normal {
color: #94A3B8;
display: flex;
align-items: center;
flex-wrap: wrap;
gap: 8rpx;
.balance-label {
color: #94A3B8;
}
.balance-num {
font-weight: 700;
color: #10B981;
font-size: 25rpx;
}
.dot-divider {
color: #64748B;
font-weight: 700;
}
.limit-text {
color: #94A3B8;
}
.free-fee-badge {
color: #10B981;
background: rgba(16, 185, 129, 0.1);
padding: 2rpx 10rpx;
border-radius: 6rpx;
font-size: 20rpx;
font-weight: 600;
}
}
}
}
}
/* 规范说明卡片 (高对比度深色模式) */
.rules-card {
background: rgba(30, 41, 59, 0.65);
border: 1px solid rgba(255, 255, 255, 0.08);
border-radius: 24rpx;
padding: 28rpx 24rpx;
margin-bottom: 30rpx;
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.2);
.rules-head {
display: flex;
align-items: center;
gap: 12rpx;
margin-bottom: 18rpx;
.rules-icon {
width: 32rpx;
height: 32rpx;
}
.rules-title {
font-size: 26rpx;
font-weight: 700;
color: #F8FAFC;
letter-spacing: 0.5rpx;
}
}
.rules-list {
display: flex;
flex-direction: column;
gap: 14rpx;
.rule-line {
display: flex;
align-items: flex-start;
gap: 10rpx;
.dot {
font-size: 28rpx;
font-weight: 800;
color: #10B981;
line-height: 1.4;
}
.text {
font-size: 23rpx;
color: #CBD5E1;
line-height: 1.6;
font-weight: 400;
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-wrap .nav-title {
color: #1C1917;
}
}
}
.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;
}
.records-btn-pill {
background: rgba(234, 88, 12, 0.08);
border-color: rgba(234, 88, 12, 0.3);
.rec-text { color: #EA580C; }
.rec-icon, .rec-arrow {
filter: brightness(0) saturate(100%) invert(44%) sepia(76%) saturate(2227%) hue-rotate(357deg) brightness(97%) contrast(93%);
}
}
}
.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-card {
.section-badge-green {
color: #EA580C;
background: #FFF7ED;
border-color: #FDBA74;
}
.wechat-channel-box {
background: #FFF7ED;
border: 1.5px solid #FDBA74;
box-shadow: 0 4rpx 16rpx rgba(234, 88, 12, 0.08);
.channel-info-col .channel-line-1 .channel-name {
color: #1C1917;
}
.channel-info-col .channel-desc {
color: #78716C;
}
}
.wechat-safe-notice {
background: #FAFAF9;
border-color: #E7E5E4;
.notice-desc {
color: #78716C;
}
}
}
.amount-card {
background: #FFFFFF;
border: 1px solid #F0ECE4;
box-shadow: 0 4rpx 20rpx rgba(28, 25, 23, 0.04);
.card-section-head {
.section-title {
color: #1C1917;
}
.section-rule-hint {
color: #EA580C;
background: #FFF7ED;
border: 1px solid #FFEDD5;
}
}
.amount-input-box {
background: #FAFAF9;
border: 2rpx solid #E7E5E4;
&.is-focused {
border-color: #EA580C;
background: #FFFFFF;
box-shadow: 0 0 0 6rpx rgba(234, 88, 12, 0.12);
}
.input-currency-symbol {
color: #EA580C;
}
.amount-field-input {
color: #1C1917;
}
.amount-input-ph {
color: #A8A29E;
}
.btn-all-in {
background: #FFF7ED;
border: 1px solid #FDBA74;
.btn-all-in-text {
color: #EA580C;
}
}
}
.amount-tips-row {
.tip-msg {
&.error {
color: #DC2626;
.tip-badge {
background: #DC2626;
}
}
&.warning {
color: #D97706;
.tip-badge {
background: #D97706;
}
}
&.normal {
color: #78716C;
.balance-label {
color: #78716C;
}
.balance-num {
color: #EA580C;
}
.dot-divider {
color: #D6D3D1;
}
.limit-text {
color: #78716C;
}
.free-fee-badge {
color: #EA580C;
background: #FFF7ED;
}
}
}
}
}
/* 规范说明卡片浅色暖阳专属高清晰度适配 (彻底解决图2红圈看不清问题) */
.rules-card {
background: #FFFFFF;
border: 1px solid #FED7AA;
box-shadow: 0 4rpx 20rpx rgba(234, 88, 12, 0.06);
.rules-head {
.rules-icon {
filter: brightness(0) saturate(100%) invert(44%) sepia(76%) saturate(2227%) hue-rotate(357deg) brightness(97%) contrast(93%);
}
.rules-title {
color: #9A3412;
font-weight: 700;
font-size: 26rpx;
}
}
.rules-list {
.rule-line {
.dot {
color: #EA580C;
font-weight: 800;
font-size: 28rpx;
}
.text {
color: #44403C;
font-size: 24rpx;
line-height: 1.6;
font-weight: 500;
}
}
}
}
.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>