From 8e8cfa68b3966a513f607bf3a777cd669f9009ab Mon Sep 17 00:00:00 2001 From: Yu Sung Date: Fri, 8 May 2026 14:39:30 +0900 Subject: [PATCH] =?UTF-8?q?feat(calculate):=20=EB=A0=88=EA=B1=B0=EC=8B=9C?= =?UTF-8?q?=20=EC=A0=95=EC=82=B0=20=ED=99=94=EB=A9=B4=20P2=201=EC=B0=A8=20?= =?UTF-8?q?i18n=20=EC=B9=98=ED=99=98(Live/Content)=20=EB=B0=8F=20=EB=A6=AC?= =?UTF-8?q?=EC=86=8C=EC=8A=A4/=EB=AC=B8=EC=84=9C=20=EC=97=85=EB=8D=B0?= =?UTF-8?q?=EC=9D=B4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/20260508_국제화도입.md | 27 ++++ src/locales/en.json | 40 ++++- src/locales/ja.json | 40 ++++- src/locales/ko.json | 40 ++++- src/views/Calculate/CalculateContent.vue | 141 +++++------------ src/views/Calculate/CalculateLive.vue | 184 +++++------------------ 6 files changed, 225 insertions(+), 247 deletions(-) diff --git a/docs/20260508_국제화도입.md b/docs/20260508_국제화도입.md index 6862c6e..de64875 100644 --- a/docs/20260508_국제화도입.md +++ b/docs/20260508_국제화도입.md @@ -16,6 +16,19 @@ - [x] 날짜/숫자/통화 포맷 정책 적용(ja: JPY 소수점 미사용 등) - [x] 하드코딩 탐지/미번역 키 점검(정규식 스캔 + missing 핸들러) - [x] 언어 전환 UX(드롭다운) 및 영속 저장(localStorage) + - [ ] P2: 레거시 정산 화면(`views/Calculate/*`) i18n 치환 + - [ ] 공통 키 정의(`view.calculate.common.*`, 단위 `common.unit.*` 보강) + - [ ] `CalculateLive.vue` 텍스트/헤더/합계/오류 치환 + - [ ] `CalculateContent.vue` 텍스트/헤더/합계/오류 치환 + - [ ] `CalculateContentDonation.vue` 텍스트/헤더/합계/오류 치환 + - [ ] `CalculateCommunityPost.vue` 텍스트/헤더/합계/오류 치환 + - [ ] `CalculateChannelDonation.vue` 텍스트/헤더/합계/오류 치환 + - [ ] `CalculateAccumulation.vue` 텍스트/헤더/합계/오류 치환 + - [ ] 검증: `npm run i18n:scan`/런타임 전환 확인 기록 + - [ ] P3: 콘텐츠 관리(`views/Content/*`) i18n 치환 + - [ ] 목록/상세/시리즈 화면 라벨/버튼/알림 메시지 치환(`view.content.*`) + - [ ] 검증: `npm run i18n:scan`/런타임 전환 확인 기록 + - [ ] P4: 공통 남은 텍스트 및 주석 정리(사용자 노출 X 주석은 후순위) ## 키 네이밍 규칙 - 네임스페이스 기반: `common.*`, `comp.*`, `view.*` @@ -133,3 +146,17 @@ - 실행 명령 2: 헤더의 언어 드롭다운으로 `ko → en → ja` 순서로 전환 - 확인 항목: 각 전환 시 Google 버튼 라벨이 즉시 새 언어로 변경됨 ✓ - 참고: 외부 위젯 특성상 캐시 환경에 따라 반영이 지연될 수 있어, SDK URL에 캐시 버스터 파라미터 추가함 + +### 6차 구현 – 레거시 정산 화면 치환(P2) (2026-05-08) +- 무엇을: `views/Calculate/*`의 사용자 노출 텍스트(툴바 타이틀/기간 필터/조회 버튼/테이블 헤더/합계/오류)를 i18n으로 치환하고, 공통/화면별 키를 `view.calculate.*` 네임스페이스로 추가함. 단위 표기(`명/캔/원`)는 `common.unit.*` 사용. +- 왜: 업무 핵심 화면의 다국어 일관성을 확보하고, 남은 하드코딩 문자열을 제거하기 위함 +- 어떻게: + - 변경 파일(1차): + - `src/views/Calculate/CalculateLive.vue`: 타이틀/기간 표시/조회 버튼/헤더/합계/오류 i18n 치환(로케일 전환 반응형) + - `src/views/Calculate/CalculateContent.vue`: 동등 범위 치환(로케일 전환 반응형) + - `src/locales/{ko,en,ja}.json`: `view.calculate.common.*`, `view.calculate.live.*`, `view.calculate.content.*`, `common.unit.{person,krw}` 추가 + - 실행 명령 1: `npm run i18n:scan` + - 기대 결과: 위 2개 파일 내 한/일문 하드코딩 라인이 0 또는 최소(주석) ✓ + - 실행 명령 2: `npm run serve` 후 `ko ↔ en ↔ ja` 전환 + - 확인 항목: 타이틀/필터 구분자/버튼/헤더/합계 단위가 즉시 전환됨 ✓ + - 비고: 나머지 레거시 정산 파일은 P2-2차로 순차 치환 예정 diff --git a/src/locales/en.json b/src/locales/en.json index 9ae9c21..8a7c15c 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -23,7 +23,9 @@ } }, "unit": { - "can": "CAN" + "can": "CAN", + "person": "people", + "krw": "KRW" }, "lang": { "ko": "한국어", @@ -56,6 +58,42 @@ } }, "view": { + "calculate": { + "common": { + "rangeSeparator": "~", + "search": "Search", + "total": "Total", + "headers": { + "creator": "Creator", + "date": "Date", + "title": "Title", + "type": "Type", + "totalCan": "Total (CAN)", + "krw": "KRW", + "fee": "Fee", + "feeWithPercent": "Fee ( {percent} )", + "settlementAmount": "Settlement amount", + "withholdingTaxWithPercent": "Withholding tax ( {percent} )", + "depositAmount": "Deposit amount" + } + }, + "live": { + "title": "Live settlement", + "headers": { + "entranceCan": "Entrance CAN", + "paidParticipants": "Paid participants" + } + }, + "content": { + "title": "Content settlement", + "headers": { + "saleDate": "Sale date", + "orderPriceCan": "Sale amount (CAN)", + "salesCount": "Sales count", + "registrationDate": "Registration date" + } + } + }, "login": { "email": "Email", "password": "Password", diff --git a/src/locales/ja.json b/src/locales/ja.json index 6e148db..94a2af7 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -23,7 +23,9 @@ } }, "unit": { - "can": "CAN" + "can": "CAN", + "person": "名", + "krw": "ウォン" }, "lang": { "ko": "한국어", @@ -56,6 +58,42 @@ } }, "view": { + "calculate": { + "common": { + "rangeSeparator": "~", + "search": "検索", + "total": "合計", + "headers": { + "creator": "クリエイター", + "date": "日付", + "title": "タイトル", + "type": "区分", + "totalCan": "合計(CAN)", + "krw": "ウォン", + "fee": "手数料", + "feeWithPercent": "手数料( {percent} )", + "settlementAmount": "精算金額", + "withholdingTaxWithPercent": "源泉徴収( {percent} )", + "depositAmount": "入金額" + } + }, + "live": { + "title": "ライブ精算", + "headers": { + "entranceCan": "入場CAN", + "paidParticipants": "有料部屋参加人数" + } + }, + "content": { + "title": "コンテンツ精算", + "headers": { + "saleDate": "販売日", + "orderPriceCan": "販売金額(CAN)", + "salesCount": "販売数", + "registrationDate": "登録日" + } + } + }, "login": { "email": "メール", "password": "パスワード", diff --git a/src/locales/ko.json b/src/locales/ko.json index 9b08de8..3418f68 100644 --- a/src/locales/ko.json +++ b/src/locales/ko.json @@ -23,7 +23,9 @@ } }, "unit": { - "can": "캔" + "can": "캔", + "person": "명", + "krw": "원" }, "lang": { "ko": "한국어", @@ -56,6 +58,42 @@ } }, "view": { + "calculate": { + "common": { + "rangeSeparator": "~", + "search": "조회", + "total": "합계", + "headers": { + "creator": "크리에이터", + "date": "날짜", + "title": "제목", + "type": "구분", + "totalCan": "합계(캔)", + "krw": "원화", + "fee": "수수료", + "feeWithPercent": "수수료( {percent} )", + "settlementAmount": "정산금액", + "withholdingTaxWithPercent": "원천세( {percent} )", + "depositAmount": "입금액" + } + }, + "live": { + "title": "라이브 정산", + "headers": { + "entranceCan": "입장캔", + "paidParticipants": "유료방참여인원" + } + }, + "content": { + "title": "콘텐츠 정산", + "headers": { + "saleDate": "판매일", + "orderPriceCan": "판매금액(캔)", + "salesCount": "판매수", + "registrationDate": "등록일" + } + } + }, "login": { "email": "이메일", "password": "비밀번호", diff --git a/src/views/Calculate/CalculateContent.vue b/src/views/Calculate/CalculateContent.vue index 6b4c583..3591e65 100644 --- a/src/views/Calculate/CalculateContent.vue +++ b/src/views/Calculate/CalculateContent.vue @@ -2,7 +2,7 @@
- 콘텐츠 정산 + {{ $t('view.calculate.content.title') }} @@ -19,7 +19,7 @@ - ~ + {{ $t('view.calculate.common.rangeSeparator') }} @@ -40,7 +40,7 @@ depressed @click="getCalculateContent" > - 조회 + {{ $t('view.calculate.common.search') }} @@ -60,21 +60,21 @@ @@ -138,87 +138,26 @@ export default { page_size: 20, total_page: 0, items: [], - headers: [ - { - text: '판매일', - align: 'center', - sortable: false, - value: 'saleDate', - }, - { - text: '크리에이터', - align: 'center', - sortable: false, - value: 'nickname', - }, - { - text: '제목', - sortable: false, - value: 'title', - align: 'center', - width: "300px" - }, - { - text: '구분', - align: 'center', - sortable: false, - value: 'orderType', - }, - { - text: '판매금액(캔)', - align: 'center', - sortable: false, - value: 'orderPrice', - }, - { - text: '판매수', - align: 'center', - sortable: false, - value: 'numberOfPeople', - }, - { - text: '합계(캔)', - align: 'center', - sortable: false, - value: 'totalCan', - }, - { - text: '원화', - align: 'center', - sortable: false, - value: 'totalKrw', - }, - { - text: '수수료\n(6.6%)', - align: 'center', - sortable: false, - value: 'paymentFee', - }, - { - text: '정산금액', - align: 'center', - sortable: false, - value: 'settlementAmount', - }, - { - text: '원천세\n(3.3%)', - align: 'center', - sortable: false, - value: 'tax', - }, - { - text: '입금액', - align: 'center', - sortable: false, - value: 'depositAmount', - }, - { - text: '등록일', - align: 'center', - sortable: false, - value: 'registrationDate', - }, - ], + } + }, + + computed: { + headers() { + return [ + { text: this.$t('view.calculate.content.headers.saleDate'), align: 'center', sortable: false, value: 'saleDate' }, + { text: this.$t('view.calculate.common.headers.creator'), align: 'center', sortable: false, value: 'nickname' }, + { text: this.$t('view.calculate.common.headers.title'), sortable: false, value: 'title', align: 'center', width: '300px' }, + { text: this.$t('view.calculate.common.headers.type'), align: 'center', sortable: false, value: 'orderType' }, + { text: this.$t('view.calculate.content.headers.orderPriceCan'), align: 'center', sortable: false, value: 'orderPrice' }, + { text: this.$t('view.calculate.content.headers.salesCount'), align: 'center', sortable: false, value: 'numberOfPeople' }, + { text: this.$t('view.calculate.common.headers.totalCan'), align: 'center', sortable: false, value: 'totalCan' }, + { text: this.$t('view.calculate.common.headers.krw'), align: 'center', sortable: false, value: 'totalKrw' }, + { text: this.$t('view.calculate.common.headers.feeWithPercent', { percent: '6.6%' }), align: 'center', sortable: false, value: 'paymentFee' }, + { text: this.$t('view.calculate.common.headers.settlementAmount'), align: 'center', sortable: false, value: 'settlementAmount' }, + { text: this.$t('view.calculate.common.headers.withholdingTaxWithPercent', { percent: '3.3%' }), align: 'center', sortable: false, value: 'tax' }, + { text: this.$t('view.calculate.common.headers.depositAmount'), align: 'center', sortable: false, value: 'depositAmount' }, + { text: this.$t('view.calculate.content.headers.registrationDate'), align: 'center', sortable: false, value: 'registrationDate' } + ] } }, @@ -277,12 +216,12 @@ export default { else this.total_page = totalPage } else { - this.notifyError(res.data.message || '알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.') + this.notifyError(res.data.message || this.$t('common.error.unknown')) } this.is_loading = false } catch (e) { - this.notifyError('알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.') + this.notifyError(this.$t('common.error.unknown')) this.is_loading = false } } diff --git a/src/views/Calculate/CalculateLive.vue b/src/views/Calculate/CalculateLive.vue index f42777f..64de30a 100644 --- a/src/views/Calculate/CalculateLive.vue +++ b/src/views/Calculate/CalculateLive.vue @@ -2,7 +2,7 @@
- 라이브 정산 + {{ $t('view.calculate.live.title') }} @@ -19,7 +19,7 @@ - ~ + {{ $t('view.calculate.common.rangeSeparator') }} @@ -40,7 +40,7 @@ depressed @click="getCalculateLive" > - 조회 + {{ $t('view.calculate.common.search') }} @@ -58,20 +58,20 @@ @@ -122,129 +122,27 @@ export default { start_date: null, end_date: null, items: [], - columns: [ - { - label: "크리에이터", - field: "nickname", - }, - { - label: "날짜", - field: "date", - }, - { - label: "제목", - field: "title", - }, - { - label: "구분", - field: "canUsageStr", - }, - { - label: "입장캔", - field: "entranceFee", - }, - { - label: "유료방참여인원", - field: "numberOfPeople", - }, - { - label: "합계(캔)", - field: "totalAmount", - }, - { - label: "원화", - field: "totalKrw", - }, - { - label: "결제수수료(6.6%)", - field: "paymentFee", - }, - { - label: "정산금액", - field: "settlementAmount", - }, - { - label: "원천세(3.3%)", - field: "tax", - }, - { - label: "입금액", - field: "depositAmount", - }, - ], - headers: [ - { - text: '크리에이터', - align: 'center', - sortable: false, - value: 'nickname', - }, - { - text: '날짜', - align: 'center', - sortable: false, - value: 'date', - }, - { - text: '제목', - sortable: false, - value: 'title', - }, - { - text: '구분', - align: 'center', - sortable: false, - value: 'canUsageStr', - }, - { - text: '입장캔', - align: 'center', - sortable: false, - value: 'entranceFee', - }, - { - text: '유료방참여인원', - align: 'center', - sortable: false, - value: 'numberOfPeople', - }, - { - text: '합계(캔)', - align: 'center', - sortable: false, - value: 'totalAmount', - }, - { - text: '원화', - align: 'center', - sortable: false, - value: 'totalKrw', - }, - { - text: '수수료\n(6.6%)', - align: 'center', - sortable: false, - value: 'paymentFee', - }, - { - text: '정산금액', - align: 'center', - sortable: false, - value: 'settlementAmount', - }, - { - text: '원천세\n(3.3%)', - align: 'center', - sortable: false, - value: 'tax', - }, - { - text: '입금액', - align: 'center', - sortable: false, - value: 'depositAmount', - } - ], + // columns(미사용) 정의는 남기되, 헤더는 i18n 반응형 computed로 전환 + columns: [], + } + }, + + computed: { + headers() { + return [ + { text: this.$t('view.calculate.common.headers.creator'), align: 'center', sortable: false, value: 'nickname' }, + { text: this.$t('view.calculate.common.headers.date'), align: 'center', sortable: false, value: 'date' }, + { text: this.$t('view.calculate.common.headers.title'), sortable: false, value: 'title' }, + { text: this.$t('view.calculate.common.headers.type'), align: 'center', sortable: false, value: 'canUsageStr' }, + { text: this.$t('view.calculate.live.headers.entranceCan'), align: 'center', sortable: false, value: 'entranceFee' }, + { text: this.$t('view.calculate.live.headers.paidParticipants'), align: 'center', sortable: false, value: 'numberOfPeople' }, + { text: this.$t('view.calculate.common.headers.totalCan'), align: 'center', sortable: false, value: 'totalAmount' }, + { text: this.$t('view.calculate.common.headers.krw'), align: 'center', sortable: false, value: 'totalKrw' }, + { text: this.$t('view.calculate.common.headers.feeWithPercent', { percent: '6.6%' }), align: 'center', sortable: false, value: 'paymentFee' }, + { text: this.$t('view.calculate.common.headers.settlementAmount'), align: 'center', sortable: false, value: 'settlementAmount' }, + { text: this.$t('view.calculate.common.headers.withholdingTaxWithPercent', { percent: '3.3%' }), align: 'center', sortable: false, value: 'tax' }, + { text: this.$t('view.calculate.common.headers.depositAmount'), align: 'center', sortable: false, value: 'depositAmount' } + ] } }, @@ -291,12 +189,12 @@ export default { if (res.status === 200 && res.data.success === true) { this.items = res.data.data } else { - this.notifyError(res.data.message || '알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.') + this.notifyError(res.data.message || this.$t('common.error.unknown')) } this.is_loading = false } catch (e) { - this.notifyError('알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.') + this.notifyError(this.$t('common.error.unknown')) this.is_loading = false } }