AI人设可以配置

This commit is contained in:
2026-09-28 17:16:34 +08:00
parent 2dd89bfde0
commit 80222099ff
10 changed files with 1269 additions and 23 deletions
+48 -17
View File
@@ -7,15 +7,15 @@ import '../../../models/ai_config.dart';
import '../../../providers/ai_config_provider.dart';
import '../../../utils/toast.dart';
import '../../../widgets/state_views.dart';
import 'ai_persona_page.dart';
/// AI 模型配置管理:列出现有配置、切换、增删改。
/// 「AI 设置」页:两个 Tab —— 模型 / 人设。
///
/// 设计上的三个要点:
/// 1. **「默认」那一项是虚拟的** —— 值来自服务器 `.env`,不能编辑/删除。
/// 它就是「什么都不选」的状态,选中后请求里 configId 传 null。
/// 2. **列表不打勾谁在用**,打勾的是 [selectedAiConfigProvider] 里存的那个。
/// 选中状态存在手机本地,不改服务端 —— 否则网页端和手机会互相打架。
/// 3. **api key 只显示掩码**。编辑时留空 = 不改动。
/// 为什么是 Tab 而不是顶栏再加一个胶囊:顶栏已经有返回、标题、当前模型胶囊、
/// 历史、新对话五块,320 宽的小屏塞不下第二个(`page_layout_test.dart` 会抓出来)。
/// 而且模型和人设本来就是**一对平行的配置**,放一个页面里切换很自然。
///
/// 入口函数名保留 `openAiConfigPage` —— 助手页的胶囊用它,不用改。
Future<void> openAiConfigPage(BuildContext context) {
return Navigator.of(context).push(
MaterialPageRoute(builder: (_) => const AiConfigPage()),
@@ -25,21 +25,52 @@ Future<void> openAiConfigPage(BuildContext context) {
class AiConfigPage extends ConsumerWidget {
const AiConfigPage({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
return DefaultTabController(
length: 2,
child: Scaffold(
appBar: AppBar(
title: const Text('AI 设置'),
bottom: const TabBar(
labelColor: Color(0xFFC8956E),
unselectedLabelColor: Color(0xFFBCAAA4),
indicatorColor: Color(0xFFC8956E),
indicatorSize: TabBarIndicatorSize.label,
tabs: [
Tab(text: '模型'),
Tab(text: '人设'),
],
),
),
body: const TabBarView(
children: [
AiModelTab(),
AiPersonaTab(),
],
),
),
);
}
}
/// 模型配置 Tab(原来的整页内容,去掉了自己的 Scaffold/AppBar)
class AiModelTab extends ConsumerWidget {
const AiModelTab({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final configs = ref.watch(aiConfigsProvider);
final selectedId = ref.watch(selectedAiConfigProvider);
return Scaffold(
appBar: AppBar(
title: const Text('AI 模型'),
actions: [
IconButton(
tooltip: '新增配置',
icon: const Icon(Icons.add),
onPressed: () => _openEditor(context, ref, null),
),
],
backgroundColor: const Color(0xFFFAF8F5),
floatingActionButton: FloatingActionButton(
onPressed: () => _openEditor(context, ref, null),
backgroundColor: const Color(0xFFC8956E),
foregroundColor: Colors.white,
tooltip: '新增配置',
child: const Icon(Icons.add),
),
body: configs.when(
loading: () => const LoadingView(tip: '正在加载配置...'),
@@ -50,7 +81,7 @@ class AiConfigPage extends ConsumerWidget {
data: (list) {
final custom = list.where((c) => c.editable).length;
return ListView(
padding: const EdgeInsets.fromLTRB(16, 12, 16, 24),
padding: const EdgeInsets.fromLTRB(16, 12, 16, 88),
children: [
_introCard(),
const SizedBox(height: 14),