。。。。

main
hs 2025-09-17 18:05:47 +08:00
parent 6ca5a27418
commit 76d0fdbd16
10 changed files with 473 additions and 398 deletions

View File

@ -352,6 +352,13 @@ setState(() {
} }
Widget _mainWidget() { Widget _mainWidget() {
bool isShowCheck = false;
if (FormUtils.hasValue(inspectedForm, 'hiddenList')) {
List list = inspectedForm['hiddenList'];
if (list.isEmpty) {
isShowCheck = true;
}
}
return ListView( return ListView(
children: [ children: [
Column( Column(
@ -380,8 +387,9 @@ setState(() {
: false, : false,
yesLabel: '同意', yesLabel: '同意',
noLabel: '申辩', noLabel: '申辩',
isEdit: true, isEdit: isShowCheck ? true : false,
isRequired: false, isRequired: false,
text: inspectedForm['INSPECTION_STATUS'] == '3' ? '同意' : '申辩',
horizontalPadding: 3, horizontalPadding: 3,
verticalPadding: 0, verticalPadding: 0,
onChanged: (val) { onChanged: (val) {

View File

@ -16,6 +16,7 @@ class _StudyClassListPageState extends State<StudyClassListPage> {
late List<dynamic> _list = []; late List<dynamic> _list = [];
late String _classId = ''; late String _classId = '';
late String _post_id = ''; late String _post_id = '';
late Map _classInfo = {};
@override @override
void initState() { void initState() {
super.initState(); super.initState();
@ -32,6 +33,7 @@ class _StudyClassListPageState extends State<StudyClassListPage> {
final result = await ApiService.getClassList(_classId, _post_id); final result = await ApiService.getClassList(_classId, _post_id);
if (result['result'] == 'success') { if (result['result'] == 'success') {
final List<dynamic> newList = result['varList'] ?? []; final List<dynamic> newList = result['varList'] ?? [];
_classInfo = result['classInfo'] ?? {};
setState(() { setState(() {
_list.addAll(newList); _list.addAll(newList);
}); });
@ -46,7 +48,7 @@ class _StudyClassListPageState extends State<StudyClassListPage> {
final result = await ApiService.getVideoPermissions(); final result = await ApiService.getVideoPermissions();
if (result['result'] == 'success') { if (result['result'] == 'success') {
SessionService.instance.setStudyToken(result['token'] ?? ''); SessionService.instance.setStudyToken(result['token'] ?? '');
pushPage(StudyDetailPage(item, widget.studyData['STUDENT_ID'],widget.studyData), context); pushPage(StudyDetailPage(_classInfo, item, widget.studyData['STUDENT_ID'],widget.studyData), context);
} }
} }
@override @override

View File

@ -24,10 +24,17 @@ enum TakeExamType { video_study, strengththen, list }
class StudyDetailPage extends StatefulWidget { class StudyDetailPage extends StatefulWidget {
final Map studyDetailDetail; final Map studyDetailDetail;
final Map classInfo;
final String studentId; final String studentId;
final Map studyData; final Map studyData;
const StudyDetailPage(this.studyDetailDetail, this.studentId, this.studyData,{super.key}); const StudyDetailPage(
this.classInfo,
this.studyDetailDetail,
this.studentId,
this.studyData, {
super.key,
});
@override @override
State<StudyDetailPage> createState() => _StudyDetailPageState(); State<StudyDetailPage> createState() => _StudyDetailPageState();
@ -54,6 +61,7 @@ class _StudyDetailPageState extends State<StudyDetailPage>
int _currentNodeIndex = 0; int _currentNodeIndex = 0;
bool _hasNodes = false; bool _hasNodes = false;
Duration _lastReported = Duration.zero; Duration _lastReported = Duration.zero;
bool _isFace = false;
// //
bool _endReported = false; // bool _endReported = false; //
@ -69,6 +77,7 @@ class _StudyDetailPageState extends State<StudyDetailPage>
WakelockPlus.enable(); WakelockPlus.enable();
_classId = widget.studyDetailDetail['CLASS_ID'] ?? ''; _classId = widget.studyDetailDetail['CLASS_ID'] ?? '';
_classCurriculumId = widget.studyDetailDetail['CLASSCURRICULUM_ID'] ?? ''; _classCurriculumId = widget.studyDetailDetail['CLASSCURRICULUM_ID'] ?? '';
_isFace = widget.classInfo['ISFACE'] == '1' ? true : false;
_tabController = TabController(length: 2, vsync: this); _tabController = TabController(length: 2, vsync: this);
WidgetsBinding.instance.addPostFrameCallback((_) { WidgetsBinding.instance.addPostFrameCallback((_) {
_showFaceIntro(); _showFaceIntro();
@ -99,16 +108,19 @@ class _StudyDetailPageState extends State<StudyDetailPage>
} }
Future<void> _showFaceIntro() async { Future<void> _showFaceIntro() async {
final ok = await CustomAlertDialog.showConfirm( if (_isFace) {
context, final ok = await CustomAlertDialog.showConfirm(
title: '温馨提示', context,
content: '重要提醒:尊敬的用户,根据规定我们会在您学习过程中多次进行人脸识别认证,为了保护您的隐私请您在摄像设备视野内确保衣冠整齐。', title: '温馨提示',
cancelText: '取消', content:
confirmText: '同意并继续', '重要提醒:尊敬的用户,根据规定我们会在您学习过程中多次进行人脸识别认证,为了保护您的隐私请您在摄像设备视野内确保衣冠整齐。',
); cancelText: '取消',
if (!ok) { confirmText: '同意并继续',
Navigator.of(context).pop(); );
return; if (!ok) {
Navigator.of(context).pop();
return;
}
} }
} }
@ -179,8 +191,6 @@ class _StudyDetailPageState extends State<StudyDetailPage>
return '$s%'; return '$s%';
} }
Future<void> _onVideoTap( Future<void> _onVideoTap(
Map<String, dynamic> data, Map<String, dynamic> data,
bool hasNodes, bool hasNodes,
@ -191,9 +201,15 @@ class _StudyDetailPageState extends State<StudyDetailPage>
debugPrint('_onVideoTap ignored because a video is loading'); debugPrint('_onVideoTap ignored because a video is loading');
return; return;
} }
// if (_isFace) {
await ApiService.fnClearUserFaceTime(); try {
_faceTimer?.cancel(); await ApiService.fnClearUserFaceTime();
} catch (e, st) {
debugPrint('fnClearUserFaceTime error: $e\n$st');
}
_faceTimer?.cancel();
_faceTimer = null;
}
// //
if (_currentVideoData != null && _lastReported > Duration.zero) { if (_currentVideoData != null && _lastReported > Duration.zero) {
@ -252,7 +268,6 @@ class _StudyDetailPageState extends State<StudyDetailPage>
seconds: int.parse('${data['VIDEOTIME'] ?? '0'}'), seconds: int.parse('${data['VIDEOTIME'] ?? '0'}'),
); );
} }
} else { } else {
ToastUtil.showNormal(context, '课件文件资源已失效,请联系管理员'); ToastUtil.showNormal(context, '课件文件资源已失效,请联系管理员');
} }
@ -267,59 +282,69 @@ class _StudyDetailPageState extends State<StudyDetailPage>
// //
await _getVideoPlayInfo(data['VIDEOCOURSEWARE_ID']); await _getVideoPlayInfo(data['VIDEOCOURSEWARE_ID']);
LoadingDialogHelper.hide(); LoadingDialogHelper.hide();
_startFaceTimer(); if (_isFace) {
_startFaceTimer();
}
} }
}); });
} }
Future<void> _navigateFaceIfNeeded(FutureOr<void> Function() onPass) async { Future<void> _navigateFaceIfNeeded(FutureOr<void> Function() onPass) async {
if (_info?['ISFACE'] == '1') { if (!_isFace) {
LoadingDialogHelper.show(); await onPass();
final resData = await ApiService.fnGetUserFace(); return;
LoadingDialogHelper.hide(); }
final pd_data = resData['pd']; LoadingDialogHelper.show();
if (FormUtils.hasValue(pd_data, 'USERAVATARURL')) { final resData = await ApiService.fnGetUserFace();
// 退 LoadingDialogHelper.hide();
final pd_data = resData['pd'];
if (FormUtils.hasValue(pd_data, 'USERAVATARURL')) {
// 退
await _exitTopRouteAndWait();
await _lockPortrait();
final passed = await pushPage<bool>(
FaceRecognitionPage(
studentId: widget.studentId,
VIDEOCOURSEWARE_ID: "",
CURRICULUM_ID: "",
CHAPTER_ID: "",
CLASS_ID: "",
mode: FaceMode.auto,
),
context,
);
await _restoreDefaultOrientations();
if (passed == true) {
LoadingDialogHelper.show();
await ApiService.fnSetUserFaceTime(_faceTime);
await onPass();
} else {
ToastUtil.showError(context, '人脸验证未通过,无法继续');
}
} else {
final ok = await CustomAlertDialog.showConfirm(
context,
title: '温馨提示',
content: '您当前还未进行人脸认证,请先进行认证',
cancelText: '取消',
);
if (ok) {
await _exitTopRouteAndWait(); await _exitTopRouteAndWait();
await _lockPortrait(); await _lockPortrait();
final passed = await pushPage<bool>( await pushPage(
FaceRecognitionPage(studentId: widget.studentId, const FaceRecognitionPage(
VIDEOCOURSEWARE_ID:"",CURRICULUM_ID:"", studentId: '',
CHAPTER_ID: "",CLASS_ID: "", VIDEOCOURSEWARE_ID: '',
mode: FaceMode.auto), CURRICULUM_ID: '',
CHAPTER_ID: '',
CLASS_ID: '',
mode: FaceMode.manual,
),
context, context,
); );
await _restoreDefaultOrientations(); await _restoreDefaultOrientations();
if (passed == true) {
LoadingDialogHelper.show();
await ApiService.fnSetUserFaceTime(_faceTime);
await onPass();
} else {
ToastUtil.showError(context, '人脸验证未通过,无法继续');
}
} else {
final ok = await CustomAlertDialog.showConfirm(
context,
title: '温馨提示',
content: '您当前还未进行人脸认证,请先进行认证',
cancelText: '取消',
);
if (ok) {
await _exitTopRouteAndWait();
await _lockPortrait();
await pushPage(
const FaceRecognitionPage(studentId: '',
VIDEOCOURSEWARE_ID: '',CURRICULUM_ID: '',
CHAPTER_ID: '',CLASS_ID: '',
mode: FaceMode.manual),
context,
);
await _restoreDefaultOrientations();
}
} }
} else {
await onPass();
} }
} }
@ -471,8 +496,16 @@ class _StudyDetailPageState extends State<StudyDetailPage>
_exitTopRouteIfPresent(); _exitTopRouteIfPresent();
}); });
ApiService.fnClearUserFaceTime(); //
_faceTimer?.cancel(); if (_isFace) {
try {
ApiService.fnClearUserFaceTime();
} catch (e, st) {
debugPrint('fnClearUserFaceTime error on end: $e\n$st');
}
_faceTimer?.cancel();
_faceTimer = null;
}
} }
} }
} }
@ -484,7 +517,8 @@ class _StudyDetailPageState extends State<StudyDetailPage>
}) async { }) async {
// snapshot VIDEOCOURSEWARE_ID // snapshot VIDEOCOURSEWARE_ID
if (snapshot['VIDEOCOURSEWARE_ID'] == null || if (snapshot['VIDEOCOURSEWARE_ID'] == null ||
snapshot['VIDEOCOURSEWARE_ID'] == '') return; snapshot['VIDEOCOURSEWARE_ID'] == '')
return;
// //
if (_endReported && !end) return; if (_endReported && !end) return;
@ -504,7 +538,9 @@ class _StudyDetailPageState extends State<StudyDetailPage>
// snapshot['IS_VIDEO']==1 // snapshot['IS_VIDEO']==1
// 100% UI 100% // 100% UI 100%
final isNonVideo = (snapshot['IS_VIDEO'] != null && snapshot['IS_VIDEO'].toString() == '1'); 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;
@ -520,7 +556,8 @@ class _StudyDetailPageState extends State<StudyDetailPage>
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>?;
@ -529,7 +566,8 @@ class _StudyDetailPageState extends State<StudyDetailPage>
} }
} }
} else { } else {
final fi = snapshot['FIRST_INDEX'] as int? ?? _currentFirstIndex; final fi =
snapshot['FIRST_INDEX'] as int? ?? _currentFirstIndex;
if (fi >= 0 && fi < _videoList.length) { if (fi >= 0 && fi < _videoList.length) {
_videoList[fi]['percent'] = str; _videoList[fi]['percent'] = str;
} }
@ -558,15 +596,20 @@ class _StudyDetailPageState extends State<StudyDetailPage>
// //
final resTraw = pd['RESOURCETIME']; final resTraw = pd['RESOURCETIME'];
final resT = (resTraw is num) ? resTraw.toDouble() : double.tryParse('$resTraw') ?? seconds.toDouble(); final resT =
(resTraw is num)
? resTraw.toDouble()
: double.tryParse('$resTraw') ?? seconds.toDouble();
final videoTimeRaw = snapshot['VIDEOTIME']; final videoTimeRaw = snapshot['VIDEOTIME'];
final videoTime = (videoTimeRaw is String) final videoTime =
? double.tryParse(videoTimeRaw) ?? 1.0 (videoTimeRaw is String)
: (videoTimeRaw is num ? videoTimeRaw.toDouble() : 1.0); ? double.tryParse(videoTimeRaw) ?? 1.0
: (videoTimeRaw is num ? videoTimeRaw.toDouble() : 1.0);
final comp = pd['PLAYCOUNT'] != null && pd['PLAYCOUNT'] > 0; final comp = pd['PLAYCOUNT'] != null && pd['PLAYCOUNT'] > 0;
final pctDouble = comp ? 100.0 : ((resT / (videoTime > 0 ? videoTime : 1.0)) * 100.0); final pctDouble =
comp ? 100.0 : ((resT / (videoTime > 0 ? videoTime : 1.0)) * 100.0);
// //
double pctClamped = pctDouble.clamp(0.00, 100.00); double pctClamped = pctDouble.clamp(0.00, 100.00);
// 2 // 2
@ -621,83 +664,10 @@ class _StudyDetailPageState extends State<StudyDetailPage>
} }
} }
///
Future<void> _startExam(Map resData) async {
Map pd = resData['pd'] ?? {};
Map paper = resData['paper'] ?? {};
setState(() {
_loading = true;
});
final arguments = {
'STAGEEXAMPAPERINPUT_ID': paper['STAGEEXAMPAPERINPUT_ID'] ?? '',
'STAGEEXAMPAPER_ID': paper['STAGEEXAMPAPER_ID'] ?? '',
'CLASS_ID': _classId,
'POST_ID': pd['POST_ID'] ?? '',
'STUDENT_ID': widget.studentId,
'NUMBEROFEXAMS': pd['NUMBEROFEXAMS'] ?? '',
};
print('--_startExam data---$arguments');
final data = await ApiService.getStartExam(arguments);
setState(() {
_loading = false;
});
if (data['result'] == 'success') {
pushPage(
TakeExamPage(
examInfo: {
'CLASS_ID': _classId,
'POST_ID': pd['POST_ID'] ?? '',
'STUDENT_ID': widget.studentId,
'STRENGTHEN_PAPER_QUESTION_ID':
paper['STAGEEXAMPAPERINPUT_ID'] ?? '',
...data,
},
examType: TakeExamType.video_study, jumpType: 2,
),
context,
);
} else {
ToastUtil.showError(context, '请求错误');
}
}
void _exitTopRouteIfPresent() {
final route = ModalRoute.of(context);
if (route == null) return;
// route
if (!route.isCurrent) {
// pop
try {
Navigator.of(context).maybePop();
} catch (_) {
//
}
}
}
/// 退退
Future<void> _exitTopRouteAndWait({int waitMs = 300}) async {
_exitTopRouteIfPresent();
await Future.delayed(Duration(milliseconds: waitMs));
}
///
Future<void> _lockPortrait() async {
await SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
}
///
Future<void> _restoreDefaultOrientations() async {
await SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
DeviceOrientation.landscapeLeft,
DeviceOrientation.landscapeRight,
]);
}
void _startFaceTimer() { void _startFaceTimer() {
//
if (!_isFace) return;
_faceTimer = Timer.periodic(Duration(seconds: _faceTime), (_) async { _faceTimer = Timer.periodic(Duration(seconds: _faceTime), (_) async {
final res = await ApiService.fnGetUserFaceTime(); final res = await ApiService.fnGetUserFaceTime();
final isPlaying = _videoController?.value.isPlaying == true; final isPlaying = _videoController?.value.isPlaying == true;
@ -714,6 +684,8 @@ class _StudyDetailPageState extends State<StudyDetailPage>
} }
Future<void> _showFaceAuthOnce() async { Future<void> _showFaceAuthOnce() async {
//
if (!_isFace) return;
// cancel // cancel
_faceTimer?.cancel(); _faceTimer?.cancel();
_faceTimer = null; _faceTimer = null;
@ -723,10 +695,14 @@ class _StudyDetailPageState extends State<StudyDetailPage>
await _lockPortrait(); await _lockPortrait();
final passed = await pushPage<bool>( final passed = await pushPage<bool>(
FaceRecognitionPage(studentId: widget.studentId, FaceRecognitionPage(
VIDEOCOURSEWARE_ID: "",CURRICULUM_ID: "", studentId: widget.studentId,
CHAPTER_ID: "",CLASS_ID: "", VIDEOCOURSEWARE_ID: "",
mode: FaceMode.auto), CURRICULUM_ID: "",
CHAPTER_ID: "",
CLASS_ID: "",
mode: FaceMode.auto,
),
context, context,
); );
@ -768,7 +744,9 @@ class _StudyDetailPageState extends State<StudyDetailPage>
debugPrint('Error resuming playback after face auth: $e\n$st'); debugPrint('Error resuming playback after face auth: $e\n$st');
} }
// //
_startFaceTimer(); if (_isFace) {
_startFaceTimer();
}
} else { } else {
ToastUtil.showError(context, '人脸验证未通过,无法继续'); ToastUtil.showError(context, '人脸验证未通过,无法继续');
if (_videoController != null) { if (_videoController != null) {
@ -785,6 +763,82 @@ class _StudyDetailPageState extends State<StudyDetailPage>
} }
} }
///
Future<void> _startExam(Map resData) async {
Map pd = resData['pd'] ?? {};
Map paper = resData['paper'] ?? {};
setState(() {
_loading = true;
});
final arguments = {
'STAGEEXAMPAPERINPUT_ID': paper['STAGEEXAMPAPERINPUT_ID'] ?? '',
'STAGEEXAMPAPER_ID': paper['STAGEEXAMPAPER_ID'] ?? '',
'CLASS_ID': _classId,
'POST_ID': pd['POST_ID'] ?? '',
'STUDENT_ID': widget.studentId,
'NUMBEROFEXAMS': pd['NUMBEROFEXAMS'] ?? '',
};
print('--_startExam data---$arguments');
final data = await ApiService.getStartExam(arguments);
setState(() {
_loading = false;
});
if (data['result'] == 'success') {
pushPage(
TakeExamPage(
examInfo: {
'CLASS_ID': _classId,
'POST_ID': pd['POST_ID'] ?? '',
'STUDENT_ID': widget.studentId,
'STRENGTHEN_PAPER_QUESTION_ID':
paper['STAGEEXAMPAPERINPUT_ID'] ?? '',
...data,
},
examType: TakeExamType.video_study,
jumpType: 3,
),
context,
);
} else {
ToastUtil.showError(context, '请求错误');
}
}
void _exitTopRouteIfPresent() {
final route = ModalRoute.of(context);
if (route == null) return;
// route
if (!route.isCurrent) {
// pop
try {
Navigator.of(context).maybePop();
} catch (_) {
//
}
}
}
/// 退退
Future<void> _exitTopRouteAndWait({int waitMs = 300}) async {
_exitTopRouteIfPresent();
await Future.delayed(Duration(milliseconds: waitMs));
}
///
Future<void> _lockPortrait() async {
await SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
}
///
Future<void> _restoreDefaultOrientations() async {
await SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
DeviceOrientation.landscapeLeft,
DeviceOrientation.landscapeRight,
]);
}
Widget _buildVideoOrCover(double containerW, double containerH) { Widget _buildVideoOrCover(double containerW, double containerH) {
final c = _videoController; final c = _videoController;
if (c != null && c.value.isInitialized) { if (c != null && c.value.isInitialized) {
@ -896,9 +950,7 @@ class _StudyDetailPageState extends State<StudyDetailPage>
const SizedBox(width: 5), const SizedBox(width: 5),
Text( Text(
(item['NAME'] ?? '').toString(), (item['NAME'] ?? '').toString(),
style: const TextStyle( style: const TextStyle(fontSize: 15),
fontSize: 15,
),
), ),
], ],
), ),

