index.jsx 8.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. import { useEffect, useState } from 'react'
  2. import Taro from '@tarojs/taro'
  3. import withLayout from '@/layout'
  4. import { ScrollView, Image } from '@tarojs/components'
  5. import Disclaimer from '@/components/Disclaimer'
  6. import { getImgURL } from '@/utils/image'
  7. import { formateLeftTime } from '@/utils/tools'
  8. import { fetch } from '@/utils/request'
  9. import { API_SPECIAL_ROOM_LIST } from '@/constants/api'
  10. import '@/assets/css/iconfont.css'
  11. import './index.scss'
  12. const defaultRuleImage = 'https://yz-websit.oss-cn-hangzhou.aliyuncs.com/xlk/index-icon19.jpg'
  13. export default withLayout((props) => {
  14. const { city } = props
  15. const [PageList, setPageList] = useState([])
  16. const [IsPull, setPull] = useState(false)
  17. const [pageNumber, setPageNumber] = useState(1)
  18. const [HasNextPage, setHasNextPage] = useState(true)
  19. useEffect(() => {
  20. GetPageList()
  21. }, [pageNumber])
  22. const PageRefresh = () => { // 页面下拉刷新回调
  23. setPull(true)
  24. }
  25. const GetPageList = () => {
  26. setHasNextPage(false)
  27. fetch({ url: API_SPECIAL_ROOM_LIST, method: 'get', payload: { pageNumber, pageSize: 10, cityId: city?.id } }).then((res) => {
  28. setPageList(pageNumber === 1 ? res.records || [] : PageList.concat(res.records || []))
  29. setHasNextPage(res.current < res.pages)
  30. setPull(false)
  31. })
  32. }
  33. const PageLoadMore = () => { // 页面上拉加载更多
  34. if (HasNextPage) {
  35. setPageNumber(pageNumber + 1)
  36. }
  37. }
  38. useEffect(() => { // 下拉刷新触发
  39. if (IsPull) {
  40. if (pageNumber === 1) {
  41. GetPageList()
  42. } else {
  43. setPageNumber(1)
  44. }
  45. }
  46. }, [IsPull])
  47. const goto = (it) => {
  48. Taro.navigateTo({
  49. url: `/pages/index/buildingDetail/index?id=${it.buildingId}`
  50. })
  51. }
  52. return (
  53. <view className='Page specialPriceHouse'>
  54. <ScrollView scroll-y refresher-enabled refresher-triggered={IsPull} onrefresherrefresh={PageRefresh} onscrolltolower={PageLoadMore} refresher-background='#f8f8f8'>
  55. <view className='PageContent'>
  56. {/* 主图 */}
  57. <view className='MainPicture'>
  58. <Image mode='widthFix' src={defaultRuleImage}></Image>
  59. </view>
  60. {/* 列表 */}
  61. <view className='List'>
  62. {
  63. PageList.map((item, index) => {
  64. const mainImg = getImgURL(item?.buildingListImg?.length ? item.buildingListImg[0].url : null)
  65. const price = item.price || '价格待定'
  66. const shareNum = item.shareList?.total || 0
  67. const uvNum = item.uvList?.length || 0
  68. // 最多6个
  69. const tags = (item.buildingTag || []).map(x => x.tagName).slice(0, 6)
  70. //
  71. const specialRoomList = item.specialRoomList || []
  72. return (
  73. <view key={item.buildingId}>
  74. <view className='Title'>
  75. <view>
  76. <text className='iconfont icon-shoucang'></text>
  77. <text>{index + 1 > 9 ? index + 1 : `0${index + 1}`}</text>
  78. <text className='iconfont icon-shoucang'></text>
  79. </view>
  80. </view>
  81. <view className='InfoContent'>
  82. <view className='Img' onClick={() => goto(item)}>
  83. <Image mode='scaleToFill' src={mainImg} className='centerLabel'></Image>
  84. {
  85. item.panoramaList.length > 0 &&
  86. <Image mode='heightFix' className='Tips Vr' src={require('@/assets/index-icon18.png')} />
  87. }
  88. {
  89. item.videoUrl !== null &&
  90. <Image mode='heightFix' className='Tips Video' src={require('@/assets/index-icon19.png')} />
  91. }
  92. </view>
  93. <view className='Name flex-h' onClick={() => goto(item)}>
  94. <view className='flex-item'>
  95. <text>{item.buildingName}</text>
  96. </view>
  97. <text></text>
  98. <text>{price}</text>
  99. </view>
  100. <text className='Address' onClick={() => goto(item)}>{item.address}</text>
  101. <view className='Tag' onClick={() => goto(item)}>
  102. {
  103. tags.map((x) => (<text key={x}>{x}</text>))
  104. }
  105. </view>
  106. <view className='Views flex-h' onClick={() => goto(item)}>
  107. <view className='flex-item'>
  108. <text className='iconfont icon-fenxiang'></text>
  109. <text>{`${shareNum} 次分享`}</text>
  110. </view>
  111. {
  112. uvNum > 0 && (
  113. <view className='Icons'>
  114. {
  115. item.uvList.map((x) => (
  116. <view key={x.uvId}>
  117. <Image mode='scaleToFill' src={getImgURL(x.photoOravatar)} className='centerLabel'></Image>
  118. </view>
  119. ))
  120. }
  121. </view>
  122. )
  123. }
  124. <text>{`...${uvNum}人围观`}</text>
  125. </view>
  126. <view className='SpecialList'>
  127. <ScrollView scrollX>
  128. {
  129. specialRoomList.map((it) => {
  130. const unitPrice = it.area ? it.currentPrice / it.area : undefined
  131. const unitW = unitPrice ? `${Number(unitPrice).toFixed(0)}/㎡` : '单价待定'
  132. const currentW = it.currentPrice ? `${Number(it.currentPrice / 10000).toFixed(1)}万` : '待定'
  133. const originalW = it.originalPrice ? `${Number(it.originalPrice / 10000).toFixed(1)}万` : '待定'
  134. const thriftW = it.thriftPrice ? `省${Number(it.thriftPrice / 10000).toFixed(1)}万` : '待定'
  135. const leftTime = formateLeftTime(new Date(it.endTime) - new Date(), 'min');
  136. return (
  137. <view className='ListItem' key={it.specialRoomId}>
  138. <text className='Tips'>{thriftW}</text>
  139. <view className='Price'>
  140. <text>{currentW}</text>
  141. <text>{originalW}</text>
  142. </view>
  143. <text className='Time'>{`距结束 ${leftTime}`}</text>
  144. <text className='HouseType'>{`${it.unitType} ${unitW}`}</text>
  145. <text className='DoorNumber'>{it.roomName}</text>
  146. </view>
  147. )
  148. })
  149. }
  150. </ScrollView>
  151. </view>
  152. </view>
  153. </view>
  154. )
  155. })
  156. }
  157. </view>
  158. {/* <view className='Bottom'>
  159. <view>
  160. <view>
  161. <text className='iconfont icon-shengming'></text>
  162. <text>免责声明</text>
  163. </view>
  164. <view>
  165. <text>&emsp;&emsp;以上价格仅供参考,具体一房一价的信息以售楼处展示为准。房屋位置交通、医疗、教育、商业等配套信息,来源于第三方不作为要约,仅供参考,双方具体权利义务应以法律规定及买卖合同约定为准。本平台对项目周边文化教育的介绍旨在提供相关信息1 意味着信息发布方对就学安排作出承诺。相关教育资首页信息存在调整的可能,应以政府教育主管部门门及办学颁布的政策规定为准。详情请仔细阅读</text>
  166. <text className='active'>《新联康使用免责条款》</text>
  167. </view>
  168. </view>
  169. </view> */}
  170. <Disclaimer />
  171. </view>
  172. </ScrollView>
  173. </view>
  174. )
  175. })