api_file.dart 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. import 'dart:convert';
  2. import 'package:archive/archive.dart';
  3. import 'package:dio/dio.dart';
  4. import 'package:uuid/uuid.dart';
  5. import '../../../utils/crypto.dart';
  6. import '../../../utils/developer/ix_developer_tools.dart';
  7. import '../../../utils/log/logger.dart';
  8. import '../../constants/keys.dart';
  9. import '../../data/models/api_exception.dart';
  10. import '../../data/models/api_result.dart';
  11. import '../../data/sp/ix_sp.dart';
  12. import '../base/base_api.dart';
  13. import '../core/api_core_paths.dart';
  14. /// 核心API
  15. class ApiFile extends BaseApi {
  16. static final _instance = ApiFile._internal();
  17. factory ApiFile() => _instance;
  18. ApiFile._internal() {
  19. _initDio();
  20. }
  21. /// 初始化Dio
  22. void _initDio() {
  23. // 此处可以设置默认的DIO参数
  24. final options = BaseOptions();
  25. options.connectTimeout = const Duration(seconds: 90);
  26. options.receiveTimeout = const Duration(seconds: 90);
  27. options.responseType = ResponseType.bytes;
  28. options.headers['content-type'] = 'multipart/form-data';
  29. dio = Dio(options);
  30. // 添加talker日志
  31. dio.interceptors.add(SimpleApiMonitorInterceptor());
  32. // 添加拦截器
  33. _setupInterceptors();
  34. }
  35. // bool _isRefreshing = false;
  36. void _setupInterceptors() {
  37. dio.interceptors.add(
  38. InterceptorsWrapper(
  39. onRequest: (options, handler) async {
  40. // 在请求发送前添加token
  41. final user = IXSP.getUser();
  42. if (user != null) {
  43. options.headers['Authorization'] = user.accessToken;
  44. }
  45. return handler.next(options);
  46. },
  47. onError: (DioException error, handler) async {
  48. return handler.next(error);
  49. },
  50. ),
  51. );
  52. }
  53. @override
  54. Map<String, dynamic>? getDefaultHeader() {
  55. // 可以设置自定义Header
  56. final headers = {
  57. 'X-NL-Product-Code': 'nomo',
  58. 'X-NL-Content-Encoding': 'gzip',
  59. };
  60. return headers;
  61. }
  62. @override
  63. Map<String, dynamic>? getDefaultQuery() {
  64. // 可以设置自定义Query
  65. return null;
  66. }
  67. @override
  68. dynamic encrypt(dynamic input) {
  69. return input;
  70. }
  71. @override
  72. dynamic decrypt(dynamic input) {
  73. try {
  74. final decryptedBytes = Crypto.decryptBytes(
  75. base64Encode(input),
  76. Keys.aesKey,
  77. Keys.aesIv,
  78. );
  79. // 使用GZip解压
  80. final gzipDecoder = GZipDecoder();
  81. final decodeBytes = gzipDecoder.decodeBytes(decryptedBytes);
  82. final data = utf8.decode(decodeBytes);
  83. log('ApiCore', '<<:$data');
  84. return jsonDecode(data);
  85. } catch (error) {
  86. throw ApiException("-2", "decrypt error: $error");
  87. }
  88. }
  89. // 上传日志文件
  90. Future<ApiResult> uploadLogFile(
  91. String filePath,
  92. String fileName,
  93. String logType,
  94. String data,
  95. ) async {
  96. final fileData = await MultipartFile.fromFile(filePath, filename: fileName);
  97. const fileType = 'gzip';
  98. final timestamp = DateTime.now().millisecondsSinceEpoch;
  99. final sign = Crypto.encrypt(
  100. '$fileType$logType$timestamp',
  101. Keys.aesKey,
  102. Keys.aesIv,
  103. );
  104. if (logType == "App_NL_Log") {
  105. final logId = const Uuid().v4();
  106. final userInfo = Crypto.encrypt(data, Keys.aesKey, Keys.aesIv);
  107. final formData = FormData.fromMap({
  108. 'file': fileData,
  109. 'fileName': fileName,
  110. 'fileType': fileType,
  111. 'logType': logType,
  112. 'timestamp': timestamp,
  113. 'sign': sign,
  114. 'userInfo': userInfo,
  115. 'logId': logId,
  116. });
  117. return post(
  118. ApiCorePaths.uploadFile,
  119. data: formData,
  120. domainType: DomainType.file,
  121. );
  122. } else {
  123. final formData = FormData.fromMap({
  124. 'file': fileData,
  125. 'fileName': fileName,
  126. 'fileType': fileType,
  127. 'timestamp': timestamp,
  128. 'logType': logType,
  129. 'sign': sign,
  130. });
  131. return post(
  132. ApiCorePaths.uploadFile,
  133. data: formData,
  134. domainType: DomainType.file,
  135. );
  136. }
  137. }
  138. // 上传图片文件
  139. Future<ApiResult> uploadImageFile(String filePath, String fileName) async {
  140. final fileData = await MultipartFile.fromFile(filePath, filename: fileName);
  141. const fileType = 'image';
  142. final timestamp = DateTime.now().millisecondsSinceEpoch;
  143. final sign = Crypto.encrypt('$fileType$timestamp', Keys.aesKey, Keys.aesIv);
  144. final formData = FormData.fromMap({
  145. 'file': fileData,
  146. 'fileType': fileType,
  147. 'timestamp': timestamp,
  148. 'sign': sign,
  149. });
  150. return post(
  151. ApiCorePaths.uploadImage,
  152. data: formData,
  153. domainType: DomainType.file,
  154. );
  155. }
  156. // 上传视频文件
  157. Future<ApiResult> uploadVideoFile(String filePath, String fileName) async {
  158. final fileData = await MultipartFile.fromFile(filePath, filename: fileName);
  159. const fileType = 'video';
  160. final timestamp = DateTime.now().millisecondsSinceEpoch;
  161. final sign = Crypto.encrypt('$fileType$timestamp', Keys.aesKey, Keys.aesIv);
  162. final formData = FormData.fromMap({
  163. 'file': fileData,
  164. 'fileType': fileType,
  165. 'timestamp': timestamp,
  166. 'sign': sign,
  167. });
  168. return post(
  169. ApiCorePaths.uploadVideo,
  170. data: formData,
  171. domainType: DomainType.file,
  172. );
  173. }
  174. // 上传多个图片文件
  175. Future<ApiResult> uploadMultipleImageFiles(
  176. List<String> filePaths,
  177. List<String> fileNames,
  178. ) async {
  179. final List<MultipartFile> files = [];
  180. for (int i = 0; i < filePaths.length; i++) {
  181. final fileData = await MultipartFile.fromFile(
  182. filePaths[i],
  183. filename: fileNames[i],
  184. );
  185. files.add(fileData);
  186. }
  187. const fileType = 'image';
  188. final timestamp = DateTime.now().millisecondsSinceEpoch;
  189. final sign = Crypto.encrypt('$fileType$timestamp', Keys.aesKey, Keys.aesIv);
  190. final formData = FormData.fromMap({
  191. 'file': files,
  192. 'fileType': fileType,
  193. 'timestamp': timestamp,
  194. 'sign': sign,
  195. });
  196. return post(
  197. ApiCorePaths.uploadImage,
  198. data: formData,
  199. domainType: DomainType.file,
  200. );
  201. }
  202. // 上传多个视频文件
  203. Future<ApiResult> uploadMultipleVideoFiles(
  204. List<String> filePaths,
  205. List<String> fileNames,
  206. ) async {
  207. final List<MultipartFile> files = [];
  208. for (int i = 0; i < filePaths.length; i++) {
  209. final fileData = await MultipartFile.fromFile(
  210. filePaths[i],
  211. filename: fileNames[i],
  212. );
  213. files.add(fileData);
  214. }
  215. const fileType = 'video';
  216. final timestamp = DateTime.now().millisecondsSinceEpoch;
  217. final sign = Crypto.encrypt('$fileType$timestamp', Keys.aesKey, Keys.aesIv);
  218. final formData = FormData.fromMap({
  219. 'file': files,
  220. 'fileType': fileType,
  221. 'timestamp': timestamp,
  222. 'sign': sign,
  223. });
  224. return post(
  225. ApiCorePaths.uploadVideo,
  226. data: formData,
  227. domainType: DomainType.file,
  228. );
  229. }
  230. }