Browse Source

上传会议记录 服务选择

newdev_shunjiawei
liwei1dao 5 months ago
parent
commit
7701c694c7
  1. 6
      lib/core/translations/language/en_us.dart
  2. 6
      lib/core/translations/language/zh_cn.dart
  3. 2
      lib/data/models/appconfig.dart
  4. 3
      lib/data/models/appconfig_model.dart
  5. 2
      lib/data/models/appconfig_model.g.dart
  6. 7
      lib/data/services/meeting/meeting_task_service.dart
  7. 9
      lib/data/services/meeting/meeting_upload_service.dart
  8. 3
      lib/modules/meeting/controllers/meeting_details_controller.dart
  9. 22
      lib/modules/meeting/model/transcribe_service.dart
  10. 49
      lib/modules/meeting/views/bottomSheet/generate_bottom_sheet.dart
  11. 173
      lib/modules/meeting/views/bottomSheet/transcribe_service_bottom_sheet.dart

6
lib/core/translations/language/en_us.dart

@ -1121,6 +1121,12 @@ const Map<String, String> enUS = {
"originalImage": "Original Image",
"sourceLanguage": "Source Language",
"targetLanguage": "Target Language",
"transcribeService": "Transcription Service",
"transcribeServiceAuto": "Auto",
"transcribeServiceByteDance": "ByteDance",
"transcribeServiceAli": "Alibaba Cloud",
"transcribeServiceGoogle": "Google",
"transcribeServiceMicrosoft": "Microsoft",
"translationTime": "Translation Time",
"shareInDevelopment": "Sharing feature under development",

6
lib/core/translations/language/zh_cn.dart

@ -1033,6 +1033,12 @@ const Map<String, String> zhCN = {
"originalImage": "原图片",
"sourceLanguage": "源语言",
"targetLanguage": "目标语言",
"transcribeService": "转写服务",
"transcribeServiceAuto": "自动",
"transcribeServiceByteDance": "字节跳动",
"transcribeServiceAli": "阿里云",
"transcribeServiceGoogle": "谷歌",
"transcribeServiceMicrosoft": "微软",
"translationTime": "翻译时间",
"shareInDevelopment": "分享功能开发中",

2
lib/data/models/appconfig.dart

@ -7,7 +7,7 @@ class AppConfig {
// true => 首页/发现页切换为精简布局,新手引导跳过 AI 引导步骤
// false => 保持原有布局
// TODO: 后续接入 BLE PID 判断逻辑,B017 设备连接时自动置 true
static bool hideAiAssistant = true;
static bool hideAiAssistant = false;
static late UserGetAppConfigResp config;

3
lib/data/models/appconfig_model.dart

@ -91,6 +91,8 @@ class DBProduct {
final String? channel;
// 渠道附加数据(JSON 字符串),例如:{"platform_id":"...","platform_key":"...","tui":"..."}
final String? channelextra;
// 是否隐藏 AI 助手(由后台按产品配置下发,true 表示该产品不展示 AI 助手)
final bool? hideaiassistant;
DBProduct({
required this.id,
@ -108,6 +110,7 @@ class DBProduct {
required this.updatepackageaddress,
this.channel,
this.channelextra,
this.hideaiassistant,
});
factory DBProduct.fromJson(Map<String, dynamic> json) =>

2
lib/data/models/appconfig_model.g.dart

@ -89,6 +89,7 @@ DBProduct _$DBProductFromJson(Map<String, dynamic> json) => DBProduct(
updatepackageaddress: json['updatepackageaddress'] as String?,
channel: json['channel'] as String?,
channelextra: json['channelextra'] as String?,
hideaiassistant: json['hideaiassistant'] as bool?,
);
Map<String, dynamic> _$DBProductToJson(DBProduct instance) => <String, dynamic>{
@ -107,4 +108,5 @@ Map<String, dynamic> _$DBProductToJson(DBProduct instance) => <String, dynamic>{
'updatepackageaddress': instance.updatepackageaddress,
'channel': instance.channel,
'channelextra': instance.channelextra,
'hideaiassistant': instance.hideaiassistant,
};

7
lib/data/services/meeting/meeting_task_service.dart

@ -6,6 +6,7 @@ import 'package:get_storage/get_storage.dart';
import '../db/sqflite_api.dart';
import '../network/api.dart';
import '../../models/user_Info.dart';
import '../../../modules/meeting/model/transcribe_service.dart';
import 'meeting_upload_service.dart';
class MeetingTaskService extends GetxService {
@ -61,6 +62,7 @@ class MeetingTaskService extends GetxService {
bool isdistinguishspeaker,
int templateid,
String tid,
TranscribeService serviceType,
) async {
if (audiourl.isEmpty) {
Map uploadData = _uploadService.uploadList.firstWhere(
@ -75,6 +77,7 @@ class MeetingTaskService extends GetxService {
uploadData['isdistinguishspeaker'] = isdistinguishspeaker;
uploadData['templateid'] = templateid;
uploadData['tid'] = tid;
uploadData['service_type'] = serviceType.value;
} else {
await submitTask(
id,
@ -83,6 +86,7 @@ class MeetingTaskService extends GetxService {
isdistinguishspeaker,
templateid,
tid,
serviceType,
);
}
}
@ -94,6 +98,7 @@ class MeetingTaskService extends GetxService {
isdistinguishspeaker,
templateid,
tid,
serviceType,
);
}
}
@ -105,6 +110,7 @@ class MeetingTaskService extends GetxService {
bool isdistinguishspeaker,
int templateid,
String tid,
TranscribeService serviceType,
) async {
await Api.startTaskEchomeet({
'id': id,
@ -113,6 +119,7 @@ class MeetingTaskService extends GetxService {
'isdistinguishspeaker': isdistinguishspeaker,
'templateid': templateid,
'tid': tid,
'service_type': serviceType.value,
});
final seconds = await _getMeetingSeconds(id);
_decrementMeetingIntegral(cost: seconds);

9
lib/data/services/meeting/meeting_upload_service.dart

@ -5,6 +5,7 @@ import 'package:get_storage/get_storage.dart';
import '../../../core/utils/logger.dart';
import '../../../core/utils/upload_oss.dart';
import '../../../modules/meeting/model/transcribe_service.dart';
import '../network/api.dart';
import '../usage_stats_service.dart';
import '../db/sqflite_api.dart';
@ -141,6 +142,13 @@ class MeetingUploadService extends GetxService {
Logger.w('MeetingOSrecord', '对象存储用量记录失败: $e');
}
if (element['isTask']) {
final int? svcVal = element['service_type'];
final TranscribeService svc = svcVal == null
? TranscribeService.auto
: TranscribeService.values.firstWhere(
(e) => e.value == svcVal,
orElse: () => TranscribeService.auto,
);
await _taskService.submitTask(
element['id'],
element['formlanguage'],
@ -148,6 +156,7 @@ class MeetingUploadService extends GetxService {
element['isdistinguishspeaker'],
element['templateid'],
element['tid'] ?? '',
svc,
);
}
element['audiourl'] = audiourl;

3
lib/modules/meeting/controllers/meeting_details_controller.dart

@ -19,6 +19,7 @@ import '../../../data/services/meeting/meeting_upload_service.dart';
import '../../../data/services/network/api.dart';
import '../model/meeting_details_model.dart';
import '../model/meeting_model.dart';
import '../model/transcribe_service.dart';
/// 会议详情控制器
class MeetingDetailsController extends GetxController
@ -407,6 +408,7 @@ class MeetingDetailsController extends GetxController
bool isdistinguishspeaker,
int templateid,
String tid,
TranscribeService serviceType,
) async {
EasyLoading.show();
_everType = 2;
@ -419,6 +421,7 @@ class MeetingDetailsController extends GetxController
isdistinguishspeaker,
templateid,
tid,
serviceType,
);
meetingDetails.value.tasktype = 1;
meetingDetails.refresh();

22
lib/modules/meeting/model/transcribe_service.dart

@ -0,0 +1,22 @@
// 与 proto 中 TranscribeService 枚举保持一致
enum TranscribeService {
unknown(0, 'Unknown'),
byteDance(1, 'ByteDance'),
ali(2, 'Ali'),
auto(3, 'Auto'),
google(4, 'Google'),
microsoft(5, 'Microsoft');
const TranscribeService(this.value, this.code);
final int value;
// 与后台 / env 字段(MeetServers)中保持一致的字符串编码
final String code;
static TranscribeService fromCode(String code) {
for (final s in TranscribeService.values) {
if (s.code.toLowerCase() == code.trim().toLowerCase()) return s;
}
return TranscribeService.auto;
}
}

49
lib/modules/meeting/views/bottomSheet/generate_bottom_sheet.dart

@ -5,7 +5,9 @@ import 'package:get/get.dart';
import 'package:get_storage/get_storage.dart';
import '../../controllers/meeting_details_controller.dart';
import '../../model/transcribe_service.dart';
import 'record_language_bottom_sheet.dart';
import 'transcribe_service_bottom_sheet.dart';
import '../template/template_view.dart';
import '../../../../data/models/user_Info.dart';
import '../../../common/widgets/recharge_dialog.dart';
@ -30,6 +32,7 @@ class _GenerateBottomSheetState extends State<GenerateBottomSheet> {
String _formlanguage = 'zh-CN';
String _tolanguageText = 'chineseSimplified'.tr; // 对应中文:中文普通话(简体)
String _tolanguage = 'zh-CN';
TranscribeService _serviceType = TranscribeService.auto;
final Map _icons = {
'auto_stories': Icons.auto_stories,
@ -309,7 +312,6 @@ class _GenerateBottomSheetState extends State<GenerateBottomSheet> {
_row(
'targetLanguage'.tr, // 对应中文:目标语言
value: _tolanguageText,
isBorder: false,
isDarkMode: isDarkMode,
onTap: () {
Get.bottomSheet(
@ -332,6 +334,33 @@ class _GenerateBottomSheetState extends State<GenerateBottomSheet> {
});
},
),
if (!widget.isSummarizeAgain)
_row(
'transcribeService'.tr, // 对应中文:转写服务
value: _serviceLabel(_serviceType),
isBorder: false,
isDarkMode: isDarkMode,
onTap: () {
Get.bottomSheet(
TranscribeServiceBottomSheet(_serviceType),
isScrollControlled: true,
backgroundColor: isDarkMode
? Colors.grey[850]
: Colors.grey[100],
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(
top: Radius.circular(12.r),
),
),
).then((value) {
if (value is TranscribeService) {
setState(() {
_serviceType = value;
});
}
});
},
),
],
),
),
@ -367,6 +396,7 @@ class _GenerateBottomSheetState extends State<GenerateBottomSheet> {
_isSpeaker,
_templateData['id'],
_templateData['tid'] ?? '',
_serviceType,
);
}
},
@ -550,6 +580,23 @@ class _GenerateBottomSheetState extends State<GenerateBottomSheet> {
);
}
String _serviceLabel(TranscribeService s) {
switch (s) {
case TranscribeService.auto:
return 'transcribeServiceAuto'.tr;
case TranscribeService.byteDance:
return 'transcribeServiceByteDance'.tr;
case TranscribeService.ali:
return 'transcribeServiceAli'.tr;
case TranscribeService.google:
return 'transcribeServiceGoogle'.tr;
case TranscribeService.microsoft:
return 'transcribeServiceMicrosoft'.tr;
case TranscribeService.unknown:
return s.code;
}
}
Widget _row(
String title, {
String? value,

173
lib/modules/meeting/views/bottomSheet/transcribe_service_bottom_sheet.dart

@ -0,0 +1,173 @@
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import '../../../../data/models/appconfig.dart';
import '../../model/transcribe_service.dart';
class TranscribeServiceBottomSheet extends StatefulWidget {
final TranscribeService selected;
const TranscribeServiceBottomSheet(this.selected, {super.key});
@override
State<TranscribeServiceBottomSheet> createState() =>
_TranscribeServiceBottomSheetState();
// 读取 env 中 MeetServers 字段并解析为可选服务列表(首项始终为 Auto)。
// env 形如:"ByteDance,Ali,Google,Microsoft"
static List<TranscribeService> resolveOptions() {
final raw = AppConfig.isInitialized()
? (AppConfig.env('MeetServers') ?? '')
: '';
const whitelist = {
TranscribeService.byteDance,
TranscribeService.ali,
TranscribeService.google,
TranscribeService.microsoft,
};
final result = <TranscribeService>[TranscribeService.auto];
for (final part in raw.split(',')) {
final s = TranscribeService.fromCode(part);
if (whitelist.contains(s) && !result.contains(s)) result.add(s);
}
return result;
}
}
class _TranscribeServiceBottomSheetState
extends State<TranscribeServiceBottomSheet> {
late final List<TranscribeService> _options;
@override
void initState() {
super.initState();
_options = TranscribeServiceBottomSheet.resolveOptions();
}
String _label(TranscribeService s) {
switch (s) {
case TranscribeService.auto:
return 'transcribeServiceAuto'.tr; // 对应中文:自动
case TranscribeService.byteDance:
return 'transcribeServiceByteDance'.tr; // 对应中文:字节跳动
case TranscribeService.ali:
return 'transcribeServiceAli'.tr; // 对应中文:阿里云
case TranscribeService.google:
return 'transcribeServiceGoogle'.tr; // 对应中文:谷歌
case TranscribeService.microsoft:
return 'transcribeServiceMicrosoft'.tr; // 对应中文:微软
case TranscribeService.unknown:
return s.code;
}
}
@override
Widget build(BuildContext context) {
final isDarkMode = Theme.of(context).brightness == Brightness.dark;
return SafeArea(
top: false,
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 12.w),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Container(
padding: EdgeInsets.symmetric(vertical: 10.w),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'transcribeService'.tr, // 对应中文:转写服务
style: TextStyle(
fontSize: 16.sp,
color: isDarkMode ? Colors.white : Colors.black87,
fontWeight: FontWeight.bold,
),
),
GestureDetector(
onTap: () => Get.back(),
child: Container(
width: 26.w,
height: 26.w,
decoration: BoxDecoration(
color: isDarkMode ? Colors.grey[700] : Colors.white,
borderRadius: BorderRadius.circular(26.r),
),
child: Icon(
Icons.close,
size: 18.w,
color: isDarkMode ? Colors.grey[300] : Colors.grey[400],
),
),
)
],
),
),
Divider(
height: 1,
color: isDarkMode ? Colors.grey[700] : Colors.grey[300],
),
Container(
margin: EdgeInsets.symmetric(vertical: 20.w),
constraints: BoxConstraints(
maxHeight: 1.sh - 180.w,
),
decoration: BoxDecoration(
color: isDarkMode ? const Color(0xFF2D2D2D) : Colors.white,
borderRadius: BorderRadius.circular(8.r),
),
child: ListView.builder(
itemCount: _options.length,
shrinkWrap: true,
itemBuilder: (BuildContext context, int index) {
return _item(index, _options[index], isDarkMode);
},
),
),
],
),
),
);
}
Widget _item(int index, TranscribeService data, bool isDarkMode) {
return GestureDetector(
onTap: () => Get.back(result: data),
child: Padding(
padding: EdgeInsets.only(left: 15.w),
child: Container(
height: 46.w,
padding: EdgeInsets.only(right: 10.w),
decoration: BoxDecoration(
border: index != 0
? Border(
top: BorderSide(
color: isDarkMode ? Colors.grey[700]! : Colors.grey[300]!,
),
)
: null,
),
child: Row(
children: [
Expanded(
child: Text(
_label(data),
style: TextStyle(
fontSize: 14.sp,
color: isDarkMode ? Colors.white : Colors.black87,
),
),
),
if (widget.selected == data)
Icon(
Icons.check,
color: isDarkMode ? Colors.white : Colors.black87,
),
],
),
),
),
);
}
}
Loading…
Cancel
Save