View File

@ -116,9 +116,6 @@ class _TakeExamPageState extends State<TakeExamPage> {
content: '您无考试次数!', content: '您无考试次数!',
); );
if (ok) { if (ok) {
if (widget.jumpType == 2) {
Navigator.pop(context);
}
Navigator.pop(context); Navigator.pop(context);
}; };
} }
@ -235,10 +232,17 @@ class _TakeExamPageState extends State<TakeExamPage> {
content: content:
passed passed
? '您的成绩为 $score 分,恭喜您通过本次考试,请继续保持!' ? '您的成绩为 $score 分,恭喜您通过本次考试,请继续保持!'
: '您的成绩为 $score 分,很遗憾您没有通过本次考试,请再接再厉!', : '您的成绩为 $score 分,很遗憾您没有通过本次考试,请再接再 厉!',
cancelText: '', cancelText: '',
confirmText: '确定', confirmText: '确定',
); );
if (widget.jumpType == 2) {
Navigator.pop(context);
}
if (widget.jumpType == 3) {
Navigator.pop(context);
Navigator.pop(context);
}
Navigator.of(context).pop(); Navigator.of(context).pop();
} }
} }

View File

@ -68,8 +68,8 @@ class MeasuresListWidget extends StatelessWidget {
// //
double col0Fixed = 40; // double col0Fixed = 40; //
double col2Fixed = 80; // double col2Fixed = 70; //
double col3Fixed = 80; // double col3Fixed = 60; //
// 4isAllowEdit == true40 // 4isAllowEdit == true40
final showCol3 = !isAllowEdit; final showCol3 = !isAllowEdit;
@ -112,7 +112,8 @@ class MeasuresListWidget extends StatelessWidget {
} }
return Table( return Table(
defaultVerticalAlignment: TableCellVerticalAlignment.middle, // top
defaultVerticalAlignment: TableCellVerticalAlignment.top,
columnWidths: columnWidths, columnWidths: columnWidths,
border: TableBorder( border: TableBorder(
horizontalInside: BorderSide(color: Colors.grey.shade300), horizontalInside: BorderSide(color: Colors.grey.shade300),
@ -123,8 +124,8 @@ class MeasuresListWidget extends StatelessWidget {
TableRow( TableRow(
decoration: BoxDecoration(color: Colors.grey.shade100), decoration: BoxDecoration(color: Colors.grey.shade100),
children: [ children: [
const Padding( Padding(
padding: EdgeInsets.all(2), padding: const EdgeInsets.all(6),
child: Center( child: Center(
child: Text( child: Text(
'序号', '序号',
@ -132,8 +133,8 @@ class MeasuresListWidget extends StatelessWidget {
), ),
), ),
), ),
const Padding( Padding(
padding: EdgeInsets.all(8), padding: const EdgeInsets.all(8),
child: Center( child: Center(
child: Text( child: Text(
'安全措施', '安全措施',
@ -142,13 +143,14 @@ class MeasuresListWidget extends StatelessWidget {
), ),
), ),
Padding( Padding(
padding: const EdgeInsets.all(2), padding: const EdgeInsets.all(6),
child: Center( child: Center(
child: Text( child: Text(
isAllowEdit ? '操作' : '是否\n涉及', isAllowEdit ? '操作' : '是否\n涉及',
style: const TextStyle( style: const TextStyle(
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
), ),
textAlign: TextAlign.center,
), ),
), ),
), ),
@ -168,41 +170,48 @@ class MeasuresListWidget extends StatelessWidget {
for (var item in measuresList) for (var item in measuresList)
TableRow( TableRow(
children: [ children: [
//
Padding( Padding(
padding: const EdgeInsets.all(8), padding: const EdgeInsets.all(6),
child: Center( child: Center(
child: Text('${measuresList.indexOf(item) + 1}'), child:
Text('${measuresList.indexOf(item) + 1}'),
), ),
), ),
// + + // + +
Padding( Padding(
padding: const EdgeInsets.all(8), padding: const EdgeInsets.all(6),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
// //
Text( Text(
item['PROTECTIVE_MEASURES'] as String? ?? '', item['PROTECTIVE_MEASURES'] as String? ?? '',
softWrap: true,
), ),
// 14 + // 14 +
for (var i = 1; i <= 4; i++) for (var i = 1; i <= 4; i++)
if ((item['QUESTION$i'] as String?) if ((item['QUESTION$i'] as String?)
?.isNotEmpty ?? ?.isNotEmpty ??
false) false)
_buildQnA(item, i), _buildQnA(item, i),
// //
if (item.containsKey('IMG_PATH') && if (item.containsKey('IMG_PATH') &&
(item['IMG_PATH'] as String).isNotEmpty && (item['IMG_PATH'] as String).isNotEmpty &&
isShowSign) isShowSign)
Row( Padding(
children: [ padding: const EdgeInsets.only(top: 6),
..._buildImageRows( child: Row(
context, children: [
(item['IMG_PATH'] as String).split(','), ..._buildImageRows(
'', context,
8, (item['IMG_PATH'] as String).split(','),
), '',
], 8,
),
],
),
), ),
], ],
), ),
@ -210,92 +219,93 @@ class MeasuresListWidget extends StatelessWidget {
// / + // / +
Padding( Padding(
padding: const EdgeInsets.all(8), padding: const EdgeInsets.all(0),
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
// //
isAllowEdit isAllowEdit
? TextButton( ? TextButton(
onPressed: () { onPressed: () {
onSign?.call(item); onSign?.call(item);
}, },
child: Text( child: Text(
(item['SIGN_ITEM'] ?? '') (item['SIGN_ITEM'] ?? '')
.toString() .toString()
.isNotEmpty .isNotEmpty
? '已签字' ? '已签字'
: '签字', : '签字',
style: TextStyle( style: TextStyle(
color: color: (item['SIGN_ITEM'] ?? '')
(item['SIGN_ITEM'] ?? '') .toString()
.toString() .isNotEmpty
.isNotEmpty ? Colors.grey.shade600
? Colors.grey.shade600 : Colors.blue,
: Colors.blue,
),
),
)
: Text(
(item['STATUS'] as String?) == '-1'
? '不涉及'
: '涉及',
style: TextStyle(
color:
(item['STATUS'] as String?) == '-1'
? Colors.black
: Colors.black,
),
), ),
),
)
: Text(
(item['STATUS'] as String?) == '-1'
? '不涉及'
: '涉及',
style: const TextStyle(
color: Colors.black,
),
),
], ],
), ),
), ),
// //
if (!isAllowEdit) if (!isAllowEdit)
Column( Padding(
crossAxisAlignment: CrossAxisAlignment.center, padding: const EdgeInsets.all(6),
children: [ child: Column(
if (item.containsKey('SIGN_PATH') && crossAxisAlignment: CrossAxisAlignment.center,
(item['SIGN_PATH'] as String).isNotEmpty) children: [
...((item['SIGN_PATH'] as String) if (item.containsKey('SIGN_PATH') &&
.split(',') (item['SIGN_PATH'] as String).isNotEmpty)
.map((s) => s.trim()) ...((item['SIGN_PATH'] as String)
.where((s) => s.isNotEmpty)).map((path) { .split(',')
final imageUrl = '$baseImgPath$path'; .map((s) => s.trim())
return Padding( .where((s) => s.isNotEmpty)).map((path) {
padding: const EdgeInsets.only(top: 5), final imageUrl = '$baseImgPath$path';
child: Center( return Padding(
child: GestureDetector( padding: const EdgeInsets.only(top: 5),
onTap: () { child: Center(
presentOpaque( child: GestureDetector(
SingleImageViewer( onTap: () {
imageUrl: imageUrl, presentOpaque(
), SingleImageViewer(
context, imageUrl: imageUrl,
);
},
child: Image.network(
imageUrl,
width: 40,
height: 40,
fit: BoxFit.fill,
errorBuilder:
(_, __, ___) => Container(
width: 40,
height: 40,
color: Colors.grey.shade200,
child: const Icon(
Icons.broken_image,
size: 18,
color: Colors.grey,
),
), ),
context,
);
},
child: Image.network(
imageUrl,
width: 40,
height: 40,
fit: BoxFit.fill,
errorBuilder:
(_, __, ___) =>
Container(
width: 40,
height: 40,
color: Colors.grey.shade200,
child: const Icon(
Icons.broken_image,
size: 18,
color: Colors.grey,
),
),
),
), ),
), ),
), );
); }).toList(),
}).toList(), ],
], ),
), ),
], ],
), ),
@ -319,39 +329,46 @@ class MeasuresListWidget extends StatelessWidget {
return Padding( return Padding(
padding: const EdgeInsets.only(top: 8), padding: const EdgeInsets.only(top: 8),
child: Row( child: Row(
crossAxisAlignment: CrossAxisAlignment.start, //
children: [ children: [
Expanded( Expanded(
flex: 2, flex: 2,
child: Text( child: Container(
'$question:', padding: const EdgeInsets.only(right: 8), //
style: const TextStyle(fontWeight: FontWeight.w800), child: Text(
'$question:',
softWrap: true,
maxLines: 2,
overflow: TextOverflow.ellipsis, // visible null
style: const TextStyle(fontWeight: FontWeight.w800),
),
), ),
), ),
Expanded( Expanded(
flex: 1, flex: 1,
child: TextFormField( child: SizedBox(
initialValue: answer, child: TextFormField(
textAlign: TextAlign.center, initialValue: answer,
// textAlign: TextAlign.center,
keyboardType: TextInputType.number, keyboardType: TextInputType.number,
inputFormatters: [FilteringTextInputFormatter.digitsOnly], inputFormatters: [FilteringTextInputFormatter.digitsOnly],
decoration: InputDecoration( decoration: InputDecoration(
isDense: true, isDense: true,
contentPadding: const EdgeInsets.symmetric( contentPadding: const EdgeInsets.symmetric(
vertical: 8, vertical: 8,
horizontal: 4, horizontal: 4,
), ),
// enabledBorder: OutlineInputBorder(
enabledBorder: OutlineInputBorder( borderSide: BorderSide(color: Colors.grey.shade300),
borderSide: BorderSide(color: Colors.grey.shade300), ),
), focusedBorder: OutlineInputBorder(
focusedBorder: OutlineInputBorder( borderSide: BorderSide(color: Colors.grey.shade300),
borderSide: BorderSide(color: Colors.grey.shade300), ),
), ),
onChanged: (val) {
item[key] = val;
},
), ),
onChanged: (val) {
item[key] = val;
},
), ),
), ),
], ],
@ -359,25 +376,27 @@ class MeasuresListWidget extends StatelessWidget {
); );
} }
// //
return Padding( return Padding(
padding: const EdgeInsets.only(top: 8), padding: const EdgeInsets.only(top: 8, bottom: 6),
child: Column( child: Row(
children: [ children: [
Padding( Expanded(
padding: const EdgeInsets.symmetric(horizontal: 12), flex: 3,
child: Row( child: Text(
mainAxisAlignment: MainAxisAlignment.spaceBetween, '$question:',
children: [ style: const TextStyle(fontWeight: FontWeight.w800),
Text( softWrap: true,
'$question:', ),
style: const TextStyle(fontWeight: FontWeight.w800), ),
), const SizedBox(width: 12),
Text(answer.isNotEmpty ? answer : '0'), Expanded(
], flex: 1,
child: Text(
answer.isNotEmpty ? answer : '0',
textAlign: TextAlign.right,
), ),
), ),
const Divider(),
], ],
), ),
); );
@ -385,11 +404,11 @@ class MeasuresListWidget extends StatelessWidget {
/// + /// +
List<Widget> _buildImageRows( List<Widget> _buildImageRows(
BuildContext context, BuildContext context,
List<String> paths, List<String> paths,
String time, String time,
double right, double right,
) { ) {
if (paths.isEmpty) return []; if (paths.isEmpty) return [];
const int imagesPerRow = 4; const int imagesPerRow = 4;
@ -423,21 +442,19 @@ class MeasuresListWidget extends StatelessWidget {
fit: BoxFit.fill, fit: BoxFit.fill,
errorBuilder: errorBuilder:
(_, __, ___) => Container( (_, __, ___) => Container(
width: imageSize, width: imageSize,
height: imageSize, height: imageSize,
color: Colors.grey.shade200, color: Colors.grey.shade200,
child: const Icon( child: const Icon(
Icons.broken_image, Icons.broken_image,
size: 18, size: 18,
color: Colors.grey, color: Colors.grey,
), ),
), ),
), ),
), ),
if (i != rowPaths.length - 1) SizedBox(width: spacing), if (i != rowPaths.length - 1) SizedBox(width: spacing),
], ],
// 使 Expanded
// Expanded(child: SizedBox()),
], ],
), ),
); );
@ -445,6 +462,7 @@ class MeasuresListWidget extends StatelessWidget {
} }
} }
/// ///
class OtherMeasuresWidget extends StatelessWidget { class OtherMeasuresWidget extends StatelessWidget {
/// ///
@ -854,7 +872,7 @@ class SignaturesListWidget extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Padding( Padding(
padding: const EdgeInsets.all(8), padding: const EdgeInsets.all(5),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
@ -862,7 +880,7 @@ class SignaturesListWidget extends StatelessWidget {
label, label,
style: const TextStyle(fontWeight: FontWeight.bold), style: const TextStyle(fontWeight: FontWeight.bold),
), ),
const SizedBox(height: 4), const SizedBox(height: 2),
TextField( TextField(
controller: TextEditingController(text: descr), controller: TextEditingController(text: descr),
maxLines: null, maxLines: null,
@ -873,7 +891,7 @@ class SignaturesListWidget extends StatelessWidget {
), ),
), ),
Padding( Padding(
padding: const EdgeInsets.all(8), padding: const EdgeInsets.all(5),
child: Text('$personDes: $name'), child: Text('$personDes: $name'),
), ),
for (var i = 0; i < signPaths.length; i++) for (var i = 0; i < signPaths.length; i++)
@ -897,7 +915,7 @@ class SignaturesListWidget extends StatelessWidget {
(_, __, ___) => const Icon(Icons.broken_image), (_, __, ___) => const Icon(Icons.broken_image),
), ),
), ),
const SizedBox(width: 16), const SizedBox(width: 10),
Expanded( Expanded(
child: Text(i < signTimes.length ? signTimes[i] : ''), child: Text(i < signTimes.length ? signTimes[i] : ''),
), ),

