index.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363
  1. <template>
  2. <div>
  3. <search-header @searchAction="onSearch" :outerKeyword="keyword" :placeholder="'品牌/类目(产品名称)/型号/店铺名'"></search-header>
  4. <div class="shop mobile-content">
  5. <div class="shop-top">
  6. <p><i class="iconfont icon-dianpu1"></i><span>{{list.totalElements || 0}}</span>家店铺</p>
  7. <span @click="onClick($event)">{{downName}} <i class="iconfont icon-arrow-down"></i></span>
  8. <ul class="supdown" v-if="down">
  9. <li @click="onDown('ORIGINAL_FACTORY-DISTRIBUTION-AGENCY-CONSIGNMENT', $event)" v-show="downName !== '全部'">全部</li>
  10. <li @click="onDown('ORIGINAL_FACTORY', $event)" v-show="downName !== '原厂'">原厂</li>
  11. <li @click="onDown('AGENCY', $event)" v-show="downName !== '代理'">代理</li>
  12. <li @click="onDown('DISTRIBUTION', $event)" v-show="downName !== '经销'">经销</li>
  13. <li @click="onDown('CONSIGNMENT', $event)" v-show="downName !== '寄售'">寄售</li>
  14. </ul>
  15. </div>
  16. <div v-if="searchLists && searchLists.length">
  17. <div class="shop-list" v-for="item in searchLists" @click="goStoreDetail(item.uuid)">
  18. <h3>{{item.storeName}}</h3>
  19. <div class="list-item">
  20. <div class="item-img">
  21. <i :style="'background:url(' + isType(item.type) + ')no-repeat 0 0/.65rem .33rem;'"></i>
  22. <img :src="item.logoUrl || '/images/component/default.png'">
  23. </div>
  24. <div class="list-item-phone">
  25. <p>电话:<span>{{item.enterprise.enTel}}</span></p>
  26. <p>传真:<span>{{item.enterprise.enFax}}</span></p>
  27. <!--<p>商家介绍: <nuxt-link :to="'/mobile/merchantDescription/'+item.uuid">点击查看</nuxt-link></p>-->
  28. <p>联系商家:<a @click="selectStoreInfo(item, $event)">点击查看</a></p>
  29. <i class="iconfont icon-shoucang" :style="item.isFocus=='true'?'color:#ff7800':'color:#bbb'" @click="focusStore(item, $event)"></i>
  30. </div>
  31. </div>
  32. </div>
  33. </div>
  34. <div class="com-none-state" v-else>
  35. <img src="/images/mobile/@2x/search-empty.png">
  36. <p>抱歉,暂无搜索结果</p>
  37. <nuxt-link to="/">返回首页</nuxt-link>
  38. </div>
  39. <remind-box :title="collectResult" :timeoutCount="timeoutCount"></remind-box>
  40. <loading v-show="isSearchingMore"></loading>
  41. <div class="mobile-modal" v-if="showStoreInfo" @touchmove="preventTouchMove($event)">
  42. <div class="mobile-modal-box">
  43. <div class="mobile-modal-header">联系方式<i @click="showStoreInfo = false" class="icon-guanbi iconfont"></i></div>
  44. <div class="mobile-modal-content">
  45. <div v-if="checkInfo(enterpriseInfo.enAddress || enterpriseInfo.address)">商家地址:{{enterpriseInfo.enAddress || enterpriseInfo.address}}</div>
  46. <!--<div class="content-line link-url">在线咨询</div>-->
  47. <div v-if="checkInfo(enterpriseInfo.enTel)">致电:<a :href="'tel:' + enterpriseInfo.enTel" target="_blank" class="content-line link-url">{{enterpriseInfo.enTel}}</a></div>
  48. <div v-if="checkInfo(enterpriseInfo.enEmail)">邮件:<a :href="'mailto:' + enterpriseInfo.enEmail" target="_blank" class="content-line link-url">{{enterpriseInfo.enEmail}}</a></div>
  49. </div>
  50. </div>
  51. </div>
  52. <login-box @onLoginBoxClose="showLoginBox = false" v-if="showLoginBox" :url="url"></login-box>
  53. </div>
  54. </div>
  55. </template>
  56. <script>
  57. import {RemindBox, Loading, LoginBox} from '~components/mobile/common'
  58. import {SearchHeader} from '~components/mobile/base'
  59. export default {
  60. layout: 'mobileNoHeader',
  61. data () {
  62. return {
  63. page: 1,
  64. count: 10,
  65. types: 'ORIGINAL_FACTORY-DISTRIBUTION-AGENCY-CONSIGNMENT',
  66. down: false,
  67. downName: '全部',
  68. isFocus: true,
  69. collectResult: '收藏成功',
  70. timeoutCount: 0,
  71. isSearchingMore: false,
  72. searchLists: [],
  73. isChange: false,
  74. showStoreInfo: false,
  75. enterpriseInfo: {},
  76. showLoginBox: false,
  77. keyword: this.$route.query.keyword,
  78. url: '',
  79. field: null
  80. }
  81. },
  82. components: {
  83. RemindBox,
  84. Loading,
  85. LoginBox,
  86. SearchHeader
  87. },
  88. // watch: {
  89. // '$route.query.keyword': {
  90. // handler: function (val) {
  91. // this.isChange = true
  92. // this.page = 1
  93. // this.type = 'ORIGINAL_FACTORY-DISTRIBUTION-AGENCY-CONSIGNMENT'
  94. // this.$store.dispatch('provider/findStoreListInMobil', { page: this.page, count: this.count, type: this.types, keyword: this.keyword || null })
  95. // },
  96. // immediate: false
  97. // }
  98. // },
  99. fetch ({ store, query }) {
  100. return Promise.all([
  101. store.dispatch('provider/findStoreListInMobil', { page: 1, count: 10, type: 'ORIGINAL_FACTORY-DISTRIBUTION-AGENCY-CONSIGNMENT', keyword: query.keyword })
  102. ])
  103. },
  104. computed: {
  105. list () {
  106. let list = JSON.parse(JSON.stringify(this.$store.state.provider.stores.storeList.data))
  107. if (this.isChange) {
  108. this.searchLists = []
  109. this.page = 1
  110. this.isChange = false
  111. } else {
  112. this.searchLists = this.searchLists.concat(list.content)
  113. this.isSearchingMore = false
  114. }
  115. return list
  116. },
  117. allPage () {
  118. return this.list.totalPages
  119. },
  120. user () {
  121. return this.$store.state.option.user
  122. }
  123. },
  124. mounted: function () {
  125. let _this = this
  126. _this.$nextTick(function () {
  127. window.addEventListener('scroll', function () {
  128. _this.scroll()
  129. }, false)
  130. document.body.onclick = () => {
  131. this.down = false
  132. }
  133. })
  134. },
  135. methods: {
  136. scroll: function () {
  137. let scrolled = document.documentElement.scrollTop || window.pageYOffset || document.body.scrollTop
  138. if (Math.ceil(scrolled + window.screen.availHeight) >= document.body.scrollHeight && !this.isSearchingMore && this.page < this.allPage) {
  139. this.getMoreStore()
  140. }
  141. },
  142. getMoreStore: function () {
  143. if (!this.isSearchingMore) {
  144. this.page++
  145. this.isSearchingMore = true
  146. this.reloadData()
  147. }
  148. },
  149. isType (type) {
  150. let bgurl = ''
  151. if (type === 'ORIGINAL_FACTORY') {
  152. bgurl = '/images/mobile/@2x/shop/original_factory.png'
  153. } else if (type === 'DISTRIBUTION') {
  154. bgurl = '/images/mobile/@2x/shop/distribution.png'
  155. } else if (type === 'AGENCY') {
  156. bgurl = '/images/mobile/@2x/shop/agency.png'
  157. } else if (type === 'CONSIGNMENT') {
  158. bgurl = '/images/mobile/@2x/shop/consignment.png'
  159. }
  160. return bgurl
  161. },
  162. onClick (e) {
  163. if (e) {
  164. e.stopPropagation()
  165. }
  166. this.down = !this.down
  167. },
  168. onDown (type, e) {
  169. if (e) {
  170. e.stopPropagation()
  171. }
  172. this.isChange = true
  173. this.down = !this.down
  174. this.types = type
  175. if (type === 'ORIGINAL_FACTORY') {
  176. this.downName = '原厂'
  177. } else if (type === 'DISTRIBUTION') {
  178. this.downName = '经销'
  179. } else if (type === 'AGENCY') {
  180. this.downName = '代理'
  181. } else if (type === 'CONSIGNMENT') {
  182. this.downName = '寄售'
  183. } else if (type === 'ORIGINAL_FACTORY-DISTRIBUTION-AGENCY-CONSIGNMENT') {
  184. this.downName = '全部'
  185. }
  186. this.reloadData()
  187. },
  188. reloadData () {
  189. this.$store.dispatch('provider/findStoreListInMobil', { page: this.page, count: this.count, type: this.types, keyword: this.keyword || null, field: this.field })
  190. },
  191. focusStore: function (item, $event) {
  192. // item.isFocus = item.isFocus === 'false' ? 'true' : 'false'
  193. $event.stopPropagation()
  194. if (this.user.logged) {
  195. if (item.isFocus === 'false') {
  196. this.$http.post('/trade/storeFocus/save', {storeName: item.storeName, storeid: item.id})
  197. .then(response => {
  198. item.isFocus = 'true'
  199. this.collectResult = '收藏成功'
  200. this.timeoutCount++
  201. })
  202. } else {
  203. this.$http.post('/trade/storeFocus/delete/storeId', [item.id])
  204. .then(response => {
  205. item.isFocus = 'false'
  206. this.collectResult = '取消成功'
  207. this.timeoutCount++
  208. })
  209. }
  210. } else {
  211. this.url = this.$route.fullPath
  212. this.showLoginBox = true
  213. }
  214. },
  215. goStoreDetail: function (uuid) {
  216. this.$router.push('/mobile/shop/' + uuid)
  217. },
  218. selectStoreInfo: function (store, $event) {
  219. $event.stopPropagation()
  220. this.enterpriseInfo = store.enterprise || {}
  221. this.showStoreInfo = true
  222. },
  223. checkInfo: function (str) {
  224. return str && str.trim() !== ''
  225. },
  226. onSearch: function (keyObj) {
  227. // console.log(keyObj)
  228. this.keyword = keyObj.keyword
  229. this.field = keyObj.type ? 'similar' : null
  230. this.onDown('ORIGINAL_FACTORY-DISTRIBUTION-AGENCY-CONSIGNMENT')
  231. this.down = false
  232. }
  233. }
  234. }
  235. </script>
  236. <style scoped lang="scss">
  237. .shop{
  238. margin-bottom: .98rem;
  239. background: #e2e4e6;
  240. .shop-top{
  241. width:100%;
  242. height:1.14rem;
  243. line-height: 1.14rem;
  244. padding:0 .3rem;
  245. position:relative;
  246. background:#fff;
  247. .supdown{
  248. position: absolute;
  249. top: .8rem;
  250. right: .1rem;
  251. z-index: 1;
  252. background: #616264;
  253. border-radius: .1rem;
  254. li{
  255. font-size: .28rem;
  256. color: #ffffff;
  257. line-height: .8rem;
  258. padding: 0 .4rem;
  259. height: .8rem;
  260. }
  261. }
  262. p{
  263. font-size:.24rem;
  264. color:#000;
  265. display: inline-block;
  266. i{
  267. font-size: .53rem;
  268. color:#418ef7;
  269. }
  270. span{
  271. font-size:.3rem;
  272. color:#f94f28;
  273. margin:0 .1rem;
  274. }
  275. }
  276. >span{
  277. font-size:.28rem;
  278. color:#53a0f7;
  279. float: right;
  280. }
  281. }
  282. .shop-list {
  283. background:#fff;
  284. margin-top:.1rem;
  285. border-bottom: .1rem solid #e2e4e6;
  286. /* padding-bottom:.1rem;*/
  287. box-shadow: 0 .03rem .01rem 0 #cdcbcb96;
  288. h3{
  289. font-size: .32rem;
  290. line-height: .4rem;
  291. margin: 0 0 0 .27rem;
  292. overflow: hidden;
  293. text-overflow: ellipsis;
  294. white-space: nowrap;
  295. padding-top: .1rem;
  296. position: relative;
  297. top: .1rem;
  298. }
  299. .list-item{
  300. width:6.77rem;
  301. margin-left:.39rem;
  302. .item-img{
  303. position:relative;
  304. width:2.42rem;
  305. height:1.69rem;
  306. display: inline-block;
  307. vertical-align: middle;
  308. i{
  309. display:block;
  310. position:absolute;
  311. width:.65rem;
  312. height:.33rem;
  313. }
  314. img{
  315. display:inline-block;
  316. width:100%;
  317. height:100%;
  318. border:.04rem solid #eee;
  319. background-color: #fff;
  320. }
  321. }
  322. .list-item-phone{
  323. width:3.95rem;
  324. padding:.18rem 0;
  325. position:relative;
  326. display: inline-block;
  327. vertical-align: middle;
  328. margin-left: .2rem;
  329. p{
  330. font-size:.28rem;
  331. line-height: .67rem;
  332. margin:0;
  333. overflow: hidden;
  334. text-overflow: ellipsis;
  335. white-space: nowrap;
  336. width: 3.2rem;
  337. }
  338. i{
  339. display:block;
  340. position:absolute;
  341. top: -.06rem;
  342. right: -.06rem;
  343. font-size:.5rem;
  344. color:#ff7800;
  345. width: .6rem;
  346. height: .6rem;
  347. text-align: center;
  348. line-height: .6rem;
  349. }
  350. i.active{
  351. color:#333;
  352. }
  353. }
  354. }
  355. &:active {
  356. background: #e1e1e1;
  357. }
  358. }
  359. }
  360. </style>