Alex 9 сар өмнө
parent
commit
41ed59b46f
2 өөрчлөгдсөн 745 нэмэгдсэн , 725 устгасан
  1. 180 177
      App.vue
  2. 565 548
      pages/home/index.vue

+ 180 - 177
App.vue

@@ -1,181 +1,184 @@
 <script>
-export default {
-    globalData: {
-        // 胶囊距上距离
-        menuTop: 0,
-        // 导航栏高度
-        navBarHeight: 0,
-        // 胶囊距右方间距(方保持左、右间距一致)
-        menuRight: 0,
-        // 胶囊距底部间距(保持底部间距一致)
-        menuBotton: 0,
-        // 胶囊高度(自定义内容可与胶囊高度保证一致)
-        menuHeight: 0,
-        // 状态栏高度
-        statusBarHeight: 0,
-        // 安全距离
-        safeAreaHeight: 0,
-        // 胶囊宽度
-        menuWidth: 0,
-        // 窗口宽度
-        windowWidth: 0,
-        // 窗口宽度高度
-        windowHeight: 0,
-        // 常规子页面可操作区域高度
-        pageContentHeight: 0,
-    },
-    onLaunch(options) {
-        const that = this;
-        // 获取系统信息
-        const systemInfo = uni.getSystemInfoSync();
-        // 胶囊按钮位置信息
-        const menuButtonInfo = wx.getMenuButtonBoundingClientRect();
-        console.log(menuButtonInfo);
-        // 导航栏高度 = 状态栏到胶囊的间距(胶囊距上距离-状态栏高度) * 2 + 胶囊高度 + 状态栏高度
-        that.globalData.menuTop = menuButtonInfo.top - systemInfo.statusBarHeight;
-        that.globalData.menuBotton = menuButtonInfo.top - systemInfo.statusBarHeight;
-        that.globalData.menuWidth = menuButtonInfo.width;
-        that.globalData.navBarHeight =
-            (menuButtonInfo.top - systemInfo.statusBarHeight) * 2 + menuButtonInfo.height + systemInfo.statusBarHeight;
-        that.globalData.menuRight = systemInfo.screenWidth - menuButtonInfo.right;
-        that.globalData.menuHeight = menuButtonInfo.height;
-        that.globalData.statusBarHeight = systemInfo.statusBarHeight;
-        that.globalData.safeAreaHeight = systemInfo.safeAreaInsets.bottom;
-        that.globalData.windowWidth = systemInfo.windowWidth;
-        that.globalData.windowHeight = systemInfo.windowHeight;
-        that.globalData.pageContentHeight =
-            systemInfo.windowHeight -
-            (that.globalData.navBarHeight + that.globalData.menuTop + that.globalData.menuBotton);
-
-        const scene = options.query.scene ? decodeURIComponent(options.query.scene) : "";
-        const inviteCode = scene ? scene.split("=")[1] : "";
-        console.log(inviteCode, options, "inviteCode");
-        this.slientLogin(inviteCode);
-    },
-    methods: {
-        slientLogin(inviteCode) {
-            uni.login({
-                success(res) {
-                    uni.$u.http
-                        .post("/user/wxLogin", {
-                            code: res.code,
-                            inviteCode,
-                        })
-                        .then((response) => {
-                            if (response.code == 200) {
-                                uni.setStorageSync("token", response.data.token);
-                            }
-                        });
-                },
-                fail: (err) => {
-                    console.log(err, "wx.login登录失败");
-                },
-            });
-        },
-    },
-};
+	export default {
+		globalData: {
+			// 胶囊距上距离
+			menuTop: 0,
+			// 导航栏高度
+			navBarHeight: 0,
+			// 胶囊距右方间距(方保持左、右间距一致)
+			menuRight: 0,
+			// 胶囊距底部间距(保持底部间距一致)
+			menuBotton: 0,
+			// 胶囊高度(自定义内容可与胶囊高度保证一致)
+			menuHeight: 0,
+			// 状态栏高度
+			statusBarHeight: 0,
+			// 安全距离
+			safeAreaHeight: 0,
+			// 胶囊宽度
+			menuWidth: 0,
+			// 窗口宽度
+			windowWidth: 0,
+			// 窗口宽度高度
+			windowHeight: 0,
+			// 常规子页面可操作区域高度
+			pageContentHeight: 0,
+		},
+		onLaunch(options) {
+			const that = this;
+			// 获取系统信息
+			const systemInfo = uni.getSystemInfoSync();
+			// 胶囊按钮位置信息
+			const menuButtonInfo = wx.getMenuButtonBoundingClientRect();
+			console.log(menuButtonInfo);
+			// 导航栏高度 = 状态栏到胶囊的间距(胶囊距上距离-状态栏高度) * 2 + 胶囊高度 + 状态栏高度
+			that.globalData.menuTop = menuButtonInfo.top - systemInfo.statusBarHeight;
+			that.globalData.menuBotton = menuButtonInfo.top - systemInfo.statusBarHeight;
+			that.globalData.menuWidth = menuButtonInfo.width;
+			that.globalData.navBarHeight =
+				(menuButtonInfo.top - systemInfo.statusBarHeight) * 2 + menuButtonInfo.height + systemInfo.statusBarHeight;
+			that.globalData.menuRight = systemInfo.screenWidth - menuButtonInfo.right;
+			that.globalData.menuHeight = menuButtonInfo.height;
+			that.globalData.statusBarHeight = systemInfo.statusBarHeight;
+			that.globalData.safeAreaHeight = systemInfo.safeAreaInsets.bottom;
+			that.globalData.windowWidth = systemInfo.windowWidth;
+			that.globalData.windowHeight = systemInfo.windowHeight;
+			that.globalData.pageContentHeight =
+				systemInfo.windowHeight -
+				(that.globalData.navBarHeight + that.globalData.menuTop + that.globalData.menuBotton);
+
+			const scene = options.query.scene ? decodeURIComponent(options.query.scene) : "";
+			const inviteCode = scene ? scene.split("=")[1] : "";
+			console.log(inviteCode, "inviteCode");
+			if (inviteCode) {
+				wx.setStorageSync('inviteCode', inviteCode)
+			}
+			this.slientLogin(inviteCode);
+		},
+		methods: {
+			slientLogin(inviteCode) {
+				uni.login({
+					success(res) {
+						uni.$u.http
+							.post("/user/wxLogin", {
+								code: res.code,
+								inviteCode,
+							})
+							.then((response) => {
+								if (response.code == 200) {
+									uni.setStorageSync("token", response.data.token);
+								}
+							});
+					},
+					fail: (err) => {
+						console.log(err, "wx.login登录失败");
+					},
+				});
+			},
+		},
+	};
 </script>
 
 <style lang="scss">
