Files
sociology_app/pages/bookShop/commodityDetail copy.vue
2025-03-19 09:41:42 +08:00

857 lines
22 KiB
Vue
Raw Permalink 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="">
<view class="header">
<!-- 顶部导航栏 -->
<z-nav-bar title="商品详情" bgColor="red"></z-nav-bar>
</view>
<view class="swiperBox">
<swiper
:indicator-dots="true"
:autoplay="true"
:interval="3000"
:duration="1000"
style="width: 100%; height: 100%"
>
<swiper-item
v-for="(item, index) in swiperlist"
:key="index"
style="width: 100%; height: 100%"
>
<image
:src="item"
mode="scaleToFill"
style="width: 100%; height: 100%"
></image>
</swiper-item>
</swiper>
</view>
<view class="commodityContent">
<view class="commodityPrice">
<span></span><em>{{ productInfo.price }}</em>
<span class="oldPrice" v-if="productInfo.activityPrice"
>原价{{ productInfo.activityPrice }}</span
>
</view>
<view class="commodityyName">
{{ productInfo.productName }}
<span
v-if="productInfo.productStock == 0"
style="color: #aaa; font-size: 26rpx"
>无货</span
>
<view
><text class="SoldNumber"
>已售<span>{{ productInfo.sumSales }}</span
></text
></view
>
</view>
<view class="contentButton">
<u-tabs
:scrollable="false"
:list="contentButtonList"
@click="contentButtonClick"
></u-tabs>
</view>
<!-- 详情 + 评价1 -->
<view v-if="contentShow == 0">
<view class="tingshuList" v-if="listenList.length > 0">
<h4>赠送听书权益</h4>
<view
class="item flexbox"
v-for="item in listenList"
:key="item.id"
style="vertical-align: middle"
>
<text style="margin-top: 10rpx; padding-right: 10rpx">{{
item.name
}}</text>
<u-icon
v-if="item.canListen == 'true'"
name="volume"
color="#71d5a1"
size="24"
@click="goToListen(item.id)"
></u-icon>
<u-icon
v-else
name="volume"
color="#71d5a1"
size="24"
@click="goToListenNone(item.id)"
></u-icon>
</view>
</view>
<view class="bookInfo">
<u-row customStyle="margin-bottom: 10px">
<u-col
><span>书名{{ productInfo.productName }}</span></u-col
>
</u-row>
<u-row customStyle="margin-bottom: 10px">
<u-col v-if="productInfo.author"
><span>作者{{ productInfo.author }}</span></u-col
>
</u-row>
<u-row>
<u-col span="6" v-if="productInfo.publisher"
><span>出版社{{ productInfo.publisher }}</span></u-col
>
<u-col span="6" v-if="productInfo.pubDate"
><span
>出版时间{{ productInfo.pubDate | formatDate }}</span
></u-col
>
</u-row>
<u-row>
<u-col span="6" v-if="productInfo.format"
><span>开本{{ productInfo.format }}</span></u-col
>
<u-col span="6" v-if="productInfo.pageNum"
><span>页数{{ productInfo.pageNum }}</span></u-col
>
</u-row>
<u-row>
<u-col span="6" v-if="productInfo.quality"
><span>内文用纸材质{{ productInfo.quality }}</span></u-col
>
</u-row>
</view>
<!-- <view class="commodityIntroduce" v-html="productInfo.productDetails"> -->
<view class="commodityIntroduce">
<view v-if="productInfo.productDetails">
<rich-text
v-if="productInfo.productDetails"
class="xiangqing"
:nodes="productInfo.productDetails | formatRichText"
></rich-text>
</view>
</view>
</view>
<view v-else>
<!-- 商品评价 -->
<view class="" v-if="commentsList && commentsList.length > 0">
<view
class="pingjiaBox"
v-for="(item, index) in commentsList"
:key="index"
>
<view class="flexbox">
<view class="touxiang">
<image :src="item.avatar" mode="aspectFit"></image>
<text class="username nowrap">{{ item.name }}</text>
</view>
<view class="contentBox">
<view class="mb30">
<span
:class="[
'star',
item.starlevel >= 1 ? 'starLight' : 'starGray',
]"
></span>
<span
:class="[
'star',
item.starlevel >= 2 ? 'starLight' : 'starGray',
]"
></span>
<span
:class="[
'star',
item.starlevel >= 3 ? 'starLight' : 'starGray',
]"
></span>
<span
:class="[
'star',
item.starlevel >= 4 ? 'starLight' : 'starGray',
]"
></span>
<span
:class="[
'star',
item.starlevel >= 5 ? 'starLight' : 'starGray',
]"
></span>
</view>
<div class="pjimgs flexbox">
<view class="item" v-for="(item1, index) in item.images">
<image
v-if="item1.length > 10"
@click="previewImage(item1)"
:src="item1"
mode="aspectFill"
style="width: 100%; height: 50px"
></image>
</view>
</div>
<view class="content" v-html="item.phtml"></view>
<text class="time">{{ item.createdate }}</text>
</view>
</view>
<!-- 显示追平 -->
<view
class="zhuiping item"
v-if="item.zphtml != ''"
style="padding-left: 50px"
>
<h5 style="color: #dbdbdb; margin: 10px">追评内容</h5>
<view class="flexbox">
<view class="contentBox">
<view class="content" v-html="item.zphtml"></view>
<text class="time">{{ item.followUpdate }}</text>
</view>
</view>
</view>
</view>
</view>
<view class="quesheng" v-else>
<text>暂无评价~</text>
</view>
</view>
<view style="height: 120rpx"></view>
</view>
<uni-goods-nav
class="goods_nav"
:fill="true"
:options="options"
:buttonGroup="buttonGroup"
@click="onClick"
@buttonClick="buttonClick"
/>
<music-play :playData="playData"></music-play>
</view>
</template>
<script>
import musicPlay from "@/components/music.vue";
import emojiList1 from "../../bkhumor-emojiplus/emoji/biaoqin.js";
import $http from "@/config/requestConfig.js";
import { mapState } from "vuex";
import loginVue from "../user/login.vue";
export default {
data() {
return {
playData: {},
contentShow: 0,
options: [
{
icon: "cart",
text: "购物车",
},
],
buttonGroup: [
{
text: "加入购物车",
backgroundColor: "linear-gradient(90deg, #FFCD1E, #FF8A18)",
color: "#fff",
},
{
text: "立即购买",
backgroundColor: "linear-gradient(90deg, #FE6035, #EF1224)",
color: "#fff",
},
],
contentButtonList: [
{
name: "商品详情",
},
{
name: "商品评价",
},
],
// 轮播图数据
swiperlist: [],
// 商品详情数据
productInfo: {},
productAmount: 1, // 商品数量
cartList: [], // 购物车列表
commentsList: [], // 评论列表
productId: null, // 商品评论
listenList: [], // 关联得听书
};
},
onLoad(e) {
this.productId = e.id;
this.getProDetail(e);
this.getComments();
// console.log(emojiList1,'emojiList1')
},
computed: {
...mapState(["userInfo"]),
},
components: {
musicPlay,
},
methods: {
goToListen(id) {
// 跳转到听书
uni.navigateTo({
url: "../listen/listen?bookid=" + id,
});
},
// 放大图片
previewImage(url) {
console.log(url);
uni.previewImage({
urls: [url],
});
},
// 获取html格式的评论1
getHtmlComment(comment) {
// 格式化html
// console.log(comment,'comment')
// 这里处理 链接 换行符
let replacedStr = comment.replace(/\[([^(\]|\[)]*)\]/g, (item, index) => {
// console.log(item, index)
var indexss = emojiList1.findIndex((item1) => item1.alt === item);
// console.log(indexss, 'indexss')
return (
'<img src="https://www.nuttyreading.com/emojis/emojis/qq/' +
emojiList1[indexss].url +
'" width="18rpx">'
);
});
// console.log(replacedStr,'replacedStr')
return replacedStr.replace(/(\r\n)|(\n)/g, "<br>");
},
// 获取评价
getComments() {
$http
.request({
url: "buy/record/All",
method: "POST", // POST、GET、PUT、DELETE具体说明查看官方文档1
data: {
bookid: this.productId,
},
header: {
//默认 无 说明:请求头
"Content-Type": "application/json",
},
})
.then((res) => {
if (res.code == 0) {
console.log(res.list, "res.list");
this.commentsList = res.list.map((item) => {
var imgList = [];
if (item.images !== null) {
imgList = item.images.split(",");
item.images = imgList;
return item;
} else {
return item;
}
});
// 评论格式化
var newarr = [];
this.commentsList.forEach((item1) => {
var pjstr = "";
var zpstr = "";
pjstr = this.getHtmlComment(item1.content);
item1.followUpcontent == ""
? (zpstr = "")
: (zpstr = this.getHtmlComment(item1.followUpcontent));
//console.log(pjstr,'99999999999----------')
item1.phtml = pjstr;
item1.zphtml = zpstr;
newarr.push(item1);
});
this.commentsList = newarr;
// console.log(this.commentsList,'评价+++++')
// this.commentsList = res.list
}
});
},
getProDetail(e) {
// 获取商品详情
uni.showLoading({
title: "加载中",
});
console.log(e.id, "e.id");
this.$http.post("/book/shopproduct/info/" + e.id).then((res) => {
console.log("shopproduct", res);
this.productInfo = res.shopProduct;
this.listenList = res.shopProduct.bookidsimages;
if (
this.productInfo.productImageList == null ||
this.productInfo.productImageList == ""
) {
this.swiperlist.push(this.productInfo.productImages);
} else {
let imgList = this.productInfo.productImageList.split(",");
// if(this.productInfo.productDetails != null){
// let info = this.formatRichText(this.productInfo.productDetails)
// }
// this.productInfo.productDetails = info
for (var i = 0; i < imgList.length; i++) {
this.swiperlist.push(imgList[i]);
}
}
uni.hideLoading();
});
},
contentButtonClick(e) {
this.contentShow = e.index;
},
// 点击购物车
onClick(e) {
console.log(e.content.text);
uni.switchTab({
url: "../peanut/shopping",
});
},
// 点击按钮组间
buttonClick(e) {
console.log(e);
if (e.index == 0) {
// 点击的是加入购物车
this.addCart();
} else {
// 点击的是立即购买
this.goPurse();
}
},
goToListenNone() {
uni.showToast({
title: "该书暂未生成音频内容,敬请期待!",
icon: "none",
});
},
// 加入购物车
addCart() {
if (this.productInfo.productStock == 0) {
uni.showToast({
title: "商品库存不足",
icon: "none",
duration: 1000,
});
} else {
this.$http
.post(`book/ordercart/getCartList?userId=${this.userInfo.id}`)
.then((res) => {
this.cartList = res.cartList;
this.isAdd();
});
}
},
isAdd() {
// 统计商品信息
let data = {
userId: this.userInfo.id,
productId: this.productInfo.productId,
productAmount: this.productAmount,
price: this.productInfo.price,
};
// 判断列表是否为空
if (this.cartList.length > 0) {
let flag = "";
let shagnpin = {};
// 循环购物车列表
flag = this.cartList.some((item, index) => {
if (item.productId == data.productId) {
shagnpin = item;
shagnpin.productAmount = item.productAmount + 1;
return true;
}
});
if (flag) {
// 已在购物车中添加
$http
.request({
url: "book/ordercart/update",
method: "POST", // POST、GET、PUT、DELETE具体说明查看官方文档
data: shagnpin,
header: {
//默认 无 说明:请求头
"Content-Type": "application/json",
},
})
.then((res) => {
if (res.code == 0) {
uni.showToast({
title: "加入购物车成功",
duration: 1000,
});
}
});
} else {
// 加入购物车
$http
.request({
url: "book/ordercart/save",
method: "POST", // POST、GET、PUT、DELETE具体说明查看官方文档
data,
header: {
//默认 无 说明:请求头
"Content-Type": "application/json",
},
})
.then((res) => {
if (res.code == 0) {
uni.showToast({
title: "加入购物车成功",
duration: 1000,
});
}
});
}
} else {
// 购物车列表为空时直接加入购物车
$http
.request({
url: "book/ordercart/save",
method: "POST", // POST、GET、PUT、DELETE具体说明查看官方文档
data,
header: {
//默认 无 说明:请求头
"Content-Type": "application/json",
},
})
.then((res) => {
if (res.code == 0) {
uni.showToast({
title: "加入购物车成功",
duration: 1000,
});
}
});
}
},
// 购买下单
goPurse() {
if (this.productInfo.productStock == 0) {
uni.showToast({
title: "商品库存不足",
icon: "none",
duration: 1000,
});
} else {
uni.navigateTo({
url:
"../bookShop/settlement?type=2&list=" + this.productInfo.productId,
});
}
},
formatRichText(html) {
//控制小程序中图片大小
let newContent = html.replace(/<img[^>]*>/gi, function (match, capture) {
match = match
.replace(/style="[^"]+"/gi, "")
.replace(/style='[^']+'/gi, "");
match = match
.replace(/width="[^"]+"/gi, "")
.replace(/width='[^']+'/gi, "");
match = match
.replace(/height="[^"]+"/gi, "")
.replace(/height='[^']+'/gi, "");
return match;
});
newContent = newContent.replace(
/style="[^"]+"/gi,
function (match, capture) {
match = match
.replace(/width:[^;]+;/gi, "max-width:100%;")
.replace(/width:[^;]+;/gi, "max-width:100%;");
return match;
},
);
newContent = newContent.replace(/<br[^>]*\/>/gi, "");
newContent = newContent.replace(
/\<img/gi,
'<img style="max-width:100%;height:auto;display:inline-block;margin:10rpx auto;"',
);
return newContent;
},
// 去购物车
goCard() {
uni.switchTab({
url: "../peanut/shopping",
});
},
},
filters: {
/**
* 处理富文本里的图片宽度自适应
* 1.去掉img标签里的style、width、height属性
* 2.img标签添加style属性max-width:100%;height:auto
* 3.修改所有style里的width属性为max-width:100%
* 4.去掉<br/>标签
* @param html
* @returns {void|string|*}
*/
formatRichText(html) {
//控制小程序中图片大小
let newContent = html.replace(/<img[^>]*>/gi, function (match, capture) {
match = match
.replace(/style="[^"]+"/gi, "")
.replace(/style='[^']+'/gi, "");
match = match
.replace(/width="[^"]+"/gi, "")
.replace(/width='[^']+'/gi, "");
match = match
.replace(/height="[^"]+"/gi, "")
.replace(/height='[^']+'/gi, "");
return match;
});
newContent = newContent.replace(
/style="[^"]+"/gi,
function (match, capture) {
match = match
.replace(/width:[^;]+;/gi, "max-width:100%;")
.replace(/width:[^;]+;/gi, "max-width:100%;");
return match;
},
);
newContent = newContent.replace(/<br[^>]*\/>/gi, "");
newContent = newContent.replace(
/\<img/gi,
'<img style="max-width:100%;height:auto;display:inline-block;margin:10rpx auto;"',
);
return newContent;
},
// 时间格式化
formatDate(date) {
console.log(date);
let newDate = new Date(date);
let year = newDate.getFullYear();
let month = newDate.getMonth().toString().padStart(2, 0);
let day = newDate.getDay().toString().padStart(2, 0);
return year + "-" + month + "-" + day;
},
},
};
</script>
<style lang="scss" scoped>
.tingshuList {
margin-top: 20rpx;
background-color: #fff;
padding: 20rpx;
border-radius: 20rpx;
margin-bottom: 20rpx;
padding-top: 40rpx;
background-image: linear-gradient(0deg, #f7fffc 0%, #def0ea 100%);
.item {
margin-bottom: 20rpx;
vertical-align: middle;
}
h4 {
color: #5fb386;
font-size: 40rpx;
margin-bottom: 20rpx;
}
text {
color: #444;
font-size: 32rpx;
padding-left: 20rpx;
}
}
.pjimgs {
margin: 10px 0;
flex-wrap: wrap;
display: flex;
justify-content: space-between;
.item {
width: 23%;
margin-right: 10px;
image {
}
}
}
.star {
display: inline-block;
width: 20px;
height: 20px;
margin-right: 10rpx;
}
.starGray {
background: url(../../static/icon/star_greey.png) no-repeat;
background-size: contain;
}
.starLight {
background: url(../../static/icon/star_light.png) no-repeat;
background-size: contain;
}
.quesheng {
text-align: center;
margin-top: 100rpx;
color: #8b8a91;
}
.pingjiaBox {
color: #555;
margin-bottom: 20rpx;
}
.flexbox {
display: flex;
}
.contentBox {
width: calc(100% - 50px);
box-sizing: border-box;
padding-left: 20rpx;
.content {
font-size: 28rpx;
line-height: 40rpx;
}
.time {
font-size: 24rpx;
color: #999;
margin-top: 6rpx;
float: right;
}
}
.nowrap {
white-space: nowrap;
overflow-x: hidden;
text-overflow: ellipsis;
}
.touxiang {
width: 50px;
overflow: hidden;
text-align: center;
image {
width: 50px !important;
padding: 3px;
height: 50px !important;
border: 1px solid #eee;
border-radius: 64px;
overflow: hidden;
}
.username {
font-size: 24rpx;
color: #999;
margin-top: 6rpx;
}
}
.xiangqing {
overflow: hidden;
overflow-x: hidden;
img {
display: block;
max-width: 100%;
}
p {
max-width: 100%;
}
}
.goods_nav {
z-index: 1;
position: fixed;
bottom: 0;
width: 100%;
}
.SoldNumber {
font-size: 24rpx;
color: #999;
margin-top: 16rpx;
}
.bookInfo {
padding: 20px 10px;
line-height: 30rpx;
background-color: #fff;
font-size: 26rpx;
color: #555;
border-radius: 20rpx 20rpx 0 0;
}
.header {
position: fixed;
top: 0%;
left: 0%;
z-index: 999;
}
.contentButton {
margin: 10px 0;
}
.swiperBox {
width: 100%;
height: 375px;
margin-top: 150rpx;
}
.commodityContent {
margin: 30rpx 20rpx 10rpx 20rpx;
height: auto;
.commodityPrice {
background-image: linear-gradient(0deg, #f7fffc 0%, #def0ea 100%);
border-top: 1px solid #fff;
// background-color: #f7faf9;
border-top-left-radius: 20rpx;
border-top-right-radius: 20rpx;
color: #ffa200;
padding: 20rpx 20rpx 40rpx 20rpx;
em {
font-size: 74rpx;
font-style: normal;
}
.oldPrice {
margin-left: 10rpx;
font-size: 32rpx;
color: #999;
}
}
.commodityyName {
margin-top: -20rpx;
padding: 30rpx 20rpx 40rpx 20rpx;
font-size: 40rpx;
border-top-left-radius: 20rpx;
border-top-right-radius: 20rpx;
background-color: #fff;
}
.commodityIntroduce {
font-size: 30rpx;
background-color: #fff;
padding: 0 20rpx 30rpx 20rpx;
}
}
.footer {
width: 100%;
height: 100rpx;
background-color: #fff;
display: flex;
justify-content: space-between;
align-items: center;
position: fixed;
bottom: 0%;
.shopcard {
margin: 0 0 0 30rpx;
text-align: center;
font-size: 20rpx;
color: #eba00b;
}
.operate {
display: flex;
view {
font-size: 32rpx;
font-weight: 700;
color: #fff;
padding: 32rpx 40rpx;
letter-spacing: 0.8px;
}
.addShopCar {
background-color: #eba00b;
}
.goBuy {
background-color: #cf3906;
}
}
}
</style>