Kaynağa Gözat

study 模块开发

靳炳淑 6 yıl önce
ebeveyn
işleme
8646aaf25a

+ 48 - 10
src/components/CodeInterpreter/index.vue

@@ -1,8 +1,30 @@
 <template>
   <div class="question-board">
     <div class="instruction">
-      <b-tag>题目要求</b-tag>
-      <p>{{ instruction }}</p>
+      <div class="line">
+        <b-tag>题目要求</b-tag>
+        <p>{{ instruction }}</p>
+      </div>
+      <div class="line">
+        <b-tag @click.native="handleShowHint">提示</b-tag>
+        <b-tag
+          v-show="showHint"
+          closable
+          aria-close-label="Close tag"
+          @close="showHint = false"
+          >{{ hint }}</b-tag
+        >
+      </div>
+      <div class="line">
+        <b-tag @click.native="handleShowAnswer">参考答案</b-tag>
+        <b-tag
+          v-show="showAnswer"
+          closable
+          aria-close-label="Close tag"
+          @close="showAnswer = false"
+          >{{ answer }}</b-tag
+        >
+      </div>
     </div>
     <div class="code-itp">
       <div id="editor-container">
@@ -61,12 +83,16 @@ export default {
   },
   props: {
     instruction: String,
-    initialCode: String
+    initialCode: String,
+    hint: String,
+    answer: String
   },
   data() {
     return {
       htmlCodes: "",
-      htmlEditor: null
+      htmlEditor: null,
+      showHint: false,
+      showAnswer: false
     };
   },
   methods: {
@@ -123,6 +149,12 @@ export default {
     handleReset() {
       this.htmlCodes = this.initialCode;
       this.$refs["editor"].resetCode(this.htmlCodes);
+    },
+    handleShowHint() {
+      this.showHint = !this.showHint;
+    },
+    handleShowAnswer() {
+      this.showAnswer = !this.showAnswer;
     }
   }
 };
