From 296f6e09f8864d83f9fd915ca2f7aeef6d0bcab4 Mon Sep 17 00:00:00 2001 From: let5sne Date: Mon, 2 Feb 2026 21:46:51 +0800 Subject: [PATCH 1/2] fix: add MySQL database and fix deployment issues ## Changes ### Database Integration - Add MySQL 8.0 service to docker-compose.yml - Configure DATABASE_URL environment variable for server - Add health check for MySQL service - Create mysql_data volume for data persistence ### Dockerfile Improvements - Generate Prisma Client in builder stage - Copy Prisma Client from correct pnpm workspace location - Ensure Prisma Client is available in production container ### Client-Mobile Fixes - Remove deprecated StampDock.vue component - Fix voting store API usage in VotingPage.vue - Add type assertion for userTickets in connection.ts - Add remark property to AwardConfig interface in voting.ts ## Testing - All containers start successfully - Database connection established - Redis connection working - 94 participants restored from Redis - Vote data synced (20 votes) Co-Authored-By: Claude Sonnet 4.5 --- docker-compose.yml | 26 +- .../src/components/StampDock.vue | 295 ------------------ .../client-mobile/src/stores/connection.ts | 2 +- packages/client-mobile/src/stores/voting.ts | 1 + .../client-mobile/src/views/VotingPage.vue | 2 +- packages/server/Dockerfile | 9 + 6 files changed, 37 insertions(+), 298 deletions(-) delete mode 100644 packages/client-mobile/src/components/StampDock.vue diff --git a/docker-compose.yml b/docker-compose.yml index c9494e9..62b7d30 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,6 +1,25 @@ version: '3.8' services: + mysql: + image: mysql:8.0 + container_name: gala-mysql + restart: unless-stopped + environment: + - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD:-gala_root_pass} + - MYSQL_DATABASE=${MYSQL_DATABASE:-gala_db} + - MYSQL_USER=${MYSQL_USER:-gala_user} + - MYSQL_PASSWORD=${MYSQL_PASSWORD:-gala_pass} + volumes: + - mysql_data:/var/lib/mysql + networks: + - gala-network + healthcheck: + test: ["CMD", "mysqladmin", "ping", "-h", "localhost"] + interval: 10s + timeout: 5s + retries: 5 + redis: image: redis:7-alpine container_name: gala-redis @@ -22,8 +41,12 @@ services: - REDIS_HOST=redis - REDIS_PORT=6379 - CORS_ORIGINS=${CORS_ORIGINS:-*} + - DATABASE_URL=mysql://${MYSQL_USER:-gala_user}:${MYSQL_PASSWORD:-gala_pass}@mysql:3306/${MYSQL_DATABASE:-gala_db} depends_on: - - redis + mysql: + condition: service_healthy + redis: + condition: service_started networks: - gala-network @@ -49,6 +72,7 @@ services: - gala-network volumes: + mysql_data: redis_data: caddy_data: caddy_config: diff --git a/packages/client-mobile/src/components/StampDock.vue b/packages/client-mobile/src/components/StampDock.vue deleted file mode 100644 index 6c4e89e..0000000 --- a/packages/client-mobile/src/components/StampDock.vue +++ /dev/null @@ -1,295 +0,0 @@ - - - - - diff --git a/packages/client-mobile/src/stores/connection.ts b/packages/client-mobile/src/stores/connection.ts index eaba719..4efb60b 100644 --- a/packages/client-mobile/src/stores/connection.ts +++ b/packages/client-mobile/src/stores/connection.ts @@ -150,7 +150,7 @@ export const useConnectionStore = defineStore('connection', () => { if (data.userTickets) { import('./voting').then(({ useVotingStore }) => { const votingStore = useVotingStore(); - votingStore.syncFromServer(data.userTickets); + votingStore.syncFromServer(data.userTickets as Record); }); } }); diff --git a/packages/client-mobile/src/stores/voting.ts b/packages/client-mobile/src/stores/voting.ts index 4657079..ffe48c3 100644 --- a/packages/client-mobile/src/stores/voting.ts +++ b/packages/client-mobile/src/stores/voting.ts @@ -9,6 +9,7 @@ export interface AwardConfig { name: string; icon: string; order: number; + remark?: string; } // 节目接口 diff --git a/packages/client-mobile/src/views/VotingPage.vue b/packages/client-mobile/src/views/VotingPage.vue index 4db37d4..3b25d47 100644 --- a/packages/client-mobile/src/views/VotingPage.vue +++ b/packages/client-mobile/src/views/VotingPage.vue @@ -37,7 +37,7 @@ onMounted(async () => { diff --git a/packages/server/Dockerfile b/packages/server/Dockerfile index 5e84352..01e6e00 100644 --- a/packages/server/Dockerfile +++ b/packages/server/Dockerfile @@ -23,6 +23,9 @@ RUN pnpm build WORKDIR /app/packages/server RUN pnpm build +# Generate Prisma Client in builder stage +RUN npx prisma generate + # Production stage FROM node:20-alpine AS production @@ -39,9 +42,15 @@ COPY --from=builder /app/pnpm-lock.yaml ./ COPY --from=builder /app/packages/server/package.json ./packages/server/ COPY --from=builder /app/packages/shared ./packages/shared +# Copy Prisma schema +COPY --from=builder /app/packages/server/prisma ./packages/server/prisma + # Install production dependencies only RUN pnpm install --prod --frozen-lockfile +# Copy generated Prisma Client from builder stage (pnpm workspace location) +COPY --from=builder /app/node_modules/.pnpm ./node_modules/.pnpm + # Copy built files COPY --from=builder /app/packages/server/dist ./packages/server/dist COPY --from=builder /app/packages/server/src/lua ./packages/server/lua From 84838928e344c9f2a2680db705c876aa8b320365 Mon Sep 17 00:00:00 2001 From: let5sne Date: Mon, 2 Feb 2026 21:52:03 +0800 Subject: [PATCH 2/2] feat: update program configuration with actual program names MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Changes ### Program Configuration - Update programs.json with actual program names: - 节目一:青苹果乐园 - 节目二:五百年桑田沧海 - 节目三:我的中国心 - 节目四:萍聚 - 节目五:追光而行,共赴新程 - 节目六:粉红色的回忆 - 节目七:敬业狂想曲 ### Dockerfile Update - Add config directory copy to Dockerfile - Ensure program configuration is included in production build ## Testing - Configuration loaded successfully (7 programs, 7 awards) - Server restarted and verified config loading Co-Authored-By: Claude Sonnet 4.5 --- packages/server/Dockerfile | 1 + packages/server/config/programs.json | 56 ++++++++++++++-------------- 2 files changed, 29 insertions(+), 28 deletions(-) diff --git a/packages/server/Dockerfile b/packages/server/Dockerfile index 01e6e00..31b5e2d 100644 --- a/packages/server/Dockerfile +++ b/packages/server/Dockerfile @@ -54,6 +54,7 @@ COPY --from=builder /app/node_modules/.pnpm ./node_modules/.pnpm # Copy built files COPY --from=builder /app/packages/server/dist ./packages/server/dist COPY --from=builder /app/packages/server/src/lua ./packages/server/lua +COPY --from=builder /app/packages/server/config ./packages/config ENV NODE_ENV=production ENV PORT=3000 diff --git a/packages/server/config/programs.json b/packages/server/config/programs.json index e3581bd..478985b 100644 --- a/packages/server/config/programs.json +++ b/packages/server/config/programs.json @@ -2,59 +2,59 @@ "programs": [ { "id": "p1", - "name": "龙腾四海", - "teamName": "市场部", - "performer": "张三、李四", + "name": "青苹果乐园", + "teamName": "", + "performer": "", "order": 1, - "remark": "大型民族舞表演,融合了古典与现代元素,展现龙的精神。" + "remark": "" }, { "id": "p2", - "name": "金马奔腾", - "teamName": "技术部", - "performer": "王五、赵六", + "name": "五百年桑田沧海", + "teamName": "", + "performer": "", "order": 2, - "remark": "动感的现代舞,充满力量与节奏感。" + "remark": "" }, { "id": "p3", - "name": "春风得意", - "teamName": "人力资源部", - "performer": "刘七、陈八", + "name": "我的中国心", + "teamName": "", + "performer": "", "order": 3, - "remark": "温馨的情景剧,讲述了职场中的温暖瞬间。" + "remark": "" }, { "id": "p4", - "name": "鸿运当头", - "teamName": "财务部", - "performer": "周九、吴十", + "name": "萍聚", + "teamName": "", + "performer": "", "order": 4, - "remark": "精彩的杂技表演,寓意新年鸿运连连。" + "remark": "" }, { "id": "p5", - "name": "马到成功", - "teamName": "运营部", - "performer": "郑十一、冯十二", + "name": "追光而行,共赴新程", + "teamName": "", + "performer": "", "order": 5, - "remark": "热血沸腾的多人合唱,充满了前进的动力。" + "remark": "" }, { "id": "p6", - "name": "一马当先", - "teamName": "产品部", - "performer": "孙十三、杨十四", + "name": "粉红色的回忆", + "teamName": "", + "performer": "", "order": 6, - "remark": "极具创意的光影秀,探索未来科技的可能。" + "remark": "" }, { "id": "p7", - "name": "万马奔腾", - "teamName": "设计部", - "performer": "何十五、林十六", + "name": "敬业狂想曲", + "teamName": "", + "performer": "", "order": 7, - "remark": "大合唱,展现团队的凝聚力和向心力。" + "remark": "" } ], "awards": [