-// ===
-// === 注意:此处导入的css,会作用于全部.vue文件,请适量导入
-// ===
-body {
-    font-family: PingFang-SC-Regular, PingFang-SC;
-}
-
-page {
-    background-color: $app-theme-bg-gray-deep-color;
-}
-
-@import "uview-ui/index.scss";
-@import "./static/css/common.scss";
-
-/* 解决小程序和app滚动条的问题 */
-/* #ifdef MP-WEIXIN || APP-PLUS */
-::-webkit-scrollbar {
-    display: none;
-    width: 0 !important;
-    height: 0 !important;
-    -webkit-appearance: none;
-    background: transparent;
-    color: transparent;
-}
-
-/* #endif */
-
-/* 解决H5 的问题 */
-/* #ifdef H5 */
-uni-scroll-view .uni-scroll-view::-webkit-scrollbar {
-    /* 隐藏滚动条,但依旧具备可以滚动的功能 */
-    display: none;
-    width: 0 !important;
-    height: 0 !important;
-    -webkit-appearance: none;
-    background: transparent;
-    color: transparent;
-}
-
-/* #endif */
-
-.shu-elip-1 {
-    overflow: hidden;
-    text-overflow: ellipsis;
-    white-space: nowrap;
-}
-
-.shu-elip-2 {
-    display: -webkit-box;
-    overflow: hidden;
-    text-overflow: ellipsis;
-    word-wrap: break-word;
-    white-space: normal !important;
-    -webkit-line-clamp: 2;
-    -webkit-box-orient: vertical;
-}
-
-// 导出 scss 变量用于在 script 下使用
-.price_color {
-    color: $app-theme-text-money-color;
-}
-
-.color_blue {
-    color: $app-theme-blue;
-}
-
-.btnGroup {
-    display: flex;
-    align-items: center;
-
-    .btn {
-        margin: 0 10rpx;
-    }
-}
-
-.mallbtn {
-    min-width: 200rpx;
-    line-height: 66rpx;
-    padding: 0 20rpx;
-    border-radius: 36rpx;
-    color: #ffffff;
-    margin-right: 20rpx;
-    text-align: center;
-    flex: 1;
-    padding: 0 30rpx;
-}
-
-.soldOutBtn {
-    @extend .mallbtn;
-    background-color: $app-theme-nobuy-bg-color;
-}
-
-.joinCartBtn {
-    @extend .mallbtn;
-    background-color: $app-theme-joincart-bg-color;
-}
-
-.buyBtn {
-    @extend .mallbtn;
-    background-color: $app-theme-buybtn-bg-color;
-}
-</style>
+	// ===
+	// === 注意:此处导入的css,会作用于全部.vue文件,请适量导入
+	// ===
+	body {
+		font-family: PingFang-SC-Regular, PingFang-SC;
+	}
+
+	page {
+		background-color: $app-theme-bg-gray-deep-color;
+	}
+
+	@import "uview-ui/index.scss";
+	@import "./static/css/common.scss";
+
+	/* 解决小程序和app滚动条的问题 */
+	/* #ifdef MP-WEIXIN || APP-PLUS */
+	::-webkit-scrollbar {
+		display: none;
+		width: 0 !important;
+		height: 0 !important;
+		-webkit-appearance: none;
+		background: transparent;
+		color: transparent;
+	}
+
+	/* #endif */
+
+	/* 解决H5 的问题 */
+	/* #ifdef H5 */
+	uni-scroll-view .uni-scroll-view::-webkit-scrollbar {
+		/* 隐藏滚动条,但依旧具备可以滚动的功能 */
+		display: none;
+		width: 0 !important;
+		height: 0 !important;
+		-webkit-appearance: none;
+		background: transparent;
+		color: transparent;
+	}
+
+	/* #endif */
+
+	.shu-elip-1 {
+		overflow: hidden;
+		text-overflow: ellipsis;
+		white-space: nowrap;
+	}
+
+	.shu-elip-2 {
+		display: -webkit-box;
+		overflow: hidden;
+		text-overflow: ellipsis;
+		word-wrap: break-word;
+		white-space: normal !important;
+		-webkit-line-clamp: 2;
+		-webkit-box-orient: vertical;
+	}
+
+	// 导出 scss 变量用于在 script 下使用
+	.price_color {
+		color: $app-theme-text-money-color;
+	}
+
+	.color_blue {
+		color: $app-theme-blue;
+	}
+
+	.btnGroup {
+		display: flex;
+		align-items: center;
+
+		.btn {
+			margin: 0 10rpx;
+		}
+	}
+
+	.mallbtn {
+		min-width: 200rpx;
+		line-height: 66rpx;
+		padding: 0 20rpx;
+		border-radius: 36rpx;
+		color: #ffffff;
+		margin-right: 20rpx;
+		text-align: center;
+		flex: 1;
+		padding: 0 30rpx;
+	}
+
+	.soldOutBtn {
+		@extend .mallbtn;
+		background-color: $app-theme-nobuy-bg-color;
+	}
+
+	.joinCartBtn {
+		@extend .mallbtn;
+		background-color: $app-theme-joincart-bg-color;
+	}
+
+	.buyBtn {
+		@extend .mallbtn;
+		background-color: $app-theme-buybtn-bg-color;
+	}
+</style>

+ 565 - 548
pages/home/index.vue

@@ -1,555 +1,572 @@
 <template>
