courses.vue 28 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012
  1. <template>
  2. <div class="container learnstyle-page">
  3. <el-row class="grid-head">
  4. </el-row>
  5. <el-row>
  6. <div class="homewort-part">
  7. <div class="assess-tips">
  8. <div class="col-1">
  9. <!-- <el-select v-model="courseVal" placeholder="请选择课程">
  10. <el-option v-for="item in courseList" :key="item.id" :label="item.name"
  11. :value="item.id" @change="getCourseSection(courseVal)">
  12. </el-option>
  13. </el-select> -->
  14. <div style="width:100%;display: flex;justify-content: space-between;align-items: center;">
  15. <span>我的课程列表</span>
  16. <el-button type="primary" plain @click="()=>{onSelectCourse()}">选课</el-button>
  17. </div>
  18. </div>
  19. <!-- <div class="col-2"><span class="total current">全部</span><span
  20. class="total ">学习中</span><span
  21. class="total ">未学习</span><span class="total ">已完成</span></div> -->
  22. </div>
  23. <div class="list-data">
  24. <div class="list-header">
  25. <div class="top">
  26. <div class="category_name" v-if="!loading">
  27. <el-tag class="elTag" :type="currentCourse.id == course.id?'success':'info'"
  28. v-for="course in courseList" :key="`c_${course.id}`"
  29. @click="()=>{selectCourse(course)}">{{course.name}}</el-tag>
  30. </div>
  31. <div v-else style="display: flex;justify-content: center;align-items: center;">
  32. <i class="el-icon-loading"></i>
  33. </div>
  34. </div>
  35. </div>
  36. <div class="table-body" v-if="courseList.length > 0">
  37. <el-table v-loading="xloading" :data="tableData" border>
  38. <el-table-column prop="gOriented" width="350" label="导向目标">
  39. </el-table-column>
  40. <el-table-column prop="pScore" label="P(问题定义)(得分/满分)">
  41. <template slot-scope="scope">
  42. <span>{{scope.row.pScore==null?0:scope.row.pScore}}/{{stepscore['P']}}</span>
  43. </template>
  44. </el-table-column>
  45. <el-table-column prop="sScore" label="S(系统拆解)(得分/满分)">
  46. <template slot-scope="scope">
  47. <span>{{scope.row.sScore==null?0:scope.row.sScore}}/{{stepscore['S']}}</span>
  48. </template>
  49. </el-table-column>
  50. <el-table-column prop="rScore" label="R(结果整合)(得分/满分)">
  51. <template slot-scope="scope">
  52. <span>{{scope.row.rScore==null?0:scope.row.rScore}}/{{stepscore['R']}}</span>
  53. </template>
  54. </el-table-column>
  55. <el-table-column prop="eScore" label="E(评估方法)(得分/满分)">
  56. <template slot-scope="scope">
  57. <span>{{scope.row.eScore==null?0:scope.row.eScore}}/{{stepscore['E']}}</span>
  58. </template>
  59. </el-table-column>
  60. <el-table-column fixed="right" label="操作" width="100">
  61. <template slot-scope="scope">
  62. <el-button @click="handleClick(scope.row)" type="text">
  63. 学习
  64. </el-button>
  65. </template>
  66. </el-table-column>
  67. </el-table>
  68. </div>
  69. </div>
  70. </div>
  71. </el-row>
  72. <!-- <template>-->
  73. <!-- <el-dialog :visible.sync="selectCourseVisible" fullscreen top="0" custom-class="GPSREN" :close-on-click-modal="false"-->
  74. <!-- :before-close="()=>{selectCourseVisible = false;}">-->
  75. <!-- <div slot="title" class="cust-title">-->
  76. <!-- 选课-->
  77. <!-- </div>-->
  78. <!-- <el-cascader :props="cascader"></el-cascader>-->
  79. <!-- <el-transfer v-model="cascader.value" :data="cascader.data"></el-transfer>-->
  80. <!-- </el-dialog>-->
  81. <!-- </template>-->
  82. <template v-if="selectCourseVisible">
  83. <el-dialog :visible.sync="selectCourseVisible" top="0" custom-class="course-selection-dialog" :close-on-click-modal="false"
  84. :before-close="()=>{selectCourseVisible = false;courseOptions.length=0;this.getCourseList();}" width="80%">
  85. <div slot="title" class="cust-title">
  86. <i class="el-icon-collection-tag"></i> 选课中心
  87. </div>
  88. <div class="course-selection-container">
  89. <!-- 选课导航 -->
  90. <!-- <div class="selection-header">-->
  91. <!-- <div class="header-title">-->
  92. <!--&lt;!&ndash; <p>请按阶段 → 年级 → 科目顺序选择您要学习的课程</p>&ndash;&gt;-->
  93. <!-- </div>-->
  94. <!-- </div>-->
  95. <!-- 级联选择器区域 -->
  96. <div class="cascader-section">
  97. <div class="section-title">
  98. <i class="el-icon-menu"></i> 课程分类选择
  99. </div>
  100. <el-cascader
  101. :props="cascaderProps"
  102. @change="handleCascaderChange"
  103. placeholder="请选择阶段/年级/科目(例如:本科 → 2025级 → 人工智能)"
  104. style="width: 100%;"
  105. size="large"
  106. clearable>
  107. </el-cascader>
  108. </div>
  109. <!-- 课程列表区域 -->
  110. <div class="courses-section flex-column">
  111. <div class="section-title">
  112. <i class="el-icon-document"></i> 可选课程列表
  113. </div>
  114. <div v-if="courseOptions.length > 0" class="courses-table-wrapper flex-item">
  115. <el-table :data="courseOptions" border style="width: 100%" stripe
  116. v-loading="selectLoading"
  117. height="100%"
  118. :header-cell-style="{background: '#f5f7fa', fontWeight: 'bold'}"
  119. class="adaptive-table">
  120. <el-table-column prop="name" label="课程名称" width="200" fixed>
  121. <template slot-scope="scope">
  122. <span class="course-name">{{ scope.row.name }}</span>
  123. </template>
  124. </el-table-column>
  125. <el-table-column prop="description" label="课程描述" min-width="300">
  126. <template slot-scope="scope">
  127. <span class="course-description">{{ scope.row.description || '暂无描述' }}</span>
  128. </template>
  129. </el-table-column>
  130. <el-table-column label="操作" width="180" align="center" fixed="right">
  131. <template slot-scope="scope">
  132. <el-button
  133. size="small"
  134. v-if="!!scope.row.studentId"
  135. @click="addCourseToStudent(scope.row.id,0)"
  136. :type="'warning'"
  137. :icon="'el-icon-circle-close'" >
  138. 取消
  139. </el-button>
  140. <el-button
  141. size="small"
  142. v-else
  143. @click="addCourseToStudent(scope.row.id,1)"
  144. :type="'success'"
  145. :icon="'el-icon-circle-check'" >
  146. 选择
  147. </el-button>
  148. </template>
  149. </el-table-column>
  150. </el-table>
  151. </div>
  152. <div v-else class="no-courses flex-item">
  153. <el-empty description="该科目下暂无课程">
  154. </el-empty>
  155. </div>
  156. </div>
  157. </div>
  158. <!-- &lt;!&ndash; 底部提示 &ndash;&gt;-->
  159. <!-- <div slot="footer" class="dialog-footer">-->
  160. <!-- <el-button @click="selectCourseVisible = false">取消</el-button>-->
  161. <!-- <el-button type="primary" @click="confirmSelection" :disabled="!selectedSubject">确认选课</el-button>-->
  162. <!-- </div>-->
  163. </el-dialog>
  164. </template>
  165. <template v-if="dialogVisible">
  166. <el-dialog :visible.sync="dialogVisible" fullscreen top="0" custom-class="GPSREN" :close-on-click-modal="false"
  167. :before-close="handleClose">
  168. <div slot="title" class="cust-title">
  169. GPS-REN学习法
  170. </div>
  171. <Gpsren :question="currentGoal" :finish="onFinish"></Gpsren>
  172. </el-dialog>
  173. </template>
  174. </div>
  175. </template>
  176. <script>
  177. import {getStepModel} from '../../api/ai'
  178. import subjectInfo from "../../components/subject-info";
  179. import Gpsren from "../../components/gpsren.vue";
  180. export default {
  181. name: 'courseVideo',
  182. components: { subjectInfo, Gpsren },
  183. data() {
  184. return {
  185. stepscore: {
  186. "P": 0,
  187. "S":0,
  188. "R":0,
  189. "E":0
  190. },
  191. selectCourseVisible:false,
  192. xloading:false,
  193. loading: false,
  194. selectLoading:false,
  195. fileHost: this.$store.state.common.fileHost,
  196. courseList: [],
  197. learnInfo: [],
  198. gradeInfo: [],
  199. subjectInfo: [],
  200. tableData: [],
  201. currentPage: 0,
  202. courseVal: 1,
  203. pageSize: 10,
  204. totalCount: 0,
  205. options: [],
  206. dialogVisible: false,
  207. currentCourse: null,
  208. currentGoal:null,
  209. cascader:{
  210. lazy: true,
  211. lazyLoad (node, resolve) {
  212. console.log(node)
  213. if(node.level == 0) {
  214. setTimeout(() => {
  215. const nodes = [{
  216. level:1,
  217. label: `选项1`,
  218. value:1,
  219. leaf: node.level > 2
  220. },{
  221. level:1,
  222. label: `选项2`,
  223. value:2,
  224. leaf: node.level > 2
  225. }]
  226. // 通过调用resolve将子节点数据返回,通知组件数据加载完成
  227. resolve(nodes);
  228. }, 1000);
  229. }
  230. }
  231. },
  232. // 新的级联选择器配置
  233. cascaderProps: {
  234. lazy: true,
  235. lazyLoad: this.lazyLoadCascader,
  236. value: 'id',
  237. label: 'name',
  238. children: 'children',
  239. leaf: 'leaf'
  240. },
  241. // 选中的科目
  242. selectedSubject: null,
  243. // 课程选项列表
  244. courseOptions: [],
  245. // 已选课程列表
  246. selectedCourses: [],
  247. transfer:{
  248. }
  249. }
  250. },
  251. mounted() {
  252. this.setStepModel()
  253. this.getCourseList()
  254. this.getLearnList()
  255. this.getGradeList()
  256. //this.getsubjectList()
  257. this.tableData = [ ]
  258. },
  259. destroyed() {
  260. },
  261. methods: {
  262. onFinish() {
  263. this.handleClose()
  264. },
  265. getLearnList() {
  266. return this.axios.get(this.$httpApi.httpUrl('/api/dictValue/selectByDictId'), {
  267. params: {
  268. pageNumber: 0,
  269. pageSize: 100,
  270. status: 1,
  271. dictId: 1
  272. }
  273. }).then(response => {
  274. this.learnInfo = response.data.data.dataList
  275. })
  276. },
  277. // getsubjectList() {
  278. // this.axios.get(this.$httpApi.httpUrl('/student/subjectInfo/selectByGradeInfoId'), {
  279. // params: {
  280. // pageNumber: 0,
  281. // pageSize: 100,
  282. // status: 1,
  283. // }
  284. // }).then(response => {
  285. // this.subjectInfo = response.data.data.dataList
  286. // })
  287. // },
  288. getGradeList(stageId) {
  289. return this.axios.get(this.$httpApi.httpUrl('/student/gradeInfo/list'), {
  290. params: {
  291. pageNumber: 0,
  292. pageSize: 100,
  293. schoolType: stageId
  294. }
  295. }).then(response => {
  296. this.gradeInfo = response.data.data.dataList
  297. })
  298. },
  299. //选课
  300. onSelectCourse(){
  301. this.selectCourseVisible = true
  302. },
  303. // 检查课程是否已选择
  304. isSelectedCourse(courseId) {
  305. return this.selectedCourses.some(course => course.id === courseId)
  306. },
  307. // 懒加载级联选择器数据
  308. async lazyLoadCascader(node, resolve) {
  309. const { level, value } = node;
  310. try {
  311. let nodes = [];
  312. if (level === 0) {
  313. // 加载阶段数据(如本科、研究生等)
  314. nodes = await this.loadStages();
  315. } else if (level === 1) {
  316. // 加载年级数据
  317. nodes = await this.loadGrades(value);
  318. } else if (level === 2) {
  319. // 加载科目数据
  320. nodes = await this.loadSubjects(value);
  321. }
  322. resolve(nodes);
  323. } catch (error) {
  324. console.error('加载级联数据失败:', error);
  325. resolve([]);
  326. }
  327. },
  328. // 加载阶段数据 - 从learnInfo获取
  329. async loadStages() {
  330. try {
  331. // 使用已获取的learnInfo数据作为阶段数据
  332. await this.getLearnList()
  333. if (this.learnInfo && this.learnInfo.length > 0) {
  334. // 假设learnInfo中的数据结构包含id和name字段
  335. return this.learnInfo.map(item => ({
  336. id: item.code,
  337. name: item.value,
  338. leaf: false
  339. }));
  340. } else {
  341. return [
  342. { id: 1, name: '本科', leaf: false },
  343. { id: 2, name: '研究生', leaf: false },
  344. { id: 3, name: '博士', leaf: false }
  345. ];
  346. }
  347. } catch (error) {
  348. console.error('处理阶段数据失败:', error);
  349. // 出错时使用默认数据
  350. return [
  351. { id: 1, name: '本科', leaf: false },
  352. { id: 2, name: '研究生', leaf: false },
  353. { id: 3, name: '博士', leaf: false }
  354. ];
  355. }
  356. },
  357. // 加载年级数据 - 从gradeInfo获取
  358. async loadGrades(stageId) {
  359. try {
  360. // 使用已获取的gradeInfo数据作为年级数据
  361. await this.getGradeList(stageId)
  362. if ((this.gradeInfo && this.gradeInfo.length > 0)) {
  363. // 过滤出对应阶段的年级数据
  364. const filteredGrades = this.gradeInfo.filter(item => {
  365. // 假设gradeInfo中有stageId字段来关联阶段
  366. return item.schoolType === stageId;
  367. });
  368. // 将数据映射为级联选择器需要的格式
  369. return filteredGrades.map(item => ({
  370. id: item.id,
  371. name: item.name,
  372. leaf: false
  373. }));
  374. } else {
  375. // 如果gradeInfo为空,使用默认数据
  376. const grades = {
  377. 1: [ // 本科阶段的年级
  378. { id: 101, name: '2025级', leaf: false },
  379. { id: 102, name: '2024级', leaf: false },
  380. { id: 103, name: '2023级', leaf: false }
  381. ],
  382. 2: [ // 研究生阶段的年级
  383. { id: 201, name: '2025级', leaf: false },
  384. { id: 202, name: '2024级', leaf: false }
  385. ],
  386. 3: [ // 博士阶段的年级
  387. { id: 301, name: '2025级', leaf: false },
  388. { id: 302, name: '2024级', leaf: false }
  389. ]
  390. };
  391. return grades[stageId] || [];
  392. }
  393. } catch (error) {
  394. console.error('处理年级数据失败:', error);
  395. // 出错时使用默认数据
  396. const grades = {
  397. 1: [ // 本科阶段的年级
  398. { id: 101, name: '2025级', leaf: false },
  399. { id: 102, name: '2024级', leaf: false },
  400. { id: 103, name: '2023级', leaf: false }
  401. ],
  402. 2: [ // 研究生阶段的年级
  403. { id: 201, name: '2025级', leaf: false },
  404. { id: 202, name: '2024级', leaf: false }
  405. ],
  406. 3: [ // 博士阶段的年级
  407. { id: 301, name: '2025级', leaf: false },
  408. { id: 302, name: '2024级', leaf: false }
  409. ]
  410. };
  411. return grades[stageId] || [];
  412. }
  413. },
  414. // 加载科目数据
  415. async loadSubjects(gradeId) {
  416. // 这里应该调用实际的API获取科目数据
  417. try {
  418. // 使用已获取的gradeInfo数据作为年级数据
  419. const response = await this.axios.get(this.$httpApi.httpUrl('/student/subjectInfo/selectByGradeInfoId'), {
  420. params: {
  421. gradeInfoId: gradeId
  422. }
  423. });
  424. // 检查API响应是否成功
  425. if (response.data.success && response.data.code === 1) {
  426. // 将返回的数据映射为级联选择器需要的格式
  427. return response.data.data.map(item => ({
  428. id: item.id,
  429. name: item.name,
  430. leaf: true // 科目是最后一级,所以leaf为true
  431. }));
  432. }
  433. // 示例数据
  434. else{
  435. const subjects = {
  436. 101: [ // 2025级本科
  437. { id: 1001, name: '人工智能', leaf: true },
  438. { id: 1002, name: '计算机科学', leaf: true },
  439. { id: 1003, name: '数据科学', leaf: true }
  440. ],
  441. 102: [ // 2024级本科
  442. { id: 1004, name: '人工智能', leaf: true },
  443. { id: 1005, name: '软件工程', leaf: true }
  444. ],
  445. 201: [ // 2025级研究生
  446. { id: 2001, name: '机器学习', leaf: true },
  447. { id: 2002, name: '深度学习', leaf: true }
  448. ]
  449. };
  450. return subjects[gradeId] || [];
  451. }
  452. }catch (error) {
  453. console.error('处理科目数据失败:', error);
  454. // 出错时使用默认数据
  455. }
  456. },
  457. // 级联选择器值变化时的处理
  458. async handleCascaderChange(value) {
  459. if (value && value.length === 3) {
  460. // 选择了完整的三级结构(阶段->年级->科目)
  461. const subjectId = value[2];
  462. this.selectedSubject = subjectId;
  463. await this.loadCoursesBySubject(subjectId);
  464. } else {
  465. this.selectedSubject = null;
  466. this.courseOptions = [];
  467. }
  468. },
  469. // 根据科目加载课程
  470. // async loadCoursesBySubject(subjectId) {
  471. // try {
  472. // // 这里应该调用实际的API获取课程数据
  473. // // 示例数据
  474. // const courses = {
  475. // 1001: [ // 人工智能科目下的课程
  476. // { id: 10001, name: '机器学习基础', description: '介绍机器学习的基本概念和算法' },
  477. // { id: 10002, name: '深度学习', description: '深入学习神经网络和深度学习模型' },
  478. // { id: 10001, name: '机器学习基础', description: '介绍机器学习的基本概念和算法' },
  479. // { id: 10002, name: '深度学习', description: '深入学习神经网络和深度学习模型' },
  480. // { id: 10001, name: '机器学习基础', description: '介绍机器学习的基本概念和算法' },
  481. // { id: 10002, name: '深度学习', description: '深入学习神经网络和深度学习模型' },
  482. // { id: 10001, name: '机器学习基础', description: '介绍机器学习的基本概念和算法' },
  483. // { id: 10002, name: '深度学习', description: '深入学习神经网络和深度学习模型' }
  484. // ],
  485. // 1002: [ // 计算机科学科目下的课程
  486. // { id: 10003, name: '数据结构与算法', description: '学习基本的数据结构和算法设计' },
  487. // { id: 10004, name: '操作系统', description: '理解操作系统的基本原理' }
  488. // ]
  489. // };
  490. //
  491. // this.courseOptions = courses[subjectId] || [];
  492. // } catch (error) {
  493. // console.error('加载课程失败:', error);
  494. // this.courseOptions = [];
  495. // }
  496. // },
  497. // 根据科目加载课程
  498. async loadCoursesBySubject(subjectId) {
  499. try {
  500. // 调用实际的API获取课程数据
  501. this.axios.get(this.$httpApi.httpUrl('/student/courseInfo/list'), {
  502. params: {
  503. subjectId: subjectId, // 添加科目ID作为筛选条件
  504. pageNumber: 0,
  505. pageSize: 100,
  506. status: 1
  507. }
  508. }).then(response=>{
  509. // 检查API响应是否成功
  510. if (response.data.success && response.data.code === 1) {
  511. // 将返回的数据映射为表格需要的格式
  512. this.courseOptions = response.data.data.dataList.map(item => ({
  513. id: item.id,
  514. name: item.name,
  515. studentId: item.studentId,
  516. description: item.description || '暂无描述'
  517. })) || [];
  518. } else {
  519. console.error('获取课程数据失败:', response.data.message);
  520. this.courseOptions = [];
  521. }
  522. })
  523. } catch (error) {
  524. console.error('加载课程失败:', error);
  525. this.courseOptions = [];
  526. }
  527. },
  528. // 选择课程选项
  529. selectCourseOption(course) {
  530. // 检查是否已选择
  531. if (this.isSelectedCourse(course.id)) {
  532. this.$message.info('该课程已选择')
  533. return
  534. }
  535. // 这里处理选择课程的逻辑
  536. console.log('选择了课程:', course)
  537. // 可以调用API将课程添加到学生的课程列表中
  538. // this.addCourseToStudent(course.id)
  539. // 添加到已选课程列表
  540. this.selectedCourses.push({
  541. id: course.id,
  542. name: course.name
  543. })
  544. // 关闭选课对话框
  545. this.selectCourseVisible = false
  546. // 刷新课程列表
  547. this.getCourseList()
  548. this.$message.success(`成功选择课程: ${course.name}`)
  549. },
  550. // 添加课程到学生课程列表(需要实现实际的API调用)
  551. async addCourseToStudent(courseId,selected) {
  552. try {
  553. // 调用API添加课程
  554. this.selectLoading = true
  555. this.axios.post(this.$httpApi.httpUrl('/student/course/collect'), { courseId:courseId,collectFlag:selected }).then(d=>{
  556. return this.loadCoursesBySubject(this.selectedSubject);
  557. }).finally(()=>{
  558. this.selectLoading = false
  559. })
  560. } catch (error) {
  561. console.error('添加课程失败:', error);
  562. this.$message.error('选课失败,请重试');
  563. }
  564. },
  565. //关闭学习界面
  566. handleClose() {
  567. this.dialogVisible = false
  568. this.currentGoal = null
  569. },
  570. //点击打开
  571. handleClick(item) {
  572. this.dialogVisible = true
  573. this.currentGoal = item
  574. },
  575. //加载
  576. getGoalInfoByCourse(courseId) {
  577. this.xloading = true
  578. this.axios.get(this.$httpApi.httpUrl(`/student/stuGoalInfo/listByCourseId`), {
  579. params: {
  580. pageNumber: this.currentPage,
  581. pageSize: this.pageSize,
  582. courseId:courseId
  583. }
  584. }).then(goals=>{
  585. this.tableData = goals.data.data.dataList || []
  586. }).finally(f => {
  587. this.xloading = false
  588. })
  589. },
  590. selectCourse(c) {
  591. //选择课程,查询课程目标列表
  592. this.currentCourse.checked = false
  593. this.currentCourse = c
  594. this.currentCourse.checked = true
  595. getStepModel().then(resp=>{
  596. if(resp.status == 200) {
  597. let res = resp.data
  598. if(res.code == 1) {
  599. let stepModels = res.data.dataList
  600. for(let n =0 ;n<stepModels.length;n++) {
  601. let m = stepModels[n]
  602. this.stepscore[m.name] = m.score
  603. }
  604. }
  605. }
  606. }).finally(d=>{
  607. this.getGoalInfoByCourse(this.currentCourse.id)
  608. })
  609. },
  610. setStepModel(){
  611. getStepModel().then(resp=>{
  612. if(resp.status == 200) {
  613. let res = resp.data
  614. if(res.code == 1) {
  615. let stepModels = res.data.dataList
  616. for(let n =0 ;n<stepModels.length;n++) {
  617. let m = stepModels[n]
  618. this.stepscore[m.name] = m.score
  619. }
  620. }
  621. }
  622. }).finally(d=>{
  623. this.getGoalInfoByCourse(this.currentCourse.id)
  624. })
  625. },
  626. getCourseList() {
  627. this.loading = true
  628. this.axios.get(this.$httpApi.httpUrl('/student/courseInfo/mylist'), {
  629. }).then(response => {
  630. this.courseList = response.data.data
  631. if (this.courseList && this.courseList.length > 0) {
  632. this.currentCourse = this.courseList[0]
  633. this.currentCourse.checked = true
  634. }
  635. // this.totalCount = response.data.data.total
  636. }).then(d => {
  637. if(!!this.currentCourse) {
  638. this.getGoalInfoByCourse(this.currentCourse.id)
  639. }
  640. }).finally(()=>{
  641. this.loading = false
  642. })
  643. },
  644. studyCourse(course) {
  645. this.$store.commit('course/updateCourseInfo', course)
  646. this.$router.push({
  647. name: 'courseDetail',
  648. })
  649. }
  650. }
  651. }
  652. </script>
  653. <style lang="scss">
  654. .el-dialog__header {
  655. background-color: #477efa !important;
  656. color: aliceblue !important;
  657. }
  658. .el-dialog__close {
  659. color: aliceblue !important;
  660. }
  661. .course-selection-dialog {
  662. height: calc(100% - 50px);
  663. display: flex;
  664. flex-direction: column;
  665. .el-dialog__body {
  666. flex: 1;
  667. overflow-y: hidden;
  668. padding: 10px 20px 20px;
  669. }
  670. }
  671. .course-selection-container {
  672. height: calc(100vh - 150px); // 减去对话框标题和其他元素的高度
  673. display: flex;
  674. flex-direction: column;
  675. overflow: hidden;
  676. padding: 20px;
  677. max-width: 1200px;
  678. margin: 0 auto;
  679. }
  680. .flex-column {
  681. display: flex;
  682. flex-direction: column;
  683. }
  684. .flex-item {
  685. flex: 1;
  686. min-height: 0; // 允许项目收缩
  687. }
  688. .selection-header {
  689. flex-shrink: 0; // 不收缩
  690. text-align: center;
  691. margin-bottom: 20px;
  692. padding-bottom: 15px;
  693. border-bottom: 1px solid #eee;
  694. .header-title {
  695. h2 {
  696. color: #303133;
  697. margin-bottom: 8px;
  698. font-size: 20px;
  699. }
  700. p {
  701. color: #909399;
  702. font-size: 14px;
  703. }
  704. }
  705. }
  706. .cascader-section {
  707. flex-shrink: 0; // 不收缩
  708. margin-bottom: 20px;
  709. padding: 15px;
  710. background: #f5f7fa;
  711. border-radius: 8px;
  712. }
  713. .courses-section {
  714. flex: 1; // 占据剩余空间
  715. min-height: 0; // 允许收缩
  716. display: flex;
  717. flex-direction: column;
  718. padding: 15px;
  719. background: #fff;
  720. border-radius: 8px;
  721. box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
  722. overflow: hidden;
  723. }
  724. .section-title {
  725. font-size: 18px;
  726. font-weight: 500;
  727. color: #606266;
  728. margin-bottom: 15px;
  729. display: flex;
  730. align-items: center;
  731. i {
  732. margin-right: 8px;
  733. color: #409EFF;
  734. }
  735. }
  736. .courses-table-wrapper {
  737. flex: 1;
  738. min-height: 0;
  739. display: flex;
  740. flex-direction: column;
  741. overflow: hidden;
  742. border: 1px solid #ebeef5;
  743. border-radius: 4px;
  744. .adaptive-table {
  745. flex: 1;
  746. min-height: 0;
  747. .el-table__header-wrapper {
  748. flex-shrink: 0;
  749. }
  750. .el-table__body-wrapper {
  751. flex: 1;
  752. min-height: 0;
  753. overflow-y: auto;
  754. overflow-x: hidden;
  755. }
  756. }
  757. }
  758. // 表格滚动条美化
  759. .courses-table-wrapper .el-table__body-wrapper::-webkit-scrollbar {
  760. width: 6px;
  761. height: 6px;
  762. }
  763. .courses-table-wrapper .el-table__body-wrapper::-webkit-scrollbar-track {
  764. background: #f1f1f1;
  765. border-radius: 3px;
  766. }
  767. .courses-table-wrapper .el-table__body-wrapper::-webkit-scrollbar-thumb {
  768. background: #c1c1c1;
  769. border-radius: 3px;
  770. }
  771. .courses-table-wrapper .el-table__body-wrapper::-webkit-scrollbar-thumb:hover {
  772. background: #a8a8a8;
  773. }
  774. .no-courses {
  775. flex: 1;
  776. display: flex;
  777. align-items: center;
  778. justify-content: center;
  779. }
  780. .course-name {
  781. font-weight: 500;
  782. color: #303133;
  783. }
  784. .course-description {
  785. color: #606266;
  786. font-size: 14px;
  787. }
  788. .no-courses {
  789. text-align: center;
  790. padding: 40px 0;
  791. }
  792. .dialog-footer {
  793. text-align: right;
  794. padding: 20px;
  795. border-top: 1px solid #eee;
  796. }
  797. .homewort-part {
  798. .assess-tips {
  799. background-color: aliceblue;
  800. border-radius: 5px;
  801. padding: 10px;
  802. }
  803. }
  804. .list-data {
  805. .list-header {
  806. .top {
  807. margin-top: 10px;
  808. padding: 10px;
  809. font-size: 14px;
  810. }
  811. }
  812. }
  813. .category_name {
  814. display: flex;
  815. justify-content: flex-start;
  816. gap: 10px;
  817. flex-wrap: wrap;
  818. }
  819. .elTag {
  820. cursor: pointer;
  821. }
  822. .learnstyle-page {
  823. // background-color: aliceblue;
  824. height: 100%;
  825. max-width: 1200px;
  826. }
  827. .demoList ul {
  828. width: 100%;
  829. box-sizing: border-box;
  830. margin-bottom: 100px;
  831. }
  832. .demoList {
  833. padding-top: 30px;
  834. }
  835. .course_detail {
  836. padding-top: 6px;
  837. max-height: 48px;
  838. line-height: 20px;
  839. display: -webkit-box;
  840. -webkit-line-clamp: 2;
  841. -webkit-box-orient: vertical;
  842. overflow: hidden;
  843. font-size: 14px;
  844. color: #93999f
  845. }
  846. .demoList li {
  847. box-sizing: border-box;
  848. width: 192px;
  849. min-height: 160px;
  850. float: left;
  851. margin-right: 40px;
  852. margin-bottom: 30px;
  853. text-align: left;
  854. img {
  855. cursor: pointer;
  856. width: 100%;
  857. height: 108px;
  858. display: block;
  859. border-radius: 8px;
  860. &:hover {
  861. opacity: 0.7;
  862. }
  863. }
  864. }
  865. .typeitem {
  866. cursor: pointer;
  867. width: 300px;
  868. .title {
  869. padding-top: 8px;
  870. font-weight: bold;
  871. &:hover {
  872. cursor: pointer;
  873. color: red;
  874. }
  875. }
  876. }
  877. .demoList li {
  878. width: 30%;
  879. }
  880. .demoList .page {
  881. position: relative;
  882. left: 0;
  883. bottom: 50px;
  884. width: 100%;
  885. text-align: center;
  886. }
  887. .demoList li .image {
  888. height: 199px;
  889. width: 100%;
  890. display: block;
  891. }
  892. .top .item {
  893. margin-left: 20px;
  894. }
  895. .grid-head {
  896. margin-bottom: 30px;
  897. }
  898. .col-1 {
  899. width: 100%;
  900. color: #999;
  901. }
  902. </style>