index.vue 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. <script setup lang="ts">
  2. import router from '@/router'
  3. definePage({
  4. name: 'xsb-search',
  5. islogin: false,
  6. style: {
  7. navigationBarTitleText: '搜索',
  8. },
  9. })
  10. const { searchList, SelectShopInfo } = storeToRefs(useSysXsbStore())
  11. const searchText = ref()
  12. const tabbarlist = ref([
  13. { name: '综合', id: 0 },
  14. { name: '销量', id: 1 },
  15. { name: '价格', id: 2 },
  16. ])
  17. const activeTab = ref(0)
  18. const { confirm: showConfirm } = useGlobalMessage()
  19. const { userInfo } = storeToRefs(useUserStore())
  20. const { data, send, isLastPage, page, error } = usePagination((pageNum, pageSize) => Apis.xsb.getSearchProductList({ data: {
  21. keywords: searchText.value,
  22. pageNum,
  23. pageSize,
  24. priceSort: activeTab.value === 2 ? 'DESC' : '',
  25. salesNum: activeTab.value === 1 ? 'DESC' : '',
  26. shopId: SelectShopInfo.value.shopId,
  27. channelId: userInfo.value.channelId || 1,
  28. } }), {
  29. immediate: false,
  30. data: resp => resp.data?.list,
  31. initialPage: 1,
  32. initialPageSize: 10,
  33. append: true,
  34. })
  35. const isSearch = ref(false)
  36. const hotText = ref<Api.xsbSearchTerm[]>([])
  37. onLoad((query: any) => {
  38. if (query.text) {
  39. searchText.value = query.text
  40. send()
  41. isSearch.value = true
  42. }
  43. })
  44. function handleSearch() {
  45. if (!searchText.value)
  46. return
  47. data.value = []
  48. isSearch.value = true
  49. send()
  50. if (!searchList.value.includes(searchText.value)) {
  51. searchList.value.push(searchText.value)
  52. }
  53. }
  54. watch(() => searchText.value, () => {
  55. if (!searchText.value) {
  56. isSearch.value = false
  57. activeTab.value = 0
  58. }
  59. })
  60. onReachBottom(() => {
  61. if (!isLastPage.value) {
  62. page.value++
  63. }
  64. })
  65. function handleChange(e: { index: number }) {
  66. activeTab.value = e.index
  67. page.value = 1
  68. data.value = []
  69. send()
  70. }
  71. function handleClearnSeachLocaData() {
  72. showConfirm({
  73. title: '警告',
  74. msg: '是否删除历史搜索记录?',
  75. confirmButtonText: '确定',
  76. cancelButtonText: '取消',
  77. success() {
  78. searchList.value = []
  79. },
  80. })
  81. }
  82. async function getSearchData() {
  83. const { data } = await Apis.xsb.SearchTerm({ data: { type: 2 } })
  84. hotText.value = data
  85. }
  86. getSearchData()
  87. const state = computed(() => {
  88. return error.value ? 'error' : !isLastPage.value ? 'loading' : 'finished'
  89. })
  90. function handleSearchText(text: string) {
  91. searchText.value = text
  92. handleSearch()
  93. }
  94. </script>
  95. <template>
  96. <view class="page-xsb">
  97. <view class="sticky top-0 bg-white px24rpx pt24rpx">
  98. <view class="box-border flex items-center justify-between border border-2rpx border-[var(--them-color)] rounded-40rpx border-solid px24rpx py14rpx">
  99. <view class="flex flex-1 items-center">
  100. <wd-icon name="search" size="20px" color="#aaa" />
  101. <view class="ml20rpx flex-1">
  102. <input v-model.trim="searchText" type="text" placeholder="请输入搜索内容">
  103. </view>
  104. </view>
  105. <view class="w-90rpx flex items-center">
  106. <view class="ml12rpx text-#DEDEDE">
  107. |
  108. </view>
  109. <view class="ml12rpx text-28rpx text-[var(--them-color)] font-semibold" @click="handleSearch">
  110. 搜索
  111. </view>
  112. </view>
  113. </view>
  114. <view v-if="!isSearch" class="h-90vh">
  115. <view v-if="searchList.length" class="mt24rpx">
  116. <view class="flex items-center justify-between">
  117. <view class="text-28rpx font-semibold">
  118. 历史搜索
  119. </view>
  120. <wd-icon name="delete-thin" size="22px" @click="handleClearnSeachLocaData" />
  121. </view>
  122. <view class="mt20rpx flex flex-wrap items-center">
  123. <view v-for="item in searchList" :key="item" class="mb20rpx mr16rpx box-border flex items-center justify-center rounded-30rpx bg-#F6F6F6 px24rpx py10rpx text-28rpx" @click="handleSearchText(item)">
  124. {{ item }}
  125. </view>
  126. </view>
  127. </view>
  128. <view v-if="hotText.length" class="mt24rpx">
  129. <view class="text-28rpx font-semibold">
  130. 热门搜索
  131. </view>
  132. <view class="mt20rpx flex flex-wrap items-center">
  133. <view v-for="item in hotText" :key="item.id" class="mb20rpx mr16rpx box-border flex items-center justify-center rounded-30rpx bg-#F6F6F6 px24rpx py10rpx text-28rpx" @click="handleSearchText(item.searchName)">
  134. {{ item.searchName }}
  135. </view>
  136. </view>
  137. </view>
  138. </view>
  139. <view v-if="isSearch">
  140. <wd-tabs v-model="activeTab" @change="handleChange">
  141. <block v-for="item in tabbarlist" :key="item.id">
  142. <wd-tab :title="item.name" />
  143. </block>
  144. </wd-tabs>
  145. </view>
  146. </view>
  147. <view v-if="isSearch" class="px24rpx pt20rpx">
  148. <view v-for="item in data" :key="item.id" class="mb20rpx box-border flex items-center justify-between rounded-16rpx bg-white p24rpx" @click="router.push({ name: 'xsb-goods', params: { id: String(item.prodId) } })">
  149. <image
  150. :src="item.pic"
  151. class="h200rpx w200rpx flex-shrink-0 rounded-16rpx"
  152. />
  153. <view class="ml20rpx flex-1">
  154. <view class="text-32rpx font-semibold">
  155. {{ item.prodName }}
  156. </view>
  157. <view class="mt14rpx text-36rpx text-#FF4A39 font-semibold">
  158. ¥{{ item.channelProdPrice }}
  159. </view>
  160. </view>
  161. </view>
  162. <wd-loadmore v-if="data.length" :state="state" :loading-props="{ color: '#9ED605', size: 20 }" />
  163. <wd-status-tip v-if="!data.length" image="search" tip="当前搜索无结果" />
  164. </view>
  165. <view class="h30rpx" />
  166. </view>
  167. </template>
  168. <style scoped lang="scss">
  169. .page-xsb{
  170. :deep(){
  171. .wd-tabs__nav-item-text{
  172. font-size: 28rpx !important;
  173. }
  174. .wd-tabs__nav-item.is-active{
  175. font-weight: 700 !important;
  176. color: var(--them-color) !important;
  177. }
  178. }
  179. }
  180. </style>