- terms.js 보강: 구글 로그인·인앱결제·광고·OCR·제3자·탈퇴·문의 반영 - /privacy, /terms 공개 라우트 + LegalView (웹 브라우저에서도 접근 = 앱 마켓 URL) - 웹 안내 페이지 하단·설정 화면에 정책 링크 추가 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+7
-2
@@ -23,6 +23,8 @@ const router = useRouter()
|
|||||||
const authed = computed(() => auth.isAuthenticated || demo.on)
|
const authed = computed(() => auth.isAuthenticated || demo.on)
|
||||||
// 광고: 유료(PREMIUM) 회원에게는 표시하지 않음
|
// 광고: 유료(PREMIUM) 회원에게는 표시하지 않음
|
||||||
const showAds = computed(() => !auth.isPremium)
|
const showAds = computed(() => !auth.isPremium)
|
||||||
|
// 공개 법적 고지(개인정보처리방침·약관)는 웹 브라우저에서도 접근 허용 (앱 마켓 정책 URL)
|
||||||
|
const isPublicLegal = computed(() => !!route.meta.public)
|
||||||
|
|
||||||
function leaveDemo() {
|
function leaveDemo() {
|
||||||
exitDemo()
|
exitDemo()
|
||||||
@@ -61,8 +63,11 @@ watch(() => route.fullPath, () => ui.closeSidebar())
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<!-- 웹(브라우저): 안내 페이지만 -->
|
<!-- 웹(브라우저): 공개 법적 고지는 노출, 그 외엔 안내 페이지 -->
|
||||||
<WebOnlyNotice v-if="!isApp" />
|
<template v-if="!isApp">
|
||||||
|
<RouterView v-if="isPublicLegal" />
|
||||||
|
<WebOnlyNotice v-else />
|
||||||
|
</template>
|
||||||
|
|
||||||
<!-- 앱(Capacitor): 전체 기능 -->
|
<!-- 앱(Capacitor): 전체 기능 -->
|
||||||
<template v-else>
|
<template v-else>
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
|
import { RouterLink } from 'vue-router'
|
||||||
import AdBanner from '@/components/AdBanner.vue'
|
import AdBanner from '@/components/AdBanner.vue'
|
||||||
// PC·모바일 웹에서 노출되는 안내 페이지. 실제 이용은 앱(모바일) 또는 PC 데스크톱 클라이언트에서.
|
// PC·모바일 웹에서 노출되는 안내 페이지. 실제 이용은 앱(모바일) 또는 PC 데스크톱 클라이언트에서.
|
||||||
// PC 설치파일은 서버 /download/ 경로(영속 디렉터리)에서 서빙 — nginx 설정 참고.
|
// PC 설치파일은 서버 /download/ 경로(영속 디렉터리)에서 서빙 — nginx 설정 참고.
|
||||||
@@ -38,6 +39,12 @@ const mobileReady = false
|
|||||||
<li><span class="f-icon">🏦</span><b>자산·부채 관리</b><span>계좌·카드·대출·투자까지</span></li>
|
<li><span class="f-icon">🏦</span><b>자산·부채 관리</b><span>계좌·카드·대출·투자까지</span></li>
|
||||||
<li><span class="f-icon">🎯</span><b>예산과 분석</b><span>예산 대비 지출·차트</span></li>
|
<li><span class="f-icon">🎯</span><b>예산과 분석</b><span>예산 대비 지출·차트</span></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
<nav class="legal-links">
|
||||||
|
<RouterLink to="/privacy">개인정보처리방침</RouterLink>
|
||||||
|
<span aria-hidden="true">·</span>
|
||||||
|
<RouterLink to="/terms">이용약관</RouterLink>
|
||||||
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 하단 광고 (유료 회원 제외) -->
|
<!-- 하단 광고 (유료 회원 제외) -->
|
||||||
@@ -158,4 +165,18 @@ const mobileReady = false
|
|||||||
font-size: 0.78rem;
|
font-size: 0.78rem;
|
||||||
opacity: 0.65;
|
opacity: 0.65;
|
||||||
}
|
}
|
||||||
|
.legal-links {
|
||||||
|
margin-top: 1.4rem;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
font-size: 0.8rem;
|
||||||
|
opacity: 0.7;
|
||||||
|
}
|
||||||
|
.legal-links a {
|
||||||
|
color: var(--color-text);
|
||||||
|
}
|
||||||
|
.legal-links a:hover {
|
||||||
|
color: hsla(160, 100%, 37%, 1);
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
+59
-18
@@ -1,14 +1,17 @@
|
|||||||
// 회원가입 약관 본문. 모달에서 '전문 보기'로 노출.
|
// 이용약관 / 개인정보처리방침 본문. 가입 모달 '전문 보기' 및 /terms, /privacy 페이지에서 노출.
|
||||||
// 서비스명: 돈돼지 가계부 (가계부·자산·예산 관리)
|
// 서비스명: 돈돼지 가계부 (가계부·자산·예산 관리)
|
||||||
|
|
||||||
export const SERVICE_NAME = '돈돼지 가계부'
|
export const SERVICE_NAME = '돈돼지 가계부'
|
||||||
|
export const EFFECTIVE_DATE = '2026-06-28'
|
||||||
|
// 개인정보 보호 문의 — 운영자 연락처(필요 시 변경)
|
||||||
|
export const CONTACT_EMAIL = 'sbsb401824@gmail.com'
|
||||||
|
|
||||||
export const TERMS_OF_SERVICE = `제1조 (목적)
|
export const TERMS_OF_SERVICE = `제1조 (목적)
|
||||||
이 약관은 ${SERVICE_NAME}(이하 "서비스")가 제공하는 가계부·자산·예산 관리 서비스의 이용과 관련하여 서비스와 회원 간의 권리, 의무 및 책임사항을 규정함을 목적으로 합니다.
|
이 약관은 ${SERVICE_NAME}(이하 "서비스")가 제공하는 가계부·자산·예산 관리 서비스의 이용과 관련하여 서비스와 회원 간의 권리, 의무 및 책임사항을 규정함을 목적으로 합니다.
|
||||||
|
|
||||||
제2조 (정의)
|
제2조 (정의)
|
||||||
1. "회원"이란 본 약관에 동의하고 서비스에 가입하여 이용하는 자를 말합니다.
|
1. "회원"이란 본 약관에 동의하고 서비스에 가입하여 이용하는 자를 말합니다.
|
||||||
2. "계정"이란 회원 식별과 서비스 이용을 위해 회원이 등록한 아이디와 비밀번호를 말합니다.
|
2. "계정"이란 회원 식별과 서비스 이용을 위해 회원이 등록(또는 소셜 로그인으로 연동)한 식별 정보를 말합니다.
|
||||||
|
|
||||||
제3조 (약관의 효력 및 변경)
|
제3조 (약관의 효력 및 변경)
|
||||||
1. 본 약관은 회원이 가입 시 동의함으로써 효력이 발생합니다.
|
1. 본 약관은 회원이 가입 시 동의함으로써 효력이 발생합니다.
|
||||||
@@ -26,33 +29,71 @@ export const TERMS_OF_SERVICE = `제1조 (목적)
|
|||||||
제6조 (게시물)
|
제6조 (게시물)
|
||||||
회원이 게시판 등에 작성한 게시물의 권리와 책임은 작성자에게 있으며, 서비스 운영이나 타인의 권리를 침해하는 게시물은 사전 통지 없이 제한될 수 있습니다.
|
회원이 게시판 등에 작성한 게시물의 권리와 책임은 작성자에게 있으며, 서비스 운영이나 타인의 권리를 침해하는 게시물은 사전 통지 없이 제한될 수 있습니다.
|
||||||
|
|
||||||
제7조 (계약 해지)
|
제7조 (유료 서비스 및 결제)
|
||||||
회원은 언제든지 탈퇴를 요청할 수 있으며, 탈퇴 시 회원의 데이터는 관련 법령에서 정한 경우를 제외하고 지체 없이 삭제됩니다.
|
1. 서비스는 일부 기능을 유료(프리미엄) 구독으로 제공할 수 있습니다.
|
||||||
|
2. 모바일 앱의 결제는 Google Play 등 앱 마켓의 인앱결제를 통해 이루어지며, 결제·환불·정기결제(자동 갱신)의 처리 및 정책은 해당 마켓의 규정을 따릅니다.
|
||||||
|
3. 구독은 만료일까지 이용할 수 있으며, 해지하더라도 남은 기간 동안 이용이 유지된 후 무료로 전환됩니다.
|
||||||
|
4. 청약철회 및 환불은 관련 법령과 앱 마켓 정책에 따릅니다.
|
||||||
|
|
||||||
제8조 (면책)
|
제8조 (광고)
|
||||||
서비스는 천재지변, 회원의 귀책사유, 제3자 서비스(시세 제공처 등)의 장애 등 합리적으로 통제할 수 없는 사유로 인한 손해에 대하여 책임을 지지 않습니다.
|
서비스는 무료 회원에게 광고를 표시할 수 있으며, 유료(프리미엄) 회원에게는 광고를 표시하지 않습니다.
|
||||||
|
|
||||||
|
제9조 (계약 해지)
|
||||||
|
회원은 언제든지 앱 내 '회원 탈퇴' 기능으로 탈퇴할 수 있으며, 탈퇴 시 회원의 데이터는 관련 법령에서 정한 경우를 제외하고 지체 없이 삭제됩니다.
|
||||||
|
|
||||||
|
제10조 (면책)
|
||||||
|
서비스는 천재지변, 회원의 귀책사유, 제3자 서비스(시세 제공처, 앱 마켓, 광고 등)의 장애 등 합리적으로 통제할 수 없는 사유로 인한 손해에 대하여 책임을 지지 않습니다.
|
||||||
|
|
||||||
부칙
|
부칙
|
||||||
본 약관은 가입 시점부터 적용됩니다.`
|
본 약관은 ${EFFECTIVE_DATE}부터 적용됩니다.`
|
||||||
|
|
||||||
export const PRIVACY_POLICY = `${SERVICE_NAME}는 회원가입 및 서비스 제공을 위해 아래와 같이 개인정보를 수집·이용합니다.
|
export const PRIVACY_POLICY = `${SERVICE_NAME}(이하 "서비스")는 이용자의 개인정보를 중요하게 생각하며, 「개인정보 보호법」 등 관련 법령을 준수합니다. 본 방침은 서비스가 어떤 정보를 어떻게 수집·이용·보관하는지 안내합니다.
|
||||||
|
|
||||||
1. 수집 항목
|
1. 수집하는 개인정보 항목
|
||||||
- 필수: 아이디, 비밀번호(암호화 저장), 이름
|
가) 회원가입·계정
|
||||||
- 선택: 이메일
|
- 로컬 가입: 아이디, 비밀번호(단방향 암호화 저장), 이름, 이메일(선택)
|
||||||
- 서비스 이용 과정에서 회원이 직접 입력하는 가계부·자산·거래 내역 등
|
- 구글 로그인: 구글 계정 식별자, 이름, 이메일, 프로필 사진(구글 제공 범위)
|
||||||
|
나) 서비스 이용 과정에서 회원이 직접 입력·등록하는 정보
|
||||||
|
- 가계부·계좌·자산·예산·거래 내역 등 가계부 데이터
|
||||||
|
- 게시판 글·댓글, 직접 업로드한 프로필 사진(선택)
|
||||||
|
다) 자동으로 생성·수집되는 정보
|
||||||
|
- 서비스 이용 기록, 기기·브라우저 정보(부정 이용 방지 및 광고 제공 목적)
|
||||||
|
- 인앱결제 시 구매 토큰 및 구독 상태(결제 검증·구독 관리 목적)
|
||||||
|
|
||||||
2. 수집·이용 목적
|
2. 수집·이용 목적
|
||||||
- 회원 식별 및 로그인 등 계정 관리
|
- 회원 식별 및 로그인 등 계정 관리
|
||||||
- 가계부·자산·예산 관리 기능 제공 및 회원 데이터 보관
|
- 가계부·자산·예산 관리 기능 제공 및 회원 데이터 보관
|
||||||
|
- 유료 구독 결제 검증 및 구독(자동 갱신·해지) 관리
|
||||||
|
- 무료 회원 대상 광고 제공
|
||||||
- 서비스 운영, 문의 응대 및 부정 이용 방지
|
- 서비스 운영, 문의 응대 및 부정 이용 방지
|
||||||
|
|
||||||
3. 보유 및 이용 기간
|
3. 처리위탁 및 제3자
|
||||||
- 회원 탈퇴 시까지 보유하며, 탈퇴 시 지체 없이 파기합니다.
|
서비스는 기능 제공을 위해 아래 사업자의 서비스를 이용하며, 필요한 범위에서 정보가 처리될 수 있습니다.
|
||||||
|
- Google: 구글 로그인(인증), 인앱결제(Google Play), 영수증 문자 인식(Google Cloud Vision OCR)
|
||||||
|
- Kakao(카카오): 광고 노출(카카오 애드핏) — 무료 회원에 한함
|
||||||
|
영수증 OCR은 회원이 촬영·선택한 영수증 이미지를 텍스트 인식 목적으로만 처리합니다. 서비스는 회원의 개인정보를 위 목적 외로 외부에 판매하지 않습니다.
|
||||||
|
|
||||||
|
4. 광고
|
||||||
|
- 무료 회원에게는 광고가 표시되며, 광고 식별·노출을 위해 기기 정보 등이 광고 사업자에 의해 처리될 수 있습니다.
|
||||||
|
- 유료(프리미엄) 회원에게는 광고가 표시되지 않습니다.
|
||||||
|
|
||||||
|
5. 결제 정보
|
||||||
|
- 결제는 Google Play 등 앱 마켓의 인앱결제로 처리되며, 카드번호 등 결제수단 정보는 서비스가 저장하지 않습니다.
|
||||||
|
- 서비스는 결제 검증·구독 관리를 위한 구매 토큰과 구독 상태(상품, 만료일 등)만 보관합니다.
|
||||||
|
|
||||||
|
6. 보유 및 이용 기간
|
||||||
|
- 회원 탈퇴 시까지 보유하며, 탈퇴 시 회원의 데이터(가계부·게시물·포인트·결제기록 등)를 지체 없이 파기합니다.
|
||||||
- 다만 관련 법령에 따라 보존이 필요한 경우 해당 기간 동안 보관합니다.
|
- 다만 관련 법령에 따라 보존이 필요한 경우 해당 기간 동안 보관합니다.
|
||||||
|
|
||||||
4. 동의 거부 권리 및 불이익
|
7. 이용자의 권리
|
||||||
- 회원은 개인정보 수집·이용 동의를 거부할 권리가 있습니다.
|
- 회원은 자신의 개인정보에 대해 열람·정정·삭제·처리정지를 요청할 수 있으며, 앱 내 '회원 탈퇴'로 계정과 데이터를 삭제할 수 있습니다.
|
||||||
- 다만 필수 항목에 동의하지 않을 경우 회원가입 및 서비스 이용이 제한됩니다.
|
- 개인정보 수집·이용 동의를 거부할 권리가 있으나, 필수 항목 미동의 시 회원가입 및 서비스 이용이 제한됩니다.
|
||||||
|
|
||||||
비밀번호는 복호화가 불가능한 방식으로 암호화하여 저장되며, 운영자도 원문을 확인할 수 없습니다.`
|
8. 안전성 확보 조치
|
||||||
|
- 비밀번호는 복호화가 불가능한 방식으로 암호화하여 저장하며, 운영자도 원문을 확인할 수 없습니다.
|
||||||
|
- 전송 구간 암호화(HTTPS) 등 합리적인 보호조치를 적용합니다.
|
||||||
|
|
||||||
|
9. 개인정보 보호 문의
|
||||||
|
- 문의: ${CONTACT_EMAIL}
|
||||||
|
|
||||||
|
본 개인정보처리방침은 ${EFFECTIVE_DATE}부터 적용됩니다.`
|
||||||
|
|||||||
@@ -31,6 +31,20 @@ const router = createRouter({
|
|||||||
component: () => import('../views/UpgradeView.vue'),
|
component: () => import('../views/UpgradeView.vue'),
|
||||||
meta: { requiresAuth: true },
|
meta: { requiresAuth: true },
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
// 개인정보처리방침 (공개 — 웹에서도 접근, 앱 마켓 정책 URL)
|
||||||
|
path: '/privacy',
|
||||||
|
name: 'privacy',
|
||||||
|
component: () => import('../views/LegalView.vue'),
|
||||||
|
meta: { public: true, doc: 'privacy' },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// 이용약관 (공개)
|
||||||
|
path: '/terms',
|
||||||
|
name: 'terms',
|
||||||
|
component: () => import('../views/LegalView.vue'),
|
||||||
|
meta: { public: true, doc: 'terms' },
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '/users',
|
path: '/users',
|
||||||
name: 'users',
|
name: 'users',
|
||||||
|
|||||||
@@ -0,0 +1,88 @@
|
|||||||
|
<script setup>
|
||||||
|
import { computed } from 'vue'
|
||||||
|
import { RouterLink, useRoute, useRouter } from 'vue-router'
|
||||||
|
import { TERMS_OF_SERVICE, PRIVACY_POLICY, SERVICE_NAME } from '@/constants/terms'
|
||||||
|
|
||||||
|
const route = useRoute()
|
||||||
|
const router = useRouter()
|
||||||
|
|
||||||
|
const isPrivacy = computed(() => route.meta.doc === 'privacy')
|
||||||
|
const title = computed(() => (isPrivacy.value ? '개인정보처리방침' : '이용약관'))
|
||||||
|
const body = computed(() => (isPrivacy.value ? PRIVACY_POLICY : TERMS_OF_SERVICE))
|
||||||
|
|
||||||
|
function goBack() {
|
||||||
|
if (window.history.length > 1) router.back()
|
||||||
|
else router.push('/')
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<main class="legal">
|
||||||
|
<header class="legal-head">
|
||||||
|
<div class="brand">{{ SERVICE_NAME }}</div>
|
||||||
|
<h1>{{ title }}</h1>
|
||||||
|
</header>
|
||||||
|
<pre class="legal-body">{{ body }}</pre>
|
||||||
|
<div class="legal-foot">
|
||||||
|
<RouterLink :to="isPrivacy ? '/terms' : '/privacy'" class="legal-link">
|
||||||
|
{{ isPrivacy ? '이용약관' : '개인정보처리방침' }} 보기
|
||||||
|
</RouterLink>
|
||||||
|
<button type="button" class="legal-back" @click="goBack">돌아가기</button>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.legal {
|
||||||
|
max-width: 760px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 1.5rem;
|
||||||
|
}
|
||||||
|
.legal-head {
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 1.25rem;
|
||||||
|
}
|
||||||
|
.brand {
|
||||||
|
font-size: 1.1rem;
|
||||||
|
font-weight: 700;
|
||||||
|
color: hsla(160, 100%, 37%, 1);
|
||||||
|
}
|
||||||
|
.legal-head h1 {
|
||||||
|
font-size: 1.4rem;
|
||||||
|
margin-top: 0.3rem;
|
||||||
|
}
|
||||||
|
.legal-body {
|
||||||
|
white-space: pre-wrap;
|
||||||
|
word-break: break-word;
|
||||||
|
font-family: inherit;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
line-height: 1.7;
|
||||||
|
color: var(--color-text);
|
||||||
|
background: var(--color-background-soft);
|
||||||
|
border: 1px solid var(--color-border);
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 1.2rem 1.3rem;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
.legal-foot {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 0.75rem;
|
||||||
|
margin-top: 1.25rem;
|
||||||
|
}
|
||||||
|
.legal-link {
|
||||||
|
color: hsla(160, 100%, 37%, 1);
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
}
|
||||||
|
.legal-back {
|
||||||
|
padding: 0.5rem 1.3rem;
|
||||||
|
border: 1px solid var(--color-border);
|
||||||
|
border-radius: 8px;
|
||||||
|
background: var(--color-background);
|
||||||
|
color: var(--color-text);
|
||||||
|
cursor: pointer;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -187,6 +187,24 @@ async function clearAppData() {
|
|||||||
</svg>
|
</svg>
|
||||||
</RouterLink>
|
</RouterLink>
|
||||||
|
|
||||||
|
<RouterLink to="/privacy" class="row row-link">
|
||||||
|
<div class="row-main">
|
||||||
|
<span class="row-label">개인정보처리방침</span>
|
||||||
|
</div>
|
||||||
|
<svg class="chevron" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||||
|
<path d="M9 18l6-6-6-6" />
|
||||||
|
</svg>
|
||||||
|
</RouterLink>
|
||||||
|
|
||||||
|
<RouterLink to="/terms" class="row row-link">
|
||||||
|
<div class="row-main">
|
||||||
|
<span class="row-label">이용약관</span>
|
||||||
|
</div>
|
||||||
|
<svg class="chevron" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||||
|
<path d="M9 18l6-6-6-6" />
|
||||||
|
</svg>
|
||||||
|
</RouterLink>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="row-main">
|
<div class="row-main">
|
||||||
<span class="row-label">앱 버전 정보</span>
|
<span class="row-label">앱 버전 정보</span>
|
||||||
|
|||||||
Reference in New Issue
Block a user