Compare commits

...

2 Commits

Author SHA1 Message Date
significative 8c3778ca78 w 3 months ago
significative 171ae05698 w 3 months ago
  1. 10
      teaching_integration_platform_template/src/api/configuration.ts
  2. 4
      teaching_integration_platform_template/src/store/module/user.ts
  3. 140
      teaching_integration_platform_template/src/views/course/index.vue
  4. 73
      teaching_integration_platform_template/src/views/home/index.vue
  5. 6
      teaching_integration_platform_template/src/views/professionalListProfile/index.vue
  6. 27
      teaching_integration_platform_template/src/views/roadbedRecommendation/components/mountNode.vue
  7. 80
      teaching_integration_platform_template/src/views/roadbedRecommendation/index.vue
  8. 64
      teaching_integration_platform_template/vite.config.ts.timestamp-1726102400305-7b45289bcf875.mjs

@ -8,22 +8,24 @@ enum Api {
} }
// 提示批量处理 // 提示批量处理
const initOptions = { text: '加载中', success: '成功', error: '失败' } const initOptions = { text: '加载中', success: '成功', error: '失败' }
function proxrequest(request, options: any = initOptions) { export function proxrequest(request, options: Partial<typeof initOptions> = initOptions) {
return async (...arg) => { return async (...arg) => {
if (!options) return request(...arg) if (!options) return request(...arg)
const loadingInstance = ElLoading.service({ text: options.text }) const loadingInstance = ElLoading.service({ text: options.text })
let result;
try { try {
await request(...arg) result = await request(...arg)
ElMessage.success(options.success) ElMessage.success(options.success)
} catch (error) { } catch (error) {
result = error
ElMessage.error(options.error) ElMessage.error(options.error)
} finally { } finally {
loadingInstance.close() loadingInstance.close()
} }
return request return result
} }
} }

