goods.vue 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562
  1. <template>
  2. <div class="module-item-goods" :style="!module.base.m ? 'margin-top:0' : ''" v-if="goodsList.length>0">
  3. <div class="item-goods-con" :style="style">
  4. <moduleBg :base="module.base" />
  5. <moduleTwtit :type="module.type" :title="module.title" v-if="module.title.s" />
  6. <div class="item-goods-style1" :class="module.base.s == 1 ? 'style2' : ''">
  7. <div class="item" v-for="(item, index) in goodsList" :key="index">
  8. <div class="pic" @click="$util.openGoods(module.list,index)">
  9. <image :src="url+item.cm.thumb" />
  10. <template v-if="module.base.sth">
  11. <span v-if="item.cm.isPreferential === 1 && item.cm.type === 1">特惠</span>
  12. <span v-if="item.cm.isBuyGive === 1 && item.cm.type === 1">买赠</span>
  13. </template>
  14. </div>
  15. <div class="c">
  16. <div class="tit" v-if="module.base.t.s">
  17. <moduleText :text="module.base.t" :type="module.type" :name="item.cm.name" /></div>
  18. <div class="price" v-if="module.base.sjg || module.base.sgm">
  19. <template v-if="module.base.sjg">
  20. <span>
  21. <b>¥{{ item.cm.price }}</b>
  22. </span>
  23. <span v-if="item.cm.type == 2">
  24. <b>{{ item.cm.priceDescribe }}</b>
  25. </span>
  26. </template>
  27. <block v-if="systemInfo.set.is_cart==1">
  28. <view v-if="module.base.sgm && item.cm.stock > 0">
  29. <view class="flex flex-x-end flex-y-center">
  30. <view class="spec-btn"
  31. v-if="item.cm.is_gg == 2" @click="showSpec(item.cm.id)">
  32. 选规格<view class="spec-num flex-center" v-if="item.cm.num>0">{{item.cm.num}}</view>
  33. </view>
  34. <view class="goods-num-block flex flex-x-end flex-y-center" v-else
  35. :style="{color:setColor}">
  36. <view class="car-goods iconfont icon-jian1"
  37. @click="changeNum(item.cm.category_id,item.cm.id,1,'goods','',item.cm.price,item.cm.many_rebate,item.cm.is_rebate)"
  38. v-if="item.cm.num>0"></view>
  39. <view class="num" v-if="item.cm.num>0">{{item.cm.num}}</view>
  40. <view class="car-goods iconfont icon-jia1 gdsf"
  41. @click="changeNum(item.cm.category_id,item.cm.id,2,'goods','',item.cm.price,item.cm.many_rebate,item.cm.is_rebate)">
  42. </view>
  43. </view>
  44. </view>
  45. <view class="flex-y-center">
  46. <view class="price" v-if="item.cm.is_rebate==1 && item.cm.rebate">
  47. <view class="rebate-border">
  48. {{item.cm.rebate}}
  49. </view>
  50. </view>
  51. <view class="ft24 many_rebate" v-if="item.cm.many_rebate>0 && item.cm.is_rebate==1">
  52. {{item.cm.many_rebate}}{{item.cm.unit}}起购
  53. </view>
  54. </view>
  55. </view>
  56. </block>
  57. <block v-else>
  58. <view @click="$util.openGoods(module.list,index)" class="car-goods iconfont icon-gouwuche2" v-if="module.base.sgm && item.cm.stock > 0"></view>
  59. </block>
  60. </div>
  61. </div>
  62. </div>
  63. </div>
  64. </div>
  65. <block v-if="systemInfo.set.is_cart==1">
  66. <shopping-car :carNum="carNum" :isDistance="is_distance" :navBtn="false"
  67. :deliveryPrice="delivery_price" :carTotal="carTotal" :carGoods="carGoods" :userInfo="userInfo"
  68. @choosebag="choosebag" :checked="pocket"/>
  69. </block>
  70. <view class="mask flex flex-column flex-nowarp flex-x-center flex-y-center" v-show="maskPop">
  71. <!-- 规格弹窗 -->
  72. <block v-if="specPop">
  73. <view class="pop-block spec-pop">
  74. <view class="title">{{goodsDetail.name}}</view>
  75. <scroll-view scroll-y="true" class="content-block">
  76. <view class="content">
  77. <block v-for="(item,index) in goodsDetail.edit_value" :key="index">
  78. <view class="spec-cat-title">
  79. <text>{{item.spec_name}}</text>
  80. <text style="font-size:24rpx;color:#aaa">(仅单选)</text>
  81. </view>
  82. <view class="spec-list flex">
  83. <view v-for="(spec,specIndex) in item.spec" :key="specIndex"
  84. @click="chooseSpec(index,specIndex)"
  85. :class="['spec-item',spec.active?'active':'']"
  86. :style="[spec.active?{'background-color':setColor,'border-color':setColor}:'']">
  87. {{spec.name}}
  88. <block v-if="spec.price">¥{{spec.price}}</block>
  89. </view>
  90. </view>
  91. </block>
  92. </view>
  93. </scroll-view>
  94. <view class="btm-block flex flex-y-baseline flex-nowarp">
  95. <view class="flex flex-nowarp flex-y-baseline">
  96. <view class="price">¥{{goodsDetail.spec_price}}</view>
  97. <view class="unit">/{{goodsDetail.unit}}</view>
  98. </view>
  99. <view class="choose-spec-list text-3" v-if="goodsDetail.specName">
  100. ({{goodsDetail.specName}})</view>
  101. <block>
  102. <view class="add-car-btn" :style="{'background-color':setColor}"
  103. v-if="goodsDetail.num == 0"
  104. @click="changeNum(goodsDetail.category_id,goodsDetail.id,2,'spec',goodsDetail.many_rebate,goodsDetail.is_rebate)">
  105. 加入购物车</view>
  106. <view class="goods-num-block flex flex-x-end flex-y-center" v-else
  107. :style="{color:setColor}">
  108. <view class="num-btn num-btn-1 iconfont icon-jian1"
  109. @click="changeNum(goodsDetail.category_id,goodsDetail.id,1,'spec',goodsDetail.many_rebate,goodsDetail.is_rebate)">
  110. </view>
  111. <view class="num">{{goodsDetail.num}}</view>
  112. <view class="num-btn num-btn-2 iconfont icon-jia1"
  113. @click="changeNum(goodsDetail.category_id,goodsDetail.id,2,'spec',goodsDetail.many_rebate,goodsDetail.is_rebate)">
  114. </view>
  115. </view>
  116. </block>
  117. </view>
  118. </view>
  119. <image src="/static/icon_5.png" mode="aspectFit" class="spec-close-btn" @click="showSpec"></image>
  120. </block>
  121. </view>
  122. </div>
  123. </template>
  124. <script>
  125. import moduleBg from './bg.vue';
  126. import moduleText from './text.vue';
  127. import moduleTwtit from './twtit.vue';
  128. // import SelectGoods from '@/views/attr/selectGoods.vue';
  129. import shoppingCar from '@/components/shoppingCar.vue';
  130. import { mapState } from 'vuex';
  131. export default {
  132. props: ['module'],
  133. components: { moduleBg, moduleText,moduleTwtit,shoppingCar},
  134. data() {
  135. return {
  136. goodsList:this.module.list,
  137. showSelectGoods:false,
  138. url:getApp().globalData.URL,
  139. carGoods: [], //购物车商品
  140. carTotal:0,
  141. is_distance:0,
  142. delivery_price:0,
  143. carNum:0,
  144. specPop: false,
  145. maskPop:false,
  146. goodsDetail:null,
  147. pocket:1
  148. };
  149. },
  150. computed: {
  151. ...mapState(['systemInfo', 'store_id', 'userInfo', 'setColor','table_id','vx_carGoods','teen_index', 'address',]),
  152. style() {
  153. if (this.module.base.fc != '') {
  154. return `color:${this.module.base.fc}`;
  155. }
  156. },
  157. dateRanges() {
  158. const {
  159. store_id,
  160. userInfo,
  161. } = this;
  162. return {
  163. store_id,
  164. userInfo,
  165. }
  166. },
  167. },
  168. watch:{
  169. vx_carGoods(nVal){
  170. console.log(nVal,"goods")
  171. if (nVal) {
  172. this.getCarList();
  173. this.getDeliveryPrice();
  174. }
  175. },
  176. // 弹窗校检
  177. dateRange: {
  178. handler(val) {
  179. this.getCarList();
  180. }
  181. }
  182. },
  183. mounted() {
  184. if(this.userInfo && this.store_id ){
  185. this.getCarList();
  186. }
  187. },
  188. methods: {
  189. choosebag(index) {
  190. this.pocket = index;
  191. },
  192. // 获取配送费
  193. getDeliveryPrice() {
  194. this.$http.request('xcx/getDeliveryPrice', {
  195. lat: this.address.lat || '',
  196. lng: this.address.lng || '',
  197. store_id: this.store_id,
  198. }, "", "", true).then(res => {
  199. let distance = Number(res.data.distance);
  200. if (distance) {
  201. if (!distance) {
  202. this.is_distance = 2;
  203. return
  204. }
  205. this.delivery_price = Number(res.data.delivery_price);
  206. if (!this.systemInfo.set.number || !distance) {
  207. this.is_distance = 1;
  208. return
  209. }
  210. // 如果大于商家距离is_distance = 2 提出超出距离
  211. if (distance > this.systemInfo.set.number) {
  212. this.is_distance = 2;
  213. } else {
  214. this.is_distance = 1;
  215. }
  216. } else {
  217. this.is_distance = 3;
  218. }
  219. }).catch(err => {})
  220. },
  221. /**
  222. * 改变商品数量
  223. * @category_id:分类id
  224. * @goods_id:商品id
  225. * @type:1减少 2增加
  226. * @data_from 购物车列表传 'car' 规格弹窗传 'spec' 无规格传 'goods' 否则不传
  227. * @car_index 购物车下标 data_form = 'car'传
  228. * @goods_price 商品价格 data_from = 'goods' 传
  229. * */
  230. changeNum(category_id, goods_id, type, data_from, car_index, goods_price, many_rebate = '', is_rebate = '',
  231. idx = '') {
  232. /* pocket 购物口袋
  233. goodsList 数据列表
  234. idx 如果是有从购物车加入 */
  235. let money = 0,
  236. pocket = this.pocket,
  237. carGoods,
  238. num = 0,
  239. spec = '',
  240. new_list = this.new_list,
  241. carItem = false;
  242. carGoods = this.carGoods;
  243. pocket = idx === '' ? pocket : idx;
  244. if (type == 2) {
  245. for (let i of new_list) {
  246. if (i.pocket == pocket) {
  247. carGoods = i.list;
  248. }
  249. }
  250. }
  251. if (type == 1) {
  252. function getData(new_list,pocket,goods_id) {
  253. let as = false
  254. for (let i of new_list) {
  255. for(let j of i.list){
  256. if (i.pocket == pocket && j.goods_id == goods_id) {
  257. as = true
  258. }
  259. }
  260. }
  261. return as
  262. }
  263. // 判断当前选中的购物口袋是否选中并且还有产品
  264. let isAllStudentType = getData(new_list,pocket,goods_id)
  265. if (isAllStudentType) {
  266. for (let i of new_list) {
  267. if (i.pocket == pocket) {
  268. carGoods = i.list;
  269. }
  270. }
  271. } else {
  272. for (let i of new_list) {
  273. for (let j of i.list) {
  274. if (j.goods_id == goods_id) {
  275. pocket = i.pocket
  276. carGoods = i.list
  277. }
  278. }
  279. }
  280. }
  281. }
  282. if (data_from == 'car') {
  283. //购物车规格
  284. carItem = carGoods[car_index]
  285. spec = carItem.spec || ''
  286. money = carItem.price
  287. } else if (data_from == 'spec') {
  288. let specArr = []
  289. let specList = this.goodsDetail.edit_value
  290. for (let i in specList) {
  291. for (let j in specList[i].spec)
  292. if (specList[i].spec[j].active) {
  293. specArr.push(specList[i].spec_name + ':' + specList[i].spec[j].name)
  294. break
  295. }
  296. }
  297. if (specArr.length != specList.length) {
  298. uni.showToast({
  299. title: "请选择规格",
  300. icon: 'none'
  301. })
  302. return false
  303. } else {
  304. spec = specArr.join(',')
  305. money = this.goodsDetail.spec_price
  306. }
  307. } else if (data_from == 'goods') {
  308. //无规格商品
  309. spec = ''
  310. money = goods_price
  311. }
  312. if (data_from != 'car') {
  313. for (let i in carGoods) {
  314. if (carGoods[i].goods_id == goods_id && carGoods[i].spec == spec) {
  315. carItem = carGoods[i]
  316. break
  317. }
  318. }
  319. }
  320. num = carItem ? carItem.num : 0
  321. if (type == 1) {
  322. if (num > 0) {
  323. // 起购
  324. if (many_rebate > 0 && is_rebate == 1) {
  325. if (many_rebate >= num) {
  326. num = num - many_rebate;
  327. } else {
  328. num--;
  329. }
  330. } else {
  331. num--
  332. }
  333. } else {
  334. return false
  335. }
  336. } else if (type == 2) {
  337. // 起购
  338. if (many_rebate > 0 && is_rebate == 1) {
  339. if (many_rebate <= num) {
  340. num++
  341. } else {
  342. num = num + many_rebate;
  343. }
  344. } else {
  345. num++
  346. }
  347. } else {
  348. return false
  349. }
  350. let datas = {
  351. user_id: this.userInfo.id,
  352. category_id: category_id, //分类id
  353. goods_id: goods_id, //是 string 商品id
  354. num: num <= 0 ? 0 : num, //是 string 购买数量
  355. table_id: this.table_id, //是 string 桌号
  356. spec: spec, //是 string 规格(json),有的传
  357. money: money,
  358. group: this.table_id,
  359. type: 'add_cart',
  360. store_id: this.store_id,
  361. pocket: pocket
  362. }
  363. if (this.systemInfo.is_qian_many == 1 && app.globalData.readyReset == 1) {
  364. app.sendSocketMessage(JSON.stringify(datas)).then(res => {
  365. this.number = num;
  366. })
  367. } else {
  368. this.$http.request('xcx/add_cart', datas, 'POST', false, true).then(res => {
  369. if (res.data.list.length == 0 && data_from == 'car') {
  370. this.pocket =1
  371. this.maskPop = false
  372. this.carGoodsPop = false
  373. }
  374. let arr = this.$utils.removal(res.data.list)
  375. this.new_list = res.data.new_list;
  376. this.computGoodsNum(arr, res.data.total_price, num, res.data.new_list)
  377. }).catch(err => {})
  378. }
  379. },
  380. //获取购物车数据
  381. getCarList() {
  382. var url = 'xcx/cart_list',
  383. datas;
  384. datas = {
  385. user_id: this.userInfo.id,
  386. store_id: this.store_id,
  387. }
  388. this.$http.request(url, datas, "", "", true).then(res => {
  389. if(res.data.list<=0){
  390. this.pocket = 1
  391. }
  392. let arr = this.$utils.removal(res.data.list)
  393. this.new_list = res.data.new_list;
  394. this.computGoodsNum(arr, res.data.total_price, 0, res.data.new_list)
  395. this.isloading = false;
  396. }).catch(err => {})
  397. },
  398. //根据购物车列表计算购物车数据
  399. computGoodsNum(list, total_price, spec_num, new_list = []) {
  400. if (this.goodsList.length <= 0) {
  401. return
  402. }
  403. let num = 0
  404. //计算商品数量
  405. let goodsList = this.goodsList;
  406. for (let i in goodsList) {
  407. goodsList[i].cm.num = 0
  408. }
  409. for (let i in list) {
  410. num += list[i].num
  411. for (let j in goodsList) {
  412. if (list[i].goods_id == goodsList[j].cm.id) {
  413. goodsList[j].cm.num += list[i].num
  414. break
  415. }
  416. }
  417. }
  418. this.goodsList = goodsList
  419. this.carNum = num
  420. this.carGoods = new_list
  421. this.carTotal = total_price
  422. if (this.detailPop || this.specPop) {
  423. this.goodsDetail.num = spec_num
  424. }
  425. },
  426. //清空购物车
  427. clearCar() {
  428. console.log("clearCar")
  429. this.pocket = 1
  430. this.new_list = []
  431. this.carGoods = []
  432. this.$store.commit('SET_CARGOODS', []) //监听购物车是否有变化
  433. this.carNum = 0
  434. this.carTotal = 0
  435. this.maskPop = false
  436. this.carGoodsPop = false
  437. let goodsList = this.goodsList
  438. for (let i in goodsList) {
  439. goodsList[i].cm.num = 0
  440. }
  441. this.goodsList = goodsList
  442. },
  443. //显示规格弹窗
  444. showSpec(goods_id) {
  445. if (this.specPop) {
  446. this.maskPop = false
  447. this.specPop = false
  448. return false
  449. }
  450. this.$http.request('xcx/goodinfo', {
  451. goods_id: goods_id
  452. }, "", "", true).then(res => {
  453. let info = res.data.goods
  454. let edit_value = info.edit_value
  455. for (let i in edit_value) {
  456. for (let j in edit_value[i].spec) {
  457. edit_value[i].spec[j] = {
  458. 'name': edit_value[i].spec[j],
  459. active: false
  460. }
  461. }
  462. }
  463. info.edit_value = edit_value
  464. info.spec_price = info.price
  465. info.num = 0
  466. info.specName = ""
  467. this.goodsDetail = info
  468. this.maskPop = true
  469. this.specPop = true
  470. }).catch(err => {})
  471. },
  472. //选择规格
  473. chooseSpec(index, specIndex) {
  474. let spec = this.goodsDetail.edit_value[index].spec
  475. for (let i in spec) {
  476. if (i == specIndex) {
  477. spec[i].active = true
  478. } else {
  479. spec[i].active = false
  480. }
  481. }
  482. this.goodsDetail.edit_value[index].spec = spec
  483. this.goodsDetail.num = 0
  484. this.computSpecPrice()
  485. },
  486. //计算规格价格
  487. computSpecPrice() {
  488. let edit_value = this.goodsDetail.edit_value
  489. let specNameArr = [],
  490. carSpecArr = []
  491. for (let i in edit_value) {
  492. for (let j in edit_value[i].spec) {
  493. if (edit_value[i].spec[j].active) {
  494. specNameArr.push(edit_value[i].spec[j].name)
  495. carSpecArr.push(edit_value[i].spec_name + ':' + edit_value[i].spec[j].name)
  496. break
  497. }
  498. }
  499. }
  500. let specName = specNameArr.join(":")
  501. this.goodsDetail.specName = specNameArr.join(',')
  502. let spec = this.goodsDetail.spec
  503. for (let i in spec) {
  504. if (spec[i].spec == specName) {
  505. this.goodsDetail.spec_price = this.userInfo.is_vip == 1 ? spec[i].growth : spec[i].growth
  506. break
  507. }
  508. }
  509. let carGoods = this.carGoods
  510. carSpecArr = carSpecArr.join(",")
  511. for (let i in carGoods) {
  512. if (this.goodsDetail.id == carGoods[i].goods_id && carSpecArr == carGoods[i].spec) {
  513. this.goodsDetail.num = carGoods[i].num
  514. break
  515. }
  516. }
  517. },
  518. }
  519. };
  520. </script>
  521. <style>
  522. @import url("./goods.css");
  523. .many_rebate {
  524. color: red;
  525. text-align: right;
  526. }
  527. .textDecoration {
  528. text-decoration: line-through;
  529. color: #999999;
  530. font-size: 20rpx;
  531. }
  532. </style>