mirror of
https://github.com/nagisa77/OpenIsle.git
synced 2026-05-21 18:07:28 +08:00
Merge pull request #119 from nagisa77/codex/update-search-functionality-with-details
Improve search result details
This commit is contained in:
@@ -10,7 +10,11 @@
|
|||||||
</template>
|
</template>
|
||||||
<template #option="{ option }">
|
<template #option="{ option }">
|
||||||
<i :class="['result-icon', iconMap[option.type] || 'fas fa-question']"></i>
|
<i :class="['result-icon', iconMap[option.type] || 'fas fa-question']"></i>
|
||||||
<span v-html="highlight(option.text)"></span>
|
<div class="result-body">
|
||||||
|
<div class="result-main" v-html="highlight(option.text)"></div>
|
||||||
|
<div v-if="option.subText" class="result-sub" v-html="highlight(option.subText)"></div>
|
||||||
|
<div v-if="option.extra" class="result-extra" v-html="highlight(option.extra)"></div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
</div>
|
</div>
|
||||||
@@ -33,7 +37,13 @@ export default {
|
|||||||
const res = await fetch(`${API_BASE_URL}/api/search/global?keyword=${encodeURIComponent(kw)}`)
|
const res = await fetch(`${API_BASE_URL}/api/search/global?keyword=${encodeURIComponent(kw)}`)
|
||||||
if (!res.ok) return []
|
if (!res.ok) return []
|
||||||
const data = await res.json()
|
const data = await res.json()
|
||||||
return data.map(r => ({ id: r.id, text: r.text, type: r.type }))
|
return data.map(r => ({
|
||||||
|
id: r.id,
|
||||||
|
text: r.text,
|
||||||
|
type: r.type,
|
||||||
|
subText: r.subText,
|
||||||
|
extra: r.extra
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
const highlight = (text) => {
|
const highlight = (text) => {
|
||||||
@@ -93,4 +103,19 @@ export default {
|
|||||||
.result-icon {
|
.result-icon {
|
||||||
opacity: 0.6;
|
opacity: 0.6;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.result-body {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.result-main {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.result-sub,
|
||||||
|
.result-extra {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -56,6 +56,8 @@ public class SearchController {
|
|||||||
dto.setType(r.type());
|
dto.setType(r.type());
|
||||||
dto.setId(r.id());
|
dto.setId(r.id());
|
||||||
dto.setText(r.text());
|
dto.setText(r.text());
|
||||||
|
dto.setSubText(r.subText());
|
||||||
|
dto.setExtra(r.extra());
|
||||||
return dto;
|
return dto;
|
||||||
})
|
})
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
@@ -92,5 +94,7 @@ public class SearchController {
|
|||||||
private String type;
|
private String type;
|
||||||
private Long id;
|
private Long id;
|
||||||
private String text;
|
private String text;
|
||||||
|
private String subText;
|
||||||
|
private String extra;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,15 +47,33 @@ public class SearchService {
|
|||||||
|
|
||||||
public List<SearchResult> globalSearch(String keyword) {
|
public List<SearchResult> globalSearch(String keyword) {
|
||||||
Stream<SearchResult> users = searchUsers(keyword).stream()
|
Stream<SearchResult> users = searchUsers(keyword).stream()
|
||||||
.map(u -> new SearchResult("user", u.getId(), u.getUsername()));
|
.map(u -> new SearchResult(
|
||||||
|
"user",
|
||||||
|
u.getId(),
|
||||||
|
u.getUsername(),
|
||||||
|
u.getIntroduction(),
|
||||||
|
null
|
||||||
|
));
|
||||||
|
|
||||||
// Merge post results while removing duplicates between search by content
|
// Merge post results while removing duplicates between search by content
|
||||||
// and search by title
|
// and search by title
|
||||||
List<SearchResult> mergedPosts = Stream.concat(
|
List<SearchResult> mergedPosts = Stream.concat(
|
||||||
searchPosts(keyword).stream()
|
searchPosts(keyword).stream()
|
||||||
.map(p -> new SearchResult("post", p.getId(), p.getTitle())),
|
.map(p -> new SearchResult(
|
||||||
|
"post",
|
||||||
|
p.getId(),
|
||||||
|
p.getTitle(),
|
||||||
|
p.getCategory().getName(),
|
||||||
|
extractSnippet(p.getContent(), keyword, false)
|
||||||
|
)),
|
||||||
searchPostsByTitle(keyword).stream()
|
searchPostsByTitle(keyword).stream()
|
||||||
.map(p -> new SearchResult("post_title", p.getId(), p.getTitle()))
|
.map(p -> new SearchResult(
|
||||||
|
"post_title",
|
||||||
|
p.getId(),
|
||||||
|
p.getTitle(),
|
||||||
|
p.getCategory().getName(),
|
||||||
|
extractSnippet(p.getContent(), keyword, true)
|
||||||
|
))
|
||||||
)
|
)
|
||||||
.collect(java.util.stream.Collectors.toMap(
|
.collect(java.util.stream.Collectors.toMap(
|
||||||
SearchResult::id,
|
SearchResult::id,
|
||||||
@@ -68,11 +86,33 @@ public class SearchService {
|
|||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
Stream<SearchResult> comments = searchComments(keyword).stream()
|
Stream<SearchResult> comments = searchComments(keyword).stream()
|
||||||
.map(c -> new SearchResult("comment", c.getId(), c.getContent()));
|
.map(c -> new SearchResult(
|
||||||
|
"comment",
|
||||||
|
c.getId(),
|
||||||
|
extractSnippet(c.getContent(), keyword, false),
|
||||||
|
c.getAuthor().getUsername(),
|
||||||
|
c.getPost().getTitle()
|
||||||
|
));
|
||||||
|
|
||||||
return Stream.concat(Stream.concat(users, mergedPosts.stream()), comments)
|
return Stream.concat(Stream.concat(users, mergedPosts.stream()), comments)
|
||||||
.toList();
|
.toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public record SearchResult(String type, Long id, String text) {}
|
private String extractSnippet(String content, String keyword, boolean fromStart) {
|
||||||
|
if (content == null) return "";
|
||||||
|
if (fromStart) {
|
||||||
|
return content.length() > 50 ? content.substring(0, 50) : content;
|
||||||
|
}
|
||||||
|
String lower = content.toLowerCase();
|
||||||
|
String kw = keyword.toLowerCase();
|
||||||
|
int idx = lower.indexOf(kw);
|
||||||
|
if (idx == -1) {
|
||||||
|
return content.length() > 50 ? content.substring(0, 50) : content;
|
||||||
|
}
|
||||||
|
int start = Math.max(0, idx - 20);
|
||||||
|
int end = Math.min(content.length(), idx + kw.length() + 20);
|
||||||
|
return content.substring(start, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
public record SearchResult(String type, Long id, String text, String subText, String extra) {}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user