feat(user): 完善提现规则展示与秒杀购买交互
- 新增提现规则卡片,展示提现额度、最低提现、单次限额、每日限额、每日提现次数、提现时间、到账时间、手续费等 - 添加提现规则说明文字,提示审核时间、提现次数限制、金额范围和提现时间段 - 优化秒杀详情和秒杀页面购买按钮交互,增加秒杀状态提示(未开始、已结束、已抢光) - 统一秒杀购买事件处理函数名为 handleBuyClick,取消按钮条件绑定,增强点击响应体验 - 新增提现规则相关样式,确保提现规则卡和说明区块视觉效果一致
This commit is contained in:
16
.workbuddy/memory/2026-06-23.md
Normal file
16
.workbuddy/memory/2026-06-23.md
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
# 2026-06-23
|
||||||
|
|
||||||
|
## 微信小程序审核修复(第二轮)
|
||||||
|
|
||||||
|
### 审核失败原因
|
||||||
|
1. **提现页面规则不完整** — 需展示可提现额度、每日提现次数、提现时间、到账时间等
|
||||||
|
2. **限时秒杀功能点击无响应** — 无法体验完整流程
|
||||||
|
|
||||||
|
### 修改文件
|
||||||
|
1. **`src/pages/user/withdraw/index.tsx`** — 将原来仅3项的 config-card 替换为完整 rules-card,新增:可提现额度、最低提现、每日限额、每日提现次数、提现时间(含兜底"全天可提")、到账时间、手续费(含兜底"免手续费"),底部加 rules-note 说明区块
|
||||||
|
2. **`src/pages/user/withdraw/index.scss`** — 新增 .rules-card / .rules-title / .rule-item / .rules-note 等样式
|
||||||
|
3. **`src/pages/shop/seckill-detail/index.tsx`** — `handleBuyNow` → `handleBuyClick`,增加未开始/已结束/已抢光三种状态的 Toast 提示,按钮 onClick 始终绑定(不再条件判断)
|
||||||
|
4. **`src/pages/seckill-detail.tsx`** — 同步修改 root 平铺版秒杀详情页(与 shop/ 子目录版内容一致)
|
||||||
|
|
||||||
|
### 构建状态
|
||||||
|
- `taro build --type weapp` 编译通过 ✓
|
||||||
@@ -91,14 +91,26 @@ const SeckillDetailPage: React.FC = () => {
|
|||||||
setCountdown(`${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`)
|
setCountdown(`${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleBuyNow = () => {
|
const handleBuyClick = () => {
|
||||||
if (!seckill) return
|
if (!seckill) return
|
||||||
|
|
||||||
if (seckill.stock <= 0) {
|
if (seckill.status === 0) {
|
||||||
Taro.showToast({ title: '已抢光', icon: 'none' })
|
Taro.showToast({ title: '活动尚未开始,请耐心等待', icon: 'none' })
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (seckill.status === 2 || new Date(seckill.endTime).getTime() <= Date.now()) {
|
||||||
|
Taro.showToast({ title: '活动已结束,下次再来', icon: 'none' })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (seckill.stock <= 0) {
|
||||||
|
Taro.showToast({ title: '已抢光,下次再来', icon: 'none' })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (submitting) return
|
||||||
|
|
||||||
// 先拉取商品规格(如果没有的话)
|
// 先拉取商品规格(如果没有的话)
|
||||||
if (!product && seckill.goodsId) {
|
if (!product && seckill.goodsId) {
|
||||||
Taro.showLoading({ title: '加载规格...' })
|
Taro.showLoading({ title: '加载规格...' })
|
||||||
@@ -255,8 +267,11 @@ const SeckillDetailPage: React.FC = () => {
|
|||||||
<View className="bg-white border-t border-gray-100 px-4 py-3">
|
<View className="bg-white border-t border-gray-100 px-4 py-3">
|
||||||
<View
|
<View
|
||||||
className="w-full py-3 rounded-full text-white text-center text-base font-medium"
|
className="w-full py-3 rounded-full text-white text-center text-base font-medium"
|
||||||
style={{ backgroundColor: isActive ? '#ef4444' : '#d1d5db' }}
|
style={{
|
||||||
onClick={isActive && !submitting ? handleBuyNow : undefined}
|
backgroundColor: isActive && !submitting ? '#ef4444' : '#d1d5db',
|
||||||
|
opacity: submitting ? 0.7 : 1,
|
||||||
|
}}
|
||||||
|
onClick={handleBuyClick}
|
||||||
>
|
>
|
||||||
<Text>
|
<Text>
|
||||||
{submitting ? '抢购中...' : isActive ? (seckill.stock > 0 ? '立即抢购' : '已抢光') : seckill.status === 0 ? '即将开始' : '已结束'}
|
{submitting ? '抢购中...' : isActive ? (seckill.stock > 0 ? '立即抢购' : '已抢光') : seckill.status === 0 ? '即将开始' : '已结束'}
|
||||||
|
|||||||
@@ -91,14 +91,26 @@ const SeckillDetailPage: React.FC = () => {
|
|||||||
setCountdown(`${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`)
|
setCountdown(`${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleBuyNow = () => {
|
const handleBuyClick = () => {
|
||||||
if (!seckill) return
|
if (!seckill) return
|
||||||
|
|
||||||
if (seckill.stock <= 0) {
|
if (seckill.status === 0) {
|
||||||
Taro.showToast({ title: '已抢光', icon: 'none' })
|
Taro.showToast({ title: '活动尚未开始,请耐心等待', icon: 'none' })
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (seckill.status === 2 || new Date(seckill.endTime).getTime() <= Date.now()) {
|
||||||
|
Taro.showToast({ title: '活动已结束,下次再来', icon: 'none' })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (seckill.stock <= 0) {
|
||||||
|
Taro.showToast({ title: '已抢光,下次再来', icon: 'none' })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (submitting) return
|
||||||
|
|
||||||
// 先拉取商品规格(如果没有的话)
|
// 先拉取商品规格(如果没有的话)
|
||||||
if (!product && seckill.goodsId) {
|
if (!product && seckill.goodsId) {
|
||||||
Taro.showLoading({ title: '加载规格...' })
|
Taro.showLoading({ title: '加载规格...' })
|
||||||
@@ -255,8 +267,11 @@ const SeckillDetailPage: React.FC = () => {
|
|||||||
<View className="bg-white border-t border-gray-100 px-4 py-3">
|
<View className="bg-white border-t border-gray-100 px-4 py-3">
|
||||||
<View
|
<View
|
||||||
className="w-full py-3 rounded-full text-white text-center text-base font-medium"
|
className="w-full py-3 rounded-full text-white text-center text-base font-medium"
|
||||||
style={{ backgroundColor: isActive ? '#ef4444' : '#d1d5db' }}
|
style={{
|
||||||
onClick={isActive && !submitting ? handleBuyNow : undefined}
|
backgroundColor: isActive && !submitting ? '#ef4444' : '#d1d5db',
|
||||||
|
opacity: submitting ? 0.7 : 1,
|
||||||
|
}}
|
||||||
|
onClick={handleBuyClick}
|
||||||
>
|
>
|
||||||
<Text>
|
<Text>
|
||||||
{submitting ? '抢购中...' : isActive ? (seckill.stock > 0 ? '立即抢购' : '已抢光') : seckill.status === 0 ? '即将开始' : '已结束'}
|
{submitting ? '抢购中...' : isActive ? (seckill.stock > 0 ? '立即抢购' : '已抢光') : seckill.status === 0 ? '即将开始' : '已结束'}
|
||||||
|
|||||||
@@ -89,6 +89,72 @@
|
|||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 提现规则卡片 */
|
||||||
|
.rules-card {
|
||||||
|
margin: 0 24rpx 24rpx;
|
||||||
|
padding: 32rpx;
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rules-title {
|
||||||
|
margin-bottom: 24rpx;
|
||||||
|
padding-bottom: 20rpx;
|
||||||
|
border-bottom: 2rpx solid #f0f0f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rules-title-text {
|
||||||
|
font-size: 30rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rules-list {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 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;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rule-value {
|
||||||
|
font-size: 26rpx;
|
||||||
|
color: #ff6b35;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 规则说明 */
|
||||||
|
.rules-note {
|
||||||
|
margin-top: 24rpx;
|
||||||
|
padding: 24rpx;
|
||||||
|
background: #fff9f5;
|
||||||
|
border-radius: 12rpx;
|
||||||
|
border-left: 6rpx solid #ff6b35;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rules-note-text {
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #888;
|
||||||
|
line-height: 1.8;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
.submit-btn {
|
.submit-btn {
|
||||||
margin: 48rpx 24rpx;
|
margin: 48rpx 24rpx;
|
||||||
padding: 24rpx 0;
|
padding: 24rpx 0;
|
||||||
|
|||||||
@@ -126,23 +126,77 @@ export default function WithdrawPage() {
|
|||||||
)}
|
)}
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
<View className="config-card">
|
{/* 提现规则 */}
|
||||||
<View className="config-item">
|
<View className="rules-card">
|
||||||
<Text className="config-label">单次限额</Text>
|
<View className="rules-title">
|
||||||
<Text className="config-value">¥{config.withdraw_max_amount || '200'}</Text>
|
<Text className="rules-title-text">提现规则</Text>
|
||||||
</View>
|
</View>
|
||||||
<View className="config-item">
|
<View className="rules-list">
|
||||||
<Text className="config-label">每日限额</Text>
|
<View className="rule-item">
|
||||||
<Text className="config-value">¥{config.withdraw_daily_limit || '2000'}</Text>
|
<Text className="rule-label">可提现额度</Text>
|
||||||
|
<Text className="rule-value">¥{stats.withdrawingTotal || '0.00'}</Text>
|
||||||
</View>
|
</View>
|
||||||
{config.withdraw_time_start && (
|
<View className="rule-item">
|
||||||
<View className="config-item">
|
<Text className="rule-label">最低提现</Text>
|
||||||
<Text className="config-label">提现时间</Text>
|
<Text className="rule-value">¥{config.withdraw_min_amount || '10'}起</Text>
|
||||||
<Text className="config-value">
|
</View>
|
||||||
{config.withdraw_time_start} - {config.withdraw_time_end}
|
<View className="rule-item">
|
||||||
</Text>
|
<Text className="rule-label">单次限额</Text>
|
||||||
|
<Text className="rule-value">¥{config.withdraw_max_amount || '200'}</Text>
|
||||||
|
</View>
|
||||||
|
<View className="rule-item">
|
||||||
|
<Text className="rule-label">每日限额</Text>
|
||||||
|
<Text className="rule-value">¥{config.withdraw_daily_limit || '2000'}</Text>
|
||||||
|
</View>
|
||||||
|
<View className="rule-item">
|
||||||
|
<Text className="rule-label">每日提现次数</Text>
|
||||||
|
<Text className="rule-value">{config.withdraw_daily_count || 3}次/天</Text>
|
||||||
|
</View>
|
||||||
|
{config.withdraw_time_start ? (
|
||||||
|
<View className="rule-item">
|
||||||
|
<Text className="rule-label">提现时间</Text>
|
||||||
|
<Text className="rule-value">{config.withdraw_time_start} - {config.withdraw_time_end}</Text>
|
||||||
|
</View>
|
||||||
|
) : (
|
||||||
|
<View className="rule-item">
|
||||||
|
<Text className="rule-label">提现时间</Text>
|
||||||
|
<Text className="rule-value">全天可提</Text>
|
||||||
</View>
|
</View>
|
||||||
)}
|
)}
|
||||||
|
<View className="rule-item">
|
||||||
|
<Text className="rule-label">到账时间</Text>
|
||||||
|
<Text className="rule-value">{config.arrival_time || '1-3个工作日'}</Text>
|
||||||
|
</View>
|
||||||
|
{config.withdraw_fee_rate && parseFloat(config.withdraw_fee_rate) > 0 ? (
|
||||||
|
<View className="rule-item">
|
||||||
|
<Text className="rule-label">手续费</Text>
|
||||||
|
<Text className="rule-value">{config.withdraw_fee_rate}%</Text>
|
||||||
|
</View>
|
||||||
|
) : (
|
||||||
|
<View className="rule-item">
|
||||||
|
<Text className="rule-label">手续费</Text>
|
||||||
|
<Text className="rule-value">免手续费</Text>
|
||||||
|
</View>
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* 规则说明 */}
|
||||||
|
<View className="rules-note">
|
||||||
|
<Text className="rules-note-text">
|
||||||
|
• 提现申请提交后将在1-3个工作日内审核到账,遇节假日顺延
|
||||||
|
</Text>
|
||||||
|
<Text className="rules-note-text">
|
||||||
|
• 每日提现次数上限为{config.withdraw_daily_count || 3}次,超出后次日可继续申请
|
||||||
|
</Text>
|
||||||
|
<Text className="rules-note-text">
|
||||||
|
• 单次提现金额范围为¥{config.withdraw_min_amount || '10'} - ¥{config.withdraw_max_amount || '200'}
|
||||||
|
</Text>
|
||||||
|
{config.withdraw_time_start && (
|
||||||
|
<Text className="rules-note-text">
|
||||||
|
• 仅在{config.withdraw_time_start}-{config.withdraw_time_end}期间可发起提现
|
||||||
|
</Text>
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
<View
|
<View
|
||||||
|
|||||||
Reference in New Issue
Block a user