feat: ✨ 填写订单
This commit is contained in:
parent
6935ad15d0
commit
f8673b8553
@ -143,6 +143,17 @@
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"root": "pagesOrder",
|
||||
"pages": [
|
||||
{
|
||||
"path": "create/create",
|
||||
"style": {
|
||||
"navigationBarTitleText": "新建订单"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
|
||||
|
@ -213,9 +213,8 @@ const handlerPay = () => {
|
||||
})
|
||||
return
|
||||
}
|
||||
uni.showToast({
|
||||
title: '跳转结算页面占用',
|
||||
icon: 'none',
|
||||
uni.navigateTo({
|
||||
url: '/pagesOrder/create/create',
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
@ -7,7 +7,7 @@
|
||||
<uni-swipe-action class="item" v-for="item in addressList" :key="item.id">
|
||||
<uni-swipe-action-item :text="item.receiver">
|
||||
<view class="item-content">
|
||||
<view class="left">
|
||||
<view class="left" @tap="handleSelectAddress(item)">
|
||||
<view class="user">
|
||||
{{ item.receiver }}
|
||||
<text class="contact">{{ item.contact }}</text>
|
||||
@ -42,6 +42,7 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { deleteMemberAddressAPI, getMemberAddressAPI } from '@/services/address'
|
||||
import { useSelectedAddressStore } from '@/stores/modules/selectedAddress'
|
||||
import type { AddressItem } from '@/types/address'
|
||||
import { onShow } from '@dcloudio/uni-app'
|
||||
import { ref } from 'vue'
|
||||
@ -60,6 +61,7 @@ onShow(() => {
|
||||
getAddressList()
|
||||
})
|
||||
|
||||
// 删除地址
|
||||
const handleDelete = (id: string) => {
|
||||
uni.showModal({
|
||||
content: '确定要删除该地址吗?',
|
||||
@ -74,6 +76,20 @@ const handleDelete = (id: string) => {
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// 创建订单时更改地址
|
||||
const props = defineProps<{
|
||||
from: string
|
||||
}>()
|
||||
|
||||
const useSelectedAddress = useSelectedAddressStore()
|
||||
|
||||
const handleSelectAddress = (address: AddressItem) => {
|
||||
if (props.from === 'order') {
|
||||
useSelectedAddress.setSelectedAddress(address)
|
||||
uni.navigateBack()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
|
361
src/pagesOrder/create/create.vue
Normal file
361
src/pagesOrder/create/create.vue
Normal file
@ -0,0 +1,361 @@
|
||||
<template>
|
||||
<scroll-view scroll-y class="viewport">
|
||||
<!-- 收货地址 -->
|
||||
<navigator
|
||||
v-if="selectedAddress"
|
||||
class="shipment"
|
||||
hover-class="none"
|
||||
url="/pagesMember/address/address?from=order"
|
||||
>
|
||||
<view class="user"> {{ selectedAddress.receiver }} {{ selectedAddress.contact }} </view>
|
||||
<view class="address">
|
||||
{{ selectedAddress.fullLocation }} {{ selectedAddress.address }}
|
||||
</view>
|
||||
<text class="icon icon-right"></text>
|
||||
</navigator>
|
||||
<navigator
|
||||
v-else
|
||||
class="shipment"
|
||||
hover-class="none"
|
||||
url="/pagesMember/address/address?from=order"
|
||||
>
|
||||
<view class="address"> 请选择收货地址 </view>
|
||||
<text class="icon icon-right"></text>
|
||||
</navigator>
|
||||
|
||||
<!-- 商品信息 -->
|
||||
<view class="goods">
|
||||
<navigator
|
||||
v-for="item in orderPreList?.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.replaceAll(',', ' ') }} </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="related">
|
||||
<view class="item">
|
||||
<text class="text">配送时间</text>
|
||||
<picker :range="deliveryList" range-key="text" @change="onChangeDelivery">
|
||||
<view class="icon-fonts picker">{{ activeDelivery.text }}</view>
|
||||
</picker>
|
||||
</view>
|
||||
<view class="item">
|
||||
<text class="text">订单备注</text>
|
||||
<input
|
||||
class="input"
|
||||
:cursor-spacing="30"
|
||||
placeholder="可选,建议留言前先与商家沟通确认"
|
||||
v-model="buyerMessage"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 支付金额 -->
|
||||
<view class="settlement">
|
||||
<view class="item">
|
||||
<text class="text">商品总价: </text>
|
||||
<text class="number symbol">{{ orderPreList?.summary.totalPrice.toFixed(2) }}</text>
|
||||
</view>
|
||||
<view class="item">
|
||||
<text class="text">运费: </text>
|
||||
<text class="number symbol">{{ orderPreList?.summary.postFee.toFixed(2) }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
|
||||
<!-- 吸底工具栏 -->
|
||||
<view class="toolbar" :style="{ paddingBottom: safeAreaInsets?.bottom + 'px' }">
|
||||
<view class="total-pay symbol">
|
||||
<text class="number"> {{ orderPreList?.summary.totalPayPrice.toFixed(2) }} </text>
|
||||
</view>
|
||||
<view
|
||||
class="button"
|
||||
:class="{ disabled: orderPreList == null || orderPreList?.goods.length === 0 }"
|
||||
>
|
||||
提交订单
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { getMemberOrderAPI } from '@/services/order'
|
||||
import { useSelectedAddressStore } from '@/stores/modules/selectedAddress'
|
||||
import type { AddressItem } from '@/types/address'
|
||||
import type { OrderPreResult } from '@/types/order'
|
||||
import { onShow } from '@dcloudio/uni-app'
|
||||
import { computed, ref } from 'vue'
|
||||
|
||||
// 获取屏幕边界到安全区域距离
|
||||
const { safeAreaInsets } = uni.getSystemInfoSync()
|
||||
// 订单备注
|
||||
const buyerMessage = ref('')
|
||||
// 配送时间
|
||||
const deliveryList = ref([
|
||||
{ type: 1, text: '时间不限 (周一至周日)' },
|
||||
{ type: 2, text: '工作日送 (周一至周五)' },
|
||||
{ type: 3, text: '周末配送 (周六至周日)' },
|
||||
])
|
||||
// 当前配送时间下标
|
||||
const activeIndex = ref(0)
|
||||
// 当前配送时间
|
||||
const activeDelivery = computed(() => deliveryList.value[activeIndex.value])
|
||||
// 修改配送时间
|
||||
const onChangeDelivery: UniHelper.SelectorPickerOnChange = (ev) => {
|
||||
activeIndex.value = ev.detail.value
|
||||
}
|
||||
|
||||
// 获取预付订单
|
||||
const orderPreList = ref<OrderPreResult>()
|
||||
const getOrderPre = async () => {
|
||||
const res = await getMemberOrderAPI()
|
||||
console.log(res)
|
||||
if (res.code === '1') {
|
||||
orderPreList.value = res.result
|
||||
}
|
||||
}
|
||||
|
||||
onShow(() => {
|
||||
getOrderPre()
|
||||
})
|
||||
|
||||
// 收货地址
|
||||
const useSelectedAddress = useSelectedAddressStore()
|
||||
const selectedAddress = computed(() => {
|
||||
return (
|
||||
useSelectedAddress.selectedAddress ||
|
||||
orderPreList.value?.userAddresses.find((item) => item.isDefault === 1)
|
||||
)
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
page {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
background-color: #f4f4f4;
|
||||
}
|
||||
|
||||
.symbol::before {
|
||||
content: '¥';
|
||||
font-size: 80%;
|
||||
margin-right: 5rpx;
|
||||
}
|
||||
|
||||
.shipment {
|
||||
margin: 20rpx;
|
||||
padding: 30rpx 30rpx 30rpx 84rpx;
|
||||
font-size: 26rpx;
|
||||
border-radius: 10rpx;
|
||||
background: url(https://pcapi-xiaotuxian-front-devtest.itheima.net/miniapp/images/locate.png)
|
||||
20rpx center / 50rpx no-repeat #fff;
|
||||
position: relative;
|
||||
|
||||
.icon {
|
||||
font-size: 36rpx;
|
||||
color: #333;
|
||||
transform: translateY(-50%);
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: 20rpx;
|
||||
}
|
||||
|
||||
.user {
|
||||
color: #333;
|
||||
margin-bottom: 5rpx;
|
||||
}
|
||||
|
||||
.address {
|
||||
color: #666;
|
||||
}
|
||||
}
|
||||
|
||||
.goods {
|
||||
margin: 20rpx;
|
||||
padding: 0 20rpx;
|
||||
border-radius: 10rpx;
|
||||
background-color: #fff;
|
||||
|
||||
.item {
|
||||
display: flex;
|
||||
padding: 30rpx 0;
|
||||
border-top: 1rpx solid #eee;
|
||||
|
||||
&:first-child {
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
.picture {
|
||||
width: 170rpx;
|
||||
height: 170rpx;
|
||||
border-radius: 10rpx;
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
|
||||
.meta {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.name {
|
||||
height: 80rpx;
|
||||
font-size: 26rpx;
|
||||
color: #444;
|
||||
}
|
||||
|
||||
.attrs {
|
||||
line-height: 1.8;
|
||||
padding: 0 15rpx;
|
||||
margin-top: 6rpx;
|
||||
font-size: 24rpx;
|
||||
align-self: flex-start;
|
||||
border-radius: 4rpx;
|
||||
color: #888;
|
||||
background-color: #f7f7f8;
|
||||
}
|
||||
|
||||
.prices {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
margin-top: 6rpx;
|
||||
font-size: 28rpx;
|
||||
|
||||
.pay-price {
|
||||
margin-right: 10rpx;
|
||||
color: #cf4444;
|
||||
}
|
||||
|
||||
.price {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
text-decoration: line-through;
|
||||
}
|
||||
}
|
||||
|
||||
.count {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
font-size: 26rpx;
|
||||
color: #444;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.related {
|
||||
margin: 20rpx;
|
||||
padding: 0 20rpx;
|
||||
border-radius: 10rpx;
|
||||
background-color: #fff;
|
||||
|
||||
.item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
min-height: 80rpx;
|
||||
font-size: 26rpx;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.input {
|
||||
flex: 1;
|
||||
text-align: right;
|
||||
margin: 20rpx 0;
|
||||
padding-right: 20rpx;
|
||||
font-size: 26rpx;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.item .text {
|
||||
width: 125rpx;
|
||||
}
|
||||
|
||||
.picker {
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.picker::after {
|
||||
content: '\e6c2';
|
||||
}
|
||||
}
|
||||
|
||||
/* 结算清单 */
|
||||
.settlement {
|
||||
margin: 20rpx;
|
||||
padding: 0 20rpx;
|
||||
border-radius: 10rpx;
|
||||
background-color: #fff;
|
||||
|
||||
.item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
height: 80rpx;
|
||||
font-size: 26rpx;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.danger {
|
||||
color: #cf4444;
|
||||
}
|
||||
}
|
||||
|
||||
/* 吸底工具栏 */
|
||||
.toolbar {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: calc(var(--window-bottom));
|
||||
z-index: 1;
|
||||
|
||||
background-color: #fff;
|
||||
height: 100rpx;
|
||||
padding: 0 20rpx;
|
||||
border-top: 1rpx solid #eaeaea;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
box-sizing: content-box;
|
||||
|
||||
.total-pay {
|
||||
font-size: 40rpx;
|
||||
color: #cf4444;
|
||||
|
||||
.decimal {
|
||||
font-size: 75%;
|
||||
}
|
||||
}
|
||||
|
||||
.button {
|
||||
width: 220rpx;
|
||||
text-align: center;
|
||||
line-height: 72rpx;
|
||||
font-size: 26rpx;
|
||||
color: #fff;
|
||||
border-radius: 72rpx;
|
||||
background-color: #27ba9b;
|
||||
}
|
||||
|
||||
.disabled {
|
||||
opacity: 0.6;
|
||||
}
|
||||
}
|
||||
</style>
|
38
src/services/order.ts
Normal file
38
src/services/order.ts
Normal file
@ -0,0 +1,38 @@
|
||||
import type { OrderPreResult } from '@/types/order'
|
||||
import { http } from '@/utils/http'
|
||||
|
||||
/** 订单状态枚举 */
|
||||
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: '已取消' },
|
||||
]
|
||||
|
||||
/**
|
||||
* 获取预付订单
|
||||
*/
|
||||
export const getMemberOrderAPI = () => {
|
||||
return http<OrderPreResult>({
|
||||
url: '/member/order/pre',
|
||||
method: 'GET',
|
||||
})
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
import type { LoginResult, ProfileDetail, ProfileParams } from '@/types/member'
|
||||
import type { LoginResult, ProfileDetail } from '@/types/member'
|
||||
import { defineStore } from 'pinia'
|
||||
import { ref } from 'vue'
|
||||
|
||||
|
19
src/stores/modules/selectedAddress.ts
Normal file
19
src/stores/modules/selectedAddress.ts
Normal file
@ -0,0 +1,19 @@
|
||||
import type { AddressItem } from '@/types/address'
|
||||
import { defineStore } from 'pinia'
|
||||
import { ref } from 'vue'
|
||||
|
||||
/**
|
||||
* 选中的地址
|
||||
*/
|
||||
export const useSelectedAddressStore = defineStore('selectedAddress', () => {
|
||||
const selectedAddress = ref<AddressItem | null>(null)
|
||||
|
||||
const setSelectedAddress = (address: AddressItem) => {
|
||||
selectedAddress.value = address
|
||||
}
|
||||
|
||||
return {
|
||||
selectedAddress,
|
||||
setSelectedAddress,
|
||||
}
|
||||
})
|
165
src/types/order.d.ts
vendored
Normal file
165
src/types/order.d.ts
vendored
Normal file
@ -0,0 +1,165 @@
|
||||
import type { OrderState } from '@/services/order'
|
||||
import type { AddressItem } from './address'
|
||||
import type { PageParams } from '@/types/global'
|
||||
|
||||
/** 获取预付订单 返回信息 */
|
||||
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
|
||||
}
|
||||
|
||||
/** 提交订单 请求参数 */
|
||||
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
|
||||
}
|
||||
|
||||
/** 订单详情 返回信息 */
|
||||
export type OrderResult = {
|
||||
/** 订单编号 */
|
||||
id: string
|
||||
/** 订单状态,1为待付款、2为待发货、3为待收货、4为待评价、5为已完成、6为已取消 */
|
||||
orderState: OrderState
|
||||
/** 倒计时--剩余的秒数 -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
|
||||
}
|
||||
|
||||
/** 物流信息 返回值类型 */
|
||||
export type OrderLogisticResult = {
|
||||
/** 快递公司 */
|
||||
company: {
|
||||
/** 公司名称 */
|
||||
name: string
|
||||
/** 快递编号 */
|
||||
number: string
|
||||
/** 联系电话 */
|
||||
tel: string
|
||||
}
|
||||
/** 商品件数 */
|
||||
count: number
|
||||
/** 物流日志 */
|
||||
list: LogisticItem[]
|
||||
}
|
||||
|
||||
/** 物流日志 */
|
||||
export type LogisticItem = {
|
||||
/** 信息ID */
|
||||
id: string
|
||||
/** 信息文字 */
|
||||
text: string
|
||||
/** 时间 */
|
||||
time: string
|
||||
}
|
||||
|
||||
/** 订单列表参数 */
|
||||
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
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user