You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

439 lines
12 KiB
Vue

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<script setup>
// 引入
import { onShow,onLoad,onHide } from "@dcloudio/uni-app"
import {ref,onMounted,nextTick,reactive,watch} from "vue"
import myButton from "@/components/myButton.vue"
import { useStore } from '@/store'
import api from "@/api/index"
const store = useStore()
/*
注意区分show_status-按钮是否有效show_state-是否展示本组件
show_type如果是团购或秒杀无法添加到购物车
*/
const props = defineProps(['show_type','goods_info','btn_text','show_state','show_status','payBtn']);// goods_info:商品详情(goodsDetail页面的info变量)
const emits = defineEmits(['choosedOk','choosedDeliveryOk'])
onLoad((e) => {
console.log('规格!!!',props)
// styleObject.value.height = store.systemInfo.screenHeight/1.5+'px'
// console.log("组件:",styleObject.value)
getDelivery()
})
onShow(() =>{
// styleObject.value.height = store.systemInfo.screenHeight/1.5+'px'
})
watch(
() => props.goods_info,
(newVal, oldVal) => {
info.value = newVal
console.log('监听参数',info.value)
goods_type.value = info.value.type
handleFunc()
}
)
watch(()=>props.show_state,(newVal, oldVal) => {
// console.log(11111,props.show_type)
if(newVal && !deliveryInfo.value) {
getDelivery()
}
styleObject.value.height = store.systemInfo.screenHeight/1.8+'px'
popup.value.open('bottom')
// console.log(deliveryInfo.value)
// console.log("组件:",props.show_state)
})
// 变量
const goods_type = ref(null)
const update_fields = ref(['cost_price','createtime','market_price','sales','sell_price','stock','weight']) // 需要更新的商品字段
const styleObject = ref({
height: '',
})
const info = ref(null)
const total_num = ref(1)
const popup = ref()
const info_text = ref('')
const deliveryInfo = ref(null)
// 函数
async function getDelivery(){ // 获取配送相关的选项
const res = await api.getDelivery()
// console.log(res)
if(res.code === 1) {
deliveryInfo.value = res.data
// console.log(deliveryInfo.value)
}
}
function chooseFunc(type){
// type.value = type
// open 方法传入参数 等同在 uni-popup 组件上绑定 type属性
popup.value.open(type)
}
function change(e) {
// console.log('当前模式:' + e.type + ',状态:' + e.show);
}
function handleFunc() {
if(info.value.specs && info.value.specs.length>0) {
choosed_list.value = new Array(info.value.specs.length);
// console.log("choosed_list:",choosed_list.value)
}
}
const choosed_list = ref([])
function choosePopFunc2(i,i2) { // 规格选择函数
choosed_list.value[i] = i2
let str = choosed_list.value.join()
getNewinfo(i,i2,str)
}
const current_specs_id = ref(null)
const emitParams = ref({total_num:1})
async function getNewinfo(i,i2,str) {
// console.log(str)
const res = await api.getNewinfo({
goods_id:info.value.id,
ks:str
})
if(res.code === 1) {
info.value.specs[i].choosed_val = i2
// 更新对应数据
for(let prop in update_fields.value) {
info.value[update_fields.value[prop]] = res.data[update_fields.value[prop]]
}
info_text.value = res.data.name
// console.log(info.value)
current_specs_id.value = res.data.id
emitParams.value.current_specs_id = res.data.id
emitParams.value.flag_res = checkFunc()
emits('choosedOk',emitParams.value)
}
else{
// res.msg
uni.showToast({
duration:2000,
title:res.msg,
icon:'error'
})
}
}
function changeNumFunc(value){
if(value<info.value.stock && value>0) {
// info.value.sell_price = parseFloat(info.value.sell_price) ++
total_num.value = value
}
else if(value<1) {
total_num.value = 1
}
else{ //
uni.showToast({
title:"",
icon:"error"
})
return
}
emitParams.value.total_num = total_num.value
emitParams.value.flag_res = checkFunc()
emits("choosedOk",emitParams.value)
// console.log(value)
}
async function ofunc(type) { //
if(['group','limited'].includes(props.show_type)){ //
return
}
let flag_res = checkFunc()
let iocn_flag = 'success',title = '已加入购物车!'
// console.log(flag_res)
if(!flag_res.flag) {
iocn_flag = 'error',
title = flag_res.text
}
else{
if(goods_type==1) {
//
let warning_text = checkDeliveryInfo()
if(warning_text) {
uni.showToast({
title:warning_text,
icon:"error"
})
return
}
}
let add_res = await addCart()
if(add_res.state) {
popup.value.close()
emitParams.value.state = 1
emitParams.value.flag_res = checkFunc()
store.cartChange = !store.cartChange
emits('choosedOk',emitParams.value)
}
else{
iocn_flag = 'error'
}
title = add_res.msg
}
uni.showToast({
title,
icon:iocn_flag,
duration: 2000,
// mask:true
});
}
async function addCart() {
// let add_res = false
let add_res = {
state:false,
msg:''
}
let params = {
goods_id:info.value.id,
spec_id:current_specs_id.value?current_specs_id.value:-1,
num:total_num.value,
frequency:deliveryInfo.value.frequency[deliveryInfo.value.frequency_index],
delivery_start_time:deliveryInfo.value.start_time[deliveryInfo.value.start_time_index],
need_milk_box:deliveryInfo.value.need_milk_box[deliveryInfo.value.need_milk_box_index]
}
const res = await api.addCart(params)
if(res.code === 1) {
add_res.state = true
}
add_res.msg = res.msg
return add_res
}
function checkDeliveryInfo() { //
if(!deliveryInfo.value) {
return ''
}
let c_arr = [
{
prop:'frequency_index',
title:''
},
{
prop:'start_time_index',
title:''
},
{
prop:'need_milk_box_index',
title:''
}
]
// deliveryInfo.value.
for(let i = 0;i<c_arr.length;i++) {
if(!deliveryInfo.value.hasOwnProperty(c_arr[i].prop)) {
return c_arr[i].title
}
}
}
function checkFunc() {
let flag = true
let res_flag = {
flag:true,
text:''
}
if(info.value.specs && info.value.specs.length>0) {
for(let item of info.value.specs) {
if(!item.hasOwnProperty('choosed_val')) {
res_flag.flag = false
res_flag.text = '请选择'+item.title
break;
}
}
}
// console.log(info.value)
return res_flag
}
function chooseDeliveryFunc(prop,title) {
// console.log(prop,title)
deliveryInfo.value[prop] = title
emits('choosedDeliveryOk',{info:deliveryInfo.value})
}
function determine(func) {
emits('payOk')
}
</script>
<template>
<view class="goodsSpecsBox">
<!-- <view class="g-cart btn-css" @tap="chooseFunc('bottom')">
</view> -->
<uni-popup ref="popup" @change="change">
<view class="popup-content" :style="styleObject" >
<!-- 产品主信息 -->
<view class="pc-row main-info">
<view class="pcr-left">
<view class="pcrl-img-box">
<image :src="info?.goods_image" mode=""></image>
</view>
</view>
<view class="pcr-right">
<view class="pcrr-row bold-text">
{{info?.goods_name}}
</view>
<view class="pcrr-row small-text">
产品描述
</view>
<view class="pcrr-row small-text">
{{info?.sellpoint}}
</view>
</view>
</view>
<!-- 规格 -->
<view class="pc-row" v-for="(item,i) in info?.specs">
<view class="pcr-title">
{{item.title}}
</view>
<view class="pc-choose-card-box">
<view @tap="choosePopFunc2(i,i2)" :class="{choosedCard:item.choosed_val==i2}" class="pc-choose-card" v-for="(item2,i2) in item.items">
{{item2.title}}
</view>
</view>
<!-- <view class="small-text">
温馨提示:配送区域为重庆市南岸区四公里到六公里
</view> -->
</view>
<!-- 配送相关选项 -->
<!-- deliveryInfo -->
<template v-if="goods_type == 1">
<view class="pc-row">
<view class="pcr-title">
配送频率
</view>
<view class="pc-choose-card-box">
<view @tap="chooseDeliveryFunc('frequency_index',i2)" :class="{choosedCard:deliveryInfo?.frequency_index==i2}" class="pc-choose-card" v-for="(item2,i2) in deliveryInfo?.frequency">
{{item2}}
</view>
</view>
</view>
<view class="pc-row">
<view class="pcr-title">
起送时间
</view>
<view class="pc-choose-card-box">
<view @tap="chooseDeliveryFunc('start_time_index',i2)" :class="{choosedCard:deliveryInfo?.start_time_index==i2}" class="pc-choose-card" v-for="(item2,i2) in deliveryInfo?.start_time">
{{item2}}
</view>
</view>
</view>
<view class="pc-row">
<view class="pcr-title">
是否需要奶箱
</view>
<view class="pc-choose-card-box">
<view @tap="chooseDeliveryFunc('need_milk_box_index',i2)" :class="{choosedCard:deliveryInfo?.need_milk_box_index==i2}" class="pc-choose-card" v-for="(item2,i2) in deliveryInfo?.need_milk_box">
{{item2}}
</view>
</view>
</view>
</template>
<!-- 数量 -->
<view class="pc-row total-info-box">
<view class="tib-left">
<view class="tib-left-row">
<text class="total-price bold-text">¥{{parseFloat(info?.sell_price) * total_num}}</text>
<text class="small-text">(库存{{info?.stock}}</text>
</view>
<view class="tib-left-row small-text">
{{info_text}}
</view>
</view>
<view class="tib-right">
<uni-number-box :value="total_num" @change="changeNumFunc" />
</view>
</view>
<!-- 按钮 -->
<view class="pc-row total-info-box">
<myButton :invalid="['group','limited'].includes(show_type)" showType="plain" style="width: 100%;" class="op-right" :type="2" @tap="ofunc(3)">
加入购物车
</myButton>
<myButton @tap="determine(1)" v-if="['group','limited'].includes(show_type) && payBtn" style="width: 100%;" class="op-right" :type="2">
{{btn_text}}
</myButton>
<myButton v-else-if="payBtn" style="width: 100%;" class="op-right" :type="2" @tap="determine(1)">
</myButton>
</view>
</view>
</uni-popup>
</view>
</template>
<style scoped lang="scss">
// .invalidCss .add-btn-part .add-btn {
// color: white !important;
// background-color: #d7d7d7 !important;
// border: 2rpx solid #d7d7d7 !important;
// }
.btn-css{
background: #7CC4E8;
color: white;
padding: 6rpx 40rpx;
border-radius: 20px;
font-size: 28rpx;
white-space: nowrap;
margin-left: 10rpx;
position: relative;
}
// 数量
.total-info-box{
display: flex;
align-items: center;
justify-content: space-between;
.tib-left{
margin-right: 20rpx;
.tib-left-row{
color: red;
margin-bottom: 20rpx;
}
}
}
// 选择区域
.choosedCard{
background-color: rgb(124, 196, 232) !important;
color: white !important;
}
.goodsSpecsBox{
.popup-content{
padding-top: 40rpx;
background-color: white;
border-radius: 10px 10px 0 0;
overflow: scroll;
.pc-row{
padding:0 40rpx;
padding-bottom: 40rpx;
.pcr-title{
color: gray;
font-size: 30rpx;
padding: 20rpx 0;
}
.pc-choose-card-box{
.pc-choose-card{
display: inline-block;
background: #f1f1f1;
margin-right: 20rpx;
margin-bottom: 20rpx;
padding: 10rpx 20rpx;
border-radius: 10rpx;
// font-weight: bolder;
font-size: 28rpx;
}
}
}
.main-info{
display: flex;
// align-items:;
.pcr-left{
margin-right: 40rpx;
.pcrl-img-box{
border: 2rpx solid #dadada;
width: 180rpx;
height: 180rpx;
image{
width: 180rpx;
height: 180rpx;
}
}
}
.pcr-right{
.pcrr-row{
margin-bottom: 20rpx;
}
}
}
}
}
</style>