八项作业整体修改提测
parent
6318206baa
commit
09daf9bb4d
|
|
@ -30,7 +30,7 @@ android {
|
|||
|
||||
defaultConfig {
|
||||
applicationId = "com.zhuoyun.qhdprevention.qhd_prevention"
|
||||
minSdk = 22
|
||||
minSdk = 24
|
||||
targetSdk = flutter.targetSdkVersion
|
||||
versionCode = flutter.versionCode
|
||||
versionName = flutter.versionName
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 11 KiB |
|
|
@ -1,8 +1,10 @@
|
|||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:photo_view/photo_view.dart';
|
||||
import 'package:qhd_prevention/pages/my_appbar.dart';
|
||||
|
||||
// 查看大图
|
||||
class SingleImageViewer extends StatelessWidget {
|
||||
final String imageUrl;
|
||||
|
|
@ -11,26 +13,59 @@ class SingleImageViewer extends StatelessWidget {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
ImageProvider provider;
|
||||
|
||||
// 选择图片来源:网络 / asset / 本地文件(优先检测 http,然后 asset,再文件)
|
||||
if (imageUrl.toLowerCase().startsWith('http')) {
|
||||
provider = NetworkImage(imageUrl);
|
||||
} else if (imageUrl.startsWith('assets/') ||
|
||||
imageUrl.startsWith('package:') ||
|
||||
imageUrl.startsWith('packages/')) {
|
||||
// 明确标记为工程资源(asset)
|
||||
provider = AssetImage(imageUrl) as ImageProvider;
|
||||
} else {
|
||||
provider = FileImage(File(imageUrl));
|
||||
// 不是明确的网络或 asset 路径 —— 在非 web 平台尝试作为文件路径
|
||||
if (!kIsWeb) {
|
||||
try {
|
||||
final file = File(imageUrl);
|
||||
if (file.existsSync()) {
|
||||
provider = FileImage(file);
|
||||
} else {
|
||||
// 文件不存在时尝试作为 asset 路径回退
|
||||
provider = AssetImage(imageUrl) as ImageProvider;
|
||||
}
|
||||
} catch (e) {
|
||||
// 任何异常都回退为 asset 尝试(避免抛出)
|
||||
provider = AssetImage(imageUrl) as ImageProvider;
|
||||
}
|
||||
} else {
|
||||
// web 平台没有 File API,可直接尝试当作 asset
|
||||
provider = AssetImage(imageUrl) as ImageProvider;
|
||||
}
|
||||
}
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: Colors.black.withValues(alpha: 0.5),
|
||||
appBar: MyAppbar(
|
||||
isBack: false,
|
||||
actions: [
|
||||
IconButton(onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
}, icon: Icon(Icons.close, color: Colors.white, size: 40,),)
|
||||
IconButton(
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
icon: const Icon(
|
||||
Icons.close,
|
||||
color: Colors.white,
|
||||
size: 40,
|
||||
),
|
||||
)
|
||||
],
|
||||
backgroundColor: Colors.black.withValues(alpha:0.5), title: '',
|
||||
backgroundColor: Colors.black.withValues(alpha: 0.5),
|
||||
title: '',
|
||||
),
|
||||
body: Center(
|
||||
child: PhotoView(
|
||||
imageProvider: provider,
|
||||
backgroundDecoration: BoxDecoration(color: Colors.black.withValues(alpha:0.5)),
|
||||
backgroundDecoration: BoxDecoration(color: Colors.black.withValues(alpha: 0.5)),
|
||||
minScale: PhotoViewComputedScale.contained,
|
||||
maxScale: PhotoViewComputedScale.covered * 2,
|
||||
onTapUp: (context, details, controllerValue) {
|
||||
|
|
|
|||
|
|
@ -24,9 +24,9 @@ class ApiService {
|
|||
/// 登录及其他管理后台接口
|
||||
// static const String basePath = "http://192.168.20.240:8500/integrated_whb";//测试服务器
|
||||
// static const String basePath = "https://qaaqwh.qhdsafety.com/integrated_whb";
|
||||
static const String basePath = "http://192.168.20.240:8500/integrated_whb";
|
||||
// static const String basePath = "http://192.168.20.240:8500/integrated_whb";
|
||||
// static const String basePath = "http://192.168.0.25:28199";//王轩服务器
|
||||
// static const String basePath = "http://192.168.0.45:28199";//长久服务器
|
||||
static const String basePath = "http://192.168.0.45:28199";//长久服务器
|
||||
|
||||
/// 图片文件服务
|
||||
static const String baseImgPath = "https://file.zcloudchina.com/YTHFile";
|
||||
|
|
@ -865,6 +865,7 @@ U6Hzm1ninpWeE+awIDAQAB
|
|||
/// 所有安全防护措施
|
||||
static Future<Map<String, dynamic>> listSignFinishAllMeasures(
|
||||
String workType,
|
||||
CUTROAD_ID,
|
||||
) {
|
||||
final String tm = DateTime.now().millisecondsSinceEpoch.toString();
|
||||
return HttpManager().request(
|
||||
|
|
@ -872,6 +873,7 @@ U6Hzm1ninpWeE+awIDAQAB
|
|||
'/app/$workType/listAllMeasures?tm=$tm',
|
||||
method: Method.post,
|
||||
data: {
|
||||
"CUTROAD_ID": CUTROAD_ID,
|
||||
"CORPINFO_ID": SessionService.instance.corpinfoId,
|
||||
"USER_ID": SessionService.instance.loginUserId,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -273,17 +273,15 @@ class _SafecheckSignListPageState extends State<SafecheckSignListPage> {
|
|||
// 显示底部选择器
|
||||
Future<void> _showStepPicker() async {
|
||||
if (stepList.isEmpty) {
|
||||
ScaffoldMessenger.of(
|
||||
context,
|
||||
).showSnackBar(SnackBar(content: Text('正在加载步骤数据,请稍后...')));
|
||||
LoadingDialogHelper.show();
|
||||
if (stepList.isEmpty) {
|
||||
ScaffoldMessenger.of(
|
||||
context,
|
||||
).showSnackBar(SnackBar(content: Text('无法加载步骤数据')));
|
||||
LoadingDialogHelper.hide();
|
||||
ToastUtil.showNormal(context, '无法加载数据');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
LoadingDialogHelper.hide();
|
||||
// 创建选项列表
|
||||
final options = stepList.map((e) => e['name'] as String).toList();
|
||||
|
||||
|
|
|
|||
|
|
@ -275,13 +275,10 @@ class _CheckPersonListPageState extends State<CheckPersonListPage> {
|
|||
// 显示底部选择器
|
||||
Future<void> _showStepPicker() async {
|
||||
if (stepList.isEmpty) {
|
||||
ScaffoldMessenger.of(
|
||||
context,
|
||||
).showSnackBar(SnackBar(content: Text('正在加载步骤数据,请稍后...')));
|
||||
LoadingDialogHelper.show();
|
||||
if (stepList.isEmpty) {
|
||||
ScaffoldMessenger.of(
|
||||
context,
|
||||
).showSnackBar(SnackBar(content: Text('无法加载步骤数据')));
|
||||
LoadingDialogHelper.hide();
|
||||
ToastUtil.showNormal(context, '无法加载数据');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -304,13 +304,10 @@ class _SafecheckDangerListPageState extends State<SafecheckDangerListPage> {
|
|||
// 显示底部选择器
|
||||
Future<void> _showStepPicker() async {
|
||||
if (stepList.isEmpty) {
|
||||
ScaffoldMessenger.of(
|
||||
context,
|
||||
).showSnackBar(SnackBar(content: Text('正在加载步骤数据,请稍后...')));
|
||||
LoadingDialogHelper.show();
|
||||
if (stepList.isEmpty) {
|
||||
ScaffoldMessenger.of(
|
||||
context,
|
||||
).showSnackBar(SnackBar(content: Text('无法加载步骤数据')));
|
||||
LoadingDialogHelper.hide();
|
||||
ToastUtil.showNormal(context, '无法加载数据');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -279,13 +279,10 @@ class _DefendRecordListPageState extends State<DefendRecordListPage> {
|
|||
// 显示底部选择器
|
||||
Future<void> _showStepPicker() async {
|
||||
if (stepList.isEmpty) {
|
||||
ScaffoldMessenger.of(
|
||||
context,
|
||||
).showSnackBar(SnackBar(content: Text('正在加载步骤数据,请稍后...')));
|
||||
LoadingDialogHelper.show();
|
||||
if (stepList.isEmpty) {
|
||||
ScaffoldMessenger.of(
|
||||
context,
|
||||
).showSnackBar(SnackBar(content: Text('无法加载步骤数据')));
|
||||
LoadingDialogHelper.hide();
|
||||
ToastUtil.showNormal(context, '无法加载数据');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -350,13 +350,10 @@ class _SafecheckStartListPageState extends State<SafecheckStartListPage> {
|
|||
// 显示底部选择器
|
||||
Future<void> _showStepPicker() async {
|
||||
if (stepList.isEmpty) {
|
||||
ScaffoldMessenger.of(
|
||||
context,
|
||||
).showSnackBar(SnackBar(content: Text('正在加载步骤数据,请稍后...')));
|
||||
LoadingDialogHelper.show();
|
||||
if (stepList.isEmpty) {
|
||||
ScaffoldMessenger.of(
|
||||
context,
|
||||
).showSnackBar(SnackBar(content: Text('无法加载步骤数据')));
|
||||
LoadingDialogHelper.hide();
|
||||
ToastUtil.showNormal(context, '无法加载数据');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -201,7 +201,9 @@ class ItemListWidget {
|
|||
VoidCallback? onTap, // 点击回调
|
||||
double fontSize = 14, // 字体大小
|
||||
bool isClean = false,
|
||||
bool isTip = false,
|
||||
VoidCallback? onTapClean, // 清除回调
|
||||
VoidCallback? onTapTip, // 提醒回调
|
||||
bool isRequired = true,
|
||||
String cleanText = '清除',
|
||||
double horizontalnum= horizontal_inset,
|
||||
|
|
@ -217,14 +219,26 @@ class ItemListWidget {
|
|||
children: [
|
||||
if (isRequired && isEditable)
|
||||
Text('* ', style: TextStyle(color: Colors.red)),
|
||||
Text(
|
||||
label,
|
||||
textAlign: TextAlign.right,
|
||||
style: TextStyle(
|
||||
fontSize: fontSize,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
label,
|
||||
textAlign: TextAlign.right,
|
||||
style: TextStyle(
|
||||
fontSize: fontSize,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
if (isTip)
|
||||
Column(
|
||||
children: [
|
||||
IconButton(onPressed: onTapTip, icon: Icon(Icons.error_outline,color: Colors.blue,size: 20,)),
|
||||
const SizedBox()
|
||||
],
|
||||
)
|
||||
],
|
||||
)
|
||||
|
||||
],
|
||||
),
|
||||
if (isClean)
|
||||
|
|
@ -237,7 +251,7 @@ class ItemListWidget {
|
|||
textStyle: TextStyle(fontSize: 11, color: Colors.white),
|
||||
borderRadius: 10,
|
||||
backgroundColor:
|
||||
cleanText == '清除' ? Colors.red : Colors.green,
|
||||
cleanText.contains('清除') ? Colors.red : Colors.green,
|
||||
onPressed: onTapClean,
|
||||
),
|
||||
SizedBox(height: 20),
|
||||
|
|
|
|||
|
|
@ -1164,19 +1164,19 @@ class _SelectionPopupState extends State<SelectionPopup> {
|
|||
title: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(key, style: TextStyle(fontSize: 15)),
|
||||
Text(key, style: TextStyle(fontSize: 13)),
|
||||
if (widget.type == 'assignments') ...[
|
||||
Text(
|
||||
'作业内容: ${item['WORK_CONTENT'] ?? ''}',
|
||||
style: TextStyle(fontSize: 15),
|
||||
style: TextStyle(fontSize: 13),
|
||||
),
|
||||
Text(
|
||||
'作业负责人: ${item['CONFIRM_USER_NAME'] ?? ''}',
|
||||
style: TextStyle(fontSize: 15),
|
||||
style: TextStyle(fontSize: 13),
|
||||
),
|
||||
Text(
|
||||
'作业申请时间: ${item['CREATTIME'] ?? ''}',
|
||||
style: TextStyle(fontSize: 15),
|
||||
style: TextStyle(fontSize: 13),
|
||||
),
|
||||
],
|
||||
],
|
||||
|
|
@ -1413,7 +1413,6 @@ class SignItemWidget extends StatelessWidget {
|
|||
const double timeBoxWidth = 120.0; // 时间文本固定宽度(可调整)
|
||||
|
||||
// 单独渲染一行:签字: [多个签字图片水平滚动] 时间(只会渲染一次)
|
||||
// 单独渲染一行:签字: [多个签字图片多行显示(Wrap)] 时间(只会渲染一次,超过宽度自动换行)
|
||||
list.add(
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 0, horizontal: 10),
|
||||
|
|
@ -1458,7 +1457,7 @@ class SignItemWidget extends StatelessWidget {
|
|||
fullUrl,
|
||||
width: thumbSize,
|
||||
height: thumbSize,
|
||||
fit: BoxFit.cover,
|
||||
fit: BoxFit.fill,
|
||||
errorBuilder: (_, __, ___) => Container(
|
||||
width: thumbSize,
|
||||
height: thumbSize,
|
||||
|
|
@ -1479,19 +1478,7 @@ class SignItemWidget extends StatelessWidget {
|
|||
// 图片与时间之间的小间隔(仅在有图片时展示)
|
||||
if (aggregatedSignPaths.isNotEmpty) const SizedBox(width: 8),
|
||||
|
||||
// 时间文本(始终固定在最右侧并底部对齐)
|
||||
SizedBox(
|
||||
width: timeBoxWidth,
|
||||
child: Text(
|
||||
lastTime,
|
||||
textAlign: TextAlign.right,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: const TextStyle(
|
||||
fontSize: 13,
|
||||
color: Colors.black87,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
],
|
||||
),
|
||||
);
|
||||
|
|
@ -1500,6 +1487,23 @@ class SignItemWidget extends StatelessWidget {
|
|||
),
|
||||
),
|
||||
);
|
||||
// 时间文本(始终固定在最右侧并底部对齐)
|
||||
list.add(const SizedBox(height: 10,));
|
||||
list.add(Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
const SizedBox(),
|
||||
Text(
|
||||
lastTime,
|
||||
textAlign: TextAlign.right,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: const TextStyle(
|
||||
fontSize: 13,
|
||||
color: Colors.black87,
|
||||
),
|
||||
)
|
||||
],
|
||||
));
|
||||
|
||||
|
||||
return list;
|
||||
|
|
@ -1573,7 +1577,7 @@ class ConfirmWithSignWidget extends StatelessWidget {
|
|||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
// 意见卡片(复用你之前的 _itemContainer 风格)
|
||||
// 意见卡片
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
|
|
@ -1591,7 +1595,7 @@ class ConfirmWithSignWidget extends StatelessWidget {
|
|||
),
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(child: ListItemFactory.headerTitle('$headerTitle:')),
|
||||
Expanded(child: ListItemFactory.headerTitle('$headerTitle')),
|
||||
const SizedBox(),
|
||||
// 仅当 pd 中存在 nameKey 且不为空时显示
|
||||
// if (FormUtils.hasValue(safePd, nameKey))
|
||||
|
|
|
|||
|
|
@ -392,7 +392,7 @@ class _HotWorkDetailFormWidgetState extends State<HotWorkDetailFormWidget> {
|
|||
if (FormUtils.hasValue(pd, 'ANALYZE_TIME') && !widget.isEditable) ...[
|
||||
const Divider(),
|
||||
ItemListWidget.OneRowButtonTitleText(
|
||||
label: '分析人:',
|
||||
label: '气体分析信息:',
|
||||
text: pd['ANALYZE_USER_NAME'] ?? '',
|
||||
onTap: widget.onAnalyzeTap,
|
||||
),
|
||||
|
|
|
|||
|
|
@ -130,7 +130,7 @@ class SpecialWorkFormBaseWork extends StatelessWidget {
|
|||
baseImgPath: baseImgPath,
|
||||
sectionKey: 'GUARDIAN',
|
||||
nameKey: 'GUARDIAN_USER_NAME',
|
||||
headerTitle: '监护人意见',
|
||||
headerTitle: '监护人签字',
|
||||
roleTitle: '监护人',
|
||||
),
|
||||
if (FormUtils.hasValue(signs, 'CONFIRM'))
|
||||
|
|
|
|||
|
|
@ -301,9 +301,12 @@ class _HotworkApplyDetailState extends State<HotworkApplyDetail> {
|
|||
builder:
|
||||
(_) => WorkAreaPicker(
|
||||
onSelected: (String id, String POSITIONS, String name) {
|
||||
pd['ELECTRONIC_FENCE_AREA_ID'] = id;
|
||||
pd['POSITIONS'] = POSITIONS;
|
||||
pd['PLS_NAME'] = name;
|
||||
setState(() {
|
||||
pd['ELECTRONIC_FENCE_AREA_ID'] = id;
|
||||
pd['POSITIONS'] = POSITIONS;
|
||||
pd['PLS_NAME'] = name;
|
||||
});
|
||||
|
||||
},
|
||||
),
|
||||
).then((_) {
|
||||
|
|
|
|||
|
|
@ -59,7 +59,6 @@ class _HotWorkListPageState extends State<HotWorkListPage> {
|
|||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_fetchSteps();
|
||||
_fetchData();
|
||||
_scrollController.addListener(_onScroll);
|
||||
}
|
||||
|
|
@ -138,9 +137,11 @@ class _HotWorkListPageState extends State<HotWorkListPage> {
|
|||
}
|
||||
|
||||
/// 申请
|
||||
void _handleApply() {
|
||||
void _handleApply() async{
|
||||
// 处理申请按钮点击逻辑
|
||||
pushPage(HotworkApplyDetail(HOTWORK_ID: '', flow: widget.flow), context);
|
||||
await pushPage(HotworkApplyDetail(HOTWORK_ID: '', flow: widget.flow), context);
|
||||
_fetchData();
|
||||
LoadingDialogHelper.hide();
|
||||
}
|
||||
|
||||
/// 打开流程图
|
||||
|
|
@ -286,9 +287,10 @@ class _HotWorkListPageState extends State<HotWorkListPage> {
|
|||
default:
|
||||
break;
|
||||
}
|
||||
LoadingDialogHelper.show();
|
||||
_fetchSteps();
|
||||
_fetchData();
|
||||
|
||||
|
||||
await _fetchData();
|
||||
LoadingDialogHelper.hide();
|
||||
}
|
||||
|
||||
Widget _buildFlowStepItem({
|
||||
|
|
|
|||
|
|
@ -227,6 +227,7 @@ class _HotworkJszyDetailState extends State<HotworkJszyDetail> {
|
|||
child: SingleChildScrollView(
|
||||
padding: EdgeInsets.all(12),
|
||||
child: Column(
|
||||
spacing: 12,
|
||||
children: [
|
||||
// _setSafeDetailWidget(),
|
||||
SpecialWorkFormBaseWork(
|
||||
|
|
@ -274,7 +275,6 @@ class _HotworkJszyDetailState extends State<HotworkJszyDetail> {
|
|||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 12,),
|
||||
_bottomButtons(),
|
||||
],
|
||||
),
|
||||
|
|
|
|||
|
|
@ -198,6 +198,7 @@ class _HotworkKszyDetailState extends State<HotworkKszyDetail> {
|
|||
child: SingleChildScrollView(
|
||||
padding: EdgeInsets.all(12),
|
||||
child: Column(
|
||||
spacing: 12,
|
||||
children: [
|
||||
// _setSafeDetailWidget(),
|
||||
SpecialWorkFormBaseWork(
|
||||
|
|
@ -243,7 +244,6 @@ class _HotworkKszyDetailState extends State<HotworkKszyDetail> {
|
|||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 12,),
|
||||
_bottomButtons(),
|
||||
],
|
||||
),
|
||||
|
|
|
|||
|
|
@ -349,7 +349,7 @@ class _HotworkSetSafeDetailState extends State<HotworkSetSafeDetail> {
|
|||
}
|
||||
|
||||
Future<void> _getMeasures() async {
|
||||
final data = await ApiService.listSignFinishAllMeasures('hotwork');
|
||||
final data = await ApiService.listSignFinishAllMeasures('hotwork', widget.HOTWORK_ID);
|
||||
setState(() {
|
||||
measuresList = List<Map<String, dynamic>>.from(
|
||||
data['measuresList'] ?? <Map<String, dynamic>>[],
|
||||
|
|
|
|||
|
|
@ -147,7 +147,7 @@ class _CutroadDetailFormWidgetState extends State<CutroadDetailFormWidget> {
|
|||
controller: widget.unitController,
|
||||
text: pd['OTHER_DEPT'] ?? '',
|
||||
),
|
||||
if (FormUtils.hasValue(pd, 'CONFIRM_USER_NAME') &&
|
||||
if (FormUtils.hasValue(pd, 'GUARDIAN_USER_NAME') &&
|
||||
!widget.isEditable) ...[
|
||||
const Divider(),
|
||||
// ItemListWidget.OneRowImageTitle(label: '作业负责人', imgPath: imgPath)
|
||||
|
|
@ -238,7 +238,10 @@ class _CutroadDetailFormWidgetState extends State<CutroadDetailFormWidget> {
|
|||
ItemListWidget.selectableLineTitleTextRightButton(
|
||||
label: '断路作业实施时间:',
|
||||
isEditable: widget.isEditable,
|
||||
text: pd['WORK_START_DATE'] ?? '',
|
||||
text:
|
||||
FormUtils.hasValue(pd, 'WORK_END_DATE')
|
||||
? '${pd['WORK_START_DATE'] ?? ''}\n-${pd['WORK_END_DATE'] ?? ''}'
|
||||
: pd['WORK_START_DATE'] ?? '',
|
||||
),
|
||||
] else ...[
|
||||
const Divider(),
|
||||
|
|
|
|||
|
|
@ -51,196 +51,7 @@ class CutroadFormBaseWork extends StatelessWidget {
|
|||
);
|
||||
}
|
||||
|
||||
Widget signItemWidget(
|
||||
String signKey,
|
||||
String nameKey,
|
||||
String name,
|
||||
BuildContext context,
|
||||
) {
|
||||
return _itemContainer(
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
// 标题行
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 5, horizontal: 10),
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(child: ListItemFactory.headerTitle('$name')),
|
||||
if (FormUtils.hasValue(pd, nameKey))
|
||||
Text(
|
||||
pd[nameKey]?.toString() ?? '',
|
||||
style: const TextStyle(fontSize: 16),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
|
||||
if (FormUtils.hasValue(signs, signKey))
|
||||
...((signs[signKey] as List<dynamic>)
|
||||
.cast<Map<String, dynamic>>()
|
||||
.map((item) {
|
||||
// 解析 SIGN_PATH
|
||||
List<String> signPaths = [];
|
||||
final rawSP =
|
||||
FormUtils.hasValue(item, 'SIGN_PATH')
|
||||
? item['SIGN_PATH']
|
||||
: null;
|
||||
if (rawSP is String && rawSP.isNotEmpty) {
|
||||
signPaths = rawSP.split(',').map((s) => s.trim()).toList();
|
||||
} else if (rawSP is List) {
|
||||
signPaths = rawSP.cast<String>();
|
||||
}
|
||||
|
||||
// 解析 SIGN_TIME 保留空格
|
||||
List<String> signTimes = [];
|
||||
final rawST =
|
||||
FormUtils.hasValue(item, 'SIGN_TIME')
|
||||
? item['SIGN_TIME']
|
||||
: null;
|
||||
if (rawST is String && rawST.isNotEmpty) {
|
||||
signTimes = rawST.split(',');
|
||||
} else if (rawST is List) {
|
||||
signTimes = rawST.cast<String>();
|
||||
}
|
||||
|
||||
final pairCount = math.min(
|
||||
signPaths.length,
|
||||
signTimes.length,
|
||||
);
|
||||
|
||||
// 解析 IMG_PATH, 最多 2 张
|
||||
List<String> imgPaths = [];
|
||||
final rawIP =
|
||||
FormUtils.hasValue(item, 'IMG_PATH')
|
||||
? item['IMG_PATH']
|
||||
: null;
|
||||
if (rawIP is String && rawIP.isNotEmpty) {
|
||||
imgPaths =
|
||||
rawIP.split(',').map((s) => s.trim()).take(2).toList();
|
||||
} else if (rawIP is List) {
|
||||
imgPaths = rawIP.cast<String>().take(2).toList();
|
||||
}
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 8.0,
|
||||
horizontal: 10,
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
if (imgPaths.isNotEmpty) ...[
|
||||
Row(
|
||||
children:
|
||||
imgPaths.map((p) {
|
||||
final fullUrl = '$baseImgPath$p';
|
||||
return GestureDetector(
|
||||
onTap:
|
||||
() => presentOpaque(
|
||||
SingleImageViewer(imageUrl: fullUrl),
|
||||
context,
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
right: 8.0,
|
||||
),
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(2),
|
||||
child: Image.network(
|
||||
fullUrl,
|
||||
width: 50,
|
||||
height: 50,
|
||||
fit: BoxFit.fill,
|
||||
errorBuilder:
|
||||
(_, __, ___) => const Icon(
|
||||
Icons.broken_image,
|
||||
size: 40,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
],
|
||||
|
||||
// 签名及时间
|
||||
...List.generate(pairCount, (index) {
|
||||
final imgPath = signPaths[index];
|
||||
final timeLabel = signTimes[index];
|
||||
final fullUrl = '$baseImgPath$imgPath';
|
||||
const imageWidth = 200.0;
|
||||
const imageHeight = 100.0;
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 8.0),
|
||||
child: Column(
|
||||
children: [
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
GestureDetector(
|
||||
onTap:
|
||||
() => presentOpaque(
|
||||
SingleImageViewer(
|
||||
imageUrl: fullUrl,
|
||||
),
|
||||
context,
|
||||
),
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
child: Image.network(
|
||||
fullUrl,
|
||||
width: imageWidth,
|
||||
height: imageHeight,
|
||||
fit: BoxFit.fill,
|
||||
errorBuilder:
|
||||
(_, __, ___) => const Icon(
|
||||
Icons.broken_image,
|
||||
size: 60,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: SizedBox(
|
||||
height: imageHeight,
|
||||
child: Align(
|
||||
alignment: Alignment.bottomRight,
|
||||
child: Text(
|
||||
timeLabel,
|
||||
style: const TextStyle(
|
||||
fontSize: 14,
|
||||
color: Colors.black87,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
if (index < pairCount - 1)
|
||||
const Padding(
|
||||
padding: EdgeInsets.only(top: 8.0),
|
||||
child: Divider(height: 1),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}),
|
||||
],
|
||||
),
|
||||
);
|
||||
})
|
||||
.toList()),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
|
|
|||
|
|
@ -71,9 +71,9 @@ class _CutroadSafeFuncSureState extends State<CutroadSafeFuncSure> {
|
|||
return <String, dynamic>{'signs': <String, dynamic>{}};
|
||||
});
|
||||
|
||||
final futureMeasures = ApiService.listSignFinishAllMeasures('cutroad')
|
||||
final futureMeasures = ApiService.listSignSureAllMeasures('cutroad', widget.CUTROAD_ID)
|
||||
.catchError((e) {
|
||||
return <String, dynamic>{'measuresList': <Map<String, dynamic>>[]};
|
||||
return <String, dynamic>{'measuresForSignList': <Map<String, dynamic>>[]};
|
||||
});
|
||||
|
||||
final results = await Future.wait([futurePd, futureSigns, futureMeasures]);
|
||||
|
|
@ -92,7 +92,7 @@ class _CutroadSafeFuncSureState extends State<CutroadSafeFuncSure> {
|
|||
: <String, dynamic>{};
|
||||
|
||||
final newMeasuresList = <Map<String, dynamic>>[];
|
||||
final rawMeasures = measuresResult['measuresList'];
|
||||
final rawMeasures = measuresResult['measuresForSignList'];
|
||||
if (rawMeasures is List) {
|
||||
for (final m in rawMeasures) {
|
||||
if (m is Map) {
|
||||
|
|
|
|||
|
|
@ -145,9 +145,11 @@ class _CutroadListPageState extends State<CutroadListPage> {
|
|||
}
|
||||
|
||||
/// 申请
|
||||
void _handleApply() {
|
||||
void _handleApply() async{
|
||||
// 处理申请按钮点击逻辑
|
||||
pushPage(CutroadApplyDetail(CUTROAD_ID: '', flow: widget.flow), context);
|
||||
await pushPage(CutroadApplyDetail(CUTROAD_ID: '', flow: widget.flow), context);
|
||||
_fetchData();
|
||||
LoadingDialogHelper.hide();
|
||||
}
|
||||
|
||||
/// 打开流程图
|
||||
|
|
@ -230,9 +232,10 @@ class _CutroadListPageState extends State<CutroadListPage> {
|
|||
default:
|
||||
break;
|
||||
}
|
||||
LoadingDialogHelper.show();
|
||||
_fetchSteps();
|
||||
_fetchData();
|
||||
|
||||
|
||||
await _fetchData();
|
||||
LoadingDialogHelper.hide();
|
||||
}
|
||||
|
||||
Widget _buildFlowStepItem({
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@ import 'package:qhd_prevention/pages/home/tap/tabList/special_Wrok/MeasuresListW
|
|||
import 'package:qhd_prevention/customWidget/BaiDuMap/Map_page.dart';
|
||||
import 'package:qhd_prevention/pages/home/tap/workArea_picker.dart';
|
||||
|
||||
|
||||
enum EditUserType {
|
||||
PROJECT_MANAGER('断路示意图负责单位', '断路示意图负责人', true),
|
||||
GUARDIAN('监护人单位', '监护人', true),
|
||||
|
|
@ -57,6 +56,7 @@ class CutroadApplyDetail extends StatefulWidget {
|
|||
|
||||
class _CutroadApplyDetailState extends State<CutroadApplyDetail> {
|
||||
late bool isEditable = false;
|
||||
|
||||
/// 编辑还是新增
|
||||
late String msg = 'add';
|
||||
|
||||
|
|
@ -69,15 +69,18 @@ class _CutroadApplyDetailState extends State<CutroadApplyDetail> {
|
|||
final TextEditingController _contentController = TextEditingController();
|
||||
final TextEditingController _relatedController = TextEditingController();
|
||||
final TextEditingController _riskController = TextEditingController();
|
||||
|
||||
/// ------------------- 新增 -------------------
|
||||
/// 视频监控摄像
|
||||
late List<dynamic> videoMonitoringList = [];
|
||||
|
||||
/// 承包商列表
|
||||
late List<dynamic> unitAllList = [];
|
||||
|
||||
/// 作业区域列表
|
||||
late List<Map<String, dynamic>> workAreaList = [];
|
||||
/// --------------------------------------
|
||||
|
||||
/// --------------------------------------
|
||||
|
||||
// 存储各单位的人员列表
|
||||
final Map<EditUserType, List<Map<String, dynamic>>> _personCache = {};
|
||||
|
|
@ -96,7 +99,6 @@ class _CutroadApplyDetailState extends State<CutroadApplyDetail> {
|
|||
pd['APPLY_USER_ID'] = SessionService.instance.loginUserId;
|
||||
pd['APPLY_USER_NAME'] = SessionService.instance.username;
|
||||
pd['IS_CONTRACTOR_WORK'] = '0';
|
||||
|
||||
}
|
||||
|
||||
_getVideoList();
|
||||
|
|
@ -128,7 +130,7 @@ class _CutroadApplyDetailState extends State<CutroadApplyDetail> {
|
|||
}
|
||||
|
||||
void set_pd_USER_ID(EditUserType type, String id) {
|
||||
pd['${type.name}_USER_ID'] = id;
|
||||
pd['${type.name}_USER_ID'] = id;
|
||||
}
|
||||
|
||||
void set_pd_USER_Name(EditUserType type, String name) {
|
||||
|
|
@ -144,9 +146,7 @@ class _CutroadApplyDetailState extends State<CutroadApplyDetail> {
|
|||
}
|
||||
|
||||
String get_pd_USER_ID(EditUserType type) {
|
||||
|
||||
return pd['${type.name}_USER_ID'] ?? '';
|
||||
|
||||
return pd['${type.name}_USER_ID'] ?? '';
|
||||
}
|
||||
|
||||
String get_pd_USER_Name(EditUserType type) {
|
||||
|
|
@ -244,13 +244,15 @@ class _CutroadApplyDetailState extends State<CutroadApplyDetail> {
|
|||
return;
|
||||
}
|
||||
|
||||
if (personList.isEmpty) { // 一般这种情况是因为重新编辑没有缓存对应部门的负责人,所以先拉取一下接口
|
||||
if (personList.isEmpty) {
|
||||
// 一般这种情况是因为重新编辑没有缓存对应部门的负责人,所以先拉取一下接口
|
||||
await _getPersonListForUnitId(unitId, type);
|
||||
final list = _personCache[type] ?? [];
|
||||
|
||||
if (list.isEmpty) { // 如果还是没数据,说明该部门没有可选的人
|
||||
if (list.isEmpty) {
|
||||
// 如果还是没数据,说明该部门没有可选的人
|
||||
ToastUtil.showNormal(context, '暂无数据,请选择其他单位');
|
||||
}else{
|
||||
} else {
|
||||
choosePersonHandle(type);
|
||||
}
|
||||
return;
|
||||
|
|
@ -287,6 +289,7 @@ class _CutroadApplyDetailState extends State<CutroadApplyDetail> {
|
|||
// },
|
||||
{'value': _riskController.text.trim(), 'message': '请填写风险辨识结果'},
|
||||
];
|
||||
|
||||
/// 各项负责人校验
|
||||
final unitRules = <EditUserType>[
|
||||
EditUserType.PROJECT_MANAGER,
|
||||
|
|
@ -295,8 +298,8 @@ class _CutroadApplyDetailState extends State<CutroadApplyDetail> {
|
|||
EditUserType.ACCEPT_CONFESS,
|
||||
EditUserType.CONFIRM,
|
||||
EditUserType.LEADER,
|
||||
EditUserType.AUDIT,
|
||||
EditUserType.APPROVE,
|
||||
EditUserType.AUDIT,
|
||||
EditUserType.APPROVE,
|
||||
EditUserType.WORK_START,
|
||||
EditUserType.WORK_END,
|
||||
EditUserType.ACCEPT,
|
||||
|
|
@ -319,7 +322,8 @@ class _CutroadApplyDetailState extends State<CutroadApplyDetail> {
|
|||
return;
|
||||
}
|
||||
|
||||
if (pd['IS_CONTRACTOR_WORK'] == '1' && !FormUtils.hasValue(pd, 'UNITS_ID')) {
|
||||
if (pd['IS_CONTRACTOR_WORK'] == '1' &&
|
||||
!FormUtils.hasValue(pd, 'UNITS_ID')) {
|
||||
ToastUtil.showNormal(context, '请选择承包商');
|
||||
return;
|
||||
}
|
||||
|
|
@ -339,7 +343,6 @@ class _CutroadApplyDetailState extends State<CutroadApplyDetail> {
|
|||
return;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
// LoadingDialogHelper.show();
|
||||
|
||||
|
|
@ -364,7 +367,8 @@ class _CutroadApplyDetailState extends State<CutroadApplyDetail> {
|
|||
pd['APPLY_USER_ID'] = SessionService.instance.loginUserId;
|
||||
pd['APPLY_USER_NAME'] = SessionService.instance.username;
|
||||
pd['USER_ID'] = SessionService.instance.loginUserId;
|
||||
pd['SPECIAL_WORK'] = FormUtils.hasValue(pd, 'SPECIAL_WORK') ? pd['SPECIAL_WORK'] : '无';
|
||||
pd['SPECIAL_WORK'] =
|
||||
FormUtils.hasValue(pd, 'SPECIAL_WORK') ? pd['SPECIAL_WORK'] : '无';
|
||||
}
|
||||
|
||||
LoadingDialogHelper.show();
|
||||
|
|
@ -397,9 +401,9 @@ class _CutroadApplyDetailState extends State<CutroadApplyDetail> {
|
|||
final choice = await BottomPicker.show<String>(
|
||||
context,
|
||||
items:
|
||||
videoMonitoringList
|
||||
.map((item) => item['VIDEONAME'] as String)
|
||||
.toList(),
|
||||
videoMonitoringList
|
||||
.map((item) => item['VIDEONAME'] as String)
|
||||
.toList(),
|
||||
itemBuilder: (item) => Text(item, textAlign: TextAlign.center),
|
||||
initialIndex: 0,
|
||||
);
|
||||
|
|
@ -408,7 +412,7 @@ class _CutroadApplyDetailState extends State<CutroadApplyDetail> {
|
|||
pd['VIDEONAME'] = choice;
|
||||
|
||||
Map<String, dynamic> result = videoMonitoringList.firstWhere(
|
||||
(item) => item['VIDEONAME'] == choice,
|
||||
(item) => item['VIDEONAME'] == choice,
|
||||
orElse: () => {}, // 避免找不到时报错
|
||||
);
|
||||
if (FormUtils.hasValue(result, 'VIDEOMANAGER_ID')) {
|
||||
|
|
@ -418,6 +422,7 @@ class _CutroadApplyDetailState extends State<CutroadApplyDetail> {
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// 选择承包商
|
||||
Future<void> _chooseUnitManager() async {
|
||||
final choice = await BottomPicker.show<String>(
|
||||
|
|
@ -431,7 +436,7 @@ class _CutroadApplyDetailState extends State<CutroadApplyDetail> {
|
|||
pd['UNITS_NAME'] = choice;
|
||||
|
||||
Map<String, dynamic> result = unitAllList.firstWhere(
|
||||
(item) => item['UNITS_NAME'] == choice,
|
||||
(item) => item['UNITS_NAME'] == choice,
|
||||
orElse: () => {}, // 避免找不到时报错
|
||||
);
|
||||
if (FormUtils.hasValue(result, 'UNITS_ID')) {
|
||||
|
|
@ -441,10 +446,9 @@ class _CutroadApplyDetailState extends State<CutroadApplyDetail> {
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// 选择经纬度
|
||||
Future<void> _showLocationHandle() async{
|
||||
Future<void> _showLocationHandle() async {
|
||||
if (!FormUtils.hasValue(pd, 'ELECTRONIC_FENCE_AREA_ID')) {
|
||||
ToastUtil.showNormal(context, '请选择作业区域');
|
||||
return;
|
||||
|
|
@ -453,10 +457,11 @@ class _CutroadApplyDetailState extends State<CutroadApplyDetail> {
|
|||
setState(() {
|
||||
pd['LONGITUDE'] = mapData['longitue'] ?? '';
|
||||
pd['LATITUDE'] = mapData['latitude'] ?? '';
|
||||
pd['LATITUDE_LONGITUDE'] = '${mapData['longitue'] ?? ''},${mapData['latitude'] ?? ''}';
|
||||
pd['LATITUDE_LONGITUDE'] =
|
||||
'${mapData['longitue'] ?? ''},${mapData['latitude'] ?? ''}';
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/// 作业区域
|
||||
Future<void> _getWorkArea() async {
|
||||
//FocusHelper.clearFocus(context);
|
||||
|
|
@ -467,16 +472,21 @@ class _CutroadApplyDetailState extends State<CutroadApplyDetail> {
|
|||
backgroundColor: Colors.transparent,
|
||||
builder:
|
||||
(_) => WorkAreaPicker(
|
||||
onSelected: (String id, String POSITIONS, String name) {
|
||||
pd['ELECTRONIC_FENCE_AREA_ID'] = id;
|
||||
pd['POSITIONS'] = POSITIONS;
|
||||
pd['PLS_NAME'] = name;
|
||||
},
|
||||
),
|
||||
onSelected: (String id, String POSITIONS, String name) {
|
||||
setState(() {
|
||||
setState(() {
|
||||
pd['ELECTRONIC_FENCE_AREA_ID'] = id;
|
||||
pd['POSITIONS'] = POSITIONS;
|
||||
pd['PLS_NAME'] = name;
|
||||
});
|
||||
});
|
||||
},
|
||||
),
|
||||
).then((_) {
|
||||
//FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
|
||||
/// 获取摄像头列表
|
||||
Future<void> _getVideoList() async {
|
||||
final result = await ApiService.getVideomanagerList();
|
||||
|
|
@ -484,6 +494,7 @@ class _CutroadApplyDetailState extends State<CutroadApplyDetail> {
|
|||
videoMonitoringList = result['varList'] ?? [];
|
||||
});
|
||||
}
|
||||
|
||||
/// 获承包商列表
|
||||
Future<void> _getUnitListAll() async {
|
||||
final result = await ApiService.getUnitListAll();
|
||||
|
|
@ -491,6 +502,7 @@ class _CutroadApplyDetailState extends State<CutroadApplyDetail> {
|
|||
unitAllList = result['varList'] ?? [];
|
||||
});
|
||||
}
|
||||
|
||||
/// 作业区域列表
|
||||
Future<void> _getPlsList() async {
|
||||
final result = await ApiService.getWorkAreaList();
|
||||
|
|
@ -499,12 +511,15 @@ class _CutroadApplyDetailState extends State<CutroadApplyDetail> {
|
|||
workAreaList = jsonDecode(zTreeNodes);
|
||||
});
|
||||
}
|
||||
|
||||
/// ------------------------------------------------------------
|
||||
|
||||
/// 初始化拉取数据
|
||||
Future<void> _getData() async {
|
||||
|
||||
final data = await ApiService.getHomeworkFindById('cutroad', widget.CUTROAD_ID);
|
||||
final data = await ApiService.getHomeworkFindById(
|
||||
'cutroad',
|
||||
widget.CUTROAD_ID,
|
||||
);
|
||||
setState(() {
|
||||
pd = data['pd'];
|
||||
if (pd['STEP_ID'] == 0) {
|
||||
|
|
@ -527,7 +542,8 @@ class _CutroadApplyDetailState extends State<CutroadApplyDetail> {
|
|||
}
|
||||
|
||||
Future<void> _getSigns(String homework_id) async {
|
||||
final data = await ApiService.listSignFinished('cutroad',
|
||||
final data = await ApiService.listSignFinished(
|
||||
'cutroad',
|
||||
homework_id.length > 0 ? homework_id : widget.CUTROAD_ID,
|
||||
);
|
||||
setState(() {
|
||||
|
|
@ -536,7 +552,8 @@ class _CutroadApplyDetailState extends State<CutroadApplyDetail> {
|
|||
}
|
||||
|
||||
Future<void> _getMeasures(String homework_id) async {
|
||||
final data = await ApiService.listSignFinishMeasures('cutroad',
|
||||
final data = await ApiService.listSignFinishMeasures(
|
||||
'cutroad',
|
||||
homework_id.length > 0 ? homework_id : widget.CUTROAD_ID,
|
||||
);
|
||||
setState(() {
|
||||
|
|
@ -565,7 +582,7 @@ class _CutroadApplyDetailState extends State<CutroadApplyDetail> {
|
|||
unitController: _unitController,
|
||||
relatedController: _relatedController,
|
||||
riskController: _riskController,
|
||||
onChooseLevel: (){},
|
||||
onChooseLevel: () {},
|
||||
// 新增
|
||||
onChooseVideoManager: _chooseVideoManager,
|
||||
onContractorHandle: _chooseUnitManager,
|
||||
|
|
@ -646,7 +663,7 @@ class _CutroadApplyDetailState extends State<CutroadApplyDetail> {
|
|||
color: Colors.white,
|
||||
child: MeasuresListWidget(
|
||||
measuresList:
|
||||
measuresList, // List<Map<String, dynamic>>
|
||||
measuresList, // List<Map<String, dynamic>>
|
||||
baseImgPath: ApiService.baseImgPath,
|
||||
isAllowEdit: false,
|
||||
),
|
||||
|
|
@ -674,45 +691,9 @@ class _CutroadApplyDetailState extends State<CutroadApplyDetail> {
|
|||
),
|
||||
isEditable
|
||||
? Row(
|
||||
spacing: 10,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Expanded(
|
||||
child: CustomButton(
|
||||
height: 45,
|
||||
textStyle: TextStyle(
|
||||
fontSize: 16,
|
||||
color: Colors.white,
|
||||
),
|
||||
text: '提交',
|
||||
backgroundColor: Colors.blue,
|
||||
onPressed: () {
|
||||
_submit('1');
|
||||
},
|
||||
),
|
||||
),
|
||||
|
||||
Expanded(
|
||||
child: CustomButton(
|
||||
textStyle: TextStyle(
|
||||
fontSize: 16,
|
||||
color: Colors.white,
|
||||
),
|
||||
text: '暂存',
|
||||
backgroundColor: Colors.green,
|
||||
onPressed: () {
|
||||
_submit('0');
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
: Column(
|
||||
children: [
|
||||
SizedBox(height: 20),
|
||||
Row(
|
||||
spacing: 10,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
SizedBox(width: 50),
|
||||
Expanded(
|
||||
child: CustomButton(
|
||||
height: 45,
|
||||
|
|
@ -720,18 +701,54 @@ class _CutroadApplyDetailState extends State<CutroadApplyDetail> {
|
|||
fontSize: 16,
|
||||
color: Colors.white,
|
||||
),
|
||||
text: '返回',
|
||||
backgroundColor: Colors.green,
|
||||
text: '提交',
|
||||
backgroundColor: Colors.blue,
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
_submit('1');
|
||||
},
|
||||
),
|
||||
),
|
||||
SizedBox(width: 50),
|
||||
|
||||
Expanded(
|
||||
child: CustomButton(
|
||||
textStyle: TextStyle(
|
||||
fontSize: 16,
|
||||
color: Colors.white,
|
||||
),
|
||||
text: '暂存',
|
||||
backgroundColor: Colors.green,
|
||||
onPressed: () {
|
||||
_submit('0');
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
: Column(
|
||||
children: [
|
||||
SizedBox(height: 20),
|
||||
Row(
|
||||
children: [
|
||||
SizedBox(width: 50),
|
||||
Expanded(
|
||||
child: CustomButton(
|
||||
height: 45,
|
||||
textStyle: TextStyle(
|
||||
fontSize: 16,
|
||||
color: Colors.white,
|
||||
),
|
||||
text: '返回',
|
||||
backgroundColor: Colors.green,
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
),
|
||||
),
|
||||
SizedBox(width: 50),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ import 'package:qhd_prevention/customWidget/single_image_viewer.dart';
|
|||
import 'package:qhd_prevention/pages/mine/mine_sign_page.dart';
|
||||
|
||||
import '../CutroadDetailFormWidget.dart';
|
||||
|
||||
/// 监护人签字
|
||||
class CutroadJhrDetail extends StatefulWidget {
|
||||
const CutroadJhrDetail({
|
||||
|
|
@ -32,13 +33,14 @@ class CutroadJhrDetail extends StatefulWidget {
|
|||
|
||||
class _CutroadJhrDetailState extends State<CutroadJhrDetail> {
|
||||
late bool isEditable = false;
|
||||
|
||||
/// 详情
|
||||
late Map<String, dynamic> pd = {};
|
||||
|
||||
/// 安全防护措施列表
|
||||
late List<Map<String, dynamic>> measuresList = [];
|
||||
late Map<String, dynamic> signs = {};
|
||||
|
||||
|
||||
List<String> imagePaths = [];
|
||||
List<String> signTimes = []; // 签字时间列表
|
||||
@override
|
||||
|
|
@ -55,7 +57,7 @@ class _CutroadJhrDetailState extends State<CutroadJhrDetail> {
|
|||
MaterialPageRoute(builder: (context) => MineSignPage()),
|
||||
);
|
||||
await NativeOrientation.setPortrait();
|
||||
if (path != null) {
|
||||
if (path != null) {
|
||||
final now = DateFormat('yyyy-MM-dd HH:mm').format(DateTime.now());
|
||||
setState(() {
|
||||
imagePaths.add(path);
|
||||
|
|
@ -137,7 +139,7 @@ if (path != null) {
|
|||
title: '作废原因',
|
||||
hintText: '请输入作废原因',
|
||||
cancelText: '取消',
|
||||
confirmText: '确定'
|
||||
confirmText: '确定',
|
||||
);
|
||||
if (reasonText.isEmpty) {
|
||||
ToastUtil.showNormal(context, '请填写作废原因');
|
||||
|
|
@ -162,32 +164,31 @@ if (path != null) {
|
|||
barrierDismissible: false,
|
||||
);
|
||||
if (confirmed) {
|
||||
LoadingDialogHelper.show();
|
||||
try {
|
||||
final result = await ApiService.saveSafeFunctionSure(
|
||||
'cutroad',
|
||||
formData,
|
||||
imagePaths,
|
||||
);
|
||||
LoadingDialogHelper.hide();
|
||||
if (result['result'] == 'success') {
|
||||
ToastUtil.showSuccess(
|
||||
context,
|
||||
'保存成功',
|
||||
);
|
||||
Navigator.of(context).pop(true);
|
||||
}
|
||||
} catch (e) {
|
||||
LoadingDialogHelper.hide();
|
||||
ToastUtil.showNormal(context, '操作失败:$e');
|
||||
}
|
||||
|
||||
LoadingDialogHelper.show();
|
||||
try {
|
||||
final result = await ApiService.saveSafeFunctionSure(
|
||||
'cutroad',
|
||||
formData,
|
||||
imagePaths,
|
||||
);
|
||||
LoadingDialogHelper.hide();
|
||||
if (result['result'] == 'success') {
|
||||
ToastUtil.showSuccess(context, '保存成功');
|
||||
Navigator.of(context).pop(true);
|
||||
}
|
||||
} catch (e) {
|
||||
LoadingDialogHelper.hide();
|
||||
ToastUtil.showNormal(context, '操作失败:$e');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 初始化拉取数据
|
||||
Future<void> _getData() async {
|
||||
final data = await ApiService.getHomeworkFindById('cutroad', widget.CUTROAD_ID);
|
||||
final data = await ApiService.getHomeworkFindById(
|
||||
'cutroad',
|
||||
widget.CUTROAD_ID,
|
||||
);
|
||||
setState(() {
|
||||
pd = data['pd'];
|
||||
|
||||
|
|
@ -197,7 +198,8 @@ if (path != null) {
|
|||
}
|
||||
|
||||
Future<void> _getMeasures(String homework_id) async {
|
||||
final data = await ApiService.listSignFinishMeasures('cutroad',
|
||||
final data = await ApiService.listSignFinishMeasures(
|
||||
'cutroad',
|
||||
homework_id.length > 0 ? homework_id : widget.CUTROAD_ID,
|
||||
);
|
||||
setState(() {
|
||||
|
|
@ -208,7 +210,8 @@ if (path != null) {
|
|||
}
|
||||
|
||||
Future<void> _getSigns(String homework_id) async {
|
||||
final data = await ApiService.listSignFinished('cutroad',
|
||||
final data = await ApiService.listSignFinished(
|
||||
'cutroad',
|
||||
homework_id.length > 0 ? homework_id : widget.CUTROAD_ID,
|
||||
);
|
||||
setState(() {
|
||||
|
|
@ -234,11 +237,10 @@ if (path != null) {
|
|||
Container(
|
||||
color: Colors.white,
|
||||
child: MeasuresListWidget(
|
||||
measuresList:
|
||||
measuresList, // List<Map<String, dynamic>>
|
||||
measuresList: measuresList, // List<Map<String, dynamic>>
|
||||
baseImgPath: ApiService.baseImgPath,
|
||||
isAllowEdit: false,
|
||||
isShowSign:true,
|
||||
isShowSign: true,
|
||||
),
|
||||
),
|
||||
],
|
||||
|
|
@ -325,7 +327,7 @@ if (path != null) {
|
|||
signs: signs,
|
||||
pd: pd,
|
||||
isEditable: false,
|
||||
onChooseLevel: (){},
|
||||
onChooseLevel: () {},
|
||||
),
|
||||
SizedBox(height: 20),
|
||||
_setSafeDetailWidget(),
|
||||
|
|
|
|||
|
|
@ -283,6 +283,7 @@ class _CutroadJszyDetailState extends State<CutroadJszyDetail> {
|
|||
child: SingleChildScrollView(
|
||||
padding: EdgeInsets.all(12),
|
||||
child: Column(
|
||||
spacing: 12,
|
||||
children: [
|
||||
// _setSafeDetailWidget(),
|
||||
CutroadFormBaseWork(
|
||||
|
|
@ -344,7 +345,6 @@ class _CutroadJszyDetailState extends State<CutroadJszyDetail> {
|
|||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 12,),
|
||||
_bottomButtons(),
|
||||
],
|
||||
),
|
||||
|
|
|
|||
|
|
@ -188,6 +188,7 @@ class _CutroadKszyDetailState extends State<CutroadKszyDetail> {
|
|||
child: SingleChildScrollView(
|
||||
padding: EdgeInsets.all(12),
|
||||
child: Column(
|
||||
spacing: 12,
|
||||
children: [
|
||||
// _setSafeDetailWidget(),
|
||||
CutroadFormBaseWork(
|
||||
|
|
@ -258,7 +259,6 @@ class _CutroadKszyDetailState extends State<CutroadKszyDetail> {
|
|||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 12,),
|
||||
_bottomButtons(),
|
||||
],
|
||||
),
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ import 'package:qhd_prevention/http/ApiService.dart';
|
|||
import 'package:qhd_prevention/pages/mine/mine_sign_page.dart';
|
||||
import 'package:qhd_prevention/pages/my_appbar.dart';
|
||||
|
||||
|
||||
/// 消防、安全管理部门意见
|
||||
class CutroadShbmDetail extends StatefulWidget {
|
||||
const CutroadShbmDetail({
|
||||
|
|
@ -58,7 +57,7 @@ class _CutroadShbmDetailState extends State<CutroadShbmDetail> {
|
|||
await NativeOrientation.setPortrait();
|
||||
if (path != null) {
|
||||
final now = DateFormat('yyyy-MM-dd HH:mm').format(DateTime.now());
|
||||
setState(() {
|
||||
setState(() {
|
||||
signImages.add(path);
|
||||
signTimes.add(now);
|
||||
});
|
||||
|
|
@ -143,7 +142,7 @@ setState(() {
|
|||
title: '作废原因',
|
||||
hintText: '请输入作废原因',
|
||||
cancelText: '取消',
|
||||
confirmText: '确定'
|
||||
confirmText: '确定',
|
||||
);
|
||||
if (reasonText.isEmpty) {
|
||||
ToastUtil.showNormal(context, '请填写作废原因');
|
||||
|
|
@ -170,29 +169,31 @@ setState(() {
|
|||
barrierDismissible: false,
|
||||
);
|
||||
if (confirmed) {
|
||||
LoadingDialogHelper.show();
|
||||
try {
|
||||
final result = await ApiService.saveSafeFunctionSure(
|
||||
'cutroad',
|
||||
formData,
|
||||
signImages,
|
||||
);
|
||||
LoadingDialogHelper.hide();
|
||||
if (result['result'] == 'success') {
|
||||
ToastUtil.showSuccess(context, '保存成功');
|
||||
Navigator.of(context).pop(true);
|
||||
}
|
||||
} catch (e) {
|
||||
LoadingDialogHelper.hide();
|
||||
ToastUtil.showNormal(context, '操作失败:$e');
|
||||
}
|
||||
|
||||
LoadingDialogHelper.show();
|
||||
try {
|
||||
final result = await ApiService.saveSafeFunctionSure(
|
||||
'cutroad',
|
||||
formData,
|
||||
signImages,
|
||||
);
|
||||
LoadingDialogHelper.hide();
|
||||
if (result['result'] == 'success') {
|
||||
ToastUtil.showSuccess(context, '保存成功');
|
||||
Navigator.of(context).pop(true);
|
||||
}
|
||||
} catch (e) {
|
||||
LoadingDialogHelper.hide();
|
||||
ToastUtil.showNormal(context, '操作失败:$e');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 初始化拉取数据
|
||||
Future<void> _getData() async {
|
||||
final data = await ApiService.getHomeworkFindById('cutroad', widget.CUTROAD_ID);
|
||||
final data = await ApiService.getHomeworkFindById(
|
||||
'cutroad',
|
||||
widget.CUTROAD_ID,
|
||||
);
|
||||
setState(() {
|
||||
pd = data['pd'];
|
||||
|
||||
|
|
@ -202,7 +203,8 @@ setState(() {
|
|||
}
|
||||
|
||||
Future<void> _getMeasures(String homework_id) async {
|
||||
final data = await ApiService.listSignFinishMeasures('cutroad',
|
||||
final data = await ApiService.listSignFinishMeasures(
|
||||
'cutroad',
|
||||
homework_id.length > 0 ? homework_id : widget.CUTROAD_ID,
|
||||
);
|
||||
setState(() {
|
||||
|
|
@ -213,7 +215,8 @@ setState(() {
|
|||
}
|
||||
|
||||
Future<void> _getSigns(String homework_id) async {
|
||||
final data = await ApiService.listSignFinished('cutroad',
|
||||
final data = await ApiService.listSignFinished(
|
||||
'cutroad',
|
||||
homework_id.length > 0 ? homework_id : widget.CUTROAD_ID,
|
||||
);
|
||||
setState(() {
|
||||
|
|
@ -279,7 +282,7 @@ setState(() {
|
|||
'消防、安全管理部门意见',
|
||||
'请输入意见',
|
||||
_contentController,
|
||||
isRequired: true
|
||||
isRequired: true,
|
||||
),
|
||||
Divider(),
|
||||
Column(
|
||||
|
|
@ -300,7 +303,7 @@ setState(() {
|
|||
),
|
||||
if (signImages.isNotEmpty) _signListWidget(),
|
||||
],
|
||||
)
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ class _CutroadSpbmDetailState extends State<CutroadSpbmDetail> {
|
|||
await NativeOrientation.setPortrait();
|
||||
if (path != null) {
|
||||
final now = DateFormat('yyyy-MM-dd HH:mm').format(DateTime.now());
|
||||
setState(() {
|
||||
setState(() {
|
||||
signImages.add(path);
|
||||
signTimes.add(now);
|
||||
});
|
||||
|
|
@ -142,7 +142,7 @@ setState(() {
|
|||
title: '作废原因',
|
||||
hintText: '请输入作废原因',
|
||||
cancelText: '取消',
|
||||
confirmText: '确定'
|
||||
confirmText: '确定',
|
||||
);
|
||||
if (reasonText.isEmpty) {
|
||||
ToastUtil.showNormal(context, '请填写作废原因');
|
||||
|
|
@ -169,29 +169,31 @@ setState(() {
|
|||
barrierDismissible: false,
|
||||
);
|
||||
if (confirmed) {
|
||||
LoadingDialogHelper.show();
|
||||
try {
|
||||
final result = await ApiService.saveSafeFunctionSure(
|
||||
'cutroad',
|
||||
formData,
|
||||
signImages,
|
||||
);
|
||||
LoadingDialogHelper.hide();
|
||||
if (result['result'] == 'success') {
|
||||
ToastUtil.showSuccess(context, '保存成功');
|
||||
Navigator.of(context).pop(true);
|
||||
}
|
||||
} catch (e) {
|
||||
LoadingDialogHelper.hide();
|
||||
ToastUtil.showNormal(context, '操作失败:$e');
|
||||
}
|
||||
|
||||
LoadingDialogHelper.show();
|
||||
try {
|
||||
final result = await ApiService.saveSafeFunctionSure(
|
||||
'cutroad',
|
||||
formData,
|
||||
signImages,
|
||||
);
|
||||
LoadingDialogHelper.hide();
|
||||
if (result['result'] == 'success') {
|
||||
ToastUtil.showSuccess(context, '保存成功');
|
||||
Navigator.of(context).pop(true);
|
||||
}
|
||||
} catch (e) {
|
||||
LoadingDialogHelper.hide();
|
||||
ToastUtil.showNormal(context, '操作失败:$e');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 初始化拉取数据
|
||||
Future<void> _getData() async {
|
||||
final data = await ApiService.getHomeworkFindById('cutroad', widget.CUTROAD_ID);
|
||||
final data = await ApiService.getHomeworkFindById(
|
||||
'cutroad',
|
||||
widget.CUTROAD_ID,
|
||||
);
|
||||
setState(() {
|
||||
pd = data['pd'];
|
||||
|
||||
|
|
@ -201,7 +203,8 @@ setState(() {
|
|||
}
|
||||
|
||||
Future<void> _getMeasures(String homework_id) async {
|
||||
final data = await ApiService.listSignFinishMeasures('cutroad',
|
||||
final data = await ApiService.listSignFinishMeasures(
|
||||
'cutroad',
|
||||
homework_id.length > 0 ? homework_id : widget.CUTROAD_ID,
|
||||
);
|
||||
setState(() {
|
||||
|
|
@ -212,7 +215,8 @@ setState(() {
|
|||
}
|
||||
|
||||
Future<void> _getSigns(String homework_id) async {
|
||||
final data = await ApiService.listSignFinished('cutroad',
|
||||
final data = await ApiService.listSignFinished(
|
||||
'cutroad',
|
||||
homework_id.length > 0 ? homework_id : widget.CUTROAD_ID,
|
||||
);
|
||||
setState(() {
|
||||
|
|
@ -278,8 +282,7 @@ setState(() {
|
|||
'审批部门负责人意见',
|
||||
'请输入意见',
|
||||
_contentController,
|
||||
isRequired: true
|
||||
|
||||
isRequired: true,
|
||||
),
|
||||
Divider(),
|
||||
Column(
|
||||
|
|
@ -305,7 +308,7 @@ setState(() {
|
|||
),
|
||||
if (signImages.isNotEmpty) _signListWidget(),
|
||||
],
|
||||
)
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ class _CutroadSetSafeDetailState extends State<CutroadSetSafeDetail> {
|
|||
return <String, dynamic>{'signs': <String, dynamic>{}};
|
||||
});
|
||||
|
||||
final futureMeasures = ApiService.listSignFinishAllMeasures('cutroad')
|
||||
final futureMeasures = ApiService.listSignFinishAllMeasures('cutroad', widget.CUTROAD_ID)
|
||||
.catchError((e) {
|
||||
return <String, dynamic>{'measuresList': <Map<String, dynamic>>[]};
|
||||
});
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ class _CutroadSzdwDetailState extends State<CutroadSzdwDetail> {
|
|||
await NativeOrientation.setPortrait();
|
||||
if (path != null) {
|
||||
final now = DateFormat('yyyy-MM-dd HH:mm').format(DateTime.now());
|
||||
setState(() {
|
||||
setState(() {
|
||||
signImages.add(path);
|
||||
signTimes.add(now);
|
||||
});
|
||||
|
|
@ -143,7 +143,7 @@ setState(() {
|
|||
title: '作废原因',
|
||||
hintText: '请输入作废原因',
|
||||
cancelText: '取消',
|
||||
confirmText: '确定'
|
||||
confirmText: '确定',
|
||||
);
|
||||
if (reasonText.isEmpty) {
|
||||
ToastUtil.showNormal(context, '请填写作废原因');
|
||||
|
|
@ -170,29 +170,31 @@ setState(() {
|
|||
barrierDismissible: false,
|
||||
);
|
||||
if (confirmed) {
|
||||
LoadingDialogHelper.show();
|
||||
try {
|
||||
final result = await ApiService.saveSafeFunctionSure(
|
||||
'cutroad',
|
||||
formData,
|
||||
signImages,
|
||||
);
|
||||
LoadingDialogHelper.hide();
|
||||
if (result['result'] == 'success') {
|
||||
ToastUtil.showSuccess(context, '保存成功');
|
||||
Navigator.of(context).pop(true);
|
||||
}
|
||||
} catch (e) {
|
||||
LoadingDialogHelper.hide();
|
||||
ToastUtil.showNormal(context, '操作失败:$e');
|
||||
}
|
||||
|
||||
LoadingDialogHelper.show();
|
||||
try {
|
||||
final result = await ApiService.saveSafeFunctionSure(
|
||||
'cutroad',
|
||||
formData,
|
||||
signImages,
|
||||
);
|
||||
LoadingDialogHelper.hide();
|
||||
if (result['result'] == 'success') {
|
||||
ToastUtil.showSuccess(context, '保存成功');
|
||||
Navigator.of(context).pop(true);
|
||||
}
|
||||
} catch (e) {
|
||||
LoadingDialogHelper.hide();
|
||||
ToastUtil.showNormal(context, '操作失败:$e');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 初始化拉取数据
|
||||
Future<void> _getData() async {
|
||||
final data = await ApiService.getHomeworkFindById('cutroad', widget.CUTROAD_ID);
|
||||
final data = await ApiService.getHomeworkFindById(
|
||||
'cutroad',
|
||||
widget.CUTROAD_ID,
|
||||
);
|
||||
setState(() {
|
||||
pd = data['pd'];
|
||||
|
||||
|
|
@ -202,7 +204,8 @@ setState(() {
|
|||
}
|
||||
|
||||
Future<void> _getMeasures(String homework_id) async {
|
||||
final data = await ApiService.listSignFinishMeasures('cutroad',
|
||||
final data = await ApiService.listSignFinishMeasures(
|
||||
'cutroad',
|
||||
homework_id.length > 0 ? homework_id : widget.CUTROAD_ID,
|
||||
);
|
||||
setState(() {
|
||||
|
|
@ -213,7 +216,8 @@ setState(() {
|
|||
}
|
||||
|
||||
Future<void> _getSigns(String homework_id) async {
|
||||
final data = await ApiService.listSignFinished('cutroad',
|
||||
final data = await ApiService.listSignFinished(
|
||||
'cutroad',
|
||||
homework_id.length > 0 ? homework_id : widget.CUTROAD_ID,
|
||||
);
|
||||
setState(() {
|
||||
|
|
@ -279,7 +283,7 @@ setState(() {
|
|||
'所在单位负责人意见',
|
||||
'请输入意见',
|
||||
_contentController,
|
||||
isRequired: true
|
||||
isRequired: true,
|
||||
),
|
||||
Divider(),
|
||||
Column(
|
||||
|
|
@ -300,7 +304,7 @@ setState(() {
|
|||
),
|
||||
if (signImages.isNotEmpty) _signListWidget(),
|
||||
],
|
||||
)
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ class _CutroadZyfzDetailState extends State<CutroadZyfzDetail> {
|
|||
await NativeOrientation.setPortrait();
|
||||
if (path != null) {
|
||||
final now = DateFormat('yyyy-MM-dd HH:mm').format(DateTime.now());
|
||||
setState(() {
|
||||
setState(() {
|
||||
signImages.add(path);
|
||||
signTimes.add(now);
|
||||
});
|
||||
|
|
@ -143,7 +143,7 @@ setState(() {
|
|||
title: '作废原因',
|
||||
hintText: '请输入作废原因',
|
||||
cancelText: '取消',
|
||||
confirmText: '确定'
|
||||
confirmText: '确定',
|
||||
);
|
||||
if (reasonText.isEmpty) {
|
||||
ToastUtil.showNormal(context, '请填写作废原因');
|
||||
|
|
@ -170,29 +170,31 @@ setState(() {
|
|||
barrierDismissible: false,
|
||||
);
|
||||
if (confirmed) {
|
||||
LoadingDialogHelper.show();
|
||||
try {
|
||||
final result = await ApiService.saveSafeFunctionSure(
|
||||
'cutroad',
|
||||
formData,
|
||||
signImages,
|
||||
);
|
||||
LoadingDialogHelper.hide();
|
||||
if (result['result'] == 'success') {
|
||||
ToastUtil.showSuccess(context, '保存成功');
|
||||
Navigator.of(context).pop(true);
|
||||
}
|
||||
} catch (e) {
|
||||
LoadingDialogHelper.hide();
|
||||
ToastUtil.showNormal(context, '操作失败:$e');
|
||||
}
|
||||
|
||||
LoadingDialogHelper.show();
|
||||
try {
|
||||
final result = await ApiService.saveSafeFunctionSure(
|
||||
'cutroad',
|
||||
formData,
|
||||
signImages,
|
||||
);
|
||||
LoadingDialogHelper.hide();
|
||||
if (result['result'] == 'success') {
|
||||
ToastUtil.showSuccess(context, '保存成功');
|
||||
Navigator.of(context).pop(true);
|
||||
}
|
||||
} catch (e) {
|
||||
LoadingDialogHelper.hide();
|
||||
ToastUtil.showNormal(context, '操作失败:$e');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 初始化拉取数据
|
||||
Future<void> _getData() async {
|
||||
final data = await ApiService.getHomeworkFindById('cutroad', widget.CUTROAD_ID);
|
||||
final data = await ApiService.getHomeworkFindById(
|
||||
'cutroad',
|
||||
widget.CUTROAD_ID,
|
||||
);
|
||||
setState(() {
|
||||
pd = data['pd'];
|
||||
|
||||
|
|
@ -202,7 +204,8 @@ setState(() {
|
|||
}
|
||||
|
||||
Future<void> _getMeasures(String homework_id) async {
|
||||
final data = await ApiService.listSignFinishMeasures('cutroad',
|
||||
final data = await ApiService.listSignFinishMeasures(
|
||||
'cutroad',
|
||||
homework_id.length > 0 ? homework_id : widget.CUTROAD_ID,
|
||||
);
|
||||
setState(() {
|
||||
|
|
@ -213,7 +216,8 @@ setState(() {
|
|||
}
|
||||
|
||||
Future<void> _getSigns(String homework_id) async {
|
||||
final data = await ApiService.listSignFinished('cutroad',
|
||||
final data = await ApiService.listSignFinished(
|
||||
'cutroad',
|
||||
homework_id.length > 0 ? homework_id : widget.CUTROAD_ID,
|
||||
);
|
||||
setState(() {
|
||||
|
|
@ -278,7 +282,7 @@ setState(() {
|
|||
'作业负责人意见',
|
||||
'请输入意见',
|
||||
_contentController,
|
||||
isRequired: true
|
||||
isRequired: true,
|
||||
),
|
||||
Divider(),
|
||||
Column(
|
||||
|
|
@ -299,7 +303,7 @@ setState(() {
|
|||
),
|
||||
if (signImages.isNotEmpty) _signListWidget(),
|
||||
],
|
||||
)
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ import 'package:qhd_prevention/customWidget/custom_alert_dialog.dart';
|
|||
import 'package:qhd_prevention/customWidget/single_image_viewer.dart';
|
||||
import 'package:qhd_prevention/pages/mine/mine_sign_page.dart';
|
||||
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dl_work/CutroadFormBaseWork.dart';
|
||||
|
||||
/// 本地路径 + 线上路径模型
|
||||
class ImageData {
|
||||
String localPath;
|
||||
|
|
@ -22,6 +23,7 @@ class ImageData {
|
|||
|
||||
ImageData({required this.localPath, required this.serverPath});
|
||||
}
|
||||
|
||||
/// 断路示意图负责人意见
|
||||
class CutroadZyrDetail extends StatefulWidget {
|
||||
const CutroadZyrDetail({
|
||||
|
|
@ -45,6 +47,7 @@ class _CutroadZyrDetailState extends State<CutroadZyrDetail> {
|
|||
final TextEditingController _contentController = TextEditingController();
|
||||
|
||||
late List<ImageData> imgList = [];
|
||||
|
||||
/// 安全防护措施列表
|
||||
late List<Map<String, dynamic>> measuresList = [];
|
||||
late Map<String, dynamic> signs = {};
|
||||
|
|
@ -67,7 +70,7 @@ class _CutroadZyrDetailState extends State<CutroadZyrDetail> {
|
|||
await NativeOrientation.setPortrait();
|
||||
if (path != null) {
|
||||
final now = DateFormat('yyyy-MM-dd HH:mm').format(DateTime.now());
|
||||
setState(() {
|
||||
setState(() {
|
||||
signImages.add(path);
|
||||
signTimes.add(now);
|
||||
});
|
||||
|
|
@ -155,7 +158,7 @@ setState(() {
|
|||
title: '作废原因',
|
||||
hintText: '请输入作废原因',
|
||||
cancelText: '取消',
|
||||
confirmText: '确定'
|
||||
confirmText: '确定',
|
||||
);
|
||||
if (reasonText.isEmpty) {
|
||||
ToastUtil.showNormal(context, '请填写作废原因');
|
||||
|
|
@ -165,7 +168,7 @@ setState(() {
|
|||
final serverPathString = imgList
|
||||
.map((e) => e.serverPath)
|
||||
.where((s) => s.isNotEmpty)
|
||||
.map((s) => s) // 将 String? 转回 String
|
||||
.map((s) => s) // 将 String? 转回 String
|
||||
.join(',');
|
||||
// 存回 measures
|
||||
final Map<String, dynamic> formData = {};
|
||||
|
|
@ -173,7 +176,7 @@ setState(() {
|
|||
formData['WORK_CONTENT'] = _contentController.text.trim();
|
||||
formData['CONIMG_PATH'] = serverPathString;
|
||||
|
||||
formData['DESCR'] = FormUtils.hasValue(pd, 'DESCR') ?pd['DESCR']: '无';
|
||||
formData['DESCR'] = FormUtils.hasValue(pd, 'DESCR') ? pd['DESCR'] : '无';
|
||||
formData['CUTROAD_ID'] = widget.CUTROAD_ID;
|
||||
formData['SIGNTIME'] = signTimes.join(',');
|
||||
formData['USER_ID'] = SessionService.instance.loginUserId;
|
||||
|
|
@ -189,29 +192,31 @@ setState(() {
|
|||
barrierDismissible: false,
|
||||
);
|
||||
if (confirmed) {
|
||||
LoadingDialogHelper.show();
|
||||
try {
|
||||
final result = await ApiService.saveSafeFunctionSure(
|
||||
'cutroad',
|
||||
formData,
|
||||
signImages,
|
||||
);
|
||||
LoadingDialogHelper.hide();
|
||||
if (result['result'] == 'success') {
|
||||
ToastUtil.showSuccess(context, '保存成功');
|
||||
Navigator.of(context).pop(true);
|
||||
}
|
||||
} catch (e) {
|
||||
LoadingDialogHelper.hide();
|
||||
ToastUtil.showNormal(context, '操作失败:$e');
|
||||
}
|
||||
|
||||
LoadingDialogHelper.show();
|
||||
try {
|
||||
final result = await ApiService.saveSafeFunctionSure(
|
||||
'cutroad',
|
||||
formData,
|
||||
signImages,
|
||||
);
|
||||
LoadingDialogHelper.hide();
|
||||
if (result['result'] == 'success') {
|
||||
ToastUtil.showSuccess(context, '保存成功');
|
||||
Navigator.of(context).pop(true);
|
||||
}
|
||||
} catch (e) {
|
||||
LoadingDialogHelper.hide();
|
||||
ToastUtil.showNormal(context, '操作失败:$e');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 初始化拉取数据
|
||||
Future<void> _getData() async {
|
||||
final data = await ApiService.getHomeworkFindById('cutroad', widget.CUTROAD_ID);
|
||||
final data = await ApiService.getHomeworkFindById(
|
||||
'cutroad',
|
||||
widget.CUTROAD_ID,
|
||||
);
|
||||
setState(() {
|
||||
pd = data['pd'];
|
||||
|
||||
|
|
@ -221,7 +226,8 @@ setState(() {
|
|||
}
|
||||
|
||||
Future<void> _getMeasures(String homework_id) async {
|
||||
final data = await ApiService.listSignFinishMeasures('cutroad',
|
||||
final data = await ApiService.listSignFinishMeasures(
|
||||
'cutroad',
|
||||
homework_id.length > 0 ? homework_id : widget.CUTROAD_ID,
|
||||
);
|
||||
setState(() {
|
||||
|
|
@ -232,13 +238,15 @@ setState(() {
|
|||
}
|
||||
|
||||
Future<void> _getSigns(String homework_id) async {
|
||||
final data = await ApiService.listSignFinished('cutroad',
|
||||
final data = await ApiService.listSignFinished(
|
||||
'cutroad',
|
||||
homework_id.length > 0 ? homework_id : widget.CUTROAD_ID,
|
||||
);
|
||||
setState(() {
|
||||
signs = data['signs'] ?? {};
|
||||
});
|
||||
}
|
||||
|
||||
/// 拍照或选图后的回调
|
||||
Future<void> _onImageAdded(String localPath) async {
|
||||
// 上传到服务器
|
||||
|
|
@ -260,6 +268,7 @@ setState(() {
|
|||
imgList.remove(item);
|
||||
});
|
||||
}
|
||||
|
||||
/// 底部按钮
|
||||
Widget _bottomButtons() {
|
||||
return Row(
|
||||
|
|
@ -314,10 +323,10 @@ setState(() {
|
|||
Column(
|
||||
children: [
|
||||
ListItemFactory.createBuildMultilineInput(
|
||||
'断路地段示意图相关说明:',
|
||||
'请输入断路地段示意图相关说明',
|
||||
_contentController,
|
||||
isRequired: true
|
||||
'断路地段示意图相关说明:',
|
||||
'请输入断路地段示意图相关说明',
|
||||
_contentController,
|
||||
isRequired: true,
|
||||
),
|
||||
Divider(),
|
||||
RepairedPhotoSection(
|
||||
|
|
@ -330,7 +339,9 @@ setState(() {
|
|||
isRequired: true,
|
||||
onMediaAdded: _onImageAdded,
|
||||
onMediaRemoved: (path) {
|
||||
final item = imgList.firstWhere((e) => e.localPath == path);
|
||||
final item = imgList.firstWhere(
|
||||
(e) => e.localPath == path,
|
||||
);
|
||||
_onImageRemoved(item);
|
||||
},
|
||||
onAiIdentify: () {},
|
||||
|
|
@ -340,7 +351,10 @@ setState(() {
|
|||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
ListItemFactory.headerTitle('断路示意图负责人签字',isRequired: true),
|
||||
ListItemFactory.headerTitle(
|
||||
'断路示意图负责人签字',
|
||||
isRequired: true,
|
||||
),
|
||||
CustomButton(
|
||||
text: '新增手写签字',
|
||||
height: 36,
|
||||
|
|
@ -353,7 +367,7 @@ setState(() {
|
|||
),
|
||||
if (signImages.isNotEmpty) _signListWidget(),
|
||||
],
|
||||
)
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -24,12 +24,17 @@ class BreakgroundDetailFormWidget extends StatefulWidget {
|
|||
final TextEditingController? contentController; // 内容
|
||||
final TextEditingController? relatedController;
|
||||
final TextEditingController? riskController;
|
||||
// 新增
|
||||
/// 选择摄像头
|
||||
final VoidCallback? onChooseVideoManager;/// 承包商
|
||||
|
||||
// 新增
|
||||
/// 选择摄像头
|
||||
final VoidCallback? onChooseVideoManager;
|
||||
|
||||
/// 承包商
|
||||
final VoidCallback? onContractorHandle;
|
||||
|
||||
/// 作业区域
|
||||
final VoidCallback? onWorkAreaHandle;
|
||||
|
||||
/// 作业地点经纬度
|
||||
final VoidCallback? onWorkAreaLocationHandle;
|
||||
|
||||
|
|
@ -39,6 +44,7 @@ class BreakgroundDetailFormWidget extends StatefulWidget {
|
|||
required this.isEditable,
|
||||
required this.onChooseLevel,
|
||||
required this.signs,
|
||||
|
||||
/// 新增
|
||||
this.onChooseVideoManager,
|
||||
this.onContractorHandle,
|
||||
|
|
@ -66,212 +72,11 @@ class BreakgroundDetailFormWidget extends StatefulWidget {
|
|||
|
||||
class _BreakgroundDetailFormWidgetState
|
||||
extends State<BreakgroundDetailFormWidget> {
|
||||
Widget signItemWidget(
|
||||
String signKey,
|
||||
String nameKey,
|
||||
String name,
|
||||
BuildContext context,
|
||||
) {
|
||||
return _itemContainer(
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
// 标题行
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 5, horizontal: 10),
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(child: ListItemFactory.headerTitle(name)),
|
||||
if (FormUtils.hasValue(widget.pd, nameKey))
|
||||
Text(
|
||||
widget.pd[nameKey]?.toString() ?? '',
|
||||
style: const TextStyle(fontSize: 16),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
|
||||
if (FormUtils.hasValue(widget.signs, signKey))
|
||||
...((widget.signs[signKey] as List<dynamic>)
|
||||
.cast<Map<String, dynamic>>()
|
||||
.map((item) {
|
||||
// 解析 SIGN_PATH
|
||||
List<String> signPaths = [];
|
||||
final rawSP =
|
||||
FormUtils.hasValue(item, 'SIGN_PATH')
|
||||
? item['SIGN_PATH']
|
||||
: null;
|
||||
if (rawSP is String && rawSP.isNotEmpty) {
|
||||
signPaths = rawSP.split(',').map((s) => s.trim()).toList();
|
||||
} else if (rawSP is List) {
|
||||
signPaths = rawSP.cast<String>();
|
||||
}
|
||||
|
||||
// 解析 SIGN_TIME 保留空格
|
||||
List<String> signTimes = [];
|
||||
final rawST =
|
||||
FormUtils.hasValue(item, 'SIGN_TIME')
|
||||
? item['SIGN_TIME']
|
||||
: null;
|
||||
if (rawST is String && rawST.isNotEmpty) {
|
||||
signTimes = rawST.split(',');
|
||||
} else if (rawST is List) {
|
||||
signTimes = rawST.cast<String>();
|
||||
}
|
||||
|
||||
final pairCount = math.min(
|
||||
signPaths.length,
|
||||
signTimes.length,
|
||||
);
|
||||
|
||||
// 解析 IMG_PATH, 最多 2 张
|
||||
List<String> imgPaths = [];
|
||||
final rawIP =
|
||||
FormUtils.hasValue(item, 'IMG_PATH')
|
||||
? item['IMG_PATH']
|
||||
: null;
|
||||
if (rawIP is String && rawIP.isNotEmpty) {
|
||||
imgPaths =
|
||||
rawIP.split(',').map((s) => s.trim()).take(2).toList();
|
||||
} else if (rawIP is List) {
|
||||
imgPaths = rawIP.cast<String>().take(2).toList();
|
||||
}
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 8.0,
|
||||
horizontal: 10,
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
if (imgPaths.isNotEmpty) ...[
|
||||
Row(
|
||||
children:
|
||||
imgPaths.map((p) {
|
||||
final fullUrl = '${ApiService.baseImgPath}$p';
|
||||
return GestureDetector(
|
||||
onTap:
|
||||
() => presentOpaque(
|
||||
SingleImageViewer(imageUrl: fullUrl),
|
||||
context,
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
right: 8.0,
|
||||
),
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(2),
|
||||
child: Image.network(
|
||||
fullUrl,
|
||||
width: 50,
|
||||
height: 50,
|
||||
fit: BoxFit.fill,
|
||||
errorBuilder:
|
||||
(_, __, ___) => const Icon(
|
||||
Icons.broken_image,
|
||||
size: 40,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
],
|
||||
|
||||
// 签名及时间
|
||||
...List.generate(pairCount, (index) {
|
||||
final imgPath = signPaths[index];
|
||||
final timeLabel = signTimes[index];
|
||||
final fullUrl = '${ApiService.baseImgPath}$imgPath';
|
||||
const imageWidth = 200.0;
|
||||
const imageHeight = 100.0;
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 8.0),
|
||||
child: Column(
|
||||
children: [
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
GestureDetector(
|
||||
onTap:
|
||||
() => presentOpaque(
|
||||
SingleImageViewer(
|
||||
imageUrl: fullUrl,
|
||||
),
|
||||
context,
|
||||
),
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
child: Image.network(
|
||||
fullUrl,
|
||||
width: imageWidth,
|
||||
height: imageHeight,
|
||||
fit: BoxFit.fill,
|
||||
errorBuilder:
|
||||
(_, __, ___) => const Icon(
|
||||
Icons.broken_image,
|
||||
size: 60,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: SizedBox(
|
||||
height: imageHeight,
|
||||
child: Align(
|
||||
alignment: Alignment.bottomRight,
|
||||
child: Text(
|
||||
timeLabel,
|
||||
style: const TextStyle(
|
||||
fontSize: 14,
|
||||
color: Colors.black87,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
if (index < pairCount - 1)
|
||||
const Padding(
|
||||
padding: EdgeInsets.only(top: 8.0),
|
||||
child: Divider(height: 1),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}),
|
||||
],
|
||||
),
|
||||
);
|
||||
})
|
||||
.toList()),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _itemContainer(Widget child) {
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 5, vertical: 8),
|
||||
child: child,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (FormUtils.hasValue(widget.pd, 'LATITUDE')) {
|
||||
widget.pd['LATITUDE_LONGITUDE'] = '${widget.pd['LATITUDE']},${widget.pd['LONGITUDE']}'; //参数map
|
||||
widget.pd['LATITUDE_LONGITUDE'] =
|
||||
'${widget.pd['LATITUDE']},${widget.pd['LONGITUDE']}'; //参数map
|
||||
}
|
||||
final pd = widget.pd;
|
||||
|
||||
|
|
@ -292,15 +97,34 @@ class _BreakgroundDetailFormWidgetState
|
|||
),
|
||||
const Divider(),
|
||||
],
|
||||
if (
|
||||
FormUtils.hasValue(pd, 'APPLY_DEPARTMENT_NAME')) ...[
|
||||
ItemListWidget.singleLineTitleText(
|
||||
label: '申请部门:',
|
||||
isEditable: false,
|
||||
text: pd['APPLY_DEPARTMENT_NAME'] ?? '',
|
||||
),
|
||||
ItemListWidget.singleLineTitleText(
|
||||
label: '作业申请单位:',
|
||||
isEditable: false,
|
||||
text: pd['APPLY_DEPARTMENT_NAME'] ?? '',
|
||||
),
|
||||
const Divider(),
|
||||
ItemListWidget.singleLineTitleText(
|
||||
label: '申请人:',
|
||||
isEditable: false,
|
||||
text: pd['APPLY_USER_NAME'] ?? '',
|
||||
),
|
||||
if (FormUtils.hasValue(pd, 'CREATTIME') && !widget.isEditable) ...[
|
||||
const Divider(),
|
||||
ItemListWidget.singleLineTitleText(
|
||||
label: '作业申请时间:',
|
||||
isEditable: false,
|
||||
text: pd['CREATTIME'] ?? '',
|
||||
),
|
||||
],
|
||||
if (FormUtils.hasValue(pd, 'CONFIRM_DEPARTMENT_NAME')) ...[
|
||||
const Divider(),
|
||||
ItemListWidget.singleLineTitleText(
|
||||
label: '作业单位:',
|
||||
isEditable: false,
|
||||
text: pd['CONFIRM_DEPARTMENT_NAME'] ?? '',
|
||||
),
|
||||
],
|
||||
const Divider(),
|
||||
|
||||
ItemListWidget.singleLineTitleText(
|
||||
label: '作业地点:',
|
||||
|
|
@ -317,42 +141,29 @@ class _BreakgroundDetailFormWidgetState
|
|||
hintText: '请输入作业内容',
|
||||
text: pd['JOB_CONTENT'] ?? '',
|
||||
),
|
||||
if (FormUtils.hasValue(pd, 'GUARDIAN_USER_NAME') &&
|
||||
!widget.isEditable) ...[
|
||||
const Divider(),
|
||||
// ItemListWidget.OneRowImageTitle(label: '作业负责人', imgPath: imgPath)
|
||||
SignRowImageTitle(
|
||||
label: '监护人:',
|
||||
signKey: 'GUARDIAN',
|
||||
signs: widget.signs,
|
||||
text: pd['GUARDIAN_USER_NAME'] ?? '',
|
||||
),
|
||||
],
|
||||
if (FormUtils.hasValue(pd, 'CONFIRM_USER_NAME') &&
|
||||
!widget.isEditable) ...[
|
||||
const Divider(),
|
||||
SignRowImageTitle(
|
||||
label: '作业负责人:',
|
||||
signKey: 'CONFIRM',
|
||||
signs: widget.signs,
|
||||
text: pd['CONFIRM_USER_NAME'] ?? '',
|
||||
),
|
||||
],
|
||||
|
||||
const Divider(),
|
||||
if (FormUtils.hasValue(pd, 'WORK_CONTENT')) ...[
|
||||
ItemListWidget.singleLineTitleText(
|
||||
label: '作业内容、范围、方式:',
|
||||
isEditable: false,
|
||||
text: pd['WORK_CONTENT'] ?? '',
|
||||
),
|
||||
const Divider(),
|
||||
],
|
||||
if (FormUtils.hasValue(pd, 'CONTENT_IMG_PATH')) ...[
|
||||
ItemListWidget.singleLineTitleText(
|
||||
label: '作业内容、范围、方式简图:',
|
||||
isEditable: false,
|
||||
text: '',
|
||||
),
|
||||
SizedBox(height: 5,),
|
||||
Padding(padding: EdgeInsets.symmetric(horizontal: 12), child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.end, // 对齐到底部
|
||||
children: List.generate(pd['CONTENT_IMG_PATH'].length, (index) {
|
||||
final fullUrl =
|
||||
ApiService.baseImgPath + pd['CONTENT_IMG_PATH'][index];
|
||||
return Container(
|
||||
margin: const EdgeInsets.only(right: 20), // 右侧 20px 间隔
|
||||
width: 60,
|
||||
height: 60,
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
presentOpaque(SingleImageViewer(imageUrl: fullUrl), context);
|
||||
},
|
||||
child: Image.network(fullUrl, fit: BoxFit.fill),
|
||||
),
|
||||
);
|
||||
}),
|
||||
),),
|
||||
const Divider(),
|
||||
],
|
||||
ItemListWidget.twoRowButtonTitleText(
|
||||
label: '关联其他特殊作业及安全作业票编号',
|
||||
isRequired: false,
|
||||
|
|
@ -378,7 +189,49 @@ class _BreakgroundDetailFormWidgetState
|
|||
controller: widget.relatedController,
|
||||
text: pd['SPECIAL_WORK'] ?? '',
|
||||
),
|
||||
|
||||
const Divider(),
|
||||
if (FormUtils.hasValue(pd, 'WORK_CONTENT')) ...[
|
||||
ItemListWidget.singleLineTitleText(
|
||||
label: '作业内容、范围、方式:',
|
||||
isEditable: false,
|
||||
text: pd['WORK_CONTENT'] ?? '',
|
||||
),
|
||||
const Divider(),
|
||||
],
|
||||
if (FormUtils.hasValue(pd, 'CONTENT_IMG_PATH')) ...[
|
||||
ItemListWidget.singleLineTitleText(
|
||||
label: '作业内容、范围、方式简图:',
|
||||
isEditable: false,
|
||||
text: '',
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 12),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.end, // 对齐到底部
|
||||
children: List.generate(pd['CONTENT_IMG_PATH'].length, (index) {
|
||||
final fullUrl =
|
||||
ApiService.baseImgPath + pd['CONTENT_IMG_PATH'][index];
|
||||
return Container(
|
||||
margin: const EdgeInsets.only(right: 20), // 右侧 20px 间隔
|
||||
width: 60,
|
||||
height: 60,
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
presentOpaque(
|
||||
SingleImageViewer(imageUrl: fullUrl),
|
||||
context,
|
||||
);
|
||||
},
|
||||
child: Image.network(fullUrl, fit: BoxFit.fill),
|
||||
),
|
||||
);
|
||||
}),
|
||||
),
|
||||
),
|
||||
const Divider(),
|
||||
],
|
||||
ItemListWidget.twoRowButtonTitleText(
|
||||
label: '风险辨识结果',
|
||||
isEditable: widget.isEditable,
|
||||
|
|
@ -403,73 +256,69 @@ class _BreakgroundDetailFormWidgetState
|
|||
controller: widget.riskController,
|
||||
text: pd['RISK_IDENTIFICATION'] ?? '',
|
||||
),
|
||||
if (FormUtils.hasValue(pd, 'WORK_START_DATE')) ...[
|
||||
const Divider(),
|
||||
ItemListWidget.selectableLineTitleTextRightButton(
|
||||
label: '作业实施时间:',
|
||||
isEditable: widget.isEditable,
|
||||
text:
|
||||
FormUtils.hasValue(pd, 'WORK_END_DATE')
|
||||
? '${pd['WORK_START_DATE'] ?? ''}\n-${pd['WORK_END_DATE'] ?? ''}'
|
||||
: pd['WORK_START_DATE'] ?? '',
|
||||
),
|
||||
] else ...[
|
||||
const Divider(),
|
||||
ItemListWidget.selectableLineTitleTextRightButton(
|
||||
label: '预计作业开始时间:',
|
||||
isEditable: widget.isEditable,
|
||||
onTap: () async {
|
||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||
mode: BottomPickerMode.dateTimeWithSeconds,
|
||||
context,
|
||||
allowFuture: true,
|
||||
);
|
||||
if (picked != null) {
|
||||
setState(() {
|
||||
pd['WORK_EXPECTED_START_TIME'] = DateFormat(
|
||||
'yyyy-MM-dd HH:mm:ss',
|
||||
).format(picked);
|
||||
|
||||
/// 开始时间必须早于结束时间
|
||||
if (FormUtils.hasValue(pd, 'WORK_EXPECTED_END_TIME') &&
|
||||
!isBeforeStr(
|
||||
pd['WORK_EXPECTED_START_TIME'],
|
||||
pd['WORK_EXPECTED_END_TIME'],
|
||||
)) {
|
||||
pd['WORK_EXPECTED_END_TIME'] = '';
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
text: pd['WORK_EXPECTED_START_TIME'] ?? '',
|
||||
),
|
||||
const Divider(),
|
||||
ItemListWidget.selectableLineTitleTextRightButton(
|
||||
label: '预计作业结束时间:',
|
||||
isEditable: widget.isEditable,
|
||||
onTap: () async {
|
||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||
context,
|
||||
minTimeStr: pd['WORK_EXPECTED_START_TIME'] ?? '',
|
||||
allowFuture: true,
|
||||
);
|
||||
if (picked != null) {
|
||||
setState(() {
|
||||
pd['WORK_EXPECTED_END_TIME'] = DateFormat(
|
||||
'yyyy-MM-dd HH:mm:ss',
|
||||
).format(picked);
|
||||
});
|
||||
}
|
||||
},
|
||||
text: pd['WORK_EXPECTED_END_TIME'] ?? '',
|
||||
),
|
||||
],
|
||||
const Divider(),
|
||||
|
||||
ItemListWidget.selectableLineTitleTextRightButton(
|
||||
label: '作业视频监控:',
|
||||
isClean: widget.isEditable,
|
||||
cleanText: '清除监控',
|
||||
onTapClean: () {
|
||||
setState(() {
|
||||
pd['VIDEONAME'] = '';
|
||||
pd['VIDEOMANAGER_ID'] = '';
|
||||
});
|
||||
},
|
||||
isRequired: false,
|
||||
isEditable: widget.isEditable,
|
||||
onTap: widget.onChooseVideoManager ?? () {},
|
||||
text: pd['VIDEONAME'] ?? '',
|
||||
),
|
||||
const Divider(),
|
||||
ItemListWidget.selectableLineTitleTextRightButton(
|
||||
label: '预计作业开始时间:',
|
||||
isEditable: widget.isEditable,
|
||||
onTap: () async {
|
||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||
mode: BottomPickerMode.dateTimeWithSeconds,
|
||||
context,
|
||||
allowFuture: true,
|
||||
);
|
||||
if (picked != null) {
|
||||
setState(() {
|
||||
pd['WORK_EXPECTED_START_TIME'] = DateFormat(
|
||||
'yyyy-MM-dd HH:mm:ss',
|
||||
).format(picked);
|
||||
|
||||
/// 开始时间必须早于结束时间
|
||||
if (FormUtils.hasValue(pd, 'WORK_EXPECTED_END_TIME') &&
|
||||
!isBeforeStr(
|
||||
pd['WORK_EXPECTED_START_TIME'],
|
||||
pd['WORK_EXPECTED_END_TIME'],
|
||||
)) {
|
||||
pd['WORK_EXPECTED_END_TIME'] = '';
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
text: pd['WORK_EXPECTED_START_TIME'] ?? '',
|
||||
),
|
||||
const Divider(),
|
||||
ItemListWidget.selectableLineTitleTextRightButton(
|
||||
label: '预计作业结束时间:',
|
||||
isEditable: widget.isEditable,
|
||||
onTap: () async {
|
||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||
context,
|
||||
minTimeStr: pd['WORK_EXPECTED_START_TIME'] ?? '',
|
||||
allowFuture: true,
|
||||
);
|
||||
if (picked != null) {
|
||||
setState(() {
|
||||
pd['WORK_EXPECTED_END_TIME'] = DateFormat(
|
||||
'yyyy-MM-dd HH:mm:ss',
|
||||
).format(picked);
|
||||
});
|
||||
}
|
||||
},
|
||||
text: pd['WORK_EXPECTED_END_TIME'] ?? '',
|
||||
),
|
||||
const Divider(),
|
||||
ListItemFactory.createYesNoSection(
|
||||
verticalPadding: 0,
|
||||
horizontalPadding: 2,
|
||||
|
|
@ -511,19 +360,40 @@ class _BreakgroundDetailFormWidgetState
|
|||
isInput: false,
|
||||
isEditable: widget.isEditable,
|
||||
buttonText: '定位',
|
||||
onTap: widget.onWorkAreaLocationHandle ?? (){},
|
||||
onTap: widget.onWorkAreaLocationHandle ?? () {},
|
||||
hintText: '',
|
||||
text: pd['LATITUDE_LONGITUDE'] ?? (widget.isEditable ? '' : '无'),
|
||||
),
|
||||
// 作业人签字
|
||||
if (FormUtils.hasValue(widget.signs, 'WORK_USER'))
|
||||
Column(
|
||||
children: [
|
||||
Container(height: 10,width: double.maxFinite,color: h_backGroundColor(),),
|
||||
signItemWidget('WORK_USER', 'WORK_USER_USER_NAME', '作业人', context),
|
||||
],
|
||||
)
|
||||
const Divider(),
|
||||
|
||||
ItemListWidget.selectableLineTitleTextRightButton(
|
||||
label: '作业视频监控:',
|
||||
isClean: widget.isEditable,
|
||||
cleanText: '清除监控',
|
||||
onTapClean: () {
|
||||
setState(() {
|
||||
pd['VIDEONAME'] = '';
|
||||
pd['VIDEOMANAGER_ID'] = '';
|
||||
});
|
||||
},
|
||||
isRequired: false,
|
||||
isEditable: widget.isEditable,
|
||||
onTap: widget.onChooseVideoManager ?? () {},
|
||||
text: pd['VIDEONAME'] ?? '',
|
||||
),
|
||||
|
||||
if (FormUtils.hasValue(widget.signs, 'WORK_USER')) ...[
|
||||
const Divider(),
|
||||
ConfirmWithSignWidget(
|
||||
signs: widget.signs,
|
||||
pd: pd,
|
||||
baseImgPath: ApiService.baseImgPath,
|
||||
sectionKey: 'WORK_USER',
|
||||
nameKey: 'WORK_USER_USER_NAME',
|
||||
headerTitle: '作业人签字',
|
||||
roleTitle: '',
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
);
|
||||
|
|
|
|||
|
|
@ -51,202 +51,6 @@ class SpecialWorkFormBaseWork extends StatelessWidget {
|
|||
);
|
||||
}
|
||||
|
||||
Widget signItemWidget(
|
||||
String signKey,
|
||||
String nameKey,
|
||||
String name,
|
||||
BuildContext context,
|
||||
) {
|
||||
return _itemContainer(
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
// 标题行
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 5, horizontal: 10),
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
name,
|
||||
style: TextStyle(fontSize: 13, fontWeight: FontWeight.bold),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 10),
|
||||
if (FormUtils.hasValue(pd, nameKey))
|
||||
Text(
|
||||
pd[nameKey]?.toString() ?? '',
|
||||
style: const TextStyle(fontSize: 13),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
|
||||
if (FormUtils.hasValue(signs, signKey))
|
||||
...((signs[signKey] as List<dynamic>)
|
||||
.cast<Map<String, dynamic>>()
|
||||
.map((item) {
|
||||
// 解析 SIGN_PATH
|
||||
List<String> signPaths = [];
|
||||
final rawSP =
|
||||
FormUtils.hasValue(item, 'SIGN_PATH')
|
||||
? item['SIGN_PATH']
|
||||
: null;
|
||||
if (rawSP is String && rawSP.isNotEmpty) {
|
||||
signPaths = rawSP.split(',').map((s) => s.trim()).toList();
|
||||
} else if (rawSP is List) {
|
||||
signPaths = rawSP.cast<String>();
|
||||
}
|
||||
|
||||
// 解析 SIGN_TIME 保留空格
|
||||
List<String> signTimes = [];
|
||||
final rawST =
|
||||
FormUtils.hasValue(item, 'SIGN_TIME')
|
||||
? item['SIGN_TIME']
|
||||
: null;
|
||||
if (rawST is String && rawST.isNotEmpty) {
|
||||
signTimes = rawST.split(',');
|
||||
} else if (rawST is List) {
|
||||
signTimes = rawST.cast<String>();
|
||||
}
|
||||
|
||||
final pairCount = math.min(
|
||||
signPaths.length,
|
||||
signTimes.length,
|
||||
);
|
||||
|
||||
// 解析 IMG_PATH, 最多 2 张
|
||||
List<String> imgPaths = [];
|
||||
final rawIP =
|
||||
FormUtils.hasValue(item, 'IMG_PATH')
|
||||
? item['IMG_PATH']
|
||||
: null;
|
||||
if (rawIP is String && rawIP.isNotEmpty) {
|
||||
imgPaths =
|
||||
rawIP.split(',').map((s) => s.trim()).take(2).toList();
|
||||
} else if (rawIP is List) {
|
||||
imgPaths = rawIP.cast<String>().take(2).toList();
|
||||
}
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 8.0,
|
||||
horizontal: 10,
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
if (imgPaths.isNotEmpty) ...[
|
||||
Row(
|
||||
children:
|
||||
imgPaths.map((p) {
|
||||
final fullUrl = '$baseImgPath$p';
|
||||
return GestureDetector(
|
||||
onTap:
|
||||
() => presentOpaque(
|
||||
SingleImageViewer(imageUrl: fullUrl),
|
||||
context,
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
right: 8.0,
|
||||
),
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(2),
|
||||
child: Image.network(
|
||||
fullUrl,
|
||||
width: 50,
|
||||
height: 50,
|
||||
fit: BoxFit.fill,
|
||||
errorBuilder:
|
||||
(_, __, ___) => const Icon(
|
||||
Icons.broken_image,
|
||||
size: 40,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
],
|
||||
|
||||
// 签名及时间
|
||||
...List.generate(pairCount, (index) {
|
||||
final imgPath = signPaths[index];
|
||||
final timeLabel = signTimes[index];
|
||||
final fullUrl = '$baseImgPath$imgPath';
|
||||
const imageWidth = 200.0;
|
||||
const imageHeight = 100.0;
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 8.0),
|
||||
child: Column(
|
||||
children: [
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
GestureDetector(
|
||||
onTap:
|
||||
() => presentOpaque(
|
||||
SingleImageViewer(
|
||||
imageUrl: fullUrl,
|
||||
),
|
||||
context,
|
||||
),
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
child: Image.network(
|
||||
fullUrl,
|
||||
width: imageWidth,
|
||||
height: imageHeight,
|
||||
fit: BoxFit.fill,
|
||||
errorBuilder:
|
||||
(_, __, ___) => const Icon(
|
||||
Icons.broken_image,
|
||||
size: 60,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: SizedBox(
|
||||
height: imageHeight,
|
||||
child: Align(
|
||||
alignment: Alignment.bottomRight,
|
||||
child: Text(
|
||||
timeLabel,
|
||||
style: const TextStyle(
|
||||
fontSize: 14,
|
||||
color: Colors.black87,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
if (index < pairCount - 1)
|
||||
const Padding(
|
||||
padding: EdgeInsets.only(top: 8.0),
|
||||
child: Divider(height: 1),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}),
|
||||
],
|
||||
),
|
||||
);
|
||||
})
|
||||
.toList()),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
|
@ -258,8 +62,9 @@ class SpecialWorkFormBaseWork extends StatelessWidget {
|
|||
BreakgroundDetailFormWidget(
|
||||
pd: pd,
|
||||
isEditable: isEditable,
|
||||
signs: {},
|
||||
signs: signs,
|
||||
onChooseLevel: onChooseLevel,
|
||||
|
||||
),
|
||||
|
||||
// 安全防护措施
|
||||
|
|
@ -293,175 +98,87 @@ class SpecialWorkFormBaseWork extends StatelessWidget {
|
|||
],
|
||||
),
|
||||
),
|
||||
// 作业人签字
|
||||
if (FormUtils.hasValue(signs, 'WORK_USER'))
|
||||
signItemWidget('WORK_USER', 'WORK_USER_USER_NAME', '作业人', context),
|
||||
|
||||
// 各环节签字及意见
|
||||
if (FormUtils.hasValue(signs, 'GUARDIAN'))
|
||||
signItemWidget('GUARDIAN', 'GUARDIAN_USER_NAME', '监护人', context),
|
||||
|
||||
ConfirmWithSignWidget(
|
||||
signs: signs,
|
||||
pd: pd,
|
||||
baseImgPath: baseImgPath,
|
||||
sectionKey: 'GUARDIAN',
|
||||
nameKey: 'GUARDIAN_USER_NAME',
|
||||
headerTitle: '监护人签字',
|
||||
roleTitle: '监护人',
|
||||
),
|
||||
if (FormUtils.hasValue(signs, 'CONFESS'))
|
||||
signItemWidget('CONFESS', 'CONFESS_USER_NAME', '安全交底人', context),
|
||||
|
||||
ConfirmWithSignWidget(
|
||||
signs: signs,
|
||||
pd: pd,
|
||||
baseImgPath: baseImgPath,
|
||||
sectionKey: 'CONFESS',
|
||||
nameKey: 'CONFESS_USER_NAME',
|
||||
headerTitle: '安全交底人',
|
||||
roleTitle: '安全交底人',
|
||||
),
|
||||
if (FormUtils.hasValue(signs, 'ACCEPT_CONFESS'))
|
||||
signItemWidget(
|
||||
'ACCEPT_CONFESS',
|
||||
'ACCEPT_CONFESS_USER_NAME',
|
||||
'接受交底人',
|
||||
context,
|
||||
ConfirmWithSignWidget(
|
||||
signs: signs,
|
||||
pd: pd,
|
||||
baseImgPath: baseImgPath,
|
||||
sectionKey: 'ACCEPT_CONFESS',
|
||||
nameKey: 'ACCEPT_CONFESS_USER_NAME',
|
||||
headerTitle: '接受交底人',
|
||||
roleTitle: '',
|
||||
),
|
||||
if (FormUtils.hasValue(signs, 'CONFIRM'))
|
||||
ConfirmWithSignWidget(
|
||||
signs: signs,
|
||||
pd: pd,
|
||||
baseImgPath: baseImgPath,
|
||||
sectionKey: 'CONFIRM',
|
||||
nameKey: 'CONFIRM_USER_NAME',
|
||||
headerTitle: '作业负责人意见',
|
||||
roleTitle: '作业负责人',
|
||||
),
|
||||
if (FormUtils.hasValue(signs, 'LEADER'))
|
||||
ConfirmWithSignWidget(
|
||||
signs: signs,
|
||||
pd: pd,
|
||||
baseImgPath: baseImgPath,
|
||||
sectionKey: 'LEADER',
|
||||
nameKey: 'LEADER_USER_NAME',
|
||||
headerTitle: '所在单位负责人意见',
|
||||
roleTitle: '所在单位负责人',
|
||||
),
|
||||
if (FormUtils.hasValue(signs, 'SAFETY'))
|
||||
ConfirmWithSignWidget(
|
||||
signs: signs,
|
||||
pd: pd,
|
||||
baseImgPath: baseImgPath,
|
||||
sectionKey: 'SAFETY',
|
||||
nameKey: 'SAFETY_USER_NAME',
|
||||
headerTitle: '有关水、电、汽、工艺、设备、消防、安全等部门意见',
|
||||
roleTitle: '',
|
||||
),
|
||||
if (FormUtils.hasValue(signs, 'APPROVE'))
|
||||
ConfirmWithSignWidget(
|
||||
signs: signs,
|
||||
pd: pd,
|
||||
baseImgPath: baseImgPath,
|
||||
sectionKey: 'APPROVE',
|
||||
nameKey: 'APPROVE_USER_NAME',
|
||||
headerTitle: '审批部门负责人意见',
|
||||
roleTitle: '审批部门负责人',
|
||||
),
|
||||
if (FormUtils.hasValue(signs, 'ACCEPT'))
|
||||
ConfirmWithSignWidget(
|
||||
signs: signs,
|
||||
pd: pd,
|
||||
baseImgPath: baseImgPath,
|
||||
sectionKey: 'ACCEPT',
|
||||
nameKey: 'ACCEPT_USER_NAME',
|
||||
headerTitle: '验收部门负责人意见',
|
||||
roleTitle: '验收部门负责人',
|
||||
),
|
||||
|
||||
// 作业负责人意见
|
||||
if (FormUtils.hasValue(signs, 'CONFIRM')) ...[
|
||||
Column(
|
||||
children: [
|
||||
_itemContainer(
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 8),
|
||||
child: ListItemFactory.headerTitle('作业负责人意见'),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Text(signs['CONFIRM'][0]['DESCR'] ?? ''),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Divider(height: 1),
|
||||
signItemWidget('CONFIRM', 'CONFIRM_USER_NAME', '作业负责人', context),
|
||||
],
|
||||
),
|
||||
],
|
||||
|
||||
// 所在单位负责人意见
|
||||
if (FormUtils.hasValue(signs, 'LEADER')) ...[
|
||||
Column(
|
||||
children: [
|
||||
_itemContainer(
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 8),
|
||||
child: ListItemFactory.headerTitle('所在单位意见'),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Text(signs['LEADER'][0]['DESCR'] ?? ''),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Divider(height: 1),
|
||||
signItemWidget('LEADER', 'LEADER_USER_NAME', '所在单位负责人', context),
|
||||
],
|
||||
),
|
||||
],
|
||||
|
||||
// 安全管理部门负责人意见
|
||||
if (FormUtils.hasValue(signs, 'SAFETY')) ...[
|
||||
Column(
|
||||
children: [
|
||||
_itemContainer(
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 8),
|
||||
child: Text(
|
||||
'有关水、电、汽、工艺、设备、消防、安全等部门意见',
|
||||
maxLines: 5,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: const TextStyle(
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Text(signs['SAFETY'][0]['DESCR'] ?? ''),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Divider(height: 1),
|
||||
signItemWidget(
|
||||
'SAFETY',
|
||||
'SAFETY_USER_NAME',
|
||||
'有关水、电、汽、工艺、设备、消防、安全等部门负责人',
|
||||
context,
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
|
||||
// 审批人意见
|
||||
if (FormUtils.hasValue(signs, 'APPROVE')) ...[
|
||||
Column(
|
||||
children: [
|
||||
_itemContainer(
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 8),
|
||||
child: ListItemFactory.headerTitle('审批人意见'),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Text(signs['APPROVE'][0]['DESCR'] ?? ''),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Divider(height: 1),
|
||||
signItemWidget('APPROVE', 'APPROVE_USER_NAME', '审批负责人', context),
|
||||
],
|
||||
),
|
||||
],
|
||||
|
||||
// // 作业开始负责人签字
|
||||
// if (FormUtils.hasValue(signs, 'WORK_START'))
|
||||
// signItemWidget(
|
||||
// 'WORK_START',
|
||||
// 'WORK_START_USER_NAME',
|
||||
// '作业开始负责人',
|
||||
// context,
|
||||
// ),
|
||||
//
|
||||
// // 作业结束负责人签字
|
||||
// if (FormUtils.hasValue(signs, 'WORK_END'))
|
||||
// signItemWidget('WORK_END', 'WORK_END_USER_NAME', '作业结束负责人', context),
|
||||
|
||||
// 完工验收意见和签字
|
||||
if (FormUtils.hasValue(signs, 'ACCEPT')) ...[
|
||||
Column(
|
||||
children: [
|
||||
_itemContainer(
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 8),
|
||||
child: ListItemFactory.headerTitle('完工验收意见'),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Text(signs['ACCEPT'][0]['DESCR'] ?? ''),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Divider(height: 1),
|
||||
signItemWidget('ACCEPT', 'ACCEPT_USER_NAME', '验收部门负责人', context),
|
||||
],
|
||||
),
|
||||
],
|
||||
],
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -275,7 +275,7 @@ class _BreakgroundSafeFuncSureState extends State<BreakgroundSafeFuncSure> {
|
|||
Future<void> _getSigns(String homework_id) async {
|
||||
final data = await ApiService.listSignFinished(
|
||||
'breakground',
|
||||
homework_id.length > 0 ? homework_id : widget.BREAKGROUND_ID,
|
||||
homework_id.length > 0 ? homework_id : '',
|
||||
);
|
||||
setState(() {
|
||||
signs = data['signs'] ?? {};
|
||||
|
|
|
|||
|
|
@ -239,7 +239,7 @@ class _BreakgroundAqjdDetailState extends State<BreakgroundAqjdDetail> {
|
|||
Future<void> _getMeasures(String homework_id) async {
|
||||
final data = await ApiService.listSignFinishMeasures(
|
||||
'breakground',
|
||||
homework_id.length > 0 ? homework_id : widget.BREAKGROUND_ID,
|
||||
homework_id.length > 0 ? homework_id : '',
|
||||
);
|
||||
setState(() {
|
||||
measuresList = List<Map<String, dynamic>>.from(
|
||||
|
|
@ -251,7 +251,7 @@ class _BreakgroundAqjdDetailState extends State<BreakgroundAqjdDetail> {
|
|||
Future<void> _getSigns(String homework_id) async {
|
||||
final data = await ApiService.listSignFinished(
|
||||
'breakground',
|
||||
homework_id.length > 0 ? homework_id : widget.BREAKGROUND_ID,
|
||||
homework_id.length > 0 ? homework_id : '',
|
||||
);
|
||||
setState(() {
|
||||
signs = data['signs'] ?? {};
|
||||
|
|
|
|||
|
|
@ -58,7 +58,6 @@ class _BreakgroundListPageState extends State<BreakgroundListPage> {
|
|||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_fetchSteps();
|
||||
_fetchData();
|
||||
_scrollController.addListener(_onScroll);
|
||||
}
|
||||
|
|
@ -137,12 +136,14 @@ class _BreakgroundListPageState extends State<BreakgroundListPage> {
|
|||
}
|
||||
|
||||
/// 申请
|
||||
void _handleApply() {
|
||||
void _handleApply() async{
|
||||
// 处理申请按钮点击逻辑
|
||||
pushPage(
|
||||
await pushPage(
|
||||
BreakgroundApplyDetail(BREAKGROUND_ID: '', flow: widget.flow),
|
||||
context,
|
||||
);
|
||||
_fetchData();
|
||||
LoadingDialogHelper.hide();
|
||||
}
|
||||
|
||||
/// 打开流程图
|
||||
|
|
@ -314,9 +315,10 @@ class _BreakgroundListPageState extends State<BreakgroundListPage> {
|
|||
default:
|
||||
break;
|
||||
}
|
||||
LoadingDialogHelper.show();
|
||||
_fetchSteps();
|
||||
_fetchData();
|
||||
|
||||
|
||||
await _fetchData();
|
||||
LoadingDialogHelper.hide();
|
||||
}
|
||||
|
||||
Widget _buildFlowStepItem({
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@ import 'package:intl/intl.dart';
|
|||
import 'package:qhd_prevention/pages/home/tap/workArea_picker.dart';
|
||||
import 'package:qhd_prevention/customWidget/BaiDuMap/Map_page.dart';
|
||||
|
||||
|
||||
enum EditUserType {
|
||||
WORK_USER('作业人单位', '作业人', true),
|
||||
GUARDIAN('监护人单位', '监护人', true),
|
||||
|
|
@ -72,15 +71,18 @@ class _BreakgroundApplyDetailState extends State<BreakgroundApplyDetail> {
|
|||
final TextEditingController _contentController = TextEditingController();
|
||||
final TextEditingController _relatedController = TextEditingController();
|
||||
final TextEditingController _riskController = TextEditingController();
|
||||
|
||||
/// ------------------- 新增 -------------------
|
||||
/// 视频监控摄像
|
||||
late List<dynamic> videoMonitoringList = [];
|
||||
|
||||
/// 承包商列表
|
||||
late List<dynamic> unitAllList = [];
|
||||
|
||||
/// 作业区域列表
|
||||
late List<Map<String, dynamic>> workAreaList = [];
|
||||
/// --------------------------------------
|
||||
|
||||
/// --------------------------------------
|
||||
|
||||
// 存储各单位的人员列表
|
||||
final Map<EditUserType, List<Map<String, dynamic>>> _personCache = {};
|
||||
|
|
@ -91,7 +93,6 @@ class _BreakgroundApplyDetailState extends State<BreakgroundApplyDetail> {
|
|||
if (widget.BREAKGROUND_ID.length > 0) {
|
||||
msg = 'edit';
|
||||
_getData();
|
||||
|
||||
} else {
|
||||
isEditable = true;
|
||||
pd['APPLY_DEPARTMENT_ID'] = SessionService.instance.deptId;
|
||||
|
|
@ -139,7 +140,7 @@ class _BreakgroundApplyDetailState extends State<BreakgroundApplyDetail> {
|
|||
void set_pd_USER_ID(EditUserType type, String id) {
|
||||
if (type == EditUserType.WORK_USER) {
|
||||
pd['${type.name}_ID'] = id;
|
||||
}else{
|
||||
} else {
|
||||
pd['${type.name}_USER_ID'] = id;
|
||||
}
|
||||
}
|
||||
|
|
@ -159,7 +160,7 @@ class _BreakgroundApplyDetailState extends State<BreakgroundApplyDetail> {
|
|||
String get_pd_USER_ID(EditUserType type) {
|
||||
if (type == EditUserType.WORK_USER) {
|
||||
return pd['${type.name}_ID'] ?? '';
|
||||
}else{
|
||||
} else {
|
||||
return pd['${type.name}_USER_ID'] ?? '';
|
||||
}
|
||||
}
|
||||
|
|
@ -167,15 +168,16 @@ class _BreakgroundApplyDetailState extends State<BreakgroundApplyDetail> {
|
|||
String get_pd_USER_Name(EditUserType type) {
|
||||
return pd['${type.name}_USER_NAME'] ?? '';
|
||||
}
|
||||
|
||||
/// ---------------------------- 新增 --------------------------------
|
||||
/// 视频监控摄像头
|
||||
Future<void> _chooseVideoManager() async {
|
||||
final choice = await BottomPicker.show<String>(
|
||||
context,
|
||||
items:
|
||||
videoMonitoringList
|
||||
.map((item) => item['VIDEONAME'] as String)
|
||||
.toList(),
|
||||
videoMonitoringList
|
||||
.map((item) => item['VIDEONAME'] as String)
|
||||
.toList(),
|
||||
itemBuilder: (item) => Text(item, textAlign: TextAlign.center),
|
||||
initialIndex: 0,
|
||||
);
|
||||
|
|
@ -184,7 +186,7 @@ class _BreakgroundApplyDetailState extends State<BreakgroundApplyDetail> {
|
|||
pd['VIDEONAME'] = choice;
|
||||
|
||||
Map<String, dynamic> result = videoMonitoringList.firstWhere(
|
||||
(item) => item['VIDEONAME'] == choice,
|
||||
(item) => item['VIDEONAME'] == choice,
|
||||
orElse: () => {}, // 避免找不到时报错
|
||||
);
|
||||
if (FormUtils.hasValue(result, 'VIDEOMANAGER_ID')) {
|
||||
|
|
@ -194,6 +196,7 @@ class _BreakgroundApplyDetailState extends State<BreakgroundApplyDetail> {
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// 选择承包商
|
||||
Future<void> _chooseUnitManager() async {
|
||||
final choice = await BottomPicker.show<String>(
|
||||
|
|
@ -207,7 +210,7 @@ class _BreakgroundApplyDetailState extends State<BreakgroundApplyDetail> {
|
|||
pd['UNITS_NAME'] = choice;
|
||||
|
||||
Map<String, dynamic> result = unitAllList.firstWhere(
|
||||
(item) => item['UNITS_NAME'] == choice,
|
||||
(item) => item['UNITS_NAME'] == choice,
|
||||
orElse: () => {}, // 避免找不到时报错
|
||||
);
|
||||
if (FormUtils.hasValue(result, 'UNITS_ID')) {
|
||||
|
|
@ -217,10 +220,9 @@ class _BreakgroundApplyDetailState extends State<BreakgroundApplyDetail> {
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// 选择经纬度
|
||||
Future<void> _showLocationHandle() async{
|
||||
Future<void> _showLocationHandle() async {
|
||||
if (!FormUtils.hasValue(pd, 'ELECTRONIC_FENCE_AREA_ID')) {
|
||||
ToastUtil.showNormal(context, '请选择作业区域');
|
||||
return;
|
||||
|
|
@ -229,10 +231,11 @@ class _BreakgroundApplyDetailState extends State<BreakgroundApplyDetail> {
|
|||
setState(() {
|
||||
pd['LONGITUDE'] = mapData['longitue'] ?? '';
|
||||
pd['LATITUDE'] = mapData['latitude'] ?? '';
|
||||
pd['LATITUDE_LONGITUDE'] = '${mapData['longitue'] ?? ''},${mapData['latitude'] ?? ''}';
|
||||
pd['LATITUDE_LONGITUDE'] =
|
||||
'${mapData['longitue'] ?? ''},${mapData['latitude'] ?? ''}';
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/// 作业区域
|
||||
Future<void> _getWorkArea() async {
|
||||
//FocusHelper.clearFocus(context);
|
||||
|
|
@ -243,16 +246,19 @@ class _BreakgroundApplyDetailState extends State<BreakgroundApplyDetail> {
|
|||
backgroundColor: Colors.transparent,
|
||||
builder:
|
||||
(_) => WorkAreaPicker(
|
||||
onSelected: (String id, String POSITIONS, String name) {
|
||||
pd['ELECTRONIC_FENCE_AREA_ID'] = id;
|
||||
pd['POSITIONS'] = POSITIONS;
|
||||
pd['PLS_NAME'] = name;
|
||||
},
|
||||
),
|
||||
onSelected: (String id, String POSITIONS, String name) {
|
||||
setState(() {
|
||||
pd['ELECTRONIC_FENCE_AREA_ID'] = id;
|
||||
pd['POSITIONS'] = POSITIONS;
|
||||
pd['PLS_NAME'] = name;
|
||||
});
|
||||
},
|
||||
),
|
||||
).then((_) {
|
||||
//FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
|
||||
/// 获取摄像头列表
|
||||
Future<void> _getVideoList() async {
|
||||
final result = await ApiService.getVideomanagerList();
|
||||
|
|
@ -260,6 +266,7 @@ class _BreakgroundApplyDetailState extends State<BreakgroundApplyDetail> {
|
|||
videoMonitoringList = result['varList'] ?? [];
|
||||
});
|
||||
}
|
||||
|
||||
/// 获承包商列表
|
||||
Future<void> _getUnitListAll() async {
|
||||
final result = await ApiService.getUnitListAll();
|
||||
|
|
@ -267,6 +274,7 @@ class _BreakgroundApplyDetailState extends State<BreakgroundApplyDetail> {
|
|||
unitAllList = result['varList'] ?? [];
|
||||
});
|
||||
}
|
||||
|
||||
/// 作业区域列表
|
||||
Future<void> _getPlsList() async {
|
||||
final result = await ApiService.getWorkAreaList();
|
||||
|
|
@ -275,6 +283,7 @@ class _BreakgroundApplyDetailState extends State<BreakgroundApplyDetail> {
|
|||
workAreaList = jsonDecode(zTreeNodes);
|
||||
});
|
||||
}
|
||||
|
||||
/// ------------------------------------------------------------
|
||||
Future<void> _chooseLevel() async {
|
||||
final choice = await BottomPicker.show<String>(
|
||||
|
|
@ -384,13 +393,15 @@ class _BreakgroundApplyDetailState extends State<BreakgroundApplyDetail> {
|
|||
return;
|
||||
}
|
||||
|
||||
if (personList.isEmpty) { // 一般这种情况是因为重新编辑没有缓存对应部门的负责人,所以先拉取一下接口
|
||||
if (personList.isEmpty) {
|
||||
// 一般这种情况是因为重新编辑没有缓存对应部门的负责人,所以先拉取一下接口
|
||||
await _getPersonListForUnitId(unitId, type);
|
||||
final list = _personCache[type] ?? [];
|
||||
|
||||
if (list.isEmpty) { // 如果还是没数据,说明该部门没有可选的人
|
||||
if (list.isEmpty) {
|
||||
// 如果还是没数据,说明该部门没有可选的人
|
||||
ToastUtil.showNormal(context, '暂无数据,请选择其他单位');
|
||||
}else{
|
||||
} else {
|
||||
choosePersonHandle(type);
|
||||
}
|
||||
return;
|
||||
|
|
@ -427,7 +438,6 @@ class _BreakgroundApplyDetailState extends State<BreakgroundApplyDetail> {
|
|||
{'value': _riskController.text.trim(), 'message': '请输入风险辨识结果'},
|
||||
];
|
||||
|
||||
|
||||
/// 各项负责人校验
|
||||
final unitRules = <EditUserType>[
|
||||
EditUserType.GUARDIAN,
|
||||
|
|
@ -459,7 +469,8 @@ class _BreakgroundApplyDetailState extends State<BreakgroundApplyDetail> {
|
|||
return;
|
||||
}
|
||||
|
||||
if (pd['IS_CONTRACTOR_WORK'] == '1' && !FormUtils.hasValue(pd, 'UNITS_ID')) {
|
||||
if (pd['IS_CONTRACTOR_WORK'] == '1' &&
|
||||
!FormUtils.hasValue(pd, 'UNITS_ID')) {
|
||||
ToastUtil.showNormal(context, '请选择承包商');
|
||||
return;
|
||||
}
|
||||
|
|
@ -526,8 +537,10 @@ class _BreakgroundApplyDetailState extends State<BreakgroundApplyDetail> {
|
|||
|
||||
/// 初始化拉取数据
|
||||
Future<void> _getData() async {
|
||||
|
||||
final data = await ApiService.getHomeworkFindById('breakground', widget.BREAKGROUND_ID);
|
||||
final data = await ApiService.getHomeworkFindById(
|
||||
'breakground',
|
||||
widget.BREAKGROUND_ID,
|
||||
);
|
||||
setState(() {
|
||||
pd = data['pd'];
|
||||
if (pd['STEP_ID'] == 0) {
|
||||
|
|
@ -544,12 +557,12 @@ class _BreakgroundApplyDetailState extends State<BreakgroundApplyDetail> {
|
|||
_relatedController.text = pd['SPECIAL_WORK'] ?? '';
|
||||
_riskController.text = pd['RISK_IDENTIFICATION'] ?? '';
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
Future<void> _getSigns(String homework_id) async {
|
||||
final data = await ApiService.listSignFinished('breakground',
|
||||
homework_id.length > 0 ? homework_id : widget.BREAKGROUND_ID,
|
||||
final data = await ApiService.listSignFinished(
|
||||
'breakground',
|
||||
homework_id.length > 0 ? homework_id : '',
|
||||
);
|
||||
setState(() {
|
||||
signs = data['signs'] ?? {};
|
||||
|
|
@ -557,8 +570,9 @@ class _BreakgroundApplyDetailState extends State<BreakgroundApplyDetail> {
|
|||
}
|
||||
|
||||
Future<void> _getMeasures(String homework_id) async {
|
||||
final data = await ApiService.listSignFinishMeasures('breakground',
|
||||
homework_id.length > 0 ? homework_id : widget.BREAKGROUND_ID,
|
||||
final data = await ApiService.listSignFinishMeasures(
|
||||
'breakground',
|
||||
homework_id.length > 0 ? homework_id : '',
|
||||
);
|
||||
setState(() {
|
||||
measuresList = List<Map<String, dynamic>>.from(
|
||||
|
|
@ -667,7 +681,7 @@ class _BreakgroundApplyDetailState extends State<BreakgroundApplyDetail> {
|
|||
color: Colors.white,
|
||||
child: MeasuresListWidget(
|
||||
measuresList:
|
||||
measuresList, // List<Map<String, dynamic>>
|
||||
measuresList, // List<Map<String, dynamic>>
|
||||
baseImgPath: ApiService.baseImgPath,
|
||||
isAllowEdit: false,
|
||||
),
|
||||
|
|
@ -695,45 +709,9 @@ class _BreakgroundApplyDetailState extends State<BreakgroundApplyDetail> {
|
|||
),
|
||||
isEditable
|
||||
? Row(
|
||||
spacing: 10,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Expanded(
|
||||
child: CustomButton(
|
||||
height: 45,
|
||||
textStyle: TextStyle(
|
||||
fontSize: 16,
|
||||
color: Colors.white,
|
||||
),
|
||||
text: '提交',
|
||||
backgroundColor: Colors.blue,
|
||||
onPressed: () {
|
||||
_submit('1');
|
||||
},
|
||||
),
|
||||
),
|
||||
|
||||
Expanded(
|
||||
child: CustomButton(
|
||||
textStyle: TextStyle(
|
||||
fontSize: 16,
|
||||
color: Colors.white,
|
||||
),
|
||||
text: '暂存',
|
||||
backgroundColor: Colors.green,
|
||||
onPressed: () {
|
||||
_submit('0');
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
: Column(
|
||||
children: [
|
||||
SizedBox(height: 20),
|
||||
Row(
|
||||
spacing: 10,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
SizedBox(width: 50),
|
||||
Expanded(
|
||||
child: CustomButton(
|
||||
height: 45,
|
||||
|
|
@ -741,18 +719,54 @@ class _BreakgroundApplyDetailState extends State<BreakgroundApplyDetail> {
|
|||
fontSize: 16,
|
||||
color: Colors.white,
|
||||
),
|
||||
text: '返回',
|
||||
backgroundColor: Colors.green,
|
||||
text: '提交',
|
||||
backgroundColor: Colors.blue,
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
_submit('1');
|
||||
},
|
||||
),
|
||||
),
|
||||
SizedBox(width: 50),
|
||||
|
||||
Expanded(
|
||||
child: CustomButton(
|
||||
textStyle: TextStyle(
|
||||
fontSize: 16,
|
||||
color: Colors.white,
|
||||
),
|
||||
text: '暂存',
|
||||
backgroundColor: Colors.green,
|
||||
onPressed: () {
|
||||
_submit('0');
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
: Column(
|
||||
children: [
|
||||
SizedBox(height: 20),
|
||||
Row(
|
||||
children: [
|
||||
SizedBox(width: 50),
|
||||
Expanded(
|
||||
child: CustomButton(
|
||||
height: 45,
|
||||
textStyle: TextStyle(
|
||||
fontSize: 16,
|
||||
color: Colors.white,
|
||||
),
|
||||
text: '返回',
|
||||
backgroundColor: Colors.green,
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
),
|
||||
),
|
||||
SizedBox(width: 50),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -208,7 +208,7 @@ class _BreakgroundDzzhDetailState extends State<BreakgroundDzzhDetail> {
|
|||
Future<void> _getMeasures(String homework_id) async {
|
||||
final data = await ApiService.listSignFinishMeasures(
|
||||
'breakground',
|
||||
homework_id.length > 0 ? homework_id : widget.BREAKGROUND_ID,
|
||||
homework_id.length > 0 ? homework_id : '',
|
||||
);
|
||||
setState(() {
|
||||
measuresList = List<Map<String, dynamic>>.from(
|
||||
|
|
@ -220,7 +220,7 @@ class _BreakgroundDzzhDetailState extends State<BreakgroundDzzhDetail> {
|
|||
Future<void> _getSigns(String homework_id) async {
|
||||
final data = await ApiService.listSignFinished(
|
||||
'breakground',
|
||||
homework_id.length > 0 ? homework_id : widget.BREAKGROUND_ID,
|
||||
homework_id.length > 0 ? homework_id : '',
|
||||
);
|
||||
setState(() {
|
||||
signs = data['signs'] ?? {};
|
||||
|
|
|
|||
|
|
@ -202,7 +202,7 @@ class _BreakgroundJhrDetailState extends State<BreakgroundJhrDetail> {
|
|||
Future<void> _getMeasures(String homework_id) async {
|
||||
final data = await ApiService.listSignFinishMeasures(
|
||||
'breakground',
|
||||
homework_id.length > 0 ? homework_id : widget.BREAKGROUND_ID,
|
||||
homework_id.length > 0 ? homework_id : '',
|
||||
);
|
||||
setState(() {
|
||||
measuresList = List<Map<String, dynamic>>.from(
|
||||
|
|
@ -214,7 +214,7 @@ class _BreakgroundJhrDetailState extends State<BreakgroundJhrDetail> {
|
|||
Future<void> _getSigns(String homework_id) async {
|
||||
final data = await ApiService.listSignFinished(
|
||||
'breakground',
|
||||
homework_id.length > 0 ? homework_id : widget.BREAKGROUND_ID,
|
||||
homework_id.length > 0 ? homework_id : '',
|
||||
);
|
||||
setState(() {
|
||||
signs = data['signs'] ?? {};
|
||||
|
|
|
|||
|
|
@ -202,7 +202,7 @@ class _BreakgroundJsjdDetailState extends State<BreakgroundJsjdDetail> {
|
|||
Future<void> _getMeasures(String homework_id) async {
|
||||
final data = await ApiService.listSignFinishMeasures(
|
||||
'breakground',
|
||||
homework_id.length > 0 ? homework_id : widget.BREAKGROUND_ID,
|
||||
homework_id.length > 0 ? homework_id : '',
|
||||
);
|
||||
setState(() {
|
||||
measuresList = List<Map<String, dynamic>>.from(
|
||||
|
|
@ -214,7 +214,7 @@ class _BreakgroundJsjdDetailState extends State<BreakgroundJsjdDetail> {
|
|||
Future<void> _getSigns(String homework_id) async {
|
||||
final data = await ApiService.listSignFinished(
|
||||
'breakground',
|
||||
homework_id.length > 0 ? homework_id : widget.BREAKGROUND_ID,
|
||||
homework_id.length > 0 ? homework_id : '',
|
||||
);
|
||||
setState(() {
|
||||
signs = data['signs'] ?? {};
|
||||
|
|
|
|||
|
|
@ -149,7 +149,7 @@ class _BreakgroundJszyDetailState extends State<BreakgroundJszyDetail> {
|
|||
Future<void> _getMeasures(String homework_id) async {
|
||||
final data = await ApiService.listSignFinishMeasures(
|
||||
'breakground',
|
||||
homework_id.length > 0 ? homework_id : widget.BREAKGROUND_ID,
|
||||
homework_id.length > 0 ? homework_id : '',
|
||||
);
|
||||
setState(() {
|
||||
measuresList = List<Map<String, dynamic>>.from(
|
||||
|
|
@ -161,7 +161,7 @@ class _BreakgroundJszyDetailState extends State<BreakgroundJszyDetail> {
|
|||
Future<void> _getSigns(String homework_id) async {
|
||||
final data = await ApiService.listSignFinished(
|
||||
'breakground',
|
||||
homework_id.length > 0 ? homework_id : widget.BREAKGROUND_ID,
|
||||
homework_id.length > 0 ? homework_id : '',
|
||||
);
|
||||
setState(() {
|
||||
signs = data['signs'] ?? {};
|
||||
|
|
@ -207,6 +207,7 @@ class _BreakgroundJszyDetailState extends State<BreakgroundJszyDetail> {
|
|||
child: SingleChildScrollView(
|
||||
padding: EdgeInsets.all(12),
|
||||
child: Column(
|
||||
spacing: 12,
|
||||
children: [
|
||||
// _setSafeDetailWidget(),
|
||||
SpecialWorkFormBaseWork(
|
||||
|
|
@ -247,7 +248,6 @@ class _BreakgroundJszyDetailState extends State<BreakgroundJszyDetail> {
|
|||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 12,),
|
||||
_bottomButtons(),
|
||||
],
|
||||
),
|
||||
|
|
|
|||
|
|
@ -132,7 +132,7 @@ class _BreakgroundKszyDetailState extends State<BreakgroundKszyDetail> {
|
|||
Future<void> _getMeasures(String homework_id) async {
|
||||
final data = await ApiService.listSignFinishMeasures(
|
||||
'breakground',
|
||||
homework_id.length > 0 ? homework_id : widget.BREAKGROUND_ID,
|
||||
homework_id.length > 0 ? homework_id : '',
|
||||
);
|
||||
setState(() {
|
||||
measuresList = List<Map<String, dynamic>>.from(
|
||||
|
|
@ -144,7 +144,7 @@ class _BreakgroundKszyDetailState extends State<BreakgroundKszyDetail> {
|
|||
Future<void> _getSigns(String homework_id) async {
|
||||
final data = await ApiService.listSignFinished(
|
||||
'breakground',
|
||||
homework_id.length > 0 ? homework_id : widget.BREAKGROUND_ID,
|
||||
homework_id.length > 0 ? homework_id : '',
|
||||
);
|
||||
setState(() {
|
||||
signs = data['signs'] ?? {};
|
||||
|
|
@ -190,6 +190,7 @@ class _BreakgroundKszyDetailState extends State<BreakgroundKszyDetail> {
|
|||
child: SingleChildScrollView(
|
||||
padding: EdgeInsets.all(12),
|
||||
child: Column(
|
||||
spacing: 12,
|
||||
children: [
|
||||
// _setSafeDetailWidget(),
|
||||
SpecialWorkFormBaseWork(
|
||||
|
|
@ -236,7 +237,6 @@ class _BreakgroundKszyDetailState extends State<BreakgroundKszyDetail> {
|
|||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 12,),
|
||||
_bottomButtons(),
|
||||
],
|
||||
),
|
||||
|
|
|
|||
|
|
@ -207,7 +207,7 @@ class _BreakgroundShbmDetailState extends State<BreakgroundShbmDetail> {
|
|||
Future<void> _getMeasures(String homework_id) async {
|
||||
final data = await ApiService.listSignFinishMeasures(
|
||||
'breakground',
|
||||
homework_id.length > 0 ? homework_id : widget.BREAKGROUND_ID,
|
||||
homework_id.length > 0 ? homework_id : '',
|
||||
);
|
||||
setState(() {
|
||||
measuresList = List<Map<String, dynamic>>.from(
|
||||
|
|
@ -219,7 +219,7 @@ class _BreakgroundShbmDetailState extends State<BreakgroundShbmDetail> {
|
|||
Future<void> _getSigns(String homework_id) async {
|
||||
final data = await ApiService.listSignFinished(
|
||||
'breakground',
|
||||
homework_id.length > 0 ? homework_id : widget.BREAKGROUND_ID,
|
||||
homework_id.length > 0 ? homework_id : '',
|
||||
);
|
||||
setState(() {
|
||||
signs = data['signs'] ?? {};
|
||||
|
|
@ -294,7 +294,7 @@ class _BreakgroundShbmDetailState extends State<BreakgroundShbmDetail> {
|
|||
children: [
|
||||
Expanded(
|
||||
child: ListItemFactory.headerTitle(
|
||||
'有关水、电、汽、工艺、设备、消防安全等部门负责人',
|
||||
'有关水、电、汽、工艺、设备、\n消防安全等部门负责人',
|
||||
),
|
||||
),
|
||||
CustomButton(
|
||||
|
|
|
|||
|
|
@ -207,7 +207,7 @@ class _BreakgroundSpbmDetailState extends State<BreakgroundSpbmDetail> {
|
|||
Future<void> _getMeasures(String homework_id) async {
|
||||
final data = await ApiService.listSignFinishMeasures(
|
||||
'breakground',
|
||||
homework_id.length > 0 ? homework_id : widget.BREAKGROUND_ID,
|
||||
homework_id.length > 0 ? homework_id : '',
|
||||
);
|
||||
setState(() {
|
||||
measuresList = List<Map<String, dynamic>>.from(
|
||||
|
|
@ -219,7 +219,7 @@ class _BreakgroundSpbmDetailState extends State<BreakgroundSpbmDetail> {
|
|||
Future<void> _getSigns(String homework_id) async {
|
||||
final data = await ApiService.listSignFinished(
|
||||
'breakground',
|
||||
homework_id.length > 0 ? homework_id : widget.BREAKGROUND_ID,
|
||||
homework_id.length > 0 ? homework_id : '',
|
||||
);
|
||||
setState(() {
|
||||
signs = data['signs'] ?? {};
|
||||
|
|
|
|||
|
|
@ -201,7 +201,7 @@ class _BreakgroundSsrDetailState extends State<BreakgroundSsrDetail> {
|
|||
Future<void> _getMeasures(String homework_id) async {
|
||||
final data = await ApiService.listSignFinishMeasures(
|
||||
'breakground',
|
||||
homework_id.length > 0 ? homework_id : widget.BREAKGROUND_ID,
|
||||
homework_id.length > 0 ? homework_id : '',
|
||||
);
|
||||
setState(() {
|
||||
measuresList = List<Map<String, dynamic>>.from(
|
||||
|
|
@ -213,7 +213,7 @@ class _BreakgroundSsrDetailState extends State<BreakgroundSsrDetail> {
|
|||
Future<void> _getSigns(String homework_id) async {
|
||||
final data = await ApiService.listSignFinished(
|
||||
'breakground',
|
||||
homework_id.length > 0 ? homework_id : widget.BREAKGROUND_ID,
|
||||
homework_id.length > 0 ? homework_id : '',
|
||||
);
|
||||
setState(() {
|
||||
signs = data['signs'] ?? {};
|
||||
|
|
|
|||
|
|
@ -352,7 +352,7 @@ class _BreakgroundSetSafeDetailState extends State<BreakgroundSetSafeDetail> {
|
|||
Future<void> _getSigns(String homework_id) async {
|
||||
final data = await ApiService.listSignFinished(
|
||||
'breakground',
|
||||
homework_id.length > 0 ? homework_id : widget.BREAKGROUND_ID,
|
||||
homework_id.length > 0 ? homework_id : '',
|
||||
);
|
||||
setState(() {
|
||||
signs = data['signs'] ?? {};
|
||||
|
|
@ -360,7 +360,7 @@ class _BreakgroundSetSafeDetailState extends State<BreakgroundSetSafeDetail> {
|
|||
}
|
||||
|
||||
Future<void> _getMeasures() async {
|
||||
final data = await ApiService.listSignFinishAllMeasures('breakground');
|
||||
final data = await ApiService.listSignFinishAllMeasures('breakground', widget.BREAKGROUND_ID);
|
||||
setState(() {
|
||||
measuresList = List<Map<String, dynamic>>.from(
|
||||
data['measuresList'] ?? <Map<String, dynamic>>[],
|
||||
|
|
|
|||
|
|
@ -208,7 +208,7 @@ class _BreakgroundSzdwDetailState extends State<BreakgroundSzdwDetail> {
|
|||
Future<void> _getMeasures(String homework_id) async {
|
||||
final data = await ApiService.listSignFinishMeasures(
|
||||
'breakground',
|
||||
homework_id.length > 0 ? homework_id : widget.BREAKGROUND_ID,
|
||||
homework_id.length > 0 ? homework_id : '',
|
||||
);
|
||||
setState(() {
|
||||
measuresList = List<Map<String, dynamic>>.from(
|
||||
|
|
@ -220,7 +220,7 @@ class _BreakgroundSzdwDetailState extends State<BreakgroundSzdwDetail> {
|
|||
Future<void> _getSigns(String homework_id) async {
|
||||
final data = await ApiService.listSignFinished(
|
||||
'breakground',
|
||||
homework_id.length > 0 ? homework_id : widget.BREAKGROUND_ID,
|
||||
homework_id.length > 0 ? homework_id : '',
|
||||
);
|
||||
setState(() {
|
||||
signs = data['signs'] ?? {};
|
||||
|
|
|
|||
|
|
@ -272,7 +272,7 @@ class _BreakgroundYsgdDetailState extends State<BreakgroundYsgdDetail> {
|
|||
Future<void> _getMeasures(String homework_id) async {
|
||||
final data = await ApiService.listSignFinishMeasures(
|
||||
'breakground',
|
||||
homework_id.length > 0 ? homework_id : widget.BREAKGROUND_ID,
|
||||
homework_id.length > 0 ? homework_id : '',
|
||||
);
|
||||
setState(() {
|
||||
measuresList = List<Map<String, dynamic>>.from(
|
||||
|
|
@ -284,7 +284,7 @@ class _BreakgroundYsgdDetailState extends State<BreakgroundYsgdDetail> {
|
|||
Future<void> _getSigns(String homework_id) async {
|
||||
final data = await ApiService.listSignFinished(
|
||||
'breakground',
|
||||
homework_id.length > 0 ? homework_id : widget.BREAKGROUND_ID,
|
||||
homework_id.length > 0 ? homework_id : '',
|
||||
);
|
||||
setState(() {
|
||||
signs = data['signs'] ?? {};
|
||||
|
|
|
|||
|
|
@ -208,7 +208,7 @@ class _BreakgroundZyfzDetailState extends State<BreakgroundZyfzDetail> {
|
|||
Future<void> _getMeasures(String homework_id) async {
|
||||
final data = await ApiService.listSignFinishMeasures(
|
||||
'breakground',
|
||||
homework_id.length > 0 ? homework_id : widget.BREAKGROUND_ID,
|
||||
homework_id.length > 0 ? homework_id : '',
|
||||
);
|
||||
setState(() {
|
||||
measuresList = List<Map<String, dynamic>>.from(
|
||||
|
|
@ -220,7 +220,7 @@ class _BreakgroundZyfzDetailState extends State<BreakgroundZyfzDetail> {
|
|||
Future<void> _getSigns(String homework_id) async {
|
||||
final data = await ApiService.listSignFinished(
|
||||
'breakground',
|
||||
homework_id.length > 0 ? homework_id : widget.BREAKGROUND_ID,
|
||||
homework_id.length > 0 ? homework_id : '',
|
||||
);
|
||||
setState(() {
|
||||
signs = data['signs'] ?? {};
|
||||
|
|
|
|||
|
|
@ -228,7 +228,7 @@ class _BreakgroundZyrDetailState extends State<BreakgroundZyrDetail> {
|
|||
Future<void> _getMeasures(String homework_id) async {
|
||||
final data = await ApiService.listSignFinishMeasures(
|
||||
'breakground',
|
||||
homework_id.length > 0 ? homework_id : widget.BREAKGROUND_ID,
|
||||
homework_id.length > 0 ? homework_id : '',
|
||||
);
|
||||
setState(() {
|
||||
measuresList = List<Map<String, dynamic>>.from(
|
||||
|
|
@ -240,7 +240,7 @@ class _BreakgroundZyrDetailState extends State<BreakgroundZyrDetail> {
|
|||
Future<void> _getSigns(String homework_id) async {
|
||||
final data = await ApiService.listSignFinished(
|
||||
'breakground',
|
||||
homework_id.length > 0 ? homework_id : widget.BREAKGROUND_ID,
|
||||
homework_id.length > 0 ? homework_id : '',
|
||||
);
|
||||
setState(() {
|
||||
signs = data['signs'] ?? {};
|
||||
|
|
|
|||
|
|
@ -78,180 +78,6 @@ class _HoistworkDetailFormWidgetState extends State<HoistWorkDetailFormWidget> {
|
|||
default: return '';
|
||||
}
|
||||
}
|
||||
Widget signItemWidget(
|
||||
String signKey,
|
||||
String nameKey,
|
||||
String name,
|
||||
BuildContext context,
|
||||
) {
|
||||
return _itemContainer(
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
// 标题行
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 5, horizontal: 10),
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: ListItemFactory.headerTitle(name),
|
||||
),
|
||||
if (FormUtils.hasValue(widget.pd, nameKey))
|
||||
Text(
|
||||
widget.pd[nameKey]?.toString() ?? '',
|
||||
style: const TextStyle(fontSize: 16),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
|
||||
if (FormUtils.hasValue(widget.signs, signKey))
|
||||
...((widget.signs[signKey] as List<dynamic>)
|
||||
.cast<Map<String, dynamic>>()
|
||||
.map((item) {
|
||||
// 解析 SIGN_PATH
|
||||
List<String> signPaths = [];
|
||||
final rawSP = FormUtils.hasValue(item, 'SIGN_PATH') ? item['SIGN_PATH'] : null;
|
||||
if (rawSP is String && rawSP.isNotEmpty) {
|
||||
signPaths = rawSP.split(',').map((s) => s.trim()).toList();
|
||||
} else if (rawSP is List) {
|
||||
signPaths = rawSP.cast<String>();
|
||||
}
|
||||
|
||||
// 解析 SIGN_TIME 保留空格
|
||||
List<String> signTimes = [];
|
||||
final rawST = FormUtils.hasValue(item, 'SIGN_TIME') ? item['SIGN_TIME'] : null;
|
||||
if (rawST is String && rawST.isNotEmpty) {
|
||||
signTimes = rawST.split(',');
|
||||
} else if (rawST is List) {
|
||||
signTimes = rawST.cast<String>();
|
||||
}
|
||||
|
||||
final pairCount = math.min(signPaths.length, signTimes.length);
|
||||
|
||||
// 解析 IMG_PATH, 最多 2 张
|
||||
List<String> imgPaths = [];
|
||||
final rawIP = FormUtils.hasValue(item, 'IMG_PATH') ? item['IMG_PATH'] : null;
|
||||
if (rawIP is String && rawIP.isNotEmpty) {
|
||||
imgPaths = rawIP.split(',').map((s) => s.trim()).take(2).toList();
|
||||
} else if (rawIP is List) {
|
||||
imgPaths = rawIP.cast<String>().take(2).toList();
|
||||
}
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 10),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
if (imgPaths.isNotEmpty) ...[
|
||||
Row(
|
||||
children: imgPaths.map((p) {
|
||||
final fullUrl = '${ApiService.baseImgPath}$p';
|
||||
return GestureDetector(
|
||||
onTap: () => presentOpaque(
|
||||
SingleImageViewer(imageUrl: fullUrl),
|
||||
context,
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(right: 8.0),
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(2),
|
||||
child: Image.network(
|
||||
fullUrl,
|
||||
width: 50,
|
||||
height: 50,
|
||||
fit: BoxFit.fill,
|
||||
errorBuilder: (_, __, ___) => const Icon(
|
||||
Icons.broken_image,
|
||||
size: 40,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
],
|
||||
|
||||
// 签名及时间
|
||||
...List.generate(pairCount, (index) {
|
||||
final imgPath = signPaths[index];
|
||||
final timeLabel = signTimes[index];
|
||||
final fullUrl = '${ApiService.baseImgPath}$imgPath';
|
||||
const imageWidth = 200.0;
|
||||
const imageHeight = 100.0;
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 8.0),
|
||||
child: Column(
|
||||
children: [
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
GestureDetector(
|
||||
onTap: () => presentOpaque(
|
||||
SingleImageViewer(imageUrl: fullUrl),
|
||||
context,
|
||||
),
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
child: Image.network(
|
||||
fullUrl,
|
||||
width: imageWidth,
|
||||
height: imageHeight,
|
||||
fit: BoxFit.fill,
|
||||
errorBuilder: (_, __, ___) =>
|
||||
const Icon(Icons.broken_image, size: 60),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: SizedBox(
|
||||
height: imageHeight,
|
||||
child: Align(
|
||||
alignment: Alignment.bottomRight,
|
||||
child: Text(
|
||||
timeLabel,
|
||||
style: const TextStyle(
|
||||
fontSize: 14,
|
||||
color: Colors.black87,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
if (index < pairCount - 1)
|
||||
const Padding(
|
||||
padding: EdgeInsets.only(top: 8.0),
|
||||
child: Divider(height: 1),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}),
|
||||
],
|
||||
),
|
||||
);
|
||||
}).toList()),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
Widget _itemContainer(Widget child) {
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 5, vertical: 8),
|
||||
child: child,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
|
@ -277,6 +103,35 @@ class _HoistworkDetailFormWidgetState extends State<HoistWorkDetailFormWidget> {
|
|||
),
|
||||
const Divider(),
|
||||
],
|
||||
ItemListWidget.singleLineTitleText(
|
||||
label: '作业申请单位:',
|
||||
isEditable: false,
|
||||
text: pd['APPLY_DEPARTMENT_NAME'] ?? '',
|
||||
),
|
||||
const Divider(),
|
||||
ItemListWidget.singleLineTitleText(
|
||||
label: '申请人:',
|
||||
isEditable: false,
|
||||
text: pd['APPLY_USER_NAME'] ?? '',
|
||||
),
|
||||
if (FormUtils.hasValue(pd, 'CONFIRM_DEPARTMENT_NAME')) ...[
|
||||
const Divider(),
|
||||
ItemListWidget.singleLineTitleText(
|
||||
label: '作业单位:',
|
||||
isEditable: false,
|
||||
text: pd['CONFIRM_DEPARTMENT_NAME'] ?? '',
|
||||
),
|
||||
],
|
||||
if (FormUtils.hasValue(pd, 'CREATTIME') && !widget.isEditable) ...[
|
||||
const Divider(),
|
||||
ItemListWidget.singleLineTitleText(
|
||||
label: '作业申请时间:',
|
||||
isEditable: false,
|
||||
text: pd['CREATTIME'] ?? '',
|
||||
),
|
||||
],
|
||||
const Divider(),
|
||||
|
||||
ItemListWidget.singleLineTitleText(
|
||||
label: '吊装地点:',
|
||||
isEditable: widget.isEditable,
|
||||
|
|
@ -294,6 +149,54 @@ class _HoistworkDetailFormWidgetState extends State<HoistWorkDetailFormWidget> {
|
|||
text: pd['TOOL_NAME'] ?? '',
|
||||
),
|
||||
const Divider(),
|
||||
ItemListWidget.multiLineTitleTextField(
|
||||
label: '吊物内容:',
|
||||
isEditable: widget.isEditable,
|
||||
controller: widget.contentController,
|
||||
hintText: '请输入吊物内容',
|
||||
text: pd['WORK_CONTENT'] ?? '',
|
||||
),
|
||||
if (FormUtils.hasValue(pd, 'WORK_USER_USER_NAME') &&
|
||||
!widget.isEditable) ...[
|
||||
const Divider(),
|
||||
SignRowImageTitle(
|
||||
label: '吊装作业人:',
|
||||
signKey: 'WORK_USER',
|
||||
signs: widget.signs,
|
||||
text: pd['WORK_USER_USER_NAME'] ?? '',
|
||||
),
|
||||
],
|
||||
if (FormUtils.hasValue(pd, 'SISUO_USER_NAME') &&
|
||||
!widget.isEditable) ...[
|
||||
const Divider(),
|
||||
SignRowImageTitle(
|
||||
label: '司索人:',
|
||||
signKey: 'SISUO',
|
||||
signs: widget.signs,
|
||||
text: pd['SISUO_USER_NAME'] ?? '',
|
||||
),
|
||||
],
|
||||
if (FormUtils.hasValue(pd, 'GUARDIAN_USER_NAME') &&
|
||||
!widget.isEditable) ...[
|
||||
const Divider(),
|
||||
SignRowImageTitle(
|
||||
label: '监护人:',
|
||||
signKey: 'GUARDIAN',
|
||||
signs: widget.signs,
|
||||
text: pd['GUARDIAN_USER_NAME'] ?? '',
|
||||
),
|
||||
],
|
||||
if (FormUtils.hasValue(pd, 'PROJECT_MANAGER_USER_NAME') &&
|
||||
!widget.isEditable) ...[
|
||||
const Divider(),
|
||||
SignRowImageTitle(
|
||||
label: '指挥人员:',
|
||||
signKey: 'HOISTING_CONDUCTOR',
|
||||
signs: widget.signs,
|
||||
text: pd['PROJECT_MANAGER_USER_NAME'] ?? '',
|
||||
),
|
||||
],
|
||||
const Divider(),
|
||||
ItemListWidget.singleLineTitleText(
|
||||
label: '吊物质量(吨):',
|
||||
keyboardType: TextInputType.numberWithOptions(
|
||||
|
|
@ -308,35 +211,12 @@ class _HoistworkDetailFormWidgetState extends State<HoistWorkDetailFormWidget> {
|
|||
const Divider(),
|
||||
ItemListWidget.selectableLineTitleTextRightButton(
|
||||
label: '作业级别:',
|
||||
isEditable: widget.isEditable,
|
||||
isEditable: false,
|
||||
onTap: widget.onChooseLevel,
|
||||
text: _getWorkLevelText(pd['WORK_LEVEL']),
|
||||
),
|
||||
const Divider(),
|
||||
ItemListWidget.multiLineTitleTextField(
|
||||
label: '吊物内容:',
|
||||
isEditable: widget.isEditable,
|
||||
controller: widget.contentController,
|
||||
hintText: '请输入吊物内容',
|
||||
text: pd['WORK_CONTENT'] ?? '',
|
||||
),
|
||||
|
||||
if (!widget.isEditable && FormUtils.hasValue(pd, 'WORK_START_DATE')) ...[
|
||||
ItemListWidget.singleLineTitleText(
|
||||
label: '作业开始时间:',
|
||||
isEditable: false,
|
||||
text: pd['WORK_START_DATE'] ?? '',
|
||||
),
|
||||
const Divider(),
|
||||
],
|
||||
if (!widget.isEditable && FormUtils.hasValue(pd, 'WORK_END_DATE')) ...[
|
||||
ItemListWidget.singleLineTitleText(
|
||||
label: '作业结束时间:',
|
||||
isEditable: false,
|
||||
text: pd['WORK_END_DATE'] ?? '',
|
||||
),
|
||||
const Divider(),
|
||||
],
|
||||
ItemListWidget.twoRowButtonTitleText(
|
||||
label: '关联其他特殊作业及安全作业票编号',
|
||||
isRequired: false,
|
||||
|
|
@ -385,71 +265,67 @@ class _HoistworkDetailFormWidgetState extends State<HoistWorkDetailFormWidget> {
|
|||
controller: widget.riskController,
|
||||
text: pd['RISK_IDENTIFICATION'] ?? '',
|
||||
),
|
||||
const Divider(),
|
||||
ItemListWidget.selectableLineTitleTextRightButton(
|
||||
label: '作业视频监控:',
|
||||
isClean: widget.isEditable,
|
||||
cleanText: '清除监控',
|
||||
onTapClean: () {
|
||||
setState(() {
|
||||
pd['VIDEONAME'] = '';
|
||||
pd['VIDEOMANAGER_ID'] = '';
|
||||
});
|
||||
},
|
||||
isRequired: false,
|
||||
isEditable: widget.isEditable,
|
||||
onTap: widget.onChooseVideoManager ?? () {},
|
||||
text: pd['VIDEONAME'] ?? '',
|
||||
),
|
||||
const Divider(),
|
||||
ItemListWidget.selectableLineTitleTextRightButton(
|
||||
label: '预计作业开始时间:',
|
||||
isEditable: widget.isEditable,
|
||||
onTap: () async {
|
||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||
mode: BottomPickerMode.dateTimeWithSeconds,
|
||||
context,
|
||||
allowFuture: true,
|
||||
);
|
||||
if (picked != null) {
|
||||
setState(() {
|
||||
pd['WORK_EXPECTED_START_TIME'] = DateFormat(
|
||||
'yyyy-MM-dd HH:mm:ss',
|
||||
).format(picked);
|
||||
if (FormUtils.hasValue(pd, 'WORK_START_DATE')) ...[
|
||||
const Divider(),
|
||||
ItemListWidget.selectableLineTitleTextRightButton(
|
||||
label: '作业实施时间:',
|
||||
isEditable: widget.isEditable,
|
||||
text:
|
||||
FormUtils.hasValue(pd, 'WORK_END_DATE')
|
||||
? '${pd['WORK_START_DATE'] ?? ''}\n-${pd['WORK_END_DATE'] ?? ''}'
|
||||
: pd['WORK_START_DATE'] ?? '',
|
||||
),
|
||||
] else ...[
|
||||
const Divider(),
|
||||
ItemListWidget.selectableLineTitleTextRightButton(
|
||||
label: '预计作业开始时间:',
|
||||
isEditable: widget.isEditable,
|
||||
onTap: () async {
|
||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||
mode: BottomPickerMode.dateTimeWithSeconds,
|
||||
context,
|
||||
allowFuture: true,
|
||||
);
|
||||
if (picked != null) {
|
||||
setState(() {
|
||||
pd['WORK_EXPECTED_START_TIME'] = DateFormat(
|
||||
'yyyy-MM-dd HH:mm:ss',
|
||||
).format(picked);
|
||||
|
||||
/// 开始时间必须早于结束时间
|
||||
if (FormUtils.hasValue(pd, 'WORK_EXPECTED_END_TIME') &&
|
||||
!isBeforeStr(
|
||||
pd['WORK_EXPECTED_START_TIME'],
|
||||
pd['WORK_EXPECTED_END_TIME'],
|
||||
)) {
|
||||
pd['WORK_EXPECTED_END_TIME'] = '';
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
text: pd['WORK_EXPECTED_START_TIME'] ?? '',
|
||||
),
|
||||
const Divider(),
|
||||
ItemListWidget.selectableLineTitleTextRightButton(
|
||||
label: '预计作业结束时间:',
|
||||
isEditable: widget.isEditable,
|
||||
onTap: () async {
|
||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||
context,
|
||||
minTimeStr: pd['WORK_EXPECTED_START_TIME'] ?? '',
|
||||
allowFuture: true,
|
||||
);
|
||||
if (picked != null) {
|
||||
setState(() {
|
||||
pd['WORK_EXPECTED_END_TIME'] = DateFormat(
|
||||
'yyyy-MM-dd HH:mm:ss',
|
||||
).format(picked);
|
||||
});
|
||||
}
|
||||
},
|
||||
text: pd['WORK_EXPECTED_END_TIME'] ?? '',
|
||||
),
|
||||
/// 开始时间必须早于结束时间
|
||||
if (FormUtils.hasValue(pd, 'WORK_EXPECTED_END_TIME') &&
|
||||
!isBeforeStr(
|
||||
pd['WORK_EXPECTED_START_TIME'],
|
||||
pd['WORK_EXPECTED_END_TIME'],
|
||||
)) {
|
||||
pd['WORK_EXPECTED_END_TIME'] = '';
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
text: pd['WORK_EXPECTED_START_TIME'] ?? '',
|
||||
),
|
||||
const Divider(),
|
||||
ItemListWidget.selectableLineTitleTextRightButton(
|
||||
label: '预计作业结束时间:',
|
||||
isEditable: widget.isEditable,
|
||||
onTap: () async {
|
||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||
context,
|
||||
minTimeStr: pd['WORK_EXPECTED_START_TIME'] ?? '',
|
||||
allowFuture: true,
|
||||
);
|
||||
if (picked != null) {
|
||||
setState(() {
|
||||
pd['WORK_EXPECTED_END_TIME'] = DateFormat(
|
||||
'yyyy-MM-dd HH:mm:ss',
|
||||
).format(picked);
|
||||
});
|
||||
}
|
||||
},
|
||||
text: pd['WORK_EXPECTED_END_TIME'] ?? '',
|
||||
),
|
||||
],
|
||||
const Divider(),
|
||||
ListItemFactory.createYesNoSection(
|
||||
verticalPadding: 0,
|
||||
|
|
@ -496,19 +372,35 @@ class _HoistworkDetailFormWidgetState extends State<HoistWorkDetailFormWidget> {
|
|||
hintText: '',
|
||||
text: pd['LATITUDE_LONGITUDE'] ?? (widget.isEditable ? '' : '无'),
|
||||
),
|
||||
const Divider(),
|
||||
|
||||
if (FormUtils.hasValue(widget.signs, 'SISUO'))
|
||||
Column(
|
||||
children: [
|
||||
Container(
|
||||
color: h_backGroundColor(),
|
||||
height: 10,
|
||||
width: double.maxFinite,
|
||||
child: SizedBox()
|
||||
),
|
||||
signItemWidget('SISUO', 'SISUO_USER_NAME', '司索人', context),
|
||||
],
|
||||
)
|
||||
ItemListWidget.selectableLineTitleTextRightButton(
|
||||
label: '作业视频监控:',
|
||||
isClean: widget.isEditable,
|
||||
cleanText: '清除监控',
|
||||
onTapClean: () {
|
||||
setState(() {
|
||||
pd['VIDEONAME'] = '';
|
||||
pd['VIDEOMANAGER_ID'] = '';
|
||||
});
|
||||
},
|
||||
isRequired: false,
|
||||
isEditable: widget.isEditable,
|
||||
onTap: widget.onChooseVideoManager ?? () {},
|
||||
text: pd['VIDEONAME'] ?? '',
|
||||
),
|
||||
if (FormUtils.hasValue(widget.signs, 'SISUO')) ...[
|
||||
const Divider(),
|
||||
ConfirmWithSignWidget(
|
||||
signs: widget.signs,
|
||||
pd: pd,
|
||||
baseImgPath: ApiService.baseImgPath,
|
||||
sectionKey: 'SISUO',
|
||||
nameKey: 'SISUO_USER_NAME',
|
||||
headerTitle: '司索人',
|
||||
roleTitle: '司索人',
|
||||
),
|
||||
]
|
||||
|
||||
],
|
||||
),
|
||||
|
|
|
|||
|
|
@ -245,8 +245,6 @@ class SpecialWorkFormBaseWork extends StatelessWidget {
|
|||
],
|
||||
),
|
||||
),
|
||||
// if (FormUtils.hasValue(signs, 'SISUO'))
|
||||
// signItemWidget('SISUO', 'SISUO_USER_NAME', '司索人', context),
|
||||
|
||||
// 其他安全防护措施
|
||||
if (FormUtils.hasValue(signs, 'MEASURES_CONFIRM'))
|
||||
|
|
@ -262,135 +260,89 @@ class SpecialWorkFormBaseWork extends StatelessWidget {
|
|||
],
|
||||
),
|
||||
),
|
||||
|
||||
// 各环节签字及意见
|
||||
if (FormUtils.hasValue(signs, 'GUARDIAN'))
|
||||
signItemWidget('GUARDIAN', 'GUARDIAN_USER_NAME', '监护人', context),
|
||||
|
||||
ConfirmWithSignWidget(
|
||||
signs: signs,
|
||||
pd: pd,
|
||||
baseImgPath: baseImgPath,
|
||||
sectionKey: 'GUARDIAN',
|
||||
nameKey: 'GUARDIAN_USER_NAME',
|
||||
headerTitle: '监护人签字',
|
||||
roleTitle: '监护人',
|
||||
),
|
||||
if (FormUtils.hasValue(signs, 'CONFESS'))
|
||||
signItemWidget('CONFESS', 'CONFESS_USER_NAME', '安全交底人', context),
|
||||
|
||||
ConfirmWithSignWidget(
|
||||
signs: signs,
|
||||
pd: pd,
|
||||
baseImgPath: baseImgPath,
|
||||
sectionKey: 'CONFESS',
|
||||
nameKey: 'CONFESS_USER_NAME',
|
||||
headerTitle: '安全交底人',
|
||||
roleTitle: '安全交底人',
|
||||
),
|
||||
if (FormUtils.hasValue(signs, 'ACCEPT_CONFESS'))
|
||||
signItemWidget('ACCEPT_CONFESS', 'ACCEPT_CONFESS_USER_NAME', '接受交底人', context),
|
||||
ConfirmWithSignWidget(
|
||||
signs: signs,
|
||||
pd: pd,
|
||||
baseImgPath: baseImgPath,
|
||||
sectionKey: 'ACCEPT_CONFESS',
|
||||
nameKey: 'ACCEPT_CONFESS_USER_NAME',
|
||||
headerTitle: '接受交底人',
|
||||
roleTitle: '',
|
||||
),
|
||||
|
||||
// 作业负责人意见
|
||||
if (FormUtils.hasValue(signs, 'CONFIRM')) ...[
|
||||
Column(
|
||||
children: [
|
||||
_itemContainer(
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Padding(padding: EdgeInsets.symmetric(horizontal: 8), child: ListItemFactory.headerTitle('作业负责人意见'),),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Text(signs['CONFIRM'][0]['DESCR'] ?? ''),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Divider(height: 1,),
|
||||
signItemWidget('CONFIRM', 'CONFIRM_USER_NAME', '作业负责人', context),
|
||||
],
|
||||
)
|
||||
if (FormUtils.hasValue(signs, 'HOISTING_CONDUCTOR'))
|
||||
ConfirmWithSignWidget(
|
||||
signs: signs,
|
||||
pd: pd,
|
||||
baseImgPath: baseImgPath,
|
||||
sectionKey: 'HOISTING_CONDUCTOR',
|
||||
nameKey: 'HOISTING_CONDUCTOR_USER_NAME',
|
||||
headerTitle: '作业指挥意见',
|
||||
roleTitle: '',
|
||||
),
|
||||
|
||||
],
|
||||
if (FormUtils.hasValue(signs, 'LEADER'))
|
||||
ConfirmWithSignWidget(
|
||||
signs: signs,
|
||||
pd: pd,
|
||||
baseImgPath: baseImgPath,
|
||||
sectionKey: 'LEADER',
|
||||
nameKey: 'LEADER_USER_NAME',
|
||||
headerTitle: '所在单位意见',
|
||||
roleTitle: '',
|
||||
),
|
||||
if (FormUtils.hasValue(signs, 'AUDIT'))
|
||||
ConfirmWithSignWidget(
|
||||
signs: signs,
|
||||
pd: pd,
|
||||
baseImgPath: baseImgPath,
|
||||
sectionKey: 'AUDIT',
|
||||
nameKey: 'AUDIT_USER_NAME',
|
||||
headerTitle: '审核部门意见',
|
||||
roleTitle: '',
|
||||
),
|
||||
if (FormUtils.hasValue(signs, 'APPROVE'))
|
||||
ConfirmWithSignWidget(
|
||||
signs: signs,
|
||||
pd: pd,
|
||||
baseImgPath: baseImgPath,
|
||||
sectionKey: 'APPROVE',
|
||||
nameKey: 'APPROVE_USER_NAME',
|
||||
headerTitle: '审批部门意见',
|
||||
roleTitle: '审批部门负责人',
|
||||
),
|
||||
if (FormUtils.hasValue(signs, 'ACCEPT'))
|
||||
ConfirmWithSignWidget(
|
||||
signs: signs,
|
||||
pd: pd,
|
||||
baseImgPath: baseImgPath,
|
||||
sectionKey: 'ACCEPT',
|
||||
nameKey: 'ACCEPT_USER_NAME',
|
||||
headerTitle: '验收部门负责人意见',
|
||||
roleTitle: '验收部门负责人',
|
||||
),
|
||||
|
||||
// 所在单位负责人意见
|
||||
if (FormUtils.hasValue(signs, 'LEADER')) ...[
|
||||
Column(
|
||||
children: [
|
||||
_itemContainer(
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Padding(padding: EdgeInsets.symmetric(horizontal: 8), child: ListItemFactory.headerTitle('所在单位意见'),),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Text(signs['LEADER'][0]['DESCR'] ?? ''),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Divider(height: 1,),
|
||||
signItemWidget('LEADER', 'LEADER_USER_NAME', '所在单位负责人', context),
|
||||
],
|
||||
)
|
||||
],
|
||||
|
||||
// 安全管理部门负责人意见
|
||||
if (FormUtils.hasValue(signs, 'AUDIT')) ...[
|
||||
Column(
|
||||
children: [
|
||||
_itemContainer(
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Padding(padding: EdgeInsets.symmetric(horizontal: 8), child: ListItemFactory.headerTitle('安全管理部门意见'),),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Text(signs['AUDIT'][0]['DESCR'] ?? ''),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Divider(height: 1,),
|
||||
signItemWidget('AUDIT', 'AUDIT_USER_NAME', '安全管理部门负责人', context),
|
||||
],
|
||||
)
|
||||
],
|
||||
|
||||
// 审批人意见
|
||||
if (FormUtils.hasValue(signs, 'APPROVE')) ...[
|
||||
Column(
|
||||
children: [
|
||||
_itemContainer(
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Padding(padding: EdgeInsets.symmetric(horizontal: 8), child: ListItemFactory.headerTitle('审批人意见'),),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Text(signs['APPROVE'][0]['DESCR'] ?? ''),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Divider(height: 1,),
|
||||
signItemWidget('APPROVE', 'APPROVE_USER_NAME', '审批负责人', context),
|
||||
],
|
||||
)
|
||||
],
|
||||
|
||||
// 作业开始负责人签字
|
||||
// if (FormUtils.hasValue(signs, 'WORK_START'))
|
||||
// signItemWidget('WORK_START', 'WORK_START_USER_NAME', '作业开始负责人', context),
|
||||
//
|
||||
// // 作业结束负责人签字
|
||||
// if (FormUtils.hasValue(signs, 'WORK_END'))
|
||||
// signItemWidget('WORK_END', 'WORK_END_USER_NAME', '作业结束负责人', context),
|
||||
|
||||
// 完工验收意见和签字
|
||||
if (FormUtils.hasValue(signs, 'ACCEPT')) ...[
|
||||
Column(
|
||||
children: [
|
||||
_itemContainer(
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Padding(padding: EdgeInsets.symmetric(horizontal: 8), child: ListItemFactory.headerTitle('完工验收意见'),),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Text(signs['ACCEPT'][0]['DESCR'] ?? ''),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Divider(height: 1,),
|
||||
signItemWidget('ACCEPT', 'ACCEPT_USER_NAME', '验收部门负责人', context),
|
||||
],
|
||||
)
|
||||
],
|
||||
],
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,15 +19,13 @@ import 'package:intl/intl.dart';
|
|||
import 'package:qhd_prevention/pages/home/tap/workArea_picker.dart';
|
||||
import 'package:qhd_prevention/customWidget/BaiDuMap/Map_page.dart';
|
||||
|
||||
|
||||
enum EditUserType {
|
||||
SISUO('司索人单位', '司索人', true),
|
||||
GUARDIAN('监护人单位', '监护人', true),
|
||||
CONFESS('安全交底人单位', '安全交底人', true),
|
||||
ACCEPT_CONFESS('接受交底人单位', '接受交底人', true),
|
||||
WORK_USER('作业人单位', '作业人', true),
|
||||
CONFIRM('作业负责人单位', '作业负责人', true),
|
||||
PROJECT_MANAGER('吊装指挥单位', '吊装指挥负责人', true),
|
||||
WORK_USER('作业人单位', '吊装作业人', true),
|
||||
PROJECT_MANAGER('作业指挥单位', '作业指挥负责人', true),
|
||||
LEADER('所在单位', '所在单位负责人', true),
|
||||
AUDIT('审核部门', '审核部门负责人', true),
|
||||
APPROVE('审批部门', '审批部门负责人', true),
|
||||
|
|
@ -68,13 +66,17 @@ class _HoistworkApplyDetailState extends State<HoistworkApplyDetail> {
|
|||
late Map<String, dynamic> pd = {};
|
||||
late Map<String, dynamic> signs = {};
|
||||
late List<Map<String, dynamic>> measuresList = [];
|
||||
|
||||
/// ------------------- 新增 -------------------
|
||||
/// 视频监控摄像
|
||||
late List<dynamic> videoMonitoringList = [];
|
||||
|
||||
/// 承包商列表
|
||||
late List<dynamic> unitAllList = [];
|
||||
|
||||
/// 作业区域列表
|
||||
late List<Map<String, dynamic>> workAreaList = [];
|
||||
|
||||
/// --------------------------------------
|
||||
final TextEditingController _locationController = TextEditingController();
|
||||
final TextEditingController _hightController = TextEditingController();
|
||||
|
|
@ -83,8 +85,6 @@ class _HoistworkApplyDetailState extends State<HoistworkApplyDetail> {
|
|||
final TextEditingController _relatedController = TextEditingController();
|
||||
final TextEditingController _riskController = TextEditingController();
|
||||
|
||||
|
||||
|
||||
// 存储各单位的人员列表
|
||||
final Map<EditUserType, List<Map<String, dynamic>>> _personCache = {};
|
||||
|
||||
|
|
@ -102,7 +102,6 @@ class _HoistworkApplyDetailState extends State<HoistworkApplyDetail> {
|
|||
pd['APPLY_USER_ID'] = SessionService.instance.loginUserId;
|
||||
pd['APPLY_USER_NAME'] = SessionService.instance.username;
|
||||
pd['IS_CONTRACTOR_WORK'] = '0';
|
||||
|
||||
}
|
||||
_getVideoList();
|
||||
_getUnitListAll();
|
||||
|
|
@ -121,6 +120,19 @@ class _HoistworkApplyDetailState extends State<HoistworkApplyDetail> {
|
|||
|
||||
_hightController.addListener(() {
|
||||
pd['PART_WEIGHT'] = _hightController.text.trim();
|
||||
setState(() {
|
||||
double height = double.parse(pd['PART_WEIGHT']);
|
||||
int level = 0;
|
||||
if (height > 100.0) {
|
||||
level = 1;
|
||||
} else if (height >= 40.0 && height <= 100.0) {
|
||||
level = 2;
|
||||
} else {
|
||||
level = 3;
|
||||
}
|
||||
pd['WORK_LEVEL'] = level;
|
||||
pd['WORK_LEVEL_NAME'] = levelList[level - 1].toString();
|
||||
});
|
||||
});
|
||||
_relatedController.addListener(() {
|
||||
pd['SPECIAL_WORK'] = _relatedController.text.trim();
|
||||
|
|
@ -129,15 +141,16 @@ class _HoistworkApplyDetailState extends State<HoistworkApplyDetail> {
|
|||
pd['RISK_IDENTIFICATION'] = _riskController.text.trim();
|
||||
});
|
||||
}
|
||||
|
||||
/// ---------------------------- 新增 --------------------------------
|
||||
/// 视频监控摄像头
|
||||
Future<void> _chooseVideoManager() async {
|
||||
final choice = await BottomPicker.show<String>(
|
||||
context,
|
||||
items:
|
||||
videoMonitoringList
|
||||
.map((item) => item['VIDEONAME'] as String)
|
||||
.toList(),
|
||||
videoMonitoringList
|
||||
.map((item) => item['VIDEONAME'] as String)
|
||||
.toList(),
|
||||
itemBuilder: (item) => Text(item, textAlign: TextAlign.center),
|
||||
initialIndex: 0,
|
||||
);
|
||||
|
|
@ -146,7 +159,7 @@ class _HoistworkApplyDetailState extends State<HoistworkApplyDetail> {
|
|||
pd['VIDEONAME'] = choice;
|
||||
|
||||
Map<String, dynamic> result = videoMonitoringList.firstWhere(
|
||||
(item) => item['VIDEONAME'] == choice,
|
||||
(item) => item['VIDEONAME'] == choice,
|
||||
orElse: () => {}, // 避免找不到时报错
|
||||
);
|
||||
if (FormUtils.hasValue(result, 'VIDEOMANAGER_ID')) {
|
||||
|
|
@ -156,6 +169,7 @@ class _HoistworkApplyDetailState extends State<HoistworkApplyDetail> {
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// 选择承包商
|
||||
Future<void> _chooseUnitManager() async {
|
||||
final choice = await BottomPicker.show<String>(
|
||||
|
|
@ -169,7 +183,7 @@ class _HoistworkApplyDetailState extends State<HoistworkApplyDetail> {
|
|||
pd['UNITS_NAME'] = choice;
|
||||
|
||||
Map<String, dynamic> result = unitAllList.firstWhere(
|
||||
(item) => item['UNITS_NAME'] == choice,
|
||||
(item) => item['UNITS_NAME'] == choice,
|
||||
orElse: () => {}, // 避免找不到时报错
|
||||
);
|
||||
if (FormUtils.hasValue(result, 'UNITS_ID')) {
|
||||
|
|
@ -179,10 +193,9 @@ class _HoistworkApplyDetailState extends State<HoistworkApplyDetail> {
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// 选择经纬度
|
||||
Future<void> _showLocationHandle() async{
|
||||
Future<void> _showLocationHandle() async {
|
||||
if (!FormUtils.hasValue(pd, 'ELECTRONIC_FENCE_AREA_ID')) {
|
||||
ToastUtil.showNormal(context, '请选择作业区域');
|
||||
return;
|
||||
|
|
@ -191,10 +204,11 @@ class _HoistworkApplyDetailState extends State<HoistworkApplyDetail> {
|
|||
setState(() {
|
||||
pd['LONGITUDE'] = mapData['longitue'] ?? '';
|
||||
pd['LATITUDE'] = mapData['latitude'] ?? '';
|
||||
pd['LATITUDE_LONGITUDE'] = '${mapData['longitue'] ?? ''},${mapData['latitude'] ?? ''}';
|
||||
pd['LATITUDE_LONGITUDE'] =
|
||||
'${mapData['longitue'] ?? ''},${mapData['latitude'] ?? ''}';
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/// 作业区域
|
||||
Future<void> _getWorkArea() async {
|
||||
//FocusHelper.clearFocus(context);
|
||||
|
|
@ -205,16 +219,19 @@ class _HoistworkApplyDetailState extends State<HoistworkApplyDetail> {
|
|||
backgroundColor: Colors.transparent,
|
||||
builder:
|
||||
(_) => WorkAreaPicker(
|
||||
onSelected: (String id, String POSITIONS, String name) {
|
||||
pd['ELECTRONIC_FENCE_AREA_ID'] = id;
|
||||
pd['POSITIONS'] = POSITIONS;
|
||||
pd['PLS_NAME'] = name;
|
||||
},
|
||||
),
|
||||
onSelected: (String id, String POSITIONS, String name) {
|
||||
setState(() {
|
||||
pd['ELECTRONIC_FENCE_AREA_ID'] = id;
|
||||
pd['POSITIONS'] = POSITIONS;
|
||||
pd['PLS_NAME'] = name;
|
||||
});
|
||||
},
|
||||
),
|
||||
).then((_) {
|
||||
//FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
|
||||
/// 获取摄像头列表
|
||||
Future<void> _getVideoList() async {
|
||||
final result = await ApiService.getVideomanagerList();
|
||||
|
|
@ -222,6 +239,7 @@ class _HoistworkApplyDetailState extends State<HoistworkApplyDetail> {
|
|||
videoMonitoringList = result['varList'] ?? [];
|
||||
});
|
||||
}
|
||||
|
||||
/// 获承包商列表
|
||||
Future<void> _getUnitListAll() async {
|
||||
final result = await ApiService.getUnitListAll();
|
||||
|
|
@ -229,6 +247,7 @@ class _HoistworkApplyDetailState extends State<HoistworkApplyDetail> {
|
|||
unitAllList = result['varList'] ?? [];
|
||||
});
|
||||
}
|
||||
|
||||
/// 作业区域列表
|
||||
Future<void> _getPlsList() async {
|
||||
final result = await ApiService.getWorkAreaList();
|
||||
|
|
@ -237,6 +256,7 @@ class _HoistworkApplyDetailState extends State<HoistworkApplyDetail> {
|
|||
workAreaList = jsonDecode(zTreeNodes);
|
||||
});
|
||||
}
|
||||
|
||||
/// ------------------------------------------------------------
|
||||
void set_pd_DEPARTMENT_ID(EditUserType type, String id) {
|
||||
pd['${type.name}_DEPARTMENT_ID'] = id;
|
||||
|
|
@ -249,7 +269,7 @@ class _HoistworkApplyDetailState extends State<HoistworkApplyDetail> {
|
|||
void set_pd_USER_ID(EditUserType type, String id) {
|
||||
if (type == EditUserType.WORK_USER) {
|
||||
pd['${type.name}_ID'] = id;
|
||||
}else{
|
||||
} else {
|
||||
pd['${type.name}_USER_ID'] = id;
|
||||
}
|
||||
}
|
||||
|
|
@ -269,7 +289,7 @@ class _HoistworkApplyDetailState extends State<HoistworkApplyDetail> {
|
|||
String get_pd_USER_ID(EditUserType type) {
|
||||
if (type == EditUserType.WORK_USER) {
|
||||
return pd['${type.name}_ID'] ?? '';
|
||||
}else{
|
||||
} else {
|
||||
return pd['${type.name}_USER_ID'] ?? '';
|
||||
}
|
||||
}
|
||||
|
|
@ -278,23 +298,6 @@ class _HoistworkApplyDetailState extends State<HoistworkApplyDetail> {
|
|||
return pd['${type.name}_USER_NAME'] ?? '';
|
||||
}
|
||||
|
||||
Future<void> _chooseLevel() async {
|
||||
final choice = await BottomPicker.show<String>(
|
||||
context,
|
||||
items: levelList,
|
||||
itemBuilder: (item) => Text(item, textAlign: TextAlign.center),
|
||||
initialIndex: 0,
|
||||
);
|
||||
if (choice != null) {
|
||||
// 用户点击确定并选择了 choice
|
||||
setState(() {
|
||||
pd['WORK_LEVEL_NAME'] = choice;
|
||||
pd['WORK_LEVEL'] = (levelList.indexOf(choice) + 1).toString();
|
||||
//FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Widget _card(Widget child) {
|
||||
return Container(
|
||||
padding: EdgeInsets.symmetric(vertical: 5),
|
||||
|
|
@ -390,13 +393,15 @@ class _HoistworkApplyDetailState extends State<HoistworkApplyDetail> {
|
|||
return;
|
||||
}
|
||||
|
||||
if (personList.isEmpty) { // 一般这种情况是因为重新编辑没有缓存对应部门的负责人,所以先拉取一下接口
|
||||
if (personList.isEmpty) {
|
||||
// 一般这种情况是因为重新编辑没有缓存对应部门的负责人,所以先拉取一下接口
|
||||
await _getPersonListForUnitId(unitId, type);
|
||||
final list = _personCache[type] ?? [];
|
||||
|
||||
if (list.isEmpty) { // 如果还是没数据,说明该部门没有可选的人
|
||||
if (list.isEmpty) {
|
||||
// 如果还是没数据,说明该部门没有可选的人
|
||||
ToastUtil.showNormal(context, '暂无数据,请选择其他单位');
|
||||
}else{
|
||||
} else {
|
||||
choosePersonHandle(type);
|
||||
}
|
||||
return;
|
||||
|
|
@ -443,12 +448,10 @@ class _HoistworkApplyDetailState extends State<HoistworkApplyDetail> {
|
|||
EditUserType.GUARDIAN,
|
||||
EditUserType.CONFESS,
|
||||
EditUserType.ACCEPT_CONFESS,
|
||||
EditUserType.CONFIRM,
|
||||
EditUserType.LEADER,
|
||||
EditUserType.PROJECT_MANAGER,
|
||||
EditUserType.AUDIT,
|
||||
if (pd['WORK_LEVEL'] == '1')
|
||||
EditUserType.APPROVE,
|
||||
if (pd['WORK_LEVEL'] == '1') EditUserType.APPROVE,
|
||||
EditUserType.WORK_USER,
|
||||
EditUserType.WORK_START,
|
||||
EditUserType.WORK_END,
|
||||
|
|
@ -462,11 +465,7 @@ class _HoistworkApplyDetailState extends State<HoistworkApplyDetail> {
|
|||
return;
|
||||
}
|
||||
}
|
||||
// 级别校验
|
||||
if (level.length == 0) {
|
||||
ToastUtil.showNormal(context, '请选择作业级别');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!FormUtils.hasValue(pd, 'WORK_EXPECTED_START_TIME')) {
|
||||
ToastUtil.showNormal(context, '请选择预计作业开始时间');
|
||||
return;
|
||||
|
|
@ -476,7 +475,8 @@ class _HoistworkApplyDetailState extends State<HoistworkApplyDetail> {
|
|||
return;
|
||||
}
|
||||
|
||||
if (pd['IS_CONTRACTOR_WORK'] == '1' && !FormUtils.hasValue(pd, 'UNITS_ID')) {
|
||||
if (pd['IS_CONTRACTOR_WORK'] == '1' &&
|
||||
!FormUtils.hasValue(pd, 'UNITS_ID')) {
|
||||
ToastUtil.showNormal(context, '请选择承包商');
|
||||
return;
|
||||
}
|
||||
|
|
@ -499,9 +499,9 @@ class _HoistworkApplyDetailState extends State<HoistworkApplyDetail> {
|
|||
// LoadingDialogHelper.show();
|
||||
|
||||
String taskId = '0';
|
||||
if (pd['WORK_LEVEL'] == '1') {
|
||||
if (pd['WORK_LEVEL'] == 1) {
|
||||
taskId = '10';
|
||||
} else if (pd['WORK_LEVEL'] == '2' || pd['WORK_LEVEL'] == '3') {
|
||||
} else if (pd['WORK_LEVEL'] == 2 || pd['WORK_LEVEL'] == 3) {
|
||||
taskId = '11';
|
||||
}
|
||||
pd['USER_ID'] = SessionService.instance.loginUserId;
|
||||
|
|
@ -550,8 +550,10 @@ class _HoistworkApplyDetailState extends State<HoistworkApplyDetail> {
|
|||
|
||||
/// 初始化拉取数据
|
||||
Future<void> _getData() async {
|
||||
|
||||
final data = await ApiService.getHomeworkFindById('hoisting', widget.HOISTING_ID);
|
||||
final data = await ApiService.getHomeworkFindById(
|
||||
'hoisting',
|
||||
widget.HOISTING_ID,
|
||||
);
|
||||
setState(() {
|
||||
pd = data['pd'];
|
||||
if (pd['STEP_ID'] == 0) {
|
||||
|
|
@ -577,7 +579,8 @@ class _HoistworkApplyDetailState extends State<HoistworkApplyDetail> {
|
|||
}
|
||||
|
||||
Future<void> _getSigns(String homework_id) async {
|
||||
final data = await ApiService.listSignFinished('hoisting',
|
||||
final data = await ApiService.listSignFinished(
|
||||
'hoisting',
|
||||
homework_id.length > 0 ? homework_id : widget.HOISTING_ID,
|
||||
);
|
||||
setState(() {
|
||||
|
|
@ -586,7 +589,8 @@ class _HoistworkApplyDetailState extends State<HoistworkApplyDetail> {
|
|||
}
|
||||
|
||||
Future<void> _getMeasures(String homework_id) async {
|
||||
final data = await ApiService.listSignFinishMeasures('hoisting',
|
||||
final data = await ApiService.listSignFinishMeasures(
|
||||
'hoisting',
|
||||
homework_id.length > 0 ? homework_id : widget.HOISTING_ID,
|
||||
);
|
||||
setState(() {
|
||||
|
|
@ -617,7 +621,7 @@ class _HoistworkApplyDetailState extends State<HoistworkApplyDetail> {
|
|||
hightController: _hightController,
|
||||
relatedController: _relatedController,
|
||||
riskController: _riskController,
|
||||
onChooseLevel: _chooseLevel,
|
||||
onChooseLevel: () {},
|
||||
// 新增
|
||||
onChooseVideoManager: _chooseVideoManager,
|
||||
onContractorHandle: _chooseUnitManager,
|
||||
|
|
@ -640,8 +644,6 @@ class _HoistworkApplyDetailState extends State<HoistworkApplyDetail> {
|
|||
SizedBox(height: 15),
|
||||
_card(_chooseItem(EditUserType.WORK_USER)),
|
||||
SizedBox(height: 15),
|
||||
_card(_chooseItem(EditUserType.CONFIRM)),
|
||||
SizedBox(height: 15),
|
||||
_card(_chooseItem(EditUserType.PROJECT_MANAGER)),
|
||||
SizedBox(height: 15),
|
||||
_card(_chooseItem(EditUserType.LEADER)),
|
||||
|
|
@ -703,7 +705,7 @@ class _HoistworkApplyDetailState extends State<HoistworkApplyDetail> {
|
|||
color: Colors.white,
|
||||
child: MeasuresListWidget(
|
||||
measuresList:
|
||||
measuresList, // List<Map<String, dynamic>>
|
||||
measuresList, // List<Map<String, dynamic>>
|
||||
baseImgPath: ApiService.baseImgPath,
|
||||
isAllowEdit: false,
|
||||
),
|
||||
|
|
@ -731,45 +733,9 @@ class _HoistworkApplyDetailState extends State<HoistworkApplyDetail> {
|
|||
),
|
||||
isEditable
|
||||
? Row(
|
||||
spacing: 10,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Expanded(
|
||||
child: CustomButton(
|
||||
height: 45,
|
||||
textStyle: TextStyle(
|
||||
fontSize: 16,
|
||||
color: Colors.white,
|
||||
),
|
||||
text: '提交',
|
||||
backgroundColor: Colors.blue,
|
||||
onPressed: () {
|
||||
_submit('1');
|
||||
},
|
||||
),
|
||||
),
|
||||
|
||||
Expanded(
|
||||
child: CustomButton(
|
||||
textStyle: TextStyle(
|
||||
fontSize: 16,
|
||||
color: Colors.white,
|
||||
),
|
||||
text: '暂存',
|
||||
backgroundColor: Colors.green,
|
||||
onPressed: () {
|
||||
_submit('0');
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
: Column(
|
||||
children: [
|
||||
SizedBox(height: 20),
|
||||
Row(
|
||||
spacing: 10,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
SizedBox(width: 50),
|
||||
Expanded(
|
||||
child: CustomButton(
|
||||
height: 45,
|
||||
|
|
@ -777,18 +743,54 @@ class _HoistworkApplyDetailState extends State<HoistworkApplyDetail> {
|
|||
fontSize: 16,
|
||||
color: Colors.white,
|
||||
),
|
||||
text: '返回',
|
||||
backgroundColor: Colors.green,
|
||||
text: '提交',
|
||||
backgroundColor: Colors.blue,
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
_submit('1');
|
||||
},
|
||||
),
|
||||
),
|
||||
SizedBox(width: 50),
|
||||
|
||||
Expanded(
|
||||
child: CustomButton(
|
||||
textStyle: TextStyle(
|
||||
fontSize: 16,
|
||||
color: Colors.white,
|
||||
),
|
||||
text: '暂存',
|
||||
backgroundColor: Colors.green,
|
||||
onPressed: () {
|
||||
_submit('0');
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
: Column(
|
||||
children: [
|
||||
SizedBox(height: 20),
|
||||
Row(
|
||||
children: [
|
||||
SizedBox(width: 50),
|
||||
Expanded(
|
||||
child: CustomButton(
|
||||
height: 45,
|
||||
textStyle: TextStyle(
|
||||
fontSize: 16,
|
||||
color: Colors.white,
|
||||
),
|
||||
text: '返回',
|
||||
backgroundColor: Colors.green,
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
),
|
||||
),
|
||||
SizedBox(width: 50),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -60,7 +60,6 @@ class _HoistworkListPageState extends State<HoistworkListPage> {
|
|||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_fetchSteps();
|
||||
_fetchData();
|
||||
_scrollController.addListener(_onScroll);
|
||||
}
|
||||
|
|
@ -140,9 +139,11 @@ class _HoistworkListPageState extends State<HoistworkListPage> {
|
|||
}
|
||||
|
||||
/// 申请
|
||||
void _handleApply() {
|
||||
void _handleApply() async{
|
||||
// 处理申请按钮点击逻辑
|
||||
pushPage(HoistworkApplyDetail(HOISTING_ID: '', flow: widget.flow), context);
|
||||
await pushPage(HoistworkApplyDetail(HOISTING_ID: '', flow: widget.flow), context);
|
||||
_fetchData();
|
||||
LoadingDialogHelper.hide();
|
||||
}
|
||||
|
||||
/// 打开流程图
|
||||
|
|
@ -201,9 +202,9 @@ class _HoistworkListPageState extends State<HoistworkListPage> {
|
|||
case '作业人签字':
|
||||
await pushPage(HoistworkZyrDetail(HOISTING_ID: item['HOISTING_ID'], flow: widget.flow), context);
|
||||
break;
|
||||
case '作业负责人签字':
|
||||
await pushPage(HoistworkZyfzDetail(HOISTING_ID: item['HOISTING_ID'], flow: widget.flow), context);
|
||||
break;
|
||||
// case '作业负责人签字':
|
||||
// await pushPage(HoistworkZyfzDetail(HOISTING_ID: item['HOISTING_ID'], flow: widget.flow), context);
|
||||
// break;
|
||||
case '吊装指挥人签字':
|
||||
await pushPage(HoistworkDzzhDetail(HOISTING_ID: item['HOISTING_ID'], flow: widget.flow), context);
|
||||
break;
|
||||
|
|
@ -231,9 +232,10 @@ class _HoistworkListPageState extends State<HoistworkListPage> {
|
|||
default:
|
||||
break;
|
||||
}
|
||||
LoadingDialogHelper.show();
|
||||
_fetchSteps();
|
||||
_fetchData();
|
||||
|
||||
|
||||
await _fetchData();
|
||||
LoadingDialogHelper.hide();
|
||||
}
|
||||
|
||||
Widget _buildFlowStepItem({
|
||||
|
|
|
|||
|
|
@ -207,6 +207,7 @@ class _HoistworkJszyDetailState extends State<HoistworkJszyDetail> {
|
|||
child: SingleChildScrollView(
|
||||
padding: EdgeInsets.all(12),
|
||||
child: Column(
|
||||
spacing: 12,
|
||||
children: [
|
||||
// _setSafeDetailWidget(),
|
||||
SpecialWorkFormBaseWork(
|
||||
|
|
@ -246,7 +247,6 @@ class _HoistworkJszyDetailState extends State<HoistworkJszyDetail> {
|
|||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 12,),
|
||||
_bottomButtons(),
|
||||
],
|
||||
),
|
||||
|
|
|
|||
|
|
@ -189,6 +189,7 @@ class _HoistworkKszyDetailState extends State<HoistworkKszyDetail> {
|
|||
child: SingleChildScrollView(
|
||||
padding: EdgeInsets.all(12),
|
||||
child: Column(
|
||||
spacing: 12,
|
||||
children: [
|
||||
// _setSafeDetailWidget(),
|
||||
SpecialWorkFormBaseWork(
|
||||
|
|
@ -235,7 +236,6 @@ class _HoistworkKszyDetailState extends State<HoistworkKszyDetail> {
|
|||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 12,),
|
||||
_bottomButtons(),
|
||||
],
|
||||
),
|
||||
|
|
|
|||
|
|
@ -186,6 +186,7 @@ class _HoistworkSsrDetailState extends State<HoistworkSsrDetail> {
|
|||
|
||||
/// 初始化拉取数据
|
||||
Future<void> _getData() async {
|
||||
LoadingDialogHelper.show();
|
||||
final data = await ApiService.getHomeworkFindById(
|
||||
'hoisting',
|
||||
widget.HOISTING_ID,
|
||||
|
|
@ -196,6 +197,7 @@ class _HoistworkSsrDetailState extends State<HoistworkSsrDetail> {
|
|||
_getSigns(pd['HOISTING_ID'] ?? '');
|
||||
_getMeasures(pd['HOISTING_ID'] ?? '');
|
||||
});
|
||||
LoadingDialogHelper.hide();
|
||||
}
|
||||
|
||||
Future<void> _getMeasures(String homework_id) async {
|
||||
|
|
|
|||
|
|
@ -359,7 +359,7 @@ class _HoistworkSetSafeDetailState extends State<HoistworkSetSafeDetail> {
|
|||
}
|
||||
|
||||
Future<void> _getMeasures() async {
|
||||
final data = await ApiService.listSignFinishAllMeasures('hoisting');
|
||||
final data = await ApiService.listSignFinishAllMeasures('hoisting', widget.HOISTING_ID);
|
||||
setState(() {
|
||||
measuresList = List<Map<String, dynamic>>.from(
|
||||
data['measuresList'] ?? <Map<String, dynamic>>[],
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
|
|||
import 'package:qhd_prevention/customWidget/ItemWidgetFactory.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:qhd_prevention/customWidget/picker/CupertinoDatePicker.dart';
|
||||
import 'package:qhd_prevention/customWidget/single_image_viewer.dart';
|
||||
import '../../../../../../tools/tools.dart';
|
||||
import '../../../item_list_widget.dart';
|
||||
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/MeasuresListWidget.dart';
|
||||
|
|
@ -9,29 +10,40 @@ import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/MeasuresListW
|
|||
/// 通用高处作业明细表单组件(支持编辑/只读)
|
||||
class HighWorkDetailFormWidget extends StatefulWidget {
|
||||
final Map<String, dynamic> pd;
|
||||
|
||||
/// 其他签字数据
|
||||
final Map<String, dynamic> signs;
|
||||
final bool isEditable;
|
||||
final VoidCallback onChooseLevel;
|
||||
// 新增
|
||||
/// 选择摄像头
|
||||
final VoidCallback? onChooseVideoManager;/// 承包商
|
||||
|
||||
// 新增
|
||||
/// 选择摄像头
|
||||
final VoidCallback? onChooseVideoManager;
|
||||
|
||||
/// 承包商
|
||||
final VoidCallback? onContractorHandle;
|
||||
|
||||
/// 作业区域
|
||||
final VoidCallback? onWorkAreaHandle;
|
||||
|
||||
/// 作业地点经纬度
|
||||
final VoidCallback? onWorkAreaLocationHandle;
|
||||
|
||||
/// 编辑模式下需提供以下控制器,非编辑模式可不传
|
||||
final TextEditingController? locationController; // 地点
|
||||
final TextEditingController? hightController; // 高度
|
||||
final TextEditingController? contentController; // 内容、
|
||||
final TextEditingController? hightController; // 高度
|
||||
final TextEditingController? contentController; // 内容、
|
||||
final TextEditingController? relatedController;
|
||||
final TextEditingController? riskController;
|
||||
|
||||
const HighWorkDetailFormWidget({
|
||||
Key? key,
|
||||
required this.pd,
|
||||
required this.signs,
|
||||
|
||||
required this.isEditable,
|
||||
required this.onChooseLevel,
|
||||
|
||||
/// 新增
|
||||
this.onChooseVideoManager,
|
||||
this.onContractorHandle,
|
||||
|
|
@ -44,35 +56,42 @@ class HighWorkDetailFormWidget extends StatefulWidget {
|
|||
this.relatedController,
|
||||
this.riskController,
|
||||
}) : assert(
|
||||
!isEditable ||
|
||||
(locationController != null &&
|
||||
hightController != null &&
|
||||
contentController != null &&
|
||||
relatedController != null &&
|
||||
riskController != null),
|
||||
'Editable mode requires all TextEditingController parameters',
|
||||
),
|
||||
super(key: key);
|
||||
!isEditable ||
|
||||
(locationController != null &&
|
||||
hightController != null &&
|
||||
contentController != null &&
|
||||
relatedController != null &&
|
||||
riskController != null),
|
||||
'Editable mode requires all TextEditingController parameters',
|
||||
),
|
||||
super(key: key);
|
||||
|
||||
@override
|
||||
State<HighWorkDetailFormWidget> createState() => _HighWorkDetailFormWidgetState();
|
||||
State<HighWorkDetailFormWidget> createState() =>
|
||||
_HighWorkDetailFormWidgetState();
|
||||
}
|
||||
|
||||
class _HighWorkDetailFormWidgetState extends State<HighWorkDetailFormWidget> {
|
||||
String _getWorkLevelText(dynamic level) {
|
||||
switch (level?.toString()) {
|
||||
case '1': return 'I级高处作业';
|
||||
case '2': return 'II级高处作业';
|
||||
case '3': return 'III级高处作业';
|
||||
case '4': return 'IV级高处作业';
|
||||
default: return '';
|
||||
case '1':
|
||||
return 'I级高处作业';
|
||||
case '2':
|
||||
return 'II级高处作业';
|
||||
case '3':
|
||||
return 'III级高处作业';
|
||||
case '4':
|
||||
return 'IV级高处作业';
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (FormUtils.hasValue(widget.pd, 'LATITUDE')) {
|
||||
widget.pd['LATITUDE_LONGITUDE'] = '${widget.pd['LATITUDE']},${widget.pd['LONGITUDE']}'; //参数map
|
||||
widget.pd['LATITUDE_LONGITUDE'] =
|
||||
'${widget.pd['LATITUDE']},${widget.pd['LONGITUDE']}'; //参数map
|
||||
}
|
||||
final pd = widget.pd;
|
||||
|
||||
|
|
@ -98,11 +117,23 @@ class _HighWorkDetailFormWidgetState extends State<HighWorkDetailFormWidget> {
|
|||
isEditable: false,
|
||||
text: pd['APPLY_DEPARTMENT_NAME'] ?? '',
|
||||
),
|
||||
const Divider(),
|
||||
|
||||
ItemListWidget.singleLineTitleText(
|
||||
label: '申请人:',
|
||||
isEditable: false,
|
||||
text: pd['APPLY_USER_NAME'] ?? '',
|
||||
),
|
||||
if (FormUtils.hasValue(pd, 'CREATTIME') && !widget.isEditable) ...[
|
||||
const Divider(),
|
||||
ItemListWidget.singleLineTitleText(
|
||||
label: '作业申请时间:',
|
||||
isEditable: false,
|
||||
text: pd['CREATTIME'] ?? '',
|
||||
),
|
||||
],
|
||||
const Divider(),
|
||||
|
||||
ItemListWidget.singleLineTitleText(
|
||||
label: '作业地点:',
|
||||
isEditable: widget.isEditable,
|
||||
|
|
@ -110,31 +141,76 @@ class _HighWorkDetailFormWidgetState extends State<HighWorkDetailFormWidget> {
|
|||
text: pd['WORK_PLACE'] ?? '',
|
||||
),
|
||||
const Divider(),
|
||||
ItemListWidget.singleLineTitleText(
|
||||
label: '作业高度(米):',
|
||||
keyboardType: TextInputType.numberWithOptions(
|
||||
decimal: true, // 允许小数点
|
||||
signed: false, // 允许负号(如需)
|
||||
),
|
||||
isEditable: widget.isEditable,
|
||||
controller: widget.hightController,
|
||||
text: pd['WORK_HIGH'] ?? '',
|
||||
),
|
||||
const Divider(),
|
||||
ItemListWidget.selectableLineTitleTextRightButton(
|
||||
label: '高处作业级别:',
|
||||
isEditable: widget.isEditable,
|
||||
onTap: widget.onChooseLevel,
|
||||
text: _getWorkLevelText(pd['WORK_LEVEL']),
|
||||
),
|
||||
const Divider(),
|
||||
ItemListWidget.multiLineTitleTextField(
|
||||
label: '作业内容:',
|
||||
isEditable: widget.isEditable,
|
||||
controller: widget.contentController,
|
||||
text: pd['WORK_CONTENT'] ?? '',
|
||||
),
|
||||
|
||||
const Divider(),
|
||||
ItemListWidget.singleLineTitleText(
|
||||
label: '作业高度(米):',
|
||||
keyboardType: TextInputType.numberWithOptions(
|
||||
decimal: true, // 允许小数点
|
||||
signed: false, // 允许负号(如需)
|
||||
),
|
||||
isEditable: widget.isEditable,
|
||||
controller: widget.hightController,
|
||||
text: pd['WORK_HIGH'] ?? '',
|
||||
),
|
||||
const Divider(),
|
||||
ItemListWidget.selectableLineTitleTextRightButton(
|
||||
label: '高处作业级别:',
|
||||
isTip: true,
|
||||
isEditable: false,
|
||||
isRequired: true,
|
||||
onTap: widget.onChooseLevel,
|
||||
onTapTip: () {
|
||||
presentOpaque(
|
||||
SingleImageViewer(imageUrl: 'assets/images/highwork_tip.jpg'),
|
||||
context,
|
||||
);
|
||||
},
|
||||
text: _getWorkLevelText(pd['WORK_LEVEL']),
|
||||
),
|
||||
if (FormUtils.hasValue(pd, 'CONFIRM_DEPARTMENT_NAME')) ...[
|
||||
const Divider(),
|
||||
ItemListWidget.singleLineTitleText(
|
||||
label: '作业单位:',
|
||||
isEditable: false,
|
||||
text: pd['CONFIRM_DEPARTMENT_NAME'] ?? '',
|
||||
),
|
||||
],
|
||||
if (FormUtils.hasValue(pd, 'WORK_USER_USER_NAME') &&
|
||||
!widget.isEditable) ...[
|
||||
const Divider(),
|
||||
SignRowImageTitle(
|
||||
label: '作业人:',
|
||||
signKey: 'WORK_USER',
|
||||
signs: widget.signs,
|
||||
text: pd['WORK_USER_USER_NAME'] ?? '',
|
||||
),
|
||||
],
|
||||
if (FormUtils.hasValue(pd, 'GUARDIAN_USER_NAME') &&
|
||||
!widget.isEditable) ...[
|
||||
const Divider(),
|
||||
SignRowImageTitle(
|
||||
label: '监护人:',
|
||||
signKey: 'GUARDIAN',
|
||||
signs: widget.signs,
|
||||
text: pd['GUARDIAN_USER_NAME'] ?? '',
|
||||
),
|
||||
],
|
||||
if (FormUtils.hasValue(pd, 'CONFIRM_USER_NAME') &&
|
||||
!widget.isEditable) ...[
|
||||
const Divider(),
|
||||
SignRowImageTitle(
|
||||
label: '作业负责人:',
|
||||
signKey: 'CONFIRM',
|
||||
signs: widget.signs,
|
||||
text: pd['CONFIRM_USER_NAME'] ?? '',
|
||||
),
|
||||
],
|
||||
const Divider(),
|
||||
ItemListWidget.twoRowButtonTitleText(
|
||||
label: '关联其他特殊作业及安全作业票编号',
|
||||
|
|
@ -143,16 +219,17 @@ class _HighWorkDetailFormWidgetState extends State<HighWorkDetailFormWidget> {
|
|||
onTap: () async {
|
||||
final val = await showDialog<String>(
|
||||
context: context,
|
||||
builder: (_) => SelectionPopup(
|
||||
type: 'assignments',
|
||||
initialValue: pd['SPECIAL_WORK'] ?? '',
|
||||
onConfirm: (v) {
|
||||
setState(() {
|
||||
pd['SPECIAL_WORK'] = v;
|
||||
widget.relatedController?.text = v;
|
||||
});
|
||||
},
|
||||
),
|
||||
builder:
|
||||
(_) => SelectionPopup(
|
||||
type: 'assignments',
|
||||
initialValue: pd['SPECIAL_WORK'] ?? '',
|
||||
onConfirm: (v) {
|
||||
setState(() {
|
||||
pd['SPECIAL_WORK'] = v;
|
||||
widget.relatedController?.text = v;
|
||||
});
|
||||
},
|
||||
),
|
||||
);
|
||||
//FocusHelper.clearFocus(context);
|
||||
},
|
||||
|
|
@ -167,16 +244,17 @@ class _HighWorkDetailFormWidgetState extends State<HighWorkDetailFormWidget> {
|
|||
onTap: () async {
|
||||
await showDialog<String>(
|
||||
context: context,
|
||||
builder: (_) => SelectionPopup(
|
||||
type: 'identification',
|
||||
initialValue: pd['RISK_IDENTIFICATION'] ?? '',
|
||||
onConfirm: (v) {
|
||||
setState(() {
|
||||
pd['RISK_IDENTIFICATION'] = v;
|
||||
widget.riskController?.text = v;
|
||||
});
|
||||
},
|
||||
),
|
||||
builder:
|
||||
(_) => SelectionPopup(
|
||||
type: 'identification',
|
||||
initialValue: pd['RISK_IDENTIFICATION'] ?? '',
|
||||
onConfirm: (v) {
|
||||
setState(() {
|
||||
pd['RISK_IDENTIFICATION'] = v;
|
||||
widget.riskController?.text = v;
|
||||
});
|
||||
},
|
||||
),
|
||||
);
|
||||
//FocusHelper.clearFocus(context);
|
||||
},
|
||||
|
|
@ -185,6 +263,7 @@ class _HighWorkDetailFormWidgetState extends State<HighWorkDetailFormWidget> {
|
|||
text: pd['RISK_IDENTIFICATION'] ?? '',
|
||||
),
|
||||
const Divider(),
|
||||
|
||||
ItemListWidget.selectableLineTitleTextRightButton(
|
||||
label: '作业视频监控:',
|
||||
isClean: widget.isEditable,
|
||||
|
|
@ -200,55 +279,67 @@ class _HighWorkDetailFormWidgetState extends State<HighWorkDetailFormWidget> {
|
|||
onTap: widget.onChooseVideoManager ?? () {},
|
||||
text: pd['VIDEONAME'] ?? '',
|
||||
),
|
||||
const Divider(),
|
||||
ItemListWidget.selectableLineTitleTextRightButton(
|
||||
label: '预计作业开始时间:',
|
||||
isEditable: widget.isEditable,
|
||||
onTap: () async {
|
||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||
mode: BottomPickerMode.dateTimeWithSeconds,
|
||||
context,
|
||||
allowFuture: true,
|
||||
);
|
||||
if (picked != null) {
|
||||
setState(() {
|
||||
pd['WORK_EXPECTED_START_TIME'] = DateFormat(
|
||||
'yyyy-MM-dd HH:mm:ss',
|
||||
).format(picked);
|
||||
if (FormUtils.hasValue(pd, 'WORK_START_DATE')) ...[
|
||||
const Divider(),
|
||||
ItemListWidget.selectableLineTitleTextRightButton(
|
||||
label: '作业实施时间:',
|
||||
isEditable: widget.isEditable,
|
||||
text:
|
||||
FormUtils.hasValue(pd, 'WORK_END_DATE')
|
||||
? '${pd['WORK_START_DATE'] ?? ''}\n-${pd['WORK_END_DATE'] ?? ''}'
|
||||
: pd['WORK_START_DATE'] ?? '',
|
||||
),
|
||||
] else ...[
|
||||
const Divider(),
|
||||
ItemListWidget.selectableLineTitleTextRightButton(
|
||||
label: '预计作业开始时间:',
|
||||
isEditable: widget.isEditable,
|
||||
onTap: () async {
|
||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||
mode: BottomPickerMode.dateTimeWithSeconds,
|
||||
context,
|
||||
allowFuture: true,
|
||||
);
|
||||
if (picked != null) {
|
||||
setState(() {
|
||||
pd['WORK_EXPECTED_START_TIME'] = DateFormat(
|
||||
'yyyy-MM-dd HH:mm:ss',
|
||||
).format(picked);
|
||||
|
||||
/// 开始时间必须早于结束时间
|
||||
if (FormUtils.hasValue(pd, 'WORK_EXPECTED_END_TIME') &&
|
||||
!isBeforeStr(
|
||||
pd['WORK_EXPECTED_START_TIME'],
|
||||
pd['WORK_EXPECTED_END_TIME'],
|
||||
)) {
|
||||
pd['WORK_EXPECTED_END_TIME'] = '';
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
text: pd['WORK_EXPECTED_START_TIME'] ?? '',
|
||||
),
|
||||
const Divider(),
|
||||
ItemListWidget.selectableLineTitleTextRightButton(
|
||||
label: '预计作业结束时间:',
|
||||
isEditable: widget.isEditable,
|
||||
onTap: () async {
|
||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||
context,
|
||||
minTimeStr: pd['WORK_EXPECTED_START_TIME'] ?? '',
|
||||
allowFuture: true,
|
||||
);
|
||||
if (picked != null) {
|
||||
setState(() {
|
||||
pd['WORK_EXPECTED_END_TIME'] = DateFormat(
|
||||
'yyyy-MM-dd HH:mm:ss',
|
||||
).format(picked);
|
||||
});
|
||||
}
|
||||
},
|
||||
text: pd['WORK_EXPECTED_END_TIME'] ?? '',
|
||||
),
|
||||
/// 开始时间必须早于结束时间
|
||||
if (FormUtils.hasValue(pd, 'WORK_EXPECTED_END_TIME') &&
|
||||
!isBeforeStr(
|
||||
pd['WORK_EXPECTED_START_TIME'],
|
||||
pd['WORK_EXPECTED_END_TIME'],
|
||||
)) {
|
||||
pd['WORK_EXPECTED_END_TIME'] = '';
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
text: pd['WORK_EXPECTED_START_TIME'] ?? '',
|
||||
),
|
||||
const Divider(),
|
||||
ItemListWidget.selectableLineTitleTextRightButton(
|
||||
label: '预计作业结束时间:',
|
||||
isEditable: widget.isEditable,
|
||||
onTap: () async {
|
||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||
context,
|
||||
minTimeStr: pd['WORK_EXPECTED_START_TIME'] ?? '',
|
||||
allowFuture: true,
|
||||
);
|
||||
if (picked != null) {
|
||||
setState(() {
|
||||
pd['WORK_EXPECTED_END_TIME'] = DateFormat(
|
||||
'yyyy-MM-dd HH:mm:ss',
|
||||
).format(picked);
|
||||
});
|
||||
}
|
||||
},
|
||||
text: pd['WORK_EXPECTED_END_TIME'] ?? '',
|
||||
),
|
||||
],
|
||||
const Divider(),
|
||||
ListItemFactory.createYesNoSection(
|
||||
verticalPadding: 0,
|
||||
|
|
@ -291,10 +382,11 @@ class _HighWorkDetailFormWidgetState extends State<HighWorkDetailFormWidget> {
|
|||
isInput: false,
|
||||
isEditable: widget.isEditable,
|
||||
buttonText: '定位',
|
||||
onTap: widget.onWorkAreaLocationHandle ?? (){},
|
||||
onTap: widget.onWorkAreaLocationHandle ?? () {},
|
||||
hintText: '',
|
||||
text: pd['LATITUDE_LONGITUDE'] ?? (widget.isEditable ? '' : '无'),
|
||||
),
|
||||
|
||||
],
|
||||
),
|
||||
);
|
||||
|
|
|
|||
|
|
@ -50,198 +50,6 @@ class HighWorkFormBaseWork extends StatelessWidget {
|
|||
child: child,
|
||||
);
|
||||
}
|
||||
|
||||
Widget signItemWidget(
|
||||
String signKey,
|
||||
String nameKey,
|
||||
String name,
|
||||
BuildContext context,
|
||||
) {
|
||||
return _itemContainer(
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
// 标题行
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 5, horizontal: 10),
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(child: ListItemFactory.headerTitle(name)),
|
||||
if (FormUtils.hasValue(pd, nameKey))
|
||||
Text(
|
||||
pd[nameKey]?.toString() ?? '',
|
||||
style: const TextStyle(fontSize: 16),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
|
||||
if (FormUtils.hasValue(signs, signKey))
|
||||
...((signs[signKey] as List<dynamic>)
|
||||
.cast<Map<String, dynamic>>()
|
||||
.map((item) {
|
||||
// 解析 SIGN_PATH
|
||||
List<String> signPaths = [];
|
||||
final rawSP =
|
||||
FormUtils.hasValue(item, 'SIGN_PATH')
|
||||
? item['SIGN_PATH']
|
||||
: null;
|
||||
if (rawSP is String && rawSP.isNotEmpty) {
|
||||
signPaths = rawSP.split(',').map((s) => s.trim()).toList();
|
||||
} else if (rawSP is List) {
|
||||
signPaths = rawSP.cast<String>();
|
||||
}
|
||||
|
||||
// 解析 SIGN_TIME 保留空格
|
||||
List<String> signTimes = [];
|
||||
final rawST =
|
||||
FormUtils.hasValue(item, 'SIGN_TIME')
|
||||
? item['SIGN_TIME']
|
||||
: null;
|
||||
if (rawST is String && rawST.isNotEmpty) {
|
||||
signTimes = rawST.split(',');
|
||||
} else if (rawST is List) {
|
||||
signTimes = rawST.cast<String>();
|
||||
}
|
||||
|
||||
final pairCount = math.min(
|
||||
signPaths.length,
|
||||
signTimes.length,
|
||||
);
|
||||
|
||||
// 解析 IMG_PATH, 最多 2 张
|
||||
List<String> imgPaths = [];
|
||||
final rawIP =
|
||||
FormUtils.hasValue(item, 'IMG_PATH')
|
||||
? item['IMG_PATH']
|
||||
: null;
|
||||
if (rawIP is String && rawIP.isNotEmpty) {
|
||||
imgPaths =
|
||||
rawIP.split(',').map((s) => s.trim()).take(2).toList();
|
||||
} else if (rawIP is List) {
|
||||
imgPaths = rawIP.cast<String>().take(2).toList();
|
||||
}
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 8.0,
|
||||
horizontal: 10,
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
if (imgPaths.isNotEmpty) ...[
|
||||
Row(
|
||||
children:
|
||||
imgPaths.map((p) {
|
||||
final fullUrl = '$baseImgPath$p';
|
||||
return GestureDetector(
|
||||
onTap:
|
||||
() => presentOpaque(
|
||||
SingleImageViewer(imageUrl: fullUrl),
|
||||
context,
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
right: 8.0,
|
||||
),
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(2),
|
||||
child: Image.network(
|
||||
fullUrl,
|
||||
width: 50,
|
||||
height: 50,
|
||||
fit: BoxFit.fill,
|
||||
errorBuilder:
|
||||
(_, __, ___) => const Icon(
|
||||
Icons.broken_image,
|
||||
size: 40,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
],
|
||||
|
||||
// 签名及时间
|
||||
...List.generate(pairCount, (index) {
|
||||
final imgPath = signPaths[index];
|
||||
final timeLabel = signTimes[index];
|
||||
final fullUrl = '$baseImgPath$imgPath';
|
||||
const imageWidth = 200.0;
|
||||
const imageHeight = 100.0;
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 8.0),
|
||||
child: Column(
|
||||
children: [
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
GestureDetector(
|
||||
onTap:
|
||||
() => presentOpaque(
|
||||
SingleImageViewer(
|
||||
imageUrl: fullUrl,
|
||||
),
|
||||
context,
|
||||
),
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
child: Image.network(
|
||||
fullUrl,
|
||||
width: imageWidth,
|
||||
height: imageHeight,
|
||||
fit: BoxFit.fill,
|
||||
errorBuilder:
|
||||
(_, __, ___) => const Icon(
|
||||
Icons.broken_image,
|
||||
size: 60,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: SizedBox(
|
||||
height: imageHeight,
|
||||
child: Align(
|
||||
alignment: Alignment.bottomRight,
|
||||
child: Text(
|
||||
timeLabel,
|
||||
style: const TextStyle(
|
||||
fontSize: 14,
|
||||
color: Colors.black87,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
if (index < pairCount - 1)
|
||||
const Padding(
|
||||
padding: EdgeInsets.only(top: 8.0),
|
||||
child: Divider(height: 1),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}),
|
||||
],
|
||||
),
|
||||
);
|
||||
})
|
||||
.toList()),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
|
|
@ -253,6 +61,7 @@ class HighWorkFormBaseWork extends StatelessWidget {
|
|||
pd: pd,
|
||||
isEditable: isEditable,
|
||||
onChooseLevel: onChooseLevel,
|
||||
signs: signs,
|
||||
),
|
||||
|
||||
// 2. 安全防护措施
|
||||
|
|
@ -295,7 +104,7 @@ class HighWorkFormBaseWork extends StatelessWidget {
|
|||
baseImgPath: baseImgPath,
|
||||
sectionKey: 'GUARDIAN',
|
||||
nameKey: 'GUARDIAN_USER_NAME',
|
||||
headerTitle: '监护人意见',
|
||||
headerTitle: '监护人签字',
|
||||
roleTitle: '监护人',
|
||||
),
|
||||
if (FormUtils.hasValue(signs, 'CONFESS'))
|
||||
|
|
@ -338,13 +147,13 @@ class HighWorkFormBaseWork extends StatelessWidget {
|
|||
headerTitle: '所在单位负责人意见',
|
||||
roleTitle: '所在单位负责人',
|
||||
),
|
||||
if (FormUtils.hasValue(signs, 'AUDIT'))
|
||||
if (FormUtils.hasValue(signs, 'REVIEWER'))
|
||||
ConfirmWithSignWidget(
|
||||
signs: signs,
|
||||
pd: pd,
|
||||
baseImgPath: baseImgPath,
|
||||
sectionKey: 'AUDIT',
|
||||
nameKey: 'AUDIT_USER_NAME',
|
||||
sectionKey: 'REVIEWER',
|
||||
nameKey: 'REVIEWER_USER_NAME',
|
||||
headerTitle: '审核部门意见',
|
||||
roleTitle: '审核部门负责人',
|
||||
),
|
||||
|
|
|
|||
|
|
@ -441,6 +441,7 @@ class _HighworkSafeFuncSureState extends State<HighworkSafeFuncSure> {
|
|||
pd: pd,
|
||||
isEditable: false,
|
||||
onChooseLevel: () {},
|
||||
signs: {},
|
||||
),
|
||||
SizedBox(height: 20),
|
||||
_setSafeDetailWidget(),
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@ import 'package:intl/intl.dart';
|
|||
import 'package:qhd_prevention/pages/home/tap/workArea_picker.dart';
|
||||
import 'package:qhd_prevention/customWidget/BaiDuMap/Map_page.dart';
|
||||
|
||||
|
||||
enum EditUserType {
|
||||
GUARDIAN('监护人单位', '监护人', true),
|
||||
CONFESS('安全交底人单位', '安全交底人', true),
|
||||
|
|
@ -57,7 +56,7 @@ class HighworkApplyDetail extends StatefulWidget {
|
|||
|
||||
class _HighworkApplyDetailState extends State<HighworkApplyDetail> {
|
||||
late bool isEditable = false;
|
||||
final levelList = ["I级高处作业", "II级高处作业", "III级高处作业","IV级高处作业"];
|
||||
final levelList = ["I级高处作业", "II级高处作业", "III级高处作业", "IV级高处作业"];
|
||||
|
||||
/// 编辑还是新增
|
||||
late String msg = 'add';
|
||||
|
|
@ -66,13 +65,17 @@ class _HighworkApplyDetailState extends State<HighworkApplyDetail> {
|
|||
late Map<String, dynamic> pd = {};
|
||||
late Map<String, dynamic> signs = {};
|
||||
late List<Map<String, dynamic>> measuresList = [];
|
||||
|
||||
/// ------------------- 新增 -------------------
|
||||
/// 视频监控摄像
|
||||
late List<dynamic> videoMonitoringList = [];
|
||||
|
||||
/// 承包商列表
|
||||
late List<dynamic> unitAllList = [];
|
||||
|
||||
/// 作业区域列表
|
||||
late List<Map<String, dynamic>> workAreaList = [];
|
||||
|
||||
/// --------------------------------------
|
||||
final TextEditingController _locationController = TextEditingController();
|
||||
final TextEditingController _hightController = TextEditingController();
|
||||
|
|
@ -80,8 +83,6 @@ class _HighworkApplyDetailState extends State<HighworkApplyDetail> {
|
|||
final TextEditingController _relatedController = TextEditingController();
|
||||
final TextEditingController _riskController = TextEditingController();
|
||||
|
||||
|
||||
|
||||
// 存储各单位的人员列表
|
||||
final Map<EditUserType, List<Map<String, dynamic>>> _personCache = {};
|
||||
|
||||
|
|
@ -99,7 +100,6 @@ class _HighworkApplyDetailState extends State<HighworkApplyDetail> {
|
|||
pd['APPLY_USER_ID'] = SessionService.instance.loginUserId;
|
||||
pd['APPLY_USER_NAME'] = SessionService.instance.username;
|
||||
pd['IS_CONTRACTOR_WORK'] = '0';
|
||||
|
||||
}
|
||||
|
||||
_getVideoList();
|
||||
|
|
@ -115,6 +115,21 @@ class _HighworkApplyDetailState extends State<HighworkApplyDetail> {
|
|||
});
|
||||
_hightController.addListener(() {
|
||||
pd['WORK_HIGH'] = _hightController.text.trim();
|
||||
setState(() {
|
||||
double height = double.parse(pd['WORK_HIGH']);
|
||||
int level = 0;
|
||||
if (height >= 2.0 && height <= 5.0) {
|
||||
level = 1;
|
||||
}else if (height >= 5.0 && height <= 15.0) {
|
||||
level = 2;
|
||||
}else if (height >= 15.0 && height <= 30.0) {
|
||||
level = 3;
|
||||
}else{
|
||||
level = 4;
|
||||
}
|
||||
pd['WORK_LEVEL'] = level;
|
||||
pd['WORK_LEVEL_NAME'] = levelList[level-1].toString();
|
||||
});
|
||||
});
|
||||
_relatedController.addListener(() {
|
||||
pd['SPECIAL_WORK'] = _relatedController.text.trim();
|
||||
|
|
@ -123,15 +138,16 @@ class _HighworkApplyDetailState extends State<HighworkApplyDetail> {
|
|||
pd['RISK_IDENTIFICATION'] = _riskController.text.trim();
|
||||
});
|
||||
}
|
||||
|
||||
/// ---------------------------- 新增 --------------------------------
|
||||
/// 视频监控摄像头
|
||||
Future<void> _chooseVideoManager() async {
|
||||
final choice = await BottomPicker.show<String>(
|
||||
context,
|
||||
items:
|
||||
videoMonitoringList
|
||||
.map((item) => item['VIDEONAME'] as String)
|
||||
.toList(),
|
||||
videoMonitoringList
|
||||
.map((item) => item['VIDEONAME'] as String)
|
||||
.toList(),
|
||||
itemBuilder: (item) => Text(item, textAlign: TextAlign.center),
|
||||
initialIndex: 0,
|
||||
);
|
||||
|
|
@ -140,7 +156,7 @@ class _HighworkApplyDetailState extends State<HighworkApplyDetail> {
|
|||
pd['VIDEONAME'] = choice;
|
||||
|
||||
Map<String, dynamic> result = videoMonitoringList.firstWhere(
|
||||
(item) => item['VIDEONAME'] == choice,
|
||||
(item) => item['VIDEONAME'] == choice,
|
||||
orElse: () => {}, // 避免找不到时报错
|
||||
);
|
||||
if (FormUtils.hasValue(result, 'VIDEOMANAGER_ID')) {
|
||||
|
|
@ -150,6 +166,7 @@ class _HighworkApplyDetailState extends State<HighworkApplyDetail> {
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// 选择承包商
|
||||
Future<void> _chooseUnitManager() async {
|
||||
final choice = await BottomPicker.show<String>(
|
||||
|
|
@ -163,7 +180,7 @@ class _HighworkApplyDetailState extends State<HighworkApplyDetail> {
|
|||
pd['UNITS_NAME'] = choice;
|
||||
|
||||
Map<String, dynamic> result = unitAllList.firstWhere(
|
||||
(item) => item['UNITS_NAME'] == choice,
|
||||
(item) => item['UNITS_NAME'] == choice,
|
||||
orElse: () => {}, // 避免找不到时报错
|
||||
);
|
||||
if (FormUtils.hasValue(result, 'UNITS_ID')) {
|
||||
|
|
@ -173,10 +190,9 @@ class _HighworkApplyDetailState extends State<HighworkApplyDetail> {
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// 选择经纬度
|
||||
Future<void> _showLocationHandle() async{
|
||||
Future<void> _showLocationHandle() async {
|
||||
if (!FormUtils.hasValue(pd, 'ELECTRONIC_FENCE_AREA_ID')) {
|
||||
ToastUtil.showNormal(context, '请选择作业区域');
|
||||
return;
|
||||
|
|
@ -185,10 +201,11 @@ class _HighworkApplyDetailState extends State<HighworkApplyDetail> {
|
|||
setState(() {
|
||||
pd['LONGITUDE'] = mapData['longitue'] ?? '';
|
||||
pd['LATITUDE'] = mapData['latitude'] ?? '';
|
||||
pd['LATITUDE_LONGITUDE'] = '${mapData['longitue'] ?? ''},${mapData['latitude'] ?? ''}';
|
||||
pd['LATITUDE_LONGITUDE'] =
|
||||
'${mapData['longitue'] ?? ''},${mapData['latitude'] ?? ''}';
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/// 作业区域
|
||||
Future<void> _getWorkArea() async {
|
||||
//FocusHelper.clearFocus(context);
|
||||
|
|
@ -199,16 +216,19 @@ class _HighworkApplyDetailState extends State<HighworkApplyDetail> {
|
|||
backgroundColor: Colors.transparent,
|
||||
builder:
|
||||
(_) => WorkAreaPicker(
|
||||
onSelected: (String id, String POSITIONS, String name) {
|
||||
pd['ELECTRONIC_FENCE_AREA_ID'] = id;
|
||||
pd['POSITIONS'] = POSITIONS;
|
||||
pd['PLS_NAME'] = name;
|
||||
},
|
||||
),
|
||||
onSelected: (String id, String POSITIONS, String name) {
|
||||
setState(() {
|
||||
pd['ELECTRONIC_FENCE_AREA_ID'] = id;
|
||||
pd['POSITIONS'] = POSITIONS;
|
||||
pd['PLS_NAME'] = name;
|
||||
});
|
||||
},
|
||||
),
|
||||
).then((_) {
|
||||
//FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
|
||||
/// 获取摄像头列表
|
||||
Future<void> _getVideoList() async {
|
||||
final result = await ApiService.getVideomanagerList();
|
||||
|
|
@ -216,6 +236,7 @@ class _HighworkApplyDetailState extends State<HighworkApplyDetail> {
|
|||
videoMonitoringList = result['varList'] ?? [];
|
||||
});
|
||||
}
|
||||
|
||||
/// 获承包商列表
|
||||
Future<void> _getUnitListAll() async {
|
||||
final result = await ApiService.getUnitListAll();
|
||||
|
|
@ -223,6 +244,7 @@ class _HighworkApplyDetailState extends State<HighworkApplyDetail> {
|
|||
unitAllList = result['varList'] ?? [];
|
||||
});
|
||||
}
|
||||
|
||||
/// 作业区域列表
|
||||
Future<void> _getPlsList() async {
|
||||
final result = await ApiService.getWorkAreaList();
|
||||
|
|
@ -231,6 +253,7 @@ class _HighworkApplyDetailState extends State<HighworkApplyDetail> {
|
|||
workAreaList = jsonDecode(zTreeNodes);
|
||||
});
|
||||
}
|
||||
|
||||
/// ------------------------------------------------------------
|
||||
void set_pd_DEPARTMENT_ID(EditUserType type, String id) {
|
||||
pd['${type.name}_DEPARTMENT_ID'] = id;
|
||||
|
|
@ -243,7 +266,7 @@ class _HighworkApplyDetailState extends State<HighworkApplyDetail> {
|
|||
void set_pd_USER_ID(EditUserType type, String id) {
|
||||
if (type == EditUserType.WORK_USER) {
|
||||
pd['${type.name}_ID'] = id;
|
||||
}else{
|
||||
} else {
|
||||
pd['${type.name}_USER_ID'] = id;
|
||||
}
|
||||
}
|
||||
|
|
@ -263,7 +286,7 @@ class _HighworkApplyDetailState extends State<HighworkApplyDetail> {
|
|||
String get_pd_USER_ID(EditUserType type) {
|
||||
if (type == EditUserType.WORK_USER) {
|
||||
return pd['${type.name}_ID'] ?? '';
|
||||
}else{
|
||||
} else {
|
||||
return pd['${type.name}_USER_ID'] ?? '';
|
||||
}
|
||||
}
|
||||
|
|
@ -303,15 +326,13 @@ class _HighworkApplyDetailState extends State<HighworkApplyDetail> {
|
|||
Widget _chooseItem(EditUserType type) {
|
||||
bool isClean = false;
|
||||
bool isRequird = true;
|
||||
if (pd['WORK_LEVEL'] == '1' && type == EditUserType.AUDIT) {
|
||||
if (pd['WORK_LEVEL'] == 1 && type == EditUserType.AUDIT) {
|
||||
isRequird = false;
|
||||
isClean = true;
|
||||
|
||||
}
|
||||
if (pd['WORK_LEVEL'] != '4' && type == EditUserType.APPROVE) {
|
||||
if (pd['WORK_LEVEL'] != 4 && type == EditUserType.APPROVE) {
|
||||
isRequird = false;
|
||||
isClean = true;
|
||||
|
||||
}
|
||||
|
||||
return Column(
|
||||
|
|
@ -390,13 +411,15 @@ class _HighworkApplyDetailState extends State<HighworkApplyDetail> {
|
|||
return;
|
||||
}
|
||||
|
||||
if (personList.isEmpty) { // 一般这种情况是因为重新编辑没有缓存对应部门的负责人,所以先拉取一下接口
|
||||
if (personList.isEmpty) {
|
||||
// 一般这种情况是因为重新编辑没有缓存对应部门的负责人,所以先拉取一下接口
|
||||
await _getPersonListForUnitId(unitId, type);
|
||||
final list = _personCache[type] ?? [];
|
||||
|
||||
if (list.isEmpty) { // 如果还是没数据,说明该部门没有可选的人
|
||||
if (list.isEmpty) {
|
||||
// 如果还是没数据,说明该部门没有可选的人
|
||||
ToastUtil.showNormal(context, '暂无数据,请选择其他单位');
|
||||
}else{
|
||||
} else {
|
||||
choosePersonHandle(type);
|
||||
}
|
||||
return;
|
||||
|
|
@ -434,8 +457,6 @@ class _HighworkApplyDetailState extends State<HighworkApplyDetail> {
|
|||
// },
|
||||
{'value': _riskController.text.trim(), 'message': '请填写风险辨识结果'},
|
||||
];
|
||||
final level = pd['WORK_LEVEL'] ?? '';
|
||||
print('---level-$level');
|
||||
|
||||
/// 各项负责人校验
|
||||
final unitRules = <EditUserType>[
|
||||
|
|
@ -444,10 +465,8 @@ class _HighworkApplyDetailState extends State<HighworkApplyDetail> {
|
|||
EditUserType.ACCEPT_CONFESS,
|
||||
EditUserType.CONFIRM,
|
||||
EditUserType.LEADER,
|
||||
if (pd['WORK_LEVEL'] != '1')
|
||||
EditUserType.AUDIT,
|
||||
if (pd['WORK_LEVEL'] == '4')
|
||||
EditUserType.APPROVE,
|
||||
if (pd['WORK_LEVEL'] != 1) EditUserType.AUDIT,
|
||||
if (pd['WORK_LEVEL'] == 4) EditUserType.APPROVE,
|
||||
EditUserType.WORK_USER,
|
||||
EditUserType.WORK_START,
|
||||
EditUserType.WORK_END,
|
||||
|
|
@ -461,11 +480,7 @@ class _HighworkApplyDetailState extends State<HighworkApplyDetail> {
|
|||
return;
|
||||
}
|
||||
}
|
||||
// 级别校验
|
||||
if (level.length == 0) {
|
||||
ToastUtil.showNormal(context, '请输入高处作业级别');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!FormUtils.hasValue(pd, 'WORK_EXPECTED_START_TIME')) {
|
||||
ToastUtil.showNormal(context, '请选择预计作业开始时间');
|
||||
return;
|
||||
|
|
@ -475,7 +490,8 @@ class _HighworkApplyDetailState extends State<HighworkApplyDetail> {
|
|||
return;
|
||||
}
|
||||
|
||||
if (pd['IS_CONTRACTOR_WORK'] == '1' && !FormUtils.hasValue(pd, 'UNITS_ID')) {
|
||||
if (pd['IS_CONTRACTOR_WORK'] == '1' &&
|
||||
!FormUtils.hasValue(pd, 'UNITS_ID')) {
|
||||
ToastUtil.showNormal(context, '请选择承包商');
|
||||
return;
|
||||
}
|
||||
|
|
@ -494,15 +510,16 @@ class _HighworkApplyDetailState extends State<HighworkApplyDetail> {
|
|||
return;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
// LoadingDialogHelper.show();
|
||||
|
||||
String taskId = '0';
|
||||
if (pd['WORK_LEVEL'] == '1') {
|
||||
if (pd['WORK_LEVEL'] == 1) {
|
||||
taskId = '5';
|
||||
} else if (pd['WORK_LEVEL'] == '2' || pd['WORK_LEVEL'] == '3') {
|
||||
} else if (pd['WORK_LEVEL'] == 2 || pd['WORK_LEVEL'] == 3) {
|
||||
taskId = '6';
|
||||
} else if (pd['WORK_LEVEL'] == '4') {
|
||||
} else if (pd['WORK_LEVEL'] == 4) {
|
||||
taskId = '7';
|
||||
}
|
||||
pd['USER_ID'] = SessionService.instance.loginUserId ?? '';
|
||||
|
|
@ -550,12 +567,12 @@ class _HighworkApplyDetailState extends State<HighworkApplyDetail> {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// 初始化拉取数据
|
||||
Future<void> _getData() async {
|
||||
|
||||
final data = await ApiService.getHomeworkFindById('highwork', widget.HIGHWORK_ID);
|
||||
final data = await ApiService.getHomeworkFindById(
|
||||
'highwork',
|
||||
widget.HIGHWORK_ID,
|
||||
);
|
||||
setState(() {
|
||||
pd = data['pd'];
|
||||
if (pd['STEP_ID'] == 0) {
|
||||
|
|
@ -581,7 +598,8 @@ class _HighworkApplyDetailState extends State<HighworkApplyDetail> {
|
|||
}
|
||||
|
||||
Future<void> _getSigns(String homework_id) async {
|
||||
final data = await ApiService.listSignFinished('highwork',
|
||||
final data = await ApiService.listSignFinished(
|
||||
'highwork',
|
||||
homework_id.length > 0 ? homework_id : widget.HIGHWORK_ID,
|
||||
);
|
||||
setState(() {
|
||||
|
|
@ -590,7 +608,8 @@ class _HighworkApplyDetailState extends State<HighworkApplyDetail> {
|
|||
}
|
||||
|
||||
Future<void> _getMeasures(String homework_id) async {
|
||||
final data = await ApiService.listSignFinishMeasures('highwork',
|
||||
final data = await ApiService.listSignFinishMeasures(
|
||||
'highwork',
|
||||
homework_id.length > 0 ? homework_id : widget.HIGHWORK_ID,
|
||||
);
|
||||
setState(() {
|
||||
|
|
@ -625,12 +644,12 @@ class _HighworkApplyDetailState extends State<HighworkApplyDetail> {
|
|||
onContractorHandle: _chooseUnitManager,
|
||||
onWorkAreaHandle: _getWorkArea,
|
||||
onWorkAreaLocationHandle: _showLocationHandle,
|
||||
signs: {},
|
||||
),
|
||||
),
|
||||
if (isEditable)
|
||||
Column(
|
||||
children: [
|
||||
|
||||
SizedBox(height: 15),
|
||||
_card(_chooseItem(EditUserType.GUARDIAN)),
|
||||
SizedBox(height: 15),
|
||||
|
|
@ -701,7 +720,7 @@ class _HighworkApplyDetailState extends State<HighworkApplyDetail> {
|
|||
color: Colors.white,
|
||||
child: MeasuresListWidget(
|
||||
measuresList:
|
||||
measuresList, // List<Map<String, dynamic>>
|
||||
measuresList, // List<Map<String, dynamic>>
|
||||
baseImgPath: ApiService.baseImgPath,
|
||||
isAllowEdit: false,
|
||||
),
|
||||
|
|
@ -729,45 +748,9 @@ class _HighworkApplyDetailState extends State<HighworkApplyDetail> {
|
|||
),
|
||||
isEditable
|
||||
? Row(
|
||||
spacing: 10,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Expanded(
|
||||
child: CustomButton(
|
||||
height: 45,
|
||||
textStyle: TextStyle(
|
||||
fontSize: 16,
|
||||
color: Colors.white,
|
||||
),
|
||||
text: '提交',
|
||||
backgroundColor: Colors.blue,
|
||||
onPressed: () {
|
||||
_submit('1');
|
||||
},
|
||||
),
|
||||
),
|
||||
|
||||
Expanded(
|
||||
child: CustomButton(
|
||||
textStyle: TextStyle(
|
||||
fontSize: 16,
|
||||
color: Colors.white,
|
||||
),
|
||||
text: '暂存',
|
||||
backgroundColor: Colors.green,
|
||||
onPressed: () {
|
||||
_submit('0');
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
: Column(
|
||||
children: [
|
||||
SizedBox(height: 20),
|
||||
Row(
|
||||
spacing: 10,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
SizedBox(width: 50),
|
||||
Expanded(
|
||||
child: CustomButton(
|
||||
height: 45,
|
||||
|
|
@ -775,18 +758,54 @@ class _HighworkApplyDetailState extends State<HighworkApplyDetail> {
|
|||
fontSize: 16,
|
||||
color: Colors.white,
|
||||
),
|
||||
text: '返回',
|
||||
backgroundColor: Colors.green,
|
||||
text: '提交',
|
||||
backgroundColor: Colors.blue,
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
_submit('1');
|
||||
},
|
||||
),
|
||||
),
|
||||
SizedBox(width: 50),
|
||||
|
||||
Expanded(
|
||||
child: CustomButton(
|
||||
textStyle: TextStyle(
|
||||
fontSize: 16,
|
||||
color: Colors.white,
|
||||
),
|
||||
text: '暂存',
|
||||
backgroundColor: Colors.green,
|
||||
onPressed: () {
|
||||
_submit('0');
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
: Column(
|
||||
children: [
|
||||
SizedBox(height: 20),
|
||||
Row(
|
||||
children: [
|
||||
SizedBox(width: 50),
|
||||
Expanded(
|
||||
child: CustomButton(
|
||||
height: 45,
|
||||
textStyle: TextStyle(
|
||||
fontSize: 16,
|
||||
color: Colors.white,
|
||||
),
|
||||
text: '返回',
|
||||
backgroundColor: Colors.green,
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
),
|
||||
),
|
||||
SizedBox(width: 50),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -58,7 +58,6 @@ class _HighworkListPageState extends State<HighworkListPage> {
|
|||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_fetchSteps();
|
||||
_fetchData();
|
||||
_scrollController.addListener(_onScroll);
|
||||
}
|
||||
|
|
@ -139,9 +138,11 @@ class _HighworkListPageState extends State<HighworkListPage> {
|
|||
}
|
||||
|
||||
/// 申请
|
||||
void _handleApply() {
|
||||
void _handleApply() async{
|
||||
// 处理申请按钮点击逻辑
|
||||
pushPage(HighworkApplyDetail(HIGHWORK_ID: '', flow: widget.flow), context);
|
||||
await pushPage(HighworkApplyDetail(HIGHWORK_ID: '', flow: widget.flow), context);
|
||||
_fetchData();
|
||||
LoadingDialogHelper.hide();
|
||||
}
|
||||
|
||||
/// 打开流程图
|
||||
|
|
@ -228,9 +229,10 @@ class _HighworkListPageState extends State<HighworkListPage> {
|
|||
default:
|
||||
break;
|
||||
}
|
||||
LoadingDialogHelper.show();
|
||||
_fetchSteps();
|
||||
_fetchData();
|
||||
|
||||
|
||||
await _fetchData();
|
||||
LoadingDialogHelper.hide();
|
||||
}
|
||||
|
||||
Widget _buildFlowStepItem({
|
||||
|
|
|
|||
|
|
@ -329,6 +329,7 @@ class _HighworkJhrDetailState extends State<HighworkJhrDetail> {
|
|||
pd: pd,
|
||||
isEditable: false,
|
||||
onChooseLevel: () {},
|
||||
signs: signs,
|
||||
),
|
||||
SizedBox(height: 20),
|
||||
_setSafeDetailWidget(),
|
||||
|
|
|
|||
|
|
@ -207,6 +207,7 @@ class _HighworkJszyDetailState extends State<HighworkJszyDetail> {
|
|||
child: SingleChildScrollView(
|
||||
padding: EdgeInsets.all(12),
|
||||
child: Column(
|
||||
spacing: 12,
|
||||
children: [
|
||||
// _setSafeDetailWidget(),
|
||||
HighWorkFormBaseWork(
|
||||
|
|
@ -246,7 +247,6 @@ class _HighworkJszyDetailState extends State<HighworkJszyDetail> {
|
|||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 12,),
|
||||
_bottomButtons(),
|
||||
],
|
||||
),
|
||||
|
|
|
|||
|
|
@ -190,6 +190,7 @@ class _HighworkKszyDetailState extends State<HighworkKszyDetail> {
|
|||
child: SingleChildScrollView(
|
||||
padding: EdgeInsets.all(12),
|
||||
child: Column(
|
||||
spacing: 12,
|
||||
children: [
|
||||
// _setSafeDetailWidget(),
|
||||
HighWorkFormBaseWork(
|
||||
|
|
@ -236,7 +237,6 @@ class _HighworkKszyDetailState extends State<HighworkKszyDetail> {
|
|||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 12,),
|
||||
_bottomButtons(),
|
||||
],
|
||||
),
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ import 'package:qhd_prevention/http/ApiService.dart';
|
|||
import 'package:qhd_prevention/pages/mine/mine_sign_page.dart';
|
||||
import 'package:qhd_prevention/pages/my_appbar.dart';
|
||||
|
||||
/// 安全管理部门意见
|
||||
/// 审核部门意见
|
||||
class HighworkShbmDetail extends StatefulWidget {
|
||||
const HighworkShbmDetail({
|
||||
super.key,
|
||||
|
|
|
|||
|
|
@ -31,14 +31,8 @@ class HighworkSpbmDetail extends StatefulWidget {
|
|||
class _HighworkSpbmDetailState extends State<HighworkSpbmDetail> {
|
||||
late bool isEditable = false;
|
||||
|
||||
/// 详情
|
||||
late Map<String, dynamic> pd = {};
|
||||
final TextEditingController _contentController = TextEditingController();
|
||||
|
||||
/// 安全防护措施列表
|
||||
late List<Map<String, dynamic>> measuresList = [];
|
||||
late Map<String, dynamic> signs = {};
|
||||
|
||||
|
||||
List<String> signImages = [];
|
||||
List<String> signTimes = []; // 签字时间列表
|
||||
@override
|
||||
|
|
@ -46,7 +40,70 @@ class _HighworkSpbmDetailState extends State<HighworkSpbmDetail> {
|
|||
super.initState();
|
||||
_getData();
|
||||
}
|
||||
late Map<String, dynamic> pd = {};
|
||||
late Map<String, dynamic> signs = {};
|
||||
late List<Map<String, dynamic>> measuresList = [];
|
||||
|
||||
/// 初始化拉取数据(并行获取 pd / signs / measures,最后一次 setState)
|
||||
Future<void> _getData() async {
|
||||
LoadingDialogHelper.show();
|
||||
|
||||
try {
|
||||
// 并行发起三个请求,并在出错时返回安全的默认值(避免 Future.wait 因一个失败而中断)
|
||||
final futurePd = ApiService.getHomeworkFindById('highwork', widget.HIGHWORK_ID)
|
||||
.catchError((e) {
|
||||
// 可加入日志记录 e
|
||||
return <String, dynamic>{}; // 回退为空 map
|
||||
});
|
||||
|
||||
final futureSigns = ApiService.listSignFinished('highwork', widget.HIGHWORK_ID)
|
||||
.catchError((e) {
|
||||
return <String, dynamic>{'signs': <String, dynamic>{}};
|
||||
});
|
||||
|
||||
final futureMeasures = ApiService.listSignFinishMeasures('highwork', widget.HIGHWORK_ID)
|
||||
.catchError((e) {
|
||||
return <String, dynamic>{'finishMeasuresList': <Map<String, dynamic>>[]};
|
||||
});
|
||||
|
||||
final results = await Future.wait([futurePd, futureSigns, futureMeasures]);
|
||||
|
||||
final pdResult = results[0] as Map<String, dynamic>? ?? <String, dynamic>{};
|
||||
final signsResult = results[1] as Map<String, dynamic>? ?? <String, dynamic>{};
|
||||
final measuresResult = results[2] as Map<String, dynamic>? ?? <String, dynamic>{};
|
||||
|
||||
// 从各自的结果里提取需要的字段,使用默认值以防字段缺失或类型不对
|
||||
final newPd = (pdResult['pd'] is Map<String, dynamic>)
|
||||
? Map<String, dynamic>.from(pdResult['pd'])
|
||||
: <String, dynamic>{};
|
||||
|
||||
final newSigns = (signsResult['signs'] is Map<String, dynamic>)
|
||||
? Map<String, dynamic>.from(signsResult['signs'])
|
||||
: <String, dynamic>{};
|
||||
|
||||
final newMeasuresList = <Map<String, dynamic>>[];
|
||||
final rawMeasures = measuresResult['finishMeasuresList'];
|
||||
if (rawMeasures is List) {
|
||||
for (final m in rawMeasures) {
|
||||
if (m is Map) {
|
||||
newMeasuresList.add(Map<String, dynamic>.from(m));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!mounted) return;
|
||||
|
||||
setState(() {
|
||||
pd = newPd;
|
||||
signs = newSigns;
|
||||
measuresList = newMeasuresList;
|
||||
});
|
||||
} catch (e, st) {
|
||||
debugPrint('[_getData] 未捕获异常: $e\n$st');
|
||||
} finally {
|
||||
LoadingDialogHelper.hide();
|
||||
}
|
||||
}
|
||||
/// 签字
|
||||
Future<void> _sign() async {
|
||||
await NativeOrientation.setLandscape();
|
||||
|
|
@ -190,42 +247,6 @@ class _HighworkSpbmDetailState extends State<HighworkSpbmDetail> {
|
|||
}
|
||||
}
|
||||
|
||||
/// 初始化拉取数据
|
||||
Future<void> _getData() async {
|
||||
final data = await ApiService.getHomeworkFindById(
|
||||
'highwork',
|
||||
widget.HIGHWORK_ID,
|
||||
);
|
||||
setState(() {
|
||||
pd = data['pd'];
|
||||
|
||||
_getSigns(pd['HIGHWORK_ID'] ?? '');
|
||||
_getMeasures(pd['HIGHWORK_ID'] ?? '');
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> _getMeasures(String homework_id) async {
|
||||
final data = await ApiService.listSignFinishMeasures(
|
||||
'highwork',
|
||||
homework_id.length > 0 ? homework_id : widget.HIGHWORK_ID,
|
||||
);
|
||||
setState(() {
|
||||
measuresList = List<Map<String, dynamic>>.from(
|
||||
data['finishMeasuresList'] ?? <Map<String, dynamic>>[],
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> _getSigns(String homework_id) async {
|
||||
final data = await ApiService.listSignFinished(
|
||||
'highwork',
|
||||
homework_id.length > 0 ? homework_id : widget.HIGHWORK_ID,
|
||||
);
|
||||
setState(() {
|
||||
signs = data['signs'] ?? {};
|
||||
});
|
||||
}
|
||||
|
||||
/// 底部按钮
|
||||
Widget _bottomButtons() {
|
||||
return Row(
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ class _HighworkSetSafeDetailState extends State<HighworkSetSafeDetail> {
|
|||
return <String, dynamic>{'signs': <String, dynamic>{}};
|
||||
});
|
||||
|
||||
final futureMeasures = ApiService.listSignFinishAllMeasures('highwork')
|
||||
final futureMeasures = ApiService.listSignFinishAllMeasures('highwork', widget.HIGHWORK_ID)
|
||||
.catchError((e) {
|
||||
return <String, dynamic>{'measuresList': <Map<String, dynamic>>[]};
|
||||
});
|
||||
|
|
@ -597,6 +597,7 @@ class _HighworkSetSafeDetailState extends State<HighworkSetSafeDetail> {
|
|||
pd: pd,
|
||||
isEditable: false,
|
||||
onChooseLevel: () {},
|
||||
signs: signs,
|
||||
),
|
||||
SizedBox(height: 20),
|
||||
_setSafeDetailWidget(),
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@ import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/MeasuresListW
|
|||
/// 通用明细表单组件(支持编辑/只读)
|
||||
class ElectricityDetailFormWidget extends StatefulWidget {
|
||||
final Map<String, dynamic> pd;
|
||||
final Map<String, dynamic> signs;
|
||||
|
||||
final bool isEditable;
|
||||
final VoidCallback onChooseLevel;
|
||||
final VoidCallback onChooseHotworkUser;
|
||||
|
|
@ -38,6 +40,7 @@ class ElectricityDetailFormWidget extends StatefulWidget {
|
|||
required this.onChooseLevel,
|
||||
required this.onChooseHotworkUser,
|
||||
required this.onAnalyzeTap,
|
||||
required this.signs,
|
||||
|
||||
/// 新增
|
||||
this.onChooseVideoManager,
|
||||
|
|
@ -86,6 +89,13 @@ class _ElectricityDetailFormWidgetState extends State<ElectricityDetailFormWidge
|
|||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
if (FormUtils.hasValue(pd, 'CHECK_NO')) ...[
|
||||
ItemListWidget.singleLineTitleText(
|
||||
label: '编号:',
|
||||
isEditable: false,
|
||||
text: pd['CHECK_NO'] ?? '',
|
||||
),
|
||||
],
|
||||
ItemListWidget.singleLineTitleText(
|
||||
label: '作业申请单位:',
|
||||
isEditable: false,
|
||||
|
|
@ -97,12 +107,12 @@ class _ElectricityDetailFormWidgetState extends State<ElectricityDetailFormWidge
|
|||
isEditable: false,
|
||||
text: pd['APPLY_USER_NAME'] ?? '',
|
||||
),
|
||||
if (FormUtils.hasValue(pd, 'CHECK_NO')) ...[
|
||||
if (FormUtils.hasValue(pd, 'CREATTIME') && !widget.isEditable) ...[
|
||||
const Divider(),
|
||||
ItemListWidget.singleLineTitleText(
|
||||
label: '编号:',
|
||||
label: '作业申请时间:',
|
||||
isEditable: false,
|
||||
text: pd['CHECK_NO'] ?? '',
|
||||
text: pd['CREATTIME'] ?? '',
|
||||
),
|
||||
],
|
||||
const Divider(),
|
||||
|
|
@ -120,42 +130,7 @@ class _ElectricityDetailFormWidgetState extends State<ElectricityDetailFormWidge
|
|||
controller: widget.contentController,
|
||||
text: pd['WORK_CONTENT'] ?? '',
|
||||
),
|
||||
|
||||
const Divider(),
|
||||
ItemListWidget.singleLineTitleText(
|
||||
label: '电工证号:',
|
||||
isEditable: widget.isEditable,
|
||||
controller: widget.cardController,
|
||||
hintText: '请输入电工证号',
|
||||
text: pd['CARD_NO'] ?? '',
|
||||
),
|
||||
const Divider(),
|
||||
|
||||
if (FormUtils.hasValue(pd, 'WORK_START_DATE'))
|
||||
Column(
|
||||
children: [
|
||||
ItemListWidget.singleLineTitleText(
|
||||
label: '作业开始时间:',
|
||||
isEditable: false,
|
||||
text: pd['WORK_START_DATE'] ?? '',
|
||||
),
|
||||
const Divider(),
|
||||
|
||||
],
|
||||
),
|
||||
if (FormUtils.hasValue(pd, 'WORK_END_DATE'))
|
||||
Column(
|
||||
children: [
|
||||
ItemListWidget.singleLineTitleText(
|
||||
label: '作业结束时间:',
|
||||
isEditable: false,
|
||||
text: pd['WORK_END_DATE'] ?? '',
|
||||
),
|
||||
const Divider(),
|
||||
|
||||
],
|
||||
),
|
||||
|
||||
ItemListWidget.singleLineTitleText(
|
||||
label: '电源接入点及许可用电功率:',
|
||||
isEditable: widget.isEditable,
|
||||
|
|
@ -164,14 +139,6 @@ class _ElectricityDetailFormWidgetState extends State<ElectricityDetailFormWidge
|
|||
text: pd['ALLOW_POWER'] ?? '',
|
||||
),
|
||||
const Divider(),
|
||||
ItemListWidget.singleLineTitleText(
|
||||
label: '用电设备名称及额定功率:',
|
||||
isEditable: widget.isEditable,
|
||||
controller: widget.ratedPowerController,
|
||||
hintText: '请输入用电设备名称及额定功率',
|
||||
text: pd['RATED_POWER'] ?? '',
|
||||
),
|
||||
const Divider(),
|
||||
ItemListWidget.singleLineTitleText(
|
||||
label: '工作电压:',
|
||||
isEditable: widget.isEditable,
|
||||
|
|
@ -180,19 +147,75 @@ class _ElectricityDetailFormWidgetState extends State<ElectricityDetailFormWidge
|
|||
text: pd['WORK_VOLTAGE'] ?? '',
|
||||
),
|
||||
const Divider(),
|
||||
ItemListWidget.singleLineTitleText(
|
||||
label: '用电设备名称及额定功率:',
|
||||
isEditable: widget.isEditable,
|
||||
controller: widget.ratedPowerController,
|
||||
hintText: '请输入用电设备名称及额定功率',
|
||||
text: pd['RATED_POWER'] ?? '',
|
||||
),
|
||||
if (FormUtils.hasValue(pd, 'GUARDIAN_USER_NAME') &&
|
||||
!widget.isEditable) ...[
|
||||
const Divider(),
|
||||
SignRowImageTitle(
|
||||
label: '监护人:',
|
||||
signKey: 'GUARDIAN',
|
||||
signs: widget.signs,
|
||||
text: pd['GUARDIAN_USER_NAME'] ?? '',
|
||||
),
|
||||
],
|
||||
if (FormUtils.hasValue(pd, 'ELECTRICITY_USER_NAME') &&
|
||||
!widget.isEditable) ...[
|
||||
const Divider(),
|
||||
SignRowImageTitle(
|
||||
label: '用电人:',
|
||||
signKey: 'ELECTRICITY',
|
||||
signs: widget.signs,
|
||||
text: pd['ELECTRICITY_USER_NAME'] ?? '',
|
||||
),
|
||||
],
|
||||
|
||||
|
||||
if (FormUtils.hasValue(pd, 'WORK_USER_USER_NAME') &&
|
||||
!widget.isEditable) ...[
|
||||
const Divider(),
|
||||
SignRowImageTitle(
|
||||
label: '作业人:',
|
||||
signKey: 'WORK_USER',
|
||||
signs: widget.signs,
|
||||
text: pd['WORK_USER_USER_NAME'] ?? '',
|
||||
),
|
||||
],
|
||||
const Divider(),
|
||||
ItemListWidget.singleLineTitleText(
|
||||
label: '作业人电工证号:',
|
||||
isEditable: widget.isEditable,
|
||||
controller: widget.cardController,
|
||||
hintText: '请输入电工证号',
|
||||
text: pd['CARD_NO'] ?? '',
|
||||
),
|
||||
if (FormUtils.hasValue(pd, 'CONFIRM_USER_NAME') &&
|
||||
!widget.isEditable) ...[
|
||||
const Divider(),
|
||||
SignRowImageTitle(
|
||||
label: '作业负责人:',
|
||||
signKey: 'CONFIRM',
|
||||
signs: widget.signs,
|
||||
text: pd['CONFIRM_USER_NAME'] ?? '',
|
||||
),
|
||||
],
|
||||
if (FormUtils.hasValue(pd, 'LEADER_CARD_NO'))
|
||||
Column(
|
||||
children: [
|
||||
const Divider(),
|
||||
ItemListWidget.singleLineTitleText(
|
||||
label: '负责人电工号:',
|
||||
label: '作业负责人电工号:',
|
||||
isEditable: false,
|
||||
text: pd['LEADER_CARD_NO'] ?? '',
|
||||
),
|
||||
const Divider(),
|
||||
|
||||
],
|
||||
),
|
||||
|
||||
const Divider(),
|
||||
ItemListWidget.twoRowButtonTitleText(
|
||||
label: '关联其他特殊作业及安全作业票编号',
|
||||
isRequired: false,
|
||||
|
|
@ -241,72 +264,67 @@ class _ElectricityDetailFormWidgetState extends State<ElectricityDetailFormWidge
|
|||
controller: widget.riskController,
|
||||
text: pd['RISK_IDENTIFICATION'] ?? '',
|
||||
),
|
||||
const Divider(),
|
||||
if (FormUtils.hasValue(pd, 'WORK_START_DATE')) ...[
|
||||
const Divider(),
|
||||
ItemListWidget.selectableLineTitleTextRightButton(
|
||||
label: '作业实施时间:',
|
||||
isEditable: widget.isEditable,
|
||||
text:
|
||||
FormUtils.hasValue(pd, 'WORK_END_DATE')
|
||||
? '${pd['WORK_START_DATE'] ?? ''}\n-${pd['WORK_END_DATE'] ?? ''}'
|
||||
: pd['WORK_START_DATE'] ?? '',
|
||||
),
|
||||
] else ...[
|
||||
const Divider(),
|
||||
ItemListWidget.selectableLineTitleTextRightButton(
|
||||
label: '预计作业开始时间:',
|
||||
isEditable: widget.isEditable,
|
||||
onTap: () async {
|
||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||
mode: BottomPickerMode.dateTimeWithSeconds,
|
||||
context,
|
||||
allowFuture: true,
|
||||
);
|
||||
if (picked != null) {
|
||||
setState(() {
|
||||
pd['WORK_EXPECTED_START_TIME'] = DateFormat(
|
||||
'yyyy-MM-dd HH:mm:ss',
|
||||
).format(picked);
|
||||
|
||||
ItemListWidget.selectableLineTitleTextRightButton(
|
||||
label: '作业视频监控:',
|
||||
isClean: widget.isEditable,
|
||||
cleanText: '清除监控',
|
||||
onTapClean: () {
|
||||
setState(() {
|
||||
pd['VIDEONAME'] = '';
|
||||
pd['VIDEOMANAGER_ID'] = '';
|
||||
});
|
||||
},
|
||||
isRequired: false,
|
||||
isEditable: widget.isEditable,
|
||||
onTap: widget.onChooseVideoManager ?? () {},
|
||||
text: pd['VIDEONAME'] ?? '',
|
||||
),
|
||||
const Divider(),
|
||||
ItemListWidget.selectableLineTitleTextRightButton(
|
||||
label: '预计作业开始时间:',
|
||||
isEditable: widget.isEditable,
|
||||
onTap: () async {
|
||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||
mode: BottomPickerMode.dateTimeWithSeconds,
|
||||
context,
|
||||
allowFuture: true,
|
||||
);
|
||||
if (picked != null) {
|
||||
setState(() {
|
||||
pd['WORK_EXPECTED_START_TIME'] = DateFormat(
|
||||
'yyyy-MM-dd HH:mm:ss',
|
||||
).format(picked);
|
||||
|
||||
/// 开始时间必须早于结束时间
|
||||
if (FormUtils.hasValue(pd, 'WORK_EXPECTED_END_TIME') &&
|
||||
!isBeforeStr(
|
||||
pd['WORK_EXPECTED_START_TIME'],
|
||||
pd['WORK_EXPECTED_END_TIME'],
|
||||
)) {
|
||||
pd['WORK_EXPECTED_END_TIME'] = '';
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
text: pd['WORK_EXPECTED_START_TIME'] ?? '',
|
||||
),
|
||||
const Divider(),
|
||||
ItemListWidget.selectableLineTitleTextRightButton(
|
||||
label: '预计作业结束时间:',
|
||||
isEditable: widget.isEditable,
|
||||
onTap: () async {
|
||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||
context,
|
||||
minTimeStr: pd['WORK_EXPECTED_START_TIME'] ?? '',
|
||||
allowFuture: true,
|
||||
);
|
||||
if (picked != null) {
|
||||
setState(() {
|
||||
pd['WORK_EXPECTED_END_TIME'] = DateFormat(
|
||||
'yyyy-MM-dd HH:mm:ss',
|
||||
).format(picked);
|
||||
});
|
||||
}
|
||||
},
|
||||
text: pd['WORK_EXPECTED_END_TIME'] ?? '',
|
||||
),
|
||||
/// 开始时间必须早于结束时间
|
||||
if (FormUtils.hasValue(pd, 'WORK_EXPECTED_END_TIME') &&
|
||||
!isBeforeStr(
|
||||
pd['WORK_EXPECTED_START_TIME'],
|
||||
pd['WORK_EXPECTED_END_TIME'],
|
||||
)) {
|
||||
pd['WORK_EXPECTED_END_TIME'] = '';
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
text: pd['WORK_EXPECTED_START_TIME'] ?? '',
|
||||
),
|
||||
const Divider(),
|
||||
ItemListWidget.selectableLineTitleTextRightButton(
|
||||
label: '预计作业结束时间:',
|
||||
isEditable: widget.isEditable,
|
||||
onTap: () async {
|
||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||
context,
|
||||
minTimeStr: pd['WORK_EXPECTED_START_TIME'] ?? '',
|
||||
allowFuture: true,
|
||||
);
|
||||
if (picked != null) {
|
||||
setState(() {
|
||||
pd['WORK_EXPECTED_END_TIME'] = DateFormat(
|
||||
'yyyy-MM-dd HH:mm:ss',
|
||||
).format(picked);
|
||||
});
|
||||
}
|
||||
},
|
||||
text: pd['WORK_EXPECTED_END_TIME'] ?? '',
|
||||
),
|
||||
],
|
||||
const Divider(),
|
||||
ListItemFactory.createYesNoSection(
|
||||
verticalPadding: 0,
|
||||
|
|
@ -353,10 +371,27 @@ class _ElectricityDetailFormWidgetState extends State<ElectricityDetailFormWidge
|
|||
hintText: '',
|
||||
text: pd['LATITUDE_LONGITUDE'] ?? (widget.isEditable ? '' : '无'),
|
||||
),
|
||||
const Divider(),
|
||||
ItemListWidget.selectableLineTitleTextRightButton(
|
||||
label: '作业视频监控:',
|
||||
isClean: widget.isEditable,
|
||||
cleanText: '清除监控',
|
||||
onTapClean: () {
|
||||
setState(() {
|
||||
pd['VIDEONAME'] = '';
|
||||
pd['VIDEOMANAGER_ID'] = '';
|
||||
});
|
||||
},
|
||||
isRequired: false,
|
||||
isEditable: widget.isEditable,
|
||||
onTap: widget.onChooseVideoManager ?? () {},
|
||||
text: pd['VIDEONAME'] ?? '',
|
||||
),
|
||||
|
||||
if (FormUtils.hasValue(pd, 'ANALYZE_TIME') && !widget.isEditable) ...[
|
||||
const Divider(),
|
||||
ItemListWidget.OneRowButtonTitleText(
|
||||
label: '分析人:',
|
||||
label: '气体分析信息:',
|
||||
text: pd['ANALYZE_USER_NAME'] ?? '',
|
||||
onTap: widget.onAnalyzeTap,
|
||||
),
|
||||
|
|
|
|||
|
|
@ -230,6 +230,7 @@ class SpecialWorkFormBaseWork extends StatelessWidget {
|
|||
onChooseLevel: onChooseLevel,
|
||||
onChooseHotworkUser: onChooseHotworkUser,
|
||||
onAnalyzeTap: onAnalyzeTap,
|
||||
signs: signs,
|
||||
),
|
||||
|
||||
// 2. 安全防护措施
|
||||
|
|
@ -264,137 +265,88 @@ class SpecialWorkFormBaseWork extends StatelessWidget {
|
|||
),
|
||||
),
|
||||
|
||||
// 4. 各环节签字及意见
|
||||
if (FormUtils.hasValue(signs, 'GUARDIAN'))
|
||||
signItemWidget('GUARDIAN', 'GUARDIAN_USER_NAME', '监护人', context),
|
||||
ConfirmWithSignWidget(
|
||||
signs: signs,
|
||||
pd: pd,
|
||||
baseImgPath: baseImgPath,
|
||||
sectionKey: 'GUARDIAN',
|
||||
nameKey: 'GUARDIAN_USER_NAME',
|
||||
headerTitle: '监护人签字',
|
||||
roleTitle: '监护人',
|
||||
),
|
||||
if (FormUtils.hasValue(signs, 'ELECTRICITY'))
|
||||
signItemWidget('ELECTRICITY', 'ELECTRICITY_USER_NAME', '用电人意见', context),
|
||||
ConfirmWithSignWidget(
|
||||
signs: signs,
|
||||
pd: pd,
|
||||
baseImgPath: baseImgPath,
|
||||
sectionKey: 'ELECTRICITY',
|
||||
nameKey: 'ELECTRICITY_USER_NAME',
|
||||
headerTitle: '用电人签字',
|
||||
roleTitle: '用电人',
|
||||
),
|
||||
if (FormUtils.hasValue(signs, 'CONFESS'))
|
||||
signItemWidget('CONFESS', 'CONFESS_USER_NAME', '安全交底人', context),
|
||||
ConfirmWithSignWidget(
|
||||
signs: signs,
|
||||
pd: pd,
|
||||
baseImgPath: baseImgPath,
|
||||
sectionKey: 'CONFESS',
|
||||
nameKey: 'CONFESS_USER_NAME',
|
||||
headerTitle: '安全交底人意见',
|
||||
roleTitle: '安全交底人',
|
||||
),
|
||||
if (FormUtils.hasValue(signs, 'ACCEPT_CONFESS'))
|
||||
signItemWidget('ACCEPT_CONFESS', 'ACCEPT_CONFESS_USER_NAME', '接受交底人', context),
|
||||
ConfirmWithSignWidget(
|
||||
signs: signs,
|
||||
pd: pd,
|
||||
baseImgPath: baseImgPath,
|
||||
sectionKey: 'ACCEPT_CONFESS',
|
||||
nameKey: 'ACCEPT_CONFESS_USER_NAME',
|
||||
headerTitle: '接受交底人',
|
||||
roleTitle: '',
|
||||
),
|
||||
|
||||
// 作业负责人意见
|
||||
if (FormUtils.hasValue(signs, 'CONFIRM')) ...[
|
||||
Column(
|
||||
children: [
|
||||
_itemContainer(
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Padding(padding: EdgeInsets.symmetric(horizontal: 8), child: ListItemFactory.headerTitle('作业负责人意见'),),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Text(signs['CONFIRM'][0]['DESCR'] ?? ''),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Divider(height: 1,),
|
||||
signItemWidget('CONFIRM', 'CONFIRM_USER_NAME', '作业负责人', context),
|
||||
],
|
||||
)
|
||||
if (FormUtils.hasValue(signs, 'CONFIRM'))
|
||||
ConfirmWithSignWidget(
|
||||
signs: signs,
|
||||
pd: pd,
|
||||
baseImgPath: baseImgPath,
|
||||
sectionKey: 'CONFIRM',
|
||||
nameKey: 'CONFIRM_USER_NAME',
|
||||
headerTitle: '作业负责人意见',
|
||||
roleTitle: '作业负责人',
|
||||
),
|
||||
if (FormUtils.hasValue(signs, 'AUDIT'))
|
||||
ConfirmWithSignWidget(
|
||||
signs: signs,
|
||||
pd: pd,
|
||||
baseImgPath: baseImgPath,
|
||||
sectionKey: 'AUDIT',
|
||||
nameKey: 'AUDIT_USER_NAME',
|
||||
headerTitle: '用电单位意见',
|
||||
roleTitle: '所在单位负责人',
|
||||
),
|
||||
if (FormUtils.hasValue(signs, 'APPROVE'))
|
||||
ConfirmWithSignWidget(
|
||||
signs: signs,
|
||||
pd: pd,
|
||||
baseImgPath: baseImgPath,
|
||||
sectionKey: 'APPROVE',
|
||||
nameKey: 'APPROVE_USER_NAME',
|
||||
headerTitle: '配送电单位意见',
|
||||
roleTitle: '配送电单位',
|
||||
),
|
||||
if (FormUtils.hasValue(signs, 'ACCEPT'))
|
||||
ConfirmWithSignWidget(
|
||||
signs: signs,
|
||||
pd: pd,
|
||||
baseImgPath: baseImgPath,
|
||||
sectionKey: 'ACCEPT',
|
||||
nameKey: 'ACCEPT_USER_NAME',
|
||||
headerTitle: '验收部门负责人意见',
|
||||
roleTitle: '验收部门负责人',
|
||||
),
|
||||
|
||||
],
|
||||
|
||||
// 所在单位负责人意见
|
||||
if (FormUtils.hasValue(signs, 'LEADER')) ...[
|
||||
Column(
|
||||
children: [
|
||||
_itemContainer(
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Padding(padding: EdgeInsets.symmetric(horizontal: 8), child: ListItemFactory.headerTitle('所在单位意见'),),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Text(signs['LEADER'][0]['DESCR'] ?? ''),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Divider(height: 1,),
|
||||
signItemWidget('LEADER', 'LEADER_USER_NAME', '所在单位负责人', context),
|
||||
],
|
||||
)
|
||||
],
|
||||
|
||||
// 安全管理部门负责人意见
|
||||
if (FormUtils.hasValue(signs, 'AUDIT')) ...[
|
||||
Column(
|
||||
children: [
|
||||
_itemContainer(
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Padding(padding: EdgeInsets.symmetric(horizontal: 8), child: ListItemFactory.headerTitle('安全管理部门意见'),),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Text(signs['AUDIT'][0]['DESCR'] ?? ''),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Divider(height: 1,),
|
||||
signItemWidget('AUDIT', 'AUDIT_USER_NAME', '安全管理部门负责人', context),
|
||||
],
|
||||
)
|
||||
],
|
||||
|
||||
// 动火审批人意见
|
||||
if (FormUtils.hasValue(signs, 'APPROVE')) ...[
|
||||
Column(
|
||||
children: [
|
||||
_itemContainer(
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Padding(padding: EdgeInsets.symmetric(horizontal: 8), child: ListItemFactory.headerTitle('动火审批人意见'),),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Text(signs['APPROVE'][0]['DESCR'] ?? ''),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Divider(height: 1,),
|
||||
signItemWidget('APPROVE', 'APPROVE_USER_NAME', '动火审批人', context),
|
||||
],
|
||||
)
|
||||
],
|
||||
|
||||
if (FormUtils.hasValue(signs, 'MONITOR'))
|
||||
signItemWidget('MONITOR', 'MONITOR_USER_NAME', '动火前在岗班长', context),
|
||||
|
||||
// 作业开始负责人签字
|
||||
// if (FormUtils.hasValue(signs, 'WORK_START'))
|
||||
// signItemWidget('WORK_START', 'WORK_START_USER_NAME', '作业开始负责人', context),
|
||||
//
|
||||
// // 作业结束负责人签字
|
||||
// if (FormUtils.hasValue(signs, 'WORK_END'))
|
||||
// signItemWidget('WORK_END', 'WORK_END_USER_NAME', '作业结束负责人', context),
|
||||
|
||||
// 完工验收意见和签字
|
||||
if (FormUtils.hasValue(signs, 'ACCEPT')) ...[
|
||||
Column(
|
||||
children: [
|
||||
_itemContainer(
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Padding(padding: EdgeInsets.symmetric(horizontal: 8), child: ListItemFactory.headerTitle('完工验收意见'),),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Text(signs['ACCEPT'][0]['DESCR'] ?? ''),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Divider(height: 1,),
|
||||
signItemWidget('ACCEPT', 'ACCEPT_USER_NAME', '验收部门负责人', context),
|
||||
],
|
||||
)
|
||||
],
|
||||
],
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -450,6 +450,7 @@ class _ElectricitySafeFuncSureState extends State<ElectricitySafeFuncSure> {
|
|||
context,
|
||||
);
|
||||
},
|
||||
signs: {},
|
||||
),
|
||||
SizedBox(height: 20),
|
||||
_setSafeDetailWidget(),
|
||||
|
|
|
|||
|
|
@ -58,7 +58,6 @@ class _ElectricityListPageState extends State<ElectricityListPage> {
|
|||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_fetchSteps();
|
||||
_fetchData();
|
||||
_scrollController.addListener(_onScroll);
|
||||
}
|
||||
|
|
@ -137,12 +136,14 @@ class _ElectricityListPageState extends State<ElectricityListPage> {
|
|||
}
|
||||
|
||||
/// 申请
|
||||
void _handleApply() {
|
||||
void _handleApply() async{
|
||||
// 处理申请按钮点击逻辑
|
||||
pushPage(
|
||||
await pushPage(
|
||||
ElectricityApplyDetail(ELECTRICITY_ID: '', flow: widget.flow),
|
||||
context,
|
||||
);
|
||||
_fetchData();
|
||||
LoadingDialogHelper.hide();
|
||||
}
|
||||
|
||||
/// 打开流程图
|
||||
|
|
@ -317,9 +318,10 @@ class _ElectricityListPageState extends State<ElectricityListPage> {
|
|||
default:
|
||||
break;
|
||||
}
|
||||
LoadingDialogHelper.show();
|
||||
_fetchSteps();
|
||||
_fetchData();
|
||||
|
||||
|
||||
await _fetchData();
|
||||
LoadingDialogHelper.hide();
|
||||
}
|
||||
|
||||
Widget _buildFlowStepItem({
|
||||
|
|
|
|||
|
|
@ -334,6 +334,7 @@ class _ElectricityJhrDetailState extends State<ElectricityJhrDetail> {
|
|||
context,
|
||||
);
|
||||
},
|
||||
signs: {},
|
||||
),
|
||||
SizedBox(height: 20),
|
||||
_setSafeDetailWidget(),
|
||||
|
|
|
|||
|
|
@ -207,6 +207,7 @@ class _ElectricityJszyDetailState extends State<ElectricityJszyDetail> {
|
|||
child: SingleChildScrollView(
|
||||
padding: EdgeInsets.all(12),
|
||||
child: Column(
|
||||
spacing: 12,
|
||||
children: [
|
||||
// _setSafeDetailWidget(),
|
||||
SpecialWorkFormBaseWork(
|
||||
|
|
@ -253,7 +254,6 @@ class _ElectricityJszyDetailState extends State<ElectricityJszyDetail> {
|
|||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 12,),
|
||||
_bottomButtons(),
|
||||
],
|
||||
),
|
||||
|
|
|
|||
|
|
@ -201,6 +201,7 @@ class _ElectricityKszyDetailState extends State<ElectricityKszyDetail> {
|
|||
child: SingleChildScrollView(
|
||||
padding: EdgeInsets.all(12),
|
||||
child: Column(
|
||||
spacing: 12,
|
||||
children: [
|
||||
// _setSafeDetailWidget(),
|
||||
SpecialWorkFormBaseWork(
|
||||
|
|
@ -246,7 +247,6 @@ class _ElectricityKszyDetailState extends State<ElectricityKszyDetail> {
|
|||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 12,),
|
||||
_bottomButtons(),
|
||||
],
|
||||
),
|
||||
|
|
|
|||
|
|
@ -218,9 +218,12 @@ class _ElectricityApplyDetailState extends State<ElectricityApplyDetail> {
|
|||
builder:
|
||||
(_) => WorkAreaPicker(
|
||||
onSelected: (String id, String POSITIONS, String name) {
|
||||
pd['ELECTRONIC_FENCE_AREA_ID'] = id;
|
||||
pd['POSITIONS'] = POSITIONS;
|
||||
pd['PLS_NAME'] = name;
|
||||
setState(() {
|
||||
pd['ELECTRONIC_FENCE_AREA_ID'] = id;
|
||||
pd['POSITIONS'] = POSITIONS;
|
||||
pd['PLS_NAME'] = name;
|
||||
});
|
||||
|
||||
},
|
||||
),
|
||||
).then((_) {
|
||||
|
|
@ -635,6 +638,7 @@ class _ElectricityApplyDetailState extends State<ElectricityApplyDetail> {
|
|||
context,
|
||||
);
|
||||
},
|
||||
signs: {},
|
||||
// 新增
|
||||
onChooseVideoManager: _chooseVideoManager,
|
||||
onContractorHandle: _chooseUnitManager,
|
||||
|
|
|
|||
|
|
@ -348,7 +348,7 @@ class _ElectricitySetSafeDetailState extends State<ElectricitySetSafeDetail> {
|
|||
}
|
||||
|
||||
Future<void> _getMeasures() async {
|
||||
final data = await ApiService.listSignFinishAllMeasures('electricity');
|
||||
final data = await ApiService.listSignFinishAllMeasures('electricity', widget.ELECTRICITY_ID);
|
||||
setState(() {
|
||||
measuresList = List<Map<String, dynamic>>.from(
|
||||
data['measuresList'] ?? <Map<String, dynamic>>[],
|
||||
|
|
@ -568,6 +568,7 @@ class _ElectricitySetSafeDetailState extends State<ElectricitySetSafeDetail> {
|
|||
context,
|
||||
);
|
||||
},
|
||||
signs: {},
|
||||
),
|
||||
SizedBox(height: 20),
|
||||
_setSafeDetailWidget(),
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/lsyd_work/Spe
|
|||
import 'package:qhd_prevention/customWidget/custom_alert_dialog.dart';
|
||||
import 'package:qhd_prevention/customWidget/single_image_viewer.dart';
|
||||
import 'package:qhd_prevention/pages/mine/mine_sign_page.dart';
|
||||
|
||||
/// 用电人签字
|
||||
class ElectricityYdrDetail extends StatefulWidget {
|
||||
const ElectricityYdrDetail({
|
||||
|
|
@ -29,13 +30,14 @@ class ElectricityYdrDetail extends StatefulWidget {
|
|||
|
||||
class _ElectricityYdrDetailState extends State<ElectricityYdrDetail> {
|
||||
late bool isEditable = false;
|
||||
|
||||
/// 详情
|
||||
late Map<String, dynamic> pd = {};
|
||||
|
||||
/// 安全防护措施列表
|
||||
late List<Map<String, dynamic>> measuresList = [];
|
||||
late Map<String, dynamic> signs = {};
|
||||
|
||||
|
||||
List<String> imagePaths = [];
|
||||
List<String> signTimes = []; // 签字时间列表
|
||||
@override
|
||||
|
|
@ -52,7 +54,7 @@ class _ElectricityYdrDetailState extends State<ElectricityYdrDetail> {
|
|||
MaterialPageRoute(builder: (context) => MineSignPage()),
|
||||
);
|
||||
await NativeOrientation.setPortrait();
|
||||
if (path != null) {
|
||||
if (path != null) {
|
||||
final now = DateFormat('yyyy-MM-dd HH:mm').format(DateTime.now());
|
||||
setState(() {
|
||||
imagePaths.add(path);
|
||||
|
|
@ -134,7 +136,7 @@ if (path != null) {
|
|||
title: '作废原因',
|
||||
hintText: '请输入作废原因',
|
||||
cancelText: '取消',
|
||||
confirmText: '确定'
|
||||
confirmText: '确定',
|
||||
);
|
||||
if (reasonText.isEmpty) {
|
||||
ToastUtil.showNormal(context, '请填写作废原因');
|
||||
|
|
@ -159,32 +161,31 @@ if (path != null) {
|
|||
barrierDismissible: false,
|
||||
);
|
||||
if (confirmed) {
|
||||
LoadingDialogHelper.show();
|
||||
try {
|
||||
final result = await ApiService.saveSafeFunctionSure(
|
||||
'electricity',
|
||||
formData,
|
||||
imagePaths,
|
||||
);
|
||||
LoadingDialogHelper.hide();
|
||||
if (result['result'] == 'success') {
|
||||
ToastUtil.showSuccess(
|
||||
context,
|
||||
'保存成功',
|
||||
);
|
||||
Navigator.of(context).pop(true);
|
||||
}
|
||||
} catch (e) {
|
||||
LoadingDialogHelper.hide();
|
||||
ToastUtil.showNormal(context, '操作失败:$e');
|
||||
}
|
||||
|
||||
LoadingDialogHelper.show();
|
||||
try {
|
||||
final result = await ApiService.saveSafeFunctionSure(
|
||||
'electricity',
|
||||
formData,
|
||||
imagePaths,
|
||||
);
|
||||
LoadingDialogHelper.hide();
|
||||
if (result['result'] == 'success') {
|
||||
ToastUtil.showSuccess(context, '保存成功');
|
||||
Navigator.of(context).pop(true);
|
||||
}
|
||||
} catch (e) {
|
||||
LoadingDialogHelper.hide();
|
||||
ToastUtil.showNormal(context, '操作失败:$e');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 初始化拉取数据
|
||||
Future<void> _getData() async {
|
||||
final data = await ApiService.getHomeworkFindById('electricity', widget.ELECTRICITY_ID);
|
||||
final data = await ApiService.getHomeworkFindById(
|
||||
'electricity',
|
||||
widget.ELECTRICITY_ID,
|
||||
);
|
||||
setState(() {
|
||||
pd = data['pd'];
|
||||
|
||||
|
|
@ -194,7 +195,8 @@ if (path != null) {
|
|||
}
|
||||
|
||||
Future<void> _getMeasures(String homework_id) async {
|
||||
final data = await ApiService.listSignFinishMeasures('electricity',
|
||||
final data = await ApiService.listSignFinishMeasures(
|
||||
'electricity',
|
||||
homework_id.length > 0 ? homework_id : widget.ELECTRICITY_ID,
|
||||
);
|
||||
setState(() {
|
||||
|
|
@ -205,7 +207,8 @@ if (path != null) {
|
|||
}
|
||||
|
||||
Future<void> _getSigns(String homework_id) async {
|
||||
final data = await ApiService.listSignFinished('electricity',
|
||||
final data = await ApiService.listSignFinished(
|
||||
'electricity',
|
||||
homework_id.length > 0 ? homework_id : widget.ELECTRICITY_ID,
|
||||
);
|
||||
setState(() {
|
||||
|
|
|
|||
|
|
@ -490,7 +490,10 @@ class _BlindboardDetailFormWidgetState
|
|||
ItemListWidget.selectableLineTitleTextRightButton(
|
||||
label: '盲板作业实施时间:',
|
||||
isEditable: widget.isEditable,
|
||||
text: pd['WORK_START_DATE'] ?? '',
|
||||
text:
|
||||
FormUtils.hasValue(pd, 'WORK_END_DATE')
|
||||
? '${pd['WORK_START_DATE'] ?? ''}\n-${pd['WORK_END_DATE'] ?? ''}'
|
||||
: pd['WORK_START_DATE'] ?? '',
|
||||
),
|
||||
] else ...[
|
||||
const Divider(),
|
||||
|
|
@ -543,9 +546,8 @@ class _BlindboardDetailFormWidgetState
|
|||
text: pd['WORK_EXPECTED_END_TIME'] ?? '',
|
||||
),
|
||||
],
|
||||
if (!widget.isEditable &&
|
||||
FormUtils.hasValue(pd, 'BOARD_PATH_NO'))
|
||||
ConfirmWithSignWidget(
|
||||
if (!widget.isEditable && FormUtils.hasValue(pd, 'BOARD_PATH_NO'))
|
||||
ConfirmWithSignWidget(
|
||||
signs: widget.signs,
|
||||
pd: pd,
|
||||
baseImgPath: ApiService.baseImgPath,
|
||||
|
|
@ -557,17 +559,35 @@ class _BlindboardDetailFormWidgetState
|
|||
roleTitle: '',
|
||||
),
|
||||
|
||||
if (FormUtils.hasValue(pd, 'CONFIRM_USER_NAME') && !widget.isEditable) ...[
|
||||
if (FormUtils.hasValue(pd, 'CONFIRM_USER_NAME') &&
|
||||
!widget.isEditable) ...[
|
||||
const Divider(),
|
||||
SignRowImageTitle(label: '作业负责人:', signKey: 'CONFIRM', signs: widget.signs, text: pd['CONFIRM_USER_NAME']??'',),
|
||||
SignRowImageTitle(
|
||||
label: '作业负责人:',
|
||||
signKey: 'CONFIRM',
|
||||
signs: widget.signs,
|
||||
text: pd['CONFIRM_USER_NAME'] ?? '',
|
||||
),
|
||||
],
|
||||
if (FormUtils.hasValue(pd, 'WORK_USER_USER_NAME') && !widget.isEditable) ...[
|
||||
if (FormUtils.hasValue(pd, 'WORK_USER_USER_NAME') &&
|
||||
!widget.isEditable) ...[
|
||||
const Divider(),
|
||||
SignRowImageTitle(label: '作业人:', signKey: 'WORK_USER', signs: widget.signs, text: pd['WORK_USER_USER_NAME']??'',),
|
||||
SignRowImageTitle(
|
||||
label: '作业人:',
|
||||
signKey: 'WORK_USER',
|
||||
signs: widget.signs,
|
||||
text: pd['WORK_USER_USER_NAME'] ?? '',
|
||||
),
|
||||
],
|
||||
if (FormUtils.hasValue(pd, 'GUARDIAN_USER_NAME') && !widget.isEditable) ...[
|
||||
if (FormUtils.hasValue(pd, 'GUARDIAN_USER_NAME') &&
|
||||
!widget.isEditable) ...[
|
||||
const Divider(),
|
||||
SignRowImageTitle(label: '监护人:', signKey: 'GUARDIAN', signs: widget.signs, text: pd['GUARDIAN_USER_NAME']??'',),
|
||||
SignRowImageTitle(
|
||||
label: '监护人:',
|
||||
signKey: 'GUARDIAN',
|
||||
signs: widget.signs,
|
||||
text: pd['GUARDIAN_USER_NAME'] ?? '',
|
||||
),
|
||||
],
|
||||
const Divider(),
|
||||
|
||||
|
|
|
|||
|
|
@ -142,9 +142,11 @@ class _BlindboardListPageState extends State<BlindboardListPage> {
|
|||
}
|
||||
|
||||
/// 申请
|
||||
void _handleApply() {
|
||||
void _handleApply() async{
|
||||
// 处理申请按钮点击逻辑
|
||||
pushPage(BlindboardApplyDetail(BLINDBOARD_ID: '', flow: widget.flow), context);
|
||||
await pushPage(BlindboardApplyDetail(BLINDBOARD_ID: '', flow: widget.flow), context);
|
||||
_fetchData();
|
||||
LoadingDialogHelper.hide();
|
||||
}
|
||||
|
||||
/// 打开流程图
|
||||
|
|
@ -228,9 +230,10 @@ class _BlindboardListPageState extends State<BlindboardListPage> {
|
|||
default:
|
||||
break;
|
||||
}
|
||||
LoadingDialogHelper.show();
|
||||
_fetchSteps();
|
||||
_fetchData();
|
||||
|
||||
|
||||
await _fetchData();
|
||||
LoadingDialogHelper.hide();
|
||||
}
|
||||
|
||||
Widget _buildFlowStepItem({
|
||||
|
|
|
|||
|
|
@ -208,6 +208,7 @@ class _BlindboardJszyDetailState extends State<BlindboardJszyDetail> {
|
|||
child: SingleChildScrollView(
|
||||
padding: EdgeInsets.all(12),
|
||||
child: Column(
|
||||
spacing: 12,
|
||||
children: [
|
||||
// _setSafeDetailWidget(),
|
||||
BlindboardFormBaseWork(
|
||||
|
|
@ -248,7 +249,6 @@ class _BlindboardJszyDetailState extends State<BlindboardJszyDetail> {
|
|||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 12,),
|
||||
_bottomButtons(),
|
||||
],
|
||||
),
|
||||
|
|
|
|||
|
|
@ -192,6 +192,7 @@ class _BlindboardKszyDetailState extends State<BlindboardKszyDetail> {
|
|||
child: SingleChildScrollView(
|
||||
padding: EdgeInsets.all(12),
|
||||
child: Column(
|
||||
spacing: 12,
|
||||
children: [
|
||||
// _setSafeDetailWidget(),
|
||||
BlindboardFormBaseWork(
|
||||
|
|
@ -238,7 +239,6 @@ class _BlindboardKszyDetailState extends State<BlindboardKszyDetail> {
|
|||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 12,),
|
||||
_bottomButtons(),
|
||||
],
|
||||
),
|
||||
|
|
|
|||
|
|
@ -209,9 +209,11 @@ class _BlindboardApplyDetailState extends State<BlindboardApplyDetail> {
|
|||
builder:
|
||||
(_) => WorkAreaPicker(
|
||||
onSelected: (String id, String POSITIONS, String name) {
|
||||
pd['ELECTRONIC_FENCE_AREA_ID'] = id;
|
||||
pd['POSITIONS'] = POSITIONS;
|
||||
pd['PLS_NAME'] = name;
|
||||
setState(() {
|
||||
pd['ELECTRONIC_FENCE_AREA_ID'] = id;
|
||||
pd['POSITIONS'] = POSITIONS;
|
||||
pd['PLS_NAME'] = name;
|
||||
});
|
||||
},
|
||||
),
|
||||
).then((_) {
|
||||
|
|
|
|||
|
|
@ -362,7 +362,7 @@ class _BlindboardSetSafeDetailState extends State<BlindboardSetSafeDetail> {
|
|||
}
|
||||
|
||||
Future<void> _getMeasures() async {
|
||||
final data = await ApiService.listSignFinishAllMeasures('blindboard');
|
||||
final data = await ApiService.listSignFinishAllMeasures('blindboard', widget.BLINDBOARD_ID);
|
||||
setState(() {
|
||||
measuresList = List<Map<String, dynamic>>.from(
|
||||
data['measuresList'] ?? <Map<String, dynamic>>[],
|
||||
|
|
|
|||
|
|
@ -9,17 +9,24 @@ import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/MeasuresListW
|
|||
/// 通用明细表单组件(支持编辑/只读)
|
||||
class SpaceWorkDetailFormWidget extends StatefulWidget {
|
||||
final Map<String, dynamic> pd;
|
||||
/// 其他签字数据
|
||||
final Map<String, dynamic> signs;
|
||||
final bool isEditable;
|
||||
late bool isEditSpaceName; // 是否手动输入受限空间名称
|
||||
final VoidCallback onChooseLevel;
|
||||
final VoidCallback onChooseSpaceName;
|
||||
final VoidCallback onAnalyzeTap;
|
||||
// 新增
|
||||
/// 选择摄像头
|
||||
final VoidCallback? onChooseVideoManager;/// 承包商
|
||||
|
||||
// 新增
|
||||
/// 选择摄像头
|
||||
final VoidCallback? onChooseVideoManager;
|
||||
|
||||
/// 承包商
|
||||
final VoidCallback? onContractorHandle;
|
||||
|
||||
/// 作业区域
|
||||
final VoidCallback? onWorkAreaHandle;
|
||||
|
||||
/// 作业地点经纬度
|
||||
final VoidCallback? onWorkAreaLocationHandle;
|
||||
|
||||
|
|
@ -38,13 +45,17 @@ class SpaceWorkDetailFormWidget extends StatefulWidget {
|
|||
required this.onChooseLevel,
|
||||
required this.onChooseSpaceName,
|
||||
required this.onAnalyzeTap,
|
||||
required this.signs,
|
||||
|
||||
/// 新增
|
||||
this.onChooseVideoManager,
|
||||
this.onContractorHandle,
|
||||
this.onWorkAreaHandle,
|
||||
this.onWorkAreaLocationHandle,
|
||||
|
||||
this.isEditSpaceName = false, /// 受限空间可选择可手写,默认选择,受限空间编号也要跟着变化
|
||||
this.isEditSpaceName = false,
|
||||
|
||||
/// 受限空间可选择可手写,默认选择,受限空间编号也要跟着变化
|
||||
this.contentController,
|
||||
this.spaceNameController,
|
||||
this.spaceNumberController,
|
||||
|
|
@ -72,7 +83,8 @@ class _SpaceWorkDetailFormWidgetState extends State<SpaceWorkDetailFormWidget> {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (FormUtils.hasValue(widget.pd, 'LATITUDE')) {
|
||||
widget.pd['LATITUDE_LONGITUDE'] = '${widget.pd['LATITUDE']},${widget.pd['LONGITUDE']}'; //参数map
|
||||
widget.pd['LATITUDE_LONGITUDE'] =
|
||||
'${widget.pd['LATITUDE']},${widget.pd['LONGITUDE']}'; //参数map
|
||||
}
|
||||
final pd = widget.pd;
|
||||
|
||||
|
|
@ -85,6 +97,14 @@ class _SpaceWorkDetailFormWidgetState extends State<SpaceWorkDetailFormWidget> {
|
|||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
if (FormUtils.hasValue(pd, 'CHECK_NO')) ...[
|
||||
ItemListWidget.singleLineTitleText(
|
||||
label: '编号:',
|
||||
isEditable: false,
|
||||
text: pd['CHECK_NO'] ?? '',
|
||||
),
|
||||
const Divider(),
|
||||
],
|
||||
ItemListWidget.singleLineTitleText(
|
||||
label: '作业申请单位:',
|
||||
isEditable: false,
|
||||
|
|
@ -96,32 +116,24 @@ class _SpaceWorkDetailFormWidgetState extends State<SpaceWorkDetailFormWidget> {
|
|||
isEditable: false,
|
||||
text: pd['APPLY_USER_NAME'] ?? '',
|
||||
),
|
||||
if (FormUtils.hasValue(pd, 'CHECK_NO')) ...[
|
||||
const Divider(),
|
||||
ItemListWidget.singleLineTitleText(
|
||||
label: '编号:',
|
||||
isEditable: false,
|
||||
text: pd['CHECK_NO'] ?? '',
|
||||
),
|
||||
],
|
||||
const Divider(),
|
||||
if (!widget.isEditSpaceName)
|
||||
ItemListWidget.selectableLineTitleTextRightButton(
|
||||
label: '受限空间名称:',
|
||||
isEditable: widget.isEditable,
|
||||
cleanText: '输入',
|
||||
isClean: widget.isEditable,
|
||||
text: pd['LIMITSPACE_NAME'] ?? '',
|
||||
onTapClean: () {
|
||||
setState(() {
|
||||
pd['LIMITSPACE_NAME'] = '';
|
||||
pd['LIMITSPACE_NUMBER'] = '';
|
||||
ItemListWidget.selectableLineTitleTextRightButton(
|
||||
label: '受限空间名称:',
|
||||
isEditable: widget.isEditable,
|
||||
cleanText: '输入',
|
||||
isClean: widget.isEditable,
|
||||
text: pd['LIMITSPACE_NAME'] ?? '',
|
||||
onTapClean: () {
|
||||
setState(() {
|
||||
pd['LIMITSPACE_NAME'] = '';
|
||||
pd['LIMITSPACE_NUMBER'] = '';
|
||||
|
||||
widget.isEditSpaceName = !widget.isEditSpaceName;
|
||||
});
|
||||
},
|
||||
onTap: widget.onChooseSpaceName,
|
||||
),
|
||||
widget.isEditSpaceName = !widget.isEditSpaceName;
|
||||
});
|
||||
},
|
||||
onTap: widget.onChooseSpaceName,
|
||||
),
|
||||
if (widget.isEditSpaceName)
|
||||
ItemListWidget.selectableLineTitleTextField(
|
||||
label: '受限空间名称:',
|
||||
|
|
@ -138,7 +150,8 @@ class _SpaceWorkDetailFormWidgetState extends State<SpaceWorkDetailFormWidget> {
|
|||
},
|
||||
onTap: widget.onChooseSpaceName,
|
||||
),
|
||||
if (FormUtils.hasValue(pd, 'LIMITSPACE_NUMBER') || widget.isEditable) ...[
|
||||
if (FormUtils.hasValue(pd, 'LIMITSPACE_NUMBER') ||
|
||||
widget.isEditable) ...[
|
||||
const Divider(),
|
||||
ItemListWidget.singleLineTitleText(
|
||||
label: '受限空间编号:',
|
||||
|
|
@ -162,22 +175,45 @@ class _SpaceWorkDetailFormWidgetState extends State<SpaceWorkDetailFormWidget> {
|
|||
controller: widget.contentController,
|
||||
text: pd['WORK_CONTENT'] ?? '',
|
||||
),
|
||||
if (FormUtils.hasValue(pd, 'WORK_START_DATE')) ...[
|
||||
if (FormUtils.hasValue(pd, 'CONFIRM_DEPARTMENT_NAME')) ...[
|
||||
const Divider(),
|
||||
ItemListWidget.selectableLineTitleTextRightButton(
|
||||
label: '作业开始时间:',
|
||||
ItemListWidget.singleLineTitleText(
|
||||
label: '作业单位:',
|
||||
isEditable: false,
|
||||
text: pd['WORK_START_DATE'] ?? '',
|
||||
text: pd['CONFIRM_DEPARTMENT_NAME'] ?? '',
|
||||
),
|
||||
],
|
||||
if (FormUtils.hasValue(pd, 'WORK_END_DATE')) ...[
|
||||
if (FormUtils.hasValue(pd, 'CONFIRM_USER_NAME') &&
|
||||
!widget.isEditable) ...[
|
||||
const Divider(),
|
||||
ItemListWidget.selectableLineTitleTextRightButton(
|
||||
label: '作业结束时间:',
|
||||
isEditable: false,
|
||||
text: pd['WORK_END_DATE'] ?? '',
|
||||
SignRowImageTitle(
|
||||
label: '作业负责人:',
|
||||
signKey: 'CONFIRM',
|
||||
signs: widget.signs,
|
||||
text: pd['CONFIRM_USER_NAME'] ?? '',
|
||||
),
|
||||
],
|
||||
if (FormUtils.hasValue(pd, 'WORK_USER_USER_NAME') &&
|
||||
!widget.isEditable) ...[
|
||||
const Divider(),
|
||||
SignRowImageTitle(
|
||||
label: '作业人:',
|
||||
signKey: 'WORK_USER',
|
||||
signs: widget.signs,
|
||||
text: pd['WORK_USER_USER_NAME'] ?? '',
|
||||
),
|
||||
],
|
||||
if (FormUtils.hasValue(pd, 'GUARDIAN_USER_NAME') &&
|
||||
!widget.isEditable) ...[
|
||||
const Divider(),
|
||||
SignRowImageTitle(
|
||||
label: '监护人:',
|
||||
signKey: 'GUARDIAN',
|
||||
signs: widget.signs,
|
||||
text: pd['GUARDIAN_USER_NAME'] ?? '',
|
||||
),
|
||||
],
|
||||
|
||||
const Divider(),
|
||||
ItemListWidget.twoRowButtonTitleText(
|
||||
label: '关联其他特殊作业及安全作业票编号',
|
||||
|
|
@ -229,71 +265,67 @@ class _SpaceWorkDetailFormWidgetState extends State<SpaceWorkDetailFormWidget> {
|
|||
controller: widget.riskController,
|
||||
text: pd['RISK_IDENTIFICATION'] ?? '',
|
||||
),
|
||||
const Divider(),
|
||||
ItemListWidget.selectableLineTitleTextRightButton(
|
||||
label: '作业视频监控:',
|
||||
isClean: widget.isEditable,
|
||||
cleanText: '清除监控',
|
||||
onTapClean: () {
|
||||
setState(() {
|
||||
pd['VIDEONAME'] = '';
|
||||
pd['VIDEOMANAGER_ID'] = '';
|
||||
});
|
||||
},
|
||||
isRequired: false,
|
||||
isEditable: widget.isEditable,
|
||||
onTap: widget.onChooseVideoManager ?? () {},
|
||||
text: pd['VIDEONAME'] ?? '',
|
||||
),
|
||||
const Divider(),
|
||||
ItemListWidget.selectableLineTitleTextRightButton(
|
||||
label: '预计作业开始时间:',
|
||||
isEditable: widget.isEditable,
|
||||
onTap: () async {
|
||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||
mode: BottomPickerMode.dateTimeWithSeconds,
|
||||
context,
|
||||
allowFuture: true,
|
||||
);
|
||||
if (picked != null) {
|
||||
setState(() {
|
||||
pd['WORK_EXPECTED_START_TIME'] = DateFormat(
|
||||
'yyyy-MM-dd HH:mm:ss',
|
||||
).format(picked);
|
||||
if (FormUtils.hasValue(pd, 'WORK_START_DATE')) ...[
|
||||
const Divider(),
|
||||
ItemListWidget.selectableLineTitleTextRightButton(
|
||||
label: '作业实施时间:',
|
||||
isEditable: widget.isEditable,
|
||||
text:
|
||||
FormUtils.hasValue(pd, 'WORK_END_DATE')
|
||||
? '${pd['WORK_START_DATE'] ?? ''}\n-${pd['WORK_END_DATE'] ?? ''}'
|
||||
: pd['WORK_START_DATE'] ?? '',
|
||||
),
|
||||
] else ...[
|
||||
const Divider(),
|
||||
ItemListWidget.selectableLineTitleTextRightButton(
|
||||
label: '预计作业开始时间:',
|
||||
isEditable: widget.isEditable,
|
||||
onTap: () async {
|
||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||
mode: BottomPickerMode.dateTimeWithSeconds,
|
||||
context,
|
||||
allowFuture: true,
|
||||
);
|
||||
if (picked != null) {
|
||||
setState(() {
|
||||
pd['WORK_EXPECTED_START_TIME'] = DateFormat(
|
||||
'yyyy-MM-dd HH:mm:ss',
|
||||
).format(picked);
|
||||
|
||||
/// 开始时间必须早于结束时间
|
||||
if (FormUtils.hasValue(pd, 'WORK_EXPECTED_END_TIME') &&
|
||||
!isBeforeStr(
|
||||
pd['WORK_EXPECTED_START_TIME'],
|
||||
pd['WORK_EXPECTED_END_TIME'],
|
||||
)) {
|
||||
pd['WORK_EXPECTED_END_TIME'] = '';
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
text: pd['WORK_EXPECTED_START_TIME'] ?? '',
|
||||
),
|
||||
const Divider(),
|
||||
ItemListWidget.selectableLineTitleTextRightButton(
|
||||
label: '预计作业结束时间:',
|
||||
isEditable: widget.isEditable,
|
||||
onTap: () async {
|
||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||
context,
|
||||
minTimeStr: pd['WORK_EXPECTED_START_TIME'] ?? '',
|
||||
allowFuture: true,
|
||||
);
|
||||
if (picked != null) {
|
||||
setState(() {
|
||||
pd['WORK_EXPECTED_END_TIME'] = DateFormat(
|
||||
'yyyy-MM-dd HH:mm:ss',
|
||||
).format(picked);
|
||||
});
|
||||
}
|
||||
},
|
||||
text: pd['WORK_EXPECTED_END_TIME'] ?? '',
|
||||
),
|
||||
/// 开始时间必须早于结束时间
|
||||
if (FormUtils.hasValue(pd, 'WORK_EXPECTED_END_TIME') &&
|
||||
!isBeforeStr(
|
||||
pd['WORK_EXPECTED_START_TIME'],
|
||||
pd['WORK_EXPECTED_END_TIME'],
|
||||
)) {
|
||||
pd['WORK_EXPECTED_END_TIME'] = '';
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
text: pd['WORK_EXPECTED_START_TIME'] ?? '',
|
||||
),
|
||||
const Divider(),
|
||||
ItemListWidget.selectableLineTitleTextRightButton(
|
||||
label: '预计作业结束时间:',
|
||||
isEditable: widget.isEditable,
|
||||
onTap: () async {
|
||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||
context,
|
||||
minTimeStr: pd['WORK_EXPECTED_START_TIME'] ?? '',
|
||||
allowFuture: true,
|
||||
);
|
||||
if (picked != null) {
|
||||
setState(() {
|
||||
pd['WORK_EXPECTED_END_TIME'] = DateFormat(
|
||||
'yyyy-MM-dd HH:mm:ss',
|
||||
).format(picked);
|
||||
});
|
||||
}
|
||||
},
|
||||
text: pd['WORK_EXPECTED_END_TIME'] ?? '',
|
||||
),
|
||||
],
|
||||
const Divider(),
|
||||
ListItemFactory.createYesNoSection(
|
||||
verticalPadding: 0,
|
||||
|
|
@ -336,14 +368,32 @@ class _SpaceWorkDetailFormWidgetState extends State<SpaceWorkDetailFormWidget> {
|
|||
isInput: false,
|
||||
isEditable: widget.isEditable,
|
||||
buttonText: '定位',
|
||||
onTap: widget.onWorkAreaLocationHandle ?? (){},
|
||||
onTap: widget.onWorkAreaLocationHandle ?? () {},
|
||||
hintText: '',
|
||||
text: pd['LATITUDE_LONGITUDE'] ?? (widget.isEditable ? '' : '无'),
|
||||
),
|
||||
const Divider(),
|
||||
|
||||
ItemListWidget.selectableLineTitleTextRightButton(
|
||||
label: '作业视频监控:',
|
||||
isClean: widget.isEditable,
|
||||
cleanText: '清除监控',
|
||||
onTapClean: () {
|
||||
setState(() {
|
||||
pd['VIDEONAME'] = '';
|
||||
pd['VIDEOMANAGER_ID'] = '';
|
||||
});
|
||||
},
|
||||
isRequired: false,
|
||||
isEditable: widget.isEditable,
|
||||
onTap: widget.onChooseVideoManager ?? () {},
|
||||
text: pd['VIDEONAME'] ?? '',
|
||||
),
|
||||
|
||||
if (FormUtils.hasValue(pd, 'ANALYZE_TIME') && !widget.isEditable) ...[
|
||||
const Divider(),
|
||||
ItemListWidget.OneRowButtonTitleText(
|
||||
label: '分析人:',
|
||||
label: '气体分析信息:',
|
||||
text: pd['ANALYZE_USER_NAME'] ?? '',
|
||||
onTap: widget.onAnalyzeTap,
|
||||
),
|
||||
|
|
|
|||
|
|
@ -55,168 +55,6 @@ class SpecialWorkFormBaseWork extends StatelessWidget {
|
|||
);
|
||||
}
|
||||
|
||||
Widget signItemWidget(
|
||||
String signKey,
|
||||
String nameKey,
|
||||
String name,
|
||||
BuildContext context,
|
||||
) {
|
||||
return _itemContainer(
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
// 标题行
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 5, horizontal: 10),
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: ListItemFactory.headerTitle(name),
|
||||
),
|
||||
if (FormUtils.hasValue(pd, nameKey))
|
||||
Text(
|
||||
pd[nameKey]?.toString() ?? '',
|
||||
style: const TextStyle(fontSize: 16),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
|
||||
if (FormUtils.hasValue(signs, signKey))
|
||||
...((signs[signKey] as List<dynamic>)
|
||||
.cast<Map<String, dynamic>>()
|
||||
.map((item) {
|
||||
// 解析 SIGN_PATH
|
||||
List<String> signPaths = [];
|
||||
final rawSP = FormUtils.hasValue(item, 'SIGN_PATH') ? item['SIGN_PATH'] : null;
|
||||
if (rawSP is String && rawSP.isNotEmpty) {
|
||||
signPaths = rawSP.split(',').map((s) => s.trim()).toList();
|
||||
} else if (rawSP is List) {
|
||||
signPaths = rawSP.cast<String>();
|
||||
}
|
||||
|
||||
// 解析 SIGN_TIME 保留空格
|
||||
List<String> signTimes = [];
|
||||
final rawST = FormUtils.hasValue(item, 'SIGN_TIME') ? item['SIGN_TIME'] : null;
|
||||
if (rawST is String && rawST.isNotEmpty) {
|
||||
signTimes = rawST.split(',');
|
||||
} else if (rawST is List) {
|
||||
signTimes = rawST.cast<String>();
|
||||
}
|
||||
|
||||
final pairCount = math.min(signPaths.length, signTimes.length);
|
||||
|
||||
// 解析 IMG_PATH, 最多 2 张
|
||||
List<String> imgPaths = [];
|
||||
final rawIP = FormUtils.hasValue(item, 'IMG_PATH') ? item['IMG_PATH'] : null;
|
||||
if (rawIP is String && rawIP.isNotEmpty) {
|
||||
imgPaths = rawIP.split(',').map((s) => s.trim()).take(2).toList();
|
||||
} else if (rawIP is List) {
|
||||
imgPaths = rawIP.cast<String>().take(2).toList();
|
||||
}
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 10),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
if (imgPaths.isNotEmpty) ...[
|
||||
Row(
|
||||
children: imgPaths.map((p) {
|
||||
final fullUrl = '$baseImgPath$p';
|
||||
return GestureDetector(
|
||||
onTap: () => SingleImageViewer(imageUrl: fullUrl),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(right: 8.0),
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(2),
|
||||
child: Image.network(
|
||||
fullUrl,
|
||||
width: 50,
|
||||
height: 50,
|
||||
fit: BoxFit.fill,
|
||||
errorBuilder: (_, __, ___) => const Icon(
|
||||
Icons.broken_image,
|
||||
size: 40,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
],
|
||||
|
||||
// 签名及时间
|
||||
...List.generate(pairCount, (index) {
|
||||
final imgPath = signPaths[index];
|
||||
final timeLabel = signTimes[index];
|
||||
final fullUrl = '$baseImgPath$imgPath';
|
||||
const imageWidth = 200.0;
|
||||
const imageHeight = 100.0;
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 8.0),
|
||||
child: Column(
|
||||
children: [
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
GestureDetector(
|
||||
onTap: () => presentOpaque(
|
||||
SingleImageViewer(imageUrl: fullUrl),
|
||||
context,
|
||||
),
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
child: Image.network(
|
||||
fullUrl,
|
||||
width: imageWidth,
|
||||
height: imageHeight,
|
||||
fit: BoxFit.fill,
|
||||
errorBuilder: (_, __, ___) =>
|
||||
const Icon(Icons.broken_image, size: 60),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: SizedBox(
|
||||
height: imageHeight,
|
||||
child: Align(
|
||||
alignment: Alignment.bottomRight,
|
||||
child: Text(
|
||||
timeLabel,
|
||||
style: const TextStyle(
|
||||
fontSize: 14,
|
||||
color: Colors.black87,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
if (index < pairCount - 1)
|
||||
const Padding(
|
||||
padding: EdgeInsets.only(top: 8.0),
|
||||
child: Divider(height: 1),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}),
|
||||
],
|
||||
),
|
||||
);
|
||||
}).toList()),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
|
|
@ -230,6 +68,7 @@ class SpecialWorkFormBaseWork extends StatelessWidget {
|
|||
onChooseLevel: onChooseLevel,
|
||||
onChooseSpaceName: onChooseSpaceName,
|
||||
onAnalyzeTap: onAnalyzeTap,
|
||||
signs: signs,
|
||||
),
|
||||
|
||||
// 2. 安全防护措施
|
||||
|
|
@ -263,138 +102,67 @@ class SpecialWorkFormBaseWork extends StatelessWidget {
|
|||
],
|
||||
),
|
||||
),
|
||||
|
||||
// 4. 各环节签字及意见
|
||||
if (FormUtils.hasValue(signs, 'GUARDIAN'))
|
||||
signItemWidget('GUARDIAN', 'GUARDIAN_USER_NAME', '监护人', context),
|
||||
|
||||
ConfirmWithSignWidget(
|
||||
signs: signs,
|
||||
pd: pd,
|
||||
baseImgPath: baseImgPath,
|
||||
sectionKey: 'GUARDIAN',
|
||||
nameKey: 'GUARDIAN_USER_NAME',
|
||||
headerTitle: '监护人签字',
|
||||
roleTitle: '监护人',
|
||||
),
|
||||
if (FormUtils.hasValue(signs, 'CONFESS'))
|
||||
signItemWidget('CONFESS', 'CONFESS_USER_NAME', '安全交底人', context),
|
||||
|
||||
ConfirmWithSignWidget(
|
||||
signs: signs,
|
||||
pd: pd,
|
||||
baseImgPath: baseImgPath,
|
||||
sectionKey: 'CONFESS',
|
||||
nameKey: 'CONFESS_USER_NAME',
|
||||
headerTitle: '安全交底人',
|
||||
roleTitle: '安全交底人',
|
||||
),
|
||||
if (FormUtils.hasValue(signs, 'ACCEPT_CONFESS'))
|
||||
signItemWidget('ACCEPT_CONFESS', 'ACCEPT_CONFESS_USER_NAME', '接受交底人', context),
|
||||
ConfirmWithSignWidget(
|
||||
signs: signs,
|
||||
pd: pd,
|
||||
baseImgPath: baseImgPath,
|
||||
sectionKey: 'ACCEPT_CONFESS',
|
||||
nameKey: 'ACCEPT_CONFESS_USER_NAME',
|
||||
headerTitle: '接受交底人',
|
||||
roleTitle: '',
|
||||
),
|
||||
if (FormUtils.hasValue(signs, 'CONFIRM'))
|
||||
ConfirmWithSignWidget(
|
||||
signs: signs,
|
||||
pd: pd,
|
||||
baseImgPath: baseImgPath,
|
||||
sectionKey: 'CONFIRM',
|
||||
nameKey: 'CONFIRM_USER_NAME',
|
||||
headerTitle: '作业负责人意见',
|
||||
roleTitle: '作业负责人',
|
||||
),
|
||||
if (FormUtils.hasValue(signs, 'LEADER'))
|
||||
ConfirmWithSignWidget(
|
||||
signs: signs,
|
||||
pd: pd,
|
||||
baseImgPath: baseImgPath,
|
||||
sectionKey: 'LEADER',
|
||||
nameKey: 'LEADER_USER_NAME',
|
||||
headerTitle: '所在单位负责人意见',
|
||||
roleTitle: '所在单位负责人',
|
||||
),
|
||||
|
||||
// 作业负责人意见
|
||||
if (FormUtils.hasValue(signs, 'CONFIRM')) ...[
|
||||
Column(
|
||||
children: [
|
||||
_itemContainer(
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Padding(padding: EdgeInsets.symmetric(horizontal: 8), child: ListItemFactory.headerTitle('作业负责人意见'),),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Text(signs['CONFIRM'][0]['DESCR'] ?? ''),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Divider(height: 1,),
|
||||
signItemWidget('CONFIRM', 'CONFIRM_USER_NAME', '作业负责人', context),
|
||||
],
|
||||
)
|
||||
|
||||
],
|
||||
|
||||
// 所在单位负责人意见
|
||||
if (FormUtils.hasValue(signs, 'LEADER')) ...[
|
||||
Column(
|
||||
children: [
|
||||
_itemContainer(
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Padding(padding: EdgeInsets.symmetric(horizontal: 8), child: ListItemFactory.headerTitle('所在单位意见'),),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Text(signs['LEADER'][0]['DESCR'] ?? ''),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Divider(height: 1,),
|
||||
signItemWidget('LEADER', 'LEADER_USER_NAME', '所在单位负责人', context),
|
||||
],
|
||||
)
|
||||
],
|
||||
|
||||
// 安全管理部门负责人意见
|
||||
if (FormUtils.hasValue(signs, 'AUDIT')) ...[
|
||||
Column(
|
||||
children: [
|
||||
_itemContainer(
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Padding(padding: EdgeInsets.symmetric(horizontal: 8), child: ListItemFactory.headerTitle('安全管理部门意见'),),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Text(signs['AUDIT'][0]['DESCR'] ?? ''),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Divider(height: 1,),
|
||||
signItemWidget('AUDIT', 'AUDIT_USER_NAME', '安全管理部门负责人', context),
|
||||
],
|
||||
)
|
||||
],
|
||||
|
||||
// 动火审批人意见
|
||||
if (FormUtils.hasValue(signs, 'APPROVE')) ...[
|
||||
Column(
|
||||
children: [
|
||||
_itemContainer(
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Padding(padding: EdgeInsets.symmetric(horizontal: 8), child: ListItemFactory.headerTitle('动火审批人意见'),),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Text(signs['APPROVE'][0]['DESCR'] ?? ''),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Divider(height: 1,),
|
||||
signItemWidget('APPROVE', 'APPROVE_USER_NAME', '动火审批人', context),
|
||||
],
|
||||
)
|
||||
],
|
||||
|
||||
if (FormUtils.hasValue(signs, 'MONITOR'))
|
||||
signItemWidget('MONITOR', 'MONITOR_USER_NAME', '动火前在岗班长', context),
|
||||
|
||||
// 作业开始负责人签字
|
||||
// if (FormUtils.hasValue(signs, 'WORK_START'))
|
||||
// signItemWidget('WORK_START', 'WORK_START_USER_NAME', '作业开始负责人', context),
|
||||
//
|
||||
// // 作业结束负责人签字
|
||||
// if (FormUtils.hasValue(signs, 'WORK_END'))
|
||||
// signItemWidget('WORK_END', 'WORK_END_USER_NAME', '作业结束负责人', context),
|
||||
|
||||
// 完工验收意见和签字
|
||||
if (FormUtils.hasValue(signs, 'ACCEPT')) ...[
|
||||
Column(
|
||||
children: [
|
||||
_itemContainer(
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Padding(padding: EdgeInsets.symmetric(horizontal: 8), child: ListItemFactory.headerTitle('完工验收意见'),),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Text(signs['ACCEPT'][0]['DESCR'] ?? ''),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Divider(height: 1,),
|
||||
signItemWidget('ACCEPT', 'ACCEPT_USER_NAME', '验收部门负责人', context),
|
||||
],
|
||||
)
|
||||
],
|
||||
if (FormUtils.hasValue(signs, 'ACCEPT'))
|
||||
ConfirmWithSignWidget(
|
||||
signs: signs,
|
||||
pd: pd,
|
||||
baseImgPath: baseImgPath,
|
||||
sectionKey: 'ACCEPT',
|
||||
nameKey: 'ACCEPT_USER_NAME',
|
||||
headerTitle: '验收部门负责人意见',
|
||||
roleTitle: '验收部门负责人',
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -451,6 +451,7 @@ class _SpaceworkSafeFuncSureState extends State<SpaceworkSafeFuncSure> {
|
|||
context,
|
||||
);
|
||||
},
|
||||
signs: {},
|
||||
),
|
||||
SizedBox(height: 20),
|
||||
_setSafeDetailWidget(),
|
||||
|
|
|
|||
|
|
@ -338,6 +338,7 @@ class _SpaceworkJhrDetailState extends State<SpaceworkJhrDetail> {
|
|||
context,
|
||||
);
|
||||
},
|
||||
signs: signs,
|
||||
),
|
||||
SizedBox(height: 20),
|
||||
_setSafeDetailWidget(),
|
||||
|
|
|
|||
|
|
@ -206,6 +206,7 @@ class _SpaceworkJszyDetailState extends State<SpaceworkJszyDetail> {
|
|||
child: SingleChildScrollView(
|
||||
padding: EdgeInsets.all(12),
|
||||
child: Column(
|
||||
spacing: 12,
|
||||
children: [
|
||||
// _setSafeDetailWidget(),
|
||||
SpecialWorkFormBaseWork(
|
||||
|
|
@ -254,7 +255,6 @@ class _SpaceworkJszyDetailState extends State<SpaceworkJszyDetail> {
|
|||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 12,),
|
||||
_bottomButtons(),
|
||||
],
|
||||
),
|
||||
|
|
|
|||
|
|
@ -201,6 +201,7 @@ class _SpaceworkKszyDetailState extends State<SpaceworkKszyDetail> {
|
|||
child: SingleChildScrollView(
|
||||
padding: EdgeInsets.all(12),
|
||||
child: Column(
|
||||
spacing: 12,
|
||||
children: [
|
||||
// _setSafeDetailWidget(),
|
||||
SpecialWorkFormBaseWork(
|
||||
|
|
@ -249,7 +250,6 @@ class _SpaceworkKszyDetailState extends State<SpaceworkKszyDetail> {
|
|||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 12,),
|
||||
_bottomButtons(),
|
||||
],
|
||||
),
|
||||
|
|
|
|||
|
|
@ -217,9 +217,11 @@ class _SpaceworkApplyDetailState extends State<SpaceworkApplyDetail> {
|
|||
builder:
|
||||
(_) => WorkAreaPicker(
|
||||
onSelected: (String id, String POSITIONS, String name) {
|
||||
pd['ELECTRONIC_FENCE_AREA_ID'] = id;
|
||||
pd['POSITIONS'] = POSITIONS;
|
||||
pd['PLS_NAME'] = name;
|
||||
setState(() {
|
||||
pd['ELECTRONIC_FENCE_AREA_ID'] = id;
|
||||
pd['POSITIONS'] = POSITIONS;
|
||||
pd['PLS_NAME'] = name;
|
||||
});
|
||||
},
|
||||
),
|
||||
).then((_) {
|
||||
|
|
@ -638,6 +640,7 @@ class _SpaceworkApplyDetailState extends State<SpaceworkApplyDetail> {
|
|||
onContractorHandle: _chooseUnitManager,
|
||||
onWorkAreaHandle: _getWorkArea,
|
||||
onWorkAreaLocationHandle: _showLocationHandle,
|
||||
signs: {},
|
||||
),
|
||||
),
|
||||
if (isEditable)
|
||||
|
|
|
|||
|
|
@ -59,7 +59,6 @@ class _SpaceworkListPageState extends State<SpaceworkListPage> {
|
|||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_fetchSteps();
|
||||
_fetchData();
|
||||
_scrollController.addListener(_onScroll);
|
||||
}
|
||||
|
|
@ -140,9 +139,11 @@ class _SpaceworkListPageState extends State<SpaceworkListPage> {
|
|||
}
|
||||
|
||||
/// 申请
|
||||
void _handleApply() {
|
||||
void _handleApply() async{
|
||||
// 处理申请按钮点击逻辑
|
||||
pushPage(SpaceworkApplyDetail(WORK_ID: '', flow: widget.flow), context);
|
||||
await pushPage(SpaceworkApplyDetail(WORK_ID: '', flow: widget.flow), context);
|
||||
_fetchData();
|
||||
LoadingDialogHelper.hide();
|
||||
}
|
||||
|
||||
/// 打开流程图
|
||||
|
|
@ -339,9 +340,10 @@ class _SpaceworkListPageState extends State<SpaceworkListPage> {
|
|||
default:
|
||||
break;
|
||||
}
|
||||
LoadingDialogHelper.show();
|
||||
_fetchSteps();
|
||||
_fetchData();
|
||||
|
||||
|
||||
await _fetchData();
|
||||
LoadingDialogHelper.hide();
|
||||
}
|
||||
|
||||
Widget _buildFlowStepItem({
|
||||
|
|
|
|||
|
|
@ -347,7 +347,7 @@ class _SpaceworkSetSafeDetailState extends State<SpaceworkSetSafeDetail> {
|
|||
}
|
||||
|
||||
Future<void> _getMeasures() async {
|
||||
final data = await ApiService.listSignFinishAllMeasures('confinedspace');
|
||||
final data = await ApiService.listSignFinishAllMeasures('confinedspace', widget.CONFINEDSPACE_ID);
|
||||
setState(() {
|
||||
measuresList = List<Map<String, dynamic>>.from(
|
||||
data['measuresList'] ?? <Map<String, dynamic>>[],
|
||||
|
|
@ -570,6 +570,7 @@ class _SpaceworkSetSafeDetailState extends State<SpaceworkSetSafeDetail> {
|
|||
context,
|
||||
);
|
||||
},
|
||||
signs: {},
|
||||
),
|
||||
SizedBox(height: 20),
|
||||
_setSafeDetailWidget(),
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ class _WorkTabDzListState extends State<WorkTabDzList> {
|
|||
},
|
||||
{
|
||||
"icon": "assets/icon-apps/icon-yh-1.png",
|
||||
"title": "设置安全",
|
||||
"title": "设置安全\n措施确认人",
|
||||
"unreadCount": eight_work_count['MEASURES_SET'] ?? '0',
|
||||
},
|
||||
{
|
||||
|
|
@ -70,11 +70,6 @@ class _WorkTabDzListState extends State<WorkTabDzList> {
|
|||
"title": "作业人\n意见",
|
||||
"unreadCount": eight_work_count['WORK_USER'] ?? '0',
|
||||
},
|
||||
{
|
||||
"icon": "assets/icon-apps/icon-yxkj-2.png",
|
||||
"title": "作业负责人\n意见",
|
||||
"unreadCount": eight_work_count['CONFIRM'] ?? '0',
|
||||
},
|
||||
{
|
||||
"icon": "assets/icon-apps/icon-yxkj-2.png",
|
||||
"title": "吊装指挥人\n意见",
|
||||
|
|
@ -127,14 +122,13 @@ class _WorkTabDzListState extends State<WorkTabDzList> {
|
|||
case 5: title = '安全交底人签字'; break;
|
||||
case 6: title = '接受交底人签字'; break;
|
||||
case 7: title = '作业人签字'; break;
|
||||
case 8: title = '作业负责人签字'; break;
|
||||
case 9: title = '吊装指挥人签字'; break;
|
||||
case 10: title = '所在单位签字'; break;
|
||||
case 11: title = '审核人签字'; break;
|
||||
case 12: title = '审批人签字'; break;
|
||||
case 13: title = '开始作业'; break;
|
||||
case 14: title = '结束作业'; break;
|
||||
case 15: title = '验收签字'; break;
|
||||
case 8: title = '吊装指挥人签字'; break;
|
||||
case 9: title = '所在单位签字'; break;
|
||||
case 10: title = '审核人签字'; break;
|
||||
case 11: title = '审批人签字'; break;
|
||||
case 12: title = '开始作业'; break;
|
||||
case 13: title = '结束作业'; break;
|
||||
case 14: title = '验收签字'; break;
|
||||
|
||||
default:
|
||||
print("按钮 $index 被点击");
|
||||
|
|
|
|||
Loading…
Reference in New Issue