jiuyiUniapp/jiuyi2/components/shop/detail/makeOrder.vue

258 lines
5.3 KiB
Vue

<script setup>
/**
* 下单组件
*/
import {
ref,
reactive,
getCurrentInstance,
computed,
defineEmits,
onMounted,
defineProps,
defineExpose
} from 'vue'
//
import util from '@/common/js/util.js'
//
import api from '@/api/index.js'
// 地址
import JyCommodityAddress from '@/components/public/jy-commodity-address'
const {
proxy
} = getCurrentInstance()
//
const props = defineProps({
// 商品信息
detail: {
type: Object,
default: () => ({})
},
// 模式 detail详情 collect收藏列表
mode: {
type: String,
default: 'detail'
},
})
// 提交
const emit = defineEmits(['confirm'])
// 地址
const address = reactive({})
// 已选择的规格下标
const spaceIndex = ref(0)
// 上次选择的规格下标
const spaceIndexLast = ref(0)
// 数量
const payNum = ref(1)
// 上次数量
const payNumLast = 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
})
onMounted(() => {
// 获取默认收货地址
if (props.mode === 'detail') getDefaultAddress()
})
// 获取默认收货地址
function getDefaultAddress() {
util.isLogin().then(res => {
api.shop.getDefaultAddress({}).then(res => {
if (res.code === 200) {
if (res.data) Object.assign(address, {}, res.data)
return
}
util.alert({
content: res.msg,
showCancel: false,
})
})
})
}
/**
* 跳转
* @param {Object} url 跳转路径
*/
function link(url) {
uni.navigateTo({
url,
})
}
/**
* 选择规格
* @param {Object} index 选择规格下标
*/
function handleSpec(index) {
if (spaceIndex.value !== index) spaceIndex.value = index
}
/**
* 打开弹窗
* @param {Object} event 携带参数
*/
function open(event) {
// 同步选择值
if (event) {
spaceIndex.value = event.spaceIndex || 0
payNum.value = event.payNum || 1
}
// 打开弹窗
proxy.$refs.payment.open()
}
// 关闭弹窗
function close() {
proxy.$refs.payment.close()
}
// 确认
function handleConfirm() {
// 验证必填项
if (props.mode == 'detail' && !address.id) {
util.alert('请选择收货地址')
return
}
//
let param = {
spec: currentSpec.value,
spaceIndex: spaceIndex.value,
payNum: payNum.value,
}
// 如果有地址信息
if (address.id) param.address = address
emit('confirm', param)
// 同步选择值
spaceIndexLast.value = spaceIndex.value
payNumLast.value = payNum.value
//
close()
}
/**
* 弹窗状态改变
* @param {Object} ev
*/
function handlePopChange(ev) {
// 关闭弹窗时 同步选择值
if (!ev.show) {
spaceIndex.value = spaceIndexLast.value
payNum.value = payNumLast.value
}
}
defineExpose({
open,
close,
})
</script>
<template>
<!-- 规格 -->
<uni-popup type="bottom" ref="payment" @change="handlePopChange">
<view class="buy popBot plr20 bfff">
<view class="address mtb40" v-if="mode === 'detail'">
<template v-if="address.id">
<JyCommodityAddress :address="address" />
</template>
<template v-else>
<view class="fmid" @click="link('/pages/mine/address/index?select=1')">
<text class="c999 f28">暂无默认地址</text>
<uni-icons type="right" color="#999" size="30rpx" />
</view>
</template>
</view>
<!-- 商品图 价格 明细 数量 -->
<view class="jy-card-commodity-content df fdr mtb40">
<!-- 商品图 -->
<image class="wh200 br10" :src="currentSpec.image" mode="aspectFill" />
<!-- 价格 明细 数量 -->
<view class="info f1 df fdc jcsb ml30">
<!-- 价格 -->
<view class="price df fdr aic">
<text class="cFF9B27 f28">单价</text>
<text class="cFF9B27 f24">¥</text>
<text class="cFF9B27 f50">{{detail.price}}</text>
</view>
<!-- 已选 -->
<view class="content-info-num">
<text class="f26 c333">已选: {{currentSpec.sku}}</text>
</view>
<!-- 计数器 -->
<view class="w200">
<uni-number-box v-model="payNum" :step="1" />
</view>
</view>
</view>
<!-- 规格 -->
<view class="spec">
<view class="selection df fdr fww">
<!-- disabled 销量为零不能选 -->
<text class="option mtb20 mr20 f26" :class="{'active': spaceIndex === index}"
v-for="(item,index) in detail.specs" :key="item.id"
@click="handleSpec(index)">{{item.sku}}</text>
</view>
</view>
<view class="btn lg primary mtb30" @click="handleConfirm">
<text class="tac cfff" v-if="mode == 'detail'">立即下单 ¥{{total}}</text>
<text class="tac cfff" v-if="mode == 'collect'">确定</text>
</view>
</view>
</uni-popup>
</template>
<style lang="scss" scoped>
// 规格
.spec {
// 选项
.option {
padding: 5rpx 15rpx;
color: #333;
background-color: #F7F7F7;
border-radius: 10rpx;
transition: .3s;
border: 2rpx solid #F7F7F7;
.text {}
// .text {
// color: #FF9B27;
// }
// 被选中
&.active {
color: #FF9B27;
background-color: #FFFBF8;
border-color: #FF9B27;
}
// 不能选
&.disabled {
background-color: F7F7F7;
.txt {
color: #999;
}
}
}
}
</style>