uniapp-商城-75-shop(8.1-商品列表,选好了 进入的订单支付页面-商品列表)

        选购好商品后,从购物车进入到订单页面,而安城订单页面的逻辑处理,和页面完善。在前面我们已经将订单页面的布局进行了说明。

        订单页面包含几个栏目,第一个是我们的快递方式,存在自提和外送,包含选择用户的默认地址;

        第二是我们商品页面,购物车中商品的展示;第三个就是支付方式,有微信和支付宝;第四个就是确认支付页面。

        本文介绍了电商平台订单支付页面的开发实现,主要包含以下内容:1. 从购物车跳转到订单支付页面的流程;2. 订单页面的四大模块:配送方式、商品列表、支付方式和支付确认;3. 商品列表组件的复用设计,通过props参数实现灵活调用;4. 支付页面核心代码实现,包括支付方式选择、地址获取、订单创建和支付处理等功能;5. 通过Vuex管理购物车数据,实现数据共享和状态管理。整个支付流程采用模块化设计思路,注重组件复用性和数据交互处理。

1、从shop中购物车页面跳转到订单页面

1.1 shop的购物车页面

1.2 购物车的选好了,点击后跳转到订单页面

            //跳转至确认订单也买那
            goPay(){

                uni.navigateTo({

                    url:”/pagesub/pageshop/paypage/paypage”
                })
            },

1.3 订单支付页面

2、订单支付paypage页面

2.1 物流方式页面

2.2 商品列表页面

2.3 支付方式界面

默认就是微信,如不是微信就然如下的方式运行

2.4 支付确认

3、支付页面paypage的商品列表(2.2小节)

            <!– 购物列表 –>
            <view class=”goodsList”>
                <goods-list :goodsList=”carsList” :totalPrice=”totalPrice” :prePrice=”preferentialPrice”
                    :totalNum=”buyNum”></goods-list>
            </view>

3.1 使用组件 good-list

<template>
	<view class="goodsLayout">
		<view class="wrapper">
			<!-- 描述数量多少 buyNum 来至于父级,父级来自于vuex -->
			<view class="title">共{
           {goodsList.length}}类商品 {
           {buyNum}}件</view>

			<!-- 选购商品列表 -->
			<view class="list">
				<!-- goodsList父传来的值 -->
				<view class="row" v-for="(item,index) in goodsList" key="index">
					<!-- 左边是商品的缩略图 名称 -->
					<view class="left">
						<image :src="item.thumb[0].url">{item.name}}</view>
					</view>
					<!-- 中间是商品数量 -->
					<view class="center">×{
           {item.numvalue}}</view>
					<!-- 商品的价格 -->
					<view class="right">
						<view class="big">¥{
           {priceFormat(item.price)}}</view>
						<view class="small" v-if="item.before_price">¥{
           {priceFormat(item.before_price)}}</view>
					</view>
				</view>
			</view>

			<!--  商品的价格合计-->
			<view class="total">
				<text>
					已优惠¥{
           {priceFormat(prePrice)}},
				</text> 合计 <text class="big">¥{
           {priceFormat(totalPrice)}}</text>
			</view>
		</view>
	</view>
</template>

3.1.1 其中priceFormat来自于公共方法中的价格格式化

    import {

        priceFormat
    } from “@/utils/tools.js”

记得在方法里面要定义:

        methods: {

            priceFormat
        }

3.2 订单支付页面paypage 的处理

从good-list中来看,有部分值来至于父级也就是 paypage页面。

为了goodlist 组件能被很多页面调用,我们就把里面的参数进行了传值处理。避免写得不灵活。

在这个订单支付页面要使用,在订单查看页面也要使用。但是值是不一样得。通过那个调用,那个传值得方式,灵活定义参数需要得值。

            <!– 购物列表 –>
            <view class=”goodsList”>
                <goods-list :goodsList=”carsList” :totalPrice=”totalPrice” :prePrice=”preferentialPrice”
                    :totalNum=”buyNum”></goods-list>
            </view>

上面是该页面调用,需要传得数值。
                <goods-list :goodsList=”carsList” :totalPrice=”totalPrice” :prePrice=”preferentialPrice”
                    :totalNum=”buyNum”></goods-list>

goodsList来自于 vuex cars 中的值  carsList

totalPrice来自于 vuex cars 中的计算值 totalPrice

prePrice 来自于 vuex cars 中的计算值 preferentialPrice

totalNum 来自于 vuex cars 中的计算值 buyNum

4、代码

<template>
	<view>
		<u-notice-bar text="本商城产品为学习交流使用, 下单概不发货, 请谨慎下单~~"></u-notice-bar>
		<view class="paypage">
			<!-- 确认订单,支付订单 -->
			<!-- 配送方式 -->
			<delivery-layout :deliveryInfo="deliveryInfo"></delivery-layout>

			<!-- 购物列表 -->
			<view class="goodsList">
				<goods-list :goodsList="carsList" :totalPrice="totalPrice" :prePrice="preferentialPrice"
					:totalNum="buyNum"></goods-list>
			</view>


			<!-- #ifndef MP-WEIXIN -->
			<view class="paytype">
				<view class="box" :class="item.value == payDefValue ? 'active':''" v-for="item in payType"
					@click="clickPayBtn(item.value)">
					<u-icon :name="item.icon" :color="item.color" class="icon" size="26"></u-icon>
					<text class="font">{
           {item.name}}</text>
				</view>
			</view>
			<!-- #endif -->


			<view class="payTabbar">
				<car-layout type="pay" :payBtnState="payBtnState" @confirmPay="onConfirmPay"></car-layout>
			</view>


			<uni-pay ref="uniPay" returnUrl="/pages/order/order" @success="paySuccess" @cancel="payCancel"
				@create="payCreate"></uni-pay>


		</view>
	</view>
