feat(user): 完善提现规则展示与秒杀购买交互

- 新增提现规则卡片,展示提现额度、最低提现、单次限额、每日限额、每日提现次数、提现时间、到账时间、手续费等
- 添加提现规则说明文字,提示审核时间、提现次数限制、金额范围和提现时间段
- 优化秒杀详情和秒杀页面购买按钮交互,增加秒杀状态提示(未开始、已结束、已抢光)
- 统一秒杀购买事件处理函数名为 handleBuyClick,取消按钮条件绑定,增强点击响应体验
- 新增提现规则相关样式,确保提现规则卡和说明区块视觉效果一致
This commit is contained in:
2026-06-23 16:52:21 +08:00
parent 45b7b100ab
commit e72ca89b2b
5 changed files with 191 additions and 25 deletions

View 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` 编译通过 ✓

View File

@@ -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 ? '即将开始' : '已结束'}

View File

@@ -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 ? '即将开始' : '已结束'}

View File

@@ -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;

View File

@@ -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