wangfukang 1 month ago
parent
commit
f76f0a4890
  1. 27
      package1/buyFood/buyFood.vue
  2. 328
      package1/order/orderDetail.vue
  3. 94
      package1/order/orderList.vue
  4. 8
      package1/order/returnOrder.vue
  5. 18
      package1/runErrand/runErrand.vue

27
package1/buyFood/buyFood.vue

@ -137,7 +137,7 @@
<uni-icons type="right" size="12" color="#8b9993"></uni-icons>
</view>
</view>
<view class="delivery-option">
<view class="delivery-option" @tap="goDetail">
<view class="delivery-choice">
<view class="radio-check" v-if="selected === 'zhiding'">
<uni-icons type="checkmarkempty" size="12"></uni-icons>
@ -357,6 +357,9 @@
<input type="digit" :value="commissionInputValue" placeholder="请输入佣金"
@input="onCommissionPopupInput" />
</view>
<view class="commission-popup-tip" v-if="isGroupBuy && groupItem && groupItem.isFaceToFace && !groupItem.groupId">
佣金为团配送单总佣金设置后会按照参团人数自动计算均摊
</view>
<view class="commission-popup-actions">
<view class="commission-popup-cancel" @tap="$refs.commissionPopup.close()">取消</view>
<view class="commission-popup-confirm" @tap="confirmCommission">确定</view>
@ -405,8 +408,11 @@
<text
style="font-size: 60rpx;">{{backendTotalAmount ? backendTotalAmount.toFixed(2) : totalAmountCalc.toFixed(2)}}</text>
</view>
<view style="height: 40rpx;text-align: center;color: red;" v-if="isGroupBuy">
若拼团失败将会为您自动退款
<view style="height: 40rpx;text-align: center;color: red;" v-if="isGroupBuy && isStoreGroupOrder">
若24小时内拼团失败将会为您自动退款
</view>
<view style="height: 40rpx;text-align: center;color: red;" v-if="isGroupBuy && !isStoreGroupOrder && isPaotui">
若1小时内拼团失败将会为您自动退款
</view>
</view>
<view class="box1" style="display: flex;padding: 40rpx;">
@ -897,7 +903,6 @@
refreshDeliveryTimeByModeChange() {
this.updateImmediateTimeStr();
if (this.formData.isImmediately === false) {
this.formData.deliveryTime = '';
this.generateDeliveryTimes();
}
},
@ -1027,7 +1032,7 @@
this.tui.request('/mall/coupon/available', 'GET', {
userId: userId,
regionId:JSON.parse(uni.getStorageSync('area')).id,
applyScene: 1,
applyScene: this.isStoreGroupOrder ? 4 : 1,
amount: amount,
merchantId: this.shopItem.id || this.shopItem.shopId || '0'
}, false, true).then((res) => {
@ -1940,6 +1945,18 @@
}
}
.commission-popup-tip {
margin-top: 18rpx;
padding: 14rpx 18rpx;
border-radius: 18rpx;
background: #fff5ec;
border: 1rpx solid rgba(255, 112, 67, 0.28);
color: #f0441f;
font-size: 22rpx;
font-weight: 800;
line-height: 34rpx;
}
.commission-popup-actions {
display: flex;
margin-top: 34rpx;

328
package1/order/orderDetail.vue

@ -154,7 +154,7 @@
</view>
<view class="status-fu" v-if="orderDetail.status == 0">
<view class="">
创建时间 <text style="color:red;font-weight: 700;">{{orderDetail.createTime | formatTime}}</text></view>
剩余支付时间 <text style="color:red;font-weight: 700;">{{payCountdownText}}</text></view>
</view>
<view class="status-fu" v-else-if="orderDetail.deliveryInfo">
<view class="">
@ -700,7 +700,7 @@
<uni-icons type="info" size="14" color="#ff5722"></uni-icons>
<text
v-if="(((payData.orderType == 2 || payData.orderType == 3) && payData.status == 2) || ((payData.orderType == 2 || payData.orderType == 3) && payData.status == 3) || (payData.deliveryType == 1 && payData.status == 3) || payData.status == 4) && payData.otherOrder == null">
取消订单需要商家同意
请确认责任方取消订单需要责任方同意
</text>
<text v-else>请选择退款原因</text>
</view>
@ -783,6 +783,23 @@
</view>
</uni-popup>
<uni-popup ref="noResponsibilityCancelPopup" type="center" background-color="transparent">
<view class="no-responsibility-cancel-popup">
<view class="no-responsibility-cancel-title">确认取消订单吗</view>
<view class="no-responsibility-cancel-desc">符合无责取消条件订单金额将按平台退款处理</view>
<view class="no-responsibility-cancel-actions">
<view class="no-responsibility-cancel-btn no-responsibility-cancel-btn-muted"
@tap="$refs.noResponsibilityCancelPopup.close()">
再想想
</view>
<view class="no-responsibility-cancel-btn no-responsibility-cancel-btn-confirm"
@tap="confirmNoResponsibilityCancel()">
确认取消
</view>
</view>
</view>
</uni-popup>
<!-- 待支付订单支付弹出层 -->
<uni-popup ref="payPopup" background-color="#fff">
<view class="pay-popup">
@ -905,7 +922,7 @@
return {
newQRList: '',
pintuan: false,
sellTime: 2,
sellTime: '',
menuButtonInfo: {},
refundType: 3,
refundTypeStatus: 1,
@ -931,7 +948,10 @@
isRefreshing: false,
groupBuyCancelPopupType: 'buy',
assignWorkerModalVisible: false,
assignWorkerSelectionKey: ''
assignWorkerSelectionKey: '',
payCountdownText: '60:00',
payCountdownSeconds: 0,
payCountdownTimer: null
}
},
computed: {
@ -1047,11 +1067,66 @@
onPullDownRefresh() {
this.getOrderDetail(this.orderId)
},
onHide() {
this.stopPayCountdown();
},
onUnload() {
uni.$off('updateDeliveryWorker');
this.stopPayCountdown();
},
methods: {
startPayCountdown() {
this.stopPayCountdown();
if (this.orderDetail.status != 0 || !this.orderDetail.createTime) {
this.setPayCountdown(0);
return;
}
this.setPayCountdown(this.getPayCountdownSeconds());
this.payCountdownTimer = setInterval(() => {
if (this.orderDetail.status != 0) {
this.stopPayCountdown();
return;
}
this.setPayCountdown(Math.max(this.payCountdownSeconds - 1, 0));
if (this.payCountdownSeconds <= 0) {
this.stopPayCountdown();
}
}, 1000);
},
stopPayCountdown() {
if (this.payCountdownTimer) {
clearInterval(this.payCountdownTimer);
this.payCountdownTimer = null;
}
},
getPayCountdownSeconds() {
const createTime = this.parseOrderTime(this.orderDetail.createTime);
if (!createTime) {
return 0;
}
const expireTime = createTime.getTime() + 60 * 60 * 1000;
const remainMs = expireTime - Date.now();
return Math.max(Math.floor(remainMs / 1000), 0);
},
setPayCountdown(totalSeconds) {
this.payCountdownSeconds = totalSeconds;
const minutes = String(Math.floor(totalSeconds / 60)).padStart(2, '0');
const seconds = String(totalSeconds % 60).padStart(2, '0');
this.payCountdownText = `${minutes}:${seconds}`;
this.$forceUpdate();
},
parseOrderTime(value) {
if (!value) return null;
if (value instanceof Date) return isNaN(value.getTime()) ? null : value;
let date = new Date(value);
if (!isNaN(date.getTime())) {
return date;
}
const normalized = String(value).replace(/-/g, '/').replace('T', ' ').split('.')[0];
date = new Date(normalized);
return isNaN(date.getTime()) ? null : date;
},
formatTimeText(value) {
if (!value) return '';
if (value == '尽快送达') return '尽快送达';
@ -1229,12 +1304,62 @@
}
return false;
},
hasNoDeliveryWorker(item) {
return !item || !item.deliveryInfo || !item.deliveryInfo.workerId;
},
isGroupSuccess(item) {
return item && item.groupInfo && (item.groupInfo.status == 1 || item.groupInfo.successTime);
},
isAfterGroupSuccessMinutes(item, minutes) {
if (!item || !item.groupInfo || !item.groupInfo.successTime) {
return false;
}
const successTime = this.parseOrderTime(item.groupInfo.successTime);
if (!successTime) {
return false;
}
return Date.now() - successTime.getTime() >= minutes * 60 * 1000;
},
isNoResponsibilityCancel(item) {
if (!item) return false;
const isNormalOrder = item.orderType == 1 && item.otherOrder == null;
const isGroupDeliveryOrder = item.deliveryType == 1 && item.otherOrder == null && this.isGroupSuccess(item);
const isSelfPickupNoMake = item.deliveryType == 2 && item.status == 3 && isNormalOrder &&
(item.userRequireMake == null || item.userRequireMake == 0) && !item.shopMakeTime;
if (isNormalOrder && item.deliveryType == 1 && this.hasNoDeliveryWorker(item)) {
return true;
}
if (isSelfPickupNoMake) {
return true;
}
if (isGroupDeliveryOrder && item.orderType == 3 && item.groupInfo.headOrderId == item.id &&
this.hasNoDeliveryWorker(item)) {
return true;
}
if (isGroupDeliveryOrder && item.orderType == 2 && this.isAfterGroupSuccessMinutes(item, 10) &&
this.hasNoDeliveryWorker(item)) {
return true;
}
if (item.otherOrder == 2 && item.status == 3 && !item.shopMakeTime) {
return true;
}
if (item.otherOrder == 1 && this.hasNoDeliveryWorker(item)) {
return true;
}
return false;
},
returnPopupProp(item) {
this.payData = item;
if (item.status == 0) {
this.cancelUnpaidOrder(item);
return;
}
if (this.isNoResponsibilityCancel(item)) {
this.$refs.noResponsibilityCancelPopup.open('center');
return;
}
if (this.payData.otherOrder == 1) {
this.refundType = 3
@ -1302,6 +1427,27 @@
}
}).catch((res) => {});
},
confirmNoResponsibilityCancel() {
this.$refs.noResponsibilityCancelPopup.close();
let item = this.payData;
let that = this;
that.tui.request("/mall/order/cancel", "POST", {
status: 1,
refundType: 3,
refundTypeStatus: 4,
orderId: item.id,
userId: uni.getStorageSync('id')
}, false, true).then((res) => {
uni.hideLoading();
if (res.code == 200) {
that.tui.toast("操作成功");
that.getOrderDetail(item.id);
that.$forceUpdate();
} else {
that.tui.toast(res.message, 2000);
}
}).catch((res) => {});
},
returnPopupPropBuy(item) {
this.payData = item;
this.groupBuyCancelPopupType = 'buy';
@ -1343,10 +1489,10 @@
this.$refs.returnPopupBuy.open('bottom');
},
returnOrder() {
/* if(this.sellTime == 5 && this.remark == ""){
that.tui.toast("请填写备注");
if(this.sellTime == ''){
this.tui.toast("请选择退款责任方");
return
} */
}
this.$refs.returnPopup.close();
let item = this.payData
let that = this
@ -1412,22 +1558,52 @@
id: that.payData.shopId,
regionId: JSON.parse(uni.getStorageSync('area')).id
}, false, true).then((res1) => {
if (res1.code == 200) {
uni.hideLoading();
//
let cartItems = [];
for (let i = 0; i < that.payData.goodsList.length; i++) {
let productPrice = that.payData.goodsList[i].price
for (let a = 0; a < res1.result.products.length; a++) {
if (res1.result.products[a].id == that.payData.goodsList[i]
.productId) {
let priceToUse = 0;
if (res1.result.products[a].attributeListPrice) {
try {
let pObj = typeof res1.result.products[a]
.attributeListPrice === 'string' ? JSON.parse(res1
.result.products[a].attributeListPrice) :
res1.result.products[a].attributeListPrice;
try {
if (res1.code == 200) {
uni.hideLoading();
// 1. JSON undefined, null
const safeJsonParse = (str, fallback = null) => {
if (!str || typeof str !== 'string') return fallback;
try {
return JSON.parse(str);
} catch (e) {
console.warn('JSON解析失败,原始数据:', str, '错误:', e.message);
return fallback;
}
};
let cartItems = [];
for (let i = 0; i < that.payData.goodsList.length; i++) {
let productPrice = that.payData.goodsList[i].price;
for (let a = 0; a < res1.result.products.length; a++) {
if (res1.result.products[a].id == that.payData.goodsList[i].productId) {
let priceToUse = 0;
let rawAttrPrice = res1.result.products[a].attributeListPrice;
// 2. attributeListPrice
let pObj = null;
if (typeof rawAttrPrice === 'string') {
pObj = safeJsonParse(rawAttrPrice); //
if (!pObj) {
//
try {
//
let fixedStr = rawAttrPrice.replace(/(\[{)(.*?)(\]})/g, (match, p1, p2, p3) => {
return p1 + p2.replace(/"/g, '\\"') + p3;
});
pObj = JSON.parse(fixedStr);
} catch (err) {
console.warn('attributeListPrice 修复解析依然失败:', err.message);
}
}
} else {
pObj = rawAttrPrice; // 使
}
// 3.
if (pObj) {
if (Array.isArray(pObj) && pObj.length > 0) {
priceToUse = parseFloat(pObj[0].specPrice);
} else {
@ -1436,34 +1612,42 @@
break;
}
}
} catch (e) {}
}
productPrice = priceToUse;
}
productPrice = priceToUse
}
that.payData.goodsList[i].id = that.payData.goodsList[i].productId;
let specStr = that.payData.goodsList[i].specs;
let cartId = that.payData.goodsList[i].productId + '_' + specStr;
// 4. specs
let parsedSpecs = safeJsonParse(specStr, []);
cartItems.push({
cartId: cartId,
item: that.payData.goodsList[i],
specs: parsedSpecs, // 使
quantity: that.payData.goodsList[i].quantity,
price: productPrice.toFixed(2)
});
}
that.payData.goodsList[i].id = that.payData.goodsList[i].productId
let specStr = that.payData.goodsList[i].specs;
let cartId = that.payData.goodsList[i].productId + '_' + specStr;
cartItems.push({
cartId: cartId,
item: that.payData.goodsList[i],
specs: JSON.parse(that.payData.goodsList[i].specs),
quantity: that.payData.goodsList[i].quantity,
price: productPrice.toFixed(2)
uni.navigateTo({
url: '/package1/buyFood/buyFood?cart=' + encodeURIComponent(JSON.stringify(cartItems)) +
'&shopItem=' + encodeURIComponent(JSON.stringify(res1.result.shop)) +
'&packageFee=' + that.payData.packageFee
});
} else {
that.tui.toast(res.message, 2000);
return;
}
uni.navigateTo({
url: '/package1/buyFood/buyFood?cart=' + encodeURIComponent(
JSON.stringify(cartItems)) +
'&shopItem=' + encodeURIComponent(JSON.stringify(res1
.result.shop)) + '&packageFee=' +
that.payData.packageFee
});
} else {
that.tui.toast(res.message,2000);
return;
} catch (e) {
console.error('结算逻辑发生异常:', e.message);
} finally {
// 5. Loading if
uni.hideLoading();
}
uni.hideLoading();
}).catch((res1) => {});
} else {
that.tui.toast(res.message);
@ -1498,6 +1682,7 @@
uni.stopPullDownRefresh()
if (res.code == 200) {
that.orderDetail = res.result;
that.startPayCountdown();
if (that.orderDetail.mallRefundRecord != null && that.orderDetail.mallRefundRecord.length >
0) {
for (let i = 0; i < that.orderDetail.mallRefundRecord.length; i++) {
@ -2463,6 +2648,59 @@
box-shadow: 0 28rpx 70rpx rgba(0, 35, 28, 0.18);
}
.no-responsibility-cancel-popup {
width: 620rpx;
padding: 46rpx 36rpx 34rpx;
box-sizing: border-box;
border-radius: 32rpx;
background: #fff;
box-shadow: 0 28rpx 70rpx rgba(0, 35, 28, 0.18);
}
.no-responsibility-cancel-title {
color: #243f38;
font-size: 36rpx;
font-weight: 900;
line-height: 52rpx;
text-align: center;
}
.no-responsibility-cancel-desc {
margin-top: 16rpx;
color: #7b8883;
font-size: 26rpx;
font-weight: 700;
line-height: 38rpx;
text-align: center;
}
.no-responsibility-cancel-actions {
display: flex;
gap: 18rpx;
margin-top: 42rpx;
}
.no-responsibility-cancel-btn {
flex: 1;
height: 82rpx;
border-radius: 999rpx;
font-size: 28rpx;
font-weight: 900;
line-height: 82rpx;
text-align: center;
}
.no-responsibility-cancel-btn-muted {
background: #f3f6f4;
color: #87938f;
}
.no-responsibility-cancel-btn-confirm {
background: linear-gradient(135deg, #fff7d7 0%, #a6ffea 100%);
color: #243f38;
box-shadow: 0 12rpx 26rpx rgba(0, 191, 160, 0.12);
}
.commission-popup-title {
color: #243f38;
font-size: 34rpx;

94
package1/order/orderList.vue

@ -149,13 +149,15 @@
</view>
</view>
</view>
<view style="display: flex;background: rgba(247, 248, 248, 0.6);border-radius: 10px;align-items: center;" @tap.stop="orderDetail(item.id)">
<view v-else style="width: 80%;overflow: scroll;display: flex;padding: 20rpx;background: rgba(247, 248, 248, 0.6);border-radius: 20rpx;" v-for="(item1,index1) in item.goodsList" :key="index1" v-if="item.goodsList != null && item.goodsList.length > 0">
<view class="goods-img">
<img :src="item1.productPicture" alt="">
<view v-if="item.otherOrder != 1" class="goods-card" @tap.stop="orderDetail(item.id)">
<scroll-view v-if="item.goodsList != null && item.goodsList.length > 0" class="goods-scroll" scroll-x enable-flex :show-scrollbar="false">
<view class="goods-scroll-inner">
<view class="goods-img goods-scroll-img" v-for="(item1,index1) in item.goodsList" :key="index1">
<image :src="item1.productPicture" mode="aspectFill"></image>
</view>
</view>
</view>
<view class="goods-content">
</scroll-view>
<view class="goods-content goods-price">
<view class="goods-name">
<view><text style="font-size: 32rpx;">{{item.totalAmount}}</text></view>
<view style="color:#777;">{{item.num}}</view>
@ -339,6 +341,10 @@
this.searchForm.pageNum++;
this.getOrderList();
},
onPullDownRefresh() {
this.resetOrderList()
this.getOrderList()
},
filters: {
formatHourMinute(value) {
if (!value) return '';
@ -388,12 +394,19 @@
},
onShow() {
this.getOrderList()
this.menuButtonInfo = uni.getMenuButtonBoundingClientRect()
this.searchForm.userId = uni.getStorageSync('id')
this.searchForm.regionId = JSON.parse(uni.getStorageSync('area')).id
this.resetOrderList()
this.getOrderList()
},
methods: {
resetOrderList() {
this.orderList = []
this.pageNum = 1
this.searchForm.pageNum = 1
this.loadStatus = 'more'
},
checkTab1(type) {
this.tab1Checked = type
if(type == 'quanbu'){
@ -491,8 +504,22 @@
});
},
goEvaluate(item){
uni.navigateTo({
url: '/package1/order/orderEvaluate?item=' + JSON.stringify(item)
let that = this;
that.tui.request("/app/comment/getByOrderId?orderId=" + item.id, "POST", {}, false, true).then((res) => {
uni.hideLoading();
if (res.code == 200) {
if (res.result != null && res.result.length > 0) {
that.tui.toast("该订单已经评价过了");
return;
}
uni.navigateTo({
url: '/package1/order/orderEvaluate?item=' + JSON.stringify(item)
});
} else {
that.tui.toast(res.message);
}
}).catch((res) => {
uni.hideLoading();
});
},
checkTabs2(type) {
@ -515,7 +542,7 @@
getOrderList(){
this.loadStatus = 'loading'
let that = this
that.tui.request("/mall/order/page", "POST", this.searchForm, false, false).then((res) => {
return that.tui.request("/mall/order/page", "POST", this.searchForm, false, false).then((res) => {
that.loadStatus = 'nomore';
if (res.code == 200) {
if (that.searchForm.pageNum == 1) {
@ -536,7 +563,9 @@
return;
}
uni.hideLoading();
}).catch((res) => {});
}).catch((res) => {}).finally(() => {
uni.stopPullDownRefresh();
});
},
returnPopupProp(item){
this.payData = item;
@ -921,23 +950,58 @@
position: relative;
background: #fff;
border-radius: 24rpx;
margin-right: 10px;
overflow: hidden;
box-shadow: 0 12rpx 24rpx rgba(0, 35, 28, 0.08);
img {
width: 160rpx;
background-size: 100%;
img,
image {
width: 100%;
height: 100%;
border-radius: 24rpx;
display: block;
}
}
.goods-card {
display: flex;
align-items: center;
padding: 20rpx;
background: rgba(247, 248, 248, 0.6);
border-radius: 20rpx;
box-sizing: border-box;
}
.goods-scroll {
flex: 1;
width: 0;
min-width: 0;
white-space: nowrap;
}
.goods-scroll-inner {
display: inline-flex;
align-items: center;
}
.goods-scroll-img {
flex: 0 0 160rpx;
margin-right: 20rpx;
}
.goods-scroll-img:last-child {
margin-right: 0;
}
.goods-content {
padding: 0 20rpx;
text-align: center;
}
.goods-price {
flex: 0 0 128rpx;
padding: 0 0 0 20rpx;
}
.goods-name {
font-weight: 900;
color: #243f38;

8
package1/order/returnOrder.vue

@ -223,7 +223,7 @@
</view>
<scroll-view scroll-y class="reason-scroll" @touchmove.stop>
<view style="padding: 0 20rpx;">
<view class="reason-type-item" v-if="orderDetail.deliveryType ==1 && orderDetail.otherOrder != 1">
<view class="reason-type-item" v-if="orderDetail.otherOrder != 1">
<radio :checked="sellTime==0" name="sellTime" @click="checkSellTime(0)" />
商品退款
</view>
@ -295,7 +295,7 @@
export default {
data() {
return {
sellTime: 0,
sellTime: 100,
pintuan: false,
menuButtonInfo: {},
orderId: '',
@ -402,6 +402,10 @@
this.$refs.carPopup.open('bottom');
},
chooseReturnType() {
if(this.sellTime == 100){
this.tui.toast("请选择售后责任方");
return
}
this.$refs.carPopup.close()
if (this.sellTime == 0) {
this.returnData.refundAmount = 0

18
package1/runErrand/runErrand.vue

@ -896,9 +896,21 @@
this.$refs.warnPopup.open();
return;
}
if (this.isKuaidi && (!this.addFormData.codeList || this.addFormData.codeList[0].code.trim() === '') && this.addFormData.picture.length === 0) {
uni.showToast({ title: '请填写取件码或上传截图凭证', icon: 'none' });
return;
if (this.isKuaidi) {
let hasEdit = false
if(this.addFormData.codeList && this.addFormData.codeList[0].code.trim() != ''){
hasEdit = true
}
if(this.addFormData.picture.length != 0){
hasEdit = true
}
if(this.addFormData.phoneNumber.length != 0){
hasEdit = true
}
if(hasEdit == false){
uni.showToast({ title: '请填写手机尾号或取件码或上传截图凭证', icon: 'none' });
return;
}
}
this.submitOrderToBackend();

Loading…
Cancel
Save