特殊作业修改0602
parent
7f21c22d66
commit
7191c4f42f
|
|
@ -0,0 +1,152 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:qhd_prevention/tools/click_util.dart';
|
||||
|
||||
class GuardedGestureDetector extends StatelessWidget {
|
||||
final Widget child;
|
||||
final GuardedTapCallback? onTap;
|
||||
final Object? guardKey;
|
||||
final int delayMs;
|
||||
final bool lockDuringExecution;
|
||||
final HitTestBehavior? behavior;
|
||||
|
||||
const GuardedGestureDetector({
|
||||
super.key,
|
||||
required this.child,
|
||||
this.onTap,
|
||||
this.guardKey,
|
||||
this.delayMs = ClickUtil.defaultDelayMs,
|
||||
this.lockDuringExecution = true,
|
||||
this.behavior,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return GestureDetector(
|
||||
behavior: behavior,
|
||||
onTap: ClickUtil.wrap(
|
||||
onTap,
|
||||
key: guardKey,
|
||||
delayMs: delayMs,
|
||||
lockDuringExecution: lockDuringExecution,
|
||||
),
|
||||
child: child,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class GuardedInkWell extends StatelessWidget {
|
||||
final Widget child;
|
||||
final GuardedTapCallback? onTap;
|
||||
final Object? guardKey;
|
||||
final int delayMs;
|
||||
final bool lockDuringExecution;
|
||||
final BorderRadius? borderRadius;
|
||||
final Color? splashColor;
|
||||
final Color? highlightColor;
|
||||
|
||||
const GuardedInkWell({
|
||||
super.key,
|
||||
required this.child,
|
||||
this.onTap,
|
||||
this.guardKey,
|
||||
this.delayMs = ClickUtil.defaultDelayMs,
|
||||
this.lockDuringExecution = true,
|
||||
this.borderRadius,
|
||||
this.splashColor,
|
||||
this.highlightColor,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return InkWell(
|
||||
borderRadius: borderRadius,
|
||||
splashColor: splashColor,
|
||||
highlightColor: highlightColor,
|
||||
onTap: ClickUtil.wrap(
|
||||
onTap,
|
||||
key: guardKey,
|
||||
delayMs: delayMs,
|
||||
lockDuringExecution: lockDuringExecution,
|
||||
),
|
||||
child: child,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class GuardedTextButton extends StatelessWidget {
|
||||
final Widget child;
|
||||
final GuardedTapCallback? onPressed;
|
||||
final Object? guardKey;
|
||||
final int delayMs;
|
||||
final bool lockDuringExecution;
|
||||
final ButtonStyle? style;
|
||||
|
||||
const GuardedTextButton({
|
||||
super.key,
|
||||
required this.child,
|
||||
this.onPressed,
|
||||
this.guardKey,
|
||||
this.delayMs = ClickUtil.defaultDelayMs,
|
||||
this.lockDuringExecution = true,
|
||||
this.style,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return TextButton(
|
||||
style: style,
|
||||
onPressed: ClickUtil.wrap(
|
||||
onPressed,
|
||||
key: guardKey,
|
||||
delayMs: delayMs,
|
||||
lockDuringExecution: lockDuringExecution,
|
||||
),
|
||||
child: child,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class GuardedIconButton extends StatelessWidget {
|
||||
final Widget icon;
|
||||
final GuardedTapCallback? onPressed;
|
||||
final Object? guardKey;
|
||||
final int delayMs;
|
||||
final bool lockDuringExecution;
|
||||
final EdgeInsetsGeometry? padding;
|
||||
final BoxConstraints? constraints;
|
||||
final double? iconSize;
|
||||
final String? tooltip;
|
||||
final Color? color;
|
||||
|
||||
const GuardedIconButton({
|
||||
super.key,
|
||||
required this.icon,
|
||||
this.onPressed,
|
||||
this.guardKey,
|
||||
this.delayMs = ClickUtil.defaultDelayMs,
|
||||
this.lockDuringExecution = true,
|
||||
this.padding,
|
||||
this.constraints,
|
||||
this.iconSize,
|
||||
this.tooltip,
|
||||
this.color,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return IconButton(
|
||||
icon: icon,
|
||||
padding: padding,
|
||||
constraints: constraints,
|
||||
iconSize: iconSize,
|
||||
tooltip: tooltip,
|
||||
color: color,
|
||||
onPressed: ClickUtil.wrap(
|
||||
onPressed,
|
||||
key: guardKey,
|
||||
delayMs: delayMs,
|
||||
lockDuringExecution: lockDuringExecution,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -48,6 +48,7 @@ abstract class SpecialWorkApplyBaseState<T extends SpecialWorkApplyBasePage>
|
|||
extends State<T> {
|
||||
bool isEditable = true;
|
||||
bool loadingInit = false;
|
||||
bool _isSubmitting = false;
|
||||
|
||||
List<dynamic> levelList = [];
|
||||
final List<String> workTypeList = const ["内部作业", "相关方作业"];
|
||||
|
|
@ -856,44 +857,48 @@ abstract class SpecialWorkApplyBaseState<T extends SpecialWorkApplyBasePage>
|
|||
|
||||
/// 通用提交入口
|
||||
Future<void> submit(String status) async {
|
||||
await beforeSubmit(status);
|
||||
if (!FormUtils.hasValue(pd, 'workLevel')) {
|
||||
ToastUtil.showNormal(context, '请选择作业等级');
|
||||
return;
|
||||
}
|
||||
final preparers =
|
||||
enableSafeProtection
|
||||
? safeController.buildPreparers()
|
||||
: <Map<String, dynamic>>[];
|
||||
if (_isSubmitting) return;
|
||||
|
||||
final newGroups = await handleSignLogs(preparers);
|
||||
_isSubmitting = true;
|
||||
LoadingDialogHelper.show();
|
||||
|
||||
if (status == '1') {
|
||||
if (!await checkForm(newGroups)) {
|
||||
try {
|
||||
await beforeSubmit(status);
|
||||
if (!FormUtils.hasValue(pd, 'workLevel')) {
|
||||
ToastUtil.showNormal(context, '请选择作业等级');
|
||||
return;
|
||||
}
|
||||
final preparers =
|
||||
enableSafeProtection
|
||||
? safeController.buildPreparers()
|
||||
: <Map<String, dynamic>>[];
|
||||
|
||||
if (enableSafeProtection) {
|
||||
final err = safeController.validate(isSubmit: true);
|
||||
if (err != null) {
|
||||
ToastUtil.showNormal(context, err);
|
||||
final newGroups = await handleSignLogs(preparers);
|
||||
|
||||
if (status == '1') {
|
||||
if (!await checkForm(newGroups)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (enableSafeProtection) {
|
||||
final err = safeController.validate(isSubmit: true);
|
||||
if (err != null) {
|
||||
ToastUtil.showNormal(context, err);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!await validateExtraForm()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!await validateExtraForm()) {
|
||||
if (!await preSubmitUpload()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!await preSubmitUpload()) {
|
||||
return;
|
||||
}
|
||||
final payload = await buildSubmitPayload(status, newGroups);
|
||||
|
||||
final payload = await buildSubmitPayload(status, newGroups);
|
||||
|
||||
LoadingDialogHelper.show();
|
||||
try {
|
||||
final result =
|
||||
status == '1'
|
||||
? await SpecialWorkApi.specialWorkSave(payload, workType)
|
||||
|
|
@ -909,6 +914,7 @@ abstract class SpecialWorkApplyBaseState<T extends SpecialWorkApplyBasePage>
|
|||
ToastUtil.showNormal(context, '作业提交失败:$e');
|
||||
} finally {
|
||||
LoadingDialogHelper.dismiss();
|
||||
_isSubmitting = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ abstract class SpecialWorkTaskPageBase extends StatefulWidget {
|
|||
/// 子类可重写:提交成功后怎么返回。
|
||||
/// 默认返回上一页。
|
||||
void onSubmitSuccess(BuildContext context) {
|
||||
Navigator.of(context).pop();
|
||||
Navigator.of(context).pop(true);
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
@ -132,6 +132,8 @@ class _SpecialWorkTaskPageBaseState extends State<SpecialWorkTaskPageBase> {
|
|||
/// 备注/意见输入
|
||||
final TextEditingController _contentController = TextEditingController();
|
||||
|
||||
bool _isSubmitting = false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
|
@ -273,11 +275,22 @@ class _SpecialWorkTaskPageBaseState extends State<SpecialWorkTaskPageBase> {
|
|||
/// - 是否定位
|
||||
/// - 是否需要额外附件/人数/日期
|
||||
Future<void> _submit(String status) async {
|
||||
if (_isSubmitting) return;
|
||||
|
||||
_isSubmitting = true;
|
||||
LoadingDialogHelper.show();
|
||||
|
||||
void finishSubmit() {
|
||||
LoadingDialogHelper.hide();
|
||||
_isSubmitting = false;
|
||||
}
|
||||
|
||||
final Map<String, dynamic> others = {};
|
||||
bool isDelayTime = true;
|
||||
|
||||
if (pd['componentName'] == 'completeDelayTime' && other['isCompleteWork'] == 1) {
|
||||
if (other['isDelayWork'] == 1 && !FormUtils.hasValue(other, 'hotTime')) {
|
||||
finishSubmit();
|
||||
ToastUtil.showNormal(context, '请选择动火日期');
|
||||
return;
|
||||
}
|
||||
|
|
@ -299,6 +312,7 @@ class _SpecialWorkTaskPageBaseState extends State<SpecialWorkTaskPageBase> {
|
|||
context,
|
||||
'【$stepName】未完成,当前填写$currentFilllTimes次,应填写$minFillTimes次,无法流转到下一步',
|
||||
);
|
||||
finishSubmit();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -314,6 +328,7 @@ class _SpecialWorkTaskPageBaseState extends State<SpecialWorkTaskPageBase> {
|
|||
if (qNumber.isNotEmpty) {
|
||||
for (var i = 0; i < qNumber.length; i++) {
|
||||
if (qNumber[i].isNotEmpty && (i >= aNumber.length || aNumber[i].isEmpty)) {
|
||||
finishSubmit();
|
||||
ToastUtil.showNormal(context, '安全防护措施第${index + 1}项未填写内容');
|
||||
return;
|
||||
}
|
||||
|
|
@ -321,11 +336,13 @@ class _SpecialWorkTaskPageBaseState extends State<SpecialWorkTaskPageBase> {
|
|||
}
|
||||
|
||||
if ('${measure['status']}' == '-1' && widget.mesureText.isNotEmpty) {
|
||||
finishSubmit();
|
||||
ToastUtil.showNormal(context, '存在不合格的安全措施,请打回');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!FormUtils.hasValue(measure, 'signPath')) {
|
||||
finishSubmit();
|
||||
ToastUtil.showNormal(context, '安全防护措施第${index + 1}项请签字');
|
||||
return;
|
||||
}
|
||||
|
|
@ -336,6 +353,7 @@ class _SpecialWorkTaskPageBaseState extends State<SpecialWorkTaskPageBase> {
|
|||
// 3) 定位必填
|
||||
if (FormUtils.hasValue(pd, 'locateStepFlag') && pd['locateStepFlag'] == 1) {
|
||||
if (pd['longitude'] == null || pd['latitude'] == null) {
|
||||
finishSubmit();
|
||||
ToastUtil.showNormal(context, '请定位');
|
||||
return;
|
||||
}
|
||||
|
|
@ -347,6 +365,7 @@ class _SpecialWorkTaskPageBaseState extends State<SpecialWorkTaskPageBase> {
|
|||
final selectLevel = group['selectLevel'];
|
||||
if (selectLevel != 1 && other['isCompleteWork'] != 998) {
|
||||
if (!(FormUtils.hasValue(other, 'isDelayWork') && other['isDelayWork'] == 1)) {
|
||||
finishSubmit();
|
||||
ToastUtil.showNormal(context, '请选择${group['actorField'] ?? '处理人'}');
|
||||
return;
|
||||
}
|
||||
|
|
@ -357,9 +376,11 @@ class _SpecialWorkTaskPageBaseState extends State<SpecialWorkTaskPageBase> {
|
|||
// 5) 签字必填
|
||||
if (signImages.isEmpty) {
|
||||
if (!FormUtils.hasValue(other, 'isCompleteWork')) {
|
||||
finishSubmit();
|
||||
ToastUtil.showNormal(context, '请签字');
|
||||
return;
|
||||
} else if (other['isCompleteWork'] == 1) {
|
||||
finishSubmit();
|
||||
ToastUtil.showNormal(context, '请签字');
|
||||
return;
|
||||
}
|
||||
|
|
@ -404,17 +425,16 @@ class _SpecialWorkTaskPageBaseState extends State<SpecialWorkTaskPageBase> {
|
|||
form['signLogs'] = _groups;
|
||||
}
|
||||
|
||||
LoadingDialogHelper.show();
|
||||
final signResult = await _checkSignature();
|
||||
if (!signResult) {
|
||||
LoadingDialogHelper.hide();
|
||||
finishSubmit();
|
||||
ToastUtil.showNormal(context, '作业提交失败');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
final res = await SpecialWorkApi.specialWorkNextStep(form);
|
||||
LoadingDialogHelper.hide();
|
||||
finishSubmit();
|
||||
if (res['success'] == true) {
|
||||
ToastUtil.showNormal(context, '提交成功');
|
||||
widget.onSubmitSuccess(context);
|
||||
|
|
@ -422,7 +442,7 @@ class _SpecialWorkTaskPageBaseState extends State<SpecialWorkTaskPageBase> {
|
|||
ToastUtil.showNormal(context, res['errMessage'] ?? '作业提交失败');
|
||||
}
|
||||
} catch (e) {
|
||||
LoadingDialogHelper.hide();
|
||||
finishSubmit();
|
||||
ToastUtil.showNormal(context, '作业提交失败');
|
||||
}
|
||||
}
|
||||
|
|
@ -666,11 +686,12 @@ class _SpecialWorkTaskPageBaseState extends State<SpecialWorkTaskPageBase> {
|
|||
barrierDismissible:false,
|
||||
);
|
||||
if (confirmed != null) {
|
||||
if (confirmed.trim().isNotEmpty) {
|
||||
if (!mounted) return;
|
||||
final rejectText = confirmed.trim();
|
||||
if (rejectText.isNotEmpty) {
|
||||
setState(() {
|
||||
rejectReason = '${confirmed}';
|
||||
rejectReason = rejectText;
|
||||
});
|
||||
Navigator.pop(context);
|
||||
_submit('2');
|
||||
}else{
|
||||
ToastUtil.showError(context, '请输入打回原因');
|
||||
|
|
|
|||
|
|
@ -449,6 +449,12 @@ class _SpecialWorkWaitPageBaseState extends State<SpecialWorkWaitPageBase> {
|
|||
}
|
||||
}
|
||||
|
||||
Future<void> _handleOpenDetail(Map<String, dynamic> item, bool isEdit) async {
|
||||
await widget.onOpenDetail(context, item, isEdit);
|
||||
if (!mounted) return;
|
||||
_refreshList();
|
||||
}
|
||||
|
||||
Widget _buildListItem(Map<String, dynamic> item) {
|
||||
final workInfo = widget.getWorkInfo(item);
|
||||
final info = widget.getInfo(workInfo);
|
||||
|
|
@ -456,12 +462,12 @@ class _SpecialWorkWaitPageBaseState extends State<SpecialWorkWaitPageBase> {
|
|||
|
||||
// 准备按钮回调
|
||||
final onFlowTap = () => _openFlowDrawer(item);
|
||||
final onViewTap = () => widget.onOpenDetail(context, item, false);
|
||||
final onViewTap = () => _handleOpenDetail(item, false);
|
||||
final onWithdrawTap = widget.canWithdraw(item, workInfo) ? () => _handleWithdraw(item) : null;
|
||||
final onDeleteTap = widget.canDeleteAndEdit(item, workInfo) ? () => _handleDelete(item) : null;
|
||||
final onEditTap = widget.canDeleteAndEdit(item, workInfo) ? () => widget.onOpenDetail(context, item, true) : null;
|
||||
final onApproveTap = widget.canApprove(item, workInfo) ? () => widget.onOpenDetail(context, item, true) : null;
|
||||
final onGasAnalysisTap = widget.isGasStep(item) ? () => widget.onOpenDetail(context, item, true) : null;
|
||||
final onEditTap = widget.canDeleteAndEdit(item, workInfo) ? () => _handleOpenDetail(item, true) : null;
|
||||
final onApproveTap = widget.canApprove(item, workInfo) ? () => _handleOpenDetail(item, true) : null;
|
||||
final onGasAnalysisTap = widget.isGasStep(item) ? () => _handleOpenDetail(item, true) : null;
|
||||
|
||||
return Card(
|
||||
color: Colors.white,
|
||||
|
|
|
|||
Loading…
Reference in New Issue