@@ -137,12 +169,18 @@ export default {
 }
 
 .instruction {
-  display: flex;
-  align-items: center;
-  p {
-    font-size: $size-small;
-    color: $text;
-    margin-left: 12px;
+  .line {
+    display: flex;
+    align-items: center;
+    margin: 2px 0;
+    p {
+      font-size: $size-small;
+      color: $text;
+      margin-left: 12px;
+    }
+    span.tag {
+      cursor: pointer;
+    }
   }
 }
 

+ 102 - 26
src/components/GitGraph/index.vue

@@ -1,28 +1,56 @@
 <template>
-  <div class="git-graph-body">
-    <div class="command-container">
-      <div class="command-box" ref="command-box">
-        <b-field
-          v-for="c in commandHistory"
-          v-bind:key="c.id"
-          :type="c.result"
-          :message="c.info"
+  <div>
+    <div class="instruction">
+      <div class="line">
+        <b-tag>题目要求</b-tag>
+        <p>{{ instruction }}</p>
+      </div>
+      <div class="line">
+        <b-tag @click.native="handleShowHint">提示</b-tag>
+        <b-tag
+          v-show="showHint"
+          closable
+          aria-close-label="Close tag"
+          @close="showHint = false"
+          >{{ hint }}</b-tag
+        >
+      </div>
+      <div class="line">
+        <b-tag @click.native="handleShowAnswer">参考答案</b-tag>
+        <b-tag
+          v-show="showAnswer"
+          closable
+          aria-close-label="Close tag"
+          @close="showAnswer = false"
+          >{{ answer }}</b-tag
         >
-          <b-input v-model="c.value" size="is-small" readOnly></b-input>
+      </div>
+    </div>
+    <div class="git-graph-body">
+      <div class="command-container">
+        <div class="command-box" ref="command-box">
+          <b-field
+            v-for="c in commandHistory"
+            v-bind:key="c.id"
+            :type="c.result"
+            :message="c.info"
+          >
+            <b-input v-model="c.value" size="is-small" readOnly></b-input>
+          </b-field>
+        </div>
+        <b-field>
+          <!-- keypress事件 屏蔽中文输入法的enter -->
+          <b-input
+            id="command-input"
+            placeholder="git"
+            v-model="commandInput"
+            @keypress.enter.native="handleCommand"
+          ></b-input>
         </b-field>
       </div>
-      <b-field>
-        <!-- keypress事件 屏蔽中文输入法的enter -->
-        <b-input
-          id="command-input"
-          placeholder="git"
-          v-model="commandInput"
-          @keypress.enter.native="handleCommand"
-        ></b-input>
-      </b-field>
+      <!--分支图-->
+      <div class="gitgraph-container"><div id="gitgraph"></div></div>
     </div>
-    <!--分支图-->
-    <div class="gitgraph-container"><div id="gitgraph"></div></div>
   </div>
 </template>
 
@@ -31,7 +59,15 @@ import { createGitgraph, templateExtend, TemplateName } from "@gitgraph/js";
 export default {
   name: "GitGraph",
   components: {},
-  props: {},
+  props: {
+    name: String,
+    id: Number,
+    description: String,
+    instruction: String,
+    preCode: Array,
+    hint: String,
+    answer: String
+  },
   watch: {},
   data() {
     return {
@@ -39,15 +75,23 @@ export default {
       commandHistory: [],
       fastCommandPointer: 0, // 上下按键访问历史命令
       branchList: [],
-      currentBranchName: ""
+      currentBranchName: "",
+      showHint: false,
+      showAnswer: false
     };
   },
   methods: {
     /** 解析命令相关方法 */
-    handleCommand(event) {
+    handleCommand(event, isPreCode) {
       //1 分词
-      let command = event.target.value;
-      command = command.trim();
+      let command;
+      if (!isPreCode) {
+        command = event.target.value;
+        command = command.trim();
+      } else {
+        command = event;
+        command = command.trim();
+      }
       let array = command.split(" ");
       array = array.filter(i => i.length > 0);
       console.log("array:", array);
@@ -170,7 +214,9 @@ export default {
       } else {
         let newBranch = this.gitGraph.branch(branchName);
         this.branchList.push(newBranch);
-        this.currentBranchName = branchName;
+        if (selfUse) {
+          this.currentBranchName = branchName; // checkout -b
+        }
         if (!selfUse) {
           this.commandCorrect(command);
         }
@@ -211,6 +257,13 @@ export default {
       } else {
         this.commandWrong(command, "no branch name" + branchName);
       }
+    },
+    // 其他方法
+    handleShowHint() {
+      this.showHint = !this.showHint;
+    },
+    handleShowAnswer() {
+      this.showAnswer = !this.showAnswer;
     }
   },
   mounted() {
@@ -230,6 +283,11 @@ export default {
       template: myTemplate
     });
 
+    // 执行preCode
+    for (let i = 0; i < this.preCode.length; i++) {
+      this.handleCommand(this.preCode[i], true);
+    }
+
     // ⬆快捷键
     document.onkeyup = function(e) {
       if (e.key === "ArrowUp") {
@@ -255,6 +313,24 @@ export default {
   justify-content: space-between;
   padding: 10px 20px;
 }
+
+.instruction {
+  padding-left: 10px;
+  .line {
+    display: flex;
+    align-items: center;
+    margin: 2px 0;
+    p {
+      font-size: $size-small;
+      color: $text;
+      margin-left: 12px;
+    }
+    span.tag {
+      cursor: pointer;
+    }
+  }
+}
+
 .command-container {
   width: 50%;
   padding: 20px 20px 10px 20px;

+ 10 - 2
src/router/routes.js

@@ -263,11 +263,19 @@ export default [
       },
       {
         path: "study/web",
-        component: () => import("@/views/student/StudyWeb")
+        component: () => import("@/views/student/StudyWeb/QuestionList.vue")
+      },
+      {
+        path: "study/web/:questionId",
+        component: () => import("@/views/student/StudyWeb/Question.vue")
       },
       {
         path: "study/git",
-        component: () => import("@/views/student/StudyGit")
+        component: () => import("@/views/student/StudyGit/QuestionList.vue")
+      },
+      {
+        path: "study/git/:questionId",
+        component: () => import("@/views/student/StudyGit/Question.vue")
       }
     ]
   },

+ 39 - 0
src/views/student/StudyGit/Question.vue

@@ -0,0 +1,39 @@
+<template>
+  <div>
+    <git-graph
+      :name="question.name"
+      :id="question.id"
+      :description="question.description"
+      :instruction="question.instruction"
+      :pre-code="question.preCode"
+      :hint="question.hint"
+      :answer="question.answer"
+    ></git-graph>
+  </div>
+</template>
+
+<script>
+import GitGraph from "@/components/GitGraph/index";
+export default {
+  components: {
+    GitGraph
+  },
+  data() {
+    return {
+      question: {
+        name: "本地分支练习1",
+        id: 1,
+        description: "git branch",
+        instruction:
+          "现在在master分支上有一次commit,请新建dev分支,并在dev分支上commit一次",
+        preCode: ["git checkout -b master", "git commit"],
+        hint: "使用 git branch 和 git commit 命令来新建分支和提交代码",
+        answer: "git branch dev;\r\ngit checkout dev;\r\ngit commit;"
+      }
+    };
+  },
+  methods: {}
+};
+</script>
+
+<style></style>

+ 124 - 0
src/views/student/StudyGit/QuestionList.vue

@@ -0,0 +1,124 @@
+<template>
+  <div>
+    <page-header
+      :loading="loadingDocList"
+      :routes="[{ name: 'git学习', path: 'git' }]"
+    >
+      <template slot="title">
+        git学习练习题
+      </template>
+      <template slot="content">
+        共有{{ qList.length }}份练习
+      </template>
+    </page-header>
+    <page-body>
+      <div class="columns is-multiline is-desktop">
+        <div v-if="loadingDocList" class="column is-4-desktop">
+          <card loading />
+        </div>
+        <div
+          v-else
+          :key="item.id"
+          v-for="item in qList"
+          class="column is-4-desktop"
+        >
+          <router-link :to="`${$route.path}/${item.id}`">
+            <card hoverable>
+              {{ item.name }}
+              <div>
+                <!--<document-state-tag :state="item.status"></document-state-tag>-->
+                <p
+                  :style="{
+                    fontSize: '12px',
+                    textAlign: 'right'
+                  }"
+                >
+                  {{ item.description }}
+                </p>
+              </div>
+            </card>
+          </router-link>
+        </div>
+        <no-data-svg
+          style="margin-top: 20px;"
+          v-if="!loadingDocList && !(qList && qList.length > 0)"
+        ></no-data-svg>
+      </div>
+    </page-body>
+  </div>
+</template>
+
+<script>
+import PageHeader from "@/components/PageHeader";
+import PageBody from "@/components/PageBody/index";
+import timeMixins from "@/mixins/time";
+import Card from "@/components/Card";
+import NoDataSvg from "@/components/NoDataSvg";
+export default {
+  components: {
+    PageBody,
+    PageHeader,
+    Card,
+    NoDataSvg
+  },
+  mixins: [timeMixins],
+  mounted() {},
+  data() {
+    return {
+      qList: [
+        {
+          name: "本地分支练习1",
+          id: 1,
+          description: "git branch",
+          instruction:
+            "现在在master分支上有一次commit,请新建dev分支,并在dev分支上commit一次",
+          preCode: ["git branch -b master", "git commit"],
+          hint: "使用 git branch 和 git commit 命令来新建分支和提交代码",
+          answer: "git branch dev;\r\ngit checkout dev;\r\ngit commit;"
+        },
+        {
+          name: "本地分支练习2",
+          description: "git commit",
+          id: 2,
+          instruction:
+            "现在在master分支上有一次commit,请新建dev分支,并在dev分支上commit一次",
+          hint: "使用 git branch 和 git commit 命令来新建分支和提交代码",
+          answer: "git branch dev;\r\ngit checkout dev;\r\ngit commit;"
+        },
+        {
+          name: "本地分支练习3",
+          description: "git checkout",
+          id: 3,
+          instruction:
+            "调整<p>的CSS样式,使文字“CSS Exercise字号为18px, 颜色为红色",
+          initialCode:
+            '<!DOCTYPE html>\r\n<html>\r\n<head>\r\n<meta charset="utf-8">\r\n<title>SEEC WEB</title>\r\n<style>\r\nbody\r\n{\r\n\tbackground-color:#d0e4fe;\r\n}\r\nh1\r\n{\r\n\tcolor:orange;\r\n\ttext-align:center;\r\n}\r\np\r\n{\r\n}\r\n</style>\r\n</head>\r\n\r\n<body>\r\n\r\n<h1>SEEC Learing</h1>\r\n<p>CSS Exercise</p>\r\n\r\n</body>\r\n</html>\r\n',
+          hint: "使用 font-size 和 color 属性控制字体的样式",
+          answer: "font-size: 18px;\r\ncolor: red;\r\n"
+        }
+      ],
+      loadingDocList: false
+    };
+  },
+  methods: {}
+};
+</script>
+
+<style lang="scss" scoped>
+.card {
+  padding: 30px;
+  .title {
+    font-size: 1.25rem;
+    small {
+      color: gray;
+      font-size: 1rem;
+    }
+  }
+  .content {
+    a {
+      margin-top: 30px;
+      width: 100%;
+    }
+  }
+}
+</style>

+ 0 - 21
src/views/student/StudyGit/index.vue

@@ -1,21 +0,0 @@
-<template>
-  <div>
-    <h2>Study Git</h2>
-    <git-graph></git-graph>
-  </div>
-</template>
-
-<script>
-import GitGraph from "@/components/GitGraph/index";
-export default {
-  components: {
-    GitGraph
-  },
-  data() {
-    return {};
-  },
-  methods: {}
-};
-</script>
-
-<style></style>

+ 5 - 1
src/views/student/StudyWeb/index.vue → src/views/student/StudyWeb/Question.vue

@@ -3,6 +3,8 @@
     <code-interpreter
       :instruction="question.instruction"
       :initial-code="question.initialCode"
+      :hint="question.hint"
+      :answer="question.answer"
     ></code-interpreter>
   </div>
 </template>
@@ -24,7 +26,9 @@ export default {
         instruction:
           "调整<p>的CSS样式,使文字“CSS Exercise字号为18px, 颜色为红色",
         initialCode:
-          '<!DOCTYPE html>\r\n<html>\r\n<head>\r\n<meta charset="utf-8">\r\n<title>SEEC WEB</title>\r\n<style>\r\nbody\r\n{\r\n\tbackground-color:#d0e4fe;\r\n}\r\nh1\r\n{\r\n\tcolor:orange;\r\n\ttext-align:center;\r\n}\r\np\r\n{\r\n}\r\n</style>\r\n</head>\r\n\r\n<body>\r\n\r\n<h1>SEEC Learing</h1>\r\n<p>CSS Exercise</p>\r\n\r\n</body>\r\n</html>\r\n'
+          '<!DOCTYPE html>\r\n<html>\r\n<head>\r\n<meta charset="utf-8">\r\n<title>SEEC WEB</title>\r\n<style>\r\nbody\r\n{\r\n\tbackground-color:#d0e4fe;\r\n}\r\nh1\r\n{\r\n\tcolor:orange;\r\n\ttext-align:center;\r\n}\r\np\r\n{\r\n}\r\n</style>\r\n</head>\r\n\r\n<body>\r\n\r\n<h1>SEEC Learing</h1>\r\n<p>CSS Exercise</p>\r\n\r\n</body>\r\n</html>\r\n',
+        hint: "使用 font-size 和 color 属性控制字体的样式",
+        answer: "font-size: 18px;\r\ncolor: red;\r\n"
       }
     };
   },

+ 138 - 0
src/views/student/StudyWeb/QuestionList.vue

@@ -0,0 +1,138 @@
+<template>
+  <div>
+    <page-header
+      :loading="loadingDocList"
+      :routes="[{ name: 'web学习', path: 'web' }]"
+    >
+      <template slot="title">
+        web学习练习题
+      </template>
+      <template slot="content">
+        共有{{ qList.length }}份练习
+      </template>
+    </page-header>
+    <page-body>
+      <div class="columns is-multiline is-desktop">
+        <div v-if="loadingDocList" class="column is-4-desktop">
+          <card loading />
+        </div>
+        <div
+          v-else
+          :key="item.id"
+          v-for="item in qList"
+          class="column is-4-desktop"
+        >
+          <router-link :to="`${$route.path}/${item.id}`">
+            <card hoverable>
+              {{ item.name }}
+              <div>
+                <!--<document-state-tag :state="item.status"></document-state-tag>-->
+                <p
+                  :style="{
+                    fontSize: '12px',
+                    textAlign: 'right'
+                  }"
+                >
+                  {{ item.description }}
+                </p>
+              </div>
+            </card>
+          </router-link>
+        </div>
+        <no-data-svg
+          style="margin-top: 20px;"
+          v-if="!loadingDocList && !(qList && qList.length > 0)"
+        ></no-data-svg>
+      </div>
+    </page-body>
+  </div>
+</template>
+
+<script>
+import PageHeader from "@/components/PageHeader";
+import PageBody from "@/components/PageBody/index";
+import timeMixins from "@/mixins/time";
+import Card from "@/components/Card";
+import NoDataSvg from "@/components/NoDataSvg";
+export default {
+  components: {
+    PageBody,
+    PageHeader,
+    Card,
+    NoDataSvg
+  },
+  mixins: [timeMixins],
+  mounted() {},
+  data() {
+    return {
+      qList: [
+        {
+          name: "CSS练习1",
+          id: 1,
+          description: "CSS字体练习",
+          instruction:
+            "调整<p>的CSS样式,使文字“CSS Exercise字号为18px, 颜色为红色",
+          initialCode:
+            '<!DOCTYPE html>\r\n<html>\r\n<head>\r\n<meta charset="utf-8">\r\n<title>SEEC WEB</title>\r\n<style>\r\nbody\r\n{\r\n\tbackground-color:#d0e4fe;\r\n}\r\nh1\r\n{\r\n\tcolor:orange;\r\n\ttext-align:center;\r\n}\r\np\r\n{\r\n}\r\n</style>\r\n</head>\r\n\r\n<body>\r\n\r\n<h1>SEEC Learing</h1>\r\n<p>CSS Exercise</p>\r\n\r\n</body>\r\n</html>\r\n',
+          hint: "使用 font-size 和 color 属性控制字体的样式",
+          answer: "font-size: 18px;\r\ncolor: red;\r\n"
+        },
+        {
+          name: "CSS练习2",
+          description: "CSS img 练习",
+          id: 2,
+          instruction:
+            "调整<p>的CSS样式,使文字“CSS Exercise字号为18px, 颜色为红色",
+          initialCode:
+            '<!DOCTYPE html>\r\n<html>\r\n<head>\r\n<meta charset="utf-8">\r\n<title>SEEC WEB</title>\r\n<style>\r\nbody\r\n{\r\n\tbackground-color:#d0e4fe;\r\n}\r\nh1\r\n{\r\n\tcolor:orange;\r\n\ttext-align:center;\r\n}\r\np\r\n{\r\n}\r\n</style>\r\n</head>\r\n\r\n<body>\r\n\r\n<h1>SEEC Learing</h1>\r\n<p>CSS Exercise</p>\r\n\r\n</body>\r\n</html>\r\n',
+          hint: "使用 font-size 和 color 属性控制字体的样式",
+          answer: "font-size: 18px;\r\ncolor: red;\r\n"
+        },
+        {
+          name: "CSS练习3",
+          description: "CSS flex布局练习1",
+          id: 3,
+          instruction:
+            "调整<p>的CSS样式,使文字“CSS Exercise字号为18px, 颜色为红色",
+          initialCode:
+            '<!DOCTYPE html>\r\n<html>\r\n<head>\r\n<meta charset="utf-8">\r\n<title>SEEC WEB</title>\r\n<style>\r\nbody\r\n{\r\n\tbackground-color:#d0e4fe;\r\n}\r\nh1\r\n{\r\n\tcolor:orange;\r\n\ttext-align:center;\r\n}\r\np\r\n{\r\n}\r\n</style>\r\n</head>\r\n\r\n<body>\r\n\r\n<h1>SEEC Learing</h1>\r\n<p>CSS Exercise</p>\r\n\r\n</body>\r\n</html>\r\n',
+          hint: "使用 font-size 和 color 属性控制字体的样式",
+          answer: "font-size: 18px;\r\ncolor: red;\r\n"
+        },
+        {
+          name: "CSS练习4",
+          description: "CSS flex布局练习2",
+          id: 4,
+          instruction:
+            "调整<p>的CSS样式,使文字“CSS Exercise字号为18px, 颜色为红色",
+          initialCode:
+            '<!DOCTYPE html>\r\n<html>\r\n<head>\r\n<meta charset="utf-8">\r\n<title>SEEC WEB</title>\r\n<style>\r\nbody\r\n{\r\n\tbackground-color:#d0e4fe;\r\n}\r\nh1\r\n{\r\n\tcolor:orange;\r\n\ttext-align:center;\r\n}\r\np\r\n{\r\n}\r\n</style>\r\n</head>\r\n\r\n<body>\r\n\r\n<h1>SEEC Learing</h1>\r\n<p>CSS Exercise</p>\r\n\r\n</body>\r\n</html>\r\n',
+          hint: "使用 font-size 和 color 属性控制字体的样式",
+          answer: "font-size: 18px;\r\ncolor: red;\r\n"
+        }
+      ],
+      loadingDocList: false
+    };
+  },
+  methods: {}
+};
+</script>
+
+<style lang="scss" scoped>
+.card {
+  padding: 30px;
+  .title {
+    font-size: 1.25rem;
+    small {
+      color: gray;
+      font-size: 1rem;
+    }
+  }
+  .content {
+    a {
+      margin-top: 30px;
+      width: 100%;
+    }
+  }
+}
+</style>