product.vue 26 KB

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