第一次上传
This commit is contained in:
@@ -0,0 +1,321 @@
|
||||
<template>
|
||||
<view class="product-detail-page">
|
||||
<!-- 全新方案:纯 CSS 手动构建的骨架屏 -->
|
||||
<view v-if="loading" class="skeleton-wrapper">
|
||||
<view class="skeleton-item skeleton-rect" style="width: 100%; height: 750rpx;"></view>
|
||||
<view class="skeleton-card" style="height: 200rpx;"></view>
|
||||
<view class="skeleton-card" style="height: 100rpx;"></view>
|
||||
<view class="skeleton-card">
|
||||
<view class="skeleton-item skeleton-text" style="width: 200rpx; height: 32rpx; margin-bottom: 20rpx;">
|
||||
</view>
|
||||
<view class="skeleton-item skeleton-rect" style="width: 100%; height: 300rpx;"></view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 页面实际内容 -->
|
||||
<view v-else class="page-content">
|
||||
|
||||
<scroll-view scroll-y>
|
||||
<!-- 1. 商品轮播图 -->
|
||||
<view class="swiper-section">
|
||||
<view class="swiper-item">
|
||||
<view class="image-placeholder swiper-image">
|
||||
<image :src="goodsInfo.img" style="width: 100%; height: 100%;" mode=""></image>
|
||||
</view>
|
||||
</view>
|
||||
<!-- <swiper class="swiper-container" circular autoplay :interval="3000" :duration="500"
|
||||
@change="e => swiperCurrent = e.detail.current">
|
||||
<swiper-item v-for="(item, index) in product.images" :key="index">
|
||||
<view class="swiper-item">
|
||||
<view class="image-placeholder swiper-image">
|
||||
<image :src="item" style="width: 100%; height: 100%;" mode=""></image>
|
||||
</view>
|
||||
</view>
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
<view class="swiper-dots">{{ swiperCurrent + 1 }} / {{ product.images.length }}</view> -->
|
||||
</view>
|
||||
|
||||
<!-- 2. 价格与商品信息 -->
|
||||
<view class="card info-card">
|
||||
<view class="price-line">
|
||||
<text class="points">{{ product.points }} 积分</text>
|
||||
<text class="original-price" v-if="product.originalPrice">+ ¥{{ product.originalPrice }}</text>
|
||||
</view>
|
||||
<text class="name">{{ product.name }}</text>
|
||||
<view class="meta-line">
|
||||
<text class="sales">已兑换 {{ product.sales }} 件</text>
|
||||
<text class="stock">库存 {{ product.stock }} 件</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 3. 规格选择 -->
|
||||
<view class="card spec-card">
|
||||
<up-cell title="规格" value="默认" isLink></up-cell>
|
||||
</view>
|
||||
|
||||
<!-- 4. 图文详情 -->
|
||||
<view class="card detail-content-card">
|
||||
<view class="section-title">
|
||||
<text>图文详情</text>
|
||||
</view>
|
||||
<up-parse :content="product.detailHtml"></up-parse>
|
||||
</view>
|
||||
|
||||
<!-- 5. 兑换须知 -->
|
||||
<view class="card detail-content-card">
|
||||
<view class="section-title">
|
||||
<text>兑换须知</text>
|
||||
</view>
|
||||
<up-parse :content="product.noticeHtml"></up-parse>
|
||||
</view>
|
||||
</scroll-view>
|
||||
<view class="" style=" height: 200rpx;">
|
||||
|
||||
</view>
|
||||
|
||||
<!-- 底部操作栏 -->
|
||||
<view class="bottom-bar">
|
||||
<button class="submit-btn">立即兑换</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from 'vue';
|
||||
import { onLoad, onShow } from '@dcloudio/uni-app';
|
||||
import { Service } from "@/Service/Service";
|
||||
import { vpGoodsService } from '@/Service/vp/vpGoodsService'
|
||||
|
||||
const loading = ref<boolean>(false);
|
||||
const swiperCurrent = ref(0);
|
||||
|
||||
// 模拟的商品详情数据
|
||||
const product = reactive({
|
||||
images: [
|
||||
'/static/dele/dele1.jpg',
|
||||
'/static/dele/dele2.jpg',
|
||||
],
|
||||
name: '品牌充电宝 10000mAh 金属外壳 超薄便携 支持多种快充协议',
|
||||
points: 2000,
|
||||
originalPrice: 19.9,
|
||||
sales: 128,
|
||||
stock: 872,
|
||||
detailHtml: `
|
||||
<div style="padding: 10px 0;">
|
||||
<p>这是一款设计精良的充电宝,小巧便携,功能强大。</p>
|
||||
|
||||
<p>采用高密度锂聚合物电芯,安全可靠。</p>
|
||||
</div>
|
||||
`,
|
||||
noticeHtml: `
|
||||
<div style="font-size: 14px; color: #666; line-height: 1.8;">
|
||||
<p>1. 积分商品兑换后不支持退换。</p>
|
||||
<p>2. 实物商品将在7个工作日内发货。</p>
|
||||
<p>3. 虚拟卡券将以短信形式发送至您的手机。</p>
|
||||
</div>
|
||||
`,
|
||||
});
|
||||
|
||||
let goodsInfo=ref<any>({})
|
||||
|
||||
let goodsId=ref('')
|
||||
|
||||
|
||||
onLoad((options:any) => {
|
||||
goodsId.value=options.id
|
||||
getData()
|
||||
});
|
||||
onShow(() => { });
|
||||
|
||||
const getData=()=>{
|
||||
vpGoodsService.GetGoodsInfo(goodsId.value).then(res=>{
|
||||
if(res.code==0){
|
||||
goodsInfo.value=res.data.goodsInfo
|
||||
}else{
|
||||
Service.Msg(res.msg)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@keyframes skeleton-blink {
|
||||
0% {
|
||||
background-position: 100% 50%;
|
||||
}
|
||||
|
||||
100% {
|
||||
background-position: 0 50%;
|
||||
}
|
||||
}
|
||||
|
||||
.skeleton-item {
|
||||
background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
|
||||
background-size: 200% 100%;
|
||||
animation: skeleton-blink 1.5s infinite linear;
|
||||
}
|
||||
|
||||
.skeleton-rect {
|
||||
border-radius: 8rpx;
|
||||
}
|
||||
|
||||
.skeleton-text {
|
||||
border-radius: 4rpx;
|
||||
}
|
||||
|
||||
.skeleton-wrapper {
|
||||
background-color: #f7f7f7;
|
||||
|
||||
.skeleton-card {
|
||||
background-color: #fff;
|
||||
padding: 30rpx;
|
||||
border-radius: 16rpx;
|
||||
margin: 24rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.product-detail-page {
|
||||
background-color: #f7f7f7;
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.page-scroll {
|
||||
flex: 1;
|
||||
height: 0;
|
||||
padding-bottom: 140rpx;
|
||||
}
|
||||
|
||||
.card {
|
||||
background-color: #fff;
|
||||
border-radius: 16rpx;
|
||||
margin: 24rpx;
|
||||
padding: 30rpx;
|
||||
box-shadow: 0 8rpx 30rpx rgba(220, 220, 230, 0.3);
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
margin-bottom: 20rpx;
|
||||
border-left: 8rpx solid #fa6400;
|
||||
padding-left: 16rpx;
|
||||
}
|
||||
|
||||
.swiper-section {
|
||||
position: relative;
|
||||
|
||||
.swiper-container {
|
||||
height: 750rpx;
|
||||
/* 1:1 的轮播图 */
|
||||
}
|
||||
|
||||
.swiper-item {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
.swiper-image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.swiper-dots {
|
||||
position: absolute;
|
||||
bottom: 20rpx;
|
||||
right: 20rpx;
|
||||
background-color: rgba(0, 0, 0, 0.4);
|
||||
color: #fff;
|
||||
padding: 4rpx 12rpx;
|
||||
border-radius: 20rpx;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.info-card {
|
||||
margin-top: -20rpx; // 与轮播图重叠
|
||||
position: relative;
|
||||
|
||||
.price-line {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
|
||||
.points {
|
||||
font-size: 48rpx;
|
||||
font-weight: bold;
|
||||
color: #fa6400;
|
||||
}
|
||||
|
||||
.original-price {
|
||||
font-size: 28rpx;
|
||||
color: #999;
|
||||
margin-left: 16rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.name {
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
margin: 16rpx 0;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.meta-line {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
font-size: 26rpx;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
|
||||
.spec-card {
|
||||
padding: 0;
|
||||
|
||||
:deep(.up-cell) {
|
||||
.up-cell__body {
|
||||
padding: 30rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.detail-content-card {
|
||||
:deep(img) {
|
||||
max-width: 100%;
|
||||
border-radius: 8rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.bottom-bar {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background-color: #fff;
|
||||
padding: 20rpx 30rpx;
|
||||
padding-bottom: calc(20rpx + constant(safe-area-inset-bottom));
|
||||
padding-bottom: calc(20rpx + env(safe-area-inset-bottom));
|
||||
z-index: 100;
|
||||
box-shadow: 0 -4rpx 20rpx rgba(0, 0, 0, 0.08);
|
||||
|
||||
.submit-btn {
|
||||
background-color: #fa6400;
|
||||
color: #fff;
|
||||
font-weight: bold;
|
||||
border-radius: 44rpx;
|
||||
height: 88rpx;
|
||||
line-height: 88rpx;
|
||||
font-size: 30rpx;
|
||||
margin: 0;
|
||||
|
||||
&::after {
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user