index.vue 7.7 KB

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