|
|
@@ -270,7 +270,7 @@
|
|
|
</view>
|
|
|
</view>
|
|
|
<view v-else-if="freightSource === 'customFallback'" class="quotes-loading">
|
|
|
- <text class="quotes-hint">跑腿报价异常,已按门店自定义规则计费</text>
|
|
|
+ <text class="quotes-hint">{{ runnerFallbackTip || '暂无可用跑腿,已按门店自定义规则计费' }}</text>
|
|
|
</view>
|
|
|
</block>
|
|
|
</view>
|
|
|
@@ -579,6 +579,8 @@ export default {
|
|
|
isFreeDelivery: false,
|
|
|
/** 跑腿运费来源:platform / custom / customFallback / bouquetIncluded / reduceFree */
|
|
|
freightSource: "",
|
|
|
+ /** 自定义兜底时的原因说明(超范围 / 接口失败等),避免一律写「报价异常」 */
|
|
|
+ runnerFallbackTip: "",
|
|
|
deliveryPolicyList: [],
|
|
|
validAddress: false,
|
|
|
hbData: [],
|
|
|
@@ -1910,8 +1912,8 @@ export default {
|
|
|
return 0;
|
|
|
}).catch(() => 0);
|
|
|
},
|
|
|
- /** 应用自定义/兜底运费到表单 */
|
|
|
- applyCustomFreightResult(distanceMeters, source) {
|
|
|
+ /** 应用自定义/兜底运费到表单;tip 仅 customFallback 时用于界面说明 */
|
|
|
+ applyCustomFreightResult(distanceMeters, source, tip) {
|
|
|
const distanceKm = (Number(distanceMeters) || 0) / 1000;
|
|
|
const fee = this.calcCustomFreight(distanceKm);
|
|
|
this.showDistance = distanceMeters;
|
|
|
@@ -1921,15 +1923,41 @@ export default {
|
|
|
if (fee == null) {
|
|
|
this.form.sendCost = 0;
|
|
|
this.freightSource = "";
|
|
|
+ this.runnerFallbackTip = "";
|
|
|
this.isFreeDelivery = false;
|
|
|
this.$msg("自定义计费规则未配置完整,无法计算运费");
|
|
|
return false;
|
|
|
}
|
|
|
this.form.sendCost = fee;
|
|
|
this.freightSource = source;
|
|
|
+ this.runnerFallbackTip = source === "customFallback"
|
|
|
+ ? (tip || "暂无可用跑腿,已按门店自定义规则计费")
|
|
|
+ : "";
|
|
|
this.isFreeDelivery = fee === 0;
|
|
|
return true;
|
|
|
},
|
|
|
+ /**
|
|
|
+ * 平台都不可用时,从禁用原因生成兜底提示(优先识别超配送范围)
|
|
|
+ * @param {Array} rawList all-delivery-quotes 原始 deliveryList
|
|
|
+ * @returns {string}
|
|
|
+ */
|
|
|
+ buildRunnerUnavailableTip(rawList) {
|
|
|
+ const reasons = (rawList || [])
|
|
|
+ .map((item) => {
|
|
|
+ const vg = item && item.valid_goods ? item.valid_goods : {};
|
|
|
+ return String((vg && vg.disable_reason) || item.type || item.disable_reason || "").trim();
|
|
|
+ })
|
|
|
+ .filter(Boolean);
|
|
|
+ const text = reasons.join(";");
|
|
|
+ if (/超配送范围|超出配送范围|超范围|超出范围/.test(text)) {
|
|
|
+ return "收货地址超配送范围,已按门店自定义规则计费";
|
|
|
+ }
|
|
|
+ if (reasons.length > 0) {
|
|
|
+ // 取第一条平台原因,避免文案过长
|
|
|
+ return reasons[0] + ",已按门店自定义规则计费";
|
|
|
+ }
|
|
|
+ return "暂无可用跑腿平台,已按门店自定义规则计费";
|
|
|
+ },
|
|
|
init() {
|
|
|
this.syncShopContext();
|
|
|
},
|
|
|
@@ -2073,6 +2101,7 @@ export default {
|
|
|
this.deliveryQuotesLoading = true;
|
|
|
this.isFreeDelivery = false;
|
|
|
this.freightSource = "";
|
|
|
+ this.runnerFallbackTip = "";
|
|
|
|
|
|
// A:含包运费花束 → 只计距 + 花束运费
|
|
|
if (mode === "bouquetIncluded") {
|
|
|
@@ -2114,20 +2143,28 @@ export default {
|
|
|
this.deliveryQuotesLoading = false;
|
|
|
if (this.hasValidRunnerCustomConfig) {
|
|
|
this.fetchDeliveryDistanceMeters().then((meters) => {
|
|
|
- this.applyCustomFreightResult(meters, "customFallback");
|
|
|
+ this.applyCustomFreightResult(
|
|
|
+ meters,
|
|
|
+ "customFallback",
|
|
|
+ "获取配送距离失败,已按门店自定义规则计费"
|
|
|
+ );
|
|
|
});
|
|
|
} else {
|
|
|
this.$msg("获取距离失败");
|
|
|
}
|
|
|
});
|
|
|
},
|
|
|
- /** 拉跑腿平台报价;失败或无可用平台时改用自定义兜底 */
|
|
|
+ /** 拉跑腿平台报价;失败或无可用平台时改用自定义兜底(提示按真实原因区分) */
|
|
|
fetchPlatformQuotesWithFallback(distanceMeters) {
|
|
|
const hasBouquet = (this.list || []).some((item) => this.isBouquetItem(item));
|
|
|
if (Number(this.allCount.weight) <= 0 && !hasBouquet) {
|
|
|
this.deliveryQuotesLoading = false;
|
|
|
if (this.hasValidRunnerCustomConfig) {
|
|
|
- this.applyCustomFreightResult(distanceMeters, "customFallback");
|
|
|
+ this.applyCustomFreightResult(
|
|
|
+ distanceMeters,
|
|
|
+ "customFallback",
|
|
|
+ "商品无重量无法跑腿报价,已按门店自定义规则计费"
|
|
|
+ );
|
|
|
} else {
|
|
|
this.$msg("商品没有重量,无法使用跑腿");
|
|
|
}
|
|
|
@@ -2135,7 +2172,11 @@ export default {
|
|
|
}
|
|
|
if (Number(this.form.openIntraCity) !== 1) {
|
|
|
this.deliveryQuotesLoading = false;
|
|
|
- this.applyCustomFreightResult(distanceMeters, "customFallback");
|
|
|
+ this.applyCustomFreightResult(
|
|
|
+ distanceMeters,
|
|
|
+ "customFallback",
|
|
|
+ "未开通自动跑腿报价,已按门店自定义规则计费"
|
|
|
+ );
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
@@ -2156,7 +2197,8 @@ export default {
|
|
|
...this.buildDeliveryQuoteAddressPayload()
|
|
|
}).then((res) => {
|
|
|
if (res.code === 1 && res.data && res.data.deliveryList) {
|
|
|
- this.deliveryQuotes = res.data.deliveryList
|
|
|
+ const rawList = res.data.deliveryList || [];
|
|
|
+ this.deliveryQuotes = rawList
|
|
|
.filter((item) => item.isAble !== false)
|
|
|
.map((item) => {
|
|
|
const price = item.price ? (item.price / 100).toFixed(1) : "0.0";
|
|
|
@@ -2181,13 +2223,28 @@ export default {
|
|
|
if (firstAvailableIndex !== -1) {
|
|
|
this.selectDelivery(this.deliveryQuotes[firstAvailableIndex], firstAvailableIndex);
|
|
|
this.freightSource = "platform";
|
|
|
+ this.runnerFallbackTip = "";
|
|
|
return;
|
|
|
}
|
|
|
+ // 有返回但全部不可用(如超配送范围)→ 按原因提示 + 自定义兜底
|
|
|
+ this.applyCustomFreightResult(
|
|
|
+ distanceMeters || this.showDistance,
|
|
|
+ "customFallback",
|
|
|
+ this.buildRunnerUnavailableTip(rawList)
|
|
|
+ );
|
|
|
+ return;
|
|
|
}
|
|
|
- // 无可用平台 → 自定义兜底
|
|
|
- this.applyCustomFreightResult(distanceMeters || this.showDistance, "customFallback");
|
|
|
+ this.applyCustomFreightResult(
|
|
|
+ distanceMeters || this.showDistance,
|
|
|
+ "customFallback",
|
|
|
+ "跑腿报价失败,已按门店自定义规则计费"
|
|
|
+ );
|
|
|
}).catch(() => {
|
|
|
- this.applyCustomFreightResult(distanceMeters || this.showDistance, "customFallback");
|
|
|
+ this.applyCustomFreightResult(
|
|
|
+ distanceMeters || this.showDistance,
|
|
|
+ "customFallback",
|
|
|
+ "跑腿报价失败,已按门店自定义规则计费"
|
|
|
+ );
|
|
|
}).finally(() => {
|
|
|
this.deliveryQuotesLoading = false;
|
|
|
});
|