Ver código fonte

feat: 做题时star和mark样式

ChenYangfan 6 anos atrás
pai
commit
0f376ed98c

+ 58 - 0
src/components/Basic/CStars.vue

@@ -0,0 +1,58 @@
+<template>
+  <div class="c-stars">
+    <c-icon class="stars-icon" @mouseenter.native="handleMouseEnter(i)" @mouseleave.native="handleMouseLeave"
+            :size="26" v-for="i in level" :key="i" theme="orange" @click.native="handleClick(i)">
+      {{isInStarRange(i) ? 'star' : 'star_border'}}
+    </c-icon>
+  </div>
+</template>
+
+<script>
+import CIcon from '@/components/Basic/CIcon'
+
+export default {
+  components: { CIcon },
+  model: {
+    prop: 'stars',
+    event: 'rate'
+  },
+  props: {
+    stars: Number,
+    // 显示几颗星
+    level: {
+      type: Number,
+      default: 5
+    },
+    disabled: Boolean
+  },
+  data () {
+    return {
+      hoverStars: this.stars
+    }
+  },
+  methods: {
+    isInStarRange (i) {
+      return i <= this.hoverStars
+    },
+    handleMouseEnter (i) {
+      this.hoverStars = i
+    },
+    handleMouseLeave () {
+      this.hoverStars = this.stars
+    },
+    handleClick (i) {
+      console.log(i)
+      this.$emit('rate', i)
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.stars-icon {
+  cursor: pointer;
+}
+.c-stars {
+  height: 26px;
+}
+</style>

+ 1 - 0
src/server/quiz.js

@@ -70,6 +70,7 @@ export function deleteQuiz ({ quizId }) {
 
 // 提交答案
 export function submitQuizStudentAnswer ({ quizId, answers = {}, records = {} }) {
+  console.log(records)
   return axios
     .post(useQuizServer(`/${quizId}/student-answer`), { answers, records })
 }

+ 11 - 1
src/views/quiz/StudentDoQuiz.vue

@@ -168,6 +168,8 @@ export default {
   margin: 0 auto;
   max-width: 800px;
   padding: 64px 24px;
+  background-color: #fcfcfc;
+  box-shadow: 0 0 0 1000px #fcfcfc;
 }
 
 .info {
@@ -175,11 +177,19 @@ export default {
   color: #7a8a9a;
   font-size: 14px;
   margin-bottom: 24px;
-  background: #f7f7f7;
   padding: 8px 12px;
+  border: 1px solid #ddd;
+  background-color: white;
 }
 
 .red {
   color: $theme-red;
 }
+
+.do-quiz-question-card:nth-child(2n) {
+  background-color: #f7f7f7;
+}
+.do-quiz-question-card:nth-child(2n + 1) {
+  background-color: #fff;
+}
 </style>

+ 57 - 23
src/views/quiz/components/DoQuizQuestionCard.vue

@@ -1,27 +1,33 @@
 <template>
-  <div class="quiz-list-item"
-       :class="question.studentAnswer ? question.studentAnswer.correct === false ? 'wrong' : '' : ''">
-    <div class="quiz-list-item__index">{{ index + 1 }}.</div>
-    <div>
-      <markdown-section class="quiz-list-item-title" :raw="question.stem"/>
-      <div v-if="question.type === QuestionKind.choice && question.studentAnswer">
-        <label class="option" :key="index" v-for="(item, index) in question.options">
-          <input @click.stop="emitChoice" v-model="question.studentAnswer.answer" type="radio" :value="index"/>
-          <b class="mr-8">{{ index }}.</b>
-          <markdown-section style="display: inline" :raw="item"/>
-        </label>
-      </div>
-      <div v-else-if="question.type === QuestionKind.trueOrFalse && question.studentAnswer">
-        <label class="option">
-          <input @click.stop="emitChoice" v-model="question.studentAnswer.answer" type="radio" :value="true"/>
-          <c-icon>check</c-icon>
-        </label>
-        <label class="option">
-          <input @click.stop="emitChoice" v-model="question.studentAnswer.answer" type="radio" :value="false"/>
-          <c-icon>close</c-icon>
-        </label>
+  <div class="do-quiz-question-card">
+    <div class="quiz-list-item"
+         :class="question.studentAnswer ? question.studentAnswer.correct === false ? 'wrong' : '' : ''">
+      <div class="quiz-list-item__index">{{ index + 1 }}.</div>
+      <div>
+        <markdown-section class="quiz-list-item-title" :raw="question.stem"/>
+        <div v-if="question.type === QuestionKind.choice && question.studentAnswer">
+          <label class="option" :key="index" v-for="(item, index) in question.options">
+            <input @click.stop="emitChoice" v-model="question.studentAnswer.answer" type="radio" :value="index"/>
+            <b class="mr-8">{{ index }}.</b>
+            <markdown-section style="display: inline" :raw="item"/>
+          </label>
+        </div>
+        <div v-else-if="question.type === QuestionKind.trueOrFalse && question.studentAnswer">
+          <label class="option">
+            <input @click.stop="emitChoice" v-model="question.studentAnswer.answer" type="radio" :value="true"/>
+            <c-icon>check</c-icon>
+          </label>
+          <label class="option">
+            <input @click.stop="emitChoice" v-model="question.studentAnswer.answer" type="radio" :value="false"/>
+            <c-icon>close</c-icon>
+          </label>
+        </div>
       </div>
     </div>
+    <div class="action-bar">
+      <c-stars :level="5" v-model="star"></c-stars>
+      <icon-button no-bold :left="12" theme="green">bookmark_border</icon-button>
+    </div>
   </div>
 </template>
 
@@ -29,10 +35,12 @@
 import CIcon from '@/components/Basic/CIcon'
 import MarkdownSection from '@/views/quiz/components/MarkdownSection'
 import QuestionKind from '@/enums/question-kind'
+import CStars from '@/components/Basic/CStars'
+import IconButton from '@/components/Basic/IconButton'
 
 // fixme: 通过几层reference传值可能会造成一点困惑 - 咕咕咕
 export default {
-  components: { CIcon, MarkdownSection },
+  components: { IconButton, CStars, CIcon, MarkdownSection },
   props: {
     questionProp: Object,
     index: Number
@@ -46,6 +54,7 @@ export default {
   data () {
     return {
       question: null,
+      star: 0,
       QuestionKind
     }
   },
@@ -61,7 +70,7 @@ export default {
 @import "~@/style/theme.scss";
 
 .quiz-list-item {
-  padding: 24px 8px;
+  padding: 32px 16px 0 16px;
   display: flex;
 
   &__index {
@@ -88,4 +97,29 @@ export default {
     color: $theme-red;
   }
 }
+
+.do-quiz-question-card {
+  overflow: hidden;
+}
+.action-bar {
+  opacity: 0.4;
+  display: flex;
+  justify-content: flex-end;
+  align-items: center;
+  padding: 0 16px 6px 16px;
+  position: relative;
+  border-top: 100px;
+  transition: .2s;
+  backdrop-filter: saturate(200%);
+
+  &:hover {
+    opacity: 1;
+  }
+}
+
+@media (max-width: 500px) {
+  .action-bar {
+    opacity: 1;
+  }
+}
 </style>

+ 1 - 1
src/views/student/tabs/StudentExplore.vue

@@ -13,7 +13,7 @@
         </c-button>
       </tab-actions>
       <section>
-        <h1 class="sub-title mb-24">按课程浏览课件</h1>
+        <h1 class="sub-title mb-12">按课程浏览课件</h1>
         <div class="no-content-warning" v-if="courses === null">
           <div class="no-content-warning-tip">加载中...</div>
         </div>

+ 6 - 4
src/views/student/tabs/StudentQuiz.vue

@@ -1,8 +1,11 @@
 <template>
   <div class="tab complex-tab">
     <div class="left">
-      <h1 class="title">课程测验
-        <c-tag theme="green">学生</c-tag>
+      <h1 class="title">
+        课程测验
+        <router-link>
+          <c-button icon=""></c-button>
+        </router-link>
       </h1>
       <div class="show-quiz-type-bar mb-24">
         <c-button block :right="6" @click="showOngoing = true" :theme="showOngoing ? 'green' : 'normal'">进行中</c-button>
@@ -32,14 +35,13 @@
 </template>
 
 <script>
-import CTag from '@/components/Basic/CTag'
 import QuizCard from '@/components/Cards/QuizCard'
 import CButton from '@/components/Basic/CButton'
 import { QuizState } from '@/enums/quiz-state'
 import { studentGetQuizzesByState } from '@/server/quiz'
 
 export default {
-  components: { CButton, QuizCard, CTag },
+  components: { CButton, QuizCard },
   data () {
     return {
       ongoingQuizzes: [],