Branch_d40a2540
yujialong 2 years ago
parent bad2c7bb35
commit 186618506f
  1. 10
      src/api/index.js
  2. BIN
      src/assets/img/exts/pdf.png
  3. BIN
      src/assets/img/exts/pic.png
  4. BIN
      src/assets/img/exts/ppt.png
  5. BIN
      src/assets/img/exts/txt.png
  6. BIN
      src/assets/img/exts/video.png
  7. BIN
      src/assets/img/exts/word.png
  8. BIN
      src/assets/img/eye.png
  9. BIN
      src/assets/img/hot.png
  10. BIN
      src/assets/img/my-school.png
  11. BIN
      src/assets/img/platform.png
  12. BIN
      src/assets/img/product-bg.png
  13. BIN
      src/assets/img/sort.png
  14. BIN
      src/assets/img/type.png
  15. 345
      src/pages/product/list/index.vue
  16. 455
      src/pages/product/show/index.vue
  17. 2
      src/pages/screen/index.vue
  18. 2
      src/pages/station/list/index.vue
  19. 43
      src/pages/station/preview/index.vue
  20. 6
      src/router/modules/product.js
  21. 9
      src/styles/page/station.scss

@ -30,10 +30,10 @@ export default {
saveLearningProgress: 'nakadai/nakadai/curriculum/learning/progressprogress/save', saveLearningProgress: 'nakadai/nakadai/curriculum/learning/progressprogress/save',
updateLearningProgress: 'nakadai/nakadai/curriculum/learning/progressprogress/update', updateLearningProgress: 'nakadai/nakadai/curriculum/learning/progressprogress/update',
// 课程笔记 // 课程笔记
addNote: `${host2}nakadai/curriculumNotes/addNote`, addNote: `nakadai/curriculumNotes/addNote`,
curriculumNoteList: `${host2}nakadai/curriculumNotes/curriculumNoteList`, curriculumNoteList: `nakadai/curriculumNotes/curriculumNoteList`,
deleteNotes: `${host2}nakadai/curriculumNotes/deleteNotes`, deleteNotes: `nakadai/curriculumNotes/deleteNotes`,
updateNote: `${host2}nakadai/curriculumNotes/updateNote`, updateNote: `nakadai/curriculumNotes/updateNote`,
// 权限管理 // 权限管理
getUserRolesPermissionMenu: `users/users/user-role/getUserRolesPermissionMenu`, getUserRolesPermissionMenu: `users/users/user-role/getUserRolesPermissionMenu`,
@ -363,6 +363,8 @@ export default {
supplierList: `nakadai/supplier/supplierList`, supplierList: `nakadai/supplier/supplierList`,
tagsList: `nakadai/tags/tagsList`, tagsList: `nakadai/tags/tagsList`,
listOfGoods: `nakadai/mall/listOfGoods`, listOfGoods: `nakadai/mall/listOfGoods`,
detailsOfGoods: `nakadai/mall/detailsOfGoods`,
addLearningRecord: `nakadai/mallCourseLearningRecord/addLearningRecord`,
// 课程管理三级联查 // 课程管理三级联查
courseDiscipline: `nakadai/nakadai/subject/courseDiscipline`, //课程学科类别 courseDiscipline: `nakadai/nakadai/subject/courseDiscipline`, //课程学科类别
courseProfessionalClass: `nakadai/nakadai/subject/courseProfessionalClass`, //课程专业类 courseProfessionalClass: `nakadai/nakadai/subject/courseProfessionalClass`, //课程专业类

Binary file not shown.

After

Width:  |  Height:  |  Size: 371 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 330 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 243 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 341 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 244 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 437 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 370 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 331 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 256 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 298 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

@ -1,99 +1,139 @@
<template> <template>
<div class="wrap"> <div class="wrap">
<el-carousel :interval="6000">
<template v-for="(item, i) in banners">
<el-carousel-item :key="i">
<div :class="['banner-item', {'cursor-pointer': item.url}]" @click="openLink(item)">
<img :src="item.banner" alt="">
<p class="banner-name">{{ item.title }}</p>
</div>
</el-carousel-item>
</template>
</el-carousel>
<div class="inner">
<div class="typw-wrap">
<div>
<img src="@/assets/img/hot.png" alt="">
<img class="m-l-5 m-r-10" src="@/assets/img/type.png" alt="">
<ul class="tab">
<li v-for="(tab, i) in tabs" :key="i" :class="{active: curTab === tab.id}" @click="tabChange(tab)">{{ tab.name }}</li>
</ul>
</div>
<div class="search"> <div class="search">
<div class="input"> <img class="icon" src="@/assets/img/search.png" alt="">
<img src="@/assets/img/search.png" alt="">
<input type="text" placeholder="请输入产品名称" v-model="form.productName"> <input type="text" placeholder="请输入产品名称" v-model="form.productName">
</div> </div>
</div> </div>
<div class="p-wrap">
<div class="switchs">
<p class="type">分类</p>
<div class="val">全部</div>
<p class="type">按学科专业</p>
<div class="val">产品精选</div>
<div class="val">按热门标签</div>
</div>
<div class="inner">
<div class="filter"> <div class="filter">
<div class="wrap-inner" style="padding-bottom: 0"> <dl>
<dl v-if="active != 2"> <dt>学科专业</dt>
<dt>学科专业</dt>
<el-select v-model="form.categoryId" clearable @change="getProfessionalClass()" @clear="clearClass()"> <el-select v-model="form.categoryId" clearable @change="getProfessionalClass()" @clear="clearClass()">
<el-option v-for="(item,index) in subjectList" :key="index" :label="item.disciplineName" :value="item.disciplineId"></el-option> <el-option v-for="(item,index) in subjectList" :key="index" :label="item.disciplineName" :value="item.disciplineId"></el-option>
</el-select> </el-select>
<dt class="m-l-20">专业类</dt> <dt style="margin: 0 10px 0 50px">专业类</dt>
<el-select v-model="form.professionalCategoryId" clearable :disabled="form.categoryId ? false : true" @change="getProfessional" @clear="clearProfess()"> <el-select v-model="form.professionalCategoryId" clearable :disabled="form.categoryId ? false : true" @change="getProfessional" @clear="clearProfess()">
<el-option v-for="(item,index) in professionalClassList" :key="index" :label="item.professionalClassName" :value="item.professionalClassId"></el-option> <el-option v-for="(item,index) in professionalClassList" :key="index" :label="item.professionalClassName" :value="item.professionalClassId"></el-option>
</el-select> </el-select>
<dt class="m-l-20">专业</dt> <dt style="margin: 0 10px 0 50px">专业</dt>
<el-select v-model="form.professionalId" clearable :disabled="form.professionalCategoryId ? false : true" @change="initData"> <el-select v-model="form.professionalId" clearable :disabled="form.professionalCategoryId ? false : true" @change="initData">
<el-option v-for="(item,index) in professionalList" :key="index" :label="item.professionalName" :value="item.professionalId"></el-option> <el-option v-for="(item,index) in professionalList" :key="index" :label="item.professionalName" :value="item.professionalId"></el-option>
</el-select> </el-select>
</dl> </dl>
<dl> <dl>
<dt>产品类型</dt> <dt>产品类型</dt>
<dd :class="{active: form.productClassification === ''}" @click="filterChange('', 'productClassification')">全部</dd> <dd :class="{active: form.productClassification === ''}" @click="filterChange('', 'productClassification')">全部</dd>
<dd v-for="(item, i) in classifications" :key="i" :class="{active: form.productClassification === item.typeId}" @click="filterChange(item.typeId, 'productClassification')">{{ item.typeName }}</dd> <dd v-for="(item, i) in classifications" :key="i" :class="{active: form.productClassification === item.typeId}" @click="filterChange(item.typeId, 'productClassification')">{{ item.typeName }}</dd>
</dl> </dl>
<dl> <dl>
<dt>购买状态</dt> <dt>购买状态</dt>
<dd v-for="(item, i) in status" :key="i" :class="{active: form.purchaseStatus === item.id}" @click="filterChange(item.id, 'purchaseStatus')">{{ item.name }}</dd> <dd v-for="(item, i) in status" :key="i" :class="{active: form.purchaseStatus === item.id}" @click="filterChange(item.id, 'purchaseStatus')">{{ item.name }}</dd>
</dl> </dl>
</div>
<div class="filter m-t-20">
<dl> <dl>
<dt>排序</dt> <dd v-for="(item, i) in sorts" :key="i" :class="{active: form.sort === item.id}" @click="filterChange(item.id, 'sort')">{{ item.name }}</dd>
<dd v-for="(item, i) in sort" :key="i" :class="{active: form.sort === item.id}" @click="filterChange(item.id, 'sort')">{{ item.name }}</dd>
</dl> </dl>
</div> </div>
</div>
<div class="courses"> <div class="courses">
<div class="course-bg"></div>
<template v-if="list.length"> <template v-if="list.length">
<ul> <ul>
<li v-for="(item, index) in list" :key="index" @click="toDetail(item.id)"> <li v-for="(item, i) in list" :key="i" @click="toDetail(item.mallId)">
<img :src="item.coverUrl" alt="" /> <img :src="item.coverDrawing" alt="" />
<img v-if="item.logoOfOurSchool" class="my-school" src="@/assets/img/my-school.png" alt="">
<div class="texts">
<div class="title">{{ item.productName }}</div> <div class="title">{{ item.productName }}</div>
<div class="desc" v-html="item.courseIntroduction"></div> <div class="desc" v-html="item.productIntroduction"></div>
<div class="metas"> <div class="metas">
<template v-if="curTab === 2">
<el-tag
type="danger"
effect="dark">
官方精选
</el-tag>
<div class="meta">{{ item.learningCount }}学过</div>
</template>
<div v-if="curTab === 3 && item.tagsName">
<el-tag v-for="(tag, i) in item.tagsName.split(',')" :key="i" class="tag">{{ tag }}</el-tag>
</div>
<template v-if="!curTab || curTab === 1">
<div class="meta"> <div class="meta">
<i class="el-icon-view"></i> <img class="icon" src="@/assets/img/eye.png" alt="">
1 {{ item.learningCount }}
</div> </div>
<div class="meta collect" @click.stop="collect(item)"> <div v-if="item.isAssociatedProduct === 0" class="meta">
<i :class="item.collectionStatus ? 'el-icon-star-on' : 'el-icon-star-off'"></i> <img class="icon" src="@/assets/img/platform.png" alt="">
平台官方
</div> </div>
<div class="meta"> <!-- <span class="type">{{ item.courseType == 1 ? '付费' : '免费'}}</span> -->
<i class="el-icon-user"></i> </template>
职站
</div> </div>
<span v-if="item.courseType == 0" class="type">{{ item.courseType == 1 ? '付费' : '免费'}}</span>
</div> </div>
</li> </li>
</ul> </ul>
<div class="pagination"> <div class="pagination">
<el-pagination background layout="total, prev, pager, next" :total="total" @current-change="handleCurrentChange" :current-page="page"> <el-pagination background layout="total, prev, pager, next" :total="total" @current-change="handleCurrentChange" :current-page="page"></el-pagination>
</el-pagination>
</div> </div>
</template> </template>
</div> </div>
</div> </div>
</div> </div>
</div>
</template> </template>
<script> <script>
import { Loading } from "element-ui"; import { Loading } from "element-ui";
import Setting from "@/setting"; import Setting from "@/setting";
export default { export default {
name: "course",
data() { data() {
return { return {
banners: [],
timer: null, timer: null,
active: +this.$route.query.source || 0, curTab: '',
tabs: [
{
id: '',
name: '全部'
},
{
id: 1,
name: '学科专业'
},
{
id: 2,
name: '产品精选'
},
{
id: 3,
name: '热门标签'
},
],
form: { form: {
categoryId: '', categoryId: '',
hotTag: 1,
professionalCategoryId: '', professionalCategoryId: '',
professionalId: '', professionalId: '',
productClassification: '', productClassification: '',
@ -119,7 +159,7 @@ export default {
name: '未购买' name: '未购买'
}, },
], ],
sort: [ sorts: [
{ {
id: 0, id: 0,
name: '综合排序' name: '综合排序'
@ -164,11 +204,22 @@ export default {
} }
}, },
mounted() { mounted() {
this.getBanner()
this.getSubject() this.getSubject()
this.getClass() this.getClass()
this.initData() this.initData()
}, },
methods: { methods: {
// banner
getBanner() {
this.$post(this.api.listMarketing, {
pageNum: 1,
pageSize: 1000
}).then(({ page }) => {
this.banners = page.records
}).catch(res => {})
},
//
getData() { getData() {
this.loadIns = Loading.service() this.loadIns = Loading.service()
this.$post(this.api.listOfGoods, { this.$post(this.api.listOfGoods, {
@ -250,6 +301,18 @@ export default {
this.classificationList = page.records this.classificationList = page.records
}).catch(res => {}) }).catch(res => {})
}, },
// tab
tabChange({ id }) {
this.curTab = id
this.form.hotTag = 1
this.form.selection = ''
if (id === 3) {
this.form.hotTag = 2
} else if (id === 2) {
this.form.selection = 1
}
this.initData()
},
// //
filterChange(id, prop) { filterChange(id, prop) {
this.form[prop] = id this.form[prop] = id
@ -259,14 +322,9 @@ export default {
this.page = val; this.page = val;
this.getData(); this.getData();
}, },
// //
collect(item) {
this.$post(`${this.api.collectCourse}?courseId=${item.id}&state=${item.collectionStatus ? 0 : 1}`).then(res => {
this.getData()
}).catch(res => {})
},
toDetail(id) { toDetail(id) {
this.$router.push(`/${this.isTourist ? 'preCourse' : 'course'}/details?id=${id}&source=${this.active}`); this.$router.push(`show?id=${id}`);
} }
} }
}; };
@ -275,154 +333,176 @@ export default {
<style lang="scss" scoped> <style lang="scss" scoped>
.wrap { .wrap {
margin: -24px; margin: -24px;
} .banner-item {
.search {
position: relative;
padding: 100px 0 130px;
text-align: center;
background: url(../../../assets/img/course-bg1.png) 0 0/100% 100% no-repeat;
h6 {
margin-bottom: 25px;
font-size: 26px;
color: #fff;
}
.input {
position: relative; position: relative;
width: 700px;
margin: 0 auto;
}
img { img {
width: 100%;
height: 336px;
}
.banner-name {
position: absolute; position: absolute;
top: 19px; top: 116px;
left: 14px; left: 188px;
font-size: 50px;
color: #2E2D31;
} }
input {
width: 100%;
height: 62px;
line-height: 62px;
padding: 0 50px;
font-size: 18px;
color: #333;
border: 0;
outline: none;
border-radius: 4px;
} }
} .inner {
.p-wrap { width: 1146px;
margin: 18px auto;
}
.typw-wrap {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
width: 80%; margin-bottom: 18px;
margin: 20px auto; .left {
.inner { display: inline-flex;
width: calc(100% - 150px);
} }
} .tab {
.switchs { display: inline-flex;
width: 150px; li {
.type { position: relative;
font-weight: bold; margin: 0 20px;
font-size: 18px;
line-height: 25px;
color: #0B1D30;
cursor: pointer;
&:after {
content: '';
position: absolute;
bottom: -10px;
left: 50%;
width: 53px;
height: 4px;
transform: translateX(-50%);
} }
.val { &.active:after {
margin: 10px 20px; background-color: #007EFF;
}
}
}
}
.search {
position: relative;
display: flex;
align-items: center;
width: 410px;
height: 48px;
padding: 0 18px;
background-color: #fff;
border-radius: 31px;
input {
height: 40px;
margin-left: 7px ;
font-size: 14px; font-size: 14px;
color: #333;
border: 0;
outline: none !important;
}
} }
}
.wrap {
.filter { .filter {
width: 100%; padding: 5px 30px;
padding: 15px;
background-color: #fff; background-color: #fff;
border-radius: 10px;
dl { dl {
display: flex; display: flex;
align-items: center; align-items: center;
margin: 20px 0; margin: 20px 0;
dt { dt {
color: #333; min-width: 60px;
font-size: 16px; margin-right: 30px;
color: #666;
font-size: 14px;
font-weight: 600; font-weight: 600;
white-space: nowrap; white-space: nowrap;
} }
dd { dd {
padding: 5px 15px; padding: 5px 15px;
color: #6a6a6a; color: #333;
font-size: 16px; font-size: 14px;
white-space: nowrap; white-space: nowrap;
cursor: pointer; cursor: pointer;
border-radius: 4px;
&.active { &.active {
color: $main-color; font-weight: 600;
background-color: #e6f0ff; color: #007EFF;
} }
} }
} }
} }
.courses { .courses {
position: relative; position: relative;
padding: 10px 0 20px; margin-top: 24px;
// background: url(../../../assets/img/course3.png) 0 0/auto no-repeat;
.course-bg {
position: absolute;
top: 0;
right: 0;
width: 602px;
height: 100%;
// background: url(../../../assets/img/course4.png) (0 -100px)/140% 140% no-repeat;
}
ul { ul {
position: relative; position: relative;
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
} }
li { li {
width: calc(20% - 20px); position: relative;
width: calc((100% - 66px) / 4);
min-height: 250px; min-height: 250px;
overflow: hidden; margin: 0 22px 22px 0;
padding: 18px;
margin: 10px;
cursor: pointer; cursor: pointer;
border-radius: 8px; border-radius: 10px;
background-color: #fff; background-color: #fff;
transition: all 0.3s; transition: all 0.3s;
overflow: hidden;
&:nth-child(4n) {
margin-right: 0;
}
img { img {
width: 100%; width: 100%;
height: 165px; height: 140px;
transition: .3s; transition: .3s;
} }
.my-school {
position: absolute;
top: 0;
right: 0;
width: 57px;
height: 22px;
}
.texts {
padding: 10px;
}
.title { .title {
margin: 10px 0 5px; margin-bottom: 10px;
color: #0B1D30; color: #0B1D30;
font-size: 16px; font-size: 14px;
font-weight: 600;
word-wrap: break-word; word-wrap: break-word;
word-break: break-all; word-break: break-all;
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap; white-space: nowrap;
} }
.desc span {
color: #f00;
font-size: 14px;
background-color: #f00;
}
.desc { .desc {
min-height: 34px;
color: #757F92; color: #757F92;
font-size: 14px; font-size: 12px;
display: -webkit-box; display: -webkit-box;
-webkit-box-orient: vertical; -webkit-box-orient: vertical;
-webkit-line-clamp: 2; -webkit-line-clamp: 2;
overflow: hidden; overflow: hidden;
&.ie { &.ie {
height: 80px; height: 80px;
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap; white-space: nowrap;
} }
} }
.tag {
margin-right: 8px;
color: #007EFF;
background-color: #F9F9F9;
border: 0;
}
.type { .type {
display: inline-block; display: inline-block;
padding: 2px 10px; padding: 4px 11px;
font-size: 12px;
color: #666;
border: 1px solid #DADADA;
border-radius: 20px; border-radius: 20px;
color: #1cdbb8;
border: 1px solid;
} }
.metas { .metas {
display: flex; display: flex;
@ -431,11 +511,15 @@ export default {
margin-top: 10px; margin-top: 10px;
} }
.meta { .meta {
color: #a9a9a9; display: inline-flex;
align-items: center;
color: #B5BFD5;
font-size: 12px; font-size: 12px;
.icon {
width: 14px;
max-height: 14px;
margin-right: 3px;
} }
.collect {
font-size: 20px;
} }
&:hover { &:hover {
box-shadow: 0px 5px 12px 4px rgba(142, 123, 253, 0.09), 0px 3px 6px 0px rgba(142, 123, 253, 0.12), 0px 1px 2px -2px rgba(142, 123, 253, 0.16); box-shadow: 0px 5px 12px 4px rgba(142, 123, 253, 0.09), 0px 3px 6px 0px rgba(142, 123, 253, 0.12), 0px 1px 2px -2px rgba(142, 123, 253, 0.16);
@ -444,11 +528,6 @@ export default {
} }
} }
} }
@media (max-width: 1700px) {
li {
width: calc(25% - 20px);
}
}
} }
} }
</style> </style>

@ -0,0 +1,455 @@
<template>
<div class="wrap">
<div class="inner">
<div class="top">
<div v-if="form.interfaceDiagrams" class="pics">
<img v-for="(pic, i) in form.interfaceDiagrams" :key="i" :src="pic" alt="">
</div>
<div class="right">
<h6>{{ form.mall.productName }}</h6>
<div class="meta">
<span class="val">48</span> 个实验项目&emsp;&emsp;已有 <span class="val">{{ form.goodsRes.learningCount }}</span>人学过
</div>
<div class="des" v-html="form.mall.productIntroduction"></div>
<div class="field">适用专业{{ form.goodsRes.disciplineName }}</div>
<div class="fields">
<div v-if="form.mall.applicationScenario" class="field"><span class="label">适用场景</span>{{ form.mall.applicationScenario }}</div>
<div v-if="form.mall.matchingCourse" class="field"><span class="label">匹配课程</span>{{ form.mall.matchingCourse }}</div>
<div v-if="form.mall.courseHours" class="field"><span class="label">预计课时</span>{{ form.mall.courseHours }}</div>
<div v-if="form.goodsRes.typeName" class="field"><span class="label">产品类型</span>{{ form.goodsRes.typeName }}</div>
</div>
<button v-if="form.goodsRes.logoOfOurSchool" class="btn" @click="toTrail">试用体验</button>
<button v-else class="btn entry" @click="toStation">进入实验</button>
</div>
</div>
<div class="course">
<div class="detail">
<ul class="tab">
<li v-for="(tab, i) in tabs" :key="i" :class="{active: curTab === tab.id}" @click="tabChange(tab)">{{ tab.name }}</li>
</ul>
<div class="courses">
<template v-if="!curTab">
<h6>课程介绍</h6>
<div class="des" v-html="form.mall.detailedIntroduction"></div>
</template>
<template v-else>
<div v-for="(item, i) in chapterList" :key="i">
<h6>{{ item.name }}</h6>
<ul v-if="item.subsectionList.length" class="list">
<li v-for="(section, i) in item.subsectionList" :key="i" @click="toPreview(item, section)">
<p class="name">
<img v-if="section.fileType === 'pptx'" src="@/assets/img/exts/ppt.png" alt="">
<img v-else-if="section.fileType === 'mp4'" src="@/assets/img/exts/video.png" alt="">
<img v-else-if="section.fileType === 'doc' || section.fileType === 'docx'" src="@/assets/img/exts/word.png" alt="">
<img v-else-if="section.fileType === 'txt'" src="@/assets/img/exts/txt.png" alt="">
<img v-else-if="section.fileType === 'pdf'" src="@/assets/img/exts/pdf.png" alt="">
<img v-else src="@/assets/img/exts/pic.png" alt="">
{{ section.projectName }}
</p>
<i :class="['status', section.whetherToStudyOrNot ? 'el-icon-success' : 'circle']" @click.stop="studySection(item, section)"></i>
</li>
</ul>
</div>
</template>
</div>
</div>
<div class="products">
<h6>热门产品推荐</h6>
<ul class="product">
<li v-for="(item, i) in hots" :key="i" @click="toDetail(item.mallId)">
<img :src="item.coverDrawing" alt="" />
<img v-if="item.logoOfOurSchool" class="my-school" src="@/assets/img/my-school.png" alt="">
<div class="texts">
<div class="title">{{ item.productName }}</div>
<div class="desc" v-html="item.productIntroduction"></div>
<div class="metas">
<template v-if="item.selected">
<el-tag
type="danger"
effect="dark">
官方精选
</el-tag>
<div class="meta">{{ item.learningCount }}学过</div>
</template>
<template v-else>
<div class="meta">
<img class="icon" src="@/assets/img/eye.png" alt="">
{{ item.learningCount }}
</div>
<div v-if="item.isAssociatedProduct === 0" class="meta">
<img class="icon" src="@/assets/img/platform.png" alt="">
平台官方
</div>
<span class="type">{{ item.courseType == 1 ? '付费' : '免费'}}</span>
</template>
</div>
</div>
</li>
</ul>
</div>
</div>
</div>
</div>
</template>
<script>
import Util from "@/libs/util"
import Setting from "@/setting"
export default {
data() {
return {
id: this.$route.query.id,
curTab: 0,
tabs: [
{
id: 0,
name: '详情介绍'
},
{
id: 1,
name: '课程目录'
},
],
form: {
mall: {},
goodsRes: {}
},
chapterList: [],
hots: []
};
},
mounted() {
this.getData()
this.getHot()
},
methods: {
//
getData() {
this.$get(`${this.api.detailsOfGoods}?mallId=${this.id}`).then(res => {
const e = res.orderDetails
if (e.mall.interfaceDiagram) e.interfaceDiagrams = e.mall.interfaceDiagram.split(',')
this.form = e
this.getChapter()
}).catch(err => {})
},
//
async getChapter() {
let res = await this.$post(`${this.api.courseLearningProgress}?courseId=${this.form.mall.associatedProduct}`)
this.chapterList = res.list
},
// tab
tabChange({ id }) {
this.curTab = id
},
//
toPreview(item, section) {
this.form.goodsRes.logoOfOurSchool ?
this.$router.push('/station/preview?courseId=' + this.form.mall.associatedProduct + '&curriculumName=' + this.form.mall.associatedProductName) :
this.toTrail()
},
// /
studySection(item) {
item.whetherToStudyOrNot ?
this.$post(`${this.api.deleteLearningProgress}?id=${item.learningProgressId}`).then(res => {
this.getProgress()
}).catch(res => {}) :
this.$post(this.api.saveLearningProgress, {
cid: this.courseId,
projectId: item.projectId,
}).then(res => {
this.getProgress()
}).catch(res => {})
},
//
toTrail() {
window.open('https://f.wps.cn/g/VekixBcm/')
},
//
toStation() {
this.$post(`${this.api.addLearningRecord}?mallId=${this.id}`).then(res => {
this.$router.push('/station/preview?courseId=' + this.form.mall.associatedProduct + '&curriculumName=' + this.form.mall.associatedProductName)
}).catch(res => {})
},
//
getHot() {
this.$post(this.api.listOfGoods, {
hotTag: 1,
sort: 1,
pageNum: 1,
pageSize: 2,
}).then(({ page }) => {
this.hots = page.records
}).catch(res => {})
},
//
toDetail(id) {
this.$router.push(`show?id=${id}`);
},
}
};
</script>
<style lang="scss" scoped>
.wrap {
background: #F3F6FA;
.inner {
width: 1154px;
margin: 0 auto;
}
.top {
display: flex;
padding: 24px;
background-color: #fff;
border-radius: 10px;
.pics {
width: 436px;
margin-right: 24px;
img {
width: 140px;
height: 62px;
margin-right: 8px;
border-radius: 8px;
&:first-child {
width: 100%;
height: 192px;
margin-bottom: 12px;
}
&:last-child {
margin-right: 0;
}
}
}
.right {
width: 646px;
}
h6 {
font-size: 24px;
font-weight: 600;
color: #2E2D31;
}
.meta {
margin: 10px 0;
font-size: 12px;
color: #2E2D31;
.val {
color: #007EFF;
}
}
.des {
margin-bottom: 15px;
font-size: 14px;
color: #666;
line-height: 20px;
}
.field {
font-size: 14px;
color: #2E2D31;
.label {
color: #333;
}
}
.fields {
display: flex;
margin: 10px 0 20px;
.field {
margin-right: 50px;
&:last-child {
margin-right: 0;
}
}
}
.btn {
width: 119px;
height: 46px;
color: #fff;
background: #64C25A;
border-radius: 6px;
border: 0;
cursor: pointer;
&:hover {
opacity: .9;
}
&:first-child {
margin-left: 11px;
}
}
.entry {
background: #007EFF;
}
}
.tab {
display: inline-flex;
li {
position: relative;
margin-right: 20px;
font-size: 18px;
line-height: 25px;
color: #0B1D30;
cursor: pointer;
&:after {
content: '';
position: absolute;
bottom: -10px;
left: 50%;
width: 53px;
height: 4px;
transform: translateX(-50%);
}
&.active:after {
background-color: #007EFF;
}
}
}
.course {
display: flex;
margin-top: 20px;
.detail {
width: 835px;
padding: 20px 36px;
background-color: #fff;
border-radius: 10px;
}
}
.courses {
margin-top: 40px;
h6 {
margin-bottom: 20px;
font-size: 14px;
color: #333;
}
.list {
height: calc(100vh - 530px);
padding-right: 15px;
overflow: auto;
li {
display: flex;
justify-content: space-between;
align-items: center;
height: 46px;
border-radius: 8px;
&:hover {
background: #F6FBFF;
}
}
.name {
display: inline-flex;
align-items: center;
font-size: 14px;
color: #333;
img {
margin-right: 8px;
}
}
.status {
font-size: 18px;
color: #00c935;
}
.circle {
width: 18px;
height: 18px;
border-radius: 50%;
border: 1px solid #ccc;
}
}
}
.products {
width: 270px;
margin-left: 24px;
&>h6 {
font-size: 14px;
color: #0B1D30;
}
}
.product {
margin-top: 11px;
li {
position: relative;
margin-bottom: 15px;
cursor: pointer;
border-radius: 10px;
background-color: #fff;
transition: all 0.3s;
overflow: hidden;
img {
width: 100%;
height: 140px;
transition: .3s;
}
.my-school {
position: absolute;
top: 0;
right: 0;
width: 57px;
height: 22px;
}
.texts {
padding: 10px;
}
.title {
margin-bottom: 10px;
color: #0B1D30;
font-size: 14px;
font-weight: 600;
word-wrap: break-word;
word-break: break-all;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.desc {
min-height: 34px;
color: #757F92;
font-size: 12px;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
&.ie {
height: 80px;
text-overflow: ellipsis;
white-space: nowrap;
}
}
.tag {
margin-right: 8px;
color: #007EFF;
background-color: #F9F9F9;
border: 0;
}
.type {
display: inline-block;
padding: 4px 11px;
font-size: 12px;
color: #666;
border: 1px solid #DADADA;
border-radius: 20px;
}
.metas {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 10px;
}
.meta {
display: inline-flex;
align-items: center;
color: #B5BFD5;
font-size: 12px;
.icon {
width: 14px;
max-height: 14px;
margin-right: 3px;
}
}
&:hover {
box-shadow: 0px 5px 12px 4px rgba(142, 123, 253, 0.09), 0px 3px 6px 0px rgba(142, 123, 253, 0.12), 0px 1px 2px -2px rgba(142, 123, 253, 0.16);
img {
transform: scale(1.05);
}
}
}
}
}
</style>

@ -327,7 +327,7 @@
</thead> </thead>
</table> </table>
</div> </div>
<div class="main_table" ref="active" style="max-height: 220px;margin-top: 0;overflow: hidden"> <div class="main_table" ref="active" style="max-height: 230px;margin-top: 0;overflow: hidden">
<table> <table>
<tbody> <tbody>
<tr v-for="(item, i) in actives" :key="i"> <tr v-for="(item, i) in actives" :key="i">

@ -19,7 +19,7 @@
<div class="item" :title="item.curriculumName" @click="goPreview(item)" :key="index" v-if="!keyword || item.curriculumName.includes(keyword)"> <div class="item" :title="item.curriculumName" @click="goPreview(item)" :key="index" v-if="!keyword || item.curriculumName.includes(keyword)">
<img :src="item.coverUrl" alt=""> <img :src="item.coverUrl" alt="">
<div class="bottom"> <div class="bottom">
<p class="text"><span>{{ item.curriculumName }}</span></p> <p class="text"><span>{{ item.goodsName || item.curriculumName }}</span></p>
<a>进入实验</a> <a>进入实验</a>
</div> </div>
</div> </div>

@ -64,7 +64,7 @@
<i class="icon el-icon-notebook-2"></i> 目录 <i class="icon el-icon-notebook-2"></i> 目录
</div> </div>
<div :class="['item', { active: type === 2 }]" @click="typeChange(2)"> <div :class="['item', { active: type === 2 }]" @click="typeChange(2)">
<i class="icon el-icon-timer"></i> 进度 <i class="icon el-icon-timer"></i> 学进度
</div> </div>
</div> </div>
<div class="chapters"> <div class="chapters">
@ -81,9 +81,9 @@
</template> </template>
</template> </template>
<div v-else class="section"> <div v-else class="section">
<p class="sectionName" v-for="(item, i) in progressList" :key="i"> <p class="sectionName" v-for="(item, i) in progressList" :key="i" :title="item.projectName">
{{ i + 1 }}. {{ i + 1 }}.
{{ item.name }} {{ item.projectName }}
<i :class="['icon', item.whetherToStudyOrNot ? 'el-icon-success' : 'circle']" @click.stop="studySection(item)"></i> <i :class="['icon', item.whetherToStudyOrNot ? 'el-icon-success' : 'circle']" @click.stop="studySection(item)"></i>
</p> </p>
</div> </div>
@ -98,6 +98,7 @@
<div class="tabs"> <div class="tabs">
<a class="item" v-for="(item, i) in tabs" :key="i" :class="{active: item.id == active}" @click="tabChange(item)">{{ item.name }}</a> <a class="item" v-for="(item, i) in tabs" :key="i" :class="{active: item.id == active}" @click="tabChange(item)">{{ item.name }}</a>
</div> </div>
<div class="tab-content">
<template v-if="active === 1"> <template v-if="active === 1">
<el-card shadow="hover" class="m-t-20 m-b-20"> <el-card shadow="hover" class="m-t-20 m-b-20">
<h4 style="margin-bottom: 10px;font-size: 16px;">课程简介</h4> <h4 style="margin-bottom: 10px;font-size: 16px;">课程简介</h4>
@ -207,6 +208,7 @@
</ul> </ul>
</div> </div>
</template> </template>
</div>
<el-dialog title="请选择项目" v-loading="loading" :visible.sync="projectVisible" width="828px" custom-class="project-dia" :close-on-click-modal="false"> <el-dialog title="请选择项目" v-loading="loading" :visible.sync="projectVisible" width="828px" custom-class="project-dia" :close-on-click-modal="false">
@ -385,24 +387,23 @@ export default {
// 10 // 10
this.overdue = isRenew this.overdue = isRenew
this.getChapter() this.getChapter()
this.getProgress()
}).catch(res => {}) }).catch(res => {})
}, },
//
async getChapter() { async getChapter() {
let res = await this.$post(`${this.api.courseLearningProgress}?courseId=${this.courseId}`); let res = await this.$get(`${this.api.curriculumChapter}/${this.courseId}`);
this.chapterList = res.chapterList; this.chapterList = res.chapterList;
const list = []
res.chapterList.forEach(e => {
e.subsectionList.forEach(n => {
n.chapterId = e.id
list.push(n)
})
})
this.progressList = list
this.schedule = +(res.schedule.replace('%', ''))
if (this.chapterList.length && this.chapterList[0].subsectionList && this.chapterList[0].subsectionList.length) { if (this.chapterList.length && this.chapterList[0].subsectionList && this.chapterList[0].subsectionList.length) {
this.preview(this.chapterList[0].subsectionList[0], this.chapterList[0].name, 1); this.preview(this.chapterList[0].subsectionList[0], this.chapterList[0].name, 1);
} }
}, },
//
async getProgress() {
let res = await this.$post(`${this.api.courseLearningProgress}?courseId=${this.courseId}`);
this.progressList = res.list
this.schedule = +(res.schedule.replace('%', ''))
},
// //
typeChange(id) { typeChange(id) {
this.getChapter() this.getChapter()
@ -489,14 +490,13 @@ export default {
studySection(item) { studySection(item) {
item.whetherToStudyOrNot ? item.whetherToStudyOrNot ?
this.$post(`${this.api.deleteLearningProgress}?id=${item.learningProgressId}`).then(res => { this.$post(`${this.api.deleteLearningProgress}?id=${item.learningProgressId}`).then(res => {
this.getChapter() this.getProgress()
}).catch(res => {}) : }).catch(res => {}) :
this.$post(this.api.saveLearningProgress, { this.$post(this.api.saveLearningProgress, {
chapterId: item.chapterId,
cid: this.courseId, cid: this.courseId,
subsectionId: item.id, projectId: item.projectId,
}).then(res => { }).then(res => {
this.getChapter() this.getProgress()
}).catch(res => {}) }).catch(res => {})
}, },
preview(row, chapterName, showDia = 0) { preview(row, chapterName, showDia = 0) {
@ -797,9 +797,6 @@ $height: 700px;
/deep/.el-progress-bar { /deep/.el-progress-bar {
width: 92%; width: 92%;
} }
/deep/.el-progress__text {
color: #fff;
}
.desc-wrap{ .desc-wrap{
position: relative; position: relative;
.desc{ .desc{
@ -878,9 +875,6 @@ $height: 700px;
border-radius: 50%; border-radius: 50%;
border: 1px solid #ccc; border: 1px solid #ccc;
} }
&.active{
color: #fff;
}
} }
} }
.buy { .buy {
@ -998,6 +992,9 @@ $height: 700px;
} }
} }
.tab-content {
width: 80%;
}
/deep/.project-dia { /deep/.project-dia {
.el-dialog__body { .el-dialog__body {
padding: 28px 32px; padding: 28px 32px;

@ -14,10 +14,14 @@ export default {
component: BasicLayout, component: BasicLayout,
children: [ children: [
{ {
name: `${pre}list`,
path: `list`, path: `list`,
component: () => import("@/pages/product/list"), component: () => import("@/pages/product/list"),
meta: { title: "产品中心" } meta: { title: "产品中心" }
}, },
{
path: `show`,
component: () => import("@/pages/product/show"),
meta: { title: "产品详情" }
},
] ]
}; };

@ -80,8 +80,11 @@
} }
/deep/.timeline { /deep/.timeline {
padding-left: 12%; padding-left: 9%;
overflow: hidden; overflow: hidden;
.el-timeline-item {
padding-bottom: 40px;
}
.el-timeline-item__node--normal { .el-timeline-item__node--normal {
top: 30px; top: 30px;
} }
@ -96,7 +99,7 @@
.sign { .sign {
position: relative; position: relative;
display: inline-block; display: inline-block;
margin-left: -15%; margin-left: -12.5%;
font-size: 14px; font-size: 14px;
color: #9076FF; color: #9076FF;
} }
@ -110,7 +113,7 @@
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
padding-bottom: 10px; padding-bottom: 10px;
margin: -32px 0 20px; margin: -22px 0 20px;
font-size: 18px; font-size: 18px;
color: #9076FF; color: #9076FF;
border-bottom: 1px dashed #bfbfbf; border-bottom: 1px dashed #bfbfbf;

Loading…
Cancel
Save