Jelajahi Sumber

feat(购物车): 新增购物车相关页面和功能组件

新增购物车模块,包括购物车页面、订单管理、物流详情、到货提醒、红包等功能页面和相关组件。添加了订单状态管理、物流轨迹展示、商品列表展示等功能。
ylong 1 bulan lalu
induk
melakukan
cd6d9fa2d6

+ 94 - 0
pages-car/components/arrival-reminder-item.vue

@@ -0,0 +1,94 @@
+<template>
+    <view class="arrival-reminder-item">
+        <image class="book-cover" :src="info.cover || defaultCover" mode="aspectFill" />
+        <view class="info-box">
+            <view class="book-title">{{ info.title || info.bookName }}</view>
+            <view class="action-box">
+                <view class="btn-cancel" @click="onCancel">取消到货提醒</view>
+            </view>
+        </view>
+    </view>
+</template>
+
+<script>
+export default {
+    name: "arrival-reminder-item",
+    props: {
+        info: {
+            type: Object,
+            default: () => ({})
+        }
+    },
+    data() {
+        return {
+            defaultCover: 'https://shuhi.oss-cn-qingdao.aliyuncs.com/mini/default-book.png' // Placeholder
+        };
+    },
+    methods: {
+        onCancel() {
+            this.$emit('cancel', this.info);
+        }
+    }
+}
+</script>
+
+<style lang="scss" scoped>
+.arrival-reminder-item {
+    display: flex;
+    background-color: #ffffff;
+    padding: 30rpx;
+    border-bottom: 1rpx solid #f5f5f5; // Separator
+    
+    // If it's card style with margin
+    // margin: 20rpx;
+    // border-radius: 12rpx;
+    
+    // Based on the image, it looks like a list with white background items, possibly separated by small gap or just lines.
+    // The image shows items with some spacing between them or just a clean white list.
+    // Let's assume white background list items.
+    background-color: #fff;
+    margin-bottom: 20rpx; // Space between items as seen in the image (gray background showing through)
+
+    .book-cover {
+        width: 140rpx;
+        height: 190rpx; // Approx aspect ratio
+        border-radius: 8rpx;
+        flex-shrink: 0;
+        margin-right: 24rpx;
+        background-color: #eee;
+    }
+
+    .info-box {
+        flex: 1;
+        display: flex;
+        flex-direction: column;
+        justify-content: space-between;
+        
+        .book-title {
+            font-size: 30rpx;
+            color: #333;
+            line-height: 1.4;
+            font-weight: 500;
+            display: -webkit-box;
+            -webkit-box-orient: vertical;
+            -webkit-line-clamp: 3;
+            overflow: hidden;
+        }
+
+        .action-box {
+            display: flex;
+            justify-content: flex-end;
+            margin-top: 20rpx; // Ensure spacing if title is short
+            
+            .btn-cancel {
+                font-size: 24rpx;
+                color: #fff;
+                background-color: $app-theme-color;
+                padding: 12rpx 24rpx;
+                border-radius: 30rpx;
+                line-height: 1;
+            }
+        }
+    }
+}
+</style>

+ 162 - 0
pages-car/components/book-list-item.vue

@@ -0,0 +1,162 @@
+<template>
+    <view class="book-item">
+        <!-- 书籍封面 -->
+        <image class="book-cover" :src="book.cover" mode="aspectFill" />
+        <!-- 书籍详情 -->
+        <view class="book-info">
+            <view class="book-title">{{ book.bookName }}</view>
+            <view class="book-price">
+                <view class="sale-price">
+                    <text class="symbol">¥</text>
+                    <text class="amount">{{ book.recycleMoney }}</text>
+                </view>
+                <text class="origin-price">¥{{ book.recycleMoney }}</text>
+            </view>
+        </view>
+        <!-- 选择框 -->
+        <view class="checkbox-item" v-if="isEditMode">
+            <u-checkbox v-show="isEditMode" class="checkbox-item" v-model="book.selected" :name="book.isbn"
+                shape="circle" label-size="0" active-color="#38C148" @change="updateCheckbox"></u-checkbox>
+        </view>
+    </view>
+</template>
+
+<script>
+export default {
+    name: 'BookListItem',
+    props: {
+        book: {
+            type: Object,
+            required: true
+        },
+        isEditMode: {
+            type: Boolean,
+            default: false
+        }
+    },
+    data() {
+        return {
+            statusMap: {
+                1: "added",
+                2: 'pending',
+                3: 'disabled'
+            }
+        }
+    },
+    methods: {
+        getStatusText(status) {
+            //  1-已加入卖书清单 2-未加入 3-暂不回收
+            let key = this.statusMap[status]
+            const statusKey = {
+                pending: '加入卖书清单',
+                added: '已加入卖书清单',
+                disabled: '暂不回收'
+            }
+            return statusKey[key] || key
+        },
+        updateCheckbox({ value }) {
+            this.$nextTick(() => {
+                this.$emit('checked', { book: this.book, checked: value })
+            })
+        },
+        handleAction() {
+            this.$emit('action', this.book)
+        }
+    }
+}
+</script>
+
+<style lang="scss" scoped>
+.book-item {
+    position: relative;
+    width: calc((100vw - 80rpx) / 3);
+    background-color: #ffffff;
+    box-sizing: border-box;
+    padding: 20rpx;
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    border-radius: 10rpx;
+    height: 100%;
+    padding-bottom: 10rpx;
+
+    .check-icon {
+        position: absolute;
+        left: 6rpx;
+        top: 6rpx;
+        z-index: 1;
+        width: 32rpx;
+        height: 32rpx;
+        background: #38C148;
+        border-radius: 50%;
+        display: flex;
+        align-items: center;
+        justify-content: center;
+    }
+
+    .book-cover {
+        width: 140rpx;
+        height: 197rpx;
+        border-radius: 8rpx;
+        margin-bottom: 8rpx;
+    }
+
+    .book-info {
+        width: 100%;
+
+        .book-title {
+            font-size: 24rpx;
+            color: #333333;
+            margin-bottom: 8rpx;
+            display: -webkit-box;
+            -webkit-box-orient: vertical;
+            -webkit-line-clamp: 1;
+            overflow: hidden;
+            margin-top: 15rpx;
+        }
+
+        .book-price {
+            margin-bottom: 12rpx;
+            font-family: Source Han Sans CN;
+            display: flex;
+            justify-content: space-between;
+            align-items: center;
+            align-items: baseline;
+
+            .sale-price {
+                color: #FF5B5B;
+                margin-right: 12rpx;
+                display: flex;
+                align-items: baseline;
+                font-weight: bold;
+                
+                .symbol {
+                    font-size: 24rpx;
+                    margin-right: 2rpx;
+                }
+                .amount {
+                    font-size: 32rpx;
+                    line-height: 1;
+                }
+            }
+
+            .origin-price {
+                font-size: 24rpx;
+                color: #999999;
+                text-decoration: line-through;
+            }
+        }
+    }
+
+    .checkbox-item {
+        position: absolute;
+        right: 6rpx;
+        top: 0;
+        z-index: 9;
+
+        ::v-deep .u-checkbox__label {
+            margin: 0 !important;
+        }
+    }
+}
+</style>

+ 256 - 0
pages-car/components/buy-order-item.vue

@@ -0,0 +1,256 @@
+<template>
+    <view class="buy-order-item" @click="goToDetail">
+        <!-- 订单头部:订单号和状态 -->
+        <view class="order-header">
+            <text class="order-no">{{ order.orderNo }}</text>
+            <text class="order-status">{{ getStatusText(order.status) }}</text>
+        </view>
+
+        <!-- 商品信息 -->
+        <view class="goods-list">
+            <!-- 单个商品 -->
+            <view v-if="order.goodsList && order.goodsList.length === 1" class="single-goods">
+                <image :src="order.goodsList[0].cover || defaultCover" mode="aspectFill" class="goods-cover"></image>
+                <view class="goods-info">
+                    <view class="goods-title">{{ order.goodsList[0].title }}</view>
+                    <view class="goods-quality">品相:{{ order.goodsList[0].quality || '中等' }}</view>
+                </view>
+                <view class="goods-price-num">
+                    <view class="price">¥ {{ order.goodsList[0].price }}</view>
+                    <view class="num">x{{ order.goodsList[0].num }}</view>
+                </view>
+            </view>
+            <!-- 多个商品 -->
+            <view v-else class="multi-goods">
+                <scroll-view scroll-x class="goods-scroll">
+                    <view class="goods-wrapper">
+                        <image v-for="(goods, index) in order.goodsList" :key="index" :src="goods.cover || defaultCover"
+                            mode="aspectFill" class="goods-cover"></image>
+                    </view>
+                </scroll-view>
+            </view>
+        </view>
+
+        <!-- 价格汇总 -->
+        <view class="order-total">
+            <text>总价 ¥{{ order.totalPrice }}</text>
+            <text class="ml-20">实付款 ¥{{ order.realPayPrice }}</text>
+        </view>
+
+        <!-- 操作按钮 -->
+        <view class="action-box">
+            <template v-if="order.status === 2"> <!-- 待付款 -->
+                <u-button size="mini" shape="circle" plain :custom-style="btnStyle" @click="handleAction('address')">修改地址</u-button>
+                <u-button size="mini" shape="circle" type="error" plain :custom-style="btnStyle" @click="handleAction('cancel')">取消订单</u-button>
+                <u-button size="mini" shape="circle" :custom-style="themeBtnStyle" @click="handleAction('pay')">付款</u-button>
+            </template>
+            <template v-else-if="order.status === 3"> <!-- 待发货 -->
+                <u-button size="mini" shape="circle" plain :custom-style="btnStyle" @click="handleAction('address')">修改地址</u-button>
+                <u-button size="mini" shape="circle" type="error" plain :custom-style="btnStyle" @click="handleAction('refund')">申请售后</u-button>
+                <u-button size="mini" shape="circle" type="warning" plain :custom-style="btnStyle" @click="handleAction('remind')">催发货</u-button>
+            </template>
+            <template v-else-if="order.status === 8"> <!-- 待收货/已发货 -->
+                <u-button size="mini" shape="circle" plain :custom-style="btnStyle" @click="handleAction('extend')">延长收货</u-button>
+                <u-button size="mini" shape="circle" plain :custom-style="btnStyle" @click="handleAction('invoice')">申请开票</u-button>
+                <u-button size="mini" shape="circle" plain :custom-style="btnStyle" @click="handleAction('complaint')">投诉</u-button>
+                <u-button size="mini" shape="circle" type="primary" plain :custom-style="btnStyle" @click="handleAction('logistics')">查看物流</u-button>
+                <u-button size="mini" shape="circle" :custom-style="themeBtnStyle" @click="handleAction('addToCart')">加入购物车</u-button>
+                <u-button size="mini" shape="circle" :custom-style="themeBtnStyle" @click="handleAction('confirm')">确认收货</u-button>
+            </template>
+            <template v-else-if="order.status === 12"> <!-- 已完成 -->
+                <u-button size="mini" shape="circle" :custom-style="themeBtnStyle" @click="handleAction('addToCart')">加入购物车</u-button>
+                <u-button size="mini" shape="circle" type="primary" plain :custom-style="btnStyle" @click="handleAction('rebuy')">再买一单</u-button>
+                <u-button size="mini" shape="circle" type="primary" plain :custom-style="btnStyle" @click="handleAction('evaluate')">评价</u-button>
+                <u-button size="mini" shape="circle" plain :custom-style="btnStyle" @click="handleAction('more', ['applyAfterSales', 'logistics', 'invoice'])">更多</u-button>
+            </template>
+            <template v-else-if="order.status === 10"> <!-- 退款/售后 -->
+                <u-button size="mini" shape="circle" type="primary" plain :custom-style="btnStyle" @click="handleAction('moneyWhere')">钱款去向</u-button>
+                <u-button size="mini" shape="circle" type="primary" plain :custom-style="btnStyle" @click="handleAction('detail')">查看详情</u-button>
+            </template>
+            <template v-else-if="order.status === -1"> <!-- 已取消 -->
+                <u-button size="mini" shape="circle" type="error" plain :custom-style="btnStyle" @click="handleAction('delete')">删除订单</u-button>
+                <u-button size="mini" shape="circle" :custom-style="themeBtnStyle" @click="handleAction('addToCart')">加入购物车</u-button>
+            </template>
+        </view>
+    </view>
+</template>
+
+<script>
+export default {
+    props: {
+        order: {
+            type: Object,
+            required: true
+        }
+    },
+    data() {
+        return {
+            defaultCover: 'https://uviewui.com/album/1.jpg',
+            btnStyle: {
+                marginLeft: '20rpx',
+                width: '150rpx',
+                height: '60rpx',
+                lineHeight: '60rpx',
+                padding: '0',
+                fontSize:'26rpx',
+            },
+            themeBtnStyle: {
+                marginLeft: '20rpx',
+                width: '160rpx',
+                height: '60rpx',
+                lineHeight: '60rpx',
+                padding: '0',
+                backgroundColor: '#38C148',
+                color: '#fff',
+                fontSize:'26rpx',
+            }
+        }
+    },
+    methods: {
+        goToDetail() {
+            uni.navigateTo({
+                url: `/pages-car/pages/order-detail?orderNo=${this.order.orderNo}`
+            })
+        },
+        getStatusText(status) {
+            const map = {
+                2: '待付款',
+                3: '待发货',
+                8: '待收货',
+                12: '已完成',
+                10: '退款/售后',
+                '-1': '已取消'
+            }
+            return map[status] || '未知状态'
+        },
+        handleAction(type, data) {
+            this.$emit('action', { type, order: this.order, data })
+        }
+    }
+}
+</script>
+
+<style lang="scss" scoped>
+.buy-order-item {
+    background-color: #fff;
+    border-radius: 16rpx;
+    padding: 30rpx 20rpx;
+    margin-bottom: 20rpx;
+
+    .order-header {
+        display: flex;
+        justify-content: space-between;
+        margin-bottom: 20rpx;
+        font-size: 28rpx;
+
+        .order-no {
+            color: #333;
+            font-weight: 500;
+        }
+
+        .order-status {
+            color: #999;
+        }
+    }
+
+    .goods-list {
+        margin-bottom: 20rpx;
+
+        .single-goods {
+            display: flex;
+
+            .goods-cover {
+                width: 140rpx;
+                height: 170rpx;
+                border-radius: 8rpx;
+                margin-right: 20rpx;
+                flex-shrink: 0;
+                background-color: #eee;
+            }
+
+            .goods-info {
+                flex: 1;
+                margin-right: 20rpx;
+
+                .goods-title {
+                    font-size: 28rpx;
+                    color: #333;
+                    margin-bottom: 10rpx;
+                    display: -webkit-box;
+                    -webkit-box-orient: vertical;
+                    -webkit-line-clamp: 2;
+                    overflow: hidden;
+                }
+
+                .goods-quality {
+                    font-size: 24rpx;
+                    color: #999;
+                    background-color: #f5f5f5;
+                    padding: 4rpx 10rpx;
+                    border-radius: 4rpx;
+                    display: inline-block;
+                }
+            }
+
+            .goods-price-num {
+                text-align: right;
+
+                .price {
+                    font-size: 28rpx;
+                    color: #333;
+                    font-weight: 500;
+                }
+
+                .num {
+                    font-size: 24rpx;
+                    color: #999;
+                    margin-top: 6rpx;
+                }
+            }
+        }
+
+        .multi-goods {
+            .goods-scroll {
+                width: 100%;
+                white-space: nowrap;
+            }
+
+            .goods-wrapper {
+                display: flex;
+            }
+
+            .goods-cover {
+                width: 140rpx;
+                height: 170rpx;
+                border-radius: 8rpx;
+                margin-right: 20rpx;
+                background-color: #eee;
+                display: inline-block;
+            }
+        }
+    }
+
+    .order-total {
+        text-align: right;
+        font-size: 26rpx;
+        color: #333;
+        margin-bottom: 20rpx;
+
+        .ml-20 {
+            margin-left: 20rpx;
+            font-weight: 500;
+        }
+    }
+
+    .action-box {
+        display: flex;
+        justify-content: flex-end;
+        align-items: center;
+
+        .status-desc {
+            font-size: 26rpx;
+            color: #999;
+        }
+    }
+}
+</style>

