- 401 自动续登重试:request.ts 1002+401→relogin(全局锁+30s冷却)→新token重试一次(既有实现,本次核验确认) - 三态:app.wxss 新增 .error-state 共享样式;首页(全模块失败判定)/福利街/任务页(双路失败判定)加错误态+重试 - 图片:11 处列表/首屏下图加 lazy-load;首页 placeholder.png(不存在)→gift.png;生成缺失的 avatar.png 灰圆默认头像 - 分享兜底:share.ts 加 DEFAULT_SHARE_IMAGE/shareImage();12 个 onShareAppMessage 全部补 imageUrl 兜底 - iOS 安全区:.page 底距 calc(120rpx+env);详情 float-share/swipe-hint、签到 float-share、3 个 add-btn、问卷 footer-btns 补 env(safe-area-inset-bottom)
117 lines
5.5 KiB
Plaintext
117 lines
5.5 KiB
Plaintext
<!-- 福利街:V8.0 手册 3B.3 TabBar 第二项 -->
|
|
<view class="page page-safe">
|
|
<view class="welfare-header">
|
|
<view class="title-row">
|
|
<text class="section-title">福利街</text>
|
|
<text class="subtitle">积分兑换 · 品牌福利</text>
|
|
</view>
|
|
<view class="mall-entry" bindtap="goMall" wx:if="{{purchaseEnabled}}">
|
|
<text>全部商品</text>
|
|
<text class="arrow">›</text>
|
|
</view>
|
|
</view>
|
|
|
|
<view wx:if="{{welfareItems.length === 0 && !loading && !loadError}}" class="empty-state">
|
|
暂无可兑换的福利
|
|
</view>
|
|
|
|
<!-- F6:错误态(首屏加载失败,可重试) -->
|
|
<view wx:if="{{loadError && welfareItems.length === 0}}" class="error-state">
|
|
<view>{{loadError}}</view>
|
|
<view class="error-state-retry" bindtap="retryLoad">重试</view>
|
|
</view>
|
|
|
|
<view class="welfare-grid">
|
|
<view
|
|
wx:for="{{welfareItems}}" wx:key="id"
|
|
class="welfare-card card card-shadow"
|
|
bindtap="goDetail" data-id="{{item.id}}"
|
|
>
|
|
<image wx:if="{{item.image && !item._imgErr}}" class="welfare-img" src="{{item.image}}" mode="aspectFill" lazy-load binderror="onImgError" data-index="{{index}}" />
|
|
<view wx:else class="welfare-img-placeholder">🎁</view>
|
|
<view class="welfare-info">
|
|
<text class="welfare-name">{{item.name}}</text>
|
|
<view class="welfare-meta">
|
|
<text class="welfare-points">{{item.points_cost}} 积分</text>
|
|
<text class="welfare-stock" wx:if="{{item.stock <= 0}}">已兑完</text>
|
|
</view>
|
|
<!-- F12:每商品抽抵扣券入口(catchtap 阻止冒泡进详情) -->
|
|
<view class="draw-entry" catchtap="openDraw" data-id="{{item.id}}">
|
|
<text class="draw-entry-icon">🎟️</text>
|
|
<text>抽抵扣券</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<view wx:if="{{loading}}" class="loading-state">加载中...</view>
|
|
<view wx:elif="{{noMore && welfareItems.length > 0}}" class="loading-state">没有更多了</view>
|
|
|
|
<!-- F12 抽抵扣券弹层 -->
|
|
<view wx:if="{{drawVisible}}" class="draw-mask" bindtap="closeDraw" catchtouchmove="noop">
|
|
<view class="draw-panel" catchtap="noop">
|
|
<view class="draw-close" catchtap="closeDraw">✕</view>
|
|
|
|
<!-- 加载中 -->
|
|
<view wx:if="{{drawLoading}}" class="draw-loading">活动加载中...</view>
|
|
|
|
<block wx:else>
|
|
<!-- 无活动 -->
|
|
<view wx:if="{{!drawLottery}}" class="draw-empty">
|
|
<view class="draw-empty-icon">🎁</view>
|
|
<view class="draw-empty-text">该商品暂无抽券活动</view>
|
|
<view class="draw-empty-sub">去看看其他商品,或先兑换心仪好物</view>
|
|
</view>
|
|
|
|
<!-- 有活动:未抽/再抽 -->
|
|
<block wx:elif="{{!drawResult}}">
|
|
<view class="draw-title">{{drawLottery.title}}</view>
|
|
<view class="draw-scope-tag" wx:if="{{drawLottery.scope === 'product'}}">本商品专属 · 高中奖率</view>
|
|
<view class="draw-product" wx:if="{{drawProduct}}">
|
|
<image wx:if="{{drawProduct.image}}" class="draw-product-img" src="{{drawProduct.image}}" mode="aspectFill" />
|
|
<view class="draw-product-name">{{drawProduct.name}}</view>
|
|
</view>
|
|
<view class="draw-prizes" wx:if="{{drawLottery.prizes.length > 0}}">
|
|
<view class="draw-prize" wx:for="{{drawLottery.prizes}}" wx:key="id" wx:if="{{item.source !== 'thanks'}}">
|
|
<image wx:if="{{item.image}}" class="draw-prize-img" src="{{item.image}}" mode="aspectFill" />
|
|
<view wx:else class="draw-prize-img draw-prize-img-placeholder">🎁</view>
|
|
<text class="draw-prize-name">{{item.name}}</text>
|
|
<text class="draw-prize-rate" wx:if="{{item.win_rate > 0}}">{{item.win_rate}}%</text>
|
|
</view>
|
|
</view>
|
|
<view class="draw-cost-row">
|
|
<text>每次消耗 {{drawLottery.points_cost}} 积分</text>
|
|
<text class="draw-balance">余额 {{drawBalance}}</text>
|
|
</view>
|
|
<button
|
|
class="draw-btn {{drawBalance < drawLottery.points_cost ? 'draw-btn-disabled' : ''}}"
|
|
bindtap="doDraw"
|
|
disabled="{{drawing}}"
|
|
>
|
|
{{drawing ? '抽奖中...' : (drawBalance < drawLottery.points_cost ? '积分不足' : '立即抽奖')}}
|
|
</button>
|
|
<view class="draw-earn" bindtap="goTasks">积分不够?去做任务赚积分 ›</view>
|
|
</block>
|
|
|
|
<!-- 抽奖结果 -->
|
|
<block wx:else>
|
|
<view class="draw-result">
|
|
<view class="draw-result-icon">{{drawResult.is_win ? '🎉' : '😅'}}</view>
|
|
<view class="draw-result-title">{{drawResult.is_win ? '恭喜中奖!' : '差一点点'}}</view>
|
|
<view class="draw-result-prize">{{drawResult.prize_name}}</view>
|
|
<image wx:if="{{drawResult.is_win && drawResult.prize_image}}" class="draw-result-img" src="{{drawResult.prize_image}}" mode="aspectFit" />
|
|
<view class="draw-result-msg" wx:if="{{drawResult.message}}">{{drawResult.message}}</view>
|
|
<view class="draw-result-balance">剩余积分 {{drawResult.balance_after}}</view>
|
|
</view>
|
|
<button
|
|
class="draw-btn"
|
|
wx:if="{{drawLottery && drawResult.balance_after >= drawLottery.points_cost}}"
|
|
bindtap="drawAgain"
|
|
>再抽一次({{drawLottery.points_cost}} 积分)</button>
|
|
<button class="draw-btn draw-btn-plain" bindtap="closeDraw">收下啦</button>
|
|
</block>
|
|
</block>
|
|
</view>
|
|
</view>
|
|
</view>
|