马晓春 知识点学习

develoop
aaaa 6 months ago
commit e44c4d5588
  1. 13
      mock/user.ts
  2. 3
      package.json
  3. 240
      pnpm-lock.yaml
  4. 267
      public/data.json
  5. 1744
      public/nodeList.json
  6. 29
      src/api/courseChaptersApi.ts
  7. BIN
      src/assets/images/gd (3).png
  8. BIN
      src/assets/images/minus-circle-filled.png
  9. BIN
      src/assets/images/minus-circle-filled@2x.png
  10. BIN
      src/assets/images/sjx(1).png
  11. BIN
      src/assets/images/sjx.png
  12. 2
      src/main.ts
  13. 10
      src/router/routers.ts
  14. 1
      src/views/MyCourseStudy/learningProcess.vue
  15. 153
      src/views/course/components/KnowledgeGraph.vue
  16. 275
      src/views/course/components/KnowledgeGraphUi/foldInfoUi.vue
  17. 5
      src/views/course/components/KnowledgeGraphUi/index.ts
  18. 195
      src/views/course/components/KnowledgeGraphUi/lookResourceUi.vue
  19. 96
      src/views/course/components/KnowledgeGraphUi/objectiveUi.vue
  20. 116
      src/views/course/components/KnowledgeGraphUi/theoryUi.vue
  21. 50
      src/views/course/components/atlasUi.vue
  22. 149
      src/views/course/courseChapters.vue
  23. 14
      src/views/course/knowledgeAtlas.vue
  24. 468
      src/views/course/spritetext.js
  25. 184
      src/views/portal/LearningPathRecommendations.vue
  26. 151
      src/views/portal/components/KnowledgeGraph.vue
  27. 221
      src/views/portal/index.vue
  28. 840
      src/views/portal/knowledgePointLearning.vue
  29. 13
      vite.config.ts

@ -10,18 +10,7 @@ function createUserList() {
desc: '平台管理员',
roles: ['平台管理员'],
buttons: ['cuser.detail'],
routes: [
'Home',
'Course',
'Student',
'Group',
'Message',
'BasicCourseInformation',
'CourseObjectives',
'CourseChapters',
'KnowledgePoints',
'CurriculumMap',
], //老师权限
routes: ['Home', 'Course', 'Student', 'Group', 'Message','BasicCourseInformation','CourseObjectives','CourseChapters','KnowledgePoints','CurriculumMap','knowledgeAtlas'], //老师权限
token: 'Admin Token',
},
{

@ -17,14 +17,17 @@
"preinstall": "node ./scripts/preinstall.js"
},
"dependencies": {
"3d-force-graph": "^1.73.3",
"@element-plus/icons-vue": "^2.3.1",
"@vueuse/core": "^10.9.0",
"axios": "^1.6.8",
"echarts": "^5.5.0",
"echarts-liquidfill": "^3.1.0",
"element-plus": "^2.6.0",
"jquery": "^3.7.1",
"nprogress": "^0.2.0",
"pinia": "^2.1.7",
"three": "^0.163.0",
"vue": "^3.4.19",
"vue-echarts": "^6.7.2",
"vue-router": "^4.3.0"

@ -1,6 +1,9 @@
lockfileVersion: '6.0'
dependencies:
3d-force-graph:
specifier: ^1.73.3
version: 1.73.3
'@element-plus/icons-vue':
specifier: ^2.3.1
version: 2.3.1(vue@3.4.19)
@ -13,6 +16,9 @@ dependencies:
echarts:
specifier: ^5.5.0
version: 5.5.0
echarts-liquidfill:
specifier: ^3.1.0
version: 3.1.0(echarts@5.5.0)
element-plus:
specifier: ^2.6.0
version: 2.6.0(vue@3.4.19)
@ -25,6 +31,9 @@ dependencies:
pinia:
specifier: ^2.1.7
version: 2.1.7(typescript@5.2.2)(vue@3.4.19)
three:
specifier: ^0.163.0
version: 0.163.0
vue:
specifier: ^3.4.19
version: 3.4.19(typescript@5.2.2)
@ -132,6 +141,17 @@ devDependencies:
packages:
/3d-force-graph@1.73.3:
resolution: {integrity: sha512-azb65Lwn2yr/fJ4+qrxjmstVxogjzwJIZL/fdboCKBg6ph/FLW+xdvYFEBZW92XxBn1C8yRKS3d2VkVT3BzLSw==}
engines: {node: '>=12'}
dependencies:
accessor-fn: 1.5.0
kapsule: 1.14.5
three: 0.163.0
three-forcegraph: 1.41.14(three@0.163.0)
three-render-objects: 1.29.4(three@0.163.0)
dev: false
/@aashutoshrathi/word-wrap@1.2.6:
resolution: {integrity: sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==}
engines: {node: '>=0.10.0'}
@ -311,6 +331,13 @@ packages:
dependencies:
'@babel/types': 7.24.0
/@babel/runtime@7.24.6:
resolution: {integrity: sha512-Ja18XcETdEl5mzzACGd+DKgaGJzPTCow7EglgwTmHdwokzDFYh/MHua6lU6DV/hjF2IaOJ4oX2nqnjG7RElKOw==}
engines: {node: '>=6.9.0'}
dependencies:
regenerator-runtime: 0.14.1
dev: false
/@babel/template@7.24.0:
resolution: {integrity: sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==}
engines: {node: '>=6.9.0'}
@ -853,6 +880,10 @@ packages:
engines: {node: '>=10.13.0'}
dev: true
/@tweenjs/tween.js@23.1.2:
resolution: {integrity: sha512-kMCNaZCJugWI86xiEHaY338CU5JpD0B97p1j1IKNn/Zto8PgACjQx0UxbHjmOcLl/dDOBnItwD07KmCs75pxtQ==}
dev: false
/@types/estree@1.0.5:
resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==}
dev: true
@ -1228,6 +1259,11 @@ packages:
- vue
dev: false
/accessor-fn@1.5.0:
resolution: {integrity: sha512-dml7D96DY/K5lt4Ra2jMnpL9Bhw5HEGws4p1OAIxFFj9Utd/RxNfEO3T3f0QIWFNwQU7gNxH9snUfqF/zNkP/w==}
engines: {node: '>=12'}
dev: false
/acorn-jsx@5.3.2(acorn@8.11.3):
resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
peerDependencies:
@ -1800,6 +1836,104 @@ packages:
/csstype@3.1.3:
resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
/d3-array@3.2.4:
resolution: {integrity: sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==}
engines: {node: '>=12'}
dependencies:
internmap: 2.0.3
dev: false
/d3-binarytree@1.0.2:
resolution: {integrity: sha512-cElUNH+sHu95L04m92pG73t2MEJXKu+GeKUN1TJkFsu93E5W8E9Sc3kHEGJKgenGvj19m6upSn2EunvMgMD2Yw==}
dev: false
/d3-color@3.1.0:
resolution: {integrity: sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==}
engines: {node: '>=12'}
dev: false
/d3-dispatch@3.0.1:
resolution: {integrity: sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==}
engines: {node: '>=12'}
dev: false
/d3-force-3d@3.0.5:
resolution: {integrity: sha512-tdwhAhoTYZY/a6eo9nR7HP3xSW/C6XvJTbeRpR92nlPzH6OiE+4MliN9feuSFd0tPtEUo+191qOhCTWx3NYifg==}
engines: {node: '>=12'}
dependencies:
d3-binarytree: 1.0.2
d3-dispatch: 3.0.1
d3-octree: 1.0.2
d3-quadtree: 3.0.1
d3-timer: 3.0.1
dev: false
/d3-format@3.1.0:
resolution: {integrity: sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==}
engines: {node: '>=12'}
dev: false
/d3-interpolate@3.0.1:
resolution: {integrity: sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==}
engines: {node: '>=12'}
dependencies:
d3-color: 3.1.0
dev: false
/d3-octree@1.0.2:
resolution: {integrity: sha512-Qxg4oirJrNXauiuC94uKMbgxwnhdda9xRLl9ihq45srlJ4Ga3CSgqGcAL8iW7N5CIv4Oz8x3E734ulxyvHPvwA==}
dev: false
/d3-quadtree@3.0.1:
resolution: {integrity: sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==}
engines: {node: '>=12'}
dev: false
/d3-scale-chromatic@3.1.0:
resolution: {integrity: sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ==}
engines: {node: '>=12'}
dependencies:
d3-color: 3.1.0
d3-interpolate: 3.0.1
dev: false
/d3-scale@4.0.2:
resolution: {integrity: sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==}
engines: {node: '>=12'}
dependencies:
d3-array: 3.2.4
d3-format: 3.1.0
d3-interpolate: 3.0.1
d3-time: 3.1.0
d3-time-format: 4.1.0
dev: false
/d3-time-format@4.1.0:
resolution: {integrity: sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==}
engines: {node: '>=12'}
dependencies:
d3-time: 3.1.0
dev: false
/d3-time@3.1.0:
resolution: {integrity: sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==}
engines: {node: '>=12'}
dependencies:
d3-array: 3.2.4
dev: false
/d3-timer@3.0.1:
resolution: {integrity: sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==}
engines: {node: '>=12'}
dev: false
/data-joint@1.3.1:
resolution: {integrity: sha512-tMK0m4OVGqiA3zkn8JmO6YAqD8UwJqIAx4AAwFl1SKTtKAqcXePuT+n2aayiX9uITtlN3DFtKKTOxJRUc2+HvQ==}
engines: {node: '>=12'}
dependencies:
index-array-by: 1.4.1
dev: false
/dayjs@1.11.10:
resolution: {integrity: sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==}
dev: false
@ -1991,6 +2125,14 @@ packages:
domhandler: 5.0.3
dev: true
/echarts-liquidfill@3.1.0(echarts@5.5.0):
resolution: {integrity: sha512-5Dlqs/jTsdTUAsd+K5LPLLTgrbbNORUSBQyk8PSy1Mg2zgHDWm83FmvA4s0ooNepCJojFYRITTQ4GU1UUSKYLw==}
peerDependencies:
echarts: ^5.0.1
dependencies:
echarts: 5.5.0
dev: false
/echarts@5.5.0:
resolution: {integrity: sha512-rNYnNCzqDAPCr4m/fqyUFv7fD9qIsd50S6GDFgO1DxZhncCsNsG7IfUlAlvZe5oSEQxtsjnHiUuppzccry93Xw==}
dependencies:
@ -2983,6 +3125,11 @@ packages:
engines: {node: '>=0.8.19'}
dev: true
/index-array-by@1.4.1:
resolution: {integrity: sha512-Zu6THdrxQdyTuT2uA5FjUoBEsFHPzHcPIj18FszN6yXKHxSfGcR4TPLabfuT//E25q1Igyx9xta2WMvD/x9P/g==}
engines: {node: '>=12'}
dev: false
/inflight@1.0.6:
resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==}
dependencies:
@ -3007,6 +3154,11 @@ packages:
side-channel: 1.0.6
dev: true
/internmap@2.0.3:
resolution: {integrity: sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==}
engines: {node: '>=12'}
dev: false
/is-accessor-descriptor@1.0.1:
resolution: {integrity: sha512-YBUanLI8Yoihw923YeFUS5fs0fF2f5TSFTNiYAAzhhDscDa3lEqYuz1pDOEP5KvX94I9ey3vsqjJcLVFVU+3QA==}
engines: {node: '>= 0.10'}
@ -3308,6 +3460,13 @@ packages:
graceful-fs: 4.2.11
dev: true
/kapsule@1.14.5:
resolution: {integrity: sha512-H0iSpTynUzZw3tgraDmReprpFRmH5oP5GPmaNsurSwLx2H5iCpOMIkp5q+sfhB4Tz/UJd1E1IbEE9Z6ksnJ6RA==}
engines: {node: '>=12'}
dependencies:
lodash-es: 4.17.21
dev: false
/keyv@4.5.4:
resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==}
dependencies:
@ -3583,6 +3742,32 @@ packages:
resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==}
dev: true
/ngraph.events@1.2.2:
resolution: {integrity: sha512-JsUbEOzANskax+WSYiAPETemLWYXmixuPAlmZmhIbIj6FH/WDgEGCGnRwUQBK0GjOnVm8Ui+e5IJ+5VZ4e32eQ==}
dev: false
/ngraph.forcelayout@3.3.1:
resolution: {integrity: sha512-MKBuEh1wujyQHFTW57y5vd/uuEOK0XfXYxm3lC7kktjJLRdt/KEKEknyOlc6tjXflqBKEuYBBcu7Ax5VY+S6aw==}
dependencies:
ngraph.events: 1.2.2
ngraph.merge: 1.0.0
ngraph.random: 1.1.0
dev: false
/ngraph.graph@20.0.1:
resolution: {integrity: sha512-VFsQ+EMkT+7lcJO1QP8Ik3w64WbHJl27Q53EO9hiFU9CRyxJ8HfcXtfWz/U8okuoYKDctbciL6pX3vG5dt1rYA==}
dependencies:
ngraph.events: 1.2.2
dev: false
/ngraph.merge@1.0.0:
resolution: {integrity: sha512-5J8YjGITUJeapsomtTALYsw7rFveYkM+lBj3QiYZ79EymQcuri65Nw3knQtFxQBU1r5iOaVRXrSwMENUPK62Vg==}
dev: false
/ngraph.random@1.1.0:
resolution: {integrity: sha512-h25UdUN/g8U7y29TzQtRm/GvGr70lK37yQPvPKXXuVfs7gCm82WipYFZcksQfeKumtOemAzBIcT7lzzyK/edLw==}
dev: false
/node-releases@2.0.14:
resolution: {integrity: sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==}
dev: true
@ -3809,6 +3994,13 @@ packages:
vue-demi: 0.14.7(vue@3.4.19)
dev: false
/polished@4.3.1:
resolution: {integrity: sha512-OBatVyC/N7SCW/FaDHrSd+vn0o5cS855TOmYi4OkdWUMSJCET/xip//ch8xGUvtr3i44X9LVyWwQlRMTN3pwSA==}
engines: {node: '>=10'}
dependencies:
'@babel/runtime': 7.24.6
dev: false
/posix-character-classes@0.1.1:
resolution: {integrity: sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==}
engines: {node: '>=0.10.0'}
@ -4000,6 +4192,10 @@ packages:
picomatch: 2.3.1
dev: true
/regenerator-runtime@0.14.1:
resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==}
dev: false
/regex-not@1.0.2:
resolution: {integrity: sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==}
engines: {node: '>=0.10.0'}
@ -4707,6 +4903,46 @@ packages:
resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==}
dev: true
/three-forcegraph@1.41.14(three@0.163.0):
resolution: {integrity: sha512-W/cZElLXO0l6ffdMmDakh4bUGSYuSv/YxInOHMN9KAQgDwJ8904SOBh8qkTnGu7UPsi0mAsrUgkfViW8heloTA==}
engines: {node: '>=12'}
peerDependencies:
three: '>=0.118.3'
dependencies:
accessor-fn: 1.5.0
d3-array: 3.2.4
d3-force-3d: 3.0.5
d3-scale: 4.0.2
d3-scale-chromatic: 3.1.0
data-joint: 1.3.1
kapsule: 1.14.5
ngraph.forcelayout: 3.3.1
ngraph.graph: 20.0.1
three: 0.163.0
tinycolor2: 1.6.0
dev: false
/three-render-objects@1.29.4(three@0.163.0):
resolution: {integrity: sha512-E6YwTN5zNsaMjo/5rosgnK44b1aq//3YJGJ5BxG9t7+euRm7ZAmNX3NIqFkoDhKtFC5WLoOxZjyNoq8Uc49gaA==}
engines: {node: '>=12'}
peerDependencies:
three: '*'
dependencies:
'@tweenjs/tween.js': 23.1.2
accessor-fn: 1.5.0
kapsule: 1.14.5
polished: 4.3.1
three: 0.163.0
dev: false
/three@0.163.0:
resolution: {integrity: sha512-HlMgCb2TF/dTLRtknBnjUTsR8FsDqBY43itYop2+Zg822I+Kd0Ua2vs8CvfBVefXkBdNDrLMoRTGCIIpfCuDew==}
dev: false
/tinycolor2@1.6.0:
resolution: {integrity: sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==}
dev: false
/to-fast-properties@2.0.0:
resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==}
engines: {node: '>=4'}
@ -5175,3 +5411,7 @@ packages:
dependencies:
tslib: 2.3.0
dev: false
settings:
autoInstallPeers: true
excludeLinksFromLockfile: false

