feat(lookup): 用户前缀查找放宽至单字符——中文姓氏单字搜索(全链路)

契约 minLength 2→1 + 服务端 bounds 1..64 + admin 两处/App 一处前端门槛
同步放宽;防抖测试基线更新('s' 与合并后 'sta' 共两条)。

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
浅念
2026-09-29 15:37:41 +08:00
parent b0a3515bf2
commit 53c25697a6
8 changed files with 34 additions and 19 deletions
@@ -175,7 +175,7 @@
async function searchUsers(prefix: string) {
query.value = prefix
options.value = []
if (prefix.trim().length < 2) return
if (prefix.trim().length < 1) return
searching.value = true
try {
const result = await fetchLookupUsers(prefix.trim())
@@ -112,7 +112,7 @@
async function searchUsers(prefix: string) {
query.value = prefix
options.value = []
if (prefix.trim().length < 2) return
if (prefix.trim().length < 1) return
searching.value = true
try {
const result = await fetchLookupUsers(prefix.trim())
@@ -410,7 +410,9 @@ class _AlbumInviteSheetState extends ConsumerState<AlbumInviteSheet> {
void _onSearchChanged(String text) {
_debounce?.cancel();
final query = text.trim();
if (query.length < 2) {
// 单字符即搜(2026-09-29 与服务端 1..64 bounds 对齐——中文姓氏单字);
// 空串清空结果。
if (query.isEmpty) {
setState(() {
_searching = false;
_results = null;
@@ -144,7 +144,7 @@ void main() {
expect(find.byIcon(Icons.person_add_outlined), findsOneWidget);
});
testWidgets('邀请搜索防抖:<2 字符不请求;连续输入合并为最后一次(300ms)',
testWidgets('邀请搜索防抖:单字符即请求;连续输入合并为最后一次(300ms)',
(tester) async {
final adapter = membersAdapter();
await pumpMembers(tester, clientOf(adapter));
@@ -152,15 +152,15 @@ void main() {
await openInviteSheet(tester);
final field = find.byType(TextField);
// 1 个字符:无请求。
// 单字符即发请求(2026-09-29 与服务端 1..64 bounds 对齐——中文姓氏单字)。
await tester.enterText(field, 's');
await tester.pump(const Duration(milliseconds: 400));
expect(
adapter.requests.where((r) => r.path == '/v1/admin/users'),
isEmpty,
isNotEmpty,
);
// 连续输入两次,防抖合并为最后一次。
// 连续输入两次,防抖合并为最后一次:'st' 不产生独立请求,只有 'sta'。
await tester.enterText(field, 'st');
await tester.pump(const Duration(milliseconds: 100));
await tester.enterText(field, 'sta');
@@ -169,8 +169,12 @@ void main() {
final lookupsRequests = adapter.requests
.where((r) => r.path == '/v1/admin/users')
.toList();
expect(lookupsRequests, hasLength(1));
expect(lookupsRequests.single.uri.queryParameters['accountPrefix'], 'sta');
// 前段 's' 一条 + 合并后的 'sta' 一条(单字符即搜后基线为 2)。
expect(lookupsRequests, hasLength(2));
expect(
lookupsRequests.map((r) => r.uri.queryParameters['accountPrefix']).toList(),
['s', 'sta'],
);
});
testWidgets('邀请流:搜索命中 → Add → POST userId 载荷 → 已添加态 + 列表刷新',