Compare commits
3 Commits
c7b315e5b1
...
5edff0f2e2
| Author | SHA1 | Date |
|---|---|---|
|
|
5edff0f2e2 | |
|
|
1362a301c0 | |
|
|
3c4e30bc88 |
|
|
@ -476,6 +476,11 @@ enum UploadFileType {
|
||||||
'410',
|
'410',
|
||||||
'special_operation_special_apply_involved_signature',
|
'special_operation_special_apply_involved_signature',
|
||||||
),
|
),
|
||||||
|
// 进出有限空间记录 - 类型: '411',
|
||||||
|
specialOperationInAndOutRecord(
|
||||||
|
'411',
|
||||||
|
'special_operation_in_and_out_record',
|
||||||
|
),
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -926,7 +926,7 @@ class ItemListWidget {
|
||||||
required VoidCallback? onTapFile, // 第一行点击回调
|
required VoidCallback? onTapFile, // 第一行点击回调
|
||||||
double fontSize = 14, // 字体大小
|
double fontSize = 14, // 字体大小
|
||||||
bool isEdit = true,
|
bool isEdit = true,
|
||||||
String buttonText = '气体分析详情',
|
String buttonText = '',
|
||||||
double horizontalnum = horizontal_inset,
|
double horizontalnum = horizontal_inset,
|
||||||
bool isRequired = false,
|
bool isRequired = false,
|
||||||
final String fileUrl = '',
|
final String fileUrl = '',
|
||||||
|
|
@ -991,7 +991,7 @@ class ItemListWidget {
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (isEdit)
|
if (isEdit && buttonText.isNotEmpty)
|
||||||
CustomButton(
|
CustomButton(
|
||||||
text: buttonText,
|
text: buttonText,
|
||||||
height: 30,
|
height: 30,
|
||||||
|
|
|
||||||
|
|
@ -169,6 +169,10 @@ class SafeProtectionController extends ChangeNotifier {
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void refresh() {
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
void ensureAtLeastOneGroup() {
|
void ensureAtLeastOneGroup() {
|
||||||
if (_groups.isEmpty) {
|
if (_groups.isEmpty) {
|
||||||
addGroup();
|
addGroup();
|
||||||
|
|
@ -359,6 +363,7 @@ class SafeProtectionModule extends StatefulWidget {
|
||||||
this.title = '安全防护措施',
|
this.title = '安全防护措施',
|
||||||
this.otherTitle = '其他安全措施',
|
this.otherTitle = '其他安全措施',
|
||||||
this.showOtherSection = false,
|
this.showOtherSection = false,
|
||||||
|
this.showAddButton = false,
|
||||||
this.onChanged,
|
this.onChanged,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -372,6 +377,7 @@ class SafeProtectionModule extends StatefulWidget {
|
||||||
final String title;
|
final String title;
|
||||||
final String otherTitle;
|
final String otherTitle;
|
||||||
final bool showOtherSection;
|
final bool showOtherSection;
|
||||||
|
final bool showAddButton;
|
||||||
final SafeMeasuresChanged? onChanged;
|
final SafeMeasuresChanged? onChanged;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
@ -451,18 +457,24 @@ class _SafeProtectionModuleState extends State<SafeProtectionModule> {
|
||||||
onSelectedWithData: (updateId, name, data) {
|
onSelectedWithData: (updateId, name, data) {
|
||||||
setState(() {
|
setState(() {
|
||||||
for (SafeMeasureGroup g in widget.controller.groups) {
|
for (SafeMeasureGroup g in widget.controller.groups) {
|
||||||
// 判重updateId
|
if (widget.controller.groups.length > 1 &&
|
||||||
if (g.updateId == updateId && widget.controller.groups.length > 1) {
|
g != group &&
|
||||||
|
g.updateId == updateId) {
|
||||||
ToastUtil.showNormal(context, '确认人不能重复');
|
ToastUtil.showNormal(context, '确认人不能重复');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
group.updateId = updateId;
|
group.updateId = updateId;
|
||||||
group.updateName = name;
|
group.updateName = name;
|
||||||
group.actUser = data['actUserId'] ?? '';
|
group.actUser = updateId;
|
||||||
|
group.actUserName = name;
|
||||||
group.departmentId = data['departmentId'] ?? '';
|
group.departmentId = data['departmentId'] ?? '';
|
||||||
group.departmentName = data['departmentName'] ?? data['actUserDepartmentName'] ?? '';
|
group.departmentName =
|
||||||
|
data['departmentName'] ?? data['actUserDepartmentName'] ?? '';
|
||||||
|
group.actUserDepartment = group.departmentId;
|
||||||
|
group.actUserDepartmentName = group.departmentName;
|
||||||
});
|
});
|
||||||
|
widget.controller.refresh();
|
||||||
widget.onChanged?.call();
|
widget.onChanged?.call();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
@ -537,16 +549,17 @@ class _SafeProtectionModuleState extends State<SafeProtectionModule> {
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
ListItemFactory.createBuildSimpleSection(widget.title),
|
ListItemFactory.createBuildSimpleSection(widget.title),
|
||||||
CustomButton(
|
if (widget.showAddButton)
|
||||||
text: '添加',
|
CustomButton(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 15),
|
text: '添加',
|
||||||
backgroundColor: Colors.blue,
|
padding: const EdgeInsets.symmetric(horizontal: 15),
|
||||||
height: 32,
|
backgroundColor: Colors.blue,
|
||||||
onPressed:
|
height: 32,
|
||||||
widget.isEditable
|
onPressed:
|
||||||
? () => setState(() => widget.controller.addGroup())
|
widget.isEditable
|
||||||
: null,
|
? () => setState(() => widget.controller.addGroup())
|
||||||
),
|
: null,
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
...widget.controller.groups.asMap().entries.map((entry) {
|
...widget.controller.groups.asMap().entries.map((entry) {
|
||||||
|
|
@ -669,4 +682,4 @@ class _SafeProtectionModuleState extends State<SafeProtectionModule> {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -155,7 +155,7 @@ class _HotWorkDetailFormWidgetState extends State<HotWorkDetailFormWidget> {
|
||||||
),
|
),
|
||||||
const Divider(),
|
const Divider(),
|
||||||
ItemListWidget.selectableLineTitleTextRightButton(
|
ItemListWidget.selectableLineTitleTextRightButton(
|
||||||
label: '申请日期:',
|
label: '申请时间:',
|
||||||
text: pd['applyTime'] ?? '',
|
text: pd['applyTime'] ?? '',
|
||||||
isEditable: widget.isEditable,
|
isEditable: widget.isEditable,
|
||||||
onTap: () async {},
|
onTap: () async {},
|
||||||
|
|
|
||||||
|
|
@ -143,9 +143,9 @@ class _HotWorkApplyPageState extends SpecialWorkApplyBaseState<HotWorkApplyPage>
|
||||||
text: pd['applyUser'] ?? '',
|
text: pd['applyUser'] ?? '',
|
||||||
),
|
),
|
||||||
const Divider(),
|
const Divider(),
|
||||||
// 申请日期
|
// 申请时间
|
||||||
ItemListWidget.selectableLineTitleTextRightButton(
|
ItemListWidget.selectableLineTitleTextRightButton(
|
||||||
label: '申请日期:',
|
label: '申请时间:',
|
||||||
isEditable: isEditable,
|
isEditable: isEditable,
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
final picked = await BottomDateTimePicker.showDate(
|
final picked = await BottomDateTimePicker.showDate(
|
||||||
|
|
@ -507,4 +507,4 @@ class _HotWorkApplyPageState extends SpecialWorkApplyBaseState<HotWorkApplyPage>
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -144,7 +144,13 @@ class _BreakgroundDetailFormWidgetState extends State<BreakgroundDetailFormWidge
|
||||||
isEditable: false,
|
isEditable: false,
|
||||||
text: pd['applyUser'] ?? '',
|
text: pd['applyUser'] ?? '',
|
||||||
),
|
),
|
||||||
|
const Divider(),
|
||||||
|
ItemListWidget.selectableLineTitleTextRightButton(
|
||||||
|
label: '申请时间:',
|
||||||
|
text: pd['applyTime'] ?? '',
|
||||||
|
isEditable: widget.isEditable,
|
||||||
|
onTap: () async {},
|
||||||
|
),
|
||||||
const Divider(),
|
const Divider(),
|
||||||
ItemListWidget.selectableLineTitleTextRightButton(
|
ItemListWidget.selectableLineTitleTextRightButton(
|
||||||
label: '作业类型:',
|
label: '作业类型:',
|
||||||
|
|
|
||||||
|
|
@ -158,6 +158,27 @@ class _DlApplyPageState extends SpecialWorkApplyBaseState<DlApplyPage> {
|
||||||
text: pd['applyUser'] ?? '',
|
text: pd['applyUser'] ?? '',
|
||||||
),
|
),
|
||||||
const Divider(),
|
const Divider(),
|
||||||
|
ItemListWidget.selectableLineTitleTextRightButton(
|
||||||
|
label: '申请时间:',
|
||||||
|
isEditable: isEditable,
|
||||||
|
onTap: () async {
|
||||||
|
final picked = await BottomDateTimePicker.showDate(
|
||||||
|
mode: BottomPickerMode.dateTimeWithSeconds,
|
||||||
|
context,
|
||||||
|
allowFuture: true,
|
||||||
|
allowPast: false,
|
||||||
|
);
|
||||||
|
if (picked != null) {
|
||||||
|
setState(() {
|
||||||
|
pd['applyTime'] = DateFormat(
|
||||||
|
'yyyy-MM-dd HH:mm:ss',
|
||||||
|
).format(picked);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
text: pd['applyTime'] ?? '',
|
||||||
|
),
|
||||||
|
const Divider(),
|
||||||
// 作业类型(内部/相关方)
|
// 作业类型(内部/相关方)
|
||||||
if (enableInnerWorkSwitch) ...[
|
if (enableInnerWorkSwitch) ...[
|
||||||
ItemListWidget.selectableLineTitleTextRightButton(
|
ItemListWidget.selectableLineTitleTextRightButton(
|
||||||
|
|
@ -360,7 +381,7 @@ class _DlApplyPageState extends SpecialWorkApplyBaseState<DlApplyPage> {
|
||||||
groups[index]['actUserName'] = name;
|
groups[index]['actUserName'] = name;
|
||||||
groups[index]['actUserDepartment'] = data['departmentId'] ?? '';
|
groups[index]['actUserDepartment'] = data['departmentId'] ?? '';
|
||||||
groups[index]['actUserDepartmentName'] = data['departmentName'] ?? '';
|
groups[index]['actUserDepartmentName'] = data['departmentName'] ?? '';
|
||||||
|
syncSafeMeasureConfirmersWithGasAnalyzer(data);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
@ -433,4 +454,4 @@ class _DlApplyPageState extends SpecialWorkApplyBaseState<DlApplyPage> {
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -144,7 +144,13 @@ class _CutRoadDetailFormWidgetState extends State<CutRoadDetailFormWidget> {
|
||||||
isEditable: false,
|
isEditable: false,
|
||||||
text: pd['applyUser'] ?? '',
|
text: pd['applyUser'] ?? '',
|
||||||
),
|
),
|
||||||
|
const Divider(),
|
||||||
|
ItemListWidget.selectableLineTitleTextRightButton(
|
||||||
|
label: '申请时间:',
|
||||||
|
text: pd['applyTime'] ?? '',
|
||||||
|
isEditable: widget.isEditable,
|
||||||
|
onTap: () async {},
|
||||||
|
),
|
||||||
const Divider(),
|
const Divider(),
|
||||||
ItemListWidget.selectableLineTitleTextRightButton(
|
ItemListWidget.selectableLineTitleTextRightButton(
|
||||||
label: '作业类型:',
|
label: '作业类型:',
|
||||||
|
|
|
||||||
|
|
@ -157,6 +157,27 @@ class _DtApplyPageState extends SpecialWorkApplyBaseState<DtApplyPage> {
|
||||||
text: pd['applyUser'] ?? '',
|
text: pd['applyUser'] ?? '',
|
||||||
),
|
),
|
||||||
const Divider(),
|
const Divider(),
|
||||||
|
ItemListWidget.selectableLineTitleTextRightButton(
|
||||||
|
label: '申请时间:',
|
||||||
|
isEditable: isEditable,
|
||||||
|
onTap: () async {
|
||||||
|
final picked = await BottomDateTimePicker.showDate(
|
||||||
|
mode: BottomPickerMode.dateTimeWithSeconds,
|
||||||
|
context,
|
||||||
|
allowFuture: true,
|
||||||
|
allowPast: false,
|
||||||
|
);
|
||||||
|
if (picked != null) {
|
||||||
|
setState(() {
|
||||||
|
pd['applyTime'] = DateFormat(
|
||||||
|
'yyyy-MM-dd HH:mm:ss',
|
||||||
|
).format(picked);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
text: pd['applyTime'] ?? '',
|
||||||
|
),
|
||||||
|
const Divider(),
|
||||||
// 作业类型(内部/相关方)
|
// 作业类型(内部/相关方)
|
||||||
if (enableInnerWorkSwitch) ...[
|
if (enableInnerWorkSwitch) ...[
|
||||||
ItemListWidget.selectableLineTitleTextRightButton(
|
ItemListWidget.selectableLineTitleTextRightButton(
|
||||||
|
|
@ -346,7 +367,7 @@ class _DtApplyPageState extends SpecialWorkApplyBaseState<DtApplyPage> {
|
||||||
groups[index]['actUserName'] = name;
|
groups[index]['actUserName'] = name;
|
||||||
groups[index]['actUserDepartment'] = data['departmentId'] ?? '';
|
groups[index]['actUserDepartment'] = data['departmentId'] ?? '';
|
||||||
groups[index]['actUserDepartmentName'] = data['departmentName'] ?? '';
|
groups[index]['actUserDepartmentName'] = data['departmentName'] ?? '';
|
||||||
|
syncSafeMeasureConfirmersWithGasAnalyzer(data);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
@ -417,4 +438,4 @@ class _DtApplyPageState extends SpecialWorkApplyBaseState<DtApplyPage> {
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -152,6 +152,27 @@ class _DzApplyPageState extends SpecialWorkApplyBaseState<DzApplyPage> {
|
||||||
text: pd['applyUser'] ?? '',
|
text: pd['applyUser'] ?? '',
|
||||||
),
|
),
|
||||||
const Divider(),
|
const Divider(),
|
||||||
|
ItemListWidget.selectableLineTitleTextRightButton(
|
||||||
|
label: '申请时间:',
|
||||||
|
isEditable: isEditable,
|
||||||
|
onTap: () async {
|
||||||
|
final picked = await BottomDateTimePicker.showDate(
|
||||||
|
mode: BottomPickerMode.dateTimeWithSeconds,
|
||||||
|
context,
|
||||||
|
allowFuture: true,
|
||||||
|
allowPast: false,
|
||||||
|
);
|
||||||
|
if (picked != null) {
|
||||||
|
setState(() {
|
||||||
|
pd['applyTime'] = DateFormat(
|
||||||
|
'yyyy-MM-dd HH:mm:ss',
|
||||||
|
).format(picked);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
text: pd['applyTime'] ?? '',
|
||||||
|
),
|
||||||
|
const Divider(),
|
||||||
// 作业类型(内部/相关方)
|
// 作业类型(内部/相关方)
|
||||||
if (enableInnerWorkSwitch) ...[
|
if (enableInnerWorkSwitch) ...[
|
||||||
ItemListWidget.selectableLineTitleTextRightButton(
|
ItemListWidget.selectableLineTitleTextRightButton(
|
||||||
|
|
@ -357,7 +378,7 @@ class _DzApplyPageState extends SpecialWorkApplyBaseState<DzApplyPage> {
|
||||||
groups[index]['actUserName'] = name;
|
groups[index]['actUserName'] = name;
|
||||||
groups[index]['actUserDepartment'] = data['departmentId'] ?? '';
|
groups[index]['actUserDepartment'] = data['departmentId'] ?? '';
|
||||||
groups[index]['actUserDepartmentName'] = data['departmentName'] ?? '';
|
groups[index]['actUserDepartmentName'] = data['departmentName'] ?? '';
|
||||||
|
syncSafeMeasureConfirmersWithGasAnalyzer(data);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
@ -418,4 +439,4 @@ class _DzApplyPageState extends SpecialWorkApplyBaseState<DzApplyPage> {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -143,7 +143,13 @@ class _HoistingDetailFormWidgetState extends State<HoistingDetailFormWidget> {
|
||||||
isEditable: false,
|
isEditable: false,
|
||||||
text: pd['applyUser'] ?? '',
|
text: pd['applyUser'] ?? '',
|
||||||
),
|
),
|
||||||
|
const Divider(),
|
||||||
|
ItemListWidget.selectableLineTitleTextRightButton(
|
||||||
|
label: '申请时间:',
|
||||||
|
text: pd['applyTime'] ?? '',
|
||||||
|
isEditable: widget.isEditable,
|
||||||
|
onTap: () async {},
|
||||||
|
),
|
||||||
const Divider(),
|
const Divider(),
|
||||||
ItemListWidget.selectableLineTitleTextRightButton(
|
ItemListWidget.selectableLineTitleTextRightButton(
|
||||||
label: '作业类型:',
|
label: '作业类型:',
|
||||||
|
|
|
||||||
|
|
@ -140,7 +140,13 @@ class _HeighWorkDetailFormWidgetState extends State<HeighWorkDetailFormWidget> {
|
||||||
isEditable: false,
|
isEditable: false,
|
||||||
text: pd['applyUser'] ?? '',
|
text: pd['applyUser'] ?? '',
|
||||||
),
|
),
|
||||||
|
const Divider(),
|
||||||
|
ItemListWidget.selectableLineTitleTextRightButton(
|
||||||
|
label: '申请时间:',
|
||||||
|
text: pd['applyTime'] ?? '',
|
||||||
|
isEditable: widget.isEditable,
|
||||||
|
onTap: () async {},
|
||||||
|
),
|
||||||
const Divider(),
|
const Divider(),
|
||||||
ItemListWidget.selectableLineTitleTextRightButton(
|
ItemListWidget.selectableLineTitleTextRightButton(
|
||||||
label: '作业类型:',
|
label: '作业类型:',
|
||||||
|
|
|
||||||
|
|
@ -149,6 +149,27 @@ class _GcApplyPageState extends SpecialWorkApplyBaseState<GcApplyPage> {
|
||||||
text: pd['applyUser'] ?? '',
|
text: pd['applyUser'] ?? '',
|
||||||
),
|
),
|
||||||
const Divider(),
|
const Divider(),
|
||||||
|
ItemListWidget.selectableLineTitleTextRightButton(
|
||||||
|
label: '申请时间:',
|
||||||
|
isEditable: isEditable,
|
||||||
|
onTap: () async {
|
||||||
|
final picked = await BottomDateTimePicker.showDate(
|
||||||
|
mode: BottomPickerMode.dateTimeWithSeconds,
|
||||||
|
context,
|
||||||
|
allowFuture: true,
|
||||||
|
allowPast: false,
|
||||||
|
);
|
||||||
|
if (picked != null) {
|
||||||
|
setState(() {
|
||||||
|
pd['applyTime'] = DateFormat(
|
||||||
|
'yyyy-MM-dd HH:mm:ss',
|
||||||
|
).format(picked);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
text: pd['applyTime'] ?? '',
|
||||||
|
),
|
||||||
|
const Divider(),
|
||||||
// 作业类型
|
// 作业类型
|
||||||
if (enableInnerWorkSwitch) ...[
|
if (enableInnerWorkSwitch) ...[
|
||||||
ItemListWidget.selectableLineTitleTextRightButton(
|
ItemListWidget.selectableLineTitleTextRightButton(
|
||||||
|
|
@ -330,7 +351,7 @@ class _GcApplyPageState extends SpecialWorkApplyBaseState<GcApplyPage> {
|
||||||
groups[index]['actUserName'] = name;
|
groups[index]['actUserName'] = name;
|
||||||
groups[index]['actUserDepartment'] = data['departmentId'] ?? '';
|
groups[index]['actUserDepartment'] = data['departmentId'] ?? '';
|
||||||
groups[index]['actUserDepartmentName'] = data['departmentName'] ?? '';
|
groups[index]['actUserDepartmentName'] = data['departmentName'] ?? '';
|
||||||
|
syncSafeMeasureConfirmersWithGasAnalyzer(data);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
@ -390,4 +411,4 @@ class _GcApplyPageState extends SpecialWorkApplyBaseState<GcApplyPage> {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -146,6 +146,13 @@ class _LsydWorkDetailFormWidgetState extends State<LsydWorkDetailFormWidget> {
|
||||||
text: pd['applyUser'] ?? '',
|
text: pd['applyUser'] ?? '',
|
||||||
),
|
),
|
||||||
const Divider(),
|
const Divider(),
|
||||||
|
ItemListWidget.selectableLineTitleTextRightButton(
|
||||||
|
label: '申请时间:',
|
||||||
|
text: pd['applyTime'] ?? '',
|
||||||
|
isEditable: widget.isEditable,
|
||||||
|
onTap: () async {},
|
||||||
|
),
|
||||||
|
const Divider(),
|
||||||
ItemListWidget.selectableLineTitleTextRightButton(
|
ItemListWidget.selectableLineTitleTextRightButton(
|
||||||
label: '作业类型:',
|
label: '作业类型:',
|
||||||
isEditable: false,
|
isEditable: false,
|
||||||
|
|
|
||||||
|
|
@ -158,6 +158,27 @@ class _LsydApplyPageState extends SpecialWorkApplyBaseState<LsydApplyPage> {
|
||||||
text: pd['applyUser'] ?? '',
|
text: pd['applyUser'] ?? '',
|
||||||
),
|
),
|
||||||
const Divider(),
|
const Divider(),
|
||||||
|
ItemListWidget.selectableLineTitleTextRightButton(
|
||||||
|
label: '申请时间:',
|
||||||
|
isEditable: isEditable,
|
||||||
|
onTap: () async {
|
||||||
|
final picked = await BottomDateTimePicker.showDate(
|
||||||
|
mode: BottomPickerMode.dateTimeWithSeconds,
|
||||||
|
context,
|
||||||
|
allowFuture: true,
|
||||||
|
allowPast: false,
|
||||||
|
);
|
||||||
|
if (picked != null) {
|
||||||
|
setState(() {
|
||||||
|
pd['applyTime'] = DateFormat(
|
||||||
|
'yyyy-MM-dd HH:mm:ss',
|
||||||
|
).format(picked);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
text: pd['applyTime'] ?? '',
|
||||||
|
),
|
||||||
|
const Divider(),
|
||||||
// 作业类型
|
// 作业类型
|
||||||
if (enableInnerWorkSwitch) ...[
|
if (enableInnerWorkSwitch) ...[
|
||||||
ItemListWidget.selectableLineTitleTextRightButton(
|
ItemListWidget.selectableLineTitleTextRightButton(
|
||||||
|
|
@ -382,7 +403,7 @@ class _LsydApplyPageState extends SpecialWorkApplyBaseState<LsydApplyPage> {
|
||||||
groups[index]['actUserName'] = name;
|
groups[index]['actUserName'] = name;
|
||||||
groups[index]['actUserDepartment'] = data['departmentId'] ?? '';
|
groups[index]['actUserDepartment'] = data['departmentId'] ?? '';
|
||||||
groups[index]['actUserDepartmentName'] = data['departmentName'] ?? '';
|
groups[index]['actUserDepartmentName'] = data['departmentName'] ?? '';
|
||||||
|
syncSafeMeasureConfirmersWithGasAnalyzer(data);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
@ -435,4 +456,4 @@ class _LsydApplyPageState extends SpecialWorkApplyBaseState<LsydApplyPage> {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -194,7 +194,13 @@ class _MbcdDetailFormWidgetState extends State<MbcdDetailFormWidget> {
|
||||||
isEditable: false,
|
isEditable: false,
|
||||||
text: pd['applyUser'] ?? '',
|
text: pd['applyUser'] ?? '',
|
||||||
),
|
),
|
||||||
|
const Divider(),
|
||||||
|
ItemListWidget.selectableLineTitleTextRightButton(
|
||||||
|
label: '申请时间:',
|
||||||
|
text: pd['applyTime'] ?? '',
|
||||||
|
isEditable: widget.isEditable,
|
||||||
|
onTap: () async {},
|
||||||
|
),
|
||||||
const Divider(),
|
const Divider(),
|
||||||
ItemListWidget.selectableLineTitleTextRightButton(
|
ItemListWidget.selectableLineTitleTextRightButton(
|
||||||
label: '作业类型:',
|
label: '作业类型:',
|
||||||
|
|
|
||||||
|
|
@ -199,6 +199,27 @@ class _MbcdApplyPageState extends SpecialWorkApplyBaseState<MbcdApplyPage> {
|
||||||
text: pd['applyUser'] ?? '',
|
text: pd['applyUser'] ?? '',
|
||||||
),
|
),
|
||||||
const Divider(),
|
const Divider(),
|
||||||
|
ItemListWidget.selectableLineTitleTextRightButton(
|
||||||
|
label: '申请时间:',
|
||||||
|
isEditable: isEditable,
|
||||||
|
onTap: () async {
|
||||||
|
final picked = await BottomDateTimePicker.showDate(
|
||||||
|
mode: BottomPickerMode.dateTimeWithSeconds,
|
||||||
|
context,
|
||||||
|
allowFuture: true,
|
||||||
|
allowPast: false,
|
||||||
|
);
|
||||||
|
if (picked != null) {
|
||||||
|
setState(() {
|
||||||
|
pd['applyTime'] = DateFormat('yyyy-MM-dd HH:mm:ss').format(
|
||||||
|
picked,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
text: pd['applyTime'] ?? '',
|
||||||
|
),
|
||||||
|
const Divider(),
|
||||||
// 作业类型
|
// 作业类型
|
||||||
if (enableInnerWorkSwitch) ...[
|
if (enableInnerWorkSwitch) ...[
|
||||||
ItemListWidget.selectableLineTitleTextRightButton(
|
ItemListWidget.selectableLineTitleTextRightButton(
|
||||||
|
|
@ -584,4 +605,4 @@ class _MbcdApplyPageState extends SpecialWorkApplyBaseState<MbcdApplyPage> {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -143,7 +143,7 @@ class _SxkjWorkDetailFormWidgetState extends State<SxkjWorkDetailFormWidget> {
|
||||||
),
|
),
|
||||||
const Divider(),
|
const Divider(),
|
||||||
ItemListWidget.selectableLineTitleTextRightButton(
|
ItemListWidget.selectableLineTitleTextRightButton(
|
||||||
label: '申请日期:',
|
label: '申请时间:',
|
||||||
text: pd['applyTime'] ?? '',
|
text: pd['applyTime'] ?? '',
|
||||||
isEditable: widget.isEditable,
|
isEditable: widget.isEditable,
|
||||||
onTap: () async {},
|
onTap: () async {},
|
||||||
|
|
@ -176,12 +176,12 @@ class _SxkjWorkDetailFormWidgetState extends State<SxkjWorkDetailFormWidget> {
|
||||||
isRequired: true,
|
isRequired: true,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
const Divider(),
|
// const Divider(),
|
||||||
ItemListWidget.selectableLineTitleTextRightButton(
|
// ItemListWidget.selectableLineTitleTextRightButton(
|
||||||
label: '管理单位:',
|
// label: '管理单位:',
|
||||||
isEditable: widget.isEditable,
|
// isEditable: widget.isEditable,
|
||||||
text: chooseLimitedSpace['manageDeptName'] ?? '',
|
// text: chooseLimitedSpace['manageDeptName'] ?? '',
|
||||||
),
|
// ),
|
||||||
const Divider(),
|
const Divider(),
|
||||||
ItemListWidget.selectableLineTitleTextRightButton(
|
ItemListWidget.selectableLineTitleTextRightButton(
|
||||||
label: '有限空间名称及编号:',
|
label: '有限空间名称及编号:',
|
||||||
|
|
|
||||||
|
|
@ -75,39 +75,40 @@ class _SxkjApplyPageState extends SpecialWorkApplyBaseState<SxkjApplyPage> {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> loadExtraData() async {
|
Future<void> loadExtraData() async {
|
||||||
|
|
||||||
final data = {
|
final data = {
|
||||||
"eqWorkType": SpecialWorkTypeEnum.confinedspaceWork.code,
|
"eqWorkType": SpecialWorkTypeEnum.confinedspaceWork.code,
|
||||||
"pageSize": 999,
|
"pageSize": 999,
|
||||||
"pageIndex": 1,
|
"pageIndex": 1,
|
||||||
"eqCorpinfoId": pd['projectExecutionLocationCorpId'] ?? '',
|
"eqCorpinfoId": pd['projectExecutionLocationCorpId'] ?? '',
|
||||||
};
|
};
|
||||||
final limitedSpaceRes = await SpecialWorkApi.specialWorkLimitedSpaceList(data);
|
final limitedSpaceRes = await SpecialWorkApi.specialWorkLimitedSpaceList(
|
||||||
|
data,
|
||||||
|
);
|
||||||
if (limitedSpaceRes['success'] == true) {
|
if (limitedSpaceRes['success'] == true) {
|
||||||
limitedSpaceList = limitedSpaceRes['data'] ?? [];
|
limitedSpaceList = limitedSpaceRes['data'] ?? [];
|
||||||
}
|
}
|
||||||
// 清空有限空间台账选择的数据
|
// 清空有限空间台账选择的数据
|
||||||
_clearRelatedParties();
|
_clearRelatedParties();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _clearRelatedParties() async {
|
Future<void> _clearRelatedParties() async {
|
||||||
setState(() {
|
setState(() {
|
||||||
pd['limitedSpaceNameAndCode'] = '';
|
pd['limitedSpaceNameAndCode'] = '';
|
||||||
pd['chooseLimitedSpace'] = {};
|
pd['chooseLimitedSpace'] = {};
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> afterInitDataLoaded() async {
|
Future<void> afterInitDataLoaded() async {
|
||||||
// 初始化允许选择的人员列表(作业负责人和监护人)
|
// 初始化允许选择的人员列表(作业负责人和监护人)
|
||||||
allowChoosePerson = {
|
allowChoosePerson = {
|
||||||
'1' : {
|
'1': {
|
||||||
"actUser": pd['workGuardianUser'] ?? pd['workGuardianUserId'] ?? '',
|
"actUser": pd['workGuardianUser'] ?? pd['workGuardianUserId'] ?? '',
|
||||||
"actUserDepartment": pd['workGuardianUserDepartment'] ?? '',
|
"actUserDepartment": pd['workGuardianUserDepartment'] ?? '',
|
||||||
"actUserDepartmentName": pd['workGuardianUserDepartmentName'] ?? '',
|
"actUserDepartmentName": pd['workGuardianUserDepartmentName'] ?? '',
|
||||||
"actUserName": pd['workGuardianUserName'] ?? '',
|
"actUserName": pd['workGuardianUserName'] ?? '',
|
||||||
},
|
},
|
||||||
'2' : {
|
'2': {
|
||||||
"actUserDepartment": pd['workChargeUserDepartment'] ?? '',
|
"actUserDepartment": pd['workChargeUserDepartment'] ?? '',
|
||||||
"actUserDepartmentName": pd['workChargeUserDepartmentName'] ?? '',
|
"actUserDepartmentName": pd['workChargeUserDepartmentName'] ?? '',
|
||||||
"actUser": pd['workChargeUser'] ?? pd['workChargeUserId'] ?? '',
|
"actUser": pd['workChargeUser'] ?? pd['workChargeUserId'] ?? '',
|
||||||
|
|
@ -145,9 +146,10 @@ class _SxkjApplyPageState extends SpecialWorkApplyBaseState<SxkjApplyPage> {
|
||||||
Future<Map<String, dynamic>> buildExtraPayload() async {
|
Future<Map<String, dynamic>> buildExtraPayload() async {
|
||||||
final preparers = safeController.buildPreparers();
|
final preparers = safeController.buildPreparers();
|
||||||
return {
|
return {
|
||||||
'others': {'measures': preparers}
|
'others': {'measures': preparers},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget buildFormContent() {
|
Widget buildFormContent() {
|
||||||
final chooseLimitedSpace = (pd['chooseLimitedSpace'] as Map?) ?? {};
|
final chooseLimitedSpace = (pd['chooseLimitedSpace'] as Map?) ?? {};
|
||||||
|
|
@ -204,9 +206,9 @@ class _SxkjApplyPageState extends SpecialWorkApplyBaseState<SxkjApplyPage> {
|
||||||
text: pd['applyUser'] ?? '',
|
text: pd['applyUser'] ?? '',
|
||||||
),
|
),
|
||||||
const Divider(),
|
const Divider(),
|
||||||
// 申请日期
|
// 申请时间
|
||||||
ItemListWidget.selectableLineTitleTextRightButton(
|
ItemListWidget.selectableLineTitleTextRightButton(
|
||||||
label: '申请日期:',
|
label: '申请时间:',
|
||||||
isEditable: isEditable,
|
isEditable: isEditable,
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
final picked = await BottomDateTimePicker.showDate(
|
final picked = await BottomDateTimePicker.showDate(
|
||||||
|
|
@ -217,7 +219,9 @@ class _SxkjApplyPageState extends SpecialWorkApplyBaseState<SxkjApplyPage> {
|
||||||
);
|
);
|
||||||
if (picked != null) {
|
if (picked != null) {
|
||||||
setState(() {
|
setState(() {
|
||||||
pd['applyTime'] = DateFormat('yyyy-MM-dd HH:mm:ss').format(picked);
|
pd['applyTime'] = DateFormat(
|
||||||
|
'yyyy-MM-dd HH:mm:ss',
|
||||||
|
).format(picked);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -244,7 +248,6 @@ class _SxkjApplyPageState extends SpecialWorkApplyBaseState<SxkjApplyPage> {
|
||||||
groupValue: pd['internalOperationFlag'] == 1,
|
groupValue: pd['internalOperationFlag'] == 1,
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
setState(() {
|
setState(() {
|
||||||
isInnerWork = value;
|
|
||||||
pd['internalOperationFlag'] = value ? 1 : 2;
|
pd['internalOperationFlag'] = value ? 1 : 2;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
@ -266,15 +269,15 @@ class _SxkjApplyPageState extends SpecialWorkApplyBaseState<SxkjApplyPage> {
|
||||||
onTap: _chooseFromLedger,
|
onTap: _chooseFromLedger,
|
||||||
text: pd['limitedSpaceNameAndCode'] ?? '',
|
text: pd['limitedSpaceNameAndCode'] ?? '',
|
||||||
),
|
),
|
||||||
const Divider(),
|
// const Divider(),
|
||||||
// 管理单位(只读,来自台账)
|
// // 管理单位(只读,来自台账)
|
||||||
ItemListWidget.singleLineTitleText(
|
// ItemListWidget.singleLineTitleText(
|
||||||
label: '管理单位:',
|
// label: '管理单位:',
|
||||||
isEditable: false,
|
// isEditable: false,
|
||||||
isTextFont: false,
|
// isTextFont: false,
|
||||||
strongRequired: true,
|
// strongRequired: true,
|
||||||
text: chooseLimitedSpace['manageDeptName'] ?? '',
|
// text: chooseLimitedSpace['manageDeptName'] ?? '',
|
||||||
),
|
// ),
|
||||||
const Divider(),
|
const Divider(),
|
||||||
// 主要介质(只读)
|
// 主要介质(只读)
|
||||||
ItemListWidget.singleLineTitleText(
|
ItemListWidget.singleLineTitleText(
|
||||||
|
|
@ -333,7 +336,8 @@ class _SxkjApplyPageState extends SpecialWorkApplyBaseState<SxkjApplyPage> {
|
||||||
isTextFont: false,
|
isTextFont: false,
|
||||||
isRequired: isEditable,
|
isRequired: isEditable,
|
||||||
text: pd['emergencyEquipment'] ?? '',
|
text: pd['emergencyEquipment'] ?? '',
|
||||||
onChanged: (value) => setState(() => pd['emergencyEquipment'] = value),
|
onChanged:
|
||||||
|
(value) => setState(() => pd['emergencyEquipment'] = value),
|
||||||
),
|
),
|
||||||
// 重新编辑时展示详情组件
|
// 重新编辑时展示详情组件
|
||||||
if (widget.isReEdit && FormUtils.hasValue(form, 'id')) ...[
|
if (widget.isReEdit && FormUtils.hasValue(form, 'id')) ...[
|
||||||
|
|
@ -372,7 +376,8 @@ class _SxkjApplyPageState extends SpecialWorkApplyBaseState<SxkjApplyPage> {
|
||||||
label: '作业监护人',
|
label: '作业监护人',
|
||||||
isEditable: isEditable,
|
isEditable: isEditable,
|
||||||
text: pd['workGuardianUserName'] ?? '请选择',
|
text: pd['workGuardianUserName'] ?? '请选择',
|
||||||
onTap: () => _chooseAlonePersonHandle(SelectPersonType.workGuardian),
|
onTap:
|
||||||
|
() => _chooseAlonePersonHandle(SelectPersonType.workGuardian),
|
||||||
),
|
),
|
||||||
const Divider(),
|
const Divider(),
|
||||||
// 签字流程组(基类提供,但 stepId=3 会被隐藏,因为 shouldHideGroup 已重写)
|
// 签字流程组(基类提供,但 stepId=3 会被隐藏,因为 shouldHideGroup 已重写)
|
||||||
|
|
@ -405,22 +410,24 @@ class _SxkjApplyPageState extends SpecialWorkApplyBaseState<SxkjApplyPage> {
|
||||||
// 区分出两个数组、企业和相关方
|
// 区分出两个数组、企业和相关方
|
||||||
if (item['userType'] == 2) {
|
if (item['userType'] == 2) {
|
||||||
firmList.add(item);
|
firmList.add(item);
|
||||||
}else{
|
} else {
|
||||||
xgfList.add(item);
|
xgfList.add(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//0610修改,作业负责人和作业监护人需与选择的作业单位关联;作业单位肯定是相关方端,所以不考虑企业端
|
||||||
DepartmentAllPersonPicker.show(
|
DepartmentAllPersonPicker.show(
|
||||||
context,
|
context,
|
||||||
allowXgfFlag: xgfList.isNotEmpty,
|
allowXgfFlag: false,
|
||||||
personsData: firmList,
|
personsData: [...firmList,...xgfList],
|
||||||
serverData: xgfList,
|
serverData: [],
|
||||||
onSelectedWithData: (userId, name, data) {
|
onSelectedWithData: (userId, name, data) {
|
||||||
setState(() {
|
setState(() {
|
||||||
groups[index]['actUser'] = userId;
|
groups[index]['actUser'] = userId;
|
||||||
groups[index]['actUserName'] = name;
|
groups[index]['actUserName'] = name;
|
||||||
groups[index]['actUserDepartment'] = data['departmentId'] ?? '';
|
groups[index]['actUserDepartment'] = data['departmentId'] ?? '';
|
||||||
groups[index]['actUserDepartmentName'] = data['departmentName'] ?? '';
|
groups[index]['actUserDepartmentName'] =
|
||||||
|
data['departmentName'] ?? '';
|
||||||
|
syncSafeMeasureConfirmersWithGasAnalyzer(data);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
@ -441,13 +448,17 @@ class _SxkjApplyPageState extends SpecialWorkApplyBaseState<SxkjApplyPage> {
|
||||||
style: BottomPickerStyle.list,
|
style: BottomPickerStyle.list,
|
||||||
title: '有限空间名称及编号',
|
title: '有限空间名称及编号',
|
||||||
height: MediaQuery.of(context).size.height - 120,
|
height: MediaQuery.of(context).size.height - 120,
|
||||||
items: limitedSpaceList.map((item) => '${item['name']}(${item['code']})').toList(),
|
items:
|
||||||
itemBuilder: (item) => Text(
|
limitedSpaceList
|
||||||
item,
|
.map((item) => '${item['name']}(${item['code']})')
|
||||||
softWrap: true,
|
.toList(),
|
||||||
maxLines: 10,
|
itemBuilder:
|
||||||
overflow: TextOverflow.visible,
|
(item) => Text(
|
||||||
),
|
item,
|
||||||
|
softWrap: true,
|
||||||
|
maxLines: 10,
|
||||||
|
overflow: TextOverflow.visible,
|
||||||
|
),
|
||||||
initialIndex: 0,
|
initialIndex: 0,
|
||||||
withIndex: true,
|
withIndex: true,
|
||||||
);
|
);
|
||||||
|
|
@ -469,32 +480,43 @@ class _SxkjApplyPageState extends SpecialWorkApplyBaseState<SxkjApplyPage> {
|
||||||
isScrollControlled: true,
|
isScrollControlled: true,
|
||||||
barrierColor: Colors.black54,
|
barrierColor: Colors.black54,
|
||||||
backgroundColor: Colors.transparent,
|
backgroundColor: Colors.transparent,
|
||||||
builder: (_) => DepartmentPicker(
|
builder:
|
||||||
onSelected: (id, name, data) async {
|
(_) => DepartmentPicker(
|
||||||
setState(() {
|
onSelected: (id, name, data) async {
|
||||||
pd['workDepartment'] = id;
|
setState(() {
|
||||||
pd['workDepartmentName'] = name;
|
pd['workDepartment'] = id;
|
||||||
// 清空作业人(如果有联动需要)
|
pd['workDepartmentName'] = name;
|
||||||
});
|
// 清空作业人(如果有联动需要)
|
||||||
await _getPersonListForUnitId(id);
|
});
|
||||||
},
|
await _getPersonListForUnitId(id);
|
||||||
data: {'corpinfoId': pd['projectExecutionLocationCorpId'] ?? ''},
|
},
|
||||||
),
|
data: {'eqCorpinfoId': pd['xgfId'] ?? ''},
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 单独选择作业负责人或监护人
|
/// 单独选择作业负责人或监护人
|
||||||
void _chooseAlonePersonHandle(SelectPersonType type) {
|
void _chooseAlonePersonHandle(SelectPersonType type) {
|
||||||
List<dynamic> personList = allPersonList;
|
List<dynamic> personList = [];
|
||||||
List<dynamic> xgfList = relatedPartiesPersonList;
|
// List<dynamic> xgfList = relatedPartiesPersonList;
|
||||||
// if (pd['xgfFlag'] == 1 && relatedPartiesPersonList.isNotEmpty) {
|
final String workDepartmentId = (pd['workDepartment'] ?? '').toString();
|
||||||
// personList = [...personList, ...relatedPartiesPersonList];
|
List<dynamic> xgfList =
|
||||||
// }
|
relatedPartiesPersonList.where((item) {
|
||||||
|
if (item is! Map) return false;
|
||||||
|
return (item['departmentId'] ?? '').toString() == workDepartmentId;
|
||||||
|
}).toList();
|
||||||
|
if (!FormUtils.hasValue(pd, 'workDepartment')) {
|
||||||
|
personList = allPersonList;
|
||||||
|
}
|
||||||
|
if (personList.isEmpty) {
|
||||||
|
ToastUtil.showNormal(context, '暂无该部门人员');
|
||||||
|
return;
|
||||||
|
}
|
||||||
DepartmentAllPersonPicker.show(
|
DepartmentAllPersonPicker.show(
|
||||||
context,
|
context,
|
||||||
allowXgfFlag: pd['xgfFlag'] == 1,
|
allowXgfFlag: false,
|
||||||
personsData: personList,
|
personsData: xgfList,
|
||||||
serverData: xgfList,
|
serverData: [],
|
||||||
onSelectedWithData: (userId, name, data) {
|
onSelectedWithData: (userId, name, data) {
|
||||||
setState(() {
|
setState(() {
|
||||||
if (type == SelectPersonType.workCharge) {
|
if (type == SelectPersonType.workCharge) {
|
||||||
|
|
@ -503,7 +525,6 @@ class _SxkjApplyPageState extends SpecialWorkApplyBaseState<SxkjApplyPage> {
|
||||||
pd['workChargeUserDepartment'] = data['departmentId'];
|
pd['workChargeUserDepartment'] = data['departmentId'];
|
||||||
pd['workChargeUserDepartmentName'] = data['departmentName'];
|
pd['workChargeUserDepartmentName'] = data['departmentName'];
|
||||||
allowChoosePerson['1'] = data;
|
allowChoosePerson['1'] = data;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
pd['workGuardianUserId'] = userId;
|
pd['workGuardianUserId'] = userId;
|
||||||
pd['workGuardianUserName'] = name;
|
pd['workGuardianUserName'] = name;
|
||||||
|
|
@ -546,4 +567,4 @@ class _SxkjApplyPageState extends SpecialWorkApplyBaseState<SxkjApplyPage> {
|
||||||
return <String, dynamic>{};
|
return <String, dynamic>{};
|
||||||
}).toList();
|
}).toList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,277 @@
|
||||||
|
import 'dart:convert';
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:intl/intl.dart';
|
||||||
|
import 'package:qhd_prevention/constants/app_enums.dart';
|
||||||
|
import 'package:qhd_prevention/customWidget/ItemWidgetFactory.dart';
|
||||||
|
import 'package:qhd_prevention/customWidget/custom_button.dart';
|
||||||
|
import 'package:qhd_prevention/customWidget/photo_picker_row.dart';
|
||||||
|
import 'package:qhd_prevention/customWidget/single_image_viewer.dart';
|
||||||
|
import 'package:qhd_prevention/customWidget/toast_util.dart';
|
||||||
|
import 'package:qhd_prevention/http/modules/file_api.dart';
|
||||||
|
import 'package:qhd_prevention/http/modules/special_work_api.dart';
|
||||||
|
import 'package:qhd_prevention/pages/mine/mine_sign_page.dart';
|
||||||
|
import 'package:qhd_prevention/pages/my_appbar.dart';
|
||||||
|
import 'package:qhd_prevention/tools/tools.dart';
|
||||||
|
|
||||||
|
class SxkjRecordAddPage extends StatefulWidget {
|
||||||
|
const SxkjRecordAddPage({super.key, required this.data});
|
||||||
|
|
||||||
|
final Map<String, dynamic> data;
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<SxkjRecordAddPage> createState() => _SxkjRecordAddPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _SxkjRecordAddPageState extends State<SxkjRecordAddPage> {
|
||||||
|
final List<String> _images = [];
|
||||||
|
Map<String, dynamic> pd = {};
|
||||||
|
|
||||||
|
List<String> signImages = [];
|
||||||
|
List<String> signTimes = [];
|
||||||
|
bool _isSubmitting = false;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
pd = Map<String, dynamic>.from(widget.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _sign() async {
|
||||||
|
await NativeOrientation.setLandscape();
|
||||||
|
final path = await Navigator.push(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(builder: (context) => MineSignPage()),
|
||||||
|
);
|
||||||
|
await NativeOrientation.setPortrait();
|
||||||
|
|
||||||
|
if (path != null) {
|
||||||
|
final now = DateFormat('yyyy-MM-dd HH:mm:ss').format(DateTime.now());
|
||||||
|
setState(() {
|
||||||
|
signImages = [path];
|
||||||
|
signTimes = [now];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String _extractUploadedPath(dynamic data) {
|
||||||
|
if (data is Map) {
|
||||||
|
final filePath = (data['filePath'] ?? '').toString();
|
||||||
|
if (filePath.isNotEmpty) return filePath;
|
||||||
|
|
||||||
|
final fileList = data['fileList'];
|
||||||
|
if (fileList is List && fileList.isNotEmpty) {
|
||||||
|
return fileList
|
||||||
|
.map(
|
||||||
|
(item) => item is Map ? (item['filePath'] ?? '').toString() : '',
|
||||||
|
)
|
||||||
|
.where((path) => path.isNotEmpty)
|
||||||
|
.join(',');
|
||||||
|
}
|
||||||
|
|
||||||
|
final foreignKey = (data['foreignKey'] ?? '').toString();
|
||||||
|
if (foreignKey.isNotEmpty) return foreignKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data is List && data.isNotEmpty) {
|
||||||
|
return data
|
||||||
|
.map((item) => item is Map ? (item['filePath'] ?? '').toString() : '')
|
||||||
|
.where((path) => path.isNotEmpty)
|
||||||
|
.join(',');
|
||||||
|
}
|
||||||
|
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<String> _uploadRecordImages() async {
|
||||||
|
final result = await FileApi.uploadFiles(
|
||||||
|
_images,
|
||||||
|
UploadFileType.specialOperationInAndOutRecord,
|
||||||
|
'',
|
||||||
|
);
|
||||||
|
if (result['success'] == true) {
|
||||||
|
final filePath = _extractUploadedPath(result['data']);
|
||||||
|
if (filePath.isNotEmpty) return filePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw Exception(result['errMessage'] ?? '记录图片上传失败');
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<String> _uploadSignImages() async {
|
||||||
|
final paths = <String>[];
|
||||||
|
for (final signImage in signImages) {
|
||||||
|
final result = await FileApi.uploadFile(
|
||||||
|
signImage,
|
||||||
|
UploadFileType.specialOperationProcessSignaturePhoto,
|
||||||
|
'',
|
||||||
|
);
|
||||||
|
if (result['success'] == true) {
|
||||||
|
final filePath = _extractUploadedPath(result['data']);
|
||||||
|
if (filePath.isNotEmpty) {
|
||||||
|
paths.add(filePath);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw Exception(result['errMessage'] ?? '签字上传失败');
|
||||||
|
}
|
||||||
|
|
||||||
|
return paths.join(',');
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _submit() async {
|
||||||
|
if (_isSubmitting) return;
|
||||||
|
if (_images.isEmpty) {
|
||||||
|
ToastUtil.showNormal(context, '请上传记录图片');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (signImages.isEmpty) {
|
||||||
|
ToastUtil.showNormal(context, '请签字');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setState(() {
|
||||||
|
_isSubmitting = true;
|
||||||
|
});
|
||||||
|
LoadingDialogHelper.show();
|
||||||
|
try {
|
||||||
|
final recordFilePath = await _uploadRecordImages();
|
||||||
|
final signPath = await _uploadSignImages();
|
||||||
|
final other = {'spaceRecordFile': recordFilePath};
|
||||||
|
|
||||||
|
final params = {
|
||||||
|
'id': pd['id'],
|
||||||
|
'workId': pd['workId'],
|
||||||
|
'stepId': pd['stepId'],
|
||||||
|
'status': 1,
|
||||||
|
'specialStepCode': pd['specialStepCode'],
|
||||||
|
'signPath': signPath,
|
||||||
|
'signTime':
|
||||||
|
signTimes.isNotEmpty
|
||||||
|
? signTimes.first
|
||||||
|
: DateFormat('yyyy-MM-dd HH:mm:ss').format(DateTime.now()),
|
||||||
|
'others': {'otherParams': jsonEncode(other)},
|
||||||
|
};
|
||||||
|
final res = await SpecialWorkApi.specialWorkNextStep(params);
|
||||||
|
if (res['success'] == true) {
|
||||||
|
ToastUtil.showNormal(context, '提交成功');
|
||||||
|
if (mounted) Navigator.pop(context, true);
|
||||||
|
} else {
|
||||||
|
ToastUtil.showNormal(context, res['errMessage'] ?? '作业提交失败');
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
ToastUtil.showNormal(
|
||||||
|
context,
|
||||||
|
e.toString().replaceFirst('Exception: ', ''),
|
||||||
|
);
|
||||||
|
} finally {
|
||||||
|
LoadingDialogHelper.hide();
|
||||||
|
if (mounted) {
|
||||||
|
setState(() {
|
||||||
|
_isSubmitting = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _signListWidget() {
|
||||||
|
return Column(
|
||||||
|
children:
|
||||||
|
signImages.map((path) {
|
||||||
|
return Column(
|
||||||
|
children: [
|
||||||
|
const SizedBox(height: 15),
|
||||||
|
const Divider(),
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
presentOpaque(
|
||||||
|
SingleImageViewer(imageUrl: path),
|
||||||
|
context,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: ConstrainedBox(
|
||||||
|
constraints: const BoxConstraints(
|
||||||
|
maxWidth: 200,
|
||||||
|
maxHeight: 150,
|
||||||
|
),
|
||||||
|
child: Image.file(File(path), fit: BoxFit.contain),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
CustomButton(
|
||||||
|
text: 'X',
|
||||||
|
height: 30,
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 10),
|
||||||
|
backgroundColor: Colors.red,
|
||||||
|
onPressed: () {
|
||||||
|
setState(() {
|
||||||
|
signImages.remove(path);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}).toList(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: MyAppbar(title: '记录上传'),
|
||||||
|
backgroundColor: Colors.white,
|
||||||
|
body: SafeArea(
|
||||||
|
child: SingleChildScrollView(
|
||||||
|
padding: const EdgeInsets.all(12),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
RepairedPhotoSection(
|
||||||
|
isRequired: true,
|
||||||
|
title: '进出有限空间记录',
|
||||||
|
maxCount: 4,
|
||||||
|
horizontalPadding: 0,
|
||||||
|
mediaType: MediaType.image,
|
||||||
|
isShowAI: false,
|
||||||
|
onChanged: (List<File> files) {
|
||||||
|
_images.clear();
|
||||||
|
for (final file in files) {
|
||||||
|
_images.add(file.path);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onAiIdentify: () {},
|
||||||
|
),
|
||||||
|
const SizedBox(height: 20),
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
ListItemFactory.headerTitle(
|
||||||
|
'${pd['actorField'] ?? ''}签字',
|
||||||
|
isRequired: true,
|
||||||
|
),
|
||||||
|
CustomButton(
|
||||||
|
text: signImages.isNotEmpty ? '重签' : '签字',
|
||||||
|
height: 36,
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 25),
|
||||||
|
backgroundColor: Colors.blue,
|
||||||
|
onPressed: _sign,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
if (signImages.isNotEmpty) _signListWidget(),
|
||||||
|
const SizedBox(height: 30),
|
||||||
|
CustomButton(
|
||||||
|
text: _isSubmitting ? '提交中...' : '提交',
|
||||||
|
onPressed: _submit,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:qhd_prevention/http/modules/special_work_api.dart';
|
import 'package:qhd_prevention/http/modules/special_work_api.dart';
|
||||||
import 'package:qhd_prevention/pages/home/Tap/special_header.dart';
|
import 'package:qhd_prevention/pages/home/Tap/special_header.dart';
|
||||||
|
import 'package:qhd_prevention/pages/home/Tap/special_work/sxkj_work/sxkj_record_add_page.dart';
|
||||||
import 'package:qhd_prevention/pages/home/Tap/special_work_wait_scaffold.dart';
|
import 'package:qhd_prevention/pages/home/Tap/special_work_wait_scaffold.dart';
|
||||||
import 'package:qhd_prevention/pages/home/Tap/special_work/sxkj_work/special_work_gas_list.dart';
|
import 'package:qhd_prevention/pages/home/Tap/special_work/sxkj_work/special_work_gas_list.dart';
|
||||||
import 'package:qhd_prevention/pages/home/Tap/special_work/sxkj_work/sxkj_apply_page.dart';
|
import 'package:qhd_prevention/pages/home/Tap/special_work/sxkj_work/sxkj_apply_page.dart';
|
||||||
|
|
@ -39,22 +40,24 @@ class SxkjWaitPage extends SpecialWorkWaitPageBase {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> onOpenDetail(
|
Future<void> onOpenDetail(
|
||||||
BuildContext context,
|
BuildContext context,
|
||||||
Map<String, dynamic> item,
|
Map<String, dynamic> item,
|
||||||
bool isEdit,
|
bool isEdit,
|
||||||
) async {
|
) async {
|
||||||
final hotworkId = item['id'] ?? '';
|
final hotworkId = item['id'] ?? '';
|
||||||
final hotworkCodeId = item['workId'] ?? '';
|
final hotworkCodeId = item['workId'] ?? '';
|
||||||
final hotworkInfo = listType == SpecialListType.task ? item['workInfo'] ?? {} : item;
|
final hotworkInfo =
|
||||||
|
listType == SpecialListType.task ? item['workInfo'] ?? {} : item;
|
||||||
|
|
||||||
final stepId = '${item['stepId'] ?? ''}';
|
final stepId = '${item['stepId'] ?? ''}';
|
||||||
final status = '${hotworkInfo['status'] ?? ''}';
|
final status = '${hotworkInfo['status'] ?? ''}';
|
||||||
|
|
||||||
final String statusName = isEdit
|
final String statusName =
|
||||||
? (listType == SpecialListType.task
|
isEdit
|
||||||
? '${item['stepName'] ?? ''}'
|
? (listType == SpecialListType.task
|
||||||
: '${hotworkInfo['currentStep'] ?? ''}')
|
? '${item['stepName'] ?? ''}'
|
||||||
: '查看';
|
: '${hotworkInfo['currentStep'] ?? ''}')
|
||||||
|
: '查看';
|
||||||
|
|
||||||
Future<void> openTaskPage({required bool editable}) async {
|
Future<void> openTaskPage({required bool editable}) async {
|
||||||
await pushPage(
|
await pushPage(
|
||||||
|
|
@ -70,6 +73,10 @@ class SxkjWaitPage extends SpecialWorkWaitPageBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (listType == SpecialListType.task) {
|
if (listType == SpecialListType.task) {
|
||||||
|
if (stepId == '30') {
|
||||||
|
await pushPage(SxkjRecordAddPage(data: item), context);
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (stepId == '2') {
|
if (stepId == '2') {
|
||||||
if (isEdit) {
|
if (isEdit) {
|
||||||
await pushPage(
|
await pushPage(
|
||||||
|
|
@ -85,11 +92,7 @@ class SxkjWaitPage extends SpecialWorkWaitPageBase {
|
||||||
if (status == '0' || status == '2') {
|
if (status == '0' || status == '2') {
|
||||||
if (isEdit) {
|
if (isEdit) {
|
||||||
await pushPage(
|
await pushPage(
|
||||||
SxkjApplyPage(
|
SxkjApplyPage(isReEdit: true, workId: hotworkId, status: status),
|
||||||
isReEdit: true,
|
|
||||||
workId: hotworkId,
|
|
||||||
status: status,
|
|
||||||
),
|
|
||||||
context,
|
context,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -107,13 +110,12 @@ class SxkjWaitPage extends SpecialWorkWaitPageBase {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget buildCardBody(
|
Widget buildCardBody(
|
||||||
BuildContext context,
|
BuildContext context,
|
||||||
Map<String, dynamic> item,
|
Map<String, dynamic> item,
|
||||||
Map<String, dynamic> workInfo,
|
Map<String, dynamic> workInfo,
|
||||||
Map<String, dynamic> info,
|
Map<String, dynamic> info,
|
||||||
String statusName,
|
String statusName,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
final chooseLimitedSpace = Map<String, dynamic>.from(
|
final chooseLimitedSpace = Map<String, dynamic>.from(
|
||||||
info['chooseLimitedSpace'] ?? {},
|
info['chooseLimitedSpace'] ?? {},
|
||||||
);
|
);
|
||||||
|
|
@ -161,10 +163,10 @@ class SxkjWaitPage extends SpecialWorkWaitPageBase {
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
buildWrapPairRow(
|
// buildWrapPairRow(
|
||||||
'管理单位: ${chooseLimitedSpace['manageDeptName'] ?? ''}',
|
// '管理单位: ${chooseLimitedSpace['manageDeptName'] ?? ''}',
|
||||||
'作业单位: ${info['workDepartmentName'] ?? ''}',
|
// '作业单位: ${info['workDepartmentName'] ?? ''}',
|
||||||
),
|
// ),
|
||||||
Text(
|
Text(
|
||||||
'有限空间名称及编号: ${info['limitedSpaceNameAndCode'] ?? ''}',
|
'有限空间名称及编号: ${info['limitedSpaceNameAndCode'] ?? ''}',
|
||||||
softWrap: true,
|
softWrap: true,
|
||||||
|
|
|
||||||
|
|
@ -1,448 +0,0 @@
|
||||||
import 'dart:convert';
|
|
||||||
import 'dart:io';
|
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:intl/intl.dart';
|
|
||||||
import 'package:qhd_prevention/constants/app_enums.dart';
|
|
||||||
import 'package:qhd_prevention/customWidget/BaiDuMap/Map_page.dart';
|
|
||||||
import 'package:qhd_prevention/customWidget/DocumentPicker.dart';
|
|
||||||
import 'package:qhd_prevention/customWidget/ItemWidgetFactory.dart';
|
|
||||||
import 'package:qhd_prevention/customWidget/MultiDictValuesPicker.dart';
|
|
||||||
import 'package:qhd_prevention/customWidget/center_multi_picker.dart';
|
|
||||||
import 'package:qhd_prevention/customWidget/custom_button.dart';
|
|
||||||
import 'package:qhd_prevention/customWidget/department_all_person_picker.dart';
|
|
||||||
import 'package:qhd_prevention/customWidget/department_person_picker.dart';
|
|
||||||
import 'package:qhd_prevention/customWidget/department_picker.dart';
|
|
||||||
import 'package:qhd_prevention/customWidget/department_picker_three.dart';
|
|
||||||
import 'package:qhd_prevention/customWidget/item_list_widget.dart';
|
|
||||||
import 'package:qhd_prevention/customWidget/picker/CupertinoDatePicker.dart';
|
|
||||||
import 'package:qhd_prevention/customWidget/read_file_page.dart';
|
|
||||||
import 'package:qhd_prevention/customWidget/related_parties_picker.dart';
|
|
||||||
import 'package:qhd_prevention/customWidget/toast_util.dart';
|
|
||||||
import 'package:qhd_prevention/tools/h_colors.dart';
|
|
||||||
import 'package:qhd_prevention/tools/tools.dart';
|
|
||||||
import 'package:qhd_prevention/http/ApiService.dart';
|
|
||||||
import 'package:qhd_prevention/pages/my_appbar.dart';
|
|
||||||
import 'package:qhd_prevention/customWidget/bottom_picker.dart';
|
|
||||||
|
|
||||||
class SxkjTzApplyPage extends StatefulWidget {
|
|
||||||
const SxkjTzApplyPage({
|
|
||||||
super.key,
|
|
||||||
required this.isEdit,
|
|
||||||
required this.work_id,
|
|
||||||
required this.info,
|
|
||||||
});
|
|
||||||
|
|
||||||
/// 是否是重新编辑
|
|
||||||
final bool isEdit;
|
|
||||||
final String work_id;
|
|
||||||
final Map<String, dynamic> info;
|
|
||||||
|
|
||||||
@override
|
|
||||||
State<SxkjTzApplyPage> createState() => _SxkjTzApplyPageState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _SxkjTzApplyPageState extends State<SxkjTzApplyPage> {
|
|
||||||
bool _isEditable = true;
|
|
||||||
|
|
||||||
// pd中各个节点规则填写提示
|
|
||||||
List<Map<String, String>> rules = [
|
|
||||||
{'name': 'manageDeptName', 'message': '请选择管理单位'},
|
|
||||||
{'name': 'name', 'message': '请填写有限空间名称'},
|
|
||||||
{'name': 'code', 'message': '请填写有限空间编号'},
|
|
||||||
{'name': 'type', 'message': '请选择有限空间类型'},
|
|
||||||
{'name': 'positionAndRange', 'message': '请填写位置及范围'},
|
|
||||||
{'name': 'mediumInfo', 'message': '请填写主要介质'},
|
|
||||||
{'name': 'hazards', 'message': '请填写主要危险及有害因素'},
|
|
||||||
{'name': 'riskLevel', 'message': '请选择风险等级'},
|
|
||||||
{'name': 'protectionRequirements', 'message': '请填写防护要求'},
|
|
||||||
{'name': 'separateSafetyMeasures', 'message': '请填写隔绝安全措施'},
|
|
||||||
{'name': 'maximumNumber', 'message': '请填写最大作业人数'},
|
|
||||||
];
|
|
||||||
|
|
||||||
/// 详情
|
|
||||||
Map<String, dynamic> pd = {'isEmergencyBook': 2};
|
|
||||||
|
|
||||||
// 类型
|
|
||||||
List typeList = [];
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
_isEditable = widget.isEdit;
|
|
||||||
if (!widget.isEdit) {
|
|
||||||
pd = widget.info;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 上传附件
|
|
||||||
Future<void> uploadFileHandle() async {
|
|
||||||
final List<SelectedFile> picked = await DocumentPicker.showPickerModal(
|
|
||||||
context,
|
|
||||||
maxAssets: 1,
|
|
||||||
maxSizeInBytes: 20 * 1024 * 1024,
|
|
||||||
allowedExtensions: ['pdf', 'doc', 'docx'],
|
|
||||||
allowMultipleFiles: false,
|
|
||||||
showPhotoSelect: false,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (picked.isNotEmpty && picked.first.path != null) {
|
|
||||||
LoadingDialogHelper.show();
|
|
||||||
final raw = await FileApi.uploadFile(
|
|
||||||
picked.first.path!,
|
|
||||||
UploadFileType.specialOperationRestrictedSpaceLedgerAttachment,
|
|
||||||
'',
|
|
||||||
);
|
|
||||||
if (raw['success']) {
|
|
||||||
LoadingDialogHelper.hide();
|
|
||||||
setState(() {
|
|
||||||
pd['emergencyBookFile'] = raw['data']['filePath'];
|
|
||||||
ToastUtil.showNormal(context, "附件上传成功");
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
ToastUtil.showNormal(context, "附件上传失败");
|
|
||||||
LoadingDialogHelper.hide();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 选择管理单位
|
|
||||||
Future<void> chooseUnitHandle() async {
|
|
||||||
showModalBottomSheet(
|
|
||||||
context: context,
|
|
||||||
isScrollControlled: true,
|
|
||||||
barrierColor: Colors.black54,
|
|
||||||
backgroundColor: Colors.transparent,
|
|
||||||
builder:
|
|
||||||
(_) => DepartmentPicker(
|
|
||||||
onSelected: (id, name, data) async {
|
|
||||||
setState(() {
|
|
||||||
pd['manageDeptName'] = name;
|
|
||||||
pd['manageDeptId'] = id;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
),
|
|
||||||
).then((_) {
|
|
||||||
// 可选:FocusHelper.clearFocus(context);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 选择有限空间类型
|
|
||||||
Future<void> chooseLevelHandle() async {
|
|
||||||
showModalBottomSheet(
|
|
||||||
context: context,
|
|
||||||
isScrollControlled: true,
|
|
||||||
barrierColor: Colors.black54,
|
|
||||||
backgroundColor: Colors.transparent,
|
|
||||||
builder:
|
|
||||||
(_) => MultiDictValuesPicker(
|
|
||||||
title: '有限空间类型',
|
|
||||||
dictType: 'finiteSpaceType',
|
|
||||||
onSelected: (id, name, extraData) {
|
|
||||||
setState(() {
|
|
||||||
pd['typeName'] = name;
|
|
||||||
pd['type'] = extraData?['dictValue'] ?? '';
|
|
||||||
});
|
|
||||||
},
|
|
||||||
),
|
|
||||||
).then((_) {});
|
|
||||||
}
|
|
||||||
|
|
||||||
// 选择风险等级
|
|
||||||
Future<void> chooseRiskLevelHandle() async {
|
|
||||||
showModalBottomSheet(
|
|
||||||
context: context,
|
|
||||||
isScrollControlled: true,
|
|
||||||
barrierColor: Colors.black54,
|
|
||||||
backgroundColor: Colors.transparent,
|
|
||||||
builder:
|
|
||||||
(_) => MultiDictValuesPicker(
|
|
||||||
title: '风险等级',
|
|
||||||
dictType: 'riskGrade',
|
|
||||||
onSelected: (id, name, extraData) {
|
|
||||||
setState(() {
|
|
||||||
pd['riskLevelName'] = name;
|
|
||||||
pd['riskLevel'] = extraData?['dictValue'] ?? '';
|
|
||||||
});
|
|
||||||
},
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 提交
|
|
||||||
Future<void> _submit() async {
|
|
||||||
if (_isEditable) {
|
|
||||||
// 根据rules规则判断
|
|
||||||
for (var item in rules) {
|
|
||||||
if (pd[item['name']] == null || pd[item['name']] == '') {
|
|
||||||
ToastUtil.showNormal(context, item['message'] ?? "请填写必填项");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 是否有应急指导书
|
|
||||||
if (pd['isEmergencyBook'] == 1) {
|
|
||||||
if (pd['emergencyBookFile'] == null || pd['emergencyBookFile'] == '') {
|
|
||||||
ToastUtil.showNormal(context, '请上传应急指导书');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
LoadingDialogHelper.show();
|
|
||||||
final res = await SpecialWorkApi.specialWorkLimitedSpaceSave(pd);
|
|
||||||
if (res['success'] == true) {
|
|
||||||
LoadingDialogHelper.hide();
|
|
||||||
ToastUtil.showNormal(context, "提交成功");
|
|
||||||
Navigator.of(context).pop();
|
|
||||||
} else {
|
|
||||||
LoadingDialogHelper.hide();
|
|
||||||
ToastUtil.showNormal(context, res['errMessage'] ?? "作业提交失败");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildDetail() {
|
|
||||||
return Container(
|
|
||||||
padding: const EdgeInsets.all(8),
|
|
||||||
decoration: const BoxDecoration(
|
|
||||||
color: Colors.white,
|
|
||||||
borderRadius: BorderRadius.all(Radius.circular(5)),
|
|
||||||
),
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
|
||||||
children: [
|
|
||||||
ItemListWidget.selectableLineTitleTextRightButton(
|
|
||||||
label: '管理单位:',
|
|
||||||
isEditable: _isEditable,
|
|
||||||
onTap: chooseUnitHandle,
|
|
||||||
text: pd['manageDeptName'] ?? '',
|
|
||||||
),
|
|
||||||
const Divider(),
|
|
||||||
ItemListWidget.singleLineTitleText(
|
|
||||||
label: '有限空间名称:',
|
|
||||||
isEditable: _isEditable,
|
|
||||||
hintText: '请输入',
|
|
||||||
isTextFont: false,
|
|
||||||
text: pd['name'] ?? '',
|
|
||||||
onChanged: (value) {
|
|
||||||
setState(() {
|
|
||||||
pd['name'] = value;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
),
|
|
||||||
const Divider(),
|
|
||||||
ItemListWidget.singleLineTitleText(
|
|
||||||
label: '有限空间编号:',
|
|
||||||
isEditable: _isEditable,
|
|
||||||
hintText: '请输入',
|
|
||||||
isTextFont: false,
|
|
||||||
text: pd['code'] ?? '',
|
|
||||||
onChanged: (value) {
|
|
||||||
setState(() {
|
|
||||||
pd['code'] = value;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
),
|
|
||||||
const Divider(),
|
|
||||||
ItemListWidget.selectableLineTitleTextRightButton(
|
|
||||||
label: '有限空间类型:',
|
|
||||||
isEditable: _isEditable,
|
|
||||||
onTap: chooseLevelHandle,
|
|
||||||
text: pd['typeName'] ?? '',
|
|
||||||
),
|
|
||||||
const Divider(),
|
|
||||||
ItemListWidget.singleLineTitleText(
|
|
||||||
label: '位置及范围:',
|
|
||||||
isEditable: _isEditable,
|
|
||||||
hintText: '请输入',
|
|
||||||
isTextFont: false,
|
|
||||||
text: pd['positionAndRange'] ?? '',
|
|
||||||
onChanged: (value) {
|
|
||||||
setState(() {
|
|
||||||
pd['positionAndRange'] = value;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
),
|
|
||||||
const Divider(),
|
|
||||||
ItemListWidget.singleLineTitleText(
|
|
||||||
label: '主要介质:',
|
|
||||||
isEditable: _isEditable,
|
|
||||||
hintText: '请输入',
|
|
||||||
isTextFont: false,
|
|
||||||
text: pd['mediumInfo'] ?? '',
|
|
||||||
onChanged: (value) {
|
|
||||||
setState(() {
|
|
||||||
pd['mediumInfo'] = value;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
),
|
|
||||||
const Divider(),
|
|
||||||
ItemListWidget.singleLineTitleText(
|
|
||||||
label: '主要危险及有害因素:',
|
|
||||||
isEditable: _isEditable,
|
|
||||||
hintText: '请输入',
|
|
||||||
isTextFont: false,
|
|
||||||
text: pd['hazards'] ?? '',
|
|
||||||
onChanged: (value) {
|
|
||||||
setState(() {
|
|
||||||
pd['hazards'] = value;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
),
|
|
||||||
const Divider(),
|
|
||||||
ItemListWidget.selectableLineTitleTextRightButton(
|
|
||||||
label: '风险等级:',
|
|
||||||
isEditable: _isEditable,
|
|
||||||
onTap: chooseRiskLevelHandle,
|
|
||||||
text: pd['riskLevelName'] ?? '',
|
|
||||||
),
|
|
||||||
|
|
||||||
const Divider(),
|
|
||||||
|
|
||||||
ItemListWidget.singleLineTitleText(
|
|
||||||
label: '防护要求:',
|
|
||||||
isEditable: _isEditable,
|
|
||||||
hintText: '请输入',
|
|
||||||
isTextFont: false,
|
|
||||||
text: pd['protectionRequirements'] ?? '',
|
|
||||||
onChanged: (value) {
|
|
||||||
setState(() {
|
|
||||||
pd['protectionRequirements'] = value;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
),
|
|
||||||
const Divider(),
|
|
||||||
ItemListWidget.singleLineTitleText(
|
|
||||||
label: '隔绝安全措施:',
|
|
||||||
isEditable: _isEditable,
|
|
||||||
hintText: '请输入',
|
|
||||||
isTextFont: false,
|
|
||||||
text: pd['separateSafetyMeasures'] ?? '',
|
|
||||||
onChanged: (value) {
|
|
||||||
setState(() {
|
|
||||||
pd['separateSafetyMeasures'] = value;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
),
|
|
||||||
const Divider(),
|
|
||||||
ItemListWidget.singleLineTitleText(
|
|
||||||
label: '最大作业人数:',
|
|
||||||
isEditable: _isEditable,
|
|
||||||
hintText: '请输入',
|
|
||||||
isTextFont: false,
|
|
||||||
isNumericInput: true,
|
|
||||||
text: '${pd['maximumNumber'] ?? ''}',
|
|
||||||
onChanged: (value) {
|
|
||||||
setState(() {
|
|
||||||
pd['maximumNumber'] = value;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
),
|
|
||||||
const Divider(),
|
|
||||||
ListItemFactory.createYesNoSection(
|
|
||||||
horizontalPadding: 2,
|
|
||||||
verticalPadding: 5,
|
|
||||||
isEdit: _isEditable,
|
|
||||||
title: '是否有应急指导书',
|
|
||||||
isRequired: true,
|
|
||||||
text: pd['isEmergencyBook'] == 1 ? '是' : '否',
|
|
||||||
groupValue: pd['isEmergencyBook'] == 1,
|
|
||||||
onChanged: (value) {
|
|
||||||
setState(() {
|
|
||||||
pd['isEmergencyBook'] = value ? 1 : 2;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
),
|
|
||||||
const Divider(),
|
|
||||||
if (pd['isEmergencyBook'] == 1)
|
|
||||||
ItemListWidget.OneRowButtonTitleTextFile(
|
|
||||||
horizontalnum: 10,
|
|
||||||
label: '应急指导书',
|
|
||||||
buttonText: _isEditable ? '上传文件' : '查看文件',
|
|
||||||
isRequired: _isEditable,
|
|
||||||
fileUrl: pd['emergencyBookFile'] ?? '',
|
|
||||||
text: '',
|
|
||||||
onTap: () async {
|
|
||||||
if (_isEditable) {
|
|
||||||
uploadFileHandle();
|
|
||||||
} else {
|
|
||||||
pushPage(
|
|
||||||
ReadFilePage(
|
|
||||||
fileUrl:
|
|
||||||
ApiService.baseImgPath + pd['emergencyBookFile'] ??
|
|
||||||
'',
|
|
||||||
),
|
|
||||||
context,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onTapFile: () async {
|
|
||||||
pushPage(
|
|
||||||
ReadFilePage(
|
|
||||||
fileUrl:
|
|
||||||
ApiService.baseImgPath + pd['emergencyBookFile'] ??
|
|
||||||
'',
|
|
||||||
),
|
|
||||||
context,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Scaffold(
|
|
||||||
backgroundColor: h_backGroundColor(),
|
|
||||||
appBar: MyAppbar(title: _isEditable ? '新增' : '查看'),
|
|
||||||
body: SafeArea(
|
|
||||||
child: SingleChildScrollView(
|
|
||||||
child: Column(
|
|
||||||
children: [
|
|
||||||
_buildDetail(),
|
|
||||||
const SizedBox(height: 20),
|
|
||||||
_isEditable
|
|
||||||
? Row(
|
|
||||||
children: [
|
|
||||||
SizedBox(width: 50),
|
|
||||||
Expanded(
|
|
||||||
child: CustomButton(
|
|
||||||
height: 45,
|
|
||||||
textStyle: TextStyle(
|
|
||||||
fontSize: 16,
|
|
||||||
color: Colors.white,
|
|
||||||
),
|
|
||||||
text: '提交',
|
|
||||||
backgroundColor: Colors.green,
|
|
||||||
onPressed: _submit,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SizedBox(width: 50),
|
|
||||||
],
|
|
||||||
)
|
|
||||||
: Row(
|
|
||||||
children: [
|
|
||||||
SizedBox(width: 50),
|
|
||||||
Expanded(
|
|
||||||
child: CustomButton(
|
|
||||||
height: 45,
|
|
||||||
textStyle: TextStyle(
|
|
||||||
fontSize: 16,
|
|
||||||
color: Colors.white,
|
|
||||||
),
|
|
||||||
text: '返回',
|
|
||||||
onPressed: () {
|
|
||||||
Navigator.pop(context);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SizedBox(width: 50),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,323 +0,0 @@
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:intl/intl.dart';
|
|
||||||
import 'package:qhd_prevention/common/route_service.dart';
|
|
||||||
import 'package:qhd_prevention/customWidget/item_list_widget.dart';
|
|
||||||
import 'package:qhd_prevention/pages/home/Tap/special_header.dart';
|
|
||||||
|
|
||||||
import 'package:qhd_prevention/pages/home/Tap/special_work/sxkj_work/tz/sxkj_tz_apply_page.dart';
|
|
||||||
import 'package:qhd_prevention/pages/my_appbar.dart';
|
|
||||||
import 'package:qhd_prevention/services/location_service.dart';
|
|
||||||
import 'package:qhd_prevention/tools/tools.dart';
|
|
||||||
import 'package:qhd_prevention/customWidget/bottom_picker.dart';
|
|
||||||
import 'package:qhd_prevention/customWidget/custom_button.dart';
|
|
||||||
import 'package:qhd_prevention/customWidget/search_bar_widget.dart';
|
|
||||||
import 'package:qhd_prevention/http/ApiService.dart';
|
|
||||||
import 'package:qhd_prevention/pages/home/Tap/special_work/dh_work/hot_task_page.dart';
|
|
||||||
|
|
||||||
class SxkjTzListPage extends StatefulWidget {
|
|
||||||
const SxkjTzListPage({Key? key}) : super(key: key);
|
|
||||||
|
|
||||||
@override
|
|
||||||
_SxkjTzListPageState createState() => _SxkjTzListPageState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _SxkjTzListPageState extends State<SxkjTzListPage> {
|
|
||||||
// Data and state variables
|
|
||||||
List<dynamic> list = [];
|
|
||||||
int currentPage = 1;
|
|
||||||
int rows = 10;
|
|
||||||
int totalPage = 1;
|
|
||||||
bool isLoading = false;
|
|
||||||
final TextEditingController _searchController = TextEditingController();
|
|
||||||
|
|
||||||
List<Map<String, dynamic>> stepList = [];
|
|
||||||
int sindex = 0;
|
|
||||||
String searchKeywords = '';
|
|
||||||
|
|
||||||
List<Map<String, dynamic>> flowList = [];
|
|
||||||
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
|
|
||||||
|
|
||||||
final ScrollController _scrollController = ScrollController();
|
|
||||||
Map searchData = {};
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
_fetchData();
|
|
||||||
_scrollController.addListener(_onScroll);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void dispose() {
|
|
||||||
_scrollController.dispose();
|
|
||||||
super.dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
void _onScroll() {
|
|
||||||
if (_scrollController.position.pixels >=
|
|
||||||
_scrollController.position.maxScrollExtent &&
|
|
||||||
!isLoading) {
|
|
||||||
if (currentPage < totalPage) {
|
|
||||||
currentPage++;
|
|
||||||
_fetchData();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> _fetchSteps() async {
|
|
||||||
try {} catch (e) {
|
|
||||||
print('Error fetching steps: $e');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> _fetchData() async {
|
|
||||||
if (isLoading) return;
|
|
||||||
setState(() => isLoading = true);
|
|
||||||
|
|
||||||
try {
|
|
||||||
var response = {};
|
|
||||||
final parentPerm =
|
|
||||||
'dashboard:hazardous:work:confined-space-operations:Confined-Space-Work-Ledger';
|
|
||||||
final targetPerm = '';
|
|
||||||
final menuPath = await RouteService.getMenuPath(parentPerm, targetPerm);
|
|
||||||
final data = {
|
|
||||||
"eqWorkType": SpecialWorkTypeEnum.confinedspaceWork.code,
|
|
||||||
"pageSize": rows,
|
|
||||||
"pageIndex": currentPage,
|
|
||||||
"menuPath": menuPath,
|
|
||||||
...searchData,
|
|
||||||
};
|
|
||||||
response = await SpecialWorkApi.specialWorkLimitedSpaceList(data);
|
|
||||||
setState(() {
|
|
||||||
if (currentPage == 1) {
|
|
||||||
list = response['data'];
|
|
||||||
} else {
|
|
||||||
list.addAll(response['data']);
|
|
||||||
}
|
|
||||||
totalPage = response['totalCount'] ?? 1;
|
|
||||||
isLoading = false;
|
|
||||||
});
|
|
||||||
} catch (e) {
|
|
||||||
print('Error fetching data: $e');
|
|
||||||
setState(() => isLoading = false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void _search() {
|
|
||||||
searchKeywords = _searchController.text.trim();
|
|
||||||
currentPage = 1;
|
|
||||||
list.clear();
|
|
||||||
_fetchData();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 申请
|
|
||||||
void _handleApply() async {
|
|
||||||
await pushPage(
|
|
||||||
SxkjTzApplyPage(isEdit: true, work_id: '', info: {}),
|
|
||||||
context,
|
|
||||||
);
|
|
||||||
_fetchData();
|
|
||||||
}
|
|
||||||
|
|
||||||
void _goToDetail(Map<String, dynamic> item, bool isEdit) async {
|
|
||||||
pushPage(
|
|
||||||
SxkjTzApplyPage(isEdit: false, work_id: item['id'] ?? '', info: item),
|
|
||||||
context,
|
|
||||||
);
|
|
||||||
_fetchData();
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildListItem(Map<String, dynamic> item) {
|
|
||||||
// actUserName
|
|
||||||
return Card(
|
|
||||||
color: Colors.white,
|
|
||||||
margin: const EdgeInsets.all(8.0),
|
|
||||||
child: InkWell(
|
|
||||||
onTap: () => _goToDetail(item, false),
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.all(12.0),
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
spacing: 8,
|
|
||||||
children: [
|
|
||||||
Row(
|
|
||||||
children: [
|
|
||||||
Expanded(
|
|
||||||
child: Text(
|
|
||||||
"有限空间名称: ${item['name'] ?? ''}",
|
|
||||||
style: const TextStyle(
|
|
||||||
fontSize: 14,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
),
|
|
||||||
softWrap: true,
|
|
||||||
maxLines: null,
|
|
||||||
overflow: TextOverflow.visible,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
Row(
|
|
||||||
children: [
|
|
||||||
Expanded(
|
|
||||||
child: Text(
|
|
||||||
"编号: ${item['code'] ?? ''}",
|
|
||||||
softWrap: true,
|
|
||||||
maxLines: null,
|
|
||||||
overflow: TextOverflow.visible,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
|
|
||||||
Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
"有限空间类型: ${item['typeName'] ?? ''}",
|
|
||||||
softWrap: true,
|
|
||||||
maxLines: null,
|
|
||||||
textAlign: TextAlign.right,
|
|
||||||
|
|
||||||
overflow: TextOverflow.visible,
|
|
||||||
),
|
|
||||||
Text(
|
|
||||||
"风险等级: ${item['riskLevelName'] ?? ''}",
|
|
||||||
softWrap: true,
|
|
||||||
maxLines: null,
|
|
||||||
overflow: TextOverflow.visible,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
Text(
|
|
||||||
"位置及范围: ${item['positionAndRange'] ?? ''}",
|
|
||||||
softWrap: true,
|
|
||||||
maxLines: 30,
|
|
||||||
overflow: TextOverflow.visible,
|
|
||||||
),
|
|
||||||
Text(
|
|
||||||
"主要介质: ${item['mediumInfo'] ?? ''}",
|
|
||||||
softWrap: true,
|
|
||||||
maxLines: 30,
|
|
||||||
overflow: TextOverflow.visible,
|
|
||||||
),
|
|
||||||
|
|
||||||
_statusButtons(item),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _statusButtons(Map<String, dynamic> item) {
|
|
||||||
final List<Widget> buttons = [];
|
|
||||||
final List<Widget> buttonRowChildren = [];
|
|
||||||
|
|
||||||
buttons.add(
|
|
||||||
CustomButton(
|
|
||||||
text: '查看',
|
|
||||||
buttonStyle: ButtonStyleType.primary,
|
|
||||||
backgroundColor: Colors.blue,
|
|
||||||
onPressed: () {
|
|
||||||
_goToDetail(item, false);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
for (int i = 0; i < buttons.length; i++) {
|
|
||||||
buttonRowChildren.add(
|
|
||||||
Expanded(child: SizedBox(height: 40, child: buttons[i])),
|
|
||||||
);
|
|
||||||
if (i != buttons.length - 1) {
|
|
||||||
buttonRowChildren.add(const SizedBox(width: 10));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Row(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
|
||||||
children: buttonRowChildren,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildListContent() {
|
|
||||||
if (isLoading && list.isEmpty) {
|
|
||||||
// 初始加载时显示居中的加载指示器
|
|
||||||
return Center(child: CircularProgressIndicator());
|
|
||||||
} else if (list.isEmpty) {
|
|
||||||
// 没有数据
|
|
||||||
return NoDataWidget.show();
|
|
||||||
} else {
|
|
||||||
// 有数据或加载更多
|
|
||||||
return ListView.builder(
|
|
||||||
padding: EdgeInsets.zero,
|
|
||||||
|
|
||||||
controller: _scrollController,
|
|
||||||
itemCount: list.length + (isLoading ? 1 : 0),
|
|
||||||
itemBuilder: (context, index) {
|
|
||||||
if (index >= list.length) {
|
|
||||||
// 加载更多时在列表底部显示加载指示器
|
|
||||||
return Padding(
|
|
||||||
padding: const EdgeInsets.symmetric(vertical: 16.0),
|
|
||||||
child: Center(child: CircularProgressIndicator()),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return _buildListItem(list[index]);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Scaffold(
|
|
||||||
key: _scaffoldKey,
|
|
||||||
appBar: MyAppbar(
|
|
||||||
title: '有限空间管理台账',
|
|
||||||
actions: [
|
|
||||||
IconButton(
|
|
||||||
onPressed: _handleApply,
|
|
||||||
icon: const Icon(Icons.add, color: Colors.white, size: 30),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
endDrawer: Drawer(
|
|
||||||
child: SafeArea(
|
|
||||||
child:
|
|
||||||
flowList.isEmpty
|
|
||||||
? Center(child: Text('暂无流程图数据'))
|
|
||||||
: ItemListWidget.specialBuildFlowStepItem(flowList: flowList),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
|
|
||||||
body: SafeArea(
|
|
||||||
child: Column(
|
|
||||||
children: [
|
|
||||||
Container(
|
|
||||||
color: Colors.white,
|
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 5, vertical: 8),
|
|
||||||
child: SearchBarWidget(
|
|
||||||
hintText: '请输入有限空间名称',
|
|
||||||
showResetButton: true,
|
|
||||||
onSearch: (val) {
|
|
||||||
searchData = {'likeName' : _searchController.text};
|
|
||||||
_fetchData();
|
|
||||||
|
|
||||||
},
|
|
||||||
onReset: () {
|
|
||||||
_searchController.text = '';
|
|
||||||
searchData = {};
|
|
||||||
|
|
||||||
_fetchData();
|
|
||||||
},
|
|
||||||
controller: _searchController,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
|
|
||||||
const Divider(height: 1),
|
|
||||||
// List
|
|
||||||
Expanded(child: _buildListContent()),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -5,10 +5,7 @@ import 'package:qhd_prevention/customWidget/toast_util.dart';
|
||||||
import 'package:qhd_prevention/customWidget/work_tab_icon_grid.dart';
|
import 'package:qhd_prevention/customWidget/work_tab_icon_grid.dart';
|
||||||
import 'package:qhd_prevention/http/modules/special_work_api.dart';
|
import 'package:qhd_prevention/http/modules/special_work_api.dart';
|
||||||
import 'package:qhd_prevention/pages/home/Tap/special_header.dart';
|
import 'package:qhd_prevention/pages/home/Tap/special_header.dart';
|
||||||
import 'package:qhd_prevention/pages/home/Tap/special_work/dh_work/dh_wait_page.dart' hide SpecialListType;
|
|
||||||
import 'package:qhd_prevention/pages/home/Tap/special_work/sxkj_work/tz/sxkj_tz_list_page.dart';
|
|
||||||
import 'package:qhd_prevention/pages/home/Tap/special_work/sxkj_work/sxkj_wait_page.dart';
|
import 'package:qhd_prevention/pages/home/Tap/special_work/sxkj_work/sxkj_wait_page.dart';
|
||||||
import 'package:qhd_prevention/pages/home/Tap/work_tab_list_page.dart';
|
|
||||||
import 'package:qhd_prevention/pages/my_appbar.dart';
|
import 'package:qhd_prevention/pages/my_appbar.dart';
|
||||||
import 'package:qhd_prevention/tools/tools.dart';
|
import 'package:qhd_prevention/tools/tools.dart';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -85,6 +85,7 @@ abstract class SpecialWorkApplyBaseState<T extends SpecialWorkApplyBasePage>
|
||||||
|
|
||||||
/// 安全防护措施控制器
|
/// 安全防护措施控制器
|
||||||
final SafeProtectionController safeController = SafeProtectionController();
|
final SafeProtectionController safeController = SafeProtectionController();
|
||||||
|
bool _isSyncingGasAndSafe = false;
|
||||||
|
|
||||||
/// 初始化完成标志
|
/// 初始化完成标志
|
||||||
bool loadingInitDone = false;
|
bool loadingInitDone = false;
|
||||||
|
|
@ -190,9 +191,16 @@ abstract class SpecialWorkApplyBaseState<T extends SpecialWorkApplyBasePage>
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
|
safeController.addListener(_handleSafeControllerChanged);
|
||||||
_loadPage();
|
_loadPage();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
safeController.removeListener(_handleSafeControllerChanged);
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> _loadPage() async {
|
Future<void> _loadPage() async {
|
||||||
LoadingDialogHelper.show();
|
LoadingDialogHelper.show();
|
||||||
try {
|
try {
|
||||||
|
|
@ -224,7 +232,9 @@ abstract class SpecialWorkApplyBaseState<T extends SpecialWorkApplyBasePage>
|
||||||
pd['signStepFlag'] = 2;
|
pd['signStepFlag'] = 2;
|
||||||
pd['gasFlag'] = pd['gasFlag'] ?? 2;
|
pd['gasFlag'] = pd['gasFlag'] ?? 2;
|
||||||
levelList = List<dynamic>.from(pd['taskWorkLevels'] ?? []);
|
levelList = List<dynamic>.from(pd['taskWorkLevels'] ?? []);
|
||||||
|
pd['applyTime'] = DateFormat(
|
||||||
|
'yyyy-MM-dd HH:mm:ss',
|
||||||
|
).format(DateTime.now());
|
||||||
if (enableSafeProtection) {
|
if (enableSafeProtection) {
|
||||||
await safeController.loadFromRaw(
|
await safeController.loadFromRaw(
|
||||||
pd['preparers'] ?? pd['PREPARERS'] ?? [],
|
pd['preparers'] ?? pd['PREPARERS'] ?? [],
|
||||||
|
|
@ -385,7 +395,7 @@ abstract class SpecialWorkApplyBaseState<T extends SpecialWorkApplyBasePage>
|
||||||
|
|
||||||
/// 根据 initData 生成签字组
|
/// 根据 initData 生成签字组
|
||||||
void _initGroupsFromInitData(bool isRefresh) {
|
void _initGroupsFromInitData(bool isRefresh) {
|
||||||
_clearAllPerson();
|
if (!widget.isReEdit) _clearAllPerson();
|
||||||
final List steps =
|
final List steps =
|
||||||
(initData['settingSignSteps'] is List)
|
(initData['settingSignSteps'] is List)
|
||||||
? List.from(initData['settingSignSteps'])
|
? List.from(initData['settingSignSteps'])
|
||||||
|
|
@ -478,7 +488,7 @@ abstract class SpecialWorkApplyBaseState<T extends SpecialWorkApplyBasePage>
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 选择部门单位
|
/// 选择部门单位
|
||||||
void chooseUnitHandle(int index) {
|
void chooseUnitHandle(int index, bool ischoosePerson) {
|
||||||
showModalBottomSheet(
|
showModalBottomSheet(
|
||||||
context: context,
|
context: context,
|
||||||
isScrollControlled: true,
|
isScrollControlled: true,
|
||||||
|
|
@ -493,9 +503,11 @@ abstract class SpecialWorkApplyBaseState<T extends SpecialWorkApplyBasePage>
|
||||||
groups[index]['actUser'] = '';
|
groups[index]['actUser'] = '';
|
||||||
groups[index]['actUserName'] = '';
|
groups[index]['actUserName'] = '';
|
||||||
});
|
});
|
||||||
await _getPersonListForUnitId(id);
|
if (ischoosePerson) {
|
||||||
|
await _getPersonListForUnitId(id);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
data: {'corpinfoId': pd['projectExecutionLocationCorpId'] ?? ''},
|
data: {'eqCorpinfoId': pd['projectExecutionLocationCorpId'] ?? ''},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -538,7 +550,7 @@ abstract class SpecialWorkApplyBaseState<T extends SpecialWorkApplyBasePage>
|
||||||
});
|
});
|
||||||
await _getPersonListForUnitId(id);
|
await _getPersonListForUnitId(id);
|
||||||
},
|
},
|
||||||
data: {'corpinfoId': pd['projectExecutionLocationCorpId'] ?? ''},
|
data: {'eqCorpinfoId': pd['xgfId'] ?? ''},
|
||||||
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
@ -606,6 +618,9 @@ abstract class SpecialWorkApplyBaseState<T extends SpecialWorkApplyBasePage>
|
||||||
groups[index]['actUserName'] = name;
|
groups[index]['actUserName'] = name;
|
||||||
groups[index]['actUserDepartment'] = data['departmentId'];
|
groups[index]['actUserDepartment'] = data['departmentId'];
|
||||||
groups[index]['actUserDepartmentName'] = data['departmentName'];
|
groups[index]['actUserDepartmentName'] = data['departmentName'];
|
||||||
|
if (stepId == '2') {
|
||||||
|
syncSafeMeasureConfirmersWithGasAnalyzer(data);
|
||||||
|
}
|
||||||
// 同步更新允许列表,用于安全措施确认人、气体分析人
|
// 同步更新允许列表,用于安全措施确认人、气体分析人
|
||||||
if (stepId == '20') {
|
if (stepId == '20') {
|
||||||
allowChoosePerson['1'] = data;
|
allowChoosePerson['1'] = data;
|
||||||
|
|
@ -619,6 +634,74 @@ abstract class SpecialWorkApplyBaseState<T extends SpecialWorkApplyBasePage>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _handleSafeControllerChanged() {
|
||||||
|
if (_isSyncingGasAndSafe) return;
|
||||||
|
|
||||||
|
Map<String, dynamic>? selectedPerson;
|
||||||
|
for (final group in safeController.groups) {
|
||||||
|
if (group.updateId.isNotEmpty) {
|
||||||
|
selectedPerson = {
|
||||||
|
'id': group.updateId,
|
||||||
|
'name': group.updateName,
|
||||||
|
'departmentId': group.departmentId,
|
||||||
|
'departmentName': group.departmentName,
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (selectedPerson == null) return;
|
||||||
|
|
||||||
|
final gasItem = groups.cast<Map?>().firstWhere(
|
||||||
|
(item) => (item?['stepId'] ?? '').toString() == '2',
|
||||||
|
orElse: () => null,
|
||||||
|
);
|
||||||
|
if (gasItem == null) return;
|
||||||
|
|
||||||
|
final nextUserId = (selectedPerson['id'] ?? '').toString();
|
||||||
|
final currentUserId = (gasItem['actUser'] ?? '').toString();
|
||||||
|
if (nextUserId.isEmpty || currentUserId == nextUserId) return;
|
||||||
|
|
||||||
|
_isSyncingGasAndSafe = true;
|
||||||
|
try {
|
||||||
|
if (!mounted) return;
|
||||||
|
setState(() {
|
||||||
|
gasItem['actUser'] = nextUserId;
|
||||||
|
gasItem['actUserName'] = (selectedPerson?['name'] ?? '').toString();
|
||||||
|
gasItem['actUserDepartment'] =
|
||||||
|
(selectedPerson?['departmentId'] ?? '').toString();
|
||||||
|
gasItem['actUserDepartmentName'] =
|
||||||
|
(selectedPerson?['departmentName'] ?? '').toString();
|
||||||
|
});
|
||||||
|
} finally {
|
||||||
|
_isSyncingGasAndSafe = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void syncSafeMeasureConfirmersWithGasAnalyzer(Map<String, dynamic> data) {
|
||||||
|
if (_isSyncingGasAndSafe) return;
|
||||||
|
|
||||||
|
_isSyncingGasAndSafe = true;
|
||||||
|
try {
|
||||||
|
for (final group in safeController.groups) {
|
||||||
|
group.updateId = (data['id'] ?? data['actUser'] ?? '').toString();
|
||||||
|
group.updateName =
|
||||||
|
(data['name'] ?? data['actUserName'] ?? '').toString();
|
||||||
|
group.actUser = group.updateId;
|
||||||
|
group.actUserName = group.updateName;
|
||||||
|
group.departmentId = (data['departmentId'] ?? '').toString();
|
||||||
|
group.departmentName =
|
||||||
|
(data['departmentName'] ?? data['actUserDepartmentName'] ?? '')
|
||||||
|
.toString();
|
||||||
|
group.actUserDepartment = group.departmentId;
|
||||||
|
group.actUserDepartmentName = group.departmentName;
|
||||||
|
}
|
||||||
|
safeController.refresh();
|
||||||
|
} finally {
|
||||||
|
_isSyncingGasAndSafe = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 清空气体检测人和安全措施确认人
|
// 清空气体检测人和安全措施确认人
|
||||||
void clearRelatedPartiesPerson() {
|
void clearRelatedPartiesPerson() {
|
||||||
setState(() {
|
setState(() {
|
||||||
|
|
@ -744,6 +827,7 @@ abstract class SpecialWorkApplyBaseState<T extends SpecialWorkApplyBasePage>
|
||||||
final canSkip = (item['canSkip'] ?? 0) is int ? (item['canSkip'] ?? 0) : 0;
|
final canSkip = (item['canSkip'] ?? 0) is int ? (item['canSkip'] ?? 0) : 0;
|
||||||
final skipCondition = (item['skipCondition'] ?? '').toString();
|
final skipCondition = (item['skipCondition'] ?? '').toString();
|
||||||
final allowXgfFlag = item['allowXgfFlag'] ?? 0;
|
final allowXgfFlag = item['allowXgfFlag'] ?? 0;
|
||||||
|
final showSignFlag = item['showSignFlag'];
|
||||||
|
|
||||||
final deptLabel = actorField.isNotEmpty ? '$actorField 部门' : '单位';
|
final deptLabel = actorField.isNotEmpty ? '$actorField 部门' : '单位';
|
||||||
final personLabel = actorField.isNotEmpty ? actorField : '人员';
|
final personLabel = actorField.isNotEmpty ? actorField : '人员';
|
||||||
|
|
@ -760,7 +844,9 @@ abstract class SpecialWorkApplyBaseState<T extends SpecialWorkApplyBasePage>
|
||||||
skipCondition.isNotEmpty &&
|
skipCondition.isNotEmpty &&
|
||||||
skipCondition.contains('gas_flag') &&
|
skipCondition.contains('gas_flag') &&
|
||||||
pd['gasFlag'] == 1;
|
pd['gasFlag'] == 1;
|
||||||
|
if (showSignFlag == 2) {
|
||||||
|
return SizedBox();
|
||||||
|
}
|
||||||
return Column(
|
return Column(
|
||||||
children: [
|
children: [
|
||||||
if (item['selectLevel'] == 1) ...[
|
if (item['selectLevel'] == 1) ...[
|
||||||
|
|
@ -784,11 +870,23 @@ abstract class SpecialWorkApplyBaseState<T extends SpecialWorkApplyBasePage>
|
||||||
(item['actUserDepartmentName'] as String?)?.isNotEmpty == true
|
(item['actUserDepartmentName'] as String?)?.isNotEmpty == true
|
||||||
? item['actUserDepartmentName']
|
? item['actUserDepartmentName']
|
||||||
: '请选择',
|
: '请选择',
|
||||||
onTap: () => chooseUnitHandle(index),
|
onTap: () => chooseUnitHandle(index, true),
|
||||||
),
|
),
|
||||||
const Divider(),
|
const Divider(),
|
||||||
],
|
],
|
||||||
if (canSkip == 1) ...[
|
if (item['selectLevel'] == 3)...[ // 只选部门
|
||||||
|
ItemListWidget.selectableLineTitleTextRightButton(
|
||||||
|
isRequired: !(canSkip == 1),
|
||||||
|
label: personLabel,
|
||||||
|
isEditable: isEditable,
|
||||||
|
text:
|
||||||
|
(item['actUserDepartmentName'] as String?)?.isNotEmpty == true
|
||||||
|
? item['actUserDepartmentName']
|
||||||
|
: '请选择',
|
||||||
|
onTap: () => chooseUnitHandle(index, false),
|
||||||
|
),
|
||||||
|
const Divider(),
|
||||||
|
]else...[if (canSkip == 1) ...[
|
||||||
if (skipCondition.isEmpty) ...[
|
if (skipCondition.isEmpty) ...[
|
||||||
ListItemFactory.createYesNoSection(
|
ListItemFactory.createYesNoSection(
|
||||||
horizontalPadding: 2,
|
horizontalPadding: 2,
|
||||||
|
|
@ -832,9 +930,9 @@ abstract class SpecialWorkApplyBaseState<T extends SpecialWorkApplyBasePage>
|
||||||
label: personLabel,
|
label: personLabel,
|
||||||
isEditable: isEditable,
|
isEditable: isEditable,
|
||||||
text:
|
text:
|
||||||
(item['actUserName'] as String?)?.isNotEmpty == true
|
(item['actUserName'] as String?)?.isNotEmpty == true
|
||||||
? item['actUserName']
|
? item['actUserName']
|
||||||
: '请选择',
|
: '请选择',
|
||||||
onTap: () => choosePersonHandle(index, allowXgfFlag == 1),
|
onTap: () => choosePersonHandle(index, allowXgfFlag == 1),
|
||||||
),
|
),
|
||||||
const Divider(),
|
const Divider(),
|
||||||
|
|
@ -845,13 +943,14 @@ abstract class SpecialWorkApplyBaseState<T extends SpecialWorkApplyBasePage>
|
||||||
label: personLabel,
|
label: personLabel,
|
||||||
isEditable: isEditable,
|
isEditable: isEditable,
|
||||||
text:
|
text:
|
||||||
(item['actUserName'] as String?)?.isNotEmpty == true
|
(item['actUserName'] as String?)?.isNotEmpty == true
|
||||||
? item['actUserName']
|
? item['actUserName']
|
||||||
: '请选择',
|
: '请选择',
|
||||||
onTap: () => choosePersonHandle(index, allowXgfFlag == 1),
|
onTap: () => choosePersonHandle(index, allowXgfFlag == 1),
|
||||||
),
|
),
|
||||||
const Divider(),
|
const Divider(),
|
||||||
],
|
],],
|
||||||
|
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -945,6 +1044,14 @@ abstract class SpecialWorkApplyBaseState<T extends SpecialWorkApplyBasePage>
|
||||||
'xgfId' : info['xgfId'] ?? ''
|
'xgfId' : info['xgfId'] ?? ''
|
||||||
};
|
};
|
||||||
payload.addAll(extraPayload);
|
payload.addAll(extraPayload);
|
||||||
|
for (final item in signLogs) {
|
||||||
|
if (item['stepId'] == '30' && info['isInnerWork'] == 1) {
|
||||||
|
item['actUserDepartment'] = pd['workChargeUserDepartment'] ?? '';
|
||||||
|
item['actUserDepartmentName'] = pd['workChargeUserDepartmentName'] ?? '';
|
||||||
|
item['actUser'] = pd['workChargeUserId'] ?? '';
|
||||||
|
item['actUserName'] = pd['workChargeUserName'] ?? '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (FormUtils.hasValue(payload, 'workId') && widget.status == '2') {
|
if (FormUtils.hasValue(payload, 'workId') && widget.status == '2') {
|
||||||
payload.remove('checkNo');
|
payload.remove('checkNo');
|
||||||
|
|
@ -1011,7 +1118,9 @@ abstract class SpecialWorkApplyBaseState<T extends SpecialWorkApplyBasePage>
|
||||||
}
|
}
|
||||||
|
|
||||||
for (final item in groupsToCheck) {
|
for (final item in groupsToCheck) {
|
||||||
if (item['actUser'] == null || item['actUser'] == '') {
|
int showSignFlag = item['showSignFlag'] ?? 1;
|
||||||
|
int selectLevel = item['selectLevel'] ?? 0;
|
||||||
|
if ((item['actUser'] == null || item['actUser'] == '') && showSignFlag == 1 && selectLevel != 3) {
|
||||||
final canSkip =
|
final canSkip =
|
||||||
(item['canSkip'] ?? 0) is int ? (item['canSkip'] ?? 0) : 0;
|
(item['canSkip'] ?? 0) is int ? (item['canSkip'] ?? 0) : 0;
|
||||||
final stepId = item['stepId'] ?? '';
|
final stepId = item['stepId'] ?? '';
|
||||||
|
|
|
||||||
|
|
@ -372,7 +372,24 @@ class _SpecialWorkTaskPageBaseState extends State<SpecialWorkTaskPageBase> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (pd['componentName'] == 'personAnderRecordFile') {
|
||||||
|
// 判断是否上传了应急响应记录 spaceRecordFile、limitSpaceWorkNum
|
||||||
|
if (!FormUtils.hasValue(other, 'limitSpaceWorkNum')) {
|
||||||
|
ToastUtil.showNormal(
|
||||||
|
context,
|
||||||
|
'请输入有限空间作业人数',
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!FormUtils.hasValue(other, 'spaceRecordFile')) {
|
||||||
|
ToastUtil.showNormal(
|
||||||
|
context,
|
||||||
|
'请上传应急响应记录',
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
// 5) 签字必填
|
// 5) 签字必填
|
||||||
if (signImages.isEmpty) {
|
if (signImages.isEmpty) {
|
||||||
if (!FormUtils.hasValue(other, 'isCompleteWork')) {
|
if (!FormUtils.hasValue(other, 'isCompleteWork')) {
|
||||||
|
|
@ -1030,7 +1047,7 @@ class _SpecialWorkTaskPageBaseState extends State<SpecialWorkTaskPageBase> {
|
||||||
|
|
||||||
final info = Map<String, dynamic>.from(raw);
|
final info = Map<String, dynamic>.from(raw);
|
||||||
final signPath = (info['signPath'] ?? '').toString().trim();
|
final signPath = (info['signPath'] ?? '').toString().trim();
|
||||||
return signPath.isNotEmpty;
|
return signPath.isNotEmpty || _getSpaceRecordFiles(info).isNotEmpty;
|
||||||
}).toList();
|
}).toList();
|
||||||
|
|
||||||
validEntries.sort((a, b) {
|
validEntries.sort((a, b) {
|
||||||
|
|
@ -1121,12 +1138,12 @@ class _SpecialWorkTaskPageBaseState extends State<SpecialWorkTaskPageBase> {
|
||||||
final info = Map<String, dynamic>.from(raw);
|
final info = Map<String, dynamic>.from(raw);
|
||||||
final stepName = (info['stepName'] ?? '').toString();
|
final stepName = (info['stepName'] ?? '').toString();
|
||||||
final signPath = (info['signPath'] ?? '').toString().trim();
|
final signPath = (info['signPath'] ?? '').toString().trim();
|
||||||
final signTime = (info['signTime'] ?? info['signerTime'] ?? '').toString().trim();
|
final signTime =
|
||||||
|
(info['signTime'] ?? info['signerTime'] ?? '').toString().trim();
|
||||||
final remarks = (info['remarks'] ?? '').toString().trim();
|
final remarks = (info['remarks'] ?? '').toString().trim();
|
||||||
|
final spaceRecordFiles = _getSpaceRecordFiles(info);
|
||||||
|
|
||||||
if (signPath.isEmpty) continue;
|
if (signPath.isEmpty && spaceRecordFiles.isEmpty) continue;
|
||||||
|
|
||||||
final imageUrl = '${ApiService.baseImgPath}$signPath';
|
|
||||||
|
|
||||||
widgets.add(
|
widgets.add(
|
||||||
Container(
|
Container(
|
||||||
|
|
@ -1167,27 +1184,35 @@ class _SpecialWorkTaskPageBaseState extends State<SpecialWorkTaskPageBase> {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
GestureDetector(
|
if (spaceRecordFiles.isNotEmpty) ...[
|
||||||
onTap: () async {
|
_buildSpaceRecordFiles(spaceRecordFiles),
|
||||||
presentOpaque(SingleImageViewer(imageUrl: imageUrl), context);
|
const SizedBox(height: 10),
|
||||||
},
|
],
|
||||||
child: Align(
|
if (signPath.isNotEmpty)
|
||||||
alignment: Alignment.centerRight,
|
GestureDetector(
|
||||||
child: ConstrainedBox(
|
onTap: () async {
|
||||||
constraints: const BoxConstraints(
|
presentOpaque(
|
||||||
maxWidth: 220,
|
SingleImageViewer(imageUrl: _fullFileUrl(signPath)),
|
||||||
maxHeight: 140,
|
context,
|
||||||
),
|
);
|
||||||
child: Image.network(
|
},
|
||||||
imageUrl,
|
child: Align(
|
||||||
fit: BoxFit.contain,
|
alignment: Alignment.centerRight,
|
||||||
errorBuilder: (context, error, stackTrace) {
|
child: ConstrainedBox(
|
||||||
return const Text('签字图片加载失败');
|
constraints: const BoxConstraints(
|
||||||
},
|
maxWidth: 220,
|
||||||
|
maxHeight: 140,
|
||||||
|
),
|
||||||
|
child: Image.network(
|
||||||
|
_fullFileUrl(signPath),
|
||||||
|
fit: BoxFit.contain,
|
||||||
|
errorBuilder: (context, error, stackTrace) {
|
||||||
|
return const Text('签字图片加载失败');
|
||||||
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
Align(
|
Align(
|
||||||
alignment: Alignment.centerRight,
|
alignment: Alignment.centerRight,
|
||||||
|
|
@ -1205,6 +1230,113 @@ class _SpecialWorkTaskPageBaseState extends State<SpecialWorkTaskPageBase> {
|
||||||
return widgets;
|
return widgets;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<String> _getSpaceRecordFiles(Map<String, dynamic> info) {
|
||||||
|
dynamic otherParams = info['otherParams'];
|
||||||
|
|
||||||
|
if (otherParams is String) {
|
||||||
|
try {
|
||||||
|
otherParams = jsonDecode(otherParams);
|
||||||
|
} catch (_) {
|
||||||
|
otherParams = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final raw =
|
||||||
|
otherParams is Map
|
||||||
|
? (otherParams['spaceRecordFile'] ?? '')
|
||||||
|
: (info['spaceRecordFile'] ?? '');
|
||||||
|
|
||||||
|
return raw
|
||||||
|
.toString()
|
||||||
|
.split(',')
|
||||||
|
.map((path) => path.trim())
|
||||||
|
.where((path) => path.isNotEmpty)
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
String _fullFileUrl(String path) {
|
||||||
|
final value = path.trim();
|
||||||
|
if (value.startsWith('http://') || value.startsWith('https://')) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
return '${ApiService.baseImgPath}$value';
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _isPreviewImage(String path) {
|
||||||
|
final lower = path.toLowerCase().split('?').first;
|
||||||
|
return lower.endsWith('.jpg') ||
|
||||||
|
lower.endsWith('.jpeg') ||
|
||||||
|
lower.endsWith('.png') ||
|
||||||
|
lower.endsWith('.webp') ||
|
||||||
|
lower.endsWith('.gif') ||
|
||||||
|
lower.endsWith('.bmp');
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildSpaceRecordFiles(List<String> files) {
|
||||||
|
return Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
|
||||||
|
Wrap(
|
||||||
|
spacing: 10,
|
||||||
|
runSpacing: 10,
|
||||||
|
children:
|
||||||
|
files.map((path) {
|
||||||
|
final fileUrl = _fullFileUrl(path);
|
||||||
|
if (_isPreviewImage(path)) {
|
||||||
|
return GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
presentOpaque(
|
||||||
|
SingleImageViewer(imageUrl: fileUrl),
|
||||||
|
context,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: ConstrainedBox(
|
||||||
|
constraints: const BoxConstraints(
|
||||||
|
maxWidth: 120,
|
||||||
|
maxHeight: 90,
|
||||||
|
),
|
||||||
|
child: Image.network(
|
||||||
|
fileUrl,
|
||||||
|
fit: BoxFit.cover,
|
||||||
|
errorBuilder: (context, error, stackTrace) {
|
||||||
|
return const Text('');
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
final fileName = path.split('/').last;
|
||||||
|
return InkWell(
|
||||||
|
onTap: () {
|
||||||
|
pushPage(ReadFilePage(fileUrl: fileUrl), context);
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
constraints: const BoxConstraints(maxWidth: 220),
|
||||||
|
padding: const EdgeInsets.symmetric(
|
||||||
|
horizontal: 10,
|
||||||
|
vertical: 8,
|
||||||
|
),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.grey.shade100,
|
||||||
|
borderRadius: BorderRadius.circular(4),
|
||||||
|
border: Border.all(color: Colors.grey.shade300),
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
fileName.isNotEmpty ? fileName : '查看附件',
|
||||||
|
maxLines: 2,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
style: const TextStyle(fontSize: 12, color: Colors.blue),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}).toList(),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// 其他安全措施回显
|
// 其他安全措施回显
|
||||||
Widget _otherMeasureWidgets() {
|
Widget _otherMeasureWidgets() {
|
||||||
if (_otherMeasuresList.isNotEmpty) {
|
if (_otherMeasuresList.isNotEmpty) {
|
||||||
|
|
|
||||||
|
|
@ -199,7 +199,7 @@ class HomePageState extends RouteAwareState<HomePage>
|
||||||
final routeService = RouteService();
|
final routeService = RouteService();
|
||||||
final mainTabs = routeService.mainTabs;
|
final mainTabs = routeService.mainTabs;
|
||||||
if (mainTabs.isEmpty) {
|
if (mainTabs.isEmpty) {
|
||||||
// 路由未加载,保持全隐藏
|
// 路由未加载,保持全隐藏ƒ
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue