JM-MiniApp/components/goodsSpecs.vue
2023-10-08 21:21:21 +08:00

439 lines
12 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.

<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>