@@ -29,7 +29,10 @@
|
|||||||
<meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" />
|
<meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" />
|
||||||
</provider>
|
</provider>
|
||||||
|
|
||||||
<!-- 카드 결제 알림 자동인식: 알림 접근 리스너 서비스 -->
|
<!-- 카드 결제 알림 자동인식(알림 접근 리스너) — 스토어 첫 출시에서는 비활성화.
|
||||||
|
Google Play NotificationListenerService(알림 접근) 정책 심사 회피용으로 선언 제거.
|
||||||
|
추후 정당화/선언 후 재활성화하려면 아래 service 블록 주석을 해제할 것. -->
|
||||||
|
<!--
|
||||||
<service
|
<service
|
||||||
android:name=".CardNotifListenerService"
|
android:name=".CardNotifListenerService"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
@@ -39,6 +42,7 @@
|
|||||||
<action android:name="android.service.notification.NotificationListenerService" />
|
<action android:name="android.service.notification.NotificationListenerService" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</service>
|
</service>
|
||||||
|
-->
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
<!-- Permissions -->
|
<!-- Permissions -->
|
||||||
|
|||||||
@@ -44,6 +44,8 @@ const mobileReady = false
|
|||||||
<RouterLink to="/privacy">개인정보처리방침</RouterLink>
|
<RouterLink to="/privacy">개인정보처리방침</RouterLink>
|
||||||
<span aria-hidden="true">·</span>
|
<span aria-hidden="true">·</span>
|
||||||
<RouterLink to="/terms">이용약관</RouterLink>
|
<RouterLink to="/terms">이용약관</RouterLink>
|
||||||
|
<span aria-hidden="true">·</span>
|
||||||
|
<RouterLink to="/account-deletion">계정 삭제</RouterLink>
|
||||||
</nav>
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -3,3 +3,8 @@
|
|||||||
// 백엔드(/api/auth/login, /api/auth/signup)는 비상용으로 그대로 유지 —
|
// 백엔드(/api/auth/login, /api/auth/signup)는 비상용으로 그대로 유지 —
|
||||||
// 되돌리려면 이 값을 true 로 바꾸면 아이디 로그인/회원가입이 다시 노출된다.
|
// 되돌리려면 이 값을 true 로 바꾸면 아이디 로그인/회원가입이 다시 노출된다.
|
||||||
export const ID_LOGIN_ENABLED = false
|
export const ID_LOGIN_ENABLED = false
|
||||||
|
|
||||||
|
// 카드 결제 알림 자동인식(NotificationListenerService) 기능.
|
||||||
|
// 스토어 첫 출시에서는 Google Play 알림 접근 정책 심사 회피를 위해 비활성화.
|
||||||
|
// (AndroidManifest 의 CardNotifListenerService 선언도 함께 주석 처리되어 있음)
|
||||||
|
export const CARD_NOTIF_ENABLED = false
|
||||||
|
|||||||
@@ -45,6 +45,13 @@ const router = createRouter({
|
|||||||
component: () => import('../views/LegalView.vue'),
|
component: () => import('../views/LegalView.vue'),
|
||||||
meta: { public: true, doc: 'terms' },
|
meta: { public: true, doc: 'terms' },
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
// 계정·데이터 삭제 안내 (공개 — 앱 마켓 데이터 삭제 정책 URL)
|
||||||
|
path: '/account-deletion',
|
||||||
|
name: 'account-deletion',
|
||||||
|
component: () => import('../views/AccountDeletionView.vue'),
|
||||||
|
meta: { public: true },
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '/users',
|
path: '/users',
|
||||||
name: 'users',
|
name: 'users',
|
||||||
|
|||||||
@@ -0,0 +1,105 @@
|
|||||||
|
<script setup>
|
||||||
|
import { useRouter } from 'vue-router'
|
||||||
|
import { SERVICE_NAME, CONTACT_EMAIL } from '@/constants/terms'
|
||||||
|
|
||||||
|
const router = useRouter()
|
||||||
|
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>계정 및 데이터 삭제</h1>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<div class="legal-body">
|
||||||
|
<p>{{ SERVICE_NAME }}는 이용자가 본인의 계정과 모든 데이터를 직접 삭제할 수 있도록 제공합니다.</p>
|
||||||
|
|
||||||
|
<h2>앱에서 삭제하기</h2>
|
||||||
|
<ol>
|
||||||
|
<li>앱(또는 PC 클라이언트)에 로그인합니다.</li>
|
||||||
|
<li><b>설정 → 계정정보</b> 화면으로 이동합니다.</li>
|
||||||
|
<li>맨 아래 <b>회원 탈퇴</b>를 눌러 안내에 따라 진행합니다.</li>
|
||||||
|
</ol>
|
||||||
|
|
||||||
|
<h2>삭제되는 데이터</h2>
|
||||||
|
<p>탈퇴 시 아래 데이터가 <b>지체 없이 영구 삭제</b>되며 복구할 수 없습니다.</p>
|
||||||
|
<ul>
|
||||||
|
<li>계정 정보(아이디·이메일·프로필 등)</li>
|
||||||
|
<li>가계부·계좌·자산·예산·거래 내역 등 모든 가계부 데이터</li>
|
||||||
|
<li>게시판 글·댓글·추천 기록</li>
|
||||||
|
<li>포인트 및 결제(구독) 기록</li>
|
||||||
|
</ul>
|
||||||
|
<p class="muted">단, 관련 법령에 따라 보존이 필요한 정보는 해당 기간 동안 보관 후 파기합니다.</p>
|
||||||
|
|
||||||
|
<h2>앱 없이 삭제를 요청하려면</h2>
|
||||||
|
<p>앱에 접근할 수 없는 경우, 아래 이메일로 가입 계정 정보와 함께 삭제를 요청하시면 처리해 드립니다.</p>
|
||||||
|
<p><b>문의:</b> {{ CONTACT_EMAIL }}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="legal-foot">
|
||||||
|
<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 {
|
||||||
|
font-size: 0.92rem;
|
||||||
|
line-height: 1.75;
|
||||||
|
color: var(--color-text);
|
||||||
|
background: var(--color-background-soft);
|
||||||
|
border: 1px solid var(--color-border);
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 1.2rem 1.3rem;
|
||||||
|
}
|
||||||
|
.legal-body h2 {
|
||||||
|
font-size: 1.02rem;
|
||||||
|
margin: 1.2rem 0 0.4rem;
|
||||||
|
color: var(--color-heading);
|
||||||
|
}
|
||||||
|
.legal-body ol,
|
||||||
|
.legal-body ul {
|
||||||
|
padding-left: 1.2rem;
|
||||||
|
}
|
||||||
|
.legal-body .muted {
|
||||||
|
font-size: 0.85rem;
|
||||||
|
opacity: 0.7;
|
||||||
|
}
|
||||||
|
.legal-foot {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
margin-top: 1.25rem;
|
||||||
|
}
|
||||||
|
.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>
|
||||||
@@ -7,6 +7,7 @@ import { useDialog } from '@/composables/dialog'
|
|||||||
import IconBtn from '@/components/ui/IconBtn.vue'
|
import IconBtn from '@/components/ui/IconBtn.vue'
|
||||||
import { imageToBlob, parseReceiptText } from '@/utils/receiptOcr'
|
import { imageToBlob, parseReceiptText } from '@/utils/receiptOcr'
|
||||||
import { cardNotif } from '@/native/cardNotif'
|
import { cardNotif } from '@/native/cardNotif'
|
||||||
|
import { CARD_NOTIF_ENABLED } from '@/config/features'
|
||||||
import { Capacitor } from '@capacitor/core'
|
import { Capacitor } from '@capacitor/core'
|
||||||
// @capacitor/camera 는 네이티브에서만 동적 로드 (웹은 file input 사용 — 정적 import 시 모바일 웹 청크 로드 실패 유발)
|
// @capacitor/camera 는 네이티브에서만 동적 로드 (웹은 file input 사용 — 정적 import 시 모바일 웹 청크 로드 실패 유발)
|
||||||
|
|
||||||
@@ -25,7 +26,7 @@ const pendingCount = ref(0) // 확인 필요(카드 알림 자동인식) 건수
|
|||||||
const editingPending = ref(false) // 수정 중인 항목이 미확인 건인지
|
const editingPending = ref(false) // 수정 중인 항목이 미확인 건인지
|
||||||
|
|
||||||
// 카드 결제 알림 자동인식 권한 (네이티브 전용)
|
// 카드 결제 알림 자동인식 권한 (네이티브 전용)
|
||||||
const notifNative = cardNotif.isNative()
|
const notifNative = CARD_NOTIF_ENABLED && cardNotif.isNative()
|
||||||
const notifEnabled = ref(true) // 미허용일 때만 배너 노출
|
const notifEnabled = ref(true) // 미허용일 때만 배너 노출
|
||||||
async function checkNotifPermission() {
|
async function checkNotifPermission() {
|
||||||
if (notifNative) notifEnabled.value = await cardNotif.isEnabled()
|
if (notifNative) notifEnabled.value = await cardNotif.isEnabled()
|
||||||
|
|||||||
Reference in New Issue
Block a user