浏览代码

feat(订单): 新增确认订单页面及组件

实现确认订单页面功能,包括地址选择、商品展示、红包选择、缺货处理选项
添加相关弹窗组件:红包选择、缺货处理、提交确认
完成订单提交逻辑及页面跳转
ylong 1 月之前
父节点
当前提交
a62fd3e1fb

+ 123 - 0
pages-car/components/buy-book-item.vue

@@ -0,0 +1,123 @@
+<template>
+    <view class="book-item">
+        <view class="book-info">
+            <view class="book-image-container">
+                <image class="book-cover" :src="book.cover" mode="aspectFill" />
+            </view>
+            <view class="book-detail">
+                <view class="top-info">
+                    <view class="book-title">{{ book.title }}</view>
+                    <view class="upsell-info" v-if="book.priceReduced">
+                        <text class="has-upsell">已降 ¥{{ book.priceReduced }}</text>
+                    </view>
+                    <view class="upsell-info" v-if="book.canReduce">
+                        <text class="can-upsell">可降 ¥{{ book.canReduce }}</text>
+                    </view>
+                </view>
+
+                <view class="flex flex-j-b flex-a-c">
+                    <view class="book-quality">品相:{{ book.quality || '中等' }}</view>
+                </view>
+                
+                <view class="flex flex-j-b flex-a-c mt-10">
+                    <view class="book-price">
+                        <text class="price">¥{{ book.price }}</text>
+                        <text class="original-price ml-10">¥{{ book.originalPrice }}</text>
+                    </view>
+                    <view class="book-num">× {{ book.num }}</view>
+                </view>
+            </view>
+        </view>
+    </view>
+</template>
+
+<script>
+export default {
+    props: {
+        book: {
+            type: Object,
+            required: true
+        }
+    }
+}
+</script>
+
+<style lang="scss" scoped>
+.book-item {
+    padding: 24rpx;
+    border-bottom: 1rpx solid #f5f5f5;
+    
+    .book-info {
+        display: flex;
+        
+        .book-image-container {
+            .book-cover {
+                width: 154rpx;
+                height: 196rpx;
+                border-radius: 8rpx;
+                background-color: #eee;
+            }
+        }
+        
+        .book-detail {
+            flex: 1;
+            margin-left: 20rpx;
+            display: flex;
+            flex-direction: column;
+            justify-content: space-between;
+            
+            .book-title {
+                font-size: 28rpx;
+                color: #333;
+                line-height: 1.4;
+                margin-bottom: 10rpx;
+                display: -webkit-box;
+                -webkit-box-orient: vertical;
+                -webkit-line-clamp: 2;
+                overflow: hidden;
+            }
+            
+            .upsell-info {
+                margin-bottom: 10rpx;
+                .has-upsell {
+                    font-size: 24rpx;
+                    color: #38C148;
+                    background-color: #e9f6eb;
+                    padding: 4rpx 10rpx;
+                    border-radius: 4rpx;
+                }
+                .can-upsell {
+                    font-size: 24rpx;
+                    color: #38C148;
+                    background-color: #e9f6eb;
+                    padding: 4rpx 10rpx;
+                    border-radius: 4rpx;
+                }
+            }
+            
+            .book-quality {
+                font-size: 24rpx;
+                color: #999;
+            }
+            
+            .book-price {
+                .price {
+                    font-size: 32rpx;
+                    color: #ff4500;
+                    font-weight: bold;
+                }
+                .original-price {
+                    font-size: 24rpx;
+                    color: #999;
+                    text-decoration: line-through;
+                }
+            }
+            
+            .book-num {
+                font-size: 28rpx;
+                color: #333;
+            }
+        }
+    }
+}
+</style>

+ 143 - 0
pages-car/components/red-packet-popup.vue

