填写订单
渲染基本信息
静态结构(分包)-封装请求API-初始化调用-类型声明-界面渲染
收货地址
计算默认收货地址-地址列表页-修改收货地址-收货地址store-选中收货地址
收取默认地址并展示在页面中---computed
定义独立的store模块,存放选中的地址
address.vue新增修改地址的函数
点击地址的时候调用change修改地址,记得传递item
有无选中的地址(selectedAddress) 没有才渲染默认
因为修改按钮原本绑定了跳转到表单界面 但是现在又有返回上一页(changeAddress) 所以禁止冒泡 绑定个空函数
立即购买
提交订单
javascript
//提交订单
const onOrderSubmit = async () => {
if (!selectAddress.value?.id) {
return uni.showToast({ icon: 'none', title: '请选择收获地址' })
}
const res = await postMemberOrderAPI({
addressId: selectAddress.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
})
//关闭当前页面,跳转到订单详情,传递订单id
uni.redirectTo({ url: `/pagesOrder/detail/detail?id=${res.result.id}` })
}
订单详情
自定义导航栏交互
javascript
//获取页面栈
const pages = getCurrentPages()
//获取当前页面实例,数组最后一项
const pageInstance = pages.at(-1) as any
//页面渲染完毕,绑定动画效果
onReady(() => {
//动画效果,导航栏背景色
pageInstance.animate(
'.navbar',
[{ backgroundColor: 'transparent' }, { backgroundColor: '#f8f8f8' }],
1000,
{
scrollSource: '#scroller',
timeRange: 1000,
startScrollOffset: 0,
endScrollOffset: 50
}
),
//动画效果,导航栏标题
pageInstance.animate('.navbar .title', [{ color: '#fff' }, { 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
})
})
订单状态渲染
待支付倒计时
待付款-订单支付
javascript
//接口封装
import { http } from '@/utils/http'
/**
* 获取微信支付参数
* @param data orderId 订单id
*/
export const getPayWxPayMiniPayAPI = (data: { orderId: string }) => {
return http<WechatMiniprogram.RequestPaymentOption>({
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
})
}
待发货-模拟发货
待收货
注意:1.DEV环境,订单状态为待发货时可模拟发货。isDEV判断环境 
javascript
//模拟发货
const onOrderSend = async () => {
if (isDev) {
await getMemberOrderConsignmentByIdAPI(query.id)
uni.showToast({ icon: 'success', title: '模拟发货' })
//主动更新订单状态
order.value!.orderState = OrderState.DaiFaHuo
}
}
<templete>
<view
v-if="isDev && order.orderState == OrderState.DaiFaHuo"
@tap="onOrderSend"
class="button"
>
模拟发货
</view>
</templete>
确认收货
javascript
<script>
//确认收货
const onOrderConfirm = async () => {
//二次确认弹窗
uni.showModal({
content: '为保障您的权益,请收到货并确认无误后,再确认收货',
success: async (success) => {
if (success.confirm) {
const res = await putMemberOrderReceiptByIdAPI(query.id)
//更新订单状态
order.value = res.result
console.log('已经确认收货啦')
}
}
})
}
<script>
<templete>
<view v-if="order.orderState == OrderState.DaiShouHuo"
@tap="onOrderConfirm"
class="button"
>
确认收货
</view>
</templete>
javascript
/**
* 确认收货
* @description 仅在订单状态为待收货时,可确认收货。
* @param id 订单id
*/
export const putMemberOrderReceiptByIdAPI = (id: string) => {
return http<OrderResult>({
method: 'PUT',
url: `/member/order/${id}/receipt`
})
}
订单物流
触发条件:获取订单详情的时候展现(onLoad),要求:orderState是发货完后 
javascript
/**
* 获取订单物流
* @description 仅在订单状态为待收货,待评价,已完成时,可获取物流信息。
* @param id 订单id
*/
export const getMemberOrderLogisticsByIdAPI = (id: string) => {
return http<OrderLogisticResult>({
method: 'GET',
url: `/member/order/${id}/logistics`
})
}
javascript
<script>
//获取订单详情
const order = ref<OrderResult>()
const getMemberOrderByIdData = async () => {
const res = await getMemberOrderByIdAPI(query.id)
order.value = res.result
if (
[OrderState.YiWanCheng, OrderState.DaiPingJia, OrderState.DaiShouHuo].includes(
order.value?.orderState
)
) {
getMemberOrderLogisticsByIdData()
}
}
//获取物流信息
const logisticList = ref<LogisticItem[]>([])
const getMemberOrderLogisticsByIdData = async () => {
const res = await getMemberOrderLogisticsByIdAPI(query.id)
logisticList.value = res.result.list
}
</script>
删除订单
javascript
/**
* 删除订单
* @description 仅在订单状态为待评价,已完成,已取消时,可删除订单。
* @param data ids 订单集合
*/
export const deleteMemberOrderAPI = (data: { ids: string[] }) => {
return http({
method: 'DELETE',
url: `/member/order`,
data
})
}
javascript
<script>
//删除订单
const onOrderDelete = () => {
uni.showModal({
content: '是否删除订单',
success: async (success) => {
if (success.confirm) {
await deleteMemberOrderAPI({ ids: [query.id] })
uni.redirectTo({ url: '/pagesOrder/list/list' })
console.log('已经删除成功了')
}
}
})
}
<script>
<templete>
<!-- 待评价/已完成/已取消 状态: 展示删除订单 -->
<view
class="button delete"
@tap="onOrderDelete"
v-if="order.orderState >= OrderState.DaiPingJia"
>
删除订单
</view>
<templete>
订单列表
Tabs滑动切换


abs页面跳转高亮
javascript
//获取页面参数(知道是'待付款'/'待发货。。')
const query = defineProps<{
type: string
}>()
//高亮下标(query.type是string,通过Number(XX)转换成number格式)
const activeIndex = ref(orderTabs.value.findIndex((v) => v.orderState === Number(query.type)))

列表渲染
封装列表组件-订单状态父传子-封装请求API-准备请求参数-初始化调用-页面渲染 
javascript
//定义props
const props = defineProps<{ orderState: number }>()
//请求参数
const queryParams: OrderListParams = {
page: 1,
pageSize: 5,
orderState: props.orderState
}
//获取订单列表
const orderList = ref<OrderItem[]>([])
const isLoading = ref(false)
// 3. 把接口请求拆成两步:初始化 + 加载更多
const loadOrderList = async () => {
if (isLoading.value) return
isLoading.value = true
try {
// 关键:每次请求前,用 props.orderState 覆盖 queryParams
queryParams.orderState = props.orderState
const res = await getMemberOrderAPI(queryParams)
orderList.value = res.result.items
} catch (err) {
uni.showToast({ icon: 'none', title: '加载失败' })
} finally {
isLoading.value = false
}
}
onMounted(() => {
// 初始化时,重置页码,再调用接口
queryParams.page = 1
loadOrderList()
})
javascript
/**
* 获取订单列表
* @param data orderState 订单状态
*/
export const getMemberOrderAPI = (data: OrderListParams) => {
return http<OrderListResult>({
method: 'GET',
url: `/member/order`,
data
})
}
订单支付
将detail页面的订单支付进行复用 但是! 原本的query.id由于query是局部变量,只能把query.id改成id,而这个id由函数进行调用的时候页面传参
javascript
<script>
//订单支付
const onOrderPay = async (id: string) => {
if (import.meta.env.DEV) {
//开发环境模拟支付
await getPayMockAPI({ orderId: id })
} else {
//正式环境支付
const res = await getPayWxPayMiniPayAPI({ orderId: id })
wx.requestPayment(res.result)
}
//成功提示
uni.showToast({ title: '支付成功', icon: 'success' })
const order = orderList.value.find((v) => v.id === id)
order!.orderState = OrderState.DaiFaHuo
}
</script>
<templete>
<view @tap="onOrderPay(order.id)" class="button primary">去支付</view>
</templete>
项目打包
微信小程序端发布上线
条件编译和网页端打包
<!-- #ifdef MP-WEIXIN --><!-- #ifdef MP-WEIXIN -->
<!-- #ifdef APP-PLUS|| H5 --><!-- #ifdef MP-WEIXIN -->


Android端
预览和调试
云打包
iOS端-预览、调试、打包
跨端兼容
样式兼容
视口差异
pnpm build:h5--打开网页版命令 
样式隔离
组件兼容
eg 有open-type属性的button组件只在小程序平台可应用
JSAPI兼容

uniCloud云开发
准备工作







城市选择和云数据库
javascript
<!-- #ifdef MP-WEIXIN -->
<picker
class="picker"
mode="region"
:value="form.fullLocation?.split(' ') || []"
@change="onRegionChange"
>
<view v-if="form.fullLocation">{{ form.fullLocation }}</view>
<view v-else class="placeholder">请选择省/市/区(县)</view>
</picker>
<!-- #endif -->
<!-- #ifdef APP-PLUS||H5 -->
<uni-data-picker
popup-title="请选择城市"
placeholder="请选择地址"
collection="opendb-city-china"
field="code as value, name as text"
orderby="value asc"
:step-searh="true"
self-field="code"
parent-field="parent_code"
>
</uni-data-picker>
<!-- #endif -->

城市选择完成



































