search.vue 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  1. <template>
  2. <view>
  3. <!-- 头部背景和搜索 -->
  4. <view>
  5. <image :src="appConfig.mobile_top_bg" class="top-image" id="top-image" mode="widthFix" @load="topImageLoad">
  6. </image>
  7. </view>
  8. <!-- 搜索 -->
  9. <router-link to="/pages/search/search" style="position: absolute; width: 100%; padding: 0 98rpx;height: 70rpx;"
  10. :style="{top: searchTop + 'rpx'}">
  11. <u-search wrap-bg-color="transparent" bg-color="#ffffff" :disabled="false" :height="62" shape="square"
  12. :show-action="false"></u-search>
  13. </router-link>
  14. <!-- 筛选 -->
  15. <view class="flex row-right bg-white p-l-30 p-r-30 p-b-20 p-t-20" @click="show = true">
  16. <u-icon name="list-dot" size="28"></u-icon>
  17. <view class="m-l-10">筛选</view>
  18. </view>
  19. <!-- 筛选弹出 -->
  20. <u-popup v-model="show" mode="right" width="80%" :closeable="true">
  21. <view class="p-20">
  22. <view v-for="(item, index) in categoryList">
  23. <view>{{ item.description }}</view>
  24. <!-- 标签 -->
  25. <view class="flex flex-wrap">
  26. <view class="tag-item" :class="{ 'tat-active': item.activeIndex == null }"
  27. @tap="changeTag(null, index)">
  28. 全部
  29. </view>
  30. <view class="tag-item" :class="{ 'tat-active': item.activeIndex == tagIndex }"
  31. v-for="(tag, tagIndex) in item.data" :key="tagIndex" @tap="changeTag(tagIndex, index)">
  32. {{ tag.name }}
  33. </view>
  34. </view>
  35. </view>
  36. <view class="confrim-btn flex w-full row-center">
  37. <button class="btn reset lg" @click="resetForm">重置</button>
  38. <button class="white btn lg" @click="refresh">确定</button>
  39. </view>
  40. </view>
  41. </u-popup>
  42. <!-- 政策列表 -->
  43. <view id="main">
  44. <mescroll-uni ref="mescrollRef" :top="top" @init="mescrollInit" @down="downCallback" @up="upCallback"
  45. :down="downOption" :up="upOption" style="left: 100px;">
  46. <view class="p-24">
  47. <view class="item" v-for="(item, index) in policyList" :key="index" @tap="goDetail(item)">
  48. <view class="font-size-28">{{item.title}}</view>
  49. <!-- <view class="flex m-t-20">
  50. <view class="flex-1">阅读次数: 1072次</view>
  51. <view class="flex-1">状态: 有效</view>
  52. </view>
  53. <view class="flex m-t-10">
  54. <view class="flex-1">支持方式: 其他</view>
  55. <view class="flex-1">支持产业: 所有产业</view>
  56. </view>
  57. <view class="flex m-t-10">
  58. <view class="flex-1">发文单位: 科技部火炬中心</view>
  59. </view> -->
  60. <view class="u-border-bottom m-t-20"></view>
  61. <view class="flex row-between p-t-20">
  62. <view class="flex primary">
  63. <u-icon name="star-fill" size="28"></u-icon>
  64. <view class="m-l-10">{{item.author}}</view>
  65. </view>
  66. <view>{{timeFormat(item.created_at)}}</view>
  67. </view>
  68. </view>
  69. </view>
  70. <loading-view v-if="showLoading" background-color="transparent" :size="50"></loading-view>
  71. </mescroll-uni>
  72. </view>
  73. <u-tabbar :list="tabarList"></u-tabbar>
  74. </view>
  75. </template>
  76. <script>
  77. import MescrollMixin from "@/components/mescroll-uni/mescroll-mixins.js";
  78. import MescrollMoreItemMixin from "@/components/mescroll-uni/mixins/mescroll-more-item.js";
  79. import {
  80. mapGetters,
  81. mapActions,
  82. mapMutations
  83. } from 'vuex'
  84. import {
  85. policyCategory,
  86. policyList
  87. } from '@/api/app'
  88. import {
  89. pxToRpx
  90. } from '@/utils/tools'
  91. import {
  92. timeFormat
  93. } from '@/utils/date'
  94. const app = getApp()
  95. const homeItem = {
  96. name: '首页'
  97. }
  98. export default {
  99. mixins: [MescrollMixin, MescrollMoreItemMixin],
  100. data() {
  101. return {
  102. statusBarHeight: 0,
  103. keyword: '',
  104. top: 0,
  105. searchTop: 0,
  106. show: false,
  107. activeIndex: 0,
  108. categoryList: [],
  109. policyList: [],
  110. downOption: {
  111. // use: false,
  112. auto: false // 不自动加载 (mixin已处理第一个tab触发downCallback)
  113. },
  114. upOption: {
  115. auto: true, // 不自动加载
  116. noMoreSize: 4, //如果列表已无数据,可设置列表的总数量要大于半页才显示无更多数据;避免列表数据过少(比如只有一条数据),显示无更多数据会不好看; 默认5
  117. empty: {
  118. icon: '/static/images/order_null.png',
  119. tip: '暂无数据~', // 提示
  120. fixed: true,
  121. top: '100rpx'
  122. }
  123. },
  124. showLoading: false
  125. }
  126. },
  127. created() {
  128. uni.getSystemInfo({
  129. success: (res) => {
  130. this.statusBarHeight = res.statusBarHeight;
  131. }
  132. });
  133. },
  134. updated: function() {
  135. this.$nextTick(() => {
  136. // 仅在整个视图都被重新渲染之后才会运行的代码
  137. setTimeout(() => {
  138. uni.createSelectorQuery().in(this).select('#main')
  139. .boundingClientRect(data => {
  140. console.log("得到布局位置信息" + JSON.stringify(data));
  141. this.top = pxToRpx(data.top)
  142. }).exec();
  143. }, 30)
  144. });
  145. },
  146. onLoad() {
  147. this.getCategoryFun()
  148. let type = uni.getStorageSync('TABBAR_TYPE')
  149. this.setTabarList({
  150. type: type
  151. })
  152. },
  153. onHide() {},
  154. onPullDownRefresh() {},
  155. methods: {
  156. ...mapMutations(["setTabarList"]),
  157. refresh() {
  158. this.show = false
  159. this.mescroll.resetUpScroll()
  160. },
  161. //筛选条件
  162. async getCategoryFun() {
  163. const {
  164. status,
  165. data
  166. } = await policyCategory({});
  167. if (status == 1) {
  168. this.categoryList = data
  169. console.log(this.categoryList)
  170. }
  171. },
  172. changeTag(tagIndex, index) {
  173. this.categoryList[index].activeIndex = tagIndex
  174. this.$forceUpdate();
  175. },
  176. resetForm() {
  177. this.categoryList = this.categoryList.map((item, index) => {
  178. item.activeIndex = null
  179. return item
  180. })
  181. },
  182. topImageLoad(e) {
  183. setTimeout(() => {
  184. uni.createSelectorQuery().in(this).select('#top-image').boundingClientRect(data => {
  185. console.log("得到布局位置信息" + JSON.stringify(data));
  186. this.searchTop = pxToRpx(data.height) - 100
  187. }).exec();
  188. }, 30)
  189. },
  190. searchTalents() {
  191. let {
  192. keyword
  193. } = this;
  194. if (!keyword) {
  195. this.$toast({
  196. title: '请输入关键字'
  197. })
  198. return;
  199. }
  200. uni.navigateTo({
  201. url: '/pages/talents/talents?keyword=' + this.keyword
  202. })
  203. },
  204. upCallback(page) {
  205. let pageNum = page.num; // 页码, 默认从1开始
  206. let pageSize = page.size; // 页长, 默认每页10条
  207. let params = {
  208. page_size: pageSize,
  209. page_no: pageNum
  210. }
  211. this.categoryList.forEach((item, index) => {
  212. if (item.activeIndex != null) {
  213. if (item.name != 'cengci') {
  214. params[item.name] = item.data[item.activeIndex].value
  215. } else {
  216. params[item.name] = item.data[item.activeIndex].name
  217. }
  218. }
  219. })
  220. console.log(this.categoryList)
  221. policyList(params).then(({
  222. data,
  223. _meta
  224. }) => {
  225. let curPageData = data;
  226. let curPageLen = curPageData.length;
  227. let hasNext = _meta.pageCount > _meta.currentPage;
  228. if (page.num == 1) this.policyList = [];
  229. this.policyList = this.policyList.concat(curPageData);
  230. this.mescroll.endSuccess(curPageLen, hasNext);
  231. })
  232. },
  233. timeFormat(time) {
  234. return timeFormat(time)
  235. },
  236. goDetail(item) {
  237. // uni.setStorageSync('policyDetail', item);
  238. uni.navigateTo({
  239. url: '/pages/policy/detail?id=' + item.id + '&title=' + item.title,
  240. })
  241. },
  242. },
  243. computed: {
  244. ...mapGetters(['appConfig', 'tabarList']),
  245. positionTop() {
  246. return this.top
  247. },
  248. }
  249. }
  250. </script>
  251. <style lang="scss">
  252. page {
  253. padding: 0;
  254. }
  255. .top-image {
  256. width: 100%;
  257. }
  258. .index-header {
  259. background-color: #E8B175;
  260. color: #fff;
  261. .header-text {
  262. min-height: 100rpx;
  263. text-align: justify;
  264. }
  265. .header-border {
  266. border-top: 1px dashed #fff;
  267. }
  268. }
  269. .item {
  270. background: #FFFFFF;
  271. box-shadow: 0px 8rpx 16rpx 2rpx rgba(0, 0, 0, 0.03);
  272. border-radius: 12rpx;
  273. opacity: 1;
  274. padding: 24rpx 34rpx;
  275. margin-bottom: 16rpx;
  276. }
  277. .tag-item {
  278. margin: 8rpx;
  279. padding: 8rpx 28rpx;
  280. background: #F7F8FA;
  281. border-radius: 8rpx 8rpx 8rpx 8rpx;
  282. opacity: 1;
  283. }
  284. .tat-active {
  285. color: #FFFFFF;
  286. background: #FEEFF5;
  287. color: #DD4250;
  288. border: 2rpx solid #DD4250;
  289. }
  290. .class-list {
  291. background-color: #fff;
  292. color: $-color-primary;
  293. .class-list-item {
  294. padding: 30rpx;
  295. .item-img {
  296. width: 50rpx;
  297. height: 50rpx;
  298. // padding: 9rpx;
  299. // background-color: #E8B175;
  300. border-radius: 8rpx;
  301. image {
  302. width: 100%;
  303. }
  304. }
  305. }
  306. }
  307. .count {
  308. border-bottom: $-solid-border;
  309. }
  310. .confrim-btn {
  311. position: fixed;
  312. bottom: 100rpx;
  313. .btn {
  314. padding: 0 80rpx;
  315. height: 84rpx;
  316. line-height: 84rpx;
  317. background-color: $-color-primary;
  318. box-shadow: 0rpx 6rpx 12rpx 2rpx rgba(243, 113, 113, 0.39);
  319. border-radius: 18rpx 18rpx 18rpx 18rpx;
  320. }
  321. .reset {
  322. background-color: #F2F2F2;
  323. color: #858585;
  324. }
  325. }
  326. </style>