课程中心联调完成 95%

This commit is contained in:
yanghang
2025-06-19 18:47:01 +08:00
parent 21db4ae1a0
commit a28f134234
4 changed files with 290 additions and 61 deletions
+2 -2
View File
@@ -3,5 +3,5 @@ ENV = 'development'
# 'development'
# base api
VITE_APP_BASE_API_Url = 'http://25.18.122.66:9786'
# VITE_APP_BASE_API_Url = 'http://25.64.16.133:9786'
# VITE_APP_BASE_API_Url = 'http://25.18.122.66:9786'
VITE_APP_BASE_API_Url = 'http://25.64.16.133:9786'
+57 -16
View File
@@ -1,27 +1,68 @@
import request from '@/api/request'
const base_url = '/traapp'
// 获取课程分类树接口
export const getCourseTypeListApi = (data) => {
return request({
url: '/traapp/app/traCrsCatalogInfo/courseQueryTraCrsCatalogInfoList',
method: 'post',
data
});
return request({
url: base_url + '/app/traCrsCatalogInfo/courseQueryTraCrsCatalogInfoList',
method: 'post',
data
});
};
// 获取生产线分类树接口
export const getPrdLineTypeListApi = (data) => {
return request({
url: '/traapp/app/traPrdLineInfo/courseQueryTraPrdLineInfoList',
method: 'post',
data
});
return request({
url: base_url + '/app/traPrdLineInfo/courseQueryTraPrdLineInfoList',
method: 'post',
data
});
};
// 获取标签分类树 接口
export const getTraTagListApi = (data) => {
return request({
url: '/traapp/app/traTagCatalogInfo/queryTraTagCatalogInfoList',
method: 'post',
data
});
};
return request({
url: base_url + '/app/traTagCatalogInfo/queryTraTagCatalogInfoList',
method: 'post',
data
});
};
// 全部模块
export const queryCrsInfoByCatalogApi = (data) => {
return request({
url: base_url + '/crsInfo/queryCrsInfoByCatalog',
method: 'post',
data
});
};
// 生产线模块-
export const queryCrsInfoByPrdLineApi = (data) => {
return request({
url: base_url + '/crsInfo/queryCrsInfoByPrdLine',
method: 'post',
data
});
};
// 最新
export const queryCrsInfoByLastnewApi = (data) => {
return request({
url: base_url + '/crsInfo/queryCrsInfoByLastnew',
method: 'post',
data
});
};
// 最热
export const queryCrsInfoByPopularApi = (data) => {
return request({
url: base_url + '/crsInfo/queryCrsInfoByPopular',
method: 'post',
data
});
};
// 推荐
export const queryCrsInfoByRecmdApi = (data) => {
return request({
url: base_url + '/crsInfo/queryCrsInfoByRecmd',
method: 'post',
data
});
};
+49 -15
View File
@@ -1,13 +1,18 @@
<template>
<view class="course-item-box" @click="clickItem">
<ImagePreview class="img-box"></ImagePreview>
<view class="img-box-view">
<ImagePreview class="img-box"></ImagePreview>
<view class="item-grade">{{itemInfo.evalGrade}}</view>
</view>
<view class="cont-box">
<view class="item-title">{{itemInfo.crsName}}</view>
<uv-scroll-list class="item-tags" :indicator="false">
<view class="item-tag" v-for="item in itemInfo.tagsList">{{item.tagName}}</view>
<view class="item-tag-view">
<view class="item-tag" v-for="item in itemInfo.tagCataList">{{item.tagName}}</view>
</view>
</uv-scroll-list>
<view class="item-publish">发布{{itemInfo.publicTime}}</view>
<view class="item-num">已学{{itemInfo.learnedNum}}人次</view>
<view class="item-publish">发布{{itemInfo.issuTm}}</view>
<view class="item-num">已学{{itemInfo.accmStdyCnt}}人次</view>
</view>
</view>
</template>
@@ -37,7 +42,7 @@
},
methods:{
clickItem(){
this.$emit('clickItem')
this.$emit('clickItem', this.itemInfo)
}
}
}
@@ -47,10 +52,29 @@
.course-item-box{
padding: 15rpx;
overflow: hidden;
.img-box{
.img-box-view{
width: 170rpx;
height: 170rpx;
float: left;
position: relative;
.img-box{
width: 170rpx;
height: 170rpx;
}
.item-grade{
position: absolute;
right: 0;
width: 60rpx;
height: 46rpx;
background-color: #ff581c;
top:20rpx;
border-radius: 8rpx 0 0 8rpx;
color:#fff;
text-align: center;
// padding-right: 10rpx;
font-size: 28rpx;
line-height: 46rpx;
}
}
.cont-box{
width: calc(100% - 170rpx);
@@ -68,15 +92,25 @@
}
.item-tags{
padding-bottom: 0 !important;
.item-tag{
height: 32rpx;
line-height: 32rpx;
font-size: 20rpx;
background-color: #eee;
color: rgb(51, 51, 51);
padding: 0 20rpx;
border-radius: 16rpx;
margin-right: 20rpx;
.item-tag-view{
white-space: nowrap;
height: 34rpx;
.item-tag{
height: 32rpx;
line-height: 32rpx;
font-size: 20rpx;
background-color: #eee;
color: rgb(51, 51, 51);
padding: 0 20rpx;
border-radius: 16rpx;
margin-right: 20rpx;
display: inline-block;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 200rpx;
box-sizing: border-box;
}
}
}
.item-publish,
+182 -28
View File
@@ -7,15 +7,15 @@
<uv-icon class="arrow-icon" name="arrow-left" @click="common.navigateBack()"/>
课程中心
</view>
<view class="input-view">
<uv-input shape="circle"
placeholderStyle='color:#999999;font-size:28rpx'
placeholder="请输入课程名"
suffixIcon="search"
:customStyle="customStyle"
:suffixIconStyle="suffixIconStyle"
:readonly="true">
</uv-input>
<view class="input-view" @click="toSearchPage">
<uv-input shape="circle"
placeholderStyle='color:#999999;font-size:28rpx'
placeholder="请输入课程名"
suffixIcon="search"
:customStyle="customStyle"
:suffixIconStyle="suffixIconStyle"
:readonly="true">
</uv-input>
</view>
<view class="tabs-view">
<uv-tabs :list="tabList" @click="changeTab" :scrollable="false"
@@ -25,8 +25,23 @@
</view>
<view class="list-view">
<uv-scroll-list class="tags-view" :indicator="false">
<uv-tags text="全部" shape="circle" plain class="tags-item" size="mini"></uv-tags>
<uv-tags text="全部" v-for="item in 15" shape="circle" plain type="info" class="tags-item" size="mini"></uv-tags>
<uv-tags text="全部"
shape="circle"
plain
class="tags-item"
size="mini"
:type="activeTag === ''?'primary':'info'"
@click="chooseTag({value:''})"
></uv-tags>
<uv-tags :text="item.label"
v-for="item in tagsList"
:key="item.value"
shape="circle"
plain
:type="activeTag === item.value?'primary':'info'"
@click="chooseTag(item)"
class="tags-item" size="mini"
></uv-tags>
</uv-scroll-list>
<view class="course-list">
<view class="left-type-list" v-if="'全部' === activeTab">
@@ -34,7 +49,7 @@
v-for="item in courseTypeList"
:key="item.value"
:class="['type-item',activeCourseType == item.value ?'is-active':'']"
@click="activeCourseType = item.value"
@click="changeCourseType(item)"
>
{{item.label}}
</view>
@@ -44,13 +59,38 @@
v-for="item in coursePrdlineList"
:key="item.value"
:class="['type-item', activePrdlineType == item.value ?'is-active':'']"
@click="activePrdlineType = item.value"
@click="changePrdLine(item)"
>
{{item.label}}
</view>
</view>
<view class="right-course-list">
<CourseItem v-for="item in 6"/>
<view
class="type-list"
v-for="item in courseListTreeShow"
:key="item.value"
>
<view
class="type-title"
v-if="item.courseList.length > 0 && showTypeName"
>
<!-- v-if="itemT.courseList.length>0 && " -->
<view class="left-color"></view>
{{item.label}}
</view>
<CourseItem v-for="itemC in item.courseList" :key="itemC.crsNum" :itemInfo="itemC" @clickItem="toCourseDetail(itemC)"/>
<view
class="type-list"
v-for="itemT in item.children"
:key="itemT.value"
>
<view class="type-title" v-if="itemT.courseList.length>0">
<view class="left-color"></view>
{{itemT.label}}
</view>
<CourseItem v-for="itemTC in itemT.courseList" :key="itemTC.crsNum" :itemInfo="itemTC" @clickItem="toCourseDetail(itemTC)"/>
</view>
</view>
</view>
</view>
</view>
@@ -64,7 +104,12 @@
import {
getPrdLineTypeListApi,
getTraTagListApi,
getCourseTypeListApi
getCourseTypeListApi,
queryCrsInfoByCatalogApi,
queryCrsInfoByPrdLineApi,
queryCrsInfoByLastnewApi,
queryCrsInfoByPopularApi,
queryCrsInfoByRecmdApi
} from "@/api/course.js"
import { onMounted, ref, computed } from 'vue'
const customStyle = {
@@ -93,41 +138,130 @@ import { onMounted, ref, computed } from 'vue'
const activeTab = ref('全部')
const activeCourseType = ref('')
const activePrdlineType = ref('')
const activeTag = ref('')
const courseTypeList = ref([])
const coursePrdlineList = ref([])
const tagsTree = ref([])
// 点击标签
const chooseTag = (item)=>{
activeTag.value = item.value
}
// 点击生产线分类
const changePrdLine = (item)=>{
activePrdlineType.value = item.value
}
// 点击课程分类
const changeCourseType = (item)=>{
activeCourseType.value = item.value
setTimeout(()=>{
console.log(courseListTreeShow.value)
})
}
const showTypeName = computed(()=>{
return (activeTab.value === '全部' && activeCourseType.value === '') || (activeTab.value === '生产线' && activePrdlineType.value === '')
})
const tagsList = computed(()=>{
let _arr = []
tagsTree.value.forEach(t=>{
let _tarr = t.children || []
_arr = _arr.concat(_tarr)
})
return _arr.sort(a,b=>{
t.required == "y" && b.required === 'N'
return _arr.sort((a,b)=>{
a.required == "Y" && b.required === 'N'
})
})
const courseListBase = ref([])
const courseList = computed(()=>{
return activeTag.value
?courseListBase.value.filter(t=>t.tagCataList.indexOf(activeTag.value)>=0)
:courseListBase.value
})
// 整理树形
const courseListTree = computed(()=>{
let _arr = activeTab.value === '全部'? courseTypeList.value
: activeTab.value === '生产线'? coursePrdlineList.value: []
let _idKey = activeTab.value === '全部'? 'tagId': 'prdLineId'
let _tree = _arr.map(t=>{
let _children = t.children||[]
return {
label: t.label,
required: t.required,
value:t.value,
courseList: courseList.value.filter(k=>k[_idKey] === t.value),
children: _children.map(k=>{
return {
...k,
courseList: courseList.value.filter(m=>m[_idKey] === k.value),
}
})
}
})
return _tree
})
// 过滤树形
const courseListTreeShow = computed(()=>{
let _type = activeTab.value === '全部'? activeCourseType.value : activePrdlineType.value
if(activeTab.value === '全部'|| activeTab.value === '生产线'){
if(_type){
return courseListTree.value.filter(t=> t.value === _type)
}else{
return courseListTree.value
}
}else{
return [{
children: [],
courseList: courseList.value,
label: "",
value: "333"
}]
}
})
const changeTab = (item) => {
if(!item) return
activeTab.value = item.name
activeCourseType.value = ''
activePrdlineType.value = ''
switch (item.name){
case '全部':
console.log(item.name)
queryCrsInfoByCatalogApi().then(res=>{
courseListBase.value = res.body || []
})
break;
case '热门':
console.log(item.name)
queryCrsInfoByPopularApi().then(res=>{
courseListBase.value = res.body || []
})
break;
case '最新':
console.log(item.name)
queryCrsInfoByLastnewApi().then(res=>{
courseListBase.value = res.body || []
})
break;
case '推荐':
console.log(item.name)
queryCrsInfoByRecmdApi().then(res=>{
courseListBase.value = res.body || []
})
break;
case '生产线':
console.log(item.name)
queryCrsInfoByPrdLineApi().then(res=>{
courseListBase.value = res.body || []
})
break;
}
}
// 跳转搜索页
const toSearchPage = () => {
common.navigateTo('/pages/search/search')
}
// 跳转 课程详情
const toCourseDetail = (item) => {
console.log(item.crsNum)
// common.navigateTo('/pages/course/detail/' + item.crsNum)
}
onMounted(()=>{
getCourseTypeListApi().then(res=>{
courseTypeList.value = res.body||[]
@@ -138,6 +272,7 @@ import { onMounted, ref, computed } from 'vue'
getTraTagListApi().then(res=>{
tagsTree.value = res.body||[]
})
changeTab({name:'全部'})
})
</script>
@@ -218,6 +353,9 @@ import { onMounted, ref, computed } from 'vue'
padding: 0 20rpx;
.uv-tags__text{
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 200rpx;
}
}
}
@@ -248,11 +386,27 @@ import { onMounted, ref, computed } from 'vue'
.right-course-list{
flex:1;
overflow-y: auto;
// .course-box{
// width: 100%;
// height: 100%;
// overflow-y: auto;
// }
.type-list{
.type-title{
font-size: 33rpx;
line-height: 43rpx;
margin: 20rpx 15rpx 5rpx;
height: 43rpx;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
font-weight: 600;
.left-color{
width: 8rpx;
height: 33rpx;
margin-top: 5rpx;
float: left;
overflow: hidden;
background-color: #06f;
margin-right: 8rpx;
}
}
}
}
}
}