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