目录
填写订单页
静态结构
购物车结算
立即购买
页面传参
选择收货地址
提交订单
订单详情页
静态结构
自定义导航栏交互
获取订单详情
订单状态
再次购买
支付倒计时
订单支付
微信支付说明
参考代码
支付成功页
模拟发货
确认收货
订单物流
删除订单
取消订单
订单列表页
静态结构
Tabs 滑动切换
获取订单列表
订单列表渲染
分页加载
订单支付
订单模块页面较多,建议用新的分包文件夹独立管理订单模块页面:填写订单页,支付订单页,订单详情页,订单列表页。
小兔鲜儿项目有三种方式可以生成订单信息,分别是:购物车结算、立即购买、再次购买。
张三 13333333333
广东省 广州市 天河区 黑马程序员3
请选择收货地址
ins风小碎花泡泡袖衬110-160cm
藏青小花 130
99.00
99.00
x5
配送时间
{{ activeDelivery.text }}
订单备注
商品总价:
495.00
运费:
5.00
99.00
提交订单
在购物车点击去结算后,进入填写订单页,用户可以选择订单的收货地址或补充订单信息。
接口详情
接口地址:/member/order/pre
请求方式:GET
登录权限: 是
请求参数:无
接口封装
src/services/order.ts
import type { OrderPreResult } from '@/types/order'
import { http } from '@/utils/http'
/**
* 填写订单-获取预付订单
*/
export const getMemberOrderPreAPI = () => {
return http({
method: 'GET',
url: '/member/order/pre',
})
}
类型声明
src/services/order.d.ts
import type { AddressItem } from './address'
/** 获取预付订单 返回信息 */
export type OrderPreResult = {
/** 商品集合 [ 商品信息 ] */
goods: OrderPreGoods[]
/** 结算信息 */
summary: {
/** 商品总价 */
totalPrice: number
/** 邮费 */
postFee: number
/** 应付金额 */
totalPayPrice: number
}
/** 用户地址列表 [ 地址信息 ] */
userAddresses: AddressItem[]
}
/** 商品信息 */
export type OrderPreGoods = {
/** 属性文字,例如“颜色:瓷白色 尺寸:8寸” */
attrsText: string
/** 数量 */
count: number
/** id */
id: string
/** 商品名称 */
name: string
/** 实付单价 */
payPrice: string
/** 图片 */
picture: string
/** 原单价 */
price: string
/** SKUID */
skuId: string
/** 实付价格小计 */
totalPayPrice: string
/** 小计总价 */
totalPrice: string
}
填写订单 – 渲染基本信息
填写订单 – 收货地址
将后端返回的预付订单数据,渲染到页面中。
从商品详情页的 SKU
组件直接点击【立即购买按钮】跳转到填写订单页,需要传递页面参数。
接口详情
接口地址:/member/order/pre/now
请求方式:GET
登录权限: 是
请求参数:
Query
字段名称 | 是否必须 | 默认值 | 备注 |
---|---|---|---|
skuId | 是 | 无 | 商品库存 ID |
count | 是 | 无 | 商品数量 |
addressId | 否 | 无 | 收货地址 ID |
接口封装
/**
* 填写订单-获取立即购买订单
*/
export const getMemberOrderPreNowAPI = (data: {
skuId: string
count: string
addressId?: string
}) => {
return http({
method: 'GET',
url: '/member/order/pre/now',
data,
})
}
从商品详情页的【立即购买事件】中收集两个必要参数,跳转填写订单页并传递页面参数。
商品详情页
填写订单页
收货地址在地址管理页面中选择,为了更好管理选中收货地址,创建独立 Store 维护。
地址 Store
src/stores/modules/address.ts
import type { AddressItem } from '@/types/address'
import { defineStore } from 'pinia'
import { ref } from 'vue'
export const useAddressStore = defineStore('address', () => {
const selectedAddress = ref()
const changeSelectedAddress = (val: AddressItem) => {
selectedAddress.value = val
}
return { selectedAddress, changeSelectedAddress }
})
地址管理页
修改选中收货地址,
组件需要阻止事件冒泡。
pagesMember/address/address.vue
{{ item.receiver }}
{{ item.contact }}
默认
{{ item.fullLocation }} {{ item.address }}
{}"
>
修改
订单填写页
{{ selecteAddress.receiver }} {{ selecteAddress.contact }}
{{ selecteAddress.fullLocation }} {{ selecteAddress.address }}
收集填写订单页的数据,点击页面底部的提交订单按钮,创建一个新的订单。
接口详情
接口地址:/member/order
请求方式:POST
登录权限: 是
请求参数:
Body
字段名称 | 是否必须 | 默认值 | 备注 |
---|---|---|---|
addressId | 是 | 无 | 收货地址 ID |
goods | 是 | 无 | 订单商品 |
deliveryTimeType | 是 | 无 | 配送时间 |
buyerMessage | 是 | 无 | 买家留言 |
payType | 是 | 无 | 支付方式(小程序中固定在线支付) |
payChannel | 是 | 无 | 支付渠道(小程序中固定微信支付) |
接口封装
/**
* 提交订单
* @param data 请求参数
*/
export const postMemberOrderAPI = (data: OrderCreateParams) => {
return http<{ id: string }>({
method: 'POST',
url: '/member/order',
data,
})
}
类型声明
/** 提交订单 请求参数 */
export type OrderCreateParams = {
/** 所选地址Id */
addressId: string
/** 配送时间类型,1为不限,2为工作日,3为双休或假日 */
deliveryTimeType: number
/** 订单备注 */
buyerMessage: string
/** 商品集合[ 商品信息 ] */
goods: {
/** 数量 */
count: number
/** skuId */
skuId: string
}[]
/** 支付渠道:支付渠道,1支付宝、2微信--支付方式为在线支付时,传值,为货到付款时,不传值 */
payChannel: 1 | 2
/** 支付方式,1为在线支付,2为货到付款 */
payType: 1 | 2
}
/** 提交订单 返回信息 */
export type OrderCreateResult = {
/** 订单Id */
id: string
}
参考代码
点击提交订单按钮实现创建订单,订单创建成功后,跳转到订单详情并传递订单 id。
提交订单
订单提交成功后,接下来进入到订单详情页。
需要展示多种订单状态 并实现不同订单状态对应的业务。
已完成通过页面参数获取到订单 id 等基础业务。
订单详情
等待付款
应付金额: ¥ 99.00
支付剩余
00 时 29 分 59 秒
去支付
待付款
再次购买
模拟发货
2023-04-14 13:14:20
张三 13333333333
广东省 广州市 天河区 黑马程序员
ins风小碎花泡泡袖衬110-160cm
藏青小花, 130
¥
99.00
x1
申请售后
去评价
商品总价:
99.00
运费:
10.00
应付金额:
109.00
订单信息
订单编号: {{ query.id }} 复制
下单时间: 2023-04-14 13:14:20
去支付
取消订单
再次购买
确认收货
去评价
删除订单
订单取消
请选择取消订单的原因:
{{ item }}
取消
确认
注意事项
滚动驱动的动画目前仅支持微信小程序端,暂不支持 H5 端、App 端,多端兼容时添加条件编译。
参考代码
订单详情
...滚动容器
版本升级
animate
类型。// 基于小程序的 Page 实例类型扩展 uni-app 的 Page
type PageInstance = Page.PageInstance & WechatMiniprogram.Page.InstanceMethods
const pageInstance = pages.at(-1) as PageInstance
请求封装
/**
* 获取订单详情
* @param id 订单id
*/
export const getMemberOrderByIdAPI = (id: string) => {
return http({
method: 'GET',
url: `/member/order/${id}`,
})
}
类型声明
/** 订单详情 返回信息 */
export type OrderResult = {
/** 订单编号 */
id: string
/** 订单状态,1为待付款、2为待发货、3为待收货、4为待评价、5为已完成、6为已取消 */
orderState: number
/** 倒计时--剩余的秒数 -1 表示已经超时,正数表示倒计时未结束 */
countdown: number
/** 商品集合 [ 商品信息 ] */
skus: OrderSkuItem[]
/** 收货人 */
receiverContact: string
/** 收货人手机 */
receiverMobile: string
/** 收货人完整地址 */
receiverAddress: string
/** 下单时间 */
createTime: string
/** 商品总价 */
totalMoney: number
/** 运费 */
postFee: number
/** 应付金额 */
payMoney: number
}
/** 商品信息 */
export type OrderSkuItem = {
/** sku id */
id: string
/** 商品 id */
spuId: string
/** 商品名称 */
name: string
/** 商品属性文字 */
attrsText: string
/** 数量 */
quantity: number
/** 购买时单价 */
curPrice: number
/** 图片地址 */
image: string
}
在订单详情中除了展示订单信息外,还需要根据不同订单状态展示不同的内容。
订单状态(orderState) | 含义 |
---|---|
1 | 待付款 |
2 | 待发货 |
3 | 待收货 |
4 | 待评价 |
5 | 已完成 |
6 | 已取消 |
订单状态常量
枚举的作用:通过枚举来替代无意义的订单状态数字,提高程序的可读性。
src/services/constants.ts
/** 订单状态枚举 */
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: '已取消' },
]
根据后端返回的数据渲染订单详情。
等待付款
应付金额: ¥ 99.00
支付剩余
00 时 29 分 59 秒
去支付
{{ orderStateList[order.orderState].text }}
再次购买
模拟发货
现在是第三种生成订单信息,从订单详情页的【再次购买】按钮跳转到填写订单页,需要传递页面参数。
接口封装
/**
* 填写订单-再次购买
* @param id 订单id
*/
export const getMemberOrderRepurchaseByIdAPI = (id: string) => {
return http({
method: 'GET',
url: `/member/order/repurchase/${id}`,
})
}
参考代码
订单详情页
再次购买
填写订单页
·
通过 uni-ui 组件库的 uni-countdown 实现倒计时。
等待付款
应付金额: ¥ 99.00
支付剩余
去支付
订单支付其实就是根据订单号查询到支付信息,在小程序中调用微信支付的 API 而已。
wx26729f20b9efae3a
的开发者才能调用该接口。此外,开发者还需要微信授权登录。调用接口
import { http } from '@/utils/http'
/**
* 获取微信支付参数
* @param data orderId 订单id
*/
export const getPayWxPayMiniPayAPI = (data: { orderId: string }) => {
return http({
method: 'GET',
url: '/pay/wxPay/miniPay',
data,
})
}
/**
* 模拟支付-内测版
* @param data orderId 订单id
*/
export const getPayMockAPI = (data: { orderId: string }) => {
return http({
method: 'GET',
url: '/pay/mock',
data,
})
}
通过环境变量区分开发环境,调用不同接口。
去支付
主要用于展示支付结果。
src/pagesOrder/payment/payment.vue
支付成功
返回首页
查看订单
仅在订单状态为待发货时,可模拟发货,调用后订单状态修改为待收货,包含模拟物流。
仅在开发期间使用,项目上线后应该是由商家发货。
接口封装
/**
* 模拟发货-内测版
* @description 在DEV环境下使用,仅在订单状态为待发货时,可模拟发货,调用后订单状态修改为待收货,包含模拟物流。
* @param id 订单id
*/
export const getMemberOrderConsignmentByIdAPI = (id: string) => {
return http({
method: 'GET',
url: `/member/order/consignment/${id}`,
})
}
参考代码
模拟发货
点击确认收货时需二次确认,提示文案:为保障您的权益,请收到货并确认无误后,再确认收货
接口封装
/**
* 确认收货
* @description 仅在订单状态为待收货时,可确认收货。
* @param id 订单id
*/
export const putMemberOrderReceiptByIdAPI = (id: string) => {
return http({
method: 'PUT',
url: `/member/order/${id}/receipt`,
})
}
参考代码
确认收货
仅在订单状态为待收货,待评价,已完成时,可获取物流信息。
请求封装
/**
* 获取订单物流
* @description 仅在订单状态为待收货,待评价,已完成时,可获取物流信息。
* @param id 订单id
*/
export const getMemberOrderLogisticsByIdAPI = (id: string) => {
return http({
method: 'GET',
url: `/member/order/${id}/logistics`,
})
}
/** 物流信息 返回值类型 */
export type OrderLogisticResult = {
/** 快递公司 */
company: {
/** 公司名称 */
name: string
/** 快递编号 */
number: string
/** 联系电话 */
tel: string
}
/** 商品件数 */
count: number
/** 物流日志 */
list: LogisticItem[]
}
/** 物流日志 */
export type LogisticItem = {
/** 信息ID */
id: string
/** 信息文字 */
text: string
/** 时间 */
time: string
}
仅在订单状态为待评价,已完成,已取消时,可删除订单。
接口封装
/**
* 删除订单
* @description 仅在订单状态为待评价,已完成,已取消时,可删除订单。
* @param data ids 订单集合
*/
export const deleteMemberOrderAPI = (data: { ids: string[] }) => {
return http({
method: 'DELETE',
url: `/member/order`,
data,
})
}
仅在订单状态为待付款时,可取消订单。
接口封装
/**
* 取消订单
* @description 仅在订单状态为待付款时,可取消订单。
* @param id 订单id
* @param data cancelReason 取消理由
*/
export const getMemberOrderCancelByIdAPI = (id: string, data: { cancelReason: string }) => {
return http({
method: 'PUT',
url: `/member/order/${id}/cancel`,
data,
})
}
根据订单的不同状态展示订单列表,并实现多 Tabs 分页加载。
待付款
2023-04-14 13:14:20
待付款
ins风小碎花泡泡袖衬110-160cm
藏青小花 130
共5件商品
实付
¥ 99
去支付
再次购买
确认收货
{{ true ? '没有更多数据~' : '正在加载...' }}
订单列表的 Tabs 支持滑动切换,从【我的】进入订单列表,能高亮对应的下标
{{ item.title }}
...省略
当前页面是多 Tabs 列表的情况,每个 Tabs 都是独立的列表,并支持分页加载。
接口信息
接口地址:/member/order
请求方式:GET
Query 参数:
字段名称 | 是否必须 | 默认值 | 备注 |
---|---|---|---|
page | 可选 | 1 | 页码 |
pageSize | 可选 | 10 | 页容量 |
orderState | 可选 | 0 | 订单状态 |
接口封装
/**
* 获取订单列表
* @param data orderState 订单状态
*/
export const getMemberOrderAPI = (data: OrderListParams) => {
return http({
method: 'GET',
url: `/member/order`,
data,
})
}
import type { PageParams } from '@/types/global'
/** 订单列表参数 */
export type OrderListParams = PageParams & { orderState: number }
/** 订单列表 */
export type OrderListResult = {
/** 总记录数 */
counts: number
/** 数据集合 [ 订单信息 ] */
items: OrderItem[]
/** 当前页码 */
page: number
/** 总页数 */
pages: number
/** 页尺寸 */
pageSize: number
}
/** 订单列表项 */
export type OrderItem = OrderResult & {
/** 总件数 */
totalNum: number
}
为了更好维护多 Tabs 列表,把列表抽离成业务组件,在组件内部独立维护列表数据,包括分页,下拉刷新等业务。
参考代码
订单列表页,把订单状态传递给列表组件(父传子)。
列表组件
{{ order.createTime }}
{{ orderStateList[order.orderState].text }}
{{ item.name }}
{{ item.attrsText }}
共{{ order.totalNum }}件商品
实付
¥ {{ order.payMoney }}
去支付
再次购买
确认收货
{{ true ? '没有更多数据~' : '正在加载...' }}
分页加载的逻辑在之前我们已经学习过,本节就不再重复讲义的内容了,下拉刷新业务同理。
订单支付功能之前我们已经学习过,也不再重复。
确认收货,删除订单等按钮的业务同理。