@ -5,6 +5,7 @@ const userStore = defineStore('userStore', () => {
const userInfo = reactive<any>({}) const userInfo = reactive<any>({})
const isLogin = ref(false) const isLogin = ref(false)
const token = ref('') const token = ref('')
const verifyToken = () => { }
userGetInfoService(token.value).then(res => { userGetInfoService(token.value).then(res => {
// @ts-ignore // @ts-ignore
@ -16,7 +17,8 @@ const userStore = defineStore('userStore', () => {
return { return {
token, token,
userInfo, userInfo,
isLogin isLogin,
verifyToken
} }
}) })
export default userStore export default userStore

@ -2,17 +2,8 @@
<div class="container" v-if="loading"> <div class="container" v-if="loading">
<div class="left" v-loading="tabLoading"> <div class="left" v-loading="tabLoading">
<div class="gruop"> <div class="gruop">
<Graph <Graph :width="1195" :height="800" :index="courseId" :id="courseId" :radio1="radio1" :checkList="checkList"
:width="1195" v-show="flag === 1" @clickGraph="clickGraphChange" v-if="isSetting" />
:height="800"
:index="courseId"
:id="courseId"
:radio1="radio1"
:checkList="checkList"
v-show="flag === 1"
@clickGraph="clickGraphChange"
v-if="isSetting"
/>
<div class="video" v-if="flag === 2"> <div class="video" v-if="flag === 2">
<video id="video" width="100%" height="100%" controls> <video id="video" width="100%" height="100%" controls>
<source :src="videoUrl" type="video/mp4" /> <source :src="videoUrl" type="video/mp4" />
@ -21,27 +12,23 @@
</div> </div>
<div class="pdf" v-if="flag === 3"> <div class="pdf" v-if="flag === 3">
<!-- <vuePdf /> --> <!-- <vuePdf /> -->
<VuePdf <VuePdf v-for="page in numOfPages" :key="page" :src="pdfUrl" :page="page" />
v-for="page in numOfPages"
:key="page"
:src="pdfUrl"
:page="page"
/>
</div> </div>
<div class="docx" v-if="flag === 4"> <div class="docx" v-if="flag === 4">
<vue-office-docx :src="docx" style="width: 100%; height: 100%" /> <vue-office-docx :src="docx" style="width: 100%; height: 100%" />
</div> </div>
<div v-show="flag != 1" class="back" @click="flag = 1"> <div v-show="flag != 1" class="back" @click="flag = 1">
<el-icon><Back /></el-icon> <el-icon>
<Back />
</el-icon>
</div> </div>
<div class="show-graph-sett" @click="showSetting" v-if="!showFlag"> <div class="show-graph-sett" @click="showSetting" v-if="!showFlag">
<el-icon><ArrowLeftBold /></el-icon> <el-icon>
<ArrowLeftBold />
</el-icon>
</div> </div>
<div <div :class="showFlag ? 'graph-setting' : 'graph-setting-hidden'" @mouseleave="heddinSetting"
:class="showFlag ? 'graph-setting' : 'graph-setting-hidden'" @mouseenter="clearHeddin">
@mouseleave="heddinSetting"
@mouseenter="clearHeddin"
>
<el-radio-group v-model="radio1" @change="radio1Change"> <el-radio-group v-model="radio1" @change="radio1Change">
<el-radio value="2" size="mini" style="margin: 0">二层</el-radio> <el-radio value="2" size="mini" style="margin: 0">二层</el-radio>
<el-radio value="3" size="mini" style="margin: 0">三层</el-radio> <el-radio value="3" size="mini" style="margin: 0">三层</el-radio>
@ -65,32 +52,17 @@
</el-table> </el-table>
</div> </div>
<div class="resource"> <div class="resource">
<el-tabs <el-tabs v-model="activeName" class="demo-tabs" @tab-click="handleClick" v-loading="isTabsLoading">
v-model="activeName"
class="demo-tabs"
@tab-click="handleClick"
v-loading="isTabsLoading"
>
<el-tab-pane label="视频" name="1"> <el-tab-pane label="视频" name="1">
<div class="files-box"> <div class="files-box">
<div <div class="item" v-for="item in courseFilesList.video" :key="item.id" @click="clickFile(item, 2)">
class="item"
v-for="item in courseFilesList.video"
:key="item.id"
@click="clickFile(item, 2)"
>
{{ item.name }} {{ item.name }}
</div> </div>
</div> </div>
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="PPT" name="2"> <el-tab-pane label="PPT" name="2">
<div class="files-box"> <div class="files-box">
<div <div class="item" v-for="item in courseFilesList.PPT" :key="item.id" @click="clickFile(item, 3)">
class="item"
v-for="item in courseFilesList.PPT"
:key="item.id"
@click="clickFile(item, 3)"
>
{{ item.name }} {{ item.name }}
</div> </div>
</div> </div>
@ -98,24 +70,14 @@
<el-tab-pane label="试题" name="3">Role</el-tab-pane> <el-tab-pane label="试题" name="3">Role</el-tab-pane>
<el-tab-pane label="文档" name="4"> <el-tab-pane label="文档" name="4">
<div class="files-box"> <div class="files-box">
<div <div class="item" v-for="item in courseFilesList.word" :key="item.id" @click="clickFile(item, 4)">
class="item"
v-for="item in courseFilesList.word"
:key="item.id"
@click="clickFile(item, 4)"
>
{{ item.name }} {{ item.name }}
</div> </div>
</div> </div>
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="其他" name="5"> <el-tab-pane label="其他" name="5">
<div class="files-box"> <div class="files-box">
<div <div class="item" v-for="item in courseFilesList.other" :key="item.id" @click="download(item)">
class="item"
v-for="item in courseFilesList.other"
:key="item.id"
@click="download(item)"
>
{{ item.name }} {{ item.name }}
</div> </div>
</div> </div>
@ -130,7 +92,8 @@
</div> </div>
<div class="description"> <div class="description">
<div class="description-box"> <div class="description-box">
Vues 设计与实现这本书的简介 Vues 设计与实现是一本深入剖析 {{ Route.query.name }}这个课程的简介{{ learn.description }}
<!-- Vues 设计与实现这本书的简介 Vues 设计与实现是一本深入剖析
Vues 框架核心原理的权威著作 Vues 框架核心原理的权威著作
本书首先会为读者搭建起一个坚实的知识基础详细介绍 Vues 本书首先会为读者搭建起一个坚实的知识基础详细介绍 Vues
的发展历程和其在前端开发领域的重要地位接着深入探讨 Vues 的发展历程和其在前端开发领域的重要地位接着深入探讨 Vues
@ -144,7 +107,7 @@
来构建复杂而强大的应用程序同时书中也提供了丰富的实战案例和最佳实践让读者能够将所学知识迅速应用到实际开发中 来构建复杂而强大的应用程序同时书中也提供了丰富的实战案例和最佳实践让读者能够将所学知识迅速应用到实际开发中
无论是前端开发的新手还是经验丰富的开发者都能从Vues 无论是前端开发的新手还是经验丰富的开发者都能从Vues
设计与实现中获得宝贵的知识和技能从而提升自己的开发水平打造出更加出色的前端应用它不仅是一本技术指南更是一本启发思考引领创新的宝典为读者打开了深入理解和掌握 设计与实现中获得宝贵的知识和技能从而提升自己的开发水平打造出更加出色的前端应用它不仅是一本技术指南更是一本启发思考引领创新的宝典为读者打开了深入理解和掌握
Vues 框架的大门 Vues 框架的大门 -->
</div> </div>
</div> </div>
<div class="hours"> <div class="hours">
@ -184,7 +147,7 @@
<script lang="ts" setup> <script lang="ts" setup>
import StuList from './components/StuList.vue' import StuList from './components/StuList.vue'
import { ref, nextTick } from 'vue' import { ref, nextTick, reactive } from 'vue'
import Graph from '../home/components/Graph1.vue' import Graph from '../home/components/Graph1.vue'
import courseTree from './components/courseTree.vue' import courseTree from './components/courseTree.vue'
import { useRoute, useRouter } from 'vue-router' import { useRoute, useRouter } from 'vue-router'
@ -199,10 +162,11 @@ import { filterFilesType } from '@/utils/filters'
import { VuePdf, createLoadingTask } from 'vue3-pdfjs/esm' import { VuePdf, createLoadingTask } from 'vue3-pdfjs/esm'
import VueOfficeDocx from '@vue-office/docx' import VueOfficeDocx from '@vue-office/docx'
// import vuePdf from './components/vuePdf.vue' // import vuePdf from './components/vuePdf.vue'
import { getCourseDetailApi } from '@/api/configuration'
const Route = useRoute() const Route = useRoute()
const Router = useRouter() const Router = useRouter()
const courseId: string = Route.query.id as string const courseId: string = Route.query.id as string
console.log(Route.query.id)
const chapterList = ref<any>([]) const chapterList = ref<any>([])
const loading = ref(false) const loading = ref(false)
const getCourseChapterEvent = async () => { const getCourseChapterEvent = async () => {
@ -216,7 +180,7 @@ const getCourseChapterEvent = async () => {
courseId: '2cd6b5b62c344fd0becff6010cba566e', courseId: '2cd6b5b62c344fd0becff6010cba566e',
}) })
chapterList.value = res.data chapterList.value = res.data
console.log(res,'res') console.log(res, 'res')
loading.value = true loading.value = true
loadingInstance.close() loadingInstance.close()
} }
@ -226,7 +190,10 @@ const courseObjectivesTrees = ref([])
const handleClick = (e: any) => { const handleClick = (e: any) => {
console.log(e) console.log(e)
} }
const learn = reactive<any>({})
if (Route.query.id) {
getCourseDetailApi(Route.query.id as string).then(res => Object.assign(learn, res.data));
}
const isTabsLoading = ref<boolean>(false) const isTabsLoading = ref<boolean>(false)
const courseFilesList = ref<any>({}) const courseFilesList = ref<any>({})
// //
@ -376,6 +343,7 @@ getCourseObjectivesListEvent()
<style lang="scss" scoped> <style lang="scss" scoped>
.view-container { .view-container {
// height: 100vh; // height: 100vh;
.container { .container {
width: $base-container-width; width: $base-container-width;
@ -383,8 +351,10 @@ getCourseObjectivesListEvent()
// height: 1600px; // height: 1600px;
display: flex; display: flex;
padding-bottom: 20px; padding-bottom: 20px;
.left { .left {
width: 1195px; width: 1195px;
// height: 800px; // height: 800px;
.gruop { .gruop {
position: relative; position: relative;
@ -392,24 +362,29 @@ getCourseObjectivesListEvent()
width: 100%; width: 100%;
height: 800px; height: 800px;
background-color: #fff; background-color: #fff;
.video { .video {
width: 100%; width: 100%;
height: 100%; height: 100%;
background-color: #d9d9d9; background-color: #d9d9d9;
#video { #video {
object-fit: cover; object-fit: cover;
} }
} }
.pdf { .pdf {
width: 100%; width: 100%;
height: 100%; height: 100%;
overflow: auto; overflow: auto;
} }
.docx { .docx {
width: 100%; width: 100%;
height: 100%; height: 100%;
overflow: auto; overflow: auto;
} }
.back { .back {
position: absolute; position: absolute;
top: 30px; top: 30px;
@ -420,6 +395,7 @@ getCourseObjectivesListEvent()
background-color: rgba(0, 0, 0, 0.1); background-color: rgba(0, 0, 0, 0.1);
border-radius: 50%; border-radius: 50%;
cursor: pointer; cursor: pointer;
i { i {
width: 100%; width: 100%;
height: 100%; height: 100%;
@ -429,16 +405,19 @@ getCourseObjectivesListEvent()
justify-content: center; justify-content: center;
} }
} }
.graph-setting { .graph-setting {
position: absolute; position: absolute;
bottom: 30px; bottom: 30px;
right: 10px; right: 10px;
width: 80px; width: 80px;
height: 270px; height: 270px;
animation: fadeIn 0.3s ease-in-out; /* 持续时间2秒,缓动函数为ease-in-out */ animation: fadeIn 0.3s ease-in-out;
/* 持续时间2秒,缓动函数为ease-in-out */
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
.reset { .reset {
width: 50px; width: 50px;
height: 30px; height: 30px;
@ -451,15 +430,18 @@ getCourseObjectivesListEvent()
cursor: pointer; cursor: pointer;
} }
} }
.graph-setting-hidden { .graph-setting-hidden {
position: absolute; position: absolute;
bottom: 30px; bottom: 30px;
right: -90px; right: -90px;
width: 80px; width: 80px;
height: 270px; height: 270px;
animation: fadeOut 0.3s ease-in-out; /* 持续时间2秒,缓动函数为ease-in-out */ animation: fadeOut 0.3s ease-in-out;
/* 持续时间2秒,缓动函数为ease-in-out */
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
.reset { .reset {
width: 50px; width: 50px;
height: 30px; height: 30px;
@ -472,24 +454,29 @@ getCourseObjectivesListEvent()
cursor: pointer; cursor: pointer;
} }
} }
@keyframes fadeIn { @keyframes fadeIn {
from { from {
right: -60px; right: -60px;
} }
to { to {
right: 10px; right: 10px;
} }
} }
@keyframes fadeOut { @keyframes fadeOut {
from { from {
right: 10px; right: 10px;
} }
to { to {
right: -60px; right: -60px;
display: none; display: none;
} }
} }
.show-graph-sett { .show-graph-sett {
position: absolute; position: absolute;
bottom: 30px; bottom: 30px;
@ -503,20 +490,24 @@ getCourseObjectivesListEvent()
padding-left: 5px; padding-left: 5px;
cursor: pointer; cursor: pointer;
transition: all 0.3s; transition: all 0.3s;
i { i {
font-size: 14px; font-size: 14px;
} }
} }
} }
.show-graph-sett:hover { .show-graph-sett:hover {
transform: scale(1.3); transform: scale(1.3);
} }
.resource { .resource {
width: 100%; width: 100%;
height: 500px; height: 500px;
margin-top: 20px; margin-top: 20px;
padding: 20px; padding: 20px;
background-color: #fff; background-color: #fff;
.files-box { .files-box {
.item { .item {
// width: 200px; // width: 200px;
@ -528,17 +519,20 @@ getCourseObjectivesListEvent()
text-decoration: underline; text-decoration: underline;
cursor: pointer; cursor: pointer;
} }
.item:hover { .item:hover {
color: Blue; color: Blue;
} }
} }
} }
.cours-target { .cours-target {
width: 100%; width: 100%;
height: 300px; height: 300px;
margin-top: 20px; margin-top: 20px;
padding: 20px; padding: 20px;
background-color: #fff; background-color: #fff;
.title { .title {
font-size: 16px; font-size: 16px;
height: 40px; height: 40px;
@ -548,34 +542,40 @@ getCourseObjectivesListEvent()
} }
} }
} }
.right { .right {
width: 400px; width: 400px;
margin-left: 20px; margin-left: 20px;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
.course-info { .course-info {
width: 100%; width: 100%;
height: 640px; height: 640px;
background-color: #fff; background-color: #fff;
.image { .image {
width: 100%; width: 100%;
img { img {
width: 100%; width: 100%;
height: 220px; height: 220px;
} }
} }
.description { .description {
overflow-y: auto; overflow-y: auto;
height: 260px; height: 260px;
padding: 10px 20px; padding: 10px 20px;
text-indent: 2em; /* 2em 约等于两个汉字的宽度 */ text-indent: 2em;
/* 2em 约等于两个汉字的宽度 */
font-size: 18px; font-size: 18px;
line-height: 40px; line-height: 40px;
.description-box { .description-box {}
}
} }
.hours { .hours {
padding: 10px 20px; padding: 10px 20px;
border-top: 1px solid rgba(0, 0, 0, 0.1); border-top: 1px solid rgba(0, 0, 0, 0.1);
@ -585,12 +585,14 @@ getCourseObjectivesListEvent()
height: 30px; height: 30px;
align-items: center; align-items: center;
font-size: 14px; font-size: 14px;
.label { .label {
color: #999; color: #999;
} }
} }
} }
} }
.chapter { .chapter {
overflow-y: auto; overflow-y: auto;
height: 460px; height: 460px;
@ -598,6 +600,7 @@ getCourseObjectivesListEvent()
margin-top: 20px; margin-top: 20px;
background-color: #fff; background-color: #fff;
} }
.student-list { .student-list {
height: 500px; height: 500px;
width: 100%; width: 100%;
@ -607,13 +610,17 @@ getCourseObjectivesListEvent()
} }
} }
} }
::-webkit-scrollbar { ::-webkit-scrollbar {
width: 4px; /* 滚动条宽度 */ width: 4px;
/* 滚动条宽度 */
} }
/* 设置滚动条上下按钮的样式 */ /* 设置滚动条上下按钮的样式 */
::-webkit-scrollbar-button { ::-webkit-scrollbar-button {
background-color: #fff; background-color: #fff;
} }
:deep(.docx-wrapper) { :deep(.docx-wrapper) {
background-color: #fff; background-color: #fff;
} }
@ -623,6 +630,7 @@ getCourseObjectivesListEvent()
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
} }
:deep(.el-checkbox-group) { :deep(.el-checkbox-group) {
display: flex !important; display: flex !important;
flex-direction: column; flex-direction: column;

@ -1,5 +1,5 @@
<template> <template>
<div class="loop" v-for="(item,index) in couresData.content" :key="item.id"> <div class="loop" v-for="(item, index) in couresData.content" :key="item.id">
<div class="main" v-if="index % 2 === 0"> <div class="main" v-if="index % 2 === 0">
<!-- <div class="course-list">111</div> --> <!-- <div class="course-list">111</div> -->
<div class="container"> <div class="container">
@ -9,7 +9,7 @@
</div> </div>
<div class="footer"> <div class="footer">
<div class="left-title">{{ item.name }}</div> <div class="left-title">{{ item.name }}</div>
<div class="go-info" @click="goToCourseInfo(item.id)"></div> <div class="go-info" @click="goToCourseInfo(item.id, item.name)"></div>
</div> </div>
</div> </div>
<div class="right-info"> <div class="right-info">
@ -28,11 +28,7 @@
</div> </div>
</div> </div>
</div> </div>
<div <div class="main" v-else style="background: linear-gradient(to right, #aecaff 60%, #5792ff)">
class="main"
v-else
style="background: linear-gradient(to right, #aecaff 60%, #5792ff)"
>
<!-- <div class="course-list">111</div> --> <!-- <div class="course-list">111</div> -->
<div class="container"> <div class="container">
<div class="right-info"> <div class="right-info">
@ -42,9 +38,9 @@
</div> </div>
<div class="crous-content"> <div class="crous-content">
<ul> <ul>
<li>总学时{{item.classhours}}学时</li> <li>总学时{{ item.classhours }}学时</li>
<li>章节数{{ item.totalchapter }}</li> <li>章节数{{ item.totalchapter }}</li>
<li>总学分{{item.credit }}</li> <li>总学分{{ item.credit }}</li>
<li>知识点总分{{ item.totalKnow }}</li> <li>知识点总分{{ item.totalKnow }}</li>
</ul> </ul>
</div> </div>
@ -63,7 +59,7 @@
</div> </div>
</div> </div>
<div class="get-more"> <div class="get-more">
<div class="btn" @click="getMore">{{btnTexst}}</div> <div class="btn" @click="getMore">{{ btnTexst }}</div>
</div> </div>
</template> </template>
@ -72,22 +68,22 @@
import Graph from './components/Graph.vue' import Graph from './components/Graph.vue'
import { getCourseList } from '@/api/course' import { getCourseList } from '@/api/course'
import { reactive, ref } from 'vue' import { reactive, ref } from 'vue'
import {useRouter} from 'vue-router' import { useRouter } from 'vue-router'
interface Page { interface Page {
pageNo: number pageNo: number
pageSize: number pageSize: number
username:string username: string
userId: string | number userId: string | number
} }
interface item { interface item {
name:string, name: string,
id:string, id: string,
description:string, description: string,
classhours:number, classhours: number,
totalchapter:number, totalchapter: number,
credit:number, credit: number,
totalKnow:number totalKnow: number
} }
interface CouresData { interface CouresData {
content: item[] content: item[]
@ -98,8 +94,8 @@ const Router = useRouter()
const currentPage: Page = reactive({ const currentPage: Page = reactive({
pageNo: 1, pageNo: 1,
pageSize: 5, pageSize: 5,
username:'xiao1111', username: 'xiao1111',
userId:3 userId: 3
}) })
const couresData: CouresData = reactive({ const couresData: CouresData = reactive({
content: [], content: [],
@ -107,21 +103,21 @@ const couresData: CouresData = reactive({
}) })
const btnTexst = ref<string>('加载更多') const btnTexst = ref<string>('加载更多')
const getCourseListEvent = async () => { const getCourseListEvent = async () => {
if( couresData.content.length && couresData.content.length === couresData.totalcount) { if (couresData.content.length && couresData.content.length === couresData.totalcount) {
btnTexst.value = '没有更多了' btnTexst.value = '没有更多了'
return return
} }
btnTexst.value = '正在加载' btnTexst.value = '正在加载'
const res: any = await getCourseList(currentPage) const res: any = await getCourseList(currentPage)
couresData.content = [... couresData.content,...res.data.list] couresData.content = [...couresData.content, ...res.data.list]
couresData.totalcount = res.data.total couresData.totalcount = res.data.total
btnTexst.value = '加载更多' btnTexst.value = '加载更多'
console.log( couresData) console.log(couresData)
} }
getCourseListEvent() getCourseListEvent()
const getMore = () => { const getMore = () => {
if(btnTexst.value === '正在加载' || btnTexst.value === '没有更多了') return if (btnTexst.value === '正在加载' || btnTexst.value === '没有更多了') return
currentPage.pageNo += 1 currentPage.pageNo += 1
getCourseListEvent() getCourseListEvent()
} }
@ -151,11 +147,11 @@ window.addEventListener('scroll', function () {
}) })
// //
const goToCourseInfo = (id:string | number):void => { const goToCourseInfo = (id: string | number, name: string): void => {
console.log(id); console.log(id);
Router.push({ Router.push({
path:'/course', path: '/course',
query:{id} query: { id, name }
}) })
} }
@ -163,15 +159,18 @@ const goToCourseInfo = (id:string | number):void => {
<style lang="scss" scoped> <style lang="scss" scoped>
.view-container { .view-container {
// height: 5000px; // height: 5000px;
// background-color: #2080f7; // background-color: #2080f7;
.main { .main {
margin-top: 50px; margin-top: 50px;
} }
.container { .container {
width: $base-container-width; width: $base-container-width;
margin: 0 auto; margin: 0 auto;
display: flex; display: flex;
.left-group { .left-group {
position: relative; position: relative;
width: 918px; width: 918px;
@ -179,6 +178,7 @@ const goToCourseInfo = (id:string | number):void => {
background-color: pink; background-color: pink;
background: url('../../assets/images/crous-card.png') no-repeat; background: url('../../assets/images/crous-card.png') no-repeat;
background-size: cover; background-size: cover;
.group { .group {
position: absolute; position: absolute;
top: 58px; top: 58px;
@ -189,6 +189,7 @@ const goToCourseInfo = (id:string | number):void => {
border-radius: 10px; border-radius: 10px;
overflow: hidden; overflow: hidden;
} }
.footer { .footer {
position: absolute; position: absolute;
bottom: 0; bottom: 0;
@ -196,11 +197,13 @@ const goToCourseInfo = (id:string | number):void => {
width: 100%; width: 100%;
height: 90px; height: 90px;
display: flex; display: flex;
.go-info { .go-info {
height: 100%; height: 100%;
width: 185px; width: 185px;
cursor: pointer; cursor: pointer;
} }
.left-title { .left-title {
flex: 1; flex: 1;
height: 100%; height: 100%;
@ -212,11 +215,13 @@ const goToCourseInfo = (id:string | number):void => {
} }
} }
} }
.right-info { .right-info {
flex: 1; flex: 1;
// background-color: skyblue; // background-color: skyblue;
margin-left: 20px; margin-left: 20px;
padding: 20px; padding: 20px;
.title { .title {
position: relative; position: relative;
height: 72px; height: 72px;
@ -226,6 +231,7 @@ const goToCourseInfo = (id:string | number):void => {
font-weight: 700; font-weight: 700;
margin-left: 30px; margin-left: 30px;
} }
.title::after { .title::after {
position: absolute; position: absolute;
top: 5px; top: 5px;
@ -236,21 +242,25 @@ const goToCourseInfo = (id:string | number):void => {
height: 40px; height: 40px;
background-color: #3374ff; background-color: #3374ff;
} }
.info { .info {
color: #888888; color: #888888;
font-size: 24px; font-size: 24px;
line-height: 35px; line-height: 35px;
height: 390px; height: 390px;
display: -webkit-box; display: -webkit-box;
-webkit-line-clamp: 11; /* 限制显示3行 */ -webkit-line-clamp: 11;
/* 限制显示3行 */
-webkit-box-orient: vertical; -webkit-box-orient: vertical;
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
} }
.crous-content { .crous-content {
width: 100%; width: 100%;
height: 100px; height: 100px;
margin-top: 60px; margin-top: 60px;
ul { ul {
width: 100%; width: 100%;
height: 100%; height: 100%;
@ -267,12 +277,14 @@ const goToCourseInfo = (id:string | number):void => {
} }
} }
} }
.get-more { .get-more {
width: 100%; width: 100%;
height: 200px; height: 200px;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
.btn { .btn {
width: 120px; width: 120px;
height: 40px; height: 40px;
@ -284,15 +296,18 @@ const goToCourseInfo = (id:string | number):void => {
cursor: pointer; cursor: pointer;
transition: all 0.3s; transition: all 0.3s;
} }
.btn:hover { .btn:hover {
transform: scale(1.1); transform: scale(1.1);
} }
} }
.banner { .banner {
width: 100%; width: 100%;
height: 410px; height: 410px;
background: url('../../assets/images/banner2.png') no-repeat; background: url('../../assets/images/banner2.png') no-repeat;
background-size: cover; background-size: cover;
.title { .title {
position: absolute; position: absolute;
top: 200px; top: 200px;

@ -1,12 +1,12 @@
<script setup lang="ts"> <script setup lang="ts">
import { onMounted, ref, watch } from 'vue'; import { onMounted, ref, watch } from 'vue';
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
import useLearnPathStore from '@/store/module/learnPath'; // import useLearnPathStore from '@/store/module/learnPath';
import { userGetInfoService, getCourseListApi } from '@/api/configuration'; import { userGetInfoService, getCourseListApi } from '@/api/configuration';
import useUserStore from '@/store/module/user'; import useUserStore from '@/store/module/user';
const userStore = useUserStore() const userStore = useUserStore()
const $router = useRouter() const $router = useRouter()
const learnPathStore = useLearnPathStore() // const learnPathStore = useLearnPathStore()
function paginationChange(currentPage: number, pageSize: number) { function paginationChange(currentPage: number, pageSize: number) {
params.value.pageNo = currentPage params.value.pageNo = currentPage
params.value.pageSize = pageSize params.value.pageSize = pageSize
@ -81,7 +81,7 @@ function toPath(item: any) {
} }
}) })
learnPathStore.setCourseData(item) // learnPathStore.setCourseData(item)
} }
</script> </script>

@ -3,17 +3,22 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { onMounted, ref } from 'vue' import { onMounted, ref, watch } from 'vue'
import { getCoursePath } from '@/api/course' import { getCoursePath } from '@/api/course'
import {useRouter} from 'vue-router' import { useRouter } from 'vue-router'
import { proxrequest } from '@/api/configuration';
const Router = useRouter() const Router = useRouter()
const nodeList = ref({nodes:[],edges:[]}) const props = defineProps(['corseId']);
const nodeList = ref({ nodes: [], edges: [] })
watch(() => props.corseId, () => getCoursePathEvent());
let prOpt: any;
const getCoursePathEvent = async () => { const getCoursePathEvent = async () => {
const res = await getCoursePath({ setTimeout(() => { prOpt = { text: '切换中', success: '切换成功', error: '切换失败' } });
corseId: '719f91586a64413898253c5b7d046fd8', const res = await proxrequest(getCoursePath, prOpt)({
corseId: props.corseId || '719f91586a64413898253c5b7d046fd8',
}) })
nodeList.value = { nodes: res.data.knowList, edges: res.data.linksList } nodeList.value = { nodes: res.data.knowList, edges: res.data.linksList }
nodeList.value.edges.forEach((item:any) => { nodeList.value.edges.forEach((item: any) => {
let target = item.target let target = item.target
let source = item.source let source = item.source
item.target = target.toString() item.target = target.toString()
@ -25,7 +30,7 @@ const getCoursePathEvent = async () => {
} }
}) })
nodeList.value.nodes.forEach((item:any) => { nodeList.value.nodes.forEach((item: any) => {
item.id = item.id.toString() item.id = item.id.toString()
}) })
console.log(nodeList.value) console.log(nodeList.value)
@ -383,16 +388,16 @@ const init = () => {
}, },
}) })
graph.data( nodeList.value) graph.data(nodeList.value)
graph.render() graph.render()
graph.on('node:click', ev => { graph.on('node:click', ev => {
console.log(ev.item._cfg.id); console.log(ev.item._cfg.id);
Router.push({ Router.push({
path:'/knowledge', path: '/knowledge',
query:{id:ev.item._cfg.id} query: { id: ev.item._cfg.id }
}) })
}); });
var edges = graph.getEdges() var edges = graph.getEdges()
edges.forEach(function (edge: any) { edges.forEach(function (edge: any) {
var line = edge.getKeyShape() var line = edge.getKeyShape()

@ -2,27 +2,17 @@
<div class="path-title"> <div class="path-title">
<div class="title">前端课程学习路径推荐</div> <div class="title">前端课程学习路径推荐</div>
<div class="setting"> <div class="setting">
<el-select <el-select v-model="courseName" placeholder="请选择课程" size="large" style="width: 200px">
v-model="courseName" <el-option v-for="item in options" :key="item.id" :label="item.label" :value="item.id" />
placeholder="请选择课程"
size="large"
style="width: 200px"
>
<el-option
v-for="item in options"
:key="item.id"
:label="item.label"
:value="item.id"
/>
</el-select> </el-select>
<el-button type="primary" style="margin-left: 20px">切换</el-button> <el-button type="primary" style="margin-left: 20px" @click="() => corseId = courseName">切换</el-button>
<el-button type="primary" style="margin-left: 20px" @click="goCourse"> <el-button type="primary" style="margin-left: 20px" @click="goCourse">
返回课程首页 返回课程首页
</el-button> </el-button>
</div> </div>
</div> </div>
<div class="path-container"> <div class="path-container">
<mountNode /> <mountNode :corseId="corseId" />
</div> </div>
<div class="statistics"> <div class="statistics">
<div class="title">学习路径</div> <div class="title">学习路径</div>
@ -33,22 +23,13 @@
<el-table-column prop="content" label="学习路径"> <el-table-column prop="content" label="学习路径">
<template v-slot="{ row }"> <template v-slot="{ row }">
<div> <div>
<el-tag <el-tag style="margin-right: 10px" type="primary" v-for="(item, index) in row.nodeList" :key="index">
style="margin-right: 10px"
type="primary"
v-for="(item, index) in row.nodeList"
:key="index"
>
{{ item }} {{ item }}
</el-tag> </el-tag>
</div> </div>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column <el-table-column prop="weight" label="数量" width="100px" />
prop="weight"
label="数量"
width="100px"
/>
<el-table-column prop="weight" label="学时" width="100px" /> <el-table-column prop="weight" label="学时" width="100px" />
</el-table> </el-table>
<div class="path-description"> <div class="path-description">
@ -59,39 +40,62 @@
<h1 style="text-align: center; font-size: 20px; font-weight: bolder"> <h1 style="text-align: center; font-size: 20px; font-weight: bolder">
相关信息 相关信息
</h1> </h1>
<div style="color: #ccc">{{ learnPathStore.courseData.name }}</div> <div style="color: #ccc">{{ learn.name }}</div>
<div style="font-size: 16px; line-height: 1.5"> <div style="font-size: 16px; line-height: 1.5">
{{ learnPathStore.courseData.description }} {{ learn.description }}
</div> </div>
</el-card> </el-card>
<el-card v-else style="margin-top: 20px"> <el-card v-else style="margin-top: 20px">
<h1 style="text-align: center; font-size: 20px; font-weight: bolder"> <h1 style="text-align: center; font-size: 20px; font-weight: bolder">
最新的课程 最新的课程
</h1> </h1>
<div style="color: #ccc"></div>
<div style="font-size: 16px; line-height: 1.5">
A Neo4j graph database stores nodes and relationships instead of tables or documents. Data is stored just like
you
might sketch ideas on a whiteboard. Your data is stored without restricting it to a pre-defined model, allowing
a
very
flexible way of thinking about and using it.
</div>
</el-card> </el-card>
</div> </div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import useLearnPathStore from '@/store/module/learnPath' // import useLearnPathStore from '@/store/module/learnPath'
import { ref } from 'vue' import { ref, reactive } from 'vue'
import { getknowLearnPath } from '@/api/course' import { getknowLearnPath } from '@/api/course'
import mountNode from './components/mountNode.vue' import mountNode from './components/mountNode.vue'
import { useRouter } from 'vue-router' import { useRoute, useRouter } from 'vue-router'
import { getCourseList } from '@/api/course'
import { getCourseDetailApi } from '@/api/configuration'
const Router = useRouter() const Router = useRouter()
const Route = useRoute()
const courseName = ref('') const courseName = ref('')
const learnPathStore = useLearnPathStore() // const learnPathStore = useLearnPathStore()
const options = ref<Record<'id' | 'label', string>[]>([]);
const currentPage = reactive({
pageNo: 1,
pageSize: 5,
username: 'xiao1111',
userId: 3
});
const learn = reactive<any>({})
if (Route.query.id) {
getCourseDetailApi(Route.query.id as string).then(res => Object.assign(learn, res.data));
}
(async function getNames() {
const res: any = await getCourseList(currentPage)
options.value = res.data.list?.map((o: Record<any, any>) => ({ id: o.id, label: o.name }))
})()
const options = [ const corseId = ref<string>('');
{
id: 1,
label: 'Vue.js',
},
]
const goCourse = () => { const goCourse = () => {
Router.push({ Router.push({
path: '/course', path: '/home',
query: { id: 'b7b169b7f9dd4ff2ae9639399206fda1' }, query: { id: 'b7b169b7f9dd4ff2ae9639399206fda1' },
}) })
} }

Loading…
Cancel
Save