@ -0,0 +1,267 @@
{
"nodes": [
{ "id": "node1", "label": "计算机", "color": "#4682B4", "classID": 0 },
{
"id": "node2",
"label": "前端",
"color": "rgba(254, 241, 0, 1)",
"classID": 1
},
{
"id": "node3",
"label": "js",
"color": "rgba(239, 242, 18, 1)",
"classID": 2
},
{
"id": "node4",
"label": "html",
"color": "rgba(230, 234, 10, 1)",
"classID": 3
},
{
"id": "node5",
"label": "css",
"color": "rgba(244, 231, 0, 1)",
"classID": 4
},
{
"id": "node6",
"label": "less",
"color": "rgba(15, 245, 57, 1)",
"classID": 5
},
{
"id": "node7",
"label": "scss",
"color": "rgba(133, 255, 11, 1)",
"classID": 6
},
{
"id": "node8",
"label": "VUE",
"color": "rgba(42, 255, 0, 1)",
"classID": 7
},
{
"id": "node9",
"label": "React",
"color": "rgba(76, 73, 245, 1)",
"classID": 8
},
{ "id": "node10", "label": "模块化", "color": "#4682B4", "classID": 9 },
{ "id": "node11", "label": "webpack", "color": "#4682B4", "classID": 10 },
{ "id": "node12", "label": "vite", "color": "#4682B4", "classID": 11 },
{
"id": "node13",
"label": "uniapp",
"color": "rgba(77, 255, 0, 1)",
"classID": 12
},
{
"id": "node14",
"label": "element",
"color": "rgba(33, 162, 255, 1)",
"classID": 13
},
{
"id": "node15",
"label": "web3",
"color": "rgba(255, 0, 251, 1)",
"classID": 14
},
{
"id": "node16",
"label": "webGl",
"color": "rgba(208, 0, 249, 1)",
"classID": 15
},
{
"id": "node17",
"label": "three",
"color": "rgba(225, 0, 255, 1)",
"classID": 16
},
{
"id": "node18",
"label": "后端",
"color": "rgba(0, 229, 255, 1)",
"classID": 17
},
{
"id": "node19",
"label": "java",
"color": "rgba(237, 229, 85, 1)",
"classID": 18
},
{
"id": "node20",
"label": "PHP",
"color": "rgba(195, 206, 215, 1)",
"classID": 19
},
{
"id": "node21",
"label": "Go",
"color": "rgba(255, 0, 0, 1)",
"classID": 20
},
{
"id": "node22",
"label": "Python",
"color": "rgba(109, 238, 180, 1)",
"classID": 21
},
{ "id": "node23", "label": "MySQL", "color": "#4682B4", "classID": 22 },
{
"id": "node24",
"label": "人工智能",
"color": "rgba(180, 5, 255, 1)",
"classID": 23
},
{
"id": "node25",
"label": "python",
"color": "rgba(255, 8, 8, 1)",
"classID": 24
},
{
"id": "node26",
"label": "AI模型",
"color": "rgba(10, 138, 244, 1)",
"classID": 25
},
{
"id": "node27",
"label": "Spring Framework",
"color": "rgba(242, 238, 14, 1)",
"classID": 26
},
{
"id": "node28",
"label": "Hibernate",
"color": "rgba(242, 238, 14, 1)",
"classID": 27
},
{
"id": "node29",
"label": "Spring MVC",
"color": "rgba(242, 238, 14, 1)",
"classID": 28
},
{
"id": "node30",
"label": "Gin",
"color": "rgba(255, 0, 0, 1)",
"classID": 29
},
{
"id": "node31",
"label": "Echo",
"color": "rgba(255, 0, 0, 1)",
"classID": 30
},
{
"id": "node32",
"label": "Beego",
"color": "rgba(255, 8, 0, 1)",
"classID": 31
},
{
"id": "node33",
"label": "Laravel",
"color": "rgba(200, 209, 217, 1)",
"classID": 32
},
{
"id": "node34",
"label": "Symfony",
"color": "rgba(182, 194, 204, 1)",
"classID": 33
},
{
"id": "node35",
"label": "CodeIgniter",
"color": "rgba(188, 197, 204, 1)",
"classID": 34
},
{
"id": "node36",
"label": "Django",
"color": "rgba(36, 245, 144, 1)",
"classID": 35
},
{
"id": "node37",
"label": "Flask",
"color": "rgba(41, 244, 176, 1)",
"classID": 36
},
{
"id": "node38",
"label": "FastAPI",
"color": "rgba(58, 244, 142, 1)",
"classID": 37
}
],
"links": [
{ "source": "node2", "target": "node3", "label": "", "classID": 0 },
{ "source": "node2", "target": "node5", "label": "", "classID": 1 },
{ "source": "node2", "target": "node4", "label": "", "classID": 2 },
{ "source": "node1", "target": "node2", "label": "前端方向", "classID": 3 },
{ "source": "node5", "target": "node6", "label": "", "classID": 4 },
{ "source": "node5", "target": "node7", "label": "", "classID": 5 },
{ "source": "node3", "target": "node8", "label": "", "classID": 6 },
{ "source": "node3", "target": "node9", "label": "", "classID": 7 },
{ "source": "node3", "target": "node10", "label": "", "classID": 8 },
{ "source": "node10", "target": "node11", "label": "", "classID": 9 },
{ "source": "node10", "target": "node12", "label": "", "classID": 10 },
{ "source": "node11", "target": "node9", "label": "", "classID": 11 },
{ "source": "node11", "target": "node8", "label": "", "classID": 12 },
{ "source": "node12", "target": "node8", "label": "", "classID": 13 },
{ "source": "node8", "target": "node13", "label": "", "classID": 14 },
{ "source": "node8", "target": "node14", "label": "", "classID": 15 },
{ "source": "node11", "target": "node13", "label": "", "classID": 16 },
{ "source": "node12", "target": "node13", "label": "", "classID": 17 },
{ "source": "node2", "target": "node15", "label": "", "classID": 18 },
{ "source": "node15", "target": "node16", "label": "", "classID": 19 },
{ "source": "node16", "target": "node17", "label": "", "classID": 20 },
{ "source": "node1", "target": "node1", "label": "", "classID": 21 },
{
"source": "node1",
"target": "node18",
"label": "后端方向",
"classID": 22
},
{ "source": "node18", "target": "node21", "label": "", "classID": 23 },
{ "source": "node18", "target": "node20", "label": "", "classID": 24 },
{ "source": "node18", "target": "node19", "label": "", "classID": 25 },
{ "source": "node18", "target": "node22", "label": "", "classID": 26 },
{ "source": "node22", "target": "node23", "label": "", "classID": 27 },
{ "source": "node19", "target": "node23", "label": "", "classID": 28 },
{ "source": "node20", "target": "node23", "label": "", "classID": 29 },
{ "source": "node21", "target": "node23", "label": "", "classID": 30 },
{
"source": "node1",
"target": "node24",
"label": "人工智能方向",
"classID": 31
},
{ "source": "node24", "target": "node25", "label": "", "classID": 32 },
{ "source": "node24", "target": "node26", "label": "", "classID": 33 },
{ "source": "node12", "target": "node9", "label": "", "classID": 34 },
{ "source": "node19", "target": "node27", "label": "", "classID": 35 },
{ "source": "node19", "target": "node28", "label": "", "classID": 36 },
{ "source": "node19", "target": "node29", "label": "", "classID": 37 },
{ "source": "node21", "target": "node30", "label": "", "classID": 38 },
{ "source": "node21", "target": "node31", "label": "", "classID": 39 },
{ "source": "node21", "target": "node32", "label": "", "classID": 40 },
{ "source": "node20", "target": "node33", "label": "", "classID": 41 },
{ "source": "node20", "target": "node34", "label": "", "classID": 42 },
{ "source": "node20", "target": "node35", "label": "", "classID": 43 },
{ "source": "node22", "target": "node36", "label": "", "classID": 44 },
{ "source": "node22", "target": "node37", "label": "", "classID": 45 },
{ "source": "node22", "target": "node38", "label": "", "classID": 46 }
]
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,29 @@
/**
*
* @returns
*/
export function getLearnInfoApi() {
return new Promise((resolve) => {
const data = [
{ name: '总学时', value: '36学时' },
{ name: '已分配学时', value: '20学时' },
{ name: '总学分', value: '2.0分' },
{ name: '章节数', value: '10章' },
{ name: '未分配学时', value: '' },
{ name: '知识点总数', value: '33个' },
]
setTimeout(() => resolve(data), 500 * Math.random())
})
}
/**
*
* @returns
*/
export function getOrogramObjectiveApi() {
return new Promise((resolve) => {
const data = {
con: '内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容',
}
setTimeout(() => resolve(data), 500 * Math.random())
})
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 322 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 510 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

@ -23,7 +23,7 @@ import gloablComponent from '@/components/index'
import 'echarts'
import ECharts from 'vue-echarts';
// 导入jquery
import $ from 'jquery'
// import $ from 'jquery'
app.use(gloablComponent)
// 注册仓库
app.use(pinia)

@ -22,6 +22,16 @@ export const constantRoute: any = [
},
],
},
{
path: '/knowledgeAtlas',
component: () => import('@/views/course/knowledgeAtlas.vue'),
name: 'knowledgeAtlas',
meta: {
title: '知识图谱',
hidden: true,
icon: 'Notebook',
},
},
{
path: '/curriculumCenter',
redirect: '/curriculumCenter/basicCourseInformation',

@ -4,6 +4,7 @@
<script lang="ts" setup>
import {} from 'vue'
</script>
<style lang="scss" scoped></style>

@ -0,0 +1,153 @@
<template>
<div id="3d-graph"></div>
</template>
<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>
<style lang='scss' scoped>
</style>

@ -0,0 +1,275 @@
<template>
<div class="fold-info-ui">
<div class="demo-collapse">
<el-collapse class="collapse" v-model="activeNames" @change="handleChange">
<el-collapse-item v-for="item in 3" :key="item" :name="item">
<template #title>
<div class="title">
<div class="icon">
<img src="@/assets/images/minus-circle-filled.png" alt="">
</div>
<div class="index">01 /</div>
<div class="text">基本概念</div>
<div class="title-tag-box">
<div class="my-tag" type="warning">32学时</div>
<div class="my-tag">本章资源</div>
</div>
</div>
</template>
<template #default>
<div class="main-box">
<div class="left"></div>
<div class="right">
<div class="structure-item">
<div class="structure-item-titile-box" v-for="item in 3" :key="item">
<div class="titile-box-titile">
<div class="sequence">5</div>
<div class="tit-box">
<div class="tit-box-left">1.1 基本概念1</div>
<div class="tit-box-right my-tag">资源</div>
<div class="tit-box-edit">
<button class="my-button">编辑</button>
</div>
</div>
</div>
<div class="titile-box-knowledge">
<div class="my-tag">知识点1</div>
<div class="my-tag">知识点1</div>
</div>
</div>
</div>
</div>
</div>
</template>
</el-collapse-item>
</el-collapse>
</div>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
const props = defineProps(['foldInfoData'])
console.log(props.foldInfoData, '可折叠基本概念接口数据');
const activeNames = ref([1])
const handleChange = (val: string[]) => {
console.log(val)
}
</script>
<style lang="scss" scoped>
::v-deep .collapse {
border-top: none;
.el-collapse-item__header {
border-bottom: none;
}
}
.fold-info-ui {
width: 100%;
height: 100%;
padding-top: 27px;
padding-left: 61px;
background: #fff;
.demo-collapse {
$title-icon-width: 15px;
$title--icon-m-r: 34px;
$title-index-width: 60px;
.title {
display: flex;
height: 22px;
width: 100%;
align-items: center;
.icon {
line-height: 0px;
width: $title-icon-width;
height: $title-icon-width;
margin-right: $title--icon-m-r;
& img {
width: 100%;
height: 100%;
}
}
.index {
width: $title-index-width;
text-align: center;
text-wrap: nowrap;
font-weight: 400;
font-size: 32px;
color: #333333;
margin-right: 15px;
}
.text {
font-weight: bold;
font-size: 24px;
color: #333333;
}
.title-tag-box {
margin-left: auto;
margin-right: 76px;
display: flex;
column-gap: 16px;
}
}
.main-box {
width: 100%;
display: flex;
$line: 1px dashed #D9D9D9;
.left {
width: calc($title-icon-width + $title--icon-m-r + $title-index-width / 2);
border-right: $line;
}
.right {
flex-grow: 1;
.structure-item {
width: 100%;
.structure-item-titile-box {
&>* {
padding-left: 42px;
}
.titile-box-titile {
&:first-child {
margin-top: 20px;
}
position: relative;
margin-bottom: 15px;
&::before {
content: '';
display: block;
position: absolute;
left: 0;
top: 50%;
width: 30px;
border-top: $line;
}
.sequence {
$height: 33px;
width: $height;
height: $height;
position: absolute;
left: 0;
top: 50%;
transform: translate(-50%, -50%);
border-radius: 50%;
background: #FFB21E;
text-align: center;
line-height: $height;
font-weight: 400;
font-size: 15px;
color: #000000;
}
.tit-box {
height: 20px;
display: flex;
align-items: center;
gap: 17px;
.tit-box-left {
font-weight: 400;
font-size: 20px;
color: #000000;
}
// .tit-box-right {}
.tit-box-edit {
margin-left: auto;
margin-right: 72px;
}
}
}
.titile-box-knowledge {
display: flex;
margin-left: 33px;
&>* {
margin-left: 38px;
border: 1px solid #0052D9;
font-weight: bold;
font-size: 12px;
color: #0052D9;
&:first-child {
margin-left: 0;
}
}
}
}
}
}
}
}
// ===================
.my-tag {
padding: 2px 8px;
font-weight: 400;
font-size: 12px;
color: #0052D9;
line-height: 20px;
background: #F2F3FF;
cursor: pointer;
border-radius: 3px;
}
[type=warning].my-tag {
color: #E37318;
background: #FFF1E9;
}
.my-button {
all: initial;
$color-start: #52A1FF;
$color-end: #4255FF;
padding: 8px 24px;
background: linear-gradient(128deg, $color-start 0%, $color-end 100%);
box-shadow: 0px 4px 7px 0px rgba(0, 82, 255, 0.27);
border-radius: 20px;
font-weight: bold;
font-size: 16px;
color: rgba(255, 255, 255, 0.9);
line-height: 24px;
text-align: center;
cursor: pointer;
&:hover {
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%);
}
}
}
</style>

