160 lines
4.4 KiB
TypeScript
160 lines
4.4 KiB
TypeScript
import { computed, ref } from 'vue'
|
|
import { showToast, useDidShow } from '@tarojs/taro'
|
|
import { createOrder } from '@/services'
|
|
import { pinia, useAppStore, useCartStore, useCustomerStore, useFulfillmentStore } from '@/stores'
|
|
import { FulfillmentScenes } from '@/shared'
|
|
import { openRoute } from '@/utils/router'
|
|
import { createEstimateActions, emptyEstimate } from './checkout-page/estimate-actions'
|
|
import { buildCheckoutPayload } from './checkout-page/payload'
|
|
import {
|
|
resolveSceneHint,
|
|
resolveSceneLabel,
|
|
resolveSceneSuffix
|
|
} from './checkout-page/scene-helpers'
|
|
|
|
interface InputLikeEvent {
|
|
detail?: {
|
|
value?: string
|
|
}
|
|
}
|
|
|
|
export function useCheckoutPage () {
|
|
const appStore = useAppStore(pinia)
|
|
const cartStore = useCartStore(pinia)
|
|
const customerStore = useCustomerStore(pinia)
|
|
const fulfillmentStore = useFulfillmentStore(pinia)
|
|
const isEstimating = ref(false)
|
|
const submitting = ref(false)
|
|
const estimate = ref(emptyEstimate)
|
|
const draftName = ref(customerStore.name)
|
|
const draftPhone = ref(customerStore.phone)
|
|
const remark = ref('')
|
|
|
|
const itemCount = computed(() => cartStore.itemCount)
|
|
const lineList = computed(() => cartStore.lineList)
|
|
const sceneLabel = computed(() => resolveSceneLabel(appStore.scene))
|
|
const sceneSuffix = computed(() => resolveSceneSuffix(appStore.scene))
|
|
const sceneHint = computed(() => resolveSceneHint(appStore.scene))
|
|
|
|
const { handleEstimate } = createEstimateActions({
|
|
appStore,
|
|
cartStore,
|
|
estimate,
|
|
isEstimating
|
|
})
|
|
|
|
function handleNameInput (event: InputLikeEvent) {
|
|
draftName.value = event.detail?.value || ''
|
|
}
|
|
|
|
function handlePhoneInput (event: InputLikeEvent) {
|
|
draftPhone.value = event.detail?.value || ''
|
|
}
|
|
|
|
function handleRemarkInput (event: InputLikeEvent) {
|
|
remark.value = event.detail?.value || ''
|
|
}
|
|
|
|
async function submitOrder () {
|
|
if (!cartStore.itemCount) {
|
|
await showToast({ title: '请先加购商品', icon: 'none' })
|
|
return
|
|
}
|
|
|
|
if (!draftName.value.trim() || !draftPhone.value.trim()) {
|
|
await showToast({ title: '请完善顾客信息', icon: 'none' })
|
|
return
|
|
}
|
|
|
|
if (appStore.scene === FulfillmentScenes.Delivery && !fulfillmentStore.addressText) {
|
|
await showToast({ title: '请先填写配送地址', icon: 'none' })
|
|
void openRoute('/pages/address/index')
|
|
return
|
|
}
|
|
|
|
if (appStore.scene === FulfillmentScenes.DineIn && !fulfillmentStore.tableNo) {
|
|
await showToast({ title: '请先填写桌号', icon: 'none' })
|
|
void openRoute('/pages/dinein/confirm/index')
|
|
return
|
|
}
|
|
|
|
customerStore.updateProfile({
|
|
name: draftName.value,
|
|
phone: draftPhone.value
|
|
})
|
|
|
|
submitting.value = true
|
|
|
|
try {
|
|
await handleEstimate()
|
|
const order = await createOrder({
|
|
...buildCheckoutPayload(appStore, cartStore),
|
|
remark: remark.value || (appStore.scene === FulfillmentScenes.Delivery
|
|
? fulfillmentStore.addressText
|
|
: undefined),
|
|
tableNo: appStore.scene === FulfillmentScenes.DineIn
|
|
? fulfillmentStore.tableNo
|
|
: undefined
|
|
})
|
|
|
|
cartStore.clear()
|
|
void openRoute(`/pages/trade/success/index?orderId=${order.orderId}&orderNo=${order.orderNo}`)
|
|
} catch (error: unknown) {
|
|
await showToast({
|
|
title: error instanceof Error ? error.message : '下单失败',
|
|
icon: 'none'
|
|
})
|
|
} finally {
|
|
submitting.value = false
|
|
}
|
|
}
|
|
|
|
function goSceneContext () {
|
|
if (appStore.scene === FulfillmentScenes.Delivery) {
|
|
void openRoute('/pages/address/index')
|
|
return
|
|
}
|
|
|
|
if (appStore.scene === FulfillmentScenes.DineIn) {
|
|
void openRoute('/pages/dinein/confirm/index')
|
|
return
|
|
}
|
|
|
|
void showToast({ title: '自提场景无需额外填写', icon: 'none' })
|
|
}
|
|
|
|
function goMenu () {
|
|
void openRoute('/pages/menu/index')
|
|
}
|
|
|
|
useDidShow(() => {
|
|
draftName.value = customerStore.name
|
|
draftPhone.value = customerStore.phone
|
|
void appStore.initBootstrap()
|
|
void appStore.initStores()
|
|
void handleEstimate()
|
|
})
|
|
|
|
return {
|
|
appStore,
|
|
draftName,
|
|
draftPhone,
|
|
estimate,
|
|
fulfillmentStore,
|
|
goMenu,
|
|
goSceneContext,
|
|
handleEstimate,
|
|
handleNameInput,
|
|
handlePhoneInput,
|
|
handleRemarkInput,
|
|
itemCount,
|
|
lineList,
|
|
remark,
|
|
sceneHint,
|
|
sceneLabel,
|
|
sceneSuffix,
|
|
submitOrder,
|
|
submitting
|
|
}
|
|
}
|