shopDetail.vue 32 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273
  1. <template>
  2. <view class="orderFood">
  3. <view class="shop-info">
  4. <view class="shop-name">
  5. {{shopInfo.shopName}}
  6. </view>
  7. <view class="address">
  8. {{shopInfo.address}}
  9. </view>
  10. </view>
  11. <view class="content">
  12. <scroll-view :scroll-y="true" class="left" :scroll-into-view="scrollTo1" scroll-with-animation>
  13. <!-- <view class="left"> -->
  14. <view class="item" :class="[active == index?'active':'']" v-for="(item,index) in list" :id="'tab'+index" :key="index" @click="handleTab(index)">
  15. <image class="icon" :src="item.imageCnUrl" mode=""></image>
  16. <view class="name">
  17. {{item.topName}}
  18. </view>
  19. </view>
  20. <!-- </view> -->
  21. </scroll-view>
  22. <scroll-view :scroll-y="true" class="right" :scroll-into-view="scrollTo" scroll-with-animation @scroll="scroll">
  23. <!-- <view class="test">
  24. </view> -->
  25. <!-- <view class="right"> -->
  26. <view class="section" v-for="(item,index) in list" :key="index">
  27. <view class="section-name" :class="'title'+index" :id="'title'+index" >
  28. {{item.topName}}
  29. </view>
  30. <!-- <zs-title :title="item.topName" :value="index" :class="'title'+index" :id="'title'+index" @changeTag="chooseTag"></zs-title> -->
  31. <view class="item" v-for="(i,d) in item.menuVoList" :key="d" >
  32. <image class="img" :src="i.imageUrl" mode=""></image>
  33. <view class="info">
  34. <view class="title">
  35. {{i.nameCn}}
  36. </view>
  37. <view class="btn-box">
  38. <view class="price-box">
  39. <view class="price">
  40. <view class="unit">
  41. </view>
  42. <view class="num">
  43. {{i.priceHead}}
  44. </view>
  45. </view>
  46. <view class="old-price">
  47. ¥{{i.price}}
  48. </view>
  49. </view>
  50. <image class="btn" @click.stop="add(i,1,item)" src="../static/add-active.png" mode=""></image>
  51. </view>
  52. </view>
  53. </view>
  54. </view>
  55. <!-- </view> -->
  56. </scroll-view>
  57. </view>
  58. <view class="total-box">
  59. <view class="price-box" @click="handleCar">
  60. <view class="car-box">
  61. <image class="icon" src="../static/shop-car.png" mode=""></image>
  62. <view class="num" v-if="totalNum">
  63. {{totalNum}}
  64. </view>
  65. </view>
  66. <view class="price">
  67. <view class="unit">
  68. </view>
  69. <view class="num">
  70. {{total}}
  71. </view>
  72. </view>
  73. </view>
  74. <button class="buy" :class="[!carList.length?'disabled':'']" :disabled="!carList.length" type="default" @click="buy">{{carList.length?'选好了':'未选择商品'}}</button>
  75. </view>
  76. <!-- 购物车 -->
  77. <u-popup :show="show" round="32rpx" mode="bottom" @close="show = false">
  78. <view class="popup-title-box" >
  79. <view class="title">
  80. 已选商品
  81. </view>
  82. <view class="clear" v-if="carList.length" @click="clear">
  83. 清空
  84. </view>
  85. </view>
  86. <u-empty
  87. mode="car"
  88. icon="http://cdn.uviewui.com/uview/empty/car.png"
  89. v-if="!carList.length"
  90. >
  91. </u-empty>
  92. <view class="car-content" v-else>
  93. <view class="item" v-for="(item,index) in carList" :key="index">
  94. <image class="img" :src="item.imageUrl" mode=""></image>
  95. <view class="info">
  96. <view class="title">
  97. {{item.nameCn}}
  98. </view>
  99. <view class="type" v-if="item.config">
  100. {{item.config}}
  101. </view>
  102. <view class="btn-box">
  103. <view class="price-box">
  104. <view class="price">
  105. <view class="unit">
  106. </view>
  107. <view class="num">
  108. {{item.sellPrice}}
  109. </view>
  110. </view>
  111. <view class="old-price">
  112. ¥{{item.orgPrice}}
  113. </view>
  114. </view>
  115. <view class="count-box">
  116. <image class="btn" src="../static/remove.png" v-if="item.quantity" @click="add(item,-1,{},index)" mode=""></image>
  117. <view class="num">
  118. {{item.quantity}}
  119. </view>
  120. <image class="btn" src="../static/add-active.png" @click="add(item,1,{},index)" mode=""></image>
  121. </view>
  122. </view>
  123. </view>
  124. </view>
  125. </view>
  126. <view class="total-box total-box1">
  127. <view class="price-box" @click="handleCar">
  128. <view class="car-box">
  129. <image class="icon" src="../static/shop-car.png" mode=""></image>
  130. <view class="num" v-if="totalNum">
  131. {{totalNum}}
  132. </view>
  133. </view>
  134. <view class="price">
  135. <view class="unit">
  136. </view>
  137. <view class="num">
  138. {{total}}
  139. </view>
  140. </view>
  141. </view>
  142. <button class="buy" :class="[!carList.length?'disabled':'']" :disabled="!carList.length" type="default" @click="buy">{{carList.length?'选好了':'未选择商品'}}</button>
  143. </view>
  144. </u-popup>
  145. <!-- 商品详情 -->
  146. <u-popup :show="show2" round="32rpx" mode="bottom" @close="show2 = false">
  147. <view class="popup-goodsDetail">
  148. <view class="box">
  149. <image class="img" :src="goodsInfo.product_img" mode="aspectFit"></image>
  150. <view class="popup-content">
  151. <view class="title">
  152. {{goodsInfo.product_name}}
  153. </view>
  154. <view class="desc" v-if="goodsInfo.product_description">
  155. {{goodsInfo.product_description}}
  156. </view>
  157. <view class="choose-box" v-if="ot == 'NXDC'">
  158. <view class="choose-item" v-for="item in goodsInfo.details.spu_specs" :key="item.code">
  159. <view class="choose-title">
  160. {{item.name}}
  161. </view>
  162. <view class="item-box">
  163. <view class="item" :class="[i.code == chooseInfo[item.code].code?'active':'']" v-for="i in item.values" :key="i.code" @click="choose(i,item.code)">
  164. {{i.name}} {{i.price?`¥${i.price}`:''}}
  165. </view>
  166. </view>
  167. </view>
  168. </view>
  169. <view class="choose-box" v-else-if="ot == 'MDL'">
  170. <view class="choose-item" v-for="item in goodsInfo.details.optional" :key="item.code">
  171. <view class="choose-title">
  172. {{item.name}}
  173. </view>
  174. <view class="item-box">
  175. <view class="item" :class="[i.id == chooseInfo[item.name+'-'+item.id].id?'active':'']" v-for="i in item.sku_infos" :key="i.id" @click="()=>choose(i,item.name+'-'+item.id)">
  176. {{i.name}} {{i.price?`¥${i.price}`:''}}
  177. </view>
  178. </view>
  179. </view>
  180. <view class="choose-item" >
  181. <view class="choose-title">
  182. 套餐内容
  183. </view>
  184. <view class="item-box">
  185. <view class="item active" v-for="i in goodsInfo.details.required" :key="i.id">
  186. {{i.product_name}}x{{i.amount}}
  187. </view>
  188. </view>
  189. </view>
  190. </view>
  191. <view class="choose-box" v-else-if="ot == 'XBK'">
  192. <view class="choose-item" v-for="item in goodsInfo.details.optional" :key="item.code">
  193. <view class="choose-title">
  194. {{item.name}}
  195. </view>
  196. <view class="item-box">
  197. <view class="item" :class="[i.id == chooseInfo[item.id].id?'active':'']" v-for="i in item.sku_infos" :key="i.id" @click="()=>choose(i,item.id)">
  198. {{i.name}} {{i.price?`¥${i.price}`:''}}
  199. </view>
  200. </view>
  201. </view>
  202. </view>
  203. <view class="choose-box" v-else-if="ot == 'XC'">
  204. <view class="choose-item" v-for="item in goodsInfo.details.specifications" :key="item.code">
  205. <view class="choose-title">
  206. {{item.name}}
  207. </view>
  208. <view class="item-box">
  209. <view class="item" :class="[i.id == chooseInfo[item.id].id?'active':'']" v-for="i in item.values" :key="i.id" @click="()=>choose(i,item.id,item)">
  210. {{i.name}} {{i.price?`¥${i.price}`:''}}
  211. </view>
  212. </view>
  213. </view>
  214. </view>
  215. </view>
  216. </view>
  217. <view class="btn-box">
  218. <view class="order-info">
  219. <view class="left">
  220. <view class="price-box">
  221. <view class="price">
  222. ¥{{(itemPrice.price*10000)*num/10000}}
  223. </view>
  224. <view class="old-price">
  225. ¥{{ (itemPrice.oldPrice*10000)*num/10000}}
  226. </view>
  227. </view>
  228. <view class="choose">
  229. {{config}}
  230. </view>
  231. </view>
  232. <view class="count-box">
  233. <image class="btn1" src="../static/remove.png" v-if="num" @click="add1(-1)" mode=""></image>
  234. <view class="num">
  235. {{num}}
  236. </view>
  237. <image class="btn1" src="../static/add-active.png" @click="add1(1)" mode=""></image>
  238. </view>
  239. </view>
  240. <button class="btn" type="default" @click="handleAdd">加入购物车</button>
  241. </view>
  242. </view>
  243. </u-popup>
  244. <u-modal :show="show1" :title="shopInfo.shopName" confirmColor="#FF4D3A" confirmText="更换门店" @confirm="confirm">
  245. <view class="modal-box">
  246. <view class="shopName">
  247. 店铺暂未营业或已暂停营业
  248. </view>
  249. <view class="notice">
  250. 请尝试更换门店~
  251. </view>
  252. </view>
  253. </u-modal>
  254. </view>
  255. </template>
  256. <script>
  257. import {shopDetail,menuList,foodGoodsDetail} from '@/api/orderFood.js'
  258. export default {
  259. data() {
  260. return {
  261. shopId:"63836999-5117-4980-8632-497f007808ef",
  262. show:false,
  263. show1:false,
  264. show2:false,
  265. active:0,
  266. list:[],
  267. shopInfo:{
  268. shopName:'',
  269. address:'',
  270. },
  271. carList:[],
  272. scrollTo:'title0',
  273. scrollTo1:'',
  274. topList:[],
  275. offsetTop:0,//顶部距离
  276. cateName:'',//跳转过来携带的分类名称
  277. ot:uni.getStorageSync('ot'),
  278. goodsInfo:{},
  279. num:1,
  280. chooseInfo:{},
  281. item:{},//弹窗内商品信息
  282. productId:'',
  283. itemPrice:{//弹窗内商品价格
  284. price:0,
  285. oldPrice:0
  286. }
  287. };
  288. },
  289. computed: {
  290. totalNum(){
  291. let total = 0
  292. this.carList.map(item=>{
  293. total+=item.quantity
  294. })
  295. return total
  296. },
  297. total() {
  298. let total = 0
  299. this.carList.map(item=>{
  300. total+=(item.sellPrice*10000*item.quantity)
  301. })
  302. return total/10000
  303. },
  304. // 选择的规格文字 同时计算当前选择的价格
  305. config(){
  306. let str = ''
  307. for (let key in this.chooseInfo) {
  308. str +=this.chooseInfo[key].name +'/'
  309. }
  310. if(this.goodsInfo.details&&this.goodsInfo.details.sku_infos){
  311. let {productId,price,oldPrice} = this.findData()
  312. this.productId = productId
  313. this.itemPrice = {
  314. price,
  315. oldPrice
  316. }
  317. }else if(this.goodsInfo.details&&this.goodsInfo.details.specifications){
  318. let addPrice = 0
  319. for (let key in this.chooseInfo) {
  320. addPrice += this.chooseInfo[key].price
  321. }
  322. this.itemPrice = {
  323. price:this.item.priceHead+addPrice,
  324. oldPrice:this.item.price+addPrice
  325. }
  326. }else if(this.ot == 'MDL'){
  327. this.itemPrice = {
  328. price:this.item.priceHead,
  329. oldPrice:this.item.price
  330. }
  331. }else if(this.ot == 'XBK'){
  332. let addPrice = 0
  333. for (let key in this.chooseInfo) {
  334. addPrice += this.chooseInfo[key].price
  335. }
  336. this.itemPrice = {
  337. price:this.item.priceHead+addPrice,
  338. oldPrice:this.item.price+addPrice
  339. }
  340. }
  341. console.log('jiage',this.itemPrice);
  342. return str
  343. }
  344. },
  345. methods: {
  346. // 选择规格
  347. choose(item,key,data){
  348. console.log(item,key);
  349. if(this.ot == 'XC'){
  350. if(this.chooseInfo[key]&&this.chooseInfo[key].id == item.id &&!data.mandatory){
  351. this.$delete(this.chooseInfo,key)
  352. }else{
  353. this.$set(this.chooseInfo,key,item)
  354. }
  355. }else if(this.ot == 'MDL'){
  356. if(this.chooseInfo[key]&&this.chooseInfo[key].id == item.id){//麦当劳不能不选择
  357. // this.$delete(this.chooseInfo,key)
  358. }else{
  359. this.$set(this.chooseInfo,key,item)
  360. }
  361. }
  362. else if(this.ot == 'XBK'){
  363. if(this.chooseInfo[key]&&this.chooseInfo[key].id == item.id){//星巴克不能不选择
  364. // this.$delete(this.chooseInfo,key)
  365. }else{
  366. this.$set(this.chooseInfo,key,item)
  367. }
  368. }
  369. else{//奈雪的茶
  370. this.$set(this.chooseInfo,key,item)
  371. }
  372. },
  373. confirm(){
  374. this.show1 = false
  375. uni.navigateTo({
  376. url:'./shopList'
  377. })
  378. },
  379. // 滚动的选择商品
  380. scroll(val){
  381. if(!this.offsetTop){
  382. this.offsetTop = val.currentTarget.offsetTop
  383. }
  384. this.topList.map((item,index)=>{
  385. if(index!=this.topList.length-1){
  386. if(val.detail.scrollTop>= (item-this.offsetTop)&&(val.detail.scrollTop <=this.topList[index+1]-this.offsetTop)){
  387. this.scrollTo1 = 'tab'+index
  388. this.active = index
  389. }
  390. }else{
  391. if(val.detail.scrollTop>= (item-this.offsetTop)){
  392. this.scrollTo1 = 'tab'+index
  393. this.active = index
  394. }
  395. }
  396. })
  397. },
  398. clear(){
  399. this.carList = []
  400. },
  401. // 购物车内添加数量 商品添加数量 选择规格时不走这里 但是选择规格的购物车内数量操作走这里
  402. add(item,num,data={},idx){//item:当前操作item num:增加或者减少 data:当前item的上层栏目,idx:购物车内当前操作商品index 方便删除
  403. // 如果需要选择规格
  404. if(data.childClassList) return this.handleItem(item,data)
  405. // 肯德基
  406. if(this.ot == 'Kfc'){
  407. if(this.carList.some(i=>item.productId == i.productId)){
  408. this.carList.forEach((row,index)=>{
  409. if(item.productId == row.productId){
  410. row.quantity+=num
  411. if(row.quantity == 0){
  412. this.carList.splice(index,1)
  413. }
  414. }
  415. })
  416. }else{
  417. let obj ={
  418. "imageUrl": item.imageUrl,
  419. "nameCn": item.nameCn,
  420. "productId": item.productId,
  421. "quantity": 1,
  422. "sellPrice": item.priceHead,
  423. "orgPrice": item.price,
  424. }
  425. this.carList.push(obj)
  426. }
  427. // }else if(this.ot == 'NXDC'){//奈雪的茶 购物车内没有的商品不会从这里添加 所以只处理有的情况
  428. }else{
  429. if(this.carList.some((i,d)=>item.productId == i.productId)){
  430. this.carList.forEach((row,index)=>{
  431. if(index == idx){
  432. row.quantity+=num
  433. if(row.quantity == 0){
  434. this.carList.splice(index,1)
  435. }
  436. }
  437. })
  438. }
  439. }
  440. },
  441. // 商品详情内数量操作
  442. add1(num){
  443. this.num+=num
  444. },
  445. // 计算当前选择规格价格和code
  446. findData(){
  447. let productId = ''
  448. let cur = {}
  449. let price = 0
  450. let oldPrice = 0
  451. let addPrice = 0
  452. for (let key in this.chooseInfo) {
  453. cur[key] = this.chooseInfo[key].code
  454. addPrice += this.chooseInfo[key].price
  455. }
  456. this.goodsInfo.details.sku_infos.map(item=>{
  457. let obj = {}
  458. item.specs.map(i=>{
  459. obj[i.code] = i.spec_code
  460. })
  461. if(this.areObjectsEqual(cur,obj)){
  462. price = item.salePrice
  463. oldPrice = item.price
  464. return productId = item.code
  465. }
  466. })
  467. console.log('找到对应的',productId,price);
  468. return {
  469. productId,
  470. price:price+addPrice,
  471. oldPrice:oldPrice+addPrice
  472. }
  473. },
  474. // 选择规格后,加入购物车
  475. handleAdd(){
  476. this.show2 = false
  477. // let {productId,price,addPrice} = this.findData()
  478. let obj = {}
  479. if(this.ot == 'NXDC'){
  480. obj ={
  481. "imageUrl": this.item.imageUrl,
  482. "nameCn": this.item.nameCn,
  483. "productId": this.item.productId,
  484. "quantity": this.num,
  485. "sellPrice": this.itemPrice.price,//市场价(如果存在套餐选项加价,这里的金额需要计算加价)
  486. "orgPrice": this.itemPrice.oldPrice,
  487. "config": JSON.parse(JSON.stringify(this.config)) , //这里只是为了直观展示套餐选项,实际下单可以传空
  488. "selected": [
  489. {
  490. "round": 0, //奈雪产品round目前没有使用,传0
  491. "products": [
  492. {
  493. "linkId": "",
  494. "productId": this.productId, //套餐选项skuID,商品详情的sku列表里面已经包含所有选项组合
  495. "quantity": 1
  496. }
  497. ]
  498. }
  499. ]
  500. }
  501. }else if(this.ot == 'XC'){
  502. let products = []
  503. for (let key in this.chooseInfo) {
  504. products.push(
  505. { "linkId": key, "productId": this.chooseInfo[key].id, "quantity": 1 }
  506. )
  507. }
  508. obj ={
  509. "imageUrl": this.item.imageUrl,
  510. "nameCn": this.item.nameCn,
  511. "productId": this.item.productId,
  512. "quantity": this.num,
  513. "sellPrice": this.itemPrice.price,//市场价(如果存在套餐选项加价,这里的金额需要计算加价)
  514. "orgPrice": this.itemPrice.oldPrice,
  515. "config": JSON.parse(JSON.stringify(this.config)) , //这里只是为了直观展示套餐选项,实际下单可以传空
  516. "selected": [
  517. {
  518. "round": 0,//喜茶产品round目前没有使用,传0
  519. "products": products
  520. }
  521. ]
  522. }
  523. }else if(this.ot == 'MDL'){
  524. let products = []
  525. for (let key in this.chooseInfo) {
  526. products.push(
  527. {
  528. "linkId": key.split('-')[1],//下单参数linkId(有时会和主商品id相同)
  529. "productId": this.chooseInfo[key].id,//套餐选项商品id
  530. "quantity": 1
  531. }
  532. )
  533. }
  534. obj ={
  535. "imageUrl": this.item.imageUrl,
  536. "nameCn": this.item.nameCn,
  537. "productId": this.item.productId,
  538. "quantity": this.num,
  539. "sellPrice": this.itemPrice.price,//市场价(如果存在套餐选项加价,这里的金额需要计算加价)
  540. "orgPrice": this.itemPrice.oldPrice,
  541. "config": JSON.parse(JSON.stringify(this.config)) , //这里只是为了直观展示套餐选项,实际下单可以传空
  542. "selected": [
  543. {
  544. "round": 0,//喜茶产品round目前没有使用,传0
  545. "products": products
  546. }
  547. ]
  548. }
  549. }
  550. else if(this.ot == 'XBK'){
  551. let products = []
  552. for (let key in this.chooseInfo) {
  553. products.push(
  554. {
  555. "linkId": key,
  556. "productId": this.chooseInfo[key].id,//套餐选项商品id
  557. "quantity": 1
  558. }
  559. )
  560. }
  561. obj ={
  562. "imageUrl": this.item.imageUrl,
  563. "nameCn": this.item.nameCn,
  564. "productId": this.item.productId,
  565. "quantity": this.num,
  566. "sellPrice": this.itemPrice.price,//市场价(如果存在套餐选项加价,这里的金额需要计算加价)
  567. "orgPrice": this.itemPrice.oldPrice,
  568. "config": JSON.parse(JSON.stringify(this.config)) , //这里只是为了直观展示套餐选项,实际下单可以传空
  569. "selected": [
  570. {
  571. "round": 0,//喜茶产品round目前没有使用,传0
  572. "products": products
  573. }
  574. ]
  575. }
  576. }
  577. this.carList.push(obj)
  578. },
  579. // 对比两个对象是否内容相同
  580. areObjectsEqual(obj1, obj2) {
  581. const keys1 = Object.keys(obj1);
  582. const keys2 = Object.keys(obj2);
  583. if (keys1.length!== keys2.length) {
  584. return false;
  585. }
  586. for (const key in obj1) {
  587. if (obj1.hasOwnProperty(key)) {
  588. if (obj1[key]!== obj2[key]) {
  589. return false;
  590. }
  591. }
  592. }
  593. return true;
  594. },
  595. handleItem(i,item){
  596. console.log(item);
  597. this.num = 1
  598. this.item = i
  599. if(!item.childClassList) return
  600. this.show2 = true
  601. foodGoodsDetail({productId:i.productId,shopId:this.shopId}).then(res=>{
  602. if(res.state = 'Success'){
  603. this.goodsInfo = res.content.data
  604. this.chooseInfo = {}
  605. if(this.goodsInfo.details.spu_specs){//奈雪的茶
  606. this.goodsInfo.details.spu_specs.map(item=>{
  607. this.$set(this.chooseInfo,item.code,item.values[0])
  608. })
  609. }else if(this.goodsInfo.details.specifications){//喜茶
  610. this.goodsInfo.details.specifications.map(item=>{
  611. this.$set(this.chooseInfo,item.id,item.values[0])
  612. })
  613. }else if(this.goodsInfo.details.optional&&this.goodsInfo.details.optional.length&&this.ot=='XBK'){//星巴克
  614. this.goodsInfo.details.optional.map(item=>{
  615. this.$set(this.chooseInfo,item.id,item.sku_infos[0])
  616. })
  617. }else if(this.goodsInfo.details.optional&&this.goodsInfo.details.optional.length){//麦当劳
  618. this.goodsInfo.details.optional.map(item=>{
  619. // id可能相同 所以加上类目的name 方便创建订单时能取到id
  620. this.$set(this.chooseInfo,item.name+'-'+item.id,item.sku_infos[0])
  621. })
  622. }
  623. console.log(this.chooseInfo);
  624. }
  625. })
  626. },
  627. handleCar(){
  628. this.show = true
  629. },
  630. handleTab(index){
  631. this.active = index
  632. this.scrollTo = 'title'+index
  633. },
  634. chooseTag(val){
  635. console.log('当前',val);
  636. },
  637. menuList(){
  638. uni.showLoading({
  639. title:'加载中'
  640. })
  641. menuList(this.shopId).then(res=>{
  642. uni.hideLoading()
  643. if(res.state = 'Success'){
  644. this.list = res.content.data
  645. this.list.map((item,index)=>{
  646. if(this.ot != 'Kfc'&&item.childClassList){
  647. item.menuVoList = JSON.parse(JSON.stringify(item.childClassList[0].menuVoList))
  648. // delete item.childClassList
  649. }
  650. // 滚动到对应栏目
  651. if(this.cateName&&(item.topName == this.cateName)){
  652. this.handleTab(index)
  653. }
  654. })
  655. this.$nextTick(()=>{
  656. let query = uni.createSelectorQuery().in(this);
  657. query.selectAll('.section-name').boundingClientRect(data=>{
  658. console.log(data);
  659. this.topList =data.map(item=>{
  660. return item.top
  661. })
  662. }).exec();
  663. })
  664. }
  665. })
  666. },
  667. shopDetail(){
  668. shopDetail({"id": this.shopId,
  669. "lat": "",
  670. "lon": ""}).then(res=>{
  671. if(res.state = 'Success'){
  672. this.shopInfo.shopName = res.content.data.shopName
  673. this.shopInfo.address = res.content.data.address
  674. //是否在营业时间内
  675. if(res.content.data.openTime&&res.content.data.closeTime&&!this.isInBusinessHours(res.content.data.openTime,res.content.data.closeTime)){
  676. this.show1 = true
  677. }
  678. }
  679. })
  680. },
  681. buy() {
  682. let that = this
  683. if (uni.getStorageSync('token')) {
  684. if(JSON.parse(uni.getStorageSync('userInfo')).setMealCode != 0&&JSON.parse(uni.getStorageSync('userInfo')).setMealCode){
  685. let info ={
  686. shopName:this.shopInfo.shopName,
  687. address:this.shopInfo.address,
  688. shopId:this.shopId,
  689. products:this.carList,
  690. total:this.total,
  691. openTime:this.shopInfo.openTime,
  692. closeTime:this.shopInfo.closeTime,
  693. totalNum:this.totalNum
  694. }
  695. uni.navigateTo({
  696. url:`/orderFood/pay`,
  697. success: function(res) {
  698. // 通过eventChannel向被打开页面传送数据
  699. res.eventChannel.emit('pay', info)
  700. }
  701. })
  702. }else{
  703. uni.showModal({
  704. title:'此商品需要开通会员才能购买',
  705. cancelText:'下次再说',
  706. confirmText:'立即开通',
  707. success(res) {
  708. if(res.confirm){
  709. uni.navigateTo({
  710. url:'/my/memberCenter/index'
  711. })
  712. }
  713. }
  714. })
  715. }
  716. }else{
  717. uni.showModal({
  718. title:'请登录',
  719. confirmText:'去登录',
  720. success(res){
  721. console.log(res);
  722. if(res.confirm){
  723. uni.navigateTo({
  724. url:`/login/login/login?redirect=/orderFood/shopDetail&id=${that.shopId}`
  725. })
  726. }
  727. }
  728. })
  729. }
  730. },
  731. isInBusinessHours(openTimeStr, closeTimeStr) {
  732. let open = openTimeStr
  733. let close = closeTimeStr
  734. if(open.indexOf('.') != -1){
  735. let index = open.indexOf('.')
  736. open = open.substr(0,index)
  737. }
  738. if(close.indexOf('.') != -1){
  739. let index = close.indexOf('.')
  740. close = close.substr(0,index)
  741. }
  742. const now = new Date();
  743. const openTime = new Date(open);
  744. const closeTime = new Date(close);
  745. // 获取当前时间的时分秒
  746. const nowHours = now.getHours();
  747. const nowMinutes = now.getMinutes();
  748. const nowSeconds = now.getSeconds();
  749. // 获取开店时间的时分秒
  750. const openHours = openTime.getHours();
  751. const openMinutes = openTime.getMinutes();
  752. const openSeconds = openTime.getSeconds();
  753. // 获取关店时间的时分秒
  754. const closeHours = closeTime.getHours();
  755. const closeMinutes = closeTime.getMinutes();
  756. const closeSeconds = closeTime.getSeconds();
  757. // 将当前时间、开店时间和关店时间转换为秒数
  758. const nowSecondsTotal = nowHours * 3600 + nowMinutes * 60 + nowSeconds;
  759. const openSecondsTotal = openHours * 3600 + openMinutes * 60 + openSeconds;
  760. const closeSecondsTotal = closeHours * 3600 + closeMinutes * 60 + closeSeconds;
  761. console.log(openSecondsTotal,closeSecondsTotal,nowSecondsTotal);
  762. if ( openSecondsTotal <nowSecondsTotal && nowSecondsTotal<closeSecondsTotal ) {
  763. return true
  764. } else {
  765. return false
  766. }
  767. }
  768. },
  769. onLoad(options) {
  770. console.log(this.isInBusinessHours("2019-08-24T09:15:22.123Z","2019-08-24T14:15:22.123"));
  771. this.cateName = options.cateName
  772. this.shopId = options.id || "63836999-5117-4980-8632-497f007808ef"
  773. // this.shopId = "63836999-5117-4980-8632-497f007808ef"
  774. this.shopDetail()
  775. this.menuList()
  776. },
  777. onReady () {
  778. // this.Observer = uni.createIntersectionObserver(this)
  779. // this.Observer.relativeTo('.test',{bottom: 0}).observe('.title0', (res) => {
  780. // console.log(12312);
  781. // // this.$emit('changeTag',this.value)
  782. // })
  783. }
  784. }
  785. </script>
  786. <style lang="scss" >
  787. .orderFood{
  788. .shop-info{
  789. width: 100%;
  790. height: 130rpx;
  791. padding: 20rpx 24rpx;
  792. box-sizing: border-box;
  793. border-bottom: 2rpx solid #F0F0F0;
  794. // position: fixed;
  795. // top: 0%;
  796. // left: 0%;
  797. // z-index: 9;
  798. background: #fff;
  799. .shop-name{
  800. font-weight: bold;
  801. font-size: 32rpx;
  802. color: #222222;
  803. }
  804. .address{
  805. font-size: 24rpx;
  806. color: #AAAAAA;
  807. margin-top: 16rpx;
  808. }
  809. }
  810. .content{
  811. height: calc(100vh - 130rpx);
  812. display: flex;
  813. overflow: auto;
  814. box-sizing: border-box;
  815. padding-bottom: calc(98rpx + env(safe-area-inset-bottom)) ;
  816. .left{
  817. flex: 0 0 176rpx;
  818. background: #F7F7F7;
  819. .item{
  820. text-align: center;
  821. padding: 16rpx 0;
  822. .icon{
  823. width: 76rpx;
  824. height: 76rpx;
  825. }
  826. .name{
  827. font-size: 24rpx;
  828. color: #AAAAAA;
  829. }
  830. }
  831. .item.active{
  832. background: #FFFFFF;
  833. .name{
  834. color: #222222;
  835. }
  836. }
  837. }
  838. .right{
  839. flex: 1;
  840. padding: 0 24rpx;
  841. overflow: auto;
  842. position: relative;
  843. .test{
  844. width: 100%;
  845. height: 60rpx;
  846. background: red;
  847. position: fixed;
  848. }
  849. .section{
  850. .section-name{
  851. font-weight: bold;
  852. font-size: 28rpx;
  853. color: #222222;
  854. padding-top: 30rpx;
  855. }
  856. .item{
  857. display: flex;
  858. margin-top: 28rpx;
  859. .img{
  860. width: 160rpx;
  861. height: 160rpx;
  862. border-radius: 8rpx 8rpx 8rpx 8rpx;
  863. }
  864. .info{
  865. flex: 1;
  866. margin-left: 26rpx;
  867. display: flex;
  868. flex-direction: column;
  869. justify-content: space-around;
  870. .title{
  871. font-weight: bold;
  872. font-size: 32rpx;
  873. color: #222222;
  874. }
  875. .btn-box{
  876. display: flex;
  877. justify-content: space-between;
  878. .price-box{
  879. display: flex;
  880. align-items: center;
  881. .price{
  882. display: flex;
  883. align-items: flex-end;
  884. color: #FF4D3A;
  885. .unit{
  886. font-size: 20rpx;
  887. }
  888. .num{
  889. font-weight: bold;
  890. font-size: 36rpx;
  891. }
  892. }
  893. .old-price{
  894. font-weight: normal;
  895. font-size: 24rpx;
  896. color: #AAAAAA;
  897. text-decoration: line-through;
  898. margin-left: 16rpx;
  899. }
  900. }
  901. .btn{
  902. width: 40rpx;
  903. height: 40rpx;
  904. }
  905. }
  906. }
  907. }
  908. }
  909. }
  910. }
  911. .total-box1{
  912. position: inherit!important;
  913. padding-bottom: 0!important;
  914. }
  915. .total-box{
  916. position: fixed;
  917. left: 0%;
  918. bottom: 0;
  919. width: 100%;
  920. padding: 10rpx 24rpx env(safe-area-inset-bottom);
  921. box-sizing: border-box;
  922. display: flex;
  923. align-items: center;
  924. justify-content: space-between;
  925. border-top: 1rpx solid #EEEEEE;
  926. .price-box{
  927. display: flex;
  928. .car-box{
  929. position: relative;
  930. display: flex;
  931. align-items: center;
  932. .icon{
  933. width: 48rpx;
  934. height: 48rpx;
  935. }
  936. .num{
  937. position: absolute;
  938. top: -18rpx;
  939. right: -18rpx;
  940. min-width: 36rpx;
  941. height: 36rpx;
  942. line-height: 36rpx;
  943. text-align: center;
  944. border-radius: 18rpx;
  945. background: #222222;
  946. font-weight: bold;
  947. font-size: 24rpx;
  948. color: #FFFFFF;
  949. margin-left: 20rpx;
  950. }
  951. }
  952. .price{
  953. display: flex;
  954. align-items: flex-end;
  955. color: #FF4D3A;
  956. .unit{
  957. font-size: 20rpx;
  958. }
  959. .num{
  960. font-weight: bold;
  961. font-size: 36rpx;
  962. }
  963. }
  964. }
  965. .buy{
  966. width: 200rpx;
  967. height: 80rpx;
  968. line-height: 80rpx;
  969. text-align: center;
  970. background: #EE4320;
  971. border-radius: 40rpx 40rpx 40rpx 40rpx;
  972. font-weight: bold;
  973. font-size: 28rpx;
  974. color: #FFFFFF;
  975. margin: 0;
  976. }
  977. .buy::after{
  978. border: none;
  979. outline: none;
  980. }
  981. .buy.disabled{
  982. background: #F6F6F6;
  983. color: #AAAAAA;
  984. }
  985. }
  986. .popup-title-box{
  987. display: flex;
  988. justify-content: space-between;
  989. padding: 24rpx;
  990. .title{
  991. font-weight: bold;
  992. font-size: 28rpx;
  993. color: #222222;
  994. }
  995. .clear{
  996. font-size: 28rpx;
  997. color: #AAAAAA;
  998. }
  999. }
  1000. .u-empty{
  1001. padding: 30rpx 0;
  1002. }
  1003. .car-content{
  1004. padding-bottom: 30rpx;
  1005. max-height: 700rpx;
  1006. overflow: auto;
  1007. .item{
  1008. display: flex;
  1009. margin-top: 28rpx;
  1010. padding: 0 24rpx;
  1011. .img{
  1012. width: 160rpx;
  1013. height: 160rpx;
  1014. border-radius: 8rpx 8rpx 8rpx 8rpx;
  1015. }
  1016. .info{
  1017. flex: 1;
  1018. margin-left: 26rpx;
  1019. display: flex;
  1020. flex-direction: column;
  1021. justify-content: space-between;
  1022. .title{
  1023. font-weight: bold;
  1024. font-size: 32rpx;
  1025. color: #222222;
  1026. }
  1027. .type{
  1028. font-weight: normal;
  1029. font-size: 24rpx;
  1030. color: #AAAAAA;
  1031. }
  1032. .btn-box{
  1033. display: flex;
  1034. justify-content: space-between;
  1035. .price-box{
  1036. display: flex;
  1037. align-items: center;
  1038. .price{
  1039. display: flex;
  1040. align-items: flex-end;
  1041. color: #FF4D3A;
  1042. .unit{
  1043. font-size: 20rpx;
  1044. }
  1045. .num{
  1046. font-weight: bold;
  1047. font-size: 36rpx;
  1048. }
  1049. }
  1050. .old-price{
  1051. font-weight: normal;
  1052. font-size: 24rpx;
  1053. color: #AAAAAA;
  1054. text-decoration: line-through;
  1055. margin-left: 16rpx;
  1056. }
  1057. }
  1058. .count-box{
  1059. display: flex;
  1060. align-items: center;
  1061. .num{
  1062. width: 100rpx;
  1063. text-align: center;
  1064. font-size: 28rpx;
  1065. color: #222222;
  1066. }
  1067. .btn{
  1068. width: 40rpx;
  1069. height: 40rpx;
  1070. }
  1071. }
  1072. }
  1073. }
  1074. }
  1075. }
  1076. .modal-box{
  1077. .shop-name{
  1078. font-weight: 600;
  1079. font-size: 32rpx;
  1080. color: #181818;
  1081. width: 100%;
  1082. text-align: center;
  1083. }
  1084. .address{
  1085. font-weight: 300;
  1086. font-size: 24rpx;
  1087. color: #AAAAAA;
  1088. margin-top: 4rpx;
  1089. width: 100%;
  1090. text-align: center;
  1091. }
  1092. .notice{
  1093. margin-top: 20rpx;
  1094. font-weight: 300;
  1095. font-size: 24rpx;
  1096. color: #AAAAAA;
  1097. text-align: center;
  1098. }
  1099. }
  1100. .popup-goodsDetail{
  1101. padding-bottom: env(safe-area-inset-bottom);
  1102. .img{
  1103. width: 750rpx;
  1104. height: 400rpx;
  1105. vertical-align: bottom;
  1106. }
  1107. .box{
  1108. max-height: 60vh;
  1109. overflow: auto;
  1110. }
  1111. .popup-content{
  1112. padding: 0 24rpx;
  1113. .title{
  1114. font-weight: 800;
  1115. font-size: 32rpx;
  1116. color: #222222;
  1117. margin-top: 24rpx;
  1118. }
  1119. .desc{
  1120. font-size: 24rpx;
  1121. color: #222222;
  1122. margin: 24rpx 0;
  1123. }
  1124. .choose-box{
  1125. .choose-item{
  1126. .choose-title{
  1127. font-size: 28rpx;
  1128. color: #222222;
  1129. }
  1130. .item-box{
  1131. display: flex;
  1132. flex-wrap: wrap;
  1133. padding: 20rpx 0;
  1134. .item{
  1135. font-size: 24rpx;
  1136. color: #222222;
  1137. padding: 0 20rpx;
  1138. line-height: 44rpx;
  1139. height: 44rpx;
  1140. background: #fff;
  1141. border-radius: 8rpx 8rpx 8rpx 8rpx;
  1142. border: 2rpx solid #F0F0F0;
  1143. margin-right: 20rpx;
  1144. margin-bottom: 10rpx;
  1145. }
  1146. .item.active{
  1147. border: 2rpx solid #EE4320;
  1148. background: #FEECE8;
  1149. }
  1150. }
  1151. }
  1152. }
  1153. }
  1154. .btn-box{
  1155. padding: 20rpx 24rpx;
  1156. border-top: 1rpx solid #EEEEEE;
  1157. .order-info{
  1158. display: flex;
  1159. align-items: center;
  1160. justify-content: space-between;
  1161. .left{
  1162. .price-box{
  1163. display: flex;
  1164. align-items: center;
  1165. .price{
  1166. font-weight: bold;
  1167. font-size: 28rpx;
  1168. color: #222222;
  1169. }
  1170. .old-price{
  1171. font-size: 22rpx;
  1172. color: #AAAAAA;
  1173. text-decoration: line-through;
  1174. }
  1175. }
  1176. .choose{
  1177. font-size: 20rpx;
  1178. color: #AAAAAA;
  1179. margin-top: 8rpx;
  1180. }
  1181. }
  1182. .count-box{
  1183. display: flex;
  1184. align-items: center;
  1185. .num{
  1186. width: 100rpx;
  1187. text-align: center;
  1188. font-size: 28rpx;
  1189. color: #222222;
  1190. }
  1191. .btn1{
  1192. width: 40rpx;
  1193. height: 40rpx;
  1194. }
  1195. }
  1196. }
  1197. .btn{
  1198. width: 702rpx;
  1199. height: 80rpx;
  1200. background: #EE4320;
  1201. font-weight: bold;
  1202. font-size: 28rpx;
  1203. color: #FFFFFF;
  1204. margin-top: 24rpx;
  1205. }
  1206. }
  1207. }
  1208. }
  1209. </style>