feat: PubMed搜索合规审计 Phase 5-7 全部修复
P1-2: [SB][STAT][UID][DEP][MESH]字段支持 P1-4: [MH:noexp]解析+抑制树展开 P3: 前端date_to/P3-1、CJK高亮/P3-3、extractPlainText/P3-4、precision_mode移除/P3-6、loadMore sort/P3-5 P4-1: 词数上限50→100 P4-2: retracted参数清理
This commit is contained in:
@@ -111,8 +111,11 @@ const nctId = computed(() => {
|
||||
// 从查询中提取纯文本词(去掉 PubMed 字段标签如 [TI]、[AB] 等)
|
||||
function extractPlainText(q: string): string {
|
||||
return q
|
||||
.replace(/\[[\w-]+\]/g, '')
|
||||
.replace(/"?\b(AND|OR|NOT)\b"?/gi, '')
|
||||
.replace(/\[[\w-]+\]/g, '') // [field tags]
|
||||
.replace(/"?\b(AND|OR|NOT)\b"?/gi, '')// boolean operators
|
||||
.replace(/[()]/g, '') // P3-4: 去掉括号
|
||||
.replace(/#\d+/g, '') // P3-4: 去掉 #N 引用标记
|
||||
.replace(/\*/g, '') // P3-4: 去掉通配符
|
||||
.replace(/"/g, '')
|
||||
.replace(/\s+/g, ' ')
|
||||
.trim()
|
||||
@@ -127,8 +130,9 @@ const highlightedTitle = computed(() => {
|
||||
const terms = plain.split(/\s+/).filter(t => t.length > 0)
|
||||
if (terms.length === 0) return ''
|
||||
const escaped = terms.map(t => t.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'))
|
||||
// 单字符词添加 \b 词边界避免过匹配("A" 不匹配每个字母 "a")
|
||||
const pattern = escaped.map(e => e.length === 1 ? `\\b${e}\\b` : e).join('|')
|
||||
// P3-3: 单字符词添加 \b 词边界,但 CJK 字符跳过(\b 对 CJK 无效)
|
||||
const isCJK = (c: string) => /[一-鿿㐀-䶿豈-]/.test(c)
|
||||
const pattern = escaped.map(e => e.length === 1 && !isCJK(e) ? `\\b${e}\\b` : e).join('|')
|
||||
const parts = title.split(new RegExp(`(${pattern})`, 'gi'))
|
||||
return parts.map((part: string) =>
|
||||
terms.some(t => part.toLowerCase() === t.toLowerCase())
|
||||
|
||||
@@ -277,7 +277,7 @@ const { page, total, goToPage } = usePagination({
|
||||
query: query.value, page: p, page_size: pageSize.value, sort: sort.value,
|
||||
}
|
||||
if (field.value !== 'all') body.field = field.value
|
||||
if (precisionMode.value !== 'majr') body.precision_mode = precisionMode.value
|
||||
// P3-6: precision_mode 不再发送(后端已忽略)
|
||||
// ── Keyset 游标分页(sort=date 时跳过 COUNT,纯翻页模式) ──
|
||||
const useKeyset = sort.value === 'date'
|
||||
if (useKeyset) {
|
||||
@@ -371,10 +371,11 @@ function restoreFromQuery() {
|
||||
datePreset.value = String(route.query.date_preset)
|
||||
} else if (route.query.date_from) {
|
||||
datePreset.value = null
|
||||
// 尝试解析 date_from/date_to 到 yearFromStr/yearToStr
|
||||
const df = String(route.query.date_from)
|
||||
if (df.length >= 4) yearFromStr.value = df.slice(0, 4)
|
||||
} else if (route.query.date_to) {
|
||||
}
|
||||
if (route.query.date_to) {
|
||||
datePreset.value = null
|
||||
const dt = String(route.query.date_to)
|
||||
if (dt.length >= 4) yearToStr.value = dt.slice(0, 4)
|
||||
}
|
||||
|
||||
@@ -214,7 +214,7 @@ function doLocalSearch() {
|
||||
if (searchParams.value.date_from) query.date_from = searchParams.value.date_from
|
||||
if (searchParams.value.date_to) query.date_to = searchParams.value.date_to
|
||||
if (searchParams.value.sort && searchParams.value.sort !== 'date') query.sort = searchParams.value.sort
|
||||
if (searchParams.value.precision_mode && searchParams.value.precision_mode !== 'majr') query.precision = searchParams.value.precision_mode
|
||||
// P3-6: precision_mode 不再发送
|
||||
if (searchParams.value.retracted) query.retracted = searchParams.value.retracted
|
||||
if (searchParams.value.negative_result) query.negative = searchParams.value.negative_result
|
||||
if (selectedTagIds.value.length > 0) query.tag = selectedTagIds.value.join(',')
|
||||
@@ -319,7 +319,7 @@ async function loadMore() {
|
||||
if (loadingMore.value || !hasMore.value) return
|
||||
loadingMore.value = true
|
||||
try {
|
||||
const body: Record<string, any> = { page_size: searchParams.value.page_size, sort: 'date' }
|
||||
const body: Record<string, any> = { page_size: searchParams.value.page_size, sort: searchParams.value.sort || 'date' }
|
||||
if (searchParams.value.query) body.query = searchParams.value.query
|
||||
if (searchParams.value.field !== 'all') body.field = searchParams.value.field
|
||||
if (searchParams.value.tag_ids.length) body.tag_ids = searchParams.value.tag_ids
|
||||
@@ -327,7 +327,7 @@ async function loadMore() {
|
||||
if (searchParams.value.date_to) body.date_to = searchParams.value.date_to
|
||||
if (searchParams.value.retracted) body.retracted = searchParams.value.retracted
|
||||
if (searchParams.value.negative_result) body.negative_result = searchParams.value.negative_result
|
||||
if (searchParams.value.precision_mode) body.precision_mode = searchParams.value.precision_mode
|
||||
// P3-6: precision_mode 不再发送
|
||||
if (cursorDate.value && cursorId.value) {
|
||||
body.cursor_date = cursorDate.value
|
||||
body.cursor_id = cursorId.value
|
||||
|
||||
Reference in New Issue
Block a user