develoop
lijiaqi 4 months ago
parent a1b7adec84
commit db752a36eb
  1. 2
      src/api/user/crouse.js
  2. 2
      src/views/course/basicCourseInformation.vue
  3. 86
      src/views/course/components/KnowledgeGraphUi/FoldAdd.vue
  4. 110
      src/views/course/components/KnowledgeGraphUi/foldInfoUi.vue
  5. 33
      src/views/course/components/courseEdit.vue
  6. 756
      src/views/course/courseDetails.vue

@ -14,7 +14,7 @@ export const addCourseApi = (data) => {
return request.post(`/api/coursesteacher/addcourse`, data) return request.post(`/api/coursesteacher/addcourse`, data)
} }
// 获取课程详情 // 根据id获取课程详情
export const getCourseDetailApi = (id) => { export const getCourseDetailApi = (id) => {
return request.get(`/api/coursesteacher/${id}`) return request.get(`/api/coursesteacher/${id}`)
} }

@ -34,7 +34,7 @@ const params = ref({
pageNo: 1, pageNo: 1,
pageSize: 7, pageSize: 7,
// username: 'qiuqiu', // username: 'qiuqiu',
username: userStore.userName, userId: userStore.data.id,
assessmenttype: '', assessmenttype: '',
category: '', category: '',
nature: '', nature: '',

@ -32,19 +32,31 @@ import { ref, reactive, watch, computed, nextTick } from 'vue'
const props = defineProps(['isD', 'data']) const props = defineProps(['isD', 'data'])
const emits = defineEmits(['update:isD', 'submit']) const emits = defineEmits(['update:isD', 'submit'])
const loading = ref(false) const loading = ref(false)
const updLoading = (boo:boolean) => loading.value = boo const updLoading = (boo: boolean) => (loading.value = boo)
const isDrawer = ref(props.isD) const isDrawer = ref(props.isD)
watch(() => props.isD, newVal => isDrawer.value = newVal) watch(
watch(()=>isDrawer.value,newVal=>emits('update:isD',newVal)) () => props.isD,
(newVal) => (isDrawer.value = newVal),
)
watch(
() => isDrawer.value,
(newVal) => emits('update:isD', newVal),
)
const options1 = computed(() => { const options1 = computed(() => {
const arr = props.data.map((item: any, i: number) => { const arr = props.data.map((item: any, i: number) => {
const obj = { ...item } const obj = { ...item }
if (item.chapterSection) obj.chapterSection = item.chapterSection.map((chap: any) => ({ ...chap, disabled: true })) if (item.chapterSection)
obj.chapterSection = item.chapterSection.map((chap: any) => ({
...chap,
disabled: true,
}))
else obj.chapterSection = [] else obj.chapterSection = []
obj.chapterSection.push({ name: `${i + 1}章第${comNum(item.chapterSection?.length)}`, pid: item.id }) obj.chapterSection.push({
name: `${i + 1}章第${comNum(item.chapterSection?.length)}`,
pid: item.id,
})
return obj return obj
}) })
arr.push({ name: `${arr.length + 1}`, pid: '' }) arr.push({ name: `${arr.length + 1}`, pid: '' })
@ -53,10 +65,9 @@ const options1 = computed(() => {
const CascaderProps = { const CascaderProps = {
label: 'name', label: 'name',
value: 'pid', value: 'pid',
children: 'chapterSection' children: 'chapterSection',
} }
import type { ComponentSize, FormInstance, FormRules } from 'element-plus' import type { ComponentSize, FormInstance, FormRules } from 'element-plus'
interface RuleForm { interface RuleForm {
@ -84,25 +95,25 @@ interface RuleForm {
const formSize = ref<ComponentSize>('default') const formSize = ref<ComponentSize>('default')
const ruleFormRef = ref<FormInstance>() const ruleFormRef = ref<FormInstance>()
const ruleForm = reactive<RuleForm>({ const ruleForm = reactive<RuleForm>({
"content": "", content: '',
"courseid": "2fa0fd63262230639d2c45a3acd9045c", courseid: '2fa0fd63262230639d2c45a3acd9045c',
"courseobjectivesid": "", courseobjectivesid: '',
"createBy": "", createBy: '',
"createTime": "", createTime: '',
"id": "", id: '',
"name": "", name: '',
"num": 0, num: 0,
"numshow": "", numshow: '',
"onlinclasshours": "", onlinclasshours: '',
"pid": undefined, pid: undefined,
"requirement": "", requirement: '',
"sysOrgCode": "", sysOrgCode: '',
"totalclasshours": "", totalclasshours: '',
"updateBy": "", updateBy: '',
"updateTime": "", updateTime: '',
"zc": "", zc: '',
"ziyuan": "", ziyuan: '',
"zywj": "" zywj: '',
}) })
// @ts-ignore // @ts-ignore
const validateChapterOrSection = (rule, value, callback) => { const validateChapterOrSection = (rule, value, callback) => {
@ -111,12 +122,12 @@ const validateChapterOrSection = (rule, value, callback) => {
if (!value && value !== '') callback(new Error('请选择新增的章或节')) if (!value && value !== '') callback(new Error('请选择新增的章或节'))
else callback() else callback()
}) })
}; }
// //
const rules = reactive<FormRules<RuleForm>>({ const rules = reactive<FormRules<RuleForm>>({
pid: [ pid: [
{ required: true, validator: validateChapterOrSection, trigger: 'change' }, { required: true, validator: validateChapterOrSection, trigger: 'change' },
] ],
}) })
const submitForm = async (formEl: FormInstance | undefined) => { const submitForm = async (formEl: FormInstance | undefined) => {
@ -136,20 +147,25 @@ const resetForm = (formEl: FormInstance | undefined) => {
activePidArr.value = undefined activePidArr.value = undefined
} }
const placeholder = ref('请输入章节名') const placeholder = ref('请输入章节名')
watch(() => ruleForm.pid, newVal => { watch(
() => ruleForm.pid,
(newVal) => {
if (newVal === undefined) placeholder.value = '请输入章节名' if (newVal === undefined) placeholder.value = '请输入章节名'
else if (newVal === '') placeholder.value = '请输入章名' else if (newVal === '') placeholder.value = '请输入章名'
else placeholder.value = '请输入节名' else placeholder.value = '请输入节名'
}) },
)
const activePidArr = ref<string[] | undefined>([]) const activePidArr = ref<string[] | undefined>([])
watch(() => activePidArr.value, newVal => {// pid watch(
() => activePidArr.value,
(newVal) => {
// pid
if (newVal === undefined) { if (newVal === undefined) {
ruleForm.pid = undefined ruleForm.pid = undefined
return return
} }
ruleForm.pid = newVal.slice(-1)[0] ruleForm.pid = newVal.slice(-1)[0]
}) },
)
</script> </script>
<style lang="scss"></style> <style lang="scss"></style>

@ -2,47 +2,63 @@
<div class="fold-info-ui"> <div class="fold-info-ui">
<div class="demo-collapse"> <div class="demo-collapse">
<el-collapse class="collapse"> <el-collapse class="collapse">
<button class="my-button" style="position: absolute;left: 0;top: 0;" @click.stop="emits('add')">新增</button> <button class="my-button" style="position: absolute; left: 0; top: 0" @click.stop="emits('add')">
新增
</button>
<el-collapse-item v-for="item in foldInfoData" :key="item.id"> <el-collapse-item v-for="item in foldInfoData" :key="item.id">
<template #title> <template #title>
<div class="title"> <div class="title">
<div class="icon"> <div class="icon">
<img src="@/assets/images/minus-circle-filled.png" alt=""> <img src="@/assets/images/minus-circle-filled.png" alt="" />
</div>
<div class="index" v-if="String(item.numshow).length == 1">
0{{ item.numshow }} /
</div> </div>
<div class="index" v-if="String(item.numshow).length == 1"> 0{{ item.numshow }} /</div>
<div class="index" v-else>{{ item.numshow }} /</div> <div class="index" v-else>{{ item.numshow }} /</div>
<div class="text">{{ item.name }}</div> <div class="text">{{ item.name }}</div>
<div class="title-tag-box"> <div class="title-tag-box">
<div class="my-tag" type="warning">{{ item.totalclasshours }}学时</div> <div class="my-tag" type="warning">
{{ item.totalclasshours }}学时
</div>
<div class="my-tag">本章资源</div> <div class="my-tag">本章资源</div>
</div> </div>
<button class="my-button" @click.stop="emits('edit', item)" style="margin-right: 10px;">编辑</button> <button class="my-button" @click.stop="emits('edit', item)" style="margin-right: 10px">
<my-btn :id="item.id" type="danger" class="is-el-button" style="margin-right: 10px;">删除</my-btn> 编辑
</button>
<my-btn :id="item.id" type="danger" class="is-el-button" style="margin-right: 10px">
删除
</my-btn>
</div> </div>
</template> </template>
<template #default> <template #default>
<div class="titile-box-knowledge chapter-knowledge"> <div class="titile-box-knowledge chapter-knowledge">
<div class="my-tag">知识点1</div> <div class="my-tag">知识点1</div>
<div class="my-tag">知识点1</div> <div class="my-tag">知识点1</div>
</div> </div>
<div class="main-box"> <div class="main-box">
<div class="left"></div> <div class="left"></div>
<div class="right"> <div class="right">
<div class="structure-item"> <div class="structure-item">
<div class="structure-item-titile-box" v-for="obj, ind in item.chapterSection" :key="item.id"> <div class="structure-item-titile-box" v-for="(obj, ind) in item.chapterSection" :key="item.id">
<div class="titile-box-titile"> <div class="titile-box-titile">
<div class="sequence">{{ ind + 1 }}</div> <div class="sequence">{{ ind + 1 }}</div>
<div class="tit-box"> <div class="tit-box">
<div class="tit-box-left">{{ obj.numshow }} {{ obj.name }}</div> <div class="tit-box-left">
{{ obj.numshow }} {{ obj.name }}
</div>
<div class="tit-box-right my-tag">资源</div> <div class="tit-box-right my-tag">资源</div>
<div class="title-tag-box"> <div class="title-tag-box">
<div class="my-tag" type="warning">{{ obj.totalclasshours }}学时</div> <div class="my-tag" type="warning">
{{ obj.totalclasshours }}学时
</div>
</div> </div>
<div class="tit-box-edit"> <div class="tit-box-edit">
<button class="my-button" @click.stop="emits('edit', obj)" <button class="my-button" @click.stop="emits('edit', obj)" style="margin-right: 10px">
style="margin-right: 10px;">编辑</button> 编辑
<my-btn :id="obj.id" type="danger" class="is-el-button" style="margin-right: 10px;">删除</my-btn> </button>
<my-btn :id="obj.id" type="danger" class="is-el-button" style="margin-right: 10px">
删除
</my-btn>
</div> </div>
</div> </div>
</div> </div>
@ -55,7 +71,6 @@
</div> </div>
</div> </div>
</template> </template>
</el-collapse-item> </el-collapse-item>
</el-collapse> </el-collapse>
</div> </div>
@ -63,7 +78,7 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ElButton } from 'element-plus'; import { ElButton } from 'element-plus'
import { ref, h, type SetupContext, withModifiers } from 'vue' import { ref, h, type SetupContext, withModifiers } from 'vue'
defineProps(['foldInfoData']) defineProps(['foldInfoData'])
const emits = defineEmits(['add', 'del', 'edit']) const emits = defineEmits(['add', 'del', 'edit'])
@ -72,19 +87,26 @@ const MyBtn = {
props: ['id'], props: ['id'],
setup(props: { id: string }, context: SetupContext) { setup(props: { id: string }, context: SetupContext) {
const loading = ref(false) const loading = ref(false)
const setLoading = (bool: boolean) => loading.value = bool const setLoading = (bool: boolean) => (loading.value = bool)
return ()=> h(ElButton, { return () =>
h(
ElButton,
{
loading: loading.value, loading: loading.value,
onClick: withModifiers(function () { onClick: withModifiers(
function () {
emits('del', props.id, setLoading) emits('del', props.id, setLoading)
}, ['stop']), },
['stop'],
),
...context.attrs, ...context.attrs,
}, context.slots) },
} context.slots,
)
},
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
::v-deep .collapse { ::v-deep .collapse {
border-top: none; border-top: none;
@ -102,13 +124,11 @@ const MyBtn = {
background: #fff; background: #fff;
position: relative; position: relative;
.demo-collapse { .demo-collapse {
$title-icon-width: 15px; $title-icon-width: 15px;
$title--icon-m-r: 34px; $title--icon-m-r: 34px;
$title-index-width: 60px; $title-index-width: 60px;
.title { .title {
display: flex; display: flex;
height: 22px; height: 22px;
@ -124,7 +144,6 @@ const MyBtn = {
& img { & img {
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
} }
@ -150,14 +169,12 @@ const MyBtn = {
display: flex; display: flex;
column-gap: 16px; column-gap: 16px;
} }
} }
.main-box { .main-box {
width: 100%; width: 100%;
display: flex; display: flex;
$line: 1px dashed #D9D9D9; $line: 1px dashed #d9d9d9;
.left { .left {
width: calc($title-icon-width + $title--icon-m-r + $title-index-width / 2); width: calc($title-icon-width + $title--icon-m-r + $title-index-width / 2);
@ -202,7 +219,7 @@ const MyBtn = {
top: 50%; top: 50%;
transform: translate(-50%, -50%); transform: translate(-50%, -50%);
border-radius: 50%; border-radius: 50%;
background: #FFB21E; background: #ffb21e;
text-align: center; text-align: center;
line-height: $height; line-height: $height;
font-weight: 400; font-weight: 400;
@ -229,9 +246,7 @@ const MyBtn = {
} }
} }
} }
} }
} }
} }
} }
@ -244,10 +259,10 @@ const MyBtn = {
flex-wrap: wrap; flex-wrap: wrap;
&>* { &>* {
border: 1px solid #0052D9; border: 1px solid #0052d9;
font-weight: bold; font-weight: bold;
font-size: 12px; font-size: 12px;
color: #0052D9; color: #0052d9;
} }
} }
@ -261,9 +276,9 @@ const MyBtn = {
padding: 2px 8px; padding: 2px 8px;
font-weight: 400; font-weight: 400;
font-size: 12px; font-size: 12px;
color: #0052D9; color: #0052d9;
line-height: 20px; line-height: 20px;
background: #F2F3FF; background: #f2f3ff;
cursor: pointer; cursor: pointer;
border-radius: 3px; border-radius: 3px;
} }
@ -272,17 +287,16 @@ const MyBtn = {
white-space: nowrap; white-space: nowrap;
} }
[type=warning].my-tag { [type='warning'].my-tag {
color: #E37318; color: #e37318;
background: #FFF1E9; background: #fff1e9;
} }
} }
.my-button { .my-button {
all: initial; all: initial;
$color-start: #52A1FF; $color-start: #52a1ff;
$color-end: #4255FF; $color-end: #4255ff;
padding: 8px 24px; padding: 8px 24px;
background: linear-gradient(128deg, $color-start 0%, $color-end 100%); background: linear-gradient(128deg, $color-start 0%, $color-end 100%);
box-shadow: 0px 4px 7px 0px rgba(0, 82, 255, 0.27); box-shadow: 0px 4px 7px 0px rgba(0, 82, 255, 0.27);
@ -295,15 +309,21 @@ const MyBtn = {
cursor: pointer; cursor: pointer;
&:hover { &:hover {
background: linear-gradient(128deg, lighten($color-start, 5%) 0%, lighten($color-end, 5%) 100%); background: linear-gradient(128deg,
lighten($color-start, 5%) 0%,
lighten($color-end, 5%) 100%);
} }
&:active { &:active {
background: linear-gradient(128deg, darken($color-start, 10%) 0%, darken($color-end, 10%) 100%); background: linear-gradient(128deg,
darken($color-start, 10%) 0%,
darken($color-end, 10%) 100%);
} }
&:disabled { &:disabled {
background: linear-gradient(128deg, lighten($color-start, 20%) 0%, lighten($color-end, 20%) 100%); background: linear-gradient(128deg,
lighten($color-start, 20%) 0%,
lighten($color-end, 20%) 100%);
} }
} }
@ -318,7 +338,5 @@ const MyBtn = {
line-height: 24px; line-height: 24px;
text-align: center; text-align: center;
cursor: pointer; cursor: pointer;
} }
</style> </style>

