|
|
- <template>
- <uv-popup ref="popup" mode="bottom" :round="20" :safeAreaInsetBottom="true" @close="handleClose">
- <view class="interactive-gift-popup">
- <!-- 标题栏 -->
- <view class="popup-header">
- <text class="popup-title">互动打赏</text>
- <uv-icon name="close" size="40rpx" color="#999" @click="close"></uv-icon>
- </view>
-
-
- <!-- 当前选中礼物信息 -->
- <view class="selected-gift-info" v-if="selectedGift">
- <view class="selected-gift-left">
- <view class="selected-gift-img">
- <image :src="selectedGift.image" mode="aspectFill"></image>
- </view>
- <view class="selected-gift-details">
- <text class="selected-gift-name">{{ selectedGift.title }}</text>
- <text class="selected-gift-price">{{ selectedGift.integerPrice }}豆豆</text>
- </view>
- </view>
- <view class="selected-gift-right">
- <uv-number-box
- v-model="giftCount"
- :min="1"
- :max="99"
- size="small"
- bgColor="#f5f5f5"
- color="#223a7a"
- />
- </view>
- </view>
-
- <!-- 用户余额信息 -->
- <view class="balance-info">
- <view class="balance-text">
- 账户余额:<text class="bean-amount">{{ userInfo.integerPrice }} 豆豆</text>
- </view>
- <view v-if="selectedGift && totalPrice > userInfo.integerPrice" class="insufficient-tip">
- 余额不足,请先充值
- </view>
- </view>
-
- <view class="gift-grid">
- <view
- v-for="(gift, idx) in giftList"
- :key="gift.id"
- :class="['gift-item', { selected: selectedIndex === idx }]"
- @click="selectGift(idx)"
- >
- <view class="gift-img">
- <image :src="gift.image" mode="aspectFill"></image>
- </view>
- <view class="gift-name">{{ gift.title }}</view>
- <view class="gift-price">{{ gift.integerPrice }}豆豆</view>
- </view>
- </view>
-
- <!-- 底部操作栏 -->
- <view class="popup-bottom">
- <view class="total-info">
- <text class="total-text">总计:</text>
- <text class="total-price">{{ totalPrice }}豆豆</text>
- </view>
- <button class="gift-btn" @click="sendGift" :disabled="!selectedGift || loading">
- {{ loading ? '赠送中...' : '赠送' }}
- </button>
- </view>
- </view>
- </uv-popup>
- </template>
-
- <script>
- export default {
- name: 'InteractiveGiftPopup',
- props: {
- bookId: {
- type: [String, Number],
- required: true
- }
- },
- data() {
- return {
- giftList: [],
- selectedIndex: 0,
- selectedGift: null,
- giftCount: 1,
- loading: false,
- }
- },
- computed: {
- totalPrice() {
- if (!this.selectedGift) return 0;
- return this.selectedGift.integerPrice * this.giftCount;
- }
- },
- methods: {
- // 打开弹窗
- open() {
- this.$refs.popup.open();
- this.getGiftList();
- this.getUserBalance();
- },
-
- // 关闭弹窗
- close() {
- this.$refs.popup.close();
- },
-
- // 处理关闭事件
- handleClose() {
- this.resetData();
- },
-
- // 重置数据
- resetData() {
- this.selectedIndex = 0;
- this.selectedGift = null;
- this.giftCount = 1;
- this.loading = false;
- },
-
- // 获取礼物列表
- getGiftList() {
- this.$fetch('getInteractionGiftList').then(res => {
- this.giftList = res.records || [];
- if (this.giftList.length > 0) {
- this.selectGift(0);
- }
- }).catch(err => {
- console.error('获取礼物列表失败:', err);
- uni.showToast({
- title: '获取礼物列表失败',
- icon: 'none'
- });
- });
- },
-
- // 选择礼物
- selectGift(index) {
- this.selectedIndex = index;
- this.selectedGift = this.giftList[index];
- this.giftCount = 1;
- },
-
- // 获取用户余额
- getUserBalance() {
- // 从store中获取用户信息
- this.$store.commit('getUserInfo');
- },
-
- // 赠送礼物
- sendGift() {
- if (!this.selectedGift) {
- uni.showToast({
- title: '请选择礼物',
- icon: 'none'
- });
- return;
- }
-
- // 检查余额是否足够
- if (this.totalPrice > this.userInfo.integerPrice) {
- uni.showToast({
- title: '余额不足,请先充值',
- icon: 'none'
- });
- setTimeout(() => {
- uni.navigateTo({
- url: '/pages_order/mine/recharge'
- })
- }, 600)
- return;
- }
-
- this.loading = true;
-
- // 创建订单
- this.$fetch('giveGift', {
- giftId: this.selectedGift.id,
- num: this.giftCount,
- bookId: this.bookId,
- }).then(res => {
- // 支付成功
- uni.showToast({
- title: '赠送成功',
- icon: 'success'
- });
-
- // 通知父组件更新数据
- this.$emit('giftSent', {
- gift: this.selectedGift,
- count: this.giftCount,
- totalPrice: this.totalPrice
- });
-
- this.getUserBalance()
-
- this.close();
- }).catch(err => {
- console.error('赠送失败:', err);
- uni.showToast({
- title: err.message || '赠送失败',
- icon: 'none'
- });
- }).finally(() => {
- this.loading = false;
- });
- }
- }
- }
- </script>
-
- <style lang="scss" scoped>
- .interactive-gift-popup {
- background: #fff;
- border-radius: 20rpx 20rpx 0 0;
- max-height: 80vh;
- display: flex;
- flex-direction: column;
- }
-
- .popup-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- padding: 32rpx 32rpx 24rpx 32rpx;
- border-bottom: 1rpx solid #f5f5f5;
-
- .popup-title {
- font-size: 32rpx;
- font-weight: bold;
- color: #333;
- }
- }
-
- .selected-gift-info {
- display: flex;
- justify-content: space-between;
- align-items: center;
- padding: 24rpx 32rpx;
- background: #f8f9ff;
- margin: 0 32rpx 24rpx 32rpx;
- border-radius: 16rpx;
-
- .selected-gift-left {
- display: flex;
- align-items: center;
- gap: 16rpx;
-
- .selected-gift-img {
- width: 60rpx;
- height: 60rpx;
- border-radius: 8rpx;
- overflow: hidden;
-
- image {
- width: 100%;
- height: 100%;
- }
- }
-
- .selected-gift-details {
- display: flex;
- flex-direction: column;
- gap: 4rpx;
-
- .selected-gift-name {
- font-size: 28rpx;
- color: #333;
- font-weight: 500;
- }
-
- .selected-gift-price {
- font-size: 24rpx;
- color: #223a7a;
- }
- }
- }
- }
-
- .balance-info {
- padding: 0 32rpx 24rpx 32rpx;
-
- .balance-text {
- font-size: 28rpx;
- color: #333;
- margin-bottom: 8rpx;
-
- .bean-amount {
- color: #223a7a;
- font-weight: 600;
- }
- }
-
- .insufficient-tip {
- font-size: 24rpx;
- color: #e94f7a;
- background: rgba(233, 79, 122, 0.1);
- padding: 8rpx 16rpx;
- border-radius: 8rpx;
- text-align: center;
- }
- }
-
- .gift-grid {
- flex: 1;
- display: flex;
- flex-wrap: wrap;
- gap: 20rpx;
- padding: 0 32rpx;
- max-height: 400rpx;
- overflow-y: auto;
- }
-
- .gift-item {
- width: calc(25% - 18rpx);
- background: #fff;
- border-radius: 12rpx;
- box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.06);
- display: flex;
- flex-direction: column;
- align-items: center;
- padding: 20rpx 4rpx;
- border: 2rpx solid transparent;
- transition: all 0.2s;
- box-sizing: border-box;
-
- &.selected {
- border-color: #223a7a;
- background: #f8f9ff;
- }
-
- .gift-img {
- width: 70rpx;
- height: 70rpx;
- border-radius: 8rpx;
- overflow: hidden;
- margin-bottom: 8rpx;
-
- image {
- width: 100%;
- height: 100%;
- }
- }
-
- .gift-name {
- font-size: 22rpx;
- color: #333;
- text-align: center;
- margin-bottom: 4rpx;
- line-height: 1.2;
- }
-
- .gift-price {
- font-size: 20rpx;
- color: #223a7a;
- text-align: center;
- }
- }
-
- .popup-bottom {
- display: flex;
- justify-content: space-between;
- align-items: center;
- padding: 24rpx 32rpx;
- border-top: 1rpx solid #f5f5f5;
- background: #fff;
- width: 100%;
- box-sizing: border-box;
-
- .total-info {
- display: flex;
- align-items: center;
- gap: 8rpx;
-
- .total-text {
- font-size: 28rpx;
- color: #666;
- }
-
- .total-price {
- font-size: 32rpx;
- color: #223a7a;
- font-weight: bold;
- }
- }
-
- .gift-btn {
- background: #223a7a;
- color: #fff;
- font-size: 28rpx;
- border-radius: 32rpx;
- padding: 0 48rpx;
- height: 68rpx;
- line-height: 68rpx;
- border: none;
- min-width: 140rpx;
- margin-left: auto;
- margin-right: 20rpx;
-
- &[disabled] {
- background: #ccc;
- color: #999;
- }
- }
- }
- </style>
|