fix(wiki): citation drawer shows real data instead of empty fallbacks

Root cause: PageCitationWithRaw record only had id/pageId/chunkId/rawId/
paragraphIdx/anchorText/confidence — missing rawTitle, chunkOrdinal,
startOffset, endOffset, snippet. Frontend displayed Source + Chunk ?
for every card.

Backend:
- Extend PageCitationWithRaw with rawTitle, chunkOrdinal, startOffset,
  endOffset, snippet fields
- Expand listWithRawByPageId SQL to LEFT JOIN mate_wiki_raw_material for
  title, JOIN mate_wiki_chunk for ordinal/offsets/content snippet (first
  200 chars via SUBSTRING)

Frontend:
- CitationDrawer: replace hardcoded Source / Chunk ? / offset with
  i18n keys
- Add 4 new i18n keys: citationUnknownSource, citationChunkN,
  citationChunkUnknown, citationOffset (zh-CN + en-US)
This commit is contained in:
matevip 2026-04-19 19:36:57 +08:00
parent 527a67374d
commit cbcb7229b6
5 changed files with 22 additions and 5 deletions

View File

@ -6,4 +6,7 @@ import java.math.BigDecimal;
* RFC-029: Citation record joined with the chunk's raw material ID.
*/
public record PageCitationWithRaw(Long id, Long pageId, Long chunkId, Long rawId,
Integer paragraphIdx, String anchorText, BigDecimal confidence) {}
Integer paragraphIdx, String anchorText, BigDecimal confidence,
String rawTitle, Integer chunkOrdinal,
Integer startOffset, Integer endOffset,
String snippet) {}

View File

@ -15,9 +15,15 @@ import java.util.List;
@Mapper
public interface WikiPageCitationMapper extends BaseMapper<WikiPageCitationEntity> {
@Select("SELECT c.id, c.page_id, c.chunk_id, wc.raw_id, c.paragraph_idx, c.anchor_text, c.confidence " +
@Select("SELECT c.id, c.page_id, c.chunk_id, wc.raw_id, " +
"c.paragraph_idx, c.anchor_text, c.confidence, " +
"rm.title AS raw_title, " +
"wc.ordinal AS chunk_ordinal, " +
"wc.start_offset, wc.end_offset, " +
"SUBSTRING(wc.content, 1, 200) AS snippet " +
"FROM mate_wiki_page_citation c " +
"JOIN mate_wiki_chunk wc ON c.chunk_id = wc.id " +
"LEFT JOIN mate_wiki_raw_material rm ON wc.raw_id = rm.id " +
"WHERE c.page_id = #{pageId} AND c.deleted = 0")
List<PageCitationWithRaw> listWithRawByPageId(@Param("pageId") Long pageId);

View File

@ -1284,6 +1284,10 @@ export default {
repair: 'Repair page',
citations: '{count} source chunks',
noCitations: 'No source citations found',
citationUnknownSource: 'Unknown source',
citationChunkN: 'Chunk {n}',
citationChunkUnknown: 'Chunk unknown',
citationOffset: 'offset {start}{end}',
},
relation: {
shared_chunk: 'Shared chunk',

View File

@ -1294,6 +1294,10 @@ export default {
repair: '修复页面',
citations: '来源 {count} 个 chunk',
noCitations: '未找到来源引用',
citationUnknownSource: '未知来源',
citationChunkN: '第 {n} 段',
citationChunkUnknown: '段落未知',
citationOffset: '偏移 {start}{end}',
},
relation: {
shared_chunk: '共享片段',

View File

@ -12,11 +12,11 @@
</div>
<div v-else class="citation-list">
<div v-for="cit in citations" :key="cit.id" class="citation-item">
<div class="citation-raw-title">{{ cit.rawTitle || 'Source' }}</div>
<div class="citation-raw-title">{{ cit.rawTitle || t('wiki.page.citationUnknownSource') }}</div>
<div class="citation-chunk-info">
Chunk {{ cit.chunkOrdinal ?? '?' }}
{{ cit.chunkOrdinal != null ? t('wiki.page.citationChunkN', { n: cit.chunkOrdinal }) : t('wiki.page.citationChunkUnknown') }}
<span v-if="cit.startOffset != null" class="citation-offset">
(offset {{ cit.startOffset }}{{ cit.endOffset }})
({{ t('wiki.page.citationOffset', { start: cit.startOffset, end: cit.endOffset }) }})
</span>
</div>
<div v-if="cit.snippet" class="citation-snippet">"{{ cit.snippet }}"</div>