Merge branch 'master-20251023-tag' into merge-20251113-tag

# Conflicts:
#	src/components/Course/courseTag.vue
This commit is contained in:
670788339
2025-11-17 13:28:18 +08:00
4 changed files with 306 additions and 234 deletions

View File

@@ -45,24 +45,24 @@
<!-- 蒙层引导组件 -->
<div v-if="showGuidance" class="guidance-overlay" @click="closeGuidance">
<div class="guidance-content">
<div class="guidance-title">新功能引导</div>
<div class="guidance-title"></div> <!--新功能引导-->
<div class="guidance-steps">
<div class="guidance-step" :class="{ active: currentStep === 1 }">
<div class="step-number">1</div>
<div class="step-number"></div>
<div class="step-content">
<div class="step-title">用标签为课程精准定位吸引更多学员可从以下维度构思</div>
<div class="step-desc"> 讲领域品质管理</div>
<div class="step-desc"> 教技能沟通技巧</div>
<div class="step-desc"> 涉内容5W1H分析法</div>
<div class="step-desc" style="padding-left: 20px;"> 讲领域品质管理</div>
<div class="step-desc" style="padding-left: 20px;"> 教技能沟通技巧</div>
<div class="step-desc" style="padding-left: 20px;"> 涉内容5W1H分析法</div>
</div>
</div>
<!-- <div class="guidance-step" :class="{ active: currentStep === 2 }">
<div class="step-number">2</div>
<div class="step-content">
<div class="step-title">添加课程标签</div>
<div class="step-desc">为课程添加相关标签,最多5个便于搜索和分类,可回车创建新标签</div>
</div>
</div>-->
<!-- <div class="guidance-step" :class="{ active: currentStep === 2 }">
<div class="step-number">2</div>
<div class="step-content">
<div class="step-title">添加课程标签</div>
<div class="step-desc">为课程添加相关标签,最多5个便于搜索和分类,可回车创建新标签</div>
</div>
</div>-->
</div>
<!-- <div class="guidance-actions">
<el-button @click="previousStep1" v-if="currentStep > 1">上一步</el-button>
@@ -75,7 +75,7 @@
</div>
<!-- 高亮指引元素 -->
<!-- <div v-if="showGuidance" class="highlight-element" :style="highlightStyle"></div>-->
<!-- <div v-if="showGuidance" class="highlight-element" :style="highlightStyle"></div>-->
<!--微课-->
@@ -114,11 +114,14 @@
</el-cascader>
</el-form-item>
<el-form-item label="标签" required class="guidance-highlight" data-step="1">
<el-form-item label="标签" required class="guidance-highlight" data-step="1" style="display: flex" >
<courseTag ref="courseTag" :courseId="curCourseId" :sysTypeList="sysTypeList"
:initialTags="courseTags" @change="handleTagsChange"
@focus="onTagFocus">
@focus="onTagFocus" style="width: 95%;">
</courseTag>
<el-tooltip content="点击查看标签新功能引导" placement="top">
<i class="el-icon-question" style="color: #409EFF; cursor: pointer;" @click="handleTagHelp"></i>
</el-tooltip>
</el-form-item>
<el-form-item label="资源归属" required>
@@ -303,11 +306,14 @@
</el-select> -->
<choice :teacherValue="teacherValues" @getTeacherList="getTeacherList"></choice>
</el-form-item>
<el-form-item label="标签" required class="guidance-highlight" data-step="1">
<el-form-item label="标签" required class="tag-from-item" data-step="1" >
<courseTag ref="courseTag" :courseId="curCourseId" :sysTypeList="sysTypeList"
:initialTags="courseTags" @change="handleTagsChange"
@focus="onTagFocus">
@focus="onTagFocus" >
</courseTag>
<el-tooltip content="点击查看标签新功能引导" placement="top">
<i class="el-icon-question" style="color: #409EFF; cursor: pointer;" @click="handleTagHelp"></i>
</el-tooltip>
</el-form-item>
<el-form-item label="关键字">
@@ -647,6 +653,9 @@ export default {
this.loadUserGroup();
},
methods: {
handleTagHelp(){
this.checkAndShowGuidance();
},
// 关键字的更改
changeKeywords(option){
if(option.target.value){
@@ -955,26 +964,26 @@ export default {
this.curCourseId = this.courseInfo.id
console.log('保存课程成功',this.curCourseId)
console.log('isTip ',this.courseInfo.isTip)
if(this.courseInfo.isTip){
// 检查是否为首次创建,显示引导
this.checkAndShowGuidance();
}
// if(this.courseInfo.isTip){
// // 检查是否为首次创建,显示引导
// this.checkAndShowGuidance();
// }
if (this.courseChooseId == 1) {
this.weike.dlgShow = true;
} else {
this.biaoke.dlgShow = true;
}
this.$nextTick(() => {
this.initTagComponent();
// 如果显示引导,初始化高亮元素
if (this.showGuidance) {
this.$nextTick(() => {
this.initGuidanceElements();
this.highlightCurrentStep();
});
}
});
// this.$nextTick(() => {
// this.initTagComponent();
// // 如果显示引导,初始化高亮元素
// if (this.showGuidance) {
// this.$nextTick(() => {
// this.initGuidanceElements();
// this.highlightCurrentStep();
// });
// }
// });
} else {
this.$message.error(rs.message);
}
@@ -983,15 +992,15 @@ export default {
// 检查并显示引导
checkAndShowGuidance() {
// 检查本地存储,判断是否为首次创建
const hasShownGuidance = localStorage.getItem('course_creation_guidance_shown');
if (!hasShownGuidance) {
this.showGuidance = true;
this.currentStep = 1;
this.isFirstCreate = true;
// 标记引导已显示
localStorage.setItem('course_creation_guidance_shown', 'true');
apiCourse.saveTip();
}
// const hasShownGuidance = localStorage.getItem('course_creation_guidance_shown');
// if (!hasShownGuidance) {
this.showGuidance = true;
this.currentStep = 1;
this.isFirstCreate = true;
// 标记引导已显示
localStorage.setItem('course_creation_guidance_shown', 'true');
// apiCourse.saveTip();
// }
},
// 初始化引导元素
initGuidanceElements() {
@@ -2012,9 +2021,9 @@ export default {
}
.step-number {
width: 24px;
//width: 24px;
height: 24px;
background: #409EFF;
//background: #409EFF;
color: white;
border-radius: 50%;
display: flex;
@@ -2060,4 +2069,26 @@ export default {
position: relative;
z-index: 10001;
}
//.el-form-item__content {
// display: flex;
// width: 80%;
// .tag-container {
// width: 95%;
// }
//}
.tag-from-item .el-form-item__content {
margin-left: 0 !important;
display: flex;
//align-items: center;
.tag-container {
width: 95%;
}
}
.guidance-highlight .el-form-item__content {
margin-left: 0 !important;
display: flex;
width: 75%;
}
</style>

View File

@@ -217,7 +217,9 @@ export default {
this.$emit('change', this.displayTags);
this.clearInput();
this.$refs.tagSelect.visible = false;
this.$nextTick(() => {
this.$refs.tagSelect.visible = false;
});
},
clearInput() {

View File

@@ -71,25 +71,21 @@
<!-- 内容导航 -->
<div class="topNav" v-if="!newData">
<div class="search-div nav" style="flex: 1;height: auto;background: #fff;">
<div class="nav-primary" style="gap: 15px;display: flex">
<div class="nav-primary" style="gap: 15px;display: flex;margin-top: 20px;">
<div @click="handleTypeAllClick(1)" class="option-item" style="position: relative;" :class="{ 'option-active': ctypeTagAll }">
<a>全部</a>
<span :class="ctypeTagAll ? 'nav-bottbor' : ''"></span>
</div>
<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"
: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"
: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" > U选小课堂
@@ -100,29 +96,31 @@
</a>
</div>
<!-- 修改热点标签区域 -->
<div style="margin-top:10px;flex: 1;">
<div style="margin:20px 0;flex: 1;">
<!-- 修改热点标签容器支持换行 -->
<div class="hot-tags-wrapper">
<div class="hot-tags-wrapper">
<div>
<div style="display: flex">
<div
class="option-item" style=" padding-top: 2px;"
:class="{ 'option-active': isAllHotTagsSelected }"
@click="handleClearHotTags"
>
<span>全部</span>
<span :class="isAllHotTagsSelected ? 'nav-bottbor' : ''"></span>
</div>
<div
class="option-item" style=" padding-top: 2px;"
v-for="tag in hotTagsList"
:key="tag.id"
@click="handleTagClick(tag, hotTagsList,1)"
:class="{ 'option-active': tag.checked }"
>
<span>{{tag.tagName}}</span>
<span :class="tag.checked ? 'nav-bottbor' : ''"></span>
<div class="fieldbox" style="padding-left: 15px;">
<div
class="option-item" style=" padding-top: 2px;"
v-for="tag in hotTagsList"
:key="tag.id"
@click="handleTagClick(tag, hotTagsList,1)"
:class="{ 'option-active': tag.checked }"
>
<span>{{tag.tagName}} </span>
<!-- <span :class="tag.checked ? 'nav-bottbor' : ''"></span>-->
</div>
</div>
</div>
</div>
</div>
@@ -253,10 +251,6 @@
</template>
<!-- 暂无数据 -->
<div class="pagination-div">
<!-- <span class="pag-text" @click="loadMore()"
v-if="moreState == 1 && courseList.length >= course.pageSize">加载更多</span> -->
<!-- <span class="pag-text-msg" v-if="moreState == 2">数据加载中</span> -->
<!-- <span class="pag-text-msg" v-else-if="moreState == 3 && courseList.length > 0">没有更多数据了</span> -->
<span class="notcoures" v-if="moreState == 3 && courseList.length == 0">
<img :src="`${webBaseUrl}/images/nocouresimg.png`" alt="">
<h5>暂无课程请优先学习其它课程吧</h5>
@@ -1784,7 +1778,7 @@ export default {
.nav-bottbor {
position: absolute;
top: 130%;
top: 100%;
left: 0;
width: 100%;
height: 4px;
@@ -2012,13 +2006,6 @@ export default {
color: #999;
}
.couderbox {
// width: 5px;
// padding: 0;
// display: inline-block;
// text-align: center;
}
.coures-border {
width: 2px;
height: 15px;
@@ -2262,16 +2249,6 @@ export default {
left: 98%;
}
// .el-radio-button{
// margin-right: 10px;
// margin-bottom: 10px;
// .el-radio-button__inner{
// background: #fff;
// border: none;
// height: 20px;
// }
// }
::v-deep .el-radio-button__inner,
.el-radio-group {
vertical-align: top;
@@ -2325,13 +2302,6 @@ export default {
}
}
.searchbar {
//background-color: #ffffff;
// border: 1px solid #f3f3f3;
// width: 900px;
// padding: 5px 20px;
}
.fixed {
position: fixed;
top: 0px;
@@ -2423,14 +2393,6 @@ export default {
}
}
// .tip{
// color:#999999;
// font-size: 12px;
// >span{
// margin-right: 8px;
// cursor: pointer;
// }
// }
.search-item {
// padding: 10px 0;
}
@@ -2473,30 +2435,6 @@ export default {
}
}
}
// .course-form {
// width: 100%;
// margin: 10px 0;
// ::v-deep.el-button {
// width: 100%;
// color: #fff;
// }
// }
// .right-box {
// .add-btn {
// width: 100%;
// padding: 15px 0;
// }
// .ranking-card {
// margin-top: 0px;
// }
// .ranking-data {
// margin: 10px 0;
// color: #999999;
// }
// }]
.search-item-type {
line-height: 25px;
padding-right: 10px;
@@ -2550,22 +2488,12 @@ export default {
padding: 0 !important;
}
/* ---end--- */
// 2025-11-07 10:00 修改
.search-div.nav {
display: block;
width: 100%;
clear: both;
}
//.search-div.nav {
// display: flex;
// flex-direction: column;
// height: auto;
// min-height: 100px;
//}
//.hot-tags-area {
// width: 100%;
// margin-top: 15px;
//}
.option-item {
margin: 0px 5px;
@@ -2614,22 +2542,6 @@ a.custom2 {
display: none;
}
/* 添加标签样式 */
//.course-tags {
// margin: 5px 0;
// min-height: 20px;
//}
//.course-tags ::v-deep .el-tag {
// color: #387DF7 !important;
// border-color: #387DF7 !important;
//}
//.course-tags ::v-deep .el-tag .el-tag__close {
// color: #387DF7 !important;
//}
//.course-tags ::v-deep .el-tag .el-tag__close:hover {
// background-color: #387DF7 !important;
// color: white !important;
//}
.course-tag-item {
color: #333333; // 默认深灰色
@@ -2648,7 +2560,7 @@ a.custom2 {
/* 保持原有的导航底部横线样式 */
.nav-bottbor {
position: absolute;
top: 130%;
top: 100%;
left: 0;
width: 100%;
height: 4px;
@@ -2668,7 +2580,7 @@ a.custom2 {
gap: 5px;
}
}
// 2025-11-07 10:00 修改
.hot-tags-wrapper {
display: flex;
flex-wrap: wrap;
@@ -2676,22 +2588,7 @@ a.custom2 {
align-items: center;
padding-top: 2px;
}
//.hot-tags-wrapper {
// display: grid;
// grid-template-columns: repeat(auto-fill, minmax(120px, max-content));
// gap: 15px 20px;
// align-items: center;
// justify-items: start;
// width: 100%;
// padding: 10px 0;
//}
//.hot-tags-wrapper .option-item {
// position: relative;
// cursor: pointer;
// white-space: nowrap;
// padding: 5px 10px;
// text-align: center;
//}
.course-tags {
margin: 5px 0;
min-height: 20px;
@@ -2738,4 +2635,23 @@ a.custom2 {
background-color: transparent !important;
}
.fieldbox {
display: flex;
white-space: nowrap;
flex-wrap: wrap;
div {
margin: 0 15px;
display: inline-block;
font-size: 14px;
line-height: 25px;
//color: #3d3d3d;
font-weight: 500;
}
.fieldactive {
color: #387DF7;
}
}
</style>

View File

@@ -56,23 +56,23 @@
<div class="topNav" v-if="!newData" style="display: flex; flex-direction: row;background-color:#fff;">
<!-- 修改后 -->
<div class="search-div nav" style="flex: 1;height: auto;">
<div class="nav-primary" style="display: flex; justify-content: space-between; align-items: center;">
<div class="nav-primary" style="display: flex; justify-content: space-between; align-items: center;margin-top: 15px;">
<div style="display: flex;">
<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>
<!-- <span :class="ctypeList[0].checked ? 'nav-bottbor' : ''"></span>-->
</div>
<div @click="handleTypeClick(ctypeList[1], ctypeList)" class="option-item"
:class="{ 'option-active': ctypeList[1].checked }" style="padding-left: 15px;">
<a>内部专享</a>
<span :class="ctypeList[1].checked ? 'nav-bottbor' : ''"></span>
<!-- <span :class="ctypeList[1].checked ? 'nav-bottbor' : ''"></span>-->
</div>
<div @click="handleTypeClick(ctypeList[2], ctypeList)" class="option-item"
:class="{ 'option-active': ctypeList[2].checked }" style="padding-left: 15px;">
<a>外部精选</a>
<span :class="ctypeList[2].checked ? 'nav-bottbor' : ''"></span>
<!-- <span :class="ctypeList[2].checked ? 'nav-bottbor' : ''"></span>-->
</div>
</div>
@@ -90,34 +90,80 @@
</div>
</div>
<div style="margin-top:10px;flex: 1;">
<!-- 修改热点标签容器支持换行 -->
<div class="hot-tags-wrapper" style="display: flex;">
<div class="hot-tags-wrapper" style="display: flex; align-items: center;">
<div
class="option-item"
style=" padding-top: 2px; margin-left: 15px;"
:class="{ 'option-active': isAllHotTagsSelected }"
@click="handleClearHotTags"
>
<span>全部</span>
<span :class="isAllHotTagsSelected ? 'nav-bottbor' : ''"></span>
</div>
<!-- <div style="margin-top:10px;flex: 1;">-->
<!-- &lt;!&ndash; 修改热点标签容器支持换行 &ndash;&gt;-->
<!-- <div class="hot-tags-wrapper" style="display: flex;">-->
<!-- <div class="hot-tags-wrapper" style="display: flex; align-items: center;">-->
<!-- <div-->
<!-- class="option-item"-->
<!-- style=" padding-top: 2px; margin-left: 15px;"-->
<!-- :class="{ 'option-active': isAllHotTagsSelected }"-->
<!-- @click="handleClearHotTags"-->
<!-- >-->
<!-- <span>全部</span>-->
<!-- </div>-->
<div
class="option-item"
style=" padding-top: 2px;"
v-for="tag in hotTagsList"
:key="tag.id"
@click="handleTagClick(tag, hotTagsList,1)"
:class="{ 'option-active': tag.checked }"
>
<span>{{tag.tagName}}</span>
<span :class="tag.checked ? 'nav-bottbor' : ''"></span>
<!-- <div-->
<!-- class="option-item"-->
<!-- style=" padding-top: 2px;"-->
<!-- v-for="tag in hotTagsList"-->
<!-- :key="tag.id"-->
<!-- @click="handleTagClick(tag, hotTagsList,1)"-->
<!-- :class="{ 'option-active': tag.checked }"-->
<!-- >-->
<!-- <span>{{tag.tagName}}</span>-->
<!-- </div>-->
<!-- </div>-->
<!-- </div>-->
<!-- </div>-->
<!-- <div style="margin:20px 0;flex: 1;">-->
<!-- <div>-->
<!-- <div style="display: flex">-->
<!-- <div-->
<!-- class="option-item" style=" padding-top: 2px;"-->
<!-- :class="{ 'option-active': isAllHotTagsSelected }"-->
<!-- @click="handleClearHotTags"-->
<!-- >-->
<!-- <span>全部</span>-->
<!-- </div>-->
<!-- <div class="fieldbox" style="padding-left: 15px;">-->
<!-- <div-->
<!-- class="option-item" style=" padding-top: 2px;"-->
<!-- v-for="tag in hotTagsList"-->
<!-- :key="tag.id"-->
<!-- @click="handleTagClick(tag, hotTagsList,1)"-->
<!-- :class="{ 'option-active': tag.checked }"-->
<!-- >-->
<!-- <span>{{tag.tagName}} </span>-->
<!-- </div>-->
<!-- </div>-->
<!-- </div>-->
<!-- </div>-->
<!-- </div>-->
<div style="margin:20px 0;flex: 1;">
<div>
<div style="display: flex">
<div class="option-item" style="padding-top: 2px;min-width: 33px;"
:class="{ 'option-active': isAllHotTagsSelected }"
@click="handleClearHotTags">
<span>全部</span>
</div>
<div class="fieldbox" style="padding-left: 15px;">
<div class="option-item" style="padding-top: 2px;"
v-for="tag in hotTagsList"
:key="tag.id"
@click="handleTagClick(tag, hotTagsList,1)"
:class="{ 'option-active': tag.checked }">
<span>{{tag.tagName}}</span>
</div>
</div>
</div>
</div>
</div>
</div>
@@ -444,6 +490,9 @@ export default {
});
return !flag;
},
isAllHotTagsSelected() {
return !this.hotTagsList.some(tag => tag.checked);
}
},
data() {
return {
@@ -711,15 +760,12 @@ export default {
},
// isAllHotTagsSelected() {
// return !this.hotTagsList.some(tag => tag.checked);
// },
handleClearHotTags() {
// 清除所有热点标签的选中状态
this.hotTagsList.forEach(tag => {
tag.checked = false;
});
this.isAllHotTagsSelected = true;
// 清空course.tags
this.course.tags = '';
@@ -1607,29 +1653,29 @@ export default {
}
// 导航
.topNav {
display: flex;
margin-bottom: 20px;
.nav {
display: flex;
align-items: center;
.option-item {
position: relative;
.nav-bottbor {
position: absolute;
top: 130%;
left: 0;
width: 100%;
height: 4px;
background: #387DF7;
border-radius: 5px;
}
}
}
}
//.topNav {
// display: flex;
// margin-bottom: 20px;
//
// .nav {
// display: flex;
// align-items: center;
//
// .option-item {
// position: relative;
//
// .nav-bottbor {
// position: absolute;
// top: 130%;
// left: 0;
// width: 100%;
// height: 4px;
// background: #387DF7;
// border-radius: 5px;
// }
// }
// }
//}
.u-class {
::v-deep .el-dialog {
@@ -2313,11 +2359,11 @@ export default {
align-items: center;
padding-top: 2px;
}
.search-div.nav {
display: block;
width: 100%;
clear: both;
}
//.search-div.nav {
// display: block;
// width: 100%;
// clear: both;
//}
.search-item-type {
line-height: 25px;
padding-right: 10px;
@@ -2325,14 +2371,14 @@ export default {
white-space: nowrap;
}
.option-item {
font-family: "Menlo", "苹方-简" !important;
color: #3d3d3d;
display: inline-block;
font-size: 14px;
margin: 0px 15px;
cursor: pointer
}
//.option-item {
// font-family: "Menlo", "苹方-简" !important;
// color: #3d3d3d;
// display: inline-block;
// font-size: 14px;
// margin: 0px 15px;
// cursor: pointer
//}
.option-border {
width: 2px;
@@ -2342,6 +2388,63 @@ export default {
background: #666;
}
.topNav {
display: flex;
margin-bottom: 20px;
height: auto;
min-height: 80px;
align-items: center;
.nav {
display: flex;
align-items: center;
.option-item {
position: relative;
margin: 0 15px;
cursor: pointer;
.nav-bottbor {
position: absolute;
top: 100%;
left: 0;
width: 100%;
height: 4px;
background: #387DF7;
border-radius: 5px;
}
}
}
}
.search-div.nav {
display: block;
width: 100%;
clear: both;
}
.option-item {
margin: 0px 5px;
}
.fieldbox {
display: flex;
white-space: nowrap;
flex-wrap: wrap;
div {
margin: 0 15px;
display: inline-block;
font-size: 14px;
line-height: 25px;
font-weight: 500;
}
.fieldactive {
color: #387DF7;
}
}
.option-active {
color: #387DF7;
}
@@ -2380,4 +2483,24 @@ export default {
font-weight: bold;
background-color: transparent !important;
}
//.fieldbox {
//
// display: flex;
// white-space: nowrap;
// flex-wrap: wrap;
//
// div {
// margin: 0 15px;
// display: inline-block;
// font-size: 14px;
// line-height: 25px;
// //color: #3d3d3d;
// font-weight: 500;
// }
//
// .fieldactive {
// color: #387DF7;
// }
//}
</style>