chore: sync various improvements and fixes
- Update gitignore and serena config - Improve connection and voting stores - Enhance admin routes and socket handling - Update client-screen views - Add auth middleware Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -4,6 +4,7 @@ import { useRouter } from 'vue-router';
|
||||
import { useAdminStore } from '../stores/admin';
|
||||
import { PRIZE_CONFIG } from '@gala/shared/types';
|
||||
import type { PrizeConfig, LotteryRound } from '@gala/shared/types';
|
||||
import { ADMIN_TOKEN_KEY } from '../router';
|
||||
|
||||
// 简单的防抖函数
|
||||
function debounce<T extends (...args: any[]) => void>(fn: T, delay: number = 300): (...args: Parameters<T>) => void {
|
||||
@@ -35,6 +36,15 @@ function debounceLeading<T extends (...args: any[]) => void>(fn: T, delay: numbe
|
||||
|
||||
const router = useRouter();
|
||||
const admin = useAdminStore();
|
||||
const adminToken = () => localStorage.getItem(ADMIN_TOKEN_KEY) || '';
|
||||
|
||||
function getAdminHeaders(extra?: Record<string, string>) {
|
||||
return {
|
||||
'Content-Type': 'application/json',
|
||||
'x-session-token': adminToken(),
|
||||
...extra,
|
||||
};
|
||||
}
|
||||
|
||||
// Local UI state
|
||||
const confirmResetCode = ref('');
|
||||
@@ -89,7 +99,9 @@ async function readJsonSafe(res: Response): Promise<any> {
|
||||
async function loadPrizeConfig() {
|
||||
prizeConfigLoading.value = true;
|
||||
try {
|
||||
const res = await fetch('/api/admin/prizes');
|
||||
const res = await fetch('/api/admin/prizes', {
|
||||
headers: getAdminHeaders(),
|
||||
});
|
||||
const data = await readJsonSafe(res);
|
||||
if (!res.ok) {
|
||||
throw new Error(data?.error || data?.message || `加载奖项配置失败(${res.status})`);
|
||||
@@ -112,7 +124,7 @@ async function savePrizeConfig() {
|
||||
try {
|
||||
const res = await fetch('/api/admin/prizes', {
|
||||
method: 'PUT',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
headers: getAdminHeaders(),
|
||||
body: JSON.stringify({ prizes: editingPrizes.value }),
|
||||
});
|
||||
const data = await readJsonSafe(res);
|
||||
@@ -172,6 +184,7 @@ async function importParticipants() {
|
||||
|
||||
const response = await fetch('/api/admin/participants/import', {
|
||||
method: 'POST',
|
||||
headers: { 'x-session-token': adminToken() },
|
||||
body: formData,
|
||||
});
|
||||
|
||||
@@ -219,7 +232,9 @@ const tagLabels: Record<string, string> = {
|
||||
// Load existing participants from server
|
||||
async function loadParticipants() {
|
||||
try {
|
||||
const response = await fetch('/api/admin/participants');
|
||||
const response = await fetch('/api/admin/participants', {
|
||||
headers: getAdminHeaders(),
|
||||
});
|
||||
const data = await readJsonSafe(response);
|
||||
if (!response.ok) {
|
||||
throw new Error(data?.error || data?.message || `加载参与者失败(${response.status})`);
|
||||
@@ -331,7 +346,7 @@ async function redrawCurrentRound() {
|
||||
try {
|
||||
const res = await fetch('/api/admin/lottery/redraw', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
headers: getAdminHeaders(),
|
||||
});
|
||||
const data = await res.json();
|
||||
if (data.success) {
|
||||
@@ -386,7 +401,7 @@ async function confirmAdvancedCleanup() {
|
||||
try {
|
||||
const res = await fetch('/api/admin/cleanup', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
headers: getAdminHeaders(),
|
||||
body: JSON.stringify({
|
||||
lottery: cleanupOptions.value.lottery,
|
||||
voting: cleanupOptions.value.voting,
|
||||
|
||||
Reference in New Issue
Block a user