Skip to content

Commit 177fa41

Browse files
author
weilei
committed
feat(difychat): 新增可折叠侧边栏和时间分组功能
- 添加可折叠的侧边栏功能,支持本地存储折叠状态 - 引入时间分组工具函数,对会话列表按时间分组显示 - 优化消息处理逻辑,修复增量消息显示问题 - 添加键盘快捷键(Ctrl+K)支持新建对话 - 改进UI动画效果和响应式布局
1 parent 5aeec11 commit 177fa41

File tree

3 files changed

+490
-113
lines changed

3 files changed

+490
-113
lines changed

examples/src/utils/difyAdapter.js

Lines changed: 42 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -32,58 +32,55 @@ export function transformBlockingResponse(response) {
3232
};
3333
}
3434

35+
/**
36+
* 解析 SSE 流式数据块
37+
* @param {string} chunk - SSE 数据块
38+
* @returns {Object|null} 解析后的数据对象
39+
*/
3540
/**
3641
* 解析 SSE 流式数据块
3742
* @param {string} chunk - SSE 数据块
3843
* @returns {Object|null} 解析后的数据对象
3944
*/
4045
export function parseSSEChunk(chunk) {
4146
try {
42-
// 处理 dify SSE 格式:data: {json}
43-
// console.log(chunk,chunk.startsWith('data: '))
47+
// console.log('chunk:', chunk);
48+
const data = chunk;
4449

45-
const cleanChunk = chunk;
46-
// 检查是否是结束标志
47-
if (cleanChunk === '[DONE]') {
48-
return { type: 'done' };
49-
}
50-
51-
const data = JSON.parse(cleanChunk);
52-
5350
// 根据 event 类型处理不同的数据
5451
switch (data.event) {
5552
case 'message':
56-
return {
57-
type: 'message',
58-
data: {
59-
id: data.message_id,
60-
content: data.answer || '',
61-
conversation_id: data.conversation_id,
62-
created_at: data.created_at,
63-
metadata: data.metadata || {},
64-
},
65-
};
66-
67-
case 'message_delta':
53+
// 检查是否是结束标志(answer 为空字符串)
54+
if (data.answer === '') {
55+
return {
56+
type: 'end',
57+
data: {
58+
id: data.message_id,
59+
conversation_id: data.conversation_id,
60+
created_at: data.created_at,
61+
task_id: data.task_id,
62+
metadata: {
63+
from_variable_selector: data.from_variable_selector || [],
64+
},
65+
},
66+
};
67+
}
68+
69+
// 返回增量数据
6870
return {
6971
type: 'delta',
7072
data: {
7173
id: data.message_id,
72-
delta: data.delta || '',
73-
conversation_id: data.conversation_id,
74-
},
75-
};
76-
77-
case 'message_end':
78-
return {
79-
type: 'end',
80-
data: {
81-
id: data.message_id,
74+
delta: data.answer, // answer 字段包含增量内容
8275
conversation_id: data.conversation_id,
83-
metadata: data.metadata || {},
76+
created_at: data.created_at,
77+
task_id: data.task_id,
78+
metadata: {
79+
from_variable_selector: data.from_variable_selector || [],
80+
},
8481
},
8582
};
86-
83+
8784
default:
8885
return {
8986
type: 'unknown',
@@ -101,7 +98,7 @@ export function parseSSEChunk(chunk) {
10198
* @returns {Function} 转换器函数
10299
*/
103100
export function createDifyTransformer() {
104-
return (chunk) => {
101+
return chunk => {
105102
return parseSSEChunk(chunk);
106103
};
107104
}
@@ -116,12 +113,12 @@ export function createDifyTransformer() {
116113
*/
117114
export function createDifyRequestConfig(options = {}) {
118115
const { baseURL = 'https://api.dify.ai/v1', apiKey, user = 'default-user' } = options;
119-
116+
120117
return {
121118
baseURL,
122119
baseOptions: {
123120
headers: {
124-
'Authorization': `Bearer ${apiKey}`,
121+
Authorization: `Bearer ${apiKey}`,
125122
'Content-Type': 'application/json',
126123
},
127124
},
@@ -154,14 +151,18 @@ export function buildChatMessageRequest(params) {
154151
inputs = {},
155152
auto_generate_name = true,
156153
} = params;
157-
154+
158155
return {
159156
query,
160157
inputs,
161158
response_mode,
162159
user,
163-
...(conversation_id && { conversation_id }),
164-
...(files.length > 0 && { files }),
160+
...(conversation_id && {
161+
conversation_id,
162+
}),
163+
...(files.length > 0 && {
164+
files,
165+
}),
165166
auto_generate_name,
166167
};
167168
}
@@ -172,4 +173,4 @@ export default {
172173
createDifyTransformer,
173174
createDifyRequestConfig,
174175
buildChatMessageRequest,
175-
};
176+
};

examples/src/utils/timeUtils.js

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
/**
2+
* 时间处理工具函数
3+
*/
4+
5+
/**
6+
* 根据时间获取分组标签
7+
* @param {string|Date|number} dateTime - 时间字符串、Date对象或Unix时间戳
8+
* @returns {string} 分组标签:今天、7天内、30天内、yyyy-MM
9+
*/
10+
export function getTimeGroup(dateTime) {
11+
// 处理Unix时间戳(秒)
12+
let createdAt;
13+
if (typeof dateTime === 'number') {
14+
// Unix时间戳通常是秒,需要转换为毫秒
15+
createdAt = new Date(dateTime * 1000);
16+
} else {
17+
createdAt = new Date(dateTime);
18+
}
19+
20+
const now = new Date();
21+
const diffTime = now - createdAt;
22+
const diffDays = Math.floor(diffTime / (1000 * 60 * 60 * 24));
23+
24+
if (diffDays === 0) {
25+
return '今天';
26+
} else if (diffDays <= 7) {
27+
return '7天内';
28+
} else if (diffDays <= 30) {
29+
return '30天内';
30+
} else {
31+
// 格式化为 yyyy-MM
32+
const year = createdAt.getFullYear();
33+
const month = String(createdAt.getMonth() + 1).padStart(2, '0');
34+
return `${year}-${month}`;
35+
}
36+
}
37+
38+
/**
39+
* 批量为数据项添加时间分组字段
40+
* @param {Array} items - 数据项数组
41+
* @param {string} timeField - 时间字段名,默认为'created_at'
42+
* @returns {Array} 添加了group字段的数据项数组
43+
*/
44+
export function addTimeGroupToItems(items, timeField = 'created_at') {
45+
return items.map(item => ({
46+
...item,
47+
group: getTimeGroup(item[timeField]),
48+
}));
49+
}
50+
51+
/**
52+
* 格式化时间为可读格式
53+
* @param {string|Date|number} dateTime - 时间字符串、Date对象或Unix时间戳
54+
* @param {string} format - 格式化模式,默认为'YYYY-MM-DD HH:mm:ss'
55+
* @returns {string} 格式化后的时间字符串
56+
*/
57+
export function formatTime(dateTime, format = 'YYYY-MM-DD HH:mm:ss') {
58+
// 处理Unix时间戳(秒)
59+
let date;
60+
if (typeof dateTime === 'number') {
61+
// Unix时间戳通常是秒,需要转换为毫秒
62+
date = new Date(dateTime * 1000);
63+
} else {
64+
date = new Date(dateTime);
65+
}
66+
67+
const year = date.getFullYear();
68+
const month = String(date.getMonth() + 1).padStart(2, '0');
69+
const day = String(date.getDate()).padStart(2, '0');
70+
const hours = String(date.getHours()).padStart(2, '0');
71+
const minutes = String(date.getMinutes()).padStart(2, '0');
72+
const seconds = String(date.getSeconds()).padStart(2, '0');
73+
74+
return format
75+
.replace('YYYY', year)
76+
.replace('MM', month)
77+
.replace('DD', day)
78+
.replace('HH', hours)
79+
.replace('mm', minutes)
80+
.replace('ss', seconds);
81+
}

0 commit comments

Comments
 (0)