فهرست منبع

Merge branch 'v1.0.1' of git.atmob.com:Atmob-Flutter/ElectronicAssistant into v1.0.1

Destiny 1 سال پیش
والد
کامیت
f0d9984b2b

+ 45 - 0
android/app/src/main/java/io/github/v7lin/wechat_kit/WechatCallbackActivity.java

@@ -0,0 +1,45 @@
+package io.github.v7lin.wechat_kit;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import com.atmob.elec_asst.activity.MainActivity;
+
+public final class WechatCallbackActivity extends Activity {
+    private static final String KEY_WECHAT_CALLBACK = "wechat_callback";
+    private static final String KEY_WECHAT_EXTRA = "wechat_extra";
+
+    @Override
+    protected void onCreate(@Nullable Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        handleIntent(getIntent());
+    }
+
+    @Override
+    protected void onNewIntent(Intent intent) {
+        super.onNewIntent(intent);
+        handleIntent(intent);
+    }
+
+    private void handleIntent(Intent intent) {
+        final Intent launchIntent = new Intent(this, MainActivity.class);
+        launchIntent.putExtra(KEY_WECHAT_CALLBACK, true);
+        launchIntent.putExtra(KEY_WECHAT_EXTRA, intent);
+//        launchIntent.setPackage(getPackageName());
+        launchIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+        startActivity(launchIntent);
+        finish();
+    }
+
+    public static Intent extraCallback(@NonNull Intent intent) {
+        if (intent.getExtras() != null && intent.getBooleanExtra(KEY_WECHAT_CALLBACK, false)) {
+            final Intent extra = intent.getParcelableExtra(KEY_WECHAT_EXTRA);
+            return extra;
+        }
+        return null;
+    }
+}

+ 4 - 6
lib/data/api/atmob_file_api.c.dart

@@ -33,12 +33,10 @@ class _AtmobFileApi implements AtmobFileApi {
       extra: _extra,
       contentType: 'multipart/form-data',
     )