@ -0,0 +1,5 @@
export { default as theoryUi } from './theoryUi.vue'
export { default as objectiveUi } from './objectiveUi.vue'
export { default as atlasUi } from '../atlasUi.vue'
export { default as lookResourceUi } from './lookResourceUi.vue'
export { default as foldInfoUi } from './foldInfoUi.vue'

@ -0,0 +1,195 @@
<template>
<div class="look-resource-ui" ref="atlas">
<div class="head">
<div class="log"></div>
<div class="text">查看资源</div>
</div>
<div class="con" v-for="item in 5" :key="item">
<div class="chapter-box">
<div class="left">第一章</div>
<div class="right">第二小节</div>
</div>
<div class="detailedness-chapter-box">
<div class="left">
<div class="vertical-dotted-line"></div>
</div>
<div class="right">
<div class="top">知识点</div>
<div class="center">知识点详情知识点内容</div>
<div class="bottom">
<div class="img-box"></div>
<div class="info-box">
<div class="text-name">知识点清单.pdf</div>
<div class="text-size">15M</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script lang="ts" setup>
const props = defineProps(['lookResource'])
console.log(props.lookResource, '查看资源接口数据');
</script>
<style lang="scss">
.look-resource-ui {
$padding-left: 18px;
width: 100%;
height: 100%;
background-color: #fff;
padding: 24px 22px 0 $padding-left;
display: flex;
flex-direction: column;
.head {
$height: 30px;
display: flex;
margin-bottom: 32px;
.log {
width: $height;
height: $height;
background: #4782FF;
border-radius: 4px;
margin-right: 12px;
}
.text {
font-weight: bold;
font-size: 20px;
color: #333333;
line-height: $height;
}
}
.con {
&>* {
display: flex;
}
$width: 51px;
.chapter-box {
$line-height: 22px;
margin-bottom: 12px;
.left {
min-width: $width;
height: 22px;
margin-right: 16px;
font-weight: 400;
font-size: 16px;
color: #333333;
line-height: $line-height;
}
.right {
line-height: $line-height;
font-weight: 400;
font-size: 14px;
color: #9A9A9A;
}
}
.detailedness-chapter-box {
.left {
width: $width;
.vertical-dotted-line {
height: 168px;
margin-left: calc(53px - $padding-left);
border-left: 1px dotted #D9D9D9;
}
}
.right {
display: flex;
flex-direction: column;
&>* {
margin-bottom: 15px;
}
&>*:last-child {
margin-bottom: 0;
}
.top {
$height: 17px;
width: 53px;
height: $height;
line-height: $height;
text-align: center;
background: #5EE183;
border-radius: 2px;
font-weight: 400;
font-size: 12px;
color: #FFFFFF;
}
.center {
$height: 22px;
height: $height;
line-height: $height;
font-weight: 400;
font-size: 16px;
color: #333333;
}
.bottom {
width: 243px;
height: 84px;
background: rgba(255, 255, 255, 0.5);
border-radius: 4px;
border: 1px solid #D9D9D9;
cursor: pointer;
transition: .3s;
padding: 17px 0 17px 20px;
display: flex;
&:hover {
border: 1px solid #6997fa;
}
.img-box {
width: 42px;
height: 50px;
background: #4D4D4D;
margin-right: 23px;
}
.info-box {
display: flex;
flex-direction: column;
$height: 22px;
&>* {
height: $height;
line-height: $height;
}
.text-name {
font-weight: 400;
font-size: 12px;
color: #333333;
margin-bottom: 6px;
}
.text-size {
font-weight: 400;
font-size: 12px;
color: #9A9A9A;
}
}
}
}
}
}
}
</style>

