index.vue 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. <template>
  2. <view class="search-page">
  3. <!-- 搜索输入框 -->
  4. <u-input placeholder="请输入搜索的服务" prefixIcon="search" v-model="value" class="rounded-input"
  5. @confirm="handleSearch"></u-input>
  6. <!-- 历史记录 -->
  7. <view class="history-search">
  8. <view class="history-search-title">历史搜索</view>
  9. <view>
  10. <image src="@/static/img/delete-bin-6-fill@1x.png" mode="widthFix" class="delete-icon"></image>
  11. 清空
  12. </view>
  13. </view>
  14. <!-- 瀑布流展示区域 -->
  15. <view class="home-ranking">
  16. <ServIces :leftList="leftList" :rightList="rightList" :ValueZoneSwiper="ValueZoneSwiper" v-if="userType == 1">
  17. </ServIces>
  18. </view>
  19. <!-- 加载更多组件 -->
  20. <up-loadmore style="margin-top: 40rpx" :status="loadmoreInfo.status" :loadmoreText="loadmoreInfo.loadingText"
  21. :loadingText="loadmoreInfo.loadmoreText" :nomoreText="loadmoreInfo.nomoreText" @loadmore="handleLoadmore"
  22. v-if="userType == 1" />
  23. </view>
  24. </template>
  25. <script setup>
  26. import { ref, reactive, onMounted, watch } from 'vue'
  27. import { onShow, onReachBottom } from '@dcloudio/uni-app'
  28. import { volTierName } from '@/api/volunteerDetailsApi/details.js'
  29. import RankingList from '@/pages/common/rankingList/index.vue'
  30. import ServIces from '@/components/Services/services.vue'
  31. import store from '@/store'
  32. // 搜索关键词
  33. const value = ref('')
  34. // 瀑布流左右列表数据
  35. const rightList = ref([])
  36. const leftList = ref([])
  37. const ValueZoneSwiper = ref([''])
  38. // 用户类型
  39. const userType = uni.getStorageSync('userType') || 1; //读取本地存储
  40. // 添加搜索定时器引用
  41. const searchTimer = ref(null);
  42. // 分页参数配置
  43. const pages = ref({
  44. current: 1,
  45. pageSize: 10,
  46. total: 0,
  47. serviceCategory: '',
  48. businessTierName: '' // 添加搜索关键词参数
  49. })
  50. // 加载更多状态配置
  51. const loadmoreInfo = ref({
  52. status: 'loadmore',
  53. loadingText: '努力加载中...',
  54. loadmoreText: '点击加载更多~',
  55. nomoreText: '已经到底啦~',
  56. })
  57. /**
  58. * 处理搜索确认事件
  59. */
  60. const handleSearch = () => {
  61. console.log('触发搜索:', value.value); // 添加日志
  62. // 重置页码
  63. pages.value.current = 1
  64. // 执行搜索
  65. getList()
  66. }
  67. /**
  68. * 加载更多数据
  69. */
  70. async function handleLoadmore(e) {
  71. if (
  72. pages.value.current < Math.ceil(pages.value.total / pages.value.pageSize)
  73. ) {
  74. pages.value.current += 1
  75. loadmoreInfo.value.status = 'loading'
  76. await getList()
  77. } else {
  78. loadmoreInfo.value.status = 'nomore'
  79. }
  80. }
  81. /**
  82. * 获取列表数据
  83. * 支持分页和关键词搜索
  84. */
  85. const getList = async () => {
  86. try {
  87. loadmoreInfo.value.status = 'loading'
  88. // 获取地址信息
  89. const address = store.state.user.addressInfo
  90. const { cityCode, latitude, longitude } = address
  91. // 构建请求参数 - 根据API接口定义调整参数
  92. const params = {
  93. pageNum: pages.value.current,
  94. pageSize: pages.value.pageSize,
  95. serviceCategory: pages.value.serviceCategory || '',
  96. businessManagementId: 0,
  97. // API接口使用的模糊搜索参数
  98. businessTierName: value.value, // 业务名称搜索参数
  99. // 地址相关参数
  100. provinceName: cityCode.data[0], // 省
  101. provinceCode: cityCode.code[0],
  102. cityName: cityCode.data[1], // 市
  103. cityCode: cityCode.code[1],
  104. districtName: cityCode.data[2],
  105. districtCode: cityCode.code[2],
  106. latitude,
  107. longitude,
  108. }
  109. console.log('搜索参数:', params); // 添加日志查看参数
  110. // 调用API获取数据
  111. const res = await volTierName(params)
  112. if (!res || !res.rows) {
  113. return
  114. }
  115. // 如果是第一页,先清空数据
  116. if (pages.value.current === 1) {
  117. leftList.value = []
  118. rightList.value = []
  119. }
  120. // 每次都追加新数据 - 左右瀑布流交替分配
  121. res.rows.forEach((item, index) => {
  122. index % 2 !== 0 ? rightList.value.push(item) : leftList.value.push(item)
  123. })
  124. // 更新分页和加载状态
  125. pages.value.total = res.total
  126. if (pages.value.current >= Math.ceil(res.total / pages.value.pageSize)) {
  127. loadmoreInfo.value.status = 'nomore'
  128. } else {
  129. loadmoreInfo.value.status = 'loadmore'
  130. }
  131. } catch (error) {
  132. // 错误处理
  133. leftList.value = []
  134. rightList.value = []
  135. loadmoreInfo.value.status = 'loadmore'
  136. pages.value.total = 0
  137. console.error('Error fetching data:', error)
  138. }
  139. }
  140. /**
  141. * 页面滚动到底部触发加载更多
  142. */
  143. onReachBottom(() => {
  144. if (
  145. pages.value.current < Math.ceil(pages.value.total / pages.value.pageSize)
  146. ) {
  147. pages.value.current = pages.value.current + 1
  148. loadmoreInfo.value.status = 'nomore'
  149. getList()
  150. }
  151. })
  152. /**
  153. * 组件挂载时获取初始数据
  154. */
  155. onMounted(() => {
  156. // 获取路由参数
  157. const query = uni.getLaunchOptionsSync().query || {}
  158. if (query && query.businessTierName) {
  159. value.value = query.businessTierName
  160. }
  161. // 加载数据
  162. getList()
  163. })
  164. /**
  165. * 监听搜索输入变化,自动触发搜索
  166. */
  167. watch(value, (newVal) => {
  168. console.log('输入变化:', newVal); // 添加日志
  169. // 重置页码
  170. pages.value.current = 1
  171. // 延迟搜索,避免频繁请求
  172. clearTimeout(searchTimer.value);
  173. searchTimer.value = setTimeout(() => {
  174. getList()
  175. }, 500)
  176. })
  177. </script>
  178. <style scoped lang="scss">
  179. .search-page {
  180. /* 搜索输入框样式 */
  181. .rounded-input {
  182. width: 682rpx;
  183. height: 64rpx;
  184. overflow: hidden;
  185. border-radius: 36rpx;
  186. background: #F4F4F4;
  187. margin-top: 18rpx;
  188. margin-left: 36rpx;
  189. margin-right: 32rpx;
  190. }
  191. .history-search {
  192. display: flex;
  193. justify-content: space-between;
  194. align-items: center;
  195. margin-top: 18rpx;
  196. margin-left: 44rpx;
  197. margin-right: 44rpx;
  198. .history-search-title {
  199. width: 120rpx;
  200. height: 36rpx;
  201. font-family: PingFang SC;
  202. font-size: 30rpx;
  203. font-weight: 500;
  204. line-height: 36rpx;
  205. letter-spacing: normal;
  206. color: #313131;
  207. }
  208. .delete-icon {
  209. /* 自动布局子元素 */
  210. width: 24rpx;
  211. height: 24rpx;
  212. font-family: PingFang SC;
  213. font-size: 24rpx;
  214. font-weight: normal;
  215. line-height: 48rpx;
  216. text-align: right;
  217. letter-spacing: normal;
  218. color: #7B7B7B;
  219. }
  220. }
  221. /* 瀑布流容器样式 */
  222. .home-ranking {
  223. margin-top: 30rpx;
  224. margin-left: 11rpx;
  225. margin-right: 17rpx;
  226. margin-bottom: 120rpx;
  227. }
  228. }
  229. </style>