feat(calculate): 레거시 정산 화면 P2 1차 i18n 치환(Live/Content) 및 리소스/문서 업데이트

This commit is contained in:
Yu Sung
2026-05-08 14:39:30 +09:00
parent 4e0b40afc0
commit 8e8cfa68b3
6 changed files with 225 additions and 247 deletions

View File

@@ -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차로 순차 치환 예정

View File

@@ -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",

View File

@@ -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": "パスワード",

View File

@@ -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": "비밀번호",

View File

@@ -2,7 +2,7 @@
<div>
<v-toolbar dark>
<v-spacer />
<v-toolbar-title>콘텐츠 정산</v-toolbar-title>
<v-toolbar-title>{{ $t('view.calculate.content.title') }}</v-toolbar-title>
<v-spacer />
</v-toolbar>
@@ -19,7 +19,7 @@
</v-col>
<v-col cols="1">
~
{{ $t('view.calculate.common.rangeSeparator') }}
</v-col>
<v-col cols="2">
@@ -40,7 +40,7 @@
depressed
@click="getCalculateContent"
>
조회
{{ $t('view.calculate.common.search') }}
</v-btn>
</v-col>
@@ -60,21 +60,21 @@
<template slot="body.prepend">
<tr>
<td colspan="5">
합계
{{ $t('view.calculate.common.total') }}
</td>
<td>{{ sumField('numberOfPeople').toLocaleString() }}</td>
<td>{{ sumField('totalCan').toLocaleString() }} </td>
<td>{{ sumField('totalKrw').toLocaleString() }} </td>
<td>{{ sumField('paymentFee').toLocaleString() }} </td>
<td>{{ sumField('settlementAmount').toLocaleString() }} </td>
<td>{{ sumField('tax').toLocaleString() }} </td>
<td>{{ sumField('depositAmount').toLocaleString() }} </td>
<td>{{ sumField('numberOfPeople').toLocaleString() }} {{ $t('common.unit.person') }}</td>
<td>{{ sumField('totalCan').toLocaleString() }} {{ $t('common.unit.can') }}</td>
<td>{{ sumField('totalKrw').toLocaleString() }} {{ $t('common.unit.krw') }}</td>
<td>{{ sumField('paymentFee').toLocaleString() }} {{ $t('common.unit.krw') }}</td>
<td>{{ sumField('settlementAmount').toLocaleString() }} {{ $t('common.unit.krw') }}</td>
<td>{{ sumField('tax').toLocaleString() }} {{ $t('common.unit.krw') }}</td>
<td>{{ sumField('depositAmount').toLocaleString() }} {{ $t('common.unit.krw') }}</td>
<td />
</tr>
</template>
<template v-slot:item.orderPrice="{ item }">
{{ item.orderPrice.toLocaleString() }}
{{ item.orderPrice.toLocaleString() }} {{ $t('common.unit.can') }}
</template>
<template v-slot:item.orderType="{ item }">
@@ -82,27 +82,27 @@
</template>
<template v-slot:item.totalCan="{ item }">
{{ item.totalCan.toLocaleString() }}
{{ item.totalCan.toLocaleString() }} {{ $t('common.unit.can') }}
</template>
<template v-slot:item.totalKrw="{ item }">
{{ item.totalKrw.toLocaleString() }}
{{ item.totalKrw.toLocaleString() }} {{ $t('common.unit.krw') }}
</template>
<template v-slot:item.paymentFee="{ item }">
{{ item.paymentFee.toLocaleString() }}
{{ item.paymentFee.toLocaleString() }} {{ $t('common.unit.krw') }}
</template>
<template v-slot:item.settlementAmount="{ item }">
{{ item.settlementAmount.toLocaleString() }}
{{ item.settlementAmount.toLocaleString() }} {{ $t('common.unit.krw') }}
</template>
<template v-slot:item.tax="{ item }">
{{ item.tax.toLocaleString() }}
{{ item.tax.toLocaleString() }} {{ $t('common.unit.krw') }}
</template>
<template v-slot:item.depositAmount="{ item }">
{{ item.depositAmount.toLocaleString() }}
{{ item.depositAmount.toLocaleString() }} {{ $t('common.unit.krw') }}
</template>
</v-data-table>
</v-col>
@@ -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
}
}

