chore: solidify guide P1 snapshot
This commit is contained in:
@@ -1,61 +1,103 @@
|
||||
<template>
|
||||
<GuideMapShell
|
||||
:search-text="searchKeyword || '搜索设施、展厅、入口'"
|
||||
floor-top="164px"
|
||||
@search-tap="handleSearchTap"
|
||||
@mode-change="handleModeChange"
|
||||
@floor-change="handleFloorChange"
|
||||
<GuidePageFrame
|
||||
active-tab="guide"
|
||||
variant="overlay"
|
||||
show-back
|
||||
:show-cancel="isSearchEditing"
|
||||
@tab-change="handleTopTabChange"
|
||||
@back="handlePageBack"
|
||||
@cancel="handleSearchCancel"
|
||||
>
|
||||
<template #overlay>
|
||||
<view class="filter-row">
|
||||
<GuideMapShell
|
||||
:search-text="searchKeyword || '搜索设施、展厅、入口'"
|
||||
search-top="60px"
|
||||
mode-top="104px"
|
||||
floor-top="208px"
|
||||
@search-tap="handleSearchTap"
|
||||
@mode-change="handleModeChange"
|
||||
@floor-change="handleFloorChange"
|
||||
>
|
||||
<template #overlay>
|
||||
<view
|
||||
v-for="filter in filters"
|
||||
:key="filter.id"
|
||||
class="filter-chip"
|
||||
:class="[{ active: currentFilter === filter.id }, `filter-${filter.id}`]"
|
||||
@tap="handleFilterChange(filter.id)"
|
||||
v-if="isSearchEditing"
|
||||
class="search-edit-row"
|
||||
@tap.stop=""
|
||||
>
|
||||
<text class="filter-text">{{ filter.label }}</text>
|
||||
<view class="search-edit-box">
|
||||
<input
|
||||
class="search-edit-input"
|
||||
type="text"
|
||||
confirm-type="search"
|
||||
:focus="searchInputFocused"
|
||||
:placeholder="searchPlaceholder"
|
||||
:value="searchDraftKeyword"
|
||||
@input="handleSearchInput"
|
||||
@confirm="handleSearchConfirm"
|
||||
/>
|
||||
<view
|
||||
v-if="searchDraftKeyword"
|
||||
class="search-clear-btn"
|
||||
@tap.stop="handleSearchClear"
|
||||
>
|
||||
<text class="search-clear-text">×</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="search-confirm-btn" @tap="handleSearchConfirm">
|
||||
<text class="search-confirm-text">搜索</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<view class="results-sheet">
|
||||
<view class="sheet-header">
|
||||
<text class="sheet-title">{{ resultTitle }}</text>
|
||||
<text class="sort-label">按距离排序</text>
|
||||
</view>
|
||||
|
||||
<view class="result-list">
|
||||
<view
|
||||
v-for="item in visibleFacilities"
|
||||
:key="item.id"
|
||||
class="result-card"
|
||||
@tap="handleFacilityClick(item)"
|
||||
>
|
||||
<view class="facility-mark">
|
||||
<text class="facility-mark-text">卫</text>
|
||||
</view>
|
||||
<view class="facility-info">
|
||||
<text class="facility-name">{{ item.name }}</text>
|
||||
<text class="facility-meta">{{ item.meta }}</text>
|
||||
</view>
|
||||
<view class="filter-row">
|
||||
<view
|
||||
class="result-action"
|
||||
:class="{ secondary: item.action === '查看' }"
|
||||
@tap.stop="handleResultAction(item)"
|
||||
v-for="filter in filters"
|
||||
:key="filter.id"
|
||||
class="filter-chip"
|
||||
:class="[{ active: currentFilter === filter.id }, `filter-${filter.id}`]"
|
||||
@tap="handleFilterChange(filter.id)"
|
||||
>
|
||||
<text class="result-action-text">{{ item.action }}</text>
|
||||
<text class="filter-text">{{ filter.label }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<view class="results-sheet">
|
||||
<view class="sheet-header">
|
||||
<text class="sheet-title">{{ resultTitle }}</text>
|
||||
<text class="sort-label">默认展示</text>
|
||||
</view>
|
||||
|
||||
<view class="result-list">
|
||||
<view
|
||||
v-for="item in visibleFacilities"
|
||||
:key="item.id"
|
||||
class="result-card"
|
||||
@tap="handleFacilityClick(item)"
|
||||
>
|
||||
<view class="facility-mark">
|
||||
<text class="facility-mark-text">卫</text>
|
||||
</view>
|
||||
<view class="facility-info">
|
||||
<text class="facility-name">{{ item.name }}</text>
|
||||
<text class="facility-meta">{{ item.meta }}</text>
|
||||
</view>
|
||||
<view
|
||||
class="result-action"
|
||||
:class="{ secondary: item.action === '查看' }"
|
||||
@tap.stop="handleResultAction(item)"
|
||||
>
|
||||
<text class="result-action-text">{{ item.action }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</GuideMapShell>
|
||||
</GuideMapShell>
|
||||
</GuidePageFrame>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, ref } from 'vue'
|
||||
import { computed, nextTick, ref } from 'vue'
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
import GuidePageFrame from '@/components/navigation/GuidePageFrame.vue'
|
||||
import GuideMapShell from '@/components/navigation/GuideMapShell.vue'
|
||||
import {
|
||||
formatNavFloorLabel,
|
||||
@@ -63,9 +105,13 @@ import {
|
||||
searchCleanNavPois,
|
||||
type CleanNavPoi
|
||||
} from '@/services/navAssets'
|
||||
import {
|
||||
navigateToGuideTopTab,
|
||||
type GuideTopTab
|
||||
} from '@/utils/guideTopTabs'
|
||||
|
||||
interface FilterItem {
|
||||
id: 'all' | 'accessible' | 'floor' | 'nearest'
|
||||
id: 'all' | 'accessible' | 'floor'
|
||||
label: string
|
||||
}
|
||||
|
||||
@@ -79,14 +125,17 @@ interface FacilityResult {
|
||||
}
|
||||
|
||||
const searchKeyword = ref('卫生间')
|
||||
const searchDraftKeyword = ref('')
|
||||
const currentFilter = ref<FilterItem['id']>('all')
|
||||
const isLoading = ref(false)
|
||||
const isSearchEditing = ref(false)
|
||||
const searchInputFocused = ref(false)
|
||||
const searchPlaceholder = '搜索设施、展厅、入口'
|
||||
|
||||
const filters: FilterItem[] = [
|
||||
{ id: 'all', label: '全部' },
|
||||
{ id: 'accessible', label: '无障碍' },
|
||||
{ id: 'floor', label: '本楼层' },
|
||||
{ id: 'nearest', label: '最近' }
|
||||
{ id: 'floor', label: '1F 点位' }
|
||||
]
|
||||
|
||||
const facilities = ref<FacilityResult[]>([])
|
||||
@@ -141,11 +190,46 @@ onLoad((options: any) => {
|
||||
if (options.keyword) {
|
||||
searchKeyword.value = decodeURIComponent(options.keyword)
|
||||
}
|
||||
searchDraftKeyword.value = searchKeyword.value
|
||||
void loadFacilityResults()
|
||||
})
|
||||
|
||||
const handleSearchTap = () => {
|
||||
console.log('保持搜索结果页')
|
||||
const handleSearchTap = async () => {
|
||||
searchDraftKeyword.value = searchKeyword.value
|
||||
isSearchEditing.value = true
|
||||
searchInputFocused.value = false
|
||||
await nextTick()
|
||||
searchInputFocused.value = true
|
||||
}
|
||||
|
||||
const handleSearchInput = (event: any) => {
|
||||
searchDraftKeyword.value = event.detail.value
|
||||
}
|
||||
|
||||
const handleSearchClear = async () => {
|
||||
searchDraftKeyword.value = ''
|
||||
searchInputFocused.value = false
|
||||
await nextTick()
|
||||
searchInputFocused.value = true
|
||||
}
|
||||
|
||||
const handleSearchCancel = () => {
|
||||
searchDraftKeyword.value = searchKeyword.value
|
||||
isSearchEditing.value = false
|
||||
searchInputFocused.value = false
|
||||
}
|
||||
|
||||
const handleSearchConfirm = async (event?: any) => {
|
||||
const confirmedKeyword = typeof event?.detail?.value === 'string'
|
||||
? event.detail.value
|
||||
: searchDraftKeyword.value
|
||||
|
||||
searchKeyword.value = confirmedKeyword.trim()
|
||||
searchDraftKeyword.value = searchKeyword.value
|
||||
currentFilter.value = 'all'
|
||||
isSearchEditing.value = false
|
||||
searchInputFocused.value = false
|
||||
await loadFacilityResults()
|
||||
}
|
||||
|
||||
const handleFilterChange = (filterId: FilterItem['id']) => {
|
||||
@@ -160,7 +244,7 @@ const handleFacilityClick = (facility: FacilityResult) => {
|
||||
|
||||
const handleResultAction = (facility: FacilityResult) => {
|
||||
uni.navigateTo({
|
||||
url: `/pages/route/detail?facilityId=${facility.id}&target=${encodeURIComponent(facility.name)}&state=planning`
|
||||
url: `/pages/route/detail?facilityId=${facility.id}&target=${encodeURIComponent(facility.name)}&state=preview`
|
||||
})
|
||||
}
|
||||
|
||||
@@ -172,12 +256,101 @@ const handleFloorChange = (floor: string) => {
|
||||
console.log('搜索页切换楼层:', floor)
|
||||
}
|
||||
|
||||
const handleTopTabChange = (tab: GuideTopTab) => {
|
||||
navigateToGuideTopTab(tab)
|
||||
}
|
||||
|
||||
const handlePageBack = () => {
|
||||
uni.navigateBack({
|
||||
delta: 1,
|
||||
fail: () => {
|
||||
uni.reLaunch({
|
||||
url: '/pages/index/index'
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.search-edit-row {
|
||||
position: absolute;
|
||||
top: 60px;
|
||||
left: 16px;
|
||||
right: 16px;
|
||||
height: 36px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
z-index: 48;
|
||||
}
|
||||
|
||||
.search-edit-box {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
height: 36px;
|
||||
padding: 0 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
box-sizing: border-box;
|
||||
background: #ffffff;
|
||||
border: 1px solid rgba(224, 223, 0, 0.55);
|
||||
border-radius: 6px;
|
||||
box-shadow: 0 0 0 2px rgba(224, 223, 0, 0.16);
|
||||
}
|
||||
|
||||
.search-edit-input {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
font-size: 14px;
|
||||
line-height: 19px;
|
||||
color: #1f2329;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.search-clear-btn {
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
margin-left: 6px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
background: #8b8b84;
|
||||
border-radius: 11px;
|
||||
}
|
||||
|
||||
.search-clear-text {
|
||||
font-size: 16px;
|
||||
line-height: 18px;
|
||||
font-weight: 500;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.search-confirm-btn {
|
||||
width: 52px;
|
||||
height: 36px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
box-sizing: border-box;
|
||||
background: #000000;
|
||||
border: 1px solid #000000;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.search-confirm-text {
|
||||
font-size: 14px;
|
||||
line-height: 19px;
|
||||
font-weight: 500;
|
||||
color: var(--museum-accent);
|
||||
}
|
||||
|
||||
.filter-row {
|
||||
position: absolute;
|
||||
top: 102px;
|
||||
top: 146px;
|
||||
left: 23px;
|
||||
right: 16px;
|
||||
display: flex;
|
||||
@@ -210,10 +383,6 @@ const handleFloorChange = (floor: string) => {
|
||||
width: 82px;
|
||||
}
|
||||
|
||||
.filter-nearest {
|
||||
width: 74px;
|
||||
}
|
||||
|
||||
.filter-text {
|
||||
font-size: 12px;
|
||||
line-height: 16px;
|
||||
|
||||
Reference in New Issue
Block a user