index1.vue 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610
  1. <template>
  2. <view class="">
  3. <mescroll-body :sticky="true" ref="mescrollRef" @init="mescrollInit" @down="downCallback" @up="upCallback">
  4. <view class="padding-lr padding-top-sm bg flex " @click.stop="goSearch(1)">
  5. <view class="flex justify-between margin-right-sm" @tap.stop="goSelectCity" style="line-height: 68rpx;">
  6. <image src="../../static/images/index/place.png" style="width: 27rpx;height: 37rpx;"
  7. class="margin-top-xs"></image>
  8. <view class="localName text-white margin-left-sm">{{city}}</view>
  9. </view>
  10. <u-search class="flex-sub" placeholder="搜索你需要的服务" shape="square" disabled :show-action="false"
  11. :animation="true" bg-color="#F7F7F7" color="#1A1A1A"></u-search>
  12. </view>
  13. <view v-if="tabIndex == 0" class="bg">
  14. <view class="padding-lr-sm ">
  15. <swiper class="screen-swiper" style="height: 260rpx;" :circular="true" :autoplay="true"
  16. interval="2500" duration="800">
  17. <swiper-item v-for="(item,index) in swiperList" :key="index">
  18. <image :src="item.imageUrl" mode="aspectFit" class="radius"></image>
  19. </swiper-item>
  20. </swiper>
  21. </view>
  22. <view class="bg" style="color: #333333;">
  23. <u-grid :col="5" :border="false">
  24. <u-grid-item v-for="(item,index) in gridData" :key='index' @click="goNav(item.url)">
  25. <image :src="item.imageUrl" style="width: 92rpx;height: 92rpx;border-radius: 92rpx;">
  26. </image>
  27. <view class="grid-text" style="font-size: 25rpx;margin-top: 10rpx;">{{item.name}}</view>
  28. </u-grid-item>
  29. </u-grid>
  30. </view>
  31. </view>
  32. <ren-dropdown-filter :filterData='filterData' :border="false" :defaultIndex='defaultIndex'
  33. @onSelected='change' class="u-skeleton-rect">
  34. </ren-dropdown-filter>
  35. <view style="background-color: #FFFFFF;" v-if="orderList.length">
  36. <view class="flex margin-bottom-sm bg padding-sm radius margin-lr-sm margin-top-sm "
  37. v-for="(item,index) in orderList" :key='index' @click="goOrder(item)" style="box-shadow: 6rpx 10rpx 4px #F5F5F5;">
  38. <view style="width: 220upx;height: 160upx;border-radius: 10rpx;">
  39. <image :src="item.massageImg?item.massageImg: '../../static/logo.png'"
  40. style="width: 220upx;height: 160upx;border-radius: 10upx;"></image>
  41. </view>
  42. <view class="margin-left text-white flex flex-direction" style="width: 65%;">
  43. <view class="flex justify-between">
  44. <view class="text-bold text-lg margin-left-xs">{{item.title}}</view>
  45. <view style="color: #999999;font-size: 22upx;">已售{{item.sales}}</view>
  46. </view>
  47. <view class="flex flex-wrap" style="margin-top: 10rpx;" v-if="item.labels.length>0">
  48. <text class="margin-bottom-xs box" v-for="(items,index) in item.labels"
  49. :key="index">{{items}}</text>
  50. </view>
  51. <!-- <view class="text-cut" style="color: #999999;">{{item.describes}}</view> -->
  52. <view style="width: 100%;display: flex;justify-content: space-between;align-items: center;">
  53. <view style="color:#FF1200;font-size: 24upx;" v-if="isVip == false">
  54. ¥<text
  55. style="font-size: 32upx;font-weight: bold;">{{item.price}}/</text>{{item.duration}}分钟
  56. </view>
  57. <view style="color:#FF1200;font-size: 24upx;" v-else>
  58. ¥<text
  59. style="font-size: 32upx;font-weight: bold;">{{item.memberPrice}}/</text>{{item.duration}}分钟
  60. </view>
  61. <!-- <view class="text-green text-df">
  62. ¥<text
  63. class="text-green text-xl text-bold">{{item.price}}</text>/<text class="text-sm">会员价:¥{{item.memberPrice}}</text>/</text>{{item.duration}}分钟
  64. </view> -->
  65. <view v-if="XCXIsSelect != '否'"
  66. style="background: #2FB57A;color: #ffffff;line-height: 56upx;border-radius: 8rpx;font-size: 24upx;padding: 0upx 23upx;"
  67. >
  68. 选择技师
  69. </view>
  70. </view>
  71. </view>
  72. </view>
  73. </view>
  74. <empty v-if="orderList.length == 0"></empty>
  75. </mescroll-body>
  76. <!-- <u-skeleton :loading="loading" :animation="true" elColor='#FFFFFF' bgColor='#FFFFFF'></u-skeleton> -->
  77. </view>
  78. </template>
  79. <script>
  80. import MescrollMixin from "@/components/mescroll-uni/components/mescroll-uni/mescroll-mixins.js";
  81. import mescrollBody from "@/components/mescroll-uni/components/mescroll-body/mescroll-body.vue";
  82. import meTabs from "@/components/mescroll-uni/me-tabs/me-tabs.vue";
  83. import empty from '@/components/empty.vue'
  84. import RenDropdownFilter from '@/components/ren-dropdown-filter/ren-dropdown-filter.vue'
  85. export default {
  86. mixins: [MescrollMixin], // 使用mixin
  87. components: {
  88. mescrollBody,
  89. meTabs,
  90. empty,
  91. RenDropdownFilter
  92. },
  93. data() {
  94. return {
  95. loading: true, // 是否显示骨架屏组件
  96. defaultSelected: [],
  97. tabIndex: 0, // tab下标
  98. tabData: [{
  99. createTime: "",
  100. gameName: '推荐',
  101. gameImg: "",
  102. id: 0,
  103. status: 0,
  104. updateTime: "",
  105. }],
  106. swiperList: [],
  107. gridData: [],
  108. value1: 0,
  109. value2: 0,
  110. value3: 0,
  111. game: [],
  112. defaultIndex: [0, 0, 0],
  113. filterData: [
  114. [{
  115. label: '推荐',
  116. value: '',
  117. }, ],
  118. [{
  119. label: '价格',
  120. value: '0',
  121. },
  122. {
  123. label: '从高到低',
  124. value: '1',
  125. },
  126. {
  127. label: '从低到高',
  128. value: '2',
  129. }
  130. ],
  131. [{
  132. label: '销量',
  133. value: '0',
  134. },
  135. {
  136. label: '从高到低',
  137. value: '1',
  138. },
  139. {
  140. label: '从低到高',
  141. value: '2',
  142. }
  143. ],
  144. ],
  145. city: '请选择城市',
  146. latitude: '',
  147. longitude: '',
  148. orderList: [],
  149. token: '',
  150. XCXIsSelect: '否',
  151. isVip: false,
  152. myId: uni.getStorageSync('userId') ? uni.getStorageSync('userId') : '',
  153. showModal: true,
  154. arr: [],
  155. tab: '',
  156. age: 0,
  157. birthDate: ''
  158. }
  159. },
  160. onLoad(e) {
  161. let that = this
  162. that.XCXIsSelect = that.$queue.getData('XCXIsSelect');
  163. uni.getLocation({
  164. type: 'gcj02',
  165. geocode: true, //设置该参数为true可直接获取经纬度及城市信息
  166. success: function(res) {
  167. console.log(res, '地理位置')
  168. that.latitude = res.latitude
  169. that.longitude = res.longitude
  170. uni.setStorageSync('latitude', res.latitude)
  171. uni.setStorageSync('longitude', res.longitude)
  172. // #ifdef APP-PLUS
  173. that.city = res.address.city
  174. that.selectCity(that.longitude, that.latitude);
  175. uni.setStorageSync('city', res.address.city)
  176. let data = {
  177. num: 1,
  178. size: 10
  179. }
  180. that.getData(data)
  181. // #endif
  182. // #ifdef H5
  183. that.selectCity(that.longitude, that.latitude);
  184. // #endif
  185. // #ifdef MP-WEIXIN
  186. that.selectCity(that.longitude, that.latitude);
  187. // uni.request({
  188. // url: 'https://apis.map.qq.com/ws/geocoder/v1/?location=' + that.latitude +
  189. // ',' + that.longitude + '&key=5DLBZ-QYMR6-334SQ-MOZUI-Z3GVO-SBFB4',
  190. // success(re) {
  191. // if (re.statusCode === 200) {
  192. // let citydata = re.data.result.address_component.city
  193. // // console.log("获取城市名称成功", citydata)/
  194. // that.city = citydata ? citydata : '未知'
  195. // uni.setStorageSync('city', citydata)
  196. // let data = {
  197. // num: 1,
  198. // size: 10
  199. // }
  200. // that.getData(data)
  201. // } else {
  202. // console.log("获取信息失败,请重试!")
  203. // }
  204. // }
  205. // });
  206. // #endif
  207. },
  208. fail: function() {
  209. console.log('获取地址失败')
  210. }
  211. })
  212. // 获取邀请码保存到本地
  213. if (e.invitation) {
  214. that.$queue.setData('inviterCode', e.invitation);
  215. }
  216. if (this.myId) {
  217. that.$Request.getT('/app/common/type/250').then(res => { //技师完成通知
  218. if (res.code == 0) {
  219. if (res.data && res.data.value) {
  220. that.arr.push(res.data.value)
  221. }
  222. }
  223. })
  224. that.$Request.getT('/app/common/type/248').then(res => { //技师取消通知
  225. if (res.code == 0) {
  226. if (res.data && res.data.value) {
  227. that.arr.push(res.data.value)
  228. }
  229. }
  230. })
  231. }
  232. },
  233. onShow() {
  234. let that = this
  235. that.city = uni.getStorageSync('city') ? uni.getStorageSync('city') : '请选择城市'
  236. that.getBannerList()
  237. that.getGrid()
  238. // that.getRenZheng()
  239. that.token = uni.getStorageSync('token')
  240. if (uni.getStorageSync('token')) {
  241. that.getIsVip()
  242. }
  243. that.myId = uni.getStorageSync('userId')
  244. // #ifdef MP-WEIXIN
  245. //订阅
  246. if (that.myId) {
  247. if (this.showModal) {
  248. this.openMsg()
  249. }
  250. }
  251. // #endif
  252. let data = {
  253. num: 1,
  254. size: 10
  255. }
  256. that.getData(data)
  257. // that.mescroll.resetUpScroll()
  258. },
  259. methods: {
  260. selectCity(longitude, latitude) {
  261. this.$Request.get('/app/Login/selectCity?lat=' + latitude + '&lng=' + longitude).then(res => {
  262. if (res.code == 0) {
  263. this.city = res.data.city ? res.data.city : '未知'
  264. uni.setStorageSync('city', res.data.city)
  265. let data = {
  266. num: 1,
  267. size: 10
  268. }
  269. this.getData(data)
  270. }
  271. });
  272. },
  273. // 开启订阅消息
  274. openMsg() {
  275. console.log('订阅消息')
  276. var that = this
  277. uni.getSetting({
  278. withSubscriptions: true, //是否获取用户订阅消息的订阅状态,默认false不返回
  279. success(ret) {
  280. console.log(ret.subscriptionsSetting, '------------------')
  281. // if (ret.subscriptionsSetting.itemSettings && Object.keys(ret.subscriptionsSetting.itemSettings).length == 2) {
  282. if (ret.subscriptionsSetting.itemSettings) {
  283. uni.setStorageSync('sendMsg', true)
  284. uni.openSetting({ // 打开设置页
  285. success(rea) {
  286. console.log(rea.authSetting)
  287. }
  288. });
  289. } else { // 用户没有点击“总是保持以上,不再询问”则每次都会调起订阅消息
  290. uni.setStorageSync('sendMsg', false)
  291. uni.showModal({
  292. title: '提示',
  293. content: '为了更好的体验,请绑定消息推送',
  294. confirmText: '确定',
  295. cancelText: '取消',
  296. success: function(res) {
  297. if (res.confirm) {
  298. wx.requestSubscribeMessage({
  299. tmplIds: that.arr,
  300. success(re) {
  301. var datas = JSON.stringify(re);
  302. if (datas.indexOf("accept") != -1) {
  303. console.log(re)
  304. // uni.setStorageSync('sendMsg', true)
  305. }
  306. },
  307. fail: (res) => {
  308. console.log(res)
  309. }
  310. })
  311. // uni.setStorageSync('sendMsg', true)
  312. that.showModal = false
  313. } else if (res.cancel) {
  314. console.log('取消')
  315. // uni.setStorageSync('sendMsg', false)
  316. that.showModal = true
  317. }
  318. }
  319. })
  320. }
  321. }
  322. })
  323. },
  324. getIsVip() {
  325. this.$Request.get("/app/UserVip/isUserVip").then(res => {
  326. if (res.code == 0) {
  327. this.isVip = res.data
  328. uni.setStorageSync('isVIP', res.data)
  329. }
  330. });
  331. },
  332. /*下拉刷新的回调 */
  333. downCallback() {
  334. // 这里加载你想下拉刷新的数据, 比如刷新轮播数据
  335. // loadSwiper();
  336. // 下拉刷新的回调,默认重置上拉加载列表为第一页 (自动执行 page.num=1, 再触发upCallback方法 )
  337. // this.$refs.uDropdown.close();
  338. this.mescroll.resetUpScroll()
  339. },
  340. /*上拉加载的回调: 其中page.num:当前页 从1开始, page.size:每页数据条数,默认10 */
  341. upCallback(page) {
  342. this.getData(page)
  343. },
  344. getData(page) {
  345. let data = {
  346. // id: curTab,
  347. page: page.num,
  348. limit: page.size,
  349. status: 1,
  350. // isRecommend: num,
  351. condition: this.value1, //智能优选
  352. by: this.value2, //销量
  353. authentication: this.value3, //价格
  354. latitude: this.latitude,
  355. longitude: this.longitude,
  356. city: this.city
  357. }
  358. this.$Request.get("/app/artificer/selectMassageTypePage", data).then(res => {
  359. this.mescroll.endBySize(res.data.list.length, res.data.list)
  360. this.loading = false;
  361. if (res.code == 0) {
  362. if (page.num == 1) {
  363. this.orderList = res.data.list
  364. for (let i = 0; i < this.orderList.length; i++) {
  365. this.orderList[i].labels = this.orderList[i].labels.split(",");
  366. }
  367. } else {
  368. this.orderList = [...this.orderList, ...res.data.list]
  369. for (let i = 0; i < this.orderList.length; i++) {
  370. this.orderList[i].labels = this.orderList[i].labels.split(",");
  371. }
  372. }
  373. }
  374. this.mescroll.endSuccess(res.data.list.length); // 隐藏加载状态栏
  375. }).catch(() => {
  376. //联网失败, 结束加载
  377. this.mescroll.endErr();
  378. });
  379. // this.getClassfly()
  380. this.getBannerList()
  381. this.getGrid()
  382. },
  383. // 切换菜单
  384. tabChange() {
  385. if (uni.getStorageSync('sendMsg')) {
  386. wx.requestSubscribeMessage({
  387. tmplIds: this.arr,
  388. success(re) {
  389. var datas = JSON.stringify(re);
  390. if (datas.indexOf("accept") != -1) {}
  391. },
  392. fail: (res) => {
  393. console.log(res)
  394. }
  395. })
  396. }
  397. this.defaultIndex = [0, 0, 0]
  398. // this.$refs.uDropdown.close();
  399. // this.orderList = []; // 置空列表,显示加载进度条
  400. this.mescroll.resetUpScroll()
  401. },
  402. // 筛选
  403. change(e) {
  404. console.log(e)
  405. this.value1 = e[0][0].value
  406. this.value3 = e[1][0].value
  407. this.value2 = e[2][0].value
  408. this.mescroll.resetUpScroll()
  409. },
  410. // 选择城市
  411. goSelectCity() {
  412. uni.navigateTo({
  413. url: '/pages/index/citys/citys'
  414. });
  415. },
  416. // 跳转游戏列表
  417. goNav(url) {
  418. if (uni.getStorageSync('sendMsg')) {
  419. wx.requestSubscribeMessage({
  420. tmplIds: this.arr,
  421. success(re) {
  422. var datas = JSON.stringify(re);
  423. if (datas.indexOf("accept") != -1) {
  424. console.log(re)
  425. }
  426. },
  427. fail: (res) => {
  428. console.log(res)
  429. }
  430. })
  431. }
  432. if (url.indexOf('/pages/') !== -1) {
  433. uni.navigateTo({
  434. url
  435. });
  436. } else {
  437. //#ifndef H5
  438. uni.navigateTo({
  439. url: '/pages/index/webView?url=' + url
  440. });
  441. //#endif
  442. //#ifdef H5
  443. window.location.href = url;
  444. //#endif
  445. }
  446. },
  447. //获取轮播图
  448. getBannerList() {
  449. this.$Request.get("/app/banner/selectBannerList", {
  450. classify: 1
  451. }).then(res => {
  452. if (res.code == 0) {
  453. this.swiperList = res.data
  454. }
  455. });
  456. },
  457. // 获取金刚区分类
  458. getGrid() {
  459. this.$Request.get("/app/banner/selectBannerList", {
  460. classify: 2
  461. }).then(res => {
  462. if (res.code == 0) {
  463. this.gridData = res.data
  464. // console.log(this.gridData, ';;;;;;')
  465. }
  466. });
  467. },
  468. // 跳转搜索
  469. goSearch(index) {
  470. if (uni.getStorageSync('sendMsg')) {
  471. console.log('授权+1')
  472. wx.requestSubscribeMessage({
  473. tmplIds: this.arr,
  474. success(re) {
  475. var datas = JSON.stringify(re);
  476. if (datas.indexOf("accept") != -1) {
  477. console.log(re)
  478. }
  479. },
  480. fail: (res) => {
  481. console.log(res)
  482. }
  483. })
  484. }
  485. uni.navigateTo({
  486. url: '/pages/index/search/index?index=' + index
  487. });
  488. },
  489. // 跳转订单
  490. goOrder(e) {
  491. console.log('授权', uni.getStorageSync('sendMsg'))
  492. if (uni.getStorageSync('sendMsg')) {
  493. wx.requestSubscribeMessage({
  494. tmplIds: this.arr,
  495. success(re) {
  496. var datas = JSON.stringify(re);
  497. if (datas.indexOf("accept") != -1) {
  498. console.log(re)
  499. }
  500. },
  501. fail: (res) => {
  502. console.log(res)
  503. }
  504. })
  505. }
  506. if (this.token) {
  507. uni.navigateTo({
  508. url: '/pages/index/order/order?massageTypeId=' + e.massageTypeId
  509. });
  510. } else {
  511. uni.navigateTo({
  512. url: '/pages/public/login'
  513. });
  514. }
  515. },
  516. }
  517. }
  518. </script>
  519. <style lang="scss">
  520. page {
  521. background-color: #FFFFFF;
  522. }
  523. .bg {
  524. background: #FFFFFF;
  525. }
  526. .sticky-tabs {
  527. z-index: 990;
  528. position: sticky;
  529. top: var(--window-top);
  530. // background-color: #fff;
  531. }
  532. /* // 使用mescroll-uni,则top为0 */
  533. .mescroll-uni,
  534. /deep/.mescroll-uni {
  535. .sticky-tabs {
  536. top: 0;
  537. }
  538. }
  539. .demo-tip {
  540. padding: 18upx;
  541. font-size: 24upx;
  542. text-align: center;
  543. }
  544. .line_s {
  545. display: inline-flex;
  546. width: 10rpx;
  547. height: 10rpx;
  548. background: #1AD566;
  549. border-radius: 50%;
  550. margin-right: 10rpx;
  551. }
  552. .line_x {
  553. display: inline-flex;
  554. width: 10rpx;
  555. height: 10rpx;
  556. background: #000000;
  557. border-radius: 50%;
  558. margin-right: 10rpx;
  559. }
  560. .box {
  561. // border: 3rpx solid #005dff;
  562. background: #E8FAE1;
  563. color: #2FB57A;
  564. padding: 5rpx 15rpx;
  565. font-size: 24upx;
  566. letter-spacing: 2rpx;
  567. border-radius: 8rpx;
  568. // margin-top: 10rpx;
  569. margin-right: 8upx;
  570. }
  571. </style>