| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487 |
- <!-- 结算页面 -->
- <template>
- <view class="container">
- <!-- <u-navbar title="确认订单" autoBack></u-navbar> -->
- <!-- 收货地址 -->
- <view class="address-section" @click="chooseWxAddress">
- <template v-if="address">
- <view class="address-content">
- <view class="info">
- <text class="name">{{address.userName}}</text>
- <text class="phone">{{address.telNumber}}</text>
- </view>
- <view class="address">
- {{address.provinceName}}{{address.cityName}}{{address.countyName}}{{address.detailInfo}}
- </view>
- </view>
- </template>
- <template v-else>
- <view class="address-empty">
- <text>请选择收货地址</text>
- <u-icon name="arrow-right" color="#999"></u-icon>
- </view>
- </template>
- </view>
- <!-- 商品信息 -->
- <view class="goods-section" v-if="sku">
- <view class="goods-item" v-for="(item, index) in Array.isArray(sku) ? sku : [sku]" :key="index">
- <image :src="item.skuImage" mode="aspectFill" class="goods-img"></image>
- <view class="goods-info">
- <view class="goods-name">{{item.productName}}</view>
- <view class="goods-spec">{{item.skuName}}</view>
- <view class="price-quantity">
- <text class="price">¥{{item.price}}</text>
- <text class="quantity">x{{item.count}}</text>
- </view>
- </view>
- </view>
- </view>
- <!-- 空状态 -->
- <view class="empty-state" v-else>
- <text>商品信息不存在</text>
- </view>
- <!-- 支付方式 -->
- <view class="payment-section">
- <view class="section-title">支付方式</view>
- <view class="payment-list">
- <view class="payment-item" @click="selectPayment('wxpay')" :class="{active: paymentMethod === 'wxpay'}">
- <view class="left">
- <image src="/static/images/wxpay.png" mode="aspectFit" class="payment-icon"></image>
- <text>微信支付</text>
- </view>
- <u-icon v-if="paymentMethod === 'wxpay'" name="checkmark" color="#F95B5B"></u-icon>
- </view>
- </view>
- </view>
- <!-- 订单金额 -->
- <view class="amount-section">
- <view class="amount-item">
- <text>商品金额</text>
- <text class="price">¥{{totalProductAmount}}</text>
- </view>
- <view class="amount-item">
- <text>运费</text>
- <text class="price">¥{{freightAmount}}</text>
- </view>
- <view class="amount-item total">
- <text>实付款</text>
- <text class="price">¥{{totalAmount}}</text>
- </view>
- </view>
- <!-- 底部提交栏 -->
- <view class="submit-bar">
- <view class="total-amount">
- <text>合计:</text>
- <text class="price">¥{{totalAmount}}</text>
- </view>
- <button class="submit-btn" @click="submitOrder" :loading="submitting" :disabled="submitting">
- {{submitting ? '提交中...' : '提交订单'}}
- </button>
- </view>
- </view>
- </template>
- <script>
- import {
- mapGetters
- } from 'vuex';
- import {
- submitOrder,
- saveCartOrder
- } from '../../../config/api.js';
- export default {
- data() {
- return {
- sku: null,
- address: null,
- paymentMethod: 'wxpay',
- submitting: false,
- freightAmount: 0,
- isFromCart: false
- }
- },
- computed: {
- ...mapGetters(['isLogin']),
- totalProductAmount() {
- if (!this.sku) return 0;
- if (Array.isArray(this.sku)) {
- return this.sku.reduce((total, item) => total + (item.price * item.count), 0);
- }
- return this.sku.price * this.sku.count;
- },
- totalAmount() {
- return this.totalProductAmount + this.freightAmount;
- }
- },
- onLoad(options) {
- if (options.sku) {
- try {
- this.sku = JSON.parse(decodeURIComponent(options.sku));
- this.isFromCart = false;
- } catch (error) {
- console.error('解析商品数据失败:', error);
- uni.showToast({
- title: '商品数据错误',
- icon: 'none'
- });
- setTimeout(() => {
- uni.navigateBack();
- }, 1500);
- }
- } else if (options.items) {
- try {
- const items = JSON.parse(decodeURIComponent(options.items));
- this.isFromCart = true;
- // 将购物车商品数据转换为结算页面需要的格式
- this.sku = items.map(item => ({
- id: item.id,
- skuId: item.skuId,
- skuImage: item.images,
- productName: item.productName,
- skuName: item.skuName,
- price: item.price,
- count: item.count
- }));
- } catch (error) {
- console.error('解析购物车数据失败:', error);
- uni.showToast({
- title: '商品数据错误',
- icon: 'none'
- });
- setTimeout(() => {
- uni.navigateBack();
- }, 1500);
- }
- } else {
- uni.showToast({
- title: '商品数据不存在',
- icon: 'none'
- });
- setTimeout(() => {
- uni.navigateBack();
- }, 1500);
- }
- },
- methods: {
- // 选择微信收货地址
- chooseWxAddress() {
- uni.chooseAddress({
- success: (res) => {
- this.address = res;
- },
- fail: (err) => {
- console.error('获取收货地址失败:', err);
- if (err.errMsg.includes('auth deny')) {
- uni.showModal({
- title: '提示',
- content: '需要您的授权才能获取收货地址,是否前往设置?',
- success: (res) => {
- if (res.confirm) {
- uni.openSetting();
- }
- }
- });
- } else {
- uni.$u.toast('获取收货地址失败');
- }
- }
- });
- },
- // 选择支付方式
- selectPayment(method) {
- this.paymentMethod = method;
- },
- // 提交订单
- async submitOrder() {
- if (!this.address) {
- return uni.$u.toast('请选择收货地址');
- }
- if (this.submitting) return;
- this.submitting = true;
- try {
- if (this.isFromCart) {
- // 购物车批量下单
- const orderList = this.sku.map(item => ({
- province: this.address.provinceName,
- city: this.address.cityName,
- area: this.address.countyName,
- address: this.address.detailInfo,
- mobile: this.address.telNumber,
- name: this.address.userName,
- skuId: item.skuId,
- count: item.count,
- payType: this.paymentMethod === 'wxpay' ? 1 : 2
- }));
- const res = await saveCartOrder(orderList);
- if (res.code === 200) {
- // 跳转到支付页面
- uni.navigateTo({
- url: `/packageOrder/pages/payment/index?orderId=${res.data.id}`
- });
- } else {
- uni.$u.toast(res.msg || '提交订单失败');
- }
- } else {
- // 单个商品下单
- const orderData = {
- mobile: this.address.telNumber,
- name: this.address.userName,
- province: this.address.provinceName,
- city: this.address.cityName,
- area: this.address.countyName,
- address: this.address.detailInfo,
- postalCode: this.address.postalCode,
- skuId: this.sku.id,
- count: this.sku.count,
- paymentMethod: this.paymentMethod
- };
- const res = await submitOrder(orderData);
- if (res.code === 200) {
- // 跳转到支付页面
- uni.navigateTo({
- url: `/packageOrder/pages/payment/index?orderId=${res.data.id}`
- });
- } else {
- uni.$u.toast(res.msg || '提交订单失败');
- }
- }
- } catch (error) {
- console.error('提交订单失败:', error);
- uni.$u.toast('提交订单失败,请重试');
- } finally {
- this.submitting = false;
- }
- }
- }
- }
- </script>
- <style lang="scss">
- .container {
- min-height: 100vh;
- background-color: #f5f5f5;
- padding-bottom: 120rpx;
- }
- .address-section {
- background-color: #fff;
- margin: 20rpx;
- padding: 30rpx;
- border-radius: 12rpx;
- .address-content {
- .info {
- margin-bottom: 20rpx;
- .name {
- font-size: 32rpx;
- font-weight: bold;
- margin-right: 20rpx;
- }
- .phone {
- font-size: 28rpx;
- color: #666;
- }
- }
- .address {
- font-size: 28rpx;
- color: #333;
- }
- }
- .address-empty {
- display: flex;
- align-items: center;
- justify-content: space-between;
- font-size: 28rpx;
- color: #999;
- }
- }
- .goods-section {
- background-color: #fff;
- margin: 20rpx;
- padding: 30rpx;
- border-radius: 12rpx;
- .goods-item {
- display: flex;
- .goods-img {
- width: 160rpx;
- height: 160rpx;
- border-radius: 8rpx;
- margin-bottom: 10rpx;
- }
- .goods-info {
- flex: 1;
- margin-left: 20rpx;
- .goods-name {
- font-size: 28rpx;
- color: #333;
- margin-bottom: 10rpx;
- }
- .goods-spec {
- font-size: 24rpx;
- color: #999;
- margin-bottom: 20rpx;
- }
- .price-quantity {
- display: flex;
- justify-content: space-between;
- align-items: center;
- .price {
- font-size: 32rpx;
- color: #F95B5B;
- font-weight: bold;
- }
- .quantity {
- font-size: 26rpx;
- color: #999;
- }
- }
- }
- }
- }
- .payment-section {
- background-color: #fff;
- margin: 20rpx;
- padding: 30rpx;
- border-radius: 12rpx;
- .section-title {
- font-size: 28rpx;
- color: #333;
- margin-bottom: 20rpx;
- }
- .payment-item {
- display: flex;
- justify-content: space-between;
- align-items: center;
- padding: 20rpx 0;
- &.active {
- .left {
- text {
- color: #F95B5B;
- }
- }
- }
- .left {
- display: flex;
- align-items: center;
- .payment-icon {
- width: 40rpx;
- height: 40rpx;
- margin-right: 20rpx;
- }
- text {
- font-size: 28rpx;
- color: #333;
- }
- }
- }
- }
- .amount-section {
- background-color: #fff;
- margin: 20rpx;
- padding: 30rpx;
- border-radius: 12rpx;
- .amount-item {
- display: flex;
- justify-content: space-between;
- margin-bottom: 20rpx;
- font-size: 28rpx;
- color: #666;
- &.total {
- margin-top: 20rpx;
- padding-top: 20rpx;
- border-top: 1px solid #f5f5f5;
- color: #333;
- font-weight: bold;
- .price {
- color: #F95B5B;
- font-size: 32rpx;
- }
- }
- .price {
- color: #333;
- }
- }
- }
- .submit-bar {
- position: fixed;
- bottom: 0;
- left: 0;
- right: 0;
- height: 100rpx;
- background-color: #fff;
- display: flex;
- align-items: center;
- padding: 0 30rpx;
- box-shadow: 0 -2rpx 10rpx rgba(0, 0, 0, 0.05);
- .total-amount {
- flex: 1;
- font-size: 28rpx;
- .price {
- color: #F95B5B;
- font-size: 36rpx;
- font-weight: bold;
- }
- }
- .submit-btn {
- width: 240rpx;
- height: 72rpx;
- line-height: 72rpx;
- background-color: #F95B5B;
- color: #fff;
- font-size: 28rpx;
- border-radius: 36rpx;
- text-align: center;
- &[disabled] {
- background-color: #ccc;
- }
- }
- }
- .empty-state {
- text-align: center;
- padding: 40rpx;
- color: #999;
- font-size: 28rpx;
- }
- </style>
|