270 lines
5.7 KiB
Plaintext
270 lines
5.7 KiB
Plaintext
<template>
|
|
<cl-page>
|
|
<custom-back />
|
|
|
|
<scroll-view scroll-y class="content" v-if="product != null">
|
|
<swiper class="banner" autoplay circular indicator-dots>
|
|
<swiper-item v-for="(img, index) in productImages" :key="index">
|
|
<image class="banner-image" :src="img" mode="aspectFill" />
|
|
</swiper-item>
|
|
</swiper>
|
|
|
|
<view class="product-info">
|
|
<view class="price-row">
|
|
<text class="price">¥{{ product.price }}</text>
|
|
<text class="original-price" v-if="product.originalPrice != null">¥{{ product.originalPrice }}</text>
|
|
<text class="sales">已售{{ product.salesCount != null ? product.salesCount : 0 }}件</text>
|
|
</view>
|
|
<text class="product-name">{{ product.name }}</text>
|
|
<text class="product-origin" v-if="product.origin != null">产地: {{ product.origin }}</text>
|
|
</view>
|
|
|
|
<view class="spec-section">
|
|
<view class="spec-row">
|
|
<text class="spec-label">规格</text>
|
|
<text class="spec-value">{{ selectedSpec.length > 0 ? selectedSpec : '请选择' }}</text>
|
|
<cl-icon name="arrow-right" :size="28" color="#999" />
|
|
</view>
|
|
</view>
|
|
|
|
<view class="detail-section">
|
|
<text class="section-title">商品详情</text>
|
|
<rich-text class="detail-content" :nodes="product.detail != null ? product.detail : '暂无详情'"></rich-text>
|
|
</view>
|
|
|
|
<view style="height: 140rpx;"></view>
|
|
</scroll-view>
|
|
|
|
<view class="bottom-bar" v-if="product != null">
|
|
<view class="action-btns">
|
|
<view class="action-item" @click="goCart">
|
|
<cl-icon name="shopping-cart" :size="44" color="#666" />
|
|
<text class="action-text">购物车</text>
|
|
</view>
|
|
</view>
|
|
<view class="buy-btns">
|
|
<cl-button class="btn-cart" type="warning" round @click="addToCart">加入购物车</cl-button>
|
|
<cl-button class="btn-buy" type="primary" round @click="buyNow">立即购买</cl-button>
|
|
</view>
|
|
</view>
|
|
</cl-page>
|
|
</template>
|
|
|
|
<script setup lang="uts">
|
|
import { ref, computed, onMounted } from 'vue';
|
|
import { router, useCool, parseObject } from '@/cool';
|
|
import CustomBack from '@/components/custom-back.uvue';
|
|
|
|
const { service } = useCool();
|
|
|
|
const product = ref<any>(null);
|
|
const selectedSpec = ref('');
|
|
|
|
const productImages = computed(() : string[] => {
|
|
if (product.value == null) return ['/static/images/product.png'];
|
|
const p = product.value as UTSJSONObject;
|
|
const mainImage = p.getString('mainImage') != null ? p.getString('mainImage') : '/static/images/product.png';
|
|
|
|
if (p.get('images') == null) return [mainImage as string];
|
|
try {
|
|
const images = parseObject<string[]>(p.get('images') as string);
|
|
return images != null ? images : [mainImage as string];
|
|
} catch {
|
|
return [mainImage as string];
|
|
}
|
|
});
|
|
|
|
async function loadProduct() {
|
|
const pages = getCurrentPages();
|
|
const currentPage = pages[pages.length - 1];
|
|
const productId = Number(currentPage.options != null && currentPage.options!['id'] != null ? currentPage.options!['id'] : 0);
|
|
|
|
if (productId != 0) {
|
|
try {
|
|
const res = await service.nongchuang.product.detail({ id: productId });
|
|
product.value = res;
|
|
} catch (e) {
|
|
product.value = {
|
|
id: productId,
|
|
name: '有机番茄',
|
|
price: 9.9,
|
|
originalPrice: 15.9,
|
|
salesCount: 128,
|
|
origin: '山东寿光',
|
|
detail: '新鲜有机番茄,当日采摘'
|
|
};
|
|
}
|
|
}
|
|
}
|
|
|
|
function goCart() {
|
|
router.push({ path: '/pages/mall/cart' });
|
|
}
|
|
|
|
async function addToCart() {
|
|
if (product.value == null) return;
|
|
try {
|
|
await service.nongchuang.cart.add({ productId: product.value.id, quantity: 1 });
|
|
uni.showToast({ title: '已加入购物车', icon: 'success' });
|
|
} catch (e: any) {
|
|
const msg = e.message;
|
|
uni.showToast({ title: msg != null ? msg : '添加失败', icon: 'none' });
|
|
}
|
|
}
|
|
|
|
function buyNow() {
|
|
uni.showToast({ title: '购买功能开发中', icon: 'none' });
|
|
}
|
|
|
|
onMounted(() => {
|
|
loadProduct();
|
|
});
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.content {
|
|
flex: 1;
|
|
}
|
|
|
|
.banner {
|
|
height: 500rpx;
|
|
|
|
.banner-image {
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
}
|
|
|
|
.product-info {
|
|
padding: 30rpx;
|
|
background: #fff;
|
|
|
|
.price-row {
|
|
display: flex;
|
|
flex-direction: row;
|
|
align-items: flex-end;
|
|
|
|
.price {
|
|
font-size: 44rpx;
|
|
font-weight: bold;
|
|
color: #ff4d4f;
|
|
margin-right: 16rpx;
|
|
}
|
|
|
|
.original-price {
|
|
font-size: 28rpx;
|
|
color: #999;
|
|
}
|
|
|
|
.sales {
|
|
font-size: 24rpx;
|
|
color: #999;
|
|
margin-left: auto;
|
|
}
|
|
}
|
|
|
|
.product-name {
|
|
font-size: 32rpx;
|
|
font-weight: bold;
|
|
color: #333;
|
|
margin-top: 16rpx;
|
|
}
|
|
|
|
.product-origin {
|
|
font-size: 26rpx;
|
|
color: #999;
|
|
margin-top: 10rpx;
|
|
}
|
|
}
|
|
|
|
.spec-section {
|
|
margin-top: 20rpx;
|
|
background: #fff;
|
|
|
|
.spec-row {
|
|
display: flex;
|
|
flex-direction: row;
|
|
align-items: center;
|
|
padding: 24rpx 30rpx;
|
|
|
|
.spec-label {
|
|
font-size: 28rpx;
|
|
color: #333;
|
|
}
|
|
|
|
.spec-value {
|
|
flex: 1;
|
|
text-align: right;
|
|
font-size: 28rpx;
|
|
color: #999;
|
|
margin-right: 10rpx;
|
|
}
|
|
}
|
|
}
|
|
|
|
.detail-section {
|
|
margin-top: 20rpx;
|
|
padding: 30rpx;
|
|
background: #fff;
|
|
|
|
.section-title {
|
|
font-size: 30rpx;
|
|
font-weight: bold;
|
|
color: #333;
|
|
margin-bottom: 20rpx;
|
|
}
|
|
|
|
.detail-content {
|
|
font-size: 28rpx;
|
|
color: #666;
|
|
line-height: 1.6;
|
|
}
|
|
}
|
|
|
|
.bottom-bar {
|
|
position: fixed;
|
|
bottom: 0;
|
|
left: 0;
|
|
right: 0;
|
|
display: flex;
|
|
flex-direction: row;
|
|
align-items: center;
|
|
padding: 16rpx 20rpx;
|
|
background: #fff;
|
|
box-shadow: 0 -4rpx 16rpx rgba(0, 0, 0, 0.06);
|
|
|
|
.action-btns {
|
|
display: flex;
|
|
flex-direction: row;
|
|
padding-right: 30rpx;
|
|
|
|
.action-item {
|
|
margin-right: 30rpx;
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
|
|
.action-text {
|
|
font-size: 20rpx;
|
|
color: #666;
|
|
}
|
|
}
|
|
}
|
|
|
|
.buy-btns {
|
|
flex: 1;
|
|
display: flex;
|
|
flex-direction: row;
|
|
|
|
.btn-cart {
|
|
flex: 1;
|
|
margin-right: 16rpx;
|
|
}
|
|
|
|
.btn-buy {
|
|
flex: 1;
|
|
}
|
|
}
|
|
}
|
|
</style>
|