| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555 |
- <template>
- <div class="detail">
- <!-- 面包屑导航 -->
- <div class="crumbs-shop">
- <div class="content">
- <div class="crumbs"></div>
- <div class="shop-box">
- <nuxt-link :to="'/shopIndex?sid=' + prodInfo.shopId" class="shop">
- <i class="self" v-if="shopInfo && shopInfo.shopId === 1">{{$t('prodDetail.selfEmployed')}}</i>
- <i class="shop-icon" v-if="shopInfo && shopInfo.shopId != 1"></i>
- {{ shopInfo ? shopInfo.shopName : '' }}
- </nuxt-link>
- <a href="javascript:void(0)" @click="toChatIm(shopInfo)" class="im-chat"><span class="btn-im"></span>{{$t('prodDetail.contactCustomerService')}}</a>
- <span
- class="favourite"
- v-if="!isShopCollection"
- @click="toggleShopCollect"
- >
- <i class="favourite-icon"></i>{{$t('prodDetail.collectionStores')}}
- </span>
- <span class="favourite active" @click="toggleShopCollect" v-else>
- <i class="favourite-icon"></i>{{$t('prodDetail.collectedStores')}}
- </span>
- </div>
- </div>
- </div>
- <!-- /面包屑导航 -->
- <div class="content">
- <div class="detail-up">
- <!-- 商品图片 -->
- <div class="img">
- <div class="big-img">
- <img v-if="(!prodInfo.video || !showVideo) && prodInfo.pic" :src="prodInfo.pic" alt />
- <img v-if="(!prodInfo.video || !showVideo) && !prodInfo.pic" src="~/assets/img/def.png" alt />
- <!-- 商品视频 -->
- <video
- v-show="showVideo"
- id="prodVideo"
- class="big-img prod-video"
- :src="prodInfo.video"
- controls
- ></video>
- <!-- 商品视频end -->
- <div class="oper-btn" v-if="showPlayBtn && prodInfo.video">
- <img
- src="~/assets/images/play.png"
- @click="playVideo"
- alt="播放"
- />
- </div>
- <div class="close-btn" v-if="!showPlayBtn && showVideo">
- <img
- src="~/assets/images/close.png"
- alt="关闭"
- @click="stopVideo"
- />
- </div>
- </div>
- <div class="small-img">
- <i
- class="left-arrow"
- @click="prevImg"
- :class="{
- limit: prodImgs.length - 5 <= 0 || this.offsetCount < 1
- }"
- ><</i
- >
- <i
- class="right-arrow"
- @click="nextImg"
- :class="{
- limit:
- prodImgs.length - 5 <= 0 ||
- this.offsetCount >= prodImgs.length - 5
- }"
- >></i
- >
- <div class="img-box">
- <div class="offset-box" ref="carouser">
- <div
- class="item"
- v-for="(item, index) in prodImgs"
- :key="index"
- :class="{ active: item.isActive }"
- @mouseover="changeProdImg(index)"
- >
- <img :src="item.img" />
- </div>
- </div>
- </div>
- </div>
- </div>
- <!-- /商品图片 -->
- <!-- 商品详情 -->
- <div class="info" v-if="prodInfo">
- <div class="name-box">
- <div class="name">{{ prodInfo.prodName }}</div>
- <div class="des">
- <div :title="prodInfo.brief" class="brief">
- {{ prodInfo.brief }}
- </div>
- </div>
- </div>
- <!-- 拼团和秒杀商品 -->
- <div class="activity">
- <div class="name flash-sale">
- {{
- prodInfo.seckill.seckillName
- ? prodInfo.seckill.seckillName
- : $t('spike.secondsOfActivity')
- }}
- </div>
- <div class="limit" v-if="countdown.obj.signs != -1">
- {{$t('prodDetail.distanceActivity')}} <span>{{ countdown.obj.signs ? $t('end') : $t('start') }}</span
- > {{$t('onlyLeft')}}:
- <span class="time" v-if="countdown && countdown.obj.day">{{
- countdown.obj.day +
- $t('day1') +
- countdown.obj.hou +
- $t('time1') +
- countdown.obj.min +
- $t('minutes') +
- countdown.obj.sec +
- $t('seconds')
- }}</span>
- <span class="time" v-else>{{
- countdown.obj.day +
- ':' +
- countdown.obj.hou +
- ':' +
- countdown.obj.min +
- ':' +
- countdown.obj.sec
- }}</span>
- </div>
- <div class="limit" v-else>{{$t('spike.secondsOfActivity')}}</div>
- </div>
- <div class="price-box">
- <div class="item goods-price">
- <span class="tit">{{$t('price')}}</span>
- <div class="con">
- <div class="price">
- ¥
- <span class="big">{{
- parsePrice(defaultSku.seckillPrice)[0]
- }}</span>
- .{{ parsePrice(defaultSku.seckillPrice)[1] }}
- </div>
- <div class="old-price" v-if="defaultSku.price">
- ¥{{ defaultSku.price.toFixed(2) }}
- </div>
- </div>
- <span v-if="findSku" class="tit">{{$t('prodDetail.remainingInventory')}}</span>
- <div v-if="findSku" class="con">
- {{defaultSku.seckillStocks}}
- </div>
- </div>
- <!-- 说明(虚拟商品) -->
- <div
- v-if="prodInfo.mold === 1 && (prodInfo.writeOffNum !== 0 || (prodInfo.writeOffNum === 0 && prodInfo.isRefund === 0))"
- class="item goods-price">
- <span class="tit">{{$t('prodDetail.instructions')}}</span>
- <div class="con">
- <!-- writeOffNum 0无需核销 1单次核销 -1多次核销 -->
- <span v-if="prodInfo.writeOffNum !== 0">
- <!-- writeOffTime核销有效期 -1.长期有效 0.自定义 1.当天24点前 x.x天内有效 -->
- <span v-if="prodInfo.writeOffTime === -1">{{$t('prodDetail.longTermValidity')}}</span>
- <span v-else-if="prodInfo.writeOffTime === 0">{{$t('prodDetail.afterPurchase')}} {{prodInfo.writeOffStart}} {{$t('prodDetail.to')}} {{prodInfo.writeOffEnd}} <i v-if="$t('language')=='zh'">{{$t('prodDetail.effective')}}</i></span>
- <span v-else-if="prodInfo.writeOffTime === 1">{{$t('prodDetail.validOnTheSameDay')}}</span>
- <span v-else>{{$t('prodDetail.purchase')}}{{prodInfo.writeOffTime}}{{$t('prodDetail.validDay')}}</span>
- </span>
- <!-- isRefund 0不支持退款 1支持退款 -->
- <span v-if="prodInfo.isRefund === 0"><span v-if="prodInfo.writeOffNum !== 0">,</span>{{$t('prodDetail.refundsAreNotAllowed')}}</span>
- </div>
- </div>
- </div>
- <div class="sku-box" v-if="prodInfo.skuList.length">
- <div
- class="items sku-text"
- v-for="(skuLine, key) in skuGroup"
- :key="key"
- >
- <span class="tit">{{ key }}</span>
- <div class="con">
- <span
- class="item"
- @click="toChooseItem(skuLineItem, key, $event)"
- :class="[
- selectedProp.find(el => el.key === key && el.value === skuLineItem) ? 'active' : '',
- isSkuLineItemNotOptional(
- allProperties,
- selectedPropObj,
- key,
- skuLineItem,
- propKeys
- )
- ? 'not-optional'
- : ''
- ]"
- v-for="skuLineItem in skuLine"
- :key="skuLineItem"
- >{{ skuLineItem }}</span
- >
- </div>
- </div>
- </div>
- <!-- 计数器 -->
- <div class="sku-box">
- <div class="items">
- <span class="tit">{{$t('quantity')}}</span>
- <div class="con">
- <div class="goods-number" onselectstart="return false">
- <span
- :class="['reduce', this.prohibit1 ? 'limit' : '']"
- @click="reduce"
- >-</span
- >
- <input
- type="number"
- class="number"
- v-model="prodNum"
- oninput="value=value.replace(/[^\d]/g,'')"
- @blur="resetProdNum"
- />
- <span
- :class="['increase', this.prohibit2 ? 'limit' : '']"
- @click="increase"
- >+</span
- >
- </div>
- </div>
- </div>
- </div>
- <div class="btns">
- <a
- href="javascript:void(0)"
- class="buy-now"
- :class="[countdown.obj.signs?'':'disabled-gray']"
- @click="buyNow"
- v-if="findSku && defaultSku.seckillStocks && countdown.obj.signs == 1"
- >{{$t('prodDetail.grabYourCopyNow')}}</a
- >
- <a
- href="javascript:void(0)"
- class="shortage"
- v-else-if="findSku && defaultSku.seckillStocks && countdown.obj.signs == 0"
- >{{$t('prodDetail.eventNotStarted')}}</a
- >
- <a
- href="javascript:void(0)"
- class="shortage"
- v-else-if="findSku && defaultSku.seckillStocks && countdown.obj.signs == -1"
- >{{$t('prodDetail.theEventHasEnded')}}</a
- >
- <a href="javascript:void(0)" class="shortage" v-else-if="!findSku"
- >{{$t('prodDetail.productNotInStock')}}</a
- >
- <a
- href="javascript:void(0)"
- class="shortage"
- v-else-if="!defaultSku.seckillStocks"
- >{{$t('prodDetail.productOutOfStock')}}</a
- >
- <a
- href="javascript:void(0)"
- class="collect"
- v-if="!isCollection"
- @click="toggleCollect()"
- >
- <i class="icon"></i>{{$t('prodDetail.collectionOfProducts')}}
- </a>
- <a
- href="javascript:void(0)"
- class="collected"
- v-if="isCollection"
- @click="toggleCollect()"
- >
- <i class="icon"></i>{{$t('prodDetail.bookmarked')}}
- </a>
- </div>
- </div>
- <!-- 商品详情 -->
- </div>
- <div class="detail-down">
- <div class="introduce-box">
- <div class="tab">
- <div
- :class="['item', introduceOrCommentInt ? 'active' : '']"
- @click="toggleIntroduceInt"
- >
- {{$t('prodDetail.productIntroduction')}}
- </div>
- <div
- :class="['item', introduceOrCommentCom ? 'active' : '']"
- @click="toggleIntroduceCom"
- >
- {{$t('prodDetail.productReviews')}}
- <i class="number">({{ prodCommData.number }})</i>
- </div>
- </div>
- <!-- 商品介绍 -->
- <div class="introduce" v-show="introduceOrCommentInt">
- <div>
- <div class="params" v-for="(params, index) in prodParameterList" :key="index">
- <div
- class="params-box"
- v-for="item in params"
- :key="item.prodParameterId"
- >
- <div class="key">{{ item.parameterKey }}</div>
- <div :title="item.parameterValue" class="value">{{ item.parameterValue }}</div>
- </div>
- </div>
- </div>
- <div v-rich="prodInfo.content" v-if="prodInfo.content"></div>
- </div>
- <!-- /商品介绍 -->
- <!-- 商品评论 -->
- <div class="comment" v-if="introduceOrCommentCom">
- <!-- 好评率 -->
- <div class="good-rates">
- <div class="score">
- <div class="tit">{{$t('prodDetail.favorableRatingRate')}}:</div>
- <div class="con">{{ prodCommData.positiveRating }}%</div>
- </div>
- <div class="average">
- <div class="item">
- <div class="text">5.0</div>
- <div class="stars">
- <i class="star"></i>
- <i class="star"></i>
- <i class="star"></i>
- <i class="star"></i>
- <i class="star"></i>
- </div>
- <div class="number">({{ prodCommData.scoreNumber5 }})</div>
- </div>
- <div class="item">
- <div class="text">4.0</div>
- <div class="stars">
- <i class="star"></i>
- <i class="star"></i>
- <i class="star"></i>
- <i class="star"></i>
- <i class="star-gray"></i>
- </div>
- <div class="number">({{ prodCommData.scoreNumber4 }})</div>
- </div>
- <div class="item">
- <div class="text">3.0</div>
- <div class="stars">
- <i class="star"></i>
- <i class="star"></i>
- <i class="star"></i>
- <i class="star-gray"></i>
- <i class="star-gray"></i>
- </div>
- <div class="number">({{ prodCommData.scoreNumber3 }})</div>
- </div>
- <div class="item">
- <div class="text">2.0</div>
- <div class="stars">
- <i class="star"></i>
- <i class="star"></i>
- <i class="star-gray"></i>
- <i class="star-gray"></i>
- <i class="star-gray"></i>
- </div>
- <div class="number">({{ prodCommData.scoreNumber2 }})</div>
- </div>
- <div class="item">
- <div class="text">1.0</div>
- <div class="stars">
- <i class="star"></i>
- <i class="star-gray"></i>
- <i class="star-gray"></i>
- <i class="star-gray"></i>
- <i class="star-gray"></i>
- </div>
- <div class="number">({{ prodCommData.scoreNumber1 }})</div>
- </div>
- </div>
- </div>
- <!-- /好评率 -->
- <!-- 评论列表 -->
- <div class="comment-tab">
- <div
- class="item"
- :class="evaluate === -1 ? 'active' : ''"
- @click="getProdCommPageByProd(-1)"
- >
- {{$t('all')}}
- <span class="number">({{ prodCommData.number }})</span>
- </div>
- <div
- class="item"
- :class="evaluate === 0 ? 'active' : ''"
- @click="getProdCommPageByProd(0)"
- >
- {{$t('prodDetail.goodReview')}}
- <span class="number">({{ prodCommData.praiseNumber }})</span>
- </div>
- <div
- class="item"
- :class="evaluate === 1 ? 'active' : ''"
- @click="getProdCommPageByProd(1)"
- >
- {{$t('prodDetail.mediumRating')}}
- <span class="number"
- >({{ prodCommData.secondaryNumber }})</span
- >
- </div>
- <div
- class="item"
- :class="evaluate === 2 ? 'active' : ''"
- @click="getProdCommPageByProd(2)"
- >
- {{$t('prodDetail.poorReviews')}}
- <span class="number"
- >({{ prodCommData.negativeNumber }})</span
- >
- </div>
- <div
- class="item"
- :class="evaluate === 3 ? 'active' : ''"
- @click="getProdCommPageByProd(3)"
- >
- {{$t('prodDetail.withPictures')}}
- <span class="number">({{ prodCommData.picNumber }})</span>
- </div>
- </div>
- <div class="comment-con" v-if="prodCommList.records.length">
- <div
- class="item"
- v-for="(item, comIndex) in prodCommList.records"
- :key="item.prodCommId"
- >
- <div class="buyer-msg">
- <div class="img">
- <img :src="item.pic" alt v-if="item.pic" />
- <img src="~/assets/images/buyer-img.png" alt v-else />
- </div>
- <div class="name">
- {{ item.nickName ? item.nickName : $t('prodDetail.anonymousUser') }}
- </div>
- </div>
- <div class="buyer-comment">
- <div class="stars">
- <i
- class="star"
- v-for="index in item.score"
- :key="index"
- ></i>
- </div>
- <div class="text">{{ item.content }}</div>
- <div class="img-box" v-if="item.pics && item.prodImgs">
- <span
- class="img"
- v-for="(img, imgIndex) in item.prodImgs"
- @click="imgShow(comIndex, imgIndex)"
- :key="imgIndex"
- >
- <img :src="img" @click="imgShow(comIndex, imgIndex)" />
- </span>
- </div>
- <div class="big-img-show" v-if="showBigImg">
- <div class="mask" @click="closeShowBigImg"></div>
- <img :src="imgPath" />
- </div>
- <div class="time-sku">
- <span class="time">{{ item.recTime }}</span>
- </div>
- <div class="seller-reply" v-if="item.replyContent">
- <div class="tit">{{$t('prodDetail.merchantResponse')}}:</div>
- <div class="con">{{ item.replyContent }}</div>
- <div class="time">{{ item.replyTime }}</div>
- </div>
- </div>
- </div>
- </div>
- <div class="comment-con" v-if="!prodCommList.records.length">
- <div class="comment-empty">{{$t('prodDetail.noComments')}}</div>
- </div>
- <!-- /评论列表 -->
- <!-- 页码 -->
- <div class="pagination">
- <div class="pages" v-if="page.pages >= 1">
- <a
- href="javascript:void(0);"
- class="item prev"
- :class="{ default: page.current <= 1 }"
- @click="getSearchProdPage(page.current - 1)"
- >{{$t('pagination.previousPage')}}</a
- >
- <div v-for="item in page.rainbow" :key="item.prodId">
- <a
- href="javascript:void(0);"
- @click="getSearchProdPage(item)"
- class="item"
- :class="{ cur: page.current == item }"
- v-if="item !== '...'"
- >{{ item }}</a
- >
- <span class="ellipsis" v-else>...</span>
- </div>
- <a
- href="javascript:void(0);"
- class="item next"
- :class="{ default: page.current > page.pages - 1 }"
- @click="getSearchProdPage(page.current + 1)"
- >{{$t('pagination.nextPage')}}</a
- >
- <div class="total-num">
- {{$t('pagination.total')}}
- <span class="num">{{ page.pages }}</span
- >{{$t('pagination.page')}}
- </div>
- </div>
- <!-- /页码 -->
- </div>
- </div>
- <!-- /商品评论 -->
- </div>
- <div class="side">
- <!-- 店内搜索 -->
- <div class="shop-search">
- <div class="tit">{{$t('prodDetail.inStoreSearch')}}</div>
- <div class="con">
- <input type="text" class="text" v-model="prodName" />
- <a href="javascript:void(0)" class="btn" @click="toShopIndex"></a>
- </div>
- </div>
- <!-- /店内搜索 -->
- <!-- 店内分类 -->
- <div class="shop-category">
- <div class="tit">{{$t('prodDetail.inStoreCategories')}}</div>
- <div class="con">
- <div
- class="items active"
- v-for="(item, index) in shopCategorys"
- :key="index"
- >
- <nuxt-link
- :to="
- '/shopIndex?sid=' +
- prodInfo.shopId +
- '&cid=' +
- item.categoryId
- "
- >
- <div class="item-main">{{ item.categoryName }}</div>
- </nuxt-link>
- </div>
- </div>
- </div>
- <!-- 店内分类 -->
- <!-- 热销产品 -->
- <div class="sale-well">
- <div class="tit">{{$t('prodDetail.hotProducts')}}</div>
- <div class="con">
- <div
- class="item"
- v-for="item in hotSales.records"
- :key="item.prodId"
- >
- <nuxt-link :to="'/detail/' + item.prodId">
- <div class="goods-img">
- <img v-if="item.pic" :src="item.pic" alt />
- <img v-else src="~/assets/img/def.png" alt />
- </div>
- <div class="goods-msg">
- <div class="goods-name">{{ item.prodName }}</div>
- <div class="goods-price">
- <div class="price">
- ¥
- <span class="big">{{ parsePrice(item.price)[0] }}</span>
- .{{ parsePrice(item.price)[1] }}
- </div>
- </div>
- </div>
- </nuxt-link>
- </div>
- </div>
- </div>
- <!-- 热销产品 -->
- </div>
- </div>
- </div>
- <!-- 滑动导航 -->
- <transition name="fade">
- <div class="scroll-tab" v-if="showScrollTab">
- <div class="content">
- <div class="shop-search">
- <input type="text" class="text" :placeholder="$t('prodDetail.inStoreSearch')" />
- <a href="javascript:void(0)" class="btn"></a>
- </div>
- <div class="tab">
- <div
- :class="['item', introduceOrCommentInt ? 'active' : '']"
- @click="toggleIntroduceInt"
- >
- {{$t('prodDetail.productIntroduction')}}
- </div>
- <div
- :class="['item', introduceOrCommentCom ? 'active' : '']"
- @click="toggleIntroduceCom"
- >
- {{$t('prodDetail.productReviews')}}
- <i class="number">({{ prodCommData.number }})</i>
- </div>
- </div>
- </div>
- </div>
- </transition>
- <!-- /滑动导航 -->
- <el-dialog
- :title="$t('tips')"
- :visible="Boolean(countdown.obj.signs == -1)"
- width="15%"
- center
- :close-on-press-escape="false"
- :close-on-click-modal="false"
- :showClose="false"
- top="25vh"
- >
- <span class="seckill-end-tips">{{$t('spike.currentSecondsAreOver')}}</span>
- <span slot="footer" class="dialog-footer">
- <el-button type="primary" @click="toIndex">{{$t('determine')}}</el-button>
- </span>
- </el-dialog>
- <!-- 登录弹窗组件 -->
- <LoginPopup v-if="showLogin" v-on:hideLoginPop="hideLoginPop" />
- <!-- /登录弹窗组件 -->
- </div>
- </template>
- <script>
- import util from '~/plugins/util'
- import { _toPage } from "~/plugins/util";
- import { picDomain } from '~/plugins/config';
- import LoginPopup from '~/components/login-popup'
- import PageUtil from '~/plugins/pageUtil'
- import Cookie from 'js-cookie'
- import bus from '~/plugins/bus'
- export default {
- components: {
- LoginPopup
- },
- data () {
- return {
- showLogin:false,
- prodName: '',
- prodInfo: {},
- prodImgs: [],
- offsetCount: 0, //图片偏移数
- showScrollTab: false,
- introduceOrCommentInt: true, // true商品介绍 false商品评论
- introduceOrCommentCom: false,
- prodCommData: {},
- prodCommType: true, // 商品评论类型
- prodCommList: {},
- shopInfo: {},
- evaluate: -1,
- hotSales: {},
- defaultSku: {}, // 选中的sku
- skuGroup: [], //
- selectedProp: [],
- findSku: true, // 能不能找得到sku
- prodNum: 1, //计数器数量
- prohibit1: true, //计数器-是否禁用
- prohibit2: false, //计数器+是否禁用
- isCollection: false, //商品是否已收藏
- isShopCollection: false,//店铺是否已收藏
- totalCartNum: 0, //购物车数量
- shopCategorys: [],
- page: {
- pages: 0, // 总页数
- rainbow: [], // 分页条
- current: 1
- },
- timer: {},
- imgPath: '', // 当前点击的评论图片
- showBigImg: false, // 评论大图显隐
- scrollTop: 0,
- toPrePage: 0, // 0不用跳转 1跳转
- prodParameterList: [],
- showVideo: false, // 是否展示视频
- showPlayBtn: true, // 视频播放按钮
- }
- },
- head () {
- return {
- title: this.$t('spike.spikeTitle'),
- }
- },
- //在页面加载之前先加载数据
- async asyncData ({ app, params, redirect }) {
- const data = await app.$axios.get('/seckill/prod', {
- params: {
- seckillId: params.seckillId
- }
- }).then(({ data }) => {
- if (data) {
- return data
- } else {
- return redirect('/error')
- }
- }).catch(()=> {
- return redirect('/error')
- })
- var prodImgs = []
- if (data) {
- if (data.imgs) {
- data.imgs.split(',').forEach(imgStr => {
- prodImgs.push({
- img: imgStr,
- isActive: false
- })
- })
- prodImgs[0].isActive = true
- }
- for (let i = 0; i < data.skuList.length; i++) {
- const element = data.skuList[i];
- element.pic = element.pic ? picDomain + element.pic : ''
- }
- // data.content = util.formatHtml(data.content) // 去除商品详情富文本样式
- // 倒计时处理
- let betweenTimestamp = util.betweenTimestamp(util.dateToTimestamp(data.seckill.startTime), util.dateToTimestamp(data.seckill.endTime))
- var countdown = {
- obj: util.betweenTime(betweenTimestamp),
- stamp: betweenTimestamp
- }
- return {
- prodInfo: data,
- prodImgs: prodImgs,
- shopId: data.shopId,
- countdown: countdown,
- }
- }
- },
- watch: {
- prodNum(nv) {
- if (nv <= 1) {
- this.prohibit1 = true
- if(this.defaultSku.seckillStocks == 0 || nv == this.defaultSku.seckillStocks){
- this.prohibit2 = true
- }
- }else if(nv == this.defaultSku.seckillStocks){
- this.prohibit2 = true
- }else {
- this.prohibit1 = false
- this.prohibit2 = false
- }
- }
- },
- mounted () {
- this.startCountdown()
- //查询商品是否已经收藏
- this.isProdCollected()
- this.isShopCollected()
- //获取店铺分类
- this.getShopCategory()
- this.groupSkuProp(this.prodInfo.skuList, this.prodInfo.seckill.seckillPrice)
- this.getShopHead(this.prodInfo.shopId)
- if (this.prodInfo.video) {
- // 获取商品视频
- this.prodVideo = document.getElementById('prodVideo')
- this.showPlayBtn = true
- }
- //获取热销商品
- this.getHotSales();
- let flag = 0
- this.prodParameterList[flag] = []
- const prodParameterList = this.prodInfo.prodParameterList || []
- for (let i = 0; i < prodParameterList.length; i++) {
- let params = prodParameterList[i]
- if (i % 3 === 0 && i !== 0) {
- flag++
- this.prodParameterList[flag] = []
- }
- this.prodParameterList[flag].push(params)
- }
- // 获取商品评论数
- this.$axios.get('/prod/prodCommData', {
- params: {
- prodId: this.prodInfo.prodId
- }
- }).then(({ data }) => {
- this.prodCommData = data
- })
- this.getProdCommPageByProd(-1);
- // 监听页面滚动
- window.addEventListener('scroll', this.scrollToTop);
- if(Cookie.get('token')) {
- this.$axios.post('/p/prodBrowseLog', {
- prodId: this.prodInfo.prodId
- })
- }
- },
- methods: {
- /**
- * 回到首页
- */
- toIndex () {
- this.$router.push({ path: '/' })
- },
- /**
- * 页面滚动事件
- */
- scrollToTop () {
- var scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;
- this.showScrollTab = scrollTop > 750 ? true : false
- },
- /**
- * 评论点击图片显示大图
- */
- imgShow (comIndex, imgIndex) {
- let imgPath = this.prodCommList.records[comIndex].prodImgs[imgIndex]
- this.imgPath = imgPath
- if (this.imgPath) {
- this.showBigImg = true
- }
- let dom = document.getElementsByTagName("body").className = "hid";
- },
- /**
- * 关闭评论大图显隐
- */
- closeShowBigImg () {
- this.showBigImg = false
- },
- /**
- * 倒计时
- */
- startCountdown () {
- this.countdown = {
- stamp: this.countdown.stamp>0? this.countdown.stamp -= 1000 : this.countdown.stamp += 1000,
- obj: util.betweenTime(this.countdown.stamp)
- }
- if (Math.abs(this.countdown.stamp) < 1000) {
- clearTimeout(this.timer)
- setTimeout(() => {
- this.$router.push({
- path:'/flash-sale'
- })
- }, 1000);
- // if (new Date().getTime() > util.dateToTimestamp(this.prodInfo.seckill.endTime)) {
- // this.$router.push({
- // path:'/flash-sale'
- // })
- // } else {
- // // location.reload()
- // }
- return
- }
- this.timer = setTimeout(() => {
- this.startCountdown()
- }, 1000);
- },
- /**
- * 小图点击事件
- */
- changeProdImg(index) {
- if (this.prodImgs[index].isActive === true) {
- return
- }
- this.prodImgs.forEach(prodImg => {
- prodImg.isActive = false
- })
- this.prodImgs[index].isActive = true
- this.prodInfo.pic = this.prodImgs[index].img
- this.stopVideo()
- },
- /**
- * 关闭视频
- */
- stopVideo() {
- this.showVideo = false
- if (this.prodVideo !== undefined) {
- this.prodVideo.pause()
- }
- this.showPlayBtn = true
- },
- /**
- * 播放视频
- */
- playVideo() {
- this.showVideo = true
- this.prodVideo.play(0)
- this.showPlayBtn = false
- },
- // 切换图片
- prevImg() {
- if (this.prodImgs.length - 5 > 0) {
- if (this.offsetCount > 0) {
- this.offsetCount--
- this.$refs.carouser.style.left = '-' + 78 * this.offsetCount + 'px'
- } else {
- return false
- }
- } else if (this.prodImgs.length - 5 <= 0) {
- return false
- } else {
- return false
- }
- },
- nextImg() {
- if (this.prodImgs.length - 5 > 0) {
- if (this.offsetCount < this.prodImgs.length - 5) {
- this.offsetCount++
- this.$refs.carouser.style.left = '-' + 78 * this.offsetCount + 'px'
- } else if (this.prodImgs.length - 5 <= 0) {
- return false
- } else {
- return false
- }
- } else {
- return false
- }
- },
- /**
- * 获取店铺信息
- */
- getShopHead (shopId) {
- this.$axios.get('/shop/headInfo', {
- params: {
- shopId: shopId
- }
- }).then(({ data }) => {
- this.shopInfo = data
- })
- },
- /**
- * 获取店铺分类
- */
- getShopCategory () {
- this.$axios.get('/category/categoryInfo', {
- params: {
- shopId: this.shopId
- }
- }).then(({ data }) => {
- this.shopCategorys = data
- })
- },
- /**
- * 价格过滤
- */
- parsePrice (value) {
- var val = Number(value)
- if (!val) {
- val = 0;
- }
- // 截取小数点后两位,并以小数点为切割点将val转化为数组
- return val.toFixed(2).split(".");
- },
- /**
- * 切换商品介绍/商品评论
- */
- toggleIntroduceInt () {
- this.introduceOrCommentInt = true
- this.introduceOrCommentCom = false
- },
- toggleIntroduceCom () {
- this.introduceOrCommentInt = false
- this.introduceOrCommentCom = true
- },
- /**
- * 获取评论分页数据
- */
- getSearchProdPage (current) {
- if (current == 0 || current == this.page.current || current > this.page.pages) {
- return
- } else {
- this.getProdCommPageByProd(this.evaluate, current);
- }
- },
- /**
- * 获取商品评论列表
- */
- getProdCommPageByProd (evaluate, curPage) {
- this.evaluate = evaluate
- this.$axios.get('/prod/prodCommPageByProd', {
- params: {
- prodId: this.prodInfo.prodId,
- current: curPage || 1,
- size: 10,
- evaluate: this.evaluate
- }
- }).then(({ data }) => {
- this.prodCommList = data
- if (this.prodCommList.records.length > 0) {
- this.prodCommList.records.forEach(prodComm => {
- var prodImgs = []
- if (prodComm.pics) {
- prodComm.pics.split(',').forEach(imgStr => {
- prodImgs.push(imgStr)
- })
- }
- prodComm.prodImgs = prodImgs
- })
- }
- data.rainbow = PageUtil.rainbowWithDot(data.current, data.pages, 5)
- this.page = data
- })
- },
- /**
- * 获取热销商品
- */
- getHotSales () {
- // this.$axios.get('/search/searchProdPage', {
- this.$axios.get('/search/page', {
- params: {
- shopId: this.prodInfo.shopId,
- size: 5,
- sort: 1,
- orderBy: 1,
- isAllProdType: true,
- current: 1,
- isActive: 1 // 过滤掉活动商品
- }
- }).then(({ data }) => {
- this.hotSales.records = data.records[0].products
- })
- },
- /**
- * 收藏商品
- */
- toggleCollect () {
- var prodId = this.prodInfo.prodId
- var isCollection = this.isCollection
- this.$axios.post('/p/user/collection/addOrCancel', prodId).then(({ data }) => {
- this.isCollection = !isCollection
- if (this.isCollection) {
- this.$message({
- message: this.$t('prodDetail.collectionSuccess'),
- type: 'success',
- duration: 1000
- });
- } else {
- this.$message({
- message: this.$t('prodDetail.uncollected'),
- type: 'warning',
- duration: 1000
- });
- }
- })
- },
- /**
- * 查询商品是否已收藏
- */
- isProdCollected () {
- if (!Cookie.get('token')) {
- return
- }
- this.$axios.get('/p/user/collection/isCollection', {
- params: {
- prodId: this.prodInfo.prodId
- }
- }).then(({ data }) => {
- this.isCollection = data
- })
- },
- /**
- * 收藏店铺
- */
- toggleShopCollect () {
- var shopId = this.prodInfo.shopId
- var isShopCollection = this.isShopCollection
- this.$axios.post('/p/shop/collection/addOrCancel', shopId).then(({ data }) => {
- this.isShopCollection = !isShopCollection
- if (this.isShopCollection) {
- this.$message({
- message: this.$t('prodDetail.collectionSuccess'),
- type: 'success',
- duration: 1000
- });
- } else {
- this.$message({
- message: this.$t('prodDetail.uncollected'),
- type: 'warning',
- duration: 1000
- });
- }
- })
- },
- /**
- * 查询店铺是否已收藏
- */
- isShopCollected () {
- if (!Cookie.get('token')) {
- return
- }
- this.$axios.get('/p/shop/collection/isCollection', {
- params: {
- shopId: this.prodInfo.shopId
- }
- }).then(({ data }) => {
- this.isShopCollection = data
- })
- },
- /**
- * 减少商品数量
- */
- reduce () {
- var prodNum = parseInt(this.prodNum)
- if(prodNum<=1){
- return
- }
- if(this.defaultSku.seckillStocks || this.defaultSku.seckillStocks == 0) {
- if (!prodNum || prodNum <= 1) {
- this.prodNum = prodNum
- this.prohibit1 = true //禁用
- this.prohibit2 = false
- if(this.defaultSku.seckillStocks == 0){
- this.prohibit2 = true
- }
- }else {
- this.prodNum = prodNum - 1
- this.prohibit1 = false
- this.prohibit2 = false
- }
- } else {
- this.prodNum = 0
- this.prohibit1 = true
- this.prohibit2 = true
- }
- },
- /**
- * 增加商品数量
- */
- increase () {
- var prodNum = parseInt(this.prodNum)
- if(this.defaultSku.seckillStocks) { // 有库存
- if(!this.prodNum) {
- this.prodNum = 1
- return
- }
- // 判断秒杀是否限购 maxNum: -1不限购
- if (this.prodInfo.seckill.maxNum != -1) { // 限购
- if (prodNum < this.defaultSku.seckillStocks && prodNum < this.prodInfo.seckill.maxNum) {
- this.prodNum = prodNum + 1
- } else if(prodNum <= this.prodInfo.seckill.maxNum && this.prodInfo.seckill.maxNum < this.defaultSku.seckillStocks) {
- this.$message({
- message: this.$t('purchaseRestrictions') + this.prodInfo.seckill.maxNum + this.$t('items'),
- type: 'warning',
- duration: 1000
- });
- this.prohibit1 = false
- this.prohibit2 = true //禁用
- } else {
- this.$message({
- message: this.$t('prodDetail.insufficientInventory'),
- type: 'warning',
- duration: 1000
- });
- this.prohibit1 = false
- this.prohibit2 = true //禁用
- }
- } else { // 不限购
- if (prodNum < this.defaultSku.seckillStocks) {
- this.prodNum = prodNum + 1
- this.prohibit1 = false
- this.prohibit2 = false
- } else {
- this.$message({
- message: this.$t('prodDetail.insufficientInventory'),
- type: 'warning',
- duration: 1000
- });
- this.prohibit1 = false
- this.prohibit2 = true //禁用
- }
- }
- }else {
- this.prodNum = 0
- this.prohibit1 = true
- this.prohibit2 = true //禁用
- }
- },
- /**
- * 手动输入数量过滤
- */
- resetProdNum () {
- //失去焦点时
- var prodNum = parseInt(this.prodNum)
- if(this.defaultSku.seckillStocks) { // 有库存
- if (!prodNum || prodNum <= 1) {
- this.prohibit1 = true //禁用
- this.prohibit2 = false //禁用
- }else {
- this.prohibit1 = false
- this.prohibit2 = false
- }
- if (this.prodInfo.seckill.maxNum != -1 ) { // 限购
- if (prodNum > this.prodInfo.seckill.maxNum && this.prodInfo.seckill.maxNum < this.defaultSku.seckillStocks) {
- // 输入数量 > 限购数量 && 限购数量 < 库存
- this.$message({
- message: this.$t('purchaseRestrictions') + this.prodInfo.seckill.maxNum + this.$t('items'),
- type: 'warning',
- duration: 1000
- });
- this.prohibit1 = false
- this.prohibit2 = true //禁用
- }else if (prodNum > this.defaultSku.seckillStocks && this.defaultSku.seckillStocks < this.prodInfo.seckill.maxNum) {
- this.$message({
- message: this.$t('prodDetail.insufficientInventory'),
- type: 'warning',
- duration: 1000
- });
- this.prohibit1 = false
- this.prohibit2 = true //禁用
- }
- } else {
- if (prodNum > this.defaultSku.seckillStocks) {
- this.$message({
- message: this.$t('prodDetail.insufficientInventory'),
- type: 'warning',
- duration: 1000
- });
- this.prohibit2 = true //禁用
- this.prohibit1 = false
- }
- }
- }else { // 无库存
- this.prodNum = 0
- this.prohibit1 = true //禁用
- this.prohibit2 = true //禁用
- }
- },
- /**
- * 组装SKU
- */
- groupSkuProp: function (skuList, defaultPrice) {
- if (skuList.length == 1 && !skuList[0].properties) {
- this.defaultSku = skuList[0]
- return;
- }
- var skuGroup = {};
- var allProperties = [];
- var propKeys = [];
- var selectedPropObj = {}
- var defaultSku = null;
- for (var i = 0; i < skuList.length; i++) {
- var isDefault = false;
- if (!defaultSku && skuList[i].seckillPrice == defaultPrice) { //找到和商品价格一样的那个SKU,作为默认选中的SKU
- defaultSku = skuList[i];
- isDefault = true;
- }
- var properties = skuList[i].properties; //版本:公开版;颜色:金色;内存:64GB
- allProperties.push(properties);
- var propList = properties.split(";"); // ["版本:公开版","颜色:金色","内存:64GB"]
- for (var j = 0; j < propList.length; j++) {
- var propval = propList[j].split(":"); //["版本","公开版"]
- var props = skuGroup[propval[0]]; //先取出 版本对应的值数组
- //如果当前是默认选中的sku,把对应的属性值 组装到selectedProp
- if (isDefault) {
- propKeys.push(propval[0]);
- selectedPropObj[propval[0]] = propval[1];
- }
- if (props == undefined) {
- props = []; //假设还没有版本,新建个新的空数组
- props.push(propval[1]); //把 "公开版" 放进空数组
- } else {
- if (props.indexOf(propval[1]) === -1) { //如果数组里面没有"公开版"
- props.push(propval[1]); //把 "公开版" 放进数组
- }
- }
- skuGroup[propval[0]] = props; //最后把数据 放回版本对应的值
- }
- }
- this.defaultSku = defaultSku
- this.propKeys = propKeys
- this.selectedPropObj = selectedPropObj
- this.parseSelectedObjToVals(skuList);
- this.skuGroup = skuGroup
- this.allProperties = allProperties
- },
- /**
- * 将已选的 {key:val,key2:val2}转换成 [val,val2]
- */
- parseSelectedObjToVals: function (skuList) {
- var selectedPropObj = this.selectedPropObj
- var selectedProperties = "";
- var selectedProp = [];
- for (var key in selectedPropObj) {
- // selectedProp.push(selectedPropObj[key]);
- selectedProp.push({key: key, value: selectedPropObj[key] });
- selectedProperties += key + ":" + selectedPropObj[key] + ";";
- }
- selectedProperties = selectedProperties.substring(0, selectedProperties.length - 1);
- this.selectedProp = selectedProp
- this.selectedProperties = selectedProperties
- this.selectedPropObj = selectedPropObj
- var findSku = false;
- for (var i = 0; i < skuList.length; i++) {
- // 解决排序问题导致无法匹配
- // if (skuList[i].properties == selectedProperties) {
- if (
- this.compareArray(selectedProperties.split(';').sort(),
- skuList[i].properties.split(';').sort())
- ) {
- findSku = true;
- this.defaultSku = skuList[i]
- // if(this.defaultSku.pic!=null){
- // this.defaultSku.pic = picDomain+this.defaultSku.pic
- // }
- this.changeSkuImg(this.defaultSku.pic);
- break;
- }
- }
- this.findSku = findSku
- },
- /**
- * 比较两个数组中的元素是否相等
- * @param a1 第一个数组
- * @param a2 第二个数组
- * @return boolean 两个数组中的元素都相等则返回 true,反之返回 false
- */
- compareArray(a1, a2) {
- if (!a1 || !a2) {
- return false;
- }
- if (a1.length !== a2.length) {
- return false;
- }
- for (var i = 0, n = a1.length; i < n; i++) {
- if (a1[i] !== a2[i]) {
- return false;
- }
- }
- return true;
- },
- /**
- * 切换SKU图片
- */
- changeSkuImg (skuPic) {
- if (skuPic) {
- // if (this.prodImgs[0].sku) {
- // this.prodImgs.splice(0, 1)
- // }
- this.prodImgs.forEach(prodImg => {
- prodImg.isActive = false
- })
- // this.prodImgs.splice(0, 0, {
- // img: skuPic,
- // isActive: true,
- // sku: true
- // });
- this.prodInfo.pic = skuPic
- } else {
- this.prodInfo.pic = this.prodImgs[0].img
- }
- },
- /**
- * 判断当前的规格值 是否可以选
- */
- isSkuLineItemNotOptional (allProperties, selectedPropObj, key, item, propKeys) {
- var selectedPropObj = Object.assign({}, selectedPropObj)
- var properties = "";
- selectedPropObj[key] = item;
- for (var j = 0; j < propKeys.length; j++) {
- properties += propKeys[j] + ":" + selectedPropObj[propKeys[j]] + ";";
- }
- properties = properties.substring(0, properties.length - 1);
- for (var i = 0; i < allProperties.length; i++) {
- if (properties == allProperties[i]) {
- return false;
- }
- }
- for (var i = 0; i < allProperties.length; i++) {
- if (allProperties[i].indexOf(item) >= 0) {
- return true;
- }
- }
- return false;
- },
- /**
- * 规格点击事件
- */
- toChooseItem (skuLineItem, key, event) {
- this.selectedPropObj[key] = skuLineItem;
- this.parseSelectedObjToVals(this.prodInfo.skuList);
- if(this.defaultSku.seckillStocks) {
- this.prodNum = 1
- this.prohibit1 = true
- this.prohibit2 = false
- }else {
- this.prodNum = 0
- this.prohibit1 = true
- this.prohibit2 = true
- }
- },
- /**
- * 立即抢购
- */
- buyNow () {
- if (!this.findSku) {
- return;
- }
- if (!this.prodNum || this.prodNum < 1) {
- this.$message({
- message: this.$t('prodDetail.pleaseEnterTheCorrectNumberOfItems'),
- type: 'warning',
- duration: 1000
- })
- return;
- }
- if (this.prodInfo.seckill.maxNum != -1 ) { // 限购
- if (this.prodNum > this.prodInfo.seckill.maxNum) {
- this.$message({
- message: this.$t('purchaseRestrictions') + this.prodInfo.seckill.maxNum + this.$t('items'),
- type: 'warning',
- duration: 1000
- });
- this.prohibit1 = false
- this.prohibit2 = true //禁用
- return
- }
- } else {
- if (this.prodNum > this.defaultSku.seckillStocks) {
- this.$message.warning(this.$t('prodDetail.insufficientInventory'))
- this.prohibit2 = true //禁用
- return
- }
- }
- if (!this.countdown.obj.signs) {
- this.$message({
- message: this.$t('prodDetail.theSpikeActivityHasNotStarted'),
- type: 'warning',
- duration: 1000
- })
- return;
- }
- if (!Cookie.get('token')) {
- bus.$emit("showLogin", true)
- } else {
- const secKillObj = {
- addrId: 0,
- prodCount: this.prodNum,
- seckillSkuId: this.defaultSku.seckillSkuId,
- }
- sessionStorage.setItem("secKillObj", JSON.stringify(secKillObj));
- this.$router.push({
- path: '/secdetail/confirm-order?seckillId=' + this.defaultSku.seckillId,
- })
- }
- },
- /**
- * 搜索
- */
- toShopIndex () {
- var searchTerms = this.prodName.trim() //去除字符串的头尾空格
- if (!searchTerms) {
- this.$message({
- message: this.$t('prodDetail.searchContentCannotBeEmpty'),
- type: 'error',
- duration: 1000
- })
- return
- }
- // 跳转到商品列表页
- let url = '/shopIndex?sid=' + this.shopId + '&pn=' + searchTerms
- this.$router.push({ path: url })
- },
- // 跳转商家客服
- toChatIm (prodInfo) {
- if (Cookie.get('token')) {
- let routeUrl = this.$router.resolve({
- path: `/chat?shopId=${prodInfo.shopId}`
- });
- window.open(routeUrl.href, 'view_window');
- } else {
- this.showLogin = true
- }
- },
- /**
- * 隐藏登录弹窗
- */
- hideLoginPop () {
- this.showLogin = false
- },
- },
- destroyed () {
- // 页面销毁时移除监听
- window.removeEventListener('scroll', this.scrollToTop)
- clearTimeout(this.timer)
- },
- }
- </script>
- <style scoped src='~/assets/css/detail.css'></style>
- <style scoped>
- .seckill-end-tips {
- width: 100%;
- text-align: center;
- display: inline-block;
- }
- </style>
|