Search.vue 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. <template>
  2. <div class="search-container">
  3. <search-input ref="search" @submit="doSearch" @recovery="doSearch"></search-input>
  4. <div class="search-result-container">
  5. <div class="sort-list">
  6. <span
  7. class="sort-item"
  8. v-for="(item, index) in sortTypeList"
  9. :key="index"
  10. @click="sortAndSearch(item, index)"
  11. :class="{ active: item.active }"
  12. >
  13. <span class="sort-text">{{ item.label }}</span>
  14. <span class="sort-icon" :class="item.sort ? 'el-icon-top' : 'el-icon-bottom'"></span>
  15. </span>
  16. </div>
  17. <div class="search-result-list" v-loading="listState.loading">
  18. <doc-card
  19. v-for="(item, index) in listState.list"
  20. :key="index"
  21. :title="item.docName"
  22. :desc="item.docSummary"
  23. :docType="item.docFileType"
  24. :price="item.price"
  25. :highlightKey="highlightKey"
  26. :subInfo="calcSubInfo(item)"
  27. @onClick="toDocDetail(item)"
  28. />
  29. <no-data v-if="listState.list.length === 0 && listState.loaded"></no-data>
  30. </div>
  31. <div class="search-pagination">
  32. <el-pagination
  33. background
  34. layout="prev, pager, next, ->, total"
  35. :hide-on-single-page="true"
  36. :current-page="listState.pageNum"
  37. :page-size="listState.pageSize"
  38. :total="listState.total"
  39. @current-change="onPageChange"
  40. >
  41. </el-pagination>
  42. </div>
  43. </div>
  44. </div>
  45. </template>
  46. <script>
  47. import { Icon, Pagination } from 'element-ui'
  48. import SearchInput from '@/components/Search'
  49. import DocCard from '@/components/doc-item-card/Card'
  50. import NoData from '@/components/NoData'
  51. import { getSearch } from '../api/modules/search'
  52. import { formatSize, dateFormatter } from '@/utils/'
  53. import { mixinBackground } from '@/utils/mixins'
  54. export default {
  55. name: 'seach',
  56. mixins: [mixinBackground],
  57. components: {
  58. [Icon.name]: Icon,
  59. [Pagination.name]: Pagination,
  60. SearchInput,
  61. DocCard,
  62. NoData
  63. },
  64. data () {
  65. return {
  66. sortTypeList: [
  67. {
  68. type: 'tSort',
  69. label: '上传时间',
  70. sort: 0,
  71. active: true
  72. },
  73. {
  74. type: 'dSort',
  75. label: '下载次数',
  76. sort: 0,
  77. active: false
  78. },
  79. {
  80. type: 'vSort',
  81. label: '浏览人数',
  82. sort: 0,
  83. active: false
  84. }
  85. ],
  86. searchQuery: {
  87. type: '',
  88. text: ''
  89. },
  90. listState: {
  91. loaded: false, // 是否已经搜索过
  92. loading: false,
  93. pageNum: 1, // 当前页
  94. pageSize: 10, // 每页多少条数据
  95. total: 0, // 一共多少条数据
  96. list: [] // 查询请求返回的数据
  97. }
  98. }
  99. },
  100. computed: {
  101. activeSortList () {
  102. return this.sortTypeList.find(item => {
  103. return item.active
  104. })
  105. },
  106. highlightKey () {
  107. return this.searchQuery.text.split(/\s+/)
  108. }
  109. },
  110. methods: {
  111. getLoginStatus: function () {
  112. console.log(loginflag)
  113. },
  114. // 恢复数据至第一次请求的状态(页码等)
  115. resetListState () {
  116. const state = {
  117. loaded: false,
  118. loading: false,
  119. pageNum: 1,
  120. list: []
  121. }
  122. Object.assign(this.listState, state)
  123. },
  124. doSearch (search) {
  125. if (search) {
  126. Object.assign(this.searchQuery, search)
  127. } else {
  128. this.searchQuery.type = this.$refs.search.type
  129. this.searchQuery.text = this.$refs.search.input
  130. }
  131. this.getList()
  132. },
  133. async getList () {
  134. if (!this.searchQuery.text) return
  135. const query = {
  136. keyWord: this.searchQuery.text,
  137. tag: this.searchQuery.type === '全部' ? '' : this.searchQuery.type,
  138. sort: this.activeSortList.type,
  139. num: this.listState.pageNum,
  140. size: this.listState.pageSize
  141. }
  142. console.log(query)
  143. this.listState.loading = true
  144. this.listState.loaded = false
  145. const r = await getSearch(query)
  146. this.listState.loading = false
  147. this.listState.loaded = true
  148. const res = r.data
  149. if (res.error_code === 0) {
  150. this.listState.total = res.data.total
  151. this.listState.list = res.data.list || []
  152. }
  153. },
  154. sortAndSearch (item, index) {
  155. if (item.active) {
  156. // 改变sort
  157. // item.sort = item.sort ? 0 : 1
  158. } else {
  159. this.sortTypeList.forEach(s => {
  160. s.active = false
  161. })
  162. item.active = true
  163. }
  164. this.resetListState()
  165. this.doSearch()
  166. },
  167. toDocDetail (item) {
  168. const { docId: id } = item
  169. window.open(`./content/${id}`) // 打开新窗口
  170. // this.$router.push({
  171. // name: 'content',
  172. // params: { id }
  173. // })
  174. },
  175. onPageChange (p) {
  176. this.listState.pageNum = p
  177. this.doSearch()
  178. },
  179. calcSubInfo (item) {
  180. const { docFileSize: size, downTimes, uploadDate, docPageSize } = item
  181. const subInfoArr = []
  182. if (uploadDate !== undefined) {
  183. const data = uploadDate.replace(/-/g, '/')
  184. subInfoArr.push(dateFormatter(data, 'yyyy/MM/dd'))
  185. }
  186. if (downTimes !== undefined) {
  187. subInfoArr.push(`${downTimes}次下载`)
  188. }
  189. if (docPageSize !== undefined) {
  190. subInfoArr.push(`共${docPageSize}页`)
  191. }
  192. if (size !== undefined) {
  193. subInfoArr.push(formatSize(size))
  194. }
  195. return subInfoArr
  196. }
  197. }
  198. }
  199. </script>
  200. <style lang="scss" scoped>
  201. .search-container {
  202. padding-top: 48px;
  203. }
  204. .search-result-container {
  205. margin: 0 auto;
  206. .sort-list {
  207. display: flex;
  208. align-items: center;
  209. margin: 18px;
  210. height: 48px;
  211. border-radius: 4px;
  212. background: #F5F6F7;
  213. .sort-item {
  214. display: flex;
  215. align-items: center;
  216. padding: 0 20px;
  217. height: 100%;
  218. font-size: 14px;
  219. color: #686868;
  220. cursor: pointer;
  221. .sort-text {
  222. margin-right: 4px;
  223. }
  224. .sort-icon {
  225. color: #aaa;
  226. }
  227. &.active {
  228. .sort-text,
  229. .sort-icon {
  230. color: $color-text--highlight;
  231. }
  232. }
  233. &:hover {
  234. .sort-text,
  235. .sort-icon {
  236. color: $color-text--highlight;
  237. }
  238. }
  239. }
  240. }
  241. .search-result-list {
  242. min-height: 500px;
  243. }
  244. .search-pagination {
  245. margin-top: 28px;
  246. padding-bottom: 60px;
  247. text-align: right;
  248. }
  249. }
  250. </style>