This article focuses on Day 9 of iterating a Spring Boot + Vue 3 enterprise portal. The update centers on accurate search matching, improved copy-warning modal design, better footer overlay interactions, and stronger navigation styling to fix search inconsistency and fragmented UI experience. Keywords: Spring Boot, Vue 3, search optimization.
The technical specification snapshot is clear
| Parameter | Description |
|---|---|
| Backend Language | Java |
| Frontend Framework | Vue 3 |
| Backend Framework | Spring Boot |
| Core Protocol | HTTP/REST |
| Data Access | MyBatis-Plus (inferred from QueryWrapper) |
| UI Styling | Tailwind CSS-style utility classes |
| GitHub Stars | Not provided in the original article |
| Core Dependencies | Spring MVC, Vue 3, Teleport, Transition |
This iteration focuses on improving search accuracy and UI completeness
This update does not introduce a major new feature. Instead, it fixes the usability of existing capabilities. Search returning the full result set, no feedback for zero matches, rough modal visuals, and weak navigation hierarchy all directly reduce user retention and retrieval efficiency.
The original page included two screenshots that correspond to the search page and the UI optimization results:
AI Visual Insight: This image shows the portal’s search results or content list interface. Key elements include the top search entry point, a card-based content layout, and a consistent light background system. This suggests the frontend already uses a component-based page structure, making it well-suited for additional interactions such as empty-state prompts, keyword feedback, and navigation highlighting.
AI Visual Insight: This image presents the optimized visual style of the page, including clearer module boundaries, more generous spacing, and likely improvements to modal or footer sections. It shows that beyond feature development, the project has started to focus on brand presence, consistency, and interaction feedback quality, which are all common priorities for enterprise websites.
The search logic must evolve from “searchable” to “accurate”
The issue in the original implementation is common: after users entered a keyword, the API did not effectively narrow the result set, so search behaved more like list browsing. For a content-driven portal, this can make users think search is broken.
The backend fix is straightforward. In the /list endpoint, the implementation adds conditional query assembly for keyword. Only when a keyword is present does it perform like matching against both content and title.
@GetMapping(value = "/list")
public Result<IPage<YucmsArticle>> queryPageList(
YucmsArticle yucmsArticle,
@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
@RequestParam(name = "keyword", required = false) String keyword,
HttpServletRequest req) {
QueryWrapper
<YucmsArticle> queryWrapper =
QueryGenerator.initQueryWrapper(yucmsArticle, req.getParameterMap()); // Initialize the base query conditions
if (oConvertUtils.isNotEmpty(keyword)) {
queryWrapper.and(wrapper -> wrapper
.like("content", keyword) // Match article content
.or()
.like("title", keyword)); // Match article title
}
Page
<YucmsArticle> page = new Page<>(pageNo, pageSize); // Pagination object
IPage
<YucmsArticle> pageList = yucmsArticleService.page(page, queryWrapper); // Execute the paginated query
return Result.OK(pageList); // Return the result
}
This code enables the article list API to support conditional searches against both titles and body content while preserving pagination and improving hit accuracy.
Empty-state feedback completes the search experience
Accurate backend filtering alone is not enough. The frontend must also tell users that the system did search, but found no results. Otherwise, users may interpret a blank screen as a loading failure, or mistake a full list as a fallback default.
The handling in SearchResult.vue is concise. When total === 0 and keyword exists, it renders an empty-state block that clearly tells the user no articles matched the keyword.
<template>
<!-- No search results prompt -->
<div v-if="total === 0 && keyword" class="text-center py-12">
<div class="w-16 h-16 mx-auto mb-4 bg-slate-100 rounded-full flex items-center justify-center">
<i data-lucide="search" class="w-8 h-8 text-slate-400"></i>
</div>
<p class="text-slate-500">No articles found for this keyword</p>
</div>
</template>
This code outputs a visible empty state when no matching result exists, preventing users from misreading the system behavior.
Copy-protection modal optimization directly affects brand conversion efficiency
The original article mentions that a prompt modal appears when users copy article content. This pattern is often used for copyright messaging, public account promotion, or content protection. The issue is not whether the modal exists, but whether it feels restrained, trustworthy, and recognizable.
This optimization includes two improvements. First, the QR code size is reduced from 112px to 96px, which lowers visual pressure. Second, a real QR code image replaces the placeholder icon, reducing cognitive friction.
<div class="w-24 h-24 mx-auto bg-white border-2 border-slate-200 rounded-lg overflow-hidden">
<img src="/fintechren.jpg" alt="Scan to follow" class="w-full h-full object-cover" />
</div>
This code makes the QR code area in the copy prompt more componentized and authentic, improving conversion credibility.
Footer interaction enhancements turn static links into effective touchpoints
The “About Us” section in an enterprise portal footer is often wasted as a standard link. Converting it into a modal shortens the path to information delivery. Users can learn about the brand and scan the QR code without leaving the current page.
The implementation uses Vue 3 Teleport and Transition. Teleport mounts the modal under body, which avoids layering conflicts. Transition adds fade and scale animations, creating a more polished experience.
<button
@click="showAboutModal = true"
class="font-bold mb-4 text-amber-500 hover:text-amber-600 transition-colors cursor-pointer text-left"
>
About Us
</button>
<Teleport to="body">
<Transition name="modal">
<div
v-if="showAboutModal"
class="fixed inset-0 z-50 flex items-center justify-center p-4"
@click.self="showAboutModal = false"
>
<div class="absolute inset-0 bg-black/60 backdrop-blur-sm"></div>
<div class="relative bg-white rounded-2xl shadow-2xl w-full max-w-md overflow-hidden">
<div class="p-6">
<p class="text-slate-700 mb-6">Fintech.Ren focuses on sharing content in the fintech space.</p>
<div class="w-36 h-36 mx-auto bg-white border-2 border-slate-200 rounded-xl overflow-hidden shadow-lg">
<img src="/fintechren.jpg" alt="Fintech.Ren" class="w-full h-full object-cover" />
</div>
</div>
</div>
</div>
</Transition>
</Teleport>
This code upgrades the footer “About Us” entry into a modal dialog and unifies information display, overlay dismissal, and QR-based follow guidance.
Navigation styling improvements increase information architecture visibility
Changing the navigation typography from text-sm to text-base and from font-medium to font-semibold may look like a minor style adjustment, but it actually strengthens the information priority of the primary navigation. Enterprise homepages especially depend on this to establish content hierarchy.
<a
href="#"
:class="[
'px-3 py-2 text-base font-semibold',
activeNavId === item.id
? 'text-bank-primary bg-slate-50'
: 'text-slate-700 hover:text-bank-primary'
]"
>
{{ item.name }}
</a>
This code improves the recognizability of first-level navigation and reinforces current-location awareness through active and hover states.
This refactor demonstrates a coordinated frontend-backend optimization path
From the outcome, this day of development did not introduce a complex architecture, but it closely matches the real pace of enterprise projects: first fix broken feedback loops and weak interactions along core user paths, then gradually improve overall completeness.
The gains can be summarized in four areas: search becomes accurate instead of loosely usable, empty-state feedback builds user trust, brand-oriented modals improve conversion entry quality, and stronger navigation clarifies the first-screen information architecture.
FAQ structured Q&A
1. Why not use a full-text search engine directly in the search API?
The current scenario still involves small- to medium-scale content queries, so implementing database like queries with QueryWrapper costs less and ships faster. If the article volume grows later, migrating to Elasticsearch would be more appropriate.
2. Why must the no-result prompt depend on the keyword condition?
Because when the keyword is empty, the UI should not display “no results.” Instead, it should prompt the user to enter a query first. This cleanly distinguishes between “not searched yet” and “searched with no match.”
3. Why use Teleport for the footer modal?
If a modal stays inside the original component tree, it can easily be affected by parent overflow, z-index, and positioning contexts. Mounting it to body with Teleport gives more stable overlay control and is better suited for global floating-layer scenarios.
AI Readability Summary
This article documents an iteration of an enterprise portal built with Spring Boot and Vue 3. It focuses on accurate search matching, no-result feedback, copy-protection modal optimization, a footer “About Us” modal, and navigation style upgrades. It extracts the core implementation approach, interaction benefits, and key code changes.