Compare commits

...

35 Commits

Author SHA1 Message Date
29331de683 Merge pull request '구글, 카카오 로그인 추가' (#33) from test into main
Reviewed-on: #33
2026-01-29 08:08:49 +00:00
Yu Sung
6bbee48d4d 카카오 로그인 추가 2026-01-29 16:25:59 +09:00
Yu Sung
03766b1c97 구글 로그인 추가 2026-01-29 15:43:10 +09:00
c49a304357 Merge pull request '콘텐츠 수정 - 태그 수정 추가' (#32) from test into main
Reviewed-on: #32
2025-06-02 13:59:01 +00:00
625c8a121f Merge pull request '콘텐츠 등록/수정 - 포인트 사용 가능 여부 추가' (#31) from test into main
Reviewed-on: #31
2025-04-24 10:28:17 +00:00
efa1643359 Merge pull request '콘텐츠 등록 - 콘텐츠 설명 전체 오픈 여부 추가' (#30) from test into main
Reviewed-on: #30
2024-11-23 18:07:30 +00:00
3b294ba020 Merge pull request ''소다라이브' -> '보이스온' 으로 변경' (#29) from test into main
Reviewed-on: #29
2024-11-21 12:43:18 +00:00
8cdbea59de Merge pull request '소장만 기능 추가' (#28) from test into main
Reviewed-on: #28
2024-11-12 14:25:52 +00:00
8ac488bf6f Merge pull request '콘텐츠 업로드 - 미리듣기 최소 시간 30초에서 15초로 변경' (#27) from test into main
Reviewed-on: #27
2024-09-25 11:17:15 +00:00
5664f1be9e Merge pull request '시리즈 관리 페이지에서만 html전체 scroll을 동작하지 않도록 수정' (#26) from test into main
Reviewed-on: #26
2024-08-16 13:28:47 +00:00
c5f707efb9 Merge pull request '시리즈 관리 - 시리즈 크기 한줄에 6개가 들어가도록 수정' (#25) from test into main
Reviewed-on: #25
2024-08-14 08:32:30 +00:00
27a827662e Merge pull request 'test' (#24) from test into main
Reviewed-on: #24
2024-08-14 07:44:43 +00:00
b7c8bed727 Merge pull request '커뮤니티 정산 - 합계 추가' (#23) from test into main
Reviewed-on: #23
2024-06-20 06:03:29 +00:00
f059dda7eb Merge pull request 'test' (#22) from test into main
Reviewed-on: #22
2024-06-03 22:26:57 +00:00
4cdcf1d0b6 Merge pull request '콘텐츠 가격 수정, 시그니처 정렬' (#21) from test into main
Reviewed-on: #21
2024-05-29 17:16:28 +00:00
4497141061 Merge pull request '커뮤니티 정산페이지 추가' (#20) from test into main
Reviewed-on: #20
2024-05-27 08:33:24 +00:00
dfaac20b63 Merge pull request '시그니처 후원 생성/수정 - 재생시간 추가' (#19) from test into main
Reviewed-on: #19
2024-05-02 06:28:56 +00:00
0d3bc1c16e Merge pull request '시리즈 등록 - 크리에이터 -> 장르로 변경' (#18) from test into main
Reviewed-on: #18
2024-04-26 19:15:33 +00:00
c88aa227fd Merge pull request '시리즈' (#17) from test into main
Reviewed-on: #17
2024-04-26 18:57:40 +00:00
3631919245 Merge pull request '콘텐츠 리스트 한정판 표시 - 판매된 개수/전체개수, 다 팔리면 Sold Out으로 표시하도록 수정' (#16) from test into main
Reviewed-on: #16
2024-03-29 03:21:24 +00:00
4a4783563e Merge pull request 'test' (#15) from test into main
Reviewed-on: #15
2024-03-28 06:58:57 +00:00
28d56ab59a Merge pull request '시그니처 관리' (#14) from test into main
Reviewed-on: #14
2024-03-13 11:39:55 +00:00
be97e0ab31 Merge pull request '시그니처 조회/등록/수정/삭제 페이지 추가' (#13) from test into main
Reviewed-on: #13
2024-03-12 06:34:30 +00:00
5e8ec80621 Merge pull request '파비콘 변경' (#12) from test into main
Reviewed-on: #12
2024-02-17 15:02:19 +00:00
0efb3ea86d Merge pull request 'test' (#11) from test into main
Reviewed-on: #11
2024-02-07 09:53:49 +00:00
c0b6a23782 Merge pull request '콘텐츠 업로드 - 미리듣기 생성하지 않을 수 있도록 수정' (#10) from test into main
Reviewed-on: #10
2024-01-30 03:31:28 +00:00
a838b3673c Merge pull request '콘텐츠 등록 - 예약 업로드 추가' (#9) from test into main
Reviewed-on: #9
2024-01-11 09:16:41 +00:00
f64f1f0fb7 Merge pull request '일자별 콘텐츠 후원 페이지 - 유/무료 구분 추가' (#8) from test into main
Reviewed-on: #8
2023-11-14 13:24:07 +00:00
3088f957e2 Merge pull request 'test' (#7) from test into main
Reviewed-on: #7
2023-11-14 12:11:01 +00:00
41f99a175c Merge pull request '콘텐츠별 누적 현황 페이지 추가' (#6) from test into main
Reviewed-on: #6
2023-11-13 15:31:10 +00:00
61b5d785a3 Merge pull request '일자별 콘텐츠 정산 페이지 추가' (#5) from test into main
Reviewed-on: #5
2023-11-13 10:07:06 +00:00
3fe7554e06 Merge pull request '콘텐츠 등록 - 대여만 가능한 콘텐츠 등록할 수 있도록 체크박스 추가' (#4) from test into main
Reviewed-on: #4
2023-10-30 02:10:49 +00:00
1def9ddd4a Merge pull request '미리듣기 시간설정 기능 추가' (#3) from test into main
Reviewed-on: #3
2023-10-04 15:43:22 +00:00
a13d442924 Merge pull request '정산 - 합계 추가' (#2) from test into main
Reviewed-on: #2
2023-10-04 07:22:59 +00:00
a1f206a3c0 Merge pull request 'test' (#1) from test into main
Reviewed-on: #1
2023-10-04 03:34:29 +00:00
7 changed files with 227 additions and 33 deletions

View File

@@ -1,2 +1,4 @@
VUE_APP_API_URL=https://test-api.sodalive.net
NODE_ENV=development
VUE_APP_GOOGLE_CLIENT_ID=758414412471-mosodbj2chno7l1j0iihldh6edmk0gk9.apps.googleusercontent.com
VUE_APP_KAKAO_JS_KEY=2be3c619ed36fd3e138bf45812c57d7f

View File

@@ -1,2 +1,4 @@
VUE_APP_API_URL=https://api.sodalive.net
NODE_ENV=production
VUE_APP_GOOGLE_CLIENT_ID=983594297130-5hrmkh6vpskeq6v34350kmilf74574h2.apps.googleusercontent.com
VUE_APP_KAKAO_JS_KEY=378e800dd9029907c559390e786157ef

View File

@@ -8,6 +8,8 @@
<title>보이스온 크리에이터 관리자</title>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@mdi/font@latest/css/materialdesignicons.min.css">
<script src="https://accounts.google.com/gsi/client" async defer></script>
<script src="https://developers.kakao.com/sdk/js/kakao.min.js"></script>
</head>
<body>
<noscript>

View File

@@ -8,4 +8,28 @@ async function logout() {
return Vue.axios.post('/creator-admin/member/logout');
}
export { login, logout }
async function loginGoogle(idToken) {
return Vue.axios.post(
"/member/login/google",
{ container: "api" },
{
headers: {
Authorization: `Bearer ${idToken}`,
},
}
);
}
async function loginKakao(accessToken) {
return Vue.axios.post(
"/member/login/kakao",
{ container: "api" },
{
headers: {
Authorization: `Bearer ${accessToken}`,
},
}
);
}
export { login, logout, loginGoogle, loginKakao }

BIN
src/assets/kakao_login.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

@@ -87,6 +87,56 @@ const accountStore = {
});
},
async LOGIN_GOOGLE({commit}, {idToken}) {
let result = false
let errorMessage = null
try {
let res = await memberApi.loginGoogle(idToken)
if (res.data.success === true) {
commit("LOGIN", res.data.data)
result = true
} else {
errorMessage = res.data.message
}
} catch (e) {
errorMessage = '구글 로그인 정보를 확인해주세요.'
}
return new Promise((resolve, reject) => {
if (result) {
resolve();
} else {
reject(errorMessage)
}
});
},
async LOGIN_KAKAO({commit}, {accessToken}) {
let result = false
let errorMessage = null
try {
let res = await memberApi.loginKakao(accessToken)
if (res.data.success === true) {
commit("LOGIN", res.data.data)
result = true
} else {
errorMessage = res.data.message
}
} catch (e) {
errorMessage = '카카오 로그인 정보를 확인해주세요.'
}
return new Promise((resolve, reject) => {
if (result) {
resolve();
} else {
reject(errorMessage)
}
});
},
async LOGOUT({commit}) {
let result = false
let errorMessage = null

View File

@@ -1,44 +1,79 @@
<template>
<v-app>
<v-main>
<v-container
align-center
justify-center
>
<v-card class="elevation-12">
<v-card-text>
<v-form>
<v-text-field
v-model="email"
label="Email"
type="text"
/>
<v-text-field
v-model="password"
:append-icon="showPassword ? 'mdi-eye' : 'mdi-eye-off'"
:type="showPassword ? 'text' : 'password'"
label="Password"
@click:append="showPassword = !showPassword"
@keyup.enter="loginSubmit"
/>
</v-form>
</v-card-text>
<v-card-actions>
<v-spacer />
<v-btn
color="primary"
@click="loginSubmit"
>
로그인
</v-btn>
</v-card-actions>
</v-card>
<v-container fluid>
<v-row
align="start"
justify="center"
style="padding-top: 10vh;"
>
<v-col
cols="12"
sm="8"
md="4"
>
<v-card class="elevation-12">
<v-card-text>
<v-form>
<v-text-field
v-model="email"
label="Email"
type="text"
/>
<v-text-field
v-model="password"
:append-icon="showPassword ? 'mdi-eye' : 'mdi-eye-off'"
:type="showPassword ? 'text' : 'password'"
label="Password"
@click:append="showPassword = !showPassword"
@keyup.enter="loginSubmit"
/>
</v-form>
</v-card-text>
<v-card-actions>
<v-spacer />
<v-btn
color="primary"
@click="loginSubmit"
>
로그인
</v-btn>
</v-card-actions>
<v-divider />
<v-card-text class="text-center">
<div
style="display: flex; flex-direction: column; align-items: center; gap: 10px;"
>
<div
id="google-login-btn"
style="width: 192px; height: 45px; display: flex; align-items: center; justify-content: center;"
/>
<v-btn
width="192"
height="45"
class="pa-0"
elevation="0"
color="transparent"
@click="loginKakao"
>
<img
src="@/assets/kakao_login.png"
alt="카카오 로그인 버튼"
style="width: 100%; height: 100%; display: block;"
>
</v-btn>
</div>
</v-card-text>
</v-card>
</v-col>
</v-row>
</v-container>
</v-main>
</v-app>
</template>
<script>
/* global Kakao */
export default {
name: "Login",
@@ -48,7 +83,86 @@ export default {
password: '',
}),
mounted() {
this.initGoogleLogin();
this.initKakaoLogin();
},
methods: {
initKakaoLogin() {
if (typeof Kakao !== 'undefined') {
if (!Kakao.isInitialized()) {
Kakao.init(process.env.VUE_APP_KAKAO_JS_KEY);
}
} else {
setTimeout(() => {
this.initKakaoLogin();
}, 500);
}
},
loginKakao() {
if (typeof Kakao !== 'undefined') {
if (!Kakao.isInitialized()) {
this.initKakaoLogin();
this.notifyError('카카오 SDK가 초기화되지 않았습니다. 잠시 후 다시 시도해주세요.');
return;
}
if (Kakao.Auth && typeof Kakao.Auth.login === 'function') {
Kakao.Auth.login({
success: (authObj) => {
this.$store.dispatch('accountStore/LOGIN_KAKAO', { accessToken: authObj.access_token })
.then(() => {
this.$router.push(this.$route.query.redirect || '/')
})
.catch((message) => {
this.notifyError(message);
})
},
fail: (err) => {
this.notifyError('카카오 로그인에 실패했습니다.');
console.error(err);
},
});
} else {
this.notifyError('카카오 인증 모듈을 불러오지 못했습니다. 페이지를 새로고침 해주세요.');
}
} else {
this.initKakaoLogin();
this.notifyError('카카오 SDK를 불러오는 중입니다. 잠시 후 다시 시도해주세요.');
}
},
initGoogleLogin() {
/* global google */
if (typeof google !== 'undefined') {
google.accounts.id.initialize({
client_id: process.env.VUE_APP_GOOGLE_CLIENT_ID,
callback: this.handleCredentialResponse
});
google.accounts.id.renderButton(
document.getElementById("google-login-btn"),
{ theme: "outline", size: "large", width: 192 }
);
} else {
setTimeout(() => {
this.initGoogleLogin();
}, 500);
}
},
handleCredentialResponse(response) {
const idToken = response.credential;
this.$store.dispatch('accountStore/LOGIN_GOOGLE', { idToken })
.then(() => {
this.$router.push(this.$route.query.redirect || '/')
})
.catch((message) => {
this.notifyError(message);
})
},
notifyError: async function (message) {
await this.$dialog.notify.error(message)
},