@@ -0,0 +1,143 @@
+<template>
+    <u-popup v-model="show" mode="bottom" border-radius="24">
+        <view class="red-packet-popup">
+            <view class="popup-header">
+                <text>选择红包</text>
+                <u-icon name="close" size="28" color="#999" class="close-icon" @click="close"></u-icon>
+            </view>
+            
+            <scroll-view scroll-y class="packet-list">
+                <view class="packet-item" v-for="(item, index) in list" :key="index" @click="selectPacket(index)">
+                    <view class="packet-info">
+                        <view class="packet-name">{{ item.name }}</view>
+                        <view class="packet-desc">{{ item.desc }}</view>
+                        <view class="packet-time">{{ item.time }}</view>
+                    </view>
+                    <view class="packet-check">
+                        <u-icon name="checkmark-circle-fill" size="40" :color="selectedIndex === index ? '#ff4500' : '#ccc'"></u-icon>
+                    </view>
+                </view>
+            </scroll-view>
+            
+            <view class="popup-footer">
+                <u-button type="primary" shape="circle" @click="confirm">确认</u-button>
+            </view>
+        </view>
+    </u-popup>
+</template>
+
+<script>
+export default {
+    props: {
+        value: {
+            type: Boolean,
+            default: false
+        }
+    },
+    data() {
+        return {
+            show: false,
+            selectedIndex: 0,
+            list: [
+                {
+                    name: '惊喜红包(满15减5)',
+                    desc: '书嗨所有商品(不包含邮费)',
+                    time: '2024-01-01 00:00:00至2024-12-31 23:59:59'
+                },
+                {
+                    name: '惊喜红包(满15减5)',
+                    desc: '书嗨所有商品(不包含邮费)',
+                    time: '2024-01-01 00:00:00至2024-12-31 23:59:59'
+                }
+            ]
+        }
+    },
+    watch: {
+        value(val) {
+            this.show = val;
+        },
+        show(val) {
+            this.$emit('input', val);
+        }
+    },
+    methods: {
+        close() {
+            this.show = false;
+        },
+        selectPacket(index) {
+            this.selectedIndex = index;
+        },
+        confirm() {
+            this.$emit('confirm', this.list[this.selectedIndex]);
+            this.close();
+        }
+    }
+}
+</script>
+
+<style lang="scss" scoped>
+.red-packet-popup {
+    height: 100%;
+    display: flex;
+    flex-direction: column;
+    overflow: hidden;
+    
+    .popup-header {
+        padding: 30rpx;
+        text-align: center;
+        font-size: 32rpx;
+        font-weight: bold;
+        position: sticky;
+        top: 0;
+        background-color: #fff;
+        border-bottom: 1rpx solid #eee;
+        
+        .close-icon {
+            position: absolute;
+            right: 30rpx;
+            top: 40rpx;
+        }
+    }
+    
+    .packet-list {
+        flex: 1;
+        padding: 20rpx;
+        box-sizing: border-box;
+        max-height: 400px;
+        overflow-y: auto;
+        
+        .packet-item {
+            display: flex;
+            align-items: center;
+            padding: 20rpx 30rpx;
+            
+            .packet-info {
+                flex: 1;
+                
+                .packet-name {
+                    font-size: 30rpx;
+                    color: #ff4500;
+                    font-weight: bold;
+                    margin-bottom: 10rpx;
+                }
+                
+                .packet-desc {
+                    font-size: 26rpx;
+                    color: #333;
+                    margin-bottom: 6rpx;
+                }
+                
+                .packet-time {
+                    font-size: 22rpx;
+                    color: #999;
+                }
+            }
+        }
+    }
+    
+    .popup-footer {
+        padding: 20rpx 40rpx;
+        padding-bottom: env(safe-area-inset-bottom);
+    }
+}
+</style>

+ 113 - 0
pages-car/components/stock-shortage-popup.vue

