Initial commit
This commit is contained in:
1
miniprogram/pages/search/search.json
Normal file
1
miniprogram/pages/search/search.json
Normal file
@@ -0,0 +1 @@
|
||||
{ "navigationStyle": "custom", "usingComponents": { "post-card": "/components/post-card/post-card" } }
|
||||
73
miniprogram/pages/search/search.ts
Normal file
73
miniprogram/pages/search/search.ts
Normal file
@@ -0,0 +1,73 @@
|
||||
import { getAvatarGradient } from '../../utils/format'
|
||||
|
||||
Page({
|
||||
data: {
|
||||
statusBarHeight: 0,
|
||||
keyword: '',
|
||||
resultTab: 'posts' as 'posts' | 'users',
|
||||
postResults: [] as any[],
|
||||
userResults: [] as any[],
|
||||
hotTopics: [] as any[],
|
||||
loading: false,
|
||||
},
|
||||
|
||||
onLoad() {
|
||||
const info = wx.getSystemInfoSync()
|
||||
this.setData({ statusBarHeight: info.statusBarHeight })
|
||||
this.loadHotTopics()
|
||||
},
|
||||
|
||||
async loadHotTopics() {
|
||||
try {
|
||||
const res = await wx.cloud.callFunction({ name: 'getHotTopics', data: {} }) as any
|
||||
this.setData({ hotTopics: res.result?.data || [] })
|
||||
} catch {}
|
||||
},
|
||||
|
||||
onInput(e: WechatMiniprogram.CustomEvent) {
|
||||
this.setData({ keyword: e.detail.value })
|
||||
},
|
||||
|
||||
onClear() {
|
||||
this.setData({ keyword: '', postResults: [], userResults: [] })
|
||||
},
|
||||
|
||||
async onSearch() {
|
||||
const kw = this.data.keyword.trim()
|
||||
if (!kw) return
|
||||
this.setData({ loading: true })
|
||||
try {
|
||||
const [posts, users] = await Promise.all([
|
||||
wx.cloud.callFunction({ name: 'searchPosts', data: { keyword: kw } }) as any,
|
||||
wx.cloud.callFunction({ name: 'searchUsers', data: { keyword: kw } }) as any,
|
||||
])
|
||||
this.setData({
|
||||
postResults: posts.result?.data || [],
|
||||
userResults: (users.result?.data || []).map((u: any) => ({
|
||||
...u,
|
||||
gradient: getAvatarGradient(u._id),
|
||||
})),
|
||||
})
|
||||
} catch {
|
||||
wx.showToast({ title: '搜索失败', icon: 'none' })
|
||||
} finally {
|
||||
this.setData({ loading: false })
|
||||
}
|
||||
},
|
||||
|
||||
onTopicTap(e: WechatMiniprogram.CustomEvent) {
|
||||
const tag = e.currentTarget.dataset.tag as string
|
||||
this.setData({ keyword: tag })
|
||||
this.onSearch()
|
||||
},
|
||||
|
||||
onResultTab(e: WechatMiniprogram.CustomEvent) {
|
||||
this.setData({ resultTab: e.currentTarget.dataset.t as 'posts' | 'users' })
|
||||
},
|
||||
|
||||
onUserTap(e: WechatMiniprogram.CustomEvent) {
|
||||
wx.navigateTo({ url: `/pages/pet-detail/pet-detail?userId=${e.currentTarget.dataset.uid}` })
|
||||
},
|
||||
|
||||
onBack() { wx.navigateBack() },
|
||||
})
|
||||
74
miniprogram/pages/search/search.wxml
Normal file
74
miniprogram/pages/search/search.wxml
Normal file
@@ -0,0 +1,74 @@
|
||||
<view class="page">
|
||||
<view class="safe-top" style="height: {{statusBarHeight}}px"></view>
|
||||
<view class="search-bar">
|
||||
<view class="back" bindtap="onBack">‹</view>
|
||||
<view class="input-wrap">
|
||||
<text class="search-icon">🔍</text>
|
||||
<input
|
||||
class="search-input"
|
||||
value="{{keyword}}"
|
||||
bindinput="onInput"
|
||||
bindconfirm="onSearch"
|
||||
placeholder="搜索宠物、话题、用户..."
|
||||
focus="{{true}}"
|
||||
confirm-type="search"
|
||||
/>
|
||||
<view wx:if="{{keyword}}" class="clear" bindtap="onClear">×</view>
|
||||
</view>
|
||||
<view class="search-btn" bindtap="onSearch">搜索</view>
|
||||
</view>
|
||||
|
||||
<!-- 热门话题 -->
|
||||
<view wx:if="{{!keyword && !loading}}" class="hot-section">
|
||||
<text class="section-title">热门话题</text>
|
||||
<view class="hot-tags">
|
||||
<view
|
||||
wx:for="{{hotTopics}}"
|
||||
wx:key="index"
|
||||
class="hot-tag"
|
||||
bindtap="onTopicTap"
|
||||
data-tag="{{item.tag}}"
|
||||
>
|
||||
<text class="tag-rank">{{index + 1}}</text>
|
||||
<text class="tag-text">{{item.tag}}</text>
|
||||
<text class="tag-count">{{item.count}}篇</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 搜索结果 -->
|
||||
<scroll-view wx:if="{{keyword}}" scroll-y="true" class="results-scroll" enhanced="true" show-scrollbar="false">
|
||||
<view class="results-tabs">
|
||||
<view class="rtab {{resultTab === 'posts' ? 'rtab-on' : ''}}" bindtap="onResultTab" data-t="posts">帖子</view>
|
||||
<view class="rtab {{resultTab === 'users' ? 'rtab-on' : ''}}" bindtap="onResultTab" data-t="users">用户</view>
|
||||
</view>
|
||||
|
||||
<view wx:if="{{resultTab === 'posts'}}">
|
||||
<post-card wx:for="{{postResults}}" wx:key="_id" post="{{item}}" />
|
||||
<view wx:if="{{!loading && postResults.length === 0}}" class="empty">
|
||||
<text>没有找到相关帖子</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view wx:if="{{resultTab === 'users'}}">
|
||||
<view
|
||||
wx:for="{{userResults}}"
|
||||
wx:key="_id"
|
||||
class="user-result"
|
||||
bindtap="onUserTap"
|
||||
data-uid="{{item._id}}"
|
||||
>
|
||||
<view class="u-avatar" style="background: {{item.gradient}}">{{item.nickName[0]}}</view>
|
||||
<view class="u-info">
|
||||
<text class="u-name">{{item.nickName}}</text>
|
||||
<text class="u-bio">{{item.bio || '宠物爱好者'}}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view wx:if="{{!loading && userResults.length === 0}}" class="empty">
|
||||
<text>没有找到相关用户</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view style="height: 60rpx;"></view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
30
miniprogram/pages/search/search.wxss
Normal file
30
miniprogram/pages/search/search.wxss
Normal file
@@ -0,0 +1,30 @@
|
||||
.page { min-height: 100vh; background: linear-gradient(180deg, #fff8f2 0%, #f5f0ff 100%); }
|
||||
.search-bar { display: flex; align-items: center; gap: 14rpx; padding: 14rpx 28rpx; }
|
||||
.back { font-size: 60rpx; color: #272235; font-weight: 300; line-height: 1; }
|
||||
.input-wrap { flex: 1; display: flex; align-items: center; background: rgba(255,255,255,0.88); border: 1rpx solid rgba(255,255,255,0.72); border-radius: 999rpx; padding: 0 20rpx; height: 76rpx; gap: 10rpx; box-shadow: 0 8rpx 18rpx rgba(78,56,96,0.08); }
|
||||
.search-icon { font-size: 30rpx; }
|
||||
.search-input { flex: 1; font-size: 28rpx; color: #272235; }
|
||||
.clear { font-size: 36rpx; color: #9b8fa8; }
|
||||
.search-btn { font-size: 28rpx; font-weight: 800; color: #ff4f91; padding: 0 6rpx; }
|
||||
|
||||
.hot-section { padding: 20rpx 28rpx; }
|
||||
.section-title { display: block; font-size: 26rpx; font-weight: 900; color: #9b8fa8; margin-bottom: 20rpx; }
|
||||
.hot-tags { display: flex; flex-direction: column; gap: 0; background: rgba(255,255,255,0.88); border-radius: 36rpx; overflow: hidden; border: 1rpx solid rgba(255,255,255,0.72); box-shadow: 0 12rpx 26rpx rgba(78,56,96,0.08); }
|
||||
.hot-tag { display: flex; align-items: center; gap: 20rpx; padding: 22rpx 28rpx; border-bottom: 1rpx solid rgba(43,37,61,0.05); }
|
||||
.hot-tag:last-child { border-bottom: none; }
|
||||
.tag-rank { font-size: 30rpx; font-weight: 900; color: #ff4f91; width: 32rpx; text-align: center; }
|
||||
.hot-tag:nth-child(n+4) .tag-rank { color: #9b8fa8; }
|
||||
.tag-text { flex: 1; font-size: 28rpx; font-weight: 700; color: #272235; }
|
||||
.tag-count { font-size: 24rpx; color: #9b8fa8; }
|
||||
|
||||
.results-tabs { display: flex; padding: 0 28rpx 20rpx; gap: 8rpx; }
|
||||
.rtab { font-size: 28rpx; font-weight: 700; color: #9b8fa8; padding: 10rpx 20rpx; border-radius: 999rpx; }
|
||||
.rtab-on { color: #ff4f91; background: rgba(255,79,145,0.10); font-weight: 900; }
|
||||
|
||||
.user-result { display: flex; align-items: center; gap: 20rpx; padding: 20rpx 28rpx; background: rgba(255,255,255,0.80); border-bottom: 1rpx solid rgba(43,37,61,0.05); }
|
||||
.u-avatar { width: 88rpx; height: 88rpx; border-radius: 28rpx; display: flex; align-items: center; justify-content: center; font-size: 36rpx; font-weight: 800; color: rgba(39,34,53,0.72); flex-shrink: 0; }
|
||||
.u-name { display: block; font-size: 28rpx; font-weight: 800; color: #272235; }
|
||||
.u-bio { display: block; font-size: 24rpx; color: #9b8fa8; margin-top: 4rpx; }
|
||||
|
||||
.empty { text-align: center; font-size: 26rpx; color: #9b8fa8; padding: 80rpx; }
|
||||
.results-scroll { }
|
||||
Reference in New Issue
Block a user