index.vue 27 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219
  1. <template>
  2. <view class="container" :style="{ height: winHeight+ 'px' }">
  3. <!-- 状态栏高度 -->
  4. <view :style="{ height: `${statusBarHeight}px` }"></view>
  5. <!-- 导航栏 -->
  6. <view :style="{ height: `${navigationBarHeight}rpx`,lineHeight: `${navigationBarHeight}rpx`}" class="order-nav">
  7. <view class="back-button" @tap="handBack()"></view>
  8. <text>吉阿婆麻辣烫</text>
  9. </view>
  10. <view class="main">
  11. <view class="nav">
  12. <view class="header">
  13. <view class="left">
  14. <view class="store-name">
  15. <text style="font-weight: 600;font-size: 35rpx;color: #141414;">{{ merchanInfo.name }}</text>
  16. <view class="iconfont iconarrow-right"></view>
  17. </view>
  18. <view class="store-score" style="margin: 7rpx 0;">
  19. <text style="font-weight: 600;font-size: 27rpx;color: #FD6716;">{{ merchanInfo.starLevel }}分</text>
  20. <text style="font-size: 21rpx;color: #999999;margin-left: 6rpx;">月销 {{ merchanInfo.sales || 0 }}</text>
  21. </view>
  22. <view class="store-addr">
  23. <text style="font-size: 23rpx;color: #141414;">商家地址:{{ merchanInfo.addressDetail }}</text>
  24. </view>
  25. <view class="store-tip" style="padding: 10rpx 30rpx 10rpx 15px ;height: 48rpx;">
  26. <swiper :indicator-dots="false" :autoplay="true" interval="2500" :duration="500" vertical="true" circular="true">
  27. <block v-for="(item,index) in merchanInfo.headline" :key='index'>
  28. <swiper-item catchtouchmove='catchTouchMove'>
  29. <view class='text acea-row row-between-wrapper'>
  30. <view class='newsTitle'>
  31. <text class='iconfont icon-laba ' style="font-size: 24rpx;margin-right: 10rpx;"></text>
  32. <text>{{item.title}}</text>
  33. </view>
  34. </view>
  35. </swiper-item>
  36. </block>
  37. </swiper>
  38. </view>
  39. </view>
  40. </view>
  41. </view>
  42. <view style="width: 100%;height: 10rpx; background-color: #F8F9FD;"></view>
  43. </view>
  44. <view class="content">
  45. <scroll-view style="height: 950rpx" class="menus" scroll-with-animation scroll-y>
  46. <view class="wrapper">
  47. <view class="menu" :id="`menu-${item.id}`" :class="{'current': item.id === currentCateId}" v-for="(item, index) in goods"
  48. :key="index" @tap="handleMenuTap(item.id)">
  49. <text>{{ item.name }}</text>
  50. <view class="dot" v-show="menuCartNum(item.id)">{{ menuCartNum(item.id) }}</view>
  51. </view>
  52. </view>
  53. </scroll-view>
  54. <!-- goods list begin -->
  55. <scroll-view class="goods" scroll-with-animation scroll-y :scroll-top="cateScrollTop" @scroll="handleGoodsScroll"
  56. @scrolltolower="handleFoot" :scroll-into-view="menuScrollIntoView">
  57. <view class="wrapper">
  58. <view class="list">
  59. <!-- category begin -->
  60. <view style="font-weight: 400;font-size: 21rpx;color: #999999;text-align: center;margin-bottom: 19rpx;">————温馨提示:湿度选择,避免浪费
  61. ————</view>
  62. <view class="category" v-for="(item, index) in goods" :key="index" :id="`cate-${item.id}`">
  63. <view class="items">
  64. <!-- 商品 begin -->
  65. <!-- <view v-if="!item.goodsList">无商品</view> -->
  66. <view class="good" v-for="(good, key) in item.goodsList" :key="key">
  67. <image :src="good.image" class="image" @tap="console.log('点击图片')"></image>
  68. <view class="right">
  69. <text class="name">{{ good.name }}</text>
  70. <text class="tips">{{ good.content }}</text>
  71. <view class="price_and_action">
  72. <text class="price">¥{{ good.otPrice }}</text>
  73. <view class="btn-group" v-if="good.use_property">
  74. <button type="primary" class="btn property_btn bg-color" hover-class="none" size="mini" @tap="console.log('选规格')">
  75. 选规格
  76. </button>
  77. <view class="dot" v-show="goodCartNum(good.id)">{{ goodCartNum(good.id) }}</view>
  78. </view>
  79. <view class="btn-group" v-else>
  80. <button type="default" v-show="goodCartNum(good.id)" plain class="btn reduce_btn" size="mini" hover-class="none"
  81. @tap="handleReduceFromCart(item, good)">
  82. <view class="iconfont iconsami-select">-</view>
  83. </button>
  84. <view class="number" v-show="goodCartNum(good.id)">{{ goodCartNum(good.id) }}</view>
  85. <button type="primary" class="btn add_btn bg-color" size="min" hover-class="none" @tap="handleAddToCart(item, good, 1)">
  86. <view class="iconfont iconadd-select">+</view>
  87. </button>
  88. </view>
  89. </view>
  90. </view>
  91. </view>
  92. <!-- 商品 end -->
  93. </view>
  94. </view>
  95. <!-- category end -->
  96. </view>
  97. </view>
  98. </scroll-view>
  99. <!-- goods list end -->
  100. </view>
  101. <!-- content end -->
  102. <!-- 购物车栏 begin -->
  103. <view class="cart-box" style="bottom: 77rpx">
  104. <view class="mark">
  105. <image src="/static/img/ic-security-settings.png" class="cart-img" @tap=""></image>
  106. <view class="tag" v-if="cart.length > 0">{{ getCartGoodsNumber }}</view>
  107. </view>
  108. <view style="font-weight: 500;font-size: 27rpx;color: #999999;" class="price" v-if="cart.length === 0">配送费2元</view>
  109. <view style="font-weight: 600;font-size: 27rpx;color: #FFFFFF;" class="price" v-else>¥{{ getCartGoodsPrice || 0 }}</view>
  110. <button :style="{backgroundColor: disabledPay ? '#000' : ''}" type="primary" class="pay-btn bg-color" @tap="toPay"
  111. :disabled="disabledPay">
  112. {{ disabledPay ? `差${spread}元起送` : '去结算' }}
  113. </button>
  114. </view>
  115. <!-- 购物车栏 end -->
  116. </view>
  117. </template>
  118. <script>
  119. // +----------------------------------------------------------------------
  120. // | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
  121. // +----------------------------------------------------------------------
  122. // | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
  123. // +----------------------------------------------------------------------
  124. // | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
  125. // +----------------------------------------------------------------------
  126. // | Author: CRMEB Team <admin@crmeb.com>
  127. // +----------------------------------------------------------------------
  128. import {
  129. getCategoryCacheTree,
  130. getMerchantInfo,
  131. getMerchantProList
  132. } from '@/api/merchant.js';
  133. let app = getApp();
  134. var statusBarHeight = uni.getSystemInfoSync().statusBarHeight + 'rpx';
  135. export default {
  136. data() {
  137. return {
  138. merId: 0,
  139. winHeight: 0,
  140. merchanInfo: {},
  141. statusBarHeight: app.globalData.statusBarHeight,
  142. navigationBarHeight: 112,
  143. goods: [], //所有商品
  144. loading: true,
  145. currentCateId: 1, //默认分类
  146. cateScrollTop: 0,
  147. lastScrollTop: 0,
  148. menuScrollIntoView: '',
  149. cart: [], //购物车
  150. goodDetailModalVisible: false, //是否饮品详情模态框
  151. good: {}, //当前饮品
  152. category: {}, //当前饮品所在分类
  153. cartPopupVisible: false,
  154. sizeCalcState: false,
  155. orderType: 'takeout',
  156. store: {
  157. min_price: 8
  158. }
  159. }
  160. },
  161. onLoad(options) {
  162. let that = this;
  163. uni.getSystemInfo({
  164. success: function(res) {
  165. that.winHeight = res.windowHeight
  166. },
  167. });
  168. this.merId = uni.getStorageSync('merId')
  169. //首页数据加载
  170. // 获取商家信息
  171. getMerchantInfo(this.merId).then(res => {
  172. this.merchanInfo = res.data
  173. });
  174. // 获取商品列表
  175. getCategoryCacheTree(this.merId).then(res => {
  176. this.goods = res.data.map(item => {
  177. return {
  178. id: item.id,
  179. name: item.name
  180. }
  181. })
  182. this.goods.unshift({
  183. id: 9999,
  184. name: '推荐'
  185. })
  186. this.currentCateId = this.goods[0].id
  187. })
  188. // this.getIndexConfig();
  189. // #ifdef MP-WEIXIN
  190. // 获取微信胶囊的位置信息 width,height,top,right,left,bottom
  191. const custom = wx.getMenuButtonBoundingClientRect()
  192. // 导航栏高度(标题栏高度) = 胶囊高度 + (顶部距离 - 状态栏高度) * 2
  193. // this.navigationBarHeight = custom.height + (custom.top - this.statusBarHeight) * 2
  194. // console.log("导航栏高度:"+this.globalData.navigationBarHeight)
  195. // #endif
  196. },
  197. computed: {
  198. goodCartNum() { //计算单个饮品添加到购物车的数量
  199. return (id) => this.cart.reduce((acc, cur) => {
  200. if (cur.id === id) {
  201. return acc += cur.number
  202. }
  203. return acc
  204. }, 0)
  205. },
  206. menuCartNum() {
  207. return (id) => this.cart.reduce((acc, cur) => {
  208. if (cur.cate_id === id) {
  209. return acc += cur.number
  210. }
  211. return acc
  212. }, 0)
  213. },
  214. getCartGoodsNumber() { //计算购物车总数
  215. return this.cart.reduce((acc, cur) => acc + cur.number, 0)
  216. },
  217. getCartGoodsPrice() { //计算购物车总价
  218. return this.cart.reduce((acc, cur) => acc + cur.number * cur.price, 0)
  219. },
  220. disabledPay() { //是否达到起送价
  221. return this.orderType == 'takeout' && (this.getCartGoodsPrice < this.store.min_price) ? true : false
  222. },
  223. spread() { //差多少元起送
  224. if (this.orderType != 'takeout') return
  225. return parseFloat((this.store.min_price - this.getCartGoodsPrice).toFixed(2))
  226. }
  227. },
  228. watch: {
  229. currentCateId(newId, oldId) {
  230. console.log(11111111111111111111)
  231. // 获取商品
  232. if (this.goods.length > 0) {
  233. getMerchantProList(newId, this.merId, 1, 999).then(res => {
  234. this.goods = this.goods.map(item => {
  235. if (item.id === newId) {
  236. item.goodsList = res.data.list
  237. }
  238. return {
  239. ...item
  240. }
  241. })
  242. })
  243. }
  244. }
  245. },
  246. methods: {
  247. handBack() {
  248. uni.navigateBack({
  249. delta: 1
  250. })
  251. },
  252. handleMenuTap(id) { //点击菜单项事件
  253. this.menuScrollIntoView = `cate-${id}`
  254. if (!this.sizeCalcState) {
  255. this.calcSize()
  256. }
  257. this.goods.forEach(item => {
  258. if (item.id !== this.currentCateId) {
  259. this.currentCateId = item.id // 点击左列获取前列表全部数据
  260. }
  261. })
  262. this.$nextTick(() => this.cateScrollTop = this.goods.find(item => item.id == id).top)
  263. },
  264. handleGoodsScroll({
  265. detail
  266. }) { //商品列表滚动事件
  267. if (!this.sizeCalcState) {
  268. this.calcSize()
  269. }
  270. const {
  271. scrollTop
  272. } = detail
  273. let tabs = this.goods.filter(item => item.top <= scrollTop).reverse()
  274. if (tabs.length > 0) {
  275. this.currentCateId = tabs[0].id
  276. }
  277. },
  278. handleFoot($event) {
  279. const nextItems = this.findNextAll(this.goods, item => item.id === this.currentCateId);
  280. if (nextItems.id) {
  281. this.currentCateId = nextItems.id
  282. }
  283. },
  284. findNextAll(arr, condition) {
  285. const index = arr.findIndex(condition);
  286. if (index !== -1) {
  287. return arr[index + 1] || {}; // 返回符合条件之后的记录
  288. }
  289. return {}; // 如果没有找到符合条件的记录,返回空对象
  290. },
  291. calcSize() {
  292. let h = 10
  293. this.goods.forEach(item => {
  294. let view = uni.createSelectorQuery().select(`#cate-${item.id}`)
  295. view.fields({
  296. size: true
  297. }, data => {
  298. // if (data.goodsList) {
  299. item.top = h
  300. h += data.height
  301. item.bottom = h
  302. // }
  303. }).exec()
  304. })
  305. this.sizeCalcState = true
  306. },
  307. showGoodDetailModal(item, good) {
  308. this.good = JSON.parse(JSON.stringify({ ...good,
  309. number: 1
  310. }))
  311. this.category = JSON.parse(JSON.stringify(item))
  312. this.goodDetailModalVisible = true
  313. },
  314. handlePropertyAdd() {
  315. this.good.number += 1
  316. },
  317. handlePropertyReduce() {
  318. if (this.good.number === 1) return
  319. this.good.number -= 1
  320. },
  321. handleAddToCartInModal() {
  322. const product = Object.assign({}, this.good, {
  323. props_text: this.getGoodSelectedProps(this.good),
  324. props: this.getGoodSelectedProps(this.good, 'id')
  325. })
  326. this.handleAddToCart(this.category, product, this.good.number)
  327. this.closeGoodDetailModal()
  328. },
  329. getGoodSelectedProps(good, type = 'text') { //计算当前饮品所选属性
  330. if (good.use_property) {
  331. let props = []
  332. good.property.forEach(({
  333. values
  334. }) => {
  335. values.forEach(value => {
  336. if (value.is_default) {
  337. props.push(type === 'text' ? value.value : value.id)
  338. }
  339. })
  340. })
  341. return type === 'text' ? props.join(',') : props
  342. }
  343. return ''
  344. },
  345. handleReduceFromCart(item, good) {
  346. const index = this.cart.findIndex(item => item.id === good.id)
  347. this.cart[index].number -= 1
  348. if (this.cart[index].number <= 0) {
  349. this.cart.splice(index, 1)
  350. }
  351. },
  352. handleAddToCart(cate, good, num) { //添加到购物车
  353. const index = this.cart.findIndex(item => {
  354. if (good.use_property) {
  355. return (item.id === good.id) && (item.props_text === good.props_text)
  356. } else {
  357. return item.id === good.id
  358. }
  359. })
  360. if (index > -1) {
  361. this.cart[index].number += num
  362. } else {
  363. this.cart.push({
  364. id: good.id,
  365. cate_id: cate.id,
  366. name: good.name,
  367. price: good.price,
  368. number: num,
  369. image: good.images,
  370. use_property: good.use_property,
  371. props_text: good.props_text,
  372. props: good.props
  373. })
  374. }
  375. },
  376. toPay() {
  377. // if(!this.isLogin) {
  378. // uni.navigateTo({url: '/pages/login/login'})
  379. // return
  380. // }
  381. uni.showLoading({
  382. title: '加载中'
  383. })
  384. uni.setStorageSync('cart', JSON.parse(JSON.stringify(this.cart)))
  385. uni.navigateTo({
  386. url: '/pages/goods/order_confirm/index'
  387. })
  388. uni.hideLoading()
  389. }
  390. }
  391. }
  392. </script>
  393. <style lang="scss" scoped>
  394. /* #ifdef H5 */
  395. page {
  396. min-height: 100%;
  397. }
  398. /* #endif */
  399. .bg-color {
  400. background-color: $bg-color-primary;
  401. }
  402. .order-nav {
  403. // height: 111rpx;
  404. position: relative;
  405. background-color: #FF6702;
  406. display: flex;
  407. align-items: center;
  408. justify-content: center;
  409. .back-button {
  410. position: absolute;
  411. left: 20rpx;
  412. }
  413. text {
  414. font-weight: 500;
  415. font-size: 35rpx;
  416. color: #FFFFFF;
  417. }
  418. }
  419. .container {
  420. display: flex;
  421. flex-direction: column;
  422. overflow: hidden;
  423. position: relative;
  424. }
  425. .loading {
  426. width: 100%;
  427. height: 100%;
  428. display: flex;
  429. align-items: center;
  430. justify-content: center;
  431. image {
  432. width: 260rpx;
  433. height: 260rpx;
  434. position: relative;
  435. margin-top: -200rpx;
  436. /* #ifdef h5 */
  437. margin-top: 0;
  438. /* #endif */
  439. }
  440. }
  441. .stores {
  442. width: 100%;
  443. display: flex;
  444. flex-direction: column;
  445. justify-content: flex-start;
  446. margin-bottom: -40rpx;
  447. .store {
  448. width: 100%;
  449. background-color: $bg-color-grey;
  450. padding: 20rpx;
  451. display: flex;
  452. align-items: center;
  453. margin-bottom: 20rpx;
  454. border-radius: 6rpx;
  455. .iconfont {
  456. font-size: 50rpx;
  457. margin-right: 15rpx;
  458. &.iconradio-button-off {
  459. color: $text-color-assist;
  460. }
  461. &.iconradio-button-on {
  462. color: $color-primary;
  463. }
  464. }
  465. .infos {
  466. flex: 1;
  467. display: flex;
  468. flex-direction: column;
  469. color: $text-color-base;
  470. overflow: hidden;
  471. .name_and_distance {
  472. width: 100%;
  473. display: flex;
  474. justify-content: space-between;
  475. margin-bottom: 10rpx;
  476. overflow: hidden;
  477. .name {
  478. flex: 1;
  479. flex-shrink: 0;
  480. overflow: hidden;
  481. text-overflow: ellipsis;
  482. white-space: nowrap;
  483. font-size: $font-size-lg;
  484. }
  485. .distance {
  486. flex-shrink: 0;
  487. font-size: $font-size-lg;
  488. font-weight: bold;
  489. margin-left: 20rpx;
  490. }
  491. }
  492. .street {
  493. color: $text-color-assist;
  494. font-size: $font-size-sm;
  495. }
  496. }
  497. }
  498. }
  499. .main {
  500. overflow: hidden;
  501. width: 100%;
  502. display: flex;
  503. flex-direction: column;
  504. }
  505. .nav {
  506. width: 100%;
  507. flex-shrink: 0;
  508. display: flex;
  509. flex-direction: column;
  510. border-radius: 23rpx;
  511. padding: 19rpx 57rpx 38rpx 58rpx;
  512. background-color: #ffffff;
  513. .header {
  514. width: 100%;
  515. display: flex;
  516. align-items: center;
  517. justify-content: space-between;
  518. .left {
  519. flex: 1;
  520. display: flex;
  521. flex-direction: column;
  522. .store-name {
  523. display: flex;
  524. justify-content: flex-start;
  525. align-items: center;
  526. font-size: $font-size-lg;
  527. margin-bottom: 10rpx;
  528. .iconfont {
  529. margin-left: 10rpx;
  530. line-height: 100%;
  531. }
  532. }
  533. .store-tip {
  534. font-weight: 400;
  535. font-size: 21rpx;
  536. color: #858687;
  537. margin-top: 10rpx;
  538. background: #F8F9FB;
  539. border-radius: 4rpx;
  540. }
  541. }
  542. .right {
  543. background-color: $bg-color-grey;
  544. border-radius: 38rpx;
  545. display: flex;
  546. align-items: center;
  547. font-size: $font-size-sm;
  548. padding: 0 38rpx;
  549. color: $text-color-assist;
  550. .dinein,
  551. .takeout {
  552. position: relative;
  553. display: flex;
  554. align-items: center;
  555. &.active {
  556. padding: 14rpx 38rpx;
  557. color: #ffffff;
  558. background-color: $color-primary;
  559. border-radius: 38rpx;
  560. }
  561. }
  562. .takeout {
  563. margin-left: 20rpx;
  564. height: 100%;
  565. flex: 1;
  566. padding: 14rpx 0;
  567. }
  568. .dinein.active {
  569. margin-left: -38rpx;
  570. }
  571. .takeout.active {
  572. margin-right: -38rpx;
  573. }
  574. }
  575. }
  576. .coupon {
  577. flex: 1;
  578. width: 100%;
  579. background-color: $bg-color-primary;
  580. font-size: $font-size-base;
  581. color: $color-primary;
  582. padding: 0 20rpx;
  583. display: flex;
  584. align-items: center;
  585. overflow: hidden;
  586. .title {
  587. flex: 1;
  588. margin-left: 10rpx;
  589. overflow: hidden;
  590. white-space: nowrap;
  591. text-overflow: ellipsis;
  592. }
  593. .iconfont {
  594. line-height: 100%;
  595. }
  596. }
  597. }
  598. .content {
  599. flex: 1;
  600. overflow: hidden;
  601. width: 100%;
  602. display: flex;
  603. border-radius: 23rpx 23rpx 0rpx 0rpx;
  604. .menus {
  605. width: 200rpx;
  606. height: 100%;
  607. overflow: hidden;
  608. background-color: $bg-color-grey;
  609. .wrapper {
  610. width: 100%;
  611. height: 100%;
  612. .menu {
  613. display: flex;
  614. align-items: center;
  615. justify-content: flex-start;
  616. padding: 30rpx 20rpx;
  617. font-size: 26rpx;
  618. color: $text-color-assist;
  619. position: relative;
  620. display: flex;
  621. align-items: center;
  622. justify-content: center;
  623. &:nth-last-child(1) {
  624. margin-bottom: 230rpx;
  625. }
  626. &.current {
  627. background-color: #ffffff;
  628. color: $text-color-base;
  629. }
  630. .dot {
  631. position: absolute;
  632. width: 34rpx;
  633. height: 34rpx;
  634. line-height: 34rpx;
  635. font-size: 22rpx;
  636. background-color: $bg-color-primary;
  637. color: #ffffff;
  638. top: 16rpx;
  639. right: 10rpx;
  640. border-radius: 100%;
  641. text-align: center;
  642. }
  643. }
  644. }
  645. }
  646. .goods {
  647. flex: 1;
  648. height: 100%;
  649. overflow: hidden;
  650. background-color: #ffffff;
  651. .wrapper {
  652. width: 100%;
  653. height: 100%;
  654. padding: 20rpx;
  655. .ads {
  656. height: calc(300 / 550 * 510rpx);
  657. image {
  658. width: 100%;
  659. height: 100%;
  660. border-radius: 8rpx;
  661. }
  662. }
  663. .list {
  664. width: 100%;
  665. font-size: $font-size-base;
  666. padding-bottom: 800rpx;
  667. .category {
  668. width: 100%;
  669. .title {
  670. padding: 30rpx 0;
  671. display: flex;
  672. align-items: center;
  673. color: $text-color-base;
  674. .icon {
  675. width: 38rpx;
  676. height: 38rpx;
  677. margin-left: 10rpx;
  678. }
  679. }
  680. }
  681. .items {
  682. display: flex;
  683. flex-direction: column;
  684. padding-bottom: -30rpx;
  685. .good {
  686. display: flex;
  687. align-items: center;
  688. margin-bottom: 30rpx;
  689. .image {
  690. width: 160rpx;
  691. height: 160rpx;
  692. margin-right: 20rpx;
  693. border-radius: 8rpx;
  694. }
  695. .right {
  696. flex: 1;
  697. // height: 160rpx;
  698. overflow: hidden;
  699. display: flex;
  700. flex-direction: column;
  701. align-items: flex-start;
  702. justify-content: space-between;
  703. padding-right: 14rpx;
  704. .name {
  705. font-size: $font-size-base;
  706. margin-bottom: 10rpx;
  707. }
  708. .tips {
  709. width: 100%;
  710. height: 40rpx;
  711. line-height: 40rpx;
  712. overflow: hidden;
  713. text-overflow: ellipsis;
  714. white-space: nowrap;
  715. font-size: $font-size-sm;
  716. color: $text-color-assist;
  717. margin-bottom: 10rpx;
  718. }
  719. .price_and_action {
  720. width: 100%;
  721. display: flex;
  722. justify-content: space-between;
  723. align-items: center;
  724. .price {
  725. font-size: $font-size-base;
  726. font-weight: 600;
  727. }
  728. .btn-group {
  729. display: flex;
  730. justify-content: space-between;
  731. align-items: center;
  732. position: relative;
  733. .btn {
  734. padding: 0 20rpx;
  735. box-sizing: border-box;
  736. font-size: $font-size-sm;
  737. height: 44rpx;
  738. line-height: 44rpx;
  739. &.property_btn {
  740. border-radius: 24rpx;
  741. }
  742. &.add_btn,
  743. &.reduce_btn {
  744. padding: 0;
  745. width: 44rpx;
  746. border-radius: 44rpx;
  747. }
  748. }
  749. .dot {
  750. position: absolute;
  751. background-color: #ffffff;
  752. border: 1px solid $bg-color-primary;
  753. color: $bg-color-primary;
  754. font-size: $font-size-sm;
  755. width: 36rpx;
  756. height: 36rpx;
  757. line-height: 36rpx;
  758. text-align: center;
  759. border-radius: 100%;
  760. right: -12rpx;
  761. top: -10rpx;
  762. }
  763. .number {
  764. width: 44rpx;
  765. height: 44rpx;
  766. line-height: 44rpx;
  767. text-align: center;
  768. }
  769. }
  770. }
  771. }
  772. }
  773. }
  774. }
  775. }
  776. }
  777. }
  778. .modal-box {
  779. max-height: 90vh;
  780. }
  781. .good-detail-modal {
  782. width: 100%;
  783. height: 100%;
  784. display: flex;
  785. flex-direction: column;
  786. .cover {
  787. height: 320rpx;
  788. padding: 30rpx 0;
  789. display: flex;
  790. justify-content: center;
  791. align-items: center;
  792. position: relative;
  793. .image {
  794. width: 260rpx;
  795. height: 260rpx;
  796. }
  797. .btn-group {
  798. position: absolute;
  799. right: 10rpx;
  800. top: 30rpx;
  801. display: flex;
  802. align-items: center;
  803. justify-content: space-around;
  804. image {
  805. width: 80rpx;
  806. height: 80rpx;
  807. }
  808. }
  809. }
  810. .detail {
  811. width: 100%;
  812. min-height: 1vh;
  813. max-height: calc(90vh - 320rpx - 80rpx - 120rpx);
  814. .wrapper {
  815. width: 100%;
  816. height: 100%;
  817. overflow: hidden;
  818. .basic {
  819. padding: 0 20rpx 30rpx;
  820. display: flex;
  821. flex-direction: column;
  822. .name {
  823. font-size: $font-size-base;
  824. color: $text-color-base;
  825. margin-bottom: 10rpx;
  826. }
  827. .tips {
  828. font-size: $font-size-sm;
  829. color: $text-color-grey;
  830. }
  831. }
  832. .properties {
  833. width: 100%;
  834. border-top: 2rpx solid $bg-color-grey;
  835. padding: 10rpx 30rpx 0;
  836. display: flex;
  837. flex-direction: column;
  838. .property {
  839. width: 100%;
  840. display: flex;
  841. flex-direction: column;
  842. margin-bottom: 30rpx;
  843. padding-bottom: -16rpx;
  844. .title {
  845. width: 100%;
  846. display: flex;
  847. justify-content: flex-start;
  848. align-items: center;
  849. margin-bottom: 20rpx;
  850. .name {
  851. font-size: 26rpx;
  852. color: $text-color-base;
  853. margin-right: 20rpx;
  854. }
  855. .desc {
  856. flex: 1;
  857. font-size: $font-size-sm;
  858. color: $color-primary;
  859. overflow: hidden;
  860. text-overflow: ellipsis;
  861. white-space: nowrap;
  862. }
  863. }
  864. .values {
  865. width: 100%;
  866. display: flex;
  867. flex-wrap: wrap;
  868. .value {
  869. border-radius: 8rpx;
  870. background-color: $bg-color-grey;
  871. padding: 16rpx 30rpx;
  872. font-size: 26rpx;
  873. color: $text-color-assist;
  874. margin-right: 16rpx;
  875. margin-bottom: 16rpx;
  876. &.default {
  877. background-color: $color-primary;
  878. color: $text-color-white;
  879. }
  880. }
  881. }
  882. }
  883. }
  884. }
  885. }
  886. .action {
  887. display: flex;
  888. align-items: center;
  889. justify-content: space-between;
  890. background-color: $bg-color-grey;
  891. height: 120rpx;
  892. padding: 0 26rpx;
  893. .left {
  894. flex: 1;
  895. display: flex;
  896. flex-direction: column;
  897. justify-content: center;
  898. margin-right: 20rpx;
  899. overflow: hidden;
  900. .price {
  901. font-size: $font-size-lg;
  902. color: $text-color-base;
  903. }
  904. .props {
  905. color: $text-color-assist;
  906. font-size: 24rpx;
  907. width: 100%;
  908. overflow: hidden;
  909. text-overflow: ellipsis;
  910. white-space: nowrap;
  911. }
  912. }
  913. .btn-group {
  914. display: flex;
  915. align-items: center;
  916. justify-content: space-around;
  917. .number {
  918. font-size: $font-size-base;
  919. width: 44rpx;
  920. height: 44rpx;
  921. line-height: 44rpx;
  922. text-align: center;
  923. }
  924. .btn {
  925. padding: 0;
  926. font-size: $font-size-base;
  927. width: 44rpx;
  928. height: 44rpx;
  929. line-height: 44rpx;
  930. border-radius: 100%;
  931. }
  932. }
  933. }
  934. .add-to-cart-btn {
  935. display: flex;
  936. justify-content: center;
  937. align-items: center;
  938. background-color: $color-primary;
  939. color: $text-color-white;
  940. font-size: $font-size-base;
  941. height: 80rpx;
  942. border-radius: 0 0 12rpx 12rpx;
  943. }
  944. }
  945. .cart-box {
  946. position: absolute;
  947. // bottom: 30rpx;
  948. left: 30rpx;
  949. right: 30rpx;
  950. height: 96rpx;
  951. border-radius: 48rpx;
  952. box-shadow: 0 0 20rpx rgba(0, 0, 0, 0.2);
  953. background-color: #000;
  954. display: flex;
  955. align-items: center;
  956. justify-content: space-between;
  957. z-index: 9999;
  958. .cart-img {
  959. width: 50rpx;
  960. height: 47rpx;
  961. position: relative;
  962. // margin-top: -48rpx;
  963. }
  964. .pay-btn {
  965. height: 100%;
  966. padding: 0 30rpx;
  967. color: #FFFFFF;
  968. border-radius: 0 50rpx 50rpx 0;
  969. display: flex;
  970. align-items: center;
  971. font-size: $font-size-base;
  972. }
  973. .mark {
  974. padding-left: 46rpx;
  975. margin-right: 30rpx;
  976. position: relative;
  977. .tag {
  978. background-color: $color-warning;
  979. color: $text-color-white;
  980. display: flex;
  981. justify-content: center;
  982. align-items: center;
  983. font-size: $font-size-sm;
  984. position: absolute;
  985. right: -13rpx;
  986. top: -20rpx;
  987. border-radius: 100%;
  988. padding: 4rpx;
  989. width: 27rpx;
  990. height: 27rpx;
  991. opacity: .9;
  992. }
  993. }
  994. .price {
  995. flex: 1;
  996. color: $text-color-base;
  997. }
  998. }
  999. .cart-popup {
  1000. .top {
  1001. background-color: $bg-color-primary;
  1002. color: $color-primary;
  1003. padding: 10rpx 30rpx;
  1004. font-size: 24rpx;
  1005. text-align: right;
  1006. }
  1007. .cart-list {
  1008. background-color: #FFFFFF;
  1009. width: 100%;
  1010. overflow: hidden;
  1011. min-height: 1vh;
  1012. max-height: 60vh;
  1013. .wrapper {
  1014. height: 100%;
  1015. display: flex;
  1016. flex-direction: column;
  1017. padding: 0 30rpx;
  1018. margin-bottom: 156rpx;
  1019. .item {
  1020. display: flex;
  1021. justify-content: space-between;
  1022. align-items: center;
  1023. padding: 30rpx 0;
  1024. position: relative;
  1025. &::after {
  1026. content: ' ';
  1027. position: absolute;
  1028. bottom: 0;
  1029. left: 0;
  1030. width: 100%;
  1031. background-color: $border-color;
  1032. height: 2rpx;
  1033. transform: scaleY(.6);
  1034. }
  1035. .left {
  1036. flex: 1;
  1037. display: flex;
  1038. flex-direction: column;
  1039. overflow: hidden;
  1040. margin-right: 30rpx;
  1041. .name {
  1042. font-size: $font-size-sm;
  1043. color: $text-color-base;
  1044. }
  1045. .props {
  1046. color: $text-color-assist;
  1047. font-size: 24rpx;
  1048. overflow: hidden;
  1049. text-overflow: ellipsis;
  1050. white-space: nowrap;
  1051. }
  1052. }
  1053. .center {
  1054. margin-right: 120rpx;
  1055. font-size: $font-size-base;
  1056. }
  1057. .right {
  1058. display: flex;
  1059. align-items: center;
  1060. justify-content: space-between;
  1061. .btn {
  1062. width: 46rpx;
  1063. height: 46rpx;
  1064. border-radius: 100%;
  1065. padding: 0;
  1066. text-align: center;
  1067. line-height: 46rpx;
  1068. }
  1069. .number {
  1070. font-size: $font-size-base;
  1071. width: 46rpx;
  1072. height: 46rpx;
  1073. text-align: center;
  1074. line-height: 46rpx;
  1075. }
  1076. }
  1077. }
  1078. }
  1079. }
  1080. }
  1081. .back-button {
  1082. width: 30rpx;
  1083. height: 30rpx;
  1084. border-right: 4rpx solid #fff;
  1085. border-bottom: 4rpx solid #fff;
  1086. transform: rotate(135deg);
  1087. margin-left: 10rpx;
  1088. display: inline-block;
  1089. position: relative;
  1090. }
  1091. .newsTitle {
  1092. display: flex;
  1093. align-items: center;
  1094. }
  1095. </style>