590 lines
13 KiB
Vue
590 lines
13 KiB
Vue
<script setup>
|
|
/**
|
|
* 搜索
|
|
*/
|
|
import {
|
|
ref,
|
|
reactive,
|
|
getCurrentInstance,
|
|
computed,
|
|
} from 'vue';
|
|
import {
|
|
onLoad,
|
|
onReady,
|
|
onPullDownRefresh,
|
|
onReachBottom
|
|
} from '@dcloudio/uni-app'
|
|
|
|
// 工具库
|
|
import util from '@/common/js/util';
|
|
// api
|
|
import api from '@/api/index.js'
|
|
// 顶部状态栏
|
|
import statusBar from '@/components/header/statusBar.vue'
|
|
import { set } from 'lodash';
|
|
|
|
const {
|
|
proxy
|
|
} = getCurrentInstance()
|
|
// 搜索状态
|
|
const searchState = ref(false)
|
|
// 搜索记录
|
|
const searchLog = reactive([])
|
|
// 热点视频
|
|
const hotVideoList = reactive([])
|
|
// 分类列表
|
|
const tabList = reactive([{
|
|
name: '视频',
|
|
getList: () => getVideoList(),
|
|
getMoreList: () => getMoreVideoList(),
|
|
refreshList: () => refreshVideoList()
|
|
},
|
|
{
|
|
name: '用户',
|
|
getList: () => getFriendList(),
|
|
getMoreList: () => getMoreFriendList(),
|
|
refreshList: () => refreshFriendList()
|
|
},
|
|
])
|
|
// 分类下标
|
|
const tabIndex = ref(0)
|
|
// 搜索关键字
|
|
const keyword = ref('')
|
|
// 视频列表
|
|
const videoList = reactive({
|
|
data: [],
|
|
pageNum: 1,
|
|
pageSize: 10,
|
|
total: 0,
|
|
})
|
|
// 用户列表
|
|
const userList = reactive({
|
|
data: [],
|
|
pageNum: 1,
|
|
pageSize: 10,
|
|
total: 0,
|
|
})
|
|
|
|
// 用户信息
|
|
const userinfo = computed(() => {
|
|
let resuilt = uni.$store.state.userinfo
|
|
return resuilt
|
|
})
|
|
|
|
onLoad(() => {
|
|
// 获取用户搜索记录
|
|
getSearchLog()
|
|
// 获取热点视频
|
|
getHotVideo()
|
|
})
|
|
|
|
onReachBottom(() => {
|
|
// 获取更多列表
|
|
if (searchState.value) tabList[tabIndex.value].getMoreList()
|
|
})
|
|
|
|
onPullDownRefresh(() => {
|
|
if (!searchState.value) {
|
|
uni.stopPullDownRefresh()
|
|
return
|
|
}
|
|
// 刷新
|
|
tabList[tabIndex.value].refreshList()
|
|
})
|
|
|
|
// 获取用户搜索记录
|
|
function getSearchLog() {
|
|
let searchList = uni.getStorageSync('searchLog');
|
|
if (searchList) {
|
|
searchList = Array.from(new Set(searchList))
|
|
searchLog.push(...searchList)
|
|
}
|
|
}
|
|
|
|
// 获取热点视频
|
|
function getHotVideo() {
|
|
// 热点视频
|
|
api.video.hotVideos().then(rs => {
|
|
if (rs.code == 200) {
|
|
hotVideoList.push(...rs.data)
|
|
return
|
|
}
|
|
util.alert({
|
|
contuent: rs.msg,
|
|
showCancel: false,
|
|
})
|
|
})
|
|
}
|
|
|
|
// tab下标
|
|
function handleTabIndex(index) {
|
|
if (tabIndex.value === index) return
|
|
tabIndex.value = index
|
|
// 重载
|
|
tabList[tabIndex.value].refreshList()
|
|
}
|
|
|
|
/**
|
|
* 查看用户主页
|
|
* @param {Object} item
|
|
*/
|
|
function handleUser(item) {
|
|
uni.navigateTo({
|
|
url: util.setUrl('/pages/index/videoHome', {
|
|
userId: item.userId
|
|
})
|
|
})
|
|
}
|
|
|
|
// 搜索
|
|
function handleSearch() {
|
|
if (!keyword.value) {
|
|
searchState.value = false
|
|
return
|
|
} else searchState.value = true
|
|
|
|
// 获取列表
|
|
tabList[tabIndex.value].getList()
|
|
|
|
|
|
// 缓存搜索历史
|
|
let searchList = uni.getStorageSync('searchLog');
|
|
searchList = searchList == '' ? [] : searchList;
|
|
searchList.push(keyword.value)
|
|
searchList = Array.from(new Set(searchList))
|
|
searchList = searchList.reverse()
|
|
|
|
uni.setStorageSync("searchLog", searchList)
|
|
}
|
|
|
|
// 重载视频列表
|
|
function refreshVideoList() {
|
|
videoList.pageNum = 1
|
|
videoList.total = 0
|
|
getVideoList()
|
|
}
|
|
|
|
// 获取更多视频列表
|
|
function getMoreVideoList() {
|
|
if (videoList.data.length >= videoList.total) return
|
|
videoList.pageNum++
|
|
getVideoList()
|
|
}
|
|
|
|
// 获取视频列表
|
|
function getVideoList() {
|
|
let obj = {
|
|
content: keyword.value,
|
|
type: +tabIndex.value + 1,
|
|
userId: userinfo.value.id,
|
|
}
|
|
|
|
api.video.videoSearch({ query: obj }).then(rs => {
|
|
// console.log('videoSearch', rs)
|
|
if (rs.code == 200) {
|
|
if (videoList.pageNum) videoList.data.length = 0
|
|
// 追加视频列表
|
|
videoList.data.push(...rs.rows.map(item => {
|
|
item.format_videoUrl = util.format_url(item.videoUrl, 'video')
|
|
item.format_header = util.format_url(item.avatar, 'img')
|
|
item.format_imageUrl = util.format_url(item.coverUrl, 'img')
|
|
return item
|
|
}))
|
|
// 视频列表
|
|
videoList.total = rs.total
|
|
// console.log('videoList', videoList.data)
|
|
return
|
|
}
|
|
util.alert({
|
|
content: rs.msg,
|
|
showCancel: false,
|
|
})
|
|
}).finally(() => {
|
|
uni.stopPullDownRefresh()
|
|
})
|
|
}
|
|
|
|
// 重载朋友列表
|
|
function refreshFriendList() {
|
|
userList.pageNum = 1
|
|
userList.total = 0
|
|
getFriendList()
|
|
}
|
|
|
|
// 获取更多朋友列表
|
|
function getMoreFriendList() {
|
|
if (userList.data.length >= userList.total) return
|
|
userList.pageNum++
|
|
getFriendList()
|
|
}
|
|
|
|
// 获取朋友列表
|
|
function getFriendList() {
|
|
let obj = {
|
|
content: keyword.value,
|
|
type: +tabIndex.value + 1,
|
|
userId: userinfo.value.id,
|
|
}
|
|
api.video.videoSearch({ query: obj }).then(rs => {
|
|
if (rs.code == 200) {
|
|
if (userList.pageNum) userList.data.length = 0
|
|
// 追加朋友列表
|
|
userList.data.push(...rs.rows.map(item => {
|
|
item.userId = item.id
|
|
item.format_userPortrait = util.format_url(item.avatar, 'img')
|
|
return item
|
|
}))
|
|
// 视频列表
|
|
userList.total = rs.total
|
|
return
|
|
}
|
|
util.alert({
|
|
content: rs.msg,
|
|
showCancel: false,
|
|
})
|
|
}).finally(() => {
|
|
uni.stopPullDownRefresh()
|
|
})
|
|
}
|
|
|
|
/**
|
|
* 点击当前元素搜索
|
|
* @param {Object} item 被点击的元素
|
|
* @param {String} key 键
|
|
*/
|
|
function handleItemSearch(item, key) {
|
|
if (key == 'search') {
|
|
keyword.value = item
|
|
} else if (key == 'title') {
|
|
keyword.value = item.topic
|
|
}
|
|
|
|
// 搜索
|
|
handleSearch()
|
|
}
|
|
|
|
// 跳转视频
|
|
function handleVideo(item) {
|
|
uni.navigateTo({
|
|
url: util.setUrl('/pages/index/videoDetail', {
|
|
videoId: item.id
|
|
})
|
|
})
|
|
}
|
|
|
|
// 删除历史记录
|
|
function deleteSearch() {
|
|
util.alert({
|
|
content: '确认删除历史记录吗?',
|
|
}).then(rs => {
|
|
uni.removeStorageSync('searchLog')
|
|
searchLog = searchLog.splice(0, searchLog.length)
|
|
})
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<view class="appbw">
|
|
<view class="ghost">
|
|
<statusBar />
|
|
<view class="head"></view>
|
|
</view>
|
|
|
|
<view class="apex">
|
|
<statusBar />
|
|
|
|
<!-- 头部 -->
|
|
<view class="header head df aic plr30">
|
|
<navigator open-type="navigateBack" class="back b">
|
|
<uni-icons type="left" size="48rpx" color="#333" />
|
|
</navigator>
|
|
|
|
<view class="search df aic ml20 f1 ptb5 plr15 bar">
|
|
<uni-icons type="search" size="32rpx" color="#aaa" />
|
|
<input class="ml20 f32" v-model="keyword" placeholder="请输入关键字" />
|
|
<view class="btn bar sm colourful w120" @click="handleSearch">搜索</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 搜索状态 -->
|
|
<template v-if="!searchState">
|
|
<!-- 历史记录 -->
|
|
<view class="searchList mtb30 mlr30">
|
|
<view class="rows">
|
|
<view class="title c333 f28 b">历史记录</view>
|
|
<uni-icons type="trash" size="24rpx" color="#999" @click="deleteSearch" />
|
|
</view>
|
|
|
|
<view class="list mt20 c333 f24">
|
|
<view class="item dib mtb10 mlr10 ptb10 plr20 bar" v-for="(item, index) in searchLog" :key="index"
|
|
@click="handleItemSearch(item, 'search')">{{ item }}</view>
|
|
|
|
<view class="nomore mtb20" v-if="!searchLog[0]">暂无搜索记录</view>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 搜索发现 -->
|
|
<view class="searchList mtb30 mlr30" v-if="0">
|
|
<view class="rows">
|
|
<view class="title c333 f28 b">搜索发现</view>
|
|
</view>
|
|
|
|
<view class="list mt20 c333 f24">
|
|
<view class="item dib mtb10 mlr10 ptb10 plr20 bar" v-for="(item, index) in 15" :key="index">电商
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 热门搜索 -->
|
|
<view class="hotList mtb30 mlr30 c333">
|
|
<view class="title f28 b">热门搜索</view>
|
|
<view class="list">
|
|
<view class="item df aic jcsb ptb20" v-for="(item, index) in hotVideoList" :key="index"
|
|
@click="handleItemSearch(item, 'title')">
|
|
<view class="rank c666 f32 b">{{ index + 1 }}</view>
|
|
|
|
<view class="content df aic f1 mlr15 f24">
|
|
<text>{{ item.topic }}</text>
|
|
<template v-if="index < 3">
|
|
<view class="label hot" v-if="index < 3">热</view>
|
|
<view class="label new" v-if="0">新</view>
|
|
</template>
|
|
<view class="f1"></view>
|
|
</view>
|
|
|
|
<view v-if="0" class="number f22">热度{{ item.play }}</view>
|
|
<view class="change wh40" v-if="0">
|
|
<image src="/static/hotSearchUp.png" mode="aspectFit" v-if="1" />
|
|
<image src="/static/hotSearchDefault.png" mode="aspectFit" v-else-if="1" />
|
|
<image src="/static/hotSearchDown.png" mode="aspectFit" v-else />
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<!-- 搜索结果 -->
|
|
<template v-else>
|
|
<!-- tab -->
|
|
<view class="tabList df plr15">
|
|
<view class="item df fdc aic plr20" v-for="(item, index) in tabList" :key="index"
|
|
:class="{ 'active': index === tabIndex }" @click="handleTabIndex(index)">
|
|
<view class="txt">{{ item.name }}</view>
|
|
<view class="line"></view>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 列表容器 -->
|
|
<view class="listBox ptb15 plr15">
|
|
<!-- 视频列表 -->
|
|
<view class="videoList" v-if="tabIndex === 0">
|
|
<view class="item oh mb25 plr30 c333 bfff br20" v-for="(item, index) in videoList.data" :key="index"
|
|
@click="handleVideo(item)">
|
|
<!-- 用户 -->
|
|
<view class="userinfo df aic mtb25">
|
|
<view class="avatar" @click.stop="handleUser(item)">
|
|
<image class="wh70 cir" :src="item.format_header" mode="aspectFill" />
|
|
</view>
|
|
|
|
<view class="user ml15 f1">
|
|
<view class="nickname f32">{{ item.userNickname }}</view>
|
|
<view class="date mt10 c999 f24">{{ item.createTime }}</view>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 简介 -->
|
|
<view class="desc mtb20 f28">{{ item.title }}</view>
|
|
|
|
<!-- 封面图 -->
|
|
<view class="coverImg mtb20">
|
|
<image :src="item.format_imageUrl" mode="aspectFill" class="br25" />
|
|
</view>
|
|
|
|
<!-- 菜单 -->
|
|
<view class="menu df mtb20 c333 f28">
|
|
<!-- 点赞数量 -->
|
|
<view class="option f1 fmid">
|
|
<image class="wh30" src="/static/indexLike.png" mode="aspectFit"
|
|
v-if="item.isLike == 1" />
|
|
<image class="wh30" src="/static/indexLike1.png" mode="aspectFit" v-else />
|
|
<view class="number ml10">{{ item.likeCount }}</view>
|
|
</view>
|
|
|
|
<!-- 评论数量 -->
|
|
<view class="option f1 fmid">
|
|
<image class="wh30" src="/static/indexMsg.png" mode="aspectFit" />
|
|
<view class="number ml10">{{ item.reviewCount }}</view>
|
|
</view>
|
|
|
|
<!-- 收藏数量 -->
|
|
<view class="option f1 fmid">
|
|
<image class="wh30" src="/static/indexCollect.png" mode="aspectFit" />
|
|
<view class="number ml10">{{ item.collectCount }}</view>
|
|
</view>
|
|
|
|
<!-- 转发数量 -->
|
|
<view class="option f1 fmid" v-if="0">
|
|
<image class="wh30" src="/static/indexShare.png" mode="aspectFit" />
|
|
<view class="number ml10">666.6w</view>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 用户热评 -->
|
|
<view class="userMsg df aic mtb25" v-if="0">
|
|
<view class="avatar">
|
|
<image class="wh70 cir" src="/static/openPage.png" mode="aspectFill" />
|
|
</view>
|
|
|
|
<view class="user ml15 f1">
|
|
<view class="nickname c666 f28">超级果农大王</view>
|
|
<view class="txt thd f24">真是美味呀 ,多买点儿!!!</view>
|
|
</view>
|
|
|
|
<view class="option fmid">
|
|
<image class="wh30" src="/static/indexLike1.png" mode="aspectFit" />
|
|
<view class="number ml10 c666 f28">6.6w</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
<view v-if="videoList.data.length == 0" class="mtb20 nomore">暂无更多</view>
|
|
</view>
|
|
|
|
<!-- 用户列表 -->
|
|
<view class="userList" v-if="tabIndex === 1">
|
|
<view class="item df aic mtb40 plr10" v-for="(item, index) in userList.data" :key="index"
|
|
@click="handleUser(item)">
|
|
<view class="avatar fs0">
|
|
<image class="wh110 cir" :src="item.format_userPortrait" mode="aspectFill" />
|
|
</view>
|
|
|
|
<view class="user oh f1 mlr25">
|
|
<view class="nickname c333 f32">{{ item.userNickname }}</view>
|
|
<view class="fans c999 f24">粉丝:{{ item.userFans }}</view>
|
|
</view>
|
|
|
|
<view class="button fs0">
|
|
<view class="btn cancel w150" v-if="item.isAttention == 0">取消关注</view>
|
|
<view class="btn focus w150" v-else>关注</view>
|
|
</view>
|
|
</view>
|
|
<view v-if="userList.data.length == 0" class="mtb20 nomore">暂无更多</view>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
</view>
|
|
</template>
|
|
|
|
<style lang="scss">
|
|
image {
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
|
|
// 顶部
|
|
.apex {
|
|
position: fixed;
|
|
top: 0;
|
|
left: 0;
|
|
right: 0;
|
|
z-index: 1;
|
|
background-color: #fff;
|
|
}
|
|
|
|
//
|
|
.search {
|
|
height: 60rpx;
|
|
background-color: #f1f1f1;
|
|
}
|
|
|
|
// 搜索列表
|
|
.searchList {
|
|
|
|
// 单项
|
|
.item {
|
|
background-color: #f1f1f1;
|
|
}
|
|
}
|
|
|
|
// 热搜列表
|
|
.hotList {
|
|
|
|
.item+.item {
|
|
border-top: 1rpx solid #F6F6F6;
|
|
}
|
|
|
|
.item:nth-child(1) .number {
|
|
color: #FF0F2E;
|
|
}
|
|
|
|
.item:nth-child(2) .number {
|
|
color: #FF370F;
|
|
}
|
|
|
|
.item:nth-child(3) .number {
|
|
color: #FF630F;
|
|
}
|
|
|
|
// 热度
|
|
.number {
|
|
color: #999999;
|
|
}
|
|
|
|
// 标签
|
|
.label {
|
|
margin-left: 20rpx;
|
|
padding: 2rpx 10rpx;
|
|
font-size: 20rpx;
|
|
color: #fff;
|
|
border-radius: 50rpx 50rpx 50rpx 2rpx;
|
|
|
|
// 热
|
|
&.hot {
|
|
background-color: #FF0F2E;
|
|
}
|
|
|
|
// 新
|
|
&.new {
|
|
background-image: linear-gradient(123deg, #27EFE2 0%, #A45EFF 43%, #FF004F 99%);
|
|
}
|
|
}
|
|
}
|
|
|
|
// 分栏列表
|
|
.tabList {
|
|
|
|
.item {
|
|
.line {
|
|
background-color: #333;
|
|
width: 0;
|
|
height: 10rpx;
|
|
border-radius: 100rpx;
|
|
}
|
|
|
|
// 激活的
|
|
&.active {
|
|
|
|
.txt {
|
|
font-weight: bold;
|
|
}
|
|
|
|
.line {
|
|
width: 30rpx;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// 列表容器
|
|
.listBox {
|
|
min-height: 95vh;
|
|
background-color: #f8f8f8;
|
|
|
|
.videoList {
|
|
.coverImg {
|
|
height: 376rpx;
|
|
}
|
|
}
|
|
}
|
|
</style> |