wangfukang 2 weeks ago
parent
commit
af80194a92
  1. 17
      package2/group/groupBuyList.vue
  2. 431
      package2/group/groupBuySingle.vue
  3. 694
      package2/group/groupPendingList.vue
  4. 4
      package2/group/searchGroup.vue
  5. 13
      package2/group/studentStoreList.vue
  6. 32
      package2/myCenter/partTimeJobRegister.vue
  7. 4
      package2/myCenter/wallet.vue
  8. 719
      package2/partTimeJob/workerOrderList.vue

17
package2/group/groupBuyList.vue

@ -21,7 +21,7 @@
</view>
</view>
<view class="title-tab">
<view class="campus-banner" @tap="goDetail('search')">
<view class="campus-banner" @tap="goPendingGroup">
<view class="banner-glow"></view>
<view class="steam steam-one"></view>
<view class="steam steam-two"></view>
@ -31,8 +31,8 @@
<view class="food-float float-three">🍢</view>
<view class="food-float float-four">🥟</view> -->
<view class="banner-copy">
<view class="banner-sticker">宿舍正在拼</view>
<view class="banner-title">今天谁还没吃</view>
<view class="banner-sticker">大家正在拼</view>
<view class="banner-title">快来加入成团</view>
<!-- <view class="banner-desc">楼下热乎的那口凑个饭搭子就出发</view> -->
<view class="banner-bubbles">
<text>拼团局开了</text>
@ -126,7 +126,7 @@
<view class="shop-content">
<view class="shop-live-row">
<text>{{getDormStatus(index)}}</text>
<text>速速加入</text>
<text>{{item.mingchu ? '明厨亮灶' : '速速加入'}}</text>
</view>
<view class="shop-name">
{{item.shopName}}
@ -560,7 +560,7 @@
console.log('数据',item)
if (type == 'shop') {
uni.navigateTo({
url: '/package2/group/groupBuySingle?type=shop&item=' + JSON.stringify(item)
url: '/package2/group/groupBuySingle?type=shop&item=' + encodeURIComponent(JSON.stringify(item))
})
} else if (type == 'search') {
if (item) {
@ -578,10 +578,15 @@
}
} else {
uni.navigateTo({
url: '/package2/group/groupBuySingle?type=product&item=' + JSON.stringify(item)
url: '/package2/group/groupBuySingle?type=product&item=' + encodeURIComponent(JSON.stringify(item))
})
}
},
goPendingGroup() {
uni.navigateTo({
url: '/package2/group/groupPendingList?scene=takeaway'
})
},
back() {
uni.navigateBack()
},

431
package2/group/groupBuySingle.vue

