게시물 가져오기 중복 복원 방지
This commit is contained in:
@@ -121,6 +121,29 @@ const postExportDateRangeModeOptions = [
|
||||
{ value: 'month', label: '특정월' },
|
||||
{ value: 'custom', label: '직접 지정' }
|
||||
]
|
||||
|
||||
const postImportStatusSummary = computed(() => {
|
||||
if (!postImportResult.value) {
|
||||
return ''
|
||||
}
|
||||
|
||||
const result = postImportResult.value
|
||||
const segments = [
|
||||
`게시물 ${Number(result.importedCount || 0)}개 가져옴`
|
||||
]
|
||||
|
||||
if (Number(result.skippedCount || 0) > 0) {
|
||||
segments.push(`${Number(result.skippedCount || 0)}개 건너뜀`)
|
||||
}
|
||||
|
||||
segments.push(`신규 자산 ${Number(result.assetCount || 0)}개`)
|
||||
|
||||
if (Number(result.reusedAssetCount || 0) > 0) {
|
||||
segments.push(`재사용 자산 ${Number(result.reusedAssetCount || 0)}개`)
|
||||
}
|
||||
|
||||
return segments.join(', ')
|
||||
})
|
||||
/** 블로그 제목·설명 카드 편집 모드 여부 */
|
||||
const editTitleDesc = ref(false)
|
||||
/** 사이트 정보 카드 편집 모드 여부 */
|
||||
@@ -975,6 +998,10 @@ const requestPostExport = async () => {
|
||||
* @returns {void}
|
||||
*/
|
||||
const openPostImportFilePicker = () => {
|
||||
if (importingPosts.value) {
|
||||
return
|
||||
}
|
||||
|
||||
postImportInputRef.value?.click()
|
||||
}
|
||||
|
||||
@@ -984,6 +1011,10 @@ const openPostImportFilePicker = () => {
|
||||
* @returns {boolean} 선택 성공 여부
|
||||
*/
|
||||
const selectPostImportFile = (file) => {
|
||||
if (importingPosts.value) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (!file) {
|
||||
return false
|
||||
}
|
||||
@@ -1028,6 +1059,10 @@ const dropPostImportFile = (event) => {
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
const importSelectedPostFile = async () => {
|
||||
if (importingPosts.value) {
|
||||
return
|
||||
}
|
||||
|
||||
if (!postImportFile.value) {
|
||||
showToast('error', '가져올 ZIP 파일을 먼저 선택해 주세요.')
|
||||
return
|
||||
@@ -1049,7 +1084,7 @@ const importSelectedPostFile = async () => {
|
||||
postImportResult.value = result
|
||||
postImportFile.value = null
|
||||
postImportFileName.value = ''
|
||||
showToast('success', `게시물 ${result.importedCount}개를 가져왔습니다.`)
|
||||
showToast('success', postImportStatusSummary.value || '게시물 가져오기가 완료되었습니다.')
|
||||
} catch (error) {
|
||||
const message = error?.data?.message || '게시물 가져오기를 완료하지 못했습니다.'
|
||||
showToast('error', message)
|
||||
@@ -3914,7 +3949,7 @@ onBeforeUnmount(() => {
|
||||
게시물 가져오기
|
||||
</h2>
|
||||
<p class="mt-1 text-sm leading-relaxed text-[#657080]">
|
||||
내보내기로 만든 ZIP 백업을 게시물과 미디어 파일로 복원합니다.
|
||||
내보내기로 만든 ZIP 백업을 게시물과 미디어 파일로 복원합니다. 이미 같은 slug가 있는 게시물은 건너뜁니다.
|
||||
</p>
|
||||
</div>
|
||||
<button
|
||||
@@ -3922,6 +3957,7 @@ onBeforeUnmount(() => {
|
||||
type="button"
|
||||
:aria-expanded="postImportExportPanel === 'import'"
|
||||
aria-controls="admin-settings-import-panel"
|
||||
:disabled="importingPosts"
|
||||
@click="togglePostImportExportPanel('import')"
|
||||
>
|
||||
{{ postImportExportPanel === 'import' ? '접기' : '가져오기' }}
|
||||
@@ -3938,6 +3974,7 @@ onBeforeUnmount(() => {
|
||||
class="sr-only"
|
||||
type="file"
|
||||
accept=".zip,application/zip"
|
||||
:disabled="importingPosts"
|
||||
@change="handlePostImportFileChange"
|
||||
>
|
||||
<button
|
||||
@@ -3956,10 +3993,18 @@ onBeforeUnmount(() => {
|
||||
</svg>
|
||||
<span>{{ postImportFileName || 'ZIP 파일을 드롭하거나 선택하세요.' }}</span>
|
||||
<span class="text-xs font-medium text-[#8a94a3]">
|
||||
같은 슬러그가 있으면 덮어쓰지 않고 새 슬러그로 가져옵니다.
|
||||
같은 slug의 게시물은 덮어쓰지 않고 건너뛰며, 건너뛴 게시물의 자산도 다시 저장하지 않습니다.
|
||||
</span>
|
||||
</span>
|
||||
</button>
|
||||
<div
|
||||
v-if="importingPosts"
|
||||
class="admin-settings-screen__import-progress rounded-md bg-[#eef5ff] px-3 py-2 text-sm text-[#1f5f99] ring-1 ring-inset ring-[#bdd8f3]"
|
||||
role="status"
|
||||
aria-live="polite"
|
||||
>
|
||||
게시물을 가져오는 중입니다. 대량 ZIP은 시간이 걸릴 수 있으니 이 화면을 닫지 마세요.
|
||||
</div>
|
||||
<div class="flex items-center justify-end">
|
||||
<button
|
||||
class="inline-flex h-10 shrink-0 cursor-pointer items-center justify-center rounded-md bg-[#15171a] px-4 text-sm font-semibold text-white transition hover:bg-black disabled:cursor-not-allowed disabled:bg-[#c7cdd4]"
|
||||
@@ -3974,7 +4019,15 @@ onBeforeUnmount(() => {
|
||||
v-if="postImportResult"
|
||||
class="rounded-md bg-[#f4fbf7] px-3 py-2 text-sm text-[#147a45] ring-1 ring-inset ring-[#b9e7cd]"
|
||||
>
|
||||
게시물 {{ postImportResult.importedCount }}개, 자산 {{ postImportResult.assetCount }}개를 가져왔습니다.
|
||||
{{ postImportStatusSummary }}
|
||||
<ul v-if="postImportResult.skippedPosts?.length" class="mt-2 grid gap-1 text-xs leading-relaxed text-[#24633f]">
|
||||
<li
|
||||
v-for="post in postImportResult.skippedPosts"
|
||||
:key="`${post.slug}-${post.reason}`"
|
||||
>
|
||||
건너뜀: {{ post.title }} ({{ post.slug }})
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div
|
||||
v-if="postImportResult?.warningCount"
|
||||
|
||||
Reference in New Issue
Block a user