product.vue 32 KB

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