index.vue 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585
  1. <template>
  2. <view class="goods-detail">
  3. <navbarTransparent :title="page.title" />
  4. <!-- swiper -->
  5. <view class="home-swiper">
  6. <uni-swiper-dot :mode="mode" :info="info" :current="current1" :dots-styles="dotsStyles">
  7. <swiper class="swiper-box" @change="change1" circular>
  8. <swiper-item v-for="(item ,index) in info" :key="index" v-if="resource_type == 1 ">
  9. <view class="swiper-item">
  10. <image style="width: 100vw;height:100vw;" :src="item.img" mode="aspectFill"></image>
  11. </view>
  12. </swiper-item>
  13. <swiper-item v-if="resource_type == 2 ">
  14. <view class="swiper-item">
  15. <video class="baner-video" id="myVideo" ref="myVideo" style="width: 100%; height: 564rpx;"
  16. :src="video_url" controls :enable-progress-gesture="false">
  17. </video>
  18. </view>
  19. </swiper-item>
  20. </swiper>
  21. </uni-swiper-dot>
  22. </view>
  23. <view style="background-color: #f9f9f9;">
  24. <!-- 价格 -->
  25. <view class="price">
  26. <view class="price-top" v-if="produceType == 1 && productDetail.price !=0 ">
  27. <text>¥</text>
  28. <text>{{productDetail.price}}</text>
  29. </view>
  30. <view class="price-top" v-if="produceType == 2">
  31. <text>{{productDetail.price}}</text>
  32. <text>积分</text>
  33. </view>
  34. <text class="price-text">{{productDetail.name}}</text>
  35. <view @click="goOther" class="price-banner" :style="{backgroundImage:'url('+backImageUrl+')'}" v-if="produceType == 1">
  36. <text>加入IHG优悦会会员享受更多福利</text>
  37. <image style="width: 12rpx;height: 20rpx;" src="/static/icon/right02.png" mode=""></image>
  38. </view>
  39. <view @click="goOtherIntegral" class="price-banner" :style="{backgroundImage:'url('+backImageUrl+')'}" v-if="produceType == 2">
  40. <text>加入IHG优悦会会员享受更多福利</text>
  41. <image style="width: 12rpx;height: 20rpx;" src="/static/icon/right02.png" mode=""></image>
  42. </view>
  43. <!--规格-->
  44. <view class="price-specs" @click="Recipientopen()">
  45. <view class="price-specs-left">
  46. <text>选择</text>
  47. </view>
  48. <view class="price-specs-main" @click="Recipientopen()">
  49. <text>{{showAttr||'请选择规格'}}</text>
  50. </view>
  51. <view @click="Recipientopen()">
  52. <image style="width: 12rpx;height: 20rpx;" src="/static/icon/right03.png" mode=""></image>
  53. </view>
  54. </view>
  55. </view>
  56. <!--酒店信息 -->
  57. <view class="about">
  58. <text class="about-title">可购买酒店信息</text>
  59. <text class="about-name">{{hotelDetail.name}}</text>
  60. <view class="about-address">
  61. <text style="margin-right:20rpx ;">地址:</text>
  62. <text>{{hotelDetail.address?hotelDetail.address:""}}</text>
  63. </view>
  64. <view class="about-phone">
  65. <text style="margin-right:20rpx ;">电话:</text>
  66. <text>{{hotelDetail.phone?hotelDetail.phone:""}}</text>
  67. </view>
  68. <view class="about-all">
  69. <text @click="goGoodsHotel(product_id)" style="margin-right: 16rpx;">全部酒店</text>
  70. <image @click="goGoodsHotel(product_id)" style="width: 12rpx;height: 20rpx;"
  71. src="/static/icon/right04.png" mode=""></image>
  72. </view>
  73. </view>
  74. <!-- 产品介绍 -->
  75. <view class="produce">
  76. <view class="produce-title">
  77. <text>产品简介</text>
  78. </view>
  79. <view class="produce-text">
  80. <u-parse :content="productDetail.details"></u-parse>
  81. </view>
  82. </view>
  83. </view>
  84. <view class="buy-btn">
  85. <view class="buy-btn-left" @click="goHome">
  86. <image style="width: 40rpx;height: 42rpx;" src="/static/icon/home01.png" mode=""></image>
  87. <text>首页</text>
  88. </view>
  89. <view class="buy-btn-right" @click="goIntegralOrder" v-if="produceType==1">
  90. <text>立即购买</text>
  91. </view>
  92. <view v-if="produceType==2" class="buy-btn-right" @click="goProductChange(product_id,flavorIsActive)">
  93. <text>立即兑换</text>
  94. </view>
  95. </view>
  96. <view style="height: 90px;background-color: #f9f9f9;"></view>
  97. <!-- 选择规格 -->
  98. <uni-popup ref="Recipient" type="bottom" mask-background-color=" rgba(0,0,0,0.3);">
  99. <view class="pop">
  100. <view class="pop-price">
  101. <view class="pop-price-left">
  102. <image style="width: 180rpx;height: 136rpx; border-radius:12rpx ;"
  103. :src="productDetail.cover_img" mode=""></image>
  104. <view class="pop-price-left-money" v-if="produceType == 1 && productDetail.price !=0 ">
  105. <text>¥</text>
  106. <text>{{productDetail.price}}</text>
  107. </view>
  108. <view class="pop-price-left-money" v-if="produceType == 2">
  109. <text>{{productDetail.price}}</text>
  110. <text>积分</text>
  111. </view>
  112. </view>
  113. <image style="width: 52rpx;height: 52rpx;" src="/static/icon/close01.png" mode=""
  114. @click="Recipientclose"></image>
  115. </view>
  116. <view class="pop-flavor" v-for="i in attr_groups" :key="i.attr_group_id" style="margin-top: 44rpx;">
  117. <text>{{i.attr_group_name}}</text>
  118. <view class="tab_flavor">
  119. <view class="flavorTitle-item"
  120. :class="{'flavorTitle-item-active':flavorIsActive[i.attr_group_name] === item.attr_name}"
  121. v-for="(item,index) in i.attr_list" :key="item.attr_id"
  122. @click="flavorchecked(item.attr_name,i.attr_group_name)">
  123. <view :class="{'active-flavor':flavorIsActive[i.attr_group_name] === item.attr_name}">
  124. {{item.attr_name}}
  125. </view>
  126. </view>
  127. </view>
  128. </view>
  129. </view>
  130. <view class="purchase" v-if="produceType == 1" @click="goIntegralOrder">
  131. <view class="purchase-btn">立即购买</view>
  132. </view>
  133. <view class="purchase" v-if="produceType == 2" @click="selectSpecs(product_id,flavorIsActive)">
  134. <view class="purchase-btn">立即兑换</view>
  135. <!-- <view class="purchase-btn">确认</view> -->
  136. </view>
  137. </uni-popup>
  138. <!-- 二维码购买 -->
  139. <!-- <uni-popup ref="codePurchase" type="center">
  140. <view class="code-purchase">
  141. <view class="title"><text>识别下方二维码即可购买</text></view>
  142. <view style="margin-left:30rpx;width: 580rpx;height: 2rpx;background: #F0F0F0;"></view>
  143. <view class="img">
  144. <image src="http://t9.9026.com/imgs/Kudosbg.png"></image>
  145. </view>
  146. <view class="btn">
  147. <view class="cancel" @click="dialogClose"><text>取消</text></view>
  148. <view class="download" @click="dialogConfirm"><text>保存图片</text></view>
  149. </view>
  150. </view>
  151. </uni-popup> -->
  152. <!-- 弹出层/核销码 -->
  153. <dialogPanel ref="dialogPanel"/>
  154. </view>
  155. </template>
  156. <script>
  157. import navbarTransparent from "@/components/extra/navbarTransparent.vue"
  158. export default {
  159. components: {
  160. navbarTransparent
  161. },
  162. data() {
  163. return {
  164. //积分跳转h5,小程序,其他页面
  165. jump_type_integral: '',
  166. jump_config_integral: {},
  167. //产品跳转h5,小程序,其他页面
  168. jump_type_vip: '',
  169. jump_config_vip: {},
  170. //加入会员广告配置
  171. advise: '',
  172. jump_type: '',
  173. jump_config: '',
  174. resource_type: '',
  175. //1:第三方产品2:积分兑换产品
  176. produceType: '',
  177. // 规格
  178. specsText: '',
  179. specs: {
  180. pack: '',
  181. weight: '',
  182. flavor: '',
  183. },
  184. // 产品详情
  185. productDetail: '',
  186. // 酒店详情
  187. hotelDetail: '',
  188. // 产品id
  189. product_id: '',
  190. //激活指定table菜单
  191. isActive: 0,
  192. flavorIsActive: {},
  193. weightIsActive: 0,
  194. packIsActive: 0,
  195. backImageUrl: require('../../../static/icon/add01.png'),
  196. //轮播图
  197. info: [{
  198. img: 'http://t9.9026.com/imgs/swiper01.png',
  199. name: '酒店预订'
  200. }, ],
  201. dotsStyles: {
  202. backgroundColor: 'rgba(255, 255, 255, .3)',
  203. border: '1px rgba(255, 255, 255, .3) solid',
  204. color: '#fff',
  205. selectedBackgroundColor: 'rgba(255, 255, 255, 1)',
  206. selectedBorder: '1px rgba(255, 255, 255, 1) solid'
  207. },
  208. //指示点显示位置
  209. current1: 0,
  210. //指示点模式
  211. mode: 'dot',
  212. attr_groups: [],
  213. page: {
  214. title: '产品详情'
  215. },
  216. sku: {
  217. keys: [],
  218. }
  219. }
  220. },
  221. onReady: function() {
  222. this.videoContext = uni.createVideoContext('myVideo')
  223. },
  224. onLoad(op) {
  225. const {
  226. id,
  227. type
  228. } = op;
  229. this.admin = this.$store.getters.userInfo
  230. this.product_id = id
  231. this.produceType = type
  232. this.getProductDetail(this.product_id, true)
  233. //vip跳转
  234. this.advise = this.$store.getters.allset.add_member
  235. this.jump_type_vip = this.advise.value.product_jump_type
  236. if (this.jump_type_vip == 1) {
  237. this.jump_config_vip = this.advise.value.product_h5_url
  238. } else if (this.jump_type_vip == 2) {
  239. this.jump_config_vip.appid = this.advise.value.product_appid
  240. this.jump_config_vip.path = this.advise.value.product_path
  241. } else if (this.jump_type_vip == 3) {
  242. this.jump_config_vip = this.advise.value.product_other_path
  243. }
  244. this.jump_type_integral = this.advise.value.integral_jump_type
  245. if (this.jump_type_integral == 1) {
  246. this.jump_config_integral = this.advise.value.integral_h5_url
  247. } else if (this.jump_type_integral == 2) {
  248. this.jump_config_integral.appid = this.advise.value.integral_appid
  249. this.jump_config_integral.path = this.advise.value.integral_path
  250. } else if (this.jump_type_integral == 3) {
  251. this.jump_config_integral = this.advise.value.integral_other_path
  252. }
  253. },
  254. computed: {
  255. showAttr: function() {
  256. if (this.flavorIsActive.length <= 0) return false;
  257. let text = '';
  258. for (const k in this.flavorIsActive) {
  259. text += `${k}-${this.flavorIsActive[k]},`
  260. }
  261. return text.substr(0, text.length - 1);
  262. },
  263. selectedHotelId: function() {
  264. return this.$store.state.tab.selectedHotelId;
  265. }
  266. },
  267. methods: {
  268. //显示所选规格
  269. //获取当前页面路径
  270. getPageUrl() {
  271. const pages = getCurrentPages();
  272. if (pages.length == 1) {
  273. const currentPage = pages[0];
  274. console.log(currentPage.options, '--------->currentPage.options')
  275. let pageUrl = `/${currentPage.route}?type=${currentPage.options.type}`;
  276. return pageUrl
  277. console.log('当前页面url:', pageUrl);
  278. } else {
  279. const currentPage = pages[pages.length - 1];
  280. console.log(currentPage.options, '--------->currentPage.options')
  281. let pageUrl = `/${currentPage.route}?type=${currentPage.options.type}`;
  282. return pageUrl
  283. console.log('当前页面url:', pageUrl);
  284. }
  285. },
  286. // 跳转其他小程序
  287. jumpHAppID(id, urls) {
  288. if (id == 1) {
  289. const url = urls; // 跳转的外链
  290. const navtitle = 'H5'; // 这个标题是你自己可以设置的
  291. uni.navigateTo({
  292. // 跳转到webview页面
  293. url: `/pages/webview/webview?url=${url}&nav=${navtitle}`,
  294. success: () => {
  295. console.log('成功')
  296. },
  297. fail: (e) => {
  298. console.log(e, "失败")
  299. }
  300. });
  301. } else if (id == 2) {
  302. let _this = this
  303. let obj = urls;
  304. console.log(obj, '----->obj');
  305. wx.navigateToMiniProgram({
  306. appId: `${obj.appid}`, //appid
  307. path: `${obj.path}`, //path
  308. extraData: { //参数
  309. foo: 'bar'
  310. },
  311. // envVersion: 'develop', //开发版develop 开发版 trial 体验版 release 正式版
  312. success(res) {
  313. let page = _this.getPageUrl()
  314. let user_id = ''
  315. if (_this.admin != null) {
  316. user_id = _this.admin.id
  317. } else {
  318. user_id = 0
  319. }
  320. _this.$api.my.userMemberAdd({
  321. user_id,
  322. page,
  323. }).then(res => {
  324. console.log(res.data);
  325. })
  326. // 打开成功
  327. },
  328. fail(e) {
  329. console.log(e, '失败')
  330. }
  331. })
  332. } else if (id == 3) {
  333. uni.redirectTo({
  334. url: urls,
  335. fail: (err) => {
  336. uni.reLaunch({
  337. url: urls
  338. })
  339. }
  340. })
  341. }
  342. },
  343. // 跳转其他小程序
  344. goOther() {
  345. let _this = this
  346. this.jumpHAppID(this.jump_type_vip, this.jump_config_vip)
  347. },
  348. goOtherIntegral(){
  349. let _this = this
  350. this.jumpHAppID(this.jump_type_integral, this.jump_config_integral)
  351. },
  352. //视频自动播放
  353. openVideoPlay() {
  354. this.videoContext.play()
  355. },
  356. // 获取商品详情
  357. getProductDetail(product_id, init = false) {
  358. this.$store.commit("tab/SET_SELECTEDHOTELId", 0)
  359. this.$api.product.getProductDetail({
  360. product_id: product_id
  361. }).then(res => {
  362. if (res.code == 0 && res.data) {
  363. this.productDetail = res.data
  364. this.info = JSON.parse(res.data.img_urls).map(item => {
  365. return {
  366. img: item
  367. }
  368. })
  369. //跳转h5和小程序
  370. this.jump_type = res.data.jump_type,
  371. this.jump_config = res.data.jump_config
  372. //banner展示视频或者图片
  373. this.resource_type = res.data.resource_type
  374. this.video_url = res.data.video_url
  375. //视频自动播放
  376. this.openVideoPlay()
  377. //规格对接
  378. this.attr_groups = JSON.parse(res.data.attr_group)
  379. //获取默认酒店
  380. const hotel_ids = JSON.parse(res.data.hotel_ids);
  381. if ((hotel_ids.constructor == Array) && (hotel_ids.length > 0)) {
  382. this.$store.commit("tab/SET_SELECTEDHOTELId", hotel_ids[0])
  383. }
  384. //
  385. const sku = JSON.parse(res.data.sku);
  386. this.sku.keys = Object.keys(sku.attrs);
  387. this.sku.sku = sku.sku;
  388. //首次默认选中第一个规格
  389. if (init) {
  390. this.attr_groups.forEach(item => {
  391. this.flavorchecked(item.attr_list[0]?.attr_name, item.attr_group_name)
  392. })
  393. }
  394. }
  395. })
  396. },
  397. // 获取酒店详情
  398. getHotelDetail(id) {
  399. this.$api.hotel.getHotelDetail({
  400. hotel_id: id
  401. }).then(res => {
  402. this.hotelDetail = res.data
  403. })
  404. },
  405. //跳转酒店列表
  406. goGoodsHotel(id) {
  407. uni.navigateTo({
  408. url: '/pages/goods/goods-hotel/index?product_id=' + id
  409. })
  410. },
  411. //首页
  412. goHome() {
  413. uni.switchTab({
  414. url: '/pages/index/index'
  415. })
  416. },
  417. //二维码购买确认按钮
  418. dialogConfirm() {
  419. console.log('确认');
  420. this.codePurchaseClose()
  421. },
  422. //二维码购买取消按钮
  423. dialogClose() {
  424. console.log('取消');
  425. this.codePurchaseClose()
  426. },
  427. //菜单index切换
  428. checked(index) {
  429. this.isActive = index
  430. },
  431. getAttrListId(name){
  432. for(let k in this.attr_groups){
  433. for(let k1 in this.attr_groups[k].attr_list){
  434. const v = this.attr_groups[k].attr_list[k1];
  435. if(v.attr_name == name){
  436. return v.attr_id;
  437. break;
  438. }
  439. }
  440. }
  441. },
  442. // 口味切换
  443. flavorchecked(index, name) {
  444. this.$set(this.flavorIsActive, name, index)
  445. this.specs.flavor = name
  446. let resTemp = []
  447. for(let k in this.flavorIsActive){
  448. resTemp.push(this.getAttrListId(this.flavorIsActive[k]));
  449. }
  450. const attr = resTemp.join(":");
  451. for(let k in this.productDetail.product_attr){
  452. if(this.productDetail.product_attr[k].attr == attr){
  453. const price = this.productDetail.product_attr[k].price;
  454. this.productDetail.price = price;
  455. this.productDetail.integral = price;
  456. break;
  457. }
  458. }
  459. },
  460. // // 重量切换
  461. // weightchecked(index,name) {
  462. // this.weightIsActive = index
  463. // this.specs.weight=name
  464. // console.log(this.specs.weight);
  465. // },
  466. // // 包装切换
  467. // packchecked(index,name) {
  468. // this.packIsActive = index
  469. // this.specs.pack=name
  470. // console.log(this.specs.pack);
  471. // },
  472. // 立即兑换
  473. selectSpecs(id, flavorIsActive) {
  474. const resArr = [];
  475. outer: for (const k in this.flavorIsActive) {
  476. inner: for (const i in this.attr_groups) {
  477. if (this.attr_groups[i].attr_group_name == k) {
  478. laster: for (const l in this.attr_groups[i].attr_list) {
  479. if (this.attr_groups[i].attr_list[l].attr_name == this.flavorIsActive[k]) {
  480. resArr.push(this.attr_groups[i].attr_list[l].attr_id);
  481. break inner;
  482. }
  483. }
  484. }
  485. }
  486. }
  487. const selectedIds = resArr.join(':');
  488. console.log(this.productDetail.integral);
  489. uni.navigateTo({
  490. url: `/pages/my/integral/integralOrder?product_id=${this.productDetail.id}&attr=${selectedIds}&integral=${this.productDetail.integral}&attrName=${this.showAttr}`
  491. })
  492. this.Recipientclose()
  493. },
  494. Recipientopen() {
  495. this.$refs.Recipient.open('bottom')
  496. },
  497. Recipientclose() {
  498. this.$refs.Recipient.close()
  499. },
  500. codePurchaseClose() {
  501. this.$refs.codePurchase.close()
  502. },
  503. // 切换轮播图指示点
  504. change1(e) {
  505. this.current1 = e.detail.current;
  506. },
  507. //积分兑换
  508. goProductChange(id, flavorIsActive) {
  509. this.Recipientopen()
  510. // const resArr = [];
  511. // outer: for (const k in this.flavorIsActive) {
  512. // inner: for (const i in this.attr_groups) {
  513. // if (this.attr_groups[i].attr_group_name == k) {
  514. // laster: for (const l in this.attr_groups[i].attr_list) {
  515. // if (this.attr_groups[i].attr_list[l].attr_name == this.flavorIsActive[k]) {
  516. // resArr.push(this.attr_groups[i].attr_list[l].attr_id);
  517. // break inner;
  518. // }
  519. // }
  520. // }
  521. // }
  522. // }
  523. // const selectedIds = resArr.join(':');
  524. // uni.navigateTo({
  525. // url: `/pages/my/integral/integralOrder?product_id=${this.productDetail.id}&attr=${selectedIds}&integral=${this.productDetail.integral}&attrName=${this.showAttr}`
  526. // })
  527. },
  528. // 跳转积分兑换
  529. goIntegralOrder() {
  530. if(this.hotelDetail.buy_jump_type == 3){
  531. this.$refs.dialogPanel.show(this.hotelDetail.buy_jump_config);
  532. return;
  533. }
  534. this.$utils.jump({
  535. jump_type: this.hotelDetail.buy_jump_type,
  536. jump_config: this.hotelDetail.buy_jump_config,
  537. attr: JSON.stringify(this.flavorIsActive)
  538. })
  539. },
  540. },
  541. watch: {
  542. selectedHotelId(newValue) {
  543. newValue && this.getHotelDetail(newValue);
  544. }
  545. }
  546. }
  547. </script>
  548. <style lang="scss" scoped src="./index.scss"></style>
  549. <style lang="scss">
  550. .produce-text img {
  551. width: 100%;
  552. object-fit: fill;
  553. }
  554. </style>