You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

2417 lines
65 KiB

<template>
<view class="page1">
<common-loading />
<view class="title">
<view class="title-sreach">
<view style="position: absolute;display: flex;" :style="{'top': (menuButtonInfo.top || 44) +'px'}">
<view class="sort-member delivery-title-tabs">
<view class="tab1">
<view class="tabs1" @tap="checkTab1('daiqu')"
:style="{'color':tab1Checked == 'daiqu'?'#000':'#777','font-size':tab1Checked== 'daiqu'?'36rpx':'30rpx'}">
<view class="tab-label">
<text>待取货</text>
<text class="tab-count" v-if="deliveryStatusCounts.daiqu > 0">{{deliveryStatusCounts.daiqu}}</text>
</view>
<img v-if="tab1Checked == 'daiqu'"
src="https://jewel-shop.oss-cn-beijing.aliyuncs.com/4bb5fc7725cb4a7a84d1d3a15f05b39c.png"
alt=""
style="width: 120rpx;height: 12rpx;position: absolute;bottom: 4rpx;left: 30rpx;" />
</view>
<view class="tabs1" @tap="checkTab1('daisong')"
:style="{'color':tab1Checked == 'daisong'?'#000':'#777','font-size':tab1Checked== 'daisong'?'36rpx':'30rpx'}">
<view class="tab-label">
<text>待送达</text>
<text class="tab-count" v-if="deliveryStatusCounts.daisong > 0">{{deliveryStatusCounts.daisong}}</text>
</view>
<img v-if="tab1Checked == 'daisong'"
src="https://jewel-shop.oss-cn-beijing.aliyuncs.com/4bb5fc7725cb4a7a84d1d3a15f05b39c.png"
alt=""
style="width: 80rpx;height: 14rpx;position: absolute;bottom: 4rpx;left: 32rpx;" />
</view>
<!-- <view class="tabs1" @tap="checkTab1('zhuandan')"
:style="{'color':tab1Checked == 'zhuandan'?'#000':'#777','font-size':tab1Checked== 'zhuandan'?'36rpx':'30rpx'}">
转单<text>()</text>
<img v-if="tab1Checked == 'zhuandan'"
src="https://jewel-shop.oss-cn-beijing.aliyuncs.com/4bb5fc7725cb4a7a84d1d3a15f05b39c.png"
alt=""
style="width: 80rpx;height: 14rpx;position: absolute;bottom: 4rpx;left: 32rpx;" />
</view> -->
</view>
<view class="title-refresh" :class="{'title-refresh--loading': refreshLoading}" @tap.stop="refreshCurrentTab">
<uni-icons type="refresh" size="20" color="#0b6b5a" style="margin-top: 6rpx;"></uni-icons>
</view>
</view>
</view>
</view>
</view>
<view class="delivery-filter-row">
<view class="guize-box1"
:style="{'background':tab1Checked1 == 'fantuan'?'rgba(130, 255, 130, 1)':'rgba(247, 248, 248, 0.6)'}"
@tap="chooseType('fantuan')">
<uni-icons type="info" size="10"></uni-icons>
饭团
</view>
<view class="guize-box1"
:style="{'background':tab1Checked1 == 'kuaidi'?'rgba(130, 255, 130, 1)':'rgba(247, 248, 248, 0.6)'}"
@tap="chooseType('kuaidi')">
<uni-icons type="info" size="10"></uni-icons>
快递
</view>
<view class="guize-box1"
:style="{'background':tab1Checked1 == 'paotui'?'rgba(130, 255, 130, 1)':'rgba(247, 248, 248, 0.6)'}"
@tap="chooseType('paotui')">
<uni-icons type="info" size="10"></uni-icons>
跑腿
</view>
<view class="delivery-ranking-btn" @tap="goDeliveryRanking">
配送排行
</view>
</view>
<view class="delivery-status-card">
<view class="delivery-status-main">
<view class="delivery-status-title-row">
<view class="delivery-status-title">今日接单状态</view>
<view class="delivery-status-pill" :class="{'delivery-status-pill--on': isOnLine == 1}">
{{isOnLine == 1 ? '已上线' : '已离线,新订单不再提醒'}}
</view>
</view>
<view class="delivery-status-desc">{{deliveryStatusText}}</view>
<view class="delivery-status-meta">
<text :class="{'delivery-status-meta--warn': !zhipaiCheck}">{{zhipaiCheck ? '自动派单已开启' : '自动派单未开启'}}</text>
<text>覆盖 {{totalRuleCount}} 条路线</text>
<text v-if="minRuleFeeText">最低 {{minRuleFeeText}} 起</text>
</view>
</view>
<view class="delivery-status-actions">
<view class="delivery-status-action delivery-status-action--primary" @tap="openPopup">
我的接单范围
</view>
<view class="delivery-status-action" :class="{'delivery-status-action--online': isOnLine != 1}" @tap="changeOnline(isOnLine == 1 ? 0 : 1)">
{{isOnLine == 1 ? '下线休息' : '上线接单'}}
</view>
</view>
</view>
<view class="content">
<scroll-view id="orderScroll" class="order-scroll" @scrolltolower="onReachPage" @scroll="handleScroll" :scroll-top="scrollTop" lower-threshold="160" scroll-y>
<view class="delivery-empty-guide" v-if="totalRuleCount == 0">
<view class="delivery-empty-illustration">赚钱地盘</view>
<view class="delivery-empty-title">还没划定赚钱地盘</view>
<view class="delivery-empty-desc">设置接单路线,用户下单时即可直接指派给你</view>
<view class="delivery-empty-btn" @tap="goRuleSetting">去设置接单范围</view>
</view>
<view class="box1" v-for="(item,index) in pageData" :key="index">
<view class="maotou" v-if="item.deliveryType == 1">
<text>{{item.numberCode.length>14 ?'多订单':item.numberCode | delPlus}}</text>
</view>
<view style="width: 100%;line-height: 70rpx;font-size: 28rpx;font-weight: 700;display: flex;">
<view v-if="item.deliveryType == 1"
style="height: 40rpx;line-height: 40rpx;background: rgba(255, 233, 89, 1);padding: 0 16rpx;border-radius: 40rpx;margin: 14rpx 20rpx 0 0;">
外卖
</view>
<view v-if="item.deliveryType == 2"
style="height: 40rpx;line-height: 40rpx;background: rgba(255, 220, 199, 1);padding: 0 16rpx;border-radius: 40rpx;margin: 14rpx 20rpx 0 0;">
代取快递
</view>
<view v-if="item.deliveryType == 3"
style="height: 40rpx;line-height: 40rpx;background: rgba(130, 255, 130, 1);padding: 0 16rpx;border-radius: 40rpx;margin: 14rpx 20rpx 0 0;">
代跑腿
</view>
<view class="appointment-delivery-tag" v-if="item.appointmentDelivery == 1">
预约配送
</view>
<view class="" :style="{'color':shouldNotify(item.mustFinishTime)?'red':''}">
{{item.mustFinishTime != null ? item.mustFinishTime : '' | formatHourMinute }}前送达
</view>
</view>
<view class="" v-if="item.remark != '' && item.remark != null"
style="background: rgba(247, 248, 248, 0.6);height: 80rpx;line-height: 80rpx;font-weight: 500;padding: 0 20rpx;border-radius: 20rpx;">
备注:{{item.remark}}
</view>
<view class="express-info-card" v-if="item.deliveryType == 3 || item.deliveryType == 2">
<view class="express-info-row">
<view class="express-info-item">
<text class="express-info-label">件数</text>
<text class="express-info-value">{{item.allCount != null ? item.allCount : 0}}件</text>
</view>
<view class="express-info-item express-info-item--code" v-if="item.getCodes != null && item.getCodes != ''">
<text class="express-info-label">取件码</text>
<text class="express-info-value">{{item.getCodes}}</text>
</view>
<view class="express-info-item" v-if="item.phoneNumber != null && item.phoneNumber != ''">
<text class="express-info-label">手机尾号</text>
<text class="express-info-value">{{item.phoneNumber}}</text>
</view>
</view>
<view class="express-picture-list" v-if="getPickupPictures(item).length > 0">
<view class="express-picture-title">取件码截图</view>
<image class="express-picture" v-for="(pic,picIndex) in getPickupPictures(item)" :key="picIndex"
:src="pic" mode="aspectFill" @tap.stop="largeImg(pic)"></image>
</view>
<!-- <view style="display: flex;padding: 10px 0;">
<view class="code-box" style="margin-right:10px;">
1-3-1290
</view>
</view> -->
<!-- <view style="display: flex;padding: 10px 0;">
<view class="code-box">
手机尾号 - 5741
</view>
</view> -->
</view>
<view style="display: flex;border-radius: 20rpx;margin-top: 32rpx;border: 1px solid rgba(166, 255, 234, 0.78);padding: 10px;">
<view class="goods-content" @tap="productDetail(item)">
<view class="goods-name" style="font-size: 24rpx;line-height: 50rpx;display: flex;">
<img src="https://jewel-shop.oss-cn-beijing.aliyuncs.com/1f77398a73454a6595c12a3c18731599.png"
alt="" style="width: 50rpx;height: 50rpx;" />
<view style="flex: 1;">
<view class="">
{{item.shopName}}
</view>
<view class="shop-address-row">
<view class="shop-address">
{{item.shopAddress}}
</view>
</view>
</view>
<view class="right">
<img @tap.stop="makeCall(item.shopPhone)"
src="https://jewel-shop.oss-cn-beijing.aliyuncs.com/869a7af6a1c24bf3a0d523c4a18b55c6.png"
alt="" style="width: 60rpx;height: 60rpx;" />
</view>
</view>
<view v-if="item.transferDelivery == 1" style="margin-top: 12rpx;background:#fff7ed;border-radius:16rpx;padding:12rpx;color:#b45309;">
<view>中转点:{{item.transferAddressName || item.shopName}}</view>
<view>送达中转点:{{item.transferArriveTime ? formatTimeText(item.transferArriveTime) : '商家未确认送达'}}</view>
<image v-if="item.transferArriveImage" :src="item.transferArriveImage" mode="aspectFill" style="width:120rpx;height:120rpx;border-radius:12rpx;margin-top:8rpx;" @tap.stop="previewImage(item.transferArriveImage)"></image>
</view>
<view class="goods-name"
style="font-size: 24rpx;line-height: 50rpx;display: flex;margin-top: 14rpx;">
<img src="https://jewel-shop.oss-cn-beijing.aliyuncs.com/d0764fb4138747769538cf1cafa3b017.png"
alt="" style="width: 50rpx;height: 50rpx;" />
<view style="flex: 1;">
<view class="">
{{item.receiverName}}
</view>
<view class="shop-address" style="color: #777;">
{{item.receiverAddress}}
</view>
</view>
<view class="right">
<img @tap.stop="makeCall(item.receiverPhone)"
src="https://jewel-shop.oss-cn-beijing.aliyuncs.com/869a7af6a1c24bf3a0d523c4a18b55c6.png"
alt="" style="width: 60rpx;height: 60rpx;" />
</view>
</view>
</view>
</view>
<view style="display: flex;border-radius: 20rpx;margin-top: 20rpx;">
<view class="goods-content">
<view class="goods-name" style="font-size: 24rpx;line-height: 50rpx;display: flex;">
<view style="flex: 1;display: flex;">
<view style="color: #777;display: flex;">
配送佣金
<view class="chaoda" v-if="item.isBig != null && item.isBig == 1">
超大/超重
</view>
</view>
<view style="flex: 1;text-align: right;">
¥{{(item.deliveryFee + item.deliveryFeeMarketplace).toFixed(2)}} <text style="color: #777;font-size: 20rpx;"
v-if="item.deliveryFeeMarketplace != null">(包含¥{{item.deliveryFeeMarketplace}}平台佣金)</text>
</view>
</view>
</view>
</view>
</view>
<view v-if="item.isReturn != null && item.isReturn == 1" class="refund-status">
<view class="refund-status-text">
<text class="refund-status-dot"></text>
<text>用户申请退款中</text>
</view>
</view>
<view v-else class="order-action">
<view v-if="item.status == 1 && item.arriveTime == null"
class="order-action-btn order-action-btn--arrive"
@tap="changeStatus(index,item,1)">
<view class="order-action-icon">
<uni-icons type="hand-up-filled" size="24" color="#fff"></uni-icons>
</view>
<text>已到店</text>
</view>
<!-- <view style="width: 20%;" @tap="changeOthers(item,1)">转单</view> -->
<view v-if="item.status == 1 && item.arriveTime != null"
class="order-action-btn order-action-btn--pickup"
@tap="changeStatus(index,item,2)">
<view class="order-action-icon">
<uni-icons type="hand-up-filled" size="24" color="#fff"></uni-icons>
</view>
<text>已取货</text>
</view>
<view v-if="item.status == 2"
class="order-action-btn order-action-btn--complete"
:class="{'order-action-btn--disabled': completingDeliveryIds[item.id]}"
@tap="changeStatus(index,item,3)">
<view class="order-action-icon">
<uni-icons type="hand-up-filled" size="24" color="#fff"></uni-icons>
</view>
<text>{{completingDeliveryIds[item.id] ? '提交中...' : '已送达'}}</text>
</view>
</view>
</view>
<uni-load-more :status="loadStatus" @change="onChange" />
<view class="list-bottom-space"></view>
</scroll-view>
<!-- 设置指派单规则弹窗 -->
<uni-popup ref="carPopup" class="dispatch-popup" type="bottom" background-color="transparent" @change="handleDispatchPopupChange">
<view class="guize-list">
<view class="dispatch-popup-title">
选择参与自动派单的接单范围
</view>
<view class="dispatch-popup-desc">
开启后,系统只会把符合你设置区域和最低佣金的订单派给你。未勾选路线不会参与指派。
</view>
<view class="zhipai-box">
开启接受指派单
<view class="zhipai">
<switch :checked="zhipaiCheck" @change="zhipaiChange"
style="transform: scale(0.7);text-align: right;" />
</view>
</view>
<view class="dispatch-warning" v-if="isOnLine != 1">
当前离线,保存后需要上线才会收到系统派单。
</view>
<view class="dispatch-empty" v-if="totalRuleCount == 0">
<view class="dispatch-empty-title">你还没有接单范围</view>
<view class="dispatch-empty-desc">先去划定想送的楼栋和最低配送费,设置后才能开启自动派单。</view>
</view>
<scroll-view scroll-y="true" class="dispatch-rule-scroll">
<view style="height: 50rpx;line-height: 50rpx;font-weight: 700;display: flex;">
外卖接单范围
<view @tap="allCheck('waimai')" v-if="zhipaiCheck"
style="color: #1E90FF;flex:1;text-align: right;padding-right: 20rpx;">
全选
</view>
</view>
<view class="guize1" v-for="(item, index) in waimaRuleList" :key="index"
style="flex-direction: column; padding-bottom: 20rpx; border-bottom: 1px solid #ddd;position: relative;">
<view v-if="!zhipaiCheck"
style="position: absolute;top: 0;left: 0;width: 100%;height: 100%;background: rgba(255, 255, 255, 0.5);">
</view>
<view style="display: flex; width: 100%;" @tap="checkVoucher(index,'waimai')">
<view class="guize1-qusong">
<view class="qusong1">
</view>
<view class="qusong2">
{{item.getAreaName}}
</view>
</view>
<view class="guize1-qusong">
<view class="qusong1">
</view>
<view class="qusong2" style="background: rgba(209, 206, 255, 1);">
{{item.putAreaName}}
</view>
</view>
<view class="dispatch-rule-fee">最低¥{{item.orderBkge || 0}}</view>
<view class="radio-check" v-if="item.isChecked">
<uni-icons type="checkmarkempty" size="12"></uni-icons>
</view>
<view class="radio-no-check" v-else></view>
<!-- <uni-icons type="closeempty" size="20" @click="selectRule(item)" color="#ff0000"
style="margin-left:5px;"></uni-icons> -->
</view>
</view>
<view style="height: 50rpx;line-height: 50rpx;font-weight: 700;display: flex;">
快递接单范围
<view @tap="allCheck('paotui')" v-if="zhipaiCheck"
style="color: #1E90FF;flex:1;text-align: right;padding-right: 20rpx;">
全选
</view>
</view>
<view class="guize1" v-for="(item, index) in paotuiRuleList" :key="index"
style="flex-direction: column; padding-bottom: 20rpx; border-bottom: 1px solid #ddd;position: relative;">
<view v-if="!zhipaiCheck"
style="position: absolute;top: 0;left: 0;width: 100%;height: 100%;background: rgba(255, 255, 255, 0.5);">
</view>
<view style="display: flex; width: 100%;" @tap="checkVoucher(index,'paotui')">
<view class="guize1-qusong">
<view class="qusong1">
</view>
<view class="qusong2">
{{item.getAreaName}}
</view>
</view>
<view class="guize1-qusong">
<view class="qusong1">
</view>
<view class="qusong2" style="background: rgba(209, 206, 255, 1);">
{{item.putAreaName}}
</view>
</view>
<view class="dispatch-rule-fee">最低¥{{item.orderBkge || 0}}</view>
<view class="radio-check" v-if="item.isChecked">
<uni-icons type="checkmarkempty" size="12"></uni-icons>
</view>
<view class="radio-no-check" v-else></view>
<!-- <uni-icons type="closeempty" size="20" @click="selectRule(item)" color="#ff0000"
style="margin-left:5px;"></uni-icons> -->
</view>
</view>
<view class="dispatch-scroll-bottom">
没有更多了
</view>
</scroll-view>
<view class="dispatch-actions">
<view class="dispatch-action-btn dispatch-action-btn--secondary" @tap="buchong">
补充范围
</view>
<view class="dispatch-action-btn dispatch-action-btn--primary" @tap="selectRule">
确认并保存
</view>
</view>
</view>
</uni-popup>
<!-- 查看大图弹出层 -->
<uni-popup ref="imgPopup" background-color="#fff">
<view class="img-popup-content">
<image :src="bigImg" mode="aspectFit" style="width: 100%;height: 100%;"></image>
</view>
</uni-popup>
<uni-popup ref="pickupCodePopup" background-color="transparent" :mask-click="false" @change="handlePickupCodePopupChange">
<view class="pickup-code-popup" @tap.stop @touchmove.stop.prevent>
<view class="pickup-code-title">输入取餐码</view>
<view class="pickup-code-desc">请输入4位取餐码</view>
<input class="pickup-code-input" v-model="pickupCode" type="number" maxlength="4"
:focus="pickupCodeInputFocus"
placeholder="请输入4位取餐码" confirm-type="done" @input="handlePickupCodeInput"
@confirm="submitPickupCode" />
<view class="pickup-code-actions">
<view class="pickup-code-action pickup-code-action--cancel" @tap="closePickupCodePopup">取消</view>
<view class="pickup-code-action pickup-code-action--confirm" @tap="submitPickupCode">
{{pickupCodeSubmitting ? '提交中...' : '确认'}}
</view>
</view>
</view>
</uni-popup>
<uni-popup ref="productPopup" background-color="transparent">
<view class="product-popup-content">
<view class="product-popup-header">
<view class="product-popup-title">订单详情</view>
<view class="product-popup-subtitle">请核对商品规格和数量</view>
</view>
<view class="product-popup-list" v-if="productData != null && productData.length > 0">
<view class="product-popup-card" v-for="(item1,index1) in productData" :key="index1">
<view class="product-popup-img">
<img :src="item1.productPicture" alt="">
</view>
<view class="product-popup-info">
<view class="product-popup-name">
{{item1.productName}}
</view>
<view class="product-popup-spec">
<text class="product-popup-label">规格</text>
<text class="product-popup-spec-text">{{item1.specs | delNode}}</text>
</view>
</view>
<view class="product-popup-quantity">
<view class="product-popup-quantity-num">x{{item1.quantity}}</view>
<view class="product-popup-quantity-label">数量</view>
</view>
</view>
</view>
<view class="product-popup-empty" v-else>
暂无商品详情
</view>
</view>
</uni-popup>
<!-- 未注册兼职弹窗 -->
<uni-popup ref="jianzhiPopup" background-color="rgba(2, 171, 255, 1)" borderRadius="40px 40px 40px 40px">
<view class="jianzhi-content" @tap="createPartTimeWorker">
<img src="https://jewel-shop.oss-cn-beijing.aliyuncs.com/faf25c687bc1417282ebac719fd1bfba.png" alt=""
style="width: 100%;height: 100%;">
<view class="jianzhi-close" @tap.stop="$refs.jianzhiPopup.close()">
<uni-icons type="close" size="40" color="#fff"></uni-icons>
</view>
</view>
</uni-popup>
</view>
</view>
</template>
<script>
export default {
data() {
return {
isOnLine: 1,
bigImg: '',
zhipaiCheck: false,
tab1Checked: 'daiqu',
menuButtonInfo: {
top: 44
},
scrollTop: 0,
oldScrollTop: 0,
isLoadingPage: false,
scrollViewHeight: 0,
isArea: false,
latitude: 39.909, // 默认纬度,可以设为用户当前位置或配送员位置
longitude: 116.39742, // 默认经度
productData: {},
searchForm: {
status: 1,
pageNum: 1,
pageSize: 10,
order: '',
returnOrderLast: 1,
regionId: '',
deliveryType: null,
workerId: uni.getStorageSync('worker') ? uni.getStorageSync('worker').workerId : ''
},
waimaRuleList: [],
tab1Checked1: '',
deliveryStatusCounts: {
daiqu: 0,
daisong: 0
},
pageData: [],
deliveryItem: [],
deliveryItem1: [],
selectRuleList: [],
totalPages: 1,
paotuiRuleList: [],
loginRedirecting: false,
refreshLoading: false,
refreshLoadingStartTime: 0,
refreshLoadingTimer: null,
pickupCode: '',
pickupCodeContext: null,
pickupCodeSubmitting: false,
pickupCodeInputFocus: false,
pickupCodePopupVisible: false,
pickupCodePopupOpening: false,
pickupCodeFocusTimer: null,
completingDeliveryIds: {},
lineStatus: [{
title: '上线',
value: 0
},
{
title: '下线',
value: 1
}
]
}
},
props: {
},
watch: {
},
mounted() {
this.loadDeliveryStatusCounts()
uni.$on('deliveryStatusCountsChange', this.setDeliveryStatusCounts)
},
onReachBottom() {
this.onReachPage();
},
beforeDestroy() {
uni.$off('deliveryStatusCountsChange', this.setDeliveryStatusCounts)
if (this.refreshLoadingTimer) {
clearTimeout(this.refreshLoadingTimer)
this.refreshLoadingTimer = null
}
if (this.refreshLoading) {
this.refreshLoading = false
uni.hideLoading()
}
if (this.pickupCodeFocusTimer) {
clearTimeout(this.pickupCodeFocusTimer)
this.pickupCodeFocusTimer = null
}
},
computed: {
totalRuleCount() {
return (this.waimaRuleList ? this.waimaRuleList.length : 0) + (this.paotuiRuleList ? this.paotuiRuleList.length : 0)
},
activeRuleCount() {
const list = (this.waimaRuleList || []).concat(this.paotuiRuleList || [])
return list.filter(item => item.getPushOrder == 1 || item.isChecked).length
},
minRuleFeeText() {
const fees = (this.waimaRuleList || []).concat(this.paotuiRuleList || [])
.map(item => parseFloat(item.orderBkge))
.filter(item => !isNaN(item) && item > 0)
if (fees.length == 0) return ''
return '¥' + Math.min.apply(null, fees).toFixed(2).replace(/\.?0+$/, '')
},
deliveryStatusText() {
if (this.totalRuleCount == 0) {
return '未设置区域,用户下单时将无法按范围指派你'
}
if (this.isOnLine != 1) {
return '已设置范围,但当前离线,系统不会派单'
}
if (!this.zhipaiCheck) {
return '已上线,未开启自动派单,系统不会派单'
}
if (this.activeRuleCount == 0) {
return '已上线,但还没有勾选参与派单的路线'
}
return '已准备好接收符合范围和佣金的订单'
}
},
filters: {
formatHourMinute(value) {
if (!value) return '';
const date = new Date(value);
// 获取日 (getDate),并补齐0
const day = String(date.getDate()).padStart(2, '0');
// 获取小时 (getHours),并补齐0
const hour = String(date.getHours()).padStart(2, '0');
// 获取分钟 (getMinutes),并补齐0
const minute = String(date.getMinutes()).padStart(2, '0');
// 拼接格式:日-日-时:分
return `${hour}:${minute}`;
},
delNode(data) {
// 1. 统一转为字符串
let str;
if (typeof data === 'object' && data !== null) {
// 对象或数组 → JSON 字符串
str = JSON.stringify(data);
} else if (typeof data === 'string') {
str = data;
} else {
// 其他类型(数字、布尔等)先转字符串
str = String(data);
}
// 2. 删除所有大括号 { } 和双引号 "
const result = str.replace(/[{}"]/g, '');
return result;
},
delPlus(data){
if (data.endsWith("+")) {
data = data.slice(0, -1); // 删除最后一个字符
}
return data;
}
},
methods: {
getPickupPictures(item) {
const pictures = item && item.getPictures
if (!pictures) return []
if (Array.isArray(pictures)) {
return pictures.filter(pic => pic)
}
if (typeof pictures === 'string') {
let value = pictures.trim()
if (!value) return []
try {
const parsed = JSON.parse(value)
if (Array.isArray(parsed)) {
return parsed.filter(pic => pic)
}
} catch (e) {}
return value.split(/[,,\s]+/).map(pic => pic.trim()).filter(pic => pic)
}
return []
},
loadDeliveryStatusCounts() {
this.setDeliveryStatusCounts(uni.getStorageSync('deliveryStatusCounts') || {})
},
setDeliveryStatusCounts(counts) {
this.deliveryStatusCounts = {
daiqu: Number(counts.daiqu) || 0,
daisong: Number(counts.daisong) || 0
}
uni.setStorageSync('deliveryStatusCounts', this.deliveryStatusCounts)
},
decreaseDeliveryStatusCount(status) {
if (status == 2) {
this.deliveryStatusCounts.daiqu = Math.max(0, Number(this.deliveryStatusCounts.daiqu) - 1)
this.deliveryStatusCounts.daisong = Number(this.deliveryStatusCounts.daisong) + 1
} else if (status == 3) {
this.deliveryStatusCounts.daisong = Math.max(0, Number(this.deliveryStatusCounts.daisong) - 1)
}
uni.setStorageSync('deliveryStatusCounts', this.deliveryStatusCounts)
uni.$emit('deliveryStatusCountsChange', this.deliveryStatusCounts)
},
formatTimeText(value) {
if (!value) return '';
const date = new Date(value);
if (isNaN(date.getTime())) return '';
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
const hour = String(date.getHours()).padStart(2, '0');
const minute = String(date.getMinutes()).padStart(2, '0');
const second = String(date.getSeconds()).padStart(2, '0');
return `${year}-${month}-${day} ${hour}:${minute}:${second}`;
},
previewImage(url) {
if (!url) return;
uni.previewImage({
current: url,
urls: [url]
});
},
ensureLogin() {
const token = uni.getStorageSync('hiver_token')
if (token && typeof token === 'string' && token.trim() && token !== 'null' && token !== 'undefined') {
return true
}
if (this.loginRedirecting) return false
this.loginRedirecting = true
const pages = getCurrentPages()
const current = pages && pages.length ? pages[pages.length - 1] : null
const route = current ? '/' + current.route : '/pages/index/index'
const query = current && current.options
? Object.keys(current.options).map(key => key + '=' + encodeURIComponent(current.options[key])).join('&')
: ''
const target = route + (query ? '?' + query : '')
const redirectKey = 'login_redirect_' + Date.now()
uni.setStorageSync(redirectKey, target)
uni.navigateTo({
url: '/package2/login/login?redirect=' + redirectKey,
complete: () => {
setTimeout(() => {
this.loginRedirecting = false
}, 1200)
}
})
return false
},
init() {
if (!this.ensureLogin()) return
this.menuButtonInfo = uni.getMenuButtonBoundingClientRect()
let worker = uni.getStorageSync('worker')
if (worker == '' || worker == undefined || worker == null) {
this.tui.toast('您还没有注册兼职')
return
}
this.isOnLine = uni.getStorageSync('worker').isOnLine
this.zhipaiCheck = uni.getStorageSync('worker').getPushOrder == 1 ? true : false
if (uni.getStorageSync('area')) {
this.searchForm.regionId = JSON.parse(uni.getStorageSync('area')).id;
}
if (uni.getStorageSync('worker')) {
this.searchForm.workerId = uni.getStorageSync('worker').workerId
}
this.$forceUpdate()
this.loadWorkerRules()
this.getDelivery()
this.$nextTick(() => {
this.measureScrollView()
})
},
goRuleSetting() {
this.goPartTimeRegister()
},
goDeliveryRanking() {
uni.navigateTo({
url: '/package2/shop/ranking'
})
},
goPartTimeRegister() {
if (uni.getStorageSync('worker')) {
uni.navigateTo({
url: '/package2/myCenter/partTimeJobRegister'
})
return
}
this.$refs.jianzhiPopup.open()
},
createPartTimeWorker() {
if (!this.ensureLogin()) return
let worker = uni.getStorageSync('worker')
if (worker) {
this.$refs.jianzhiPopup.close()
uni.navigateTo({
url: '/package2/myCenter/partTimeJobRegister'
})
return
}
const area = uni.getStorageSync('area') ? JSON.parse(uni.getStorageSync('area')) : {}
this.tui.request("/worker/admin/add", "POST", {
userId: uni.getStorageSync('id'),
isChangeArea: 1,
region: area.id
}, false, true).then((res) => {
if (res.code == 200) {
if (res.result != null) {
uni.setStorageSync('worker', res.result)
}
this.$refs.jianzhiPopup.close()
uni.navigateTo({
url: '/package2/myCenter/partTimeJobRegister'
})
} else {
this.tui.toast(res.message)
}
uni.hideLoading()
}).catch((res) => {})
},
ensureWorkerRegistered() {
if (!this.ensureLogin()) return false
const worker = uni.getStorageSync('worker')
if (worker && worker.workerId) return true
this.$refs.jianzhiPopup.open()
return false
},
loadWorkerRules(openAfterLoad) {
const worker = uni.getStorageSync('worker')
if (!worker || !worker.workerId) return
let that = this
that.tui.request("/app/workerRelaPrice/getByWorkerId?workerId=" + worker.workerId,
"GET", {}, false, true).then((res) => {
if (res.code == 200) {
let list = res.result && res.result.workerRelaPriceList ? res.result.workerRelaPriceList : []
for (let i = 0; i < list.length; i++) {
list[i].isChecked = list[i].getPushOrder == 1
}
that.waimaRuleList = list.filter(item => item.orderType == 0)
that.paotuiRuleList = list.filter(item => item.orderType == 1)
that.zhipaiCheck = uni.getStorageSync('worker').getPushOrder == 1 ? true : false
that.$forceUpdate()
if (openAfterLoad) {
that.setHomeTabBarVisible(false)
that.$refs.carPopup.open()
}
} else {
that.tui.toast(res.message)
}
}).catch((res) => {})
},
// 获取用户位置
getUserLocation(item) {
if (!this.ensureLogin()) return
let that = this;
uni.getLocation({
type: 'gcj02',
isHighAccuracy: true,
success: (res) => {
that.latitude = res.latitude;
that.longitude = res.longitude;
that.tui.request('/worker/admin/editLocation', "POST", {
workerId: item.workerId,
geolocation: that.latitude + ',' + that.longitude
}, false, false, true).then((res) => {
}).catch((res) => {});
}
});
},
onReachPage() {
if (!this.ensureLogin()) return
if (this.isLoadingPage || this.searchForm.pageNum >= this.totalPages) return;
this.isLoadingPage = true;
this.searchForm.pageNum++;
this.getDelivery();
},
handleScroll(e) {
this.oldScrollTop = e.detail.scrollTop
const detail = e.detail || {};
const viewHeight = this.scrollViewHeight || 0;
const reachBottom = viewHeight > 0 && detail.scrollTop + viewHeight >= detail.scrollHeight - 180;
if (reachBottom) {
this.onReachPage();
}
},
measureScrollView() {
const query = uni.createSelectorQuery().in(this);
query.select('#orderScroll').boundingClientRect();
query.exec((res) => {
if (res && res[0] && res[0].height) {
this.scrollViewHeight = res[0].height;
}
});
},
scrollToTop() {
this.scrollTop = this.oldScrollTop
this.$nextTick(() => {
this.scrollTop = 0
})
},
chooseType(type) {
if (!this.ensureWorkerRegistered()) return
if (this.tab1Checked1 == type) {
this.tab1Checked1 = ''
this.searchForm.deliveryType = null
} else {
this.tab1Checked1 = type;
if (type == 'fantuan') {
this.searchForm.deliveryType = 1
} else if (type == 'kuaidi') {
this.searchForm.deliveryType = 2
} else if (type == 'paotui') {
this.searchForm.deliveryType = 3
}
}
this.searchForm.pageNum = 1
this.scrollToTop()
this.getDelivery()
this.$forceUpdate();
},
shouldNotify(mustFinishTimeStr) {
// 直接解析 ISO 8601 格式的时间字符串(自动处理时区偏移)
const targetTime = new Date(mustFinishTimeStr);
// 校验解析是否成功
if (isNaN(targetTime.getTime())) {
throw new Error('Invalid date format: ' + mustFinishTimeStr);
}
const currentTime = new Date();
const diffMs = targetTime - currentTime; // 毫秒差,正数表示未来,负数表示已过
// 超过目标时间(diffMs <= 0)或 剩余时间不到10分钟(0 < diffMs < 600000)
return diffMs <= 0 || diffMs < 10 * 60 * 1000;
},
getDelivery() {
if (!this.ensureLogin()) return
let that = this
that.isLoadingPage = true;
this.tui.request("/mall/delivery/pagebyworker", "POST", this.searchForm, false, false).then((res) => {
that.isLoadingPage = false;
that.loadStatus = 'nomore';
if (res.code == 200) {
if (this.searchForm.status == 1) {
if (that.searchForm.pageNum == 1) {
that.deliveryItem1 = res.result.records;
} else {
that.deliveryItem1 = [...that.deliveryItem1, ...res.result.records]
}
that.pageData = that.deliveryItem1
} else {
if (that.searchForm.pageNum == 1) {
that.deliveryItem = res.result.records;
} else {
that.deliveryItem = [...that.deliveryItem, ...res.result.records]
}
that.pageData = that.deliveryItem
}
that.totalPages = res.result.pages; // pages = 总页数
that.$forceUpdate();
} else {
that.tui.toast(res.message);
}
if (that.refreshLoading) {
that.finishRefreshLoading()
} else {
uni.hideLoading();
}
}).catch((res) => {
that.isLoadingPage = false;
if (that.refreshLoading) {
that.finishRefreshLoading()
}
});
},
//查看大图
largeImg(img) {
if (!img) return
this.bigImg = img
this.$refs.imgPopup.open()
},
zhipaiChange(e) {
this.zhipaiCheck = e.detail.value
},
checkVoucher(index, type) {
if (type == 'waimai') {
this.waimaRuleList[index].isChecked = !this.waimaRuleList[index].isChecked
} else {
this.paotuiRuleList[index].isChecked = !this.paotuiRuleList[index].isChecked
}
},
productDetail(item) {
const goodsList = item.goodsList || item.mallOrderGoodsList || item.orderGoodsList || [];
this.productData = goodsList;
this.$refs.productPopup.open()
},
buchong() {
this.$refs.carPopup.close()
this.goPartTimeRegister()
},
handleDispatchPopupChange(e) {
this.setHomeTabBarVisible(!(e && e.show))
},
setHomeTabBarVisible(visible) {
this.$emit('tabbar-visible-change', visible)
},
selectRule(item) {
//TODO 这里应该改成 复选,选中的遍历再放进来
// let rule = {
// id: item.id,
// getPushOrder: 1
// }
// this.selectRuleList.push(rule)
this.selectRuleList = []
this.waimaiData = []
this.kuaidiData = []
for (let i = 0; i < this.waimaRuleList.length; i++) {
let rule = {
id: this.waimaRuleList[i].id,
getPushOrder: 1
}
if (!this.waimaRuleList[i].isChecked) {
rule.getPushOrder = 0
} else {
this.waimaiData.push(this.waimaRuleList[i])
}
this.selectRuleList.push(rule)
}
for (let i = 0; i < this.paotuiRuleList.length; i++) {
let rule = {
id: this.paotuiRuleList[i].id,
getPushOrder: 1
}
if (!this.paotuiRuleList[i].isChecked) {
rule.getPushOrder = 0
} else {
this.kuaidiData.push(this.paotuiRuleList[i])
}
this.selectRuleList.push(rule)
}
let submitData = {
userId: uni.getStorageSync('id'),
workerRelaPriceList: this.selectRuleList,
getPushOrder: this.zhipaiCheck ? 1 : 0
};
if (!this.ensureLogin()) return
let that = this;
this.tui.request('/app/workerRelaPrice/batchUpdate', 'post', submitData).then(res => {
uni.hideLoading();
if (res.code == 200) {
let worker = uni.getStorageSync('worker') || {}; // 避免取不到时出错
worker.getPushOrder = that.zhipaiCheck ? 1 : 0;
uni.setStorageSync('worker', worker);
uni.setStorageSync('waimaiData', that.waimaiData)
uni.setStorageSync('kuaidiData', that.kuaidiData)
if (that.zhipaiCheck == false) {
uni.removeStorageSync('waimaiData')
uni.removeStorageSync('kuaidiData')
}
uni.showToast({
title: '设置成功'
});
that.$refs.carPopup.close()
} else {
uni.showToast({
title: res.message,
icon: 'none'
});
}
}).catch(err => {
uni.hideLoading();
});
},
allCheck(type) {
let data = []
if (type == 'waimai') {
data = this.waimaRuleList
} else {
data = this.paotuiRuleList
}
for (let i = 0; i < data.length; i++) {
data[i].isChecked = true
}
},
openPopup() {
if (!this.ensureLogin()) return
const worker = uni.getStorageSync('worker')
if (!worker || !worker.workerId) {
this.$refs.jianzhiPopup.open()
return
}
this.loadWorkerRules(true)
},
showRuleEditedConfirm() {
uni.showModal({
title: '提示',
content: '您编辑了接单规则,开启后才会接到路线订单,需要现在开启吗?',
confirmText: '确认',
cancelText: '取消',
success: (res) => {
if (res.confirm) {
this.openPopup()
}
}
})
},
checkArea() {
this.isArea = !this.isArea
},
openPickupCodePopup(index, item, regionId) {
if (this.pickupCodePopupVisible || this.pickupCodePopupOpening) return
this.pickupCodePopupOpening = true
this.pickupCodePopupVisible = true
this.pickupCode = ''
this.pickupCodeInputFocus = false
this.pickupCodeContext = {
index,
item,
regionId
}
this.$refs.pickupCodePopup.open()
this.$nextTick(() => {
if (this.pickupCodeFocusTimer) {
clearTimeout(this.pickupCodeFocusTimer)
}
this.pickupCodeFocusTimer = setTimeout(() => {
if (!this.pickupCodeContext || !this.pickupCodePopupOpening) return
this.pickupCodeInputFocus = true
this.pickupCodePopupOpening = false
this.pickupCodeFocusTimer = null
}, 300)
})
},
handlePickupCodePopupChange(e) {
const show = e && e.show
this.pickupCodePopupVisible = !!show
if (!show) {
this.pickupCodePopupOpening = false
this.pickupCodeInputFocus = false
if (this.pickupCodeFocusTimer) {
clearTimeout(this.pickupCodeFocusTimer)
this.pickupCodeFocusTimer = null
}
}
},
closePickupCodePopup() {
if (this.pickupCodeSubmitting) return
this.$refs.pickupCodePopup.close()
this.pickupCode = ''
this.pickupCodeContext = null
this.pickupCodeInputFocus = false
this.pickupCodePopupOpening = false
if (this.pickupCodeFocusTimer) {
clearTimeout(this.pickupCodeFocusTimer)
this.pickupCodeFocusTimer = null
}
},
handlePickupCodeInput(e) {
const value = String(e.detail.value || '').replace(/\D/g, '').slice(0, 4)
this.pickupCode = value
return value
},
submitPickupCode() {
if (this.pickupCodeSubmitting) return
const context = this.pickupCodeContext
if (!context) return
if (!this.pickupCode) {
uni.showToast({
title: '请输入取餐码',
icon: 'none'
})
return
}
this.pickupCodeSubmitting = true
this.tui.request('/mall/delivery/transferPickup', 'POST', {
regionId: context.regionId,
deliveryId: context.item.id,
workerId: context.item.workerId,
pickupCode: this.pickupCode
}, false, true).then((res) => {
if (res.code == 200) {
this.pageData.splice(context.index, 1)
this.decreaseDeliveryStatusCount(2)
this.tui.toast(res.message, 200)
this.$refs.pickupCodePopup.close()
this.pickupCode = ''
this.pickupCodeContext = null
this.pickupCodeInputFocus = false
this.$forceUpdate()
} else {
uni.showToast({
title: res.message || '取餐码错误',
icon: 'none',
duration: 2500
})
}
this.pickupCodeSubmitting = false
}).catch(() => {
this.pickupCodeSubmitting = false
})
},
changeStatus(index, item, status) {
if (!this.ensureLogin()) return
if (status == 3) {
if (this.completingDeliveryIds[item.id]) {
this.tui.toast('送达处理中,请勿重复提交')
return
}
this.$set(this.completingDeliveryIds, item.id, true)
}
let regionId = JSON.parse(uni.getStorageSync('area')).id
let url = ''
if (status == 2) {
if (item.transferDelivery == 1) {
if (this.pickupCodePopupVisible || this.pickupCodePopupOpening) return
this.openPickupCodePopup(index, item, regionId)
return
}
url = "/mall/delivery/pickup"
} else if (status == 3) {
url = "/mall/delivery/complete"
} else if (status == 1) {
url = "/mall/delivery/arriveShop"
}
let that = this
this.getUserLocation(item)
that.tui.request(url, "POST", {
regionId: regionId,
deliveryId: item.id,
workerId: item.workerId
}, false, true).then((res) => {
if (status == 3) {
that.$delete(that.completingDeliveryIds, item.id)
}
if (res.code == 200) {
if (status == 2 || status == 3) {
that.pageData.splice(index, 1)
that.decreaseDeliveryStatusCount(status)
} else {
that.pageData[index].arriveTime = "qq"
}
that.tui.toast(res.message, 200);
/* that.searchForm.pageNum = 1
that.getDelivery() */
that.$forceUpdate();
} else {
that.tui.toast(res.message, 200);
return;
}
uni.hideLoading();
}).catch((res) => {
if (status == 3) {
that.$delete(that.completingDeliveryIds, item.id)
}
});
},
checkTab1(type) {
if (!this.ensureWorkerRegistered()) return
this.tab1Checked = type
if (type == 'daiqu') {
this.searchForm.status = 1
} else {
this.searchForm.status = 2
}
this.searchForm.pageNum = 1
this.scrollToTop()
this.getDelivery()
},
refreshCurrentTab() {
if (!this.ensureWorkerRegistered()) return
if (this.refreshLoading) return
this.refreshLoading = true
this.refreshLoadingStartTime = Date.now()
if (this.refreshLoadingTimer) {
clearTimeout(this.refreshLoadingTimer)
this.refreshLoadingTimer = null
}
uni.showLoading({
title: '刷新中...',
mask: true
})
this.searchForm.pageNum = 1
this.scrollToTop()
this.getDelivery()
},
finishRefreshLoading() {
const elapsed = Date.now() - this.refreshLoadingStartTime
const delay = Math.max(1000 - elapsed, 0)
if (this.refreshLoadingTimer) {
clearTimeout(this.refreshLoadingTimer)
}
this.refreshLoadingTimer = setTimeout(() => {
this.refreshLoading = false
this.refreshLoadingTimer = null
uni.hideLoading()
}, delay)
},
makeCall(phone) {
uni.makePhoneCall({
phoneNumber: phone
});
},
changeOnline(value) {
if (!this.ensureLogin()) return
const worker = uni.getStorageSync('worker')
if (!worker || !worker.workerId) {
this.tui.toast('您还没有注册兼职')
return
}
let url = ''
if (this.isOnLine == value) {
if (value == 0) {
url = '/worker/offLine'
value = 1
} else {
url = '/worker/onLine'
value = 0
}
} else {
if (value == 0) {
url = '/worker/offLine'
} else {
url = '/worker/onLine'
}
}
this.tui.request(url, "POST", {
id: worker.workerId
}, false, true).then((res) => {
if (res.code == 200) {
let worker = uni.getStorageSync('worker') || {}; // 避免取不到时出错
worker.isOnLine = value;
this.isOnLine = value
uni.setStorageSync('worker', worker);
this.tui.toast(value == 0 ? '下线后不再接收新订单通知' : res.message)
} else {
this.tui.toast(res.message)
}
})
this.isArea = !this.isArea
this.$forceUpdate()
},
ceshi(e) {
if (e.detail.code) {
// 将 code 发送给后端
this.tui.request("/social/wechat/getPhone", "POST", {
code: e.detail.code
}, false, true).then((res) => {
if (res.code == 200) {
} else {
this.tui.toast(res.message)
}
})
}
}
}
}
</script>
<style lang="scss">
page {
width: 100%;
height: 100%;
font-size: 24rpx;
background: #F5F8F5;
color: #00231C;
}
.page1 {
width: 100%;
height: 100%;
font-size: 24rpx;
position: relative;
display: flex;
flex-direction: column;
}
.title {
background: url('https://jewel-shop.oss-cn-beijing.aliyuncs.com/8bc15960c2dc40268e295d6dd23aecce.png') no-repeat;
width: 100%;
height: 380rpx;
}
.title-sreach {
width: 100%;
display: flex;
height: 200rpx;
position: relative;
}
.sort-member {
line-height: 60rpx;
text-align: center;
height: 60rpx;
}
.delivery-title-tabs {
width: 460rpx;
display: flex;
align-items: center;
}
.delivery-title-tabs .tab1 {
width: 340rpx;
flex-shrink: 0;
}
.title-refresh {
width: 58rpx;
height: 58rpx;
margin-left: 18rpx;
flex-shrink: 0;
display: flex;
align-items: center;
justify-content: center;
border: 2rpx solid rgba(166, 255, 234, 0.88);
border-radius: 50%;
background: rgba(255, 255, 255, 0.7);
box-shadow: 0 8rpx 20rpx rgba(0, 35, 28, 0.08);
}
.title-refresh:active {
opacity: 0.75;
}
.title-refresh--loading {
animation: refresh-rotate 0.8s linear infinite;
}
@keyframes refresh-rotate {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
.tab1 {
height: 60rpx;
line-height: 60rpx;
display: flex;
}
.tabs1 {
position: relative;
font-size: 30rpx;
font-weight: 700;
color: #777;
flex: 1;
min-width: 0;
display: flex;
justify-content: center;
align-items: center;
white-space: nowrap;
}
.tab-label {
display: flex;
align-items: center;
justify-content: center;
white-space: nowrap;
}
.tab-count {
min-width: 32rpx;
height: 32rpx;
line-height: 32rpx;
margin-left: 8rpx;
padding: 0 8rpx;
display: inline-block;
border-radius: 999rpx;
background: linear-gradient(135deg, #ff8a1f 0%, #ff3f5f 100%);
color: #fff;
font-size: 20rpx;
font-weight: 900;
text-align: center;
vertical-align: middle;
box-sizing: border-box;
}
.delivery-filter-row {
width: 95%;
height: 72rpx;
margin: -200rpx auto 0;
display: flex;
align-items: center;
line-height: 64rpx;
}
.delivery-ranking-btn {
margin-left: auto;
height: 58rpx;
line-height: 58rpx;
padding: 0 22rpx;
border-radius: 999rpx;
background: linear-gradient(135deg, #fff3c7 0%, #ffd7a6 100%);
box-shadow: 0 10rpx 22rpx rgba(255, 155, 75, 0.16);
color: #8a4b0e;
font-size: 22rpx;
font-weight: 900;
text-align: center;
flex-shrink: 0;
}
.delivery-ranking-btn:active {
transform: scale(0.96);
}
.delivery-status-card {
width: 95%;
margin: 18rpx auto 0;
padding: 22rpx;
box-sizing: border-box;
display: flex;
align-items: center;
border-radius: 28rpx;
background:
radial-gradient(circle at 92% 20%, rgba(166, 255, 234, 0.58) 0, rgba(166, 255, 234, 0) 160rpx),
linear-gradient(135deg, rgba(255, 255, 255, 0.94), rgba(244, 255, 250, 0.92));
box-shadow: 0 16rpx 36rpx rgba(0, 35, 28, 0.1);
}
.delivery-status-main {
flex: 1;
min-width: 0;
}
.delivery-status-title-row {
display: flex;
align-items: center;
}
.delivery-status-title {
font-size: 30rpx;
font-weight: 900;
color: #00231C;
}
.delivery-status-pill {
margin-left: 14rpx;
height: 40rpx;
line-height: 40rpx;
padding: 0 16rpx;
border-radius: 40rpx;
background: rgba(255, 117, 88, 0.14);
color: #d34a32;
font-size: 22rpx;
font-weight: 800;
}
.delivery-status-pill--on {
background: rgba(166, 255, 234, 0.72);
color: #00624f;
}
.delivery-status-desc {
margin-top: 10rpx;
color: #4c625d;
font-size: 24rpx;
line-height: 34rpx;
}
.delivery-status-meta {
margin-top: 12rpx;
display: flex;
flex-wrap: wrap;
gap: 10rpx;
color: #0b6b5a;
font-size: 20rpx;
font-weight: 700;
}
.delivery-status-meta text {
padding: 4rpx 12rpx;
border-radius: 999rpx;
background: rgba(166, 255, 234, 0.36);
}
.delivery-status-meta .delivery-status-meta--warn {
background: rgba(255, 117, 88, 0.12);
color: #d96b5c;
}
.delivery-status-actions {
width: 172rpx;
margin-left: 16rpx;
flex-shrink: 0;
}
.delivery-status-action {
height: 58rpx;
line-height: 58rpx;
margin-top: 10rpx;
border-radius: 62rpx;
background: rgba(255, 255, 255, 0.82);
color: #52635f;
font-size: 22rpx;
font-weight: 800;
text-align: center;
border: 2rpx solid rgba(0, 35, 28, 0.08);
box-shadow: 0 8rpx 18rpx rgba(0, 35, 28, 0.08);
}
.delivery-status-action:first-child {
margin-top: 0;
}
.delivery-status-action--primary {
background: rgba(255, 255, 255, 0.72);
color: #047464;
border-color: rgba(88, 220, 190, 0.52);
box-shadow: 0 8rpx 18rpx rgba(0, 112, 91, 0.08);
}
.delivery-status-action--online {
background: linear-gradient(90deg, rgba(227, 255, 150, 1), rgba(166, 255, 234, 1));
color: #00231C;
border-color: rgba(166, 255, 234, 0.8);
box-shadow: 0 10rpx 22rpx rgba(0, 112, 91, 0.14);
}
.filter-divider {
flex-shrink: 0;
padding: 0 14rpx 0 2rpx;
color: rgba(0, 35, 28, 0.72);
font-weight: 700;
}
.content {
flex: 1;
width: 95%;
min-height: 0;
overflow: hidden;
margin: 20rpx auto 0;
}
.order-scroll {
width: 100%;
height: 100%;
overflow: scroll;
-webkit-overflow-scrolling: touch;
box-sizing: border-box;
}
.list-bottom-space {
width: 100%;
height: calc(260rpx + constant(safe-area-inset-bottom));
height: calc(260rpx + env(safe-area-inset-bottom));
flex-shrink: 0;
}
.delivery-empty-guide {
margin: 20rpx auto;
padding: 44rpx 30rpx;
border-radius: 30rpx;
background: #fff;
text-align: center;
box-shadow: 0 12rpx 30rpx rgba(0, 35, 28, 0.06);
}
.delivery-empty-illustration {
width: 180rpx;
height: 180rpx;
line-height: 180rpx;
margin: 0 auto 24rpx;
border-radius: 50%;
background: linear-gradient(135deg, #e3ff96, #a6ffea);
color: #07372f;
font-size: 28rpx;
font-weight: 900;
}
.delivery-empty-title {
font-size: 34rpx;
font-weight: 900;
color: #00231C;
}
.delivery-empty-desc {
margin-top: 14rpx;
color: #6d7b77;
font-size: 24rpx;
line-height: 38rpx;
}
.delivery-empty-btn {
width: 320rpx;
height: 78rpx;
line-height: 78rpx;
margin: 28rpx auto 0;
border-radius: 78rpx;
background: linear-gradient(90deg, rgba(227, 255, 150, 1), rgba(166, 255, 234, 1));
color: #00231C;
font-size: 28rpx;
font-weight: 900;
}
.box1 {
width: 100%;
margin: 20rpx auto 20rpx;
background: #fff;
border-radius: 20rpx;
padding: 20rpx;
position: relative;
}
.goods-content {
flex: 1;
}
.goods-name {
font-size: 32rpx;
font-weight: 900;
}
.maotou {
width: auto;
background: url('https://jewel-shop.oss-cn-beijing.aliyuncs.com/a1584a13e9db4b6fbcc66890219d0018.png') no-repeat;
height: 90rpx;
background-size: 100%;
position: absolute;
top: -20rpx;
right: 20rpx;
text-align: center;
line-height: 140rpx;
font-weight: 900;
font-size: 24rpx;
padding: 0 10px;
}
.right {
width: 60rpx;
padding-top: 20rpx;
}
.shop-address-row {
display: flex;
align-items: center;
width: 100%;
min-width: 0;
margin-top: 8rpx;
}
.detail-tag {
width: 32rpx;
height: 30rpx;
line-height: 30rpx;
flex-shrink: 0;
font-weight: 700;
font-size: 20rpx;
color: #fff;
text-align: center;
background: #00BFFF;
border-radius: 10rpx;
margin-right: 10rpx;
}
.shop-address {
flex: 1;
min-width: 0;
color: #777;
line-height: 40rpx;
word-wrap: break-word;
word-break: break-all;
white-space: normal;
}
.express-info-card {
margin-top: 16rpx;
padding: 16rpx 18rpx;
border-radius: 18rpx;
background: rgba(247, 248, 248, 0.72);
color: #596560;
box-sizing: border-box;
}
.express-info-row {
display: flex;
align-items: center;
flex-wrap: wrap;
gap: 12rpx;
}
.express-info-item {
min-height: 48rpx;
padding: 0 16rpx;
display: flex;
align-items: center;
border-radius: 999rpx;
background: #fff;
box-sizing: border-box;
max-width: 100%;
}
.express-info-item--code {
flex: 1;
min-width: 220rpx;
}
.express-info-label {
flex-shrink: 0;
margin-right: 8rpx;
color: #8a9691;
font-size: 22rpx;
font-weight: 700;
line-height: 32rpx;
}
.express-info-value {
min-width: 0;
color: #313b37;
font-size: 24rpx;
font-weight: 900;
line-height: 34rpx;
word-break: break-all;
}
.express-picture-list {
margin-top: 14rpx;
display: flex;
align-items: center;
flex-wrap: wrap;
gap: 12rpx;
}
.express-picture-title {
height: 44rpx;
line-height: 44rpx;
padding: 0 14rpx;
border-radius: 999rpx;
background: rgba(166, 255, 234, 0.46);
color: #0b6b5a;
font-size: 22rpx;
font-weight: 800;
}
.express-picture {
width: 112rpx;
height: 112rpx;
border-radius: 14rpx;
background: #eef4f1;
border: 1px solid rgba(0, 35, 28, 0.08);
box-sizing: border-box;
}
.refund-status {
width: 100%;
margin-top: 24rpx;
display: flex;
align-items: center;
}
.refund-status-text {
width: 100%;
min-height: 72rpx;
padding: 0 22rpx;
display: flex;
align-items: center;
background: rgba(255, 244, 236, 0.96);
color: #c56a35;
border: 1px solid rgba(255, 181, 120, 0.52);
border-radius: 18rpx;
font-size: 26rpx;
font-weight: 800;
box-sizing: border-box;
}
.refund-status-dot {
width: 14rpx;
height: 14rpx;
margin-right: 12rpx;
border-radius: 50%;
background: #ff9a4a;
box-shadow: 0 0 0 8rpx rgba(255, 154, 74, 0.12);
}
.order-action {
width: 100%;
height: 104rpx;
margin-top: 32rpx;
}
.order-action-btn {
position: relative;
width: 100%;
height: 96rpx;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
border-radius: 48rpx;
color: #fff;
font-size: 34rpx;
font-weight: 900;
letter-spacing: 2rpx;
box-shadow: 0 14rpx 30rpx rgba(0, 70, 58, 0.18);
}
.order-action-btn::before {
content: '';
position: absolute;
top: 0;
left: -20%;
width: 56%;
height: 100%;
background: linear-gradient(90deg, rgba(255, 255, 255, 0), rgba(255, 255, 255, 0.22), rgba(255, 255, 255, 0));
transform: skewX(-18deg);
}
.order-action-btn:active {
transform: scale(0.98);
opacity: 0.9;
}
.order-action-btn--arrive,
.order-action-btn--pickup,
.order-action-btn--complete {
background:
radial-gradient(circle at 88% 45%, rgba(166, 255, 234, 0.52) 0, rgba(166, 255, 234, 0) 120rpx),
linear-gradient(90deg, #07372f 0%, #005849 52%, #0aa385 100%);
}
.order-action-icon {
position: relative;
width: 52rpx;
height: 52rpx;
margin-right: 12rpx;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
background: rgba(255, 255, 255, 0.18);
}
.guize-list {
width: 100%;
padding: 30rpx 28rpx 0;
background: #fff;
border-radius: 36rpx 36rpx 0 0;
height: 76vh;
position: relative;
display: flex;
flex-direction: column;
box-sizing: border-box;
}
.dispatch-popup {
position: relative;
z-index: 1001;
}
.dispatch-popup-title {
line-height: 48rpx;
font-size: 34rpx;
font-weight: 900;
text-align: center;
color: #00231C;
}
.dispatch-popup-desc {
margin: 12rpx 0 8rpx;
padding: 18rpx 20rpx;
border-radius: 18rpx;
background: rgba(166, 255, 234, 0.22);
color: #526964;
font-size: 24rpx;
line-height: 36rpx;
}
.dispatch-warning {
margin: 12rpx 0;
padding: 14rpx 18rpx;
border-radius: 16rpx;
background: rgba(255, 233, 89, 0.24);
color: #926500;
font-size: 24rpx;
font-weight: 700;
}
.dispatch-empty {
margin: 20rpx 0;
padding: 34rpx 20rpx;
border-radius: 22rpx;
background: rgba(247, 248, 248, 0.9);
text-align: center;
}
.dispatch-empty-title {
font-size: 30rpx;
font-weight: 900;
color: #00231C;
}
.dispatch-empty-desc {
margin-top: 10rpx;
color: #7b8a85;
font-size: 24rpx;
line-height: 36rpx;
}
.dispatch-rule-fee {
height: 40rpx;
line-height: 40rpx;
margin: 20rpx 16rpx 0 0;
padding: 0 12rpx;
border-radius: 40rpx;
background: rgba(255, 233, 89, 0.32);
color: #8a5a00;
font-size: 20rpx;
font-weight: 800;
flex-shrink: 0;
}
.dispatch-rule-scroll {
flex: 1;
min-height: 0;
height: auto;
overflow-y: scroll;
}
.dispatch-scroll-bottom {
width: 100%;
height: 60rpx;
line-height: 60rpx;
color: #9ca6a2;
text-align: center;
}
.dispatch-actions {
display: flex;
gap: 18rpx;
padding: 18rpx 0 24rpx;
padding: 18rpx 0 calc(24rpx + constant(safe-area-inset-bottom));
padding: 18rpx 0 calc(24rpx + env(safe-area-inset-bottom));
background: #fff;
flex-shrink: 0;
z-index: 2;
}
.dispatch-action-btn {
flex: 1;
height: 78rpx;
line-height: 78rpx;
border-radius: 78rpx;
text-align: center;
font-size: 28rpx;
font-weight: 900;
box-sizing: border-box;
}
.dispatch-action-btn--secondary {
background: rgba(166, 255, 234, 0.28);
color: #00624f;
border: 2rpx solid rgba(166, 255, 234, 0.88);
}
.dispatch-action-btn--primary {
background: linear-gradient(90deg, rgba(227, 255, 150, 1), rgba(166, 255, 234, 1));
color: #00231C;
box-shadow: 0 10rpx 22rpx rgba(0, 112, 91, 0.14);
}
.zhipai-box {
display: flex;
height: 100rpx;
line-height: 100rpx;
font-size: 32rpx;
font-weight: 700;
border-bottom: 1px solid #eee;
}
.zhipai {
flex: 1;
text-align: right;
}
.radio-check {
background: linear-gradient(90deg, rgba(227, 255, 150, 1), rgba(166, 255, 234, 1));
width: 48rpx;
height: 48rpx;
border-radius: 48rpx;
text-align: center;
line-height: 48rpx;
margin: 16rpx 20rpx 0 0;
}
.radio-no-check {
width: 48rpx;
height: 48rpx;
border-radius: 48rpx;
border: 1px solid #eee;
margin: 16rpx 20rpx 0 0;
}
.guize1-qusong {
display: flex;
flex: 1;
padding-top: 20rpx;
}
.guize1 {
display: flex;
}
.qusong1 {
width: 40rpx;
height: 40rpx;
background: rgba(0, 35, 28, 1);
color: #fff;
border-radius: 40rpx;
text-align: center;
line-height: 40rpx;
font-size: 20rpx;
z-index: 80;
}
.qusong2 {
height: 40rpx;
font-size: 24rpx;
line-height: 38rpx;
text-align: center;
background: rgba(166, 255, 234, 0.5);
padding: 0 20rpx;
margin-left: -10rpx;
font-weight: 700;
border-top-right-radius: 40rpx;
border-bottom-right-radius: 40rpx;
}
.qusong3 {
width: 190rpx;
height: 70rpx;
background: #fff;
border-radius: 10rpx;
padding: 10rpx 20rpx;
flex: 1;
}
.btn {
width: 95%;
height: 100rpx;
font-size: 32rpx;
font-weight: 700;
background: linear-gradient(90deg, rgba(227, 255, 150, 1), rgba(166, 255, 234, 1));
border-radius: 100rpx;
line-height: 100rpx;
text-align: center;
margin: 20rpx 20rpx;
flex: 1;
}
.code-box {
display: inline-block;
height: 32rpx;
line-height: 32rpx;
background: rgba(166, 255, 234, 0.4);
padding: 0 20rpx;
border-radius: 10rpx;
color: #000;
border: 1px solid rgba(2, 251, 221, 1);
}
.img-popup-content {
width: 500rpx;
height: 500rpx;
}
.pickup-code-popup {
width: 640rpx;
padding: 42rpx 34rpx 30rpx;
box-sizing: border-box;
border-radius: 32rpx;
background: #fff;
box-shadow: 0 24rpx 56rpx rgba(0, 35, 28, 0.18);
}
.pickup-code-title {
color: #00231C;
font-size: 34rpx;
font-weight: 900;
line-height: 46rpx;
text-align: center;
}
.pickup-code-desc {
margin-top: 10rpx;
color: #7b8a85;
font-size: 24rpx;
line-height: 34rpx;
text-align: center;
}
.pickup-code-input {
width: 100%;
height: 92rpx;
margin-top: 34rpx;
padding: 0 26rpx;
box-sizing: border-box;
border: 2rpx solid rgba(166, 255, 234, 0.88);
border-radius: 22rpx;
background: rgba(247, 255, 251, 0.96);
color: #00231C;
font-size: 34rpx;
font-weight: 800;
text-align: center;
}
.pickup-code-actions {
display: flex;
gap: 18rpx;
margin-top: 34rpx;
}
.pickup-code-action {
flex: 1;
height: 78rpx;
line-height: 78rpx;
border-radius: 78rpx;
text-align: center;
font-size: 28rpx;
font-weight: 900;
}
.pickup-code-action--cancel {
background: rgba(247, 248, 248, 0.96);
color: #526964;
}
.pickup-code-action--confirm {
background: linear-gradient(90deg, rgba(227, 255, 150, 1), rgba(166, 255, 234, 1));
color: #00231C;
}
.chaoda {
height: 30rpx;
line-height: 30rpx;
margin: 10rpx 0 0 20rpx;
padding: 0 10rpx;
background: rgba(255, 117, 88, 1);
color: #fff;
border-radius: 10rpx;
}
.appointment-delivery-tag {
height: 48rpx;
margin: 10rpx 12rpx 0 0;
padding: 0 16rpx;
border-radius: 14rpx;
background: linear-gradient(135deg, #ff8f1f 0%, #ff6a3d 100%);
color: #fff;
font-size: 22rpx;
font-weight: 800;
line-height: 48rpx;
box-shadow: 0 8rpx 18rpx rgba(255, 106, 61, 0.16);
}
.shangxian-btn {
background: url('https://jewel-shop.oss-cn-beijing.aliyuncs.com/7620b3eed7b14bb69d3c456ed0be72b3.png') no-repeat;
padding-left: 16rpx;
}
.lixian-btn {
background: url('https://jewel-shop.oss-cn-beijing.aliyuncs.com/462cacb9682f4919a3e750700bbc5f3e.png') no-repeat;
text-align: right;
padding-right: 16rpx;
}
.shangxia-btn {
width: 150rpx;
height: 64rpx;
line-height: 64rpx;
flex-shrink: 0;
background-size: 132rpx 50rpx;
background-position: center;
font-size: 20rpx;
font-weight: 700;
box-sizing: border-box;
}
.guize-box {
font-size: 20rpx;
font-weight: 700;
background: rgba(166, 255, 234, 1);
width: 132rpx;
height: 64rpx;
line-height: 64rpx;
border-radius: 50rpx;
margin-right: 12rpx;
padding: 0 4rpx;
text-align: center;
box-sizing: border-box;
flex-shrink: 0;
}
.guize-box1 {
font-size: 20rpx;
font-weight: 700;
text-align: center;
width: 110rpx;
height: 64rpx;
line-height: 64rpx;
border-radius: 50rpx;
margin-right: 12rpx;
padding: 0 4rpx;
box-sizing: border-box;
flex-shrink: 0;
}
.product-popup-content {
width: 680rpx;
max-height: 880rpx;
padding: 34rpx 28rpx 30rpx;
box-sizing: border-box;
overflow: scroll;
border-radius: 36rpx;
background:
radial-gradient(circle at 92% 4%, rgba(166, 255, 234, 0.38) 0, rgba(166, 255, 234, 0) 180rpx),
linear-gradient(180deg, #ffffff 0%, #f8fffc 100%);
box-shadow: 0 24rpx 56rpx rgba(0, 35, 28, 0.18);
}
.product-popup-header {
margin-bottom: 26rpx;
text-align: center;
}
.product-popup-title {
color: #143d35;
font-size: 36rpx;
font-weight: 900;
line-height: 48rpx;
}
.product-popup-subtitle {
margin-top: 8rpx;
color: #7b8a85;
font-size: 24rpx;
line-height: 34rpx;
}
.product-popup-list {
display: flex;
flex-direction: column;
gap: 20rpx;
}
.product-popup-card {
display: flex;
align-items: center;
padding: 22rpx;
border: 1px solid rgba(166, 255, 234, 0.58);
border-radius: 28rpx;
background: rgba(255, 255, 255, 0.88);
box-shadow: 0 12rpx 28rpx rgba(0, 35, 28, 0.06);
}
.product-popup-img {
width: 128rpx;
height: 128rpx;
flex-shrink: 0;
overflow: hidden;
border-radius: 22rpx;
background: #f0f5f3;
img {
width: 100%;
height: 100%;
background-size: 100%;
}
}
.product-popup-info {
flex: 1;
min-width: 0;
padding: 0 22rpx;
}
.product-popup-name {
color: #172f2a;
font-size: 30rpx;
font-weight: 900;
line-height: 42rpx;
}
.product-popup-spec {
display: flex;
align-items: flex-start;
margin-top: 16rpx;
}
.product-popup-label {
flex-shrink: 0;
height: 34rpx;
padding: 0 14rpx;
border-radius: 999rpx;
background: rgba(166, 255, 234, 0.72);
color: #126255;
font-size: 20rpx;
font-weight: 800;
line-height: 34rpx;
}
.product-popup-spec-text {
flex: 1;
margin-left: 12rpx;
color: #65736f;
font-size: 24rpx;
line-height: 34rpx;
word-break: break-all;
}
.product-popup-quantity {
width: 92rpx;
height: 92rpx;
flex-shrink: 0;
border-radius: 28rpx;
background: linear-gradient(135deg, #fff4ce 0%, #a6ffea 100%);
color: #103f36;
text-align: center;
box-shadow: 0 10rpx 20rpx rgba(0, 35, 28, 0.08);
}
.product-popup-quantity-num {
padding-top: 16rpx;
font-size: 30rpx;
font-weight: 900;
line-height: 34rpx;
}
.product-popup-quantity-label {
margin-top: 2rpx;
color: #52736b;
font-size: 20rpx;
line-height: 28rpx;
}
.product-popup-empty {
padding: 80rpx 20rpx;
border-radius: 28rpx;
background: rgba(247, 255, 251, 0.9);
color: #7b8a85;
font-size: 28rpx;
font-weight: 700;
text-align: center;
}
.jianzhi-content {
width: 300px;
height: 350px;
position: relative;
}
.jianzhi-close {
position: absolute;
bottom: -50px;
left: 130px;
}
</style>