Browse Source

[feat]亲密度分析,增加文件上传Api

hezihao 7 months ago
parent
commit
98ab526d55

+ 84 - 0
lib/data/api/atmob_file_api.c.dart

@@ -0,0 +1,84 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'atmob_file_api.dart';
+
+// **************************************************************************
+// RetrofitGenerator
+// **************************************************************************
+
+// ignore_for_file: unnecessary_brace_in_string_interps,no_leading_underscores_for_local_identifiers,unused_element,unnecessary_string_interpolations
+
+class _AtmobFileApi implements AtmobFileApi {
+  _AtmobFileApi(this._dio, {this.baseUrl, this.errorLogger});
+
+  final Dio _dio;
+
+  String? baseUrl;
+
+  final ParseErrorLogger? errorLogger;
+
+  @override
+  Future<BaseResponse<UploadResultBean>> uploadImage(
+    UploadRequest 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<UploadResultBean>>(
+      Options(
+            method: 'POST',
+            headers: _headers,
+            extra: _extra,
+            contentType: 'multipart/form-data',
+          )
+          .compose(
+            _dio.options,
+            '/project/keyboard/v1/upload/image',
+            queryParameters: queryParameters,
+            data: _data,
+          )
+          .copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
+    );
+    final _result = await _dio.fetch<Map<String, dynamic>>(_options);
+    late BaseResponse<UploadResultBean> _value;
+    try {
+      _value = BaseResponse<UploadResultBean>.fromJson(
+        _result.data!,
+        (json) => UploadResultBean.fromJson(json as Map<String, dynamic>),
+      );
+    } on Object catch (e, s) {
+      errorLogger?.logError(e, s, _options);
+      rethrow;
+    }
+    return _value;
+  }
+
+  RequestOptions _setStreamType<T>(RequestOptions requestOptions) {
+    if (T != dynamic &&
+        !(requestOptions.responseType == ResponseType.bytes ||
+            requestOptions.responseType == ResponseType.stream)) {
+      if (T == String) {
+        requestOptions.responseType = ResponseType.plain;
+      } else {
+        requestOptions.responseType = ResponseType.json;
+      }
+    }
+    return requestOptions;
+  }
+
+  String _combineBaseUrls(String dioBaseUrl, String? baseUrl) {
+    if (baseUrl == null || baseUrl.trim().isEmpty) {
+      return dioBaseUrl;
+    }
+
+    final url = Uri.parse(baseUrl);
+
+    if (url.isAbsolute) {
+      return url.toString();
+    }
+
+    return Uri.parse(dioBaseUrl).resolveUri(url).toString();
+  }
+}

+ 24 - 0
lib/data/api/atmob_file_api.dart

@@ -0,0 +1,24 @@
+import 'package:dio/dio.dart';
+import 'package:keyboard/data/api/request/upload_request.dart';
+import 'package:keyboard/data/api/response/upload_result_bean.dart';
+import 'package:retrofit/error_logger.dart';
+import 'package:retrofit/http.dart';
+import '../../base/base_response.dart';
+import '../../di/network_module.dart';
+import '../consts/Constants.dart';
+
+part 'atmob_file_api.c.dart';
+// part 'atmob_file_api.g.dart';
+
+@RestApi()
+abstract class AtmobFileApi {
+  factory AtmobFileApi(Dio dio, {String baseUrl}) = _AtmobFileApi;
+
+  /// 文件上传
+  @MultiPart()
+  @POST("/project/keyboard/v1/upload/image")
+  Future<BaseResponse<UploadResultBean>> uploadImage(
+      @Body() UploadRequest request);
+}
+
+final atmobFileApi = AtmobFileApi(fileDio, baseUrl: Constants.baseUrl);

+ 27 - 0
lib/data/api/request/upload_request.dart

@@ -0,0 +1,27 @@
+import 'dart:io';
+import 'package:dio/dio.dart';
+import 'package:flutter/widgets.dart';
+import 'package:json_annotation/json_annotation.dart';
+
+import '../../../base/app_base_request.dart';
+
+part 'upload_request.g.dart';
+
+@JsonSerializable()
+class UploadRequest extends AppBaseRequest {
+  @JsonKey(ignore: true)
+  File? file;
+
+  UploadRequest({this.file});
+
+  @override
+  Map<String, dynamic> toJson() {
+    final json = _$UploadRequestToJson(this);
+    debugPrint('file path: ${file?.path}');
+    if (file != null) {
+      json['file'] = MultipartFile.fromFileSync(file!.path,
+          contentType: DioMediaType('image', 'jpeg'));
+    }
+    return json;
+  }
+}