@ -0,0 +1,96 @@
<template>
<div class="objective-ui">
<div class="container">
<div class="title">课程目标</div>
<button class="more btn">了解更多</button>
<div class="content">
{{ orogramObjective.con }}
</div>
</div>
</div>
</template>
<script lang="ts" setup>
defineProps(['orogramObjective'])
</script>
<style lang="scss">
.objective-ui {
$border-width: 3px;
$line-height: 17px;
width: 100%;
height: 100%;
background: #FFFFFF;
border: $border-width solid #EDEDED;
padding: calc(16px - $border-width) 0 $line-height 66px;
button {
all: initial;
}
.btn {
$background-color: #F2F3FF;
width: 64px;
height: 18px;
line-height: 18px;
text-align: center;
background-color: $background-color;
border-radius: 45px;
font-weight: 400;
font-size: 12px;
color: #0052D9;
cursor: pointer;
&:hover {
background: darken($background-color, 5%);
}
&:active {
background: darken($background-color, 10%);
}
&:disabled {
background: lighten($background-color, 20%);
}
}
.container {
$row-height: 23px;
height: 100%;
width: 443px;
display: grid;
grid-template-columns: repeat(2, auto);
grid-template-rows: $row-height 1fr;
row-gap: 25px;
.title {
font-weight: bold;
font-size: 20px;
color: #333333;
line-height: $row-height;
text-align: left;
}
.more {
justify-self: end;
}
.content {
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 5;
-webkit-box-orient: vertical;
grid-column: 1/3;
font-weight: 400;
font-size: 14px;
color: #999999;
line-height: $line-height;
text-align: left;
}
}
}
</style>

@ -0,0 +1,116 @@
<template>
<div class="theory-ui">
<div class="container">
<div class="top">
<div class="title">计算机导论</div>
<button class="my-button">导入</button>
<button class="my-button">编辑</button>
</div>
<div class="bottom">
<div class="text-container" v-for="item, index in props.learnInfo" :key="index">
<div class="text-name">{{ addUnit(item.name, ':') }}</div>
<div class="text-value">{{ item.value }}</div>
</div>
</div>
</div>
</div>
</template>
<script lang="ts" setup>
function addUnit(viewStr: string, unit: string): string {
if (viewStr) return `${viewStr}${unit}`
else return ''
}
const props = defineProps(['learnInfo'])
</script>
<style lang="scss">
.theory-ui {
width: 100%;
height: 100%;
display: flex;
background-color: #fff;
.container {
$border-width: 3px;
flex-grow: 1;
border: $border-width solid #EDEDED;
padding-top: calc(10px - $border-width);
padding-left: 61px;
display: flex;
flex-direction: column;
.top {
display: flex;
margin-top: 30px;
margin-bottom: 46px;
.my-button {
all: initial;
$color-start: #52A1FF;
$color-end: #4255FF;
padding: 8px 24px;
background: linear-gradient(128deg, $color-start 0%, $color-end 100%);
box-shadow: 0px 4px 7px 0px rgba(0, 82, 255, 0.27);
border-radius: 20px;
font-weight: bold;
font-size: 16px;
color: rgba(255, 255, 255, 0.9);
line-height: 24px;
text-align: center;
cursor: pointer;
&:hover {
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%);
}
}
&>*:first-child {
margin-right: 82px;
}
&>*:last-child {
margin-left: 20px;
}
.title {
width: 208px;
height: 34px;
font-size: 36px;
color: #5577FF;
}
}
.bottom {
display: grid;
grid-template-columns: repeat(2, 1fr);
row-gap: 15px;
.text-container {
font-weight: 400;
font-size: 15px;
color: #333333;
width: 100%;
height: 20px;
display: flex;
.text-name {
width: 93px;
}
}
}
}
}
</style>

@ -0,0 +1,50 @@
<template>
<div class="atlas-ui" ref="atlas">
<professionalProfile v-bind="atlasAttribute" />
<div class="on-off" @click="()=>$emit('hadRouter')">
<el-icon>
<Right />
</el-icon>
</div>
</div>
</template>
<script lang="ts" setup>
import { ref, reactive, onMounted } from 'vue'
import professionalProfile from './KnowledgeGraph.vue'
const $emit = defineEmits(['hadRouter'])
const atlas = ref(null)
const atlasAttribute = reactive({ width: 0, height: 0 })
onMounted(() => {
const el: HTMLElement = atlas.value!
const width = +getComputedStyle(el).width.slice(0, -2)
const height = +getComputedStyle(el).height.slice(0, -2)
atlasAttribute.width = width
atlasAttribute.height = height
})
</script>
<style lang="scss">
.atlas-ui {
width: 100%;
height: 100%;
position: relative;
overflow: hidden;
&:hover .on-off {
transform: translate(0%);
padding-right: 10px;
}
.on-off {
position: absolute;
top: 0;
right: 0;
cursor: pointer;
padding-top: 5px;
transform: translate(100%);
transition: all .3s;
}
}
</style>

@ -1,9 +1,150 @@
<template>
<div>课程章节</div>
<div class="course-chapters">
<div class="flex-layout">
<div class="flex-left">
<div class="left" ref="atlasCon">
<!-- 知识图谱 -->
<atlas-ui @hadRouter="handle" />
</div>
<div class="right-top radius-10 vertical-line">
<!-- 计算机导论 -->
<theory-ui :learnInfo="learnInfo" />
</div>
<div class="right-bottom radius-10 vertical-line">
<!-- 课程目标 -->
<objective-ui :orogramObjective="orogramObjective" />
</div>
<div class="bottom">
<!-- 可折叠基本概念 -->
<fold-info-ui :foldInfoData="foldInfoData"/>
</div>
</div>
<div class="flex_right">
<div class="top-container">
<img src="" alt="">
</div>
<div class="bottom-container radius-10">
<!-- 查看资源 -->
<look-resource-ui :lookResource="lookResource"/>
</div>
</div>
</div>
</div>
</template>
<script lang="ts" setup>
import {} from 'vue'
<script lang='ts' setup>
import { getLearnInfoApi, getOrogramObjectiveApi } from '@/api/courseChaptersApi'
import { theoryUi, objectiveUi, atlasUi, lookResourceUi,foldInfoUi } from './components/KnowledgeGraphUi/index'
import { reactive } from 'vue'
import { useRouter } from 'vue-router'
const $router = useRouter()
// atlas-ui
const handle = () => $router.push('/knowledgeAtlas')
// theory-ui
const learnInfo: object[] = reactive([])
getLearnInfoApi().then(res => learnInfo.push(...res as object[]))
// objective-ui
const orogramObjective: any = reactive({})
getOrogramObjectiveApi().then(res => Object.assign(orogramObjective, res))
// look-resource-ui
const lookResource:any = reactive({})
// fold-info-ui
const foldInfoData:any = reactive({})
</script>
<style lang="scss" scoped></style>
<style lang='scss' scoped>
.course-chapters {
width: 100%;
height: 100%;
position: relative;
background: #F2F7FB;
&,
* {
box-sizing: border-box;
}
$right-box-width: 555px;
.radius-10 {
border-radius: 10px;
overflow: hidden;
}
.vertical-line {
position: relative;
&::before {
content: '';
display: block;
position: absolute;
height: 100%;
width: 12px;
background-color: #2147FB;
}
}
.flex-layout {
display: flex;
justify-content: space-between;
align-items: flex-start;
.flex-left {
display: grid;
grid-template-columns: repeat(2, auto);
width: 1243px;
.left {
grid-row: 1/3;
width: 664px;
height: 424px;
}
.right-top {
justify-self: end;
width: $right-box-width;
height: 243px;
}
.right-bottom {
justify-self: end;
align-self: end;
width: $right-box-width;
height: 168px;
}
.bottom {
margin-top: 15px;
grid-column: 1/3;
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;
}
}
}
}
</style>

