product.vue 25 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210
  1. <template>
  2. <view class="container">
  3. <view class="carousel">
  4. <swiper indicator-dots circular=true duration="400">
  5. <swiper-item class="swiper-item" v-for="(item,index) in product.images_text" :key="index">
  6. <view class="image-wrapper">
  7. <image :src="item" class="loaded" @click="previewImage(index)" mode="aspectFill"></image>
  8. </view>
  9. </swiper-item>
  10. </swiper>
  11. </view>
  12. <!-- 秒杀的话才显示 -->
  13. <view class="flash" v-if="flash">
  14. <view class="sales_price" v-if="product.market_price"><view class="symbol">¥</view>{{specProduct.sales_price}}</view>
  15. <view class="left" v-if="product.market_price">
  16. <view class="market_price">¥{{specProduct.market_price}}</view>
  17. <view class="sold" v-if="progress.number">秒{{progress.number}}件</view>
  18. </view>
  19. <view class="right">
  20. <view class="time" v-if="countdown && progress.number != progress.sold">
  21. {{product.flash.text}}
  22. <uni-countdown
  23. ref="countd"
  24. :showDay="countdown.day > 0 ? true : false"
  25. :day="countdown.day"
  26. :hour="countdown.hour"
  27. :minute="countdown.minute"
  28. :second="countdown.second"
  29. @timeup="timeup"
  30. color="#fffa30"
  31. borderWidth="22rpx"
  32. splitorColor="#fffa30"
  33. background-color="#282f2c00"
  34. border-color="#00B26A"></uni-countdown>
  35. </view>
  36. <view class="time" v-else :class="{'flashDone': progress.number == false}">抢购已结束</view>
  37. <view class="progress" v-if="progress.number">
  38. <ProgressBar
  39. class="ProgressBar"
  40. :Sold="progress.sold"
  41. :widthUpx="250"
  42. :Width="percentage(progress.number, progress.sold)"
  43. Type="candy"
  44. :Vice="true"></ProgressBar>
  45. </view>
  46. </view>
  47. </view>
  48. <view class="introduce-section" v-if="product.product_id">
  49. <text class="title">{{product.title}}</text>
  50. <view class="price-box" v-if="flash == false">
  51. <text class="price-tip">¥</text>
  52. <text class="price">{{specProduct.sales_price}}</text>
  53. <text class="m-price" v-if="specProduct.market_price">¥{{specProduct.market_price}}</text>
  54. <text class="coupon-tip" v-if="specProduct.market_price > 0 && specProduct.market_price > specProduct.sales_price">{{(specProduct.sales_price/specProduct.market_price*10).toFixed(1)}}折</text>
  55. </view>
  56. <view class="bot-row">
  57. <text>销量: {{product.sales}}</text>
  58. <text>总库存: {{product.stock}}</text>
  59. <text>浏览量: {{product.look}}</text>
  60. </view>
  61. </view>
  62. <view class="c-list">
  63. <view class="c-row b-b" @click="toggleSpec" v-if="product.use_spec">
  64. <text class="tit">购买类型</text>
  65. <view class="con">
  66. <text class="selected-text">
  67. {{specSelectedName}}
  68. </text>
  69. <text style="margin-left: 50rpx;">库存:{{specProduct.stock}}</text>
  70. </view>
  71. <text class="yticon icon-you"></text>
  72. </view>
  73. <view class="c-row b-b" @click="toggleCoupon" v-if="product.coupon.length">
  74. <text class="tit">优惠券</text>
  75. <text class="con t-r red">查看可用优惠券</text>
  76. <text class="yticon icon-you"></text>
  77. </view>
  78. <view class="c-row b-b" v-if="product.server">
  79. <text class="tit">服务</text>
  80. <view class="bz-list con">
  81. {{product.server}}
  82. </view>
  83. </view>
  84. </view>
  85. <!-- 评价 -->
  86. <view class="eva-section" v-if="product.evaluate_data && product.evaluate_data.count > 0">
  87. <view class="e-header" @click="$api.navTo('/pages/product/evaluate?product_id='+product.product_id)">
  88. <text class="tit">评价</text>
  89. <text>({{product.evaluate_data.count}})</text>
  90. <text class="tip">好评率 {{product.evaluate_data.avg}}%</text>
  91. <text class="yticon icon-you"></text>
  92. </view>
  93. <view class="eva-box" v-for="(item, index) in product.evaluate_list" :key="index">
  94. <image class="portrait" :src="item.avatar" mode="aspectFill"></image>
  95. <view class="right">
  96. <text class="name">{{item.username}}</text>
  97. <text class="con">{{item.comment}}</text>
  98. <view class="bot">
  99. <text class="attr" v-if="item.spec">购买类型:{{item.spec}}</text>
  100. <text class="attr" v-else></text>
  101. <text class="time">{{item.createtime_text}}</text>
  102. </view>
  103. </view>
  104. </view>
  105. </view>
  106. <view class="detail-desc" v-if="product.desc">
  107. <view class="d-header">
  108. <text>图文详情</text>
  109. </view>
  110. <rich-text :nodes="product.desc"></rich-text>
  111. </view>
  112. <!-- 底部操作菜单 -->
  113. <view class="page-bottom">
  114. <navigator url="/pages/index/index" open-type="switchTab" class="p-b-btn">
  115. <text class="yticon icon-fangzi"></text>
  116. <text>首页</text>
  117. </navigator>
  118. <navigator url="/pages/cart/cart" open-type="switchTab" class="p-b-btn">
  119. <text class="yticon icon-gouwuche"></text>
  120. <text>购物车</text>
  121. <text class="cart-count" v-if="product.cart_num">{{product.cart_num}}</text>
  122. </navigator>
  123. <view class="p-b-btn" :class="{active: favorite}" @click="toFavorite" v-if="!flash">
  124. <text class="yticon icon-shoucang"></text>
  125. <text>收藏</text>
  126. </view>
  127. <view class="p-b-btn" v-else>
  128. <!-- 站位 -->
  129. <text></text>
  130. </view>
  131. <view class="action-btn-group">
  132. <button :class="{'only': flash}" type="primary" class=" action-btn no-border buy-now-btn" @click="buy">立即购买</button>
  133. <button v-if="!flash" type="primary" class=" action-btn no-border add-cart-btn" @click="addCart">加入购物车</button>
  134. </view>
  135. </view>
  136. <!-- 领取优惠券-模态层弹窗 -->
  137. <view class="popup spec" :class="couponClass" @touchmove.stop.prevent="stopPrevent" @click="toggleCoupon">
  138. <!-- 遮罩层 -->
  139. <view class="mask"></view>
  140. <view class="layer attr-content content-coupon" @click.stop="stopPrevent">
  141. <!-- 优惠券页面,仿mt -->
  142. <view class="coupon-item" v-for="(item, index) in product.coupon" :key="index">
  143. <view class="con">
  144. <view class="left">
  145. <text class="title">{{item.title}}</text>
  146. <text class="time">有效期至{{item.endtime_text}}</text>
  147. </view>
  148. <view class="right">
  149. <text class="price">{{item.value}}</text>
  150. <text>满{{item.least}}可用</text>
  151. </view>
  152. <view class="circle l"></view>
  153. <view class="circle r"></view>
  154. </view>
  155. <text class="tips">限一张使用</text>
  156. </view>
  157. </view>
  158. <button class="btn retract" @click="toggleCoupon">收起</button>
  159. </view>
  160. <!-- 规格-模态层弹窗 -->
  161. <view class="popup spec" :class="specClass" @touchmove.stop.prevent="stopPrevent" @click="toggleSpec">
  162. <!-- 遮罩层 -->
  163. <view class="mask"></view>
  164. <view class="layer attr-content" @click.stop="stopPrevent">
  165. <view class="a-t">
  166. <image v-if="specProduct.image" mode="aspectFill" :src="specProduct.image"></image>
  167. <view class="right">
  168. <text class="price">¥{{specProduct.sales_price}}</text>
  169. <text class="stock">库存:{{specProduct.stock}}件</text>
  170. <view class="selected">
  171. 已选:
  172. <text class="selected-text">
  173. {{specSelectedName}}
  174. </text>
  175. </view>
  176. </view>
  177. </view>
  178. <view v-for="(item,index) in specList" :key="index" class="attr-list">
  179. <text>{{item.name}}</text>
  180. <view class="item-list">
  181. <text v-for="(childItem, childIndex) in specChildList" v-if="childItem.pid === item.id" :key="childIndex" class="tit"
  182. :class="{selected: childItem.selected}" @click="selectSpec(childIndex, childItem.pid)">
  183. {{childItem.name}}
  184. </text>
  185. </view>
  186. </view>
  187. <button class="btn" @click="toggleSpec">完成</button>
  188. </view>
  189. </view>
  190. <!-- 分享 -->
  191. <!-- <share ref="share" :contentHeight="580" :shareList="shareList"></share> -->
  192. </view>
  193. </template>
  194. <script>
  195. import {
  196. mapGetters
  197. } from 'vuex';
  198. import share from '@/components/share';
  199. import ProgressBar from '@/components/Progress-Bar/Progress-Bar';
  200. import uniCountdown from '@/components/uni-countdown/uni-countdown.vue';
  201. export default {
  202. components: {
  203. share,
  204. ProgressBar,
  205. uniCountdown
  206. },
  207. computed: {
  208. ...mapGetters(['userInfo', 'hasLogin']),
  209. specSelectedName() {
  210. return this.specSelected.join(' ');
  211. },
  212. specProduct() {
  213. if (this.product.use_spec == 1) {
  214. let market_price = this.product.market_price;
  215. let sales_price = this.product.sales_price;
  216. let stock = this.product.stock;
  217. let image = this.product.image;
  218. let specSelectedName = this.specSelected.join(' ');
  219. let specTableList = this.specTableList;
  220. for (var item of this.specTableList) {
  221. if (item.value.join(' ') == specSelectedName) {
  222. market_price = item.market_price;
  223. sales_price = item.sales_price;
  224. stock = item.stock;
  225. image = item.image;
  226. }
  227. }
  228. return {
  229. market_price,
  230. sales_price,
  231. stock,
  232. image
  233. };
  234. } else {
  235. return this.product;
  236. }
  237. }
  238. },
  239. data() {
  240. return {
  241. couponClass: 'none',
  242. specClass: 'none',
  243. specSelected: [],
  244. favorite: false,
  245. shareList: [],
  246. specList: [],
  247. specChildList: [],
  248. specTableList: [],
  249. product: {},
  250. flash: false,
  251. id: false,
  252. countdown: {},
  253. progress:{
  254. sold:1,
  255. number:1
  256. }
  257. };
  258. },
  259. onPullDownRefresh(){
  260. if (this.$refs && this.$refs.countd) {
  261. this.$refs.countd.syncFlag = false;
  262. }
  263. this.getDetail(this.id, this.flash?this.flash:0);
  264. },
  265. onShareAppMessage(e) {
  266. return {
  267. title: this.product.title,
  268. };
  269. },
  270. onLoad(options) {
  271. this.id = options.id;
  272. let flash_id = options.flash ? options.flash : 0;
  273. if (flash_id != 0) {
  274. this.flash = flash_id;
  275. }
  276. this.getDetail(this.id, flash_id);
  277. },
  278. methods: {
  279. // 为0时刷新页面
  280. timeup(){
  281. this.getDetail(this.id, this.flash?this.flash:0);
  282. },
  283. // 获取商品详情
  284. async getDetail(id, flash_id) {
  285. let apiUrl = flash_id == 0 ? '/product/detail' : '/flash/productDetail'
  286. let product = await this.$api.request(apiUrl + `?id=${id}&flash_id=${flash_id}`, 'GET');
  287. uni.stopPullDownRefresh();
  288. if (!product) {
  289. setTimeout(function(){
  290. uni.navigateBack();
  291. }, 3000);
  292. return;
  293. }
  294. console.log(product)
  295. product.desc = product.desc.replace(/\<img/gi, '<img style="max-width:100%!important;height:auto!important"');
  296. console.log(product)
  297. this.product = product;
  298. if (product.flash) {
  299. this.countdown = product.flash.countdown;
  300. this.progress = product.flash;
  301. }
  302. this.favorite = this.product.favorite;
  303. if (this.product.use_spec) {
  304. let specList = this.product.spec_list;
  305. let specTableList = this.product.spec_table_list;
  306. let e = 1;
  307. let ee = 1;
  308. let specChildList = [];
  309. for (let i in specList) {
  310. specList[i].id = e++;
  311. for (let ii in specList[i].child) {
  312. specChildList.push({
  313. id: ee++,
  314. pid: specList[i].id,
  315. name: specList[i].child[ii]
  316. })
  317. }
  318. }
  319. this.specList = specList;
  320. this.specChildList = specChildList;
  321. this.specTableList = specTableList;
  322. //console.log(this.specList)
  323. //console.log(specChildList)
  324. //规格 默认选中第一条
  325. this.specSelected = [];
  326. this.specList.forEach(item => {
  327. for (let cItem of this.specChildList) {
  328. if (cItem.pid === item.id) {
  329. this.$set(cItem, 'selected', true);
  330. this.specSelected.push(cItem.name);
  331. break; //forEach不能使用break
  332. }
  333. }
  334. })
  335. }
  336. },
  337. //领取优惠券开关
  338. toggleCoupon() {
  339. if (this.couponClass === 'show') {
  340. this.couponClass = 'hide';
  341. setTimeout(() => {
  342. this.couponClass = 'none';
  343. }, 250);
  344. } else if (this.couponClass === 'none') {
  345. this.couponClass = 'show';
  346. }
  347. },
  348. //规格弹窗开关
  349. toggleSpec() {
  350. if (this.specClass === 'show') {
  351. this.specClass = 'hide';
  352. setTimeout(() => {
  353. this.specClass = 'none';
  354. }, 250);
  355. } else if (this.specClass === 'none') {
  356. this.specClass = 'show';
  357. }
  358. },
  359. //选择规格
  360. selectSpec(index, pid) {
  361. let list = this.specChildList;
  362. list.forEach(item => {
  363. if (item.pid === pid) {
  364. this.$set(item, 'selected', false);
  365. }
  366. })
  367. this.$set(list[index], 'selected', true);
  368. //存储已选择
  369. /**
  370. * 修复选择规格存储错误
  371. * 将这几行代码替换即可
  372. * 选择的规格存放在specSelected中
  373. */
  374. this.specSelected = [];
  375. //console.log(list)
  376. list.forEach(item => {
  377. if (item.selected === true) {
  378. this.specSelected.push(item.name);
  379. }
  380. })
  381. },
  382. //分享
  383. share() {
  384. this.$refs.share.toggleMask();
  385. },
  386. //收藏
  387. async toFavorite() {
  388. if (this.flash) {
  389. this.$api.msg('秒杀商品不能收藏');
  390. return;
  391. }
  392. let is_login = await this.$api.checkLogin();
  393. if (is_login) {
  394. this.favorite = !this.favorite;
  395. let bool = await this.$api.request('/product/favorite?id=' + this.product.product_id);
  396. if (!bool) {
  397. this.favorite = !this.favorite;
  398. }
  399. }
  400. },
  401. async buy() {
  402. let spec = this.product.spec;
  403. let url = `/pages/order/createOrder?id=${this.product.product_id}&spec=${spec}`;
  404. if (this.flash) {
  405. url = url + `&flash_id=${this.flash}`;
  406. }
  407. uni.navigateTo({
  408. url:url
  409. });
  410. },
  411. //添加购物车
  412. async addCart() {
  413. if (this.flash) {
  414. this.$api.msg('秒杀商品不能加入购物车');
  415. return;
  416. }
  417. let is_login = await this.$api.checkLogin();
  418. let spec = this.product.spec;
  419. let data = await this.$api.request('/cart/add?id=' + this.product.product_id + '&spec='+ spec);
  420. if (data) {
  421. this.product.cart_num++;
  422. }
  423. },
  424. stopPrevent() {},
  425. // 计算百分比
  426. percentage(number, sold) {
  427. if (!sold) {
  428. return 0;
  429. }
  430. return parseInt(sold / number * 100);
  431. },
  432. // 查看图片
  433. previewImage(index){
  434. uni.previewImage({
  435. current:this.product.images_text[index],
  436. urls:this.product.images_text,
  437. indicator:"number",
  438. loop: true
  439. })
  440. }
  441. },
  442. }
  443. </script>
  444. <style lang='scss'>
  445. page {
  446. background: $page-color-base;
  447. padding-bottom: 160upx;
  448. }
  449. .icon-you {
  450. font-size: $font-base + 2upx;
  451. color: #888;
  452. }
  453. .carousel {
  454. height: 722upx;
  455. position: relative;
  456. swiper {
  457. height: 100%;
  458. }
  459. .image-wrapper {
  460. width: 100%;
  461. height: 100%;
  462. }
  463. .swiper-item {
  464. display: flex;
  465. justify-content: center;
  466. align-content: center;
  467. height: 750upx;
  468. overflow: hidden;
  469. image {
  470. width: 100%;
  471. height: 100%;
  472. }
  473. }
  474. }
  475. /* 标题简介 */
  476. .introduce-section {
  477. background: #fff;
  478. padding: 20upx 30upx;
  479. .title {
  480. font-size: 32upx;
  481. color: $font-color-dark;
  482. height: 50upx;
  483. line-height: 50upx;
  484. }
  485. .price-box {
  486. display: flex;
  487. align-items: baseline;
  488. height: 64upx;
  489. padding: 10upx 0;
  490. font-size: 26upx;
  491. color: $uni-color-primary;
  492. }
  493. .price {
  494. font-size: $font-lg + 2upx;
  495. }
  496. .m-price {
  497. margin: 0 12upx;
  498. color: $font-color-light;
  499. text-decoration: line-through;
  500. }
  501. .coupon-tip {
  502. align-items: center;
  503. padding: 4upx 10upx;
  504. background: $uni-color-primary;
  505. font-size: $font-sm;
  506. color: #fff;
  507. border-radius: 6upx;
  508. line-height: 1;
  509. transform: translateY(-4upx);
  510. }
  511. .bot-row {
  512. display: flex;
  513. align-items: center;
  514. height: 50upx;
  515. font-size: $font-sm;
  516. color: $font-color-light;
  517. text {
  518. flex: 1;
  519. }
  520. }
  521. }
  522. /* 分享 */
  523. .share-section {
  524. display: flex;
  525. align-items: center;
  526. color: $font-color-base;
  527. background: linear-gradient(left, #fdf5f6, #fbebf6);
  528. padding: 12upx 30upx;
  529. .share-icon {
  530. display: flex;
  531. align-items: center;
  532. width: 70upx;
  533. height: 30upx;
  534. line-height: 1;
  535. border: 1px solid $uni-color-primary;
  536. border-radius: 4upx;
  537. position: relative;
  538. overflow: hidden;
  539. font-size: 22upx;
  540. color: $uni-color-primary;
  541. &:after {
  542. content: '';
  543. width: 50upx;
  544. height: 50upx;
  545. border-radius: 50%;
  546. left: -20upx;
  547. top: -12upx;
  548. position: absolute;
  549. background: $uni-color-primary;
  550. }
  551. }
  552. .icon-xingxing {
  553. position: relative;
  554. z-index: 1;
  555. font-size: 24upx;
  556. margin-left: 2upx;
  557. margin-right: 10upx;
  558. color: #fff;
  559. line-height: 1;
  560. }
  561. .tit {
  562. font-size: $font-base;
  563. margin-left: 10upx;
  564. }
  565. .icon-bangzhu1 {
  566. padding: 10upx;
  567. font-size: 30upx;
  568. line-height: 1;
  569. }
  570. .share-btn {
  571. flex: 1;
  572. text-align: right;
  573. font-size: $font-sm;
  574. color: $uni-color-primary;
  575. }
  576. .icon-you {
  577. font-size: $font-sm;
  578. margin-left: 4upx;
  579. color: $uni-color-primary;
  580. }
  581. }
  582. .c-list {
  583. font-size: $font-sm + 2upx;
  584. color: $font-color-base;
  585. background: #fff;
  586. .c-row {
  587. display: flex;
  588. align-items: center;
  589. padding: 20upx 30upx;
  590. position: relative;
  591. }
  592. .tit {
  593. width: 140upx;
  594. }
  595. .con {
  596. flex: 1;
  597. color: $font-color-dark;
  598. .selected-text {
  599. margin-right: 10upx;
  600. }
  601. }
  602. .bz-list {
  603. height: 40upx;
  604. font-size: $font-sm+2upx;
  605. color: $font-color-dark;
  606. text {
  607. display: inline-block;
  608. margin-right: 30upx;
  609. }
  610. }
  611. .con-list {
  612. flex: 1;
  613. display: flex;
  614. flex-direction: column;
  615. color: $font-color-dark;
  616. line-height: 40upx;
  617. }
  618. .red {
  619. color: $uni-color-primary;
  620. }
  621. }
  622. /* 评价 */
  623. .eva-section {
  624. display: flex;
  625. flex-direction: column;
  626. padding: 20upx 30upx;
  627. background: #fff;
  628. margin-top: 16upx;
  629. .e-header {
  630. display: flex;
  631. align-items: center;
  632. height: 70upx;
  633. font-size: $font-sm + 2upx;
  634. color: $font-color-light;
  635. .tit {
  636. font-size: $font-base + 2upx;
  637. color: $font-color-dark;
  638. margin-right: 4upx;
  639. }
  640. .tip {
  641. flex: 1;
  642. text-align: right;
  643. }
  644. .icon-you {
  645. margin-left: 10upx;
  646. }
  647. }
  648. }
  649. .eva-box {
  650. display: flex;
  651. padding: 20upx 0;
  652. .portrait {
  653. flex-shrink: 0;
  654. width: 80upx;
  655. height: 80upx;
  656. border-radius: 100px;
  657. }
  658. .right {
  659. flex: 1;
  660. display: flex;
  661. flex-direction: column;
  662. font-size: $font-base;
  663. color: $font-color-base;
  664. padding-left: 26upx;
  665. .con {
  666. font-size: $font-base;
  667. color: $font-color-dark;
  668. padding: 20upx 0;
  669. }
  670. .bot {
  671. display: flex;
  672. justify-content: space-between;
  673. font-size: $font-sm;
  674. color: $font-color-light;
  675. }
  676. }
  677. }
  678. /* 详情 */
  679. .detail-desc {
  680. background: #fff;
  681. margin-top: 16upx;
  682. .d-header {
  683. display: flex;
  684. justify-content: center;
  685. align-items: center;
  686. height: 80upx;
  687. font-size: $font-base + 2upx;
  688. color: $font-color-dark;
  689. position: relative;
  690. text {
  691. padding: 0 20upx;
  692. background: #fff;
  693. position: relative;
  694. z-index: 1;
  695. }
  696. &:after {
  697. position: absolute;
  698. left: 50%;
  699. top: 50%;
  700. transform: translateX(-50%);
  701. width: 300upx;
  702. height: 0;
  703. content: '';
  704. border-bottom: 1px solid #ccc;
  705. }
  706. }
  707. }
  708. /* 规格选择弹窗 */
  709. .attr-content {
  710. padding: 10upx 30upx;
  711. .a-t {
  712. display: flex;
  713. image {
  714. width: 170upx;
  715. height: 170upx;
  716. flex-shrink: 0;
  717. margin-top: -40upx;
  718. border-radius: 8upx;
  719. ;
  720. }
  721. .right {
  722. display: flex;
  723. flex-direction: column;
  724. padding-left: 24upx;
  725. font-size: $font-sm + 2upx;
  726. color: $font-color-base;
  727. line-height: 42upx;
  728. .price {
  729. font-size: $font-lg;
  730. color: $uni-color-primary;
  731. margin-bottom: 10upx;
  732. }
  733. .selected-text {
  734. margin-right: 10upx;
  735. }
  736. }
  737. }
  738. .attr-list {
  739. display: flex;
  740. flex-direction: column;
  741. font-size: $font-base + 2upx;
  742. color: $font-color-base;
  743. padding-top: 30upx;
  744. padding-left: 10upx;
  745. }
  746. .item-list {
  747. padding: 20upx 0 0;
  748. display: flex;
  749. flex-wrap: wrap;
  750. text {
  751. display: flex;
  752. align-items: center;
  753. justify-content: center;
  754. background: #eee;
  755. margin-right: 20upx;
  756. margin-bottom: 20upx;
  757. border-radius: 100upx;
  758. min-width: 60upx;
  759. height: 60upx;
  760. padding: 0 20upx;
  761. font-size: $font-base;
  762. color: $font-color-dark;
  763. }
  764. .selected {
  765. background: #fbebee;
  766. color: $uni-color-primary;
  767. }
  768. }
  769. }
  770. /* 弹出层 */
  771. .popup {
  772. position: fixed;
  773. left: 0;
  774. top: 0;
  775. right: 0;
  776. bottom: 0;
  777. z-index: 99;
  778. &.show {
  779. display: block;
  780. .mask {
  781. animation: showPopup 0.2s linear both;
  782. }
  783. .layer {
  784. animation: showLayer 0.2s linear both;
  785. }
  786. }
  787. &.hide {
  788. .mask {
  789. animation: hidePopup 0.2s linear both;
  790. }
  791. .layer {
  792. animation: hideLayer 0.2s linear both;
  793. }
  794. }
  795. &.none {
  796. display: none;
  797. }
  798. .mask {
  799. position: fixed;
  800. top: 0;
  801. width: 100%;
  802. height: 100%;
  803. z-index: 1;
  804. background-color: rgba(0, 0, 0, 0.4);
  805. }
  806. .layer {
  807. position: fixed;
  808. z-index: 99;
  809. bottom: 0;
  810. width: 100%;
  811. min-height: 40vh;
  812. border-radius: 10upx 10upx 0 0;
  813. background-color: #fff;
  814. .btn {
  815. height: 66upx;
  816. line-height: 66upx;
  817. border-radius: 100upx;
  818. background: $uni-color-primary;
  819. font-size: $font-base + 2upx;
  820. color: #fff;
  821. margin: 30upx auto 20upx;
  822. }
  823. }
  824. @keyframes showPopup {
  825. 0% {
  826. opacity: 0;
  827. }
  828. 100% {
  829. opacity: 1;
  830. }
  831. }
  832. @keyframes hidePopup {
  833. 0% {
  834. opacity: 1;
  835. }
  836. 100% {
  837. opacity: 0;
  838. }
  839. }
  840. @keyframes showLayer {
  841. 0% {
  842. transform: translateY(120%);
  843. }
  844. 100% {
  845. transform: translateY(0%);
  846. }
  847. }
  848. @keyframes hideLayer {
  849. 0% {
  850. transform: translateY(0);
  851. }
  852. 100% {
  853. transform: translateY(120%);
  854. }
  855. }
  856. }
  857. /* 底部操作菜单 */
  858. .page-bottom {
  859. position: fixed;
  860. left: 30upx;
  861. bottom: 30upx;
  862. z-index: 95;
  863. display: flex;
  864. justify-content: center;
  865. align-items: center;
  866. width: 690upx;
  867. height: 100upx;
  868. background: rgba(255, 255, 255, .9);
  869. box-shadow: 0 0 20upx 0 rgba(0, 0, 0, .5);
  870. border-radius: 16upx;
  871. .p-b-btn {
  872. display: flex;
  873. flex-direction: column;
  874. align-items: center;
  875. justify-content: center;
  876. font-size: $font-sm;
  877. color: $font-color-base;
  878. width: 96upx;
  879. height: 80upx;
  880. position: relative;
  881. /* 购物车数量 */
  882. .cart-count{
  883. border: 4rpx solid #fa436a;
  884. width: 40rpx;
  885. height: 40rpx;
  886. color: #fa436a;
  887. text-align: center;
  888. border-radius: 40rpx;
  889. position: absolute;
  890. background: #fff;
  891. top: -10rpx;
  892. right: 0;
  893. }
  894. .yticon {
  895. font-size: 46upx;
  896. line-height: 48upx;
  897. color: $font-color-light;
  898. }
  899. &.active,
  900. &.active .yticon {
  901. color: $uni-color-primary;
  902. }
  903. }
  904. .action-btn-group {
  905. display: flex;
  906. height: 76upx;
  907. border-radius: 100px;
  908. overflow: hidden;
  909. box-shadow: 0 20upx 40upx -16upx #fa436a;
  910. box-shadow: 1px 2px 5px rgba(219, 63, 96, 0.4);
  911. background: linear-gradient(to right, #ffac30, #fa436a, #F56C6C);
  912. margin-left: 20upx;
  913. position: relative;
  914. .only {
  915. width: 360rpx!important;
  916. }
  917. &:after {
  918. content: '';
  919. position: absolute;
  920. top: 50%;
  921. right: 50%;
  922. transform: translateY(-50%);
  923. height: 28upx;
  924. width: 0;
  925. border-right: 1px solid rgba(255, 255, 255, .5);
  926. }
  927. .action-btn {
  928. display: flex;
  929. align-items: center;
  930. justify-content: center;
  931. width: 180upx;
  932. height: 100%;
  933. font-size: $font-base;
  934. padding: 0;
  935. border-radius: 0;
  936. background: transparent;
  937. }
  938. }
  939. }
  940. .flash {
  941. height: 100upx;
  942. background: linear-gradient(to right, #ffac30, #fa436a, #F56C6C);
  943. display: flex;
  944. flex-direction: row;
  945. position: relative;
  946. .sales_price{
  947. .symbol{
  948. font-size: 30upx;
  949. display: inline;
  950. }
  951. color: #fff;
  952. font-size: 50upx;
  953. }
  954. .left{
  955. font-size: 28upx;
  956. padding: 10upx;
  957. .market_price{
  958. color: #DCDFE6;
  959. text-decoration: line-through;
  960. }
  961. .sold{
  962. color: #E4E7ED;
  963. }
  964. }
  965. .right{
  966. height: 100%;
  967. width: 300upx;
  968. position: absolute;
  969. right: 0;
  970. padding: 4upx;
  971. margin-right: 20upx;
  972. .time{
  973. font-size: 30upx;
  974. color: #fffa30;
  975. text-align: center;
  976. .uni-countdown{
  977. display: inline-flex;
  978. }
  979. }
  980. .progress{
  981. position: absolute;
  982. bottom: 7rpx;
  983. right: 10upx;
  984. }
  985. .flashDone{
  986. font-size: 40rpx;
  987. height: 90rpx;
  988. line-height: 90rpx;
  989. }
  990. }
  991. }
  992. /* 优惠券列表 */
  993. .content-coupon{
  994. padding-bottom: 100rpx;
  995. max-height: 800rpx;
  996. overflow: auto;
  997. }
  998. .retract{
  999. position: fixed;
  1000. bottom: 0;
  1001. width: 700rpx;
  1002. z-index: 100;
  1003. margin: 20rpx 25rpx;
  1004. color:#ffffff;
  1005. background: #fa436a;
  1006. }
  1007. .coupon-item {
  1008. display: flex;
  1009. flex-direction: column;
  1010. background: #fff;
  1011. .con {
  1012. display: flex;
  1013. align-items: center;
  1014. position: relative;
  1015. height: 120upx;
  1016. padding: 0 30upx;
  1017. &:after {
  1018. position: absolute;
  1019. left: 0;
  1020. bottom: 0;
  1021. content: '';
  1022. width: 100%;
  1023. height: 0;
  1024. border-bottom: 1px dashed #f3f3f3;
  1025. transform: scaleY(50%);
  1026. }
  1027. }
  1028. .left {
  1029. display: flex;
  1030. flex-direction: column;
  1031. justify-content: center;
  1032. flex: 1;
  1033. overflow: hidden;
  1034. height: 100upx;
  1035. }
  1036. .title {
  1037. font-size: 32upx;
  1038. color: $font-color-dark;
  1039. margin-bottom: 10upx;
  1040. }
  1041. .time {
  1042. font-size: 24upx;
  1043. color: $font-color-light;
  1044. }
  1045. .right {
  1046. display: flex;
  1047. flex-direction: column;
  1048. justify-content: center;
  1049. align-items: center;
  1050. font-size: 26upx;
  1051. color: $font-color-base;
  1052. height: 100upx;
  1053. }
  1054. .price {
  1055. font-size: 44upx;
  1056. color: $base-color;
  1057. &:before {
  1058. content: '¥';
  1059. font-size: 34upx;
  1060. }
  1061. }
  1062. .tips {
  1063. font-size: 24upx;
  1064. color: $font-color-light;
  1065. line-height: 60upx;
  1066. padding-left: 30upx;
  1067. }
  1068. .circle {
  1069. position: absolute;
  1070. left: -6upx;
  1071. bottom: -10upx;
  1072. z-index: 10;
  1073. width: 20upx;
  1074. height: 20upx;
  1075. background: #f3f3f3;
  1076. border-radius: 100px;
  1077. &.r {
  1078. left: auto;
  1079. right: -6upx;
  1080. }
  1081. }
  1082. }
  1083. </style>