index.vue 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. <template>
  2. <div class="topicSearch">
  3. <div class="searchInWeb" v-if="!mobile">
  4. <div class="title">
  5. 为您找到 {{dataList.length}} 个 "{{page.keyword}}"的相关文章
  6. </div>
  7. <div class="list" v-loading="loading">
  8. <TopicCell
  9. v-for="(art, index) of dataList"
  10. :art="art"
  11. :mobile="false"
  12. :info="art.ownerInfo"
  13. :key="art.id + 'art' + index"
  14. :formatPublichTime="formatPublichTime"
  15. :left="-20"
  16. />
  17. </div>
  18. <div class="pagination">
  19. <el-pagination background layout="prev, pager, next" :total="page.total"
  20. :page-size="page.size" @current-change="pageChange"></el-pagination>
  21. </div>
  22. </div>
  23. <div class="searchInH5" v-else>
  24. <div class="title">
  25. 搜索包含"{{page.keyword}}"的文章
  26. </div>
  27. <van-pull-refresh v-model="refreshing" @refresh="onRefresh" class="listArea" :class="{noneInWx: !$deviceType.app}">
  28. <div style="text-align: center" v-if="firstLoading">
  29. <van-loading size="24px">加载中...</van-loading>
  30. </div>
  31. <van-list
  32. v-else
  33. v-model="loading"
  34. :finished="finished"
  35. finished-text="没有更多了"
  36. @load="onLoad"
  37. :immediate-check="false"
  38. class="list"
  39. >
  40. <TopicCell
  41. v-for="(art, index) of dataList"
  42. :art="art"
  43. :mobile="mobile"
  44. :info="art.ownerInfo"
  45. :key="art.id + 'art' + index"
  46. :formatPublichTime="formatPublichTime"
  47. :left="0"
  48. />
  49. </van-list>
  50. </van-pull-refresh>
  51. </div>
  52. </div>
  53. </template>
  54. <script>
  55. import TopicCell from "@/components/user/jishuin/topicCell"
  56. import moment from "moment"
  57. export default {
  58. components: { TopicCell },
  59. head() {
  60. const {
  61. canonical = "", title = "", keywords = "", description = "", h1 = ""
  62. } = this.seoInfo
  63. return {
  64. title: title,
  65. meta: [ {
  66. 'name': 'keywords',
  67. 'content': keywords
  68. }, {
  69. 'name': 'description',
  70. 'content': description
  71. }, {
  72. 'name': 'h1',
  73. 'content': h1
  74. } ],
  75. script: [ {
  76. src: "https://res.wx.qq.com/open/js/jweixin-1.2.0.js",
  77. },
  78. {
  79. src: "https://hm.baidu.com/hm.js?18455f493c982100e5a82ec978a8d06e"
  80. },
  81. {
  82. src: "https://g.alicdn.com/de/prismplayer/2.8.2/aliplayer-h5-min.js",
  83. }
  84. ],
  85. link: [ {
  86. rel: "canonical",
  87. href: canonical
  88. }, {
  89. rel: "stylesheet",
  90. href: "https://g.alicdn.com/de/prismplayer/2.8.2/skins/default/aliplayer-min.css"
  91. }
  92. ]
  93. };
  94. },
  95. async asyncData({ $axios, params, req, app }) {
  96. const { headers: { host }, url } = req
  97. //拼接canonical
  98. let canonical = ""
  99. if (host.indexOf('local') !== -1) {
  100. canonical = 'http://' + host + url
  101. } else {
  102. canonical = 'https://' + host + url
  103. }
  104. return {
  105. title: `技术圈-程序员客栈`,
  106. mobile: app.$deviceType.isMobile(),
  107. seoInfo: {
  108. title: `技术圈-程序员客栈`,
  109. keywords: `技术圈-程序员客栈`,
  110. description: `技术圈-程序员客栈`,
  111. h1: '/',
  112. canonical
  113. }
  114. }
  115. },
  116. data() {
  117. return {
  118. baseUrl: "",
  119. jishuBaseUrl: "",
  120. keyword: "",
  121. dataList: [],
  122. page: {
  123. keyword: "",
  124. page: 1,
  125. pageSize: 20,
  126. total: 0,
  127. },
  128. loading: false,
  129. finished: false,
  130. refreshing: false,
  131. firstLoading: false, //移动端加载loading
  132. isLoading: false //控制防止一次没响应,重复请求接口
  133. };
  134. },
  135. computed: {
  136. },
  137. created() {
  138. this.page.keyword = this.$route.query.keyword || ''
  139. this.baseUrl = this.$store.state.domainConfig.siteUrl;
  140. this.jishuBaseUrl = this.$store.state.domainConfig.jishuinUrl;
  141. },
  142. mounted() {
  143. this.getList()
  144. },
  145. methods: {
  146. getList() {
  147. if (this.isLoading) {
  148. return
  149. }
  150. this.loading = true
  151. this.isLoading = true
  152. this.$axios.post('/api/community/topicList/search', this.page).then(res => {
  153. if (Number(res.data.status) === 1) {
  154. let data = res.data.data
  155. this.page.total = data.total
  156. let list = data.list || []
  157. if (this.page.page === 1 || !this.mobile) {
  158. this.dataList = [ ...list ]
  159. } else {
  160. this.dataList = [ ...this.dataList, ...list ]
  161. }
  162. if (this.mobile) {
  163. this.page.page += 1
  164. }
  165. if (this.page.total <= this.dataList.length) {
  166. this.finished = true
  167. }
  168. this.error = false
  169. }
  170. }).finally(() => {
  171. this.firstLoading = false
  172. this.refreshing = false
  173. this.isLoading = false
  174. this.$nextTick(() => {
  175. this.loading = false
  176. })
  177. })
  178. },
  179. pageChange(i) {
  180. this.page.page = i
  181. this.getList()
  182. },
  183. formatPublichTime(ts) {
  184. try {
  185. ts = moment(ts).toDate().getTime()
  186. let now = new Date().getTime()
  187. let fromNow = Math.floor((now - ts) / 1000)
  188. if (fromNow < 5 * 60) {
  189. return "刚刚";
  190. } else if (fromNow < 60 * 60) {
  191. return Math.floor(fromNow / 60) + "分钟前";
  192. } else if (fromNow < 60 * 60 * 24) {
  193. return Math.floor(fromNow / 3600) + "小时前";
  194. } else if (fromNow < 60 * 60 * 24 * 10) {
  195. return Math.floor(fromNow / 86400) + "天前";
  196. } else {
  197. return moment(ts).format("YYYY-MM-DD HH:mm")
  198. }
  199. } catch ( e ) {
  200. console.log(e)
  201. return ""
  202. }
  203. },
  204. onLoad() {
  205. this.getList()
  206. },
  207. /** 移动端下拉刷新 **/
  208. onRefresh() {
  209. console.log("refresh")
  210. // 清空列表数据
  211. this.finished = false;
  212. this.page.page = 1
  213. this.page.total = 0
  214. this.onLoad();
  215. },
  216. },
  217. };
  218. </script>
  219. <style lang='scss' scoped>
  220. @import "../../../assets/css/scssCommon";
  221. .topicSearch {
  222. .searchInWeb {
  223. background-color: #fff;
  224. width: 800px;
  225. min-width: 800px;
  226. margin: 20px auto 20px auto;
  227. padding: 20px;
  228. .title {
  229. margin-top: 20px;
  230. }
  231. .list {
  232. margin-top: 20px;
  233. min-height: 300px;
  234. }
  235. .pagination {
  236. margin-top: 70px;
  237. text-align: center;
  238. }
  239. }
  240. .searchInH5 {
  241. width: 100vw;
  242. min-width: 100vw;
  243. margin-top: -20px;
  244. .title {
  245. padding-left: pxtovw(10);
  246. height: pxtovw(40);
  247. line-height: pxtovw(40);
  248. }
  249. .list {
  250. background-color: #fff;
  251. height: calc(100% - pxtovw(40));
  252. padding: pxtovw(10);
  253. }
  254. }
  255. }
  256. </style>