Dify 1.8.1 前端对话页面二次开发指南(搜索 + 时间分类)
对话页面功能增强,新增核心功能,同步解决开发中常见问题。
·
一、开发概述
适用场景
对话页面功能增强,新增对话搜索(模糊匹配) 、时间分组展示核心功能,同步解决开发中常见问题。
技术依赖
- 组件复用:系统内置
Input组件(保证样式统一) - 核心文件:
web/src/components/sidebar/ConversationList.tsx(搜索框)、web/src/components/sidebar/ConversationGroup.tsx(时间分组)
二、核心功能实现(可直接复制使用)
1. 对话搜索框(ConversationList.tsx)
tsx
import Input from '@/components/ui/input/Input';
import { useState } from 'react';
const ConversationList = ({ conversations }) => {
// 搜索关键词状态
const [searchKeyword, setSearchKeyword] = useState('');
// 实时筛选:匹配对话名称/摘要(支持模糊搜索)
const filteredConversations = conversations.filter(conversation =>
conversation.name.includes(searchKeyword) ||
(conversation.summary && conversation.summary.includes(searchKeyword))
);
return (
<div className="max-w-[280px] flex-1">
{/* 搜索框组件(优化垂直居中样式) */}
<Input
type="text"
className="!py-2 mb-4 line-height-1"
showLeftIcon={true}
showClearIcon={true}
placeholder="搜索对话"
value={searchKeyword}
onChange={e => setSearchKeyword(e.target.value)} // 实时更新关键词
onClear={() => setSearchKeyword('')} // 清空搜索
wrapperClassName="w-full"
/>
{/* 渲染筛选后的对话列表 */}
<ConversationGroup filteredConversations={filteredConversations} />
</div>
);
};
export default ConversationList;
2. 时间分类功能(ConversationGroup.tsx)
tsx
const ConversationGroup = ({ filteredConversations }) => {
// 时间分组工具函数:按「今天/昨天/最近7天/更早」分类
const getTimeGroup = (time: string) => {
const conversationTime = new Date(time);
const now = new Date();
const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
const yesterday = new Date(today);
yesterday.setDate(yesterday.getDate() - 1);
const recent7Days = new Date(today);
recent7Days.setDate(recent7Days.getDate() - 7);
if (conversationTime >= today) return 'today';
if (conversationTime >= yesterday) return 'yesterday';
if (conversationTime >= recent7Days) return 'recent7';
return 'earlier';
};
// 按时间分组处理(修复新对话无updated_at问题)
const groupedConversations = filteredConversations.reduce((groups, item) => {
const updatedAt = item.updated_at || Math.floor(Date.now() / 1000); // 兜底当前时间
const groupKey = getTimeGroup(new Date(updatedAt * 1000).toISOString());
groups[groupKey] = groups[groupKey] || [];
groups[groupKey].push(item);
return groups;
}, {} as Record<string, typeof filteredConversations>);
// 分组渲染(按时间倒序展示)
const groupOrder = ['today', 'yesterday', 'recent7', 'earlier'];
return (
<div>
{groupOrder.map(key => {
const conversations = groupedConversations[key];
if (!conversations?.length) return null;
return (
<div key={key} className="mb-4">
<h3 className="text-sm font-medium text-text-tertiary mb-2">
{key === 'today' ? '今天' :
key === 'yesterday' ? '昨天' :
key === 'recent7' ? '最近7天' : '更早'}
</h3>
{conversations.map(conversation => (
<ConversationItem key={conversation.id} conversation={conversation} />
))}
</div>
);
})}
</div>
);
};
export default ConversationGroup;
三、常见问题解决方案(问题 - 原因 - 解决)
| 问题描述 | 原因分析 | 解决方案 | ||
|---|---|---|---|---|
| 搜索图标贴底,不垂直居中 | Tailwind 类名错误 + 行高偏移 | 补充 line-height-1,删除拆分的 -translate-y 类名,统一样式控制 |
||
| 新对话默认显示在「更早」 | 新对话 updated_at 为 undefined,分组误判 |
给 updated_at 加兜底:`item.updated_at |
Math.floor(Date.now() / 1000)` | |
| 搜索无实时筛选效果 | 未绑定 onChange 或筛选逻辑不全 |
绑定 onChange 实时更新 searchKeyword,筛选条件包含 name 和 summary |
||
| 收藏状态刷新后丢失 | 仅本地维护状态,未从接口获取初始值 | 组件挂载时调用 /api/conversations/${id}/status,用 is_collected 初始化 |
||
| 反馈提交后数据库无数据 | 未关联 message_feedbacks 表,接口未写入 |
后端接口添加表插入逻辑,确保 message_id、rating 等字段存储 |
四、功能验证清单
- 搜索验证:输入关键词,对话列表实时筛选,结果匹配名称 / 摘要;清空关键词后显示全部
- 分类验证:新创建对话显示在「今天」分组,历史对话按时间正确归类(昨天 / 最近 7 天 / 更早)
- 样式验证:搜索图标垂直居中,分组标题样式统一,无布局错乱
- 边界验证:无
summary的对话仅匹配名称,无updated_at的新对话正常归类
欢迎评论私信讨论Dify相关的问题,需要源码私我
更多推荐
所有评论(0)