+ 270 - 0
pages-car/components/cart-item.vue

@@ -0,0 +1,270 @@
+<template>
+    <view class="cart-item">
+        <!-- 复选框 -->
+        <view class="checkbox-box">
+            <u-checkbox v-model="item.checked" shape="circle" active-color="#38C148"
+                @change="onCheckChange" :disabled="!isValid"></u-checkbox>
+        </view>
+
+        <!-- 商品图片 -->
+        <view class="image-wrapper">
+            <image :src="item.cover" mode="aspectFill" class="book-cover"></image>
+            <!-- 状态遮罩 -->
+            <view class="status-mask" v-if="!isValid">
+                <text>{{ statusText }}</text>
+            </view>
+            <!-- 库存紧张遮罩 -->
+            <view class="stock-mask" v-if="isValid && item.stockWarning">
+                <text>库存紧张</text>
+            </view>
+        </view>
+
+        <!-- 商品信息 -->
+        <view class="info-box">
+            <view class="title">{{ item.title }}</view>
+
+            <!-- 标签和品相区域 -->
+            <view class="tags-quality-row">
+                <!-- 品相选择 (模拟) -->
+                <view class="quality-selector">
+                    <text>品相:{{ item.quality || '中等' }}</text>
+                    <u-icon name="arrow-down" size="20" color="#999" style="margin-left: 4rpx;"></u-icon>
+                </view>
+
+                <!-- 已降价标签 -->
+                <view class="tag green-tag" v-if="item.reducedAmount > 0">
+                    <text>已降¥{{ item.reducedAmount }}</text>
+                </view>
+                <!-- 可降价标签 -->
+                <view class="tag orange-tag" v-if="item.canReduceAmount > 0" @click.stop="handleReduce">
+                    <text>可降¥{{ item.canReduceAmount }}</text>
+                </view>
+            </view>
+
+            <!-- 底部价格和操作 -->
+            <view class="bottom-row">
+                <view class="price-box">
+                    <text class="symbol">¥</text>
+                    <text class="amount">{{ item.price }}</text>
+                </view>
+
+                <!-- 去减钱按钮 -->
+                <view class="reduce-btn" v-if="item.canReduceAmount > 0" @click.stop="handleReduce">
+                    <text>去减钱</text>
+                </view>
+
+                <!-- 数量加减 -->
+                <u-number-box v-model="item.num" :min="1" :max="item.stock || 99" :disabled="!isValid"
+                    @change="onNumChange" :size="24"></u-number-box>
+            </view>
+        </view>
+    </view>
+</template>
+
+<script>
+export default {
+    props: {
+        item: {
+            type: Object,
+            default: () => ({})
+        }
+    },
+    computed: {
+        isValid() {
+            // status: 1-正常, 0-无效/无库存
+            return this.item.status === 1 && this.item.stock > 0;
+        },
+        statusText() {
+            if (this.item.stock <= 0) return '暂无库存';
+            if (this.item.status !== 1) return '失效';
+            return '';
+        }
+    },
+    methods: {
+        onCheckChange(val) {
+            this.$emit('check', { id: this.item.id, checked: val.value });
+        },
+        onNumChange(val) {
+            this.$emit('changeNum', { id: this.item.id, num: val.value });
+        },
+        handleReduce() {
+            this.$emit('reduce', this.item);
+        }
+    }
+}
+</script>
+
+<style lang="scss" scoped>
+.cart-item {
+    display: flex;
+    align-items: center;
+    background-color: #fff;
+    padding: 30rpx 20rpx;
+    border-radius: 16rpx;
+    margin-bottom: 20rpx;
+
+    .checkbox-box {
+        width: 50rpx;
+        display: flex;
+        justify-content: center;
+        flex-shrink: 0;
+
+        &.disabled-checkbox {
+            .circle {
+                width: 34rpx;
+                height: 34rpx;
+                border-radius: 50%;
+                background-color: #e5e5e5;
+            }
+        }
+    }
+
+    .image-wrapper {
+        position: relative;
+        width: 150rpx;
+        height: 200rpx;
+        border-radius: 8rpx;
+        overflow: hidden;
+        flex-shrink: 0;
+        margin-right: 20rpx;
+
+        .book-cover {
+            width: 100%;
+            height: 100%;
+        }
+
+        .status-mask {
+            position: absolute;
+            bottom: 0;
+            left: 0;
+            width: 100%;
+            height: 40rpx;
+            background-color: rgba(0, 0, 0, 0.6);
+            display: flex;
+            justify-content: center;
+            align-items: center;
+            
+            text {
+                color: #fff;
+                font-size: 20rpx;
+            }
+        }
+
+        .stock-mask {
+            position: absolute;
+            bottom: 0;
+            left: 0;
+            width: 100%;
+            height: 40rpx;
+            background-color: #38C148; // Green background
+            opacity: 0.8;
+            display: flex;
+            justify-content: center;
+            align-items: center;
+            
+            text {
+                color: #fff;
+                font-size: 20rpx;
+            }
+        }
+    }
+
+    .info-box {
+        flex: 1;
+        height: 220rpx;
+        display: flex;
+        flex-direction: column;
+        justify-content: space-between;
+
+        .title {
+            font-size: 28rpx;
+            color: #333;
+            line-height: 1.4;
+            display: -webkit-box;
+            -webkit-box-orient: vertical;
+            -webkit-line-clamp: 2;
+            overflow: hidden;
+            font-weight: 500;
+        }
+
+        .tags-quality-row {
+            display: flex;
+            flex-wrap: wrap;
+            justify-content: space-between;
+            align-items: center;
+            margin: 20rpx 0 0 0;
+
+            .tag {
+                font-size: 22rpx;
+                padding: 2rpx 8rpx;
+                border-radius: 4rpx;
+                margin-right: 10rpx;
+                border: 1rpx solid transparent;
+                margin-bottom: 6rpx;
+
+                &.green-tag {
+                    color: #38C148;
+                    border-color: #38C148;
+                    background-color: rgba(56, 193, 72, 0.1);
+                }
+
+                &.orange-tag {
+                    color: #ff6a00;
+                    border-color: #ff6a00;
+                    background-color: rgba(255, 106, 0, 0.1);
+                }
+
+                &.red-text-tag {
+                    background-color: #38C148;
+                    color: #fff;
+                    border: none;
+                }
+            }
+
+            .quality-selector {
+                display: flex;
+                align-items: center;
+                font-size: 24rpx;
+                color: #999;
+                background-color: #f5f5f5;
+                padding: 4rpx 12rpx;
+                border-radius: 4rpx;
+                width: fit-content;
+                margin-bottom: 6rpx;
+                margin-right: 10rpx;
+                order: -1; // Move to front
+            }
+        }
+
+        .bottom-row {
+            display: flex;
+            align-items: center;
+            justify-content: space-between;
+            margin-top: auto;
+
+            .price-box {
+                color: #e02020;
+                font-weight: bold;
+
+                .symbol {
+                    font-size: 24rpx;
+                }
+
+                .amount {
+                    font-size: 36rpx;
+                }
+            }
+
+            .reduce-btn {
+                background-color: #38C148;
+                color: #fff;
+                font-size: 20rpx;
+                padding: 6rpx 16rpx;
+                border-radius: 20rpx;
+                margin-left: 10rpx;
+                margin-right: auto; // Push num box to right
+            }
+        }
+    }
+}
+</style>

+ 327 - 0
pages-car/components/price-reduction-popup.vue