-            .compose(
-              _dio.options,
-              '/project/secretary/v1/talk/generate',
-              queryParameters: queryParameters,
-              data: _data,
-            )
+            .compose(_dio.options, '/project/secretary/v1/talk/generate',
+                queryParameters: queryParameters,
+                data: _data,
+                onSendProgress: onSendProgress)
             .copyWith(
                 baseUrl: _combineBaseUrls(
               _dio.options.baseUrl,

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

@@ -8,7 +8,6 @@ import 'network_module.dart';
 
 part 'atmob_file_api.c.dart';
 
-@RestApi()
 abstract class AtmobFileApi {
   factory AtmobFileApi(Dio dio, {String baseUrl}) = _AtmobFileApi;
 

+ 5 - 1
lib/data/consts/constants.dart

@@ -7,7 +7,7 @@ import '../../utils/common_utils.dart';
 class Constants {
   Constants._();
 
-  static const String env = envProd;
+  static const String env = envTest;
 
   static const String envDev = 'dev';
 
@@ -34,6 +34,10 @@ class Constants {
   static const String appDefaultChannel = "Android";
   static const int appDefaultAppId = 0;
   static const int appDefaultTgPlatformId = 0;
+
+  static bool isProdEnv() {
+    return Constants.env == Constants.envProd;
+  }
 }
 
 String getBaseUrl() {

+ 37 - 1
lib/data/repositories/talk_repository.dart

@@ -5,8 +5,10 @@ import 'package:electronic_assistant/data/api/atmob_file_api.dart';
 import 'package:electronic_assistant/data/api/request/talk_create_request.dart';
 import 'package:electronic_assistant/data/api/request/talk_delete_request.dart';
 import 'package:electronic_assistant/data/api/request/talk_file_request.dart';
+import 'package:flutter_foreground_task/flutter_foreground_task.dart';
 import 'package:get/get.dart';
 
+import '../../utils/foreground_util.dart';
 import '../../utils/http_handler.dart';
 import '../api/request/talk_generate_request.dart';
 import '../api/request/talk_paginate_request.dart';
@@ -57,7 +59,7 @@ class TalkRepository {
 
   Future<TalkPaginateResponse> refreshHomeTalkData({int? sortType = 1}) {
     int limit;
-    if (_talkList.isEmpty) {
+    if (_talkList.isEmpty || _talkList.length < 10) {
       limit = 10;
     } else {
       limit = _talkList.length;
@@ -144,6 +146,12 @@ class TalkRepository {
 
   Future<String> uploadTalkFile(String talkId, double duration, File file) {
     _uploadingTalkIds.add(talkId);
+    startForegroundService(
+        serviceId: talkId.hashCode,
+        notificationTitle: '正在上传录音',
+        notificationText: '请勿关闭应用',
+        callback: setUploadCallback);
+    _uploadingTalkProgress[talkId] = RxDouble(0);
     return atmobFileApi
         .uploadTalkFile(TalkFileRequest(talkId, duration, file: file).toJson(),
             onSendProgress: (count, total) {
@@ -161,6 +169,9 @@ class TalkRepository {
         .catchError((error) {
           _uploadingTalkIds.remove(talkId);
           throw error;
+        })
+        .whenComplete(() {
+          stopForegroundService();
         });
   }
 
@@ -172,4 +183,29 @@ class TalkRepository {
   }
 }
 
+class UploadTaskHandler extends TaskHandler {
+  @override
+  Future<void> onDestroy(DateTime timestamp) {
+    // TODO: implement onDestroy
+    return Future.value();
+  }
+
+  @override
+  void onRepeatEvent(DateTime timestamp) {
+    // TODO: implement onRepeatEvent
+  }
+
+  @override
+  Future<void> onStart(DateTime timestamp, TaskStarter starter) {
+    // TODO: implement onStart
+    return Future.value();
+  }
+}
+
+@pragma('vm:entry-point')
+void setUploadCallback() {
+  // The setTaskHandler function must be called to handle the task in the background.
+  FlutterForegroundTask.setTaskHandler(UploadTaskHandler());
+}
+
 final talkRepository = TalkRepository._();

+ 9 - 0
lib/main.dart

@@ -9,6 +9,7 @@ import 'package:electronic_assistant/sdk/gravity/gravity_helper.dart';
 import 'package:electronic_assistant/utils/app_info_util.dart';
 import 'package:electronic_assistant/device/device_info_util.dart';
 import 'package:electronic_assistant/utils/mmkv_util.dart';
+import 'package:electronic_assistant/utils/toast_util.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_foreground_task/flutter_foreground_task.dart';
 import 'package:flutter_screenutil/flutter_screenutil.dart';
@@ -36,9 +37,17 @@ void main() async {
   //初始化
   await initAfterGrant();
 
+  //檢查地址
+  checkEnv();
   runApp(const MyApp());
 }
 
+void checkEnv() {
+  if (!Constants.isProdEnv()) {
+    ToastUtil.showToast('不是正式环境!!!');
+  }
+}
+
 initChannel() async {
   await AtmobChannelReader.default4Test(Constants.appDefaultChannel,
       Constants.appDefaultTgPlatformId, Constants.appDefaultAppId);

+ 1 - 0
lib/module/record/controller.dart

@@ -145,6 +145,7 @@ class RecordController extends BaseController {
       confirmOnTap: () {
         _deleteCurrentRecord();
         EAAlertDialog.dismiss();
+        Get.back();
       },
       cancelOnTap: () {
         EAAlertDialog.dismiss();

+ 11 - 4
lib/module/talk/common_view.dart

@@ -37,7 +37,7 @@ Widget getAddAgendaView(String addTxt, {VoidCallback? onClick}) {
   );
 }
 
-Widget getTalkUploadingView() {
+Widget getTalkUploadingView(RxDouble progress) {
   return SizedBox(
     width: double.infinity,
     child: Column(
@@ -47,10 +47,17 @@ Widget getTalkUploadingView() {
             width: 100.w,
             height: 100.w,
             child: Assets.anim.talkAnalyse.image()),
-        SizedBox(height: 12.h),
-        Text(StringName.talkUploadingTips.tr,
+        SizedBox(height: 3.h),
+        Text('谈话上传中',
             style:
-                TextStyle(fontSize: 14.sp, color: ColorName.secondaryTextColor))
+                TextStyle(fontSize: 15.sp, color: ColorName.primaryTextColor)),
+        SizedBox(height: 3.h),
+        Obx(() {
+          return Text(
+              '谈话已上传${(progress.value * 100).toFormattedString(1)}%,请稍后查看...',
+              style: TextStyle(
+                  fontSize: 12.sp, color: ColorName.secondaryTextColor));
+        })
       ],
     ),
   );

+ 5 - 0
lib/module/talk/controller.dart

@@ -118,6 +118,10 @@ class TalkController extends BaseController {
     eventReport(EventId.event_101001, params: {EventId.id: eventTag});
   }
 
+  RxDouble getUploadingProgress() {
+    return talkRepository.getUploadProgress(talkBean.value!.id);
+  }
+
   void eventReport(String eventId, {Map<String, dynamic>? params}) {
     if (talkBean.value == null || talkBean.value?.isExample == true) {
       return;
@@ -351,6 +355,7 @@ class TalkController extends BaseController {
     WakelockPlus.enable();
     talkRepository.uploadTalkFile(talkId, duration, file).then((taskId) {
       isUploadedFile = true;
+      talkBean.value?.status.value = TalkStatus.analysing;
       taskRepository.addTask(taskId);
     }).catchError((error) {
       isUploading.value = false;

+ 1 - 1
lib/module/talk/summary/view.dart

@@ -66,7 +66,7 @@ class SummaryView extends BasePage<SummaryController> {
       child: Column(
         crossAxisAlignment: CrossAxisAlignment.start,
         children: [
-          Text(StringName.homeTalkTodoTitle.tr,
+          Text(StringName.talkTodoAll.tr,
               style: TextStyle(
                   fontWeight: FontWeight.bold,
                   color: ColorName.primaryTextColor,

+ 1 - 1
lib/module/talk/view.dart

@@ -210,7 +210,7 @@ class TalkPage extends BasePage<TalkController> {
   }
 
   Widget buildElectricUploading() {
-    return getTalkUploadingView();
+    return getTalkUploadingView(controller.getUploadingProgress());
   }
 
   Widget buildTabContentView() {

+ 34 - 0
lib/utils/foreground_util.dart

@@ -0,0 +1,34 @@
+import 'package:flutter_foreground_task/flutter_foreground_task.dart';
+
+Future<ServiceRequestResult> startForegroundService({
+  int? serviceId,
+  required String notificationTitle,
+  required String notificationText,
+  NotificationIconData? notificationIcon,
+  List<NotificationButton>? notificationButtons,
+  required Function callback,
+}) async {
+  final NotificationPermission notificationPermission =
+      await FlutterForegroundTask.checkNotificationPermission();
+  if (notificationPermission != NotificationPermission.granted) {
+    await FlutterForegroundTask.requestNotificationPermission();
+  }
+  if (await FlutterForegroundTask.isRunningService) {
+    return FlutterForegroundTask.restartService();
+  } else {
+    return FlutterForegroundTask.startService(
+      serviceId: serviceId,
+      notificationTitle: notificationTitle,
+      notificationText: notificationText,
+      notificationIcon: notificationIcon,
+      notificationButtons: notificationButtons,
+      callback: callback,
+    );
+  }
+}
+
+Future<void> stopForegroundService() async {
+  if (await FlutterForegroundTask.isRunningService) {
+    FlutterForegroundTask.stopService();
+  }
+}