View File

@ -167,13 +167,13 @@ class _HotWorkDetailFormWidgetState extends State<HotWorkDetailFormWidget> {
hintText: '请选择动火人及证书编号', hintText: '请选择动火人及证书编号',
onTap: widget.onChooseHotworkUser, onTap: widget.onChooseHotworkUser,
), ),
if (FormUtils.hasValue(pd, 'WORK_USER_DEPARTMENT_NAME') && if (FormUtils.hasValue(pd, 'UNIT_NAME') &&
!widget.isEditable) ...[ !widget.isEditable) ...[
const Divider(), const Divider(),
ItemListWidget.singleLineTitleText( ItemListWidget.singleLineTitleText(
label: '作业单位:', label: '作业单位:',
isEditable: false, isEditable: false,
text: pd['WORK_USER_DEPARTMENT_NAME'] ?? '', text: pd['UNIT_NAME'] ?? '',
), ),
], ],
if (FormUtils.hasValue(pd, 'CONFIRM_USER_NAME') && if (FormUtils.hasValue(pd, 'CONFIRM_USER_NAME') &&
@ -186,6 +186,14 @@ class _HotWorkDetailFormWidgetState extends State<HotWorkDetailFormWidget> {
text: pd['CONFIRM_USER_NAME'] ?? '', text: pd['CONFIRM_USER_NAME'] ?? '',
), ),
], ],
if (FormUtils.hasValue(pd, 'ANALYZE_TIME') && !widget.isEditable) ...[
const Divider(),
ItemListWidget.OneRowStartButtonTitle(
label: '气体分析信息:',
text: pd['ANALYZE_USER_NAME'] ?? '',
onTap: widget.onAnalyzeTap,
),
],
const Divider(), const Divider(),
ItemListWidget.twoRowButtonTitleText( ItemListWidget.twoRowButtonTitleText(
label: '关联其他特殊作业及安全作业票编号', label: '关联其他特殊作业及安全作业票编号',
@ -388,14 +396,7 @@ class _HotWorkDetailFormWidgetState extends State<HotWorkDetailFormWidget> {
text: pd['VIDEONAME'] ?? '', text: pd['VIDEONAME'] ?? '',
), ),
if (FormUtils.hasValue(pd, 'ANALYZE_TIME') && !widget.isEditable) ...[
const Divider(),
ItemListWidget.OneRowStartButtonTitle(
label: '气体分析信息:',
text: pd['ANALYZE_USER_NAME'] ?? '',
onTap: widget.onAnalyzeTap,
),
],
], ],
), ),
); );

