From 6751d691832c973e29ea30098d7fc0fb4e01e216 Mon Sep 17 00:00:00 2001 From: nabivi Date: Tue, 25 Aug 2026 13:19:17 +0900 Subject: [PATCH] =?UTF-8?q?fix(fe):=20=ED=94=84=EB=A1=A0=ED=8A=B8=20?= =?UTF-8?q?=EB=85=B9=EC=9D=8C=20=ED=99=94=EC=9E=90=20=EB=B6=84=EB=A6=AC=20?= =?UTF-8?q?=EC=B2=98=EB=A6=AC=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../checklist/RecordingModals.test.js | 19 ++++++++++- .../checklist/RecordingTextModal.vue | 34 +++++++++++++++++-- 2 files changed, 50 insertions(+), 3 deletions(-) diff --git a/frontend/src/components/checklist/RecordingModals.test.js b/frontend/src/components/checklist/RecordingModals.test.js index 874f63b..ec0ac47 100644 --- a/frontend/src/components/checklist/RecordingModals.test.js +++ b/frontend/src/components/checklist/RecordingModals.test.js @@ -46,7 +46,7 @@ describe('RecordingTextModal', () => { [{ isLoading: true }, '녹음 내용을 불러오고 있어요.'], [{ errorMessage: '조회 실패' }, '조회 실패'], [{ text: '' }, '변환된 녹음 텍스트가 아직 없어요.'], - [{ text: '첫 줄\n둘째 줄' }, '첫 줄\n둘째 줄'], + [{ text: '화자 정보 없는 녹음' }, '화자 정보 없는 녹음'], ])('조회 상태에 맞는 본문을 표시한다', (state, message) => { const wrapper = mount(RecordingTextModal, { props: { open: true, ...state }, @@ -55,6 +55,23 @@ describe('RecordingTextModal', () => { expect(wrapper.text()).toContain(message); }); + test('백엔드 화자 번호를 A와 B로 바꾸고 화자마다 별도 줄로 표시한다', () => { + const wrapper = mount(RecordingTextModal, { + props: { + open: true, + text: '화자 1: 첫 번째 발화 이어지는 발화\n화자 2: 두 번째 발화\n화자 1: 다시 첫 번째 화자', + }, + }); + + expect( + wrapper.findAll('.recording-text-modal__speaker-line').map((line) => line.text()), + ).toEqual([ + 'A: 첫 번째 발화 이어지는 발화', + 'B: 두 번째 발화', + 'A: 다시 첫 번째 화자', + ]); + }); + test('모달 shell 닫힘을 상위로 전달한다', async () => { const wrapper = mount(RecordingTextModal, { props: { open: true } }); await wrapper.get('.shell-close').trigger('click'); diff --git a/frontend/src/components/checklist/RecordingTextModal.vue b/frontend/src/components/checklist/RecordingTextModal.vue index ec5f794..a40a1aa 100644 --- a/frontend/src/components/checklist/RecordingTextModal.vue +++ b/frontend/src/components/checklist/RecordingTextModal.vue @@ -10,7 +10,28 @@ const props = defineProps({ errorMessage: { type: String, default: '' }, }); const emit = defineEmits(['close']); -const hasText = computed(() => Boolean(props.text.trim())); +const transcriptLines = computed(() => { + const speakerAliases = new Map(); + + return props.text + .split(/\r?\n/) + .map((line) => line.trim()) + .filter(Boolean) + .map((line) => { + const speakerLine = line.match(/^화자\s+([^:]+):\s*(.*)$/); + if (!speakerLine) return line; + + const [, speaker, content] = speakerLine; + if (!speakerAliases.has(speaker)) { + speakerAliases.set( + speaker, + String.fromCharCode(65 + speakerAliases.size), + ); + } + return `${speakerAliases.get(speaker)}: ${content}`; + }); +}); +const hasText = computed(() => transcriptLines.value.length > 0);