142 lines
6.6 KiB
Plaintext
142 lines
6.6 KiB
Plaintext
<view class="exchange-page">
|
|
|
|
<!-- Balance Header (sticky) -->
|
|
<view class="balance-header">
|
|
<view class="balance-card">
|
|
<view class="balance-left">
|
|
<text class="balance-label">我的阳光值</text>
|
|
<view class="balance-value-row">
|
|
<text class="balance-emoji">☀️</text>
|
|
<text class="balance-value">{{currentSunlight}}</text>
|
|
</view>
|
|
</view>
|
|
<view class="balance-right" bindtap="goToOrders">
|
|
<t-icon name="assignment" size="40rpx" color="#558B2F" />
|
|
<text class="orders-text">兑换记录</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
|
|
<!-- Scrollable Content -->
|
|
<scroll-view scroll-y class="page-scroll" show-scrollbar="{{false}}" enhanced="{{true}}" lower-threshold="200" bindscrolltolower="onReachBottom">
|
|
|
|
<!-- Items Grid -->
|
|
<view class="items-grid" wx:if="{{items.length > 0}}">
|
|
<view class="item-card {{!item.isActive ? 'inactive' : ''}}" wx:for="{{items}}" wx:key="id" bindtap="onItemTap" data-item="{{item}}">
|
|
<view class="item-image-wrap">
|
|
<image wx:if="{{item.image}}" src="{{item.image.url}}" mode="aspectFill" class="item-img" lazy-load />
|
|
<view wx:else class="item-img-placeholder">
|
|
<t-icon name="gift" size="64rpx" color="#C5E1A5" />
|
|
</view>
|
|
<!-- Stock Badge -->
|
|
<view class="stock-badge" wx:if="{{item.isActive && item.stock >= 0 && item.stock <= 10 && item.stock > 0}}">
|
|
<text>仅剩 {{item.stock}}</text>
|
|
</view>
|
|
<!-- Status overlays -->
|
|
<view class="sold-out-mask" wx:if="{{item.stock === 0}}">
|
|
<text>已兑完</text>
|
|
</view>
|
|
<view class="sold-out-mask not-started" wx:elif="{{item.notStarted}}">
|
|
<text>未开始</text>
|
|
</view>
|
|
<view class="sold-out-mask ended" wx:elif="{{item.hasEnded}}">
|
|
<text>已结束</text>
|
|
</view>
|
|
</view>
|
|
<view class="item-info">
|
|
<text class="item-name">{{item.name}}</text>
|
|
<view class="item-price-row">
|
|
<text class="price-sun">☀️</text>
|
|
<text class="price-val">{{item.costSunlight}}</text>
|
|
</view>
|
|
<view class="item-time" wx:if="{{item.hasTimeLimit}}">
|
|
<t-icon name="time" size="24rpx" color="#9CA3AF" />
|
|
<text>{{item.timeLabel}}</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- Loading / Empty States -->
|
|
<view class="state-footer" wx:if="{{isLoading}}">
|
|
<t-loading theme="circular" size="40rpx" text="加载中..." inherit-color />
|
|
</view>
|
|
<view class="empty-state" wx:elif="{{!isLoading && items.length === 0}}">
|
|
<text class="empty-icon">🎁</text>
|
|
<text class="empty-title">暂无可兑换商品</text>
|
|
<text class="empty-desc">新的好礼正在路上,敬请期待</text>
|
|
</view>
|
|
<view class="state-footer" wx:elif="{{!hasMore && items.length > 0}}">
|
|
<text class="no-more">— 已经到底啦 —</text>
|
|
</view>
|
|
|
|
<!-- Spacer -->
|
|
<view style="height: 60rpx;"></view>
|
|
|
|
</scroll-view>
|
|
|
|
<!-- Redeem Popup -->
|
|
<t-popup visible="{{showRedeemPopup}}" bind:visible-change="onPopupClose" placement="bottom">
|
|
<view class="redeem-popup" wx:if="{{selectedItem}}">
|
|
<view class="popup-header">
|
|
<text class="popup-title">确认兑换</text>
|
|
<view class="popup-close" bindtap="onPopupClose">
|
|
<t-icon name="close" size="40rpx" color="#999" />
|
|
</view>
|
|
</view>
|
|
|
|
<!-- Item Preview -->
|
|
<view class="redeem-item-preview">
|
|
<view class="preview-img-wrap">
|
|
<image wx:if="{{selectedItem.image}}" src="{{selectedItem.image.url}}" mode="aspectFill" class="preview-img" />
|
|
<view wx:else class="preview-img-placeholder">
|
|
<t-icon name="gift" size="48rpx" color="#C5E1A5" />
|
|
</view>
|
|
</view>
|
|
<view class="preview-info">
|
|
<text class="preview-name">{{selectedItem.name}}</text>
|
|
<text class="preview-desc">{{selectedItem.description}}</text>
|
|
<view class="preview-cost">
|
|
<text class="cost-sun">☀️</text>
|
|
<text class="cost-val">{{selectedItem.costSunlight}}</text>
|
|
<text class="cost-unit">阳光值</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- Address Form (Physical only) -->
|
|
<view class="address-form" wx:if="{{selectedItem.type === 'PHYSICAL'}}">
|
|
<view class="form-title">收货信息</view>
|
|
<view class="form-item">
|
|
<text class="form-label">姓名</text>
|
|
<input placeholder="请输入收货人姓名" value="{{redeemForm.recipientName}}"
|
|
bindinput="onFormInput" data-field="recipientName" />
|
|
</view>
|
|
<view class="form-item">
|
|
<text class="form-label">电话</text>
|
|
<input type="number" placeholder="请输入联系电话" value="{{redeemForm.phone}}"
|
|
bindinput="onFormInput" data-field="phone" />
|
|
</view>
|
|
<view class="form-item">
|
|
<text class="form-label">地址</text>
|
|
<input placeholder="请输入详细收货地址" value="{{redeemForm.address}}"
|
|
bindinput="onFormInput" data-field="address" />
|
|
</view>
|
|
</view>
|
|
|
|
<!-- Balance Check -->
|
|
<view class="balance-check {{currentSunlight >= selectedItem.costSunlight ? '' : 'insufficient'}}">
|
|
<text>当前余额: ☀️ {{currentSunlight}}</text>
|
|
<text wx:if="{{currentSunlight < selectedItem.costSunlight}}" class="insufficient-tip">余额不足</text>
|
|
</view>
|
|
|
|
<!-- Confirm Button -->
|
|
<view class="redeem-btn {{currentSunlight >= selectedItem.costSunlight && selectedItem.stock !== 0 ? '' : 'disabled'}}"
|
|
bindtap="confirmRedeem">
|
|
<text>立即兑换</text>
|
|
</view>
|
|
</view>
|
|
</t-popup>
|
|
</view>
|