|
|
@@ -0,0 +1,776 @@
|
|
|
+<!--
|
|
|
+ 36523 门店确认页配送业务面板:拉取配置、配送方式、地址、跑腿报价、费用计算、提交校验。
|
|
|
+ 供 affirmGhs.vue 引用,通过 change 事件向父页面同步下单所需字段。
|
|
|
+-->
|
|
|
+<template>
|
|
|
+ <view>
|
|
|
+ <tui-list-cell class="line-cell" :hover="false" :arrow="false">
|
|
|
+ <button
|
|
|
+ v-for="(item, index) in visibleMethodList"
|
|
|
+ :key="item.style"
|
|
|
+ class="admin-button-com middle sh-method-btn"
|
|
|
+ :class="[
|
|
|
+ selectedMethodIndex === index ? 'blue' : 'default',
|
|
|
+ item.name && item.name.length <= 2 ? 'sh-method-btn--short' : 'sh-method-btn--long'
|
|
|
+ ]"
|
|
|
+ @click="selectMethodByIndex(index)"
|
|
|
+ >{{ item.name }}</button>
|
|
|
+ </tui-list-cell>
|
|
|
+
|
|
|
+ <tui-list-cell
|
|
|
+ v-if="currentMethodExplains.length > 0"
|
|
|
+ class="line-cell"
|
|
|
+ :hover="false"
|
|
|
+ :arrow="false"
|
|
|
+ >
|
|
|
+ <view>
|
|
|
+ <view v-for="(exp, index) in currentMethodExplains" :key="index">
|
|
|
+ <text :style="'width:100%;color:' + (Number(exp.color) === 2 ? 'red' : Number(exp.color) === 3 ? '#3385FF' : '#333333') + ';font-weight:' + (Number(exp.fontWeight) === 2 ? 'bold' : 'normal') + ';'">{{ exp.explain }}</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </tui-list-cell>
|
|
|
+
|
|
|
+ <block v-if="$util.isEmpty(wlList) && localForm.sendType == 3">
|
|
|
+ <tui-list-cell class="line-cell" :hover="false">
|
|
|
+ <view class="tui-title">配送物流</view>
|
|
|
+ <input type="text" placeholder="请填选物流" v-model="localForm.wlName" @focus="localForm.wlName=''" placeholder-class="tui-placeholder"/>
|
|
|
+ </tui-list-cell>
|
|
|
+ </block>
|
|
|
+ <block v-else>
|
|
|
+ <tui-list-cell class="line-cell" :arrow="true" v-if="localForm.sendType == 3">
|
|
|
+ <div class="tui-title">配送物流</div>
|
|
|
+ <picker mode="selector" :value="localForm.wlId" :range="wlList" range-key="name" @change="changeWlFn" class="tui-input">
|
|
|
+ <div v-if="localForm.wlId">{{ wlSelData.name }}</div>
|
|
|
+ <div class="tui-placeholder" v-else>请选择</div>
|
|
|
+ </picker>
|
|
|
+ </tui-list-cell>
|
|
|
+ </block>
|
|
|
+
|
|
|
+ <tui-list-cell class="line-cell" :hover="false" :arrow="false" v-if="showShMethodExtraFee">
|
|
|
+ <view>
|
|
|
+ <text style="color: red;width:100%;">{{ shMethodUnMeetWarningText }}</text>
|
|
|
+ </view>
|
|
|
+ </tui-list-cell>
|
|
|
+
|
|
|
+ <tui-list-cell v-if="localForm.sendType == 2 && ghsInfo.openIntraCity != 1" class="line-cell" :hover="false" :arrow="false">
|
|
|
+ <view>
|
|
|
+ <text v-if="ghsInfo.openIntraCity == 0" style="color: #3385FF;width:100%;font-size:30upx;font-weight:bold;">运费自理或到付(请联系客服)</text>
|
|
|
+ <text v-if="ghsInfo.openIntraCity == 2" style="color: red;width:100%;font-size:30upx;font-weight:bold;">跑腿配送暂不可用,请选其它方式</text>
|
|
|
+ </view>
|
|
|
+ </tui-list-cell>
|
|
|
+
|
|
|
+ <tui-list-cell class="line-cell" :hover="false" :arrow="true" v-if="displayAddress" @click="modifyAddress">
|
|
|
+ <view class="tui-title">收花地址</view>
|
|
|
+ <view v-if="validAddress || ghsInfo.shopId==10649 || ghsInfo.shopId ==33668">
|
|
|
+ <view style="overflow: hidden;text-overflow: ellipsis;white-space: nowrap;width:420upx;"><text>{{ shopInfo.address }}</text></view>
|
|
|
+ <view v-if="shopInfo.showAddress!=shopInfo.fullAddress" style="color:#848181;"><text>{{ shopInfo.showAddress }}</text></view>
|
|
|
+ </view>
|
|
|
+ <view v-else>
|
|
|
+ <view><text style="color:red;font-weight:bold;font-size:30upx;">请填写您的地址</text></view>
|
|
|
+ </view>
|
|
|
+ </tui-list-cell>
|
|
|
+
|
|
|
+ <tui-list-cell v-if="localForm.sendType == 2 && ghsInfo.openIntraCity == 1" class="line-cell" :hover="false">
|
|
|
+ <view v-if="ghsInfo.openIntraCity == 1 && deliveryQuotes.length > 0" class="delivery-quotes-container">
|
|
|
+ <view class="delivery-quotes-grid">
|
|
|
+ <view
|
|
|
+ v-for="(item, index) in deliveryQuotes"
|
|
|
+ :key="index"
|
|
|
+ class="delivery-quote-item"
|
|
|
+ :class="{
|
|
|
+ 'active': selectedDeliveryIndex === index,
|
|
|
+ 'disabled': !item.isAble,
|
|
|
+ 'fixed-width': deliveryQuotes.length <= 2
|
|
|
+ }"
|
|
|
+ @click="selectDelivery(item, index)"
|
|
|
+ >
|
|
|
+ <view class="platform-name">{{ item.displayName || item.name }}</view>
|
|
|
+ <view class="platform-price">{{ item.priceText }}元</view>
|
|
|
+ <view v-if="item.type" class="platform-type">{{ item.type }}</view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view v-else style="text-align: center; padding: 20upx 0;">
|
|
|
+ <text v-if="validAddress">正在获取运费...</text>
|
|
|
+ <text v-else style="color:red;font-weight:bold;font-size:32upx;" @click="modifyAddress">收货地址缺失,请填写</text>
|
|
|
+ </view>
|
|
|
+ </tui-list-cell>
|
|
|
+
|
|
|
+ <tui-list-cell class="line-cell" :hover="false" v-if="displaySendCost && Number(showDistance)>0">
|
|
|
+ <view class="tui-title">距离</view>
|
|
|
+ <text v-if="showDistance > 100" style="color: #3385FF">{{ (showDistance/1000).toFixed(1) }}公里</text>
|
|
|
+ <text v-else style="color: #3385FF">{{ showDistance }} 米</text>
|
|
|
+ <text v-if="showDeliveryPolicy" class="delivery-policy-link" @click="showDeliveryPolicyModal">免跑腿费条件</text>
|
|
|
+ </tui-list-cell>
|
|
|
+
|
|
|
+ <tui-list-cell class="line-cell" :hover="false" v-if="displaySendCost">
|
|
|
+ <view class="tui-title">跑腿费</view>
|
|
|
+ <view>
|
|
|
+ <text :class="isFreeDelivery ? 'delivery-price-free' : 'delivery-price-normal'">¥{{ localForm.sendCost }}</text>
|
|
|
+ <text v-if="isFreeDelivery" class="free-delivery-tag">¥0【免跑腿费】</text>
|
|
|
+ </view>
|
|
|
+ </tui-list-cell>
|
|
|
+
|
|
|
+ <tui-list-cell class="line-cell" :hover="false" v-if="showShMethodExtraFee">
|
|
|
+ <view class="tui-title">{{ shMethodExtraFeeLabel }}</view>
|
|
|
+ <text style="color: #3385FF">¥{{ shMethodExtraFeeAmount }}</text>
|
|
|
+ </tui-list-cell>
|
|
|
+
|
|
|
+ <tui-list-cell class="line-cell" :hover="false" :arrow="false">
|
|
|
+ <view class="tui-title">总金额</view>
|
|
|
+ <text style="color: #3385FF">¥ {{ panelTotalPrice }}</text>
|
|
|
+ </tui-list-cell>
|
|
|
+
|
|
|
+ <tui-list-cell class="line-cell" :hover="false" :arrow="true">
|
|
|
+ <view class="tui-title">配送日期</view>
|
|
|
+ <picker mode="date" :value="sendTimeWant" @change="bindDateChange" style="width:400upx;">
|
|
|
+ <view class="uni-input" v-if="sendTimeWant==''" style="color:#CCCCCC;">请选日期,默认当天</view>
|
|
|
+ <view class="uni-input">{{ sendTimeWant }}</view>
|
|
|
+ </picker>
|
|
|
+ </tui-list-cell>
|
|
|
+
|
|
|
+ <tui-list-cell class="line-cell" :hover="false" :arrow="false">
|
|
|
+ <textarea style="height: 100upx" v-model="remark" placeholder="这里写备注"/>
|
|
|
+ </tui-list-cell>
|
|
|
+
|
|
|
+ <uni-popup ref="deliveryPolicyPopup" type="center" background-color="#fff">
|
|
|
+ <view class="policy-popup-content">
|
|
|
+ <view class="policy-title">免费配送条件</view>
|
|
|
+ <scroll-view scroll-y="true" class="policy-scroll">
|
|
|
+ <view class="policy-list">
|
|
|
+ <block v-for="(item, index) in deliveryPolicyList" :key="index">
|
|
|
+ <view class="policy-item">{{ item }}</view>
|
|
|
+ </block>
|
|
|
+ </view>
|
|
|
+ </scroll-view>
|
|
|
+ <view class="policy-btn" @click="closeDeliveryPolicy">知道了</view>
|
|
|
+ </view>
|
|
|
+ </uni-popup>
|
|
|
+ </view>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import { mapGetters } from "vuex";
|
|
|
+import TuiListCell from "@/components/plugin/list-cell";
|
|
|
+import { getWlList } from "@/api/ghs";
|
|
|
+import { getShMethod } from "@/api/purchase";
|
|
|
+import { currentShop } from "@/api/shop";
|
|
|
+import { allDeliveryQuotes } from "@/api/express/delivery";
|
|
|
+
|
|
|
+export default {
|
|
|
+ name: "AffirmShMethodPanel",
|
|
|
+ components: {
|
|
|
+ TuiListCell
|
|
|
+ },
|
|
|
+ props: {
|
|
|
+ ghsInfo: { type: Object, default: () => ({}) },
|
|
|
+ ghsId: { type: [Number, String], default: 0 },
|
|
|
+ commodityPrice: { type: [Number, String], default: 0 },
|
|
|
+ commodityBigCount: { type: [Number, String], default: 0 },
|
|
|
+ commodityWeight: { type: [Number, String], default: 0 },
|
|
|
+ selectList: { type: Array, default: () => [] }
|
|
|
+ },
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ methodList: [],
|
|
|
+ /** 当前选中的配送方式下标,默认加载后选中第一项 */
|
|
|
+ selectedMethodIndex: -1,
|
|
|
+ wlList: [],
|
|
|
+ wlSelData: { id: 0, name: "" },
|
|
|
+ shopInfo: {
|
|
|
+ lat: "",
|
|
|
+ long: "",
|
|
|
+ fullAddress: "",
|
|
|
+ showAddress: "",
|
|
|
+ address: ""
|
|
|
+ },
|
|
|
+ validAddress: false,
|
|
|
+ localForm: {
|
|
|
+ sendType: 0,
|
|
|
+ wlName: "",
|
|
|
+ wlId: 0,
|
|
|
+ sendCost: 0,
|
|
|
+ packCost: 0
|
|
|
+ },
|
|
|
+ deliveryQuotes: [],
|
|
|
+ selectedDeliveryIndex: -1,
|
|
|
+ selectedDeliveryData: null,
|
|
|
+ showDistance: 0,
|
|
|
+ sendTimeWant: "",
|
|
|
+ remark: "",
|
|
|
+ deliveryPolicyList: []
|
|
|
+ };
|
|
|
+ },
|
|
|
+ computed: {
|
|
|
+ ...mapGetters(["getLoginInfo"]),
|
|
|
+ visibleMethodList() {
|
|
|
+ return (this.methodList || [])
|
|
|
+ .filter(item => Number(item.status) === 1)
|
|
|
+ .sort((a, b) => Number(a.sort) - Number(b.sort))
|
|
|
+ },
|
|
|
+ currentShMethod() {
|
|
|
+ const list = this.visibleMethodList
|
|
|
+ if (this.selectedMethodIndex >= 0 && this.selectedMethodIndex < list.length) {
|
|
|
+ return list[this.selectedMethodIndex]
|
|
|
+ }
|
|
|
+ return null
|
|
|
+ },
|
|
|
+ displayAddress() {
|
|
|
+ return Number(this.localForm.sendType) !== 1
|
|
|
+ },
|
|
|
+ displaySendCost() {
|
|
|
+ if (Number(this.localForm.sendType) === 2) {
|
|
|
+ return ![0, 2].includes(Number(this.ghsInfo.openIntraCity))
|
|
|
+ }
|
|
|
+ return false
|
|
|
+ },
|
|
|
+ isFreeDelivery() {
|
|
|
+ if (!this.displaySendCost || !this.validAddress) {
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ const distanceInMeters = Number(this.showDistance) || 0
|
|
|
+ const freeKmInMeters = (Number(this.ghsInfo.hcFreeKm) || 0) * 1000
|
|
|
+ if (distanceInMeters < freeKmInMeters) {
|
|
|
+ return true
|
|
|
+ }
|
|
|
+ if (distanceInMeters > freeKmInMeters) {
|
|
|
+ let mapData = this.ghsInfo.hcMap
|
|
|
+ if (mapData && typeof mapData === "string") {
|
|
|
+ try {
|
|
|
+ mapData = JSON.parse(mapData)
|
|
|
+ } catch (e) {
|
|
|
+ mapData = []
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (mapData && Array.isArray(mapData) && mapData.length > 0) {
|
|
|
+ const flowerCount = Number(this.commodityBigCount) || 0
|
|
|
+ const flowerPrice = Number(this.commodityPrice) || 0
|
|
|
+ for (const rule of mapData) {
|
|
|
+ const ruleNum = Number(rule.num) || 0
|
|
|
+ const rulePrice = Number(rule.price) || 0
|
|
|
+ const ruleDistance = (Number(rule.distance) || 0) * 1000
|
|
|
+ if (flowerCount >= ruleNum && flowerPrice >= rulePrice && distanceInMeters <= ruleDistance) {
|
|
|
+ return true
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return false
|
|
|
+ },
|
|
|
+ showDeliveryPolicy() {
|
|
|
+ if (!this.displaySendCost) {
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ let hasPolicy = false
|
|
|
+ if (this.ghsInfo.hcFreeKm && Number(this.ghsInfo.hcFreeKm) > 0) {
|
|
|
+ hasPolicy = true
|
|
|
+ }
|
|
|
+ let mapData = this.ghsInfo.hcMap
|
|
|
+ if (mapData && typeof mapData === "string") {
|
|
|
+ try {
|
|
|
+ mapData = JSON.parse(mapData)
|
|
|
+ } catch (e) {}
|
|
|
+ }
|
|
|
+ if (mapData && Array.isArray(mapData) && mapData.length > 0) {
|
|
|
+ hasPolicy = true
|
|
|
+ }
|
|
|
+ return hasPolicy
|
|
|
+ },
|
|
|
+ showShMethodExtraFee() {
|
|
|
+ const method = this.currentShMethod
|
|
|
+ if (!method || !this.checkShMethodBelowMinimum(method)) {
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ const unMeet = Number(method.unMeet) || 0
|
|
|
+ const fee = Number(method.unMeetFee) || 0
|
|
|
+ return (unMeet === 0 || unMeet === 2) && fee > 0
|
|
|
+ },
|
|
|
+ shMethodExtraFeeLabel() {
|
|
|
+ const method = this.currentShMethod
|
|
|
+ if (!method) {
|
|
|
+ return "包装费"
|
|
|
+ }
|
|
|
+ return Number(method.unMeet) === 2 ? "包装费" : "运费"
|
|
|
+ },
|
|
|
+ shMethodExtraFeeAmount() {
|
|
|
+ if (!this.showShMethodExtraFee) {
|
|
|
+ return 0
|
|
|
+ }
|
|
|
+ const method = this.currentShMethod
|
|
|
+ return parseFloat(Number(method && method.unMeetFee) || 0)
|
|
|
+ },
|
|
|
+ shMethodUnMeetWarningText() {
|
|
|
+ const method = this.currentShMethod
|
|
|
+ if (!method) {
|
|
|
+ return ""
|
|
|
+ }
|
|
|
+ const tips = []
|
|
|
+ const minAmount = Number(method.minAmount) || 0
|
|
|
+ const minNum = Number(method.minNum) || 0
|
|
|
+ if (minAmount > 0) {
|
|
|
+ tips.push("不满" + minAmount + "元")
|
|
|
+ }
|
|
|
+ if (minNum > 0) {
|
|
|
+ tips.push("不满" + minNum + "扎")
|
|
|
+ }
|
|
|
+ const conditionText = tips.length > 0 ? tips.join("且") : "未达最低消费"
|
|
|
+ return "当天订单" + conditionText + ",加" + this.shMethodExtraFeeLabel + this.shMethodExtraFeeAmount + "元"
|
|
|
+ },
|
|
|
+ currentMethodExplains() {
|
|
|
+ const method = this.currentShMethod
|
|
|
+ if (!method || !Array.isArray(method.explains)) {
|
|
|
+ return []
|
|
|
+ }
|
|
|
+ return method.explains
|
|
|
+ .filter(exp => exp && exp.explain)
|
|
|
+ .sort((a, b) => Number(a.sort) - Number(b.sort))
|
|
|
+ },
|
|
|
+ runnerFeeAmount() {
|
|
|
+ if (!this.displaySendCost || this.isFreeDelivery) {
|
|
|
+ return 0
|
|
|
+ }
|
|
|
+ return Number(this.localForm.sendCost) || 0
|
|
|
+ },
|
|
|
+ panelTotalPrice() {
|
|
|
+ let price = Number(this.commodityPrice) || 0
|
|
|
+ price += this.runnerFeeAmount
|
|
|
+ price += this.shMethodExtraFeeAmount
|
|
|
+ return parseFloat(price.toFixed(2))
|
|
|
+ }
|
|
|
+ },
|
|
|
+ watch: {
|
|
|
+ ghsId: {
|
|
|
+ immediate: true,
|
|
|
+ handler(val) {
|
|
|
+ if (val) {
|
|
|
+ this.loadPanelData(val)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ commodityPrice() {
|
|
|
+ this.emitPanelChange()
|
|
|
+ },
|
|
|
+ commodityBigCount() {
|
|
|
+ this.emitPanelChange()
|
|
|
+ },
|
|
|
+ remark() {
|
|
|
+ this.emitPanelChange()
|
|
|
+ },
|
|
|
+ sendTimeWant() {
|
|
|
+ this.emitPanelChange()
|
|
|
+ },
|
|
|
+ "localForm.wlName"() {
|
|
|
+ this.emitPanelChange()
|
|
|
+ }
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ /** 面板初始化:配送配置、物流列表、门店地址 */
|
|
|
+ loadPanelData(ghsId) {
|
|
|
+ getShMethod({ ghsId: ghsId }).then(res => {
|
|
|
+ if (res.code == 1) {
|
|
|
+ this.methodList = res.data && res.data.method ? res.data.method : []
|
|
|
+ if (this.visibleMethodList.length > 0) {
|
|
|
+ this.selectMethodByIndex(0)
|
|
|
+ } else {
|
|
|
+ this.selectedMethodIndex = -1
|
|
|
+ this.emitPanelChange()
|
|
|
+ }
|
|
|
+ }
|
|
|
+ })
|
|
|
+ getWlList({ id: ghsId }).then(res => {
|
|
|
+ if (res.code == 1) {
|
|
|
+ this.wlList = res.data.list ? res.data.list : []
|
|
|
+ }
|
|
|
+ })
|
|
|
+ this.loadShopInfo()
|
|
|
+ },
|
|
|
+ /** 页面 onShow 时刷新地址,并按需重拉跑腿报价 */
|
|
|
+ onPageShow() {
|
|
|
+ this.loadShopInfo(() => {
|
|
|
+ if (Number(this.localForm.sendType) === 2 && this.displaySendCost && this.validAddress) {
|
|
|
+ this.getDeliveryQuotes()
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ loadShopInfo(callback) {
|
|
|
+ currentShop().then(res => {
|
|
|
+ if (res.code == 1) {
|
|
|
+ this.shopInfo = res.data
|
|
|
+ this.validAddress = !this.$util.isEmpty(this.shopInfo.lat) &&
|
|
|
+ !this.$util.isEmpty(this.shopInfo.long) &&
|
|
|
+ !this.$util.isEmpty(this.shopInfo.address)
|
|
|
+ }
|
|
|
+ if (typeof callback === "function") {
|
|
|
+ callback()
|
|
|
+ }
|
|
|
+ this.emitPanelChange()
|
|
|
+ })
|
|
|
+ },
|
|
|
+ checkShMethodBelowMinimum(method) {
|
|
|
+ if (!method) {
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ const minAmount = Number(method.minAmount) || 0
|
|
|
+ const minNum = Number(method.minNum) || 0
|
|
|
+ if (minAmount <= 0 && minNum <= 0) {
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ const allPrice = Number(this.commodityPrice) || 0
|
|
|
+ const bigLength = Number(this.commodityBigCount) || 0
|
|
|
+ return (minAmount > 0 && allPrice < minAmount) || (minNum > 0 && bigLength < minNum)
|
|
|
+ },
|
|
|
+ /** 按列表下标切换配送方式,并同步 sendType 供下单与条件展示 */
|
|
|
+ selectMethodByIndex(index) {
|
|
|
+ const list = this.visibleMethodList
|
|
|
+ if (!list[index]) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ this.selectedMethodIndex = index
|
|
|
+ const sendType = Number(list[index].style)
|
|
|
+ this.localForm.sendType = sendType
|
|
|
+ if (sendType === 2) {
|
|
|
+ if (this.displaySendCost && Number(this.ghsInfo.openIntraCity) === 1 && this.validAddress) {
|
|
|
+ this.getDeliveryQuotes()
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ this.deliveryQuotes = []
|
|
|
+ this.selectedDeliveryIndex = -1
|
|
|
+ this.selectedDeliveryData = null
|
|
|
+ this.localForm.sendCost = 0
|
|
|
+ this.showDistance = 0
|
|
|
+ }
|
|
|
+ this.syncPackCostByMethod()
|
|
|
+ this.emitPanelChange()
|
|
|
+ },
|
|
|
+ syncPackCostByMethod() {
|
|
|
+ const method = this.currentShMethod
|
|
|
+ if (method && this.checkShMethodBelowMinimum(method)) {
|
|
|
+ const unMeet = Number(method.unMeet) || 0
|
|
|
+ const fee = parseFloat(Number(method.unMeetFee) || 0)
|
|
|
+ if ((unMeet === 0 || unMeet === 2) && fee > 0) {
|
|
|
+ this.localForm.packCost = fee
|
|
|
+ return
|
|
|
+ }
|
|
|
+ }
|
|
|
+ this.localForm.packCost = 0
|
|
|
+ },
|
|
|
+ changeWlFn(e) {
|
|
|
+ this.wlSelData = this.wlList[e.detail.value]
|
|
|
+ this.localForm.wlId = this.wlSelData.id
|
|
|
+ this.localForm.wlName = this.wlSelData.name
|
|
|
+ this.emitPanelChange()
|
|
|
+ },
|
|
|
+ getDeliveryQuotes() {
|
|
|
+ this.deliveryQuotes = []
|
|
|
+ this.selectedDeliveryIndex = -1
|
|
|
+ this.selectedDeliveryData = null
|
|
|
+ allDeliveryQuotes({
|
|
|
+ ghsId: this.ghsId,
|
|
|
+ totalPrice: this.commodityPrice,
|
|
|
+ weight: this.commodityWeight,
|
|
|
+ selectList: this.selectList,
|
|
|
+ weight: 1,
|
|
|
+ remark: ""
|
|
|
+ }).then(res => {
|
|
|
+ if (res.code === 1 && res.data && res.data.deliveryList) {
|
|
|
+ this.deliveryQuotes = res.data.deliveryList
|
|
|
+ .filter(item => item.isAble !== false)
|
|
|
+ .map(item => {
|
|
|
+ const price = item.price ? (item.price / 100).toFixed(1) : "0.0"
|
|
|
+ let displayName = item.name
|
|
|
+ let bracketContent = ""
|
|
|
+ if (displayName && displayName.includes("(")) {
|
|
|
+ bracketContent = displayName.split("(")[1].replace(")", "")
|
|
|
+ displayName = displayName.split("(")[0].trim()
|
|
|
+ }
|
|
|
+ if (item.en_name == "didi" && bracketContent != "") {
|
|
|
+ item.type = bracketContent
|
|
|
+ }
|
|
|
+ return {
|
|
|
+ ...item,
|
|
|
+ displayName: displayName,
|
|
|
+ priceText: price,
|
|
|
+ priceNumber: parseFloat(price),
|
|
|
+ bracketContent: bracketContent
|
|
|
+ }
|
|
|
+ })
|
|
|
+ const firstAvailableIndex = this.deliveryQuotes.findIndex(item => item.isAble)
|
|
|
+ if (firstAvailableIndex !== -1) {
|
|
|
+ this.selectDelivery(this.deliveryQuotes[firstAvailableIndex], firstAvailableIndex)
|
|
|
+ } else {
|
|
|
+ this.emitPanelChange()
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ uni.showToast({ title: "暂无跑腿可用", icon: "none" })
|
|
|
+ }
|
|
|
+ }).catch(() => {
|
|
|
+ uni.showToast({ title: "没有获取到跑腿费用", icon: "none" })
|
|
|
+ })
|
|
|
+ },
|
|
|
+ selectDelivery(item, index) {
|
|
|
+ this.selectedDeliveryIndex = index
|
|
|
+ this.selectedDeliveryData = item
|
|
|
+ this.localForm.sendCost = item.priceNumber
|
|
|
+ this.showDistance = item.distance || 0
|
|
|
+ this.emitPanelChange()
|
|
|
+ },
|
|
|
+ modifyAddress() {
|
|
|
+ const shopId = this.getLoginInfo.admin && this.getLoginInfo.admin.currentShopId
|
|
|
+ this.$util.pageTo({ url: "/admin/shop/add?id=" + shopId })
|
|
|
+ },
|
|
|
+ showDeliveryPolicyModal() {
|
|
|
+ this.deliveryPolicyList = []
|
|
|
+ if (this.ghsInfo.hcFreeKm && Number(this.ghsInfo.hcFreeKm) > 0) {
|
|
|
+ this.deliveryPolicyList.push(Number(this.ghsInfo.hcFreeKm) + "公里内免费配送")
|
|
|
+ }
|
|
|
+ let mapData = this.ghsInfo.hcMap
|
|
|
+ if (mapData && typeof mapData === "string") {
|
|
|
+ try {
|
|
|
+ mapData = JSON.parse(mapData)
|
|
|
+ } catch (e) {
|
|
|
+ mapData = []
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (mapData && Array.isArray(mapData) && mapData.length > 0) {
|
|
|
+ mapData.forEach(rule => {
|
|
|
+ const num = Number(rule.num) || 0
|
|
|
+ const price = Number(rule.price) || 0
|
|
|
+ const distance = Number(rule.distance) || 0
|
|
|
+ this.deliveryPolicyList.push("满" + num + "扎" + price + "元," + distance + "公里内免费配送")
|
|
|
+ })
|
|
|
+ }
|
|
|
+ if (this.deliveryPolicyList.length === 0) {
|
|
|
+ uni.showToast({ title: "暂无详细配送政策", icon: "none" })
|
|
|
+ return
|
|
|
+ }
|
|
|
+ this.$refs.deliveryPolicyPopup.open()
|
|
|
+ },
|
|
|
+ closeDeliveryPolicy() {
|
|
|
+ this.$refs.deliveryPolicyPopup.close()
|
|
|
+ },
|
|
|
+ bindDateChange(e) {
|
|
|
+ this.sendTimeWant = e.detail.value
|
|
|
+ },
|
|
|
+ /** 提交前校验,失败时提示并返回 false */
|
|
|
+ validateBeforeSubmit() {
|
|
|
+ if (Number(this.localForm.sendType) === 3 && this.$util.isEmpty(this.localForm.wlName)) {
|
|
|
+ this.$msg("请填选物流")
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ const method = this.currentShMethod
|
|
|
+ if (method && Number(method.unMeet) === 1 && this.checkShMethodBelowMinimum(method)) {
|
|
|
+ this.$msg("未达到最低消费,不能下单")
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ return true
|
|
|
+ },
|
|
|
+ /** 向父页面同步面板状态 */
|
|
|
+ emitPanelChange() {
|
|
|
+ this.syncPackCostByMethod()
|
|
|
+ this.$emit("change", {
|
|
|
+ sendType: this.localForm.sendType,
|
|
|
+ wlName: this.localForm.wlName,
|
|
|
+ wlId: this.localForm.wlId,
|
|
|
+ sendCost: this.localForm.sendCost,
|
|
|
+ packCost: this.localForm.packCost,
|
|
|
+ sendTimeWant: this.sendTimeWant,
|
|
|
+ remark: this.remark,
|
|
|
+ showDistance: this.showDistance,
|
|
|
+ selectedDeliveryData: this.selectedDeliveryData,
|
|
|
+ totalPrice: this.panelTotalPrice,
|
|
|
+ runnerFeeAmount: this.runnerFeeAmount,
|
|
|
+ extraFeeAmount: this.shMethodExtraFeeAmount
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="scss" scoped>
|
|
|
+.delivery-quotes-container {
|
|
|
+ width: 100%;
|
|
|
+ margin-top: 20upx;
|
|
|
+}
|
|
|
+
|
|
|
+.delivery-quotes-grid {
|
|
|
+ display: flex;
|
|
|
+ flex-wrap: wrap;
|
|
|
+ padding: 0;
|
|
|
+ width: 100%;
|
|
|
+}
|
|
|
+
|
|
|
+.delivery-quote-item {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ flex: 0 0 calc(33% - 7upx);
|
|
|
+ width: calc(33% - 7upx);
|
|
|
+ min-height: 140upx;
|
|
|
+ padding: 16upx 10upx;
|
|
|
+ margin-right: 10upx;
|
|
|
+ margin-bottom: 10upx;
|
|
|
+ background: #FFFFFF;
|
|
|
+ border: 2upx solid #DDDDDD;
|
|
|
+ border-radius: 8upx;
|
|
|
+ box-sizing: border-box;
|
|
|
+
|
|
|
+ &:nth-child(3n) {
|
|
|
+ margin-right: 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ &.fixed-width {
|
|
|
+ flex: 0 0 220rpx;
|
|
|
+ width: 220rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .platform-name {
|
|
|
+ font-size: 26upx;
|
|
|
+ color: #333;
|
|
|
+ font-weight: bold;
|
|
|
+ margin-bottom: 8upx;
|
|
|
+ text-align: center;
|
|
|
+ line-height: 1.3;
|
|
|
+ max-width: 100%;
|
|
|
+ overflow: hidden;
|
|
|
+ text-overflow: ellipsis;
|
|
|
+ display: -webkit-box;
|
|
|
+ -webkit-line-clamp: 2;
|
|
|
+ line-clamp: 2;
|
|
|
+ -webkit-box-orient: vertical;
|
|
|
+ word-break: break-all;
|
|
|
+ }
|
|
|
+
|
|
|
+ .platform-price {
|
|
|
+ font-size: 30upx;
|
|
|
+ color: #333;
|
|
|
+ font-weight: bold;
|
|
|
+ margin-bottom: 4upx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .platform-type {
|
|
|
+ font-size: 20upx;
|
|
|
+ color: #868686;
|
|
|
+ margin-top: 4upx;
|
|
|
+ text-align: center;
|
|
|
+ line-height: 1.3;
|
|
|
+ max-width: 100%;
|
|
|
+ overflow: hidden;
|
|
|
+ text-overflow: ellipsis;
|
|
|
+ display: -webkit-box;
|
|
|
+ -webkit-line-clamp: 2;
|
|
|
+ line-clamp: 2;
|
|
|
+ -webkit-box-orient: vertical;
|
|
|
+ word-break: break-all;
|
|
|
+ }
|
|
|
+
|
|
|
+ &.active {
|
|
|
+ background: #09C567;
|
|
|
+ border-color: #09C567;
|
|
|
+
|
|
|
+ .platform-name,
|
|
|
+ .platform-price {
|
|
|
+ color: #FFFFFF;
|
|
|
+ }
|
|
|
+
|
|
|
+ .platform-type {
|
|
|
+ color: rgba(255, 255, 255, 0.85);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ &.disabled {
|
|
|
+ opacity: 0.5;
|
|
|
+ background: #F5F5F5;
|
|
|
+
|
|
|
+ .platform-name,
|
|
|
+ .platform-price,
|
|
|
+ .platform-type {
|
|
|
+ color: #CCCCCC;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.delivery-price-normal {
|
|
|
+ color: #3385FF;
|
|
|
+}
|
|
|
+
|
|
|
+.delivery-price-free {
|
|
|
+ color: #999;
|
|
|
+ text-decoration: line-through;
|
|
|
+}
|
|
|
+
|
|
|
+.free-delivery-tag {
|
|
|
+ color: #3385FF;
|
|
|
+ margin-left: 5upx;
|
|
|
+}
|
|
|
+
|
|
|
+.delivery-policy-link {
|
|
|
+ color: rgb(201, 52, 52);
|
|
|
+ font-size: 30upx;
|
|
|
+ margin-left: 30upx;
|
|
|
+ font-weight: bold;
|
|
|
+ text-decoration: underline;
|
|
|
+}
|
|
|
+
|
|
|
+.policy-popup-content {
|
|
|
+ width: 600upx;
|
|
|
+ background-color: #fff;
|
|
|
+ border-radius: 20upx;
|
|
|
+ padding: 30upx;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ align-items: center;
|
|
|
+}
|
|
|
+.policy-title {
|
|
|
+ font-size: 34upx;
|
|
|
+ font-weight: bold;
|
|
|
+ color: #333;
|
|
|
+ margin-bottom: 30upx;
|
|
|
+}
|
|
|
+.policy-scroll {
|
|
|
+ width: 100%;
|
|
|
+ max-height: 50vh;
|
|
|
+ margin-bottom: 30upx;
|
|
|
+}
|
|
|
+.policy-list {
|
|
|
+ width: 100%;
|
|
|
+}
|
|
|
+.policy-item {
|
|
|
+ font-size: 30upx;
|
|
|
+ color: #666;
|
|
|
+ margin-bottom: 20upx;
|
|
|
+ text-align: left;
|
|
|
+ line-height: 1.5;
|
|
|
+ display: list-item;
|
|
|
+ list-style-type: disc;
|
|
|
+ margin-left: 40upx;
|
|
|
+}
|
|
|
+.policy-btn {
|
|
|
+ width: 50%;
|
|
|
+ height: 80upx;
|
|
|
+ line-height: 80upx;
|
|
|
+ text-align: center;
|
|
|
+ background-color: #3385ff;
|
|
|
+ color: #fff;
|
|
|
+ font-size: 32upx;
|
|
|
+ border-radius: 40upx;
|
|
|
+}
|
|
|
+</style>
|
|
|
+
|
|
|
+<style lang="scss">
|
|
|
+/* 36523 配送方式按钮:二字 60upx,三到四字 32upx(与 affirmGhs.vue 一致) */
|
|
|
+.sh-method-btn {
|
|
|
+ width: 115upx;
|
|
|
+ height: 100upx;
|
|
|
+ margin-right: 15upx;
|
|
|
+}
|
|
|
+.sh-method-btn:last-child {
|
|
|
+ margin-right: 0;
|
|
|
+}
|
|
|
+.sh-method-btn--short {
|
|
|
+ line-height: 60upx;
|
|
|
+}
|
|
|
+.sh-method-btn--long {
|
|
|
+ line-height: 32upx;
|
|
|
+}
|
|
|
+</style>
|