develoop
ww 4 months ago
commit c85e9ee528
  1. 7175
      pnpm-lock.yaml
  2. 5
      src/api/courseChaptersApi.ts
  3. 238
      src/api/sectionApi.ts
  4. 11
      src/api/user/chapter.js
  5. 2
      src/api/user/crouse.js
  6. 1
      src/assets/icons/博士帽.svg
  7. 22
      src/router/routers.ts
  8. 104
      src/store/modules/user.ts
  9. 44
      src/utils/request.ts
  10. 48
      src/views/course/CourseObjectives.vue
  11. 59
      src/views/course/CourseObjectives111.vue
  12. 111
      src/views/course/basicCourseInformation.vue
  13. 125
      src/views/course/components/KnowledgeGraphUi/FoldAdd.vue
  14. 44
      src/views/course/components/KnowledgeGraphUi/foldInfoUi.vue
  15. 35
      src/views/course/components/chapters-details.vue
  16. 191
      src/views/course/components/course-brief.vue
  17. 171
      src/views/course/components/course-chapters.vue
  18. 433
      src/views/course/components/course-object.vue
  19. 135
      src/views/course/components/courseEdit.vue
  20. 172
      src/views/course/components/knowledge-graph.vue
  21. 142
      src/views/course/components/knowledge-statistic.vue
  22. 89
      src/views/course/components/resource-management.vue
  23. 179
      src/views/course/courseChapters.vue
  24. 55
      src/views/course/courseDetails.vue
  25. 0
      vite.config.ts.timestamp-1718962043727-a5f9abeb4a0c.mjs

File diff suppressed because it is too large Load Diff

