Explorar o código

[feat]亲密度分析,截图回复-识图回复,对接获取识图回复配置接口

hezihao hai 7 meses
pai
achega
a8a073b887

+ 1 - 0
assets/string/base/string.xml

@@ -315,6 +315,7 @@
 
     <string name="for_ta">对于TA</string>
     <string name="for_me">对于我</string>
+    <string name="choose_reply_tone">选择回复语气</string>
 
     <string name="preview">预览</string>
 

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

@@ -40,6 +40,7 @@ import 'package:keyboard/data/api/response/chat_super_speak_response.dart';
 import 'package:keyboard/data/api/response/config_response.dart';
 import 'package:keyboard/data/api/response/intimacy_analyze_chat_config_response.dart';
 import 'package:keyboard/data/api/response/intimacy_analyze_config_response.dart';
+import 'package:keyboard/data/api/response/intimacy_analyze_reply_config_response.dart';
 import 'package:keyboard/data/api/response/intimacy_analyze_response.dart';
 import 'package:keyboard/data/api/response/item_list_response.dart';
 import 'package:keyboard/data/api/response/item_retention_response.dart';
@@ -275,6 +276,11 @@ abstract class AtmobApi {
   Future<BaseResponse<IntimacyAnalyzeChatConfigResponse>>
   getIntimacyAnalyzeChatConfig(@Body() AppBaseRequest request);
 
+  /// 获取识图回复配置
+  @POST("/project/keyboard/v1/intimacy/reply/config")
+  Future<BaseResponse<IntimacyAnalyzeReplyConfigResponse>>
+  getIntimacyAnalyzeReplyConfig(@Body() AppBaseRequest request);
+
   // 获取星座梗语与解读
   @POST("/project/keyboard/v1/keyboard/memeExplain")
   Future<BaseResponse<KeyboardMemeExplainResponse>> getKeyboardMemeExplain(

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

@@ -1275,6 +1275,43 @@ class _AtmobApi implements AtmobApi {
   }
 
   @override
+  Future<BaseResponse<IntimacyAnalyzeReplyConfigResponse>>
+  getIntimacyAnalyzeReplyConfig(AppBaseRequest 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<IntimacyAnalyzeReplyConfigResponse>>(
+          Options(method: 'POST', headers: _headers, extra: _extra)
+              .compose(
+                _dio.options,
+                '/project/keyboard/v1/intimacy/reply/config',
+                queryParameters: queryParameters,
+                data: _data,
+              )
+              .copyWith(
+                baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl),
+              ),
+        );
+    final _result = await _dio.fetch<Map<String, dynamic>>(_options);
+    late BaseResponse<IntimacyAnalyzeReplyConfigResponse> _value;
+    try {
+      _value = BaseResponse<IntimacyAnalyzeReplyConfigResponse>.fromJson(
+        _result.data!,
+        (json) => IntimacyAnalyzeReplyConfigResponse.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 {

+ 26 - 0
lib/data/api/response/intimacy_analyze_reply_config_response.dart

@@ -0,0 +1,26 @@
+import 'package:json_annotation/json_annotation.dart';
+import 'package:keyboard/data/api/response/for_me_bean.dart';
+import 'package:keyboard/data/api/response/for_ta_bean.dart';
+import 'package:keyboard/data/api/response/tone_bean.dart';
+
+import '../../bean/ai_model.dart';
+import '../../bean/intimacy_analyze_direction.dart';
+
+part 'intimacy_analyze_reply_config_response.g.dart';
+
+/// 亲密度-识图回复配置
+@JsonSerializable()
+class IntimacyAnalyzeReplyConfigResponse {
+  /// 语气列表
+  @JsonKey(name: 'tones')
+  List<ToneBean>? tones;
+
+  IntimacyAnalyzeReplyConfigResponse(this.tones);
+
+  factory IntimacyAnalyzeReplyConfigResponse.fromJson(
+    Map<String, dynamic> json,
+  ) => _$IntimacyAnalyzeReplyConfigResponseFromJson(json);
+
+  Map<String, dynamic> toJson() =>
+      _$IntimacyAnalyzeReplyConfigResponseToJson(this);
+}

+ 19 - 0
lib/data/api/response/intimacy_analyze_reply_config_response.g.dart

@@ -0,0 +1,19 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'intimacy_analyze_reply_config_response.dart';
+
+// **************************************************************************
+// JsonSerializableGenerator
+// **************************************************************************
+
+IntimacyAnalyzeReplyConfigResponse _$IntimacyAnalyzeReplyConfigResponseFromJson(
+  Map<String, dynamic> json,
+) => IntimacyAnalyzeReplyConfigResponse(
+  (json['tones'] as List<dynamic>?)
+      ?.map((e) => ToneBean.fromJson(e as Map<String, dynamic>))
+      .toList(),
+);
+
+Map<String, dynamic> _$IntimacyAnalyzeReplyConfigResponseToJson(
+  IntimacyAnalyzeReplyConfigResponse instance,
+) => <String, dynamic>{'tones': instance.tones};

+ 22 - 0
lib/data/api/response/tone_bean.dart

@@ -0,0 +1,22 @@
+import 'package:json_annotation/json_annotation.dart';
+
+part 'tone_bean.g.dart';
+
+/// 语气实体类
+@JsonSerializable()
+class ToneBean {
+  /// 表情包
+  @JsonKey(name: 'emoji')
+  String? emoji;
+
+  /// 标题
+  @JsonKey(name: 'title')
+  String? title;
+
+  ToneBean(this.emoji, this.title);
+
+  factory ToneBean.fromJson(Map<String, dynamic> json) =>
+      _$ToneBeanFromJson(json);
+
+  Map<String, dynamic> toJson() => _$ToneBeanToJson(this);
+}

+ 15 - 0
lib/data/api/response/tone_bean.g.dart

@@ -0,0 +1,15 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'tone_bean.dart';
+
+// **************************************************************************
+// JsonSerializableGenerator
+// **************************************************************************
+
+ToneBean _$ToneBeanFromJson(Map<String, dynamic> json) =>
+    ToneBean(json['emoji'] as String?, json['title'] as String?);
+
+Map<String, dynamic> _$ToneBeanToJson(ToneBean instance) => <String, dynamic>{
+  'emoji': instance.emoji,
+  'title': instance.title,
+};

+ 26 - 0
lib/data/repository/intimacy_analyze_repository.dart

@@ -12,6 +12,7 @@ import '../api/atmob_api.dart';
 import '../api/request/intimacy_analyze_request.dart';
 import '../api/response/intimacy_analyze_chat_config_response.dart';
 import '../api/response/intimacy_analyze_config_response.dart';
+import '../api/response/intimacy_analyze_reply_config_response.dart';
 import '../api/response/intimacy_analyze_response.dart';
 
 /// 亲密度分析Repository层
@@ -29,11 +30,16 @@ class IntimacyAnalyzeRepository {
   Rxn<IntimacyAnalyzeChatConfigResponse> intimacyAnalyzeChatConfig =
       Rxn<IntimacyAnalyzeChatConfigResponse>();
 
+  /// 识图回复配置
+  Rxn<IntimacyAnalyzeReplyConfigResponse> intimacyAnalyzeReplyConfig =
+      Rxn<IntimacyAnalyzeReplyConfigResponse>();
+
   IntimacyAnalyzeRepository(this.atmobApi) {
     AtmobLog.d(tag, '$tag...init');
     // 初始化时,刷新配置
     _refreshIntimacyAnalyzeConfig();
     _refreshIntimacyAnalyzeChatConfig();
+    _refreshIntimacyAnalyzeReplyConfig();
   }
 
   /// 从Getx的依赖注入中,获取实例,适合在没有依赖注入上下文的地方使用
@@ -65,6 +71,18 @@ class IntimacyAnalyzeRepository {
     });
   }
 
+  /// 刷新识图回复配置
+  void _refreshIntimacyAnalyzeReplyConfig() {
+    AsyncUtil.retry(
+      () => requestIntimacyAnalyzeReplyConfig(),
+      Duration(seconds: 3),
+      maxRetry: 100,
+    ).then((IntimacyAnalyzeReplyConfigResponse configResponse) {
+      AtmobLog.d(tag, "获取识图回复配置成功: ${configResponse.toJson()}");
+      intimacyAnalyzeReplyConfig.value = configResponse;
+    });
+  }
+
   /// 获取亲密度配置
   Future<IntimacyAnalyzeConfigResponse> requestIntimacyAnalyzeConfig() {
     return atmobApi
@@ -79,6 +97,14 @@ class IntimacyAnalyzeRepository {
         .then(HttpHandler.handle(true));
   }
 
+  /// 获取识图回复配置
+  Future<IntimacyAnalyzeReplyConfigResponse>
+  requestIntimacyAnalyzeReplyConfig() {
+    return atmobApi
+        .getIntimacyAnalyzeReplyConfig(AppBaseRequest())
+        .then(HttpHandler.handle(true));
+  }
+
   /// 分析亲密度
   Future<IntimacyAnalyzeResponse> getIntimacyAnalyze(
     IntimacyAnalyzeRequest request,

+ 23 - 12
lib/module/intimacy_analyse/screenshot_reply/scan_image_reply/scan_image_reply_controller.dart

@@ -5,6 +5,7 @@ import 'package:get/get_rx/src/rx_types/rx_types.dart';
 import 'package:injectable/injectable.dart';
 import 'package:keyboard/base/base_controller.dart';
 import 'package:keyboard/data/bean/upload_info.dart';
+import 'package:keyboard/resource/string.gen.dart';
 import 'package:wechat_assets_picker/wechat_assets_picker.dart';
 
 import '../../../../data/bean/option_select_config.dart';
@@ -30,6 +31,9 @@ class ScanImageReplyController extends BaseController {
   RxList<OptionSelectConfig> replyToneOptionSelectConfigList =
       <OptionSelectConfig>[].obs;
 
+  /// 当前选择的语气
+  Rxn<OptionSelectItem> currentSelectReplyToneOption = Rxn();
+
   /// 是否上传页
   RxBool isUploadPage = true.obs;
 
@@ -58,18 +62,22 @@ class ScanImageReplyController extends BaseController {
 
   /// 回复语气列表
   void _initReplyToneOptionSelectConfigList() {
-    replyToneOptionSelectConfigList.add(
-      OptionSelectConfig("选择回复语气", "", [
-        OptionSelectItem("😁 高冷"),
-        OptionSelectItem("😁 幽默搞笑"),
-        OptionSelectItem("😁 贴心暖男"),
-        OptionSelectItem("😁 温柔体贴"),
-        OptionSelectItem("😁 阳光大男孩"),
-        OptionSelectItem("😁 都市精英"),
-        OptionSelectItem("😁 小狼狗"),
-        OptionSelectItem("😁 小奶狗"),
-      ]),
-    );
+    // 语气列表
+    var toneList =
+        intimacyAnalyzeConfigHelper.intimacyAnalyzeReplyConfig.value?.tones ??
+        [];
+    if (toneList.isNotEmpty) {
+      var newList =
+          toneList.map((item) {
+            return OptionSelectItem("${item.emoji} ${item.title}");
+          }).toList();
+
+      replyToneOptionSelectConfigList.clear();
+      replyToneOptionSelectConfigList.add(
+        OptionSelectConfig(StringName.chooseReplyTone, "", newList),
+      );
+      replyToneOptionSelectConfigList.refresh();
+    }
   }
 
   /// 选中回复语气的选项
@@ -87,6 +95,9 @@ class ScanImageReplyController extends BaseController {
     optionItem.selected = true;
     // 由于Rx响应式变量,无法监听对象中嵌套对象的某个属性的变化,导致页面不会刷新,需要手动刷新页面
     replyToneOptionSelectConfigList.refresh();
+
+    // 保存当前选择的语气选项
+    currentSelectReplyToneOption.value = optionItem;
   }
 
   /// 切换回复模型

+ 14 - 8
lib/module/intimacy_analyse/screenshot_reply/scan_image_reply/scan_image_reply_view.dart

@@ -329,14 +329,20 @@ class ScanImageReplyView extends BaseView<ScanImageReplyController> {
                             ),
                           ),
                           // 回复内容
-                          Text(
-                            "😁 键盘侠",
-                            style: TextStyle(
-                              color: ColorName.black80,
-                              fontSize: 14.sp,
-                              fontWeight: FontWeight.w500,
-                            ),
-                          ),
+                          Obx(() {
+                            return Text(
+                              controller
+                                      .currentSelectReplyToneOption
+                                      .value
+                                      ?.name ??
+                                  "",
+                              style: TextStyle(
+                                color: ColorName.black80,
+                                fontSize: 14.sp,
+                                fontWeight: FontWeight.w500,
+                              ),
+                            );
+                          }),
                         ],
                       ),
                     ),

+ 2 - 0
lib/resource/string.gen.dart

@@ -226,6 +226,7 @@ class StringName {
   static final String intimacyAnalyseReportPreviewBubbleText = 'intimacy_analyse_report_preview_bubble_text'.tr; // 报告还有2565字未显示,点击按钮查看完整报告
   static final String forTa = 'for_ta'.tr; // 对于TA
   static final String forMe = 'for_me'.tr; // 对于我
+  static final String chooseReplyTone = 'choose_reply_tone'.tr; // 选择回复语气
   static final String preview = 'preview'.tr; // 预览
   static final String retry = 'retry'.tr; // 再试试
   static final String nextStep = 'next_step'.tr; // 下一步
@@ -494,6 +495,7 @@ class StringMultiSource {
       'intimacy_analyse_report_preview_bubble_text': '报告还有2565字未显示,点击按钮查看完整报告',
       'for_ta': '对于TA',
       'for_me': '对于我',
+      'choose_reply_tone': '选择回复语气',
       'preview': '预览',
       'retry': '再试试',
       'next_step': '下一步',

+ 5 - 0
lib/utils/intimacy_analyze_config_helper.dart

@@ -3,6 +3,7 @@ import 'package:injectable/injectable.dart';
 
 import '../data/api/response/intimacy_analyze_chat_config_response.dart';
 import '../data/api/response/intimacy_analyze_config_response.dart';
+import '../data/api/response/intimacy_analyze_reply_config_response.dart';
 import '../data/repository/intimacy_analyze_repository.dart';
 
 /// 亲密度分析模块的配置的帮助类
@@ -19,6 +20,10 @@ class IntimacyAnalyzeConfigHelper {
   Rxn<IntimacyAnalyzeChatConfigResponse> get intimacyAnalyzeChatConfig =>
       intimacyAnalyzeRepository.intimacyAnalyzeChatConfig;
 
+  /// 对话分析配置
+  Rxn<IntimacyAnalyzeReplyConfigResponse> get intimacyAnalyzeReplyConfig =>
+      intimacyAnalyzeRepository.intimacyAnalyzeReplyConfig;
+
   IntimacyAnalyzeConfigHelper(this.intimacyAnalyzeRepository);
 
   /// 是否可以自定义预测方向