Files
uniapp-im-shop/pages/mall/confirm-order.vue
2026-01-06 16:35:57 +08:00

248 lines
6.2 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 { onLoad, onShow } from '@dcloudio/uni-app'
import { getProductDetail, addOrder } from '@/api/mall'
import { reactive, ref } from 'vue'
import { formatRMB } from '@/utils'
import { getUserAddress } from '@/api'
import { getUserPayPwd } from '@/api/my-index'
import { navigateTo, redirectTo } from '@/utils/router'
import { useUI } from '@/utils/use-ui'
import { useUserStore } from '@/stores/user'
const { showToast, showDialog } = useUI()
const { refreshUserInfo } = useUserStore()
const viewData = ref({})
/** 单价 */
const priceData = ref(0)
const formData = reactive({
/** 数量 */
num: 1,
/** 规格 */
spec: 0,
/** 默认支付方式 */
payWay: 1,
/** 合计 */
total: 0,
/** 默认地址 */
address: '',
/** 可选数量 */
maxNum: 1
})
/** 顶部地址信息 */
const topRessData = reactive({
name: '',
houseNum: '',
id: '',
phone: '',
state: false,
loading: true
})
const tixian = ref(null)
/** 获取用户地址 */
const userRess = async () => {
topRessData.loading = true
const res = await getUserAddress({ pageNum: 1, pageSize: 99 }, false)
const data = res.rows.find(v => v.defaultAddress == 1)
topRessData.state = !data?.id
topRessData.name = data?.name || ''
topRessData.houseNum = data?.houseNum || ''
topRessData.id = data?.id || ''
topRessData.phone = data?.phone || ''
topRessData.loading = false
}
/** 用户地址跳转 */
const onRess = () => {
navigateTo('/pages/address/index')
}
const getData = async productId => {
const res = await getProductDetail(productId)
viewData.value = res.data
const { id, price, stockQuantity } = res.data.skuList.find(
v => v.isDefault == 1
)
formData.maxNum = stockQuantity
formData.spec = id
priceData.value = price
formData.total = price
}
/** 数量切换 */
const onChange = i => {
formData.total = priceData.value * i
}
/** 规格选择 */
const onSpecChange = item => {
formData.spec = item.id
formData.num = 1
formData.total = item.price
priceData.value = item.price
formData.maxNum = item.stockQuantity
}
// 提交订单
const onConfirm = async () => {
if (!topRessData.id) {
showToast(`请选择地址`)
return
}
const res = await getUserPayPwd()
if (res?.data) {
tixian.value.open()
} else {
const show = await showDialog('提示', '请先设置支付密码')
if (show) {
navigateTo('/pages/my-index/wallet/edit-password', { type: 0 })
}
}
}
const submit = async e => {
const data = {
payPassword: e.join(''),
addressId: topRessData.id,
productId: viewData.value.id,
quantity: formData.num,
skuId: formData.spec
}
tixian.value.close()
const res = await addOrder(data)
await refreshUserInfo()
redirectTo('/pages/shop-together/detail', {
id: res.data.groupId,
type: 'add'
})
}
onShow(() => {
userRess()
})
onLoad(async e => {
await getData(e.productId)
})
</script>
<template>
<view class="mall-confirm-order">
<uu-pwdModal ref="tixian" @success="submit"></uu-pwdModal>
<!-- 地址 -->
<view class="address-box" @click="onRess">
<text v-if="topRessData.state" class="wu-adres">
暂无收货/默认地址(点击添加)
</text>
<view v-else class="left-name">
<text class="adres">{{ topRessData.houseNum }}</text>
<view class="bottom-name">
<text>{{ topRessData.name }}</text>
<text>{{ topRessData.phone }}</text>
</view>
</view>
<image
src="/static/images/public/right-arrow.png"
mode="heightFix"
class="right-box"
></image>
</view>
<!-- 商品展示 -->
<view class="public-product_item">
<image
:src="viewData.mainImage"
mode="scaleToFill"
class="left-img"
></image>
<view class="right-content">
<text class="product-name">
{{ viewData.productName }}
</text>
<view class="line-box">
<view class="rmb-box">
<text>¥{{ viewData.originalPrice || '' }}</text>
<text>¥{{ priceData }}</text>
</view>
<!-- 添加数量 -->
<view class="add-num">
<uni-number-box
v-model="formData.num"
:min="1"
:max="formData.maxNum"
@change="onChange"
></uni-number-box>
</view>
</view>
</view>
</view>
<!-- 规格 -->
<view class="spec-box">
<text class="title">规格</text>
<view class="spec-item">
<text
v-for="(item, index) in viewData.skuList"
:key="index"
:class="{
'on-text': formData.spec === item.id,
disabled: item.stockQuantity <= 0
}"
@click="item.stockQuantity > 0 && onSpecChange(item)"
>
{{ item.specText }}*{{ item.stockQuantity }}
</text>
</view>
</view>
<!-- 合计 -->
<view class="total-box">
<text class="name">合计</text>
<view class="num">
<text>¥</text>
<text>{{ formatRMB(formData.total) }}</text>
</view>
</view>
<!-- 付款方式 -->
<view class="pay-way">
<view class="pay-way-item" @click="formData.payWay = 1">
<view class="icon">
<image
src="/static/images/public/integral.png"
mode="aspectFit"
class="left-icon"
></image>
<text>积分</text>
</view>
<view class="check">
<image
v-show="formData.payWay == 1"
src="/static/images/public/check-to-confirm.png"
mode="aspectFit"
class="check-icon"
></image>
</view>
</view>
</view>
<!-- 底部按钮 -->
<bottom-view>
<cb-button @click="onConfirm">确认支付</cb-button>
</bottom-view>
</view>
</template>
<style lang="scss" scoped>
page {
background: #f9f9f9;
}
@import '@/styles/mall.scss';
@import './styles/confirm-order.scss';
</style>