|
|
@@ -2,7 +2,22 @@
|
|
|
<v-card hover class="ma-5 px-3 my-8" style="cursor: default;height: 20%">
|
|
|
<v-row>
|
|
|
<v-col class="d-flex">
|
|
|
- <v-card-title class="ma-0 pa-0">{{ examInfo.examName }}</v-card-title>
|
|
|
+ <v-card-title class="ma-0 pa-0">
|
|
|
+ <v-tooltip top v-if="examInfo.isPublic">
|
|
|
+ <template v-slot:activator="{ on, attrs }">
|
|
|
+ <v-icon v-bind="attrs" v-on="on">mdi-lock-off</v-icon>
|
|
|
+ </template>
|
|
|
+ <span>无需邀请码即可加入</span>
|
|
|
+ </v-tooltip>
|
|
|
+ <v-tooltip top v-else>
|
|
|
+ <template v-slot:activator="{ on, attrs }">
|
|
|
+ <v-icon v-bind="attrs" v-on="on">mdi-lock</v-icon>
|
|
|
+ </template>
|
|
|
+ <span>输入邀请码加入评测</span>
|
|
|
+ </v-tooltip>
|
|
|
+
|
|
|
+ {{ examInfo.examName }}</v-card-title
|
|
|
+ >
|
|
|
<v-chip :color="statusToColor(state)" label class="ml-5" outlined>{{
|
|
|
state
|
|
|
}}</v-chip>
|
|
|
@@ -71,6 +86,20 @@
|
|
|
</v-col>
|
|
|
<v-spacer></v-spacer>
|
|
|
</v-row>
|
|
|
+ <v-dialog v-model="inputInviteCode" max-width="500">
|
|
|
+ <v-card class="pa-2 pt-3">
|
|
|
+ <v-text-field label="请输入邀请码" v-model="inviteCode"> </v-text-field>
|
|
|
+ <v-card-actions class="justify-end">
|
|
|
+ <v-btn color="success" @click="joinExamByInviteCode">确定</v-btn>
|
|
|
+ </v-card-actions>
|
|
|
+ </v-card>
|
|
|
+ </v-dialog>
|
|
|
+ <v-snackbar top v-model="joinSuccess" timeout="2000" color="success">
|
|
|
+ 加入评测成功
|
|
|
+ </v-snackbar>
|
|
|
+ <v-snackbar top v-model="joinFailed" timeout="2000" color="error">
|
|
|
+ 加入评测失败,验证码错误
|
|
|
+ </v-snackbar>
|
|
|
</v-card>
|
|
|
</template>
|
|
|
|
|
|
@@ -84,7 +113,11 @@ export default Vue.extend({
|
|
|
name: 'StudentExamInfoCard',
|
|
|
data() {
|
|
|
return {
|
|
|
- state: (null as unknown) as ExamStateText
|
|
|
+ state: (null as unknown) as ExamStateText,
|
|
|
+ inviteCode: '',
|
|
|
+ inputInviteCode: false,
|
|
|
+ joinSuccess: false,
|
|
|
+ joinFailed: false
|
|
|
}
|
|
|
},
|
|
|
props: {
|
|
|
@@ -103,15 +136,31 @@ export default Vue.extend({
|
|
|
getExamLength(startTime: LocalDateTime, endTime: LocalDateTime): string {
|
|
|
return timeLength(startTime, endTime)
|
|
|
},
|
|
|
- onJoinExam() {
|
|
|
+ joinExamByInviteCode() {
|
|
|
const examId = this.examInfo.examId ?? 0
|
|
|
- const inviteCode = this.examInfo.inviteCode ?? ''
|
|
|
- joinExamByInviteCode(inviteCode, examId).then(({ data }) => {
|
|
|
- const joinSuccess = data.result
|
|
|
- if (joinSuccess) {
|
|
|
- this.$emit('joinExam')
|
|
|
- }
|
|
|
- })
|
|
|
+ const inviteCode = this.inviteCode
|
|
|
+ joinExamByInviteCode(inviteCode, examId)
|
|
|
+ .then(({ data }) => {
|
|
|
+ const joinSuccess = data.result
|
|
|
+ this.inputInviteCode = false
|
|
|
+ if (joinSuccess) {
|
|
|
+ this.joinSuccess = true
|
|
|
+ this.$emit('joinExam')
|
|
|
+ } else {
|
|
|
+ this.joinFailed = true
|
|
|
+ }
|
|
|
+ })
|
|
|
+ .finally(() => {
|
|
|
+ this.inviteCode = ''
|
|
|
+ })
|
|
|
+ },
|
|
|
+
|
|
|
+ onJoinExam() {
|
|
|
+ if (this.examInfo.isPublic) {
|
|
|
+ //TODO
|
|
|
+ } else {
|
|
|
+ this.inputInviteCode = true
|
|
|
+ }
|
|
|
},
|
|
|
onOpenResult() {
|
|
|
const examId = this.examInfo.examId?.toString() ?? ''
|