View File

@@ -2,7 +2,7 @@
<div>
<v-toolbar dark>
<v-spacer />
<v-toolbar-title>라이브 정산</v-toolbar-title>
<v-toolbar-title>{{ $t('view.calculate.live.title') }}</v-toolbar-title>
<v-spacer />
</v-toolbar>
@@ -19,7 +19,7 @@
</v-col>
<v-col cols="1">
~
{{ $t('view.calculate.common.rangeSeparator') }}
</v-col>
<v-col cols="2">
@@ -40,7 +40,7 @@
depressed
@click="getCalculateLive"
>
조회
{{ $t('view.calculate.common.search') }}
</v-btn>
</v-col>
</v-row>
@@ -58,20 +58,20 @@
<template slot="body.prepend">
<tr>
<td colspan="5">
합계
{{ $t('view.calculate.common.total') }}
</td>
<td>{{ sumField('numberOfPeople').toLocaleString() }} </td>
<td>{{ sumField('totalAmount').toLocaleString() }} </td>
<td>{{ sumField('totalKrw').toLocaleString() }} </td>
<td>{{ sumField('paymentFee').toLocaleString() }} </td>
<td>{{ sumField('settlementAmount').toLocaleString() }} </td>
<td>{{ sumField('tax').toLocaleString() }} </td>
<td>{{ sumField('depositAmount').toLocaleString() }} </td>
<td>{{ sumField('numberOfPeople').toLocaleString() }} {{ $t('common.unit.person') }}</td>
<td>{{ sumField('totalAmount').toLocaleString() }} {{ $t('common.unit.can') }}</td>
<td>{{ sumField('totalKrw').toLocaleString() }} {{ $t('common.unit.krw') }}</td>
<td>{{ sumField('paymentFee').toLocaleString() }} {{ $t('common.unit.krw') }}</td>
<td>{{ sumField('settlementAmount').toLocaleString() }} {{ $t('common.unit.krw') }}</td>
<td>{{ sumField('tax').toLocaleString() }} {{ $t('common.unit.krw') }}</td>
<td>{{ sumField('depositAmount').toLocaleString() }} {{ $t('common.unit.krw') }}</td>
</tr>
</template>
<template v-slot:item.entranceFee="{ item }">
{{ item.entranceFee.toLocaleString() }}
{{ item.entranceFee.toLocaleString() }} {{ $t('common.unit.can') }}
</template>
<template v-slot:item.canUsageStr="{ item }">
@@ -79,27 +79,27 @@
</template>
<template v-slot:item.totalAmount="{ item }">
{{ item.totalAmount.toLocaleString() }}
{{ item.totalAmount.toLocaleString() }} {{ $t('common.unit.can') }}
</template>
<template v-slot:item.totalKrw="{ item }">
{{ item.totalKrw.toLocaleString() }}
{{ item.totalKrw.toLocaleString() }} {{ $t('common.unit.krw') }}
</template>
<template v-slot:item.paymentFee="{ item }">
{{ item.paymentFee.toLocaleString() }}
{{ item.paymentFee.toLocaleString() }} {{ $t('common.unit.krw') }}
</template>
<template v-slot:item.settlementAmount="{ item }">
{{ item.settlementAmount.toLocaleString() }}
{{ item.settlementAmount.toLocaleString() }} {{ $t('common.unit.krw') }}
</template>
<template v-slot:item.tax="{ item }">
{{ item.tax.toLocaleString() }}
{{ item.tax.toLocaleString() }} {{ $t('common.unit.krw') }}
</template>
<template v-slot:item.depositAmount="{ item }">
{{ item.depositAmount.toLocaleString() }}
{{ item.depositAmount.toLocaleString() }} {{ $t('common.unit.krw') }}
</template>
</v-data-table>
</v-col>
@@ -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
}
}