feat(search): 大神关键词搜索走服务端(昵称/品类/段位/标签)
- 仓储 getCompanions(keyword?):参数化 LIKE 搜索 name/track/rank_name/tags 及 id 精确匹配 - 接口 /api/companions 支持 ?keyword=(长度截断 40) - 小程序 api.js getCompanions(keyword) 带 encodeURIComponent;首页监听 searchKeyword 防抖 350ms 走服务端搜索,搜索态以服务端结果为准(含空结果不展示陈旧数据) - 回归 95 套件/668 用例全绿;冒烟 4/4(昵称/品类命中、无匹配空数组、无关键词向后兼容)
这个提交包含在:
@@ -191,10 +191,12 @@ export async function getMyActivities(userId) {
|
||||
/**
|
||||
* 获取同城大神列表
|
||||
*/
|
||||
export async function getCompanions() {
|
||||
export async function getCompanions(keyword) {
|
||||
try {
|
||||
const list = await http.get('/companions');
|
||||
if (Array.isArray(list) && list.length > 0) {
|
||||
const kw = String(keyword == null ? '' : keyword).trim();
|
||||
const query = kw ? `?keyword=${encodeURIComponent(kw)}` : '';
|
||||
const list = await http.get(`/companions${query}`);
|
||||
if (Array.isArray(list)) {
|
||||
return list
|
||||
.filter((c) => !c.auditStatus || c.auditStatus === '已通过')
|
||||
.map((c) => ({
|
||||
|
||||
@@ -266,7 +266,7 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, onMounted, onUnmounted } from 'vue';
|
||||
import { ref, computed, watch, onMounted, onUnmounted } from 'vue';
|
||||
import { onLoad, onShow } from '@dcloudio/uni-app';
|
||||
import AppTabBar from '@/components/CustomTabBar.vue';
|
||||
import SkeletonScreen from '@/components/SkeletonScreen.vue';
|
||||
@@ -352,17 +352,32 @@ const loadInitialData = async () => {
|
||||
}
|
||||
};
|
||||
|
||||
const fetchLiveCompanions = async () => {
|
||||
const fetchLiveCompanions = async (keyword = '') => {
|
||||
try {
|
||||
const list = await getCompanions();
|
||||
if (Array.isArray(list) && list.length > 0) {
|
||||
experts.value = list;
|
||||
const kw = String(keyword || '').trim();
|
||||
const list = await getCompanions(kw);
|
||||
if (Array.isArray(list)) {
|
||||
if (kw) {
|
||||
// 服务端搜索:以服务端结果为准(含空结果),避免仅过滤已加载的一页数据
|
||||
experts.value = list;
|
||||
} else if (list.length > 0) {
|
||||
experts.value = list;
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
console.warn('[Index] 获取大神数据失败:', err);
|
||||
}
|
||||
};
|
||||
|
||||
// 关键词变化时防抖走服务端搜索,覆盖超出当前加载范围的候选
|
||||
let searchTimer = null;
|
||||
watch(searchKeyword, (val) => {
|
||||
if (searchTimer) clearTimeout(searchTimer);
|
||||
searchTimer = setTimeout(() => {
|
||||
fetchLiveCompanions(String(val || '').trim());
|
||||
}, 350);
|
||||
});
|
||||
|
||||
const fetchLiveBanners = async () => {
|
||||
try {
|
||||
const list = await getBanners();
|
||||
|
||||
在新工单中引用
屏蔽一个用户