Compare commits
2 Commits
b6334867c5
...
26c64aa5ea
| Author | SHA1 | Date |
|---|---|---|
|
|
26c64aa5ea | |
|
|
96face82a6 |
|
|
@ -60,7 +60,7 @@ class BaiduMapWebView extends StatelessWidget {
|
|||
const SizedBox(height: 8),
|
||||
const Text('地图未初始化'),
|
||||
const SizedBox(height: 12),
|
||||
ElevatedButton(onPressed: onRetry, child: const Text('重试初始化')),
|
||||
CustomButton(text: '重试初始化', backgroundColor: Colors.blue, onPressed: onRetry,),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
|
|
|||
|
|
@ -30,32 +30,20 @@ class _MapPageState extends State<MapPage> {
|
|||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_initLocation();
|
||||
_loadWebView();
|
||||
}
|
||||
|
||||
/// 获取定位(并初始化 WebView 控制器)
|
||||
Future<void> _initLocation() async {
|
||||
setState(() {
|
||||
_isLoading = true;
|
||||
_errorMessage = null;
|
||||
});
|
||||
try {
|
||||
await fetchAndSaveBd09(context);
|
||||
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
String latitude = prefs.getString('bd_lat') ?? '';
|
||||
String longitude = prefs.getString('bd_lon') ?? '';
|
||||
_loadWebView(LocationResult(latitude: latitude, longitude: longitude));
|
||||
|
||||
} catch (e, st) {
|
||||
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
String latitude = prefs.getString('bd_lat') ?? '';
|
||||
String longitude = prefs.getString('bd_lon') ?? '';
|
||||
_loadWebView(LocationResult(latitude: latitude, longitude: longitude));
|
||||
}
|
||||
}
|
||||
Future<void> _loadWebView(LocationResult loc) async {
|
||||
// Future<void> _initLocation() async {
|
||||
// setState(() {
|
||||
// _isLoading = true;
|
||||
// _errorMessage = null;
|
||||
// });
|
||||
// Map<String, double> prefs = geographicCentroid(_gsonList);
|
||||
// _loadWebView(LocationResult(latitude: prefs['lat'].toString(), longitude: prefs['lon'].toString()));
|
||||
//
|
||||
// }
|
||||
Future<void> _loadWebView() async {
|
||||
// 解析 gson
|
||||
try {
|
||||
final parsed = jsonDecode(widget.gson);
|
||||
|
|
@ -69,11 +57,14 @@ class _MapPageState extends State<MapPage> {
|
|||
_gsonList = [];
|
||||
}
|
||||
if (!mounted) return;
|
||||
|
||||
Map<String, double> prefs = geographicCentroid(_gsonList);
|
||||
// _loadWebView(LocationResult(latitude: prefs['lat'].toString(), longitude: prefs['lon'].toString()));
|
||||
setState(() {
|
||||
_longitude = loc.longitudeAsDouble;
|
||||
_latitude = loc.latitudeAsDouble;
|
||||
_longitude = prefs['lon'];
|
||||
_latitude = prefs['lat'];
|
||||
});
|
||||
|
||||
|
||||
// 初始化 WebViewController 并加载本地页面
|
||||
_controller = WebViewController()
|
||||
..setJavaScriptMode(JavaScriptMode.unrestricted)
|
||||
|
|
@ -132,6 +123,7 @@ class _MapPageState extends State<MapPage> {
|
|||
'GSON': _gsonList,
|
||||
't': DateTime.now().millisecondsSinceEpoch,
|
||||
};
|
||||
debugPrint('网页初始化参数: ${jsonEncode(params)}');
|
||||
|
||||
final jsonParams = jsonEncode(params);
|
||||
|
||||
|
|
@ -198,7 +190,7 @@ class _MapPageState extends State<MapPage> {
|
|||
controller: _isLoading || _errorMessage != null ? null : _controller,
|
||||
isLoading: _isLoading,
|
||||
errorMessage: _errorMessage,
|
||||
onRetry: _initLocation,
|
||||
onRetry: _loadWebView,
|
||||
),),
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import 'package:flutter/material.dart';
|
||||
/// 自定义默认按钮(支持不可点击/禁用状态)
|
||||
class CustomButton extends StatelessWidget {
|
||||
|
||||
/// 自定义默认按钮(支持不可点击/禁用状态和防连点功能)
|
||||
class CustomButton extends StatefulWidget {
|
||||
final String text; // 按钮文字
|
||||
final Color backgroundColor; // 按钮背景色
|
||||
final double borderRadius; // 圆角半径(默认5)
|
||||
|
|
@ -20,6 +21,9 @@ class CustomButton extends StatelessWidget {
|
|||
/// 新增:禁用时的文字颜色(可选)
|
||||
final Color? disabledTextColor;
|
||||
|
||||
/// 新增:防连点间隔时间(毫秒)
|
||||
final int debounceInterval;
|
||||
|
||||
const CustomButton({
|
||||
super.key,
|
||||
required this.text,
|
||||
|
|
@ -33,51 +37,75 @@ class CustomButton extends StatelessWidget {
|
|||
this.enabled = true,
|
||||
this.disabledBackgroundColor,
|
||||
this.disabledTextColor,
|
||||
this.debounceInterval = 1000, // 默认1秒防连点
|
||||
});
|
||||
|
||||
@override
|
||||
State<CustomButton> createState() => _CustomButtonState();
|
||||
}
|
||||
|
||||
class _CustomButtonState extends State<CustomButton> {
|
||||
// 记录最后一次点击时间
|
||||
DateTime _lastClickTime = DateTime(0);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
// 如果 enabled 为 false 或 onPressed 为 null,则视为不可点击
|
||||
final bool isEnabled = enabled && onPressed != null;
|
||||
final bool isEnabled = widget.enabled && widget.onPressed != null;
|
||||
|
||||
// 计算展示用背景色与文字样式
|
||||
final Color bgColor = isEnabled
|
||||
? backgroundColor
|
||||
: (disabledBackgroundColor ?? Colors.grey.shade400);
|
||||
? widget.backgroundColor
|
||||
: (widget.disabledBackgroundColor ?? Colors.grey.shade400);
|
||||
|
||||
TextStyle finalTextStyle;
|
||||
if (textStyle != null) {
|
||||
if (widget.textStyle != null) {
|
||||
finalTextStyle = isEnabled
|
||||
? textStyle!
|
||||
: textStyle!.copyWith(
|
||||
color: disabledTextColor ?? textStyle!.color?.withOpacity(0.8) ?? Colors.white70,
|
||||
? widget.textStyle!
|
||||
: widget.textStyle!.copyWith(
|
||||
color: widget.disabledTextColor ?? widget.textStyle!.color?.withOpacity(0.8) ?? Colors.white70,
|
||||
);
|
||||
} else {
|
||||
finalTextStyle = TextStyle(
|
||||
color: isEnabled ? Colors.white : (disabledTextColor ?? Colors.white70),
|
||||
color: isEnabled ? Colors.white : (widget.disabledTextColor ?? Colors.white70),
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.bold,
|
||||
);
|
||||
}
|
||||
|
||||
// 处理点击事件(添加防连点逻辑)
|
||||
void handleOnPressed() {
|
||||
final now = DateTime.now();
|
||||
if (now.difference(_lastClickTime).inMilliseconds < widget.debounceInterval) {
|
||||
// 在防连点间隔内,不执行操作
|
||||
return;
|
||||
}
|
||||
|
||||
_lastClickTime = now;
|
||||
|
||||
if (widget.onPressed != null) {
|
||||
widget.onPressed!();
|
||||
}
|
||||
}
|
||||
|
||||
// 点击拦截器 + 视觉反馈(禁用时降低不透明度)
|
||||
return Opacity(
|
||||
opacity: isEnabled ? 1.0 : 0.65,
|
||||
child: AbsorbPointer(
|
||||
absorbing: !isEnabled,
|
||||
child: GestureDetector(
|
||||
onTap: isEnabled ? onPressed : null,
|
||||
onTap: isEnabled ? handleOnPressed : null,
|
||||
child: Container(
|
||||
height: height ?? 45, // 默认高度45
|
||||
padding: padding ?? const EdgeInsets.all(6), // 默认内边距
|
||||
margin: margin ?? const EdgeInsets.symmetric(horizontal: 5), // 默认外边距
|
||||
height: widget.height ?? 45, // 默认高度45
|
||||
padding: widget.padding ?? const EdgeInsets.all(6), // 默认内边距
|
||||
margin: widget.margin ?? const EdgeInsets.symmetric(horizontal: 5), // 默认外边距
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(borderRadius),
|
||||
borderRadius: BorderRadius.circular(widget.borderRadius),
|
||||
color: bgColor,
|
||||
),
|
||||
child: Center(
|
||||
child: Text(
|
||||
text,
|
||||
widget.text,
|
||||
style: finalTextStyle,
|
||||
),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import 'dart:io';
|
||||
import 'package:device_info_plus/device_info_plus.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:image_picker/image_picker.dart';
|
||||
|
|
@ -6,6 +7,7 @@ import 'package:permission_handler/permission_handler.dart';
|
|||
import 'package:qhd_prevention/customWidget/custom_alert_dialog.dart';
|
||||
import 'package:qhd_prevention/customWidget/full_screen_video_page.dart';
|
||||
import 'package:qhd_prevention/customWidget/single_image_viewer.dart';
|
||||
import 'package:qhd_prevention/customWidget/toast_util.dart';
|
||||
import 'package:qhd_prevention/tools/tools.dart';
|
||||
import 'package:video_compress/video_compress.dart';
|
||||
import 'package:wechat_assets_picker/wechat_assets_picker.dart';
|
||||
|
|
@ -95,9 +97,7 @@ class _MediaPickerGridState extends State<MediaPickerRow> {
|
|||
} catch (e) {
|
||||
debugPrint('❌ 视频转码失败: $e');
|
||||
if (mounted) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text('视频转码失败: ${e.toString()}')),
|
||||
);
|
||||
ToastUtil.showNormal(context, '视频转码失败');
|
||||
}
|
||||
return;
|
||||
} finally {
|
||||
|
|
@ -206,9 +206,7 @@ class _MediaPickerGridState extends State<MediaPickerRow> {
|
|||
if (permission != PermissionState.authorized &&
|
||||
permission != PermissionState.limited) {
|
||||
if (mounted) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(content: Text('请到设置中开启相册访问权限')),
|
||||
);
|
||||
ToastUtil.showNormal(context, '请到设置中开启相册访问权限');
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
@ -245,24 +243,41 @@ class _MediaPickerGridState extends State<MediaPickerRow> {
|
|||
}
|
||||
|
||||
} else {
|
||||
// Android: 使用 permission_handler 请求存储权限(简单处理)
|
||||
final PermissionStatus current = await Permission.storage.status;
|
||||
PermissionStatus status;
|
||||
if (current.isGranted) {
|
||||
status = PermissionStatus.granted;
|
||||
// Android: 更可靠地请求权限(适配不同 Android 版本)
|
||||
final DeviceInfoPlugin deviceInfo = DeviceInfoPlugin();
|
||||
final androidInfo = await deviceInfo.androidInfo;
|
||||
final int sdkInt = androidInfo.version.sdkInt ?? 0;
|
||||
|
||||
PermissionStatus permissionStatus = PermissionStatus.denied;
|
||||
|
||||
if (sdkInt >= 33) {
|
||||
// Android 13+: 使用更细粒度的媒体权限
|
||||
// 如果应用只选图片,request photos;只选视频则 request videos;若两者都可能同时需要,可请求两个。
|
||||
if (widget.mediaType == MediaType.image) {
|
||||
permissionStatus = await Permission.photos.request(); // maps to READ_MEDIA_IMAGES on Android
|
||||
} else if (widget.mediaType == MediaType.video) {
|
||||
permissionStatus = await Permission.videos.request(); // maps to READ_MEDIA_VIDEO
|
||||
} else {
|
||||
status = await Permission.storage.request();
|
||||
// 两者皆可(同时请求会合并成单个系统对话)
|
||||
final statuses = await [Permission.photos, Permission.videos].request();
|
||||
permissionStatus = statuses[Permission.photos] ?? statuses[Permission.videos] ?? PermissionStatus.denied;
|
||||
}
|
||||
} else if (sdkInt >= 30) {
|
||||
// Android 11/12: 通常仍然使用 READ_EXTERNAL_STORAGE;若需要“全部文件访问”,要 request manageExternalStorage(慎用)
|
||||
permissionStatus = await Permission.storage.request();
|
||||
} else {
|
||||
// Android 10 及以下
|
||||
permissionStatus = await Permission.storage.request();
|
||||
}
|
||||
|
||||
debugPrint('Android storage permission: $status');
|
||||
|
||||
if (status == PermissionStatus.granted) {
|
||||
// 处理结果
|
||||
if (permissionStatus.isGranted) {
|
||||
// 有权限:继续打开 AssetPicker
|
||||
final remaining = widget.maxCount - _mediaPaths.length;
|
||||
final List<AssetEntity>? assets = await AssetPicker.pickAssets(
|
||||
context,
|
||||
pickerConfig: AssetPickerConfig(
|
||||
requestType:
|
||||
widget.mediaType == MediaType.image ? RequestType.image : RequestType.video,
|
||||
requestType: widget.mediaType == MediaType.image ? RequestType.image : RequestType.video,
|
||||
maxAssets: remaining,
|
||||
gridCount: 4,
|
||||
),
|
||||
|
|
@ -286,19 +301,18 @@ class _MediaPickerGridState extends State<MediaPickerRow> {
|
|||
if (mounted) setState(() {});
|
||||
widget.onChanged(_mediaPaths.map((p) => File(p)).toList());
|
||||
}
|
||||
} else if (status == PermissionStatus.permanentlyDenied) {
|
||||
} else if (permissionStatus.isPermanentlyDenied) {
|
||||
// 用户点了“不再询问”或系统拒绝弹窗,跳转设置页并提示
|
||||
if (mounted) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(content: Text('请到设置中开启相册访问权限')),
|
||||
);
|
||||
ToastUtil.showNormal(context, '请到设置中开启相册访问权限');
|
||||
}
|
||||
await openAppSettings();
|
||||
return;
|
||||
} else {
|
||||
if (mounted) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(content: Text('相册访问权限被拒绝')),
|
||||
);
|
||||
ToastUtil.showNormal(context, '相册访问权限被拒绝');
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
} catch (e, st) {
|
||||
|
|
@ -326,7 +340,6 @@ class _MediaPickerGridState extends State<MediaPickerRow> {
|
|||
}
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
if (widget.mediaType == MediaType.image) {
|
||||
XFile? picked = await _picker.pickImage(source: ImageSource.camera);
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ class _PromisePageState extends State<PromisePage> {
|
|||
setState(() {
|
||||
info['FILEPATH'] = path;
|
||||
});
|
||||
FocusHelper.clearFocus(context);
|
||||
//FocusHelper.clearFocus(context);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import 'dart:io';
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:pdfx/pdfx.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'package:qhd_prevention/customWidget/toast_util.dart';
|
||||
import 'package:qhd_prevention/pages/my_appbar.dart';
|
||||
import 'package:qhd_prevention/customWidget/custom_button.dart';
|
||||
import 'package:dio/dio.dart';
|
||||
|
|
@ -69,9 +70,8 @@ class _RemoteFilePageState extends State<RemoteFilePage> {
|
|||
setState(() {
|
||||
_isLoading = false;
|
||||
});
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text('文件加载失败: $e')),
|
||||
);
|
||||
|
||||
ToastUtil.showNormal(context, '文件加载失败: $e');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1282,6 +1282,7 @@ U6Hzm1ninpWeE+awIDAQAB
|
|||
static Future<Map<String, dynamic>> safeKeyprojectCheckSubmit(Map data) {
|
||||
return HttpManager().request(
|
||||
basePath,
|
||||
// 'http://192.168.0.45:28199',
|
||||
'/app/keyprojectcheck/add',
|
||||
method: Method.post,
|
||||
data: {...data},
|
||||
|
|
|
|||
|
|
@ -21,8 +21,8 @@ enum Method { get, post, put, delete }
|
|||
class HttpManager {
|
||||
HttpManager._internal() {
|
||||
_dio = Dio(BaseOptions(
|
||||
connectTimeout: const Duration(milliseconds: 10000),
|
||||
receiveTimeout: const Duration(milliseconds: 10000),
|
||||
connectTimeout: const Duration(milliseconds: 20000),
|
||||
receiveTimeout: const Duration(milliseconds: 20000),
|
||||
headers: {
|
||||
'Content-Type': Headers.formUrlEncodedContentType,
|
||||
},
|
||||
|
|
@ -96,7 +96,6 @@ class HttpManager {
|
|||
);
|
||||
|
||||
try {
|
||||
print("======>$data");
|
||||
switch (method) {
|
||||
case Method.get:
|
||||
resp = await _dio.get(url,
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ class GlobalMessage {
|
|||
Future<T?> showDialogAfterUnfocus<T>(
|
||||
BuildContext context,
|
||||
Widget dialog,
|
||||
) async {
|
||||
) async {
|
||||
// 取消焦点并尝试隐藏键盘
|
||||
FocusScope.of(context).unfocus();
|
||||
try {
|
||||
|
|
@ -136,9 +136,9 @@ class MyApp extends StatelessWidget {
|
|||
GlobalWidgetsLocalizations.delegate,
|
||||
// 如果使用了其他本地化包,请添加对应的 delegate
|
||||
],
|
||||
supportedLocales: [
|
||||
const Locale('zh', 'CN'), // 中文
|
||||
const Locale('en', 'US'), // 英文(备用)
|
||||
supportedLocales: const [
|
||||
Locale('zh', 'CN'), // 中文
|
||||
Locale('en', 'US'), // 英文(备用)
|
||||
],
|
||||
locale: const Locale('zh', 'CN'),
|
||||
// 强制使用中文
|
||||
|
|
@ -146,9 +146,16 @@ class MyApp extends StatelessWidget {
|
|||
// 在路由变化时统一取消焦点(防止 push/pop 时焦点回到 TextField)
|
||||
navigatorObservers: [KeyboardUnfocusNavigatorObserver(), routeObserver],
|
||||
builder: (context, child) {
|
||||
// 使用 EasyLoading.init,同时在其内部把 textScaleFactor 固定为 1.0
|
||||
return EasyLoading.init(
|
||||
builder: (context, widget) {
|
||||
return GestureDetector(
|
||||
// 拿到当前 MediaQuery 并创建一个 textScaleFactor = 1.0 的副本
|
||||
final mq = MediaQuery.maybeOf(context) ?? MediaQueryData.fromWindow(WidgetsBinding.instance.window);
|
||||
final fixed = mq.copyWith(textScaleFactor: 1.0);
|
||||
|
||||
return MediaQuery(
|
||||
data: fixed,
|
||||
child: GestureDetector(
|
||||
behavior: HitTestBehavior.translucent,
|
||||
onTap: () {
|
||||
// 全局点击空白处取消焦点(隐藏键盘)
|
||||
|
|
@ -159,6 +166,7 @@ class MyApp extends StatelessWidget {
|
|||
}
|
||||
},
|
||||
child: widget,
|
||||
),
|
||||
);
|
||||
},
|
||||
)(context, child);
|
||||
|
|
|
|||
|
|
@ -90,7 +90,8 @@ class _CheckListPageState extends State<CheckListPage> {
|
|||
}
|
||||
|
||||
void _goToDetail(Map<String, dynamic> item) async {
|
||||
pushPage(SafecheckDetail(OUTSOURCED_ID: widget.OUTSOURCED_ID,KEYPROJECTCHECK_ID: item['KEYPROJECTCHECK_ID'], isEdit: false,), context);
|
||||
await pushPage(SafecheckDetail(OUTSOURCED_ID: widget.OUTSOURCED_ID,KEYPROJECTCHECK_ID: item['KEYPROJECTCHECK_ID'], isEdit: false,), context);
|
||||
_fetchData();
|
||||
}
|
||||
|
||||
Widget _buildListItem(Map<String, dynamic> item) {
|
||||
|
|
@ -199,8 +200,9 @@ class _CheckListPageState extends State<CheckListPage> {
|
|||
return Scaffold(
|
||||
key: _scaffoldKey,
|
||||
appBar: MyAppbar(title: '安全检查记录', actions: [
|
||||
TextButton(onPressed: () {
|
||||
pushPage(SafecheckDetail(OUTSOURCED_ID: widget.OUTSOURCED_ID,KEYPROJECTCHECK_ID: '', isEdit: true,), context);
|
||||
TextButton(onPressed: () async {
|
||||
await pushPage(SafecheckDetail(OUTSOURCED_ID: widget.OUTSOURCED_ID,KEYPROJECTCHECK_ID: '', isEdit: true,), context);
|
||||
_fetchData();
|
||||
}, child: Text('发起', style: TextStyle(color: Colors.white, fontSize: 16),))
|
||||
],),
|
||||
|
||||
|
|
|
|||
|
|
@ -11,9 +11,9 @@ Widget HiddenListTable({
|
|||
required void Function(Map<String, dynamic> item, int index) removeHidden,
|
||||
required BuildContext context,
|
||||
}) {
|
||||
Widget _buildCell(String text, {bool isHeader = false, Alignment alignment = Alignment.center, double minWidth = 50}) {
|
||||
Widget _buildCell(String text, {bool isHeader = false, Alignment alignment = Alignment.center, double minWidth = 40}) {
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 10),
|
||||
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 5),
|
||||
alignment: alignment,
|
||||
child: ConstrainedBox(
|
||||
constraints: BoxConstraints(minWidth: minWidth),
|
||||
|
|
@ -29,7 +29,6 @@ Widget HiddenListTable({
|
|||
);
|
||||
}
|
||||
|
||||
// 仍保留 Table 的 header 用法(用于有数据时)
|
||||
TableRow _buildHeader() {
|
||||
return TableRow(
|
||||
decoration: BoxDecoration(color: Colors.grey.shade200),
|
||||
|
|
@ -59,38 +58,41 @@ Widget HiddenListTable({
|
|||
_buildCell(descr),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 6),
|
||||
child: Align(
|
||||
alignment: Alignment.center,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
IconButton(
|
||||
icon: const Icon(Icons.info_outline, size: 22, color: Colors.blue),
|
||||
icon: const Icon(Icons.info_outline, size: 20, color: Colors.blue,),
|
||||
onPressed: () => showHidden(item, index),
|
||||
tooltip: '查看',
|
||||
padding: EdgeInsets.zero,
|
||||
constraints: const BoxConstraints(),
|
||||
padding: const EdgeInsets.all(4),
|
||||
constraints: const BoxConstraints(minWidth: 24, minHeight: 24),
|
||||
visualDensity: VisualDensity.compact,
|
||||
),
|
||||
if (forbidEdit) // 注意:原逻辑保留,如需反向请改为 if (!forbidEdit)
|
||||
if (forbidEdit)
|
||||
IconButton(
|
||||
icon: const Icon(Icons.delete_outline, size: 22, color: Colors.red),
|
||||
icon: const Icon(Icons.delete_outline, size: 20, color: Colors.red,),
|
||||
onPressed: () => removeHidden(item, index),
|
||||
tooltip: '删除',
|
||||
padding: EdgeInsets.zero,
|
||||
constraints: const BoxConstraints(),
|
||||
padding: const EdgeInsets.all(4),
|
||||
constraints: const BoxConstraints(minWidth: 24, minHeight: 24),
|
||||
visualDensity: VisualDensity.compact,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
// 当 hiddenList 为空时,单独渲染表头(使用 Row + Expanded 来模仿 Table 的列宽)
|
||||
Widget _buildHeaderRowWidget() {
|
||||
return Container(
|
||||
decoration: BoxDecoration(color: Colors.grey.shade200),
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(flex: 2, child: _buildCell('序号', isHeader: true, alignment: Alignment.center)),
|
||||
Expanded(flex: 1, child: _buildCell('序号', isHeader: true, alignment: Alignment.center)),
|
||||
Expanded(flex: 3, child: _buildCell('隐患部位', isHeader: true)),
|
||||
Expanded(flex: 3, child: _buildCell('隐患描述', isHeader: true)),
|
||||
Expanded(flex: 3, child: _buildCell('操作', isHeader: true, alignment: Alignment.center)),
|
||||
|
|
@ -99,9 +101,14 @@ Widget HiddenListTable({
|
|||
);
|
||||
}
|
||||
|
||||
final tableWidth = MediaQuery.of(context).size.width - 50;
|
||||
// 用 LayoutBuilder 安全获取可用宽度(避免直接依赖 MediaQuery.of(context) 的 null 问题)
|
||||
return LayoutBuilder(builder: (ctx, constraints) {
|
||||
// 优先使用父级给出的约束宽度,否则退回到可选的 MediaQuery,再 fallback 一个合理值
|
||||
final double availableWidth = (constraints.maxWidth != double.infinity && constraints.maxWidth > 0)
|
||||
? constraints.maxWidth
|
||||
: ((MediaQuery.maybeOf(ctx)?.size.width ?? 400.0));
|
||||
final tableWidth = (availableWidth - 20).clamp(200.0, double.infinity);
|
||||
|
||||
// 如果没有数据,返回“表头 + 跨列居中显示暂无数据”的布局
|
||||
if (hiddenList.isEmpty) {
|
||||
return SingleChildScrollView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
|
|
@ -130,7 +137,6 @@ Widget HiddenListTable({
|
|||
);
|
||||
}
|
||||
|
||||
// 否则,使用原来的 Table 渲染有数据的行
|
||||
return SingleChildScrollView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
child: SizedBox(
|
||||
|
|
@ -138,19 +144,21 @@ Widget HiddenListTable({
|
|||
child: Table(
|
||||
defaultVerticalAlignment: TableCellVerticalAlignment.middle,
|
||||
columnWidths: const {
|
||||
0: FlexColumnWidth(2), // 序号
|
||||
1: FlexColumnWidth(3), // 隐患部位
|
||||
2: FlexColumnWidth(3), // 隐患描述
|
||||
3: FlexColumnWidth(3), // 操作按钮
|
||||
0: FlexColumnWidth(1),
|
||||
1: FlexColumnWidth(3),
|
||||
2: FlexColumnWidth(3),
|
||||
3: FlexColumnWidth(3),
|
||||
},
|
||||
border: TableBorder.symmetric(
|
||||
inside: BorderSide(color: Colors.grey.shade300, width: 0.5),
|
||||
),
|
||||
// 把 map 转成 List<TableRow> 更明确、避免惰性展开可能的问题
|
||||
children: [
|
||||
_buildHeader(),
|
||||
...hiddenList.asMap().entries.map((e) => _buildRow(e.value, e.key)),
|
||||
...hiddenList.asMap().entries.map((e) => _buildRow(e.value, e.key)).toList(),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,21 +2,14 @@ import 'dart:convert';
|
|||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:geolocator/geolocator.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:qhd_prevention/customWidget/ItemWidgetFactory.dart';
|
||||
import 'package:qhd_prevention/customWidget/bottom_picker.dart';
|
||||
import 'package:qhd_prevention/customWidget/bottom_picker_two.dart';
|
||||
import 'package:qhd_prevention/customWidget/custom_button.dart';
|
||||
import 'package:qhd_prevention/customWidget/date_picker_dialog.dart';
|
||||
import 'package:qhd_prevention/customWidget/department_person_picker.dart';
|
||||
import 'package:qhd_prevention/customWidget/department_picker_hidden_type.dart';
|
||||
import 'package:qhd_prevention/customWidget/department_picker_two.dart';
|
||||
import 'package:qhd_prevention/customWidget/full_screen_video_page.dart';
|
||||
import 'package:qhd_prevention/customWidget/picker/CupertinoDatePicker.dart';
|
||||
import 'package:qhd_prevention/customWidget/single_image_viewer.dart';
|
||||
import 'package:qhd_prevention/customWidget/toast_util.dart';
|
||||
import 'package:qhd_prevention/customWidget/video_player_widget.dart';
|
||||
import 'package:qhd_prevention/pages/home/tap/item_list_widget.dart';
|
||||
import 'package:qhd_prevention/tools/tools.dart';
|
||||
import '../../../../customWidget/photo_picker_row.dart';
|
||||
|
|
@ -428,18 +421,14 @@ class _SafeDrawerPageState extends State<SafeDrawerPage> {
|
|||
|
||||
Future<void> _pickHazardLevel() async {
|
||||
if (_hazardLevels.isEmpty) return ToastUtil.showNormal(context, '隐患级别数据为空');
|
||||
final choice = await BottomPickerTwo.show<String>(
|
||||
final found = await BottomPicker.show(
|
||||
context,
|
||||
items: _hazardLevels,
|
||||
itemBuilder: (i) => Text(i['NAME'], textAlign: TextAlign.center),
|
||||
initialIndex: 0,
|
||||
);
|
||||
FocusHelper.clearFocus(context);
|
||||
if (choice == null) return;
|
||||
final found = _hazardLevels.firstWhere(
|
||||
(e) => e['NAME'] == choice,
|
||||
orElse: () => null,
|
||||
);
|
||||
//FocusHelper.clearFocus(context);
|
||||
|
||||
if (found != null) {
|
||||
setState(() {
|
||||
hiddenForm['HIDDENLEVEL'] = found['BIANMA'] ?? found['id'] ?? '';
|
||||
|
|
@ -503,7 +492,7 @@ class _SafeDrawerPageState extends State<SafeDrawerPage> {
|
|||
hiddenForm['RECTIFICATIONDEPT'] = target?['UNITS_ID'] ?? '';
|
||||
_getUnitPerson();
|
||||
|
||||
FocusHelper.clearFocus(context);
|
||||
//FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -537,7 +526,7 @@ class _SafeDrawerPageState extends State<SafeDrawerPage> {
|
|||
orElse: () => {},
|
||||
);
|
||||
hiddenForm['RECTIFICATIONOR'] = target?['PERSONNELMANAGEMENT_ID'];
|
||||
FocusHelper.clearFocus(context);
|
||||
//FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -549,7 +538,7 @@ class _SafeDrawerPageState extends State<SafeDrawerPage> {
|
|||
final selectData = DateFormat('yyyy-MM-dd HH:mm').format(picked);
|
||||
hiddenForm['RECTIFICATIONDEADLINE'] = selectData;
|
||||
});
|
||||
FocusHelper.clearFocus(context);
|
||||
//FocusHelper.clearFocus(context);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
|
|
@ -169,7 +170,9 @@ class _SafecheckDetailState extends State<SafecheckDetail> {
|
|||
|
||||
Future<void> _getData() async {
|
||||
try {
|
||||
final result = await ApiService.getSafeCheckGoEdit(widget.KEYPROJECTCHECK_ID);
|
||||
final result = await ApiService.getSafeCheckGoEdit(
|
||||
widget.KEYPROJECTCHECK_ID,
|
||||
);
|
||||
// 在 await 之后检查 mounted,避免页面已经被 pop 导致 setState 报错
|
||||
if (!mounted) return;
|
||||
setState(() {
|
||||
|
|
@ -228,15 +231,19 @@ class _SafecheckDetailState extends State<SafecheckDetail> {
|
|||
}
|
||||
|
||||
try {
|
||||
final toUnitListData = await ApiService.getSafeCheckToUnitList(widget.OUTSOURCED_ID);
|
||||
final toUnitListData = await ApiService.getSafeCheckToUnitList(
|
||||
widget.OUTSOURCED_ID,
|
||||
);
|
||||
if (!mounted) return;
|
||||
setState(() {
|
||||
toCheckUnitList = toUnitListData['varList'] ?? [];
|
||||
// 仅在没有选择时自动回填
|
||||
if (!FormUtils.hasValue(form, 'UNITS_NAME') && toCheckUnitList.isNotEmpty) {
|
||||
if (!FormUtils.hasValue(form, 'UNITS_NAME') &&
|
||||
toCheckUnitList.isNotEmpty) {
|
||||
form['UNITS_NAME'] = toCheckUnitList.first['UNITS_NAME'];
|
||||
}
|
||||
if (!FormUtils.hasValue(form, 'UNITS_ID') && toCheckUnitList.isNotEmpty) {
|
||||
if (!FormUtils.hasValue(form, 'UNITS_ID') &&
|
||||
toCheckUnitList.isNotEmpty) {
|
||||
form['UNITS_ID'] = toCheckUnitList.first['UNITS_ID'];
|
||||
}
|
||||
});
|
||||
|
|
@ -266,7 +273,7 @@ class _SafecheckDetailState extends State<SafecheckDetail> {
|
|||
form['PERSONNELMANAGEMENT_ID'] = data['PERSONNELMANAGEMENT_ID'];
|
||||
form['INSPECTED_SITEUSER_INDEX'] = personList.indexOf(data);
|
||||
|
||||
FocusHelper.clearFocus(context);
|
||||
//FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -285,7 +292,7 @@ class _SafecheckDetailState extends State<SafecheckDetail> {
|
|||
final data = FormUtils.findMapForKeyValue(typeList, 'name', choice);
|
||||
form['INSPECTION_TYPE'] = data['id'];
|
||||
|
||||
FocusHelper.clearFocus(context);
|
||||
//FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -412,7 +419,6 @@ class _SafecheckDetailState extends State<SafecheckDetail> {
|
|||
Future<void> _submit() async {
|
||||
if (!widget.isEdit) {
|
||||
Navigator.of(context).pop();
|
||||
|
||||
return;
|
||||
}
|
||||
bool required = true;
|
||||
|
|
@ -537,11 +543,17 @@ class _SafecheckDetailState extends State<SafecheckDetail> {
|
|||
'INSPECTION_USER_NAME': loginUser['NAME'] ?? '',
|
||||
});
|
||||
}
|
||||
// 使用 Expando 标记已访问对象,防止循环引用
|
||||
final seen = Expando<bool>();
|
||||
final sanitized = _sanitizeForJson(origHiddenList, seen);
|
||||
// 如果 sanitized 为 null(极少见),退回到空列表
|
||||
final safeForJson = sanitized ?? [];
|
||||
String HIDDENJSON = jsonEncode(safeForJson);
|
||||
|
||||
// 准备 form 字段(JSON 字符串等)
|
||||
form['INSPECTORJSON'] = jsonEncode(inspectors);
|
||||
form['SITUATIONJSON'] = jsonEncode(situations);
|
||||
form['HIDDENJSON'] = jsonEncode(origHiddenList);
|
||||
form['HIDDENJSON'] = HIDDENJSON;
|
||||
form['delInspectors'] = delInspectors.join(',');
|
||||
form['delSituations'] = delSituations.join(',');
|
||||
form['delHiddens'] = delHiddens.join(',');
|
||||
|
|
@ -549,15 +561,11 @@ class _SafecheckDetailState extends State<SafecheckDetail> {
|
|||
form['CREATOR'] = loginUser['USER_ID'] ?? loginUserId;
|
||||
form['CORPINFO_ID'] = SessionService.instance.corpinfoId ?? '';
|
||||
form['ACTION_USER'] = loginUser['NAME'] ?? '';
|
||||
LoadingDialogHelper.show(); // 显示 loading
|
||||
|
||||
// 提交主表
|
||||
try {
|
||||
final requestData = <String, dynamic>{
|
||||
'CORPINFO_ID': form['CORPINFO_ID'],
|
||||
...form,
|
||||
};
|
||||
final res = await ApiService.safeKeyprojectCheckSubmit(requestData);
|
||||
LoadingDialogHelper.show();
|
||||
final res = await ApiService.safeKeyprojectCheckSubmit(form);
|
||||
// 如果你的 ApiService 返回结构不同,请按实际调整判断
|
||||
if (res != null && res['result'] == 'success') {
|
||||
final pd = res['pd'] ?? {};
|
||||
|
|
@ -613,6 +621,63 @@ class _SafecheckDetailState extends State<SafecheckDetail> {
|
|||
}
|
||||
}
|
||||
|
||||
// Helper: 将任意结构"净化"成可 JSON 序列化的形式(打断循环、替换 File 等)
|
||||
dynamic _sanitizeForJson(dynamic value, Expando<bool> seen) {
|
||||
// 常量直接返回
|
||||
if (value == null || value is num || value is bool || value is String)
|
||||
return value;
|
||||
|
||||
// 防止循环引用:如果已经访问过,直接返回 null 或一个占位符
|
||||
try {
|
||||
if (seen[value] == true) {
|
||||
// 已访问 -> 打断循环。返回 null 也可以改为返回字符串 "(circular)"
|
||||
return null;
|
||||
}
|
||||
} catch (_) {
|
||||
// 某些原始类型可能不能作为 Expando key ——忽略
|
||||
}
|
||||
|
||||
// 标记为已访问(仅对引用类型有意义)
|
||||
try {
|
||||
seen[value] = true;
|
||||
} catch (_) {}
|
||||
|
||||
// 特殊类型处理
|
||||
if (value is File) {
|
||||
return value.path; // 或者 path 的 basename: p.basename(value.path)
|
||||
}
|
||||
if (value is DateTime) return value.toIso8601String();
|
||||
if (value is Uri) return value.toString();
|
||||
|
||||
// Map -> 递归处理键值(键转成字符串)
|
||||
if (value is Map) {
|
||||
final out = <String, dynamic>{};
|
||||
for (final entry in value.entries) {
|
||||
final k = entry.key?.toString() ?? '';
|
||||
final v = _sanitizeForJson(entry.value, seen);
|
||||
if (v != null) out[k] = v;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
// List/Iterable -> 递归处理元素,过滤 null
|
||||
if (value is Iterable) {
|
||||
final listOut = <dynamic>[];
|
||||
for (final e in value) {
|
||||
final s = _sanitizeForJson(e, seen);
|
||||
if (s != null) listOut.add(s);
|
||||
}
|
||||
return listOut;
|
||||
}
|
||||
|
||||
// 其他不可直接序列化的对象:尝试用 toString() 作为备选(或返回 null)
|
||||
try {
|
||||
return value.toString();
|
||||
} catch (_) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// ========== 上传附件的方法 ==========
|
||||
Future<void> uploadHiddenFiles(
|
||||
List<List<Map<String, dynamic>>> hiddenFilesPerHidden,
|
||||
|
|
@ -695,7 +760,9 @@ class _SafecheckDetailState extends State<SafecheckDetail> {
|
|||
body: SafeArea(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 12, vertical: 12),
|
||||
child: form.isNotEmpty ? ListView(
|
||||
child:
|
||||
form.isNotEmpty
|
||||
? ListView(
|
||||
children: [
|
||||
Column(
|
||||
children: [
|
||||
|
|
@ -773,14 +840,28 @@ class _SafecheckDetailState extends State<SafecheckDetail> {
|
|||
text: form['INSPECTION_TIME_START'] ?? '',
|
||||
onTap: () async {
|
||||
DateTime? picked =
|
||||
await BottomDateTimePicker.showDate(context,mode: BottomPickerMode.dateTimeWithSeconds,);
|
||||
await BottomDateTimePicker.showDate(
|
||||
context,
|
||||
mode:
|
||||
BottomPickerMode
|
||||
.dateTime,
|
||||
);
|
||||
if (picked != null) {
|
||||
setState(() {
|
||||
form['INSPECTION_TIME_START'] = DateFormat(
|
||||
form['INSPECTION_TIME_START'] =
|
||||
DateFormat(
|
||||
'yyyy-MM-dd HH:mm',
|
||||
).format(picked);
|
||||
/// 开始时间必须早于结束时间
|
||||
if (FormUtils.hasValue(form, 'INSPECTION_TIME_END') &&
|
||||
!isBeforeStr(
|
||||
form['INSPECTION_TIME_START'],
|
||||
form['INSPECTION_TIME_END'],
|
||||
)) {
|
||||
form['INSPECTION_TIME_END'] = '';
|
||||
}
|
||||
});
|
||||
FocusHelper.clearFocus(context);
|
||||
//FocusHelper.clearFocus(context);
|
||||
}
|
||||
},
|
||||
),
|
||||
|
|
@ -792,18 +873,25 @@ class _SafecheckDetailState extends State<SafecheckDetail> {
|
|||
text: form['INSPECTION_TIME_END'] ?? '',
|
||||
onTap: () async {
|
||||
DateTime? picked =
|
||||
await BottomDateTimePicker.showDate(context,mode: BottomPickerMode.dateTimeWithSeconds,);
|
||||
await BottomDateTimePicker.showDate(
|
||||
context,
|
||||
minTimeStr: form['INSPECTION_TIME_START'] ?? '',
|
||||
mode:
|
||||
BottomPickerMode
|
||||
.dateTime,
|
||||
);
|
||||
if (picked != null) {
|
||||
setState(() {
|
||||
form['INSPECTION_TIME_END'] = DateFormat(
|
||||
form['INSPECTION_TIME_END'] =
|
||||
DateFormat(
|
||||
'yyyy-MM-dd HH:mm',
|
||||
).format(picked);
|
||||
|
||||
});
|
||||
FocusHelper.clearFocus(context);
|
||||
//FocusHelper.clearFocus(context);
|
||||
}
|
||||
},
|
||||
),
|
||||
|
||||
const Divider(),
|
||||
MultiTextFieldWithTitle(
|
||||
label: "检查情况",
|
||||
|
|
@ -815,9 +903,8 @@ class _SafecheckDetailState extends State<SafecheckDetail> {
|
|||
onTextsChanged: (texts) {
|
||||
setState(() {
|
||||
multiTexts = texts; // 保存到状态变量
|
||||
form['situationList'] = _stringsToSituationList(
|
||||
texts,
|
||||
);
|
||||
form['situationList'] =
|
||||
_stringsToSituationList(texts);
|
||||
});
|
||||
},
|
||||
),
|
||||
|
|
@ -836,7 +923,8 @@ class _SafecheckDetailState extends State<SafecheckDetail> {
|
|||
const Divider(),
|
||||
ItemListWidget.itemContainer(
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
ListItemFactory.headerTitle('发现问题'),
|
||||
if (widget.isEdit)
|
||||
|
|
@ -849,8 +937,11 @@ class _SafecheckDetailState extends State<SafecheckDetail> {
|
|||
),
|
||||
backgroundColor: Colors.blue,
|
||||
onPressed: () {
|
||||
_openDrawer(form, -1); // 添加括号和 await
|
||||
FocusHelper.clearFocus(context);
|
||||
_openDrawer(
|
||||
{},
|
||||
-1,
|
||||
); // 添加括号和 await
|
||||
//FocusHelper.clearFocus(context);
|
||||
},
|
||||
),
|
||||
],
|
||||
|
|
@ -861,7 +952,8 @@ class _SafecheckDetailState extends State<SafecheckDetail> {
|
|||
forbidEdit: widget.isEdit,
|
||||
baseImgPath: ApiService.baseImgPath,
|
||||
personSignImg: form['PERSON_SIGN_IMG'] ?? '',
|
||||
personSignTime: form['PERSON_SIGN_TIME'] ?? '',
|
||||
personSignTime:
|
||||
form['PERSON_SIGN_TIME'] ?? '',
|
||||
showHidden: (item, idx) {
|
||||
_openDrawer(item, idx);
|
||||
},
|
||||
|
|
@ -872,20 +964,29 @@ class _SafecheckDetailState extends State<SafecheckDetail> {
|
|||
),
|
||||
|
||||
if (!widget.isEdit)
|
||||
Column(children: [
|
||||
Column(
|
||||
children: [
|
||||
const Divider(),
|
||||
ItemListWidget.twoRowTitleAndImages(
|
||||
title: '签字',
|
||||
onTapCallBack: (p) {
|
||||
presentOpaque(SingleImageViewer(imageUrl: p), context);
|
||||
presentOpaque(
|
||||
SingleImageViewer(imageUrl: p),
|
||||
context,
|
||||
);
|
||||
},
|
||||
imageUrls: [
|
||||
'${form['PERSON_SIGN_IMG'] ?? ''}',
|
||||
],
|
||||
),
|
||||
const Divider(),
|
||||
ItemListWidget.singleLineTitleText(label: '签字时间', isEditable: false, text: form['PERSON_SIGN_TIME'] ?? '')
|
||||
],)
|
||||
ItemListWidget.singleLineTitleText(
|
||||
label: '签字时间',
|
||||
isEditable: false,
|
||||
text: form['PERSON_SIGN_TIME'] ?? '',
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
|
@ -923,7 +1024,8 @@ class _SafecheckDetailState extends State<SafecheckDetail> {
|
|||
],
|
||||
),
|
||||
],
|
||||
): SizedBox(),
|
||||
)
|
||||
: SizedBox(),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
|
|
|||
|
|
@ -61,7 +61,6 @@ class _CheckRecordDetailPageState extends State<CheckRecordDetailPage> {
|
|||
super.initState();
|
||||
// 启动时并行请求,UI 使用 setState 更新
|
||||
_fetchAll();
|
||||
_initLocation();
|
||||
}
|
||||
@override
|
||||
void dispose() {
|
||||
|
|
|
|||
|
|
@ -472,7 +472,7 @@ class _DangerWaitListPageState extends State<DangerWaitListPage> {
|
|||
}
|
||||
|
||||
void _showMessage(String msg) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(msg)));
|
||||
ToastUtil.showNormal(context, msg);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -125,7 +125,7 @@ class _HomeNfcDetailPageState extends State<HomeNfcDetailPage> {
|
|||
|
||||
void _showMessage(String msg) {
|
||||
if (!mounted) return;
|
||||
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(msg)));
|
||||
ToastUtil.showNormal(context, msg);
|
||||
}
|
||||
|
||||
Future<void> _startCheckItem(Map item, int index) async {
|
||||
|
|
|
|||
|
|
@ -139,7 +139,7 @@ class _NfcCheckDangerDetailState extends State<NfcCheckDangerDetail> {
|
|||
pd['HIDDENTYPE'] = ids;
|
||||
pd['HIDDENTYPE_NAME'] = names.join('/');
|
||||
});
|
||||
FocusHelper.clearFocus(context);
|
||||
//FocusHelper.clearFocus(context);
|
||||
} catch (_) {}
|
||||
},
|
||||
),
|
||||
|
|
@ -198,7 +198,7 @@ class _NfcCheckDangerDetailState extends State<NfcCheckDangerDetail> {
|
|||
pd['RECTIFICATIONDEPT'] = id;
|
||||
pd['RECTIFICATIONDEPTNAME'] = name;
|
||||
});
|
||||
FocusHelper.clearFocus(context);
|
||||
//FocusHelper.clearFocus(context);
|
||||
_getPersonListForUnitId(typeStr);
|
||||
},
|
||||
),
|
||||
|
|
@ -214,7 +214,7 @@ class _NfcCheckDangerDetailState extends State<NfcCheckDangerDetail> {
|
|||
result['userList'] as List,
|
||||
);
|
||||
});
|
||||
FocusHelper.clearFocus(context);
|
||||
//FocusHelper.clearFocus(context);
|
||||
}
|
||||
|
||||
/// 弹出人员选择,需先选择单位
|
||||
|
|
@ -233,7 +233,7 @@ class _NfcCheckDangerDetailState extends State<NfcCheckDangerDetail> {
|
|||
pd['RECTIFICATIONOR'] = userId;
|
||||
pd['RECTIFICATIONORNAME'] = name;
|
||||
});
|
||||
FocusHelper.clearFocus(context);
|
||||
//FocusHelper.clearFocus(context);
|
||||
},
|
||||
).then((_) {});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -286,7 +286,7 @@ setState(() {
|
|||
signImages.add(path);
|
||||
signTimes.add(now);
|
||||
inspectedForm['INSPECTED_SITEUSER_SIGN_TIME'] = now;
|
||||
FocusHelper.clearFocus(context);
|
||||
//FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -206,8 +206,6 @@ class _CheckPersonDetailState extends State<CheckPersonDetail> {
|
|||
ToastUtil.showNormal(context, '请求失败:${e.toString()}');
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
// ========== 罚单提交方法
|
||||
|
|
@ -271,7 +269,6 @@ setState(() {
|
|||
signTimes = [];
|
||||
signImages.add(path);
|
||||
signTimes.add(now);
|
||||
FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -369,7 +366,6 @@ setState(() {
|
|||
});
|
||||
},
|
||||
),
|
||||
if (inspectorForm['INSPECTION_STATUS'] == '-1')
|
||||
Column(
|
||||
children: [
|
||||
const Divider(),
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ class SafecheckAssignmentDetailPage extends StatefulWidget {
|
|||
|
||||
class _SafecheckAssignmentDetailPageState
|
||||
extends State<SafecheckAssignmentDetailPage> {
|
||||
late bool _isEdit = false;
|
||||
late bool _isEdit = widget.HIDDEN_ID == '-2';
|
||||
late Map<String, dynamic> form = {};
|
||||
late List files = [];
|
||||
late List<String> hiddenVideo = [];
|
||||
|
|
@ -57,9 +57,8 @@ class _SafecheckAssignmentDetailPageState
|
|||
void initState() {
|
||||
// TODO: implement initState
|
||||
super.initState();
|
||||
if (widget.HIDDEN_ID == '-2') {
|
||||
_isEdit = true;
|
||||
}
|
||||
_isEdit = widget.HIDDEN_STATUS == '-2';
|
||||
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
_getData();
|
||||
});
|
||||
|
|
@ -79,6 +78,7 @@ class _SafecheckAssignmentDetailPageState
|
|||
.map((item) => '${ApiService.baseImgPath}${item['FILEPATH']}')
|
||||
.toList();
|
||||
files = data['hImgs'];
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -97,7 +97,7 @@ class _SafecheckAssignmentDetailPageState
|
|||
form['RECTIFICATIONDEPT'] = id;
|
||||
form['RECTIFICATIONDEPTNAME'] = name;
|
||||
});
|
||||
FocusHelper.clearFocus(context);
|
||||
//FocusHelper.clearFocus(context);
|
||||
_getPersonListForUnitId(typeStr);
|
||||
},
|
||||
),
|
||||
|
|
@ -113,7 +113,7 @@ class _SafecheckAssignmentDetailPageState
|
|||
result['userList'] as List,
|
||||
);
|
||||
});
|
||||
FocusHelper.clearFocus(context);
|
||||
//FocusHelper.clearFocus(context);
|
||||
}
|
||||
|
||||
/// 弹出人员选择,需先选择单位
|
||||
|
|
@ -132,7 +132,7 @@ class _SafecheckAssignmentDetailPageState
|
|||
form['RECTIFICATIONOR'] = userId;
|
||||
form['RECTIFICATIONORNAME'] = name;
|
||||
});
|
||||
FocusHelper.clearFocus(context);
|
||||
//FocusHelper.clearFocus(context);
|
||||
},
|
||||
).then((_) {});
|
||||
}
|
||||
|
|
@ -154,14 +154,9 @@ class _SafecheckAssignmentDetailPageState
|
|||
}
|
||||
}
|
||||
Map data = {
|
||||
'HIDDEN_ID': form['HIDDEN_ID'],
|
||||
'HIDDENLEVEL': form['HIDDENLEVEL'],
|
||||
'RECTIFICATIONDEPT': form['RECTIFICATIONDEPT'],
|
||||
'RECTIFICATIONDEADLINE': form['RECTIFICATIONDEADLINE'],
|
||||
'RECTIFICATIONOR': form['RECTIFICATIONOR'],
|
||||
...form,
|
||||
'HIDDEN_STATUS': widget.HIDDEN_STATUS,
|
||||
'INSPECTION_ID': widget.INSPECTION_ID,
|
||||
'HIDDENDESCR': form['HIDDENDESCR'],
|
||||
};
|
||||
try {
|
||||
LoadingDialogHelper.show();
|
||||
|
|
|
|||
|
|
@ -342,7 +342,7 @@ class _SafecheckAssignmentListState extends State<SafecheckAssignmentList> {
|
|||
),
|
||||
),
|
||||
|
||||
body: SafeArea(child: Expanded(child: _buildListContent()),),
|
||||
body: SafeArea(child: _buildListContent(),),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -98,11 +98,11 @@ class _SafeCheckFormViewState extends State<SafeCheckFormView> {
|
|||
const Divider(),
|
||||
ItemListWidget.OneRowImageTitle(
|
||||
label: '检查人签字',
|
||||
text: item['INSPECTION_USER_SIGN_TIME'],
|
||||
text: item['INSPECTION_USER_SIGN_TIME'] ?? '',
|
||||
onTapCallBack: (path) {
|
||||
presentOpaque(SingleImageViewer(imageUrl: path), context);
|
||||
},
|
||||
imgPath: item['INSPECTION_USER_SIGN_IMG'],
|
||||
imgPath: item['INSPECTION_USER_SIGN_IMG'] ?? '',
|
||||
),
|
||||
],
|
||||
);
|
||||
|
|
|
|||
|
|
@ -72,7 +72,6 @@ setState(() {
|
|||
signTimes = [];
|
||||
signImages.add(path);
|
||||
signTimes.add(now);
|
||||
FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -173,25 +173,28 @@ class _SafeCheckDrawerPageState extends State<SafeCheckDrawerPage> {
|
|||
hiddenForm['CREATTIME'] = DateFormat('yyyy-MM-dd HH:mm').format(picked);
|
||||
});
|
||||
}
|
||||
FocusHelper.clearFocus(context);
|
||||
//FocusHelper.clearFocus(context);
|
||||
|
||||
}
|
||||
|
||||
/// 隐患发现人
|
||||
Future<void> _pickDangerPerson() async {
|
||||
List inspectorList = hiddenForm['inspectorList'];
|
||||
final choice = await BottomPicker.show<String>(
|
||||
context,
|
||||
items: [SessionService.instance.username as String],
|
||||
items: inspectorList.map((val) => val['INSPECTION_USER_NAME'] as String).toList(),
|
||||
itemBuilder: (item) => Text(item, textAlign: TextAlign.center),
|
||||
initialIndex: 0,
|
||||
);
|
||||
FocusHelper.clearFocus(context);
|
||||
//FocusHelper.clearFocus(context);
|
||||
|
||||
if (choice != null) {
|
||||
setState(() {
|
||||
hiddenForm['CREATOR_INDEX'] = 0;
|
||||
hiddenForm['CREATOR'] = SessionService.instance.loginUserId;
|
||||
hiddenForm['CREATOR_NAME'] = SessionService.instance.username;
|
||||
final data = FormUtils.findMapForKeyValue(inspectorList, 'INSPECTION_USER_NAME', choice);
|
||||
hiddenForm['CREATOR'] = data['INSPECTION_USER_ID'];
|
||||
|
||||
hiddenForm['CREATOR_NAME'] = choice;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -376,7 +379,7 @@ class _SafeCheckDrawerPageState extends State<SafeCheckDrawerPage> {
|
|||
itemBuilder: (i) => Text(i['NAME'], textAlign: TextAlign.center),
|
||||
initialIndex: 0,
|
||||
);
|
||||
FocusHelper.clearFocus(context);
|
||||
//FocusHelper.clearFocus(context);
|
||||
if (choice == null) return;
|
||||
final found = _hazardLevels.firstWhere(
|
||||
(e) => e['NAME'] == choice,
|
||||
|
|
@ -395,7 +398,7 @@ class _SafeCheckDrawerPageState extends State<SafeCheckDrawerPage> {
|
|||
}
|
||||
});
|
||||
}
|
||||
FocusHelper.clearFocus(context);
|
||||
//FocusHelper.clearFocus(context);
|
||||
}
|
||||
|
||||
Future<void> _pickHazardType() async {
|
||||
|
|
@ -416,7 +419,7 @@ class _SafeCheckDrawerPageState extends State<SafeCheckDrawerPage> {
|
|||
hiddenForm['HIDDENTYPE_NAME'] = names.join('/');
|
||||
|
||||
});
|
||||
FocusHelper.clearFocus(context);
|
||||
//FocusHelper.clearFocus(context);
|
||||
|
||||
} catch (_) {}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -191,13 +191,25 @@ class _SafecheckStartDetailState extends State<SafecheckStartDetail> {
|
|||
final data = FormUtils.findMapForKeyValue(typeList, 'name', choice);
|
||||
form['INSPECTION_TYPE'] = data['id'];
|
||||
|
||||
FocusHelper.clearFocus(context);
|
||||
//FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _openDrawer(Map<String, dynamic> hiddenForm, int index) async {
|
||||
try {
|
||||
if (hiddenForm.length == 0) {
|
||||
hiddenForm = {
|
||||
'ISRELEVANT': '2',
|
||||
'SOURCE': '5',
|
||||
'hiddenImgs': <Map<String, dynamic>>[],
|
||||
'zgImgs': <Map<String, dynamic>>[],
|
||||
'hiddenVideos': <Map<String, dynamic>>[],
|
||||
'RECTIFICATIONTYPE': '2',
|
||||
'inspectorList': form['inspectorList'],
|
||||
|
||||
};
|
||||
}
|
||||
final result = await openCustomDrawer<Map>(
|
||||
context,
|
||||
SafeCheckDrawerPage(
|
||||
|
|
@ -600,7 +612,6 @@ class _SafecheckStartDetailState extends State<SafecheckStartDetail> {
|
|||
setState(() {
|
||||
signImages.add(path);
|
||||
signTimes.add(now);
|
||||
FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -792,7 +803,7 @@ class _SafecheckStartDetailState extends State<SafecheckStartDetail> {
|
|||
hiddenList.removeAt(index);
|
||||
form['hiddenList'] = hiddenList;
|
||||
});
|
||||
FocusHelper.clearFocus(context);
|
||||
//FocusHelper.clearFocus(context);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -814,9 +825,11 @@ class _SafecheckStartDetailState extends State<SafecheckStartDetail> {
|
|||
final int index = int.parse(typeStr);
|
||||
inspectorList[index]['INSPECTION_DEPARTMENT_NAME'] = name;
|
||||
inspectorList[index]['INSPECTION_DEPARTMENT_ID'] = id;
|
||||
form['inspectorList'] = inspectorList;
|
||||
|
||||
}
|
||||
});
|
||||
FocusHelper.clearFocus(context);
|
||||
//FocusHelper.clearFocus(context);
|
||||
_getPersonListForUnitId(typeStr);
|
||||
},
|
||||
),
|
||||
|
|
@ -837,7 +850,7 @@ class _SafecheckStartDetailState extends State<SafecheckStartDetail> {
|
|||
result['userList'] as List,
|
||||
);
|
||||
});
|
||||
FocusHelper.clearFocus(context);
|
||||
//FocusHelper.clearFocus(context);
|
||||
}
|
||||
|
||||
/// 弹出人员选择,需先选择单位
|
||||
|
|
@ -863,9 +876,10 @@ class _SafecheckStartDetailState extends State<SafecheckStartDetail> {
|
|||
item['INSPECTION_USER_INDEX'] = '$index';
|
||||
item['INSPECTION_USER_NAME'] = name;
|
||||
item['INSPECTION_USER_ID'] = userId;
|
||||
form['inspectorList'] = inspectorList;
|
||||
}
|
||||
});
|
||||
FocusHelper.clearFocus(context);
|
||||
//FocusHelper.clearFocus(context);
|
||||
},
|
||||
).then((_) {});
|
||||
}
|
||||
|
|
@ -1032,7 +1046,7 @@ class _SafecheckStartDetailState extends State<SafecheckStartDetail> {
|
|||
'yyyy-MM-dd HH:mm:ss',
|
||||
).format(picked);
|
||||
});
|
||||
FocusHelper.clearFocus(context);
|
||||
//FocusHelper.clearFocus(context);
|
||||
}
|
||||
},
|
||||
),
|
||||
|
|
@ -1053,7 +1067,7 @@ class _SafecheckStartDetailState extends State<SafecheckStartDetail> {
|
|||
'yyyy-MM-dd HH:mm:ss',
|
||||
).format(picked);
|
||||
});
|
||||
FocusHelper.clearFocus(context);
|
||||
//FocusHelper.clearFocus(context);
|
||||
}
|
||||
},
|
||||
),
|
||||
|
|
@ -1138,7 +1152,7 @@ class _SafecheckStartDetailState extends State<SafecheckStartDetail> {
|
|||
backgroundColor: Colors.blue,
|
||||
onPressed: () {
|
||||
_openDrawer({}, -1); // 添加括号和 await
|
||||
FocusHelper.clearFocus(context);
|
||||
//FocusHelper.clearFocus(context);
|
||||
},
|
||||
),
|
||||
],
|
||||
|
|
@ -1210,7 +1224,9 @@ class _SafecheckStartDetailState extends State<SafecheckStartDetail> {
|
|||
isRequired: false,
|
||||
hintText: '检查人意见',
|
||||
onChanged: (val) {
|
||||
setState(() {
|
||||
form['INSPECTION_USER_OPINION'] = val;
|
||||
});
|
||||
},
|
||||
text: form['INSPECTION_USER_OPINION'] ?? '',
|
||||
),
|
||||
|
|
@ -1218,6 +1234,9 @@ class _SafecheckStartDetailState extends State<SafecheckStartDetail> {
|
|||
.toString()
|
||||
.isNotEmpty &&
|
||||
_isEdit)
|
||||
Column(
|
||||
children: [
|
||||
const Divider(),
|
||||
ItemListWidget.itemContainer(
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
|
|
@ -1235,6 +1254,8 @@ class _SafecheckStartDetailState extends State<SafecheckStartDetail> {
|
|||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
if (signImages.isNotEmpty) _signListWidget(),
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import 'package:http/http.dart' as http;
|
|||
import 'package:photo_view/photo_view.dart';
|
||||
import 'package:qhd_prevention/customWidget/ItemWidgetFactory.dart';
|
||||
import 'package:qhd_prevention/customWidget/single_image_viewer.dart';
|
||||
import 'package:qhd_prevention/customWidget/toast_util.dart';
|
||||
import 'package:qhd_prevention/http/ApiService.dart';
|
||||
import 'package:qhd_prevention/pages/my_appbar.dart';
|
||||
import 'package:qhd_prevention/tools/tools.dart';
|
||||
|
|
@ -49,9 +50,7 @@ class _CompanySafetyCommitmentDetailState extends State<CompanySafetyCommitmentD
|
|||
}
|
||||
|
||||
void _showError(String message) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text(message)),
|
||||
);
|
||||
ToastUtil.showNormal(context, message);
|
||||
setState(() => isLoading = false);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -312,7 +312,6 @@ class _SafetyMeetingDetailPageState extends State<SafetyMeetingDetailPage> {
|
|||
setState(() {
|
||||
signImages.add(path);
|
||||
// signTimes.add(now);
|
||||
FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -185,14 +185,13 @@ class HomePageState extends State<HomePage> {
|
|||
void initState() {
|
||||
super.initState();
|
||||
// 使用初始化加载:先恢复缓存(若存在则直接显示),然后再发起网络请求(成功则覆盖缓存)
|
||||
_initialLoad();
|
||||
BadgeManager().initAllModules();
|
||||
_initialLoad();
|
||||
|
||||
}
|
||||
|
||||
/// 首次加载:先恢复缓存(如果有),然后在后台去刷新(只有当无缓存时才显示 loading)
|
||||
Future<void> _initialLoad() async {
|
||||
|
||||
/// 清单列表
|
||||
final data = await ApiService.getListData();
|
||||
if (data['result'] == 'success') {
|
||||
|
|
@ -239,11 +238,11 @@ class HomePageState extends State<HomePage> {
|
|||
return;
|
||||
}
|
||||
|
||||
await _loadHiddenCache();
|
||||
_loadHiddenCache();
|
||||
// 拉取其他数据 + 隐患列表(当 hiddenList 为空时显示 loading,否则不显示)
|
||||
await _fetchData();
|
||||
await _fetchHiddenList(showLoading: hiddenList.isEmpty);
|
||||
await fetchAndSaveBd09(context);
|
||||
_fetchData();
|
||||
_fetchHiddenList(showLoading: hiddenList.isEmpty);
|
||||
fetchAndSaveBd09(context);
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -706,7 +705,9 @@ class HomePageState extends State<HomePage> {
|
|||
return GestureDetector(
|
||||
onTap: () async {
|
||||
if (index == 1) {
|
||||
LoadingDialogHelper.show();
|
||||
bool isRest= await _getIsRest();
|
||||
LoadingDialogHelper.hide();
|
||||
if(isRest){
|
||||
ToastUtil.showNormal(context, "您已经处于离岗状态中");
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
|
||||
import 'dart:async';
|
||||
import 'dart:math';
|
||||
import 'dart:ui';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:qhd_prevention/customWidget/remote_file_page.dart';
|
||||
import 'package:qhd_prevention/pages/home/study/take_exam_page.dart';
|
||||
import 'package:qhd_prevention/pages/home/study/study_practise_page.dart';
|
||||
|
|
@ -54,7 +56,10 @@ class _StudyDetailPageState extends State<StudyDetailPage>
|
|||
// 上报控制相关字段
|
||||
bool _endReported = false; // 确保最终结束上报只执行一次
|
||||
Future<void>? _ongoingSubmit; // 用于串行化提交请求
|
||||
final int _uploadIntervalSeconds = 1; // 周期性上报间隔(秒)
|
||||
final int _uploadIntervalSeconds = 5; // 周期性上报间隔(秒)
|
||||
|
||||
// 新增:防止并发加载视频
|
||||
bool _isLoadingVideo = false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
|
|
@ -74,7 +79,7 @@ class _StudyDetailPageState extends State<StudyDetailPage>
|
|||
_tabController.dispose();
|
||||
WakelockPlus.disable();
|
||||
|
||||
// 最佳努力:让未完成的提交完成(非阻塞)
|
||||
// 让未完成的提交完成(非阻塞)
|
||||
if (_ongoingSubmit != null) {
|
||||
_ongoingSubmit!.whenComplete(() {});
|
||||
}
|
||||
|
|
@ -95,7 +100,8 @@ class _StudyDetailPageState extends State<StudyDetailPage>
|
|||
final ok = await CustomAlertDialog.showConfirm(
|
||||
context,
|
||||
title: '温馨提示',
|
||||
content: '重要提醒:尊敬的用户,根据规定我们会在您学习过程中多次进行人脸识别认证,为了保护您的隐私请您在摄像设备视野内确保衣冠整齐。',
|
||||
content:
|
||||
'重要提醒:尊敬的用户,根据规定我们会在您学习过程中多次进行人脸识别认证,为了保护您的隐私请您在摄像设备视野内确保衣冠整齐。',
|
||||
cancelText: '取消',
|
||||
confirmText: '同意并继续',
|
||||
);
|
||||
|
|
@ -161,11 +167,27 @@ class _StudyDetailPageState extends State<StudyDetailPage>
|
|||
int fi,
|
||||
int ni,
|
||||
) async {
|
||||
if (_isLoadingVideo) {
|
||||
debugPrint('_onVideoTap ignored because a video is loading');
|
||||
return;
|
||||
}
|
||||
|
||||
// 后端清除人脸计时
|
||||
await ApiService.fnClearUserFaceTime();
|
||||
_faceTimer?.cancel();
|
||||
|
||||
// 如果当前有视频播放且有未上报的进度,先做一次快照上报(避免丢失)
|
||||
if (_currentVideoData != null && _lastReported > Duration.zero) {
|
||||
await _submitPlayTime(end: false, seconds: _lastReported.inSeconds);
|
||||
final prevSnapshot = <String, dynamic>{
|
||||
'VIDEOCOURSEWARE_ID': _currentVideoData?['VIDEOCOURSEWARE_ID'] ?? '',
|
||||
'CURRICULUM_ID': _currentVideoData?['CURRICULUM_ID'] ?? '',
|
||||
'CHAPTER_ID': _currentVideoData?['CHAPTER_ID'] ?? '',
|
||||
'VIDEOTIME': _currentVideoData?['VIDEOTIME'] ?? 0,
|
||||
'IS_NODE': _hasNodes,
|
||||
'FIRST_INDEX': _currentFirstIndex,
|
||||
'NODE_INDEX': _currentNodeIndex,
|
||||
};
|
||||
await _submitPlayTime(snapshot: prevSnapshot, end: false, seconds: _lastReported.inSeconds);
|
||||
}
|
||||
_lastReported = Duration.zero;
|
||||
|
||||
|
|
@ -174,14 +196,20 @@ class _StudyDetailPageState extends State<StudyDetailPage>
|
|||
_currentFirstIndex = fi;
|
||||
_currentNodeIndex = ni;
|
||||
|
||||
// 暂停已有播放器
|
||||
_videoController?.pause();
|
||||
// 暂停已有播放器(安全)
|
||||
try {
|
||||
if (_videoController != null && _videoController!.value.isPlaying) {
|
||||
await _videoController!.pause();
|
||||
}
|
||||
} catch (_) {}
|
||||
|
||||
await _navigateFaceIfNeeded(() async {
|
||||
if ((data['IS_VIDEO'] ?? 0) == 1) {
|
||||
// 文档
|
||||
if (data['VIDEOFILES'] != null) {
|
||||
_videoController?.pause();
|
||||
try {
|
||||
await _videoController?.pause();
|
||||
} catch (_) {}
|
||||
await pushPage(
|
||||
RemoteFilePage(
|
||||
fileUrl: ApiService.baseImgPath + data['VIDEOFILES'],
|
||||
|
|
@ -189,10 +217,17 @@ class _StudyDetailPageState extends State<StudyDetailPage>
|
|||
),
|
||||
context,
|
||||
);
|
||||
await _submitPlayTime(
|
||||
end: true,
|
||||
seconds: int.parse(data['VIDEOTIME'] ?? '0'),
|
||||
);
|
||||
// 对文档直接上报完整时长(用 data 做快照)
|
||||
final docSnapshot = <String, dynamic>{
|
||||
'VIDEOCOURSEWARE_ID': data['VIDEOCOURSEWARE_ID'] ?? '',
|
||||
'CURRICULUM_ID': data['CURRICULUM_ID'] ?? '',
|
||||
'CHAPTER_ID': data['CHAPTER_ID'] ?? '',
|
||||
'VIDEOTIME': data['VIDEOTIME'] ?? 0,
|
||||
'IS_NODE': hasNodes,
|
||||
'FIRST_INDEX': fi,
|
||||
'NODE_INDEX': ni,
|
||||
};
|
||||
await _submitPlayTime(snapshot: docSnapshot, end: true, seconds: int.parse('${data['VIDEOTIME'] ?? '0'}'));
|
||||
} else {
|
||||
ScaffoldMessenger.of(
|
||||
context,
|
||||
|
|
@ -213,10 +248,15 @@ class _StudyDetailPageState extends State<StudyDetailPage>
|
|||
LoadingDialogHelper.hide();
|
||||
final pd_data = resData['pd'];
|
||||
if (FormUtils.hasValue(pd_data, 'USERAVATARURL')) {
|
||||
// 先退出可能的全屏并锁定为竖屏,避免横屏导致人脸页面布局错乱
|
||||
await _exitTopRouteAndWait();
|
||||
await _lockPortrait();
|
||||
final passed = await pushPage<bool>(
|
||||
FaceRecognitionPage(studentId: widget.studentId, mode: FaceMode.auto),
|
||||
context,
|
||||
);
|
||||
await _restoreDefaultOrientations();
|
||||
|
||||
if (passed == true) {
|
||||
await ApiService.fnSetUserFaceTime(_faceTime);
|
||||
await onPass();
|
||||
|
|
@ -231,12 +271,14 @@ class _StudyDetailPageState extends State<StudyDetailPage>
|
|||
cancelText: '取消',
|
||||
);
|
||||
if (ok) {
|
||||
await _exitTopRouteAndWait();
|
||||
await _lockPortrait();
|
||||
await pushPage(
|
||||
const FaceRecognitionPage(studentId: '', mode: FaceMode.manual),
|
||||
context,
|
||||
);
|
||||
await _restoreDefaultOrientations();
|
||||
}
|
||||
|
||||
}
|
||||
} else {
|
||||
await onPass();
|
||||
|
|
@ -244,13 +286,20 @@ class _StudyDetailPageState extends State<StudyDetailPage>
|
|||
}
|
||||
|
||||
Future<void> _getVideoPlayInfo(String vidId) async {
|
||||
if (_isLoadingVideo) {
|
||||
debugPrint('_getVideoPlayInfo blocked: already loading a video');
|
||||
return;
|
||||
}
|
||||
_isLoadingVideo = true;
|
||||
|
||||
try {
|
||||
final res = await ApiService.fnGetVideoPlayInfo(vidId);
|
||||
final url = res['videoList']?[0]?['playURL'] ?? '';
|
||||
_videoCoverUrl = res['videoBase']?['coverURL'] ?? '';
|
||||
|
||||
final prog = await ApiService.fnGetVideoPlayProgress(
|
||||
vidId,
|
||||
_currentVideoData!['CURRICULUM_ID'],
|
||||
_currentVideoData?['CURRICULUM_ID'],
|
||||
_classId,
|
||||
widget.studentId,
|
||||
);
|
||||
|
|
@ -266,14 +315,21 @@ class _StudyDetailPageState extends State<StudyDetailPage>
|
|||
return (double.tryParse(s) ?? 0.0).toInt();
|
||||
})();
|
||||
|
||||
// 先销毁旧 controller
|
||||
// 先销毁旧 controller(安全顺序:removeListener -> pause -> dispose -> null)
|
||||
if (_videoController != null) {
|
||||
try {
|
||||
_videoController?.removeListener(_onTimeUpdate);
|
||||
_videoController!.removeListener(_onTimeUpdate);
|
||||
} catch (_) {}
|
||||
try {
|
||||
_videoController?.dispose();
|
||||
if (_videoController!.value.isPlaying) {
|
||||
await _videoController!.pause();
|
||||
}
|
||||
} catch (_) {}
|
||||
try {
|
||||
await _videoController!.dispose();
|
||||
} catch (_) {}
|
||||
_videoController = null;
|
||||
}
|
||||
|
||||
// 创建新 controller
|
||||
_videoController = VideoPlayerController.networkUrl(Uri.parse(url));
|
||||
|
|
@ -284,13 +340,25 @@ class _StudyDetailPageState extends State<StudyDetailPage>
|
|||
_lastReported = Duration.zero;
|
||||
_ongoingSubmit = null;
|
||||
|
||||
setState(() {});
|
||||
if (mounted) setState(() {});
|
||||
|
||||
// 直接从上次播放点 seek,并立即播放
|
||||
_videoController!
|
||||
..seekTo(Duration(seconds: seen))
|
||||
..play()
|
||||
..addListener(_onTimeUpdate);
|
||||
try {
|
||||
await _videoController!.seekTo(Duration(seconds: seen));
|
||||
await _videoController!.play();
|
||||
// 移除(防止重复)后再添加
|
||||
try {
|
||||
_videoController!.removeListener(_onTimeUpdate);
|
||||
} catch (_) {}
|
||||
_videoController!.addListener(_onTimeUpdate);
|
||||
} catch (e, st) {
|
||||
debugPrint('Error during play/seek/addListener: $e\n$st');
|
||||
}
|
||||
} catch (e, st) {
|
||||
debugPrint('_getVideoPlayInfo error: $e\n$st');
|
||||
} finally {
|
||||
_isLoadingVideo = false;
|
||||
}
|
||||
}
|
||||
|
||||
// 改进版本的 _onTimeUpdate,包含周期性上报 + 接近结束时的最终上报
|
||||
|
|
@ -306,10 +374,22 @@ class _StudyDetailPageState extends State<StudyDetailPage>
|
|||
final secondsSinceLast = (pos - _lastReported).inSeconds;
|
||||
if (secondsSinceLast >= _uploadIntervalSeconds && !_endReported) {
|
||||
_lastReported = pos;
|
||||
|
||||
// 创建快照:避免 _currentVideoData 后续被替换影响上报
|
||||
final snapshot = <String, dynamic>{
|
||||
'VIDEOCOURSEWARE_ID': _currentVideoData?['VIDEOCOURSEWARE_ID'] ?? '',
|
||||
'CURRICULUM_ID': _currentVideoData?['CURRICULUM_ID'] ?? '',
|
||||
'CHAPTER_ID': _currentVideoData?['CHAPTER_ID'] ?? '',
|
||||
'VIDEOTIME': _currentVideoData?['VIDEOTIME'] ?? 0,
|
||||
'IS_NODE': _hasNodes,
|
||||
'FIRST_INDEX': _currentFirstIndex,
|
||||
'NODE_INDEX': _currentNodeIndex,
|
||||
};
|
||||
|
||||
// 串行上报:通过 _ongoingSubmit 链式调用来保证顺序
|
||||
_ongoingSubmit = (_ongoingSubmit ?? Future.value())
|
||||
.then((_) {
|
||||
return _submitPlayTime(end: false, seconds: pos.inSeconds);
|
||||
return _submitPlayTime(snapshot: snapshot, end: false, seconds: pos.inSeconds);
|
||||
})
|
||||
.whenComplete(() {
|
||||
// 完成后清理引用
|
||||
|
|
@ -324,9 +404,20 @@ class _StudyDetailPageState extends State<StudyDetailPage>
|
|||
if (endedOrClose && !_endReported) {
|
||||
_endReported = true;
|
||||
final finalSeconds = (dur.inMilliseconds / 1000.0).ceil();
|
||||
|
||||
final snapshot = <String, dynamic>{
|
||||
'VIDEOCOURSEWARE_ID': _currentVideoData?['VIDEOCOURSEWARE_ID'] ?? '',
|
||||
'CURRICULUM_ID': _currentVideoData?['CURRICULUM_ID'] ?? '',
|
||||
'CHAPTER_ID': _currentVideoData?['CHAPTER_ID'] ?? '',
|
||||
'VIDEOTIME': _currentVideoData?['VIDEOTIME'] ?? 0,
|
||||
'IS_NODE': _hasNodes,
|
||||
'FIRST_INDEX': _currentFirstIndex,
|
||||
'NODE_INDEX': _currentNodeIndex,
|
||||
};
|
||||
|
||||
_ongoingSubmit = (_ongoingSubmit ?? Future.value())
|
||||
.then((_) async {
|
||||
await _submitPlayTime(end: true, seconds: finalSeconds);
|
||||
await _submitPlayTime(snapshot: snapshot, end: true, seconds: finalSeconds);
|
||||
})
|
||||
.whenComplete(() {
|
||||
_ongoingSubmit = null;
|
||||
|
|
@ -341,18 +432,20 @@ class _StudyDetailPageState extends State<StudyDetailPage>
|
|||
}
|
||||
|
||||
Future<void> _submitPlayTime({
|
||||
required Map<String, dynamic> snapshot,
|
||||
required bool end,
|
||||
required int seconds,
|
||||
}) async {
|
||||
if (_currentVideoData == null) return;
|
||||
// snapshot 中应该包含 VIDEOCOURSEWARE_ID, CURRICULUM_ID, CHAPTER_ID, VIDEOTIME, ...
|
||||
if (snapshot['VIDEOCOURSEWARE_ID'] == null || snapshot['VIDEOCOURSEWARE_ID'] == '') return;
|
||||
|
||||
// 如果已经上报结束并且当前不是结束上报,则跳过非结束上报
|
||||
if (_endReported && !end) return;
|
||||
|
||||
Map data = {
|
||||
'VIDEOCOURSEWARE_ID': _currentVideoData!['VIDEOCOURSEWARE_ID'] ?? '',
|
||||
'CURRICULUM_ID': _currentVideoData!['CURRICULUM_ID'] ?? '',
|
||||
'CHAPTER_ID': _currentVideoData!['CHAPTER_ID'] ?? '',
|
||||
'VIDEOCOURSEWARE_ID': snapshot['VIDEOCOURSEWARE_ID'] ?? '',
|
||||
'CURRICULUM_ID': snapshot['CURRICULUM_ID'] ?? '',
|
||||
'CHAPTER_ID': snapshot['CHAPTER_ID'] ?? '',
|
||||
'RESOURCETIME': seconds,
|
||||
'IS_END': end ? '1' : '0',
|
||||
'CLASS_ID': _classId,
|
||||
|
|
@ -376,8 +469,7 @@ class _StudyDetailPageState extends State<StudyDetailPage>
|
|||
? resTraw.toDouble()
|
||||
: double.tryParse('$resTraw') ?? seconds.toDouble();
|
||||
|
||||
// 从当前视频数据中安全解析 videoTime
|
||||
final videoTimeRaw = _currentVideoData!['VIDEOTIME'];
|
||||
final videoTimeRaw = snapshot['VIDEOTIME'];
|
||||
final videoTime =
|
||||
(videoTimeRaw is String)
|
||||
? double.tryParse(videoTimeRaw) ?? 1.0
|
||||
|
|
@ -392,11 +484,21 @@ class _StudyDetailPageState extends State<StudyDetailPage>
|
|||
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
if (_hasNodes) {
|
||||
_videoList[_currentFirstIndex]['nodes'][_currentNodeIndex]['percent'] =
|
||||
str;
|
||||
if (snapshot['IS_NODE'] == true) {
|
||||
final fi = snapshot['FIRST_INDEX'] as int? ?? _currentFirstIndex;
|
||||
final ni = snapshot['NODE_INDEX'] as int? ?? _currentNodeIndex;
|
||||
// 保护性检查,避免索引越界
|
||||
if (fi >= 0 && fi < _videoList.length) {
|
||||
final nodes = _videoList[fi]['nodes'] as List<dynamic>?;
|
||||
if (nodes != null && ni >= 0 && ni < nodes.length) {
|
||||
_videoList[fi]['nodes'][ni]['percent'] = str;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
_videoList[_currentFirstIndex]['percent'] = str;
|
||||
final fi = snapshot['FIRST_INDEX'] as int? ?? _currentFirstIndex;
|
||||
if (fi >= 0 && fi < _videoList.length) {
|
||||
_videoList[fi]['percent'] = str;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -484,6 +586,26 @@ class _StudyDetailPageState extends State<StudyDetailPage>
|
|||
}
|
||||
}
|
||||
|
||||
/// 退出顶部路由并短暂等待(用于退出全屏播放器等)
|
||||
Future<void> _exitTopRouteAndWait({int waitMs = 300}) async {
|
||||
_exitTopRouteIfPresent();
|
||||
await Future.delayed(Duration(milliseconds: waitMs));
|
||||
}
|
||||
|
||||
/// 锁定为竖屏
|
||||
Future<void> _lockPortrait() async {
|
||||
await SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
|
||||
}
|
||||
|
||||
/// 恢复允许横竖(你可以按需修改恢复策略)
|
||||
Future<void> _restoreDefaultOrientations() async {
|
||||
await SystemChrome.setPreferredOrientations([
|
||||
DeviceOrientation.portraitUp,
|
||||
DeviceOrientation.landscapeLeft,
|
||||
DeviceOrientation.landscapeRight,
|
||||
]);
|
||||
}
|
||||
|
||||
void _startFaceTimer() {
|
||||
_faceTimer = Timer.periodic(Duration(seconds: _faceTime), (_) async {
|
||||
final res = await ApiService.fnGetUserFaceTime();
|
||||
|
|
@ -505,11 +627,17 @@ class _StudyDetailPageState extends State<StudyDetailPage>
|
|||
_faceTimer?.cancel();
|
||||
_faceTimer = null;
|
||||
|
||||
// 退出横屏/全屏并锁定竖屏,然后 push 人脸识别页面
|
||||
await _exitTopRouteAndWait();
|
||||
await _lockPortrait();
|
||||
|
||||
final passed = await pushPage<bool>(
|
||||
FaceRecognitionPage(studentId: widget.studentId, mode: FaceMode.auto),
|
||||
context,
|
||||
);
|
||||
|
||||
await _restoreDefaultOrientations();
|
||||
|
||||
if (passed == true) {
|
||||
await ApiService.fnSetUserFaceTime(_faceTime);
|
||||
// 认证通过后 —— 恢复播放、重新添加 listener,并更新上报基准
|
||||
|
|
@ -555,20 +683,17 @@ class _StudyDetailPageState extends State<StudyDetailPage>
|
|||
_videoController = null;
|
||||
}
|
||||
_faceTimer?.cancel();
|
||||
setState(() {
|
||||
});
|
||||
setState(() {});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Widget _buildVideoOrCover(double containerW, double containerH) {
|
||||
final c = _videoController;
|
||||
if (c != null && c.value.isInitialized) {
|
||||
return VideoPlayerWidget(
|
||||
allowSeek: false,
|
||||
controller: _videoController,
|
||||
coverUrl:
|
||||
_videoCoverUrl.isNotEmpty
|
||||
coverUrl: _videoCoverUrl.isNotEmpty
|
||||
? ApiService.baseImgPath + _videoCoverUrl
|
||||
: ApiService.baseImgPath + (_info?['COVERPATH'] ?? ''),
|
||||
aspectRatio: _videoController?.value.aspectRatio ?? 16 / 9,
|
||||
|
|
@ -730,8 +855,7 @@ class _StudyDetailPageState extends State<StudyDetailPage>
|
|||
],
|
||||
SizedBox(width: 20),
|
||||
CustomButton(
|
||||
onPressed:
|
||||
() => pushPage(
|
||||
onPressed: () => pushPage(
|
||||
StudyPractisePage(
|
||||
videoCoursewareId: m['VIDEOCOURSEWARE_ID'],
|
||||
),
|
||||
|
|
|
|||
|
|
@ -190,13 +190,42 @@ class _StudyMyTaskPageState extends State<StudyMyTaskPage> with RouteAware {
|
|||
await _uploadSignAndNavigate(item, imagePath);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _uploadSignAndNavigate(Map item, String imagePath) async {
|
||||
try {
|
||||
Future<String> _getImageBase64WithHeader(String imagePath) async {
|
||||
final File file = File(imagePath);
|
||||
final List<int> bytes = await file.readAsBytes();
|
||||
final String signBase64 = base64Encode(bytes);
|
||||
final String base64Data = base64Encode(bytes);
|
||||
|
||||
// 根据文件扩展名确定MIME类型
|
||||
final extension = imagePath.split('.').last.toLowerCase();
|
||||
|
||||
String header;
|
||||
switch (extension) {
|
||||
case 'jpg':
|
||||
case 'jpeg':
|
||||
header = 'data:image/jpeg;base64,';
|
||||
break;
|
||||
case 'png':
|
||||
header = 'data:image/png;base64,';
|
||||
break;
|
||||
case 'gif':
|
||||
header = 'data:image/gif;base64,';
|
||||
break;
|
||||
case 'webp':
|
||||
header = 'data:image/webp;base64,';
|
||||
break;
|
||||
case 'svg':
|
||||
header = 'data:image/svg+xml;base64,';
|
||||
break;
|
||||
default:
|
||||
// 对于未知类型,使用通用的二进制数据头
|
||||
header = 'data:application/octet-stream;base64,';
|
||||
}
|
||||
|
||||
return header + base64Data;
|
||||
}
|
||||
Future<void> _uploadSignAndNavigate(Map item, String imagePath) async {
|
||||
try {
|
||||
final String signBase64 = await _getImageBase64WithHeader(imagePath);
|
||||
final result = await ApiService.signUpdate(
|
||||
signBase64,
|
||||
item['CLASS_ID'],
|
||||
|
|
|
|||
|
|
@ -29,16 +29,22 @@ class ItemListWidget {
|
|||
ValueChanged<String>? onFieldSubmitted,
|
||||
int maxLines = 5,
|
||||
|
||||
///输入时数字
|
||||
List<TextInputFormatter> inputFormatters = const [],
|
||||
/// 强制必选 不受是否可以编译和是否必选影响
|
||||
// 新增参数:数字输入控制
|
||||
bool isNumericInput = false, // 是否为数字输入
|
||||
int maxDecimalPlaces = 2, // 最大小数位数
|
||||
TextInputType keyboardType = TextInputType.text,
|
||||
|
||||
/// 强制必选 不受是否可以编译和是否必选影响
|
||||
}) {
|
||||
// 如果启用数字输入,使用数字键盘
|
||||
final actualKeyboardType = isNumericInput
|
||||
? const TextInputType.numberWithOptions(decimal: true)
|
||||
: keyboardType;
|
||||
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(vertical: vertical_inset, horizontal: horizontal_inset),
|
||||
child: Row(
|
||||
mainAxisAlignment:
|
||||
isEditable
|
||||
mainAxisAlignment: isEditable
|
||||
? MainAxisAlignment.start
|
||||
: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
|
|
@ -61,26 +67,51 @@ class ItemListWidget {
|
|||
child: TextField(
|
||||
autofocus: false,
|
||||
controller: controller,
|
||||
onChanged: onChanged, // <--- 直接回传实时值
|
||||
keyboardType: keyboardType,
|
||||
onChanged: onChanged,
|
||||
onSubmitted: onFieldSubmitted,
|
||||
keyboardType: actualKeyboardType,
|
||||
style: TextStyle(fontSize: fontSize),
|
||||
maxLines: 1,
|
||||
inputFormatters: inputFormatters,
|
||||
// 添加输入格式化器(如果是数字输入)
|
||||
inputFormatters: isNumericInput
|
||||
? [
|
||||
// 过滤非数字和小数点字符
|
||||
FilteringTextInputFormatter.allow(RegExp(r'[\d\.]')),
|
||||
// 自定义格式化器,限制小数位数
|
||||
TextInputFormatter.withFunction((oldValue, newValue) {
|
||||
if (newValue.text.isEmpty) return newValue;
|
||||
|
||||
// 检查多个小数点的情况
|
||||
if (newValue.text.split('.').length > 2) {
|
||||
return oldValue;
|
||||
}
|
||||
|
||||
// 使用正则表达式匹配有效输入
|
||||
if (RegExp(r'^\d*\.?\d{0,' + maxDecimalPlaces.toString() + r'}$')
|
||||
.hasMatch(newValue.text)) {
|
||||
return newValue;
|
||||
}
|
||||
|
||||
return oldValue;
|
||||
}),
|
||||
]
|
||||
: null,
|
||||
decoration: InputDecoration(
|
||||
isDense: true,
|
||||
hintText: hintText,
|
||||
contentPadding: EdgeInsets.symmetric(vertical: 8),
|
||||
),
|
||||
|
||||
),
|
||||
)
|
||||
: Expanded(child: Text(
|
||||
: Expanded(
|
||||
child: Text(
|
||||
text ?? '',
|
||||
maxLines: maxLines,
|
||||
style: TextStyle(fontSize: fontSize, color: detailtextColor),
|
||||
textAlign: TextAlign.right,
|
||||
overflow: TextOverflow.ellipsis, // 超出省略
|
||||
)),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
|
@ -188,6 +219,7 @@ class ItemListWidget {
|
|||
Text('* ', style: TextStyle(color: Colors.red)),
|
||||
Text(
|
||||
label,
|
||||
textAlign: TextAlign.right,
|
||||
style: TextStyle(
|
||||
fontSize: fontSize,
|
||||
fontWeight: FontWeight.bold,
|
||||
|
|
@ -218,9 +250,10 @@ class ItemListWidget {
|
|||
children: [
|
||||
Flexible(
|
||||
child: Text(
|
||||
text.isNotEmpty ? text : '请选择',
|
||||
text.isNotEmpty ? text : (isEditable ? '请选择' : '无'),
|
||||
maxLines: 5,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
textAlign: TextAlign.right,
|
||||
style: TextStyle(
|
||||
fontSize: fontSize,
|
||||
color: isEditable ? (text == '请选择' ? Colors.black87 :Colors.black) : detailtextColor,
|
||||
|
|
|
|||
|
|
@ -599,19 +599,31 @@ class SignaturesListWidget extends StatelessWidget {
|
|||
padding: const EdgeInsets.symmetric(horizontal: 20),
|
||||
child: Wrap(
|
||||
spacing: 8,
|
||||
children:
|
||||
(first['IMG_PATH'] as List)
|
||||
children: (first['IMG_PATH'] as List)
|
||||
.cast<String>()
|
||||
.map(
|
||||
(img) => Image.network(
|
||||
'$baseImgPath$img',
|
||||
.map((img) {
|
||||
final fullUrl = '$baseImgPath$img';
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
presentOpaque(SingleImageViewer(imageUrl: fullUrl), context);
|
||||
},
|
||||
child: Image.network(
|
||||
fullUrl,
|
||||
width: 50,
|
||||
height: 50,
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
fit: BoxFit.cover,
|
||||
errorBuilder: (ctx, err, st) => Container(
|
||||
width: 50,
|
||||
height: 50,
|
||||
color: Colors.grey[200],
|
||||
child: const Icon(Icons.broken_image, size: 20),
|
||||
),
|
||||
),
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
),
|
||||
|
||||
for (var i = 0; i < signPaths.length; i++)
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 20),
|
||||
|
|
|
|||
|
|
@ -116,6 +116,7 @@ class _DangerousOptionsPageState extends State<DangerousOptionsPage> {
|
|||
ToastUtil.showNormal(context, '请签字');
|
||||
return;
|
||||
}
|
||||
LoadingDialogHelper.show();
|
||||
List<String> filePaths =
|
||||
signImgList.map((img) => img.filePath ?? '').toList();
|
||||
final result = await ApiService.saveDangerousOptionsFile(filePaths);
|
||||
|
|
@ -143,6 +144,7 @@ class _DangerousOptionsPageState extends State<DangerousOptionsPage> {
|
|||
}
|
||||
}
|
||||
setState(() => buttonLoading = true);
|
||||
LoadingDialogHelper.hide();
|
||||
Navigator.pop(context, {
|
||||
'imgList':
|
||||
imgList
|
||||
|
|
@ -172,7 +174,7 @@ class _DangerousOptionsPageState extends State<DangerousOptionsPage> {
|
|||
signImgList.add(imageData);
|
||||
signTimes.add(now);
|
||||
});
|
||||
FocusHelper.clearFocus(context);
|
||||
//FocusHelper.clearFocus(context);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -148,12 +148,12 @@ class _HotWorkDetailFormWidgetState extends State<HotWorkDetailFormWidget> {
|
|||
),
|
||||
],
|
||||
const Divider(),
|
||||
ItemListWidget.twoRowSelectableTitleText(
|
||||
ItemListWidget.selectableLineTitleTextRightButton(
|
||||
isRequired: widget.isEditable,
|
||||
label: '动火人及证书编号:',
|
||||
isEditable: widget.isEditable,
|
||||
text:pd['WORK_USER'] ?? '',
|
||||
onTap: widget.onChooseHotworkUser,
|
||||
text: pd['WORK_USER'] ?? '',
|
||||
controller: widget.hotworkPersonController,
|
||||
),
|
||||
const Divider(),
|
||||
ItemListWidget.twoRowButtonTitleText(
|
||||
|
|
@ -175,7 +175,7 @@ class _HotWorkDetailFormWidgetState extends State<HotWorkDetailFormWidget> {
|
|||
},
|
||||
),
|
||||
);
|
||||
FocusHelper.clearFocus(context);
|
||||
//FocusHelper.clearFocus(context);
|
||||
},
|
||||
hintText: '请输入关联的其他特殊作业及安全作业票编号',
|
||||
controller: widget.relatedController,
|
||||
|
|
@ -200,7 +200,7 @@ class _HotWorkDetailFormWidgetState extends State<HotWorkDetailFormWidget> {
|
|||
},
|
||||
),
|
||||
);
|
||||
FocusHelper.clearFocus(context);
|
||||
//FocusHelper.clearFocus(context);
|
||||
},
|
||||
hintText: '请输入风险辨识结果',
|
||||
controller: widget.riskController,
|
||||
|
|
@ -318,7 +318,7 @@ class _HotWorkDetailFormWidgetState extends State<HotWorkDetailFormWidget> {
|
|||
text: pd['LATITUDE_LONGITUDE'] ?? (widget.isEditable ? '' : '无'),
|
||||
),
|
||||
|
||||
if (FormUtils.hasValue(pd, 'ANALYZE_TIME')) ...[
|
||||
if (FormUtils.hasValue(pd, 'ANALYZE_TIME') && !widget.isEditable) ...[
|
||||
const Divider(),
|
||||
ItemListWidget.OneRowButtonTitleText(
|
||||
label: '分析人:',
|
||||
|
|
|
|||
|
|
@ -87,7 +87,6 @@ class _HotworkSafeFuncSureState extends State<HotworkSafeFuncSure> {
|
|||
/// 签字
|
||||
Future<void> _sign() async {
|
||||
await NativeOrientation.setLandscape();
|
||||
FocusHelper.clearFocus(context);
|
||||
final path = await Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(builder: (context) => MineSignPage()),
|
||||
|
|
@ -95,11 +94,9 @@ class _HotworkSafeFuncSureState extends State<HotworkSafeFuncSure> {
|
|||
await NativeOrientation.setPortrait();
|
||||
if (path != null) {
|
||||
final now = DateFormat('yyyy-MM-dd HH:mm').format(DateTime.now());
|
||||
|
||||
setState(() {
|
||||
imagePaths.add(path);
|
||||
signTimes.add(now);
|
||||
FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,7 +61,6 @@ class _HotworkAqglDetailState extends State<HotworkAqglDetail> {
|
|||
setState(() {
|
||||
signImages.add(path);
|
||||
signTimes.add(now);
|
||||
FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -90,7 +90,6 @@ class _HotworkAqjdDetailState extends State<HotworkAqjdDetail> {
|
|||
setState(() {
|
||||
signImages.add(path);
|
||||
signTimes.add(now);
|
||||
FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,7 +63,6 @@ class _HotworkDbbzDetailState extends State<HotworkDbbzDetail> {
|
|||
setState(() {
|
||||
signImages.add(path);
|
||||
signTimes.add(now);
|
||||
FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ class _HotworkApplyDetailState extends State<HotworkApplyDetail> {
|
|||
_getData();
|
||||
} else {
|
||||
isEditable = true;
|
||||
// pd['ANALYZE_TIME'] = 1;
|
||||
pd['ANALYZE_TIME'] = 1;
|
||||
pd['APPLY_DEPARTMENT_ID'] = SessionService.instance.deptId;
|
||||
pd['APPLY_DEPARTMENT_NAME'] =
|
||||
SessionService.instance.loginUser!['DEPARTMENT_NAME'] ?? '';
|
||||
|
|
@ -187,7 +187,7 @@ class _HotworkApplyDetailState extends State<HotworkApplyDetail> {
|
|||
// 用户点击确定并选择了 choice
|
||||
setState(() {
|
||||
pd['WORK_LEVEL'] = choice;
|
||||
FocusHelper.clearFocus(context);
|
||||
//FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -210,7 +210,7 @@ class _HotworkApplyDetailState extends State<HotworkApplyDetail> {
|
|||
if (FormUtils.hasValue(result, 'USER_ID')) {
|
||||
pd['WORK_USER_ID'] = result['USER_ID'];
|
||||
}
|
||||
FocusHelper.clearFocus(context);
|
||||
//FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -238,7 +238,7 @@ class _HotworkApplyDetailState extends State<HotworkApplyDetail> {
|
|||
if (FormUtils.hasValue(result, 'VIDEOMANAGER_ID')) {
|
||||
pd['VIDEOMANAGER_ID'] = result['VIDEOMANAGER_ID'];
|
||||
}
|
||||
FocusHelper.clearFocus(context);
|
||||
//FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -261,7 +261,7 @@ class _HotworkApplyDetailState extends State<HotworkApplyDetail> {
|
|||
if (FormUtils.hasValue(result, 'UNITS_ID')) {
|
||||
pd['UNITS_ID'] = result['UNITS_ID'];
|
||||
}
|
||||
FocusHelper.clearFocus(context);
|
||||
//FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -272,17 +272,18 @@ class _HotworkApplyDetailState extends State<HotworkApplyDetail> {
|
|||
ToastUtil.showNormal(context, '请选择作业区域');
|
||||
return;
|
||||
}
|
||||
Map mapData = await pushPage(MapPage(gson: pd['POSITIONS']), context);
|
||||
final mapData = await pushPage(MapPage(gson: pd['POSITIONS']), context);
|
||||
setState(() {
|
||||
pd['LONGITUDE'] = mapData['longitue'];
|
||||
pd['LATITUDE'] = mapData['latitude'];
|
||||
pd['LATITUDE_LONGITUDE'] = '${mapData['longitue']},${mapData['latitude']}';
|
||||
pd['LONGITUDE'] = mapData['longitue'] ?? '';
|
||||
pd['LATITUDE'] = mapData['latitude'] ?? '';
|
||||
pd['LATITUDE_LONGITUDE'] = '${mapData['longitue'] ?? ''},${mapData['latitude'] ?? ''}';
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
/// 作业区域
|
||||
Future<void> _getWorkArea() async {
|
||||
FocusHelper.clearFocus(context);
|
||||
//FocusHelper.clearFocus(context);
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
isScrollControlled: true,
|
||||
|
|
@ -297,7 +298,7 @@ class _HotworkApplyDetailState extends State<HotworkApplyDetail> {
|
|||
},
|
||||
),
|
||||
).then((_) {
|
||||
FocusHelper.clearFocus(context);
|
||||
//FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
/// 获取摄像头列表
|
||||
|
|
@ -390,7 +391,7 @@ class _HotworkApplyDetailState extends State<HotworkApplyDetail> {
|
|||
|
||||
/// 弹出单位选择
|
||||
void chooseUnitHandle(EditUserType type) {
|
||||
FocusHelper.clearFocus(context);
|
||||
//FocusHelper.clearFocus(context);
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
isScrollControlled: true,
|
||||
|
|
@ -409,7 +410,7 @@ class _HotworkApplyDetailState extends State<HotworkApplyDetail> {
|
|||
},
|
||||
),
|
||||
).then((_) {
|
||||
FocusHelper.clearFocus(context);
|
||||
//FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -425,7 +426,7 @@ class _HotworkApplyDetailState extends State<HotworkApplyDetail> {
|
|||
|
||||
/// 弹出人员选择,需先选择单位
|
||||
void choosePersonHandle(EditUserType type) async {
|
||||
FocusHelper.clearFocus(context);
|
||||
//FocusHelper.clearFocus(context);
|
||||
|
||||
String unitId = get_pd_DEPARTMENT_ID(type);
|
||||
final personList = _personCache[type] ?? [];
|
||||
|
|
@ -464,7 +465,7 @@ class _HotworkApplyDetailState extends State<HotworkApplyDetail> {
|
|||
});
|
||||
},
|
||||
).then((_) {
|
||||
FocusHelper.clearFocus(context);
|
||||
//FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -530,8 +531,8 @@ class _HotworkApplyDetailState extends State<HotworkApplyDetail> {
|
|||
ToastUtil.showNormal(context, '请选择预计作业开始时间');
|
||||
return;
|
||||
}
|
||||
if (!FormUtils.hasValue(pd, 'WORK_EXPECTED_START_TIME')) {
|
||||
ToastUtil.showNormal(context, '请选择预计作业开始时间');
|
||||
if (!FormUtils.hasValue(pd, 'WORK_EXPECTED_END_TIME')) {
|
||||
ToastUtil.showNormal(context, '请选择预计作业结束时间');
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -61,7 +61,6 @@ class _HotworkDhspDetailState extends State<HotworkDhspDetail> {
|
|||
setState(() {
|
||||
signImages.add(path);
|
||||
signTimes.add(now);
|
||||
FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,7 +27,12 @@ import 'package:qhd_prevention/pages/home/tap/tabList/special_Wrok/dh_work/jsjd_
|
|||
class HotWorkListPage extends StatefulWidget {
|
||||
final String flow;
|
||||
final String workTypeTitle;
|
||||
const HotWorkListPage({Key? key, required this.flow, required this.workTypeTitle}) : super(key: key);
|
||||
|
||||
const HotWorkListPage({
|
||||
Key? key,
|
||||
required this.flow,
|
||||
required this.workTypeTitle,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
_HotWorkListPageState createState() => _HotWorkListPageState();
|
||||
|
|
@ -131,6 +136,7 @@ class _HotWorkListPageState extends State<HotWorkListPage> {
|
|||
list.clear();
|
||||
_fetchData();
|
||||
}
|
||||
|
||||
/// 申请
|
||||
void _handleApply() {
|
||||
// 处理申请按钮点击逻辑
|
||||
|
|
@ -140,7 +146,7 @@ class _HotWorkListPageState extends State<HotWorkListPage> {
|
|||
/// 打开流程图
|
||||
Future<void> _openFlowDrawer(String hotworkId) async {
|
||||
try {
|
||||
final response = await ApiService.workGetFlowList('', hotworkId);
|
||||
final response = await ApiService.workGetFlowList('hotwork', hotworkId);
|
||||
final List<dynamic>? newFlow = response['flowList'];
|
||||
if (newFlow == null || newFlow.isEmpty) {
|
||||
ToastUtil.showNormal(context, '暂无流程图数据');
|
||||
|
|
@ -161,7 +167,6 @@ class _HotWorkListPageState extends State<HotWorkListPage> {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void _goToDetail(Map<String, dynamic> item) async {
|
||||
final allowed = await WorkAreaHelper.checkInSpecialWorkArea(
|
||||
context: context,
|
||||
|
|
@ -172,59 +177,110 @@ class _HotWorkListPageState extends State<HotWorkListPage> {
|
|||
|
||||
switch (widget.flow) {
|
||||
case '提交申请':
|
||||
await pushPage(HotworkApplyDetail(HOTWORK_ID: item['HOTWORK_ID'], flow: widget.flow), context);
|
||||
await pushPage(
|
||||
HotworkApplyDetail(HOTWORK_ID: item['HOTWORK_ID'], flow: widget.flow),
|
||||
context,
|
||||
);
|
||||
_fetchData();
|
||||
break;
|
||||
case '气体检测':
|
||||
await pushPage(HotworkGasList(HOTWORK_ID: item['HOTWORK_ID'], addFlag:true), context);
|
||||
await pushPage(
|
||||
HotworkGasList(HOTWORK_ID: item['HOTWORK_ID'], addFlag: true),
|
||||
context,
|
||||
);
|
||||
break;
|
||||
case '设置安全措施确认人':
|
||||
await pushPage(HotworkSetSafeDetail(HOTWORK_ID: item['HOTWORK_ID'], flow: widget.flow), context);
|
||||
await pushPage(
|
||||
HotworkSetSafeDetail(
|
||||
HOTWORK_ID: item['HOTWORK_ID'],
|
||||
flow: widget.flow,
|
||||
),
|
||||
context,
|
||||
);
|
||||
break;
|
||||
case '安全措施确认':
|
||||
await pushPage(HotworkSafeFuncSure(HOTWORK_ID: item['HOTWORK_ID'], flow: widget.flow), context);
|
||||
await pushPage(
|
||||
HotworkSafeFuncSure(
|
||||
HOTWORK_ID: item['HOTWORK_ID'],
|
||||
flow: widget.flow,
|
||||
),
|
||||
context,
|
||||
);
|
||||
break;
|
||||
case '监护人签字':
|
||||
await pushPage(HotworkJhrDetail(HOTWORK_ID: item['HOTWORK_ID'], flow: widget.flow), context);
|
||||
await pushPage(
|
||||
HotworkJhrDetail(HOTWORK_ID: item['HOTWORK_ID'], flow: widget.flow),
|
||||
context,
|
||||
);
|
||||
break;
|
||||
case '安全交底人签字':
|
||||
await pushPage(HotworkAqjdDetail(HOTWORK_ID: item['HOTWORK_ID'], flow: widget.flow), context);
|
||||
await pushPage(
|
||||
HotworkAqjdDetail(HOTWORK_ID: item['HOTWORK_ID'], flow: widget.flow),
|
||||
context,
|
||||
);
|
||||
|
||||
break;
|
||||
case '接受交底人签字':
|
||||
await pushPage(HotworkJsjdDetail(HOTWORK_ID: item['HOTWORK_ID'], flow: widget.flow), context);
|
||||
await pushPage(
|
||||
HotworkJsjdDetail(HOTWORK_ID: item['HOTWORK_ID'], flow: widget.flow),
|
||||
context,
|
||||
);
|
||||
|
||||
break;
|
||||
case '作业负责人签字':
|
||||
await pushPage(HotworkZyfzDetail(HOTWORK_ID: item['HOTWORK_ID'], flow: widget.flow), context);
|
||||
await pushPage(
|
||||
HotworkZyfzDetail(HOTWORK_ID: item['HOTWORK_ID'], flow: widget.flow),
|
||||
context,
|
||||
);
|
||||
|
||||
break;
|
||||
case '所在单位签字':
|
||||
await pushPage(HotworkSzdwDetail(HOTWORK_ID: item['HOTWORK_ID'], flow: widget.flow), context);
|
||||
await pushPage(
|
||||
HotworkSzdwDetail(HOTWORK_ID: item['HOTWORK_ID'], flow: widget.flow),
|
||||
context,
|
||||
);
|
||||
|
||||
break;
|
||||
case '安全管理部门签字':
|
||||
await pushPage(HotworkAqglDetail(HOTWORK_ID: item['HOTWORK_ID'], flow: widget.flow), context);
|
||||
await pushPage(
|
||||
HotworkAqglDetail(HOTWORK_ID: item['HOTWORK_ID'], flow: widget.flow),
|
||||
context,
|
||||
);
|
||||
|
||||
break;
|
||||
case '审批人签字':
|
||||
await pushPage(HotworkDhspDetail(HOTWORK_ID: item['HOTWORK_ID'], flow: widget.flow), context);
|
||||
await pushPage(
|
||||
HotworkDhspDetail(HOTWORK_ID: item['HOTWORK_ID'], flow: widget.flow),
|
||||
context,
|
||||
);
|
||||
|
||||
break;
|
||||
case '当班班长验票':
|
||||
await pushPage(HotworkDbbzDetail(HOTWORK_ID: item['HOTWORK_ID'], flow: widget.flow), context);
|
||||
await pushPage(
|
||||
HotworkDbbzDetail(HOTWORK_ID: item['HOTWORK_ID'], flow: widget.flow),
|
||||
context,
|
||||
);
|
||||
|
||||
break;
|
||||
case '开始作业':
|
||||
await pushPage(HotworkKszyDetail(HOTWORK_ID: item['HOTWORK_ID'], flow: widget.flow), context);
|
||||
await pushPage(
|
||||
HotworkKszyDetail(HOTWORK_ID: item['HOTWORK_ID'], flow: widget.flow),
|
||||
context,
|
||||
);
|
||||
|
||||
break;
|
||||
case '结束作业':
|
||||
await pushPage(HotworkJszyDetail(HOTWORK_ID: item['HOTWORK_ID'], flow: widget.flow), context);
|
||||
await pushPage(
|
||||
HotworkJszyDetail(HOTWORK_ID: item['HOTWORK_ID'], flow: widget.flow),
|
||||
context,
|
||||
);
|
||||
|
||||
break;
|
||||
case '验收签字':
|
||||
await pushPage(HotworkYsgdDetail(HOTWORK_ID: item['HOTWORK_ID'], flow: widget.flow), context);
|
||||
await pushPage(
|
||||
HotworkYsgdDetail(HOTWORK_ID: item['HOTWORK_ID'], flow: widget.flow),
|
||||
context,
|
||||
);
|
||||
|
||||
break;
|
||||
default:
|
||||
|
|
@ -246,9 +302,7 @@ class _HotWorkListPageState extends State<HotWorkListPage> {
|
|||
final Color dotColor =
|
||||
status == 1 ? Colors.green : (status == 0 ? Colors.blue : Colors.grey);
|
||||
final Color textColor =
|
||||
status == 1
|
||||
? Colors.green
|
||||
: (status == 0 ? Colors.blue : Colors.black);
|
||||
status == 1 ? Colors.green : (status == 0 ? Colors.blue : Colors.black);
|
||||
|
||||
return ListTile(
|
||||
visualDensity: VisualDensity(vertical: -4),
|
||||
|
|
@ -319,8 +373,14 @@ class _HotWorkListPageState extends State<HotWorkListPage> {
|
|||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text("编号: ${item['CHECK_NO'] ?? ''}", style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),),
|
||||
Text("作业级别: ${item['WORK_LEVEL'] ?? ''}", style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),),
|
||||
Text(
|
||||
"编号: ${item['CHECK_NO'] ?? ''}",
|
||||
style: TextStyle(fontSize: 14, fontWeight: FontWeight.bold),
|
||||
),
|
||||
Text(
|
||||
"作业级别: ${item['WORK_LEVEL'] ?? ''}",
|
||||
style: TextStyle(fontSize: 14, fontWeight: FontWeight.bold),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
|
|
@ -343,27 +403,47 @@ class _HotWorkListPageState extends State<HotWorkListPage> {
|
|||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text("安全交底人: ${item['CONFESS_USER_NAME'] ?? ''}"),
|
||||
Text("接受交底人: ${item['ACCEPT_CONFESS_USER_NAME'] ?? ''}"),
|
||||
Expanded(child: Text("安全交底人: ${item['CONFESS_USER_NAME'] ?? ''}",softWrap: true,
|
||||
maxLines: null, // 不限制行数
|
||||
overflow: TextOverflow.visible,)
|
||||
),
|
||||
Expanded(child: Text("接受交底人: ${item['ACCEPT_CONFESS_USER_NAME'] ?? ''}",softWrap: true,
|
||||
textAlign: TextAlign.right,
|
||||
maxLines: null, // 不限制行数
|
||||
overflow: TextOverflow.visible,)
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text("作业负责人: ${item['CONFIRM_USER_NAME'] ?? ''}"),
|
||||
Text("动火点负责人: ${item['LEADER_USER_NAME'] ?? ''}"),
|
||||
Expanded(child: Text("作业负责人: ${item['CONFIRM_USER_NAME'] ?? ''}",softWrap: true,
|
||||
maxLines: null, // 不限制行数
|
||||
overflow: TextOverflow.visible,)
|
||||
),
|
||||
Expanded(child: Text("动火点负责人: ${item['LEADER_USER_NAME'] ?? ''}",softWrap: true,
|
||||
textAlign: TextAlign.right,
|
||||
maxLines: null, // 不限制行数
|
||||
overflow: TextOverflow.visible,)
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
if (item['AUDIT_USER_NAME'] != null)
|
||||
Text("安全管理部门负责人: ${item['AUDIT_USER_NAME'] ?? ''}"),
|
||||
const SizedBox(height: 8),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [Text("动火前在岗班长: ${item['MONITOR_USER_NAME'] ?? ''}")],
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text("动火前在岗班长: ${item['MONITOR_USER_NAME'] ?? ''}"),
|
||||
Text("验收部门负责人: ${item['ACCEPT_USER_NAME'] ?? ''}"),
|
||||
Expanded(
|
||||
child: Text("验收部门负责人: ${item['ACCEPT_USER_NAME'] ?? ''}"),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
|
|
@ -379,7 +459,8 @@ class _HotWorkListPageState extends State<HotWorkListPage> {
|
|||
],
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Row(children: [
|
||||
Row(
|
||||
children: [
|
||||
CustomButton(
|
||||
text: '查看流程图',
|
||||
height: 35,
|
||||
|
|
@ -388,8 +469,9 @@ class _HotWorkListPageState extends State<HotWorkListPage> {
|
|||
backgroundColor: Colors.blue,
|
||||
onPressed: () => _openFlowDrawer(item['HOTWORK_ID']),
|
||||
),
|
||||
SizedBox(width: 1,)
|
||||
],)
|
||||
SizedBox(width: 1),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -60,7 +60,6 @@ class _HotworkJhrDetailState extends State<HotworkJhrDetail> {
|
|||
setState(() {
|
||||
imagePaths.add(path);
|
||||
signTimes.add(now);
|
||||
FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,7 +61,6 @@ class _HotworkJsjdDetailState extends State<HotworkJsjdDetail> {
|
|||
setState(() {
|
||||
signImages.add(path);
|
||||
signTimes.add(now);
|
||||
FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,7 +64,6 @@ class _HotworkJszyDetailState extends State<HotworkJszyDetail> {
|
|||
setState(() {
|
||||
signImages.add(path);
|
||||
signTimes.add(now);
|
||||
FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -65,7 +65,6 @@ class _HotworkKszyDetailState extends State<HotworkKszyDetail> {
|
|||
setState(() {
|
||||
signImages.add(path);
|
||||
signTimes.add(now);
|
||||
FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,6 +26,11 @@ class HotworkGasList extends StatefulWidget {
|
|||
class _HotworkGasListState extends State<HotworkGasList> {
|
||||
late List list = [];
|
||||
bool isLoading = true;
|
||||
List<Map<String, dynamic>> GAS_TYPE_LIST = [
|
||||
{"NAME": "有毒", "VALUE": "1"},
|
||||
{"NAME": "可燃", "VALUE": "2"},
|
||||
{"NAME": "氧气", "VALUE": "3"},
|
||||
];
|
||||
|
||||
Future<void> _getListData() async {
|
||||
final data = await ApiService.workGasList('hotwork', widget.HOTWORK_ID);
|
||||
|
|
@ -50,11 +55,19 @@ class _HotworkGasListState extends State<HotworkGasList> {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
String getGasTypeName(String type) {
|
||||
for (Map item in GAS_TYPE_LIST) {
|
||||
if (item['VALUE'] == type) {
|
||||
return item['NAME'];
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
Widget _buildListItem(Map item) {
|
||||
final images = (item['SIGN_PATH'] as String?)?.split(',') ?? [];
|
||||
final baseImgPath = ApiService.baseImgPath;
|
||||
|
||||
String typeName = item['GAS_TYPE'] == '1' ? '有毒' : (item['GAS_TYPE'] == '2' ? '可燃' : (item['GAS_TYPE'] == '3' ? '氧气':''));
|
||||
return Container(
|
||||
color: Colors.white,
|
||||
margin: const EdgeInsets.symmetric(vertical: 5, horizontal: 5),
|
||||
|
|
@ -64,6 +77,14 @@ class _HotworkGasListState extends State<HotworkGasList> {
|
|||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text('气体类型: $typeName'),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 6),
|
||||
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
|
|
@ -72,6 +93,22 @@ class _HotworkGasListState extends State<HotworkGasList> {
|
|||
],
|
||||
),
|
||||
const SizedBox(height: 6),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text('上限: ${item['UPPER_LIMIT'] ?? ''}'),
|
||||
Text('下限: ${item['LOWER_LIMIT'] ?? ''}'),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 6),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text('检测值: ${item['GAS_VALUE'] ?? ''}'),
|
||||
Text('计量单位: ${item['GAS_UNIT'] ?? ''}'),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 6),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
|
|
|
|||
|
|
@ -163,7 +163,6 @@ class _HotworkSetSafeDetailState extends State<HotworkSetSafeDetail> {
|
|||
/// 签字
|
||||
Future<void> _sign() async {
|
||||
await NativeOrientation.setLandscape();
|
||||
FocusHelper.clearFocus(context);
|
||||
final path = await Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(builder: (context) => MineSignPage()),
|
||||
|
|
@ -175,7 +174,6 @@ class _HotworkSetSafeDetailState extends State<HotworkSetSafeDetail> {
|
|||
setState(() {
|
||||
imagePaths.add(path);
|
||||
signTimes.add(now);
|
||||
FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,7 +61,6 @@ class _HotworkSzdwDetailState extends State<HotworkSzdwDetail> {
|
|||
setState(() {
|
||||
signImages.add(path);
|
||||
signTimes.add(now);
|
||||
FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -97,7 +97,6 @@ class _HotworkYsgdDetailState extends State<HotworkYsgdDetail> {
|
|||
setState(() {
|
||||
signImages.add(path);
|
||||
signTimes.add(now);
|
||||
FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -376,7 +375,7 @@ class _HotworkYsgdDetailState extends State<HotworkYsgdDetail> {
|
|||
'yyyy-MM-dd HH:mm:ss',
|
||||
).format(picked);
|
||||
});
|
||||
FocusHelper.clearFocus(context);
|
||||
//FocusHelper.clearFocus(context);
|
||||
}
|
||||
},
|
||||
),
|
||||
|
|
|
|||
|
|
@ -61,7 +61,6 @@ class _HotworkZyfzDetailState extends State<HotworkZyfzDetail> {
|
|||
setState(() {
|
||||
signImages.add(path);
|
||||
signTimes.add(now);
|
||||
FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -326,7 +326,7 @@ class _CutroadDetailFormWidgetState extends State<CutroadDetailFormWidget> {
|
|||
},
|
||||
),
|
||||
);
|
||||
FocusHelper.clearFocus(context);
|
||||
//FocusHelper.clearFocus(context);
|
||||
},
|
||||
hintText: '请输入关联的其他特殊作业及安全作业票编号',
|
||||
controller: widget.relatedController,
|
||||
|
|
@ -350,7 +350,7 @@ class _CutroadDetailFormWidgetState extends State<CutroadDetailFormWidget> {
|
|||
},
|
||||
),
|
||||
);
|
||||
FocusHelper.clearFocus(context);
|
||||
//FocusHelper.clearFocus(context);
|
||||
},
|
||||
hintText: '请输入风险辨识结果',
|
||||
controller: widget.riskController,
|
||||
|
|
|
|||
|
|
@ -90,7 +90,6 @@ class _CutroadSafeFuncSureState extends State<CutroadSafeFuncSure> {
|
|||
/// 签字
|
||||
Future<void> _sign() async {
|
||||
await NativeOrientation.setLandscape();
|
||||
FocusHelper.clearFocus(context);
|
||||
final path = await Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(builder: (context) => MineSignPage()),
|
||||
|
|
@ -101,7 +100,6 @@ if (path != null) {
|
|||
setState(() {
|
||||
imagePaths.add(path);
|
||||
signTimes.add(now);
|
||||
FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -331,7 +329,7 @@ if (path != null) {
|
|||
// 更新状态、序号等
|
||||
measures['STATUS'] = result['status'].toString();
|
||||
index = result['index'] as int;
|
||||
FocusHelper.clearFocus(context);
|
||||
//FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -89,7 +89,6 @@ class _CutroadAqjdDetailState extends State<CutroadAqjdDetail> {
|
|||
setState(() {
|
||||
signImages.add(path);
|
||||
signTimes.add(now);
|
||||
FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -320,7 +320,7 @@ class _CutroadListPageState extends State<CutroadListPage> {
|
|||
children: [
|
||||
Text(
|
||||
"编号: ${item['CHECK_NO'] ?? ''}",
|
||||
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
|
||||
style: TextStyle(fontSize: 14, fontWeight: FontWeight.bold),
|
||||
),
|
||||
|
||||
],
|
||||
|
|
@ -329,35 +329,64 @@ class _CutroadListPageState extends State<CutroadListPage> {
|
|||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text("申请人: ${item['APPLY_USER_NAME'] ?? ''}"),
|
||||
Text("作业项目负责人: ${item['PROJECT_MANAGER_USER_NAME'] ?? ''}"),
|
||||
Expanded(child: Text("作业项目负责人: ${item['PROJECT_MANAGER_USER_NAME'] ?? ''}",softWrap: true,
|
||||
textAlign: TextAlign.right,
|
||||
maxLines: null, // 不限制行数
|
||||
overflow: TextOverflow.visible,)
|
||||
),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text("监护人: ${item['GUARDIAN_USER_NAME'] ?? ''}"),
|
||||
Text("安全交底人: ${item['CONFESS_USER_NAME'] ?? ''}"),
|
||||
Expanded(child: Text("安全交底人: ${item['CONFESS_USER_NAME'] ?? ''}",softWrap: true,
|
||||
textAlign: TextAlign.right,
|
||||
maxLines: null, // 不限制行数
|
||||
overflow: TextOverflow.visible,)
|
||||
),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text("接受交底人: ${item['ACCEPT_CONFESS_USER_NAME'] ?? ''}"),
|
||||
Text("作业负责人: ${item['CONFIRM_USER_NAME'] ?? ''}"),
|
||||
Expanded(child: Text("接受交底人: ${item['ACCEPT_CONFESS_USER_NAME'] ?? ''}",softWrap: true,
|
||||
maxLines: null, // 不限制行数
|
||||
overflow: TextOverflow.visible,)
|
||||
),
|
||||
Expanded(child: Text("作业负责人: ${item['CONFIRM_USER_NAME'] ?? ''}",softWrap: true,
|
||||
textAlign: TextAlign.right,
|
||||
maxLines: null, // 不限制行数
|
||||
overflow: TextOverflow.visible,)
|
||||
),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text("所在单位负责人: ${item['LEADER_USER_NAME'] ?? ''}"),
|
||||
Text("消防、安全管理部门: ${item['AUDIT_USER_NAME'] ?? ''}"),
|
||||
Expanded(child: Text("所在单位负责人: ${item['LEADER_USER_NAME'] ?? ''}",softWrap: true,
|
||||
maxLines: null, // 不限制行数
|
||||
overflow: TextOverflow.visible,)
|
||||
),
|
||||
Expanded(child: Text("消防、安全管理部门: ${item['AUDIT_USER_NAME'] ?? ''}",softWrap: true,
|
||||
textAlign: TextAlign.right,
|
||||
maxLines: null, // 不限制行数
|
||||
overflow: TextOverflow.visible,)
|
||||
),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text("审批部门负责人: ${item['APPROVE_USER_NAME'] ?? ''}"),
|
||||
Text("验收部门负责人: ${item['ACCEPT_USER_NAME'] ?? ''}"),
|
||||
Expanded(child: Text("审批部门负责人: ${item['APPROVE_USER_NAME'] ?? ''}",softWrap: true,
|
||||
maxLines: null, // 不限制行数
|
||||
overflow: TextOverflow.visible,)
|
||||
),
|
||||
Expanded(child: Text("验收部门负责人: ${item['ACCEPT_USER_NAME'] ?? ''}",softWrap: true,
|
||||
maxLines: null, // 不限制行数
|
||||
textAlign: TextAlign.right,
|
||||
overflow: TextOverflow.visible,)
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
|
|
|
|||
|
|
@ -199,7 +199,7 @@ class _CutroadApplyDetailState extends State<CutroadApplyDetail> {
|
|||
|
||||
/// 弹出单位选择
|
||||
void chooseUnitHandle(EditUserType type) {
|
||||
FocusHelper.clearFocus(context);
|
||||
//FocusHelper.clearFocus(context);
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
isScrollControlled: true,
|
||||
|
|
@ -218,7 +218,7 @@ class _CutroadApplyDetailState extends State<CutroadApplyDetail> {
|
|||
},
|
||||
),
|
||||
).then((_) {
|
||||
FocusHelper.clearFocus(context);
|
||||
//FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -234,7 +234,7 @@ class _CutroadApplyDetailState extends State<CutroadApplyDetail> {
|
|||
|
||||
/// 弹出人员选择,需先选择单位
|
||||
void choosePersonHandle(EditUserType type) async {
|
||||
FocusHelper.clearFocus(context);
|
||||
//FocusHelper.clearFocus(context);
|
||||
|
||||
String unitId = get_pd_DEPARTMENT_ID(type);
|
||||
final personList = _personCache[type] ?? [];
|
||||
|
|
@ -270,7 +270,7 @@ class _CutroadApplyDetailState extends State<CutroadApplyDetail> {
|
|||
});
|
||||
},
|
||||
).then((_) {
|
||||
FocusHelper.clearFocus(context);
|
||||
//FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -414,7 +414,7 @@ class _CutroadApplyDetailState extends State<CutroadApplyDetail> {
|
|||
if (FormUtils.hasValue(result, 'VIDEOMANAGER_ID')) {
|
||||
pd['VIDEOMANAGER_ID'] = result['VIDEOMANAGER_ID'];
|
||||
}
|
||||
FocusHelper.clearFocus(context);
|
||||
//FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -437,7 +437,7 @@ class _CutroadApplyDetailState extends State<CutroadApplyDetail> {
|
|||
if (FormUtils.hasValue(result, 'UNITS_ID')) {
|
||||
pd['UNITS_ID'] = result['UNITS_ID'];
|
||||
}
|
||||
FocusHelper.clearFocus(context);
|
||||
//FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -449,17 +449,17 @@ class _CutroadApplyDetailState extends State<CutroadApplyDetail> {
|
|||
ToastUtil.showNormal(context, '请选择作业区域');
|
||||
return;
|
||||
}
|
||||
Map mapData = await pushPage(MapPage(gson: pd['POSITIONS']), context);
|
||||
final mapData = await pushPage(MapPage(gson: pd['POSITIONS']), context);
|
||||
setState(() {
|
||||
pd['LONGITUDE'] = mapData['longitue'];
|
||||
pd['LATITUDE'] = mapData['latitude'];
|
||||
pd['LATITUDE_LONGITUDE'] = '${mapData['longitue']},${mapData['latitude']}';
|
||||
pd['LONGITUDE'] = mapData['longitue'] ?? '';
|
||||
pd['LATITUDE'] = mapData['latitude'] ?? '';
|
||||
pd['LATITUDE_LONGITUDE'] = '${mapData['longitue'] ?? ''},${mapData['latitude'] ?? ''}';
|
||||
});
|
||||
|
||||
}
|
||||
/// 作业区域
|
||||
Future<void> _getWorkArea() async {
|
||||
FocusHelper.clearFocus(context);
|
||||
//FocusHelper.clearFocus(context);
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
isScrollControlled: true,
|
||||
|
|
@ -474,7 +474,7 @@ class _CutroadApplyDetailState extends State<CutroadApplyDetail> {
|
|||
},
|
||||
),
|
||||
).then((_) {
|
||||
FocusHelper.clearFocus(context);
|
||||
//FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
/// 获取摄像头列表
|
||||
|
|
|
|||
|
|
@ -60,7 +60,6 @@ if (path != null) {
|
|||
setState(() {
|
||||
imagePaths.add(path);
|
||||
signTimes.add(now);
|
||||
FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,7 +61,6 @@ class _CutroadJsjdDetailState extends State<CutroadJsjdDetail> {
|
|||
setState(() {
|
||||
signImages.add(path);
|
||||
signTimes.add(now);
|
||||
FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,7 +64,6 @@ class _CutroadJszyDetailState extends State<CutroadJszyDetail> {
|
|||
setState(() {
|
||||
signImages.add(path);
|
||||
signTimes.add(now);
|
||||
FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -65,7 +65,6 @@ class _CutroadKszyDetailState extends State<CutroadKszyDetail> {
|
|||
setState(() {
|
||||
signImages.add(path);
|
||||
signTimes.add(now);
|
||||
FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,7 +61,6 @@ class _CutroadShbmDetailState extends State<CutroadShbmDetail> {
|
|||
setState(() {
|
||||
signImages.add(path);
|
||||
signTimes.add(now);
|
||||
FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,7 +60,6 @@ class _CutroadSpbmDetailState extends State<CutroadSpbmDetail> {
|
|||
setState(() {
|
||||
signImages.add(path);
|
||||
signTimes.add(now);
|
||||
FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -174,7 +174,6 @@ if (path != null) {
|
|||
setState(() {
|
||||
imagePaths.add(path);
|
||||
signTimes.add(now);
|
||||
FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,7 +61,6 @@ class _CutroadSzdwDetailState extends State<CutroadSzdwDetail> {
|
|||
setState(() {
|
||||
signImages.add(path);
|
||||
signTimes.add(now);
|
||||
FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -96,7 +96,6 @@ class _CutroadYsgdDetailState extends State<CutroadYsgdDetail> {
|
|||
setState(() {
|
||||
signImages.add(path);
|
||||
signTimes.add(now);
|
||||
FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -367,7 +366,7 @@ class _CutroadYsgdDetailState extends State<CutroadYsgdDetail> {
|
|||
'yyyy-MM-dd HH:mm',
|
||||
).format(picked);
|
||||
});
|
||||
FocusHelper.clearFocus(context);
|
||||
//FocusHelper.clearFocus(context);
|
||||
}
|
||||
},
|
||||
),
|
||||
|
|
|
|||
|
|
@ -61,7 +61,6 @@ class _CutroadZyfzDetailState extends State<CutroadZyfzDetail> {
|
|||
setState(() {
|
||||
signImages.add(path);
|
||||
signTimes.add(now);
|
||||
FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -70,7 +70,6 @@ class _CutroadZyrDetailState extends State<CutroadZyrDetail> {
|
|||
setState(() {
|
||||
signImages.add(path);
|
||||
signTimes.add(now);
|
||||
FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -372,7 +372,7 @@ class _BreakgroundDetailFormWidgetState
|
|||
},
|
||||
),
|
||||
);
|
||||
FocusHelper.clearFocus(context);
|
||||
//FocusHelper.clearFocus(context);
|
||||
},
|
||||
hintText: '请输入关联的其他特殊作业及安全作业票编号',
|
||||
controller: widget.relatedController,
|
||||
|
|
@ -397,7 +397,7 @@ class _BreakgroundDetailFormWidgetState
|
|||
},
|
||||
),
|
||||
);
|
||||
FocusHelper.clearFocus(context);
|
||||
//FocusHelper.clearFocus(context);
|
||||
},
|
||||
hintText: '请输入风险辨识结果',
|
||||
controller: widget.riskController,
|
||||
|
|
|
|||
|
|
@ -87,7 +87,6 @@ class _BreakgroundSafeFuncSureState extends State<BreakgroundSafeFuncSure> {
|
|||
/// 签字
|
||||
Future<void> _sign() async {
|
||||
await NativeOrientation.setLandscape();
|
||||
FocusHelper.clearFocus(context);
|
||||
final path = await Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(builder: (context) => MineSignPage()),
|
||||
|
|
@ -98,7 +97,6 @@ class _BreakgroundSafeFuncSureState extends State<BreakgroundSafeFuncSure> {
|
|||
setState(() {
|
||||
imagePaths.add(path);
|
||||
signTimes.add(now);
|
||||
FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -350,7 +348,7 @@ class _BreakgroundSafeFuncSureState extends State<BreakgroundSafeFuncSure> {
|
|||
// 更新状态、序号等
|
||||
measures['STATUS'] = result['status'].toString();
|
||||
index = result['index'] as int;
|
||||
FocusHelper.clearFocus(context);
|
||||
//FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -89,7 +89,6 @@ class _BreakgroundAqjdDetailState extends State<BreakgroundAqjdDetail> {
|
|||
setState(() {
|
||||
signImages.add(path);
|
||||
signTimes.add(now);
|
||||
FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@ import 'package:qhd_prevention/customWidget/custom_button.dart';
|
|||
import 'package:qhd_prevention/customWidget/search_bar_widget.dart';
|
||||
import 'package:qhd_prevention/http/ApiService.dart';
|
||||
|
||||
|
||||
class BreakgroundListPage extends StatefulWidget {
|
||||
final String flow;
|
||||
final String workTypeTitle;
|
||||
|
|
@ -88,8 +87,7 @@ class _BreakgroundListPageState extends State<BreakgroundListPage> {
|
|||
stepList = [
|
||||
{'STEP_NAME': '全部', 'STEP_ID': ''},
|
||||
...response['list'] ?? [],
|
||||
{"STEP_NAME": "验收归档",
|
||||
"STEP_ID": "99"}
|
||||
{"STEP_NAME": "验收归档", "STEP_ID": "99"},
|
||||
];
|
||||
});
|
||||
} catch (e) {
|
||||
|
|
@ -142,13 +140,19 @@ class _BreakgroundListPageState extends State<BreakgroundListPage> {
|
|||
/// 申请
|
||||
void _handleApply() {
|
||||
// 处理申请按钮点击逻辑
|
||||
pushPage(BreakgroundApplyDetail(BREAKGROUND_ID: '', flow: widget.flow), context);
|
||||
pushPage(
|
||||
BreakgroundApplyDetail(BREAKGROUND_ID: '', flow: widget.flow),
|
||||
context,
|
||||
);
|
||||
}
|
||||
|
||||
/// 打开流程图
|
||||
Future<void> _openFlowDrawer(String hotworkId) async {
|
||||
try {
|
||||
final response = await ApiService.workGetFlowList('breakground', hotworkId);
|
||||
final response = await ApiService.workGetFlowList(
|
||||
'breakground',
|
||||
hotworkId,
|
||||
);
|
||||
final List<dynamic>? newFlow = response['flowList'];
|
||||
if (newFlow == null || newFlow.isEmpty) {
|
||||
ToastUtil.showNormal(context, '暂无流程图数据');
|
||||
|
|
@ -179,49 +183,133 @@ class _BreakgroundListPageState extends State<BreakgroundListPage> {
|
|||
|
||||
switch (widget.flow) {
|
||||
case '提交申请':
|
||||
await pushPage(BreakgroundApplyDetail(BREAKGROUND_ID: item['BREAKGROUND_ID'], flow: widget.flow), context);
|
||||
await pushPage(
|
||||
BreakgroundApplyDetail(
|
||||
BREAKGROUND_ID: item['BREAKGROUND_ID'],
|
||||
flow: widget.flow,
|
||||
),
|
||||
context,
|
||||
);
|
||||
break;
|
||||
case '作业人签字':
|
||||
await pushPage(BreakgroundZyrDetail(BREAKGROUND_ID: item['BREAKGROUND_ID'], flow: widget.flow), context);
|
||||
await pushPage(
|
||||
BreakgroundZyrDetail(
|
||||
BREAKGROUND_ID: item['BREAKGROUND_ID'],
|
||||
flow: widget.flow,
|
||||
),
|
||||
context,
|
||||
);
|
||||
break;
|
||||
case '设置安全措施确认人':
|
||||
await pushPage(BreakgroundSetSafeDetail(BREAKGROUND_ID: item['BREAKGROUND_ID'], flow: widget.flow), context);
|
||||
await pushPage(
|
||||
BreakgroundSetSafeDetail(
|
||||
BREAKGROUND_ID: item['BREAKGROUND_ID'],
|
||||
flow: widget.flow,
|
||||
),
|
||||
context,
|
||||
);
|
||||
break;
|
||||
case '安全措施确认':
|
||||
await pushPage(BreakgroundSafeFuncSure(BREAKGROUND_ID: item['BREAKGROUND_ID'], flow: widget.flow), context);
|
||||
await pushPage(
|
||||
BreakgroundSafeFuncSure(
|
||||
BREAKGROUND_ID: item['BREAKGROUND_ID'],
|
||||
flow: widget.flow,
|
||||
),
|
||||
context,
|
||||
);
|
||||
break;
|
||||
case '监护人签字':
|
||||
await pushPage(BreakgroundJhrDetail(BREAKGROUND_ID: item['BREAKGROUND_ID'], flow: widget.flow), context);
|
||||
await pushPage(
|
||||
BreakgroundJhrDetail(
|
||||
BREAKGROUND_ID: item['BREAKGROUND_ID'],
|
||||
flow: widget.flow,
|
||||
),
|
||||
context,
|
||||
);
|
||||
break;
|
||||
case '安全交底人签字':
|
||||
await pushPage(BreakgroundAqjdDetail(BREAKGROUND_ID: item['BREAKGROUND_ID'], flow: widget.flow), context);
|
||||
await pushPage(
|
||||
BreakgroundAqjdDetail(
|
||||
BREAKGROUND_ID: item['BREAKGROUND_ID'],
|
||||
flow: widget.flow,
|
||||
),
|
||||
context,
|
||||
);
|
||||
break;
|
||||
case '接受交底人签字':
|
||||
await pushPage(BreakgroundJsjdDetail(BREAKGROUND_ID: item['BREAKGROUND_ID'], flow: widget.flow), context);
|
||||
await pushPage(
|
||||
BreakgroundJsjdDetail(
|
||||
BREAKGROUND_ID: item['BREAKGROUND_ID'],
|
||||
flow: widget.flow,
|
||||
),
|
||||
context,
|
||||
);
|
||||
break;
|
||||
case '作业负责人签字':
|
||||
await pushPage(BreakgroundZyfzDetail(BREAKGROUND_ID: item['BREAKGROUND_ID'], flow: widget.flow), context);
|
||||
await pushPage(
|
||||
BreakgroundZyfzDetail(
|
||||
BREAKGROUND_ID: item['BREAKGROUND_ID'],
|
||||
flow: widget.flow,
|
||||
),
|
||||
context,
|
||||
);
|
||||
break;
|
||||
|
||||
case '所在单位签字':
|
||||
await pushPage(BreakgroundSzdwDetail(BREAKGROUND_ID: item['BREAKGROUND_ID'], flow: widget.flow), context);
|
||||
await pushPage(
|
||||
BreakgroundSzdwDetail(
|
||||
BREAKGROUND_ID: item['BREAKGROUND_ID'],
|
||||
flow: widget.flow,
|
||||
),
|
||||
context,
|
||||
);
|
||||
break;
|
||||
case '有关水、电、汽、工艺、设备、消防安全等部门':
|
||||
await pushPage(BreakgroundShbmDetail(BREAKGROUND_ID: item['BREAKGROUND_ID'], flow: widget.flow), context);
|
||||
await pushPage(
|
||||
BreakgroundShbmDetail(
|
||||
BREAKGROUND_ID: item['BREAKGROUND_ID'],
|
||||
flow: widget.flow,
|
||||
),
|
||||
context,
|
||||
);
|
||||
break;
|
||||
case '审批人签字':
|
||||
await pushPage(BreakgroundSpbmDetail(BREAKGROUND_ID: item['BREAKGROUND_ID'], flow: widget.flow), context);
|
||||
await pushPage(
|
||||
BreakgroundSpbmDetail(
|
||||
BREAKGROUND_ID: item['BREAKGROUND_ID'],
|
||||
flow: widget.flow,
|
||||
),
|
||||
context,
|
||||
);
|
||||
break;
|
||||
case '开始作业':
|
||||
await pushPage(BreakgroundKszyDetail(BREAKGROUND_ID: item['BREAKGROUND_ID'], flow: widget.flow), context);
|
||||
await pushPage(
|
||||
BreakgroundKszyDetail(
|
||||
BREAKGROUND_ID: item['BREAKGROUND_ID'],
|
||||
flow: widget.flow,
|
||||
),
|
||||
context,
|
||||
);
|
||||
|
||||
break;
|
||||
case '结束作业':
|
||||
await pushPage(BreakgroundJszyDetail(BREAKGROUND_ID: item['BREAKGROUND_ID'], flow: widget.flow), context);
|
||||
await pushPage(
|
||||
BreakgroundJszyDetail(
|
||||
BREAKGROUND_ID: item['BREAKGROUND_ID'],
|
||||
flow: widget.flow,
|
||||
),
|
||||
context,
|
||||
);
|
||||
|
||||
break;
|
||||
case '验收签字':
|
||||
await pushPage(BreakgroundYsgdDetail(BREAKGROUND_ID: item['BREAKGROUND_ID'], flow: widget.flow), context);
|
||||
await pushPage(
|
||||
BreakgroundYsgdDetail(
|
||||
BREAKGROUND_ID: item['BREAKGROUND_ID'],
|
||||
flow: widget.flow,
|
||||
),
|
||||
context,
|
||||
);
|
||||
|
||||
break;
|
||||
default:
|
||||
|
|
@ -335,11 +423,7 @@ class _BreakgroundListPageState extends State<BreakgroundListPage> {
|
|||
children: [
|
||||
Text(
|
||||
"编号: ${item['CHECK_NO'] ?? ''}",
|
||||
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
|
||||
),
|
||||
Text(
|
||||
"作业级别: ${_getWorkLevelText(item['WORK_LEVEL'])}",
|
||||
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
|
||||
style: TextStyle(fontSize: 14, fontWeight: FontWeight.bold),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
|
@ -353,29 +437,55 @@ class _BreakgroundListPageState extends State<BreakgroundListPage> {
|
|||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text("安全交底人: ${item['CONFESS_USER_NAME'] ?? ''}"),
|
||||
Text("接受交底人: ${item['ACCEPT_CONFESS_USER_NAME'] ?? ''}"),
|
||||
Expanded(child: Text("安全交底人: ${item['CONFESS_USER_NAME'] ?? ''}",softWrap: true,
|
||||
maxLines: null, // 不限制行数
|
||||
overflow: TextOverflow.visible,)
|
||||
),
|
||||
Expanded(child: Text("接受交底人: ${item['ACCEPT_CONFESS_USER_NAME'] ?? ''}",softWrap: true,
|
||||
textAlign: TextAlign.right,
|
||||
maxLines: null, // 不限制行数
|
||||
overflow: TextOverflow.visible,)
|
||||
),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text("作业负责人: ${item['CONFIRM_USER_NAME'] ?? ''}"),
|
||||
Text("所在单位负责人: ${item['LEADER_USER_NAME'] ?? ''}"),
|
||||
Expanded(child: Text("作业负责人: ${item['CONFIRM_USER_NAME'] ?? ''}",softWrap: true,
|
||||
maxLines: null, // 不限制行数
|
||||
overflow: TextOverflow.visible,)
|
||||
),
|
||||
Expanded(child: Text("所在单位负责人: ${item['LEADER_USER_NAME'] ?? ''}",softWrap: true,
|
||||
textAlign: TextAlign.right,
|
||||
maxLines: null, // 不限制行数
|
||||
overflow: TextOverflow.visible,)
|
||||
),
|
||||
],
|
||||
),
|
||||
if (FormUtils.hasValue(item, 'SAFETY_USER_NAME'))
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text("审核部门负责人: ${item['AUDIT_USER_NAME'] ?? ''}"),
|
||||
Text("审批部门负责人: ${item['APPROVE_USER_NAME'] ?? ''}"),
|
||||
Text(
|
||||
"有关水、电、汽、工艺、设备、消防安全等部门: ${item['SAFETY_USER_NAME'] ?? ''}",
|
||||
),
|
||||
],
|
||||
),
|
||||
if (FormUtils.hasValue(item, 'APPROVE_USER_NAME'))
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Expanded(child: Text("审批部门负责人: ${item['APPROVE_USER_NAME'] ?? ''}",softWrap: true,
|
||||
maxLines: null, // 不限制行数
|
||||
overflow: TextOverflow.visible,)
|
||||
),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text("验收部门负责人: ${item['ACCEPT_USER_NAME'] ?? ''}"),
|
||||
SizedBox()
|
||||
SizedBox(),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
|
|
|
|||
|
|
@ -190,7 +190,7 @@ class _BreakgroundApplyDetailState extends State<BreakgroundApplyDetail> {
|
|||
if (FormUtils.hasValue(result, 'VIDEOMANAGER_ID')) {
|
||||
pd['VIDEOMANAGER_ID'] = result['VIDEOMANAGER_ID'];
|
||||
}
|
||||
FocusHelper.clearFocus(context);
|
||||
//FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -213,7 +213,7 @@ class _BreakgroundApplyDetailState extends State<BreakgroundApplyDetail> {
|
|||
if (FormUtils.hasValue(result, 'UNITS_ID')) {
|
||||
pd['UNITS_ID'] = result['UNITS_ID'];
|
||||
}
|
||||
FocusHelper.clearFocus(context);
|
||||
//FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -225,17 +225,17 @@ class _BreakgroundApplyDetailState extends State<BreakgroundApplyDetail> {
|
|||
ToastUtil.showNormal(context, '请选择作业区域');
|
||||
return;
|
||||
}
|
||||
Map mapData = await pushPage(MapPage(gson: pd['POSITIONS']), context);
|
||||
final mapData = await pushPage(MapPage(gson: pd['POSITIONS']), context);
|
||||
setState(() {
|
||||
pd['LONGITUDE'] = mapData['longitue'];
|
||||
pd['LATITUDE'] = mapData['latitude'];
|
||||
pd['LATITUDE_LONGITUDE'] = '${mapData['longitue']},${mapData['latitude']}';
|
||||
pd['LONGITUDE'] = mapData['longitue'] ?? '';
|
||||
pd['LATITUDE'] = mapData['latitude'] ?? '';
|
||||
pd['LATITUDE_LONGITUDE'] = '${mapData['longitue'] ?? ''},${mapData['latitude'] ?? ''}';
|
||||
});
|
||||
|
||||
}
|
||||
/// 作业区域
|
||||
Future<void> _getWorkArea() async {
|
||||
FocusHelper.clearFocus(context);
|
||||
//FocusHelper.clearFocus(context);
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
isScrollControlled: true,
|
||||
|
|
@ -250,7 +250,7 @@ class _BreakgroundApplyDetailState extends State<BreakgroundApplyDetail> {
|
|||
},
|
||||
),
|
||||
).then((_) {
|
||||
FocusHelper.clearFocus(context);
|
||||
//FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
/// 获取摄像头列表
|
||||
|
|
@ -288,7 +288,7 @@ class _BreakgroundApplyDetailState extends State<BreakgroundApplyDetail> {
|
|||
setState(() {
|
||||
pd['WORK_LEVEL_NAME'] = choice;
|
||||
pd['WORK_LEVEL'] = (levelList.indexOf(choice) + 1).toString();
|
||||
FocusHelper.clearFocus(context);
|
||||
//FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -339,7 +339,7 @@ class _BreakgroundApplyDetailState extends State<BreakgroundApplyDetail> {
|
|||
|
||||
/// 弹出单位选择
|
||||
void chooseUnitHandle(EditUserType type) {
|
||||
FocusHelper.clearFocus(context);
|
||||
//FocusHelper.clearFocus(context);
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
isScrollControlled: true,
|
||||
|
|
@ -358,7 +358,7 @@ class _BreakgroundApplyDetailState extends State<BreakgroundApplyDetail> {
|
|||
},
|
||||
),
|
||||
).then((_) {
|
||||
FocusHelper.clearFocus(context);
|
||||
//FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -374,7 +374,7 @@ class _BreakgroundApplyDetailState extends State<BreakgroundApplyDetail> {
|
|||
|
||||
/// 弹出人员选择,需先选择单位
|
||||
void choosePersonHandle(EditUserType type) async {
|
||||
FocusHelper.clearFocus(context);
|
||||
//FocusHelper.clearFocus(context);
|
||||
|
||||
String unitId = get_pd_DEPARTMENT_ID(type);
|
||||
final personList = _personCache[type] ?? [];
|
||||
|
|
@ -410,7 +410,7 @@ class _BreakgroundApplyDetailState extends State<BreakgroundApplyDetail> {
|
|||
});
|
||||
},
|
||||
).then((_) {
|
||||
FocusHelper.clearFocus(context);
|
||||
//FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -61,7 +61,6 @@ class _BreakgroundDzzhDetailState extends State<BreakgroundDzzhDetail> {
|
|||
setState(() {
|
||||
signImages.add(path);
|
||||
signTimes.add(now);
|
||||
FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -62,7 +62,6 @@ class _BreakgroundJhrDetailState extends State<BreakgroundJhrDetail> {
|
|||
setState(() {
|
||||
imagePaths.add(path);
|
||||
signTimes.add(now);
|
||||
FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,7 +61,6 @@ class _BreakgroundJsjdDetailState extends State<BreakgroundJsjdDetail> {
|
|||
setState(() {
|
||||
signImages.add(path);
|
||||
signTimes.add(now);
|
||||
FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,7 +64,6 @@ class _BreakgroundJszyDetailState extends State<BreakgroundJszyDetail> {
|
|||
setState(() {
|
||||
signImages.add(path);
|
||||
signTimes.add(now);
|
||||
FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -65,7 +65,6 @@ class _BreakgroundKszyDetailState extends State<BreakgroundKszyDetail> {
|
|||
setState(() {
|
||||
signImages.add(path);
|
||||
signTimes.add(now);
|
||||
FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,7 +60,6 @@ class _BreakgroundShbmDetailState extends State<BreakgroundShbmDetail> {
|
|||
setState(() {
|
||||
signImages.add(path);
|
||||
signTimes.add(now);
|
||||
FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,7 +60,6 @@ class _BreakgroundSpbmDetailState extends State<BreakgroundSpbmDetail> {
|
|||
setState(() {
|
||||
signImages.add(path);
|
||||
signTimes.add(now);
|
||||
FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,7 +60,6 @@ class _BreakgroundSsrDetailState extends State<BreakgroundSsrDetail> {
|
|||
setState(() {
|
||||
signImages.add(path);
|
||||
signTimes.add(now);
|
||||
FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -175,7 +175,6 @@ class _BreakgroundSetSafeDetailState extends State<BreakgroundSetSafeDetail> {
|
|||
setState(() {
|
||||
imagePaths.add(path);
|
||||
signTimes.add(now);
|
||||
FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,7 +61,6 @@ class _BreakgroundSzdwDetailState extends State<BreakgroundSzdwDetail> {
|
|||
setState(() {
|
||||
signImages.add(path);
|
||||
signTimes.add(now);
|
||||
FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -97,7 +97,6 @@ class _BreakgroundYsgdDetailState extends State<BreakgroundYsgdDetail> {
|
|||
setState(() {
|
||||
signImages.add(path);
|
||||
signTimes.add(now);
|
||||
FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -370,7 +369,7 @@ class _BreakgroundYsgdDetailState extends State<BreakgroundYsgdDetail> {
|
|||
'yyyy-MM-dd HH:mm:ss',
|
||||
).format(picked);
|
||||
});
|
||||
FocusHelper.clearFocus(context);
|
||||
//FocusHelper.clearFocus(context);
|
||||
}
|
||||
},
|
||||
),
|
||||
|
|
|
|||
|
|
@ -61,7 +61,6 @@ class _BreakgroundZyfzDetailState extends State<BreakgroundZyfzDetail> {
|
|||
setState(() {
|
||||
signImages.add(path);
|
||||
signTimes.add(now);
|
||||
FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -74,7 +74,6 @@ class _BreakgroundZyrDetailState extends State<BreakgroundZyrDetail> {
|
|||
setState(() {
|
||||
signImages.add(path);
|
||||
signTimes.add(now);
|
||||
FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -355,7 +355,7 @@ class _HoistworkDetailFormWidgetState extends State<HoistWorkDetailFormWidget> {
|
|||
},
|
||||
),
|
||||
);
|
||||
FocusHelper.clearFocus(context);
|
||||
//FocusHelper.clearFocus(context);
|
||||
},
|
||||
hintText: '请输入关联的其他特殊作业及安全作业票编号',
|
||||
controller: widget.relatedController,
|
||||
|
|
@ -379,7 +379,7 @@ class _HoistworkDetailFormWidgetState extends State<HoistWorkDetailFormWidget> {
|
|||
},
|
||||
),
|
||||
);
|
||||
FocusHelper.clearFocus(context);
|
||||
//FocusHelper.clearFocus(context);
|
||||
},
|
||||
hintText: '请输入风险辨识结果',
|
||||
controller: widget.riskController,
|
||||
|
|
|
|||
|
|
@ -86,7 +86,6 @@ class _HoistworkSafeFuncSureState extends State<HoistworkSafeFuncSure> {
|
|||
/// 签字
|
||||
Future<void> _sign() async {
|
||||
await NativeOrientation.setLandscape();
|
||||
FocusHelper.clearFocus(context);
|
||||
final path = await Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(builder: (context) => MineSignPage()),
|
||||
|
|
@ -97,7 +96,6 @@ class _HoistworkSafeFuncSureState extends State<HoistworkSafeFuncSure> {
|
|||
setState(() {
|
||||
imagePaths.add(path);
|
||||
signTimes.add(now);
|
||||
FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -349,7 +347,7 @@ class _HoistworkSafeFuncSureState extends State<HoistworkSafeFuncSure> {
|
|||
// 更新状态、序号等
|
||||
measures['STATUS'] = result['status'].toString();
|
||||
index = result['index'] as int;
|
||||
FocusHelper.clearFocus(context);
|
||||
//FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -89,7 +89,6 @@ class _HoistworkAqjdDetailState extends State<HoistworkAqjdDetail> {
|
|||
setState(() {
|
||||
signImages.add(path);
|
||||
signTimes.add(now);
|
||||
FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -152,7 +152,7 @@ class _HoistworkApplyDetailState extends State<HoistworkApplyDetail> {
|
|||
if (FormUtils.hasValue(result, 'VIDEOMANAGER_ID')) {
|
||||
pd['VIDEOMANAGER_ID'] = result['VIDEOMANAGER_ID'];
|
||||
}
|
||||
FocusHelper.clearFocus(context);
|
||||
//FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -175,7 +175,7 @@ class _HoistworkApplyDetailState extends State<HoistworkApplyDetail> {
|
|||
if (FormUtils.hasValue(result, 'UNITS_ID')) {
|
||||
pd['UNITS_ID'] = result['UNITS_ID'];
|
||||
}
|
||||
FocusHelper.clearFocus(context);
|
||||
//FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -187,17 +187,17 @@ class _HoistworkApplyDetailState extends State<HoistworkApplyDetail> {
|
|||
ToastUtil.showNormal(context, '请选择作业区域');
|
||||
return;
|
||||
}
|
||||
Map mapData = await pushPage(MapPage(gson: pd['POSITIONS']), context);
|
||||
final mapData = await pushPage(MapPage(gson: pd['POSITIONS']), context);
|
||||
setState(() {
|
||||
pd['LONGITUDE'] = mapData['longitue'];
|
||||
pd['LATITUDE'] = mapData['latitude'];
|
||||
pd['LATITUDE_LONGITUDE'] = '${mapData['longitue']},${mapData['latitude']}';
|
||||
pd['LONGITUDE'] = mapData['longitue'] ?? '';
|
||||
pd['LATITUDE'] = mapData['latitude'] ?? '';
|
||||
pd['LATITUDE_LONGITUDE'] = '${mapData['longitue'] ?? ''},${mapData['latitude'] ?? ''}';
|
||||
});
|
||||
|
||||
}
|
||||
/// 作业区域
|
||||
Future<void> _getWorkArea() async {
|
||||
FocusHelper.clearFocus(context);
|
||||
//FocusHelper.clearFocus(context);
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
isScrollControlled: true,
|
||||
|
|
@ -212,7 +212,7 @@ class _HoistworkApplyDetailState extends State<HoistworkApplyDetail> {
|
|||
},
|
||||
),
|
||||
).then((_) {
|
||||
FocusHelper.clearFocus(context);
|
||||
//FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
/// 获取摄像头列表
|
||||
|
|
@ -290,7 +290,7 @@ class _HoistworkApplyDetailState extends State<HoistworkApplyDetail> {
|
|||
setState(() {
|
||||
pd['WORK_LEVEL_NAME'] = choice;
|
||||
pd['WORK_LEVEL'] = (levelList.indexOf(choice) + 1).toString();
|
||||
FocusHelper.clearFocus(context);
|
||||
//FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -345,7 +345,7 @@ class _HoistworkApplyDetailState extends State<HoistworkApplyDetail> {
|
|||
|
||||
/// 弹出单位选择
|
||||
void chooseUnitHandle(EditUserType type) {
|
||||
FocusHelper.clearFocus(context);
|
||||
//FocusHelper.clearFocus(context);
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
isScrollControlled: true,
|
||||
|
|
@ -364,7 +364,7 @@ class _HoistworkApplyDetailState extends State<HoistworkApplyDetail> {
|
|||
},
|
||||
),
|
||||
).then((_) {
|
||||
FocusHelper.clearFocus(context);
|
||||
//FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -380,7 +380,7 @@ class _HoistworkApplyDetailState extends State<HoistworkApplyDetail> {
|
|||
|
||||
/// 弹出人员选择,需先选择单位
|
||||
void choosePersonHandle(EditUserType type) async {
|
||||
FocusHelper.clearFocus(context);
|
||||
//FocusHelper.clearFocus(context);
|
||||
|
||||
String unitId = get_pd_DEPARTMENT_ID(type);
|
||||
final personList = _personCache[type] ?? [];
|
||||
|
|
@ -416,7 +416,7 @@ class _HoistworkApplyDetailState extends State<HoistworkApplyDetail> {
|
|||
});
|
||||
},
|
||||
).then((_) {
|
||||
FocusHelper.clearFocus(context);
|
||||
//FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -504,7 +504,6 @@ class _HoistworkApplyDetailState extends State<HoistworkApplyDetail> {
|
|||
} else if (pd['WORK_LEVEL'] == '2' || pd['WORK_LEVEL'] == '3') {
|
||||
taskId = '11';
|
||||
}
|
||||
pd['WORK_LEVEL_NAME'] = levelList[int.parse(pd['WORK_LEVEL'])];
|
||||
pd['USER_ID'] = SessionService.instance.loginUserId;
|
||||
pd['STEP_ID'] = status;
|
||||
pd['CORPINFO_ID'] = SessionService.instance.corpinfoId;
|
||||
|
|
|
|||
|
|
@ -61,7 +61,6 @@ class _HoistworkDzzhDetailState extends State<HoistworkDzzhDetail> {
|
|||
setState(() {
|
||||
signImages.add(path);
|
||||
signTimes.add(now);
|
||||
FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -340,11 +340,11 @@ class _HoistworkListPageState extends State<HoistworkListPage> {
|
|||
children: [
|
||||
Text(
|
||||
"编号: ${item['CHECK_NO'] ?? ''}",
|
||||
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
|
||||
style: TextStyle(fontSize: 14, fontWeight: FontWeight.bold),
|
||||
),
|
||||
Text(
|
||||
"作业级别: ${_getWorkLevelText(item['WORK_LEVEL'])}",
|
||||
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
|
||||
style: TextStyle(fontSize: 14, fontWeight: FontWeight.bold),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
|
@ -358,22 +358,43 @@ class _HoistworkListPageState extends State<HoistworkListPage> {
|
|||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text("安全交底人: ${item['CONFESS_USER_NAME'] ?? ''}"),
|
||||
Text("接受交底人: ${item['ACCEPT_CONFESS_USER_NAME'] ?? ''}"),
|
||||
Expanded(child: Text("安全交底人: ${item['CONFESS_USER_NAME'] ?? ''}",softWrap: true,
|
||||
maxLines: null, // 不限制行数
|
||||
overflow: TextOverflow.visible,)
|
||||
),
|
||||
Expanded(child: Text("接受交底人: ${item['ACCEPT_CONFESS_USER_NAME'] ?? ''}",softWrap: true,
|
||||
textAlign: TextAlign.right,
|
||||
maxLines: null, // 不限制行数
|
||||
overflow: TextOverflow.visible,)
|
||||
),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text("作业负责人: ${item['CONFIRM_USER_NAME'] ?? ''}"),
|
||||
Text("所在单位负责人: ${item['LEADER_USER_NAME'] ?? ''}"),
|
||||
Expanded(child: Text("作业负责人: ${item['CONFIRM_USER_NAME'] ?? ''}",softWrap: true,
|
||||
maxLines: null, // 不限制行数
|
||||
overflow: TextOverflow.visible,)
|
||||
),
|
||||
Expanded(child: Text("所在单位负责人: ${item['LEADER_USER_NAME'] ?? ''}",softWrap: true,
|
||||
textAlign: TextAlign.right,
|
||||
maxLines: null, // 不限制行数
|
||||
overflow: TextOverflow.visible,)
|
||||
),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text("审核部门负责人: ${item['AUDIT_USER_NAME'] ?? ''}"),
|
||||
Text("审批部门负责人: ${item['APPROVE_USER_NAME'] ?? ''}"),
|
||||
Expanded(child: Text("审核部门负责人: ${item['AUDIT_USER_NAME'] ?? ''}",softWrap: true,
|
||||
maxLines: null, // 不限制行数
|
||||
overflow: TextOverflow.visible,)
|
||||
),
|
||||
Expanded(child: Text("审批部门负责人: ${item['APPROVE_USER_NAME'] ?? ''}",softWrap: true,
|
||||
textAlign: TextAlign.right,
|
||||
maxLines: null, // 不限制行数
|
||||
overflow: TextOverflow.visible,)
|
||||
),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
|
|
|
|||
|
|
@ -62,7 +62,6 @@ class _HoistworkJhrDetailState extends State<HoistworkJhrDetail> {
|
|||
setState(() {
|
||||
imagePaths.add(path);
|
||||
signTimes.add(now);
|
||||
FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,7 +61,6 @@ class _HoistworkJsjdDetailState extends State<HoistworkJsjdDetail> {
|
|||
setState(() {
|
||||
signImages.add(path);
|
||||
signTimes.add(now);
|
||||
FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,7 +64,6 @@ class _HoistworkJszyDetailState extends State<HoistworkJszyDetail> {
|
|||
setState(() {
|
||||
signImages.add(path);
|
||||
signTimes.add(now);
|
||||
FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -65,7 +65,6 @@ class _HoistworkKszyDetailState extends State<HoistworkKszyDetail> {
|
|||
setState(() {
|
||||
signImages.add(path);
|
||||
signTimes.add(now);
|
||||
FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,7 +60,6 @@ class _HoistworkShbmDetailState extends State<HoistworkShbmDetail> {
|
|||
setState(() {
|
||||
signImages.add(path);
|
||||
signTimes.add(now);
|
||||
FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,7 +60,6 @@ class _HoistworkSpbmDetailState extends State<HoistworkSpbmDetail> {
|
|||
setState(() {
|
||||
signImages.add(path);
|
||||
signTimes.add(now);
|
||||
FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,7 +60,6 @@ class _HoistworkSsrDetailState extends State<HoistworkSsrDetail> {
|
|||
setState(() {
|
||||
signImages.add(path);
|
||||
signTimes.add(now);
|
||||
FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -174,7 +174,6 @@ class _HoistworkSetSafeDetailState extends State<HoistworkSetSafeDetail> {
|
|||
setState(() {
|
||||
imagePaths.add(path);
|
||||
signTimes.add(now);
|
||||
FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,7 +61,6 @@ class _HoistworkSzdwDetailState extends State<HoistworkSzdwDetail> {
|
|||
setState(() {
|
||||
signImages.add(path);
|
||||
signTimes.add(now);
|
||||
FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -97,7 +97,6 @@ class _HoistworkYsgdDetailState extends State<HoistworkYsgdDetail> {
|
|||
setState(() {
|
||||
signImages.add(path);
|
||||
signTimes.add(now);
|
||||
FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -370,7 +369,7 @@ class _HoistworkYsgdDetailState extends State<HoistworkYsgdDetail> {
|
|||
'yyyy-MM-dd HH:mm:ss',
|
||||
).format(picked);
|
||||
});
|
||||
FocusHelper.clearFocus(context);
|
||||
//FocusHelper.clearFocus(context);
|
||||
}
|
||||
},
|
||||
),
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue