Files
gxtyzx-uniapp/src/package/goods/detail.vue
T
2024-08-08 01:53:51 +08:00

620 lines
18 KiB
Vue
Raw 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="goods-info">
<uv-swiper :list="photo" indicator indicatorMode="line" circular height="750rpx" radius="0"></uv-swiper>
</view>
<uni-card :border="false" :is-shadow="false" :padding="0">
<uv-cell-group :customStyle="{backgroundColor: '#ffffff'}" :border="false">
<uv-cell :border="false" :cellStyle="{padding: '10px 5px'}">
<template v-slot:title>
<view class="pirce-bar" style="display: flex;">
<view class="web-text-danger">¥</view>
<view class="web-text-danger" style="font-size: 40rpx;">{{ form.price }}</view>
</view>
</template>
<template v-slot:right-icon>
<text class="web-text-secondary" style="text-decoration: line-through">划线价¥{{ form.price * 2 }}</text>
</template>
</uv-cell>
<uv-cell :cellStyle="{padding: '0px 5px 15px 5px'}">
<template v-slot:title>
<view class="flex">
<view class="web-text-heading font-bold" style="font-size: 26rpx; ">{{ form.goodsName }}</view>
</view>
</template>
</uv-cell>
<!-- <uv-cell title="参数" :label="form.goodsName" :cellStyle="{padding: '10px 5px'}">-->
<!-- </uv-cell>-->
<!-- <uv-cell title="客服电话" label="0771-8888888" :border="false" :cellStyle="{padding: '10px 5px'}"-->
<!-- @click="callPhone('0771-8888888')">-->
<!-- </uv-cell>-->
</uv-cell-group>
</uni-card>
<uni-card :border="false" :is-shadow="false" :padding="0">
<uv-cell :cellStyle="{padding: '10px 5px'}" :center="true" @click="openSpecForm">
<template v-slot:title>
<view class="flex" v-if="!skuText">
<view class="web-text-secondary w-15p">可选</view>
<view class="uv-page__tag-item" v-for="(item, index) in form.goodsSpecValue" :key="index">
<uv-tags :text="`${item.value}`" :plain="!item.checked" type="info" :name="index" class="mr-10"
@click="radioClick">
</uv-tags>
</view>
</view>
<view class="flex" v-else>
<view class="web-text-secondary w-15p">已选</view>
<uv-text class="web-text-heading" type="warning" plain :text="skuText" />
</view>
</template>
<template v-slot:value>
<uv-icon name="arrow-right" color="#cccccc"></uv-icon>
</template>
</uv-cell>
<uv-cell :cellStyle="{padding: '10px 5px'}">
<template v-slot:title>
<view class="flex">
<view class="web-text-secondary w-15p">配送</view>
<view class="web-text-heading">啦啦</view>
</view>
</template>
<template v-slot:value>
<uv-icon name="arrow-right" color="#cccccc"></uv-icon>
</template>
</uv-cell>
<uv-cell :border="false" :cellStyle="{padding: '10px 5px'}">
<template v-slot:title>
<view class="flex">
<view class="web-text-secondary w-15p">保障</view>
<view class="web-text-heading value">坏了包赔 假一赔十 七天无理由</view>
</view>
</template>
<template v-slot:value>
<uv-icon name="arrow-right" color="#cccccc"></uv-icon>
</template>
</uv-cell>
</uni-card>
<uni-card title="商品详情" :is-shadow="false" :border="false" :padding="0">
<view class="web-text-heading booking-content">
<view v-html="form.content"></view>
</view>
</uni-card>
<!-- {{ goodsList }}-->
<view class="xieyi web-cell web-text-secondary web-cell-align-top">
<view class="web-cell web-cell-content web-cell-align-top">
<uv-avatar src="https://oss.wsdns.cn/20240723/2f9ae761ebb343fcbcaccd7441c88e20.png" size="20" v-if="!disabled"
@click="onDisabled"></uv-avatar>
<uv-avatar src="https://oss.wsdns.cn/20240723/cc887e4a1cd749ebb5a1cfa2484c01f2.png" size="20" v-else
@click="onDisabled"></uv-avatar>
<!-- <uni-icons type="circle" size="20" color="#a4a5a7" v-if="!disabled" @click="onDisabled"></uni-icons>-->
<!-- <uni-icons type="checkbox" size="20" color="#11a954" v-else @click="onDisabled"></uni-icons>-->
<view class="text" @click="onDisabled">
<text>我已阅读并同意</text>
<text class="link"
@click.stop="navTo('/package/article/detail?articleId=503')">《购买协议》
</text>
</view>
</view>
</view>
<uv-gap height="50"></uv-gap>
<!-- <view class="save-btn">-->
<!-- <uv-button-->
<!-- :customStyle="{background: 'linear-gradient(to right, #f5a4a4, #ff0000)',borderRadius: '30px',color: '#ff6e0c'}"-->
<!-- text="立即购买" @click="save"></uv-button>-->
<!-- </view>-->
<view class="goods-nav-btn">
<uni-goods-nav :fill="true" :options="options" :button-group="buttonGroup" @click="onClick"
@buttonClick="save"/>
<uv-gap :height="safeAreaInsets.bottom"/>
</view>
</view>
<!-- 选择规格弹窗 -->
<uni-popup ref="specForm" type="center" border-radius="10px 10px 0 0">
<uni-card :title="form.goodsName" :border="false" :is-shadow="false" :padding="0">
<view class="spec-card" style="width: 660rpx;">
<block v-if="form.goodsSpecValue">
<uv-cell-group :customStyle="{ backgroundColor: '#ffffff' }" :border="false">
<block v-for="(item, index) in form.goodsSpecValue" :key="index">
<uv-cell :title="item.value" :cellStyle="{ padding: '10px 0' }" :label="item.address">
<template v-slot:label>
<view class="tags flex mt-10">
<view class="tag mr-15" v-for="value in item.detail">
<uv-tags :text="value" v-if="onPlain(value)" plain border-color="#eeeeee" color="#808080"
@click="onTag(value,index)"></uv-tags>
<uv-tags :text="value" v-else plain color="#ff0000" border-color="#ff0000"
@click="onTag(value,index)"></uv-tags>
</view>
</view>
</template>
</uv-cell>
</block>
<uv-cell :cellStyle="{ padding: '40px 0' }">
</uv-cell>
<uv-cell :cellStyle="{ padding: '10px 0', backgroundColor: '#f3f3f3' }">
<template v-slot:label>
<view class="web-text-secondary">
已选规格:{{ skuText }}
</view>
</template>
</uv-cell>
</uv-cell-group>
<view class="flex m-20 justify-between items-center">
<view class="total-price web-text-heading">
总计
<text class="text-red-500" style="font-weight: 500; font-size: 36rpx">¥{{ form.price }}</text>
</view>
<view class="add-cart">
<uv-button type="warning" class="add-address" iconSize="16" :customStyle="{ borderRadius: '6px', padding: '5px 20px',
backgroundColor: '#ff0000', color: '#ffffff', fontWeight: 'bold' }" :text="isNew ? '立即购买' : '加入购物车'"
@click="gotoBuy"></uv-button>
</view>
</view>
</block>
</view>
</uni-card>
</uni-popup>
<!-- 活动订场弹窗 -->
<!-- <uni-popup ref="popup" type="center">-->
<!-- <view class="popup-booking-tel">-->
<!-- <text class="title">场馆热线</text>-->
<!-- <text class="desc">主体育场、足球训练场:0771-4953380</text>-->
<!-- <text class="desc">体育馆、综合训练馆、网球馆:0771-4953380</text>-->
<!-- <text class="desc">游泳跳水馆:0771-4736008</text>-->
<!-- <text class="title">参观接待</text>-->
<!-- <text class="desc">预约电话:0771-4736955</text>-->
<!-- <text class="desc">传真号码:0771-4736955</text>-->
<!-- <text class="title">大型活动订场</text>-->
<!-- <text class="desc">预约电话:0771-4736970、0771-4736994</text>-->
<!-- <text class="title">威拓普健身馆</text>-->
<!-- <text class="desc">联系电话:0771-5588699</text>-->
<!-- </view>-->
<!-- <view class="web-cell popup-close" @click="closeBookingTel">-->
<!-- <uv-icon name="close-circle" color="#ffffff" size="30"></uv-icon>-->
<!-- </view>-->
<!-- </uni-popup>-->
<!-- 登录组件 -->
<ws-login ref="login" @done="reload"/>
</template>
<script>
import {
storeToRefs
} from 'pinia';
import * as GoodsApi from '@/api/shop/goods';
import * as CartApi from '@/api/shop/cart';
import {
useCartStore
} from '@/store/modules/cart';
import UvAvatar from "@/uni_modules/uv-avatar/components/uv-avatar/uv-avatar.vue";
import UvGap from "@/uni_modules/uv-gap/components/uv-gap/uv-gap.vue";
import UvButton from "@/uni_modules/uv-button/components/uv-button/uv-button.vue";
import UvText from "@/uni_modules/uv-text/components/uv-text/uv-text.vue";
const cartStore = useCartStore();
const {
goodsList,
orderInfo,
totalPrice,
carNum,
merchantId,
merchantName,
merchantCode,
type,
dateTime,
isNew,
isLogin
} = storeToRefs(cartStore)
export default {
components: {UvText, UvButton, UvGap, UvAvatar},
data() {
return {
id: 0,
form: {},
// 场馆相册
photo: [],
cart: {},
safeAreaInsets: {},
isLogin: false,
disabled: true,
specForm: false,
sku: [],
skuText: '',
orderInfo,
goodsList,
totalPrice,
carNum,
merchantId,
merchantName,
merchantCode,
type,
isNew,
dateTime,
options: [{
icon: 'server-fill',
text: '客服'
}, {
icon: 'bag',
text: '购物车',
info: 0
}],
buttonGroup: [
{
text: '加入购物车',
backgroundColor: 'linear-gradient(to right, #ffc940, #ff6e0c)',
color: '#fff'
}, {
text: '立即购买',
backgroundColor: 'linear-gradient(90deg, #ff0000, #ff6767)',
color: '#fff'
}
],
customButtonGroup1: [{
text: '立即购买',
backgroundColor: 'linear-gradient(90deg, #ccff66, #008e04)',
color: '#fff'
}]
}
},
onLoad(option) {
this.id = option.id
this.reload();
},
onShow() {
// 登录状态
if (uni.getStorageSync('user_id') && uni.getStorageSync('access_token')) {
this.isLogin = true;
}
},
methods: {
async reload() {
const app = this
// 获取系统信息
uni.getSystemInfo({
success(data) {
if (data) {
app.safeAreaInsets = data.safeAreaInsets;
app.statusBarHeight = data.statusBarHeight + 50;
}
}
});
// 请求数据
Promise.all([app.getGoods(), app.listCart()]).then(data => {
const form = data[0]
form.content = this.formatRichText(form.content)
app.form = form;
cartStore.merchantId = form.merchantId
cartStore.merchantName = form.merchantName
cartStore.merchantCode = form.merchantCode
// 修改标题
uni.setNavigationBarTitle({
title: form.goodsName
})
// 加载场馆相册
if (form.files) {
app.photo = JSON.parse(form.files)
}
// 购物车信息
app.cart = data[1]
console.log(app.cart.totalNums)
// 更新购物车角标
if (app.cart?.totalNums) {
app.options[1].info = app.cart.totalNums
}
})
},
getGoods() {
return new Promise((resolve, reject) => {
GoodsApi.getGoods(this.id).then(result => {
resolve(result)
}).catch(reject)
})
},
listCart() {
return new Promise((resolve, reject) => {
CartApi.listCart().then(result => {
resolve(result)
}).catch(reject)
})
},
onDisabled() {
this.disabled = !this.disabled;
},
navTo(url) {
uni.navigateTo({
url
})
},
onPlain(text) {
const index = this.sku.findIndex(d => d === text)
return index < 0;
},
onTag(text, index) {
const app = this
const parent = this.sku.findIndex(d => d === text)
if (parent < 0) {
app.sku.push(text)
app.skuText = app.sku.join('、')
}
},
// openBookingTel() {
// // 通过组件定义的ref调用uni-popup方法 ,如果传入参数 ,type 属性将失效 ,仅支持 ['top','left','bottom','right','center']
// this.$refs.popup.open('center')
// },
// closeBookingTel() {
// this.$refs.popup.close()
// },
callPhone(phone) {
uni.makePhoneCall({
phoneNumber: phone
});
},
onMap() {
uni.getLocation({
type: 'gcj02', //返回可以用于uni.openLocation的经纬度
success: function (res) {
console.log('返回可以用于uni.openLocation的经纬度: ', res);
const latitude = this.merchant.latitude;
const longitude = this.merchant.longitude;
uni.openLocation({
latitude: latitude,
longitude: longitude,
success: function () {
console.log('success');
}
});
}
});
},
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;
},
openSpecForm(){
this.$refs.specForm.open('center');
},
onClick({index, content}) {
console.log(index, content)
// 客服按钮
if (index === 0) {
uni.contact({
type: 'updateCustomerService',
success: function () {
console.log('客服会话打开成功');
},
fail: function (err) {
console.error('客服会话打开失败:', err);
}
});
}
// 前往购物车
if (index === 1) {
uni.navigateTo({url: `/package/cart/index`})
}
},
save({index, content}) {
const app = this
const {form} = this
if (!app.isLogin && !cartStore.isLogin) {
this.$refs.login.open('bottom');
return false;
}
if (!this.disabled) {
uni.showToast({
title: '请先阅读并同意订票协议',
icon: 'none'
})
return false
}
// 加入购物车
if (index === 0) {
form.cartNum = 1;
form.isNew = false;
cartStore.isNew = false;
// 单规格
if (form.specs === 0) {
CartApi.addCart(form).then(data => {
app.reload()
uni.showToast({
title: '添加成功',
icon: 'success'
});
}).catch(res => {
uni.showToast({
title: res.message,
icon: 'none'
});
})
return false
}
// 多规格
if (form.specs === 1) {
this.$refs.specForm.open('center');
return false;
}
return false;
}
// 立即购买
if (index === 1) {
form.cartNum = 1;
form.isNew = true;
cartStore.isNew = true;
// 多规格
if (form.specs === 1) {
form.spec = app.skuText;
this.$refs.specForm.open('center');
return false;
}
CartApi.addCart(form).then(cartId => {
// 跳转页面
uni.navigateTo({
url: `/package/goods/checkout?id=${cartId}`
})
})
}
},
gotoBuy() {
const app = this
this.disabled = !this.disabled;
CartApi.addCart({
...app.form,
spec: app.skuText,
cartNum: 1,
isNew: app.isNew
}).then(cardId => {
if (app.isNew) {
// CartApi.removeCart(data.id)
// 跳转页面
uni.navigateTo({
url: `/package/goods/checkout?id=${cardId}`
})
} else {
}
})
this.$refs.specForm.close();
},
}
}
</script>
<style>
page {
background-size: 100%;
background-repeat: no-repeat;
background-color: #f0f2f5;
//color: #ff6e0c;
width: 750rpx;
overflow-x: hidden;
}
img {
max-width: 100%;
}
</style>
<style lang="scss" scoped>
.container {
}
.goods-info {
width: 750rpx;
height: 750rpx;
background-color: #fff;
}
.merchant-name {
padding: 30rpx;
font-weight: 500;
font-size: 42rpx;
background-color: #ffffff;
}
.save-btn {
width: 700rpx;
left: 25rpx;
height: 80rpx;
position: fixed;
bottom: 30rpx;
}
.booking-tel {
position: fixed;
z-index: 1;
top: 270px;
right: 0;
width: 80px;
height: 38px;
border-radius: 50px 0 0 50px;
background: linear-gradient(to right, #f5a4a4, #008e04);
display: flex;
align-items: center;
justify-content: center;
color: #ffffff;
font-size: 13px;
}
.popup-booking-tel {
background-color: #ffffff;
width: 560rpx;
min-height: 400rpx;
border-radius: 20rpx;
margin: auto;
padding: 20px;
z-index: 9999;
display: flex;
flex-direction: column;
.title {
font-weight: bold;
font-size: 38rpx;
text-align: center;
padding: 10px 0;
}
.desc {
line-height: 2rem;
}
}
.popup-close {
display: flex;
margin-top: 24rpx;
justify-content: center;
}
.booking-content {
padding: 10px;
font-size: 30rpx;
line-height: 1.5rem;
}
.xieyi {
margin-bottom: 80rpx;
padding: 0 30rpx;
.text {
margin-left: 5rpx;
.link {
color: #0f80ff;
}
}
}
.goods-nav-btn {
width: 750rpx;
position: fixed;
bottom: 0;
background-color: #fff;
}
</style>