@ -1,5 +1,6 @@
<template>
<!-- 拼团单一商家 -->
<page-meta :page-style="popupPageStyle"></page-meta>
<view class="page1" :class="{'store-group-page': isStoreGroupOrder}">
<!-- 固定顶部导航栏悬浮在背景图之上 -->
<view class="nav-bar"
@ -42,10 +43,10 @@
</view>
<view class="shop-content-center">
<view class="shop-rate">
<view class="shop-rate-num">{{shopItem.shopScore}}</view>
<view class="shop-rate-num">{{shopItem.shopScore ? shopItem.shopScore : 5}}</view>
<view>
<uni-rate :disabled="true" size="20" disabledColor="rgba(255, 184, 84, 1)"
:value="shopItem.shopScore" />
:value="shopItem.shopScore ? shopItem.shopScore : 5" />
</view>
</view>
<view class="shop-tag">
@ -56,8 +57,16 @@
</view>
</view>
<view class="shop-content-bottom">
<view class="shop-deal" @tap.stop="goDetail('shopEvaluate')" style="color: #777;">
店铺评价<uni-icons type="right" size="12"></uni-icons>
<view class="shop-action-list">
<view class="shop-action-btn" @tap.stop="goDetail('openKitchen')">
明厨亮灶
</view>
<view class="shop-action-btn" @tap.stop="goDetail('shopDetail')">
商家资质
</view>
<view class="shop-action-btn" @tap.stop="goDetail('shopEvaluate')">
店铺评价
</view>
</view>
<view class="shop-deal1">
销量 <text> {{shopItem.saleCount != null ? shopItem.saleCount : 0}}</text>
@ -126,7 +135,7 @@
</view>
<view class="catalog-goods">
<view class="goods-member goods-card" :id="'category-' + item.categoryId"
v-for="(item,index) in productItem" :key="index" @tap="goDetail('product',item)">
v-for="(item,index) in productItem" :key="index" @tap="openGoodsDetail(item)">
<view class="goods-card-shine"></view>
<view @tap.stop="buyingye" v-if="item.status == 1"
style="width: 100%;height:100%;position: absolute;top: 0;background: rgba(0, 0, 0, 0.1);z-index: 999;border-radius: 20rpx;">
@ -139,7 +148,7 @@
alt=""
style="width:30rpx;height:30rpx;position: absolute;top: 0;left: 0;background-size: 100%;" />
</view>
<view class="goods-content" @tap="goDetail('goodsDetail')">
<view class="goods-content">
<view class="goods-name">
{{item.productName}}
</view>
@ -175,7 +184,7 @@
<view v-if="item.productGroupBuyPrices != null && item.isMoreBuy != 1"
class="goods-btn group-buy-btn" style="margin-left: 6%;"
:style="{'float':groupId != ''?'right':''}" @tap="openPopup('xiadan','pintuan',item)">
:style="{'float':groupId != ''?'right':''}" @tap.stop="openPopup('xiadan','pintuan',item)">
<view class="btn-spark">
<view class="spark-dot spark-dot-1"></view>
<view class="spark-dot spark-dot-2"></view>
@ -183,7 +192,7 @@
</view>
<text>拼团购买¥{{ getGroupPrice(item) }}</text>
</view>
<view class="goods-btn solo-buy-btn" v-if="!groupId" @tap="openPopup('xiadan','dandu',item)"
<view class="goods-btn solo-buy-btn" v-if="!groupId" @tap.stop="openPopup('xiadan','dandu',item)"
style="background: rgba(166, 255, 234, 0.3);border: 1px solid rgba(166, 255, 234, 0.5);height:68rpx;">
直接购买¥{{item.attributeListPrice | sliceMsg}}
</view>
@ -205,7 +214,10 @@
</view>
<view class="bottom-price">
<view class="bottom-price-label">已选合计</view>
<view>{{cartTotalPrice}}</view>
<view>{{cartTotalPayPrice}}</view>
<view class="package-fee-tip" v-if="cartTotalPackageFeeNumber > 0">
含餐盒费{{cartTotalPackageFee}}
</view>
</view>
</view>
<view class="bottom-right checkout-btn" @tap="submitCartCheckout">
@ -218,7 +230,7 @@
<!-- 购物车弹窗 -->
<uni-popup ref="carPopup" background-color="#fff">
<uni-popup ref="carPopup" background-color="#fff" @change="onBottomPopupChange">
<view class="car-content">
<view class="car-close" @tap="$refs.carPopup.close()">
<uni-icons type="close" size="30" color="#fff"></uni-icons>
@ -247,8 +259,11 @@
</view>
<view class="goods-content-bottom" style="margin-top: 10rpx;">
<view
style="font-size: 28rpx;line-height: 54rpx;margin-right: 20rpx;flex: 1;color: red;">
class="cart-item-price">
{{cartItem.price}}
<text class="package-fee-pill" v-if="getPackageFee(cartItem.item) > 0">
餐盒费{{formatMoney(getPackageFee(cartItem.item))}}
</text>
</view>
<view class="goods-num">
<view class="num-plus" style="background: #999;color: #fff;"
@ -275,7 +290,10 @@
alt="" />
</view>
<view class="bottom-price" style="line-height: 48rpx;">
<view>{{cartTotalPrice}}</view>
<view>{{cartTotalPayPrice}}</view>
<view class="package-fee-tip" v-if="cartTotalPackageFeeNumber > 0">
含餐盒费{{cartTotalPackageFee}}
</view>
</view>
</view>
<view class="bottom-right" @tap="submitCartCheckout">
@ -296,8 +314,43 @@
alt="购物车是空的" style="width:600rpx;height:740rpx;" />
</view>
</uni-popup>
<!-- 商品详情弹窗 -->
<uni-popup ref="goodsDetailPopup" background-color="#fff" @change="onBottomPopupChange">
<view class="car-content goods-detail-popup">
<view class="car-close" @tap="$refs.goodsDetailPopup.close()">
<uni-icons type="close" size="30" color="#fff"></uni-icons>
</view>
<view class="detail-popup-title">商品详情</view>
<scroll-view scroll-y style="max-height: 68vh;">
<view class="detail-cover" v-if="detailItem.productPicture">
<image class="detail-cover-img" :src="detailItem.productPicture" mode="widthFix"></image>
</view>
<view class="detail-info">
<view class="detail-name">{{detailItem.productName || ''}}</view>
<view class="detail-meta">
<view class="detail-price">{{formatMoney(getAttributePrice(detailItem))}}</view>
<view class="detail-group-price" v-if="getDetailGroupPrice(detailItem)">
拼团{{getDetailGroupPrice(detailItem)}}
</view>
<view class="detail-sale">销量 {{detailItem.tailWarn != null ? detailItem.tailWarn : 0}}</view>
</view>
<view class="detail-fee" v-if="getPackageFee(detailItem) > 0">
餐盒费 {{formatMoney(getPackageFee(detailItem))}}
</view>
</view>
<view class="detail-section">
<view class="detail-section-title">商品详情</view>
<view class="detail-rich" v-if="getProductIntro(detailItem)">
<rich-text :nodes="getProductIntro(detailItem)"></rich-text>
</view>
<view class="detail-empty" v-else>暂无商品详情</view>
</view>
<view style="height: 36rpx;"></view>
</scroll-view>
</view>
</uni-popup>
<!-- 拼团和选规格弹窗 -->
<uni-popup ref="pintuanPopup" background-color="#fff">
<uni-popup ref="pintuanPopup" background-color="#fff" @change="onBottomPopupChange">
<view class="car-content group-order-popup">
<view class="car-close" @tap="$refs.pintuanPopup.close()">
<uni-icons type="close" size="30" color="#fff"></uni-icons>
@ -326,6 +379,9 @@
<view class="popup-origin-price"
style="font-size: 28rpx;line-height: 54rpx;margin-right: 20rpx;">
{{currentItem.attributeListPrice | sliceMsg}}
<text class="package-fee-pill popup-package-fee" v-if="currentPackageFeeNumber > 0">
餐盒费{{currentPackageFee}}
</text>
</view>
</view>
</view>
@ -447,7 +503,7 @@
</view>
</uni-popup>
<!-- 拼团和选规格弹窗 -->
<uni-popup ref="pintuanGroupPopup" background-color="#fff">
<uni-popup ref="pintuanGroupPopup" background-color="#fff" @change="onBottomPopupChange">
<view class="car-content join-team-popup">
<view class="car-close" @tap="$refs.pintuanGroupPopup.close()">
<uni-icons type="close" size="30" color="#fff"></uni-icons>
@ -489,7 +545,7 @@
</uni-popup>
<!-- 支付弹出层 -->
<uni-popup ref="payPopup" background-color="#fff">
<uni-popup ref="payPopup" background-color="#fff" @change="onBottomPopupChange">
<view class="pay-popup"
style="height: auto;background: #fff;border-radius: 40rpx 40rpx 0 0;padding-top: 40rpx;">
<view class="content" style="height: 100%;margin-top:0">
@ -619,7 +675,7 @@
</uni-popup>
<!-- 优惠券选择弹出层 -->
<uni-popup ref="couponPopup" type="bottom" background-color="#F5F8F5">
<uni-popup ref="couponPopup" type="bottom" background-color="#F5F8F5" @change="onBottomPopupChange">
<view style="width: 100%; height: 800rpx; display: flex; flex-direction: column;">
<view
style="height: 100rpx; line-height: 100rpx; text-align: center; font-size: 32rpx; font-weight: bold; border-bottom: 1px solid #eee; position: relative; background: #fff;">
@ -718,6 +774,7 @@
moreBuyData: [],
vModelValue: 0,
currentItem: {},
detailItem: {},
checkMoreBuyIndex: '',
parsedSpecs: [],
moreBuyList: [],
@ -748,6 +805,7 @@
targetMembers: 2,
backendTotalAmount: 0,
currentOrderId: '',
isCreatingOrder: false,
onlineWorkerInterval: 2500,
onlineWorkerDuration: 500,
menuList: [{
@ -759,7 +817,9 @@
availableCoupons: [],
selectedCoupon: null,
freeOrderEffectVisible: false,
freeOrderAmount: '0.00'
freeOrderAmount: '0.00',
popupPageStyle: '',
bottomPopupOpenCount: 0
}
},
components: {
@ -775,6 +835,21 @@
cartTotalPrice() {
return this.cartItems.reduce((acc, curr) => acc + (curr.quantity * curr.price), 0).toFixed(2);
},
cartTotalPackageFeeNumber() {
return this.cartItems.reduce((acc, curr) => acc + (curr.quantity * this.getPackageFee(curr.item)), 0);
},
cartTotalPackageFee() {
return this.formatMoney(this.cartTotalPackageFeeNumber);
},
cartTotalPayPrice() {
return this.formatMoney(parseFloat(this.cartTotalPrice || 0) + this.cartTotalPackageFeeNumber);
},
currentPackageFeeNumber() {
return this.getPackageFee(this.currentItem);
},
currentPackageFee() {
return this.formatMoney(this.currentPackageFeeNumber);
},
stickyInnerHeight() {
// sticky
// iPhone
@ -836,12 +911,10 @@
} else {
this.targetMembers = 2; // Default fallback
}
let parsedItem = this.parseRouteItem(option.item);
if (this.type == 'shop') {
try {
this.shopItem = JSON.parse(decodeURIComponent(option.item));
} catch (e) {
this.shopItem = JSON.parse(option.item);
}
if (parsedItem) {
this.shopItem = parsedItem;
if (this.shopItem.products) {
this.shopRecommend = this.shopItem.products
for (let i = 0; i < this.shopRecommend.length; i++) {
@ -849,15 +922,16 @@
this.shopRecommend[i].isChecked = false
}
}
}
} else {
try {
this.productItem = JSON.parse(decodeURIComponent(option.item));
} catch (e) {
this.productItem = JSON.parse(option.item);
if (parsedItem) {
this.productItem = Array.isArray(parsedItem) ? parsedItem : [parsedItem];
}
}
if (this.shopItem && this.shopItem.id) {
this.getCategory(this.shopItem.id);
this.getProduct('');
}
},
onShow() {
this.menuButtonInfo = uni.getMenuButtonBoundingClientRect();
@ -893,6 +967,26 @@
this.detectCurrentCategory();
},
methods: {
parseRouteItem(item) {
if (item == null || item === '') return null;
try {
return JSON.parse(decodeURIComponent(item));
} catch (e) {
try {
return JSON.parse(item);
} catch (err) {
return null;
}
}
},
onBottomPopupChange(e) {
if (e.show) {
this.bottomPopupOpenCount += 1;
} else {
this.bottomPopupOpenCount = Math.max(0, this.bottomPopupOpenCount - 1);
}
this.popupPageStyle = this.bottomPopupOpenCount > 0 ? 'overflow:hidden;' : '';
},
nowMakeMethod() {
this.nowMake = !this.nowMake
},
@ -1361,6 +1455,12 @@
this.$refs.pintuanPopup.close();
},
submitPintuan(isFaceToFace) {
if (this.currentOrderId && this.backendTotalAmount) {
this.$refs.payPopup.open('bottom');
if (this.$refs.pintuanPopup) this.$refs.pintuanPopup.close();
return;
}
if (this.isCreatingOrder) return;
let specChoices = {};
for (let spec of this.parsedSpecs) {
specChoices[spec.name] = spec.canbuy === 1 ? spec.selected[0] : spec.selected;
@ -1398,6 +1498,13 @@
this.$refs.pintuanPopup.close();
},
submitFTFJoinPay(specChoices) {
if (this.currentOrderId && this.backendTotalAmount) {
this.$refs.payPopup.open('bottom');
if (this.$refs.pintuanPopup) this.$refs.pintuanPopup.close();
return;
}
if (this.isCreatingOrder) return;
this.isCreatingOrder = true;
let items = [{
productId: this.currentItem.id,
specs: JSON.stringify(specChoices || {}),
@ -1441,6 +1548,7 @@
});
this.tui.request("/mall/order/create", "POST", payload, false, false).then(res => {
uni.hideLoading();
this.isCreatingOrder = false;
if (res.success && res.result) {
this.currentOrderId = res.result.id;
this.groupdeliveryType = res.result.deliveryType;
@ -1458,6 +1566,7 @@
}
}).catch(err => {
uni.hideLoading();
this.isCreatingOrder = false;
});
},
showFreeOrderEffect(orderInfo) {
@ -1534,6 +1643,14 @@
}
}
},
getPackageFee(item) {
let fee = item && item.lunchBox != null ? parseFloat(item.lunchBox) : 0;
return isNaN(fee) ? 0 : fee;
},
formatMoney(value) {
let amount = parseFloat(value);
return (isNaN(amount) ? 0 : amount).toFixed(2);
},
getSpecDisplayString(specs) {
if (!specs) return '';
let arr = [];
@ -1564,11 +1681,7 @@
});
},
goDetail(type) {
if (type == 'goodsDetail') {
// uni.navigateTo({
// url: '/package1/goods/goodsDetail'
// })
} else if (type == 'shopDetail') {
if (type == 'shopDetail') {
uni.navigateTo({
url: '/package2/group/groupBuyDetail?item=' + JSON.stringify(this.shopItem)
})
@ -1576,8 +1689,56 @@
uni.navigateTo({
url: '/package2/group/shopEvaluate?item=' + JSON.stringify(this.shopItem)
})
} else if (type == 'openKitchen') {
this.tui.toast('明厨亮灶暂未开放');
}
},
openGoodsDetail(item) {
this.detailItem = item || {};
this.$refs.goodsDetailPopup.open('bottom');
},
getProductIntro(item) {
if (!item || item.productIntro == undefined || item.productIntro == null) return '';
let intro = '';
if (typeof item.productIntro === 'object') {
intro = item.productIntro.html || item.productIntro.text || '';
} else {
intro = item.productIntro;
}
return this.normalizeRichText(intro);
},
normalizeRichText(html) {
if (!html || typeof html !== 'string') return html || '';
const imageStyle = 'max-width:100%;width:100%;height:auto;display:block;margin:12px auto;';
return html.replace(/<img\b([^>]*)>/gi, (match, attrs) => {
if (/style\s*=/i.test(attrs)) {
return '<img' + attrs.replace(/style=(["'])(.*?)\1/i, (styleMatch, quote, styleValue) => {
return 'style=' + quote + imageStyle + styleValue + quote;
}) + '>';
}
return '<img style="' + imageStyle + '"' + attrs + '>';
});
},
getAttributePrice(item) {
let price = 0;
if (!item || !item.attributeListPrice) return price;
try {
let pObj = typeof item.attributeListPrice === 'string' ? JSON.parse(item.attributeListPrice) : item.attributeListPrice;
if (Array.isArray(pObj) && pObj.length > 0) {
price = parseFloat(pObj[0].specPrice);
} else {
for (let k in pObj) {
price = parseFloat(pObj[k].specPrice);
break;
}
}
} catch (e) {}
return isNaN(price) ? 0 : price;
},
getDetailGroupPrice(item) {
if (!item || !item.productGroupBuyPrices || item.isMoreBuy == 1) return '';
return this.getGroupPrice(item);
},
buyingye() {
uni.showToast({
title: '商品不在售卖时间!',
@ -1756,6 +1917,7 @@
})
},
onJoinSuccessPopupChange(e) {
this.onBottomPopupChange(e);
if (!e.show) {
uni.redirectTo({
url: '/package1/order/pendGroup?groupId=' + this.groupId
@ -1988,12 +2150,50 @@
.shop-content-bottom {
display: flex;
align-items: center;
margin-top: 8rpx;
}
.shop-deal {
flex: 1;
}
.shop-action-list {
flex: 1;
min-width: 0;
display: flex;
align-items: center;
gap: 8rpx;
}
.shop-action-btn {
height: 42rpx;
padding: 0 12rpx;
border-radius: 999rpx;
background: rgba(246, 255, 252, 0.86);
border: 1rpx solid rgba(166, 255, 234, 0.62);
color: #52625d;
font-size: 20rpx;
font-weight: 800;
line-height: 42rpx;
white-space: nowrap;
box-shadow: inset 0 0 0 1rpx rgba(255, 255, 255, 0.72);
}
.shop-action-btn:active {
transform: scale(0.96);
opacity: 0.86;
}
.shop-deal1 {
flex-shrink: 0;
margin-left: 10rpx;
color: #87938f;
font-size: 22rpx;
font-weight: 700;
white-space: nowrap;
}
.shop-bottom {
margin-top: 20rpx;
line-height: 40rpx;
@ -3117,6 +3317,170 @@
line-height: 26rpx;
}
.package-fee-tip {
margin-top: 2rpx;
color: #7c8b86;
font-size: 20rpx;
font-weight: 700;
line-height: 24rpx;
}
.cart-item-price {
flex: 1;
display: flex;
align-items: center;
flex-wrap: wrap;
gap: 10rpx;
margin-right: 20rpx;
color: #ff4d38;
font-size: 28rpx;
font-weight: 900;
line-height: 54rpx;
}
.package-fee-pill {
display: inline-flex;
align-items: center;
height: 34rpx;
line-height: 34rpx;
padding: 0 12rpx;
border-radius: 999rpx;
background: rgba(255, 244, 232, 0.92);
border: 1rpx solid rgba(255, 180, 118, 0.54);
color: #b4572d;
font-size: 20rpx;
font-weight: 800;
white-space: nowrap;
}
.goods-detail-popup {
border-top-left-radius: 40rpx;
border-top-right-radius: 40rpx;
background:
radial-gradient(circle at 92% 0, rgba(166, 255, 234, 0.28) 0, rgba(166, 255, 234, 0) 220rpx),
linear-gradient(180deg, #ffffff 0%, #f7fffb 100%);
padding-bottom: 30rpx;
}
.detail-popup-title {
position: sticky;
top: 0;
z-index: 2;
height: 76rpx;
line-height: 76rpx;
text-align: center;
color: #102f29;
font-size: 32rpx;
font-weight: 900;
background: rgba(255, 255, 255, 0.94);
border-radius: 40rpx 40rpx 0 0;
}
.detail-cover {
width: 100%;
border-radius: 30rpx;
overflow: hidden;
background: #f4f7f6;
box-shadow: 0 14rpx 30rpx rgba(0, 35, 28, 0.08);
}
.detail-cover-img {
width: 100%;
display: block;
}
.detail-info {
padding: 24rpx 4rpx 18rpx;
}
.detail-name {
color: #102f29;
font-size: 34rpx;
font-weight: 900;
line-height: 46rpx;
}
.detail-meta {
display: flex;
align-items: center;
flex-wrap: wrap;
gap: 14rpx;
margin-top: 14rpx;
}
.detail-price {
color: #ff4d38;
font-size: 34rpx;
font-weight: 900;
}
.detail-group-price,
.detail-fee {
height: 38rpx;
line-height: 38rpx;
padding: 0 14rpx;
border-radius: 999rpx;
font-size: 22rpx;
font-weight: 800;
white-space: nowrap;
}
.detail-group-price {
background: rgba(255, 57, 57, 0.1);
color: #ff4d38;
}
.detail-sale {
margin-left: auto;
color: #7c8b86;
font-size: 22rpx;
font-weight: 700;
}
.detail-fee {
display: inline-block;
margin-top: 16rpx;
background: rgba(255, 244, 232, 0.92);
border: 1rpx solid rgba(255, 180, 118, 0.54);
color: #b4572d;
}
.detail-section {
margin-top: 10rpx;
padding: 22rpx;
border-radius: 28rpx;
background: rgba(255, 255, 255, 0.82);
border: 1rpx solid rgba(166, 255, 234, 0.36);
}
.detail-section-title {
margin-bottom: 16rpx;
color: #102f29;
font-size: 30rpx;
font-weight: 900;
}
.detail-rich {
color: #3a4b46;
font-size: 26rpx;
line-height: 44rpx;
width: 100%;
overflow: hidden;
word-break: break-all;
}
.detail-rich rich-text,
.detail-rich img,
.detail-rich image {
max-width: 100% !important;
}
.detail-empty {
color: #9aa5a1;
font-size: 26rpx;
line-height: 44rpx;
}
.checkout-btn:active,
.group-buy-btn:active,
.solo-buy-btn:active,
@ -3176,6 +3540,11 @@
font-weight: 900;
}
.popup-package-fee {
margin-left: 12rpx;
vertical-align: middle;
}
.team-rule-card {
box-shadow: 0 10rpx 20rpx rgba(0, 35, 28, 0.05);
transition: transform 0.18s ease;

694
package2/group/groupPendingList.vue

@ -0,0 +1,694 @@
<template>
<view class="pending-page" :class="{'store-scene': isStoreScene}">
<view class="hero">
<view class="top-bar" @tap="back">
<view class="back-btn" :style="navPaddingStyle">
<uni-icons type="left" size="27" color="#fff"></uni-icons>
</view>
</view>
<view class="hero-copy">
<view class="hero-kicker">{{isStoreScene ? '校园团购' : '校园外卖'}}</view>
<view class="hero-title">{{isStoreScene ? '正在等你来拼团' : '附近饭搭子开团中'}}</view>
<view class="hero-sub">{{isStoreScene ? '同学们发起的到店团,凑齐就一起省' : '公开拼饭局都在这里,点进店铺直接参团'}}</view>
</view>
<view class="hero-badge">
<image src="/static/images/img/loading.gif" mode="aspectFit"></image>
<text>待成团</text>
</view>
</view>
<view class="search-card">
<view class="search-box">
<uni-icons type="search" size="18" :color="searchIconColor"></uni-icons>
<input type="text" v-model="query.keyWord" confirm-type="search" placeholder="搜索商品或商家"
@confirm="searchGroup" />
<view class="search-btn" @tap="searchGroup">搜索</view>
</view>
</view>
<view class="list-wrap">
<view class="empty-card" v-if="groupList.length === 0 && loadStatus !== 'loading'">
<view class="empty-icon"></view>
<view class="empty-title">暂时没有待成团</view>
<view class="empty-sub">换个关键词试试或者稍后再来看看同学们的新团</view>
</view>
<view class="group-card" v-for="(item,index) in groupList" :key="item.id" @tap="joinGroup(item)">
<view class="rank-pill">热拼 {{index + 1}}</view>
<view class="shop-row">
<view class="shop-img">
<image :src="item.uiShopIcon" mode="aspectFill"></image>
<view class="scene-mark">{{isStoreScene ? '团' : '饭'}}</view>
</view>
<view class="shop-info">
<view class="shop-name">{{item.uiShopName}}</view>
<view class="product-name">{{item.uiProductName}}</view>
<view class="tag-row">
<text>{{item.uiShopType}}</text>
<text>{{item.uiTargetMembers}}人成团</text>
<text>还差{{item.uiMissingMembers}}</text>
</view>
</view>
</view>
<view class="product-row">
<image :src="item.uiProductImage" mode="aspectFill"></image>
<view class="product-copy">
<view class="price-row">
<text class="group-label">拼团价</text>
<text class="price">¥{{item.uiGroupPrice}}</text>
</view>
<view class="progress-bar">
<view class="progress-inner" :style="item.uiProgressStyle"></view>
</view>
<view class="progress-copy">{{item.uiCurrentMembers}}人已拼 · 点击参与这一团</view>
</view>
</view>
<view class="card-bottom">
<view class="time-copy">{{item.uiExpireText}}</view>
<view class="join-btn">{{isStoreScene ? '参与到店团' : '参与拼饭局'}}</view>
</view>
</view>
<uni-load-more :status="loadStatus" v-if="groupList.length > 0" />
</view>
</view>
</template>
<script>
export default {
data() {
return {
scene: 'takeaway',
menuButtonInfo: {
top: 0
},
loadStatus: 'more',
navPaddingStyle: '',
totalPages: 1,
query: {
regionId: '',
status: 0,
isFace: 0,
merchantType: 1,
pageNumber: 1,
pageSize: 10,
keyWord: ''
},
groupList: []
}
},
computed: {
isStoreScene() {
return this.scene === 'storeGroup'
},
searchIconColor() {
return this.isStoreScene ? '#f0642f' : '#08735d'
}
},
onLoad(option) {
this.scene = option && option.scene ? option.scene : 'takeaway'
this.query.merchantType = this.isStoreScene ? 2 : 1
this.initRegion()
},
onShow() {
this.menuButtonInfo = uni.getMenuButtonBoundingClientRect()
this.navPaddingStyle = 'padding-top: ' + this.menuButtonInfo.top + 'px;'
},
onReachBottom() {
if (this.loadStatus === 'loading' || this.query.pageNumber >= this.totalPages) return
this.query.pageNumber += 1
this.getGroupList()
},
methods: {
initRegion() {
const area = uni.getStorageSync('area')
if (!area) {
this.tui.toast('请先选择区域')
return
}
try {
const areaInfo = typeof area === 'string' ? JSON.parse(area) : area
this.query.regionId = areaInfo.id || ''
} catch (e) {
this.query.regionId = ''
}
if (!this.query.regionId) {
this.tui.toast('请先选择区域')
return
}
this.getGroupList()
},
searchGroup() {
this.query.pageNumber = 1
this.totalPages = 1
this.groupList = []
this.getGroupList()
},
getGroupList() {
if (!this.query.regionId) return
this.loadStatus = 'loading'
this.tui.request('/mall/admin/orderGroup/page', 'POST', this.query, false, false).then((res) => {
if (res.code == 200) {
const result = res.result || {}
const list = Array.isArray(result.records) ? result.records.map(item => this.formatGroupItem(item)) : []
if (this.query.pageNumber === 1) {
this.groupList = list
} else {
this.groupList = [...this.groupList, ...list]
}
this.totalPages = result.pages || result.totalPages || 1
this.loadStatus = this.query.pageNumber >= this.totalPages ? 'nomore' : 'more'
} else {
this.loadStatus = 'nomore'
this.tui.toast(res.message)
}
}).catch(() => {
this.loadStatus = 'nomore'
})
},
joinGroup(item) {
const shopItem = item.shopItem || {}
if (!shopItem.id) {
this.tui.toast('商家信息缺失,暂时无法参团')
return
}
const sceneQuery = this.isStoreScene ? '&orderScene=storeGroup' : ''
const shopItemStr = encodeURIComponent(JSON.stringify(shopItem))
uni.navigateTo({
url: '/package2/group/groupBuySingle?type=shop&item=' + shopItemStr +
'&groupId=' + item.id +
'&targetMembers=' + (item.targetMembers || 2) +
'&isFaceToFace=0' + sceneQuery
})
},
getShopIcon(item) {
return (item.shopItem && item.shopItem.shopIcon) || item.productPicture || '/static/images/img/shangpintu.png'
},
formatGroupItem(item) {
return {
...item,
uiShopIcon: this.getShopIcon(item),
uiProductImage: item.productPicture || this.getShopIcon(item),
uiShopName: this.getShopName(item),
uiProductName: item.productName || '同学发起的拼团',
uiShopType: this.getShopType(item),
uiTargetMembers: item.targetMembers || 2,
uiCurrentMembers: item.currentMembers || 0,
uiMissingMembers: this.missingMembers(item),
uiGroupPrice: this.formatPrice(item.groupPrice),
uiExpireText: this.formatExpireText(item),
uiProgressStyle: this.buildProgressStyle(item)
}
},
getShopName(item) {
return (item.shopItem && item.shopItem.shopName) || item.shopName || '未知商家'
},
getShopType(item) {
const shopItem = item.shopItem || {}
return shopItem.shopTypeTitle || (shopItem.shopTakeaway && shopItem.shopTakeaway.type) || (this.isStoreScene ? '团购' : '美食')
},
missingMembers(item) {
const target = Number(item.targetMembers || 2)
const current = Number(item.currentMembers || 0)
return Math.max(target - current, 0)
},
buildProgressStyle(item) {
const target = Number(item.targetMembers || 2)
const current = Number(item.currentMembers || 0)
const percent = target > 0 ? Math.min(100, Math.max(12, Math.round(current / target * 100))) : 12
return 'width: ' + percent + '%;'
},
formatPrice(price) {
const num = Number(price || 0)
return num ? num.toFixed(2) : '--'
},
formatExpireText(item) {
if (!item.expireTime) return '24小时内成团'
const expire = new Date(item.expireTime).getTime()
const diff = expire - Date.now()
if (isNaN(expire) || diff <= 0) return '即将结束'
const hours = Math.floor(diff / 3600000)
const minutes = Math.floor((diff % 3600000) / 60000)
return hours > 0 ? '剩余约' + hours + '小时' + minutes + '分' : '剩余约' + minutes + '分'
},
back() {
uni.navigateBack()
}
}
}
</script>
<style lang="scss" scoped>
.pending-page {
min-height: 100vh;
padding-bottom: 140rpx;
background:
radial-gradient(circle at 12% 8%, rgba(197, 255, 153, 0.5), transparent 34%),
radial-gradient(circle at 90% 18%, rgba(175, 255, 231, 0.48), transparent 36%),
linear-gradient(180deg, #f6ffea 0%, #f7fff9 42%, #fff9ef 100%);
color: #06382f;
box-sizing: border-box;
}
.store-scene {
background:
radial-gradient(circle at 82% 120rpx, rgba(255, 241, 210, 0.86) 0, rgba(255, 241, 210, 0) 260rpx),
radial-gradient(circle at 10% 260rpx, rgba(255, 190, 185, 0.3) 0, rgba(255, 190, 185, 0) 240rpx),
linear-gradient(180deg, #ffd0b8 0%, #ffe6d6 260rpx, #fff7ef 560rpx, #fffaf6 100%);
color: #3f2618;
}
.hero {
min-height: 360rpx;
padding: 0 26rpx 36rpx;
box-sizing: border-box;
position: relative;
overflow: hidden;
background: linear-gradient(135deg, #0f8b6b 0%, #87eabf 58%, #fff0c8 100%);
color: #fff;
}
.store-scene .hero {
background: linear-gradient(115deg, rgba(255, 132, 80, 0.98) 0%, rgba(255, 185, 113, 0.94) 56%, rgba(255, 236, 218, 0.9) 100%);
}
.hero::after {
content: '';
width: 420rpx;
height: 420rpx;
border-radius: 50%;
background: rgba(255, 255, 255, 0.22);
position: absolute;
right: -170rpx;
top: -130rpx;
}
.top-bar {
height: 98rpx;
position: relative;
z-index: 2;
}
.back-btn {
width: 68rpx;
height: 68rpx;
display: flex;
align-items: center;
justify-content: center;
}
.hero-copy {
position: relative;
z-index: 2;
width: 66%;
padding-top: 24rpx;
}
.hero-kicker {
display: inline-block;
padding: 8rpx 18rpx;
border-radius: 999rpx;
background: rgba(255, 255, 255, 0.34);
font-size: 22rpx;
font-weight: 900;
}
.hero-title {
margin-top: 18rpx;
font-size: 48rpx;
line-height: 58rpx;
font-weight: 900;
}
.hero-sub {
margin-top: 12rpx;
font-size: 24rpx;
line-height: 36rpx;
font-weight: 800;
color: rgba(255, 255, 255, 0.86);
}
.hero-badge {
width: 190rpx;
height: 190rpx;
border-radius: 42rpx;
position: absolute;
right: 32rpx;
bottom: 42rpx;
z-index: 2;
background: rgba(255, 255, 255, 0.42);
box-shadow: 0 22rpx 44rpx rgba(0, 45, 29, 0.16);
text-align: center;
overflow: hidden;
}
.hero-badge image {
width: 120rpx;
height: 120rpx;
margin-top: 16rpx;
}
.hero-badge text {
display: block;
font-size: 23rpx;
font-weight: 900;
}
.search-card {
width: 94%;
margin: -32rpx auto 22rpx;
padding: 16rpx;
border-radius: 34rpx;
background: rgba(255, 255, 255, 0.76);
box-shadow: 0 18rpx 42rpx rgba(20, 115, 88, 0.12);
box-sizing: border-box;
position: relative;
z-index: 3;
}
.store-scene .search-card {
box-shadow: 0 18rpx 42rpx rgba(178, 102, 48, 0.12);
}
.search-box {
height: 72rpx;
padding: 0 16rpx;
border-radius: 28rpx;
background: #fff;
display: flex;
align-items: center;
}
.search-box input {
flex: 1;
min-width: 0;
height: 72rpx;
margin-left: 12rpx;
font-size: 24rpx;
color: #243d36;
}
.search-btn {
width: 86rpx;
height: 44rpx;
border-radius: 999rpx;
background: linear-gradient(90deg, #dcff9c, #baffec);
color: #08735d;
font-size: 22rpx;
font-weight: 900;
line-height: 44rpx;
text-align: center;
}
.store-scene .search-btn {
background: linear-gradient(135deg, #ff7444 0%, #ffae53 100%);
color: #fff;
}
.list-wrap {
width: 94%;
margin: 0 auto;
}
.empty-card,
.group-card {
border-radius: 34rpx;
background: rgba(255, 255, 255, 0.86);
box-shadow: 0 18rpx 44rpx rgba(19, 91, 70, 0.12);
border: 1rpx solid rgba(255, 255, 255, 0.86);
box-sizing: border-box;
}
.store-scene .empty-card,
.store-scene .group-card {
box-shadow: 0 16rpx 34rpx rgba(178, 102, 48, 0.12);
border-color: rgba(255, 221, 188, 0.72);
}
.empty-card {
min-height: 460rpx;
padding-top: 110rpx;
text-align: center;
}
.empty-icon {
width: 100rpx;
height: 100rpx;
margin: 0 auto 22rpx;
border-radius: 34rpx;
background: linear-gradient(135deg, #e8ffb8, #b8ffe9);
color: #08735d;
font-size: 34rpx;
font-weight: 900;
line-height: 100rpx;
}
.store-scene .empty-icon {
background: linear-gradient(135deg, #ff9a72 0%, #ffd38a 100%);
color: #fff;
}
.empty-title {
font-size: 30rpx;
font-weight: 900;
}
.empty-sub {
width: 78%;
margin: 14rpx auto 0;
color: rgba(0, 35, 28, 0.56);
font-size: 24rpx;
line-height: 38rpx;
}
.group-card {
margin-bottom: 22rpx;
padding: 20rpx 18rpx 18rpx;
position: relative;
overflow: hidden;
}
.rank-pill {
position: absolute;
right: 18rpx;
top: 18rpx;
z-index: 2;
padding: 5rpx 13rpx;
border-radius: 999rpx;
background: rgba(219, 255, 157, 0.72);
color: #08735d;
font-size: 18rpx;
font-weight: 900;
}
.store-scene .rank-pill {
background: #fff0dc;
color: #e96632;
}
.shop-row {
display: flex;
}
.shop-img {
width: 168rpx;
height: 168rpx;
flex-shrink: 0;
border-radius: 30rpx;
overflow: hidden;
position: relative;
background: #f4fff3;
box-shadow: 0 14rpx 28rpx rgba(20, 75, 57, 0.14);
}
.shop-img image {
width: 100%;
height: 100%;
}
.scene-mark {
width: 42rpx;
height: 42rpx;
border-radius: 50%;
background: rgba(255, 255, 255, 0.92);
color: #ff5a35;
font-size: 22rpx;
font-weight: 900;
line-height: 42rpx;
text-align: center;
position: absolute;
left: 10rpx;
top: 10rpx;
}
.shop-info {
flex: 1;
min-width: 0;
padding-left: 20rpx;
box-sizing: border-box;
}
.shop-name {
padding-right: 92rpx;
font-size: 33rpx;
line-height: 42rpx;
font-weight: 900;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.product-name {
margin-top: 10rpx;
color: rgba(0, 35, 28, 0.58);
font-size: 24rpx;
line-height: 34rpx;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.store-scene .product-name {
color: #876247;
}
.tag-row {
margin-top: 16rpx;
overflow: hidden;
}
.tag-row text {
display: inline-block;
margin: 0 8rpx 8rpx 0;
padding: 5rpx 10rpx;
border-radius: 12rpx;
background: rgba(184, 255, 225, 0.62);
color: #08735d;
font-size: 20rpx;
font-weight: 900;
}
.store-scene .tag-row text {
background: #fff0dc;
color: #d65f2c;
}
.product-row {
margin-top: 18rpx;
padding: 14rpx;
border-radius: 26rpx;
background: rgba(255, 250, 237, 0.72);
display: flex;
}
.store-scene .product-row {
background: #fff7ee;
}
.product-row image {
width: 110rpx;
height: 110rpx;
border-radius: 22rpx;
background: #fff;
flex-shrink: 0;
}
.product-copy {
flex: 1;
min-width: 0;
padding-left: 16rpx;
box-sizing: border-box;
}
.price-row {
height: 42rpx;
display: flex;
align-items: center;
}
.group-label {
margin-right: 10rpx;
padding: 4rpx 9rpx;
border-radius: 10rpx;
background: #fff0dc;
color: #b4572d;
font-size: 19rpx;
font-weight: 900;
}
.price {
color: #f0441f;
font-size: 30rpx;
font-weight: 900;
}
.progress-bar {
height: 14rpx;
margin-top: 16rpx;
border-radius: 999rpx;
background: rgba(214, 239, 210, 0.8);
overflow: hidden;
}
.progress-inner {
height: 100%;
border-radius: 999rpx;
background: linear-gradient(90deg, #a6ffea 0%, #e3ff96 100%);
}
.store-scene .progress-inner {
background: linear-gradient(90deg, #ff7444 0%, #ffd16e 100%);
}
.progress-copy {
margin-top: 10rpx;
color: rgba(0, 35, 28, 0.52);
font-size: 21rpx;
font-weight: 800;
}
.store-scene .progress-copy {
color: #8f715b;
}
.card-bottom {
height: 58rpx;
margin-top: 16rpx;
padding-top: 12rpx;
border-top: 1rpx solid rgba(20, 90, 70, 0.08);
display: flex;
align-items: center;
}
.time-copy {
flex: 1;
color: rgba(0, 35, 28, 0.58);
font-size: 22rpx;
font-weight: 800;
}
.store-scene .time-copy {
color: #8f715b;
}
.join-btn {
width: 160rpx;
height: 50rpx;
border-radius: 999rpx;
background: linear-gradient(90deg, rgba(227, 255, 150, 1), rgba(166, 255, 234, 1));
color: #08735d;
font-size: 24rpx;
font-weight: 900;
line-height: 50rpx;
text-align: center;
box-shadow: 0 12rpx 24rpx rgba(13, 114, 82, 0.16);
}
.store-scene .join-btn {
background: linear-gradient(135deg, #ff7444 0%, #ff9f38 100%);
color: #fff;
box-shadow: 0 12rpx 24rpx rgba(255, 126, 39, 0.24);
}
</style>

4
package2/group/searchGroup.vue

@ -302,7 +302,7 @@
goDetail(type,item){
if(type == 'shop'){
uni.navigateTo({
url:'/package2/group/groupBuySingle?type=shop&item=' + JSON.stringify(item)
url:'/package2/group/groupBuySingle?type=shop&item=' + encodeURIComponent(JSON.stringify(item))
})
}else if(type == 'search'){
uni.navigateTo({
@ -310,7 +310,7 @@
})
}else{
uni.navigateTo({
url:'/package2/group/groupBuySingle?type=product&item=' + JSON.stringify(item)
url:'/package2/group/groupBuySingle?type=product&item=' + encodeURIComponent(JSON.stringify(item))
})
}
},

13
package2/group/studentStoreList.vue

@ -16,12 +16,12 @@
<view class="hero-left">
<view class="hand-tag">Campus walk</view>
<view class="hero-title">万能杂货铺
<view class="brand-chip" style="width: 340rpx;">半径里# 下课后去哪儿拼一单</view>
<view class="brand-chip" style="width: 340rpx;">半径里# 点击松鼠立即参团</view>
</view>
</view>
<view class="squirrel-card">
<view class="squirrel-card" @tap="goPendingGroup">
<image class="squirrel-img" src="/static/images/img/songshu.png" mode="aspectFit"></image>
<view class="squirrel-dialog">今天一起逛吗</view>
<view class="squirrel-dialog">点我看看</view>
<view class="group-pop"></view>
</view>
</view>
@ -452,6 +452,11 @@
url: '/package2/group/groupBuySingle?type=shop&orderScene=storeGroup&item=' + encodeURIComponent(JSON.stringify(item))
})
},
goPendingGroup() {
uni.navigateTo({
url: '/package2/group/groupPendingList?scene=storeGroup'
})
},
getShopType(item) {
if (item.shopTypeTitle) return item.shopTypeTitle
if (item.shopTakeaway && item.shopTakeaway.type) return item.shopTakeaway.type
@ -764,7 +769,7 @@
.squirrel-dialog {
width: 150rpx;
padding: 10rpx 12rpx;
padding: 20rpx 12rpx;
border-radius: 22rpx;
background: #fff;
color: #9b4d28;

32
package2/myCenter/partTimeJobRegister.vue

@ -101,8 +101,8 @@
</view>
</view>
<view class="qusong3" style="display:flex; align-items:center;">
<input type="digit" v-model="item.orderBkge" placeholder="填写配送费"
style="flex:1;">
<input type="digit" :value="item.orderBkge" placeholder="填写配送费"
@input="onOrderBkgeInput($event, item)" style="flex:1;">
<uni-icons type="closeempty" size="20" @click="removeRule('waima', index)"
color="#ff0000" style="margin-left:10rpx;"></uni-icons>
</view>
@ -147,8 +147,8 @@
</view>
</view>
<view class="qusong3" style="display:flex; align-items:center;">
<input type="digit" v-model="item.orderBkge" placeholder="填写配送费"
style="flex:1;">
<input type="digit" :value="item.orderBkge" placeholder="填写配送费"
@input="onOrderBkgeInput($event, item)" style="flex:1;">
<uni-icons type="closeempty" size="20" @click="removeRule('paotui', index)"
color="#ff0000" style="margin-left:10rpx;"></uni-icons>
</view>
@ -269,6 +269,28 @@
this.menuButtonInfo = uni.getMenuButtonBoundingClientRect()
},
methods: {
formatMoneyInput(value) {
value = String(value || '');
value = value.replace(/[^\d.]/g, '');
const dotIndex = value.indexOf('.');
if (dotIndex !== -1) {
value = value.slice(0, dotIndex + 1) + value.slice(dotIndex + 1).replace(/\./g, '');
const parts = value.split('.');
value = parts[0] + '.' + parts[1].slice(0, 2);
}
return value;
},
normalizeOrderBkge(item) {
const value = this.formatMoneyInput(item.orderBkge);
const amount = parseFloat(value);
item.orderBkge = isNaN(amount) ? '' : (Math.floor(amount * 100) / 100).toFixed(2).replace(/\.?0+$/, '');
return item.orderBkge;
},
onOrderBkgeInput(e, item) {
const value = this.formatMoneyInput(e.detail.value);
item.orderBkge = value;
return value;
},
getWorkerMessage() {
let that = this
that.tui.request("/app/workerRelaPrice/getByWorkerId?workerId=" + uni.getStorageSync('worker').workerId,
@ -453,6 +475,7 @@
let workerRelaPriceList = [];
if (this.formData.waima) {
this.waimaRuleList.forEach(item => this.normalizeOrderBkge(item));
let invalid = this.waimaRuleList.find(item => !item.orderBkge);
if (invalid) return uni.showToast({
title: '请填写外卖配送费',
@ -461,6 +484,7 @@
workerRelaPriceList = workerRelaPriceList.concat(this.waimaRuleList);
}
if (this.formData.paotui) {
this.paotuiRuleList.forEach(item => this.normalizeOrderBkge(item));
let invalid = this.paotuiRuleList.find(item => !item.orderBkge);
if (invalid) return uni.showToast({
title: '请填写快递配送费',

4
package2/myCenter/wallet.vue

@ -184,6 +184,10 @@
},
wxPayment(){
let that = this
if(this.commionAmount < 1 || this.commionAmount > 5000){
that.tui.toast('单笔提现金额应在1-5000之间')
return
}
let data = {
commission:this.commionAmount,
aliName:this.aliName,

719
package2/partTimeJob/workerOrderList.vue

@ -1,5 +1,5 @@
<template>
<!-- 兼职订单列表 -->
<!-- 配送员已完成订单列表 -->
<view class="page1">
<view class="title">
<view class="title-sreach">
@ -7,118 +7,141 @@
<uni-icons type="left" size="28"></uni-icons>
</view>
<view class="title-name" :style="{'padding-top': menuButtonInfo.top +'px'}">
订单列表
已完成订单
</view>
</view>
</view>
<view style="margin-top: -140rpx;">
<view class="box1" @tap="goDetail(item)" v-for="(item,index) in orderList" :key="index">
<view style="display: flex;height: 50rpx;border-bottom: 1px solid #eee;">
<view style="display: flex;padding-right: 20rpx;" v-if="item.numberCode">
{{'#' + item.numberCode | delPlus}}
</view>
<view style="flex: 1;display: flex;">
{{item.createTime | formatISOTime}}
<!-- <text>已退款</text> -->
</view>
<view>
{{item.status == 0?'待支付':item.status == 2?'待配送员接单':(item.status == 3 && item.deliveryType == 1 && item.shopMakeTime == null) || (item.status == 3 && item.deliveryType == 2 && item.userRequireMake == 1)?'待出餐':(item.status == 3 && item.deliveryType == 1 && item.shopMakeTime != null)?'待取货':(item.status == 3 && item.deliveryType == 1 && item.shopMakeTime != null) || (item.status == 3 && item.deliveryType == 2 && item.userRequireMake != 1)?'待消费':item.status == 4?'待送达':item.status == 5?'已完成':item.status == 7?'待同意退款':item.status == 8?'已退款':item.status == 6?'已取消':item.status == 11?'售后中':item.status == 12?'已售后':""}}
</view>
<view class="summary-card">
<view class="summary-label">共计送达</view>
<view class="summary-count">{{totalCount}}<text></text></view>
</view>
<view style="height: auto;padding-top: 20rpx;">
<view style="height: 50rpx;line-height: 50rpx;font-size: 28rpx;font-weight: 700;display: flex;">
商品 <text><text>{{item.goodsNum}}</text></text>
<view class="search-card">
<view class="date-picker-wrap">
<uni-datetime-picker :clear-icon="false" v-model="range" type="daterange" @change="searchList" />
</view>
<view style="display: flex;" v-for="(item1,index1) in item.goodsList" :key="index">
<view style="flex: 1;height: 20px;line-height: 20px;">
{{item1.productName}}
<view class="reset-btn" @tap="resetDateRange">重置</view>
</view>
<view style="width: 100rpx;">
{{'X' + item1.quantity}}
<view class="list-wrap">
<view class="box1" @tap="goDetail(item)" v-for="(item,index) in orderList" :key="index">
<view class="order-head">
<view class="type-tag" :class="'type-' + item.deliveryType">
{{deliveryTypeText(item.deliveryType)}}
</view>
<view>
{{'¥'+ item1.price}}
<view class="order-code" v-if="item.numberCode">
#{{orderCodeText(item.numberCode)}}
</view>
<view class="done-tag">已送达</view>
</view>
<view class="time-row">
<text v-if="item.mustFinishTime">{{item.mustFinishTime | formatHourMinute}}前送达</text>
<text v-else>{{item.createTime | formatISOTime}}</text>
</view>
<view style="height: 80rpx;border-top: 1px solid #eee;display: flex;">
<view class="pinzi" @tap.stop="tanchuang(item.deliveryType)" style="width:auto;font-weight:700;margin-right: 20rpx;color:#00231C;background:linear-gradient(90deg, rgba(227, 255, 150, 1), rgba(166, 255, 234, 1));padding:0 12rpx;">
{{item.deliveryType == 1?'配送':item.isPack == 1?'自取-打包':item.isPack == 0?'自取-堂食':'自取'}}
<view class="time-detail">
<view class="time-item" v-if="item.acceptTime">
<text>接单</text>{{item.acceptTime | formatISOTime}}
</view>
<view v-if="item.orderType != 1 && item.groupInfo != null" @tap.stop="getGroupOrders(item.id)" class="pinzi">
<view class="time-item" v-if="item.arriveTime">
<text>到店</text>{{item.arriveTime | formatISOTime}}
</view>
<view style="flex: 1;"></view>
<view @tap.stop="mealServing(item)" v-if="currentIndex == 13" class="btn" style="margin: 10rpx 0 0 20rpx;">
已出餐
<view class="time-item" v-if="item.getTime">
<text>取货</text>{{item.getTime | formatISOTime}}
</view>
<view class="time-item" v-if="item.finishTime">
<text>送达</text>{{item.finishTime | formatISOTime}}
</view>
</view>
<view class="remark" v-if="item.remark != '' && item.remark != null">
备注{{item.remark}}
</view>
<view style="width:100%;height:60rpx;"></view>
<!-- 拼团详情弹窗 -->
<uni-popup ref="pintuanPopup" background-color="#fff">
<view class="guize-list">
<view v-for="(item,index) in tuanzhangOrder" :key="index">
<view style="height: 80rpx;line-height: 80rpx;font-size: 36rpx;font-weight: 700;">
订单-{{item.numberCode}}
<view class="extra-info" v-if="item.deliveryType == 2 || item.deliveryType == 3">
<text>{{item.allCount != null ? item.allCount : 0}}</text>
<text v-if="item.getCodes != null">取件码{{item.getCodes}}</text>
<text v-if="item.phoneNumber != null">尾号{{item.phoneNumber}}</text>
</view>
<view class="">
<view class="dingdan">
<view style="display:flex">
<view style="width:300rpx;">
订单状态
<view class="route-box">
<view class="route-line">
<view class="route-dot get"></view>
<view class="route-main">
<view class="route-name">{{item.shopName || '取货点'}}</view>
<view class="route-address">{{item.shopAddress || '暂无取货地址'}}</view>
</view>
<view class="pituan-text">
{{item.status == 0?'待支付':item.status == 2?'待配送员接单':(item.status == 3 && item.deliveryType == 1 && item.shopMakeTime == null) || (item.status == 3 && item.deliveryType == 2 && item.userRequireMake == 1)?'待出餐':(item.status == 3 && item.deliveryType == 1 && item.shopMakeTime != null)?'待取货':(item.status == 3 && item.deliveryType == 2)?'待消费':item.status == 4?'待送达':item.status == 5?'已完成':item.status == 7?'待同意退款':item.status == 8?'已退款':item.status == 6?'已取消':item.status == 11?'售后中':item.status == 12?'已售后':""}}
</view>
<view class="route-line">
<view class="route-dot send"></view>
<view class="route-main">
<view class="route-name">{{item.receiverName || '收货人'}}</view>
<view class="route-address">{{item.receiverAddress || '暂无收货地址'}}</view>
</view>
<view style="display:flex">
<view style="width:300rpx;">
订单号
</view>
<view class="pituan-text">
{{item.id}}
</view>
<view class="goods-row" v-if="item.goodsList && item.goodsList.length > 0" @tap.stop="productDetail(item)">
<view class="goods-title">
商品详情
</view>
<view style="display:flex">
<view style="width:300rpx;">
订单时间
<view class="goods-desc">
{{item.goodsNum}}点击查看规格和数量
</view>
<view class="pituan-text">
{{item.createTime | formatISOTime}}
<uni-icons type="right" size="14" color="#7a8582"></uni-icons>
</view>
<view class="fee-row">
<view class="big-tag" v-if="item.isBig != null && item.isBig == 1">超大/超重</view>
<view class="fee-text">
配送佣金 <text>{{item.deliveryFee || 0}}</text>
</view>
<view class="market-fee" v-if="item.deliveryFeeMarketplace != null">
含平台{{item.deliveryFeeMarketplace}}
</view>
<view class="dingdan" v-for="(item1,index1) in item.goodsList" :key="index1">
<view class="pt-title">
商品信息
</view>
<view style="display: flex;font-weight: 700;">
<view style="flex:1">
商品名{{item1.productName}}
</view>
<view style="width:100rpx;">
X{{item1.quantity}}
<view class="empty-box" v-if="orderList.length == 0 && loadStatus == 'nomore'">
暂无已完成订单
</view>
<view style="width:220rpx;text-align: right;padding-right:20rpx;">
{{item1.price}}
</view>
<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 class="dingdan">
<view style="text-align: right;padding-right: 20rpx;color: #777;">
餐盒费{{item.packageFee}} 配送费{{item.deliveryFee}}
</view>
<view style="text-align: right;padding-right: 20rpx;font-size: 28rpx;font-weight: 700;color: red;">
总计{{item.totalAmount}}
<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>
<view class="bottom-space"></view>
</view>
</template>
@ -134,9 +157,14 @@
order: '',
regionId: JSON.parse(uni.getStorageSync('area')).id,
deliveryType: null,
workerId: uni.getStorageSync('worker').workerId
workerId: uni.getStorageSync('worker').workerId,
startDate: '',
endDate: ''
},
range: [],
productData: [],
totalPages: 1,
totalCount: 0,
tuanzhangOrder:[],
orderList: [],
currentIndex: 10,
@ -149,6 +177,14 @@
this.getList();
},
filters: {
formatHourMinute(value) {
if (!value) return '';
const date = new Date(value);
const day = String(date.getDate()).padStart(2, '0');
const hour = String(date.getHours()).padStart(2, '0');
const minute = String(date.getMinutes()).padStart(2, '0');
return `${day}${hour}:${minute}`;
},
formatISOTime(isoString) {
const date = new Date(isoString);
const year = date.getFullYear();
@ -164,6 +200,17 @@
data = data.slice(0, -1);
}
return data;
},
delNode(data) {
let str;
if (typeof data === 'object' && data !== null) {
str = JSON.stringify(data);
} else if (typeof data === 'string') {
str = data;
} else {
str = String(data);
}
return str.replace(/[{}"]/g, '');
}
},
onShow() {
@ -182,7 +229,7 @@
getList() {
this.loadStatus = 'loading'
let that = this
that.tui.request("/mall/delivery/pagebyworker", "POST", this.searchForm, false, false).then((
that.tui.request("/mall/delivery/pagebyworkerHistory", "POST", this.searchForm, false, false).then((
res) => {
that.loadStatus = 'nomore';
if (res.code == 200) {
@ -193,11 +240,14 @@
}
for(let i=0;i<that.orderList.length;i++){
that.orderList[i].goodsNum = 0
if (that.orderList[i].goodsList && that.orderList[i].goodsList.length) {
for(let m=0;m<that.orderList[i].goodsList.length;m++){
that.orderList[i].goodsNum += that.orderList[i].goodsList[m].quantity
}
}
}
that.totalPages = res.result.pages;
that.totalCount = res.result.total || that.orderList.length;
that.$forceUpdate();
} else {
that.tui.toast(res.message);
@ -206,6 +256,35 @@
uni.hideLoading();
}).catch((res) => {});
},
deliveryTypeText(type) {
if (type == 1) return '外卖';
if (type == 2) return '代取快递';
if (type == 3) return '代跑腿';
return '配送';
},
orderCodeText(numberCode) {
if (!numberCode) return '';
if (numberCode.length > 14) return '多订单';
return numberCode.endsWith("+") ? numberCode.slice(0, -1) : numberCode;
},
productDetail(item) {
this.productData = item.goodsList || [];
this.$refs.productPopup.open()
},
searchList(range) {
const dateRange = range || this.range || [];
this.searchForm.startDate = dateRange[0] || '';
this.searchForm.endDate = dateRange[1] || '';
this.searchForm.pageNum = 1;
this.getList();
},
resetDateRange() {
this.range = [];
this.searchForm.startDate = '';
this.searchForm.endDate = '';
this.searchForm.pageNum = 1;
this.getList();
},
tanchuang(v){
this.tui.toast('该订单为'+(v==1?'配送':'自取')+'单')
},
@ -286,12 +365,14 @@
height: 100%;
font-size: 24rpx;
position: relative;
padding-bottom: 40rpx;
}
.title {
background: url('https://jewel-shop.oss-cn-beijing.aliyuncs.com/8bc15960c2dc40268e295d6dd23aecce.png') no-repeat;
width: 100%;
height: 20%;
height: 360rpx;
background-size: 100% 100%;
}
.title-sreach {
@ -315,121 +396,449 @@
text-align: center;
}
.title-tab {
.summary-card {
width: 92%;
height: 128rpx;
margin: -156rpx auto 24rpx;
padding: 24rpx 28rpx;
box-sizing: border-box;
display: flex;
margin: -120rpx auto 0;
align-items: center;
border-radius: 28rpx;
background:
radial-gradient(circle at 92% 0, rgba(166, 255, 234, 0.78) 0, rgba(166, 255, 234, 0) 170rpx),
#fff;
box-shadow: 0 14rpx 34rpx rgba(0, 35, 28, 0.08);
}
.status-scroll-view {
width: 100%;
white-space: nowrap;
/* 辅助滚动,与 flex 配合确保不换行 */
height: auto;
.summary-label {
flex: 1;
color: #61716d;
font-size: 26rpx;
font-weight: 700;
}
.status-list {
.summary-count {
color: #00231C;
font-size: 52rpx;
font-weight: 900;
line-height: 64rpx;
}
.summary-count text {
margin-left: 6rpx;
color: #61716d;
font-size: 24rpx;
font-weight: 700;
}
.list-wrap {
width: 92%;
margin: 0 auto;
}
.search-card {
width: 92%;
margin: 0 auto 8rpx;
padding: 16rpx 18rpx;
box-sizing: border-box;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
align-items: center;
padding: 0 0;
/* 可根据设计添加左右留白,但会影响“一排5个”精准计算,故留白为0 */
min-height: 88rpx;
/* 保证内部项撑开高度 */
border-radius: 22rpx;
background: #fff;
box-shadow: 0 10rpx 24rpx rgba(0, 35, 28, 0.05);
}
/* 每个状态项:宽度为屏幕宽度的1/5,保证一行正好显示5个,超出滚动 */
.status-item {
flex-shrink: 0;
width: 20vw;
/* 关键:屏幕宽度的1/5,正好一排5个 */
.date-picker-wrap {
flex: 1;
min-width: 0;
}
.reset-btn {
width: 88rpx;
height: 56rpx;
margin-left: 14rpx;
border-radius: 56rpx;
background: rgba(166, 255, 234, 0.48);
color: #126255;
font-size: 24rpx;
font-weight: 800;
line-height: 56rpx;
text-align: center;
padding: 20rpx 0;
position: relative;
}
.box1 {
width: 100%;
margin: 18rpx auto;
background: #fff;
border-radius: 24rpx;
padding: 22rpx;
box-sizing: border-box;
transition: all 0.2s cubic-bezier(0.25, 0.46, 0.45, 0.94);
/* 点击反馈 */
-webkit-tap-highlight-color: transparent;
box-shadow: 0 10rpx 28rpx rgba(0, 35, 28, 0.05);
}
.order-head {
display: flex;
align-items: center;
min-height: 44rpx;
}
.type-tag {
height: 40rpx;
line-height: 40rpx;
padding: 0 16rpx;
border-radius: 40rpx;
font-size: 22rpx;
font-weight: 700;
}
.type-1 {
background: rgba(255, 233, 89, 1);
}
.type-2 {
background: rgba(255, 220, 199, 1);
}
.type-3 {
background: rgba(130, 255, 130, 1);
}
.order-code {
flex: 1;
min-width: 0;
margin-left: 14rpx;
color: #60716c;
font-size: 22rpx;
height: 40rpx;
line-height: 40rpx;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.status-text {
.done-tag {
height: 38rpx;
line-height: 38rpx;
padding: 0 14rpx;
border-radius: 12rpx;
background: rgba(166, 255, 234, 0.5);
color: #0b665a;
font-size: 22rpx;
font-weight: 700;
}
.time-row {
margin-top: 12rpx;
color: #223b36;
font-size: 28rpx;
color: #666666;
font-weight: normal;
line-height: 1.4;
transition: color 0.2s, font-weight 0.2s;
font-weight: 800;
line-height: 38rpx;
}
/* 激活状态样式 */
.status-item.active .status-text {
color: #ff6b35;
font-weight: 500;
.time-detail {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 8rpx 14rpx;
margin-top: 12rpx;
padding: 12rpx 14rpx;
border-radius: 16rpx;
background: rgba(247, 248, 248, 0.58);
}
/* 激活指示条(下划线) */
.status-item.active::after {
content: '';
position: absolute;
bottom: 0;
left: 50%;
transform: translateX(-50%);
width: 40rpx;
height: 4rpx;
background-color: #ff6b35;
border-radius: 2rpx;
transition: width 0.2s ease;
.time-item {
min-width: 0;
color: #6f7c78;
font-size: 20rpx;
line-height: 30rpx;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.box1 {
width: 95%;
margin: 20rpx auto;
background: #fff;
.time-item text {
margin-right: 8rpx;
color: #243d38;
font-weight: 800;
}
.remark,
.extra-info {
margin-top: 14rpx;
padding: 12rpx 16rpx;
border-radius: 16rpx;
background: rgba(247, 248, 248, 0.72);
color: #5f6c69;
font-size: 22rpx;
line-height: 34rpx;
}
.extra-info {
display: flex;
flex-wrap: wrap;
gap: 12rpx 24rpx;
}
.route-box {
margin-top: 16rpx;
padding: 14rpx 16rpx;
border: 1px solid rgba(166, 255, 234, 0.78);
border-radius: 20rpx;
padding: 20rpx 20rpx 0;
}
.btn{
background: linear-gradient(90deg, rgba(227, 255, 150, 1), rgba(166, 255, 234, 1));
padding:0 10rpx;
height: 50rpx;
border-radius: 14rpx;
line-height: 50rpx;
.route-line {
display: flex;
padding: 8rpx 0;
}
.route-dot {
width: 38rpx;
height: 38rpx;
line-height: 38rpx;
flex-shrink: 0;
margin: 3rpx 14rpx 0 0;
text-align: center;
border-radius: 38rpx;
background: #00231C;
color: #fff;
font-size: 20rpx;
font-weight: 700;
margin-top: 20rpx;
}
.pinzi{
margin: 20rpx 0;
background: linear-gradient(90deg, #FF4500, #FFA07A);
width: 40rpx;
height: 40rpx;
.route-dot.send {
background: #8adfca;
color: #00231C;
}
.route-main {
flex: 1;
min-width: 0;
}
.route-name {
color: #152d28;
font-size: 25rpx;
font-weight: 800;
line-height: 34rpx;
}
.route-address {
margin-top: 4rpx;
color: #7a8582;
font-size: 22rpx;
line-height: 32rpx;
word-break: break-all;
}
.goods-row {
display: flex;
align-items: center;
margin-top: 16rpx;
padding: 14rpx 16rpx;
border-radius: 18rpx;
background: rgba(247, 248, 248, 0.72);
}
.goods-title {
color: #172f2a;
font-size: 24rpx;
font-weight: 900;
}
.goods-desc {
flex: 1;
min-width: 0;
margin-left: 16rpx;
color: #7a8582;
font-size: 22rpx;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.fee-row {
display: flex;
align-items: center;
margin-top: 16rpx;
color: #64726f;
font-size: 24rpx;
line-height: 40rpx;
text-align: center;
}
.big-tag {
margin-right: 12rpx;
padding: 0 10rpx;
height: 32rpx;
line-height: 32rpx;
border-radius: 10rpx;
background: rgba(255, 117, 88, 1);
color: #fff;
font-size: 20rpx;
font-weight: 700;
}
.guize-list {
width: 100%;
padding: 20rpx;
overflow: scroll;
background: #fff;
max-height: 1000rpx;
line-height: 25px;
.fee-text {
flex: 1;
}
.pt-title{
.fee-text text {
color: #00231C;
font-size: 30rpx;
font-weight: 900;
}
.market-fee {
color: #9aa4a1;
font-size: 20rpx;
}
.empty-box {
padding: 120rpx 0;
color: #8b9894;
font-size: 28rpx;
font-weight: 700;
color: #777;
text-align: center;
}
.dingdan{
border-top: 1px solid #eee;
.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);
}
.uni-popup__wrapper{
border-radius: 20rpx !important;
.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;
}
.pituan-text{
.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;
}
.product-popup-img img {
width: 100%;
height: 100%;
background-size: 100%;
}
.product-popup-info {
flex: 1;
text-align:right;
padding-right:20rpx;
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;
}
.bottom-space {
width: 100%;
height: 60rpx;
}
</style>
Loading…
Cancel
Save