Jelajahi Sumber

admin show answerbook

ali 2 tahun lalu
induk
melakukan
a127398387

+ 1 - 0
src/components/Widgets/Classroom/AdminClassroomShow/components/TestList.vue

@@ -27,6 +27,7 @@
                  outline
                  color="grey"
                  label="تصحیح" />
+          <!--          :to="{name: 'Admin.Classroom.TestSet.Test.AnswerBooks.ShowGrade', params: {classroom_id: classroomId, answer_book_id: inputData.props.row.id}}"-->
         </div>
       </template>
       <template v-else-if="inputData.col.name === 'actions'">

+ 3 - 3
src/components/Widgets/Test/AdminShowTestGrade/AdminShowTestGrade.vue → src/components/Widgets/Test/AdminAnswerBookShow/AdminAnswerBookShow.vue

@@ -1,5 +1,5 @@
 <template>
-  <div class="AdminShowTestGrade"
+  <div class="AdminAnswerBookShow"
        :style="localOptions.style">
     <q-card v-if="!answerBook.loading && answerBook.id">
       <q-card-section class="flex justify-between">
@@ -145,7 +145,7 @@ import { AnswerBook } from 'src/models/AnswerBook.js'
 import { mixinWidget, mixinAuth } from 'src/mixin/Mixins.js'
 
 export default {
-  name: 'AdminShowTestGrade',
+  name: 'AdminAnswerBookShow',
   components: { EntityShow, EntityEdit },
   mixins: [mixinWidget, mixinAuth],
   data () {
@@ -235,7 +235,7 @@ export default {
 </script>
 
 <style scoped lang="scss">
-.AdminShowTestGrade {
+.AdminAnswerBookShow {
   :deep(.q-banner) {
     background: #FCF9F4 0 0 no-repeat padding-box;
     padding: 20px;

+ 0 - 0
src/components/Widgets/Test/AdminShowTestGrade/OptionPanel.vue → src/components/Widgets/Test/AdminAnswerBookShow/OptionPanel.vue


+ 21 - 0
src/components/Widgets/Test/ShowTestGradeForGrader/OptionPanel.vue

@@ -0,0 +1,21 @@
+<template>
+  <option-panel-tabs v-model:options="localOptions">
+    <template #main-tab>
+      ...
+    </template>
+  </option-panel-tabs>
+</template>
+
+<script>
+import { defineComponent } from 'vue'
+import { mixinOptionPanel } from 'quasar-ui-q-page-builder'
+import OptionPanelTabs from 'quasar-ui-q-page-builder/src/components/OptionPanelComponents/OptionPanelTabs.vue'
+
+export default defineComponent({
+  name: 'OptionPanel',
+  components: {
+    OptionPanelTabs
+  },
+  mixins: [mixinOptionPanel]
+})
+</script>

+ 267 - 0
src/components/Widgets/Test/ShowTestGradeForGrader/ShowTestGradeForGrader.vue

@@ -0,0 +1,267 @@
+<template>
+  <div class="ShowTestGradeForGrader"
+       :style="localOptions.style">
+    <q-card v-if="!answerBook.loading && answerBook.id">
+      <q-card-section class="flex justify-between">
+        <div>{{ answerBook.test_info.title }}</div>
+      </q-card-section>
+      <q-separator />
+      <q-banner>
+        وضعیت آزمون:
+        {{ answerBook.status_info.label }}
+      </q-banner>
+      <q-btn v-if="!this.answerBook.grader"
+             color="primary"
+             class="full-width"
+             @click="setGraderToMe">
+        تصحیح توسط شما
+      </q-btn>
+      <q-separator />
+      <q-banner>
+        <div class="row">
+          <div class="col-md-4 col-12">
+            {{ toShamsi(answerBook.attending_start_time) }}
+          </div>
+          <div class="col-md-4 col-12">
+            {{ answerBook.test_info.test_set_info.test_set_questions.length }}
+            سوال
+          </div>
+          <div class="col-md-4 col-12">
+            {{ answerBook.duration }}
+            دقیقه
+          </div>
+        </div>
+      </q-banner>
+      <q-list separator>
+        <q-item v-for="(answerSheet, answerSheetIndex) in answerBook.answer_sheet_info.list"
+                :key="answerSheetIndex"
+                clickable>
+          <q-item-section>
+            <q-item-label v-html="'<span>' + (answerSheetIndex + 1) + ' - </span>' + answerSheet.test_set_question_info.question_info.text" />
+            <q-item-label>
+              <entity-show v-if="mounted"
+                           ref="entityShow"
+                           v-model:value="questionInputs[answerSheetIndex]"
+                           :loaded-data="answerSheet"
+                           :show-close-button="false"
+                           :show-edit-button="false"
+                           :show-expand-button="false"
+                           :show-save-button="false"
+                           :show-index-button="false"
+                           :show-reload-button="false"
+                           :default-layout="false" />
+            </q-item-label>
+            <q-item-label v-if="currentUserIsGrader">
+              <q-input v-model="questionInputs[answerSheetIndex].score"
+                       :loading="questionInputs[answerSheetIndex].loading"
+                       label="نمره">
+                <template v-slot:append>
+                  <q-btn color="primary"
+                         flat
+                         label="ثبت نمره"
+                         :loading="questionInputs[answerSheetIndex].loading"
+                         @click="submitScore(answerSheetIndex)" />
+                </template>
+              </q-input>
+            </q-item-label>
+          </q-item-section>
+
+          <q-item-section side>
+            <q-badge v-if="answerSheet.score !== null">
+              {{ answerSheet.score }}
+              از
+              {{ answerSheet.test_set_question_info.question_info.mark }}
+              نمره
+            </q-badge>
+            <q-badge v-else>
+              {{ answerSheet.test_set_question_info.question_info.mark }}
+              نمره
+            </q-badge>
+          </q-item-section>
+        </q-item>
+      </q-list>
+      <q-separator class="q-my-lg" />
+      <div class="q-pa-lg">
+        <entity-show v-if="mounted"
+                     ref="entityShow"
+                     v-model:value="overallAnswerInput"
+                     :loaded-data="answerBook"
+                     :show-close-button="false"
+                     :show-edit-button="false"
+                     :show-expand-button="false"
+                     :show-save-button="false"
+                     :show-index-button="false"
+                     :show-reload-button="false"
+                     :default-layout="false" />
+      </div>
+      <template v-if="$route.query.send_objection && $route.query.send_objection.toString() === '1'">
+        <q-separator class="q-my-xl" />
+        <q-card-section>
+          <entity-edit v-if="mounted"
+                       ref="objectionEntityEdit"
+                       v-model:value="objectionInputs"
+                       title="ثبت اعتراض"
+                       :api="objectionApi"
+                       :loaded-data="{}"
+                       :show-close-button="false"
+                       :show-edit-button="false"
+                       :show-expand-button="false"
+                       :show-save-button="false"
+                       :show-reload-button="false">
+            <template #after-form-builder>
+              <div class="flex justify-end q-mt-md">
+                <q-btn color="primary"
+                       label="ثبت اعتراض"
+                       @click="sendObjection" />
+              </div>
+            </template>
+          </entity-edit>
+        </q-card-section>
+      </template>
+      <template v-else-if="answerBook.objection_request">
+        <div>
+          متن اعتراض:
+        </div>
+        <div v-html="answerBook.objection_request" />
+      </template>
+      <template v-if="answerBook.objection_result">
+        <div>
+          نتیجه اعتراض:
+        </div>
+        <div v-html="answerBook.objection_result" />
+      </template>
+    </q-card>
+    <div v-else>
+      کمی صبر کنید...
+    </div>
+  </div>
+</template>
+
+<script>
+import Assist from 'src/assets/js/Assist.js'
+import { APIGateway } from 'src/api/APIGateway.js'
+import { EntityShow, EntityEdit } from 'quasar-crud'
+import { AnswerBook } from 'src/models/AnswerBook.js'
+import { mixinWidget, mixinAuth } from 'src/mixin/Mixins.js'
+
+export default {
+  name: 'ShowTestGradeForGrader',
+  components: { EntityShow, EntityEdit },
+  mixins: [mixinWidget, mixinAuth],
+  data () {
+    return {
+      mounted: false,
+      currentUserIsGrader: false,
+      overallAnswerInput: [
+        { type: 'input', name: 'overall_answer_text', responseKey: 'overall_answer_text', label: 'متن پاسخ جامع', placeholder: ' ', inputType: 'textarea', col: 'col-12' },
+        { type: 'file', name: 'overall_answer_attachment', responseKey: 'overall_answer_attachment', label: 'فایل پیوست جامع', placeholder: ' ', col: 'col-12' }
+      ],
+      questionInput: [
+        { type: 'input', name: 'answer_text', responseKey: 'answer_text', label: 'متن پاسخ', placeholder: ' ', inputType: 'textarea', col: 'col-12' },
+        { type: 'file', name: 'answer_attachment', responseKey: 'answer_attachment', label: 'فایل پیوست', placeholder: ' ', col: 'col-12' }
+      ],
+      questionInputs: [],
+      objectionInputs: [
+        { type: 'input', name: 'objection_request', responseKey: 'objection_request', label: 'متن اعتراض', placeholder: ' ', inputType: 'textarea', col: 'col-12' }
+      ],
+      objectionApi: APIGateway.answerBook.APIAdresses.submitObjectionRequest(this.$route.params.answer_book_id),
+      participateType: null,
+      participateTypeDialog: false,
+      answerBook: new AnswerBook(),
+      timerInterval: null
+    }
+  },
+  mounted () {
+    this.getAnswerBook()
+    this.mounted = true
+  },
+  methods: {
+    sendObjection () {
+      this.answerBook.loading = true
+      this.$refs.objectionEntityEdit.editEntity(false)
+        .then(() => {
+          this.getTestQuestions()
+        })
+        .catch(() => {
+          this.getTestQuestions()
+        })
+    },
+    toShamsi (miladi) {
+      return Assist.miladiToShamsi(miladi)
+    },
+    loadAnswerBook (answerBook) {
+      this.answerBook = new AnswerBook(answerBook)
+      this.answerBook.answer_sheet_info.list.forEach(() => {
+        this.questionInputs.push(this.questionInput)
+      })
+      this.currentUserIsGrader = this.answerBook.grader === this.user.id
+    },
+    setGraderToMe () {
+      this.answerBook.loading = true
+      APIGateway.answerBook.setGraderToMe(this.$route.params.answer_book_id)
+        .then((answerBook) => {
+          this.loadAnswerBook(answerBook)
+          this.answerBook.loading = false
+        })
+        .catch(() => {
+          this.getAnswerBook()
+          this.answerBook.loading = false
+        })
+    },
+    submitScore (index) {
+      this.questionInputs[index].loading = true
+      APIGateway.answerSheet.submitScore(this.$route.params.answer_book_id, this.questionInputs[index])
+        .then(() => {
+          this.questionInputs[index].loading = false
+          this.getAnswerBook()
+        })
+        .catch(() => {
+          this.questionInputs[index].loading = false
+        })
+    },
+    getAnswerBook () {
+      this.answerBook.loading = true
+      APIGateway.answerBook.get(this.$route.params.answer_book_id)
+        .then((answerBook) => {
+          this.loadAnswerBook(answerBook)
+          this.answerBook.loading = false
+        })
+        .catch(() => {
+          this.answerBook.loading = false
+        })
+    }
+  }
+}
+</script>
+
+<style scoped lang="scss">
+.ShowTestGradeForGrader {
+  :deep(.q-banner) {
+    background: #FCF9F4 0 0 no-repeat padding-box;
+    padding: 20px;
+    .q-banner__content {
+      font-size: 16px;
+      font-weight: normal;
+    }
+  }
+  :deep(.q-list) {
+    .q-item {
+      .q-item__section {
+        display: inline-block;
+        .entity-crud-formBuilder {
+          margin-top: 8px;
+          .outsideLabel {
+            margin-bottom: 8px;
+          }
+        }
+      }
+      .q-badge {
+        background: #ACBCAE 0 0 no-repeat padding-box;
+        border-radius: 18px;
+        height: 32px;
+        padding: 4px 16px;
+      }
+    }
+  }
+}
+</style>

+ 2 - 2
src/pages/Admin/Classroom/ClassroomAnswerBookShowGrade.vue

@@ -9,11 +9,11 @@
 import { mixinPageOptions } from 'src/mixin/Mixins.js'
 
 export default {
-  name: 'UserPanel.Classroom.MyAsGraderClassroom.AnswerBooks.ShowGrade',
+  name: 'Admin.Classroom.TestSet.Test.AnswerBooks.ShowGrade',
   mixins: [mixinPageOptions],
   data: () => {
     return {
-      sections: [{ data: { rows: [{ cols: [{ widgets: [{ name: 'AdminShowTestGrade' }] }] }] } }]
+      sections: [{ data: { rows: [{ cols: [{ widgets: [{ name: 'AdminAnswerBookShow' }] }] }] } }]
     }
   },
   created() {

+ 23 - 0
src/pages/Admin/Classroom/ClassroomAnswerBookShowGradeForGrader.vue

@@ -0,0 +1,23 @@
+<template>
+  <q-page-builder v-model:sections="currenSections"
+                  v-model:options="pageConfig"
+                  :editable="pageBuilderEditable"
+                  :loading="pageBuilderLoading" />
+</template>
+
+<script>
+import { mixinPageOptions } from 'src/mixin/Mixins.js'
+
+export default {
+  name: 'UserPanel.Classroom.MyAsGraderClassroom.AnswerBooks.ShowGrade',
+  mixins: [mixinPageOptions],
+  data: () => {
+    return {
+      sections: [{ data: { rows: [{ cols: [{ widgets: [{ name: 'ShowTestGradeForGrader' }] }] }] } }]
+    }
+  },
+  created() {
+    this.currenSections = this.sections
+  }
+}
+</script>

+ 4 - 2
src/router/routes.js

@@ -344,7 +344,7 @@ const routes = [
                 children: [
                   { name: 'UserPanel.Classroom.MyAsGraderClassroom.Index', path: '', component: () => import('src/pages/Admin/Classroom/MyAsGraderClassrooms.vue') },
                   { name: 'UserPanel.Classroom.MyAsGraderClassroom.AnswerBooks', path: ':classroom_id/answer_books', component: () => import('src/pages/Admin/Classroom/ClassroomAnswerBooks.vue') },
-                  { name: 'UserPanel.Classroom.MyAsGraderClassroom.AnswerBooks.ShowGrade', path: ':classroom_id/answer_books/:answer_book_id/show_grades', component: () => import('src/pages/Admin/Classroom/ClassroomAnswerBookShowGrade.vue') },
+                  { name: 'UserPanel.Classroom.MyAsGraderClassroom.AnswerBooks.ShowGrade', path: ':classroom_id/answer_books/:answer_book_id/show_grades', component: () => import('src/pages/Admin/Classroom/ClassroomAnswerBookShowGradeForGrader.vue') },
                   { name: 'UserPanel.Classroom.MyAsGraderClassroom.AnswerBooks.SubmitGrade', path: ':classroom_id/answer_books/:answer_book_id/submit_grade', component: () => import('src/pages/Admin/Classroom/ClassroomAnswerBookSubmitGrade.vue') }
                 ]
               }
@@ -680,7 +680,9 @@ const routes = [
                     children: [
                       { name: 'Admin.Classroom.TestSet.Index', path: '', component: () => import('src/pages/Admin/TestSet/Index.vue') },
                       { name: 'Admin.Classroom.TestSet.Test.Show', path: ':test_set_id/test/:id', component: () => import('src/pages/Admin/Test/Show.vue') },
-                      { name: 'Admin.Classroom.TestSet.Test.Create', path: ':test_set_id/test/create', component: () => import('src/pages/Admin/Test/Create.vue') }
+                      { name: 'Admin.Classroom.TestSet.Test.Create', path: ':test_set_id/test/create', component: () => import('src/pages/Admin/Test/Create.vue') },
+                      { name: 'Admin.Classroom.TestSet.Test.AnswerBooks.Index', path: 'answer_books', component: () => import('src/pages/Admin/Classroom/ClassroomAnswerBookShowGrade.vue') },
+                      { name: 'Admin.Classroom.TestSet.Test.AnswerBooks.ShowGrade', path: 'answer_books/:answer_book_id/show_grades', component: () => import('src/pages/Admin/Classroom/ClassroomAnswerBookShowGrade.vue') }
                     ]
                   }
                 ]