parent
a1b7adec84
commit
db752a36eb
6 changed files with 210 additions and 823 deletions
@ -1,727 +1,55 @@ |
||||
<script setup> |
||||
import { ref, onMounted } from 'vue' |
||||
import { ElMessage, ElMessageBox } from 'element-plus' |
||||
import { id } from 'element-plus/es/locales.mjs' |
||||
import * as echarts from 'echarts' |
||||
|
||||
// import { useRoute } from 'vue-router' |
||||
|
||||
import { |
||||
getCourseList, |
||||
addCourse, |
||||
editCourse, |
||||
deleteCourse, |
||||
getCourseInfo, |
||||
} from '@/api/courseChaptersApi' |
||||
import { useRoute, useRouter } from 'vue-router' |
||||
const route = useRoute() |
||||
const router = useRouter() |
||||
// id : 分目标id |
||||
// targetId : 选中的分类 |
||||
|
||||
const targetList = ref([ |
||||
{ |
||||
label: '课程目标一', |
||||
id: 1, |
||||
disabled: false, |
||||
}, |
||||
{ |
||||
label: '课程目标二', |
||||
disabled: false, |
||||
id: 2, |
||||
}, |
||||
{ |
||||
label: '课程目标三', |
||||
id: 3, |
||||
disabled: false, |
||||
}, |
||||
]) |
||||
const formData = ref({ |
||||
description: '', |
||||
}) |
||||
const activeIndex = ref(0) |
||||
// 新增 |
||||
const addPoint = (id) => { |
||||
console.log(id, 'id') |
||||
activeIndex.value = id |
||||
dialogVisible.value = true |
||||
flog.value = false |
||||
// updateDisabledStatus() |
||||
} |
||||
const text = ref('') |
||||
const textChange = (val) => { |
||||
console.log(text.value, 'text.value') |
||||
} |
||||
// 弹窗 |
||||
const dialogVisible = ref(false) |
||||
// 关闭弹窗 |
||||
const handleClose = () => { |
||||
dialogVisible.value = false |
||||
} |
||||
// 弹窗提交事件 |
||||
// const submit = async () => { |
||||
// if (flog.value) { |
||||
// await editCourse({ |
||||
// ...editdata.value, |
||||
// content: formData.value.description, |
||||
// }) |
||||
// } else { |
||||
// await addCourse({ |
||||
// objectiveId: activeIndex.value, |
||||
// content: formData.value.description, |
||||
// }) |
||||
// } |
||||
// getList() |
||||
// dialogVisible.value = false |
||||
// formData.value.description = '' |
||||
// activeIndex.value = '' |
||||
// } |
||||
const close = () => { |
||||
formData.value = { |
||||
id: null, |
||||
target: '', |
||||
description: '', |
||||
} |
||||
dialogVisible.value = false |
||||
} |
||||
// 筛选目标 |
||||
// const filterTarger = (target) => { |
||||
// const res = targetList.value.find((item) => { |
||||
// if (item.id === target) { |
||||
// console.log(item, 'item') |
||||
// return item |
||||
// } |
||||
// }) |
||||
// return res.label |
||||
// } |
||||
const editdata = ref({ id: '', objectiveId: '' }) |
||||
// 编辑事件 |
||||
const flog = ref(false) |
||||
const editBook = async (obj) => { |
||||
// 回显目标详情 |
||||
const res = await getCourseInfo({ id: obj.id }) |
||||
console.log(res, '回显res') |
||||
editdata.value.id = res.data.id |
||||
editdata.value.objectiveId = res.data.objectiveId |
||||
flog.value = true |
||||
// console.log(obj, '回显后obj') |
||||
activeIndex.value = res.data.id |
||||
formData.value.description = res.data.content |
||||
dialogVisible.value = true |
||||
} |
||||
// 弹窗提交事件 |
||||
const submit = async () => { |
||||
if (flog.value) { |
||||
await editCourse({ |
||||
...editdata.value, |
||||
content: formData.value.description, |
||||
}) |
||||
} else { |
||||
await addCourse({ |
||||
objectiveId: activeIndex.value, |
||||
content: formData.value.description, |
||||
}) |
||||
} |
||||
getList() |
||||
dialogVisible.value = false |
||||
formData.value.description = '' |
||||
activeIndex.value = '' |
||||
} |
||||
// 删除课程目标 |
||||
const del = async (obj) => { |
||||
await ElMessageBox.confirm('你确认要删除该课程目标吗', '温馨提示', { |
||||
type: 'warning', |
||||
confirmButtonText: '确认', |
||||
cancelButtonText: '取消', |
||||
}) |
||||
await deleteCourse({ id: obj.id }) |
||||
ElMessage.success('删除成功') |
||||
getList() |
||||
} |
||||
const data = ref({}) |
||||
const courseId = ref(0) |
||||
// 获取课程知识点列表 |
||||
const getList = async () => { |
||||
const res = await getCourseList({ id: courseId.value }) |
||||
console.log(res, 'res') |
||||
data.value = res.data[0] |
||||
console.log(data.value, 'data.value') |
||||
text.value = res.data[0].name |
||||
} |
||||
|
||||
onMounted(async () => { |
||||
if (!Object.keys(route.query).length) { |
||||
return router.push('/curriculumCenter/courseDetails') |
||||
|
||||
// return router.push('/curriculumCenter/basicCourseInformation') |
||||
} |
||||
courseId.value = route.query.id |
||||
console.log(courseId.value, 'courseid.vlue') |
||||
getList() |
||||
let chartDom = document.getElementById('main') |
||||
// myChart.resize({ |
||||
// width: 200, |
||||
// height: 100, |
||||
// }) |
||||
let myChart = echarts.init(chartDom) |
||||
let option |
||||
option = { |
||||
radar: [ |
||||
{ |
||||
nameGap: 10, |
||||
indicator: [ |
||||
{ |
||||
text: '目标一\n', |
||||
max: 100, |
||||
}, |
||||
{ |
||||
text: '目标五\n\n', |
||||
max: 100, |
||||
}, |
||||
{ |
||||
text: '目标四\n\n', |
||||
max: 100, |
||||
}, |
||||
{ |
||||
text: '目标三\n\n', |
||||
max: 100, |
||||
}, |
||||
{ |
||||
text: '目标二\n\n', |
||||
max: 100, |
||||
}, |
||||
], |
||||
// 中心位置 |
||||
center: ['50%', '60%'], |
||||
// 半径 |
||||
radius: 60, |
||||
// 圆角起始角度 |
||||
startAngle: 90, |
||||
// 分割数 |
||||
splitNumber: 5, |
||||
shape: 'circle', |
||||
name: { |
||||
formatter: '{value}', |
||||
textStyle: { |
||||
color: '#333333', |
||||
fontSize: 12, |
||||
}, |
||||
gap: 10, |
||||
}, |
||||
splitArea: { |
||||
areaStyle: { |
||||
color: [ |
||||
'transparent', |
||||
'transparent', |
||||
'rgba(114, 172, 209, 0)', |
||||
'transparent', |
||||
'rgba(114, 172, 209, 0)', |
||||
], |
||||
}, |
||||
}, |
||||
// 设置雷达图中间射线的颜色 |
||||
axisLine: { |
||||
lineStyle: { |
||||
color: '#C8D9FF', |
||||
}, |
||||
}, |
||||
splitLine: { |
||||
lineStyle: { |
||||
color: '#DADADA', |
||||
width: 2, |
||||
type: 'dashed', //dashed solid dotted 射线类型【实线 虚线】 |
||||
}, |
||||
}, |
||||
}, |
||||
{ |
||||
nameGap: 10, |
||||
indicator: [ |
||||
{ |
||||
text: '达成度', |
||||
max: 100, |
||||
}, |
||||
{ |
||||
text: '达成度', |
||||
max: 100, |
||||
}, |
||||
{ |
||||
text: '达成度', |
||||
max: 100, |
||||
}, |
||||
{ |
||||
text: '达成度', |
||||
max: 100, |
||||
}, |
||||
{ |
||||
text: '达成度', |
||||
max: 100, |
||||
}, |
||||
], |
||||
|
||||
center: ['50%', '60%'], |
||||
radius: 60, |
||||
startAngle: 90, |
||||
splitNumber: 1, |
||||
shape: 'circle', |
||||
splitArea: { |
||||
show: false, |
||||
}, |
||||
axisLine: { |
||||
show: false, |
||||
}, |
||||
name: { |
||||
formatter: '{value}', |
||||
textStyle: { |
||||
color: 'rgba(0,0,0,0.4)', |
||||
fontSize: 12, |
||||
}, |
||||
}, |
||||
splitLine: { |
||||
lineStyle: { |
||||
color: '#6093FF', |
||||
type: 'solid', |
||||
width: 8, |
||||
}, |
||||
}, |
||||
}, |
||||
], |
||||
series: [ |
||||
{ |
||||
type: 'radar', |
||||
emphasis: { |
||||
lineStyle: { |
||||
width: 20, |
||||
}, |
||||
}, |
||||
symbol: 'none', |
||||
data: [ |
||||
{ |
||||
value: [74, 60, 80, 60, 74], |
||||
name: 'Data C', |
||||
areaStyle: { |
||||
color: '#DBE4F9', |
||||
}, |
||||
}, |
||||
], |
||||
}, |
||||
{ |
||||
type: 'radar', |
||||
emphasis: { |
||||
lineStyle: { |
||||
width: 20, |
||||
}, |
||||
}, |
||||
symbol: 'none', |
||||
data: [ |
||||
{ |
||||
value: [74, 60, 80, 40, 74], |
||||
name: 'Data B', |
||||
areaStyle: { |
||||
color: '#0052FF', |
||||
}, |
||||
}, |
||||
], |
||||
}, |
||||
], |
||||
} |
||||
|
||||
option && myChart.setOption(option) |
||||
}) |
||||
<script setup lang="ts"> |
||||
// import { ref } from 'vue' |
||||
import courseBrief from './components/course-brief.vue' |
||||
import courseObject from './components/course-object.vue' |
||||
import courseChapters from './components/course-chapters.vue' |
||||
import KnowledgeGraph from './components/knowledge-graph.vue' |
||||
import knowledgestatistic from './components/knowledge-statistic.vue' |
||||
import chaptersdetails from './components/chapters-details.vue' |
||||
import resourcemanagement from './components/resource-management.vue' |
||||
// import knowledgegraph from './components/KnowledgeGraph.vue' |
||||
</script> |
||||
<template> |
||||
<div class="top"> |
||||
<div class="object"> |
||||
<!-- <h3>课程目标</h3> --> |
||||
<div class="left"> |
||||
<div class="total"> |
||||
<div class="title">| 课程总目标</div> |
||||
<div class="content1"> |
||||
<textarea class="textarea" @change="textChange" v-model="text"> |
||||
文本内容</textarea> |
||||
</div> |
||||
</div> |
||||
<div class="radar"> |
||||
<div class="title">| 课程目标雷达图</div> |
||||
<div id="main" class="radarmap"></div> |
||||
</div> |
||||
</div> |
||||
<div class="right"> |
||||
<div class="objectives"> |
||||
<div class="title">| 课程目标</div> |
||||
<div class="objectivebottom"> |
||||
<el-scrollbar height="270px"> |
||||
<ul class="objectLi"> |
||||
<li v-for="(item, index) in data.courseObjectivesTrees" :key="item.id"> |
||||
<div class="courseObject"> |
||||
<div class="courseObject1">{{ item.name }}</div> |
||||
<div class="courseObject2"> |
||||
<el-button type="primary" @click="addPoint(item.id)"> |
||||
新增 |
||||
</el-button> |
||||
</div> |
||||
</div> |
||||
<div class="smallContent"> |
||||
<el-scrollbar height="200px"> |
||||
<ul class="small"> |
||||
<li v-for="(obj, i) in item.contents" :key="obj.id"> |
||||
<div class="partObject"> |
||||
<div class="partObject1"> |
||||
<!-- {{ item.content }} --> |
||||
<!-- {{ item.introduce }} --> |
||||
课程目标{{ i + 1 }} |
||||
<!-- {{ filterTarger(obj.targetId) }} --> |
||||
</div> |
||||
<div class="partObject2"> |
||||
<el-button class="edit" type="text" @click="editBook(obj)"> |
||||
编辑 |
||||
</el-button> |
||||
<el-button class="destroy" type="text" @click="del(obj)"> |
||||
删除 |
||||
</el-button> |
||||
</div> |
||||
</div> |
||||
<div class="partObjectIntroduce"> |
||||
{{ obj.content }} |
||||
</div> |
||||
</li> |
||||
</ul> |
||||
</el-scrollbar> |
||||
</div> |
||||
</li> |
||||
</ul> |
||||
</el-scrollbar> |
||||
<el-dialog v-if="dialogVisible" v-model="dialogVisible" :title="flog ? '编辑' : '新增'" width="500" |
||||
:before-close="handleClose"> |
||||
<el-form :model="formData" label-width="auto" style="max-width: 600px"> |
||||
<el-form-item label="内容" prop="description"> |
||||
<el-input v-model="formData.description" placeholder="请输入内容"></el-input> |
||||
</el-form-item> |
||||
</el-form> |
||||
<template #footer> |
||||
<div class="dialog-footer"> |
||||
<el-button @click="close">取消</el-button> |
||||
<el-button type="primary" @click="submit">确定</el-button> |
||||
</div> |
||||
</template> |
||||
</el-dialog> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
<div class="point"> |
||||
<div class="map">知识图谱</div> |
||||
<div class="knowledge"> |
||||
<div class="percent"> |
||||
<span>知识点掌握百分比</span> |
||||
</div> |
||||
|
||||
<div class="core_knowledge"> |
||||
<SvgIcon class="svg-element" name="博士帽" width="40" height="40" /> |
||||
<span class="text">核心知识点</span> |
||||
<span class="number" style="color: #ffa400">69</span> |
||||
个 |
||||
</div> |
||||
<div class="error_knowledge"> |
||||
<SvgIcon class="svg-element" name="知识点" width="40" height="40" /> |
||||
<span class="text">易错知识点</span> |
||||
<span class="number" style="color: #5570fe">69</span> |
||||
个 |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
<div class="bottom"> |
||||
<div class="chapters"></div> |
||||
<div class="chaptersDetails"> |
||||
<div class="chaptersContent"></div> |
||||
<div class="resource"></div> |
||||
</div> |
||||
</div> |
||||
<el-row :gutter="20"> |
||||
<el-col :span="14"> |
||||
<course-brief></course-brief> |
||||
<courseObject></courseObject> |
||||
</el-col> |
||||
<el-col :span="10"> |
||||
<KnowledgeGraph></KnowledgeGraph> |
||||
<!-- <knowledgegraph></knowledgegraph> --> |
||||
<knowledgestatistic></knowledgestatistic> |
||||
</el-col> |
||||
</el-row> |
||||
<el-row :gutter="20"> |
||||
<el-col :span="10"> |
||||
<course-chapters></course-chapters> |
||||
</el-col> |
||||
<el-col :span="14"> |
||||
<chaptersdetails></chaptersdetails> |
||||
<resourcemanagement></resourcemanagement> |
||||
</el-col> |
||||
</el-row> |
||||
</template> |
||||
<style scoped lang="scss"> |
||||
.top { |
||||
display: flex; |
||||
justify-content: space-between; |
||||
// margin-top: 20px; |
||||
|
||||
.object { |
||||
display: flex; |
||||
justify-content: space-between; |
||||
width: 69%; |
||||
height: 400px; |
||||
// border: 1px solid black; |
||||
|
||||
// background-color: pink; |
||||
.total { |
||||
border-radius: 20px; |
||||
width: 360px; |
||||
height: 120px; |
||||
background-color: #74deff; |
||||
background-image: linear-gradient(to right, #4984ff, #74deff); |
||||
|
||||
.content1 { |
||||
border-radius: 20px; |
||||
margin-top: 10px; |
||||
width: 100%; |
||||
height: 100px; |
||||
background-color: #fff; |
||||
background-image: linear-gradient(#c7e3ff, #ffffff); |
||||
|
||||
.textarea { |
||||
width: 100%; |
||||
resize: none; |
||||
border: none; |
||||
background: transparent; |
||||
padding: 20px; |
||||
// height: 100px; |
||||
} |
||||
} |
||||
<style lang="scss" scoped> |
||||
.el-row { |
||||
// margin-bottom: 10px; |
||||
} |
||||
|
||||
.radar { |
||||
// float: left |
||||
border-radius: 20px; |
||||
width: 360px; |
||||
margin-top: 50px; |
||||
margin-right: 20px; |
||||
height: 130px; |
||||
background-color: #ffa674; |
||||
background-image: linear-gradient(to right, #f9e397, #ffa674); |
||||
.el-row:last-child { |
||||
margin-bottom: 0; |
||||
} |
||||
|
||||
.title { |
||||
padding-left: 30px; |
||||
font-size: 24px; |
||||
font-weight: 600; |
||||
color: #fff; |
||||
height: 40px; |
||||
line-height: 30px; |
||||
padding-top: 10px; |
||||
.el-col { |
||||
border-radius: 4px; |
||||
// margin-right: 10px; |
||||
} |
||||
|
||||
.radarmap { |
||||
border-radius: 20px; |
||||
margin-top: 10px; |
||||
// margin-right: 20px; |
||||
width: 100%; |
||||
height: 180px; |
||||
background-color: #fff; |
||||
background-image: linear-gradient(#ffe9c7, #ffffff); |
||||
} |
||||
|
||||
.objectives { |
||||
// margin-top: 20px; |
||||
margin-right: 20px; |
||||
// float: right; |
||||
border-radius: 20px; |
||||
width: 650px; |
||||
height: 230px; |
||||
// background-color: #4984FFFF |
||||
background-image: linear-gradient(to right, #4984ff, #74deff); |
||||
} |
||||
|
||||
.objectivebottom { |
||||
border-radius: 20px; |
||||
margin-top: 10px; |
||||
width: 100%; |
||||
height: 350px; |
||||
background-image: linear-gradient(#c7e3ff, #ffffff); |
||||
|
||||
.objectLi>li { |
||||
// width: 545px; |
||||
height: 250px; |
||||
// margin: 40px; |
||||
// background-color: #ffffff; |
||||
border-radius: 5px; |
||||
margin: 20px; |
||||
|
||||
.courseObject { |
||||
height: 45px; |
||||
line-height: 40px; |
||||
display: flex; |
||||
align-items: center; |
||||
justify-content: space-between; |
||||
padding: 0 20px; |
||||
border-bottom: 1px solid #e7e7e7; |
||||
|
||||
.courseObject1 { |
||||
height: 30px; |
||||
line-height: 30px; |
||||
font-size: 14px; |
||||
background-color: #6093ff; |
||||
padding: 0px 16px; |
||||
color: #fff; |
||||
} |
||||
|
||||
.courseObject2 { |
||||
font-size: 14px; |
||||
color: #0052d9; |
||||
} |
||||
} |
||||
} |
||||
|
||||
// overflow-y: auto |
||||
.smallContent { |
||||
// border-radius: 20px; |
||||
padding: 10px; |
||||
width: 100%; |
||||
height: 200px; |
||||
background-color: #fff; |
||||
background-image: linear-gradient(#c7e3ff, #ffffff); |
||||
} |
||||
|
||||
.small>li { |
||||
// display: inline-flex; |
||||
// width: 650px; |
||||
height: 150px; |
||||
// margin: 40px; |
||||
background-color: #ffffff; |
||||
border-radius: 5px; |
||||
margin: 20px; |
||||
|
||||
.partObject { |
||||
height: 45px; |
||||
line-height: 40px; |
||||
display: flex; |
||||
align-items: center; |
||||
justify-content: space-between; |
||||
padding: 0 20px; |
||||
border-bottom: 1px solid #e7e7e7; |
||||
|
||||
.partObject1 { |
||||
height: 30px; |
||||
line-height: 30px; |
||||
font-size: 14px; |
||||
background-color: #6093ff; |
||||
padding: 0px 16px; |
||||
color: #fff; |
||||
} |
||||
|
||||
.partObject2 { |
||||
font-size: 14px; |
||||
color: #0052d9; |
||||
} |
||||
} |
||||
|
||||
.partObjectIntroduce { |
||||
height: 149px; |
||||
font-size: 16px; |
||||
padding: 15px; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
h3 { |
||||
text-align: center; |
||||
font-size: 36px; |
||||
} |
||||
} |
||||
|
||||
.point { |
||||
width: 30%; |
||||
height: 400px; |
||||
// background-color: blue; |
||||
|
||||
.map { |
||||
width: 100%; |
||||
height: 260px; |
||||
background-color: pink; |
||||
} |
||||
|
||||
.knowledge { |
||||
display: flex; |
||||
justify-content: space-between; |
||||
// border: 1px solid black; |
||||
width: 100%; |
||||
height: 129px; |
||||
margin: 10px 0; |
||||
overflow: hidden; |
||||
|
||||
.percent { |
||||
margin-right: 13px; |
||||
width: 150px; |
||||
height: 129px; |
||||
background: #ffffff; |
||||
border-radius: 12px 12px 12px 12px; |
||||
box-shadow: 0px 3px 13px 0px rgba(225, 232, 246, 0.76); |
||||
|
||||
span { |
||||
display: block; |
||||
font-family: Inter, Inter; |
||||
font-weight: bold; |
||||
font-size: 14px; |
||||
color: #333333; |
||||
margin-top: 10px; |
||||
text-align: center; |
||||
} |
||||
} |
||||
|
||||
.core_knowledge { |
||||
width: 100px; |
||||
height: 129px; |
||||
text-align: center; |
||||
.grid-content { |
||||
border-radius: 6px; |
||||
margin-bottom: 20px; |
||||
background: #ffffff; |
||||
box-shadow: 0px 3px 13px 0px rgba(225, 232, 246, 0.76); |
||||
border-radius: 12px 12px 12px 12px; |
||||
} |
||||
|
||||
.svg-element { |
||||
margin-top: 10px; |
||||
} |
||||
|
||||
.error_knowledge { |
||||
width: 100px; |
||||
height: 129px; |
||||
text-align: center; |
||||
background: #ffffff; |
||||
box-shadow: 0px 3px 13px 0px rgba(225, 232, 246, 0.76); |
||||
border-radius: 12px 12px 12px 12px; |
||||
} |
||||
|
||||
.text { |
||||
display: block; |
||||
font-family: Inter, Inter; |
||||
font-weight: bold; |
||||
font-size: 14px; |
||||
color: #333333; |
||||
margin-top: 15px; |
||||
margin-bottom: 5px; |
||||
text-align: center; |
||||
} |
||||
|
||||
.number { |
||||
text-align: center; |
||||
font-family: Inter, Inter; |
||||
font-weight: bold; |
||||
font-size: 24px; |
||||
margin-left: 20px; |
||||
} |
||||
} |
||||
} |
||||
|
||||
.bottom { |
||||
margin-top: 20px; |
||||
display: flex; |
||||
justify-content: space-between; |
||||
|
||||
.chapters { |
||||
width: 40%; |
||||
height: 800px; |
||||
background-color: red; |
||||
} |
||||
|
||||
.chaptersDetails { |
||||
width: 59%; |
||||
height: 800px; |
||||
background-color: yellow; |
||||
|
||||
.chaptersContent { |
||||
width: 100%; |
||||
height: 25%; |
||||
background-color: purple; |
||||
} |
||||
} |
||||
box-shadow: 0px 1px 2px 0px rgba(0, 0, 0, 0.1); |
||||
} |
||||
</style> |
||||
|
Loading…
Reference in new issue