controller.dart 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. import 'dart:convert';
  2. import 'package:electronic_assistant/base/base_controller.dart';
  3. import 'package:electronic_assistant/data/bean/chat_item.dart';
  4. import 'package:electronic_assistant/data/bean/progressing_chat_item.dart';
  5. import 'package:electronic_assistant/data/bean/stream_chat_origin_data.dart';
  6. import 'package:electronic_assistant/data/repositories/chat_repository.dart';
  7. import 'package:electronic_assistant/module/chat/start/view.dart';
  8. import 'package:electronic_assistant/resource/colors.gen.dart';
  9. import 'package:flutter/material.dart';
  10. import 'package:get/get.dart';
  11. import 'package:pull_to_refresh/pull_to_refresh.dart';
  12. import '../../utils/http_handler.dart';
  13. class ChatController extends BaseController {
  14. final RefreshController refreshController = RefreshController();
  15. final ScrollController listScrollController = ScrollController();
  16. final TextEditingController inputController = TextEditingController();
  17. final RxList chatItems = [].obs;
  18. var isOpenStart = false;
  19. @override
  20. void onReady() {
  21. super.onReady();
  22. refreshController.requestLoading();
  23. }
  24. void loadMoreHistory() {
  25. bool isEmpty = chatItems.isEmpty;
  26. chatRepository
  27. .chatHistory(chatItems.isEmpty ? null : chatItems.last.id)
  28. .then((value) => chatItems.addAll(value))
  29. .whenComplete(() => refreshController.loadComplete())
  30. .whenComplete(() {
  31. if (isEmpty) {
  32. scrollToBottom();
  33. }
  34. });
  35. }
  36. void showStartSheet(BuildContext context) {
  37. if (!isOpenStart) {
  38. WidgetsBinding.instance.addPostFrameCallback((_) {
  39. showModalBottomSheet(
  40. context: context,
  41. isScrollControlled: true,
  42. barrierColor: ColorName.black55,
  43. backgroundColor: ColorName.transparent,
  44. builder: (BuildContext context) {
  45. return const ChatStartPage();
  46. },
  47. );
  48. });
  49. isOpenStart = true;
  50. }
  51. }
  52. sendMessage() {
  53. if (inputController.text.isEmpty) {
  54. return;
  55. }
  56. String chatContent = inputController.text;
  57. inputController.clear();
  58. chatItems.insert(
  59. 0,
  60. ChatItem(
  61. id: chatItems.isEmpty ? 0 : chatItems.last.id + 1,
  62. conversationId:
  63. chatItems.isEmpty ? "" : chatItems.last.conversationId,
  64. role: "user",
  65. content: chatContent,
  66. createTime: DateTime.now().toString()));
  67. ProgressingChatItem progressingChatItem = ProgressingChatItem(
  68. id: chatItems.last.id + 1,
  69. conversationId: chatItems.last.conversationId,
  70. role: "assistant",
  71. content: "",
  72. createTime: DateTime.now().toString(),
  73. );
  74. chatItems.insert(0, progressingChatItem);
  75. scrollToBottom();
  76. chatRepository.streamChat(chatContent).then((stream) {
  77. stream.listen((event) {
  78. try {
  79. Map<String, dynamic> json = jsonDecode(event.data);
  80. if (json.isEmpty) {
  81. return;
  82. }
  83. StreamChatOriginData data = StreamChatOriginData.fromJson(json);
  84. if (data.choices == null || data.choices!.isEmpty) {
  85. return;
  86. }
  87. Delta? delta = data.choices![0].delta;
  88. if (delta == null) {
  89. return;
  90. }
  91. progressingChatItem.append(delta.content ?? "");
  92. } catch (ignore) {}
  93. }, onDone: () {
  94. progressingChatItem.content = progressingChatItem.streamContent.value;
  95. progressingChatItem.isFinished.value = true;
  96. }, onError: (error) {
  97. progressingChatItem.isFailed.value = true;
  98. progressingChatItem.error.value = "网络错误,请检查网络连接";
  99. debugPrint("error: $error");
  100. debugPrintStack();
  101. });
  102. }).catchError((error) {
  103. progressingChatItem.isFailed.value = true;
  104. if (error is ServerErrorException) {
  105. progressingChatItem.error.value = error.message ?? "服务出错,请稍后再试";
  106. } else {
  107. progressingChatItem.error.value = "网络错误,请检查网络连接";
  108. debugPrint("error: $error");
  109. debugPrintStack();
  110. }
  111. });
  112. }
  113. void scrollToBottom() {
  114. Future.delayed(const Duration(milliseconds: 300), () {
  115. listScrollController.animateTo(
  116. 0,
  117. duration: const Duration(milliseconds: 300),
  118. curve: Curves.easeOut,
  119. );
  120. });
  121. }
  122. }