This commit is contained in:
2026-10-11 16:00:40 +07:00
parent 5980a5385e
commit 1c48c52a99
7 changed files with 60 additions and 57 deletions
+17 -17
View File
@@ -1875,7 +1875,7 @@ message SetScreenSoundRsp {
message MapItem {
string kind = 1;
int32 itemID = 2;
string itemID = 2;
string label = 3;
int32 x = 4;
int32 y = 5;
@@ -1895,7 +1895,7 @@ message GetGameMapRsp {
message UpdateGameMapItemReq {
int32 gameID = 1;
string kind = 2;
int32 itemID = 3;
string itemID = 3;
int32 x = 4;
int32 y = 5;
bool hidden = 6;
@@ -2008,7 +2008,7 @@ message ParticipationRsp {
}
message Team {
int32 ID = 1;
string ID = 1;
string name = 2;
string status = 3;
string password = 4;
@@ -2076,7 +2076,7 @@ message GetGameResultsRsp {
message GameReview {
int32 ID = 1;
int32 gameID = 2;
int32 teamID = 3;
string teamID = 3;
string team_name = 4;
int32 rating = 5;
string text = 6;
@@ -2088,7 +2088,7 @@ message GameReview {
message CreateGameReviewReq {
int32 gameID = 1;
int32 teamID = 2;
string teamID = 2;
string password = 3;
int32 rating = 4;
string text = 5;
@@ -2187,12 +2187,12 @@ message AddTeamReq {
}
message AddTeamRsp {
int32 ID = 1;
string ID = 1;
string password = 2;
}
message UpdateTeamReq {
int32 ID = 1;
string ID = 1;
string name = 2;
}
@@ -2200,14 +2200,14 @@ message UpdateTeamRsp {
}
message DeleteTeamReq {
int64 ID = 1;
string ID = 1;
}
message DeleteTeamRsp {
}
message GiveTeamApplicationsReq {
int64 ID = 1;
string ID = 1;
string name = 2;
}
@@ -2215,7 +2215,7 @@ message GiveTeamApplicationsRsp {
}
message GetTeamStoryReq {
int64 ID = 1;
string ID = 1;
string password = 2;
}
@@ -2231,7 +2231,7 @@ message TeamAction {
}
message AddTeamActionReq {
int64 ID = 1;
string ID = 1;
string password = 2;
string code = 3;
}
@@ -2240,14 +2240,14 @@ message AddTeamActionRsp {
}
message DeleteLastTeamActionReq {
int64 ID = 1;
string ID = 1;
}
message DeleteLastTeamActionRsp {
}
message GetTeamAnswersReq {
int64 ID = 1;
string ID = 1;
string password = 2;
}
@@ -2256,7 +2256,7 @@ message GetTeamAnswersRsp {
}
message SubmitTeamAnswersReq {
int64 ID = 1;
string ID = 1;
string password = 2;
repeated Answer answers = 3;
}
@@ -2265,7 +2265,7 @@ message SubmitTeamAnswersRsp {
}
message SetTeamAnswerScoreReq {
int64 ID = 1;
string ID = 1;
string questionCode = 2;
// Балл; отсутствует — сбросить выставленный балл
optional int32 score = 3;
@@ -2404,7 +2404,7 @@ message DeviceHeartbeatReq {
string deviceID = 1;
string connectionID = 2;
optional int32 organizerGameID = 3;
optional int32 teamID = 4;
optional string teamID = 4;
string password = 5;
string screenID = 6;
string accessToken = 7;
@@ -2439,7 +2439,7 @@ message DeviceConnection {
string userAgent = 5;
bool connected = 6;
optional int32 gameID = 7;
optional int32 teamID = 8;
optional string teamID = 8;
optional int32 screenID = 9;
string kind = 10; // browser, organizer, team, screen
}
@@ -405,7 +405,7 @@ export type TeamAnswers = {
};
export type Team = {
ID: number | undefined;
ID: string | undefined;
name: string | undefined;
status: string | undefined;
password: string | undefined;
@@ -712,7 +712,7 @@ export type SetScreenSoundRsp = {
export type MapItem = {
kind: string | undefined;
itemID: number | undefined;
itemID: string | undefined;
label: string | undefined;
x: number | undefined;
y: number | undefined;
@@ -732,7 +732,7 @@ export type GetGameMapRsp = {
export type UpdateGameMapItemReq = {
gameID: number | undefined;
kind: string | undefined;
itemID: number | undefined;
itemID: string | undefined;
x: number | undefined;
y: number | undefined;
hidden: boolean | undefined;
@@ -895,7 +895,7 @@ export type GetGameResultsRsp = {
export type GameReview = {
ID: number | undefined;
gameID: number | undefined;
teamID: number | undefined;
teamID: string | undefined;
teamName: string | undefined;
rating: number | undefined;
text: string | undefined;
@@ -907,7 +907,7 @@ export type GameReview = {
export type CreateGameReviewReq = {
gameID: number | undefined;
teamID: number | undefined;
teamID: string | undefined;
password: string | undefined;
rating: number | undefined;
text: string | undefined;
@@ -1007,12 +1007,12 @@ export type AddTeamReq = {
};
export type AddTeamRsp = {
ID: number | undefined;
ID: string | undefined;
password: string | undefined;
};
export type UpdateTeamReq = {
ID: number | undefined;
ID: string | undefined;
name: string | undefined;
};
@@ -1020,14 +1020,14 @@ export type UpdateTeamRsp = {
};
export type DeleteTeamReq = {
ID: number | undefined;
ID: string | undefined;
};
export type DeleteTeamRsp = {
};
export type GiveTeamApplicationsReq = {
ID: number | undefined;
ID: string | undefined;
name: string | undefined;
};
@@ -1035,7 +1035,7 @@ export type GiveTeamApplicationsRsp = {
};
export type GetTeamStoryReq = {
ID: number | undefined;
ID: string | undefined;
password: string | undefined;
};
@@ -1051,7 +1051,7 @@ export type TeamAction = {
};
export type AddTeamActionReq = {
ID: number | undefined;
ID: string | undefined;
password: string | undefined;
code: string | undefined;
};
@@ -1060,14 +1060,14 @@ export type AddTeamActionRsp = {
};
export type DeleteLastTeamActionReq = {
ID: number | undefined;
ID: string | undefined;
};
export type DeleteLastTeamActionRsp = {
};
export type GetTeamAnswersReq = {
ID: number | undefined;
ID: string | undefined;
password: string | undefined;
};
@@ -1076,7 +1076,7 @@ export type GetTeamAnswersRsp = {
};
export type SubmitTeamAnswersReq = {
ID: number | undefined;
ID: string | undefined;
password: string | undefined;
answers: Answer[] | undefined;
};
@@ -1085,7 +1085,7 @@ export type SubmitTeamAnswersRsp = {
};
export type SetTeamAnswerScoreReq = {
ID: number | undefined;
ID: string | undefined;
questionCode: string | undefined;
// Балл; отсутствует — сбросить выставленный балл
score?: number;
@@ -1285,7 +1285,7 @@ export type DeviceHeartbeatReq = {
deviceID: string | undefined;
connectionID: string | undefined;
organizerGameID?: number;
teamID?: number;
teamID?: string;
password: string | undefined;
screenID: string | undefined;
accessToken: string | undefined;
@@ -1322,7 +1322,7 @@ export type DeviceConnection = {
userAgent: string | undefined;
connected: boolean | undefined;
gameID?: number;
teamID?: number;
teamID?: string;
screenID?: number;
kind: string | undefined;
};
+12 -9
View File
@@ -81,7 +81,6 @@ async function setActiveTab(value: string) {
if (!isGameTab(value) || (value === 'state' ? !canViewState.value : !canManageGame.value)) return
activeTab.value = value
await router.replace({ query: { ...route.query, tab: value } })
if (value === 'answers') await loadGameAnswers()
}
function onStateTabKeydown(event: KeyboardEvent) {
@@ -546,7 +545,7 @@ async function unbindScreen(screen: ScreenState) {
await getGameScreens()
}
async function toTeamStory(id: number, password: string, newTab: boolean = false) {
async function toTeamStory(id: string, password: string, newTab: boolean = false) {
const uri = '/team-story/' + id + '?password=' + password
if (newTab) {
window.open(uri, '_blank')
@@ -687,7 +686,7 @@ async function updateGame() {
}
const giveApplicationTeam = ref<Team>({
ID: 0,
ID: '',
name: '',
status: '',
password: '',
@@ -703,7 +702,7 @@ const giveApplicationTeam = ref<Team>({
const deletedTeamName = ref('')
const deletedTeam = ref<Team>({
ID: 0,
ID: '',
name: '',
status: '',
password: '',
@@ -778,7 +777,7 @@ async function deleteGame() {
router.push('/games')
}
function getTeamStoryURL(id: number, password: string): string {
function getTeamStoryURL(id: string, password: string): string {
const url = new URL(`/team-story/${id}`, window.location.origin)
url.searchParams.set('password', password)
return url.toString()
@@ -866,7 +865,7 @@ const answersTeams = ref<TeamAnswers[]>([])
// Баллы по ключу "teamID:questionCode" (undefined — балл не выставлен)
const scores = ref<Record<string, number | undefined>>({})
function scoreKey(teamID: number | undefined, questionCode: string | undefined): string {
function scoreKey(teamID: string | undefined, questionCode: string | undefined): string {
return (teamID ?? '') + ':' + (questionCode ?? '')
}
@@ -920,9 +919,13 @@ async function saveAllScores() {
await loadGameAnswers()
}
if (canManageGame.value && activeTab.value === 'answers') {
loadGameAnswers()
}
watch(
[canManageGame, activeTab],
([canManage, tab]) => {
if (canManage && tab === 'answers') void loadGameAnswers()
},
{ immediate: true },
)
function getCurrentUTC(): Date {
const now = new Date()
+1 -1
View File
@@ -12,7 +12,7 @@ defineProps<{
const emit = defineEmits<{
add: []
'open-qr': [team: Team]
preview: [id: number, password: string]
preview: [id: string, password: string]
delete: [team: Team]
'give-application': [team: Team, application: Application]
}>()
+8 -8
View File
@@ -25,9 +25,9 @@ const authStore = useAuthStore()
const client = getAuthClient()
const message = useMessage()
const route = useRoute()
const teamId = route.params.id
const teamId = String(route.params.id)
const password = route.query.password
useDeviceContext(() => ({ teamID: Number(teamId), password: typeof password === 'string' ? password : undefined }))
useDeviceContext(() => ({ teamID: teamId, password: typeof password === 'string' ? password : undefined }))
const newPlacesCount = ref(0)
const actions = ref<TeamAction[]>([])
@@ -78,7 +78,7 @@ async function getStory() {
let res
try {
res = await client.GetTeamStory({
ID: Number(teamId),
ID: teamId,
password: password as string,
})
} catch (err) {
@@ -131,7 +131,7 @@ getAnswers()
async function addAction(newCode: string): Promise<boolean> {
try {
await client.AddTeamAction({
ID: Number(teamId),
ID: teamId,
password: password as string,
code: newCode,
})
@@ -165,7 +165,7 @@ async function getAnswers() {
let res
try {
res = await client.GetTeamAnswers({
ID: Number(teamId),
ID: teamId,
password: password as string,
})
} catch (err) {
@@ -183,7 +183,7 @@ async function getAnswers() {
async function submitAnswers() {
await client.SubmitTeamAnswers({
ID: Number(teamId),
ID: teamId,
password: password as string,
answers: (story.value.questions || []).map((question) => ({
questionCode: question.code,
@@ -241,7 +241,7 @@ async function submitReview() {
reviewLoading.value = true
await client.CreateGameReview({
gameID: Number(game.value?.ID),
teamID: Number(teamId),
teamID: teamId,
password: password as string,
rating: reviewRating.value,
difficulty: reviewDifficulty.value,
@@ -255,7 +255,7 @@ async function submitReview() {
async function deleteLast() {
await client.DeleteLastTeamAction({
ID: Number(teamId),
ID: teamId,
})
await getStory()
code.value = ''
@@ -85,13 +85,13 @@ test('requests never overlap; latest context follows in-flight request; disabled
fixture.documentEvents.dispatchEvent(new Event('visibilitychange'))
fixture.callbacks.get(1)!()
const lease = fixture.store.claim()
lease.set({ teamID: 2, password: 'secret' })
lease.set({ teamID: '019a1234-5678-7abc-8def-000000000002', password: 'secret' })
await settle()
assert.equal(requests.length, 1)
first.resolve(json(true))
await settle()
assert.equal(requests.length, 2)
assert.equal(requests[1].teamID, 2)
assert.equal(requests[1].teamID, '019a1234-5678-7abc-8def-000000000002')
assert.equal(requests[0].deviceID, requests[1].deviceID)
assert.equal(requests[0].connectionID, requests[1].connectionID)
globalThis.fetch = async () => json(false)
+3 -3
View File
@@ -9,12 +9,12 @@ test('page leases clear context and reject late updates after navigation', () =>
setActivePinia(createPinia())
const store = useDevicePresenceStore()
const player = store.claim()
player.set({ teamID: 2, password: 'secret' })
assert.equal(store.context.teamID, 2)
player.set({ teamID: '019a1234-5678-7abc-8def-000000000002', password: 'secret' })
assert.equal(store.context.teamID, '019a1234-5678-7abc-8def-000000000002')
const screen = store.claim()
screen.set({ screenID: '3', accessToken: 'token' })
player.clear()
player.set({ teamID: 2, password: 'stale' })
player.set({ teamID: '019a1234-5678-7abc-8def-000000000002', password: 'stale' })
assert.deepEqual(store.context, { screenID: '3', accessToken: 'token' })
screen.clear()
screen.set({ screenID: '3', accessToken: 'stale' })