Browse Source

[new]增加本地文件选择功能

zk 1 year ago
parent
commit
5b8eaa0d71

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

@@ -129,4 +129,8 @@
     <string name="popup_nearly_a_month">近一个月</string>
     <string name="popup_custom_time">自定义时间</string>
     <string name="popup_agenda_filter_txt">展示%s待办</string>
+    <string name="import_local_audio">导入本地音频</string>
+    <string name="select_and_import">选择并导入</string>
+    <string name="authorization_failed">授权失败</string>
+    <string name="please_choice_local_audio_file">请选择本地音频文件</string>
 </resources>

+ 20 - 3
lib/module/audiopicker/controller.dart

@@ -1,7 +1,9 @@
 import 'dart:io';
 
 import 'package:electronic_assistant/base/base_controller.dart';
+import 'package:electronic_assistant/resource/string.gen.dart';
 import 'package:electronic_assistant/utils/audio_picker_utils.dart';
+import 'package:electronic_assistant/utils/file_upload_check_helper.dart';
 import 'package:electronic_assistant/utils/toast_util.dart';
 import 'package:get/get.dart';
 import 'package:photo_manager/photo_manager.dart';
@@ -15,13 +17,17 @@ class AudioPickerController extends BaseController {
   final audioList = RxList<AssetEntity>();
   AssetPathEntity? currentPath;
 
+  final _currentEntity = Rxn<AssetEntity?>();
+
+  AssetEntity? get currentEntity => _currentEntity.value;
+
   @override
   void onReady() async {
     super.onReady();
     if (!await AudioPickerUtils.hasPermission()) {
       bool permission = await AudioPickerUtils.requestPermissionExtend();
       if (!permission) {
-        ToastUtil.showToast('授权失败');
+        ToastUtil.showToast(StringName.authorizationFailed.tr);
         return;
       }
     }
@@ -47,7 +53,16 @@ class AudioPickerController extends BaseController {
     return listEntity.first;
   }
 
-  void onItemClick(AssetEntity entity) async {
+  void onItemClick(AssetEntity entity) {
+    _currentEntity.value = entity;
+  }
+
+  void onImportClick() async {
+    AssetEntity? entity = _currentEntity.value;
+    if (entity == null) {
+      ToastUtil.showToast(StringName.pleaseChoiceLocalAudioFile.tr);
+      return;
+    }
     File? file = await entity.file;
     if (file == null) {
       ToastUtil.showToast('文件不存在');
@@ -57,7 +72,9 @@ class AudioPickerController extends BaseController {
     try {
       TalkBean bean = await talkRepository.talkCreate(
           const Uuid().v4(), entity.duration,
-          localAudioUrl: entity.id, uploadType: FileUploadType.local);
+          localAudioUrl:
+              FileUploadCheckHelper.joinUploadServerAudioTag(entity.id),
+          uploadType: FileUploadType.local);
       Get.back();
       TalkPage.start(bean);
     } catch (e) {

+ 136 - 19
lib/module/audiopicker/view.dart

@@ -1,59 +1,176 @@
+import 'package:electronic_assistant/base/base_controller.dart';
 import 'package:electronic_assistant/base/base_page.dart';
 import 'package:electronic_assistant/data/bean/store_item.dart';
 import 'package:electronic_assistant/dialog/add_agenda_dialog.dart';
+import 'package:electronic_assistant/resource/assets.gen.dart';
+import 'package:electronic_assistant/resource/string.gen.dart';
 import 'package:electronic_assistant/utils/expand.dart';
 import 'package:flutter/cupertino.dart';
 import 'package:flutter/src/widgets/framework.dart';
 import 'package:flutter_screenutil/flutter_screenutil.dart';
+import 'package:get/get.dart';
 import 'package:get/get_state_manager/src/rx_flutter/rx_obx_widget.dart';
 import 'package:photo_manager/photo_manager.dart';
 
+import '../../resource/colors.gen.dart';
+import '../../utils/common_style.dart';
 import 'controller.dart';
 
 class AudioPickerPage extends BasePage<AudioPickerController> {
   const AudioPickerPage({super.key});
 
   @override
+  Color backgroundColor() {
+    return ColorName.transparent;
+  }
+
+  @override
   Widget buildBody(BuildContext context) {
     return Container(
+      decoration: BoxDecoration(
+        color: "#F6F5F8".toColor(),
+        borderRadius: const BorderRadius.only(
+          topLeft: Radius.circular(16),
+          topRight: Radius.circular(16),
+        ),
+      ),
       height: ScreenUtil().screenHeight - 70.h,
       child: Column(
         children: [
-          Text('AudioPickerPage'),
+          _buildTitleView(),
           Expanded(child: Obx(() {
             return ListView.builder(
               itemBuilder: _buildItem,
               itemCount: controller.audioList.length,
             );
-          }))
+          })),
+          _buildImportBtnView()
+        ],
+      ),
+    );
+  }
+
+  Widget _buildTitleView() {
+    return Container(
+      padding: EdgeInsets.symmetric(vertical: 18.h),
+      child: Stack(
+        children: [
+          Center(
+              child: Text(
+            StringName.importLocalAudio.tr,
+            style:
+                TextStyle(fontSize: 17.sp, color: ColorName.primaryTextColor),
+          )),
+          Container(
+            margin: EdgeInsets.only(right: 16.w),
+            child: GestureDetector(
+              onTap: () {
+                Get.back();
+              },
+              child: Align(
+                alignment: Alignment.centerRight,
+                child: Text(
+                  StringName.cancel.tr,
+                  style: TextStyle(
+                      fontSize: 14.sp, color: ColorName.secondaryTextColor),
+                ),
+              ),
+            ),
+          ),
         ],
       ),
     );
   }
 
+  Widget _buildImportBtnView() {
+    return Container(
+      color: ColorName.white,
+      padding: EdgeInsets.symmetric(vertical: 6.h),
+      child: GestureDetector(
+        onTap: () {
+          controller.onImportClick();
+        },
+        child: Container(
+          height: 48.h,
+          margin: EdgeInsets.symmetric(horizontal: 16.w),
+          width: double.infinity,
+          decoration: getCommonDecoration(8.w),
+          child: Center(
+            child: Text(
+              StringName.selectAndImport.tr,
+              style: TextStyle(fontSize: 16.sp, color: ColorName.white),
+            ),
+          ),
+        ),
+      ),
+    );
+  }
+
   Widget _buildItem(BuildContext context, int index) {
     AssetEntity entity = controller.audioList[index];
     return GestureDetector(
       onTap: () {
         controller.onItemClick(entity);
       },
-      child: Container(
-        margin: EdgeInsets.only(bottom: 10),
-        padding: EdgeInsets.all(10),
-        child: Row(
-          children: [
-            Column(
-              crossAxisAlignment: CrossAxisAlignment.start,
-              children: [
-                Text(entity.title ?? ''),
-                Text(
-                    '创建时间:${entity.createDateSecond?.toFormattedDate('yyyy-MM-dd HH:mm:ss')}'),
-                Text('时长:${entity.duration}'),
-              ],
-            )
-          ],
-        ),
-      ),
+      child: Obx(() {
+        return Container(
+          decoration: controller.currentEntity?.id == entity.id
+              ? BoxDecoration(
+                  border: Border.all(color: '#6177F2'.toColor(), width: 2.w),
+                  color: '#E7E9F6'.toColor(),
+                  borderRadius: BorderRadius.circular(8.w),
+                )
+              : BoxDecoration(
+                  color: ColorName.white,
+                  borderRadius: BorderRadius.circular(8.w),
+                ),
+          margin: EdgeInsets.only(bottom: 8.h, left: 16.w, right: 16.w),
+          padding: EdgeInsets.symmetric(horizontal: 10.w, vertical: 14.h),
+          child: Row(
+            children: [
+              Assets.images.iconFilesFile.image(width: 32.w, height: 32.w),
+              SizedBox(width: 8.w),
+              Expanded(
+                child: Column(
+                  crossAxisAlignment: CrossAxisAlignment.start,
+                  children: [
+                    Text(
+                      maxLines: 2,
+                      overflow: TextOverflow.ellipsis,
+                      entity.title ?? '',
+                      style: TextStyle(
+                          fontSize: 14.sp,
+                          color: ColorName.primaryTextColor,
+                          fontWeight: FontWeight.bold),
+                    ),
+                    Row(
+                      children: [
+                        Text(entity.duration.toDouble().toFormattedDuration(),
+                            style: TextStyle(
+                                fontSize: 12.sp,
+                                color: ColorName.tertiaryTextColor)),
+                        SizedBox(width: 6.w),
+                        Container(
+                            width: 1,
+                            height: 9,
+                            color: ColorName.tertiaryTextColor),
+                        SizedBox(width: 6.w),
+                        Text(
+                            entity.createDateSecond
+                                    ?.toFormattedDate('yyyy-MM-dd HH:mm') ??
+                                '',
+                            style: TextStyle(
+                                fontSize: 12.sp,
+                                color: ColorName.tertiaryTextColor))
+                      ],
+                    )
+                  ],
+                ),
+              )
+            ],
+          ),
+        );
+      }),
     );
   }
 }

+ 8 - 2
lib/module/talk/controller.dart

@@ -20,6 +20,7 @@ import 'package:electronic_assistant/resource/colors.gen.dart';
 import 'package:electronic_assistant/resource/string.gen.dart';
 import 'package:electronic_assistant/utils/error_handler.dart';
 import 'package:electronic_assistant/utils/expand.dart';
+import 'package:electronic_assistant/utils/file_upload_check_helper.dart';
 import 'package:electronic_assistant/utils/mmkv_util.dart';
 import 'package:flutter/cupertino.dart';
 import 'package:flutter/material.dart';
@@ -514,8 +515,13 @@ Future<File?> getFileByTalk(TalkBean? bean) async {
     return null;
   }
   if (bean.uploadType == TalkUploadType.localUpload) {
-    return await AudioPickerUtils.getAssetFile(bean.localAudioUrl);
-    // return await getChoiceUploadFile(bean.id);
+    String? audioId = FileUploadCheckHelper.getLocalAudioId(bean.localAudioUrl);
+    if (audioId != null && audioId.isNotEmpty) {
+      return await AudioPickerUtils.getAssetFile(
+          FileUploadCheckHelper.getLocalAudioId(bean.localAudioUrl));
+    } else {
+      return await FileUploadCheckHelper.getChoiceUploadFile(bean.id);
+    }
   } else {
     return await RecordController.getRecordFile(bean.id);
   }

+ 10 - 0
lib/utils/common_style.dart

@@ -12,3 +12,13 @@ Decoration getPrimaryBtnDecoration(double radius) {
     borderRadius: BorderRadius.circular(radius),
   );
 }
+
+Decoration getCommonDecoration(double radius) {
+  return BoxDecoration(
+    gradient: LinearGradient(
+      colors: ['#6177F2'.toColor(), '#8B9DFF'.toColor()],
+      stops: const [0, 1.0],
+    ),
+    borderRadius: BorderRadius.circular(radius),
+  );
+}

+ 13 - 0
lib/utils/common_utils.dart

@@ -1,3 +1,7 @@
+import 'dart:io';
+
+import 'package:electronic_assistant/device/atmob_platform_info.dart';
+
 bool getBoolValue(bool? value) {
   return value ?? false;
 }
@@ -10,3 +14,12 @@ String stringToUnicode(String input) {
   }
   return unicodeString.toString();
 }
+
+String? getDeviceId() {
+  if (Platform.isAndroid) {
+    return atmobPlatformInfo.androidId;
+  } else if (Platform.isIOS) {
+    return atmobPlatformInfo.idfv;
+  }
+  return null;
+}

+ 22 - 0
lib/utils/file_upload_check_helper.dart

@@ -13,6 +13,7 @@ import '../resource/string.gen.dart';
 import 'audio_picker_utils.dart';
 import 'package:path_provider/path_provider.dart';
 
+import 'common_utils.dart';
 import 'error_handler.dart';
 
 class FileUploadCheckHelper {
@@ -116,6 +117,27 @@ class FileUploadCheckHelper {
     String newFilePath = '${dir.path}/${file.uri.pathSegments.last}';
     file.renameSync(newFilePath);
   }
+
+  static const String _uploadServerAudioTag = '_&&@@##_';
+
+  //拼接设备ID用于标识
+  static String joinUploadServerAudioTag(String id) {
+    return '${getDeviceId()}$_uploadServerAudioTag$id';
+  }
+
+  static String? getLocalAudioId(String? tag) {
+    if (tag == null || tag.isEmpty) {
+      return null;
+    }
+    if (!tag.contains(_uploadServerAudioTag)) {
+      return null;
+    }
+    List<String> audioTag = tag.split(_uploadServerAudioTag);
+    if (audioTag.first != getDeviceId()) {
+      return null;
+    }
+    return tag.split(_uploadServerAudioTag).last;
+  }
 }
 
 class PickerException implements Exception {

+ 1 - 1
plugin/gravity_engine/android/src/main/java/com/atmob/gravity_engine/GravityEnginePlugin.java

@@ -103,7 +103,7 @@ public class GravityEnginePlugin implements FlutterPlugin, MethodCallHandler {
                 gravityEngineSdk.initialize(accessToken, clientId, clientId, channel, new InitializeCallback() {
                     @Override
                     public void onFailed(String s, JSONObject jsonObject) {
-                        result.error(s, "GravityEngine init failed, msg: " + jsonObject.toString(), null);
+                        result.error(s, "GravityEngine init failed, msg: " + jsonObject, null);
                     }
 
                     @Override

+ 9 - 1
pubspec.lock

@@ -14,9 +14,17 @@ packages:
     description: dart
     source: sdk
     version: "0.3.2"
-  alipay_kit_android:
+  alipay_kit:
     dependency: "direct main"
     description:
+      name: alipay_kit
+      sha256: "6d6086b4cda1e0cd9b29b6dfe8d0ce88b9efc1c9f2c8d6fb39ac24c4e0f79b06"
+      url: "https://pub.dev"
+    source: hosted
+    version: "6.0.0"
+  alipay_kit_android:
+    dependency: transitive
+    description:
       name: alipay_kit_android
       sha256: "402917c30e5a1c1bb36cab7c99e355f65a98da96c2666657805a985b00937f6f"
       url: "https://pub.dev"