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>