Untitled
unknown
javascript
a year ago
37 kB
9
Indexable
<template> <div> <v-main> <v-container class="grey lighten-4"> <v-layout justify-center align-center> <v-flex> <div> <div class="color-option"> <v-layout wrap> <v-flex xs12 sm12 md12 d-flex> <v-select v-model="status_id" :items="statuses" item-text="name" item-value="id" label="Status" solo ></v-select> </v-flex> </v-layout> <v-menu ref="menu1" v-model="menu1" :close-on-content-click="false" transition="scale-transition" offset-y max-width="290px" min-width="290px" > <template v-slot:activator="{ on }"> <v-text-field v-model="datee" label="Fecha de inicio" persistent-hint prepend-icon="event" v-on="on" ></v-text-field> </template> <v-date-picker v-model="datee" no-title @input="menu1 = false"></v-date-picker> </v-menu> <v-spacer></v-spacer> <div style="padding-bottom: 1rem;" class="mt-2"> <order-statistic :total-pending="catering.totals" :total-delivered="catering.delivered" :date-delivered-list="catering.datesDeliveredCount" :dates-pending-list="catering.datesPendingCount" /> </div> </div> <v-toolbar color="#27884d" dark tabs> <template> <v-tabs show-arrows v-model="tabs" slider-color="white" > <v-tabs-slider color="teal lighten-3"></v-tabs-slider> <v-tab v-for="(n, index) in catering.caterings" :key="`${index}${n.name}`" :href="'#tab-' + index" @click="chooseCatering(n)" >{{ n.name }} <span title="Pedidos Pendientes">({{ n.pending }})</span> </v-tab> </v-tabs> </template> </v-toolbar> <!-- <v-tabs-items v-model="tabs"> --> </div> </v-flex> </v-layout> </v-container> <template> <v-app> <v-main style="padding: 0px 0px 0px"> <div v-for="(item, indice) in rutas" :key="`${indice}${item.name}`" style="padding: 5px" > <div class="container-fluid"> <order-statistic-by-route :total-pending="pendingData.pending" :total-delivered="pendingData.done" :date-pending-list="datesPendingCountByCatering" :date-delivered-list="datesDeliveredCountByCatering" :total-not-answer="notAnswer" :total-donated="plateDonated" :total-change-address="changeDirection" :item="item" :route-status-name="item.route_status_name" /> </div> <v-stepper v-model="stepper"> <v-stepper-header v-if="item.items && item.items.length > 0"> <div v-for="(step, index) in item.items" :key="index"> <v-container v-if="step !== undefined"> <v-layout row wrap style="border-radius: 12px" v-if="step !== undefined" :style="[step.is_multiple === 1 && step.color !== undefined ? { 'background-color' : step.color } : {} ]" > <v-flex xs2 sm2 md2 v-if="step !== undefined"> <v-stepper-step :color="chooseColor(step.status)" :complete-icon="'check'" :step="index + 1" :complete="parseStatus(step.status)" :rules="[() => step.status === 2 ? false : true]" @click="showDetails(step,item.items[index+1])" > <span style="font-size: 10px;}" :style="[getStyleSchedule(step)]" >{{ step.start | moment }} - {{ step.finish | moment }}</span> <span v-if="step.at" :style="[step.is_multiple === 1 && step.color !== undefined ? { 'color' : 'white' } : {}]" style="color: green" >{{ parseTime(step.at) }}</span> <span v-if="step.status == 4" :style="[step.is_multiple === 1 && step.color !== undefined ? { 'color' : 'white' } : {}]" style="color: red" >-{{ parseLastTime(step.last_time) }}</span> <h3 v-if="step !== undefined" :style="[step.is_multiple === 1 && step.color !== undefined ? { 'color' : 'white' } : {} ]" > {{ step.client }} <strong>({{ chooseStatus(step.status) }})</strong> </h3> <order-customer-label :is-daily="step.is_daily" :is-first="step.is_first" :is-especial="step.is_especial" :is-influencer="step.is_influencer" /> </v-stepper-step> </v-flex> </v-layout> </v-container> </div> </v-stepper-header> </v-stepper> </div> </v-main> </v-app> </template> <v-dialog @keydown.esc="loadModal = false" v-model="loadModal" persistent max-width="1000px"> <v-card> <v-card-text> <table class="meal_order"> <tr> <th>CLIENTE</th> <td> <router-link :to="'/client/'+dealerData.customer_id"> <span style="padding: 15px;margin-right: 28rem;" class="subheading text-xs-left" >{{ dealerData.client }}</span> </router-link> <v-btn color="primary" v-if="dealerData.photo_url" @click="showImg(dealerData.photo_url)" >VER FOTO </v-btn> <v-btn color="primary" v-if="dealerData.evidence_images.length > 0" @click="dialogImg = true;" >VER FOTO </v-btn> </td> </tr> <tr> <th>ENTREGA ESTIMADA</th> <td> <h4 style="padding: 15px;margin-right: 28rem;" class="green-text"> {{ dealerData.time }} </h4> </td> </tr> <tr> <th>TELEFONO</th> <td> <span style="padding: 15px;" class="subheading text-xs-left">{{ dealerData.telefono }}</span> </td> </tr> <tr> <th>DIRECCION</th> <td> <span style="padding: 15px;" class="subheading text-xs-left">{{ dealerData.option_label ? dealerData.option_label + ': ' : ' ' }}{{ dealerData.address }}</span> </td> </tr> <tr> <th>ESPECIFICACIONES</th> <td> <span style="padding: 15px;" class="subheading text-xs-left">{{ dealerData.indications }}</span> </td> </tr> <tr> <th>MENSAJE</th> <td> <span style="padding: 15px;" class="subheading text-xs-left">{{ dealerData.message }}</span> </td> </tr> </table> <br> <table class="meal_order"> <thead> <tr> <th>TIPO</th> <th>NOMBRE</th> <th>NOTA</th> </tr> </thead> <tbody> <tr v-for="item in itemOrder"> <td>{{ item.type.toUpperCase() }} | {{ item.calories }} KCAL</td> <td>{{ item.name.toUpperCase() }}</td> <td>{{ item.note }}</td> </tr> </tbody> </table> </v-card-text> <v-card-actions style="padding-bottom: 1rem"> <v-btn color="blue darken-1" @click="loadModal = false">CERRAR</v-btn> <v-spacer></v-spacer> <v-btn color="indigo" dark @click="showTardies()">VER TARDANZAS</v-btn> <v-btn color="teal" dark @click="showClaimsCustomer()">VER RECLAMOS</v-btn> <!-- <v-btn color="danger" dark @click="markAsComplete(5)">CLIENTE NO CONTESTO</v-btn>--> <!-- <v-btn color="blue" dark @click="markAsComplete(6)">CAMBIO DE DIRECCION</v-btn>--> <v-btn color="primary" @click="markAsComplete(1)">MARCAR COMO ENTREGADO</v-btn> <v-speed-dial v-model="fab" :top="top" :bottom="bottom" :right="right" :left="left" :direction="direction" :open-on-hover="hover" :transition="transition" > <template v-slot:activator> <v-btn v-model="fab" color="blue darken-2" dark fab > <v-icon v-if="fab">person</v-icon> <v-icon v-else>mdi-plus</v-icon> </v-btn> </template> <template> <v-tooltip left> <template v-slot:activator="{ on }"> <v-btn fab v-on="on" dark @click="sendDelayNotification(dealerData.customer_id,itemOrder)" small > <v-icon>thumb_down_alt</v-icon> </v-btn> </template> <span> AVISAR PEDIDO CON RETRASO </span> </v-tooltip> </template> <template v-for="status in trackingStatuses"> <v-tooltip left> <template v-slot:activator="{ on }"> <v-btn fab v-on="on" dark @click="markAsComplete(status.id)" small :color="status.color" > <v-icon>{{ status.icon }}</v-icon> </v-btn> </template> <span>{{ status.name }}</span> </v-tooltip> </template> </v-speed-dial> </v-card-actions> </v-card> </v-dialog> <v-dialog @keydown.esc="dialogImg = false" v-model="dialogImg" persistent max-width="800px"> <v-card> <v-card-text> <v-container grid-list-md> <v-layout wrap> <v-flex xs12> <v-img v-if="img_url" :src="img_url" aspect-ratio="1" class="grey lighten-2"></v-img> </v-flex> </v-layout> </v-container> <v-row> <v-carousel cols="12" md="12" height="auto" > <v-carousel-item v-for="(image,index) in dealerData.evidence_images" :key="index" > <v-img v-if="image" :src="image" class="grey lighten-2"></v-img> <v-sheet height="100%" tile > <v-row class="fill-height" align="center" justify="center" > <div class="text-h2"> Slide {{ i + 1 }} </div> </v-row> </v-sheet> </v-carousel-item> </v-carousel> </v-row> </v-card-text> <v-card-actions> <v-btn color="blue darken-1" @click="dialogImg = false">Cerrar</v-btn> </v-card-actions> </v-card> </v-dialog> <!-- Lista de reclamos --> <v-dialog @keydown.esc="loadModalClaims = false" v-model="loadModalClaims" persistent max-width="1200px" > <v-card> <v-container grid-list-md> <v-data-table :headers="headersClaims" :items="reclamos" no-data-text="NO TIENE RECLAMOS AUN" > <template v-slot:item="props"> <tr> <td> <v-btn v-if="props.item.photo_url" color="primary" @click="showImg(props.item.photo_url)">FOTO </v-btn> <v-btn v-else color="pink">NO FOTO</v-btn> </td> <td class="text-xs-left">{{ props.item.level.toUpperCase() }}</td> <td class="text-xs-left green--text">{{ props.item.description }}</td> <td class="text-xs-left">{{ props.item.catering ? props.item.catering.toUpperCase() : 'NO TIENE' }} </td> <td class="text-xs-left">{{ props.item.discount_catering }}</td> <td class="text-xs-left">{{ props.item.dealer ? props.item.dealer.toUpperCase() : 'NO TIENE' }}</td> <td class="text-xs-left">{{ props.item.discount_dealer }}</td> <td class="text-xs-left">{{ props.item.discount_owner }}</td> <td class="text-xs-left">{{ props.item.date }}</td> <td class="text-xs-left">{{ props.item.user ? props.item.user.toUpperCase() : 'NO TIENE' }}</td> </tr> </template> </v-data-table> </v-container> <v-card-actions class="pb-3"> <v-btn color="blue darken-1" @click="loadModalClaims = false">CERRAR</v-btn> </v-card-actions> </v-card> </v-dialog> <!-- Lista de reclamos --> <v-dialog @keydown.esc="loadModalTardies = false" v-model="loadModalTardies" persistent max-width="1200px" > <v-card> <v-container grid-list-md> <v-data-table :headers="headersTardies" :items="tardies" no-data-text="NO TIENE TARDANZAS AUN" > <template v-slot:item="props"> <tr> <td class="text-xs-left">{{ props.item.date }}</td> <td class="text-xs-left">{{ props.item.must_delivered }}</td> <td class="text-xs-left">{{ props.item.delivered }}</td> <td class="text-xs-left red--text">{{ props.item.diff }}</td> </tr> </template> </v-data-table> </v-container> <v-card-actions class="pb-3"> <v-btn color="blue darken-1" @click="loadModalTardies = false">CERRAR</v-btn> </v-card-actions> </v-card> </v-dialog> </v-main> </div> </template> <script> import Menu from "../../components/Menu.vue"; import Header from "../../components/Header"; import moment from "moment"; import axios from "axios"; import firestore from '../../plugins/firebase' import OrderStatistic from "./components/OrderStatistic"; import OrderStatisticByRoute from "./components/OrderStatisticByRoute"; import OrderCustomerLabel from "./components/OrderCustomerLabel"; import AuthFirebase from "../../mixins/AuthFirebase"; export default { components: { OrderCustomerLabel, OrderStatisticByRoute, OrderStatistic, "app-header": Header, "app-menu": Menu }, mixins: [AuthFirebase], created() { this.getVars() this.$store.dispatch("GET_TRACKS", { catering_id: this.catering_selected, status_id: this.status_id, datee: this.datee }); }, mounted() { window.Echo.channel("private-newOrder") .listen(".order-check", e => { console.log(e) this.$store.commit("UPDATE_ITEM_TRACK", e); }) .listen(".route-check", e => { this.$store.commit("UPDATE_ROUTE_CONFIRM", e); }) setInterval(this.updateClock, 100); this.getNotificationStatus(); }, computed: { getStyleSchedule() { return (step) => { let color = { "font-weight": "bold", "border-radius": "10px", "padding": "5px" } if (step.start === "10:00:00" && step.finish === "12:30:00") { color["background-color"] = 'green !important' } else if (step.start === "10:00:00" && step.finish === "13:30:00") { color["background-color"] = 'yellow !important' } else if (step.start === "12:00:00" && step.finish === "13:30:00") { color["background-color"] = 'orange !important' } if (step.is_multiple === 1 && step.color !== undefined) { color["color"] = 'black' } return color } }, headersTardies() { return this.$store.getters.getHeadersTardies; }, headersClaims() { return this.$store.getters.getHeadersClaims; }, pendingData() { return this.$store.getters.getPending; }, permisos() { return this.$store.getters.getPermissions; }, tracks() { return this.$store.getters.getTracks; }, catering() { return this.$store.getters.getCatering; }, loading() { return this.$store.getters.getLoading; }, rutas() { return this.tracks[this.index] ? this.tracks[this.index].rutas : []; } }, data: () => ({ vars: {}, newMethod: true, orderData: { dealer: { id: null, lat: null, lng: null, }, order: {}, route: [] }, direction: 'top', fab: false, fling: false, hover: false, top: false, right: true, bottom: true, left: false, transition: 'slide-y-reverse-transition', loadModalTardies: false, tardies: [], loadModalClaims: false, reclamos: [], caterings: [], catering_selected: null, subscription: null, serviceWorkerRegistation: null, time: "", status_id: null, datee: new Date().toISOString().substr(0, 10), menu1: false, statuses: [ {id: null, name: "TODOS"}, {id: 0, name: "PENDIENTES"}, {id: 1, name: "TERMINADOS"} ], rules: { required: value => !!value || "Campo obligatorio." }, dialogImg: false, img_url: null, drawer: false, stepper: 0, index: 0, tabs: null, dealerData: { evidence_images: [] }, loadModal: false, itemOrder: [], totals: 0, delivered: 0, changeDirection: 0, plateDonated: 0, notAnswer: 0, trackingStatuses: [ {id: 7, name: "CLIENTE DONÓ SU PEDIDO", icon: 'thumb_up_alt', color: 'danger'}, {id: 6, name: "CAMBIÓ DE DIRECCIÓN", icon: 'map', color: 'green'}, {id: 5, name: "CLIENTE NO CONTESTO", icon: 'phone_disabled', color: 'info'}, {id: 11, name: "RETORNAR A DOMICILIO", icon: 'house', color: 'indigo'}, ], datesPendingCountByCatering: [], datesDeliveredCountByCatering: [] }), props: {}, watch: { catering_selected: { handler(val) { if (val !== null) { this.$store.dispatch("GET_TRACKS", { catering_id: val, datee: this.datee }); } }, deep: true }, status_id: { handler(val) { this.$store.dispatch("GET_TRACKS", { catering_id: this.catering_selected, status_id: val }); }, deep: true }, datee: { handler(val) { this.$store.dispatch("GET_TRACKS", { catering_id: this.catering_selected, status_id: this.status_id, datee: val }); }, deep: true } }, methods: { async sendDelayNotification(user_id, orders) { try { await axios.post("/delivery/delay-notification-wo", { user_id, order: this.orderData.order.id }) this.$store.commit("SET_SNACKBAR", { show: true, text: "Notificación enviada", color: "primary" }); this.loadModal = false; } catch (e) { // console.log(e) this.$store.commit("SET_SNACKBAR", { show: true, text: "No se pudo actualizar", color: "danger" }); } }, getVars() { axios .get('estimate_time_variables') .then(({data}) => { this.vars = data }) .catch(error => alert(error)) }, chooseCatering(cat) { this.catering_selected = cat.id; this.datesPendingCountByCatering = this.catering.caterings.find(e => e.id === cat.id).pendingOrdersByDates; this.datesDeliveredCountByCatering = this.catering.caterings.find(e => e.id === cat.id).deliveredOrdersByDates; this.getCountStatus() }, getCheckList() { axios .get("supervision/get/" + this.catering_selected) .then(response => { this.checklist = response.data; }) .catch(error => { //console.log(error); }); }, getCountStatus() { axios .get("/caterings/count/status", { params: { id: this.catering_selected, date: this.datee } }) .then(response => { this.changeDirection = response.data.changeDirection; this.plateDonated = response.data.plateDonated this.notAnswer = response.data.notAnswer }) .catch(error => { //console.log(error); }); }, updateMarker(id) { let routeData = this.$router.resolve({ name: "real_time_tracking", params: { dealer_id: id } }); window.open(routeData.href, "_blank"); }, async markAsComplete(status) { try { this.dealerData.status = status const response = await axios.post("/repartos/actualizar", this.dealerData) this.$store.commit("UPDATE_ITEM_BACK", response.data); this.$store.commit("SET_SNACKBAR", { show: true, text: "Actualizado con exito", color: "primary" }); this.loadModal = false; } catch (e) { //console.log(e) this.$store.commit("SET_SNACKBAR", { show: true, text: "No se pudo actualizar", color: "danger" }); } }, showTardies() { this.loadModalTardies = true; axios .get("tardies/" + this.dealerData.customer_id) .then(response => { this.tardies = response.data; }) .catch(err => { console.error(err); }); }, showClaimsCustomer() { this.loadModalClaims = true; axios .get("claims/" + this.dealerData.customer_id) .then(response => { this.reclamos = response.data; }) .catch(err => { console.error(err); }); }, getNotificationStatus() { if ( "Notification" in window && "serviceWorker" in navigator && Notification.permission !== "denied" && Notification.permission !== "granted" ) { Notification.requestPermission().then(result => { if (result === "granted") { this.createSubscription() .then(val => { return axios.post(`subscription/backend/store`, { subscription: val }); }) .then(response => { alert("Ahora podras recibir notificaciones ."); }); } }); } }, createSubscription() { if (this.serviceWorkerRegistation === null) { return navigator.serviceWorker.ready.then(swreg => { this.serviceWorkerRegistation = swreg; return this.subscribe(this.serviceWorkerRegistation); }); } else { return this.subscribe(this.serviceWorkerRegistation); } }, subscribe(swreg) { const vapidPublicKey = process.env.VUE_APP_VAPID_PUBLIC_KEY; const convertedVapidPublicKey = this.urlBase64ToUint8Array( vapidPublicKey ); return swreg.pushManager.subscribe({ userVisibleOnly: true, applicationServerKey: convertedVapidPublicKey }); }, urlBase64ToUint8Array(base64String) { const padding = "=".repeat((4 - (base64String.length % 4)) % 4); const base64 = (base64String + padding) .replace(/\-/g, "+") .replace(/_/g, "/"); const rawData = window.atob(base64); let outputArray = new Uint8Array(rawData.length); for (let i = 0; i < rawData.length; ++i) { outputArray[i] = rawData.charCodeAt(i); } return outputArray; }, parseTime(date) { return moment(date).format("HH:mm"); }, parseLastTime(last_time) { if (last_time != undefined) { return moment(this.time.diff(moment(last_time))).format("mm:ss"); } }, updateClock: function () { let now = new Date(); this.time = moment(now, "YYYY.MM.DD HH:mm"); }, chooseColor(status) { if (status == 1) { return "success"; } else if (status == 7) { return "success"; } else if (status === 2) { return "red"; } else if (status === 3) { return "purple"; } else if (status === 4) { return "yellow"; } return "gray"; }, chooseStatus(status) { let statusName = "PENDIENTE" switch (status) { case 1: statusName = "ENTREGADO"; break case 2: statusName = "PROBLEMA"; break case 3: statusName = "CAMINO"; break case 4: statusName = "LLEGO"; break case 5: statusName = "NO CONTESTO"; break case 6: statusName = "CAMBIO DE DIRECCION"; break case 7: statusName = "DONADO"; break case 11: statusName = "RETORNAR A DOMICILIO"; break default: statusName = "PENDIENTE"; } return statusName; }, showImg(url) { this.img_url = process.env.VUE_APP__API + "v1/photo/order/" + url; this.dialogImg = true; }, parseStatus(status) { if (status === 0) { return false; } else if (status === 2) { return false; } else if (status === 7) { return true; } else if (status === 1) { return true; } }, deg2rad(deg) { return deg * (Math.PI / 180); }, getDistance(lon1, lat1, lat2, lon2) { let R = 6371; // Radius of the earth in km let dLat = this.deg2rad(lat2 - lat1); // this.deg2rad below let dLon = this.deg2rad(lon2 - lon1); let a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(this.deg2rad(lat1)) * Math.cos(this.deg2rad(lat2)) * Math.sin(dLon / 2) * Math.sin(dLon / 2); let c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); let d = R * c; // Distance in km return d; }, showDetails(data, next) { data.evidence_images = [] this.dealerData = data axios.get("order/" + data.id).then(response => { this.itemOrder = response.data.items this.dealerData.evidence_images = response.data.client.evidence_images }); axios.get("realtime/estimate/time/" + data.id).then(response => { let rep = response.data; this.orderData.dealer.id = rep.dealer_id this.orderData.order = rep.order this.orderData.route = rep.route this.orderData.time = rep.time if (this.orderData.order.status_id === 9 || this.orderData.order.status_id === 3) { this.loadDataFirestore() } else { this.dealerData.time = this.orderData.order.time } this.loadModal = true }); }, loadDataFirestore() { var vm = this let auth = this.validateAuth(vm.orderData.dealer.id) if (auth) { firestore .collection('coords') .where('dealer_id', '==', vm.orderData.dealer.id) .orderBy('timestamp', 'desc') .limit(1) .get().then(function (prevSnapshot) { prevSnapshot.forEach(doc => { if (doc.data()) { vm.orderData.dealer.lat = doc.data().lat vm.orderData.dealer.lng = doc.data().lng vm.calculateRouteTime(vm) if (vm.orderData.order.status_id === 9) { vm.calculateRouteTime(vm) } else { vm.calculateTime(vm) } } }) }) } }, calculateTime(vm) { if (this.newMethod) { let origin = {lat: this.orderData.dealer.lat, lng: this.orderData.dealer.lng} let destination = { lat: this.orderData.order.latitude, lng: this.orderData.order.longitude } let distance = this.getDistance( origin.lat, origin.lng, destination.lat, destination.lng ) let te = parseInt(this.vars.te) let tk = parseInt(this.vars.tk) let delayTime = 5 if (distance < 0.5) { delayTime = 0 te = 0 } let duration = parseInt(distance * tk + te + delayTime) vm.dealerData.time = 'En ' + duration + ' min' vm.loadModal = true; } else { this.$gmapApiPromiseLazy().then(() => { let latLngA = new google.maps.LatLng(this.orderData.dealer.lat, this.orderData.dealer.lng) let latLngB = new google.maps.LatLng( this.orderData.order.longitude, this.orderData.order.latitude ) var distanceService = new google.maps.DistanceMatrixService() distanceService.getDistanceMatrix( { origins: [latLngA], destinations: [latLngB], travelMode: 'DRIVING', avoidHighways: true, avoidTolls: false, drivingOptions: { departureTime: new Date(Date.now()), // for the time N milliseconds from now. trafficModel: 'pessimistic' } }, function (response, status) { if (status !== google.maps.DistanceMatrixStatus.OK) { console.log('Error:', status) } else { vm.dealerData.time = 'En ' + response.rows[0].elements[0].duration.text vm.loadModal = true; } } ) }) } }, calculateRouteTime(vm) { if (this.newMethod) { let origin = {lat: this.orderData.dealer.lat, lng: this.orderData.dealer.lng} let destination = { lat: this.orderData.order.latitude, lng: this.orderData.order.longitude } let distance = this.getDistance( origin.lat, origin.lng, destination.lat, destination.lng ) let specialDelivery = vm.orderData.route const te = parseInt(this.vars.te) const tk = parseInt(this.vars.tk) let pointsValue = 0 if (specialDelivery.length > 0) { pointsValue = specialDelivery.length * te + specialDelivery.length * tk } let duration = distance * tk + te + pointsValue let delayTime = vm.orderData.time let range = moment() .add(duration, 'minutes') .add(delayTime, 'minutes') .format('hh:mm A') vm.dealerData.time = range vm.loadModal = true; } else { this.$gmapApiPromiseLazy().then(() => { let origin = new google.maps.LatLng(this.orderData.dealer.lat, this.orderData.dealer.lng) let destination = new google.maps.LatLng( this.orderData.order.longitude, this.orderData.order.latitude ) let points = [] let specialDelivery = vm.orderData.route specialDelivery.map(item => { let point = new google.maps.LatLng(item.longitude, item.latitude) points.push({location: point, stopover: true}) }) var directionsService = new google.maps.DirectionsService() directionsService.route( { origin: origin, destination: destination, travelMode: 'DRIVING', optimizeWaypoints: false, waypoints: points }, (response, status) => { if (status === 'OK') { // let distance = 0 let duration = 0 let legs = response.routes[0].legs legs.map(item => { // distance += item.distance.value duration += item.duration.value }) let delayTime = vm.orderData.time let range = moment() .add(duration, 'seconds') .add(delayTime, 'minutes') .format('hh:mm A') vm.dealerData.time = range vm.loadModal = true; } else { console.log(status) } } ) }) } }, cateringName(index) { this.index = index; } }, filters: { moment: function (date) { return moment(date, "HH:mm").format("h:mm A"); } } }; </script> <style> .v-stepper__step { cursor: pointer; align-items: center; display: flex; flex-direction: row; padding: 24px; position: relative; } .v-stepper__header { height: 100%; } .span-title { font-weight: bold; font-size: 1.2em; } .v-card__actions { padding: 0 8px; } .subheading .hola { font-size: 12px !important; } .meal_order { font-family: "Trebuchet MS", Arial, Helvetica, sans-serif; border-collapse: collapse; width: 100%; } .meal_order td, .meal_order th { border: 1px solid #ddd; padding: 8px; } .meal_order tr:nth-child(even) { background-color: #f2f2f2; } .meal_order tr:hover { background-color: #ddd; } .meal_order th { padding-top: 12px; padding-bottom: 12px; text-align: left; background-color: #4caf50; color: white; } .v-speed-dial { position: relative !important; } .v-btn--floating { position: relative !important; margin: 3px 0 !important; } .v-speed-dial--bottom:not(.v-speed-dial--absolute) { bottom: 0; margin-left: 20px; } </style>
Editor is loading...
Leave a Comment