feat: 星之界打手端UI与提现/充值/排行榜等页面同步更新

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
XingQue
2026-07-08 22:56:08 +08:00
parent 40bc391f76
commit 2ea2860791
103 changed files with 7856 additions and 6814 deletions

View File

@@ -87,7 +87,11 @@
},
{
"root": "pages/fighter-recharge",
"pages": ["fighter-recharge"]
"pages": ["fighter-recharge", "fighter-deposit"]
},
{
"root": "pages/fighter-ledger",
"pages": ["fighter-ledger"]
},
{
"root": "pages/fighter-msg",
@@ -99,7 +103,7 @@
},
{
"root": "pages/withdraw",
"pages": ["withdraw", "components/mode1/mode1", "components/mode2/mode2"]
"pages": ["withdraw", "withdraw-records", "components/mode1/mode1", "components/mode2/mode2"]
},
{
"root": "pages/invite-fighter",

View File

@@ -1,5 +1,18 @@
import { openCustomerServiceChat, resolveKefuIconUrl } from '../../utils/kefu-nav.js';
const CS_HOUR_START = 8;
const CS_HOUR_END = 23;
function getCsOnlineStatus() {
const hour = new Date().getHours();
const online = hour >= CS_HOUR_START && hour < CS_HOUR_END;
return {
csOnline: online,
csHoursText: '8:00-23:00',
csStatusText: online ? '在线' : '在线时间',
};
}
Component({
properties: {
bottom: { type: String, value: '200rpx' },
@@ -11,6 +24,9 @@ Component({
csUnread: 0,
floatY: 520,
iconUrl: '',
csOnline: false,
csHoursText: '8:00-23:00',
csStatusText: '在线时间',
},
lifetimes: {
@@ -27,6 +43,7 @@ Component({
app.on('configApplied', this._configHandler);
}
this.syncCsUnread();
this._syncOnlineStatus();
},
detached() {
const app = getApp();
@@ -47,10 +64,14 @@ Component({
this._syncIcon();
this._syncFromGlobal();
this.syncCsUnread();
this._syncOnlineStatus();
},
},
methods: {
_syncOnlineStatus() {
this.setData(getCsOnlineStatus());
},
_syncIcon() {
const url = resolveKefuIconUrl(getApp());
if (url && url !== this.data.iconUrl) {

View File

@@ -15,7 +15,8 @@
<image class="kefu-float-icon-img" src="{{iconUrl}}" mode="aspectFit" binderror="onIconError"/>
<view class="kefu-text-col">
<text class="kefu-float-text">联系客服</text>
<text class="kefu-float-sub" wx:if="{{csUnread > 0}}">有新消息</text>
<text class="kefu-float-sub kefu-float-sub--warn" wx:if="{{csUnread > 0}}">有新消息</text>
<text class="kefu-float-sub {{csOnline ? 'kefu-float-sub--online' : ''}}" wx:else>{{csStatusText}} {{csHoursText}}</text>
</view>
</view>
<view class="kefu-float-close" catchtap="onHideTap">

View File

@@ -31,27 +31,34 @@
.kefu-float--full {
display: flex;
align-items: stretch;
background: #fff;
border-radius: 16rpx;
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.1);
border: 1rpx solid rgba(124, 58, 237, 0.18);
background: linear-gradient(135deg, #07c160 0%, #06ad56 100%);
border-radius: 999rpx;
box-shadow: 0 8rpx 28rpx rgba(7, 193, 96, 0.45);
border: 2rpx solid rgba(255, 255, 255, 0.85);
overflow: visible;
animation: kefu-pulse 2.4s ease-in-out infinite;
}
@keyframes kefu-pulse {
0%, 100% { box-shadow: 0 8rpx 28rpx rgba(7, 193, 96, 0.45); }
50% { box-shadow: 0 8rpx 36rpx rgba(7, 193, 96, 0.65), 0 0 0 8rpx rgba(7, 193, 96, 0.12); }
}
.kefu-unread-badge {
position: absolute;
top: -10rpx;
right: -6rpx;
min-width: 32rpx;
height: 32rpx;
line-height: 32rpx;
padding: 0 6rpx;
min-width: 36rpx;
height: 36rpx;
line-height: 36rpx;
padding: 0 8rpx;
background: #fa5151;
color: #fff;
font-size: 18rpx;
font-size: 20rpx;
font-weight: 700;
text-align: center;
border-radius: 16rpx;
border: 2rpx solid #fff;
border-radius: 18rpx;
border: 3rpx solid #fff;
z-index: 2;
}
@@ -63,7 +70,7 @@
.kefu-float-main {
display: flex;
align-items: center;
padding: 14rpx 16rpx;
padding: 18rpx 24rpx;
flex: 1;
}
@@ -72,11 +79,13 @@
}
.kefu-float-icon-img {
width: 36rpx;
height: 36rpx;
margin-right: 10rpx;
width: 44rpx;
height: 44rpx;
margin-right: 12rpx;
flex-shrink: 0;
border-radius: 8rpx;
border-radius: 50%;
background: rgba(255, 255, 255, 0.95);
padding: 4rpx;
}
.kefu-text-col {
@@ -86,32 +95,42 @@
}
.kefu-float-text {
font-size: 24rpx;
color: #333;
font-weight: 600;
font-size: 28rpx;
color: #fff;
font-weight: 700;
white-space: nowrap;
}
.kefu-float-sub {
font-size: 18rpx;
color: #fa5151;
font-size: 20rpx;
color: rgba(255, 255, 255, 0.92);
margin-top: 2rpx;
font-weight: 600;
}
.kefu-float-sub--online {
color: #e8ffe8;
}
.kefu-float-sub--warn {
color: #fff3e0;
}
.kefu-float-close {
width: 48rpx;
width: 52rpx;
display: flex;
align-items: center;
justify-content: center;
background: #f5f3ff;
color: #999;
font-size: 32rpx;
background: rgba(0, 0, 0, 0.12);
color: rgba(255, 255, 255, 0.9);
font-size: 34rpx;
line-height: 1;
border-left: 1rpx solid rgba(124, 58, 237, 0.1);
border-left: 1rpx solid rgba(255, 255, 255, 0.25);
border-radius: 0 999rpx 999rpx 0;
}
.kefu-float-close:active {
background: #ede9fe;
background: rgba(0, 0, 0, 0.2);
}
.kefu-permanent-row {
@@ -133,7 +152,7 @@
.kefu-permanent-label {
font-size: 20rpx;
color: #aaa;
color: #888;
}
.kefu-wrap--mini {
@@ -141,16 +160,17 @@
}
.kefu-float--mini {
width: 72rpx;
height: 72rpx;
width: 96rpx;
height: 96rpx;
padding: 0;
border-radius: 50%;
background: #fff;
box-shadow: 0 4rpx 14rpx rgba(0, 0, 0, 0.1);
border: 1rpx solid rgba(124, 58, 237, 0.2);
background: linear-gradient(135deg, #07c160 0%, #06ad56 100%);
box-shadow: 0 8rpx 24rpx rgba(7, 193, 96, 0.45);
border: 3rpx solid #fff;
display: flex;
align-items: center;
justify-content: center;
animation: kefu-pulse 2.4s ease-in-out infinite;
}
.kefu-float--mini:active {
@@ -158,7 +178,9 @@
}
.kefu-float-mini-icon-img {
width: 40rpx;
height: 40rpx;
border-radius: 8rpx;
width: 48rpx;
height: 48rpx;
border-radius: 50%;
background: rgba(255, 255, 255, 0.95);
padding: 4rpx;
}

View File

@@ -3,9 +3,9 @@
* 星阙 = xq星之界 = xzj与 club 表 club_id 一致。
* 不要依赖后端猜测:前端必须明确所属 club。
*/
export const CLUB_ID = 'xq';
export const CLUB_ID = 'xzj';
/** 与 club 表 wx_appid 一致,登录时可传给后端反查 club */
export const WX_APP_ID = 'wx0e4be86faac4a8d1';
export const WX_APP_ID = 'wxdefa454152e78a03';
export const CLUB_NAME = '星电竞';
export const CLUB_NAME = '星之界电竞';

View File

@@ -443,6 +443,11 @@ Page({
if (res.data.code === 200 || res.data.code === 0) {
const newList = res.data.data.list || [];
const hasMore = res.data.data.has_more || false;
const serverClumber = res.data.data.clumber;
if (Array.isArray(serverClumber) && serverClumber.length) {
app.globalData.clumber = serverClumber;
this.setData({ huiyuanList: serverClumber });
}
// 🆕 处理每条订单,增加 hasRequiredMember 字段
const processedList = newList.map(item => this.processDingdanItem(item));
@@ -506,9 +511,13 @@ Page({
}
const zhidingNicheng = item.zhiding_nicheng || '';
// 订单要求指定会员时,核对用户是否持有该会员类型
// 订单要求指定会员时,核对用户是否持有该会员类型(优先后端字段)
let hasRequiredMember = true;
if (item.yaoqiuleixing == 1 && item.huiyuan_id) {
if (item.hasRequiredMember !== undefined) {
hasRequiredMember = !!item.hasRequiredMember;
} else if (item.has_required_member !== undefined) {
hasRequiredMember = !!item.has_required_member;
} else if (item.yaoqiuleixing == 1 && item.huiyuan_id) {
hasRequiredMember = userHasHuiyuan(this.data.huiyuanList, item.huiyuan_id);
}
@@ -549,13 +558,16 @@ Page({
switch (failureType) {
case 'huiyuan':
params = { needScroll: '0', scrollTo: 'member' };
url = '/pages/fighter-recharge/fighter-recharge';
params = { scrollTo: 'member' };
break;
case 'yajin':
params = { needScroll: '1', scrollTo: 'bottom', requiredYajin: requiredYajin };
url = '/pages/fighter-recharge/fighter-deposit';
params = { requiredYajin: requiredYajin };
break;
case 'jifen':
params = { needScroll: '1', scrollTo: 'bottom' };
url = '/pages/fighter-recharge/fighter-recharge';
params = { scrollTo: 'jifen' };
break;
}

View File

@@ -1,10 +1,11 @@
{
"navigationBarTitleText": "抢单大厅",
"navigationBarBackgroundColor": "#0b0f1a",
"navigationBarTextStyle": "white",
"navigationBarTitleText": "抢单列表",
"navigationBarBackgroundColor": "#f7dc51",
"backgroundColorTop": "#f7dc51",
"navigationBarTextStyle": "black",
"enablePullDownRefresh": false,
"backgroundTextStyle": "dark",
"backgroundColor": "#0b0f1a",
"backgroundColor": "#fff8e1",
"usingComponents": {
"chenghao-tag": "/components/chenghao-tag/chenghao-tag",
"global-notification": "/components/global-notification/global-notification",

View File

@@ -18,7 +18,7 @@
refresher-default-style="black"
refresher-background="#0b0f1a"
refresher-background="#fff8e1"
refresher-triggered="{{scrollViewRefreshing}}"
@@ -40,7 +40,7 @@
<!-- 公告置顶 -->
<view class="xym-gonggao-bar" wx:if="{{gonggao}}">
<image class="xym-gonggao-ico" src="/images/notice.png" mode="aspectFit"/>
<image class="xym-gonggao-ico" src="https://bintao.xmxym88.com/xcx/bintao/38.png" mode="aspectFit"/>
<text class="xym-gonggao-txt">{{gonggao}}</text>
</view>
@@ -82,7 +82,7 @@
indicator-color="rgba(255,255,255,0.6)"
indicator-active-color="#00c8ff"
indicator-active-color="#ffd061"
autoplay="{{lunboList.length > 1}}"
@@ -110,7 +110,7 @@
<!-- 商品类型选择 -->
<view class="leixing-quyu">
<view class="leixing-quyu dingdanxiang1 filter-card mx20">
<scroll-view class="leixing-scroll" scroll-x enhanced show-scrollbar="{{false}}">

View File

@@ -1,9 +1,9 @@
/* pages/qiangdan/qiangdan.wxss - 机甲风格抢单页 */
/* pages/qiangdan/qiangdan.wxss - 逍遥梦抢单页 */
@import '../../styles/dashou-xym-theme.wxss';
@import '../../styles/dashou-xym-order-card.wxss';
page {
background-color: #0b0f1a;
background-color: #f7dc51;
}
.qiangdan-page {
@@ -33,7 +33,7 @@ page {
/* ====== 1. 商品类型区域 ====== */
.leixing-quyu {
padding: 24rpx 0 16rpx;
padding: 30rpx 0 20rpx;
background: rgba(18, 22, 38, 0.9);
backdrop-filter: blur(20rpx);
border-bottom: 1rpx solid rgba(255, 255, 255, 0.05);
@@ -46,26 +46,26 @@ page {
.leixing-scroll {
width: 100%;
white-space: nowrap;
height: 158rpx;
height: 180rpx;
}
.leixing-container {
display: inline-flex;
padding: 0 30rpx;
gap: 16rpx;
gap: 20rpx;
}
.leixing-item {
display: inline-flex;
flex-direction: column;
align-items: center;
width: 132rpx;
width: 160rpx;
position: relative;
transition: all 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
}
.leixing-active {
transform: translateY(-6rpx);
transform: translateY(-8rpx);
}
.guangyun-effect {
@@ -86,9 +86,9 @@ page {
}
.leixing-tupian {
width: 100rpx;
height: 100rpx;
border-radius: 28rpx;
width: 120rpx;
height: 120rpx;
border-radius: 32rpx;
z-index: 1;
box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.6);
transition: all 0.3s ease;
@@ -101,8 +101,8 @@ page {
}
.leixing-jieshao {
margin-top: 12rpx;
font-size: 22rpx;
margin-top: 16rpx;
font-size: 24rpx;
color: #b0c0e0;
max-width: 100%;
overflow: hidden;
@@ -771,7 +771,7 @@ page {
max-width: 50%;
}
/* 被指定订单(功能样式,不影响订单卡片 UI */
/* 被指定订单(星阙功能保留,不影响星之界卡片 UI */
.my-zhiding-banner {
margin: 16rpx 24rpx 0;
padding: 22rpx;

View File

@@ -4,7 +4,7 @@
"chenghao-tag": "/components/chenghao-tag/chenghao-tag"
},
"backgroundTextStyle": "dark",
"navigationBarBackgroundColor": "#f5f3ff",
"navigationBarBackgroundColor": "#f7dc51",
"navigationBarTitleText": "常规发单",
"navigationBarTextStyle": "black",
"backgroundColor": "#f5f5f5",

View File

@@ -290,7 +290,7 @@ page {
.filter-switch.active {
background: linear-gradient(180deg, #fae04d, #ffc0a3);
color: #6d28d9;
color: #492f00;
}
.link-list {
@@ -324,7 +324,7 @@ page {
.copy-link-btn {
padding: 8rpx 20rpx;
background: linear-gradient(180deg, #fae04d, #ffc0a3);
color: #6d28d9;
color: #492f00;
border-radius: 15rpx;
font-size: 22rpx;
}
@@ -339,7 +339,7 @@ page {
padding: 15rpx 40rpx;
background: linear-gradient(180deg, #fae04d, #ffc0a3);
border-radius: 30rpx;
color: #6d28d9;
color: #492f00;
font-size: 26rpx;
}
@@ -374,7 +374,7 @@ page {
.copy-modal-grid-btn,
.edit-modal-grid-btn {
background: linear-gradient(180deg, #fae04d, #ffc0a3);
color: #6d28d9;
color: #492f00;
}
.delete-modal-grid-btn {
@@ -485,7 +485,7 @@ page {
.confirm-add-grid-btn {
background: linear-gradient(180deg, #fae04d, #ffc0a3);
color: #6d28d9;
color: #492f00;
}
.confirm-content {
@@ -539,7 +539,7 @@ page {
.confirm-new-link-grid-btn {
background: linear-gradient(180deg, #fae04d, #ffc0a3);
color: #6d28d9;
color: #492f00;
}
.loading-mask {
@@ -569,7 +569,7 @@ page {
width: 90rpx;
height: 90rpx;
border: 8rpx solid #eee;
border-top: 8rpx solid #9333ea;
border-top: 8rpx solid #ffd061;
border-radius: 50%;
animation: spin 1.2s linear infinite;
margin-bottom: 35rpx;

View File

@@ -0,0 +1,139 @@
import request from '../../utils/request.js';
import { getOrderStatusText } from '../../utils/api-helper.js';
const PAGE_SIZE = 15;
const TYPE_CONFIG = {
commission: { title: '佣金记录', statuses: [3, 8] },
settle: { title: '结算记录', statuses: [3] },
withdraw: { title: '提现记录', api: 'withdraw' },
deduct: { title: '扣款记录', api: 'deduct' },
};
Page({
data: {
pageTitle: '交易明细',
type: 'commission',
statusBar: 20,
list: [],
page: 1,
hasMore: true,
loading: false,
refreshing: false,
},
onLoad(options) {
const sys = wx.getSystemInfoSync();
const type = (options.type || 'commission').trim();
const cfg = TYPE_CONFIG[type] || TYPE_CONFIG.commission;
this.setData({
type,
pageTitle: cfg.title,
statusBar: sys.statusBarHeight || 20,
});
this.loadList(true);
},
goBack() {
wx.navigateBack({ fail: () => wx.switchTab({ url: '/pages/fighter/fighter' }) });
},
onRefresh() {
this.setData({ refreshing: true });
this.loadList(true).finally(() => this.setData({ refreshing: false }));
},
onLoadMore() {
if (this.data.hasMore && !this.data.loading) {
this.loadList(false);
}
},
async loadList(refresh) {
const { type, loading } = this.data;
if (loading) return;
const page = refresh ? 1 : this.data.page;
this.setData({ loading: true });
try {
let rows = [];
let hasMore = false;
if (type === 'withdraw') {
const res = await request({
url: '/yonghu/tixianjiluhq',
method: 'POST',
data: { page, limit: PAGE_SIZE },
});
const body = res?.data;
if (body && (body.code === 200 || body.code === 0)) {
const raw = body.data?.list || [];
rows = raw.map((item, idx) => ({
id: item.id || item.jilu_id || `${page}-${idx}`,
title: item.beizhu || item.status_text || item.zhuangtai_text || '提现',
time: item.creat_time || item.create_time || item.tijiao_shijian || '',
amount: `${item.jine || item.amount || item.tixian_jine || '0.00'}`,
minus: true,
}));
hasMore = raw.length >= PAGE_SIZE;
}
} else if (type === 'deduct') {
const res = await request({
url: '/yonghu/dsfklbhq',
method: 'POST',
data: { page, page_size: PAGE_SIZE, zhuangtai: 0 },
});
const body = res?.data;
if (body && (body.code === 200 || body.code === 0)) {
const raw = body.data?.list || [];
rows = raw.map((item, idx) => ({
id: item.fadan_id || item.id || `${page}-${idx}`,
title: item.yuanyin || item.beizhu || item.fakuan_yuanyin || '扣款',
time: item.creat_time || item.create_time || '',
amount: `${item.jine || item.fakuan_jine || item.fakuanjine || '0.00'}`,
minus: true,
}));
hasMore = raw.length >= PAGE_SIZE;
}
} else {
const cfg = TYPE_CONFIG[type] || TYPE_CONFIG.commission;
const res = await request({
url: '/dingdan/dshqdingdan',
method: 'POST',
data: {
zhuangtai_list: cfg.statuses,
page,
page_size: PAGE_SIZE,
},
});
const body = res?.data;
if (body && (body.code === 200 || body.code === 0)) {
const raw = body.data?.list || [];
rows = raw.map((item) => {
const amt = item.jine || item.dashou_fencheng || '0.00';
const brief = (item.jieshao || '').trim();
const title = brief
? (brief.length > 18 ? `${brief.slice(0, 18)}` : brief)
: `订单 ${item.dingdan_id || ''}`;
return {
id: item.dingdan_id,
title,
time: item.wancheng_shijian || item.jiesuan_shijian || item.creat_time || getOrderStatusText(item.zhuangtai),
amount: `${amt}`,
minus: false,
};
});
hasMore = body.data?.has_more ?? raw.length >= PAGE_SIZE;
}
}
const list = refresh ? rows : [...this.data.list, ...rows];
this.setData({
list,
page: refresh ? 2 : page + 1,
hasMore,
});
} catch (e) {
console.error('ledger load fail', e);
} finally {
this.setData({ loading: false });
}
},
});

View File

@@ -0,0 +1,4 @@
{
"navigationStyle": "custom",
"usingComponents": {}
}

View File

@@ -0,0 +1,20 @@
<view class="ledger-page safe-area">
<view class="status-bar" style="height:{{statusBar}}px"></view>
<view class="nav-bar flexb">
<text class="back" bindtap="goBack"></text>
<text class="nav-title">{{pageTitle}}</text>
<text class="back placeholder"></text>
</view>
<scroll-view scroll-y class="ledger-scroll" refresher-enabled refresher-triggered="{{refreshing}}" bindrefresherrefresh="onRefresh" bindscrolltolower="onLoadMore">
<view wx:if="{{loading && list.length === 0}}" class="empty-box">加载中...</view>
<view wx:elif="{{list.length === 0}}" class="empty-box">暂无记录</view>
<view wx:for="{{list}}" wx:key="id" class="list-item flexb">
<view class="item-main">
<view class="row-t">{{item.title}}</view>
<view class="row-d">{{item.time}}</view>
</view>
<text class="row-r {{item.minus ? 'minus' : ''}}">{{item.amount}}</text>
</view>
<view wx:if="{{list.length > 0 && !hasMore}}" class="load-tip">— 已加载全部 —</view>
</scroll-view>
</view>

View File

@@ -0,0 +1,75 @@
@import '../../styles/xym-layout.wxss';
.ledger-page {
min-height: 100vh;
background: #f5f5f5;
display: flex;
flex-direction: column;
}
.nav-bar {
padding: 0 24rpx 16rpx;
}
.back {
width: 60rpx;
font-size: 48rpx;
color: #333;
line-height: 1;
}
.back.placeholder {
visibility: hidden;
}
.nav-title {
font-size: 34rpx;
font-weight: 700;
color: #222;
}
.ledger-scroll {
flex: 1;
height: 0;
padding: 0 24rpx;
box-sizing: border-box;
}
.list-item {
background: #fff;
border-radius: 16rpx;
padding: 24rpx;
margin-bottom: 16rpx;
}
.row-t {
font-size: 28rpx;
color: #222;
font-weight: 600;
}
.row-d {
font-size: 24rpx;
color: #999;
margin-top: 8rpx;
}
.row-r {
font-size: 30rpx;
font-weight: 700;
color: #492f00;
flex-shrink: 0;
margin-left: 16rpx;
}
.row-r.minus {
color: #ff4c45;
}
.empty-box,
.load-tip {
text-align: center;
color: #999;
font-size: 26rpx;
padding: 80rpx 0;
}

View File

@@ -62,6 +62,17 @@ Page(createPage({
onShow() {
this.registerNotificationComponent();
const app = getApp();
const filterKey = app.globalData._fighterOrdersStatusKey;
if (filterKey) {
app.globalData._fighterOrdersStatusKey = null;
if (this.data.statusList.some((s) => s.key === filterKey)) {
this.setData({ currentStatusKey: filterKey });
}
if (this.data.xuanzhongLeixingId) {
this.loadCurrentStatusOrders(true);
}
}
if (wx.getStorageSync('uid')) {
reconnectForRole('dashou');
if (app.startImWhenReady) app.startImWhenReady();

View File

@@ -346,4 +346,5 @@ page {
color: #999;
}
@import '../../styles/dashou-xym-orders-theme.wxss';
@import '../../styles/dashou-xym-orders-theme.wxss';
@import '../../styles/dashou-xym-orders-page.wxss';

View File

@@ -2,10 +2,10 @@
"usingComponents": {
"global-notification": "/components/global-notification/global-notification"
},
"navigationBarTitleText": "排行榜",
"navigationBarBackgroundColor": "#0d1117",
"navigationBarTextStyle": "white",
"navigationBarTitleText": "排行榜",
"navigationBarBackgroundColor": "#FFE566",
"navigationBarTextStyle": "black",
"enablePullDownRefresh": true,
"backgroundColor": "#0d1117",
"backgroundTextStyle": "light"
"backgroundColor": "#FFE566",
"backgroundTextStyle": "dark"
}

View File

@@ -1,35 +1,36 @@
<view class="rank-page">
<image class="page-bg" src="{{imgUrls.pageBg}}" mode="aspectFill" />
<view class="top-bar">
<view class="top-row">
<text class="page-title">{{roleMeta.title}}</text>
<view class="refresh-wrap" bindtap="onRefreshTap">
<image class="refresh-ico" src="{{imgUrls.refreshIcon}}" mode="aspectFit" />
<!-- 顶区:黄底 + 白 Tab + 时间筛选 -->
<view class="header-zone">
<view class="role-tabs">
<view
wx:for="{{roleList}}" wx:key="key"
class="role-tab {{currentRole === item.key ? 'active' : ''}}"
data-role="{{item.key}}" bindtap="onRoleTap"
>
<text class="role-tab-text">{{item.label}}</text>
<view class="role-tab-line" wx:if="{{currentRole === item.key}}"></view>
</view>
</view>
<scroll-view scroll-x class="role-scroll" enhanced show-scrollbar="{{false}}">
<view class="role-line">
<scroll-view scroll-x class="date-scroll" enhanced show-scrollbar="{{false}}">
<view class="date-line">
<view
wx:for="{{roleList}}" wx:key="key"
class="role-chip {{currentRole === item.key ? 'on' : ''}}"
data-role="{{item.key}}" bindtap="onRoleTap"
wx:for="{{dateList}}" wx:key="key"
class="date-tab {{currentDate === item.key ? 'active' : ''}}"
data-date="{{item.key}}" bindtap="onDateTap"
>{{item.label}}</view>
</view>
</scroll-view>
<view class="date-grid">
<view
wx:for="{{dateList}}" wx:key="key"
class="date-chip {{currentDate === item.key ? 'on' : ''}}"
data-date="{{item.key}}" bindtap="onDateTap"
>{{item.label}}</view>
</view>
<text class="sort-tip">{{currentDate}} · 按{{sortLabel}} · TOP50</text>
<view class="scope-row">
<view class="scope-chip {{fanwei === 'jituan' ? 'on' : ''}}" data-fanwei="jituan" bindtap="onScopeTap">集团总榜</view>
<view class="scope-chip {{fanwei === 'club' ? 'on' : ''}}" data-fanwei="club" bindtap="onScopeTap">本俱乐部榜</view>
<!-- 临时隐藏集团总榜,恢复时取消 wx:if 注释 -->
<view wx:if="{{showJituanScope}}" class="scope-tab {{fanwei === 'jituan' ? 'active' : ''}}" data-fanwei="jituan" bindtap="onScopeTap">集团总榜</view>
<view class="scope-tab {{fanwei === 'club' ? 'active' : ''}}" data-fanwei="club" bindtap="onScopeTap">本俱乐部榜</view>
<view class="refresh-btn" bindtap="onRefreshTap">
<image class="refresh-ico" src="{{imgUrls.refreshIcon}}" mode="aspectFit" />
</view>
</view>
<text class="sort-tip">{{currentDate}} · 按{{sortLabel}} · TOP50</text>
<view class="reward-banner" wx:if="{{rewardInfo && rewardInfo.scheme_enabled}}" bindtap="onShowRules">
<view class="reward-banner-main">
@@ -54,95 +55,71 @@
</view>
<scroll-view wx:else scroll-y class="body-scroll" enhanced show-scrollbar="{{false}}">
<!-- 前三名领奖台 -->
<view class="podium-zone" wx:if="{{topThree.length > 0}}">
<view class="podium-row">
<!-- 前三名 · 纯 CSS 领奖台 -->
<view class="podium-panel" wx:if="{{topThree.length > 0}}">
<view class="podium-cols">
<!-- 榜二 -->
<view class="p-col p-second" wx:if="{{topThree[1]}}">
<view class="p-badge badge-silver"><text>2</text></view>
<view class="p-avatar-wrap wrap-silver">
<view class="podium-col col-2" wx:if="{{topThree[1]}}">
<view class="crown crown-silver">👑</view>
<view class="avatar-ring ring-silver">
<image class="p-avatar" src="{{topThree[1].avatar || defaultAvatar}}" mode="aspectFill" data-zone="top" data-index="1" binderror="onAvatarError" />
</view>
<text class="p-name">{{topThree[1].nicheng}}</text>
<text class="p-uid">ID {{topThree[1].uid}}</text>
<view class="p-amount">
<text class="p-money">{{topThree[1].mainPrefix}}{{topThree[1].mainValue}}</text>
<text class="p-label">{{topThree[1].mainLabel}}</text>
<text class="p-reward" wx:if="{{topThree[1].rewardAmount > 0}}">奖 ¥{{topThree[1].rewardAmount}}</text>
</view>
<text class="p-label">{{topThree[1].mainLabel}}</text>
<text class="p-amount">{{topThree[1].mainPrefix}}{{topThree[1].mainValue}}</text>
<view class="p-metrics">
<text class="p-metric" wx:for="{{topThree[1].metrics}}" wx:key="label" wx:for-item="m">{{m.label}} {{m.value}}</text>
</view>
<view class="p-pedestal pedestal-silver"></view>
<text class="p-reward" wx:if="{{topThree[1].rewardAmount > 0}}">奖 ¥{{topThree[1].rewardAmount}}</text>
<view class="pedestal pedestal-2"></view>
</view>
<!-- 榜一 -->
<view class="p-col p-first" wx:if="{{topThree[0]}}">
<view class="p-badge badge-first"><text>1</text></view>
<view class="p-avatar-wrap wrap-first">
<view class="podium-col col-1" wx:if="{{topThree[0]}}">
<view class="crown crown-gold">👑</view>
<view class="avatar-ring ring-gold">
<image class="p-avatar p-avatar-lg" src="{{topThree[0].avatar || defaultAvatar}}" mode="aspectFill" data-zone="top" data-index="0" binderror="onAvatarError" />
</view>
<text class="p-name p-name-first">{{topThree[0].nicheng}}</text>
<text class="p-uid">ID {{topThree[0].uid}}</text>
<view class="p-amount">
<text class="p-money p-money-first">{{topThree[0].mainPrefix}}{{topThree[0].mainValue}}</text>
<text class="p-label">{{topThree[0].mainLabel}}</text>
<text class="p-reward" wx:if="{{topThree[0].rewardAmount > 0}}">奖 ¥{{topThree[0].rewardAmount}}</text>
</view>
<text class="p-name p-name-lg">{{topThree[0].nicheng}}</text>
<text class="p-label">{{topThree[0].mainLabel}}</text>
<text class="p-amount p-amount-lg">{{topThree[0].mainPrefix}}{{topThree[0].mainValue}}</text>
<view class="p-metrics">
<text class="p-metric" wx:for="{{topThree[0].metrics}}" wx:key="label" wx:for-item="m">{{m.label}} {{m.value}}</text>
</view>
<view class="p-pedestal pedestal-first"></view>
<text class="p-reward" wx:if="{{topThree[0].rewardAmount > 0}}">奖 ¥{{topThree[0].rewardAmount}}</text>
<view class="pedestal pedestal-1"></view>
</view>
<!-- 榜三 -->
<view class="p-col p-third" wx:if="{{topThree[2]}}">
<view class="p-badge badge-bronze"><text>3</text></view>
<view class="p-avatar-wrap wrap-bronze">
<view class="podium-col col-3" wx:if="{{topThree[2]}}">
<view class="crown crown-bronze">👑</view>
<view class="avatar-ring ring-bronze">
<image class="p-avatar" src="{{topThree[2].avatar || defaultAvatar}}" mode="aspectFill" data-zone="top" data-index="2" binderror="onAvatarError" />
</view>
<text class="p-name">{{topThree[2].nicheng}}</text>
<text class="p-uid">ID {{topThree[2].uid}}</text>
<view class="p-amount">
<text class="p-money">{{topThree[2].mainPrefix}}{{topThree[2].mainValue}}</text>
<text class="p-label">{{topThree[2].mainLabel}}</text>
<text class="p-reward" wx:if="{{topThree[2].rewardAmount > 0}}">奖 ¥{{topThree[2].rewardAmount}}</text>
</view>
<text class="p-label">{{topThree[2].mainLabel}}</text>
<text class="p-amount">{{topThree[2].mainPrefix}}{{topThree[2].mainValue}}</text>
<view class="p-metrics">
<text class="p-metric" wx:for="{{topThree[2].metrics}}" wx:key="label" wx:for-item="m">{{m.label}} {{m.value}}</text>
</view>
<view class="p-pedestal pedestal-bronze"></view>
<text class="p-reward" wx:if="{{topThree[2].rewardAmount > 0}}">奖 ¥{{topThree[2].rewardAmount}}</text>
<view class="pedestal pedestal-3"></view>
</view>
</view>
</view>
<!-- 4-50 名 -->
<view class="list-wrap" wx:if="{{restList.length > 0}}">
<view class="list-title-row">
<text class="list-title">完整榜单</text>
<text class="list-range">第 4 - {{rankList.length}} 名</text>
</view>
<view class="list-card" wx:for="{{restList}}" wx:key="mingci">
<image class="list-card-bg" src="{{imgUrls.cardBg}}" mode="aspectFill" />
<view class="list-card-body">
<view class="lc-rank"><text>{{item.mingci}}</text></view>
<image class="lc-avatar" src="{{item.avatar || defaultAvatar}}" mode="aspectFill" data-zone="rest" data-index="{{index}}" binderror="onAvatarError" />
<view class="lc-info">
<text class="lc-name">{{item.nicheng}}</text>
<text class="lc-uid">ID {{item.uid}}<text wx:if="{{item.clubName && fanwei === 'jituan'}}"> · {{item.clubName}}</text></text>
<view class="lc-tags">
<text class="lc-tag" wx:for="{{item.metrics}}" wx:key="label" wx:for-item="m">{{m.label}} {{m.value}}</text>
</view>
</view>
<view class="lc-score">
<text class="lc-money">{{item.mainPrefix}}{{item.mainValue}}</text>
<text class="lc-label">{{item.mainLabel}}</text>
<text class="lc-reward" wx:if="{{item.rewardAmount > 0}}">奖¥{{item.rewardAmount}}</text>
<!-- 4 名以后列表 -->
<view class="list-panel" wx:if="{{restList.length > 0}}">
<view class="list-row" wx:for="{{restList}}" wx:key="mingci">
<text class="li-rank">{{item.mingci}}</text>
<image class="li-avatar" src="{{item.avatar || defaultAvatar}}" mode="aspectFill" data-zone="rest" data-index="{{index}}" binderror="onAvatarError" />
<text class="li-name">{{item.nicheng}}</text>
<view class="li-right">
<text class="li-amount">{{item.mainPrefix}}{{item.mainValue}}</text>
<text class="li-label">{{item.mainLabel}}</text>
<view class="li-tags">
<text class="li-tag" wx:for="{{item.metrics}}" wx:key="label" wx:for-item="m">{{m.label}} {{m.value}}</text>
</view>
<text class="li-reward" wx:if="{{item.rewardAmount > 0}}">奖¥{{item.rewardAmount}}</text>
</view>
</view>
</view>

View File

@@ -1,145 +1,147 @@
page {
background: #0d1117;
color: #fff;
font-family: -apple-system, BlinkMacSystemFont, 'PingFang SC', sans-serif;
background: #ffe566;
color: #333;
font-family: -apple-system, BlinkMacSystemFont, 'PingFang SC', 'Helvetica Neue', sans-serif;
}
/* 主题色 */
/* 选中/金额: #6BA3F7 浅蓝: #8EB8FF 银: #A8B4C4 铜: #C4A882 */
.rank-page {
min-height: 100vh;
position: relative;
background: linear-gradient(180deg, #ffe566 0%, #ffe566 420rpx, #fff8dc 520rpx, #ffffff 620rpx);
}
.page-bg {
position: fixed;
top: 0; left: 0;
width: 100%; height: 100%;
z-index: 0;
}
/* ========== 顶栏 ========== */
.top-bar {
/* ========== 顶区 ========== */
.header-zone {
position: relative;
z-index: 10;
padding: 16rpx 28rpx 20rpx;
padding-bottom: 8rpx;
}
.top-row {
.role-tabs {
display: flex;
align-items: stretch;
background: #ffffff;
margin: 0 0 0;
padding: 0 8rpx;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.04);
}
.role-tab {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 24rpx 0 18rpx;
position: relative;
}
.role-tab-text {
font-size: 28rpx;
color: #666666;
line-height: 1.2;
}
.role-tab.active .role-tab-text {
color: #1a1a1a;
font-weight: 700;
font-size: 30rpx;
}
.role-tab-line {
position: absolute;
bottom: 8rpx;
left: 50%;
transform: translateX(-50%);
width: 48rpx;
height: 6rpx;
border-radius: 6rpx;
background: #3d2914;
}
.date-scroll {
width: 100%;
white-space: nowrap;
padding: 20rpx 0 8rpx;
}
.date-line {
display: inline-flex;
padding: 0 20rpx;
gap: 8rpx;
}
.date-tab {
display: inline-block;
padding: 10rpx 22rpx;
font-size: 26rpx;
color: rgba(0, 0, 0, 0.45);
border-radius: 8rpx;
}
.date-tab.active {
color: #1a1a1a;
font-weight: 700;
position: relative;
}
.date-tab.active::after {
content: '';
position: absolute;
left: 50%;
bottom: 0;
transform: translateX(-50%);
width: 36rpx;
height: 4rpx;
border-radius: 4rpx;
background: #3d2914;
}
.scope-row {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 20rpx;
gap: 12rpx;
padding: 8rpx 24rpx 12rpx;
}
.page-title {
font-size: 38rpx;
font-weight: 700;
color: #fff;
.scope-tab {
padding: 8rpx 20rpx;
border-radius: 999rpx;
font-size: 22rpx;
color: rgba(0, 0, 0, 0.55);
background: rgba(255, 255, 255, 0.55);
border: 1rpx solid rgba(0, 0, 0, 0.06);
}
.refresh-wrap {
width: 60rpx; height: 60rpx;
.scope-tab.active {
color: #1a1a1a;
font-weight: 600;
background: #ffffff;
border-color: rgba(0, 0, 0, 0.12);
}
.refresh-btn {
margin-left: auto;
width: 56rpx;
height: 56rpx;
border-radius: 50%;
background: rgba(255,255,255,0.14);
background: rgba(255, 255, 255, 0.7);
display: flex;
align-items: center;
justify-content: center;
}
.refresh-ico {
width: 32rpx; height: 32rpx;
opacity: 0.8;
}
.role-scroll {
width: 100%;
white-space: nowrap;
margin-bottom: 16rpx;
}
.role-line {
display: inline-flex;
gap: 12rpx;
}
.role-chip {
display: inline-block;
padding: 12rpx 28rpx;
border-radius: 999rpx;
font-size: 26rpx;
color: rgba(255,255,255,0.65);
background: rgba(20, 26, 40, 0.75);
border: 1rpx solid rgba(255,255,255,0.12);
}
.role-chip.on {
color: #fff;
font-weight: 600;
background: rgba(107, 163, 247, 0.45);
border-color: rgba(107, 163, 247, 0.65);
box-shadow: 0 0 20rpx rgba(107, 163, 247, 0.2);
}
.date-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 10rpx;
margin-bottom: 12rpx;
}
.date-chip {
text-align: center;
padding: 14rpx 0;
border-radius: 14rpx;
font-size: 24rpx;
color: rgba(255,255,255,0.65);
background: rgba(20, 26, 40, 0.72);
border: 1rpx solid rgba(255,255,255,0.08);
}
.date-chip.on {
color: #A8CCFF;
font-weight: 600;
background: rgba(107, 163, 247, 0.35);
border-color: rgba(107, 163, 247, 0.55);
}
.sort-tip {
display: block;
font-size: 22rpx;
color: rgba(255,255,255,0.45);
margin-top: 8rpx;
}
.scope-row {
display: flex;
gap: 12rpx;
margin-top: 16rpx;
}
.scope-chip {
padding: 10rpx 24rpx;
border-radius: 999rpx;
font-size: 24rpx;
color: rgba(255,255,255,0.65);
background: rgba(20, 26, 40, 0.75);
border: 1rpx solid rgba(255,255,255,0.12);
}
.scope-chip.on {
color: #fff;
background: rgba(255, 193, 7, 0.35);
border-color: rgba(255, 193, 7, 0.5);
width: 28rpx;
height: 28rpx;
opacity: 0.65;
}
.reward-banner {
margin-top: 16rpx;
padding: 20rpx 24rpx;
margin: 0 24rpx 12rpx;
padding: 18rpx 22rpx;
border-radius: 16rpx;
background: linear-gradient(135deg, rgba(255,193,7,0.2), rgba(107,163,247,0.15));
border: 1rpx solid rgba(255,193,7,0.35);
background: rgba(255, 255, 255, 0.85);
border: 1rpx solid rgba(255, 193, 7, 0.35);
display: flex;
align-items: center;
justify-content: space-between;
@@ -148,237 +150,285 @@ page {
.reward-banner-main {
display: flex;
flex-direction: column;
gap: 6rpx;
gap: 4rpx;
}
.reward-tag { font-size: 28rpx; font-weight: 600; color: #ffd666; }
.reward-club { font-size: 22rpx; color: rgba(255,255,255,0.7); }
.reward-status { font-size: 22rpx; color: rgba(255,255,255,0.55); }
.reward-tag { font-size: 26rpx; font-weight: 600; color: #d48806; }
.reward-club { font-size: 22rpx; color: #666; }
.reward-status { font-size: 22rpx; color: #999; }
.reward-status.pending { color: #52c41a; font-weight: 600; }
.reward-status.claimed { color: #8c8c8c; }
.reward-link { font-size: 24rpx; color: #8EB8FF; }
.p-reward {
display: block;
margin-top: 6rpx;
font-size: 22rpx;
color: #ffd666;
font-weight: 600;
}
.lc-reward {
display: block;
margin-top: 4rpx;
font-size: 22rpx;
color: #ffd666;
}
.claim-bar {
position: fixed;
left: 0; right: 0; bottom: 0;
z-index: 100;
padding: 20rpx 28rpx calc(20rpx + env(safe-area-inset-bottom));
background: linear-gradient(180deg, rgba(13,17,23,0.2), rgba(13,17,23,0.95));
display: flex;
align-items: center;
justify-content: space-between;
border-top: 1rpx solid rgba(255,193,7,0.3);
}
.claim-text { display: flex; flex-direction: column; }
.claim-title { font-size: 26rpx; color: #fff; }
.claim-amount { font-size: 36rpx; font-weight: 700; color: #ffd666; }
.claim-btn {
margin: 0;
padding: 0 40rpx;
height: 72rpx;
line-height: 72rpx;
font-size: 28rpx;
background: linear-gradient(135deg, #ffc107, #ff9800);
color: #1a1a1a;
border-radius: 999rpx;
border: none;
}
.bottom-gap {
height: 160rpx;
}
.reward-link { font-size: 24rpx; color: #d48806; }
/* ========== 状态 ========== */
.state-wrap {
position: relative;
z-index: 5;
display: flex;
flex-direction: column;
align-items: center;
padding: 140rpx 0;
color: rgba(255,255,255,0.45);
padding: 120rpx 0;
color: rgba(0, 0, 0, 0.45);
font-size: 28rpx;
}
.loader {
width: 48rpx; height: 48rpx;
border: 3rpx solid rgba(255,255,255,0.12);
border-top-color: #6BA3F7;
width: 48rpx;
height: 48rpx;
border: 3rpx solid rgba(0, 0, 0, 0.08);
border-top-color: #ffb800;
border-radius: 50%;
animation: spin 0.7s linear infinite;
margin-bottom: 20rpx;
}
@keyframes spin {
to { transform: rotate(360deg); }
}
.state-img {
width: 160rpx; height: 160rpx;
width: 160rpx;
height: 160rpx;
margin-bottom: 20rpx;
opacity: 0.65;
opacity: 0.5;
}
/* ========== 滚动 ========== */
/* ========== 滚动 ========== */
.body-scroll {
position: relative;
z-index: 5;
height: calc(100vh - 300rpx);
height: calc(100vh - 280rpx);
}
/* ========== 领奖台(纯 CSS ========== */
.podium-panel {
margin: 8rpx 24rpx 24rpx;
padding: 28rpx 12rpx 0;
border-radius: 28rpx;
background: rgba(14, 18, 30, 0.88);
border: 1rpx solid rgba(255, 255, 255, 0.1);
/* ========== 领奖台 ========== */
.podium-zone {
padding: 16rpx 16rpx 0;
}
.podium-cols {
.podium-row {
display: flex;
align-items: flex-end;
justify-content: center;
gap: 10rpx;
gap: 6rpx;
}
.p-col {
.podium-col {
flex: 1;
max-width: 220rpx;
max-width: 230rpx;
display: flex;
flex-direction: column;
align-items: center;
position: relative;
}
.p-first {
max-width: 250rpx;
margin-bottom: 16rpx;
.col-1 {
max-width: 260rpx;
margin-bottom: 10rpx;
}
.p-badge {
width: 44rpx; height: 44rpx;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 14rpx;
font-size: 24rpx;
font-weight: 800;
}
.p-first .p-badge {
width: 52rpx; height: 52rpx;
.crown {
font-size: 28rpx;
line-height: 1;
margin-bottom: 6rpx;
filter: drop-shadow(0 2rpx 4rpx rgba(0, 0, 0, 0.15));
}
.badge-first {
color: #fff;
background: linear-gradient(145deg, #6BA3F7, #4A7FD4);
box-shadow: 0 4rpx 16rpx rgba(107, 163, 247, 0.4);
.col-1 .crown {
font-size: 34rpx;
}
.badge-silver {
color: #fff;
background: linear-gradient(145deg, #A8B4C4, #7A8899);
box-shadow: 0 4rpx 12rpx rgba(168, 180, 196, 0.25);
}
.badge-bronze {
color: #fff;
background: linear-gradient(145deg, #C4A882, #9A7858);
box-shadow: 0 4rpx 12rpx rgba(196, 168, 130, 0.25);
}
.p-avatar-wrap {
.avatar-ring {
border-radius: 50%;
padding: 4rpx;
margin-bottom: 12rpx;
padding: 6rpx;
margin-bottom: 10rpx;
background: #ffffff;
}
.wrap-first {
padding: 5rpx;
background: linear-gradient(145deg, #8EB8FF, #5B8FD8);
box-shadow: 0 6rpx 24rpx rgba(107, 163, 247, 0.3);
.ring-gold {
padding: 8rpx;
box-shadow: 0 0 0 4rpx #ffd700, 0 8rpx 20rpx rgba(255, 183, 0, 0.35);
}
.wrap-silver {
background: linear-gradient(145deg, #C8D0DA, #909AA8);
.ring-silver {
box-shadow: 0 0 0 4rpx #b8c4d4, 0 6rpx 16rpx rgba(120, 140, 180, 0.25);
}
.wrap-bronze {
background: linear-gradient(145deg, #D4B896, #A88860);
.ring-bronze {
box-shadow: 0 0 0 4rpx #cd9a5a, 0 6rpx 16rpx rgba(205, 127, 50, 0.25);
}
.p-avatar {
width: 100rpx; height: 100rpx;
width: 96rpx;
height: 96rpx;
border-radius: 50%;
display: block;
background: #1a2030;
background: #f0f0f0;
}
.p-avatar-lg {
width: 120rpx; height: 120rpx;
width: 116rpx;
height: 116rpx;
}
.p-name {
font-size: 26rpx;
font-weight: 600;
color: rgba(255,255,255,0.92);
color: #1a1a1a;
max-width: 100%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
text-align: center;
margin-bottom: 8rpx;
}
.p-name-first {
.p-name-lg {
font-size: 28rpx;
color: #fff;
}
.p-uid {
margin-top: 4rpx;
font-size: 20rpx;
color: rgba(255,255,255,0.35);
}
.p-amount {
margin: 12rpx 0 10rpx;
text-align: center;
}
.p-money {
display: block;
font-size: 30rpx;
font-weight: 700;
color: #8EB8FF;
letter-spacing: -0.5rpx;
}
.p-money-first {
font-size: 34rpx;
color: #A8CCFF;
}
.p-label {
display: block;
font-size: 22rpx;
color: #999999;
line-height: 1.2;
}
.p-amount {
font-size: 34rpx;
font-weight: 800;
color: #ffb800;
line-height: 1.3;
margin-top: 2rpx;
}
.p-amount-lg {
font-size: 40rpx;
}
.p-sub-label {
font-size: 22rpx;
color: #999999;
margin-top: 6rpx;
}
.p-sub-value {
font-size: 28rpx;
font-weight: 700;
color: #ffb800;
line-height: 1.2;
}
.p-sub-value-lg {
font-size: 32rpx;
}
.p-reward {
margin-top: 4rpx;
font-size: 20rpx;
color: rgba(255,255,255,0.35);
color: #d48806;
font-weight: 600;
}
.pedestal {
width: 92%;
margin-top: 14rpx;
border-radius: 16rpx 16rpx 0 0;
background: linear-gradient(180deg, #ffe08a 0%, #ffd04d 100%);
box-shadow: inset 0 2rpx 0 rgba(255, 255, 255, 0.5);
}
.pedestal-1 {
height: 88rpx;
background: linear-gradient(180deg, #ffe08a 0%, #ffc933 100%);
}
.pedestal-2 {
height: 64rpx;
background: linear-gradient(180deg, #ffe08a 0%, #ffd04d 100%);
}
.pedestal-3 {
height: 48rpx;
background: linear-gradient(180deg, #ffe08a 0%, #ffd04d 100%);
}
/* ========== 列表区(白底) ========== */
.list-panel {
margin-top: 8rpx;
background: #ffffff;
border-radius: 32rpx 32rpx 0 0;
padding: 24rpx 28rpx 0;
min-height: 400rpx;
box-shadow: 0 -4rpx 20rpx rgba(0, 0, 0, 0.04);
}
.list-row {
display: flex;
align-items: center;
padding: 24rpx 0;
border-bottom: 1rpx solid #f3f3f3;
}
.list-row:last-child {
border-bottom: none;
}
.li-rank {
width: 44rpx;
flex-shrink: 0;
font-size: 32rpx;
font-weight: 700;
color: #333333;
text-align: center;
}
.li-avatar {
width: 72rpx;
height: 72rpx;
border-radius: 50%;
flex-shrink: 0;
margin: 0 16rpx 0 8rpx;
background: #f0f0f0;
}
.li-name {
flex: 1;
min-width: 0;
font-size: 28rpx;
font-weight: 500;
color: #1a1a1a;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.li-right {
flex-shrink: 0;
text-align: right;
margin-left: 12rpx;
}
.li-amount {
display: block;
font-size: 30rpx;
font-weight: 700;
color: #1a1a1a;
line-height: 1.3;
}
.li-orders {
display: block;
margin-top: 4rpx;
font-size: 24rpx;
color: #999999;
}
.li-reward {
display: block;
margin-top: 4rpx;
font-size: 20rpx;
color: #d48806;
}
.sort-tip {
display: block;
padding: 0 24rpx 8rpx;
font-size: 22rpx;
color: rgba(0, 0, 0, 0.45);
}
.p-metrics {
@@ -386,174 +436,86 @@ page {
flex-wrap: wrap;
gap: 6rpx;
justify-content: center;
margin-bottom: 16rpx;
min-height: 36rpx;
margin: 8rpx 0 10rpx;
max-width: 100%;
}
.p-metric {
font-size: 18rpx;
color: rgba(255,255,255,0.55);
background: rgba(255,255,255,0.1);
font-size: 20rpx;
color: #888;
background: rgba(255, 255, 255, 0.65);
padding: 4rpx 10rpx;
border-radius: 8rpx;
}
/* 底座 · 圆角柱体,非方块 */
.p-pedestal {
width: 88%;
border-radius: 20rpx 20rpx 0 0;
position: relative;
}
.p-pedestal::before {
content: '';
position: absolute;
top: 0; left: 10%; right: 10%;
height: 2rpx;
background: rgba(255,255,255,0.15);
border-radius: 2rpx;
}
.pedestal-first {
height: 100rpx;
background: linear-gradient(180deg, rgba(107,163,247,0.55) 0%, rgba(107,163,247,0.22) 100%);
border: 1rpx solid rgba(107,163,247,0.35);
border-bottom: none;
}
.pedestal-silver {
height: 72rpx;
background: linear-gradient(180deg, rgba(168,180,196,0.45) 0%, rgba(168,180,196,0.18) 100%);
border: 1rpx solid rgba(168,180,196,0.28);
border-bottom: none;
}
.pedestal-bronze {
height: 56rpx;
background: linear-gradient(180deg, rgba(196,168,130,0.45) 0%, rgba(196,168,130,0.18) 100%);
border: 1rpx solid rgba(196,168,130,0.28);
border-bottom: none;
}
/* ========== 列表 ========== */
.list-wrap {
padding: 0 24rpx;
}
.list-title-row {
display: flex;
align-items: baseline;
justify-content: space-between;
padding: 8rpx 8rpx 20rpx;
}
.list-title {
font-size: 30rpx;
font-weight: 700;
color: rgba(255,255,255,0.85);
}
.list-range {
font-size: 22rpx;
color: rgba(255,255,255,0.3);
}
.list-card {
position: relative;
margin-bottom: 14rpx;
border-radius: 18rpx;
overflow: hidden;
border: 1rpx solid rgba(255,255,255,0.05);
}
.list-card-bg {
position: absolute;
top: 0; left: 0;
width: 100%; height: 100%;
z-index: 0;
}
.list-card-body {
position: relative;
z-index: 1;
display: flex;
align-items: center;
padding: 20rpx 22rpx;
background: rgba(12, 16, 28, 0.92);
backdrop-filter: blur(8px);
}
.lc-rank {
width: 48rpx;
flex-shrink: 0;
text-align: center;
}
.lc-rank text {
font-size: 32rpx;
font-weight: 700;
color: rgba(255,255,255,0.18);
}
.lc-avatar {
width: 80rpx; height: 80rpx;
border-radius: 50%;
flex-shrink: 0;
margin: 0 16rpx 0 6rpx;
border: 2rpx solid rgba(107, 163, 247, 0.2);
background: #1a2030;
}
.lc-info { flex: 1; min-width: 0; }
.lc-name {
.li-label {
display: block;
font-size: 28rpx;
font-weight: 600;
color: rgba(255,255,255,0.92);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.lc-uid {
display: block;
margin-top: 4rpx;
margin-top: 2rpx;
font-size: 22rpx;
color: rgba(255,255,255,0.32);
color: #999;
}
.lc-tags {
.li-tags {
display: flex;
flex-wrap: wrap;
gap: 8rpx;
margin-top: 8rpx;
gap: 6rpx;
justify-content: flex-end;
margin-top: 6rpx;
max-width: 280rpx;
}
.lc-tag {
.li-tag {
font-size: 20rpx;
color: rgba(255,255,255,0.5);
background: rgba(255,255,255,0.1);
padding: 2rpx 10rpx;
color: #888;
background: #f5f5f5;
padding: 2rpx 8rpx;
border-radius: 6rpx;
}
.lc-score {
flex-shrink: 0;
text-align: right;
margin-left: 10rpx;
.bottom-gap {
height: 160rpx;
}
.lc-money {
display: block;
font-size: 28rpx;
/* ========== 领取栏 ========== */
.claim-bar {
position: fixed;
left: 0;
right: 0;
bottom: 0;
z-index: 100;
padding: 20rpx 28rpx calc(20rpx + env(safe-area-inset-bottom));
background: #ffffff;
display: flex;
align-items: center;
justify-content: space-between;
border-top: 1rpx solid #f0f0f0;
box-shadow: 0 -4rpx 16rpx rgba(0, 0, 0, 0.06);
}
.claim-text {
display: flex;
flex-direction: column;
}
.claim-title {
font-size: 26rpx;
color: #333;
}
.claim-amount {
font-size: 36rpx;
font-weight: 700;
color: #8EB8FF;
color: #ffb800;
}
.lc-label {
display: block;
margin-top: 2rpx;
font-size: 20rpx;
color: rgba(255,255,255,0.32);
.claim-btn {
margin: 0;
padding: 0 40rpx;
height: 72rpx;
line-height: 72rpx;
font-size: 28rpx;
background: linear-gradient(135deg, #ffc107, #ffb300);
color: #1a1a1a;
border-radius: 999rpx;
border: none;
}

View File

@@ -0,0 +1,368 @@
// pages/fighter-recharge/fighter-deposit.js — 平台履约金/保证金独立页
import request from '../../utils/request';
import PopupService from '../../services/popupService.js';
import { ensurePhoneAuth } from '../../utils/phone-auth.js';
import { ICON_KEYS, resolveConfiguredIcon, resolveMiniappIcon, ICON_FOLDER, refreshPindaoConfig } from '../../utils/miniapp-icons.js';
import { resolveAvatarFromStorage, onAvatarImageError } from '../../utils/avatar.js';
const app = getApp();
const DEFAULT_RULES = [
'履约金有效期为永久有效',
'超过15天未接单可联系客服申请退还',
'缴纳后可优先接锁单/平台单等待遇',
];
const DEFAULT_BENEFITS = [
{ label: '平台订单优先', key: ICON_KEYS.FIGHTER_DEPOSIT_BENEFIT_1 },
{ label: '快人一步', key: ICON_KEYS.FIGHTER_DEPOSIT_BENEFIT_2 },
{ label: '优质接单', key: ICON_KEYS.FIGHTER_DEPOSIT_BENEFIT_3 },
{ label: '解锁平台单', key: ICON_KEYS.FIGHTER_DEPOSIT_BENEFIT_4 },
];
Page({
data: {
imgUrls: { pageBg: '', hero: '' },
avatarUrl: '',
nickname: '',
uid: '',
yajin: 0,
yajinDisplay: '0.00',
yajinActive: false,
depositRules: DEFAULT_RULES,
depositBenefits: DEFAULT_BENEFITS,
agreed: false,
payAmountLabel: '',
yajinAmount: '100',
quickAmounts: ['100', '500', '1000', '5000'],
showAmountModal: false,
showPayMethodModal: false,
showBalanceModal: false,
showConfirmModal: false,
balanceOptions: [],
selectedBalanceId: null,
selectedBalanceInfo: null,
currentYajinAmount: null,
currentDingdanid: '',
payLoading: false,
loadingText: '处理中...',
},
onLoad(options) {
this._jumpParams = options || {};
this.initImages();
this.loadUserInfo();
},
onHide() {
this.selectComponent('#popupNotice')?.cleanup?.();
},
async onShow() {
const phoneOk = await ensurePhoneAuth({ redirect: true, role: 'dashou' });
if (!phoneOk) return;
this.registerNotification();
this.loadYajin();
this.refreshConfiguredIcons();
PopupService.checkAndShow(this, 'dashouchongzhi');
const preset = this._jumpParams?.presetAmount || this._jumpParams?.requiredYajin;
if (preset && parseFloat(preset) > 0) {
this.setData({ yajinAmount: String(parseInt(preset, 10)) });
}
},
registerNotification() {
const comp = this.selectComponent('#global-notification');
if (comp?.showNotification) {
app.globalData.globalNotification = {
show: (data) => comp.showNotification(data),
hide: () => comp.hideNotification(),
};
}
},
initImages() {
const fb = (key) => `${ICON_FOLDER}/${key}.png`;
const depositBenefits = DEFAULT_BENEFITS.map((item) => ({
label: item.label,
iconUrl: resolveMiniappIcon(app, item.key, fb(item.key)),
}));
this.setData({
imgUrls: {
pageBg: resolveConfiguredIcon(app, ICON_KEYS.FIGHTER_DEPOSIT_BG),
hero: resolveConfiguredIcon(app, ICON_KEYS.FIGHTER_DEPOSIT_HERO),
},
depositBenefits,
});
},
async refreshConfiguredIcons() {
try {
await refreshPindaoConfig(app);
} catch (e) {
console.warn('refreshConfiguredIcons failed', e);
}
this.initImages();
this.loadUserInfo();
},
loadUserInfo() {
const gd = app.globalData || {};
this.setData({
avatarUrl: resolveAvatarFromStorage(app),
nickname: gd.dashouNicheng || gd.nicheng || '打手',
uid: wx.getStorageSync('uid') || gd.uid || '',
});
},
onAvatarError() {
onAvatarImageError(this, 'avatarUrl', app);
},
loadYajin() {
const yajin = parseFloat(app.globalData.yajin || 0) || 0;
this.setData({
yajin,
yajinDisplay: yajin.toFixed(2),
yajinActive: yajin > 0,
});
},
toggleAgree() {
this.setData({ agreed: !this.data.agreed });
},
onTapPay() {
if (!this.data.agreed) {
wx.showToast({ title: '请先阅读并同意缴纳规则', icon: 'none' });
return;
}
this.setData({ showAmountModal: true });
},
hideAmountModal() {
this.setData({ showAmountModal: false });
},
onYajinInput(e) {
let v = (e.detail.value || '').replace(/[^\d]/g, '');
if (v) {
const n = parseInt(v, 10);
if (n > 10000) v = '10000';
if (n < 1) v = '1';
}
this.setData({ yajinAmount: v });
},
setQuickAmount(e) {
this.setData({ yajinAmount: e.currentTarget.dataset.amount });
},
onConfirmAmount() {
const amount = this.data.yajinAmount;
if (!amount || amount < 1 || amount > 10000) {
wx.showToast({ title: '请输入1-10000元', icon: 'none' });
return;
}
this.hideAmountModal();
this.setData({
currentYajinAmount: amount,
payAmountLabel: `(¥ ${amount}`,
showPayMethodModal: true,
});
},
hidePayMethodModal() {
this.setData({ showPayMethodModal: false });
},
onPayMethodSelect(e) {
const method = e.currentTarget.dataset.method;
this.hidePayMethodModal();
if (method === 'wx') {
this.setData({ yajinAmount: this.data.currentYajinAmount }, () => this.handleYajinPay());
} else {
this.fetchBalanceOptions();
}
},
async fetchBalanceOptions() {
this.showLoading('获取抵扣信息...');
try {
const res = await request({
url: '/shangpin/czhqdy',
method: 'POST',
data: {
leixing: 2,
yajin_jine: parseInt(this.data.currentYajinAmount, 10),
},
});
if (res.data.code === 200) {
this.setData({ balanceOptions: res.data.data || [], showBalanceModal: true });
} else {
wx.showToast({ title: res.data.message || '获取失败', icon: 'none' });
}
} catch (err) {
wx.showToast({ title: '网络错误', icon: 'none' });
} finally {
this.hideLoading();
}
},
hideBalanceModal() {
this.setData({ showBalanceModal: false });
},
onBalanceSelect(e) {
const id = e.currentTarget.dataset.id;
const selected = this.data.balanceOptions.find((o) => o.id === id);
if (!selected) return;
this.setData({
selectedBalanceId: id,
selectedBalanceInfo: selected,
showConfirmModal: true,
showBalanceModal: false,
});
},
hideConfirmModal() {
this.setData({ showConfirmModal: false });
},
async confirmBalancePay() {
const { selectedBalanceId, currentYajinAmount } = this.data;
if (!selectedBalanceId) return;
this.hideConfirmModal();
this.showLoading('抵扣支付中...');
try {
const res = await request({
url: '/shangpin/dsqrgmdh',
method: 'POST',
data: {
leixing: 2,
shenfen_id: selectedBalanceId,
yajin_jine: parseInt(currentYajinAmount, 10),
},
});
if (res.data.code === 200) {
const data = res.data.data || {};
if (data.yajin !== undefined) app.globalData.yajin = data.yajin;
this.loadYajin();
wx.showToast({ title: '缴纳成功', icon: 'success' });
} else {
wx.showToast({ title: res.data.message || '购买失败', icon: 'none' });
}
} catch (err) {
wx.showToast({ title: '网络错误', icon: 'none' });
} finally {
this.hideLoading();
}
},
confirmWechatPurchase() {
return new Promise((resolve) => {
wx.showModal({
title: '确认微信支付',
content: '您即将通过微信支付缴纳履约金。购买成功后不可随意退款,请确认无误后再继续。',
confirmText: '确认购买',
cancelText: '再想想',
success: (res) => resolve(!!res.confirm),
fail: () => resolve(false),
});
});
},
async handleYajinPay() {
const amount = this.data.yajinAmount;
if (!amount || amount < 1 || amount > 10000) {
wx.showToast({ title: '请输入1-10000元', icon: 'none' });
return;
}
if (!(await this.confirmWechatPurchase())) return;
this.showLoading('发起支付中...');
try {
const res = await request({
url: '/shangpin/yajingoumai',
method: 'POST',
data: { jine: parseInt(amount, 10) },
});
if (res.data.code === 200) {
this.setData({ currentDingdanid: res.data.dingdanid });
await this.wechatPay(res.data.payParams);
} else {
wx.showToast({ title: res.data.message || '支付发起失败', icon: 'none' });
}
} catch (err) {
wx.showToast({ title: '支付失败', icon: 'none' });
} finally {
this.hideLoading();
}
},
wechatPay(payParams) {
return new Promise((resolve, reject) => {
wx.requestPayment({
timeStamp: payParams.timeStamp,
nonceStr: payParams.nonceStr,
package: payParams.package,
signType: payParams.signType || 'MD5',
paySign: payParams.paySign,
success: async () => {
wx.showToast({ title: '支付成功!确认中...', icon: 'none' });
try {
await this.startPolling();
resolve();
} catch (e) {
reject(e);
}
},
fail: async (res) => {
wx.showToast({ title: res.errMsg?.includes('cancel') ? '已取消支付' : '支付失败', icon: 'none' });
try {
await request({
url: '/shangpin/yajinshibai',
method: 'POST',
data: { dingdanid: this.data.currentDingdanid },
});
} catch (e) { /* ignore */ }
reject(new Error(res.errMsg));
},
});
});
},
async startPolling() {
const dingdanid = this.data.currentDingdanid;
if (!dingdanid) return;
this.showLoading('确认支付结果...');
for (let i = 0; i < 10; i++) {
try {
const res = await request({
url: '/shangpin/yajinlunxun',
method: 'POST',
data: { dingdanid },
});
if (res.data.code === 200) {
if (res.data.yajin !== undefined) app.globalData.yajin = res.data.yajin;
this.loadYajin();
this.hideLoading();
wx.showToast({ title: '履约金缴纳成功', icon: 'success' });
return;
}
} catch (e) { /* retry */ }
await new Promise((r) => setTimeout(r, 2000));
}
this.hideLoading();
wx.showToast({ title: '确认超时,请稍后查看余额', icon: 'none' });
},
showLoading(text) {
this.setData({ payLoading: true, loadingText: text || '处理中...' });
},
hideLoading() {
this.setData({ payLoading: false });
},
stopPropagation() {},
});

View File

@@ -0,0 +1,10 @@
{
"usingComponents": {
"global-notification": "/components/global-notification/global-notification",
"popup-notice": "/components/popup-notice/popup-notice"
},
"navigationBarTitleText": "平台履约金",
"navigationBarBackgroundColor": "#FFF9F0",
"navigationBarTextStyle": "black",
"backgroundColor": "#FFF9F0"
}

View File

@@ -0,0 +1,133 @@
<!-- 平台履约金 / 保证金充值页 -->
<view class="deposit-page">
<image wx:if="{{imgUrls.pageBg}}" class="page-bg" src="{{imgUrls.pageBg}}" mode="widthFix" />
<view class="page-bg-fallback" wx:else></view>
<view class="page-body">
<view class="user-row">
<image class="user-avatar" src="{{avatarUrl}}" mode="aspectFill" binderror="onAvatarError" />
<view class="user-info">
<text class="user-name">{{nickname || '打手'}}</text>
<text class="user-id">会员ID: {{uid || '--'}}</text>
</view>
</view>
<view class="deposit-card">
<view class="deposit-card-left">
<text class="deposit-card-title">平台接单履约金</text>
<view class="deposit-price-row">
<text class="deposit-currency">¥</text>
<text class="deposit-price">{{yajinDisplay}}</text>
</view>
<text class="deposit-validity">有效期:永久有效</text>
</view>
<view class="deposit-card-right">
<view class="icon-clip icon-clip-deposit" wx:if="{{imgUrls.hero}}">
<image class="icon-clip-img" src="{{imgUrls.hero}}" mode="aspectFill" />
</view>
<view class="deposit-status">{{yajinActive ? '已缴纳' : '未激活'}}</view>
</view>
<view class="deposit-shimmer"></view>
</view>
<view class="section-card">
<text class="section-title">履约金规则</text>
<view class="rule-list">
<view wx:for="{{depositRules}}" wx:key="index" class="rule-item">
<text class="rule-num">{{index + 1}}.</text>
<text class="rule-text">{{item}}</text>
</view>
</view>
</view>
<view class="section-card">
<text class="section-title">平台履约金权益</text>
<view class="benefit-grid">
<view wx:for="{{depositBenefits}}" wx:key="label" class="benefit-item">
<view wx:if="{{item.iconUrl}}" class="icon-clip icon-clip-deposit-benefit">
<image class="icon-clip-img" src="{{item.iconUrl}}" mode="aspectFill" />
</view>
<text>{{item.label}}</text>
</view>
</view>
</view>
</view>
<view class="footer-bar">
<view class="agree-row" bindtap="toggleAgree">
<view class="agree-check {{agreed ? 'agree-check--on' : ''}}">{{agreed ? '✓' : ''}}</view>
<text class="agree-text">已阅读并同意</text>
<text class="agree-link">《平台履约金缴纳规则》</text>
</view>
<view class="pay-btn {{agreed ? '' : 'pay-btn--disabled'}}" bindtap="onTapPay">
<text>缴纳履约金{{payAmountLabel}}</text>
<view class="pay-btn-shimmer"></view>
</view>
</view>
</view>
<!-- 金额输入弹窗 -->
<view class="modal-mask" wx:if="{{showAmountModal}}" bindtap="hideAmountModal">
<view class="modal-panel" catchtap="stopPropagation">
<text class="modal-title">缴纳履约金</text>
<text class="modal-sub">支持 1-10000 元整数</text>
<view class="amount-input-wrap">
<text class="amount-prefix">¥</text>
<input class="amount-input" type="digit" value="{{yajinAmount}}" bindinput="onYajinInput" focus="{{showAmountModal}}" />
</view>
<view class="quick-row">
<view wx:for="{{quickAmounts}}" wx:key="*this" class="quick-chip {{yajinAmount == item ? 'active' : ''}}" bindtap="setQuickAmount" data-amount="{{item}}">{{item}}元</view>
</view>
<view class="modal-actions">
<view class="modal-btn cancel" bindtap="hideAmountModal">取消</view>
<view class="modal-btn confirm" bindtap="onConfirmAmount">下一步</view>
</view>
</view>
</view>
<!-- 支付方式 -->
<view class="modal-mask" wx:if="{{showPayMethodModal}}" bindtap="hidePayMethodModal">
<view class="modal-panel" catchtap="stopPropagation">
<text class="modal-title">选择支付方式</text>
<view class="pay-method-item" bindtap="onPayMethodSelect" data-method="wx">
<text class="pay-method-name">微信支付</text>
<text class="pay-method-desc">安全快捷</text>
</view>
<view class="pay-method-item" bindtap="onPayMethodSelect" data-method="balance">
<text class="pay-method-name">余额抵扣</text>
<text class="pay-method-desc">使用佣金或分红</text>
</view>
</view>
</view>
<view class="modal-mask" wx:if="{{showBalanceModal}}" bindtap="hideBalanceModal">
<view class="modal-panel" catchtap="stopPropagation">
<text class="modal-title">选择抵扣身份</text>
<view wx:for="{{balanceOptions}}" wx:key="id" class="balance-item" bindtap="onBalanceSelect" data-id="{{item.id}}">
<text>{{item.jieshao}}</text>
<text class="balance-need">需¥{{item.xuyao}}</text>
</view>
</view>
</view>
<view class="modal-mask" wx:if="{{showConfirmModal}}" bindtap="hideConfirmModal">
<view class="modal-panel" catchtap="stopPropagation">
<text class="modal-title">确认抵扣</text>
<view class="confirm-row"><text>身份</text><text>{{selectedBalanceInfo.jieshao}}</text></view>
<view class="confirm-row"><text>金额</text><text>¥{{selectedBalanceInfo.xuyao}}</text></view>
<view class="modal-actions">
<view class="modal-btn cancel" bindtap="hideConfirmModal">取消</view>
<view class="modal-btn confirm" bindtap="confirmBalancePay">确认支付</view>
</view>
</view>
</view>
<view class="loading-mask" wx:if="{{payLoading}}">
<view class="loading-box">
<view class="loading-spinner"></view>
<text>{{loadingText}}</text>
</view>
</view>
<global-notification id="global-notification" />
<popup-notice id="popupNotice" />

View File

@@ -0,0 +1,279 @@
@import '../../styles/xym-recharge-shared.wxss';
.deposit-page {
min-height: 100vh;
background: #fff9f0;
padding-bottom: calc(220rpx + env(safe-area-inset-bottom));
position: relative;
}
.page-bg {
position: absolute;
top: 0;
left: 0;
width: 100%;
z-index: 0;
}
.page-bg-fallback {
position: absolute;
top: 0;
left: 0;
right: 0;
height: 360rpx;
background: linear-gradient(180deg, #ffe082 0%, #fff9f0 100%);
z-index: 0;
}
.page-body {
position: relative;
z-index: 1;
padding: 24rpx 30rpx 0;
}
.user-row {
display: flex;
align-items: center;
margin-bottom: 24rpx;
}
.user-avatar {
width: 88rpx;
height: 88rpx;
border-radius: 50%;
margin-right: 20rpx;
background: #eee;
}
.user-name {
display: block;
font-size: 32rpx;
font-weight: 700;
color: #222;
}
.user-id {
display: block;
margin-top: 6rpx;
font-size: 24rpx;
color: #999;
}
.deposit-card {
position: relative;
overflow: hidden;
border-radius: 24rpx;
padding: 32rpx 28rpx;
background: linear-gradient(135deg, #fff8e1 0%, #ffe0b2 100%);
display: flex;
justify-content: space-between;
align-items: stretch;
margin-bottom: 24rpx;
box-shadow: 0 8rpx 24rpx rgba(255, 183, 77, 0.25);
}
.deposit-card-left {
flex: 1;
min-width: 0;
}
.deposit-card-title {
font-size: 30rpx;
font-weight: 700;
color: #492f00;
}
.deposit-price-row {
display: flex;
align-items: baseline;
margin: 16rpx 0 8rpx;
}
.deposit-currency {
font-size: 36rpx;
font-weight: 700;
color: #222;
margin-right: 4rpx;
}
.deposit-price {
font-size: 64rpx;
font-weight: 800;
color: #222;
line-height: 1;
}
.deposit-validity {
font-size: 24rpx;
color: #947641;
}
.deposit-card-right {
position: relative;
width: 200rpx;
display: flex;
align-items: center;
justify-content: center;
}
.icon-clip {
overflow: hidden;
flex-shrink: 0;
background: rgba(255, 255, 255, 0.5);
}
.icon-clip-img {
width: 100%;
height: 100%;
display: block;
}
.icon-clip-deposit {
width: 180rpx;
height: 180rpx;
border-radius: 40rpx;
}
.icon-clip-deposit-benefit {
width: 36rpx;
height: 36rpx;
border-radius: 14rpx;
}
.deposit-status {
position: absolute;
right: 0;
bottom: 0;
padding: 6rpx 16rpx;
border-radius: 8rpx;
background: rgba(0, 0, 0, 0.08);
font-size: 22rpx;
color: #666;
}
.deposit-shimmer {
position: absolute;
inset: 0;
background: linear-gradient(105deg, transparent 40%, rgba(255, 255, 255, 0.45) 50%, transparent 60%);
animation: card-shimmer 3s infinite;
pointer-events: none;
}
.section-card {
background: #fff;
border-radius: 20rpx;
padding: 28rpx;
margin-bottom: 20rpx;
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.04);
}
.section-title {
display: block;
text-align: center;
font-size: 30rpx;
font-weight: 700;
color: #333;
margin-bottom: 20rpx;
}
.rule-item {
display: flex;
gap: 8rpx;
margin-bottom: 12rpx;
font-size: 26rpx;
color: #666;
line-height: 1.6;
}
.benefit-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 20rpx 16rpx;
}
.benefit-item {
display: flex;
align-items: center;
gap: 10rpx;
font-size: 26rpx;
color: #555;
}
.footer-bar {
position: fixed;
left: 0;
right: 0;
bottom: 0;
padding: 20rpx 30rpx calc(20rpx + env(safe-area-inset-bottom));
background: rgba(255, 249, 240, 0.96);
box-shadow: 0 -4rpx 20rpx rgba(0, 0, 0, 0.06);
z-index: 10;
}
.agree-row {
display: flex;
align-items: center;
flex-wrap: wrap;
margin-bottom: 16rpx;
font-size: 24rpx;
color: #666;
}
.agree-check {
width: 32rpx;
height: 32rpx;
border-radius: 50%;
border: 2rpx solid #ccc;
margin-right: 10rpx;
display: flex;
align-items: center;
justify-content: center;
font-size: 20rpx;
color: #fff;
}
.agree-check--on {
background: #f5a623;
border-color: #f5a623;
}
.agree-link {
color: #e6a23c;
}
.pay-btn {
position: relative;
overflow: hidden;
height: 96rpx;
border-radius: 48rpx;
background: linear-gradient(90deg, #fae04d, #ffc0a3);
display: flex;
align-items: center;
justify-content: center;
font-size: 32rpx;
font-weight: 700;
color: #492f00;
box-shadow: 0 8rpx 20rpx rgba(245, 166, 35, 0.35);
}
.pay-btn--disabled {
opacity: 0.55;
}
.pay-btn-shimmer {
position: absolute;
inset: 0;
background: linear-gradient(105deg, transparent 40%, rgba(255, 255, 255, 0.5) 50%, transparent 60%);
animation: btn-shimmer 2.5s infinite;
pointer-events: none;
}
@keyframes card-shimmer {
0% { transform: translateX(-120%); }
100% { transform: translateX(120%); }
}
@keyframes btn-shimmer {
0% { transform: translateX(-120%); }
100% { transform: translateX(120%); }
}

View File

@@ -1,72 +1,57 @@
// pages/dashou-chongzhi/index.js
// pages/fighter-recharge/fighter-recharge.js
import request from '../../utils/request';
import PopupService from '../../services/popupService.js';
import { ensurePhoneAuth } from '../../utils/phone-auth.js';
import { ICON_KEYS, resolveConfiguredIcon, resolveMiniappIcon, ICON_FOLDER, refreshPindaoConfig } from '../../utils/miniapp-icons.js';
import { resolveAvatarFromStorage, onAvatarImageError } from '../../utils/avatar.js';
const app = getApp();
const PLATFORM_ADVANTAGE_META = [
{ key: ICON_KEYS.FIGHTER_RECHARGE_ADVANTAGE_1, title: '订单丰富', desc: '平台单、商家单多种类型' },
{ key: ICON_KEYS.FIGHTER_RECHARGE_ADVANTAGE_2, title: '俱乐部专属', desc: '按俱乐部独立配置权益' },
{ key: ICON_KEYS.FIGHTER_RECHARGE_ADVANTAGE_3, title: '客服支持', desc: '遇到问题随时联系客服' },
{ key: ICON_KEYS.FIGHTER_RECHARGE_ADVANTAGE_4, title: '安全可靠', desc: '资金与订单平台保障' },
];
Page({
data: {
// ========== 全局数据 ==========
clubmber: [], // 会员列表(注意:全局变量中是 clumber这里保持原样
yajin: 0, // 押金
jifen: 0, // 积分(注意:全局变量中是 jinfen
jifenProgress: 0, // 积分进度条角度
// ========== 会员商品列表 ==========
huiyuanList: [], // 从后端获取的会员列表
currentHuiyuanIndex: 0, // 当前选中的会员索引
currentHuiyuan: {}, // 当前选中的会员详情
// ========== 押金充值相关 ==========
showYajinModal: false, // 显示押金弹窗
yajinAmount: '100', // 押金金额
// ========== 支付相关 ==========
payLoading: false, // 支付加载状态
imgUrls: { pageBg: '' },
avatarUrl: '',
nickname: '',
uid: '',
memberBadge: '会员',
agreed: false,
memberBenefits: [],
platformAdvantages: [],
clubmber: [],
jifen: 0,
huiyuanList: [],
currentHuiyuanIndex: 0,
currentHuiyuan: {},
payLoading: false,
loadingText: '支付中...',
// ========== 订单ID记录 ==========
currentDingdanid: '', // 当前操作的订单ID
// ========== 计算高度 ==========
huiyuanListHeight: 120,
// ========== 会员详情规则 ==========
currentDingdanid: '',
detailRules: [],
// ========== 新增:跳转参数处理 ==========
// 用于接收从其他页面跳转过来的参数,决定是否自动滚动
jumpParams: {},
// ========== 新增:支付方式选择 ==========
showPayMethodModal: false, // 支付方式选择弹窗
currentBuyType: null, // 当前购买类型1会员 2押金 3积分
currentHuiyuanId: null, // 当前选中的会员ID用于会员购买
currentBuyIsTrial: false, // 正式/体验:仅体验禁余额抵扣
currentYajinAmount: null, // 当前押金金额(用于押金购买)
// ========== 新增:余额抵扣身份选择 ==========
showBalanceModal: false, // 余额抵扣身份选择弹窗
balanceOptions: [], // 后端返回的身份列表
selectedBalanceId: null, // 选中的身份ID
// ========== 新增:余额抵扣确认弹窗 ==========
showConfirmModal: false, // 余额抵扣确认弹窗
selectedBalanceInfo: null, // 选中的身份详情(用于确认弹窗)
// ========== 新增:会员详情弹窗 ==========
showPayMethodModal: false,
currentBuyType: null,
currentHuiyuanId: null,
currentBuyIsTrial: false,
showBalanceModal: false,
balanceOptions: [],
selectedBalanceId: null,
showConfirmModal: false,
selectedBalanceInfo: null,
showMemberModal: false,
currentMemberDetail: null,
},
// ========== 生命周期函数 ==========
onLoad(options) {
//console.log('页面加载,跳转参数:', options);
// ✅ 新增:保存跳转参数
this.setData({
jumpParams: options || {}
});
this.setData({ jumpParams: options || {} });
this.initImages();
this.loadUserInfo();
this.initPage();
},
@@ -86,6 +71,7 @@ onHide() {
this.registerNotificationComponent();
this.loadFromGlobalData();
this.checkAndRefreshData();
this.refreshConfiguredIcons();
// 调用统一弹窗组件检查并展示公告
PopupService.checkAndShow(this, 'dashouchongzhi');
@@ -112,16 +98,139 @@ onHide() {
// ========== 初始化页面 ==========
async initPage() {
// 从全局数据加载
this.loadFromGlobalData();
// 获取会员商品列表
await this.fetchHuiyuanList();
// 计算会员列表高度
this.calculateHuiyuanHeight();
},
initImages() {
this.setData({
imgUrls: {
pageBg: resolveConfiguredIcon(app, ICON_KEYS.FIGHTER_RECHARGE_VIP_BG),
},
platformAdvantages: this.buildPlatformAdvantages(),
});
},
async refreshConfiguredIcons() {
try {
await refreshPindaoConfig(app);
} catch (e) {
console.warn('refreshConfiguredIcons failed', e);
}
this.initImages();
const list = this.data.huiyuanList || [];
const idx = this.data.currentHuiyuanIndex || 0;
if (list.length) {
this.applyCurrentHuiyuan(list[idx] || {}, idx);
}
this.loadUserInfo();
},
_icon(key, fallbackRel) {
return resolveMiniappIcon(app, key, fallbackRel);
},
buildPlatformAdvantages() {
const fb = (name) => `${ICON_FOLDER}/${name}.png`;
const keys = [
ICON_KEYS.FIGHTER_RECHARGE_ADVANTAGE_1,
ICON_KEYS.FIGHTER_RECHARGE_ADVANTAGE_2,
ICON_KEYS.FIGHTER_RECHARGE_ADVANTAGE_3,
ICON_KEYS.FIGHTER_RECHARGE_ADVANTAGE_4,
];
return PLATFORM_ADVANTAGE_META.map((item, i) => ({
title: item.title,
desc: item.desc,
iconUrl: this._icon(keys[i], fb(keys[i])),
}));
},
loadUserInfo() {
const gd = app.globalData || {};
this.setData({
avatarUrl: resolveAvatarFromStorage(app),
nickname: gd.dashouNicheng || gd.nicheng || '打手',
uid: wx.getStorageSync('uid') || gd.uid || '',
});
},
onAvatarError() {
onAvatarImageError(this, 'avatarUrl', app);
},
resolveOssUrl(path) {
if (!path) return '';
if (path.startsWith('http')) return path;
return (app.globalData.ossImageUrl || '') + path;
},
buildMemberBenefits(huiyuan = {}) {
const name = huiyuan.mingzi || '会员';
const formalPrice = huiyuan.jiage || '0';
const trialPrice = huiyuan.trial_price || '0';
const fb = (name) => `${ICON_FOLDER}/${name}.png`;
const meta = [
{
key: ICON_KEYS.FIGHTER_RECHARGE_BENEFIT_1,
title: '充值立得',
desc: `开通${name}正式版 ¥${formalPrice},享优先接单`,
},
{
key: ICON_KEYS.FIGHTER_RECHARGE_BENEFIT_2,
title: '体验尝鲜',
desc: huiyuan.can_buy_trial
? `体验版 ¥${trialPrice}/${huiyuan.trial_days || 0}终身1次`
: '正式会员支持余额抵扣',
},
{
key: ICON_KEYS.FIGHTER_RECHARGE_BENEFIT_3,
title: '专属特权',
desc: '解锁平台单、优质接单等待遇',
},
];
return meta.map((item) => ({
title: item.title,
desc: item.desc,
iconUrl: this._icon(item.key, fb(item.key)),
}));
},
applyCurrentHuiyuan(huiyuan, index) {
this.setData({
currentHuiyuanIndex: index,
currentHuiyuan: huiyuan,
detailRules: this.buildDetailRules(huiyuan),
memberBenefits: this.buildMemberBenefits(huiyuan),
memberBadge: huiyuan.mingzi || '会员',
});
},
toggleAgree() {
this.setData({ agreed: !this.data.agreed });
},
goToDeposit() {
wx.navigateTo({ url: '/pages/fighter-recharge/fighter-deposit' });
},
onTapTrial(e) {
if (!this.data.agreed) {
wx.showToast({ title: '请先阅读并同意会员协议', icon: 'none' });
return;
}
this.onBuyHuiyuanClick(e);
},
onTapFormal(e) {
if (!this.data.agreed) {
wx.showToast({ title: '请先阅读并同意会员协议', icon: 'none' });
return;
}
this.onBuyHuiyuanClick(e);
},
stopPropagation() {},
// ========== 从全局变量加载数据 ==========
loadFromGlobalData() {
const app = getApp();
@@ -135,35 +244,7 @@ onHide() {
this.setData({
clubmber: clubmber,
yajin: globalData.yajin || 0,
jifen: globalData.jinfen || 0 // ✅ 注意:这里从 jinfen 读取
});
// 计算积分进度条
this.calculateJifenProgress();
},
// ========== 计算积分进度条角度 ==========
calculateJifenProgress() {
const jifen = this.data.jifen || 0;
const progress = (jifen / 10) * 360; // 满分10分
this.setData({
jifenProgress: progress
});
},
// ========== 计算会员列表高度 ==========
calculateHuiyuanHeight() {
const clubmber = this.data.clubmber || [];
const itemHeight = 100; // 每个会员标签高度
const maxHeight = 300; // 最大高度3个会员
let height = clubmber.length * itemHeight;
height = Math.min(height, maxHeight);
this.setData({
huiyuanListHeight: height
jifen: globalData.jinfen || 0,
});
},
@@ -177,17 +258,15 @@ onHide() {
});
if (res.data.code === 200) {
const huiyuanList = res.data.data || [];
// 处理数据,标记已购买的会员
const processedList = this.processHuiyuanList(huiyuanList);
const currentHuiyuan = processedList[0] || {};
this.setData({
huiyuanList: processedList,
currentHuiyuan,
detailRules: this.buildDetailRules(currentHuiyuan)
});
const huiyuanList = this.processHuiyuanList(res.data.data || []);
let index = 0;
const targetId = this.data.jumpParams.huiyuanId;
if (targetId) {
const found = huiyuanList.findIndex((h) => String(h.id) === String(targetId));
if (found >= 0) index = found;
}
this.applyCurrentHuiyuan(huiyuanList[index] || {}, index);
this.setData({ huiyuanList });
} else {
wx.showToast({
title: res.data.message || '获取会员列表失败',
@@ -214,7 +293,9 @@ onHide() {
return {
...item,
isBought: !!boughtItem,
buyInfo: boughtItem || null
buyInfo: boughtItem || null,
cardImageUrl: this.resolveOssUrl(item.card_image),
cardBgUrl: this.resolveOssUrl(item.card_bg),
};
});
},
@@ -223,43 +304,27 @@ onHide() {
onSwiperChange(e) {
const current = e.detail.current;
const huiyuanList = this.data.huiyuanList || [];
const currentHuiyuan = huiyuanList[current] || {};
this.setData({
currentHuiyuanIndex: current,
currentHuiyuan,
detailRules: this.buildDetailRules(currentHuiyuan)
});
this.applyCurrentHuiyuan(huiyuanList[current] || {}, current);
},
// ========== 手动选择会员 ==========
selectHuiyuan(e) {
const index = e.currentTarget.dataset.index;
const huiyuanList = this.data.huiyuanList || [];
const currentHuiyuan = huiyuanList[index] || {};
this.setData({
currentHuiyuanIndex: index,
currentHuiyuan,
detailRules: this.buildDetailRules(currentHuiyuan)
});
this.applyCurrentHuiyuan(huiyuanList[index] || {}, index);
},
buildDetailRules(huiyuan = {}) {
const formalDays = huiyuan.formal_days || 30;
const rules = [
`正式会员有效期${formalDays},从购买当天开始计算`,
'会员期间享受优先接单特权',
'支持随时续费,未过期续费天数叠加,已过期从今天重新计算'
`有效期${formalDays}`,
'可接多种订单类型',
'支持续费,天数叠加',
'正式会员支持余额抵扣',
];
if (huiyuan.can_buy_trial) {
rules.push(`体验会员终身仅可购买1次${huiyuan.trial_days || 0}天),体验期仅限制佣金提现`);
rules[3] = `体验版¥${huiyuan.trial_price}/${huiyuan.trial_days}`;
}
if (huiyuan.trial_enabled && !huiyuan.can_buy_trial) {
rules.push('您已使用过该会员的体验资格');
}
rules.push('体验会员仅支持微信支付;正式会员可使用佣金、分红或押金抵扣');
return rules;
return rules.slice(0, 4);
},
// ========== 格式化到期时间 ==========
@@ -313,112 +378,10 @@ onHide() {
// ========== 处理自动滚动 ==========
handleAutoScroll() {
const { jumpParams } = this.data;
if (!jumpParams || !jumpParams.needScroll) return;
if (!jumpParams || jumpParams.scrollTo !== 'jifen') return;
setTimeout(() => {
let scrollTop = 0;
if (jumpParams.scrollTo === 'bottom') {
scrollTop = 2000;
} else if (jumpParams.scrollTo === 'member') {
return;
}
if (scrollTop > 0) {
wx.pageScrollTo({
scrollTop: scrollTop,
duration: 300
});
}
}, 800);
},
// ========== 押金充值相关 ==========
showYajinModal() {
this.setData({
showYajinModal: true,
yajinAmount: '100'
});
},
hideYajinModal() {
this.setData({
showYajinModal: false
});
},
onYajinInput(e) {
let value = e.detail.value;
value = value.replace(/[^\d]/g, '');
if (value) {
const num = parseInt(value);
if (num < 1) value = '1';
if (num > 10000) value = '10000';
}
this.setData({
yajinAmount: value
});
},
setYajinAmount(e) {
const amount = e.currentTarget.dataset.amount;
this.setData({
yajinAmount: amount
});
},
async handleYajinPay() {
const amount = this.data.yajinAmount;
if (!amount || amount < 1 || amount > 10000) {
wx.showToast({
title: '请输入1-10000元的金额',
icon: 'none'
});
return;
}
const confirmed = await this.confirmWechatPurchase('yajin');
if (!confirmed) return;
this.showLoading('发起支付中...');
try {
const res = await request({
url: '/shangpin/yajingoumai',
method: 'POST',
data: {
jine: parseInt(amount)
}
});
if (res.data.code === 200) {
const payParams = res.data.payParams;
const dingdanid = res.data.dingdanid;
this.setData({
currentDingdanid: dingdanid
});
await this.wechatPay(payParams, 'yajin');
} else {
wx.showToast({
title: res.data.message || '支付发起失败',
icon: 'none'
});
}
} catch (error) {
console.error('押金支付失败:', error);
wx.showToast({
title: '支付失败,请重试',
icon: 'none'
});
} finally {
this.hideLoading();
}
wx.pageScrollTo({ selector: '#jifen-section', duration: 300 });
}, 600);
},
// ========== 积分充值相关 ==========
@@ -858,6 +821,7 @@ onHide() {
const isTrial = e.currentTarget.dataset.trial === true || e.currentTarget.dataset.trial === 'true';
if (isTrial) {
this.setData({ currentBuyIsTrial: true });
this.handleHuiyuanBuy(e);
return;
}
@@ -866,25 +830,7 @@ onHide() {
currentBuyType: 1,
currentHuiyuanId: huiyuanId,
currentBuyIsTrial: false,
showPayMethodModal: true
});
},
onYajinClick() {
this.showYajinModal();
},
onYajinConfirm() {
const amount = this.data.yajinAmount;
if (!amount || amount < 1 || amount > 10000) {
wx.showToast({ title: '请输入1-10000元的金额', icon: 'none' });
return;
}
this.hideYajinModal();
this.setData({
currentBuyType: 2,
currentYajinAmount: amount,
showPayMethodModal: true
showPayMethodModal: true,
});
},
@@ -895,29 +841,20 @@ onHide() {
// 🔥 修改点2选择支付方式时再次校验积分状态防止异步过程中积分变化
onPayMethodSelect(e) {
const method = e.currentTarget.dataset.method;
const { currentBuyType, currentHuiyuanId, currentYajinAmount, jifen } = this.data;
const { currentBuyType, currentHuiyuanId, jifen } = this.data;
this.hidePayMethodModal();
// 如果是积分购买,且积分已满,直接拒绝
if (currentBuyType === 3 && jifen >= 10) {
wx.showToast({
title: '积分已满,无需补充',
icon: 'none'
});
wx.showToast({ title: '积分已满,无需补充', icon: 'none' });
return;
}
if (method === 'wx') {
if (currentBuyType === 1) {
this.handleHuiyuanBuy({
currentTarget: { dataset: { id: currentHuiyuanId, trial: 'false' } }
});
} else if (currentBuyType === 2) {
this.setData({ yajinAmount: currentYajinAmount }, () => {
this.handleYajinPay();
currentTarget: { dataset: { id: currentHuiyuanId, trial: this.data.currentBuyIsTrial ? 'true' : 'false' } },
});
} else if (currentBuyType === 3) {
// ✅ 调用已修正的积分支付函数
this.handleJifenBuy({ currentTarget: { dataset: { disabled: 'false' } } });
}
} else if (method === 'balance') {
@@ -927,7 +864,7 @@ onHide() {
// 🔥 修改点3请求余额抵扣选项前校验积分状态
async fetchBalanceOptions() {
const { currentBuyType, currentHuiyuanId, currentYajinAmount, currentBuyIsTrial, jifen } = this.data;
const { currentBuyType, currentHuiyuanId, currentBuyIsTrial, jifen } = this.data;
if (currentBuyType === 1 && currentBuyIsTrial) {
wx.showToast({ title: '体验会员仅支持微信支付', icon: 'none' });
@@ -952,9 +889,8 @@ onHide() {
data: {
leixing: currentBuyType,
huiyuan_id: currentBuyType === 1 ? currentHuiyuanId : undefined,
is_trial: currentBuyType === 1 ? false : undefined,
yajin_jine: currentBuyType === 2 ? parseInt(currentYajinAmount) : undefined,
}
is_trial: currentBuyType === 1 ? currentBuyIsTrial : undefined,
},
});
if (res.data.code === 200) {
const options = res.data.data || [];
@@ -995,7 +931,7 @@ onHide() {
},
async confirmBalancePay() {
const { selectedBalanceId, currentBuyType, currentHuiyuanId, currentYajinAmount, currentBuyIsTrial } = this.data;
const { selectedBalanceId, currentBuyType, currentHuiyuanId, currentBuyIsTrial } = this.data;
if (!selectedBalanceId) return;
this.hideConfirmModal();
@@ -1010,14 +946,13 @@ onHide() {
shenfen_id: selectedBalanceId,
huiyuan_id: currentBuyType === 1 ? currentHuiyuanId : undefined,
is_trial: currentBuyType === 1 ? currentBuyIsTrial : undefined,
yajin_jine: currentBuyType === 2 ? parseInt(currentYajinAmount) : undefined,
}
},
});
if (res.data.code === 200) {
const responseData = res.data.data || {};
await this.updateAfterPayment(
currentBuyType === 1 ? 'huiyuan' : (currentBuyType === 2 ? 'yajin' : 'jifen'),
currentBuyType === 1 ? 'huiyuan' : 'jifen',
currentBuyType === 1 ? currentHuiyuanId : null,
responseData
);

View File

@@ -1,12 +1,10 @@
{
"usingComponents": {
"global-notification": "/components/global-notification/global-notification"
},
"navigationBarTitleText": "充值中心",
"navigationBarBackgroundColor": "#0a0e2a",
"navigationBarTextStyle": "white",
"backgroundColor": "#0a0e2a",
"backgroundTextStyle": "light",
"enablePullDownRefresh": false,
"onReachBottomDistance": 50
}
"usingComponents": {
"global-notification": "/components/global-notification/global-notification",
"popup-notice": "/components/popup-notice/popup-notice"
},
"navigationBarTitleText": "VIP",
"navigationBarBackgroundColor": "#FFF9F0",
"navigationBarTextStyle": "black",
"backgroundColor": "#FFF9F0"
}

View File

@@ -1,541 +1,210 @@
<!--pages/dashou-chongzhi/index.wxml-->
<view class="page-container">
<!-- ❌ 删除自定义导航栏区块 -->
<!-- VIP 会员 + 积分充值页 -->
<view class="vip-page">
<image wx:if="{{imgUrls.pageBg}}" class="page-bg" src="{{imgUrls.pageBg}}" mode="widthFix" />
<view class="page-bg-fallback" wx:else></view>
<!-- ======================= -->
<!-- VIP会员区域 - 放在上面 -->
<!-- ======================= -->
<view class="vip-section">
<view class="section-header">
<view class="header-decoration">
<view class="dec-line"></view>
<view class="dec-diamond"></view>
<text class="dec-text">VIP会员充值</text>
<view class="dec-diamond"></view>
<view class="dec-line"></view>
<view class="page-body">
<view class="user-row">
<image class="user-avatar" src="{{avatarUrl}}" mode="aspectFill" binderror="onAvatarError" />
<view class="user-info">
<text class="user-name">{{nickname || '打手'}}</text>
<text class="user-id">会员ID: {{uid || '--'}}</text>
</view>
<text class="section-subtitle">选择你的会员</text>
<view class="member-badge">{{memberBadge}}</view>
</view>
<!-- 会员卡片滑动区域 -->
<swiper
class="vip-swiper"
current="{{currentHuiyuanIndex}}"
circular="{{true}}"
previous-margin="120rpx"
next-margin="120rpx"
duration="500"
easing-function="easeOutCubic"
<swiper
class="vip-swiper"
current="{{currentHuiyuanIndex}}"
circular="{{huiyuanList.length > 1}}"
previous-margin="40rpx"
next-margin="40rpx"
duration="400"
bindchange="onSwiperChange">
<swiper-item wx:for="{{huiyuanList}}" wx:key="id">
<view class="vip-card {{index === currentHuiyuanIndex ? 'active' : ''}}"
data-index="{{index}}" bindtap="selectHuiyuan">
<!-- 机甲风格边框 -->
<view class="card-frame">
<view class="frame-corner tl"></view>
<view class="frame-corner tr"></view>
<view class="frame-corner bl"></view>
<view class="frame-corner br"></view>
<view class="frame-line top"></view>
<view class="frame-line right"></view>
<view class="frame-line bottom"></view>
<view class="frame-line left"></view>
</view>
<!-- 卡片内容 -->
<view class="card-content">
<view class="vip-badge" wx:if="{{item.isBought}}">
<text class="badge-text">已拥有</text>
<view class="vip-card {{index === currentHuiyuanIndex ? 'vip-card--active' : ''}}" data-index="{{index}}" bindtap="selectHuiyuan">
<image wx:if="{{item.cardBgUrl}}" class="vip-card-bg-img" src="{{item.cardBgUrl}}" mode="aspectFill" />
<view class="vip-card-bg" wx:else></view>
<view class="vip-card-inner">
<view class="vip-card-left">
<view class="vip-title-row">
<text class="vip-name">{{item.mingzi}}</text>
<view class="vip-status">{{item.isBought ? '已激活' : '未激活'}}</view>
</view>
<view class="vip-price-row">
<text class="vip-currency">¥</text>
<text class="vip-price">{{item.jiage}}</text>
</view>
<text class="vip-validity">有效期 {{item.formal_days || 30}} 天</text>
</view>
<view class="vip-badge trial-badge" wx:if="{{item.can_buy_trial}}">
<text class="badge-text">可购体验</text>
</view>
<view class="vip-badge trial-off-badge" wx:elif="{{item.trial_enabled}}">
<text class="badge-text">体验已用/不可购</text>
</view>
<view class="vip-title">
<text class="title-text">{{item.mingzi}}</text>
<view class="title-underline"></view>
</view>
<view class="vip-price">
<text class="price-symbol">¥</text>
<text class="price-number">{{item.jiage}}</text>
<text class="price-unit">/{{item.formal_days || 30}}天</text>
</view>
<view class="vip-trial-price" wx:if="{{item.trial_enabled || item.can_buy_trial}}">
<text class="trial-price-label">体验</text>
<text class="trial-price-value">¥{{item.trial_price}}/{{item.trial_days}}天</text>
</view>
<view class="vip-features">
<view class="feature-item" wx:for="{{item.features || ['特权功能', '专属标识', '优先接单']}}"
wx:key="index">
<image class="feature-icon" src="/static/images/check-tech.png"></image>
<text class="feature-text">{{item}}</text>
<view class="vip-card-right">
<view class="icon-clip icon-clip-vip" wx:if="{{item.cardImageUrl}}">
<image class="icon-clip-img" src="{{item.cardImageUrl}}" mode="aspectFill" />
</view>
<view class="vip-logo-fallback" wx:else>
<text class="vip-logo-text">VIP</text>
</view>
</view>
</view>
<!-- 选中状态指示器 -->
<view class="card-indicator" wx:if="{{index === currentHuiyuanIndex}}">
<view class="indicator-triangle"></view>
<view class="indicator-glow"></view>
</view>
<view class="vip-shimmer"></view>
</view>
</swiper-item>
</swiper>
<!-- 会员详细介绍 -->
<view class="vip-detail">
<view class="detail-header">
<view class="detail-title">
<image class="detail-icon" src="/static/images/info-tech.png"></image>
<text class="title-text">{{currentHuiyuan.mingzi}} - 会员详情</text>
<view class="section-head">
<view class="section-bar"></view>
<text class="section-title">{{currentHuiyuan.mingzi || '会员'}}规则</text>
</view>
<scroll-view class="rules-scroll" scroll-x enable-flex>
<view class="rules-row">
<view wx:for="{{detailRules}}" wx:key="index" class="rule-card">
<view class="rule-num">{{index + 1}}</view>
<text class="rule-text">{{item}}</text>
</view>
<view class="detail-tech"></view>
</view>
<view class="detail-content">
<scroll-view class="detail-scroll" scroll-y>
<text class="detail-text">{{currentHuiyuan.jieshao || '加载中...'}}</text>
<view class="detail-rules">
<view class="rule-item" wx:for="{{detailRules}}" wx:key="index">
<view class="rule-number">{{index + 1}}</view>
<text class="rule-text">{{item}}</text>
</view>
</view>
</scroll-view>
</scroll-view>
<view class="section-head">
<view class="section-bar"></view>
<text class="section-title">{{currentHuiyuan.mingzi || '会员'}}专属权益</text>
</view>
<view class="benefits-row">
<view wx:for="{{memberBenefits}}" wx:key="title" class="benefit-card">
<view wx:if="{{item.iconUrl}}" class="icon-clip icon-clip-benefit">
<image class="icon-clip-img" src="{{item.iconUrl}}" mode="aspectFill" />
</view>
<text class="benefit-title">{{item.title}}</text>
<text class="benefit-desc">{{item.desc}}</text>
</view>
<!-- 购买区域 - 点击按钮先弹出支付方式选择 -->
<view class="buy-section">
<view class="buy-info">
<view class="price-display">
<!-- 🔥 将“机甲能源”改为“价格” -->
<text class="price-label">价格:</text>
<text class="price-value">¥{{currentHuiyuan.jiage}}</text>
<text class="price-days">/{{currentHuiyuan.formal_days || 30}}天</text>
</view>
<text class="buy-desc" wx:if="{{currentHuiyuan.isBought && currentHuiyuan.buyInfo}}">
已激活,<text class="expire-date">{{currentHuiyuan.buyInfo.daoqi}}</text>后到期
</text>
<text class="buy-desc" wx:else>正式会员支持微信或余额抵扣</text>
<text class="buy-desc trial-hint" wx:if="{{currentHuiyuan.can_buy_trial}}">
体验版仅微信支付 ¥{{currentHuiyuan.trial_price}}/{{currentHuiyuan.trial_days}}天终身1次
</text>
<text class="buy-desc trial-warn" wx:elif="{{!currentHuiyuan.trial_enabled}}">
本俱乐部尚未为该会员开启体验版,请联系管理员在后台配置
</text>
</view>
<view class="section-head">
<view class="section-bar"></view>
<text class="section-title">平台优势</text>
</view>
<view class="advantage-grid">
<view wx:for="{{platformAdvantages}}" wx:key="title" class="advantage-item">
<view wx:if="{{item.iconUrl}}" class="icon-clip icon-clip-advantage">
<image class="icon-clip-img" src="{{item.iconUrl}}" mode="aspectFill" />
</view>
<view class="buy-action">
<view class="tech-buy-btn {{currentHuiyuan.isBought ? 'renew' : ''}}"
bindtap="onBuyHuiyuanClick" data-id="{{currentHuiyuan.id}}" data-trial="false">
<view class="buy-btn-bg"></view>
<view class="buy-btn-glow"></view>
<text class="buy-btn-text">
{{currentHuiyuan.isBought ? '正式续费' : '购买正式版'}}
</text>
<view class="buy-btn-energy">
<view class="energy-dot"></view>
<view class="energy-dot"></view>
<view class="energy-dot"></view>
</view>
</view>
<view
wx:if="{{currentHuiyuan.can_buy_trial}}"
class="tech-buy-btn trial-buy-btn"
bindtap="onBuyHuiyuanClick"
data-id="{{currentHuiyuan.id}}"
data-trial="true"
>
<view class="buy-btn-bg"></view>
<text class="buy-btn-text">购买体验版</text>
</view>
<text class="advantage-title">{{item.title}}</text>
<text class="advantage-desc">{{item.desc}}</text>
</view>
</view>
<view id="jifen-section" class="jifen-section">
<view class="section-head">
<view class="section-bar"></view>
<text class="section-title">积分充值</text>
</view>
<view class="jifen-card">
<view class="jifen-left">
<text class="jifen-label">当前积分</text>
<text class="jifen-value">{{jifen}}</text>
<text class="jifen-tip" wx:if="{{jifen < 10}}">积分不足将影响接单与提现</text>
<text class="jifen-tip jifen-tip--ok" wx:else>积分充足</text>
</view>
<view class="jifen-btn {{jifen >= 10 ? 'jifen-btn--disabled' : ''}}" bindtap="onJifenClick" data-disabled="{{jifen >= 10}}">
{{jifen >= 10 ? '已满' : '补充积分'}}
</view>
</view>
</view>
<view class="owned-section" wx:if="{{clubmber.length > 0}}">
<view class="section-head">
<view class="section-bar"></view>
<text class="section-title">我的会员</text>
</view>
<view wx:for="{{clubmber}}" wx:key="huiyuanid" class="owned-item" data-item="{{item}}" bindtap="showMemberDetail">
<text class="owned-name">{{item.huiyuanming}}</text>
<text class="owned-expire">到期 {{formatDaoqiTime(item.daoqi)}}</text>
</view>
</view>
</view>
<!-- ======================= -->
<!-- 三卡片区域 - 放在下面 -->
<!-- ======================= -->
<view class="tech-grid">
<!-- 会员区域 - 高度限制最多3个超出可滚动 -->
<view class="tech-card huiyuan-card">
<view class="card-header">
<view class="card-title">
<text class="title-text">我的会员</text>
<view class="title-text">👑</view>
</view>
<view class="card-badge">{{clubmber.length}}</view>
<view class="footer-bar">
<view class="deposit-banner" bindtap="goToDeposit">
<text class="deposit-banner-text">缴纳履约金,快人一步</text>
<text class="deposit-banner-link">去缴纳 ></text>
</view>
<view class="agree-row" bindtap="toggleAgree">
<view class="agree-check {{agreed ? 'agree-check--on' : ''}}">{{agreed ? '✓' : ''}}</view>
<text class="agree-text">已阅读并同意</text>
<text class="agree-link">《{{currentHuiyuan.mingzi || '会员'}}协议》</text>
</view>
<view class="buy-row">
<view
wx:if="{{currentHuiyuan.can_buy_trial}}"
class="buy-btn buy-btn--outline"
bindtap="onTapTrial"
data-id="{{currentHuiyuan.id}}"
data-trial="true">
体验会员 (¥{{currentHuiyuan.trial_price}})
</view>
<scroll-view
class="huiyuan-scroll"
scroll-y
enable-flex
style="height: {{huiyuanListHeight}}rpx">
<view wx:for="{{clubmber}}" wx:key="huiyuanid" class="huiyuan-item" data-item="{{item}}" bindtap="showMemberDetail">
<view class="huiyuan-tag tech-tag">
<view class="tag-triangle"></view>
<text class="tag-name">{{item.huiyuanming}}</text>
<text class="tag-time">到期: {{formatDaoqiTime(item.daoqi)}}</text>
<view class="tag-glow"></view>
</view>
</view>
<view wx:if="{{clubmber.length === 0}}" class="empty-huiyuan">
<image class="empty-icon" src="/static/images/empty-member.png"></image>
<text class="empty-text">暂无会员</text>
</view>
</scroll-view>
<view class="card-footer">
<text class="footer-text">共{{clubmber.length}}个会员</text>
<view class="footer-line"></view>
<view
class="buy-btn buy-btn--primary {{currentHuiyuan.can_buy_trial ? '' : 'buy-btn--full'}}"
bindtap="onTapFormal"
data-id="{{currentHuiyuan.id}}"
data-trial="false">
{{currentHuiyuan.isBought ? '续费正式会员' : '升级正式会员'}} (¥{{currentHuiyuan.jiage}})
<view class="buy-btn-shimmer"></view>
</view>
</view>
<!-- 押金区域 - 点击充值按钮弹出押金输入弹窗 -->
<view class="tech-card yajin-card">
<view class="card-header">
<view class="card-title">
<text class="title-text">我的押金</text>
<view class="title-text">💰</view>
</view>
<view class="card-corner"></view>
</view>
<view class="yajin-display">
<view class="amount-container">
<text class="amount-symbol">¥</text>
<text class="amount-number">{{yajin}}</text>
</view>
<text class="amount-unit">可用余额</text>
</view>
<view class="tech-line"></view>
<view class="action-container">
<view class="tech-btn yajin-btn" bindtap="onYajinClick">
<view class="btn-bg"></view>
<text class="btn-text">立即充值</text>
<view class="btn-arrow" style="display:none;">➤</view>
<view class="btn-glow"></view>
</view>
</view>
<view class="card-corner corner-bottom"></view>
</view>
<!-- 积分区域 - 点击补充按钮弹出支付方式选择 -->
<view class="tech-card jifen-card">
<view class="card-header">
<view class="card-title">
<text class="title-text">我的积分</text>
<view class="title-text">⭐</view>
</view>
</view>
<view class="jifen-display">
<view class="circle-progress">
<view class="circle-bg"></view>
<view class="circle-mask" style="transform: rotate({{jifenProgress}}deg);"></view>
<view class="circle-fill" style="transform: rotate({{jifenProgress}}deg);"></view>
<view class="circle-center">
<text class="jifen-value">{{jifen}}</text>
<text class="jifen-label">积分</text>
</view>
<view class="circle-dots">
<view class="circle-dot" wx:for="{{10}}" wx:key="index"
style="transform: rotate({{index * 36}}deg);"></view>
</view>
</view>
<view class="jifen-status">
<text class="status-text" wx:if="{{jifen < 10}}">积分不足,影响接单,提现权限</text>
<text class="status-text full" wx:else>积分充足,无需补充</text>
</view>
</view>
<view class="action-container">
<view class="tech-btn jifen-btn" bindtap="onJifenClick" data-disabled="{{jifen >= 10}}">
<view class="btn-bg"></view>
<text class="btn-text">{{jifen >= 10 ? '积分已满' : '立即补充'}}</text>
<view class="btn-energy" wx:if="{{jifen < 10}}"></view>
<view class="btn-glow" wx:if="{{jifen < 10}}"></view>
</view>
</view>
</view>
</view>
<!-- ======================= -->
<!-- 押金充值弹窗(原有,确认事件改为 onYajinConfirm -->
<!-- ======================= -->
<view class="tech-modal" wx:if="{{showYajinModal}}">
<view class="modal-backdrop" bindtap="hideYajinModal"></view>
<view class="modal-container">
<view class="modal-corner tl"></view>
<view class="modal-corner tr"></view>
<view class="modal-corner bl"></view>
<view class="modal-corner br"></view>
<view class="modal-header">
<text class="modal-title">押金充值</text>
<text class="modal-subtitle">充值保证金</text>
<view class="modal-close" bindtap="hideYajinModal">
<text class="close-text">✕</text>
</view>
</view>
<view class="modal-body">
<view class="input-section">
<view class="input-label">
<image class="label-icon" src="/static/images/money-tech.png"></image>
<text class="label-text">充值金额 (1-10000元)</text>
</view>
<view class="input-container">
<view class="input-prefix">¥</view>
<input
class="yajin-input"
type="digit"
placeholder="输入充值金额"
placeholder-class="input-placeholder"
value="{{yajinAmount}}"
bindinput="onYajinInput"
maxlength="5"
focus="{{showYajinModal}}"/>
<view class="input-underline"></view>
</view>
<text class="input-tip">支持1-10000元整数充值</text>
</view>
<view class="quick-section">
<text class="quick-title">快速选择</text>
<view class="quick-buttons">
<view
class="quick-btn {{yajinAmount == '100' ? 'active' : ''}}"
bindtap="setYajinAmount"
data-amount="100">
<text class="quick-text">100元</text>
</view>
<view
class="quick-btn {{yajinAmount == '500' ? 'active' : ''}}"
bindtap="setYajinAmount"
data-amount="500">
<text class="quick-text">500元</text>
</view>
<view
class="quick-btn {{yajinAmount == '1000' ? 'active' : ''}}"
bindtap="setYajinAmount"
data-amount="1000">
<text class="quick-text">1000元</text>
</view>
<view
class="quick-btn {{yajinAmount == '5000' ? 'active' : ''}}"
bindtap="setYajinAmount"
data-amount="5000">
<text class="quick-text">5000元</text>
</view>
</view>
</view>
</view>
<view class="modal-footer">
<view class="modal-btn cancel-btn" bindtap="hideYajinModal">
<text class="btn-text">取消</text>
</view>
<view class="modal-divider"></view>
<view class="modal-btn confirm-btn" bindtap="onYajinConfirm">
<text class="btn-text">确认支付</text>
<view class="btn-sparkle"></view>
</view>
</view>
</view>
</view>
<!-- ====== 支付方式选择弹窗 ====== -->
<view class="tech-modal" wx:if="{{showPayMethodModal}}">
<view class="modal-backdrop" bindtap="hidePayMethodModal"></view>
<view class="modal-container small">
<view class="modal-corner tl"></view>
<view class="modal-corner tr"></view>
<view class="modal-corner bl"></view>
<view class="modal-corner br"></view>
<view class="modal-header">
<text class="modal-title">选择支付方式</text>
<view class="modal-close" bindtap="hidePayMethodModal">
<text class="close-text">✕</text>
</view>
</view>
<view class="modal-body">
<view class="pay-method-list">
<view class="pay-method-item" bindtap="onPayMethodSelect" data-method="wx">
<image class="method-icon" src="/static/images/wechat-pay.png"></image>
<text class="method-name">微信支付</text>
<text class="method-desc">安全快捷</text>
</view>
<view class="pay-method-item" bindtap="onPayMethodSelect" data-method="balance">
<image class="method-icon" src="/static/images/balance-pay.png"></image>
<text class="method-name">余额抵扣</text>
<text class="method-desc">使用佣金或分红</text>
</view>
</view>
</view>
</view>
</view>
<!-- ====== 余额抵扣身份选择弹窗 ====== -->
<view class="tech-modal" wx:if="{{showBalanceModal}}">
<view class="modal-backdrop" bindtap="hideBalanceModal"></view>
<view class="modal-container">
<view class="modal-corner tl"></view>
<view class="modal-corner tr"></view>
<view class="modal-corner bl"></view>
<view class="modal-corner br"></view>
<view class="modal-header">
<text class="modal-title">选择抵扣身份</text>
<view class="modal-close" bindtap="hideBalanceModal">
<text class="close-text">✕</text>
</view>
</view>
<view class="modal-body">
<view class="balance-list">
<view wx:for="{{balanceOptions}}" wx:key="id" class="balance-item"
data-id="{{item.id}}" bindtap="onBalanceSelect">
<view class="balance-info">
<text class="balance-name">{{item.jieshao}}</text>
<text class="balance-amount">需¥{{item.xuyao}}</text>
</view>
<view class="balance-arrow">➤</view>
</view>
</view>
</view>
</view>
</view>
<!-- ====== 余额抵扣确认弹窗 ====== -->
<view class="tech-modal" wx:if="{{showConfirmModal}}">
<view class="modal-backdrop" bindtap="hideConfirmModal"></view>
<view class="modal-container">
<view class="modal-corner tl"></view>
<view class="modal-corner tr"></view>
<view class="modal-corner bl"></view>
<view class="modal-corner br"></view>
<view class="modal-header">
<text class="modal-title">确认抵扣</text>
<view class="modal-close" bindtap="hideConfirmModal">
<text class="close-text">✕</text>
</view>
</view>
<view class="modal-body">
<view class="confirm-detail">
<view class="detail-row">
<text class="detail-label">抵扣身份:</text>
<text class="detail-value">{{selectedBalanceInfo && selectedBalanceInfo.jieshao}}</text>
</view>
<view class="detail-row">
<text class="detail-label">所需金额:</text>
<text class="detail-value">¥{{selectedBalanceInfo && selectedBalanceInfo.xuyao}}</text>
</view>
<view class="detail-row">
<text class="detail-label">实际扣除:</text>
<text class="detail-value">¥{{selectedBalanceInfo && selectedBalanceInfo.xuyao}}</text>
</view>
<view class="detail-tip">确认后将从您的余额中扣除</view>
</view>
</view>
<view class="modal-footer">
<view class="modal-btn cancel-btn" bindtap="hideConfirmModal">
<text class="btn-text">取消</text>
</view>
<view class="modal-divider"></view>
<view class="modal-btn confirm-btn" bindtap="confirmBalancePay">
<text class="btn-text">确认支付</text>
<view class="btn-sparkle"></view>
</view>
</view>
</view>
</view>
<!-- ====== 会员详情弹窗 ====== -->
<view class="tech-modal" wx:if="{{showMemberModal}}">
<view class="modal-backdrop" bindtap="hideMemberModal"></view>
<view class="modal-container">
<view class="modal-corner tl"></view>
<view class="modal-corner tr"></view>
<view class="modal-corner bl"></view>
<view class="modal-corner br"></view>
<view class="modal-header">
<text class="modal-title">会员详情</text>
<view class="modal-close" bindtap="hideMemberModal">
<text class="close-text">✕</text>
</view>
</view>
<view class="modal-body">
<view class="member-detail">
<view class="detail-row">
<text class="detail-label">会员名称:</text>
<text class="detail-value">{{currentMemberDetail && currentMemberDetail.huiyuanming}}</text>
</view>
<view class="detail-row">
<text class="detail-label">到期时间:</text>
<text class="detail-value">{{currentMemberDetail && currentMemberDetail.daoqi}}</text>
</view>
<view class="detail-row">
<text class="detail-label">剩余天数:</text>
<text class="detail-value">{{formatRemainTime(currentMemberDetail && currentMemberDetail.daoqi)}}</text>
</view>
</view>
</view>
</view>
</view>
<!-- ❌ 删除“进入提示弹窗”整个区块 -->
<!-- ======================= -->
<!-- 支付加载动画(原有) -->
<!-- ======================= -->
<view class="tech-loading" wx:if="{{payLoading}}">
<view class="loading-backdrop"></view>
<view class="loading-content">
<view class="loading-spinner">
<view class="spinner-ring ring-1"></view>
<view class="spinner-ring ring-2"></view>
<view class="spinner-ring ring-3"></view>
<view class="spinner-core"></view>
<view class="spinner-energy"></view>
</view>
<text class="loading-text">{{loadingText}}</text>
<text class="loading-subtext">正在连接支付系统...</text>
</view>
</view>
<!-- ======================= -->
<!-- 底部机甲装饰 -->
<!-- ======================= -->
<view class="tech-footer">
<view class="footer-line"></view>
<view class="footer-text">星阙网络 © 科技</view>
</view>
</view>
<!-- 通知组件 -->
<global-notification id="global-notification" />
<!-- 支付方式 -->
<view class="modal-mask" wx:if="{{showPayMethodModal}}" bindtap="hidePayMethodModal">
<view class="modal-panel" catchtap="stopPropagation">
<text class="modal-title">选择支付方式</text>
<view class="pay-method-item" bindtap="onPayMethodSelect" data-method="wx">
<text class="pay-method-name">微信支付</text>
<text class="pay-method-desc">安全快捷</text>
</view>
<view class="pay-method-item" bindtap="onPayMethodSelect" data-method="balance">
<text class="pay-method-name">余额抵扣</text>
<text class="pay-method-desc">使用佣金或分红</text>
</view>
</view>
</view>
<!-- 🆕 统一弹窗组件 -->
<popup-notice id="popupNotice" />
<view class="modal-mask" wx:if="{{showBalanceModal}}" bindtap="hideBalanceModal">
<view class="modal-panel" catchtap="stopPropagation">
<text class="modal-title">选择抵扣身份</text>
<view wx:for="{{balanceOptions}}" wx:key="id" class="balance-item" bindtap="onBalanceSelect" data-id="{{item.id}}">
<text>{{item.jieshao}}</text>
<text class="balance-need">需¥{{item.xuyao}}</text>
</view>
</view>
</view>
<view class="modal-mask" wx:if="{{showConfirmModal}}" bindtap="hideConfirmModal">
<view class="modal-panel" catchtap="stopPropagation">
<text class="modal-title">确认抵扣</text>
<view class="confirm-row"><text>身份</text><text>{{selectedBalanceInfo.jieshao}}</text></view>
<view class="confirm-row"><text>金额</text><text>¥{{selectedBalanceInfo.xuyao}}</text></view>
<view class="modal-actions">
<view class="modal-btn cancel" bindtap="hideConfirmModal">取消</view>
<view class="modal-btn confirm" bindtap="confirmBalancePay">确认支付</view>
</view>
</view>
</view>
<view class="modal-mask" wx:if="{{showMemberModal}}" bindtap="hideMemberModal">
<view class="modal-panel" catchtap="stopPropagation">
<text class="modal-title">会员详情</text>
<view class="confirm-row"><text>名称</text><text>{{currentMemberDetail.huiyuanming}}</text></view>
<view class="confirm-row"><text>到期</text><text>{{currentMemberDetail.daoqi}}</text></view>
<view class="confirm-row"><text>剩余</text><text>{{formatRemainTime(currentMemberDetail.daoqi)}}</text></view>
</view>
</view>
<view class="loading-mask" wx:if="{{payLoading}}">
<view class="loading-box">
<view class="loading-spinner"></view>
<text>{{loadingText}}</text>
</view>
</view>
<global-notification id="global-notification" />
<popup-notice id="popupNotice" />

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
// pages/dashouzhongxin/dashouzhongxin.js
import { createPage, request, isRoleStatusActive, isCenterPageActive, syncRoleStatuses, syncProfileFields, syncGroupFields, ensureRoleOnCenterPage, clearCacheAndEnterNormal, lockPrimaryRole, migrateLegacyCenterRole, enterLockedRole, parseSceneOptions } from '../../utils/base-page.js'
import { resolveAvatarUrl, getDefaultAvatarUrl } from '../../utils/avatar.js'
import { resolveAvatarUrl } from '../../utils/avatar.js'
import { fetchMyZhidingOrders, processZhidingList, filterZhidingBannerList } from '../../utils/zhiding-order.js'
import { openPrivateChat, buildInviterPeerId } from '../../utils/im-user.js'
import { isStaffMode, getStaffContext } from '../../utils/staff-api.js'
@@ -8,19 +8,18 @@ import { ensurePhoneAuth } from '../../utils/phone-auth.js'
import {
ICON_KEYS,
resolveMiniappIcon,
resolveConfiguredIcon,
refreshPindaoConfig,
getPindaoConfig,
resolvePindaoImages,
warmupPindaoConfig,
PINDAO_ICON_FALLBACK,
defaultIconRel,
ICON_FOLDER,
} from '../../utils/miniapp-icons.js'
import { getDefaultAvatarUrl } from '../../utils/avatar.js'
const PLATFORM_INVITE_CODE = '0000008RffVgKHMj7kQC'
/** 会员/保证金横幅 COS 兜底(后台未上传时仍显示) */
const FIGHTER_BANNER_VIP_FALLBACK = 'https://bintao-1308403501.cos.ap-guangzhou.myqcloud.com/uploads/images/20260512123427531240452.png'
const FIGHTER_BANNER_DEPOSIT_FALLBACK = 'https://bintao-1308403501.cos.ap-guangzhou.myqcloud.com/uploads/images/202605121234283091d3980.png'
const app = getApp()
Page(createPage({
data: {
@@ -35,8 +34,7 @@ Page(createPage({
shangjiaCertified: false,
totalAssets: '0.00',
assetBreakdown: [],
pendingAuthList: [],
showAuthSection: false,
moreFuncList: [],
inviteCode: '',
guanshiInviteCode: '',
zuzhangInviteCode: '',
@@ -94,111 +92,58 @@ Page(createPage({
showRechargeBanners: false,
showPindaoEntry: true,
userBg: '',
qiepianBanner: '',
ksIcon: '',
penaltyTipIcon: '',
followExpanded: false,
followClass: '',
pendingPenaltyCount: 0,
myZhidingList: [],
myZhidingCount: 0,
showBadgeZone: false,
},
_syncBadgeZoneFlags(patch = {}) {
const d = { ...this.data, ...patch };
const showBadgeZone = !!(
(d.chenghaoList && d.chenghaoList.length > 0)
|| (d.isGuanshi && d.guanshiChenghaoList && d.guanshiChenghaoList.length > 0)
|| (d.identityTagList && d.identityTagList.length > 0)
);
return { ...patch, showBadgeZone };
orderNavXym: [],
tradeNavXym: [],
inviteNavXym: [],
},
_buildImgUrls(ossImageUrl) {
const app = getApp();
const dsBase = ossImageUrl + 'beijing/dashouduan/';
const iconBase = ossImageUrl + 'beijing/dashouduan/dashoutubiaobeijing/';
const gsBase = ossImageUrl + 'beijing/guanshiduan/';
const khBase = ossImageUrl + 'beijing/kaohe/';
const icon = (key, fallback) => resolveMiniappIcon(app, key, fallback);
const icon = (key, fallback) => resolveMiniappIcon(app, key, fallback || defaultIconRel(key));
return {
pageBg: dsBase + 'page-bg.jpg',
userCardBg: dsBase + 'user-card-bg.png',
vipCardBg: dsBase + 'vip-card-bg.jpg',
assetPanelBg: dsBase + 'asset-panel-bg.png',
rankHubBg: dsBase + 'rank-hub-bg.png',
rankTileBg: dsBase + 'rank-tile-bg.png',
funcPanelBg: dsBase + 'func-panel-bg.png',
listBg: dsBase + 'list-card-bg.png',
topBg: iconBase + 'top-bg.jpg',
cardBg: iconBase + 'card-bg.jpg',
iconRefresh: icon(ICON_KEYS.ICON_REFRESH, gsBase + 'icon-refresh.png'),
iconCopy: gsBase + 'icon-copy.png',
iconVip: dsBase + 'icon-vip.png',
iconArrowLight: dsBase + 'icon-arrow-light.png',
iconSectionAsset: dsBase + 'icon-section-asset.png',
iconSectionRank: dsBase + 'icon-section-rank.png',
iconSectionFunc: dsBase + 'icon-section-func.png',
iconSectionGuanshi: dsBase + 'icon-section-guanshi.png',
iconSectionZuzhang: dsBase + 'icon-section-zuzhang.png',
iconSectionKaohe: dsBase + 'icon-section-kaohe.png',
iconSectionMore: dsBase + 'icon-section-more.png',
iconRankDashou: dsBase + 'rank-dashou.png',
iconRankGuanshi: dsBase + 'rank-guanshi.png',
iconRankZuzhang: dsBase + 'rank-zuzhang.png',
iconRankShangjia: dsBase + 'rank-shangjia.png',
iconGame: iconBase + 'icon-game.jpg',
iconRecharge: iconBase + 'icon-recharge.jpg',
iconOrders: iconBase + 'icon-orders.jpg',
iconPunish: iconBase + 'icon-punish.jpg',
iconRank: iconBase + 'icon-rank.jpg',
iconInvite: gsBase + 'icon-invite.png',
iconMedal: iconBase + 'icon-medal.jpg',
iconEdit: iconBase + 'icon-edit.jpg',
iconBook: iconBase + 'icon-book.jpg',
iconArrow: gsBase + 'icon-arrow.png',
iconSub: gsBase + 'icon-sub.png',
iconRecord: gsBase + 'icon-record.png',
iconPoster: gsBase + 'icon-poster.png',
iconWithdraw: gsBase + 'icon-withdraw.png',
iconContact: gsBase + 'icon-contact.png',
avatarDefault: ossImageUrl + 'avatar/default.jpg',
iconClear: ossImageUrl + 'beijing/tubiao/grzx_qingchu.jpg',
iconSwitch: '/images/_exit.png',
iconKefu: ossImageUrl + 'beijing/tubiao/grzx_kefu.jpg',
iconKuaishou: ossImageUrl + 'beijing/tubiao/grzx_guanzhualong.jpg',
iconPindao: icon(ICON_KEYS.MINE_PINDAO, ossImageUrl + PINDAO_ICON_FALLBACK),
iconKaoheDafen: khBase + 'daofen.png',
iconKaoheJilu: khBase + 'jilu.png',
iconKaoheZhongxin: khBase + 'zhongxin.png',
iconShangjia: ossImageUrl + 'beijing/tubiao/grzx_shangjia.jpg',
iconDashouAuth: ossImageUrl + 'beijing/tubiao/grzx_dashou.jpg',
iconGuanshiAuth: ossImageUrl + 'beijing/tubiao/grzx_guanshi.jpg',
iconZuzhangAuth: ossImageUrl + 'beijing/tubiao/grzx_zuzhang.jpg',
kefuBannerBg: dsBase + 'kefu-banner-bg.png',
totalAssetBg: dsBase + 'total-asset-bg.png',
authPanelBg: dsBase + 'auth-panel-bg.png',
bannerVip: resolveConfiguredIcon(app, ICON_KEYS.FIGHTER_RECHARGE_MEMBER) || FIGHTER_BANNER_VIP_FALLBACK,
bannerDeposit: resolveConfiguredIcon(app, ICON_KEYS.FIGHTER_RECHARGE_DEPOSIT) || FIGHTER_BANNER_DEPOSIT_FALLBACK,
iconRefresh: icon(ICON_KEYS.ICON_REFRESH, 'beijing/guanshiduan/icon-refresh.png'),
iconCopy: icon(ICON_KEYS.FIGHTER_MINE_COPY, 'beijing/guanshiduan/icon-copy.png'),
iconEdit: icon(ICON_KEYS.FIGHTER_MINE_EDIT, 'beijing/dashouduan/dashoutubiaobeijing/icon-edit.jpg'),
iconPunish: icon(ICON_KEYS.FIGHTER_MINE_PUNISH, 'beijing/dashouduan/dashoutubiaobeijing/icon-punish.jpg'),
iconMedal: icon(ICON_KEYS.FIGHTER_MINE_MEDAL, 'beijing/dashouduan/dashoutubiaobeijing/icon-medal.jpg'),
iconBook: icon(ICON_KEYS.FIGHTER_MINE_BOOK, 'beijing/dashouduan/dashoutubiaobeijing/icon-book.jpg'),
iconRank: icon(ICON_KEYS.FIGHTER_MINE_RANK, 'beijing/dashouduan/dashoutubiaobeijing/icon-rank.jpg'),
iconInvite: icon(ICON_KEYS.FIGHTER_MINE_INVITE, 'beijing/guanshiduan/icon-invite.png'),
iconContact: icon(ICON_KEYS.FIGHTER_MINE_CONTACT, 'beijing/guanshiduan/icon-contact.png'),
iconKefu: icon(ICON_KEYS.FIGHTER_MINE_KEFU, 'beijing/tubiao/grzx_kefu.jpg'),
iconPindao: icon(ICON_KEYS.MINE_PINDAO, PINDAO_ICON_FALLBACK),
iconKaoheDafen: icon(ICON_KEYS.FIGHTER_MINE_KAOHE_DAFEN, 'beijing/kaohe/daofen.png'),
iconKaoheJilu: icon(ICON_KEYS.FIGHTER_MINE_KAOHE_JILU, 'beijing/kaohe/jilu.png'),
iconKaoheZhongxin: icon(ICON_KEYS.FIGHTER_MINE_KAOHE_ZHONGXIN, 'beijing/kaohe/zhongxin.png'),
iconShangjia: icon(ICON_KEYS.FIGHTER_MINE_SHANGJIA, 'beijing/tubiao/grzx_shangjia.jpg'),
iconDashouAuth: icon(ICON_KEYS.FIGHTER_MINE_DASHOU_AUTH, 'beijing/tubiao/grzx_dashou.jpg'),
iconClear: icon(ICON_KEYS.FIGHTER_MINE_CLEAR, 'beijing/tubiao/grzx_qingchu.jpg'),
iconSwitch: icon(ICON_KEYS.FIGHTER_MINE_SWITCH, `${ICON_FOLDER}/fighter_mine_switch.png`),
iconRecord: icon(ICON_KEYS.FIGHTER_MINE_RECORD, 'beijing/guanshiduan/icon-record.png'),
bannerVip: icon(ICON_KEYS.FIGHTER_RECHARGE_MEMBER, `${ICON_FOLDER}/fighter_recharge_member.png`),
bannerDeposit: icon(ICON_KEYS.FIGHTER_RECHARGE_DEPOSIT, `${ICON_FOLDER}/fighter_recharge_deposit.png`),
avatarDefault: getDefaultAvatarUrl(app),
};
},
_applyRankBoardIcons(imgUrls) {
const iconMap = {
dashou: imgUrls.iconRankDashou,
guanshi: imgUrls.iconRankGuanshi,
zuzhang: imgUrls.iconRankZuzhang,
shangjia: imgUrls.iconRankShangjia,
};
return (this.data.rankBoardList || []).map((item) => ({
...item,
icon: iconMap[item.type] || imgUrls.iconRank,
}));
},
onLoad(options) {
const app = getApp();
const sys = wx.getSystemInfoSync();
const ossImageUrl = app.globalData.ossImageUrl || '';
const imgUrls = this._buildImgUrls(ossImageUrl);
const nav = this._buildNavLists(app);
this.setData({
imgUrls,
rankBoardList: this._applyRankBoardIcons(imgUrls),
...nav,
statusBar: sys.statusBarHeight || 20,
navBar: (sys.statusBarHeight || 20) + 44,
});
@@ -225,15 +170,48 @@ Page(createPage({
this.syncConfiguredAssets();
},
_buildNavLists(app) {
const icon = (key) => resolveMiniappIcon(app, key, defaultIconRel(key));
return {
orderNavXym: [
{ name: '待完成', statusKey: 'jinxingzhong', icon: icon(ICON_KEYS.FIGHTER_ORDER_PENDING), badge: 0, showBadge: false },
{ name: '待结算', statusKey: 'jiesuanzhong', icon: icon(ICON_KEYS.FIGHTER_ORDER_SETTLING), badge: 0, showBadge: false },
{ name: '已完成', statusKey: 'yiwancheng', icon: icon(ICON_KEYS.FIGHTER_ORDER_DONE), badge: 0, showBadge: false },
{ name: '已关闭', statusKey: 'yituikuan', icon: icon(ICON_KEYS.FIGHTER_ORDER_CLOSED), badge: 0, showBadge: false },
],
tradeNavXym: [
{ name: '佣金记录', type: 'commission', icon: icon(ICON_KEYS.FIGHTER_TRADE_COMMISSION) },
{ name: '提现记录', type: 'withdraw', icon: icon(ICON_KEYS.FIGHTER_TRADE_WITHDRAW) },
{ name: '结算记录', type: 'settle', icon: icon(ICON_KEYS.FIGHTER_TRADE_SETTLE) },
{ name: '扣款记录', type: 'deduct', icon: icon(ICON_KEYS.FIGHTER_TRADE_DEDUCT) },
{ name: '充值记录', type: 'recharge', icon: icon(ICON_KEYS.FIGHTER_TRADE_RECHARGE) },
],
inviteNavXym: [
{ name: '我的下级', action: 'subordinate', icon: icon(ICON_KEYS.FIGHTER_INVITE_SUBORDINATE) },
{ name: '推广海报', action: 'poster', icon: icon(ICON_KEYS.FIGHTER_INVITE_POSTER) },
{ name: '邀请码', action: 'inviteCode', icon: icon(ICON_KEYS.FIGHTER_INVITE_CODE) },
],
ksIcon: icon(ICON_KEYS.FIGHTER_KUAISHOU_CASH),
qiepianBanner: icon(ICON_KEYS.FIGHTER_MINE_QIEPIAN),
penaltyTipIcon: icon(ICON_KEYS.FIGHTER_MINE_PENALTY_TIP),
};
},
syncConfiguredAssets() {
const app = getApp();
const bannerVip = resolveConfiguredIcon(app, ICON_KEYS.FIGHTER_RECHARGE_MEMBER) || FIGHTER_BANNER_VIP_FALLBACK;
const bannerDeposit = resolveConfiguredIcon(app, ICON_KEYS.FIGHTER_RECHARGE_DEPOSIT) || FIGHTER_BANNER_DEPOSIT_FALLBACK;
const imgUrls = { ...this.data.imgUrls, bannerVip, bannerDeposit };
const ossImageUrl = app.globalData.ossImageUrl || '';
const imgUrls = this._buildImgUrls(ossImageUrl);
const nav = this._buildNavLists(app);
const bannerVip = imgUrls.bannerVip;
const bannerDeposit = imgUrls.bannerDeposit;
this.setData({
imgUrls,
...nav,
showRechargeBanners: !!(bannerVip || bannerDeposit),
showPindaoEntry: this.data.isDashou || this.data.isGuanshi || this.data.isZuzhang || this.data.isKaoheguan,
// showPindaoEntry: ... || this.data.isKaoheguan 临时隐藏考核官
showPindaoEntry: this.data.isDashou || this.data.isGuanshi || this.data.isZuzhang,
}, () => {
this._buildMoreFuncList();
});
},
@@ -257,6 +235,7 @@ Page(createPage({
warmupPindaoConfig(app);
this.checkRoleStatuses();
this.syncConfiguredAssets();
this.loadPenaltyCount();
if (isCenterPageActive(this, 'isDashou', 'dashoustatus')) {
if (!this.data.isDashou) this.setData({ isDashou: true });
ensureRoleOnCenterPage(this, 'dashou');
@@ -299,8 +278,7 @@ Page(createPage({
layoutSparse: subRoleCount === 0,
}, () => {
this._updateTotalAssets();
this._updatePendingAuth();
this.setData(this._syncBadgeZoneFlags());
this._buildMoreFuncList();
});
if (isDashou) {
const uid = wx.getStorageSync('uid') || '';
@@ -326,43 +304,82 @@ Page(createPage({
total += this._parseMoney(d.ketixian);
breakdown.push({ label: '组长余额', amount: d.ketixian || '0.00' });
}
if (d.isKaoheguan) {
total += this._parseMoney(d.kaoheYue);
breakdown.push({ label: '考核余额', amount: d.kaoheYue || '0.00' });
}
// 临时隐藏考核官余额展示,恢复时取消注释
// if (d.isKaoheguan) {
// total += this._parseMoney(d.kaoheYue);
// breakdown.push({ label: '考核余额', amount: d.kaoheYue || '0.00' });
// }
this.setData({ totalAssets: total.toFixed(2), assetBreakdown: breakdown });
},
/** 打手端:已认证不展示;商家始终第一位 */
_updatePendingAuth() {
/** 更多功能:常用优先,按身份动态展示 */
_buildMoreFuncList() {
const d = this.data;
const img = d.imgUrls || {};
const list = [];
list.push({
type: 'shangjia',
name: '商家',
icon: img.iconShangjia,
tag: d.shangjiaCertified ? '进入商家端' : '去认证',
done: d.shangjiaCertified,
});
list.push({
type: 'staff',
name: '商家客服',
icon: img.iconKefu || img.iconShangjia,
tag: isStaffMode() ? '进入工作台' : '去入驻',
done: isStaffMode(),
});
if (!d.isGuanshi) {
list.push({ type: 'guanshi', name: '管事', icon: img.iconGuanshiAuth, tag: '去认证' });
const push = (action, name, icon, extra = {}) => {
list.push({ action, name, icon, ...extra });
};
if (d.isZuzhang) {
push('goToYaoqingGuanshi', '邀请管事', img.iconInvite);
}
// 组长由后台添加,前端不再展示「组长认证」入口
push('contactInviter', '联系管事', img.iconInvite);
if (d.isGuanshi) {
push('contactZuzhang', '联系组长', img.iconContact);
}
push('goToKefu', '在线客服', img.iconKefu);
push('onTapShangjiaAuth', d.shangjiaCertified ? '进入商家端' : '商家认证', img.iconShangjia);
push('onTapStaffAuth', isStaffMode() ? '商家客服工作台' : '商家客服入驻', img.iconKefu || img.iconShangjia);
if (d.showPindaoEntry) {
push('openPindaoModal', '频道', img.iconPindao);
}
push('goToMyPunishment', '我的处罚', img.iconPunish);
// push('goToKaohe', '考核金牌', img.iconMedal); // 临时隐藏,恢复时取消注释
push('goToDashouExam', '接单考试', img.iconBook);
push('goToRanking', '总排行榜', img.iconRank, { rankType: 'dashou' });
// 会员记录 / 分红记录已合并至「佣金记录」页 Tab 切换
// 临时隐藏考核官入口,恢复时取消注释
// if (d.isKaoheguan) {
// push('goToKaoheDafen', '考核打分', img.iconKaoheDafen);
// push('goToKaoheJilu', '考核记录', img.iconKaoheJilu);
// push('goToKaoheZhongxin', '考核中心', img.iconKaoheZhongxin);
// }
if (!d.isDashou) {
list.push({ type: 'dashou', name: '接单员', icon: img.iconDashouAuth, tag: '去认证' });
push('goToAuth', '接单员认证', img.iconDashouAuth, { authType: 'dashou' });
}
push('goToRules', '用户规则', img.iconBook);
push('switchToNormal', '返回点单端', img.iconSwitch);
push('clearCache', '退出登录', img.iconClear);
this.setData({ moreFuncList: list });
},
onMoreFuncTap(e) {
const { action, authType, rankType } = e.currentTarget.dataset;
if (action === 'goToAuth' && authType) {
this.goToAuth({ currentTarget: { dataset: { type: authType } } });
return;
}
if (action === 'goToRanking') {
this.goToRanking({ currentTarget: { dataset: { type: rankType || 'dashou' } } });
return;
}
if (action === 'onTapStaffAuth') {
this.onTapAuthItem({ currentTarget: { dataset: { type: 'staff' } } });
return;
}
if (action === 'onTapShangjiaAuth') {
this.onTapShangjiaAuth();
return;
}
if (typeof this[action] === 'function') {
this[action]();
}
this.setData({
pendingAuthList: list,
showAuthSection: list.length > 0,
});
},
async refreshAllInfo(showToast = true) {
@@ -429,7 +446,7 @@ Page(createPage({
...(d.zuzhang || []),
...(d.guanshi || []),
];
this.setData(this._syncBadgeZoneFlags({ identityTagList: merged }));
this.setData({ identityTagList: merged });
}
} catch (e) {
/* 静默 */
@@ -567,7 +584,7 @@ Page(createPage({
data: { role: 'guanshi' },
});
if (res && res.data.code === 0 && res.data.data) {
this.setData(this._syncBadgeZoneFlags({ guanshiChenghaoList: res.data.data.chenghao_list || [] }));
this.setData({ guanshiChenghaoList: res.data.data.chenghao_list || [] });
}
} catch (e) {}
},
@@ -729,12 +746,15 @@ Page(createPage({
goToInviteUser() { wx.navigateTo({ url: '/pages/invite-fighter/invite-fighter' }); },
goToMySubordinate() { wx.navigateTo({ url: '/pages/my-fighter/my-fighter' }); },
goToRechargeRecord() { wx.navigateTo({ url: '/pages/recharge-log/recharge-log' }); },
goToRechargeRecord() { wx.navigateTo({ url: '/pages/recharge-log/recharge-log?tab=guanshi' }); },
goToCommissionLog(tab = 'dashou') {
wx.navigateTo({ url: `/pages/recharge-log/recharge-log?tab=${tab}` });
},
goToGuanshiRanking() {
wx.navigateTo({ url: '/pages/fighter-rank/fighter-rank?type=guanshi' });
},
goToPromoPoster() { wx.navigateTo({ url: '/pages/poster/poster' }); },
goToFenhongJilu() { wx.navigateTo({ url: '/pages/leader-bonus-log/leader-bonus-log' }); },
goToFenhongJilu() { wx.navigateTo({ url: '/pages/recharge-log/recharge-log?tab=zuzhang' }); },
goToYaoqingGuanshi() { wx.navigateTo({ url: '/pages/invite-manager/invite-manager' }); },
goToGuanshiAuthPage() { wx.navigateTo({ url: '/pages/verify/verify?type=guanshi' }); },
@@ -771,17 +791,17 @@ Page(createPage({
});
if (res && res.data.code === 0 && res.data.data) {
const list = res.data.data.chenghao_list || [];
this.setData(this._syncBadgeZoneFlags({ chenghaoList: list }));
this.setData({ chenghaoList: list });
const app = getApp();
app.globalData.chenghaoList = list;
} else {
this.setData(this._syncBadgeZoneFlags({ chenghaoList: [] }));
this.setData({ chenghaoList: [] });
}
} catch (e) {
}
},
// 联系邀请人
// 联系管事(邀请人
async contactInviter() {
wx.showLoading({ title: '获取邀请人...', mask: true });
try {
@@ -1149,9 +1169,7 @@ Page(createPage({
}
wx.navigateTo({ url: '/pages/verify/verify?type=shangjia' });
},
goToReceiveOrder() {
wx.switchTab({ url: '/pages/accept-order/accept-order' });
},
goToReceiveOrder() { wx.switchTab({ url: '/pages/accept-order/accept-order' }) },
async loadMyZhidingOrders() {
if (!isCenterPageActive(this, 'isDashou', 'dashoustatus')) return;
@@ -1177,18 +1195,101 @@ Page(createPage({
});
},
openZhidingDetailFromMine(e) {
const item = e.currentTarget.dataset.item;
const id = item?.dingdan_id || e.currentTarget.dataset.id;
if (!id) return;
getApp().globalData._acceptOrderHighlight = id;
wx.switchTab({
url: '/pages/accept-order/accept-order',
fail: () => wx.showToast({ title: '跳转失败', icon: 'none' }),
});
},
goToDashouExam() { wx.navigateTo({ url: '/pages/dashou-exam/dashou-exam' }) },
goToMyOrders() { wx.switchTab({ url: '/pages/fighter-orders/fighter-orders' }) },
goToOrdersWithStatus(e) {
const statusKey = e.currentTarget.dataset.status;
if (statusKey) {
getApp().globalData._fighterOrdersStatusKey = statusKey;
}
wx.switchTab({ url: '/pages/fighter-orders/fighter-orders' });
},
goToAllOrders() {
getApp().globalData._fighterOrdersStatusKey = 'all';
wx.switchTab({ url: '/pages/fighter-orders/fighter-orders' });
},
goToTradeNav(e) {
const type = e.currentTarget.dataset.type;
if (type === 'commission') {
this.goToCommissionLog('dashou');
return;
}
if (type === 'recharge') {
if (this.data.isGuanshi) {
this.goToCommissionLog('guanshi');
} else {
this.onComingSoon();
}
return;
}
if (type === 'withdraw') {
wx.navigateTo({ url: '/pages/withdraw/withdraw-records' });
return;
}
if (type === 'deduct') {
wx.navigateTo({ url: '/pages/fighter-ledger/fighter-ledger?type=deduct' });
return;
}
wx.navigateTo({ url: `/pages/fighter-ledger/fighter-ledger?type=${type}` });
},
goToWalletDetail() {
this.goToCommissionLog('dashou');
},
onInviteNavTap(e) {
if (!this.data.isGuanshi) {
this.goToGuanshiAuthPage();
return;
}
const action = e.currentTarget.dataset.action;
if (action === 'subordinate') {
this.goToMySubordinate();
return;
}
if (action === 'poster') {
this.goToPromoPoster();
return;
}
if (action === 'inviteCode') {
this.goToInviteUser();
}
},
onComingSoon() {
wx.showToast({ title: '该功能待开发', icon: 'none' });
},
toggleFollowKuaishou() {
const next = !this.data.followExpanded;
this.setData({ followExpanded: next, followClass: next ? 'expanded' : '' });
},
onQiepianTap() {
this.onComingSoon();
},
async loadPenaltyCount() {
if (!this.data.isDashou && !this.data.isGuanshi) return;
try {
const res = await request({ url: '/yonghu/cffktjhq', method: 'POST' });
const body = res?.data;
if (body && (body.code === 200 || body.code === 0) && body.data) {
const d = body.data;
const cnt = Number(d.daichuli_fakuan || d.fakuan_wait || d.pending || 0);
this.setData({ pendingPenaltyCount: cnt > 0 ? cnt : 0 });
}
} catch (e) {
/* ignore */
}
},
goToMyPunishment() { wx.navigateTo({ url: '/pages/penalty/penalty/penalty' }) },
async loadExamStatus() {
try {
const res = await request({ url: '/jituan/dashou-exam/status', method: 'POST' });
@@ -1202,9 +1303,9 @@ Page(createPage({
}
} catch (e) { /* 静默 */ }
},
goToMyOrders() { wx.navigateTo({ url: '/pages/fighter-orders/fighter-orders' }) },
goToMyPunishment() { wx.navigateTo({ url: '/pages/penalty/penalty/penalty' }) },
goToRecharge() { wx.navigateTo({ url: '/pages/fighter-recharge/fighter-recharge' }) },
goToRecharge() { wx.navigateTo({ url: '/pages/fighter-recharge/fighter-recharge' }); },
goToRechargeMember() { wx.navigateTo({ url: '/pages/fighter-recharge/fighter-recharge' }); },
goToRechargeDeposit() { wx.navigateTo({ url: '/pages/fighter-recharge/fighter-deposit' }); },
goToRanking(e) {
const type = e?.currentTarget?.dataset?.type || 'dashou';
wx.navigateTo({ url: `/pages/fighter-rank/fighter-rank?type=${type}` });

View File

@@ -3,11 +3,10 @@
"global-notification": "/components/global-notification/global-notification",
"chenghao-tag": "/components/chenghao-tag/chenghao-tag",
"tab-bar": "/tab-bar/index",
"pindao-modal": "/components/pindao-modal/pindao-modal",
"kefu-float": "/components/kefu-float/kefu-float"
"pindao-modal": "/components/pindao-modal/pindao-modal"
},
"navigationStyle": "custom",
"backgroundColor": "#f5f3ff",
"backgroundColor": "#fff8e1",
"backgroundTextStyle": "dark",
"enablePullDownRefresh": false,
"onReachBottomDistance": 50

View File

@@ -14,17 +14,16 @@
<view class="btn-bg unreg-btn" bindtap="onRegister"><text class="unreg-btn-text">立即注册</text></view>
<view class="unreg-btn-secondary" bindtap="quickRegisterAsPlatform"><text>平台直签注册</text></view>
<view class="unreg-link" bindtap="switchToNormal"><text>返回点单端</text></view>
<view class="unreg-link" bindtap="clearCache"><text>清除缓存,重新登录</text></view>
<view class="unreg-link" bindtap="clearCache"><text>退出登录</text></view>
</view>
</view>
<tab-bar/>
<kefu-float bottom="200rpx" />
</view>
</block>
<!-- 已注册 -->
<block wx:else>
<view class="user-page">
<view class="user-page xym-user">
<view class="page-header">
<view class="status-bar" style="height:{{statusBar}}px"></view>
<view class="nav-bar" style="height:{{navBar - statusBar}}px">
@@ -40,11 +39,10 @@
refresher-enabled="{{true}}"
refresher-threshold="80"
refresher-default-style="black"
refresher-background="#f5f3ff"
refresher-background="#fff8e1"
refresher-triggered="{{scrollViewRefreshing}}"
bindrefresherrefresh="onPullDownRefresh"
>
<!-- 用户信息 -->
<view class="user-info flexb">
<view class="flex">
<image class="avatar" src="{{avatarUrl || imgUrls.avatarDefault}}" mode="aspectFill" bindtap="previewAvatar"/>
@@ -56,10 +54,11 @@
<text class="role-tag">接单员</text>
<text class="role-tag" wx:if="{{isGuanshi}}">管事</text>
<text class="role-tag" wx:if="{{isZuzhang}}">组长</text>
<text class="role-tag" wx:if="{{isKaoheguan}}">考核</text>
<!-- 临时隐藏考核身份标签,恢复时取消注释 -->
<!-- <text class="role-tag" wx:if="{{isKaoheguan}}">考核</text> -->
</view>
</view>
<view class="sn-row" bindtap="copyUid">
<view class="sn-row flex" bindtap="copyUid">
<text class="sn">ID: {{uid || '--'}}</text>
<image class="copy-ico" src="{{imgUrls.iconCopy}}" mode="aspectFit"/>
</view>
@@ -71,17 +70,7 @@
</view>
</view>
<!-- 被指定订单(紧凑条,不占满屏) -->
<view class="my-zhiding-mine-strip" wx:if="{{myZhidingCount > 0 && isDashou}}" bindtap="goToZhidingFromMine">
<view class="my-zhiding-mine-strip-left">
<text class="my-zhiding-mine-badge">指定</text>
<text class="my-zhiding-mine-count">{{myZhidingCount}}单待接待</text>
</view>
<text class="my-zhiding-mine-arrow">去处理 </text>
</view>
<!-- 称号 -->
<view class="badge-zone" wx:if="{{showBadgeZone}}">
<view class="badge-zone" wx:if="{{chenghaoList.length > 0 || (isGuanshi && guanshiChenghaoList.length > 0) || identityTagList.length > 0}}">
<scroll-view scroll-x class="badge-scroll" wx:if="{{chenghaoList.length > 0}}">
<view class="badge-tag-wrap" wx:for="{{chenghaoList}}" wx:key="index">
<chenghao-tag mingcheng="{{item.mingcheng}}" texiaoJson="{{item.texiao_json}}"/>
@@ -99,9 +88,8 @@
</scroll-view>
</view>
<!-- 佣金/资产卡(逍遥梦 wallet-card -->
<view class="wallet-card flexb">
<view class="wallet-left">
<view bindtap="goToWalletDetail">
<view class="w-label">我的佣金(元)</view>
<view class="w-num">¥{{totalAssets}}</view>
<view class="w-sub">可提现 ¥{{yongjin || '0.00'}} · 查看</view>
@@ -112,17 +100,19 @@
</view>
</view>
<!-- 会员充值 + 保证金(无后台图时显示文字按钮) -->
<view class="banner-row flex" wx:if="{{showRechargeBanners}}">
<image wx:if="{{imgUrls.bannerVip}}" class="banner-img" src="{{imgUrls.bannerVip}}" mode="widthFix" bindtap="goToRecharge"/>
<image wx:if="{{imgUrls.bannerDeposit}}" class="banner-img" src="{{imgUrls.bannerDeposit}}" mode="widthFix" bindtap="goToRecharge"/>
<image wx:if="{{imgUrls.bannerVip}}" class="banner-img" src="{{imgUrls.bannerVip}}" mode="widthFix" bindtap="goToRechargeMember"/>
<image wx:if="{{imgUrls.bannerDeposit}}" class="banner-img" src="{{imgUrls.bannerDeposit}}" mode="widthFix" bindtap="goToRechargeDeposit"/>
</view>
<view class="recharge-text-row flex" wx:else>
<view class="recharge-text-btn" catchtap="goToRecharge">充值会员</view>
<view class="recharge-text-btn" catchtap="goToRecharge">充值保证金</view>
<view class="recharge-text-btn" catchtap="goToRechargeMember">充值会员</view>
<view class="recharge-text-btn" catchtap="goToRechargeDeposit">充值保证金</view>
</view>
<view class="qiepian-wrap" bindtap="onQiepianTap">
<image class="qiepian-banner" src="{{qiepianBanner}}" mode="widthFix"/>
</view>
<!-- 资产统计(逍遥梦 freeze-row -->
<view class="freeze-row flexa">
<view class="freeze-col flexmc">
<text class="freeze-num">{{jinfen || '0'}}</text>
@@ -138,132 +128,78 @@
</view>
</view>
<!-- 角色扩展统计(从左往右排列,不均分撑满) -->
<view class="stats-bar" wx:if="{{isGuanshi || isZuzhang || isKaoheguan}}">
<view class="stat-cell" wx:if="{{isGuanshi}}"><text class="stat-val">{{yaoqingzongshu || 0}}</text><text class="stat-lbl">邀请总数</text></view>
<view class="stat-cell" wx:if="{{isGuanshi}}"><text class="stat-val">{{yichongzhiDashou || 0}}</text><text class="stat-lbl">已充值</text></view>
<view class="stat-cell" wx:if="{{isGuanshi}}"><text class="stat-val">{{fenyongzonge || '0.00'}}</text><text class="stat-lbl">分成总额</text></view>
<view class="stat-cell" wx:if="{{isGuanshi}}"><text class="stat-val">{{zhuanhualv || 0}}%</text><text class="stat-lbl">有效率</text></view>
<view class="stat-cell" wx:if="{{isZuzhang}}"><text class="stat-val">{{guanshiCount || 0}}</text><text class="stat-lbl">邀请管事</text></view>
<view class="stat-cell" wx:if="{{isZuzhang}}"><text class="stat-val">{{fenhongZonge || '0.00'}}</text><text class="stat-lbl">分红总额</text></view>
<view class="stat-cell" wx:if="{{isKaoheguan}}"><text class="stat-val">{{shenheZongshu || 0}}</text><text class="stat-lbl">审核总数</text></view>
<view class="stat-cell" wx:if="{{isKaoheguan}}"><text class="stat-val">{{tongguoZongshu || 0}}</text><text class="stat-lbl">通过总数</text></view>
<view class="stat-cell" wx:if="{{isKaoheguan}}"><text class="stat-val">{{pendingShenheCount || 0}}</text><text class="stat-lbl">待审核</text></view>
<view wx:if="{{pendingPenaltyCount > 0}}" class="tip-bar flexb" bindtap="goToMyPunishment">
<view class="flex">
<image class="tip-ico" src="{{penaltyTipIcon}}" mode="aspectFit"/>
<text>你有{{pendingPenaltyCount}}条罚单待处理, 前往处理</text>
</view>
<text class="tip-arrow"></text>
</view>
<!-- 接单服务(对应逍遥梦「我的订单」四宫格) -->
<view class="panel shadow">
<view class="panel-title flexb"><text class="lg">接单服务</text></view>
<view class="my-box shadow order-nav-box">
<view class="panel-title flexb" bindtap="goToAllOrders">
<text class="lg">我的订单</text>
<text class="muted">全部订单 </text>
</view>
<view class="order-nav">
<view class="nav-item flexmc" bindtap="goToReceiveOrder">
<image class="nav-icon" src="{{imgUrls.iconGame}}" mode="aspectFit"/><text class="sm">抢单大厅</text>
</view>
<view class="nav-item flexmc" bindtap="goToMyOrders">
<image class="nav-icon" src="{{imgUrls.iconOrders}}" mode="aspectFit"/><text class="sm">我的订单</text>
</view>
<view class="nav-item flexmc" bindtap="goToMyPunishment">
<image class="nav-icon" src="{{imgUrls.iconPunish}}" mode="aspectFit"/><text class="sm">我的处罚</text>
</view>
<view class="nav-item flexmc" bindtap="goToKaohe">
<image class="nav-icon" src="{{imgUrls.iconMedal}}" mode="aspectFit"/><text class="sm">考核金牌</text>
</view>
<view class="nav-item flexmc" bindtap="goToDashouExam">
<image class="nav-icon" src="{{imgUrls.iconBook}}" mode="aspectFit"/>
<text class="sm">接单考试</text>
<text wx:if="{{examEnabled}}" class="exam-tag {{examPassed ? 'exam-tag-pass' : 'exam-tag-pending'}}">{{examPassed ? '已通过' : '待考试'}}</text>
</view>
</view>
</view>
<!-- 荣耀排行榜(横向滑动,省空间) -->
<view class="rank-hub panel shadow">
<view class="panel-title flexb">
<text class="lg">荣耀排行榜</text>
<text class="rank-hub-tip">TOP50</text>
</view>
<scroll-view scroll-x class="rank-hub-scroll" enhanced show-scrollbar="{{false}}">
<view class="rank-hub-track">
<view
wx:for="{{rankBoardList}}"
wx:key="type"
class="rank-tile {{item.themeClass}}"
bindtap="goToRanking"
data-type="{{item.type}}"
>
<view class="rank-tile-inner">
<image class="rank-tile-icon" src="{{item.icon}}" mode="aspectFit"/>
<view class="rank-tile-text">
<text class="rank-tile-name">{{item.name}}</text>
<text class="rank-tile-sub">{{item.sub}}</text>
</view>
<text class="rank-tile-go">进入</text>
</view>
<view wx:for="{{orderNavXym}}" wx:key="name" class="nav-item" data-status="{{item.statusKey}}" bindtap="goToOrdersWithStatus">
<view class="icon-wrap">
<view wx:if="{{item.showBadge && item.badge > 0}}" class="nav-badge">{{item.badge}}</view>
<image class="nav-icon" src="{{item.icon}}" mode="aspectFit"/>
</view>
</view>
</scroll-view>
</view>
<!-- 管事功能 -->
<view class="panel shadow" wx:if="{{isGuanshi}}">
<view class="panel-title"><text class="lg">管事功能</text></view>
<view class="func-grid">
<view class="func-item flexmc" bindtap="goToInviteUser"><image class="func-icon" src="{{imgUrls.iconInvite}}" mode="aspectFit"/><text class="func-txt">邀请用户</text></view>
<view class="func-item flexmc" bindtap="goToMySubordinate"><image class="func-icon" src="{{imgUrls.iconSub}}" mode="aspectFit"/><text class="func-txt">我的下级</text></view>
<view class="func-item flexmc" bindtap="goToRechargeRecord"><image class="func-icon" src="{{imgUrls.iconRecord}}" mode="aspectFit"/><text class="func-txt">会员记录</text></view>
<view class="func-item flexmc" bindtap="goToPromoPoster"><image class="func-icon" src="{{imgUrls.iconPoster}}" mode="aspectFit"/><text class="func-txt">推广海报</text></view>
<view class="func-item flexmc" bindtap="contactZuzhang"><image class="func-icon" src="{{imgUrls.iconContact}}" mode="aspectFit"/><text class="func-txt">联系组长</text></view>
</view>
</view>
<!-- 组长功能 -->
<view class="panel shadow" wx:if="{{isZuzhang}}">
<view class="panel-title"><text class="lg">组长功能</text></view>
<view class="func-grid">
<view class="func-item flexmc" bindtap="goToFenhongJilu"><image class="func-icon" src="{{imgUrls.iconRecord}}" mode="aspectFit"/><text class="func-txt">分红记录</text></view>
<view class="func-item flexmc" bindtap="goToYaoqingGuanshi"><image class="func-icon" src="{{imgUrls.iconInvite}}" mode="aspectFit"/><text class="func-txt">邀请管事</text></view>
</view>
</view>
<!-- 考核官功能 -->
<view class="panel shadow" wx:if="{{isKaoheguan}}">
<view class="panel-title"><text class="lg">考核官功能</text></view>
<view class="func-grid">
<view class="func-item flexmc" bindtap="goToKaoheDafen"><image class="func-icon" src="{{imgUrls.iconKaoheDafen}}" mode="aspectFit"/><text class="func-txt">考核打分</text></view>
<view class="func-item flexmc" bindtap="goToKaoheJilu"><image class="func-icon" src="{{imgUrls.iconKaoheJilu}}" mode="aspectFit"/><text class="func-txt">考核记录</text></view>
<view class="func-item flexmc" bindtap="goToKaoheZhongxin"><image class="func-icon" src="{{imgUrls.iconKaoheZhongxin}}" mode="aspectFit"/><text class="func-txt">考核中心</text></view>
</view>
</view>
<!-- 身份认证 -->
<view class="panel shadow" wx:if="{{showAuthSection}}">
<view class="panel-title"><text class="lg">身份认证</text></view>
<view class="func-grid">
<view class="func-item flexmc" wx:for="{{pendingAuthList}}" wx:key="type" bindtap="onTapAuthItem" data-type="{{item.type}}">
<image class="func-icon" src="{{item.icon}}" mode="aspectFit"/>
<text class="func-txt">{{item.name}}</text>
<text class="func-tag {{item.done ? 'func-tag-done' : ''}}">{{item.tag}}</text>
<text class="sm">{{item.name}}</text>
</view>
</view>
</view>
<!-- 更多功能 -->
<view class="panel shadow">
<view class="panel-title"><text class="lg">更多功能</text></view>
<view class="func-grid">
<view class="func-item flexmc" bindtap="goToKefu"><image class="func-icon" src="{{imgUrls.iconKefu}}" mode="aspectFit"/><text class="func-txt">在线客服</text></view>
<view class="func-item flexmc" bindtap="goToGuanzhuKs"><image class="func-icon" src="{{imgUrls.iconKuaishou}}" mode="aspectFit"/><text class="func-txt">关注快手</text></view>
<view class="func-item flexmc" wx:if="{{showPindaoEntry}}" bindtap="openPindaoModal"><image class="func-icon" src="{{imgUrls.iconPindao}}" mode="aspectFit"/><text class="func-txt">频道</text></view>
<view class="func-item flexmc" bindtap="contactInviter"><image class="func-icon" src="{{imgUrls.iconInvite}}" mode="aspectFit"/><text class="func-txt">联系邀请人</text></view>
<view class="func-item flexmc" bindtap="goToRules"><image class="func-icon" src="{{imgUrls.iconBook}}" mode="aspectFit"/><text class="func-txt">用户规则</text></view>
<view class="func-item flexmc" bindtap="switchToNormal"><image class="func-icon" src="{{imgUrls.iconSwitch}}" mode="aspectFit"/><text class="func-txt">返回点单端</text></view>
<view class="func-item flexmc" bindtap="clearCache"><image class="func-icon" src="{{imgUrls.iconClear}}" mode="aspectFit"/><text class="func-txt">清除缓存</text></view>
<view class="my-box shadow trade-box">
<view class="section-hd">交易明细</view>
<view class="trade-list">
<view wx:for="{{tradeNavXym}}" wx:key="name" class="trade-item" data-type="{{item.type}}" bindtap="goToTradeNav">
<image class="trade-icon" src="{{item.icon}}" mode="aspectFit"/>
<text class="sm">{{item.name}}</text>
</view>
</view>
</view>
<view class="my-box shadow invite-box">
<view class="section-hd">好友邀请</view>
<view class="invite-row">
<view wx:for="{{inviteNavXym}}" wx:key="name" class="invite-item" data-action="{{item.action}}" bindtap="onInviteNavTap">
<image class="invite-icon" src="{{item.icon}}" mode="aspectFit"/>
<text class="sm">{{item.name}}</text>
</view>
</view>
</view>
<view class="my-box shadow more-box">
<view class="section-hd">更多功能</view>
<view class="func-list">
<view
wx:for="{{moreFuncList}}"
wx:key="action"
class="func-item-xym"
bindtap="onMoreFuncTap"
data-action="{{item.action}}"
data-auth-type="{{item.authType}}"
data-rank-type="{{item.rankType}}"
>
<view class="func-icon-wrap"><image class="func-icon-xym" src="{{item.icon}}" mode="aspectFit"/></view>
<text class="func-txt-xym">{{item.name}}</text>
</view>
</view>
</view>
<view class="load-tip">— 已加载全部 —</view>
<view class="content-bottom"></view>
</scroll-view>
<view class="follow-kuaishou {{followClass}}" bindtap="toggleFollowKuaishou">
<image class="ks-icon" src="{{ksIcon}}" mode="aspectFit"/>
<text wx:if="{{followExpanded}}" class="ks-text" catchtap="goToGuanzhuKs">关注快手</text>
</view>
<tab-bar/>
<kefu-float bottom="200rpx" />
</view>
</block>

View File

@@ -1,7 +1,8 @@
/* 打手端个人中心 - 逍遥梦 UI逻辑不变 */
@import '../../styles/dashou-xym-user.wxss';
page {
background: #f5f3ff;
background: #fff8e1;
color: #333;
}
@@ -16,7 +17,7 @@ page {
flex-direction: column;
overflow: hidden;
box-sizing: border-box;
background: linear-gradient(180deg, #c4b5fd 0%, #fff 28%, #f5f3ff 100%);
background: linear-gradient(180deg, #f7dc51 0%, #fff 28%, #fff8e1 100%);
position: relative;
}
@@ -24,6 +25,7 @@ page {
position: relative;
z-index: 2;
flex-shrink: 0;
background: linear-gradient(180deg, #f7dc51 0%, #ffd061 100%);
}
.status-bar,
@@ -65,10 +67,6 @@ page {
padding-bottom: 0;
}
.content-bottom {
height: 12rpx;
}
.refresh-float {
position: fixed;
right: 24rpx;
@@ -126,7 +124,7 @@ page {
padding: 2rpx 12rpx;
border-radius: 8rpx;
background: linear-gradient(180deg, #fae04d, #ffc0a3);
color: #6d28d9;
color: #492f00;
}
.sn-row {
@@ -238,7 +236,7 @@ page {
border: 2rpx solid #fff;
border-radius: 60rpx;
background: linear-gradient(180deg, #fae04d, #ffc0a3);
color: #6d28d9;
color: #492f00;
white-space: nowrap;
}
@@ -272,8 +270,8 @@ page {
border-radius: 16rpx;
font-size: 28rpx;
font-weight: 600;
color: #6d28d9;
background: linear-gradient(180deg, #f5f3ff, #ffe8b8);
color: #492f00;
background: linear-gradient(180deg, #fff8e1, #ffe8b8);
border: 1rpx solid rgba(201, 169, 98, 0.45);
}
@@ -305,7 +303,7 @@ page {
.btn-bg {
background: linear-gradient(180deg, #fae04d, #ffc0a3);
border-radius: 30px;
color: #6d28d9;
color: #492f00;
}
.withdraw {
@@ -334,7 +332,7 @@ page {
.vip-strip-sub {
display: block;
font-size: 22rpx;
color: rgba(196, 181, 253, 0.65);
color: rgba(252, 210, 112, 0.65);
margin-top: 4rpx;
}
@@ -344,39 +342,6 @@ page {
font-weight: 700;
}
.stats-bar {
margin: 12rpx 30rpx 0;
padding: 16rpx 16rpx 8rpx;
background: #fdfcfa;
border-radius: 16rpx;
display: flex;
flex-wrap: wrap;
justify-content: flex-start;
align-content: flex-start;
box-shadow: 0 3px 10px rgba(0, 0, 0, 0.04);
}
.stat-cell {
width: 25%;
padding: 8rpx 0 12rpx;
box-sizing: border-box;
text-align: center;
}
.stat-val {
display: block;
font-size: 28rpx;
font-weight: 700;
color: #222;
}
.stat-lbl {
display: block;
font-size: 22rpx;
color: #999;
margin-top: 4rpx;
}
.panel {
margin: 20rpx 20rpx 12rpx;
background: #fdfcfa;
@@ -552,7 +517,7 @@ page {
}
.rank-theme-gold {
background: linear-gradient(135deg, #a8842a 0%, #c4b5fd 100%);
background: linear-gradient(135deg, #a8842a 0%, #f5d563 100%);
}
.rank-theme-gold .rank-tile-name,
@@ -608,7 +573,7 @@ page {
margin-bottom: 16rpx;
}
.unreg-btn-text { color: #6d28d9; }
.unreg-btn-text { color: #492f00; }
.unreg-btn-secondary {
text-align: center;
@@ -644,7 +609,7 @@ page {
width: 60rpx;
height: 60rpx;
border: 4rpx solid rgba(0, 0, 0, 0.08);
border-top-color: #9333ea;
border-top-color: #ffd061;
border-radius: 50%;
animation: fighterSpin 0.8s linear infinite;
}
@@ -652,39 +617,3 @@ page {
@keyframes fighterSpin {
to { transform: rotate(360deg); }
}
.my-zhiding-mine-strip {
margin: 0 24rpx 16rpx;
padding: 20rpx 24rpx;
border-radius: 16rpx;
background: linear-gradient(90deg, #ff6b00, #ff4500);
border: 2rpx solid #ff3300;
box-shadow: 0 8rpx 24rpx rgba(255, 69, 0, 0.4);
display: flex;
align-items: center;
justify-content: space-between;
}
.my-zhiding-mine-strip:active { opacity: 0.92; }
.my-zhiding-mine-strip-left {
display: flex;
align-items: center;
gap: 12rpx;
}
.my-zhiding-mine-badge {
font-size: 22rpx;
font-weight: 800;
color: #ff4500;
background: #fff;
padding: 4rpx 14rpx;
border-radius: 999rpx;
}
.my-zhiding-mine-count {
font-size: 28rpx;
color: #fff;
font-weight: 700;
}
.my-zhiding-mine-arrow {
font-size: 26rpx;
color: #fff;
font-weight: 700;
}

View File

@@ -1,5 +1,5 @@
{
"navigationBarTitleText": "关注星阙",
"navigationBarTitleText": "星之界",
"usingComponents": {
"global-notification": "/components/global-notification/global-notification"
},

View File

@@ -1,6 +1,6 @@
@import '../../styles/shangjia-xym-common.wxss';
page { background: #f5f3ff; }
page { background: #fff8e1; }
.sub-scroll { height: calc(100vh - 120rpx); }

View File

@@ -4,9 +4,9 @@
"popup-notice": "/components/popup-notice/popup-notice"
},
"backgroundTextStyle": "dark",
"navigationBarBackgroundColor": "#f5f3ff",
"navigationBarBackgroundColor": "#f7dc51",
"navigationBarTitleText": "自定义发单",
"navigationBarTextStyle": "black",
"backgroundColor": "#f5f5f5",
"backgroundColor": "#fff8e1",
"enablePullDownRefresh": false
}

View File

@@ -159,7 +159,7 @@
<text class="field-optional">选填</text>
</view>
<view class="switch-row">
<switch checked="{{commissionEnabled}}" bindchange="onCommissionToggle" color="#9333ea"/>
<switch checked="{{commissionEnabled}}" bindchange="onCommissionToggle" color="#ffd061"/>
<text class="switch-label">{{commissionEnabled ? '已开启' : '未开启'}}</text>
</view>
<input

View File

@@ -1,7 +1,7 @@
{
"navigationStyle": "custom",
"enablePullDownRefresh": true,
"backgroundColor": "#f5f3ff",
"backgroundColor": "#fff8e1",
"backgroundTextStyle": "dark",
"usingComponents": {
"global-notification": "/components/global-notification/global-notification",

View File

@@ -1,7 +1,7 @@
@import '../../styles/shangjia-xym-common.wxss';
page {
background: #f5f3ff;
background: #fff8e1;
}
.sj-page--home {
@@ -85,13 +85,13 @@ page {
.dot.active {
width: 16rpx;
border-radius: 8rpx;
background: #9333ea;
background: #ffd061;
}
.sj-notice-bar {
display: flex;
align-items: center;
background: #f5f3ff;
background: #fdf9db;
margin: 12rpx 24rpx 0;
border-radius: 10rpx;
padding: 10rpx 16rpx;
@@ -166,7 +166,7 @@ page {
.sj-fadan-big-title {
font-size: 30rpx;
font-weight: 700;
color: #6d28d9;
color: #492f00;
}
.sj-fadan-big-sub {

View File

@@ -1,5 +1,5 @@
{
"navigationStyle": "custom",
"backgroundColor": "#f5f3ff",
"backgroundColor": "#fff8e1",
"usingComponents": {}
}

View File

@@ -96,7 +96,7 @@
min-height: 64rpx;
border-radius: 10rpx;
background: linear-gradient(180deg, #fae04d, #ffc0a3);
color: #6d28d9;
color: #492f00;
font-size: 28rpx;
font-weight: 700;
flex-shrink: 0;

View File

@@ -1,5 +1,5 @@
{
"navigationStyle": "custom",
"backgroundColor": "#f5f3ff",
"backgroundColor": "#fff8e1",
"usingComponents": {}
}

View File

@@ -3,8 +3,8 @@
"global-notification": "/components/global-notification/global-notification"
},
"navigationBarTitleText": "处罚记录",
"navigationBarBackgroundColor": "#0a0a12",
"navigationBarTextStyle": "white",
"backgroundColor": "#0a0a12",
"navigationBarBackgroundColor": "#f7dc51",
"navigationBarTextStyle": "black",
"backgroundColor": "#fff8e1",
"enablePullDownRefresh": false
}

View File

@@ -2,20 +2,20 @@
/* 🔴【样式与cfss页面基本相同只添加了独占按钮样式】 */
:root {
--cyber-blue: rgba(0, 243, 255, 0.7);
--cyber-pink: rgba(255, 0, 255, 0.7);
--cyber-purple: rgba(157, 0, 255, 0.7);
--cyber-green: rgba(0, 255, 157, 0.7);
--cyber-red: rgba(255, 0, 102, 0.7);
--cyber-blue: rgba(255, 208, 97, 0.85);
--cyber-pink: rgba(255, 192, 163, 0.85);
--cyber-purple: rgba(230, 126, 34, 0.85);
--cyber-green: rgba(76, 175, 80, 0.85);
--cyber-red: rgba(230, 74, 25, 0.85);
--cyber-bg: #2a2a3a;
--cyber-card: #333344;
--cyber-border: rgba(255, 255, 255, 0.15);
--cyber-glow: rgba(0, 243, 255, 0.2);
--cyber-bg: #fff8e1;
--cyber-card: #fef6d4;
--cyber-border: rgba(255, 208, 97, 0.35);
--cyber-glow: rgba(255, 208, 97, 0.2);
--cyber-text: #ffffff;
--cyber-text-light: #e6e6e6;
--cyber-text-lighter: #cccccc;
--cyber-text: #333333;
--cyber-text-light: #666666;
--cyber-text-lighter: #888888;
}
.cfss-container {
@@ -38,8 +38,8 @@
bottom: 0;
background-image:
linear-gradient(rgba(0, 243, 255, 0.05) 1px, transparent 1px),
linear-gradient(90deg, rgba(0, 243, 255, 0.05) 1px, transparent 1px);
linear-gradient(rgba(255, 208, 97, 0.08) 1px, transparent 1px),
linear-gradient(90deg, rgba(255, 208, 97, 0.08) 1px, transparent 1px);
background-size: 40rpx 40rpx;
pointer-events: none;
opacity: 0.15;
@@ -48,14 +48,14 @@
/* ====== 统计卡片 ====== */
.tongji-card {
background: rgba(255, 0, 102, 0.3);
background: #fef6d4;
border-radius: 20rpx;
padding: 30rpx;
margin-bottom: 30rpx;
border: 1rpx solid var(--cyber-border);
box-shadow:
0 0 20rpx rgba(255, 0, 102, 0.2),
inset 0 0 10rpx rgba(0, 243, 255, 0.05);
inset 0 0 10rpx rgba(255, 208, 97, 0.05);
position: relative;
overflow: hidden;
z-index: 1;
@@ -109,7 +109,7 @@
/* ====== 类型切换 ====== */
.leixing-qiehuan {
display: flex;
background: rgba(255, 0, 102, 0.3);
background: #fef6d4;
border-radius: 16rpx;
padding: 10rpx;
margin-bottom: 30rpx;
@@ -133,8 +133,8 @@
}
.leixing-active {
background: linear-gradient(135deg, rgba(0, 243, 255, 0.15), rgba(157, 0, 255, 0.15));
box-shadow: 0 0 15rpx rgba(0, 243, 255, 0.2);
background: linear-gradient(135deg, rgba(250, 224, 77, 0.25), rgba(255, 192, 163, 0.25));
box-shadow: 0 0 15rpx rgba(255, 208, 97, 0.2);
}
.leixing-text {
@@ -211,7 +211,7 @@
/* 处罚卡片 */
.chufa-card {
background: rgba(560, 50, 65, 0.8);
background: #fff;
border-radius: 20rpx;
padding: 30rpx;
margin-bottom: 30rpx;
@@ -236,7 +236,7 @@
right: -1px;
bottom: -1px;
border-radius: 21rpx;
background: linear-gradient(45deg, rgba(138, 60, 138, 0.3), rgba(131, 208, 212, 0.3), rgba(255, 0, 255, 0.3), rgba(0, 243, 255, 0.3));
background: linear-gradient(45deg, rgba(250, 224, 77, 0.3), rgba(255, 192, 163, 0.3), rgba(255, 208, 97, 0.3), rgba(255, 224, 130, 0.3));
z-index: -1;
opacity: 0;
transition: opacity 0.3s ease;
@@ -298,9 +298,9 @@
}
.zhuangtai-weizhi {
background: rgba(128, 0, 255, 0.2);
border-color: rgba(128, 0, 255, 0.5);
box-shadow: 0 0 8rpx rgba(128, 0, 255, 0.2);
background: rgba(255, 152, 0, 0.15);
border-color: rgba(255, 152, 0, 0.5);
box-shadow: 0 0 8rpx rgba(255, 152, 0, 0.2);
}
/* 其他文字内容 */
@@ -423,7 +423,7 @@
.modal-content {
position: relative;
background: #3a3a4a;
background: #fff;
border-radius: 30rpx;
width: 90%;
max-height: 80vh;
@@ -458,11 +458,11 @@
justify-content: center;
border-radius: 50%;
background: rgba(137, 210, 214, 0.1);
border: 1rpx solid rgba(0, 243, 255, 0.3);
border: 1rpx solid rgba(255, 208, 97, 0.3);
}
.modal-close:active {
background: rgba(0, 243, 255, 0.2);
background: rgba(255, 208, 97, 0.2);
transform: scale(0.95);
}
@@ -492,7 +492,7 @@
color: var(--cyber-blue);
margin-bottom: 25rpx;
padding-bottom: 15rpx;
border-bottom: 1rpx solid rgba(0, 243, 255, 0.2);
border-bottom: 1rpx solid rgba(255, 208, 97, 0.2);
text-shadow: 0 0 8rpx var(--cyber-blue);
}
@@ -534,13 +534,13 @@
font-size: 24rpx;
padding: 8rpx 20rpx;
border-radius: 8rpx;
background: rgba(0, 243, 255, 0.1);
border: 1rpx solid rgba(0, 243, 255, 0.3);
background: rgba(255, 208, 97, 0.1);
border: 1rpx solid rgba(255, 208, 97, 0.3);
flex-shrink: 0;
}
.fuzhi-btn:active {
background: rgba(0, 243, 255, 0.2);
background: rgba(255, 208, 97, 0.2);
}
.full-row {
@@ -598,7 +598,7 @@
border-radius: 10rpx;
overflow: hidden;
position: relative;
border: 1rpx solid rgba(0, 243, 255, 0.2);
border: 1rpx solid rgba(255, 208, 97, 0.2);
}
.tupian-image {
@@ -628,7 +628,7 @@
.preview-text {
color: white;
font-size: 24rpx;
background: rgba(0, 243, 255, 0.7);
background: rgba(255, 208, 97, 0.7);
padding: 8rpx 16rpx;
border-radius: 8rpx;
}
@@ -636,7 +636,7 @@
/* 🔴【新增】弹窗底部按钮独占一行样式 */
.modal-footer {
padding: 30rpx;
border-top: 1rpx solid rgba(0, 243, 255, 0.2);
border-top: 1rpx solid rgba(255, 208, 97, 0.2);
flex-shrink: 0;
}
@@ -666,9 +666,9 @@
/* 按钮样式 */
.btn-kefu {
background: rgba(0, 243, 255, 0.1);
background: rgba(255, 208, 97, 0.1);
border-color: var(--cyber-blue);
box-shadow: 0 0 12rpx rgba(0, 243, 255, 0.2);
box-shadow: 0 0 12rpx rgba(255, 208, 97, 0.2);
}
/* 响应式调整 */
@@ -712,7 +712,7 @@
aspect-ratio: 1;
border-radius: 12rpx;
overflow: hidden;
border: 1rpx solid rgba(0, 243, 255, 0.3);
border: 1rpx solid rgba(255, 208, 97, 0.3);
background-color: rgba(0, 0, 0, 0.2);
}
@@ -745,7 +745,7 @@
.preview-text {
color: white;
font-size: 24rpx;
background: rgba(0, 243, 255, 0.7);
background: rgba(255, 208, 97, 0.7);
padding: 8rpx 16rpx;
border-radius: 8rpx;
}

View File

@@ -1,7 +1,7 @@
/* pages/merchant-order-detail/merchant-order-detail.wxss - 商家订单详情(逍遥梦金色主题) */
@import '../../styles/shangjia-xym-common.wxss';
page { background: #f5f3ff; }
page { background: #fff8e1; }
.sjddxq-page { padding-bottom: calc(200rpx + env(safe-area-inset-bottom)); }
/* 加载状态居中布局 */
@@ -94,7 +94,7 @@ page { background: #f5f3ff; }
bottom: 0;
left: 0;
right: 0;
background: linear-gradient(180deg, rgba(245, 243, 255, 0.96), #f5f3ff 30%);
background: linear-gradient(180deg, rgba(255, 248, 225, 0.96), #fff8e1 30%);
padding: 16rpx 24rpx calc(16rpx + env(safe-area-inset-bottom));
box-shadow: 0 -8rpx 28rpx rgba(0, 0, 0, 0.08);
display: flex;
@@ -123,20 +123,20 @@ page { background: #f5f3ff; }
.sj-action-btn--gold {
background: linear-gradient(180deg, #fae04d, #ffc0a3);
color: #6d28d9;
color: #492f00;
border: 2rpx solid #fff;
box-shadow: 0 6rpx 18rpx rgba(245, 213, 99, 0.35);
}
.sj-action-btn--outline {
background: rgba(255, 255, 255, 0.95);
color: #6d28d9;
border: 2rpx solid #c4b5fd;
color: #492f00;
border: 2rpx solid #ffd061;
}
.sj-action-btn--warn {
background: linear-gradient(180deg, #ffb74d, #ff8a65);
color: #6d28d9;
color: #492f00;
border: 2rpx solid #fff;
box-shadow: 0 6rpx 16rpx rgba(255, 138, 101, 0.28);
}
@@ -149,7 +149,7 @@ page { background: #f5f3ff; }
.modal { position: fixed; top: 0; left: 0; right: 0; bottom: 0; z-index: 1000; display: flex; align-items: center; justify-content: center; }
.modal-mask { position: absolute; width: 100%; height: 100%; background: rgba(0,0,0,0.45); }
.modal-content { position: relative; width: 620rpx; background: #fdfcfa; border-radius: 32rpx; overflow: hidden; border: 2rpx solid rgba(245, 213, 99, 0.4); }
.modal-hd { padding: 32rpx; font-size: 34rpx; font-weight: 700; color: #6d28d9; display: flex; justify-content: space-between; border-bottom: 1rpx solid rgba(245, 213, 99, 0.35); }
.modal-hd { padding: 32rpx; font-size: 34rpx; font-weight: 700; color: #492f00; display: flex; justify-content: space-between; border-bottom: 1rpx solid rgba(245, 213, 99, 0.35); }
.modal-close { color: #999; font-size: 40rpx; }
.modal-body { padding: 32rpx; }
.modal-tip { font-size: 28rpx; color: #555; margin-bottom: 12rpx; }
@@ -163,7 +163,7 @@ page { background: #f5f3ff; }
.fenhong-tip { text-align: center; font-size: 28rpx; color: #ff9800; margin: 16rpx 0 0; }
.modal-btns { display: flex; border-top: 1rpx solid #f0f0f0; }
.modal-btn { flex: 1; text-align: center; padding: 28rpx; font-size: 30rpx; font-weight: 500; }
.modal-btn.cancel { color: #886633; background: #f5f3ff; }
.modal-btn.cancel { color: #886633; background: #fff8e1; }
.modal-btn.confirm { color: #492f00; background: linear-gradient(180deg, #fae04d, #ffc0a3); font-weight: 700; }

View File

@@ -2,7 +2,7 @@
"navigationBarTitleText": "我的派单",
"enablePullDownRefresh": false,
"backgroundTextStyle": "dark",
"backgroundColor": "#f5f3ff",
"backgroundColor": "#fff8e1",
"usingComponents": {
"global-notification": "/components/global-notification/global-notification",
"chenghao-tag": "/components/chenghao-tag/chenghao-tag"

View File

@@ -89,7 +89,7 @@
refresher-enabled="{{true}}"
refresher-threshold="80"
refresher-default-style="black"
refresher-background="#f5f3ff"
refresher-background="#fff8e1"
refresher-triggered="{{scrollViewRefreshing}}"
bindrefresherrefresh="onPullDownRefresh"
bindscrolltolower="onReachBottom"

View File

@@ -6,13 +6,13 @@
page {
height: 100%;
overflow: hidden;
background: #f5f3ff;
background: #fff8e1;
}
.sj-page {
height: 100vh;
display: flex;
flex-direction: column;
background: #f5f3ff;
background: #fff8e1;
overflow: hidden;
box-sizing: border-box;
}
@@ -125,8 +125,8 @@ page {
text-align: center;
}
.time-pill--active {
color: #6d28d9;
background: linear-gradient(180deg, #f5f3ff, #ffe9b8);
color: #492f00;
background: linear-gradient(180deg, #fff8e1, #ffe9b8);
border: 1rpx solid #e8c547;
}
.time-sep {
@@ -177,7 +177,7 @@ page {
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.04);
}
.staff-filter-pill--active {
background: linear-gradient(180deg, #f5f3ff, #ffe9b8);
background: linear-gradient(180deg, #fff8e1, #ffe9b8);
border-color: #e8c547;
box-shadow: 0 4rpx 12rpx rgba(232, 197, 71, 0.25);
}
@@ -193,7 +193,7 @@ page {
}
.staff-filter-pill--active .staff-filter-tag {
background: rgba(255, 255, 255, 0.85);
color: #6d28d9;
color: #492f00;
}
.staff-filter-value {
flex: 1;
@@ -206,7 +206,7 @@ page {
white-space: nowrap;
}
.staff-filter-pill--active .staff-filter-value {
color: #6d28d9;
color: #492f00;
}
.staff-filter-arrow {
flex-shrink: 0;
@@ -572,7 +572,7 @@ page {
.load-more-btn {
background: linear-gradient(180deg, #fae04d, #ffc0a3);
color: #6d28d9;
color: #492f00;
border: 2rpx solid #fff;
box-shadow: 0 6rpx 16rpx rgba(245, 213, 99, 0.3);
}

View File

@@ -1,4 +1,4 @@
page { background: #f7f8fa; }
page { background: #fff8e1; }
.page-container { padding-bottom: 30rpx; }
.stats-card {

View File

@@ -3,10 +3,10 @@
"global-notification": "/components/global-notification/global-notification"
},
"navigationBarTitleText": "商家排行榜",
"navigationBarBackgroundColor": "#000000",
"navigationBarTextStyle": "white",
"navigationBarBackgroundColor": "#f7dc51",
"navigationBarTextStyle": "black",
"enablePullDownRefresh": false,
"backgroundColor": "#000000",
"backgroundColor": "#fff8e1",
"backgroundTextStyle": "dark",
"onReachBottomDistance": 50
}

View File

@@ -1,8 +1,8 @@
{
"navigationBarTitleText": "商家充值",
"navigationBarBackgroundColor": "#0a0e17",
"navigationBarTextStyle": "white",
"backgroundColor": "#0a0e17",
"navigationBarBackgroundColor": "#f7dc51",
"navigationBarTextStyle": "black",
"backgroundColor": "#fff8e1",
"backgroundTextStyle": "light",
"enablePullDownRefresh": false,
"usingComponents": {

View File

@@ -6,23 +6,23 @@
/* 科技主题色 - 增强对比度 */
:root {
--primary-color: #00f3ff; /* 主科技蓝 */
--primary-light: #4dfbff; /* 亮科技蓝 */
--primary-dark: #00a0b0; /* 暗科技蓝 */
--secondary-color: #ff2a6d; /* 科技粉红 */
--accent-color: #ffd700; /* 科技金 */
--accent-purple: #9d4edd; /* 科技紫 */
--dark-bg: #0a0e17; /* 深色背景 */
--medium-bg: #13182b; /* 中色背景 */
--light-bg: #1c2238; /* 浅色背景 */
--card-bg: rgba(20, 25, 40, 0.85); /* 卡片背景 - 提高透明度 */
--border-glow: rgba(0, 243, 255, 0.4);
--text-primary: #ffffff; /* 主要文字 */
--text-secondary: #a0aec0; /* 次要文字 */
--text-highlight: #ffffff; /* 高亮文字 */
--text-glow: #00f3ff; /* 发光文字 */
--shadow-tech: 0 8rpx 24rpx rgba(0, 0, 0, 0.5);
--shadow-glow: 0 0 20rpx rgba(0, 243, 255, 0.25);
--primary-color: #ffd061;
--primary-light: #ffe082;
--primary-dark: #e6a020;
--secondary-color: #ffc0a3;
--accent-color: #e67e22;
--accent-purple: #ffb74d;
--dark-bg: #fff8e1;
--medium-bg: #fff9f0;
--light-bg: #fff8e1;
--card-bg: #fef6d4;
--border-glow: rgba(255, 208, 97, 0.4);
--text-primary: #222222;
--text-secondary: #666666;
--text-highlight: #492f00;
--text-glow: #e67e22;
--shadow-tech: 0 8rpx 24rpx rgba(0, 0, 0, 0.08);
--shadow-glow: 0 0 20rpx rgba(255, 208, 97, 0.25);
}
/* 全局页面样式 - 修复背景 */
@@ -31,9 +31,9 @@
color: var(--text-primary);
min-height: 100vh;
background: linear-gradient(145deg,
var(--dark-bg) 0%,
var(--medium-bg) 50%,
var(--light-bg) 100%
#f7dc51 0%,
#fff8e1 50%,
#fff9f0 100%
) !important;
position: relative;
overflow-x: hidden;
@@ -46,17 +46,17 @@
/* ========== 余额卡片样式 - 完全重写 ========== */
.balance-card {
background: rgba(20, 25, 40, 0.9); /* 降低透明度,提高文字可见性 */
background: #fef6d4; /* 降低透明度,提高文字可见性 */
border-radius: 25rpx;
padding: 35rpx 25rpx;
margin: 0 0 35rpx;
position: relative;
overflow: hidden;
border: 1.5rpx solid rgba(0, 243, 255, 0.3);
border: 1.5rpx solid rgba(255, 208, 97, 0.3);
box-shadow:
var(--shadow-tech),
var(--shadow-glow),
inset 0 0 15rpx rgba(0, 243, 255, 0.08);
inset 0 0 15rpx rgba(255, 208, 97, 0.08);
z-index: 1;
/* 移除或大幅降低毛玻璃效果 */
backdrop-filter: blur(2px);
@@ -82,9 +82,9 @@
letter-spacing: 1.5rpx;
color: var(--text-primary) !important; /* 强制使用白色,确保可见 */
text-shadow:
0 0 15rpx rgba(0, 243, 255, 0.8),
0 0 30rpx rgba(0, 243, 255, 0.4),
0 0 45rpx rgba(0, 243, 255, 0.2);
0 0 15rpx rgba(255, 208, 97, 0.8),
0 0 30rpx rgba(255, 208, 97, 0.4),
0 0 45rpx rgba(255, 208, 97, 0.2);
position: relative;
display: inline-block;
/* 移除背景渐变,直接用纯色加阴影 */
@@ -142,10 +142,10 @@
/* VIP商家标签 */
.balance-chip {
background: linear-gradient(90deg,
rgba(0, 243, 255, 0.15),
rgba(255, 208, 97, 0.15),
rgba(255, 42, 109, 0.15)
);
border: 1rpx solid rgba(0, 243, 255, 0.3);
border: 1rpx solid rgba(255, 208, 97, 0.3);
border-radius: 20rpx;
padding: 10rpx 20rpx;
display: flex;
@@ -154,8 +154,8 @@
height: 44rpx;
min-width: 180rpx;
box-shadow:
0 4rpx 12rpx rgba(0, 243, 255, 0.2),
inset 0 0 8rpx rgba(0, 243, 255, 0.1);
0 4rpx 12rpx rgba(255, 208, 97, 0.2),
inset 0 0 8rpx rgba(255, 208, 97, 0.1);
position: relative;
z-index: 10; /* 确保在最上层 */
}
@@ -201,9 +201,9 @@
color: var(--text-primary) !important; /* 强制使用白色 */
line-height: 1;
text-shadow:
0 0 20rpx rgba(0, 243, 255, 0.8),
0 0 40rpx rgba(0, 243, 255, 0.5),
0 0 60rpx rgba(0, 243, 255, 0.3);
0 0 20rpx rgba(255, 208, 97, 0.8),
0 0 40rpx rgba(255, 208, 97, 0.5),
0 0 60rpx rgba(255, 208, 97, 0.3);
letter-spacing: -1.5rpx;
display: inline-block;
position: relative;
@@ -242,10 +242,10 @@
display: flex;
align-items: center;
justify-content: center;
background: rgba(0, 243, 255, 0.08);
background: rgba(255, 208, 97, 0.08);
padding: 10rpx 22rpx;
border-radius: 18rpx;
border: 1rpx solid rgba(0, 243, 255, 0.2);
border: 1rpx solid rgba(255, 208, 97, 0.2);
min-width: 150rpx;
}
@@ -337,7 +337,7 @@
/* ========== 充值金额区域 ========== */
.amount-section {
background: rgba(25, 30, 48, 0.9);
background: #fef6d4;
border-radius: 25rpx;
padding: 35rpx 25rpx;
margin-bottom: 35rpx;
@@ -345,7 +345,7 @@
backdrop-filter: blur(4px);
box-shadow:
var(--shadow-tech),
inset 0 0 15rpx rgba(0, 243, 255, 0.05);
inset 0 0 15rpx rgba(255, 208, 97, 0.05);
position: relative;
z-index: 1;
}
@@ -387,8 +387,8 @@
}
.amount-item {
background: rgba(255, 255, 255, 0.05);
border: 2rpx solid rgba(255, 255, 255, 0.12);
background: rgba(255, 255, 255, 0.85);
border: 2rpx solid rgba(255, 208, 97, 0.35);
border-radius: 18rpx;
padding: 26rpx 10rpx;
text-align: center;
@@ -408,15 +408,15 @@
.amount-item.active {
background: linear-gradient(135deg,
rgba(0, 243, 255, 0.15),
rgba(157, 78, 221, 0.15)
rgba(250, 224, 77, 0.35),
rgba(255, 192, 163, 0.35)
);
border-color: var(--primary-color);
transform: translateY(-3rpx);
box-shadow:
0 10rpx 25rpx rgba(0, 243, 255, 0.2),
0 0 30rpx rgba(0, 243, 255, 0.1),
inset 0 0 12rpx rgba(0, 243, 255, 0.1);
0 10rpx 25rpx rgba(255, 208, 97, 0.2),
0 0 30rpx rgba(255, 208, 97, 0.1),
inset 0 0 12rpx rgba(255, 208, 97, 0.1);
}
.amount-text {
@@ -442,7 +442,7 @@
height: 90%;
background: radial-gradient(
circle at center,
rgba(0, 243, 255, 0.2) 0%,
rgba(255, 208, 97, 0.2) 0%,
transparent 70%
);
border-radius: 50%;
@@ -515,7 +515,7 @@
.custom-input:focus {
border-bottom-color: var(--primary-color);
box-shadow: 0 0 15rpx rgba(0, 243, 255, 0.3);
box-shadow: 0 0 15rpx rgba(255, 208, 97, 0.3);
}
.placeholder {
@@ -589,23 +589,23 @@
/* 激活状态 - 修复为科技蓝渐变 */
.pay-button.active {
background: linear-gradient(135deg,
#008ca3, /* 深蓝 */
#00b8d4, /* 中蓝 */
#00f3ff /* 亮蓝 */
#fae04d,
#ffc0a3,
#ffd061
);
border: 1.5rpx solid rgba(0, 243, 255, 0.6);
border: 1.5rpx solid rgba(255, 208, 97, 0.6);
box-shadow:
0 12rpx 35rpx rgba(0, 243, 255, 0.4),
0 0 50rpx rgba(0, 243, 255, 0.3),
inset 0 0 20rpx rgba(0, 243, 255, 0.15);
0 12rpx 35rpx rgba(255, 208, 97, 0.4),
0 0 50rpx rgba(255, 208, 97, 0.3),
inset 0 0 20rpx rgba(255, 208, 97, 0.15);
}
.pay-button.active:active {
transform: scale(0.98);
box-shadow:
0 8rpx 25rpx rgba(0, 243, 255, 0.4),
0 0 35rpx rgba(0, 243, 255, 0.3),
inset 0 0 15rpx rgba(0, 243, 255, 0.15);
0 8rpx 25rpx rgba(255, 208, 97, 0.4),
0 0 35rpx rgba(255, 208, 97, 0.3),
inset 0 0 15rpx rgba(255, 208, 97, 0.15);
}
/* 按钮闪光特效 */
@@ -658,7 +658,7 @@
color: white !important;
text-shadow:
0 0 12rpx rgba(255, 255, 255, 0.8),
0 0 25rpx rgba(0, 243, 255, 0.6);
0 0 25rpx rgba(255, 208, 97, 0.6);
}
/* ========== 支付状态提示 ========== */
@@ -668,7 +668,7 @@
left: 0;
right: 0;
bottom: 0;
background: rgba(10, 14, 23, 0.95);
background: rgba(255, 248, 225, 0.95);
display: flex;
justify-content: center;
align-items: center;
@@ -678,8 +678,8 @@
.status-content {
background: linear-gradient(135deg,
rgba(25, 30, 48, 0.95),
rgba(40, 47, 75, 0.95)
#fff,
#fef6d4
);
border-radius: 28rpx;
padding: 60rpx 40rpx;
@@ -689,7 +689,7 @@
border: 2rpx solid var(--primary-color);
box-shadow:
0 20rpx 50rpx rgba(0, 0, 0, 0.6),
0 0 50rpx rgba(0, 243, 255, 0.4);
0 0 50rpx rgba(255, 208, 97, 0.4);
position: relative;
overflow: hidden;
animation: statusAppear 0.3s ease-out;
@@ -706,7 +706,7 @@
color: var(--text-primary) !important;
display: block;
margin-bottom: 15rpx;
text-shadow: 0 0 10rpx rgba(0, 243, 255, 0.6);
text-shadow: 0 0 10rpx rgba(255, 208, 97, 0.6);
position: relative;
z-index: 10;
}
@@ -729,13 +729,13 @@
}
.action-button {
background: linear-gradient(135deg, #008ca3, #00f3ff);
background: linear-gradient(135deg, #fae04d, #ffd061);
border-radius: 20rpx;
padding: 20rpx 40rpx;
min-width: 200rpx;
box-shadow:
0 8rpx 24rpx rgba(0, 243, 255, 0.4),
0 0 16rpx rgba(0, 243, 255, 0.3);
0 8rpx 24rpx rgba(255, 208, 97, 0.4),
0 0 16rpx rgba(255, 208, 97, 0.3);
display: flex;
align-items: center;
justify-content: center;
@@ -745,8 +745,8 @@
.action-button:active {
transform: scale(0.95);
box-shadow:
0 4rpx 12rpx rgba(0, 243, 255, 0.4),
0 0 8rpx rgba(0, 243, 255, 0.3);
0 4rpx 12rpx rgba(255, 208, 97, 0.4),
0 0 8rpx rgba(255, 208, 97, 0.3);
}
.action-text {
@@ -764,7 +764,7 @@
left: 0;
right: 0;
bottom: 0;
background: rgba(10, 14, 23, 0.92);
background: rgba(255, 248, 225, 0.92);
display: flex;
justify-content: center;
align-items: center;
@@ -793,7 +793,7 @@
margin: 0 auto 30rpx;
box-shadow:
0 0 20rpx var(--primary-color),
inset 0 0 12rpx rgba(0, 243, 255, 0.2);
inset 0 0 12rpx rgba(255, 208, 97, 0.2);
position: relative;
}
@@ -805,7 +805,7 @@
.loading-text {
font-size: 28rpx;
color: var(--text-primary);
text-shadow: 0 0 10rpx rgba(0, 243, 255, 0.6);
text-shadow: 0 0 10rpx rgba(255, 208, 97, 0.6);
letter-spacing: 1rpx;
}
@@ -814,12 +814,12 @@
/* ========== 修复背景颜色和间距 ========== */
/* 1. 调整背景颜色为更亮的科技风 */
/* 1. 橙黄主题背景 */
page {
background: linear-gradient(135deg,
#0e1424 0%, /* 调亮深色部分 */
#1a2238 50%,
#242d45 100%
background: linear-gradient(180deg,
#f7dc51 0%,
#fff8e1 50%,
#fff9f0 100%
) !important;
height: 100%;
}
@@ -836,8 +836,8 @@ page {
margin: 0 0 30rpx !important; /* 增加下方间距 */
padding: 35rpx 25rpx !important; /* 增加内边距 */
border-radius: 25rpx !important;
background: rgba(25, 30, 48, 0.9) !important; /* 调亮背景 */
border: 1.5rpx solid rgba(0, 243, 255, 0.4) !important; /* 加强边框 */
background: #fef6d4 !important; /* 调亮背景 */
border: 1.5rpx solid rgba(255, 208, 97, 0.4) !important; /* 加强边框 */
}
/* 4. 调整余额字体和颜色 - 确保可见 */
@@ -847,21 +847,19 @@ page {
.currency {
font-size: 42rpx !important;
color: #ffd700 !important; /* 使用更亮的金色 */
text-shadow: 0 0 20rpx rgba(255, 215, 0, 0.8) !important;
color: #e67e22 !important;
text-shadow: none !important;
}
.amount {
font-size: 72rpx !important; /* 稍微调大 */
color: #ffffff !important;
text-shadow:
0 0 25rpx rgba(0, 243, 255, 0.8),
0 0 50rpx rgba(0, 243, 255, 0.5) !important;
font-size: 72rpx !important;
color: #222 !important;
text-shadow: none !important;
}
.unit {
font-size: 30rpx !important;
color: #a0aec0 !important; /* 调亮灰色 */
color: #666 !important;
}
/* 5. 调整充值金额区域 */
@@ -869,7 +867,7 @@ page {
margin-bottom: 30rpx !important;
padding: 30rpx 25rpx !important;
border-radius: 25rpx !important;
background: rgba(30, 35, 55, 0.9) !important; /* 调亮背景 */
background: #fff !important; /* 调亮背景 */
}
/* 6. 调整快捷金额网格 */
@@ -885,7 +883,7 @@ page {
.amount-text {
font-size: 32rpx !important;
color: #ffffff !important;
color: #333 !important;
}
/* 7. 调整输入区域 - 修复占位符溢出问题 */
@@ -900,27 +898,27 @@ page {
.custom-input {
padding: 28rpx 20rpx 28rpx 60rpx !important;
height: 145rpx !important; /* 增加高度,让内容有足够空间 */
height: 145rpx !important;
font-size: 40rpx !important;
color: #ffffff !important;
border-bottom: 2rpx solid rgba(255, 255, 255, 0.2) !important;
color: #222 !important;
border-bottom: 2rpx solid rgba(0, 0, 0, 0.12) !important;
}
.custom-input:focus {
border-bottom-color: #00f3ff !important;
box-shadow: 0 0 20rpx rgba(0, 243, 255, 0.4) !important;
border-bottom-color: #ffd061 !important;
box-shadow: 0 0 20rpx rgba(255, 208, 97, 0.4) !important;
}
.input-label {
font-size: 40rpx !important;
color: #ffd700 !important; /* 使用金色 */
text-shadow: 0 0 15rpx rgba(255, 215, 0, 0.6) !important;
color: #e67e22 !important;
text-shadow: none !important;
top: 50% !important;
transform: translateY(-50%) !important;
}
.placeholder {
color: rgba(160, 174, 192, 0.8) !important; /* 调亮占位符 */
color: rgba(102, 102, 102, 0.7) !important;
font-size: 34rpx !important;
font-weight: 500 !important;
}
@@ -937,49 +935,45 @@ page {
.pay-button.active {
background: linear-gradient(135deg,
#0099b0, /* 更亮的蓝 */
#00ccff, /* 亮蓝 */
#00f3ff /* 最亮蓝 */
#fae04d,
#ffc0a3,
#ffd061
) !important;
border: 1.5rpx solid rgba(0, 243, 255, 0.8) !important;
border: 1.5rpx solid rgba(255, 208, 97, 0.8) !important;
}
.button-text {
font-size: 36rpx !important;
color: #ffffff !important;
text-shadow: 0 0 10rpx rgba(0, 243, 255, 0.8) !important;
color: #492f00 !important;
text-shadow: none !important;
}
/* 9. 调整标题文字颜色 - 确保清晰可见 */
.title-text {
font-size: 36rpx !important;
color: #ffffff !important;
text-shadow:
0 0 20rpx rgba(0, 243, 255, 0.8),
0 0 40rpx rgba(0, 243, 255, 0.4) !important;
color: #222 !important;
text-shadow: none !important;
}
.section-title {
font-size: 34rpx !important;
color: #ffffff !important;
text-shadow: 0 0 15rpx rgba(255, 255, 255, 0.3) !important;
color: #222 !important;
text-shadow: none !important;
}
.subtitle-text,
.amount-hint {
color: #b8c2cc !important; /* 调亮灰色文字 */
color: #666 !important;
font-size: 26rpx !important;
}
/* 10. 调整卡片文字颜色 */
.chip-text {
color: #ffffff !important;
text-shadow: 0 0 8rpx rgba(0, 243, 255, 0.6) !important;
color: #492f00 !important;
text-shadow: none !important;
}
.tag-text {
color: #4dfbff !important; /* 使用亮科技蓝 */
text-shadow: 0 0 8rpx rgba(0, 243, 255, 0.4) !important;
color: #e67e22 !important;
text-shadow: none !important;
}
/* 11. 增强装饰元素可见性(但不干扰文字) */

View File

@@ -5,9 +5,9 @@
"chenghao-tag": "/components/chenghao-tag/chenghao-tag"
},
"backgroundTextStyle": "dark",
"navigationBarBackgroundColor": "#f5f3ff",
"navigationBarBackgroundColor": "#f7dc51",
"navigationBarTitleText": "常规发单",
"navigationBarTextStyle": "black",
"backgroundColor": "#f5f5f5",
"backgroundColor": "#fff8e1",
"enablePullDownRefresh": false
}

View File

@@ -1,4 +1,4 @@
.page { padding: 24rpx; background: #f5f5f5; min-height: 100vh; box-sizing: border-box; }
.page { padding: 24rpx; background: #fff8e1; min-height: 100vh; box-sizing: border-box; }
.head-tip { font-size: 24rpx; color: #888; margin-bottom: 16rpx; line-height: 1.5; }
.tabs { display: flex; margin-bottom: 24rpx; }
.tab { flex: 1; text-align: center; padding: 20rpx; background: #fff; margin-right: 8rpx; border-radius: 8rpx; font-size: 28rpx; }

View File

@@ -2,7 +2,7 @@
.role-page {
min-height: 100vh;
background: linear-gradient(180deg, #c4b5fd 0%, #fff 28%, #f5f3ff 100%);
background: linear-gradient(180deg, #f7dc51 0%, #fff 28%, #fff8e1 100%);
box-sizing: border-box;
}

View File

@@ -6,7 +6,7 @@
"chenghao-tag": "/components/chenghao-tag/chenghao-tag"
},
"navigationStyle": "custom",
"backgroundColor": "#f5f3ff",
"backgroundColor": "#fff8e1",
"backgroundTextStyle": "dark",
"enablePullDownRefresh": true
}

View File

@@ -1,7 +1,7 @@
@import '../../styles/shangjia-xym-common.wxss';
page {
background: #f5f3ff;
background: #fff8e1;
}
.user-page {
@@ -120,7 +120,7 @@ page {
font-size: 24rpx;
font-weight: 600;
color: #7a5a12;
background: linear-gradient(180deg, #f5f3ff, #ffe9b8);
background: linear-gradient(180deg, #fff8e1, #ffe9b8);
border: 1rpx solid #e8c547;
border-radius: 28rpx;
box-shadow: 0 2rpx 8rpx rgba(200, 160, 40, 0.15);
@@ -301,7 +301,7 @@ page {
width: 60rpx;
height: 60rpx;
border: 4rpx solid rgba(0, 0, 0, 0.08);
border-top-color: #9333ea;
border-top-color: #ffd061;
border-radius: 50%;
animation: sjSpin 0.8s linear infinite;
}

View File

@@ -535,7 +535,10 @@ Page(createPage({
switchTab(e) {
const index = parseInt(e.currentTarget.dataset.index);
this.setData({ activeTab: index, displayCount: 10, searchKeyword: '' }, () => this.applyFilter());
this.setData({ activeTab: index, displayCount: 10, searchKeyword: '' }, () => {
this.applyFilter();
this.calculateScrollHeight();
});
},
onSearchInput(e) {
@@ -662,8 +665,9 @@ Page(createPage({
const rpxRatio = 750 / windowWidth;
const headerHeight = 150 / rpxRatio;
const tabBarHeight = 130 / rpxRatio;
const kefuBarHeight = this.data.activeTab === 2 ? (112 / rpxRatio) : 0;
const safeAreaBottom = systemInfo.safeArea ? (windowHeight - systemInfo.safeArea.bottom) : 0;
this.setData({ scrollHeight: windowHeight - headerHeight - tabBarHeight - safeAreaBottom });
this.setData({ scrollHeight: windowHeight - headerHeight - tabBarHeight - kefuBarHeight - safeAreaBottom });
},
onAvatarError(e) {

View File

@@ -1,4 +1,5 @@
{
"navigationBarTitleText": "星之界",
"usingComponents": {
"global-notification": "/components/global-notification/global-notification",
"tab-bar": "/tab-bar/index"

View File

@@ -31,6 +31,10 @@
</view>
</view>
<view class="kefu-entry" wx:if="{{activeTab === 2}}">
<button class="kefu-btn" bindtap="chatKefu">💬 联系客服</button>
</view>
<!-- 会话列表 (上拉加载更多) -->
<scroll-view class="conversation-list" scroll-y="true" bindscrolltolower="onScrollToLower" style="height: {{scrollHeight}}px">
<block wx:for="{{filteredConversations}}" wx:key="key" wx:for-index="i" wx:if="{{i < displayCount}}">
@@ -66,9 +70,6 @@
</view>
</block>
<view class="kefu-entry" wx:if="{{activeTab === 2 && filteredConversations.length === 0}}">
<button class="kefu-btn" bindtap="chatKefu">联系客服</button>
</view>
<view class="load-tip" wx:if="{{filteredConversations.length > displayCount}}">上拉加载更多</view>
<view class="empty" wx:if="{{filteredConversations.length === 0 && activeTab !== 2}}">
<text>暂无相关消息</text>

View File

@@ -337,16 +337,25 @@
/* 客服入口 */
.kefu-entry {
text-align: center;
padding: 100rpx 0;
padding: 16rpx 24rpx 8rpx;
background: #fff;
}
.kefu-btn {
width: 300rpx;
background: #07c160;
width: 100%;
height: 88rpx;
line-height: 88rpx;
background: linear-gradient(135deg, #07c160 0%, #06ad56 100%);
color: #fff;
border-radius: 40rpx;
font-size: 28rpx;
border-radius: 44rpx;
font-size: 32rpx;
font-weight: 700;
box-shadow: 0 8rpx 24rpx rgba(7, 193, 96, 0.35);
border: none;
}
.kefu-btn::after {
border: none;
}
/* 操作弹窗 */

View File

@@ -141,7 +141,7 @@ page {
line-height: 1.2;
}
.gradient-bg {
background: linear-gradient(to right, rgba(147, 51, 234, 0.05), rgba(147, 51, 234, 0.15));
background: linear-gradient(to right, rgba(255, 208, 97, 0.05), rgba(255, 208, 97, 0.15));
}
.title-text {
font-size: 34rpx;

View File

@@ -308,13 +308,16 @@ Page({
let params = {};
switch (failureType) {
case 'huiyuan':
params = { needScroll: '0', scrollTo: 'member' };
url = '/pages/fighter-recharge/fighter-recharge';
params = { scrollTo: 'member' };
break;
case 'yajin':
params = { needScroll: '1', scrollTo: 'bottom', requiredYajin: requiredYajin };
url = '/pages/fighter-recharge/fighter-deposit';
params = { requiredYajin: requiredYajin };
break;
case 'jifen':
params = { needScroll: '1', scrollTo: 'bottom' };
url = '/pages/fighter-recharge/fighter-recharge';
params = { scrollTo: 'jifen' };
break;
}
if (huiyuanId) params.huiyuanId = huiyuanId;

View File

@@ -25,7 +25,7 @@
class="xym-lunbo-swiper"
indicator-dots="{{lunboList.length > 1}}"
indicator-color="rgba(255,255,255,0.6)"
indicator-active-color="#9333ea"
indicator-active-color="#ffd061"
autoplay="{{lunboList.length > 1}}"
interval="4000"
circular

View File

@@ -1,288 +1,401 @@
// 管事会员记录页面逻辑
// 佣金记录(三合一:接单佣金 / 管事分佣 / 组长分红)
import request from '../../utils/request.js';
import { getOrderStatusText } from '../../utils/api-helper.js';
import { isRoleStatusActive } from '../../utils/base-page.js';
// 每页数据条数常量 - 统一管理,方便修改
const MEIYE_TIAOSHU = 50;
const MEIYE_TIAOSHU_GUANSHI = 50;
const PAGE_SIZE_DASHOU = 15;
const PAGE_SIZE_ZUZHANG = 5;
const REFRESH_CD = 2000;
const TAB_MAP = {
dashou: 'dashou',
commission: 'dashou',
guanshi: 'guanshi',
recharge: 'guanshi',
zuzhang: 'zuzhang',
fenhong: 'zuzhang',
};
Page({
data: {
// 从全局变量获取的数据
yaoqingzongshu: 0, // 邀请打手总数
fenyongzonge: '0.00', // 分成总额
// 从接口获取的数据
chongzhiDashouShuliang: 0, // 充值打手数量
dashouList: [], // 打手列表数据
zongTiaoshu: 0, // 总条数
// 分页相关
dangqianYe: 1, // 当前页
meiyouGengduo: false, // 没有更多数据
jiazaiZhong: false, // 加载中状态
jiazaiGengduo: false, // 加载更多状态
// UI状态
cuowuTishi: '', // 错误提示
shuaxinKezhi: false, // 刷新按钮是否可点击
shuaxinCd: 2000, // 刷新冷却时间(毫秒)
// 常量(用于模板)
meiyeTiaoshu: MEIYE_TIAOSHU // 每页条数
activeTab: 'dashou',
tabs: [],
isDashou: false,
isGuanshi: false,
isZuzhang: false,
// 管事分佣统计
yaoqingzongshu: 0,
fenyongzonge: '0.00',
chongzhiDashouShuliang: 0,
// 组长分红统计
fenhongZonge: '0.00',
yaoqingGuanshi: 0,
fenhongCishu: 0,
// 接单佣金列表
dashouCommissionList: [],
dashouPage: 1,
dashouHasMore: true,
dashouTotal: 0,
// 管事分佣列表
guanshiList: [],
guanshiPage: 1,
guanshiHasMore: false,
guanshiTotal: 0,
// 组长分红列表
zuzhangList: [],
zuzhangPage: 1,
zuzhangHasMore: true,
zuzhangTotal: 0,
jiazaiZhong: false,
jiazaiGengduo: false,
shuaxinKezhi: false,
cuowuTishi: '',
loadedTabs: {},
scrollTop: 0,
},
onLoad(options) {
// 从全局变量获取管事数据
this.huoquQuanjubianliang();
// 加载第一页数据
this.jiazaiShuju(true);
this._initRoles();
const requested = TAB_MAP[(options.tab || options.type || '').trim()] || 'dashou';
const tabs = this._buildTabs();
const activeTab = tabs.find((t) => t.key === requested)?.key || tabs[0]?.key || 'dashou';
this.setData({ tabs, activeTab }, () => {
if (this.data.isGuanshi) this.huoquQuanjubianliang();
this._loadTab(activeTab, true);
});
},
onShow() {
// 页面显示时检查全局变量是否有更新
this.registerNotificationComponent();
this.huoquQuanjubianliang();
if (this.data.isGuanshi) this.huoquQuanjubianliang();
},
// 🆕 新增:注册通知组件
registerNotificationComponent() {
const app = getApp();
const notificationComp = this.selectComponent('#global-notification');
if (notificationComp && notificationComp.showNotification) {
console.log('🏪 商城页面注册通知组件');
app.globalData.globalNotification = {
show: (data) => notificationComp.showNotification(data),
hide: () => notificationComp.hideNotification()
};
}
},
// 获取全局变量数据
huoquQuanjubianliang() {
registerNotificationComponent() {
const app = getApp();
const guanshiData = app.globalData.guanshi;
const notificationComp = this.selectComponent('#global-notification');
if (notificationComp && notificationComp.showNotification) {
app.globalData.globalNotification = {
show: (data) => notificationComp.showNotification(data),
hide: () => notificationComp.hideNotification(),
};
}
},
_initRoles() {
const isDashou = isRoleStatusActive(wx.getStorageSync('dashoustatus'));
const isGuanshi = isRoleStatusActive(wx.getStorageSync('guanshistatus'));
const isZuzhang = isRoleStatusActive(wx.getStorageSync('zuzhangstatus'));
this.setData({
isDashou: isDashou || (!isGuanshi && !isZuzhang),
isGuanshi,
isZuzhang,
});
},
_buildTabs() {
const { isDashou, isGuanshi, isZuzhang } = this.data;
const tabs = [];
if (isDashou) tabs.push({ key: 'dashou', label: '接单佣金' });
if (isGuanshi) tabs.push({ key: 'guanshi', label: '管事分佣' });
if (isZuzhang) tabs.push({ key: 'zuzhang', label: '组长分红' });
if (!tabs.length) tabs.push({ key: 'dashou', label: '接单佣金' });
return tabs;
},
onTabTap(e) {
const key = e.currentTarget.dataset.key;
if (key === this.data.activeTab) return;
this.setData({ activeTab: key, cuowuTishi: '', scrollTop: 0 });
if (!this.data.loadedTabs[key]) {
this._loadTab(key, true);
}
},
huoquQuanjubianliang() {
const guanshiData = getApp().globalData.guanshi;
if (guanshiData) {
this.setData({
yaoqingzongshu: guanshiData.yaoqingzongshu || 0,
fenyongzonge: guanshiData.fenyongzonge || '0.00'
fenyongzonge: guanshiData.fenyongzonge || '0.00',
});
}
},
// 加载数据核心方法
async jiazaiShuju(chushihua = false) {
// 防止重复请求
if (this.data.jiazaiZhong) return;
// 如果是初始化加载,重置分页
if (chushihua) {
_loadTab(tab, reset) {
if (tab === 'dashou') return this._loadDashouCommission(reset);
if (tab === 'guanshi') return this._loadGuanshi(reset);
if (tab === 'zuzhang') return this._loadZuzhang(reset);
return Promise.resolve();
},
shuaxinShuju() {
if (this.data.shuaxinKezhi) {
wx.showToast({ title: `请等待${REFRESH_CD / 1000}`, icon: 'none' });
return;
}
this.setData({ shuaxinKezhi: true, cuowuTishi: '' });
this._loadTab(this.data.activeTab, true).finally(() => {
setTimeout(() => this.setData({ shuaxinKezhi: false }), REFRESH_CD);
});
},
shanglaJiazai() {
const { activeTab, jiazaiGengduo, jiazaiZhong, loadedTabs } = this.data;
if (!loadedTabs[activeTab] || jiazaiGengduo || jiazaiZhong) return;
if (activeTab === 'dashou' && !this.data.dashouHasMore) return;
if (activeTab === 'guanshi' && this.data.guanshiHasMore === false) return;
if (activeTab === 'zuzhang' && !this.data.zuzhangHasMore) return;
this._loadTab(activeTab, false);
},
chongshiJiazai() {
this.setData({ cuowuTishi: '' });
this._loadTab(this.data.activeTab, true);
},
async _loadDashouCommission(reset) {
if (this.data.jiazaiZhong || this.data.jiazaiGengduo) return;
const page = reset ? 1 : this.data.dashouPage;
if (!reset && !this.data.dashouHasMore) return;
this.setData({
jiazaiZhong: reset,
jiazaiGengduo: !reset,
cuowuTishi: '',
});
try {
const res = await request({
url: '/dingdan/dshqdingdan',
method: 'POST',
data: {
zhuangtai_list: [3, 8],
page,
page_size: PAGE_SIZE_DASHOU,
},
});
const body = res?.data;
if (body && (body.code === 200 || body.code === 0)) {
const raw = body.data?.list || [];
const rows = raw.map((item) => {
const amt = item.jine || item.dashou_fencheng || '0.00';
const brief = (item.jieshao || '').trim();
const title = brief
? (brief.length > 18 ? `${brief.slice(0, 18)}` : brief)
: `订单 ${item.dingdan_id || ''}`;
return {
id: item.dingdan_id,
title,
time: item.wancheng_shijian || item.jiesuan_shijian || item.creat_time || getOrderStatusText(item.zhuangtai),
amount: parseFloat(amt || 0).toFixed(2),
};
});
const list = reset ? rows : [...this.data.dashouCommissionList, ...rows];
const hasMore = body.data?.has_more ?? raw.length >= PAGE_SIZE_DASHOU;
const loadedTabs = { ...this.data.loadedTabs, dashou: true };
this.setData({
dashouCommissionList: list,
dashouPage: reset ? 2 : page + 1,
dashouHasMore: hasMore,
dashouTotal: body.data?.total || list.length,
loadedTabs,
});
} else {
this.setData({ cuowuTishi: body?.msg || '数据加载失败' });
}
} catch (e) {
console.error('接单佣金加载失败', e);
this.setData({ cuowuTishi: '网络错误,请检查网络连接' });
} finally {
this.setData({ jiazaiZhong: false, jiazaiGengduo: false });
}
},
async _loadGuanshi(reset) {
if (this.data.jiazaiZhong || this.data.jiazaiGengduo) return;
if (reset) {
this.setData({
dangqianYe: 1,
meiyouGengduo: false,
dashouList: [],
zongTiaoshu: 0,
chongzhiDashouShuliang: 0
guanshiPage: 1,
guanshiHasMore: false,
guanshiList: [],
guanshiTotal: 0,
chongzhiDashouShuliang: 0,
});
} else {
// 上拉加载更多时,检查是否还有更多数据
if (this.data.meiyouGengduo) return;
// 如果有数据但不足一页,说明后端已经没数据了
if (this.data.dashouList.length > 0 && this.data.dashouList.length < MEIYE_TIAOSHU) {
this.setData({ meiyouGengduo: true });
if (this.data.guanshiList.length > 0 && this.data.guanshiList.length < MEIYE_TIAOSHU_GUANSHI) {
this.setData({ guanshiHasMore: false });
return;
}
// 如果数据量已经达到总条数,则不请求
if (this.data.dashouList.length >= this.data.zongTiaoshu && this.data.zongTiaoshu > 0) {
this.setData({ meiyouGengduo: true });
if (this.data.guanshiList.length >= this.data.guanshiTotal && this.data.guanshiTotal > 0) {
this.setData({ guanshiHasMore: false });
return;
}
}
// 设置加载状态
const dangqianYe = reset ? 1 : this.data.guanshiPage;
this.setData({
jiazaiZhong: chushihua ? true : false,
jiazaiGengduo: !chushihua ? true : false,
cuowuTishi: ''
jiazaiZhong: reset,
jiazaiGengduo: !reset,
cuowuTishi: '',
});
try {
const { dangqianYe } = this.data;
// 严格按照您的request规范调用
const res = await request({
url: '/shangpin/fenhonghq',
method: 'POST',
data: {
page: dangqianYe,
page_size: MEIYE_TIAOSHU // 使用统一常量
}
data: { page: dangqianYe, page_size: MEIYE_TIAOSHU_GUANSHI },
});
// 处理返回数据
if (res.data.code === 200) {
const data = res.data.data || {};
const newList = data.list || [];
const total = data.total || 0;
// 处理头像URL拼接
const processedList = this.chuliTouxiangURL(newList);
// 计算是否有更多数据
const hasMoreData = processedList.length === MEIYE_TIAOSHU;
// 更新数据
const newList = this.chuliTouxiangURL(data.list || []);
const hasMore = newList.length === MEIYE_TIAOSHU_GUANSHI;
const loadedTabs = { ...this.data.loadedTabs, guanshi: true };
this.setData({
dashouList: chushihua ? processedList : [...this.data.dashouList, ...processedList],
zongTiaoshu: total,
guanshiList: reset ? newList : [...this.data.guanshiList, ...newList],
guanshiTotal: data.total || 0,
chongzhiDashouShuliang: data.chongzhi_dashou_shuliang || 0,
meiyouGengduo: !hasMoreData,
dangqianYe: chushihua ? 2 : this.data.dangqianYe + 1
guanshiHasMore: hasMore,
guanshiPage: reset ? 2 : dangqianYe + 1,
loadedTabs,
});
// 如果数据为空,显示空状态
if (chushihua && processedList.length === 0) {
wx.showToast({
title: '暂无数据',
icon: 'none',
duration: 1500
});
}
// 如果加载了数据,给个提示
if (processedList.length > 0) {
if (chushihua) {
wx.showToast({
title: `已加载${processedList.length}条记录`,
icon: 'success',
duration: 1000
});
}
}
} else {
this.setData({
cuowuTishi: res.data.msg || '数据加载失败'
});
wx.showToast({
title: res.data.msg || '加载失败',
icon: 'none',
duration: 2000
});
this.setData({ cuowuTishi: res.data.msg || '数据加载失败' });
}
} catch (error) {
console.error('加载数据失败:', error);
this.setData({
cuowuTishi: '网络错误,请检查网络连接'
});
wx.showToast({
title: '网络错误',
icon: 'none',
duration: 2000
});
} catch (e) {
console.error('管事分佣加载失败', e);
this.setData({ cuowuTishi: '网络错误,请检查网络连接' });
} finally {
this.setData({
jiazaiZhong: false,
jiazaiGengduo: false
});
this.setData({ jiazaiZhong: false, jiazaiGengduo: false });
}
},
async _loadZuzhang(reset) {
if (this.data.jiazaiZhong || this.data.jiazaiGengduo) return;
const page = reset ? 1 : this.data.zuzhangPage;
if (!reset && !this.data.zuzhangHasMore) return;
this.setData({
jiazaiZhong: reset,
jiazaiGengduo: !reset,
cuowuTishi: '',
});
try {
const res = await request({
url: '/shangpin/zuzhangfenhong',
method: 'POST',
data: { page, page_size: PAGE_SIZE_ZUZHANG },
});
if (res.data.code === 200) {
const data = res.data.data || {};
const processedList = this.processZuzhangList(data.list || []);
const loadedTabs = { ...this.data.loadedTabs, zuzhang: true };
if (reset) {
this.setData({
fenhongZonge: data.fenhong_zonge || '0.00',
yaoqingGuanshi: data.yaoqing_guanshi || 0,
fenhongCishu: data.fenhong_cishu || 0,
zuzhangList: processedList,
zuzhangTotal: data.total || 0,
zuzhangPage: 2,
zuzhangHasMore: processedList.length === PAGE_SIZE_ZUZHANG,
loadedTabs,
});
} else {
const newList = [...this.data.zuzhangList, ...processedList];
this.setData({
zuzhangList: newList,
zuzhangPage: page + 1,
zuzhangHasMore: processedList.length === PAGE_SIZE_ZUZHANG,
loadedTabs,
});
}
} else {
this.setData({ cuowuTishi: res.data.msg || '数据加载失败' });
}
} catch (e) {
console.error('组长分红加载失败', e);
this.setData({ cuowuTishi: '网络错误,请检查网络连接' });
} finally {
this.setData({ jiazaiZhong: false, jiazaiGengduo: false });
}
},
// 处理头像URL拼接
chuliTouxiangURL(list) {
const app = getApp();
const ossUrl = app.globalData.ossImageUrl || '';
return list.map(item => {
// 确保有头像URL如果没有则使用默认头像
return list.map((item) => {
let touxiangUrl = item.avatar || '';
if (touxiangUrl && !touxiangUrl.startsWith('http')) {
touxiangUrl = ossUrl + touxiangUrl;
}
// 格式化时间
let shijian = item.create_time || '';
if (shijian) {
// 如果是时间戳,转换为日期格式
if (/^\d+$/.test(shijian)) {
const date = new Date(parseInt(shijian));
shijian = `${date.getMonth() + 1}${date.getDate()}${date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}`;
const date = new Date(parseInt(shijian, 10));
shijian = `${date.getMonth() + 1}${date.getDate()}${String(date.getHours()).padStart(2, '0')}:${String(date.getMinutes()).padStart(2, '0')}`;
} else {
// 如果是字符串,提取日期和时间
try {
const dateObj = new Date(shijian);
shijian = `${dateObj.getMonth() + 1}${dateObj.getDate()}${dateObj.getHours().toString().padStart(2, '0')}:${dateObj.getMinutes().toString().padStart(2, '0')}`;
} catch (e) {
shijian = `${dateObj.getMonth() + 1}${dateObj.getDate()}${String(dateObj.getHours()).padStart(2, '0')}:${String(dateObj.getMinutes()).padStart(2, '0')}`;
} catch (err) {
shijian = shijian.substring(0, 10);
}
}
}
return {
...item,
touxiangUrl: touxiangUrl || '/images/default-avatar.png',
shijian: shijian,
fenhong: parseFloat(item.fenhong || 0).toFixed(2)
shijian,
fenhong: parseFloat(item.fenhong || 0).toFixed(2),
};
});
},
// 刷新数据(带防重复点击)
shuaxinShuju() {
// 检查是否在冷却中
if (this.data.shuaxinKezhi) {
wx.showToast({
title: `请等待${this.data.shuaxinCd/1000}`,
icon: 'none',
duration: 1000
});
return;
}
// 设置冷却状态
this.setData({ shuaxinKezhi: true });
// 显示刷新动画
this.setData({
jiazaiZhong: true
});
// 刷新数据
this.jiazaiShuju(true).finally(() => {
// 2秒后恢复按钮可点击
setTimeout(() => {
this.setData({ shuaxinKezhi: false });
}, this.data.shuaxinCd);
});
processZuzhangList(list) {
const app = getApp();
const ossUrl = app.globalData.ossImageUrl || '';
const defaultAvatar = ossUrl + (app.globalData.morentouxiang || 'avatar/default.jpg');
return list.map((item) => ({
dashouAvatar: this.getFullUrl(item.dashou_avatar, ossUrl, defaultAvatar),
dashouNicheng: item.dashou_nicheng || '接单员',
dashouYonghuid: item.dashou_yonghuid || '',
guanshiAvatar: this.getFullUrl(item.guanshi_avatar, ossUrl, defaultAvatar),
guanshiNicheng: item.guanshi_nicheng || '管事',
guanshiYonghuid: item.guanshi_yonghuid || '',
fenhong: parseFloat(item.fenhong || 0).toFixed(2),
shijian: this.formatTime(item.create_time),
}));
},
// 上拉加载更多
shanglaJiazai() {
// 没有更多数据时不再请求
if (this.data.meiyouGengduo) {
wx.showToast({
title: '已经到底了',
icon: 'none',
duration: 1000
});
return;
}
// 如果正在加载,不再请求
if (this.data.jiazaiGengduo || this.data.jiazaiZhong) {
return;
}
this.jiazaiShuju(false);
getFullUrl(relativePath, ossUrl, defaultUrl) {
if (!relativePath) return defaultUrl;
if (relativePath.startsWith('http')) return relativePath;
return ossUrl + (relativePath.startsWith('/') ? relativePath : `/${relativePath}`) || defaultUrl;
},
// 重试加载
chongshiJiazai() {
this.setData({
cuowuTishi: '',
meiyouGengduo: false
});
this.jiazaiShuju(true);
}
});
formatTime(timestamp) {
if (!timestamp) return '';
try {
const date = new Date(timestamp);
return `${date.getMonth() + 1}${date.getDate()}${String(date.getHours()).padStart(2, '0')}:${String(date.getMinutes()).padStart(2, '0')}`;
} catch (e) {
return String(timestamp).substring(0, 10) || '';
}
},
});

View File

@@ -1,11 +1,11 @@
{
"usingComponents": {
"global-notification": "/components/global-notification/global-notification"
},
"navigationBarTitleText": "会员记录",
"navigationBarBackgroundColor": "#0a0a0f",
"navigationBarTextStyle": "white",
"backgroundColor": "#0a0a0f",
"backgroundTextStyle": "light",
"enablePullDownRefresh": false
}
"usingComponents": {
"global-notification": "/components/global-notification/global-notification"
},
"navigationBarTitleText": "佣金记录",
"navigationBarBackgroundColor": "#f7dc51",
"navigationBarTextStyle": "black",
"backgroundColor": "#fff8e1",
"backgroundTextStyle": "dark",
"enablePullDownRefresh": false
}

View File

@@ -1,119 +1,191 @@
<!-- 管事会员记录页面 -->
<!-- 佣金记录(接单佣金 / 管事分佣 / 组长分红) -->
<view class="page-container">
<!-- 固定顶部区域 - 不动 -->
<view class="fixed-top">
<!-- 顶部统计区域 -->
<view class="tongji-quyu">
<!-- 分红总额 -->
<view class="fenyong-zonge">
<view class="zonge-label">分红总额</view>
<view class="zonge-value">¥{{fenyongzonge}}</view>
<view class="zonge-tip">累计收益</view>
</view>
<!-- Tab 切换 -->
<view class="tab-bar" wx:if="{{tabs.length > 1}}">
<view
wx:for="{{tabs}}"
wx:key="key"
class="tab-item {{activeTab === item.key ? 'active' : ''}}"
data-key="{{item.key}}"
bindtap="onTabTap"
>{{item.label}}</view>
</view>
<!-- 底部统计信息 -->
<view class="tongji-bottom">
<view class="tongji-item">
<view class="tongji-number">{{yaoqingzongshu}}</view>
<view class="tongji-label">邀请接单员</view>
<!-- 管事分佣统计 -->
<view class="stats-card" wx:if="{{activeTab === 'guanshi'}}">
<view class="stats-main">
<text class="stats-label">分红总额</text>
<text class="stats-amount">¥{{fenyongzonge}}</text>
<text class="stats-tip">累计管事分佣收益</text>
</view>
<view class="stats-row">
<view class="stats-cell">
<text class="stats-num">{{yaoqingzongshu}}</text>
<text class="stats-sub">邀请接单员</text>
</view>
<view class="tongji-divider"></view>
<view class="tongji-item">
<view class="tongji-number">{{chongzhiDashouShuliang}}</view>
<view class="tongji-label">充值接单员</view>
<view class="stats-divider"></view>
<view class="stats-cell">
<text class="stats-num">{{chongzhiDashouShuliang}}</text>
<text class="stats-sub">充值接单员</text>
</view>
</view>
</view>
<!-- 刷新按钮 -->
<view class="shuaxin-anniu" bindtap="shuaxinShuju">
<text class="shuaxin-icon {{shuaxinKezhi ? 'shuaxin-disabled' : ''}}">↻</text>
<!-- 组长分红统计 -->
<view class="stats-card" wx:if="{{activeTab === 'zuzhang'}}">
<view class="stats-row three">
<view class="stats-cell">
<text class="stats-label-sm">分红总额</text>
<text class="stats-amount-sm">¥{{fenhongZonge}}</text>
</view>
<view class="stats-divider"></view>
<view class="stats-cell">
<text class="stats-label-sm">邀请管事</text>
<text class="stats-num">{{yaoqingGuanshi}}</text>
</view>
<view class="stats-divider"></view>
<view class="stats-cell">
<text class="stats-label-sm">分红次数</text>
<text class="stats-num">{{fenhongCishu}}</text>
</view>
</view>
</view>
<!-- 接单佣金说明 -->
<view class="stats-card dashou-hd" wx:if="{{activeTab === 'dashou'}}">
<text class="dashou-title">接单佣金明细</text>
<text class="dashou-sub">已完成 / 已结算订单的分佣记录</text>
</view>
<view class="refresh-btn" bindtap="shuaxinShuju">
<text class="refresh-icon {{shuaxinKezhi ? 'spin' : ''}}">↻</text>
</view>
</view>
<!-- 滚动区域 - 只包裹列表部分 -->
<scroll-view
class="scroll-area"
<scroll-view
class="scroll-area {{tabs.length > 1 ? 'has-tabs' : ''}} {{activeTab}}"
scroll-y
enable-back-to-top
bindscrolltolower="shanglaJiazai">
<!-- 全局加载状态 -->
<view wx:if="{{jiazaiZhong && dashouList.length === 0}}" class="jiazai-quanju">
<view class="jiazai-spinner"></view>
<view class="jiazai-text">加载中...</view>
scroll-top="{{scrollTop}}"
bindscrolltolower="shanglaJiazai"
>
<!-- 加载中 -->
<view wx:if="{{jiazaiZhong && activeTab === 'dashou' && dashouCommissionList.length === 0}}" class="state-box">
<view class="spinner"></view>
<text>加载中...</text>
</view>
<!-- 空数据提示 -->
<view wx:if="{{!jiazaiZhong && dashouList.length === 0}}" class="kong-shuju">
<view class="kong-icon">🚀</view>
<view class="kong-text">暂无会员记录</view>
<view class="kong-tip">快去邀请接单员吧</view>
<view class="kong-btn" bindtap="shuaxinShuju">点击刷新</view>
<view wx:if="{{jiazaiZhong && activeTab === 'guanshi' && guanshiList.length === 0}}" class="state-box">
<view class="spinner"></view>
<text>加载中...</text>
</view>
<view wx:if="{{jiazaiZhong && activeTab === 'zuzhang' && zuzhangList.length === 0}}" class="state-box">
<view class="spinner"></view>
<text>加载中...</text>
</view>
<!-- 会员记录卡片列表 -->
<block wx:if="{{dashouList.length > 0}}">
<!-- 列表标题 -->
<view class="list-title">
<text class="title-text">充值记录</text>
<text class="title-count">({{dashouList.length}}/{{zongTiaoshu}})</text>
<!-- 接单佣金列表 -->
<block wx:if="{{activeTab === 'dashou'}}">
<view wx:if="{{!jiazaiZhong && dashouCommissionList.length === 0}}" class="empty-box">
<text class="empty-icon">📋</text>
<text class="empty-title">暂无佣金记录</text>
<text class="empty-tip">完成订单后将在此展示</text>
<view class="empty-btn" bindtap="shuaxinShuju">刷新</view>
</view>
<!-- 卡片列表 -->
<view class="card-list">
<block wx:for="{{dashouList}}" wx:key="index">
<view class="dashou-card">
<!-- 圆形头像区域 -->
<view class="touxiang-quyu">
<image
class="dashou-touxiang"
src="{{item.touxiangUrl}}"
mode="aspectFill">
</image>
<!-- 头像边框效果 -->
<view class="touxiang-border"></view>
<block wx:if="{{dashouCommissionList.length > 0}}">
<view class="list-hd">
<text class="list-title">佣金明细</text>
<text class="list-count">{{dashouCommissionList.length}}条</text>
</view>
<view class="record-list">
<view wx:for="{{dashouCommissionList}}" wx:key="id" class="record-card">
<view class="record-main">
<text class="record-title">{{item.title}}</text>
<text class="record-time">{{item.time}}</text>
</view>
<text class="record-amt plus">+¥{{item.amount}}</text>
</view>
</view>
<view wx:if="{{jiazaiGengduo}}" class="footer-tip"><view class="spinner sm"></view><text>加载更多...</text></view>
<view wx:if="{{!dashouHasMore && dashouCommissionList.length > 0}}" class="footer-tip muted">—— 没有更多了 ——</view>
</block>
</block>
<!-- 信息区域 -->
<view class="xinxi-quyu">
<view class="nicheng">{{item.nicheng}}</view>
<view class="dashou-id">ID: {{item.yonghuid}}</view>
<!-- 管事分佣列表 -->
<block wx:if="{{activeTab === 'guanshi'}}">
<view wx:if="{{!jiazaiZhong && guanshiList.length === 0}}" class="empty-box">
<text class="empty-icon">🚀</text>
<text class="empty-title">暂无分佣记录</text>
<text class="empty-tip">邀请接单员充值后将获得分佣</text>
<view class="empty-btn" bindtap="shuaxinShuju">刷新</view>
</view>
<block wx:if="{{guanshiList.length > 0}}">
<view class="list-hd">
<text class="list-title">分佣明细</text>
<text class="list-count">{{guanshiList.length}}/{{guanshiTotal}}</text>
</view>
<view class="record-list">
<view wx:for="{{guanshiList}}" wx:key="index" class="record-card avatar-card">
<image class="avatar" src="{{item.touxiangUrl}}" mode="aspectFill"/>
<view class="record-main">
<text class="record-title">{{item.nicheng}}</text>
<text class="record-time">ID: {{item.yonghuid}} · {{item.shijian}}</text>
</view>
<!-- 分红金额区域 -->
<view class="fenhong-quyu">
<view class="fenhong-value">
<text class="fenhong-jiahao">+</text>
<text class="fenhong-shuzi">¥{{item.fenhong}}</text>
</view>
<view class="shijian">{{item.shijian}}</view>
<view class="amt-col">
<text class="record-amt plus">+¥{{item.fenhong}}</text>
</view>
</view>
</block>
</view>
<!-- 加载更多提示 -->
<view wx:if="{{jiazaiGengduo}}" class="jiazai-gengduo">
<view class="gengduo-spinner"></view>
<text class="gengduo-text">加载更多中...</text>
</view>
<!-- 没有更多数据 -->
<view wx:if="{{meiyouGengduo && dashouList.length > 0}}" class="meiyou-gengduo">
<view class="meiyou-icon">✓</view>
<text class="meiyou-text">已经到底了,共{{dashouList.length}}条记录</text>
</view>
<view wx:if="{{jiazaiGengduo}}" class="footer-tip"><view class="spinner sm"></view><text>加载更多...</text></view>
<view wx:if="{{!guanshiHasMore && guanshiList.length > 0}}" class="footer-tip muted">—— 没有更多了 ——</view>
</block>
</block>
<!-- 组长分红列表 -->
<block wx:if="{{activeTab === 'zuzhang'}}">
<view wx:if="{{!jiazaiZhong && zuzhangList.length === 0}}" class="empty-box">
<text class="empty-icon">📭</text>
<text class="empty-title">暂无分红记录</text>
<text class="empty-tip">邀请管事并让接单员充值即可获得分红</text>
<view class="empty-btn" bindtap="shuaxinShuju">刷新</view>
</view>
<block wx:if="{{zuzhangList.length > 0}}">
<view class="list-hd">
<text class="list-title">分红明细</text>
<text class="list-count">{{zuzhangList.length}}/{{zuzhangTotal}}</text>
</view>
<view class="record-list">
<view wx:for="{{zuzhangList}}" wx:key="index" class="bonus-card">
<view class="bonus-left">
<image class="avatar sm" src="{{item.dashouAvatar}}" mode="aspectFill"/>
<view class="bonus-info">
<text class="record-title">{{item.dashouNicheng}}</text>
<text class="record-time">ID: {{item.dashouYonghuid}}</text>
</view>
</view>
<view class="bonus-mid">
<text class="bonus-tag">所属管事</text>
<text class="bonus-arrow">→</text>
</view>
<view class="bonus-right">
<image class="avatar sm" src="{{item.guanshiAvatar}}" mode="aspectFill"/>
<view class="bonus-info">
<text class="record-title">{{item.guanshiNicheng}}</text>
<text class="record-amt plus">+¥{{item.fenhong}}</text>
<text class="record-time">{{item.shijian}}</text>
</view>
</view>
</view>
</view>
<view wx:if="{{jiazaiGengduo}}" class="footer-tip"><view class="spinner sm"></view><text>加载更多...</text></view>
<view wx:if="{{!zuzhangHasMore && zuzhangList.length > 0}}" class="footer-tip muted">—— 没有更多了 ——</view>
</block>
</block>
</scroll-view>
<!-- 错误提示 -->
<view wx:if="{{cuowuTishi}}" class="cuowu-quyu">
<view class="cuowu-icon">⚠️</view>
<view class="cuowu-text">{{cuowuTishi}}</view>
<view class="cuowu-btn" bindtap="chongshiJiazai">重试加载</view>
<view wx:if="{{cuowuTishi}}" class="error-bar">
<text>{{cuowuTishi}}</text>
<view class="error-btn" bindtap="chongshiJiazai">重试</view>
</view>
</view>
<global-notification id="global-notification" />

View File

@@ -1,506 +1,420 @@
/* 管事会员记录页面样式 - 赛博风格 */
/* 页面容器 */
/* 佣金记录 - 逍遥梦黄色风格 */
page {
height: 100%;
background: #0a0a0f;
}
.page-container {
height: 100%;
background: linear-gradient(135deg, #0a0a0f 0%, #1a1a2e 50%, #16213e 100%);
position: relative;
}
/* 固定顶部区域 */
.fixed-top {
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 100;
background: linear-gradient(135deg, #0a0a0f 0%, #1a1a2e 100%);
padding-bottom: 20rpx;
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.3);
}
/* 顶部统计区域 - 赛博卡片设计 */
.tongji-quyu {
position: relative;
margin: 20rpx 30rpx 0;
padding: 40rpx 30rpx;
background: rgba(20, 20, 35, 0.9);
border-radius: 24rpx;
border: 1px solid rgba(100, 255, 255, 0.1);
box-shadow:
0 10rpx 30rpx rgba(0, 0, 0, 0.4),
0 0 20rpx rgba(100, 255, 255, 0.05) inset,
0 0 0 1px rgba(100, 255, 255, 0.1);
backdrop-filter: blur(10px);
overflow: hidden;
}
.tongji-bg {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background:
linear-gradient(45deg,
rgba(100, 255, 255, 0.03) 0%,
rgba(255, 100, 255, 0.03) 100%);
z-index: 0;
}
/* 分红总额样式 - 赛博霓虹效果 */
.fenyong-zonge {
position: relative;
text-align: center;
padding: 20rpx 0 30rpx;
margin-bottom: 25rpx;
border-bottom: 1px solid rgba(100, 255, 255, 0.1);
z-index: 1;
}
.zonge-label {
font-size: 26rpx;
color: rgba(255, 255, 255, 0.7);
margin-bottom: 15rpx;
text-transform: uppercase;
letter-spacing: 2rpx;
}
.zonge-value {
font-size: 60rpx;
font-weight: 800;
color: #00ffea;
margin-bottom: 8rpx;
text-shadow:
0 0 10rpx rgba(0, 255, 234, 0.5),
0 0 20rpx rgba(0, 255, 234, 0.3);
font-family: 'Arial', sans-serif;
}
.zonge-tip {
font-size: 22rpx;
color: rgba(255, 255, 255, 0.5);
}
/* 底部统计信息 */
.tongji-bottom {
display: flex;
justify-content: space-around;
align-items: center;
z-index: 1;
position: relative;
}
.tongji-item {
text-align: center;
flex: 1;
}
.tongji-number {
font-size: 40rpx;
font-weight: 700;
color: #ffffff;
margin-bottom: 6rpx;
text-shadow: 0 0 10rpx rgba(255, 255, 255, 0.3);
}
.tongji-label {
font-size: 24rpx;
color: rgba(255, 255, 255, 0.6);
}
.tongji-divider {
width: 1px;
height: 45rpx;
background: linear-gradient(to bottom,
transparent 0%,
rgba(100, 255, 255, 0.3) 50%,
transparent 100%);
}
/* 刷新按钮 - 固定在右上角 */
.shuaxin-anniu {
position: absolute;
top: 60rpx;
right: 60rpx;
z-index: 200;
display: flex;
align-items: center;
justify-content: center;
width: 70rpx;
height: 70rpx;
background: rgba(20, 20, 35, 0.95);
border-radius: 50%;
border: 1px solid rgba(100, 255, 255, 0.2);
box-shadow:
0 8rpx 20rpx rgba(0, 0, 0, 0.4),
0 0 20rpx rgba(100, 255, 255, 0.1);
backdrop-filter: blur(10px);
transition: all 0.3s ease;
}
.shuaxin-anniu:active {
transform: scale(0.95);
background: rgba(100, 255, 255, 0.1);
box-shadow:
0 4rpx 10rpx rgba(0, 0, 0, 0.3),
0 0 30rpx rgba(100, 255, 255, 0.2);
}
.shuaxin-icon {
font-size: 32rpx;
color: #00ffea;
transition: all 0.3s ease;
}
.shuaxin-disabled {
color: rgba(255, 255, 255, 0.3);
animation: rotate 1s linear infinite;
}
@keyframes rotate {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
/* 滚动区域 - 只包裹列表部分 */
.scroll-area {
position: fixed;
top: 340rpx; /* 根据固定区域高度调整 */
left: 0;
right: 0;
bottom: 0;
z-index: 50;
}
/* 全局加载状态 */
.jiazai-quanju {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 120rpx 0;
}
.jiazai-spinner {
width: 80rpx;
height: 80rpx;
border: 4rpx solid rgba(100, 255, 255, 0.1);
border-top: 4rpx solid #00ffea;
border-radius: 50%;
animation: spin 1s linear infinite;
margin-bottom: 30rpx;
box-shadow: 0 0 20rpx rgba(0, 255, 234, 0.3);
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.jiazai-text {
font-size: 28rpx;
color: rgba(255, 255, 255, 0.7);
}
/* 空数据提示 */
.kong-shuju {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 120rpx 30rpx;
background: rgba(20, 20, 35, 0.5);
border-radius: 24rpx;
border: 1px solid rgba(100, 255, 255, 0.1);
margin: 40rpx 30rpx 0;
}
.kong-icon {
font-size: 100rpx;
margin-bottom: 30rpx;
color: rgba(255, 255, 255, 0.2);
}
.kong-text {
font-size: 32rpx;
color: rgba(255, 255, 255, 0.8);
margin-bottom: 10rpx;
font-weight: 500;
}
.kong-tip {
font-size: 26rpx;
color: rgba(255, 255, 255, 0.5);
margin-bottom: 50rpx;
}
.kong-btn {
padding: 20rpx 50rpx;
background: linear-gradient(90deg, #00ffea 0%, #0088ff 100%);
color: #000;
border-radius: 50rpx;
font-size: 28rpx;
font-weight: 600;
box-shadow: 0 8rpx 20rpx rgba(0, 255, 234, 0.3);
}
.kong-btn:active {
transform: scale(0.95);
box-shadow: 0 4rpx 10rpx rgba(0, 255, 234, 0.2);
}
/* 列表标题 */
.list-title {
margin: 0 30rpx 20rpx;
display: flex;
align-items: baseline;
}
.title-text {
font-size: 32rpx;
color: #ffffff;
font-weight: 600;
margin-right: 10rpx;
text-shadow: 0 0 10rpx rgba(255, 255, 255, 0.2);
}
.title-count {
font-size: 24rpx;
color: rgba(255, 255, 255, 0.5);
}
/* 卡片列表 */
.card-list {
margin: 0 30rpx;
}
/* 打手卡片 - 赛博风格设计 */
.dashou-card {
position: relative;
display: flex;
align-items: center;
padding: 30rpx;
margin-bottom: 20rpx;
background: rgba(20, 20, 35, 0.7);
border-radius: 20rpx;
border: 1px solid rgba(100, 255, 255, 0.1);
box-shadow:
0 8rpx 24rpx rgba(0, 0, 0, 0.3),
0 0 0 1px rgba(100, 255, 255, 0.05);
transition: all 0.3s ease;
}
.dashou-card:active {
transform: translateY(-2rpx);
background: rgba(30, 30, 50, 0.8);
box-shadow:
0 12rpx 30rpx rgba(0, 0, 0, 0.4),
0 0 20rpx rgba(100, 255, 255, 0.1);
}
/* 头像区域 - 纯圆形 */
.touxiang-quyu {
position: relative;
margin-right: 30rpx;
flex-shrink: 0;
}
.dashou-touxiang {
width: 100rpx;
height: 100rpx;
border-radius: 50%; /* 确保是纯圆形 */
z-index: 2;
position: relative;
}
.touxiang-border {
position: absolute;
top: -4rpx;
left: -4rpx;
width: 108rpx;
height: 108rpx;
border-radius: 50%;
background: linear-gradient(45deg, #00ffea, #ff00ff);
z-index: 1;
opacity: 0.3;
animation: borderGlow 2s linear infinite;
}
@keyframes borderGlow {
0%, 100% { opacity: 0.3; }
50% { opacity: 0.6; }
}
/* 信息区域 */
.xinxi-quyu {
flex: 1;
min-width: 0; /* 防止内容撑开 */
}
.nicheng {
font-size: 32rpx;
font-weight: 600;
color: #ffffff;
margin-bottom: 10rpx;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
text-shadow: 0 0 10rpx rgba(255, 255, 255, 0.2);
}
.dashou-id {
font-size: 24rpx;
color: rgba(255, 255, 255, 0.5);
letter-spacing: 1rpx;
}
/* 分红金额区域 */
.fenhong-quyu {
text-align: right;
flex-shrink: 0;
min-width: 180rpx;
}
.fenhong-value {
margin-bottom: 8rpx;
}
.fenhong-jiahao {
font-size: 26rpx;
color: #00ff00;
margin-right: 4rpx;
}
.fenhong-shuzi {
font-size: 32rpx;
font-weight: 700;
color: #00ff00;
text-shadow: 0 0 10rpx rgba(0, 255, 0, 0.5);
}
.shijian {
font-size: 22rpx;
color: rgba(255, 255, 255, 0.4);
}
/* 加载更多提示 */
.jiazai-gengduo {
display: flex;
flex-direction: column;
align-items: center;
padding: 40rpx 0 60rpx;
margin: 0 30rpx;
}
.gengduo-spinner {
width: 40rpx;
height: 40rpx;
border: 3rpx solid rgba(100, 255, 255, 0.1);
border-top: 3rpx solid #00ffea;
border-radius: 50%;
animation: spin 1s linear infinite;
margin-bottom: 20rpx;
}
.gengduo-text {
font-size: 26rpx;
color: rgba(255, 255, 255, 0.6);
}
/* 没有更多数据 */
.meiyou-gengduo {
display: flex;
flex-direction: column;
align-items: center;
padding: 50rpx 0 80rpx;
margin: 0 30rpx;
color: rgba(255, 255, 255, 0.4);
}
.meiyou-icon {
width: 60rpx;
height: 60rpx;
border-radius: 50%;
background: rgba(0, 255, 234, 0.1);
display: flex;
align-items: center;
justify-content: center;
font-size: 32rpx;
color: #00ffea;
margin-bottom: 20rpx;
border: 1px solid rgba(0, 255, 234, 0.2);
}
.meiyou-text {
font-size: 26rpx;
text-align: center;
}
/* 错误提示 */
.cuowu-quyu {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 100rpx 30rpx;
background: rgba(40, 20, 20, 0.8);
border-radius: 24rpx;
border: 1px solid rgba(255, 100, 100, 0.2);
margin: 40rpx 30rpx 0;
}
.cuowu-icon {
font-size: 80rpx;
color: #ff5555;
margin-bottom: 30rpx;
text-shadow: 0 0 20rpx rgba(255, 85, 85, 0.5);
}
.cuowu-text {
font-size: 30rpx;
color: rgba(255, 255, 255, 0.9);
margin-bottom: 40rpx;
text-align: center;
line-height: 1.5;
}
.cuowu-btn {
padding: 20rpx 50rpx;
background: linear-gradient(90deg, #ff5555 0%, #ff8800 100%);
color: #fff;
border-radius: 50rpx;
font-size: 28rpx;
font-weight: 600;
box-shadow: 0 8rpx 20rpx rgba(255, 85, 85, 0.3);
}
.cuowu-btn:active {
transform: scale(0.95);
box-shadow: 0 4rpx 10rpx rgba(255, 85, 85, 0.2);
}
height: 100%;
background: #fff8e1;
}
.page-container {
height: 100%;
background: linear-gradient(180deg, #f7dc51 0%, #fff 18%, #fff8e1 100%);
position: relative;
}
.fixed-top {
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 100;
padding: 16rpx 24rpx 20rpx;
background: linear-gradient(180deg, #f7dc51 0%, #ffd061 85%, #fff8e1 100%);
box-shadow: 0 6rpx 20rpx rgba(0, 0, 0, 0.06);
}
.tab-bar {
display: flex;
background: rgba(255, 255, 255, 0.75);
border-radius: 999rpx;
padding: 6rpx;
margin-bottom: 20rpx;
}
.tab-item {
flex: 1;
text-align: center;
padding: 16rpx 8rpx;
font-size: 26rpx;
color: #666;
border-radius: 999rpx;
transition: all 0.2s;
}
.tab-item.active {
background: linear-gradient(180deg, #fae04d, #ffc0a3);
color: #492f00;
font-weight: 700;
box-shadow: 0 4rpx 12rpx rgba(250, 180, 80, 0.35);
}
.stats-card {
background: #fef6d4;
border-radius: 24rpx;
padding: 28rpx 24rpx;
border: 2rpx solid rgba(255, 255, 255, 0.8);
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.06);
}
.stats-main {
text-align: center;
padding-bottom: 20rpx;
margin-bottom: 20rpx;
border-bottom: 1rpx solid rgba(0, 0, 0, 0.06);
}
.stats-label,
.stats-label-sm {
display: block;
font-size: 24rpx;
color: #888;
margin-bottom: 8rpx;
}
.stats-amount {
display: block;
font-size: 52rpx;
font-weight: 800;
color: #e65100;
line-height: 1.2;
}
.stats-amount-sm {
display: block;
font-size: 36rpx;
font-weight: 700;
color: #e65100;
}
.stats-tip {
display: block;
font-size: 22rpx;
color: #999;
margin-top: 6rpx;
}
.stats-row {
display: flex;
align-items: center;
justify-content: space-around;
}
.stats-row.three .stats-cell {
flex: 1;
text-align: center;
}
.stats-cell {
text-align: center;
flex: 1;
}
.stats-num {
display: block;
font-size: 36rpx;
font-weight: 700;
color: #333;
}
.stats-sub {
display: block;
font-size: 22rpx;
color: #888;
margin-top: 4rpx;
}
.stats-divider {
width: 1rpx;
height: 48rpx;
background: rgba(0, 0, 0, 0.08);
}
.dashou-hd {
text-align: center;
padding: 32rpx 24rpx;
}
.dashou-title {
display: block;
font-size: 32rpx;
font-weight: 700;
color: #333;
}
.dashou-sub {
display: block;
font-size: 24rpx;
color: #888;
margin-top: 8rpx;
}
.refresh-btn {
position: absolute;
top: 20rpx;
right: 36rpx;
width: 64rpx;
height: 64rpx;
background: rgba(255, 255, 255, 0.9);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.08);
}
.refresh-icon {
font-size: 32rpx;
color: #e65100;
}
.refresh-icon.spin {
animation: spin 1s linear infinite;
opacity: 0.5;
}
@keyframes spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
/* 调整滚动区域的顶部距离,增加间隔 */
.scroll-area {
position: fixed;
top: 400rpx; /* 从 340rpx 增加到 360rpx增加20rpx的间隔 */
left: 0;
right: 0;
bottom: 0;
z-index: 50;
}
/* 如果觉得还不够,可以再增加列表标题的上边距 */
.list-title {
margin: 10rpx 30rpx 20rpx; /* 从 0 30rpx 20rpx 改为 10rpx 30rpx 20rpx */
display: flex;
align-items: baseline;
}
position: fixed;
top: 280rpx;
left: 0;
right: 0;
bottom: 0;
z-index: 50;
}
.scroll-area.has-tabs.dashou { top: 300rpx; }
.scroll-area.has-tabs.guanshi { top: 420rpx; }
.scroll-area.has-tabs.zuzhang { top: 320rpx; }
.scroll-area.guanshi:not(.has-tabs) { top: 400rpx; }
.scroll-area.zuzhang:not(.has-tabs) { top: 300rpx; }
.state-box,
.empty-box {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 80rpx 40rpx;
margin: 24rpx;
background: #fff;
border-radius: 24rpx;
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.05);
}
.spinner {
width: 64rpx;
height: 64rpx;
border: 4rpx solid #ffe082;
border-top-color: #e65100;
border-radius: 50%;
animation: spin 0.8s linear infinite;
margin-bottom: 20rpx;
}
.spinner.sm {
width: 36rpx;
height: 36rpx;
margin-bottom: 0;
margin-right: 12rpx;
}
.empty-icon {
font-size: 72rpx;
margin-bottom: 16rpx;
}
.empty-title {
font-size: 30rpx;
font-weight: 600;
color: #333;
margin-bottom: 8rpx;
}
.empty-tip {
font-size: 24rpx;
color: #999;
margin-bottom: 32rpx;
text-align: center;
}
.empty-btn {
padding: 16rpx 48rpx;
background: linear-gradient(180deg, #fae04d, #ffc0a3);
color: #492f00;
font-size: 28rpx;
font-weight: 600;
border-radius: 999rpx;
}
.list-hd {
display: flex;
align-items: baseline;
margin: 8rpx 24rpx 16rpx;
}
.list-title {
font-size: 30rpx;
font-weight: 700;
color: #333;
margin-right: 12rpx;
}
.list-count {
font-size: 24rpx;
color: #999;
}
.record-list {
padding: 0 24rpx 40rpx;
}
.record-card {
display: flex;
align-items: center;
padding: 24rpx;
margin-bottom: 16rpx;
background: #fff;
border-radius: 20rpx;
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.05);
}
.record-card.avatar-card .avatar {
width: 88rpx;
height: 88rpx;
border-radius: 50%;
margin-right: 20rpx;
flex-shrink: 0;
background: #eee;
}
.record-main {
flex: 1;
min-width: 0;
}
.record-title {
display: block;
font-size: 28rpx;
font-weight: 600;
color: #333;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.record-time {
display: block;
font-size: 22rpx;
color: #999;
margin-top: 6rpx;
}
.record-amt {
font-size: 30rpx;
font-weight: 700;
flex-shrink: 0;
}
.record-amt.plus {
color: #2e7d32;
}
.amt-col {
text-align: right;
}
.bonus-card {
display: flex;
align-items: center;
padding: 20rpx;
margin-bottom: 16rpx;
background: #fff;
border-radius: 20rpx;
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.05);
}
.bonus-left,
.bonus-right {
display: flex;
align-items: center;
flex: 1;
min-width: 0;
}
.bonus-right {
flex-direction: row;
justify-content: flex-end;
}
.avatar.sm {
width: 64rpx;
height: 64rpx;
border-radius: 50%;
margin-right: 12rpx;
flex-shrink: 0;
background: #eee;
}
.bonus-info {
min-width: 0;
flex: 1;
}
.bonus-mid {
display: flex;
flex-direction: column;
align-items: center;
padding: 0 8rpx;
flex-shrink: 0;
}
.bonus-tag {
font-size: 20rpx;
color: #999;
}
.bonus-arrow {
font-size: 24rpx;
color: #e65100;
}
.footer-tip {
display: flex;
align-items: center;
justify-content: center;
padding: 24rpx;
font-size: 24rpx;
color: #999;
}
.footer-tip.muted {
padding-bottom: 60rpx;
}
.error-bar {
position: fixed;
bottom: 40rpx;
left: 24rpx;
right: 24rpx;
z-index: 200;
background: #fff;
border-radius: 16rpx;
padding: 20rpx 24rpx;
display: flex;
align-items: center;
justify-content: space-between;
box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.12);
font-size: 26rpx;
color: #666;
}
.error-btn {
padding: 10rpx 28rpx;
background: linear-gradient(180deg, #fae04d, #ffc0a3);
color: #492f00;
font-size: 24rpx;
font-weight: 600;
border-radius: 999rpx;
}

View File

@@ -1,484 +1,440 @@
// pages/withdraw/withdraw.js
// 子组件版本 - 完整代码,仅适配生命周期,业务逻辑不动
// pages/withdraw/components/mode1/mode1.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;
const ASSET_TYPES = {
dashou_yue: { leixing: 1, label: '接单员佣金' },
dashou_yajin: { leixing: 5, label: '接单员保证金' },
shangjia_yue: { leixing: 6, label: '商家余额' },
guanshi_fenyong: { leixing: 2, label: '管事分红' },
zuzhang_fenyong: { leixing: 3, label: '组长分红' },
kaoheguan_fenyong: { leixing: 4, label: '考核官分佣' },
};
const FROM_ASSET_MAP = {
dashou: 'dashou_yue',
guanshi: 'guanshi_fenyong',
zuzhang: 'zuzhang_fenyong',
kaoheguan: 'kaoheguan_fenyong',
kaohe: 'kaoheguan_fenyong',
shangjia: 'shangjia_yue',
yajin: 'dashou_yajin',
};
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,
properties: { options: { type: Object, value: {} } },
data: {
imgUrls: { iconWechat: '', iconAlipay: '' },
assetList: [],
displayAssetList: [],
totalAmount: '0.00',
canWithdraw: false,
isLoadingAssets: false,
selectedAsset: null,
tixianAmount: '',
feeRateText: '--',
currentRate: '0%',
shouxufei: '0.00',
shijidaozhang: '0.00',
currentRate: asset.rate
});
showTixianModal: false,
submitting: false,
txfangshi: null,
txdianhua: '',
txzh: '',
txtupian: '',
showSkfsModal: false,
tempTxfangshi: null,
tempTxPhone: '',
tempTxAccount: '',
tempTxImage: '',
choosingImage: false,
},
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' });
}
attached() {
this.initImageUrls();
this.loadAllAssets();
this.loadWithdrawMethod();
},
onQuickAmount(e) {
const val = e.currentTarget.dataset.value;
this.setData({ tixianAmount: val.toString() });
this.onAmountInput({ detail: { value: val.toString() } });
pageLifetimes: {
show() {
this.registerNotification();
this.loadAllAssets();
PopupService.checkAndShow(this, 'tixian');
},
hide() {
const popup = this.selectComponent('#popupNotice');
popup?.cleanup?.();
},
},
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 };
methods: {
formatRatePercent(rate) {
const r = parseFloat(rate) || 0;
if (r <= 1 && r > 0) return `${(r * 100).toFixed(0)}%`;
return `${r}%`;
},
registerNotification() {
const comp = this.selectComponent('#global-notification');
if (comp?.showNotification) {
app.globalData.globalNotification = {
show: (data) => comp.showNotification(data),
hide: () => comp.hideNotification(),
};
}
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: '' });
},
initImageUrls() {
const ossBase = app.globalData.ossImageUrl || '';
const imgDir = `${ossBase}beijing/tixian/`;
this.setData({
imgUrls: {
iconWechat: `${imgDir}icon_wechat.png`,
iconAlipay: `${imgDir}icon_alipay.png`,
},
});
},
onSetSkfs() {
this.setData({
showSkfsModal: true,
tempTxfangshi: this.data.txfangshi,
tempTxPhone: this.data.txdianhua,
tempTxAccount: this.data.txzh,
tempTxImage: ''
});
},
/** 顶部展示:不含保证金的可提现合计 */
calcDisplayTotal(assets) {
let total = 0;
(assets || []).forEach((item) => {
if (item.type === 'dashou_yajin') return;
total += parseFloat(item.amount) || 0;
});
return total;
},
onSelectFangshi(e) {
this.setData({ tempTxfangshi: e.currentTarget.dataset.fangshi });
},
hasAnyWithdrawable(assets) {
return (assets || []).some((item) => parseFloat(item.amount) > 0);
},
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 };
applyRouteOptions(assets) {
const opts = this.properties.options || {};
const fromKey = FROM_ASSET_MAP[opts.from];
let selected = null;
if (fromKey) {
selected = assets.find((a) => a.type === fromKey) || null;
} else if (assets.length === 1) {
selected = assets[0];
}
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' });
}
},
const patch = {};
if (selected) {
patch.selectedAsset = selected;
patch.feeRateText = selected.rateText;
}
if (opts.amount && parseFloat(opts.amount) > 0) {
const amt = parseFloat(opts.amount);
const max = selected ? parseFloat(selected.amount) : amt;
patch.tixianAmount = Math.min(amt, max).toFixed(2);
}
if (Object.keys(patch).length) {
this.setData(patch, () => {
this.recalcFee(this.data.tixianAmount, this.data.selectedAsset);
});
}
},
onCloseModifyModal() { this.setData({ showModifyModal: false, modifyingRecord: null }); },
onSelectAsset(e) {
const index = e.currentTarget.dataset.index;
const asset = this.data.displayAssetList[index];
if (!asset || parseFloat(asset.amount) <= 0) {
wx.showToast({ title: '该账户无可提余额', icon: 'none' });
return;
}
let amount = this.data.tixianAmount;
const max = parseFloat(asset.amount);
if (amount && parseFloat(amount) > max) {
amount = asset.amount;
}
this.setData({ selectedAsset: asset, tixianAmount: amount });
this.recalcFee(amount, asset);
},
onViewFailReason(e) {
const record = e.currentTarget.dataset.record;
const reason = record.fail_reason || record.shibaiyuanyin || '暂无详细信息';
this.setData({ currentFailReason: reason, showFailModal: true });
},
async loadAllAssets() {
this.setData({ isLoadingAssets: true, totalAmount: '0.00', canWithdraw: false, assetList: [] });
try {
const res = await request({ url: '/yonghu/tixianzichan', method: 'POST' });
if (res?.data?.code === 200 || res?.data?.code === 0) {
const data = res.data.data || {};
const assets = [];
const push = (type, amount, rate) => {
const cfg = ASSET_TYPES[type];
if (!cfg || !amount || parseFloat(amount) <= 0) return;
assets.push({
type,
leixing: cfg.leixing,
label: cfg.label,
amount: parseFloat(amount).toFixed(2),
rate: rate || 0,
rateText: this.formatRatePercent(rate || 0),
});
};
push('dashou_yue', data.dashou_yue, data.dashou_rate);
push('dashou_yajin', data.dashou_yajin, data.dashou_yajin_rate);
push('shangjia_yue', data.shangjia_yue, data.shangjia_rate);
push('guanshi_fenyong', data.guanshi_fenyong, data.guanshi_rate);
push('zuzhang_fenyong', data.zuzhang_fenyong, data.zuzhang_rate);
push('kaoheguan_fenyong', data.kaoheguan_fenyong, data.kaoheguan_rate);
onCloseFailModal() { this.setData({ showFailModal: false }); },
const displayTotal = this.calcDisplayTotal(assets);
const firstRate = assets.find((a) => a.type !== 'dashou_yajin')?.rate || 0;
this.setData({
assetList: assets,
displayAssetList: assets,
totalAmount: displayTotal.toFixed(2),
canWithdraw: this.hasAnyWithdrawable(assets),
isLoadingAssets: false,
feeRateText: displayTotal > 0 ? this.formatRatePercent(firstRate) : '--',
}, () => this.applyRouteOptions(assets));
if (!this.data.selectedAsset) {
this.recalcFee(this.data.tixianAmount, null);
}
} else {
throw new Error(res?.data?.msg || '获取资产失败');
}
} catch (err) {
console.error('loadAllAssets', err);
this.setData({ isLoadingAssets: false, totalAmount: '0.00', canWithdraw: false, assetList: [] });
}
},
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';
},
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 || txfangshi) {
this.setData({ txzh, txtupian, txfangshi, txdianhua });
return;
}
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) { /* ignore */ }
},
registerNotification() {
const comp = this.selectComponent('#global-notification');
if (comp?.showNotification) {
app.globalData.globalNotification = {
show: (data) => comp.showNotification(data),
hide: () => comp.hideNotification()
};
}
recalcFee(amountStr, asset) {
const amount = parseFloat(amountStr);
if (!amountStr || isNaN(amount) || amount <= 0 || !asset) {
this.setData({
shouxufei: '0.00',
shijidaozhang: '0.00',
feeRateText: asset ? asset.rateText : this.data.feeRateText,
});
return;
}
const rate = parseFloat(asset.rate) || 0;
const fee = amount * rate;
this.setData({
shouxufei: fee.toFixed(2),
shijidaozhang: (amount - fee).toFixed(2),
feeRateText: asset.rateText,
currentRate: asset.rateText,
});
},
onAmountInput(e) {
let val = e.detail.value;
if (val && !/^\d*\.?\d{0,2}$/.test(val)) return;
this.setData({ tixianAmount: val });
this.recalcFee(val, this.data.selectedAsset);
},
onWithdrawAll() {
const { selectedAsset } = this.data;
if (!selectedAsset) {
wx.showToast({ title: '请先选择提现账户', icon: 'none' });
return;
}
const max = selectedAsset.amount;
this.setData({ tixianAmount: max });
this.recalcFee(max, selectedAsset);
},
onTapWithdraw() {
if (this.data.submitting) return;
if (!this.hasAnyWithdrawable(this.data.assetList)) {
wx.showToast({ title: '暂无可提现余额', icon: 'none' });
return;
}
const { selectedAsset, tixianAmount } = 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: `超过${selectedAsset.label}可提余额`, icon: 'none' });
return;
}
const { txfangshi, txzh, txtupian } = this.data;
if (!txfangshi || (!txzh && !txtupian)) {
wx.showToast({ title: '请先设置收款方式', icon: 'none' });
this.onSetSkfs();
return;
}
this.applyIdentityAndConfirm(selectedAsset);
},
applyIdentityAndConfirm(asset) {
this.recalcFee(this.data.tixianAmount, asset);
this.setData({ selectedAsset: asset, showTixianModal: true });
},
async onConfirmWithdraw() {
const { selectedAsset, tixianAmount, txfangshi, txzh, txtupian } = 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;
}
const leixing = selectedAsset.leixing;
let txskfs = 0;
if (txzh && txtupian) txskfs = 3;
else if (txzh) txskfs = 1;
else if (txtupian) txskfs = 2;
this.setData({ submitting: true });
try {
const res = await request({
url: '/yonghu/tixian',
method: 'POST',
data: { leixing, jine: amount.toFixed(2), fangshi: txfangshi, txskfs },
});
if (res?.data?.code === 0) {
this.setData({
showTixianModal: false,
selectedAsset: null,
tixianAmount: '',
submitting: false,
});
await this.loadAllAssets();
wx.showModal({
title: '申请成功',
content: '提现申请已提交,请前往「提现记录」查看审核进度。',
confirmText: '查看提现记录',
cancelText: '知道了',
success: (res) => {
if (res.confirm) {
wx.navigateTo({ url: '/pages/withdraw/withdraw-records' });
}
},
});
} else {
wx.showToast({ title: res?.data?.msg || '提现失败', icon: 'none' });
this.setData({ submitting: false });
}
} catch (err) {
wx.showToast({ title: '网络错误', icon: 'none' });
this.setData({ submitting: false });
}
},
onCloseTixianModal() {
if (this.data.submitting) return;
this.setData({ showTixianModal: false, selectedAsset: null });
},
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 && !this.data.txtupian) {
wx.showToast({ title: '请上传微信收款码', icon: 'none' }); return;
}
if (tempTxfangshi == 2 && !tempTxAccount && !tempTxImage && !this.data.txzh) {
wx.showToast({ title: '请填写支付宝账号或上传收款码', icon: 'none' }); return;
}
try {
const res = await upload({
url: '/yonghu/sksc',
formData: { txdianhua: tempTxPhone, txzh: tempTxAccount || '' },
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 || this.data.txtupian,
showSkfsModal: false,
});
wx.setStorageSync('txfangshi', tempTxfangshi);
wx.setStorageSync('txdianhua', tempTxPhone);
wx.setStorageSync('txzh', data.txzh || '');
wx.setStorageSync('txtupian', data.txtupian || this.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 }); },
stopPropagation() {},
},
stopPropagation() {}
}
});
});

View File

@@ -1,133 +1,115 @@
<!-- pages/withdraw/withdraw.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>
<!-- mode1 收款码手动审核 - 参考逍遥梦样式 -->
<view class="ref-page">
<view class="method-card method-card--row">
<view class="method-tab method-tab--active">
<image wx:if="{{txfangshi == 1}}" class="method-tab-icon" src="{{imgUrls.iconWechat}}" mode="aspectFit" />
<image wx:elif="{{txfangshi == 2}}" class="method-tab-icon" src="{{imgUrls.iconAlipay}}" mode="aspectFit" />
<view wx:else class="method-tab-icon method-tab-icon--placeholder"></view>
<text class="method-tab-text">{{txfangshi == 1 ? '微信零钱' : (txfangshi == 2 ? '收款码' : '请先设置收款')}}</text>
<view class="method-tab-line"></view>
</view>
<!-- 层次分隔线 -->
<view class="divider-line"></view>
<text class="method-setting" bindtap="onSetSkfs">设置收款方式</text>
</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 class="account-card" wx:if="{{displayAssetList.length > 0}}">
<scroll-view scroll-x enable-flex class="account-scroll" show-scrollbar="{{false}}">
<view
wx:for="{{displayAssetList}}"
wx:key="type"
class="account-chip {{selectedAsset.type === item.type ? 'account-chip--active' : ''}} {{item.amount <= 0 ? 'account-chip--disabled' : ''}}"
bindtap="onSelectAsset"
data-index="{{index}}"
>
<text class="chip-label">{{item.label}}</text>
<text class="chip-amount">¥{{item.amount}}</text>
</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>
<text wx:if="{{!selectedAsset}}" class="account-warn">请先选择上方提现账户</text>
<text wx:else class="account-ok">当前:{{selectedAsset.label}}</text>
</view>
<view class="safe-bottom"></view>
<view class="amount-card">
<view class="avail-row">
<text class="avail-label">当前可提现:</text>
<text class="avail-symbol">¥</text>
<text class="avail-amount">{{selectedAsset ? selectedAsset.amount : totalAmount}}</text>
</view>
<view class="input-row">
<text class="input-symbol">¥</text>
<input
class="amount-input"
type="digit"
placeholder="请输入金额"
placeholder-class="amount-placeholder"
value="{{tixianAmount}}"
bindinput="onAmountInput"
/>
<text class="withdraw-all" bindtap="onWithdrawAll">全部提现</text>
</view>
<view class="input-divider"></view>
<view class="fee-tip">
<text>提示:提现手续费</text>
<text class="fee-highlight">{{feeRateText}}</text>
<text>。</text>
</view>
</view>
<view class="submit-wrap">
<view class="confirm-btn {{canWithdraw && !submitting ? '' : 'confirm-btn--disabled'}}" bindtap="onTapWithdraw">
<text wx:if="{{submitting}}">处理中...</text>
<text wx:else>确认提现</text>
</view>
</view>
<view class="notice-box">
<view class="notice-title">📢 提现须知</view>
<view class="notice-item">🕒 提交后将进入人工审核,请耐心等待</view>
<view class="notice-item">📌 审核结果可在「提现记录」中查看</view>
<view class="notice-item">💰 每笔只能从单个账户提现,请先选择对应账户</view>
<view class="notice-item">✅ 请确保收款方式与收款码正确后再提交</view>
<view class="notice-item">🎧 如有疑问请联系客服核实处理</view>
</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-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.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="info-row"><text>费率</text><text>{{currentRate}}</text></view>
<view class="info-row"><text>提现金额</text><text>¥{{tixianAmount}}</text></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 class="info-row"><text>收款</text><text>{{txfangshi == 1 ? '微信' : (txfangshi == 2 ? '支付宝' : '未设置')}}</text></view>
</view>
<view class="modal-footer">
<view class="modal-btn cancel" bindtap="onCloseTixianModal">取消</view>
<view class="modal-btn confirm" bindtap="onConfirmWithdraw">{{submitting ? '处理中' : '提交申请'}}</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>
<view class="modal-body skfs-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 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 class="modal-footer">
<view class="modal-btn cancel" bindtap="onCloseSkfsModal">取消</view>
<view class="modal-btn confirm" bindtap="onConfirmSkfs">保存</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" />
<popup-notice id="popupNotice" />

View File

@@ -1,424 +1,85 @@
/* pages/withdraw/withdraw.wxss - 终极优化版 */
@import '../mode2/mode2.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;
}
.method-card--row {
display: flex;
align-items: center;
justify-content: space-between;
padding-right: 24rpx;
}
.method-setting {
font-size: 26rpx;
color: #ff8c00;
flex-shrink: 0;
padding: 16rpx 8rpx;
}
.method-tab-icon--placeholder {
background: #e0e0e0;
border-radius: 8rpx;
}
.skfs-body .toggle-row {
display: flex;
gap: 16rpx;
margin-bottom: 24rpx;
}
.toggle-item {
flex: 1;
text-align: center;
padding: 20rpx;
border-radius: 12rpx;
background: #f5f5f5;
font-size: 28rpx;
color: #666;
}
.toggle-item.active {
background: #fff8e1;
color: #ff8c00;
font-weight: 600;
border: 2rpx solid #FFD54F;
}
.field-input {
width: 100%;
box-sizing: border-box;
padding: 24rpx;
margin-bottom: 16rpx;
background: #f8f8f8;
border-radius: 12rpx;
font-size: 28rpx;
}
.upload-wrap {
margin-top: 16rpx;
}
.upload-trigger {
padding: 48rpx;
text-align: center;
border: 2rpx dashed #ddd;
border-radius: 12rpx;
color: #999;
font-size: 28rpx;
}
.image-preview {
position: relative;
}
.image-preview image {
width: 100%;
height: 320rpx;
border-radius: 12rpx;
}
.image-actions {
display: flex;
justify-content: center;
gap: 32rpx;
margin-top: 16rpx;
font-size: 28rpx;
color: #ff8c00;
}

View File

@@ -1,21 +1,8 @@
// pages/withdraw/components/mode2/mode2.js
// UI 与 mode1 完全一致,业务逻辑为自动打款审核收款
// pages/withdraw/components/mode2/mode2.js — 自动打款纯提现
import request from '../../../../utils/request.js';
import PopupService from '../../../../services/popupService.js';
const app = getApp();
const yemianshuju = 5;
let lastPullDownTime = 0;
const PULL_DOWN_INTERVAL = 2000;
const TX_STATUS = {
SHENHEZHONG: 1,
TIXIAN_CHENGGONG: 2,
TIXIAN_SHIBAI: 3,
SHENHE_CHENGGONG: 4,
SHENHE_SHIBAI: 5,
DAI_SHOUKUAN: 6,
};
const ASSET_CONFIG = {
dashou_yue: { leixing: 1, label: '接单员佣金' },
@@ -26,58 +13,41 @@ const ASSET_CONFIG = {
shangjia_yue: { leixing: 6, label: '商家余额' },
};
const LEIXING_LABEL = {
1: '接单员佣金', 2: '管事分红', 3: '组长分红',
4: '考核官分佣', 5: '接单员保证金', 6: '商家余额',
/** 页面入参 from 与资产 type 映射 */
const FROM_ASSET_MAP = {
dashou: 'dashou_yue',
guanshi: 'guanshi_fenyong',
zuzhang: 'zuzhang_fenyong',
kaoheguan: 'kaoheguan_fenyong',
kaohe: 'kaoheguan_fenyong',
shangjia: 'shangjia_yue',
yajin: 'dashou_yajin',
};
Component({
properties: { options: { type: Object, value: {} } },
data: {
imgUrls: {
pageBg: '', cardBg: '', assetTileBg: '',
},
imgUrls: { iconWechat: '' },
assetList: [],
displayAssetList: [],
totalAmount: '0.00',
canWithdraw: false,
selectedAsset: null,
isLoadingAssets: false,
tixianleixing: null,
tixianjine: '',
currentRate: '0.00',
feeRateText: '--',
showTixian: false,
recordList: [],
page: 1,
loading: false,
nomore: false,
canloadmore: true,
isRefreshing: false,
shouxufei: '0.00',
shijidaozhang: '0.00',
currentTixianId: null,
submitting: false,
mchId: '',
currentStatusFilter: 0,
statusTabs: [
{ value: 0, label: '全部' },
{ value: 1, label: '审核中' },
{ value: 6, label: '待收款' },
{ value: 4, label: '审核成功' },
{ value: 5, label: '审核失败' },
{ value: 2, label: '提现成功' },
{ value: 3, label: '提现失败' },
],
hasPendingCollect: false,
showCollectConfirm: false,
collectConfirmRecord: null,
showDetailModal: false,
detailTitle: '',
detailContent: '',
},
lifetimes: {
attached() {
this.initImageUrls();
this.chushihuashuju();
}
this.loadAllAssets();
},
},
pageLifetimes: {
show() {
@@ -88,7 +58,7 @@ Component({
hide() {
const popupComp = this.selectComponent('#popupNotice');
if (popupComp && popupComp.cleanup) popupComp.cleanup();
}
},
},
methods: {
registerNotificationComponent() {
@@ -96,127 +66,11 @@ Component({
if (notificationComp && notificationComp.showNotification) {
app.globalData.globalNotification = {
show: (data) => notificationComp.showNotification(data),
hide: () => notificationComp.hideNotification()
hide: () => notificationComp.hideNotification(),
};
}
},
initImageUrls() {
const ossBase = app.globalData.ossImageUrl || '';
const imgDir = `${ossBase}beijing/tixian/`;
this.setData({
imgUrls: {
pageBg: `${imgDir}page_bg.png`,
cardBg: `${imgDir}card_bg.png`,
assetTileBg: `${imgDir}asset_tile_bg.png`,
}
});
},
parseZhuangtai(item) {
const raw = item.zhuangtai ?? item.status ?? item.state;
const n = parseInt(raw, 10);
return Number.isNaN(n) ? -1 : n;
},
/** 规范化列表字段(兼容后端多种命名 / 嵌套 audit */
normalizeRecordFields(item) {
const audit = item.audit || item.shenhe || item.shenhe_info || {};
const shenheJiluId = item.shenhe_jilu_id ?? item.shenheJiluId
?? item.audit_id ?? item.shenheid ?? audit.id ?? audit.shenhe_jilu_id ?? null;
const shenheDanhao = String(
item.shenhe_danhao || item.shenheDanhao || item.audit_shenhe_danhao
|| audit.shenhe_danhao || audit.danhao || ''
).trim();
const tixianjiluId = item.tixianjilu_id ?? item.tixianjiluId ?? item.id ?? null;
const zhuangtai = this.parseZhuangtai(item);
return {
...item,
zhuangtai: zhuangtai >= 0 ? zhuangtai : item.zhuangtai,
shenhe_jilu_id: shenheJiluId,
shenhe_danhao: shenheDanhao,
tixianjilu_id: tixianjiluId,
};
},
hasAuditJiluId(item) {
const id = item.shenhe_jilu_id;
return id !== null && id !== undefined && id !== '' && id !== 0 && id !== '0';
},
hasShenheDanhao(item) {
return !!(item.shenhe_danhao && String(item.shenhe_danhao).trim());
},
isNewAuditRecord(item) {
return this.hasAuditJiluId(item) && this.hasShenheDanhao(item);
},
/** 待收款是否可点击状态6 + 审核记录ID + 审核单号 缺一不可 */
canCollectRecord(item) {
return this.parseZhuangtai(item) === TX_STATUS.DAI_SHOUKUAN
&& this.hasAuditJiluId(item)
&& this.hasShenheDanhao(item);
},
getLeixingLabel(leixing) {
return LEIXING_LABEL[parseInt(leixing)] || '提现';
},
getStatusBadgeClass(status) {
switch (parseInt(status)) {
case TX_STATUS.SHENHEZHONG: return 'status-wait';
case TX_STATUS.TIXIAN_CHENGGONG:
case TX_STATUS.SHENHE_CHENGGONG: return 'status-done';
case TX_STATUS.DAI_SHOUKUAN: return 'status-pending';
case TX_STATUS.TIXIAN_SHIBAI:
case TX_STATUS.SHENHE_SHIBAI: return 'status-fail';
default: return 'status-wait';
}
},
processRecordItem(item) {
item = this.normalizeRecordFields(item);
const isNew = this.isNewAuditRecord(item);
const status = this.parseZhuangtai(item);
let statusText = '未知';
let canCollect = false;
let canShowDetail = false;
let detailReason = '';
switch (status) {
case TX_STATUS.SHENHEZHONG: statusText = '审核中'; break;
case TX_STATUS.TIXIAN_CHENGGONG: statusText = '提现成功'; break;
case TX_STATUS.TIXIAN_SHIBAI:
statusText = '提现失败';
if (item.fail_reason || item.bhliyou) {
canShowDetail = true;
detailReason = item.fail_reason || item.bhliyou;
}
break;
case TX_STATUS.SHENHE_CHENGGONG: statusText = '审核成功'; break;
case TX_STATUS.SHENHE_SHIBAI:
statusText = '审核失败';
if (item.bhliyou) { canShowDetail = true; detailReason = item.bhliyou; }
break;
case TX_STATUS.DAI_SHOUKUAN:
statusText = '待收款';
canCollect = this.canCollectRecord(item);
break;
}
return {
...item,
isNewAudit: isNew,
leixingLabel: this.getLeixingLabel(item.leixing),
statusText,
statusBadgeClass: this.getStatusBadgeClass(status),
canCollect,
canShowDetail,
detailReason,
};
},
gengxinYue(data, leixing) {
if (!data) return;
if (data.new_yongjin !== undefined && data.new_yongjin !== null) {
@@ -239,51 +93,79 @@ Component({
}
},
updatePendingCollectFlag(list) {
const hasPending = (list || []).some(item => item.canCollect);
if (hasPending !== this.data.hasPendingCollect) {
this.setData({ hasPendingCollect: hasPending });
initImageUrls() {
const ossBase = app.globalData.ossImageUrl || '';
const imgDir = `${ossBase}beijing/tixian/`;
this.setData({
imgUrls: {
iconWechat: `${imgDir}icon_wechat.png`,
},
});
},
/** 顶部展示:不含保证金的可提现合计 */
calcDisplayTotal(assets) {
let total = 0;
(assets || []).forEach((item) => {
if (item.type === 'dashou_yajin') return;
total += parseFloat(item.amount) || 0;
});
return total;
},
hasAnyWithdrawable(assets) {
return (assets || []).some((item) => parseFloat(item.amount) > 0);
},
applyRouteOptions(assets) {
const opts = this.properties.options || {};
const fromKey = FROM_ASSET_MAP[opts.from];
let selected = null;
if (fromKey) {
selected = assets.find((a) => a.type === fromKey) || null;
} else if (assets.length === 1) {
selected = assets[0];
}
const patch = {};
if (selected) {
patch.selectedAsset = selected;
patch.tixianleixing = selected.leixing;
patch.feeRateText = selected.rateText;
}
if (opts.amount && parseFloat(opts.amount) > 0) {
const amt = parseFloat(opts.amount);
const max = selected ? parseFloat(selected.amount) : amt;
patch.tixianjine = Math.min(amt, max).toFixed(2);
}
if (Object.keys(patch).length) {
this.setData(patch, () => {
this.recalcFee(this.data.tixianjine, this.data.selectedAsset);
});
}
},
/** 微信确认收款成功后,本地先把对应记录标为「提现成功」 */
markLocalRecordWithdrawSuccess(record) {
if (!record) return;
const matchId = String(record.tixianjilu_id || record.id || '');
const matchDanhao = String(record.shenhe_danhao || '').trim();
if (!matchId && !matchDanhao) return;
const newList = (this.data.recordList || []).map((item) => {
const itemId = String(item.tixianjilu_id || item.id || '');
const itemDanhao = String(item.shenhe_danhao || '').trim();
const isMatch = (matchId && itemId === matchId)
|| (matchDanhao && itemDanhao === matchDanhao);
if (!isMatch) return item;
return this.processRecordItem({
...item,
zhuangtai: TX_STATUS.TIXIAN_CHENGGONG,
});
});
this.setData({ recordList: newList });
this.updatePendingCollectFlag(newList);
},
async finishWxCollectSuccess(record) {
this.markLocalRecordWithdrawSuccess(record);
await this.loadAllAssets();
await this.huoquJilu(true, true);
// 后端若尚未落库,刷新后仍可能显示待收款,再覆盖一次本地成功态
this.markLocalRecordWithdrawSuccess(record);
PopupService.checkAndShow(this, 'tixianchenggong');
wx.showToast({
title: '提现成功',
icon: 'success',
duration: 3000,
onSelectAsset(e) {
const index = e.currentTarget.dataset.index;
const asset = this.data.displayAssetList[index];
if (!asset || parseFloat(asset.amount) <= 0) {
wx.showToast({ title: '该账户无可提余额', icon: 'none' });
return;
}
let jine = this.data.tixianjine;
const max = parseFloat(asset.amount);
if (jine && parseFloat(jine) > max) {
jine = asset.amount;
}
this.setData({
selectedAsset: asset,
tixianleixing: asset.leixing,
tixianjine: jine,
});
this.recalcFee(jine, asset);
},
async loadAllAssets() {
this.setData({ isLoadingAssets: true });
this.setData({ isLoadingAssets: true, totalAmount: '0.00', canWithdraw: false, assetList: [] });
try {
const res = await request({ url: '/yonghu/tixianzichan', method: 'POST' });
if (res?.data?.code === 200 || res?.data?.code === 0) {
@@ -298,6 +180,7 @@ Component({
label: cfg.label,
amount: parseFloat(amount).toFixed(2),
rate: rate || 0,
rateText: this.formatRatePercent(rate || 0),
});
};
pushAsset('dashou_yue', data.dashou_yue, data.dashou_rate);
@@ -307,63 +190,114 @@ Component({
pushAsset('zuzhang_fenyong', data.zuzhang_fenyong, data.zuzhang_rate);
pushAsset('kaoheguan_fenyong', data.kaoheguan_fenyong, data.kaoheguan_rate);
let total = 0;
assets.forEach(item => { total += parseFloat(item.amount); });
this.setData({ assetList: assets, totalAmount: total.toFixed(2), isLoadingAssets: false });
const displayTotal = this.calcDisplayTotal(assets);
const firstRate = assets.find((a) => a.type !== 'dashou_yajin')?.rate || 0;
this.setData({
assetList: assets,
displayAssetList: assets,
totalAmount: displayTotal.toFixed(2),
canWithdraw: this.hasAnyWithdrawable(assets),
isLoadingAssets: false,
feeRateText: displayTotal > 0 ? this.formatRatePercent(firstRate) : '--',
}, () => this.applyRouteOptions(assets));
if (!this.data.selectedAsset) {
this.recalcFee(this.data.tixianjine, null);
}
} else {
throw new Error(res?.data?.msg || '获取资产失败');
}
} catch (err) {
console.error('loadAllAssets', err);
this.setData({ isLoadingAssets: false });
this.setData({ isLoadingAssets: false, totalAmount: '0.00', canWithdraw: false, assetList: [] });
}
},
chushihuashuju() {
this.loadAllAssets();
this.huoquJilu(true);
formatRatePercent(rate) {
const r = parseFloat(rate) || 0;
if (r <= 1 && r > 0) return `${(r * 100).toFixed(0)}%`;
return `${r}%`;
},
/** 点击资产卡片(与 mode1 一致) */
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' });
recalcFee(amountStr, asset) {
const amount = parseFloat(amountStr);
if (!amountStr || isNaN(amount) || amount <= 0 || !asset) {
this.setData({
shouxufei: '0.00',
shijidaozhang: '0.00',
feeRateText: asset ? this.formatRatePercent(asset.rate) : this.data.feeRateText,
});
return;
}
const rate = parseFloat(asset.rate) || 0;
const fee = amount * rate;
const actual = amount - fee;
this.setData({
selectedAsset: asset,
tixianleixing: asset.leixing,
currentRate: asset.rate,
tixianjine: '',
shouxufei: '0.00',
shijidaozhang: '0.00',
showTixian: true,
shouxufei: fee.toFixed(2),
shijidaozhang: actual.toFixed(2),
feeRateText: this.formatRatePercent(rate),
currentRate: this.formatRatePercent(rate),
});
},
onJineInput(e) {
this.setData({ tixianjine: e.detail.value, shouxufei: '0.00', shijidaozhang: '0.00' });
const val = e.detail.value;
this.setData({ tixianjine: val });
this.recalcFee(val, this.data.selectedAsset);
},
onQuickAmountTap(e) {
const value = e.currentTarget.dataset.value;
this.setData({ tixianjine: value.toString(), shouxufei: '0.00', shijidaozhang: '0.00' });
onWithdrawAll() {
const { selectedAsset } = this.data;
if (!selectedAsset) {
wx.showToast({ title: '请先选择提现账户', icon: 'none' });
return;
}
const max = selectedAsset.amount;
this.setData({ tixianjine: max });
this.recalcFee(max, selectedAsset);
},
onStatusFilterTap(e) {
const value = parseInt(e.currentTarget.dataset.value);
if (value === this.data.currentStatusFilter) return;
this.setData({ currentStatusFilter: value });
this.huoquJilu(true);
onTapWithdraw() {
if (this.data.submitting) return;
if (!this.hasAnyWithdrawable(this.data.assetList)) {
wx.showToast({ title: '暂无可提现余额', icon: 'none' });
return;
}
const { selectedAsset, tixianjine } = this.data;
if (!selectedAsset) {
wx.showToast({ title: '请先选择要提现的账户', icon: 'none' });
return;
}
const jineValue = parseFloat(tixianjine);
if (!tixianjine || isNaN(jineValue) || jineValue <= 0) {
wx.showToast({ title: '请输入有效金额', icon: 'none' });
return;
}
if (jineValue <= 0.1) {
wx.showToast({ title: '提现金额须大于0.1元', icon: 'none' });
return;
}
if (jineValue > parseFloat(selectedAsset.amount)) {
wx.showToast({ title: `超过${selectedAsset.label}可提余额`, icon: 'none' });
return;
}
this.applyIdentityAndConfirm(selectedAsset);
},
applyIdentityAndConfirm(asset) {
this.recalcFee(this.data.tixianjine, asset);
this.setData({
selectedAsset: asset,
tixianleixing: asset.leixing,
currentRate: this.formatRatePercent(asset.rate),
showTixian: true,
});
},
async onConfirmTixian() {
if (this.data.submitting) return;
const { tixianleixing, tixianjine, selectedAsset } = this.data;
if (!tixianleixing || !selectedAsset) {
wx.showToast({ title: '请选择提现类型', icon: 'none' });
wx.showToast({ title: '请选择提现身份', icon: 'none' });
return;
}
const jineValue = parseFloat(tixianjine);
@@ -372,7 +306,7 @@ Component({
return;
}
if (jineValue > parseFloat(selectedAsset.amount)) {
wx.showToast({ title: `超过可提${selectedAsset.label}`, icon: 'none' });
wx.showToast({ title: `超过${selectedAsset.label}可提余额`, icon: 'none' });
return;
}
@@ -381,24 +315,30 @@ Component({
const res = await request({
url: '/yonghu/zddksh',
method: 'POST',
data: { leixing: tixianleixing, jine: jineValue.toFixed(2) }
data: { leixing: tixianleixing, jine: jineValue.toFixed(2) },
});
if (res.statusCode === 200 && res.data && res.data.code === 0) {
const data = res.data.data || {};
this.gengxinYue(data, tixianleixing);
if (data.shouxufei !== undefined) {
this.setData({
shouxufei: parseFloat(data.shouxufei || 0).toFixed(2),
shijidaozhang: parseFloat(data.shijidaozhang || 0).toFixed(2),
});
}
this.setData({ showTixian: false, submitting: false, selectedAsset: null });
this.setData({
showTixian: false,
submitting: false,
selectedAsset: null,
tixianjine: '',
shouxufei: '0.00',
shijidaozhang: '0.00',
});
await this.loadAllAssets();
this.huoquJilu(true);
wx.showModal({
title: '申请已提交',
content: '您的提现申请已提交,请等待后台审核。审核通过后,请在本页「提现记录」中点击「收款」按钮,主动确认后才能到账微信零钱。',
showCancel: false,
title: '申请成功',
content: '提现申请已提交,请前往「提现记录」查看进度;审核通过后可在该页点击「收款」确认到账。',
confirmText: '查看提现记录',
cancelText: '知道了',
success: (res) => {
if (res.confirm) {
wx.navigateTo({ url: '/pages/withdraw/withdraw-records' });
}
},
});
} else {
wx.showModal({ title: '提现申请失败', content: res.data?.msg || '未知错误', showCancel: false });
@@ -410,233 +350,20 @@ Component({
}
},
onCollectTap(e) {
const index = e.currentTarget.dataset.index;
const record = this.data.recordList[index];
if (!record) return;
if (this.parseZhuangtai(record) !== TX_STATUS.DAI_SHOUKUAN) {
wx.showToast({ title: '当前状态不可收款', icon: 'none' });
return;
}
if (!this.hasShenheDanhao(record) || !this.hasAuditJiluId(record)) {
wx.showToast({ title: '审核信息不完整,请刷新后重试', icon: 'none' });
return;
}
onCloseTixian() {
if (this.data.submitting) {
wx.showToast({ title: '正在处理中,请稍后', icon: 'none' });
return;
}
this.setData({ showCollectConfirm: true, collectConfirmRecord: record });
},
onCloseCollectConfirm() {
if (this.data.submitting) return;
this.setData({ showCollectConfirm: false, collectConfirmRecord: null });
},
async onConfirmCollect() {
if (this.data.submitting) return;
let record = this.data.collectConfirmRecord;
if (!record) return;
if (!this.canCollectRecord(record)) {
await this.huoquJilu(true, true);
const refreshed = (this.data.recordList || []).find(
r => String(r.id) === String(record.id)
|| String(r.tixianjilu_id) === String(record.tixianjilu_id)
);
if (refreshed) record = refreshed;
}
if (!this.canCollectRecord(record)) {
wx.showModal({
title: '暂时无法收款',
content: '缺少审核单号或审核记录ID请下拉刷新后重试。仍不行请联系客服。',
showCancel: false,
});
return;
}
this.setData({ showCollectConfirm: false, submitting: true, collectConfirmRecord: record });
try {
const res = await request({
url: '/yonghu/tixiansq',
method: 'POST',
data: {
shenhe_danhao: record.shenhe_danhao,
shenhe_jilu_id: record.shenhe_jilu_id || '',
tixianjilu_id: record.tixianjilu_id || record.id || '',
leixing: record.leixing,
}
});
if (res.statusCode === 200 && res.data && res.data.code === 0) {
const data = res.data.data;
this.setData({
currentTixianId: data.tixian_id,
mchId: data.mch_id || '',
collectConfirmRecord: record,
});
this.tiaoqiWeixinQueRen(data.package_info);
} else {
wx.showModal({ title: '收款失败', content: res.data?.msg || '无法发起收款,请稍后重试', showCancel: false });
this.setData({ submitting: false, collectConfirmRecord: null });
}
} catch (err) {
wx.showModal({ title: '网络错误', content: '网络连接失败,请稍后重试', showCancel: false });
this.setData({ submitting: false, collectConfirmRecord: null });
}
},
tiaoqiWeixinQueRen(packageInfo) {
const appId = app.globalData.appId;
const mchId = this.data.mchId;
if (!appId || !mchId) {
wx.showModal({ title: '配置错误', content: '无法调起收款,请联系客服', showCancel: false });
this.setData({ submitting: false, collectConfirmRecord: null });
return;
}
wx.requestMerchantTransfer({
appId, mchId, package: packageInfo,
success: () => { this.tongzhiHouduanQueRen(1); },
fail: () => {
this.tongzhiHouduanQueRen(0);
wx.showModal({
title: '确认收款失败',
content: '微信收款确认失败,您可在记录中再次点击「收款」重试。',
showCancel: false,
});
}
});
},
async tongzhiHouduanQueRen(result) {
if (!this.data.currentTixianId) {
this.setData({ submitting: false, collectConfirmRecord: null });
return;
}
const record = this.data.collectConfirmRecord;
const wxConfirmed = result === 1;
try {
const res = await request({
url: '/yonghu/tixianqr',
method: 'POST',
data: {
tixian_id: this.data.currentTixianId,
result: result,
shenhe_danhao: record ? record.shenhe_danhao : '',
shenhe_jilu_id: record ? (record.shenhe_jilu_id || '') : '',
tixianjilu_id: record ? (record.tixianjilu_id || record.id || '') : '',
leixing: record ? record.leixing : '',
}
});
if (res.statusCode === 200 && res.data && res.data.code === 0) {
const data = res.data.data || {};
this.gengxinYue(data, record ? record.leixing : null);
}
// 微信已确认收款:不论 tixianqr 返回什么,都刷新列表,不弹系统异常
if (wxConfirmed) {
await this.finishWxCollectSuccess(record);
} else if (res.statusCode === 200 && res.data && res.data.code === 0) {
await this.loadAllAssets();
this.huoquJilu(true);
wx.showToast({
title: '收款已取消',
icon: 'none',
duration: 3000,
});
} else {
wx.showModal({
title: '确认状态失败',
content: res.data?.msg || '操作失败',
showCancel: false,
});
}
} catch (err) {
if (wxConfirmed) {
await this.finishWxCollectSuccess(record);
} else {
wx.showModal({
title: '网络错误',
content: '网络连接失败',
showCancel: false,
});
}
} finally {
this.setData({ submitting: false, currentTixianId: null, collectConfirmRecord: null });
}
},
onViewDetail(e) {
const index = e.currentTarget.dataset.index;
const record = this.data.recordList[index];
if (!record || !record.canShowDetail) return;
const status = parseInt(record.zhuangtai);
let detailTitle = '失败原因';
if (status === TX_STATUS.SHENHE_SHIBAI) detailTitle = '审核失败原因';
else if (status === TX_STATUS.TIXIAN_SHIBAI) detailTitle = '提现失败原因';
this.setData({
showDetailModal: true,
detailTitle,
detailContent: record.detailReason || '暂无详细信息',
showTixian: false,
selectedAsset: null,
tixianleixing: null,
shouxufei: '0.00',
shijidaozhang: '0.00',
});
},
onCloseDetailModal() {
this.setData({ showDetailModal: false, detailTitle: '', detailContent: '' });
},
onCloseTixian() {
if (this.data.submitting) { wx.showToast({ title: '正在处理中,请稍后', icon: 'none' }); return; }
this.setData({
showTixian: false, selectedAsset: null, tixianleixing: null,
tixianjine: '', shouxufei: '0.00', shijidaozhang: '0.00', submitting: false,
});
},
async huoquJilu(fresh = false, force = false) {
const now = Date.now();
if (!force && now - lastPullDownTime < 2000 && !fresh) return;
if (!force && (this.data.loading || this.data.isRefreshing)) return;
const page = fresh ? 1 : this.data.page;
if (fresh) this.setData({ nomore: false, canloadmore: true, isRefreshing: true });
if (this.data.nomore && !fresh) return;
this.setData({ loading: true });
lastPullDownTime = now;
try {
const res = await request({
url: '/yonghu/tixianjiluhq',
method: 'POST',
data: { page, limit: yemianshuju, mode: 2, zhuangtai: this.data.currentStatusFilter }
});
if (res.statusCode === 200 && res.data && res.data.code === 0) {
const data = res.data.data;
const processedList = (data.list || []).map(item => this.processRecordItem(item));
const newList = fresh ? processedList : [...this.data.recordList, ...processedList];
this.setData({
recordList: newList,
page: page + 1,
nomore: !(data.has_more === true),
canloadmore: data.has_more === true,
loading: false,
isRefreshing: false,
});
this.updatePendingCollectFlag(newList);
} else {
this.setData({ loading: false, isRefreshing: false });
}
} catch (err) {
this.setData({ loading: false, isRefreshing: false });
}
},
onReachBottom() {
if (this.data.canloadmore && !this.data.nomore && !this.data.loading && !this.data.isRefreshing) {
const now = Date.now();
if (now - lastPullDownTime >= PULL_DOWN_INTERVAL) this.huoquJilu();
}
},
stopPropagation() {}
}
stopPropagation() {},
},
});

View File

@@ -1,113 +1,91 @@
<!-- mode2 自动打款 - UI 与 mode1 手动提现完全一致,逻辑为自动审核收款 -->
<view class="app">
<image class="global-bg" src="{{imgUrls.pageBg}}" mode="aspectFill" />
<!-- 资产区域(与 mode1 相同) -->
<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="type">
<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 && !isLoadingAssets}}" class="assets-empty">暂无可用资金</view>
</view>
</scroll-view>
<!-- mode2 自动打款 - 参考逍遥梦样式(仅微信零钱) -->
<view class="ref-page">
<!-- 提现方式:仅微信 -->
<view class="method-card">
<view class="method-tab method-tab--active">
<image class="method-tab-icon" src="{{imgUrls.iconWechat}}" mode="aspectFit" />
<text class="method-tab-text">微信零钱</text>
<view class="method-tab-line"></view>
</view>
<view class="divider-line"></view>
</view>
<!-- 提现记录区mode1 布局 + 自动打款筛选/收款 -->
<view class="history-section">
<view class="history-header">
<text class="history-title">提现记录</text>
</view>
<view wx:if="{{hasPendingCollect}}" class="pending-tip">
您有审核通过的提现待收款,请点击「收款」按钮,在微信中主动确认后才能到账。
</view>
<scroll-view class="filter-scroll" scroll-x show-scrollbar="{{false}}">
<view class="filter-track">
<view
wx:for="{{statusTabs}}"
wx:key="value"
class="filter-chip {{currentStatusFilter == item.value ? 'active' : ''}}"
bindtap="onStatusFilterTap"
data-value="{{item.value}}"
>{{item.label}}</view>
<!-- 选择提现账户(多身份时展示 -->
<view class="account-card" wx:if="{{displayAssetList.length > 0}}">
<scroll-view scroll-x enable-flex class="account-scroll" show-scrollbar="{{false}}">
<view
wx:for="{{displayAssetList}}"
wx:key="type"
class="account-chip {{selectedAsset.type === item.type ? 'account-chip--active' : ''}} {{item.amount <= 0 ? 'account-chip--disabled' : ''}}"
bindtap="onSelectAsset"
data-index="{{index}}"
>
<text class="chip-label">{{item.label}}</text>
<text class="chip-amount">¥{{item.amount}}</text>
</view>
</scroll-view>
<scroll-view class="history-scroll" scroll-y enable-back-to-top bindscrolltolower="onReachBottom">
<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">微信零钱</text>
<text class="history-type">{{item.leixingLabel}}</text>
</view>
<view class="history-status">
<!-- 待收款:整块可点击 → 弹出确认收款弹窗 → 用户确认后才请求后端 -->
<view
wx:if="{{item.canCollect}}"
class="status-badge status-pending collect-tappable"
bindtap="onCollectTap"
data-index="{{index}}"
>
<text>{{item.statusText}}</text>
<text class="collect-sub">点击收款</text>
</view>
<view wx:elif="{{item.canShowDetail}}" class="status-badge status-fail">
{{item.statusText}}
<text class="fail-link" bindtap="onViewDetail" data-index="{{index}}">详情</text>
</view>
<view wx:else class="status-badge {{item.statusBadgeClass}}">{{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="onReachBottom">加载更多记录</view>
<view wx:if="{{recordList.length === 0 && !loading}}" class="load-tip">暂无提现记录</view>
</scroll-view>
<text wx:if="{{!selectedAsset}}" class="account-warn">请先选择上方提现账户</text>
<text wx:else class="account-ok">当前:{{selectedAsset.label}}</text>
</view>
<view class="safe-bottom"></view>
<!-- 金额输入区 -->
<view class="amount-card">
<view class="avail-row">
<text class="avail-label">当前可提现:</text>
<text class="avail-symbol">¥</text>
<text class="avail-amount">{{selectedAsset ? selectedAsset.amount : totalAmount}}</text>
</view>
<view class="input-row">
<text class="input-symbol">¥</text>
<input
class="amount-input"
type="digit"
placeholder="请输入金额"
placeholder-class="amount-placeholder"
value="{{tixianjine}}"
bindinput="onJineInput"
/>
<text class="withdraw-all" bindtap="onWithdrawAll">全部提现</text>
</view>
<view class="input-divider"></view>
<view class="fee-tip">
<text>提示:提现手续费</text>
<text class="fee-highlight">{{feeRateText}}</text>
<text>。</text>
</view>
</view>
<!-- 确认按钮 -->
<view class="submit-wrap">
<view
class="confirm-btn {{canWithdraw && !submitting ? '' : 'confirm-btn--disabled'}}"
bindtap="onTapWithdraw"
>
<text wx:if="{{submitting}}">处理中...</text>
<text wx:else>确认提现</text>
</view>
</view>
<!-- 提现须知 -->
<view class="notice-box">
<view class="notice-title">📢 提现须知</view>
<view class="notice-item">🕒 提交后需等待后台审核,请耐心等待</view>
<view class="notice-item">📌 审核通过后,请前往「提现记录」点击「收款」确认到账</view>
<view class="notice-item">💰 每笔只能从单个账户提现,请先选择对应账户再填写金额</view>
<view class="notice-item">✅ 提现方式仅支持微信零钱,暂不支持支付宝</view>
<view class="notice-item">🎧 运营账户不足时暂时无法提现,请稍后再试或联系客服</view>
</view>
</view>
<!-- 申请提现弹窗mode1 样式,无收款方式) -->
<!-- 确认提现弹窗 -->
<view wx:if="{{showTixian}}" class="modal-mask" bindtap="onCloseTixian">
<view class="modal-dialog" catchtap="stopPropagation">
<view class="modal-header">申请提现</view>
<view class="modal-header">确认提现</view>
<view class="modal-body">
<view class="auto-tip">提交后需等待审核,审核通过后请在本页点击「收款」确认到账</view>
<view class="info-row"><text>项目</text><text>{{selectedAsset.label}}</text></view>
<view class="auto-tip">提交后需等待审核,审核通过后请在「提现记录」中点击「收款」确认到账</view>
<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="{{tixianjine}}" bindinput="onJineInput" />
</view>
<view class="quick-row">
<view wx:for="{{[100,200,500,1000]}}" wx:key="item" class="quick-chip" data-value="{{item}}" bindtap="onQuickAmountTap">¥{{item}}</view>
</view>
<view class="info-row"><text>费率</text><text>{{currentRate}}</text></view>
<view class="info-row"><text>提现金额</text><text>¥{{tixianjine}}</text></view>
<view class="fee-row">
<text>手续费 ¥{{shouxufei}}</text>
<text>到账 ¥{{shijidaozhang}}</text>
@@ -120,33 +98,5 @@
</view>
</view>
<!-- 收款确认弹窗 -->
<view wx:if="{{showCollectConfirm}}" class="modal-mask" bindtap="onCloseCollectConfirm">
<view class="modal-dialog" catchtap="stopPropagation">
<view class="modal-header">确认收款</view>
<view class="modal-body">
<view class="auto-tip">审核已通过,{{collectConfirmRecord.leixingLabel}} ¥{{collectConfirmRecord.jine}}</view>
<view>请点击「去收款」,然后在微信弹窗中主动确认,资金才会打入您的微信零钱。</view>
<view class="warn-tip" wx:if="{{collectConfirmRecord.shenhe_danhao}}">审核单号:{{collectConfirmRecord.shenhe_danhao}}</view>
<view class="warn-tip">注意:审核通过≠已到账,必须您本人点击确认才能完成收款!</view>
</view>
<view class="modal-footer">
<view class="modal-btn cancel" bindtap="onCloseCollectConfirm">稍后再说</view>
<view class="modal-btn confirm" bindtap="onConfirmCollect">{{submitting ? '处理中...' : '去收款'}}</view>
</view>
</view>
</view>
<!-- 失败/驳回详情弹窗 -->
<view wx:if="{{showDetailModal}}" class="modal-mask" bindtap="onCloseDetailModal">
<view class="modal-dialog" catchtap="stopPropagation">
<view class="modal-header">{{detailTitle}}</view>
<view class="modal-body">{{detailContent}}</view>
<view class="modal-footer">
<view class="modal-btn confirm" bindtap="onCloseDetailModal">知道了</view>
</view>
</view>
</view>
<global-notification id="global-notification" />
<popup-notice id="popupNotice" />

View File

@@ -1,408 +1,325 @@
/* mode2 自动打款 - UI 完全复用 mode1 样式 */
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-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);
}
.status-pending {
color: #3b82f6;
background: rgba(59,130,246,0.1);
}
.fail-link {
margin-left: 8rpx;
text-decoration: underline;
}
.collect-tappable {
display: inline-flex;
flex-direction: column;
align-items: center;
gap: 4rpx;
padding: 10rpx 18rpx;
cursor: pointer;
border: 2rpx solid rgba(59,130,246,0.35);
box-shadow: 0 4rpx 12rpx rgba(59,130,246,0.15);
}
.collect-tappable:active {
transform: scale(0.97);
opacity: 0.9;
}
.collect-sub {
font-size: 22rpx;
font-weight: 700;
color: #1d4ed8;
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; }
/* 自动打款专属(少量追加) */
.pending-tip {
margin: 0 8rpx 16rpx;
padding: 16rpx 20rpx;
font-size: 24rpx;
color: #1d4ed8;
background: rgba(59,130,246,0.08);
border-radius: 20rpx;
line-height: 1.5;
}
.filter-scroll {
width: 100%;
white-space: nowrap;
margin-bottom: 12rpx;
}
.filter-track {
display: inline-flex;
gap: 12rpx;
padding: 0 8rpx;
}
.filter-chip {
flex-shrink: 0;
padding: 10rpx 22rpx;
font-size: 24rpx;
color: #64748b;
background: rgba(255,255,255,0.8);
border-radius: 30rpx;
border: 1rpx solid rgba(0,0,0,0.06);
}
.filter-chip.active {
color: #3b82f6;
background: #eff6ff;
border-color: #3b82f6;
}
.auto-tip {
font-size: 24rpx;
color: #3b82f6;
margin-bottom: 20rpx;
line-height: 1.5;
}
.warn-tip {
font-size: 24rpx;
color: #f59e0b;
margin-top: 16rpx;
font-weight: 600;
}
/* 弹窗(与 mode1 一致) */
.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;
font-size: 28rpx;
color: #334155;
line-height: 1.6;
}
.info-row, .amount-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;
}
.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; }
background: #f5f5f5;
min-height: 100vh;
}
.ref-page {
min-height: 100vh;
padding: 24rpx 24rpx 48rpx;
box-sizing: border-box;
}
/* 提现方式 Tab */
.method-card {
background: #fff;
border-radius: 16rpx;
padding: 0 32rpx;
margin-bottom: 20rpx;
}
.method-tab {
display: inline-flex;
flex-direction: column;
align-items: center;
padding: 28rpx 16rpx 20rpx;
position: relative;
}
.method-tab-icon {
width: 48rpx;
height: 48rpx;
margin-bottom: 8rpx;
}
.method-tab-text {
font-size: 28rpx;
color: #333;
font-weight: 500;
}
.method-tab-line {
position: absolute;
bottom: 0;
left: 50%;
transform: translateX(-50%);
width: 80rpx;
height: 6rpx;
background: #FFD54F;
border-radius: 3rpx;
}
/* 账户选择 */
.account-card {
background: #fff;
border-radius: 16rpx;
padding: 20rpx 16rpx 16rpx;
margin-bottom: 20rpx;
}
.account-scroll {
white-space: nowrap;
display: flex;
flex-direction: row;
}
.account-chip {
display: inline-flex;
flex-direction: column;
align-items: center;
padding: 16rpx 24rpx;
margin-right: 16rpx;
border-radius: 12rpx;
background: #f8f8f8;
border: 2rpx solid transparent;
min-width: 160rpx;
}
.account-chip--active {
background: #fffbeb;
border-color: #FFD54F;
}
.account-chip--disabled {
opacity: 0.45;
}
.chip-label {
font-size: 24rpx;
color: #666;
margin-bottom: 4rpx;
}
.chip-amount {
font-size: 28rpx;
color: #333;
font-weight: 600;
}
.account-warn {
display: block;
margin-top: 12rpx;
font-size: 24rpx;
color: #ff8c00;
padding: 0 8rpx;
}
.account-ok {
display: block;
margin-top: 12rpx;
font-size: 24rpx;
color: #888;
padding: 0 8rpx;
}
/* 金额卡片 */
.amount-card {
background: #fff;
border-radius: 16rpx;
padding: 32rpx 32rpx 28rpx;
margin-bottom: 32rpx;
}
.avail-row {
display: flex;
align-items: baseline;
margin-bottom: 32rpx;
}
.avail-label {
font-size: 28rpx;
color: #333;
}
.avail-symbol {
font-size: 28rpx;
color: #ff8c00;
margin-left: 4rpx;
}
.avail-amount {
font-size: 32rpx;
color: #ff8c00;
font-weight: 700;
}
.input-row {
display: flex;
align-items: center;
padding-bottom: 8rpx;
}
.input-symbol {
font-size: 64rpx;
font-weight: 700;
color: #333;
line-height: 1;
margin-right: 8rpx;
}
.amount-input {
flex: 1;
font-size: 56rpx;
font-weight: 600;
color: #333;
height: 80rpx;
min-height: 80rpx;
}
.amount-placeholder {
color: #ccc;
font-size: 40rpx;
font-weight: 400;
}
.withdraw-all {
font-size: 28rpx;
color: #ff8c00;
padding: 8rpx 0 8rpx 16rpx;
flex-shrink: 0;
}
.input-divider {
height: 1rpx;
background: #eee;
margin: 16rpx 0 20rpx;
}
.fee-tip {
font-size: 26rpx;
color: #666;
}
.fee-highlight {
color: #ff8c00;
font-weight: 600;
}
/* 确认按钮 */
.submit-wrap {
padding: 0 8rpx;
margin-bottom: 32rpx;
}
.confirm-btn {
width: 100%;
height: 96rpx;
background: linear-gradient(90deg, #FFD54F 0%, #FFB300 100%);
border-radius: 48rpx;
display: flex;
align-items: center;
justify-content: center;
font-size: 34rpx;
font-weight: 700;
color: #333;
box-shadow: 0 8rpx 20rpx rgba(255, 179, 0, 0.35);
}
.confirm-btn:active {
opacity: 0.92;
transform: scale(0.99);
}
.confirm-btn--disabled {
background: linear-gradient(90deg, #e0e0e0, #bdbdbd);
box-shadow: none;
color: #999;
}
/* 须知 */
.notice-box {
background: #ebebeb;
border-radius: 16rpx;
padding: 28rpx 28rpx 32rpx;
}
.notice-title {
font-size: 28rpx;
color: #333;
font-weight: 600;
margin-bottom: 20rpx;
}
.notice-item {
font-size: 26rpx;
color: #555;
line-height: 1.7;
margin-bottom: 8rpx;
}
/* 确认弹窗 */
.modal-mask {
position: fixed;
inset: 0;
background: rgba(0, 0, 0, 0.5);
display: flex;
align-items: center;
justify-content: center;
z-index: 1001;
}
.modal-dialog {
width: 620rpx;
background: #fff;
border-radius: 20rpx;
overflow: hidden;
}
.modal-header {
padding: 32rpx;
font-size: 34rpx;
font-weight: 700;
text-align: center;
border-bottom: 1rpx solid #f0f0f0;
}
.modal-body {
padding: 32rpx;
font-size: 28rpx;
color: #333;
}
.auto-tip {
font-size: 24rpx;
color: #ff8c00;
margin-bottom: 20rpx;
line-height: 1.5;
}
.info-row {
display: flex;
justify-content: space-between;
margin-bottom: 16rpx;
font-size: 28rpx;
}
.fee-row {
display: flex;
justify-content: space-between;
background: #fff8e1;
padding: 20rpx;
border-radius: 12rpx;
margin-top: 16rpx;
color: #333;
}
.modal-footer {
display: flex;
border-top: 1rpx solid #f0f0f0;
}
.modal-btn {
flex: 1;
text-align: center;
padding: 28rpx;
font-size: 30rpx;
}
.modal-btn.cancel {
color: #999;
border-right: 1rpx solid #f0f0f0;
}
.modal-btn.confirm {
color: #ff8c00;
font-weight: 600;
}

View File

@@ -0,0 +1,243 @@
// pages/withdraw/components/record-mode1/record-mode1.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.loadWithdrawRecords(true);
},
pageLifetimes: {
show() {
this.registerNotification();
PopupService.checkAndShow(this, 'tixian');
},
hide() {
const popup = this.selectComponent('#popupNotice');
popup?.cleanup?.();
}
},
methods: {
onPullDownRefresh() {
return this.loadWithdrawRecords(true);
},
onLoadMoreFromScroll() {
this.loadMoreRecords();
},
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 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,7 @@
{
"component": true,
"usingComponents": {
"global-notification": "/components/global-notification/global-notification",
"popup-notice": "/components/popup-notice/popup-notice"
}
}

View File

@@ -0,0 +1,60 @@
<!-- record-mode1仅提现记录收款码手动审核 -->
<view class="app">
<image class="global-bg" src="{{imgUrls.pageBg}}" mode="aspectFill" />
<view class="history-section history-section--full">
<view class="history-header">
<text class="history-title">提现记录</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>
<view wx:if="{{recordList.length === 0 && !loading}}" class="load-tip">暂无提现记录</view>
</scroll-view>
</view>
<view class="safe-bottom"></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,67 @@
@import "../record-mode2/record-mode2.wxss";
.history-section--full {
flex: 1;
min-height: calc(100vh - 48rpx);
margin-top: 24rpx;
}
.history-section--full .history-scroll {
height: calc(100vh - 200rpx);
}
.toggle-row {
display: flex;
gap: 16rpx;
margin-bottom: 20rpx;
}
.toggle-item {
flex: 1;
text-align: center;
padding: 16rpx;
border-radius: 12rpx;
background: #f1f5f9;
font-size: 28rpx;
color: #64748b;
}
.toggle-item.active {
background: #eff6ff;
color: #3b82f6;
font-weight: 600;
}
.field-input {
width: 100%;
box-sizing: border-box;
padding: 20rpx;
border: 1rpx solid #e2e8f0;
border-radius: 12rpx;
margin-bottom: 16rpx;
font-size: 28rpx;
}
.upload-trigger {
padding: 40rpx;
text-align: center;
border: 2rpx dashed #cbd5e1;
border-radius: 12rpx;
color: #64748b;
font-size: 28rpx;
}
.image-preview image {
width: 100%;
height: 240rpx;
border-radius: 12rpx;
}
.image-actions {
display: flex;
gap: 24rpx;
justify-content: center;
margin-top: 12rpx;
font-size: 26rpx;
color: #3b82f6;
}

View File

@@ -0,0 +1,513 @@
// pages/withdraw/components/record-mode2/record-mode2.js
// UI 与 mode1 完全一致,业务逻辑为自动打款审核收款
import request from '../../../../utils/request.js';
import PopupService from '../../../../services/popupService.js';
const app = getApp();
const yemianshuju = 5;
let lastPullDownTime = 0;
const PULL_DOWN_INTERVAL = 2000;
const TX_STATUS = {
SHENHEZHONG: 1,
TIXIAN_CHENGGONG: 2,
TIXIAN_SHIBAI: 3,
SHENHE_CHENGGONG: 4,
SHENHE_SHIBAI: 5,
DAI_SHOUKUAN: 6,
};
const ASSET_CONFIG = {
dashou_yue: { leixing: 1, label: '接单员佣金' },
guanshi_fenyong: { leixing: 2, label: '管事分红' },
zuzhang_fenyong: { leixing: 3, label: '组长分红' },
kaoheguan_fenyong: { leixing: 4, label: '考核官分佣' },
dashou_yajin: { leixing: 5, label: '接单员保证金' },
shangjia_yue: { leixing: 6, label: '商家余额' },
};
const LEIXING_LABEL = {
1: '接单员佣金', 2: '管事分红', 3: '组长分红',
4: '考核官分佣', 5: '接单员保证金', 6: '商家余额',
};
Component({
properties: { options: { type: Object, value: {} } },
data: {
imgUrls: {
pageBg: '', cardBg: '', assetTileBg: '',
},
assetList: [],
totalAmount: '0.00',
selectedAsset: null,
isLoadingAssets: false,
tixianleixing: null,
tixianjine: '',
currentRate: '0.00',
showTixian: false,
recordList: [],
page: 1,
loading: false,
nomore: false,
canloadmore: true,
isRefreshing: false,
shouxufei: '0.00',
shijidaozhang: '0.00',
currentTixianId: null,
submitting: false,
mchId: '',
currentStatusFilter: 0,
statusTabs: [
{ value: 0, label: '全部' },
{ value: 1, label: '审核中' },
{ value: 6, label: '待收款' },
{ value: 4, label: '审核成功' },
{ value: 5, label: '审核失败' },
{ value: 2, label: '提现成功' },
{ value: 3, label: '提现失败' },
],
hasPendingCollect: false,
showCollectConfirm: false,
collectConfirmRecord: null,
showDetailModal: false,
detailTitle: '',
detailContent: '',
},
lifetimes: {
attached() {
this.initImageUrls();
this.huoquJilu(true);
}
},
pageLifetimes: {
show() {
this.registerNotificationComponent();
PopupService.checkAndShow(this, 'tixian');
},
hide() {
const popupComp = this.selectComponent('#popupNotice');
if (popupComp && popupComp.cleanup) popupComp.cleanup();
}
},
methods: {
registerNotificationComponent() {
const notificationComp = this.selectComponent('#global-notification');
if (notificationComp && notificationComp.showNotification) {
app.globalData.globalNotification = {
show: (data) => notificationComp.showNotification(data),
hide: () => notificationComp.hideNotification()
};
}
},
initImageUrls() {
const ossBase = app.globalData.ossImageUrl || '';
const imgDir = `${ossBase}beijing/tixian/`;
this.setData({
imgUrls: {
pageBg: `${imgDir}page_bg.png`,
cardBg: `${imgDir}card_bg.png`,
assetTileBg: `${imgDir}asset_tile_bg.png`,
}
});
},
parseZhuangtai(item) {
const raw = item.zhuangtai ?? item.status ?? item.state;
const n = parseInt(raw, 10);
return Number.isNaN(n) ? -1 : n;
},
/** 规范化列表字段(兼容后端多种命名 / 嵌套 audit */
normalizeRecordFields(item) {
const audit = item.audit || item.shenhe || item.shenhe_info || {};
const shenheJiluId = item.shenhe_jilu_id ?? item.shenheJiluId
?? item.audit_id ?? item.shenheid ?? audit.id ?? audit.shenhe_jilu_id ?? null;
const shenheDanhao = String(
item.shenhe_danhao || item.shenheDanhao || item.audit_shenhe_danhao
|| audit.shenhe_danhao || audit.danhao || ''
).trim();
const tixianjiluId = item.tixianjilu_id ?? item.tixianjiluId ?? item.id ?? null;
const zhuangtai = this.parseZhuangtai(item);
return {
...item,
zhuangtai: zhuangtai >= 0 ? zhuangtai : item.zhuangtai,
shenhe_jilu_id: shenheJiluId,
shenhe_danhao: shenheDanhao,
tixianjilu_id: tixianjiluId,
};
},
hasAuditJiluId(item) {
const id = item.shenhe_jilu_id;
return id !== null && id !== undefined && id !== '' && id !== 0 && id !== '0';
},
hasShenheDanhao(item) {
return !!(item.shenhe_danhao && String(item.shenhe_danhao).trim());
},
isNewAuditRecord(item) {
return this.hasAuditJiluId(item) && this.hasShenheDanhao(item);
},
/** 待收款是否可点击状态6 + 审核记录ID + 审核单号 缺一不可 */
canCollectRecord(item) {
return this.parseZhuangtai(item) === TX_STATUS.DAI_SHOUKUAN
&& this.hasAuditJiluId(item)
&& this.hasShenheDanhao(item);
},
getLeixingLabel(leixing) {
return LEIXING_LABEL[parseInt(leixing)] || '提现';
},
getStatusBadgeClass(status) {
switch (parseInt(status)) {
case TX_STATUS.SHENHEZHONG: return 'status-wait';
case TX_STATUS.TIXIAN_CHENGGONG:
case TX_STATUS.SHENHE_CHENGGONG: return 'status-done';
case TX_STATUS.DAI_SHOUKUAN: return 'status-pending';
case TX_STATUS.TIXIAN_SHIBAI:
case TX_STATUS.SHENHE_SHIBAI: return 'status-fail';
default: return 'status-wait';
}
},
processRecordItem(item) {
item = this.normalizeRecordFields(item);
const isNew = this.isNewAuditRecord(item);
const status = this.parseZhuangtai(item);
let statusText = '未知';
let canCollect = false;
let canShowDetail = false;
let detailReason = '';
switch (status) {
case TX_STATUS.SHENHEZHONG: statusText = '审核中'; break;
case TX_STATUS.TIXIAN_CHENGGONG: statusText = '提现成功'; break;
case TX_STATUS.TIXIAN_SHIBAI:
statusText = '提现失败';
if (item.fail_reason || item.bhliyou) {
canShowDetail = true;
detailReason = item.fail_reason || item.bhliyou;
}
break;
case TX_STATUS.SHENHE_CHENGGONG: statusText = '审核成功'; break;
case TX_STATUS.SHENHE_SHIBAI:
statusText = '审核失败';
if (item.bhliyou) { canShowDetail = true; detailReason = item.bhliyou; }
break;
case TX_STATUS.DAI_SHOUKUAN:
statusText = '待收款';
canCollect = this.canCollectRecord(item);
break;
}
return {
...item,
isNewAudit: isNew,
leixingLabel: this.getLeixingLabel(item.leixing),
statusText,
statusBadgeClass: this.getStatusBadgeClass(status),
canCollect,
canShowDetail,
detailReason,
};
},
gengxinYue(data, leixing) {
if (!data) return;
if (data.new_yongjin !== undefined && data.new_yongjin !== null) {
app.globalData.yongjin = data.new_yongjin;
}
if (data.new_fenyong !== undefined && data.new_fenyong !== null) {
app.globalData.guanshi.fenyongtixian = data.new_fenyong;
}
if (data.new_yajin !== undefined && data.new_yajin !== null) {
app.globalData.yajin = data.new_yajin;
}
if (data.new_shangjia_yue !== undefined && data.new_shangjia_yue !== null) {
if (app.globalData.shangjia) app.globalData.shangjia.sjyue = data.new_shangjia_yue;
}
if (data.current_rate !== undefined && leixing) {
const rate = parseFloat(data.current_rate);
const rateKeyMap = { 1: 'dashouRate', 5: 'dashou_yajin_rate', 6: 'shangjia_rate', 2: 'guanshi_rate', 3: 'zuzhang_rate', 4: 'kaoheguan_rate' };
const key = rateKeyMap[leixing];
if (key) wx.setStorageSync(key, rate);
}
},
updatePendingCollectFlag(list) {
const hasPending = (list || []).some(item => item.canCollect);
if (hasPending !== this.data.hasPendingCollect) {
this.setData({ hasPendingCollect: hasPending });
}
},
/** 微信确认收款成功后,本地先把对应记录标为「提现成功」 */
markLocalRecordWithdrawSuccess(record) {
if (!record) return;
const matchId = String(record.tixianjilu_id || record.id || '');
const matchDanhao = String(record.shenhe_danhao || '').trim();
if (!matchId && !matchDanhao) return;
const newList = (this.data.recordList || []).map((item) => {
const itemId = String(item.tixianjilu_id || item.id || '');
const itemDanhao = String(item.shenhe_danhao || '').trim();
const isMatch = (matchId && itemId === matchId)
|| (matchDanhao && itemDanhao === matchDanhao);
if (!isMatch) return item;
return this.processRecordItem({
...item,
zhuangtai: TX_STATUS.TIXIAN_CHENGGONG,
});
});
this.setData({ recordList: newList });
this.updatePendingCollectFlag(newList);
},
async finishWxCollectSuccess(record) {
this.markLocalRecordWithdrawSuccess(record);
await this.huoquJilu(true, true);
this.markLocalRecordWithdrawSuccess(record);
PopupService.checkAndShow(this, 'tixianchenggong');
wx.showToast({
title: '提现成功',
icon: 'success',
duration: 3000,
});
},
onPullDownRefresh() {
return this.huoquJilu(true, true);
},
onStatusFilterTap(e) {
const value = parseInt(e.currentTarget.dataset.value, 10);
if (value === this.data.currentStatusFilter) return;
this.setData({ currentStatusFilter: value });
this.huoquJilu(true);
},
onCollectTap(e) {
const index = e.currentTarget.dataset.index;
const record = this.data.recordList[index];
if (!record) return;
if (this.parseZhuangtai(record) !== TX_STATUS.DAI_SHOUKUAN) {
wx.showToast({ title: '当前状态不可收款', icon: 'none' });
return;
}
if (!this.hasShenheDanhao(record) || !this.hasAuditJiluId(record)) {
wx.showToast({ title: '审核信息不完整,请刷新后重试', icon: 'none' });
return;
}
if (this.data.submitting) {
wx.showToast({ title: '正在处理中,请稍后', icon: 'none' });
return;
}
this.setData({ showCollectConfirm: true, collectConfirmRecord: record });
},
onCloseCollectConfirm() {
if (this.data.submitting) return;
this.setData({ showCollectConfirm: false, collectConfirmRecord: null });
},
async onConfirmCollect() {
if (this.data.submitting) return;
let record = this.data.collectConfirmRecord;
if (!record) return;
if (!this.canCollectRecord(record)) {
await this.huoquJilu(true, true);
const refreshed = (this.data.recordList || []).find(
r => String(r.id) === String(record.id)
|| String(r.tixianjilu_id) === String(record.tixianjilu_id)
);
if (refreshed) record = refreshed;
}
if (!this.canCollectRecord(record)) {
wx.showModal({
title: '暂时无法收款',
content: '缺少审核单号或审核记录ID请下拉刷新后重试。仍不行请联系客服。',
showCancel: false,
});
return;
}
this.setData({ showCollectConfirm: false, submitting: true, collectConfirmRecord: record });
try {
const res = await request({
url: '/yonghu/tixiansq',
method: 'POST',
data: {
shenhe_danhao: record.shenhe_danhao,
shenhe_jilu_id: record.shenhe_jilu_id || '',
tixianjilu_id: record.tixianjilu_id || record.id || '',
leixing: record.leixing,
}
});
if (res.statusCode === 200 && res.data && res.data.code === 0) {
const data = res.data.data;
this.setData({
currentTixianId: data.tixian_id,
mchId: data.mch_id || '',
collectConfirmRecord: record,
});
this.tiaoqiWeixinQueRen(data.package_info);
} else {
wx.showModal({ title: '收款失败', content: res.data?.msg || '无法发起收款,请稍后重试', showCancel: false });
this.setData({ submitting: false, collectConfirmRecord: null });
}
} catch (err) {
wx.showModal({ title: '网络错误', content: '网络连接失败,请稍后重试', showCancel: false });
this.setData({ submitting: false, collectConfirmRecord: null });
}
},
tiaoqiWeixinQueRen(packageInfo) {
const appId = app.globalData.appId;
const mchId = this.data.mchId;
if (!appId || !mchId) {
wx.showModal({ title: '配置错误', content: '无法调起收款,请联系客服', showCancel: false });
this.setData({ submitting: false, collectConfirmRecord: null });
return;
}
wx.requestMerchantTransfer({
appId, mchId, package: packageInfo,
success: () => { this.tongzhiHouduanQueRen(1); },
fail: () => {
this.tongzhiHouduanQueRen(0);
wx.showModal({
title: '确认收款失败',
content: '微信收款确认失败,您可在记录中再次点击「收款」重试。',
showCancel: false,
});
}
});
},
async tongzhiHouduanQueRen(result) {
if (!this.data.currentTixianId) {
this.setData({ submitting: false, collectConfirmRecord: null });
return;
}
const record = this.data.collectConfirmRecord;
const wxConfirmed = result === 1;
try {
const res = await request({
url: '/yonghu/tixianqr',
method: 'POST',
data: {
tixian_id: this.data.currentTixianId,
result: result,
shenhe_danhao: record ? record.shenhe_danhao : '',
shenhe_jilu_id: record ? (record.shenhe_jilu_id || '') : '',
tixianjilu_id: record ? (record.tixianjilu_id || record.id || '') : '',
leixing: record ? record.leixing : '',
}
});
if (res.statusCode === 200 && res.data && res.data.code === 0) {
const data = res.data.data || {};
this.gengxinYue(data, record ? record.leixing : null);
}
// 微信已确认收款:不论 tixianqr 返回什么,都刷新列表,不弹系统异常
if (wxConfirmed) {
await this.finishWxCollectSuccess(record);
} else if (res.statusCode === 200 && res.data && res.data.code === 0) {
this.huoquJilu(true);
wx.showToast({
title: '收款已取消',
icon: 'none',
duration: 3000,
});
} else {
wx.showModal({
title: '确认状态失败',
content: res.data?.msg || '操作失败',
showCancel: false,
});
}
} catch (err) {
if (wxConfirmed) {
await this.finishWxCollectSuccess(record);
} else {
wx.showModal({
title: '网络错误',
content: '网络连接失败',
showCancel: false,
});
}
} finally {
this.setData({ submitting: false, currentTixianId: null, collectConfirmRecord: null });
}
},
onViewDetail(e) {
const index = e.currentTarget.dataset.index;
const record = this.data.recordList[index];
if (!record || !record.canShowDetail) return;
const status = parseInt(record.zhuangtai);
let detailTitle = '失败原因';
if (status === TX_STATUS.SHENHE_SHIBAI) detailTitle = '审核失败原因';
else if (status === TX_STATUS.TIXIAN_SHIBAI) detailTitle = '提现失败原因';
this.setData({
showDetailModal: true,
detailTitle,
detailContent: record.detailReason || '暂无详细信息',
});
},
onCloseDetailModal() {
this.setData({ showDetailModal: false, detailTitle: '', detailContent: '' });
},
async huoquJilu(fresh = false, force = false) {
const now = Date.now();
if (!force && now - lastPullDownTime < 2000 && !fresh) return;
if (!force && (this.data.loading || this.data.isRefreshing)) return;
const page = fresh ? 1 : this.data.page;
if (fresh) this.setData({ nomore: false, canloadmore: true, isRefreshing: true });
if (this.data.nomore && !fresh) return;
this.setData({ loading: true });
lastPullDownTime = now;
try {
const res = await request({
url: '/yonghu/tixianjiluhq',
method: 'POST',
data: { page, limit: yemianshuju, mode: 2, zhuangtai: this.data.currentStatusFilter }
});
if (res.statusCode === 200 && res.data && res.data.code === 0) {
const data = res.data.data;
const processedList = (data.list || []).map(item => this.processRecordItem(item));
const newList = fresh ? processedList : [...this.data.recordList, ...processedList];
this.setData({
recordList: newList,
page: page + 1,
nomore: !(data.has_more === true),
canloadmore: data.has_more === true,
loading: false,
isRefreshing: false,
});
this.updatePendingCollectFlag(newList);
} else {
this.setData({ loading: false, isRefreshing: false });
}
} catch (err) {
this.setData({ loading: false, isRefreshing: false });
}
},
onReachBottom() {
if (this.data.canloadmore && !this.data.nomore && !this.data.loading && !this.data.isRefreshing) {
const now = Date.now();
if (now - lastPullDownTime >= PULL_DOWN_INTERVAL) this.huoquJilu();
}
},
stopPropagation() {}
}
});

View File

@@ -0,0 +1,7 @@
{
"component": true,
"usingComponents": {
"global-notification": "/components/global-notification/global-notification",
"popup-notice": "/components/popup-notice/popup-notice"
}
}

View File

@@ -0,0 +1,90 @@
<!-- record-mode2仅提现记录自动打款 -->
<view class="app">
<image class="global-bg" src="{{imgUrls.pageBg}}" mode="aspectFill" />
<view class="history-section history-section--full">
<view class="history-header">
<text class="history-title">提现记录</text>
</view>
<view wx:if="{{hasPendingCollect}}" class="pending-tip">
您有审核通过的提现待收款,请点击「收款」按钮,在微信中主动确认后才能到账。
</view>
<scroll-view class="filter-scroll" scroll-x show-scrollbar="{{false}}">
<view class="filter-track">
<view
wx:for="{{statusTabs}}"
wx:key="value"
class="filter-chip {{currentStatusFilter == item.value ? 'active' : ''}}"
bindtap="onStatusFilterTap"
data-value="{{item.value}}"
>{{item.label}}</view>
</view>
</scroll-view>
<scroll-view class="history-scroll" scroll-y enable-back-to-top bindscrolltolower="onReachBottom">
<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">微信零钱</text>
<text class="history-type">{{item.leixingLabel}}</text>
</view>
<view class="history-status">
<view
wx:if="{{item.canCollect}}"
class="status-badge status-pending collect-tappable"
bindtap="onCollectTap"
data-index="{{index}}"
>
<text>{{item.statusText}}</text>
<text class="collect-sub">点击收款</text>
</view>
<view wx:elif="{{item.canShowDetail}}" class="status-badge status-fail">
{{item.statusText}}
<text class="fail-link" bindtap="onViewDetail" data-index="{{index}}">详情</text>
</view>
<view wx:else class="status-badge {{item.statusBadgeClass}}">{{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="onReachBottom">加载更多记录</view>
<view wx:if="{{recordList.length === 0 && !loading}}" class="load-tip">暂无提现记录</view>
</scroll-view>
</view>
<view class="safe-bottom"></view>
</view>
<view wx:if="{{showCollectConfirm}}" class="modal-mask" bindtap="onCloseCollectConfirm">
<view class="modal-dialog" catchtap="stopPropagation">
<view class="modal-header">确认收款</view>
<view class="modal-body">
<view class="auto-tip">审核已通过,{{collectConfirmRecord.leixingLabel}} ¥{{collectConfirmRecord.jine}}</view>
<view>请点击「去收款」,然后在微信弹窗中主动确认,资金才会打入您的微信零钱。</view>
<view class="warn-tip" wx:if="{{collectConfirmRecord.shenhe_danhao}}">审核单号:{{collectConfirmRecord.shenhe_danhao}}</view>
<view class="warn-tip">注意:审核通过≠已到账,必须您本人点击确认才能完成收款!</view>
</view>
<view class="modal-footer">
<view class="modal-btn cancel" bindtap="onCloseCollectConfirm">稍后再说</view>
<view class="modal-btn confirm" bindtap="onConfirmCollect">{{submitting ? '处理中...' : '去收款'}}</view>
</view>
</view>
</view>
<view wx:if="{{showDetailModal}}" class="modal-mask" bindtap="onCloseDetailModal">
<view class="modal-dialog" catchtap="stopPropagation">
<view class="modal-header">{{detailTitle}}</view>
<view class="modal-body">{{detailContent}}</view>
<view class="modal-footer">
<view class="modal-btn confirm" bindtap="onCloseDetailModal">知道了</view>
</view>
</view>
</view>
<global-notification id="global-notification" />
<popup-notice id="popupNotice" />

View File

@@ -0,0 +1,416 @@
/* mode2 自动打款 - UI 完全复用 mode1 样式 */
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-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);
}
.status-pending {
color: #3b82f6;
background: rgba(59,130,246,0.1);
}
.fail-link {
margin-left: 8rpx;
text-decoration: underline;
}
.collect-tappable {
display: inline-flex;
flex-direction: column;
align-items: center;
gap: 4rpx;
padding: 10rpx 18rpx;
cursor: pointer;
border: 2rpx solid rgba(59,130,246,0.35);
box-shadow: 0 4rpx 12rpx rgba(59,130,246,0.15);
}
.collect-tappable:active {
transform: scale(0.97);
opacity: 0.9;
}
.collect-sub {
font-size: 22rpx;
font-weight: 700;
color: #1d4ed8;
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); }
.history-section--full {
flex: 1;
min-height: calc(100vh - 48rpx);
margin-top: 24rpx;
}
.history-section--full .history-scroll {
height: calc(100vh - 280rpx);
}
/* 自动打款专属(少量追加) */
.pending-tip {
margin: 0 8rpx 16rpx;
padding: 16rpx 20rpx;
font-size: 24rpx;
color: #1d4ed8;
background: rgba(59,130,246,0.08);
border-radius: 20rpx;
line-height: 1.5;
}
.filter-scroll {
width: 100%;
white-space: nowrap;
margin-bottom: 12rpx;
}
.filter-track {
display: inline-flex;
gap: 12rpx;
padding: 0 8rpx;
}
.filter-chip {
flex-shrink: 0;
padding: 10rpx 22rpx;
font-size: 24rpx;
color: #64748b;
background: rgba(255,255,255,0.8);
border-radius: 30rpx;
border: 1rpx solid rgba(0,0,0,0.06);
}
.filter-chip.active {
color: #3b82f6;
background: #eff6ff;
border-color: #3b82f6;
}
.auto-tip {
font-size: 24rpx;
color: #3b82f6;
margin-bottom: 20rpx;
line-height: 1.5;
}
.warn-tip {
font-size: 24rpx;
color: #f59e0b;
margin-top: 16rpx;
font-weight: 600;
}
/* 弹窗(与 mode1 一致) */
.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;
font-size: 28rpx;
color: #334155;
line-height: 1.6;
}
.info-row, .amount-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;
}
.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; }

View File

@@ -0,0 +1,51 @@
// pages/withdraw/withdraw-records.js — 提现记录独立页
import { createPage, request } from '../../utils/base-page.js';
Page(createPage({
data: {
pageMode: 0,
loadError: false,
},
onLoad() {
this.fetchPageMode();
},
async fetchPageMode() {
try {
const res = await request({
url: '/peizhi/hqtxzsym',
method: 'POST',
});
if (res.statusCode === 200 && res.data && res.data.code === 0) {
const mode = parseInt(res.data.data.mode, 10);
this.setData({
pageMode: (mode === 1 || mode === 2) ? mode : 1,
loadError: false,
});
} else {
this.setData({ pageMode: 1, loadError: false });
}
} catch (err) {
console.error('获取展示模式失败:', err);
this.setData({ loadError: true });
}
},
retryFetch() {
this.setData({ loadError: false, pageMode: 0 });
this.fetchPageMode();
},
onPullDownRefresh() {
const mode = this.data.pageMode;
const compId = mode === 1 ? '#record-mode2' : mode === 2 ? '#record-mode1' : null;
if (!compId) {
wx.stopPullDownRefresh();
return;
}
const comp = this.selectComponent(compId);
const p = comp && comp.onPullDownRefresh ? comp.onPullDownRefresh() : Promise.resolve();
Promise.resolve(p).finally(() => wx.stopPullDownRefresh());
},
}));

View File

@@ -0,0 +1,11 @@
{
"navigationBarTitleText": "提现记录",
"navigationBarBackgroundColor": "#ffffff",
"navigationBarTextStyle": "black",
"backgroundColor": "#f5f7fb",
"enablePullDownRefresh": true,
"usingComponents": {
"record-mode1": "./components/record-mode1/record-mode1",
"record-mode2": "./components/record-mode2/record-mode2"
}
}

View File

@@ -0,0 +1,14 @@
<view class="records-container">
<view wx:if="{{pageMode === 0 && !loadError}}" class="loading-center">
<view class="loading-spinner"></view>
<text class="loading-text">加载中...</text>
</view>
<view wx:elif="{{loadError}}" class="error-center">
<text class="error-text">加载失败,请检查网络</text>
<view class="retry-btn" bindtap="retryFetch">点击重试</view>
</view>
<record-mode1 wx:elif="{{pageMode === 2}}" id="record-mode1" />
<record-mode2 wx:elif="{{pageMode === 1}}" id="record-mode2" />
</view>

View File

@@ -0,0 +1,41 @@
.records-container {
width: 100%;
min-height: 100vh;
background: #f5f7fb;
}
.loading-center, .error-center {
height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
color: #64748b;
}
.loading-spinner {
width: 60rpx;
height: 60rpx;
border: 4rpx solid rgba(59, 130, 246, 0.2);
border-top-color: #3b82f6;
border-radius: 50%;
animation: spin 0.8s linear infinite;
margin-bottom: 24rpx;
}
@keyframes spin {
to { transform: rotate(360deg); }
}
.loading-text, .error-text {
font-size: 28rpx;
}
.retry-btn {
margin-top: 24rpx;
padding: 16rpx 48rpx;
background: #3b82f6;
color: #fff;
border-radius: 40rpx;
font-size: 28rpx;
}

View File

@@ -1,14 +1,14 @@
{
"usingComponents": {
"mode1": "./components/mode1/mode1",
"mode2": "./components/mode2/mode2"
},
"navigationBarTitleText": "提现中心",
"navigationBarBackgroundColor": "#ffffff",
"navigationBarTextStyle": "black",
"backgroundColor": "#f5f7fb",
"enablePullDownRefresh": false,
"onReachBottomDistance": 50,
"navigationStyle": "default",
"disableScroll": false
}
"usingComponents": {
"mode1": "./components/mode1/mode1",
"mode2": "./components/mode2/mode2"
},
"navigationBarTitleText": "提现",
"navigationBarBackgroundColor": "#FFD54F",
"navigationBarTextStyle": "black",
"backgroundColor": "#f5f5f5",
"enablePullDownRefresh": false,
"onReachBottomDistance": 50,
"navigationStyle": "default",
"disableScroll": false
}

View File

@@ -1,13 +1,19 @@
/* pages/withdraw/withdraw.wxss */
.tixian-container {
width: 100%;
min-height: 100vh;
background: #f5f5f5;
}
/* 加载状态 */
.loading-center, .error-center {
height: 100vh;
color: #ffffff;
background: #1a0b2e;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
color: #666;
background: #f5f5f5;
}
.loading-spinner {

View File

@@ -34,9 +34,34 @@
},
"libVersion": "3.14.3",
"packOptions": {
"ignore": [],
"ignore": [
{
"value": "_backup_20260705_pre_split",
"type": "folder"
},
{
"value": "_backup_withdraw_20260705",
"type": "folder"
},
{
"value": "_backup_pre_redesign",
"type": "folder"
},
{
"value": "_backup_20260706",
"type": "folder"
},
{
"value": "_backup_ui_20260706",
"type": "folder"
},
{
"value": ".bak",
"type": "suffix"
}
],
"include": []
},
"appid": "wx0e4be86faac4a8d1",
"appid": "wxdefa454152e78a03",
"simulatorPluginLibVersion": {}
}

View File

@@ -17,80 +17,47 @@
box-shadow: 0 10rpx 28rpx rgba(0, 0, 0, 0.09);
}
/* 平台订单 - 机甲冷色 */
/* 平台订单 */
.xym-pingtai-order {
padding-bottom: 5rpx;
background: linear-gradient(145deg, rgba(18, 28, 48, 0.98), rgba(8, 18, 35, 0.98));
border: 1rpx solid rgba(0, 200, 255, 0.12);
box-shadow: 0 20rpx 40rpx rgba(0, 0, 0, 0.55);
}
.xym-pingtai-order::before {
content: '';
position: absolute;
top: 0;
left: 10%;
width: 80%;
height: 4rpx;
background: linear-gradient(90deg, transparent, #00c8ff, transparent);
border-radius: 2rpx;
opacity: 0.75;
z-index: 2;
background: #927a46;
}
.xym-pingtai-head {
height: 72rpx;
padding: 0 24rpx;
background: transparent;
background: linear-gradient(50deg, #957c48, #5c4a28);
border-radius: 30rpx 30rpx 0 0;
border-bottom: 1rpx dashed rgba(255, 255, 255, 0.08);
}
.xym-head-time {
font-size: 24rpx;
color: #c0d0ff;
text-shadow: 0 0 5px rgba(0, 200, 255, 0.3);
color: #fcd270;
}
.xym-head-tag {
font-size: 22rpx;
padding: 4rpx 16rpx;
border-radius: 40rpx;
border-radius: 8rpx;
font-weight: 600;
background: rgba(0, 200, 255, 0.08);
color: #aac8ff;
border: 1rpx solid rgba(0, 200, 255, 0.3);
box-shadow: 0 0 10rpx rgba(0, 200, 255, 0.15);
background: rgba(252, 210, 112, 0.22);
color: #fcd270;
border: 1rpx solid rgba(252, 210, 112, 0.4);
}
.xym-pingtai-body {
border-radius: 0 0 30rpx 30rpx;
border-radius: 40rpx 10rpx 30rpx 30rpx;
padding: 0 20rpx 24rpx;
background: transparent;
background: linear-gradient(to bottom, #3a3220, #cec180);
}
/* 商家订单 - 机甲暖色 */
/* 商家订单 */
.xym-shangjia-order {
padding-bottom: 5rpx;
background: linear-gradient(145deg, rgba(38, 18, 48, 0.98), rgba(25, 8, 35, 0.98));
border: 1rpx solid rgba(255, 77, 109, 0.12);
box-shadow: 0 20rpx 40rpx rgba(0, 0, 0, 0.55);
background: linear-gradient(to bottom, #fff8e1, #ffe0b2);
overflow: hidden;
}
.xym-shangjia-order::before {
content: '';
position: absolute;
top: 0;
left: 10%;
width: 80%;
height: 4rpx;
background: linear-gradient(90deg, transparent, #ff4d6d, transparent);
border-radius: 2rpx;
opacity: 0.75;
z-index: 2;
}
.xym-shangjia-body {
border-radius: 10rpx 10rpx 30rpx 30rpx;
padding: 0 20rpx 24rpx;
@@ -101,13 +68,13 @@
}
.xym-shangjia-head .xym-head-time {
color: #ffc0d0;
color: #888;
}
.xym-shangjia-head .xym-head-tag {
background: rgba(255, 77, 109, 0.12);
color: #ffb3c6;
border-color: rgba(255, 77, 109, 0.35);
background: rgba(255, 255, 255, 0.65);
color: #492f00;
border-color: rgba(255, 208, 97, 0.5);
}
.order-con {
@@ -126,23 +93,7 @@
border-radius: 12rpx;
margin-right: 14rpx;
flex-shrink: 0;
background: rgba(255, 255, 255, 0.06);
}
.xym-pingtai-body .o-logo {
border: 2rpx solid rgba(0, 200, 255, 0.45);
box-shadow: 0 6rpx 18rpx rgba(0, 200, 255, 0.2);
}
.xym-shangjia-body .o-logo,
.gold-card .o-logo {
border: 2rpx solid rgba(255, 77, 109, 0.35);
box-shadow: 0 6rpx 18rpx rgba(255, 77, 109, 0.15);
}
.gold-card .o-logo {
border-color: rgba(255, 215, 0, 0.45);
box-shadow: 0 6rpx 18rpx rgba(255, 215, 0, 0.2);
background: #eee;
}
.o-col {
@@ -156,11 +107,11 @@
font-weight: 700;
font-size: 30rpx;
line-height: 1.5;
color: #ffb3c6;
color: #333;
}
.o-goods.light {
color: #b0c8f0;
color: #fff;
}
.line2 {
@@ -189,7 +140,7 @@
.m-name-sm {
font-size: 26rpx;
font-weight: 600;
color: #ffb3c6;
color: #333;
}
.zhiding-strip {
@@ -262,6 +213,7 @@
margin-top: 8rpx;
}
/* 金牌卡底部商家条 */
.gold-card .merchant-strip {
margin: 16rpx 6rpx 0;
padding: 16rpx 20rpx;
@@ -344,7 +296,7 @@
}
.xym-pingtai-body .zhiding-strip .zhiding-name {
color: #ffc0d0;
color: #f5e6b8;
}
.reward-badge {
@@ -357,21 +309,17 @@
display: flex;
align-items: baseline;
z-index: 3;
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.25);
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.08);
}
.reward-badge.normal-reward {
color: #ffd700;
background: rgba(0, 0, 0, 0.35);
border: 1rpx solid rgba(255, 215, 0, 0.35);
text-shadow: 0 0 12px rgba(255, 215, 0, 0.45);
color: #492f00;
background: linear-gradient(to bottom, #fae04d, #ffc0a3);
}
.reward-badge.platform-reward {
color: #fff;
background: linear-gradient(145deg, rgba(0, 200, 255, 0.25), rgba(0, 120, 200, 0.15));
border: 1rpx solid rgba(0, 200, 255, 0.35);
box-shadow: 0 0 16rpx rgba(0, 200, 255, 0.2);
background: linear-gradient(to right, #dabd83, #704029);
}
.xym-shangjia-body .reward-badge:not(.member-tip) {
@@ -379,20 +327,13 @@
}
.reward-badge.member-tip {
background: rgba(255, 77, 109, 0.15);
border: 1rpx solid rgba(255, 77, 109, 0.35);
background: rgba(255, 255, 255, 0.85);
padding: 8rpx 16rpx;
border-radius: 20rpx;
top: 16rpx;
right: 10rpx;
}
.reward-tip {
font-size: 22rpx;
color: #ff9aab;
font-weight: 600;
}
.reward-yen {
font-size: 28rpx;
}
@@ -403,7 +344,13 @@
}
.reward-num.dark {
color: #ffd700;
color: #c00;
}
.reward-tip {
font-size: 22rpx;
color: #c0392b;
font-weight: 600;
}
.reward-yen.sm {
@@ -420,15 +367,15 @@
}
.remark-block.gold {
color: #b0c8f0;
border-color: rgba(0, 200, 255, 0.45);
background: rgba(255, 255, 255, 0.03);
color: #fff;
border-color: #ffd700;
background: rgba(255, 215, 0, 0.12);
}
.remark-block.dark {
color: #e0c8ff;
border-color: rgba(255, 77, 109, 0.45);
background: rgba(255, 255, 255, 0.03);
color: #666;
border-color: #87ceeb;
background: rgba(135, 206, 235, 0.12);
}
.remark-label {
@@ -436,11 +383,11 @@
}
.remark-block.gold .remark-label {
color: #80d0ff;
color: #ffd700;
}
.remark-block.dark .remark-label {
color: #ff9aab;
color: #87ceeb;
}
.xuqiu-tags-row {
@@ -450,20 +397,16 @@
}
.xym-shangjia-body .xuqiu-tags-row {
border-top-color: rgba(255, 255, 255, 0.08);
border-top-color: rgba(0, 0, 0, 0.08);
}
.xuqiu-tags-row .xuqiu-label {
font-size: 22rpx;
color: #80d0ff;
color: #87ceeb;
margin-bottom: 8rpx;
display: block;
}
.xym-shangjia-body .xuqiu-tags-row .xuqiu-label {
color: #ff9aab;
}
.o-foot {
margin-top: 18rpx;
padding: 0 10rpx 8rpx;
@@ -475,62 +418,35 @@
}
.o-amt.light {
color: #aac8ff;
color: #f5e6b8;
}
.btn-bg {
background: linear-gradient(145deg, #1a2a48, #0e1a30);
border-radius: 0;
color: #fff;
border: 1rpx solid rgba(255, 255, 255, 0.1);
box-shadow:
0 8rpx 0 #0a1525,
0 12rpx 28rpx rgba(0, 0, 0, 0.55),
inset 0 2rpx 6rpx rgba(0, 200, 255, 0.35);
background: linear-gradient(180deg, #fae04d, #ffc0a3);
border-radius: 60rpx;
color: #492f00;
}
.qiangdan {
color: #fff;
color: #492f00;
width: 180rpx;
min-width: 100rpx;
padding: 15rpx 10rpx;
border: 2rpx solid #fff;
box-sizing: border-box;
font-size: 26rpx;
font-weight: 700;
flex-shrink: 0;
clip-path: polygon(10% 0%, 90% 0%, 100% 25%, 100% 75%, 90% 100%, 10% 100%, 0% 75%, 0% 25%);
}
.xym-shangjia-order .qiangdan.btn-bg,
.xym-shangjia-order .qiangdan {
background: linear-gradient(145deg, #3a2048, #251030);
box-shadow:
0 8rpx 0 #2a0a1a,
0 12rpx 28rpx rgba(0, 0, 0, 0.55),
inset 0 2rpx 6rpx rgba(255, 77, 109, 0.35);
}
.gold-card .qiangdan.btn-bg,
.gold-card .qiangdan {
background: linear-gradient(145deg, #3a3018, #251a08);
box-shadow:
0 8rpx 0 #1a1208,
0 12rpx 28rpx rgba(0, 0, 0, 0.55),
inset 0 2rpx 6rpx rgba(255, 215, 0, 0.35);
}
.qiangdan.btn-qiang-brown {
background: linear-gradient(145deg, #1a2a48, #0e1a30) !important;
color: #fff !important;
box-shadow:
0 8rpx 0 #0a1525,
0 12rpx 28rpx rgba(0, 0, 0, 0.55),
inset 0 2rpx 6rpx rgba(0, 200, 255, 0.35) !important;
background: linear-gradient(to right, #7a4a2d 0%, #e4ce94 100%) !important;
color: #000 !important;
}
.view-more-inline {
font-size: 22rpx;
color: #00c8ff;
color: #87ceeb;
margin-left: 4rpx;
}
@@ -547,41 +463,26 @@
padding-right: 12rpx;
}
/* 优质商家 - 机甲金牌 */
/* 优质商家金牌卡片 — 与逍遥梦 ui-preview 一致 */
.xym-order-item.gold-card {
margin-bottom: 20rpx;
border-radius: 30rpx;
box-shadow: 0 20rpx 40rpx rgba(0, 0, 0, 0.55), 0 0 24rpx rgba(255, 215, 0, 0.08);
box-shadow: 0 12rpx 32rpx rgba(248, 211, 44, 0.28);
overflow: hidden;
border: 1rpx solid rgba(255, 215, 0, 0.2);
}
.gold-card {
padding-bottom: 5rpx;
position: relative;
background: linear-gradient(145deg, rgba(28, 22, 12, 0.98), rgba(18, 12, 6, 0.98));
}
.gold-card::before {
content: '';
position: absolute;
top: 0;
left: 10%;
width: 80%;
height: 4rpx;
background: linear-gradient(90deg, transparent, #ffd700, transparent);
border-radius: 2rpx;
opacity: 0.85;
z-index: 2;
background: linear-gradient(to bottom, #ffecc5, #fffbf3);
}
.gold-head {
height: 77rpx;
display: flex;
align-items: center;
background: linear-gradient(145deg, rgba(58, 48, 24, 0.95), rgba(38, 28, 12, 0.95));
background: linear-gradient(127deg, #F8D32C 0%, #FFB26A 35%, #FFEE58 70%, #F8D32C 100%);
border-radius: 32rpx 32rpx 0 0;
border-bottom: 1rpx dashed rgba(255, 215, 0, 0.15);
}
.kehuduan-banner-wrap,
@@ -611,21 +512,19 @@
.tag-pill.tag-youzhi,
.tag-youzhi {
background: linear-gradient(145deg, rgba(255, 215, 0, 0.25), rgba(255, 140, 0, 0.15));
color: #ffd700;
background: linear-gradient(180deg, #fae04d, #ffc0a3);
color: #492c00;
font-size: 24rpx;
padding: 4rpx 18rpx;
border-radius: 10rpx;
margin-right: 10rpx;
font-weight: 600;
border: 1rpx solid rgba(255, 215, 0, 0.35);
text-shadow: 0 0 8px rgba(255, 215, 0, 0.35);
}
.gold-body-wrap {
border-radius: 0 0 30rpx 30rpx;
border-radius: 10rpx 10rpx 30rpx 30rpx;
padding: 0 20rpx 20rpx;
background: linear-gradient(to bottom, rgba(20, 16, 10, 0.98) 0%, rgba(42, 34, 22, 0.95) 55%, rgba(58, 46, 28, 0.92) 100%);
background: linear-gradient(to bottom, #1f1a14 0%, #342b22 38%, #4a3d30 68%, #6b5638 100%);
}
.gold-inner {
@@ -774,31 +673,29 @@
padding: 0 10rpx 6rpx;
}
.merchant-plain {
/* 公告条 */
.xym-gonggao-bar {
display: flex;
align-items: center;
background: #fdf9db;
margin: 0 24rpx 0;
border-radius: 10rpx;
padding: 10rpx 16rpx;
}
.merchant-user {
display: flex;
align-items: center;
.xym-gonggao-ico {
width: 40rpx;
height: 40rpx;
flex-shrink: 0;
margin-right: 12rpx;
}
.m-info {
flex: 1;
min-width: 0;
}
.dark-t {
color: #e8c547;
}
.o-amt-grey {
.xym-gonggao-txt {
font-size: 24rpx;
color: rgba(255, 255, 255, 0.65);
}
.kehuduan-foot {
display: flex;
align-items: center;
color: #666;
line-height: 1.5;
flex: 1;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}

View File

@@ -0,0 +1,119 @@
/* 打手订单 Tab - 逍遥梦 order 页布局增强 */
@import './xym-layout.wxss';
.ds-page.xym-order-page {
background: #f5f5f5;
min-height: 100vh;
display: flex;
flex-direction: column;
}
.xym-order-page .xym-order-header {
position: relative;
flex-shrink: 0;
padding-bottom: 8rpx;
}
.xym-order-page .xym-order-bg {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 200rpx;
z-index: 0;
}
.xym-order-page .xym-order-title-bar {
position: relative;
z-index: 2;
text-align: center;
padding: 16rpx 0 8rpx;
}
.xym-order-page .xym-order-title {
font-size: 34rpx;
font-weight: 700;
color: #343434;
}
.xym-order-page .main-container {
flex: 1;
min-height: 0;
}
.xym-order-page .order-card-xym {
margin: 0 0 16rpx;
padding: 20rpx;
border-radius: 16rpx;
background: #fff;
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.05);
display: flex;
align-items: flex-start;
}
.xym-order-page .card-hd-xym {
width: 100%;
display: flex;
justify-content: space-between;
margin-bottom: 12rpx;
}
.xym-order-page .card-time-xym {
font-size: 22rpx;
color: #999;
}
.xym-order-page .card-status-xym {
font-size: 24rpx;
font-weight: 600;
}
.xym-order-page .card-bd-xym {
display: flex;
width: 100%;
}
.xym-order-page .goods-img-xym {
width: 120rpx;
height: 120rpx;
border-radius: 12rpx;
flex-shrink: 0;
background: #f0f0f0;
}
.xym-order-page .goods-info-xym {
flex: 1;
margin-left: 16rpx;
min-width: 0;
}
.xym-order-page .goods-name-xym {
font-size: 28rpx;
font-weight: 600;
color: #222;
line-height: 1.4;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
}
.xym-order-page .goods-sub-xym {
font-size: 24rpx;
color: #666;
margin-top: 8rpx;
}
.xym-order-page .goods-price-xym {
font-size: 30rpx;
font-weight: 700;
color: #492f00;
margin-top: 8rpx;
}
.xym-order-page .load-tip-xym {
text-align: center;
color: #999;
font-size: 24rpx;
padding: 20rpx 0 40rpx;
}

View File

@@ -13,8 +13,8 @@
}
.leixing-item.leixing-active {
background: linear-gradient(180deg, #ede9fe, #c4b5fd) !important;
box-shadow: 0 4rpx 12rpx rgba(147, 51, 234, 0.35) !important;
background: linear-gradient(180deg, #fff0c2, #f5d563) !important;
box-shadow: 0 4rpx 12rpx rgba(255, 208, 97, 0.35) !important;
}
.leixing-active .leixing-name {
@@ -32,14 +32,14 @@
}
.type-btn.type-active {
background: linear-gradient(180deg, #c4b5fd, #a78bfa) !important;
background: linear-gradient(180deg, #fae04d, #ffc0a3) !important;
color: #492f00 !important;
box-shadow: 0 2rpx 8rpx rgba(180, 130, 20, 0.2) !important;
}
.search-box {
background: #fff !important;
border: 1rpx solid rgba(147, 51, 234, 0.3) !important;
border: 1rpx solid rgba(255, 208, 97, 0.3) !important;
}
.left-status {
@@ -48,7 +48,7 @@
}
.status-item.status-active {
background: #f5f3ff !important;
background: #fff8e1 !important;
}
.status-active .status-name {
@@ -56,7 +56,7 @@
}
.status-dot {
background: #9333ea !important;
background: #ffd061 !important;
}
.right-list {
@@ -74,11 +74,11 @@
.loading-spinner,
.mini-spinner {
border-top-color: #9333ea !important;
border-top-color: #ffd061 !important;
}
.load-more-btn {
background: linear-gradient(180deg, #c4b5fd, #a78bfa) !important;
background: linear-gradient(180deg, #fae04d, #ffc0a3) !important;
color: #492f00 !important;
border: 2rpx solid #fff !important;
}

View File

@@ -24,13 +24,13 @@ page {
.role-chip {
background: rgba(255, 255, 255, 0.8) !important;
color: #666 !important;
border: 2rpx solid rgba(147, 51, 234, 0.25) !important;
border: 2rpx solid rgba(255, 208, 97, 0.25) !important;
}
.role-chip.on {
background: linear-gradient(180deg, #c4b5fd, #a78bfa) !important;
background: linear-gradient(180deg, #fae04d, #ffc0a3) !important;
color: #492f00 !important;
border-color: #9333ea !important;
border-color: #ffd061 !important;
font-weight: 700 !important;
}
@@ -40,7 +40,7 @@ page {
}
.date-chip.on {
background: #ede9fe !important;
background: #fef6d4 !important;
color: #492f00 !important;
font-weight: 700 !important;
}
@@ -76,7 +76,7 @@ page {
}
.my-rank-bar {
background: linear-gradient(180deg, #c4b5fd, #a78bfa) !important;
background: linear-gradient(180deg, #fae04d, #ffc0a3) !important;
}
.my-rank-bar text {
@@ -88,5 +88,5 @@ page {
}
.loader {
border-top-color: #9333ea !important;
border-top-color: #ffd061 !important;
}

View File

@@ -1,7 +1,7 @@
/* 打手充值页 - 逍遥梦风格视觉覆盖(不改 wxml/逻辑) */
.page-container {
background: linear-gradient(180deg, #c4b5fd 0%, #fff 22%, #f5f3ff 100%) !important;
background: linear-gradient(180deg, #f7dc51 0%, #fff 22%, #fff8e1 100%) !important;
}
.page-container::before {
@@ -19,18 +19,18 @@
.dec-line,
.dec-diamond {
background: #9333ea !important;
background: #ffd061 !important;
}
.vip-card {
background: #fdfcfa !important;
border: 2rpx solid rgba(147, 51, 234, 0.5) !important;
border: 2rpx solid rgba(255, 208, 97, 0.5) !important;
box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.08) !important;
}
.vip-card.active {
border-color: #9333ea !important;
box-shadow: 0 8rpx 28rpx rgba(147, 51, 234, 0.35) !important;
border-color: #ffd061 !important;
box-shadow: 0 8rpx 28rpx rgba(255, 208, 97, 0.35) !important;
}
.card-frame,
@@ -69,7 +69,7 @@
.tech-buy-btn,
.tech-btn,
.modal-btn.confirm-btn {
background: linear-gradient(180deg, #c4b5fd, #a78bfa) !important;
background: linear-gradient(180deg, #fae04d, #ffc0a3) !important;
border: 2rpx solid #fff !important;
border-radius: 44rpx !important;
box-shadow: 0 4rpx 12rpx rgba(180, 130, 20, 0.25) !important;
@@ -122,8 +122,8 @@
.huiyuan-tag,
.tech-tag {
background: #ede9fe !important;
border: 1rpx solid rgba(147, 51, 234, 0.4) !important;
background: #fef6d4 !important;
border: 1rpx solid rgba(255, 208, 97, 0.4) !important;
}
.tag-name {
@@ -135,7 +135,7 @@
}
.tech-line {
background: linear-gradient(90deg, transparent, #9333ea, transparent) !important;
background: linear-gradient(90deg, transparent, #ffd061, transparent) !important;
}
.tech-modal .modal-container {
@@ -168,13 +168,13 @@
}
.quick-btn {
background: #ede9fe !important;
border: 2rpx solid rgba(147, 51, 234, 0.4) !important;
background: #fef6d4 !important;
border: 2rpx solid rgba(255, 208, 97, 0.4) !important;
}
.quick-btn.active {
background: linear-gradient(180deg, #c4b5fd, #a78bfa) !important;
border-color: #9333ea !important;
background: linear-gradient(180deg, #fae04d, #ffc0a3) !important;
border-color: #ffd061 !important;
}
.quick-text {
@@ -182,7 +182,7 @@
}
.pay-method-item {
background: #ede9fe !important;
background: #fef6d4 !important;
border-radius: 16rpx !important;
}
@@ -204,8 +204,8 @@
}
.spinner-ring {
border-color: rgba(147, 51, 234, 0.3) !important;
border-top-color: #9333ea !important;
border-color: rgba(255, 208, 97, 0.3) !important;
border-top-color: #ffd061 !important;
}
.tech-footer .footer-text {

View File

@@ -1,13 +1,13 @@
/* 打手端抢单页 - 机甲风格辅助样式(不改 wxml / 逻辑 */
/* 打手端抢单页 - 逍遥梦风格视觉覆盖(不改 wxml 结构/class */
.xym-lunbo-container {
margin: 8rpx 24rpx 10rpx;
border-radius: 20rpx;
overflow: hidden;
flex-shrink: 0;
box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.45);
border: 2rpx solid rgba(0, 200, 255, 0.25);
background: rgba(18, 22, 38, 0.85);
box-shadow: 0 6rpx 18rpx rgba(0, 0, 0, 0.08);
border: 2rpx solid rgba(255, 255, 255, 0.7);
background: #fff;
}
.xym-section-gap {
@@ -15,34 +15,6 @@
flex-shrink: 0;
}
.xym-gonggao-bar {
display: flex;
align-items: center;
background: rgba(18, 22, 38, 0.88);
margin: 0 24rpx 8rpx;
border-radius: 12rpx;
padding: 10rpx 16rpx;
border: 1rpx solid rgba(0, 200, 255, 0.22);
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.35);
}
.xym-gonggao-ico {
width: 40rpx;
height: 40rpx;
flex-shrink: 0;
margin-right: 12rpx;
}
.xym-gonggao-txt {
font-size: 24rpx;
color: #b0c8f0;
line-height: 1.5;
flex: 1;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.xym-lunbo-swiper {
height: 300rpx;
border-radius: 20rpx;
@@ -54,56 +26,331 @@
border-radius: 20rpx;
}
.qiangdan-page {
background: linear-gradient(180deg, #f7dc51 0%, #fff 28%, #fff8e1 100%) !important;
}
.qiangdan-page::before {
display: none !important;
}
.leixing-quyu {
background: #fff !important;
border-bottom: none !important;
box-shadow: 0 4rpx 14rpx rgba(0, 0, 0, 0.06) !important;
margin: 6rpx 20rpx 8rpx !important;
border-radius: 28rpx !important;
padding: 14rpx 0 8rpx !important;
border: 2rpx solid rgba(255, 224, 130, 0.5) !important;
}
.leixing-scroll {
height: 132rpx !important;
}
.leixing-item {
width: 120rpx !important;
}
.leixing-tupian {
width: 88rpx !important;
height: 88rpx !important;
border-radius: 20rpx !important;
border: none !important;
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.08) !important;
}
.leixing-active .leixing-tupian {
border: 3rpx solid #ffd061 !important;
box-shadow: 0 6rpx 16rpx rgba(255, 208, 97, 0.45) !important;
}
.leixing-jieshao {
margin-top: 8rpx !important;
font-size: 22rpx !important;
color: #666 !important;
text-shadow: none !important;
}
.leixing-active .leixing-jieshao {
color: #492f00 !important;
font-weight: 700 !important;
}
.guangyun-effect {
background: radial-gradient(circle, rgba(255, 208, 97, 0.35) 0%, transparent 70%) !important;
}
.biaoqian-quyu {
background: transparent !important;
padding: 8rpx 20rpx 0 !important;
}
.biaoqian-item {
background: rgba(255, 255, 255, 0.65) !important;
border: 2rpx solid rgba(201, 162, 39, 0.25) !important;
}
.biaoqian-active {
background: linear-gradient(180deg, #fff0c2, #f5d563) !important;
border-color: rgba(180, 130, 20, 0.85) !important;
}
.fenge-xian {
background: linear-gradient(90deg, transparent, #ffd061, transparent) !important;
opacity: 0.6 !important;
margin: 6rpx 30rpx 0 !important;
}
.dingdan-list {
padding: 16rpx 20rpx 0 !important;
margin-top: 8rpx !important;
}
.refreshing-text,
.pull-down-text {
color: #6a9cff !important;
text-shadow: 0 0 8px rgba(0, 200, 255, 0.35) !important;
color: #6b5420 !important;
text-shadow: none !important;
}
.tip-text {
color: #8a9ac0 !important;
color: #999 !important;
}
.tip-icon {
filter: drop-shadow(0 0 16px rgba(0, 200, 255, 0.25)) !important;
opacity: 0.65 !important;
filter: none !important;
}
.dingdan-card {
border-radius: 28rpx !important;
box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.08) !important;
border: none !important;
backdrop-filter: none !important;
}
.pingtai-card {
background: linear-gradient(to bottom, #927a46, #cec180) !important;
padding: 0 0 16rpx !important;
}
.pingtai-card::before,
.shangjia-card::before {
display: none !important;
}
.pingtai-card .card-top,
.shangjia-card .card-top {
background: linear-gradient(50deg, #957c48, #5c4a28) !important;
border-radius: 28rpx 28rpx 0 0 !important;
margin: -28rpx -24rpx 16rpx !important;
padding: 16rpx 24rpx !important;
}
.pingtai-tag,
.creat-time {
color: #fcd270 !important;
}
.shangjia-card {
background: linear-gradient(to bottom, #fff8e1, #ffe0b2) !important;
}
.card-content,
.jieshao-box,
.beizhu-box,
.shangjia-jieshao,
.shangjia-beizhu {
background: rgba(255, 255, 255, 0.55) !important;
border-radius: 12rpx !important;
}
.jieshao-label,
.beizhu-label,
.xuqiu-label {
color: #87ceeb !important;
}
.jieshao-text,
.beizhu-text {
color: #333 !important;
}
.fenyong-box {
background: linear-gradient(to bottom, #fae04d, #ffc0a3) !important;
border-radius: 30rpx !important;
}
.fenyong-text,
.fenyong-price,
.fenyong-unit {
color: #492f00 !important;
}
.qiangdan-btn,
.mecha-btn {
background: linear-gradient(180deg, #fae04d, #ffc0a3) !important;
border: 2rpx solid #fff !important;
box-shadow: 0 4rpx 12rpx rgba(180, 130, 20, 0.25) !important;
}
.qiangdan-btn .btn-text,
.mecha-btn .btn-text {
color: #492f00 !important;
}
.btn-shine,
.btn-glow,
.mecha-overlay {
display: none !important;
}
.loading-mask {
background: rgba(5, 8, 18, 0.92) !important;
background: rgba(255, 248, 225, 0.85) !important;
}
.loading-mask-text,
.loading-text,
.no-more-text {
color: #6a9cff !important;
color: #999 !important;
}
.unauthorized-container {
background: radial-gradient(ellipse at top, #1a1f30, #0b0f1a) !important;
background: linear-gradient(180deg, #f7dc51, #fff 50%) !important;
}
.unauthorized-card {
background: rgba(18, 28, 48, 0.95) !important;
border: 1rpx solid rgba(0, 200, 255, 0.2) !important;
box-shadow: 0 12rpx 40rpx rgba(0, 0, 0, 0.55) !important;
background: #fdfcfa !important;
border: none !important;
box-shadow: 0 8rpx 32rpx rgba(0, 0, 0, 0.08) !important;
}
.unauthorized-card .title {
color: #c0d0ff !important;
color: #343434 !important;
}
.unauthorized-card .message,
.unauthorized-card .description {
color: #8a9ac0 !important;
color: #666 !important;
}
.btn-register {
background: linear-gradient(145deg, #1a2a48, #0e1a30) !important;
border: 1rpx solid rgba(0, 200, 255, 0.35) !important;
background: linear-gradient(180deg, #fae04d, #ffc0a3) !important;
border-radius: 44rpx !important;
}
.btn-register .btn-text {
color: #fff !important;
color: #492f00 !important;
}
.card-glow {
display: none !important;
}
.order-type-tag {
font-size: 22rpx;
padding: 6rpx 16rpx;
border-radius: 8rpx;
font-weight: 600;
line-height: 1.4;
}
.tag-platform {
background: rgba(252, 210, 112, 0.22);
color: #fcd270;
border: 1rpx solid rgba(252, 210, 112, 0.45);
}
.tag-merchant {
background: rgba(255, 255, 255, 0.45);
color: #492f00;
border: 1rpx solid rgba(255, 208, 97, 0.55);
}
.fenyong-mark {
width: 36rpx;
height: 36rpx;
line-height: 36rpx;
text-align: center;
font-size: 22rpx;
font-weight: 700;
color: #492f00;
background: rgba(255, 255, 255, 0.72);
border-radius: 50%;
margin-right: 8rpx;
flex-shrink: 0;
}
.fenyong-icon {
display: none !important;
}
.qiangdan-btn {
min-width: 180rpx !important;
height: 68rpx !important;
border-radius: 34rpx !important;
}
.qiangdan-btn .btn-text {
font-size: 28rpx !important;
font-weight: 700 !important;
letter-spacing: 1rpx;
}
/* 手动刷新悬浮钮(抢单池 / 接单页) */
.refresh-float {
position: fixed;
right: 24rpx;
top: calc(env(safe-area-inset-top) + 88rpx);
z-index: 20;
width: 64rpx;
height: 64rpx;
background: rgba(255, 255, 255, 0.92);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 6rpx 16rpx rgba(0, 0, 0, 0.12);
border: 2rpx solid rgba(255, 208, 97, 0.45);
}
.refresh-float:active {
transform: scale(0.96);
}
.refresh-float-ico {
width: 34rpx;
height: 34rpx;
}
.dingdanxiang1.filter-card {
margin: 12rpx 20rpx 8rpx !important;
border-radius: 24rpx !important;
background: rgba(255, 255, 255, 0.95) !important;
box-shadow: 0 6rpx 18rpx rgba(0, 0, 0, 0.06) !important;
border: 2rpx solid rgba(255, 224, 130, 0.45) !important;
}
.xym-gonggao-bar {
margin: 8rpx 20rpx 0;
padding: 12rpx 16rpx;
border-radius: 12rpx;
background: rgba(255, 255, 255, 0.9);
display: flex;
align-items: center;
}
.xym-gonggao-ico {
width: 32rpx;
height: 32rpx;
margin-right: 12rpx;
flex-shrink: 0;
}
.xym-gonggao-txt {
font-size: 24rpx;
color: #492f00;
flex: 1;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}

292
styles/dashou-xym-user.wxss Normal file
View File

@@ -0,0 +1,292 @@
/* 打手「我的」页 - 逍遥梦 user 页视觉(仅样式) */
@import './xym-layout.wxss';
.shadow {
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.06);
}
.user-page.xym-user {
background: linear-gradient(180deg, #f7dc51 0%, #fff 28%, #fff8e1 100%);
}
.user-page.xym-user .bg-img {
display: none;
}
.user-page.xym-user .wallet-card {
margin: 0 30rpx;
padding: 20rpx;
border-radius: 26rpx;
background: #fef6d4;
}
.user-page.xym-user .w-label {
color: #666;
font-size: 26rpx;
}
.user-page.xym-user .w-num {
font-size: 44rpx;
font-weight: 700;
color: #222;
margin-top: 10rpx;
}
.user-page.xym-user .w-sub {
color: #666;
font-size: 26rpx;
margin-top: 8rpx;
}
.user-page.xym-user .btn-outline {
padding: 10rpx 24rpx;
font-size: 26rpx;
font-weight: 700;
border: 2rpx solid #fff;
border-radius: 60rpx;
background: linear-gradient(180deg, #fae04d, #ffc0a3);
color: #492f00;
white-space: nowrap;
margin-left: 12rpx;
}
.user-page.xym-user .banner-row {
margin: 20rpx 24rpx 0;
align-items: flex-start;
}
.user-page.xym-user .banner-img {
width: 48%;
height: 150rpx;
border-radius: 16rpx;
overflow: hidden;
background: #eee;
display: block;
}
.user-page.xym-user .banner-row .banner-img:first-child {
margin-right: 2%;
}
.user-page.xym-user .qiepian-wrap {
margin: 20rpx 24rpx 0;
border-radius: 16rpx;
overflow: hidden;
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.08);
}
.user-page.xym-user .qiepian-banner {
width: 100%;
display: block;
min-height: 120rpx;
}
.user-page.xym-user .tip-bar {
margin: 22rpx 30rpx 0;
padding: 20rpx;
border-radius: 20rpx;
background: #ffedee;
color: #ff4c45;
font-size: 26rpx;
}
.user-page.xym-user .tip-ico {
width: 28rpx;
height: 28rpx;
margin-right: 12rpx;
}
.user-page.xym-user .tip-arrow {
color: #ff4c45;
font-size: 36rpx;
}
.user-page.xym-user .my-box {
border-radius: 20rpx;
margin: 20rpx;
padding-bottom: 10rpx;
background: #fdfcfa;
}
.user-page.xym-user .panel-title {
padding: 35rpx 35rpx 0;
font-weight: 700;
}
.user-page.xym-user .lg {
font-size: 32rpx;
font-weight: 700;
color: #222;
}
.user-page.xym-user .muted {
color: #999;
font-size: 28rpx;
}
.user-page.xym-user .sm {
font-size: 24rpx;
color: #666;
}
.user-page.xym-user .order-nav {
padding: 26rpx 0 10rpx;
display: flex;
align-items: center;
justify-content: space-around;
}
.user-page.xym-user .nav-item {
width: 25%;
display: flex;
flex-direction: column;
align-items: center;
}
.user-page.xym-user .icon-wrap {
position: relative;
display: flex;
justify-content: center;
}
.user-page.xym-user .nav-badge {
position: absolute;
top: -8rpx;
right: 8rpx;
min-width: 32rpx;
height: 32rpx;
line-height: 32rpx;
text-align: center;
font-size: 20rpx;
background: #ff4c45;
color: #fff;
border-radius: 16rpx;
z-index: 1;
padding: 0 6rpx;
}
.user-page.xym-user .nav-icon {
width: 62rpx;
height: 62rpx;
margin-bottom: 10rpx;
}
.user-page.xym-user .section-hd {
font-weight: 700;
font-size: 32rpx;
padding: 30rpx 20rpx 0;
color: #222;
}
.user-page.xym-user .trade-list {
flex-wrap: wrap;
padding: 20rpx 10rpx;
display: flex;
align-items: center;
justify-content: flex-start;
}
.user-page.xym-user .trade-item {
width: 20%;
padding: 12rpx 0;
display: flex;
flex-direction: column;
align-items: center;
}
.user-page.xym-user .trade-icon {
width: 50rpx;
height: 50rpx;
margin-bottom: 10rpx;
}
.user-page.xym-user .invite-row {
padding: 20rpx 10rpx 30rpx;
display: flex;
align-items: center;
justify-content: space-around;
}
.user-page.xym-user .invite-item {
width: 33.33%;
padding: 10rpx 0;
display: flex;
flex-direction: column;
align-items: center;
}
.user-page.xym-user .invite-icon {
width: 50rpx;
height: 50rpx;
margin-bottom: 8rpx;
}
.user-page.xym-user .func-list {
display: flex;
flex-wrap: wrap;
padding: 10rpx 0;
}
.user-page.xym-user .func-item-xym {
width: 25%;
padding: 16rpx 0;
display: flex;
flex-direction: column;
align-items: center;
}
.user-page.xym-user .func-icon-wrap {
width: 88rpx;
height: 88rpx;
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 8rpx;
}
.user-page.xym-user .func-icon-xym {
width: 48rpx;
height: 48rpx;
}
.user-page.xym-user .func-txt-xym {
font-size: 24rpx;
color: #666;
text-align: center;
}
.user-page.xym-user .follow-kuaishou {
position: fixed;
right: 0;
bottom: calc(280rpx + env(safe-area-inset-bottom));
z-index: 99;
display: flex;
align-items: center;
background: rgba(255, 255, 255, 0.95);
border-radius: 40rpx 0 0 40rpx;
padding: 12rpx 16rpx 12rpx 20rpx;
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.08);
}
.user-page.xym-user .follow-kuaishou.expanded {
padding-right: 24rpx;
}
.user-page.xym-user .ks-icon {
width: 48rpx;
height: 48rpx;
}
.user-page.xym-user .ks-text {
font-size: 24rpx;
color: #333;
margin-left: 10rpx;
white-space: nowrap;
}
.user-page.xym-user .load-tip {
text-align: center;
color: #999;
font-size: 24rpx;
padding: 24rpx 0 40rpx;
}

View File

@@ -5,7 +5,7 @@
margin-bottom: 24rpx;
border-radius: 30rpx;
position: relative;
background: linear-gradient(to bottom, #f5f3ff, #ddd6fe);
background: linear-gradient(to bottom, #fff8e1, #ffe0b2);
box-sizing: border-box;
overflow: hidden;
box-shadow: 0 12rpx 32rpx rgba(0, 0, 0, 0.12);

View File

@@ -10,7 +10,7 @@
min-height: 100vh;
display: flex;
flex-direction: column;
background: linear-gradient(180deg, #c4b5fd 0%, #fff 28%, #f5f3ff 100%);
background: linear-gradient(180deg, #f7dc51 0%, #fff 28%, #fff8e1 100%);
box-sizing: border-box;
overflow: hidden;
}
@@ -49,13 +49,13 @@
font-weight: 700;
border: 2rpx solid #fff;
border-radius: 60rpx;
background: linear-gradient(180deg, #c4b5fd, #a78bfa);
background: linear-gradient(180deg, #fae04d, #ffc0a3);
color: #492f00;
white-space: nowrap;
}
.sj-btn-bg {
background: linear-gradient(180deg, #c4b5fd, #a78bfa);
background: linear-gradient(180deg, #fae04d, #ffc0a3);
border-radius: 60rpx;
color: #492f00;
font-weight: 700;
@@ -66,7 +66,7 @@
font-size: 20rpx;
padding: 4rpx 12rpx;
border-radius: 8rpx;
background: #8b5cf6;
background: #ffb74d;
color: #fff;
}
@@ -74,7 +74,7 @@
margin: 0 30rpx;
padding: 24rpx 20rpx;
border-radius: 26rpx;
background: #ede9fe;
background: #fef6d4;
}
.sj-w-label {
@@ -129,11 +129,11 @@
}
.sj-fadan-btn--regular {
background: linear-gradient(135deg, #f5f3ff, #ddd6fe);
background: linear-gradient(135deg, #fff8e1, #ffe0b2);
}
.sj-fadan-btn--custom {
background: linear-gradient(135deg, #ede9fe, #c4b5fd);
background: linear-gradient(135deg, #fef6d4, #ffd061);
}
.sj-fadan-title {
@@ -219,7 +219,7 @@
text-align: center;
padding: 16rpx 8rpx;
border-radius: 12rpx;
background: linear-gradient(180deg, #f5f3ff, #ede9fe);
background: linear-gradient(180deg, #fff8e1, #fef6d4);
font-size: 24rpx;
color: #492f00;
font-weight: 600;

View File

@@ -7,11 +7,11 @@
padding: 24rpx;
padding-bottom: 160rpx;
box-sizing: border-box;
background: linear-gradient(180deg, #c4b5fd 0%, #f5f5f5 18%, #f5f5f5 100%);
background: linear-gradient(180deg, #f7dc51 0%, #fff8e1 18%, #fff8e1 100%);
}
.sj-form-theme .balance-card {
background: #ede9fe !important;
background: #fef6d4 !important;
border-radius: 26rpx !important;
padding: 28rpx 24rpx !important;
margin-bottom: 20rpx !important;
@@ -76,7 +76,7 @@
}
.sj-form-theme .card-dot {
background: #9333ea !important;
background: #ffd061 !important;
}
.sj-form-theme .card-title,
@@ -108,12 +108,12 @@
.sj-form-theme .type-chip--active,
.sj-form-theme .type-active {
background: linear-gradient(180deg, #c4b5fd, #a78bfa) !important;
background: linear-gradient(180deg, #fae04d, #ffc0a3) !important;
color: #492f00 !important;
font-weight: 700 !important;
border: none !important;
transform: none !important;
box-shadow: 0 4rpx 12rpx rgba(147, 51, 234, 0.35) !important;
box-shadow: 0 4rpx 12rpx rgba(255, 208, 97, 0.45) !important;
}
.sj-form-theme .type-text {
@@ -161,11 +161,11 @@
}
.sj-form-theme .submit-btn {
background: linear-gradient(180deg, #c4b5fd, #a78bfa) !important;
background: linear-gradient(180deg, #fae04d, #ffc0a3) !important;
color: #492f00 !important;
border-radius: 44rpx !important;
font-weight: 700 !important;
box-shadow: 0 6rpx 16rpx rgba(147, 51, 234, 0.35) !important;
box-shadow: 0 6rpx 16rpx rgba(255, 208, 97, 0.45) !important;
}
.sj-form-theme .submit-bar {
@@ -174,7 +174,7 @@
}
.sj-form-theme switch {
color: #9333ea !important;
color: #ffd061 !important;
}
.sj-form-theme .search-section {
@@ -197,7 +197,7 @@
}
.sj-form-theme .search-btn {
background: linear-gradient(180deg, #c4b5fd, #a78bfa) !important;
background: linear-gradient(180deg, #fae04d, #ffc0a3) !important;
box-shadow: none !important;
}
@@ -233,7 +233,7 @@
.sj-form-theme .generate-grid-btn,
.sj-form-theme .copy-grid-btn,
.sj-form-theme .action-grid-btn {
background: linear-gradient(180deg, #c4b5fd, #a78bfa) !important;
background: linear-gradient(180deg, #fae04d, #ffc0a3) !important;
color: #492f00 !important;
border: 2rpx solid #fff !important;
box-shadow: none !important;
@@ -250,7 +250,7 @@
}
.sj-form-theme .tutorial-btn {
background: linear-gradient(180deg, #c4b5fd, #a78bfa) !important;
background: linear-gradient(180deg, #fae04d, #ffc0a3) !important;
color: #492f00 !important;
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1) !important;
}

5
styles/xym-layout.wxss Normal file
View File

@@ -0,0 +1,5 @@
/* 逍遥梦布局工具类 */
.flex { display: flex; align-items: center; }
.flexb { display: flex; align-items: center; justify-content: space-between; }
.flexa { display: flex; align-items: center; justify-content: space-around; }
.flexmc { display: flex; flex-direction: column; align-items: center; justify-content: center; }

View File

@@ -0,0 +1,171 @@
/* 会员/保证金充值页共用弹窗与 loading */
.modal-mask {
position: fixed;
inset: 0;
background: rgba(0, 0, 0, 0.45);
z-index: 1000;
display: flex;
align-items: flex-end;
justify-content: center;
}
.modal-panel {
width: 100%;
background: #fff;
border-radius: 32rpx 32rpx 0 0;
padding: 32rpx 28rpx calc(24rpx + env(safe-area-inset-bottom));
}
.modal-title {
display: block;
font-size: 34rpx;
font-weight: 700;
text-align: center;
margin-bottom: 8rpx;
}
.modal-sub {
display: block;
text-align: center;
font-size: 24rpx;
color: #999;
margin-bottom: 24rpx;
}
.amount-input-wrap {
display: flex;
align-items: center;
border-bottom: 2rpx solid #f0e6d8;
padding-bottom: 12rpx;
margin-bottom: 20rpx;
}
.amount-prefix {
font-size: 40rpx;
font-weight: 700;
color: #492f00;
margin-right: 8rpx;
}
.amount-input {
flex: 1;
font-size: 36rpx;
}
.quick-row {
display: flex;
flex-wrap: wrap;
gap: 16rpx;
margin-bottom: 24rpx;
}
.quick-chip {
padding: 12rpx 24rpx;
border-radius: 999rpx;
background: #f5f5f5;
font-size: 26rpx;
color: #666;
}
.quick-chip.active {
background: #fff3cd;
color: #492f00;
font-weight: 600;
}
.modal-actions {
display: flex;
gap: 20rpx;
}
.modal-btn {
flex: 1;
height: 88rpx;
border-radius: 44rpx;
display: flex;
align-items: center;
justify-content: center;
font-size: 30rpx;
}
.modal-btn.cancel {
background: #f5f5f5;
color: #666;
}
.modal-btn.confirm {
background: linear-gradient(90deg, #fae04d, #ffc0a3);
color: #492f00;
font-weight: 700;
}
.pay-method-item {
padding: 28rpx 20rpx;
border-bottom: 1rpx solid #f0f0f0;
}
.pay-method-name {
display: block;
font-size: 30rpx;
font-weight: 600;
}
.pay-method-desc {
display: block;
font-size: 24rpx;
color: #999;
margin-top: 6rpx;
}
.balance-item {
display: flex;
justify-content: space-between;
padding: 24rpx 12rpx;
border-bottom: 1rpx solid #f5f5f5;
font-size: 28rpx;
}
.balance-need {
color: #e6a23c;
font-weight: 600;
}
.confirm-row {
display: flex;
justify-content: space-between;
padding: 16rpx 0;
font-size: 28rpx;
}
.loading-mask {
position: fixed;
inset: 0;
background: rgba(0, 0, 0, 0.35);
z-index: 2000;
display: flex;
align-items: center;
justify-content: center;
}
.loading-box {
background: #fff;
border-radius: 20rpx;
padding: 40rpx 48rpx;
display: flex;
flex-direction: column;
align-items: center;
gap: 16rpx;
}
.loading-spinner {
width: 56rpx;
height: 56rpx;
border: 4rpx solid #f0e6d8;
border-top-color: #f5a623;
border-radius: 50%;
animation: spin 0.8s linear infinite;
}
@keyframes spin {
to { transform: rotate(360deg); }
}

Some files were not shown because too many files have changed in this diff Show More