</template>

<script>
	import {
		mapGetters,
		mapMutations
	} from "vuex"
	const addressCloudObj = uniCloud.importObject("green-mall-address");
	const orderCloudObj = uniCloud.importObject("green-mall-order", {
		customUI: true
	});
	export default {
		data() {
			return {
				deliveryInfo: {
					address: "",
					username: "",
					mobile: ""
				},

				// #ifdef APP-PLUS || H5
				payDefValue: "alipay",
				// #endif

				// #ifdef MP-WEIXIN
				payDefValue: 'wxpay',
				// #endif

				payType: [{
					name: "支付宝",
					value: "alipay", //必须写这个值,后面要用到
					color: "#1578FF",
					icon: "zhifubao" //:color="item.value==payDefValue ? item.color :''"
				}, {
					name: "微信",
					value: "wxpay",
					color: "#04C15F",
					icon: "weixin-fill"
				}],

				payLoading: true
			};
		},
		computed: {
			...mapGetters(['carsList', 'totalPrice', 'preferentialPrice', "buyNum"]),
			payBtnState() {
				let bool = Object.keys(this.deliveryInfo).every(item => {
					return this.deliveryInfo[item] != ""
				})
				return this.carsList.length > 0 && this.totalPrice > 0 && bool && this.payLoading
			}
		},
		onLoad() {
			this.getDefAddressData();
			uni.$on("selectAddressEvent", (e) => {
				this.deliveryInfo = e;
			})
		},
		onUnload() {
			uni.$off("selectAddressEvent")
		},

		methods: {
			...mapMutations(["SET_CARS_LIST"]),

			//点击支付按钮发起支付	
			async onConfirmPay() {
				this.payLoading = false;
				let obj = {
					deliveryInfo: this.deliveryInfo,
					carsList: this.carsList,
					createTime: Date.now(),
					payType: this.payDefValue,
					status: 0,
					total_fee: this.totalPrice,
					done: false
				}

				let order_no = await orderCloudObj.createOrder(obj);
				let out_trade_no = order_no + "_" + String(Math.random()).substring(3, 9)


				this.$refs.uniPay.createOrder({
					provider: this.payDefValue, // 支付供应商
					total_fee: this.totalPrice, // 支付金额,单位分 100 = 1元
					type: "goods", // 支付回调类型
					order_no, // 业务系统订单号
					out_trade_no, // 插件支付单号
					description: "购买商品的支付", // 支付描述
				})
			},


			//支付成功的回调
			paySuccess(e) {
				this.payLoading = true;
				this.SET_CARS_LIST();
				console.log(e);
			},
			payCancel(e) {
				console.log(e);
			},
			payCreate(e) {
				console.log(e);
			},





			//选择支付类型
			clickPayBtn(value) {
				this.payDefValue = value
			},

			//获取默认地址
			async getDefAddressData() {
				let res = await addressCloudObj.getDefAddress();
				if (!res.data.length) return;
				let {
					address,
					area_name,
					username,
					mobile
				} = res.data[0];
				this.deliveryInfo = {
					address: area_name + address,
					username,
					mobile
				}

			}
		}
	}
</script>

<style lang="scss" scoped>
	page {
		background: $page-bg-color; //页面背景色
	}

	.paypage {
		padding: 30rpx;

		.goodsList {
			margin-top: 30rpx;
		}

		.paytype {
			@include flex-box();

			.box {
				//box 就两个支付方式    
				width: 49%; //一个支付方式站49 剩下中间的2的空格
				height: 75rpx;
				background: #fff;
				border-radius: 10rpx;
				@include flex-box-set();
				border: 1px solid #fff;
				//filter: grayscale(100%);   //滤镜效果  100%把颜色全滤掉      我们已经用了 :color="item.value==payDefValue ? item.color :''"  就不用滤镜了
				filter: grayscale(100%);

				.font {
					padding-left: 10rpx;
				}
			}

			//可以这样 当用text时,若用view + style  就不用下面的方式
			.box:first-child.active {
				border-color: #1578FF; //边框颜色
				color: #1578FF;
				filter: grayscale(0%);
				//filter: grayscale(0%)
			}

			.box:last-child.active {
				border-color: #04C15F;
				color: #04C15F;
				filter: grayscale(0%);
				//filter: grayscale(0%)
			}
		}

		.payTabbar {
			position: fixed;
			width: 100%;
			bottom: 0;
			left: 0;
		}
	}
</style>

© 版权声明
THE END
如果内容对您有所帮助,就支持一下吧!
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容