-    <view class="container" :style="{ background: containerBg }" :class="bookList.length ? 'book-list' : 'no-list'">
-        <u-navbar :is-back="false" :border-bottom="false" :background="{ background: navbarBackground }">
-            <text class="nav-title">卖书给书嗨</text>
-        </u-navbar>
-
-        <not-scanned v-if="!bookList.length"></not-scanned>
-        <scan-book-list
-            v-else
-            @updateBooks="updateBooksList"
-            @deleted="getLastOrder"
-            :bookList="bookList"
-            ref="scanBookList"
-        ></scan-book-list>
-        <!-- 底部固定按钮 -->
-        <view class="bottom-fixed">
-            <view class="btn-wrap mb-20">
-                <button class="scan-btn flex-1" @click="handleScan">
-                    <u-icon name="scan" color="#FFFFFF" size="40"></u-icon>
-                    <text>扫码卖书</text>
-                </button>
-                <button class="isbn-btn flex-1" @click="goToInputISBN">
-                    <u-icon name="edit-pen" color="#4CD964" size="40"></u-icon>
-                    <text>输入ISBN</text>
-                </button>
-            </view>
-
-            <view class="flex-a flex-j-b pad-20" style="padding-top: 0" v-if="bookList.length">
-                <view class="left-info" style="min-width: 194px">
-                    <view class="flex-a common-text">
-                        共<text class="color-red">{{ totalBooks }}</text
-                        >件 预估回收价 <text class="color-red">¥{{ totalPrice || 0 }}</text>
-                    </view>
-                    <text class="common-text tip">*旧书预估价格满 {{ orderInfo.minOrderMoney }} 元起收</text>
-                </view>
-
-                <button class="scan-btn next-btn" @click="onNext" :disabled="isDisabled">下一步</button>
-            </view>
-
-            <service-info v-if="bookList.length" :serviceList="serviceList" :firstOrder="orderInfo.firstOrder"></service-info>
-        </view>
-
-        <InputIsbn ref="isbnPopup" @submit="checkBookISBN" />
-        <!-- 套装书说明弹窗 -->
-        <CommonDialog ref="setBookDialog" title="套装书说明" :showCancel="false" @confirm="handleSetBookConfirm">
-            <text
-                >套装书(ISBN码相同的系列书箱)只需扫描其中一册,扫码价即套装价。打包时请把所有单册统在一起或放在一个袋子里寄出。</text
-            >
-        </CommonDialog>
-
-        <!-- 暂不回收弹窗 -->
-        <CommonDialog ref="notAcceptDialog" title="暂不回收" :showCancel="false">
-            <text>这本书暂时不回收,请您过段时间再来试试~</text>
-        </CommonDialog>
-
-        <!-- 暂无信息弹窗 -->
-        <CommonDialog ref="noInfoDialog" title="暂无信息" :showCancel="false">
-            <text>抱歉,没有该书的信息,书嗨会定期补充图书信息,请您过段时间再来试试~</text>
-        </CommonDialog>
-
-        <!-- 扫累了弹窗 -->
-        <CommonDialog ref="tiredDialog" title="温馨提示" :showCancel="false">
-            <text>扫累了,休息休息吧~</text>
-        </CommonDialog>
-
-        <!-- 该书超出最大回收本数  maxAcceptDialog-->
-        <CommonDialog ref="maxAcceptDialog" title="温馨提示" :showCancel="false">
-            <text>该书超出最大回收本数</text>
-        </CommonDialog>
-
-        <!-- 单个订单最多40本书  orderMaxNumDialog-->
-        <CommonDialog ref="orderMaxNumDialog" title="温馨提示" :showCancel="false">
-            <text>单个订单最多40本书</text>
-        </CommonDialog>
-
-        <!-- 温馨提示弹窗 -->
-        <KindReminder ref="kindReminder" @start="handleStartSelling" @viewRules="handleViewRules" />
-
-        <view 
-            class="customer-service" 
-            :style="{ left: servicePosition.left + 'px', right: servicePosition.right + 'px', bottom: servicePosition.bottom + 'px' }"
-            @touchstart="touchStart"
-            @touchmove="touchMove"
-            @touchend="touchEnd"
-        >
-            <button class="service-btn" open-type="contact">
-                <image src="/static/img/kf.png" mode="widthFix" style="width: 126rpx; height: 140rpx"></image>
-            </button>
-        </view>
-
-        <ConfirmBooks ref="confirmBooks" @incomplete="handleIncomplete" />
-        <!-- 首单免费弹窗 -->
-        <FirstOrderFreePopup ref="firstOrderFreePopup" />
-    </view>
+	<view class="container" :style="{ background: containerBg }" :class="bookList.length ? 'book-list' : 'no-list'">
+		<u-navbar :is-back="false" :border-bottom="false" :background="{ background: navbarBackground }">
+			<text class="nav-title">卖书给书嗨</text>
+		</u-navbar>
+
+		<not-scanned v-if="!bookList.length"></not-scanned>
+		<scan-book-list v-else @updateBooks="updateBooksList" @deleted="getLastOrder" :bookList="bookList"
+			ref="scanBookList"></scan-book-list>
+		<!-- 底部固定按钮 -->
+		<view class="bottom-fixed">
+			<view class="btn-wrap mb-20">
+				<button class="scan-btn flex-1" @click="handleScan">
+					<u-icon name="scan" color="#FFFFFF" size="40"></u-icon>
+					<text>扫码卖书</text>
+				</button>
+				<button class="isbn-btn flex-1" @click="goToInputISBN">
+					<u-icon name="edit-pen" color="#4CD964" size="40"></u-icon>
+					<text>输入ISBN</text>
+				</button>
+			</view>
+
+			<view class="flex-a flex-j-b pad-20" style="padding-top: 0" v-if="bookList.length">
+				<view class="left-info" style="min-width: 194px">
+					<view class="flex-a common-text">
+						共<text class="color-red">{{ totalBooks }}</text>件 预估回收价 <text
+							class="color-red">¥{{ totalPrice || 0 }}</text>
+					</view>
+					<text class="common-text tip">*旧书预估价格满 {{ orderInfo.minOrderMoney }} 元起收</text>
+				</view>
+
+				<button class="scan-btn next-btn" @click="onNext" :disabled="isDisabled">下一步</button>
+			</view>
+
+			<service-info v-if="bookList.length" :serviceList="serviceList"
+				:firstOrder="orderInfo.firstOrder"></service-info>
+		</view>
+
+		<InputIsbn ref="isbnPopup" @submit="checkBookISBN" />
+		<!-- 套装书说明弹窗 -->
+		<CommonDialog ref="setBookDialog" title="套装书说明" :showCancel="false" @confirm="handleSetBookConfirm">
+			<text>套装书(ISBN码相同的系列书箱)只需扫描其中一册,扫码价即套装价。打包时请把所有单册统在一起或放在一个袋子里寄出。</text>
+		</CommonDialog>
+
+		<!-- 暂不回收弹窗 -->
+		<CommonDialog ref="notAcceptDialog" title="暂不回收" :showCancel="false">
+			<text>这本书暂时不回收,请您过段时间再来试试~</text>
+		</CommonDialog>
+
+		<!-- 暂无信息弹窗 -->
+		<CommonDialog ref="noInfoDialog" title="暂无信息" :showCancel="false">
+			<text>抱歉,没有该书的信息,书嗨会定期补充图书信息,请您过段时间再来试试~</text>
+		</CommonDialog>
+
+		<!-- 扫累了弹窗 -->
+		<CommonDialog ref="tiredDialog" title="温馨提示" :showCancel="false">
+			<text>扫累了,休息休息吧~</text>
+		</CommonDialog>
+
+		<!-- 该书超出最大回收本数  maxAcceptDialog-->
+		<CommonDialog ref="maxAcceptDialog" title="温馨提示" :showCancel="false">
+			<text>该书超出最大回收本数</text>
+		</CommonDialog>
+
+		<!-- 单个订单最多40本书  orderMaxNumDialog-->
+		<CommonDialog ref="orderMaxNumDialog" title="温馨提示" :showCancel="false">
+			<text>单个订单最多40本书</text>
+		</CommonDialog>
+
+		<!-- 温馨提示弹窗 -->
+		<KindReminder ref="kindReminder" @start="handleStartSelling" @viewRules="handleViewRules" />
+
+		<view class="customer-service"
+			:style="{ left: servicePosition.left + 'px', right: servicePosition.right + 'px', bottom: servicePosition.bottom + 'px' }"
+			@touchstart="touchStart" @touchmove="touchMove" @touchend="touchEnd">
+			<button class="service-btn" open-type="contact">
+				<image src="/static/img/kf.png" mode="widthFix" style="width: 126rpx; height: 140rpx"></image>
+			</button>
+		</view>
+
+		<ConfirmBooks ref="confirmBooks" @incomplete="handleIncomplete" />
+		<!-- 首单免费弹窗 -->
+		<FirstOrderFreePopup ref="firstOrderFreePopup" />
+	</view>
 </template>
 
 <script>
