feat(client): 搜索选项支持拼音和首字母
使用 lpinyin 预计算每个选项的全拼和首字母, 输入 wl 可匹配「五粮液」,输入 maotai 可匹配「茅台」。 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,11 +1,27 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:lpinyin/lpinyin.dart';
|
||||||
import '../core/theme/app_theme.dart';
|
import '../core/theme/app_theme.dart';
|
||||||
|
|
||||||
class OptionItem {
|
class OptionItem {
|
||||||
final int id;
|
final int id;
|
||||||
final String name;
|
final String name;
|
||||||
final String? code;
|
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) {
|
Widget build(BuildContext context) {
|
||||||
final filtered = _keyword.isEmpty
|
final filtered = _keyword.isEmpty
|
||||||
? widget.options
|
? widget.options
|
||||||
: widget.options.where((o) =>
|
: widget.options.where((o) => o.matches(_keyword)).toList();
|
||||||
o.name.toLowerCase().contains(_keyword.toLowerCase()) ||
|
|
||||||
(o.code?.toLowerCase().contains(_keyword.toLowerCase()) ?? false)).toList();
|
|
||||||
|
|
||||||
return AlertDialog(
|
return AlertDialog(
|
||||||
title: Text(widget.title, style: const TextStyle(fontSize: 16)),
|
title: Text(widget.title, style: const TextStyle(fontSize: 16)),
|
||||||
|
|||||||
Reference in New Issue
Block a user