瀏覽代碼

[fix]亲密度分析,截图回复-识图回复,识图回复接口从SSE流式改为普通的HTTP接口

hezihao 7 月之前
父節點
當前提交
d7699adafb

+ 6 - 0
lib/data/api/atmob_api.dart

@@ -307,6 +307,12 @@ abstract class AtmobApi {
   Future<BaseResponse<IntimacyAnalyzeReplyConfigResponse>>
   getIntimacyAnalyzeReplyConfig(@Body() AppBaseRequest request);
 
+  /// 识图回复
+  @POST("/project/keyboard/v1/intimacy/reply/analyze")
+  Future<BaseResponse<IntimacyReplyAnalyzeResponse>> intimacyReplyAnalyze(
+    @Body() IntimacyReplyAnalyzeRequest request,
+  );
+
   // 获取星座梗语与解读
   @POST("/project/keyboard/v1/keyboard/memeExplain")
   Future<BaseResponse<KeyboardMemeExplainResponse>> getKeyboardMemeExplain(

+ 34 - 0
lib/data/api/atmob_api.g.dart

@@ -1411,6 +1411,40 @@ class _AtmobApi implements AtmobApi {
   }
 
   @override
+  Future<BaseResponse<IntimacyReplyAnalyzeResponse>> intimacyReplyAnalyze(
+    IntimacyReplyAnalyzeRequest request,
+  ) async {
+    final _extra = <String, dynamic>{};
+    final queryParameters = <String, dynamic>{};
+    final _headers = <String, dynamic>{};
+    final _data = <String, dynamic>{};
+    _data.addAll(request.toJson());
+    final _options = _setStreamType<BaseResponse<IntimacyReplyAnalyzeResponse>>(
+      Options(method: 'POST', headers: _headers, extra: _extra)
+          .compose(
+            _dio.options,
+            '/project/keyboard/v1/intimacy/reply/analyze',
+            queryParameters: queryParameters,
+            data: _data,
+          )
+          .copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
+    );
+    final _result = await _dio.fetch<Map<String, dynamic>>(_options);
+    late BaseResponse<IntimacyReplyAnalyzeResponse> _value;
+    try {
+      _value = BaseResponse<IntimacyReplyAnalyzeResponse>.fromJson(
+        _result.data!,
+        (json) =>
+            IntimacyReplyAnalyzeResponse.fromJson(json as Map<String, dynamic>),
+      );
+    } on Object catch (e, s) {
+      errorLogger?.logError(e, s, _options);
+      rethrow;
+    }
+    return _value;
+  }
+
+  @override
   Future<BaseResponse<KeyboardMemeExplainResponse>> getKeyboardMemeExplain(
     KeyboardMemeExplainRequest request,
   ) async {

+ 0 - 23
lib/data/api/atmob_stream_api.c.dart

@@ -61,29 +61,6 @@ class _AtmobStreamApi implements AtmobStreamApi {
     return _result.data!;
   }
 
-  @override
-  Future<ResponseBody> intimacyReplyAnalyze(
-    IntimacyReplyAnalyzeRequest request,
-  ) async {
-    final _extra = <String, dynamic>{};
-    final queryParameters = <String, dynamic>{};
-    final _headers = <String, dynamic>{};
-    final _data = <String, dynamic>{};
-    _data.addAll(request.toJson());
-    final _options = _setStreamType<ResponseBody>(
-      Options(method: 'POST', headers: _headers, extra: _extra)
-          .compose(
-            _dio.options,
-            '/project/keyboard/v1/intimacy/reply/analyze',
-            queryParameters: queryParameters,
-            data: _data,
-          )
-          .copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
-    );
-    final _result = await _dio.fetch<ResponseBody>(_options);
-    return _result.data!;
-  }
-
   RequestOptions _setStreamType<T>(RequestOptions requestOptions) {
     if (T != dynamic &&
         !(requestOptions.responseType == ResponseType.bytes ||

+ 0 - 6
lib/data/api/atmob_stream_api.dart

@@ -29,10 +29,4 @@ abstract class AtmobStreamApi {
   Future<ResponseBody> intimacyChatAnalyze(
     @Body() IntimacyChatAnalyzeRequest request,
   );
-
-  /// 识图回复
-  @POST("/project/keyboard/v1/intimacy/reply/analyze")
-  Future<ResponseBody> intimacyReplyAnalyze(
-    @Body() IntimacyReplyAnalyzeRequest request,
-  );
 }

+ 4 - 22
lib/data/api/response/intimacy_reply_analyze_response.dart

@@ -7,30 +7,12 @@ part 'intimacy_reply_analyze_response.g.dart';
 /// 识图回复响应
 @JsonSerializable()
 class IntimacyReplyAnalyzeResponse {
-  @JsonKey(name: "id")
-  String? id;
-
-  @JsonKey(name: "object")
-  String? object;
-
-  /// 创建时间
-  @JsonKey(name: "created")
-  int? created;
-
-  /// Ai模型
-  @JsonKey(name: "model")
-  String? model;
-
-  /// 选择项列表
-  @JsonKey(name: "choices")
-  List<AnalyzeChoiceItem>? choices;
+  /// 回复列表
+  @JsonKey(name: "list")
+  List<String>? list;
 
   IntimacyReplyAnalyzeResponse(
-    this.id,
-    this.object,
-    this.created,
-    this.model,
-    this.choices,
+    this.list,
   );
 
   factory IntimacyReplyAnalyzeResponse.fromJson(Map<String, dynamic> json) =>

+ 2 - 14
lib/data/api/response/intimacy_reply_analyze_response.g.dart

@@ -9,21 +9,9 @@ part of 'intimacy_reply_analyze_response.dart';
 IntimacyReplyAnalyzeResponse _$IntimacyReplyAnalyzeResponseFromJson(
   Map<String, dynamic> json,
 ) => IntimacyReplyAnalyzeResponse(
-  json['id'] as String?,
-  json['object'] as String?,
-  (json['created'] as num?)?.toInt(),
-  json['model'] as String?,
-  (json['choices'] as List<dynamic>?)
-      ?.map((e) => AnalyzeChoiceItem.fromJson(e as Map<String, dynamic>))
-      .toList(),
+  (json['list'] as List<dynamic>?)?.map((e) => e as String).toList(),
 );
 
 Map<String, dynamic> _$IntimacyReplyAnalyzeResponseToJson(
   IntimacyReplyAnalyzeResponse instance,
-) => <String, dynamic>{
-  'id': instance.id,
-  'object': instance.object,
-  'created': instance.created,
-  'model': instance.model,
-  'choices': instance.choices,
-};
+) => <String, dynamic>{'list': instance.list};

+ 4 - 29
lib/data/repository/intimacy_analyze_repository.dart

@@ -165,37 +165,12 @@ class IntimacyAnalyzeRepository {
         .then(HttpHandler.handle(true));
   }
 
-  /// 识图回复(SSE流式)
-  Future<Stream<Message>> intimacyReplyAnalyze(
+  /// 识图回复
+  Future<IntimacyReplyAnalyzeResponse> intimacyReplyAnalyze(
     IntimacyReplyAnalyzeRequest request,
   ) {
-    return atmobStreamApi
+    return atmobApi
         .intimacyReplyAnalyze(request)
-        .then((response) async {
-          List<String>? contentType = response.headers['Content-Type'];
-          if (contentType != null) {
-            for (var value in contentType) {
-              if (value.contains('text/event-stream')) {
-                return response.stream;
-              } else if (value.contains('application/json')) {
-                BaseResponse<String> baseResponse = BaseResponse.fromJson(
-                  jsonDecode(
-                    await response.stream
-                        .map((bytes) => utf8.decoder.convert(bytes))
-                        .toList()
-                        .then((value) => value.join()),
-                  ),
-                  (json) => json as String,
-                );
-                throw ServerErrorException(
-                  baseResponse.code,
-                  baseResponse.message,
-                );
-              }
-            }
-          }
-          throw Exception('Invalid content type');
-        })
-        .then((stream) => SSEParseUtil.parse(stream));
+        .then(HttpHandler.handle(true));
   }
 }

+ 33 - 65
lib/module/intimacy_analyse/screenshot_reply/scan_image_reply/scan_image_reply_controller.dart

@@ -74,9 +74,6 @@ class ScanImageReplyController extends BaseController {
   /// 是否有识别结果
   Rx<bool> hasScanResult = false.obs;
 
-  /// 对话分析的订阅(SSE)
-  StreamSubscription<Message>? _intimacyReplyAnalyzeSubscription;
-
   ScanImageReplyController(
     this.intimacyAnalyzeConfigHelper,
     this.uploadFileManager,
@@ -91,13 +88,6 @@ class ScanImageReplyController extends BaseController {
     _initReplyModeList();
   }
 
-  @override
-  void onClose() {
-    // 取消SSE流数据订阅
-    _intimacyReplyAnalyzeSubscription?.cancel();
-    super.onClose();
-  }
-
   /// 初始化回复语气列表
   void _initReplyToneOptionSelectConfigList() {
     // 语气列表
@@ -260,9 +250,6 @@ class ScanImageReplyController extends BaseController {
       return;
     }
 
-    // 用于累计生成的内容
-    StringBuffer buffer = StringBuffer();
-
     // 切换为生成中
     isResultGenerating.value = true;
     hasScanResult.value = false;
@@ -273,60 +260,41 @@ class ScanImageReplyController extends BaseController {
     replyToneList.refresh();
 
     // 请求分析截图
-    Stream<Message> stream = await intimacyAnalyzeRepository
-        .intimacyReplyAnalyze(
-          IntimacyReplyAnalyzeRequest(imageList, title, mode),
-        );
-    _intimacyReplyAnalyzeSubscription = stream.listen(
-      (message) {
-        // 流数据更新
-        String json = message.data;
-        // 解析json为实体类
-        IntimacyReplyAnalyzeResponse response =
-            IntimacyReplyAnalyzeResponse.fromJson(jsonDecode(json));
-
-        List<String> contentList =
-            response.choices?.map((item) {
-              return item.delta?.content ?? "";
-            }).toList() ??
-            [];
-        // 数组转字符串
-        String content = contentList.join("");
-
-        // 累计内容
-        buffer.write(content);
-
-        // 刷新列表
-        replyToneList.clear();
-        replyToneList.add(buffer.toString());
-        replyToneList.refresh();
-
-        // 改为已有识别结果
-        hasScanResult.value = true;
-      },
-      onError: (error) {
-        // 发生异常
-        isResultGenerating.value = false;
-        hasScanResult.value = false;
-
-        AtmobLog.e(_tag, error.toString());
-        if (error is ServerErrorException) {
-          // 需要Vip权限
-          if (error.code == 1005) {
-            ToastUtil.show(error.message);
-            StorePage.start();
-          } else {
-            ToastUtil.show(error.message);
-          }
+    try {
+      IntimacyReplyAnalyzeResponse response = await intimacyAnalyzeRepository
+          .intimacyReplyAnalyze(
+            IntimacyReplyAnalyzeRequest(imageList, title, mode),
+          );
+      var newList = response.list ?? [];
+
+      // 刷新列表
+      replyToneList.clear();
+      replyToneList.addAll(newList);
+      replyToneList.refresh();
+
+      // 改为已有识别结果
+      hasScanResult.value = true;
+    } catch (error) {
+      // 发生异常
+      isResultGenerating.value = false;
+      hasScanResult.value = false;
+
+      AtmobLog.e(_tag, error.toString());
+      if (error is ServerErrorException) {
+        // 需要Vip权限
+        if (error.code == 1005) {
+          ToastUtil.show(error.message);
+          StorePage.start();
         } else {
-          ErrorHandler.toastError(error);
+          ToastUtil.show(error.message);
         }
-      },
-      onDone: () {
-        // 流关闭
-        isResultGenerating.value = false;
-      },
-    );
+      } else {
+        ErrorHandler.toastError(error);
+      }
+    } finally {
+      // 生成结束
+      isResultGenerating.value = false;
+    }
   }
 
   /// 删除上传信息

+ 13 - 10
lib/module/intimacy_analyse/screenshot_reply/scan_image_reply/scan_image_reply_view.dart

@@ -459,16 +459,19 @@ class ScanImageReplyView extends BaseView<ScanImageReplyController> {
             ),
           ),
           // 图标
-          GestureDetector(
-            onTap: () {
-              // 拷贝回复语气
-              controller.copyReplyTone(replyTone);
-            },
-            child: Container(
-              margin: EdgeInsets.only(right: 14.w),
-              child: Assets.images.iconActionCopy.image(
-                width: 18.w,
-                height: 18.w,
+          Visibility(
+            visible: replyTone.isNotEmpty,
+            child: GestureDetector(
+              onTap: () {
+                // 拷贝回复语气
+                controller.copyReplyTone(replyTone);
+              },
+              child: Container(
+                margin: EdgeInsets.only(right: 14.w),
+                child: Assets.images.iconActionCopy.image(
+                  width: 18.w,
+                  height: 18.w,
+                ),
               ),
             ),
           ),