|
|
@@ -4,13 +4,14 @@
|
|
|
<view class="header-bg"></view>
|
|
|
|
|
|
<!-- Custom Navbar -->
|
|
|
- <Navbar :title="product.bookName || '详情'" :titleSize="32" title-color="#fff" back-icon-color="#fff" background="transparent">
|
|
|
+ <Navbar :title="product.bookName || '详情'" :titleSize="32" title-color="#fff" back-icon-color="#fff"
|
|
|
+ background="transparent">
|
|
|
</Navbar>
|
|
|
|
|
|
<!-- Notification Bar -->
|
|
|
<view class="notification-bar">
|
|
|
<u-avatar size="40" src="https://img.yzcdn.cn/vant/cat.jpeg"></u-avatar>
|
|
|
-
|
|
|
+
|
|
|
<text class="notif-text">微 ** 用户 购买了 《苏菲的世界》</text>
|
|
|
</view>
|
|
|
|
|
|
@@ -40,12 +41,14 @@
|
|
|
@position-change="handlePositionChange" :z-index="20">
|
|
|
<!-- #ifdef MP-ALIPAY -->
|
|
|
<button class="service-btn" @click="navigateToCustomerService">
|
|
|
- <image src="/pages-sell/static/goods/icon-kefu.png" class="cs-icon" style="width: 100rpx;" mode="widthFix"></image>
|
|
|
+ <image src="/pages-sell/static/goods/icon-kefu.png" class="cs-icon" style="width: 100rpx;"
|
|
|
+ mode="widthFix"></image>
|
|
|
</button>
|
|
|
<!-- #endif -->
|
|
|
<!-- #ifndef MP-ALIPAY -->
|
|
|
<button class="service-btn" open-type="contact">
|
|
|
- <image src="/pages-sell/static/goods/icon-kefu.png" class="cs-icon" style="width: 100rpx" mode="widthFix"></image>
|
|
|
+ <image src="/pages-sell/static/goods/icon-kefu.png" class="cs-icon" style="width: 100rpx"
|
|
|
+ mode="widthFix"></image>
|
|
|
</button>
|
|
|
<!-- #endif -->
|
|
|
</FloatingDrag>
|
|
|
@@ -61,16 +64,12 @@
|
|
|
<view class="indicator" v-if="currentTab === 1"></view>
|
|
|
</view>
|
|
|
</view>
|
|
|
-
|
|
|
+
|
|
|
<!-- Product Detail Content -->
|
|
|
- <ProductContent
|
|
|
- :currentTab="currentTab"
|
|
|
- :product="product"
|
|
|
- :tipsContent="tipsContent"
|
|
|
- :relatedBooksList="relatedBooksList"
|
|
|
- @bookClick="onBookClick">
|
|
|
+ <ProductContent :currentTab="currentTab" :product="product" :tipsContent="tipsContent"
|
|
|
+ :relatedBooksList="relatedBooksList" @bookClick="onBookClick">
|
|
|
</ProductContent>
|
|
|
-
|
|
|
+
|
|
|
<u-gap height="220"></u-gap>
|
|
|
</view>
|
|
|
|
|
|
@@ -79,276 +78,276 @@
|
|
|
|
|
|
<!-- Select Popup -->
|
|
|
<SelectGoodPopup ref="selectPopup" @confirm="onPopupConfirm"></SelectGoodPopup>
|
|
|
-
|
|
|
+
|
|
|
<!-- Share Popup -->
|
|
|
<SharePopup ref="sharePopup" :product="product"></SharePopup>
|
|
|
</view>
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
-import Navbar from '@/components/navbar/navbar.vue'
|
|
|
-import SelectGoodPopup from '../components/select-good-popup/index.vue'
|
|
|
-import InfoCard from '../components/detail/info-card.vue'
|
|
|
-import ServiceCard from '../components/detail/service-card.vue'
|
|
|
-import ProductContent from '../components/detail/product-content.vue'
|
|
|
-import FooterBar from '../components/detail/footer-bar.vue'
|
|
|
-import FloatingDrag from "@/components/floating-drag.vue";
|
|
|
-import SharePopup from '../components/detail/share-popup.vue';
|
|
|
-
|
|
|
-export default {
|
|
|
- components: {
|
|
|
- Navbar,
|
|
|
- SelectGoodPopup,
|
|
|
- InfoCard,
|
|
|
- ServiceCard,
|
|
|
- ProductContent,
|
|
|
- FooterBar,
|
|
|
- FloatingDrag,
|
|
|
- SharePopup
|
|
|
- },
|
|
|
- data() {
|
|
|
- return {
|
|
|
- currentTab: 0,
|
|
|
- hasStock: false, // Toggle this to test stock status
|
|
|
- tipsContent: [
|
|
|
- '印刷版次较多,二手图书封面、版次、原价等信息可能与商品介绍有差异,具体以收到实物为准;',
|
|
|
- '二手图书性质特殊,不保证随新书赠送的光盘、海报、卡片等内容,仅支持图书质量问题退款,否则将扣除运费成本;',
|
|
|
- '收到的图书如有质量问题,请于七天内联系客服处理,超出售后时效,不予处理。'
|
|
|
- ],
|
|
|
- relatedBooksList: [],
|
|
|
- product: {},
|
|
|
- servicePosition: {
|
|
|
- left: "auto",
|
|
|
- right: 0,
|
|
|
- bottom: "300rpx",
|
|
|
- },
|
|
|
- }
|
|
|
- },
|
|
|
- onLoad(options) {
|
|
|
- const isbn = options.isbn || options.id; // Support both just in case
|
|
|
- if (isbn) {
|
|
|
- this.getBookDetail(isbn);
|
|
|
- } else {
|
|
|
- uni.showToast({
|
|
|
- title: '参数错误',
|
|
|
- icon: 'none'
|
|
|
- });
|
|
|
- setTimeout(() => {
|
|
|
- uni.navigateBack();
|
|
|
- }, 1500);
|
|
|
- }
|
|
|
- },
|
|
|
- methods: {
|
|
|
- getBookDetail(isbn) {
|
|
|
- uni.showLoading({ title: '加载中' });
|
|
|
- this.$u.api.getBookDetailAjax({ isbn }).then(res => {
|
|
|
- uni.hideLoading();
|
|
|
- if (res.code === 200) {
|
|
|
- this.product = res.data;
|
|
|
- this.hasStock = res.data.skuList.some(sku => sku.stockNum > 0);
|
|
|
- if (res.data.recommendList) {
|
|
|
- this.relatedBooksList = res.data.recommendList;
|
|
|
- }
|
|
|
- } else {
|
|
|
- uni.showToast({
|
|
|
- title: res.msg || '获取详情失败',
|
|
|
- icon: 'none'
|
|
|
- });
|
|
|
- }
|
|
|
- }).catch(() => {
|
|
|
- uni.hideLoading();
|
|
|
- });
|
|
|
- },
|
|
|
- switchTab(index) {
|
|
|
- this.currentTab = index;
|
|
|
- },
|
|
|
- openSelectPopup() {
|
|
|
- this.$refs.selectPopup.open(this.product);
|
|
|
+ import Navbar from '@/components/navbar/navbar.vue'
|
|
|
+ import SelectGoodPopup from '../components/select-good-popup/index.vue'
|
|
|
+ import InfoCard from '../components/detail/info-card.vue'
|
|
|
+ import ServiceCard from '../components/detail/service-card.vue'
|
|
|
+ import ProductContent from '../components/detail/product-content.vue'
|
|
|
+ import FooterBar from '../components/detail/footer-bar.vue'
|
|
|
+ import FloatingDrag from "@/components/floating-drag.vue";
|
|
|
+ import SharePopup from '../components/detail/share-popup.vue';
|
|
|
+
|
|
|
+ export default {
|
|
|
+ components: {
|
|
|
+ Navbar,
|
|
|
+ SelectGoodPopup,
|
|
|
+ InfoCard,
|
|
|
+ ServiceCard,
|
|
|
+ ProductContent,
|
|
|
+ FooterBar,
|
|
|
+ FloatingDrag,
|
|
|
+ SharePopup
|
|
|
},
|
|
|
- handleNotify() {
|
|
|
- uni.showToast({
|
|
|
- title: '已订阅到货通知',
|
|
|
- icon: 'success'
|
|
|
- });
|
|
|
- },
|
|
|
- onPopupConfirm(data) {
|
|
|
- console.log('Added to cart:', data);
|
|
|
- uni.showToast({
|
|
|
- title: '已加入购物车',
|
|
|
- icon: 'success'
|
|
|
- });
|
|
|
- },
|
|
|
- showServicePopup() {
|
|
|
- // Placeholder for service popup
|
|
|
- },
|
|
|
- onBookClick(book) {
|
|
|
- console.log('Book clicked:', book);
|
|
|
- uni.navigateTo({
|
|
|
- url: '/pages-sell/pages/detail?id=' + encodeURIComponent(book.title)
|
|
|
- });
|
|
|
- },
|
|
|
- openSharePopup() {
|
|
|
- this.$refs.sharePopup.open();
|
|
|
- },
|
|
|
- // 处理位置变更
|
|
|
- handlePositionChange(position) {
|
|
|
- this.servicePosition = position;
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ currentTab: 0,
|
|
|
+ hasStock: false, // Toggle this to test stock status
|
|
|
+ tipsContent: [
|
|
|
+ '印刷版次较多,二手图书封面、版次、原价等信息可能与商品介绍有差异,具体以收到实物为准;',
|
|
|
+ '二手图书性质特殊,不保证随新书赠送的光盘、海报、卡片等内容,仅支持图书质量问题退款,否则将扣除运费成本;',
|
|
|
+ '收到的图书如有质量问题,请于七天内联系客服处理,超出售后时效,不予处理。'
|
|
|
+ ],
|
|
|
+ relatedBooksList: [],
|
|
|
+ product: {},
|
|
|
+ servicePosition: {
|
|
|
+ left: "auto",
|
|
|
+ right: 0,
|
|
|
+ bottom: "300rpx",
|
|
|
+ },
|
|
|
+ }
|
|
|
},
|
|
|
- //支付宝小程序的客服
|
|
|
- navigateToCustomerService() {
|
|
|
- uni.navigateTo({
|
|
|
- url: "/pages-mine/pages/customer-service",
|
|
|
- });
|
|
|
+ onLoad(options) {
|
|
|
+ const isbn = options.isbn || options.id; // Support both just in case
|
|
|
+ if (isbn) {
|
|
|
+ this.getBookDetail(isbn);
|
|
|
+ } else {
|
|
|
+ uni.showToast({
|
|
|
+ title: '参数错误',
|
|
|
+ icon: 'none'
|
|
|
+ });
|
|
|
+ setTimeout(() => {
|
|
|
+ uni.navigateBack();
|
|
|
+ }, 1500);
|
|
|
+ }
|
|
|
},
|
|
|
+ methods: {
|
|
|
+ getBookDetail(isbn) {
|
|
|
+ uni.showLoading({ title: '加载中' });
|
|
|
+ this.$u.api.getBookDetailAjax({ isbn }).then(res => {
|
|
|
+ uni.hideLoading();
|
|
|
+ if (res.code === 200) {
|
|
|
+ this.product = res.data;
|
|
|
+ this.hasStock = res.data.skuList.some(sku => sku.stockNum > 0);
|
|
|
+ if (res.data.recommendList) {
|
|
|
+ this.relatedBooksList = res.data.recommendList;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ uni.showToast({
|
|
|
+ title: res.msg || '获取详情失败',
|
|
|
+ icon: 'none'
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }).catch(() => {
|
|
|
+ uni.hideLoading();
|
|
|
+ });
|
|
|
+ },
|
|
|
+ switchTab(index) {
|
|
|
+ this.currentTab = index;
|
|
|
+ },
|
|
|
+ openSelectPopup(sourceFrom) {
|
|
|
+ this.$refs.selectPopup.open(this.product, sourceFrom);
|
|
|
+ },
|
|
|
+ handleNotify() {
|
|
|
+ uni.showToast({
|
|
|
+ title: '已订阅到货通知',
|
|
|
+ icon: 'success'
|
|
|
+ });
|
|
|
+ },
|
|
|
+ onPopupConfirm(data) {
|
|
|
+ console.log('Added to cart:', data);
|
|
|
+ uni.showToast({
|
|
|
+ title: '已加入购物车',
|
|
|
+ icon: 'success'
|
|
|
+ });
|
|
|
+ },
|
|
|
+ showServicePopup() {
|
|
|
+ // Placeholder for service popup
|
|
|
+ },
|
|
|
+ onBookClick(book) {
|
|
|
+ console.log('Book clicked:', book);
|
|
|
+ uni.navigateTo({
|
|
|
+ url: '/pages-sell/pages/detail?id=' + encodeURIComponent(book.title)
|
|
|
+ });
|
|
|
+ },
|
|
|
+ openSharePopup() {
|
|
|
+ this.$refs.sharePopup.open();
|
|
|
+ },
|
|
|
+ // 处理位置变更
|
|
|
+ handlePositionChange(position) {
|
|
|
+ this.servicePosition = position;
|
|
|
+ },
|
|
|
+ //支付宝小程序的客服
|
|
|
+ navigateToCustomerService() {
|
|
|
+ uni.navigateTo({
|
|
|
+ url: "/pages-mine/pages/customer-service",
|
|
|
+ });
|
|
|
+ },
|
|
|
+ }
|
|
|
}
|
|
|
-}
|
|
|
</script>
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
-.detail-page {
|
|
|
- min-height: 100vh;
|
|
|
- background-color: #f5f5f5;
|
|
|
- position: relative;
|
|
|
- padding-bottom: 100rpx;
|
|
|
-}
|
|
|
-
|
|
|
-.header-bg {
|
|
|
- position: absolute;
|
|
|
- top: 0;
|
|
|
- left: 0;
|
|
|
- width: 100%;
|
|
|
- height: 664rpx;
|
|
|
- background: linear-gradient(0deg, #4ED868 0%, #D1FFE5 100%);
|
|
|
- z-index: 0;
|
|
|
-}
|
|
|
-
|
|
|
-.notification-bar {
|
|
|
- position: fixed;
|
|
|
- top: 180rpx;
|
|
|
- /* Adjust based on navbar height */
|
|
|
- left: 30rpx;
|
|
|
- z-index: 10;
|
|
|
- background: rgba(0, 0, 0, 0.3);
|
|
|
- border-radius: 30rpx;
|
|
|
- padding: 6rpx 20rpx 6rpx 6rpx;
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
-
|
|
|
- .notif-text {
|
|
|
- font-size: 24rpx;
|
|
|
- color: #fff;
|
|
|
- margin-left: 10rpx;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-.content-scroll {
|
|
|
- position: relative;
|
|
|
- z-index: 1;
|
|
|
- height: 100vh;
|
|
|
-}
|
|
|
-
|
|
|
-.cover-area {
|
|
|
- position: relative;
|
|
|
- display: flex;
|
|
|
- justify-content: center;
|
|
|
- padding-top: 60rpx;
|
|
|
- padding-bottom: 40rpx;
|
|
|
-
|
|
|
- .book-cover {
|
|
|
- width: 360rpx;
|
|
|
- height: 360rpx;
|
|
|
- box-shadow: 0 10rpx 20rpx rgba(0, 0, 0, 0.1);
|
|
|
+ .detail-page {
|
|
|
+ min-height: 100vh;
|
|
|
+ background-color: #f5f5f5;
|
|
|
+ position: relative;
|
|
|
+ padding-bottom: 100rpx;
|
|
|
}
|
|
|
|
|
|
- .share-btn {
|
|
|
+ .header-bg {
|
|
|
position: absolute;
|
|
|
- right: 50rpx;
|
|
|
- top: 50rpx;
|
|
|
+ top: 0;
|
|
|
+ left: 0;
|
|
|
+ width: 100%;
|
|
|
+ height: 664rpx;
|
|
|
+ background: linear-gradient(0deg, #4ED868 0%, #D1FFE5 100%);
|
|
|
+ z-index: 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ .notification-bar {
|
|
|
+ position: fixed;
|
|
|
+ top: 180rpx;
|
|
|
+ /* Adjust based on navbar height */
|
|
|
+ left: 30rpx;
|
|
|
+ z-index: 10;
|
|
|
+ background: rgba(0, 0, 0, 0.3);
|
|
|
+ border-radius: 30rpx;
|
|
|
+ padding: 6rpx 20rpx 6rpx 6rpx;
|
|
|
display: flex;
|
|
|
- flex-direction: column;
|
|
|
align-items: center;
|
|
|
- z-index: 10; // Ensure it's clickable
|
|
|
|
|
|
- .share-icon {
|
|
|
- width: 40rpx;
|
|
|
- height: 40rpx;
|
|
|
- margin-bottom: 4rpx;
|
|
|
+ .notif-text {
|
|
|
+ font-size: 24rpx;
|
|
|
+ color: #fff;
|
|
|
+ margin-left: 10rpx;
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- text {
|
|
|
- font-size: 20rpx;
|
|
|
- color: #333;
|
|
|
- }
|
|
|
+ .content-scroll {
|
|
|
+ position: relative;
|
|
|
+ z-index: 1;
|
|
|
+ height: 100vh;
|
|
|
}
|
|
|
-}
|
|
|
|
|
|
-.banner-area {
|
|
|
- background: #f5f5f5;
|
|
|
- padding: 20rpx;
|
|
|
+ .cover-area {
|
|
|
+ position: relative;
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ padding-top: 60rpx;
|
|
|
+ padding-bottom: 40rpx;
|
|
|
+
|
|
|
+ .book-cover {
|
|
|
+ width: 360rpx;
|
|
|
+ height: 360rpx;
|
|
|
+ box-shadow: 0 10rpx 20rpx rgba(0, 0, 0, 0.1);
|
|
|
+ }
|
|
|
|
|
|
- .banner-img {
|
|
|
- width: 100%;
|
|
|
- border-radius: 20rpx;
|
|
|
+ .share-btn {
|
|
|
+ position: absolute;
|
|
|
+ right: 50rpx;
|
|
|
+ top: 50rpx;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ align-items: center;
|
|
|
+ z-index: 10; // Ensure it's clickable
|
|
|
+
|
|
|
+ .share-icon {
|
|
|
+ width: 40rpx;
|
|
|
+ height: 40rpx;
|
|
|
+ margin-bottom: 4rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ text {
|
|
|
+ font-size: 20rpx;
|
|
|
+ color: #333;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
-}
|
|
|
-
|
|
|
-.service-btn {
|
|
|
- padding: 0;
|
|
|
- margin: 0;
|
|
|
- background-color: transparent;
|
|
|
- line-height: 1;
|
|
|
- border-radius: 0;
|
|
|
-
|
|
|
- &::after {
|
|
|
- border: none;
|
|
|
+
|
|
|
+ .banner-area {
|
|
|
+ background: #f5f5f5;
|
|
|
+ padding: 20rpx;
|
|
|
+
|
|
|
+ .banner-img {
|
|
|
+ width: 100%;
|
|
|
+ border-radius: 20rpx;
|
|
|
+ }
|
|
|
}
|
|
|
-}
|
|
|
-
|
|
|
-.tabs-header {
|
|
|
- display: flex;
|
|
|
- justify-content: center;
|
|
|
- /* Center the tabs */
|
|
|
- background: #F8F8F8;
|
|
|
- padding: 20rpx 0;
|
|
|
- /* Remove horizontal padding as we center items */
|
|
|
-
|
|
|
- .tab-item {
|
|
|
- padding: 0 30rpx;
|
|
|
- /* Add internal padding for hit area */
|
|
|
- position: relative;
|
|
|
|
|
|
- text {
|
|
|
- font-family: 'Source Han Sans SC';
|
|
|
- font-size: 30rpx;
|
|
|
- /* Assuming 30px from design tool = 30rpx */
|
|
|
- color: #666666;
|
|
|
- transition: all 0.3s;
|
|
|
+ .service-btn {
|
|
|
+ padding: 0;
|
|
|
+ margin: 0;
|
|
|
+ background-color: transparent;
|
|
|
+ line-height: 1;
|
|
|
+ border-radius: 0;
|
|
|
+
|
|
|
+ &::after {
|
|
|
+ border: none;
|
|
|
}
|
|
|
+ }
|
|
|
+
|
|
|
+ .tabs-header {
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ /* Center the tabs */
|
|
|
+ background: #F8F8F8;
|
|
|
+ padding: 20rpx 0;
|
|
|
+ /* Remove horizontal padding as we center items */
|
|
|
+
|
|
|
+ .tab-item {
|
|
|
+ padding: 0 30rpx;
|
|
|
+ /* Add internal padding for hit area */
|
|
|
+ position: relative;
|
|
|
|
|
|
- &.active {
|
|
|
text {
|
|
|
+ font-family: 'Source Han Sans SC';
|
|
|
font-size: 30rpx;
|
|
|
- /* Keep consistent size or adjust if 'big' effect needed, user said 30px */
|
|
|
- font-weight: bold;
|
|
|
- color: #333333;
|
|
|
+ /* Assuming 30px from design tool = 30rpx */
|
|
|
+ color: #666666;
|
|
|
+ transition: all 0.3s;
|
|
|
}
|
|
|
|
|
|
- .indicator {
|
|
|
- position: absolute;
|
|
|
- bottom: 2rpx;
|
|
|
- /* Adjust vertical position */
|
|
|
- left: 50%;
|
|
|
- transform: translateX(-50%);
|
|
|
- width: 120rpx;
|
|
|
- /* Make it wider or relative to text? Usually fixed or text width. Let's try matching text width visually or a fixed width */
|
|
|
- height: 8rpx;
|
|
|
- /* Slightly thicker for gradient visibility */
|
|
|
- background: linear-gradient(90deg, rgba(78, 217, 100, 0.1) 0%, #4ED964 100%);
|
|
|
- border-radius: 4rpx;
|
|
|
+ &.active {
|
|
|
+ text {
|
|
|
+ font-size: 30rpx;
|
|
|
+ /* Keep consistent size or adjust if 'big' effect needed, user said 30px */
|
|
|
+ font-weight: bold;
|
|
|
+ color: #333333;
|
|
|
+ }
|
|
|
+
|
|
|
+ .indicator {
|
|
|
+ position: absolute;
|
|
|
+ bottom: 2rpx;
|
|
|
+ /* Adjust vertical position */
|
|
|
+ left: 50%;
|
|
|
+ transform: translateX(-50%);
|
|
|
+ width: 120rpx;
|
|
|
+ /* Make it wider or relative to text? Usually fixed or text width. Let's try matching text width visually or a fixed width */
|
|
|
+ height: 8rpx;
|
|
|
+ /* Slightly thicker for gradient visibility */
|
|
|
+ background: linear-gradient(90deg, rgba(78, 217, 100, 0.1) 0%, #4ED964 100%);
|
|
|
+ border-radius: 4rpx;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
-}
|
|
|
|
|
|
|
|
|
</style>
|