-import notScanned from "./components/notScanned.vue";
-import InputIsbn from "./components/InputIsbn.vue";
-import ScanBookList from "./components/ScanBookList.vue";
-import CommonDialog from "@/components/common-dialog.vue";
-import KindReminder from "./components/KindReminder.vue";
-import ServiceInfo from "./components/ServiceInfo.vue";
-import ConfirmBooks from "./components/ConfirmBooks.vue";
-import FirstOrderFreePopup from "./components/FirstOrderFreePopup.vue";
-export default {
-    components: {
-        notScanned,
-        InputIsbn,
-        ScanBookList,
-        CommonDialog,
-        KindReminder,
-        ServiceInfo,
-        ConfirmBooks,
-        FirstOrderFreePopup,
-    },
-    data() {
-        return {
-            orderInfo: {},
-            collapseState: {
-                step1: false,
-                step3: false,
-            },
-            scrollTop: 0,
-            bookList: [],
-            serviceList: [],
-            currentBook: {},
-            // 客服按钮位置
-            servicePosition: {
-                left: 'auto',
-                right: 0,
-                bottom: '20%'
-            },
-            // 触摸开始位置
-            startX: 0,
-            startY: 0,
-            // 屏幕宽度和高度
-            screenWidth: 0,
-            screenHeight: 0,
-            // 初始位置记录,用于计算拖动
-            initialLeft: 0,
-            initialBottom: 0,
-            // 是否正在更新位置,用于防止频繁更新
-            isUpdatingPosition: false,
-        };
-    },
-    computed: {
-        navbarBackground() {
-            if (this.scrollTop > 0) {
-                return "linear-gradient(180deg, #4CD964 0%, #5ff178 100%)";
-            }
-            return "transparent";
-        },
-        containerBg() {
-            return this.bookList.length > 0
-                ? "linear-gradient(180deg, #4CD964 0%, #F8F8F8 25%)"
-                : "linear-gradient(180deg, #4CD964 0%, #ffffff 25%)";
-        },
-        containerPb() {
-            return this.bookList.length > 0 ? "300rpx" : "110rpx";
-        },
-        totalBooks() {
-            return this.bookList.reduce((sum, book) => sum + (book.num || 1), 0);
-        },
-        totalPrice() {
-            return this.bookList.reduce((sum, book) => sum + book.recyclePrice * (book.num || 1), 0).toFixed(2);
-        },
-        isDisabled() {
-            return this.totalPrice < this.orderInfo.minOrderMoney;
-        },
-    },
-    onPageScroll(e) {
-        this.$nextTick(() => {
-            this.scrollTop = e.scrollTop;
-        });
-    },
-    onReady() {
-        // 获取屏幕宽度和高度
-        uni.getSystemInfo({
-            success: (res) => {
-                this.screenWidth = res.windowWidth;
-                this.screenHeight = res.windowHeight;
-            }
-        });
-    },
-    methods: {
-        // 触摸开始
-        touchStart(e) {
-            const touch = e.touches[0];
-            this.startX = touch.clientX;
-            this.startY = touch.clientY;
-            
-            // 记录初始位置,用于计算移动距离
-            if (this.servicePosition.right !== 'auto') {
-                // 如果是靠右定位,记录当前位置但不立即改变显示位置
-                // 只在内部计算中使用,避免视觉上的位置跳动
-                this.initialLeft = this.screenWidth - 126;
-            } else {
-                this.initialLeft = parseFloat(this.servicePosition.left);
-            }
-            
-            // 如果bottom是百分比,转换为具体像素值,但不改变显示位置
-            if (typeof this.servicePosition.bottom === 'string' && this.servicePosition.bottom.includes('%')) {
-                const percentage = parseFloat(this.servicePosition.bottom) / 100;
-                this.initialBottom = this.screenHeight * percentage;
-            } else {
-                this.initialBottom = parseFloat(this.servicePosition.bottom);
-            }
-        },
-        
-        // 触摸移动
-        touchMove(e) {
-            // 阻止默认行为,防止页面滚动
-            e.preventDefault && e.preventDefault();
-            e.stopPropagation && e.stopPropagation();
-            
-            const touch = e.touches[0];
-            
-            // 计算移动距离
-            const deltaX = touch.clientX - this.startX;
-            const deltaY = touch.clientY - this.startY;
-            
-            // 使用初始位置计算新位置,避免累积误差
-            let newLeft = this.initialLeft + deltaX;
-            let newBottom = this.initialBottom - deltaY; // 注意:y轴方向是相反的
-            
-            // 确保按钮不超出屏幕边界
-            if (newLeft < 0) {
-                newLeft = 0;
-            } else if (newLeft > this.screenWidth - 126) {
-                newLeft = this.screenWidth - 126;
-            }
-            
-            // 确保按钮不超出屏幕垂直边界
-            if (newBottom < 20) {
-                newBottom = 20;
-            } else if (newBottom > this.screenHeight - 160) {
-                newBottom = this.screenHeight - 160;
-            }
-            
-            // 使用节流方式更新位置,避免过于频繁的更新
-            if (!this.isUpdatingPosition) {
-                this.isUpdatingPosition = true;
-                
-                // 更新位置 - 第一次移动时才真正改变right为auto
-                this.servicePosition = {
-                    left: newLeft,
-                    right: 'auto',
-                    bottom: newBottom
-                };
-                
-                // 使用setTimeout代替requestAnimationFrame,在微信小程序中更兼容
-                setTimeout(() => {
-                    this.isUpdatingPosition = false;
-                }, 16); // 约等于60fps的刷新率
-            }
-            
-            // 不更新起始点,保持相对于初始触摸点的位移计算
-            // 这样可以避免累积误差,使拖动更精确
-        },
-        
-        // 触摸结束,实现吸附效果
-        touchEnd() {
-            // 确保不再有待处理的更新
-            this.isUpdatingPosition = false;
-            
-            const buttonCenter = this.servicePosition.left + 63; // 按钮中心位置
-            const halfScreen = this.screenWidth / 2;
-            
-            // 判断是吸附到左边还是右边
-            if (buttonCenter < halfScreen) {
-                // 吸附到左边
-                this.servicePosition = {
-                    left: 0,
-                    right: 'auto',
-                    bottom: this.servicePosition.bottom
-                };
-            } else {
-                // 吸附到右边
-                this.servicePosition = {
-                    left: 'auto',
-                    right: 0,
-                    bottom: this.servicePosition.bottom
-                };
-            }
-        },
-        
-        handleStart() {
-            this.showPopup = true;
-        },
-        //套装书确认
-        handleSetBookConfirm() {
-            this.$refs.confirmBooks.openPopup(this.currentBook);
-        },
-        //书册补全
-        handleIncomplete() {
-            this.$refs.scanBookList.handleDeleteBook(this.currentBook);
-        },
-
-        //提交
-        onNext() {
-            let orderId = this.orderInfo.orderId;
-            //预提交
-            uni.$u.http.get("/token/order/preSubmit?orderId=" + orderId).then((res) => {
-                if (res.code == 200) {
-                    if (res.data.code == 1 || res.data.code == 2) {
-                        uni.navigateTo({
-                            url: "/pages-home/pages/book-order",
-                        });
-                        uni.setStorageSync("orderId", orderId);
-                    } else {
-                        uni.showToast({
-                            icon: "none",
-                            title: res.msg,
-                        });
-                    }
-                } else {
-                    uni.showToast({
-                        icon: "none",
-                        title: res.msg,
-                    });
-                }
-            });
-        },
-
-        updateBooksList(data) {
-            this.bookList = data;
-        },
-
-        toggleCollapse(step) {
-            this.$set(this.collapseState, step, !this.collapseState[step]);
-        },
-        handleScan() {
-            uni.scanCode({
-                scanType: ["barCode"],
-                success: (res) => {
-                    this.checkBookISBN(res.result);
-                },
-                fail: () => {
-                    uni.showToast({
-                        title: "扫码失败",
-                        icon: "none",
-                    });
-                },
-            });
-        },
-        checkBookISBN(isbn) {
-            uni.$u.http.get("/token/order/scanIsbn?isbn=" + isbn).then((res) => {
-                if (res.code == 200) {
-                    let code = res.data.code;
-                    if (code == 1) {
-                        res.data.num = 1;
-                        res.data.status = 1;
-                        res.data.recyclePrice = res.data.recycleMoney;
-                        this.currentBook = res.data;
-                        this.bookList.push(res.data);
-                        if (res.data.suit == 1) {
-                            this.$refs.setBookDialog.openPopup();
-                        }
-                    } else if (code == 2) {
-                        let item = this.bookList.find((v) => v.isbn === isbn);
-                        item.num = item.num + 1;
-                    } else {
-                        this.handleBookCode(res.data.code);
-                    }
-                } else {
-                    uni.showToast({
-                        title: res.msg,
-                        icon: "none",
-                    });
-                }
-            });
-        },
-        //处理扫码之后不同的状态 0-扫码频繁 1-成功 2-本单已有该书,数量+1  3-没有该书 4-本书暂不回收 5-超过每单最大可卖数量  6-单个订单最多40本书
-        handleBookCode(code) {
-            if (code == 1) {
-                this.bookList.push();
-            }
-            let tempKeys = [
-                "tiredDialog",
-                "",
-                "",
-                "noInfoDialog",
-                "notAcceptDialog",
-                "maxAcceptDialog",
-                "orderMaxNumDialog",
-            ];
-            let key = tempKeys[code];
-            if (key) {
-                this.$refs[key].openPopup();
-            }
-        },
-        //获取当前用户未提交订单 /api/token/order/lastOrder
-        getLastOrder() {
-            uni.$u.http.get("/token/order/lastOrder").then((res) => {
-                if (res.code == 200) {
-                    this.orderInfo = res.data;
-                    if (res.data.showDialog == 1) {
-                        this.$refs.firstOrderFreePopup.openPopup();
-                    } else if (res.data.showDialog == 2) {
-                        this.$refs.kindReminder.openPopup();
-                    }
-
-                    this.bookList = res.data?.orderDetailList
-                        ? res.data.orderDetailList.map((v) => {
-                              v.orderId = res.data.orderId;
-                              return v;
-                          })
-                        : [];
-                    this.serviceList = res.data.serviceList || [];
-                }
-            });
-        },
-
-        goToScannedBooks() {
-            uni.navigateTo({
-                url: "/pages-home/pages/scaned-book",
-            });
-        },
-        goToInputISBN() {
-            this.$refs.isbnPopup.openPopup();
-        },
-        handleStartSelling() {
-            // 标记已显示过温馨提示
-            uni.setStorageSync("kindReminderShown", true);
-        },
-    },
-
-    onShow() {
-        // 获取上一个订单
-        setTimeout(() => {
-            this.getLastOrder();
-        }, 300);
-    },
-};
+	import notScanned from "./components/notScanned.vue";
+	import InputIsbn from "./components/InputIsbn.vue";
+	import ScanBookList from "./components/ScanBookList.vue";
+	import CommonDialog from "@/components/common-dialog.vue";
+	import KindReminder from "./components/KindReminder.vue";
+	import ServiceInfo from "./components/ServiceInfo.vue";
+	import ConfirmBooks from "./components/ConfirmBooks.vue";
+	import FirstOrderFreePopup from "./components/FirstOrderFreePopup.vue";
+	export default {
+		components: {
+			notScanned,
+			InputIsbn,
+			ScanBookList,
+			CommonDialog,
+			KindReminder,
+			ServiceInfo,
+			ConfirmBooks,
+			FirstOrderFreePopup,
+		},
+		data() {
+			return {
+				orderInfo: {},
+				collapseState: {
+					step1: false,
+					step3: false,
+				},
+				scrollTop: 0,
+				bookList: [],
+				serviceList: [],
+				currentBook: {},
+				// 客服按钮位置
+				servicePosition: {
+					left: 'auto',
+					right: 0,
+					bottom: '20%'
+				},
+				// 触摸开始位置
+				startX: 0,
+				startY: 0,
+				// 屏幕宽度和高度
+				screenWidth: 0,
+				screenHeight: 0,
+				// 初始位置记录,用于计算拖动
+				initialLeft: 0,
+				initialBottom: 0,
+				// 是否正在更新位置,用于防止频繁更新
+				isUpdatingPosition: false,
+			};
+		},
+		computed: {
+			navbarBackground() {
+				if (this.scrollTop > 0) {
+					return "linear-gradient(180deg, #4CD964 0%, #5ff178 100%)";
+				}
+				return "transparent";
+			},
+			containerBg() {
+				return this.bookList.length > 0 ?
+					"linear-gradient(180deg, #4CD964 0%, #F8F8F8 25%)" :
+					"linear-gradient(180deg, #4CD964 0%, #ffffff 25%)";
+			},
+			containerPb() {
+				return this.bookList.length > 0 ? "300rpx" : "110rpx";
+			},
+			totalBooks() {
+				return this.bookList.reduce((sum, book) => sum + (book.num || 1), 0);
+			},
+			totalPrice() {
+				return this.bookList.reduce((sum, book) => sum + book.recyclePrice * (book.num || 1), 0).toFixed(2);
+			},
+			isDisabled() {
+				return this.totalPrice < this.orderInfo.minOrderMoney;
+			},
+		},
+		onPageScroll(e) {
+			this.$nextTick(() => {
+				this.scrollTop = e.scrollTop;
+			});
+		},
+		onReady() {
+			// 获取屏幕宽度和高度
+			uni.getSystemInfo({
+				success: (res) => {
+					this.screenWidth = res.windowWidth;
+					this.screenHeight = res.windowHeight;
+				}
+			});
+		},
+		methods: {
+			slientLogin() {
+				let inviteCode = wx.getStorageSync('inviteCode') || ''
+				let token = wx.getStorageSync('token')
+				if (token) return;
+				uni.login({
+					success(res) {
+						uni.$u.http
+							.post("/user/wxLogin", {
+								code: res.code,
+								inviteCode,
+							})
+							.then((response) => {
+								if (response.code == 200) {
+									uni.setStorageSync("token", response.data.token);
+								}
+							});
+					},
+					fail: (err) => {
+						console.log(err, "wx.login登录失败");
+					},
+				});
+			},
+			// 触摸开始
+			touchStart(e) {
+				const touch = e.touches[0];
+				this.startX = touch.clientX;
+				this.startY = touch.clientY;
+
+				// 记录初始位置,用于计算移动距离
+				if (this.servicePosition.right !== 'auto') {
+					// 如果是靠右定位,记录当前位置但不立即改变显示位置
+					// 只在内部计算中使用,避免视觉上的位置跳动
+					this.initialLeft = this.screenWidth - 126;
+				} else {
+					this.initialLeft = parseFloat(this.servicePosition.left);
+				}
+
+				// 如果bottom是百分比,转换为具体像素值,但不改变显示位置
+				if (typeof this.servicePosition.bottom === 'string' && this.servicePosition.bottom.includes('%')) {
+					const percentage = parseFloat(this.servicePosition.bottom) / 100;
+					this.initialBottom = this.screenHeight * percentage;
+				} else {
+					this.initialBottom = parseFloat(this.servicePosition.bottom);
+				}
+			},
+
+			// 触摸移动
+			touchMove(e) {
+				// 阻止默认行为,防止页面滚动
+				e.preventDefault && e.preventDefault();
+				e.stopPropagation && e.stopPropagation();
+
+				const touch = e.touches[0];
+
+				// 计算移动距离
+				const deltaX = touch.clientX - this.startX;
+				const deltaY = touch.clientY - this.startY;
+
+				// 使用初始位置计算新位置,避免累积误差
+				let newLeft = this.initialLeft + deltaX;
+				let newBottom = this.initialBottom - deltaY; // 注意:y轴方向是相反的
+
+				// 确保按钮不超出屏幕边界
+				if (newLeft < 0) {
+					newLeft = 0;
+				} else if (newLeft > this.screenWidth - 126) {
+					newLeft = this.screenWidth - 126;
+				}
+
+				// 确保按钮不超出屏幕垂直边界
+				if (newBottom < 20) {
+					newBottom = 20;
+				} else if (newBottom > this.screenHeight - 160) {
+					newBottom = this.screenHeight - 160;
+				}
+
+				// 使用节流方式更新位置,避免过于频繁的更新
+				if (!this.isUpdatingPosition) {
+					this.isUpdatingPosition = true;
+
+					// 更新位置 - 第一次移动时才真正改变right为auto
+					this.servicePosition = {
+						left: newLeft,
+						right: 'auto',
+						bottom: newBottom
+					};
+
+					// 使用setTimeout代替requestAnimationFrame,在微信小程序中更兼容
+					setTimeout(() => {
+						this.isUpdatingPosition = false;
+					}, 16); // 约等于60fps的刷新率
+				}
+
+				// 不更新起始点,保持相对于初始触摸点的位移计算
+				// 这样可以避免累积误差,使拖动更精确
+			},
+
+			// 触摸结束,实现吸附效果
+			touchEnd() {
+				// 确保不再有待处理的更新
+				this.isUpdatingPosition = false;
+
+				const buttonCenter = this.servicePosition.left + 63; // 按钮中心位置
+				const halfScreen = this.screenWidth / 2;
+
+				// 判断是吸附到左边还是右边
+				if (buttonCenter < halfScreen) {
+					// 吸附到左边
+					this.servicePosition = {
+						left: 0,
+						right: 'auto',
+						bottom: this.servicePosition.bottom
+					};
+				} else {
+					// 吸附到右边
+					this.servicePosition = {
+						left: 'auto',
+						right: 0,
+						bottom: this.servicePosition.bottom
+					};
+				}
+			},
+
+			handleStart() {
+				this.showPopup = true;
+			},
+			//套装书确认
+			handleSetBookConfirm() {
+				this.$refs.confirmBooks.openPopup(this.currentBook);
+			},
+			//书册补全
+			handleIncomplete() {
+				this.$refs.scanBookList.handleDeleteBook(this.currentBook);
+			},
+
+			//提交
+			onNext() {
+				let orderId = this.orderInfo.orderId;
+				//预提交
+				uni.$u.http.get("/token/order/preSubmit?orderId=" + orderId).then((res) => {
+					if (res.code == 200) {
+						if (res.data.code == 1 || res.data.code == 2) {
+							uni.navigateTo({
+								url: "/pages-home/pages/book-order",
+							});
+							uni.setStorageSync("orderId", orderId);
+						} else {
+							uni.showToast({
+								icon: "none",
+								title: res.msg,
+							});
+						}
+					} else {
+						uni.showToast({
+							icon: "none",
+							title: res.msg,
+						});
+					}
+				});
+			},
+
+			updateBooksList(data) {
+				this.bookList = data;
+			},
+
+			toggleCollapse(step) {
+				this.$set(this.collapseState, step, !this.collapseState[step]);
+			},
+			handleScan() {
+				uni.scanCode({
+					scanType: ["barCode"],
+					success: (res) => {
+						this.checkBookISBN(res.result);
+					},
+					fail: () => {
+						uni.showToast({
+							title: "扫码失败",
+							icon: "none",
+						});
+					},
+				});
+			},
+			checkBookISBN(isbn) {
+				uni.$u.http.get("/token/order/scanIsbn?isbn=" + isbn).then((res) => {
+					if (res.code == 200) {
+						let code = res.data.code;
+						if (code == 1) {
+							res.data.num = 1;
+							res.data.status = 1;
+							res.data.recyclePrice = res.data.recycleMoney;
+							this.currentBook = res.data;
+							this.bookList.push(res.data);
+							if (res.data.suit == 1) {
+								this.$refs.setBookDialog.openPopup();
+							}
+						} else if (code == 2) {
+							let item = this.bookList.find((v) => v.isbn === isbn);
+							item.num = item.num + 1;
+						} else {
+							this.handleBookCode(res.data.code);
+						}
+					} else {
+						uni.showToast({
+							title: res.msg,
+							icon: "none",
+						});
+					}
+				});
+			},
+			//处理扫码之后不同的状态 0-扫码频繁 1-成功 2-本单已有该书,数量+1  3-没有该书 4-本书暂不回收 5-超过每单最大可卖数量  6-单个订单最多40本书
+			handleBookCode(code) {
+				if (code == 1) {
+					this.bookList.push();
+				}
+				let tempKeys = [
+					"tiredDialog",
+					"",
+					"",
+					"noInfoDialog",
+					"notAcceptDialog",
+					"maxAcceptDialog",
+					"orderMaxNumDialog",
+				];
+				let key = tempKeys[code];
+				if (key) {
+					this.$refs[key].openPopup();
+				}
+			},
+			//获取当前用户未提交订单 /api/token/order/lastOrder
+			getLastOrder() {
+				uni.$u.http.get("/token/order/lastOrder").then((res) => {
+					if (res.code == 200) {
+						this.orderInfo = res.data;
+						if (res.data.showDialog == 1) {
+							this.$refs.firstOrderFreePopup.openPopup();
+						} else if (res.data.showDialog == 2) {
+							this.$refs.kindReminder.openPopup();
+						}
+
+						this.bookList = res.data?.orderDetailList ?
+							res.data.orderDetailList.map((v) => {
+								v.orderId = res.data.orderId;
+								return v;
+							}) : [];
+						this.serviceList = res.data.serviceList || [];
+					}
+				});
+			},
+
+			goToScannedBooks() {
+				uni.navigateTo({
+					url: "/pages-home/pages/scaned-book",
+				});
+			},
+			goToInputISBN() {
+				this.$refs.isbnPopup.openPopup();
+			},
+			handleStartSelling() {
+				// 标记已显示过温馨提示
+				uni.setStorageSync("kindReminderShown", true);
+			},
+		},
+
+		onShow() {
+			// 获取上一个订单
+			setTimeout(() => {
+				this.getLastOrder();
+				setTimeout(() => {
+					this.slientLogin()
+				}, 10)
+			}, 300);
+		},
+	};
 </script>
 
 <style lang="scss" scoped>
