You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2541 lines
81 KiB

3 months ago
  1. <template>
  2. <view :data-theme="theme">
  3. <skeleton :show="showSkeleton" :isNodes="isNodes" ref="skeleton" loading="chiaroscuro" selector="skeleton"
  4. bgcolor="#FFF"></skeleton>
  5. <view class="product-con skeleton" :style="{visibility: showSkeleton ? 'hidden' : 'visible'}">
  6. <view class='navbar' :class="opacity>0.6?'bgwhite':''">
  7. <view class='navbarH' :style='"height:"+navH+"rpx;"'>
  8. <view class='navbarCon acea-row' :style="{ paddingRight: navbarRight + 'px' }">
  9. <!-- #ifdef MP -->
  10. <view class="select_nav flex justify-center align-center" id="home" :style="{ top: homeTop + 'rpx' }">
  11. <text class="iconfont icon-fanhui2 px-20" @tap="returns"></text>
  12. <text class="iconfont icon-gengduo5 px-20" @tap="showNav"></text>
  13. <text class="nav_line"></text>
  14. </view>
  15. <!-- #endif -->
  16. <!-- #ifdef H5 || APP-PLUS -->
  17. <view id="home" class="home acea-row row-center-wrapper iconfont icon-xiangzuo h5_back"
  18. :class="opacity>0.5?'on':''" :style="{ top: homeTop + 'rpx' }" v-if="returnShow"
  19. @tap="returns">
  20. </view>
  21. <!-- #endif -->
  22. <!-- 头部tab标题 -->
  23. <!-- #ifdef H5 || APP-PLUS-->
  24. <view class="tab_nav" v-show="opacity > 0.6">
  25. <view class="header flex justify-between align-center">
  26. <view class="item" :class="navActive === index ? 'on' : ''" v-for="(item,index) in navList"
  27. :key='index' @tap="tap(index)">
  28. {{ item }}
  29. </view>
  30. </view>
  31. </view>
  32. <!-- #endif -->
  33. <!-- #ifdef H5 || APP-PLUS -->
  34. <view class="right_select" :style="{ top: homeTop + 'rpx' }" @tap="showNav">
  35. <text class="iconfont icon-gengduo2"></text>
  36. </view>
  37. <!-- #endif -->
  38. </view>
  39. </view>
  40. </view>
  41. <view class="dialog_nav" v-show="currentPage" :style="{ top: navH + 'rpx' }">
  42. <view class="dialog_nav_item" :class="item.after" v-for="(item,index) in selectNavList" :key="index"
  43. @click="linkPage(item.url)">
  44. <text class="iconfont" :class="item.icon"></text>
  45. <text class="pl-20">{{item.name}}</text>
  46. </view>
  47. </view>
  48. <view class="detail_container">
  49. <scroll-view :scroll-top="scrollTop" scroll-y='true' scroll-with-animation="true"
  50. :style='"height:"+height+"px;"' @scroll="scroll">
  51. <view id="past0">
  52. <productConSwiper class="skeleton-rect" :imgUrls="sliderImage" :videoline="videoLink"
  53. @videoPause="videoPause"></productConSwiper>
  54. <!-- 氛围图card -->
  55. <activity-style v-if="productInfo.activityStyle" :productInfo="productInfo"></activity-style>
  56. <view class="pad30">
  57. <view class='wrapper mb30 borRadius14'>
  58. <view class='share acea-row row-between row-bottom share-icon-box'>
  59. <view class='x-money skeleton-rect flex align-baseline' v-if="!productInfo.activityStyle">
  60. <text class='num font-44'>{{attr.productSelect.price}}</text>
  61. <view class="flex pl-2"
  62. v-if="attr.productSelect.vipPrice && attr.productSelect.vipPrice > 0">
  63. <image :src="urlDomain+'crmebimage/perset/staticImg/vip_badge.png'" class="vip_icon"></image>
  64. <text
  65. class='vip_money skeleton-rect'>{{attr.productSelect.vipPrice}}</text>
  66. </view>
  67. </view>
  68. <view class='iconfont icon-fenxiang share-icon' @click="listenerActionSheet"></view>
  69. </view>
  70. <view class='introduce skeleton-rect share-introduce'>{{productInfo.storeName}}</view>
  71. <view class='label acea-row row-between-wrapper'>
  72. <view class="skeleton-rect">原价:{{attr.productSelect.otPrice || 0}}</view>
  73. <view class="skeleton-rect">
  74. 库存:{{productInfo.stock || 0}}{{productInfo.unitName || ''}}</view>
  75. <view class="skeleton-rect">
  76. 销量:{{Math.floor(productInfo.sales) + Math.floor(productInfo.ficti) || 0}}{{productInfo.unitName || ''}}
  77. </view>
  78. </view>
  79. <view v-if="defaultCoupon.length>0 && type=='normal'"
  80. class='coupon acea-row row-between-wrapper' @click='couponTap'>
  81. <view class='hide line1 acea-row skeleton-rect'>优惠券
  82. <view class='activity'>{{defaultCoupon[0].minPrice}}{{defaultCoupon[0].money}}
  83. </view>
  84. </view>
  85. <view class='iconfont icon-jiantou'></view>
  86. </view>
  87. <view class="coupon acea-row row-between-wrapper" v-if="activityH5.length">
  88. <view class="line1 acea-row">
  89. <text class="activityName skeleton-rect">&nbsp;&nbsp;&nbsp;</text>
  90. <view v-for='(item,index) in activityH5' :key='index' @click="goActivity(item)"
  91. class="activityBox">
  92. <view v-if="item.type === '1'" class="skeleton-rect"
  93. :class="index==0?'activity_pin':'' || index==1?'activity_miao':'' || index==2?'activity_kan':''">
  94. <text class="iconfonts iconfont icon-miaosha1"></text>
  95. <text class="activity_title"> 参与秒杀</text>
  96. </view>
  97. <view class="skeleton-rect"
  98. :class="index==0?'activity_pin':'' || index==1?'activity_miao':'' || index==2?'activity_kan':''"
  99. v-if="item.type === '2'">
  100. <text class="iconfonts iconfont icon-kanjia"></text>
  101. <text class="activity_title"> 参与砍价</text>
  102. </view>
  103. <view class="skeleton-rect"
  104. :class="index==0?'activity_pin':'' || index==1?'activity_miao':'' || index==2?'activity_kan':''"
  105. v-if="item.type === '3'">
  106. <text class="iconfonts iconfont icon-pintuan"></text>
  107. <text class="activity_title"> 参与拼团</text>
  108. </view>
  109. </view>
  110. </view>
  111. </view>
  112. </view>
  113. <view class='attribute mb30 borRadius14' @click="selecAttr">
  114. <view class="acea-row row-between-wrapper">
  115. <view class="line1 skeleton-rect">{{attrTxt}}
  116. <text class='atterTxt'>{{attrValue}}</text>
  117. </view>
  118. <view class='iconfont icon-jiantou'></view>
  119. </view>
  120. <view class="acea-row row-between-wrapper" style="margin-top:7px;padding-left:55px;"
  121. v-if="skuArr.length > 1">
  122. <view class="flex">
  123. <image :src="item.image" v-for="(item,index) in skuArr.slice(0,4)" :key="index"
  124. class="attrImg"></image>
  125. </view>
  126. <view class="switchTxt">{{skuArr.length}}种规格可选</view>
  127. </view>
  128. </view>
  129. <view class='userEvaluation' id="past1">
  130. <view class='title acea-row row-between-wrapper'
  131. :style="replyCount==0?'border-bottom-left-radius:14rpx;border-bottom-right-radius:14rpx;':''">
  132. <view>用户评价<i>({{replyCount}})</i></view>
  133. <navigator class='praise' hover-class='none'
  134. :url='"/pages/goods/goods_comment_list/index?productId="+id'>
  135. <i>好评</i>&nbsp;<text class='font_color px-12'>{{replyChance || 0}}%</text>
  136. <text class='iconfont icon-jiantou'></text>
  137. </navigator>
  138. </view>
  139. <block v-if="replyCount">
  140. <userEvaluation :reply="reply"></userEvaluation>
  141. </block>
  142. </view>
  143. <!-- 优品推荐 -->
  144. <view class="superior borRadius14" if='good_list.length' id="past2">
  145. <view class="title acea-row row-center-wrapper">
  146. <image :src="urlDomain+'crmebimage/perset/staticImg/xzuo.png'"></image>
  147. <view class="titleTxt">优品推荐</view>
  148. <image :src="urlDomain+'crmebimage/perset/staticImg/xyou.png'"></image>
  149. </view>
  150. <view class="slider-banner banner">
  151. <swiper indicator-dots="true" :autoplay="autoplay" :circular="circular"
  152. :interval="interval" :duration="duration" indicator-color="#999"
  153. :indicator-active-color="indicatorBg" :style="'height:'+clientHeight+'px'">
  154. <swiper-item v-for="(item,indexw) in good_list" :key="indexw">
  155. <view class="list acea-row row-middle" :id="'list'+indexw">
  156. <view class="item" v-for="(val,indexn) in item.list" :key="indexn"
  157. @click="goDetail(val)">
  158. <view class="pictrue">
  159. <image :src="val.image"></image>
  160. <span class="pictrue_log pictrue_log_class"
  161. v-if="val.activityH5 && val.activityH5.type === '1'">秒杀</span>
  162. <span class="pictrue_log pictrue_log_class"
  163. v-if="val.activityH5 && val.activityH5.type === '2'">砍价</span>
  164. <span class="pictrue_log pictrue_log_class"
  165. v-if="val.activityH5 && val.activityH5.type === '3'">拼团</span>
  166. </view>
  167. <view class="name line1">{{val.storeName}}</view>
  168. <view class="money theme_price">¥{{val.price}}</view>
  169. </view>
  170. </view>
  171. </swiper-item>
  172. <!-- <view class="swiper-pagination" slot="pagination"></view> -->
  173. </swiper>
  174. </view>
  175. </view>
  176. </view>
  177. </view>
  178. <view class='product-intro' id="past3">
  179. <view class='title'>
  180. <image :src="urlDomain+'crmebimage/perset/staticImg/xzuo.png'"></image>
  181. <span class="sp">产品详情</span>
  182. <image :src="urlDomain+'crmebimage/perset/staticImg/xyou.png'"></image>
  183. </view>
  184. <view class='conter'>
  185. <jyf-parser :html="description" ref="article" :tag-style="tagStyle"></jyf-parser>
  186. </view>
  187. </view>
  188. <view style='height:120rpx;'></view>
  189. </scroll-view>
  190. </view>
  191. <view class='footer acea-row row-between-wrapper'>
  192. <!-- #ifdef MP -->
  193. <button hover-class='none' class='item skeleton-rect' @click="onClickService"
  194. v-if="chatConfig.telephone_service_switch === 'open'">
  195. <view class='iconfont icon-kefu'></view>
  196. <view>客服</view>
  197. </button>
  198. <template v-else>
  199. <button open-type="contact" hover-class='none' class='item skeleton-rect' v-if="chatConfig.wx_chant_independent=='open'">
  200. <view class='iconfont icon-kefu'></view>
  201. <view>客服</view>
  202. </button>
  203. <button class="item" hover-class='none' @click="wxChatService" v-else>
  204. <view class='iconfont icon-kefu'></view>
  205. <text>联系客服</text>
  206. </button>
  207. </template>
  208. <!-- #endif -->
  209. <!-- #ifndef MP -->
  210. <view class="item skeleton-rect" @click="onClickService">
  211. <view class="iconfont icon-kefu"></view>
  212. <view>客服</view>
  213. </view>
  214. <!-- #endif -->
  215. <block v-if="type === 'normal'">
  216. <view @click="setCollect" class='item skeleton-rect'>
  217. <view class='iconfont icon-shoucang1' v-if="userCollect"></view>
  218. <view class='iconfont icon-shoucang' v-else></view>
  219. <view>收藏</view>
  220. </view>
  221. <navigator open-type='switchTab' class="animated item skeleton-rect"
  222. :class="animated==true?'bounceIn':''" url='/pages/order_addcart/order_addcart'
  223. hover-class="none">
  224. <view class='iconfont icon-gouwuche1'>
  225. <text v-if="Math.floor(CartCount)>0" class='num bg_color'>{{CartCount}}</text>
  226. </view>
  227. <view>购物车</view>
  228. </navigator>
  229. <view class="bnt acea-row skeleton-rect" v-if="attr.productSelect.stock <= 0">
  230. <form @submit="joinCart" report-submit="true"><button class="joinCart bnts"
  231. form-type="submit">加入购物车</button></form>
  232. <form report-submit="true"><button class="bnts bg-color-hui" form-type="submit">已售罄</button>
  233. </form>
  234. </view>
  235. <view class="bnt acea-row skeleton-rect" v-else>
  236. <form @submit="joinCart" report-submit="true"><button class="joinCart bnts"
  237. form-type="submit">加入购物车</button></form>
  238. <form @submit="goBuy" report-submit="true"><button class="buy bnts"
  239. form-type="submit">立即购买</button>
  240. </form>
  241. </view>
  242. </block>
  243. <view class="bnt bntVideo acea-row skeleton-rect"
  244. v-if="attr.productSelect.stock <= 0 && type === 'video'">
  245. <form report-submit="true"><button class="bnts bg-color-hui" form-type="submit">已售罄</button>
  246. </form>
  247. </view>
  248. <view class="bnt bntVideo acea-row skeleton-rect"
  249. v-if="attr.productSelect.stock > 0 && type === 'video'">
  250. <form @submit="goBuy" report-submit="true"><button class="buy bnts" form-type="submit">立即购买</button>
  251. </form>
  252. </view>
  253. </view>
  254. <shareRedPackets :sharePacket="sharePacket" @listenerActionSheet="listenerActionSheet"
  255. @showShare="showShare"></shareRedPackets>
  256. <!-- 组件 -->
  257. <productWindow :attr="attr" :isShow='1' :iSplus='1' @myevent="onMyEvent" @ChangeAttr="ChangeAttr"
  258. @ChangeCartNum="ChangeCartNum" @attrVal="attrVal" @iptCartNum="iptCartNum" id='product-window'
  259. @getImg="showImg">
  260. </productWindow>
  261. <couponListWindow :coupon='coupon' :typeNum="couponDeaultType[0].useType"
  262. @ChangCouponsClone="ChangCouponsClone" @ChangCoupons="ChangCoupons"
  263. @ChangCouponsUseState="ChangCouponsUseState" @tabCouponType="tabCouponType"></couponListWindow>
  264. <!-- 分享按钮 -->
  265. <view class="generate-posters" :class="posters ? 'on' : ''">
  266. <view class="generateCon acea-row row-middle">
  267. <!-- #ifndef MP -->
  268. <button class="item" hover-class="none" v-if="weixinStatus === true" @click="H5ShareBox = true">
  269. <view class="pictrue">
  270. <image :src="urlDomain+'crmebimage/perset/staticImg/weixin.png'"></image>
  271. </view>
  272. <view class="">分享给好友</view>
  273. </button>
  274. <!-- #endif -->
  275. <!-- #ifdef MP -->
  276. <button class="item" open-type="share" hover-class="none">
  277. <view class="pictrue">
  278. <image :src="urlDomain+'crmebimage/perset/staticImg/weixin.png'"></image>
  279. </view>
  280. <view class="">分享给好友</view>
  281. </button>
  282. <!-- #endif -->
  283. <!-- #ifdef APP-PLUS -->
  284. <view class="item" @click="appShare('WXSceneSession')">
  285. <view class="iconfont icon-weixin3"></view>
  286. <view class="">微信好友</view>
  287. </view>
  288. <view class="item" @click="appShare('WXSenceTimeline')">
  289. <view class="iconfont icon-pengyouquan"></view>
  290. <view class="">微信朋友圈</view>
  291. </view>
  292. <!-- #endif -->
  293. <!-- #ifdef H5 || MP -->
  294. <view class="item" @click="getpreviewImage">
  295. <view class="pictrue">
  296. <image :src="urlDomain+'crmebimage/perset/staticImg/changan.png'"></image>
  297. </view>
  298. <view class="">预览发图</view>
  299. </view>
  300. <!-- #endif -->
  301. <!-- #ifdef MP -->
  302. <button class="item" hover-class="none" @click="savePosterPath">
  303. <view class="pictrue">
  304. <image :src="urlDomain+'crmebimage/perset/staticImg/haibao.png'"></image>
  305. </view>
  306. <view class="">保存海报</view>
  307. </button>
  308. <!-- #endif -->
  309. </view>
  310. <view class="generateClose acea-row row-center-wrapper" @click="posterImageClose">取消</view>
  311. </view>
  312. <cus-previewImg ref="cusPreviewImg" :list="skuArr" @changeSwitch="changeSwitch"
  313. @shareFriend="listenerActionSheet" />
  314. <view class="mask" v-if="posters" @click="closePosters"></view>
  315. <view class="mask" v-if="canvasStatus"></view>
  316. <view class="mask_transparent" v-if="currentPage" @touchmove="hideNav" @click="hideNav()"></view>
  317. <!-- 海报展示 -->
  318. <view class='poster-pop' v-if="canvasStatus">
  319. <image :src='imagePath'></image>
  320. </view>
  321. <view class="canvas" v-else>
  322. <canvas style="width:750px;height:1190px;" canvas-id="firstCanvas"></canvas>
  323. <canvas canvas-id="qrcode" :style="{width: `${qrcodeSize}px`, height: `${qrcodeSize}px`}" />
  324. </view>
  325. <!-- 发送给朋友图片 -->
  326. <view class="share-box" v-if="H5ShareBox">
  327. <image :src="urlDomain+'crmebimage/perset/staticImg/share-info.png'" @click="H5ShareBox = false"></image>
  328. </view>
  329. </view>
  330. </view>
  331. </template>
  332. <script>
  333. import activityStyle from "./components/activityStyle.vue";
  334. import uQRCode from '@/js_sdk/Sansnn-uQRCode/uqrcode.js'
  335. import store from '@/store';
  336. import {
  337. HTTP_H5_URL
  338. } from '@/config/app.js';
  339. import {
  340. spread
  341. } from "@/api/user";
  342. import {
  343. getProductDetail,
  344. collectAdd,
  345. collectDel,
  346. postCartAdd,
  347. getReplyList,
  348. getReplyConfig,
  349. getProductGood,
  350. getReplyProduct
  351. } from '@/api/store.js';
  352. import {
  353. getCoupons,
  354. tokenIsExistApi
  355. } from '@/api/api.js';
  356. import {
  357. getCartCounts
  358. } from '@/api/order.js';
  359. import {
  360. toLogin
  361. } from '@/libs/login.js';
  362. import {
  363. mapGetters
  364. } from "vuex";
  365. import {
  366. imageBase64
  367. } from "@/api/public";
  368. import productConSwiper from '@/components/productConSwiper';
  369. import couponListWindow from '@/components/couponListWindow';
  370. import productWindow from '@/components/productWindow';
  371. import userEvaluation from '@/components/userEvaluation';
  372. import shareRedPackets from '@/components/shareRedPackets';
  373. import cusPreviewImg from '@/components/cus-previewImg/cus-previewImg.vue'
  374. import {
  375. silenceBindingSpread
  376. } from "@/utils";
  377. import parser from "@/components/jyf-parser/jyf-parser";
  378. import {
  379. computeUser
  380. } from "@/api/user.js";
  381. // #ifdef MP
  382. import {
  383. base64src
  384. } from '@/utils/base64src.js'
  385. import {
  386. getQrcode
  387. } from '@/api/api.js';
  388. // #endif
  389. let app = getApp();
  390. import {
  391. setThemeColor
  392. } from '@/utils/setTheme.js'
  393. import {
  394. Debounce
  395. } from '@/utils/validate.js'
  396. import navBar from '@/components/navBar';
  397. export default {
  398. components: {
  399. productConSwiper,
  400. couponListWindow,
  401. productWindow,
  402. userEvaluation,
  403. shareRedPackets,
  404. cusPreviewImg,
  405. "jyf-parser": parser,
  406. activityStyle,
  407. navBar
  408. },
  409. data() {
  410. let that = this;
  411. return {
  412. urlDomain: this.$Cache.get("imgHost"),
  413. showSkeleton: true, //骨架屏显示隐藏
  414. isNodes: 0, //控制什么时候开始抓取元素节点,只要数值改变就重新抓取
  415. //属性是否打开
  416. coupon: {
  417. coupon: false,
  418. type: 0,
  419. list: [],
  420. count: []
  421. },
  422. attrTxt: '请选择', //属性页面提示
  423. attrValue: '', //已选属性
  424. animated: false, //购物车动画
  425. id: 0, //商品id
  426. replyCount: 0, //总评论数量
  427. reply: [], //评论列表
  428. productInfo: {}, //商品详情
  429. productValue: [], //系统属性
  430. couponList: [], //优惠券
  431. cart_num: 1, //购买数量
  432. isAuto: false, //没有授权的不会自动授权
  433. isShowAuth: false, //是否隐藏授权
  434. isOpen: false, //是否打开属性组件
  435. actionSheetHidden: true,
  436. storeImage: '', //海报产品图
  437. PromotionCode: '', //二维码图片
  438. posterbackgd: `${this.$Cache.get("imgHost")}crmebimage/perset/staticImg/posterbackgd.png`,
  439. sharePacket: {
  440. isState: true, //默认不显示
  441. touchstart: false
  442. }, //分销商详细
  443. circular: false,
  444. autoplay: false,
  445. interval: 3000,
  446. duration: 500,
  447. clientHeight: "",
  448. systemStore: {}, //门店信息
  449. good_list: [],
  450. replyChance: 0,
  451. CartCount: 0,
  452. isDown: true,
  453. posters: false,
  454. weixinStatus: false,
  455. attr: {
  456. cartAttr: false,
  457. productAttr: [],
  458. productSelect: {}
  459. },
  460. description: '',
  461. navActive: 0,
  462. H5ShareBox: false, //公众号分享图片
  463. activityH5: [],
  464. retunTop: true, //顶部返回
  465. navH: "",
  466. navList: [],
  467. opacity: 0,
  468. scrollY: 0,
  469. topArr: [],
  470. toView: '',
  471. height: 0,
  472. heightArr: [],
  473. lock: false,
  474. scrollTop: 0,
  475. tagStyle: {
  476. img: 'width:100%;display:block;',
  477. table: 'width:100%',
  478. video: 'width:100%'
  479. },
  480. sliderImage: [],
  481. videoLink: '',
  482. qrcodeSize: 600,
  483. canvasStatus: false, //是否显示海报
  484. imagePath: '', //海报路径
  485. imgTop: '',
  486. errT: '',
  487. homeTop: 20,
  488. navbarRight: 0,
  489. userCollect: false,
  490. returnShow: true, //判断顶部返回是否出现
  491. type: "",
  492. theme: app.globalData.theme,
  493. indicatorBg: '',
  494. shareStatus: true,
  495. skuArr: [],
  496. currentPage: false,
  497. selectSku: {},
  498. selectNavList: [{
  499. name: '首页',
  500. icon: 'icon-shouye8',
  501. url: '/pages/index/index',
  502. after: 'dialog_after'
  503. },
  504. {
  505. name: '搜索',
  506. icon: 'icon-sousuo6',
  507. url: '/pages/goods/goods_search/index',
  508. after: 'dialog_after'
  509. },
  510. {
  511. name: '购物车',
  512. icon: 'icon-gouwuche7',
  513. url: '/pages/order_addcart/order_addcart',
  514. after: 'dialog_after'
  515. },
  516. {
  517. name: '我的收藏',
  518. icon: 'icon-shoucang3',
  519. url: '/pages/users/user_goods_collection/index',
  520. after: 'dialog_after'
  521. },
  522. {
  523. name: '个人中心',
  524. icon: 'icon-gerenzhongxin1',
  525. url: '/pages/user/index'
  526. },
  527. ],
  528. chatConfig: {
  529. consumer_hotline: '',
  530. telephone_service_switch: 'close',
  531. wx_chant_independent:'open'
  532. }, //客服配置
  533. defaultCoupon: [],
  534. couponDeaultType: [{
  535. useType: 1
  536. }],
  537. //优惠券分页数据
  538. where: {
  539. page: 1,
  540. limit: 999,
  541. productId: 0,
  542. type: 0
  543. },
  544. couponType: 0, //优惠券类型 类型,1-通用,2-商品,3-品类
  545. };
  546. },
  547. computed: mapGetters(['isLogin', 'uid', 'chatUrl', 'productType']),
  548. watch: {
  549. productInfo: {
  550. handler: function() {
  551. this.$nextTick(() => {});
  552. },
  553. immediate: true
  554. }
  555. },
  556. onShow() {
  557. //校验token是否有效,true为有效,false为无效
  558. this.getTokenIsExist();
  559. },
  560. onLoad(options) {
  561. //用户从分享卡片进入的场景下获取主题色配置
  562. this.$set(this, 'theme', this.$Cache.get('theme'));
  563. //判断顶部返回是否出现
  564. var pages = getCurrentPages();
  565. this.returnShow = pages.length === 1 ? false : true;
  566. if (pages.length <= 1) {
  567. this.retunTop = false
  568. }
  569. //页面中需要计算的一些值
  570. let that = this;
  571. uni.getSystemInfo({
  572. success: function(res) {
  573. that.height = res.windowHeight
  574. //res.windowHeight:获取整个窗口高度为px,*2为rpx;98为头部占据的高度;
  575. // #ifndef APP-PLUS || H5 || MP-ALIPAY
  576. //that.navbarRight = res.windowWidth - uni.getMenuButtonBoundingClientRect().left;
  577. // #endif
  578. },
  579. });
  580. //获取浏览器中的参数,商品id ,normal普通商品
  581. if (!options.scene && !options.id) {
  582. this.showSkeleton = false;
  583. this.$util.Tips({
  584. title: '缺少参数无法查看商品'
  585. }, {
  586. url: '/pages/index/index'
  587. });
  588. return;
  589. }
  590. if (options.id) this.id = options.id;
  591. // 仅仅小程序扫码进入获取商品id,商品类型
  592. if (options.scene) {
  593. let qrCodeValue = this.$util.getUrlParams(decodeURIComponent(options.scene));
  594. let mapeMpQrCodeValue = this.$util.formatMpQrCodeData(qrCodeValue);
  595. app.globalData.spread = mapeMpQrCodeValue.spread;
  596. this.id = mapeMpQrCodeValue.id;
  597. this.type = mapeMpQrCodeValue.type ? mapeMpQrCodeValue.type : 'normal';
  598. }
  599. if (options.type === 'video') {
  600. // #ifdef MP
  601. this.navH = 160;
  602. // #endif
  603. this.type = options.type
  604. } else {
  605. this.type = 'normal'
  606. this.navH = app.globalData.navHeight;
  607. }
  608. // 商品类型vuex存储
  609. this.$store.commit("PRODUCT_TYPE", this.type);
  610. // 客服配置
  611. this.$set(this, 'chatConfig', this.$Cache.getItem('chatConfig'));
  612. // #ifdef H5
  613. computeUser();
  614. // #endif
  615. if (options.spread) this.$Cache.set('spread',options.spread);
  616. this.getGoodsDetails(); //商品详情
  617. this.getCouponType(); //获取默认的 优惠券类型
  618. this.getProductReplyList(); //评论列表
  619. this.getProductReplyCount(); //评论条数
  620. this.getGoods(); //优品推荐
  621. //主题色颜色配置
  622. this.indicatorBg = setThemeColor();
  623. },
  624. onReady() {
  625. this.isNodes++;
  626. this.$nextTick(function() {
  627. // #ifdef MP
  628. const menuButton = uni.getMenuButtonBoundingClientRect();
  629. const query = uni.createSelectorQuery().in(this);
  630. query
  631. .select('#home')
  632. .boundingClientRect(data => {
  633. this.homeTop = menuButton.top * 2 + menuButton.height - data.height;
  634. })
  635. .exec();
  636. // #endif
  637. // #ifdef APP-PLUS
  638. this.homeTop = 60;
  639. // #endif
  640. });
  641. },
  642. /**
  643. * 用户点击右上角分享
  644. */
  645. // #ifdef MP
  646. onShareAppMessage: function(res) {
  647. let that = this;
  648. that.$set(that, 'actionSheetHidden', !that.actionSheetHidden);
  649. return {
  650. title: that.productInfo.storeName || '',
  651. imageUrl: that.productInfo.image || '',
  652. path: '/pages/goods/goods_details/index?id=' + that.id + '&spread=' + that.uid,
  653. }
  654. },
  655. // #endif
  656. onReachBottom() {
  657. this.getCouponList(this.couponType);
  658. },
  659. // 滚动监听
  660. onPageScroll(e) {
  661. // 传入scrollTop值并触发所有easy-loadimage组件下的滚动监听事件
  662. uni.$emit('scroll');
  663. },
  664. methods: {
  665. //独立客服跳转
  666. wxChatService(){
  667. let chatUrlArr = this.chatUrl.split('?')
  668. uni.navigateTo({
  669. url:`/pages/users/web_page/index?webUel=${chatUrlArr[0]}&title=客服&${chatUrlArr[1]}`
  670. })
  671. },
  672. //校验token是否有效,true为有效,false为无效
  673. getTokenIsExist() {
  674. this.$LoginAuth.getTokenIsExist().then(data => {
  675. if (data) {
  676. this.getCouponList(1); //优惠券列表 类型,1-通用,2-商品,3-品类
  677. this.getCartCount(true); //购物车数量
  678. //绑定关系
  679. silenceBindingSpread();
  680. }
  681. });
  682. },
  683. // #ifdef APP-PLUS
  684. appShare(scene) {
  685. let that = this
  686. let routes = getCurrentPages(); // 获取当前打开过的页面路由数组
  687. let curRoute = routes[routes.length - 1].$page.fullPath // 获取当前页面路由,也就是最后一个打开的页面路由
  688. uni.share({
  689. provider: "weixin",
  690. scene: scene,
  691. type: 0,
  692. href: `${HTTP_H5_URL}${curRoute}&spread=${that.uid}`,
  693. title: that.productInfo.storeName,
  694. summary: app.globalData.companyName,
  695. imageUrl: that.productInfo.image,
  696. success: function(res) {
  697. that.posters = false;
  698. },
  699. fail: function(err) {
  700. uni.showToast({
  701. title: '分享失败',
  702. icon: 'none',
  703. duration: 2000
  704. })
  705. that.posters = false;
  706. }
  707. });
  708. },
  709. // #endif
  710. onClickService() {
  711. if (this.chatConfig.telephone_service_switch === 'open') {
  712. uni.makePhoneCall({
  713. phoneNumber: this.chatConfig.consumer_hotline //仅为示例
  714. });
  715. } else {
  716. // #ifdef APP-PLUS
  717. uni.navigateTo({
  718. url: '/pages/users/web_page/index?webUel=' + this.chatUrl + '&title=客服'
  719. })
  720. // #endif
  721. // #ifndef APP-PLUS
  722. location.href = this.chatUrl;
  723. // #endif
  724. }
  725. },
  726. goActivity: function(e) {
  727. let item = e;
  728. if (item.type === "1") {
  729. uni.navigateTo({
  730. url: `/pages/activity/goods_seckill_details/index?id=${item.id}`
  731. });
  732. } else if (item.type === "2") {
  733. uni.navigateTo({
  734. url: `/pages/activity/goods_bargain_details/index?id=${item.id}&startBargainUid=${this.uid}`
  735. });
  736. } else {
  737. uni.navigateTo({
  738. url: `/pages/activity/goods_combination_details/index?id=${item.id}`
  739. });
  740. }
  741. },
  742. /**
  743. * 购物车手动填写
  744. *
  745. */
  746. iptCartNum: function(e) {
  747. this.$set(this.attr.productSelect, 'cart_num', e ? e : 1);
  748. },
  749. // 后退
  750. returns: function() {
  751. uni.navigateBack()
  752. },
  753. showNav() {
  754. this.currentPage = !this.currentPage;
  755. },
  756. tap: function(index) {
  757. var id = "past" + index;
  758. var index = index;
  759. var that = this;
  760. this.$set(this, 'toView', id);
  761. this.$set(this, 'navActive', index);
  762. this.$set(this, 'lock', true);
  763. this.$set(this, 'scrollTop', index > 0 ? that.topArr[index] - (app.globalData.navHeight / 2) : that
  764. .topArr[index]);
  765. },
  766. scroll: function(e) {
  767. var that = this,
  768. scrollY = e.detail.scrollTop;
  769. var opacity = scrollY / 500;
  770. opacity = opacity > 1 ? 1 : opacity;
  771. that.$set(that, 'opacity', opacity);
  772. that.$set(that, 'scrollY', scrollY);
  773. if (that.lock) {
  774. that.$set(that, 'lock', false)
  775. return;
  776. }
  777. for (var i = 0; i < that.topArr.length; i++) {
  778. if (scrollY < that.topArr[i] - (app.globalData.navHeight / 2) + that.heightArr[i]) {
  779. that.$set(that, 'navActive', i)
  780. break
  781. }
  782. }
  783. that.$set(that.sharePacket, 'touchstart', true); //滑动屏幕时让分享气泡缩回
  784. },
  785. /*
  786. *去商品详情页
  787. */
  788. goDetail(item) {
  789. if (!item.activityH5) {
  790. uni.redirectTo({
  791. url: '/pages/goods/goods_details/index?id=' + item.id
  792. })
  793. return
  794. }
  795. if (item.activityH5.length == 0) {
  796. uni.redirectTo({
  797. url: '/pages/goods/goods_details/index?id=' + item.id
  798. })
  799. return
  800. }
  801. // 砍价
  802. if (item.activityH5 && item.activityH5.type == 2) {
  803. uni.redirectTo({
  804. url: `/pages/activity/goods_bargain_details/index?id=${item.activityH5.id}&bargain=${this.uid}`
  805. })
  806. return
  807. }
  808. // 拼团
  809. if (item.activityH5 && item.activityH5.type == 3) {
  810. uni.redirectTo({
  811. url: `/pages/activity/goods_combination_details/index?id=${item.activityH5.id}`
  812. })
  813. return
  814. }
  815. // 秒杀
  816. if (item.activityH5 && item.activityH5.type == 1) {
  817. debugger
  818. uni.redirectTo({
  819. url: `/pages/activity/goods_seckill_details/index?id=${item.activityH5.id}`
  820. })
  821. return
  822. }
  823. },
  824. ChangCouponsClone: function() {
  825. this.$set(this.coupon, 'coupon', false)
  826. },
  827. /**
  828. * 购物车数量加和数量减
  829. *
  830. */
  831. ChangeCartNum: function(changeValue) {
  832. //changeValue:是否 加|减
  833. //获取当前变动属性
  834. let productSelect = this.productValue[this.attrValue];
  835. //如果没有属性,赋值给商品默认库存
  836. if (productSelect === undefined && !this.attr.productAttr.length)
  837. productSelect = this.attr.productSelect;
  838. //无属性值即库存为0;不存在加减;
  839. if (productSelect === undefined) return;
  840. let stock = productSelect.stock || 0;
  841. let num = this.attr.productSelect;
  842. if (changeValue) {
  843. num.cart_num++;
  844. if (num.cart_num > stock) {
  845. this.$set(this.attr.productSelect, "cart_num", stock);
  846. this.$set(this, "cart_num", stock);
  847. }
  848. } else {
  849. num.cart_num--;
  850. if (num.cart_num < 1) {
  851. this.$set(this.attr.productSelect, "cart_num", 1);
  852. this.$set(this, "cart_num", 1);
  853. }
  854. }
  855. },
  856. attrVal(val) {
  857. this.$set(this.attr.productAttr[val.indexw], 'index', this.attr.productAttr[val.indexw].attrValues[val
  858. .indexn]);
  859. },
  860. /**
  861. * 属性变动赋值
  862. *
  863. */
  864. ChangeAttr: function(res) {
  865. let productSelect = this.productValue[res];
  866. this.$set(this, "selectSku", productSelect);
  867. if (productSelect) {
  868. this.$set(this.attr.productSelect, "image", productSelect.image);
  869. this.$set(this.attr.productSelect, "price", productSelect.price);
  870. this.$set(this.attr.productSelect, "stock", productSelect.stock);
  871. this.$set(this.attr.productSelect, "unique", productSelect.id);
  872. this.$set(this.attr.productSelect, "cart_num", 1);
  873. this.$set(this.attr.productSelect, "vipPrice", productSelect.vipPrice);
  874. this.$set(this.attr.productSelect, 'otPrice', productSelect.otPrice);
  875. this.$set(this, "attrValue", res);
  876. this.$set(this, "attrTxt", "已选择");
  877. } else {
  878. this.$set(this.attr.productSelect, "image", this.productInfo.image);
  879. this.$set(this.attr.productSelect, "price", this.productInfo.price);
  880. this.$set(this.attr.productSelect, "stock", 0);
  881. this.$set(this.attr.productSelect, "unique", this.productInfo.id);
  882. this.$set(this.attr.productSelect, "cart_num", 1);
  883. this.$set(this.attr.productSelect, "vipPrice", this.productInfo.vipPrice);
  884. this.$set(this.attr.productSelect, 'otPrice', this.productInfo.otPrice);
  885. this.$set(this, "attrValue", "");
  886. this.$set(this, "attrTxt", "请选择");
  887. }
  888. },
  889. /**
  890. * 领取完毕移除当前页面领取过的优惠券展示
  891. */
  892. ChangCoupons: function(e) {
  893. let coupon = e;
  894. let couponList = this.$util.ArrayRemove(this.couponList, 'id', coupon.id);
  895. this.$set(this, 'couponList', couponList);
  896. this.getCouponList();
  897. },
  898. setClientHeight: function() {
  899. let that = this;
  900. if (!that.good_list.length) return;
  901. let view = uni.createSelectorQuery().in(this).select("#list0");
  902. view.fields({
  903. size: true,
  904. }, data => {
  905. that.$set(that, 'clientHeight', data.height + 20)
  906. }).exec();
  907. },
  908. /**
  909. * 优品推荐
  910. *
  911. */
  912. getGoods() {
  913. getProductGood().then(res => {
  914. let good_list = res.data.list || [];
  915. let count = Math.ceil(good_list.length / 6);
  916. let goodArray = new Array();
  917. for (let i = 0; i < count; i++) {
  918. let list = good_list.slice(i * 6, i * 6 + 6);
  919. if (list.length) goodArray.push({
  920. list: list
  921. });
  922. }
  923. this.$set(this, 'good_list', goodArray);
  924. let navList = ['商品', '评价', '详情'];
  925. if (goodArray.length) {
  926. navList.splice(2, 0, '推荐')
  927. }
  928. this.$set(this, 'navList', navList);
  929. this.$nextTick(() => {
  930. if (good_list.length) {
  931. // #ifndef APP-PLUS
  932. this.setClientHeight();
  933. // #endif
  934. // #ifdef APP-PLUS
  935. setTimeout(() => {
  936. this.setClientHeight();
  937. }, 1000)
  938. // #endif
  939. };
  940. })
  941. });
  942. },
  943. /**
  944. * 获取产品详情
  945. *
  946. */
  947. getGoodsDetails: function() {
  948. let that = this;
  949. getProductDetail(that.id, that.type).then(res => {
  950. let productInfo = res.data.productInfo;
  951. // 字符串数组转数组;
  952. let arrayImg = productInfo.sliderImage;
  953. let sliderImage = JSON.parse(arrayImg);
  954. if (that.getFileType(sliderImage[0]) == 'video') {
  955. //判断轮播图第一张是否是视频,如果是,就赋值给videoLink,并且将其在轮播图中删除
  956. this.$set(this, 'videoLink', sliderImage[0]);
  957. sliderImage.splice(0, 1);
  958. }
  959. that.$set(that, 'sliderImage', sliderImage);
  960. console.log(this.sliderImage);
  961. that.$set(that, 'productInfo', productInfo);
  962. that.$set(that, 'description', productInfo.content);
  963. that.$set(that, 'userCollect', res.data.userCollect);
  964. that.$set(that.attr, 'productAttr', res.data.productAttr);
  965. that.$set(that, 'productValue', res.data.productValue);
  966. for (let key in res.data.productValue) {
  967. let obj = res.data.productValue[key];
  968. that.skuArr.push(obj)
  969. }
  970. this.$set(this, "selectSku", that.skuArr[0]);
  971. that.$set(that.sharePacket, 'priceName', res.data.priceName);
  972. //that.$set(that.sharePacket, 'isState', Math.floor(res.data.priceName) != 0 ?false : true);
  973. that.$set(that.sharePacket, 'isState', (res.data.priceName != "0" && res.data.priceName !==
  974. null) ? false : true);
  975. that.$set(that, 'activityH5', res.data.activityAllH5 ? res.data.activityAllH5 : []);
  976. uni.setNavigationBarTitle({
  977. title: productInfo.storeName.substring(0, 7) + "..."
  978. })
  979. let productAttr = this.attr.productAttr.map(item => {
  980. return {
  981. attrName: item.attrName,
  982. attrValues: item.attrValues.split(','),
  983. id: item.id,
  984. isDel: item.isDel,
  985. productId: item.productId,
  986. type: item.type
  987. }
  988. });
  989. this.$set(this.attr, 'productAttr', productAttr);
  990. // var navList = ['商品', '评价', '详情'];
  991. // if (goodArray.length) {
  992. // navList.splice(2, 0, '推荐')
  993. // }
  994. //that.$set(that, 'navList', navList);
  995. //无需登录即可分享
  996. that.getCartCount();
  997. //#ifdef H5
  998. that.make(that.uid);
  999. that.ShareInfo();
  1000. this.getImageBase64(this.productInfo.image);
  1001. // #endif
  1002. // #ifdef MP
  1003. that.getQrcode();
  1004. // #endif
  1005. setTimeout(function() {
  1006. that.infoScroll();
  1007. }, 500);
  1008. // #ifdef MP
  1009. that.imgTop = res.data.productInfo.image
  1010. // #endif
  1011. // #ifndef H5
  1012. that.downloadFilestoreImage();
  1013. // #endif
  1014. that.DefaultSelect();
  1015. this.showSkeleton = false
  1016. setTimeout(() => {
  1017. this.defaultCoupon = this.coupon.list;
  1018. }, 1000)
  1019. }).catch(err => {
  1020. //状态异常返回上级页面
  1021. that.$util.Tips({
  1022. title: err.toString()
  1023. }, {
  1024. tab: 3,
  1025. url: 1
  1026. });
  1027. this.showSkeleton = false
  1028. })
  1029. },
  1030. //评论列表
  1031. getProductReplyList: function() {
  1032. getReplyProduct(this.id).then(res => {
  1033. this.reply = res.data.productReply ? [res.data.productReply] : [];
  1034. })
  1035. },
  1036. //评论条数
  1037. getProductReplyCount: function() {
  1038. let that = this;
  1039. getReplyConfig(that.id).then(res => {
  1040. that.$set(that, 'replyChance', res.data.replyChance * 100);
  1041. that.$set(that, 'replyCount', res.data.sumCount);
  1042. });
  1043. },
  1044. infoScroll: function() {
  1045. var that = this,
  1046. topArr = [],
  1047. heightArr = [];
  1048. for (var i = 0; i < that.navList.length; i++) { //productList
  1049. //获取元素所在位置
  1050. var query = uni.createSelectorQuery().in(this);
  1051. var idView = "#past" + i;
  1052. // if (!that.data.good_list.length && i == 2) {
  1053. // var idView = "#past" + 3;
  1054. // }
  1055. query.select(idView).boundingClientRect();
  1056. query.exec(function(res) {
  1057. var top = res[0].top;
  1058. var height = res[0].height;
  1059. topArr.push(top);
  1060. heightArr.push(height);
  1061. that.$set(that, 'topArr', topArr);
  1062. that.$set(that, 'heightArr', heightArr);
  1063. });
  1064. };
  1065. },
  1066. /**
  1067. * 默认选中属性
  1068. *
  1069. */
  1070. DefaultSelect: function() {
  1071. let productAttr = this.attr.productAttr;
  1072. let value = [];
  1073. //默认选中每种规格的第一个
  1074. for (let key in this.productValue) {
  1075. if (this.productValue[key].stock > 0) {
  1076. value = this.attr.productAttr.length ? key.split(",") : [];
  1077. break;
  1078. }
  1079. }
  1080. for (let i = 0; i < value.length; i++) {
  1081. this.$set(productAttr[i], "index", value[i]);
  1082. }
  1083. //sort();排序函数:数字-英文-汉字;
  1084. let productSelect = this.productValue[value.join(",")];
  1085. if (productSelect && productAttr.length) {
  1086. this.$set(this.attr.productSelect, "storeName", this.productInfo.storeName);
  1087. this.$set(this.attr.productSelect, "image", productSelect.image);
  1088. this.$set(this.attr.productSelect, "price", productSelect.price);
  1089. this.$set(this.attr.productSelect, "stock", productSelect.stock);
  1090. this.$set(this.attr.productSelect, "unique", productSelect.id);
  1091. this.$set(this.attr.productSelect, "cart_num", 1);
  1092. this.$set(this.attr.productSelect, "vipPrice", productSelect
  1093. .vipPrice); //attr.productSelect.otPrice
  1094. this.$set(this.attr.productSelect, 'otPrice', productSelect.otPrice);
  1095. this.$set(this, "attrValue", value.join(","));
  1096. this.$set(this, "attrTxt", "已选择");
  1097. } else if (!productSelect && productAttr.length) {
  1098. this.$set(this.attr.productSelect, "storeName", this.productInfo.storeName);
  1099. this.$set(this.attr.productSelect, "image", this.productInfo.image);
  1100. this.$set(this.attr.productSelect, "price", this.productInfo.price);
  1101. this.$set(this.attr.productSelect, "stock", 0);
  1102. this.$set(this.attr.productSelect, "unique", this.productInfo.id);
  1103. this.$set(this.attr.productSelect, "cart_num", 1);
  1104. this.$set(this.attr.productSelect, "vipPrice", this.productInfo.vipPrice);
  1105. this.$set(this.attr.productSelect, 'otPrice', this.productInfo.otPrice);
  1106. this.$set(this, "attrValue", "");
  1107. this.$set(this, "attrTxt", "请选择");
  1108. } else if (!productSelect && !productAttr.length) {
  1109. this.$set(this.attr.productSelect, "storeName", this.productInfo.storeName);
  1110. this.$set(this.attr.productSelect, "image", this.productInfo.image);
  1111. this.$set(this.attr.productSelect, "price", this.productInfo.price);
  1112. this.$set(this.attr.productSelect, "stock", this.productInfo.stock);
  1113. this.$set(this.attr.productSelect, "unique", this.productInfo.id || "");
  1114. this.$set(this.attr.productSelect, "cart_num", 1);
  1115. this.$set(this.attr.productSelect, "vipPrice", this.productInfo.vipPrice);
  1116. this.$set(this.attr.productSelect, 'otPrice', this.productInfo.otPrice);
  1117. this.$set(this, "attrValue", "");
  1118. this.$set(this, "attrTxt", "请选择");
  1119. }
  1120. },
  1121. /**
  1122. * 获取优惠券
  1123. *
  1124. */
  1125. getCouponList(type) {
  1126. let that = this;
  1127. if (type != undefined || type != null) {
  1128. that.where.type = type;
  1129. } else {
  1130. that.where.type = "";
  1131. }
  1132. that.where.productId = that.id;
  1133. if (that.loadend) return;
  1134. if (that.loading) return;
  1135. // if (isPage === true) that.$set(that, 'productList', []);
  1136. that.loading = true;
  1137. that.loadTitle = '';
  1138. getCoupons(that.where).then(res => {
  1139. let list = res.data.list;
  1140. let couponList = that.$util.SplitArray(list, that.coupon.list);
  1141. let loadend = list.length < that.where.limit;
  1142. that.loadend = loadend;
  1143. that.loading = false;
  1144. that.loadTitle = loadend ? '已全部加载' : '加载更多';
  1145. that.$set(that.coupon, 'list', couponList);
  1146. that.$set(that.where, 'page', that.where.page + 1);
  1147. });
  1148. },
  1149. async getCouponType() {
  1150. //在onLoad只调用一次,获取默认的类型作为打开优惠券列表的参数,不会随着切换变化
  1151. let dataList = await getCoupons({
  1152. productId: this.id
  1153. });
  1154. if (dataList.length) {
  1155. this.couponDeaultType = dataList.data;
  1156. this.$set(this.coupon, 'type', dataList);
  1157. }
  1158. },
  1159. //切换优惠券头部
  1160. tabCouponType(type) {
  1161. this.loadend = false;
  1162. this.loading = false;
  1163. this.where.page = 1;
  1164. this.where.limit = 999;
  1165. this.$set(this.coupon, 'list', []);
  1166. this.$set(this.coupon, 'type', type);
  1167. this.couponType = type; //优惠券类型
  1168. this.getCouponList(type);
  1169. },
  1170. ChangCouponsUseState(index) {
  1171. let that = this;
  1172. that.coupon.list[index].isUse = true;
  1173. that.$set(that.coupon, 'list', that.coupon.list);
  1174. that.$set(that.coupon, 'coupon', false);
  1175. },
  1176. /**
  1177. *
  1178. *
  1179. * 收藏商品
  1180. */
  1181. setCollect: function() {
  1182. let that = this;
  1183. if (this.isLogin === false) {
  1184. toLogin();
  1185. } else {
  1186. if (this.userCollect) {
  1187. collectDel(this.productInfo.id).then(res => {
  1188. that.$set(that, 'userCollect', !that.userCollect);
  1189. })
  1190. } else {
  1191. collectAdd(this.productInfo.id).then(res => {
  1192. that.$set(that, 'userCollect', !that.userCollect);
  1193. })
  1194. }
  1195. }
  1196. },
  1197. /**
  1198. * 打开属性插件
  1199. */
  1200. selecAttr: function() {
  1201. this.$set(this.attr, 'cartAttr', true);
  1202. this.$set(this, 'isOpen', true);
  1203. },
  1204. /**
  1205. * 打开优惠券插件
  1206. */
  1207. couponTap: function() {
  1208. let that = this;
  1209. if (that.isLogin === false) {
  1210. toLogin();
  1211. } else {
  1212. // this.loadend = false;
  1213. // this.loading = false;
  1214. // this.$set(that.coupon, 'list', []);
  1215. // //that.getCouponList(this.couponDeaultType[0].useType); //打开弹框默认请求商品券
  1216. that.$set(that.coupon, 'coupon', true);
  1217. }
  1218. },
  1219. onMyEvent: function() {
  1220. this.$set(this.attr, 'cartAttr', false);
  1221. this.$set(this, 'isOpen', false);
  1222. },
  1223. /**
  1224. * 打开属性加入购物车
  1225. *
  1226. */
  1227. joinCart: function(e) {
  1228. //是否登录
  1229. if (this.isLogin === false) {
  1230. toLogin();
  1231. } else {
  1232. this.goCat(1);
  1233. }
  1234. },
  1235. /*
  1236. * 加入购物车
  1237. */
  1238. goCat: function(num) {
  1239. let that = this,
  1240. productSelect = that.productValue[this.attrValue];
  1241. //打开属性
  1242. if (that.attrValue) {
  1243. //默认选中了属性,但是没有打开过属性弹窗还是自动打开让用户查看默认选中的属性
  1244. that.attr.cartAttr = !that.isOpen ? true : false;
  1245. } else {
  1246. if (that.isOpen) that.attr.cartAttr = true;
  1247. else that.attr.cartAttr = !that.attr.cartAttr;
  1248. }
  1249. //只有关闭属性弹窗时进行加入购物车
  1250. if (that.attr.cartAttr === true && that.isOpen === false)
  1251. return (that.isOpen = true);
  1252. //如果有属性,没有选择,提示用户选择
  1253. if (
  1254. that.attr.productAttr.length &&
  1255. productSelect.stock === 0 &&
  1256. that.isOpen === true
  1257. )
  1258. return that.$util.Tips({
  1259. title: "产品库存不足,请选择其它"
  1260. });
  1261. if (num === 1) {
  1262. let q = {
  1263. productId: parseFloat(that.id),
  1264. cartNum: parseFloat(that.attr.productSelect.cart_num),
  1265. isNew: false,
  1266. productAttrUnique: that.attr.productSelect !== undefined ?
  1267. that.attr.productSelect.unique : that.productInfo.id
  1268. };
  1269. postCartAdd(q).then(function(res) {
  1270. that.isOpen = false;
  1271. that.attr.cartAttr = false;
  1272. that.$util.Tips({
  1273. title: "添加购物车成功",
  1274. success: () => {
  1275. that.getCartCount(true);
  1276. }
  1277. });
  1278. })
  1279. .catch(res => {
  1280. that.isOpen = false;
  1281. return that.$util.Tips({
  1282. title: res
  1283. });
  1284. });
  1285. } else {
  1286. this.getPreOrder();
  1287. }
  1288. },
  1289. /**
  1290. * 获取购物车数量
  1291. * @param boolean 是否展示购物车动画和重置属性
  1292. */
  1293. getCartCount: function(isAnima) {
  1294. let that = this;
  1295. const isLogin = that.isLogin;
  1296. if (isLogin) {
  1297. getCartCounts(true, 'total').then(res => {
  1298. that.CartCount = res.data.count;
  1299. //加入购物车后重置属性
  1300. if (isAnima) {
  1301. that.animated = true;
  1302. setTimeout(function() {
  1303. that.animated = false;
  1304. }, 500);
  1305. }
  1306. });
  1307. }
  1308. },
  1309. /**
  1310. * 立即购买
  1311. */
  1312. goBuy: Debounce(function(e) {
  1313. if (this.isLogin === false) {
  1314. toLogin();
  1315. } else {
  1316. this.goCat(0);
  1317. }
  1318. }),
  1319. /**
  1320. * 预下单
  1321. */
  1322. getPreOrder: function() {
  1323. this.$Order.getPreOrder(this.type === 'normal' ? 'buyNow' : 'video', [{
  1324. "attrValueId": parseFloat(this.attr.productSelect.unique),
  1325. "productId": parseFloat(this.id),
  1326. "productNum": parseFloat(this.attr.productSelect.cart_num)
  1327. }]);
  1328. this.isOpen = false;
  1329. },
  1330. // 授权关闭
  1331. authColse: function(e) {
  1332. this.isShowAuth = e
  1333. },
  1334. /**
  1335. * 分享打开
  1336. *
  1337. */
  1338. listenerActionSheet: function() {
  1339. // if (this.isLogin === false) {
  1340. // toLogin();
  1341. // } else {
  1342. // // #ifdef H5
  1343. // if (this.$wechat.isWeixin() === true) {
  1344. // this.weixinStatus = true;
  1345. // }
  1346. // // #endif
  1347. // this.goPoster()
  1348. // this.posters = true;
  1349. // }
  1350. // #ifdef H5
  1351. if (this.$wechat.isWeixin() === true) {
  1352. this.weixinStatus = true;
  1353. }
  1354. // #endif
  1355. this.goPoster()
  1356. this.posters = true;
  1357. },
  1358. closePosters: function() {
  1359. this.posters = false;
  1360. this.currentPage = false;
  1361. },
  1362. //隐藏海报
  1363. posterImageClose: function() {
  1364. this.canvasStatus = false
  1365. this.posters = false;
  1366. },
  1367. //替换安全域名
  1368. setDomain: function(url) {
  1369. url = url ? url.toString() : '';
  1370. //本地调试打开,生产请注销
  1371. if (url.indexOf("https://") > -1) return url;
  1372. else return url.replace('http://', 'https://');
  1373. },
  1374. //获取海报产品图(解决跨域问题,只适用于小程序)
  1375. downloadFilestoreImage: function() {
  1376. let that = this;
  1377. uni.downloadFile({
  1378. url: that.setDomain(that.productInfo.image),
  1379. success: function(res) {
  1380. that.storeImage = res.tempFilePath;
  1381. },
  1382. fail: function() {
  1383. return that.$util.Tips({
  1384. title: ''
  1385. });
  1386. that.storeImage = '';
  1387. },
  1388. });
  1389. },
  1390. // 小程序关闭分享弹窗;
  1391. goFriend: function() {
  1392. this.posters = false;
  1393. },
  1394. // 小程序二维码
  1395. getQrcode() {
  1396. let that = this;
  1397. let data = {
  1398. pid: that.uid,
  1399. id: that.id,
  1400. path: 'pages/goods/goods_details/index'
  1401. }
  1402. getQrcode(data).then(res => {
  1403. base64src(res.data.code, Date.now(), res => {
  1404. that.PromotionCode = res;
  1405. });
  1406. }).catch(err => {
  1407. that.errT = err;
  1408. });
  1409. },
  1410. // 生成二维码;
  1411. make(uid) {
  1412. let href = location.href.split('?')[0] + "?id=" + this.id + "&spread=" + this.uid;
  1413. uQRCode.make({
  1414. canvasId: 'qrcode',
  1415. text: href,
  1416. size: this.qrcodeSize,
  1417. margin: 10,
  1418. success: res => {
  1419. this.PromotionCode = res;
  1420. },
  1421. complete: () => {},
  1422. fail: res => {
  1423. this.$util.Tips({
  1424. title: '海报二维码生成失败!'
  1425. });
  1426. }
  1427. })
  1428. },
  1429. getImageBase64: function(images) {
  1430. let that = this;
  1431. imageBase64({
  1432. url: images
  1433. }).then(res => {
  1434. that.imgTop = res.data.code;
  1435. })
  1436. },
  1437. /**
  1438. * 生成海报
  1439. */
  1440. goPoster: function() {
  1441. let that = this;
  1442. uni.showLoading({
  1443. title: '海报生成中',
  1444. mask: true
  1445. });
  1446. that.posters = false;
  1447. let arrImagesUrl = '';
  1448. let arrImagesUrlTop = '';
  1449. if (!that.PromotionCode) {
  1450. uni.hideLoading();
  1451. that.$util.Tips({
  1452. title: that.errT
  1453. });
  1454. return
  1455. }
  1456. setTimeout(() => {
  1457. if (!that.imgTop) {
  1458. uni.hideLoading();
  1459. that.$util.Tips({
  1460. title: '无法生成商品海报!'
  1461. });
  1462. return
  1463. }
  1464. }, 1000);
  1465. uni.downloadFile({
  1466. url: that.imgTop, //仅为示例,并非真实的资源
  1467. success: (res) => {
  1468. arrImagesUrlTop = res.tempFilePath;
  1469. let arrImages = [that.posterbackgd, arrImagesUrlTop, that.PromotionCode];
  1470. let storeName = that.productInfo.storeName;
  1471. let price = that.productInfo.price;
  1472. setTimeout(() => {
  1473. that.$util.PosterCanvas(arrImages, storeName, price, that.productInfo
  1474. .otPrice,
  1475. function(tempFilePath) {
  1476. that.imagePath = tempFilePath;
  1477. that.canvasStatus = true;
  1478. uni.hideLoading();
  1479. });
  1480. }, 500);
  1481. }
  1482. });
  1483. },
  1484. // 图片预览;
  1485. getpreviewImage: function() {
  1486. if (this.imagePath) {
  1487. let photoList = [];
  1488. photoList.push(this.imagePath)
  1489. uni.previewImage({
  1490. urls: photoList,
  1491. current: this.imagePath
  1492. });
  1493. } else {
  1494. this.$util.Tips({
  1495. title: '您的海报尚未生成'
  1496. });
  1497. }
  1498. },
  1499. /*
  1500. * 保存到手机相册
  1501. */
  1502. // #ifdef MP
  1503. savePosterPath: function() {
  1504. let that = this;
  1505. uni.getSetting({
  1506. success(res) {
  1507. if (!res.authSetting['scope.writePhotosAlbum']) {
  1508. uni.authorize({
  1509. scope: 'scope.writePhotosAlbum',
  1510. success() {
  1511. uni.saveImageToPhotosAlbum({
  1512. filePath: that.imagePath,
  1513. success: function(res) {
  1514. that.posterImageClose();
  1515. that.$util.Tips({
  1516. title: '保存成功',
  1517. icon: 'success'
  1518. });
  1519. },
  1520. fail: function(res) {
  1521. that.$util.Tips({
  1522. title: '保存失败'
  1523. });
  1524. }
  1525. })
  1526. }
  1527. })
  1528. } else {
  1529. uni.saveImageToPhotosAlbum({
  1530. filePath: that.imagePath,
  1531. success: function(res) {
  1532. that.posterImageClose();
  1533. that.$util.Tips({
  1534. title: '保存成功',
  1535. icon: 'success'
  1536. });
  1537. },
  1538. fail: function(res) {
  1539. that.$util.Tips({
  1540. title: '保存失败'
  1541. });
  1542. },
  1543. })
  1544. }
  1545. }
  1546. })
  1547. },
  1548. // #endif
  1549. ShareInfo() {
  1550. let data = this.productInfo;
  1551. let href = location.href;
  1552. if (this.$wechat.isWeixin()) {
  1553. href = href.indexOf("?") === -1 ? href + "?spread=" + this.uid : href + "&spread=" + this.uid;
  1554. let configAppMessage = {
  1555. desc: app.globalData.companyName,
  1556. title: data.storeName,
  1557. link: href,
  1558. imgUrl: data.image
  1559. };
  1560. this.$wechat.wechatEvevt([
  1561. "updateAppMessageShareData",
  1562. "updateTimelineShareData",
  1563. "onMenuShareAppMessage",
  1564. "onMenuShareTimeline"
  1565. ], configAppMessage).then(res => {
  1566. // console.log(res);
  1567. }).catch(err => {
  1568. console.log(err);
  1569. })
  1570. }
  1571. },
  1572. showShare(status) {
  1573. let that = this;
  1574. that.$set(that.sharePacket, 'touchstart', status);
  1575. },
  1576. hideNav() {
  1577. this.currentPage = false;
  1578. },
  1579. //下拉导航页面跳转
  1580. linkPage(url) {
  1581. if (url == '/pages/index/index' || url == '/pages/order_addcart/order_addcart' || url ==
  1582. '/pages/user/index') {
  1583. uni.switchTab({
  1584. url
  1585. })
  1586. } else {
  1587. uni.navigateTo({
  1588. url
  1589. })
  1590. }
  1591. this.currentPage = false
  1592. },
  1593. //点击sku图片打开轮播图
  1594. showImg(index) {
  1595. this.$refs.cusPreviewImg.open(this.selectSku.suk)
  1596. },
  1597. //滑动轮播图选择商品
  1598. changeSwitch(e) {
  1599. let productSelect = this.skuArr[e];
  1600. this.$set(this, 'selectSku', productSelect);
  1601. var skuList = productSelect.suk.split(',');
  1602. skuList.forEach((i, index) => {
  1603. this.$set(this.attr.productAttr[index], 'index', skuList[index]);
  1604. })
  1605. if (productSelect) {
  1606. this.$set(this.attr.productSelect, "image", productSelect.image);
  1607. this.$set(this.attr.productSelect, "price", productSelect.price);
  1608. this.$set(this.attr.productSelect, "stock", productSelect.stock);
  1609. this.$set(this.attr.productSelect, "unique", productSelect.id);
  1610. this.$set(this.attr.productSelect, "vipPrice", productSelect.vipPrice);
  1611. this.$set(this, "attrTxt", "已选择");
  1612. this.$set(this, "attrValue", productSelect.suk)
  1613. }
  1614. },
  1615. getFileType(fileName) {
  1616. // 后缀获取
  1617. let suffix = '';
  1618. // 获取类型结果
  1619. let result = '';
  1620. try {
  1621. const flieArr = fileName.split('.');
  1622. suffix = flieArr[flieArr.length - 1];
  1623. } catch (err) {
  1624. suffix = '';
  1625. }
  1626. // fileName无后缀返回 false
  1627. if (!suffix) {
  1628. return false;
  1629. }
  1630. suffix = suffix.toLocaleLowerCase();
  1631. // 图片格式
  1632. const imglist = ['png', 'jpg', 'jpeg', 'bmp', 'gif'];
  1633. // 进行图片匹配
  1634. result = imglist.find(item => item === suffix);
  1635. if (result) {
  1636. return 'image';
  1637. }
  1638. // 匹配 视频
  1639. const videolist = ['mp4', 'm2v', 'mkv', 'rmvb', 'wmv', 'avi', 'flv', 'mov', 'm4v'];
  1640. result = videolist.find(item => item === suffix);
  1641. if (result) {
  1642. return 'video';
  1643. }
  1644. // 其他 文件类型
  1645. return 'other';
  1646. },
  1647. videoPause() {
  1648. }
  1649. },
  1650. }
  1651. </script>
  1652. <style scoped lang="scss">
  1653. .lang{
  1654. width: 170rpx !important;
  1655. height: 60rpx !important;
  1656. border-radius: 33rpx;
  1657. }
  1658. .circle{
  1659. width: 58rpx !important;
  1660. height: 58rpx !important;
  1661. border-radius: 50%;
  1662. }
  1663. .product-con {
  1664. height: 100%;
  1665. }
  1666. .x-money {
  1667. font-size: 28rpx;
  1668. font-weight: 700;
  1669. @include price_color(theme);
  1670. }
  1671. .bg-color-hui {
  1672. background: #bbb !important;
  1673. border-radius: 0 25px 25px 0;
  1674. }
  1675. .select_nav {
  1676. width: 170rpx !important;
  1677. height: 60rpx !important;
  1678. border-radius: 33rpx;
  1679. background: rgba(255, 255, 255, 0.3);
  1680. border: 1px solid rgba(0,0,0,0.07);
  1681. color: #000;
  1682. position: fixed;
  1683. font-size: 18px;
  1684. line-height: 58rpx;
  1685. z-index: 1000;
  1686. left: 14rpx;
  1687. }
  1688. .px-20 {
  1689. padding: 0 20rpx 0;
  1690. }
  1691. .nav_line {
  1692. content: '';
  1693. display: inline-block;
  1694. width: 1px;
  1695. height: 34rpx;
  1696. background: #b3b3b3;
  1697. position: absolute;
  1698. left: 0;
  1699. right: 0;
  1700. margin: auto;
  1701. }
  1702. .bgwhite {
  1703. background: #fff;
  1704. }
  1705. .input {
  1706. display: flex;
  1707. align-items: center;
  1708. /* #ifdef MP */
  1709. width: 300rpx;
  1710. /* #endif */
  1711. /* #ifndef MP */
  1712. width: 460rpx;
  1713. /* #endif */
  1714. height: 58rpx;
  1715. padding: 0 0 0 30rpx;
  1716. border: 1px solid rgba(0, 0, 0, 0.07);
  1717. border-radius: 33rpx;
  1718. color: #666;
  1719. font-size: 26rpx;
  1720. position: fixed;
  1721. left: 0;
  1722. right: 0;
  1723. margin: auto;
  1724. background: rgba(255, 255, 255, 0.3);
  1725. .iconfont {
  1726. margin-right: 20rpx;
  1727. font-size: 26rpx;
  1728. color: #666666;
  1729. }
  1730. }
  1731. .container_detail {
  1732. /* #ifdef MP */
  1733. margin-top: 32rpx;
  1734. /* #endif */
  1735. }
  1736. .tab_nav {
  1737. width: 100%;
  1738. height: 48px;
  1739. padding: 0 30rpx 0;
  1740. }
  1741. .right_select {
  1742. width: 58rpx;
  1743. height: 58rpx;
  1744. background: rgba(255, 255, 255, 0.3);
  1745. border: 1px solid rgba(0, 0, 0, 0.1);
  1746. border-radius: 50%;
  1747. position: fixed;
  1748. right: 20rpx;
  1749. text-align: center;
  1750. line-height: 58rpx;
  1751. }
  1752. .dialog_nav {
  1753. position: absolute;
  1754. /* #ifdef MP */
  1755. left: 14rpx;
  1756. /* #endif */
  1757. /* #ifdef H5 || APP-PLUS*/
  1758. right: 14rpx;
  1759. /* #endif */
  1760. width: 240rpx;
  1761. background: #FFFFFF;
  1762. box-shadow: 0px 0px 16rpx rgba(0, 0, 0, 0.08);
  1763. z-index: 310;
  1764. border-radius: 14rpx;
  1765. &::before {
  1766. content: '';
  1767. width: 0;
  1768. height: 0;
  1769. position: absolute;
  1770. /* #ifdef MP */
  1771. left: 0;
  1772. right: 0;
  1773. margin: auto;
  1774. /* #endif */
  1775. /* #ifdef H5 || APP-PLUS */
  1776. right: 8px;
  1777. /* #endif */
  1778. top: -9px;
  1779. border-bottom: 10px solid #F5F5F5;
  1780. border-left: 10px solid transparent;
  1781. /*transparent 表示透明*/
  1782. border-right: 10px solid transparent;
  1783. }
  1784. }
  1785. .dialog_nav_item {
  1786. width: 100%;
  1787. height: 84rpx;
  1788. line-height: 84rpx;
  1789. padding: 0 20rpx 0;
  1790. box-sizing: border-box;
  1791. border-bottom: #eee;
  1792. font-size: 28rpx;
  1793. color: #333;
  1794. position: relative;
  1795. .iconfont {
  1796. font-size: 32rpx;
  1797. }
  1798. }
  1799. .dialog_after {
  1800. ::after {
  1801. content: '';
  1802. position: absolute;
  1803. width: 172rpx;
  1804. height: 1px;
  1805. background-color: #EEEEEE;
  1806. bottom: 0;
  1807. right: 0;
  1808. }
  1809. }
  1810. .pl-20 {
  1811. padding-left: 20rpx;
  1812. }
  1813. .activity {
  1814. padding: 0 20rpx;
  1815. @include coupons_border_color(theme);
  1816. @include main_color(theme);
  1817. font-size: 24rpx;
  1818. line-height: 34rpx;
  1819. position: relative;
  1820. margin-left: 4rpx;
  1821. }
  1822. .product-con .wrapper .coupon .activity:before {
  1823. content: ' ';
  1824. position: absolute;
  1825. width: 7rpx;
  1826. height: 10rpx;
  1827. border-radius: 0 7rpx 7rpx 0;
  1828. @include coupons_border_color(theme);
  1829. background-color: #fff !important;
  1830. bottom: 50%;
  1831. left: -3rpx;
  1832. margin-bottom: -6rpx;
  1833. // border-left-color: #fff ;
  1834. @include white_left_border;
  1835. }
  1836. .product-con .wrapper .coupon .activity:after {
  1837. content: ' ';
  1838. position: absolute;
  1839. width: 7rpx;
  1840. height: 10rpx;
  1841. border-radius: 7rpx 0 0 7rpx;
  1842. @include coupons_border_color(theme);
  1843. background-color: #fff;
  1844. right: -3rpx;
  1845. bottom: 50%;
  1846. margin-bottom: -6rpx;
  1847. // border-right-color: #fff;
  1848. @include white_right_border;
  1849. }
  1850. .justify-center {
  1851. justify-content: center;
  1852. }
  1853. .align-center {
  1854. align-items: center;
  1855. }
  1856. .align-baseline {
  1857. align-items: baseline;
  1858. }
  1859. .bg_color {
  1860. @include main_bg_color(theme);
  1861. }
  1862. .vip_icon {
  1863. width: 44rpx;
  1864. height: 28rpx;
  1865. }
  1866. .pl-2 {
  1867. padding-left: 20rpx;
  1868. }
  1869. .vip_money {
  1870. background: #FFE7B9;
  1871. border-radius: 4px;
  1872. font-size: 22rpx;
  1873. color: #333;
  1874. line-height: 28rpx;
  1875. text-align: center;
  1876. padding: 0 6rpx;
  1877. box-sizing: border-box;
  1878. margin-left: -4rpx;
  1879. }
  1880. .theme_price {
  1881. @include price_color(theme);
  1882. }
  1883. .activityName {
  1884. line-height: 44rpx;
  1885. }
  1886. .userEvaluation {
  1887. i {
  1888. display: inline-block;
  1889. }
  1890. }
  1891. .bntVideo {
  1892. width: auto !important;
  1893. .buy {
  1894. border-radius: 50rpx !important;
  1895. }
  1896. }
  1897. .attribute {
  1898. .line1 {
  1899. width: 600rpx;
  1900. }
  1901. }
  1902. .chat-btn {
  1903. background-color: antiquewhite !important;
  1904. }
  1905. .activity_pin {
  1906. width: auto;
  1907. height: 44rpx;
  1908. line-height: 44rpx;
  1909. // background: linear-gradient(90deg, rgba(233, 51, 35, 1) 0%, rgba(250, 101, 20, 1) 100%);
  1910. @include linear-gradient(theme);
  1911. opacity: 1;
  1912. border-radius: 22rpx;
  1913. padding: 0 15rpx;
  1914. // margin-left: 19rpx;
  1915. }
  1916. .activity_miao {
  1917. width: auto;
  1918. height: 44rpx;
  1919. line-height: 44rpx;
  1920. padding: 0 15rpx;
  1921. // background: linear-gradient(90deg, rgba(250, 102, 24, 1) 0%, rgba(254, 161, 15, 1) 100%);
  1922. @include linear-gradient(theme);
  1923. opacity: 1;
  1924. border-radius: 22rpx;
  1925. margin-left: 19rpx;
  1926. }
  1927. .iconfonts {
  1928. color: #fff !important;
  1929. font-size: 28rpx;
  1930. }
  1931. .activity_title {
  1932. font-size: 24rpx;
  1933. color: #fff;
  1934. }
  1935. .activity_kan {
  1936. width: auto;
  1937. height: 44rpx;
  1938. line-height: 44rpx;
  1939. padding: 0 15rpx;
  1940. @include linear-gradient(theme);
  1941. opacity: 1;
  1942. border-radius: 22rpx;
  1943. margin-left: 19rpx;
  1944. }
  1945. .mask {
  1946. z-index: 300 !important;
  1947. }
  1948. .head-bar {
  1949. background: #fff;
  1950. }
  1951. .generate-posters {
  1952. width: 100%;
  1953. height: 318rpx;
  1954. background-color: #fff;
  1955. position: fixed;
  1956. left: 0;
  1957. bottom: 0;
  1958. z-index: 388;
  1959. transform: translate3d(0, 100%, 0);
  1960. transition: all 0.3s cubic-bezier(0.25, 0.5, 0.5, 0.9);
  1961. border-top: 1rpx solid #eee;
  1962. .generateCon {
  1963. height: 220rpx;
  1964. }
  1965. .generateClose {
  1966. height: 98rpx;
  1967. font-size: 28rpx;
  1968. color: #333333;
  1969. border-top: 1px solid #eee;
  1970. }
  1971. .item {
  1972. .pictrue {
  1973. width: 96rpx;
  1974. height: 96rpx;
  1975. border-radius: 50%;
  1976. margin: 0 auto 6rpx auto;
  1977. image {
  1978. width: 100%;
  1979. height: 100%;
  1980. border-radius: 50%;
  1981. }
  1982. }
  1983. }
  1984. }
  1985. .generate-posters.on {
  1986. transform: translate3d(0, 0, 0);
  1987. }
  1988. .generate-posters .item {
  1989. flex: 1;
  1990. text-align: center;
  1991. font-size: 30rpx;
  1992. }
  1993. .generate-posters .item .iconfont {
  1994. font-size: 80rpx;
  1995. color: #5eae72;
  1996. }
  1997. .generate-posters .item .iconfont.icon-haibao {
  1998. color: #5391f1;
  1999. }
  2000. .generate-posters .item .iconfont.icon-haowuquan1 {
  2001. color: #ff954d;
  2002. }
  2003. .product-con .footer {
  2004. padding: 0 20rpx 0 30rpx;
  2005. position: fixed;
  2006. bottom: 0;
  2007. width: 100%;
  2008. box-sizing: border-box;
  2009. background-color: #fff;
  2010. z-index: 277;
  2011. border-top: 1rpx solid #f0f0f0;
  2012. height: 100rpx;
  2013. height: calc(100rpx+ constant(safe-area-inset-bottom)); ///兼容 IOS<11.2/
  2014. height: calc(100rpx + env(safe-area-inset-bottom)); ///兼容 IOS>11.2/
  2015. }
  2016. .product-con .footer .item {
  2017. font-size: 18rpx;
  2018. color: #666;
  2019. }
  2020. .product-con .footer .item .iconfont {
  2021. text-align: center;
  2022. font-size: 40rpx;
  2023. }
  2024. .product-con .footer .item .iconfont.icon-shoucang1 {
  2025. @include main_color(theme);
  2026. }
  2027. .product-con .footer .item .iconfont.icon-gouwuche1 {
  2028. font-size: 40rpx;
  2029. position: relative;
  2030. }
  2031. .product-con .footer .item .iconfont.icon-gouwuche1 .num {
  2032. color: #fff;
  2033. position: absolute;
  2034. font-size: 18rpx;
  2035. padding: 2rpx 8rpx 3rpx;
  2036. border-radius: 200rpx;
  2037. top: -10rpx;
  2038. right: -10rpx;
  2039. }
  2040. .product-con .footer .bnt {
  2041. width: 444rpx;
  2042. height: 76rpx;
  2043. }
  2044. .product-con .footer .bnt .bnts {
  2045. width: 222rpx;
  2046. text-align: center;
  2047. line-height: 76rpx;
  2048. color: #fff;
  2049. font-size: 28rpx;
  2050. }
  2051. .product-con .footer .bnt .joinCart {
  2052. border-radius: 50rpx 0 0 50rpx;
  2053. @include left_color(theme);
  2054. }
  2055. .product-con .footer .bnt .buy {
  2056. border-radius: 0 50rpx 50rpx 0;
  2057. @include main_bg_color(theme);
  2058. }
  2059. .product-con .store-info {
  2060. margin-top: 20rpx;
  2061. background-color: #fff;
  2062. }
  2063. .product-con .store-info .title {
  2064. padding: 0 30rpx;
  2065. font-size: 28rpx;
  2066. color: #282828;
  2067. height: 80rpx;
  2068. line-height: 80rpx;
  2069. border-bottom: 1px solid #f5f5f5;
  2070. }
  2071. .product-con .store-info .info {
  2072. padding: 0 30rpx;
  2073. height: 126rpx;
  2074. }
  2075. .product-con .store-info .info .picTxt {
  2076. width: 615rpx;
  2077. }
  2078. .product-con .store-info .info .picTxt .pictrue {
  2079. width: 76rpx;
  2080. height: 76rpx;
  2081. }
  2082. .product-con .store-info .info .picTxt .pictrue image {
  2083. width: 100%;
  2084. height: 100%;
  2085. border-radius: 6rpx;
  2086. }
  2087. .product-con .store-info .info .picTxt .text {
  2088. width: 522rpx;
  2089. }
  2090. .product-con .store-info .info .picTxt .text .name {
  2091. font-size: 30rpx;
  2092. color: #282828;
  2093. }
  2094. .product-con .store-info .info .picTxt .text .address {
  2095. font-size: 24rpx;
  2096. color: #666;
  2097. margin-top: 3rpx;
  2098. }
  2099. .product-con .store-info .info .picTxt .text .address .iconfont {
  2100. color: #707070;
  2101. font-size: 18rpx;
  2102. margin-left: 10rpx;
  2103. }
  2104. .product-con .store-info .info .picTxt .text .address .addressTxt {
  2105. max-width: 480rpx;
  2106. }
  2107. .product-con .store-info .info .iconfont {
  2108. font-size: 40rpx;
  2109. }
  2110. .product-con .superior {
  2111. background-color: #fff;
  2112. margin-top: 30rpx;
  2113. padding: 0 24rpx 30rpx 24rpx;
  2114. }
  2115. .product-con .superior .title {
  2116. height: 98rpx;
  2117. }
  2118. .product-con .superior .title image {
  2119. width: 20rpx;
  2120. height: 20rpx;
  2121. }
  2122. .product-con .superior .title .titleTxt {
  2123. margin: 0 10rpx;
  2124. font-size: 30rpx;
  2125. color: #333333;
  2126. }
  2127. .product-con .superior .slider-banner {
  2128. width: 100%;
  2129. margin: 0 auto;
  2130. position: relative;
  2131. }
  2132. .product-con .superior .slider-banner swiper {
  2133. height: 100%;
  2134. width: 100%;
  2135. }
  2136. .product-con .superior .slider-banner swiper-item {
  2137. height: 100%;
  2138. }
  2139. .product-con .superior .slider-banner .list {
  2140. width: 100%;
  2141. }
  2142. .product-con .superior .slider-banner .list .item {
  2143. width: 198rpx;
  2144. margin: 0 22rpx 30rpx 0;
  2145. font-size: 26rpx;
  2146. }
  2147. .product-con .superior .slider-banner .list .item:nth-of-type(3n) {
  2148. margin-right: 0;
  2149. }
  2150. .product-con .superior .slider-banner .list .item .pictrue {
  2151. position: relative;
  2152. width: 100%;
  2153. height: 198rpx;
  2154. }
  2155. .product-con .superior .slider-banner .list .item .pictrue image {
  2156. width: 100%;
  2157. height: 100%;
  2158. border-radius: 6rpx;
  2159. }
  2160. .product-con .superior .slider-banner .list .item .name {
  2161. color: #282828;
  2162. margin-top: 12rpx;
  2163. }
  2164. .product-con .superior .slider-banner .swiper-pagination-bullet {
  2165. background-color: #999;
  2166. }
  2167. .product-con .superior .slider-banner .swiper-pagination-bullet-active {
  2168. background-color: $theme-color;
  2169. }
  2170. button {
  2171. padding: 0;
  2172. margin: 0;
  2173. line-height: normal;
  2174. background-color: #fff;
  2175. }
  2176. button::after {
  2177. border: 0;
  2178. }
  2179. action-sheet-item {
  2180. padding: 0;
  2181. height: 240rpx;
  2182. align-items: center;
  2183. display: flex;
  2184. }
  2185. .contact {
  2186. font-size: 16px;
  2187. width: 50%;
  2188. background-color: #fff;
  2189. padding: 8rpx 0;
  2190. border-radius: 0;
  2191. margin: 0;
  2192. line-height: 2;
  2193. }
  2194. .contact::after {
  2195. border: none;
  2196. }
  2197. .action-sheet {
  2198. font-size: 17px;
  2199. line-height: 1.8;
  2200. width: 50%;
  2201. position: absolute;
  2202. top: 0;
  2203. right: 0;
  2204. padding: 25rpx 0;
  2205. }
  2206. .canvas {
  2207. position: fixed;
  2208. z-index: -5;
  2209. opacity: 0;
  2210. }
  2211. .poster-pop {
  2212. position: fixed;
  2213. width: 450rpx;
  2214. height: 714rpx;
  2215. top: 50%;
  2216. left: 50%;
  2217. transform: translateX(-50%);
  2218. margin-top: -432rpx;
  2219. z-index: 399;
  2220. }
  2221. .poster-pop image {
  2222. width: 100%;
  2223. height: 100%;
  2224. display: block;
  2225. }
  2226. .poster-pop .close {
  2227. width: 46rpx;
  2228. height: 75rpx;
  2229. position: fixed;
  2230. right: 0;
  2231. top: -73rpx;
  2232. display: block;
  2233. }
  2234. .poster-pop .save-poster {
  2235. background-color: #df2d0a;
  2236. font-size: 22rpx;
  2237. color: #fff;
  2238. text-align: center;
  2239. height: 76rpx;
  2240. line-height: 76rpx;
  2241. width: 100%;
  2242. }
  2243. .poster-pop .keep {
  2244. color: #fff;
  2245. text-align: center;
  2246. font-size: 25rpx;
  2247. margin-top: 10rpx;
  2248. }
  2249. .mask {
  2250. position: fixed;
  2251. top: 0;
  2252. left: 0;
  2253. right: 0;
  2254. bottom: 0;
  2255. background-color: rgba(0, 0, 0, 0.6);
  2256. }
  2257. .pro-wrapper .iconn {
  2258. background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHgAAAB4CAYAAAA5ZDbSAAAYKElEQVR4nO2deXhTVfrHP0nTlpautHSjZSkt+x42UTYVF5C4gsKIOqOjIxJHZdTfyG+eEZ1xxgVHjeLo6KiIKKsYcAUEBQooASxQKC1QulPolm50S+aPJPXmZm2a3BTo53n6QM49956T+8259yzv+x7ZmC8WcbGjU2migBFAGpAK9AGSgBjzX3dAAYSbT6kBWoA6oNz8VwycAU4BuUCmUquuku5beIZOpXF6XCFRPbyGTqUJAsYCVwCTgTFASjsvYxE6Gkh2UlYBcADYCewB9iu16qb21tmfXBQC61SaeGA2cANwHb8K5GtSzH83mz/X6lSarcCXwCalVn1Wonp4TKcVWKfSRAJzgLuAaUCAXytkIgy4xfzXqlNpfgA+A9Yotepqv9bMAbLO9g7WqTTjgYcxidvdnXNaDK3k1Z4lt6aEorrzFDdUUFpfQXljDfrmehpaGmkxtlLf0ghAqCIYhSyAEEUw4YEhxAZHkBDag6SQHvTqHktaeCJ9w+JRyN3+TdUBa4F3lFr13vZ/a89x9Q7uFALrVBo5plaxGJjkKn9lUy37zmVzqPwkmZWnOVlTQouh1at1UsgD6B+eyIjofozqkcqEuEFEB4W5c2oGsAzYqNSqDV6tlB06tcA6lUYG3Ao8Cwx3lveEvojvS34h42wWx6rzMRiNUlSxDblMxuDI3kyKH8LViSMZENHL1SmHMX2vz5Vatc8q22kF1qk004BXAKWjPGUXqtDm7+Xrwv3k1Xau/kzfsHhuTB6LqvdE4rpFOcuqA/6k1Kp3+KIenU5gnUqTDLwEzHOUZ9+5bD47vYNdZ7MwGH3+lOsQcpmcq+KHcFe/aUzoOdBZ1s+Ap5RadYE3y+80ApvfswuBF7AzzDEYjWwpPsBHuVvJri6UpE7eZmBkMvemXcuMpDHIZTJ7WWqAZ4Dl3no/dwqBdSpNX2AlcKW94ztKM3n7+Jfk6ot9XhcpSItI4uFBs5iWMMJRlt3AAqVWfbqjZfldYJ1KczfwFhAhPpZdXciyoxvQnc/xaR38hTI2ncVDb2NgpN3JMj3wiFKrXtmRMvwmsE6lCQbeBB4QH6tvaWT58c2sPv2D5L1hqZHLZMztN4VHBs0mVBFsL8t7wCKlVt3oyfVdCSz35KJuFJqMaf7WRty9544zd/sLfHpqxyUvLpj6Fp+d+oG5219g77nj9rI8AOw03zOv43WBdSrNKGAfME6Y3mRo4dWjG1i0ZzklDRXeLrbTU9JQwaI9y1l2ZANNhhbx4XHAPvO98ypeFVin0lyPqeUmCdOL6su5b+cyPjm5HSOXfqt1hBEjq05t576dyyiqLxcfTsLUkq/3ZpleE1in0twKaDFNyLeRUZbFgh9fvmiHPr4gu7qQBT++zJ6yY+JDYYBWp9Lc5q2yvCKwTqWZj2myPUiYvjZvJ3/c9w7VTXXeKOaSorqpjkf3/Zt1eTvFh4KANeZ72mE6LLD517YCwXKeESOvZ23kn5lrOv1MlD8xGA38I3MNrx3dKH51BQArdCrN7R0to0MC61SaG4FPEYhrMBp4/tAqVuRu62jdLhs+PrmN5w6tEjeGAGCV+R57jMcC61Sa4cBqBI9lg9HA0kOf8EW+pEuilwTa/L0sPfSJWGTL49rpSpszPBLYPGb7CsGcshEjL2SuZnPBT57W5bJnc8FPvJC5Wvy4DgO+8nSc3G6BzUZvGxAZq715bBOfn8nwpA5dCPj8TAZvHtskTk4GNphnB9uFJy14OaJJjHV5O/kwZ4sHl+rCHh/mbLHXux6HaU6/XbRLYPPCwf3CtIyyLF48vK695XbhghcPryOjLEucfL9ZA7dxW2Dzkp/VL6iovpwlBz7qGgr5AIPRwJIDH9mb8XpLp9L0c/c6bglsXqxfiWDJr8nQwpM/v4e+qd7dsrpoJ/qmep78+T3x3HUE8LFZE5e424IXIlqsf/OYtmv6UQKyqwvRZGnFyVdi0sQlLgXWqTQpmMxs2th37jirTu5ws4pddJRPT+1gn+1S4wtmbZziTgtehmC8W9/SyPOHPr2sV4WkxoiR5w6tajPcNxOOSRunOBVYp9JMBu4Qpr11bNNluZ7rb0obKnnLdnw8B5MDnkMcCmw2Sv8X0GYemF1dyBrb8VkXErEmb6e9fo+VRmKcteBbERmlLzu6oWtI5EcMRgPLjqwXJysxaWUXuwKbu+DPCtO2l/xyyVo/XkzoynPZUZopTl6KAy0dteDZCHyFDEYjy49v9koFu+g4bx//UmywOAyTZjY4EvhJ4Yfvig9wqqbUO7XrosPk6ovZUnxAnPykvbw2DuA6lWYiokmNFblbvVY5byGXyUkLTyQ1IpHk0BiigsIIVXQjQCajtvkC+uZ6ShsqOFVTygl9EY2tzf6uslf5KHcr1/ey6iJdCUwErBbj7Xn4Pyj88NP57E4zYxUWGMK1SaOZnjACZWw6IQFBrk8CWo0GMitOs6vsKN8W6i6JYV52dSH7zmWLHd4eRCSwlWeDOWxCEQLP+sf2vcPOs0d8W1sX9AqN5XfpM7gheSzd3BTVGRllWaw8+T37zmV7oXb+Y3L8MF6b8JAwqQ7oBbSFkxC34DsRiHu2ocrekpVkhCqCWTjoJub0ndyecAoumRQ3hElxQ9h/PodXjqwnR1/ktWtLye6yLM42VBEf0uaf3B2Thu9aEsSdrDuFHzYV7KPVT+Pe0TH9WTf9/5mXOs2r4goZG5vOJ1Of4g8DZyKX+cSLx6cYjAY2FewTJ1tp2PatdCpNAjBVePDrwp99Vjln3NF3Mu9MelT4y/QZATI5vx94I8uveITwwBCfl+dtviq0sYGbCiRYPgh/trMRmL/m6Iv8EjbhvvQZ/HnEXAIkblHjYgfw/lWP0yNYqhBc3uFMbRknrF8xAcBNlg/CuzhTmGtr8SHf1swOt/SZhHqwSvJyLfQPT+TtKxYRdpG15G22Ws2y/EcOoFNpAoGrhTmk7jkPjerDMyPudJ3Rx6RFJPHc6AXIHM/fdzp2nT0qTroaCIRfe9FjEZjjlDfqOVEtXc8yUB7A35T3unwsH6nM4+OT31NYd570iCQeH3orkUGuY6Wdu1DN+ye+Jas6n6jA7jwyeLYjr3sApiYM5/a+V9mzbOyUZFcXUtFYI3y9RGCywsywCGw1c7X/fI6kC/rzUqfRu3tPp3mOVRXwwO7XaDYHPDteXUBNcwPLxv/e6XkXWpv43a5XKa7/dXLjWHUBX85YSpA80OF5fxxyM1uLD1LVVOv+F/ETRoz8fP6EeGZrEpAhF3xo45eKU1LVjSB5IPemXesy35biA23iWjhQkevyvMzK01biAlQ01nBS73xuPVQRzIK0q53m6UwcstVsEvzaybKS/peKDgd/cZvreo0myo0QganhCTZpLgKQAZDSvafNo18uk9GzW6TLc2/vc5XTVt6ZyLTVTAkg16k00UBvS6rBaJR05Wh64ki38s1KGc+81GltYnVXdOOJoa79pBNDerB09AIiAkMBk7gPDZxFbDeboD82hAeGcGX8ELfq529ya4rF8Tp7A9EKRDEiSxoqaDJIs/IiQ8b4WKfR4azy/mnY7Tw48EZKGypJDo11FLXGhhuTx3JN0ijya8uIDg4jJti+uAajgZIGU5TaZkMrClmAy75BZ8EScTctwip6xnAFkC5MkXJyIyk0xm2RLEQEhra1xvYQJFeIvzxg6rxtKT7A/vIcsqsLaTG0Eh0URs9ukYQogjAYjfQPT+TshSpqmxvaXa6U5NaUiL/jIAXQV5iSX1smWYUSQ6MlK0uIESPfFOr4KHcrOfoiBkT0YnriSB4dfDNDono7/NGVN+rJrDjN3nPH2VGayfkLeolr7pxiWzeXVAWmTSzayJNQ4DCF9DNGx6sLeP7Qp+Toi7gxeRxLR9/tdEwsJCY4gumJI5meOJKnh8/hh9LDfJS7lcOVeb6ttJsU1Z0XJ/VWAPFWmeptMvmMZqN3g3i74pOT23nj2BeM7tGftdOX0CcszuNryWXyNrG3lRzi
  2259. width: 100rpx;
  2260. height: 100rpx;
  2261. background-repeat: no-repeat;
  2262. background-size: 100% 100%;
  2263. margin: 0 auto;
  2264. }
  2265. .pro-wrapper .iconn.iconn1 {
  2266. background-image: url('data:image/png;base64,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
  2267. }
  2268. .pictrue_log {
  2269. width: 80upx;
  2270. height: 40upx;
  2271. border-radius: 10upx 0 12upx 0;
  2272. line-height: 40upx;
  2273. font-size: 24upx;
  2274. }
  2275. .pictrue_log_class {
  2276. z-index: 3;
  2277. background: -webkit-gradient(linear, left top, right top, from(rgba(246, 122, 56, 1)), to(rgba(241, 27, 9, 1)));
  2278. background: linear-gradient(90deg, rgba(246, 122, 56, 1) 0%, rgba(241, 27, 9, 1) 100%);
  2279. opacity: 1;
  2280. position: absolute;
  2281. top: 0;
  2282. left: 0;
  2283. color: #fff;
  2284. text-align: center;
  2285. }
  2286. .tab_nav .header {
  2287. width: 100%;
  2288. height: 96rpx;
  2289. padding: 20rpx 80rpx 0;
  2290. font-size: 30rpx;
  2291. color: #050505;
  2292. background-color: #fff;
  2293. }
  2294. .icon-xiangzuo {
  2295. /* #ifdef H5 */
  2296. top: 20rpx !important;
  2297. /* #endif */
  2298. }
  2299. .navbar .header .item {
  2300. position: relative;
  2301. margin: 0 25rpx;
  2302. }
  2303. .navbar .header .item.on:before {
  2304. position: absolute;
  2305. width: 60rpx;
  2306. height: 5rpx;
  2307. background-repeat: no-repeat;
  2308. content: "";
  2309. @include linear-gradient(theme);
  2310. bottom: -10rpx;
  2311. left: 50%;
  2312. margin-left: -28rpx;
  2313. }
  2314. .navbar {
  2315. position: fixed;
  2316. // background-color: #fff;
  2317. top: 0;
  2318. left: 0;
  2319. z-index: 99;
  2320. width: 100%;
  2321. }
  2322. .navbar .navbarH {
  2323. position: relative;
  2324. }
  2325. .navbar .navbarH .navbarCon {
  2326. position: absolute;
  2327. bottom: 0;
  2328. height: 100rpx;
  2329. width: 100%;
  2330. }
  2331. .h5_back {
  2332. color: #000;
  2333. position: fixed;
  2334. left: 20rpx;
  2335. font-size: 32rpx;
  2336. text-align: center;
  2337. width: 58rpx;
  2338. height: 58rpx;
  2339. background: rgba(255, 255, 255, 0.3);
  2340. border: 1px solid rgba(0, 0, 0, 0.1);
  2341. border-radius: 50%;
  2342. }
  2343. .share-box {
  2344. z-index: 1000;
  2345. position: fixed;
  2346. left: 0;
  2347. top: 0;
  2348. width: 100%;
  2349. height: 100%;
  2350. image {
  2351. width: 100%;
  2352. height: 100%;
  2353. }
  2354. }
  2355. .mask_transparent {
  2356. position: fixed;
  2357. top: 0;
  2358. left: 0;
  2359. right: 0;
  2360. bottom: 0;
  2361. background: transparent;
  2362. z-index: 300;
  2363. }
  2364. .px-12 {
  2365. padding-left: 12rpx;
  2366. padding-right: 12rpx;
  2367. }
  2368. .font-44 {
  2369. font-size: 44rpx;
  2370. }
  2371. .font_color {
  2372. @include main_color(theme);
  2373. }
  2374. .attrImg {
  2375. width: 66rpx;
  2376. height: 66rpx;
  2377. border-radius: 6rpx;
  2378. display: block;
  2379. margin-right: 14rpx;
  2380. }
  2381. .switchTxt {
  2382. height: 60rpx;
  2383. flex: 1;
  2384. line-height: 60rpx;
  2385. box-sizing: border-box;
  2386. background: #EEEEEE;
  2387. padding-right: 0 24rpx 0;
  2388. border-radius: 8rpx;
  2389. text-align: center;
  2390. }
  2391. .share-icon-box{
  2392. position: relative;
  2393. .share-icon{
  2394. position: absolute;
  2395. right: -15rpx;
  2396. top: 20rpx;
  2397. }
  2398. }
  2399. .share-introduce{
  2400. padding-right: 16rpx;
  2401. }
  2402. </style>