feat: 관리자 수동 이미지 대체 기능 추가
This commit is contained in:
@@ -16,6 +16,11 @@ export function useAdminCustomItems({
|
||||
customItemModalDraftLabel,
|
||||
customItemModalLabelSaving,
|
||||
customItemModalTargetTemplateId,
|
||||
customItemReplacementQuery,
|
||||
customItemReplacementItems,
|
||||
customItemReplacementLoading,
|
||||
customItemReplacementTargetId,
|
||||
customItemReplacementBusy,
|
||||
templates,
|
||||
selectedTemplateId,
|
||||
refreshCustomItems,
|
||||
@@ -56,12 +61,41 @@ export function useAdminCustomItems({
|
||||
customItemModalHistoryActive.value = true
|
||||
}
|
||||
|
||||
async function refreshReplacementCandidates() {
|
||||
const currentItemId = modalTargetCustomItem.value?.id || ''
|
||||
if (!currentItemId) {
|
||||
customItemReplacementItems.value = []
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
customItemReplacementLoading.value = true
|
||||
const data = await api.listAdminCustomItems({
|
||||
q: customItemReplacementQuery.value,
|
||||
page: 1,
|
||||
limit: 50,
|
||||
filter: 'all',
|
||||
})
|
||||
customItemReplacementItems.value = (data.items || []).filter((item) => item?.id && item.id !== currentItemId)
|
||||
} catch (e) {
|
||||
error.value = '대체할 이미지 목록을 불러오지 못했어요.'
|
||||
customItemReplacementItems.value = []
|
||||
} finally {
|
||||
customItemReplacementLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
function openCustomItemModal(item) {
|
||||
modalTargetCustomItem.value = item || null
|
||||
customItemModalDraftLabel.value = item?.label || ''
|
||||
customItemModalTargetTemplateId.value = ''
|
||||
customItemReplacementQuery.value = item?.label || ''
|
||||
customItemReplacementItems.value = []
|
||||
customItemReplacementTargetId.value = ''
|
||||
customItemReplacementBusy.value = false
|
||||
customItemModalOpen.value = true
|
||||
pushCustomItemModalHistoryState()
|
||||
void refreshReplacementCandidates()
|
||||
}
|
||||
|
||||
function closeCustomItemModal({ fromPopState = false } = {}) {
|
||||
@@ -71,6 +105,11 @@ export function useAdminCustomItems({
|
||||
customItemModalDraftLabel.value = ''
|
||||
customItemModalLabelSaving.value = false
|
||||
customItemModalTargetTemplateId.value = ''
|
||||
customItemReplacementQuery.value = ''
|
||||
customItemReplacementItems.value = []
|
||||
customItemReplacementTargetId.value = ''
|
||||
customItemReplacementLoading.value = false
|
||||
customItemReplacementBusy.value = false
|
||||
|
||||
if (fromPopState) {
|
||||
customItemModalHistoryActive.value = false
|
||||
@@ -190,6 +229,35 @@ export function useAdminCustomItems({
|
||||
}
|
||||
}
|
||||
|
||||
async function replaceCustomItem(item = modalTargetCustomItem.value) {
|
||||
resetMessages()
|
||||
const targetItem = customItemReplacementItems.value.find((entry) => entry.id === customItemReplacementTargetId.value)
|
||||
if (!item?.id) {
|
||||
error.value = '대체할 원본 아이템을 찾지 못했어요.'
|
||||
return
|
||||
}
|
||||
if (!targetItem?.id) {
|
||||
error.value = '대체할 대상 이미지를 먼저 선택해주세요.'
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
customItemReplacementBusy.value = true
|
||||
const data = await api.replaceAdminCustomItem(item.id, {
|
||||
targetItemId: targetItem.id,
|
||||
targetSourceType: targetItem.sourceType || 'user',
|
||||
})
|
||||
if (selectedTemplateId.value) await loadTemplate()
|
||||
await refreshCustomItems()
|
||||
closeCustomItemModal()
|
||||
success.value = `"${item.label}" 이미지를 "${data.targetItem?.label || targetItem.label}" 기준으로 대체했어요.`
|
||||
} catch (e) {
|
||||
error.value = e?.status === 409 ? '같은 이미지/이름으로는 대체할 수 없어요.' : '이미지 대체에 실패했어요.'
|
||||
} finally {
|
||||
customItemReplacementBusy.value = false
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
submitCustomItemSearch,
|
||||
changeCustomItemFilter,
|
||||
@@ -205,5 +273,7 @@ export function useAdminCustomItems({
|
||||
removeUnusedCustomItems,
|
||||
saveCustomItemModalLabel,
|
||||
promoteCustomItem,
|
||||
refreshReplacementCandidates,
|
||||
replaceCustomItem,
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user