product.vue 27 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156
  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 imgList" :key="index">
  6. <view class="image-wrapper"><image :src="item" class="loaded" mode="scaleToFill"></image></view>
  7. </swiper-item>
  8. </swiper>
  9. </view>
  10. <view class="introduce-section seckill-box-title" v-if="goodsType == 1">
  11. <view class="title flex">
  12. <view class="title-box">
  13. <text class="price-tip">¥</text>
  14. <text class="price">{{ goodsObjact.price }}</text>
  15. <!-- <text class="m-price" v-if="goodsObjact.ot_price > goodsObjact.price">¥{{ goodsObjact.ot_price }}</text> -->
  16. <!-- <text class="coupon-tip">7折</text> -->
  17. </view>
  18. <view class="flex timeStop">
  19. <view>距离结束</view>
  20. <uni-countdown
  21. color="#ffffff"
  22. background-color="#D65B3F"
  23. splitor-color="#FFFFFF"
  24. :show-day="false"
  25. :hour="seckillObj.stopTimeH"
  26. :minute="seckillObj.stopTimeM"
  27. :second="seckillObj.stopTimeS"
  28. ></uni-countdown>
  29. </view>
  30. </view>
  31. </view>
  32. <view class="introduce-section">
  33. <text class="title" v-if="goodsType == 1">{{ goodsObjact.title }}</text>
  34. <view class="price-box" v-if="goodsType == 0">
  35. <text class="price-tip">¥</text>
  36. <text class="price">{{ goodsObjact.price }}</text>
  37. <text class="m-price" v-if="goodsObjact.ot_price > goodsObjact.price">¥{{ goodsObjact.ot_price }}</text>
  38. <!-- <text class="coupon-tip">7折</text> -->
  39. </view>
  40. <text class="title" v-if="goodsType == 0">{{ goodsObjact.store_name }}</text>
  41. <view class="bot-row">
  42. <text>快递: {{ goodsObjact.postage }}</text>
  43. <text style="text-align: center;">销量: {{ goodsObjact.sales }}</text>
  44. <text style="text-align: right;">{{ storeObjact.address | address }}</text>
  45. </view>
  46. </view>
  47. <view class="c-list">
  48. <view class="c-row b-b">
  49. <text class="tit">赠送</text>
  50. <view class="con">
  51. <text class="selected-text">购买赠送<text class="num">200</text>艺金券</text>
  52. </view>
  53. </view>
  54. </view>
  55. <view class="c-list">
  56. <view class="c-row b-b" @click="toggleSpec">
  57. <text class="tit">购买数量</text>
  58. <view class="con">
  59. <text class="selected-text">{{ goodsNumber }}</text>
  60. </view>
  61. <text class="iconfont iconenter"></text>
  62. </view>
  63. <view class="c-row b-b" v-if="goodsType == 1">
  64. <text class="tit">限购数量</text>
  65. <view class="con">
  66. <text class="selected-text">{{ goodsObjact.num + goodsObjact.unit_name }}</text>
  67. </view>
  68. </view>
  69. <!-- <view class="c-row b-b">
  70. <text class="tit">优惠券</text>
  71. <text class="con t-r red">领取优惠券</text>
  72. <text class="iconfont iconenter"></text>
  73. </view> -->
  74. <view class="c-row b-b" v-if="goodsObjact.is_integral == 1 && goodsType == 0">
  75. <text class="tit">积分</text>
  76. <view class="bz-list con">
  77. <text>最高抵扣¥{{ moneyNum(goodsObjact.use_max_integral) == 0 ? moneyNum(goodsObjact.price) : moneyNum(goodsObjact.use_max_integral) }}</text>
  78. </view>
  79. </view>
  80. </view>
  81. <view class="shop-box flex" v-if="goodsType == 0 && shopId > 0">
  82. <view class="flex">
  83. <image :src="shopInfo.logo" mode=" aspectFit" class="shop-img"></image>
  84. <text class="font-size-lg">{{ shopInfo.title }}</text>
  85. </view>
  86. <navigator :url="'/pages/shoping/index?merid=' + shopId"><view class="shop-button">进店逛逛</view></navigator>
  87. </view>
  88. <view class="detail-desc">
  89. <view class="d-header"><text>商品详情</text></view>
  90. <rich-text class="detail-centent" :nodes="goodsObjact.description"></rich-text>
  91. <view :class="{ contentBottomHeight: goodsType == 1 || goodsType == 2, goodsBottom: goodsType == 0 }"></view>
  92. </view>
  93. <!-- 底部操作菜单 -->
  94. <view class="page-bottom" v-if="goodsType == 0">
  95. <!-- <navigator url="/pages/index/index" open-type="switchTab" class="p-b-btn">
  96. <text class="iconfont iconhome"></text>
  97. <text>首页</text>
  98. </navigator>
  99. <navigator url="/pages/cart/cart" open-type="switchTab" class="p-b-btn">
  100. <text class="iconfont iconcart"></text>
  101. <text>购物车</text>
  102. </navigator> -->
  103. <!-- <view class="p-b-btn" :class="{ active: goodsObjact.userCollect }" @click="toFavorite(goodsObjact)">
  104. <text class="iconfont " :class="{ iconlike: !goodsObjact.userCollect, iconlikefill: goodsObjact.userCollect }"></text>
  105. <text>收藏</text>
  106. </view> -->
  107. <view class="action-btn-group">
  108. <button type="primary" class=" action-btn no-border buy-now-btn" @click="toggleSpec(2)">加入购物车</button>
  109. <button type="primary" class=" action-btn no-border add-cart-btn" @click="toggleSpec(1)">立即购买</button>
  110. </view>
  111. <!-- <view class="action-btn-group">
  112. <button type="primary" class=" action-btn no-border add-cart-btn" style="width: 750rpx;" @click="toggleSpec(1)">立即购买</button>
  113. </view> -->
  114. </view>
  115. <!-- 秒杀商品购买 -->
  116. <view class="goods-pay-box flex" :class="{ stop: seckillObj.stop }" v-if="goodsType == 1">
  117. <view class="goods-pay bgLine" v-if="!seckillObj.stop" @click="toggleSpec(1)"><text>立即购买</text></view>
  118. <view class="goods-pay-stop" v-else>活动已结束</view>
  119. </view>
  120. <!-- 拼团商品购买 -->
  121. <view class="goods-pay-box flex" v-if="goodsType == 2">
  122. <view class="goods-pay bg-warning" @click="navToProductGoods">
  123. <view class="goods-buttom-money">¥{{ goodsObjact.product_price }}</view>
  124. <view class="goods-buttom">单独购买</view>
  125. </view>
  126. <view class="goods-pay bg-danger" @click="toggleSpec(1)">
  127. <view class="goods-buttom-money">¥{{ goodsObjact.price }}</view>
  128. <view class="goods-buttom">我要拼团</view>
  129. </view>
  130. </view>
  131. <!-- 规格-模态层弹窗 -->
  132. <view class="popup spec" :class="specClass" @touchmove.stop.prevent="stopPrevent" @click="toggleSpec">
  133. <!-- 遮罩层 -->
  134. <view class="mask"></view>
  135. <view class="layer attr-content" @click.stop="stopPrevent">
  136. <view class="a-t">
  137. <image :src="actionImage"></image>
  138. <view class="right">
  139. <view class="good-name clamp">{{ goodsObjact.store_name }}</view>
  140. <text class="price">¥{{ actionPrice }}</text>
  141. <!-- <text class="stock">库存:{{ goodsObjact.stock }}件</text> -->
  142. <!-- <view class="selected" v-if="goodsType == 0">
  143. 已选:
  144. <text class="selected-text" v-for="(sItem, sIndex) in specSelected" :key="sIndex">{{ sItem }}</text>
  145. </view> -->
  146. </view>
  147. </view>
  148. <view v-for="(item, index) in specList" :key="index" class="attr-list">
  149. <text>{{ item.attr_name }}</text>
  150. <view class="item-list">
  151. <text
  152. v-for="(childItem, childIndex) in item.attr_value"
  153. :key="childIndex"
  154. class="tit"
  155. :class="{ selected: childItem.check }"
  156. @click="selectSpec(childItem, item, index)"
  157. >
  158. {{ childItem.attr }}
  159. </text>
  160. </view>
  161. </view>
  162. <view class="attr-list" style="padding-bottom: 120rpx;">
  163. <text>购买数量</text>
  164. <view class="item-list">
  165. <uni-number-box class="step" :isMin="true" :value="goodsNumber" :min="1" :max="goodsNumberMax" @eventChange="numberChange"></uni-number-box>
  166. </view>
  167. </view>
  168. <button class="btn" @click.stop="buy">确定</button>
  169. </view>
  170. </view>
  171. <view :class="{ seckillBottom: goodsType == 1, goodsBottom: goodsType == 0 }"></view>
  172. <!-- 分享 -->
  173. <!-- <share ref="share" :contentHeight="580" :shareList="shareList"></share> -->
  174. </view>
  175. </template>
  176. <script>
  177. // import share from '@/components/share';
  178. import uniNumberBox from '@/components/uni-number-box.vue';
  179. import uniCountdown from '@/components/uni-countdown/uni-countdown.vue';
  180. import { goodsDetail, cartAdd, collectAdd, collectDel, seckillGoods, groupGoods } from '@/api/product.js';
  181. // #ifdef H5
  182. import { weixindata,shareLoad } from '@/utils/wxAuthorized';
  183. import { mapState } from 'vuex';
  184. import weixinObj from "@/plugin/jweixin-module/index.js";
  185. // #endif
  186. export default {
  187. components: {
  188. uniNumberBox,
  189. uniCountdown
  190. },
  191. filters: {
  192. address(val) {
  193. let str = '';
  194. if (val) {
  195. str = val[0] + ' ' + val[1];
  196. }
  197. return str;
  198. }
  199. },
  200. data() {
  201. return {
  202. details: '',
  203. reply: '', //评论
  204. type: 1, //默认支付方式add为
  205. goodsNumber: 1, //购买数量
  206. goodsid: '', //商品id
  207. specClass: 'none', //显示隐藏弹窗
  208. shareList: [], //分享列表
  209. goodsObjact: {}, //保存商品数据
  210. storeObjact: {}, //保存店铺数据
  211. //图片循环
  212. imgList: [],
  213. specList: [],
  214. // 对比对象
  215. productValue: [],
  216. actionPrice: 0, //默认选中商品价格
  217. actionImage: '', //默认选中图片
  218. uniqueId: '', //选中的商品分类
  219. specSelected: [], //选中的分类
  220. specSelectedName: '', //选中分类名称
  221. goodsNumberMax: 0, //最大可购买数量
  222. shopId: '', //商店id
  223. //商店信息
  224. shopInfo: {
  225. logo: '',
  226. title: ''
  227. }, //商店信息
  228. goodsType: 0, //商品类型1秒杀商品0为普通商品2为拼团商品
  229. // 秒杀数据保存
  230. seckillObj: {
  231. stopTime: 0, //结束时间
  232. stop: false, //是否结束
  233. stopTimeH: 0, //小时
  234. stopTimeM: 0, //分钟
  235. stopTimeS: 0 //秒钟
  236. },
  237. // 拼团数据保存
  238. pink: {
  239. id: '', //拼团编号
  240. uid: '', //用户编号
  241. people: '', //拼团人数
  242. price: '', //拼团价格
  243. stop_time: '', //拼团结束时间
  244. nickname: '', //团长昵称
  245. avatar: '', //团长头像
  246. count: '', //拼团剩余人数
  247. h: '', //时
  248. i: '', //分
  249. s: '' //秒
  250. }
  251. };
  252. },
  253. async onLoad(options) {
  254. let obj = this;
  255. //保存商品id
  256. this.goodsid = options.id;
  257. // 判断有无人邀请
  258. if (options.spread) {
  259. // 存储邀请人
  260. uni.setStorageSync('spread', options.spread);
  261. }
  262. // 判断是否为秒杀商品
  263. if (options.type == 1) {
  264. // 保存商品类型
  265. this.goodsType = 1;
  266. // 保存结束时间
  267. this.seckillObj.stopTime = options.stoptime;
  268. // 获取当前时间毫秒数
  269. let stoptime = options.stoptime * 1000;
  270. // 获取当前时间
  271. let acitonTime = new Date();
  272. // 判断当前时间是否大于结束时间
  273. if (acitonTime.getTime() > stoptime) {
  274. // 当前秒杀时间已经结束
  275. this.seckillObj.stop = true;
  276. } else {
  277. // 计算倒计时
  278. this.timeComputed(stoptime, this.seckillObj);
  279. }
  280. this.seckillGoods();
  281. return;
  282. }
  283. if (options.type == 2) {
  284. // 保存当前拼团商品类型
  285. this.goodsType = 2;
  286. // 家在数据
  287. this.groupGoods();
  288. return;
  289. }
  290. if (this.goodsType == 0) {
  291. // 加载普通商品详情
  292. this.goodsDetail();
  293. }
  294. },
  295. computed: {
  296. // #ifdef H5
  297. ...mapState(['weichatObj', 'baseURL', 'urlFile']),
  298. ...mapState('user', ['userInfo'])
  299. // #endif
  300. },
  301. methods: {
  302. navTo(url) {
  303. uni.navigateTo({
  304. url
  305. });
  306. },
  307. // 转换字符串为数字
  308. moneyNum: function(value) {
  309. return +value;
  310. },
  311. navToProductGoods() {
  312. uni.redirectTo({
  313. url: '/pages/product/product?id=' + this.goodsObjact.product_id
  314. });
  315. },
  316. // 获取商品信息
  317. goodsDetail() {
  318. let obj = this;
  319. goodsDetail({}, this.goodsid).then(function({ data }) {
  320. obj.details = data;
  321. let goods = data.storeInfo;
  322. let store_info = data.system_store; // 保存店铺信息
  323. console.log(store_info);
  324. obj.storeObjact = store_info;
  325. obj.goodsObjact = goods;
  326. obj.reply = data.reply; //保存评论列表
  327. obj.imgList = goods.slider_image; //保存轮播图
  328. obj.specList = data.productAttr; //保存分类列表
  329. console.log(data.productAttr);
  330. obj.productValue = data.productValue; //保存分类查询数据
  331. obj.actionPrice = goods.price; //保存默认选中商品价格
  332. obj.actionImage = goods.image_base; //保存默认选中商品价格
  333. obj.goodsNumberMax = goods.stock; //保存默认选中最大可购买商品数量
  334. obj.shopId = data.mer_id; //保存商店id
  335. // 保存默认选中的对象
  336. obj.specSelected = []; //初始化默认选择对象
  337. for (let i = 0; i < obj.specList.length; i++) {
  338. // 设置默认数据
  339. let attrValue = obj.specList[i].attr_value[0];
  340. attrValue.check = true;
  341. obj.specSelected.push(attrValue.attr);
  342. }
  343. //保存默认选中的对象字符串名称
  344. let str = obj.specSelected.join(',');
  345. // 设置默认值
  346. obj.actionImage = obj.productValue[str].image;
  347. obj.uniqueId = obj.productValue[str].unique;
  348. // #ifdef H5
  349. obj.shareDate();
  350. // #endif
  351. });
  352. },
  353. // #ifdef H5
  354. // 加载微信html5页面分享方法
  355. shareDate() {
  356. let obj = this;
  357. // 保存分享人id链接
  358. let url = window.location.href + '&spread=' + this.userInfo.uid;
  359. // 判断是否微信浏览器
  360. let bool = uni.getStorageSync('weichatBrowser') || '';
  361. if (bool) {
  362. // 过滤微信强制添加的链接地址
  363. url = url.replace(/[\?,&]from=singlemessage/g, '');
  364. let data = {
  365. link: url, // 分享链接
  366. imgUrl: obj.goodsObjact.image, // 分享图标
  367. desc: obj.goodsObjact.store_info,
  368. title: obj.goodsObjact.store_name,
  369. success: function(e) {
  370. console.log(e);
  371. }
  372. };
  373. shareLoad(data);
  374. }
  375. },
  376. // #endif
  377. // 购买数量变化
  378. numberChange(e) {
  379. this.goodsNumber = e.number;
  380. },
  381. //规格弹窗开关
  382. toggleSpec(str) {
  383. if (this.specClass === 'show') {
  384. this.specClass = 'hide';
  385. setTimeout(() => {
  386. this.specClass = 'none';
  387. }, 250);
  388. } else if (this.specClass === 'none') {
  389. this.specClass = 'show';
  390. }
  391. // 保存当前购买类型
  392. this.type = str;
  393. },
  394. //选择规格
  395. selectSpec(item, arr, ind) {
  396. arr.attr_value.forEach(function(e) {
  397. e.check = false;
  398. });
  399. item.check = true;
  400. this.specSelected[ind] = item.attr;
  401. let str = this.specSelected.join(',');
  402. this.specSelectedName = this.specSelected.join(' ');
  403. if (this.productValue[str]) {
  404. let data = this.productValue[str];
  405. this.actionPrice = data.price;
  406. this.goodsNumberMax = data.stock;
  407. this.actionImage = data.image;
  408. this.uniqueId = data.unique;
  409. }
  410. },
  411. //分享
  412. share() {
  413. this.$refs.share.toggleMask();
  414. },
  415. //收藏
  416. toFavorite(item) {
  417. let obj = this;
  418. item.userCollect = !item.userCollect;
  419. if (!item.userCollect) {
  420. collectDel({ id: obj.goodsid, category: 'product' }).then(function(e) {
  421. uni.showToast({
  422. title: '成功取消收藏',
  423. type: 'top',
  424. duration: 1500
  425. });
  426. });
  427. } else {
  428. collectAdd({ id: obj.goodsid, category: 'product' }).then(function(e) {
  429. uni.showToast({
  430. title: '成功加入收藏',
  431. type: 'top',
  432. duration: 1500
  433. });
  434. });
  435. }
  436. },
  437. // 立即购买
  438. buy() {
  439. let obj = this;
  440. let data = {
  441. cartNum: obj.goodsNumber, //商品数量
  442. uniqueId: obj.uniqueId, //商品标签
  443. new: '1', //商品是否新增加到购物车1为不加入0为加入
  444. mer_id: obj.shopId
  445. // type: 0,//0为余额支付 1为消费券支付 2为积分支付
  446. };
  447. if (obj.type == 2) {
  448. data.new = 0;
  449. }
  450. if (obj.goodsType == 0) {
  451. data.productId = obj.goodsid; //商品编号
  452. }
  453. // 判断是否为秒杀商品
  454. if (obj.goodsType == 1) {
  455. data.secKillId = obj.goodsid; //秒杀商品编号
  456. data.productId = obj.goodsObjact.product_id; //商品编号
  457. // 判断是否秒杀已经结束
  458. if (obj.seckillObj.stop) {
  459. uni.showModal({
  460. title: '提示',
  461. content: '当前活动已经结束',
  462. showCancel: false
  463. });
  464. return;
  465. }
  466. }
  467. // 判断是否为拼团商品
  468. if (obj.goodsType == 2) {
  469. data.combinationId = obj.goodsid; //拼团编号
  470. data.productId = obj.goodsObjact.product_id; //商品编号
  471. }
  472. cartAdd(data)
  473. .then(function({ data }) {
  474. if (obj.type == 1) {
  475. // 跳转到支付页
  476. uni.navigateTo({
  477. url: '/pages/order/createOrder?id=' + data.cartId + '&goodsType=' + obj.goodsType
  478. });
  479. }
  480. if (obj.type == 2) {
  481. uni.showToast({
  482. title: '成功加入购物车',
  483. type: 'top',
  484. duration: 2000
  485. });
  486. obj.toggleSpec();
  487. }
  488. })
  489. .catch(e => {
  490. console.log(e);
  491. });
  492. },
  493. stopPrevent() {}
  494. }
  495. };
  496. </script>
  497. <style lang="scss">
  498. page {
  499. background: $page-color-base;
  500. }
  501. //秒杀底部高度
  502. .seckillBottom {
  503. height: 110rpx;
  504. }
  505. // 文章页底部高度撑开
  506. .contentBottomHeight {
  507. height: 110rpx;
  508. }
  509. //默认商品底部高度
  510. .goodsBottom {
  511. height: 160rpx;
  512. }
  513. .iconenter {
  514. font-size: $font-base + 2rpx;
  515. color: #888;
  516. }
  517. .carousel {
  518. /* #ifdef APP-PLUS */
  519. padding-top: var(--status-bar-height);
  520. /* #endif */
  521. height: 722rpx;
  522. position: relative;
  523. swiper {
  524. height: 100%;
  525. }
  526. .image-wrapper {
  527. width: 100%;
  528. height: 100%;
  529. }
  530. .swiper-item {
  531. display: flex;
  532. justify-content: center;
  533. align-content: center;
  534. // height: 750rpx;
  535. height: 710rpx;
  536. overflow: hidden;
  537. image {
  538. width: 100%;
  539. height: 100%;
  540. }
  541. }
  542. }
  543. // 秒杀
  544. .seckill-box-title {
  545. background: linear-gradient(90deg, rgba(239, 78, 81, 1) 0%, rgba(244, 113, 59, 1) 100%) !important;
  546. .price,
  547. .price-tip,
  548. .timeStop,
  549. .m-price {
  550. color: #ffffff !important;
  551. }
  552. .price-tip {
  553. font-size: $font-base;
  554. }
  555. .price {
  556. font-size: 45rpx !important;
  557. font-weight: bold;
  558. }
  559. .timeStop {
  560. }
  561. }
  562. // 底部拼团、秒杀支付按钮
  563. .goods-pay-box {
  564. position: fixed;
  565. left: 0;
  566. bottom: 0;
  567. z-index: 95;
  568. width: 750rpx;
  569. height: 100rpx;
  570. line-height: 1;
  571. color: #ffffff;
  572. text-align: center;
  573. font-size: $font-lg;
  574. .bgLine {
  575. background: linear-gradient(90deg, rgba(239, 78, 81, 1) 0%, rgba(244, 113, 59, 1) 100%);
  576. }
  577. // 拼团支付按钮
  578. .goods-pay {
  579. display: flex;
  580. align-content: center;
  581. flex-wrap: wrap;
  582. justify-content: center;
  583. .goods-buttom,
  584. .goods-buttom-money {
  585. width: 100%;
  586. }
  587. .goods-buttom-money {
  588. font-size: $font-base;
  589. }
  590. }
  591. .goods-pay-stop,
  592. .goods-pay {
  593. padding: 15rpx 0;
  594. height: 100%;
  595. width: 100%;
  596. }
  597. .goods-pay-stop {
  598. background: $color-gray;
  599. line-height: 70rpx;
  600. }
  601. }
  602. /* 标题简介 */
  603. .introduce-section {
  604. background: #fff;
  605. padding: 20rpx 30rpx;
  606. .title {
  607. font-size: 32rpx;
  608. color: $font-color-dark;
  609. height: 50rpx;
  610. line-height: 50rpx;
  611. }
  612. .price-box {
  613. display: flex;
  614. align-items: baseline;
  615. height: 64rpx;
  616. padding: 10rpx 0;
  617. font-size: 26rpx;
  618. color: #FD3B39;
  619. }
  620. .price {
  621. font-size: $font-lg + 2rpx;
  622. }
  623. .m-price {
  624. margin: 0 12rpx;
  625. color: $font-color-light;
  626. text-decoration: line-through;
  627. }
  628. .coupon-tip {
  629. align-items: center;
  630. padding: 4rpx 10rpx;
  631. background: $uni-color-primary;
  632. font-size: $font-sm;
  633. color: #fff;
  634. border-radius: 6rpx;
  635. line-height: 1;
  636. transform: translateY(-4rpx);
  637. }
  638. .bot-row {
  639. display: flex;
  640. align-items: center;
  641. height: 50rpx;
  642. font-size: $font-sm;
  643. color: $font-color-light;
  644. text {
  645. flex: 1;
  646. }
  647. }
  648. }
  649. /* 分享 */
  650. .share-section {
  651. display: flex;
  652. align-items: center;
  653. color: $font-color-base;
  654. background: linear-gradient(left, #fdf5f6, #fbebf6);
  655. padding: 12rpx 30rpx;
  656. .share-icon {
  657. display: flex;
  658. align-items: center;
  659. width: 70rpx;
  660. height: 30rpx;
  661. line-height: 1;
  662. border: 1px solid $uni-color-primary;
  663. border-radius: 4rpx;
  664. position: relative;
  665. overflow: hidden;
  666. font-size: 22rpx;
  667. color: $uni-color-primary;
  668. &:after {
  669. content: '';
  670. width: 50rpx;
  671. height: 50rpx;
  672. border-radius: 50%;
  673. left: -20rpx;
  674. top: -12rpx;
  675. position: absolute;
  676. background: $uni-color-primary;
  677. }
  678. }
  679. .iconfavorfill {
  680. position: relative;
  681. z-index: 1;
  682. font-size: 24rpx;
  683. margin-left: 2rpx;
  684. margin-right: 10rpx;
  685. color: #fff;
  686. line-height: 1;
  687. }
  688. .tit {
  689. font-size: $font-base;
  690. margin-left: 10rpx;
  691. }
  692. .iconprompt {
  693. padding: 10rpx;
  694. font-size: 30rpx;
  695. line-height: 1;
  696. }
  697. .share-btn {
  698. flex: 1;
  699. text-align: right;
  700. font-size: $font-sm;
  701. color: $uni-color-primary;
  702. }
  703. .iconenter {
  704. font-size: $font-sm;
  705. margin-left: 4rpx;
  706. color: $uni-color-primary;
  707. }
  708. }
  709. .c-list {
  710. margin-top: 20rpx;
  711. font-size: $font-sm + 2rpx;
  712. color: $font-color-base;
  713. background: #fff;
  714. .c-row {
  715. display: flex;
  716. align-items: center;
  717. padding: 20rpx 30rpx;
  718. position: relative;
  719. }
  720. .tit {
  721. width: 140rpx;
  722. }
  723. .con {
  724. flex: 1;
  725. color: $font-color-dark;
  726. .selected-text {
  727. margin-right: 10rpx;
  728. .num {
  729. color: #FD3B39;
  730. }
  731. }
  732. }
  733. .bz-list {
  734. height: 40rpx;
  735. font-size: $font-sm + 2rpx;
  736. color: $font-color-dark;
  737. text {
  738. display: inline-block;
  739. margin-right: 30rpx;
  740. }
  741. }
  742. .con-list {
  743. flex: 1;
  744. display: flex;
  745. flex-direction: column;
  746. color: $font-color-dark;
  747. line-height: 40rpx;
  748. }
  749. .red {
  750. color: $uni-color-primary;
  751. }
  752. }
  753. /* 评价 */
  754. .eva-section {
  755. display: flex;
  756. flex-direction: column;
  757. padding: 20rpx 30rpx;
  758. background: #fff;
  759. margin-top: 16rpx;
  760. .e-header {
  761. display: flex;
  762. align-items: center;
  763. height: 70rpx;
  764. font-size: $font-sm + 2rpx;
  765. color: $font-color-light;
  766. .tit {
  767. font-size: $font-base + 2rpx;
  768. color: $font-color-dark;
  769. margin-right: 4rpx;
  770. }
  771. .tip {
  772. flex: 1;
  773. text-align: right;
  774. }
  775. .iconenter {
  776. margin-left: 10rpx;
  777. }
  778. }
  779. }
  780. .eva-box {
  781. display: flex;
  782. padding: 20rpx 0;
  783. .portrait {
  784. flex-shrink: 0;
  785. width: 80rpx;
  786. height: 80rpx;
  787. border-radius: 100px;
  788. }
  789. .right {
  790. flex: 1;
  791. display: flex;
  792. flex-direction: column;
  793. font-size: $font-base;
  794. color: $font-color-base;
  795. padding-left: 26rpx;
  796. .con {
  797. font-size: $font-base;
  798. color: $font-color-dark;
  799. padding: 20rpx 0;
  800. }
  801. .bot {
  802. display: flex;
  803. justify-content: space-between;
  804. font-size: $font-sm;
  805. color: $font-color-light;
  806. }
  807. }
  808. }
  809. .eva-boxs {
  810. width: 100%;
  811. overflow: hidden;
  812. padding: 10px 28rpx;
  813. background: #f4f4f4;
  814. border-radius: 12rpx;
  815. font-size: $font-sm + 2rpx;
  816. color: #333;
  817. .portrait {
  818. flex-shrink: 0;
  819. width: 80rpx;
  820. height: 80rpx;
  821. border-radius: 100px;
  822. }
  823. .right {
  824. flex: 1;
  825. display: flex;
  826. flex-direction: column;
  827. font-size: $font-base;
  828. color: $font-color-base;
  829. .con {
  830. font-size: $font-base;
  831. color: $font-color-dark;
  832. }
  833. .bot {
  834. display: flex;
  835. justify-content: space-between;
  836. font-size: $font-sm;
  837. color: $font-color-light;
  838. }
  839. }
  840. }
  841. /* 详情 */
  842. .detail-desc {
  843. background: #fff;
  844. margin-top: 16rpx;
  845. /deep/ img {
  846. max-width: 100% !important;
  847. display: inline !important;
  848. }
  849. /deep/ div {
  850. max-width: 100% !important;
  851. }
  852. .d-header {
  853. display: flex;
  854. justify-content: center;
  855. align-items: center;
  856. height: 80rpx;
  857. font-size: $font-base + 2rpx;
  858. color: $font-color-dark;
  859. position: relative;
  860. text {
  861. padding: 0 20rpx;
  862. background: #fff;
  863. position: relative;
  864. z-index: 1;
  865. }
  866. &:after {
  867. position: absolute;
  868. left: 50%;
  869. top: 50%;
  870. transform: translateX(-50%);
  871. width: 300rpx;
  872. height: 0;
  873. content: '';
  874. border-bottom: 1px solid #ccc;
  875. }
  876. }
  877. }
  878. /* 规格选择弹窗 */
  879. .attr-content {
  880. padding: 10rpx 0 0;
  881. .a-t {
  882. padding: 0 30rpx;
  883. display: flex;
  884. image {
  885. width: 170rpx;
  886. height: 170rpx;
  887. flex-shrink: 0;
  888. border-radius: 8rpx;
  889. }
  890. .right {
  891. display: flex;
  892. flex-direction: column;
  893. padding-left: 24rpx;
  894. font-size: $font-sm + 2rpx;
  895. color: $font-color-base;
  896. line-height: 42rpx;
  897. .good-name {
  898. padding-top: 20rpx;
  899. max-width: 320rpx;
  900. font-size: 30rpx;
  901. font-family: PingFang SC;
  902. font-weight: bold;
  903. color: #1d2023;
  904. line-height: 42rpx;
  905. margin-bottom: 15rpx;
  906. }
  907. .price {
  908. font-size: 60rpx;
  909. font-family: PingFang SC;
  910. font-weight: bold;
  911. color: #ff6f0f;
  912. // font-size: $font-lg;
  913. // color: $uni-color-primary;
  914. // margin-bottom: 10rpx;
  915. }
  916. .selected-text {
  917. margin-right: 10rpx;
  918. }
  919. }
  920. }
  921. .attr-list {
  922. display: flex;
  923. flex-direction: column;
  924. font-size: $font-base + 2rpx;
  925. color: $font-color-base;
  926. padding-top: 30rpx;
  927. padding-left: 40rpx;
  928. padding-right: 30rpx;
  929. }
  930. .item-list {
  931. padding: 20rpx 0 0;
  932. display: flex;
  933. flex-wrap: wrap;
  934. .tit {
  935. display: flex;
  936. align-items: center;
  937. justify-content: center;
  938. background: #eee;
  939. // margin-left: 10rpx;
  940. margin-right: 20rpx;
  941. margin-bottom: 20rpx;
  942. border-radius: 100rpx;
  943. min-width: 60rpx;
  944. height: 60rpx;
  945. padding: 0 20rpx;
  946. font-size: $font-base;
  947. color: $font-color-dark;
  948. }
  949. .selected {
  950. background: #fbebee;
  951. color: $uni-color-primary;
  952. }
  953. }
  954. }
  955. /* 弹出层 */
  956. .popup {
  957. position: fixed;
  958. left: 0;
  959. top: 0;
  960. right: 0;
  961. bottom: 0;
  962. z-index: 99;
  963. &.show {
  964. display: block;
  965. .mask {
  966. animation: showPopup 0.2s linear both;
  967. }
  968. .layer {
  969. animation: showLayer 0.2s linear both;
  970. }
  971. }
  972. &.hide {
  973. .mask {
  974. animation: hidePopup 0.2s linear both;
  975. }
  976. .layer {
  977. animation: hideLayer 0.2s linear both;
  978. }
  979. }
  980. &.none {
  981. display: none;
  982. }
  983. .mask {
  984. position: fixed;
  985. top: 0;
  986. width: 100%;
  987. height: 100%;
  988. z-index: 1;
  989. background-color: rgba(0, 0, 0, 0.4);
  990. }
  991. .layer {
  992. position: fixed;
  993. z-index: 99;
  994. bottom: 0;
  995. width: 100%;
  996. min-height: 30vh;
  997. border-radius: 10rpx 10rpx 0 0;
  998. background-color: #fff;
  999. .btn {
  1000. position: absolute;
  1001. bottom: 0;
  1002. width: 750rpx;
  1003. height: 98rpx;
  1004. background: #FE5B38;
  1005. line-height: 98rpx;
  1006. // background: $uni-color-primary;
  1007. font-size: $font-base + 2rpx;
  1008. color: #fff;
  1009. }
  1010. }
  1011. @keyframes showPopup {
  1012. 0% {
  1013. opacity: 0;
  1014. }
  1015. 100% {
  1016. opacity: 1;
  1017. }
  1018. }
  1019. @keyframes hidePopup {
  1020. 0% {
  1021. opacity: 1;
  1022. }
  1023. 100% {
  1024. opacity: 0;
  1025. }
  1026. }
  1027. @keyframes showLayer {
  1028. 0% {
  1029. transform: translateY(120%);
  1030. }
  1031. 100% {
  1032. transform: translateY(0%);
  1033. }
  1034. }
  1035. @keyframes hideLayer {
  1036. 0% {
  1037. transform: translateY(0);
  1038. }
  1039. 100% {
  1040. transform: translateY(120%);
  1041. }
  1042. }
  1043. }
  1044. /* 底部操作菜单 */
  1045. .page-bottom {
  1046. position: fixed;
  1047. left: 0rpx;
  1048. bottom: 0rpx;
  1049. z-index: 95;
  1050. display: flex;
  1051. justify-content: center;
  1052. align-items: center;
  1053. width: 750rpx;
  1054. height: 98rpx;
  1055. background: rgba(255, 255, 255, 0.9);
  1056. box-shadow: 0 0 20rpx 0 rgba(0, 0, 0, 0.5);
  1057. // border-radius: 16rpx;
  1058. .p-b-btn {
  1059. display: flex;
  1060. flex-direction: column;
  1061. align-items: center;
  1062. justify-content: center;
  1063. font-size: $font-sm;
  1064. color: $font-color-base;
  1065. width: 100rpx;
  1066. height: 98rpx;
  1067. .iconfont {
  1068. font-size: 40rpx;
  1069. line-height: 48rpx;
  1070. color: $font-color-light;
  1071. }
  1072. &.active,
  1073. &.active .iconfont {
  1074. color: $uni-color-primary;
  1075. }
  1076. .icon-fenxiang2 {
  1077. font-size: 42rpx;
  1078. transform: translateY(-2rpx);
  1079. }
  1080. .iconlikefill {
  1081. font-size: 46rpx;
  1082. }
  1083. }
  1084. .action-btn-group {
  1085. display: flex;
  1086. height: 98rpx;
  1087. // border-radius: 100px;
  1088. overflow: hidden;
  1089. // margin-left: 20rpx;
  1090. position: relative;
  1091. // &:after {
  1092. // content: '';
  1093. // position: absolute;
  1094. // top: 50%;
  1095. // right: 50%;
  1096. // transform: translateY(-50%);
  1097. // height: 28rpx;
  1098. // width: 0;
  1099. // border-right: 1px solid rgba(255, 255, 255, 0.5);
  1100. // }
  1101. .action-btn {
  1102. display: flex;
  1103. align-items: center;
  1104. justify-content: center;
  1105. width: 375rpx;
  1106. height: 100%;
  1107. font-size: 34rpx;
  1108. padding: 0;
  1109. border-radius: 0;
  1110. // background: transparent;
  1111. background: #ffb238;
  1112. &.buy-now-btn {
  1113. background-color: #ffb238;
  1114. }
  1115. &.add-cart-btn {
  1116. background: #FD3B39;
  1117. }
  1118. }
  1119. }
  1120. }
  1121. // 商店头
  1122. .shop-box {
  1123. background-color: #ffffff;
  1124. margin-top: 20rpx;
  1125. margin-bottom: 10rpx;
  1126. padding: 20rpx;
  1127. .shop-img {
  1128. border-radius: 300rpx;
  1129. height: 80rpx;
  1130. width: 80rpx;
  1131. margin-right: 20rpx;
  1132. }
  1133. .shop-button {
  1134. border-radius: 100rpx;
  1135. padding: 10rpx 20rpx;
  1136. color: $color-red;
  1137. border: 1px solid $color-red;
  1138. font-size: $font-lg;
  1139. line-height: 1;
  1140. }
  1141. }
  1142. </style>