+ 66 - 0
lib/data/api/request/upload_request.g.dart

@@ -0,0 +1,66 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'upload_request.dart';
+
+// **************************************************************************
+// JsonSerializableGenerator
+// **************************************************************************
+
+UploadRequest _$UploadRequestFromJson(Map<String, dynamic> json) =>
+    UploadRequest()
+      ..appPlatform = (json['appPlatform'] as num).toInt()
+      ..os = json['os'] as String
+      ..osVersion = json['osVersion'] as String
+      ..packageName = json['packageName'] as String?
+      ..appVersionName = json['appVersionName'] as String?
+      ..appVersionCode = (json['appVersionCode'] as num?)?.toInt()
+      ..channelName = json['channelName'] as String?
+      ..appId = (json['appId'] as num?)?.toInt()
+      ..tgPlatform = (json['tgPlatform'] as num?)?.toInt()
+      ..oaid = json['oaid'] as String?
+      ..aaid = json['aaid'] as String?
+      ..androidId = json['androidId'] as String?
+      ..imei = json['imei'] as String?
+      ..simImei0 = json['simImei0'] as String?
+      ..simImei1 = json['simImei1'] as String?
+      ..mac = json['mac'] as String?
+      ..idfa = json['idfa'] as String?
+      ..idfv = json['idfv'] as String?
+      ..machineId = json['machineId'] as String?
+      ..brand = json['brand'] as String?
+      ..model = json['model'] as String?
+      ..wifiName = json['wifiName'] as String?
+      ..region = json['region'] as String?
+      ..locLng = (json['locLng'] as num?)?.toDouble()
+      ..locLat = (json['locLat'] as num?)?.toDouble()
+      ..authToken = json['authToken'] as String?;
+
+Map<String, dynamic> _$UploadRequestToJson(UploadRequest instance) =>
+    <String, dynamic>{
+      'appPlatform': instance.appPlatform,
+      'os': instance.os,
+      'osVersion': instance.osVersion,
+      'packageName': instance.packageName,
+      'appVersionName': instance.appVersionName,
+      'appVersionCode': instance.appVersionCode,
+      'channelName': instance.channelName,
+      'appId': instance.appId,
+      'tgPlatform': instance.tgPlatform,
+      'oaid': instance.oaid,
+      'aaid': instance.aaid,
+      'androidId': instance.androidId,
+      'imei': instance.imei,
+      'simImei0': instance.simImei0,
+      'simImei1': instance.simImei1,
+      'mac': instance.mac,
+      'idfa': instance.idfa,
+      'idfv': instance.idfv,
+      'machineId': instance.machineId,
+      'brand': instance.brand,
+      'model': instance.model,
+      'wifiName': instance.wifiName,
+      'region': instance.region,
+      'locLng': instance.locLng,
+      'locLat': instance.locLat,
+      'authToken': instance.authToken,
+    };

+ 23 - 0
lib/data/api/response/upload_result_bean.dart

@@ -0,0 +1,23 @@
+import 'package:json_annotation/json_annotation.dart';
+
+part 'upload_result_bean.g.dart';
+
+/// 上传文件的结果
+@JsonSerializable()
+class UploadResultBean {
+  /// 路径,用于提交给服务端
+  @JsonKey(name: 'filePath')
+  String filePath;
+
+  /// cdn前缀
+  @JsonKey(name: 'cdnPrefix')
+  int? cdnPrefix;
+
+  UploadResultBean({
+    required this.filePath,
+    this.cdnPrefix,
+  });
+
+  factory UploadResultBean.fromJson(Map<String, dynamic> json) =>
+      _$UploadResultBeanFromJson(json);
+}

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

