goods_detail.vue 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657
  1. <template>
  2. <view>
  3. <uni-nav-bar :fixed="true" title="咖啡屋" left-icon="left" backgroundColor="rgb(0,0,0,0)" :border="false" @clickLeft="onHome"/>
  4. <!-- 详情弹窗 -->
  5. <view class=" detail-pop">
  6. <!-- <image src="../../static/icon_5.png" mode="aspectFit" class="detail-close-btn"
  7. @click="showGoodsDetail"></image>-->
  8. <!-- <scroll-view scroll-y="true" class="content-block"> -->
  9. <image :src="URL+goodsDetail.thumb" mode="aspectFill" class="goods-img"></image>
  10. <!-- <view class="" style="padding: 0 10rpx;">
  11. <rich-text :nodes="goodsDetail.description"></rich-text>
  12. </view> -->
  13. <!-- </scroll-view> -->
  14. <view class="btm-block">
  15. <!-- <view class="goods-name ft28" style="font-size: 34rpx;">{{goodsDetail.name}}</view> -->
  16. <view class="flex box-pack-between">
  17. <view class="goods-name ft28" style="font-size: 34rpx;flex: 1;">{{goodsDetail.name}}</view>
  18. <view class="sales ft26 flex-center">已售:{{goodsDetail.fictitious?goodsDetail.fictitious:0}}</view>
  19. </view>
  20. <view class="goods-desc">{{goodsDetail.desc}}</view>
  21. <view class="flex flex-y-center flex-nowarp box-pack-between">
  22. <view class="">
  23. <view class="flex flex-nowarp flex-y-baseline">
  24. <view class="price">¥{{goodsDetail.price}}</view>
  25. <view class="unit">/{{goodsDetail.unit}}</view>
  26. </view>
  27. <view class="price" v-if="goodsDetail.is_rebate==1">
  28. <view class="rebate-border">
  29. {{goodsDetail.rebate}}
  30. </view>
  31. </view>
  32. </view>
  33. <view>
  34. <view class="add-car-btn" :style="{'background-color':setColor}" v-if="goodsDetail.is_gg == 2"
  35. @click="showSpec(goodsDetail.id)">选规格</view>
  36. <view class="add-car-btn" :data-i='goodsDetail.num' :style="{'background-color':setColor}"
  37. v-else-if="goodsDetail.num == 0"
  38. @click="changeNum(goodsDetail.category_id,goodsDetail.id,2,'goods','',goodsDetail.price,goodsDetail.many_rebate,goodsDetail.is_rebate)">
  39. 加入购物车
  40. </view>
  41. <block v-else>
  42. <view class="goods-num-block flex flex-x-end flex-y-center" :style="{color:setColor}">
  43. <view class="num-btn num-btn-1 iconfont icon-jian1"
  44. @click="changeNum(goodsDetail.category_id,goodsDetail.id,1,'goods','',goodsDetail.price,goodsDetail.many_rebate,goodsDetail.is_rebate)">
  45. </view>
  46. <view class="num">{{goodsDetail.num}}</view>
  47. <view class="num-btn num-btn-2 iconfont icon-jia1"
  48. @click="changeNum(goodsDetail.category_id,goodsDetail.id,2,'goods','',goodsDetail.price,goodsDetail.many_rebate,goodsDetail.is_rebate)">
  49. </view>
  50. </view>
  51. <view class="ft24 many_rebate" v-if="goodsDetail.many_rebate>0 && goodsDetail.is_rebate==1">
  52. {{goodsDetail.many_rebate}}{{goodsDetail.unit}}起购
  53. </view>
  54. </block>
  55. </view>
  56. </view>
  57. </view>
  58. <view class="mask flex flex-column flex-nowarp flex-x-center flex-y-center" v-show="maskPop">
  59. <!-- 规格弹窗 -->
  60. <block v-if="specPop">
  61. <view class="pop-block spec-pop">
  62. <view class="title">{{goodsDetail.name}}</view>
  63. <scroll-view scroll-y="true" class="content-block">
  64. <view class="content">
  65. <block v-for="(item,index) in goodsDetail.edit_value" :key="index">
  66. <view class="spec-cat-title">
  67. <text>{{item.spec_name}}</text>
  68. <text style="font-size:24rpx;color:#aaa">(仅单选)</text>
  69. </view>
  70. <view class="spec-list flex">
  71. <view v-for="(spec,specIndex) in item.spec" :key="specIndex"
  72. @click="chooseSpec(index,specIndex)"
  73. :class="['spec-item',spec.active?'active':'']"
  74. :style="[spec.active?{'background-color':setColor,'border-color':setColor}:'']">
  75. {{spec.name}}
  76. <block v-if="spec.price">¥{{spec.price}}</block>
  77. </view>
  78. </view>
  79. </block>
  80. </view>
  81. </scroll-view>
  82. <view class="btm-block flex flex-y-baseline flex-nowarp">
  83. <view class="flex flex-nowarp flex-y-baseline">
  84. <view class="price">¥{{goodsDetail.spec_price}}</view>
  85. <view class="unit">/{{goodsDetail.unit}}</view>
  86. </view>
  87. <view class="choose-spec-list text-3" v-if="goodsDetail.specName">
  88. ({{goodsDetail.specName}})</view>
  89. <block>
  90. <view class="add-car-btn" :style="{'background-color':setColor}"
  91. v-if="goodsDetail.num == 0"
  92. @click="changeNum(goodsDetail.category_id,goodsDetail.id,2,'spec',goodsDetail.many_rebate,goodsDetail.is_rebate)">
  93. 加入购物车</view>
  94. <view class="goods-num-block flex flex-x-end flex-y-center" v-else
  95. :style="{color:setColor}">
  96. <view class="num-btn num-btn-1 iconfont icon-jian1"
  97. @click="changeNum(goodsDetail.category_id,goodsDetail.id,1,'spec',goodsDetail.many_rebate,goodsDetail.is_rebate)">
  98. </view>
  99. <view class="num">{{goodsDetail.num}}</view>
  100. <view class="num-btn num-btn-2 iconfont icon-jia1"
  101. @click="changeNum(goodsDetail.category_id,goodsDetail.id,2,'spec',goodsDetail.many_rebate,goodsDetail.is_rebate)">
  102. </view>
  103. </view>
  104. </block>
  105. </view>
  106. </view>
  107. <image src="/static/icon_5.png" mode="aspectFit" class="spec-close-btn" @click="showSpec"></image>
  108. </block>
  109. </view>
  110. <shopping-car :carNum="carNum" :isDistance="is_distance" :navBtn="true" :deliveryPrice="delivery_price"
  111. :carTotal="carTotal" :carGoods="carGoods" :userInfo="userInfo" @choosebag="choosebag" :checked="pocket"/>
  112. <view class="detail-title">
  113. -- 商品详情 --
  114. </view>
  115. <view class="detail-content">
  116. <mp-html :content="description" />
  117. <!-- <rich-text :nodes="description"></rich-text> -->
  118. </view>
  119. <view class="hg100">
  120. </view>
  121. </view>
  122. <!-- #ifdef MP-WEIXIN -->
  123. <view v-if="goodsDetail.feedid || goodsDetail.finder" class="flex-row flex-y-center share_commission"
  124. @click="openVideo">
  125. <image src="/static/wx_video.png"></image>
  126. </view>
  127. <!-- #endif -->
  128. </view>
  129. </template>
  130. <script>
  131. import mpHtml from '@/uni_modules/mp-html/components/mp-html/mp-html'
  132. let hideLoading = false;
  133. import {
  134. mapState,
  135. mapMutations
  136. } from 'vuex'
  137. import shoppingCar from '@/components/shoppingCar.vue';
  138. export default {
  139. components: {
  140. shoppingCar
  141. },
  142. data() {
  143. return {
  144. carGoods: [], //购物车商品
  145. carNum: 0, //购物车数量
  146. carTotal: 0, //购物车价格
  147. goodsDetail: {}, //详情数据
  148. URL: getApp().globalData.URL,
  149. description: '', //文本
  150. maskPop: false,
  151. specPop: false,
  152. goodsList: [],
  153. goods_id: '',
  154. is_distance: null,
  155. delivery_price: 0,
  156. pocket: 1,
  157. list: []
  158. }
  159. },
  160. onLoad(e) {
  161. console.log(e, "eeee")
  162. this.goods_id = e.id;
  163. if (e.userInfo & e.store_id & e.setColor & e.systemInfo) {
  164. this.userInfo = e.userInfo;
  165. this.store_id = e.store_id;
  166. this.setColor = e.setColor;
  167. this.systemInfo = e.systemInfo;
  168. this.$store.commit('SET_STORE_ID', e.store_id)
  169. // this.$store.commit('SET_TEEN_INDEX', 1)
  170. //重置默认
  171. this.$store.commit('SET_TABLE_ID', "")
  172. this.$store.commit('SET_CATE_ID', '')
  173. this.$store.dispatch('getSystemStup', e.store_id);
  174. this.$store.dispatch('getOpenid', e.store_id);
  175. this.$store.dispatch('SET_USER_INFO', e.userInfo);
  176. this.$store.dispatch('SET_MONITOR_COLOR', e.setColor);
  177. this.$store.dispatch('SET_SYSTEM', e.systemInfo);
  178. }
  179. this.goodInfo();
  180. uni.setNavigationBarColor({
  181. frontColor: '#ffffff',
  182. backgroundColor: this.setColor,
  183. })
  184. },
  185. onShow() {
  186. this.getDeliveryPrice();
  187. },
  188. onShareAppMessage(e) {
  189. return {
  190. title: this.goodsDetail.name,
  191. path: 'menber/goods_detail?id=' + this.goodsDetail.id,
  192. imageUrl: this.URL + this.goodsDetail.thumb,
  193. }
  194. },
  195. onShareTimeline() {
  196. return {
  197. title: this.goodsDetail.name,
  198. query: `id=${this.goodsDetail.id}&setColor=${this.setColor}&store_id=${this.store_id}&userInfo=${this.userInfo}&systemInfo=${this.systemInfo}`,
  199. imageUrl: this.URL + this.goodsDetail.thumb,
  200. }
  201. },
  202. computed: {
  203. ...mapState(['systemInfo', 'setColor', 'store_id', 'userInfo', 'address'])
  204. },
  205. watch: {
  206. setColor(nVal) {
  207. uni.setNavigationBarColor({
  208. frontColor: '#ffffff',
  209. backgroundColor: nVal,
  210. })
  211. },
  212. address(val) {
  213. this.getDeliveryPrice();
  214. }
  215. },
  216. methods: {
  217. choosebag(index) {
  218. this.pocket = index;
  219. },
  220. onHome(e){
  221. uni.switchTab({
  222. url:'/pages/home/home'
  223. })
  224. },
  225. // 获取配送费
  226. getDeliveryPrice() {
  227. this.$http.request('xcx/getDeliveryPrice', {
  228. lat: this.address.lat || '',
  229. lng: this.address.lng || '',
  230. store_id: this.store_id,
  231. }, "", "", hideLoading).then(res => {
  232. let distance = Number(res.data.distance);
  233. if (distance) {
  234. if (!distance) {
  235. this.is_distance = 2;
  236. return
  237. }
  238. this.delivery_price = Number(res.data.delivery_price);
  239. if (!this.systemInfo.set.number || !distance) {
  240. this.is_distance = 1;
  241. return
  242. }
  243. // 如果大于商家距离is_distance = 2 提出超出距离
  244. if (distance > this.systemInfo.set.number) {
  245. this.is_distance = 2;
  246. } else {
  247. this.is_distance = 1;
  248. }
  249. } else {
  250. this.is_distance = 3;
  251. }
  252. }).catch(err => {})
  253. },
  254. openVideo() {
  255. let goods = this.goodsDetail;
  256. if (goods.feedid && goods.finder) {
  257. wx.openChannelsActivity({
  258. finderUserName: goods.finder,
  259. feedId: goods.feedid,
  260. success: () => {
  261. console.log("打开成功")
  262. }
  263. })
  264. } else {
  265. wx.openChannelsUserProfile({
  266. finderUserName: goods.finder,
  267. success: () => {
  268. console.log("打开成功")
  269. }
  270. })
  271. }
  272. },
  273. //清空购物车
  274. clearCar() {
  275. this.pocket=1
  276. this.goodsDetail.num =0
  277. this.carGoods = []
  278. this.$store.commit('SET_CARGOODS', []) //监听购物车是否有变化
  279. this.carNum = 0
  280. this.carTotal = 0
  281. this.maskPop = false
  282. this.carGoodsPop = false
  283. let goodsList = this.goodsList
  284. for (let i in goodsList) {
  285. goodsList[i].num = 0
  286. for (let j in goodsList[i].goods_list) {
  287. goodsList[i].goods_list[j].num = 0
  288. }
  289. }
  290. this.goodsList = goodsList
  291. },
  292. showSpec() {
  293. if (this.specPop) {
  294. this.maskPop = false
  295. this.specPop = false
  296. return false
  297. }
  298. this.maskPop = true
  299. this.specPop = true
  300. },
  301. goodInfo() {
  302. this.$http.request('xcx/goodinfo', {
  303. goods_id: this.goods_id,
  304. }, "", "", hideLoading).then(res => {
  305. let info = res.data.goods;
  306. if (res.data.goods.description) {
  307. this.description = res.data.goods.description.replace(/\<img/gi,
  308. '<img style="max-width:100%;height:auto" ');
  309. }
  310. let edit_value = info.edit_value
  311. for (let i in edit_value) {
  312. for (let j in edit_value[i].spec) {
  313. edit_value[i].spec[j] = {
  314. 'name': edit_value[i].spec[j],
  315. active: false
  316. }
  317. }
  318. }
  319. info.edit_value = edit_value
  320. info.spec_price = info.price
  321. info.num = 0
  322. info.specName = ""
  323. this.category_id = info.category_id
  324. this.goodsDetail = info;
  325. this.getCarList();
  326. console.log(info, "infoinfoinfoinfo")
  327. }).catch(err => {})
  328. },
  329. //选择规格
  330. chooseSpec(index, specIndex) {
  331. let spec = this.goodsDetail.edit_value[index].spec
  332. for (let i in spec) {
  333. if (i == specIndex) {
  334. spec[i].active = true
  335. } else {
  336. spec[i].active = false
  337. }
  338. }
  339. this.goodsDetail.edit_value[index].spec = spec
  340. this.goodsDetail.num = 0
  341. this.computSpecPrice()
  342. },
  343. //计算规格价格
  344. computSpecPrice() {
  345. let edit_value = this.goodsDetail.edit_value
  346. let specNameArr = [],
  347. carSpecArr = []
  348. for (let i in edit_value) {
  349. for (let j in edit_value[i].spec) {
  350. if (edit_value[i].spec[j].active) {
  351. specNameArr.push(edit_value[i].spec[j].name)
  352. carSpecArr.push(edit_value[i].spec_name + ':' + edit_value[i].spec[j].name)
  353. break
  354. }
  355. }
  356. }
  357. let specName = specNameArr.join(":")
  358. this.goodsDetail.specName = specNameArr.join(',')
  359. let spec = this.goodsDetail.spec
  360. for (let i in spec) {
  361. if (spec[i].spec == specName) {
  362. this.goodsDetail.spec_price = this.userInfo.is_vip == 1 ? spec[i].growth : spec[i].growth
  363. break
  364. }
  365. }
  366. // let carGoods = this.carGoods
  367. // carSpecArr = carSpecArr.join(",")
  368. // for (let i in carGoods) {
  369. // if (this.goodsDetail.id == carGoods[i].goods_id && carSpecArr == carGoods[i].spec) {
  370. // this.goodsDetail.num = carGoods[i].num
  371. // break
  372. // }
  373. // }
  374. },
  375. //获取购物车数据
  376. getCarList() {
  377. this.$http.request('xcx/cart_list', {
  378. user_id: this.userInfo.id,
  379. }, "", "", hideLoading).then(res => {
  380. if(res.data.list<=0){
  381. this.pocket=1
  382. }
  383. let arr = this.$utils.removal(res.data.list),
  384. num = 0;
  385. // this.list = arr;
  386. this.computGoodsNum(arr, res.data.total_price, num, res.data.new_list);
  387. }).catch(err => {})
  388. },
  389. /**
  390. * 改变商品数量
  391. * @category_id:分类id
  392. * @goods_id:商品id
  393. * @type:1减少 2增加
  394. * @data_from 购物车列表传 'car' 规格弹窗传 'spec' 无规格传 'goods' 否则不传
  395. * @car_index 购物车下标 data_form = 'car'传
  396. * @goods_price 商品价格 data_from = 'goods' 传
  397. * */
  398. changeNum(category_id, goods_id, type, data_from, car_index, goods_price, many_rebate = '', is_rebate =
  399. '', idx = '') {
  400. console.log(many_rebate, is_rebate)
  401. let money = 0,
  402. pocket = this.pocket,
  403. num = 0,
  404. spec = '',
  405. carItem = false,
  406. new_list = this.carGoods,
  407. carGoods = this.carGoods;
  408. // carGoods = ? this.list : carGoods;
  409. pocket = idx === '' ? pocket : idx;
  410. if (type == 2) {
  411. for (let i of new_list) {
  412. if (i.pocket == pocket) {
  413. carGoods = i.list;
  414. }
  415. }
  416. }
  417. if (type == 1) {
  418. function getData(new_list, pocket, goods_id) {
  419. let as = false
  420. for (let i of new_list) {
  421. for (let j of i.list) {
  422. if (i.pocket == pocket && j.goods_id == goods_id) {
  423. as = true
  424. }
  425. }
  426. }
  427. return as
  428. }
  429. // 判断当前选中的购物口袋是否选中并且还有产品
  430. let isAllStudentType = getData(new_list, pocket, goods_id)
  431. if (isAllStudentType) {
  432. for (let i of new_list) {
  433. if (i.pocket == pocket) {
  434. carGoods = i.list;
  435. }
  436. }
  437. } else {
  438. for (let i of new_list) {
  439. for (let j of i.list) {
  440. if (j.goods_id == goods_id) {
  441. pocket = i.pocket
  442. carGoods = i.list
  443. }
  444. }
  445. }
  446. }
  447. }
  448. console.log(carGoods, "carGoods")
  449. if (data_from == 'car') {
  450. //购物车规格
  451. carItem = carGoods[car_index]
  452. spec = carItem.spec || ''
  453. money = carItem.price
  454. // console.log(money, "money")
  455. } else if (data_from == 'spec') {
  456. let specArr = []
  457. let specList = this.goodsDetail.edit_value
  458. for (let i in specList) {
  459. for (let j in specList[i].spec)
  460. if (specList[i].spec[j].active) {
  461. specArr.push(specList[i].spec_name + ':' + specList[i].spec[j].name)
  462. break
  463. }
  464. }
  465. if (specArr.length != specList.length) {
  466. uni.showToast({
  467. title: "请选择规格",
  468. icon: 'none'
  469. })
  470. return false
  471. } else {
  472. spec = specArr.join(',')
  473. money = this.goodsDetail.spec_price
  474. }
  475. } else if (data_from == 'goods') {
  476. //无规格商品
  477. spec = ''
  478. money = goods_price
  479. }
  480. if (data_from != 'car') {
  481. for (let i in carGoods) {
  482. if (carGoods[i].goods_id == goods_id && carGoods[i].spec == spec) {
  483. carItem = carGoods[i]
  484. break
  485. }
  486. }
  487. }
  488. num = carItem ? carItem.num : 0
  489. if (type == 1) {
  490. if (num > 0) {
  491. // 起购
  492. if (many_rebate > 0 && is_rebate == 1) {
  493. if (many_rebate >= num) {
  494. num = num - many_rebate;
  495. } else {
  496. num--;
  497. }
  498. } else {
  499. num--
  500. }
  501. } else {
  502. return false
  503. }
  504. } else if (type == 2) {
  505. // 起购
  506. if (many_rebate > 0 && is_rebate == 1) {
  507. if (many_rebate <= num) {
  508. num++
  509. } else {
  510. num = num + many_rebate;
  511. }
  512. } else {
  513. num++
  514. }
  515. } else {
  516. return false
  517. }
  518. this.$http.request('xcx/add_cart', {
  519. user_id: this.userInfo.id, //是 string 用户id
  520. category_id: category_id, //分类id
  521. goods_id: goods_id, //是 string 商品id
  522. num: num, //是 string 购买数量
  523. table_id: this.systemInfo.table_id, //是 string 桌号
  524. spec: spec, //是 string 规格(json),有的传
  525. money: money,
  526. pocket,
  527. }, 'POST', false, true).then(res => {
  528. // console.log(res)
  529. if (res.data.list.length == 0 && data_from == 'car') {
  530. this.pocket = 1
  531. this.maskPop = false
  532. this.carGoodsPop = false
  533. }
  534. let arr = this.$utils.removal(res.data.list)
  535. this.computGoodsNum(arr, res.data.total_price, num, res.data.new_list)
  536. }).catch(err => {})
  537. },
  538. //根据购物车列表计算购物车数据
  539. computGoodsNum(list, total_price, spec_nums, new_list) {
  540. let num = 0,
  541. spec_num = 0;
  542. //计算商品数量
  543. for (let i in list) {
  544. num += list[i].num
  545. }
  546. this.carNum = num
  547. this.carGoods = new_list
  548. this.list = list;
  549. this.$store.commit('SET_CARGOODS', list) //监听购物车是否有变化
  550. this.carTotal = total_price
  551. // if (this.detailPop || this.specPop) {
  552. for (let i of list) {
  553. if (i.goods_id == this.goodsDetail.id) {
  554. spec_num = i.num
  555. }
  556. }
  557. this.goodsDetail.num = spec_num || 0
  558. // }
  559. },
  560. },
  561. }
  562. </script>
  563. <style>
  564. @import url("../pages/index/index.css");
  565. .sales {
  566. font-size: 9pt;
  567. color: #999;
  568. padding-left: 20rpx;
  569. min-width: 100rpx;
  570. }
  571. .share_commission {
  572. position: absolute;
  573. right: 0;
  574. top: 450rpx;
  575. border-top-left-radius: 40rpx;
  576. border-bottom-left-radius: 40rpx;
  577. }
  578. .share_commission image {
  579. width: 100rpx;
  580. height: 126rpx;
  581. margin-right: 14rpx;
  582. margin-left: 20rpx;
  583. }
  584. .detail-pop {
  585. width: 100%;
  586. }
  587. .detail-pop .goods-img {
  588. width: 100%;
  589. }
  590. .detail-pop .btm-block {
  591. background-color: #FFFFFF;
  592. margin-bottom: 20rpx;
  593. }
  594. .detail-pop .detail-title {
  595. height: 100rpx;
  596. text-align: center;
  597. background-color: #FFFFFF;
  598. line-height: 100rpx;
  599. border-bottom: 1rpx solid #f1f1f1;
  600. }
  601. .detail-pop .detail-content {
  602. background-color: #FFFFFF;
  603. }
  604. .hg100 {
  605. height: 100rpx;
  606. }
  607. .many_rebate {
  608. margin-top: 20rpx;
  609. }
  610. </style>