feat(search): 库存搜索支持拼音/首字母,按回车触发

- 新增 util.ToPinyin(),使用 go-pinyin 生成全拼和首字母
- Product model 新增 name_pinyin / name_initials 列(AutoMigrate)
- 启动时自动回填存量商品拼音
- Create / Update / FindOrCreate 写入时同步生成拼音
- 库存搜索 SQL 加入拼音/首字母 LIKE 条件
- 前端去掉 300ms 防抖,改为回车/点击搜索按钮触发

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
wangjia
2026-05-25 21:27:54 +08:00
parent 5f2248001d
commit e9a6543a8b
9 changed files with 105 additions and 23 deletions
@@ -1,4 +1,3 @@
import 'dart:async';
import 'package:dio/dio.dart';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
@@ -28,21 +27,16 @@ class InventoryListScreen extends ConsumerStatefulWidget {
class _InventoryListScreenState extends ConsumerState<InventoryListScreen> {
final _searchCtrl = TextEditingController();
Timer? _debounce;
Set<String> _filterWarehouse = {};
@override
void dispose() {
_searchCtrl.dispose();
_debounce?.cancel();
super.dispose();
}
void _onSearchChanged(String value) {
_debounce?.cancel();
_debounce = Timer(const Duration(milliseconds: 300), () {
ref.read(inventoryListProvider.notifier).setKeyword(value);
});
void _triggerSearch() {
ref.read(inventoryListProvider.notifier).setKeyword(_searchCtrl.text.trim());
}
Future<void> _editRemark(BuildContext context, Inventory item) async {
@@ -333,15 +327,20 @@ class _InventoryListScreenState extends ConsumerState<InventoryListScreen> {
),
const Spacer(),
SizedBox(
width: 200,
width: 220,
child: TextField(
controller: _searchCtrl,
decoration: const InputDecoration(
hintText: '搜索商品名/编码',
prefixIcon: Icon(Icons.search, size: 16),
hintStyle: TextStyle(fontSize: 13),
decoration: InputDecoration(
hintText: '名称/编码/拼音,回车搜索',
prefixIcon: const Icon(Icons.search, size: 16),
hintStyle: const TextStyle(fontSize: 12),
suffixIcon: IconButton(
icon: const Icon(Icons.search, size: 16),
tooltip: '搜索',
onPressed: _triggerSearch,
),
),
onChanged: _onSearchChanged,
onSubmitted: (_) => _triggerSearch(),
),
),
],