统一排行榜对齐星雀UI,页面资源后台配置实时刷新

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
XingQue
2026-06-27 01:26:11 +08:00
parent 1ab2e2080a
commit 21112173f2
292 changed files with 64010 additions and 81 deletions

View File

@@ -0,0 +1,484 @@
// pages/tixian/tixian.js
// 子组件版本 - 完整代码,仅适配生命周期,业务逻辑不动
import request from '../../../../utils/request.js';
import upload from '../../../../utils/upload.js';
import PopupService from '../../../../services/popupService.js';
const app = getApp();
const PAGE_SIZE = 10;
let lastPullDownTime = 0;
const PULL_DOWN_INTERVAL = 2000;
Component({
data: {
imgUrls: {
pageBg: '',
cardBg: '',
iconWechat: '',
iconAlipay: '',
iconRecord: '',
iconRefresh: '',
},
assetList: [],
totalAmount: '0.00',
selectedAsset: null,
txfangshi: null,
txdianhua: '',
txzh: '',
txtupian: '',
ossImageUrl: '',
showTixianModal: false,
tixianAmount: '',
shouxufei: '0.00',
shijidaozhang: '0.00',
currentRate: '0.00',
recordList: [],
page: 1,
nomore: false,
loading: false,
isRefreshing: false,
canloadmore: true,
showSkfsModal: false,
tempTxfangshi: null,
tempTxPhone: '',
tempTxAccount: '',
tempTxImage: '',
choosingImage: false,
showModifyModal: false,
modifyingRecord: null,
modifyTxfangshi: null,
modifyTxPhone: '',
modifyTxAccount: '',
modifyTxImage: '',
modifyImageUrl: '',
showFailModal: false,
currentFailReason: '',
isLoading: false,
},
attached() {
this.initImageUrls();
this.loadAllAssets();
this.loadWithdrawMethod();
this.loadWithdrawRecords(true);
},
pageLifetimes: {
show() {
this.registerNotification();
PopupService.checkAndShow(this, 'tixian');
},
hide() {
const popup = this.selectComponent('#popupNotice');
popup?.cleanup?.();
}
},
methods: {
// 下拉刷新
onPullDownRefresh() {
if (this.data.isRefreshing) {
wx.stopPullDownRefresh();
return;
}
this.setData({ isRefreshing: true });
this.loadWithdrawRecords(true).then(() => {
wx.stopPullDownRefresh();
this.setData({ isRefreshing: false });
}).catch(() => {
wx.stopPullDownRefresh();
this.setData({ isRefreshing: false });
});
},
// 底部按钮加载更多
loadMoreRecords() {
if (this.data.nomore) {
wx.showToast({ title: '没有更多记录了', icon: 'none' });
return;
}
if (this.data.loading) return;
this.loadWithdrawRecords();
},
initImageUrls() {
const ossBase = app.globalData.ossImageUrl || '';
const imgDir = `${ossBase}beijing/tixian/`;
this.setData({
imgUrls: {
pageBg: `${imgDir}page_bg.png`,
cardBg: `${imgDir}card_bg.png`,
iconWechat: `${imgDir}icon_wechat.png`,
iconAlipay: `${imgDir}icon_alipay.png`,
iconRecord: `${imgDir}icon_record.png`,
iconRefresh: `${imgDir}icon_refresh.png`,
assetTileBg: `${imgDir}asset_tile_bg.png`,
}
});
},
async loadAllAssets() {
this.setData({ isLoading: true });
try {
const res = await request({ url: '/yonghu/tixianzichan', method: 'POST' });
if (res?.data?.code === 200) {
const data = res.data.data;
const assets = [];
if (data.dashou_yue && parseFloat(data.dashou_yue) > 0) {
assets.push({ type: 'dashou_yue', label: '打手佣金', amount: data.dashou_yue, rate: data.dashou_rate || 0 });
}
if (data.dashou_yajin && parseFloat(data.dashou_yajin) > 0) {
assets.push({ type: 'dashou_yajin', label: '打手保证金', amount: data.dashou_yajin, rate: data.dashou_yajin_rate || 0 });
}
if (data.shangjia_yue && parseFloat(data.shangjia_yue) > 0) {
assets.push({ type: 'shangjia_yue', label: '商家余额', amount: data.shangjia_yue, rate: data.shangjia_rate || 0 });
}
if (data.guanshi_fenyong && parseFloat(data.guanshi_fenyong) > 0) {
assets.push({ type: 'guanshi_fenyong', label: '管事分红', amount: data.guanshi_fenyong, rate: data.guanshi_rate || 0 });
}
if (data.zuzhang_fenyong && parseFloat(data.zuzhang_fenyong) > 0) {
assets.push({ type: 'zuzhang_fenyong', label: '组长分红', amount: data.zuzhang_fenyong, rate: data.zuzhang_rate || 0 });
}
if (data.kaoheguan_fenyong && parseFloat(data.kaoheguan_fenyong) > 0) {
assets.push({ type: 'kaoheguan_fenyong', label: '考核官分佣', amount: data.kaoheguan_fenyong, rate: data.kaoheguan_rate || 0 });
}
let total = 0;
assets.forEach(item => { total += parseFloat(item.amount); });
this.setData({ assetList: assets, totalAmount: total.toFixed(2), isLoading: false });
// 缓存费率
wx.setStorageSync('dashouRate', data.dashou_rate || 0);
wx.setStorageSync('dashou_yajin_rate', data.dashou_yajin_rate || 0);
wx.setStorageSync('shangjia_rate', data.shangjia_rate || 0);
wx.setStorageSync('guanshi_rate', data.guanshi_rate || 0);
wx.setStorageSync('zuzhang_rate', data.zuzhang_rate || 0);
wx.setStorageSync('kaoheguan_rate', data.kaoheguan_rate || 0);
} else {
throw new Error(res?.data?.msg || '获取资产失败');
}
} catch (err) {
console.error(err);
wx.showToast({ title: '加载失败', icon: 'none' });
this.setData({ isLoading: false });
}
},
async loadWithdrawMethod() {
const txzh = wx.getStorageSync('txzh') || '';
const txtupian = wx.getStorageSync('txtupian') || '';
const txfangshi = wx.getStorageSync('txfangshi') || null;
const txdianhua = wx.getStorageSync('txdianhua') || '';
if (txzh || txtupian) {
this.setData({ txzh, txtupian, txfangshi, txdianhua, ossImageUrl: app.globalData.ossImageUrl || '' });
} else {
try {
const res = await request({ url: '/yonghu/tixianhq', method: 'POST' });
if (res?.data?.code === 0) {
const data = res.data.data;
this.setData({
txzh: data.txzh || '',
txtupian: data.txtupian || '',
txfangshi: data.txfangshi || null,
txdianhua: data.txdianhua || '',
});
wx.setStorageSync('txzh', data.txzh || '');
wx.setStorageSync('txtupian', data.txtupian || '');
wx.setStorageSync('txfangshi', data.txfangshi || null);
wx.setStorageSync('txdianhua', data.txdianhua || '');
}
} catch (err) {}
}
},
onSelectAsset(e) {
const index = e.currentTarget.dataset.index;
const asset = this.data.assetList[index];
if (!asset || parseFloat(asset.amount) <= 0) {
wx.showToast({ title: '无可提现金额', icon: 'none' });
return;
}
this.setData({
selectedAsset: asset,
showTixianModal: true,
tixianAmount: '',
shouxufei: '0.00',
shijidaozhang: '0.00',
currentRate: asset.rate
});
},
onAmountInput(e) {
let val = e.detail.value;
if (val && !/^\d*\.?\d{0,2}$/.test(val)) return;
this.setData({ tixianAmount: val });
if (val && parseFloat(val) > 0) {
const amount = parseFloat(val);
const rate = parseFloat(this.data.selectedAsset.rate) || 0;
const fee = amount * rate;
const actual = amount - fee;
this.setData({ shouxufei: fee.toFixed(2), shijidaozhang: actual.toFixed(2) });
} else {
this.setData({ shouxufei: '0.00', shijidaozhang: '0.00' });
}
},
onQuickAmount(e) {
const val = e.currentTarget.dataset.value;
this.setData({ tixianAmount: val.toString() });
this.onAmountInput({ detail: { value: val.toString() } });
},
async onConfirmWithdraw() {
const { selectedAsset, tixianAmount, txfangshi, txzh, txtupian, txdianhua } = this.data;
if (!selectedAsset) { wx.showToast({ title: '请选择提现项目', icon: 'none' }); return; }
const amount = parseFloat(tixianAmount);
if (isNaN(amount) || amount <= 0) { wx.showToast({ title: '请输入有效金额', icon: 'none' }); return; }
if (amount > parseFloat(selectedAsset.amount)) { wx.showToast({ title: '超过可提现金额', icon: 'none' }); return; }
if (!txfangshi || (!txzh && !txtupian)) {
wx.showToast({ title: '请先设置收款方式', icon: 'none' });
this.setData({ showTixianModal: false });
this.onSetSkfs();
return;
}
let leixing = 1;
switch (selectedAsset.type) {
case 'dashou_yue': leixing = 1; break;
case 'dashou_yajin': leixing = 5; break;
case 'shangjia_yue': leixing = 6; break;
case 'guanshi_fenyong': leixing = 2; break;
case 'zuzhang_fenyong': leixing = 3; break;
case 'kaoheguan_fenyong': leixing = 4; break;
}
let txskfs = 0;
if (txzh && txtupian) txskfs = 3;
else if (txzh) txskfs = 1;
else if (txtupian) txskfs = 2;
try {
const res = await request({
url: '/yonghu/tixian',
method: 'POST',
data: { leixing, jine: amount.toFixed(2), fangshi: txfangshi, txskfs }
});
if (res?.data?.code === 0) {
const newAssetList = this.data.assetList.map(item => {
if (item.type === selectedAsset.type) {
const newAmount = (parseFloat(item.amount) - amount).toFixed(2);
return { ...item, amount: newAmount };
}
return item;
});
let newTotal = 0;
newAssetList.forEach(item => { newTotal += parseFloat(item.amount); });
this.setData({ assetList: newAssetList, totalAmount: newTotal.toFixed(2), showTixianModal: false, selectedAsset: null });
this.loadWithdrawRecords(true);
wx.showToast({ title: '提现申请已提交', icon: 'success' });
} else {
wx.showToast({ title: res?.data?.msg || '提现失败', icon: 'none' });
}
} catch (err) {
wx.showToast({ title: '网络错误', icon: 'none' });
}
},
onCloseTixianModal() {
this.setData({ showTixianModal: false, selectedAsset: null, tixianAmount: '' });
},
onSetSkfs() {
this.setData({
showSkfsModal: true,
tempTxfangshi: this.data.txfangshi,
tempTxPhone: this.data.txdianhua,
tempTxAccount: this.data.txzh,
tempTxImage: ''
});
},
onSelectFangshi(e) {
this.setData({ tempTxfangshi: e.currentTarget.dataset.fangshi });
},
onPhoneInput(e) { this.setData({ tempTxPhone: e.detail.value }); },
onAccountInput(e) { this.setData({ tempTxAccount: e.detail.value }); },
onChooseImage() {
if (this.data.choosingImage) return;
this.setData({ choosingImage: true });
wx.chooseMedia({
count: 1, mediaType: ['image'],
success: (res) => { this.setData({ tempTxImage: res.tempFiles[0].tempFilePath }); },
complete: () => { this.setData({ choosingImage: false }); }
});
},
onPreviewImage() {
if (this.data.tempTxImage) wx.previewImage({ urls: [this.data.tempTxImage] });
},
onDeleteImage() { this.setData({ tempTxImage: '' }); },
async onConfirmSkfs() {
const { tempTxfangshi, tempTxPhone, tempTxAccount, tempTxImage } = this.data;
if (!tempTxfangshi) { wx.showToast({ title: '请选择提现方式', icon: 'none' }); return; }
if (!tempTxPhone) { wx.showToast({ title: '请输入收款人电话', icon: 'none' }); return; }
if (tempTxfangshi == 1 && !tempTxImage) { wx.showToast({ title: '请上传微信收款码', icon: 'none' }); return; }
if (tempTxfangshi == 2 && !tempTxAccount && !tempTxImage) {
wx.showToast({ title: '请填写支付宝账号或上传收款码', icon: 'none' }); return;
}
const formData = { txdianhua: tempTxPhone, txzh: tempTxAccount || '' };
try {
const res = await upload({ url: '/yonghu/sksc', formData, filePath: tempTxImage || null, fileName: 'file' });
if (res?.data?.code === 0) {
const data = res.data.data;
this.setData({
txfangshi: tempTxfangshi, txdianhua: tempTxPhone, txzh: data.txzh || '', txtupian: data.txtupian || '', showSkfsModal: false
});
wx.setStorageSync('txfangshi', tempTxfangshi);
wx.setStorageSync('txdianhua', tempTxPhone);
wx.setStorageSync('txzh', data.txzh || '');
wx.setStorageSync('txtupian', data.txtupian || '');
wx.showToast({ title: '设置成功', icon: 'success' });
} else {
wx.showToast({ title: res?.data?.msg || '保存失败', icon: 'none' });
}
} catch (err) {
wx.showToast({ title: '网络错误', icon: 'none' });
}
},
onCloseSkfsModal() { this.setData({ showSkfsModal: false }); },
async loadWithdrawRecords(refresh = false) {
const now = Date.now();
if (now - lastPullDownTime < PULL_DOWN_INTERVAL && !refresh) return;
if (this.data.loading || this.data.isRefreshing) return;
const page = refresh ? 1 : this.data.page;
if (this.data.nomore && !refresh) return;
this.setData({ loading: true, isRefreshing: refresh });
lastPullDownTime = now;
try {
const res = await request({ url: '/yonghu/tixianjiluhq', method: 'POST', data: { page, limit: PAGE_SIZE } });
if (res?.data?.code === 0) {
const list = (res.data.data.list || []).map(item => ({
...item,
statusText: this.getStatusText(item.zhuangtai),
statusColor: this.getStatusColor(item.zhuangtai)
}));
const newList = refresh ? list : [...this.data.recordList, ...list];
const hasMore = res.data.data.has_more === true;
this.setData({
recordList: newList, page: page + 1, nomore: !hasMore, canloadmore: hasMore,
loading: false, isRefreshing: false
});
} else {
this.setData({ loading: false, isRefreshing: false });
}
} catch (err) {
this.setData({ loading: false, isRefreshing: false });
}
},
onModifyRecord(e) {
const record = e.currentTarget.dataset.record;
if (parseInt(record.zhuangtai) !== 1) {
wx.showToast({ title: '只有审核中的记录可修改', icon: 'none' });
return;
}
this.setData({
modifyingRecord: record,
modifyTxfangshi: record.fangshi,
modifyTxPhone: record.txdianhua || '',
modifyTxAccount: record.txzh || '',
modifyTxImage: '',
modifyImageUrl: record.txtupian ? (app.globalData.ossImageUrl + record.txtupian) : '',
showModifyModal: true
});
},
onSelectModifyFangshi(e) { this.setData({ modifyTxfangshi: e.currentTarget.dataset.fangshi }); },
onModifyPhoneInput(e) { this.setData({ modifyTxPhone: e.detail.value }); },
onModifyAccountInput(e) { this.setData({ modifyTxAccount: e.detail.value }); },
onChooseModifyImage() {
if (this.data.choosingImage) return;
this.setData({ choosingImage: true });
wx.chooseMedia({
count: 1, mediaType: ['image'],
success: (res) => { this.setData({ modifyTxImage: res.tempFiles[0].tempFilePath }); },
complete: () => { this.setData({ choosingImage: false }); }
});
},
onPreviewModifyImage() {
if (this.data.modifyTxImage) wx.previewImage({ urls: [this.data.modifyTxImage] });
else if (this.data.modifyImageUrl) wx.previewImage({ urls: [this.data.modifyImageUrl] });
},
onDeleteModifyImage() { this.setData({ modifyTxImage: '' }); },
async onConfirmModify() {
const { modifyTxfangshi, modifyTxPhone, modifyTxAccount, modifyTxImage, modifyingRecord } = this.data;
if (!modifyTxfangshi) { wx.showToast({ title: '请选择提现方式', icon: 'none' }); return; }
if (!modifyTxPhone) { wx.showToast({ title: '请输入收款人电话', icon: 'none' }); return; }
if (modifyTxfangshi == 1 && !modifyTxImage) { wx.showToast({ title: '请上传微信收款码', icon: 'none' }); return; }
if (modifyTxfangshi == 2 && !modifyTxAccount && !modifyTxImage) {
wx.showToast({ title: '请填写支付宝账号或上传收款码', icon: 'none' }); return;
}
const formData = { tixian_id: modifyingRecord.id, fangshi: modifyTxfangshi, txdianhua: modifyTxPhone, txzh: modifyTxAccount || '' };
try {
const res = await upload({ url: '/yonghu/yonghutxshxg', formData, filePath: modifyTxImage || null, fileName: 'file' });
if (res?.data?.code === 0) {
const data = res.data.data;
const newList = this.data.recordList.map(item => {
if (item.id === modifyingRecord.id) {
return { ...item, fangshi: modifyTxfangshi, txdianhua: modifyTxPhone, txzh: modifyTxAccount || '', txtupian: data.txtupian || modifyingRecord.txtupian };
}
return item;
});
this.setData({ recordList: newList, showModifyModal: false, modifyingRecord: null });
wx.showToast({ title: '修改成功', icon: 'success' });
} else {
wx.showToast({ title: res?.data?.msg || '修改失败', icon: 'none' });
}
} catch (err) {
wx.showToast({ title: '网络错误', icon: 'none' });
}
},
onCloseModifyModal() { this.setData({ showModifyModal: false, modifyingRecord: null }); },
onViewFailReason(e) {
const record = e.currentTarget.dataset.record;
const reason = record.fail_reason || record.shibaiyuanyin || '暂无详细信息';
this.setData({ currentFailReason: reason, showFailModal: true });
},
onCloseFailModal() { this.setData({ showFailModal: false }); },
getStatusText(zhuangtai) {
const s = parseInt(zhuangtai);
if (s === 1) return '审核中';
if (s === 2) return '成功';
if (s === 3) return '失败';
return '未知';
},
getStatusColor(zhuangtai) {
const s = parseInt(zhuangtai);
if (s === 1) return '#F5A623';
if (s === 2) return '#2ED158';
if (s === 3) return '#FF4D4F';
return '#999';
},
registerNotification() {
const comp = this.selectComponent('#global-notification');
if (comp?.showNotification) {
app.globalData.globalNotification = {
show: (data) => comp.showNotification(data),
hide: () => comp.hideNotification()
};
}
},
stopPropagation() {}
}
});

