1.优化补足了首页下拉刷新中对获取场站接口的加入,确保能够实时获取数据并渲染。

2.优化修改了tcp重连机制,具体操作:断开重连时候不再建立新链接 而是将旧链接重置,并重新发送数据。
3.大面积的给项目中的各个页面 手动接入了多语言的支持。同时也调整了相应带来的问题英文长度较大影响原有的样式的问题,已解决了对应的样式不和谐问题。保证了外观的统一性。
4.给项目中的主要操作加了几个核心的操作比如远程遥控和路径规划添加了双层的保护,设置里安全模式,即在此期间对服务器推送的重复登录操作后的自动退出登录做一个拦截 保证操作的安全性。
This commit is contained in:
2026-07-02 16:04:30 +08:00
parent d5a83c1221
commit 0db64a96e7
69 changed files with 5018 additions and 1532 deletions

View File

@@ -1,5 +1,6 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:maibu_satabot_v2/core/localization/app_localizations.dart';
import '../constants/report_constants.dart';
/// 媒体上传模块
@@ -23,6 +24,7 @@ class MediaUploader extends StatelessWidget {
@override
Widget build(BuildContext context) {
final loc = AppLocalizations.of(context);
return Container(
margin: const EdgeInsets.symmetric(
horizontal: AppDimensions.horizontalPadding,
@@ -43,8 +45,8 @@ class MediaUploader extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'上传图片/视频',
style: TextStyle(
loc.translate('report.upload_media'),
style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.w600,
color: AppColors.textPrimary,
@@ -58,14 +60,14 @@ class MediaUploader extends StatelessWidget {
// 拍照按钮
_buildUploadButton(
icon: Icons.camera_alt,
label: '拍照',
label: loc.translate('report.take_photo'),
onTap: onCameraTap,
),
const SizedBox(width: 8),
// 录像按钮
_buildUploadButton(
icon: Icons.videocam,
label: '录像',
label: loc.translate('report.record_video'),
onTap: onVideoTap,
),
const SizedBox(width: 8),
@@ -74,84 +76,94 @@ class MediaUploader extends StatelessWidget {
final String filePath = entry.value;
final bool isNetworkImage = filePath.startsWith('http');
final bool isVideo = _isVideoFile(filePath);
return GestureDetector(
onTap: () => onTap?.call(entry.key),
child: Stack(
children: [
Container(
width: 80,
height: 80,
margin: const EdgeInsets.only(right: 8),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(AppDimensions.borderRadiusSmall),
color: AppColors.cardBackground,
),
child: ClipRRect(
borderRadius: BorderRadius.circular(AppDimensions.borderRadiusSmall),
child: isVideo
? _buildVideoThumbnail(filePath)
: (isNetworkImage
? Image.network(
filePath,
fit: BoxFit.cover,
errorBuilder: (context, error, stackTrace) {
return _buildPlaceholderIcon(Icons.broken_image);
},
)
: Image.file(
File(filePath),
fit: BoxFit.cover,
errorBuilder: (context, error, stackTrace) {
return _buildPlaceholderIcon(Icons.broken_image);
},
)),
),
),
Positioned(
top: 4,
right: 12,
child: GestureDetector(
onTap: () => onRemove(entry.key),
child: Container(
width: 20,
height: 20,
decoration: const BoxDecoration(
color: Colors.black54,
shape: BoxShape.circle,
children: [
Container(
width: 80,
height: 80,
margin: const EdgeInsets.only(right: 8),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(
AppDimensions.borderRadiusSmall,
),
child: const Icon(
Icons.close,
size: 14,
color: Colors.white,
color: AppColors.cardBackground,
),
child: ClipRRect(
borderRadius: BorderRadius.circular(
AppDimensions.borderRadiusSmall,
),
child: isVideo
? _buildVideoThumbnail(filePath)
: (isNetworkImage
? Image.network(
filePath,
fit: BoxFit.cover,
errorBuilder:
(context, error, stackTrace) {
return _buildPlaceholderIcon(
Icons.broken_image,
);
},
)
: Image.file(
File(filePath),
fit: BoxFit.cover,
errorBuilder:
(context, error, stackTrace) {
return _buildPlaceholderIcon(
Icons.broken_image,
);
},
)),
),
),
),
// 视频播放图标
if (isVideo)
Positioned(
child: Container(
width: 80,
height: 80,
margin: const EdgeInsets.only(right: 8),
alignment: Alignment.center,
top: 4,
right: 12,
child: GestureDetector(
onTap: () => onRemove(entry.key),
child: Container(
padding: const EdgeInsets.all(8),
width: 20,
height: 20,
decoration: const BoxDecoration(
color: Colors.black38,
color: Colors.black54,
shape: BoxShape.circle,
),
child: const Icon(
Icons.play_arrow,
Icons.close,
size: 14,
color: Colors.white,
size: 24,
),
),
),
),
],
),
// 视频播放图标
if (isVideo)
Positioned(
child: Container(
width: 80,
height: 80,
margin: const EdgeInsets.only(right: 8),
alignment: Alignment.center,
child: Container(
padding: const EdgeInsets.all(8),
decoration: const BoxDecoration(
color: Colors.black38,
shape: BoxShape.circle,
),
child: const Icon(
Icons.play_arrow,
color: Colors.white,
size: 24,
),
),
),
),
],
),
);
}).toList(),
// 添加按钮
@@ -228,17 +240,9 @@ class MediaUploader extends StatelessWidget {
fit: StackFit.expand,
children: [
// 灰色背景
Container(
color: Colors.grey[300],
),
Container(color: Colors.grey[300]),
// 视频图标
const Center(
child: Icon(
Icons.videocam,
color: Colors.grey,
size: 32,
),
),
const Center(child: Icon(Icons.videocam, color: Colors.grey, size: 32)),
],
);
}
@@ -247,13 +251,7 @@ class MediaUploader extends StatelessWidget {
Widget _buildPlaceholderIcon(IconData icon) {
return Container(
color: Colors.grey[300],
child: Center(
child: Icon(
icon,
color: Colors.grey,
size: 32,
),
),
child: Center(child: Icon(icon, color: Colors.grey, size: 32)),
);
}
}