@ -0,0 +1,14 @@
<template>
<div class="knowledge-atlas">
<atlas-ui @hadRouter="handle" />
</div>
</template>
<script lang='ts' setup>
import { atlasUi } from './components/KnowledgeGraphUi/index'
import { useRouter } from 'vue-router';
const $router = useRouter()
const handle = () => $router.push('/curriculumCenter/courseChapters')
</script>
<style lang='scss' scoped></style>

@ -0,0 +1,468 @@
import { LinearFilter, Sprite, SpriteMaterial, SRGBColorSpace, Texture } from 'three';
function _callSuper(t, o, e) {
return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e));
}
function _isNativeReflectConstruct() {
try {
var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));
} catch (t) {}
return (_isNativeReflectConstruct = function () {
return !!t;
})();
}
function _iterableToArrayLimit(r, l) {
var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
if (null != t) {
var e,
n,
i,
u,
a = [],
f = !0,
o = !1;
try {
if (i = (t = t.call(r)).next, 0 === l) {
if (Object(t) !== t) return;
f = !1;
} else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0);
} catch (r) {
o = !0, n = r;
} finally {
try {
if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return;
} finally {
if (o) throw n;
}
}
return a;
}
}
function _toPrimitive(t, r) {
if ("object" != typeof t || !t) return t;
var e = t[Symbol.toPrimitive];
if (void 0 !== e) {
var i = e.call(t, r || "default");
if ("object" != typeof i) return i;
throw new TypeError("@@toPrimitive must return a primitive value.");
}
return ("string" === r ? String : Number)(t);
}
function _toPropertyKey(t) {
var i = _toPrimitive(t, "string");
return "symbol" == typeof i ? i : String(i);
}
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
function _defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor);
}
}
function _createClass(Constructor, protoProps, staticProps) {
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
if (staticProps) _defineProperties(Constructor, staticProps);
Object.defineProperty(Constructor, "prototype", {
writable: false
});
return Constructor;
}
function _inherits(subClass, superClass) {
if (typeof superClass !== "function" && superClass !== null) {
throw new TypeError("Super expression must either be null or a function");
}
subClass.prototype = Object.create(superClass && superClass.prototype, {
constructor: {
value: subClass,
writable: true,
configurable: true
}
});
Object.defineProperty(subClass, "prototype", {
writable: false
});
if (superClass) _setPrototypeOf(subClass, superClass);
}
function _getPrototypeOf(o) {
_getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) {
return o.__proto__ || Object.getPrototypeOf(o);
};
return _getPrototypeOf(o);
}
function _setPrototypeOf(o, p) {
_setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) {
o.__proto__ = p;
return o;
};
return _setPrototypeOf(o, p);
}
function _assertThisInitialized(self) {
if (self === void 0) {
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
}
return self;
}
function _possibleConstructorReturn(self, call) {
if (call && (typeof call === "object" || typeof call === "function")) {
return call;
} else if (call !== void 0) {
throw new TypeError("Derived constructors may only return object or undefined");
}
return _assertThisInitialized(self);
}
function _slicedToArray(arr, i) {
return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest();
}
function _toConsumableArray(arr) {
return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();
}
function _arrayWithoutHoles(arr) {
if (Array.isArray(arr)) return _arrayLikeToArray(arr);
}
function _arrayWithHoles(arr) {
if (Array.isArray(arr)) return arr;
}
function _iterableToArray(iter) {
if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
}
function _unsupportedIterableToArray(o, minLen) {
if (!o) return;
if (typeof o === "string") return _arrayLikeToArray(o, minLen);
var n = Object.prototype.toString.call(o).slice(8, -1);
if (n === "Object" && o.constructor) n = o.constructor.name;
if (n === "Map" || n === "Set") return Array.from(o);
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
}
function _arrayLikeToArray(arr, len) {
if (len == null || len > arr.length) len = arr.length;
for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
return arr2;
}
function _nonIterableSpread() {
throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
function _nonIterableRest() {
throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
var three = typeof window !== 'undefined' && window.THREE ? window.THREE // Prefer consumption from global THREE, if exists
: {
LinearFilter: LinearFilter,
Sprite: Sprite,
SpriteMaterial: SpriteMaterial,
SRGBColorSpace: SRGBColorSpace,
Texture: Texture
};
var _default = /*#__PURE__*/function (_three$Sprite) {
_inherits(_default, _three$Sprite);
function _default() {
var _this;
var text = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
var textHeight = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 10;
var color = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'rgba(255, 255, 255, 1)';
_classCallCheck(this, _default);
_this = _callSuper(this, _default, [new three.SpriteMaterial()]);
_this._text = "".concat(text);
_this._textHeight = textHeight;
_this._color = color;
_this._backgroundColor = false; // no background color
_this._padding = 0;
_this._borderWidth = 0;
_this._borderRadius = 0;
_this._borderColor = 'white';
_this._strokeWidth = 0;
_this._strokeColor = 'white';
_this._fontFace = 'system-ui';
_this._fontSize = 90; // defines text resolution
_this._fontWeight = 'normal';
_this._canvas = document.createElement('canvas');
_this._genCanvas();
return _this;
}
_createClass(_default, [{
key: "text",
get: function get() {
return this._text;
},
set: function set(text) {
this._text = text;
this._genCanvas();
}
}, {
key: "textHeight",
get: function get() {
return this._textHeight;
},
set: function set(textHeight) {
this._textHeight = textHeight;
this._genCanvas();
}
}, {
key: "color",
get: function get() {
return this._color;
},
set: function set(color) {
this._color = color;
this._genCanvas();
}
}, {
key: "backgroundColor",
get: function get() {
return this._backgroundColor;
},
set: function set(color) {
this._backgroundColor = color;
this._genCanvas();
}
}, {
key: "padding",
get: function get() {
return this._padding;
},
set: function set(padding) {
this._padding = padding;
this._genCanvas();
}
}, {
key: "borderWidth",
get: function get() {
return this._borderWidth;
},
set: function set(borderWidth) {
this._borderWidth = borderWidth;
this._genCanvas();
}
}, {
key: "borderRadius",
get: function get() {
return this._borderRadius;
},
set: function set(borderRadius) {
this._borderRadius = borderRadius;
this._genCanvas();
}
}, {
key: "borderColor",
get: function get() {
return this._borderColor;
},
set: function set(borderColor) {
this._borderColor = borderColor;
this._genCanvas();
}
}, {
key: "fontFace",
get: function get() {
return this._fontFace;
},
set: function set(fontFace) {
this._fontFace = fontFace;
this._genCanvas();
}
}, {
key: "fontSize",
get: function get() {
return this._fontSize;
},
set: function set(fontSize) {
this._fontSize = fontSize;
this._genCanvas();
}
}, {
key: "fontWeight",
get: function get() {
return this._fontWeight;
},
set: function set(fontWeight) {
this._fontWeight = fontWeight;
this._genCanvas();
}
}, {
key: "strokeWidth",
get: function get() {
return this._strokeWidth;
},
set: function set(strokeWidth) {
this._strokeWidth = strokeWidth;
this._genCanvas();
}
}, {
key: "strokeColor",
get: function get() {
return this._strokeColor;
},
set: function set(strokeColor) {
this._strokeColor = strokeColor;
this._genCanvas();
}
}, {
key: "_genCanvas",
value: function _genCanvas() {
var _this2 = this;
var canvas = this._canvas;
var ctx = canvas.getContext('2d');
var border = Array.isArray(this.borderWidth) ? this.borderWidth : [this.borderWidth, this.borderWidth]; // x,y border
var relBorder = border.map(function (b) {
return b * _this2.fontSize * 0.1;
}); // border in canvas units
var borderRadius = Array.isArray(this.borderRadius) ? this.borderRadius : [this.borderRadius, this.borderRadius, this.borderRadius, this.borderRadius]; // tl tr br bl corners
var relBorderRadius = borderRadius.map(function (b) {
return b * _this2.fontSize * 0.1;
}); // border radius in canvas units
var padding = Array.isArray(this.padding) ? this.padding : [this.padding, this.padding]; // x,y padding
var relPadding = padding.map(function (p) {
return p * _this2.fontSize * 0.1;
}); // padding in canvas units
var lines = this.text.split('\n');
var font = "".concat(this.fontWeight, " ").concat(this.fontSize, "px ").concat(this.fontFace);
ctx.font = font; // measure canvas with appropriate font
var innerWidth = Math.max.apply(Math, _toConsumableArray(lines.map(function (line) {
return ctx.measureText(line).width;
})));
var innerHeight = this.fontSize * lines.length;
canvas.width = innerWidth + relBorder[0] * 2 + relPadding[0] * 2;
canvas.height = innerHeight + relBorder[1] * 2 + relPadding[1] * 2;
// paint border
if (this.borderWidth) {
ctx.strokeStyle = this.borderColor;
if (relBorder[0]) {
// left + right borders
var hb = relBorder[0] / 2;
ctx.lineWidth = relBorder[0];
ctx.beginPath();
ctx.moveTo(hb, relBorderRadius[0]);
ctx.lineTo(hb, canvas.height - relBorderRadius[3]);
ctx.moveTo(canvas.width - hb, relBorderRadius[1]);
ctx.lineTo(canvas.width - hb, canvas.height - relBorderRadius[2]);
ctx.stroke();
}
if (relBorder[1]) {
// top + bottom borders
var _hb = relBorder[1] / 2;
ctx.lineWidth = relBorder[1];
ctx.beginPath();
ctx.moveTo(Math.max(relBorder[0], relBorderRadius[0]), _hb);
ctx.lineTo(canvas.width - Math.max(relBorder[0], relBorderRadius[1]), _hb);
ctx.moveTo(Math.max(relBorder[0], relBorderRadius[3]), canvas.height - _hb);
ctx.lineTo(canvas.width - Math.max(relBorder[0], relBorderRadius[2]), canvas.height - _hb);
ctx.stroke();
}
if (this.borderRadius) {
// strike rounded corners
var cornerWidth = Math.max.apply(Math, _toConsumableArray(relBorder));
var _hb2 = cornerWidth / 2;
ctx.lineWidth = cornerWidth;
ctx.beginPath();
[!!relBorderRadius[0] && [relBorderRadius[0], _hb2, _hb2, relBorderRadius[0]], !!relBorderRadius[1] && [canvas.width - relBorderRadius[1], canvas.width - _hb2, _hb2, relBorderRadius[1]], !!relBorderRadius[2] && [canvas.width - relBorderRadius[2], canvas.width - _hb2, canvas.height - _hb2, canvas.height - relBorderRadius[2]], !!relBorderRadius[3] && [relBorderRadius[3], _hb2, canvas.height - _hb2, canvas.height - relBorderRadius[3]]].filter(function (d) {
return d;
}).forEach(function (_ref) {
var _ref2 = _slicedToArray(_ref, 4),
x0 = _ref2[0],
x1 = _ref2[1],
y0 = _ref2[2],
y1 = _ref2[3];
ctx.moveTo(x0, y0);
ctx.quadraticCurveTo(x1, y0, x1, y1);
});
ctx.stroke();
}
}
// paint background
if (this.backgroundColor) {
ctx.fillStyle = this.backgroundColor;
if (!this.borderRadius) {
ctx.fillRect(relBorder[0], relBorder[1], canvas.width - relBorder[0] * 2, canvas.height - relBorder[1] * 2);
} else {
// fill with rounded corners
ctx.beginPath();
ctx.moveTo(relBorder[0], relBorderRadius[0]);
[[relBorder[0], relBorderRadius[0], canvas.width - relBorderRadius[1], relBorder[1], relBorder[1], relBorder[1]],
// t
[canvas.width - relBorder[0], canvas.width - relBorder[0], canvas.width - relBorder[0], relBorder[1], relBorderRadius[1], canvas.height - relBorderRadius[2]],
// r
[canvas.width - relBorder[0], canvas.width - relBorderRadius[2], relBorderRadius[3], canvas.height - relBorder[1], canvas.height - relBorder[1], canvas.height - relBorder[1]],
// b
[relBorder[0], relBorder[0], relBorder[0], canvas.height - relBorder[1], canvas.height - relBorderRadius[3], relBorderRadius[0]] // t
].forEach(function (_ref3) {
var _ref4 = _slicedToArray(_ref3, 6),
x0 = _ref4[0],
x1 = _ref4[1],
x2 = _ref4[2],
y0 = _ref4[3],
y1 = _ref4[4],
y2 = _ref4[5];
ctx.quadraticCurveTo(x0, y0, x1, y1);
ctx.lineTo(x2, y2);
});
ctx.closePath();
ctx.fill();
}
}
ctx.translate.apply(ctx, _toConsumableArray(relBorder));
ctx.translate.apply(ctx, _toConsumableArray(relPadding));
// paint text
ctx.font = font; // Set font again after canvas is resized, as context properties are reset
ctx.fillStyle = this.color;
ctx.textBaseline = 'bottom';
var drawTextStroke = this.strokeWidth > 0;
if (drawTextStroke) {
ctx.lineWidth = this.strokeWidth * this.fontSize / 10;
ctx.strokeStyle = this.strokeColor;
}
lines.forEach(function (line, index) {
var lineX = (innerWidth - ctx.measureText(line).width) / 2;
var lineY = (index + 1) * _this2.fontSize;
drawTextStroke && ctx.strokeText(line, lineX, lineY);
ctx.fillText(line, lineX, lineY);
});
// Inject canvas into sprite
if (this.material.map) this.material.map.dispose(); // gc previous texture
var texture = this.material.map = new three.Texture(canvas);
texture.minFilter = three.LinearFilter;
texture.colorSpace = three.SRGBColorSpace;
texture.needsUpdate = true;
var yScale = this.textHeight * lines.length + border[1] * 2 + padding[1] * 2;
this.scale.set(yScale * canvas.width / canvas.height, yScale, 0);
}
}, {
key: "clone",
value: function clone() {
return new this.constructor(this.text, this.textHeight, this.color).copy(this);
}
}, {
key: "copy",
value: function copy(source) {
three.Sprite.prototype.copy.call(this, source);
this.color = source.color;
this.backgroundColor = source.backgroundColor;
this.padding = source.padding;
this.borderWidth = source.borderWidth;
this.borderColor = source.borderColor;
this.fontFace = source.fontFace;
this.fontSize = source.fontSize;
this.fontWeight = source.fontWeight;
this.strokeWidth = source.strokeWidth;
this.strokeColor = source.strokeColor;
return this;
}
}]);
return _default;
}(three.Sprite);
export { _default as default };

@ -1,66 +1,134 @@
<template>
<e-charts class="chart" :option="option" />
<!-- <e-charts id="main" class="chart" /> -->
<!-- <div class="container" ref="containerRef">
<h1>Scroll down to load more content</h1>
<div class="content">
<p v-for="item in content" :key="item.id">{{ item.text }}</p>
</div>
<button v-if="showButton" @click="scrollDown">加载更多</button>
</div> -->
<!-- <div class="container" @mouseover="startTimer" @mouseleave="clearTimer">
<h1>Hover for 5 seconds to scroll down and load more content</h1>
<div class="content" ref="contentRef">
<p v-for="item in content" :key="item.id">{{ item.text }}</p>
<p v-if="!allContentLoaded">Loading more content...</p>
</div>
</div> -->
</template>
<!-- 学习路径推荐 -->
<script lang="ts" setup>
// import echarts from 'echarts/types/dist/echarts';
import { ref } from 'vue';
// import * as echarts from 'echarts';
import 'echarts'
import ECharts from 'vue-echarts';
var ROOT_PATH = 'https://echarts.apache.org/examples';
var chartDom = document.getElementById('main');
var myChart = echarts.init(chartDom);
var option;
myChart.showLoading();
$.getJSON(ROOT_PATH + '/data/asset/data/les-miserables.json', function (graph) {
myChart.hideLoading();
const option = ref({
tooltip: {},
legend: [
{
data: graph.categories.map(function (a) {
return a.name;
})
}
],
series: [
{
name: 'Les Miserables',
type: 'graph',
layout: 'none',
data: graph.nodes,
links: graph.links,
categories: graph.categories,
roam: true,
label: {
show: true,
position: 'right',
formatter: '{b}'
},
labelLayout: {
hideOverlap: true
},
scaleLimit: {
min: 0.4,
max: 2
},
lineStyle: {
color: 'source',
curveness: 0.3
}
}
]
});
myChart.setOption(option);
});
option && myChart.setOption(option);
<script lang="ts" >
// import { onMounted, ref, reactive } from 'vue';
// export default {
// setup() {
// const containerRef = ref(null);
// const visibleContent = ref([]);
// const content = reactive([
// { id: 1, text: 'Content 1' },
// { id: 2, text: 'Content 2' },
// { id: 3, text: 'Content 3' },
// { id: 4, text: 'Content 4' },
// { id: 5, text: 'Content 5' },
// { id: 6, text: 'Content 6' },
// { id: 7, text: 'Content 7' },
// { id: 8, text: 'Content 8' },
// { id: 9, text: 'Content 9' },
// { id: 10, text: 'Content 10' }
// ]);
// const showButton = ref(true); //
// const scrollDown = () => {
// const container = containerRef.value;
// container.scrollTo({
// top: container.scrollHeight,
// behavior: 'smooth'
// });
// loadMore();
// };
// const loadMore = () => {
// const startIndex = visibleContent.value.length;
// const endIndex = startIndex + 3; // 3
// //
// visibleContent.value = [...visibleContent.value, ...content.slice(startIndex, endIndex)];
// //
// if (visibleContent.value.length >= content.length) {
// showButton.value = false; //
// }
// };
// onMounted(() => {
// const container = containerRef.value;
// container.addEventListener('scroll', handleScroll);
// });
// const handleScroll = () => {
// const container = containerRef.value;
// const scrollPosition = container.scrollTop + container.clientHeight;
// const scrollHeight = container.scrollHeight;
// //
// if (scrollPosition === scrollHeight) {
// showButton.value = true; //
// }
// };
// return {
// containerRef,
// visibleContent,
// showButton,
// scrollDown,
// content
// };
// }
// };
</script>
<style lang="scss" scoped>
.chart {
height: 400px;
}
/* 添加一些样式 */
// .container {
// width: 100%;
// height: 100vh;
// overflow-y: auto;
// display: flex;
// flex-direction: column;
// justify-content: center;
// align-items: center;
// background-color: lightgray;
// }
// .container .content {
// margin-top: 20px;
// padding: 10px;
// border: 1px solid gray;
// background-color: white;
// }
// .container {
// width: 100px;
// height: 100px;
// // overflow-y: auto;
// // display: flex;
// // flex-direction: column;
// // justify-content: center;
// // align-items: center;
// background-color: lightgray;
// }
// .content {
// margin-top: 20px;
// padding: 10px;
// border: 1px solid gray;
// background-color: white;
// }
// .chart {
// height: 400px;
// width: 100%;
// }
</style>

@ -0,0 +1,151 @@
<template>
<div id="3d-graph"></div>
</template>
<script lang="ts" setup>
// import { useRouter } from 'vue-router'
import { onMounted, ref,reactive } 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 = 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,
}
})
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>
<style lang='scss' scoped>
</style>