View File

@@ -0,0 +1,21 @@
{
"component": true,
"usingComponents": {
"global-notification": "/components/global-notification/global-notification",
"popup-notice": "/components/popup-notice/popup-notice"
},
"navigationBarTitleText": "提现中心",
"navigationBarBackgroundColor": "#1a0b2e",
"navigationBarTextStyle": "white",
"backgroundColor": "#1a0b2e",
"enablePullDownRefresh": false,
"onReachBottomDistance": 50,
"navigationStyle": "default",
"disableScroll": false
}

View File

@@ -0,0 +1,133 @@
<!-- pages/tixian/tixian.wxml -->
<!-- 最终版:资产卡片添加背景图,微调模糊 -->
<view class="app">
<!-- 页面背景(全局模糊降低) -->
<image class="global-bg" src="{{imgUrls.pageBg}}" mode="aspectFill" />
<!-- 资产区域 -->
<view class="assets-section">
<view class="main-card" style="background-image: url('{{imgUrls.cardBg}}'); background-size: cover;">
<!-- 总余额 -->
<view class="balance-wrap">
<text class="balance-label">可提总余额</text>
<text class="balance-value">¥{{totalAmount}}</text>
</view>
<!-- 内部分隔线 -->
<view class="inner-divider"></view>
<!-- 左右滑动提示 -->
<text class="assets-hint">← 左右滑动查看更多资产 →</text>
<!-- 资产横向滚动区 -->
<scroll-view class="assets-scroll" scroll-x="true" show-scrollbar="{{false}}" enhanced>
<view class="assets-track">
<block wx:for="{{assetList}}" wx:key="index">
<!-- 每个资产卡片加上自己的背景图 -->
<view class="asset-tile" bindtap="onSelectAsset" data-index="{{index}}" style="background-image: url('{{imgUrls.assetTileBg}}'); background-size: cover; background-position: center;">
<text class="asset-name">{{item.label}}</text>
<text class="asset-balance">¥{{item.amount}}</text>
<text class="asset-fee">费率 {{item.rate}}%</text>
</view>
</block>
<view wx:if="{{assetList.length === 0 && !isLoading}}" class="assets-empty">暂无可用资金</view>
</view>
</scroll-view>
</view>
<!-- 层次分隔线 -->
<view class="divider-line"></view>
</view>
<!-- 提现记录区 -->
<view class="history-section">
<view class="history-header">
<text class="history-title">提现记录</text>
<text class="history-settings" bindtap="onSetSkfs">收款方式</text>
</view>
<scroll-view class="history-scroll" scroll-y enable-back-to-top bindscrolltolower="onLoadMoreFromScroll">
<view wx:for="{{recordList}}" wx:key="index" class="history-item">
<view class="history-info">
<text class="history-amount">¥{{item.jine}}</text>
<text class="history-time">{{item.create}}</text>
</view>
<view class="history-detail">
<text class="history-method">{{item.fangshi == 1 ? '微信' : '支付宝'}}</text>
<text class="history-type">{{item.leixing == 1 ? '佣金' : (item.leixing == 2 ? '分红' : (item.leixing == 3 ? '组长' : (item.leixing == 4 ? '考核官' : '保证金')))}}</text>
</view>
<view class="history-status">
<view wx:if="{{item.zhuangtai == 1}}" class="status-badge status-wait" bindtap="onModifyRecord" data-record="{{item}}">{{item.statusText}} ✏修改</view>
<view wx:elif="{{item.zhuangtai == 3}}" class="status-badge status-fail">
{{item.statusText}}
<text class="fail-link" bindtap="onViewFailReason" data-record="{{item}}">详情</text>
</view>
<view wx:else class="status-badge status-done">{{item.statusText}}</view>
</view>
</view>
<view wx:if="{{loading}}" class="load-tip">加载中...</view>
<view wx:if="{{nomore && recordList.length > 0}}" class="more-tip">—— 没有更多了 ——</view>
<view wx:if="{{!nomore && recordList.length > 0}}" class="load-more-btn" bindtap="loadMoreRecords">加载更多记录</view>
</scroll-view>
</view>
<view class="safe-bottom"></view>
</view>
<!-- ========== 弹窗(完整保留,无省略) ========== -->
<!-- 提现弹窗 -->
<view wx:if="{{showTixianModal}}" class="modal-mask" bindtap="onCloseTixianModal">
<view class="modal-dialog" catchtap="stopPropagation">
<view class="modal-header">提现</view>
<view class="modal-body">
<view class="info-row"><text>项目</text><text>{{selectedAsset.label}}</text></view>
<view class="info-row"><text>可提</text><text>¥{{selectedAsset.amount}}</text></view>
<view class="info-row"><text>费率</text><text>{{currentRate}}%</text></view>
<view class="amount-row"><text>金额</text><input type="digit" placeholder="0.00" value="{{tixianAmount}}" bindinput="onAmountInput" /></view>
<view class="quick-row"><view wx:for="{{[100,200,500,1000]}}" wx:key="item" class="quick-chip" data-value="{{item}}" bindtap="onQuickAmount">¥{{item}}</view></view>
<view class="fee-row"><text>手续费 ¥{{shouxufei}}</text><text>到账 ¥{{shijidaozhang}}</text></view>
<view class="method-row"><text>收款方式 {{txfangshi == 1 ? '微信' : (txfangshi == 2 ? '支付宝' : '未设置')}}</text><text class="link-text" bindtap="onSetSkfs">更换</text></view>
</view>
<view class="modal-footer"><view class="modal-btn cancel" bindtap="onCloseTixianModal">取消</view><view class="modal-btn confirm" bindtap="onConfirmWithdraw">确认</view></view>
</view>
</view>
<!-- 设置收款方式弹窗 -->
<view wx:if="{{showSkfsModal}}" class="modal-mask" bindtap="onCloseSkfsModal">
<view class="modal-dialog" catchtap="stopPropagation">
<view class="modal-header">收款方式</view>
<view class="modal-body">
<view class="toggle-row"><view class="toggle-item {{tempTxfangshi == 1 ? 'active' : ''}}" bindtap="onSelectFangshi" data-fangshi="1">微信</view><view class="toggle-item {{tempTxfangshi == 2 ? 'active' : ''}}" bindtap="onSelectFangshi" data-fangshi="2">支付宝</view></view>
<input class="field-input" placeholder="手机号" value="{{tempTxPhone}}" bindinput="onPhoneInput" />
<view wx:if="{{tempTxfangshi == 2}}"><input class="field-input" placeholder="支付宝账号" value="{{tempTxAccount}}" bindinput="onAccountInput" /></view>
<view class="upload-wrap"><view wx:if="{{!tempTxImage}}" class="upload-trigger" bindtap="onChooseImage">+ 上传收款码</view><view wx:else class="image-preview"><image src="{{tempTxImage}}" mode="aspectFill" /><view class="image-actions"><text bindtap="onPreviewImage">预览</text><text bindtap="onDeleteImage">删除</text></view></view></view>
</view>
<view class="modal-footer"><view class="modal-btn cancel" bindtap="onCloseSkfsModal">取消</view><view class="modal-btn confirm" bindtap="onConfirmSkfs">保存</view></view>
</view>
</view>
<!-- 修改审核中记录弹窗 -->
<view wx:if="{{showModifyModal}}" class="modal-mask" bindtap="onCloseModifyModal">
<view class="modal-dialog" catchtap="stopPropagation">
<view class="modal-header">修改信息</view>
<view class="modal-body">
<view class="toggle-row"><view class="toggle-item {{modifyTxfangshi == 1 ? 'active' : ''}}" bindtap="onSelectModifyFangshi" data-fangshi="1">微信</view><view class="toggle-item {{modifyTxfangshi == 2 ? 'active' : ''}}" bindtap="onSelectModifyFangshi" data-fangshi="2">支付宝</view></view>
<input class="field-input" placeholder="电话" value="{{modifyTxPhone}}" bindinput="onModifyPhoneInput" />
<view wx:if="{{modifyTxfangshi == 2}}"><input class="field-input" placeholder="支付宝账号" value="{{modifyTxAccount}}" bindinput="onModifyAccountInput" /></view>
<view class="upload-wrap"><view wx:if="{{modifyImageUrl}}" class="current-img"><image src="{{modifyImageUrl}}" mode="aspectFill" bindtap="onPreviewModifyImage" /></view><view class="upload-trigger" bindtap="onChooseModifyImage">+ 上传新图片</view><view wx:if="{{modifyTxImage}}" class="image-preview"><image src="{{modifyTxImage}}" mode="aspectFill" /><view class="image-actions"><text bindtap="onPreviewModifyImage">预览</text><text bindtap="onDeleteModifyImage">删除</text></view></view></view>
</view>
<view class="modal-footer"><view class="modal-btn cancel" bindtap="onCloseModifyModal">取消</view><view class="modal-btn confirm" bindtap="onConfirmModify">确认</view></view>
</view>
</view>
<!-- 失败原因弹窗 -->
<view wx:if="{{showFailModal}}" class="modal-mask" bindtap="onCloseFailModal">
<view class="modal-dialog" catchtap="stopPropagation">
<view class="modal-header">失败原因</view>
<view class="modal-body">{{currentFailReason}}</view>
<view class="modal-footer"><view class="modal-btn confirm" bindtap="onCloseFailModal">知道了</view></view>
</view>
</view>
<global-notification id="global-notification" />
<popup-notice id="popupNotice" />

