更新关键词管理模块:调整关键词请求参数,优化关键词列表的获取逻辑,移除本地筛选功能,改为服务端搜索,提升代码可读性和用户体验。

This commit is contained in:
超级老白兔
2025-09-29 16:38:36 +08:00
parent f5480bdc58
commit 713956aa4f
4 changed files with 43 additions and 37 deletions

View File

@@ -65,17 +65,17 @@ const NavCommon: React.FC<NavCommonProps> = ({ title = "触客宝" }) => {
key: "userInfo",
label: (
<div style={{ fontWeight: "bold", color: "#188eee" }}>
{user.username}{user.account}
{user.account}
</div>
),
},
{
key: "profile",
icon: <UserSwitchOutlined style={{ fontSize: 16 }} />,
label: "个人资料",
key: "settings",
icon: <SettingOutlined style={{ fontSize: 16 }} />,
label: "全局配置",
onClick: () => {
console.log("个人资料点击");
// TODO: 跳转到个人资料页面
navigate("/pc/commonConfig");
},
},
{
@@ -120,14 +120,14 @@ const NavCommon: React.FC<NavCommonProps> = ({ title = "触客宝" }) => {
<BellOutlined style={{ fontSize: 20 }} />
</Badge>
</div>
<Button
{/* <Button
onClick={() => {
navigate("/pc/commonConfig");
}}
icon={<SettingOutlined />}
>
全局配置
</Button>
</Button> */}
<Dropdown
menu={{ items: userMenuItems }}
placement="bottomRight"

View File

@@ -136,7 +136,7 @@ export interface KeywordAddRequest {
level: number; // 优先级
replyType: number; // 回复类型:文本回复、模板回复
status: string;
materialId: number;
metailGroups: any[];
}
export interface KeywordUpdateRequest extends KeywordAddRequest {

View File

@@ -15,7 +15,6 @@ import {
} from "antd";
import {
SearchOutlined,
FilterOutlined,
FormOutlined,
DeleteOutlined,
} from "@ant-design/icons";
@@ -38,7 +37,7 @@ interface KeywordItem {
keywords: string;
status: number;
content: string;
materialId: string;
metailGroupsOptions: { title: string; id: number }[];
level: number;
}
@@ -56,6 +55,8 @@ const KeywordManagement = forwardRef<any, Record<string, never>>(
pageSize: 10,
total: 0,
});
// 已提交的搜索关键词(仅在点击搜索时更新,用于服务端查询)
const [keywordQuery, setKeywordQuery] = useState<string>("");
//匹配类型
const getMatchTypeText = (type: number) => {
@@ -102,15 +103,16 @@ const KeywordManagement = forwardRef<any, Record<string, never>>(
}
};
// 获取关键词列表
// 获取关键词列表(服务端搜索)
const fetchKeywords = async (params?: KeywordListParams) => {
try {
setLoading(true);
const requestParams = {
page: pagination.current.toString(),
limit: pagination.pageSize.toString(),
keyword: keywordQuery || undefined,
...params,
};
} as KeywordListParams;
const response = await getKeywordList(requestParams);
if (response) {
setKeywordsList(response.list || []);
@@ -175,20 +177,12 @@ const KeywordManagement = forwardRef<any, Record<string, never>>(
}
};
// 搜索和筛选功能
const filteredKeywords = keywordsList.filter(item => {
if (!searchValue) return true;
return (
item.title.toLowerCase().includes(searchValue.toLowerCase()) ||
item.keywords.toLowerCase().includes(searchValue.toLowerCase()) ||
item.content.toLowerCase().includes(searchValue.toLowerCase())
);
});
// 移除本地筛选,改为服务端搜索,列表直接使用 keywordsList
// 搜索处理函数
const handleSearch = (value: string) => {
setKeywordQuery(value || "");
setPagination(prev => ({ ...prev, current: 1 }));
fetchKeywords({ keyword: value });
};
// 分页处理函数
@@ -200,10 +194,11 @@ const KeywordManagement = forwardRef<any, Record<string, never>>(
}));
};
// 组件挂载和分页变化时获取数据
// 初始化与依赖变化时获取数据(依赖分页与搜索关键字)
useEffect(() => {
fetchKeywords();
}, [pagination.current, pagination.pageSize]);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [pagination.current, pagination.pageSize, keywordQuery]);
return (
<div className={styles.keywordContent}>
@@ -216,16 +211,15 @@ const KeywordManagement = forwardRef<any, Record<string, never>>(
style={{ width: 300 }}
prefix={<SearchOutlined />}
/>
{/* <Button icon={<FilterOutlined />}>筛选</Button> */}
</div>
<div className={styles.keywordList}>
{loading ? (
<div className={styles.loading}>...</div>
) : filteredKeywords.length === 0 ? (
) : keywordsList.length === 0 ? (
<div className={styles.empty}></div>
) : (
filteredKeywords.map(item => (
keywordsList.map(item => (
<div key={item.id} className={styles.keywordItem}>
<div className={styles.itemContent}>
<div className={styles.leftSection}>
@@ -234,7 +228,18 @@ const KeywordManagement = forwardRef<any, Record<string, never>>(
<Tag color="default">{getMatchTypeText(item.type)}</Tag>
<Tag color="default">{getPriorityText(item.level)}</Tag>
</div>
<div className={styles.description}>{item.content}</div>
{item.content.length ? (
<div className={styles.description}>{item.content}</div>
) : (
<div className={styles.description}>
{item.metailGroupsOptions.map(v => (
<Tag color="success" key={v.id}>
{v.title}
</Tag>
))}
</div>
)}
<div className={styles.footer}>
<Tag color={getReplyTypeColor(item.replyType)}>
{getReplyTypeText(item.replyType)}

View File

@@ -28,6 +28,8 @@ const KeywordModal: React.FC<KeywordModalProps> = ({
}) => {
const [form] = Form.useForm();
const [loading, setLoading] = useState(false);
const title = mode === "add" ? "添加关键词回复" : "编辑关键词回复";
const [selectedOptions, setSelectedOptions] = useState<any[]>([]);
// 获取关键词详情
const fetchKeywordDetails = useCallback(
@@ -44,8 +46,9 @@ const KeywordModal: React.FC<KeywordModalProps> = ({
level: keyword.level,
replyType: keyword.replyType,
status: keyword.status,
materialId: keyword.materialId,
metailGroups: keyword.metailGroups,
});
setSelectedOptions(keyword.metailGroupsOptions);
}
} catch (error) {
console.error("获取关键词详情失败:", error);
@@ -82,7 +85,7 @@ const KeywordModal: React.FC<KeywordModalProps> = ({
level: values.level,
replyType: values.replyType,
status: values.status || "1",
materialId: values.materialId,
metailGroups: values.metailGroups,
};
const response = await addKeyword(data);
@@ -104,7 +107,7 @@ const KeywordModal: React.FC<KeywordModalProps> = ({
level: values.level,
replyType: values.replyType,
status: values.status,
materialId: values.materialId,
metailGroups: values.metailGroups,
};
const response = await updateKeyword(data);
@@ -131,17 +134,15 @@ const KeywordModal: React.FC<KeywordModalProps> = ({
onCancel();
};
const title = mode === "add" ? "添加关键词回复" : "编辑关键词回复";
const [selectedOptions, setSelectedOptions] = useState<any[]>([]);
const handSelectMaterial = (options: any[]) => {
if (options.length === 0) {
form.setFieldsValue({
materialId: null,
metailGroups: [],
});
} else {
// 在单选模式下只取第一个选项的ID
form.setFieldsValue({
materialId: options[0].id,
metailGroups: options.map(v => v.id),
});
}
setSelectedOptions(options);
@@ -222,7 +223,7 @@ const KeywordModal: React.FC<KeywordModalProps> = ({
</Form.Item>
) : (
<Form.Item
name="materialId"
name="metailGroups"
label="回复内容"
rules={[{ required: true, message: "请输入回复内容" }]}
>