You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
yanzong_qianduan/pages/sureOrder/index.vue

1114 lines
25 KiB

<template>
<view class="sureOrder">
<view>
<u-navbar title="确认订单" :border-bottom="false" title-color="#333" :background="background"></u-navbar>
</view>
<view class="buyType">
<view class="toDoor" :class="buyType=='sm'?'':'toDoor-dis'" @click="choseType('sm')">
送货上门
</view>
<view class="toDoor" :class="buyType=='zq'?'':'toDoor-dis'" @click="choseType('zq')">
到店自取
</view>
<view class="toDoor-on" :style="{'left': buyType=='sm'?'0':'345rpx'}">{{buyType=='zq'?'到店自取':'送货上门'}}</view>
</view>
<view class="getSelf" >
<view class="address" v-if="buyType=='sm'">
<view class="addAddress">
<view class="tip" v-if="true">请点击添加收货地址</view>
<view class="info" v-else>
<view class="name"></view>
<view class="detail"></view>
</view>
</view>
<view class="leftImg">
<image :src="$picUrl+'/static/order/left.png'"></image>
</view>
</view>
<view class="shopAddress" v-if="buyType=='zq'">
<view class="youTime">
花梨服务站
</view>
<view class="leftImg">
切换
<image src="/static/order/left.png" mode=""></image>
</view>
</view>
<view class="addressDetail">
</view>
<view class="lookMap" v-if="buyType=='zq'">
<image src="/static/user/address.png" mode="" class="addressIcon"></image>
<view class="range">
距您16.39km
</view>
<view class="checkMap">
查看地图
</view>
<image src="/static/order/left.png" mode="" class="rightIcon"></image>
</view>
<view class="pickUp">
<view class="pickPeople">
<view class="title">
取件人
</view>
<view class="name">
</view>
</view>
<view class="pickPeople">
<view class="title">
</view>
<view class="name">
<image src="/static/order/edit.png" mode="" class="edit"></image>
</view>
</view>
<view class="pickPeople">
<view class="title">
预留电话
</view>
<view class="name">
</view>
</view>
<view class="pickPeople">
<view class="title">
</view>
<view class="name">
<image src="/static/order/edit.png" mode="" class="edit"></image>
</view>
</view>
</view>
</view>
<view class="preTime">
<view class="left">
<view class="bagImg">
<image src="/static/order/bag.png" mode="" class="bag"></image>
街边取
</view>
<view class="preText">
如果您不方便只需要在街边稍候送到您的手上
</view>
</view>
<view class="switch">
<switch />
</view>
</view>
<view class="time">
<view class="youTime">
预计到货时间
</view>
<view class="leftImg">
<text class="leftText">2024-12-20 0930</text>
<image src="/static/order/left.png" mode=""></image>
</view>
</view>
<view class="time">
<view class="youTime">
您期待的收货时间
</view>
<view class="leftImg">
请选择
<image src="/static/order/left.png" mode=""></image>
</view>
</view>
<view class="goodsDetail">
<view class="goodsType">
<image src="/static/order/bag.png" mode="" class="bag"></image>
<text>大白兔家电</text>
<image src="/static/order/left.png" mode="" class="leftIcon"></image>
</view>
<view class="goods">
<view class="goodsImg">
<image :src="goodsInfo.goods_image" mode=""></image>
</view>
<view class="goodsInfo">
<view class="goodsName">
{{goodsInfo.goods_name}}
</view>
<view class="goodsPrice">
<text>{{goodsInfo.goods_price_min}}</text>
</view>
</view>
<view class="goodsNum">
x1
</view>
</view>
</view>
<view class="time">
<view class="youTime" style="width: 60rpx;">
留言
</view>
<input type="textarea" placeholder="建议留言前先和店家沟通" v-model="remark" style="width:100%;" maxlength="100" />
</view>
<view class="orderTips">
<view class="orderTitle">
<view class="total">
商品总额
</view>
<view class="price">
¥{{goodsInfo.goods_price_min}}
</view>
</view>
<view class="orderTitle">
<view class="total">
运费
</view>
<view class="price">
¥{{goodsInfo.goods_price_min}}
</view>
</view>
<view class="orderTitle">
<view class="total">
商品数量
</view>
<view class="price">
<text class="couponNum">1件</text>
</view>
</view>
<view class="orderTitle">
<view class="total">
优惠券
</view>
<view class="price" @click="choseCoupon">
<text class="couponNum">{{couponList.length}}张可用</text>
<image src="/static/order/left.png" mode=""></image>
</view>
</view>
<view class="line">
</view>
<view class="amount">
<view class="left">
</view>
<view class="right">
<text class="totalNum">共1件,合计:</text>
<text class="allPrice">¥{{goodsInfo.goods_price_min}}</text>
</view>
</view>
</view>
<view class="payType">
<view class="itemType">
<view class="payName">
<image src="/static/order/wChat.png" mode="" class="payIcon"></image>
微信支付
</view>
<image src="/static/order/right.png" mode="" class="chose"></image>
</view>
<view class="line">
</view>
<view class="itemType">
<view class="" v-for="(item,index) in payMethList" :key="index" @click="chosePayType(item)">
<view class="payName">
<image src="/static/order/friends.png" mode="" class="payIcon"></image>
余额支付
</view>
<image src="/static/order/right.png" mode="" class="chose" v-if="payType==item.method"></image>
</view>
</view>
<view class="line">
</view>
<!-- <view class="itemType">
<view class="payName">
<image src="/static/order/shop.png" mode="" class="payIcon"></image>
到店支付
</view>
</view> -->
</view>
<view class="footer">
<view class="meetPrice">
应付款
<text class="type">¥</text>
<text class="price">{{goodsInfo.goods_price_min}}</text>
</view>
<view class="btn" @click="orderPay">
提交订单
</view>
</view>
</view>
</template>
<script>
import * as Verify from '@/utils/verify'
import * as CheckoutApi from '@/api/checkout'
import * as SharpCheckoutApi from '@/api/sharp/checkout'
import * as BargainCheckoutApi from '@/api/bargain/checkout'
import * as GrouponCheckoutApi from '@/api/groupon/checkout'
import { CouponTypeEnum } from '@/common/enum/coupon'
import { OrderTypeEnum, DeliveryTypeEnum } from '@/common/enum/order'
const CouponColors = ['red', 'blue', 'violet', 'yellow']
// 根据指定mode获取对应的api类
const getCheckoutApi = (mode) => {
const apiEnum = {
buyNow: CheckoutApi,
cart: CheckoutApi,
bargain: BargainCheckoutApi,
sharp: SharpCheckoutApi,
groupon: GrouponCheckoutApi
}
return apiEnum[mode]
}
// 根据指定mode获取param
const getModeParam = (mode, options) => {
const param = {}
// 结算模式: 立即购买
if (mode === 'buyNow') {
param.goodsId = options.goodsId
param.goodsNum = options.goodsNum
param.goodsSkuId = options.goodsSkuId
}
// 结算模式: 购物车
if (mode === 'cart') {
param.cartIds = options.cartIds
}
// 结算模式: 砍价活动
if (mode === 'bargain') {
param.taskId = options.taskId
param.goodsSkuId = options.goodsSkuId
}
// 结算模式: 整点秒杀
if (mode === 'sharp') {
param.activeTimeId = options.activeTimeId
param.sharpGoodsId = options.sharpGoodsId
param.goodsSkuId = options.goodsSkuId
param.goodsNum = options.goodsNum
}
// 结算模式: 多人拼团
if (mode === 'groupon') {
param.grouponGoodsId = options.grouponGoodsId
param.taskId = options.taskId
param.goodsSkuId = options.goodsSkuId
param.goodsNum = options.goodsNum
param.stepPeople = options.stepPeople
}
return param
}
export default {
data() {
return {
// 枚举类
OrderTypeEnum,
DeliveryTypeEnum,
CouponTypeEnum,
// 当前页面参数
options: {},
// 配送方式
isShowTab: false,
DeliveryTypeEnum,
curDelivery: null,
// 自提信息
selectedShopId: 0, // 选择的门店ID
linkman: '', // 自提联系人
phone: '', // 自提联系电话
// 优惠券颜色组
CouponColors,
// 选择的优惠券
selectCouponId: 0,
// 是否使用积分抵扣
isUsePoints: false,
// 买家留言
remark: '',
// 禁用submit按钮
disabled: false,
// 是否显示积分说明
showPoints: false,
// 是否显示优惠券弹窗
showPopup: false,
// 订单信息 (从后端api中获取)
order: {
// 商品列表
goodsList: [],
// 优惠券列表
couponList: [],
// 是否存在收货地址
existAddress: false,
// 默认收货地址
address: null,
// 是否存在收货地址
existAddress: false,
// 当前用户收货城市是否存在配送规则中
isIntraRegion: true,
// 是否存在错误
hasError: false,
// 错误信息
errorMsg: '',
},
// 个人信息
personal: {},
// 商城设置
setting: {}
}
},
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
this.options = options;
console.log(options)
// 注册全局事件订阅: 选择自提门店
uni.$on('syncSelectedId', selectedId => {
this.selectedShopId = selectedId
})
},
/**
* 生命周期函数--监听页面的卸载
*/
onUnload() {
// 卸载全局事件订阅: 选择自提门店
uni.$off('syncSelectedId')
},
/**
* 生命周期函数--监听页面显示
*/
onShow() {
// 获取当前订单信息
this.getOrderData()
},
methods: {
// 获取订单数据
getOrderData() {
const app = this
const { options: { mode } } = app
// 请求的参数
const params = app.getRequestParam()
// 请求api
getCheckoutApi(mode)
.order(mode, params)
.then(result => app.initData(result.data))
.catch(err => err)
},
// 初始化数据
initData({ order, setting, personal }) {
const app = this
app.order = order
app.personal = personal
app.setting = setting
// 显示错误信息
if (order.hasError) {
app.showToast(order.errorMsg, 3000)
}
// 当前选择的配送方式
app.curDelivery = order.delivery
// 如果只有一种配送方式则不显示选项卡
app.isShowTab = setting.deliveryType.length > 1
// 上门自提联系信息
if (app.linkman === '') {
app.linkman = order.lastExtract.linkman
}
if (app.phone === '') {
app.phone = order.lastExtract.phone
}
},
// 获取api请求的参数
getRequestParam() {
const app = this
const { options } = app
// 结算模式的固定参数
const modeParam = getModeParam(options.mode, options)
// 订单结算参数(用户选择)
const orderParam = {
delivery: app.curDelivery || 0,
shopId: app.selectedShopId || 0,
couponId: app.selectCouponId || 0,
isUsePoints: app.isUsePoints ? 1 : 0,
}
return { ...orderParam, ...modeParam }
},
// 切换配送方式
handleSwichDelivery(key) {
this.curDelivery = key
this.getOrderData()
},
// 显示积分说明
handleShowPoints() {
this.showPoints = true
},
// 显示优惠券弹窗
handleShowPopup() {
this.showPopup = true
},
// 选择优惠券
handleSelectCoupon(index) {
const app = this
const { couponList } = app.order
// 当前选择的优惠券
const couponItem = couponList[index]
// 判断是否在适用范围
if (!couponItem.is_apply) {
app.showToast(couponItem.not_apply_info)
return
}
// 记录选中的优惠券id
app.selectCouponId = couponItem.user_coupon_id
// 重新获取订单信息
app.getOrderData()
// 隐藏优惠券弹层
app.showPopup = false
},
// 不使用优惠券
handleNotUseCoupon() {
const app = this
app.selectCouponId = 0
// 重新获取订单信息
app.getOrderData()
// 隐藏优惠券弹层
app.showPopup = false
},
// 快递配送:选择收货地址
onSelectAddress() {
this.$navTo('pages/address/index', { from: 'checkout' })
},
// 上门自提:选择自提点
onSelectExtractPoint() {
this.$navTo('pages/shop/extract', { selectedId: this.selectedShopId })
},
// 跳转到商品详情页
onTargetGoods(goodsId) {
this.$navTo('pages/goods/detail', { goodsId })
},
// 订单提交
onSubmitOrder() {
const app = this
if (app.disabled) {
return false
}
// 表单验证
if (!app.onVerifyFrom()) {
return false
}
// 按钮禁用
app.disabled = true
// 请求api
getCheckoutApi(app.options.mode)
.submit(app.options.mode, app.getFormData())
.then(result => {
// 订单创建成功: 跳转到订单支付页
const orderId = result.data.orderId
setTimeout(() => {
this.$navTo('pages/checkout/cashier/index', { orderId }, 'redirectTo')
}, 100)
})
.catch(res => app.showToast(res.errMsg, 3000))
.finally(() => setTimeout(() => app.disabled = false, 800))
},
// 跳转到我的订单(等待1秒)
navToMyOrder() {
setTimeout(() => {
this.$navTo('pages/order/index', {}, 'redirectTo')
}, 1000)
},
// 表单提交的数据
getFormData() {
const app = this
const { options } = app
// 表单数据
const form = {
delivery: app.curDelivery,
couponId: app.selectCouponId || 0,
shopId: app.selectedShopId || 0,
linkman: app.linkman,
phone: app.phone,
isUsePoints: app.isUsePoints ? 1 : 0,
remark: app.remark || '',
}
// 获取不同模式的参数
const modeParam = getModeParam(options.mode, options)
return { ...form, ...modeParam }
},
// 表单验证
onVerifyFrom() {
const app = this
if (app.hasError) {
app.showToast(app.errorMsg, 3000)
return false
}
// 验证自提填写的联系方式
if (app.curDelivery == DeliveryTypeEnum.EXTRACT.value) {
app.linkman = app.linkman.trim()
app.phone = app.phone.trim()
if (app.selectedShopId <= 0) {
app.showToast('请选择自提的门店')
return false
}
if (Verify.isEmpty(app.linkman)) {
app.showToast('请填写自提联系人')
return false
}
if (Verify.isEmpty(app.phone)) {
app.showToast('请填写自提联系电话')
return false
}
if (!Verify.isPhone(app.phone)) {
app.showToast('请输入正确的联系电话')
return false
}
}
return true
},
// 显示toast信息
showToast(title, duration = 2000) {
this.$refs.uToast.show({ title, duration })
}
}
}
</script>
<style lang="scss" scoped>
.sureOrder {
width: 750rpx;
min-height: 750rpx;
padding-bottom: 120rpx;
background: url('https://www.royaum.com.cn/static/news/login-bg.png') center top no-repeat;
background-size: 100% auto;
}
.buyType {
width: 700rpx;
margin: 30rpx auto 0;
position: relative;
height: 88rpx;
.toDoor {
width: 50%;
height: 74rpx;
background-color: rgba(255, 255, 255, 0.5);
font-size: 28rpx;
font-weight: 500;
color: #606060;
line-height: 74rpx;
text-align: center;
float: left;
margin-top: 14rpx;
float: left;
&-on{
width: 350rpx;
height: 88rpx;
background-color: #FFF;
text-align: center;
font-size: 34rpx;
font-weight: 400;
color: #000;
line-height: 88rpx;
position: absolute;
bottom: 0;
left: 0;
z-index: 2;
border-radius: 10rpx 10rpx 0 0;
}
&-dis{
border-radius: 10rpx 10rpx 0 0;
}
}
}
.getSelf {
width: 700rpx;
margin: 0 auto;
.shopAddress {
display: flex;
align-items: center;
justify-content: space-between;
.youTime {
font-size: 24rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 400;
color: #000000;
}
.leftImg {
font-size: 24rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 400;
color: #9E9E9E;
image {
width: 18rpx;
height: 18rpx;
margin-left: 16rpx;
}
}
}
background-image: url('https://www.royaum.com.cn/static/order/map.png');
background-size: 100%;
height: 160rpx;
padding: 14rpx 46rpx 0 32rpx;
box-sizing: border-box;
.addressDetail {
height: 34rpx;
font-size: 24rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 400;
color: #838383;
line-height: 34rpx;
margin-top: 6rpx;
}
.lookMap {
display: flex;
align-items: center;
margin-top: 8rpx;
.addressIcon {
width: 23rpx;
height: 26rpx;
margin-right: 14rpx;
}
.range {
font-size: 20rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 400;
color: #F42B17;
line-height: 26rpx;
padding-right: 10rpx;
border-right: 2rpx solid #D9D9D9;
margin-right: 10rpx;
}
.checkMap {
font-size: 20rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 400;
color: #2B2B2B;
line-height: 26rpx;
margin-right: 24rpx;
}
.rightIcon {
width: 18rpx;
height: 18rpx;
}
}
.pickUp {
display: flex;
justify-content: space-around;
margin-top: 26rpx;
.pickPeople {
.title {
height: 28rpx;
font-size: 20rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 400;
color: #838383;
line-height: 28rpx;
}
.name {
height: 28rpx;
font-size: 20rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 600;
color: #2C2C2C;
line-height: 28rpx;
margin-top: 10rpx;
.edit {
width: 20rpx;
height: 20rpx;
}
}
}
}
}
.leftText {
font-size: 24rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 400;
color: #F21A1C;
line-height: 28rpx;
}
.address {
margin-left: 26rpx;
background-image: url('../../static/order/map.png');
width: 694rpx;
height: 154rpx;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 52rpx 0 32rpx;
.addAddress {
font-size: 28rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 500;
color: #F32E2E;
}
.leftImg {
width: 18rpx;
height: 18rpx;
image {
width: 100%;
height: 100%;
}
}
}
.preTime {
width: 694rpx;
height: 140rpx;
background: #FFFFFF;
border-radius: 10rpx 10rpx 10rpx 10rpx;
opacity: 1;
margin: 12rpx 0 0 26rpx;
display: flex;
justify-content: space-between;
padding: 34rpx 0 0 30rpx;
.left {
.bagImg {
height: 30rpx;
font-size: 24rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 400;
color: #000000;
line-height: 30rpx;
margin-bottom: 10rpx;
.bag {
width: 30rpx;
height: 30rpx;
}
}
}
.preText {
height: 34rpx;
font-size: 24rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 400;
color: #959595;
line-height: 34rpx;
}
}
.time {
display: flex;
width: 694rpx;
height: 90rpx;
background: #FFFFFF;
border-radius: 10rpx 10rpx 10rpx 10rpx;
opacity: 1;
margin: 12rpx 0 0 26rpx;
align-items: center;
justify-content: space-between;
padding: 0 32rpx 0 28rpx;
.youTime {
font-size: 24rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 400;
color: #000000;
}
.leftImg {
font-size: 24rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 400;
color: #9E9E9E;
image {
width: 18rpx;
height: 18rpx;
margin-left: 16rpx;
}
}
}
.goodsDetail {
width: 694rpx;
min-height: 266rpx;
background: #FFFFFF;
border-radius: 10rpx 10rpx 10rpx 10rpx;
opacity: 1;
margin: 12rpx 0 0 26rpx;
padding: 32rpx 24rpx 24rpx 12rpx;
.goodsType {
display: flex;
align-items: center;
font-size: 28rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 500;
color: #333333;
.bag {
width: 30rpx;
height: 30rpx;
margin-right: 20rpx;
}
.leftIcon {
width: 18rpx;
height: 18rpx;
margin-left: 20rpx;
}
}
.goods {
display: flex;
align-items: center;
margin-top: 28rpx;
.goodsImg {
width: 162rpx;
height: 148rpx;
border-radius: 0rpx 0rpx 0rpx 0rpx;
opacity: 1;
image {
width: 100%;
height: 100%;
}
}
.goodsInfo {
margin-left: 20rpx;
.goodsName {
min-height: 40rpx;
font-size: 28rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 400;
color: #1E1E1E;
line-height: 40rpx;
margin-bottom: 4rpx;
}
.goodsPrice {
height: 50rpx;
font-size: 24rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 600;
color: #F21A1C;
line-height: 50rpx;
text {
font-size: 36rpx;
}
}
}
.goodsNum {
font-size: 28rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 500;
color: #1E1E1E;
margin-left: 150rpx;
}
}
}
.orderTips {
width: 694rpx;
height: 342rpx;
background: #FFFFFF;
border-radius: 10rpx 10rpx 10rpx 10rpx;
opacity: 1;
margin: 12rpx 0 0 26rpx;
padding: 22rpx 36rpx 24rpx 24rpx;
.orderTitle {
margin-bottom: 24rpx;
display: flex;
justify-content: space-between;
height: 34rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 400;
color: #2D2D2D;
line-height: 34rpx;
.total {
font-size: 24rpx;
}
.price {
.couponNum {
font-size: 28rpx;
color: #F42B17;
}
font-size: 28rpx;
image {
width: 18rpx;
height: 18rpx;
margin-left: 18rpx;
}
}
}
.amount {
display: flex;
justify-content: space-between;
margin-top: 20rpx;
.left {
width: 20rpx;
height: 34rpx;
}
.right {
display: flex;
align-items: center;
.totalNum {
height: 34rpx;
font-size: 24rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 400;
color: #000000;
line-height: 34rpx;
}
.allPrice {
font-size: 28rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 600;
color: #F42B17;
line-height: 34rpx;
}
}
}
}
.line {
width: 100%;
height: 0rpx;
opacity: 1;
border: 2rpx solid #F1F1F1;
}
.payType {
width: 694rpx;
height: 270rpx;
background: #FFFFFF;
border-radius: 10rpx 10rpx 10rpx 10rpx;
opacity: 1;
margin: 12rpx 0 0rpx 26rpx;
padding: 24rpx 26rpx 0;
.line {
margin-bottom: 24rpx;
}
.itemType {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 28rpx;
.payName {
display: flex;
align-items: center;
height: 42rpx;
font-size: 24rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 400;
color: #000000;
line-height: 42rpx;
.payIcon {
width: 42rpx;
height: 42rpx;
margin-right: 16rpx;
}
}
.chose {
width: 34rpx;
height: 24rpx;
margin-right: 26rpx;
}
}
}
.footer {
width: 100%;
height: 120rpx;
position: fixed;
background-color: #FFF;
bottom: 0;
display: flex;
justify-content: space-between;
align-items: center;
.meetPrice {
margin-left: 26rpx;
font-size: 24rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 400;
color: #000000;
.type {
font-size: 24rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 400;
color: #F42B17;
margin-left: 12rpx;
}
.price {
font-size: 40rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 600;
color: #F42B17;
}
}
.btn {
width: 214rpx;
height: 74rpx;
background: linear-gradient(180deg, #FD5D06 0%, #F3211A 100%);
border-radius: 100rpx 100rpx 100rpx 100rpx;
opacity: 1;
text-align: center;
font-size: 28rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 500;
color: #FFFFFF;
line-height: 74rpx;
margin-right: 20rpx;
}
}
</style>