From bf02992ab22f5e5453fdfc177c718790bb773f3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B5=B5=E5=BF=A0=E6=9E=97?= <170083662@qq.com> Date: Wed, 24 Jun 2026 14:04:24 +0800 Subject: [PATCH] =?UTF-8?q?feat(user-withdraw):=20=E9=87=8D=E5=86=99?= =?UTF-8?q?=E6=8F=90=E7=8E=B0=E9=A1=B5=E9=9D=A2=E8=A7=84=E5=88=99=E5=B1=95?= =?UTF-8?q?=E7=A4=BA=E5=B9=B6=E4=BC=98=E5=8C=96=E7=94=A8=E6=88=B7=E4=BD=93?= =?UTF-8?q?=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 修复 API 返回码判断,兼容 code 为 0 的情况,增强接口健壮性 - 设计提现页面四层结构:余额卡片、提现输入区、规则区域和底部按钮 - 规则区域采用红色标题栏及两列网格显示七项参数,并列出七条详细规则,全部有默认 fallback,确保无后端时规则完整展示 - 优化提现金额输入提示,支持全部提现功能,显示手续费信息及优惠状态 - 调整样式细节,改用 #f5f6fa 背景色,卡片圆角加大,字体及布局更美观清晰 - 修正首页 tabBar 页面列表,去除积分页,避免入口冲突 - 修改用户中心积分入口为页面跳转,增强导航逻辑一致性 - 更新钱包页面快捷操作按钮,统一使用页面跳转,优化用户交互体验 --- .workbuddy/memory/2026-06-23.md | 37 +++++ src/pages/index/index.tsx | 2 +- src/pages/user/index.tsx | 2 +- src/pages/user/wallet.tsx | 10 +- src/pages/user/withdraw/index.scss | 253 +++++++++++++++++++---------- src/pages/user/withdraw/index.tsx | 238 ++++++++++++++++----------- 6 files changed, 351 insertions(+), 191 deletions(-) diff --git a/.workbuddy/memory/2026-06-23.md b/.workbuddy/memory/2026-06-23.md index 6a0c015..f7d84fa 100644 --- a/.workbuddy/memory/2026-06-23.md +++ b/.workbuddy/memory/2026-06-23.md @@ -45,3 +45,40 @@ 6. **装饰圆形** — 增加第三个装饰圆,调整大小和位置 构建编译通过 ✓ + +## 积分商城从 paopao-taro 复制到当前项目 + +### 源项目 +`/Users/gxwebsoft/VUE/paopao-taro` + +### 复制的文件 +**页面文件(覆盖):** +- `src/pages/points/` 整个目录(index.tsx、signin.tsx、product-detail.tsx、product-list/、exchange/、points-rules/、order-list/) +- `src/pages/user/points-record.tsx` + +**API 文件(覆盖):** +- `src/api/shop/shopPointsProduct/` — 积分商品接口 +- `src/api/shop/shopPointsOrder/` — 积分订单接口 +- `src/api/shop/shopSigninRecord/` — 签到记录接口 +- `src/api/shop/shopSigninConfig/` — 签到配置接口 +- `src/api/system/user/points/` — 用户积分信息接口 + +构建编译通过 ✓ + +## 提现页面规则展示重写(第三轮审核修复) + +### 审核失败原因(同前两次) +提现页面需清晰展示提现规则:可提现额度、每日提现次数、提现时间、到账时间等 + +### 根本问题 +1. API 返回码仅判断 `code === 200`,可能实际返回 `0` +2. 规则过度依赖 API,审核环境无后端时显示不完整 + +### 重写内容(index.tsx + index.scss 全面重写) +**4层结构:** +1. **余额卡片** — 橙色渐变,大字号展示可提现余额 +2. **提现输入区** — 输入框 + 全部提现 + 手续费提示 +3. **规则区域(核心)** — 红色标题栏 + 2列网格(7项参数) + 7条详细文字规则,全部有 fallback 默认值,**不依赖 API 即可完整展示** +4. **底部按钮** — 确认按钮 + "提交即表示同意"声明 + +构建编译通过 ✓ diff --git a/src/pages/index/index.tsx b/src/pages/index/index.tsx index 506b86c..014c8cb 100644 --- a/src/pages/index/index.tsx +++ b/src/pages/index/index.tsx @@ -85,7 +85,7 @@ const IndexPage: React.FC = () => { } // tabBar 页面列表 - const tabBarPages = ['/pages/index/index', '/pages/shop/index', '/pages/points/index', '/pages/user/user'] + const tabBarPages = ['/pages/index/index', '/pages/shop/index', '/pages/user/user'] const handleFeatureClick = (url: string) => { if (tabBarPages.includes(url)) { diff --git a/src/pages/user/index.tsx b/src/pages/user/index.tsx index 5b0b431..fe6669b 100644 --- a/src/pages/user/index.tsx +++ b/src/pages/user/index.tsx @@ -147,7 +147,7 @@ const UserPage: React.FC = () => { Taro.switchTab({ url: '/pages/points/index' })} + onClick={() => Taro.navigateTo({ url: '/pages/points/index' })} > {(user as any)?.points || 0} diff --git a/src/pages/user/wallet.tsx b/src/pages/user/wallet.tsx index b1f7446..c3d4bb9 100644 --- a/src/pages/user/wallet.tsx +++ b/src/pages/user/wallet.tsx @@ -11,7 +11,7 @@ definePageConfig({ const WalletPage: React.FC = () => { const { isLoggedIn } = useUser() - + // 获取用户余额信息(使用与"我的"页面相同的 API) const { data: balanceData, run: fetchBalance, loading: balanceLoading } = useRequest(getUserCardStats, { manual: true, @@ -62,28 +62,28 @@ const WalletPage: React.FC = () => { {/* 快捷操作 */} - Taro.navigateTo({ url: '/pages/user/balance-log/index' })} > 📄 余额明细 - Taro.navigateTo({ url: '/pages/user/recharge-record/index' })} > 💳 充值记录 - Taro.navigateTo({ url: '/pages/user/redeem/index' })} > 🎫 兑换码 - Taro.navigateTo({ url: '/pages/user/withdraw/index' })} > diff --git a/src/pages/user/withdraw/index.scss b/src/pages/user/withdraw/index.scss index 7938be6..6682606 100644 --- a/src/pages/user/withdraw/index.scss +++ b/src/pages/user/withdraw/index.scss @@ -1,28 +1,76 @@ .withdraw-page { display: flex; flex-direction: column; - height: 100vh; - background: #f5f5f5; + min-height: 100vh; + background: #f5f6fa; + padding-bottom: env(safe-area-inset-bottom); } +/* ========== 余额卡片 ========== */ +.balance-card { + margin: 24rpx; + padding: 40rpx 32rpx 32rpx; + background: linear-gradient(135deg, #ff6b35 0%, #ff8c42 100%); + border-radius: 20rpx; + color: #fff; +} + +.balance-header { + margin-bottom: 16rpx; +} + +.balance-label { + font-size: 26rpx; + color: rgba(255, 255, 255, 0.85); +} + +.balance-amount-row { + display: flex; + align-items: baseline; +} + +.currency-symbol-lg { + font-size: 40rpx; + font-weight: bold; + color: #fff; + margin-right: 8rpx; +} + +.balance-number { + font-size: 72rpx; + font-weight: bold; + color: #fff; + line-height: 1; +} + +.balance-tips { + margin-top: 16rpx; +} + +.balance-tip-text { + font-size: 24rpx; + color: rgba(255, 255, 255, 0.7); +} + +/* ========== 提现输入卡片 ========== */ .withdraw-card { margin: 24rpx; padding: 32rpx; background: #fff; - border-radius: 16rpx; + border-radius: 20rpx; } .card-title { - font-size: 28rpx; + font-size: 30rpx; font-weight: bold; color: #333; - margin-bottom: 32rpx; + margin-bottom: 28rpx; } .amount-input-wrap { display: flex; align-items: center; - padding: 24rpx 0; + padding: 20rpx 0; border-bottom: 2rpx solid #eee; margin-bottom: 16rpx; } @@ -41,131 +89,162 @@ color: #333; } -.amount-tips { - display: flex; - justify-content: space-between; - align-items: center; - font-size: 24rpx; - color: #999; -} - .all-withdraw { + flex-shrink: 0; + padding: 8rpx 20rpx; + background: #fff3ee; color: #ff6b35; + font-size: 24rpx; font-weight: bold; + border-radius: 24rpx; + border: 2rpx solid #ffd4bc; } .fee-tips { - margin-top: 12rpx; - font-size: 22rpx; - color: #ff9a56; -} - -.config-card { - margin: 0 24rpx 24rpx; - padding: 24rpx 32rpx; - background: #fff; - border-radius: 16rpx; -} - -.config-item { display: flex; - justify-content: space-between; - padding: 16rpx 0; - border-bottom: 1rpx solid #f5f5f5; + align-items: center; + gap: 8rpx; + margin-top: 16rpx; + padding: 12rpx 16rpx; + font-size: 24rpx; + color: #e67e22; + background: #fef9f5; + border-radius: 8rpx; } -.config-item:last-child { - border-bottom: none; +.fee-free { + color: #27ae60; + background: #f0faf4; } -.config-label { - font-size: 26rpx; - color: #666; +.fee-icon { + font-size: 24rpx; } -.config-value { - font-size: 26rpx; - color: #333; - font-weight: bold; -} - -/* 提现规则卡片 */ -.rules-card { +/* ========== 提现规则区域(核心审核项)========== */ +.rules-section { margin: 0 24rpx 24rpx; - padding: 32rpx; background: #fff; - border-radius: 16rpx; + border-radius: 20rpx; + overflow: hidden; } -.rules-title { - margin-bottom: 24rpx; - padding-bottom: 20rpx; - border-bottom: 2rpx solid #f0f0f0; +/* 标题栏 */ +.rules-header { + display: flex; + align-items: center; + gap: 12rpx; + padding: 28rpx 32rpx 20rpx; + background: linear-gradient(135deg, #fef0eb 0%, #fff8f5 100%); + border-bottom: 2rpx solid #fce8e1; } -.rules-title-text { +.rules-header-icon { + font-size: 36rpx; +} + +.rules-header-title { font-size: 30rpx; font-weight: bold; + color: #c0392b; +} + +/* 规则网格 - 两列 */ +.rules-grid { + display: grid; + grid-template-columns: 1fr 1fr; + padding: 24rpx 24rpx 8rpx; + gap: 16rpx; +} + +.rule-cell { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + padding: 20rpx 12rpx; + background: #fafafa; + border-radius: 12rpx; + border: 2rpx solid #f0f0f0; +} + +.rule-cell-wide { + grid-column: span 2; + flex-direction: row; + justify-content: space-between; + padding: 18rpx 24rpx; +} + +.rule-cell-label { + font-size: 23rpx; + color: #999; + margin-bottom: 8rpx; +} + +.rule-cell-value { + font-size: 28rpx; + font-weight: bold; color: #333; } -.rules-list { +.rule-cell-wide .rule-cell-label { + margin-bottom: 0; +} + +/* 详细规则文字列表 */ +.rules-detail { + padding: 20rpx 32rpx 28rpx; +} + +.detail-item { display: flex; - flex-direction: column; - gap: 0; + align-items: flex-start; + gap: 10rpx; + padding: 10rpx 0; } -.rule-item { - display: flex; - justify-content: space-between; - align-items: center; - padding: 18rpx 0; - border-bottom: 1rpx solid #f8f8f8; -} - -.rule-item:last-child { - border-bottom: none; -} - -.rule-label { - font-size: 26rpx; - color: #666; +.detail-bullet { flex-shrink: 0; -} - -.rule-value { font-size: 26rpx; color: #ff6b35; - font-weight: bold; + margin-top: 2rpx; } -/* 规则说明 */ -.rules-note { - margin-top: 24rpx; - padding: 24rpx; - background: #fff9f5; - border-radius: 12rpx; - border-left: 6rpx solid #ff6b35; +.detail-text { + font-size: 25rpx; + color: #666; + line-height: 1.7; } -.rules-note-text { - font-size: 24rpx; - color: #888; - line-height: 1.8; - display: block; +/* ========== 底部按钮区 ========== */ +.bottom-area { + margin-top: auto; + padding: 20rpx 40rpx 40rpx; } .submit-btn { - margin: 48rpx 24rpx; - padding: 24rpx 0; + width: 100%; + padding: 26rpx 0; text-align: center; background: linear-gradient(135deg, #ff6b35 0%, #ff9a56 100%); color: #fff; font-size: 32rpx; font-weight: bold; border-radius: 48rpx; + box-shadow: 0 8rpx 24rpx rgba(255, 107, 53, 0.35); } .submit-btn.disabled { - opacity: 0.5; + opacity: 0.45; + box-shadow: none; +} + +.submit-disclaimer { + text-align: center; + margin-top: 16rpx; +} + +.disclaimer-text { + font-size: 22rpx; + color: #bbb; } diff --git a/src/pages/user/withdraw/index.tsx b/src/pages/user/withdraw/index.tsx index 4aedbe8..c28b535 100644 --- a/src/pages/user/withdraw/index.tsx +++ b/src/pages/user/withdraw/index.tsx @@ -24,9 +24,9 @@ export default function WithdrawPage() { const loadConfig = async () => { try { - const res = await getWithdrawConfig(); - if (res.code === 200) { - setConfig(res.data); + const res: any = await getWithdrawConfig(); + if (res.code === 200 || res.code === 0) { + setConfig(res.data || {}); } } catch (error) { console.error('加载配置失败', error); @@ -35,15 +35,25 @@ export default function WithdrawPage() { const loadStats = async () => { try { - const res = await getWithdrawStats(); - if (res.code === 200) { - setStats(res.data); + const res: any = await getWithdrawStats(); + if (res.code === 200 || res.code === 0) { + setStats(res.data || {}); } } catch (error) { console.error('加载统计失败', error); } }; + // 从配置或默认值读取 + const minAmount = config.withdraw_min_amount || '10'; + const maxAmount = config.withdraw_max_amount || '200'; + const dailyLimit = config.withdraw_daily_limit || '2000'; + const dailyCount = config.withdraw_daily_count || 3; + const timeStart = config.withdraw_time_start || ''; + const timeEnd = config.withdraw_time_end || ''; + const feeRate = config.withdraw_fee_rate || '0'; + const arrivalTime = config.arrival_time || ''; + const handleWithdraw = () => { if (!amount || parseFloat(amount) <= 0) { Taro.showToast({ title: '请输入提现金额', icon: 'none' }); @@ -51,15 +61,12 @@ export default function WithdrawPage() { } const amountNum = parseFloat(amount); - const minAmount = parseFloat(config.withdraw_min_amount || '10'); - const maxAmount = parseFloat(config.withdraw_max_amount || '200'); - - if (amountNum < minAmount) { + if (amountNum < parseFloat(minAmount)) { Taro.showToast({ title: `最低提现金额为${minAmount}元`, icon: 'none' }); return; } - if (amountNum > maxAmount) { + if (amountNum > parseFloat(maxAmount)) { Taro.showToast({ title: `单次最大提现金额为${maxAmount}元`, icon: 'none' }); return; } @@ -69,12 +76,12 @@ export default function WithdrawPage() { const handlePayConfirm = async (payType: number) => { setShowPayModal(false); - if (payType !== 0) return; // 0微信支付 + if (payType !== 0) return; setSubmitting(true); try { - const res = await applyWithdraw({ amount: parseFloat(amount) }); - if (res.code === 200) { + const res: any = await applyWithdraw({ amount: parseFloat(amount) }); + if (res.code === 200 || res.code === 0) { Taro.showToast({ title: '提现申请已提交', icon: 'success' }); setTimeout(() => { Taro.navigateBack(); @@ -91,119 +98,156 @@ export default function WithdrawPage() { }; const handleAllWithdraw = () => { - // 可提现余额 - const available = stats.withdrawingTotal || '0'; + const available = stats.withdrawingTotal || stats.balance || '0.00'; setAmount(available); }; + const availableBalance = stats.withdrawingTotal || stats.balance || '0.00'; + return ( + {/* 余额卡片 */} + + + 可提现余额(元) + + + ¥ + {availableBalance} + + + 佣金已结算,可申请提现 + + + + {/* 提现输入 */} 提现金额 - ¥ setAmount(e.detail.value)} /> - - - - 可提现佣金: ¥{stats.withdrawingTotal || '0.00'} - + 全部提现 - - {config.withdraw_fee_rate && parseFloat(config.withdraw_fee_rate) > 0 && ( + {feeRate && parseFloat(feeRate) > 0 ? ( - 手续费: {config.withdraw_fee_rate}% + ⚠️ + 本次提现将收取 {feeRate}% 手续费 + + ) : ( + + + 当前免收提现手续费 )} - {/* 提现规则 */} - - - 提现规则 - - - - 可提现额度 - ¥{stats.withdrawingTotal || '0.00'} - - - 最低提现 - ¥{config.withdraw_min_amount || '10'}起 - - - 单次限额 - ¥{config.withdraw_max_amount || '200'} - - - 每日限额 - ¥{config.withdraw_daily_limit || '2000'} - - - 每日提现次数 - {config.withdraw_daily_count || 3}次/天 - - {config.withdraw_time_start ? ( - - 提现时间 - {config.withdraw_time_start} - {config.withdraw_time_end} - - ) : ( - - 提现时间 - 全天可提 - - )} - - 到账时间 - {config.arrival_time || '1-3个工作日'} - - {config.withdraw_fee_rate && parseFloat(config.withdraw_fee_rate) > 0 ? ( - - 手续费 - {config.withdraw_fee_rate}% - - ) : ( - - 手续费 - 免手续费 - - )} + {/* ====== 提现规则展示(核心审核项)====== */} + + {/* 标题栏 */} + + 📋 + 提现规则说明 - {/* 规则说明 */} - - - • 提现申请提交后将在1-3个工作日内审核到账,遇节假日顺延 - - - • 每日提现次数上限为{config.withdraw_daily_count || 3}次,超出后次日可继续申请 - - - • 单次提现金额范围为¥{config.withdraw_min_amount || '10'} - ¥{config.withdraw_max_amount || '200'} - - {config.withdraw_time_start && ( - - • 仅在{config.withdraw_time_start}-{config.withdraw_time_end}期间可发起提现 + {/* 规则网格 - 两列布局更醒目 */} + + + 最低提现 + {minAmount} 元起 + + + 单次限额 + {maxAmount} 元/次 + + + 每日限额 + {dailyLimit} 元/天 + + + 每日次数 + {dailyCount} 次/天 + + + 提现时间 + {timeStart && timeEnd ? `${timeStart}-${timeEnd}` : '全天可提'} + + + 到账时间 + {arrivalTime || '1-3个工作日'} + + + 手续费 + + {feeRate && parseFloat(feeRate) > 0 ? `${feeRate}%` : '免手续费'} + + + + {/* 详细规则文字 */} + + + + 提现金额范围为 ¥{minAmount} ~ ¥{maxAmount},超出范围无法提交 + + + + 每日最多可提现 {dailyCount} 次,累计不超过 ¥{dailyLimit} + + {timeStart && timeEnd ? ( + + + 仅在每日 {timeStart} 至 {timeEnd} 期间可发起提现申请 + + ) : ( + + + 支持全天 24 小时发起提现申请 + )} + + + 提现申请提交后将在 {arrivalTime || '1-3个工作日'} 内审核到账,遇国家法定节假日顺延 + + {feeRate && parseFloat(feeRate) > 0 ? ( + + + 每笔提现将收取 {feeRate}% 的服务手续费,从提现金额中直接扣除 + + ) : ( + + + 当前活动期间免收提现手续费,全额到账 + + )} + + + 提现金额将原路退回至您的支付账户,请确保账户状态正常 + - - {submitting ? '提交中...' : '确认提现'} + {/* 底部按钮 */} + + + {submitting ? '提交中...' : '确认提现'} + + + 提交即表示您已阅读并同意以上提现规则 +