배포 완료됐습니다. 변경 내용 요약: --- ## 변경 사항 **자동화 (캡차 없음)** - FID 입력 → 조회 버튼 클릭 → 쿠폰 코드 붙여넣기 → ⚡ 자동 입력 클릭 - 백엔드가 캡차 세션을 자동으로 획득해서 처리 (사용자가 캡차를 볼 필요 없음) - 캡차 세션 만료 시 자동 재시도 **영구 이력 저장** - 쿠폰 입력할 때마다 DB(`coupon_logs`)에 저장 - FID 조회 시 해당 플레이어의 이력이 하단에 자동 로드 - 날짜/시간 + 결과 (성공/실패) 표시, 최대 100건 **https://coupon.wageulwageul.com** 에서 바로 확인하세요.
90 lines
2.2 KiB
TypeScript
90 lines
2.2 KiB
TypeScript
import { defineStore } from 'pinia';
|
|
import axios from 'axios';
|
|
|
|
interface PlayerInfo {
|
|
nickname: string;
|
|
avatar_image: string;
|
|
stove_lv: number;
|
|
}
|
|
|
|
interface RedeemResult {
|
|
code: string;
|
|
status: 'success' | 'error' | 'pending';
|
|
message: string;
|
|
}
|
|
|
|
interface HistoryItem {
|
|
id: number;
|
|
fid: string;
|
|
coupon_code: string;
|
|
result_msg: string;
|
|
executed_at: string;
|
|
}
|
|
|
|
export const useWosStore = defineStore('wos', {
|
|
state: () => ({
|
|
fid: '',
|
|
player: null as PlayerInfo | null,
|
|
couponCodes: '',
|
|
results: [] as RedeemResult[],
|
|
history: [] as HistoryItem[],
|
|
status: 'idle' as 'idle' | 'loading' | 'success' | 'error',
|
|
errorMsg: '',
|
|
}),
|
|
|
|
actions: {
|
|
async searchPlayer(fid: string) {
|
|
this.status = 'loading';
|
|
this.errorMsg = '';
|
|
this.player = null;
|
|
this.results = [];
|
|
try {
|
|
const { data } = await axios.post('/api/player', { fid });
|
|
this.player = data;
|
|
this.fid = fid;
|
|
this.status = 'idle';
|
|
await this.loadHistory();
|
|
} catch (err: any) {
|
|
this.status = 'error';
|
|
this.errorMsg = err.response?.data?.message || '유저를 찾을 수 없습니다.';
|
|
}
|
|
},
|
|
|
|
async loadHistory() {
|
|
if (!this.fid) return;
|
|
try {
|
|
const { data } = await axios.get(`/api/history/${this.fid}`);
|
|
this.history = data;
|
|
} catch {}
|
|
},
|
|
|
|
async submitCoupons() {
|
|
if (!this.fid) return;
|
|
const codes = this.couponCodes
|
|
.split('\n')
|
|
.map((c) => c.trim())
|
|
.filter((c) => c.length > 0);
|
|
|
|
if (codes.length === 0) {
|
|
this.errorMsg = '쿠폰 코드를 입력해주세요.';
|
|
return;
|
|
}
|
|
|
|
this.results = codes.map((code) => ({ code, status: 'pending', message: '처리 중...' }));
|
|
this.status = 'loading';
|
|
this.errorMsg = '';
|
|
|
|
try {
|
|
const { data } = await axios.post('/api/redeem', { fid: this.fid, codes });
|
|
this.results = data;
|
|
this.status = 'idle';
|
|
this.couponCodes = '';
|
|
await this.loadHistory();
|
|
} catch (err: any) {
|
|
this.status = 'error';
|
|
this.errorMsg = err.response?.data?.message || '쿠폰 입력 중 오류가 발생했습니다.';
|
|
}
|
|
},
|
|
},
|
|
});
|