View File

@@ -0,0 +1,424 @@
/* pages/tixian/tixian.wxss - 终极优化版 */
page {
background-color: #f5f7fb;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
height: 100%;
}
.app {
display: flex;
flex-direction: column;
min-height: 100vh;
padding: 0 24rpx 0;
position: relative;
z-index: 1;
box-sizing: border-box;
}
/* 页面背景模糊极低,不影响阅读 */
.global-bg {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: -1;
opacity: 0.1;
object-fit: cover;
filter: blur(1rpx);
}
/* 资产区域整体与顶部保持间距 */
.assets-section {
margin-top: 24rpx;
flex-shrink: 0;
}
/* 主卡片玻璃质感 - 模糊加重避免抢眼,同时文字对比加强 */
.main-card {
background: rgba(248, 250, 252, 0.88); /* 稍微降低透明度,让背景更柔和 */
backdrop-filter: blur(28rpx); /* 增强模糊,不抢眼 */
-webkit-backdrop-filter: blur(28rpx);
border-radius: 48rpx;
padding: 30rpx 28rpx 24rpx; /* 稍微缩小高度 */
margin-bottom: 20rpx;
box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.04);
border: 1rpx solid rgba(255, 255, 255, 0.4);
background-size: cover;
}
/* 总余额 - 字体加深加粗,增加阴影提高可读性 */
.balance-wrap {
text-align: center;
margin-bottom: 20rpx; /* 减小间距,让卡片更紧凑 */
}
.balance-label {
font-size: 28rpx;
color: #0f172a; /* 更深色 */
letter-spacing: 1px;
display: block;
margin-bottom: 10rpx;
font-weight: 700; /* 加粗 */
text-shadow: 0 1rpx 2rpx rgba(255,255,255,0.8);
}
.balance-value {
font-size: 68rpx;
font-weight: 800;
color: #0f172a;
font-family: 'DIN', monospace;
letter-spacing: -1rpx;
text-shadow: 0 1rpx 2rpx rgba(255,255,255,0.6);
}
/* 内部分隔线(横杠)- 明显且保持层次 */
.inner-divider {
width: 60%;
height: 2rpx;
background: linear-gradient(90deg, transparent, #64748b, #64748b, transparent); /* 加深颜色 */
margin: 0 auto 20rpx auto;
border-radius: 2rpx;
opacity: 0.9;
}
/* 左右滑动提示 - 字体明显 */
.assets-hint {
display: block;
text-align: center;
font-size: 24rpx;
color: #334155; /* 深灰 */
margin-bottom: 14rpx;
font-weight: 600;
}
.assets-scroll {
width: 100%;
white-space: nowrap;
}
.assets-track {
display: inline-flex;
gap: 16rpx;
}
/* 资产小卡片 - 背景半透模糊,字体深色加粗 */
.asset-tile {
width: 170rpx;
background: rgba(255, 255, 255, 0.75); /* 稍微提高透明度,让模糊背景透出 */
backdrop-filter: blur(8rpx); /* 自身轻微模糊,不抢眼 */
border-radius: 28rpx;
padding: 18rpx 12rpx;
display: inline-flex;
flex-direction: column;
align-items: center;
text-align: center;
border: 1rpx solid rgba(255,255,255,0.5);
box-shadow: 0 2rpx 8rpx rgba(0,0,0,0.02);
transition: all 0.2s;
white-space: normal;
background-size: cover;
background-position: center;
}
.asset-tile:active {
background: rgba(255, 255, 255, 0.9);
transform: scale(0.98);
}
.asset-name {
font-size: 24rpx;
font-weight: 700; /* 加粗 */
color: #1e293b; /* 深色 */
margin-bottom: 10rpx;
text-shadow: 0 1rpx 1rpx rgba(255,255,255,0.5);
}
.asset-balance {
font-size: 28rpx;
font-weight: 800; /* 加粗 */
color: #2d6a4f;
font-family: monospace;
margin-bottom: 6rpx;
text-shadow: 0 1rpx 1rpx rgba(255,255,255,0.3);
}
.asset-fee {
font-size: 20rpx;
font-weight: 600; /* 加粗并加深 */
color: #475569;
text-shadow: 0 1rpx 1rpx rgba(255,255,255,0.3);
}
.assets-empty {
width: 400rpx;
text-align: center;
color: #a0abb9;
padding: 40rpx 0;
}
/* 外部层次分隔线 - 保持不变,保留分层 */
.divider-line {
height: 2rpx;
background: linear-gradient(90deg, transparent, #cbd5e1, #cbd5e1, transparent);
margin: 16rpx 0 20rpx;
width: 80%;
margin-left: auto;
margin-right: auto;
}
/* 提现记录区 - 无改动,自然贴底 */
.history-section {
flex: 1;
display: flex;
flex-direction: column;
min-height: 0;
margin-top: 0;
}
.history-header {
display: flex;
justify-content: space-between;
align-items: baseline;
padding: 0 8rpx 20rpx;
flex-shrink: 0;
}
.history-title {
font-size: 34rpx;
font-weight: 600;
color: #1e293b;
}
.history-settings {
font-size: 28rpx;
color: #3b82f6;
}
.history-scroll {
flex: 1;
width: 100%;
padding: 0 20rpx;
box-sizing: border-box;
}
.history-item {
display: flex;
align-items: center;
padding: 28rpx 0;
border-bottom: 1rpx solid rgba(0,0,0,0.05);
}
.history-info {
width: 160rpx;
}
.history-amount {
font-size: 36rpx;
font-weight: 700;
color: #1e293b;
display: block;
}
.history-time {
font-size: 22rpx;
color: #94a3b8;
}
.history-detail {
flex: 1;
padding: 0 20rpx;
}
.history-method {
font-size: 30rpx;
color: #334155;
display: block;
margin-bottom: 6rpx;
}
.history-type {
font-size: 24rpx;
color: #94a3b8;
}
.history-status {
text-align: right;
}
.status-badge {
font-size: 26rpx;
font-weight: 500;
padding: 6rpx 14rpx;
border-radius: 30rpx;
display: inline-block;
}
.status-wait {
color: #f59e0b;
background: rgba(245,158,11,0.1);
}
.status-done {
color: #10b981;
background: rgba(16,185,129,0.1);
}
.status-fail {
color: #ef4444;
background: rgba(239,68,68,0.1);
}
.fail-link {
margin-left: 8rpx;
text-decoration: underline;
}
.load-tip, .more-tip {
text-align: center;
padding: 30rpx;
font-size: 24rpx;
color: #94a3b8;
}
.load-more-btn {
margin: 16rpx 0 20rpx;
padding: 20rpx;
text-align: center;
background: rgba(255,255,255,0.7);
backdrop-filter: blur(8rpx);
border-radius: 40rpx;
font-size: 28rpx;
color: #3b82f6;
border: 1rpx solid rgba(255,255,255,0.5);
}
.load-more-btn:active {
background: rgba(255,255,255,0.9);
}
.safe-bottom {
height: 12rpx;
flex-shrink: 0;
}
/* ========== 弹窗样式(完整保留) ========== */
.modal-mask {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0,0,0,0.5);
display: flex;
align-items: center;
justify-content: center;
z-index: 1000;
}
.modal-dialog {
width: 600rpx;
background: rgba(255,255,255,0.96);
backdrop-filter: blur(20rpx);
border-radius: 48rpx;
overflow: hidden;
box-shadow: 0 20rpx 40rpx rgba(0,0,0,0.1);
border: 1rpx solid rgba(255,255,255,0.6);
}
.modal-header {
padding: 36rpx 32rpx 20rpx;
font-size: 36rpx;
font-weight: 700;
border-bottom: 1rpx solid rgba(0,0,0,0.05);
}
.modal-body {
padding: 32rpx;
}
.info-row, .amount-row, .method-row {
display: flex;
justify-content: space-between;
margin-bottom: 24rpx;
font-size: 28rpx;
}
.amount-row input {
border: 1rpx solid rgba(0,0,0,0.1);
border-radius: 28rpx;
padding: 16rpx 20rpx;
width: 260rpx;
background: rgba(255,255,255,0.9);
}
.quick-row {
display: flex;
gap: 16rpx;
margin: 24rpx 0;
}
.quick-chip {
flex: 1;
background: rgba(241,245,249,0.8);
text-align: center;
padding: 12rpx;
border-radius: 40rpx;
font-size: 28rpx;
}
.fee-row {
display: flex;
justify-content: space-between;
background: rgba(248,250,252,0.8);
padding: 20rpx;
border-radius: 28rpx;
margin: 20rpx 0;
}
.link-text {
color: #3b82f6;
}
.toggle-row {
display: flex;
gap: 20rpx;
margin-bottom: 28rpx;
}
.toggle-item {
flex: 1;
text-align: center;
padding: 20rpx;
border: 1rpx solid rgba(0,0,0,0.08);
border-radius: 30rpx;
background: rgba(255,255,255,0.8);
}
.toggle-item.active {
border-color: #3b82f6;
background: #eff6ff;
}
.field-input {
width: 100%;
border: 1rpx solid rgba(0,0,0,0.08);
border-radius: 28rpx;
padding: 20rpx;
margin-bottom: 20rpx;
box-sizing: border-box;
background: rgba(255,255,255,0.9);
}
.upload-trigger {
background: rgba(241,245,249,0.8);
border: 1rpx dashed #cbd5e1;
border-radius: 28rpx;
padding: 28rpx;
text-align: center;
}
.image-preview {
margin-top: 16rpx;
position: relative;
}
.image-preview image {
width: 100%;
height: 200rpx;
border-radius: 28rpx;
}
.image-actions {
display: flex;
justify-content: space-around;
background: rgba(0,0,0,0.6);
padding: 12rpx;
position: absolute;
bottom: 0;
left: 0;
right: 0;
color: white;
border-bottom-left-radius: 28rpx;
border-bottom-right-radius: 28rpx;
}
.current-img {
margin: 20rpx 0;
}
.current-img image {
width: 100%;
height: 140rpx;
border-radius: 24rpx;
}
.modal-footer {
display: flex;
border-top: 1rpx solid rgba(0,0,0,0.05);
}
.modal-btn {
flex: 1;
text-align: center;
padding: 28rpx;
font-size: 30rpx;
}
.modal-btn.cancel {
color: #8f9bb3;
border-right: 1rpx solid rgba(0,0,0,0.05);
}
.modal-btn.confirm {
color: #3b82f6;
}