diff --git a/client/lib/widgets/searchable_option_field.dart b/client/lib/widgets/searchable_option_field.dart index 977491e..4b5ccc5 100644 --- a/client/lib/widgets/searchable_option_field.dart +++ b/client/lib/widgets/searchable_option_field.dart @@ -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)),