View File

@ -1,18 +0,0 @@
import 'package:flutter/material.dart';
import 'package:qhd_prevention/pages/my_appbar.dart';
class HotSafeWorkChoosePage extends StatefulWidget {
const HotSafeWorkChoosePage({super.key});
@override
State<HotSafeWorkChoosePage> createState() => _HotSafeWorkChoosePageState();
}
class _HotSafeWorkChoosePageState extends State<HotSafeWorkChoosePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: MyAppbar(title: 'dong'),
);
}
}

View File

@ -364,35 +364,33 @@ class _HotWorkListPageState extends State<HotWorkListPage> {
overflow: TextOverflow.visible, 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( Expanded(
child: Text( child: Text(
"安全交底人: ${item['CONFESS_USER_NAME'] ?? ''}", "安全交底人: ${item['CONFESS_USER_NAME'] ?? ''}",
softWrap: true, softWrap: true,
maxLines: null, maxLines: null,
textAlign: TextAlign.right,
overflow: TextOverflow.visible, overflow: TextOverflow.visible,
), ),
), ),
const SizedBox(width: 8), ],
),
Row(
children: [
Expanded( Expanded(
child: Text( child: Text(
"接受交底人: ${item['ACCEPT_CONFESS_USER_NAME'] ?? ''}", "接受交底人: ${item['ACCEPT_CONFESS_USER_NAME'] ?? ''}",
softWrap: true,
maxLines: null,
overflow: TextOverflow.visible,
),
),
Expanded(
child: Text(
"作业负责人: ${item['CONFIRM_USER_NAME'] ?? ''}",
textAlign: TextAlign.right, textAlign: TextAlign.right,
softWrap: true, softWrap: true,
maxLines: null, maxLines: null,
@ -404,19 +402,10 @@ class _HotWorkListPageState extends State<HotWorkListPage> {
Row( Row(
children: [ children: [
Expanded(
child: Text(
"作业负责人: ${item['CONFIRM_USER_NAME'] ?? ''}",
softWrap: true,
maxLines: null,
overflow: TextOverflow.visible,
),
),
const SizedBox(width: 8),
Expanded( Expanded(
child: Text( child: Text(
"所在单位负责人: ${item['LEADER_USER_NAME'] ?? ''}", "所在单位负责人: ${item['LEADER_USER_NAME'] ?? ''}",
textAlign: TextAlign.right, textAlign: TextAlign.left,
softWrap: true, softWrap: true,
maxLines: null, maxLines: null,
overflow: TextOverflow.visible, overflow: TextOverflow.visible,

View File

@ -65,13 +65,17 @@ class _BlindboardApplyDetailState extends State<BlindboardApplyDetail> {
late List<dynamic> boardList = [ late List<dynamic> boardList = [
{'BOARD_MATERIAL': '', 'BOARD_SPECIFICATION': '', 'BOARD_NO': ''}, {'BOARD_MATERIAL': '', 'BOARD_SPECIFICATION': '', 'BOARD_NO': ''},
]; ];
/// ------------------- ------------------- /// ------------------- -------------------
/// ///
late List<dynamic> videoMonitoringList = []; late List<dynamic> videoMonitoringList = [];
/// ///
late List<dynamic> unitAllList = []; late List<dynamic> unitAllList = [];
/// ///
late List<dynamic> workAreaList = []; late List<dynamic> workAreaList = [];
/// -------------------------------------- /// --------------------------------------
late Map<String, dynamic> signs = {}; late Map<String, dynamic> signs = {};
late List<Map<String, dynamic>> measuresList = []; late List<Map<String, dynamic>> measuresList = [];
@ -86,8 +90,6 @@ class _BlindboardApplyDetailState extends State<BlindboardApplyDetail> {
final TextEditingController _relatedController = TextEditingController(); final TextEditingController _relatedController = TextEditingController();
final TextEditingController _riskController = TextEditingController(); final TextEditingController _riskController = TextEditingController();
// //
final Map<EditUserType, List<Map<String, dynamic>>> _personCache = {}; final Map<EditUserType, List<Map<String, dynamic>>> _personCache = {};
@ -105,7 +107,6 @@ class _BlindboardApplyDetailState extends State<BlindboardApplyDetail> {
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['IS_CONTRACTOR_WORK'] = '0'; pd['IS_CONTRACTOR_WORK'] = '0';
} }
_getVideoList(); _getVideoList();
@ -132,15 +133,16 @@ class _BlindboardApplyDetailState extends State<BlindboardApplyDetail> {
pd['RISK_IDENTIFICATION'] = _riskController.text.trim(); pd['RISK_IDENTIFICATION'] = _riskController.text.trim();
}); });
} }
/// ---------------------------- -------------------------------- /// ---------------------------- --------------------------------
/// ///
Future<void> _chooseVideoManager() async { Future<void> _chooseVideoManager() async {
final choice = await BottomPicker.show<String>( final choice = await BottomPicker.show<String>(
context, context,
items: items:
videoMonitoringList videoMonitoringList
.map((item) => item['VIDEONAME'] as String) .map((item) => item['VIDEONAME'] as String)
.toList(), .toList(),
itemBuilder: (item) => Text(item, textAlign: TextAlign.center), itemBuilder: (item) => Text(item, textAlign: TextAlign.center),
initialIndex: 0, initialIndex: 0,
); );
@ -149,7 +151,7 @@ class _BlindboardApplyDetailState extends State<BlindboardApplyDetail> {
pd['VIDEONAME'] = choice; pd['VIDEONAME'] = choice;
Map<String, dynamic> result = videoMonitoringList.firstWhere( Map<String, dynamic> result = videoMonitoringList.firstWhere(
(item) => item['VIDEONAME'] == choice, (item) => item['VIDEONAME'] == choice,
orElse: () => {}, // orElse: () => {}, //
); );
if (FormUtils.hasValue(result, 'VIDEOMANAGER_ID')) { if (FormUtils.hasValue(result, 'VIDEOMANAGER_ID')) {
@ -159,6 +161,7 @@ class _BlindboardApplyDetailState extends State<BlindboardApplyDetail> {
}); });
} }
} }
/// ///
Future<void> _chooseUnitManager() async { Future<void> _chooseUnitManager() async {
final choice = await BottomPicker.show<String>( final choice = await BottomPicker.show<String>(
@ -172,7 +175,7 @@ class _BlindboardApplyDetailState extends State<BlindboardApplyDetail> {
pd['UNITS_NAME'] = choice; pd['UNITS_NAME'] = choice;
Map<String, dynamic> result = unitAllList.firstWhere( Map<String, dynamic> result = unitAllList.firstWhere(
(item) => item['UNITS_NAME'] == choice, (item) => item['UNITS_NAME'] == choice,
orElse: () => {}, // orElse: () => {}, //
); );
if (FormUtils.hasValue(result, 'UNITS_ID')) { if (FormUtils.hasValue(result, 'UNITS_ID')) {
@ -183,9 +186,8 @@ class _BlindboardApplyDetailState extends State<BlindboardApplyDetail> {
} }
} }
/// ///
Future<void> _showLocationHandle() async{ Future<void> _showLocationHandle() async {
if (!FormUtils.hasValue(pd, 'ELECTRONIC_FENCE_AREA_ID')) { if (!FormUtils.hasValue(pd, 'ELECTRONIC_FENCE_AREA_ID')) {
ToastUtil.showNormal(context, '请选择作业区域'); ToastUtil.showNormal(context, '请选择作业区域');
return; return;
@ -194,10 +196,11 @@ class _BlindboardApplyDetailState extends State<BlindboardApplyDetail> {
setState(() { setState(() {
pd['LONGITUDE'] = mapData['longitue'] ?? ''; pd['LONGITUDE'] = mapData['longitue'] ?? '';
pd['LATITUDE'] = mapData['latitude'] ?? ''; pd['LATITUDE'] = mapData['latitude'] ?? '';
pd['LATITUDE_LONGITUDE'] = '${mapData['longitue'] ?? ''},${mapData['latitude'] ?? ''}'; pd['LATITUDE_LONGITUDE'] =
'${mapData['longitue'] ?? ''},${mapData['latitude'] ?? ''}';
}); });
} }
/// ///
Future<void> _getWorkArea() async { Future<void> _getWorkArea() async {
//FocusHelper.clearFocus(context); //FocusHelper.clearFocus(context);
@ -208,18 +211,19 @@ class _BlindboardApplyDetailState extends State<BlindboardApplyDetail> {
backgroundColor: Colors.transparent, backgroundColor: Colors.transparent,
builder: builder:
(_) => WorkAreaPicker( (_) => WorkAreaPicker(
onSelected: (String id, String POSITIONS, String name) { onSelected: (String id, String POSITIONS, String name) {
setState(() { setState(() {
pd['ELECTRONIC_FENCE_AREA_ID'] = id; pd['ELECTRONIC_FENCE_AREA_ID'] = id;
pd['POSITIONS'] = POSITIONS; pd['POSITIONS'] = POSITIONS;
pd['PLS_NAME'] = name; pd['PLS_NAME'] = name;
}); });
}, },
), ),
).then((_) { ).then((_) {
//FocusHelper.clearFocus(context); //FocusHelper.clearFocus(context);
}); });
} }
/// ///
Future<void> _getVideoList() async { Future<void> _getVideoList() async {
final result = await ApiService.getVideomanagerList(); final result = await ApiService.getVideomanagerList();
@ -227,6 +231,7 @@ class _BlindboardApplyDetailState extends State<BlindboardApplyDetail> {
videoMonitoringList = result['varList'] ?? []; videoMonitoringList = result['varList'] ?? [];
}); });
} }
/// ///
Future<void> _getUnitListAll() async { Future<void> _getUnitListAll() async {
final result = await ApiService.getUnitListAll(); final result = await ApiService.getUnitListAll();
@ -316,7 +321,7 @@ class _BlindboardApplyDetailState extends State<BlindboardApplyDetail> {
isEditable: isEditable, isEditable: isEditable,
isClean: isClean, isClean: isClean,
onTapClean: () { onTapClean: () {
ToastUtil.showNormal(context, '已清除'); ToastUtil.showNormal(context, '已清除');
setState(() { setState(() {
set_pd_USER_ID(type, ''); set_pd_USER_ID(type, '');
set_pd_USER_Name(type, ''); set_pd_USER_Name(type, '');
@ -440,9 +445,23 @@ class _BlindboardApplyDetailState extends State<BlindboardApplyDetail> {
]; ];
final level = pd['WORK_TYPE'] ?? ''; final level = pd['WORK_TYPE'] ?? '';
print('---level-$level'); print('---level-$level');
int index = 0;
for (Map item in boardList) { for (Map item in boardList) {
if (!FormUtils.hasValue(item, 'BOARD_MATERIAL')) {
ToastUtil.showNormal(context, '请填写盲板抽堵参数第${index+1}项材质');
return;
}
if (!FormUtils.hasValue(item, 'BOARD_SPECIFICATION')) {
ToastUtil.showNormal(context, '请填写盲板抽堵参数第${index+1}项规格');
return;
}
if (!FormUtils.hasValue(item, 'BOARD_NO')) {
ToastUtil.showNormal(context, '请填写盲板抽堵参数第${index+1}项编号');
return;
}
index += 1;
} }
/// ///
final unitRules = <EditUserType>[ final unitRules = <EditUserType>[
EditUserType.GUARDIAN, EditUserType.GUARDIAN,
@ -478,7 +497,8 @@ class _BlindboardApplyDetailState extends State<BlindboardApplyDetail> {
return; return;
} }
if (pd['IS_CONTRACTOR_WORK'] == '1' && !FormUtils.hasValue(pd, 'UNITS_ID')) { if (pd['IS_CONTRACTOR_WORK'] == '1' &&
!FormUtils.hasValue(pd, 'UNITS_ID')) {
ToastUtil.showNormal(context, '请选择承包商'); ToastUtil.showNormal(context, '请选择承包商');
return; return;
} }
@ -510,7 +530,8 @@ 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'] : ''; 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;
@ -548,8 +569,6 @@ class _BlindboardApplyDetailState extends State<BlindboardApplyDetail> {
} }
} }
/// ///
Future<void> _getData() async { Future<void> _getData() async {
final data = await ApiService.getHomeworkFindById( final data = await ApiService.getHomeworkFindById(

View File

@ -16,7 +16,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
# In Windows, build-name is used as the major, minor, and patch parts # In Windows, build-name is used as the major, minor, and patch parts
# of the product and file versions while build-number is used as the build suffix. # of the product and file versions while build-number is used as the build suffix.
version: 2.1.2+9 version: 2.1.2+10
environment: environment:
sdk: ^3.7.0 sdk: ^3.7.0