2025-12-27 16:06:24 +08:00

208 lines
8.1 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="detail-container">
<!-- 商品轮播图 -->
<view class="swiper-container">
<swiper indicator-dots :autoplay="false" :interval="3000" :duration="1000" indicator-active-color="#ff4d4f"
style="height: 100%;">
<swiper-item v-for="(item, index) in carouselImages" :key="index" style="height: 100%;">
<image :src="item" mode="aspectFill" class="swiper-image"></image>
</swiper-item>
</swiper>
<view class="swiper-indicator">{{ currentImageIndex + 1 }}/{{ carouselImages.length }}</view>
</view>
<!-- 商品信息 -->
<view class="product-info">
<view class="product-price">
<view>
<text class="price-number">{{ selectedGoodsInfo.points }}</text>
<text class="price-unit">积分</text>
</view>
<view class="exchange-info">已兑{{ productInfo.exchange_count }}</view>
</view>
<view class="product-name">{{ productInfo.commodity_name }}</view>
</view>
<!-- 商品详情 -->
<view class="product-details">
<view class="detail-title">
<view class="line"></view>
<view>商品详情</view>
<view class="line"></view>
</view>
<view class="detail-content">
<image v-for="(item, index) in detailImages" :key="index" :src="item" mode="widthFix"
class="detail-image" />
</view>
</view>
<!-- 底部操作栏 -->
<view class="bottom-bar">
<view class="points-info">
<text class="points-number">{{ selectedGoodsInfo.points }}积分</text>
<text class="points-label">当前积分{{ userPoints }}</text>
</view>
<view v-if="userPoints < selectedGoodsInfo.points" class="insufficient-points">
积分不足还差{{ selectedGoodsInfo.points - userPoints }}积分哦
</view>
<button v-else class="exchange-btn" @click="showSpecPopup = true">立即兑换</button>
<!-- <button class="exchange-btn" @click="showSpecPopup = true">立即兑换</button> -->
</view>
<!-- 规格选择弹窗 -->
<view v-if="showSpecPopup" class="spec-popup" @click.self="showSpecPopup = false">
<view class="popup-content">
<view class="close-btn" @click="showSpecPopup = false">×</view>
<view class="popup-header">
<view class="spec-image">
<image :src="selectedGoodsInfo.goods_info.commodity_pic" class="spec-image-item">
</image>
</view>
<view class="spec-info">
<view class="spec-price">
<text class="spec-price-number">{{ selectedGoodsInfo.points }}</text>
<text class="spec-price-unit">积分</text>
</view>
<view class="spec-change">
<view class="spec-selected">已选{{ selectedGoodsInfo.goods_info.goods_name }}</view>
</view>
</view>
</view>
<view class="spec-section">
<view class="spec-title">规格</view>
<view class="spec-options">
<view v-for="(spec, index) in productInfo.goods_info_list" :key="index"
:class="['spec-option', { active: selectedSpecId === spec.id }]" @click="selectSpec(spec)">
{{ spec.goods_info.goods_name }}
</view>
</view>
</view>
<view class="quantity-section">
<view class="quantity-title">数量</view>
<view class="quantity-control">
<button class="quantity-btn" @click="decreaseQuantity" :disabled="quantity <= 1">-</button>
<view class="quantity-input">{{ quantity }}</view>
<button class="quantity-btn" @click="increaseQuantity">+</button>
</view>
</view>
<view class="popup-footer">
<button class="confirm-btn" @click="confirmExchange">立即兑换</button>
</view>
</view>
</view>
</view>
</template>
<script>
import { request, picUrl, NavgateTo } from "../../../utils";
import { apiArr } from "../../../api/pointShop";
import { apiArr as apiArr2 } from '../../../api/v2User';
export default {
data() {
return {
productInfo: {},
userPoints: 0,
currentImageIndex: 0,
showSpecPopup: false,
selectedSpecId: 1,
selectedSpec: '',
quantity: 1,
selectedGoodsInfo: {}
};
},
computed: {
// 处理轮播图数据
carouselImages() {
if (this.productInfo.commodity_carousel) {
return this.productInfo.commodity_carousel.split(',').map(item => picUrl + item);
}
return [];
},
// 处理详情图片数据
detailImages() {
if (this.productInfo.commodity_detail_pic) {
return this.productInfo.commodity_detail_pic.split(',').map(item => picUrl + item);
}
return [];
}
},
methods: {
// 选择规格
selectSpec(spec) {
this.selectedSpecId = spec.id;
this.selectedSpec = spec.goods_info.goods_name;
this.selectedGoodsInfo = {
...spec,
goods_info: {
...spec.goods_info,
commodity_pic: picUrl + spec.goods_info.commodity_pic
}
};
this.quantity = 1;
},
// 减少数量
decreaseQuantity() {
if (this.quantity > 1) {
this.quantity--;
}
},
// 增加数量
increaseQuantity() {
if (this.quantity < this.selectedGoodsInfo.goods_info.stock && this.quantity < this.selectedGoodsInfo.goods_info.limit_buy) {
this.quantity++;
}
},
// 确认兑换
confirmExchange() {
const orderInfo = {
productId: this.productInfo.id,
specId: this.selectedSpecId,
specName: this.selectedSpec,
quantity: this.quantity,
price: this.selectedGoodsInfo.points,
goodsInfo: this.selectedGoodsInfo,
}
this.showSpecPopup = false;
NavgateTo('/packages/jfShop/submitOrder/index?orderInfo=' + JSON.stringify(orderInfo));
},
// 获取用户积分
getPointNum() {
request(apiArr2.getUserInfo, 'POST', {}, { silent: false }).then(res => {
this.userPoints = res.points;
});
},
},
onshow() {
this.getPointNum();
},
onLoad(options) {
this.getPointNum();
const orderInfo = JSON.parse(options.product);
const params = {
id: orderInfo.id
}
request(apiArr.pointGoodInfo, 'POST', params, { silent: false }, false).then(res => {
this.productInfo = res;
// 默认选择第一个规格
if (res.goods_info_list && res.goods_info_list.length > 0) {
this.selectedSpecId = res.goods_info_list[0].id;
this.selectedSpec = res.goods_info_list[0].goods_info.goods_name;
this.selectedGoodsInfo = {
...res.goods_info_list[0],
goods_info: {
...res.goods_info_list[0].goods_info,
commodity_pic: picUrl + res.goods_info_list[0].goods_info.commodity_pic
}
};
}
});
}
};
</script>
<style>
@import url('./index.css');
</style>