-.customer-service {
-    position: fixed;
-    width: 126rpx;
-    height: 140rpx;
-    bottom: 20%;
-    z-index: 999;
-    transition: all 0.3s ease; /* 添加过渡效果使吸附更平滑 */
-    button {
-        height: max-content;
-        background-color: transparent;
-        padding: 0;
-    }
-}
-.container {
-    height: 100%;
-    position: relative;
-    overflow: auto;
-    z-index: 1;
-    /* #ifdef MP-WEIXIN */
-    min-height: 100vh;
-    /* #endif */
-    /* #ifndef MP-WEIXIN */
-    min-height: calc(100vh - 120rpx);
-
-    /* #endif */
-    &.book-list {
-        padding-bottom: 300rpx;
-    }
-
-    padding-bottom: 130rpx;
-
-    .nav-title {
-        font-family: PingFang SC;
-        font-weight: bold;
-        font-size: 34rpx;
-        color: #ffffff;
-        padding-left: 40rpx;
-    }
-}
-
-.common-text {
-    font-family: PingFang SC;
-    font-weight: 500;
-    font-size: 28rpx;
-    color: #999999;
-
-    &.tip {
-        color: #ff8a4b;
-    }
-}
-
-.color-red {
-    color: #ff0000;
-    margin: 0 10rpx;
-}
-
-.bottom-fixed {
-    position: fixed;
-    left: 0;
-    right: 0;
-    bottom: 0;
-    z-index: 9;
-    background-color: #ffffff;
-    /* #ifdef H5 */
-    padding-bottom: 120rpx;
-    /* #endif */
-
-    .btn-wrap {
-        display: flex;
-        gap: 20rpx;
-        padding: 20rpx;
-        padding-bottom: 0;
-
-        button {
-            flex: 1;
-            height: 88rpx;
-            border-radius: 10rpx;
-            display: flex;
-            align-items: center;
-            justify-content: center;
-            gap: 10rpx;
-            border: none;
-
-            text {
-                font-size: 32rpx;
-            }
-
-            &::after {
-                border: none;
-            }
-        }
-
-        .isbn-btn {
-            background-color: #ffffff;
-            color: #4cd964;
-            border: 3rpx solid #4cd964;
-        }
-    }
-
-    .scan-btn {
-        background-color: #4cd964;
-        color: #ffffff;
-    }
-
-    .next-btn {
-        margin: 0;
-        margin-left: 20rpx;
-
-        &[aria-disabled="true"] {
-            background-color: #cccccc;
-            color: #ffffff;
-            opacity: 0.7;
-            cursor: not-allowed;
-        }
-    }
-}
-</style>
+	.customer-service {
+		position: fixed;
+		width: 126rpx;
+		height: 140rpx;
+		bottom: 20%;
+		z-index: 999;
+		transition: all 0.3s ease;
+
+		/* 添加过渡效果使吸附更平滑 */
+		button {
+			height: max-content;
+			background-color: transparent;
+			padding: 0;
+		}
+	}
+
+	.container {
+		height: 100%;
+		position: relative;
+		overflow: auto;
+		z-index: 1;
+		/* #ifdef MP-WEIXIN */
+		min-height: 100vh;
+		/* #endif */
+		/* #ifndef MP-WEIXIN */
+		min-height: calc(100vh - 120rpx);
+
+		/* #endif */
+		&.book-list {
+			padding-bottom: 300rpx;
+		}
+
+		padding-bottom: 130rpx;
+
+		.nav-title {
+			font-family: PingFang SC;
+			font-weight: bold;
+			font-size: 34rpx;
+			color: #ffffff;
+			padding-left: 40rpx;
+		}
+	}
+
+	.common-text {
+		font-family: PingFang SC;
+		font-weight: 500;
+		font-size: 28rpx;
+		color: #999999;
+
+		&.tip {
+			color: #ff8a4b;
+		}
+	}
+
+	.color-red {
+		color: #ff0000;
+		margin: 0 10rpx;
+	}
+
+	.bottom-fixed {
+		position: fixed;
+		left: 0;
+		right: 0;
+		bottom: 0;
+		z-index: 9;
+		background-color: #ffffff;
+		/* #ifdef H5 */
+		padding-bottom: 120rpx;
+		/* #endif */
+
+		.btn-wrap {
+			display: flex;
+			gap: 20rpx;
+			padding: 20rpx;
+			padding-bottom: 0;
+
+			button {
+				flex: 1;
+				height: 88rpx;
+				border-radius: 10rpx;
+				display: flex;
+				align-items: center;
+				justify-content: center;
+				gap: 10rpx;
+				border: none;
+
+				text {
+					font-size: 32rpx;
+				}
+
+				&::after {
+					border: none;
+				}
+			}
+
+			.isbn-btn {
+				background-color: #ffffff;
+				color: #4cd964;
+				border: 3rpx solid #4cd964;
+			}
+		}
+
+		.scan-btn {
+			background-color: #4cd964;
+			color: #ffffff;
+		}
+
+		.next-btn {
+			margin: 0;
+			margin-left: 20rpx;
+
+			&[aria-disabled="true"] {
+				background-color: #cccccc;
+				color: #ffffff;
+				opacity: 0.7;
+				cursor: not-allowed;
+			}
+		}
+	}
+</style>