@ -96,6 +96,7 @@ export const deleteCourse = (params: any) => {
// 获取详情
export const getCourseInfo = (params: any) => {
return request({
<<<<<<< HEAD
// <<<<<<< HEAD
url: '/objective_contents/' + params.id,
method: 'get',
@ -111,5 +112,9 @@ export const getCourseInfo = (params: any) => {
// // params
// >>>>>>> 1a620e19de970965f426e07348b1dbc4be900eaf
// >>>>>>> 991fa5ab08c56c84c5a276226f8fbc2ec78f859a
=======
url: '/api/objective_contents/' + params.id,
// method: 'get',
>>>>>>> 0b7db324dad8347654933e91ae7e6ca8d2dabd05
})
}

@ -1,151 +1,151 @@
import request from '@/utils/request'
/**
/**
* linkedlist
* @param {string} courseid courseid
* @returns
* 2fa0fd63262230639d2c45a3acd9045c
*/
export function getChapterApi(courseid: string) {
return request.get(`/chapter/aaa/${courseid}`);
return request.get(`/chapter/aaa/${courseid}`)
}
// 响应接口
export interface DeleteRes {
code: number;
data: boolean;
message: string;
code: number
data: boolean
message: string
}
/**
/**
*
* @param {string} id id
* @returns
* @returns
*/
export function deleteSectionApi(id: string): Promise<DeleteRes> {
return request.delete(`/chapter/${id}`);
return request.delete(`/chapter/${id}`)
}
// 响应接口
export interface GetByIdCourseVoRes {
code: number;
data: {
classhours: number;
credit: number;
description: string;
id: string;
img: string;
name: string;
objectContent: string;
teacher: string;
totalAssignHours: number;
totalHours: number;
totalKnow: number;
totalNotAssignHours: number;
totalchapter: number;
};
message: string;
}
/**
* id查询课程Vo版
* @param {string} id id
* @returns
*/
export function getByIdCourseVoApi(id: string): Promise<GetByIdCourseVoRes> {
return request.get(`/api/coursesteacher/getById/${id}`);
code: number
data: {
classhours: number
credit: number
description: string
id: string
img: string
name: string
objectContent: string
teacher: string
totalAssignHours: number
totalHours: number
totalKnow: number
totalNotAssignHours: number
totalchapter: number
}
message: string
}
/**
* id查询课程Vo版
* @param {string} id id
* @returns
*/
export function getByIdCourseVoApi(id: string): Promise<GetByIdCourseVoRes> {
return request.get(`/api/coursesteacher/getById/${id}`)
}
// 参数接口
// 参数接口
export interface AddChapterParams {
content?: string;
courseid?: string;
courseobjectivesid?: string;
createBy?: string;
createTime?: Record<string, unknown>;
id?: string;
name?: string;
num?: number;
numshow?: string;
onlinclasshours?: string;
pid?: string;
requirement?: string;
sysOrgCode?: string;
totalclasshours?: string;
updateBy?: string;
updateTime?: Record<string, unknown>;
zc?: string;
ziyuan?: string;
zywj?: string;
}
// 响应接口
export interface AddChapterRes {
code: number;
data: boolean;
message: string;
}
/**
*
* @param {object} params chapter
* @param {string} params.content
* @param {string} params.courseid
* @param {string} params.courseobjectivesid
* @param {string} params.createBy
* @param {object} params.createTime
* @param {string} params.id
* @param {string} params.name
* @param {number} params.num
* @param {string} params.numshow
* @param {string} params.onlinclasshours 线
* @param {string} params.pid
* @param {string} params.requirement
* @param {string} params.sysOrgCode
* @param {string} params.totalclasshours
* @param {string} params.updateBy
* @param {object} params.updateTime
* @param {string} params.zc
* @param {string} params.ziyuan
* @param {string} params.zywj
* @returns
*/
export function addChapterApi(params: AddChapterParams): Promise<AddChapterRes> {
return request.post(`/chapter/add`, params);
}
content?: string
courseid?: string
courseobjectivesid?: string
createBy?: string
createTime?: Record<string, unknown>
id?: string
name?: string
num?: number
numshow?: string
onlinclasshours?: string
pid?: string
requirement?: string
sysOrgCode?: string
totalclasshours?: string
updateBy?: string
updateTime?: Record<string, unknown>
zc?: string
ziyuan?: string
zywj?: string
}
// 响应接口
export interface AddChapterRes {
code: number
data: boolean
message: string
}
/**
*
* @param {object} params chapter
* @param {string} params.content
* @param {string} params.courseid
* @param {string} params.courseobjectivesid
* @param {string} params.createBy
* @param {object} params.createTime
* @param {string} params.id
* @param {string} params.name
* @param {number} params.num
* @param {string} params.numshow
* @param {string} params.onlinclasshours 线
* @param {string} params.pid
* @param {string} params.requirement
* @param {string} params.sysOrgCode
* @param {string} params.totalclasshours
* @param {string} params.updateBy
* @param {object} params.updateTime
* @param {string} params.zc
* @param {string} params.ziyuan
* @param {string} params.zywj
* @returns
*/
export function addChapterApi(
params: AddChapterParams,
): Promise<AddChapterRes> {
return request.post(`/chapter/add`, params)
}
// 参数接口
// 参数接口
export interface UpdateChapterParams {
content?: string;
courseid?: string;
courseobjectivesid?: string;
createBy?: string;
createTime?: Record<string, unknown>;
id?: string;
name?: string;
num?: number;
numshow?: string;
onlinclasshours?: string;
pid?: string;
requirement?: string;
sysOrgCode?: string;
totalclasshours?: string;
updateBy?: string;
updateTime?: Record<string, unknown>;
zc?: string;
ziyuan?: string;
zywj?: string;
content?: string
courseid?: string
courseobjectivesid?: string
createBy?: string
createTime?: Record<string, unknown>
id?: string
name?: string
num?: number
numshow?: string
onlinclasshours?: string
pid?: string
requirement?: string
sysOrgCode?: string
totalclasshours?: string
updateBy?: string
updateTime?: Record<string, unknown>
zc?: string
ziyuan?: string
zywj?: string
}
// 响应接口
export interface UpdateChapterRes {
code: number;
data: boolean;
message: string;
code: number
data: boolean
message: string
}
/**
/**
*
* @param {object} params chapter
* @param {string} params.content
@ -169,6 +169,8 @@ export interface UpdateChapterRes {
* @param {string} params.zywj
* @returns
*/
export function updateChapterApi(params: UpdateChapterParams): Promise<UpdateChapterRes> {
return request.put(`/chapter`, params);
}
export function updateChapterApi(
params: UpdateChapterParams,
): Promise<UpdateChapterRes> {
return request.put(`/chapter`, params)
}

@ -0,0 +1,11 @@
import request from '@/utils/request'
// 获取课程章节列表
export const getChaptersListApi = (params) => {
return request.get(`/chapter2/chapter?courseId=${params.id}`)
}
// 添加课程章节
export const addChaptersApi = (params) => request.post('/chapter2/add', params)
// 删除课程章节
export const delChapterstApi = (id) => {
return request.delete(`/chapter2/delete/${id}`)
}

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

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1716622721837" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2719" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><path d="M865.92 420.48h50.346667v161.28h-50.346667z" fill="#FF354A" p-id="2720"></path><path d="M876.16 627.84l-32.853333-32.853333a21.248 21.248 0 0 1 0-30.08l32.853333-32.853334a21.248 21.248 0 0 1 30.08 0l32.853333 32.853334c8.32 8.32 8.32 21.76 0 30.08l-32.853333 32.853333a21.248 21.248 0 0 1-30.08 0z" fill="#FF354A" p-id="2721"></path><path d="M744.96 809.173333l-83.2 37.76a377.898667 377.898667 0 0 1-312.96 0l-83.2-37.76a64.021333 64.021333 0 0 1-37.546667-58.24V363.52h554.453334v387.2c0 25.173333-14.72 48-37.546667 58.453333z" fill="#FCCA1E" p-id="2722"></path><path d="M895.36 440.32l-331.306667 165.333333c-37.12 18.56-80.64 18.56-117.546666 0L114.986667 440.32c-48.64-24.32-48.64-93.653333 0-117.973333l331.306666-165.333334c37.12-18.56 80.64-18.56 117.546667 0l331.306667 165.333334c48.853333 24.32 48.853333 93.653333 0.213333 117.973333z" fill="#2953FF" p-id="2723"></path></svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

@ -43,17 +43,6 @@ export const constantRoute: any = [
icon: 'HomeFilled', // 菜单图标
},
children: [
// {
// path: '/curriculumCenter/course',
// redirect: '/curriculumCenter/basicCourseInformation',
// component: () => import('@/views/course/index.vue'),
// name: 'Course',
// meta: {
// title: '课程',
// hidden: false,
// icon: 'Notebook',
// },
// },
{
path: '/curriculumCenter/basicCourseInformation',
component: () => import('@/views/course/basicCourseInformation.vue'),
@ -64,6 +53,16 @@ export const constantRoute: any = [
icon: 'Notebook',
},
},
{
path: '/curriculumCenter/courseDetails',
component: () => import('@/views/course/courseDetails.vue'),
name: 'CourseDetails',
meta: {
title: '课程详情',
hidden: false,
icon: 'Notebook',
},
},
{
path: '/curriculumCenter/CourseObjectives',
component: () => import('@/views/course/CourseObjectives.vue'),
@ -172,6 +171,7 @@ export const constantRoute: any = [
},
],
},
{
path: '/myCourseStudyManagement',
component: () => import('@/layout/index.vue'),

@ -74,6 +74,7 @@ const useUserStore = defineStore('User', {
message: '登录成功!',
title: `Hi ${getTime()}!`,
})
<<<<<<< HEAD
return 'ok'
} else {
ElNotification({
@ -119,6 +120,109 @@ const useUserStore = defineStore('User', {
this.routes = ''
usePermissionStore.removeRouter()
location.reload()
=======
if (res.code === 200) {
// @ts-expect-error
this.token = res.data.token as string
// @ts-expect-error
SET_TKOEN('TOKEN', this.token)
// localStorage.setItem('TOKEN', this.token)
ElNotification({
type: 'success',
message: '登录成功!',
title: `Hi ${getTime()}!`,
})
return 'ok'
} else {
// ElNotification({
// // type: 'error',
// message: res.message,
// })
ElMessage.error(res.message)
return Promise.reject(new Error(res.data.message))
}
},
//手机号登录
async userPhoneLogin(data: loginType) {
const res: any = await userPhoneLoginService(data)
console.log(res, 11111)
if (res.code === 200) {
// @ts-expect-error
this.token = res.data.token as string //接收返回的token
// @ts-expect-error
SET_TKOEN('TOKEN', this.token)
// localStorage.setItem('TOKEN', this.token)
ElNotification({
type: 'success',
message: '登录成功!',
title: `Hi ${getTime()}!`,
})
return 'ok'
} else {
ElNotification({
type: 'error',
message: res.message,
})
return Promise.reject(new Error(res.data.message))
}
},
// 获取用户信息事件
async getUserInfo() {
const result: any = await userGetInfoService(GET_TKOEN('TOKEN'))
if (result.code === 200) {
const res = await userIdenService(result.data.id)
console.log(res, 'huonghu')
// @ts-expect-error
console.log(res.data, 'res.data')
this.userInfo = res.data
console.log(this.userInfo, 'this.userInfo')
// @ts-expect-error
this.data = result.data
console.log(result, '123')
// @ts-expect-error
this.userName = result.data.username
// this.avatar = result.data.checkUser.avatar
// @ts-expect-error
this.routes = result.data.permissions
return {
result,
}
} else {
return Promise.reject('登录过期')
}
},
// 退出登录事件
logout() {
const usePermissionStore = permissionStore()
console.log(usePermissionStore)
// 清除token
REMOVE_TOKEN('TOKEN'),
// ;(this.userName = ''), (this.avatar = '')
// @ts-expect-error
(this.userName = ''),
// @ts-expect-error
(this.avatar = '')
// @ts-expect-error
this.token = ''
// @ts-expect-error
this.routes = ''
usePermissionStore.removeRouter()
location.reload()
},
>>>>>>> 0b7db324dad8347654933e91ae7e6ca8d2dabd05
},
},
getters: {},

@ -21,28 +21,28 @@ request.interceptors.response.use(
},
(error) => {
//处理网络错误
let msg = ''
const status = error.response.status
switch (status) {
case 401:
msg = 'token过期'
break
case 403:
msg = '无权访问'
break
case 404:
msg = '请求地址错误'
break
case 500:
msg = '服务器出现问题'
break
default:
msg = '无网络'
}
ElMessage({
type: 'error',
message: msg,
})
// let msg = ''
// const status = error.response.status
// switch (status) {
// case 401:
// msg = 'token过期'
// break
// case 403:
// msg = '无权访问'
// break
// case 404:
// msg = '请求地址错误'
// break
// case 500:
// msg = '服务器出现问题'
// break
// default:
// msg = '出错了'
// }
// ElMessage({
// type: 'error',
// message: msg,
// })
return Promise.reject(error)
},
)

@ -45,8 +45,9 @@ const addBook = (id) => {
flog.value = false
// updateDisabledStatus()
}
const text = ref('我是后台获取的值')
const text = ref('')
const textChange = (val) => {
text.value = val
console.log(text.value)
}
//
@ -336,8 +337,7 @@ onMounted(async () => {
<div class="title">| 课程总目标</div>
<div class="content1">
<textarea class="textarea" @change="textChange" v-model="text">
文本内容</textarea
>
文本内容</textarea>
</div>
</div>
<div class="footContent">
@ -348,17 +348,14 @@ onMounted(async () => {
</div>
</div>
<div class="rightContent">
<div
class="title"
style="
<div class="title" style="
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 20px;
height: 60px;
"
>
">
<div class="left2">| 课程分目标</div>
<div class="right2">
<!-- <el-button type="primary" @click="addBook">新增</el-button> -->
@ -367,10 +364,7 @@ onMounted(async () => {
<div class="content2">
<el-scrollbar height="600px">
<ul class="objectLi">
<li
v-for="(item, index) in data.courseObjectivesTrees"
:key="item.id"
>
<li v-for="(item, index) in data.courseObjectivesTrees" :key="item.id">
<div class="courseObject">
<!-- {{ filterTarger(item.targetId) }} -->
<div class="courseObject1">{{ item.name }}</div>
@ -395,18 +389,10 @@ onMounted(async () => {
<!-- {{ filterTarger(obj.targetId) }} -->
</div>
<div class="partObject2">
<el-button
class="edit"
type="text"
@click="editBook(obj)"
>
<el-button class="edit" type="text" @click="editBook(obj)">
编辑
</el-button>
<el-button
class="destroy"
type="text"
@click="del(obj)"
>
<el-button class="destroy" type="text" @click="del(obj)">
删除
</el-button>
</div>
@ -424,13 +410,8 @@ onMounted(async () => {
</div>
</div>
</div>
<el-dialog
v-if="dialogVisible"
v-model="dialogVisible"
:title="flog ? '编辑' : '新增'"
width="500"
:before-close="handleClose"
>
<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="target">
<el-select v-model="formData.target" placeholder="Select" size="large" style="width: 240px">
@ -439,10 +420,7 @@ onMounted(async () => {
</el-select>
</el-form-item> -->
<el-form-item label="内容" prop="description">
<el-input
v-model="formData.description"
placeholder="请输入内容"
></el-input>
<el-input v-model="formData.description" placeholder="请输入内容"></el-input>
</el-form-item>
</el-form>
<template #footer>
@ -545,7 +523,7 @@ const li
background-color: #fff;
background-image: linear-gradient(#c7e3ff, #ffffff);
.objectLi > li {
.objectLi>li {
width: 845px;
height: 250px;
// margin: 40px;
@ -588,7 +566,7 @@ const li
background-image: linear-gradient(#c7e3ff, #ffffff);
}
.small > li {
.small>li {
// display: inline-flex;
width: 650px;
height: 150px;

@ -108,15 +108,15 @@ const close = () => {
dialogVisible.value = false
}
//
const filterTarger = (target) => {
const res = targetList.value.find((item) => {
if (item.id === target) {
console.log(item)
return item
}
})
return res.label
}
// const filterTarger = (target) => {
// const res = targetList.value.find((item) => {
// if (item.id === target) {
// console.log(item)
// return item
// }
// })
// return res.label
// }
//
const flog = ref(false)
@ -166,7 +166,7 @@ onMounted(async () => {
const res = await getCourseList({ id: courseId.value })
console.log(res)
list.value = res.data
console.log(list.value)
console.log(list.value, 'list.value')
content88.value = list.value[0].contents[0].content
console.log(list.value[0].contents[0].content)
console.log(content88.value)
@ -233,17 +233,14 @@ onMounted(async () => {
</div>
</div>
<div class="rightContent">
<div
class="title"
style="
<div class="title" style="
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 20px;
height: 60px;
"
>
">
<div class="left2">| 课程分目标</div>
<div class="right2">
<!-- <el-button type="primary" @click="addBook">新增</el-button> -->
@ -276,18 +273,10 @@ onMounted(async () => {
<!-- {{ filterTarger(obj.targetId) }} -->
</div>
<div class="partObject2">
<el-button
class="edit"
type="text"
@click="editBook(obj)"
>
<el-button class="edit" type="text" @click="editBook(obj)">
编辑
</el-button>
<el-button
class="destroy"
type="text"
@click="del(obj.id)"
>
<el-button class="destroy" type="text" @click="del(obj.id)">
删除
</el-button>
</div>
@ -305,13 +294,7 @@ onMounted(async () => {
</div>
</div>
</div>
<el-dialog
v-if="dialogVisible"
v-model="dialogVisible"
title="新增目标"
width="500"
:before-close="handleClose"
>
<el-dialog v-if="dialogVisible" v-model="dialogVisible" title="新增目标" width="500" :before-close="handleClose">
<el-form :model="formData" label-width="auto" style="max-width: 600px">
<!-- <el-form-item label="目标" prop="target">
<el-select v-model="formData.target" placeholder="Select" size="large" style="width: 240px">
@ -320,10 +303,7 @@ onMounted(async () => {
</el-select>
</el-form-item> -->
<el-form-item label="内容" prop="description">
<el-input
v-model="formData.description"
placeholder="请输入内容"
></el-input>
<el-input v-model="formData.description" placeholder="请输入内容"></el-input>
</el-form-item>
</el-form>
<template #footer>
@ -426,13 +406,14 @@ const li
background-color: #fff;
background-image: linear-gradient(#c7e3ff, #ffffff);
.objectLi > li {
.objectLi>li {
width: 845px;
height: 250px;
// margin: 40px;
// background-color: #ffffff;
border-radius: 5px;
margin: 20px;
.courseObject {
height: 45px;
line-height: 40px;
@ -457,6 +438,7 @@ const li
}
}
}
// overflow-y: auto
.smallContent {
// border-radius: 20px;
@ -466,7 +448,8 @@ const li
background-color: #fff;
background-image: linear-gradient(#c7e3ff, #ffffff);
}
.small > li {
.small>li {
// display: inline-flex;
width: 750px;
height: 150px;

@ -20,21 +20,21 @@ const router = useRouter()
// console.log(route)
// import { client } from '@/utils/alioss.js'
//
const courseList = ref([])
const courseList = ref()
//
const teacherList = ref([])
const teacherList = ref()
const getTeacherList = async () => {
const res = await getTeacherListApi()
console.log(res)
console.log(res, 'teacher')
teacherList.value = res.data
console.log(teacherList.value)
console.log(teacherList.value, 'teacherList.value')
}
const total = ref(0)
const params = ref({
pageNo: 1,
pageSize: 7,
// username: 'qiuqiu',
username: userStore.userName,
userId: userStore.data.id,
assessmenttype: '',
category: '',
nature: '',
@ -45,14 +45,14 @@ const loading = ref(false)
const getCourseList = async () => {
loading.value = true
// console.log(params.value, '11')
if (userStore.userInfo.roleId === 2) {
if (userStore.userInfo.roleId[0] === 2) {
params.value.pageSize = 8
}
const res = await getCourseListApi(params.value)
courseList.value = res.data.list
total.value = res.data.total
console.log(res.data.list)
console.log(courseList.value, 'courseList.value')
loading.value = false
// console.log(userStore.userName, '1111')
}
@ -106,11 +106,11 @@ const onEditCourse = (item: any) => {
}
//
const onSuccess = () => {
// loading.value = true
loading.value = true
getCourseList()
// loading.value = false
loading.value = false
}
//
//
const onDeleteCourse = async (id: any) => {
await ElMessageBox.confirm('您确定删除这条课程信息吗', '温馨提示', {
confirmButtonText: '确认',
@ -119,20 +119,24 @@ const onDeleteCourse = async (id: any) => {
})
await deleteCourseApi(id)
.then(() => {
console.log(id, '删除id')
ElMessage.success('删除成功')
// console.log(res)
})
.catch((err: any) => {
console.log(id, 'id')
ElMessage.error(err.response.data.message)
})
getCourseList()
}
// id
// id
const onGetCourseObject = async (id: any) => {
console.log(id, 'id')
// const res = await getCourseObjectApi(id)
router.push({
path: '/curriculumCenter/CourseObjectives',
path: '/curriculumCenter/courseDetails',
// path: '/curriculumCenter/CourseObjectives',
query: {
id: id,
},
@ -171,17 +175,13 @@ const CloseCouresNameChangeEvent = () => {
<div class="btn">
<!-- <el-button type="primary" round size="large">全部课程</el-button>
<el-button type="primary" round plain size="large">我的文件夹</el-button> -->
<el-form inline v-if="userStore.userInfo.roleId === 1">
<el-form-item label="课程教师:" class="short-form-item">
<el-form inline v-if="userStore.userInfo.roleId[0] === '1'">
<!-- <el-form-item label="课程教师:" class="short-form-item">
<el-select v-model="params.teacher">
<el-option
v-for="teachers in teacherList"
:key="teachers.username"
:value="teachers.username"
:label="teachers.name"
></el-option>
<el-option v-for="teachers in teacherList" :key="teachers.username" :value="teachers.username"
:label="teachers.name"></el-option>
</el-select>
</el-form-item>
</el-form-item> -->
<el-form-item label="课程类别:" class="short-form-item">
<el-select v-model="params.category">
<el-option label="专业教育" value="1"></el-option>
@ -208,11 +208,7 @@ const CloseCouresNameChangeEvent = () => {
</el-form>
<div class="course">
<ul class="course_list">
<li
v-if="userStore.userInfo.roleId === 1"
@click="onAddCourse()"
class="add_course"
>
<li v-if="userStore.userInfo.roleId[0] === '1'" @click="onAddCourse()" class="add_course">
<div class="plus">
<el-icon class="avatar-uploader-icon">
<Plus />
@ -228,50 +224,33 @@ const CloseCouresNameChangeEvent = () => {
</p> -->
</li>
<li v-for="item in courseList" :key="item.id">
<img :src="item.img" alt="" />
<h2 class="course_name" @click="onEditCourse(item)">
<img title="点击查看课程详情" :src="item.img" alt="" @click="onGetCourseObject(item.id)" />
<h2 title="点击查看课程基本信息" class="course_name" @click="onEditCourse(item)">
{{ item.name }}
</h2>
<p class="teacher_name">讲师{{ item.teacher }}</p>
<p class="credit">
<span>{{ item.classhours }}</span>
学时|
学时 |
<span>{{ item.credit }}</span>
学分
</p>
<el-icon class="del" @click="onDeleteCourse(item.id)">
<Delete />
</el-icon>
<el-button
class="object"
round
plain
@click="onGetCourseObject(item.id)"
>
查看课程目标
<el-button class="object" round plain @click="onGetCourseObject(item.id)">
查看课程详情
</el-button>
</li>
</ul>
</div>
<el-pagination
v-model:current-page="params.pageNo"
v-model:page-size="params.pageSize"
:page-sizes="[2, 5, 7, 10]"
:background="true"
layout="jumper,total, sizes, prev, pager, next "
:total="total"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
style="margin-top: 10px; justify-content: center"
/>
<el-pagination v-model:current-page="params.pageNo" v-model:page-size="params.pageSize"
:page-sizes="[2, 5, 7, 10]" :background="true" layout="jumper,total, sizes, prev, pager, next " :total="total"
@size-change="handleSizeChange" @current-change="handleCurrentChange"
style="margin-top: 10px; justify-content: center" />
</div>
<course-edit
ref="drawer"
@success="onSuccess"
@couresNameChange="couresNameChangeEvent"
@CloseCouresNameChange="CloseCouresNameChangeEvent"
:flog="flog"
></course-edit>
<course-edit ref="drawer" @success="onSuccess" @couresNameChange="couresNameChangeEvent"
@CloseCouresNameChange="CloseCouresNameChangeEvent" :flog="flog"></course-edit>
</div>
</div>
</template>
@ -317,6 +296,7 @@ const CloseCouresNameChangeEvent = () => {
}
.course {
// display: flex;
// flex: 0 0 25%;
// justify-content: space-between;
@ -354,6 +334,7 @@ const CloseCouresNameChangeEvent = () => {
margin-left: 30px;
margin-top: 10px;
font-weight: bold;
&:hover {
cursor: pointer;
}
@ -363,14 +344,15 @@ const CloseCouresNameChangeEvent = () => {
background-color: #cccccc;
width: 100%;
height: 178px;
cursor: pointer;
}
p {
margin-left: 30px;
margin-top: 10px;
margin-top: 5px;
color: #555555;
font-size: 14px;
padding-top: 12px;
padding-top: 10px;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
@ -383,22 +365,23 @@ const CloseCouresNameChangeEvent = () => {
.del {
position: absolute;
margin-left: 302px;
margin-top: -90px;
margin-left: 280px;
margin-top: -80px;
color: #0052ff;
cursor: pointer;
}
.object {
position: absolute;
margin-left: 204px;
margin-top: -24px;
margin-left: 180px;
margin-top: -29px;
}
}
.plus {
width: 100%;
height: 178px;
&:hover {
cursor: pointer;
}
@ -413,8 +396,10 @@ const CloseCouresNameChangeEvent = () => {
text-align: center;
}
}
.add_course {
border: 2px dashed rgb(143, 139, 139);
h2 {
font-size: 40px;
text-align: center;
@ -422,13 +407,15 @@ const CloseCouresNameChangeEvent = () => {
color: #535050;
font-weight: bold;
margin-top: 20px;
&:hover {
cursor: pointer;
}
}
}
.short-form-item {
width: 250px;
margin-right: 65px;
width: 300px;
margin-right: 100px;
}
</style>

@ -1,4 +1,5 @@
<template>
<<<<<<< HEAD
<div class="add-or-edit">
<el-drawer v-model="isDrawer" title="新增章节" direction="rtl" size="50%">
<el-form
@ -47,6 +48,31 @@
</el-form>
</el-drawer>
</div>
=======
<div class="add-or-edit">
<el-drawer v-model="isDrawer" title="新增章节" direction="rtl" size="50%">
<el-form ref="ruleFormRef" style="max-width: 600px" :model="ruleForm" :rules="rules" label-width="auto"
class="demo-ruleForm" :size="formSize" status-icon>
<el-form-item label="章节" prop="pid">
<el-cascader v-model="activePidArr" :options="options1" :props="CascaderProps"
:show-all-levels="false" clearable />
</el-form-item>
<el-form-item label="章节名" prop="name">
<el-input v-model="ruleForm.name" style="width: 240px" :placeholder="placeholder" />
</el-form-item>
<el-form-item label="总学时" prop="totalclasshours">
<el-input v-model="ruleForm.totalclasshours" style="width: 240px" placeholder="请输入总学时" />
</el-form-item>
<el-form-item>
<el-button type="primary" :loading="loading" @click="submitForm(ruleFormRef)">
提交
</el-button>
<el-button @click="resetForm(ruleFormRef)">重置</el-button>
</el-form-item>
</el-form>
</el-drawer>
</div>
>>>>>>> 0b7db324dad8347654933e91ae7e6ca8d2dabd05
</template>
<script lang="ts" setup>
function comNum(n: number | undefined) {
@ -61,6 +87,7 @@ const updLoading = (boo: boolean) => (loading.value = boo)
const isDrawer = ref(props.isD)
watch(
<<<<<<< HEAD
() => props.isD,
(newVal) => (isDrawer.value = newVal),
)
@ -81,6 +108,30 @@ const options1 = computed(() => {
obj.chapterSection.push({
name: `${i + 1}章第${comNum(item.chapterSection?.length)}`,
pid: item.id,
=======
() => props.isD,
(newVal) => (isDrawer.value = newVal),
)
watch(
() => isDrawer.value,
(newVal) => emits('update:isD', newVal),
)
const options1 = computed(() => {
const arr = props.data.map((item: any, i: number) => {
const obj = { ...item }
if (item.chapterSection)
obj.chapterSection = item.chapterSection.map((chap: any) => ({
...chap,
disabled: true,
}))
else obj.chapterSection = []
obj.chapterSection.push({
name: `${i + 1}章第${comNum(item.chapterSection?.length)}`,
pid: item.id,
})
return obj
>>>>>>> 0b7db324dad8347654933e91ae7e6ca8d2dabd05
})
return obj
})
@ -88,9 +139,15 @@ const options1 = computed(() => {
return arr
})
const CascaderProps = {
<<<<<<< HEAD
label: 'name',
value: 'pid',
children: 'chapterSection',
=======
label: 'name',
value: 'pid',
children: 'chapterSection',
>>>>>>> 0b7db324dad8347654933e91ae7e6ca8d2dabd05
}
import type { ComponentSize, FormInstance, FormRules } from 'element-plus'
@ -120,6 +177,7 @@ interface RuleForm {
const formSize = ref<ComponentSize>('default')
const ruleFormRef = ref<FormInstance>()
const ruleForm = reactive<RuleForm>({
<<<<<<< HEAD
content: '',
courseid: '2fa0fd63262230639d2c45a3acd9045c',
courseobjectivesid: '',
@ -164,6 +222,52 @@ const submitForm = async (formEl: FormInstance | undefined) => {
console.log('error submit!', fields)
}
})
=======
content: '',
courseid: '2fa0fd63262230639d2c45a3acd9045c',
courseobjectivesid: '',
createBy: '',
createTime: '',
id: '',
name: '',
num: 0,
numshow: '',
onlinclasshours: '',
pid: undefined,
requirement: '',
sysOrgCode: '',
totalclasshours: '',
updateBy: '',
updateTime: '',
zc: '',
ziyuan: '',
zywj: '',
})
// @ts-ignore
const validateChapterOrSection = (rule, value, callback) => {
nextTick(() => {
const value = ruleForm.pid
if (!value && value !== '') callback(new Error('请选择新增的章或节'))
else callback()
})
}
//
const rules = reactive<FormRules<RuleForm>>({
pid: [
{ required: true, validator: validateChapterOrSection, trigger: 'change' },
],
})
const submitForm = async (formEl: FormInstance | undefined) => {
if (!formEl) return
await formEl.validate((valid, fields) => {
if (valid) {
emits('submit', ruleForm, updLoading)
} else {
console.log('error submit!', fields)
}
})
>>>>>>> 0b7db324dad8347654933e91ae7e6ca8d2dabd05
}
const resetForm = (formEl: FormInstance | undefined) => {
@ -173,6 +277,7 @@ const resetForm = (formEl: FormInstance | undefined) => {
}
const placeholder = ref('请输入章节名')
watch(
<<<<<<< HEAD
() => ruleForm.pid,
(newVal) => {
if (newVal === undefined) placeholder.value = '请输入章节名'
@ -191,6 +296,26 @@ watch(
}
ruleForm.pid = newVal.slice(-1)[0]
},
=======
() => ruleForm.pid,
(newVal) => {
if (newVal === undefined) placeholder.value = '请输入章节名'
else if (newVal === '') placeholder.value = '请输入章名'
else placeholder.value = '请输入节名'
},
)
const activePidArr = ref<string[] | undefined>([])
watch(
() => activePidArr.value,
(newVal) => {
// pid
if (newVal === undefined) {
ruleForm.pid = undefined
return
}
ruleForm.pid = newVal.slice(-1)[0]
},
>>>>>>> 0b7db324dad8347654933e91ae7e6ca8d2dabd05
)
</script>
<style lang="scss"></style>

@ -2,11 +2,15 @@
<div class="fold-info-ui">
<div class="demo-collapse">
<el-collapse class="collapse">
<<<<<<< HEAD
<button
class="my-button"
style="position: absolute; left: 0; top: 0"
@click.stop="emits('add')"
>
=======
<button class="my-button" style="position: absolute; left: 0; top: 0" @click.stop="emits('add')">
>>>>>>> 0b7db324dad8347654933e91ae7e6ca8d2dabd05
新增
</button>
<el-collapse-item v-for="item in foldInfoData" :key="item.id">
@ -26,6 +30,7 @@
</div>
<div class="my-tag">本章资源</div>
</div>
<<<<<<< HEAD
<button
class="my-button"
@click.stop="emits('edit', item)"
@ -39,6 +44,12 @@
class="is-el-button"
style="margin-right: 10px"
>
=======
<button class="my-button" @click.stop="emits('edit', item)" style="margin-right: 10px">
编辑
</button>
<my-btn :id="item.id" type="danger" class="is-el-button" style="margin-right: 10px">
>>>>>>> 0b7db324dad8347654933e91ae7e6ca8d2dabd05
删除
</my-btn>
</div>
@ -52,11 +63,15 @@
<div class="left"></div>
<div class="right">
<div class="structure-item">
<<<<<<< HEAD
<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">
>>>>>>> 0b7db324dad8347654933e91ae7e6ca8d2dabd05
<div class="titile-box-titile">
<div class="sequence">{{ ind + 1 }}</div>
<div class="tit-box">
@ -70,6 +85,7 @@
</div>
</div>
<div class="tit-box-edit">
<<<<<<< HEAD
<button
class="my-button"
@click.stop="emits('edit', obj)"
@ -83,6 +99,12 @@
class="is-el-button"
style="margin-right: 10px"
>
=======
<button class="my-button" @click.stop="emits('edit', obj)" style="margin-right: 10px">
编辑
</button>
<my-btn :id="obj.id" type="danger" class="is-el-button" style="margin-right: 10px">
>>>>>>> 0b7db324dad8347654933e91ae7e6ca8d2dabd05
删除
</my-btn>
</div>
@ -286,7 +308,11 @@ const MyBtn = {
gap: 38px;
flex-wrap: wrap;
<<<<<<< HEAD
& > * {
=======
&>* {
>>>>>>> 0b7db324dad8347654933e91ae7e6ca8d2dabd05
border: 1px solid #0052d9;
font-weight: bold;
font-size: 12px;
@ -337,6 +363,7 @@ const MyBtn = {
cursor: pointer;
&:hover {
<<<<<<< HEAD
background: linear-gradient(
128deg,
lighten($color-start, 5%) 0%,
@ -358,6 +385,23 @@ const MyBtn = {
lighten($color-start, 20%) 0%,
lighten($color-end, 20%) 100%
);
=======
background: linear-gradient(128deg,
lighten($color-start, 5%) 0%,
lighten($color-end, 5%) 100%);
}
&:active {
background: linear-gradient(128deg,
darken($color-start, 10%) 0%,
darken($color-end, 10%) 100%);
}
&:disabled {
background: linear-gradient(128deg,
lighten($color-start, 20%) 0%,
lighten($color-end, 20%) 100%);
>>>>>>> 0b7db324dad8347654933e91ae7e6ca8d2dabd05
}
}

@ -0,0 +1,35 @@
<script lang="ts" setup></script>
<template>
<div class="grid-content chapters-details" style="height: 300px">
<h1>章节详情</h1>
<div class="info">
<p>本章名称认识计算机导论</p>
<p>
简介
适用专业软件工程专业本章目标本课程对每个专题的讲座内容进行系统整理形成了由讲座概要专题内容拓展阅读文献教学课件和教学视频等组成的教学内容体系学生可以根据自己的学习兴趣由浅入深地进行拓展学习通过学术讲座学术沙龙学术讨论等形式使学生掌握较扎实的课程与教学的基础理论知识和其他相关知识树立先进的教育观念了解国内外教育改革实践了解国内外课程与教学研究的历史现状和动向形成较强的独立从事课程与教学研究能力对现实的课程与教学问题具有清晰的认识能在现代教育观念指导下投入我国基础教育课程改革的实践
</p>
<p>章节编号1110</p>
<p>章节总学时26h</p>
</div>
</div>
</template>
<style lang="scss" scoped>
.chapters-details {
h1 {
padding-top: 20px;
text-align: center;
font-size: 24px;
font-weight: 700;
color: #333333ff;
}
.info {
padding: 20px;
p {
margin: 10px;
}
}
}
</style>

@ -0,0 +1,191 @@
<script lang="ts" setup>
import { ref } from 'vue'
import { useRoute } from 'vue-router'
import { getCourseDetailApi } from '@/api/user/crouse'
import { onMounted } from 'vue'
const route = useRoute()
const courseId = ref()
const courseDetails = ref({
img: '',
name: '',
teacher: '',
description: '',
code: '',
})
courseId.value = route.query.id
console.log(courseId.value, 'id')
const getCourseDetails = async () => {
const res = await getCourseDetailApi(courseId.value)
courseDetails.value = res.data
// console.log(res)
console.log(courseDetails.value, 'courseDetails.value')
}
onMounted(() => {
getCourseDetails()
})
</script>
<template>
<div class="grid-content course-brief" style="height: 350px">
<h1 style="text-align:">课程基本信息</h1>
<div class="box">
<div class="image">
<img :src="courseDetails.img" alt="" />
</div>
<div class="text">
<h2 class="title">
{{ courseDetails.name }}
<span>主讲教师{{ courseDetails.teacher }}</span>
</h2>
<div>
<h3>
课程简介:
<el-scrollbar height="70px">
<p class="pp">{{ courseDetails.description }}</p>
</el-scrollbar>
<!-- <textarea name="" id=""></textarea> -->
</h3>
<div class="brief">
<ul class="ull">
<li>
<p>课程编码</p>
<p>{{ courseDetails.code }}</p>
</li>
<li>
<p>课程学分</p>
<p>{{ courseDetails.category }}</p>
</li>
<li>
<p>课程学时</p>
<p>{{ courseDetails.classhours }}</p>
</li>
<li>
<p>课程性质</p>
<p>{{ courseDetails.nature }}</p>
</li>
<li>
<p>考核方式</p>
<p>{{ courseDetails.assessmentway }}</p>
</li>
<li>
<p>考核类型</p>
<p>{{ courseDetails.assessmenttype }}</p>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</template>
<style lang="scss" scoped>
.course-brief {
// display: flex;
// justify-content: space-between;
h1 {
// display: block;
padding-top: 20px;
text-align: center;
font-size: 24px;
font-weight: 700;
color: #333333ff;
}
.box {
width: 100%;
height: 80%;
display: flex;
justify-content: space-between;
.image {
// position: relative;
margin-top: 20px;
margin-left: 20px;
margin-right: 20px;
width: 40%;
height: 90%;
border-radius: 6px;
background-color: rgb(211, 196, 199);
img {
width: 100%;
height: 100%;
border-radius: 6px;
// margin: 25px;
// margin: 10px;
// width: 100%;
// height: 100%;
// background-color: rgb(211, 196, 199);
}
}
.text {
width: 60%;
height: 100%;
// margin: 50px;
margin: 20px 60px 60px 0px;
// background-color: #74deff;
// background-image: linear-gradient(to right, #4984ff, #74deff);
border-radius: 20px;
h2 {
font-weight: 600;
font-size: 26px;
margin-bottom: 20px;
font-family: Inter, Inter;
color: #333333ff;
span {
margin-left: 40px;
font-size: 18px;
line-height: 30px;
color: #8a8b99;
}
}
h3 {
color: #8a8b99;
font-size: 14px;
.pp {
margin-top: 10px;
display: inline;
padding-left: 35px;
color: #2e2e2e;
}
}
.brief {
border-radius: 4px;
width: 100%;
height: 50%;
.ull {
display: flex;
flex-wrap: wrap;
margin-top: 10px;
}
li {
// margin-top: 10px;
margin-right: 80px;
font-size: 14px;
text-align: center;
margin-bottom: 15px;
p {
margin-top: 10px;
font-size: 16px;
}
p:nth-child(1) {
color: #8a8b99;
font-size: 14px;
}
}
}
}
}
}
</style>

@ -0,0 +1,171 @@
<script setup lang="ts">
import { ref } from 'vue'
import type Node from 'element-plus/es/components/tree/src/model/node'
import { ElMessage, ElMessageBox } from 'element-plus'
import { useRoute } from 'vue-router'
import {
getChaptersListApi,
addChaptersApi,
delchaptersApi,
} from '@/api/user/chapter'
import { onMounted } from 'vue'
const route = useRoute()
// const router = useRouter()
const courseId = ref()
onMounted(() => {
courseId.value = route.query.id
getChaptersList()
})
// console.log(courseId.value, 'courseId.value')
const getChaptersList = async () => {
console.log(courseId.value, 'courseId.value')
const res = await getChaptersListApi({ id: courseId.value })
const transformedData: Tree[] = res.data.map((item: any) => ({
id: item.id,
name: item.name,
pid: item.pid,
children: item.children.map((children: any) => ({
id: children.id,
name: children.name,
pid: children.pid,
children: children.children.map((children: any) => ({
id: children.id,
name: children.name,
pid: children.pid,
})),
})),
}))
dataSource.value = transformedData
console.log(res)
}
interface Tree {
id: number
name: string
pid: any
children?: Tree[]
}
let id = 1000
//
const append = async (data: Tree) => {
ElMessageBox.prompt('请输入章节名称', '添加', {
confirmButtonText: '确定',
cancelButtonText: '取消',
}).then(async ({ value }) => {
const newChild = {
id: id++,
name: `${value}`,
pid: data.id,
courseId: courseId.value,
}
if (!data.children) {
data.children = []
}
data.children.push(newChild)
const res = await addChaptersApi(newChild)
console.log(res)
if (res.code === 200) {
//
dataSource.value = [...dataSource.value]
ElMessage({
type: 'success',
message: '添加成功',
})
} else {
ElMessage({
type: 'error',
message: '添加失败,请稍后再试',
})
}
// dataSource.value = [...dataSource.value]
})
}
//
const remove = async (node: Node, data: Tree) => {
const res = await getChaptersListApi(data.id)
console.log(res, 'delres')
ElMessageBox.confirm('确定删除本章节吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
center: true,
})
const parent = node.parent
const children: Tree[] = parent.data.children || parent.data
const index = children.findIndex((d) => d.id === data.id)
children.splice(index, 1)
dataSource.value = [...dataSource.value]
}
const dataSource = ref<Tree[]>([
{
id,
name: '',
pid: '',
children: [
{
id,
name: '',
pid: '',
children: [
{
id,
name: '',
pid: '',
},
],
},
],
},
])
</script>
<template>
<div class="grid-content course-chapters" style="height: 820px">
<h1>课程章节</h1>
<!-- <button @click="getChaptersList">获取</button> -->
<div class="custom-tree-container">
<el-tree style="max-width: 600px" :data="dataSource" node-key="id" default-expand-all
:expand-on-click-node="false" empty-text="暂无章节">
<template #default="{ node, data }">
<span class="custom-tree-node">
<span>{{ data.name }}</span>
<span>
<el-button @click="append(data)">添加</el-button>
<el-button @click="remove(node, data)">删除</el-button>
<!-- <a @click="append(data)"></a> -->
<!-- <a style="margin-left: 8px" @click="remove(node, data)">删除</a> -->
</span>
</span>
</template>
</el-tree>
</div>
</div>
</template>
<style lang="scss" scoped>
.course-chapters {
.show-checkbox {
display: false;
}
h1 {
padding: 20px;
text-align: center;
font-size: 24px;
font-weight: 700;
color: #333333ff;
}
.custom-tree-node {
flex: 1;
display: flex;
align-items: center;
justify-content: space-between;
font-size: 18px;
padding-right: 8px;
// width: 20%
// width: 200px;
}
}
</style>

@ -0,0 +1,433 @@
<script setup lang="ts">
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'
const emit = defineEmits(['updateObject'])
import {
getCourseList,
addCourse,
editCourse,
deleteCourse,
getCourseInfo,
} from '@/api/courseChaptersApi'
import { useRoute, useRouter } from 'vue-router'
const route = useRoute()
const router = useRouter()
const formData = ref({
description: '',
})
const activeIndex = ref(0)
//
const addPoint = (id: any) => {
console.log(id, 'id')
activeIndex.value = id
dialogVisible.value = true
flog.value = false
// updateDisabledStatus()
}
const params = ref({
content: '',
id: '',
objectiveId: '',
})
const content = ref('')
const textChange = async (val: any) => {
params.value.content = content.value
console.log(params.value.content, ' params.value.content')
console.log(params.value, 'params.value')
console.log(params.value.id, 'params.id')
// const jsonstr = JSON.stringify(params)
// const res = await editCourse(jsonstr)
const res = await editCourse({
id: params.value.id,
objectiveId: params.value.objectiveId,
content: params.value.content,
})
console.log(res, 'res')
console.log(content.value, 'text.value')
}
//
const dialogVisible = ref(false)
//
const handleClose = () => {
dialogVisible.value = false
}
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]
params.value = res.data[0].contents[0]
console.log(params.value, 'params.value')
console.log(data.value, 'data.value')
content.value = res.data[0].contents[0].content
}
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')
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: 100,
//
startAngle: 90,
//
splitNumber: 5,
shape: 'circle',
name: {
formatter: '{value}',
textStyle: {
color: '#333333',
fontSize: 16,
},
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: 100,
startAngle: 90,
splitNumber: 1,
shape: 'circle',
splitArea: {
show: false,
},
axisLine: {
show: false,
},
name: {
formatter: '{value}',
textStyle: {
color: 'rgba(0,0,0,0.4)',
fontSize: 16,
},
},
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>
<template>
<div class="grid-content course-object" style="height: 450px">
<h1>课程目标</h1>
<div class="all_content">
<div class="graph">
<div class="title">课程目标雷达图</div>
<div id="main" class="radarmap"></div>
</div>
<div class="object">
<span>课程总目标:</span>
<!-- <el-scrollbar height="90px"> -->
<textarea class="textarea" @change="textChange" v-model="content"></textarea>
<!-- </el-scrollbar> -->
<div class="demo-collapse">
<el-collapse v-model="activeName" accordion>
<el-collapse-item title="知识目标" name="1">
<ul>
<li>目标一</li>
<li>目标二</li>
</ul>
</el-collapse-item>
<el-collapse-item title="素质目标" name="2">
<ul>
<li>目标一</li>
<li>目标二</li>
</ul>
</el-collapse-item>
<el-collapse-item title="价值目标" name="3">
<ul>
<li>目标一</li>
<li>目标二</li>
</ul>
</el-collapse-item>
<el-collapse-item title="思政目标" name="4">
<ul>
<li>目标一</li>
<li>目标二</li>
</ul>
</el-collapse-item>
</el-collapse>
</div>
</div>
</div>
</div>
</template>
<style lang="scss" scoped>
.course-object {
h1 {
padding: 20px;
text-align: center;
font-size: 24px;
font-weight: 700;
color: #333333ff;
}
.all_content {
width: 100%;
height: 100%;
display: flex;
justify-content: space-between;
.graph {
width: 40%;
height: 100%;
.title {
text-align: center;
font-size: 24px;
font-weight: 400;
color: #333333ff;
}
.radarmap {
width: 100%;
height: 90%;
margin-top: -60px;
}
}
.object {
width: 60%;
span {
// text-align: center;
font-size: 20px;
font-weight: 400;
// color: #4984ffff;
}
// span:hover {
// color: red;
// }
.el-scrollbar {
height: 30%;
width: 100%;
}
.textarea {
width: 90%;
height: 20%;
border: none;
resize: none;
}
.demo-collapse {
padding-top: 20px;
.el-collapse {
--el-collapse-header-font-size: 16px;
}
}
}
}
}
.el-collapse-item__header:hover {
color: #385ea9 !important;
/* 强制应用样式 */
}
</style>

@ -1,12 +1,13 @@
<script setup lang="ts">
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 { editCourseApi } from '../../../api/user/crouse'
import { addCourseApi } from '../../../api/user/crouse'
import { getCourseListApi, getCourseDetailApi } from '../../../api/user/crouse'
import request from '../../../utils/request'
import { tool, client } from '../../../utils/alioss.js'
// import request from '../../../utils/request'
import { tool } from '../../../utils/alioss.js'
import useUserStore from '@/store/modules/user'
// import { useRoute } from 'vue-router'
const userStore = useUserStore()
@ -24,7 +25,7 @@ const formRef = ref()
// }
// const beforeAvatarUpload = (file: any) => {}
const defaultForm = {
teacher: '2140110334',
teacher: userStore.data.id,
img: '',
name: '',
category: ref(''),
@ -57,7 +58,7 @@ const rules = {
trigger: 'blur',
},
{
pattern: /^[a-zA-Z\u4e00-\u9fa5A-Z0-9]*$/,
pattern: /^[a-zA-Z\u4e00-\u9fa5A-Z]*$/,
message: '只能输入汉字或字母',
trigger: 'blur',
},
@ -89,6 +90,11 @@ const rules = {
trigger: 'blur',
},
{ max: 10, message: '不能超过10个字符', trigger: 'blur' },
// {
// validator: validateUniqueCode,
// message: '',
// trigger: 'blur',
// },
],
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) => {
@ -162,9 +187,8 @@ defineExpose({ open })
const props = defineProps(['flog'])
const onSubmit = async () => {
console.log(formModel.value, 'formModel.value')
// console.log(formModel.value, 'formModel.value')
formModel.value.classhours = formModel.value.classhours.toString()
await formRef.value.validate()
const isEdit = formModel.value.id
if (isEdit) {
@ -172,39 +196,31 @@ const onSubmit = async () => {
ElMessage.success('修改成功')
emit('CloseCouresNameChange')
emit('success')
console.log(formModel.value, 'formModel.value')
} else {
console.log(formModel.value, 'formModel.value')
// console.log(formModel.value)
await addCourseApi(formModel.value)
ElMessage.success('添加成功')
.then(() => {
ElMessage.success('添加成功')
// console.log(res)
})
.catch((err: any) => {
// console.log(err)
ElMessage.error(err.response.data.message)
})
//
emit('CloseCouresNameChange')
emit('success')
// emit('ClosecreditChange')
// emit('CloseclasshoursChange')
}
formModel.value = { ...defaultForm }
imgUrl.value = ''
emit('success')
visibleDrawer.value = false
}
// const fileList: any = ref([])
// function updHandle() {
// updFile()
// }
// function updFile() {
// const fileName = fileList.value[0]?.name
// const file = fileList.value[0]?.raw
// try {
// client()
// .multipartUpload(fileName, file)
// .then((res) => {
// console.log(res, 'url')
// })
// } catch (error) {
// console.log(error, 'error')
// }
// }
//
const emit = defineEmits([
'success',
@ -226,22 +242,7 @@ const courseNameInput = () => {
emit('couresNameChange', formModel.value.name)
}
}
// const creditInput = () => {
// if (!props.flog) {
// emit('creditChange', formModel.value.credit)
// }
// }
// const classhoursInput = () => {
// if (!props.flog) {
// emit('classhoursChange', formModel.value.classhours)
// }
// }
// watch(
// () => props.flog,
// (newVal) => {
// console.log(newVal)
// },
// )
onMounted(() => {
console.log(props.flog)
})
@ -267,20 +268,11 @@ const upload = async (option: any) => {
</script>
<template>
<el-drawer
:before-close="handleClose"
v-model="visibleDrawer"
direction="rtl"
:title="formModel.id ? '编辑课程' : '添加课程'"
>
<el-drawer :before-close="handleClose" v-model="visibleDrawer" direction="rtl"
:title="formModel.id ? '编辑课程' : '添加课程'">
<el-form :model="formModel" :rules="rules" ref="formRef">
<el-form-item label="课程封面" prop="img">
<el-upload
v-model="formModel.img"
class="avatar-uploader"
:http-request="upload"
:show-file-list="false"
>
<el-upload v-model="formModel.img" class="avatar-uploader" :http-request="upload" :show-file-list="false">
<img v-if="imgUrl" :src="imgUrl" class="avatar" />
<el-icon v-else class="avatar-uploader-icon">
<Plus />
@ -319,12 +311,8 @@ const upload = async (option: any) => {
</el-upload> -->
</el-form-item>
<el-form-item label="课程名称" prop="name">
<el-input
:disabled="nameDisabled"
style="width: 200px"
v-model="formModel.name"
@input="courseNameInput"
></el-input>
<el-input :disabled="nameDisabled" style="width: 200px" v-model="formModel.name"
@input="courseNameInput"></el-input>
</el-form-item>
<el-form-item label="课程类别" prop="category">
<el-radio-group v-model="formModel.category">
@ -340,25 +328,13 @@ const upload = async (option: any) => {
</el-radio-group>
</el-form-item>
<el-form-item label="课程编码" prop="code">
<el-input
style="width: 200px"
v-model="formModel.code"
:disabled="codeDisabled"
></el-input>
<el-input style="width: 200px" v-model="formModel.code" :disabled="codeDisabled"></el-input>
</el-form-item>
<el-form-item label="课程学分" prop="credit">
<el-input
style="width: 200px"
v-model="formModel.credit"
@input="creditInput"
></el-input>
<el-input style="width: 200px" v-model="formModel.credit"></el-input>
</el-form-item>
<el-form-item label="课程学时" prop="classhours">
<el-input
style="width: 200px"
v-model="formModel.classhours"
@input="classhoursInput"
></el-input>
<el-input style="width: 200px" v-model="formModel.classhours"></el-input>
</el-form-item>
<el-form-item label="考核类型" prop="assessmenttype">
<el-radio-group v-model="formModel.assessmenttype">
@ -385,7 +361,7 @@ const upload = async (option: any) => {
</el-form>
<template #footer>
<span class="dialog-footer" v-if="userStore.userInfo.roleId === 1">
<span class="dialog-footer" v-if="userStore.userInfo.roleId[0] === '1'">
<el-button @click="handleClose" size="large">取消</el-button>
<el-button type="primary" size="large" @click="onSubmit()">
确认
@ -403,6 +379,7 @@ const upload = async (option: any) => {
height: 178px;
display: block;
}
.el-upload {
border: 1px dashed var(--el-border-color);
border-radius: 6px;
@ -411,9 +388,11 @@ const upload = async (option: any) => {
overflow: hidden;
transition: var(--el-transition-duration-fast);
}
.el-upload:hover {
border-color: var(--el-color-primary);
}
.el-icon.avatar-uploader-icon {
font-size: 28px;
color: #8c939d;

@ -0,0 +1,172 @@
<script lang="ts" setup>
// // import { useRouter } from 'vue-router'
// import { onMounted, ref, reactive, watch } from 'vue'
// import ForceGraph3D from '3d-force-graph'
// //@ts-ignore
// import {
// CSS2DRenderer,
// CSS2DObject,
// } from 'three/examples/jsm/renderers/CSS2DRenderer.js'
// //@ts-ignore
// import SpriteText from '../spritetext.js'
// // const $router = useRouter()
// // const jsonData = ref(null)
// let Graph: any = reactive({})
// const props = defineProps({
// width: {
// // type: Number,
// // default:
// // window.innerWidth ||
// // document.documentElement.clientWidth ||
// // document.body.clientWidth,
// },
// height: {
// type: Number,
// // default:
// // window.innerHeight ||
// // document.documentElement.clientHeight ||
// // document.body.clientHeight,
// },
// })
// watch(
// () => props.width,
// (ne) => Graph.width(ne),
// )
// watch(
// () => props.height,
// (ne) => Graph.height(ne),
// )
// const dom = ref(null)
// onMounted(() => {
// Graph = ForceGraph3D({
// extraRenderers: [new CSS2DRenderer()],
// })(document.getElementById('3d-graph') as HTMLElement)
// .jsonUrl('../../../public/data.json')
// // .nodeAutoColorBy('group')
// .nodeThreeObject((node: any) => {
// const nodeEl = document.createElement('div')
// nodeEl.textContent = node.label
// nodeEl.style.color = '#333333'
// nodeEl.style.borderRadius = '50%'
// // console.log(node, 111, Graph.graphData().nodes)
// return new CSS2DObject(nodeEl)
// })
// .linkLabel((link: any) => link.label) //
// .linkWidth(0.8)
// .linkHoverPrecision(0.5) //
// .linkColor(() => '#dd92fd') // 线
// .backgroundColor('#f5f6fd')
// .width(props.width)
// .height(props.height)
// .linkThreeObjectExtend(true)
// .nodeColor((node: any) => {
// return node.color
// })
// .nodeRelSize(7) // 4
// .nodeResolution(20)
// .linkDirectionalArrowLength(3) // 线3
// .linkDirectionalArrowRelPos(1) // 线线
// .nodeThreeObjectExtend(true)
// .onNodeClick((node: any) => {
// // Aim at node from outside it
// //
// const targetDistance = 200 //
// //
// const distRatio = 1 + targetDistance / Math.hypot(node.x, node.y, node.z)
// const newPos = {
// x: node.x * distRatio,
// y: node.y * distRatio,
// z: node.z * distRatio,
// }
// //
// if (node.x === 0 && node.y === 0 && node.z === 0) {
// newPos.z = targetDistance // z
// }
// //
// //@ts-ignore
// Graph.cameraPosition(
// newPos, //
// node, //
// 3000, //
// )
// //
// //@ts-ignore
// const graphData = Graph.graphData()
// // 线线
// graphData.links.forEach((link: any) => {
// // console.log(link);
// if (link.source.id === node.id || link.target.id === node.id) {
// setLabel()
// // 线
// // link.color = '#FF0000' // 线
// //@ts-ignore
// Graph.linkColor((item: any): any => {
// if (item.source.id === node.id || item.target.id === node.id) {
// return 'red'
// } else {
// return '#dd92fd'
// }
// })
// } else {
// // Graph.linkColor(() => '#a4c7fe') // 线
// }
// })
// //
// //@ts-ignore
// Graph.graphData(graphData)
// })
// dom.value = document.querySelector('canvas') as any
// })
// const setLabel = () => {
// //@ts-ignore
// Graph.linkThreeObject((link: any) => {
// // extend link with text sprite
// const sprite = new SpriteText(`${link.label}`)
// sprite.color = '#ccc'
// sprite.textHeight = 1.5
// return sprite
// })
// //@ts-ignore
// Graph.linkPositionUpdate((sprite, { start, end }) => {
// //@ts-ignore
// const middlePos = Object.assign(
// ...['x', 'y', 'z'].map((c) => ({
// //@ts-ignore
// [c]: start[c] + (end[c] - start[c]) / 2, // calc middle point
// })),
// )
// // Position sprite
// Object.assign(sprite.position, middlePos)
// })
// //@ts-ignore
// Graph.d3Force('charge').strength(-120)
// }
// // const goToEditAtlas = () => {
// // console.log(jsonData.value)
// // $router.push({ name: 'EditAtlas', params: { id: 123 } })
// // }
</script>
<template>
<div class="grid-content knowledge-graph" style="height: 500px">
<!-- <div class="graph">
<div id="3d-graph"></div>
</div> -->
</div>
</template>
<style lang="scss" scoped>
.graph {
width: 200px;
height: 400px;
}
</style>

@ -0,0 +1,142 @@
<script lang="ts" setup>
import { ref, onMounted } from 'vue'
import * as echarts from 'echarts'
import 'echarts-liquidfill'
const liquidechart1 = ref(null) //
const liquidechart2 = ref(null) //
onMounted(() => {
const myChart1 = echarts.init(liquidechart1.value) // 使 ref
myChart1.setOption({
title: {
text: '知识点达成度',
textStyle: {
color: '#888',
fontFamily: 'microsoft yahei',
fontSize: 24,
fontWeight: '400',
align: 'center',
verticalAlign: 'middle',
},
left: 'center',
top: '20%',
},
series: [
{
type: 'liquidFill',
radius: '95%',
waveAnimation: true,
data: [0.5], //
direction: 'left',
itemStyle: {
normal: {
color: '#1890ff',
},
},
outline: {
borderDistance: 3,
itemStyle: {
borderColor: '#4984ff',
borderWidth: 10,
},
},
itemStyle: {
opacity: 0.9,
},
backgroundStyle: {
color: '#fff',
},
label: {
show: true,
color: '#000',
insideColor: '#fff',
fontSize: 24,
fontWeight: 400,
align: 'center',
verticalAlign: 'middle',
},
},
],
})
const myChart2 = echarts.init(liquidechart2.value) // 使 ref
myChart2.setOption({
title: {
text: '知识点完成度',
textStyle: {
color: '#888',
fontFamily: 'microsoft yahei',
fontSize: 24,
fontWeight: '400',
align: 'center',
verticalAlign: 'middle',
},
left: 'center',
top: '20%',
},
series: [
{
type: 'liquidFill',
radius: '95%',
waveAnimation: true,
data: [0.8], //
direction: 'left',
itemStyle: {
normal: {
color: '#1890ff',
},
},
outline: {
borderDistance: 1,
itemStyle: {
borderColor: '#1890ff',
borderWidth: 10,
},
},
itemStyle: {
opacity: 0.9,
},
backgroundStyle: {
color: '#fff',
},
label: {
show: true,
color: '#000',
insideColor: '#fff',
fontSize: 24,
fontWeight: 400,
align: 'center',
verticalAlign: 'middle',
},
},
],
})
})
</script>
<template>
<div class="grid-content knowledge-statistic" style="height: 300px">
<h1>知识点统计</h1>
<div class="box">
<div style="width: 300px; height: 250px" ref="liquidechart1"></div>
<div style="width: 300px; height: 250px" ref="liquidechart2"></div>
</div>
</div>
</template>
<style lang="scss" scoped>
.knowledge-statistic {
h1 {
padding-top: 20px;
text-align: center;
font-size: 24px;
font-weight: 700;
color: #333333ff;
}
.box {
display: flex;
justify-content: space-around;
}
}
</style>

@ -0,0 +1,89 @@
<script lang="ts" setup>
import { computed, ref } from 'vue'
interface User {
chapter: string
name: string
type: string
}
const search = ref('')
const filterTableData = computed(() =>
tableData.filter(
(data) =>
!search.value ||
data.type.toLowerCase().includes(search.value.toLowerCase()),
),
)
const handleEdit = (index: number, row: User) => {
console.log(index, row)
}
const handleDelete = (index: number, row: User) => {
console.log(index, row)
}
const tableData: User[] = [
{
chapter: '1.1课程标准',
type: 'PDF',
name: '好好学习',
},
{
chapter: '离散数学',
type: 'PPT',
name: '好好学习',
},
{
chapter: '1.1课程标准',
type: '视频',
name: '好好学习',
},
{
chapter: '1.1课程标准',
type: 'word',
name: '好好学习',
},
]
</script>
<template>
<div class="grid-content resource-management" style="height: 500px">
<h1>资源管理</h1>
<el-table :data="filterTableData" style="width: 90%; margin-left: 30px; font-size: 16px">
<el-table-column label="相关内容" prop="chapter" />
<el-table-column label="文件名称" prop="name" />
<el-table-column label="文件类型" prop="type" />
<!-- <el-table-column label="修改" prop="name" />
<el-table-column label="文件类型" prop="name" /> -->
<el-table-column align="right">
<template #header>
<el-input v-model="search" size="small" placeholder="输入内容进行搜索" />
</template>
<template #default="scope">
<el-button size="small" @click="handleEdit(scope.$index, scope.row)">
编辑
</el-button>
<el-button size="small" type="danger" @click="handleDelete(scope.$index, scope.row)">
删除
</el-button>
</template>
</el-table-column>
</el-table>
</div>
</template>
<style lang="scss" scoped>
.resource-management {
h1 {
// display: block;
padding: 20px;
text-align: center;
font-size: 24px;
font-weight: 700;
color: #333333ff;
}
// el-table {
// font-size: 20px;
// }
}
</style>

@ -28,12 +28,11 @@
<FoldAdd v-model:is-d="showHide" v-if="showHide" :data="foldInfoData" @submit="foldAddSubmit" />
<FoldEdit v-model:is-d="showHide1" v-if="showHide1" :editData="activeEditData" :data="foldInfoData"
@submit="foldEditSubmit" />
</div>
</div>
<div class="flex_right">
<div class="top-container">
<img src="" alt="">
<img src="" alt="" />
</div>
<div class="bottom-container radius-10">
<!-- 查看资源 -->
@ -84,11 +83,15 @@
</div>
</div>
</div>
<<<<<<< HEAD
</div>
=======
>>>>>>> 0b7db324dad8347654933e91ae7e6ca8d2dabd05
</template>
<script lang="ts" setup>
import {
<<<<<<< HEAD
getLearnInfoApi,
getOrogramObjectiveApi,
} from '@/api/courseChaptersApi'
@ -106,6 +109,25 @@ import {
foldInfoUi,
FoldAdd,
FoldEdit,
=======
getLearnInfoApi,
getOrogramObjectiveApi,
} from '@/api/courseChaptersApi'
import {
getChapterApi,
deleteSectionApi,
addChapterApi,
updateChapterApi,
} from '@/api/sectionApi'
import {
theoryUi,
objectiveUi,
atlasUi,
lookResourceUi,
foldInfoUi,
FoldAdd,
FoldEdit,
>>>>>>> 0b7db324dad8347654933e91ae7e6ca8d2dabd05
} from './components/KnowledgeGraphUi/index'
import { ref, reactive } from 'vue'
import { useRouter } from 'vue-router'
@ -131,15 +153,23 @@ const lookResource: any = reactive({})
// fold-info-ui
const foldInfoData: any = reactive([])
function getFold() {
<<<<<<< HEAD
getChapterApi('2fa0fd63262230639d2c45a3acd9045c').then((res) => {
foldInfoData.length = 0
foldInfoData.push(...res.data)
})
=======
getChapterApi('2fa0fd63262230639d2c45a3acd9045c').then((res) => {
foldInfoData.length = 0
foldInfoData.push(...res.data)
})
>>>>>>> 0b7db324dad8347654933e91ae7e6ca8d2dabd05
}
getFold()
//
const showHide = ref(false)
function foldAddSubmit(data: any, updLoading: Function) {
<<<<<<< HEAD
updLoading(true)
addChapterApi(data)
.then(() => {
@ -185,15 +215,50 @@ function flodDel(id: string,setLoading:Function) {
ElMessage({
message: `删除成功`,
type: 'success'
=======
updLoading(true)
addChapterApi(data)
.then(() => {
ElMessage({
message: `添加${data.pid === '' ? '章' : '节'}成功`,
type: 'success',
})
showHide.value = false
getFold()
})
getFold()
}).catch(() => {
ElMessage({
message: `删除失败`,
type: 'error'
.catch(() => {
ElMessage({
message: `添加${data.pid === '' ? '章' : '节'}失败`,
type: 'error',
})
})
.finally(() => updLoading(false))
}
//
const foldDelLoading = ref(false)
function flodDel(id: string) {
foldDelLoading.value = true
deleteSectionApi(id)
.then(() => {
ElMessage({
message: `删除成功`,
type: 'success',
})
getFold()
>>>>>>> 0b7db324dad8347654933e91ae7e6ca8d2dabd05
})
.catch(() => {
ElMessage({
message: `删除失败`,
type: 'error',
})
})
<<<<<<< HEAD
}).finally(() =>setLoading(false))
>>>>>>> d7b4e7a9c5db447232028c52d0cc49bb8a28830e
=======
.finally(() => (foldDelLoading.value = false))
>>>>>>> 0b7db324dad8347654933e91ae7e6ca8d2dabd05
}
//
const showHide1 = ref(false)
@ -203,6 +268,7 @@ function hanEdit(data: any) {
showHide1.value = true
}
function foldEditSubmit(data: any, updLoading: Function) {
<<<<<<< HEAD
updLoading(true)
updateChapterApi(data)
.then(() => {
@ -220,6 +286,25 @@ function foldEditSubmit(data: any, updLoading: Function) {
})
})
.finally(() => updLoading(false))
=======
updLoading(true)
updateChapterApi(data)
.then(() => {
ElMessage({
message: `更新${data.pid === '' ? '章' : '节'}成功`,
type: 'success',
})
showHide1.value = false
getFold()
})
.catch(() => {
ElMessage({
message: `更新${data.pid === '' ? '章' : '节'}失败`,
type: 'error',
})
})
.finally(() => updLoading(false))
>>>>>>> 0b7db324dad8347654933e91ae7e6ca8d2dabd05
}
</script>
@ -242,6 +327,10 @@ function foldEditSubmit(data: any, updLoading: Function) {
.vertical-line {
position: relative;
<<<<<<< HEAD
=======
background: #f2f7fb;
>>>>>>> 0b7db324dad8347654933e91ae7e6ca8d2dabd05
&::before {
content: '';
@ -289,6 +378,7 @@ function foldEditSubmit(data: any, updLoading: Function) {
}
}
<<<<<<< HEAD
.flex_right {
width: 355px;
@ -299,6 +389,23 @@ function foldEditSubmit(data: any, updLoading: Function) {
img {
width: 100%;
height: 100%;
=======
.radius-10 {
border-radius: 10px;
overflow: hidden;
}
.vertical-line {
position: relative;
&::before {
content: '';
display: block;
position: absolute;
height: 100%;
width: 12px;
background-color: #2147fb;
>>>>>>> 0b7db324dad8347654933e91ae7e6ca8d2dabd05
}
}
@ -306,6 +413,64 @@ function foldEditSubmit(data: any, updLoading: Function) {
min-height: 945px;
}
}
<<<<<<< HEAD
}
=======
.flex-layout {
display: flex;
justify-content: space-between;
align-items: flex-start;
.flex-left {
display: grid;
grid-template-columns: 664px 555px;
justify-content: space-between;
width: 1243px;
.left {
grid-row: 1/3;
height: 424px;
}
.right-top {
width: 100%;
height: 243px;
}
.right-bottom {
align-self: end;
width: 100%;
height: 168px;
}
.bottom {
margin-top: 15px;
grid-column: 1/3;
width: 100%;
min-width: 100%;
min-height: 521px;
}
}
.flex_right {
width: 355px;
.top-container {
height: 231px;
margin-bottom: 23px;
img {
width: 100%;
height: 100%;
}
}
.bottom-container {
min-height: 945px;
}
}
}
>>>>>>> 0b7db324dad8347654933e91ae7e6ca8d2dabd05
}
</style>

@ -0,0 +1,55 @@
<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>
<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 lang="scss" scoped>
.el-row {
// margin-bottom: 10px;
}
.el-row:last-child {
margin-bottom: 0;
}
.el-col {
border-radius: 4px;
// margin-right: 10px;
}
.grid-content {
border-radius: 6px;
margin-bottom: 20px;
background: #ffffff;
box-shadow: 0px 1px 2px 0px rgba(0, 0, 0, 0.1);
}
</style>
Loading…
Cancel
Save