@@ -0,0 +1,113 @@
+<template>
+    <u-popup v-model="show" mode="bottom" border-radius="24" height="600rpx">
+        <view class="stock-shortage-popup">
+            <view class="popup-header">
+                <text>如遇缺货</text>
+                <u-icon name="close" size="28" color="#999" class="close-icon" @click="close"></u-icon>
+            </view>
+            
+            <view class="option-list">
+                <view class="option-item" v-for="(item, index) in options" :key="index" @click="selectOption(index)">
+                    <view class="option-text">{{ item.text }}</view>
+                    <view class="option-check">
+                        <u-icon name="checkmark-circle-fill" size="40" :color="selectedIndex === index ? '#38C148' : '#ccc'"></u-icon>
+                    </view>
+                </view>
+            </view>
+            
+            <view class="popup-footer">
+                <u-button type="primary" shape="circle" @click="confirm">确认</u-button>
+            </view>
+        </view>
+    </u-popup>
+</template>
+
+<script>
+export default {
+    props: {
+        value: {
+            type: Boolean,
+            default: false
+        }
+    },
+    data() {
+        return {
+            show: false,
+            selectedIndex: 1, // Default to "其他商品继续发货"
+            options: [
+                { text: '缺货时电话与我沟通', value: 1 },
+                { text: '其他商品继续发货(缺货商品退款)', value: 2 },
+                { text: '有缺货直接取消订单', value: 3 }
+            ]
+        }
+    },
+    watch: {
+        value(val) {
+            this.show = val;
+        },
+        show(val) {
+            this.$emit('input', val);
+        }
+    },
+    methods: {
+        close() {
+            this.show = false;
+        },
+        selectOption(index) {
+            this.selectedIndex = index;
+        },
+        confirm() {
+            this.$emit('confirm', this.options[this.selectedIndex]);
+            this.close();
+        }
+    }
+}
+</script>
+
+<style lang="scss" scoped>
+.stock-shortage-popup {
+    height: 100%;
+    display: flex;
+    flex-direction: column;
+    overflow-y: hidden;
+    
+    .popup-header {
+        padding: 30rpx;
+        text-align: center;
+        font-size: 32rpx;
+        font-weight: bold;
+        position: relative;
+        border-bottom: 1rpx solid #eee;
+        
+        .close-icon {
+            position: absolute;
+            right: 30rpx;
+            top: 40rpx;
+        }
+    }
+    
+    .option-list {
+        flex: 1;
+        padding: 20rpx;
+        max-height: 400rpx;
+        overflow-y: auto;
+        
+        .option-item {
+            display: flex;
+            justify-content: space-between;
+            align-items: center;
+            padding: 20rpx 30rpx;
+            
+            .option-text {
+                font-size: 28rpx;
+                color: #333;
+            }
+        }
+    }
+    
+    .popup-footer {
+        padding: 20rpx 40rpx;
+        padding-bottom: env(safe-area-inset-bottom);
+    }
+}
+</style>

+ 164 - 0
pages-car/components/submit-confirm.vue

