Commit 39a2c4f6 by lijiabin

【需求 17679】 feat: 完善查看更多 等内容

parent 493a8ee2
...@@ -14,8 +14,10 @@ const locale = ref(zhCn) ...@@ -14,8 +14,10 @@ const locale = ref(zhCn)
// console.log(res) // console.log(res)
// }) // })
onMounted(() => { onMounted(() => {
if (import.meta.env.MODE === 'production') {
setTimeout(() => { setTimeout(() => {
initWxConfig() initWxConfig()
}, 3000) }, 3000)
}
}) })
</script> </script>
...@@ -12,6 +12,10 @@ import type { ...@@ -12,6 +12,10 @@ import type {
ColumnItemDto, ColumnItemDto,
VideoOptionDto, VideoOptionDto,
CommentChildrenSearchParams, CommentChildrenSearchParams,
SearchMoreColumnParams,
SearchMoreColumnItemDto,
SearchMoreVideoParams,
SearchMoreVideoItemDto,
} from './types' } from './types'
import type { BackendServicePageResult, PageSearchParams } from '@/utils/request/types' import type { BackendServicePageResult, PageSearchParams } from '@/utils/request/types'
...@@ -108,6 +112,19 @@ export const getColumnList = (data: PageSearchParams) => { ...@@ -108,6 +112,19 @@ export const getColumnList = (data: PageSearchParams) => {
} }
/** /**
* 获取专栏列表查看更多
*/
export const getColumnListViewMore = (data: SearchMoreColumnParams) => {
return service.request<BackendServicePageResult<SearchMoreColumnItemDto>>({
url: '/api/yaCulture/viewMore',
method: 'POST',
data: {
type: 'column',
...data,
},
})
}
/**
* 获取首页视频列表list —— 分页 * 获取首页视频列表list —— 分页
*/ */
export const getVideoList = (data: PageSearchParams) => { export const getVideoList = (data: PageSearchParams) => {
...@@ -122,6 +139,19 @@ export const getVideoList = (data: PageSearchParams) => { ...@@ -122,6 +139,19 @@ export const getVideoList = (data: PageSearchParams) => {
} }
/** /**
* 获取视频列表查看更多
*/
export const getVideoListViewMore = (data: SearchMoreVideoParams) => {
return service.request<BackendServicePageResult<SearchMoreVideoItemDto>>({
url: '/api/yaCulture/viewMore',
method: 'POST',
data: {
type: 'video',
...data,
},
})
}
/**
* 点赞或者取消点赞文章 * 点赞或者取消点赞文章
*/ */
export const addOrCanceArticlelLike = (articleId: number | string) => { export const addOrCanceArticlelLike = (articleId: number | string) => {
......
...@@ -173,6 +173,7 @@ export interface ColumnItemDto { ...@@ -173,6 +173,7 @@ export interface ColumnItemDto {
title: string title: string
color: string color: string
sort: number sort: number
id: number
yaColumnVoList: { yaColumnVoList: {
articleId: number articleId: number
collectCount: number collectCount: number
...@@ -300,3 +301,69 @@ export interface CommentItemDto { ...@@ -300,3 +301,69 @@ export interface CommentItemDto {
childrenPageList: CommentItemDto[] childrenPageList: CommentItemDto[]
loadingChildren: boolean loadingChildren: boolean
} }
/**
* 搜索更多专栏查询参数
*/
export interface SearchMoreColumnParams extends PageSearchParams {
columnId: number
sortLogic: number
title?: string
}
/**
* 搜索更多专栏返回参数
*/
export interface SearchMoreColumnItemDto {
articleId: number
collectCount: number
content: string
createTime: number
createUserId: number
description: string
faceUrl: string
hasPraised: boolean
isRecommend: number
playCount: number
praiseCount: number
replyCount: number
showAvatar: string
showName: string
title: string
type: ArticleTypeEnum.COLUMN
videoDuration: string
viewCount: number
}
/**
* 搜索更多视频查询参数
*/
export interface SearchMoreVideoParams extends PageSearchParams {
columnId: number | string
sortLogic: number
title?: string
}
/**
* 搜索更多视频返回参数
*/
export interface SearchMoreVideoItemDto {
articleId: number
collectCount: number
content: string
createTime: number
createUserId: number
description: string
faceUrl: string
hasPraised: boolean
isRecommend: number
playCount: number
praiseCount: number
replyCount: number
showAvatar: string
showName: string
title: string
type: ArticleTypeEnum.VIDEO
videoDuration: string
viewCount: number
}
...@@ -143,6 +143,18 @@ export const constantsRoute = [ ...@@ -143,6 +143,18 @@ export const constantsRoute = [
name: 'CultureAuditArticle', name: 'CultureAuditArticle',
component: () => import('@/views/auditArticle/index.vue'), component: () => import('@/views/auditArticle/index.vue'),
}, },
// YA文化专栏的搜索
{
path: 'columnSearchList/:id',
name: 'CultureColumnSearchList',
component: () => import('@/views/columnSearchList/index.vue'),
},
// YA文化视频的搜索
{
path: 'videoSearchList/:id?',
name: 'CultureVideoSearchList',
component: () => import('@/views/videoSearchList/index.vue'),
},
// 发布文章 // 发布文章
// { // {
// { // {
...@@ -171,7 +183,7 @@ export const constantsRoute = [ ...@@ -171,7 +183,7 @@ export const constantsRoute = [
path: '/backend', path: '/backend',
name: 'Backend', name: 'Backend',
component: () => import('@/views/backend/index.vue'), component: () => import('@/views/backend/index.vue'),
redirect: '/backend/manager', redirect: '/backend/tags',
children: [ children: [
{ {
path: 'manager', path: 'manager',
......
<template>
<div ref="searchPageRef" class="bg-white/90">
<div>
<!-- 搜索栏 -->
<div class="p-4">
<div class="flex items-center gap-2 justify-between">
<el-button link @click="router.back()" class="text-gray-600 hover:text-primary">
<el-icon class="mr-1"><ArrowLeft /></el-icon>
返回
</el-button>
<div class="w-auto flex items-center gap-2">
<el-input
v-model="searchParams.title"
placeholder="输入关键词搜索"
class="w-400px"
size="default"
@keyup.enter="handleSearch"
clearable
/>
<el-button type="primary" @click="handleSearch">搜索</el-button>
</div>
</div>
</div>
<!-- 一级分类 -->
<div class="flex items-center justify-between mb-6 border-b border-gray-200 p-4">
<div class="flex items-center gap-2">
<span class="text-gray-600 text-base">当前栏目:{{ columnTitle }}</span>
<!-- <template v-else>
<span class="text-gray-600 text-14px">分类:</span>
<div class="flex gap-2">
<button
v-for="sort in [{ label: '全部', value: '' }, ...articleTypeListOptions]"
:key="sort.value"
class="px-4 py-1.5 rounded-lg text-14px transition-colors cursor-pointer"
:class="{
'text-blue-600 bg-blue-50': searchParams.type === sort.value,
'text-gray-600 hover:text-blue-600': searchParams.type !== sort.value,
}"
@click="changeType(sort.value)"
>
{{ sort.label }}
</button>
</div>
</template> -->
</div>
<div class="text-gray-500 text-14px">
<el-select
v-model="searchParams.sortLogic"
placeholder="请选择排序方式"
class="w-100px!"
@change="changeSort"
>
<el-option
v-for="sort in sortOptions"
:key="sort.value"
:label="sort.label"
:value="sort.value"
/>
</el-select>
</div>
</div>
<div v-show="list.length">
<div class="space-y-4">
<div
v-for="item in list"
:key="item.articleId"
class="flex gap-4 p-4 rounded-lg hover:bg-gray-50 transition-colors cursor-pointer"
@click="handleClick(item)"
>
<!-- 封面图 -->
<div
v-if="item.faceUrl"
class="flex-shrink-0 w-240px h-135px rounded-lg overflow-hidden bg-gray-100 relative"
>
<img :src="item.faceUrl" class="w-full h-full object-cover" />
<!-- <div
v-if="item.type === ArticleTypeEnum.VIDEO"
class="absolute bottom-2 right-2 bg-black/70 text-white text-12px px-2 py-0.5 rounded"
>
{{ item.videoDuration }}
</div> -->
</div>
<!-- 内容信息 -->
<div class="flex-1 flex flex-col justify-between min-w-0">
<div>
<!-- 标题 -->
<h3 class="text-16px font-500 text-gray-900 mb-2 line-clamp-1">
{{ item.title }}
</h3>
<!-- 描述 -->
<p class="text-14px text-gray-600 mb-3 line-clamp-2">
{{ item.content }}
</p>
</div>
<!-- 底部信息 -->
<div class="flex items-center gap-4 text-13px text-gray-500">
<span>{{ item.showName }}</span>
<span>{{ dayjs(item.createTime * 1000).format('YYYY-MM-DD HH:mm:ss') }}</span>
<div class="flex items-center gap-1">
<el-icon class="text-sm">
<View />
</el-icon>
<span class="font-medium text-gray-500">{{ item.viewCount }}</span>
</div>
<div class="flex items-center gap-1">
<el-icon class="text-sm">
<ChatDotRound />
</el-icon>
<span class="font-medium">{{ item.replyCount }}</span>
</div>
<div class="flex items-center gap-1">
<el-icon class="text-sm">
<Star />
</el-icon>
<span class="font-medium">{{ item.praiseCount }}</span>
</div>
</div>
</div>
<div class="flex-shrink-0 self-end">
<span class="text-blue-600 text-13px">{{
articleTypeListOptions.find((i) => i.value === item.type)?.label
}}</span>
</div>
</div>
</div>
<div class="bottom-pagination backdrop-blur-8 border-t border-gray-200">
<div class="max-w-7xl mx-auto py-6">
<div class="flex items-center justify-end gap-4">
<!-- 左侧:回到顶部按钮 -->
<div class="left">
<ScrollTopComp />
</div>
<!-- 右侧:分页器 -->
<div class="right">
<div
class="pagination-wrapper bg-white rounded-lg shadow-sm border border-gray-100 p-3"
>
<el-pagination
v-model:current-page="searchParams.current"
v-model:page-size="searchParams.size"
:page-sizes="[5, 20, 1]"
layout="prev, pager, next, jumper, total"
:total="total"
class="custom-pagination"
@current-change="
(e) => {
;(handleBackTop(), goToPage(e))
}
"
@size-change="changePageSize"
/>
</div>
</div>
</div>
</div>
</div>
</div>
<div v-show="!list.length">
<div class="flex items-center justify-center h-full">
<el-empty description="暂无数据" />
</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { articleTypeListOptions } from '@/constants'
import { getColumnListViewMore } from '@/api'
import { usePageSearch, useScrollTop } from '@/hooks'
import dayjs from 'dayjs'
import type { SearchMoreColumnItemDto } from '@/api'
const router = useRouter()
const route = useRoute()
const searchPageRef = ref<HTMLElement | null>(null)
const { ScrollTopComp, handleBackTop } = useScrollTop(searchPageRef)
const columnTitle = route.query.columnTitle || ''
const sortOptions = [
{ label: '最热', value: 0 },
{ label: '最新', value: 1 },
]
const { total, goToPage, changePageSize, refresh, searchParams, list } = usePageSearch(
getColumnListViewMore,
{
defaultParams: {
sortLogic: sortOptions[0]?.value,
columnId: route.params.id,
},
},
)
// const changeType = (value: ArticleTypeEnum) => {
// searchParams.value.type = value
// refresh()
// }
const changeSort = (value: number) => {
searchParams.value.sortLogic = value
refresh()
}
const handleSearch = () => {
refresh()
}
const handleClick = (item: SearchMoreColumnItemDto) => {
window.open(`/articleDetail/${item.articleId}`)
}
onActivated(() => {})
</script>
<style scoped></style>
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
<!-- 第一个视频 - 占据两列 --> <!-- 第一个视频 - 占据两列 -->
<div <div
v-show="list.length >= 1" v-show="list.length >= 1"
@click="router.push(`/videoDetail/${list[0]?.id}`)" @click="openDetailPage(`/videoDetail/${list[0]?.id}`)"
class="lg:col-span-2 group relative rounded-lg overflow-hidden bg-white shadow-sm hover:shadow-xl transition-all duration-500 cursor-pointer" class="lg:col-span-2 group relative rounded-lg overflow-hidden bg-white shadow-sm hover:shadow-xl transition-all duration-500 cursor-pointer"
> >
<div class="relative overflow-hidden mb-5"> <div class="relative overflow-hidden mb-5">
...@@ -125,7 +125,7 @@ ...@@ -125,7 +125,7 @@
v-for="(item, index) in list.slice(1, 3)" v-for="(item, index) in list.slice(1, 3)"
:key="index" :key="index"
class="group relative rounded-lg overflow-hidden bg-white shadow-sm hover:shadow-lg transition-all duration-300 cursor-pointer" class="group relative rounded-lg overflow-hidden bg-white shadow-sm hover:shadow-lg transition-all duration-300 cursor-pointer"
@click="router.push(`/videoDetail/${item?.id}`)" @click="openDetailPage(`/videoDetail/${item?.id}`)"
> >
<div class="relative overflow-hidden"> <div class="relative overflow-hidden">
<img <img
...@@ -204,7 +204,7 @@ ...@@ -204,7 +204,7 @@
<!-- 剩余视频 - 标准网格 --> <!-- 剩余视频 - 标准网格 -->
<div v-show="list.length > 3" class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6"> <div v-show="list.length > 3" class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6">
<div <div
@click="router.push(`/videoDetail/${item.id}`)" @click="openDetailPage(`/videoDetail/${item.id}`)"
v-for="item in list.slice(3)" v-for="item in list.slice(3)"
:key="item.id" :key="item.id"
class="group relative rounded-lg overflow-hidden bg-white shadow-sm hover:shadow-lg transition-all duration-300 cursor-pointer" class="group relative rounded-lg overflow-hidden bg-white shadow-sm hover:shadow-lg transition-all duration-300 cursor-pointer"
...@@ -292,7 +292,7 @@ ...@@ -292,7 +292,7 @@
<div v-show="searchParams.current !== 1"> <div v-show="searchParams.current !== 1">
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6"> <div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6">
<div <div
@click="router.push(`/videoDetail/${item.id}`)" @click="openDetailPage(`/videoDetail/${item.id}`)"
v-for="item in list" v-for="item in list"
:key="item.id" :key="item.id"
class="group relative rounded-lg overflow-hidden bg-white shadow-sm hover:shadow-lg transition-all duration-300 cursor-pointer" class="group relative rounded-lg overflow-hidden bg-white shadow-sm hover:shadow-lg transition-all duration-300 cursor-pointer"
...@@ -419,7 +419,6 @@ ...@@ -419,7 +419,6 @@
</template> </template>
<script setup lang="ts" name="VideoList"> <script setup lang="ts" name="VideoList">
import { useRouter } from 'vue-router'
import { useScrollTop } from '@/hooks' import { useScrollTop } from '@/hooks'
import { ArticleTypeEnum, TABS_REF_KEY } from '@/constants' import { ArticleTypeEnum, TABS_REF_KEY } from '@/constants'
import { usePageSearch } from '@/hooks' import { usePageSearch } from '@/hooks'
...@@ -428,8 +427,6 @@ import dayjs from 'dayjs' ...@@ -428,8 +427,6 @@ import dayjs from 'dayjs'
const tabsRef = inject(TABS_REF_KEY) const tabsRef = inject(TABS_REF_KEY)
const router = useRouter()
const { ScrollTopComp, handleBackTop } = useScrollTop(tabsRef!) const { ScrollTopComp, handleBackTop } = useScrollTop(tabsRef!)
const { list, total, searchParams, loading, goToPage, changePageSize, refresh } = usePageSearch( const { list, total, searchParams, loading, goToPage, changePageSize, refresh } = usePageSearch(
getArticleList, getArticleList,
...@@ -450,6 +447,10 @@ const toggleTab = (sortLogic: number) => { ...@@ -450,6 +447,10 @@ const toggleTab = (sortLogic: number) => {
refresh() refresh()
} }
const openDetailPage = (path: string) => {
window.open(path)
}
defineExpose({ defineExpose({
refresh: () => { refresh: () => {
refresh() refresh()
......
...@@ -20,9 +20,9 @@ ...@@ -20,9 +20,9 @@
class="flex items-center cursor-pointer" class="flex items-center cursor-pointer"
@click=" @click="
router.push({ router.push({
path: '/searchPage', path: `/columnSearchList/${item.id}`,
query: { query: {
type: ArticleTypeEnum.COLUMN, columnTitle: item.title,
}, },
}) })
" "
...@@ -149,7 +149,7 @@ const { list, total, searchParams, goToPage, changePageSize, loading, refresh } ...@@ -149,7 +149,7 @@ const { list, total, searchParams, goToPage, changePageSize, loading, refresh }
) )
defineExpose({ defineExpose({
refresh: () => { refresh: () => {
searchParams.value.current = 0 // searchParams.value.current = 0
refresh() refresh()
}, },
}) })
......
...@@ -26,11 +26,7 @@ ...@@ -26,11 +26,7 @@
}, },
}) })
" "
> ></div>
<span class="mr-1 text-14px color-#606266 hover:text-[var(--dynamic-color)]"
>查看更多 >></span
>
</div>
</div> </div>
<div class="p-4"> <div class="p-4">
......
<template> <template>
<div> <div>
<div class="flex items-center justify-between pb-4">
<div class="flex items-center space-x-1 justify-between w-full">
<div class="flex items-center space-x-1">
<div
v-for="tab in tabs"
:key="tab.sortLogic"
:class="[
'px-6 py-2 rounded-full text-sm font-medium cursor-pointer transition-all duration-200',
searchParamsMore.sortLogic === tab.sortLogic
? 'bg-orange-400 text-white shadow-md'
: 'text-gray-600 hover:text-orange-500 hover:bg-orange-50',
]"
@click="changeSort(tab.sortLogic)"
>
{{ tab.label }}
</div>
</div>
<span
class="mr-1 text-14px color-#606266 cursor-pointer"
@click="
router.push({
path: `/videoSearchList`,
})
"
>
查看更多 >></span
>
</div>
</div>
<div v-loading="loadingMore" class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6 mb-6">
<div
@click="router.push(`/videoDetail/${item.articleId}`)"
v-for="item in listMore"
:key="item.id"
class="group relative rounded-lg overflow-hidden bg-white shadow-sm hover:shadow-lg transition-all duration-300 cursor-pointer"
>
<div class="relative overflow-hidden">
<img
:src="item.faceUrl"
class="w-full h-44 object-cover group-hover:scale-105 transition-transform duration-500"
/>
<div class="absolute inset-0 bg-gradient-to-t from-black/40 to-transparent"></div>
<!-- 标签 -->
<!-- <div
class="absolute top-3 left-3 bg-gradient-to-r from-indigo-500 to-purple-500 text-white px-2.5 py-1 rounded-full text-xs font-semibold"
>
{{ item.tagNameList[0] }}
</div> -->
<div
v-if="item.isRecommend"
class="absolute top-0 left-0 w-15 h-7 z-1000 bg-#FFF9B9 flex items-center justify-center border-2px border-solid border-#f4f0eb rounded-tl-lg rounded-br-lg"
>
<img class="w-6" src="@/assets/img/culture/recommend.png" alt="" />
<div class="text-12px text-#000 line-height-12px">推荐</div>
</div>
<!-- 时长 -->
<div
class="absolute bottom-3 right-3 bg-black/80 backdrop-blur-sm text-white px-2 py-1 rounded-lg text-xs"
>
{{ item?.videoDuration }}
</div>
<!-- 数据 -->
<div class="absolute bottom-3 left-3 flex gap-3 text-white text-xs">
<div class="flex items-center gap-1 bg-black/50 backdrop-blur-sm px-2 py-1 rounded-lg">
<el-icon class="text-sm"><View /></el-icon>
<span>{{ item.viewCount }}</span>
</div>
<div class="flex items-center gap-1 bg-black/50 backdrop-blur-sm px-2 py-1 rounded-lg">
<el-icon class="text-sm"><ChatDotRound /></el-icon>
<span>{{ item.replyCount }}</span>
</div>
<div class="flex items-center gap-1 bg-black/50 backdrop-blur-sm px-2 py-1 rounded-lg">
<el-icon class="text-sm"><Star /></el-icon>
<span>{{ item.replyCount }}</span>
</div>
</div>
<!-- 播放按钮 -->
<!-- <div
class="absolute inset-0 flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity duration-300"
>
<div
class="bg-white/90 backdrop-blur-sm rounded-full flex items-center justify-center shadow-xl transform scale-90 group-hover:scale-100 transition-transform duration-300"
>
<el-icon size="50" color="#333"><VideoPlay /></el-icon>
</div>
</div> -->
</div>
<div class="p-4">
<h3
class="font-semibold text-base mb-2 group-hover:text-blue-600 transition-colors line-clamp-1"
>
{{ item.title }}
</h3>
<div class="flex items-center justify-between text-gray-500 text-xs">
<div class="flex items-center gap-2">
<img :src="item.showAvatar" alt="" class="w-6 h-6 rounded-full object-cover" />
<span class="font-medium">{{ item.showName }}</span>
</div>
<span>{{ dayjs(item.createTime * 1000).format('YYYY-MM-DD HH:mm') }}</span>
</div>
</div>
</div>
</div>
<div v-loading="loading" v-if="list.length"> <div v-loading="loading" v-if="list.length">
<div class="w-full max-w-6xl mx-auto"> <div class="w-full max-w-6xl mx-auto">
<div <div
...@@ -20,9 +127,9 @@ ...@@ -20,9 +127,9 @@
class="flex items-center cursor-pointer" class="flex items-center cursor-pointer"
@click=" @click="
router.push({ router.push({
path: '/searchPage', path: `/videoSearchList/${item.id}`,
query: { query: {
type: ArticleTypeEnum.VIDEO, columnTitle: item.title,
}, },
}) })
" "
...@@ -131,7 +238,7 @@ ...@@ -131,7 +238,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { View, ChatDotRound, Star } from '@element-plus/icons-vue' import { View, ChatDotRound, Star } from '@element-plus/icons-vue'
import { getVideoList } from '@/api' import { getVideoList, getVideoListViewMore } from '@/api'
import { usePageSearch, useScrollTop } from '@/hooks' import { usePageSearch, useScrollTop } from '@/hooks'
import { TABS_REF_KEY, ArticleTypeEnum } from '@/constants' import { TABS_REF_KEY, ArticleTypeEnum } from '@/constants'
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
...@@ -141,6 +248,11 @@ const router = useRouter() ...@@ -141,6 +248,11 @@ const router = useRouter()
const tabsRef = inject(TABS_REF_KEY) const tabsRef = inject(TABS_REF_KEY)
const { handleBackTop, ScrollTopComp } = useScrollTop(tabsRef!) const { handleBackTop, ScrollTopComp } = useScrollTop(tabsRef!)
const tabs = [
{ label: '最多播放', sortLogic: 0 },
{ label: '最新发布', sortLogic: 1 },
]
const { list, total, searchParams, goToPage, changePageSize, loading, refresh } = usePageSearch( const { list, total, searchParams, goToPage, changePageSize, loading, refresh } = usePageSearch(
getVideoList, getVideoList,
{ {
...@@ -148,10 +260,31 @@ const { list, total, searchParams, goToPage, changePageSize, loading, refresh } ...@@ -148,10 +260,31 @@ const { list, total, searchParams, goToPage, changePageSize, loading, refresh }
immediate: false, immediate: false,
}, },
) )
const {
list: listMore,
total: totalMore,
searchParams: searchParamsMore,
goToPage: goToPageMore,
changePageSize: changePageSizeMore,
loading: loadingMore,
refresh: refreshMore,
} = usePageSearch(getVideoListViewMore, {
defaultSize: 3,
defaultParams: {
sortLogic: 0,
},
immediate: false,
})
const changeSort = (sortLogic: number) => {
searchParamsMore.value.sortLogic = sortLogic
refreshMore()
}
defineExpose({ defineExpose({
refresh: () => { refresh: () => {
searchParams.value.current = 0 // searchParams.value.current = 0
refresh() refresh()
refreshMore()
}, },
}) })
</script> </script>
......
...@@ -184,8 +184,8 @@ ...@@ -184,8 +184,8 @@
<div class="text-sm text-gray-700"> <div class="text-sm text-gray-700">
<div class="font-medium mb-1">温馨提示</div> <div class="font-medium mb-1">温馨提示</div>
<p class="text-xs leading-relaxed"> <p class="text-xs leading-relaxed">
实物商品兑换后请联系相关负责人领取奖励 实物商品兑换后,请耐心等待各地人才发展部伙伴统一发放安排
<span class="text-blue-600 cursor-pointer hover:underline ml-1">查看联系人</span> <!-- <span class="text-blue-600 cursor-pointer hover:underline ml-1">查看联系人</span> -->
</p> </p>
</div> </div>
</div> </div>
......
...@@ -170,6 +170,6 @@ const handleView = (item: AuditListItemDto) => { ...@@ -170,6 +170,6 @@ const handleView = (item: AuditListItemDto) => {
} }
const openArticleDetail = (id: number) => { const openArticleDetail = (id: number) => {
window.open(`/articleDetail/${id}`) window.open(`/auditArticle/${id}`)
} }
</script> </script>
<template>
<div ref="searchPageRef" class="bg-white/90">
<div>
<!-- 搜索栏 -->
<div class="p-4">
<div class="flex items-center gap-2 justify-between">
<el-button link @click="router.back()" class="text-gray-600 hover:text-primary">
<el-icon class="mr-1"><ArrowLeft /></el-icon>
返回
</el-button>
<div class="w-auto flex items-center gap-2">
<el-input
v-model="searchParams.title"
placeholder="输入关键词搜索"
class="w-400px"
size="default"
@keyup.enter="handleSearch"
clearable
/>
<el-button type="primary" @click="handleSearch">搜索</el-button>
</div>
</div>
</div>
<!-- 一级分类 -->
<div class="flex items-center justify-between mb-6 border-b border-gray-200 p-4">
<div class="flex items-center gap-2">
<span v-if="columnTitle" class="text-gray-600 text-base"
>当前栏目:{{ columnTitle }}</span
>
<!-- <template v-else>
<span class="text-gray-600 text-14px">分类:</span>
<div class="flex gap-2">
<button
v-for="sort in [{ label: '全部', value: '' }, ...articleTypeListOptions]"
:key="sort.value"
class="px-4 py-1.5 rounded-lg text-14px transition-colors cursor-pointer"
:class="{
'text-blue-600 bg-blue-50': searchParams.type === sort.value,
'text-gray-600 hover:text-blue-600': searchParams.type !== sort.value,
}"
@click="changeType(sort.value)"
>
{{ sort.label }}
</button>
</div>
</template> -->
</div>
<div class="text-gray-500 text-14px">
<el-select
v-model="searchParams.sortLogic"
placeholder="请选择排序方式"
class="w-100px!"
@change="changeSort"
>
<el-option
v-for="sort in sortOptions"
:key="sort.value"
:label="sort.label"
:value="sort.value"
/>
</el-select>
</div>
</div>
<div v-show="list.length">
<div class="space-y-4">
<div
v-for="item in list"
:key="item.articleId"
class="flex gap-4 p-4 rounded-lg hover:bg-gray-50 transition-colors cursor-pointer"
@click="handleClick(item)"
>
<!-- 封面图 -->
<div
v-if="item.faceUrl"
class="flex-shrink-0 w-240px h-135px rounded-lg overflow-hidden bg-gray-100 relative"
>
<img :src="item.faceUrl" class="w-full h-full object-cover" />
<div
class="absolute bottom-2 right-2 bg-black/70 text-white text-12px px-2 py-0.5 rounded"
>
{{ item.videoDuration }}
</div>
</div>
<!-- 内容信息 -->
<div class="flex-1 flex flex-col justify-between min-w-0">
<div>
<!-- 标题 -->
<h3 class="text-16px font-500 text-gray-900 mb-2 line-clamp-1">
{{ item.title }}
</h3>
<!-- 描述 -->
<p class="text-14px text-gray-600 mb-3 line-clamp-2">
{{ item.content }}
</p>
</div>
<!-- 底部信息 -->
<div class="flex items-center gap-4 text-13px text-gray-500">
<span>{{ item.showName }}</span>
<span>{{ dayjs(item.createTime * 1000).format('YYYY-MM-DD HH:mm:ss') }}</span>
<div class="flex items-center gap-1">
<el-icon class="text-sm">
<View />
</el-icon>
<span class="font-medium text-gray-500">{{ item.viewCount }}</span>
</div>
<div class="flex items-center gap-1">
<el-icon class="text-sm">
<ChatDotRound />
</el-icon>
<span class="font-medium">{{ item.replyCount }}</span>
</div>
<div class="flex items-center gap-1">
<el-icon class="text-sm">
<Star />
</el-icon>
<span class="font-medium">{{ item.praiseCount }}</span>
</div>
</div>
</div>
<div class="flex-shrink-0 self-end">
<span class="text-blue-600 text-13px">{{
articleTypeListOptions.find((i) => i.value === item.type)?.label
}}</span>
</div>
</div>
</div>
<div class="bottom-pagination backdrop-blur-8 border-t border-gray-200">
<div class="max-w-7xl mx-auto py-6">
<div class="flex items-center justify-end gap-4">
<!-- 左侧:回到顶部按钮 -->
<div class="left">
<ScrollTopComp />
</div>
<!-- 右侧:分页器 -->
<div class="right">
<div
class="pagination-wrapper bg-white rounded-lg shadow-sm border border-gray-100 p-3"
>
<el-pagination
v-model:current-page="searchParams.current"
v-model:page-size="searchParams.size"
:page-sizes="[5, 20, 1]"
layout="prev, pager, next, jumper, total"
:total="total"
class="custom-pagination"
@current-change="
(e) => {
;(handleBackTop(), goToPage(e))
}
"
@size-change="changePageSize"
/>
</div>
</div>
</div>
</div>
</div>
</div>
<div v-show="!list.length">
<div class="flex items-center justify-center h-full">
<el-empty description="暂无数据" />
</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { articleTypeListOptions } from '@/constants'
import { getVideoListViewMore } from '@/api'
import { usePageSearch, useScrollTop } from '@/hooks'
import dayjs from 'dayjs'
import type { SearchMoreVideoItemDto } from '@/api'
const router = useRouter()
const route = useRoute()
const searchPageRef = ref<HTMLElement | null>(null)
const { ScrollTopComp, handleBackTop } = useScrollTop(searchPageRef)
const columnTitle = route.query.columnTitle || ''
const sortOptions = [
{ label: '最热', value: 0 },
{ label: '最新', value: 1 },
]
const { total, goToPage, changePageSize, refresh, searchParams, list } = usePageSearch(
getVideoListViewMore,
{
defaultParams: {
sortLogic: sortOptions[0]?.value,
columnId: Number(route.params.id) || '',
},
},
)
// const changeType = (value: ArticleTypeEnum) => {
// searchParams.value.type = value
// refresh()
// }
const changeSort = (value: number) => {
searchParams.value.sortLogic = value
refresh()
}
const handleSearch = () => {
refresh()
}
const handleClick = (item: SearchMoreVideoItemDto) => {
window.open(`/articleDetail/${item.articleId}`)
}
</script>
<style scoped></style>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment