<template> <div class="text-h4 headline"> 比赛管理 </div> <v-card class="game-info-card"> <v-container> <!-- <v-card-title color="indigo"> 提交比赛 </v-card-title> --> <v-form ref="form" v-model="isValid"> <v-row no-gutters> <v-col align-self="center"> <v-autocomplete variant="underlined" v-model="player1" label="姓名" :rules="[rules.player_not_none, rules.player1]" :items="arr"></v-autocomplete> </v-col> <v-col cols="2" align-self="center"> <div class="text-h6" style="text-align: center;">VS</div> </v-col> <v-col align-self="center"> <v-autocomplete variant="underlined" v-model="player2" label="姓名" :rules="[rules.player_not_none, rules.player2]" :items="arr"></v-autocomplete> </v-col> </v-row> <v-row no-gutters> <v-col align-self="center"> <v-select variant="underlined" v-model="score1" label="得分" :rules="[rules.score_not_none, rules.score1]" :items="['0', '1', '2', '3', '4', '5']"></v-select> </v-col> <v-col cols="2" align-self="center"> <div class="text-h6" style="text-align: center;">:</div> </v-col> <v-col align-self="center"> <v-select variant="underlined" v-model="score2" label="得分" :rules="[rules.score_not_none, rules.score2]" :items="['0', '1', '2', '3', '4', '5']"></v-select> </v-col> </v-row> <v-dialog> <template v-slot:activator="{ props: activatorProps }"> <v-btn block v-bind="activatorProps" class="text-none mb-4" color="indigo" size="large" variant="outlined"> <template v-slot:default> 选择比赛日期:{{ selectedDate.toLocaleDateString() }} </template> </v-btn> </template> <template v-slot:default="{ isActive }"> <v-card> <v-locale-provider locale="zhHans"> <v-date-picker v-model="selectedDate" header="日期" title="选择比赛日期" color="indigo" width="100%"></v-date-picker> </v-locale-provider> <v-card-actions> <v-spacer></v-spacer> <v-btn variant="flat" text="确定" color="indigo" @click="isActive.value = false"></v-btn> </v-card-actions> </v-card> </template> </v-dialog> <v-btn :disabled="!isValid" :loading="loading" class="text-none mb-4" color="indigo" size="large" variant="flat" block @click="submit"> 提交 </v-btn> </v-form> </v-container> </v-card> <v-dialog v-model="dialog" width="auto"> <v-card width="300px"> <v-card-title> {{ cardtitle }} </v-card-title> <v-card-text> {{ cardtext }} </v-card-text> <template v-slot:actions> <v-btn class="ms-auto" variant="flat" color="indigo" text="确认" @click="dialog = false"></v-btn> </template> </v-card> </v-dialog> <div> <v-card class="mx-auto my-2" href="/lauched_games.html" width="95%" rel="noopener" target="_blank" title="已提交比赛" append-icon="mdi-chevron-right"></v-card> <v-card class="mx-auto my-2" href="/audit_games.html" width="95%" rel="noopener" target="_blank" title="待审核比赛" append-icon="mdi-chevron-right"></v-card> </div> </template> <script setup> import { ref } from 'vue'; import { reactive } from 'vue'; import axios from 'axios'; import { watch } from 'vue'; const isValid = ref(false); const player1 = ref(null); const player2 = ref(null); const score1 = ref(null); const score2 = ref(null); const loading = ref(false); const selectedDate = ref(new Date()); const arr = ref(new Array()); const id = ref(null); const form = ref(null); const form1 = ref(null); const form2 = ref(null); var s1; var s2; var p1_id; var p2_id; const rules = reactive({ email: v => !!(v || '').match(/@/) || 'Please enter a valid email', length: len => v => (v || '').length >= len || `Invalid character length, required ${len}`, player_not_none: v => !!v || '姓名不能为空', player1: v => v != player2.value || '姓名不能相同', player2: v => v != player1.value || '姓名不能相同', required: v => !!v || 'This field is required', score_not_none: v => !!v || '得分不能为空', score1: v => v != score2.value || '得分不能相同', score2: v => v != score1.value || '得分不能相同', }); // 监听 player1 的变化,并更新 player2 的验证规则 watch(player1, (newVal, oldVal) => { if (newVal !== oldVal) { form.value.validate(); // 触发表单验证 } }); watch(player2, (newVal, oldVal) => { if (newVal !== oldVal) { form.value.validate(); // 触发表单验证 } }); watch(score1, (newVal, oldVal) => { if (newVal !== oldVal) { form.value.validate(); // 触发表单验证 } }); watch(score2, (newVal, oldVal) => { if (newVal !== oldVal) { form.value.validate(); // 触发表单验证 } }); axios.get('/api/players') .then(function (response) { const data = response.data; for (var i = 0; i < data.Players.length; i++) { arr.value[i] = data.Players[i].player_id.toString() + '-' + data.Players[i].player_real_name; } }) .catch(function (error) { console.log(error); }) function submit() { loading.value = true; p1_id = parseInt(player1.value); p2_id = parseInt(player2.value); s1 = parseInt(score1.value); s2 = parseInt(score2.value); if (s1 < s2) { id.value = p1_id; } else { id.value = p2_id; } axios.post('/api/launchGame', { player1_id: p1_id, score1: s1, player2_id: p2_id, score2: s2, confirmer_id: id.value, game_date: selectedDate.value.toLocaleDateString(), }) .then(function (response) { const data = response.data; console.log(data) if (data.status == 'SUCCESS') { info('提交成功!', ""); } }) .catch(function (error) { console.log(error); }); loading.value = false; } const cardtitle = ref(null); const cardtext = ref(null); const dialog = ref(false); function info(title, text) { cardtitle.value = title; cardtext.value = text; dialog.value = true; } </script> <style> .game-info-card { width: 95%; margin: auto; margin-top: 20px; /* padding: 5px; */ } .headline { margin-left: 5%; margin-top: 5%; margin-bottom: 2%; } </style>