From c5ca4034428a2bfadb97204e7436d3ed62a1ee6d Mon Sep 17 00:00:00 2001
From: hyoseung930 <35983843+hyoseung930@users.noreply.github.com>
Date: Fri, 26 Jun 2026 15:05:36 +0900
Subject: [PATCH] =?UTF-8?q?autoCoupon:=20alliance=20=EC=97=B0=EB=A7=B9?=
=?UTF-8?q?=EC=9B=90=20=EB=AA=A9=EB=A1=9D=20=EC=97=B0=EB=8F=99=20=EC=B6=94?=
=?UTF-8?q?=EA=B0=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- /api/alliances: alliance 백엔드 프록시
- /api/alliance-members: R5 PIN 인증 후 연맹원 목록 반환 (쿠폰 등록 여부 포함)
- AlliancePanel.vue: 연맹 선택 + R5 PIN 인증 + 역할별 필터 + 쿠폰 등록 현황
- HomeView.vue에 AlliancePanel 추가
---
back/src/wos/wos.controller.ts | 26 +-
front/src/components/AlliancePanel.vue | 326 +++++++++++++++++++++++++
front/src/views/HomeView.vue | 3 +
3 files changed, 354 insertions(+), 1 deletion(-)
create mode 100644 front/src/components/AlliancePanel.vue
diff --git a/back/src/wos/wos.controller.ts b/back/src/wos/wos.controller.ts
index 71b9dcb..ccb7fb2 100644
--- a/back/src/wos/wos.controller.ts
+++ b/back/src/wos/wos.controller.ts
@@ -1,5 +1,8 @@
-import { Controller, Post, Get, Delete, Patch, Body, Param, Query, HttpCode } from '@nestjs/common';
+import { Controller, Post, Get, Delete, Patch, Body, Param, Query, HttpCode, BadRequestException, ForbiddenException } from '@nestjs/common';
import { WosService } from './wos.service';
+import axios from 'axios';
+
+const ALLIANCE_API = 'http://localhost:3005/api';
@Controller('api')
export class WosController {
@@ -59,4 +62,25 @@ export class WosController {
async deleteCoupon(@Param('id') id: string) {
return this.wosService.deleteCoupon(Number(id));
}
+
+ @Get('alliances')
+ async getAlliances() {
+ const { data } = await axios.get(`${ALLIANCE_API}/alliances`);
+ return data;
+ }
+
+ @Post('alliance-members')
+ @HttpCode(200)
+ async getAllianceMembers(@Body() body: { alliance_id: number; pin: string }) {
+ if (!body.alliance_id || !body.pin) throw new BadRequestException('alliance_id와 pin이 필요합니다');
+ try {
+ await axios.get(`${ALLIANCE_API}/alliances/${body.alliance_id}/pending`, { params: { pin: body.pin } });
+ } catch {
+ throw new ForbiddenException('PIN이 틀렸습니다');
+ }
+ const { data: members } = await axios.get(`${ALLIANCE_API}/members`, { params: { alliance_id: body.alliance_id } });
+ const wosUsers = await this.wosService.listUsers();
+ const nicknameSet = new Set(wosUsers.map((u: any) => u.nickname?.toLowerCase()));
+ return members.map((m: any) => ({ ...m, in_coupon_system: nicknameSet.has(m.nickname?.toLowerCase()) }));
+ }
}
diff --git a/front/src/components/AlliancePanel.vue b/front/src/components/AlliancePanel.vue
new file mode 100644
index 0000000..0de0ff8
--- /dev/null
+++ b/front/src/components/AlliancePanel.vue
@@ -0,0 +1,326 @@
+
+