@ -52,9 +52,9 @@
<p style="color: #A6A6A6;">计算机导论的简介计算机导论的简介计算机导论的简介计算机导论的简介计算机导论的简介计算机导论的简介计算机导
论的简介计算机导论的简介计算机导论的简介计算机导论的简介计算机导论的简介</p></div>
<div class="box">
<p style="font-size: 14px;color: #6B6B6B;">总学时 36小时</p>
<p style="font-size: 14px;color: #6B6B6B;">总学时 36小时&nbsp;</p>
<p style="font-size: 14px;color: #6B6B6B;">总学分 2.0</p>
<p style="font-size: 14px;color: #6B6B6B;">章节数 10</p>
<p style="font-size: 14px;color: #6B6B6B;">章节数 10&nbsp;</p>
<p style="font-size: 14px;color: #6B6B6B;">知识点总数 33</p>
</div>
</div>
@ -137,7 +137,7 @@
<div class="content">
<img src="/src/assets/images/tp.png">
</div>
<h1>计算机导论 {{ userList.name }}</h1>
<!-- <h1>计算机导论 {{ userList.name }}</h1> -->
<button></button>
</div>
<div class="icon1">
@ -146,7 +146,31 @@
<div class="icon"><img src="/src/assets/images/kc3.png"></div>
</div>
</div>
<div class="botto">
<button
ref="hoverButton"
@mouseover="startHoverTimer"
@mouseout="clearHoverTimer"
@click="handleClick"
:disabled="isButtonDisabled"
:content="buttonContent"
>
{{ buttonContent }}
</button>
<p v-if="showMessage">{{ message }}</p>
</div>
</el-scrollbar>
</div>
<!-- 底部 -->
@ -158,13 +182,15 @@
<p style="font-size: 13px;margin-top: 70px">黄淮学院版权所有@2023 湘豫CP备 19005950-1<br>
违法和不良信息举报 举报电话0xxx-8xxxxxxx 举报邮箱xxxxxxxxx@qq.com</p>
</div>
<div></div>
<div>
</div>
<!-- {{ userList }} -->
</template>
// @ts-expect-error
<script lang="ts" setup>
<script lang="ts" >
import { ref } from 'vue'
import { watchEffect, onMounted, onUnmounted } from 'vue';
import { getUserInfo } from '@/api/user'
const userList = ref<any>([])
const getUserListEvent = async () => {
@ -177,6 +203,169 @@ const getUserListEvent = async () => {
}
}
getUserListEvent()
export default {
name: 'HoverButton',
setup() {
const hoverTimer = ref(0);
const hoverCount = ref(0);
const buttonContent = ref('123进行开始');
const showMessage = ref(false);
const message = ref('');
const isButtonDisabled = ref(false);
//
const startHoverTimer = () => {
if (hoverCount.value >= 3) return; //
clearTimeout(hoverTimer.value); //
hoverTimer.value = setTimeout(() => {
showMessage.value = true;
message.value = '你好!';
hideButton();
}, 3000);
};
//
const clearHoverTimer = () => {
clearTimeout(hoverTimer.value);
};
//
const hideButton = () => {
isButtonDisabled.value = true;
setTimeout(() => {
isButtonDisabled.value = false;
hoverCount.value++;
if (hoverCount.value === 3) {
buttonContent.value = '加载更多';
}
showMessage.value = false;
}, 1000);
};
//
const handleClick = () => {
if (buttonContent.value === '加载更多') {
buttonContent.value = '新的一次开始了';
hoverCount.value = 0; //
setTimeout(() => {
buttonContent.value = '123进行开始';
}, 1000); //
}
};
//
onMounted(() => {
// DOM
});
//
onUnmounted(() => {
clearTimeout(hoverTimer.value);
});
// hoverCount
watchEffect(() => {
if (hoverCount.value >= 3 && buttonContent.value !== '加载更多') {
buttonContent.value = '加载更多';
}
});
//
return {
hoverTimer,
hoverCount,
buttonContent,
showMessage,
message,
isButtonDisabled,
startHoverTimer,
clearHoverTimer,
handleClick,
};
},
};
</script>
<style lang="scss" scoped>
@ -496,4 +685,24 @@ img {
font-size: 17px;
color: #7F9EED;
}
.botto{
position: relative;
width: 148px;
height: 36px;
line-height: 34px;
text-align: center;
font-size: 16px;
border: 1px solid #4285f4;
border-radius: 1px;
color: #4285f4;
cursor: pointer;
margin: 0 auto;
}
button[disabled] {
opacity: 0.5;
cursor: not-allowed;
}
</style>

