index.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536
  1. <template>
  2. <view class="container-view">
  3. <view class="card-box">
  4. <view class="card-top flex-row">
  5. <view class="top-left">
  6. <view>取车城市</view>
  7. <view @tap="navToPage" data-url="/pages/pickCarCity/pickCarCity?isFromComponent=true">
  8. {{cityName?cityName:desc_city}}
  9. <img style="margin-left: 4rpx;" src="https://qiniu.bms16.com/FiyzNhwVDwsoE-DszdymtconOypM" />
  10. </view>
  11. </view>
  12. <view class="top-center">
  13. <view class="flex-row">
  14. 我的位置
  15. <view class="distance">距最近门店<text>{{distance}}</text></view>
  16. </view>
  17. <view v-if="isHaveCity||myLocation.address" class="other-record-wrap" @tap="navToMyPo">
  18. <text class="other-record-ellipsis">{{hideProvinceAndCity(myLocation.address?myLocation.address:desc_adress)}}</text>
  19. <img src="https://qiniu.bms16.com/FiyzNhwVDwsoE-DszdymtconOypM" />
  20. </view>
  21. <view v-else @tap="navToMyPo" style="color: #C2CEE0;font-weight: 400;">
  22. 请选择您的位置
  23. </view>
  24. </view>
  25. <view class="top-right">
  26. <view>当前位置</view>
  27. <view class="top-right-img-wrap" @tap="getCurLocation">
  28. <img src="https://qiniu.bms16.com/Fg_gyOd78GozjxF4pPXM29Vme2CQ" />
  29. </view>
  30. </view>
  31. </view>
  32. <view class="card-center">
  33. <view class="center-left" @tap="openCalendar">
  34. <view style="margin-bottom: 26rpx;">取车时间</view>
  35. <view v-if="takeCar!=''" class="take-car-text">{{takeCar}}<img
  36. src="https://qiniu.bms16.com/FiyzNhwVDwsoE-DszdymtconOypM" /></view>
  37. <view v-else style="color: #C2CEE0;font-weight: 400;">请选择取车时间</view>
  38. </view>
  39. <view class="center-right" style="margin-left: 60rpx;" v-if="isUpdate" @tap="$emit('changeType')">
  40. <view style="margin-bottom: 18rpx;">选择租车类型</view>
  41. <view class="leatse-type">
  42. <view>{{ LEASE_TYPE_ARR.find(v => v.value == duration_unit).label }}</view>
  43. <img src="https://qiniu.bms16.com/FiyzNhwVDwsoE-DszdymtconOypM" />
  44. </view>
  45. </view>
  46. <view class="center-right" v-else>
  47. <view>选择{{ rentalType === 'short' ? '短租' : '长租'}}类型</view>
  48. <view class="lease-type-wrap">
  49. <view v-for="(unit, index) in leaseUnitsResult" :key="index" @tap="duration_unit = unit.value"
  50. :class="['lease-type-item', duration_unit === unit.value && 'lease-type-item-checked']">
  51. {{ unit.label }}
  52. </view>
  53. </view>
  54. </view>
  55. </view>
  56. <view v-if="isUpdate" class="options">
  57. <view class="cancle-btn" @tap="updateClose('cancle')">关闭</view>
  58. <view class="submit-btn" @tap="updateClose('confirm')">确定</view>
  59. </view>
  60. <view @tap="navToCarRental" class="select-btn" v-else>
  61. 立即选车
  62. </view>
  63. <view class="hire-tip flex-row">
  64. <view class="tip-text flex-row">
  65. <view>
  66. <image src="https://qiniu.bms16.com/FslaL_pBjFXzLsF9Ni_KEDbnVLFs" />
  67. </view>
  68. <text>大平台</text>
  69. </view>
  70. <view class="tip-text flex-row">
  71. <view>
  72. <image src="https://qiniu.bms16.com/FslaL_pBjFXzLsF9Ni_KEDbnVLFs" />
  73. </view>
  74. <text>有保障</text>
  75. </view>
  76. <view class="flex-row">
  77. <view>
  78. <image src="https://qiniu.bms16.com/FslaL_pBjFXzLsF9Ni_KEDbnVLFs" />
  79. </view>
  80. <text>放心租</text>
  81. </view>
  82. </view>
  83. </view>
  84. <Calendar ref="calendar" :showPopup.sync="isShowCalendar" @valuesUpdated="handleValuesUpdated" @close="closePopup" />
  85. </view>
  86. </template>
  87. <script module="tools" lang="wxs" src="@/pages/common/wxs/tools.wxs"></script>
  88. <script module="tools" lang="sjs" src="@/pages/common/wxs/tools.sjs"></script>
  89. <script>
  90. const config = require('../../../../common/config.js');
  91. const common = require('../../../../common/common.js');
  92. const http = require('../../../../common/http.js');
  93. const storage = require('../../../../common/storage.js');
  94. import Calendar from '@/component/smartCalendar';
  95. import {
  96. LEASE_TYPE,
  97. LEASE_TYPE_ARR
  98. } from '@/common/constant.js'
  99. export default {
  100. components: {
  101. Calendar
  102. },
  103. props: {
  104. // 长租还是短租
  105. rentalType: {
  106. type: String,
  107. default: ''
  108. },
  109. // 是否为更新数据的作用
  110. isUpdate: {
  111. type: Boolean,
  112. default: false
  113. }
  114. },
  115. computed: {
  116. leaseUnitsResult() {
  117. return LEASE_TYPE_ARR.filter(v => v.type === this.rentalType)
  118. }
  119. },
  120. data() {
  121. return {
  122. LEASE_TYPE_ARR,
  123. isShowCalendar: false,
  124. desc_adress: '',
  125. desc_city: '', //选中城市 默认为当前城市
  126. desc_cityCode: '',
  127. desc_city: '', //选中城市 默认为当前城市
  128. distance: '',
  129. takeCar: '',
  130. returnCar: '',
  131. leaseTime: 1,
  132. rentalUnit: '',
  133. duration_unit: 1,
  134. startDate: '',
  135. from: '',
  136. nowCity: '', //当前城市
  137. nowAdress: '', //当前位置
  138. emptyAdress: false,
  139. currentCity: true,
  140. myLocation: {
  141. latitude: null,
  142. longitude: null
  143. },
  144. cityCode: '',
  145. cityName: '',
  146. isHaveCity: true,
  147. dateText: ''
  148. };
  149. },
  150. watch: {
  151. // 切换长租短租时的默认值
  152. rentalType: {
  153. handler(val) {
  154. const mapVal = {
  155. 'short': LEASE_TYPE.day,
  156. 'long': LEASE_TYPE.month
  157. }
  158. this.duration_unit = mapVal[val]
  159. }
  160. }
  161. },
  162. created() {
  163. const locationStr = uni.getStorageSync('user_current_location');
  164. if (locationStr) {
  165. this.myLocation = locationStr;
  166. this.loadAddressLocation()
  167. } else {
  168. this.getCurLocation()
  169. }
  170. this.rentalUnit = '天'
  171. //#ifdef MP-ALIPAY
  172. this.from = 'ali'
  173. //#endif
  174. //#ifdef MP-WEIXIN
  175. this.from = 'wx'
  176. //#endif
  177. this.loadTime()
  178. },
  179. mounted() {
  180. uni.$on('getNewAdress', this.getNewAdress);
  181. uni.$on('getCityInfo', this.getCityInfo);
  182. },
  183. beforeDestroy() {
  184. uni.$off('getCityInfo', this.getCityInfo);
  185. uni.$off('getNewAdress', this.getNewAdress);
  186. },
  187. methods: {
  188. getCityInfo(info) {
  189. this.setData({
  190. cityCode: info.cityCode,
  191. cityName: info.cityName
  192. });
  193. this.loadHaveCity()
  194. },
  195. getNewAdress(adress) {
  196. this.setData({
  197. myLocation: JSON.parse(adress)
  198. });
  199. },
  200. setDataInfo(data) {
  201. const newData = {
  202. duration_unit: data.duration_unit,
  203. takeCar: data.takeCar,
  204. myLocation: data.myLocation,
  205. cityName: data.cityName,
  206. cityCode: data.cityCode
  207. }
  208. this.setData(newData)
  209. this.$refs.calendar && this.$refs.calendar.setTakeCarData({
  210. takeCar: data.takeCar,
  211. dateText: data.dateText
  212. })
  213. },
  214. updateClose(type) {
  215. if (type === 'cancle') {
  216. this.$emit('close')
  217. } else {
  218. const obj = {
  219. myLocation: this.myLocation,
  220. desc_adress: this.desc_adress,
  221. takeCar: this.takeCar,
  222. duration_unit: this.duration_unit,
  223. cityName: this.cityName,
  224. cityCode: this.cityCode
  225. }
  226. this.$emit('close', obj)
  227. }
  228. },
  229. loadTime() {
  230. let _isNextDay = (new Date().getMinutes() - 0) > 30 && ((new Date().getHours() - 0 + 1) == 0)
  231. let _startH = (new Date().getMinutes() - 0) > 30 ? (new Date().getHours() - 0 + 1) : (new Date()
  232. .getHours() - 0)
  233. let _startM = (new Date().getMinutes() - 0) > 30 ? (new Date().getMinutes() - 30) : (new Date()
  234. .getMinutes() - 0 + 30)
  235. let time_text = _isNextDay ? common.getToDay(1) : common.getToDay()
  236. _startH = _startH < 10 && _startH !== '00' ? '0' + _startH : _startH
  237. _startM = _startM < 10 && _startM !== '00' ? '0' + _startM : _startM
  238. const startDate = time_text + 'T' + _startH + ':' + _startM
  239. this.startDate = startDate
  240. this.takeCar = common.formatDate(time_text) + ' ' + _startH + ':' + _startM
  241. const endDate = common.loadAugmentTime(this.leaseTime, startDate, 1)
  242. this.returnCar = common.formatTimeDate(endDate)
  243. },
  244. bindPickerChange(e) {
  245. const index = e.detail.value;
  246. this.setData({
  247. selectStatus: index,
  248. takeCar: '',
  249. leaseTime: '',
  250. rentalUnit: ''
  251. });
  252. if (this.selectStatus == 0) {
  253. this.rentalUnit = '小时'
  254. this.duration_unit = 4
  255. } else if (this.selectStatus == 1) {
  256. this.rentalUnit = '天'
  257. this.duration_unit = 1
  258. } else if (this.selectStatus == 2) {
  259. this.rentalUnit = '周'
  260. this.duration_unit = 6
  261. }
  262. },
  263. bindHireCar() {
  264. this.setData({
  265. isShowHireCar: true
  266. });
  267. },
  268. navToPage(e) {
  269. const url = e.currentTarget.dataset.url;
  270. if (!url) {
  271. return;
  272. }
  273. uni.navigateTo({
  274. url
  275. });
  276. },
  277. getSkipUrlParams() {
  278. const rentalUnit = LEASE_TYPE_ARR.find(v => v.value === this.duration_unit).unit
  279. return {
  280. rentalUnit,
  281. desc_adress: this.desc_adress,
  282. takeCar: this.takeCar,
  283. returnCar: this.returnCar,
  284. leaseTime: this.leaseTime,
  285. duration_unit: this.duration_unit,
  286. longitude: this.myLocation.longitude,
  287. latitude: this.myLocation.latitude,
  288. desc_city: this.desc_city,
  289. startDate: this.startDate
  290. }
  291. },
  292. _getSkipUrlUrl() {
  293. const rentalUnit = LEASE_TYPE_ARR.find(v => v.value === this.duration_unit).unit
  294. const myLocation = JSON.stringify(this.myLocation)
  295. const skipUrl = `/pages/carRental/carRental?desc_adress=${this.desc_adress}&takeCar=${this.takeCar}` +
  296. `&returnCar=${this.returnCar}&leaseTime=${this.leaseTime}&rentalUnit=${rentalUnit}` +
  297. `&duration_unit=${this.duration_unit}&longitude=${this.myLocation.longitude}` +
  298. `&latitude=${this.myLocation.latitude}&desc_city=${this.desc_city}&startDate=${this.startDate}&myLocation=${myLocation}&cityName=${this.cityName}&cityCode=${this.cityCode}`;
  299. return skipUrl
  300. },
  301. loadFaceToken() {
  302. const me = this
  303. http.postApi(config.API_USER_FACE_TOKEN, {}, (resp) => {
  304. if (resp.data.code === 200) {
  305. me.face_token = resp.data.data.token
  306. me.face_key = resp.data.data.key
  307. uni.navigateTo({
  308. url: '/pages/livenessView/livenessView?face_token=' + me.face_token +
  309. '&face_key=' + this.face_key
  310. })
  311. } else {
  312. common.simpleToast(resp.data.msg)
  313. }
  314. })
  315. },
  316. // 判断是否登录或者实名
  317. _inletChecked() {
  318. const { userInfo = '' } = storage.getUserInfoData()
  319. if (userInfo.is_auth == 1 && userInfo.status != 2) {
  320. uni.showModal({
  321. title: '身份认证提示',
  322. content: '尚未完成身份认证,是否进行身份认证?',
  323. cancelText: '取消',
  324. confirmText: '确定',
  325. success: res => {
  326. if (res.confirm) {
  327. this.loadFaceToken()
  328. }
  329. }
  330. })
  331. return false
  332. }
  333. if (!storage.getUserToken()) {
  334. uni.showModal({
  335. title: '提示',
  336. content: '您还未登录,请先登录',
  337. showCancel: false,
  338. confirmText: '确定',
  339. success: function(res) {
  340. if (res.confirm) {
  341. //#ifdef MP-ALIPAY
  342. uni.navigateTo({
  343. url: '/pages/phoneLogin/phoneLogin',
  344. })
  345. //#endif
  346. //#ifdef MP-WEIXIN
  347. uni.navigateTo({
  348. url: '/pages/login/login',
  349. })
  350. //#endif
  351. }
  352. }
  353. })
  354. return false
  355. }
  356. return true
  357. },
  358. async navToCarRental() {
  359. const check = await this._inletChecked()
  360. if (!check) return
  361. if (this.desc_adress == '') {
  362. common.simpleToast('请选择您的位置')
  363. return;
  364. }
  365. if (this.takeCar == '') {
  366. common.simpleToast('请选择取车时间')
  367. return;
  368. }
  369. if (this.leaseTime == '' || this.rentalUnit == '') {
  370. common.simpleToast('请选择租借时长')
  371. return;
  372. }
  373. // 我的位置+取车时间+还车时间+租借时长+租借时长单位+租借时长值+经度+纬度+选中城市+开始时间+是否为当前城市+城市代码
  374. const url = this._getSkipUrlUrl()
  375. uni.navigateTo({
  376. url
  377. })
  378. },
  379. openCalendar() {
  380. if (this.isUpdate) {
  381. this.$emit('calendarChange', '100%')
  382. }
  383. this.setData({
  384. isShowCalendar: true
  385. });
  386. },
  387. close() {
  388. this.setData({
  389. isShowCalendar: false
  390. })
  391. },
  392. loadAddressLocation(data) {
  393. common.loading()
  394. const me = this
  395. //#ifdef MP-ALIPAY
  396. const _pi = "ali_index"
  397. //#endif
  398. //#ifdef MP-WEIXIN
  399. const _pi = "wx_index"
  400. //#endif
  401. const lng = data ? data.longitude + '' : me.myLocation.longitude + ""
  402. const lat = data ? data.latitude + '' : me.myLocation.latitude + ""
  403. const pData = {
  404. lng,
  405. lat,
  406. pi: _pi
  407. }
  408. http.postApi(config.API_MAP_REGEO, pData, function(resp) {
  409. if (resp.data.code === 200) {
  410. uni.hideLoading()
  411. let jsonData = resp.data.data.data
  412. if (jsonData.code === 0) {
  413. if (!!me.myLocation.address) {
  414. me.nowAdress = me.myLocation.address
  415. me.desc_adress = me.myLocation.address
  416. } else {
  417. me.nowAdress = jsonData.address
  418. me.desc_adress = jsonData.address
  419. }
  420. me.nowCity = jsonData.city
  421. if (me.desc_city == '') {
  422. me.desc_city = me.nowCity
  423. }
  424. me.loadHaveCity()
  425. me.loadNearShop(me.desc_adress, lng, lat)
  426. }
  427. } else {
  428. uni.hideLoading()
  429. common.simpleToast(resp.data.msg)
  430. }
  431. })
  432. },
  433. loadHaveCity() {
  434. const me = this
  435. if (me.desc_city != '') {
  436. if (me.cityName == '' || (me.cityName != '' && me.cityName == me.desc_city)) {
  437. me.isHaveCity = true
  438. } else {
  439. me.isHaveCity = false
  440. }
  441. } else {
  442. me.isHaveCity = false
  443. }
  444. },
  445. loadNearShop(_cityname, _longitude, _latitude) {
  446. const me = this
  447. const pData = {
  448. cityname: _cityname,
  449. longitude: _longitude,
  450. latitude: _latitude
  451. }
  452. http.postApi(config.API_DAYHIRE_USER_MOST_NEAR_SHOP, pData, function(resp) {
  453. if (resp.data.code === 200) {
  454. let shopInfo = resp.data.data.shop_info ||{}
  455. let distance = ('distance' in shopInfo)?shopInfo.distance:''
  456. me.distance = common.formatDistance(distance)
  457. } else {
  458. common.simpleToast(resp.data.msg)
  459. }
  460. })
  461. },
  462. handleValuesUpdated(e) {
  463. this.takeCar = e.takeCar
  464. this.returnCar = e.returnCar
  465. this.leaseTime = e.leaseTime
  466. this.startDate = e.startDate
  467. this.dateText = e.date
  468. this.closePopup()
  469. },
  470. // 获取当前位置
  471. getCurLocation() {
  472. uni.getLocation({
  473. type: 'gcj02',
  474. success: res => {
  475. const myLocation = {
  476. longitude: res.longitude,
  477. latitude: res.latitude
  478. }
  479. this.setData({ myLocation })
  480. uni.setStorageSync('user_current_location', myLocation)
  481. this.loadAddressLocation(myLocation)
  482. }
  483. })
  484. },
  485. navToMyPo() {
  486. const _desc_city = this.cityName != '' ? this.cityName : this.desc_city
  487. uni.navigateTo({
  488. url: '/pages/myPosition/myPosition?descAdress=' + this.desc_adress + '&descCity=' +
  489. _desc_city +
  490. '&nowCity=' + this.desc_city + '&longitude=' + this.longitude + '&latitude=' + this
  491. .latitude + '&isFromComponent=true',
  492. success: function(res) {},
  493. fail: function(res) {},
  494. complete: function(res) {}
  495. });
  496. },
  497. closePopup() {
  498. if (this.isUpdate) {
  499. const timer = setTimeout(() => {
  500. this.$emit('calendarChange', 'auto')
  501. clearTimeout(timer)
  502. }, 300)
  503. }
  504. this.isShowCalendar = false
  505. },
  506. hideProvinceAndCity(address){
  507. return common.hideProvinceAndCity(address)
  508. }
  509. }
  510. };
  511. </script>
  512. <style>
  513. @import './index.css';
  514. </style>