605 lines
12 KiB
Vue
605 lines
12 KiB
Vue
<script setup>
|
||
/**
|
||
* 商品详情
|
||
*/
|
||
|
||
import {
|
||
ref,
|
||
reactive,
|
||
nextTick,
|
||
getCurrentInstance,
|
||
computed,
|
||
onMounted,
|
||
onUnmounted,
|
||
defineProps,
|
||
} from 'vue'
|
||
import {
|
||
useStore
|
||
} from 'vuex'
|
||
// 接口地址
|
||
import api from '@/api/index.js'
|
||
//
|
||
import util from '@/common/js/util.js'
|
||
|
||
// 传参
|
||
const props = defineProps({
|
||
id: {
|
||
type: [Number, String],
|
||
default: ''
|
||
},
|
||
detail: {
|
||
type: Object,
|
||
default: {}
|
||
},
|
||
})
|
||
|
||
const {
|
||
proxy
|
||
} = getCurrentInstance()
|
||
// 在这里设置swiper高度补足多端差异
|
||
const bannerHeight = ref('800rpx')
|
||
// 轮播图详情
|
||
const bannerIndex = ref(0)
|
||
// 商品评论
|
||
const comment = reactive({
|
||
list: [],
|
||
total: 0,
|
||
})
|
||
// 最近购买订单列表
|
||
const recentOrderList = ref([])
|
||
//
|
||
const menuFn = {
|
||
// 店铺
|
||
store() {
|
||
link('/pages/shop/store/index')
|
||
},
|
||
// 客服
|
||
customerService() {
|
||
link('/pages/news/question-answer/index')
|
||
},
|
||
// 收藏
|
||
heibianStar() {
|
||
//
|
||
}
|
||
}
|
||
// 已选择的规格下标
|
||
const spaceIndex = ref(0)
|
||
// 数量
|
||
const payNum = ref(1)
|
||
// 当前选择的规格
|
||
const currentSpec = computed(() => {
|
||
let spec = props.detail.specs || []
|
||
return spec[spaceIndex.value] || {}
|
||
})
|
||
// 应付总价
|
||
const total = computed(() => {
|
||
let price = parseFloat(props.detail.price) * 100
|
||
let result = parseInt(price * payNum.value) / 100
|
||
return result
|
||
})
|
||
// 详情
|
||
const banner = computed(() => {
|
||
let result = []
|
||
if (props.detail.sliderImage) result = props.detail.sliderImage.split(',')
|
||
return result
|
||
})
|
||
// 当前登录的用户信息
|
||
const userinfo = computed(() => {
|
||
return uni.$store.state.userinfo
|
||
})
|
||
|
||
onMounted(() => {
|
||
// 获取商品评论
|
||
getProComment()
|
||
// 获取最近购买
|
||
getRecentOrder()
|
||
})
|
||
|
||
|
||
// 获取最近购买
|
||
function getRecentOrder() {
|
||
api.shop.recentOrder({
|
||
query: {
|
||
// 产品id
|
||
productId: props.id,
|
||
}
|
||
}).then(rs => {
|
||
if (rs.code == 200) {
|
||
// 结果
|
||
const result = rs.data
|
||
let list = []
|
||
//
|
||
for (let i = 0; i < result.length / 2; i++) {
|
||
if (!result[i * 2 + 1]) break
|
||
list.push([result[i * 2], result[i * 2 + 1]])
|
||
}
|
||
recentOrderList.value = list
|
||
return
|
||
}
|
||
util.alert({
|
||
content: rs.msg,
|
||
showCancel: false,
|
||
})
|
||
})
|
||
}
|
||
|
||
// 获取商品评论
|
||
function getProComment() {
|
||
api.shop.getProComment({
|
||
query: {
|
||
// 产品id
|
||
productId: props.id,
|
||
pageNum: 1,
|
||
pageSize: 2,
|
||
}
|
||
}).then(rs => {
|
||
if (rs.code == 200) {
|
||
comment.list = rs.rows
|
||
comment.total = rs.total
|
||
return
|
||
}
|
||
util.alert({
|
||
content: rs.msg,
|
||
showCancel: false,
|
||
})
|
||
})
|
||
}
|
||
|
||
/**
|
||
* 跳转路径
|
||
* @param {Object} url
|
||
*/
|
||
function link(url) {
|
||
uni.navigateTo({
|
||
url,
|
||
})
|
||
}
|
||
|
||
// 收藏店铺
|
||
function handleCollectStore() {
|
||
api.shop.followShop({
|
||
data: {
|
||
shopId: props.detail.merId,
|
||
status: {
|
||
0: 1,
|
||
1: 0,
|
||
} [props.detail.isFollow]
|
||
}
|
||
}).then(rs => {
|
||
if (rs.code == 200) {
|
||
// 关注状态
|
||
props.detail.isFollow = {
|
||
0: 1,
|
||
1: 0,
|
||
} [props.detail.isFollow]
|
||
// 关注数量
|
||
props.detail.merFollowNumber = rs.data
|
||
return
|
||
}
|
||
util.alert({
|
||
content: rs.msg,
|
||
showCancel: false,
|
||
})
|
||
})
|
||
}
|
||
|
||
// 商品收藏
|
||
function handleCollect() {
|
||
util.isLogin().then(rs => {
|
||
//
|
||
api.shop.addProductCollect({
|
||
data: {
|
||
productId: id.value,
|
||
status: {
|
||
0: 1,
|
||
1: 0,
|
||
} [props.detail.isCollect]
|
||
}
|
||
}).then(rs => {
|
||
if (rs.code == 200) {
|
||
// 关注状态
|
||
props.detail.isCollect = {
|
||
0: 1,
|
||
1: 0,
|
||
} [props.detail.isCollect]
|
||
// 关注数量
|
||
props.detail.collectNumber = rs.data
|
||
return
|
||
}
|
||
util.alert({
|
||
content: rs.msg,
|
||
showCancel: false,
|
||
})
|
||
})
|
||
}).catch(() => {
|
||
// 登录
|
||
uni.navigateTo({
|
||
url: '/pages/login/loginPhone'
|
||
})
|
||
})
|
||
}
|
||
|
||
// 获取店铺信息
|
||
function getShop() {
|
||
api.shop.shopDetail({
|
||
query: {
|
||
shopId: props.detail.merId
|
||
}
|
||
}).then(rs => {
|
||
if (rs.code == 200) {
|
||
Object.assign(props.detail, {}, rs.data)
|
||
return
|
||
}
|
||
util.alert({
|
||
content: rs.msg,
|
||
showCancel: false,
|
||
})
|
||
})
|
||
}
|
||
|
||
/**
|
||
* 立即下单
|
||
*/
|
||
function handlePay(event) {
|
||
// 产生待付款订单
|
||
api.shop.addOrder({
|
||
data: [{
|
||
// 地址id
|
||
addressId: event.address.id,
|
||
// 产品id
|
||
productId: props.detail.id,
|
||
// 规格id
|
||
attrValueId: event.spec.id,
|
||
// 数量
|
||
payNum: event.payNum,
|
||
// 0-普通订单,1-视频号订单
|
||
orderType: 0,
|
||
// 分享人id
|
||
// shareId: userinfo.id,
|
||
}],
|
||
}).then(rs => {
|
||
if (rs.code === 200) {
|
||
// 跳转
|
||
if (rs.data && rs.data[0]) uni.navigateTo({
|
||
url: util.setUrl('/pages/shop/commodity/payment', {
|
||
orderId: rs.data[0].orderId,
|
||
})
|
||
})
|
||
return
|
||
}
|
||
util.alert({
|
||
content: rs.msg,
|
||
showCancel: false,
|
||
})
|
||
})
|
||
}
|
||
</script>
|
||
|
||
<template>
|
||
<view class="container">
|
||
|
||
<!-- 轮播图 -->
|
||
<view class="banner pr" v-if="detail.sliderImage">
|
||
<swiper class="swiper" :style="{height: bannerHeight,}" :current="bannerIndex"
|
||
@change="($event) => bannerIndex = $event.detail.current">
|
||
<swiper-item v-for="(item, index) in banner" :key="index">
|
||
<image class="poster" :src="item" mode="aspectFill" />
|
||
</swiper-item>
|
||
</swiper>
|
||
|
||
<!-- 计数器 -->
|
||
<view class="count pa ptb5 plr20 bar">
|
||
<text class="text cfff f24">{{ bannerIndex + 1 }} / {{ banner.length }}</text>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 商品详情 -->
|
||
<view class="detail bfff ptb25 plr20">
|
||
<view class="line df fdr jcsb">
|
||
<view class="price df fdr aic">
|
||
<text class="txt">¥</text>
|
||
<text class="txt f56">{{detail.price}}</text>
|
||
</view>
|
||
|
||
<!-- 已售 -->
|
||
<view class="sold">
|
||
<text class="c999 f26">已售 {{detail.sales}}</text>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 优惠券 -->
|
||
<view class="coupon df fdr fww f26 mtb20 cFF9B27" v-if="0">
|
||
<view class="item">
|
||
<text>限时直降0.5元</text>
|
||
</view>
|
||
<view class="item">
|
||
<text>平台立减1元</text>
|
||
</view>
|
||
<view class="item">
|
||
<text>关注店铺1元优惠券</text>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 商品名称 -->
|
||
<view class="name mtb20 t2hd">
|
||
<text class="c333 f34">{{detail.name}}</text>
|
||
</view>
|
||
|
||
<view class="history mtb20 df fdr jcsb aic">
|
||
<text class="c666 f28">商品修改历史</text>
|
||
<uni-icons type="right" color="#999" size="30rpx" />
|
||
</view>
|
||
|
||
<!-- 福利政策 -->
|
||
<view class="gift df fdr fww mtb20">
|
||
<view class="item">
|
||
<text class="text">假一赔十</text>
|
||
</view>
|
||
<view class="item">
|
||
<text class="text">7天无理由退货</text>
|
||
</view>
|
||
<view class="item">
|
||
<text class="text">全场包邮</text>
|
||
</view>
|
||
<view class="item">
|
||
<text class="text">48h内发货</text>
|
||
</view>
|
||
<view class="item" v-if="0">
|
||
<text class="text">支持先用后付</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 最近购买 -->
|
||
<view class="recently mtb20" v-if="recentOrderList[0]">
|
||
<swiper class="swiper" style="height: 220rpx;" :autoplay="true" vertical="true">
|
||
<swiper-item v-for="(item, index) in recentOrderList" :key="index">
|
||
<view class="list plr10 bfff">
|
||
<view class="item bsb df fdr jcsb aic plr10" v-for="(secItem, secIndex) in item"
|
||
:key="secIndex">
|
||
<view class="avatar">
|
||
<image class="avatar wh70 cir" :src="secItem.avatar" mode="aspectFill" />
|
||
</view>
|
||
|
||
<view class="name f1 mlr10">
|
||
<text class="name c666 f28">{{secItem.nickname}}</text>
|
||
</view>
|
||
<view class="info mlr10 tar">
|
||
<!-- <view class="fn">刚刚下单</view> -->
|
||
<view class="time">
|
||
<text class="c999 f26">{{secItem.time}}</text>
|
||
</view>
|
||
</view>
|
||
<view class="btn sm warm plr15">
|
||
<text class="cfff f26">立即购买</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</swiper-item>
|
||
</swiper>
|
||
</view>
|
||
|
||
<!-- 商品评价 -->
|
||
<view class="evaluate mtb20 plr25 bfff">
|
||
<view class="header df fdr jcsb aic ptb25"
|
||
@click="link(util.setUrl('/pages/shop/commodity/evaluate',{id: detail.id}))">
|
||
<text class="modelTitle">商品评价({{comment.total}})</text>
|
||
<uni-icons type="right" />
|
||
</view>
|
||
|
||
<!-- 部分评论 -->
|
||
<view class="list">
|
||
<view class="item ptb20" v-for="(item, index) in comment.list" :key="index">
|
||
<view class="userinfo df fdr aic">
|
||
<image class="avatar wh45 cir" :src="item.avatar" mode="aspectFill" />
|
||
<view class="name thd f32 f1 ml20">
|
||
<text class="c666 f28">{{item.nickname}}</text>
|
||
</view>
|
||
</view>
|
||
<view class="content t2hd mt10">
|
||
<text class="c333 f28">{{item.content}}</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 店铺 -->
|
||
<view class="store df fdr aic jcsb mtb20 ptb20 plr25 bfff">
|
||
<view class="header df fdr jcsb aic">
|
||
<!-- 店铺头像 -->
|
||
<image class="wh140 br20" :src="detail.merAvatar" mode="aspectFill" />
|
||
<!-- 店铺信息 名称 评分 关注数量 -->
|
||
<view class="info f1 mlr20">
|
||
<!-- 店铺名称 -->
|
||
<view class="name thd">
|
||
<text class="f34 c333">{{detail.merName}}</text>
|
||
</view>
|
||
<view class="line df fdr aic mt10">
|
||
<!-- 评分 -->
|
||
<!-- <view class="item f24 c666 df aic ">
|
||
<uni-rate class="mr10" :value="4.5" :size="12" activeColor="#FF9B27" readonly />
|
||
<text>4.5</text>
|
||
</view> -->
|
||
<!-- 关注数量 -->
|
||
<view class="item follow">
|
||
<text class=" c666 f24">{{detail.merFollowNumber}}关注</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 关注按钮 -->
|
||
<view @click="handleCollectStore" class="btn sm warm fmid fdr plr30">
|
||
<uni-icons class="mr10" color="#fff" type="plusempty" size="13" v-if="detail.isFollow != 1" />
|
||
<text class="cfff f28" v-else>已</text>
|
||
<text class="cfff f28">关注</text>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 宝贝详情 -->
|
||
<view class="p25 mtb240 bfff">
|
||
<view class="title">
|
||
<text class="modelTitle">宝贝详情</text>
|
||
</view>
|
||
|
||
<!-- 商品详情 -->
|
||
<view class="content mt30">
|
||
<rich-text :nodes="detail.infoRichText || ''" />
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 填充 -->
|
||
<view class="fill" style="height: 180rpx;"></view>
|
||
|
||
<!-- 底部 -->
|
||
<view class="footerMneu pa rows plr20 shadow bfff">
|
||
<view class="menu df fdr jcsb aic">
|
||
<view class="option ver">
|
||
<image class="wh30" src="/static/store.png" mode="widthFix" />
|
||
<view class="f24 c999 mt10">店铺</view>
|
||
</view>
|
||
|
||
<view class="option ver " @click="handleCollect">
|
||
<view class="wh30 fmid">
|
||
<uni-icons type="star-filled" size="45rpx" color="#FF9B27" v-if="detail.isCollect == 1" />
|
||
<uni-icons type="star" size="45rpx" color="#666" v-else />
|
||
</view>
|
||
<view class="f24 c999 mt10">
|
||
<text v-if="detail.isCollect == 1">已</text>
|
||
<text>收藏</text>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- <view class="option ver ">
|
||
<image class="wh30" src="/static/customer-service.png" mode="widthFix" />
|
||
<view class="f24 c999 mt10">客服</view>
|
||
</view> -->
|
||
</view>
|
||
|
||
<!-- 下单 -->
|
||
<view class="btn lg primary f1 ml30" @click="$refs.makeOrderRef.open()">
|
||
<text>立即购买</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<style lang="scss">
|
||
.container {
|
||
overflow: hidden;
|
||
}
|
||
|
||
// 轮播图
|
||
.banner {
|
||
.swiper {
|
||
|
||
.poster {
|
||
width: 750rpx;
|
||
height: 800rpx;
|
||
}
|
||
}
|
||
|
||
.count {
|
||
bottom: 20rpx;
|
||
right: 20rpx;
|
||
background-color: rgba(0, 0, 0, .4);
|
||
|
||
.text {
|
||
color: #fff;
|
||
}
|
||
}
|
||
}
|
||
|
||
// 模块标题
|
||
.modelTitle {
|
||
color: #333;
|
||
font-size: 30rpx;
|
||
}
|
||
|
||
// 详情
|
||
.detail {
|
||
.price .txt {
|
||
color: #FF7F37;
|
||
}
|
||
|
||
// 优惠券
|
||
.coupon {
|
||
.item {
|
||
padding: 2rpx 10rpx;
|
||
margin-right: 15rpx;
|
||
margin-bottom: 15rpx;
|
||
border: 2rpx solid;
|
||
border-radius: 6rpx;
|
||
}
|
||
}
|
||
|
||
.gift {
|
||
.item {
|
||
margin-right: 20rpx;
|
||
margin-right: 20rpx;
|
||
}
|
||
|
||
.text {
|
||
color: #999;
|
||
font-size: 24rpx;
|
||
}
|
||
}
|
||
}
|
||
|
||
// 最近购买
|
||
.recently {
|
||
height: 220rpx;
|
||
|
||
.item {
|
||
height: 110rpx;
|
||
|
||
&+.item {
|
||
border-top: 2rpx solid #eee;
|
||
}
|
||
|
||
.info .fn {
|
||
color: #FF9B27;
|
||
}
|
||
}
|
||
}
|
||
|
||
// 商品评价
|
||
.evaluate {
|
||
.header {
|
||
border-bottom: 2rpx solid #eee;
|
||
}
|
||
|
||
.list {
|
||
.item+.item {
|
||
border-top: 2rpx solid #eee;
|
||
}
|
||
}
|
||
}
|
||
|
||
// 店铺
|
||
.store {
|
||
|
||
.info {
|
||
.item {
|
||
margin-right: 10rpx;
|
||
}
|
||
|
||
.item+.item {
|
||
padding-left: 10rpx;
|
||
border-left: 2rpx solid #eee;
|
||
}
|
||
}
|
||
}
|
||
|
||
// 底部菜单
|
||
.footerMneu {
|
||
left: 0;
|
||
right: 0;
|
||
bottom: 0;
|
||
|
||
// 选项
|
||
.option {
|
||
width: 80rpx;
|
||
}
|
||
}
|
||
</style> |