feat(client): 搜索选项支持拼音和首字母

使用 lpinyin 预计算每个选项的全拼和首字母,
输入 wl 可匹配「五粮液」,输入 maotai 可匹配「茅台」。

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
wangjia
2026-04-30 20:16:48 +08:00
parent cdf273da76
commit 6fc6b52631
@@ -1,11 +1,27 @@
import 'package:flutter/material.dart';
import 'package:lpinyin/lpinyin.dart';
import '../core/theme/app_theme.dart';
class OptionItem {
final int id;
final String name;
final String? code;
const OptionItem({required this.id, required this.name, this.code});
// 拼音索引,构造时预计算
late final String _fullPinyin;
late final String _initials;
OptionItem({required this.id, required this.name, this.code}) {
_fullPinyin = PinyinHelper.getPinyinE(name, separator: '', defPinyin: '').toLowerCase();
_initials = PinyinHelper.getShortPinyin(name).toLowerCase();
}
bool matches(String kw) {
final k = kw.toLowerCase();
return name.toLowerCase().contains(k) ||
(_fullPinyin.isNotEmpty && _fullPinyin.contains(k)) ||
(_initials.isNotEmpty && _initials.contains(k)) ||
(code?.toLowerCase().contains(k) ?? false);
}
}
/// 点击后弹出搜索对话框的下拉选择框
@@ -112,9 +128,7 @@ class _SearchDialogState extends State<_SearchDialog> {
Widget build(BuildContext context) {
final filtered = _keyword.isEmpty
? widget.options
: widget.options.where((o) =>
o.name.toLowerCase().contains(_keyword.toLowerCase()) ||
(o.code?.toLowerCase().contains(_keyword.toLowerCase()) ?? false)).toList();
: widget.options.where((o) => o.matches(_keyword)).toList();
return AlertDialog(
title: Text(widget.title, style: const TextStyle(fontSize: 16)),