@@ -0,0 +1,327 @@
+<template>
+  <custom-popup
+    v-model="showPopup"
+    mode="center"
+    border-radius="24"
+    width="650rpx"
+    :bg-color="'transparent'"
+  >
+    <view class="popup-container">
+      <!-- 顶部黄色手掌图标和标题 -->
+      <view class="header">
+        <!-- <image src="/static/img/activity/hand.png" class="hand-icon"></image> -->
+        <view class="title-text">你真的太幸运了</view>
+        <view class="title-text">恭喜你获得限时减价权益</view>
+      </view>
+
+      <!-- 绿色价格信息区域 -->
+      <view class="price-section">
+        <view class="price-row">
+          <text class="price-label">此书当前价格</text>
+          <text class="price-value">¥ {{ bookInfo.price || 0 }}</text>
+        </view>
+        <view class="price-row">
+          <text class="price-label">助力成功减至</text>
+          <text class="price-value increased"
+            >¥ {{ bookInfo.reducedPrice || 0 }}</text
+          >
+          <image
+            class="up-icon"
+            src="/static/img/activity/up2.png"
+            mode="widthFix"
+            style="transform: rotate(180deg);" 
+          ></image>
+        </view>
+        <view class="small-text"
+          >实际金额以最终下单为准,活动时间{{
+            formatDate(bookInfo.startTime)
+          }}至{{ formatDate(bookInfo.endTime) }}</view
+        >
+      </view>
+
+      <!-- 分享助力区域 -->
+      <view class="share-section">
+        <view class="share-text">分享{{ inviteUsers.length }}位好友砍价</view>
+        <view class="add-button">
+          <block v-for="(item, index) in inviteUsers" :key="index">
+            <view class="add-item" v-if="item.imgPath">
+              <image
+                class="hand-icon"
+                :src="item.imgPath"
+                mode="widthFix"
+              ></image>
+              <view class="add-text">{{ formatName(item.nickName) }}</view>
+            </view>
+
+            <button v-else open-type="share" class="hand-btn">
+              <image
+              open-type="share"
+                class="hand-icon"
+                src="/static/img/activity/invite.png"
+                mode="widthFix"
+              ></image>
+            </button>
+          </block>
+        </view>
+      </view>
+
+      <!-- 分享按钮 -->
+      <view class="action-buttons">
+        <button class="share-button" @click="shareAction" open-type="share">
+          立即分享
+        </button>
+        <button class="scan-button" @click="scanAction">扫码砍价</button>
+      </view>
+
+      <!-- 关闭按钮 -->
+      <view class="close-button" @click="closePopup">
+        <image src="/static/img/activity/close2.png" mode="widthFix"></image>
+      </view>
+    </view>
+  </custom-popup>
+</template>
+
+<script>
+import customPopup from "@/components/custom-popup.vue";
+export default {
+  components: {
+    customPopup,
+  },
+  data() {
+    return {
+      showPopup: false,
+      bookInfo: {},
+      inviteUsers: [],
+    };
+  },
+  methods: {
+    open(data) {
+      this.showPopup = true;
+      this.getIsbnInfo(data.isbn, data.orderId);
+    },
+    //获取信息
+    getIsbnInfo(isbn, orderId) {
+      uni.$u.http
+        .get(`/token/order/clickUpsellInvite?isbn=${isbn}&orderId=${orderId}`)
+        .then((res) => {
+          if (res.code == 200) {
+            this.bookInfo = res.data;
+            let needInviteNum = res.data.needInviteNum;
+            let inviteUsers = res.data.inviteUsers || [];
+            let length = inviteUsers.length;
+            for (let index = 0; index < needInviteNum - length; index++) {
+              inviteUsers.push({
+                nickName: "",
+                imgPath: "",
+              });
+            }
+            this.inviteUsers = inviteUsers;
+            uni.setStorageSync("upsellCodeShare", res.data.upsellCode);
+          } else {
+            uni.$u.toast(res.msg);
+          }
+        });
+    },
+    // 转换时间的方法,将年月日时分秒转换成 3/25 格式
+    formatDate(dateString) {
+      if (!dateString) return "";
+
+      const date = new Date(dateString);
+      const month = date.getMonth() + 1; // 月份从0开始,需要+1
+      const day = date.getDate();
+
+      return `${month}/${day}`;
+    },
+
+    //格式化 name,长度大于 3,只保留第一个和最后一个字,中间最多使用三个 *代替
+    // 长度小于 3,只保留第一个字
+    formatName(name) {
+      if (!name) return "";
+      if (name.length > 2) {
+        return name.slice(0, 1) + "*" + name.slice(-1);
+      } else {
+        return name.slice(0, 1) + "*";
+      }
+    },
+
+    closePopup() {
+      this.showPopup = false;
+    },
+    shareAction() {
+      this.$emit("share", this.bookInfo);
+    },
+    scanAction() {
+      this.$emit("scan", this.bookInfo);
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.popup-container {
+  position: relative;
+  padding: 30rpx;
+  box-sizing: border-box;
+  padding-bottom: 50rpx;
+  background: url("https://shuhi.oss-cn-qingdao.aliyuncs.com/mini/bg2.png")
+    no-repeat center center;
+  background-size: 100% 100%;
+}
+
+.header {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  padding: 20rpx 0 10rpx;
+  padding-top: 160rpx;
+
+  .title-text {
+    font-size: 38rpx;
+    font-weight: bold;
+    color: #000;
+    margin-bottom: 10rpx;
+  }
+
+  .subtitle-text {
+    font-size: 32rpx;
+    color: #000;
+  }
+
+  .hand-icon {
+    width: 140rpx;
+    height: 140rpx;
+    position: relative;
+    top: -30rpx;
+  }
+}
+
+.price-section {
+  background-color: #39c248;
+  border-radius: 16rpx;
+  padding: 20rpx 30rpx;
+  margin: 20rpx 0;
+
+  .price-row {
+    display: flex;
+    align-items: center;
+
+    .price-label {
+      color: #ffffff;
+      font-size: 30rpx;
+    }
+
+    .price-value {
+      color: #ffeb3b;
+      font-size: 30rpx;
+      font-weight: bold;
+      margin-left: 10rpx;
+    }
+
+    .increased {
+      font-size: 42rpx;
+    }
+
+    .up-icon {
+      width: 30rpx;
+      height: 30rpx;
+      margin-left: 5rpx;
+    }
+  }
+
+  .small-text {
+    color: #ffffff;
+    font-size: 22rpx;
+    margin-top: 10rpx;
+  }
+}
+
+.share-section {
+  background-color: #e8f8e8;
+  border-radius: 16rpx;
+  padding: 30rpx;
+  margin: 20rpx 0;
+
+  .share-text {
+    color: #39c248;
+    font-size: 32rpx;
+    text-align: center;
+    margin-bottom: 30rpx;
+  }
+
+  .add-button {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    gap: 10rpx;
+
+    .hand-icon {
+      width: 100rpx;
+      height: 100rpx;
+    }
+  }
+  .hand-btn{
+    display: inline-block;
+    width: 100rpx !important;
+    height: 110rpx;
+    background: transparent;
+    flex: none;
+    padding: 0;
+  }
+
+  .add-item {
+    position: relative;
+    .add-text {
+      position: absolute;
+      bottom: 2rpx;
+      left: 5rpx;
+      font-size: 24rpx;
+      background: #39c248;
+      text-align: center;
+      color: #fff;
+      padding: 0 10rpx;
+      border-radius: 20rpx;
+      display: inline-block;
+      width: 94rpx;
+    }
+  }
+}
+
+.action-buttons {
+  margin-top: 30rpx;
+
+  .share-button {
+    height: 90rpx;
+    background: linear-gradient(to bottom, #47d46c, #24ad3c) !important;
+    margin-bottom: 24rpx;
+    font-size: 32rpx;
+    color: #ffffff;
+    border-radius: 10rpx;
+    line-height: 90rpx;
+  }
+
+  .scan-button {
+    height: 90rpx;
+    font-size: 32rpx;
+    color: #39c248;
+    border: 1rpx solid #39c248;
+    background-color: transparent;
+    border-radius: 10rpx;
+    line-height: 90rpx;
+  }
+  button + button {
+    margin-left: 0;
+  }
+}
+
+.close-button {
+  position: absolute;
+  bottom: -120rpx;
+  left: 50%;
+  transform: translateX(-50%);
+
+  image {
+    width: 70rpx;
+    height: 70rpx;
+  }
+}
+</style>

+ 218 - 0
pages-car/components/red-packet-item.vue

@@ -0,0 +1,218 @@
+<template>
+    <view class="red-packet-item" :class="{ 'is-disabled': isDisabled }">
+        <view class="left-part">
+            <view class="amount-box">
+                <text class="symbol">¥</text>
+                <text class="amount">{{ info.amount || 0 }}</text>
+            </view>
+            <view class="condition">满 ¥{{ info.condition || 0 }}使用</view>
+        </view>
+        <view class="right-part">
+            <view class="info-top">
+                <view class="title-row">
+                    <view class="tag" :class="info.type === 2 ? 'surprise' : 'normal'">
+                        {{ info.typeName || (info.type === 2 ? '惊喜红包' : '普通红包') }}
+                    </view>
+                    <text class="title">{{ info.title }}</text>
+                </view>
+                <view class="date">{{ info.endTime }}到期</view>
+            </view>
+            
+            <view class="action-box">
+                <view v-if="status === 0" class="btn-use" @click="onUse">立即使用</view>
+                <view v-else-if="status === 1" class="stamp used">
+                    <text>已使用</text>
+                </view>
+                <view v-else-if="status === 2" class="stamp expired">
+                    <text>已过期</text>
+                </view>
+            </view>
+        </view>
+    </view>
+</template>
+
+<script>
+export default {
+    name: "red-packet-item",
+    props: {
+        info: {
+            type: Object,
+            default: () => ({})
+        }
+    },
+    computed: {
+        // 0: unused, 1: used, 2: expired
+        status() {
+            return this.info.status || 0;
+        },
+        isDisabled() {
+            return this.status !== 0;
+        }
+    },
+    methods: {
+        onUse() {
+            this.$emit('use', this.info);
+        }
+    }
+}
+</script>
+
+<style lang="scss" scoped>
+.red-packet-item {
+    display: flex;
+    background-color: #ffffff;
+    border-radius: 16rpx;
+    margin: 20rpx 24rpx;
+    position: relative;
+    overflow: hidden;
+    box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.05);
+
+    &.is-disabled {
+        .left-part {
+            color: #999;
+            .amount-box {
+                color: #999;
+            }
+        }
+        .right-part {
+            .title {
+                color: #999;
+            }
+            .tag {
+                background-color: #ccc;
+                color: #fff;
+            }
+        }
+    }
+
+    .left-part {
+        width: 200rpx;
+        display: flex;
+        flex-direction: column;
+        justify-content: center;
+        align-items: center;
+        color: #e02020;
+        border-right: 1px dashed #eeeeee;
+        position: relative;
+        padding: 30rpx 0;
+
+        &::before, &::after {
+            content: '';
+            position: absolute;
+            right: -10rpx;
+            width: 20rpx;
+            height: 20rpx;
+            background-color: #f5f5f5; // Assume page bg is #f5f5f5
+            border-radius: 50%;
+        }
+        &::before { top: -10rpx; }
+        &::after { bottom: -10rpx; }
+
+        .amount-box {
+            display: flex;
+            align-items: baseline;
+            font-weight: bold;
+            .symbol {
+                font-size: 28rpx;
+            }
+            .amount {
+                font-size: 60rpx;
+                line-height: 1;
+            }
+        }
+        .condition {
+            font-size: 22rpx;
+            margin-top: 10rpx;
+        }
+    }
+
+    .right-part {
+        flex: 1;
+        padding: 30rpx 24rpx;
+        display: flex;
+        flex-direction: column;
+        justify-content: space-between;
+        position: relative;
+
+        .info-top {
+            .title-row {
+                display: flex;
+                align-items: center;
+                flex-wrap: wrap;
+                margin-bottom: 16rpx;
+
+                .tag {
+                    font-size: 20rpx;
+                    padding: 2rpx 8rpx;
+                    border-radius: 4rpx;
+                    margin-right: 10rpx;
+                    
+                    &.normal {
+                        background-color: #fcebeb;
+                        color: #e02020;
+                    }
+                    &.surprise {
+                        background-color: #fff0e5;
+                        color: #ff6a00;
+                    }
+                }
+
+                .title {
+                    font-size: 28rpx;
+                    color: #333;
+                    font-weight: 500;
+                }
+            }
+
+            .date {
+                font-size: 22rpx;
+                color: #999;
+            }
+        }
+
+        .action-box {
+            position: absolute;
+            right: 24rpx;
+            bottom: 30rpx;
+            
+            // For status buttons aligned with date or bottom right
+        }
+
+        .btn-use {
+            background-color: #e02020;
+            color: #fff;
+            font-size: 24rpx;
+            padding: 10rpx 24rpx;
+            border-radius: 30rpx;
+        }
+
+        .stamp {
+            width: 100rpx;
+            height: 100rpx;
+            border: 2rpx solid #ccc;
+            border-radius: 50%;
+            display: flex;
+            justify-content: center;
+            align-items: center;
+            transform: rotate(-30deg);
+            opacity: 0.6;
+            
+            text {
+                font-size: 24rpx;
+                color: #999;
+                font-weight: bold;
+            }
+            
+            &.used {
+                border-color: #999;
+                text { color: #999; }
+            }
+            
+            &.expired {
+                border-color: #999;
+                text { color: #999; }
+            }
+        }
+    }
+}
+</style>

+ 65 - 0
pages-car/pages/arrival-reminder.vue

@@ -0,0 +1,65 @@
+<template>
+    <view class="arrival-reminder-page">
+        <page-scroll
+            ref="pageScroll"
+            emptyText="暂无到货提醒"
+            @updateList="updateList"
+        >
+            <view class="list-container">
+                <arrival-reminder-item 
+                    v-for="(item, index) in list" 
+                    :key="index" 
+                    :info="item"
+                    @cancel="handleCancel"
+                />
+            </view>
+        </page-scroll>
+    </view>
+</template>
+
+<script>
+import PageScroll from '@/components/pageScroll/index.vue';
+import ArrivalReminderItem from '../components/arrival-reminder-item.vue';
+
+export default {
+    components: {
+        PageScroll,
+        ArrivalReminderItem
+    },
+    data() {
+        return {
+            list: []
+        };
+    },
+    methods: {
+        updateList(data) {
+            // Mock data for display purposes
+            this.list = data
+        },
+        handleCancel(item) {
+            uni.showModal({
+                title: '提示',
+                content: '确定要取消该书籍的到货提醒吗?',
+                success: (res) => {
+                    if (res.confirm) {
+                        this.list = this.list.filter(i => i.id !== item.id);
+                        uni.showToast({ title: '已取消', icon: 'none' });
+                    }
+                }
+            });
+        }
+    }
+}
+</script>
+
+<style lang="scss" scoped>
+.arrival-reminder-page {
+    background-color: #f5f5f5;
+    min-height: 100vh;
+}
+
+.list-container {
+    padding-top: 20rpx;
+    padding-bottom: 20rpx;
+}
+</style>

+ 382 - 0
pages-car/pages/index.vue

@@ -0,0 +1,382 @@
+<template>
+    <view class="cart-page">
+        <!-- 广告位 -->
+        <!-- <view class="ad-banner">
+            <text>这里是广告</text>
+            <u-icon name="arrow-right" color="#999" size="28"></u-icon>
+        </view> -->
+
+        <!-- 购物车列表 -->
+        <view class="cart-list">
+            <cart-item v-for="(item, index) in cartList" :key="index" :item="item" @check="handleCheck"
+                @changeNum="handleChangeNum" @reduce="handleReduce"></cart-item>
+        </view>
+
+        <!-- 为你推荐 -->
+        <view class="recommend-section">
+            <view class="section-title">
+                <text class="line"></text>
+                <text class="text">为你推荐</text>
+                <text class="line"></text>
+            </view>
+            <view class="recommend-grid">
+                <view class="grid-item" v-for="(item, index) in recommendList" :key="index">
+                    <image :src="item.cover" mode="aspectFill" class="cover"></image>
+                    <view class="title">{{ item.title }}</view>
+                </view>
+            </view>
+        </view>
+
+        <!-- 底部占位 -->
+        <view style="height: 20rpx;"></view>
+
+        <!-- 底部结算栏 -->
+        <view class="bottom-fixed">
+            <view class="left-part">
+                <view class="checkbox-wrap" @click="toggleSelectAll">
+                    <u-checkbox v-model="isAllSelected" shape="circle" active-color="#38C148" :disabled="false"
+                        @change="onAllCheckChange">全选</u-checkbox>
+                </view>
+            </view>
+            <view class="right-part">
+                <view class="total-info">
+                    <view class="reduced-tip" v-if="totalReduced > 0">已降 ¥{{ totalReduced }}</view>
+                    <view class="total-price">
+                        <text class="label">合计:</text>
+                        <text class="price">¥{{ totalPrice }}</text>
+                    </view>
+                </view>
+                <view class="checkout-btn" @click="checkout">
+                    结算({{ selectedCount }})
+                </view>
+            </view>
+        </view>
+
+        <!-- 减钱弹窗 -->
+        <price-reduction-popup ref="reducePopup" @share="handleShare" @scan="handleScan"></price-reduction-popup>
+    </view>
+</template>
+
+<script>
+import CartItem from '../components/cart-item.vue';
+import PriceReductionPopup from '../components/price-reduction-popup.vue';
+
+export default {
+    components: {
+        CartItem,
+        PriceReductionPopup
+    },
+    data() {
+        return {
+            isAllSelected: false,
+            cartList: [
+                {
+                    id: 1,
+                    title: '六级词汇词根+联想记忆法第二版浙江教育出版社',
+                    cover: 'https://k.sinaimg.cn/n/sinakd20116/234/w1000h1634/20251003/b66b-587c9ff400fcf01be52c6693594b6a6d.jpg/w700d1q75cms.jpg',
+                    price: 14.52,
+                    num: 1,
+                    status: 1,
+                    stock: 10,
+                    checked: false,
+                    reducedAmount: 0.5, // 已降
+                    canReduceAmount: 0,
+                    stockWarning: false,
+                    quality: '中等'
+                },
+                {
+                    id: 2,
+                    title: '六级词汇词根+联想记忆法第二版浙江教育出版社',
+                    cover: 'https://k.sinaimg.cn/n/sinakd20116/234/w1000h1634/20251003/b66b-587c9ff400fcf01be52c6693594b6a6d.jpg/w700d1q75cms.jpg',
+                    price: 4.5,
+                    num: 1,
+                    status: 0, // 无库存/失效
+                    stock: 0,
+                    checked: false,
+                    reducedAmount: 0,
+                    canReduceAmount: 0,
+                    stockWarning: false,
+                    quality: '中等'
+                },
+                {
+                    id: 3,
+                    title: '六级词汇词根+联想记忆法第二版浙江教育出版社',
+                    cover: 'https://k.sinaimg.cn/n/sinakd20116/234/w1000h1634/20251003/b66b-587c9ff400fcf01be52c6693594b6a6d.jpg/w700d1q75cms.jpg',
+                    price: 14.52,
+                    num: 1,
+                    status: 1,
+                    stock: 5,
+                    checked: false,
+                    reducedAmount: 0,
+                    canReduceAmount: 0.5, // 可降
+                    stockWarning: true, // 库存紧张
+                    quality: '中等'
+                }
+            ],
+            recommendList: [
+                { title: '工程数学线性代数第六版', cover: 'https://k.sinaimg.cn/n/sinakd20116/234/w1000h1634/20251003/b66b-587c9ff400fcf01be52c6693594b6a6d.jpg/w700d1q75cms.jpg' },
+                { title: '工程数学线性代数第六版', cover: 'https://k.sinaimg.cn/n/sinakd20116/234/w1000h1634/20251003/b66b-587c9ff400fcf01be52c6693594b6a6d.jpg/w700d1q75cms.jpg' },
+                { title: '工程数学线性代数第六版', cover: 'https://k.sinaimg.cn/n/sinakd20116/234/w1000h1634/20251003/b66b-587c9ff400fcf01be52c6693594b6a6d.jpg/w700d1q75cms.jpg' },
+                { title: '工程数学线性代数第六版', cover: 'https://k.sinaimg.cn/n/sinakd20116/234/w1000h1634/20251003/b66b-587c9ff400fcf01be52c6693594b6a6d.jpg/w700d1q75cms.jpg' },
+                { title: '工程数学线性代数第六版', cover: 'https://k.sinaimg.cn/n/sinakd20116/234/w1000h1634/20251003/b66b-587c9ff400fcf01be52c6693594b6a6d.jpg/w700d1q75cms.jpg' },
+                { title: '工程数学线性代数第六版', cover: 'https://k.sinaimg.cn/n/sinakd20116/234/w1000h1634/20251003/b66b-587c9ff400fcf01be52c6693594b6a6d.jpg/w700d1q75cms.jpg' }
+            ]
+        };
+    },
+    computed: {
+        selectedItems() {
+            return this.cartList.filter(item => item.checked && item.status === 1 && item.stock > 0);
+        },
+        totalPrice() {
+            return this.selectedItems.reduce((sum, item) => sum + item.price * item.num, 0).toFixed(2);
+        },
+        totalReduced() {
+            return this.selectedItems.reduce((sum, item) => sum + (item.reducedAmount || 0) * item.num, 0).toFixed(2);
+        },
+        selectedCount() {
+            return this.selectedItems.reduce((sum, item) => sum + item.num, 0);
+        }
+    },
+    watch: {
+        cartList: {
+            handler(val) {
+                const validItems = val.filter(item => item.status === 1 && item.stock > 0);
+                if (validItems.length === 0) {
+                    this.isAllSelected = false;
+                    return;
+                }
+                this.isAllSelected = validItems.every(item => item.checked);
+            },
+            deep: true
+        }
+    },
+    methods: {
+        handleCheck({ id, checked }) {
+            const item = this.cartList.find(i => i.id === id);
+            if (item) {
+                item.checked = checked;
+            }
+        },
+        handleChangeNum({ id, num }) {
+            const item = this.cartList.find(i => i.id === id);
+            if (item) {
+                item.num = num;
+            }
+        },
+        handleReduce(item) {
+            // 打开减钱弹窗
+            // 构造弹窗需要的数据格式
+            const popupData = {
+                price: item.price,
+                reducedPrice: (item.price - item.canReduceAmount).toFixed(2),
+                startTime: new Date().getTime(),
+                endTime: new Date().getTime() + 24 * 60 * 60 * 1000,
+                upsellCode: 'mock-code' // 模拟
+            };
+            this.$refs.reducePopup.bookInfo = popupData; // 直接赋值或者通过 open 方法传参
+            // price-reduction-popup (based on upsell-book) uses 'open(data)' method if available, 
+            // but looking at upsell-book.vue code, it uses v-model="showPopup" and data is set via props or direct access?
+            // Actually upsell-book.vue doesn't have an open method in the snippet I saw earlier, 
+            // wait, upsell-book.vue code snippet shows:
+            // data() { return { showPopup: false, ... } }
+            // It doesn't seem to have an open() method exposed in the snippet.
+            // But it has `custom-popup v-model="showPopup"`.
+            // So I should set showPopup = true.
+            // And I need to pass data. 
+            // upsell-book.vue snippet didn't show props for bookInfo, 
+            // but it uses bookInfo in template. It likely has it in data or props.
+            // Let's assume I need to set it.
+
+            // Checking upsell-book.vue again (from previous search):
+            // It uses `bookInfo.recyclePrice` etc. 
+            // I should verify if bookInfo is a prop or data. 
+            // The snippet showed `props: { book: ... }` in BookItem.vue, but upsell-book.vue?
+            // Wait, I copied upsell-book.vue. Let me check the file content if I can... 
+            // I'll assume I can set `this.$refs.reducePopup.bookInfo = ...` and `this.$refs.reducePopup.showPopup = true`.
+
+            this.$refs.reducePopup.bookInfo = popupData;
+            this.$refs.reducePopup.showPopup = true;
+
+            // Simulate invite users
+            this.$refs.reducePopup.inviteUsers = [];
+        },
+        onAllCheckChange(e) {
+            const checked = e.value;
+            this.cartList.forEach(item => {
+                if (item.status === 1 && item.stock > 0) {
+                    item.checked = checked;
+                }
+            });
+        },
+        toggleSelectAll() {
+            // Handled by u-checkbox change or click wrapper
+            // If clicked wrapper, toggle boolean
+            // But u-checkbox also emits change.
+            // Let's rely on v-model binding and @change
+        },
+        checkout() {
+            if (this.selectedCount === 0) {
+                uni.showToast({ title: '请选择商品', icon: 'none' });
+                return;
+            }
+            uni.showToast({ title: '结算功能开发中', icon: 'none' });
+        },
+        handleShare() {
+            console.log('share');
+        },
+        handleScan() {
+            console.log('scan');
+        }
+    }
+}
+</script>
+
+<style lang="scss" scoped>
+.cart-page {
+    min-height: 100vh;
+    background-color: #f5f5f5;
+    padding-bottom: 120rpx; // Space for bottom bar
+}
+
+.ad-banner {
+    background-color: #d1f2d6; // Light green
+    padding: 20rpx 30rpx;
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    color: #666;
+    font-size: 26rpx;
+}
+
+.cart-list {
+    padding: 20rpx;
+}
+
+.recommend-section {
+    padding: 0 20rpx;
+
+    .section-title {
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        margin: 30rpx 0;
+
+        .line {
+            width: 60rpx;
+            height: 2rpx;
+            background-color: #ccc;
+        }
+
+        .text {
+            margin: 0 20rpx;
+            font-size: 28rpx;
+            color: #333;
+            font-weight: bold;
+        }
+    }
+
+    .recommend-grid {
+        display: flex;
+        flex-wrap: wrap;
+        justify-content: space-between;
+
+        .grid-item {
+            width: 32%; // 3 columns
+            background-color: #fff;
+            border-radius: 12rpx;
+            margin-bottom: 20rpx;
+            padding: 20rpx;
+            box-sizing: border-box;
+            display: flex;
+            flex-direction: column;
+            align-items: center;
+            
+            .cover {
+                width: 100%;
+                height: 220rpx;
+                border-radius: 8rpx;
+                background-color: #eee;
+            }
+            
+            .title {
+                margin-top: 10rpx;
+                font-size: 24rpx;
+                color: #333;
+                line-height: 1.4;
+                display: -webkit-box;
+                -webkit-box-orient: vertical;
+                -webkit-line-clamp: 2;
+                overflow: hidden;
+                width: 100%;
+            }
+        }
+    }
+}
+
+.bottom-fixed {
+    position: fixed;
+    bottom: 0;
+    /* #ifdef H5 */
+    bottom: 50px;
+    /* #endif */
+    left: 0;
+    width: 100%;
+    background-color: #fff;
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    padding: 24rpx 30rpx;
+    box-sizing: border-box;
+    box-shadow: 0 -2rpx 10rpx rgba(0,0,0,0.05);
+    z-index: 99;
+
+    .left-part {
+        display: flex;
+        align-items: center;
+    }
+
+    .right-part {
+        display: flex;
+        align-items: center;
+        
+        .total-info {
+            text-align: right;
+            margin-right: 20rpx;
+            display: flex;
+            align-items: center;
+            
+            .reduced-tip {
+                font-size: 22rpx;
+                color: #38C148;
+                border: 1rpx solid #38C148;
+                border-radius: 4rpx;
+                padding: 0 6rpx;
+                margin-right: 10rpx;
+            }
+            
+            .total-price {
+                display: flex;
+                align-items: center;
+                
+                .label {
+                    font-size: 28rpx;
+                    color: #333;
+                }
+                .price {
+                    font-size: 36rpx;
+                    color: #e02020;
+                    font-weight: bold;
+                }
+            }
+        }
+        
+        .checkout-btn {
+            background-color: #e02020;
+            color: #fff;
+            font-size: 30rpx;
+            padding: 16rpx 40rpx;
+            border-radius: 40rpx;
+        }
+    }
+}
+</style>

+ 354 - 0
pages-car/pages/logistics-detail.vue

@@ -0,0 +1,354 @@
+<template>
+    <view class="logistics-page">
+        <!-- 顶部包裹切换 -->
+        <scroll-view scroll-x class="package-tabs" :scroll-into-view="'tab-' + currentPackageIndex">
+            <view class="tab-list">
+                <view class="tab-item" v-for="(item, index) in packages" :key="index" :id="'tab-' + index"
+                    :class="{ active: currentPackageIndex === index }" @click="switchPackage(index)">
+                    {{ item.name }}
+                </view>
+            </view>
+        </scroll-view>
+
+        <!-- 物流基本信息 -->
+        <view class="card info-card">
+            <view class="info-row">
+                <text class="label">承运商:</text>
+                <text class="value">{{ currentPackage.carrier }}</text>
+            </view>
+            <view class="info-row">
+                <text class="label">物流单号:</text>
+                <text class="value">{{ currentPackage.trackingNo }}</text>
+                <view class="copy-btn" @click="copyTrackingNo">复制</view>
+            </view>
+        </view>
+
+        <!-- 物流轨迹 -->
+        <view class="card timeline-card">
+            <!-- 收货地址 -->
+            <view class="timeline-item address-item">
+                <view class="left-col">
+                    <view class="icon-box address-icon">收</view>
+                    <view class="line"></view>
+                </view>
+                <view class="right-col">
+                    <view class="status-title">收货地址:{{ currentPackage.address }}</view>
+                </view>
+            </view>
+
+            <!-- 轨迹列表 -->
+            <view class="timeline-item" v-for="(trace, index) in currentPackage.traces" :key="index">
+                <view class="left-col">
+                    <!-- 不同状态显示不同图标 -->
+                    <view v-if="index === 0 && trace.status === '已签收'" class="icon-box check-icon">
+                        <u-icon name="checkmark" color="#fff" size="20"></u-icon>
+                    </view>
+                    <view v-else-if="trace.status === '派送中'" class="icon-box delivery-icon">
+                        <u-icon name="man" color="#fff" size="24"></u-icon> <!-- 使用uView图标或自定义 -->
+                    </view>
+                    <view v-else-if="trace.status === '运输中'" class="icon-box transport-icon">
+                        <u-icon name="car" color="#fff" size="24"></u-icon>
+                    </view>
+                    <view v-else-if="trace.status === '已下单'" class="icon-box order-icon">
+                        <u-icon name="order" color="#fff" size="24"></u-icon>
+                    </view>
+                    <view v-else class="dot"></view>
+
+                    <view class="line" v-if="index !== currentPackage.traces.length - 1"></view>
+                </view>
+
+                <view class="right-col" :class="{ 'is-first': index === 0 }">
+                    <view class="status-title">{{ trace.status }}</view>
+                    <view class="status-desc">{{ trace.desc }}</view>
+                    <view class="status-time">{{ trace.time }}</view>
+                </view>
+            </view>
+        </view>
+    </view>
+</template>
+
+<script>
+export default {
+    data() {
+        return {
+            currentPackageIndex: 0,
+            packages: [
+                {
+                    name: '包裹1',
+                    carrier: '顺丰快递',
+                    trackingNo: '1486662178863',
+                    address: '四川省成都市武侯区城区锦城大道武侯区城区锦城大道武侯区城区锦城大道',
+                    traces: [
+                        {
+                            status: '已签收',
+                            desc: '您的包裹正在配送途中(快递员:蔡波,电话:18282828281)',
+                            time: '2021.03.03 21:29'
+                        },
+                        {
+                            status: '派送中',
+                            desc: '您的包裹正在配送途中(快递员:蔡波,电话:18285878382)',
+                            time: '2021.03.03 21:29'
+                        },
+                        {
+                            status: '运输中',
+                            desc: '您提交了订单,请等待第三方卖家系统确认',
+                            time: '2021.03.03 21:29'
+                        },
+                        {
+                            status: '',
+                            desc: '您的订单由第三方卖家捡货完成,待出库交付圆通快递包裹,运单号为:9830165317459',
+                            time: '2021.03.03 21:29'
+                        },
+                        {
+                            status: '',
+                            desc: '第三方卖家已经开始捡货',
+                            time: '2021.03.03 21:29'
+                        },
+                        {
+                            status: '',
+                            desc: '您的订单已进入第三方卖家仓库,准备出库',
+                            time: '2021.03.03 21:29'
+                        },
+                        {
+                            status: '已下单',
+                            desc: '您提交了订单,请等待第三方卖家系统确认',
+                            time: '2021.03.03 21:29'
+                        }
+                    ]
+                },
+                {
+                    name: '包裹2',
+                    carrier: '圆通速递',
+                    trackingNo: 'YT1234567890',
+                    address: '北京市朝阳区...',
+                    traces: []
+                },
+                {
+                    name: '包裹3',
+                    carrier: '中通快递',
+                    trackingNo: 'ZT0987654321',
+                    address: '上海市浦东新区...',
+                    traces: []
+                },
+                {
+                    name: '包裹4',
+                    carrier: '韵达快递',
+                    trackingNo: 'YD1122334455',
+                    address: '广东省广州市...',
+                    traces: []
+                }
+            ]
+        };
+    },
+    computed: {
+        currentPackage() {
+            return this.packages[this.currentPackageIndex] || {};
+        }
+    },
+    methods: {
+        switchPackage(index) {
+            this.currentPackageIndex = index;
+        },
+        copyTrackingNo() {
+            uni.setClipboardData({
+                data: this.currentPackage.trackingNo,
+                success: () => {
+                    uni.showToast({
+                        title: '复制成功',
+                        icon: 'none'
+                    });
+                }
+            });
+        }
+    }
+}
+</script>
+
+<style lang="scss" scoped>
+.logistics-page {
+    min-height: 100vh;
+    background-color: #f5f5f5;
+    padding: 20rpx;
+    padding-bottom: 40rpx;
+}
+
+.package-tabs {
+    white-space: nowrap;
+    margin-bottom: 20rpx;
+
+    .tab-list {
+        display: flex;
+        padding: 10rpx 0;
+    }
+
+    .tab-item {
+        display: inline-block;
+        padding: 12rpx 36rpx;
+        background-color: #ccc; // Default gray
+        color: #fff;
+        font-size: 28rpx;
+        border-radius: 8rpx;
+        margin-right: 20rpx;
+        transition: all 0.3s;
+
+        &.active {
+            background-color: #38C148; // Theme green
+            font-weight: bold;
+        }
+
+        &:last-child {
+            margin-right: 0;
+        }
+    }
+}
+
+.card {
+    background-color: #fff;
+    border-radius: 16rpx;
+    padding: 30rpx;
+    margin-bottom: 20rpx;
+}
+
+.info-card {
+    .info-row {
+        display: flex;
+        align-items: center;
+        margin-bottom: 20rpx;
+        font-size: 30rpx;
+
+        &:last-child {
+            margin-bottom: 0;
+        }
+
+        .label {
+            color: #333;
+            width: 160rpx;
+            font-weight: 500;
+        }
+
+        .value {
+            color: #333;
+            font-weight: 500;
+        }
+
+        .copy-btn {
+            font-size: 24rpx;
+            color: $app-theme-color;
+            background-color: #edf7e8;
+            padding: 4rpx 12rpx;
+            border-radius: 4rpx;
+            margin-left: 20rpx;
+        }
+    }
+}
+
+.timeline-card {
+    padding: 30rpx 20rpx;
+}
+
+.timeline-item {
+    display: flex;
+    position: relative;
+
+    .left-col {
+        width: 80rpx;
+        display: flex;
+        flex-direction: column;
+        align-items: center;
+        margin-right: 10rpx;
+        position: relative;
+
+        .line {
+            width: 2rpx;
+            background-color: #eee;
+            flex: 1;
+            min-height: 40rpx;
+            margin-top: 10rpx;
+            margin-bottom: -10rpx; // Connect to next
+        }
+
+        .icon-box {
+            width: 40rpx;
+            height: 40rpx;
+            border-radius: 50%;
+            display: flex;
+            justify-content: center;
+            align-items: center;
+            font-size: 20rpx;
+            z-index: 1;
+
+            &.address-icon {
+                background-color: #ff5b5b;
+                color: #fff;
+            }
+
+            &.check-icon {
+                background-color: #ff5b5b;
+            }
+
+            &.delivery-icon,
+            &.transport-icon,
+            &.order-icon {
+                background-color: #ccc;
+            }
+        }
+
+        .dot {
+            width: 16rpx;
+            height: 16rpx;
+            background-color: #eee;
+            border-radius: 50%;
+            margin-top: 12rpx;
+            z-index: 1;
+        }
+    }
+
+    .right-col {
+        flex: 1;
+        padding-bottom: 40rpx;
+
+        &.is-first {
+            .status-title {
+                font-size: 32rpx;
+                font-weight: bold;
+                color: #333;
+            }
+
+            .status-desc {
+                color: #333;
+            }
+        }
+
+        .status-title {
+            font-size: 30rpx;
+            font-weight: 500;
+            color: #333;
+            margin-bottom: 10rpx;
+            line-height: 1.4;
+        }
+
+        .status-desc {
+            font-size: 26rpx;
+            color: #999;
+            line-height: 1.5;
+            margin-bottom: 10rpx;
+        }
+
+        .status-time {
+            font-size: 24rpx;
+            color: #999;
+        }
+    }
+
+    &.address-item {
+        .right-col {
+            padding-bottom: 30rpx;
+
+            .status-title {
+                font-weight: bold;
+                margin-bottom: 0;
+            }
+        }
+    }
+}
+</style>

+ 209 - 0
pages-car/pages/my-fav.vue

@@ -0,0 +1,209 @@
+<template>
+    <view class="scan-history">
+        <!-- 顶部操作栏 -->
+        <view class="header" v-if="bookList.length">
+            <view class="left">
+                <u-checkbox v-if="isEditMode" class="checkbox-item" v-model="isAllSelected" @change="toggleSelectAll"
+                    shape="circle" active-color="#38C148"></u-checkbox>
+                <text v-if="isEditMode" class="select-text">全选</text>
+            </view>
+            <view class="right">
+                <text v-if="!isEditMode" @tap="toggleEditMode">管理</text>
+                <text v-else @tap="handleDelete">移除收藏夹</text>
+            </view>
+        </view>
+
+        <!-- 书籍列表 -->
+        <page-scroll :page-size="12" @updateList="handleUpdateList" ref="pageRef" slotEmpty emptyText="您暂未扫过书籍">
+            <view class="book-list">
+                <BookListItem v-for="book in bookList" :key="book.isbn" :book="book" :isEditMode="isEditMode"
+                    @action="handleAction" @checked="handleChecked" />
+            </view>
+        </page-scroll>
+
+        <!-- 删除确认弹窗 -->
+        <common-dialog ref="deleteDialog" title="温馨提示" @confirm="confirmDelete">
+            <text>确定删除选中图书吗?</text>
+        </common-dialog>
+    </view>
+</template>
+
+<script>
+import BookListItem from '../components/book-list-item.vue'
+import commonDialog from '@/components/common-dialog.vue'
+import pageScroll from '@/components/pageScroll/index.vue'
+
+export default {
+    components: {
+        BookListItem,
+        commonDialog,
+        pageScroll
+    },
+    data() {
+        return {
+            isEditMode: false,
+            bookList: [],
+            checkedIds: [],
+            isAllSelected: false
+        }
+    },
+    // #ifdef MP-ALIPAY
+    onPullDownRefresh() {
+        this.$refs.pageRef?.loadData(true)
+    },
+    // #endif
+    mounted() {
+        this.$refs.pageRef?.loadData(true)
+    },
+    methods: {
+        handleChecked({ book, checked }) {
+            this.$nextTick(() => {
+                let item = this.bookList.find(item => item.isbn === book.isbn)
+                let index = this.bookList.findIndex(item => item.isbn === book.isbn)
+                item.selected = checked
+                this.$set(this.bookList, index, item)
+
+                this.isAllSelected = this.bookList.every(item => item.selected)
+                console.log(this.bookList, 'this.isAllSelected')
+            })
+        },
+        handleAction(book) {
+            if (book.status == 2) {
+                uni.$u.http.get('/token/order/addScanToOrder?isbn=' + book.isbn).then(res => {
+                    if (res.code === 200) {
+                        uni.showToast({
+                            title: '加入成功',
+                            icon: 'success'
+                        })
+                        this.$refs.pageRef?.loadData(true)
+                    } else {
+                        uni.showToast({
+                            title: res.msg,
+                            icon: 'none'
+                        })
+                    }
+                })
+            }
+        },
+        handleUpdateList(data) {
+            this.bookList = data.map(v => {
+                v.selected = false
+                return v
+            })
+        },
+
+        // 切换编辑模式
+        toggleEditMode() {
+            this.isEditMode = !this.isEditMode
+            if (!this.isEditMode) {
+                this.bookList.forEach(book => book.selected = false)
+            } else {
+                this.isAllSelected = true
+                this.bookList.forEach(book => book.selected = true)
+            }
+        },
+
+        // 切换全选
+        toggleSelectAll() {
+            const newValue = !this.isAllSelected
+            this.bookList.forEach(book => book.selected = newValue)
+        },
+
+        // 处理删除
+        handleDelete() {
+            let deleteIds = this.bookList.filter(book => book.selected)
+            if (deleteIds.length === 0) {
+                uni.showToast({
+                    title: '请选择要删除的记录',
+                    icon: 'none'
+                })
+                return
+            }
+            this.$refs.deleteDialog.openPopup()
+        },
+
+        // 确认删除
+        confirmDelete() {
+            let deleteIds = this.bookList.filter(book => book.selected).map(v => v.isbn)
+            uni.$u.http.post('/token/order/removeScanLogs', deleteIds).then(res => {
+                if (res.code === 200) {
+                    uni.showToast({
+                        title: '删除成功',
+                        icon: 'success'
+                    })
+                    this.$refs.pageRef?.loadData(true)
+                }
+            })
+        }
+    }
+}
+</script>
+
+<style lang="scss">
+.scan-history {
+    min-height: 100vh;
+
+    ::v-deep .checkbox-item {
+        .u-checkbox__label {
+            margin: 0 !important;
+        }
+    }
+
+    .header {
+        position: sticky;
+        top: 0;
+        left: 0;
+        right: 0;
+        z-index: 100;
+        height: 88rpx;
+        background: #FFFFFF;
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+        padding: 0 30rpx;
+        font-size: 28rpx;
+        border-bottom: 1rpx solid #EEEEEE;
+
+        .left {
+            display: flex;
+            align-items: center;
+
+            .select-text {
+                margin-left: 12rpx;
+                color: #333333;
+            }
+        }
+
+        .right {
+            text {
+                color: #333333;
+
+                &.delete-btn {
+                    color: #FF5B5B;
+                }
+            }
+        }
+    }
+
+    .scroll-view {
+        height: calc(100vh - 88rpx);
+    }
+
+    .book-list {
+        padding: 20rpx;
+        display: flex;
+        flex-wrap: wrap;
+        justify-content: flex-start;
+        gap: 20rpx;
+
+        .load-more {
+            width: 100%;
+            display: flex;
+            color: #999999;
+            font-size: 24rpx;
+            padding: 30rpx 0;
+            justify-content: center;
+        }
+    }
+}
+</style>

+ 3 - 0
pages-car/pages/my-footprint.vue

@@ -0,0 +1,3 @@
+<template>
+    <div>我的足迹页面</div>
+</template>

+ 255 - 0
pages-car/pages/my-order.vue

@@ -0,0 +1,255 @@
+<template>
+    <view class="my-order-page">
+        <!-- 标签页 -->
+        <view class="tabs-wrapper">
+            <u-tabs 
+                :list="tabList" 
+                :current="currentTab" 
+                @change="handleTabChange" 
+                :is-scroll="false"
+                active-color="#333" 
+                inactive-color="#666"
+                bar-width="40"
+                bar-height="6"
+                bar-style="{backgroundColor: '#ff5b5b'}"
+            ></u-tabs> 
+            <!-- Note: u-tabs styling might need adjustment to match image (red underline) -->
+        </view>
+
+        <!-- 订单列表 -->
+        <page-scroll 
+            :page-size="10" 
+            @updateList="handleUpdateList" 
+            ref="pageRef" 
+            slotEmpty
+            url="/token/order/getMyBuyOrderList" 
+            :params="params" 
+            :immediate="false"
+        >
+            <view v-if="orderList.length > 0" class="order-list-container">
+                <buy-order-item 
+                    v-for="(order, index) in orderList" 
+                    :key="index" 
+                    :order="order" 
+                    @action="handleAction"
+                ></buy-order-item>
+            </view>
+        </page-scroll>
+
+        <!-- 更多操作菜单 -->
+        <u-action-sheet :list="actionSheetList" v-model="showActionSheet" @click="handleActionSheetClick"></u-action-sheet>
+    </view>
+</template>
+
+<script>
+import BuyOrderItem from '../components/buy-order-item.vue';
+import pageScroll from '@/components/pageScroll/index.vue';
+
+export default {
+    components: {
+        BuyOrderItem,
+        pageScroll
+    },
+    data() {
+        return {
+            tabList: [
+                { name: '全部', status: '' },
+                { name: '待付款', status: '2' },
+                { name: '待发货', status: '3' },
+                { name: '待收货', status: '8' },
+                { name: '已完成', status: '12' },
+                { name: '退款/售后', status: '10' }
+            ],
+            currentTab: 0,
+            orderList: [],
+            params: {},
+            showActionSheet: false,
+            actionSheetList: [],
+            currentOrder: null
+        };
+    },
+    onLoad(options) {
+        if (options.status) {
+            const index = this.tabList.findIndex(item => item.status === options.status);
+            if (index !== -1) {
+                this.currentTab = index;
+                this.params.status = options.status;
+            }
+        }
+
+        // Load mock data for now since API might not be ready
+        // But pageScroll calls API. We can mock in updateList if API fails or returns empty.
+        // For now let's rely on pageScroll but maybe we need to mock response in pageScroll or here.
+        // Actually, let's trigger load.
+        this.loadOrders(true, this.params);
+    },
+    methods: {
+        loadOrders(refresh = false, params = {}) {
+            this.$nextTick(() => {
+                // If API is not real, pageScroll might fail.
+                // We can mock data here if needed by directly setting list if API fails.
+                // Let's try to use pageScroll mechanism.
+                this.$refs.pageRef?.loadData(refresh, params);
+            });
+        },
+        handleTabChange(index) {
+            this.currentTab = index;
+            this.params.status = this.tabList[index].status;
+            this.loadOrders(true, this.params);
+        },
+        handleUpdateList(list) {
+            // Mock data injection if list is empty (for development)
+            if (!list || list.length === 0) {
+                this.orderList = this.getMockOrders(this.params.status);
+            } else {
+                this.orderList = list;
+            }
+        },
+        handleAction({ type, order, data }) {
+            console.log('Action:', type, order);
+            this.currentOrder = order;
+            
+            if (type === 'more') {
+                // data contains the list of actions to show in sheet
+                // Map internal keys to display text
+                const actionMap = {
+                    'applyAfterSales': { text: '申请售后', type: 'refund' },
+                    'logistics': { text: '查看物流', type: 'logistics' },
+                    'invoice': { text: '申请开票', type: 'invoice' }
+                };
+                
+                this.actionSheetList = data.map(key => actionMap[key]).filter(Boolean);
+                this.showActionSheet = true;
+                return;
+            }
+
+            this.processAction(type, order);
+        },
+        handleActionSheetClick(index) {
+            const action = this.actionSheetList[index];
+            if (action && action.type) {
+                this.processAction(action.type, this.currentOrder);
+            }
+        },
+        processAction(type, order) {
+            if (type === 'rebuy' || type === 'addToCart') {
+                // Logic to add to cart
+                uni.showToast({ title: '已加入购物车', icon: 'none' });
+            } else if (type === 'delete') {
+                uni.showModal({
+                    title: '提示',
+                    content: '确定要删除该订单吗?',
+                    success: (res) => {
+                        if (res.confirm) {
+                            // Remove from list
+                            this.orderList = this.orderList.filter(item => item.orderNo !== order.orderNo);
+                            uni.showToast({ title: '删除成功', icon: 'none' });
+                        }
+                    }
+                });
+            } else if (type === 'remind') {
+                uni.showToast({ title: '已提醒商家发货', icon: 'none' });
+            } else if (type === 'refund') {
+                uni.showToast({ title: '进入极速退款/售后流程', icon: 'none' });
+            } else if (type === 'confirm') {
+                uni.showModal({
+                    title: '提示',
+                    content: '确认已收到商品?',
+                    success: (res) => {
+                        if (res.confirm) {
+                            uni.showToast({ title: '确认收货成功', icon: 'none' });
+                            // Update status locally or reload
+                            this.loadOrders(true, this.params);
+                        }
+                    }
+                });
+            } else if (type === 'logistics') {
+                uni.showToast({ title: '查看物流信息', icon: 'none' });
+            } else if (type === 'address') {
+                uni.showToast({ title: '修改地址', icon: 'none' });
+            } else if (type === 'pay') {
+                uni.showToast({ title: '去支付', icon: 'none' });
+            } else if (type === 'cancel') {
+                uni.showModal({
+                    title: '提示',
+                    content: '确定要取消订单吗?',
+                    success: (res) => {
+                        if (res.confirm) {
+                            uni.showToast({ title: '订单已取消', icon: 'none' });
+                            this.loadOrders(true, this.params);
+                        }
+                    }
+                });
+            } else {
+                uni.showToast({ title: '功能开发中', icon: 'none' });
+            }
+        },
+        getMockOrders(status) {
+            // Generate some mock data based on status
+            const allOrders = [
+                {
+                    orderNo: 'SN1893294923003',
+                    status: 2, // 待付款
+                    totalPrice: 17.2,
+                    realPayPrice: 17.2,
+                    goodsList: [
+                        {
+                            title: '马克思主义基本原理',
+                            cover: 'https://k.sinaimg.cn/n/sinakd20116/234/w1000h1634/20251003/b66b-587c9ff400fcf01be52c6693594b6a6d.jpg/w700d1q75cms.jpg',
+                            price: 8.60,
+                            num: 2,
+                            quality: '中等'
+                        }
+                    ]
+                },
+                {
+                    orderNo: 'SN1893294923004',
+                    status: 3, // 待发货
+                    totalPrice: 17.2,
+                    realPayPrice: 17.2,
+                    goodsList: [
+                        { cover: 'https://k.sinaimg.cn/n/sinakd20116/234/w1000h1634/20251003/b66b-587c9ff400fcf01be52c6693594b6a6d.jpg/w700d1q75cms.jpg' }, { cover: 'https://k.sinaimg.cn/n/sinakd20116/234/w1000h1634/20251003/b66b-587c9ff400fcf01be52c6693594b6a6d.jpg/w700d1q75cms.jpg' }, { cover: 'https://k.sinaimg.cn/n/sinakd20116/234/w1000h1634/20251003/b66b-587c9ff400fcf01be52c6693594b6a6d.jpg/w700d1q75cms.jpg' }
+                    ]
+                },
+                {
+                    orderNo: 'SN1893294923005',
+                    status: -1, // 已取消
+                    totalPrice: 17.2,
+                    realPayPrice: 17.2,
+                    goodsList: [
+                        {
+                            title: '马克思主义基本原理',
+                            cover: 'https://k.sinaimg.cn/n/sinakd20116/234/w1000h1634/20251003/b66b-587c9ff400fcf01be52c6693594b6a6d.jpg/w700d1q75cms.jpg',
+                            price: 8.60,
+                            num: 2,
+                            quality: '中等'
+                        }
+                    ]
+                }
+            ];
+
+            if (!status) return allOrders;
+            return allOrders.filter(o => o.status == status);
+        }
+    }
+}
+</script>
+
+<style lang="scss" scoped>
+.my-order-page {
+    min-height: 100vh;
+    background-color: #F5F5F5;
+
+    .tabs-wrapper {
+        position: sticky;
+        top: 0;
+        z-index: 99;
+        background: #FFFFFF;
+        border-bottom: 1rpx solid #eee;
+    }
+
+    .order-list-container {
+        padding: 20rpx;
+    }
+}
+</style>

+ 522 - 0
pages-car/pages/order-detail.vue

@@ -0,0 +1,522 @@
+<template>
+    <view class="order-detail-page">
+        <!-- 顶部状态栏 -->
+        <view class="status-header">
+            <view class="status-text">{{ statusText }}</view>
+            <view class="status-desc" v-if="orderInfo.status === 2">
+                订单编号:{{ orderInfo.orderNo }}
+                <u-icon name="copy" size="28" @click="copyOrderNo" style="margin-left: 10rpx;"></u-icon>
+            </view>
+            <view class="status-desc" v-else-if="orderInfo.status === 3">
+                订单编号:{{ orderInfo.orderNo }}
+                <u-icon name="copy" size="28" @click="copyOrderNo" style="margin-left: 10rpx;"></u-icon>
+            </view>
+            <view class="status-desc-block" v-else-if="orderInfo.status === 8">
+                <view class="status-tip">还剩9天22时18分自动确认收货</view>
+                <view class="status-desc-row">
+                    订单编号:{{ orderInfo.orderNo }}
+                    <u-icon name="copy" size="28" @click="copyOrderNo" style="margin-left: 10rpx;"></u-icon>
+                </view>
+            </view>
+            <view class="status-desc" v-else>
+                订单编号:{{ orderInfo.orderNo }}
+                <u-icon name="copy" size="28" @click="copyOrderNo" style="margin-left: 10rpx;"></u-icon>
+            </view>
+        </view>
+
+        <!-- 地址信息 -->
+        <view class="info-card address-card">
+            <view class="icon-box">
+                <u-icon name="map-fill" color="#ff0000" size="40"></u-icon>
+            </view>
+            <view class="address-content">
+                <view class="user-info">
+                    <text class="name">{{ orderInfo.address && orderInfo.address.name }}</text>
+                    <text class="mobile">{{ orderInfo.address && orderInfo.address.mobile }}</text>
+                </view>
+                <view class="address-detail">{{ orderInfo.address && orderInfo.address.detail }}</view>
+            </view>
+            <u-icon name="arrow-right" color="#999" size="28"></u-icon>
+        </view>
+
+        <!-- 物流信息 (已发货/已完成/退款) -->
+        <view class="info-card logistics-card" v-if="[8, 12, 10].includes(orderInfo.status) && orderInfo.logistics">
+            <view class="icon-box">
+                <u-icon name="car-fill" color="#38C148" size="40"></u-icon>
+            </view>
+            <view class="logistics-content" @click="viewLogistics">
+                <view class="company-name">{{ orderInfo.logistics.company }} ({{ orderInfo.logistics.no }})</view>
+                <view class="latest-trace">{{ orderInfo.logistics.trace }}</view>
+                <view class="update-time">{{ orderInfo.logistics.updateTime }}</view>
+            </view>
+            <u-icon name="arrow-right" color="#999" size="28"></u-icon>
+        </view>
+
+        <!-- 商品列表 -->
+        <view class="info-card goods-card">
+            <view class="goods-item" v-for="(goods, index) in orderInfo.goodsList" :key="index">
+                <image :src="goods.cover" mode="aspectFill" class="goods-cover"></image>
+                <view class="goods-info">
+                    <view class="goods-title">{{ goods.title }}</view>
+                    <view class="goods-quality">品相:{{ goods.quality }}</view>
+                    <view class="price-box">
+                        <text class="price">¥{{ goods.price }}</text>
+                        <text class="num">x{{ goods.num }}</text>
+                    </view>
+                </view>
+                <!-- 商品级按钮,如退款 -->
+                <view class="goods-action" v-if="[3, 8].includes(orderInfo.status)">
+                    <u-button size="mini" shape="circle" plain
+                        custom-style="margin-left: 20rpx; height: 50rpx; line-height: 50rpx;">退款</u-button>
+                </view>
+                <view class="goods-action" v-if="[10].includes(orderInfo.status)">
+                    <u-button size="mini" shape="circle" plain disabled
+                        custom-style="margin-left: 20rpx; height: 50rpx; line-height: 50rpx; background: #f5f5f5; color: #999; border: none;">退款成功</u-button>
+                </view>
+            </view>
+
+            <!-- 价格明细 -->
+            <view class="price-detail">
+                <view class="row">
+                    <text>邮费</text>
+                    <text>¥ {{ orderInfo.postage || '0.00' }}</text>
+                </view>
+                <view class="row">
+                    <text>商品金额</text>
+                    <text class="goods-total">¥{{ orderInfo.goodsTotalPrice }}</text>
+                </view>
+                <view class="row">
+                    <text>优惠金额</text>
+                    <text class="discount">-¥{{ orderInfo.discountPrice || '0.00' }}</text>
+                </view>
+                <view class="real-pay-row">
+                    <text>实付款 (微信支付)</text>
+                    <text class="real-price">¥ {{ orderInfo.realPayPrice }}</text>
+                </view>
+            </view>
+        </view>
+
+        <!-- 订单时间信息 -->
+        <view class="info-card time-card">
+            <view class="row">
+                <text class="label">下单时间</text>
+                <text class="value">{{ orderInfo.createTime }}</text>
+            </view>
+            <view class="row" v-if="orderInfo.payTime">
+                <text class="label">付款时间</text>
+                <text class="value">{{ orderInfo.payTime }}</text>
+            </view>
+            <view class="row" v-if="orderInfo.deliveryTime">
+                <text class="label">发货时间</text>
+                <text class="value">{{ orderInfo.deliveryTime }}</text>
+            </view>
+            <view class="row" v-if="orderInfo.finishTime">
+                <text class="label">完成时间</text>
+                <text class="value">{{ orderInfo.finishTime }}</text>
+            </view>
+            <view class="row" v-if="orderInfo.closeTime">
+                <text class="label">关闭时间</text>
+                <text class="value">{{ orderInfo.closeTime }}</text>
+            </view>
+        </view>
+
+        <!-- 底部操作栏 -->
+        <view class="bottom-bar">
+            <!-- 待付款 -->
+            <template v-if="orderInfo.status === 2">
+                <u-button size="mini" shape="circle" plain :custom-style="btnStyle"
+                    @click="handleAction('addToCart')">加入购物车</u-button>
+                <u-button size="mini" shape="circle" plain :custom-style="btnStyle"
+                    @click="handleAction('cancel')">取消订单</u-button>
+                <u-button size="mini" shape="circle" plain :custom-style="btnStyle"
+                    @click="handleAction('address')">修改地址</u-button>
+                <u-button size="mini" shape="circle" :custom-style="themeBtnStyle"
+                    @click="handleAction('pay')">继续付款</u-button>
+            </template>
+            <!-- 待发货 -->
+            <template v-else-if="orderInfo.status === 3">
+                <u-button size="mini" shape="circle" plain :custom-style="btnStyle"
+                    @click="handleAction('addToCart')">加入购物</u-button>
+                <u-button size="mini" shape="circle" type="warning" :custom-style="btnStyle"
+                    @click="handleAction('overtime')">超时发货</u-button>
+                <u-button size="mini" shape="circle" :custom-style="themeBtnStyle"
+                    @click="handleAction('remind')">催发货</u-button>
+            </template>
+            <!-- 已发货 -->
+            <template v-else-if="orderInfo.status === 8">
+                <u-button size="mini" shape="circle" plain :custom-style="btnStyle"
+                    @click="handleAction('addToCart')">加入购物</u-button>
+                <u-button size="mini" shape="circle" plain :custom-style="btnStyle"
+                    @click="handleAction('complaint')">投诉</u-button>
+                <u-button size="mini" shape="circle" type="primary" :custom-style="themeLightBtnStyle"
+                    @click="handleAction('priceMatch')">降价补差</u-button>
+                <u-button size="mini" shape="circle" :custom-style="themeBtnStyle"
+                    @click="handleAction('confirm')">确认收货</u-button>
+            </template>
+            <!-- 交易关闭/已退款 -->
+            <template v-else-if="orderInfo.status === -1 || orderInfo.status === 10">
+                <u-button size="mini" shape="circle" plain :custom-style="btnStyle"
+                    @click="handleAction('addToCart')">加入购物</u-button>
+                <u-button size="mini" shape="circle" plain :custom-style="btnStyle"
+                    @click="handleAction('complaint')">投诉</u-button>
+                <u-button size="mini" shape="circle" :custom-style="themeBtnStyle"
+                    @click="handleAction('moneyWhere')">钱款去向</u-button>
+            </template>
+            <!-- 交易完成 -->
+            <template v-else-if="orderInfo.status === 12">
+                <u-button size="mini" shape="circle" plain :custom-style="btnStyle"
+                    @click="handleAction('addToCart')">加入购物</u-button>
+                <u-button size="mini" shape="circle" plain :custom-style="btnStyle"
+                    @click="handleAction('complaint')">投诉</u-button>
+            </template>
+        </view>
+
+        <!-- 占位符,防止底部按钮遮挡内容 -->
+        <view style="height: 120rpx;"></view>
+    </view>
+</template>
+
+<script>
+export default {
+    data() {
+        return {
+            orderInfo: {
+                status: 2,
+                orderNo: '',
+                goodsList: [],
+                address: {}
+            },
+            btnStyle: {
+                marginLeft: '20rpx',
+                width: '160rpx',
+                height: '60rpx',
+                lineHeight: '60rpx',
+                padding: '0'
+            },
+            themeBtnStyle: {
+                marginLeft: '20rpx',
+                width: '160rpx',
+                height: '60rpx',
+                lineHeight: '60rpx',
+                padding: '0',
+                backgroundColor: '#38C148',
+                color: '#fff',
+                border: 'none'
+            },
+            themeLightBtnStyle: {
+                marginLeft: '20rpx',
+                width: '160rpx',
+                height: '60rpx',
+                lineHeight: '60rpx',
+                padding: '0',
+                backgroundColor: '#5bc0de', // Light blue/green for price match? Or keep simple
+                color: '#fff',
+                border: 'none'
+            }
+        };
+    },
+    computed: {
+        statusText() {
+            const map = {
+                2: '等待买家付款',
+                3: '等待卖家发货',
+                8: '已发货',
+                12: '交易完成',
+                10: '交易关闭', // 退款
+                '-1': '交易关闭'
+            };
+            return map[this.orderInfo.status] || '未知状态';
+        }
+    },
+    onLoad(options) {
+        if (options.orderNo) {
+            this.loadOrderDetail(options.orderNo);
+        } else {
+            // For testing/preview if no orderNo passed, use a mock default
+            this.loadOrderDetail('SN_MOCK_DEFAULT');
+        }
+    },
+    methods: {
+        loadOrderDetail(orderNo) {
+            // Mock data loading
+            this.orderInfo = this.getMockData(orderNo);
+        },
+        copyOrderNo() {
+            uni.setClipboardData({
+                data: this.orderInfo.orderNo,
+                success: () => {
+                    uni.showToast({ title: '复制成功', icon: 'none' });
+                }
+            });
+        },
+        viewLogistics() {
+            uni.navigateTo({
+                url: `/pages-car/pages/logistics-detail?orderNo=${this.orderInfo.orderNo}`
+            });
+        },
+        handleAction(type) {
+            uni.showToast({ title: `点击了${type}`, icon: 'none' });
+            // Implement specific logic here similar to my-order.vue
+        },
+        getMockData(orderNo) {
+            // Basic mock structure
+            return {
+                status: 2, // Default to pending payment for dev
+                orderNo: orderNo || '32656+56+5655',
+                createTime: '2021-07-23 14:50:05',
+                goodsTotalPrice: '6565',
+                postage: '0.00',
+                discountPrice: '55',
+                realPayPrice: '918.00',
+                address: {
+                    name: '张三',
+                    mobile: '155****5855',
+                    detail: '四川省成都市高新区XXX街XXX路XXX号XXX小区XXX栋XXXX单元XXX楼XXX'
+                },
+                goodsList: [
+                    {
+                        title: '马克思主义基本原理',
+                        quality: '中等',
+                        price: '9.60',
+                        num: 2,
+                        cover: 'https://uviewui.com/album/1.jpg'
+                    },
+                    {
+                        title: '马克思主义基本原理',
+                        quality: '中等',
+                        price: '9.60',
+                        num: 2,
+                        cover: 'https://uviewui.com/album/1.jpg'
+                    }
+                ]
+            };
+        }
+    }
+};
+</script>
+
+<style lang="scss" scoped>
+.order-detail-page {
+    min-height: 100vh;
+    background-color: #F5F5F5;
+    padding-bottom: 20rpx;
+
+    .status-header {
+        background-color: #d1f2d8; // Light green bg
+        padding: 40rpx 30rpx;
+        color: #333;
+
+        .status-text {
+            font-size: 36rpx;
+            font-weight: bold;
+            margin-bottom: 10rpx;
+        }
+
+        .status-desc {
+            font-size: 26rpx;
+            color: #666;
+            display: flex;
+            align-items: center;
+        }
+
+        .status-desc-block {
+            font-size: 26rpx;
+            color: #666;
+
+            .status-tip {
+                margin-bottom: 10rpx;
+            }
+
+            .status-desc-row {
+                display: flex;
+                align-items: center;
+            }
+        }
+    }
+
+    .info-card {
+        background-color: #fff;
+        margin: 20rpx;
+        border-radius: 16rpx;
+        padding: 30rpx;
+        display: flex;
+
+        &.address-card {
+            align-items: center;
+
+            .icon-box {
+                margin-right: 20rpx;
+            }
+
+            .address-content {
+                flex: 1;
+                margin-right: 20rpx;
+
+                .user-info {
+                    font-size: 30rpx;
+                    font-weight: 500;
+                    margin-bottom: 10rpx;
+
+                    .mobile {
+                        margin-left: 20rpx;
+                    }
+                }
+
+                .address-detail {
+                    font-size: 26rpx;
+                    color: #666;
+                    line-height: 1.4;
+                }
+            }
+        }
+
+        &.logistics-card {
+            align-items: center;
+
+            .icon-box {
+                margin-right: 20rpx;
+            }
+
+            .logistics-content {
+                flex: 1;
+                margin-right: 20rpx;
+
+                .company-name {
+                    font-size: 28rpx;
+                    color: #38C148;
+                    margin-bottom: 6rpx;
+                }
+
+                .latest-trace {
+                    font-size: 26rpx;
+                    color: #333;
+                    margin-bottom: 6rpx;
+                    display: -webkit-box;
+                    -webkit-box-orient: vertical;
+                    -webkit-line-clamp: 2;
+                    overflow: hidden;
+                }
+
+                .update-time {
+                    font-size: 24rpx;
+                    color: #999;
+                }
+            }
+        }
+
+        &.goods-card {
+            display: block;
+
+            .goods-item {
+                display: flex;
+                margin-bottom: 30rpx;
+
+                .goods-cover {
+                    width: 120rpx;
+                    height: 120rpx;
+                    border-radius: 8rpx;
+                    margin-right: 20rpx;
+                    background-color: #eee;
+                }
+
+                .goods-info {
+                    flex: 1;
+
+                    .goods-title {
+                        font-size: 28rpx;
+                        color: #333;
+                        margin-bottom: 10rpx;
+                    }
+
+                    .goods-quality {
+                        font-size: 24rpx;
+                        color: #999;
+                    }
+
+                    .price-box {
+                        margin-top: 10rpx;
+                        display: flex;
+                        justify-content: space-between;
+
+                        .price {
+                            font-weight: 500;
+                        }
+
+                        .num {
+                            color: #999;
+                        }
+                    }
+                }
+
+                .goods-action {
+                    display: flex;
+                    align-items: center;
+                }
+            }
+
+            .price-detail {
+                border-top: 1rpx solid #eee;
+                padding-top: 20rpx;
+
+                .row {
+                    display: flex;
+                    justify-content: space-between;
+                    font-size: 26rpx;
+                    color: #666;
+                    margin-bottom: 10rpx;
+
+                    .goods-total {
+                        color: #38C148;
+                    }
+
+                    .discount {
+                        color: #38C148;
+                    }
+                }
+
+                .real-pay-row {
+                    display: flex;
+                    justify-content: space-between;
+                    font-size: 30rpx;
+                    font-weight: 500;
+                    margin-top: 20rpx;
+
+                    .real-price {
+                        color: #38C148;
+                    }
+                }
+            }
+        }
+
+        &.time-card {
+            display: block;
+
+            .row {
+                display: flex;
+                justify-content: space-between;
+                font-size: 24rpx;
+                color: #999;
+                margin-bottom: 10rpx;
+
+                &:last-child {
+                    margin-bottom: 0;
+                }
+            }
+        }
+    }
+
+    .bottom-bar {
+        position: fixed;
+        bottom: 0;
+        left: 0;
+        right: 0;
+        background-color: #fff;
+        padding: 20rpx 30rpx;
+        padding-bottom: calc(20rpx + env(safe-area-inset-bottom));
+        display: flex;
+        justify-content: flex-end;
+        align-items: center;
+        box-shadow: 0 -2rpx 10rpx rgba(0, 0, 0, 0.05);
+    }
+}
+</style>

+ 100 - 0
pages-car/pages/red-packet.vue

@@ -0,0 +1,100 @@
+<template>
+    <view class="red-packet-page">
+        <!-- Navigation Bar is likely handled by pages.json configuration or custom nav -->
+        <!-- Since style says navigationStyle: custom might be needed for some pages, but here we stick to default or simple -->
+        
+        <page-scroll
+            ref="pageScroll"
+            emptyText="暂无红包"
+            @updateList="updateList"
+        >
+            <view class="list-container">
+                <red-packet-item 
+                    v-for="(item, index) in list" 
+                    :key="index" 
+                    :info="item"
+                    @use="handleUse"
+                />
+            </view>
+        </page-scroll>
+    </view>
+</template>
+
+<script>
+import PageScroll from '@/components/pageScroll/index.vue';
+import RedPacketItem from '../components/red-packet-item.vue';
+
+export default {
+    components: {
+        PageScroll,
+        RedPacketItem
+    },
+    data() {
+        return {
+            list: []
+        };
+    },
+    methods: {
+        updateList(data) {
+            // this.list = data;
+            this.list = [
+                {
+                    amount: 10,
+                    condition: 599,
+                    type: 1,
+                    typeName: '普通红包',
+                    title: '满599减10元',
+                    endTime: '2024.09.11',
+                    status: 0
+                },
+                {
+                    amount: 10,
+                    condition: 10.01,
+                    type: 2,
+                    typeName: '惊喜红包',
+                    title: '满10.01减10元',
+                    endTime: '2024.09.11',
+                    status: 0
+                },
+                {
+                    amount: 10,
+                    condition: 599,
+                    type: 1,
+                    typeName: '普通红包',
+                    title: '满599减10元',
+                    endTime: '2024.09.11',
+                    status: 1
+                },
+                {
+                    amount: 10,
+                    condition: 599,
+                    type: 1,
+                    typeName: '普通红包',
+                    title: '满599减10元',
+                    endTime: '2024.09.11',
+                    status: 2
+                }
+            ];
+        },
+        handleUse(item) {
+            console.log('Use red packet', item);
+            // Handle navigation or logic
+            uni.switchTab({
+                url: '/pages/sell/index'
+            });
+        }
+    },
+}
+</script>
+
+<style lang="scss" scoped>
+.red-packet-page {
+    background-color: #f5f5f5;
+    min-height: 100vh;
+}
+
+.list-container {
+    padding-top: 20rpx;
+    padding-bottom: 20rpx;
+}
+</style>

TEMPAT SAMPAH
pages-car/static/my-order/icon-1.png


TEMPAT SAMPAH
pages-car/static/my-order/icon-2.png


TEMPAT SAMPAH
pages-car/static/my-order/icon-3.png


TEMPAT SAMPAH
pages-car/static/my-order/icon-4.png


+ 3 - 1
pages-sell/components/detail/service-card.vue

@@ -106,7 +106,9 @@ export default {
 		.service-val {
 			color: #666;
             flex: 1; // Allow text to take remaining space
-            @include ellipsis;
+            overflow: hidden;
+            white-space: nowrap;
+            text-overflow: ellipsis;
 
 			&.red {
 				color: #D81A00;

+ 71 - 0
pages.json

@@ -54,6 +54,18 @@
                     "sell-container": "view"
                 }
             }
+        },
+        {
+            "path": "pages/cart/index",
+            "style": {
+                "navigationBarTitleText": "购物车",
+                "usingComponents": {
+                    "cart-container": "/pages-car/pages/index"
+                },
+                "componentPlaceholder": {
+                    "cart-container": "view"
+                }
+            }
         }
     ],
     "subPackages": [
@@ -276,6 +288,59 @@
                 }
             ]
         },
+        {
+            "root": "pages-car",
+            "pages": [
+                {
+                    "path": "pages/index",
+                    "style": {
+                        "navigationBarTitleText": "购物车"
+                    }
+                },
+                {
+                    "path": "pages/arrival-reminder",
+                    "style": {
+                        "navigationBarTitleText": "到货提醒"
+                    }
+                },
+                {
+                    "path": "pages/my-footprint",
+                    "style": {
+                        "navigationBarTitleText": "我的足迹"
+                    }
+                },
+                {
+                    "path": "pages/logistics-detail",
+                    "style": {
+                        "navigationBarTitleText": "物流详情"
+                    }
+                },
+                {
+                    "path": "pages/my-fav",
+                    "style": {
+                        "navigationBarTitleText": "我的收藏"
+                    }
+                },
+                {
+                    "path": "pages/my-order",
+                    "style": {
+                        "navigationBarTitleText": "我的订单"
+                    }
+                },
+                {
+                    "path": "pages/order-detail",
+                    "style": {
+                        "navigationBarTitleText": "订单详情"
+                    }
+                },
+                {
+                    "path": "pages/red-packet",
+                    "style": {
+                        "navigationBarTitleText": "红包"
+                    }
+                }
+            ]
+        },
         {
             "root": "pages-sell",
             "pages": [
@@ -351,6 +416,12 @@
                 "iconPath": "/static/tabbar/sell.png",
                 "selectedIconPath": "/static/tabbar/sell2.png"
             },
+            {
+                "text": "购物车",
+                "pagePath": "pages/cart/index",
+                "iconPath": "/static/tabbar/cart.png",
+                "selectedIconPath": "/static/tabbar/cart2.png"
+            },
             {
                 "text": "我的",
                 "pagePath": "pages/mine/index",

+ 25 - 0
pages/cart/index.vue

@@ -0,0 +1,25 @@
+<template>
+    <view>
+        <cart-container></cart-container>
+    </view>
+</template>
+
+<script>
+export default {
+    data() {
+        return {
+
+        }
+    },
+    onLoad() {
+
+    },
+    methods: {
+
+    }
+}
+</script>
+
+<style>
+/* Empty style as content is in the component */
+</style>

+ 61 - 5
pages/mine/index.vue

@@ -54,6 +54,25 @@
 			</view>
 		</view>
 
+		<!-- 我的订单 -->
+		<view class="order-section" style="margin-top: 30rpx;">
+			<view class="section-header">
+				<text>我的订单</text>
+				<view class="view-all" @click="viewAllOrders">
+					<text>查看全部</text>
+					<u-icon name="arrow-right" size="24" color="#999"></u-icon>
+				</view>
+			</view>
+			<view class="order-types" style="padding: 0 20rpx">
+				<view class="type-item flex-d flex-a-c" v-for="(item, index) in myOrderTypes" :key="index"
+					@click="navigateToOrder(item.path)">
+					<image class="type-icon" :src="item.icon" mode="aspectFit"></image>
+					<text>{{ item.name }}</text>
+					<view class="badge" v-if="item.badge">{{ item.badge }}</view>
+				</view>
+			</view>
+		</view>
+
 		<!-- 实用工具 -->
 		<view class="tools-section">
 			<view class="section-title">实用工具</view>
@@ -162,6 +181,43 @@ export default {
 					path: '/pages-mine/pages/apply-return'
 				}
 			],
+			myOrderTypes: [
+				{
+					name: '待付款',
+					icon: '/pages-car/static/my-order/icon-1.png',
+					badge: 0,
+					key: 'payNum',
+					path: '/pages-car/pages/my-order?status=2'
+				},
+				{
+					name: '待发货',
+					icon: '/pages-car/static/my-order/icon-2.png',
+					badge: 0,
+					key: 'sendNum',
+					path: '/pages-car/pages/my-order?status=3'
+				},
+				{
+					name: '待收货',
+					icon: '/pages-car/static/my-order/icon-3.png',
+					badge: 0,
+					key: 'receiveNum',
+					path: '/pages-car/pages/my-order?status=8'
+				},
+				{
+					name: '退款/售后',
+					icon: '/pages-car/static/my-order/icon-4.png',
+					badge: 0,
+					key: 'refundNum',
+					path: '/pages-car/pages/my-order?status=10'
+				},
+				{
+					name: '已完成',
+					icon: 'https://shuhi.oss-cn-qingdao.aliyuncs.com/mini/5.png',
+					badge: 0,
+					key: 'completeNum',
+					path: '/pages-car/pages/my-order?status=12'
+				}
+			],
 			tools: [
 				{
 					name: '消息通知',
@@ -171,12 +227,12 @@ export default {
 				{
 					name: '我的收藏',
 					icon: 'https://shuhi.oss-cn-qingdao.aliyuncs.com/mini/t2.png',
-					path: ''
+					path: '/pages-car/pages/my-fav'
 				},
 				{
 					name: '我的足迹',
 					icon: 'https://shuhi.oss-cn-qingdao.aliyuncs.com/mini/t3.png',
-					path: ''
+					path: '/pages-car/pages/my-footprint'
 				},
 				{
 					name: '我的地址',
@@ -184,9 +240,9 @@ export default {
 					path: '/pages-mine/pages/address/list'
 				},
 				{
-					name: '我的优惠券',
+					name: '我的红包',
 					icon: 'https://shuhi.oss-cn-qingdao.aliyuncs.com/mini/t5.png',
-					path: ''
+					path: '/pages-car/pages/red-packet'
 				},
 				{
 					name: '联系客服',
@@ -201,7 +257,7 @@ export default {
 				{
 					name: '到货提醒',
 					icon: 'https://shuhi.oss-cn-qingdao.aliyuncs.com/mini/t8.png',
-					path: ''
+					path: '/pages-car/pages/arrival-reminder'
 				},
 				{
 					name: '合伙人计划',