Compare commits

..

1 Commits

Author SHA1 Message Date
Caojr
7eefffed0f fix 35 2025-07-02 17:06:14 +08:00
17 changed files with 356 additions and 1381 deletions

View File

@@ -1,7 +1,7 @@
/**
* 课程的操作,课程的添加,修改,列表查询,课程的审核发布等操作。
* 针对于管理员,教师的功能
*
*
**/
import ajax from '@/utils/xajax.js'
@@ -170,9 +170,7 @@ const updateContentOrders = function(cid,items) {
const detail = function(id) {
return ajax.get('/xboe/m/course/manage/detail?id=' + id);
}
const getDictIds = function(pid,type) {
return ajax.get(`/xboe/m/course/manage/getDictIds?pid=${pid}&type=${type}`);
}
/**
* 更新内容的名称
* @param {Object} data
@@ -276,7 +274,7 @@ const countWaitAudit = function() {
}
/**
* [已用courseAudit中的hrbpAuditList替换]
* [已用courseAudit中的hrbpAuditList替换]
* 当前用户需要审核的课程列表
* @param {Object} query 同pageList
*/
@@ -285,9 +283,9 @@ const auditList = function(query) {
}
/**
* 【已移到courseAudit中】
* 教师需要审核的课程列表
/**
* 【已移到courseAudit中】
* 教师需要审核的课程列表
*/
const teacherAuditList = function(query) {
return ajax.post('/xboe/m/course/audit/teacher-course', query);
@@ -448,7 +446,6 @@ export default {
findUpdateLogs,
getUpdateLog,
detail,
getDictIds,
saveContent,
pageList,
setEnabled,

View File

@@ -1,64 +0,0 @@
/**课程标签模块的相关处理*/
import ajax from '@/utils/xajax.js'
/**
* 分页查询:标签列表
* @param {Object} query
*/
const portalPageList = function(query) {
return ajax.post('/xboe/m/coursetag/page', query);
}
//改变标签的公共属性
const changeTagPublic = function (row){
// 返回 Promise 的 API 调用
return ajax.post('/xboe/m/coursetag/changePublicStatus', {
id: row.id,
isPublic: row.isPublic
});
}
//改变标签的热点属性
const changeTagHot = function (row){
// 返回 Promise 的 API 调用
return ajax.post('/xboe/m/coursetag/changeHotStatus', {
id: row.id,
isHot: row.isHot
});
}
//查询指定id的标签关联的所有课程
const showCourseByTag = function (query){
return ajax.post('/xboe/m/coursetag/showCourseByTag', query);
}
//解除指定id的课程和某个标签之间的关联关系
const unbindCourseTagRelation = function (params){
return ajax.post('/xboe/m/coursetag/unbind', params);
}
//编辑课程:标签模糊查询
const searchTags = function (params){
return ajax.post('/xboe/m/coursetag/searchTags', params);
}
//编辑课程:创建标签(与当前课程关联)
const createTag = function (params){
return ajax.post('/xboe/m/coursetag/createTag', params);
}
//获取最新前10个热点标签
const getHotTagList = function (params){
return ajax.post('/xboe/m/coursetag/getHotTagList', params);
}
export default {
portalPageList,
changeTagPublic,
changeTagHot,
showCourseByTag,
unbindCourseTagRelation,
searchTags,
createTag,
getHotTagList
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

View File

@@ -73,9 +73,6 @@
:props="{ value: 'id', label: 'name' }"
:options="sysTypeListMap"></el-cascader>
</el-form-item>
<el-form-item label="标签" required>
<courseTag ref="courseTag" :courseId="curCourseId" :sysTypeList="sysTypeList" :initialTags="courseTags" @change="handleTagsChange"></courseTag>
</el-form-item>
<el-form-item label="资源归属" required>
<el-input placeholder="请选择" v-model="orgName" >
<el-button v-if="identity==3 || identity==5" @click="showChooseOrg()" slot="append" icon="el-icon-search">选择</el-button>
@@ -256,9 +253,6 @@
</el-select> -->
<choice :teacherValue="teacherValues" @getTeacherList="getTeacherList"></choice>
</el-form-item>
<el-form-item label="标签" required>
<courseTag ref="courseTag" :courseId="curCourseId" :sysTypeList="sysTypeList" :initialTags="courseTags" @change="handleTagsChange"></courseTag>
</el-form-item>
<el-form-item label="关键字">
<el-input v-model.trim="keywords" maxlength="100" @keyup.enter.native="changeKeywords" placeholder="请输入关键字"></el-input>
<el-tag v-for="(tag,index) in tips" size="small" :key="index" closable type="info" @close="closeKeywordsTag(tag,index)">
@@ -408,7 +402,6 @@
</div>
</template>
<script>
import courseTag from "@/components/Course/courseTag.vue";
import choice from '@/components/Course/choice.vue';
import agreement from '@/components/Portal/agreement.vue';
import weikeContent from '@/components/Course/weikeContent.vue';
@@ -425,7 +418,6 @@ import apiCourse from '../../api/modules/course.js';
import apiCourseAudit from '../../api/modules/courseAudit.js';
import apiOrg from '../../api/system/organiza.js';
import apiUser from '../../api/system/user.js';
import apiCourseTag from '../../api/modules/courseTag.js';
import WxEditor from '@/components/Editor/index.vue';
import catalogSort from '@/components/Course/catalogSort.vue';
import { courseType, getType } from '../../utils/tools.js';
@@ -434,7 +426,7 @@ import filecloud from '@/components/FileCloud/index.vue';
import chooseOrg from '@/components/System/chooseOrg.vue';
export default {
props: {},
components: { courseTag, weikeContent, catalogCourseware, imageUpload, WxEditor, catalogSort,agreement,filecloud,choice,chooseOrg},
components: { weikeContent, catalogCourseware, imageUpload, WxEditor, catalogSort,agreement,filecloud,choice,chooseOrg},
data() {
return {
keywords:'',//关键字的定义
@@ -474,7 +466,6 @@ export default {
orgName:'',
orgNamePath:'',
orgKid:'',
courseTags:[],
courseInfo: {
id: '',
name: '',
@@ -601,15 +592,6 @@ export default {
closeKeywordsTag(item,index){
this.tips.splice(index, 1);
},
// 处理标签变化事件
handleTagsChange(tags) {
console.log("父组件:",tags)
let ids = "";
tags.forEach(tag=>{
ids += tag.id + ',';
})
this.courseInfo.tags = ids;
},
showChooseOrg(){
this.$refs.refChooseOrg.dlgShow = true;
},
@@ -740,7 +722,6 @@ export default {
this.$emit('close');
},
initShow(editData) {
console.log('初始化显示内容============', editData)
//console.log(this.$refs.weikePanel,'this.$refs.weikePanel');
//this.$refs.weikePanel.init();
//this.$refs.onlineCourse.resetData();
@@ -788,8 +769,6 @@ export default {
this.tips=[];
if (!editData) {
this.tips=[];
this.courseTags=[],
//console.log("新建课程?");
//以下为了保证初始化处理
this.weikeReset = Math.round(Math.random()) + '';
@@ -886,8 +865,6 @@ export default {
if (rs.status == 200) {
this.courseChooseShow = false;
this.courseInfo = rs.result;
this.curCourseId = this.courseInfo.id
console.log('保存课程成功',this.curCourseId)
if (this.courseChooseId == 1) {
this.weike.dlgShow = true;
} else {
@@ -916,8 +893,6 @@ export default {
try {
const { result, status } = await apiCourse.detail(id);
if (status === 200) {
this.courseTags = result.tagList;
console.log('获取课程信息成功', this.courseTags);
//把数据附给三个对象
if(result.course.visible==''){
result.course.visible=false;
@@ -983,6 +958,7 @@ export default {
}
});
}
this.resOwnerArray=[];
if (result.course.resOwner1 == '') {
this.resOwnerArray.push(result.course.resOwner1);
@@ -1267,7 +1243,7 @@ export default {
teachers: saveTeachers,
crowds:crowds
};
console.log(postData);
//console.log(postData);
//this.btnLoading=false;
apiCourse
.saveBase(postData)

View File

@@ -1,229 +0,0 @@
<template>
<div class="tag-container">
<el-select style="width: 100%;"
v-model="selectedTags"
multiple
filterable
value-key="id"
remote
reserve-keyword
:remote-method="debouncedSearch"
:loading="loading"
:disabled="sysTypeList.length===0"
:placeholder="sysTypeList.length === 0 ? '请先选择课程分类' : '请输入标签名称'"
@remove-tag="handleTagRemove"
@change="handleSelectionChange"
@keyup.enter.native="handleEnterKey"
@keyup.delete.native="handleDeleteKey"
ref="tagSelect"
>
<el-option
v-for="item in searchResults"
:key="item.id"
:label="item.tagName"
:value="item"
/>
</el-select>
</div>
</template>
<script>
import { debounce } from 'lodash'
import apiCourseTag from '@/api/modules/courseTag.js'
import { mapGetters } from 'vuex';
export default {
props: {
courseId:{
type:String,
require:true,
},
sysTypeList:{
type:Array,
require:true,
default: []
},
maxTags: {
type: Number,
default: 10
},
// 添加接收初始标签数据的props
initialTags: {
type: Array,
default: () => []
}
},
data() {
return {
selectedTags: [],
searchResults: [],
loading: false,
tagMap: new Map(),
inputBuffer: '',
params: {},
tag: {}
}
},
computed: {
...mapGetters(['userInfo']),
displayTags() {
return this.selectedTags.map(tag =>
typeof tag === 'object' ? tag : this.tagMap.get(tag)
).filter(Boolean)
}
},
created() {
this.debouncedSearch = debounce(this.doSearch, 500)
console.log("----------sysTypeList.length---------->"+this.sysTypeList.length)
console.log("----------sysTypeList.length---------->"+(this.sysTypeList.length===0))
},
// 添加:挂载时初始化标签数据
mounted() {
if (this.initialTags && this.initialTags.length > 0) {
this.selectedTags = this.initialTags;
this.searchResults = this.initialTags;
// 将初始标签添加到tagMap中确保删除功能正常
this.initialTags.forEach(tag => {
if (tag.id) {
this.tagMap.set(tag.id, tag);
}
});
}
},
watch: {
// 监听课程ID变化重置所有状态
courseId(newVal) {
this.resetTagState();
},
// 监听初始标签变化,重新加载
initialTags(newVal) {
this.selectedTags = newVal || [];
this.searchResults = newVal || [];
this.tagMap.clear(); // 清空旧缓存
newVal.forEach(tag => {
if (tag.id) this.tagMap.set(tag.id, tag);
});
}
},
methods: {
// 新增:重置标签状态的方法
resetTagState() {
this.selectedTags = [];
this.searchResults = [];
this.tagMap.clear();
this.loading = false;
this.params = {};
},
handleTagRemove(tagId) {
this.selectedTags = this.selectedTags.filter(id => id !== tagId)
this.$emit('change', this.displayTags)
// 清空输入框内容
if (this.$refs.tagSelect) {
const input = this.$refs.tagSelect.$refs.input
if (input) {
input.value = ''
}
}
},
removeTag(tagId) {
this.handleTagRemove(tagId)
},
// 新增:处理删除键事件
handleDeleteKey(event) {
// 如果输入框内容为空,不执行任何搜索
if (!event.target.value.trim()) {
this.searchResults = []
}
},
//按回车键,创建新标签
handleEnterKey(event) {
const inputVal = event.target.value?.trim()
if (!this.searchResults.length && inputVal && this.selectedTags.length < this.maxTags) {
this.createNewTag(event.target.value.trim())
event.target.value = ''
}
},
// 新增:处理选择变化事件
handleSelectionChange() {
this.$emit('change', this.displayTags)
// 选择标签后清空输入框
if (this.$refs.tagSelect) {
const input = this.$refs.tagSelect.$refs.input
if (input) {
input.value = ''
}
}
},
//创建新标签
async createNewTag(tagName) {
// 标签不能超过八个字
if (tagName.length > 8) {
this.$message.error('标签不能超过8个字')
return;
}
this.loading = true
try {
this.params.courseId = this.courseId;
this.params.tagName = tagName;
// 分类
if (this.sysTypeList.length > 0) {
this.params.sysType1 = this.sysTypeList[0]; //一级的id
}
if (this.sysTypeList.length > 1) {
this.params.sysType2 = this.sysTypeList[1]; //二级的id
}
if (this.sysTypeList.length > 2) {
this.params.sysType3 = this.sysTypeList[2]; //三级的id
}
const {result:newTag} = await apiCourseTag.createTag(this.params)
this.$message.success('标签创建成功');
this.searchResults.push(newTag)
console.log("----------newTag---------->",this.searchResults)
this.tagMap.set(newTag.id, newTag)
this.$emit('change', this.displayTags)
} finally {
this.loading = false
}
},
// 修改doSearch方法添加搜索结果为空时的提示
async doSearch(query) {
if (!query.trim()) {
this.searchResults = []
return
}
this.loading = true
try {
const {result:tags} = await apiCourseTag.searchTags({tagName:query})
tags.forEach(item => {
this.tagMap.set(item.id, item)
})
this.searchResults = tags
// 当搜索结果为空时,提示用户可以按回车键创建标签
if (tags.length === 0) {
this.$message.info('无此标签,按回车键创建')
}
} finally {
this.loading = false
}
}
}
}
</script>
<style scoped>
.tag-container {
position: relative;
}
.tag-preview {
margin-top: 8px;
}
.el-tag {
margin-right: 6px;
margin-bottom: 6px;
}
</style>

View File

@@ -109,7 +109,7 @@ export default {
if(res.status==200){
this.info=res.result;
//检查是否过期
if(res.result.deadTime!='' && res.result.deadTime != null){
if(res.result.deadTime!=''){
var d = new Date(res.result.deadTime);
var now=new Date();
if(now.getTime() > d.getTime()){

View File

@@ -317,7 +317,7 @@ export default {
}
setInterval(() => {
console.log('当前状态:',this.currentProgress,this.isDrag,this.videoDom.currentTime , this.videoDom.duration)
//console.log('this.currentProgress::',this.currentProgress,this.isDrag,this.videoDom.currentTime , this.videoDom.duration)
// 视频播放时本地记录视频实时播放时长,视频设置了禁止拖动时执行
if(!this.isDrag){
var time = localStorage.getItem('videoProgressData')
@@ -364,11 +364,6 @@ export default {
}
// 根据视频的readyState判断下一帧是否已加载并控制loading的显示
this.isShowLoading = this.videoDom.readyState < 3;
console.log("当前缓存:"+this.videoDom.readyState)
if (this.videoDom.readyState < 3){
console.log("详细信息",this.videoDom)
console.log("卡了",this.videoDom.readyState)
}
//if()
//console.log(this.videoDom.readyState,'this.videoDom.readyState');
}, 1000);

View File

@@ -37,6 +37,7 @@ export default {
},
isDrag:{
type: Boolean,
default: true,
},
blobId:{
type: String,

View File

@@ -128,8 +128,7 @@ export const iframes=[
{title:'查看受众', path:'/iframe/ugroup/view',hidden:false,component:'manage/AudienceView'},
{title:'问答管理', path:'/iframe/qa/manages',hidden:false,component:'qa/ManageList'},
{title:'待审核课程', path:'/iframe/course/noapproved',hidden:false,component:'examine/NotApproved'},
{title:'已审核课程', path:'/iframe/course/reviewed',hidden:false,component:'examine/Reviewed'},
{title:'标签管理', path:'/iframe/tag/manages',hidden:false,component:'tag/TagManageList'},
{title:'已审核课程', path:'/iframe/course/reviewed',hidden:false,component:'examine/Reviewed'}
]

View File

@@ -624,8 +624,12 @@ export default {
// if(item.minute){
// item.duration=parseFloat(item.minute)*60;
// }
// 如果没有给一个默认值30分钟
item.duration = item.minute ? parseFloat(item.minute) * 60 : 1800;
// 视频文件才可以设置时长其他类型直接赋值0
if (item.fileType === 'mp4' || item.fileType === 'mp3') {
item.duration = item.minute ? parseFloat(item.minute) * 60 : 0;
} else {
item.duration = 0;
}
});
this.loading = true;
coueseFile.batchUpdate(this.fileList).then(rs => {

View File

@@ -5,8 +5,8 @@
<!-- 当轮播图等于一张时 -->
<swiper :options="swiperOptiontwo">
<swiper-slide style="margin: 0 auto" v-for="(item, idx) in resonimg" :key="'a' + idx"
class="swiper-slide games pointer" >
<div class="bannbox" @click="handleCarouselClick(item)" :style="{
class="swiper-slide games pointer">
<div class="bannbox" :style="{
background: `url(${fileBaseUrl + item.image
}) center center no-repeat`,
}"></div>
@@ -17,8 +17,8 @@
<div id="container" style="z-index: 99" v-else>
<swiper :options="swiperOption" ref="mySwiper" v-if="resonimg.length > 1">
<swiper-slide style="margin: 0 auto" v-for="(item, idx) in resonimg" :key="'b' + idx"
class="swiper-slide games pointer" >
<div class="bannbox" @click="handleCarouselClick(item)" :style="{
class="swiper-slide games pointer">
<div class="bannbox" :style="{
background: `url(${fileBaseUrl + item.image
}) center center no-repeat`,
}"></div>
@@ -220,7 +220,7 @@ export default {
autoplay: false,
// noSwiping: true,
},
// resonimg: [],
resonimg: [],
swiperOption: {
autoplay: {
delay: 2000,
@@ -249,13 +249,6 @@ export default {
this.getToolData()
},
methods: {
// 添加点击轮播图跳转的方法
handleCarouselClick(item) {
if (item.url) {
window.open(item.url, '_blank');
}
},
downTool(toolInfo) {
console.log(toolInfo);
window.open(`/activityApi/xboe/m/boe/tools/url/download?urlStr=${process.env.VUE_APP_BOE_WEB_URL}/upload${toolInfo.filePath}&fileName=${toolInfo.name}`)

View File

@@ -8,7 +8,7 @@
<div class="navTop">
<div>
<router-link to="/grateful" class="nav">首页</router-link>&nbsp;>&nbsp;
<span style="cursor: pointer;" class="nav">认证讲师库</span>
<span style="cursor: pointer;" class="nav">认证讲师库2023</span>
</div>
<div style="position: relative;">
<el-input class="portal-input" placeholder="请输入课程名称" style="border-radius: 20px !important; "

View File

@@ -20,7 +20,7 @@
</div>
<div class="label">
<author :aid="caseDetail.sysCreateAid" :onlyAvatar="true" :avatar="authorInfo.avatar"
:sex="authorInfo.sex" :name="authorInfo.name"></author>
:sex="authorInfo.sex"></author>
<span>案主{{ authorInfo.name }} ({{ authorInfo.orgInfo }})</span>
<!-- <span>案主{{ authorInfo.name }}</span>
<span>工号{{ authorInfo.code }}</span>

View File

@@ -1609,7 +1609,7 @@ export default {
})
console.log(res?.result?.list ,'有没有数据2');
this.caseList.list = res.result.list
this.getCaseUserData(res.result.list);
// this.getCaseUserData(res.result.list);
// 给所有的赋值
this.caseList.count = res.result.count;
this.caseList.showPagCount = res.result.count;

View File

@@ -43,7 +43,7 @@
:disabled="!twoList.children.length" :open-delay="0" :close-delay="0" trigger="hover"
:visible-arrow="false" @hide="leaveIndex" @show="changeIndex(twoList.id)" transition="none">
<div class="course-two-content" slot="reference">{{
twoList.name }}</div>-
twoList.name }}</div>
<!-- 内容 -->
<div class="course-three-box">
<div class="course-three-box-title">
@@ -284,40 +284,32 @@
<!-- 内容导航 -->
<div class="topNav" v-if="!newData">
<div class="search-div nav" style="height: 100px;flex: 1;">
<div @click="handleTypeAllClick(1)" class="option-item" style="font-weight: bold" :class="{ 'option-active': ctypeTagAll }">
<div @click="handleTypeAllClick(1)" class="option-item" :class="{ 'option-active': ctypeTagAll }">
<a>全部</a>
<span :class="ctypeTagAll ? 'nav-bottbor' : ''"></span>
</div>
<div @click="handleTypeClick(ctypeList[0], ctypeList)" class="option-item" style="font-weight: bold"
<div @click="handleTypeClick(ctypeList[0], ctypeList)" class="option-item"
:class="{ 'option-active': ctypeList[0].checked }">
<a>录播课</a>
<span :class="ctypeList[0].checked ? 'nav-bottbor' : ''"></span>
</div>
<div @click="handleTypeClick(ctypeList[1], ctypeList)" class="option-item" style="font-weight: bold"
<div @click="handleTypeClick(ctypeList[1], ctypeList)" class="option-item"
:class="{ 'option-active': ctypeList[1].checked }">
<a>线下课</a>
<span :class="ctypeList[1].checked ? 'nav-bottbor' : ''"></span>
</div>
<div @click="handleTypeClick(ctypeList[2], ctypeList)" class="option-item" style="font-weight: bold"
<div @click="handleTypeClick(ctypeList[2], ctypeList)" class="option-item"
:class="{ 'option-active': ctypeList[2].checked }">
<a>学习项目</a>
<span :class="ctypeList[2].checked ? 'nav-bottbor' : ''"></span>
</div>
<a class="option-item">
<span @click="uClassClick" class="Uxtext" style="font-weight: bold"> U选小课堂
<span @click="uClassClick" class="Uxtext" style=""> U选小课堂
<span class="uxicon">
<svg-icon icon-class="hot" style="font-size:22px"></svg-icon>
</span>
</span>
</a>
<!-- 热点标签 add by zhengsongbo on 2025-08-01 -->
<div style="margin-top:10px;flex: 1;">
<div class="option-item" style="padding-top: 2px"
v-for="tag in hotTagsList" :key="tag.id"
@click="handleTagClick(tag, hotTagsList)">
<a class="custom" :class="tag.checked ? 'custom2' : ''">{{tag.tagName}}</a>
</div>
</div>
</div>
<div id="fixd-box" class="upload" style="margin-left: 26px;">
<div v-if="identity == 2 || identity == 3 || identity == 5">
@@ -333,11 +325,9 @@
<div v-if="stagList.length > 0 && !newData" class="search-div" style="padding: 0;margin-bottom: 20px;">
<div class="searchbar" style="background-color:#f6f7fb;display: flex;justify-content: space-between;">
<div style="line-height: 30px;">
<span class="item-title"> 搜索条件:</span>
<el-tag closable v-for="(tag, tagIdx) in stagList" :key="'t' + tagIdx" @close="stagClose(tag, tagIdx)"
:style="{ color: tag.type === 0 ? '#ff0000' : '' }">
{{ tag.tagName }}
</el-tag>
<span class="item-title"> 搜索条件</span>
<el-tag closable v-for="(tag, tagIdx) in stagList" :key="'t' + tagIdx" @close="stagClose(tag, tagIdx)">{{
tag.name }}</el-tag>
</div>
<div>
<el-button type="primary" size="mini" @click="handleClearTags">清除</el-button>
@@ -371,9 +361,6 @@
<span v-if="cinfo.type == 40" class="course-type-left">学习项目</span>
</div>
<div class="course-title two-line-ellipsis" :title="cinfo.title" v-html="cinfo.name"></div>
<el-tag v-for="tag in cinfo.tagList" v-if="cinfo.tagList && cinfo.tagList.length > 0" :style="{ color: '',margin: '5px'}">
{{tag.tagName}}
</el-tag>
<!-- 关键字 -->
<div class="keywordInfo-every">
<div class="keywordInfo" v-for="(keyword, index) in cinfo.keywordsActive" :key="index">
@@ -520,14 +507,12 @@ import apiTeacher from "@/api/modules/teacher.js";
import apiUser from "@/api/system/user.js";
import scene from "@/api/modules/scene.js";
import apiUserbasic from "@/api/boe/userbasic.js";
import apiManage from '@/api/manage/manage.js';
import interactBar from "@/components/Portal/interactBar.vue";
import courseImage from "@/components/Course/courseImage.vue";
import { courseType, getType, toScore, formatDate, formatUserNumber, formatDateByFmt } from "@/utils/tools.js";
import { deepClone, param } from "../../../utils";
import apiSearchterm from "@/api/modules/searchterm.js";
import apiPlace from "@/api/phase2/place.js"
import apiCourseTag from '@/api/modules/courseTag.js'
export default {
name: "index",
components: {
@@ -549,43 +534,21 @@ export default {
},
stagList() { //计算出选择的内容
let list = [];
// 关键词
if (this.keyword) {
list.push({
type: 0,
id: 'keyword',
name: this.keyword,
tagName: this.keyword,
checked: true
});
})
}
// 课程类型
this.ctypeList.forEach(item => {
if (item.checked) {
list.push({
...item,
tagName: item.name
});
list.push(item);
}
});
// 热点标签 - 这是关键修复
this.hotTagsList.forEach(item => {
if (item.checked) {
list.push({
...item,
name: item.tagName || item.name,
tagName: item.tagName || item.name,
type: 14
});
}
});
// 三级分类
this.oneList.forEach(one => {
var twoChildChecked = false;
var twoChildChecked = false;//是否有下级
one.children.forEach(two => {
if (two.checked) {
twoChildChecked = true;
@@ -593,28 +556,34 @@ export default {
var threeChildChecked = false;
two.children.forEach(three => {
if (three.checked) {
list.push({
...three,
tagName: three.name
});
list.push(three);
threeChildChecked = true;
}
});
if (two.checked && !threeChildChecked) {
list.push({
...two,
tagName: two.name
});
list.push(two);
}
});
if (one.checked && !twoChildChecked) {
list.push({
...one,
tagName: one.name
});
list.push(one);
}
});
})
// this.oneList.forEach(item=>{
// if(item.checked){
// list.push(item);
// }
// });
// this.twoList.forEach(item=>{
// if(item.checked){
// list.push(item);
// }
// });
// this.threeList.forEach(item=>{
// if(item.checked){
// list.push(item);
// }
// });
//console.log(list,'list');
return list;
},
ctypeTagAll() {
@@ -644,14 +613,12 @@ export default {
},
data() {
return {
hotTagsList: [],
newData: false,//线上品牌系列隐藏
navTitle: [],
// 设置高亮
twoId: '',
count: 0,//分页总条条数
showUClass: false,
projectDialogVisible: false,
ctypeList: [
{ type: 1, id: 20, name: '录播课', checked: false },
{ type: 1, id: 30, name: '线下课', checked: false },
@@ -662,7 +629,7 @@ export default {
twoList: [], //二级分类{type:12}
threeList: [],//三级分类{type:13}
searching: false,//是否正在搜索中
studentInfo: {},
resonimg: {},
formatDate,
formatNum: formatUserNumber,
@@ -720,17 +687,6 @@ export default {
console.log(rs.message);
}
})
//初始化:获取最新前10个热点标签
apiCourseTag.getHotTagList(null).then(rs => {
if (rs.status == 200) {
this.hotTagsList = rs.result.map(tag => ({
...tag,
checked: false
}));
} else {
console.log(rs.message);
}
})
},
mounted() {
let screenWidth = window.screen.availWidth;
@@ -896,54 +852,10 @@ export default {
//搜索条件
stagClose(tag, tagIndex) {
tag.checked = false;
// 根据标签类型处理不同的清除逻辑
if (tag.type == 0) {
// 关键词类型
this.keyword = '';
} else if (tag.type == 1) {
// 课程类型(录播课、线下课、学习项目)
this.ctypeList.forEach(item => {
if (item.id == tag.id) {
item.checked = false;
}
});
} else if (tag.type == 14) {
// 热点标签类型
this.hotTagsList.forEach(item => {
if (item.id == tag.id) {
item.checked = false;
}
});
// 更新course.tags移除被删除的热点标签
const checkedHotTags = this.hotTagsList.filter(tag => tag.checked);
let tagIds = checkedHotTags.map(tag => tag.id).join(',');
this.course.tags = tagIds;
} else if (tag.type == 11 || tag.type == 12 || tag.type == 13) {
// 三级分类标签
this.oneList.forEach(one => {
if (one.id == tag.id) {
one.checked = false;
}
one.children.forEach(two => {
if (two.id == tag.id) {
two.checked = false;
}
two.children.forEach(three => {
if (three.id == tag.id) {
three.checked = false;
}
});
});
});
}
// 重置导航标题
this.navTitle = [];
// 触发搜索更新
this.navTitle = []
this.searchData();
},
@@ -981,33 +893,28 @@ export default {
this.searchData();
},
// 清除
handleClearTags() {
//清空所有的条件
this.keyword = '';
this.ctypeList.forEach(item => {
item.checked = false;
});
this.hotTagsList.forEach(item => {
item.checked = false;
});
this.course.tags = ''; // 清空标签ID
// 添加清除三级分类的逻辑
this.oneList.forEach(one => {
one.checked = false;
one.children.forEach(two => {
two.checked = false;
two.children.forEach(three => {
three.checked = false;
handleClearTags() {
//清空所有的条件
this.keyword = '';
this.ctypeList.forEach(item => {
item.checked = false;
});
});
});
// 清空导航标题
this.navTitle = [];
this.searchData();
},
this.oneList.forEach(one => {
one.checked = false;
one.children.forEach(two => {
two.checked = false;
two.children.forEach(three => {
three.checked = false;
})
})
});
this.twoList = [];
this.threeList = [];
this.navTitle = [];
this.newData = false;
sessionStorage.removeItem(this.localSessionKey)
this.searchData();
},
// 导航切换(录播课,线下课,学习项目)
handleTypeClick(item, list) {
item.checked = !item.checked;
@@ -1019,24 +926,11 @@ handleClearTags() {
this.searchData();
},
//点击标签
handleTagClick(item, list) {
item.checked = !item.checked;
// 更新course.tags
const checkedTags = this.hotTagsList.filter(tag => tag.checked);
let tagIds = checkedTags.map(tag => tag.id).join(',');
this.course.tags = tagIds;
// 强制触发stagList重新计算
this.$nextTick(() => {
this.searchData();
});
},
//三级分类
handleOptionClick(item, level, list) {
// 线上品牌展示效果
this.newData = item.newData;
console.log(this.newData);
// 单选,排除法
this.oneList.forEach(one => {
one.checked = false;
@@ -1413,18 +1307,12 @@ handleClearTags() {
},
getAllChecked() { //获取全部选中的标签
let list = [];
//获取选中的课程类型
this.ctypeList.forEach(item => {
if (item.checked) {
list.push(item);
}
});
//获取选中的热点标签
this.hotTagsList.forEach(item => {
if (item.checked) {
list.push(item);
}
});
this.oneList.forEach(one => {
one.children.forEach(two => {
two.children.forEach(three => {
@@ -1487,18 +1375,7 @@ handleClearTags() {
that.course.sysType3 += item.id;
}
});
apiCourseTag.getHotTagList(that.course).then(rs => {
if (rs.status == 200) {
// 保留已选中标签的状态
const currentCheckedTags = this.hotTagsList.filter(tag => tag.checked);
this.hotTagsList = rs.result.map(tag => ({
...tag,
checked: currentCheckedTags.some(checkedTag => checkedTag.id === tag.id)
}));
} else {
console.log(rs.message);
}
}),
this.isFind = true;
this.course.device = 1;
if (this.course.pageIndex == 1) {
@@ -1540,7 +1417,7 @@ handleClearTags() {
item.name = item.name;
}
});
console.log(res.result.list,'data')
console.log(res.result.list,'data')
this.courseList = res?.result?.list ?? []
console.log(this.courseList);
if (this.newData) {
@@ -2544,73 +2421,4 @@ handleClearTags() {
.option-active {
color: #387DF7;
}
/* 项目简介 方法一:外部 CSS 类 */
::v-deep.el-dialog {
border-radius: 3% 3% 1% 1%;
padding: 0;
}
::v-deep.custom-class .el-dialog__header {
height: 100px;
margin: 0 !important;
padding: 0 !important;
background-image: url('../../../assets/images/project/title-bg.png');
background-size: 100% 100%; /* 完全填充 */
display: block; /* 避免行内元素空隙 */
}
::v-deep.custom-class .el-dialog__header .el-dialog__title {
padding: 0 !important;
font-size: 35px;
font-weight: bold;
color: white;
margin: 60px;
line-height: 100px;
}
::v-deep.custom-class .el-dialog__body {
margin: 0 !important;
padding: 0 !important;
}
/* ---end--- */
/* ---标签管理 added by zhengsongbo on 2025-08-01--- */
.search-div.nav {
display: block;
width: 100%;
clear: both;
}
.option-item {
margin: 0px 5px;
}
/* 热点标签:自定义按钮样式 */
a.custom {
/* 基础样式 */
display: inline-block; /* 使内边距生效 */
padding: 1px; /* 按钮内边距 */
margin: 1px 5px;
background-color: #F2F2F2; /* 淡灰色背景 */
color: #333; /* 文字颜色 */
text-decoration: none; /* 去除下划线 */
border-radius: 3px; /* 圆角设计 */
font-family: Arial, sans-serif; /* 字体 */
font-size: 14px; /* 文字大小 */
height: 24px;
line-height: 20px;
/* 过渡效果,使颜色变化更平滑 */
transition: background-color 0.2s ease;
}
/* 鼠标悬停效果 */
a.custom:hover {
background-color: #DDEDFF; /* 浅蓝色背景 */
}
/* 可选:点击时效果 */
a.custom:active {
background-color: #757575; /* 点击时更深的灰色 */
}
/* 鼠标悬停效果 */
a.custom2 {
background-color: #DDEDFF; /* 浅蓝色背景 */
}
/* ---end--- */
</style>
}</style>

View File

@@ -22,101 +22,91 @@
<div class="course-playbox" ref="coursePlayerBox" id="id_course_player_box">
<div class="course-player" ref="coursePlayer" id="id_course_player">
<div>
<div v-if="renderCourse">
<div v-if="resType == null || resType == 0">
<!--先显示视频图片-->
<course-image v-if="courseInfo.id != ''" :course="courseInfo"></course-image>
</div>
<div v-if="resType == 10" style="position: relative;">
<videoPlayer ref="myVideoPlayer" id="myVideoPlayer" @progress="progress" :src="blobUrl" :blobId="blobId" @onPlayerPlaying="onPlayerPlaying"
:initTime="contentData.lastStudyTime" :notePlay="notePlay" @onPlayerPlay="onPlayerPlay"
:isDrag="curriculumData.isDrag" @onFullscreen="onFullscreen" @onPlayerPause="onPlayerPause"
@onPlayerEnded="onPlayerEnded" :isCrowd="isCrowd" @onTimeUpdate="handleAudioTimeUpdate"></videoPlayer>
<div class="player-box" v-if="playerBoxShow">
<div class="player-praise" style="cursor: pointer;">
<div @click="praiseContent">
<img class="icon-small" v-if="isPraise" :src="require('@/assets/images/icon/praise-active.png')" />
<img class="icon-small" v-else :src="require('@/assets/images/icon/zhan.png')" />
<!-- {{ courseInfo.praises }} -->
<div style="color:#fff;cursor: pointer;"></div>
</div>
<div style="margin-left: 15px;cursor: pointer;" @click="treadContent">
<img class="icon-small" v-if="isTrample"
:src="require('@/assets/images/icon/trample-active.png')" />
<img class="icon-small" v-else :src="require('@/assets/images/icon/cai.png')" />
<!-- {{ courseInfo.trampleCount }} -->
<div style="color:#fff;cursor: pointer;"></div>
</div>
<div v-if="resType == null || resType == 0">
<!--先显示视频图片-->
<course-image v-if="courseInfo.id != ''" :course="courseInfo"></course-image>
</div>
<div v-if="resType == 10" style="position: relative;">
<videoPlayer ref="myVideoPlayer" id="myVideoPlayer" @progress="progress" :src="blobUrl" :blobId="blobId" @onPlayerPlaying="onPlayerPlaying"
:initTime="contentData.lastStudyTime" :notePlay="notePlay" @onPlayerPlay="onPlayerPlay"
:isDrag="curriculumData.isDrag" @onFullscreen="onFullscreen" @onPlayerPause="onPlayerPause"
@onPlayerEnded="onPlayerEnded" :isCrowd="isCrowd" @onTimeUpdate="handleAudioTimeUpdate"></videoPlayer>
<div class="player-box" v-if="playerBoxShow">
<div class="player-praise" style="cursor: pointer;">
<div @click="praiseContent">
<img class="icon-small" v-if="isPraise" :src="require('@/assets/images/icon/praise-active.png')" />
<img class="icon-small" v-else :src="require('@/assets/images/icon/zhan.png')" />
<!-- {{ courseInfo.praises }} -->
<div style="color:#fff;cursor: pointer;"></div>
</div>
<div v-if="!scoreInfo.has" class="player-rate">
<div style="margin-left: 15px;cursor: pointer;" @click="treadContent">
<img class="icon-small" v-if="isTrample"
:src="require('@/assets/images/icon/trample-active.png')" />
<img class="icon-small" v-else :src="require('@/assets/images/icon/cai.png')" />
<!-- {{ courseInfo.trampleCount }} -->
<div style="color:#fff;cursor: pointer;"></div>
</div>
</div>
<div v-if="!scoreInfo.has" class="player-rate">
<el-rate v-model="scoreInfo.score" text-color="#ff9900" score-template="{value}" void-color="#fff" @change="addScore"></el-rate>
<el-rate v-model="scoreInfo.score" text-color="#ff9900" score-template="{value}" void-color="#fff" @change="addScore"></el-rate>
</div>
<div v-if="scoreInfo.has" style="padding-top: 5px;display: flex;">
<div class="player-rate" style="padding-left: 35px;">
<el-rate disabled v-model="courseInfo.score" :allow-half="true"></el-rate>
</div>
<div v-if="scoreInfo.has" style="padding-top: 5px;display: flex;">
<div class="player-rate" style="padding-left: 35px;">
<el-rate disabled v-model="courseInfo.score" :allow-half="true"></el-rate>
</div>
<span class="score-text" style="margin-top:35px">
<span class="score-text" style="margin-top:35px">
<span style="color:#ffb30f;">{{ toScore(courseInfo.score) }}</span>
<span style="font-size: 12px;color: #fff"></span>
</span>
</div>
</div>
</div>
<div v-if="resType == 20">
<div class="con-audio">
<div class="con-audio-title">{{ contentData.contentName }}</div>
<div class="con-audio-player">
<audioPlayer v-if="resType == 20" :url="blobUrl" :name="contentData.contentName" @onPlaying="audioPlaying" :isDrag="curriculumData.isDrag"
@onPlay="audioPlay" @onPause="audioPause" @onPlayEnd="audioEnd"></audioPlayer>
</div>
</div>
</div>
<div v-if="resType == 40">
<div style="padding: 10px;color: #ed0000; " v-if="curCFile.converStatus < 2 && !contentData.content">
<div>此课程内容无法预览请联系管理员</div>
</div>
<div style="padding: 10px;color: #ed0000;" v-if="curCFile.converStatus == 3 && !contentData.content">
此课程内容无法预览请联系管理员
</div>
<pdfPreview :autoScroll="true" v-if="resType == 40" :filePath="fileBaseUrl + contentData.content">
</pdfPreview>
</div>
<div v-if="resType == 41">
<div style="padding: 20px;" v-html="contentData.content"></div>
</div>
<div v-if="resType == 50" style="min-height: 500px;">
<iframe v-if="scormUrl" :src="scormUrl" frameborder="0" border="0px" style="width:100%;height:500px;border:0px;"></iframe>
</div>
<div v-if="resType == 52">
<div v-if="contentData.content != ''">
<div class="hyper-link" v-if="conLink.openType == 2">
<div class="hyper-link-row">{{ contentData.contentName }}</div>
<div class="hyper-link-row">{{ conLink.url }}</div>
</div>
<div v-if="conLink.openType == 1"><iframe :src="conLink.url"
style="width: 100%;border:0px;min-height: 473px;" frameborder="0"></iframe></div>
</div>
</div>
<div v-if="resType == 60">
<homework @submit="homeWorkSubmit" v-if="resType == 60 && studyId != ''" :studyId="studyId" :content="contentData"></homework>
</div>
<div v-if="resType == 61">
<exam @startTest="startTest" v-if="resType == 61 && studyId != '' " :studyId="studyId" :content="contentData"></exam>
</div>
<div v-if="resType == 62" style="padding:5px">
<assess v-if="resType == 62 && studyId != '' && contentData.id" :studyId="studyId" :content="contentData">
</assess>
</div>
</div>
<div v-if="!renderCourse && Internet ==2" style="margin:350px 250px" class="jianjie pdftext" id="pdfPreview">
<div style="margin-top:40px;font-weight:700;font-size: 22px;color: #ccc">
<span>十分抱歉您当前的网络环境不符合观看要求为了保障课程信息的安全您需要接入公司内网才能观看</span>
<div v-if="resType == 20">
<div class="con-audio">
<div class="con-audio-title">{{ contentData.contentName }}</div>
<div class="con-audio-player">
<audioPlayer v-if="resType == 20" :url="blobUrl" :name="contentData.contentName" @onPlaying="audioPlaying" :isDrag="curriculumData.isDrag"
@onPlay="audioPlay" @onPause="audioPause" @onPlayEnd="audioEnd"></audioPlayer>
</div>
</div>
<div style="margin-top:20px;text-align:center" @click="refreshPage">
<el-button type="primary">重新检测</el-button>
</div>
<div v-if="resType == 40">
<div style="padding: 10px;color: #ed0000; " v-if="curCFile.converStatus < 2 && !contentData.content">
<div>此课程内容无法预览请联系管理员</div>
</div>
<div style="padding: 10px;color: #ed0000;" v-if="curCFile.converStatus == 3 && !contentData.content">
此课程内容无法预览请联系管理员
</div>
<pdfPreview :autoScroll="true" v-if="resType == 40" :filePath="fileBaseUrl + contentData.content">
</pdfPreview>
</div>
<div v-if="resType == 41">
<div style="padding: 20px;" v-html="contentData.content"></div>
</div>
<div v-if="resType == 50" style="min-height: 500px;">
<iframe v-if="scormUrl" :src="scormUrl" frameborder="0" border="0px" style="width:100%;height:500px;border:0px;"></iframe>
</div>
<div v-if="resType == 52">
<div v-if="contentData.content != ''">
<div class="hyper-link" v-if="conLink.openType == 2">
<div class="hyper-link-row">{{ contentData.contentName }}</div>
<div class="hyper-link-row">{{ conLink.url }}</div>
</div>
<div v-if="conLink.openType == 1"><iframe :src="conLink.url"
style="width: 100%;border:0px;min-height: 473px;" frameborder="0"></iframe></div>
</div>
</div>
<div v-if="resType == 60">
<homework @submit="homeWorkSubmit" v-if="resType == 60 && studyId != ''" :studyId="studyId" :content="contentData"></homework>
</div>
<div v-if="resType == 61">
<exam @startTest="startTest" v-if="resType == 61 && studyId != '' " :studyId="studyId" :content="contentData"></exam>
</div>
<div v-if="resType == 62" style="padding:5px">
<assess v-if="resType == 62 && studyId != '' && contentData.id" :studyId="studyId" :content="contentData">
</assess>
</div>
</div>
<!--交互部分-->
@@ -177,7 +167,7 @@
</div>
<!-- 课程单元 -->
<div class="course-units" v-if="tab == 1">
<div style="min-height: 350px;max-height: 650px ;overflow-y: auto;">
<div :style="`height: ${controlHeight}px;overflow-y: auto;`">
<div class="catalog" v-if="courseInfo.type == 20">
<div v-for="(item, index) in catalogTree" :key="index" :name="index">
<el-menu
@@ -313,17 +303,6 @@
</div>
</div>
</div>
<el-dialog class="protocol" :close-on-click-modal="false" :visible="protocolDialogVisible" width="30%"
:show-close="false">
<div class="protocol-title">{{warnTitle}}</div>
<div class="protocol-content">
&emsp;&emsp;{{warn}}
</div>
<span slot="footer" class="dialog-footer">
<el-button type="primary" @click="protocolDialogVisible = false">
</el-button>
</span>
</el-dialog>
<!-- <div><portal-footer></portal-footer></div> -->
</div>
</template>
@@ -390,7 +369,6 @@
},
data() {
return {
protocolDialogVisible: false,
tentative: false,
isContentTypeTwo: null,
isContentType: null,
@@ -412,7 +390,6 @@
curCFile: {
converStatus: 4,
},
Internet: 3,//1是成功 2是是失败 3是检测中
radio: '',
interactRuning: false,
playerBoxShow: false,
@@ -454,7 +431,6 @@
getType: getType,
ctabName: 'catalog',
resType: null,
renderCourse: true,
activeNames: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
scoreInfo: {
dlgShow: false,
@@ -478,12 +454,9 @@
cumulativeDuration:0, //非音频累计时长
maxDuration:0, //非音频最大时长
defaultMaxTime:1800, //非音频默认最大时间
warn:"测试内容",
warnTitle:"测试标题",
}
},
mounted() {
this.getInternet();
// 增加的用户受众id
let localKey = "user_" + this.userInfo.sysId + "_gids";
let hasIds = sessionStorage.getItem(localKey);
@@ -531,6 +504,10 @@
return treeList;
}
},
destroyed(){
this.cleanAppendTime();
this.stopStudyTime();
},
methods: {
handleOpen(key,path){
if(this.isFalse){
@@ -545,13 +522,13 @@
},
noteChange(){
//视频点定位,直接到播放的视频位置
this.timer = new Date().getTime()
this.timer = new Date().getTime()
},
//清空追加学习时长事件
cleanAppendTime(){
if(this.appendStudyOtherHandle){
window.clearTimeout(this.appendStudyOtherHandle);
}
if(this.appendStudyOtherHandle){
window.clearTimeout(this.appendStudyOtherHandle);
}
},
//非音视频课学习时长的增加,每一分钟保存一次
appendStudyOtherTime() {
@@ -562,46 +539,46 @@
if (!this.contentData.id) {
return;
}
//每一分钟保存一次
// 取消阅读的每分钟六十秒的计时,最多是设置的时间或默认时间
let $this=this;
let startTime = new Date().getTime();
this.appendStudyOtherHandle = setTimeout(function() {
let endTime = new Date().getTime();
let totalTime = Math.round((endTime - startTime) / 1000);
$this.cumulativeDuration += totalTime;
if($this.cumulativeDuration <= $this.maxDuration){
//发送时长
$this.sendStudyOtherTime(totalTime);
//递归调用
$this.appendStudyOtherTime();
}else{
clearTimeout(this.appendStudyOtherHandle);
$this.cumulativeDuration = 0;
$this.maxDuration = 0;
}
}, 1000*60);
//每一分钟保存一次
// 取消阅读的每分钟六十秒的计时,最多是设置的时间或默认时间
let $this=this;
let startTime = new Date().getTime();
this.appendStudyOtherHandle = setTimeout(function() {
let endTime = new Date().getTime();
let totalTime = Math.round((endTime - startTime) / 1000);
$this.cumulativeDuration += totalTime;
if($this.cumulativeDuration <= $this.maxDuration){
//发送时长
$this.sendStudyOtherTime(totalTime);
//递归调用
$this.appendStudyOtherTime();
}else{
clearTimeout(this.appendStudyOtherHandle);
$this.cumulativeDuration = 0;
$this.maxDuration = 0;
}
}, 1000*60);
},
sendStudyOtherTime(totalTime){
//静默处理
apiStat.sendEvent({
"key": "StudyCourseOther",//课程学习的key
"title": "非音视频课内容",//事件的标题
"parameters":"second:" + totalTime,//second:value 本次的学习时长
"content": "学习课程",//事件的内容
"objId": this.courseInfo.id,//课程的id
"objType": "1",//类型
"source":"page",
"objInfo": ""+this.courseInfo.name,
"aid":this.userInfo.aid, //当前登录人的id
"aname":this.userInfo.name,//当前人的姓名
"status": 1 //状态
}).then(rs=>{
if(rs.status != 200) {
console.log(rs.message);
}
});
"key": "StudyCourseOther",//课程学习的key
"title": "非音视频课内容",//事件的标题
"parameters":"second:" + totalTime,//second:value 本次的学习时长
"content": "学习课程",//事件的内容
"objId": this.courseInfo.id,//课程的id
"objType": "1",//类型
"source":"page",
"objInfo": ""+this.courseInfo.name,
"aid":this.userInfo.aid, //当前登录人的id
"aname":this.userInfo.name,//当前人的姓名
"status": 1 //状态
}).then(rs=>{
if(rs.status != 200) {
console.log(rs.message);
}
});
},
//笔记组件触发,播放指定时间
onPlayVideo(contentId,time){
@@ -610,32 +587,32 @@
console.log(contentId,this.contentData.id,'两个内容id');
let $this=this;
if(this.contentData.id==contentId){
this.onPlayerPause()
this.contentData.lastStudyTime=time;
setTimeout(() => {
$this.$refs.myVideoPlayer.startPlay(time);
}, 10)
console.log('开始播放1');
this.onPlayerPause()
this.contentData.lastStudyTime=time;
setTimeout(() => {
$this.$refs.myVideoPlayer.startPlay(time);
}, 10)
console.log('开始播放1');
}else{
//通过contentId
let toResContent=null;
this.contentList.forEach(c => {
if(c.id==contentId){
c.lastStudyTime=time;
toResContent=c;
//通过contentId
let toResContent=null;
this.contentList.forEach(c => {
if(c.id==contentId){
c.lastStudyTime=time;
toResContent=c;
}
});
if(toResContent){
this.changePlayRes(toResContent);
setTimeout(() => {
$this.$refs.myVideoPlayer.startPlay(time);
}, 10)
console.log('开始播放2');
}else{
this.$message.error('资源已不存在或更换过,已无法定位');
}
});
if(toResContent){
this.changePlayRes(toResContent);
setTimeout(() => {
$this.$refs.myVideoPlayer.startPlay(time);
}, 10)
console.log('开始播放2');
}else{
this.$message.error('资源已不存在或更换过,已无法定位');
}
}
this.playerBoxShow = false;
},
@@ -713,23 +690,23 @@
}else if(r.contentType==50){ //scorm
this.scormUrl='';
apiCourseFile.detail(r.contentRefId).then(cfrs => {
if(cfrs.status==200){
this.curCFile = cfrs.result;
//this.scormUrl=cfrs
let pars='?mode=normal&r='+Math.random();
pars+='&scormId='+this.curCFile.id;
pars+='&courseId='+this.courseId;
pars+='&contentId='+r.id;
pars+='&studentId='+this.userInfo.aid;
pars+='&studentName='+encodeURIComponent(this.userInfo.name);
pars+='&lmsId='+this.studyId;
pars+='&scoId=';//不指定scorm模块自动根据学习记录定位
let urlPre=window.location.protocol;
let configUrl=process.env.VUE_APP_SCORM_URL;
configUrl=urlPre+configUrl.substring(configUrl.indexOf(':')+1);
if(cfrs.status==200){
this.curCFile = cfrs.result;
//this.scormUrl=cfrs
let pars='?mode=normal&r='+Math.random();
pars+='&scormId='+this.curCFile.id;
pars+='&courseId='+this.courseId;
pars+='&contentId='+r.id;
pars+='&studentId='+this.userInfo.aid;
pars+='&studentName='+encodeURIComponent(this.userInfo.name);
pars+='&lmsId='+this.studyId;
pars+='&scoId=';//不指定scorm模块自动根据学习记录定位
let urlPre=window.location.protocol;
let configUrl=process.env.VUE_APP_SCORM_URL;
configUrl=urlPre+configUrl.substring(configUrl.indexOf(':')+1);
this.scormUrl=configUrl+pars;//播放的首页
}
this.scormUrl=configUrl+pars;//播放的首页
}
});
}else if (r.contentType == 52) {
@@ -760,12 +737,12 @@
setTimeout(() => {
this.isContentTypeTwo = r.contentType
$this.isShowTime()
}, 2000);
}
}, 2000);
}
}
//以下是学习记录,50是scorm项目
if (this.contentData.contentType > 20 && this.contentData.contentType !== 50) { //非视频类的
//用户的学习时长,非音视频课程学习,单独的处理
//用户的学习时长,非音视频课程学习,单独的处理
this.isAppendTime = false;
this.appendStudyOtherHandle = setTimeout(function() {
@@ -775,18 +752,18 @@
// 没有设置默认时长三十分钟,
$this.maxDuration = r.duration !== 0 ? r.duration * 2 : $this.defaultMaxTime;
$this.$store.dispatch("userTrigger", {
"key": "StudyCourseOther",//课程学习的key
"title": "非音视频课内容",//事件的标题
"parameters":"second:15",//second:value 本次的学习时长
"content": "学习课程",//事件的内容
"objId": $this.courseInfo.id,//课程的id
"objType": "1",//类型
"source":"page",
"objInfo": ""+$this.courseInfo.name,
"aid":$this.userInfo.aid, //当前登录人的id
"aname":$this.userInfo.name,//当前人的姓名
"status": 1 //状态
});
"key": "StudyCourseOther",//课程学习的key
"title": "非音视频课内容",//事件的标题
"parameters":"second:15",//second:value 本次的学习时长
"content": "学习课程",//事件的内容
"objId": $this.courseInfo.id,//课程的id
"objType": "1",//类型
"source":"page",
"objInfo": ""+$this.courseInfo.name,
"aid":$this.userInfo.aid, //当前登录人的id
"aname":$this.userInfo.name,//当前人的姓名
"status": 1 //状态
});
$this.appendStudyOtherTime();
}, 15000); //非音视频课程学习,十五秒后记录
this.isContentType = this.contentData.contentType
@@ -803,21 +780,20 @@
this.$nextTick(function(){
if (r.contentType == 10) {
console.log('视频处理lastStudyTime',this.contentData.lastStudyTime)
console.log('视频处理progressVideo',this.contentData.progressVideo)
this.$refs.myVideoPlayer.updateProgressByClickBar2(this.contentData.lastStudyTime,this.contentData.progressVideo);
}
if (r.contentType == 10) {
console.log('视频处理lastStudyTime',this.contentData.lastStudyTime)
console.log('视频处理progressVideo',this.contentData.progressVideo)
this.$refs.myVideoPlayer.updateProgressByClickBar2(this.contentData.lastStudyTime,this.contentData.progressVideo);
}
let h=$this.$refs.coursePlayer.offsetHeight;
//解决获取高度不正的问题
if(h>400 && h<500){
h=h+40;
}else if(h>500){
h=h+60;
}
// 移除高度控制 防止内容塌陷
// $this.controlHeight=h-95;
let h=$this.$refs.coursePlayer.offsetHeight;
//解决获取高度不正的问题
if(h>400 && h<500){
h=h+40;
}else if(h>500){
h=h+60;
}
$this.controlHeight=h-95;
})
@@ -959,9 +935,9 @@
this.interactRuning = true;
let teacherId='';
if(this.teachers.length>0){
teacherId=this.teachers[0].teacherId;
teacherId=this.teachers[0].teacherId;
}else{
teacherId=this.courseInfo.sysCreateAid
teacherId=this.courseInfo.sysCreateAid
}
let postData = {
objType: 1,
@@ -1102,7 +1078,7 @@
class: 'catalog-cell-state1'
};
}
break;
break;
}
return data;
},
@@ -1163,8 +1139,8 @@
var markDiv = div.querySelector("#" + divId);
console.log("去除水印 ---- gx markDiv ----",markDiv);
if (markDiv) {
console.log("执行去除水印 ---- gx markDiv ----",markDiv);
div.removeChild(markDiv);
console.log("执行去除水印 ---- gx markDiv ----",markDiv);
div.removeChild(markDiv);
}
}
},
@@ -1223,9 +1199,9 @@
var time = localStorage.getItem('videoProgressData')
var arr = time&&JSON.parse(time) || {}
if(arr[this.blobId] && this.contentData.progressVideo<arr[this.blobId]) {
postData.progressVideo = arr[this.blobId]
// postData.contentId = this.contentData.id
// postData.courseId = this.contentData.courseId
postData.progressVideo = arr[this.blobId]
// postData.contentId = this.contentData.id
// postData.courseId = this.contentData.courseId
}
}
//console.log('记录播放时间')
@@ -1283,9 +1259,9 @@
var time = localStorage.getItem('videoProgressData')
var arr = time&&JSON.parse(time) || {}
if(arr[this.blobId] && this.contentData.progressVideo<arr[this.blobId]) {
postData.progressVideo = arr[this.blobId]
// postData.contentId = this.contentData.id
// postData.courseId = this.contentData.courseId
postData.progressVideo = arr[this.blobId]
// postData.contentId = this.contentData.id
// postData.courseId = this.contentData.courseId
}
}
//console.log('记录播放时间')
@@ -1323,17 +1299,6 @@
audiences:this.audiences
}).then(rs => {
if (rs.status == 200) {
if(rs.result.isPermission){
this.protocolDialogVisible=true
}
if (!rs.result.isPermission || (rs.result.isPermission && this.Internet==1)){
// this.getInternet()
this.renderCourse = true
}else{
// this.Internet=1;
this.renderCourse = false
this.protocolDialogVisible=true
}
if(rs.result.contents.length==0){
$this.$message.error('课程内容已删除或课程已不再使用');
return;
@@ -1344,11 +1309,11 @@
}
//设置必须的字段
if(rs.result.contents.length==1){
$this.tab=2;
//console.log('内容只有一个');
$this.tab=2;
//console.log('内容只有一个');
}
if(!rs.result.isCrowd){
$this.$message.error('您没有查看该课程的权限');
$this.$message.error('您没有查看该课程的权限');
}
// 是否播放
this.isCrowd = rs.result.isCrowd
@@ -1392,8 +1357,7 @@
}
}
this.courseInfo = rs.result.course;
this.warn = rs.result.warn;
this.warnTitle = rs.result.warnTitle;
if (rs.result.teachers && rs.result.teachers.length > 0) {
let userIds = [];
let ctoUsers = [];
@@ -1422,53 +1386,12 @@
this.totalContent = rs.result.contents.length;
//加载学习的数据
this.loadStudyData(rs.result);
} else {
this.$message.error(rs.message);
}
});
},
refreshPage() {
location.reload();
// this.getInternet();
// this.loadData();
},
getXmlHttpRequest() {
if (window.XMLHttpRequest) {
return new XMLHttpRequest();
}
else if (window.ActiveXObject) {
return new ActiveXObject("Microsoft.XMLHTTP");
}
},
// 检测是否为内网
getInternet() {
this.Internet = 3;
let $this = this;
let xmlhttp = this.getXmlHttpRequest();
let timedOut = false;
let timer = setTimeout(function () {
timedOut = true;
xmlhttp.abort();
}, 1000);
xmlhttp.open("HEAD", window.location.protocol + "//uapi.boe.com.cn/500.html", true);
xmlhttp.send();
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4) {
if (xmlhttp.status == 200) {
clearTimeout(timer);
$this.Internet = 1;
} else {
clearTimeout(timer);
// $this.protocolDialogVisible=true
$this.Internet = 2;
}
} else {
if (timedOut) return;//忽略中止请求
clearTimeout(timer);//取消等待的超时
}
}
},
loadStudyData(result) {
let $this=this;
this.loadScorePraiseAndTrample();
@@ -1591,37 +1514,37 @@
progress(val) {
const progressValue = parseFloat(val) * 100;
this.sendEventProgress = Number(progressValue.toFixed(2));
},
},
saveStudyDuration(duration) { //保存本地存储的学习时长
if (duration > 0) {
//发送用户学习事件
//console.log('保存到后台学习时长='+duration);
let postData={
"key": "StudyCourse",//课程学习的key
"title": "学习课程",//事件的标题
"parameters":"second:"+duration,//second:value,total:value 本次的学习时长
"content": "学习课程【"+this.courseInfo.name+"】",//事件的内容
"objId": this.courseInfo.id,//课程的id
"objType": "1",//类型
"source":"page",
"objInfo": ""+this.courseInfo.name,
"aid":this.userInfo.aid, //当前登录人的id
"aname":this.userInfo.name,//当前人的姓名
"status": 1, //状态
"contentId": this.contentData.id,
}
if(this.resType == 10){
postData.progress = this.sendEventProgress;
}
//静默处理
apiStat.sendEvent(postData).then(rs=>{
if(rs.status == 200) {
// this.appendStartTime = new Date();//重新计时
// studyUtil.clearStudyDuration(); //清除本地存储
} else {
console.log(rs.message);
"key": "StudyCourse",//课程学习的key
"title": "学习课程",//事件的标题
"parameters":"second:"+duration,//second:value,total:value 本次的学习时长
"content": "学习课程【"+this.courseInfo.name+"】",//事件的内容
"objId": this.courseInfo.id,//课程的id
"objType": "1",//类型
"source":"page",
"objInfo": ""+this.courseInfo.name,
"aid":this.userInfo.aid, //当前登录人的id
"aname":this.userInfo.name,//当前人的姓名
"status": 1, //状态
"contentId": this.contentData.id,
}
});
if(this.resType == 10){
postData.progress = this.sendEventProgress;
}
//静默处理
apiStat.sendEvent(postData).then(rs=>{
if(rs.status == 200) {
// this.appendStartTime = new Date();//重新计时
// studyUtil.clearStudyDuration(); //清除本地存储
} else {
console.log(rs.message);
}
});
// let postAppendData = {
// id: this.appentId,
// studyId: this.studyId,
@@ -1643,13 +1566,13 @@
},
//结束追加学习时长
stopStudyTime(){
//console.log('停止追加学习时长');
this.isAppendTime=false;
//暂停让他为空 从新计时
this.appendStartTime = null
if (this.appendHandle != null) {
window.clearTimeout(this.appendHandle);
}
//console.log('停止追加学习时长');
this.isAppendTime=false;
//暂停让他为空 从新计时
this.appendStartTime = null
if (this.appendHandle != null) {
window.clearTimeout(this.appendHandle);
}
},
appendStudyTime() {
// 暂停的时候重新从十五秒开始计时
@@ -1671,11 +1594,11 @@
this.appendHandle && window.clearTimeout(this.appendHandle);
//启动下次追加学习时长
this.appendHandle = setTimeout(() => {
let endTime = new Date().getTime();
this.appentInterval = 60
let totalTime = Math.round((endTime - this.appendStartTime) / 1000);
this.appendStudyTime();
this.saveStudyDuration(totalTime)
let endTime = new Date().getTime();
this.appentInterval = 60
let totalTime = Math.round((endTime - this.appendStartTime) / 1000);
this.appendStudyTime();
this.saveStudyDuration(totalTime)
}, this.appentInterval * 1000);
},
@@ -1741,30 +1664,26 @@
},
handleAudioTimeUpdate(currentTime) {
// if(this.contentStudysLength.length == 0){
let params = {
studyId: this.studyId, //学习id,
courseId: this.courseId, //课程id,
contentId: this.contentData.id, //内容id,
contentType: this.contentData.contentType,
contentName: this.contentData.contentName, //内容名称
progress: 1,
status: 2,
contentTotal: this.totalContent
};
if(currentTime > 2 && this.trueFalse){
apiStudy.studyContent(params).then(()=>{
if(this.contentData.status<2){
this.contentData.status = 2;
}
})
this.trueFalse = false
}
let params = {
studyId: this.studyId, //学习id,
courseId: this.courseId, //课程id,
contentId: this.contentData.id, //内容id,
contentType: this.contentData.contentType,
contentName: this.contentData.contentName, //内容名称
progress: 1,
status: 2,
contentTotal: this.totalContent
};
if(currentTime > 2 && this.trueFalse){
apiStudy.studyContent(params).then(()=>{
if(this.contentData.status<2){
this.contentData.status = 2;
}
})
this.trueFalse = false
}
},
},
destroyed(){
this.cleanAppendTime();
this.stopStudyTime();
},
}
</script>
@@ -1801,44 +1720,21 @@
margin: 20px auto;
.course-playbox {
background-color: #fff;
//min-height: 400px;
min-height: 400px;
display: flex;
justify-content: space-between;
.course-player-container {
display: flex;
flex-direction: column;
height: 100%;
}
.course-player{ //内容播放区域
flex: 4; // 80%高度
flex:1;
min-width: 700px;
// min-height: 400px;
// max-height: 800px;
height: 80%;
min-height: 400px;
max-height: 800px;
//height: 100%;
border: 1px solid #ffffff;
padding-right: 20px;
background-color: rgb(238, 238, 238);
// overflow: auto;
}
.course-control{ //内容控制区域
width: 420px;
}
}
@media screen and (max-width: 1200px) {
.course-playbox,
.course-infobox {
flex-direction: column;
}
.course-player,
.course-info {
min-width: 100%;
padding-right: 0;
}
.course-control,
.course-teacher {
width: 100%;
margin-top: 20px;
width: 420px;
}
}
.course-infobox {
@@ -1960,10 +1856,13 @@
}
.player-box {
position: relative;
width: 100%;
max-width: 300px;
margin: 20px auto;
position: absolute;
// top: 62px;
// left: 184px;
width: 300px;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
height: 187px;
background: rgba(74, 74, 74, .5);
border-radius: 33px;
@@ -2106,7 +2005,6 @@
}
.course-interact {
flex: 1; // 20%高度
height: 54px;
// padding-top: 10px;
// padding-right: 10px;
@@ -2470,18 +2368,4 @@
height: 200px;
background: url('../../../public/images/couresdetail.png');
}
.protocol {
.protocol-title {
font-size: 20px;
font-weight: 600;
text-align: center;
margin-bottom: 25px;
}
.protocol-content {
font-size: 14px;
line-height: 25px;
}
}
</style>

View File

@@ -1,389 +0,0 @@
<template>
<div class="u-page" style="padding-right:32px">
<div style="width: 100%; margin-left: 12px;padding: 2px 0px 10px 12px;background-color: white">
<el-form :inline="true" style="margin-left: 12px;" :model="pageData" class="demo-form-inline">
<el-form-item label="标签ID:" label-width="60px">
<el-input id="tag-id" placeholder="请输入标签ID" v-model="pageData.id" clearable />
</el-form-item>
<el-form-item label="标签名称:" label-width="80px">
<el-input id="tag-id" placeholder="请输入标签名称" v-model="pageData.tagName" clearable />
</el-form-item>
<el-form-item label="热点标签:" label-width="80px">
<el-select v-model="pageData.isHot" style="width: 120px;" clearable placeholder="请选择状态">
<el-option label="开启" value="true"></el-option>
<el-option label="关闭" value="false"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button @click="getsearch" icon="el-icon-search" type="primary">查询</el-button>
<!-- 添加重置按钮 -->
<el-button @click="resetSearch" icon="el-icon-refresh">重置</el-button>
</el-form-item>
</el-form>
</div>
<div style="padding: 5px 0px 2px 12px;">
<!-- <el-checkbox label="前台公共显示"></el-checkbox>-->
<!-- <el-checkbox label="热点标签展示"></el-checkbox>-->
</div>
<div style="width: 100%; margin-left: 12px;padding: 2px 0px 10px 12px;background-color: white">
<el-table style="width: 96%; margin:2px 32px 10px 12px;" :data="pageData.list" border stripe
:header-cell-style="{ background: '#E9F0FF' }"
@selection-change="handleSelectionChange"
@sort-change="handleSortChange">
<el-table-column type="selection" width="80px"></el-table-column>
<el-table-column label="标签ID" width="200px" prop="id"></el-table-column>
<el-table-column label="标签名称" width="235px" prop="tagName"></el-table-column>
<el-table-column label="已关联课程" width="220px"
prop="useCount"
sortable="custom"
:sort-orders="['descending', 'ascending']"
>
<template #default="scope">
<a v-if="scope.row.useCount > 0"
@click="showCourseByTag(`${scope.row.id}`)"
style="font-weight:bold; color: #409EFF; text-decoration: underline;">
{{ scope.row.useCount }}
</a>
<span style="font-weight:bold; color: #409EFF; text-decoration: underline;" v-else>0</span>
</template>
</el-table-column>
<el-table-column label="前台公共显示" width="220px" prop="isPublic">
<template #default="scope"><!-- 开关状态会直接修改 pageData.list 中的数据 -->
<el-switch
v-model="scope.row.isPublic"
:disabled="scope.row.isHot==1?true:false"
@change="handlePublicChange(scope.row)"
>
</el-switch>
</template>
</el-table-column>
<el-table-column label="热点标签展示" width="220px" prop="isHot">
<template #default="scope">
<el-switch
v-model="scope.row.isHot"
:disabled="scope.row.isPublic==0?true:false"
@change="handleHotChange(scope.row)"
>
</el-switch>
</template>
</el-table-column>
</el-table>
<div v-if="pageData.list.length > 0" style="text-align: center;margin-top: 50px;">
<el-pagination
background
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="pageData.pageIndex"
:page-sizes="[10, 20, 30, 40]"
:page-size="pageData.pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="total"
></el-pagination>
</div>
</div>
<!-- 标签关联课程弹窗 -->
<el-dialog custom-class="g-dialog" title="关联课程"
width="850px" top="20px"
:visible.sync="dialogVisible"
:modal-append-to-body="true"
:append-to-body="true">
<div class="dialog-content-container">
<el-table
:data="pageData.list2"
border stripe style="width: 100%"
:header-cell-style="{ background: '#E9F0FF' }"
@sort-change="handleSortChange2">
<el-table-column label="序号" width="60px" align="center">
<template #default="scope">
{{ scope.$index + 1 }}
</template>
</el-table-column>
<el-table-column label="关联课程名称" width="200px" prop="courseName"></el-table-column>
<el-table-column label="关联课程ID" width="100px" prop="courseId"></el-table-column>
<el-table-column label="关联人" width="80px" prop="sysCreateBy"></el-table-column>
<el-table-column label="关联时间" width="110px" prop="sysCreateTime"
:formatter="dateFormat" sortable="custom"
:sort-orders="['descending', 'ascending']"></el-table-column>
<el-table-column label="本课程绑定的其他标签" width="200px" prop="otherTags"></el-table-column>
<el-table-column label="操作" width="60px">
<template #default="scope">
<a @click="unbindCurrentTag(scope.row)"
style="font-weight:bold; color: #409EFF;">
解绑
</a>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<div v-if="pageData.list2.length > 0" class="pagination-container">
<el-pagination
background
@size-change="handleSizeChange2"
@current-change="handleCurrentChange2"
:current-page="pageData.pageIndex2"
:page-sizes="[10, 20, 30, 40]"
:page-size="pageData.pageSize2"
layout="total, sizes, prev, pager, next, jumper"
:total="total2">
</el-pagination>
</div>
</div>
</el-dialog>
</div>
</template>
<script>
import moment from 'moment';
import apiCourseTag from '@/api/modules/courseTag.js'
import { mapGetters } from 'vuex';
export default {
name: 'courseTagItems',
computed: {
...mapGetters(['userInfo'])
},
data() {
return {
pageData: {
pageIndex: 1,
pageIndex2: 1,
pageSize: 10,
pageSize2: 10,
list:[],
list2:[],
orderField: null,
orderAsc: null,
orderField2: null,
orderAsc2: null,
},
total: 0,
total2: 0,
dialogVisible: false,
tagId: null,
}
},
created() {
this.getCourseTagList()
},
methods: {
//重置搜索条件
resetSearch() {
this.pageData.id = '';
this.pageData.tagName = '';
this.pageData.isHot = '';
this.pageData.pageIndex = 1;
this.getCourseTagList(); // 重置后重新加载列表
},
//初始化:课程标签列表
getsearch(){
this.pageData.pageIndex = 1;
this.getCourseTagList()
},
//课程标签列表:排序
handleSortChange({ prop, order }) {
this.pageData.orderField = prop; // 当前排序字段
this.pageData.orderAsc = order === 'ascending'; // 排序方向
this.getCourseTagList(); // 重新获取数据
},
//TODO:课程标签列表:监听选中项变化(批量的设置标签公共显示|热点标签)
handleSelectionChange(selection) {
this.selectedRows = selection; // 更新选中的行数据
},
//课程标签列表:获取课程标签列表数据
getCourseTagList() {
const { pageIndex, pageSize, orderField, orderAsc } = this.pageData
let query = { pageIndex, pageSize, orderField, orderAsc}
//拼接查询条件
if (this.pageData.id) {
const { id } = this.pageData
query.id = id
}
if (this.pageData.tagName) {
const { tagName } = this.pageData
query.tagName = tagName
}
if (this.pageData.isHot) {
const { isHot } = this.pageData
query.isHot = isHot
}
apiCourseTag.portalPageList(query).then((res) => {
if (res.status == 200) {
this.total = res.result.count
this.pageData.list = res.result.list
}
})
.catch((err) => {
this.$message.error('获取数据失败')
})
},
//课程标签列表:改变标签的公共属性
async handlePublicChange(row) {
// 保存原始状态用于回滚
const originalStatus = row.isPublic;
try {
// 调用 API 更新状态
await apiCourseTag.changeTagPublic(row);
this.$message.success('更新成功');
} catch (error) {
// 发生错误时回滚状态
row.isPublic = originalStatus;
this.$message.error('更新失败:' + error.message);
}
},
//课程标签列表:改变标签的热点属性
async handleHotChange(row) {
const isPublic=row.isPublic;
// 保存原始状态用于回滚
const originalStatus = row.isHot;
try {
// 调用 API 更新状态
await apiCourseTag.changeTagHot(row).then((res)=>{
if (res.status == 200){
this.$message.success(res.message);
}else {
row.isHot=false;
this.$message.warning(res.message);
}
});
} catch (error) {
// 发生错误时回滚状态
row.isHot = originalStatus;
this.$message.error('更新失败:' + error.message);
}
},
//课程标签列表:改变条数的回调
handleSizeChange(value) {
this.pageData.pageIndex = 1;
this.pageData.pageSize = value;
this.getCourseTagList();
},
//课程标签列表:改变页数的回调
handleCurrentChange(value) {
this.pageData.pageIndex = value;
this.getCourseTagList();
},
//标签关联的所有课程弹出框显示指定标签id关联的课程列表
showCourseByTag(tagId) {
this.tagId=tagId;
this.getCourseOfTagList(tagId);
this.dialogVisible=true;
},
//分页查询指定标签关联的所有课程
getCourseOfTagList(){
const { pageIndex2:pageIndex, pageSize2:pageSize, orderField2:orderField, orderAsc2:orderAsc } = this.pageData
let query = { pageIndex, pageSize, orderField, orderAsc }
//拼接查询条件
if (this.tagId) {
query.id = this.tagId
apiCourseTag.showCourseByTag(query).then((res) => {
if (res.status == 200) {
this.total2 = res.result.count
this.pageData.list2 = res.result.list
if (this.total2==0){
this.dialogVisible=false
this.getCourseTagList(); // 重新获取课程标签列表数据
}
}
})
.catch((err) => {
this.$message.error('获取数据失败')
});
}
},
//标签关联课程列表:排序
handleSortChange2({ prop, order }) {
this.pageData.orderField2 = prop; // 当前排序字段
this.pageData.orderAsc2 = order === 'ascending'; // 排序方向
this.getCourseOfTagList(); // 重新获取数据
},
//标签关联的所有课程列表:改变条数的回调
handleSizeChange2(value) {
this.pageData.pageIndex2= 1;
this.pageData.pageSize2 = value;
this.getCourseOfTagList();
},
//标签关联的所有课程列表:改变页数的回调
handleCurrentChange2(value) {
this.pageData.pageIndex2 = value;
this.getCourseOfTagList();
},
//关联时间格式化
dateFormat(row, column) {
return row[column.property] ?
moment(row[column.property]).format('YYYY-MM-DD') : '';
},
//解除指定课程和当前标签的关联关系
unbindCurrentTag (row) {
let id = row.id;
let tagId = this.tagId;
let courseId = row.courseId;
//拼接查询条件
if (tagId && courseId) {
let params = { id, tagId, courseId }
apiCourseTag.unbindCourseTagRelation(params).then((res) => {
if (res.status == 200) {
//刷新列表
this.getCourseOfTagList(this.tagId);
}
})
.catch((err) => {
this.$message.error('解绑失败!')
});
}
}
}
}
</script>
<style>
.demo-form-inline {
display: flex;
align-items: center;
flex-wrap: wrap;
gap: 10px; /* 间距 */
}
.demo-form-inline .el-form-item {
margin-bottom: 0; /* 消除默认底部间距 */
}
.dialog-content-container {
padding: 10px;
border: 1px solid #d9d9d9;
}
.pagination-container {
margin-top: 20px;
text-align: center;
}
.g-dialog .el-dialog__header {
background-color: #409EFF;
padding: 15px 20px;
}
.g-dialog .el-dialog__title {
color: white;
font-weight: bold;
}
.g-dialog .el-dialog__headerbtn .el-dialog__close {
color: white;
}
</style>