@@ -0,0 +1,19 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'upload_result_bean.dart';
+
+// **************************************************************************
+// JsonSerializableGenerator
+// **************************************************************************
+
+UploadResultBean _$UploadResultBeanFromJson(Map<String, dynamic> json) =>
+    UploadResultBean(
+      filePath: json['filePath'] as String,
+      cdnPrefix: (json['cdnPrefix'] as num?)?.toInt(),
+    );
+
+Map<String, dynamic> _$UploadResultBeanToJson(UploadResultBean instance) =>
+    <String, dynamic>{
+      'filePath': instance.filePath,
+      'cdnPrefix': instance.cdnPrefix,
+    };

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

@@ -1,3 +1,5 @@
+import 'dart:io';
+
 import 'package:get/get_rx/src/rx_types/rx_types.dart';
 import 'package:injectable/injectable.dart';
 import 'package:keyboard/base/app_base_request.dart';
@@ -7,7 +9,10 @@ import '../../utils/async_util.dart';
 import '../../utils/atmob_log.dart';
 import '../../utils/http_handler.dart';
 import '../api/atmob_api.dart';
+import '../api/atmob_file_api.dart';
+import '../api/request/upload_request.dart';
 import '../api/response/intimacy_analyze_config_response.dart';
+import '../api/response/upload_result_bean.dart';
 
 /// 亲密度分析Repository层
 @LazySingleton()
@@ -39,6 +44,13 @@ class IntimacyAnalyzeRepository {
     });
   }
 
+  /// 上传图片
+  Future<UploadResultBean> uploadImage({required File? file}) {
+    return atmobFileApi
+        .uploadImage(UploadRequest(file: file))
+        .then(HttpHandler.handle(false));
+  }
+
   /// 获取亲密度配置
   Future<IntimacyAnalyzeConfigResponse> requestIntimacyAnalyzeConfig() {
     return atmobApi

+ 23 - 2
lib/di/network_module.dart

@@ -44,13 +44,34 @@ abstract class NetworkModule {
     return streamDio;
   }
 
+  static Dio _createFileDio() {
+    Dio dio = Dio(
+      BaseOptions(
+        sendTimeout: const Duration(seconds: 15),
+        receiveTimeout: const Duration(seconds: 15),
+      ),
+    );
+    dio.interceptors.add(
+      PrettyDioLogger(
+        requestHeader: true,
+        requestBody: true,
+        responseBody: true,
+        responseHeader: true,
+        enabled: BuildConfig.isDebug,
+      ),
+    );
+    return dio;
+  }
+
   @singleton
-  AtmobApi provideAtmobApi(@Named("defaultDio")Dio dio) {
+  AtmobApi provideAtmobApi(@Named("defaultDio") Dio dio) {
     return AtmobApi(dio, baseUrl: Constants.baseUrl);
   }
 
   @singleton
-  AtmobStreamApi provideAtmobStreamApi(@Named("streamDio")Dio streamDio) {
+  AtmobStreamApi provideAtmobStreamApi(@Named("streamDio") Dio streamDio) {
     return AtmobStreamApi(streamDio, baseUrl: Constants.baseUrl);
   }
 }
+
+final fileDio = NetworkModule._createFileDio();

+ 6 - 2
lib/module/intimacy_analyse/intimacy_analyse_upload/intimacy_analyse_upload_page.dart

@@ -14,7 +14,6 @@ import 'package:wechat_assets_picker/wechat_assets_picker.dart';
 import '../../../resource/assets.gen.dart';
 import '../../../router/app_page_arguments.dart';
 import '../../../router/app_pages.dart';
-import '../../../utils/fake_image_util.dart';
 import '../../../utils/string_format_util.dart';
 import '../../../widget/actionbtn/action_btn.dart';
 import '../../../widget/gradient_text.dart';
@@ -220,6 +219,10 @@ class IntimacyAnalyseUploadPage
         children: [
           // 图片九宫格
           Container(
+            constraints: BoxConstraints(
+              // 最小高度
+              minHeight: 212.h
+            ),
             margin: EdgeInsets.only(left: 12.w, right: 12.w),
             padding: EdgeInsets.only(
               left: 12.w,
@@ -233,7 +236,8 @@ class IntimacyAnalyseUploadPage
             ),
             child: UploadNineGrid(
               mode: Mode.preview,
-              imageSrcList: [...FakeImageUtil.getImageUrlList()],
+              // 上传的图片列表
+              imageSrcList: [],
               maxCount: 9,
               spacing: 8.0,
             ),