search.vue 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. <route lang="json5">
  2. {
  3. layout: 'default',
  4. style: {
  5. navigationStyle: 'custom',
  6. },
  7. }
  8. </route>
  9. <script lang="ts" setup>
  10. // 必须导入需要用到的页面生命周期(即使在当前页面上没有直接使用到)
  11. // eslint-disable-next-line unused-imports/no-unused-imports
  12. import { onPageScroll, onReachBottom } from '@dcloudio/uni-app'
  13. import { useQueue } from 'wot-design-uni'
  14. import useZPaging from 'z-paging/components/z-paging/js/hooks/useZPaging.js'
  15. import { categoryList, getList } from '@/api/product'
  16. import { t } from '@/locale'
  17. import { goBack } from '@/utils/page'
  18. defineOptions({
  19. name: 'SearchPage', // 搜索
  20. })
  21. // 获取屏幕边界到安全区域距离
  22. const systemInfo = uni.getSystemInfoSync()
  23. const safeAreaInsets = systemInfo.safeAreaInsets
  24. // z-paging
  25. const paging = ref(null)
  26. // 类似mixins,如果是页面滚动务必要写这一行,并传入当前ref绑定的paging,注意此处是paging,而非paging.value
  27. useZPaging(paging)
  28. // 搜索关键词
  29. const formData = ref<any>({
  30. storeName: '',
  31. prices: 0,
  32. cateId: 0,
  33. sortWay: 0, // 3=销量升序,4=销量降序
  34. })
  35. const { closeOutside } = useQueue()
  36. const option1 = ref<Record<string, any>[]>([
  37. { label: t('home.priceTab.allPrice'), value: 0 },
  38. {
  39. label: t('home.priceTab.300spot'),
  40. value: 300,
  41. minPrice: 0,
  42. maxPrice: 300,
  43. },
  44. {
  45. label: t('home.priceTab.500spot'),
  46. value: 500,
  47. minPrice: 300,
  48. maxPrice: 500,
  49. },
  50. {
  51. label: t('home.priceTab.1000spot'),
  52. value: 1000,
  53. minPrice: 500,
  54. maxPrice: 1000,
  55. },
  56. {
  57. label: t('home.priceTab.2000spot'),
  58. value: 2000,
  59. minPrice: 1000,
  60. maxPrice: 2000,
  61. },
  62. ])
  63. const option2 = ref<Record<string, any>[]>([
  64. { label: t('search.filterCategory'), value: 0 },
  65. ])
  66. async function getCategoryList() {
  67. const res = await categoryList({ page: 1, size: 20 })
  68. console.log(res)
  69. option2.value = [...option2.value, ...res.data.list.map((i: any) => ({ label: i.name, value: i.id }))]
  70. }
  71. // 搜索结果
  72. const dataList = ref([])
  73. async function queryList(pageNo: number, pageSize: number) {
  74. try {
  75. const currentTab = option1.value.find((i: any) => i.value === formData.value.prices) || option1.value[0]
  76. console.log(currentTab)
  77. const minPrice = currentTab?.minPrice ?? undefined
  78. const maxPrice = currentTab?.maxPrice ?? undefined
  79. const params = {
  80. page: pageNo,
  81. size: pageSize,
  82. storeName: formData.value.storeName,
  83. cateId: formData.value.cateId ? formData.value.cateId : undefined,
  84. sortWay: formData.value.sortWay === 1 ? 3 : formData.value.sortWay === -1 ? 4 : 0,
  85. minPrice,
  86. maxPrice,
  87. }
  88. const res = await getList(params)
  89. paging.value.complete(res.data.list)
  90. }
  91. catch (err) {
  92. console.log(err)
  93. paging.value.complete(false)
  94. }
  95. }
  96. onLoad(() => {
  97. getCategoryList()
  98. })
  99. </script>
  100. <template>
  101. <z-paging ref="paging" v-model="dataList" use-page-scroll @query="queryList" @click="closeOutside">
  102. <template #top>
  103. <view class="bg-white" :style="{ paddingTop: `${safeAreaInsets?.top}px` }">
  104. <wd-navbar :bordered="false">
  105. <template #title>
  106. <view class="content">
  107. <view class="back">
  108. <wd-icon name="thin-arrow-left" size="32rpx" @click="goBack" />
  109. </view>
  110. <input v-model.trim="formData.storeName" class="search-input" type="text" :placeholder="$t('search.placeholder')" @confirm="queryList(1, 20)">
  111. <wd-icon name="search" custom-class="search-icon" color="#999" size="32rpx" />
  112. </view>
  113. </template>
  114. </wd-navbar>
  115. <view class="flex bg-white text-center">
  116. <wd-drop-menu class="flex-1">
  117. <wd-drop-menu-item v-model="formData.prices" :options="option1" @change="queryList(1, 20)" />
  118. </wd-drop-menu>
  119. <wd-drop-menu class="flex-1">
  120. <wd-drop-menu-item v-model="formData.cateId" :options="option2" @change="queryList(1, 20)" />
  121. </wd-drop-menu>
  122. <view class="flex-1">
  123. <wd-sort-button v-model="formData.sortWay" :title="t('search.filterSellers')" @change="queryList(1, 20)" />
  124. </view>
  125. </view>
  126. </view>
  127. </template>
  128. <view class="px-24rpx pb-24rpx">
  129. <view class="grid grid-cols-2 gap-22rpx">
  130. <product v-for="(item, index) in dataList" :key="index" :height="340" :item="item" />
  131. </view>
  132. </view>
  133. </z-paging>
  134. </template>
  135. <style>
  136. page {
  137. background: #fff;
  138. }
  139. </style>
  140. <style lang="scss" scoped>
  141. :deep() {
  142. .wd-navbar__title {
  143. margin: 0;
  144. max-width: 100%;
  145. .content {
  146. box-sizing: border-box;
  147. position: relative;
  148. height: 100%;
  149. display: flex;
  150. align-items: center;
  151. padding: 19rpx 25rpx 19rpx 0;
  152. .back {
  153. padding: 0 25rpx;
  154. }
  155. .search-input {
  156. flex: 1;
  157. height: 100%;
  158. text-align: left;
  159. background: rgba(245, 245, 245, 0.6);
  160. border-radius: 8rpx;
  161. border: 1px solid #efefef;
  162. font-size: 28rpx;
  163. padding: 16rpx 64rpx 16rpx 22rpx;
  164. font-weight: normal;
  165. &:active {
  166. border-color: rgba(230, 27, 40, 0.65);
  167. }
  168. &:focus-within {
  169. border-color: rgba(230, 27, 40, 0.65) !important;
  170. }
  171. &:focus-visible {
  172. border-color: rgba(230, 27, 40, 0.65) !important;
  173. }
  174. }
  175. .search-icon {
  176. position: absolute;
  177. right: 42rpx;
  178. top: 50%;
  179. transform: translateY(-50%);
  180. }
  181. }
  182. }
  183. }
  184. </style>