1.填寫訂單-渲染基本信息
- 靜態結構(分包)
- 封裝請求API
import { http } from '@/utils/http'
import { OrderPreResult } from '@/types/order'export const getmemberOrderPreAPI = () => {return http<OrderPreResult>({method: 'GET',url: '/member/order/pre',})
}
- 初始化調用
// 獲取訂單信息
const orderPre = ref<OrderPreResult>()
const getmemberOrderPreData = async () => {const res = await getmemberOrderPreAPI()orderPre.value = res.result
}
// 初始化調用
onLoad(() => {getmemberOrderPreData()
})
- 類型聲明
- 界面渲染
<!-- 商品信息 --><view class="goods"><navigatorv-for="item in orderPre?.goods":key="item.skuId":url="`/pages/goods/goods?id=${item.id}`"class="item"hover-class="none"><image class="picture" :src="item.picture" /><view class="meta"><view class="name ellipsis"> {{ item.name }} </view><view class="attrs">{{ item.attrsText }} </view><view class="prices"><view class="pay-price symbol">{{ item.payPrice }}</view><view class="price symbol">{{ item.price }}</view></view><view class="count">x{{ item.count }}</view></view></navigator></view><!-- 吸底工具欄 --><view class="toolbar" :style="{ paddingBottom: safeAreaInsets?.bottom + 'px' }"><view class="total-pay symbol"><text class="number">{{ orderPre?.summary.totalPayPrice.toFixed(2) }}</text></view><view class="button" :class="{ disabled: true }"> 提交訂單 </view></view>
2. 收貨地址
- 計算默認收貨地址
const selectedAddress = computed(() => {// 查找默認收貨地址return orderPre.value?.userAddresses.find((v) => v.isDefault)
})
- 地址列表頁
- 修改收貨地址
<view class="item-content" @tap="onChangeAddress(item)">
- 收貨地址Store
import { AddressItem } from '@/types/address'
import { defineStore } from 'pinia'
import { ref } from 'vue'export const useAddressStore = defineStore('address', () => {const selectedAddress = ref<AddressItem>()const changeSelectedAddress = (val: AddressItem) => {selectedAddress.value = val}return {selectedAddress,changeSelectedAddress,}
})
- 選中收貨地址
// 單純的阻止冒泡,否則修改頁面沒法跳轉@tap.stop="() => {}"// 修改收貨地址
const onChangeAddress = (item: AddressItem) => {//修改地址const addressStore = useAddressStore()addressStore.changeSelectedAddress(item)// 返回上一頁uni.navigateBack()
}
3.立即購買
- 封裝
export const getmemberOrderPreNowAPI = (data: {skuId: stringcount: stringaddressId?: string
}) => {return http<OrderPreResult>({method: 'GET',url: '/member/order/pre/now',data,})
}
- 立即購買事件,跳轉頁面傳參
@buy-now="onBuyNow"// 立即購買
const onBuyNow = (ev: SkuPopupEvent) => {// 跳轉并傳參uni.navigateTo({ url: `/pagesOrder/create/create?skuId=${ev._id}&count=${ev.buy_num}` })
}
- 立即購買
// 頁面參數
const query = defineProps<{// 可有可無skuId?: stringcount?: string
}>()// 獲取訂單信息
const orderPre = ref<OrderPreResult>()
const getmemberOrderPreData = async () => {if (query.count && query.skuId) {const res = await getmemberOrderPreNowAPI({skuId: query.skuId,count: query.count,})orderPre.value = res.result} else {const res = await getmemberOrderPreAPI()orderPre.value = res.result}
}
4.提交訂單
- 封裝請求API
// /member/order
export const postMemberOrderAPI = (data: OrderCreateParams) => {return http<{ id: string }>({method: 'POST',url: '/member/order',data,})
}
- 類型聲明文件
- 提交按鈕事件
- 調用接口成功
- 跳轉訂單詳情
// 提交訂單
const onOrderSubmit = async () => {if (!selectedAddress.value?.id) {uni.showToast({ title: '請選擇收貨地址' })}const res = await postMemberOrderAPI({addressId: selectedAddress.value!.id,buyerMessage: buyerMessage.value,deliveryTimeType: activeDelivery.value.type,goods: orderPre.value!.goods.map((v) => ({ count: v.count, skuId: v.skuId })),payChannel: 2,payType: 1,})// 關閉當前頁面,再跳轉uni.redirectTo({ url: `/pagesOrder/detail/detail?id=${res.result.id}` })
}
- 無收貨地址交互
5.自定義導航欄交互
- 導航欄左上角按鈕,返回首頁
// 獲取頁面棧
// pages是一個數組
const pages = getCurrentPages()
// 獲取當前頁面實例,數組最后一項
const pageInstance = pages.at(-1) as any<navigatorv-if="pages.length > 1"open-type="navigateBack"class="back icon-left"></navigator>
- 滾動驅動的動畫
// 頁面渲染完畢,綁定動畫效果d
onReady(() => {// 動畫效果,導航欄背景色pageInstance.animate('.navbar', // 選擇器[{ backgroundColor: 'transparent' }, { backgroundColor: '#f8f8f8' }], // 關鍵幀信息1000, // 動畫持續時長{scrollSource: '#scroller', // scroll-view 的選擇器startScrollOffset: 0, // 開始滾動偏移量endScrollOffset: 50, // 停止滾動偏移量timeRange: 1000, // 時間長度},)// 動畫效果,導航欄標題pageInstance.animate('.navbar .title', [{ color: 'transparent' }, { color: '#000' }], 1000, {scrollSource: '#scroller',timeRange: 1000,startScrollOffset: 0,endScrollOffset: 50,})// 動畫效果,導航欄返回按鈕pageInstance.animate('.navbar .back', [{ color: '#fff' }, { color: '#000' }], 1000, {scrollSource: '#scroller',timeRange: 1000,startScrollOffset: 0,endScrollOffset: 50,})
})
6.訂單狀態渲染
- 渲染訂單狀態
<template v-if="order"><!-- 訂單狀態 --><view class="overview" :style="{ paddingTop: safeAreaInsets!.top + 20 + 'px' }"><!-- 待付款狀態:展示去支付按鈕和倒計時 --><template v-if="order.orderState === OrderState.DaiFuKuan"><view class="status icon-clock">等待付款</view><view class="tips"><text class="money">應付金額: ¥ 99.00</text><text class="time">支付剩余</text>00 時 29 分 59 秒</view><view class="button">去支付</view></template><!-- 其他訂單狀態:展示再次購買按鈕 --><template v-else><!-- 訂單狀態文字 --><view class="status"> {{ orderStateList[order.orderState].text }} </view><view class="button-group"><navigatorclass="button":url="`/pagesOrder/create/create?orderId=${query.id}`"hover-class="none">再次購買</navigator><!-- 待發貨狀態:模擬發貨,開發期間使用,用于修改訂單狀態為已發貨 --><view v-if="false" class="button"> 模擬發貨 </view></view></template></view>
- 訂單狀態常量
/** 訂單狀態枚舉 */
export enum OrderState {/** 待付款 */DaiFuKuan = 1,/** 待發貨 */DaiFaHuo = 2,/** 待收貨 */DaiShouHuo = 3,/** 待評價 */DaiPingJia = 4,/** 已完成 */YiWanCheng = 5,/** 已取消 */YiQuXiao = 6,
}/** 訂單狀態列表 */
export const orderStateList = [{ id: 0, text: '' },{ id: 1, text: '待付款' },{ id: 2, text: '待發貨' },{ id: 3, text: '待收貨' },{ id: 4, text: '待評價' },{ id: 5, text: '已完成' },{ id: 6, text: '已取消' },
]
7.待支付倒計時
//倒計時
const onTimeUp = () => {// 修改訂單狀態為已取消order.value!.orderState = OrderState.YiQuXiao
}<uni-countdowncolor="#fff":show-colon="false":show-day="false"splitor-color="#fff":second="order.countdown"@timeup="onTimeUp"/>
8. 代付款-訂單支付
// 去支付
const onOrderPay = async () => {if (import.meta.env.DEV) {// 開發環境模擬支付await getPayMockAPI({ orderId: query.id })} else {// 正式微信支付const res = await getPayWxPayMiniPayAPI({ orderId: query.id })wx.requestPayment(res.result)}// 關閉當前頁,再跳轉uni.redirectTo({ url: `/pagesOrder/Payment/Payment?id=${query.id}` })
}
主要測試,開發環境模擬支付,即可
9.待發貨-模擬發貨
- dev環境
// 是否為開發環境
const isDev = import.meta.env.DEV<view@tap="onOrderSend"v-if="isDev && order.orderState === OrderState.DaiFaHuo"class="button">模擬發貨</view>
- 模擬發貨,并更新訂單狀態
// 模擬發貨
const onOrderSend = async () => {if (isDev) {await getMemberOrderConsignmentByIdAPI(query.id)// 輕提示uni.showToast({ icon: 'success', title: '模擬成功' })// 主動更新訂單狀態order.value!.orderState = OrderState.DaiFaHuo}
}
打包時這里的代碼會被自動剔除,優化掉
10.待收貨-確認收貨
僅在訂單狀態為待收貨時,可確認收貨
// 待收貨=>確認收貨
const onOrderConfirm = () => {// 二次確認彈窗uni.showModal({content: '為保障你的權益,請收到貨并確認無誤后,再確認收貨',success: async (success) => {if (success.confirm) {const res = await putMemberOrderReceiptByIdAPI(query.id)// 主動更新order.value = res.result}},})
}<!-- 待收貨狀態: 展示確認收貨按鈕 --><viewv-if="order.orderState === OrderState.DaiShouHuo"@tap="onOrderConfirm"class="button">確認收貨</view>