@ -1,12 +1,13 @@
<script setup lang="ts"> <script setup lang="ts">
import { ElMessage } from 'element-plus' import { ElMessage } from 'element-plus'
import { requiredNumber } from 'element-plus/es/components/table-v2/src/common.mjs' import request from '@/utils/request'
// import { requiredNumber } from 'element-plus/es/components/table-v2/src/common.mjs'
import { ref, watch, onMounted } from 'vue' import { ref, watch, onMounted } from 'vue'
import { editCourseApi } from '../../../api/user/crouse' import { editCourseApi } from '../../../api/user/crouse'
import { addCourseApi } from '../../../api/user/crouse' import { addCourseApi } from '../../../api/user/crouse'
import { getCourseListApi, getCourseDetailApi } from '../../../api/user/crouse' import { getCourseListApi, getCourseDetailApi } from '../../../api/user/crouse'
import request from '../../../utils/request' // import request from '../../../utils/request'
import { tool, client } from '../../../utils/alioss.js' import { tool } from '../../../utils/alioss.js'
import useUserStore from '@/store/modules/user' import useUserStore from '@/store/modules/user'
// import { useRoute } from 'vue-router' // import { useRoute } from 'vue-router'
const userStore = useUserStore() const userStore = useUserStore()
@ -24,7 +25,7 @@ const formRef = ref()
// } // }
// const beforeAvatarUpload = (file: any) => {} // const beforeAvatarUpload = (file: any) => {}
const defaultForm = { const defaultForm = {
teacher: userStore.userName, teacher: userStore.data.id,
img: '', img: '',
name: '', name: '',
category: ref(''), category: ref(''),
@ -89,6 +90,11 @@ const rules = {
trigger: 'blur', trigger: 'blur',
}, },
{ max: 10, message: '不能超过10个字符', trigger: 'blur' }, { max: 10, message: '不能超过10个字符', trigger: 'blur' },
// {
// validator: validateUniqueCode,
// message: '',
// trigger: 'blur',
// },
], ],
credit: [ credit: [
{ {
@ -122,6 +128,25 @@ const rules = {
}, },
], ],
} }
//
// const validateUniqueCode = async (rule, value, callback) => {
// if (!value) {
// return callback() //
// }
// try {
// const response = await request(`/api/checkCourseCode?code=${value}`) //
// const data = await response.json()
// if (data.exists) {
// callback(new Error('使')) //
// } else {
// callback() //
// }
// } catch (error) {
// console.error(':', error)
// callback(new Error(''))
// }
// }
// //
// const onSelectFile = (uploadFile) => { // const onSelectFile = (uploadFile) => {

