。。。。

main
hs 2025-09-17 10:58:46 +08:00
parent 0923f27daa
commit 2bb1fae09b
51 changed files with 1709 additions and 1919 deletions

View File

@ -25,9 +25,9 @@ class ApiService {
/// ///
// static const String basePath = "https://qaaqwh.qhdsafety.com/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.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"; static const String baseImgPath = "https://file.zcloudchina.com/YTHFile";

View File

@ -280,10 +280,7 @@ class _SafecheckAssignmentDetailPageState
isEditable: _isEdit, isEditable: _isEdit,
isRequired: false, isRequired: false,
isClean: false, isClean: false,
onTapClean: () { onTapClean: () {},
ToastUtil.showNormal(context, '已清除');
setState(() {});
},
text: form['RECTIFICATIONDEPTNAME'] ?? '请选择', text: form['RECTIFICATIONDEPTNAME'] ?? '请选择',
onTap: () => chooseUnitHandle('key'), onTap: () => chooseUnitHandle('key'),
), ),

View File

@ -202,7 +202,7 @@ class _StrengthenStudyPageState extends State<StrengthenStudyPage> {
'STUDENT_ID': widget.studentId, 'STUDENT_ID': widget.studentId,
'STRENGTHEN_PAPER_QUESTION_ID': _info['STRENGTHEN_STAGEEXAMPAPER_INPUT_ID'], 'STRENGTHEN_PAPER_QUESTION_ID': _info['STRENGTHEN_STAGEEXAMPAPER_INPUT_ID'],
...data ...data
}, examType: type), context); }, examType: type, jumpType: 2,), context);
} else { } else {
ToastUtil.showError(context, '请求错误'); ToastUtil.showError(context, '请求错误');
} }

View File

@ -212,12 +212,7 @@ class _StudyDetailPageState extends State<StudyDetailPage>
seconds: _lastReported.inSeconds, seconds: _lastReported.inSeconds,
); );
} }
_lastReported = Duration.zero;
_currentVideoData = data;
_hasNodes = hasNodes;
_currentFirstIndex = fi;
_currentNodeIndex = ni;
// //
try { try {
@ -250,6 +245,7 @@ class _StudyDetailPageState extends State<StudyDetailPage>
'IS_NODE': hasNodes, 'IS_NODE': hasNodes,
'FIRST_INDEX': fi, 'FIRST_INDEX': fi,
'NODE_INDEX': ni, 'NODE_INDEX': ni,
'IS_VIDEO': 1,
}; };
await _submitPlayTime( await _submitPlayTime(
snapshot: docSnapshot, snapshot: docSnapshot,
@ -262,6 +258,12 @@ class _StudyDetailPageState extends State<StudyDetailPage>
ToastUtil.showNormal(context, '课件文件资源已失效,请联系管理员'); ToastUtil.showNormal(context, '课件文件资源已失效,请联系管理员');
} }
} else { } else {
_currentVideoData = data;
_lastReported = Duration.zero;
_hasNodes = hasNodes;
_currentFirstIndex = fi;
_currentNodeIndex = ni;
LoadingDialogHelper.show(); LoadingDialogHelper.show();
// //
await _getVideoPlayInfo(data['VIDEOCOURSEWARE_ID']); await _getVideoPlayInfo(data['VIDEOCOURSEWARE_ID']);
@ -475,14 +477,14 @@ class _StudyDetailPageState extends State<StudyDetailPage>
required bool end, required bool end,
required int seconds, required int seconds,
}) async { }) async {
// snapshot VIDEOCOURSEWARE_ID, CURRICULUM_ID, CHAPTER_ID, VIDEOTIME, ... // snapshot VIDEOCOURSEWARE_ID
if (snapshot['VIDEOCOURSEWARE_ID'] == null || if (snapshot['VIDEOCOURSEWARE_ID'] == null ||
snapshot['VIDEOCOURSEWARE_ID'] == '') snapshot['VIDEOCOURSEWARE_ID'] == '') return;
return;
// //
if (_endReported && !end) return; if (_endReported && !end) return;
//
Map data = { Map data = {
'VIDEOCOURSEWARE_ID': snapshot['VIDEOCOURSEWARE_ID'] ?? '', 'VIDEOCOURSEWARE_ID': snapshot['VIDEOCOURSEWARE_ID'] ?? '',
'CURRICULUM_ID': snapshot['CURRICULUM_ID'] ?? '', 'CURRICULUM_ID': snapshot['CURRICULUM_ID'] ?? '',
@ -495,6 +497,10 @@ class _StudyDetailPageState extends State<StudyDetailPage>
'loading': false, 'loading': false,
}; };
// snapshot['IS_VIDEO']==1
// 100% UI 100%
final isNonVideo = (snapshot['IS_VIDEO'] != null && snapshot['IS_VIDEO'].toString() == '1');
const int maxRetries = 2; const int maxRetries = 2;
int attempt = 0; int attempt = 0;
while (true) { while (true) {
@ -503,32 +509,14 @@ class _StudyDetailPageState extends State<StudyDetailPage>
final resData = await ApiService.fnSubmitPlayTime(data); final resData = await ApiService.fnSubmitPlayTime(data);
final pd = resData['pd'] ?? {}; final pd = resData['pd'] ?? {};
// RESOURCETIME if (isNonVideo) {
final resTraw = pd['RESOURCETIME']; // 100% RESOURCETIME
final resT = final str = '100%';
(resTraw is num)
? resTraw.toDouble()
: double.tryParse('$resTraw') ?? seconds.toDouble();
final videoTimeRaw = snapshot['VIDEOTIME'];
final videoTime =
(videoTimeRaw is String)
? double.tryParse(videoTimeRaw) ?? 1.0
: (videoTimeRaw is num ? videoTimeRaw.toDouble() : 1.0);
final comp = pd['PLAYCOUNT'] != null && pd['PLAYCOUNT'] > 0;
final pctDouble =
comp ? 100.0 : ((resT / (videoTime > 0 ? videoTime : 1.0)) * 100.0);
final pct = (pctDouble.clamp(0.00, 100.00) * 100).round() / 100;
final str = '${pct}%';
if (mounted) { if (mounted) {
setState(() { setState(() {
if (snapshot['IS_NODE'] == true) { if (snapshot['IS_NODE'] == true) {
final fi = snapshot['FIRST_INDEX'] as int? ?? _currentFirstIndex; final fi = snapshot['FIRST_INDEX'] as int? ?? _currentFirstIndex;
final ni = snapshot['NODE_INDEX'] as int? ?? _currentNodeIndex; final ni = snapshot['NODE_INDEX'] as int? ?? _currentNodeIndex;
//
if (fi >= 0 && fi < _videoList.length) { if (fi >= 0 && fi < _videoList.length) {
final nodes = _videoList[fi]['nodes'] as List<dynamic>?; final nodes = _videoList[fi]['nodes'] as List<dynamic>?;
if (nodes != null && ni >= 0 && ni < nodes.length) { if (nodes != null && ni >= 0 && ni < nodes.length) {
@ -544,7 +532,63 @@ class _StudyDetailPageState extends State<StudyDetailPage>
}); });
} }
// // pd
if (end && pd['CANEXAM'] == '1') {
_videoController?.pause();
final ok = await CustomAlertDialog.showConfirm(
context,
title: '温馨提示',
content: '当前任务内所有课程均已学完,是否直接参加考试?',
cancelText: '',
confirmText: '',
);
if (ok) {
_startExam(resData);
}
}
break; // -> 退
}
//
final resTraw = pd['RESOURCETIME'];
final resT = (resTraw is num) ? resTraw.toDouble() : double.tryParse('$resTraw') ?? seconds.toDouble();
final videoTimeRaw = snapshot['VIDEOTIME'];
final videoTime = (videoTimeRaw is String)
? double.tryParse(videoTimeRaw) ?? 1.0
: (videoTimeRaw is num ? videoTimeRaw.toDouble() : 1.0);
final comp = pd['PLAYCOUNT'] != null && pd['PLAYCOUNT'] > 0;
final pctDouble = comp ? 100.0 : ((resT / (videoTime > 0 ? videoTime : 1.0)) * 100.0);
//
double pctClamped = pctDouble.clamp(0.00, 100.00);
// 2
final pctRounded = (pctClamped * 100).round() / 100;
final str = '${pctRounded}%';
if (mounted) {
setState(() {
if (snapshot['IS_NODE'] == true) {
final fi = snapshot['FIRST_INDEX'] as int? ?? _currentFirstIndex;
final ni = snapshot['NODE_INDEX'] as int? ?? _currentNodeIndex;
if (fi >= 0 && fi < _videoList.length) {
final nodes = _videoList[fi]['nodes'] as List<dynamic>?;
if (nodes != null && ni >= 0 && ni < nodes.length) {
_videoList[fi]['nodes'][ni]['percent'] = str;
}
}
} else {
final fi = snapshot['FIRST_INDEX'] as int? ?? _currentFirstIndex;
if (fi >= 0 && fi < _videoList.length) {
_videoList[fi]['percent'] = str;
}
}
});
}
//
if (end && pd['CANEXAM'] == '1') { if (end && pd['CANEXAM'] == '1') {
_videoController?.pause(); _videoController?.pause();
@ -572,6 +616,7 @@ class _StudyDetailPageState extends State<StudyDetailPage>
} }
} }
/// ///
Future<void> _startExam(Map resData) async { Future<void> _startExam(Map resData) async {
Map pd = resData['pd'] ?? {}; Map pd = resData['pd'] ?? {};
@ -604,7 +649,7 @@ class _StudyDetailPageState extends State<StudyDetailPage>
paper['STAGEEXAMPAPERINPUT_ID'] ?? '', paper['STAGEEXAMPAPERINPUT_ID'] ?? '',
...data, ...data,
}, },
examType: TakeExamType.video_study, examType: TakeExamType.video_study, jumpType: 2,
), ),
context, context,
); );

View File

@ -212,7 +212,7 @@ class _StudyMyTaskPageState extends State<StudyMyTaskPage>
resData['STAGEEXAMPAPERINPUT_ID'] ?? '', resData['STAGEEXAMPAPERINPUT_ID'] ?? '',
...data ...data
}, },
examType: TakeExamType.video_study), examType: TakeExamType.video_study, jumpType: 1,),
context); context);
} else { } else {
ToastUtil.showError(context, '请求错误'); ToastUtil.showError(context, '请求错误');

View File

@ -50,11 +50,14 @@ class TakeExamPage extends StatefulWidget {
const TakeExamPage({ const TakeExamPage({
required this.examInfo, required this.examInfo,
required this.examType, required this.examType,
required this.jumpType,
super.key, super.key,
}); });
final Map<String, dynamic> examInfo; final Map<String, dynamic> examInfo;
final TakeExamType examType; final TakeExamType examType;
final int jumpType;
@override @override
State<TakeExamPage> createState() => _TakeExamPageState(); State<TakeExamPage> createState() => _TakeExamPageState();
@ -113,6 +116,9 @@ class _TakeExamPageState extends State<TakeExamPage> {
content: '您无考试次数!', content: '您无考试次数!',
); );
if (ok) { if (ok) {
if (widget.jumpType == 2) {
Navigator.pop(context);
}
Navigator.pop(context); Navigator.pop(context);
}; };
} }

View File

@ -37,14 +37,19 @@ class ItemListWidget {
/// ///
}) { }) {
// 使 // 使
final actualKeyboardType = isNumericInput final actualKeyboardType =
isNumericInput
? const TextInputType.numberWithOptions(decimal: true) ? const TextInputType.numberWithOptions(decimal: true)
: keyboardType; : keyboardType;
return Container( return Container(
padding: const EdgeInsets.symmetric(vertical: vertical_inset, horizontal: horizontal_inset), padding: const EdgeInsets.symmetric(
vertical: vertical_inset,
horizontal: horizontal_inset,
),
child: Row( child: Row(
mainAxisAlignment: isEditable mainAxisAlignment:
isEditable
? MainAxisAlignment.start ? MainAxisAlignment.start
: MainAxisAlignment.spaceBetween, : MainAxisAlignment.spaceBetween,
children: [ children: [
@ -73,12 +78,18 @@ class ItemListWidget {
style: TextStyle(fontSize: fontSize), style: TextStyle(fontSize: fontSize),
maxLines: 1, maxLines: 1,
// //
inputFormatters: isNumericInput inputFormatters:
isNumericInput
? [ ? [
// //
FilteringTextInputFormatter.allow(RegExp(r'[\d\.]')), FilteringTextInputFormatter.allow(
RegExp(r'[\d\.]'),
),
// //
TextInputFormatter.withFunction((oldValue, newValue) { TextInputFormatter.withFunction((
oldValue,
newValue,
) {
if (newValue.text.isEmpty) return newValue; if (newValue.text.isEmpty) return newValue;
// //
@ -87,8 +98,11 @@ class ItemListWidget {
} }
// 使 // 使
if (RegExp(r'^\d*\.?\d{0,' + maxDecimalPlaces.toString() + r'}$') if (RegExp(
.hasMatch(newValue.text)) { r'^\d*\.?\d{0,' +
maxDecimalPlaces.toString() +
r'}$',
).hasMatch(newValue.text)) {
return newValue; return newValue;
} }
@ -130,7 +144,6 @@ class ItemListWidget {
bool isRequired = true, bool isRequired = true,
String hintText = '请输入', String hintText = '请输入',
ValueChanged<String>? onChanged, ValueChanged<String>? onChanged,
}) { }) {
return Container( return Container(
// padding线 // padding线
@ -211,7 +224,10 @@ class ItemListWidget {
return InkWell( return InkWell(
onTap: isEditable ? onTap : null, onTap: isEditable ? onTap : null,
child: Container( child: Container(
padding: EdgeInsets.symmetric(vertical: vertical_inset, horizontal: horizontalnum), padding: EdgeInsets.symmetric(
vertical: vertical_inset,
horizontal: horizontalnum,
),
child: Row( child: Row(
children: [ children: [
// 1. // 1.
@ -232,13 +248,19 @@ class ItemListWidget {
if (isTip) if (isTip)
Column( Column(
children: [ children: [
IconButton(onPressed: onTapTip, icon: Icon(Icons.error_outline,color: Colors.blue,size: 20,)), IconButton(
const SizedBox() onPressed: onTapTip,
icon: Icon(
Icons.error_outline,
color: Colors.blue,
size: 20,
),
),
const SizedBox(),
], ],
) ),
], ],
) ),
], ],
), ),
if (isClean) if (isClean)
@ -270,7 +292,12 @@ class ItemListWidget {
textAlign: TextAlign.right, textAlign: TextAlign.right,
style: TextStyle( style: TextStyle(
fontSize: fontSize, fontSize: fontSize,
color: isEditable ? (text == '请选择' ? Colors.black87 :Colors.black) : detailtextColor, color:
isEditable
? (text == '请选择'
? Colors.black87
: Colors.black)
: detailtextColor,
), ),
), ),
), ),
@ -306,7 +333,10 @@ class ItemListWidget {
return InkWell( return InkWell(
onTap: isEditable ? onTap : null, onTap: isEditable ? onTap : null,
child: Container( child: Container(
padding: const EdgeInsets.symmetric(vertical: vertical_inset, horizontal: horizontal_inset), padding: const EdgeInsets.symmetric(
vertical: vertical_inset,
horizontal: horizontal_inset,
),
child: Row( child: Row(
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: [ children: [
@ -390,7 +420,10 @@ class ItemListWidget {
bool isRequired = true, bool isRequired = true,
}) { }) {
return Container( return Container(
padding: EdgeInsets.symmetric(vertical: vertical_inset, horizontal: horizontal_inset), padding: EdgeInsets.symmetric(
vertical: vertical_inset,
horizontal: horizontal_inset,
),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
@ -482,7 +515,10 @@ class ItemListWidget {
bool isRequired = true, bool isRequired = true,
}) { }) {
return Container( return Container(
padding: const EdgeInsets.symmetric(vertical: vertical_inset, horizontal: horizontal_inset), padding: const EdgeInsets.symmetric(
vertical: vertical_inset,
horizontal: horizontal_inset,
),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
@ -519,7 +555,11 @@ class ItemListWidget {
vertical: 2, vertical: 2,
horizontal: 10, horizontal: 10,
), ),
textStyle: TextStyle(color: Colors.white, fontSize: 11, fontWeight: FontWeight.bold), textStyle: TextStyle(
color: Colors.white,
fontSize: 11,
fontWeight: FontWeight.bold,
),
backgroundColor: Colors.green, backgroundColor: Colors.green,
onPressed: onTap, onPressed: onTap,
), ),
@ -569,10 +609,13 @@ class ItemListWidget {
required String text, // required String text, //
required VoidCallback? onTap, // required VoidCallback? onTap, //
double fontSize = 14, // double fontSize = 14, //
String buttonText = '分析详情' String buttonText = '气体分析详情',
}) { }) {
return Container( return Container(
padding: const EdgeInsets.symmetric(vertical: vertical_inset, horizontal: horizontal_inset), padding: const EdgeInsets.symmetric(
vertical: vertical_inset,
horizontal: horizontal_inset,
),
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
@ -604,11 +647,12 @@ class ItemListWidget {
CustomButton( CustomButton(
text: buttonText, text: buttonText,
height: 30, height: 30,
padding: const EdgeInsets.symmetric( padding: const EdgeInsets.symmetric(vertical: 2, horizontal: 10),
vertical: 2, textStyle: TextStyle(
horizontal: 10, color: Colors.white,
fontSize: 11,
fontWeight: FontWeight.bold,
), ),
textStyle: TextStyle(color: Colors.white, fontSize: 11, fontWeight: FontWeight.bold),
backgroundColor: Colors.green, backgroundColor: Colors.green,
onPressed: onTap, onPressed: onTap,
), ),
@ -628,7 +672,10 @@ class ItemListWidget {
bool isRequired = false, bool isRequired = false,
}) { }) {
return Container( return Container(
padding: const EdgeInsets.symmetric(vertical: vertical_inset, horizontal: horizontal_inset), padding: const EdgeInsets.symmetric(
vertical: vertical_inset,
horizontal: horizontal_inset,
),
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
@ -655,27 +702,28 @@ class ItemListWidget {
), ),
); );
} }
/// ///
/// + () /// + ()
static Widget OneRowStartButtonTitle({ static Widget OneRowStartButtonTitle({
required String label, // required String label, //
String buttonText = '分析详情', // String buttonText = '气体分析详情', //
String text = '', // String text = '', //
required VoidCallback onTap, // required VoidCallback onTap, //
double fontSize = 14, // double fontSize = 14, //
Color btnColor = Colors.green, Color btnColor = Colors.green,
}) { }) {
return Container( return Container(
padding: const EdgeInsets.symmetric(vertical: vertical_inset, horizontal: horizontal_inset), padding: const EdgeInsets.symmetric(
vertical: vertical_inset,
horizontal: horizontal_inset,
),
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
children: [ children: [
Text( Text(
label, label,
style: TextStyle( style: TextStyle(fontSize: fontSize, fontWeight: FontWeight.bold),
fontSize: fontSize,
fontWeight: FontWeight.bold,
),
), ),
CustomButton( CustomButton(
text: buttonText, text: buttonText,
@ -701,7 +749,10 @@ class ItemListWidget {
void Function(String)? onTapCallBack, void Function(String)? onTapCallBack,
}) { }) {
return Container( return Container(
padding: const EdgeInsets.symmetric(vertical: vertical_inset, horizontal: horizontal_inset), padding: const EdgeInsets.symmetric(
vertical: vertical_inset,
horizontal: horizontal_inset,
),
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
@ -720,7 +771,8 @@ class ItemListWidget {
children: [ children: [
GestureDetector( GestureDetector(
onTap: () { onTap: () {
if (onTapCallBack != null) onTapCallBack('${ApiService.baseImgPath}$imgPath'); if (onTapCallBack != null)
onTapCallBack('${ApiService.baseImgPath}$imgPath');
}, },
child: child:
imgPath.isNotEmpty imgPath.isNotEmpty
@ -731,10 +783,9 @@ class ItemListWidget {
) )
: SizedBox(), : SizedBox(),
), ),
if (text.isNotEmpty) if (text.isNotEmpty) Text(text),
Text(text)
], ],
) ),
], ],
), ),
); );
@ -758,13 +809,13 @@ class ItemListWidget {
// //
if (title.isNotEmpty) if (title.isNotEmpty)
Padding( Padding(
padding: const EdgeInsets.symmetric(vertical: vertical_inset, horizontal: horizontal_inset), padding: const EdgeInsets.symmetric(
vertical: vertical_inset,
horizontal: horizontal_inset,
),
child: Text( child: Text(
title, title,
style: TextStyle( style: TextStyle(fontSize: fontSize, fontWeight: FontWeight.bold),
fontSize: fontSize,
fontWeight: FontWeight.bold,
),
), ),
), ),
@ -779,16 +830,20 @@ class ItemListWidget {
return Container( return Container(
margin: const EdgeInsets.only(right: 8), // margin: const EdgeInsets.only(right: 8), //
child: ClipRRect( child: ClipRRect(
borderRadius: BorderRadius.circular(8), borderRadius: BorderRadius.circular(8),
child: GestureDetector( child: GestureDetector(
onTap: () { onTap: () {
if (onTapCallBack != null) onTapCallBack('${ApiService.baseImgPath}${imageUrls![index] ?? ''}'); if (onTapCallBack != null)
onTapCallBack(
'${ApiService.baseImgPath}${imageUrls![index] ?? ''}',
);
}, },
child: Image.network( child: Image.network(
'${ApiService.baseImgPath}${imageUrls![index] ?? ''}', '${ApiService.baseImgPath}${imageUrls![index] ?? ''}',
width: 80, // width: 80,
height: 80, // //
height: 80,
//
fit: BoxFit.fill, fit: BoxFit.fill,
loadingBuilder: (context, child, loadingProgress) { loadingBuilder: (context, child, loadingProgress) {
if (loadingProgress == null) return child; if (loadingProgress == null) return child;
@ -796,7 +851,9 @@ class ItemListWidget {
width: 80, width: 80,
height: 80, height: 80,
color: Colors.grey[200], color: Colors.grey[200],
child: const Center(child: CircularProgressIndicator()), child: const Center(
child: CircularProgressIndicator(),
),
); );
}, },
errorBuilder: (context, error, stackTrace) { errorBuilder: (context, error, stackTrace) {
@ -808,7 +865,7 @@ class ItemListWidget {
); );
}, },
), ),
) ),
), ),
); );
}, },
@ -817,6 +874,7 @@ class ItemListWidget {
], ],
); );
} }
/// ///
/// + /// +
/// ///
@ -832,7 +890,10 @@ class ItemListWidget {
bool isRequired = true, bool isRequired = true,
}) { }) {
return Container( return Container(
padding: const EdgeInsets.symmetric(vertical: vertical_inset, horizontal: horizontal_inset), padding: const EdgeInsets.symmetric(
vertical: vertical_inset,
horizontal: horizontal_inset,
),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
@ -910,15 +971,19 @@ class ItemListWidget {
), ),
); );
} }
/// ///
/// ///
static Widget mulColumnRowTitleAndImages({ static Widget mulColumnRowTitleAndImages({
required String title, // required String title, //
required List<dynamic>? imageUrls, required List<dynamic>? imageUrls,
required String text, // required String text, //
required List<dynamic>? signUrls, /// required List<dynamic>? signUrls,
required List<dynamic>? signTimes, ///
///
required List<dynamic>? signTimes,
///
double row2Height = 80, // double row2Height = 80, //
double fontSize = 14, // double fontSize = 14, //
void Function(String)? onTapCallBack, void Function(String)? onTapCallBack,
@ -930,13 +995,13 @@ class ItemListWidget {
children: [ children: [
// //
Padding( Padding(
padding: const EdgeInsets.symmetric(vertical: vertical_inset, horizontal: horizontal_inset), padding: const EdgeInsets.symmetric(
vertical: vertical_inset,
horizontal: horizontal_inset,
),
child: Text( child: Text(
title, title,
style: TextStyle( style: TextStyle(fontSize: fontSize, fontWeight: FontWeight.bold),
fontSize: fontSize,
fontWeight: FontWeight.bold,
),
), ),
), ),
@ -954,12 +1019,17 @@ class ItemListWidget {
borderRadius: BorderRadius.circular(8), borderRadius: BorderRadius.circular(8),
child: GestureDetector( child: GestureDetector(
onTap: () { onTap: () {
if (onTapCallBack != null) onTapCallBack('${ApiService.baseImgPath}${imageUrls![index] ?? ''}'); if (onTapCallBack != null)
onTapCallBack(
'${ApiService.baseImgPath}${imageUrls![index] ?? ''}',
);
}, },
child: Image.network( child: Image.network(
'${ApiService.baseImgPath}${imageUrls![index] ?? ''}', '${ApiService.baseImgPath}${imageUrls![index] ?? ''}',
width: 80, // width: 80,
height: 80, // //
height: 80,
//
fit: BoxFit.fill, fit: BoxFit.fill,
loadingBuilder: (context, child, loadingProgress) { loadingBuilder: (context, child, loadingProgress) {
if (loadingProgress == null) return child; if (loadingProgress == null) return child;
@ -967,7 +1037,9 @@ class ItemListWidget {
width: 80, width: 80,
height: 80, height: 80,
color: Colors.grey[200], color: Colors.grey[200],
child: const Center(child: CircularProgressIndicator()), child: const Center(
child: CircularProgressIndicator(),
),
); );
}, },
errorBuilder: (context, error, stackTrace) { errorBuilder: (context, error, stackTrace) {
@ -979,13 +1051,13 @@ class ItemListWidget {
); );
}, },
), ),
) ),
), ),
); );
}, },
), ),
), ),
Row() Row(),
], ],
); );
} }
@ -1000,17 +1072,17 @@ class ItemListWidget {
bool isRequired = true, bool isRequired = true,
}) { }) {
return Container( return Container(
padding: const EdgeInsets.symmetric(vertical: vertical_inset, horizontal: horizontal_inset), padding: const EdgeInsets.symmetric(
vertical: vertical_inset,
horizontal: horizontal_inset,
),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
// //
Text( Text(
label, label,
style: TextStyle( style: TextStyle(fontSize: fontSize, fontWeight: FontWeight.bold),
fontSize: fontSize,
fontWeight: FontWeight.bold,
),
maxLines: 1, maxLines: 1,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
), ),
@ -1019,17 +1091,18 @@ class ItemListWidget {
text, text,
maxLines: 5, maxLines: 5,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
style: TextStyle( style: TextStyle(fontSize: fontSize, color: detailtextColor),
fontSize: fontSize,
color: detailtextColor,
),
), ),
], ],
), ),
); );
} }
static Widget itemContainer(Widget child, {double horizontal = horizontal_inset, double vertical = vertical_inset}) {
static Widget itemContainer(
Widget child, {
double horizontal = horizontal_inset,
double vertical = vertical_inset,
}) {
return Container( return Container(
decoration: BoxDecoration( decoration: BoxDecoration(
color: Colors.white, color: Colors.white,
@ -1040,10 +1113,111 @@ class ItemListWidget {
); );
} }
// static Widget aaa({}){
// return
// }
static Widget buildFlowStepItem({
required List<Map<String, dynamic>> flowList,
}) {
final int lastDoneIndex = flowList.lastIndexWhere((e) => e['STATUS'] == 1);
return ListView.builder(
padding: const EdgeInsets.symmetric(vertical: 16),
itemCount: flowList.length + 1, // +1
itemBuilder: (context, i) {
if (i == 0) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
child: Text(
'查看流程图',
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
);
}
final idx = i - 1;
final item = flowList[idx];
final bool isFirst = idx == 0;
final bool isLast = idx == flowList.length - 1;
// lastDoneIndex
final int status;
if (idx <= lastDoneIndex) {
status = 1; //
} else if (idx == lastDoneIndex + 1) {
status = 0; //
} else {
status = -1; //
}
//
final Color dotColor =
status == 1
? Colors.green
: (status == 0 ? Colors.blue : Colors.grey);
final Color textColor =
status == 1
? Colors.green
: (status == 0 ? Colors.blue : Colors.black);
return ListTile(
visualDensity: VisualDensity(vertical: -4),
contentPadding: const EdgeInsets.symmetric(horizontal: 16),
leading: Container(
width: 24,
alignment: Alignment.center,
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
// 线
isFirst
? SizedBox(height: 6 + 5)
: Expanded(
child: Container(width: 1, color: Colors.grey[300]),
),
//
CircleAvatar(radius: 6, backgroundColor: dotColor),
// 线
isLast
? SizedBox(height: 6 + 5)
: Expanded(
child: Container(width: 1, color: Colors.grey[300]),
),
],
),
),
title: Text(
item['STEP_NAME'] ?? '',
style: TextStyle(color: textColor, fontSize: 15),
),
subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (item['SIGN_USER'] != null) ...[
Text(
item['SIGN_USER'],
style: TextStyle(color: textColor, fontSize: 13),
),
] else if (item['FINISHED_SIGN_USER'] != null) ...[
Text(
item['FINISHED_SIGN_USER'],
style: TextStyle(color: textColor, fontSize: 13),
),
] else if (item['ACT_USER_NAME'] != null) ...[
Text(
item['ACT_USER_NAME'],
style: TextStyle(color: textColor, fontSize: 13),
),
],
if (item['ACT_TIME'] != null)
Text(
item['ACT_TIME'],
style: TextStyle(color: textColor, fontSize: 13),
),
],
),
);
},
);
}
} }

