2025-12-02 23:51:09 +08:00

496 lines
18 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="container p-bottom" :style="appThemeStyle">
<view>
<!-- 实物订单选择配送方式 -->
<view>
<!-- 配送方式选项卡 -->
<!-- <view class="swiper-tab dis-flex flex-y-center flex-x-around">
<view class="swiper-tab-item" :class="{ on: curDelivery == DeliveryTypeEnum.EXPRESS.value }"
@click="handleSwichDelivery(DeliveryTypeEnum.EXPRESS.value)">
<text>快递配送</text>
</view>
</view> -->
<!-- 快递配送配送地址 -->
<view @click="onSelectAddress" class="flow-delivery">
<view class="flow-delivery__detail dis-flex flex-y-center">
<view class="detail-location dis-flex">
<text class="iconfont icon-dingwei"></text>
</view>
<view class="detail-content flex-box">
<block v-if="order.address">
<view class="detail-content__title dis-flex">
<text class="f-30">{{ order.address.buyerName }}</text>
<text class="detail-content__title-phone f-28">{{ order.address.buyerPhone }}</text>
</view>
<view class="address detail-content__describe">
<text class="region" v-for="(region, idx) in order.address.region" :key="idx">{{ region }}</text>
<text class="detail">{{ order.address.detail }}</text>
</view>
</block>
<block v-else>
<view class="detail-content__describe dis-flex">
<text class="col-6">请选择配送地址</text>
</view>
</block>
</view>
<view class="detail-arrow dis-flex">
<text class="iconfont icon-arrow-right"></text>
</view>
</view>
</view>
</view>
<!-- 商品列表 -->
<view class="checkout_list" v-for="(item, index) in order.goodsList" :key="index">
<view class="flow-shopList dis-flex" data-index="index" @click="onTargetGoods(item.goodsId)">
<!-- 商品图片 -->
<view class="flow-list-left">
<image mode="scaleToFill" :src="item.image"></image>
</view>
<view class="flow-list-right flex-box">
<!-- 商品名称 -->
<text class="goods-name twoline-hide">{{ item.title }}</text>
<!-- 商品规格 -->
<view class="goods-props clearfix">
<view class="goods-props-item" v-for="(props, idx) in item.skuInfo" :key="idx">
<text class="group-name">{{ props.propertyName }}: </text>
<text>{{ props.propertyValue }}</text>
</view>
</view>
<!-- 商品数量和单价 -->
<view class="flow-list-cont dis-flex flex-x-between flex-y-center">
<text class="small">×{{ item.buy_num }}</text>
<text class="flow-cont" :class="[item.is_user_grade ? 'price-delete' : '']">¥{{ item.price }}</text>
</view>
<!-- 会员折扣价 -->
<view v-if="item.is_user_grade" class="grade-price">
<text>会员折扣价:¥{{ 0 }}</text>
</view>
</view>
</view>
</view>
<view class="flow-num-box b-f">
<!-- <text>共{{ order.orderTotalNum }}件商品,合计:</text>
<text class="flow-money col-m">¥{{ order.orderTotalPrice }}</text> -->
<text>共{{ order.orderTotalNum }}件商品</text>
</view>
<!-- 商品金额 -->
<view class="flow-all-money b-f m-top20">
<view class="flow-all-list dis-flex">
<text class="flex-five">订单总金额:</text>
<view class="flex-five t-r">
<text class="col-m">¥{{ order.orderTotalPrice }}</text>
</view>
</view>
<!-- 优惠券 -->
<view class="flow-all-list dis-flex">
<text class="flex-five">优惠券:</text>
<view class="flex-five t-r">
<view v-if="order.couponList.length > 0" @click="handleShowPopup()">
<text class="col-m" v-if="order.couponId > 0">-¥{{ order.couponMoney }}</text>
<text class="col-m" v-else>有{{ order.couponList.length }}张优惠券</text>
<text class="right-arrow iconfont icon-arrow-right"></text>
</view>
<text v-else class="">无优惠券可用</text>
</view>
</view>
<!-- 积分抵扣 -->
<!-- <view v-if="order.isAllowPoints" class="points flow-all-list dis-flex flex-y-center">
<view class="block-left flex-five" @click="handleShowPoints()">
<text class="title">可用{{ setting.points_name }}抵扣:</text>
<text class="iconfont icon-help"></text>
</view>
<view class="flex-five dis-flex flex-x-end flex-y-center">
<text class="points-money col-m">-¥{{ order.pointsMoney }}</text>
<u-switch v-model="isUsePoints" size="42" :active-color="appTheme.mainBg" @change="getOrderData()"></u-switch>
</view>
</view> -->
<!-- 配送费用 -->
<view v-if="curDelivery == DeliveryTypeEnum.EXPRESS.value" class="dis-flex flow-all-list">
<text class="flex-five">配送费用:</text>
<view class="flex-five t-r">
<view>
<text class="col-m" v-if="!order.isIntraRegion">+¥{{ 0 }}</text>
<text v-else>不在配送范围</text>
</view>
</view>
</view>
</view>
<!-- 买家留言 -->
<view class="flow-all-money b-f m-top20">
<view class="ipt-wrapper flow-all-list">
<input class="input" v-model="remark" placeholder="选填买家留言50字以内" />
</view>
</view>
<!-- 提交订单 -->
<view class="flow-fixed-footer b-f m-top10">
<view class="dis-flex chackout-box">
<view class="chackout-left pl-12">实付款:
<text class="col-m">¥{{ order.orderTotalPrice }}</text>
</view>
<view class="chackout-right" @click="onSubmitOrder()">
<view class="flow-btn f-32" :class="{ disabled }">提交订单</view>
</view>
</view>
</view>
<!-- 积分说明弹窗 -->
<u-modal v-model="showPoints" :title="`${setting.points_name}说明`">
<scroll-view class="points-content" :scroll-y="true">
<text>{{ setting.points_describe }}</text>
</scroll-view>
</u-modal>
<!-- 优惠券弹出框 -->
<u-popup v-model="showPopup" mode="bottom">
<view class="popup__coupon">
<view class="coupon__title f-30">选择优惠券</view>
<!-- 优惠券列表 -->
<scroll-view :scroll-y="true" style="height: 650rpx;">
<view class="coupon-list">
<view class="coupon-item" v-for="(item, index) in order.couponList" :key="index">
<view class="item-wrapper" :class="[ !item.state.value ? 'disable' : '' ]" @click="handleSelectCoupon(index)">
<!-- 优惠券类型 (标签) -->
<view class="coupon-tag">
<text>{{ CouponTypeEnum[item.coupon_type].name }}</text>
</view>
<view class="coupon-left">
<!-- 优惠额度/折扣 -->
<view class="coupon-reduce">
<block v-if="item.coupon_type == CouponTypeEnum.FULL_DISCOUNT.value">
<view class="coupon-reduce-unit"><text></text></view>
<view class="coupon-reduce-amount">
<text class="value">{{ item.reduce_price }}</text>
</view>
</block>
<block v-if="item.coupon_type == CouponTypeEnum.DISCOUNT.value">
<view class="coupon-reduce-amount">
<text class="value">{{ item.discount }}</text>
</view>
</block>
</view>
<!-- 最低消费金额 -->
<text class="coupon-hint">{{ item.min_price }}元可用</text>
</view>
<view class="coupon-content">
<view class="coupon-name">{{ item.name }}</view>
<view class="coupon-middle">
<view class="coupon-expire">
<text v-if="item.expire_type == CouponTypeEnum.FULL_DISCOUNT.value">领取后{{ item.expire_day }}天内有效</text>
<text v-if="item.expire_type == CouponTypeEnum.DISCOUNT.value">
<block v-if="item.start_time === item.end_time">{{ item.start_time }} 当天有效</block>
<block v-else>{{ item.start_time }}~{{ item.end_time }}</block>
</text>
</view>
</view>
<view v-if="item.describe" class="coupon-expand" @click.stop="handleDescribe(index)">
<text>使用说明</text>
<text class="coupon-expand-arrow iconfont icon-arrow-down" :class="[item.expand ? 'expand' : '']" />
</view>
</view>
<view class="coupon-right">
<view class="my-radio" :class="{ checked: selectCouponId == item.user_coupon_id }">
<u-icon name="checkbox-mark" :size="20" />
</view>
</view>
</view>
<!-- 优惠券描述 -->
<view :class="[item.expand ? 'expand' : '']" class="coupon-expand-rules">
<view class="coupon-expand-rules-content">
<view class="pre">{{ item.describe }}</view>
</view>
</view>
</view>
</view>
</scroll-view>
<!-- 不使用优惠券 -->
<view class="coupon__do_not">
<view class="control" @click="handleNotUseCoupon()">
<text class="f-26">不使用优惠券</text>
</view>
</view>
</view>
</u-popup>
</view>
<u-toast ref="uToast" />
</view>
</template>
<script>
import * as CheckoutApi from '@/api/checkout'
import * as OrderApi from '@/api/order'
import { CouponTypeEnum } from '@/common/enum/coupon'
import { OrderTypeEnum, DeliveryTypeEnum } from '@/common/enum/order'
import storage from '@/utils/storage'
const CouponColors = ['red', 'blue', 'violet', 'yellow']
// 根据指定mode获取对应的api类
const getCheckoutApi = (mode) => {
const apiEnum = {
buyNow: CheckoutApi,
cart: CheckoutApi
}
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
}
return param
}
export default {
data() {
return {
// 枚举类
OrderTypeEnum,
DeliveryTypeEnum,
CouponTypeEnum,
// 当前页面参数
options: {},
// 配送方式
// isShowTab: false,
curDelivery: 10,
DeliveryTypeEnum,
// 优惠券颜色组
CouponColors,
// 选择的优惠券
selectCouponId: 0,
// 是否使用积分抵扣
isUsePoints: false,
// 买家留言
remark: '',
// 禁用submit按钮
disabled: false,
// 是否显示积分说明
showPoints: false,
// 是否显示优惠券弹窗
showPopup: false,
// 订单信息 (从后端api中获取)
order: {
couponList: [],
},
// 商城设置
setting: {}
}
},
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
this.options = options
},
/**
* 生命周期函数--监听页面的卸载
*/
onUnload() {
},
/**
* 生命周期函数--监听页面显示
*/
onShow() {
// 获取当前订单信息
const goods = storage.get('goods')
console.warn('----- my data is goods: ', goods)
goods.forEach(item => {
item.skuInfo = item.skuInfo || []
})
this.order.goodsList = goods
// this.getOrderData()
OrderApi.apiGetAddressList({}).then(res => {
const ob = this.order.address = res.data.rows.find(item => item.status === 'default') || {}
this.order.address.region = [ob.province, ob.city, ob.region]
this.order.couponList = []
this.order.orderTotalPrice = goods.reduce((total, item) => total + item.price * item.buy_num, 0)
this.order.orderTotalNum = goods.reduce((total, item) => total + item.buy_num, 0)
})
},
methods: {
// 快递配送:选择收货地址
onSelectAddress() {
this.$navTo('pages/address/index', { from: 'checkout' })
},
// 跳转到商品详情页
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
const skuList = app.order.goodsList.map(item => ({
skuId: item.goodsSkuId,
num: item.buy_num,
}))
OrderApi.apiOrderAdd({ buyerAddressId: this.order.address.id, vvTradeOrderLineDTOList: skuList }).then(res => {
res.data.package = res.data.prepayId
res.data.timeStamp = String(res.data.timeStamp)
// 判断订单是否已支付: 已支付跳转订单列表 未支付跳转支付页
if (!res.data.package) {
app.showToast(result.message, 1500)
setTimeout(() => app.$navTo('pages/order/index', {}, 'redirectTo'), 1500)
} else {
// 订单未支付: 跳转到订单支付页
setTimeout(() => app.$navTo('pages/checkout/cashier/index', res.data, 'redirectTo'), 100)
}
}).finally(() => setTimeout(() => app.disabled = false, 1600))
},
// 表单提交的数据
getFormData() {
const app = this
const { options } = app
// 表单数据
const form = {
delivery: app.curDelivery,
couponId: app.selectCouponId || 0,
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
}
return true
},
// 显示toast信息
showToast(title, duration = 2000) {
this.$refs.uToast.show({ title, duration })
},
// 获取api请求的参数
getRequestParam() {
const app = this
const { options } = app
// 结算模式的固定参数
const modeParam = getModeParam(options.mode, options)
// 订单结算参数(用户选择)
const orderParam = {
delivery: app.curDelivery || 0,
couponId: app.selectCouponId || 0,
isUsePoints: app.isUsePoints ? 1 : 0,
}
return { ...orderParam, ...modeParam }
},
// 获取订单数据
getOrderData() {
const app = this
const { options: { mode } } = app
const params = app.getRequestParam()
getCheckoutApi(mode)
.order(mode, params)
.then(result => app.initData(result.data))
.catch(err => err)
},
// 初始化数据
initData({ order, setting }) {
const app = this
app.order = order
app.setting = setting
// 当前选择的配送方式
// app.curDelivery = order.delivery
// app.isShowTab = setting.deliveryType.length > 1 // 如果只有一种配送方式则不显示选项卡
// 是否使用积分抵扣
// app.isUsePoints = order.isUsePoints
app.selectCouponId = order.couponId
},
// 切换配送方式
/* handleSwichDelivery(key) {
this.curDelivery = key
this.getOrderData()
},
// 显示积分抵扣说明
handleShowPoints() {
this.showPoints = true
}, */
// 显示优惠券弹窗
handleShowPopup() {
this.showPopup = true
},
// 展开优惠券描述
handleDescribe(index) {
const { couponList } = this.order
couponList[index].expand = !couponList[index].expand
},
// 选择优惠券
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 = app.selectCouponId == couponItem.user_coupon_id ? 0 : couponItem.user_coupon_id
// 重新获取订单信息
app.getOrderData()
// 隐藏优惠券弹层
app.showPopup = false
},
// 不使用优惠券
handleNotUseCoupon() {
this.selectCouponId = 0
// 重新获取订单信息
this.getOrderData()
// 隐藏优惠券弹层
this.showPopup = false
},
}
}
</script>
<style lang="scss" scoped>
@import "./style.scss";
</style>