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(昵称/品类命中、无匹配空数组、无关键词向后兼容)
这个提交包含在:
@@ -742,11 +742,11 @@ export class MysqlRepository {
|
||||
return null;
|
||||
}
|
||||
|
||||
async getCompanions(): Promise<any[]> {
|
||||
async getCompanions(keyword?: string): Promise<any[]> {
|
||||
try {
|
||||
await pool.query("ALTER TABLE companions ADD COLUMN reject_reason VARCHAR(255) DEFAULT '' AFTER audit_status");
|
||||
} catch (_) {}
|
||||
const [rows]: any = await pool.query(`
|
||||
let sql = `
|
||||
SELECT
|
||||
id, user_id as userId, name, avatar, gender, age, track, rank_name as \`rank\`,
|
||||
hourly_rate as hourlyRate, voice_duration as voiceDuration,
|
||||
@@ -754,8 +754,17 @@ export class MysqlRepository {
|
||||
status, audit_status as auditStatus, COALESCE(reject_reason, '') as rejectReason,
|
||||
id_card_masked as idCardMasked, tags, apply_time as applyTime
|
||||
FROM companions
|
||||
ORDER BY id ASC
|
||||
`);
|
||||
`;
|
||||
const params: any[] = [];
|
||||
const kw = String(keyword == null ? '' : keyword).trim();
|
||||
if (kw) {
|
||||
// 关键词搜索:昵称 / 陪玩品类 / 段位 / 技能标签(参数化,避免注入)
|
||||
sql += ' WHERE name LIKE ? OR track LIKE ? OR rank_name LIKE ? OR tags LIKE ? OR CAST(id AS CHAR) = ?';
|
||||
const like = `%${kw}%`;
|
||||
params.push(like, like, like, like, kw);
|
||||
}
|
||||
sql += ' ORDER BY id ASC';
|
||||
const [rows]: any = await pool.query(sql, params);
|
||||
return rows.map((r: any) => {
|
||||
let tagsArr = [];
|
||||
try {
|
||||
|
||||
@@ -1073,7 +1073,8 @@ app.get('/api/users/:id/my-activities', async (req: Request, res: Response) => {
|
||||
// 4. 陪玩与大神管理接口 (落盘 MySQL)
|
||||
app.get('/api/companions', async (req: Request, res: Response) => {
|
||||
try {
|
||||
const companions = await repo.getCompanions();
|
||||
const keyword = req.query.keyword ? String(req.query.keyword).slice(0, 40) : undefined;
|
||||
const companions = await repo.getCompanions(keyword);
|
||||
// 管理端可见全量(含待审核/已驳回及内部备注);公开目录仅展示已通过审核的大神,并剥离内部审核备注
|
||||
if (isVerifiedAdminRequest(req)) {
|
||||
return res.json({ code: 20000, data: companions });
|
||||
|
||||
在新工单中引用
屏蔽一个用户