47 lines
2.5 KiB
Vue
47 lines
2.5 KiB
Vue
<template>
|
|
<view class="page-shell search-page">
|
|
<PageHeader title="查找家谱" />
|
|
<view class="search-panel">
|
|
<input v-model="keyword" class="search-input" placeholder="输入姓氏、谱名或地区" placeholder-class="placeholder" @confirm="search" />
|
|
<text class="search-button" @click="search">搜索</text>
|
|
</view>
|
|
<text class="search-tip">仅展示已开放申请加入的家谱。</text>
|
|
<view class="result-list">
|
|
<GenealogyCard v-for="item in results" :key="item.id" :genealogy="item" @select="openApply" />
|
|
<view v-if="searched && !results.length" class="empty-result"><text>暂未找到公开家谱</text><text>可联系家谱创建者开通公开申请</text></view>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { onMounted, ref } from 'vue'
|
|
import PageHeader from '@/components/PageHeader.vue'
|
|
import GenealogyCard from '@/components/GenealogyCard.vue'
|
|
import { appApi } from '@/utils/api.js'
|
|
|
|
const keyword = ref('')
|
|
const allResults = ref([])
|
|
const results = ref([])
|
|
const searched = ref(false)
|
|
|
|
onMounted(async () => { allResults.value = await appApi.getPublicGenealogies(); results.value = allResults.value })
|
|
const search = () => {
|
|
const value = keyword.value.trim()
|
|
results.value = value ? allResults.value.filter((item) => `${item.name}${item.surname}${item.location}`.includes(value)) : allResults.value
|
|
searched.value = true
|
|
}
|
|
const openApply = (genealogy) => uni.showModal({ title: '申请加入', content: `确认申请加入“${genealogy.name}”吗?`, success: async ({ confirm }) => { if (confirm) { await appApi.applyToJoin(genealogy.id, { message: '希望加入家谱并完善本人资料' }); uni.showToast({ title: '申请已提交,等待审核', icon: 'none' }) } } })
|
|
</script>
|
|
|
|
<style scoped lang="scss">
|
|
.search-page { padding-bottom: 36rpx; }
|
|
.search-panel { display: flex; align-items: center; gap: 18rpx; margin: 28rpx; padding: 0 22rpx; border: 1rpx solid $gold; background: #fffaf0; }
|
|
.search-input { flex: 1; height: 82rpx; color: $ink; font-size: 27rpx; }
|
|
.placeholder { color: #b6aa99; }
|
|
.search-button { color: $brand-red; font-size: 27rpx; font-weight: 700; }
|
|
.search-tip { display: block; margin: -8rpx 28rpx 22rpx; color: $ink-muted; font-size: 22rpx; }
|
|
.result-list { display: flex; flex-direction: column; gap: 18rpx; margin: 0 28rpx; }
|
|
.empty-result { display: flex; flex-direction: column; align-items: center; gap: 14rpx; padding: 90rpx 20rpx; color: $ink-muted; font-size: 26rpx; }
|
|
.empty-result text + text { color: #a69783; font-size: 22rpx; }
|
|
</style>
|