| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250 |
- <script setup lang="ts">
- import type { Paging } from '@/model/base'
- import type { Article, ArticleParams, Category, CreateCarousalsRequest, Recommends } from '@/model/pet-manual'
- import carousalApi from '@/api/carousal'
- import CardList from '@/pages/pet-manual/components/CardList.vue'
- import circle from '@/static/image/feed-plan/circle.png'
- import message from '@/static/image/feed-plan/message.png'
- import ToolApi from '@/utils'
- interface DotStyle {
- backgroundColor: string
- selectedBackgroundColor: string
- selectedBorder: string
- border: string
- }
- const listModel = ref<Article[]>([])
- const safeHeight = ToolApi.getSafeHeight()
- const searchValue = ref<string>('')
- const cardState = ref<'update' | 'updatePage'>('update')
- const info = ref<CreateCarousalsRequest[]>([
- {
- imageUrl: '',
- targetId: '',
- targetType: '',
- targetUrl: '',
- },
- ])
- const current = ref<number>(0)
- const dotStyle = ref<DotStyle>({
- backgroundColor: '#DCDCDC',
- selectedBackgroundColor: '#0052D9',
- selectedBorder: 'none',
- border: 'none',
- })
- function change(e: CustomEvent<{ current: number }>): void {
- current.value = e.detail.current
- }
- const typeList = ref<Category[]>([])
- const articleParams = ref<ArticleParams>({
- page: 1,
- size: 10,
- title: '',
- categoryId: '',
- })
- const articlePaging = ref<Paging>({
- page: 1,
- size: 10,
- total: 0,
- })
- async function handleClickType(item: Category) {
- typeList.value.forEach(i => (i.isClick = false))
- item.isClick = true
- articleParams.value.categoryId = item.id
- cardState.value = 'update'
- await updateArticleList()
- }
- const isSearch = ref<boolean>(true)
- const isSearchSource = ref<boolean>(false)
- function handleSearchFocus() {
- isSearch.value = false
- isSearchSource.value = false
- updateSearchList()
- }
- async function handleSearchBlur() {
- if (searchValue.value !== '') {
- isSearchSource.value = true
- reset()
- articleParams.value.title = searchValue.value
- await updateArticleList()
- }
- }
- function handleSearchKeyword(keyword: string): void {
- searchValue.value = keyword
- handleSearchBlur()
- }
- async function handleCancel() {
- isSearch.value = true
- reset()
- articleParams.value.categoryId = typeList.value.filter(item => item.isClick === true)[0].id
- await updateArticleList()
- }
- function handleSearchClear() {
- isSearchSource.value = false
- }
- const historyList = ref<string[]>([])
- const findList = ref<Recommends[]>([])
- async function updateArticleList() {
- const articleListApi = await carousalApi.getArticleList(articleParams.value)
- if (cardState.value === 'update') {
- listModel.value = articleListApi.data
- }
- else if (cardState.value === 'updatePage') {
- listModel.value.push(...articleListApi.data)
- }
- else {
- listModel.value = articleListApi.data
- }
- articlePaging.value = articleListApi.pagination
- }
- async function handleLoadArticle() {
- articleParams.value.page += 1
- cardState.value = 'updatePage'
- await updateArticleList()
- }
- async function updateSearchList() {
- historyList.value = await carousalApi.getSearchRecords()
- findList.value = await carousalApi.getSearchRecommends()
- }
- async function init() {
- info.value = await carousalApi.getCarousalList()
- typeList.value = (await carousalApi.getTypeList()).map((item, index) => {
- return {
- name: item.name,
- id: item.id,
- code: item.code,
- isClick: index === 0,
- }
- })
- articleParams.value.categoryId = typeList.value[0].id
- await updateArticleList()
- await updateSearchList()
- }
- function reset() {
- articleParams.value = {
- page: 1,
- size: 10,
- title: '',
- categoryId: '',
- }
- listModel.value = []
- }
- function handleJumpUrl(item: CreateCarousalsRequest) {
- if (item.targetType === 'url') {
- uni.navigateTo({
- url: item.targetUrl,
- })
- }
- }
- init()
- </script>
- <template>
- <view class="flex flex-col bg-[#F5F6F7] overflow-y-auto" :style="`height:calc(100vh - ${safeHeight}px)`">
- <view class="mx-[6px]">
- <uni-search-bar
- v-model="searchValue"
- placeholder="请搜索你想要的内容"
- bg-color="white" clear-button="auto"
- :cancel-button="isSearch ? 'none' : 'always'"
- :radius="20"
- @focus="handleSearchFocus"
- @cancel="handleCancel"
- @blur="handleSearchBlur"
- @clear="handleSearchClear"
- />
- </view>
- <view v-show="!isSearch" class=" mt-4">
- <view v-show="!isSearchSource" class="mx-4">
- <text class="text-[18px] font-600">
- 历史记录
- </text>
- <view class="mt-4 flex gap-2 flex-wrap text-[12px] text-[#999] font-400 leading-5">
- <view v-for="(item, index) in historyList" :key="index" class="px-2 py-0.5 flex justify-center items-center bg-[white] rounded-sm" @click="handleSearchKeyword(item)">
- {{ item }}
- </view>
- </view>
- <view class="mt-8">
- <text class="text-[18px] font-600">
- 搜索发现
- </text>
- <view class="mt-4 flex gap-2 flex-wrap text-[12px] text-[#999] font-400 leading-5">
- <view v-for="(item, index) in findList" :key="index" class="px-2 py-0.5 flex justify-center items-center bg-[white] rounded-sm gap-1" @click="handleSearchKeyword(item.keyword)">
- <view class="flex items-center justify-center">
- <uni-icons color="#999999" size="14" type="search" />
- </view>
- <view class="flex items-center justify-center">
- {{ item.keyword }}
- </view>
- </view>
- </view>
- </view>
- </view>
- <CardList v-show="isSearchSource" :card-list="listModel" @load-more="handleLoadArticle" />
- </view>
- <view v-show="isSearch">
- <view class="ml-4 mt-4 text-[20px] font-600">
- 热门推荐
- </view>
- <view class="mx-4 mt-4">
- <uni-swiper-dot :info="info" :current="current" field="content" mode="dot" :dots-styles="dotStyle">
- <swiper class="swiper-box" @change="change">
- <swiper-item v-for="(item, index) in info" :key="index">
- <view class="swiper-item w-full h-full flex items-center justify-center">
- <image :src="item.imageUrl" mode="heightFix" class="w-full h-full" @tap="handleJumpUrl(item)" />
- </view>
- </swiper-item>
- </swiper>
- </uni-swiper-dot>
- </view>
- <view class="ml-4 mt-5 text-[20px] font-600">
- 养宠贴士
- </view>
- <view class="mx-4 sticky top-0 bg-[#f5f6f7]">
- <scroll-view class="scroll mt-2" scroll-x="auto">
- <view class="group h-[40px] mt-1">
- <view
- v-for="(item, index) in typeList" :key="index" class="item h-[30px] w-[28%] rounded-15px relative" style="border: 1px solid #E7E7E7"
- @tap="handleClickType(item)"
- >
- <view v-if="item.isClick">
- <image :src="message" class="absolute w-full" style="height: calc(100% + 5px)" />
- <image :src="circle" class="w-[14px] h-[14px] absolute right-2 top-[-4px]" />
- </view>
- <view class="w-full h-full flex items-center justify-center text-[14px] z-20 relative font-600" :class="item.isClick ? 'type_select_span' : 'type_span'">
- {{ item.name }}
- </view>
- </view>
- </view>
- </scroll-view>
- </view>
- <CardList :card-list="listModel" @load-more="handleLoadArticle" />
- </view>
- </view>
- </template>
- <style scoped>
- .scroll{
- box-sizing: border-box;
- .group{
- white-space: nowrap;
- .item{
- display: inline-block;
- margin-right: 10px;
- }
- }
- }
- .type_span{
- color:#999
- }
- .type_select_span{
- color:#FFF
- }
- </style>
|