|
|
@@ -1,4 +1,4 @@
|
|
|
-import React, { useState, useMemo, useCallback } from 'react';
|
|
|
+import React, { useState, useMemo, useCallback, useRef } from 'react';
|
|
|
import { useQuery } from '@tanstack/react-query';
|
|
|
import { format } from 'date-fns';
|
|
|
import { Plus, Search, Edit, Trash2, Filter, X } from 'lucide-react';
|
|
|
@@ -57,6 +57,9 @@ export const UserManagement = () => {
|
|
|
|
|
|
const [isCreateForm, setIsCreateForm] = useState(true);
|
|
|
|
|
|
+ // 输入法输入状态 - 使用 ref 确保同步更新
|
|
|
+ const isComposingRef = useRef(false);
|
|
|
+
|
|
|
const createForm = useForm<CreateUserFormData>({
|
|
|
resolver: zodResolver(createUserFormSchema),
|
|
|
defaultValues: {
|
|
|
@@ -136,7 +139,10 @@ export const UserManagement = () => {
|
|
|
const handleSearchChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
|
|
const keyword = e.target.value;
|
|
|
setSearchParams(prev => ({ ...prev, keyword }));
|
|
|
- debouncedSearch(keyword);
|
|
|
+ // 只在非输入法状态下触发防抖更新(使用 ref 确保读取最新值)
|
|
|
+ if (!isComposingRef.current) {
|
|
|
+ debouncedSearch(keyword);
|
|
|
+ }
|
|
|
};
|
|
|
|
|
|
// 处理搜索表单提交
|
|
|
@@ -320,6 +326,12 @@ export const UserManagement = () => {
|
|
|
placeholder="搜索用户名、昵称或邮箱..."
|
|
|
value={searchParams.keyword || ''}
|
|
|
onChange={handleSearchChange}
|
|
|
+ onCompositionStart={() => { isComposingRef.current = true }}
|
|
|
+ onCompositionEnd={(e) => {
|
|
|
+ isComposingRef.current = false;
|
|
|
+ // 输入法结束后,使用最终输入的值触发搜索
|
|
|
+ debouncedSearch(e.currentTarget.value);
|
|
|
+ }}
|
|
|
className="pl-8"
|
|
|
/>
|
|
|
</div>
|
|
|
@@ -421,12 +433,6 @@ export const UserManagement = () => {
|
|
|
roleIds: filters.roleIds.filter(id => id !== roleId)
|
|
|
})}
|
|
|
/>
|
|
|
- <X
|
|
|
- className="h-3 w-3 cursor-pointer pointer-events-auto"
|
|
|
- onClick={() => handleFilterChange({
|
|
|
- roleIds: filters.roleIds.filter(id => id !== roleId)
|
|
|
- })}
|
|
|
- />
|
|
|
</Badge>
|
|
|
))}
|
|
|
</div>
|
|
|
@@ -487,27 +493,22 @@ export const UserManagement = () => {
|
|
|
</Badge>
|
|
|
)}
|
|
|
{filters.roleIds.map(roleId => (
|
|
|
- <Badge
|
|
|
- key={roleId}
|
|
|
- variant="secondary"
|
|
|
+ <Badge
|
|
|
+ key={roleId}
|
|
|
+ variant="secondary"
|
|
|
className="flex items-center gap-1 overflow-visible cursor-pointer hover:opacity-80"
|
|
|
onClick={() => handleFilterChange({
|
|
|
roleIds: filters.roleIds.filter(id => id !== roleId)
|
|
|
})}
|
|
|
>
|
|
|
角色: {roleId === 1 ? '管理员' : '普通用户'}
|
|
|
- <X
|
|
|
- className="h-3 w-3 cursor-pointer pointer-events-auto"
|
|
|
- onClick={() => handleFilterChange({
|
|
|
- roleIds: filters.roleIds.filter(id => id !== roleId)
|
|
|
- })}
|
|
|
- />
|
|
|
<X
|
|
|
className="h-3 w-3 cursor-pointer pointer-events-auto"
|
|
|
onClick={() => handleFilterChange({
|
|
|
roleIds: filters.roleIds.filter(id => id !== roleId)
|
|
|
})}
|
|
|
/>
|
|
|
+ </Badge>
|
|
|
))}
|
|
|
{filters.createdAt && (
|
|
|
<Badge variant="secondary" className="flex items-center gap-1 overflow-visible">
|