taxiService.vue 28 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036
  1. <template>
  2. <view>
  3. <map class="map" @tap="onMapTap" :latitude="map.latitude" :longitude="map.longitude" :markers="map.covers" :scale="map.scale" :polyline="map.polyline"></map>
  4. <!--地址输入-->
  5. <uni-popup class="popup" ref="popup" type="top">
  6. <view class="destination">
  7. <input type="text" v-model="input" :focus="focus" @input="onInputAddress" :placeholder="'请输入' + (selectType == 'end' ? '目的地' : '出发地')" />
  8. <text @tap="closePopup">取消</text>
  9. </view>
  10. <view class="addressHistory" v-for="(v, i) in suggestion" :key="i" @tap="setAddress(v)">
  11. <text>{{ v.title }}</text>
  12. {{ v.addr }}
  13. </view>
  14. </uni-popup>
  15. <!--地址输入-->
  16. <view class="taxi">
  17. <!-- 等待司机接单 -->
  18. <view class="order" v-if="status == -1">
  19. <view class="money">
  20. <text>预计费用{{ order.estimated_price }}元</text>
  21. {{ order.start }} - {{ order.end }}
  22. </view>
  23. <button class="xiadan" type="primary" disabled>订单已取消</button>
  24. </view>
  25. <!--输入位置-->
  26. <view class="call" v-if="status == 1">
  27. <view class="input" style="border-bottom: 1px solid #F0F0F0;">
  28. <text class="icon green">&#xe608;</text>
  29. <input type="text" :value="currAddress.formatted_addresses.recommend" disabled="disabled" @tap="selectAddress('start')" placeholder="出发位置" />
  30. <button type="primary" @tap="call">呼叫司机</button>
  31. </view>
  32. <view class="input">
  33. <text class="icon orange">&#xe608;</text>
  34. <input type="text" :value="toAddress.title" placeholder="你要去哪" disabled="disabled" @tap="selectAddress('end')" />
  35. </view>
  36. <view class="input">
  37. <text class="icon blue">&#xe608;</text>
  38. <input type="mobile" v-model="mobile" placeholder="联系电话(不填则使用注册手机号)" />
  39. </view>
  40. </view>
  41. <!-- 预估车费 -->
  42. <view class="theFare" v-if="status == 2">
  43. <view class="money">
  44. <text>预计费用{{ price }}元</text>
  45. 作为参考不作为最终付款
  46. </view>
  47. <button class="xiadan" type="primary" @tap="createOrder()">立即下单</button>
  48. </view>
  49. <!-- 等待司机接单 -->
  50. <view class="order" v-if="status == 3">
  51. <view class="cancel"><text class="text" @tap="cancel('确定要取消订单吗?')">取消订单</text></view>
  52. <view class="money">
  53. <text>预计费用{{ price }}元</text>
  54. 作为参考不作为最终付款
  55. </view>
  56. <button class="xiadan" type="primary" disabled>等待司机接单{{ cancelData.time }}</button>
  57. </view>
  58. <!-- 已接单 -->
  59. <view class="new" v-if="status == 4">
  60. <view class="cancel"><text class="text" @tap="cancel('确定要取消订单吗?')">取消订单</text></view>
  61. <view class="user">
  62. <image :src="order.driver.avatar" mode=""></image>
  63. <view class="name">
  64. <text class="item1">{{ order.driver.nickname }}</text>
  65. <!-- <text class="icon yellow">&#xe642;</text> -->
  66. <text class="item2">{{ order.driver.total_order }}单</text>
  67. <text class="item2">驾龄{{ order.driver.driving_age }}年</text>
  68. <text class="item2">总里程{{ order.driver.total_distance }}km</text>
  69. </view>
  70. <view class="phone" @tap="callPhone(order.driver.mobile)">
  71. <text class="icon blue">&#xe657;</text>
  72. {{ order.driver.mobile }}
  73. </view>
  74. </view>
  75. <view class="money">
  76. <text>预计费用{{ order.estimated_price }}元</text>
  77. <view v-if="order.status==4">司机等待10分钟内免费,超出后每分钟1元</view>
  78. </view>
  79. <button class="xiadan" type="primary" disabled>{{order.status==1?'司机已接单':'司机等待中'}}</button>
  80. </view>
  81. <!--进行中-->
  82. <view class="new" v-if="status == 5">
  83. <view class="user">
  84. <image :src="order.driver.avatar" mode=""></image>
  85. <view class="name">
  86. <text class="item1">{{ order.driver.nickname }}</text>
  87. <!-- <text class="icon yellow">&#xe642;</text>
  88. <text class="item2">5.0</text> -->
  89. <text class="item2">{{ order.driver.total_order }}单</text>
  90. <text class="item2">驾龄{{ order.driver.driving_age }}年</text>
  91. <text class="item2">总里程{{ order.driver.total_distance }}km</text>
  92. </view>
  93. <view class="phone" @tap="callPhone(order.driver.mobile)">
  94. <text class="icon blue">&#xe657;</text>
  95. {{ order.driver.mobile }}
  96. </view>
  97. </view>
  98. <view class="money tips">
  99. <view class="item" style="width: 100%; font-size: 40upx; font-weight: 800;text-align: center;">实时费用{{ actual.price }}元</view>
  100. <view class="item" style="width: 100%; font-size: 22upx;color: #D2D2D2; margin-top:20upx;text-align: center;">
  101. 已行驶{{ actual.distance | kilometer }} km,预计还需要{{ route.duration }}分钟到达
  102. </view>
  103. </view>
  104. </view>
  105. <!-- 付款 -->
  106. <view class="payment" v-if="status == 6">
  107. <view class="user">
  108. <image :src="order.driver.avatar" mode=""></image>
  109. <view class="name">
  110. <text class="item1">{{ order.driver.nickname }}</text>
  111. <!-- <text class="icon yellow">&#xe642;</text>
  112. <text class="item2">5.0</text> -->
  113. <text class="item2">{{ order.driver.total_order }}单</text>
  114. <text class="item2">驾龄{{ order.driver.driving_age }}年</text>
  115. <text class="item2">总里程{{ order.driver.total_distance }}km</text>
  116. </view>
  117. <view class="phone" @tap="callPhone(order.driver.mobile)">
  118. <text class="icon blue">&#xe657;</text>
  119. {{ order.driver.mobile }}
  120. </view>
  121. </view>
  122. <view class="money">
  123. <text style="width: 100%; font-size: 40upx; font-weight: 800;text-align: center;">实时费用{{ order.price }}元</text>
  124. <text style="width: 100%; font-size: 22upx;color: #D2D2D2; margin-top:20upx;text-align: center;">到达时间{{ order.end_time | date }}</text>
  125. </view>
  126. <button class="xiadan" type="primary" @tap="pay">确认支付{{ order.price }}元</button>
  127. </view>
  128. <!-- 付款后,待评价 -->
  129. <view class="comment" v-if="status == 7">
  130. <view class="user">
  131. <image :src="order.driver.avatar" mode=""></image>
  132. <view class="name">
  133. <text class="item1">{{ order.driver.nickname }}</text>
  134. <!-- <text class="icon"></text>
  135. <text class="item2">5.0</text> -->
  136. <text class="item2">{{ order.driver.total_order }}单</text>
  137. <text class="item2">驾龄{{ order.driver.driving_age }}年</text>
  138. <text class="item2">总里程{{ order.driver.total_distance }}km</text>
  139. </view>
  140. <view class="phone">
  141. <text></text>
  142. {{ order.driver.mobile }}
  143. </view>
  144. </view>
  145. <view class="money" v-if="order.comment == 1">
  146. <view>订单已完成,到达时间{{ order.end_time | date }}</view>
  147. <view>已付{{ order.price }}元</view>
  148. </view>
  149. <view class="comments" v-if="order.comment == 0">
  150. <my-issue :score="score" :headPicShow="false" :submitShow="false" @scoreChange="scoreChange" :headTitleShow="false" />
  151. </view>
  152. <button class="comment-btn" type="primary" v-if="order.comment == 0" @tap="comment">评价本次服务</button>
  153. <button class="done" type="primary" v-if="order.comment == 1" @tap="done">订单已完成</button>
  154. </view>
  155. </view>
  156. </view>
  157. </template>
  158. <script>
  159. import QQMapWX from '../../libs/qqmap-wx-jssdk/qqmap-wx-jssdk.js';
  160. import uniPopup from '@/components/uni-popup/uni-popup.vue';
  161. import myIssue from '@/components/myIssue.vue';
  162. import helper from '../../common/helper.js';
  163. import api from '../../common/api.js';
  164. export default {
  165. components: {
  166. uniPopup,
  167. myIssue
  168. },
  169. filters: {
  170. date: value => {
  171. let date = new Date(value * 1000);
  172. let h = date.getHours();
  173. let m = date.getMinutes();
  174. return (h > 9 ? h : '0' + h) + ':' + (m > 9 ? m : '0' + m);
  175. },
  176. kilometer: value => {
  177. let distance = parseFloat(value / 1000);
  178. return distance.toFixed(2);
  179. },
  180. duration: value => {
  181. if (value > 3600) {
  182. let h = parseInt(value / 3600);
  183. let s = value % 3600;
  184. if (s > 0) {
  185. return h + '小时' + parseInt(s / 60) + '分钟';
  186. } else {
  187. return h + '小时';
  188. }
  189. } else {
  190. return parseInt(value / 60) + '分钟';
  191. }
  192. }
  193. },
  194. data() {
  195. return {
  196. input: '',
  197. score: 5,
  198. host: helper.host,
  199. qqmapsdk: {},
  200. city: '',
  201. currLocation: {},
  202. currAddress: {},
  203. suggestion: [],
  204. region: '',
  205. toAddress: {},
  206. covers: [],
  207. result: {},
  208. order: {},
  209. status: 0,
  210. show: false,
  211. msg: '',
  212. action: '',
  213. orderId: '',
  214. mobile: '',
  215. map: {
  216. latitude: '',
  217. longitude: '',
  218. covers: [],
  219. scale: 16
  220. },
  221. focus: false,
  222. price: '',
  223. timer: '',
  224. actual: {
  225. price: 0,
  226. distance: 0
  227. },
  228. route: {
  229. duration: '--'
  230. },
  231. cancelData: {
  232. timer: '',
  233. time: ''
  234. },
  235. selectType: 'end'
  236. };
  237. },
  238. onLoad(option) {
  239. this.initSdk();
  240. if (option.action == 'call') {
  241. // 不存在则获取当前位置
  242. this.getLocation();
  243. this.status = 1;
  244. this.selectAddress(option.type);
  245. }
  246. // 用户端订单
  247. if (option.action == 'order') {
  248. this.orderId = option.order_id;
  249. }
  250. },
  251. onShow() {
  252. // 如果存在订单则更新订单信息
  253. if (this.orderId) {
  254. this.getOrderInfo();
  255. }
  256. },
  257. onHide() {
  258. // 隐藏时关闭定时器
  259. if (this.timer) {
  260. console.log('清除定时器');
  261. clearInterval(this.timer);
  262. this.timer = '';
  263. }
  264. if(this.cancelData.timer){
  265. clearInterval(this.cancelData.timer);
  266. this.cancelData.timer = '';
  267. }
  268. },
  269. methods: {
  270. // 点击地图
  271. onMapTap(e) {
  272. let res = e.detail;
  273. // 设置地图信息
  274. this.map.latitude = res.latitude;
  275. this.map.longitude = res.longitude;
  276. // 坐标点
  277. this.map.covers = [];
  278. this.map.covers.push({
  279. latitude: res.latitude,
  280. longitude: res.longitude,
  281. iconPath: '../../static/marker.png'
  282. });
  283. // 坐标转地址信息
  284. this.qqmapsdk.reverseGeocoder({
  285. location: {
  286. latitude: res.latitude,
  287. longitude: res.longitude
  288. },
  289. complete: e => {
  290. console.log(e);
  291. if (e.status == 0) {
  292. this.currAddress = e.result;
  293. }
  294. }
  295. });
  296. },
  297. selectAddress(type) {
  298. this.focus = false;
  299. this.selectType = type;
  300. this.suggestion = [];
  301. this.input = '';
  302. this.openPopup();
  303. },
  304. scoreChange(score) {
  305. this.score = score;
  306. },
  307. async comment() {
  308. let res = await api.orderComment(this.orderId, this.score);
  309. helper.toast(res.msg);
  310. this.getOrderInfo();
  311. },
  312. async pay() {
  313. let res = await api.getOrderPayData(this.orderId);
  314. if (res.msg) {
  315. helper.toast(res.msg);
  316. return false;
  317. }
  318. // 仅作为示例,非真实参数信息。
  319. uni.requestPayment({
  320. provider: 'wxpay',
  321. timeStamp: res.timeStamp,
  322. nonceStr: res.nonceStr,
  323. package: res.package,
  324. signType: res.signType,
  325. paySign: res.paySign,
  326. success: res => {
  327. this.getOrderInfo();
  328. },
  329. fail: err => {
  330. console.log('fail:' + JSON.stringify(err));
  331. }
  332. });
  333. },
  334. callPhone(mobile) {
  335. uni.makePhoneCall({
  336. phoneNumber: mobile
  337. });
  338. },
  339. closeModal() {
  340. this.show = false;
  341. },
  342. async getOrderInfo() {
  343. console.log('获取订单信息');
  344. let res = await api.getOrderInfo(this.orderId);
  345. this.order = res.data;
  346. // 设置状态
  347. this.setStatus(res.data.status, res.data);
  348. // 设置地图
  349. this.map.latitude = res.data.start_latitude;
  350. this.map.longitude = res.data.start_longitude;
  351. // 坐标点
  352. this.map.covers.push({
  353. latitude: res.data.start_latitude,
  354. longitude: res.data.start_longitude,
  355. iconPath: '../../static/marker.png'
  356. });
  357. // 路径规划
  358. // 如果订单为进行中,则实时更新费用及到达时间
  359. if (this.order.status == 2) {
  360. this.updateOrderInfo();
  361. }
  362. // 如果订单为未完成状态,则定时更新
  363. if (this.order.status != 99 && this.order.status != -1 && !this.timer) {
  364. console.log('注册定时器');
  365. this.timer = setInterval(() => {
  366. this.getOrderInfo();
  367. }, 3 * 1000);
  368. }
  369. // 如果订单状态为已完成,切存在定时器,则关闭
  370. if (this.order.status == 99 && this.timer) {
  371. console.log('清除定时器');
  372. clearInterval(this.timer);
  373. this.timer = '';
  374. }
  375. // 订单为等待接单状态
  376. if (this.order.status == 0) {
  377. this.registerCancelTimer();
  378. }
  379. },
  380. registerCancelTimer() {
  381. if (!this.cancelData.timer) {
  382. this.cancelData.timer = setInterval(() => {
  383. let timestamp = Date.parse(new Date()) / 1000;
  384. let s = this.order.createtime + 5 * 60 - timestamp;
  385. // 订单超时
  386. if (s <= 0) {
  387. clearInterval(this.cancelData.timer);
  388. this.cancelData.timer = '';
  389. this.cancelData.time = '';
  390. api.cancelOrder(this.orderId);
  391. uni.showModal({
  392. title: '订单提示',
  393. content: '订单已超时并取消,请重新呼叫',
  394. showCancel: false,
  395. success: res => {
  396. if (res.confirm) {
  397. uni.navigateBack({
  398. url: '/pages/index/index'
  399. });
  400. }
  401. }
  402. });
  403. return false;
  404. }
  405. // 倒计时
  406. if (s < 60) {
  407. this.cancelData.time = s + '秒';
  408. }
  409. if (s > 60) {
  410. this.cancelData.time = parseInt(s / 60) + '分' + parseInt(s % 60) + '秒';
  411. }
  412. }, 1000);
  413. }
  414. },
  415. setStatus(orderStatus, order) {
  416. let status = 0;
  417. switch (orderStatus) {
  418. case '-1':
  419. // 已取消
  420. status = -1;
  421. break;
  422. case '0':
  423. // 未接单
  424. status = 3;
  425. this.price = order.estimated_price;
  426. break;
  427. case '1':
  428. // 已接单
  429. status = 4;
  430. break;
  431. case '2':
  432. // 进行中
  433. status = 5;
  434. break;
  435. case '3':
  436. // 待支付
  437. status = 6;
  438. break;
  439. case '4':
  440. // 出发
  441. status = 4;
  442. break;
  443. case '99':
  444. // 订单已完成
  445. status = 7;
  446. break;
  447. }
  448. this.status = status;
  449. },
  450. // 取消订单
  451. async cancel(tips) {
  452. if (!tips) {
  453. tips = '确定要取消订单吗';
  454. }
  455. uni.showModal({
  456. title: '操作提示',
  457. content: tips,
  458. success: async res => {
  459. if (res.confirm) {
  460. let res = await api.cancelOrder(this.orderId);
  461. helper.toast(res.msg);
  462. if (res.code == 1) {
  463. uni.navigateBack({
  464. url: '/pages/index/index'
  465. });
  466. }
  467. }
  468. }
  469. });
  470. },
  471. // 创建订单
  472. async createOrder() {
  473. let data = {
  474. start: this.currAddress.formatted_addresses.recommend,
  475. start_city: this.currAddress.ad_info.city,
  476. start_address: this.currAddress.address,
  477. start_latitude: this.currAddress.location.lat,
  478. start_longitude: this.currAddress.location.lng,
  479. end: this.toAddress.title,
  480. end_city: this.toAddress.city,
  481. end_address: this.toAddress.addr,
  482. end_latitude: this.toAddress.latitude,
  483. end_longitude: this.toAddress.longitude,
  484. distance: this.result.distance,
  485. duration: this.result.duration,
  486. mobile: this.mobile
  487. };
  488. let res = await api.createOrder(data);
  489. helper.toast(res.msg);
  490. if (res.code != 0) {
  491. this.orderId = res.data.order_id;
  492. this.getOrderInfo();
  493. }
  494. },
  495. // 呼叫司机
  496. call() {
  497. if (!this.toAddress.title) {
  498. helper.toast('请输入目的地');
  499. return false;
  500. }
  501. let from = this.currAddress.location.lat + ',' + this.currAddress.location.lng;
  502. let to = this.toAddress.latitude + ',' + this.toAddress.longitude;
  503. // 计算驾车距离
  504. this.qqmapsdk.calculateDistance({
  505. mode: 'driving',
  506. from: from,
  507. to: to,
  508. complete: async res => {
  509. this.result = res.result.elements[0];
  510. let data = await api.getPrice(this.result.distance, 0);
  511. this.price = data.data;
  512. this.status = 2;
  513. }
  514. });
  515. },
  516. onInputAddress(e) {
  517. let address = e.detail.value;
  518. //调用关键词提示接口
  519. this.qqmapsdk.getSuggestion({
  520. //获取输入框值并设置keyword参数
  521. keyword: address,
  522. region: this.city,
  523. success: res => {
  524. //搜索成功后的回调
  525. console.log(res);
  526. let sug = [];
  527. for (let i = 0; i < res.data.length; i++) {
  528. sug.push({
  529. // 获取返回结果,放到sug数组中
  530. title: res.data[i].title,
  531. id: res.data[i].id,
  532. addr: res.data[i].address,
  533. city: res.data[i].city,
  534. district: res.data[i].district,
  535. latitude: res.data[i].location.lat,
  536. longitude: res.data[i].location.lng
  537. });
  538. }
  539. this.suggestion = sug;
  540. },
  541. fail: function(error) {
  542. console.error(error);
  543. },
  544. complete: function(res) {
  545. console.log(res);
  546. }
  547. });
  548. },
  549. setAddress(address) {
  550. if (this.selectType == 'end') {
  551. this.toAddress = address;
  552. } else {
  553. this.currAddress = {
  554. formatted_addresses: {
  555. recommend: address.title
  556. },
  557. ad_info: {
  558. city: address.city
  559. },
  560. address: address.addr,
  561. location: {
  562. lat: address.latitude,
  563. lng: address.longitude
  564. }
  565. };
  566. }
  567. this.closePopup();
  568. },
  569. openPopup(key) {
  570. let popup = key || 'popup';
  571. this.$refs['popup'].open();
  572. },
  573. closePopup(key) {
  574. let popup = key || 'popup';
  575. this.$refs['popup'].close();
  576. },
  577. initSdk() {
  578. this.qqmapsdk = new QQMapWX({
  579. key: helper.config.qqmapsdk.key
  580. });
  581. },
  582. getLocation() {
  583. uni.getLocation({
  584. type: 'gcj02',
  585. success: res => {
  586. // 当前地址
  587. this.currLocation = res;
  588. // 设置地图信息
  589. this.map.latitude = res.latitude;
  590. this.map.longitude = res.longitude;
  591. // 坐标点
  592. this.map.covers.push({
  593. latitude: res.latitude,
  594. longitude: res.longitude,
  595. iconPath: '../../static/marker.png'
  596. });
  597. // 坐标转地址信息
  598. this.qqmapsdk.reverseGeocoder({
  599. location: {
  600. latitude: res.latitude,
  601. longitude: res.longitude
  602. },
  603. complete: res => {
  604. console.log(res);
  605. if (res.status == 0) {
  606. this.currAddress = res.result;
  607. this.city = res.result.address_component.city;
  608. }
  609. }
  610. });
  611. }
  612. });
  613. },
  614. updateOrderInfo() {
  615. // 更新坐标信息
  616. uni.getLocation({
  617. type: 'gcj02',
  618. success: async res => {
  619. // 当前地址
  620. this.currLocation = res;
  621. this.map.latitude = res.latitude;
  622. this.map.longitude = res.longitude;
  623. // 设置当前坐标点
  624. let covers = [
  625. {
  626. latitude: res.latitude,
  627. longitude: res.longitude,
  628. iconPath: '../../static/marker.png'
  629. }
  630. ];
  631. this.map.covers=covers;
  632. // 更新订单位置
  633. res.order_id = this.orderId;
  634. let data = await api.updateOrderLocation(res);
  635. this.actual = data.data;
  636. // 更新路径
  637. this.direction();
  638. }
  639. });
  640. },
  641. // 路径规划
  642. direction() {
  643. this.qqmapsdk.direction({
  644. mode: 'driving',
  645. from: this.currLocation.latitude + ',' + this.currLocation.longitude,
  646. to: this.order.end_latitude + ',' + this.order.end_longitude,
  647. complete: res => {
  648. if (!res.result || !res.result.routes || res.result.routes.length == 0) {
  649. helper.toast('未获取到有效路线');
  650. return false;
  651. }
  652. let coors = res.result.routes[0].polyline,
  653. pl = []; //坐标解压(返回的点串坐标,通过前向差分进行压缩)
  654. this.route = res.result.routes[0];
  655. let kr = 1000000;
  656. // 处理坐标
  657. for (let i = 2; i < coors.length; i++) {
  658. coors[i] = Number(coors[i - 2]) + Number(coors[i]) / kr;
  659. }
  660. for (let i = 0; i < coors.length; i += 2) {
  661. pl.push({ latitude: coors[i], longitude: coors[i + 1] });
  662. }
  663. this.map.latitude = pl[0].latitude;
  664. this.map.longitude = pl[0].longitude;
  665. this.map.polyline = [
  666. {
  667. points: pl,
  668. color: '#227AFF',
  669. width: 4
  670. }
  671. ];
  672. }
  673. });
  674. },
  675. address() {
  676. this.$refs.popup.open();
  677. },
  678. appraisal() {
  679. uni.navigateTo({
  680. url: 'appraisal'
  681. });
  682. },
  683. done() {
  684. uni.navigateBack({
  685. url: '/pages/index/index'
  686. });
  687. }
  688. }
  689. };
  690. </script>
  691. <style lang="scss" scoped>
  692. input {
  693. font-size: 26upx;
  694. }
  695. .icon {
  696. font-size: 56upx;
  697. }
  698. .map {
  699. width: 100%;
  700. height: calc(100vh - 400upx);
  701. }
  702. .call {
  703. padding: 30upx;
  704. }
  705. .taxi {
  706. width: 100%;
  707. height: 400upx;
  708. flex-direction: column;
  709. align-items: center;
  710. background-color: #ffffff;
  711. .input {
  712. display: flex;
  713. align-items: center;
  714. width: 90%;
  715. padding: 20upx 0;
  716. text {
  717. width: 10%;
  718. }
  719. input {
  720. width: 60%;
  721. }
  722. button {
  723. font-size: 26upx;
  724. background-color: #ffffff;
  725. color: #333333;
  726. float: right;
  727. }
  728. }
  729. }
  730. .tips {
  731. .item {
  732. font-size: 28upx;
  733. color: #000000;
  734. }
  735. }
  736. .popup {
  737. height: 100%;
  738. .destination {
  739. display: flex;
  740. justify-content: space-between;
  741. align-items: center;
  742. padding: 10upx 0;
  743. border-bottom: 1px solid #eeeeee;
  744. text {
  745. font-size: 28upx;
  746. color: #d2d2d2;
  747. }
  748. }
  749. .addressHistory {
  750. padding: 20upx 0;
  751. border-bottom: 1px solid #eeeeee;
  752. display: flex;
  753. flex-direction: column;
  754. font-size: 24upx;
  755. color: #d2d2d2;
  756. text {
  757. color: #101010;
  758. font-size: 28upx;
  759. }
  760. }
  761. }
  762. .theFare {
  763. width: 100%;
  764. height: 100%;
  765. .money {
  766. display: flex;
  767. flex-direction: column;
  768. align-items: center;
  769. justify-content: center;
  770. font-size: 22upx;
  771. height: 234upx;
  772. color: #d2d2d2;
  773. text {
  774. margin-bottom: 10upx;
  775. color: #101010;
  776. font-size: 38upx;
  777. font-weight: 800;
  778. }
  779. }
  780. .xiadan {
  781. width: 100%;
  782. border-radius: 0px;
  783. background-color: #32c45e;
  784. border: none;
  785. position: absolute;
  786. bottom: 0;
  787. }
  788. .xiadan:after {
  789. border: none;
  790. }
  791. }
  792. .order {
  793. width: 100%;
  794. height: 100%;
  795. .cancel {
  796. font-size: 28upx;
  797. text-align: right;
  798. width: 95%;
  799. .text {
  800. padding-top: 10px;
  801. display: inline-block;
  802. }
  803. }
  804. .money {
  805. display: flex;
  806. flex-direction: column;
  807. align-items: center;
  808. justify-content: center;
  809. font-size: 22upx;
  810. height: 200upx;
  811. color: #d2d2d2;
  812. text {
  813. margin-bottom: 10upx;
  814. color: #101010;
  815. font-size: 38upx;
  816. font-weight: 800;
  817. }
  818. }
  819. .xiadan {
  820. width: 100%;
  821. border-radius: 0px;
  822. background-color: #e1e1e1;
  823. position: absolute;
  824. bottom: 0;
  825. color: #999999;
  826. }
  827. .xiadan:after {
  828. border: none;
  829. }
  830. }
  831. .new {
  832. width: 100%;
  833. height: 100%;
  834. .cancel {
  835. font-size: 28upx;
  836. text-align: right;
  837. width: 95%;
  838. .text {
  839. padding-top: 10px;
  840. display: inline-block;
  841. }
  842. }
  843. .user {
  844. width: 100%;
  845. display: flex;
  846. justify-content: center;
  847. align-items: center;
  848. font-size: 28upx;
  849. .icon {
  850. font-size: 28upx;
  851. }
  852. image {
  853. width: 80upx;
  854. height: 80upx;
  855. border-radius: 50%;
  856. }
  857. .name {
  858. width: 40%;
  859. margin-left: 20upx;
  860. .item2 {
  861. font-size: 24upx;
  862. padding-left: 20upx;
  863. }
  864. }
  865. .phone {
  866. width: 40%;
  867. text-align: right;
  868. }
  869. }
  870. .money {
  871. display: flex;
  872. flex-direction: column;
  873. align-items: center;
  874. justify-content: center;
  875. font-size: 22upx;
  876. height: 200upx;
  877. color: #d2d2d2;
  878. text {
  879. margin-bottom: 10upx;
  880. color: #101010;
  881. font-size: 38upx;
  882. font-weight: 800;
  883. }
  884. }
  885. .xiadan {
  886. width: 100%;
  887. border-radius: 0px;
  888. background-color: #e1e1e1;
  889. position: absolute;
  890. bottom: 0;
  891. color: #999999;
  892. }
  893. .xiadan:after {
  894. border: none;
  895. }
  896. }
  897. .payment {
  898. height: 100%;
  899. .user {
  900. display: flex;
  901. justify-content: center;
  902. align-items: center;
  903. font-size: 28upx;
  904. padding: 20upx;
  905. image {
  906. width: 80upx;
  907. height: 80upx;
  908. border-radius: 50%;
  909. }
  910. .name {
  911. width: 40%;
  912. margin-left: 20upx;
  913. .item2 {
  914. font-size: 24upx;
  915. padding-left: 20upx;
  916. }
  917. }
  918. .phone {
  919. width: 40%;
  920. text-align: right;
  921. }
  922. .icon {
  923. font-size: 28upx;
  924. }
  925. }
  926. .money {
  927. display: flex;
  928. align-items: center;
  929. justify-content: flex-end;
  930. flex-direction: column;
  931. font-size: 22upx;
  932. height: 100upx;
  933. color: #d2d2d2;
  934. padding: 20upx;
  935. text {
  936. width: 45%;
  937. margin-bottom: 10upx;
  938. color: #101010;
  939. font-size: 30upx;
  940. }
  941. }
  942. .xiadan {
  943. width: 100%;
  944. border-radius: 0px;
  945. background-color: #32c45e;
  946. position: absolute;
  947. bottom: 0;
  948. }
  949. .xiadan:after {
  950. border: none;
  951. }
  952. }
  953. .cancel-text {
  954. height: 100%;
  955. display: flex;
  956. align-items: center;
  957. justify-content: center;
  958. font-size: 16px;
  959. color: red;
  960. }
  961. .comment {
  962. width: 100%;
  963. height: 100%;
  964. background-color: #ffffff;
  965. .user {
  966. width: 100%;
  967. display: flex;
  968. justify-content: center;
  969. align-items: center;
  970. font-size: 28upx;
  971. image {
  972. width: 80upx;
  973. height: 80upx;
  974. border-radius: 50%;
  975. }
  976. .name {
  977. width: 40%;
  978. margin-left: 20upx;
  979. .item2 {
  980. font-size: 20upx;
  981. padding-left: 20upx;
  982. }
  983. }
  984. .phone {
  985. width: 40%;
  986. text-align: right;
  987. }
  988. }
  989. .money {
  990. text-align: center;
  991. padding-top: 40upx;
  992. height: 120upx;
  993. font-size: 28upx;
  994. text {
  995. margin-bottom: 10upx;
  996. color: #101010;
  997. font-size: 30upx;
  998. }
  999. }
  1000. .comment-btn {
  1001. width: 100%;
  1002. border-radius: 0px;
  1003. background-color: #32c45e;
  1004. height: 90upx;
  1005. color: #ffffff;
  1006. border-top: 1px solid #dddddd;
  1007. position: absolute;
  1008. bottom: 0;
  1009. }
  1010. .comment-btn:after {
  1011. border: none;
  1012. }
  1013. .done {
  1014. height: 90upx;
  1015. width: 100%;
  1016. border-radius: 0px;
  1017. background-color: #32c45e;
  1018. color: #ffffff;
  1019. border-top: 1px solid #dddddd;
  1020. position: absolute;
  1021. bottom: 0;
  1022. }
  1023. .done:after {
  1024. border: none;
  1025. }
  1026. }
  1027. </style>