<template>
|
<view class="hall-page">
|
<view class="hall-page__header" :style="{ paddingTop: statusBarHeight + 'px' }">
|
<view class="hall-page__user-row" @click="handleUserClick">
|
<view class="hall-page__user">
|
<image class="hall-page__avatar" :src="centerUserInfo.fullImgUrl || '/static/image/ic_pic@2x.png'" mode="aspectFill"></image>
|
<text class="hall-page__name">{{ centerUserInfo.name }}</text>
|
</view>
|
<view class="hall-page__status" v-if="hasApprovedOfficial" @click="openStatusPicker">
|
<view class="hall-page__status-dot" :class="{ 'hall-page__status-dot--offline': acceptingStatus === 0 }"></view>
|
<text class="hall-page__status-text">{{ acceptingStatus === 1 ? '接单中' : '已下线' }}</text>
|
<text class="hall-page__status-arrow">▼</text>
|
</view>
|
<view class="hall-page__user" style="opacity: 0;">
|
<image class="hall-page__avatar" :src="centerUserInfo.fullImgUrl || '/static/image/ic_pic@2x.png'" mode="aspectFill"></image>
|
<text class="hall-page__name">{{ centerUserInfo.name }}</text>
|
</view>
|
</view>
|
|
<view class="hall-page__stats">
|
<view v-for="item in stats" :key="item.label" class="hall-page__stat-item">
|
<text class="hall-page__stat-value">{{ hasApprovedOfficial ? item.value : '-' }}</text>
|
<text class="hall-page__stat-label">{{ item.label }}</text>
|
</view>
|
</view>
|
|
<view class="hall-page__tabs">
|
<view v-for="tab in displayTabs" :key="tab.value" class="hall-page__tab" :class="{ 'hall-page__tab--active': activeTab === tab.value }" @click="activeTab = tab.value">
|
<text class="hall-page__tab-text">{{ tab.label }}</text>
|
<text v-if="tab.count" class="hall-page__tab-count">{{ hasApprovedOfficial ? tab.count : '' }}</text>
|
<view v-if="activeTab === tab.value" class="hall-page__tab-line"></view>
|
</view>
|
<view class="hall-page__filter" @click="toggleFilterPopup(true)">
|
<text class="hall-page__filter-text" :class="{ 'hall-page__filter-text--active': showFilterPopup }">筛选</text>
|
<image :src="showFilterPopup ? '/static/image/ic_shaixuan_sel@2x.png' : '/static/image/ic_shaixuan@2x.png'" mode="widthFix" class="hall-page__filter-icon"></image>
|
</view>
|
</view>
|
</view>
|
|
<view v-if="showFilterPopup" class="filter-popup" :style="{ top: headerHeight + 'px', bottom: tabbarHeight + 'px' }" @click="toggleFilterPopup(false)">
|
<view class="filter-popup__panel" @click.stop>
|
<scroll-view class="filter-popup__content" scroll-y>
|
<view v-for="section in filterSections" :key="section.key" class="filter-popup__section">
|
<text class="filter-popup__title">{{ section.title }}</text>
|
<view class="filter-popup__options">
|
<view
|
v-for="option in section.options"
|
:key="option"
|
class="filter-popup__option"
|
:class="{ 'filter-popup__option--active': selectedFilters[section.key] === option }"
|
@click="selectFilter(section.key, option)"
|
>
|
<text class="filter-popup__option-text">{{ option }}</text>
|
</view>
|
</view>
|
</view>
|
</scroll-view>
|
|
<view class="filter-popup__actions">
|
<button class="filter-popup__button filter-popup__button--reset" hover-class="filter-popup__button--hover" @click="resetFilters">重置</button>
|
<button class="filter-popup__button filter-popup__button--confirm" hover-class="filter-popup__button--hover" @click="confirmFilters">确认</button>
|
</view>
|
</view>
|
</view>
|
|
<scroll-view class="hall-page__body" scroll-y :style="bodyStyle" @scrolltolower="handleScrollToLower">
|
<view class="hall-page__verified" v-if="!hasApprovedOfficial">
|
<image src="/static/image/default_unverified@2x.png" mode="widthFix"></image>
|
<button @click="toDriverCertification">去认证</button>
|
</view>
|
<view v-else-if="hasApprovedOfficial && acceptingStatus === 1 && currentOrderList.length" class="hall-page__list">
|
<view v-for="(item, index) in currentOrderList" :key="item.id" class="order-card" @click="goToOrderDetail(item, index)">
|
<view class="order-card__head">
|
<view class="order-card__time" v-if="item.remainMinutes > 0">
|
<text class="order-card__time-main">{{ formatRemainTime(item.remainMinutes) }}</text>
|
<text class="order-card__time-sub">送达</text>
|
</view>
|
<view class="order-card__time" v-else>
|
<text class="order-card__time-main">配送已超时,请尽快送达</text>
|
</view>
|
<view v-if="activeTab === 'hall'" class="order-card__price-wrap">
|
<text class="order-card__price">¥{{ item.platformRewardAmount ? (item.driverFee + item.platformRewardAmount) / 100 : (item.driverFee / 100).toFixed(2) }}</text>
|
</view>
|
<view v-else class="order-card__price-wrap order-card__price-wrap--serial-only">
|
<text v-if="item.code" class="order-card__serial">#{{ index + 1 }}</text>
|
</view>
|
</view>
|
|
<view class="order-card__meta">
|
<view class="order-card__tags">
|
<image v-if="item.isUrgent === 1" class="order-card__tag-img" src="/static/image/ic_jisuda@2x.png" mode="widthFix"></image>
|
<image v-else class="order-card__tag-img" src="/static/image/ic_biaosuda@2x.png" mode="widthFix"></image>
|
<text v-if="item.isValuable === true" class="order-card__tag order-card__tag--orange">贵重物品</text>
|
<text v-else class="order-card__tag order-card__tag--blue">{{ item.goodLevelName }}</text>
|
</view>
|
<text v-if="activeTab === 'hall' && item.platformRewardAmount" class="order-card__extra">含加急¥{{ (item.platformRewardAmount / 100).toFixed(2) }}</text>
|
</view>
|
|
<view class="order-card__route">
|
<view class="order-card__route-side">
|
<view class="order-card__distance-block order-card__distance-block--top">
|
<text class="order-card__distance-value">{{ formatDistanceParts(item.depositDistance).value }}</text>
|
<text class="order-card__distance-unit">{{ formatDistanceParts(item.depositDistance).unit }}</text>
|
</view>
|
<view class="order-card__line"></view>
|
<view class="order-card__distance-block order-card__distance-block--bottom">
|
<text class="order-card__distance-value">{{ formatDistanceParts(item.takeDistance).value }}</text>
|
<text class="order-card__distance-unit">{{ formatDistanceParts(item.takeDistance).unit }}</text>
|
</view>
|
</view>
|
<view class="order-card__route-main">
|
<view class="order-card__route-item">
|
<view class="order-card__route-texts">
|
<text class="order-card__route-title"><text class="order-card__route-badge-text order-card__route-badge-text--take">取</text>{{ item.depositShopName }}</text>
|
<text class="order-card__route-desc">{{ item.depositShopAddress }}</text>
|
</view>
|
<image src="/static/image/ic_daohang@2x.png" mode="widthFix" class="order-card__nav" @click.stop="navigateToAddress(item, 'deposit')"></image>
|
</view>
|
<view class="order-card__route-item order-card__route-item--destination">
|
<view class="order-card__route-texts">
|
<template v-if="item.takeShopId">
|
<text class="order-card__route-title"><text class="order-card__route-badge-text order-card__route-badge-text--send">送</text>{{ item.takeName }}</text>
|
<text class="order-card__route-desc">{{ item.takeAddress }}</text>
|
</template>
|
<text v-else class="order-card__route-title"><text class="order-card__route-badge-text order-card__route-badge-text--send">送</text>{{ item.takeAddress }}</text>
|
</view>
|
<image src="/static/image/ic_daohang@2x.png" mode="widthFix" class="order-card__nav" @click.stop="navigateToAddress(item, 'take')"></image>
|
</view>
|
</view>
|
</view>
|
|
<view class="order-card__goods" v-if="item.items && item.items.length > 0" @click.stop="toggleGoodsExpand(item.id)">
|
<text class="order-card__goods-text">{{ getGoodsText(item.items, item.id) }}</text>
|
<u-icon v-if="getGoodsText(item.items, item.id).length > 20" name="arrow-down" :class="{ 'order-card__goods-arrow--expanded': expandedGoodsIds.includes(item.id) }" size="12" color="#a4a9b1"></u-icon>
|
</view>
|
|
<view class="order-card__actions" :class="'order-card__actions--' + activeTab">
|
<template v-if="activeTab === 'pickup'">
|
<view class="order-card__icon-actions">
|
<view class="order-card__icon-action" @click.stop="handleCancelOrder(item)">
|
<image class="order-card__action-icon" src="/static/image/ic_cancle@2x.png" mode="aspectFit"></image>
|
<text class="order-card__action-text">取消</text>
|
</view>
|
<view class="order-card__icon-action" @click.stop="handleCall(item)">
|
<image class="order-card__action-icon" src="/static/image/ic_call@2x.png" mode="aspectFit"></image>
|
<text class="order-card__action-text">联系</text>
|
</view>
|
</view>
|
<button class="order-card__button order-card__button--code" hover-class="order-card__button--hover" @click.stop="handleShowPickupCode(item)">取货码</button>
|
</template>
|
<template v-else-if="activeTab === 'delivering'">
|
<view class="order-card__icon-actions order-card__icon-actions--single">
|
<view class="order-card__icon-action" @click.stop="handleCall(item)">
|
<image class="order-card__action-icon" src="/static/image/ic_call@2x.png" mode="aspectFit"></image>
|
<text class="order-card__action-text">联系</text>
|
</view>
|
</view>
|
<button class="order-card__button order-card__button--code" hover-class="order-card__button--hover" @click.stop="handleShowPickupCode(item)" v-if="item.takeShopId">存件码</button>
|
</template>
|
<button v-else class="order-card__button" hover-class="order-card__button--hover" @click.stop="handleGrabOrder(item)">立即抢单</button>
|
</view>
|
</view>
|
</view>
|
|
<view v-else class="hall-page__empty">
|
<image class="hall-page__empty-icon" :src="acceptingStatus === 0 ? '/static/image/default_nodata_grey@2x.png' : '/static/image/default_nodata@2x.png'" mode="aspectFit"></image>
|
</view>
|
</scroll-view>
|
|
<!-- 取消订单 -->
|
<u-modal
|
:show="show"
|
showCancelButton
|
@cancel="show = false"
|
cancelColor="#666666"
|
confirmColor="#0055FF"
|
title="取消订单确认"
|
@confirm="confirmCancelOrder">
|
<view style="text-align: center;color: #333333;font-size: 28rpx;font-weight: 400;">
|
您今日还可取消 {{ cancelRemain }} 次订单,次数用尽后今日将无法接单,是否确认取消?
|
</view>
|
</u-modal>
|
|
<!-- 立即抢单 -->
|
<u-modal
|
:show="showGrabModal"
|
showCancelButton
|
@cancel="showGrabModal = false"
|
cancelColor="#666666"
|
confirmColor="#0055FF"
|
title="温馨提示"
|
@confirm="confirmGrabOrder">
|
<view style="text-align: center;color: #333333;font-size: 28rpx;font-weight: 400;">
|
{{ selectedGrabOrder && selectedGrabOrder.hasOversized === 1 ? '本订单有特大件尺寸行李,请确认是否继续抢单?' : '是否确认接单?' }}
|
</view>
|
</u-modal>
|
|
<!-- 取货码/存件码 -->
|
<u-popup :show="show1" round="20" mode="bottom">
|
<view class="qrcode">
|
<view class="qrcode-title">
|
<image src="/static/image/ic_close@2x.png" mode="widthFix" style="opacity: 0;"></image>
|
<text>{{ activeTab === 'delivering' ? '存件码' : '取货码' }}</text>
|
<image src="/static/image/ic_close@2x.png" mode="widthFix" @click="show1 = false"></image>
|
</view>
|
<view class="qrcode-image">
|
<image v-if="selectedPickupOrder && selectedPickupOrder.driverVerifyCode" :src="'https://api.qrserver.com/v1/create-qr-code/?size=200x200&data=' + selectedPickupOrder.driverVerifyCode" mode="widthFix"></image>
|
</view>
|
<view class="qrcode-btn" hover-class="qrcode-btn--hover" @click="show1 = false">关闭</view>
|
</view>
|
</u-popup>
|
|
<u-popup :show="showPhotoDeliverPopup" round="20" mode="bottom">
|
<view class="photo-deliver">
|
<view class="photo-deliver__header">
|
<image class="photo-deliver__close-placeholder" mode="aspectFit"></image>
|
<text class="photo-deliver__title">拍照送达</text>
|
<image class="photo-deliver__close" mode="aspectFit" @click="showPhotoDeliverPopup = false"></image>
|
</view>
|
|
<view class="photo-deliver__section">
|
<view class="photo-deliver__label-row">
|
<text class="photo-deliver__label">拍摄送达照片</text>
|
<text class="photo-deliver__required">*</text>
|
<text class="photo-deliver__hint">最多3张照片</text>
|
</view>
|
|
<view class="photo-deliver__photos">
|
<view class="photo-deliver__upload-card">
|
<image class="photo-deliver__upload-icon" mode="aspectFit"></image>
|
<text class="photo-deliver__upload-text">点击拍照</text>
|
</view>
|
|
<view class="photo-deliver__preview-card">
|
<image class="photo-deliver__preview-image" mode="aspectFill"></image>
|
<view class="photo-deliver__preview-mask">
|
<text class="photo-deliver__preview-delete">删除</text>
|
</view>
|
</view>
|
</view>
|
</view>
|
|
<view class="photo-deliver__section photo-deliver__section--remark">
|
<text class="photo-deliver__remark-title">备注信息</text>
|
<textarea class="photo-deliver__textarea" maxlength="200" placeholder="请输入" placeholder-style="color: #c7cbd3;" />
|
</view>
|
|
<button class="photo-deliver__submit" hover-class="photo-deliver__submit--hover" @click="showPhotoDeliverPopup = false">确认送达</button>
|
</view>
|
</u-popup>
|
|
<u-picker
|
:show="showStatusPicker"
|
confirmColor="#10B2FA"
|
keyName="text"
|
:columns="[statusOptions]"
|
@confirm="confirmStatus"
|
@cancel="showStatusPicker = false" />
|
</view>
|
</template>
|
|
<script>
|
import { mapState } from 'vuex'
|
export default {
|
data() {
|
return {
|
tts: null,
|
show: false,
|
show1: false,
|
showGrabModal: false,
|
selectedGrabOrder: null,
|
selectedCancelOrder: null,
|
cancelRemain: 0,
|
selectedPickupOrder: null,
|
showPhotoDeliverPopup: false,
|
routeInfo: null,
|
statusBarHeight: 0,
|
headerHeight: 0,
|
tabbarHeight: 0,
|
scrollHeight: 0,
|
showFilterPopup: false,
|
acceptingStatus: 0,
|
showStatusPicker: false,
|
hasApprovedOfficial: false,
|
statusOptions: [
|
{ text: '上线', value: 1 },
|
{ text: '下线', value: 0 }
|
],
|
centerUserInfo: {},
|
activeTab: 'hall',
|
expandedGoodsIds: [],
|
categoryList: [],
|
filterSections: [
|
{ key: 'sort', title: '排序', options: ['综合排序', '距离最近'] },
|
{ key: 'level', title: '物品等级', options: ['不限'] },
|
{ key: 'distance', title: '位置范围', options: ['不限', '500m', '1km', '2km', '3km', '4km', '5km', '6km', '7km'] }
|
],
|
selectedFilters: {
|
sort: '综合排序',
|
level: '不限',
|
distance: '不限'
|
},
|
stats: [
|
{ value: '-', label: '服务分' },
|
{ value: '-', label: '今日预计佣金' },
|
{ value: '-', label: '今日接单' }
|
],
|
tabs: [
|
{ label: '抢单大厅', value: 'hall' },
|
{ label: '待取货', value: 'pickup' },
|
{ label: '配送中', value: 'delivering' }
|
],
|
orderList: [],
|
pickupOrderList: [],
|
deliveringOrderList: [],
|
hallPage: 1,
|
hallPageSize: 10,
|
hallLoading: false,
|
hallHasMore: true,
|
pickupLoading: false,
|
deliveringLoading: false,
|
activeOrderCount: null
|
}
|
},
|
|
watch: {
|
activeTab(newVal) {
|
this.loadOrdersByTab(newVal)
|
}
|
},
|
|
onLoad() {
|
const systemInfo = uni.getSystemInfoSync()
|
const safeBottom = systemInfo.safeAreaInsets ? systemInfo.safeAreaInsets.bottom || 0 : 0
|
const windowHeight = systemInfo.windowHeight || 0
|
this.statusBarHeight = systemInfo.statusBarHeight || 0
|
this.headerHeight = this.statusBarHeight + uni.upx2px(308)
|
this.tabbarHeight = uni.upx2px(100) + safeBottom
|
this.scrollHeight = Math.max(windowHeight - this.headerHeight, 0)
|
if (this.userInfo.auditStatus === 99) return;
|
this.acceptingStatus = this.userInfo.acceptingStatus || 0
|
this.$u.api.centerInfo().then(res => {
|
if (res.code === 200) {
|
this.acceptingStatus = res.data.acceptingStatus
|
if (res.data.acceptingStatus === 1) {
|
this.loadOrdersByTab(this.activeTab)
|
}
|
}
|
})
|
uni.$on('jiedanSuccess', () => {
|
this.loadOrdersByTab(this.activeTab)
|
})
|
},
|
|
onShow() {
|
this.getCenterInfo()
|
this.getCategoryListData()
|
this.getActiveOrderCount()
|
this.getUserInfoDetail()
|
},
|
|
computed: {
|
...mapState(['userInfo', 'token']),
|
|
displayTabs() {
|
return this.tabs.map(tab => {
|
if (tab.value === 'pickup') {
|
return { ...tab, count: this.activeOrderCount?.grabbedCount }
|
} else if (tab.value === 'delivering') {
|
return { ...tab, count: this.activeOrderCount?.deliveringCount }
|
}
|
return tab
|
})
|
},
|
|
currentOrderList() {
|
const orderMap = {
|
hall: this.orderList,
|
pickup: this.pickupOrderList,
|
delivering: this.deliveringOrderList
|
}
|
|
return orderMap[this.activeTab] || []
|
},
|
|
bodyStyle() {
|
return {
|
marginTop: this.headerHeight + 'px',
|
height: this.scrollHeight + 'px'
|
}
|
}
|
},
|
|
onReady() {
|
this.initTTS() // 页面渲染完成初始化语音
|
},
|
|
methods: {
|
handleScrollToLower() {
|
if (this.acceptingStatus === 0) return;
|
this.hallPage++
|
if (this.activeTab === 'hall') {
|
console.log('hall')
|
this.getHallOrders()
|
} else if (this.activeTab === 'pickup') {
|
this.getPickupOrders()
|
} else if (this.activeTab === 'delivering') {
|
this.getDeliveringOrders()
|
}
|
},
|
getUserInfoDetail() {
|
this.$u.api.verifyDetail().then(res => {
|
if (res.code === 200) {
|
this.hasApprovedOfficial = res.data.hasApprovedOfficial === true
|
}
|
})
|
},
|
formatRemainTime(minutes) {
|
if (!minutes) return 0
|
if (minutes === 0) {
|
return '配送已超时'
|
}
|
if (minutes >= 60) {
|
return (minutes / 60).toFixed(2) + '小时内'
|
}
|
return minutes + '分钟内'
|
},
|
|
getGoodsText(items, itemId) {
|
if (!items || items.length === 0) return '无'
|
const text = items.map(i => `${i.name}*${i.quantity}`).join('、')
|
if (text.length > 20 && !this.expandedGoodsIds.includes(itemId)) {
|
return text.substring(0, 20) + '...'
|
}
|
return text
|
},
|
|
toggleGoodsExpand(id) {
|
const index = this.expandedGoodsIds.indexOf(id)
|
if (index > -1) {
|
this.expandedGoodsIds.splice(index, 1)
|
} else {
|
this.expandedGoodsIds.push(id)
|
}
|
},
|
|
formatDistanceParts(distance) {
|
if (distance === null || distance === undefined || distance === '') {
|
return { value: '--', unit: '' }
|
}
|
|
if (typeof distance === 'number') {
|
if (distance >= 1000) {
|
return { value: (distance / 1000).toFixed(1), unit: 'km' }
|
}
|
return { value: String(Math.round(distance)), unit: 'm' }
|
}
|
|
const text = String(distance).trim()
|
const match = text.match(/^([\d.]+)\s*([a-zA-Z\u4e00-\u9fa5]*)$/)
|
if (match) {
|
return {
|
value: match[1],
|
unit: match[2] || ''
|
}
|
}
|
|
return { value: text, unit: '' }
|
},
|
|
navigateToAddress(item, type) {
|
let latitude, longitude, name, address
|
if (type === 'deposit') {
|
latitude = item.depositLat
|
longitude = item.depositLng
|
name = item.depositShopName
|
address = item.depositShopAddress
|
} else {
|
latitude = item.takeLat
|
longitude = item.takeLng
|
name = item.takeName
|
address = item.takeAddress
|
}
|
if (!latitude || !longitude) {
|
uni.showToast({ title: '地址坐标缺失', icon: 'none' })
|
return
|
}
|
uni.openLocation({
|
latitude,
|
longitude,
|
name,
|
address,
|
success: () => {},
|
fail: (err) => {
|
uni.showToast({ title: '打开地图失败', icon: 'none' })
|
console.error('openLocation fail:', err)
|
}
|
})
|
},
|
|
handleUserClick() {
|
uni.navigateTo({
|
url: '/pages/test/test'
|
})
|
},
|
getActiveOrderCount() {
|
this.$u.api.activeOrderCount().then(res => {
|
if (res.code === 200) {
|
this.activeOrderCount = res.data
|
}
|
}).catch((err) => {
|
this.activeOrderCount = null
|
})
|
},
|
|
handleGrabOrder(item) {
|
console.log(item)
|
this.selectedGrabOrder = item
|
this.showGrabModal = true
|
},
|
|
confirmGrabOrder() {
|
if (!this.selectedGrabOrder) return
|
this.$u.api.grabOrder({ orderId: this.selectedGrabOrder.id }).then(res => {
|
this.showGrabModal = false
|
if (res.code === 200) {
|
uni.showToast({ title: '抢单成功', icon: 'success' })
|
this.hallPage = 1
|
this.hallHasMore = true
|
this.orderList = []
|
this.getHallOrders()
|
this.getActiveOrderCount()
|
this.getCenterInfo()
|
} else {
|
uni.showToast({ title: res.message || '抢单失败', icon: 'none' })
|
}
|
}).catch(() => {
|
this.showGrabModal = false
|
})
|
},
|
|
handleCancelOrder(item) {
|
this.selectedCancelOrder = item
|
this.$u.api.cancelLimit().then(res => {
|
if (res.code === 200) {
|
this.cancelRemain = res.data.remain
|
}
|
}).finally(() => {
|
this.show = true
|
})
|
},
|
|
confirmCancelOrder() {
|
if (!this.selectedCancelOrder) return
|
this.$u.api.cancelOrder({ orderId: this.selectedCancelOrder.id }).then(res => {
|
this.show = false
|
if (res.code === 200) {
|
uni.showToast({ title: '取消成功', icon: 'success' })
|
this.getPickupOrders()
|
this.getCenterInfo()
|
this.getActiveOrderCount()
|
} else {
|
uni.showToast({ title: res.message || '取消失败', icon: 'none' })
|
}
|
}).catch(() => {
|
this.show = false
|
})
|
},
|
|
handleCall(item) {
|
if (item.contactPhone) {
|
uni.makePhoneCall({
|
phoneNumber: item.contactPhone
|
})
|
}
|
},
|
|
handleShowPickupCode(item) {
|
this.selectedPickupOrder = item
|
this.show1 = true
|
},
|
|
goToOrderDetail(item, index) {
|
let url = `/pages/order-detail/order-detail?id=${item.id}`
|
if (this.activeTab === 'pickup' || this.activeTab === 'delivering') {
|
url += `&index=${index + 1}`
|
}
|
uni.navigateTo({ url })
|
},
|
|
getCenterInfo() {
|
this.$u.api.centerInfo().then(res => {
|
if (res.code === 200) {
|
this.acceptingStatus = res.data.acceptingStatus
|
this.centerUserInfo = {
|
fullImgUrl: res.data.fullImgUrl,
|
name: res.data.name
|
}
|
this.stats = [
|
{ value: res.data.score, label: '服务分' },
|
{ value: ((res.data.todayCommission / 100) || 0).toFixed(2), label: '今日预计佣金' },
|
{ value: res.data.todayOrderCount, label: '今日接单' }
|
]
|
}
|
})
|
},
|
|
getCategoryListData() {
|
this.$u.api.getCategoryList({ type: 3 }).then(res => {
|
if (res.code === 200) {
|
this.categoryList = res.data || []
|
this.filterSections.forEach(section => {
|
if (section.key === 'level') {
|
section.options = ['不限', ...this.categoryList.map(item => item.name)]
|
}
|
})
|
}
|
})
|
},
|
|
loadOrdersByTab(tab) {
|
if (this.userInfo.auditStatus === 99) return;
|
if (this.acceptingStatus === 0) return;
|
if (tab === 'hall') {
|
this.hallPage = 1
|
this.hallHasMore = true
|
this.orderList = []
|
this.getHallOrders()
|
} else if (tab === 'pickup') {
|
this.pickupOrderList = []
|
this.getPickupOrders()
|
} else if (tab === 'delivering') {
|
this.deliveringOrderList = []
|
this.getDeliveringOrders()
|
}
|
},
|
|
getHallOrders() {
|
if (this.acceptingStatus === 0) return;
|
if (this.hallLoading || !this.hallHasMore) {
|
return
|
}
|
this.hallLoading = true
|
|
let distance = null
|
if (this.selectedFilters.distance !== '不限') {
|
const distanceText = this.selectedFilters.distance
|
if (distanceText.includes('km')) {
|
distance = parseInt(distanceText) * 1000
|
} else {
|
distance = parseInt(distanceText)
|
}
|
}
|
|
const sortTypeMap = {
|
'综合排序': 1,
|
'距离最近': 2
|
}
|
const sortType = this.selectedFilters.sort !== '不限' ? (sortTypeMap[this.selectedFilters.sort] || null) : null
|
|
let gradeId = null
|
if (this.selectedFilters.level !== '不限') {
|
const selectedCategory = this.categoryList.find(item => item.name === this.selectedFilters.level)
|
if (selectedCategory) {
|
gradeId = selectedCategory.id
|
}
|
}
|
|
console.log('接单大厅:', { distance, gradeId, sortType })
|
this.$u.api.grabOrderHall({
|
capacity: this.hallPageSize,
|
page: this.hallPage,
|
model: {
|
distance: distance,
|
gradeId: gradeId,
|
sortType: sortType
|
}
|
}).then(res => {
|
console.log('接单大厅', res)
|
this.hallLoading = false
|
if (res.code === 200) {
|
const list = res.data.records || []
|
this.orderList = this.hallPage === 1 ? list : this.orderList.concat(list)
|
this.hallHasMore = list.length >= this.hallPageSize
|
}
|
}).finally(() => {
|
this.hallLoading = false
|
})
|
},
|
|
getPickupOrders() {
|
if (this.acceptingStatus === 0) return;
|
if (this.pickupLoading) return
|
this.pickupLoading = true
|
this.$u.api.activeOrders({ status: 3 }).then(res => {
|
console.log('待取货:', res)
|
this.pickupLoading = false
|
if (res.code === 200) {
|
this.pickupOrderList = res.data.records || res.data || []
|
}
|
}).catch((err) => {
|
this.pickupLoading = false
|
})
|
},
|
|
getDeliveringOrders() {
|
if (this.acceptingStatus === 0) return;
|
if (this.deliveringLoading) return
|
this.deliveringLoading = true
|
this.$u.api.activeOrders({ status: 4 }).then(res => {
|
console.log('配送中:', res)
|
this.deliveringLoading = false
|
if (res.code === 200) {
|
this.deliveringOrderList = res.data || []
|
}
|
}).catch((err) => {
|
this.deliveringLoading = false
|
})
|
},
|
|
openStatusPicker() {
|
this.showStatusPicker = true
|
},
|
|
confirmStatus(e) {
|
this.showStatusPicker = false
|
const selectedValue = e.value[0]
|
this.$u.api.updateAcceptingStatus({ status: selectedValue.value }).then(res => {
|
if (res.code === 200) {
|
this.acceptingStatus = selectedValue.value
|
this.getCenterInfo()
|
if (this.acceptingStatus === 0) {
|
this.orderList = []
|
this.pickupOrderList = []
|
this.deliveringOrderList = []
|
} else {
|
if (this.activeTab === 'pickup') {
|
this.getPickupOrders()
|
} else if (this.activeTab === 'delivering') {
|
this.getDeliveringOrders()
|
} else {
|
this.hallPage = 1
|
this.hallHasMore = true
|
this.orderList = []
|
this.getHallOrders()
|
}
|
}
|
}
|
})
|
},
|
|
toDriverCertification() {
|
uni.navigateTo({
|
url: '/pages/driver-certification/driver-certification'
|
})
|
},
|
|
toggleFilterPopup(show) {
|
this.showFilterPopup = show
|
},
|
|
selectFilter(key, option) {
|
this.selectedFilters = {
|
...this.selectedFilters,
|
[key]: option
|
}
|
},
|
|
resetFilters() {
|
this.showFilterPopup = false
|
if (this.userInfo.auditStatus === 99) return;
|
this.selectedFilters = {
|
sort: '综合排序',
|
level: '不限',
|
distance: '不限'
|
}
|
if (this.activeTab === 'hall') {
|
this.hallPage = 1
|
this.hallHasMore = true
|
this.orderList = []
|
this.getHallOrders()
|
}
|
},
|
|
confirmFilters() {
|
this.showFilterPopup = false
|
if (this.userInfo.auditStatus === 99) {
|
this.hallHasMore = true
|
return
|
}
|
if (this.activeTab === 'hall') {
|
this.hallPage = 1
|
this.hallHasMore = true
|
this.orderList = []
|
this.getHallOrders()
|
}
|
},
|
|
initTTS() {
|
if (uni.getSystemInfoSync().platform !== 'android') {
|
console.log('仅支持安卓')
|
return
|
}
|
|
try {
|
// 导入安卓原生类
|
const TextToSpeech = plus.android.importClass('android.speech.tts.TextToSpeech')
|
const Locale = plus.android.importClass('java.util.Locale')
|
|
// 创建TTS
|
this.tts = new TextToSpeech(plus.android.runtimeMainActivity(), {
|
onInit: (status) => {
|
if (status == 0) {
|
// 设置中文
|
this.tts.setLanguage(Locale.CHINA)
|
console.log('语音初始化成功')
|
}
|
}
|
})
|
} catch (e) {
|
console.log('初始化失败', e)
|
}
|
},
|
|
speak(text) {
|
if (!this.tts) {
|
uni.showToast({
|
title: '语音未准备好',
|
icon: 'none'
|
})
|
return
|
}
|
|
try {
|
// 安卓原生播报(QUEUE_FLUSH = 立即播报,打断上一条)
|
this.tts.speak(text, 0, null)
|
} catch (err) {
|
console.log('播报失败', err)
|
}
|
},
|
|
stopSpeak() {
|
if (this.tts) this.tts.stop()
|
}
|
},
|
|
onUnload() {
|
if (this.tts) {
|
this.tts.stop()
|
this.tts.shutdown()
|
}
|
}
|
}
|
</script>
|
|
<style lang="scss" scoped>
|
.hall-page {
|
position: relative;
|
height: 100vh;
|
background: #f5f6f8;
|
overflow: hidden;
|
|
.qrcode {
|
padding: 36rpx 30rpx;
|
box-sizing: border-box;
|
.qrcode-title {
|
width: 100%;
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
image {
|
width: 28rpx;
|
height: 28rpx;
|
}
|
text {
|
font-weight: 600;
|
font-size: 32rpx;
|
color: #111111;
|
}
|
}
|
.qrcode-image {
|
width: 100%;
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
margin-top: 60rpx;
|
image {
|
width: 400rpx;
|
height: 400rpx;
|
}
|
}
|
.qrcode-btn {
|
width: 100%;
|
height: 88rpx;
|
line-height: 88rpx;
|
text-align: center;
|
background: #106EFA;
|
border-radius: 50rpx;
|
font-weight: bold;
|
font-size: 32rpx;
|
color: #FFFFFF;
|
margin-top: 68rpx;
|
|
&--hover {
|
opacity: 0.92;
|
transform: translateY(2rpx);
|
}
|
}
|
}
|
|
.photo-deliver {
|
padding: 32rpx 28rpx calc(env(safe-area-inset-bottom) + 28rpx);
|
background: #ffffff;
|
box-sizing: border-box;
|
border-top-left-radius: 20rpx;
|
border-top-right-radius: 20rpx;
|
overflow: hidden;
|
|
&__header {
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
}
|
|
&__title {
|
font-size: 34rpx;
|
font-weight: 700;
|
color: #111111;
|
}
|
|
&__close,
|
&__close-placeholder {
|
width: 36rpx;
|
height: 36rpx;
|
flex-shrink: 0;
|
}
|
|
&__close-placeholder {
|
opacity: 0;
|
}
|
|
&__section {
|
margin-top: 56rpx;
|
|
&--remark {
|
margin-top: 46rpx;
|
}
|
}
|
|
&__label-row {
|
display: flex;
|
align-items: center;
|
flex-wrap: wrap;
|
}
|
|
&__label,
|
&__remark-title {
|
font-size: 28rpx;
|
font-weight: 700;
|
color: #23262d;
|
}
|
|
&__required {
|
margin-left: 4rpx;
|
font-size: 28rpx;
|
font-weight: 700;
|
color: #ff3b30;
|
}
|
|
&__hint {
|
margin-left: 12rpx;
|
font-size: 24rpx;
|
color: #a8adb7;
|
}
|
|
&__photos {
|
display: flex;
|
gap: 18rpx;
|
margin-top: 30rpx;
|
}
|
|
&__upload-card,
|
&__preview-card {
|
position: relative;
|
width: 160rpx;
|
height: 160rpx;
|
border-radius: 8rpx;
|
overflow: hidden;
|
}
|
|
&__upload-card {
|
display: flex;
|
flex-direction: column;
|
align-items: center;
|
justify-content: center;
|
border: 2rpx dashed #c9ced6;
|
background: #ffffff;
|
box-sizing: border-box;
|
}
|
|
&__upload-icon {
|
width: 52rpx;
|
height: 52rpx;
|
}
|
|
&__upload-text {
|
margin-top: 14rpx;
|
font-size: 26rpx;
|
color: #9da3ae;
|
}
|
|
&__preview-card {
|
background: #eef1f5;
|
}
|
|
&__preview-image {
|
width: 100%;
|
height: 100%;
|
}
|
|
&__preview-mask {
|
position: absolute;
|
left: 0;
|
right: 0;
|
bottom: 0;
|
display: flex;
|
justify-content: center;
|
align-items: center;
|
height: 48rpx;
|
background: rgba(0, 0, 0, 0.46);
|
}
|
|
&__preview-delete {
|
font-size: 26rpx;
|
color: #ffffff;
|
}
|
|
&__textarea {
|
width: 100%;
|
height: 110rpx;
|
margin-top: 24rpx;
|
padding: 28rpx 24rpx;
|
border-radius: 12rpx;
|
background: #f7f8fa;
|
box-sizing: border-box;
|
font-size: 30rpx;
|
color: #2c3139;
|
}
|
|
&__submit {
|
width: 100%;
|
height: 88rpx;
|
line-height: 88rpx;
|
margin-top: 86rpx;
|
border-radius: 50rpx;
|
background: #106efa;
|
font-size: 32rpx;
|
font-weight: 700;
|
color: #ffffff;
|
border: 0;
|
padding: 0;
|
|
&::after {
|
border: 0;
|
}
|
|
&--hover {
|
opacity: 0.92;
|
}
|
}
|
}
|
|
&__header {
|
position: fixed;
|
left: 0;
|
top: 0;
|
right: 0;
|
z-index: 10;
|
background: linear-gradient(180deg, #2473f5 0%, #1e6fef 100%);
|
box-shadow: 0 12rpx 24rpx rgba(36, 115, 245, 0.08);
|
}
|
|
&__user-row {
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
padding: 20rpx 24rpx 0;
|
}
|
|
&__user {
|
display: flex;
|
align-items: center;
|
gap: 14rpx;
|
}
|
|
&__avatar {
|
width: 42rpx;
|
height: 42rpx;
|
border-radius: 50%;
|
border: 2rpx solid rgba(255, 255, 255, 0.7);
|
}
|
|
&__name {
|
font-size: 28rpx;
|
font-weight: 500;
|
color: #ffffff;
|
}
|
|
&__status {
|
display: flex;
|
align-items: center;
|
padding: 10rpx 16rpx;
|
border-radius: 999rpx;
|
background: rgba(255, 255, 255, 0.16);
|
backdrop-filter: blur(10rpx);
|
}
|
|
&__status-dot {
|
width: 14rpx;
|
height: 14rpx;
|
border-radius: 50%;
|
background: #32d74b;
|
margin-right: 10rpx;
|
|
&--offline {
|
background: #ff3b30;
|
}
|
}
|
|
&__status-text,
|
&__status-arrow {
|
font-size: 24rpx;
|
color: #ffffff;
|
}
|
|
&__status-arrow {
|
font-size: 18rpx;
|
margin-left: 8rpx;
|
}
|
|
&__stats {
|
display: flex;
|
justify-content: space-between;
|
padding: 34rpx 36rpx 28rpx;
|
}
|
|
&__stat-item {
|
display: flex;
|
flex-direction: column;
|
align-items: center;
|
min-width: 160rpx;
|
}
|
|
&__stat-value {
|
font-size: 52rpx;
|
line-height: 1;
|
font-weight: 700;
|
color: #ffffff;
|
}
|
|
&__stat-label {
|
margin-top: 12rpx;
|
font-size: 26rpx;
|
color: rgba(255, 255, 255, 0.86);
|
}
|
|
&__tabs {
|
display: flex;
|
align-items: center;
|
height: 88rpx;
|
padding: 0 18rpx;
|
background: #ffffff;
|
}
|
|
&__tab {
|
position: relative;
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
height: 100%;
|
padding: 0 18rpx;
|
font-size: 32rpx;
|
color: #8b9099;
|
}
|
|
&__tab--active {
|
color: #242933;
|
font-weight: 700;
|
}
|
|
&__tab-text {
|
font-size: inherit;
|
color: inherit;
|
}
|
|
&__tab-count {
|
margin-left: 6rpx;
|
font-size: 28rpx;
|
color: #8b9099;
|
}
|
|
&__tab-line {
|
position: absolute;
|
left: 18rpx;
|
right: 18rpx;
|
bottom: 0;
|
height: 5rpx;
|
border-radius: 999rpx;
|
background: #2473f5;
|
}
|
|
&__filter {
|
margin-left: auto;
|
display: flex;
|
align-items: center;
|
gap: 6rpx;
|
padding-right: 10rpx;
|
}
|
|
&__filter-text {
|
font-size: 28rpx;
|
color: #9aa1ab;
|
|
&--active {
|
color: #106efa;
|
}
|
}
|
&__filter-icon {
|
width: 28rpx;
|
height: 28rpx;
|
}
|
|
&__body {
|
box-sizing: border-box;
|
background-color: #F6F9FF;
|
}
|
|
&__list {
|
padding: 30rpx;
|
}
|
|
&__verified {
|
width: 100%;
|
height: 100%;
|
display: flex;
|
flex-direction: column;
|
align-items: center;
|
justify-content: center;
|
image {
|
width: 320rpx;
|
height: 320rpx;
|
}
|
button {
|
width: 160rpx;
|
height: 64rpx;
|
line-height: 64rpx;
|
text-align: center;
|
padding: 0 !important;
|
border: 0 !important;
|
background: #106EFA;
|
border-radius: 50rpx;
|
margin-top: 40rpx;
|
font-weight: 400;
|
font-size: 28rpx;
|
color: #FFFFFF;
|
}
|
}
|
|
&__empty {
|
display: flex;
|
justify-content: center;
|
align-items: center;
|
height: 100%;
|
padding-bottom: env(safe-area-inset-bottom);
|
box-sizing: border-box;
|
}
|
|
&__empty-icon {
|
width: 320rpx;
|
height: 320rpx;
|
}
|
}
|
|
.filter-popup {
|
position: fixed;
|
left: 0;
|
right: 0;
|
z-index: 20;
|
|
&__panel {
|
display: flex;
|
flex-direction: column;
|
height: 100%;
|
background: #ffffff;
|
border-bottom-left-radius: 28rpx;
|
border-bottom-right-radius: 28rpx;
|
}
|
|
&__content {
|
flex: 1;
|
overflow-y: auto;
|
padding: 22rpx 18rpx 0;
|
}
|
|
&__section {
|
margin-bottom: 28rpx;
|
}
|
|
&__title {
|
display: block;
|
margin-bottom: 20rpx;
|
font-size: 28rpx;
|
font-weight: 700;
|
color: #252b33;
|
}
|
|
&__options {
|
display: flex;
|
flex-wrap: wrap;
|
gap: 18rpx 20rpx;
|
}
|
|
&__option {
|
display: flex;
|
justify-content: center;
|
align-items: center;
|
width: 226rpx;
|
height: 74rpx;
|
border-radius: 10rpx;
|
background: #f5f5f5;
|
border: 2rpx solid transparent;
|
box-sizing: border-box;
|
|
&--active {
|
background: #edf5ff;
|
border-color: #3d8cff;
|
}
|
}
|
|
&__option-text {
|
font-size: 28rpx;
|
color: #4b515a;
|
|
.filter-popup__option--active & {
|
font-weight: 600;
|
color: #2678ff;
|
}
|
}
|
|
&__actions {
|
flex-shrink: 0;
|
display: flex;
|
gap: 24rpx;
|
padding: 8rpx 18rpx 26rpx;
|
}
|
|
&__button {
|
flex: 1;
|
height: 92rpx;
|
line-height: 92rpx;
|
border-radius: 999rpx;
|
font-size: 34rpx;
|
font-weight: 700;
|
border: 0;
|
padding: 0;
|
|
&::after {
|
border: 0;
|
}
|
|
&--reset {
|
background: #ebebeb;
|
color: #777d86;
|
}
|
|
&--confirm {
|
background: linear-gradient(180deg, #2d82ff 0%, #206ef6 100%);
|
color: #ffffff;
|
}
|
|
&--hover {
|
opacity: 0.92;
|
}
|
}
|
}
|
|
.order-card {
|
margin-bottom: 20rpx;
|
padding: 20rpx;
|
border-radius: 24rpx;
|
background: #ffffff;
|
box-shadow: 0 10rpx 24rpx rgba(26, 44, 81, 0.04);
|
|
&__head {
|
display: flex;
|
justify-content: space-between;
|
align-items: flex-start;
|
}
|
|
&__time-main {
|
font-size: 42rpx;
|
font-weight: 700;
|
color: #ff8d27;
|
}
|
|
&__time-sub {
|
margin-left: 8rpx;
|
font-size: 28rpx;
|
color: #a3a8b2;
|
}
|
|
&__price-wrap {
|
display: flex;
|
flex-direction: column;
|
align-items: center;
|
gap: 8rpx;
|
|
&--serial-only {
|
justify-content: flex-start;
|
min-width: 54rpx;
|
}
|
}
|
|
&__serial {
|
font-size: 38rpx;
|
font-weight: 700;
|
line-height: 1;
|
color: #2c3139;
|
}
|
|
&__price {
|
font-size: 44rpx;
|
font-weight: 700;
|
color: #ff3b30;
|
}
|
|
&__meta {
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
gap: 16rpx;
|
margin-top: 12rpx;
|
}
|
|
&__extra {
|
flex-shrink: 0;
|
font-size: 24rpx;
|
color: #a0a5af;
|
}
|
|
&__tags {
|
display: flex;
|
flex: 1;
|
flex-wrap: wrap;
|
gap: 10rpx;
|
}
|
|
&__tag-wrap {
|
display: flex;
|
align-items: center;
|
}
|
|
&__tag-icon {
|
width: 108rpx;
|
height: 40rpx;
|
}
|
|
&__tag-img {
|
width: 108rpx;
|
height: 40rpx;
|
}
|
|
&__tag {
|
padding: 4rpx 10rpx;
|
border-radius: 8rpx;
|
font-size: 22rpx;
|
line-height: 1.2;
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
border: 1rpx solid #2473f5;
|
color: #2473f5;
|
|
&--orange {
|
border: none;
|
background: linear-gradient(319deg, #EE9D0E 0%, #FF4E4E 100%);
|
color: #ffffff;
|
}
|
|
&--red {
|
border-color: #ff6c57;
|
color: #ff6c57;
|
}
|
|
&--blue-light {
|
border-color: #74a9ff;
|
color: #74a9ff;
|
}
|
|
&--blue {
|
background: rgba(16,178,250,0.08);
|
border-radius: 15rpx;
|
border: 2rpx solid #106EFA;
|
font-weight: 400;
|
font-size: 22rpx;
|
color: #106EFA;
|
}
|
}
|
|
&__route {
|
display: flex;
|
margin-top: 20rpx;
|
}
|
|
&__route-side {
|
width: 70rpx;
|
display: flex;
|
flex-direction: column;
|
align-items: center;
|
flex-shrink: 0;
|
padding: 14rpx 0 8rpx;
|
border-radius: 26rpx;
|
background: #f6f7f9;
|
margin-right: 20rpx;
|
}
|
|
&__distance-block {
|
display: flex;
|
flex-direction: column;
|
align-items: center;
|
line-height: 1;
|
|
&--top {
|
margin-bottom: 6rpx;
|
}
|
|
&--bottom {
|
margin-top: 6rpx;
|
}
|
}
|
|
&__distance-value {
|
font-size: 26rpx;
|
font-weight: 700;
|
color: #333333;
|
text-align: center;
|
}
|
|
&__distance-unit {
|
margin-top: 6rpx;
|
font-size: 18rpx;
|
font-weight: 500;
|
color: #8c939f;
|
text-align: center;
|
text-transform: lowercase;
|
}
|
|
&__line {
|
position: relative;
|
width: 100%;
|
flex: 1;
|
min-height: 62rpx;
|
margin: 8rpx 0;
|
background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='26' viewBox='0 0 20 26'%3E%3Cpath fill='%238C939F' d='M10 0C5.03 0 1 3.99 1 8.92c0 6.31 7.28 12.87 8.07 13.57a1.4 1.4 0 0 0 1.86 0C11.72 21.79 19 15.23 19 8.92 19 3.99 14.97 0 10 0Zm0 12.24a3.32 3.32 0 1 1 0-6.64 3.32 3.32 0 0 1 0 6.64Z'/%3E%3C/svg%3E") center center no-repeat;
|
background-size: 20rpx 26rpx;
|
|
&::before,
|
&::after {
|
content: '';
|
position: absolute;
|
left: 50%;
|
transform: translateX(-50%);
|
width: 2rpx;
|
border-radius: 999rpx;
|
background: #cfd4dc;
|
}
|
|
&::before {
|
top: 0;
|
height: 18rpx;
|
}
|
|
&::after {
|
bottom: 0;
|
height: 24rpx;
|
}
|
}
|
|
&__route-main {
|
flex: 1;
|
}
|
|
&__route-item {
|
display: flex;
|
justify-content: space-between;
|
align-items: flex-start;
|
gap: 16rpx;
|
|
&--destination {
|
margin-top: 20rpx;
|
}
|
}
|
|
&__route-badge {
|
width: 44rpx;
|
height: 44rpx;
|
border-radius: 50%;
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
font-size: 24rpx;
|
font-weight: 600;
|
color: #ffffff;
|
margin-right: 16rpx;
|
flex-shrink: 0;
|
|
&--take {
|
background: #10B2FA;
|
}
|
|
&--send {
|
background: #FF8A00;
|
}
|
}
|
|
&__route-badge-text {
|
display: inline-flex;
|
align-items: center;
|
justify-content: center;
|
width: 36rpx;
|
height: 36rpx;
|
border-radius: 50%;
|
font-size: 22rpx;
|
font-weight: 600;
|
color: #ffffff;
|
margin-right: 8rpx;
|
vertical-align: middle;
|
|
&--take {
|
background: #10B2FA;
|
}
|
|
&--send {
|
background: #FF8A00;
|
}
|
}
|
|
&__route-texts {
|
flex: 1;
|
min-width: 0;
|
}
|
|
&__route-title {
|
width: 500rpx;
|
display: block;
|
font-size: 40rpx;
|
font-weight: 700;
|
color: #2d3139;
|
line-height: 1.3;
|
overflow: hidden;
|
text-overflow: ellipsis;
|
white-space: nowrap;
|
}
|
|
&__route-desc {
|
width: 500rpx;
|
display: block;
|
margin-top: 8rpx;
|
font-size: 28rpx;
|
color: #9ea4ae;
|
line-height: 1.4;
|
overflow: hidden;
|
text-overflow: ellipsis;
|
white-space: nowrap;
|
}
|
|
&__nav {
|
width: 48rpx;
|
height: 48rpx;
|
flex-shrink: 0;
|
}
|
|
&__goods {
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
height: 70rpx;
|
padding: 0 20rpx;
|
margin-top: 20rpx;
|
border-radius: 16rpx;
|
background: #f4f5f7;
|
}
|
|
&__goods-text {
|
flex: 1;
|
font-size: 28rpx;
|
color: #7a818d;
|
white-space: nowrap;
|
overflow: hidden;
|
text-overflow: ellipsis;
|
}
|
|
&__goods-arrow {
|
margin-left: 12rpx;
|
font-size: 24rpx;
|
color: #a4a9b1;
|
transition: transform 0.3s;
|
|
&--expanded {
|
transform: rotate(180deg);
|
}
|
}
|
|
&__button {
|
margin-top: 24rpx;
|
width: 100%;
|
height: 88rpx;
|
line-height: 88rpx;
|
border-radius: 999rpx;
|
background: linear-gradient(180deg, #2b7fff 0%, #1f6ff3 100%);
|
font-size: 34rpx;
|
font-weight: 700;
|
color: #ffffff;
|
border: 0;
|
padding: 0;
|
|
&::after {
|
border: 0;
|
}
|
|
&--hover {
|
opacity: 0.92;
|
}
|
}
|
|
&__actions {
|
margin-top: 24rpx;
|
|
&--pickup,
|
&--delivering {
|
display: flex;
|
align-items: center;
|
gap: 22rpx;
|
}
|
}
|
|
&__icon-actions {
|
display: flex;
|
align-items: center;
|
gap: 20rpx;
|
flex-shrink: 0;
|
|
&--single {
|
gap: 0;
|
}
|
}
|
|
&__icon-action {
|
display: flex;
|
flex-direction: column;
|
align-items: center;
|
justify-content: center;
|
width: 74rpx;
|
}
|
|
&__action-icon {
|
width: 40rpx;
|
height: 40rpx;
|
border-radius: 8rpx;
|
background: #f7f8fa;
|
}
|
|
&__action-text {
|
margin-top: 8rpx;
|
font-size: 26rpx;
|
line-height: 1;
|
color: #5b616b;
|
}
|
|
&__button--code {
|
flex: 1;
|
margin-top: 0;
|
}
|
}
|
</style>
|