StoreDetail.vue 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545
  1. <template>
  2. <div class="store-detail mobile-content">
  3. <div class="store-logo">
  4. <div class="store-logo-box">
  5. <img :src="store.logoUrl || '/images/component/default.png'"/>
  6. <i v-if="showIcon" class="iconfont icon-shoucang" :style="isFocus === 'true'?'color:#ff7800':'color: #ddd'" @click="collectStore"></i>
  7. </div>
  8. </div>
  9. <div class="store-switch-item">
  10. <span :class="activeType=='product'?'mobile-switch-btn active':'mobile-switch-btn'" @click="activeType='product'">产品</span>
  11. <span :class="activeType=='detail'?'mobile-switch-btn active':'mobile-switch-btn'" @click="activeType='detail'">介绍</span>
  12. </div>
  13. <div class="store-info" v-if="activeType=='detail' && store.description && store.description.length">
  14. <div class="contact-info">
  15. <h4>联系我们</h4>
  16. <ul class="list-unstyled clearfix">
  17. <li>
  18. <div>电&nbsp;&nbsp;话:</div>
  19. <div v-if="store.enterprise.enTel"><a :href="'tel:' + store.enterprise.enTel" @click="clickTel = true" :class="{'click-tel': clickTel}">{{store.enterprise.enTel}}</a></div>
  20. <div v-else><span>-</span></div>
  21. </li>
  22. <li>
  23. <div>传&nbsp;&nbsp;真:</div>
  24. <div v-if="store.enterprise.enFax"> {{store.enterprise.enFax}}</div>
  25. <div v-else><span>-</span></div>
  26. </li>
  27. <li>
  28. <div>手&nbsp;&nbsp;机:</div>
  29. <div v-if="store.enterprise.enPhone"> <a :href="'tel:' + store.enterprise.enPhone" @click="clickPhone = true" :class="{'click-phone': clickPhone}">{{store.enterprise.enPhone}}</a></div>
  30. <div v-else><span>-</span></div>
  31. </li>
  32. <li>
  33. <div>微&nbsp;&nbsp;信:</div>
  34. <div v-if="store.enterprise.enWeixin"> {{store.enterprise.enWeixin}}</div>
  35. <div v-else><span>-</span></div>
  36. </li>
  37. <li>
  38. <div>Q&nbsp;&nbsp;&nbsp;&nbsp;Q:</div>
  39. <div v-if="store.enterprise.enQQ"> {{store.enterprise.enQQ}}</div>
  40. <div v-else><span>-</span></div>
  41. </li>
  42. <li>
  43. <div>店铺地址:</div>
  44. <div v-if="store.enterprise.enAddress">{{store.enterprise.enAddress}}</div>
  45. <div v-else><span>-</span></div>
  46. </li>
  47. </ul>
  48. </div>
  49. <div class="store-description">
  50. <h4>企业简介</h4>
  51. <p>
  52. {{store.description}}
  53. </p>
  54. </div>
  55. </div>
  56. <div class="com-none-state" v-if="activeType=='detail' && (!store.description || !store.description.length)">
  57. <img src="/images/mobile/@2x/empty-collect.png">
  58. <p>抱歉,暂无店铺简介</p>
  59. <nuxt-link to="/">返回首页</nuxt-link>
  60. </div>
  61. <div class="product-store" v-if="activeType == 'product'">
  62. <table v-if="commodities.content&&commodities.content.length > 0">
  63. <thead id="product-head" >
  64. <tr>
  65. <th style="width: 1.77rem;">型号/品牌</th>
  66. <th style="width: 1.75rem;">包装</th>
  67. <th style="width: 2.2rem;">价格梯度</th>
  68. <th style="width: 1.77rem;">交期(天)</th>
  69. </tr>
  70. </thead>
  71. <thead class="active" v-show="isScrollOverTab">
  72. <tr>
  73. <th style="width: 1.77rem;">型号/品牌</th>
  74. <th style="width: 1.75rem;">包装</th>
  75. <th style="width: 2.2rem;">价格梯度</th>
  76. <th style="width: 1.77rem;">交期(天)</th>
  77. </tr>
  78. </thead>
  79. <tbody id="product-body">
  80. <tr v-for="commodity in searchLists" @click="goProductDetail(commodity.uuid)">
  81. <td class="store-name">
  82. <div>{{commodity.code}}</div>
  83. <div>{{commodity.brandNameCn}}</div>
  84. </td>
  85. <td>
  86. <div v-if="!commodity.packaging && !commodity.breakUp && !commodity.produceDate">-</div>
  87. <div>{{commodity.packaging}}</div>
  88. <div>{{commodity.breakUp?'可拆卖':'不可拆卖'}}</div>
  89. <div>{{commodity.produceDate}}</div>
  90. </td>
  91. <td class="price-level-wrap">
  92. <div v-if="!commodity.prices || commodity.prices.length == 0">-</div>
  93. <div class="price-number fl">
  94. <div v-for="price in commodity.prices">{{price.start}}+</div>
  95. </div>
  96. <div class="price-number fr">
  97. <div v-for="price in commodity.prices" class="price-level">
  98. <span v-if="commodity.currencyName.indexOf('RMB')!==-1">¥{{price.rMBPrice | currency}}</span>
  99. <span v-if="commodity.currencyName.indexOf('USD')!==-1">${{price.uSDPrice | currency}}</span>
  100. </div>
  101. </div>
  102. </td>
  103. <td>
  104. <div v-if="commodity.b2cMinDelivery">
  105. <span>{{commodity.b2cMinDelivery}}</span>
  106. <span v-if="commodity.b2cMaxDelivery && commodity.b2cMaxDelivery !== commodity.b2cMinDelivery">-</span>
  107. <span v-if="commodity.b2cMaxDelivery && commodity.b2cMaxDelivery !== commodity.b2cMinDelivery">{{commodity.b2cMaxDelivery}}</span>
  108. </div>
  109. <div v-if="commodity.minBuyQty"><span class="order-tag">订</span>{{commodity.minBuyQty}}起订</div>
  110. <div v-if="commodity.reserve"><span class="order-tag reserve-tag">库</span>{{commodity.reserve}}</div>
  111. <div v-if="!commodity.b2cMinDelivery">
  112. <span>—</span>
  113. </div>
  114. </td>
  115. </tr>
  116. </tbody>
  117. </table>
  118. <div v-if="!commodities.content || commodities.content.length == 0" class="no-product">
  119. <img src="/images/mobile/@2x/car@2x.png" alt="">
  120. <div>抱歉,暂无上架产品信息</div>
  121. </div>
  122. </div>
  123. <remind-box :title="collectResult" :timeoutCount="timeoutCount"></remind-box>
  124. <loading v-show="isSearchingMore"></loading>
  125. <login-box @onLoginBoxClose="showLoginBox = false" v-if="showLoginBox"></login-box>
  126. </div>
  127. </template>
  128. <script>
  129. import {RemindBox, Loading, LoginBox} from '~components/mobile/common'
  130. export default {
  131. data () {
  132. return {
  133. activeType: 'product',
  134. collectResult: '收藏成功',
  135. timeoutCount: 0,
  136. clickTel: false,
  137. clickPhone: false,
  138. isSearchingMore: false,
  139. searchLists: [],
  140. page: 1,
  141. showLoginBox: false,
  142. isScrollOverTab: false
  143. }
  144. },
  145. components: {
  146. RemindBox,
  147. Loading,
  148. LoginBox
  149. },
  150. mounted: function () {
  151. let _this = this
  152. _this.$nextTick(function () {
  153. window.addEventListener('scroll', function () {
  154. _this.scroll()
  155. }, false)
  156. })
  157. },
  158. filters: {
  159. currency: function (num) {
  160. if (typeof num === 'number') {
  161. if (num <= 0.000001) {
  162. num = 0.000001
  163. } else {
  164. if (num.toString().indexOf('.') === -1) {
  165. num += '.00'
  166. } else {
  167. let inputStr = num.toString()
  168. let arr = inputStr.split('.')
  169. let floatNum = arr[1]
  170. if (floatNum.length > 6) {
  171. num = inputStr.substring(0, arr[0].length + 7)
  172. if (Number(floatNum.charAt(6)) > 4) {
  173. num = (Number(num) * 1000000 + 1) / 1000000
  174. }
  175. } else if (floatNum.length === 1) {
  176. num = num + '0'
  177. }
  178. }
  179. }
  180. }
  181. return num
  182. }
  183. },
  184. created () {
  185. this.clickTel = false
  186. this.clickPhone = false
  187. },
  188. computed: {
  189. store () {
  190. return this.$store.state.shop.storeInfo.store.data
  191. },
  192. commodities () {
  193. let list = this.$store.state.shop.storeInfo.storeCommodity.data
  194. this.searchLists = this.searchLists.concat(list.content)
  195. this.isSearchingMore = false
  196. return list
  197. },
  198. allPage () {
  199. return this.commodities.totalPages
  200. },
  201. isFocus () {
  202. return this.$store.state.shop.storeInfo.focusList.data
  203. },
  204. user () {
  205. return this.$store.state.option.user
  206. },
  207. showIcon() {
  208. return this.store.uuid !== this.$store.state.option.storeStatus.data.uuid
  209. }
  210. },
  211. methods: {
  212. scroll: function () {
  213. let scrolled = document.documentElement.scrollTop || window.pageYOffset || document.body.scrollTop
  214. if (Math.ceil(scrolled + window.screen.availHeight) >= document.body.scrollHeight && !this.isSearchingMore && this.page < this.allPage && this.activeType === 'product') {
  215. this.getMoreCom()
  216. }
  217. let tbodyObj = document.getElementById('product-body')
  218. let theadObj = document.getElementById('product-head')
  219. if (theadObj) {
  220. this.isScrollOverTab = tbodyObj.getBoundingClientRect().top - theadObj.getBoundingClientRect().height - 5 <= theadObj.getBoundingClientRect().height
  221. }
  222. },
  223. getMoreCom: function () {
  224. if (!this.isSearchingMore) {
  225. this.page++
  226. this.isSearchingMore = true
  227. this.pageCommodity({ page: this.page, count: 6 })
  228. }
  229. },
  230. async pageCommodity (pageParams, kindId, keyword) {
  231. let params = { storeid: this.$route.params.uuid, origin: 'store', kindUuid: kindId, code: keyword }
  232. params.page = pageParams.page
  233. params.count = pageParams.count
  234. try {
  235. let { data } = await this.$http.get('/api/commodity/commodities', { params })
  236. this.$store.commit('shop/storeInfo/GET_STORE_COMMODITY_SUCCESS', data)
  237. } catch (err) {
  238. this.$store.commit('shop/storeInfo/GET_STORE_COMMODITY_FAILURE', err)
  239. }
  240. },
  241. goProductDetail: function (uuid) {
  242. if (uuid) {
  243. this.$router.push('/mobile/brand/componentDetail/' + uuid)
  244. } else {
  245. this.collectResult = '卖家上传的产品暂无参数,请联系卖家了解具体详情。'
  246. this.timeoutCount ++
  247. }
  248. },
  249. collectStore: function () {
  250. if (this.user.logged) {
  251. if (this.isFocus === 'false') {
  252. this.$store.dispatch('shop/StoreFocus', {storeName: this.store.storeName, storeid: this.store.id})
  253. .then(response => {
  254. this.$store.dispatch('shop/StoreFocusList', {id: this.store.id})
  255. this.collectResult = '收藏成功'
  256. this.timeoutCount++
  257. })
  258. } else if (this.isFocus === 'true') {
  259. this.$http.post('/trade/storeFocus/delete/storeId', [this.store.id])
  260. .then(response => {
  261. this.$store.dispatch('shop/StoreFocusList', {id: this.store.id})
  262. this.collectResult = '取消成功'
  263. this.timeoutCount++
  264. })
  265. }
  266. } else {
  267. this.showLoginBox = true
  268. }
  269. }
  270. }
  271. }
  272. </script>
  273. <style lang="scss" scoped>
  274. .store-detail {
  275. margin: 0 auto;
  276. margin-bottom: 1.2rem;
  277. text-align: center;
  278. background: #f7f7f7;
  279. height: 100%;
  280. .store-logo {
  281. height: 3.17rem;
  282. width: 6.96rem;
  283. display: inline-block;
  284. margin: .2rem auto;
  285. line-height: 2.13rem;
  286. background: #fff;
  287. text-align: center;
  288. border-radius: .1rem;
  289. background: url('/images/mobile/@2x/brand-bg.png') no-repeat;
  290. background-size: cover;
  291. .store-logo-box {
  292. border: .04rem solid #c7e5fd;
  293. border-radius: .1rem;
  294. height: 2.21rem;
  295. width: 3.73rem;
  296. margin: .5rem auto 0;
  297. background: #fff;
  298. position: relative;
  299. img {
  300. max-height: 2.1rem;
  301. max-width: 3.6rem;
  302. }
  303. >i {
  304. position: absolute;
  305. font-size: .4rem;
  306. background: #fff;
  307. width: .6rem;
  308. height: .6rem;
  309. line-height: .6rem;
  310. border-radius: 100%;
  311. box-shadow: 0 0 .05rem #aaa;
  312. right: -1.44rem;
  313. top: .75rem;
  314. text-align: center;
  315. }
  316. }
  317. }
  318. .store-switch-item {
  319. text-align: center;
  320. background: #fff;
  321. .mobile-switch-btn {
  322. background: #fff;
  323. color: #666;
  324. display: inline-block;
  325. height: .64rem;
  326. font-size: .34rem;
  327. line-height: .64rem;
  328. width: 1.4rem;
  329. &:first-child {
  330. margin-right: 1.78rem;
  331. }
  332. &.active {
  333. color: #fc5708;
  334. border-bottom: .04rem solid #fc5708;
  335. }
  336. }
  337. }
  338. .store-info {
  339. background: #f7f7f7;
  340. width: 100%;
  341. h4{
  342. width: 100%;
  343. text-align: left;
  344. font-size: 0.3rem;
  345. line-height: 0.6rem;
  346. height: 0.6rem;
  347. letter-spacing: 0px;
  348. color: #333;
  349. font-weight: normal;
  350. border-bottom: 1px solid #efeded;
  351. padding-left: 0.11rem;
  352. &:before{
  353. content: '';
  354. display: inline-block;
  355. width: 0.08rem;
  356. height: 0.26rem;
  357. background-color: #145dee;
  358. margin-right: 0.13rem;
  359. position: relative;
  360. top: 0.02rem;
  361. }
  362. }
  363. .contact-info{
  364. background: #fff;
  365. width: 6.96rem;
  366. margin: .2rem auto;
  367. border-radius: .1rem;
  368. ul{
  369. padding: 0.22rem 0rem;
  370. li{
  371. div{
  372. float: left;
  373. font-size: .28rem;
  374. color: #666;
  375. line-height: .53rem;
  376. width:80%;
  377. text-align: left;
  378. &:first-child{
  379. width: 20%;
  380. text-align: right;
  381. padding-right: 0.04rem;
  382. }
  383. a{
  384. color: #145dee;
  385. }
  386. .click-tel, .click-phone{
  387. color: #f44336;
  388. }
  389. }
  390. &:last-child{
  391. div{
  392. width: 74%;
  393. padding-right:.34rem;
  394. word-wrap: break-word;
  395. &:first-child{
  396. text-align: left;
  397. padding: 0rem 0rem 0rem .36rem;
  398. width: 26%;
  399. }
  400. }
  401. }
  402. }
  403. }
  404. }
  405. .store-description{
  406. background: #fff;
  407. width: 6.96rem;
  408. margin: .2rem auto;
  409. border-radius: .1rem;
  410. p {
  411. text-indent:2em;
  412. background: #fff;
  413. margin: .2rem auto 0;
  414. padding: .04rem .34rem;
  415. width: 100%;
  416. font-size: .28rem;
  417. color: #666;
  418. text-align: left;
  419. height: 95%;
  420. box-shadow: 0 .03rem .01rem 0 #cdcbcb96;
  421. line-height: .5rem;
  422. word-break: break-all;
  423. }
  424. }
  425. }
  426. .product-store {
  427. margin: .2rem 0 0 0;
  428. table {
  429. width: 100%;
  430. font-size: .28rem;
  431. thead {
  432. background: #d5e5fb;
  433. &.active {
  434. position: fixed;
  435. top: .88rem;
  436. z-index: 2;
  437. }
  438. tr {
  439. th {
  440. font-weight: bold;
  441. text-align: center;
  442. height: .78rem;
  443. line-height: .78rem;
  444. }
  445. }
  446. }
  447. tbody {
  448. tr {
  449. background: #fff;
  450. border-bottom: 0.2rem solid #f7f7f7;
  451. td {
  452. padding: .2rem .1rem;
  453. text-align: left;
  454. &.price-level-wrap {
  455. text-align: center;
  456. }
  457. div {
  458. overflow: hidden;
  459. text-overflow: ellipsis;
  460. white-space: nowrap;
  461. margin-bottom: .2rem;
  462. max-width: 1.58rem;
  463. &:last-child {
  464. margin-bottom: 0;
  465. }
  466. }
  467. .price-level:last-child {
  468. color: #fc5708;
  469. }
  470. .price-number {
  471. display: inline-block;
  472. vertical-align: middle;
  473. margin-bottom: 0;
  474. width: .9rem;
  475. }
  476. .order-tag {
  477. display: inline-block;
  478. font-size: .18rem;
  479. color: #fff;
  480. font-weight: bold;
  481. background: #ee1717;
  482. height: .27rem;
  483. width: .27rem;
  484. line-height: .27rem;
  485. text-align: center;
  486. border-radius: .05rem;
  487. position: relative;
  488. top: -.05rem;
  489. margin-right: .05rem;
  490. &.reserve-tag {
  491. background: #07bb1c;
  492. }
  493. }
  494. }
  495. &:active {
  496. background: #e1e1e1;
  497. }
  498. }
  499. }
  500. }
  501. .no-store {
  502. background: #fff;
  503. padding-top: 1rem;
  504. img {
  505. display: block;
  506. text-align: center;
  507. margin: 0 auto;
  508. margin-bottom: .45rem;
  509. width: 3.31rem;
  510. height: 2.13rem;
  511. }
  512. div {
  513. width: 5.27rem;
  514. margin: 0 auto;
  515. text-align: center;
  516. line-height: .4rem;
  517. color: #999;
  518. .link-url {
  519. color: #01a44e;
  520. }
  521. }
  522. }
  523. }
  524. .no-product {
  525. background: #fff;
  526. padding-top: 1rem;
  527. img {
  528. display: block;
  529. text-align: center;
  530. margin: 0 auto;
  531. margin-bottom: .45rem;
  532. width: 3.31rem;
  533. height: 2.13rem;
  534. }
  535. div {
  536. width: 5.27rem;
  537. margin: 0 auto;
  538. text-align: center;
  539. line-height: .4rem;
  540. font-size: .32rem;
  541. color: #999;
  542. }
  543. }
  544. }
  545. </style>