@ -10,7 +10,6 @@
<li>学生入口&nbsp;&nbsp;|</li>
<li>毕业生入口</li>
</ul>
</div>
<div class="nav2">
<ul>
@ -30,20 +29,389 @@
<h1>知识图谱</h1>
<p>(专业代码 080902H)</p>
</div>
<!-- 知识图谱 -->
<div class="subnav">
<h1>知识图谱</h1>
</div>
<div class="content">
<e-charts id="main" class="chart" />
<!-- 侧边栏 -->
<div class="sidebar">
<div class="sidebar-header">
<div class="sidebar-header-imag">
<div class="sidebar-header-imag1"><img src="/src/assets/images/gd (3).png" width="100%" height="100%"></div>
<div class="sidebar-header-imag2"><img src="/src/assets/images/sjx(1).png" width="100%" height="100%"></div>
</div>
<h1>知识点</h1>
<p>共发布225个</p>
<a>详情 &nbsp;&nbsp;&nbsp;></a>
<div class="sidebar-header-line"></div>
</div>
<!-- <div class="bo"> -->
<div class="content">
<div class="txt">
<div class="txt1">联试题数233 &nbsp;&nbsp;&nbsp;关联学习数22</div>
<div class="imag"><img src="/src/assets/images/sjx(1).png" width="100%" height="100%"></div>
</div>
</div>
<div class="lina">
<e-charts style="height: 260px;" id="lina" />
</div>
<!-- <div id="staff_all_orderCount" style="width: 300px;height:300px;"></div> -->
<!-- <e-chars class="lina" option="option"/> -->
<!-- 百分率 -->
<div class="completion">
<!-- <div class="echates-title">知识点掌握百分比</div> -->
<div class="box">
<div id="liquidfill" style="width: 65%; height: 65%; "></div>
<div class="percentage">
<h4>平均完成率:<p>80%</p>
</h4>
</div>
</div>
<div class="box">
<div id="liquidfil" style="width: 65%; height: 65%; "></div>
<div class="percentage">
<h4>平均完成率:<p>60%</p>
</h4>
</div>
</div>
<!-- <div class="circle">
<div class="header1">
<div class="inner-header1 flex"></div>
<div>
<svg class="waves" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 24 150 28" preserveAspectRatio="none" shape-rendering="auto">
<defs>
<path id="gentle-wave" d="M-160 44c30 0 58-18 88-18s 58 18 88 18 58-18 88-18 58 18 88 18 v44h-352z" />
</defs>
<g class="parallax">
<use xlink:href="#gentle-wave" x="48" y="0" fill="rgba(0,0,255,0.3)" />
<use xlink:href="#gentle-wave" x="48" y="3" fill="rgba(255,255,255,0.5)" />
<use xlink:href="#gentle-wave" x="48" y="3" fill="rgba(255,255,255,0.3)" />
<use xlink:href="#gentle-wave" x="48" y="1" fill="#fff" />
</g>
</svg>
</div>
</div>
</div> -->
<!-- <div class="percentage">
<h4>平均完成率:<p>96%</p></h4>
</div> -->
</div>
<!-- 知识点 -->
<div class="knowledge">
<div class="libox">
<h1>49</h1>
<p>80% ~ 100%</p>
</div>
<div class="libox" style="border-left: 2px solid #74a5ff;">
<h1>3</h1>
<p>60% ~ 79%</p>
</div>
<div class="libox" style="border-left: 2px solid #74a5ff;">
<h1>4</h1>
<p>59%以下</p>
</div>
</div>
<!-- 知识点方法 -->
<div class="box1">
<div class="method">
<li>掌握最好基本方法</li>
<li>关联资源数最多法律责任</li>
<li>掌握最欠缺基本知识方法</li>
</div>
</div>
</div>
</div>
<!-- 底部 -->
<div class="footer">
<h3>软件工程专业</h3>
<h1>教学一体化平台</h1>
<p>关于我们&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp; &nbsp;联系我们&nbsp; &nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp; 服务协议
</p>
<p style="font-size: 13px;margin-top: 70px">黄淮学院版权所有@2023 湘豫CP备 19005950-1<br>
违法和不良信息举报 举报电话0xxx-8xxxxxxx 举报邮箱xxxxxxxxx@qq.com</p>
</div>
<div></div>
</template>
<script lang="ts" setup>
// import axios from 'axios';
import {} from 'vue'
import { ref, onMounted, markRaw } from 'vue'
import * as echarts from 'echarts';
import 'echarts-liquidfill'
// var ROOT_PATH = 'https://echarts.apache.org/examples';
// type EChartsOption = echarts.EChartsOption;
var option = null
// dom dom
onMounted(() => {
const dom = document.getElementById('main')
// dom echarts
var myChart = echarts.init(dom);
console.log(dom, 'dom')
// loading
myChart.showLoading();
// json
fetch('../../../public/nodeList.json').then((res) => {
res.json().then(graph => {
console.log(graph);
myChart.hideLoading();
// node links
option = {
tooltip: {},
legend: [
{
data: graph.categories.map(function (a: { name: string }) {
return a.name;
})
}
],
series: [
{
name: 'Les Miserables',
type: 'graph',
layout: 'none',
data: graph.nodes,
links: graph.links,
categories: graph.categories,
roam: true,
label: {
show: true,
position: 'right',
formatter: '{b}'
},
labelLayout: {
hideOverlap: true
},
scaleLimit: {
min: 0.4,
max: 2
},
lineStyle: {
color: 'source',
curveness: 0.3
}
}
]
};
// echarts
myChart.setOption(option);
})
})
// option && myChart.setOption(option);
})
onMounted(() => {
const chartInstance: any = ref(null)
const updateChart = () => {
chartInstance.value = markRaw(
echarts.init(document?.getElementById(`liquidfill`,)),
)
const option = {
series: [
{
name: '自定义盒子',
type: 'liquidFill',
phase: 0.1,
amplitude: 10,
data: [
{
value: 0.8,
itemStyle: {
color: '#95DCFE',
},
},
{
value: 0.7,
itemStyle: {
color: '#0191F7',
},
},
],
radius: '95%',
//
itemStyle: {
shadowBlur: 5,
},
backgroundStyle: {
color: 'rgba(5, 108, 252, 0.1)',
borderWidth: 2,
borderColor: '#0052FF',
},
outline: {
show: false,
},
//
label: {
show: true,
align: 'center',
distance: 50,
color: '#05FCF6',
fontSize: '24px',
insideColor: '#0052FF ',
},
},
],
}
chartInstance.value.setOption(option, true)
chartInstance?.value?.resize()
}
updateChart()
})
//
onMounted(() => {
const dom = document.getElementById('lina')
// dom echarts
var myChart = echarts.init(dom);
console.log(dom, 'dom')
// loading
myChart.showLoading();
// json
fetch('../../../public/nodeList.json').then((res) => {
res.json().then(graph => {
console.log(graph);
myChart.hideLoading();
// node links
option = {
xAxis: {
type: 'category',
boundaryGap: false,
data: ['记忆', '理解', '应用', '分析', '评价']
},
yAxis: {
type: 'value',
// min:'700',
splitLine:{
show:false
}
},
series: [
{
data: [820, 932, 901, 934, 1290],
type: 'line',
areaStyle: {},
}
]
};
// echarts
myChart.setOption(option);
})
})
// option && myChart.setOption(option);
})
//
onMounted(() => {
const chartInstance: any = ref(null)
const updateChart = () => {
chartInstance.value = markRaw(
echarts.init(document?.getElementById(`liquidfil`,)),
)
const option = {
series: [
{
name: '自定义盒子',
type: 'liquidFill',
phase: 0.1,
amplitude: 10,
data: [
{
value: 0.6,
itemStyle: {
color: '#b3edfa',
},
},
{
value: 0.5,
itemStyle: {
color: '#47d9fa',
},
},
],
radius: '95%',
//
itemStyle: {
shadowBlur: 5,
},
backgroundStyle: {
color: 'rgba(5, 108, 252, 0.1)',
borderWidth: 2,
borderColor: '#0052FF',
},
outline: {
show: false,
},
//
label: {
show: true,
align: 'center',
distance: 50,
color: '#05FCF6',
fontSize: '24px',
insideColor: '#0052FF ',
},
},
],
}
chartInstance.value.setOption(option, true)
chartInstance?.value?.resize()
}
updateChart()
})
// const option = ref({
// xAxis: {
// type: 'category',
// boundaryGap: false,
// data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
// },
// yAxis: {
// type: 'value'
// },
// series: [
// {
// data: [820, 932, 901, 934, 1290, 1330, 1320],
// type: 'line',
// areaStyle: {}
// }
// ]
// });
</script>
<style lang="scss" scoped>
* {
margin: 0;
padding: 0;
/* box-sizing: border-box; */
/* font: 14px/28px "微软雅黑"; */
}
ul {
@ -164,4 +532,468 @@ img {
margin-left: 80px;
}
.subnav {
width: 100%;
margin: auto;
margin-top: 50px;
height: 50px;
// background-color: #7F9EED;
}
.subnav h1 {
border-bottom: 4px solid #0052FF;
font-size: 20px;
width: 10%;
height: 35px;
margin: auto;
font-weight: bolder;
color: #0052FF;
text-align: center;
}
.content {
margin-top: 30px;
width: 100%;
height: 750px;
// background-color: #74a5ff;
// background: linear-gradient(#dde6f8, #b5cdf9, #97b8f8);
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: space-around;
}
.chart {
width: 72%;
height: 100%;
border: 1px solid rgba(75, 112, 170, 0.2);
// background-color: rgb(185, 207, 250,0.5);
// background-color: rgba(0, 80, 251, 0.1);
// background-color: bisque
}
.cha {
width: 100%;
height: 100%;
// background-color: bisque
}
.sidebar {
width: 25%;
height: 100%;
// background: linear-gradient(#74a5ff, #91b7ff, #A4c3ff);
}
.sidebar .sidebar-header {
width: 100%;
height: 7%;
background: linear-gradient(#74a5ff, #91b7ff, #A4c3ff);
// transform: perspective(3em) rotateY(-6deg);
}
.sidebar .sidebar-header-imag {
width: 100%;
display: flex;
height: 28%;
flex-direction: row;
justify-content: space-between;
flex-wrap: nowrap;
}
.sidebar .sidebar-header-imag1 {
width: 5%;
height: 100%;
}
.sidebar .sidebar-header-imag2 {
width: 8%;
height: 100%;
}
.sidebar .sidebar-header-imag1:hover {
background-color: #728cc4;
}
.sidebar .sidebar-header h1 {
width: 20%;
font-weight: bolder;
color: #fafafa;
float: left;
margin-left: 10px;
font-size: 16px;
line-height: 30px;
// background-color: #728cc4;
// transform: perspective(3em) rotateY(-6deg);
}
.sidebar .sidebar-header p {
width: 33%;
// font-weight:bolder;
color: #fafafa;
float: left;
margin-left: 10px;
font-size: 13px;
line-height: 30px;
// background-color: #728cc4;
// transform: perspective(3em) rotateY(-6deg);
}
.sidebar .sidebar-header a {
width: 20%;
font-weight: bolder;
color: #fafafa;
float: right;
margin-right: 3px;
font-size: 13px;
line-height: 30px;
// background-color: #728cc4;
// transform: perspective(3em) rotateY(-6deg);
}
.sidebar .sidebar-header-line {
width: 60%;
height: 5%;
border-radius: 2px 2px 2px 2px;
background-color: #74a5ff;
float: left;
margin-top: 10px;
box-shadow: 1.5px -2px #F0F4FA;
// box-shadow: 1.5px 1px #F0F4FA;
// transform: perspective(3em) rotateY(-6deg);
}
.sidebar .content {
width: 100%;
height: 6%;
background: linear-gradient(#74a5ff, #91b7ff, #A4c3ff);
margin-top: 10px;
}
.sidebar .content .txt {
width: 100%;
height: 100%;
// background-color: #728cc4;
flex-direction: row;
justify-content: space-between;
flex-wrap: nowrap;
display: flex;
}
.sidebar .content .txt .imag {
width: 15%;
height: 60%;
}
.sidebar .content .txt1 {
width: 90%;
height: 5%;
font-size: 14px;
margin-left: 4px;
color: #FFFFFF;
margin-top: 15px;
}
.sidebar .lina {
width: 100%;
height: 30%;
display: flex;
flex-direction: column-reverse;
// background-color: #A1C1FF;
}
//
.sidebar .completion {
width: 100%;
height: 21%;
margin: auto;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: space-around;
// background-color: #A1C1FF;
// background: linear-gradient(#74a5ff, #91b7ff, #A4c3ff);
// background-color: rgba(43, 111, 237, 0.5);
}
.sidebar .completion .box {
width: 48%;
height: 95%;
display: flex;
flex-wrap: wrap;
justify-content: space-around;
flex-direction: row;
align-content: center;
// background: #7786a4;
}
.sidebar .completion .circle {
border-radius: 50%;
width: 100px;
height: 100px;
// background: #b0c4ed;
}
.percentage {
width: 90%;
height: 15%;
margin-top: 20px;
border-radius: 10px 10px 10px 10px;
background-color: rgb(125, 159, 232,0.5);
}
.percentage h4 {
width: 100%;
height: 90%;
font-size: 15px;
line-height: 20px;
// text-align: center;
display: flex;
flex-wrap: nowrap;
justify-content: space-evenly;
color: #F0F4FA;
font-weight: bold;
// background-color: #5582dc;
}
.percentage h4 p {
width: 20%;
height: 90%;
font-size: 15px;
line-height: 20px;
color: #1470ea;
// background-color: #b3c8f2;
}
//
.header1 {
position: relative;
text-align: center;
border-radius: 100%;
background: linear-gradient(60deg, rgba(84, 58, 183, 1) 0%, rgba(0, 172, 193, 1) 100%);
// color: rgb(207, 59, 59);
}
.inner-header1 {
height: 65vh;
height: 20%;
width: 100%;
margin: 0;
padding: 0;
}
.flex {
display: flex;
justify-content: center;
align-items: center;
text-align: center;
}
.waves {
position: relative;
width: 100%;
height: 50%;
border-radius: 50%;
// margin-bottom: -7px;
min-height: 100px;
max-height: 150px;
// color: #0052FF;
}
// .content1 {
// position: relative;
// height: 20vh;
// text-align: center;
// background-color: white;
// }
.parallax>use {
/* 使use元素执行move-forever动画 */
animation: move-forever 25s cubic-bezier(.55, .5, .45, .5) infinite;
}
.parallax>use:nth-child(1) {
/* 延迟2秒启动动画 */
/* 设置动画持续时间为7秒 */
// background-color: #0052FF;
animation-delay: -3s;
animation-duration: 10s;
// animation-duration: 7s;
// animation-delay: -2s;
}
.parallax>use:nth-child(2) {
// background-color: #0052FF;
animation-delay: -3s;
animation-duration: 10s;
}
// .parallax>use:nth-child(3) {
// animation-delay: -4s;
// animation-duration: 13s;
// }
// .parallax>use:nth-child(4) {
// animation-delay: -5s;
// animation-duration: 20s;
// }
@keyframes move-forever {
0% {
// color: #0052FF;
transform: translate3d(-90px, 0, 0);
}
100% {
transform: translate3d(85px, 0, 0);
}
}
@media (max-width: 768px) {
.waves {
// background-color: #0052FF;
height: 40px;
min-height: 40px;
}
// .content {
// height: 30vh;
// }
// h1 {
// font-size: 24px;
// }
}
//
.knowledge {
width: 100%;
height: 15%;
display: flex;
flex-direction: row;
justify-content: center;
background-color: #A1C1FF;
// background-color: #A4c3ff;
padding-top: 20px;
}
.knowledge .libox {
width: 32%;
height: 80%;
// float: left;
// margin-left: 10px;
// background-color: #7caefa
}
.knowledge .libox h1 {
width: 100%;
height: 50%;
color: #F0F4FA;
line-height: 50px;
text-align: center;
margin: auto;
font-size: 26px;
font-weight: bold;
// background-color: #4c668e
}
.knowledge .libox p {
width: 100%;
height: 50%;
color: #F0F4FA;
line-height: 50px;
text-align: center;
margin: auto;
font-size: 15px;
// font-weight:bold;
// background-color: #a1bde8
}
//
.box1{
width: 100%;
height: 147px;
background-color: #A1C1FF;
// height: 100%;
}
.method {
width: 90%;
height: 85%;
margin: auto;
border-radius: 15px 15px 15px 15px;
background-color: #74a5ff;
// background: linear-gradient(#74a5ff, #91b7ff, #A4c3ff);
}
.method li {
width: 90%;
height: 20%;
font-size: 16px;
font-weight: bold;
line-height: 35px;
margin-left: 10px;
padding-top: 10px;
color: #F0F4FA;
// background-color: #74a5ff;
}
//
.footer {
margin-top: 100px;
width: 100%;
height: 250px;
// position: absolute;
text-align: center;
background-color: #252527;
}
.footer h3 {
width: 100%;
// position: absolute;
text-align: center;
font-size: 15px;
padding-top: 40px;
color: #7F9EED;
font-weight: bolder;
}
.footer h1 {
width: 100%;
// position: absolute;
font-family: "kaiti_gb2312";
margin-top: 10px;
font-size: 25px;
color: #7F9EED;
font-weight: bolder;
}
.footer p {
width: 100%;
height: 20px;
// position: absolute;
font-family: "kaiti_gb2312";
margin-top: 25px;
font-size: 17px;
color: #7F9EED;
}
.echates-title {
color: #333;
font-size: 14px;
font-weight: 700;
margin-bottom: 10px;
}
.bo{
width: 100%;
background: linear-gradient(#74a5ff, #91b7ff, #A4c3ff);
}
</style>

@ -36,16 +36,3 @@ export default ({ command }: any) => {
},
}
}
// const webpack = require('webpack')
// module.exports = {
// configureWebpack: {
// plugins: [
// new webpack.ProvidePlugin({
// $: 'jquery',
// jQuery: 'jquery',
// 'windows.jQuery': 'jquery'
// })
// ]
// }
// }
Loading…
Cancel
Save