AI助手优化-头像和对话功能
This commit is contained in:
@@ -6,10 +6,24 @@ class ChatSessionItem {
|
||||
final String title;
|
||||
final String updateTime;
|
||||
|
||||
/// 本会话绑定的人设 id。null = 内置默认人设。
|
||||
///
|
||||
/// 会话的人设在**新建时确定、之后不可改** —— 一次对话从头到尾是同一个人。
|
||||
final int? personaId;
|
||||
|
||||
/// 人设显示名。人设被删了会回落成「默认人设」,历史会话不会因此打不开
|
||||
final String personaName;
|
||||
|
||||
/// 人设头像相对路径。null = 用默认头像
|
||||
final String? personaAvatar;
|
||||
|
||||
const ChatSessionItem({
|
||||
required this.id,
|
||||
required this.title,
|
||||
required this.updateTime,
|
||||
this.personaId,
|
||||
this.personaName = '默认人设',
|
||||
this.personaAvatar,
|
||||
});
|
||||
|
||||
factory ChatSessionItem.fromJson(Map<String, dynamic> json) {
|
||||
@@ -17,6 +31,9 @@ class ChatSessionItem {
|
||||
id: asInt(json['id']),
|
||||
title: asNonEmpty(json['title'], '新对话'),
|
||||
updateTime: formatDateTime(json['updateTime']),
|
||||
personaId: asNullableInt(json['personaId']),
|
||||
personaName: asNonEmpty(json['personaName'], '默认人设'),
|
||||
personaAvatar: asNonEmpty(json['personaAvatar'], ''),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ class AiPersonaItem {
|
||||
required this.isDefault,
|
||||
required this.editable,
|
||||
required this.defaultPrompt,
|
||||
this.avatar,
|
||||
});
|
||||
|
||||
/// null = 虚拟的「默认」项(内容是服务端代码内置的)
|
||||
@@ -42,6 +43,10 @@ class AiPersonaItem {
|
||||
/// 以后改了默认人设,App 不用跟着改版本。
|
||||
final String? defaultPrompt;
|
||||
|
||||
/// 头像**相对路径**(如 `persona/2026/09/29/xxx.jpg`)。
|
||||
/// 用 [Avatar] 组件显示,它会自己拼 host。null = 用默认头像。
|
||||
final String? avatar;
|
||||
|
||||
/// 用于「显示已选中的是哪一项」的稳定标识。
|
||||
///
|
||||
/// 默认项没有 id,用 -1 代替 —— 不能直接用 null 当 map key 去比较。
|
||||
@@ -58,6 +63,7 @@ class AiPersonaItem {
|
||||
// 用户项上这个字段是 null —— 不能直接用 asNonEmpty(它要 fallback 参数,
|
||||
// 而我们恰恰需要保留「null = 没有」这个语义,供「恢复默认」按钮判断)
|
||||
defaultPrompt: _nullableNonEmpty(json['defaultPrompt']),
|
||||
avatar: _nullableNonEmpty(json['avatar']),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -3,12 +3,21 @@ class AuthResponse {
|
||||
final String? username;
|
||||
final String? nickname;
|
||||
|
||||
const AuthResponse({required this.token, this.username, this.nickname});
|
||||
/// 头像相对路径。null = 用默认头像
|
||||
final String? avatar;
|
||||
|
||||
const AuthResponse({
|
||||
required this.token,
|
||||
this.username,
|
||||
this.nickname,
|
||||
this.avatar,
|
||||
});
|
||||
|
||||
factory AuthResponse.fromJson(Map<String, dynamic> json) => AuthResponse(
|
||||
token: json['token']?.toString() ?? '',
|
||||
username: json['username']?.toString(),
|
||||
nickname: json['nickname']?.toString(),
|
||||
avatar: json['avatar']?.toString(),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -17,13 +26,27 @@ class UserInfo {
|
||||
final String username;
|
||||
final String nickname;
|
||||
|
||||
const UserInfo({this.id, required this.username, required this.nickname});
|
||||
/// 头像相对路径。null = 用默认头像
|
||||
final String? avatar;
|
||||
|
||||
Map<String, dynamic> toJson() => {'id': id, 'username': username, 'nickname': nickname};
|
||||
const UserInfo({
|
||||
this.id,
|
||||
required this.username,
|
||||
required this.nickname,
|
||||
this.avatar,
|
||||
});
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
'id': id,
|
||||
'username': username,
|
||||
'nickname': nickname,
|
||||
'avatar': avatar,
|
||||
};
|
||||
|
||||
factory UserInfo.fromJson(Map<String, dynamic> json) => UserInfo(
|
||||
id: json['id']?.toString(),
|
||||
username: json['username']?.toString() ?? '',
|
||||
nickname: json['nickname']?.toString() ?? '',
|
||||
avatar: json['avatar']?.toString(),
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user