@ -1,727 +1,55 @@
<script setup> <script setup lang="ts">
import { ref, onMounted } from 'vue' // import { ref } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus' import courseBrief from './components/course-brief.vue'
import { id } from 'element-plus/es/locales.mjs' import courseObject from './components/course-object.vue'
import * as echarts from 'echarts' import courseChapters from './components/course-chapters.vue'
import KnowledgeGraph from './components/knowledge-graph.vue'
// import { useRoute } from 'vue-router' import knowledgestatistic from './components/knowledge-statistic.vue'
import chaptersdetails from './components/chapters-details.vue'
import { import resourcemanagement from './components/resource-management.vue'
getCourseList, // import knowledgegraph from './components/KnowledgeGraph.vue'
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> </script>
<template> <template>
<div class="top"> <el-row :gutter="20">
<div class="object"> <el-col :span="14">
<!-- <h3>课程目标</h3> --> <course-brief></course-brief>
<div class="left"> <courseObject></courseObject>
<div class="total"> </el-col>
<div class="title">| 课程总目标</div> <el-col :span="10">
<div class="content1"> <KnowledgeGraph></KnowledgeGraph>
<textarea class="textarea" @change="textChange" v-model="text"> <!-- <knowledgegraph></knowledgegraph> -->
文本内容</textarea> <knowledgestatistic></knowledgestatistic>
</div> </el-col>
</div> </el-row>
<div class="radar"> <el-row :gutter="20">
<div class="title">| 课程目标雷达图</div> <el-col :span="10">
<div id="main" class="radarmap"></div> <course-chapters></course-chapters>
</div> </el-col>
</div> <el-col :span="14">
<div class="right"> <chaptersdetails></chaptersdetails>
<div class="objectives"> <resourcemanagement></resourcemanagement>
<div class="title">| 课程目标</div> </el-col>
<div class="objectivebottom"> </el-row>
<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>
</template> </template>
<style scoped lang="scss">
.top {
display: flex;
justify-content: space-between;
// margin-top: 20px;
.object { <style lang="scss" scoped>
display: flex; .el-row {
justify-content: space-between; // margin-bottom: 10px;
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;
}
}
} }
.radar { .el-row:last-child {
// float: left margin-bottom: 0;
border-radius: 20px;
width: 360px;
margin-top: 50px;
margin-right: 20px;
height: 130px;
background-color: #ffa674;
background-image: linear-gradient(to right, #f9e397, #ffa674);
} }
.title { .el-col {
padding-left: 30px; border-radius: 4px;
font-size: 24px; // margin-right: 10px;
font-weight: 600;
color: #fff;
height: 40px;
line-height: 30px;
padding-top: 10px;
} }
.radarmap { .grid-content {
border-radius: 20px; border-radius: 6px;
margin-top: 10px; margin-bottom: 20px;
// 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;
background: #ffffff; background: #ffffff;
box-shadow: 0px 3px 13px 0px rgba(225, 232, 246, 0.76); box-shadow: 0px 1px 2px 0px rgba(0, 0, 0, 0.1);
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;
}
}
} }
</style> </style>

Loading…
Cancel
Save