Browse Source

接口对接

ChengYuXuan 5 years ago
parent
commit
5175500fcf

+ 1 - 1
src/api/axios.config.ts

@@ -12,7 +12,7 @@ export default function axiosConfig() {
 
       const responseData = response.data
 
-      if (responseData.err === 0) {
+      if (responseData.code === 0) {
         return Promise.resolve(response)
       } else {
         return Promise.reject(response)

+ 37 - 7
src/api/exam.ts

@@ -6,13 +6,17 @@ import {
   Pageable,
   ExamStatus,
   ID,
-  ExamQuestionSerializer
+  ExamQuestionSerializer,
+  LocalDateTime
 } from '@/api/types'
 
-export const getAllExamList = (
-  params: Pageable<{ status?: ExamStatus; id?: ID }>
-) => {
-  return axios.get<ReceivedData<Array<ExamSerializer>>>(`${EXAM_MODULE}`, {
+export const createExam = (exam: ExamSerializer) => {
+  return axios.post<ReceivedData>(`${EXAM_MODULE}`, exam)
+}
+
+// TODO pageable URL
+export const getAllExamList = (params?: Pageable) => {
+  return axios.get<ReceivedData<Array<ExamSerializer>>>(`${EXAM_MODULE}/list`, {
     params
   })
 }
@@ -21,8 +25,10 @@ export const getExamById = (examId: ID) => {
   return axios.get<ReceivedData<ExamSerializer>>(`${EXAM_MODULE}/${examId}`)
 }
 
-export const createExam = (exam: object) => {
-  return axios.post(`${EXAM_MODULE}`)
+export const extendExamTime = (examId: ID, endTime: LocalDateTime) => {
+  return axios.put<ReceivedData>(
+    `${EXAM_MODULE}/${examId}/time?endTime=${endTime}`
+  )
 }
 
 export const getExamQuestions = (examId: ID) => {
@@ -30,3 +36,27 @@ export const getExamQuestions = (examId: ID) => {
     `${EXAM_MODULE}/${examId}/question`
   )
 }
+
+export const joinExamByInviteCode = (inviteCode: string, examId: ID) => {
+  return axios.put<ReceivedData>(
+    `${EXAM_MODULE}/invite/code?inviteCode=${inviteCode}&examId=${examId}`
+  )
+}
+
+export const setExamPaperFromSample = (examId: ID, sampleExamPaperId: ID) => {
+  return axios.post<ReceivedData>(
+    `${EXAM_MODULE}/question/sample/${examId}/?sampleExamPaperId=${sampleExamPaperId}`
+  )
+}
+
+export const getExamsByStudentId = (page: Pageable) => {
+  return axios.get<ReceivedData<Array<ExamSerializer>>>(
+    `${EXAM_MODULE}/student/exams?pageSize=${page.pageSize}&pageNum=${page.pageNum}`
+  )
+}
+
+export const getExamsByTeacherId = (page: Pageable) => {
+  return axios.get<ReceivedData<Array<ExamSerializer>>>(
+    `${EXAM_MODULE}/teacher/exams?pageSize=${page.pageSize}&pageNum=${page.pageNum}`
+  )
+}

+ 13 - 0
src/api/judge.ts

@@ -0,0 +1,13 @@
+import axios from 'axios'
+import { JUDGE_MODULE } from '@/api/prefix'
+import { ReceivedData } from '@/api/types'
+
+export const objectiveJudge = (
+  answers: Array<string>,
+  questionIds: Array<string>
+) => {
+  return axios.post<ReceivedData>(`${JUDGE_MODULE}/objective`, {
+    answers,
+    questionIds
+  })
+}

+ 2 - 0
src/api/prefix.ts

@@ -2,3 +2,5 @@ const BASE_URL = '/api'
 
 export const EXAM_MODULE = BASE_URL + '/exam'
 export const QUESTION_MODULE = BASE_URL + '/question'
+export const USER_MODULE = BASE_URL + '/user'
+export const JUDGE_MODULE = BASE_URL + '/judge'

+ 23 - 7
src/api/question.ts

@@ -1,12 +1,28 @@
 import axios from 'axios'
 import { QUESTION_MODULE } from './prefix'
-import { Pageable, QuestionSerializer, ReceivedData } from '@/api/types'
+import {
+  ExamQuestionSerializer,
+  ID,
+  Pageable,
+  ExtendedQuestionSerializer,
+  QuestionStemSerializer,
+  ReceivedData
+} from '@/api/types'
 
-export const getQuestions = (params: Pageable) => {
-  return axios.get<ReceivedData<Array<QuestionSerializer>>>(
-    `${QUESTION_MODULE}/`,
-    {
-      params
-    }
+export const getQuestionInfo = (id: ID) => {
+  return axios.get<ReceivedData<ExtendedQuestionSerializer>>(
+    `${QUESTION_MODULE}/${id}`
+  )
+}
+
+export const getQuestionStem = (id: ID) => {
+  return axios.get<ReceivedData<QuestionStemSerializer>>(
+    `${QUESTION_MODULE}/${id}/stem`
+  )
+}
+
+export const getSamplePaper = () => {
+  return axios.get<ReceivedData<Array<ExamQuestionSerializer>>>(
+    `${QUESTION_MODULE}/sample`
   )
 }

+ 47 - 52
src/api/types.d.ts

@@ -1,60 +1,47 @@
-import { AxiosRequestConfig } from 'axios'
-
 export type ID = number | string
 
 export interface AxiosResponseInfo {}
 
 export interface ReceivedData<R = {}, E = 0> extends AxiosResponseInfo {
-  err?: E | 0 | 401
-  res?: R
+  code: E | 0 | 401
+  result: R
+  msg: string
   page?: PageSerializer
 }
 
+export type QuestionType = 'choice' | 'blank' | 'code' | 'multi_choice'
 export interface ErrorData extends AxiosResponseInfo {
   err: number
   msg: string
 }
 
 export interface PageSerializer {
-  page?: number
-  limit?: number
-  size?: number
-  total?: number
+  pageNum?: number
+  pageSize?: number
 }
 
 export type Pageable<T = {}> = T & {
-  page?: number
-  limit?: number
+  pageNum?: number
+  pageSize?: number
 }
-
+//yyyy-MM-dd HH:mm:ss
 export type LocalDateTime = string
 
 export type UserRole = 'STUDENT' | 'TEACHER'
 
-export type ExamStatus =
-  | 'READY' // 考试已准备好,考试尚未开始
-  | 'AVAILABLE' // 考试可用,表示考试正在进行
-  | 'FINISHED' // 考试已完成,在考试结束后使用
-  | 'CLOSED' // 考试已关闭,表示考试生命周期结束
-
 export interface ExamSerializer {
-  id?: number
-  title?: string
-  startAt?: LocalDateTime
-  endAt?: LocalDateTime
-  status?: ExamStatus
-  creator?: {
-    id?: number
-    username?: string
-  }
-  joined?: boolean
-  // result?: ResultSerializer
-  isReentryPermitted?: boolean
-  inviteCode?: string
+  antiCheating?: boolean
   comment?: string
-  participantsNumber?: number
-  lastTime?: number
+  creatorId?: number
   difficulty?: number
+  endTime?: LocalDateTime
+  examId?: number
+  position?: string
+  skills?: Array<string>
+  startTime?: LocalDateTime
+  examName?: string
+  // 上边是创建考试所需的信息
+  inviteCode?: string
 }
 
 export interface ResultSerializer {
@@ -77,42 +64,48 @@ export interface ResultSerializer {
   }>
 }
 
-export interface OptionSerializer {
-  label?: string
-  content?: string
-}
+export type OptionSerializer = Map<string, string>
 
-export interface QuestionSerializer {
+export interface QuestionStemSerializer {
   id?: number
   stem?: string
-  index?: number
+  type?: QuestionType
+  options?: OptionSerializer
+  keyPoints?: string
+  tags?: Array<string>
+  knowledgeId?: Array<string>
+}
+
+export interface ExtendedQuestionSerializer extends QuestionStemSerializer {
+  answer?: string
+  analysis?: string
+  lastModifiedTime?: LocalDateTime
 }
 
 export type ChoiceAnswer = string
 
-export interface ChoiceQuestionSerializer extends QuestionSerializer {
-  studentId?: number
-  single?: boolean
-  options?: Array<OptionSerializer>
-  lastCommitAnswer?: ChoiceAnswer
-}
+// export interface ChoiceQuestionSerializer extends ExtendedQuestionSerializer {
+//   studentId?: number
+//   single?: boolean
+//   lastCommitAnswer?: ChoiceAnswer
+// }
 
 export interface CodeTuple {
   lang?: string
   code?: string
 }
 
-export interface CodeQuestionSerializer extends QuestionSerializer {
-  studentId?: number
-  codeTuples?: Array<CodeTuple>
-  lastCommitCodes?: Array<CodeTuple>
-}
+// export interface CodeQuestionSerializer extends ExtendedQuestionSerializer {
+//   studentId?: number
+//   codeTuples?: Array<CodeTuple>
+//   lastCommitCodes?: Array<CodeTuple>
+// }
 
 export interface ExamQuestionSerializer {
   id?: number
-  singleChoiceQuestions?: Array<ChoiceQuestionSerializer>
-  multiChoiceQuestions?: Array<ChoiceQuestionSerializer>
-  codeQuestions?: Array<CodeQuestionSerializer>
+  name?: string
+  questionAndScore?: QuestionAndScore
+  // codeQuestions?: Array<CodeQuestionSerializer>
 }
 
 export interface UserSerializer {
@@ -123,3 +116,5 @@ export interface UserSerializer {
   role?: UserRole
   createdAt?: LocalDateTime
 }
+
+export type QuestionAndScore = Map<string, number>

+ 13 - 0
src/api/user.ts

@@ -0,0 +1,13 @@
+import axios from 'axios'
+import { USER_MODULE } from '@/api/prefix'
+import { ID, ReceivedData, UserSerializer } from '@/api/types'
+
+export const getUserInfo = () => {
+  return axios.get<ReceivedData<UserSerializer>>(`${USER_MODULE}`)
+}
+
+export const getExamJoinedUsers = (examId: ID) => {
+  return axios.get<ReceivedData<Array<UserSerializer>>>(
+    `${USER_MODULE}/${examId}`
+  )
+}

+ 3 - 2
src/mock/api/exam/_examId/get.json

@@ -1,4 +1,5 @@
 {
-  "err": 0,
-  "res": "@EXAM_SERIALIZER"
+  "code": 0,
+  "result": "@EXAM_SERIALIZER",
+  "msg": ""
 }

+ 1 - 1
src/mock/api/exam/_examId/question/get.json

@@ -1,5 +1,5 @@
 {
   "err": 0,
-  "res": "@EXAM_QUESTION_SERIALIZER"
+  "result": "@EXAM_QUESTION_SERIALIZER"
 
 }

+ 5 - 0
src/mock/api/exam/_examId/time/put.json

@@ -0,0 +1,5 @@
+{
+  "code": "0",
+  "result": "ok",
+  "msg": ""
+}

+ 0 - 5
src/mock/api/exam/get.json

@@ -1,5 +0,0 @@
-{
-  "err": 0,
-  "res|5": ["@EXAM_SERIALIZER"],
-  "page": "@PAGE_SERIALIZER"
-}

+ 5 - 0
src/mock/api/exam/invite/code/put.json

@@ -0,0 +1,5 @@
+{
+  "result": "ok",
+  "code": "0",
+  "msg": ""
+}

+ 6 - 0
src/mock/api/exam/list/get.json

@@ -0,0 +1,6 @@
+{
+  "code": 0,
+  "result|5-10": ["@EXAM_SERIALIZER"],
+  "page": "@PAGE_SERIALIZER",
+  "msg": ""
+}

+ 3 - 2
src/mock/api/exam/post.json

@@ -1,4 +1,5 @@
 {
-  "err":0,
-  "res": "@Exam_Serializer"
+  "code":0,
+  "result": "ok",
+  "msg": ""
 }

+ 5 - 0
src/mock/api/exam/question/sample/_examId/post.json

@@ -0,0 +1,5 @@
+{
+  "result": "ok",
+  "code": "0",
+  "msg": ""
+}

+ 5 - 0
src/mock/api/exam/student/exams/get.json

@@ -0,0 +1,5 @@
+{
+  "code": "0",
+  "result|1-10": ["@EXAM_SERIALIZER"],
+  "msg": ""
+}

+ 5 - 0
src/mock/api/exam/teacher/exams/get.json

@@ -0,0 +1,5 @@
+{
+  "code": "0",
+  "result|1-10": ["@EXAM_SERIALIZER"],
+  "msg": ""
+}

+ 5 - 0
src/mock/api/judge/objective/post.json

@@ -0,0 +1,5 @@
+{
+  "code":0,
+  "result": "ok",
+  "msg": ""
+}

+ 5 - 0
src/mock/api/question/_id/get.json

@@ -0,0 +1,5 @@
+{
+  "code": "0",
+  "result": "@EXTENDED_QUESTION_SERIALIZER",
+  "msg": ""
+}

+ 5 - 0
src/mock/api/question/_id/stem/get.json

@@ -0,0 +1,5 @@
+{
+  "code": "0",
+  "result": "@QUESTION_STEM_SERIALIZER",
+  "msg": ""
+}

+ 0 - 4
src/mock/api/question/get.json

@@ -1,4 +0,0 @@
-{
-  "err": 0,
-  "res|10": ["@QUESTION_DETAIL_SERIALIZER"]
-}

+ 5 - 0
src/mock/api/question/sample/get.json

@@ -0,0 +1,5 @@
+{
+  "code": "0",
+  "result|1-5":["@EXAM_QUESTION_SERIALIZER"],
+  "msg": ""
+}

+ 3 - 0
src/mock/api/user/_examId/get.json

@@ -0,0 +1,3 @@
+{
+  "students|10-50": ["@USER_SERIALIZER"]
+}

+ 5 - 0
src/mock/api/user/get.json

@@ -0,0 +1,5 @@
+{
+  "result": "@USER_SERIALIZER",
+  "code": "0",
+  "msg": ""
+}

+ 62 - 27
src/mock/serializers.js

@@ -16,33 +16,38 @@ const basicExtendsTypes = () => ({
   CHOICE_PROBLEM_TYPE: (problemType) =>
     problemType || randomArrayValue(['SINGLE', 'MULTI']),
   EXAM_STATUS: (examStatus) =>
-    examStatus || randomArrayValue(['READY', 'AVAILABLE', 'FINISHED', 'CLOSED'])
+    // examStatus || randomArrayValue(['READY', 'AVAILABLE', 'FINISHED', 'CLOSED'])
+    examStatus || randomArrayValue(['READY', 'AVAILABLE', 'FINISHED']),
+  QUESTION_TYPE: () =>
+    randomArrayValue(['choice', 'multi_choice', 'blank', 'code'])
 })
 
 const serializersPlugin = (mock) => ({
+  USER_SERIALIZER: () =>
+    mock({
+      'id|1-1000': 1,
+      username: '@CWORD',
+      email: '@EMAIL',
+      'phone|10000000000-20000000000': 1,
+      role: '@USER_ROLE'
+    }),
   EXAM_SERIALIZER: (examId) =>
     mock({
-      'id|1-2000': 1,
-      title: '@CTITLE',
-      startAt: '@DATETIME',
-      endAt: '@DATETIME',
-      'lastTime|1-3': 1,
-      status: '@EXAM_STATUS',
-      creator: {
-        'id|1-1000': 1,
-        username: '@CNAME'
-      },
-      joined: '@BOOLEAN',
-      isReentryPermitted: '@BOOLEAN',
-      inviteCode: '@WORD(5)',
-      'difficulty|0-100': 1,
-      comment: '@CPARAGRAPH'
+      antiCheating: '@BOOL',
+      comment: '@CPARAGRAPH',
+      'creatorId|100-1000': 1,
+      'difficulty|10-100': 1,
+      endTime: '@DATETIME',
+      'examId|1-2000': 1,
+      position: '@CTITLE',
+      'skills|1-3': ['@CWORD'],
+      startTime: '@DATETIME',
+      examName: '@CTITLE',
+      inviteCode: '@WORD(5)'
     }),
   PAGE_SERIALIZER: () => ({
-    page: 1,
-    limit: 20,
-    size: 20,
-    total: 20
+    pageNum: 1,
+    pageSize: 20
   }),
 
   SINGLE_CHOICE_QUESTION_SERIALIZER: () =>
@@ -131,18 +136,48 @@ const serializersPlugin = (mock) => ({
   EXAM_QUESTION_SERIALIZER: () =>
     mock({
       'id|1-1000': 1,
-      'singleChoiceQuestions|15': ['@SINGLE_CHOICE_QUESTION_SERIALIZER'],
-      'multiChoiceQuestions|10': ['@MULTI_CHOICE_QUESTION_SERIALIZER'],
-      'codeQuestions|3': ['@CODE_QUESTION_SERIALIZER']
+      name: '@CTITLE',
+      questionAndScore: '@QUESTION_AND_SCORE_SERIALIZER'
+    }),
+  QUESTION_AND_SCORE_SERIALIZER: () => {
+    return {
+      '19030': 2,
+      '19031': 3,
+      '19033': 4,
+      '19035': 3,
+      '19037': 2
+    }
+  },
+  QUESTION_STEM_SERIALIZER: () =>
+    mock({
+      'id|1-1000': 1,
+      stem: '@CPARAGRAPH',
+      type: '@QUESTION_TYPE',
+      options: '@OPTION_SERIALIZER',
+      keyPoints: '@CWORD',
+      'tags|1-3': ['@CWORD'],
+      'knowledgeId|1-3': ['@CWORD']
+    }),
+  OPTION_SERIALIZER: () =>
+    mock({
+      A: '@CSENTENCE',
+      B: '@CSENTENCE',
+      C: '@CSENTENCE',
+      D: '@CSENTENCE'
     }),
-  QUESTION_DETAIL_SERIALIZER: () => {
+  EXTENDED_QUESTION_SERIALIZER: () =>
     mock({
       'id|1-1000': 1,
       stem: '@CPARAGRAPH',
-      knowledgeId: '@CWORD',
-      skillId: '@CWORD'
+      type: '@QUESTION_TYPE',
+      options: '@OPTION_SERIALIZER',
+      keyPoints: '@CWORD',
+      'tags|1-3': ['@CWORD'],
+      'knowledgeId|1-3': ['@CWORD'],
+      answer: 'A',
+      analysis: '@CPARAGRAPH',
+      lastModifiedTime: '@DATETIME'
     })
-  }
 })
 
 module.exports = function(random, mock) {

+ 4 - 0
src/router/index.ts

@@ -4,6 +4,7 @@ import student from '@/router/student'
 import exam from '@/router/exam'
 import teacher from '@/router/teacher'
 import store from '@/store/index'
+import { jumpToLogin } from '@/api/axios.config'
 Vue.use(VueRouter)
 
 const routes: Array<RouteConfig> = [
@@ -28,6 +29,9 @@ router.beforeEach((to, from, next) => {
   if (id_token) {
     store.commit('setToken', id_token)
   }
+  // if (!store.getters.isLogin) {
+  //   jumpToLogin()
+  // }
   next()
 })
 

+ 2 - 1
src/store/index.ts

@@ -23,7 +23,8 @@ export const mutations: MutationTree<RootState> = {
 export const getters: GetterTree<RootState, RootState> = {
   isStudent: (state) => state.user.role === 'STUDENT',
   isTeacher: (state) => state.user.role === 'TEACHER',
-  getId: (state) => state.user.id
+  getId: (state) => state.user.id,
+  isLogin: (state) => Boolean(state.token)
 }
 
 export default new Vuex.Store({