seckillGoods.vue 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983
  1. <template>
  2. <view class="container">
  3. <navbar :config="config" backColor="#666"></navbar>
  4. <view id="page-top">
  5. <view class="product">
  6. <view class="u-bg-fff pb40">
  7. <view class="pic">
  8. <swiper
  9. class="swiper"
  10. indicator-dots="true"
  11. :autoplay="true"
  12. interval="2000"
  13. duration="1500"
  14. circular="true"
  15. >
  16. <swiper-item v-if="dataForm.video_url">
  17. <j-video
  18. class="jvideo"
  19. :url="dataForm.video_url"
  20. width="750rpx"
  21. height="620rpx"
  22. ></j-video>
  23. </swiper-item>
  24. <swiper-item v-for="(item, index) in imglist" :key="index">
  25. <image :src="item" mode="aspectFill"></image>
  26. </swiper-item>
  27. </swiper>
  28. <view class="p-price">
  29. <view class="pd24 u-flex-center" style="align-items: baseline">
  30. <view class="u-FFF u-font36">
  31. <rich-text
  32. :nodes="$mUtil.priceBigSmallTwo(dataForm.min_price)"
  33. ></rich-text>
  34. </view>
  35. <text class="discount u-font24 u-ml20 u-del"
  36. >¥{{ dataForm.max_sale_price }}</text
  37. >
  38. </view>
  39. <view class="p-ab u-flex-center">
  40. <view class="triangle-bottomright"></view>
  41. <view class="seckill u-text-center u-font28">
  42. <!-- active_state 0:未开始 * 1:进行中 * 2:已结束 -->
  43. <view class="u-bold" v-if="dataForm.active_state == 1"
  44. >距结束</view
  45. >
  46. <view
  47. class="u-bold"
  48. v-if="
  49. dataForm.active_state == 0 || dataForm.active_state == 2
  50. "
  51. >已结束</view
  52. >
  53. <view v-if="dataForm.active_state != 2">
  54. <uni-countdown
  55. :backgroundColor="'none'"
  56. @timeup="overDown1"
  57. :color="'#3775F6'"
  58. :splitorColor="'#3775F6'"
  59. :show-day="time1[0] > 0"
  60. :day="time1[0]"
  61. :hour="time1[1]"
  62. :minute="time1[2]"
  63. :second="time1[3]"
  64. ></uni-countdown>
  65. </view>
  66. </view>
  67. </view>
  68. </view>
  69. <view class="mt10 u-plr30">
  70. <view>
  71. <view
  72. v-if="shop.platform_shop"
  73. class="tipsStatus"
  74. style="vertical-align: middle"
  75. >自营</view
  76. >
  77. <text class="u-font34 u-bold u-1A1A1A">{{
  78. dataForm.title
  79. }}</text>
  80. </view>
  81. <view class="u-font24 u-mt15 u-999">
  82. <text
  83. >已售
  84. <text class="u-FF0000">{{ dataForm.result_sale_num }}</text
  85. >件,仅剩<text class="u-FF0000">{{
  86. dataForm.residue_stock_total
  87. }}</text
  88. >件</text
  89. >
  90. </view>
  91. <!--优惠-->
  92. </view>
  93. </view>
  94. </view>
  95. <view class="u-bg-fff u-mt10">
  96. <view class="u-plr30 u-flex-center-sb pt-pb35">
  97. <view class="u-flex-center" @click="goShop">
  98. <view>
  99. <image class="u-avatar104" :src="shop.logo"></image>
  100. </view>
  101. <view class="u-ml25">
  102. <view class="u-font28 u-1A1A1A u-bold"
  103. >{{ shop.shop_name }}
  104. </view>
  105. <view class="u-999 u-font24 u-mt5 u-text2">
  106. <text
  107. class="iconfont"
  108. style="color: #00bf5a"
  109. @click.stop="goLocal"
  110. >&#xe6db;</text
  111. >
  112. {{ shop.province_name }}{{ shop.city_name }}{{ shop.area_name
  113. }}{{ shop.address }}
  114. </view>
  115. </view>
  116. </view>
  117. <view class="iconfont" @click="goShop">&#xe6c7;</view>
  118. </view>
  119. </view>
  120. </view>
  121. <view class="u-bg-fff u-mt10">
  122. <view
  123. class="tab u-flex-center-sa u-font30 u-1A1A1A u-border-one-one"
  124. :style="[{ top: `calc(${statusBarHeight}px + 44px)` }]"
  125. >
  126. <view
  127. @tap="change(0)"
  128. class="pb30"
  129. :class="{ active: isChecked == 0 }"
  130. >商品详情</view
  131. >
  132. <view
  133. @tap="change(1)"
  134. class="pb30"
  135. :class="{ active: isChecked == 1 }"
  136. >用户评论({{ commentListLength }})</view
  137. >
  138. </view>
  139. <view class="u-mt10">
  140. <!--商品详情-->
  141. <view v-if="isChecked == 0">
  142. <view class="richText ql-editor-box">
  143. <u-parse
  144. class="custom-parse"
  145. :html="goodsInfo.mobile_detail"
  146. ></u-parse>
  147. </view>
  148. </view>
  149. <!--评论-->
  150. <view class="u-plr30" v-else>
  151. <comment :value="commentList"></comment>
  152. </view>
  153. </view>
  154. </view>
  155. </view>
  156. <view style="height: 170rpx; background-color: white"></view>
  157. <view class="bottom-btn u-bg-fff">
  158. <view class="pt-pb30 u-plr30 u-flex-center-sb">
  159. <button
  160. open-type="share"
  161. class="u-text-center"
  162. style="line-height: normal; margin-left: 25rpx"
  163. >
  164. <view class="iconfont2 u-font44 u-999">&#xe684;</view>
  165. <view class="u-font28 u-1A1A1A">分享</view>
  166. </button>
  167. <!--秒杀按钮-->
  168. <view class="seckill-btn" v-if="dataForm.active_state == 0">
  169. <button v-if="ispay" class="u-btn-two u-DCCDA4" @click="notStarted()">
  170. 立即购买
  171. </button>
  172. </view>
  173. <view class="seckill-btn" v-if="dataForm.active_state == 1">
  174. <button
  175. v-if="ispay"
  176. class="u-btn-two u-DCCDA4"
  177. @click="buy(1, dataForm.id)"
  178. >
  179. 立即购买
  180. </button>
  181. </view>
  182. <view class="seckill-btn" v-if="dataForm.active_state == 2">
  183. <button
  184. v-if="ispay"
  185. class="u-btn-two u-DCCDA4"
  186. @click="itSover(1, dataForm.id)"
  187. >
  188. 立即购买
  189. </button>
  190. </view>
  191. </view>
  192. </view>
  193. <!--规格-->
  194. <uv-popup type="bottom" ref="specOpenRef">
  195. <view class="u-bg-fff spec">
  196. <view class="u-plr30 flex-sb u-border-one-one pb30">
  197. <view class="u-flex-center">
  198. <image
  199. class="u-goods200"
  200. :src="choseConfig.cover ? choseConfig.cover : cover"
  201. ></image>
  202. <view class="u-ml20">
  203. <view class="u-999 u-font24 u-flex-center">
  204. <view class="u-00BF5A u-font36">
  205. <rich-text
  206. :nodes="
  207. $mUtil.priceBigSmall(
  208. choseConfig.activity_price
  209. ? choseConfig.activity_price
  210. : moPrice
  211. )
  212. "
  213. ></rich-text>
  214. </view>
  215. <text class="u-del u-ml15"
  216. >¥{{
  217. choseConfig.market_price
  218. ? choseConfig.market_price
  219. : moDelPrice
  220. }}
  221. </text>
  222. </view>
  223. <view class="u-font22 u-999 u-mt5"
  224. >活动库存 {{ stock }} 件
  225. <text
  226. >商品库存{{
  227. choseConfig.able_stock
  228. ? choseConfig.able_stock
  229. : goods_total_stock
  230. }}</text
  231. >
  232. </view>
  233. <view class="u-1A1A1A u-mt25"
  234. >{{
  235. choseConfig.sku_set_name ? choseConfig.sku_set_name : "请选择"
  236. }}
  237. </view>
  238. </view>
  239. </view>
  240. <view class="iconfont u-999 closeIcon" @click="specOpenRef.close()"
  241. >&#xe612;</view
  242. >
  243. </view>
  244. <view>
  245. <view class="">
  246. <view
  247. class="u-mt30"
  248. v-for="(item, index) in skuTab"
  249. :key="item.head.id"
  250. >
  251. <view class="u-plr30">{{ item.head.name }}</view>
  252. <view class="u-mt20 u-border-one-one pb30">
  253. <view class="u-plr30 u-flex u-flex-warp">
  254. <view
  255. class="spec-item"
  256. :class="childrenItem.flag ? 'activeColor' : ''"
  257. @click="chonseSku(index, childrenItem.id)"
  258. v-for="childrenItem in item.values"
  259. :key="childrenItem.id"
  260. >{{ childrenItem.name }}</view
  261. >
  262. </view>
  263. </view>
  264. </view>
  265. </view>
  266. <view class="u-plr30 u-mt30">
  267. <view class="u-flex-center-sb">
  268. <view>购买数量</view>
  269. <view class="u-flex-center">
  270. <view class="iconfont minus" @click="resNum">&#xe60b;</view>
  271. <view class="num">{{ add_num }}</view>
  272. <view class="iconfont plus-sign" @click="addNum">&#xe686;</view>
  273. </view>
  274. </view>
  275. <view class="specOpen-btn">
  276. <view v-if="btnType == 0">
  277. <button class="u-btn-two" @click="btnBuy(btnType)">
  278. {{ btnName }}
  279. </button>
  280. </view>
  281. <view v-else>
  282. <button class="u-btn-two" @click="btnBuy(btnType)">
  283. {{ btnName }}
  284. </button>
  285. </view>
  286. </view>
  287. </view>
  288. </view>
  289. </view>
  290. </uv-popup>
  291. <!--页面加载动画-->
  292. <ldLoading isFullScreen :active="loading"></ldLoading>
  293. </view>
  294. </template>
  295. <script setup>
  296. import { ref } from "vue";
  297. import { onShareAppMessage, onShow, onLoad } from "@dcloudio/uni-app";
  298. import comment from "@/components/ld-comment/ld-comment.vue";
  299. const $http = uni.$http;
  300. const $mUtil = uni.$mUtil;
  301. const specOpenRef = ref(null);
  302. // 手机状态栏高度
  303. const statusBarHeight = ref(uni.getSystemInfoSync().statusBarHeight);
  304. const imglist = ref([]); // 详情图片数组
  305. const isChecked = ref(0);
  306. const btnName = ref("");
  307. const btnType = ref(""); // 0 购物车,1 立即购买
  308. const dataForm = ref({}); // 商品详情
  309. const shop = ref({}); // 店铺信息
  310. const shopDiscounts = ref({}); // 店铺首单优惠
  311. const stock = ref(0);
  312. const goods_total_stock = ref(0);
  313. const cover = ref("");
  314. const loading = ref(true);
  315. const moDelPrice = ref("");
  316. const moPrice = ref("");
  317. const goodsSkuList = ref([]); // sku 组合值
  318. const skuTab = ref([]); // sku 二位数组
  319. const goods_id = ref(null);
  320. const limit_buy_num = ref(0);
  321. const choseConfig = ref({});
  322. const hasId = ref("");
  323. const add_num = ref(1);
  324. const goStatus = ref(0); // 0: 购物车,1 下单
  325. const shop_id = ref(0);
  326. const commentList = ref([]);
  327. const commentListLength = ref(0);
  328. const goodsInfo = ref({});
  329. const time1 = ref([0, 0, 0, 0]);
  330. const ispay = ref(getApp().globalData.openPay);
  331. const able_stock = ref(0);
  332. // 生命周期
  333. onShow(() => {});
  334. onLoad((options) => {
  335. // 当用户进来有缓存店铺
  336. // 店铺推荐(商品)
  337. if (options.id) {
  338. getDetailInfo(options.id);
  339. }
  340. if (options.shareId) {
  341. recordSave(options.shareId, options.id);
  342. }
  343. });
  344. onShareAppMessage(() => {
  345. let user = uni.getStorageSync("personal");
  346. if (res.from === "button") {
  347. // 来自页面内分享按钮
  348. console.log(res.target);
  349. }
  350. return {
  351. title: dataForm.value.title,
  352. imageUrl: dataForm.value.cover,
  353. path: `/pages/product/goods/seckillGoods?id=${
  354. dataForm.value.id
  355. }&share=1&shareId=${user.id || ""}`,
  356. };
  357. });
  358. // 方法
  359. const notStarted = () => {
  360. uni.$uv.toast("活动尚未开始");
  361. };
  362. const itSover = () => {
  363. uni.$uv.toast("活动已结束");
  364. };
  365. const goLocal = () => {
  366. uni.openLocation({
  367. latitude: Number(shop.value.tx_latitude),
  368. longitude: Number(shop.value.tx_longitude),
  369. name: shop.value.name,
  370. address: shop.value.address,
  371. success: function () {
  372. console.log("success");
  373. },
  374. });
  375. };
  376. const goShop = () => {
  377. uni.navigateTo({
  378. url: "/pages/convenienceService/shopDetails?shopId=" + shop_id.value,
  379. });
  380. };
  381. const recordSave = (share_user_id, goods_id) => {
  382. $http
  383. .post("/share/record/save", {
  384. share_user_id: share_user_id,
  385. goods_id: goods_id,
  386. })
  387. .then((res) => {});
  388. };
  389. const getDetailInfo = (id) => {
  390. $http.get("/marketing/seckillActivityGoods/info/" + id).then((res) => {
  391. loading.value = false;
  392. if (res && res.code == 200) {
  393. dataForm.value = res.data;
  394. shop_id.value = res.data.shop_id;
  395. $http
  396. .get("/marketing/firstOrder/getByShop/" + shop_id.value)
  397. .then((res) => {
  398. if (res && res.code == 200) {
  399. shopDiscounts.value = res.data;
  400. }
  401. });
  402. $http.get("/yxt/shop/info/" + shop_id.value).then((res) => {
  403. if (res.data && res.code == 200) {
  404. shop.value = res.data;
  405. }
  406. });
  407. imglist.value = res.data.cover.split(",");
  408. if (res.data.active_state == 0 || res.data.active_state == 2) {
  409. time1.value = $mUtil
  410. .countDown(res.data.will_start_time)
  411. .split(":")
  412. .map((val) => Number(val));
  413. } else {
  414. time1.value = $mUtil
  415. .countDown(res.data.finish_time)
  416. .split(":")
  417. .map((val) => Number(val));
  418. }
  419. $http.get(`/goods/content/${dataForm.value.goods_id}`).then((res) => {
  420. if (res && res.code == 200) {
  421. goodsInfo.value = res.data;
  422. }
  423. });
  424. $http
  425. .get(`/comment/orderGoods/getgoodscomments/${dataForm.value.goods_id}`)
  426. .then((res) => {
  427. if (res && res.code == 200) {
  428. commentList.value = res.list;
  429. commentListLength.value =
  430. res.list && res.list.length ? res.list.length : 0;
  431. }
  432. });
  433. }
  434. });
  435. };
  436. const change = (i) => {
  437. isChecked.value = i;
  438. };
  439. const buy = (i, id) => {
  440. btnType.value = i;
  441. checkSku(id);
  442. if (i == 0) {
  443. btnName.value = "加入购物车";
  444. } else {
  445. btnName.value = "立即购买";
  446. }
  447. };
  448. const resNum = () => {
  449. if (add_num.value > 1) {
  450. add_num.value--;
  451. }
  452. };
  453. const addNum = () => {
  454. add_num.value++;
  455. };
  456. const chonseSku = (index, id) => {
  457. skuTab.value[index].values.forEach((res) => {
  458. res.flag = false;
  459. if (res.id == id) {
  460. res.flag = true;
  461. }
  462. });
  463. let choseId = [];
  464. skuTab.value.forEach((res) => {
  465. res.values.forEach((Key) => {
  466. if (Key.flag) {
  467. choseId.push(Key.id);
  468. }
  469. });
  470. });
  471. let totalId = choseId.sort((a, b) => a - b).join("|");
  472. hasId.value = totalId;
  473. goodsSkuList.value.forEach((res) => {
  474. let temp = res.sku_hash_code;
  475. let sku_hash_code_val = temp
  476. .split("|")
  477. .sort((a, b) => a - b)
  478. .join("|");
  479. if (sku_hash_code_val == totalId) {
  480. choseConfig.value = res;
  481. stock.value = dataForm.value.real_stock_total;
  482. able_stock.value = res.able_stock;
  483. }
  484. });
  485. };
  486. const checkSku = (id) => {
  487. $http
  488. .get(`/marketing/seckillActivityGoods/skus/${dataForm.value.id}`)
  489. .then((res) => {
  490. loading.value = false;
  491. goods_total_stock.value = res.data.goods_total_stock;
  492. if (res && res.code == 200) {
  493. choseConfig.value = {};
  494. hasId.value = "";
  495. res.data.goods.sku_table.forEach((keys) => {
  496. keys.values.forEach((val) => {
  497. val.flag = false;
  498. });
  499. });
  500. limit_buy_num.value = dataForm.value.limit_buy_num;
  501. goods_id.value = dataForm.value.goods_id;
  502. goodsSkuList.value = res.data.goods_sku_list;
  503. moPrice.value = dataForm.value.min_price;
  504. moDelPrice.value = dataForm.value.min_sale_price;
  505. cover.value = imglist.value[0];
  506. stock.value = dataForm.value.real_stock_total;
  507. if (res.data.goods_auth) {
  508. if (res.data.goods_auth.added) {
  509. specOpenRef.value.open();
  510. } else {
  511. uni.$uv.toast("该商品已经下架");
  512. }
  513. } else {
  514. uni.$uv.toast("没有经营权限");
  515. }
  516. if (skuTab.value.length == 0) {
  517. skuTab.value = res.data.goods.sku_table;
  518. for (let i in skuTab.value) {
  519. skuTab.value[i].values[0].flag = true;
  520. }
  521. }
  522. chonseSku(0, skuTab.value[0].values[0].id);
  523. }
  524. });
  525. };
  526. const btnBuys = () => {
  527. if (skuTab.value.length > 0 && hasId.value == "") {
  528. uni.$uv.toast("请选中 sku");
  529. return false;
  530. }
  531. if (add_num.value > limit_buy_num.value && limit_buy_num.value != 0) {
  532. uni.$uv.toast("商品限购" + limit_buy_num.value + "件");
  533. return false;
  534. }
  535. if (goodsSkuList.value.length > 0 && able_stock.value < add_num.value) {
  536. uni.$uv.toast("商品库存只有" + able_stock.value + "件");
  537. $http
  538. .post(`/singlegoods/understockrecord/save`, {
  539. shop_id: shop_id.value,
  540. goods_id: goods_id.value,
  541. single_goods_id: choseConfig.value.single_goods_id,
  542. sku_set_name: choseConfig.value.sku_set_name,
  543. buy_num: add_num.value,
  544. })
  545. .then((res) => {});
  546. return false;
  547. }
  548. if (goStatus.value == 0) {
  549. let data = {
  550. goods_id: goods_id.value,
  551. sku_hash_code: hasId.value,
  552. add_num: add_num.value,
  553. source_shop_id: shop_id.value.toString(),
  554. };
  555. $http.post(`/cart/add`, data).then((res) => {
  556. if (res && res.code == 200) {
  557. uni.$uv.toast("添加成功");
  558. // specOpen.value.close();
  559. choseConfig.value = {};
  560. add_num.value = 1;
  561. cartList();
  562. }
  563. });
  564. } else {
  565. psotJson();
  566. }
  567. };
  568. const psotJson = () => {
  569. let dataJson = {};
  570. let childArr = [];
  571. let parendArr = [];
  572. choseConfig.value;
  573. childArr.push({
  574. user_cart_id: 0,
  575. activity_goods_id: choseConfig.value.activity_goods_id,
  576. goods_id: goods_id.value,
  577. num: add_num.value,
  578. sku_hash_code: choseConfig.value.sku_hash_code,
  579. });
  580. parendArr.push({
  581. shop_id: shop.value.id,
  582. source_shop_id: shop.value.id,
  583. activity_id: dataForm.value.seckill_id,
  584. sponsor_activity_id: 0,
  585. user_remark: "",
  586. items: childArr,
  587. });
  588. dataJson = {
  589. is_cart: false,
  590. receipt_id: null,
  591. shipment_mode: 0,
  592. shop_orders: parendArr,
  593. marketing_type: 1,
  594. };
  595. uni.setStorageSync("dataJson", dataJson);
  596. uni.navigateTo({
  597. url: "../surePay/surePaySechill",
  598. });
  599. };
  600. const btnBuy = (i) => {
  601. goStatus.value = i;
  602. let token = uni.getStorageSync("apiToken");
  603. if (!token) {
  604. uni.navigateTo({
  605. url: "/pages/login/index",
  606. });
  607. } else {
  608. btnBuys();
  609. }
  610. };
  611. const cartList = () => {
  612. // 实现购物车逻辑
  613. };
  614. </script>
  615. <style lang="scss" scoped>
  616. .pd24 {
  617. padding: 24rpx;
  618. }
  619. .pd20 {
  620. padding: 20rpx;
  621. }
  622. .pt20-pb14 {
  623. padding-top: 20rpx;
  624. padding-bottom: 14rpx;
  625. }
  626. .pt28-pb18 {
  627. padding-top: 28rpx;
  628. padding-bottom: 18rpx;
  629. }
  630. .pb30 {
  631. padding-bottom: 30rpx;
  632. }
  633. .pb40 {
  634. padding-bottom: 40rpx;
  635. }
  636. .pb50 {
  637. padding-bottom: 50rpx;
  638. }
  639. .pt-pb30 {
  640. padding-top: 30rpx;
  641. padding-bottom: 30rpx;
  642. }
  643. .pt-pb35 {
  644. padding-top: 35rpx;
  645. padding-bottom: 35rpx;
  646. }
  647. .ml54 {
  648. margin-left: 54rpx;
  649. }
  650. .ml138 {
  651. margin-left: 138rpx;
  652. }
  653. .br-rd10 {
  654. border-radius: 10rpx;
  655. }
  656. .br-rd20 {
  657. border-radius: 20rpx;
  658. }
  659. .stb-btn {
  660. padding: 8rpx 18rpx;
  661. border-radius: 10rpx;
  662. }
  663. .br-FF0000 {
  664. border: 1rpx solid #00bf5a;
  665. border-radius: 24rpx;
  666. padding: 6rpx 12rpx;
  667. }
  668. .bg-FFF6EE {
  669. background-color: #fff6ee;
  670. }
  671. .mt80 {
  672. margin-top: 80rpx;
  673. }
  674. .mt10 {
  675. margin-top: 10rpx;
  676. }
  677. .product {
  678. // padding-bottom: 150rpx;
  679. }
  680. .pic {
  681. width: 100%;
  682. position: relative;
  683. .swiper {
  684. // height: 620rpx;
  685. height: 100vw;
  686. video {
  687. width: 100%;
  688. // height: 620rpx;
  689. height: 100vw;
  690. }
  691. image {
  692. width: 100%;
  693. // height: 620rpx;
  694. height: 100vw;
  695. }
  696. }
  697. .p-price {
  698. width: 100%;
  699. // position: absolute;
  700. top: 460rpx;
  701. // background: linear-gradient(90deg,#20a733, #0a824b);
  702. background: #00bf5a;
  703. border-radius: 20rpx 20rpx 0px 0px;
  704. position: relative;
  705. top: -16rpx;
  706. .discount {
  707. color: #ffffff;
  708. }
  709. }
  710. }
  711. .richText {
  712. padding: 30rpx;
  713. ::v-deep img {
  714. margin-top: 0 !important;
  715. }
  716. }
  717. //秒杀,拼团样式
  718. .p-ab {
  719. position: absolute;
  720. top: 0;
  721. right: 0;
  722. height: 100%;
  723. }
  724. .stb-list {
  725. padding-bottom: 10rpx;
  726. }
  727. .triangle-bottomright {
  728. width: 0;
  729. height: 0;
  730. border-bottom: 105rpx solid #dccda4;
  731. border-left: 60rpx solid transparent;
  732. }
  733. .seckill {
  734. background-color: #dccda4;
  735. color: #00bf5a;
  736. padding: 12rpx 15rpx;
  737. box-sizing: border-box;
  738. border-radius: 5rpx 20rpx 0px 0px;
  739. text-align: center;
  740. // width: 150rpx;
  741. }
  742. .seckill-btn {
  743. width: 76%;
  744. }
  745. .br-284534 {
  746. border-bottom: 1rpx solid rgba($color: #284534, $alpha: 0.3);
  747. }
  748. .gb-te {
  749. padding-top: 20rpx;
  750. padding-bottom: 15rpx;
  751. }
  752. .gb-btn {
  753. padding: 18rpx 80rpx 8rpx;
  754. line-height: 30rpx;
  755. }
  756. .btn-bg-dccda4 {
  757. background: #dccda4;
  758. border-radius: 48rpx 0rpx 0rpx 48rpx;
  759. }
  760. .btn-bg-00321E {
  761. background: #0b844a;
  762. border-radius: 0px 48px 48px 0px;
  763. }
  764. .tab {
  765. position: sticky;
  766. top: 0;
  767. background-color: #fff;
  768. padding-top: 38rpx;
  769. z-index: 9;
  770. .pb30 {
  771. position: relative;
  772. &::before {
  773. content: "";
  774. position: absolute;
  775. left: 50%;
  776. bottom: 0;
  777. transform: translateX(-50%);
  778. width: 0;
  779. height: 2px;
  780. background: #00bf5a;
  781. transition: all 0.3s;
  782. }
  783. &.active {
  784. font-size: 30rpx;
  785. color: #00bf5a;
  786. font-weight: 700;
  787. &::before {
  788. width: 100%;
  789. }
  790. }
  791. }
  792. }
  793. .bottom-btn {
  794. width: 100%;
  795. position: fixed;
  796. bottom: 0;
  797. z-index: 9;
  798. border-top: 1rpx solid #e6e6e6;
  799. .cart {
  800. position: relative;
  801. .number {
  802. position: absolute;
  803. top: -10rpx;
  804. left: 45rpx;
  805. padding: 4rpx 8rpx;
  806. background-color: #ff0000;
  807. border: 4rpx solid #ffffff;
  808. border-radius: 40rpx;
  809. }
  810. }
  811. .cart-btn {
  812. width: 230rpx;
  813. height: 85rpx;
  814. background: #dccda4;
  815. border-radius: 43rpx 0rpx 0rpx 43rpx;
  816. }
  817. .buy-btn {
  818. width: 230rpx;
  819. height: 85rpx;
  820. line-height: 85rpx;
  821. background: #0b844a;
  822. border-radius: 0rpx 43rpx 43rpx 0rpx;
  823. }
  824. }
  825. .flex-sb {
  826. display: flex;
  827. justify-content: space-between;
  828. }
  829. //弹窗
  830. .spec {
  831. border-radius: 18rpx 18rpx 0rpx 0rpx;
  832. padding-top: 30rpx;
  833. max-height: 900rpx;
  834. overflow-y: auto;
  835. .spec-item {
  836. background-color: #f6f6f6;
  837. border: 1px solid #f6f6f6;
  838. padding: 12rpx 30rpx;
  839. margin-bottom: 24rpx;
  840. font-size: 24rpx;
  841. color: #1a1a1a;
  842. border-radius: 4px;
  843. }
  844. .activeColor {
  845. background-color: #e1e6e3;
  846. border: 1px solid #3775f6;
  847. color: #00bf5a;
  848. border-radius: 4px;
  849. }
  850. .spec-item:not(:last-child) {
  851. margin-right: 24rpx;
  852. }
  853. //减号
  854. .minus {
  855. width: 50rpx;
  856. height: 50rpx;
  857. line-height: 50rpx;
  858. text-align: center;
  859. background: #dedede;
  860. border-radius: 8rpx 0rpx 0rpx 8rpx;
  861. }
  862. .num {
  863. width: 74rpx;
  864. height: 46rpx;
  865. line-height: 46rpx;
  866. text-align: center;
  867. border: 1px solid #dedede;
  868. }
  869. //加号
  870. .plus-sign {
  871. width: 50rpx;
  872. height: 50rpx;
  873. line-height: 50rpx;
  874. text-align: center;
  875. background: #dedede;
  876. border-radius: 0rpx 8rpx 8rpx 0rpx;
  877. }
  878. .specOpen-btn {
  879. margin-top: 68rpx;
  880. padding-bottom: 34rpx;
  881. button {
  882. background-color: #00bf5a;
  883. color: #ffffff;
  884. }
  885. }
  886. }
  887. </style>