significative 2 months ago
parent 85ba65f018
commit 171ae05698
  1. 4
      teaching_integration_platform_admin_template/.env.development
  2. 3
      teaching_integration_platform_template/.env.development
  3. 10
      teaching_integration_platform_template/src/api/configuration.ts
  4. 4
      teaching_integration_platform_template/src/store/module/user.ts
  5. 142
      teaching_integration_platform_template/src/views/course/index.vue
  6. 175
      teaching_integration_platform_template/src/views/home/index.vue
  7. 6
      teaching_integration_platform_template/src/views/professionalListProfile/index.vue
  8. 41
      teaching_integration_platform_template/src/views/roadbedRecommendation/components/mountNode.vue
  9. 80
      teaching_integration_platform_template/src/views/roadbedRecommendation/index.vue
  10. 64
      teaching_integration_platform_template/vite.config.ts.timestamp-1726102400305-7b45289bcf875.mjs

@ -1,5 +1,5 @@
# 变量必须以 VITE_ 为前缀才能暴露给外部读取
NODE_ENV = 'development'
VITE_APP_TITLE = '无糖运营平台'
# VITE_APP_BASE_API = 'http://127.0.0.1:8080'
VITE_APP_BASE_API = 'http://39.106.16.162:8080'
VITE_APP_BASE_API = 'http://127.0.0.1:8080'
# VITE_APP_BASE_API = 'http://39.106.16.162:8080'

@ -1,4 +1,5 @@
# 变量必须以 VITE_ 为前缀才能暴露给外部读取
NODE_ENV = 'development'
VITE_APP_TITLE = '教学一体化平台'
VITE_APP_BASE_API = 'http://39.106.16.162:8080'
VITE_APP_BASE_API = 'http://127.0.0.1:8080'
# VITE_APP_BASE_API = 'http://39.106.16.162:8080'

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

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

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

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

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

@ -3,29 +3,34 @@
</template>
<script lang="ts" setup>
import { onMounted, ref } from 'vue'
import { onMounted, ref, watch } from 'vue'
import { getCoursePath } from '@/api/course'
import {useRouter} from 'vue-router'
import { useRouter } from 'vue-router'
import { proxrequest } from '@/api/configuration';
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 res = await getCoursePath({
corseId: '719f91586a64413898253c5b7d046fd8',
setTimeout(() => { prOpt = { text: '切换中', success: '切换成功', error: '切换失败' } });
const res = await proxrequest(getCoursePath, prOpt)({
corseId: props.corseId || '719f91586a64413898253c5b7d046fd8',
})
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 source = item.source
item.target = target.toString()
item.source = source.toString()
item.data = {
type: '第一阶段',
amount: '10学时',
date: '学习基础知识',
amount: '10学时',
date: '学习基础知识',
}
})
nodeList.value.nodes.forEach((item:any) => {
nodeList.value.nodes.forEach((item: any) => {
item.id = item.id.toString()
})
console.log(nodeList.value)
@ -247,7 +252,7 @@ const init = () => {
G6.registerEdge('polyline', {
itemType: 'edge',
draw: function draw(cfg, group) {
var startPoint = cfg.startPoint
var endPoint = cfg.endPoint
var centerPoint = {
@ -275,7 +280,7 @@ const init = () => {
var controlPoint = {
x:
((line1EndPoint.x - startPoint.x) * (endPoint.y - startPoint.y)) /
(line1EndPoint.y - startPoint.y) +
(line1EndPoint.y - startPoint.y) +
startPoint.x,
y: endPoint.y,
}
@ -351,7 +356,7 @@ const init = () => {
return line
},
})
var graph = new G6.Graph({
container: 'mountNode',
width: window.innerWidth - 19,
@ -383,16 +388,16 @@ const init = () => {
},
})
graph.data( nodeList.value)
graph.data(nodeList.value)
graph.render()
graph.on('node:click', ev => {
console.log(ev.item._cfg.id);
Router.push({
path:'/knowledge',
query:{id:ev.item._cfg.id}
path: '/knowledge',
query: { id: ev.item._cfg.id }
})
});
});
var edges = graph.getEdges()
edges.forEach(function (edge: any) {
var line = edge.getKeyShape()

@ -2,27 +2,17 @@
<div class="path-title">
<div class="title">前端课程学习路径推荐</div>
<div class="setting">
<el-select
v-model="courseName"
placeholder="请选择课程"
size="large"
style="width: 200px"
>
<el-option
v-for="item in options"
:key="item.id"
:label="item.label"
:value="item.id"
/>
<el-select v-model="courseName" 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-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>
</div>
</div>
<div class="path-container">
<mountNode />
<mountNode :corseId="corseId" />
</div>
<div class="statistics">
<div class="title">学习路径</div>
@ -33,22 +23,13 @@
<el-table-column prop="content" label="学习路径">
<template v-slot="{ row }">
<div>
<el-tag
style="margin-right: 10px"
type="primary"
v-for="(item, index) in row.nodeList"
:key="index"
>
<el-tag style="margin-right: 10px" type="primary" v-for="(item, index) in row.nodeList" :key="index">
{{ item }}
</el-tag>
</div>
</template>
</el-table-column>
<el-table-column
prop="weight"
label="数量"
width="100px"
/>
<el-table-column prop="weight" label="数量" width="100px" />
<el-table-column prop="weight" label="学时" width="100px" />
</el-table>
<div class="path-description">
@ -59,39 +40,62 @@
<h1 style="text-align: center; font-size: 20px; font-weight: bolder">
相关信息
</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">
{{ learnPathStore.courseData.description }}
{{ learn.description }}
</div>
</el-card>
<el-card v-else style="margin-top: 20px">
<h1 style="text-align: center; font-size: 20px; font-weight: bolder">
最新的课程
</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>
</div>
</template>
<script lang="ts" setup>
import useLearnPathStore from '@/store/module/learnPath'
import { ref } from 'vue'
// import useLearnPathStore from '@/store/module/learnPath'
import { ref, reactive } from 'vue'
import { getknowLearnPath } from '@/api/course'
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 Route = useRoute()
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 = [
{
id: 1,
label: 'Vue.js',
},
]
const corseId = ref<string>('');
const goCourse = () => {
Router.push({
path: '/course',
path: '/home',
query: { id: 'b7b169b7f9dd4ff2ae9639399206fda1' },
})
}

Loading…
Cancel
Save