@@ -0,0 +1,164 @@
+<template>
+    <u-popup v-model="showPopup" @close="closePopup" mode="center" border-radius="30" :width="width">
+        <view class="submit-confirm">
+            <view class="container-form">
+                <view class="icon-wrapper">
+                    <image src="/static/tabbar/home2.png" class="tip-icon"></image>
+                    <text class="tip-text">温馨提示</text>
+                </view>
+
+                <view class="content">
+                    <view> 目前付款后<span class="highlight">24小时</span>内发货,如有发货超时或者物流异常情况,您可联系在线客服处理。
+                    </view>
+                    <view class="mt-20"> 页面库存同步有延迟为预估数字,<span
+                            class="highlight">实际库存以发货为准。</span>下单后如有售后电话或短信通知无货,请留意查收短信通知及时申请退款。</view>
+                </view>
+
+                <view class="footer">
+                    <button class="cancel-btn" @click="handleCancel">取消</button>
+                    <button class="confirm-btn" :disabled="countdown > 0" @click="handleConfirm">
+                        确定提交{{ countdown > 0 ? `(${countdown}s)` : "" }}
+                    </button>
+                </view>
+            </view>
+        </view>
+    </u-popup>
+</template>
+
+<script>
+export default {
+    props: {
+        width: {
+            type: String,
+            default: "92%",
+        },
+    },
+    data() {
+        return {
+            showPopup: false,
+            countdown: 15,
+        };
+    },
+    methods: {
+        openPopup() {
+            this.showPopup = true;
+            this.startCountdown();
+        },
+        closePopup() {
+            this.showPopup = false;
+            this.countdown = 10;
+        },
+        handleConfirm() {
+            this.$emit("confirm");
+            this.closePopup();
+        },
+        handleCancel() {
+            this.$emit("cancel");
+            this.closePopup();
+        },
+        startCountdown() {
+            this.countdown = 15;
+            const timer = setInterval(() => {
+                if (this.countdown > 0) {
+                    this.countdown--;
+                } else {
+                    clearInterval(timer);
+                }
+            }, 1000);
+        },
+    },
+};
+</script>
+
+<style lang="scss" scoped>
+.submit-confirm {
+    background: #ffffff;
+    border-radius: 26rpx;
+    overflow: hidden;
+    padding: 16rpx;
+    background: linear-gradient(-90deg, #98e05f, #0de3ac);
+
+    .container-form {
+        background: #effcf3;
+        border-radius: 26rpx;
+        padding: 30rpx;
+        padding-bottom: 40rpx;
+    }
+
+    .icon-wrapper {
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        margin-bottom: 20rpx;
+
+        .tip-icon {
+            width: 48rpx;
+            height: 48rpx;
+            margin-right: 10rpx;
+        }
+
+        .tip-text {
+            font-family: Source Han Sans CN;
+            font-weight: bold;
+            font-size: 36rpx;
+            color: #37c148;
+        }
+    }
+
+    .content {
+        padding: 0 10rpx;
+        font-size: 32rpx;
+        color: #333333;
+        line-height: 48rpx;
+
+        view {
+            font-size: 32rpx;
+        }
+
+        .highlight {
+            color: #ff0000;
+        }
+    }
+
+    .mt-20 {
+        margin-top: 20rpx;
+    }
+
+    .footer {
+        display: flex;
+        gap: 30rpx;
+        margin-top: 30rpx;
+        padding: 0 10rpx;
+
+        button {
+            height: 88rpx;
+            line-height: 88rpx;
+            font-size: 32rpx;
+            border: none;
+            border-radius: 10rpx;
+
+            &::after {
+                border: none;
+            }
+
+            &.cancel-btn {
+                flex: 1;
+                background-color: #E3E3E3;
+                color: #ffffff;
+                width: 135rpx;
+            }
+
+            &.confirm-btn {
+                flex: 2.5;
+                width: 335rpx;
+                background-color: #38c148;
+                color: #ffffff;
+
+                &:disabled {
+                    opacity: 0.7;
+                }
+            }
+        }
+    }
+}
+</style>

+ 334 - 0
pages-car/pages/confirm-order.vue

@@ -0,0 +1,334 @@
+<template>
+    <view class="confirm-order">
+        <!-- 收货地址部分 -->
+        <view class="section-card">
+            <view class="flex-a flex-j-b mb-20" @click="handleAddress" v-if="defaultAddr.id">
+                <image src="/pages-mine/static/adderss.png" style="width: 40rpx; height: 40rpx"></image>
+                <view class="flex-d flex-1 ml-24" style="margin-right: 90rpx">
+                    <view class="flex-a flex-j-b mb-10">
+                        <view :style="titleStyle">收货人:{{ defaultAddr.name }}</view>
+                        <view :style="titleStyle">{{ defaultAddr.mobile }}</view>
+                    </view>
+                    <view :style="titleStyle">地址:{{ defaultAddr.fullAddress }}</view>
+                </view>
+                <u-icon name="arrow-right" :size="28" color="#666" top="4"></u-icon>
+            </view>
+
+            <view class="flex-a flex-j-b" @click="handleAddress" v-else>
+                <view class="flex-a">
+                    <u-icon name="plus-circle-fill" :size="48" color="#38C148" top="2"></u-icon>
+                    <view :style="titleStyle" class="ml-10 font-30">添加收货地址</view>
+                    <text class="u-required">*</text>
+                </view>
+
+                <view class="flex-a">
+                    <view :style="titleStyle" class="ml-10">请添加</view>
+                    <u-icon name="arrow-right" :size="28" color="#666" top="4"></u-icon>
+                </view>
+            </view>
+        </view>
+
+        <!-- 商品列表 -->
+        <view class="book-list">
+            <buy-book-item v-for="(book, index) in books" :key="index" :book="book"></buy-book-item>
+        </view>
+
+        <!-- 订单信息 -->
+        <view class="section-card mt-20" style="padding: 0; overflow: hidden;">
+            <u-cell-group :border="false">
+                <u-cell-item title="配送服务" value="快递 免邮" :arrow="false" :title-style="{ color: '#333' }"
+                    :value-style="{ color: '#333' }"></u-cell-item>
+                <u-cell-item title="红包" :value="selectedPacket ? selectedPacket.name : ''" @click="showRedPacket = true"
+                    :title-style="{ color: '#333' }"></u-cell-item>
+                <u-cell-item title="订单备注" :arrow="false" :title-style="{ color: '#333' }">
+                    <u-input slot="right-icon" v-model="submitData.remark" type="text" placeholder="无备注"
+                        input-align="right" :custom-style="{ color: '#999', minHeight: '28px' }" />
+                </u-cell-item>
+                <u-cell-item title="如遇缺货" :value="selectedStockOption.text || '其他商品继续发货'"
+                    @click="showStockShortage = true" :border-bottom="false"
+                    :title-style="{ color: '#ff4500', fontWeight: 'bold' }"></u-cell-item>
+            </u-cell-group>
+        </view>
+
+        <!-- 底部栏 -->
+        <view class="bottom-bar">
+            <view class="order-summary">
+                <view class="total">
+                    共<text class="num">{{ totalNum }}</text>本
+                    <text class="reduce-text" v-if="totalReduced > 0">已降¥{{ totalReduced }}</text>
+                    合计: <text class="price">¥{{ totalPrice }}</text>
+                </view>
+                <u-button type="primary" shape="circle" @click="submitOrder">提交订单</u-button>
+            </view>
+        </view>
+
+        <submit-confirm ref="submitConfirmDialog" @confirm="handleConfirmSubmit"></submit-confirm>
+        <red-packet-popup v-model="showRedPacket" @confirm="onRedPacketConfirm"></red-packet-popup>
+        <stock-shortage-popup v-model="showStockShortage" @confirm="onStockShortageConfirm"></stock-shortage-popup>
+    </view>
+</template>
+
+<script>
+import SubmitConfirm from "@/pages-car/components/submit-confirm.vue";
+import BuyBookItem from "@/pages-car/components/buy-book-item.vue";
+import RedPacketPopup from "@/pages-car/components/red-packet-popup.vue";
+import StockShortagePopup from "@/pages-car/components/stock-shortage-popup.vue";
+
+export default {
+    components: {
+        SubmitConfirm,
+        BuyBookItem,
+        RedPacketPopup,
+        StockShortagePopup
+    },
+    data() {
+        return {
+            titleStyle: {
+                "font-family": "PingFang SC",
+                "font-weight": 400,
+                color: "#333333",
+            },
+            books: [],
+            defaultAddr: {},
+            submitData: {
+                addressId: "",
+                remark: "",
+            },
+            totalNum: 0,
+            totalPrice: 0,
+            totalReduced: 0,
+            btnStyle: {
+                width: '240rpx',
+                height: '80rpx',
+                lineHeight: '80rpx',
+                background: 'linear-gradient(90deg, #ff8c00, #ff4500)',
+                color: '#fff',
+                fontSize: '30rpx',
+                margin: '0'
+            },
+            showRedPacket: false,
+            showStockShortage: false,
+            selectedPacket: null,
+            selectedStockOption: { text: '其他商品继续发货(缺货商品退款)', value: 2 }
+        };
+    },
+    methods: {
+        //添加或者选择地址
+        handleAddress() {
+            uni.navigateTo({
+                url: `/pages-mine/pages/address/list?id=${this.defaultAddr.id}&isSelect=1`,
+            });
+        },
+
+        onRedPacketConfirm(packet) {
+            this.selectedPacket = packet;
+            // Recalculate price if needed
+        },
+
+        onStockShortageConfirm(option) {
+            this.selectedStockOption = option;
+        },
+
+        submitOrder() {
+            if (!this.submitData.addressId) {
+                this.$u.toast("请选择收货地址");
+                return;
+            }
+            // 显示确认弹窗
+            this.$refs.submitConfirmDialog.openPopup();
+        },
+
+        // 确认提交订单
+        handleConfirmSubmit() {
+            // 处理订单提交
+            uni.showToast({
+                title: '订单提交成功',
+                icon: "success",
+            });
+            setTimeout(() => {
+                uni.redirectTo({
+                    url: "/pages-car/pages/my-order"
+                });
+            }, 1500);
+
+            // uni.$u.http.post("/token/order/submitBuyOrder", this.submitData).then((res) => {
+            //     if (res.code == 200) {
+            //         uni.navigateTo({
+            //             url: "/pages-car/pages/pay-success",
+            //         });
+            //     } else {
+            //         uni.showToast({
+            //             title: res.msg,
+            //             icon: "none",
+            //         });
+            //     }
+            // });
+        },
+        //获取默认地址
+        getDefaultAddress() {
+            // Mock default address
+            this.defaultAddr = {
+                id: '1',
+                name: '张三',
+                mobile: '18888888888',
+                fullAddress: '北京市朝阳区xx街道xx小区1号楼101'
+            };
+            this.submitData.addressId = this.defaultAddr.id;
+
+            // uni.$u.http.get("/token/user/address/getDefault").then((res) => {
+            //     if (res.code == 200) {
+            //         this.defaultAddr = res.data;
+            //         this.submitData.addressId = this.defaultAddr.id;
+            //     }
+            // });
+        },
+        // 获取结算商品信息
+        getCheckoutInfo() {
+            // Mock books data
+            this.books = [
+                {
+                    title: '商品名称商品名称商品',
+                    cover: 'https://k.sinaimg.cn/n/sinakd20116/234/w1000h1634/20251003/b66b-587c9ff400fcf01be52c6693594b6a6d.jpg/w700d1q75cms.jpg',
+                    quality: '中等',
+                    price: '0.01',
+                    originalPrice: '0.01',
+                    priceReduced: '0.5',
+                    num: 1
+                },
+                {
+                    title: '商品名称商品名称商品',
+                    cover: 'https://k.sinaimg.cn/n/sinakd20116/234/w1000h1634/20251003/b66b-587c9ff400fcf01be52c6693594b6a6d.jpg/w700d1q75cms.jpg',
+                    quality: '中等',
+                    canReduce: '0.5',
+                    price: '0.01',
+                    originalPrice: '0.01',
+                    num: 1
+                }
+            ];
+            this.totalNum = 2;
+            this.totalPrice = '0.01';
+            this.totalReduced = '1.01';
+        }
+    },
+    mounted() {
+        this.getDefaultAddress();
+        this.getCheckoutInfo();
+    },
+
+    onShow() {
+        let selectAddr = uni.getStorageSync("selectAddr");
+        if (selectAddr) {
+            this.defaultAddr = selectAddr;
+            this.submitData.addressId = selectAddr.id;
+            uni.removeStorageSync("selectAddr"); // Clear after use
+        }
+    },
+};
+</script>
+
+<style lang="scss">
+.confirm-order {
+    min-height: 100vh;
+    background: #f5f5f5;
+    padding: 20rpx 30rpx;
+    padding-bottom: calc(env(safe-area-inset-bottom) + 120rpx);
+}
+
+.section-card {
+    background: #fff;
+    margin-bottom: 20rpx;
+    padding: 30rpx;
+    border-radius: 16rpx;
+    box-sizing: border-box;
+}
+
+.u-required {
+    color: #ff0000;
+    margin-left: 8rpx;
+}
+
+.book-list {
+    background: #fff;
+    border-radius: 16rpx;
+    margin-bottom: 20rpx;
+}
+
+.info-row {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    padding: 20rpx 0;
+    font-size: 28rpx;
+    color: #333;
+
+    .label {
+        &.red-label {
+            color: #ff4500;
+            font-weight: bold;
+        }
+    }
+
+    .value {
+        &.text-gray {
+            color: #999;
+        }
+    }
+
+    .mr-10 {
+        margin-right: 10rpx;
+    }
+}
+
+.bottom-bar {
+    position: fixed;
+    bottom: 0;
+    left: 0;
+    right: 0;
+    background: #fff;
+    padding: 20rpx 30rpx;
+    padding-bottom: env(safe-area-inset-bottom);
+    box-shadow: 0 -2rpx 10rpx rgba(0, 0, 0, 0.05);
+
+    .order-summary {
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+
+        .total {
+            font-size: 28rpx;
+            color: #666;
+
+            .num {
+                color: #333;
+                font-weight: bold;
+                margin: 0 4rpx;
+            }
+
+            .reduce-text {
+                color: #38C148;
+                margin-left: 10rpx;
+                margin-right: 10rpx;
+                background-color: #e6f9e9;
+                padding: 4rpx 10rpx;
+                border-radius: 4rpx;
+                font-size: 24rpx;
+            }
+
+            .price {
+                font-size: 36rpx;
+                color: #ff4500;
+                font-weight: bold;
+                margin-left: 10rpx;
+            }
+        }
+    }
+}
+
+.mt-20 {
+    margin-top: 20rpx;
+}
+
+.ml-10 {
+    margin-left: 10rpx;
+}
+</style>

+ 12 - 2
pages-car/pages/index.vue

@@ -54,17 +54,23 @@
 
         <!-- 减钱弹窗 -->
         <price-reduction-popup ref="reducePopup" @share="handleShare" @scan="handleScan"></price-reduction-popup>
+
+        <common-dialog ref="reduceDialog" title="温馨提示" @confirm="onNext">
+            <text>购物车中有可减钱的商品,如您提交订单,则失去该资格哦~</text>
+        </common-dialog>
     </view>
 </template>
 
 <script>
 import CartItem from '../components/cart-item.vue';
 import PriceReductionPopup from '../components/price-reduction-popup.vue';
+import CommonDialog from '@/components/common-dialog.vue';
 
 export default {
     components: {
         CartItem,
-        PriceReductionPopup
+        PriceReductionPopup,
+        CommonDialog
     },
     data() {
         return {
@@ -219,7 +225,11 @@ export default {
                 uni.showToast({ title: '请选择商品', icon: 'none' });
                 return;
             }
-            uni.showToast({ title: '结算功能开发中', icon: 'none' });
+            this.$refs.reduceDialog.openPopup();
+        },
+        onNext() {
+            // 提交订单
+            uni.navigateTo({ url: '/pages-car/pages/confirm-order' });
         },
         handleShare() {
             console.log('share');

+ 6 - 0
pages.json

@@ -333,6 +333,12 @@
                         "navigationBarTitleText": "订单详情"
                     }
                 },
+                {
+                    "path": "pages/confirm-order",
+                    "style": {
+                        "navigationBarTitleText": "确认订单"
+                    }
+                },
                 {
                     "path": "pages/red-packet",
                     "style": {