reportHome.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496
  1. <template>
  2. <view class="container">
  3. <view v-show="menuCurrent === 0">
  4. <view class="menus-box">
  5. <view class="menus-item-box" @click="toReportList(key, data.value)" v-for="(data,key) in categoryList"
  6. :key="key">
  7. <view class="icon-box">
  8. <view class="iconfont icon-hetong"></view>
  9. </view>
  10. <view class="text-box">
  11. {{ key }}
  12. </view>
  13. </view>
  14. <!-- <view class="menus-item-box" @click="toReportList('二手住宅市场')">
  15. <view class="icon-box">
  16. <view class="iconfont icon-hetong"></view>
  17. </view>
  18. <view class="text-box">
  19. 二手住宅市场
  20. </view>
  21. </view>
  22. <view class="menus-item-box" @click="toReportList('住宅租赁市场')">
  23. <view class="icon-box">
  24. <view class="iconfont icon-chengshi"></view>
  25. </view>
  26. <view class="text-box">
  27. 住宅租赁市场
  28. </view>
  29. </view>
  30. <view class="menus-item-box" @click="toReportList('房地产中介行业')">
  31. <view class="icon-box">
  32. <view class="iconfont icon-zhongjie"></view>
  33. </view>
  34. <view class="text-box">
  35. 房地产中介行业
  36. </view>
  37. </view> -->
  38. </view>
  39. </view>
  40. <view v-show="menuCurrent === 1">
  41. <view class="header-box">
  42. <view class="search-box">
  43. <u-search v-model="searchForm.keyword" :clearabled="true" bg-color="#E5E5E5"
  44. :input-style="searchInputStyle" placeholder="搜索您想要的内容"
  45. @search="searchHistory(searchForm.keyword, 1)"
  46. @custom="searchHistory(searchForm.keyword, 1)"></u-search>
  47. </view>
  48. </view>
  49. <u-empty margin-top="50" mode="data" v-if="list.length === 0" iconSize="120" textSize="58" text="暂无数据">
  50. </u-empty>
  51. <view class="list-box">
  52. <view class="list-item-box" v-for="item in list" :key="item.id" @click="onClickReport(item)">
  53. <view class="image-box">
  54. <image :src="item.imgUrl" mode="aspectFill"></image>
  55. </view>
  56. <view class="info-box">
  57. <view class="title">
  58. {{item.title}}
  59. </view>
  60. <view class="time">
  61. <span class="iconfont icon-time"></span>
  62. <span>{{item.time}}</span>
  63. </view>
  64. <view class="func">
  65. <view v-if="item.free > 0" class="button free">免费</view>
  66. <view v-else-if="item.memberFree > 0" class="button member-free">会员免费</view>
  67. <view v-else :class="['button', item.status > 0 ? 'free' : 'buy']">
  68. {{item.status > 0 ? '已购买' : '立即购买'}}
  69. </view>
  70. </view>
  71. </view>
  72. </view>
  73. </view>
  74. <!-- <u-loadmore :status="status" margin-top="20" margin-bottom="20"/> -->
  75. </view>
  76. <view v-show="menuCurrent === 2">
  77. <view class="header-box">
  78. <view class="search-box">
  79. <u-search v-model="searchForm.keyword" :clearabled="true" bg-color="#E5E5E5"
  80. :input-style="searchInputStyle" placeholder="搜索您想要的内容" @search="searchMy(searchForm.keyword, 1)"
  81. @custom="searchMy(searchForm.keyword, 1)"></u-search>
  82. </view>
  83. </view>
  84. <u-empty
  85. margin-top="50"
  86. mode="data" v-if="list2.length === 0" iconSize="120" textSize="58" text="暂无数据">
  87. </u-empty>
  88. <view class="list-box">
  89. <view class="list-item-box" v-for="item in list2" :key="item.id" @click="onClickReport(item)">
  90. <view class="image-box">
  91. <image :src="item.imgUrl" mode="aspectFill"></image>
  92. </view>
  93. <view class="info-box">
  94. <view class="title">
  95. {{item.title}}
  96. </view>
  97. <view class="time">
  98. <span>购买时间:&nbsp;{{item.time}}</span>
  99. </view>
  100. <view class="func">
  101. <view class="price">实付款:{{item.price}}元</view>
  102. </view>
  103. </view>
  104. </view>
  105. </view>
  106. </view>
  107. <u-loadmore v-if="menuCurrent !== 0 && status !== 'nomore'" :status="status" margin-top="20" margin-bottom="20"
  108. @loadmore="loadMore" />
  109. <view class="bottom-block"></view>
  110. <view class="bottom-box">
  111. <view class="menu-box">
  112. <view class="menu-item-box" :class="{'is-active': menuCurrent === 0}" @click="onMenuClick(0)">
  113. <view class="iconfont icon-home"></view>
  114. <view class="text">首页</view>
  115. </view>
  116. <view class="menu-item-box" :class="{'is-active': menuCurrent === 1}" @click="onMenuClick(1)">
  117. <view class="iconfont icon-time"></view>
  118. <view class="text">我的浏览</view>
  119. </view>
  120. <view class="menu-item-box" :class="{'is-active': menuCurrent === 2}" @click="onMenuClick(2)">
  121. <view class="iconfont icon-baogao"></view>
  122. <view class="text">我的报告</view>
  123. </view>
  124. </view>
  125. </view>
  126. </view>
  127. </template>
  128. <script setup>
  129. import {
  130. ref,
  131. computed
  132. } from 'vue'
  133. import {
  134. onLoad,
  135. onReachBottom
  136. } from '@dcloudio/uni-app'
  137. import {
  138. getReportCate,
  139. loadReportHistory,
  140. loadMyReport
  141. } from '@/api/report.js'
  142. import {
  143. useReportStore
  144. } from '@/store/reportStore.js'
  145. const reportStore = useReportStore();
  146. const categoryList = ref({});
  147. const pageNum = ref(1);
  148. const status = ref('nomore');
  149. const list = ref([]);
  150. const list2 = ref([]);
  151. const listCount = ref(0);
  152. const listCount2 = ref(0);
  153. const customButtonStyle = {
  154. height: '40rpx',
  155. lineHeight: '40rpx',
  156. padding: '0 30rpx'
  157. }
  158. const searchInputStyle = {
  159. backgroundColor: '#E5E5E5'
  160. }
  161. const searchForm = ref({
  162. keyword: '',
  163. type: 0
  164. })
  165. const menuCurrent = ref(0)
  166. function onMenuClick(index) {
  167. menuCurrent.value = index;
  168. searchForm.value.keyword = ""
  169. status.value = 'loadmore'
  170. if (index === 1) {
  171. // 浏览记录
  172. searchHistory("", 1)
  173. } else if (index === 2) {
  174. // 我的报告
  175. searchMy("", 1)
  176. }
  177. }
  178. function searchHistory(keyword, pageNumber, pageSize) {
  179. status.value = 'loading'
  180. loadReportHistory({
  181. keyword,
  182. pageNumber: pageNumber,
  183. pageSize: pageSize ? pageSize : 10
  184. }).then(res => {
  185. if (res.code === 0) {
  186. if (pageNumber === 1) {
  187. list.value = res.data
  188. } else {
  189. list.value = [...list.value, ...res.data]
  190. }
  191. listCount.value = res.count
  192. if (list.value.length === res.count) {
  193. status.value = 'nomore'
  194. } else {
  195. status.value = 'loadmore'
  196. }
  197. pageNum.value = pageNumber + 1;
  198. }
  199. })
  200. }
  201. function searchMy(keyword, pageNumber, pageSize) {
  202. status.value = 'loading'
  203. loadMyReport({
  204. keyword,
  205. pageNumber: pageNumber,
  206. pageSize: pageSize ? pageSize : 10
  207. }).then(res => {
  208. if (res.code === 0) {
  209. if (pageNumber === 1) {
  210. list2.value = res.data
  211. } else {
  212. list2.value = [...list2.value, ...res.data]
  213. }
  214. listCount2.value = res.count
  215. if (list2.value.length === res.count) {
  216. status.value = 'nomore'
  217. } else {
  218. status.value = 'loadmore'
  219. }
  220. pageNum.value = pageNumber + 1;
  221. }
  222. })
  223. }
  224. function toReportList(model, val) {
  225. uni.setStorageSync("reportCate", categoryList.value[model].child);
  226. uni.navigateTo({
  227. url: `/pages/researchReport/reportList/reportList?model=${model}&value=${val}`
  228. })
  229. }
  230. async function init() {
  231. const cateRes = await getReportCate();
  232. if (cateRes.code === 0) {
  233. const result = cateRes.data.reduce((acc, curr) => {
  234. const modifiedChild = [{
  235. value: " ",
  236. label: "全部"
  237. }, // 新增的默认项(value 为空格)
  238. ...curr.child.map(child => ({
  239. value: child.code, // 将子对象的 code 改为 value
  240. label: child.name
  241. }))
  242. ];
  243. acc[curr.name] = {
  244. value: curr.code,
  245. child: modifiedChild
  246. };
  247. return acc;
  248. }, {});
  249. categoryList.value = result;
  250. reportStore.setReportCate(result);
  251. }
  252. }
  253. function onClickReport(report) {
  254. uni.navigateTo({
  255. url: `/pages/reportDetail/reportDetail?id=${report.id}&title=${report.title}`
  256. })
  257. }
  258. function loadMore() {
  259. if (menuCurrent.value === 1) {
  260. if (list.value.length === listCount) {
  261. return
  262. }
  263. searchHistory(searchForm.value.keyword, pageNum.value)
  264. } else {
  265. if (list2.value.length === listCount2) {
  266. return
  267. }
  268. searchMy(searchForm.value.keyword, pageNum.value)
  269. }
  270. }
  271. onReachBottom(() => {
  272. loadMore()
  273. })
  274. onLoad((load) => {
  275. // console.log(load,"reporthome")
  276. if (load.menuCurrent) {
  277. menuCurrent.value = Number(load.menuCurrent)
  278. }
  279. init()
  280. })
  281. </script>
  282. <style lang="scss" scoped>
  283. $image-width: 230rpx;
  284. .container {
  285. height: 100vh;
  286. width: 100vw;
  287. background-color: $uni-text-color-inverse;
  288. .header-box {
  289. padding: 0 20rpx;
  290. background-color: $uni-text-color-inverse;
  291. @include topMagnet();
  292. }
  293. .search-box {
  294. margin-bottom: 20rpx;
  295. ::v-deep(.u-search) {
  296. background-color: #e5e5e5;
  297. border-radius: 50rpx;
  298. .u-action {
  299. width: 18%;
  300. background-color: $uni-color-primary;
  301. border-radius: 50rpx;
  302. color: $uni-text-color-inverse;
  303. margin-right: 8rpx;
  304. font-size: 28rpx;
  305. line-height: 50rpx;
  306. letter-spacing: 3rpx;
  307. text-align: center;
  308. }
  309. }
  310. }
  311. .list-box {
  312. padding: 0 20rpx;
  313. .list-item-box {
  314. padding: 30rpx 20rpx;
  315. display: flex;
  316. gap: 20rpx;
  317. height: 210rpx;
  318. border-bottom: 5rpx solid #E6E6E6;
  319. &:active {
  320. background-color: $uni-bg-color-hover;
  321. }
  322. .image-box {
  323. width: $image-width;
  324. image {
  325. width: $image-width;
  326. flex: 0 0 $image-width;
  327. height: 100%;
  328. border-radius: $uni-card-border-radius;
  329. }
  330. }
  331. .info-box {
  332. .title {
  333. font-size: $uni-title-font-size-2;
  334. font-weight: bold;
  335. line-height: 40rpx;
  336. margin-bottom: 15rpx;
  337. @include text-line-overflow(2);
  338. }
  339. .time {
  340. font-size: $uni-font-size-2;
  341. color: $uni-text-color-grey;
  342. .iconfont {
  343. font-size: $uni-font-size-2;
  344. padding-right: 10rpx;
  345. }
  346. }
  347. .func {
  348. display: flex;
  349. justify-content: flex-end;
  350. font-size: $uni-font-size-2;
  351. font-weight: bold;
  352. .button {
  353. text-align: center;
  354. width: 130rpx;
  355. }
  356. .price {
  357. color: $uni-color-error;
  358. font-size: $uni-title-font-size-2;
  359. }
  360. .buy {
  361. padding: 6rpx 25rpx;
  362. background-color: $uni-color-error;
  363. border-radius: $uni-card-border-radius;
  364. color: $uni-text-color-inverse;
  365. }
  366. .free {
  367. padding: 6rpx 25rpx;
  368. background-color: $uni-color-primary;
  369. border-radius: $uni-card-border-radius;
  370. color: $uni-text-color-inverse;
  371. }
  372. .member-free {
  373. padding: 10rpx 20rpx;
  374. @include backgroundImg('http://www.gzrea.org.cn:8543/icon/wxmp/bg-label.png');
  375. color: $uni-text-color;
  376. }
  377. }
  378. }
  379. }
  380. }
  381. .menus-box {
  382. padding: 0 20rpx;
  383. .menus-item-box {
  384. width: 100%;
  385. padding: 35rpx 50rpx;
  386. margin-bottom: 35rpx;
  387. display: flex;
  388. gap: 30rpx;
  389. align-items: center;
  390. background-color: #006AF4;
  391. border-radius: $uni-card-border-radius;
  392. &:active {
  393. background-color: #005AF4;
  394. }
  395. .icon-box {
  396. width: 40%;
  397. text-align: center;
  398. width: 100rpx;
  399. height: 100rpx;
  400. line-height: 100rpx;
  401. text-align: center;
  402. border-radius: 50%;
  403. border: 3rpx solid $uni-text-color-inverse;
  404. background-color: #004DC9;
  405. .iconfont {
  406. font-size: 60rpx;
  407. color: $uni-text-color-inverse;
  408. }
  409. }
  410. .text-box {
  411. font-size: 50rpx;
  412. font-weight: bold;
  413. color: $uni-text-color-inverse;
  414. }
  415. }
  416. }
  417. .bottom-block {
  418. // height: 112rpx;
  419. height: calc(112rpx + env(safe-area-inset-bottom, 0));
  420. }
  421. .bottom-box {
  422. padding: 5rpx 20rpx;
  423. background-color: $uni-bg-color-grey;
  424. border: 1rpx solid #E9E9E9;
  425. padding-bottom: calc(5rpx + env(safe-area-inset-bottom, 0));
  426. @include bottomMagnet();
  427. .menu-box {
  428. height: 100rpx;
  429. display: flex;
  430. align-items: center;
  431. .menu-item-box {
  432. width: calc(100% / 3);
  433. text-align: center;
  434. .iconfont {
  435. font-size: 55rpx;
  436. }
  437. .text {
  438. font-size: $uni-font-size-2;
  439. }
  440. }
  441. .is-active {
  442. color: $uni-color-primary;
  443. }
  444. }
  445. }
  446. }
  447. </style>