Forráskód Böngészése

update: 预上线版本

weijin 4 éve
szülő
commit
445e4a0766

+ 5 - 4
src/api/axios.config.ts

@@ -7,7 +7,7 @@ export default function axiosConfig() {
   axios.interceptors.response.use(
     function(response: AxiosResponse) {
       if (process.env.NODE_ENV === 'development') {
-        console.log('[AXIOS] response value: ', response)
+        // console.log('[AXIOS] response value: ', response)
       }
 
       const responseData = response.data
@@ -41,7 +41,7 @@ export default function axiosConfig() {
   axios.interceptors.request.use(
     function(config) {
       if (process.env.NODE_ENV === 'development') {
-        console.log('[AXIOS] request config: ', config)
+        // console.log('[AXIOS] request config: ', config)
       }
       if (store.state.token) {
         config.headers = {
@@ -64,10 +64,11 @@ export default function axiosConfig() {
 axiosConfig()
 
 // const portal = process.env.portalUrl
-const portal = 'http://p.seec.seecoder.cn'
+const portal = 'https://p.seec.seecoder.cn'
+// const portal = 'http://localhost:8088' //dev location
+// const portal = 'https://p-server.seec.seecoder.cn' //backend location
 
 export const getLoginUrl = () => {
-  console.log(portal)
   const location = window.location
   return `${portal}/interaction?client_id=seec-mooc&redirect_uri=${encodeURIComponent(
     location.origin + '/'

+ 9 - 4
src/utils/common.ts

@@ -18,15 +18,20 @@ export const timeLength = function(
   const t = e - s
 
   const duration = dayjs.duration(t, 'millisecond')
-
+  let day = dayjs(end, TIME_FORMAT).diff(
+    dayjs(start, TIME_FORMAT).valueOf(),
+    'day'
+  )
   let hour = duration.get('hour')
   let min = duration.get('minute')
 
   let format = ''
-  if (hour > 0) {
+
+  if (day > 0) {
+    format = `${day}天${hour}小时${min}分`
+  } else if (hour > 0) {
     format = `${hour}小时${min}分`
-  }
-  if (hour <= 0) {
+  } else {
     format = `${min}分`
   }
 

+ 11 - 4
src/views/components/ExamQuestionsInfo.vue

@@ -97,10 +97,17 @@ export default Vue.extend({
       const examId = this.$route.params.examId
       getExamSubmitRecords(examId).then(({ data }) => {
         let records = data.result
-        this.submitAnswers = new Map()
-        records.forEach((val) => {
-          this.submitAnswers.set(val.questionId, val.submitAnswer)
-        })
+        if (records && records.length > 0) {
+          this.submitAnswers = new Map()
+          records.forEach((val) => {
+            this.submitAnswers.set(val.questionId, val.submitAnswer)
+          })
+        } else {
+          this.submitAnswers = new Map()
+          this.examQuestions.forEach((val) => {
+            this.submitAnswers.set(val.id, '无')
+          })
+        }
       })
     }
   },

+ 35 - 12
src/views/exam/BeforeExam.vue

@@ -18,20 +18,31 @@
     </page-header>
     <v-container>
       <v-card class="mb-5" hover style="cursor: default" v-if="examInfo">
-        <v-card-title class="text-h4">{{ examInfo.examName }}</v-card-title>
-        <v-card-subtitle class="text-h5 black--text">评测信息</v-card-subtitle>
-        <v-card-text class="text-body-1 black--text"
-          >开始时间: {{ examInfo.startTime }} 结束时间:
-          {{ examInfo.endTime }} 评测时长:{{ examLength }}
-        </v-card-text>
+        <!--        <v-card-title class="text-h4">{{ examInfo.examName }}</v-card-title>-->
+        <v-card-title class="text-h5 black--text">评测信息</v-card-title>
+        <v-card-text class="text-body-1"
+          >评测名称: {{ examInfo.examName }}</v-card-text
+        >
+        <v-card-text class="text-body-1"
+          >开始时间: {{ examInfo.startTime }}</v-card-text
+        >
+        <v-card-text class="text-body-1"
+          >结束时间: {{ examInfo.endTime }}</v-card-text
+        >
+        <v-card-text class="text-body-1"
+          >评测时长: {{ examLength }}</v-card-text
+        >
 
         <v-card-subtitle class="text-h5 black--text">评测规则</v-card-subtitle>
-        <v-card-text>{{ examInfo.comment }}</v-card-text>
-        <v-card-subtitle class="text-h5 black--text">评测内容</v-card-subtitle>
-        <v-card-text
-          class="text-body-1 black--text"
-          v-if="examQuestionsNum > 0"
+        <v-card-text class="text-body-1"
+          >1. 请按题目顺序作答,题目一旦作答将
+          <strong>不可返回</strong> !</v-card-text
         >
+        <v-card-text class="text-body-1" v-if="examInfo.comment"
+          >2. {{ examInfo.comment }}</v-card-text
+        >
+        <v-card-subtitle class="text-h5 black--text">评测内容</v-card-subtitle>
+        <v-card-text class="text-body-1" v-if="examQuestionsNum > 0">
           客观题 {{ examQuestionsNum - codeQuestionsNum }} 道 编程题
           {{ codeQuestionsNum }} 道
         </v-card-text>
@@ -121,4 +132,16 @@ export default Vue.extend({
 })
 </script>
 
-<style scoped></style>
+<style scoped>
+.text-h5 {
+  padding-bottom: 8px;
+}
+.text-h5 + .text-body-1 {
+  padding-top: 0;
+}
+.text-body-1 {
+  margin-left: 32px;
+  color: rgba(0, 0, 0, 0.6);
+  padding: 10px 16px;
+}
+</style>

+ 39 - 24
src/views/exam/ExamPane.vue

@@ -83,27 +83,29 @@
           <div class="pa-2 px-6 text--secondary justify-space-between d-flex">
             <v-dialog v-model="exitDialog" persistent max-width="290">
               <template v-slot:activator="{ on, attrs }">
-                <v-btn color="error" v-bind="attrs" v-on="on">退出评测</v-btn>
+                <v-btn color="error" v-bind="attrs" v-on="on" @click="leaveExam"
+                  >退出评测</v-btn
+                >
               </template>
-              <v-card>
-                <v-card-title class="headline">
-                  确认离开评测?
-                </v-card-title>
-                <v-card-text>退出后将无法再次进入</v-card-text>
-                <v-card-actions>
-                  <v-spacer></v-spacer>
-                  <v-btn
-                    color="success darken-1"
-                    text
-                    @click="exitDialog = false"
-                  >
-                    否
-                  </v-btn>
-                  <v-btn color="error darken-1" text @click="leaveExam">
-                    是
-                  </v-btn>
-                </v-card-actions>
-              </v-card>
+              <!--              <v-card>-->
+              <!--                <v-card-title class="headline">-->
+              <!--                  确认离开评测?-->
+              <!--                </v-card-title>-->
+              <!--                <v-card-text>退出后将无法再次进入</v-card-text>-->
+              <!--                <v-card-actions>-->
+              <!--                  <v-spacer></v-spacer>-->
+              <!--                  <v-btn-->
+              <!--                    color="success darken-1"-->
+              <!--                    text-->
+              <!--                    @click="exitDialog = false"-->
+              <!--                  >-->
+              <!---->
+              <!--                  </v-btn>-->
+              <!--                  <v-btn color="error darken-1" text @click="leaveExam">-->
+              <!---->
+              <!--                  </v-btn>-->
+              <!--                </v-card-actions>-->
+              <!--              </v-card>-->
             </v-dialog>
             <v-dialog v-model="submitDialog" persistent max-width="290">
               <template v-slot:activator="{ on, attrs }">
@@ -194,7 +196,11 @@
             v-if="currentQuestionIndex >= 0"
             class="d-flex justify-center px-10 py-10"
           >
-            <v-btn color="info" @click="nextQuestion" :disabled="fetchingStem"
+            <v-btn
+              v-if="currentQuestionIndex < this.questionIds.length - 1"
+              color="info"
+              @click="nextQuestion"
+              :disabled="fetchingStem"
               >下一题</v-btn
             >
           </div>
@@ -452,9 +458,18 @@ export default Vue.extend({
                 this.fetchQuestionStem(0)
               } else {
                 // 中途重进考试,可以基于本地存储恢复现场
-                this.objectiveAnswers = new Map(
-                  Object.entries(this.getExamAnswers())
-                )
+                try {
+                  this.objectiveAnswers = new Map(
+                    Object.entries(this.getExamAnswers())
+                  )
+                } catch (e) {
+                  // 本地存储丢失
+                  this.clearLocalStorage()
+                  this.setExamId(this.examId)
+                  this.objectiveAnswers = new Map()
+                  this.currentQuestionIndex = 0
+                  this.fetchQuestionStem(0)
+                }
 
                 getExamSubmitRecords(this.examId).then(({ data }) => {
                   if (data.result.find((val) => val.message)) {

+ 1 - 1
src/views/exam/ExamResult.vue

@@ -72,7 +72,7 @@ export default Vue.extend({
         {
           text: '评测管理',
           disabled: false,
-          href: '/teacher/exams'
+          href: '/teacher/created-exams'
         },
         {
           text: '成绩报告',

+ 5 - 5
src/views/student/StudentHome.vue

@@ -82,11 +82,11 @@ export default Vue.extend({
         url: '/student/home',
         icon: mdiHome
       },
-      {
-        name: '个人信息',
-        url: '/student/info',
-        icon: mdiAccount
-      },
+      // {
+      //   name: '个人信息',
+      //   url: '/student/info',
+      //   icon: mdiAccount
+      // },
       {
         name: '我的评测',
         url: '/student/exams',

+ 13 - 3
src/views/student/components/StudentExamInfoCard.vue

@@ -24,15 +24,25 @@
       </v-col>
       <v-col class="mr-3 d-flex justify-end">
         <v-btn
-          v-if="state === '未开始'"
+          v-if="
+            !examInfo.isJoined && (state === '未开始' || state === '进行中')
+          "
           :disabled="examInfo.isJoined"
           :outlined="examInfo.isJoined"
           color="primary"
           class="mx-2"
           @click="onJoinExam"
         >
-          <template v-if="examInfo.isJoined">已加入</template>
-          <template v-else>报名参加</template>
+          <template>报名参加</template>
+        </v-btn>
+        <v-btn
+          v-if="examInfo.isJoined && state === '未开始'"
+          :disabled="examInfo.isJoined"
+          :outlined="examInfo.isJoined"
+          color="primary"
+          class="mx-2"
+        >
+          <template>已经加入</template>
         </v-btn>
         <v-btn
           v-if="examInfo.isJoined && state === '进行中'"

+ 94 - 20
src/views/teacher/ExamCreate.vue

@@ -111,26 +111,86 @@
             ></v-time-picker>
           </v-menu>
         </v-row>
-        <v-slider
-          label="评测时长"
-          :tick-labels="examLengthTicks"
-          class="ma-4"
-          max="5"
-          v-model="examLength"
-        ></v-slider>
+        <!--        <v-slider-->
+        <!--          label="评测时长"-->
+        <!--          :tick-labels="examLengthTicks"-->
+        <!--          class="ma-4"-->
+        <!--          max="5"-->
+        <!--          v-model="examLength"-->
+        <!--        ></v-slider>-->
+        <!--        <v-row class="ma-4">-->
+        <!--          <v-text-field-->
+        <!--            :value="computedEndDate"-->
+        <!--            label="结束日期"-->
+        <!--            prepend-icon="mdi-calendar"-->
+        <!--            disabled-->
+        <!--          ></v-text-field>-->
+        <!--          <v-text-field-->
+        <!--            :value="computedEndTime"-->
+        <!--            label="结束时间"-->
+        <!--            prepend-icon="mdi-clock-time-four-outline"-->
+        <!--            disabled-->
+        <!--          ></v-text-field>-->
+        <!--        </v-row>-->
+        <!--结束日期/时间-->
         <v-row class="ma-4">
-          <v-text-field
-            :value="computedEndDate"
-            label="结束日期"
-            prepend-icon="mdi-calendar"
-            disabled
-          ></v-text-field>
-          <v-text-field
-            :value="computedEndTime"
-            label="结束时间"
-            prepend-icon="mdi-clock-time-four-outline"
-            disabled
-          ></v-text-field>
+          <v-menu
+            v-model="menu3"
+            :close-on-content-click="false"
+            transition="scale-transition"
+            offset-y
+            max-width="290px"
+            min-width="290px"
+          >
+            <template v-slot:activator="{ on, attrs }">
+              <v-text-field
+                v-model="endDate"
+                label="结束日期"
+                prepend-icon="mdi-calendar"
+                readonly
+                v-bind="attrs"
+                v-on="on"
+              ></v-text-field>
+            </template>
+            <v-date-picker
+              v-model="endDate"
+              no-title
+              @input="menu3 = false"
+              :min="minEndDate"
+            ></v-date-picker>
+          </v-menu>
+
+          <v-menu
+            v-model="menu4"
+            ref="menu4"
+            :close-on-content-click="false"
+            :nudge-right="40"
+            :return-value.sync="endTime"
+            transition="scale-transition"
+            offset-y
+            max-width="290px"
+            min-width="290px"
+          >
+            <template v-slot:activator="{ on, attrs }">
+              <v-text-field
+                v-model="endTime"
+                label="结束时间"
+                prepend-icon="mdi-clock-time-four-outline"
+                readonly
+                v-bind="attrs"
+                v-on="on"
+                :rules="arrayRules"
+              ></v-text-field>
+            </template>
+            <v-time-picker
+              v-if="menu4"
+              v-model="endTime"
+              full-width
+              @click:minute="$refs.menu4.save(endTime)"
+              :min="minEndTime"
+              format="24hr"
+            ></v-time-picker>
+          </v-menu>
         </v-row>
         <v-row class="pl-2">
           <v-switch
@@ -222,6 +282,8 @@ export default Vue.extend({
       difficulty: 50,
       startDate: '',
       startTime: '',
+      endDate: '',
+      endTime: '',
       comment: '',
       antiCheating: false,
       isPrivate: false,
@@ -241,6 +303,7 @@ export default Vue.extend({
       ],
       examLength: 0,
       minStartDate: '',
+      minEndDate: '',
       nowDateTimeFormatted: '',
       nowDatetime: (null as unknown) as Dayjs
     }
@@ -256,6 +319,15 @@ export default Vue.extend({
       }
       return ''
     },
+    minEndTime(): string {
+      const nowDate = this.nowDateTimeFormatted.substr(0, 10)
+      const min = this.nowDatetime.add(5, 'minute').format('HH:mm') // bad
+
+      if (this.endDate === nowDate) {
+        return min
+      }
+      return ''
+    },
 
     computedEndDate(): string {
       if (this.startTime === '') {
@@ -294,7 +366,7 @@ export default Vue.extend({
         skills: this.skills,
         difficulty: this.difficulty,
         startTime: this.startDate + ' ' + this.startTime + ':00',
-        endTime: this.computedExamEndDateTime,
+        endTime: this.endDate + ' ' + this.endTime + ':00',
         comment: this.comment,
         antiCheating: this.antiCheating,
         isPublic: !this.isPrivate
@@ -316,7 +388,9 @@ export default Vue.extend({
     this.nowDatetime = dayjs()
     this.nowDateTimeFormatted = this.nowDatetime.format(TIME_FORMAT)
     this.startDate = this.nowDateTimeFormatted.substr(0, 10)
+    this.endDate = this.startDate
     this.minStartDate = this.startDate
+    this.minEndDate = this.startDate
   }
 })
 </script>

+ 1 - 1
src/views/teacher/ExamManage.vue

@@ -77,7 +77,7 @@ export default Vue.extend({
         {
           text: '主页',
           disabled: false,
-          href: '/teacher'
+          href: '/teacher/home'
         },
         {
           text: '评测管理',

+ 1 - 1
vue.config.js

@@ -13,7 +13,7 @@ module.exports = {
         changeOrigin: true
       },
       '^/analysis_api': {
-        target: 'http://analysis.seec.seecoder.cn',
+        target: 'https://analysis.seec.seecoder.cn',
         pathRewrite: {
           '^/analysis_api': '/eval'
         }