567 lines
16 KiB
Vue
567 lines
16 KiB
Vue
<template>
|
|
<view class="main_div max_page">
|
|
<view class="fixed_search_div">
|
|
<view class="back_div" @click="common.navigateBack()">
|
|
<view class="back-icon"></view>
|
|
</view>
|
|
<view class="fixed_search_input_div fl1">
|
|
<uv-input v-model="inputValue" shape="circle" :customStyle="fixedCustomStyles" confirmType="search" placeholderStyle="color:#999999;font-size:26rpx" placeholder="请输入关键字" :adjust-position="false" @confirm="search">
|
|
<template #suffix>
|
|
<uv-icon name="search" color="#2c8ef2" size="24" @click="search()"></uv-icon>
|
|
</template>
|
|
</uv-input>
|
|
</view>
|
|
</view>
|
|
<!-- 主体 -->
|
|
<view class="search_content" v-if="fromType === 'course'">
|
|
<scroll-view class="lists-view lists-view-course" :scroll-y="true" @scrolltolower="scrolltolower">
|
|
<view class="view-list course-list">
|
|
<course-item class="course-item" v-for="itemC in courseList" :key="itemC.crsNum" :itemInfo="itemC" @clickItem="toCourseDetail(itemC)" />
|
|
<view class="view-tips">
|
|
{{ hasMore ? '滚动加载更多' : '全部加载完成' }}
|
|
</view>
|
|
</view>
|
|
<!-- <view class="view-result" v-show="courseList.length === 0">暂无数据</view> -->
|
|
<list-no-data v-show="courseList.length == 0">暂无数据</list-no-data>
|
|
</scroll-view>
|
|
</view>
|
|
<view class="search_content" v-else>
|
|
<view class="tabs-view">
|
|
<uv-tabs :list="tabList" @click="changeTab" :scrollable="false" active-style="font-weight:bold; color:#000;" line-color="#06f"></uv-tabs>
|
|
</view>
|
|
<scroll-view class="lists-view" :scroll-y="true" @scrolltolower="scrolltolower">
|
|
<view class="ability-view model-view" v-show="showModelList('ability')">
|
|
<view class="view-title">
|
|
<image src="@/static/images/search/result/ability.png" class="view-title-img"></image>
|
|
功能
|
|
</view>
|
|
<view class="view-list">
|
|
<view class="ability-view-item" v-for="item in abilityListShow" @click="clickAbility(item)">
|
|
<image class="icon" v-if="item.type === 'course'" src="@/static/images/index/navigation_course.png"></image>
|
|
<image class="icon" v-if="item.type === 'dialog'" src="@/static/images/index/navigation_question_answering.png"></image>
|
|
<image class="icon" v-if="item.type === 'test'" src="@/static/images/index/navigation_ai.png"></image>
|
|
<image class="icon" v-if="item.type === 'task'" src="@/static/images/index/navigation_learning_tasks.png"></image>
|
|
<image class="icon" v-if="item.type === 'exam'" src="@/static/images/index/navigation_examination.png"></image>
|
|
<image class="icon" v-if="item.type === 'examTest'" src="@/static/images/index/navigation_practice.png"></image>
|
|
<image class="icon" v-if="item.type === 'wrong'" src="@/static/images/index/navigation_wrong_question.png"></image>
|
|
<image class="icon" v-if="item.type === 'analysis'" src="@/static/images/index/navigation_learning_analysis.png"></image>
|
|
<view class="title">{{ item.title }}</view>
|
|
</view>
|
|
</view>
|
|
<view class="view-result" v-show="abilityListShow.length === 0">暂无数据</view>
|
|
</view>
|
|
|
|
<view class="course-view model-view" v-show="showModelList('course')">
|
|
<view class="view-title">
|
|
<image src="@/static/images/search/result/course.png" class="view-title-img"></image>
|
|
课程
|
|
</view>
|
|
<view class="view-list course-list">
|
|
<course-item class="course-item" v-for="itemC in courseList" :key="itemC.crsNum" :itemInfo="itemC" @clickItem="toCourseDetail(itemC)" />
|
|
</view>
|
|
<view class="view-tips" v-if="activeTab === 'course'">
|
|
{{ hasMore ? '滚动加载更多' : '全部加载完成' }}
|
|
</view>
|
|
<view class="view-result" v-show="courseList.length === 0">暂无数据</view>
|
|
</view>
|
|
<view class="task-view model-view" v-show="showModelList('task')">
|
|
<view class="view-title">
|
|
<image src="@/static/images/search/result/task.png" class="view-title-img"></image>
|
|
任务
|
|
</view>
|
|
<view class="view-list">
|
|
<TaskItem :item="item" v-for="(item, index) in taskList"></TaskItem>
|
|
</view>
|
|
<view class="view-tips" v-if="activeTab === 'task'">
|
|
{{ hasMore ? '滚动加载更多' : '全部加载完成' }}
|
|
</view>
|
|
<view class="view-result" v-show="taskList.length === 0">暂无数据</view>
|
|
</view>
|
|
<view class="test-view model-view" v-show="showModelList('test')">
|
|
<view class="view-title">
|
|
<image src="@/static/images/search/result/test.png" class="view-title-img"></image>
|
|
AI陪练
|
|
</view>
|
|
<view class="view-list"></view>
|
|
<view class="view-result" v-show="testList.length === 0">暂无数据</view>
|
|
</view>
|
|
<view class="exam-view model-view" v-show="showModelList('exam')">
|
|
<view class="view-title">
|
|
<image src="@/static/images/search/result/exam.png" class="view-title-img"></image>
|
|
考试
|
|
</view>
|
|
<view class="view-list">
|
|
<ExamItem class="exam-list" :item="item" v-for="item in examList"></ExamItem>
|
|
</view>
|
|
<view class="view-tips" v-if="activeTab === 'exam'">
|
|
{{ hasMore ? '滚动加载更多' : '全部加载完成' }}
|
|
</view>
|
|
<view class="view-result" v-show="examList.length === 0">暂无数据</view>
|
|
</view>
|
|
</scroll-view>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { ref, watchEffect, nextTick, onMounted, computed } from 'vue'
|
|
import common from '@/common/common.js'
|
|
import { onShow } from '@dcloudio/uni-app'
|
|
import TaskItem from '@/pages/learningTasks/components/content-item.vue'
|
|
import ExamItem from '@/pages/testingHall/components/content-item.vue'
|
|
import { onLoad } from '@dcloudio/uni-app'
|
|
import { appSearchCrsApi } from '@/api/search.js'
|
|
|
|
const fromType = ref('')
|
|
onLoad(params => {
|
|
inputValue.value = params.searchName
|
|
fromType.value = params.from
|
|
pageInfo.value.limit = fromType.value === 'course' ? 15 : 3
|
|
})
|
|
onShow(() => {
|
|
search()
|
|
})
|
|
// 静态样式配置
|
|
const fixedCustomStyles = {
|
|
backgroundColor: '#ffffff',
|
|
paddingLeft: '40rpx',
|
|
paddingTop: '5px',
|
|
paddingBottom: '5px',
|
|
border: 'none'
|
|
}
|
|
const inputValue = ref('')
|
|
const searchValue = ref('')
|
|
const activeTab = ref('')
|
|
const tabList = ref([
|
|
{
|
|
name: '全部',
|
|
type: 'all'
|
|
},
|
|
{
|
|
name: '功能',
|
|
type: 'ability'
|
|
},
|
|
{
|
|
name: '课程',
|
|
type: 'course'
|
|
},
|
|
{
|
|
name: '任务',
|
|
type: 'task'
|
|
},
|
|
{
|
|
name: 'AI陪练',
|
|
type: 'test'
|
|
},
|
|
{
|
|
name: '考试',
|
|
type: 'exam'
|
|
}
|
|
])
|
|
const abilityListShow = computed(() => {
|
|
if (searchValue.value) {
|
|
let _arr = abilityList.value.filter(t => t.title.includes(searchValue.value.toUpperCase()))
|
|
let _sum = 4 - (_arr.length % 4)
|
|
if (_sum !== 4) {
|
|
for (let i = 0; i < _sum; i++) {
|
|
_arr.push({})
|
|
}
|
|
}
|
|
return _arr
|
|
} else {
|
|
return abilityList.value
|
|
}
|
|
})
|
|
const abilityList = ref([
|
|
{
|
|
title: 'AI学习',
|
|
type: 'course',
|
|
path: '/pages/course/index',
|
|
isTab: true
|
|
},
|
|
{
|
|
title: 'AI问答',
|
|
type: 'dialog',
|
|
path: '/pages/index/dialog',
|
|
params: {
|
|
animationType: 'slide-in-bottom'
|
|
}
|
|
},
|
|
{
|
|
title: 'AI陪练',
|
|
type: 'test',
|
|
path: ''
|
|
},
|
|
{
|
|
title: '学习任务',
|
|
type: 'task',
|
|
path: '/pages/learningTasks/index'
|
|
},
|
|
{
|
|
title: '考试中心',
|
|
type: 'exam',
|
|
path: '/pages/testingHall/index'
|
|
},
|
|
{
|
|
title: '竞赛练习',
|
|
type: 'examTest',
|
|
path: ''
|
|
},
|
|
{
|
|
title: '错题本',
|
|
type: 'wrong',
|
|
path: '/pages/wrongQuestionRecord/index'
|
|
},
|
|
{
|
|
title: '学习分析',
|
|
type: 'analysis',
|
|
path: ''
|
|
}
|
|
])
|
|
const testList = ref([])
|
|
const taskList = ref([])
|
|
const examList = ref([])
|
|
const courseList = ref([])
|
|
const showModelList = typeName => {
|
|
return ['', 'all', typeName].indexOf(activeTab.value) >= 0
|
|
}
|
|
const changeTab = item => {
|
|
if (!item) return
|
|
activeTab.value = item.type
|
|
console.log(item)
|
|
switch (item.type) {
|
|
case 'all':
|
|
pageInfo.value.limit = 3
|
|
break
|
|
case 'ability':
|
|
break
|
|
case 'course':
|
|
pageInfo.value.limit = 15
|
|
break
|
|
case 'task':
|
|
pageInfo.value.limit = 15
|
|
break
|
|
case 'test':
|
|
pageInfo.value.limit = 15
|
|
break
|
|
case 'exam':
|
|
pageInfo.value.limit = 15
|
|
break
|
|
default:
|
|
pageInfo.value.limit = 3
|
|
break
|
|
}
|
|
getData(1)
|
|
}
|
|
const clickAbility = item => {
|
|
if (item.isTab) {
|
|
common.switchTab(item.path)
|
|
} else {
|
|
common.navigateTo(item.path, item.params || {})
|
|
}
|
|
}
|
|
const pageInfo = ref({
|
|
page: 1,
|
|
limit: 3,
|
|
total: 0
|
|
})
|
|
const search = () => {
|
|
searchValue.value = inputValue.value
|
|
const pages = getCurrentPages()
|
|
if (pages.length >= 2) {
|
|
const prevPage = pages[pages.length - 2]
|
|
if (prevPage.route === 'pages/search/search') {
|
|
if (prevPage.$vm && typeof prevPage.$vm.$?.exposed?.search === 'function') {
|
|
prevPage.$vm.$?.exposed?.search(searchValue.value, false)
|
|
}
|
|
}
|
|
}
|
|
|
|
getData(1)
|
|
}
|
|
const getMore = () => {
|
|
if(activeTab.value && activeTab.value !== 'all'){
|
|
getData()
|
|
}
|
|
}
|
|
const getData = (flag = null) => {
|
|
if (flag) {
|
|
pageInfo.value.page = 1
|
|
courseList.value = []
|
|
examList.value = []
|
|
taskList.value = []
|
|
}
|
|
let _isCourse = fromType.value === 'course' || activeTab.value==='course'
|
|
appSearchCrsApi({
|
|
type: _isCourse ? '01'
|
|
: activeTab.value==='exam' ? '02'
|
|
: activeTab.value==='task' ? '03'
|
|
: '00', //00 首页搜索 01课程搜索 '02' 考试搜索 '03' 任务搜索
|
|
searchName: searchValue.value,
|
|
page: pageInfo.value.page,
|
|
limit: pageInfo.value.limit
|
|
}).then(res => {
|
|
courseList.value = courseList.value.concat(res.body.traCrsInfoVoList || [])
|
|
if (fromType.value !== 'course') {
|
|
examList.value = examList.value.concat(res.body.traExamPapersExtVoList || [])
|
|
taskList.value = taskList.value.concat(res.body.traTaskInfoExtVoList || [])
|
|
}
|
|
pageInfo.value.total = res.total || 0
|
|
// switch (activeTab.value) {
|
|
// case 'all':
|
|
// break
|
|
// case 'ability':
|
|
// break
|
|
// case 'course':
|
|
// pageInfo.value.total = res.total || 0
|
|
// break
|
|
// case 'task':
|
|
// pageInfo.value.total = res.total || 0
|
|
// break
|
|
// case 'test':
|
|
// pageInfo.value.total = res.total || 0
|
|
// break
|
|
// case 'exam':
|
|
// pageInfo.value.total = res.total || 0
|
|
// break
|
|
// default:
|
|
// pageInfo.value.total = res.total || 0
|
|
// break
|
|
// }
|
|
})
|
|
}
|
|
const hasMore = computed(() => {
|
|
return pageInfo.value.limit * pageInfo.value.page <= pageInfo.value.total
|
|
})
|
|
const scrolltolower = () => {
|
|
if (!hasMore.value) {
|
|
return
|
|
}
|
|
pageInfo.value.page += 1
|
|
getData()
|
|
}
|
|
const toCourseDetail = item => {
|
|
common.navigateTo('/pages/courseDetail/index?crsId=' + item.crsId)
|
|
}
|
|
</script>
|
|
|
|
<style scoped lang="scss">
|
|
.search_content {
|
|
height: calc(100% - 94rpx);
|
|
background-color: #fff;
|
|
border-radius: 30rpx 30rpx 0 0;
|
|
|
|
.tabs-view {
|
|
height: 84rpx;
|
|
}
|
|
|
|
.lists-view {
|
|
height: calc(100% - 90rpx);
|
|
box-sizing: border-box;
|
|
padding: 24rpx 30rpx;
|
|
&.lists-view-course {
|
|
height: 100%;
|
|
}
|
|
.view-result {
|
|
width: 100%;
|
|
text-align: center;
|
|
height: 100rpx;
|
|
line-height: 100rpx;
|
|
color: #999;
|
|
font-size: 26rpx;
|
|
}
|
|
.view-tips {
|
|
padding-top: 20rpx;
|
|
width: 100%;
|
|
text-align: center;
|
|
color: #999;
|
|
font-size: 25rpx;
|
|
}
|
|
.model-view {
|
|
border: 2px solid #f1f1f1;
|
|
border-radius: 15rpx;
|
|
padding: 20rpx 24rpx 24rpx;
|
|
margin-bottom: 24rpx;
|
|
|
|
.view-title {
|
|
height: 40rpx;
|
|
line-height: 40rpx;
|
|
padding-left: 50rpx;
|
|
position: relative;
|
|
font-size: 29rpx;
|
|
|
|
.view-title-img {
|
|
position: absolute;
|
|
left: 5rpx;
|
|
top: 5rpx;
|
|
width: 30rpx;
|
|
height: 30rpx;
|
|
}
|
|
}
|
|
&.ability-view {
|
|
.view-list {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
justify-content: space-between;
|
|
}
|
|
}
|
|
.view-list {
|
|
overflow: hidden;
|
|
|
|
.scroll-view-item {
|
|
display: inline-block;
|
|
margin-right: 30rpx;
|
|
background-color: #ffffff;
|
|
border-radius: 22rpx;
|
|
box-shadow: #eaeaea 0 0 6rpx;
|
|
padding: 32rpx 22rpx 36rpx 26rpx;
|
|
}
|
|
&.course-list {
|
|
margin: 6rpx -20rpx 0;
|
|
}
|
|
.exam-list {
|
|
border: 2rpx solid #e8e8e8;
|
|
}
|
|
.course-item {
|
|
display: flex;
|
|
.left {
|
|
border-radius: 16rpx;
|
|
overflow: hidden;
|
|
width: 180rpx;
|
|
height: 146rpx;
|
|
|
|
.img {
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
}
|
|
|
|
.right {
|
|
width: calc(100% - 180rpx);
|
|
margin-left: 22rpx;
|
|
display: flex;
|
|
flex-direction: column;
|
|
justify-content: space-between;
|
|
|
|
.title {
|
|
width: 100%;
|
|
font-weight: 500;
|
|
font-size: 30rpx;
|
|
color: #333333;
|
|
line-height: 40rpx;
|
|
text-align: left;
|
|
font-style: normal;
|
|
}
|
|
|
|
.note {
|
|
font-family: PingFangSC, PingFang SC;
|
|
font-weight: 400;
|
|
font-size: 23rpx;
|
|
color: #666666;
|
|
line-height: 33rpx;
|
|
text-align: left;
|
|
font-style: normal;
|
|
}
|
|
|
|
.button_div {
|
|
display: flex;
|
|
justify-content: flex-end;
|
|
|
|
.button {
|
|
text-align: center;
|
|
line-height: 62rpx;
|
|
width: 138rpx;
|
|
height: 62rpx;
|
|
background: #ebf1ff;
|
|
border-radius: 30rpx;
|
|
font-weight: 500;
|
|
font-size: 30rpx;
|
|
color: #0066ff;
|
|
font-style: normal;
|
|
margin-right: 10rpx;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
.ability-view-item {
|
|
width: 98rpx;
|
|
margin-right: 50rpx;
|
|
float: left;
|
|
margin-top: 24rpx;
|
|
|
|
&:nth-child(4n) {
|
|
margin-right: 0rpx;
|
|
}
|
|
|
|
.icon {
|
|
width: 88rpx;
|
|
height: 86rpx;
|
|
margin-left: 5rpx;
|
|
}
|
|
|
|
.title {
|
|
margin-top: 10rpx;
|
|
font-family: PingFangSC, PingFang SC;
|
|
font-weight: 400;
|
|
font-size: 25rpx;
|
|
white-space: nowrap;
|
|
line-height: 35rpx;
|
|
text-align: center;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
.fixed_search_div {
|
|
padding: 10rpx 15rpx 24rpx 10rpx;
|
|
display: flex;
|
|
align-items: center;
|
|
height: 94rpx;
|
|
box-sizing: border-box;
|
|
|
|
.back_div {
|
|
// margin-right: 10rpx;
|
|
padding: 10rpx 10rpx 10rpx 20rpx;
|
|
|
|
// background-color: red;
|
|
.back-icon {
|
|
position: relative;
|
|
width: 40rpx;
|
|
height: 40rpx;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.back-icon::before,
|
|
.back-icon::after {
|
|
content: '';
|
|
position: absolute;
|
|
transition: all 0.3s ease;
|
|
}
|
|
|
|
.back-icon::after {
|
|
top: 25%;
|
|
left: 25%;
|
|
width: 40%;
|
|
height: 40%;
|
|
border-top: 4rpx solid #2b2c2e;
|
|
border-left: 4rpx solid #2b2c2e;
|
|
transform: rotate(-45deg);
|
|
}
|
|
}
|
|
}
|
|
|
|
.main_div {
|
|
width: 100vw;
|
|
background: linear-gradient(90deg, #f1f7ff 0%, #d8edff 50%, #c3e6ff 100%);
|
|
padding-top: var(--status-bar-height);
|
|
height: 100vh;
|
|
overflow: hidden;
|
|
}
|
|
::v-deep .uv-tabs__wrapper__nav__item__text {
|
|
white-space: nowrap;
|
|
}
|
|
</style>
|