View File

@ -61,16 +61,59 @@ class MeasuresListWidget extends StatelessWidget {
border: Border.all(color: Colors.grey.shade300), border: Border.all(color: Colors.grey.shade300),
borderRadius: BorderRadius.circular(4), borderRadius: BorderRadius.circular(4),
), ),
child: Table( child: LayoutBuilder(
defaultVerticalAlignment: TableCellVerticalAlignment.middle, builder: (context, constraints) {
// margin
final containerWidth = constraints.maxWidth;
// .top / .bottom //
columnWidths: { double col0Fixed = 40; //
0: FlexColumnWidth(10), double col2Fixed = 60; //
1: FixedColumnWidth(210), double col3Fixed = 80; //
2: FlexColumnWidth(20),
if (!isAllowEdit) 3: FixedColumnWidth(60), // 4isAllowEdit == true40
}, final showCol3 = !isAllowEdit;
//
double fixedTotal =
col0Fixed + col2Fixed + (showCol3 ? col3Fixed : 0);
// 10% 0
final minFlexPortion = containerWidth * 0.10;
if (fixedTotal + minFlexPortion > containerWidth &&
fixedTotal > 0) {
final availableForFixed = (containerWidth - minFlexPortion)
.clamp(0.0, containerWidth);
final scale = availableForFixed / fixedTotal;
col0Fixed = (col0Fixed * scale).clamp(
28.0,
col0Fixed,
); // 28px
col2Fixed = (col2Fixed * scale).clamp(
60.0,
col2Fixed,
); // 60px
if (showCol3)
col3Fixed = (col3Fixed * scale).clamp(
36.0,
col3Fixed,
); // 36px
fixedTotal =
col0Fixed + col2Fixed + (showCol3 ? col3Fixed : 0);
}
//
final columnWidths = <int, TableColumnWidth>{
0: FixedColumnWidth(col0Fixed),
1: const FlexColumnWidth(1),
2: FixedColumnWidth(col2Fixed),
};
if (showCol3) {
columnWidths[3] = FixedColumnWidth(col3Fixed);
}
return Table(
defaultVerticalAlignment: TableCellVerticalAlignment.middle,
columnWidths: columnWidths,
border: TableBorder( border: TableBorder(
horizontalInside: BorderSide(color: Colors.grey.shade300), horizontalInside: BorderSide(color: Colors.grey.shade300),
verticalInside: BorderSide(color: Colors.grey.shade300), verticalInside: BorderSide(color: Colors.grey.shade300),
@ -103,7 +146,9 @@ class MeasuresListWidget extends StatelessWidget {
child: Center( child: Center(
child: Text( child: Text(
isAllowEdit ? '操作' : '是否\n涉及', isAllowEdit ? '操作' : '是否\n涉及',
style: const TextStyle(fontWeight: FontWeight.bold), style: const TextStyle(
fontWeight: FontWeight.bold,
),
), ),
), ),
), ),
@ -136,19 +181,13 @@ class MeasuresListWidget extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
// //
Text(item['PROTECTIVE_MEASURES'] as String? ?? ''), Text(
// // item['PROTECTIVE_MEASURES'] as String? ?? '',
// if (item.containsKey('SIGN_PATH') && ),
// (item['SIGN_PATH'] as String).isNotEmpty)
// ..._buildImageRows(
// context,
// (item['SIGN_PATH'] as String).split(','),
// item['SIGN_TIME'] as String? ?? '',
// ),
// 14 + // 14 +
for (var i = 1; i <= 4; i++) for (var i = 1; i <= 4; i++)
if ((item['QUESTION$i'] as String?)?.isNotEmpty ?? if ((item['QUESTION$i'] as String?)
?.isNotEmpty ??
false) false)
_buildQnA(item, i), _buildQnA(item, i),
// //
@ -169,7 +208,7 @@ class MeasuresListWidget extends StatelessWidget {
), ),
), ),
// / + // / +
Padding( Padding(
padding: const EdgeInsets.all(8), padding: const EdgeInsets.all(8),
child: Column( child: Column(
@ -210,13 +249,14 @@ class MeasuresListWidget extends StatelessWidget {
], ],
), ),
), ),
//
if (!isAllowEdit) if (!isAllowEdit)
Column( Column(
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: [ children: [
if (item.containsKey('SIGN_PATH') && if (item.containsKey('SIGN_PATH') &&
(item['SIGN_PATH'] as String).isNotEmpty) (item['SIGN_PATH'] as String).isNotEmpty)
// SIGN_PATH path
...((item['SIGN_PATH'] as String) ...((item['SIGN_PATH'] as String)
.split(',') .split(',')
.map((s) => s.trim()) .map((s) => s.trim())
@ -228,7 +268,9 @@ class MeasuresListWidget extends StatelessWidget {
child: GestureDetector( child: GestureDetector(
onTap: () { onTap: () {
presentOpaque( presentOpaque(
SingleImageViewer(imageUrl: imageUrl), SingleImageViewer(
imageUrl: imageUrl,
),
context, context,
); );
}, },
@ -237,7 +279,6 @@ class MeasuresListWidget extends StatelessWidget {
width: 40, width: 40,
height: 40, height: 40,
fit: BoxFit.fill, fit: BoxFit.fill,
//
errorBuilder: errorBuilder:
(_, __, ___) => Container( (_, __, ___) => Container(
width: 40, width: 40,
@ -259,6 +300,8 @@ class MeasuresListWidget extends StatelessWidget {
], ],
), ),
], ],
);
},
), ),
), ),
], ],
@ -1144,12 +1187,17 @@ class _SelectionPopupState extends State<SelectionPopup> {
), ),
// //
Expanded( Expanded(
child: child: ListTileTheme(
ListTileTheme(
dense: true, dense: true,
contentPadding: const EdgeInsets.symmetric(vertical: 0, horizontal: 0), contentPadding: const EdgeInsets.symmetric(
vertical: 0,
horizontal: 0,
),
child: ListView.builder( child: ListView.builder(
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 12), padding: const EdgeInsets.symmetric(
horizontal: 12,
vertical: 12,
),
itemCount: list.length, itemCount: list.length,
itemBuilder: (c, i) { itemBuilder: (c, i) {
final item = list[i]; final item = list[i];
@ -1161,10 +1209,15 @@ class _SelectionPopupState extends State<SelectionPopup> {
final checked = value.contains(key); final checked = value.contains(key);
return CheckboxListTile( return CheckboxListTile(
controlAffinity: ListTileControlAffinity.leading, controlAffinity: ListTileControlAffinity.leading,
contentPadding: const EdgeInsets.symmetric(vertical: 0, horizontal: 0), contentPadding: const EdgeInsets.symmetric(
vertical: 0,
horizontal: 0,
),
activeColor: Colors.blue, activeColor: Colors.blue,
dense: true, // dense: true,
visualDensity: const VisualDensity(vertical: -4), // -1..-4 //
visualDensity: const VisualDensity(vertical: -4),
// -1..-4
title: Column( title: Column(
mainAxisSize: MainAxisSize.min, // Column mainAxisSize: MainAxisSize.min, // Column
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
@ -1199,12 +1252,10 @@ class _SelectionPopupState extends State<SelectionPopup> {
selectValue.remove(key); selectValue.remove(key);
}); });
}, },
) );
;
}, },
), ),
) ),
), ),
// / // /
Padding( Padding(
@ -1317,13 +1368,15 @@ class SignItemWidget extends StatelessWidget {
final rawSP = final rawSP =
FormUtils.hasValue(item, 'SIGN_PATH') ? item['SIGN_PATH'] : null; FormUtils.hasValue(item, 'SIGN_PATH') ? item['SIGN_PATH'] : null;
if (rawSP is String && rawSP.isNotEmpty) { if (rawSP is String && rawSP.isNotEmpty) {
signPaths = rawSP signPaths =
rawSP
.split(',') .split(',')
.map((s) => s.trim()) .map((s) => s.trim())
.where((s) => s.isNotEmpty) .where((s) => s.isNotEmpty)
.toList(); .toList();
} else if (rawSP is List) { } else if (rawSP is List) {
signPaths = rawSP signPaths =
rawSP
.cast<String>() .cast<String>()
.map((s) => s.trim()) .map((s) => s.trim())
.where((s) => s.isNotEmpty) .where((s) => s.isNotEmpty)
@ -1353,13 +1406,12 @@ class SignItemWidget extends StatelessWidget {
FormUtils.hasValue(item, 'IMG_PATH') ? item['IMG_PATH'] : null; FormUtils.hasValue(item, 'IMG_PATH') ? item['IMG_PATH'] : null;
if (rawIP is String && rawIP.isNotEmpty) { if (rawIP is String && rawIP.isNotEmpty) {
aggregatedImgPaths.addAll( aggregatedImgPaths.addAll(
rawIP.split(',') rawIP.split(',').map((s) => s.trim()).where((s) => s.isNotEmpty),
.map((s) => s.trim())
.where((s) => s.isNotEmpty),
); );
} else if (rawIP is List) { } else if (rawIP is List) {
aggregatedImgPaths.addAll( aggregatedImgPaths.addAll(
rawIP.cast<String>() rawIP
.cast<String>()
.map((s) => s.trim()) .map((s) => s.trim())
.where((s) => s.isNotEmpty), .where((s) => s.isNotEmpty),
); );
@ -1374,10 +1426,12 @@ class SignItemWidget extends StatelessWidget {
Container( Container(
padding: EdgeInsets.symmetric(horizontal: 12), padding: EdgeInsets.symmetric(horizontal: 12),
child: Row( child: Row(
children: displayImgPaths.map((p) { children:
displayImgPaths.map((p) {
final fullUrl = '$baseImgPath$p'; final fullUrl = '$baseImgPath$p';
return GestureDetector( return GestureDetector(
onTap: () => presentOpaque( onTap:
() => presentOpaque(
SingleImageViewer(imageUrl: fullUrl), SingleImageViewer(imageUrl: fullUrl),
context, context,
), ),
@ -1390,11 +1444,15 @@ class SignItemWidget extends StatelessWidget {
width: smallThumbSize, width: smallThumbSize,
height: smallThumbSize, height: smallThumbSize,
fit: BoxFit.cover, fit: BoxFit.cover,
errorBuilder: (_, __, ___) => Container( errorBuilder:
(_, __, ___) => Container(
width: smallThumbSize, width: smallThumbSize,
height: smallThumbSize, height: smallThumbSize,
color: Colors.grey.shade200, color: Colors.grey.shade200,
child: const Icon(Icons.broken_image, size: 24), child: const Icon(
Icons.broken_image,
size: 24,
),
), ),
), ),
), ),
@ -1415,9 +1473,8 @@ class SignItemWidget extends StatelessWidget {
} }
// //
final lastTime = aggregatedSignTimes.isNotEmpty final lastTime =
? aggregatedSignTimes.last.trim() aggregatedSignTimes.isNotEmpty ? aggregatedSignTimes.last.trim() : '';
: '';
// //
const double thumbSize = 60.0; const double thumbSize = 60.0;
@ -1433,8 +1490,9 @@ class SignItemWidget extends StatelessWidget {
child: LayoutBuilder( child: LayoutBuilder(
builder: (ctx, constraints) { builder: (ctx, constraints) {
// = - - // = - -
final double maxImageAreaWidth = final double maxImageAreaWidth = (constraints.maxWidth -
(constraints.maxWidth - timeBoxWidth - 8) timeBoxWidth -
8)
.clamp(0.0, constraints.maxWidth); .clamp(0.0, constraints.maxWidth);
return Align( return Align(
@ -1448,7 +1506,9 @@ class SignItemWidget extends StatelessWidget {
// 使 Wrap // 使 Wrap
if (aggregatedSignPaths.isNotEmpty) if (aggregatedSignPaths.isNotEmpty)
ConstrainedBox( ConstrainedBox(
constraints: BoxConstraints(maxWidth: maxImageAreaWidth), constraints: BoxConstraints(
maxWidth: maxImageAreaWidth,
),
child: Padding( child: Padding(
padding: const EdgeInsets.only(left: 6.0), padding: const EdgeInsets.only(left: 6.0),
child: Wrap( child: Wrap(
@ -1456,10 +1516,12 @@ class SignItemWidget extends StatelessWidget {
runSpacing: 6.0, runSpacing: 6.0,
alignment: WrapAlignment.start, alignment: WrapAlignment.start,
crossAxisAlignment: WrapCrossAlignment.end, crossAxisAlignment: WrapCrossAlignment.end,
children: aggregatedSignPaths.map((imgPath) { children:
aggregatedSignPaths.map((imgPath) {
final fullUrl = '$baseImgPath$imgPath'; final fullUrl = '$baseImgPath$imgPath';
return GestureDetector( return GestureDetector(
onTap: () => presentOpaque( onTap:
() => presentOpaque(
SingleImageViewer(imageUrl: fullUrl), SingleImageViewer(imageUrl: fullUrl),
context, context,
), ),
@ -1470,7 +1532,8 @@ class SignItemWidget extends StatelessWidget {
width: thumbSize, width: thumbSize,
height: thumbSize, height: thumbSize,
fit: BoxFit.fill, fit: BoxFit.fill,
errorBuilder: (_, __, ___) => Container( errorBuilder:
(_, __, ___) => Container(
width: thumbSize, width: thumbSize,
height: thumbSize, height: thumbSize,
color: Colors.grey.shade200, color: Colors.grey.shade200,
@ -1488,9 +1551,8 @@ class SignItemWidget extends StatelessWidget {
), ),
// //
if (aggregatedSignPaths.isNotEmpty) const SizedBox(width: 8), if (aggregatedSignPaths.isNotEmpty)
const SizedBox(width: 8),
], ],
), ),
); );
@ -1500,8 +1562,9 @@ class SignItemWidget extends StatelessWidget {
), ),
); );
// //
list.add(const SizedBox(height: 10,)); list.add(const SizedBox(height: 10));
list.add(Row( list.add(
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
const SizedBox(), const SizedBox(),
@ -1509,18 +1572,16 @@ class SignItemWidget extends StatelessWidget {
lastTime, lastTime,
textAlign: TextAlign.right, textAlign: TextAlign.right,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
style: const TextStyle( style: const TextStyle(fontSize: 13, color: Colors.black87),
fontSize: 13,
color: Colors.black87,
), ),
)
], ],
)); ),
);
return list; return list;
} }
} }
/// ///
class ConfirmWithSignWidget extends StatelessWidget { class ConfirmWithSignWidget extends StatelessWidget {
const ConfirmWithSignWidget({ const ConfirmWithSignWidget({
@ -1571,14 +1632,16 @@ class ConfirmWithSignWidget extends StatelessWidget {
final safePd = pd ?? <String, dynamic>{}; final safePd = pd ?? <String, dynamic>{};
// section // section
if (!FormUtils.hasValue(safeSigns, sectionKey)) { // if (!FormUtils.hasValue(safeSigns, sectionKey)) {
return const SizedBox.shrink(); // return const SizedBox.shrink();
} // }
// signs // signs
final sectionList = safeSigns[sectionKey]; final sectionList = safeSigns[sectionKey];
String descrText = ''; String descrText = '';
if (sectionList is List && sectionList.isNotEmpty && sectionList[0] is Map) { if (sectionList is List &&
sectionList.isNotEmpty &&
sectionList[0] is Map) {
final first = sectionList[0] as Map; final first = sectionList[0] as Map;
final dynamic ds = first[descrField]; final dynamic ds = first[descrField];
if (ds != null) { if (ds != null) {
@ -1607,7 +1670,17 @@ class ConfirmWithSignWidget extends StatelessWidget {
), ),
child: Row( child: Row(
children: [ children: [
Expanded(child: ListItemFactory.headerTitle('$headerTitle')), Expanded(
child: Text(
'$headerTitle',
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.bold,
),
maxLines: 5,
overflow: TextOverflow.ellipsis,
),
),
const SizedBox(), const SizedBox(),
// pd nameKey // pd nameKey
// if (FormUtils.hasValue(safePd, nameKey)) // if (FormUtils.hasValue(safePd, nameKey))
@ -1622,7 +1695,10 @@ class ConfirmWithSignWidget extends StatelessWidget {
// descrText // descrText
if (descrText.isNotEmpty) if (descrText.isNotEmpty)
Padding( Padding(
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 5), padding: const EdgeInsets.symmetric(
horizontal: 10,
vertical: 5,
),
child: Text( child: Text(
descrText, descrText,
maxLines: 100, maxLines: 100,
@ -1633,14 +1709,18 @@ class ConfirmWithSignWidget extends StatelessWidget {
// imgsKey safePd ItemListWidget.twoRowTitleAndImages imageUrls // imgsKey safePd ItemListWidget.twoRowTitleAndImages imageUrls
if (imgsKey.isNotEmpty && FormUtils.hasValue(safePd, imgsKey)) if (imgsKey.isNotEmpty && FormUtils.hasValue(safePd, imgsKey))
Builder(builder: (ctx) { Builder(
builder: (ctx) {
final dynamic rawImgs = safePd[imgsKey]; final dynamic rawImgs = safePd[imgsKey];
// ItemListWidget imageUrls rawImgs // ItemListWidget imageUrls rawImgs
if (rawImgs != null) { if (rawImgs != null) {
return ItemListWidget.twoRowTitleAndImages( return ItemListWidget.twoRowTitleAndImages(
onTapCallBack: (val) { onTapCallBack: (val) {
// 使 context // 使 context
presentOpaque(SingleImageViewer(imageUrl: val), context); presentOpaque(
SingleImageViewer(imageUrl: val),
context,
);
}, },
title: '', title: '',
imageUrls: rawImgs, imageUrls: rawImgs,
@ -1648,10 +1728,12 @@ class ConfirmWithSignWidget extends StatelessWidget {
} else { } else {
return const SizedBox.shrink(); return const SizedBox.shrink();
} }
}), },
),
// contentKey pd // contentKey pd
if (contentKey.isNotEmpty && FormUtils.hasValue(safePd, contentKey)) if (contentKey.isNotEmpty &&
FormUtils.hasValue(safePd, contentKey))
ItemListWidget.itemContainer( ItemListWidget.itemContainer(
Text( Text(
(safePd[contentKey] ?? '').toString(), (safePd[contentKey] ?? '').toString(),
@ -1701,7 +1783,8 @@ class SignRowImageTitle extends StatelessWidget {
final List<String> imagePaths = []; final List<String> imagePaths = [];
final safeSigns = signs ?? <String, dynamic>{}; final safeSigns = signs ?? <String, dynamic>{};
final rawList = FormUtils.hasValue(safeSigns, signKey) ? safeSigns[signKey] : null; final rawList =
FormUtils.hasValue(safeSigns, signKey) ? safeSigns[signKey] : null;
if (rawList == null) return imagePaths; if (rawList == null) return imagePaths;
@ -1711,14 +1794,16 @@ class SignRowImageTitle extends StatelessWidget {
if (raw is! Map) continue; if (raw is! Map) continue;
final item = Map<String, dynamic>.from(raw); final item = Map<String, dynamic>.from(raw);
final rawSP = FormUtils.hasValue(item, 'SIGN_PATH') ? item['SIGN_PATH'] : null; final rawSP =
FormUtils.hasValue(item, 'SIGN_PATH') ? item['SIGN_PATH'] : null;
if (rawSP is String && rawSP.isNotEmpty) { if (rawSP is String && rawSP.isNotEmpty) {
imagePaths.addAll( imagePaths.addAll(
rawSP.split(',').map((s) => s.trim()).where((s) => s.isNotEmpty), rawSP.split(',').map((s) => s.trim()).where((s) => s.isNotEmpty),
); );
} else if (rawSP is List) { } else if (rawSP is List) {
imagePaths.addAll( imagePaths.addAll(
rawSP.cast<dynamic>() rawSP
.cast<dynamic>()
.where((e) => e != null) .where((e) => e != null)
.map((e) => e.toString().trim()) .map((e) => e.toString().trim())
.where((s) => s.isNotEmpty), .where((s) => s.isNotEmpty),
@ -1732,14 +1817,18 @@ class SignRowImageTitle extends StatelessWidget {
); );
} else if (rawList is Map) { } else if (rawList is Map) {
// Map SIGN_PATH // Map SIGN_PATH
final rawSP = FormUtils.hasValue(rawList, 'SIGN_PATH') ? rawList['SIGN_PATH'] : null; final rawSP =
FormUtils.hasValue(rawList, 'SIGN_PATH')
? rawList['SIGN_PATH']
: null;
if (rawSP is String && rawSP.isNotEmpty) { if (rawSP is String && rawSP.isNotEmpty) {
imagePaths.addAll( imagePaths.addAll(
rawSP.split(',').map((s) => s.trim()).where((s) => s.isNotEmpty), rawSP.split(',').map((s) => s.trim()).where((s) => s.isNotEmpty),
); );
} else if (rawSP is List) { } else if (rawSP is List) {
imagePaths.addAll( imagePaths.addAll(
rawSP.cast<dynamic>() rawSP
.cast<dynamic>()
.where((e) => e != null) .where((e) => e != null)
.map((e) => e.toString().trim()) .map((e) => e.toString().trim())
.where((s) => s.isNotEmpty), .where((s) => s.isNotEmpty),
@ -1764,8 +1853,7 @@ class SignRowImageTitle extends StatelessWidget {
try { try {
presentOpaque(SingleImageViewer(imageUrl: fullUrl), context); presentOpaque(SingleImageViewer(imageUrl: fullUrl), context);
return; return;
} catch (_) { } catch (_) {}
}
} }
@override @override
@ -1773,10 +1861,7 @@ class SignRowImageTitle extends StatelessWidget {
final imagePaths = _extractSignPaths(); final imagePaths = _extractSignPaths();
return Container( return Container(
padding: const EdgeInsets.symmetric( padding: const EdgeInsets.symmetric(vertical: 5, horizontal: 12),
vertical: 5,
horizontal: 12,
),
child: Row( child: Row(
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
@ -1784,10 +1869,7 @@ class SignRowImageTitle extends StatelessWidget {
// //
Text( Text(
label, label,
style: TextStyle( style: TextStyle(fontSize: fontSize, fontWeight: FontWeight.bold),
fontSize: fontSize,
fontWeight: FontWeight.bold,
),
), ),
// const SizedBox(width: 12), // const SizedBox(width: 12),
@ -1804,7 +1886,8 @@ class SignRowImageTitle extends StatelessWidget {
runSpacing: gap, runSpacing: gap,
alignment: WrapAlignment.end, alignment: WrapAlignment.end,
crossAxisAlignment: WrapCrossAlignment.end, crossAxisAlignment: WrapCrossAlignment.end,
children: imagePaths.map((p) { children:
imagePaths.map((p) {
final fullUrl = '${ApiService.baseImgPath}$p'; final fullUrl = '${ApiService.baseImgPath}$p';
return GestureDetector( return GestureDetector(
onTap: () => _openPreview(context, fullUrl), onTap: () => _openPreview(context, fullUrl),
@ -1815,11 +1898,15 @@ class SignRowImageTitle extends StatelessWidget {
width: imageSize, width: imageSize,
height: imageSize, height: imageSize,
fit: BoxFit.cover, fit: BoxFit.cover,
errorBuilder: (_, __, ___) => Container( errorBuilder:
(_, __, ___) => Container(
width: imageSize, width: imageSize,
height: imageSize, height: imageSize,
color: Colors.grey.shade200, color: Colors.grey.shade200,
child: const Icon(Icons.broken_image, size: 24), child: const Icon(
Icons.broken_image,
size: 24,
),
), ),
), ),
), ),
@ -1843,5 +1930,3 @@ class SignRowImageTitle extends StatelessWidget {
); );
} }
} }

View File

@ -167,13 +167,13 @@ class _HotWorkDetailFormWidgetState extends State<HotWorkDetailFormWidget> {
hintText: '请选择动火人及证书编号', hintText: '请选择动火人及证书编号',
onTap: widget.onChooseHotworkUser, onTap: widget.onChooseHotworkUser,
), ),
if (FormUtils.hasValue(pd, 'UNIT_NAME') && if (FormUtils.hasValue(pd, 'WORK_USER_DEPARTMENT_NAME') &&
!widget.isEditable) ...[ !widget.isEditable) ...[
const Divider(), const Divider(),
ItemListWidget.singleLineTitleText( ItemListWidget.singleLineTitleText(
label: '作业单位:', label: '作业单位:',
isEditable: false, isEditable: false,
text: pd['UNIT_NAME'] ?? '', text: pd['WORK_USER_DEPARTMENT_NAME'] ?? '',
), ),
], ],
if (FormUtils.hasValue(pd, 'CONFIRM_USER_NAME') && if (FormUtils.hasValue(pd, 'CONFIRM_USER_NAME') &&
@ -252,6 +252,7 @@ class _HotWorkDetailFormWidgetState extends State<HotWorkDetailFormWidget> {
isEditable: widget.isEditable, isEditable: widget.isEditable,
onTap: () async { onTap: () async {
DateTime? picked = await BottomDateTimePicker.showDate( DateTime? picked = await BottomDateTimePicker.showDate(
mode: BottomPickerMode.dateTimeWithSeconds,
context, context,
minTimeStr: pd['WORK_EXPECTED_START_TIME'] ?? '', minTimeStr: pd['WORK_EXPECTED_START_TIME'] ?? '',
allowFuture: true, allowFuture: true,
@ -303,6 +304,7 @@ class _HotWorkDetailFormWidgetState extends State<HotWorkDetailFormWidget> {
isEditable: widget.isEditable, isEditable: widget.isEditable,
onTap: () async { onTap: () async {
DateTime? picked = await BottomDateTimePicker.showDate( DateTime? picked = await BottomDateTimePicker.showDate(
mode: BottomPickerMode.dateTimeWithSeconds,
context, context,
minTimeStr: pd['WORK_EXPECTED_START_TIME'] ?? '', minTimeStr: pd['WORK_EXPECTED_START_TIME'] ?? '',
allowFuture: true, allowFuture: true,

View File

@ -187,10 +187,7 @@ class _HotworkSafeFuncSureState extends State<HotworkSafeFuncSure> {
/// 1 0 /// 1 0
Future<void> _submit(String status) async { Future<void> _submit(String status) async {
if (_otherController.text.trim().isEmpty) {
ToastUtil.showNormal(context, '请输入其他安全措施,没有请填“无”');
return;
}
if (imagePaths.isEmpty) { if (imagePaths.isEmpty) {
ToastUtil.showNormal(context, '请签字'); ToastUtil.showNormal(context, '请签字');
return; return;
@ -201,6 +198,10 @@ class _HotworkSafeFuncSureState extends State<HotworkSafeFuncSure> {
if (!_validateAndProceed(context)) { if (!_validateAndProceed(context)) {
return; return;
} }
if (_otherController.text.trim().isEmpty) {
ToastUtil.showNormal(context, '请输入其他安全措施,没有请填“无”');
return;
}
} else { } else {
reasonText = await CustomAlertDialog.showInput( reasonText = await CustomAlertDialog.showInput(
context, context,
@ -242,7 +243,7 @@ class _HotworkSafeFuncSureState extends State<HotworkSafeFuncSure> {
); );
LoadingDialogHelper.hide(); LoadingDialogHelper.hide();
if (result['result'] == 'success') { if (result['result'] == 'success') {
ToastUtil.showSuccess(context, status == '1' ? '提交成功' : '已暂存'); ToastUtil.showSuccess(context, status == '1' ? '提交成功' : '操作成功');
Navigator.of(context).pop(true); // true Navigator.of(context).pop(true); // true
} }
} catch (e) { } catch (e) {
@ -370,6 +371,7 @@ class _HotworkSafeFuncSureState extends State<HotworkSafeFuncSure> {
], ],
), ),
ItemListWidget.singleLineTitleText( ItemListWidget.singleLineTitleText(
isNumericInput: true,
label: '其他安全措施:', label: '其他安全措施:',
isEditable: true, isEditable: true,
hintText: '请输入其他安全措施', hintText: '请输入其他安全措施',

View File

@ -263,7 +263,7 @@ class _HotworkDbbzDetailState extends State<HotworkDbbzDetail> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: MyAppbar(title: '班长验票'), appBar: MyAppbar(title: '动火前,岗位当班班长验票情况'),
body: SafeArea( body: SafeArea(
child: SingleChildScrollView( child: SingleChildScrollView(
padding: EdgeInsets.all(12), padding: EdgeInsets.all(12),
@ -290,7 +290,7 @@ class _HotworkDbbzDetailState extends State<HotworkDbbzDetail> {
Column( Column(
children: [ children: [
ListItemFactory.createBuildMultilineInput( ListItemFactory.createBuildMultilineInput(
'动火前在岗班长意见', '动火前,岗位当班班长意见',
'请输入意见', '请输入意见',
_contentController, _contentController,
isRequired: true, isRequired: true,
@ -301,7 +301,7 @@ class _HotworkDbbzDetailState extends State<HotworkDbbzDetail> {
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
ListItemFactory.headerTitle('动火前在岗班长'), ListItemFactory.headerTitle('动火前,岗位当班班长'),
CustomButton( CustomButton(
text: '新增手写签字', text: '新增手写签字',
height: 36, height: 36,

View File

@ -379,8 +379,10 @@ class _HotworkApplyDetailState extends State<HotworkApplyDetail> {
onTapClean: () { onTapClean: () {
ToastUtil.showNormal(context, '已清除'); ToastUtil.showNormal(context, '已清除');
setState(() { setState(() {
pd['${type.name}_DEPARTMENT_NAME'] = ''; set_pd_USER_ID(type, '');
pd['${type.name}_USER_NAME'] = ''; set_pd_USER_Name(type, '');
set_pd_DEPARTMENT_NAME(type, '');
set_pd_DEPARTMENT_ID(type, '');
_personCache.remove(type); _personCache.remove(type);
}); });
}, },
@ -579,7 +581,7 @@ class _HotworkApplyDetailState extends State<HotworkApplyDetail> {
pd['ACTION_USER'] = SessionService.instance.username; pd['ACTION_USER'] = SessionService.instance.username;
pd['APPLY_STATUS'] = status; pd['APPLY_STATUS'] = status;
pd['TASK_ID'] = taskId; pd['TASK_ID'] = taskId;
pd['SPECIAL_WORK'] = FormUtils.hasValue(pd, 'SPECIAL_WORK') ? pd['SPECIAL_WORK'] : '';
// //
if (msg == 'add') { if (msg == 'add') {
pd['HOTWORK_ID'] = widget.HOTWORK_ID; pd['HOTWORK_ID'] = widget.HOTWORK_ID;
@ -598,7 +600,7 @@ class _HotworkApplyDetailState extends State<HotworkApplyDetail> {
final result = await ApiService.submitHomework(url, pd); final result = await ApiService.submitHomework(url, pd);
LoadingDialogHelper.hide(); LoadingDialogHelper.hide();
if (result['result'] == 'success') { if (result['result'] == 'success') {
ToastUtil.showSuccess(context, status == '1' ? '提交成功' : '已暂存'); ToastUtil.showSuccess(context, status == '1' ? '提交成功' : '操作成功');
Navigator.of(context).pop(true); Navigator.of(context).pop(true);
} else { } else {
ToastUtil.showError(context, result['msg'] ?? '提交失败'); ToastUtil.showError(context, result['msg'] ?? '提交失败');

View File

@ -1,5 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:qhd_prevention/customWidget/toast_util.dart'; import 'package:qhd_prevention/customWidget/toast_util.dart';
import 'package:qhd_prevention/pages/home/tap/item_list_widget.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/dh_work_detai/hotwork_apply_detail.dart'; import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/dh_work_detai/hotwork_apply_detail.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/aqcs_work_detail/hotwork_safe_func_sure.dart'; import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/aqcs_work_detail/hotwork_safe_func_sure.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/aqgl_work_detail/hotwork_aqgl_detail.dart'; import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/aqgl_work_detail/hotwork_aqgl_detail.dart';
@ -139,7 +140,10 @@ class _HotWorkListPageState extends State<HotWorkListPage> {
/// ///
void _handleApply() async { void _handleApply() async {
// //
await pushPage(HotworkApplyDetail(HOTWORK_ID: '', flow: widget.flow), context); await pushPage(
HotworkApplyDetail(HOTWORK_ID: '', flow: widget.flow),
context,
);
_fetchData(); _fetchData();
LoadingDialogHelper.hide(); LoadingDialogHelper.hide();
} }
@ -286,78 +290,10 @@ class _HotWorkListPageState extends State<HotWorkListPage> {
break; break;
} }
await _fetchData(); await _fetchData();
LoadingDialogHelper.hide(); LoadingDialogHelper.hide();
} }
Widget _buildFlowStepItem({
required Map<String, dynamic> item,
required bool isFirst,
required bool isLast,
required int status, // 1 = , 0 = , -1 =
}) {
//
final Color dotColor =
status == 1 ? Colors.green : (status == 0 ? Colors.blue : Colors.grey);
final Color textColor =
status == 1 ? Colors.green : (status == 0 ? Colors.blue : Colors.black);
return ListTile(
visualDensity: VisualDensity(vertical: -4),
contentPadding: const EdgeInsets.symmetric(horizontal: 16),
leading: Container(
width: 24,
alignment: Alignment.center,
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
// 线
isFirst
? SizedBox(height: 6 + 5)
: Expanded(child: Container(width: 1, color: Colors.grey[300])),
//
CircleAvatar(radius: 6, backgroundColor: dotColor),
// 线
isLast
? SizedBox(height: 6 + 5)
: Expanded(child: Container(width: 1, color: Colors.grey[300])),
],
),
),
title: Text(
item['STEP_NAME'] ?? '',
style: TextStyle(color: textColor, fontSize: 15),
),
subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (item['SIGN_USER'] != null)
Text(
item['SIGN_USER'],
style: TextStyle(color: textColor, fontSize: 13),
),
if (item['FINISHED_SIGN_USER'] != null)
Text(
item['FINISHED_SIGN_USER'],
style: TextStyle(color: textColor, fontSize: 13),
),
if (item['ACT_USER_NAME'] != null)
Text(
item['ACT_USER_NAME'],
style: TextStyle(color: textColor, fontSize: 13),
),
if (item['ACT_TIME'] != null)
Text(
item['ACT_TIME'],
style: TextStyle(color: textColor, fontSize: 13),
),
],
),
);
}
Widget _buildListItem(Map<String, dynamic> item) { Widget _buildListItem(Map<String, dynamic> item) {
return Card( return Card(
color: Colors.white, color: Colors.white,
@ -368,107 +304,196 @@ class _HotWorkListPageState extends State<HotWorkListPage> {
padding: const EdgeInsets.all(12.0), padding: const EdgeInsets.all(12.0),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
spacing: 8,
children: [ children: [
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"编号: ${item['CHECK_NO'] ?? ''}",
style: TextStyle(fontSize: 14, fontWeight: FontWeight.bold),
),
Text(
"作业级别: ${item['WORK_LEVEL'] ?? ''}",
style: TextStyle(fontSize: 14, fontWeight: FontWeight.bold),
),
],
),
const SizedBox(height: 8),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text("申请人: ${item['APPLY_USER_NAME'] ?? ''}"),
Text("分析人: ${item['ANALYZE_USER_NAME'] ?? ''}"),
],
),
const SizedBox(height: 8),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text("监护人: ${item['GUARDIAN_USER_NAME'] ?? ''}"),
Text("审批部门负责人: ${item['APPROVE_USER_NAME'] ?? ''}"),
],
),
const SizedBox(height: 8),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(child: Text("安全交底人: ${item['CONFESS_USER_NAME'] ?? ''}",softWrap: true,
maxLines: null, //
overflow: TextOverflow.visible,)
),
Expanded(child: Text("接受交底人: ${item['ACCEPT_CONFESS_USER_NAME'] ?? ''}",softWrap: true,
textAlign: TextAlign.right,
maxLines: null, //
overflow: TextOverflow.visible,)
),
],
),
const SizedBox(height: 8),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(child: Text("作业负责人: ${item['CONFIRM_USER_NAME'] ?? ''}",softWrap: true,
maxLines: null, //
overflow: TextOverflow.visible,)
),
Expanded(child: Text("动火点负责人: ${item['LEADER_USER_NAME'] ?? ''}",softWrap: true,
textAlign: TextAlign.right,
maxLines: null, //
overflow: TextOverflow.visible,)
),
],
),
const SizedBox(height: 8),
if (item['AUDIT_USER_NAME'] != null)
Text("安全管理部门负责人: ${item['AUDIT_USER_NAME'] ?? ''}"),
const SizedBox(height: 8),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [Text("动火前在岗班长: ${item['MONITOR_USER_NAME'] ?? ''}")],
),
const SizedBox(height: 8),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Expanded( Expanded(
child: Text("验收部门负责人: ${item['ACCEPT_USER_NAME'] ?? ''}"), child: Text(
"编号: ${item['CHECK_NO'] ?? ''}",
style: const TextStyle(fontSize: 14, fontWeight: FontWeight.bold),
softWrap: true,
maxLines: null,
overflow: TextOverflow.visible,
),
),
const SizedBox(width: 8),
Expanded(
child: Text(
"作业级别: ${item['WORK_LEVEL'] ?? ''}",
textAlign: TextAlign.right,
style: const TextStyle(fontSize: 14, fontWeight: FontWeight.bold),
softWrap: true,
maxLines: null,
overflow: TextOverflow.visible,
),
), ),
], ],
), ),
const SizedBox(height: 8),
Row(
children: [
Expanded(
child: Text(
"申请人: ${item['APPLY_USER_NAME'] ?? ''}",
softWrap: true,
maxLines: null,
overflow: TextOverflow.visible,
),
),
const SizedBox(width: 8),
Expanded(
child: Text(
"分析人: ${item['ANALYZE_USER_NAME'] ?? ''}",
textAlign: TextAlign.right,
softWrap: true,
maxLines: null,
overflow: TextOverflow.visible,
),
),
],
),
Row(
children: [
Expanded(
child: Text(
"监护人: ${item['GUARDIAN_USER_NAME'] ?? ''}",
softWrap: true,
maxLines: null,
overflow: TextOverflow.visible,
),
),
const SizedBox(width: 8),
Expanded(
child: item['APPROVE_USER_NAME'] != null
? Text(
"审批部门负责人: ${item['APPROVE_USER_NAME'] ?? ''}",
textAlign: TextAlign.right,
softWrap: true,
maxLines: null,
overflow: TextOverflow.visible,
)
: const SizedBox.shrink(),
),
],
),
Row(
children: [
Expanded(
child: Text(
"安全交底人: ${item['CONFESS_USER_NAME'] ?? ''}",
softWrap: true,
maxLines: null,
overflow: TextOverflow.visible,
),
),
const SizedBox(width: 8),
Expanded(
child: Text(
"接受交底人: ${item['ACCEPT_CONFESS_USER_NAME'] ?? ''}",
textAlign: TextAlign.right,
softWrap: true,
maxLines: null,
overflow: TextOverflow.visible,
),
),
],
),
Row(
children: [
Expanded(
child: Text(
"作业负责人: ${item['CONFIRM_USER_NAME'] ?? ''}",
softWrap: true,
maxLines: null,
overflow: TextOverflow.visible,
),
),
const SizedBox(width: 8),
Expanded(
child: Text(
"所在单位负责人: ${item['LEADER_USER_NAME'] ?? ''}",
textAlign: TextAlign.right,
softWrap: true,
maxLines: null,
overflow: TextOverflow.visible,
),
),
],
),
if (item['AUDIT_USER_NAME'] != null)
Text(
"安全管理部门负责人: ${item['AUDIT_USER_NAME'] ?? ''}",
softWrap: true,
maxLines: null,
overflow: TextOverflow.visible,
),
if (FormUtils.hasValue(item, 'APPROVE_USER_NAME'))
Row(
children: [
Expanded(
child: Text(
"动火审批负责人: ${item['APPROVE_USER_NAME'] ?? ''}",
softWrap: true,
maxLines: null,
overflow: TextOverflow.visible,
textAlign: TextAlign.left,
)
),
],
),
Row(
children: [
Expanded(
child: Text(
"动火前在岗班长: ${item['MONITOR_USER_NAME'] ?? ''}",
textAlign: TextAlign.left,
softWrap: true,
maxLines: null,
overflow: TextOverflow.visible,
),
),
Expanded(
child: Text(
"验收部门负责人: ${item['ACCEPT_USER_NAME'] ?? ''}",
textAlign: TextAlign.right,
softWrap: true,
maxLines: null,
overflow: TextOverflow.visible,
),
),
],
),
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Expanded( Expanded(
child: Text( child: Text(
"审核状态: ${_getStatusText(item)}", "审核状态: ${_getStatusText(item)}",
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
softWrap: true,
maxLines: null,
), ),
), ),
], ],
), ),
const SizedBox(height: 8),
Row( Row(
children: [ children: [
CustomButton( CustomButton(
text: '查看流程图', text: '查看流程图',
height: 35, height: 35,
padding: EdgeInsets.symmetric(horizontal: 12), padding: const EdgeInsets.symmetric(horizontal: 12),
margin: EdgeInsets.only(left: 0), margin: const EdgeInsets.only(left: 0),
backgroundColor: Colors.blue, backgroundColor: Colors.blue,
onPressed: () => _openFlowDrawer(item['HOTWORK_ID']), onPressed: () => _openFlowDrawer(item['HOTWORK_ID']),
), ),
SizedBox(width: 1), const SizedBox(width: 8),
], ],
), ),
], ],
@ -581,48 +606,7 @@ class _HotWorkListPageState extends State<HotWorkListPage> {
child: child:
flowList.isEmpty flowList.isEmpty
? Center(child: Text('暂无流程图数据')) ? Center(child: Text('暂无流程图数据'))
: ListView.builder( : ItemListWidget.buildFlowStepItem(flowList: flowList),
padding: const EdgeInsets.symmetric(vertical: 16),
itemCount: flowList.length + 1, // +1
itemBuilder: (context, i) {
if (i == 0) {
return Padding(
padding: const EdgeInsets.symmetric(
horizontal: 16,
vertical: 8,
),
child: Text(
'查看流程图',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
);
}
final idx = i - 1;
final item = flowList[idx];
final bool isFirst = idx == 0;
final bool isLast = idx == flowList.length - 1;
// lastDoneIndex
final int status;
if (idx <= lastDoneIndex) {
status = 1; //
} else if (idx == lastDoneIndex + 1) {
status = 0; //
} else {
status = -1; //
}
return _buildFlowStepItem(
item: item,
isFirst: isFirst,
isLast: isLast,
status: status,
);
},
),
), ),
), ),

View File

@ -380,6 +380,7 @@ class _HotworkYsgdDetailState extends State<HotworkYsgdDetail> {
), ),
onTap: () async { onTap: () async {
DateTime? picked = await BottomDateTimePicker.showDate( DateTime? picked = await BottomDateTimePicker.showDate(
allowPast:false,
mode: BottomPickerMode.dateTimeWithSeconds, mode: BottomPickerMode.dateTimeWithSeconds,
context, context,
); );

View File

@ -121,12 +121,12 @@ class _CutroadDetailFormWidgetState extends State<CutroadDetailFormWidget> {
isEditable: false, isEditable: false,
text: pd['APPLY_USER_NAME'] ?? '', text: pd['APPLY_USER_NAME'] ?? '',
), ),
if (FormUtils.hasValue(pd, 'CONFIRM_DEPARTMENT_NAME')) ...[ if (FormUtils.hasValue(pd, 'WORK_USER_DEPARTMENT_NAME')) ...[
const Divider(), const Divider(),
ItemListWidget.singleLineTitleText( ItemListWidget.singleLineTitleText(
label: '作业单位:', label: '作业单位:',
isEditable: false, isEditable: false,
text: pd['CONFIRM_DEPARTMENT_NAME'] ?? '', text: pd['WORK_USER_DEPARTMENT_NAME'] ?? '',
), ),
], ],
if (FormUtils.hasValue(pd, 'CONFIRM_USER_NAME') && if (FormUtils.hasValue(pd, 'CONFIRM_USER_NAME') &&
@ -247,6 +247,7 @@ class _CutroadDetailFormWidgetState extends State<CutroadDetailFormWidget> {
isEditable: widget.isEditable, isEditable: widget.isEditable,
onTap: () async { onTap: () async {
DateTime? picked = await BottomDateTimePicker.showDate( DateTime? picked = await BottomDateTimePicker.showDate(
mode: BottomPickerMode.dateTimeWithSeconds,
context, context,
minTimeStr: pd['WORK_EXPECTED_START_TIME'] ?? '', minTimeStr: pd['WORK_EXPECTED_START_TIME'] ?? '',
allowFuture: true, allowFuture: true,
@ -299,6 +300,7 @@ class _CutroadDetailFormWidgetState extends State<CutroadDetailFormWidget> {
isEditable: widget.isEditable, isEditable: widget.isEditable,
onTap: () async { onTap: () async {
DateTime? picked = await BottomDateTimePicker.showDate( DateTime? picked = await BottomDateTimePicker.showDate(
mode: BottomPickerMode.dateTimeWithSeconds,
context, context,
minTimeStr: pd['WORK_EXPECTED_START_TIME'] ?? '', minTimeStr: pd['WORK_EXPECTED_START_TIME'] ?? '',
allowFuture: true, allowFuture: true,

View File

@ -39,8 +39,6 @@ class _CutroadSafeFuncSureState extends State<CutroadSafeFuncSure> {
/// ///
final TextEditingController _otherController = TextEditingController(); final TextEditingController _otherController = TextEditingController();
/// ///
List<String> imagePaths = []; List<String> imagePaths = [];
List<String> signTimes = []; // List<String> signTimes = []; //
@ -48,8 +46,8 @@ class _CutroadSafeFuncSureState extends State<CutroadSafeFuncSure> {
void initState() { void initState() {
super.initState(); super.initState();
_getData(); _getData();
} }
late Map<String, dynamic> pd = {}; late Map<String, dynamic> pd = {};
late Map<String, dynamic> signs = {}; late Map<String, dynamic> signs = {};
late List<Map<String, dynamic>> measuresList = []; late List<Map<String, dynamic>> measuresList = [];
@ -60,34 +58,51 @@ class _CutroadSafeFuncSureState extends State<CutroadSafeFuncSure> {
try { try {
// Future.wait // Future.wait
final futurePd = ApiService.getHomeworkFindById('cutroad', widget.CUTROAD_ID) final futurePd = ApiService.getHomeworkFindById(
.catchError((e) { 'cutroad',
widget.CUTROAD_ID,
).catchError((e) {
// e // e
return <String, dynamic>{}; // 退 map return <String, dynamic>{}; // 退 map
}); });
final futureSigns = ApiService.listSignFinished('cutroad', widget.CUTROAD_ID) final futureSigns = ApiService.listSignFinished(
.catchError((e) { 'cutroad',
widget.CUTROAD_ID,
).catchError((e) {
return <String, dynamic>{'signs': <String, dynamic>{}}; return <String, dynamic>{'signs': <String, dynamic>{}};
}); });
final futureMeasures = ApiService.listSignSureAllMeasures('cutroad', widget.CUTROAD_ID) final futureMeasures = ApiService.listSignSureAllMeasures(
.catchError((e) { 'cutroad',
return <String, dynamic>{'measuresForSignList': <Map<String, dynamic>>[]}; widget.CUTROAD_ID,
).catchError((e) {
return <String, dynamic>{
'measuresForSignList': <Map<String, dynamic>>[],
};
}); });
final results = await Future.wait([futurePd, futureSigns, futureMeasures]); final results = await Future.wait([
futurePd,
futureSigns,
futureMeasures,
]);
final pdResult = results[0] as Map<String, dynamic>? ?? <String, dynamic>{}; final pdResult =
final signsResult = results[1] as Map<String, dynamic>? ?? <String, dynamic>{}; results[0] as Map<String, dynamic>? ?? <String, dynamic>{};
final measuresResult = results[2] 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>) final newPd =
(pdResult['pd'] is Map<String, dynamic>)
? Map<String, dynamic>.from(pdResult['pd']) ? Map<String, dynamic>.from(pdResult['pd'])
: <String, dynamic>{}; : <String, dynamic>{};
final newSigns = (signsResult['signs'] is Map<String, dynamic>) final newSigns =
(signsResult['signs'] is Map<String, dynamic>)
? Map<String, dynamic>.from(signsResult['signs']) ? Map<String, dynamic>.from(signsResult['signs'])
: <String, dynamic>{}; : <String, dynamic>{};
@ -114,6 +129,7 @@ class _CutroadSafeFuncSureState extends State<CutroadSafeFuncSure> {
LoadingDialogHelper.hide(); LoadingDialogHelper.hide();
} }
} }
/// ///
void chooseUnitHandle(MeasureItem item) { void chooseUnitHandle(MeasureItem item) {
showModalBottomSheet( showModalBottomSheet(
@ -122,8 +138,7 @@ class _CutroadSafeFuncSureState extends State<CutroadSafeFuncSure> {
barrierColor: Colors.black54, barrierColor: Colors.black54,
backgroundColor: Colors.transparent, backgroundColor: Colors.transparent,
builder: builder:
(_) => (_) => DepartmentPicker(
DepartmentPicker(
onSelected: (id, name) async { onSelected: (id, name) async {
setState(() { setState(() {
item.DEPARTMENT_ID = id; item.DEPARTMENT_ID = id;
@ -145,8 +160,6 @@ class _CutroadSafeFuncSureState extends State<CutroadSafeFuncSure> {
}); });
} }
/// ///
Future<void> _sign() async { Future<void> _sign() async {
await NativeOrientation.setLandscape(); await NativeOrientation.setLandscape();
@ -221,6 +234,7 @@ if (path != null) {
}).toList(), }).toList(),
); );
} }
bool _validateAndProceed(BuildContext context) { bool _validateAndProceed(BuildContext context) {
for (var i = 0; i < measuresList.length; i++) { for (var i = 0; i < measuresList.length; i++) {
final m = measuresList[i]; final m = measuresList[i];
@ -234,10 +248,9 @@ if (path != null) {
// STATUS == '1' ANSWER // STATUS == '1' ANSWER
if (m['STATUS'] == '1') { if (m['STATUS'] == '1') {
for (var j = 1; j <= 4; j++) { for (var j = 1; j <= 4; j++) {
if (FormUtils.hasValue(m, 'QUESTION${j}') if (FormUtils.hasValue(m, 'QUESTION${j}')) {
) { if (!FormUtils.hasValue(m, 'ANSWER${j}') ||
if (!FormUtils.hasValue(m, 'ANSWER${j}') (m['ANSWER${j}'] as String?)!.length == 0) {
|| (m['ANSWER${j}'] as String?)!.length == 0) {
ToastUtil.showNormal(context, '${i + 1}项未填写第${j}'); ToastUtil.showNormal(context, '${i + 1}项未填写第${j}');
return false; return false;
} }
@ -247,12 +260,10 @@ if (path != null) {
} }
return true; return true;
} }
/// 1 0 /// 1 0
Future<void> _submit(String status) async { Future<void> _submit(String status) async {
if (_otherController.text.trim().isEmpty) {
ToastUtil.showNormal(context, '请输入其他安全措施,没有请填“无”');
return;
}
if (imagePaths.isEmpty) { if (imagePaths.isEmpty) {
ToastUtil.showNormal(context, '请签字'); ToastUtil.showNormal(context, '请签字');
return; return;
@ -263,13 +274,17 @@ if (path != null) {
if (!_validateAndProceed(context)) { if (!_validateAndProceed(context)) {
return; return;
} }
if (_otherController.text.trim().isEmpty) {
ToastUtil.showNormal(context, '请输入其他安全措施,没有请填“无”');
return;
}
} else { } else {
reasonText = await CustomAlertDialog.showInput( reasonText = await CustomAlertDialog.showInput(
context, context,
title: '作废原因', title: '作废原因',
hintText: '请输入作废原因', hintText: '请输入作废原因',
cancelText: '取消', cancelText: '取消',
confirmText: '确定' confirmText: '确定',
); );
if (reasonText.isEmpty) { if (reasonText.isEmpty) {
ToastUtil.showNormal(context, '请填写作废原因'); ToastUtil.showNormal(context, '请填写作废原因');
@ -304,17 +319,13 @@ if (path != null) {
); );
LoadingDialogHelper.hide(); LoadingDialogHelper.hide();
if (result['result'] == 'success') { if (result['result'] == 'success') {
ToastUtil.showSuccess( ToastUtil.showSuccess(context, status == '1' ? '提交成功' : '操作成功');
context,
status == '1' ? '提交成功' : '已暂存',
);
Navigator.of(context).pop(true); // true Navigator.of(context).pop(true); // true
} }
} catch (e) { } catch (e) {
LoadingDialogHelper.hide(); LoadingDialogHelper.hide();
ToastUtil.showNormal(context, '操作失败:$e'); ToastUtil.showNormal(context, '操作失败:$e');
} }
} }
} }
@ -337,16 +348,25 @@ if (path != null) {
} }
} }
//measures['STATUS'] //measures['STATUS']
final result = await pushPage(DangerousOptionsPage(index: index,status: int.parse(FormUtils.hasValue(measures, 'STATUS') ? measures['STATUS'] : '1'), final result = await pushPage(
DangerousOptionsPage(
index: index,
status: int.parse(
FormUtils.hasValue(measures, 'STATUS') ? measures['STATUS'] : '1',
),
measures: measures['PROTECTIVE_MEASURES'] ?? '', measures: measures['PROTECTIVE_MEASURES'] ?? '',
imgList: imgList, imgList: imgList,
signImgList: signImgList), context); signImgList: signImgList,
),
context,
);
if (result != null) { if (result != null) {
setState(() { setState(() {
// local + remote // local + remote
final returned = result['imgList'] as List<dynamic>; final returned = result['imgList'] as List<dynamic>;
// ImageData // ImageData
final imgDataList = returned.map((m) { final imgDataList =
returned.map((m) {
return ImageData( return ImageData(
localPath: m['local'] as String, localPath: m['local'] as String,
serverPath: m['remote'] as String, serverPath: m['remote'] as String,
@ -364,14 +384,15 @@ if (path != null) {
measures['IMG_PATH'] = serverPathString; measures['IMG_PATH'] = serverPathString;
// //
measures['SIGN_ITEM'] = List<Map<String,dynamic>>.from(result['signImgList'] as List); measures['SIGN_ITEM'] = List<Map<String, dynamic>>.from(
result['signImgList'] as List,
);
// //
measures['STATUS'] = result['status'].toString(); measures['STATUS'] = result['status'].toString();
index = result['index'] as int; index = result['index'] as int;
//FocusHelper.clearFocus(context); //FocusHelper.clearFocus(context);
}); });
} }
} }
/// ///
@ -392,8 +413,7 @@ if (path != null) {
Container( Container(
color: Colors.white, color: Colors.white,
child: MeasuresListWidget( child: MeasuresListWidget(
measuresList: measuresList: measuresList, // List<Map<String, dynamic>>
measuresList, // List<Map<String, dynamic>>
baseImgPath: ApiService.baseImgPath, baseImgPath: ApiService.baseImgPath,
isAllowEdit: true, isAllowEdit: true,
onSign: (item) { onSign: (item) {
@ -403,11 +423,13 @@ if (path != null) {
), ),
], ],
), ),
ItemListWidget.singleLineTitleText(label: '其他安全措施:', ItemListWidget.singleLineTitleText(
isNumericInput: true,
label: '其他安全措施:',
isEditable: true, isEditable: true,
hintText: '请输入其他安全措施', hintText: '请输入其他安全措施',
controller controller: _otherController,
:_otherController), ),
SizedBox(height: 20), SizedBox(height: 20),
Row( Row(
@ -508,8 +530,7 @@ class MeasureItem {
List<Map<String, dynamic>>? userList, List<Map<String, dynamic>>? userList,
this.userIndex = -1, this.userIndex = -1,
List<Map<String, dynamic>>? selectMeasures, List<Map<String, dynamic>>? selectMeasures,
}) }) : userList = userList ?? [],
: userList = userList ?? [],
selectMeasures = selectMeasures ?? []; selectMeasures = selectMeasures ?? [];
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {

View File

@ -1,5 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:qhd_prevention/customWidget/toast_util.dart'; import 'package:qhd_prevention/customWidget/toast_util.dart';
import 'package:qhd_prevention/pages/home/tap/item_list_widget.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dl_work/dl_work_detai/cutroad_apply_detail.dart'; import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dl_work/dl_work_detai/cutroad_apply_detail.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dl_work/aqcs_work_detail/cutroad_safe_func_sure.dart'; import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dl_work/aqcs_work_detail/cutroad_safe_func_sure.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dl_work/aqjd_work_detail/cutroad_aqjd_detail.dart'; import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dl_work/aqjd_work_detail/cutroad_aqjd_detail.dart';
@ -237,72 +238,7 @@ ToastUtil.showNormal(context, '获取流程图失败');
LoadingDialogHelper.hide(); LoadingDialogHelper.hide();
} }
Widget _buildFlowStepItem({
required Map<String, dynamic> item,
required bool isFirst,
required bool isLast,
required int status, // 1 = , 0 = , -1 =
}) {
//
final Color dotColor =
status == 1 ? Colors.green : (status == 0 ? Colors.blue : Colors.grey);
final Color textColor =
status == 1 ? Colors.green : (status == 0 ? Colors.blue : Colors.black);
return ListTile(
visualDensity: VisualDensity(vertical: -4),
contentPadding: const EdgeInsets.symmetric(horizontal: 16),
leading: Container(
width: 24,
alignment: Alignment.center,
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
// 线
isFirst
? SizedBox(height: 6 + 5)
: Expanded(child: Container(width: 1, color: Colors.grey[300])),
//
CircleAvatar(radius: 6, backgroundColor: dotColor),
// 线
isLast
? SizedBox(height: 6 + 5)
: Expanded(child: Container(width: 1, color: Colors.grey[300])),
],
),
),
title: Text(
item['STEP_NAME'] ?? '',
style: TextStyle(color: textColor, fontSize: 15),
),
subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (item['SIGN_USER'] != null)
Text(
item['SIGN_USER'],
style: TextStyle(color: textColor, fontSize: 13),
),
if (item['FINISHED_SIGN_USER'] != null)
Text(
item['FINISHED_SIGN_USER'],
style: TextStyle(color: textColor, fontSize: 13),
),
if (item['ACT_USER_NAME'] != null)
Text(
item['ACT_USER_NAME'],
style: TextStyle(color: textColor, fontSize: 13),
),
if (item['ACT_TIME'] != null)
Text(
item['ACT_TIME'],
style: TextStyle(color: textColor, fontSize: 13),
),
],
),
);
}
@ -371,8 +307,14 @@ ToastUtil.showNormal(context, '获取流程图失败');
maxLines: null, // maxLines: null, //
overflow: TextOverflow.visible,) overflow: TextOverflow.visible,)
), ),
Expanded(child: Text("消防、安全管理部门: ${item['AUDIT_USER_NAME'] ?? ''}",softWrap: true,
textAlign: TextAlign.right, ],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(child: Text("消防、安全管理部门负责人: ${item['AUDIT_USER_NAME'] ?? ''}",softWrap: true,
textAlign: TextAlign.left,
maxLines: null, // maxLines: null, //
overflow: TextOverflow.visible,) overflow: TextOverflow.visible,)
), ),
@ -528,48 +470,7 @@ ToastUtil.showNormal(context, '获取流程图失败');
child: child:
flowList.isEmpty flowList.isEmpty
? Center(child: Text('暂无流程图数据')) ? Center(child: Text('暂无流程图数据'))
: ListView.builder( : ItemListWidget.buildFlowStepItem(flowList: flowList),
padding: const EdgeInsets.symmetric(vertical: 16),
itemCount: flowList.length + 1, // +1
itemBuilder: (context, i) {
if (i == 0) {
return Padding(
padding: const EdgeInsets.symmetric(
horizontal: 16,
vertical: 8,
),
child: Text(
'查看流程图',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
);
}
final idx = i - 1;
final item = flowList[idx];
final bool isFirst = idx == 0;
final bool isLast = idx == flowList.length - 1;
// lastDoneIndex
final int status;
if (idx <= lastDoneIndex) {
status = 1; //
} else if (idx == lastDoneIndex + 1) {
status = 0; //
} else {
status = -1; //
}
return _buildFlowStepItem(
item: item,
isFirst: isFirst,
isLast: isLast,
status: status,
);
},
),
), ),
), ),

View File

@ -178,8 +178,10 @@ class _CutroadApplyDetailState extends State<CutroadApplyDetail> {
onTapClean: () { onTapClean: () {
ToastUtil.showNormal(context, '已清除'); ToastUtil.showNormal(context, '已清除');
setState(() { setState(() {
pd['${type.name}_DEPARTMENT_NAME'] = ''; set_pd_USER_ID(type, '');
pd['${type.name}_USER_NAME'] = ''; set_pd_USER_Name(type, '');
set_pd_DEPARTMENT_NAME(type, '');
set_pd_DEPARTMENT_ID(type, '');
_personCache.remove(type); _personCache.remove(type);
}); });
}, },
@ -356,8 +358,7 @@ class _CutroadApplyDetailState extends State<CutroadApplyDetail> {
pd['CREATOR'] = SessionService.instance.loginUserId; pd['CREATOR'] = SessionService.instance.loginUserId;
pd['ACTION_USER'] = SessionService.instance.username; pd['ACTION_USER'] = SessionService.instance.username;
pd['APPLY_STATUS'] = status; pd['APPLY_STATUS'] = status;
pd['SPECIAL_WORK'] = FormUtils.hasValue(pd, 'SPECIAL_WORK') ? pd['SPECIAL_WORK'] : '';
//
if (msg == 'add') { if (msg == 'add') {
pd['STEP_ID'] = status; pd['STEP_ID'] = status;
pd['TASK_ID'] = taskId; pd['TASK_ID'] = taskId;
@ -368,8 +369,7 @@ class _CutroadApplyDetailState extends State<CutroadApplyDetail> {
pd['APPLY_USER_ID'] = SessionService.instance.loginUserId; pd['APPLY_USER_ID'] = SessionService.instance.loginUserId;
pd['APPLY_USER_NAME'] = SessionService.instance.username; pd['APPLY_USER_NAME'] = SessionService.instance.username;
pd['USER_ID'] = SessionService.instance.loginUserId; pd['USER_ID'] = SessionService.instance.loginUserId;
pd['SPECIAL_WORK'] =
FormUtils.hasValue(pd, 'SPECIAL_WORK') ? pd['SPECIAL_WORK'] : '';
} }
LoadingDialogHelper.show(); LoadingDialogHelper.show();
@ -380,7 +380,7 @@ class _CutroadApplyDetailState extends State<CutroadApplyDetail> {
final result = await ApiService.submitHomework(url, pd); final result = await ApiService.submitHomework(url, pd);
LoadingDialogHelper.hide(); LoadingDialogHelper.hide();
if (result['result'] == 'success') { if (result['result'] == 'success') {
ToastUtil.showSuccess(context, status == '1' ? '提交成功' : '已暂存'); ToastUtil.showSuccess(context, status == '1' ? '提交成功' : '操作成功');
Navigator.of(context).pop(true); Navigator.of(context).pop(true);
} }
} catch (e) { } catch (e) {

View File

@ -371,6 +371,7 @@ class _CutroadYsgdDetailState extends State<CutroadYsgdDetail> {
), ),
onTap: () async { onTap: () async {
DateTime? picked = await BottomDateTimePicker.showDate( DateTime? picked = await BottomDateTimePicker.showDate(
allowPast:false,
mode: BottomPickerMode.dateTimeWithSeconds, mode: BottomPickerMode.dateTimeWithSeconds,
context, context,
); );

View File

@ -176,7 +176,7 @@ class _CutroadZyrDetailState extends State<CutroadZyrDetail> {
formData['WORK_CONTENT'] = _contentController.text.trim(); formData['WORK_CONTENT'] = _contentController.text.trim();
formData['CONIMG_PATH'] = serverPathString; formData['CONIMG_PATH'] = serverPathString;
formData['DESCR'] = FormUtils.hasValue(pd, 'DESCR') ? pd['DESCR'] : ''; formData['DESCR'] = pd['DESCR'] ?? '';
formData['CUTROAD_ID'] = widget.CUTROAD_ID; formData['CUTROAD_ID'] = widget.CUTROAD_ID;
formData['SIGNTIME'] = signTimes.join(','); formData['SIGNTIME'] = signTimes.join(',');
formData['USER_ID'] = SessionService.instance.loginUserId; formData['USER_ID'] = SessionService.instance.loginUserId;

View File

@ -117,12 +117,12 @@ class _BreakgroundDetailFormWidgetState
text: pd['CREATTIME'] ?? '', text: pd['CREATTIME'] ?? '',
), ),
], ],
if (FormUtils.hasValue(pd, 'CONFIRM_DEPARTMENT_NAME')) ...[ if (FormUtils.hasValue(pd, 'WORK_USER_DEPARTMENT_NAME')) ...[
const Divider(), const Divider(),
ItemListWidget.singleLineTitleText( ItemListWidget.singleLineTitleText(
label: '作业单位:', label: '作业单位:',
isEditable: false, isEditable: false,
text: pd['CONFIRM_DEPARTMENT_NAME'] ?? '', text: pd['WORK_USER_DEPARTMENT_NAME'] ?? '',
), ),
], ],
const Divider(), const Divider(),
@ -190,49 +190,24 @@ class _BreakgroundDetailFormWidgetState
controller: widget.relatedController, controller: widget.relatedController,
text: pd['SPECIAL_WORK'] ?? '', text: pd['SPECIAL_WORK'] ?? '',
), ),
const Divider(),
const Divider(), if (FormUtils.hasValue(pd, 'CONTENT_IMG_PATH') &&
if (FormUtils.hasValue(pd, 'WORK_CONTENT')) ...[ !widget.isEditable) ...[
ItemListWidget.singleLineTitleText( ConfirmWithSignWidget(
label: '作业内容、范围、方式:', signs: widget.signs,
isEditable: false, pd: pd,
text: pd['WORK_CONTENT'] ?? '', baseImgPath: ApiService.baseImgPath,
), sectionKey: 'WORK_USER',
const Divider(), nameKey: 'WORK_CONTENT',
], headerTitle: '作业范围、内容、方式(包括深度、面积,并附简图):',
if (FormUtils.hasValue(pd, 'CONTENT_IMG_PATH')) ...[ imgsKey: 'CONTENT_IMG_PATH',
ItemListWidget.singleLineTitleText( contentKey: 'WORK_CONTENT',
label: '作业内容、范围、方式简图:', roleTitle: '',
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(), const Divider(),
], ],
ItemListWidget.twoRowButtonTitleText( ItemListWidget.twoRowButtonTitleText(
label: '风险辨识结果', label: '风险辨识结果',
isEditable: widget.isEditable, isEditable: widget.isEditable,
@ -270,6 +245,7 @@ class _BreakgroundDetailFormWidgetState
isEditable: widget.isEditable, isEditable: widget.isEditable,
onTap: () async { onTap: () async {
DateTime? picked = await BottomDateTimePicker.showDate( DateTime? picked = await BottomDateTimePicker.showDate(
mode: BottomPickerMode.dateTimeWithSeconds,
context, context,
minTimeStr: pd['WORK_EXPECTED_START_TIME'] ?? '', minTimeStr: pd['WORK_EXPECTED_START_TIME'] ?? '',
allowFuture: true, allowFuture: true,
@ -321,6 +297,7 @@ class _BreakgroundDetailFormWidgetState
isEditable: widget.isEditable, isEditable: widget.isEditable,
onTap: () async { onTap: () async {
DateTime? picked = await BottomDateTimePicker.showDate( DateTime? picked = await BottomDateTimePicker.showDate(
mode: BottomPickerMode.dateTimeWithSeconds,
context, context,
minTimeStr: pd['WORK_EXPECTED_START_TIME'] ?? '', minTimeStr: pd['WORK_EXPECTED_START_TIME'] ?? '',
allowFuture: true, allowFuture: true,
@ -402,18 +379,7 @@ class _BreakgroundDetailFormWidgetState
text: pd['VIDEONAME'] ?? '', 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: '',
),
],
], ],
), ),
); );

View File

@ -187,10 +187,7 @@ class _BreakgroundSafeFuncSureState extends State<BreakgroundSafeFuncSure> {
/// 1 0 /// 1 0
Future<void> _submit(String status) async { Future<void> _submit(String status) async {
if (_otherController.text.trim().isEmpty) {
ToastUtil.showNormal(context, '请输入其他安全措施,没有请填“无”');
return;
}
if (imagePaths.isEmpty) { if (imagePaths.isEmpty) {
ToastUtil.showNormal(context, '请签字'); ToastUtil.showNormal(context, '请签字');
return; return;
@ -201,6 +198,10 @@ class _BreakgroundSafeFuncSureState extends State<BreakgroundSafeFuncSure> {
if (!_validateAndProceed(context)) { if (!_validateAndProceed(context)) {
return; return;
} }
if (_otherController.text.trim().isEmpty) {
ToastUtil.showNormal(context, '请输入其他安全措施,没有请填“无”');
return;
}
} else { } else {
reasonText = await CustomAlertDialog.showInput( reasonText = await CustomAlertDialog.showInput(
context, context,
@ -242,7 +243,7 @@ class _BreakgroundSafeFuncSureState extends State<BreakgroundSafeFuncSure> {
); );
LoadingDialogHelper.hide(); LoadingDialogHelper.hide();
if (result['result'] == 'success') { if (result['result'] == 'success') {
ToastUtil.showSuccess(context, status == '1' ? '提交成功' : '已暂存'); ToastUtil.showSuccess(context, status == '1' ? '提交成功' : '操作成功');
Navigator.of(context).pop(true); // true Navigator.of(context).pop(true); // true
} }
} catch (e) { } catch (e) {
@ -382,6 +383,7 @@ class _BreakgroundSafeFuncSureState extends State<BreakgroundSafeFuncSure> {
], ],
), ),
ItemListWidget.singleLineTitleText( ItemListWidget.singleLineTitleText(
isNumericInput: true,
label: '其他安全措施:', label: '其他安全措施:',
isEditable: true, isEditable: true,
hintText: '请输入其他安全措施', hintText: '请输入其他安全措施',

View File

@ -1,5 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:qhd_prevention/customWidget/toast_util.dart'; import 'package:qhd_prevention/customWidget/toast_util.dart';
import 'package:qhd_prevention/pages/home/tap/item_list_widget.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dt_work/aqcs_work_detail/breakground_safe_func_sure.dart'; import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dt_work/aqcs_work_detail/breakground_safe_func_sure.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dt_work/aqjd_work_detail/breakground_aqjd_detail.dart'; import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dt_work/aqjd_work_detail/breakground_aqjd_detail.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dt_work/dt_work_detai/breakground_apply_detail.dart'; import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dt_work/dt_work_detai/breakground_apply_detail.dart';
@ -320,72 +321,7 @@ ToastUtil.showNormal(context, '获取流程图失败');
LoadingDialogHelper.hide(); LoadingDialogHelper.hide();
} }
Widget _buildFlowStepItem({
required Map<String, dynamic> item,
required bool isFirst,
required bool isLast,
required int status, // 1 = , 0 = , -1 =
}) {
//
final Color dotColor =
status == 1 ? Colors.green : (status == 0 ? Colors.blue : Colors.grey);
final Color textColor =
status == 1 ? Colors.green : (status == 0 ? Colors.blue : Colors.black);
return ListTile(
visualDensity: VisualDensity(vertical: -4),
contentPadding: const EdgeInsets.symmetric(horizontal: 16),
leading: Container(
width: 24,
alignment: Alignment.center,
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
// 线
isFirst
? SizedBox(height: 6 + 5)
: Expanded(child: Container(width: 1, color: Colors.grey[300])),
//
CircleAvatar(radius: 6, backgroundColor: dotColor),
// 线
isLast
? SizedBox(height: 6 + 5)
: Expanded(child: Container(width: 1, color: Colors.grey[300])),
],
),
),
title: Text(
item['STEP_NAME'] ?? '',
style: TextStyle(color: textColor, fontSize: 15),
),
subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (item['SIGN_USER'] != null)
Text(
item['SIGN_USER'],
style: TextStyle(color: textColor, fontSize: 13),
),
if (item['FINISHED_SIGN_USER'] != null)
Text(
item['FINISHED_SIGN_USER'],
style: TextStyle(color: textColor, fontSize: 13),
),
if (item['ACT_USER_NAME'] != null)
Text(
item['ACT_USER_NAME'],
style: TextStyle(color: textColor, fontSize: 13),
),
if (item['ACT_TIME'] != null)
Text(
item['ACT_TIME'],
style: TextStyle(color: textColor, fontSize: 13),
),
],
),
);
}
String _getWorkLevelText(dynamic level) { String _getWorkLevelText(dynamic level) {
switch (level?.toString()) { switch (level?.toString()) {
@ -478,28 +414,25 @@ ToastUtil.showNormal(context, '获取流程图失败');
children: [ children: [
Expanded( Expanded(
child: Text( child: Text(
"有关水、电、汽、工艺、设备、消防安全等部门: ${item['SAFETY_USER_NAME'] ?? ''}", "有关部门负责人: ${item['SAFETY_USER_NAME'] ?? ''}",
softWrap: true, softWrap: true,
maxLines: null, // maxLines: null, //
overflow: TextOverflow.visible, overflow: TextOverflow.visible,
), ),
), ),
],
),
if (FormUtils.hasValue(item, 'APPROVE_USER_NAME')) if (FormUtils.hasValue(item, 'APPROVE_USER_NAME'))
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded( Expanded(
child: Text( child: Text(
"审批部门负责人: ${item['APPROVE_USER_NAME'] ?? ''}", "审批部门负责人: ${item['APPROVE_USER_NAME'] ?? ''}",
softWrap: true, softWrap: true,
textAlign: TextAlign.right,
maxLines: null, // maxLines: null, //
overflow: TextOverflow.visible, overflow: TextOverflow.visible,
), ),
), ),
], ],
), ),
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
@ -642,48 +575,7 @@ ToastUtil.showNormal(context, '获取流程图失败');
child: child:
flowList.isEmpty flowList.isEmpty
? Center(child: Text('暂无流程图数据')) ? Center(child: Text('暂无流程图数据'))
: ListView.builder( : ItemListWidget.buildFlowStepItem(flowList: flowList),
padding: const EdgeInsets.symmetric(vertical: 16),
itemCount: flowList.length + 1, // +1
itemBuilder: (context, i) {
if (i == 0) {
return Padding(
padding: const EdgeInsets.symmetric(
horizontal: 16,
vertical: 8,
),
child: Text(
'查看流程图',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
);
}
final idx = i - 1;
final item = flowList[idx];
final bool isFirst = idx == 0;
final bool isLast = idx == flowList.length - 1;
// lastDoneIndex
final int status;
if (idx <= lastDoneIndex) {
status = 1; //
} else if (idx == lastDoneIndex + 1) {
status = 0; //
} else {
status = -1; //
}
return _buildFlowStepItem(
item: item,
isFirst: isFirst,
isLast: isLast,
status: status,
);
},
),
), ),
), ),

View File

@ -320,8 +320,10 @@ class _BreakgroundApplyDetailState extends State<BreakgroundApplyDetail> {
onTapClean: () { onTapClean: () {
ToastUtil.showNormal(context, '已清除'); ToastUtil.showNormal(context, '已清除');
setState(() { setState(() {
pd['${type.name}_DEPARTMENT_NAME'] = ''; set_pd_USER_ID(type, '');
pd['${type.name}_USER_NAME'] = ''; set_pd_USER_Name(type, '');
set_pd_DEPARTMENT_NAME(type, '');
set_pd_DEPARTMENT_ID(type, '');
_personCache.remove(type); _personCache.remove(type);
}); });
}, },
@ -494,7 +496,7 @@ class _BreakgroundApplyDetailState extends State<BreakgroundApplyDetail> {
pd['CREATOR'] = SessionService.instance.loginUserId; pd['CREATOR'] = SessionService.instance.loginUserId;
pd['ACTION_USER'] = SessionService.instance.username; pd['ACTION_USER'] = SessionService.instance.username;
pd['APPLY_STATUS'] = status; pd['APPLY_STATUS'] = status;
pd['SPECIAL_WORK'] = FormUtils.hasValue(pd, 'SPECIAL_WORK') ? pd['SPECIAL_WORK'] : '';
// //
if (msg == 'add') { if (msg == 'add') {
pd['TASK_ID'] = taskId; pd['TASK_ID'] = taskId;
@ -513,7 +515,7 @@ class _BreakgroundApplyDetailState extends State<BreakgroundApplyDetail> {
final result = await ApiService.submitHomework(url, pd); final result = await ApiService.submitHomework(url, pd);
LoadingDialogHelper.hide(); LoadingDialogHelper.hide();
if (result['result'] == 'success') { if (result['result'] == 'success') {
ToastUtil.showSuccess(context, status == '1' ? '提交成功' : '已暂存'); ToastUtil.showSuccess(context, status == '1' ? '提交成功' : '操作成功');
Navigator.of(context).pop(true); Navigator.of(context).pop(true);
} }
} catch (e) { } catch (e) {

View File

@ -374,6 +374,7 @@ class _BreakgroundYsgdDetailState extends State<BreakgroundYsgdDetail> {
), ),
onTap: () async { onTap: () async {
DateTime? picked = await BottomDateTimePicker.showDate( DateTime? picked = await BottomDateTimePicker.showDate(
allowPast:false,
mode: BottomPickerMode.dateTimeWithSeconds, mode: BottomPickerMode.dateTimeWithSeconds,
context, context,
); );

View File

@ -180,7 +180,7 @@ class _BreakgroundZyrDetailState extends State<BreakgroundZyrDetail> {
.toList() .toList()
.join(','); .join(',');
formData['WORK_CONTENT'] = _contentController.text; formData['WORK_CONTENT'] = _contentController.text;
formData['DESCR'] = pd['DESCR'] ?? ''; formData['DESCR'] = pd['DESCR'] ?? '';
final confirmed = await CustomAlertDialog.showConfirm( final confirmed = await CustomAlertDialog.showConfirm(
context, context,
title: '提示', title: '提示',

View File

@ -115,12 +115,13 @@ class _HoistworkDetailFormWidgetState extends State<HoistWorkDetailFormWidget> {
isEditable: false, isEditable: false,
text: pd['APPLY_USER_NAME'] ?? '', text: pd['APPLY_USER_NAME'] ?? '',
), ),
if (FormUtils.hasValue(pd, 'CONFIRM_DEPARTMENT_NAME')) ...[
if (FormUtils.hasValue(pd, 'WORK_USER_DEPARTMENT_NAME')) ...[
const Divider(), const Divider(),
ItemListWidget.singleLineTitleText( ItemListWidget.singleLineTitleText(
label: '作业单位:', label: '作业单位:',
isEditable: false, isEditable: false,
text: pd['CONFIRM_DEPARTMENT_NAME'] ?? '', text: pd['WORK_USER_DEPARTMENT_NAME'] ?? '',
), ),
], ],
if (FormUtils.hasValue(pd, 'CREATTIME') && !widget.isEditable) ...[ if (FormUtils.hasValue(pd, 'CREATTIME') && !widget.isEditable) ...[
@ -294,6 +295,7 @@ class _HoistworkDetailFormWidgetState extends State<HoistWorkDetailFormWidget> {
isEditable: widget.isEditable, isEditable: widget.isEditable,
onTap: () async { onTap: () async {
DateTime? picked = await BottomDateTimePicker.showDate( DateTime? picked = await BottomDateTimePicker.showDate(
mode: BottomPickerMode.dateTimeWithSeconds,
context, context,
minTimeStr: pd['WORK_EXPECTED_START_TIME'] ?? '', minTimeStr: pd['WORK_EXPECTED_START_TIME'] ?? '',
allowFuture: true, allowFuture: true,
@ -345,6 +347,7 @@ class _HoistworkDetailFormWidgetState extends State<HoistWorkDetailFormWidget> {
isEditable: widget.isEditable, isEditable: widget.isEditable,
onTap: () async { onTap: () async {
DateTime? picked = await BottomDateTimePicker.showDate( DateTime? picked = await BottomDateTimePicker.showDate(
mode: BottomPickerMode.dateTimeWithSeconds,
context, context,
minTimeStr: pd['WORK_EXPECTED_START_TIME'] ?? '', minTimeStr: pd['WORK_EXPECTED_START_TIME'] ?? '',
allowFuture: true, allowFuture: true,

View File

@ -186,10 +186,7 @@ class _HoistworkSafeFuncSureState extends State<HoistworkSafeFuncSure> {
/// 1 0 /// 1 0
Future<void> _submit(String status) async { Future<void> _submit(String status) async {
if (_otherController.text.trim().isEmpty) {
ToastUtil.showNormal(context, '请输入其他安全措施,没有请填“无”');
return;
}
if (imagePaths.isEmpty) { if (imagePaths.isEmpty) {
ToastUtil.showNormal(context, '请签字'); ToastUtil.showNormal(context, '请签字');
return; return;
@ -200,6 +197,10 @@ class _HoistworkSafeFuncSureState extends State<HoistworkSafeFuncSure> {
if (!_validateAndProceed(context)) { if (!_validateAndProceed(context)) {
return; return;
} }
if (_otherController.text.trim().isEmpty) {
ToastUtil.showNormal(context, '请输入其他安全措施,没有请填“无”');
return;
}
} else { } else {
reasonText = await CustomAlertDialog.showInput( reasonText = await CustomAlertDialog.showInput(
context, context,
@ -241,7 +242,7 @@ class _HoistworkSafeFuncSureState extends State<HoistworkSafeFuncSure> {
); );
LoadingDialogHelper.hide(); LoadingDialogHelper.hide();
if (result['result'] == 'success') { if (result['result'] == 'success') {
ToastUtil.showSuccess(context, status == '1' ? '提交成功' : '已暂存'); ToastUtil.showSuccess(context, status == '1' ? '提交成功' : '操作成功');
Navigator.of(context).pop(true); // true Navigator.of(context).pop(true); // true
} }
} catch (e) { } catch (e) {
@ -381,6 +382,7 @@ class _HoistworkSafeFuncSureState extends State<HoistworkSafeFuncSure> {
], ],
), ),
ItemListWidget.singleLineTitleText( ItemListWidget.singleLineTitleText(
isNumericInput: true,
label: '其他安全措施:', label: '其他安全措施:',
isEditable: true, isEditable: true,
hintText: '请输入其他安全措施', hintText: '请输入其他安全措施',

View File

@ -320,8 +320,10 @@ class _HoistworkApplyDetailState extends State<HoistworkApplyDetail> {
onTapClean: () { onTapClean: () {
ToastUtil.showNormal(context, '已清除'); ToastUtil.showNormal(context, '已清除');
setState(() { setState(() {
pd['${type.name}_DEPARTMENT_NAME'] = ''; set_pd_USER_ID(type, '');
pd['${type.name}_USER_NAME'] = ''; set_pd_USER_Name(type, '');
set_pd_DEPARTMENT_NAME(type, '');
set_pd_DEPARTMENT_ID(type, '');
_personCache.remove(type); _personCache.remove(type);
}); });
}, },
@ -505,7 +507,7 @@ class _HoistworkApplyDetailState extends State<HoistworkApplyDetail> {
pd['CREATOR'] = SessionService.instance.loginUserId; pd['CREATOR'] = SessionService.instance.loginUserId;
pd['ACTION_USER'] = SessionService.instance.username; pd['ACTION_USER'] = SessionService.instance.username;
pd['APPLY_STATUS'] = status; pd['APPLY_STATUS'] = status;
pd['SPECIAL_WORK'] = FormUtils.hasValue(pd, 'SPECIAL_WORK') ? pd['SPECIAL_WORK'] : '';
// //
if (msg == 'add') { if (msg == 'add') {
pd['STEP_ID'] = status; pd['STEP_ID'] = status;
@ -526,7 +528,7 @@ class _HoistworkApplyDetailState extends State<HoistworkApplyDetail> {
final result = await ApiService.submitHomework(url, pd); final result = await ApiService.submitHomework(url, pd);
LoadingDialogHelper.hide(); LoadingDialogHelper.hide();
if (result['result'] == 'success') { if (result['result'] == 'success') {
ToastUtil.showSuccess(context, status == '1' ? '提交成功' : '已暂存'); ToastUtil.showSuccess(context, status == '1' ? '提交成功' : '操作成功');
Navigator.of(context).pop(true); Navigator.of(context).pop(true);
} }
} catch (e) { } catch (e) {

View File

@ -1,5 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:qhd_prevention/customWidget/toast_util.dart'; import 'package:qhd_prevention/customWidget/toast_util.dart';
import 'package:qhd_prevention/pages/home/tap/item_list_widget.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dz_work/aqcs_work_detail/hoistwork_safe_func_sure.dart'; import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dz_work/aqcs_work_detail/hoistwork_safe_func_sure.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dz_work/aqjd_work_detail/hoistwork_aqjd_detail.dart'; import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dz_work/aqjd_work_detail/hoistwork_aqjd_detail.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dz_work/dz_work_detai/hoistwork_apply_detail.dart'; import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dz_work/dz_work_detai/hoistwork_apply_detail.dart';
@ -24,7 +25,6 @@ import 'package:qhd_prevention/customWidget/custom_button.dart';
import 'package:qhd_prevention/customWidget/search_bar_widget.dart'; import 'package:qhd_prevention/customWidget/search_bar_widget.dart';
import 'package:qhd_prevention/http/ApiService.dart'; import 'package:qhd_prevention/http/ApiService.dart';
class HoistworkListPage extends StatefulWidget { class HoistworkListPage extends StatefulWidget {
final String flow; final String flow;
final String workTypeTitle; final String workTypeTitle;
@ -88,7 +88,6 @@ class _HoistworkListPageState extends State<HoistworkListPage> {
stepList = [ stepList = [
{'STEP_NAME': '全部', 'STEP_ID': ''}, {'STEP_NAME': '全部', 'STEP_ID': ''},
...response['list'] ?? [], ...response['list'] ?? [],
]; ];
}); });
} catch (e) { } catch (e) {
@ -141,7 +140,10 @@ class _HoistworkListPageState extends State<HoistworkListPage> {
/// ///
void _handleApply() async { void _handleApply() async {
// //
await pushPage(HoistworkApplyDetail(HOISTING_ID: '', flow: widget.flow), context); await pushPage(
HoistworkApplyDetail(HOISTING_ID: '', flow: widget.flow),
context,
);
_fetchData(); _fetchData();
LoadingDialogHelper.hide(); LoadingDialogHelper.hide();
} }
@ -178,132 +180,154 @@ ToastUtil.showNormal(context, '获取流程图失败');
if (!allowed) return; if (!allowed) return;
switch (widget.flow) { switch (widget.flow) {
case '提交申请': case '提交申请':
await pushPage(HoistworkApplyDetail(HOISTING_ID: item['HOISTING_ID'], flow: widget.flow), context); await pushPage(
HoistworkApplyDetail(
HOISTING_ID: item['HOISTING_ID'],
flow: widget.flow,
),
context,
);
break; break;
case '司索人签字': case '司索人签字':
await pushPage(HoistworkSsrDetail(HOISTING_ID: item['HOISTING_ID'], flow: widget.flow), context); await pushPage(
HoistworkSsrDetail(
HOISTING_ID: item['HOISTING_ID'],
flow: widget.flow,
),
context,
);
break; break;
case '设置安全措施确认人': case '设置安全措施确认人':
await pushPage(HoistworkSetSafeDetail(HOISTING_ID: item['HOISTING_ID'], flow: widget.flow), context); await pushPage(
HoistworkSetSafeDetail(
HOISTING_ID: item['HOISTING_ID'],
flow: widget.flow,
),
context,
);
break; break;
case '安全措施确认': case '安全措施确认':
await pushPage(HoistworkSafeFuncSure(HOISTING_ID: item['HOISTING_ID'], flow: widget.flow), context); await pushPage(
HoistworkSafeFuncSure(
HOISTING_ID: item['HOISTING_ID'],
flow: widget.flow,
),
context,
);
break; break;
case '监护人签字': case '监护人签字':
await pushPage(HoistworkJhrDetail(HOISTING_ID: item['HOISTING_ID'], flow: widget.flow), context); await pushPage(
HoistworkJhrDetail(
HOISTING_ID: item['HOISTING_ID'],
flow: widget.flow,
),
context,
);
break; break;
case '安全交底人签字': case '安全交底人签字':
await pushPage(HoistworkAqjdDetail(HOISTING_ID: item['HOISTING_ID'], flow: widget.flow), context); await pushPage(
HoistworkAqjdDetail(
HOISTING_ID: item['HOISTING_ID'],
flow: widget.flow,
),
context,
);
break; break;
case '接受交底人签字': case '接受交底人签字':
await pushPage(HoistworkJsjdDetail(HOISTING_ID: item['HOISTING_ID'], flow: widget.flow), context); await pushPage(
HoistworkJsjdDetail(
HOISTING_ID: item['HOISTING_ID'],
flow: widget.flow,
),
context,
);
break; break;
case '作业人签字': case '作业人签字':
await pushPage(HoistworkZyrDetail(HOISTING_ID: item['HOISTING_ID'], flow: widget.flow), context); await pushPage(
HoistworkZyrDetail(
HOISTING_ID: item['HOISTING_ID'],
flow: widget.flow,
),
context,
);
break; break;
// case '作业负责人签字': // case '作业负责人签字':
// await pushPage(HoistworkZyfzDetail(HOISTING_ID: item['HOISTING_ID'], flow: widget.flow), context); // await pushPage(HoistworkZyfzDetail(HOISTING_ID: item['HOISTING_ID'], flow: widget.flow), context);
// break; // break;
case '吊装指挥人签字': case '吊装指挥人签字':
await pushPage(HoistworkDzzhDetail(HOISTING_ID: item['HOISTING_ID'], flow: widget.flow), context); await pushPage(
HoistworkDzzhDetail(
HOISTING_ID: item['HOISTING_ID'],
flow: widget.flow,
),
context,
);
break; break;
case '所在单位签字': case '所在单位签字':
await pushPage(HoistworkSzdwDetail(HOISTING_ID: item['HOISTING_ID'], flow: widget.flow), context); await pushPage(
HoistworkSzdwDetail(
HOISTING_ID: item['HOISTING_ID'],
flow: widget.flow,
),
context,
);
break; break;
case '审核人签字': case '审核人签字':
await pushPage(HoistworkShbmDetail(HOISTING_ID: item['HOISTING_ID'], flow: widget.flow), context); await pushPage(
HoistworkShbmDetail(
HOISTING_ID: item['HOISTING_ID'],
flow: widget.flow,
),
context,
);
break; break;
case '审批人签字': case '审批人签字':
await pushPage(HoistworkSpbmDetail(HOISTING_ID: item['HOISTING_ID'], flow: widget.flow), context); await pushPage(
HoistworkSpbmDetail(
HOISTING_ID: item['HOISTING_ID'],
flow: widget.flow,
),
context,
);
break; break;
case '开始作业': case '开始作业':
await pushPage(HoistworkKszyDetail(HOISTING_ID: item['HOISTING_ID'], flow: widget.flow), context); await pushPage(
HoistworkKszyDetail(
HOISTING_ID: item['HOISTING_ID'],
flow: widget.flow,
),
context,
);
break; break;
case '结束作业': case '结束作业':
await pushPage(HoistworkJszyDetail(HOISTING_ID: item['HOISTING_ID'], flow: widget.flow), context); await pushPage(
HoistworkJszyDetail(
HOISTING_ID: item['HOISTING_ID'],
flow: widget.flow,
),
context,
);
break; break;
case '验收签字': case '验收签字':
await pushPage(HoistworkYsgdDetail(HOISTING_ID: item['HOISTING_ID'], flow: widget.flow), context); await pushPage(
HoistworkYsgdDetail(
HOISTING_ID: item['HOISTING_ID'],
flow: widget.flow,
),
context,
);
break; break;
default: default:
break; break;
} }
await _fetchData(); await _fetchData();
LoadingDialogHelper.hide(); LoadingDialogHelper.hide();
} }
Widget _buildFlowStepItem({
required Map<String, dynamic> item,
required bool isFirst,
required bool isLast,
required int status, // 1 = , 0 = , -1 =
}) {
//
final Color dotColor =
status == 1 ? Colors.green : (status == 0 ? Colors.blue : Colors.grey);
final Color textColor =
status == 1 ? Colors.green : (status == 0 ? Colors.blue : Colors.black);
return ListTile(
visualDensity: VisualDensity(vertical: -4),
contentPadding: const EdgeInsets.symmetric(horizontal: 16),
leading: Container(
width: 24,
alignment: Alignment.center,
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
// 线
isFirst
? SizedBox(height: 6 + 5)
: Expanded(child: Container(width: 1, color: Colors.grey[300])),
//
CircleAvatar(radius: 6, backgroundColor: dotColor),
// 线
isLast
? SizedBox(height: 6 + 5)
: Expanded(child: Container(width: 1, color: Colors.grey[300])),
],
),
),
title: Text(
item['STEP_NAME'] ?? '',
style: TextStyle(color: textColor, fontSize: 15),
),
subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (item['SIGN_USER'] != null)
Text(
item['SIGN_USER'],
style: TextStyle(color: textColor, fontSize: 13),
),
if (item['FINISHED_SIGN_USER'] != null)
Text(
item['FINISHED_SIGN_USER'],
style: TextStyle(color: textColor, fontSize: 13),
),
if (item['ACT_USER_NAME'] != null)
Text(
item['ACT_USER_NAME'],
style: TextStyle(color: textColor, fontSize: 13),
),
if (item['ACT_TIME'] != null)
Text(
item['ACT_TIME'],
style: TextStyle(color: textColor, fontSize: 13),
),
],
),
);
}
String _getWorkLevelText(dynamic level) { String _getWorkLevelText(dynamic level) {
switch (level?.toString()) { switch (level?.toString()) {
case '1': case '1':
@ -346,52 +370,103 @@ ToastUtil.showNormal(context, '获取流程图失败');
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Text("申请人: ${item['APPLY_USER_NAME'] ?? ''}"), Text("申请人: ${item['APPLY_USER_NAME'] ?? ''}"),
Text("司索人: ${item['SISUO_USER_NAME'] ?? ''}"),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text("监护人: ${item['GUARDIAN_USER_NAME'] ?? ''}"), Text("监护人: ${item['GUARDIAN_USER_NAME'] ?? ''}"),
Expanded(
child: Text(
"安全交底人: ${item['CONFESS_USER_NAME'] ?? ''}",
softWrap: true,
textAlign: TextAlign.right,
maxLines: null, //
overflow: TextOverflow.visible,
),
),
], ],
), ),
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Expanded(child: Text("安全交底人: ${item['CONFESS_USER_NAME'] ?? ''}",softWrap: true, Expanded(
child: Text(
"接受交底人: ${item['ACCEPT_CONFESS_USER_NAME'] ?? ''}",
softWrap: true,
textAlign: TextAlign.left,
maxLines: null, // maxLines: null, //
overflow: TextOverflow.visible,) overflow: TextOverflow.visible,
), ),
Expanded(child: Text("接受交底人: ${item['ACCEPT_CONFESS_USER_NAME'] ?? ''}",softWrap: true, ),
Expanded(
child: Text(
"作业人: ${item['WORK_USER_USER_NAME'] ?? ''}",
softWrap: true,
textAlign: TextAlign.right, textAlign: TextAlign.right,
maxLines: null, // maxLines: null, //
overflow: TextOverflow.visible,) overflow: TextOverflow.visible,
),
), ),
], ],
), ),
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Expanded(child: Text("所在单位负责人: ${item['LEADER_USER_NAME'] ?? ''}",softWrap: true, Expanded(
child: Text(
"作业指挥负责人: ${item['PROJECT_MANAGER_USER_NAME'] ?? ''}",
softWrap: true,
textAlign: TextAlign.left,
maxLines: null, //
overflow: TextOverflow.visible,
),
),
Expanded(
child: Text(
"所在单位负责人: ${item['LEADER_USER_NAME'] ?? ''}",
softWrap: true,
textAlign: TextAlign.right, textAlign: TextAlign.right,
maxLines: null, // maxLines: null, //
overflow: TextOverflow.visible,) overflow: TextOverflow.visible,
),
), ),
], ],
), ),
if (FormUtils.hasValue(item, 'AUDIT_USER_NAME'))
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Expanded(child: Text("审核部门负责人: ${item['AUDIT_USER_NAME'] ?? ''}",softWrap: true, Expanded(
child: Text(
"审核部门负责人: ${item['AUDIT_USER_NAME'] ?? ''}",
softWrap: true,
maxLines: null, // maxLines: null, //
overflow: TextOverflow.visible,) overflow: TextOverflow.visible,
), ),
Expanded(child: Text("审批部门负责人: ${item['APPROVE_USER_NAME'] ?? ''}",softWrap: true, ),
if (FormUtils.hasValue(item, 'APPROVE_USER_NAME'))
Expanded(
child: Text(
"审批部门负责人: ${item['APPROVE_USER_NAME'] ?? ''}",
softWrap: true,
textAlign: TextAlign.right, textAlign: TextAlign.right,
maxLines: null, // maxLines: null, //
overflow: TextOverflow.visible,) overflow: TextOverflow.visible,
),
), ),
], ],
), ),
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Text("验收部门负责人: ${item['ACCEPT_USER_NAME'] ?? ''}"), Text("验收部门负责人: ${item['ACCEPT_USER_NAME'] ?? ''}"),
SizedBox() SizedBox(),
], ],
), ),
Row( Row(
@ -528,48 +603,7 @@ ToastUtil.showNormal(context, '获取流程图失败');
child: child:
flowList.isEmpty flowList.isEmpty
? Center(child: Text('暂无流程图数据')) ? Center(child: Text('暂无流程图数据'))
: ListView.builder( : ItemListWidget.buildFlowStepItem(flowList: flowList),
padding: const EdgeInsets.symmetric(vertical: 16),
itemCount: flowList.length + 1, // +1
itemBuilder: (context, i) {
if (i == 0) {
return Padding(
padding: const EdgeInsets.symmetric(
horizontal: 16,
vertical: 8,
),
child: Text(
'查看流程图',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
);
}
final idx = i - 1;
final item = flowList[idx];
final bool isFirst = idx == 0;
final bool isLast = idx == flowList.length - 1;
// lastDoneIndex
final int status;
if (idx <= lastDoneIndex) {
status = 1; //
} else if (idx == lastDoneIndex + 1) {
status = 0; //
} else {
status = -1; //
}
return _buildFlowStepItem(
item: item,
isFirst: isFirst,
isLast: isLast,
status: status,
);
},
),
), ),
), ),

View File

@ -374,6 +374,7 @@ class _HoistworkYsgdDetailState extends State<HoistworkYsgdDetail> {
), ),
onTap: () async { onTap: () async {
DateTime? picked = await BottomDateTimePicker.showDate( DateTime? picked = await BottomDateTimePicker.showDate(
allowPast:false,
mode: BottomPickerMode.dateTimeWithSeconds, mode: BottomPickerMode.dateTimeWithSeconds,
context, context,
); );

View File

@ -174,12 +174,12 @@ class _HighWorkDetailFormWidgetState extends State<HighWorkDetailFormWidget> {
}, },
text: _getWorkLevelText(pd['WORK_LEVEL']), text: _getWorkLevelText(pd['WORK_LEVEL']),
), ),
if (FormUtils.hasValue(pd, 'CONFIRM_DEPARTMENT_NAME')) ...[ if (FormUtils.hasValue(pd, 'WORK_USER_DEPARTMENT_NAME')) ...[
const Divider(), const Divider(),
ItemListWidget.singleLineTitleText( ItemListWidget.singleLineTitleText(
label: '作业单位:', label: '作业单位:',
isEditable: false, isEditable: false,
text: pd['CONFIRM_DEPARTMENT_NAME'] ?? '', text: pd['WORK_USER_DEPARTMENT_NAME'] ?? '',
), ),
], ],
if (FormUtils.hasValue(pd, 'WORK_USER_USER_NAME') && if (FormUtils.hasValue(pd, 'WORK_USER_USER_NAME') &&
@ -277,6 +277,7 @@ class _HighWorkDetailFormWidgetState extends State<HighWorkDetailFormWidget> {
isEditable: widget.isEditable, isEditable: widget.isEditable,
onTap: () async { onTap: () async {
DateTime? picked = await BottomDateTimePicker.showDate( DateTime? picked = await BottomDateTimePicker.showDate(
mode: BottomPickerMode.dateTimeWithSeconds,
context, context,
minTimeStr: pd['WORK_EXPECTED_START_TIME'] ?? '', minTimeStr: pd['WORK_EXPECTED_START_TIME'] ?? '',
allowFuture: true, allowFuture: true,
@ -328,6 +329,7 @@ class _HighWorkDetailFormWidgetState extends State<HighWorkDetailFormWidget> {
isEditable: widget.isEditable, isEditable: widget.isEditable,
onTap: () async { onTap: () async {
DateTime? picked = await BottomDateTimePicker.showDate( DateTime? picked = await BottomDateTimePicker.showDate(
mode: BottomPickerMode.dateTimeWithSeconds,
context, context,
minTimeStr: pd['WORK_EXPECTED_START_TIME'] ?? '', minTimeStr: pd['WORK_EXPECTED_START_TIME'] ?? '',
allowFuture: true, allowFuture: true,

View File

@ -185,10 +185,7 @@ class _HighworkSafeFuncSureState extends State<HighworkSafeFuncSure> {
/// 1 0 /// 1 0
Future<void> _submit(String status) async { Future<void> _submit(String status) async {
if (_otherController.text.trim().isEmpty) {
ToastUtil.showNormal(context, '请输入其他安全措施,没有请填“无”');
return;
}
if (imagePaths.isEmpty) { if (imagePaths.isEmpty) {
ToastUtil.showNormal(context, '请签字'); ToastUtil.showNormal(context, '请签字');
return; return;
@ -199,6 +196,10 @@ class _HighworkSafeFuncSureState extends State<HighworkSafeFuncSure> {
if (!_validateAndProceed(context)) { if (!_validateAndProceed(context)) {
return; return;
} }
if (_otherController.text.trim().isEmpty) {
ToastUtil.showNormal(context, '请输入其他安全措施,没有请填“无”');
return;
}
} else { } else {
reasonText = await CustomAlertDialog.showInput( reasonText = await CustomAlertDialog.showInput(
context, context,
@ -240,7 +241,7 @@ class _HighworkSafeFuncSureState extends State<HighworkSafeFuncSure> {
); );
LoadingDialogHelper.hide(); LoadingDialogHelper.hide();
if (result['result'] == 'success') { if (result['result'] == 'success') {
ToastUtil.showSuccess(context, status == '1' ? '提交成功' : '已暂存'); ToastUtil.showSuccess(context, status == '1' ? '提交成功' : '操作成功');
Navigator.of(context).pop(true); // true Navigator.of(context).pop(true); // true
} }
} catch (e) { } catch (e) {
@ -369,6 +370,7 @@ class _HighworkSafeFuncSureState extends State<HighworkSafeFuncSure> {
], ],
), ),
ItemListWidget.singleLineTitleText( ItemListWidget.singleLineTitleText(
isNumericInput: true,
label: '其他安全措施:', label: '其他安全措施:',
isEditable: true, isEditable: true,
hintText: '请输入其他安全措施', hintText: '请输入其他安全措施',

View File

@ -336,8 +336,10 @@ class _HighworkApplyDetailState extends State<HighworkApplyDetail> {
onTapClean: () { onTapClean: () {
ToastUtil.showNormal(context, '已清除'); ToastUtil.showNormal(context, '已清除');
setState(() { setState(() {
pd['${type.name}_DEPARTMENT_NAME'] = ''; set_pd_USER_ID(type, '');
pd['${type.name}_USER_NAME'] = ''; set_pd_USER_Name(type, '');
set_pd_DEPARTMENT_NAME(type, '');
set_pd_DEPARTMENT_ID(type, '');
_personCache.remove(type); _personCache.remove(type);
}); });
}, },
@ -525,7 +527,7 @@ class _HighworkApplyDetailState extends State<HighworkApplyDetail> {
pd['CREATOR'] = SessionService.instance.loginUserId; pd['CREATOR'] = SessionService.instance.loginUserId;
pd['ACTION_USER'] = SessionService.instance.username; pd['ACTION_USER'] = SessionService.instance.username;
pd['APPLY_STATUS'] = status; pd['APPLY_STATUS'] = status;
pd['SPECIAL_WORK'] = FormUtils.hasValue(pd, 'SPECIAL_WORK') ? pd['SPECIAL_WORK'] : '';
// //
if (msg == 'add') { if (msg == 'add') {
pd['STEP_ID'] = status; pd['STEP_ID'] = status;
@ -547,7 +549,7 @@ class _HighworkApplyDetailState extends State<HighworkApplyDetail> {
final result = await ApiService.submitHomework(url, pd); final result = await ApiService.submitHomework(url, pd);
LoadingDialogHelper.hide(); LoadingDialogHelper.hide();
if (result['result'] == 'success') { if (result['result'] == 'success') {
ToastUtil.showSuccess(context, status == '1' ? '提交成功' : '已暂存'); ToastUtil.showSuccess(context, status == '1' ? '提交成功' : '操作成功');
Navigator.of(context).pop(true); Navigator.of(context).pop(true);
}else{ }else{
ToastUtil.showError(context, result['msg'] ?? '提交失败'); ToastUtil.showError(context, result['msg'] ?? '提交失败');

View File

@ -1,5 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:qhd_prevention/customWidget/toast_util.dart'; import 'package:qhd_prevention/customWidget/toast_util.dart';
import 'package:qhd_prevention/pages/home/tap/item_list_widget.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/gc_work/gc_work_detai/highwork_apply_detail.dart'; import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/gc_work/gc_work_detai/highwork_apply_detail.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/gc_work/aqcs_work_detail/highwork_safe_func_sure.dart'; import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/gc_work/aqcs_work_detail/highwork_safe_func_sure.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/gc_work/aqjd_work_detail/highwork_aqjd_detail.dart'; import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/gc_work/aqjd_work_detail/highwork_aqjd_detail.dart';
@ -233,72 +234,7 @@ class _HighworkListPageState extends State<HighworkListPage> {
LoadingDialogHelper.hide(); LoadingDialogHelper.hide();
} }
Widget _buildFlowStepItem({
required Map<String, dynamic> item,
required bool isFirst,
required bool isLast,
required int status, // 1 = , 0 = , -1 =
}) {
//
final Color dotColor =
status == 1 ? Colors.green : (status == 0 ? Colors.blue : Colors.grey);
final Color textColor =
status == 1 ? Colors.green : (status == 0 ? Colors.blue : Colors.black);
return ListTile(
visualDensity: VisualDensity(vertical: -4),
contentPadding: const EdgeInsets.symmetric(horizontal: 16),
leading: Container(
width: 24,
alignment: Alignment.center,
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
// 线
isFirst
? SizedBox(height: 6 + 5)
: Expanded(child: Container(width: 1, color: Colors.grey[300])),
//
CircleAvatar(radius: 6, backgroundColor: dotColor),
// 线
isLast
? SizedBox(height: 6 + 5)
: Expanded(child: Container(width: 1, color: Colors.grey[300])),
],
),
),
title: Text(
item['STEP_NAME'] ?? '',
style: TextStyle(color: textColor, fontSize: 15),
),
subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (item['SIGN_USER'] != null)
Text(
item['SIGN_USER'],
style: TextStyle(color: textColor, fontSize: 13),
),
if (item['FINISHED_SIGN_USER'] != null)
Text(
item['FINISHED_SIGN_USER'],
style: TextStyle(color: textColor, fontSize: 13),
),
if (item['ACT_USER_NAME'] != null)
Text(
item['ACT_USER_NAME'],
style: TextStyle(color: textColor, fontSize: 13),
),
if (item['ACT_TIME'] != null)
Text(
item['ACT_TIME'],
style: TextStyle(color: textColor, fontSize: 13),
),
],
),
);
}
String _getWorkLevelText(dynamic level) { String _getWorkLevelText(dynamic level) {
switch (level?.toString()) { switch (level?.toString()) {
@ -362,31 +298,64 @@ class _HighworkListPageState extends State<HighworkListPage> {
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Expanded(child: Text("作业负责人: ${item['CONFIRM_USER_NAME'] ?? ''}",softWrap: true, Expanded(child: Text("作业人: ${item['WORK_USER_USER_NAME'] ?? ''}",softWrap: true,
maxLines: null, // maxLines: null, //
overflow: TextOverflow.visible,) overflow: TextOverflow.visible,)
), ),
Expanded(child: Text("所在单位负责人: ${item['LEADER_USER_NAME'] ?? ''}",softWrap: true, Expanded(child: Text("作业负责人: ${item['CONFIRM_USER_NAME'] ?? ''}",softWrap: true,
maxLines: null, // maxLines: null, //
textAlign: TextAlign.right, textAlign: TextAlign.right,
overflow: TextOverflow.visible,) overflow: TextOverflow.visible,)
), ),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Text(
"所在单位负责人: ${item['LEADER_USER_NAME'] ?? ''}",
softWrap: true,
textAlign: TextAlign.left,
maxLines: null, //
overflow: TextOverflow.visible,
),
),
],
),
if (FormUtils.hasValue(item, 'AUDIT_USER_NAME'))
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Text(
"审核部门负责人: ${item['AUDIT_USER_NAME'] ?? ''}",
softWrap: true,
textAlign: TextAlign.left,
maxLines: null, //
overflow: TextOverflow.visible,
),
),
if (FormUtils.hasValue(item, 'APPROVE_USER_NAME'))
Expanded(
child: Text(
"审批部门负责人: ${item['APPROVE_USER_NAME'] ?? ''}",
softWrap: true,
textAlign: TextAlign.right,
maxLines: null, //
overflow: TextOverflow.visible,
),
),
], ],
), ),
if (item['AUDIT_USER_NAME'] != null)
Text("安全管理部门负责人: ${item['AUDIT_USER_NAME'] ?? ''}"),
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
if (item['APPROVE_USER_NAME'] != null)
Expanded(child: Text("审批部门负责人: ${item['APPROVE_USER_NAME'] ?? ''}",softWrap: true,
maxLines: null, //
overflow: TextOverflow.visible,)
),
Expanded(child: Text("验收部门负责人: ${item['ACCEPT_USER_NAME'] ?? ''}",softWrap: true, Expanded(child: Text("验收部门负责人: ${item['ACCEPT_USER_NAME'] ?? ''}",softWrap: true,
maxLines: null, // maxLines: null, //
textAlign: TextAlign.right, textAlign: TextAlign.left,
overflow: TextOverflow.visible,) overflow: TextOverflow.visible,)
), ),
], ],
@ -525,48 +494,7 @@ class _HighworkListPageState extends State<HighworkListPage> {
child: child:
flowList.isEmpty flowList.isEmpty
? Center(child: Text('暂无流程图数据')) ? Center(child: Text('暂无流程图数据'))
: ListView.builder( : ItemListWidget.buildFlowStepItem(flowList: flowList),
padding: const EdgeInsets.symmetric(vertical: 16),
itemCount: flowList.length + 1, // +1
itemBuilder: (context, i) {
if (i == 0) {
return Padding(
padding: const EdgeInsets.symmetric(
horizontal: 16,
vertical: 8,
),
child: Text(
'查看流程图',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
);
}
final idx = i - 1;
final item = flowList[idx];
final bool isFirst = idx == 0;
final bool isLast = idx == flowList.length - 1;
// lastDoneIndex
final int status;
if (idx <= lastDoneIndex) {
status = 1; //
} else if (idx == lastDoneIndex + 1) {
status = 0; //
} else {
status = -1; //
}
return _buildFlowStepItem(
item: item,
isFirst: isFirst,
isLast: isLast,
status: status,
);
},
),
), ),
), ),

View File

@ -374,6 +374,7 @@ class _HighworkYsgdDetailState extends State<HighworkYsgdDetail> {
), ),
onTap: () async { onTap: () async {
DateTime? picked = await BottomDateTimePicker.showDate( DateTime? picked = await BottomDateTimePicker.showDate(
allowPast:false,
mode: BottomPickerMode.dateTimeWithSeconds, mode: BottomPickerMode.dateTimeWithSeconds,
context, context,
); );

View File

@ -278,6 +278,7 @@ class _ElectricityDetailFormWidgetState extends State<ElectricityDetailFormWidge
isEditable: widget.isEditable, isEditable: widget.isEditable,
onTap: () async { onTap: () async {
DateTime? picked = await BottomDateTimePicker.showDate( DateTime? picked = await BottomDateTimePicker.showDate(
mode: BottomPickerMode.dateTimeWithSeconds,
context, context,
minTimeStr: pd['WORK_EXPECTED_START_TIME'] ?? '', minTimeStr: pd['WORK_EXPECTED_START_TIME'] ?? '',
allowFuture: true, allowFuture: true,
@ -329,6 +330,7 @@ class _ElectricityDetailFormWidgetState extends State<ElectricityDetailFormWidge
isEditable: widget.isEditable, isEditable: widget.isEditable,
onTap: () async { onTap: () async {
DateTime? picked = await BottomDateTimePicker.showDate( DateTime? picked = await BottomDateTimePicker.showDate(
mode: BottomPickerMode.dateTimeWithSeconds,
context, context,
minTimeStr: pd['WORK_EXPECTED_START_TIME'] ?? '', minTimeStr: pd['WORK_EXPECTED_START_TIME'] ?? '',
allowFuture: true, allowFuture: true,

View File

@ -188,10 +188,7 @@ class _ElectricitySafeFuncSureState extends State<ElectricitySafeFuncSure> {
/// 1 0 /// 1 0
Future<void> _submit(String status) async { Future<void> _submit(String status) async {
if (_otherController.text.trim().isEmpty) {
ToastUtil.showNormal(context, '请输入其他安全措施,没有请填“无”');
return;
}
if (imagePaths.isEmpty) { if (imagePaths.isEmpty) {
ToastUtil.showNormal(context, '请签字'); ToastUtil.showNormal(context, '请签字');
return; return;
@ -202,6 +199,10 @@ class _ElectricitySafeFuncSureState extends State<ElectricitySafeFuncSure> {
if (!_validateAndProceed(context)) { if (!_validateAndProceed(context)) {
return; return;
} }
if (_otherController.text.trim().isEmpty) {
ToastUtil.showNormal(context, '请输入其他安全措施,没有请填“无”');
return;
}
} else { } else {
reasonText = await CustomAlertDialog.showInput( reasonText = await CustomAlertDialog.showInput(
context, context,
@ -243,7 +244,7 @@ class _ElectricitySafeFuncSureState extends State<ElectricitySafeFuncSure> {
); );
LoadingDialogHelper.hide(); LoadingDialogHelper.hide();
if (result['result'] == 'success') { if (result['result'] == 'success') {
ToastUtil.showSuccess(context, status == '1' ? '提交成功' : '已暂存'); ToastUtil.showSuccess(context, status == '1' ? '提交成功' : '操作成功');
Navigator.of(context).pop(true); // true Navigator.of(context).pop(true); // true
} }
} catch (e) { } catch (e) {
@ -371,6 +372,7 @@ class _ElectricitySafeFuncSureState extends State<ElectricitySafeFuncSure> {
], ],
), ),
ItemListWidget.singleLineTitleText( ItemListWidget.singleLineTitleText(
isNumericInput: true,
label: '其他安全措施:', label: '其他安全措施:',
isEditable: true, isEditable: true,
hintText: '请输入其他安全措施', hintText: '请输入其他安全措施',

View File

@ -1,5 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:qhd_prevention/customWidget/toast_util.dart'; import 'package:qhd_prevention/customWidget/toast_util.dart';
import 'package:qhd_prevention/pages/home/tap/item_list_widget.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/lsyd_work/lsyd_work_detai/electricity_apply_detail.dart'; import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/lsyd_work/lsyd_work_detai/electricity_apply_detail.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/lsyd_work/aqcs_work_detail/electricity_safe_func_sure.dart'; import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/lsyd_work/aqcs_work_detail/electricity_safe_func_sure.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/lsyd_work/aqjd_work_detail/electricity_aqjd_detail.dart'; import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/lsyd_work/aqjd_work_detail/electricity_aqjd_detail.dart';
@ -323,72 +324,7 @@ ToastUtil.showNormal(context, '获取流程图失败');
LoadingDialogHelper.hide(); LoadingDialogHelper.hide();
} }
Widget _buildFlowStepItem({
required Map<String, dynamic> item,
required bool isFirst,
required bool isLast,
required int status, // 1 = , 0 = , -1 =
}) {
//
final Color dotColor =
status == 1 ? Colors.green : (status == 0 ? Colors.blue : Colors.grey);
final Color textColor =
status == 1 ? Colors.green : (status == 0 ? Colors.blue : Colors.black);
return ListTile(
visualDensity: VisualDensity(vertical: -4),
contentPadding: const EdgeInsets.symmetric(horizontal: 16),
leading: Container(
width: 24,
alignment: Alignment.center,
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
// 线
isFirst
? SizedBox(height: 6 + 5)
: Expanded(child: Container(width: 1, color: Colors.grey[300])),
//
CircleAvatar(radius: 6, backgroundColor: dotColor),
// 线
isLast
? SizedBox(height: 6 + 5)
: Expanded(child: Container(width: 1, color: Colors.grey[300])),
],
),
),
title: Text(
item['STEP_NAME'] ?? '',
style: TextStyle(color: textColor, fontSize: 15),
),
subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (item['SIGN_USER'] != null)
Text(
item['SIGN_USER'],
style: TextStyle(color: textColor, fontSize: 13),
),
if (item['FINISHED_SIGN_USER'] != null)
Text(
item['FINISHED_SIGN_USER'],
style: TextStyle(color: textColor, fontSize: 13),
),
if (item['ACT_USER_NAME'] != null)
Text(
item['ACT_USER_NAME'],
style: TextStyle(color: textColor, fontSize: 13),
),
if (item['ACT_TIME'] != null)
Text(
item['ACT_TIME'],
style: TextStyle(color: textColor, fontSize: 13),
),
],
),
);
}
Widget _buildListItem(Map<String, dynamic> item) { Widget _buildListItem(Map<String, dynamic> item) {
return Card( return Card(
@ -399,6 +335,7 @@ ToastUtil.showNormal(context, '获取流程图失败');
child: Padding( child: Padding(
padding: const EdgeInsets.all(12.0), padding: const EdgeInsets.all(12.0),
child: Column( child: Column(
spacing: 8,
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Row( Row(
@ -410,7 +347,7 @@ ToastUtil.showNormal(context, '获取流程图失败');
), ),
], ],
), ),
const SizedBox(height: 8),
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
@ -419,54 +356,68 @@ ToastUtil.showNormal(context, '获取流程图失败');
Text("分析人: ${item['ANALYZE_USER_NAME'] ?? ''}"), Text("分析人: ${item['ANALYZE_USER_NAME'] ?? ''}"),
], ],
), ),
const SizedBox(height: 8),
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Text("监护人: ${item['GUARDIAN_USER_NAME'] ?? ''}"), Text("监护人: ${item['GUARDIAN_USER_NAME'] ?? ''}"),
Expanded(child: Text("安全交底人: ${item['CONFESS_USER_NAME'] ?? ''}",softWrap: true, Expanded(child: Text("用电人: ${item['ELECTRICITY_USER_NAME'] ?? ''}",softWrap: true,
textAlign: TextAlign.right, textAlign: TextAlign.right,
maxLines: null, // maxLines: null, //
overflow: TextOverflow.visible,) overflow: TextOverflow.visible,)
), ),
], ],
), ),
const SizedBox(height: 8),
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Expanded(child: Text("接受交底人: ${item['ACCEPT_CONFESS_USER_NAME'] ?? ''}",softWrap: true, Expanded(child: Text("安全交底人: ${item['CONFESS_USER_NAME'] ?? ''}",softWrap: true,
textAlign: TextAlign.left,
maxLines: null, // maxLines: null, //
overflow: TextOverflow.visible,) overflow: TextOverflow.visible,)
), ),
Expanded(child: Text("接受交底人: ${item['ACCEPT_CONFESS_USER_NAME'] ?? ''}",softWrap: true,
maxLines: null, //
textAlign: TextAlign.right,
overflow: TextOverflow.visible,)
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(child: Text("作业负责人: ${item['CONFIRM_USER_NAME'] ?? ''}",softWrap: true, Expanded(child: Text("作业负责人: ${item['CONFIRM_USER_NAME'] ?? ''}",softWrap: true,
maxLines: null, // maxLines: null, //
overflow: TextOverflow.visible,) overflow: TextOverflow.visible,)
), ),
], Expanded(child: Text("用电负责人: ${item['AUDIT_USER_NAME'] ?? ''}",softWrap: true,
),
const SizedBox(height: 8),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(child: Text("用电单位负责人: ${item['AUDIT_USER_NAME'] ?? ''}",softWrap: true,
maxLines: null, // maxLines: null, //
overflow: TextOverflow.visible,)
),
Expanded(child: Text("配送电单位负责人: ${item['APPROVE_USER_NAME'] ?? ''}",softWrap: true,
textAlign: TextAlign.right, textAlign: TextAlign.right,
maxLines: null, //
overflow: TextOverflow.visible,) overflow: TextOverflow.visible,)
), ),
], ],
), ),
const SizedBox(height: 8),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [Expanded(child: Text("配送电单位负责人: ${item['APPROVE_USER_NAME'] ?? ''}",softWrap: true,
textAlign: TextAlign.left,
maxLines: null, //
overflow: TextOverflow.visible,)
),],
),
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [Text("验收部门负责人: ${item['ACCEPT_USER_NAME'] ?? ''}")], children: [Text("验收部门负责人: ${item['ACCEPT_USER_NAME'] ?? ''}")],
), ),
const SizedBox(height: 8),
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
@ -478,7 +429,7 @@ ToastUtil.showNormal(context, '获取流程图失败');
), ),
], ],
), ),
const SizedBox(height: 8),
Row( Row(
children: [ children: [
CustomButton( CustomButton(
@ -602,48 +553,7 @@ ToastUtil.showNormal(context, '获取流程图失败');
child: child:
flowList.isEmpty flowList.isEmpty
? Center(child: Text('暂无流程图数据')) ? Center(child: Text('暂无流程图数据'))
: ListView.builder( : ItemListWidget.buildFlowStepItem(flowList: flowList),
padding: const EdgeInsets.symmetric(vertical: 16),
itemCount: flowList.length + 1, // +1
itemBuilder: (context, i) {
if (i == 0) {
return Padding(
padding: const EdgeInsets.symmetric(
horizontal: 16,
vertical: 8,
),
child: Text(
'查看流程图',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
);
}
final idx = i - 1;
final item = flowList[idx];
final bool isFirst = idx == 0;
final bool isLast = idx == flowList.length - 1;
// lastDoneIndex
final int status;
if (idx <= lastDoneIndex) {
status = 1; //
} else if (idx == lastDoneIndex + 1) {
status = 0; //
} else {
status = -1; //
}
return _buildFlowStepItem(
item: item,
isFirst: isFirst,
isLast: isLast,
status: status,
);
},
),
), ),
), ),

View File

@ -308,8 +308,10 @@ class _ElectricityApplyDetailState extends State<ElectricityApplyDetail> {
onTapClean: () { onTapClean: () {
ToastUtil.showNormal(context, '已清除'); ToastUtil.showNormal(context, '已清除');
setState(() { setState(() {
pd['${type.name}_DEPARTMENT_NAME'] = ''; set_pd_USER_ID(type, '');
pd['${type.name}_USER_NAME'] = ''; set_pd_USER_Name(type, '');
set_pd_DEPARTMENT_NAME(type, '');
set_pd_DEPARTMENT_ID(type, '');
_personCache.remove(type); _personCache.remove(type);
}); });
}, },
@ -518,7 +520,7 @@ class _ElectricityApplyDetailState extends State<ElectricityApplyDetail> {
pd['ISANALYZE'] = _isGasAnalyze ? 1 : 0; pd['ISANALYZE'] = _isGasAnalyze ? 1 : 0;
pd['APPLY_STATUS'] = status; pd['APPLY_STATUS'] = status;
pd['TASK_ID'] = taskId; pd['TASK_ID'] = taskId;
pd['SPECIAL_WORK'] = FormUtils.hasValue(pd, 'SPECIAL_WORK') ? pd['SPECIAL_WORK'] : '';
// //
if (msg == 'add') { if (msg == 'add') {
pd['ELECTRICITY_ID'] = widget.ELECTRICITY_ID; pd['ELECTRICITY_ID'] = widget.ELECTRICITY_ID;
@ -537,7 +539,7 @@ class _ElectricityApplyDetailState extends State<ElectricityApplyDetail> {
final result = await ApiService.submitHomework(url, pd); final result = await ApiService.submitHomework(url, pd);
LoadingDialogHelper.hide(); LoadingDialogHelper.hide();
if (result['result'] == 'success') { if (result['result'] == 'success') {
ToastUtil.showSuccess(context, status == '1' ? '提交成功' : '已暂存'); ToastUtil.showSuccess(context, status == '1' ? '提交成功' : '操作成功');
Navigator.of(context).pop(true); Navigator.of(context).pop(true);
} else { } else {
ToastUtil.showSuccess(context, '提交失败'); ToastUtil.showSuccess(context, '提交失败');

View File

@ -380,6 +380,7 @@ class _ElectricityYsgdDetailState extends State<ElectricityYsgdDetail> {
), ),
onTap: () async { onTap: () async {
DateTime? picked = await BottomDateTimePicker.showDate( DateTime? picked = await BottomDateTimePicker.showDate(
allowPast:false,
mode: BottomPickerMode.dateTimeWithSeconds, mode: BottomPickerMode.dateTimeWithSeconds,
context, context,
); );

View File

@ -346,12 +346,12 @@ class _BlindboardDetailFormWidgetState
isEditable: false, isEditable: false,
text: pd['APPLY_USER_NAME'] ?? '', text: pd['APPLY_USER_NAME'] ?? '',
), ),
if (FormUtils.hasValue(pd, 'CONFIRM_DEPARTMENT_NAME')) ...[ if (FormUtils.hasValue(pd, 'WORK_USER_DEPARTMENT_NAME')) ...[
const Divider(), const Divider(),
ItemListWidget.singleLineTitleText( ItemListWidget.singleLineTitleText(
label: '作业单位:', label: '作业单位:',
isEditable: false, isEditable: false,
text: pd['CONFIRM_DEPARTMENT_NAME'] ?? '', text: pd['WORK_USER_DEPARTMENT_NAME'] ?? '',
), ),
], ],
const Divider(), const Divider(),
@ -499,6 +499,7 @@ class _BlindboardDetailFormWidgetState
isEditable: widget.isEditable, isEditable: widget.isEditable,
onTap: () async { onTap: () async {
DateTime? picked = await BottomDateTimePicker.showDate( DateTime? picked = await BottomDateTimePicker.showDate(
mode: BottomPickerMode.dateTimeWithSeconds,
context, context,
minTimeStr: pd['WORK_EXPECTED_START_TIME'] ?? '', minTimeStr: pd['WORK_EXPECTED_START_TIME'] ?? '',
allowFuture: true, allowFuture: true,
@ -551,6 +552,7 @@ class _BlindboardDetailFormWidgetState
isEditable: widget.isEditable, isEditable: widget.isEditable,
onTap: () async { onTap: () async {
DateTime? picked = await BottomDateTimePicker.showDate( DateTime? picked = await BottomDateTimePicker.showDate(
mode: BottomPickerMode.dateTimeWithSeconds,
context, context,
minTimeStr: pd['WORK_EXPECTED_START_TIME'] ?? '', minTimeStr: pd['WORK_EXPECTED_START_TIME'] ?? '',
allowFuture: true, allowFuture: true,

View File

@ -197,10 +197,7 @@ class _BlindboardSafeFuncSureState extends State<BlindboardSafeFuncSure> {
/// 1 0 /// 1 0
Future<void> _submit(String status) async { Future<void> _submit(String status) async {
if (_otherController.text.trim().isEmpty) {
ToastUtil.showNormal(context, '请输入其他安全措施,没有请填“无”');
return;
}
if (imagePaths.isEmpty) { if (imagePaths.isEmpty) {
ToastUtil.showNormal(context, '请签字'); ToastUtil.showNormal(context, '请签字');
return; return;
@ -211,6 +208,10 @@ class _BlindboardSafeFuncSureState extends State<BlindboardSafeFuncSure> {
if (!_validateAndProceed(context)) { if (!_validateAndProceed(context)) {
return; return;
} }
if (_otherController.text.trim().isEmpty) {
ToastUtil.showNormal(context, '请输入其他安全措施,没有请填“无”');
return;
}
} else { } else {
reasonText = await CustomAlertDialog.showInput( reasonText = await CustomAlertDialog.showInput(
context, context,
@ -252,7 +253,7 @@ class _BlindboardSafeFuncSureState extends State<BlindboardSafeFuncSure> {
); );
LoadingDialogHelper.hide(); LoadingDialogHelper.hide();
if (result['result'] == 'success') { if (result['result'] == 'success') {
ToastUtil.showSuccess(context, status == '1' ? '提交成功' : '已暂存'); ToastUtil.showSuccess(context, status == '1' ? '提交成功' : '操作成功');
Navigator.of(context).pop(true); // true Navigator.of(context).pop(true); // true
} }
} catch (e) { } catch (e) {
@ -384,6 +385,7 @@ class _BlindboardSafeFuncSureState extends State<BlindboardSafeFuncSure> {
], ],
), ),
ItemListWidget.singleLineTitleText( ItemListWidget.singleLineTitleText(
isNumericInput: true,
label: '其他安全措施:', label: '其他安全措施:',
isEditable: true, isEditable: true,
hintText: '请输入其他安全措施', hintText: '请输入其他安全措施',

View File

@ -22,6 +22,8 @@ import 'package:qhd_prevention/customWidget/bottom_picker.dart';
import 'package:qhd_prevention/customWidget/custom_button.dart'; import 'package:qhd_prevention/customWidget/custom_button.dart';
import 'package:qhd_prevention/customWidget/search_bar_widget.dart'; import 'package:qhd_prevention/customWidget/search_bar_widget.dart';
import 'package:qhd_prevention/http/ApiService.dart'; import 'package:qhd_prevention/http/ApiService.dart';
import 'package:qhd_prevention/pages/home/tap/item_list_widget.dart';
class BlindboardListPage extends StatefulWidget { class BlindboardListPage extends StatefulWidget {
final String flow; final String flow;
@ -235,72 +237,7 @@ ToastUtil.showNormal(context, '获取流程图失败');
LoadingDialogHelper.hide(); LoadingDialogHelper.hide();
} }
Widget _buildFlowStepItem({
required Map<String, dynamic> item,
required bool isFirst,
required bool isLast,
required int status, // 1 = , 0 = , -1 =
}) {
//
final Color dotColor =
status == 1 ? Colors.green : (status == 0 ? Colors.blue : Colors.grey);
final Color textColor =
status == 1 ? Colors.green : (status == 0 ? Colors.blue : Colors.black);
return ListTile(
visualDensity: VisualDensity(vertical: -4),
contentPadding: const EdgeInsets.symmetric(horizontal: 16),
leading: Container(
width: 24,
alignment: Alignment.center,
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
// 线
isFirst
? SizedBox(height: 6 + 5)
: Expanded(child: Container(width: 1, color: Colors.grey[300])),
//
CircleAvatar(radius: 6, backgroundColor: dotColor),
// 线
isLast
? SizedBox(height: 6 + 5)
: Expanded(child: Container(width: 1, color: Colors.grey[300])),
],
),
),
title: Text(
item['STEP_NAME'] ?? '',
style: TextStyle(color: textColor, fontSize: 15),
),
subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (item['SIGN_USER'] != null)
Text(
item['SIGN_USER'],
style: TextStyle(color: textColor, fontSize: 13),
),
if (item['FINISHED_SIGN_USER'] != null)
Text(
item['FINISHED_SIGN_USER'],
style: TextStyle(color: textColor, fontSize: 13),
),
if (item['ACT_USER_NAME'] != null)
Text(
item['ACT_USER_NAME'],
style: TextStyle(color: textColor, fontSize: 13),
),
if (item['ACT_TIME'] != null)
Text(
item['ACT_TIME'],
style: TextStyle(color: textColor, fontSize: 13),
),
],
),
);
}
String _getWorkLevelText(dynamic level) { String _getWorkLevelText(dynamic level) {
switch (level?.toString()) { switch (level?.toString()) {
@ -503,48 +440,7 @@ ToastUtil.showNormal(context, '获取流程图失败');
child: child:
flowList.isEmpty flowList.isEmpty
? Center(child: Text('暂无流程图数据')) ? Center(child: Text('暂无流程图数据'))
: ListView.builder( : ItemListWidget.buildFlowStepItem(flowList: flowList),
padding: const EdgeInsets.symmetric(vertical: 16),
itemCount: flowList.length + 1, // +1
itemBuilder: (context, i) {
if (i == 0) {
return Padding(
padding: const EdgeInsets.symmetric(
horizontal: 16,
vertical: 8,
),
child: Text(
'查看流程图',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
);
}
final idx = i - 1;
final item = flowList[idx];
final bool isFirst = idx == 0;
final bool isLast = idx == flowList.length - 1;
// lastDoneIndex
final int status;
if (idx <= lastDoneIndex) {
status = 1; //
} else if (idx == lastDoneIndex + 1) {
status = 0; //
} else {
status = -1; //
}
return _buildFlowStepItem(
item: item,
isFirst: isFirst,
isLast: isLast,
status: status,
);
},
),
), ),
), ),

View File

@ -318,8 +318,10 @@ class _BlindboardApplyDetailState extends State<BlindboardApplyDetail> {
onTapClean: () { onTapClean: () {
ToastUtil.showNormal(context, '已清除'); ToastUtil.showNormal(context, '已清除');
setState(() { setState(() {
pd['${type.name}_DEPARTMENT_NAME'] = ''; set_pd_USER_ID(type, '');
pd['${type.name}_USER_NAME'] = ''; set_pd_USER_Name(type, '');
set_pd_DEPARTMENT_NAME(type, '');
set_pd_DEPARTMENT_ID(type, '');
_personCache.remove(type); _personCache.remove(type);
}); });
}, },
@ -506,7 +508,7 @@ class _BlindboardApplyDetailState extends State<BlindboardApplyDetail> {
pd['ACTION_USER'] = SessionService.instance.username; pd['ACTION_USER'] = SessionService.instance.username;
pd['APPLY_STATUS'] = status; pd['APPLY_STATUS'] = status;
pd['boardList'] = jsonEncode(boardList).toString(); pd['boardList'] = jsonEncode(boardList).toString();
pd['SPECIAL_WORK'] = FormUtils.hasValue(pd, 'SPECIAL_WORK') ? pd['SPECIAL_WORK'] : '';
// //
if (msg == 'add') { if (msg == 'add') {
pd['STEP_ID'] = status; pd['STEP_ID'] = status;
@ -528,7 +530,7 @@ class _BlindboardApplyDetailState extends State<BlindboardApplyDetail> {
final result = await ApiService.submitHomework(url, pd); final result = await ApiService.submitHomework(url, pd);
LoadingDialogHelper.hide(); LoadingDialogHelper.hide();
if (result['result'] == 'success') { if (result['result'] == 'success') {
ToastUtil.showSuccess(context, status == '1' ? '提交成功' : '已暂存'); ToastUtil.showSuccess(context, status == '1' ? '提交成功' : '操作成功');
Navigator.of(context).pop(true); Navigator.of(context).pop(true);
} }
} catch (e) { } catch (e) {

View File

@ -367,6 +367,7 @@ class _BlindboardYsgdDetailState extends State<BlindboardYsgdDetail> {
), ),
onTap: () async { onTap: () async {
DateTime? picked = await BottomDateTimePicker.showDate( DateTime? picked = await BottomDateTimePicker.showDate(
allowPast:false,
mode: BottomPickerMode.dateTimeWithSeconds, mode: BottomPickerMode.dateTimeWithSeconds,
context, context,
); );

View File

@ -186,12 +186,12 @@ class _SpaceWorkDetailFormWidgetState extends State<SpaceWorkDetailFormWidget> {
controller: widget.contentController, controller: widget.contentController,
text: pd['WORK_CONTENT'] ?? '', text: pd['WORK_CONTENT'] ?? '',
), ),
if (FormUtils.hasValue(pd, 'CONFIRM_DEPARTMENT_NAME')) ...[ if (FormUtils.hasValue(pd, 'WORK_USER_DEPARTMENT_NAME')) ...[
const Divider(), const Divider(),
ItemListWidget.singleLineTitleText( ItemListWidget.singleLineTitleText(
label: '作业单位:', label: '作业单位:',
isEditable: false, isEditable: false,
text: pd['CONFIRM_DEPARTMENT_NAME'] ?? '', text: pd['WORK_USER_DEPARTMENT_NAME'] ?? '',
), ),
], ],
if (FormUtils.hasValue(pd, 'CONFIRM_USER_NAME') && if (FormUtils.hasValue(pd, 'CONFIRM_USER_NAME') &&
@ -297,6 +297,7 @@ class _SpaceWorkDetailFormWidgetState extends State<SpaceWorkDetailFormWidget> {
isEditable: widget.isEditable, isEditable: widget.isEditable,
onTap: () async { onTap: () async {
DateTime? picked = await BottomDateTimePicker.showDate( DateTime? picked = await BottomDateTimePicker.showDate(
mode: BottomPickerMode.dateTimeWithSeconds,
context, context,
minTimeStr: pd['WORK_EXPECTED_START_TIME'] ?? '', minTimeStr: pd['WORK_EXPECTED_START_TIME'] ?? '',
allowFuture: true, allowFuture: true,
@ -345,9 +346,11 @@ class _SpaceWorkDetailFormWidgetState extends State<SpaceWorkDetailFormWidget> {
const Divider(), const Divider(),
ItemListWidget.selectableLineTitleTextRightButton( ItemListWidget.selectableLineTitleTextRightButton(
label: '预计作业结束时间:', label: '预计作业结束时间:',
isEditable: widget.isEditable, isEditable: widget.isEditable,
onTap: () async { onTap: () async {
DateTime? picked = await BottomDateTimePicker.showDate( DateTime? picked = await BottomDateTimePicker.showDate(
mode: BottomPickerMode.dateTimeWithSeconds,
context, context,
minTimeStr: pd['WORK_EXPECTED_START_TIME'] ?? '', minTimeStr: pd['WORK_EXPECTED_START_TIME'] ?? '',
allowFuture: true, allowFuture: true,

View File

@ -186,10 +186,7 @@ class _SpaceworkSafeFuncSureState extends State<SpaceworkSafeFuncSure> {
/// 1 0 /// 1 0
Future<void> _submit(String status) async { Future<void> _submit(String status) async {
if (_otherController.text.trim().isEmpty) {
ToastUtil.showNormal(context, '请输入其他安全措施,没有请填“无”');
return;
}
if (imagePaths.isEmpty) { if (imagePaths.isEmpty) {
ToastUtil.showNormal(context, '请签字'); ToastUtil.showNormal(context, '请签字');
return; return;
@ -200,6 +197,10 @@ class _SpaceworkSafeFuncSureState extends State<SpaceworkSafeFuncSure> {
if (!_validateAndProceed(context)) { if (!_validateAndProceed(context)) {
return; return;
} }
if (_otherController.text.trim().isEmpty) {
ToastUtil.showNormal(context, '请输入其他安全措施,没有请填“无”');
return;
}
} else { } else {
reasonText = await CustomAlertDialog.showInput( reasonText = await CustomAlertDialog.showInput(
context, context,
@ -241,7 +242,7 @@ class _SpaceworkSafeFuncSureState extends State<SpaceworkSafeFuncSure> {
); );
LoadingDialogHelper.hide(); LoadingDialogHelper.hide();
if (result['result'] == 'success') { if (result['result'] == 'success') {
ToastUtil.showSuccess(context, status == '1' ? '提交成功' : '已暂存'); ToastUtil.showSuccess(context, status == '1' ? '提交成功' : '操作成功');
Navigator.of(context).pop(true); // true Navigator.of(context).pop(true); // true
} }
} catch (e) { } catch (e) {
@ -369,6 +370,7 @@ class _SpaceworkSafeFuncSureState extends State<SpaceworkSafeFuncSure> {
], ],
), ),
ItemListWidget.singleLineTitleText( ItemListWidget.singleLineTitleText(
isNumericInput: true,
label: '其他安全措施:', label: '其他安全措施:',
isEditable: true, isEditable: true,
hintText: '请输入其他安全措施', hintText: '请输入其他安全措施',

View File

@ -329,8 +329,10 @@ class _SpaceworkApplyDetailState extends State<SpaceworkApplyDetail> {
onTapClean: () { onTapClean: () {
ToastUtil.showNormal(context, '已清除'); ToastUtil.showNormal(context, '已清除');
setState(() { setState(() {
pd['${type.name}_DEPARTMENT_NAME'] = ''; set_pd_USER_ID(type, '');
pd['${type.name}_USER_NAME'] = ''; set_pd_USER_Name(type, '');
set_pd_DEPARTMENT_NAME(type, '');
set_pd_DEPARTMENT_ID(type, '');
_personCache.remove(type); _personCache.remove(type);
}); });
}, },
@ -503,7 +505,7 @@ class _SpaceworkApplyDetailState extends State<SpaceworkApplyDetail> {
pd['ACTION_USER'] = SessionService.instance.username; pd['ACTION_USER'] = SessionService.instance.username;
pd['APPLY_STATUS'] = status; pd['APPLY_STATUS'] = status;
pd['TASK_ID'] = '4'; pd['TASK_ID'] = '4';
pd['SPECIAL_WORK'] = FormUtils.hasValue(pd, 'SPECIAL_WORK') ? pd['SPECIAL_WORK'] : '';
// //
if (msg == 'add') { if (msg == 'add') {
pd['APPLY_DEPARTMENT_ID'] = SessionService.instance.deptId; pd['APPLY_DEPARTMENT_ID'] = SessionService.instance.deptId;
@ -521,7 +523,7 @@ class _SpaceworkApplyDetailState extends State<SpaceworkApplyDetail> {
final result = await ApiService.submitHomework(url, pd); final result = await ApiService.submitHomework(url, pd);
LoadingDialogHelper.hide(); LoadingDialogHelper.hide();
if (result['result'] == 'success') { if (result['result'] == 'success') {
ToastUtil.showSuccess(context, status == '1' ? '提交成功' : '已暂存'); ToastUtil.showSuccess(context, status == '1' ? '提交成功' : '操作成功');
Navigator.of(context).pop(true); Navigator.of(context).pop(true);
} else { } else {
ToastUtil.showError(context, result['msg'] ?? '提交失败'); ToastUtil.showError(context, result['msg'] ?? '提交失败');

View File

@ -1,5 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:qhd_prevention/customWidget/toast_util.dart'; import 'package:qhd_prevention/customWidget/toast_util.dart';
import 'package:qhd_prevention/pages/home/tap/item_list_widget.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/sxkj_work/space_work_detai/spacework_apply_detail.dart'; import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/sxkj_work/space_work_detai/spacework_apply_detail.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/sxkj_work/aqcs_work_detail/spacework_safe_func_sure.dart'; import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/sxkj_work/aqcs_work_detail/spacework_safe_func_sure.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/sxkj_work/aqgl_work_detail/spacework_aqgl_detail.dart'; import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/sxkj_work/aqgl_work_detail/spacework_aqgl_detail.dart';
@ -345,72 +346,7 @@ ToastUtil.showNormal(context, '获取流程图失败');
LoadingDialogHelper.hide(); LoadingDialogHelper.hide();
} }
Widget _buildFlowStepItem({
required Map<String, dynamic> item,
required bool isFirst,
required bool isLast,
required int status, // 1 = , 0 = , -1 =
}) {
//
final Color dotColor =
status == 1 ? Colors.green : (status == 0 ? Colors.blue : Colors.grey);
final Color textColor =
status == 1 ? Colors.green : (status == 0 ? Colors.blue : Colors.black);
return ListTile(
visualDensity: VisualDensity(vertical: -4),
contentPadding: const EdgeInsets.symmetric(horizontal: 16),
leading: Container(
width: 24,
alignment: Alignment.center,
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
// 线
isFirst
? SizedBox(height: 6 + 5)
: Expanded(child: Container(width: 1, color: Colors.grey[300])),
//
CircleAvatar(radius: 6, backgroundColor: dotColor),
// 线
isLast
? SizedBox(height: 6 + 5)
: Expanded(child: Container(width: 1, color: Colors.grey[300])),
],
),
),
title: Text(
item['STEP_NAME'] ?? '',
style: TextStyle(color: textColor, fontSize: 15),
),
subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (item['SIGN_USER'] != null)
Text(
item['SIGN_USER'],
style: TextStyle(color: textColor, fontSize: 13),
),
if (item['FINISHED_SIGN_USER'] != null)
Text(
item['FINISHED_SIGN_USER'],
style: TextStyle(color: textColor, fontSize: 13),
),
if (item['ACT_USER_NAME'] != null)
Text(
item['ACT_USER_NAME'],
style: TextStyle(color: textColor, fontSize: 13),
),
if (item['ACT_TIME'] != null)
Text(
item['ACT_TIME'],
style: TextStyle(color: textColor, fontSize: 13),
),
],
),
);
}
Widget _buildListItem(Map<String, dynamic> item) { Widget _buildListItem(Map<String, dynamic> item) {
return Card( return Card(
@ -421,6 +357,7 @@ ToastUtil.showNormal(context, '获取流程图失败');
child: Padding( child: Padding(
padding: const EdgeInsets.all(12.0), padding: const EdgeInsets.all(12.0),
child: Column( child: Column(
spacing: 8,
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Row( Row(
@ -432,7 +369,7 @@ ToastUtil.showNormal(context, '获取流程图失败');
), ),
], ],
), ),
const SizedBox(height: 8),
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
@ -440,7 +377,7 @@ ToastUtil.showNormal(context, '获取流程图失败');
Text("分析人: ${item['ANALYZE_USER_NAME'] ?? ''}"), Text("分析人: ${item['ANALYZE_USER_NAME'] ?? ''}"),
], ],
), ),
const SizedBox(height: 8),
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
@ -452,7 +389,7 @@ ToastUtil.showNormal(context, '获取流程图失败');
), ),
], ],
), ),
const SizedBox(height: 8),
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
@ -460,29 +397,32 @@ ToastUtil.showNormal(context, '获取流程图失败');
maxLines: null, // maxLines: null, //
overflow: TextOverflow.visible,) overflow: TextOverflow.visible,)
), ),
Expanded(child: Text("作业负责人: ${item['CONFIRM_USER_NAME'] ?? ''}",softWrap: true, Expanded(child: Text("作业人: ${item['WORK_USER_USER_NAME'] ?? ''}",softWrap: true,
textAlign: TextAlign.right, textAlign: TextAlign.right,
maxLines: null, // maxLines: null, //
overflow: TextOverflow.visible,) overflow: TextOverflow.visible,)
), ),
], ],
), ),
const SizedBox(height: 8),
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Expanded(child: Text("所在单位负责人: ${item['LEADER_USER_NAME'] ?? ''}",softWrap: true, Expanded(child: Text("作业负责人: ${item['CONFIRM_USER_NAME'] ?? ''}",softWrap: true,
maxLines: null, // maxLines: null, //
overflow: TextOverflow.visible,) overflow: TextOverflow.visible,)
), ),
Expanded(child: Text("验收部门负责人: ${item['ACCEPT_USER_NAME'] ?? ''}",softWrap: true, Expanded(child: Text("所在单位负责人: ${item['LEADER_USER_NAME'] ?? ''}",softWrap: true,
textAlign: TextAlign.right, textAlign: TextAlign.right,
maxLines: null, // maxLines: null, //
overflow: TextOverflow.visible,) overflow: TextOverflow.visible,)
), ),
], ],
), ),
const SizedBox(height: 8), Text("验收部门负责人: ${item['ACCEPT_USER_NAME'] ?? ''}",softWrap: true,
textAlign: TextAlign.right,
maxLines: null, //
overflow: TextOverflow.visible,),
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
@ -494,7 +434,7 @@ ToastUtil.showNormal(context, '获取流程图失败');
), ),
], ],
), ),
const SizedBox(height: 8),
Row( Row(
children: [ children: [
CustomButton( CustomButton(
@ -618,48 +558,7 @@ ToastUtil.showNormal(context, '获取流程图失败');
child: child:
flowList.isEmpty flowList.isEmpty
? Center(child: Text('暂无流程图数据')) ? Center(child: Text('暂无流程图数据'))
: ListView.builder( : ItemListWidget.buildFlowStepItem(flowList: flowList),
padding: const EdgeInsets.symmetric(vertical: 16),
itemCount: flowList.length + 1, // +1
itemBuilder: (context, i) {
if (i == 0) {
return Padding(
padding: const EdgeInsets.symmetric(
horizontal: 16,
vertical: 8,
),
child: Text(
'查看流程图',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
);
}
final idx = i - 1;
final item = flowList[idx];
final bool isFirst = idx == 0;
final bool isLast = idx == flowList.length - 1;
// lastDoneIndex
final int status;
if (idx <= lastDoneIndex) {
status = 1; //
} else if (idx == lastDoneIndex + 1) {
status = 0; //
} else {
status = -1; //
}
return _buildFlowStepItem(
item: item,
isFirst: isFirst,
isLast: isLast,
status: status,
);
},
),
), ),
), ),

View File

@ -384,6 +384,7 @@ class _SpaceworkYsgdDetailState extends State<SpaceworkYsgdDetail> {
), ),
onTap: () async { onTap: () async {
DateTime? picked = await BottomDateTimePicker.showDate( DateTime? picked = await BottomDateTimePicker.showDate(
allowPast:false,
mode: BottomPickerMode.dateTimeWithSeconds, mode: BottomPickerMode.dateTimeWithSeconds,
context, context,
); );