Compare commits

...

2 Commits

Author SHA1 Message Date
hs 1a1d582874 Merge remote-tracking branch 'origin/main' 2025-08-01 16:41:50 +08:00
hs 5e9f726eaa 封装修改八项作业结构 2025-08-01 16:41:44 +08:00
42 changed files with 7374 additions and 371 deletions

View File

@ -24,13 +24,13 @@ class BottomPicker {
/// [itemExtent]:
/// [height]:
static Future<T?> show<T>(
BuildContext context, {
required List<T> items,
required Widget Function(T item) itemBuilder,
int initialIndex = 0,
double itemExtent = 40.0,
double height = 250,
}) {
BuildContext context, {
required List<T> items,
required Widget Function(T item) itemBuilder,
int initialIndex = 0,
double itemExtent = 40.0,
double height = 250,
}) {
if (items.isEmpty) return Future.value(null);
//
@ -51,16 +51,25 @@ class BottomPicker {
children: [
//
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
padding: const EdgeInsets.symmetric(
horizontal: 16,
vertical: 8,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
TextButton(
onPressed: () {FocusScope.of(context).unfocus();Navigator.of(ctx).pop();},
onPressed: () {
FocusScope.of(context).unfocus();
Navigator.of(ctx).pop();
},
child: const Text('取消'),
),
TextButton(
onPressed: () {FocusScope.of(context).unfocus(); Navigator.of(ctx).pop(selected);},
onPressed: () {
FocusScope.of(context).unfocus();
Navigator.of(ctx).pop(selected);
},
child: const Text('确定'),
),
],
@ -70,8 +79,9 @@ class BottomPicker {
//
Expanded(
child: CupertinoPicker(
scrollController:
FixedExtentScrollController(initialItem: initialIndex),
scrollController: FixedExtentScrollController(
initialItem: initialIndex,
),
itemExtent: 30,
onSelectedItemChanged: (index) {
selected = items[index];

View File

@ -607,8 +607,8 @@ U6Hzm1ninpWeE+awIDAQAB
},
);
}
///
static Future<Map<String, dynamic>> dhGetFlowList(String hotworkId) {
///
static Future<Map<String, dynamic>> hotGetFlowList(String hotworkId) {
return HttpManager().request(
basePath,
'/app/hotwork/getFlowList',
@ -618,7 +618,18 @@ U6Hzm1ninpWeE+awIDAQAB
},
);
}
///
///
static Future<Map<String, dynamic>> highGetFlowList(String highworkId) {
return HttpManager().request(
basePath,
'/app/highwork/getFlowList',
method: Method.post,
data: {
"HIGHWORK_ID":highworkId
},
);
}
///
static Future<Map<String, dynamic>> getHomeworkFindById(String hotworkId) {
return HttpManager().request(
basePath,
@ -631,8 +642,22 @@ U6Hzm1ninpWeE+awIDAQAB
},
);
}
///
static Future<Map<String, dynamic>> getHighHomeworkFindById(String hotworkId) {
return HttpManager().request(
basePath,
'/app/highwork/findById',
method: Method.post,
data: {
"HIGHWORK_ID":hotworkId,
"CORPINFO_ID":SessionService.instance.corpinfoId,
"USER_ID":SessionService.instance.loginUserId,
},
);
}
///
static Future<Map<String, dynamic>> submitHotwork(String url, Map data) {
static Future<Map<String, dynamic>> submitHomework(String url, Map data) {
return HttpManager().request(
basePath,
url,
@ -681,22 +706,22 @@ U6Hzm1ninpWeE+awIDAQAB
);
}
///
static Future<Map<String, dynamic>> listSignFinishMeasures(String hotworkId) {
static Future<Map<String, dynamic>> listSignFinishMeasures(String workType,String hotworkId) {
return HttpManager().request(
basePath,
'/app/hotwork/listSignFinishMeasures',
'/app/$workType/listSignFinishMeasures',
method: Method.post,
data: {
"HOTWORK_ID":hotworkId,
},
);
}
///
static Future<Map<String, dynamic>> listSignFinishAllMeasures() {
/// hotwork
static Future<Map<String, dynamic>> listSignFinishAllMeasures(String workType) {
final String tm = DateTime.now().millisecondsSinceEpoch.toString();
return HttpManager().request(
basePath,
'/app/hotwork/listAllMeasures?tm=$tm',
'/app/$workType/listAllMeasures?tm=$tm',
method: Method.post,
data: {
"CORPINFO_ID":SessionService.instance.corpinfoId,
@ -756,6 +781,7 @@ U6Hzm1ninpWeE+awIDAQAB
);
}
///
static Future<Map<String, dynamic>> saveGasTest(
Map<String, dynamic> formData,
@ -780,6 +806,7 @@ U6Hzm1ninpWeE+awIDAQAB
}
///
static Future<Map<String, dynamic>> saveSafeFunctionSure (
String workType,
Map<String, dynamic> formData,
List<String> filePaths,
) async {
@ -796,7 +823,7 @@ U6Hzm1ninpWeE+awIDAQAB
}
return HttpManager().uploadFaceImage(
baseUrl: basePath,
path: '/app/hotwork/nextStep',
path: '/app/$workType/nextStep',
fromData: data,
);
}

View File

@ -3,12 +3,9 @@ import 'dart:io';
import 'package:flutter/material.dart';
import 'package:qhd_prevention/customWidget/custom_button.dart';
import '../../../customWidget/single_image_viewer.dart';
import '../../../tools/tools.dart';
class ItemListWidget {
static const Color detailtextColor = Colors.black54;
///
/// - + TextField
/// - +
@ -19,6 +16,7 @@ class ItemListWidget {
String? text, //
String hintText = '请输入',
double fontSize = 15, //
bool isRequired = true,
}) {
return Container(
padding: const EdgeInsets.symmetric(vertical: 5, horizontal: 12),
@ -28,9 +26,18 @@ class ItemListWidget {
? MainAxisAlignment.start
: MainAxisAlignment.spaceBetween,
children: [
Text(
label,
style: TextStyle(fontSize: fontSize, fontWeight: FontWeight.bold),
Row(
children: [
if (isRequired && isEditable)
Text('* ', style: TextStyle(color: Colors.red)),
Text(
label,
style: TextStyle(
fontSize: fontSize,
fontWeight: FontWeight.bold,
),
),
],
), //
const SizedBox(width: 8),
isEditable
@ -67,6 +74,7 @@ class ItemListWidget {
String? text, //
double fontSize = 15, //
double height = 110, //
bool isRequired = true,
}) {
return Container(
// padding线
@ -75,9 +83,18 @@ class ItemListWidget {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
label,
style: TextStyle(fontSize: fontSize, fontWeight: FontWeight.bold),
Row(
children: [
if (isRequired && isEditable)
Text('* ', style: TextStyle(color: Colors.red)),
Text(
label,
style: TextStyle(
fontSize: fontSize,
fontWeight: FontWeight.bold,
),
),
],
),
const SizedBox(height: 8),
Expanded(
@ -95,7 +112,7 @@ class ItemListWidget {
decoration: InputDecoration(
hintText: '请输入',
// TextField
contentPadding: EdgeInsets.zero,
//contentPadding: EdgeInsets.zero,
border: InputBorder.none,
),
)
@ -127,7 +144,7 @@ class ItemListWidget {
double fontSize = 15, //
bool isClean = false,
VoidCallback? onTapClean, //
bool isRequired = true,
}) {
return InkWell(
onTap: isEditable ? onTap : null,
@ -136,9 +153,18 @@ class ItemListWidget {
child: Row(
children: [
// 1.
Text(
label,
style: TextStyle(fontSize: fontSize, fontWeight: FontWeight.bold),
Row(
children: [
if (isRequired && isEditable)
Text('* ', style: TextStyle(color: Colors.red)),
Text(
label,
style: TextStyle(
fontSize: fontSize,
fontWeight: FontWeight.bold,
),
),
],
),
if (isClean)
Column(
@ -196,6 +222,7 @@ class ItemListWidget {
VoidCallback? onTap, //
double fontSize = 15, //
double row2Height = 80, //
bool isRequired = true,
}) {
return Container(
padding: const EdgeInsets.symmetric(vertical: 5, horizontal: 12),
@ -208,12 +235,18 @@ class ItemListWidget {
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
label,
style: TextStyle(
fontSize: fontSize,
fontWeight: FontWeight.bold,
),
Row(
children: [
if (isRequired && isEditable)
Text('* ', style: TextStyle(color: Colors.red)),
Text(
label,
style: TextStyle(
fontSize: fontSize,
fontWeight: FontWeight.bold,
),
),
],
),
Row(
children: [
@ -247,7 +280,7 @@ class ItemListWidget {
style: TextStyle(fontSize: fontSize),
decoration: InputDecoration(
hintText: '请输入',
contentPadding: EdgeInsets.zero,
//contentPadding: EdgeInsets.zero,
border: InputBorder.none,
),
)
@ -279,6 +312,7 @@ class ItemListWidget {
required String hintText,
double fontSize = 15, //
double row2Height = 80, //
bool isRequired = true,
}) {
return Container(
padding: const EdgeInsets.symmetric(vertical: 5, horizontal: 12),
@ -290,14 +324,24 @@ class ItemListWidget {
child: Row(
children: [
Flexible(
child: Text(
label,
style: TextStyle(
fontSize: fontSize,
fontWeight: FontWeight.bold,
),
maxLines: 1,
overflow: TextOverflow.ellipsis,
child: Row(
children: [
Row(
children: [
if (isRequired && isEditable)
Text('* ', style: TextStyle(color: Colors.red)),
Text(
label,
style: TextStyle(
fontSize: fontSize,
fontWeight: FontWeight.bold,
),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
],
),
],
),
),
const SizedBox(width: 8),
@ -331,7 +375,7 @@ class ItemListWidget {
style: TextStyle(fontSize: fontSize),
decoration: InputDecoration(
hintText: hintText,
contentPadding: EdgeInsets.zero,
//contentPadding: EdgeInsets.zero,
border: InputBorder.none,
),
)
@ -367,6 +411,7 @@ class ItemListWidget {
Expanded(
child: Row(
children: [
Text(
label,
style: TextStyle(
@ -409,15 +454,21 @@ class ItemListWidget {
required VoidCallback? onTap, //
double fontSize = 15, //
Color btnColor = Colors.blue,
bool isRequired = false,
}) {
return Container(
padding: const EdgeInsets.symmetric(vertical: 5, horizontal: 12),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
label,
style: TextStyle(fontSize: fontSize, fontWeight: FontWeight.bold),
Row(
children: [
Text("* ", style: TextStyle(color: Colors.red),),
Text(
label,
style: TextStyle(fontSize: fontSize, fontWeight: FontWeight.bold),
),
],
),
CustomButton(
text: buttonText,
@ -430,6 +481,7 @@ class ItemListWidget {
),
);
}
static Widget itemContainer(Widget child) {
return Container(
decoration: BoxDecoration(

View File

@ -5,7 +5,7 @@ import '../../../../../customWidget/ItemWidgetFactory.dart';
import '../../../../../customWidget/single_image_viewer.dart';
import '../../../../../tools/tools.dart';
import '../special_Wrok/MeasuresListWidget.dart';
import 'WorkDetailFormWidget.dart';
import 'dh_work/HotWorkDetailFormWidget.dart';
class SpecialWorkFormBaseWork extends StatelessWidget {
///
@ -221,7 +221,7 @@ class SpecialWorkFormBaseWork extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// 1.
WorkDetailFormWidget(
HotWorkDetailFormWidget(
pd: pd,
isEditable: isEditable,
onChooseLevel: onChooseLevel,

View File

@ -1,180 +0,0 @@
import 'package:flutter/material.dart';
import '../../../../../tools/tools.dart';
import '../../item_list_widget.dart';
import '../special_Wrok/MeasuresListWidget.dart';
///
/// TextEditingController
class WorkDetailFormWidget extends StatelessWidget {
final Map<String, dynamic> pd;
final bool isEditable;
final VoidCallback onChooseLevel;
final VoidCallback onChooseHotworkUser;
final VoidCallback onAnalyzeTap;
///
final TextEditingController? contentController;
final TextEditingController? locationController;
final TextEditingController? methodController;
final TextEditingController? hotworkPersonController;
final TextEditingController? relatedController;
final TextEditingController? riskController;
const WorkDetailFormWidget({
Key? key,
required this.pd,
required this.isEditable,
required this.onChooseLevel,
required this.onChooseHotworkUser,
required this.onAnalyzeTap,
this.contentController,
this.locationController,
this.methodController,
this.hotworkPersonController,
this.relatedController,
this.riskController,
}) : assert(
!isEditable ||
(contentController != null &&
locationController != null &&
methodController != null &&
hotworkPersonController != null &&
relatedController != null &&
riskController != null),
'Editable mode requires all TextEditingController parameters',
),
super(key: key);
@override
Widget build(BuildContext context) {
final pd = this.pd;
return
Container(
padding: EdgeInsets.symmetric(vertical: 10),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(5),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
ItemListWidget.singleLineTitleText(
label: '申请单位:',
isEditable: false,
text: pd['APPLY_DEPARTMENT_NAME'] ?? '',
),
const Divider(),
ItemListWidget.singleLineTitleText(
label: '申请人:',
isEditable: false,
text: pd['APPLY_USER_NAME'] ?? '',
),
if (FormUtils.hasValue(pd, 'CHECK_NO')) ...[
const Divider(),
ItemListWidget.singleLineTitleText(
label: '编号:',
isEditable: false,
text: pd['CHECK_NO'] ?? '',
),
],
const Divider(),
ItemListWidget.multiLineTitleTextField(
label: '作业内容:',
isEditable: isEditable,
controller: contentController,
text: pd['WORK_CONTENT'] ?? '',
),
const Divider(),
ItemListWidget.singleLineTitleText(
label: '动火地点及动火部位:',
isEditable: isEditable,
controller: locationController,
text: pd['WORK_PLACE'] ?? '',
),
const Divider(),
ItemListWidget.selectableLineTitleTextField(
label: '动火作业级别:',
isEditable: isEditable,
onTap: onChooseLevel,
text: pd['WORK_LEVEL'] ?? '',
),
const Divider(),
ItemListWidget.singleLineTitleText(
label: '动火方式:',
isEditable: isEditable,
controller: methodController,
text: pd['WORK_FUNCTION'] ?? '',
),
if (pd['WORK_START_DATE']?.toString().isNotEmpty == true) ...[
const Divider(),
ItemListWidget.singleLineTitleText(
label: '动火作业实施时间:',
isEditable: isEditable,
text: '${pd['WORK_START_DATE']}${pd['WORK_END_DATE'] ?? '--'}',
),
],
const Divider(),
ItemListWidget.twoRowSelectableTitleText(
label: '动火人及证书编号:',
isEditable: isEditable,
onTap: onChooseHotworkUser,
text: pd['WORK_USER'] ?? '',
controller: hotworkPersonController,
),
const Divider(),
ItemListWidget.twoRowButtonTitleText(
label: '关联其他特殊作业及安全作业票:',
isEditable: isEditable,
onTap: () async {
final val = await showDialog<String>(
context: context,
builder:
(_) => SelectionPopup(
type: 'assignments',
initialValue: pd['SPECIAL_WORK'] ?? '',
onConfirm: (v) => Navigator.of(context).pop(v),
),
);
if (val != null) pd['SPECIAL_WORK'] = val;
FocusHelper.clearFocus(context);
},
hintText: '请输入关联的其他特殊作业及安全作业票编号',
controller: relatedController,
text: pd['SPECIAL_WORK'] ?? '',
),
const Divider(),
ItemListWidget.twoRowButtonTitleText(
label: '风险辨识结果:',
isEditable: isEditable,
onTap: () async {
final val = await showDialog<String>(
context: context,
builder:
(_) => SelectionPopup(
type: 'identification',
initialValue: pd['RISK_IDENTIFICATION'] ?? '',
onConfirm: (v) => Navigator.of(context).pop(v),
),
);
if (val != null) pd['RISK_IDENTIFICATION'] = val;
FocusHelper.clearFocus(context);
},
hintText: '请输入风险辨识结果',
controller: riskController,
text: pd['RISK_IDENTIFICATION'] ?? '',
),
if (FormUtils.hasValue(pd, 'ANALYZE_TIME')) ...[
const Divider(),
ItemListWidget.OneRowButtonTitleText(
label: '分析人:',
text: pd['ANALYZE_USER_NAME'] ?? '',
onTap: onAnalyzeTap,
),
],
],
),
);
}
}

View File

@ -0,0 +1,188 @@
import 'package:flutter/material.dart';
import '../../../../../../tools/tools.dart';
import '../../../item_list_widget.dart';
import '../../special_Wrok/MeasuresListWidget.dart';
/// /
class HotWorkDetailFormWidget extends StatefulWidget {
final Map<String, dynamic> pd;
final bool isEditable;
final VoidCallback onChooseLevel;
final VoidCallback onChooseHotworkUser;
final VoidCallback onAnalyzeTap;
///
final TextEditingController? contentController;
final TextEditingController? locationController;
final TextEditingController? methodController;
final TextEditingController? hotworkPersonController;
final TextEditingController? relatedController;
final TextEditingController? riskController;
const HotWorkDetailFormWidget({
Key? key,
required this.pd,
required this.isEditable,
required this.onChooseLevel,
required this.onChooseHotworkUser,
required this.onAnalyzeTap,
this.contentController,
this.locationController,
this.methodController,
this.hotworkPersonController,
this.relatedController,
this.riskController,
}) : assert(
!isEditable ||
(contentController != null &&
locationController != null &&
methodController != null &&
hotworkPersonController != null &&
relatedController != null &&
riskController != null),
'Editable mode requires all TextEditingController parameters',
),
super(key: key);
@override
State<HotWorkDetailFormWidget> createState() => _HotWorkDetailFormWidgetState();
}
class _HotWorkDetailFormWidgetState extends State<HotWorkDetailFormWidget> {
@override
Widget build(BuildContext context) {
final pd = widget.pd;
return Container(
padding: const EdgeInsets.symmetric(vertical: 10),
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(5)),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
ItemListWidget.singleLineTitleText(
label: '申请单位:',
isEditable: false,
text: pd['APPLY_DEPARTMENT_NAME'] ?? '',
),
const Divider(),
ItemListWidget.singleLineTitleText(
label: '申请人:',
isEditable: false,
text: pd['APPLY_USER_NAME'] ?? '',
),
if (FormUtils.hasValue(pd, 'CHECK_NO')) ...[
const Divider(),
ItemListWidget.singleLineTitleText(
label: '编号:',
isEditable: false,
text: pd['CHECK_NO'] ?? '',
),
],
const Divider(),
ItemListWidget.multiLineTitleTextField(
label: '作业内容:',
isEditable: widget.isEditable,
controller: widget.contentController,
text: pd['WORK_CONTENT'] ?? '',
),
const Divider(),
ItemListWidget.singleLineTitleText(
label: '动火地点及动火部位:',
isEditable: widget.isEditable,
controller: widget.locationController,
text: pd['WORK_PLACE'] ?? '',
),
const Divider(),
ItemListWidget.selectableLineTitleTextField(
label: '动火作业级别:',
isEditable: widget.isEditable,
onTap: widget.onChooseLevel,
text: pd['WORK_LEVEL'] ?? '',
),
const Divider(),
ItemListWidget.singleLineTitleText(
label: '动火方式:',
isEditable: widget.isEditable,
controller: widget.methodController,
text: pd['WORK_FUNCTION'] ?? '',
),
if (pd['WORK_START_DATE']?.toString().isNotEmpty == true) ...[
const Divider(),
ItemListWidget.singleLineTitleText(
label: '动火作业实施时间:',
isEditable: false,
text: '${pd['WORK_START_DATE']}${pd['WORK_END_DATE'] ?? '--'}',
),
],
const Divider(),
ItemListWidget.twoRowSelectableTitleText(
label: '动火人及证书编号:',
isEditable: widget.isEditable,
onTap: widget.onChooseHotworkUser,
text: pd['WORK_USER'] ?? '',
controller: widget.hotworkPersonController,
),
const Divider(),
ItemListWidget.twoRowButtonTitleText(
label: '关联其他特殊作业及安全作业票:',
isEditable: widget.isEditable,
onTap: () async {
final val = await showDialog<String>(
context: context,
builder: (_) => SelectionPopup(
type: 'assignments',
initialValue: pd['SPECIAL_WORK'] ?? '',
onConfirm: (val) {
setState(() {
pd['SPECIAL_WORK'] = val;
widget.relatedController?.text = val;
});
},
),
);
FocusHelper.clearFocus(context);
},
hintText: '请输入关联的其他特殊作业及安全作业票编号',
controller: widget.relatedController,
text: pd['SPECIAL_WORK'] ?? '',
),
const Divider(),
ItemListWidget.twoRowButtonTitleText(
label: '风险辨识结果:',
isEditable: widget.isEditable,
onTap: () async {
await showDialog<String>(
context: context,
builder: (_) => SelectionPopup(
type: 'identification',
initialValue: pd['RISK_IDENTIFICATION'] ?? '',
onConfirm: (val) {
setState(() {
pd['RISK_IDENTIFICATION'] = val;
widget.riskController?.text = val;
});
},
),
);
FocusHelper.clearFocus(context);
},
hintText: '请输入风险辨识结果',
controller: widget.riskController,
text: pd['RISK_IDENTIFICATION'] ?? '',
),
if (FormUtils.hasValue(pd, 'ANALYZE_TIME')) ...[
const Divider(),
ItemListWidget.OneRowButtonTitleText(
label: '分析人:',
text: pd['ANALYZE_USER_NAME'] ?? '',
onTap: widget.onAnalyzeTap,
),
],
],
),
);
}
}

View File

@ -18,7 +18,7 @@ import 'package:qhd_prevention/pages/mine/mine_sign_page.dart';
import 'package:qhd_prevention/pages/my_appbar.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_Wrok/MeasuresListWidget.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_Wrok/dh_work/qtfx_work_detail/hotwork_gas_list.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/WorkDetailFormWidget.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/HotWorkDetailFormWidget.dart';
///
class HotworkSafeFuncSure extends StatefulWidget {
@ -254,7 +254,7 @@ class _HotworkSafeFuncSureState extends State<HotworkSafeFuncSure> {
onConfirm: () async {
LoadingDialogHelper.show(context);
try {
final result = await ApiService.saveSafeFunctionSure(
final result = await ApiService.saveSafeFunctionSure('hotwork',
formData,
imagePaths,
);
@ -453,7 +453,7 @@ class _HotworkSafeFuncSureState extends State<HotworkSafeFuncSure> {
padding: EdgeInsets.all(12),
child: Column(
children: [
WorkDetailFormWidget(
HotWorkDetailFormWidget(
pd: pd,
isEditable: false,
onChooseLevel: () {},

View File

@ -180,7 +180,7 @@ class _HotworkAqglDetailState extends State<HotworkAqglDetail> {
onConfirm: () async {
LoadingDialogHelper.show(context);
try {
final result = await ApiService.saveSafeFunctionSure(
final result = await ApiService.saveSafeFunctionSure('hotwork',
formData,
signImages,
);
@ -210,7 +210,7 @@ class _HotworkAqglDetailState extends State<HotworkAqglDetail> {
}
Future<void> _getMeasures(String homework_id) async {
final data = await ApiService.listSignFinishMeasures(
final data = await ApiService.listSignFinishMeasures('hotwork',
homework_id.length > 0 ? homework_id : widget.HOTWORK_ID,
);
setState(() {

View File

@ -210,7 +210,7 @@ class _HotworkAqjdDetailState extends State<HotworkAqjdDetail> {
onConfirm: () async {
LoadingDialogHelper.show(context);
try {
final result = await ApiService.saveSafeFunctionSure(
final result = await ApiService.saveSafeFunctionSure('hotwork',
formData,
signImages,
);
@ -240,7 +240,7 @@ class _HotworkAqjdDetailState extends State<HotworkAqjdDetail> {
}
Future<void> _getMeasures(String homework_id) async {
final data = await ApiService.listSignFinishMeasures(
final data = await ApiService.listSignFinishMeasures('hotwork',
homework_id.length > 0 ? homework_id : widget.HOTWORK_ID,
);
setState(() {

View File

@ -183,6 +183,7 @@ class _HotworkDbbzDetailState extends State<HotworkDbbzDetail> {
LoadingDialogHelper.show(context);
try {
final result = await ApiService.saveSafeFunctionSure(
'hotwork',
formData,
signImages,
);
@ -212,7 +213,7 @@ class _HotworkDbbzDetailState extends State<HotworkDbbzDetail> {
}
Future<void> _getMeasures(String homework_id) async {
final data = await ApiService.listSignFinishMeasures(
final data = await ApiService.listSignFinishMeasures('hotwork',
homework_id.length > 0 ? homework_id : widget.HOTWORK_ID,
);
setState(() {

View File

@ -7,7 +7,7 @@ import 'package:qhd_prevention/customWidget/department_person_picker.dart';
import 'package:qhd_prevention/customWidget/department_picker.dart';
import 'package:qhd_prevention/customWidget/toast_util.dart';
import 'package:qhd_prevention/pages/home/tap/item_list_widget.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/WorkDetailFormWidget.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/HotWorkDetailFormWidget.dart';
import 'package:qhd_prevention/tools/h_colors.dart';
import 'package:qhd_prevention/tools/tools.dart';
import 'package:qhd_prevention/http/ApiService.dart';
@ -301,6 +301,7 @@ class _HotworkApplyDetailState extends State<HotworkApplyDetail> {
if (personList.isEmpty) {
//
ToastUtil.showNormal(context, '请先选择' + type.displayName);
return;
}
DepartmentPersonPicker.show(
@ -408,7 +409,7 @@ class _HotworkApplyDetailState extends State<HotworkApplyDetail> {
printLongString(jsonStr);
try {
String url = "/app/hotwork/" + msg;
final result = await ApiService.submitHotwork(url, pd);
final result = await ApiService.submitHomework(url, pd);
LoadingDialogHelper.hide(context);
if (result['result'] == 'success') {
ToastUtil.showSuccess(context, status == '1' ? '提交成功' : '已暂存');
@ -472,7 +473,7 @@ class _HotworkApplyDetailState extends State<HotworkApplyDetail> {
}
Future<void> _getMeasures(String homework_id) async {
final data = await ApiService.listSignFinishMeasures(
final data = await ApiService.listSignFinishMeasures('hotwork',
homework_id.length > 0 ? homework_id : widget.HOTWORK_ID,
);
setState(() {
@ -493,7 +494,7 @@ class _HotworkApplyDetailState extends State<HotworkApplyDetail> {
child: Column(
children: [
_card(
WorkDetailFormWidget(
HotWorkDetailFormWidget(
pd: pd,
isEditable: isEditable,
contentController: _contentController,

View File

@ -180,6 +180,7 @@ class _HotworkDhspDetailState extends State<HotworkDhspDetail> {
LoadingDialogHelper.show(context);
try {
final result = await ApiService.saveSafeFunctionSure(
'hotwork',
formData,
signImages,
);
@ -209,7 +210,7 @@ class _HotworkDhspDetailState extends State<HotworkDhspDetail> {
}
Future<void> _getMeasures(String homework_id) async {
final data = await ApiService.listSignFinishMeasures(
final data = await ApiService.listSignFinishMeasures('hotwork',
homework_id.length > 0 ? homework_id : widget.HOTWORK_ID,
);
setState(() {

View File

@ -137,7 +137,7 @@ class _HotWorkListPageState extends State<HotWorkListPage> {
///
Future<void> _openFlowDrawer(String hotworkId) async {
try {
final response = await ApiService.dhGetFlowList(hotworkId);
final response = await ApiService.hotGetFlowList(hotworkId);
final List<dynamic>? newFlow = response['flowList'];
if (newFlow == null || newFlow.isEmpty) {
ToastUtil.showNormal(context, '暂无流程图数据');

View File

@ -4,7 +4,7 @@ import 'package:intl/intl.dart';
import 'package:qhd_prevention/customWidget/ItemWidgetFactory.dart';
import 'package:qhd_prevention/customWidget/custom_button.dart';
import 'package:qhd_prevention/customWidget/toast_util.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/WorkDetailFormWidget.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/HotWorkDetailFormWidget.dart';
import 'package:qhd_prevention/tools/tools.dart';
import 'package:qhd_prevention/http/ApiService.dart';
import 'package:qhd_prevention/pages/my_appbar.dart';
@ -170,6 +170,7 @@ class _HotworkJhrDetailState extends State<HotworkJhrDetail> {
LoadingDialogHelper.show(context);
try {
final result = await ApiService.saveSafeFunctionSure(
'hotwork',
formData,
imagePaths,
);
@ -202,7 +203,7 @@ class _HotworkJhrDetailState extends State<HotworkJhrDetail> {
}
Future<void> _getMeasures(String homework_id) async {
final data = await ApiService.listSignFinishMeasures(
final data = await ApiService.listSignFinishMeasures('hotwork',
homework_id.length > 0 ? homework_id : widget.HOTWORK_ID,
);
setState(() {
@ -326,7 +327,7 @@ class _HotworkJhrDetailState extends State<HotworkJhrDetail> {
child: Column(
children: [
// _card(_defaultDetail()),
WorkDetailFormWidget(
HotWorkDetailFormWidget(
pd: pd,
isEditable: false,
onChooseLevel: (){},

View File

@ -171,6 +171,7 @@ class _HotworkJsjdDetailState extends State<HotworkJsjdDetail> {
LoadingDialogHelper.show(context);
try {
final result = await ApiService.saveSafeFunctionSure(
'hotwork',
formData,
signImages,
);
@ -200,7 +201,7 @@ class _HotworkJsjdDetailState extends State<HotworkJsjdDetail> {
}
Future<void> _getMeasures(String homework_id) async {
final data = await ApiService.listSignFinishMeasures(
final data = await ApiService.listSignFinishMeasures('hotwork',
homework_id.length > 0 ? homework_id : widget.HOTWORK_ID,
);
setState(() {

View File

@ -216,6 +216,7 @@ class _HotworkJszyDetailState extends State<HotworkJszyDetail> {
LoadingDialogHelper.show(context);
try {
final result = await ApiService.saveSafeFunctionSure(
'hotwork',
formData,
signImages,
);
@ -245,7 +246,7 @@ class _HotworkJszyDetailState extends State<HotworkJszyDetail> {
}
Future<void> _getMeasures(String homework_id) async {
final data = await ApiService.listSignFinishMeasures(
final data = await ApiService.listSignFinishMeasures('hotwork',
homework_id.length > 0 ? homework_id : widget.HOTWORK_ID,
);
setState(() {

View File

@ -188,7 +188,7 @@ class _HotworkKszyDetailState extends State<HotworkKszyDetail> {
onConfirm: () async {
LoadingDialogHelper.show(context);
try {
final result = await ApiService.saveSafeFunctionSure(
final result = await ApiService.saveSafeFunctionSure('hotwork',
formData,
signImages,
);
@ -218,7 +218,7 @@ class _HotworkKszyDetailState extends State<HotworkKszyDetail> {
}
Future<void> _getMeasures(String homework_id) async {
final data = await ApiService.listSignFinishMeasures(
final data = await ApiService.listSignFinishMeasures('hotwork',
homework_id.length > 0 ? homework_id : widget.HOTWORK_ID,
);
setState(() {

View File

@ -9,7 +9,7 @@ import 'package:qhd_prevention/customWidget/department_person_picker.dart';
import 'package:qhd_prevention/customWidget/department_picker.dart';
import 'package:qhd_prevention/customWidget/toast_util.dart';
import 'package:qhd_prevention/pages/home/tap/item_list_widget.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/WorkDetailFormWidget.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/HotWorkDetailFormWidget.dart';
import 'package:qhd_prevention/tools/tools.dart';
import 'package:qhd_prevention/http/ApiService.dart';
import 'package:qhd_prevention/pages/my_appbar.dart';
@ -321,6 +321,7 @@ class _HotworkSetSafeDetailState extends State<HotworkSetSafeDetail> {
LoadingDialogHelper.show(context);
try {
final result = await ApiService.saveSafeFunctionSure(
'hotwork',
formData,
imagePaths,
);
@ -358,7 +359,7 @@ class _HotworkSetSafeDetailState extends State<HotworkSetSafeDetail> {
}
Future<void> _getMeasures() async {
final data = await ApiService.listSignFinishAllMeasures();
final data = await ApiService.listSignFinishAllMeasures('hotwork');
setState(() {
measuresList = List<Map<String, dynamic>>.from(
data['measuresList'] ?? <Map<String, dynamic>>[],
@ -544,7 +545,7 @@ class _HotworkSetSafeDetailState extends State<HotworkSetSafeDetail> {
child: Column(
children: [
// _card(_defaultDetail()),
WorkDetailFormWidget(
HotWorkDetailFormWidget(
pd: pd,
isEditable: false,
onChooseLevel: (){},

View File

@ -180,6 +180,7 @@ class _HotworkSzdwDetailState extends State<HotworkSzdwDetail> {
LoadingDialogHelper.show(context);
try {
final result = await ApiService.saveSafeFunctionSure(
'hotwork',
formData,
signImages,
);
@ -199,7 +200,7 @@ class _HotworkSzdwDetailState extends State<HotworkSzdwDetail> {
///
Future<void> _getData() async {
final data = await ApiService.getHomeworkFindById(widget.HOTWORK_ID);
final data = await ApiService.getHighHomeworkFindById(widget.HOTWORK_ID);
setState(() {
pd = data['pd'];
@ -209,7 +210,7 @@ class _HotworkSzdwDetailState extends State<HotworkSzdwDetail> {
}
Future<void> _getMeasures(String homework_id) async {
final data = await ApiService.listSignFinishMeasures(
final data = await ApiService.listSignFinishMeasures('hotwork',
homework_id.length > 0 ? homework_id : widget.HOTWORK_ID,
);
setState(() {

View File

@ -237,6 +237,7 @@ class _HotworkYsgdDetailState extends State<HotworkYsgdDetail> {
LoadingDialogHelper.show(context);
try {
final result = await ApiService.saveSafeFunctionSure(
'hotwork',
formData,
signImages,
);
@ -266,7 +267,7 @@ class _HotworkYsgdDetailState extends State<HotworkYsgdDetail> {
}
Future<void> _getMeasures(String homework_id) async {
final data = await ApiService.listSignFinishMeasures(
final data = await ApiService.listSignFinishMeasures('hotwork',
homework_id.length > 0 ? homework_id : widget.HOTWORK_ID,
);
setState(() {

View File

@ -180,6 +180,7 @@ class _HotworkZyfzDetailState extends State<HotworkZyfzDetail> {
LoadingDialogHelper.show(context);
try {
final result = await ApiService.saveSafeFunctionSure(
'hotwork',
formData,
signImages,
);
@ -209,7 +210,7 @@ class _HotworkZyfzDetailState extends State<HotworkZyfzDetail> {
}
Future<void> _getMeasures(String homework_id) async {
final data = await ApiService.listSignFinishMeasures(
final data = await ApiService.listSignFinishMeasures('hotwork',
homework_id.length > 0 ? homework_id : widget.HOTWORK_ID,
);
setState(() {

View File

@ -0,0 +1,155 @@
import 'package:flutter/material.dart';
import '../../../../../../tools/tools.dart';
import '../../../item_list_widget.dart';
import '../../special_Wrok/MeasuresListWidget.dart';
/// /
class HighWorkDetailFormWidget extends StatefulWidget {
final Map<String, dynamic> pd;
final bool isEditable;
final VoidCallback onChooseLevel;
///
final TextEditingController? locationController; //
final TextEditingController? hightController; //
final TextEditingController? contentController; //
final TextEditingController? relatedController;
final TextEditingController? riskController;
const HighWorkDetailFormWidget({
Key? key,
required this.pd,
required this.isEditable,
required this.onChooseLevel,
this.locationController,
this.hightController,
this.contentController,
this.relatedController,
this.riskController,
}) : assert(
!isEditable ||
(locationController != null &&
hightController != null &&
contentController != null &&
relatedController != null &&
riskController != null),
'Editable mode requires all TextEditingController parameters',
),
super(key: key);
@override
State<HighWorkDetailFormWidget> createState() => _HighWorkDetailFormWidgetState();
}
class _HighWorkDetailFormWidgetState extends State<HighWorkDetailFormWidget> {
String _getWorkLevelText(dynamic level) {
switch (level?.toString()) {
case '1': return 'I级高处作业';
case '2': return 'II级高处作业';
case '3': return 'III级高处作业';
case '4': return 'IV级高处作业';
default: return '';
}
}
@override
Widget build(BuildContext context) {
final pd = widget.pd;
return Container(
padding: const EdgeInsets.symmetric(vertical: 10),
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(5)),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
if (!widget.isEditable && FormUtils.hasValue(pd, 'CHECK_NO')) ...[
ItemListWidget.singleLineTitleText(
label: '编号:',
isEditable: false,
text: pd['CHECK_NO'] ?? '',
),
const Divider(),
],
ItemListWidget.singleLineTitleText(
label: '作业地点:',
isEditable: widget.isEditable,
controller: widget.locationController,
text: pd['WORK_PLACE'] ?? '',
),
const Divider(),
ItemListWidget.singleLineTitleText(
label: '作业高度(米):',
isEditable: widget.isEditable,
controller: widget.hightController,
text: pd['WORK_HIGH'] ?? '',
),
const Divider(),
ItemListWidget.selectableLineTitleTextField(
label: '高处作业级别:',
isEditable: widget.isEditable,
onTap: widget.onChooseLevel,
text: _getWorkLevelText(pd['WORK_LEVEL']),
),
const Divider(),
ItemListWidget.multiLineTitleTextField(
label: '作业内容:',
isEditable: widget.isEditable,
controller: widget.contentController,
text: pd['WORK_CONTENT'] ?? '',
),
const Divider(),
ItemListWidget.twoRowButtonTitleText(
label: '关联的其他特殊作业及安全作业票编号:',
isEditable: widget.isEditable,
onTap: () async {
final val = await showDialog<String>(
context: context,
builder: (_) => SelectionPopup(
type: 'assignments',
initialValue: pd['SPECIAL_WORK'] ?? '',
onConfirm: (v) {
setState(() {
pd['SPECIAL_WORK'] = v;
widget.relatedController?.text = v;
});
},
),
);
FocusHelper.clearFocus(context);
},
hintText: '请输入关联的其他特殊作业及安全作业票编号',
controller: widget.relatedController,
text: pd['SPECIAL_WORK'] ?? '',
),
const Divider(),
ItemListWidget.twoRowButtonTitleText(
label: '风险辨识结果:',
isEditable: widget.isEditable,
onTap: () async {
await showDialog<String>(
context: context,
builder: (_) => SelectionPopup(
type: 'identification',
initialValue: pd['RISK_IDENTIFICATION'] ?? '',
onConfirm: (v) {
setState(() {
pd['RISK_IDENTIFICATION'] = v;
widget.riskController?.text = v;
});
},
),
);
FocusHelper.clearFocus(context);
},
hintText: '请输入风险辨识结果',
controller: widget.riskController,
text: pd['RISK_IDENTIFICATION'] ?? '',
),
],
),
);
}
}

View File

@ -0,0 +1,360 @@
import 'dart:io';
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:qhd_prevention/customWidget/toast_util.dart';
import 'package:qhd_prevention/http/ApiService.dart';
import 'package:qhd_prevention/pages/my_appbar.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/tools/tools.dart';
import 'package:qhd_prevention/pages/mine/mine_sign_page.dart';
/// + 线
class ImageData {
String localPath;
String serverPath;
ImageData({required this.localPath, required this.serverPath});
}
class SignImageData {
String SIGNER_TIME;
String? filePath;
int? key = 0;
SignImageData({
required this.SIGNER_TIME,
required this.filePath,
required this.key,
});
Map<String, dynamic> toJson() => {
'SIGNER_TIME': SIGNER_TIME,
'filePath': filePath,
'key': key,
};
factory SignImageData.fromJson(Map<String, dynamic> json) {
return SignImageData(
SIGNER_TIME: json['SIGNER_TIME'] as String,
filePath: json['filePath'] as String?,
key:
json['key'] is int
? json['key'] as int
: int.tryParse(json['key']?.toString() ?? ''),
);
}
}
class DangerousOptionsPage extends StatefulWidget {
final int index;
final int status;
final String measures;
final List<ImageData> imgList;
final List<Map<String, dynamic>> signImgList;
const DangerousOptionsPage({
Key? key,
required this.index,
this.status = 1,
this.measures = '',
this.imgList = const [],
this.signImgList = const [],
}) : super(key: key);
@override
_DangerousOptionsPageState createState() => _DangerousOptionsPageState();
}
class _DangerousOptionsPageState extends State<DangerousOptionsPage> {
late int index;
late int status;
late String measures;
late List<ImageData> imgList;
late List<SignImageData> signImgList;
List<String> signTimes = [];
bool buttonLoading = false;
@override
void initState() {
super.initState();
index = widget.index;
status = widget.status;
measures = widget.measures;
imgList = List<ImageData>.from(widget.imgList);
signImgList =
widget.signImgList.map((map) => SignImageData.fromJson(map)).toList();
}
///
Future<void> _onImageAdded(String localPath) async {
//
final res = await ApiService.uploadSaveFile(localPath);
final url = res['FILE_PATH'] as String;
setState(() {
imgList.add(ImageData(localPath: localPath, serverPath: url));
});
}
///
Future<void> _onImageRemoved(ImageData item) async {
if (item.serverPath != null) {
await ApiService.deleteSaveFile(item.serverPath!);
}
setState(() {
imgList.remove(item);
});
}
Future<void> _submit() async {
if (signImgList.isEmpty) {
ToastUtil.showNormal(context, '请签字');
return;
}
List<String> filePaths =
signImgList.map((img) => img.filePath ?? '').toList();
final result = await ApiService.saveDangerousOptionsFile(filePaths);
final List<dynamic> signList = result['FILE_PATH_LIST'];
List<Map<String, dynamic>> sineImageList = [];
for (SignImageData data in signImgList) {
for (Map<String, dynamic> img in signList) {
String imgName = 'file${data.key}';
if (data.filePath!.contains('uploadFiles')) {
final idata = {
'filePath': data.filePath,
'SIGNER_TIME': data.SIGNER_TIME,
'key': data.key,
};
sineImageList.add(idata);
}
if (imgName == img['key']) {
final idata = {
'filePath': img['filePath'] ?? '',
'SIGNER_TIME': data.SIGNER_TIME,
'key': data.key,
};
sineImageList.add(idata);
}
}
}
setState(() => buttonLoading = true);
Navigator.pop(context, {
'imgList':
imgList
.map((e) => {'local': e.localPath, 'remote': e.serverPath})
.toList(),
'signImgList': sineImageList,
'index': index,
'status': status,
});
}
Future<void> _sign() async {
final String path = await Navigator.push(
context,
MaterialPageRoute(builder: (c) => MineSignPage()),
);
if (path != null) {
final now = DateFormat('yyyy-MM-dd HH:mm').format(DateTime.now());
setState(() {
final imageData = SignImageData(
SIGNER_TIME: now,
filePath: path,
key: signImgList.length,
);
signImgList.add(imageData);
signTimes.add(now);
});
FocusHelper.clearFocus(context);
}
}
Widget _signListWidget() {
return Column(
children:
signImgList.map((imgData) {
final idx = signImgList.indexOf(imgData);
return Column(
children: [
const SizedBox(height: 10),
const Divider(),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
GestureDetector(
child: ConstrainedBox(
constraints: const BoxConstraints(
maxWidth: 230,
maxHeight: 150,
),
child:
(imgData.filePath ?? '').contains('uploadFiles')
? Image.network(
'${ApiService.baseImgPath}${imgData.filePath}',
)
: Image.file(
File(imgData.filePath ?? ''),
fit: BoxFit.contain,
),
),
onTap:
() => presentOpaque(
SingleImageViewer(imageUrl: imgData.filePath ?? ''),
context,
),
),
Column(
children: [
CustomButton(
text: '删除',
height: 30,
padding: const EdgeInsets.symmetric(horizontal: 10),
backgroundColor: Colors.red,
onPressed: () {
setState(() => signImgList.removeAt(idx));
},
),
const SizedBox(height: 80),
],
),
],
),
],
);
}).toList(),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: MyAppbar(title: '安全措施'),
body: Padding(
padding: const EdgeInsets.all(12.0),
child: Container(
padding: EdgeInsets.symmetric(horizontal: 10, vertical: 10),
color: Colors.white,
child: ListView(
children: [
Table(
border: TableBorder.all(color: Colors.grey.shade300),
columnWidths: {0: FlexColumnWidth(3), 1: FlexColumnWidth(2)},
children: [
TableRow(
decoration: BoxDecoration(color: Colors.grey.shade200),
children: [
Padding(
padding: EdgeInsets.all(10),
child: Center(
child: Text(
'主要安全措施',
style: TextStyle(fontWeight: FontWeight.bold),
),
),
),
Padding(
padding: EdgeInsets.all(10),
child: Center(
child: Text(
'操作',
style: TextStyle(fontWeight: FontWeight.bold),
),
),
),
],
),
TableRow(
children: [
Padding(
padding: const EdgeInsets.symmetric(
vertical: 12,
horizontal: 5,
),
child: Text(measures),
),
Padding(
padding: const EdgeInsets.all(0),
child: Column(
children: [
RadioListTile<int>(
value: -1,
groupValue: status,
title: Text('不涉及'),
contentPadding: const EdgeInsets.symmetric(
vertical: 0,
horizontal: 8.0,
),
visualDensity: VisualDensity(
vertical: -4,
horizontal: 0,
),
onChanged: (v) => setState(() => status = v!),
),
RadioListTile<int>(
value: 1,
groupValue: status,
title: Text('涉及'),
contentPadding: const EdgeInsets.symmetric(
vertical: 4.0,
horizontal: 8.0,
),
visualDensity: VisualDensity(
vertical: -4,
horizontal: 0,
),
onChanged: (v) => setState(() => status = v!),
),
],
),
),
],
),
],
),
const SizedBox(height: 20),
RepairedPhotoSection(
title: '上传图片',
maxCount: 2,
mediaType: MediaType.image,
initialMediaPaths:
imgList
.map((e) => '${ApiService.baseImgPath}${e.serverPath}')
.toList(),
onChanged: (paths) {},
onMediaAdded: _onImageAdded,
onMediaRemoved: (path) {
final item = imgList.firstWhere((e) => e.localPath == path);
_onImageRemoved(item);
},
onAiIdentify: () {},
),
const SizedBox(height: 20),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text('签字:', style: TextStyle(fontSize: 16)),
CustomButton(
text: '新增手写签字',
height: 36,
backgroundColor: Colors.green,
onPressed: _sign,
),
],
),
if (signImgList.isNotEmpty) _signListWidget(),
const SizedBox(height: 30),
CustomButton(
text: '保存',
backgroundColor: Colors.blue,
onPressed: buttonLoading ? null : _submit,
),
],
),
),
),
);
}
}

View File

@ -0,0 +1,516 @@
import 'dart:convert';
import 'dart:io';
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:qhd_prevention/customWidget/ItemWidgetFactory.dart';
import 'package:qhd_prevention/customWidget/custom_button.dart';
import 'package:qhd_prevention/customWidget/department_person_picker.dart';
import 'package:qhd_prevention/customWidget/department_picker.dart';
import 'package:qhd_prevention/customWidget/toast_util.dart';
import 'package:qhd_prevention/pages/home/tap/item_list_widget.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/aqcs_work_detail/dangerous_options_page.dart';
import 'package:qhd_prevention/tools/tools.dart';
import 'package:qhd_prevention/customWidget/custom_alert_dialog.dart';
import 'package:qhd_prevention/customWidget/single_image_viewer.dart';
import 'package:qhd_prevention/http/ApiService.dart';
import 'package:qhd_prevention/pages/mine/mine_sign_page.dart';
import 'package:qhd_prevention/pages/my_appbar.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_Wrok/MeasuresListWidget.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_Wrok/dh_work/qtfx_work_detail/hotwork_gas_list.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/HotWorkDetailFormWidget.dart';
///
class HotworkSafeFuncSure extends StatefulWidget {
const HotworkSafeFuncSure({
super.key,
required this.HOTWORK_ID,
required this.flow,
});
final String HOTWORK_ID;
final String flow;
@override
State<HotworkSafeFuncSure> createState() => _HotworkSafeFuncSureState();
}
class _HotworkSafeFuncSureState extends State<HotworkSafeFuncSure> {
late bool isEditable = false;
final levelList = ["特级", "一级", "二级"];
///
late String msg = 'add';
///
late Map<String, dynamic> pd = {};
late List<Map<String, dynamic>> measuresList = [];
///
final TextEditingController _otherController = TextEditingController();
///
late List<dynamic> workUserList = [];
///
List<String> imagePaths = [];
List<String> signTimes = []; //
@override
void initState() {
super.initState();
_getData();
_getHotWorkNameList();
}
///
void chooseUnitHandle(MeasureItem item) {
showModalBottomSheet(
context: context,
isScrollControlled: true,
barrierColor: Colors.black54,
backgroundColor: Colors.transparent,
builder:
(_) =>
DepartmentPicker(
onSelected: (id, name) async {
setState(() {
item.DEPARTMENT_ID = id;
item.DEPARTMENT_NAME = name;
});
_getPersonListForUnitId(item);
},
),
).then((_) {});
}
Future<void> _getPersonListForUnitId(MeasureItem item) async {
//
final result = await ApiService.getListTreePersonList(item.DEPARTMENT_ID);
setState(() {
item.userList = List<Map<String, dynamic>>.from(
result['userList'] ?? <Map<String, dynamic>>[],
);
});
}
///
Future<void> _sign() async {
FocusHelper.clearFocus(context);
final path = await Navigator.push(
context,
MaterialPageRoute(builder: (context) => MineSignPage()),
);
if (path != null) {
final now = DateFormat('yyyy-MM-dd HH:mm').format(DateTime.now());
setState(() {
imagePaths.add(path);
signTimes.add(now);
FocusHelper.clearFocus(context);
});
}
}
Widget _signListWidget() {
return Column(
children:
imagePaths.map((path) {
return Column(
children: [
const SizedBox(height: 10),
const Divider(),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
GestureDetector(
child: // ConstrainedBox BoxFit.contain
ConstrainedBox(
constraints: const BoxConstraints(
maxWidth: 200,
maxHeight: 150,
),
child: Image.file(
File(path),
//
fit: BoxFit.contain,
),
),
onTap: () {
presentOpaque(
SingleImageViewer(imageUrl: path),
context,
);
},
),
Column(
children: [
Container(
padding: const EdgeInsets.only(right: 5),
child: CustomButton(
text: 'X',
height: 30,
padding: const EdgeInsets.symmetric(horizontal: 10),
backgroundColor: Colors.red,
onPressed: () {
setState(() {
imagePaths.remove(path);
});
},
),
),
const SizedBox(height: 80),
],
),
],
),
],
);
}).toList(),
);
}
bool _validateAndProceed(BuildContext context) {
for (var i = 0; i < measuresList.length; i++) {
final m = measuresList[i];
// 1.
if (!FormUtils.hasValue(m, 'SIGN_ITEM')) {
ToastUtil.showNormal(context, '${i + 1}项未签字');
return false;
}
// STATUS == '1' ANSWER
if (m['STATUS'] == '1') {
for (var j = 1; j <= 4; j++) {
if (FormUtils.hasValue(m, 'QUESTION${j}')
) {
if (!FormUtils.hasValue(m, 'ANSWER${j}')
|| (m['ANSWER${j}'] as String?)!.length == 0) {
ToastUtil.showNormal(context, '${i + 1}项未填写第${j}');
return false;
}
}
}
}
}
return true;
}
/// 1 0
Future<void> _submit(String status) async {
if (_otherController.text.trim().isEmpty) {
ToastUtil.showNormal(context, '请输入其他安全措施,没有请填“无”');
return;
}
if (imagePaths.isEmpty) {
ToastUtil.showNormal(context, '请签字');
return;
}
String reasonText = '';
if (status == '1') {
if (!_validateAndProceed(context)) {
return;
}
} else {
await showDialog<String>(
context: context,
builder:
(_) =>
CustomAlertDialog(
title: '作废原因',
mode: DialogMode.input,
hintText: '请输入作废原因',
cancelText: '取消',
confirmText: '确定',
onInputConfirm: (text) {
reasonText = text;
},
),
);
if (reasonText.isEmpty) {
ToastUtil.showNormal(context, '请填写作废原因');
return;
}
}
final Map<String, dynamic> formData = {};
//
formData['APPLY_STATUS'] = status;
formData['HOTWORK_ID'] = widget.HOTWORK_ID;
formData['DESCR'] = _otherController.text.trim().isEmpty ? _otherController.text.trim() : "";
formData['SIGNTIME'] = signTimes.join(',');
formData['USER_ID'] = SessionService.instance.loginUserId;
formData['STEP_REASON'] = reasonText;
formData['MEASURES'] = json.encode(measuresList);
await showDialog<String>(
context: context,
builder:
(_) =>
CustomAlertDialog(
title: '提示',
content: '请确认' + (status == '1' ? "通过" : "作废") + '本作业票?',
cancelText: '取消',
confirmText: '确定',
onConfirm: () async {
LoadingDialogHelper.show(context);
try {
final result = await ApiService.saveSafeFunctionSure(
'highwork',
formData,
imagePaths,
);
LoadingDialogHelper.hide(context);
if (result['result'] == 'success') {
ToastUtil.showSuccess(
context,
status == '1' ? '提交成功' : '已暂存',
);
Navigator.pop(context);
}
} catch (e) {
LoadingDialogHelper.hide(context);
ToastUtil.showNormal(context, '操作失败:$e');
}
},
),
);
}
void printLongString(String text, {int chunkSize = 800}) {
final pattern = RegExp('.{1,$chunkSize}'); // chunkSize
for (final match in pattern.allMatches(text)) {
print(match.group(0));
}
}
Future<void> _getHotWorkNameList() async {
final result = await ApiService.getHotWorkNameList();
setState(() {
workUserList = result['varList'] ?? '';
});
}
///
Future<void> _getData() async {
final data = await ApiService.getHighHomeworkFindById(widget.HOTWORK_ID);
setState(() {
pd = data['pd'];
_getMeasures();
});
}
Future<void> _getMeasures() async {
final data = await ApiService.listSignSureAllMeasures(widget.HOTWORK_ID);
setState(() {
measuresList = List<Map<String, dynamic>>.from(
data['measuresForSignList'] ?? <Map<String, dynamic>>[],
);
});
}
Future<void> _itemToSign(Map<String, dynamic> measures, int index) async {
//
final List<Map<String, dynamic>> signImgList = measures['SIGN_ITEM'] ?? [];
//
final List<ImageData> imgList = [];
if ((measures['IMG_PATH'] as String?)?.isNotEmpty ?? false) {
for (var path in (measures['IMG_PATH'] as String).split(',')) {
imgList.add(ImageData(localPath:path, serverPath: path));
}
}
//measures['STATUS']
final result = await pushPage(DangerousOptionsPage(index: index,status: int.parse(FormUtils.hasValue(measures, 'STATUS') ? measures['STATUS'] : '1'),
measures: measures['PROTECTIVE_MEASURES'] ?? '',
imgList: imgList,
signImgList: signImgList), context);
if (result != null) {
setState(() {
// local + remote
final returned = result['imgList'] as List<dynamic>;
// ImageData
final imgDataList = returned.map((m) {
return ImageData(
localPath: m['local'] as String,
serverPath: m['remote'] as String,
);
}).toList();
// serverPath
final serverPathString = imgDataList
.map((e) => e.serverPath)
.where((s) => s.isNotEmpty)
.map((s) => s) // String? String
.join(',');
// measures
measures['IMG_PATH'] = serverPathString;
//
measures['SIGN_ITEM'] = List<Map<String,dynamic>>.from(result['signImgList'] as List);
//
measures['STATUS'] = result['status'].toString();
index = result['index'] as int;
});
}
}
///
Widget _setSafeDetailWidget() {
return Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(8),
),
padding: EdgeInsets.symmetric(horizontal: 5),
child: Column(
children: [
if (measuresList.isNotEmpty)
Column(
children: [
SizedBox(height: 5),
ListItemFactory.createBuildSimpleSection('安全防护措施'),
Container(
color: Colors.white,
child: MeasuresListWidget(
measuresList:
measuresList, // List<Map<String, dynamic>>
baseImgPath: ApiService.baseImgPath,
isAllowEdit: true,
onSign: (item) {
_itemToSign(item, measuresList.indexOf(item));
},
),
),
],
),
ItemListWidget.singleLineTitleText(label: '其他安全措施:',
isEditable: true,
hintText: '请输入其他安全措施',
controller
:_otherController),
SizedBox(height: 20),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
SizedBox(),
CustomButton(
text: '新增手写签字',
height: 36,
backgroundColor: Colors.green,
onPressed: () {
_sign();
},
),
],
),
SizedBox(height: 10),
if (imagePaths.isNotEmpty) _signListWidget(),
],
),
);
}
///
Widget _bottomButtons() {
return Row(
spacing: 10,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: CustomButton(
height: 45,
textStyle: TextStyle(fontSize: 16, color: Colors.white),
text: '作废',
backgroundColor: Colors.red,
onPressed: () {
_submit('-1');
},
),
),
Expanded(
child: CustomButton(
textStyle: TextStyle(fontSize: 16, color: Colors.white),
text: '通过',
backgroundColor: Colors.green,
onPressed: () {
_submit('1');
},
),
),
],
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: MyAppbar(title: '安全措施确认人意见'),
body: SafeArea(
child: SingleChildScrollView(
padding: EdgeInsets.all(12),
child: Column(
children: [
HotWorkDetailFormWidget(
pd: pd,
isEditable: false,
onChooseLevel: () {},
onChooseHotworkUser: () {},
onAnalyzeTap: () {
pushPage(
HotworkGasList(HOTWORK_ID: widget.HOTWORK_ID),
context,
);
},
),
SizedBox(height: 20),
_setSafeDetailWidget(),
SizedBox(height: 20),
_bottomButtons(),
],
),
),
),
);
}
}
class MeasureItem {
final double id;
String DEPARTMENT_ID;
String DEPARTMENT_NAME;
String USER_ID;
String USER_NAME;
List<Map<String, dynamic>> userList;
int userIndex;
List<Map<String, dynamic>> selectMeasures;
MeasureItem({
required this.id,
this.DEPARTMENT_ID = '',
this.DEPARTMENT_NAME = '',
this.USER_ID = '',
this.USER_NAME = '',
List<Map<String, dynamic>>? userList,
this.userIndex = -1,
List<Map<String, dynamic>>? selectMeasures,
})
: userList = userList ?? [],
selectMeasures = selectMeasures ?? [];
Map<String, dynamic> toJson() {
return {
'id': id,
'DEPARTMENT_ID': DEPARTMENT_ID,
'DEPARTMENT_NAME': DEPARTMENT_NAME,
'USER_ID': USER_ID,
'USER_NAME': USER_NAME,
'userList': userList,
'userIndex': userIndex,
'selectMeasures': selectMeasures,
};
}
}

View File

@ -0,0 +1,328 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:qhd_prevention/customWidget/ItemWidgetFactory.dart';
import 'package:qhd_prevention/customWidget/custom_button.dart';
import 'package:qhd_prevention/customWidget/toast_util.dart';
import 'package:qhd_prevention/pages/home/tap/item_list_widget.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/SpecialWorkFormBaseWork.dart';
import 'package:qhd_prevention/tools/tools.dart';
import 'package:qhd_prevention/customWidget/custom_alert_dialog.dart';
import 'package:qhd_prevention/customWidget/single_image_viewer.dart';
import 'package:qhd_prevention/http/ApiService.dart';
import 'package:qhd_prevention/pages/mine/mine_sign_page.dart';
import 'package:qhd_prevention/pages/my_appbar.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_Wrok/dh_work/qtfx_work_detail/hotwork_gas_list.dart';
///
class HotworkAqglDetail extends StatefulWidget {
const HotworkAqglDetail({
super.key,
required this.HOTWORK_ID,
required this.flow,
});
final String HOTWORK_ID;
final String flow;
@override
State<HotworkAqglDetail> createState() => _HotworkAqglDetailState();
}
class _HotworkAqglDetailState extends State<HotworkAqglDetail> {
late bool isEditable = false;
///
late Map<String, dynamic> pd = {};
final TextEditingController _contentController = TextEditingController();
///
late List<Map<String, dynamic>> measuresList = [];
late Map<String, dynamic> signs = {};
List<String> signImages = [];
List<String> signTimes = []; //
@override
void initState() {
super.initState();
_getData();
}
///
Future<void> _sign() async {
final path = await Navigator.push(
context,
MaterialPageRoute(builder: (context) => MineSignPage()),
);
if (path != null) {
final now = DateFormat('yyyy-MM-dd HH:mm').format(DateTime.now());
setState(() {
signImages.add(path);
signTimes.add(now);
FocusHelper.clearFocus(context);
});
}
}
Widget _signListWidget() {
return Column(
children:
signImages.map((path) {
return Column(
children: [
const SizedBox(height: 10),
const Divider(),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
GestureDetector(
child: // ConstrainedBox BoxFit.contain
ConstrainedBox(
constraints: const BoxConstraints(
maxWidth: 200,
maxHeight: 150,
),
child: Image.file(
File(path),
//
fit: BoxFit.contain,
),
),
onTap: () {
presentOpaque(
SingleImageViewer(imageUrl: path),
context,
);
},
),
Column(
children: [
Container(
padding: const EdgeInsets.only(right: 5),
child: CustomButton(
text: 'X',
height: 30,
padding: const EdgeInsets.symmetric(horizontal: 10),
backgroundColor: Colors.red,
onPressed: () {
setState(() {
signImages.remove(path);
});
},
),
),
const SizedBox(height: 80),
],
),
],
),
],
);
}).toList(),
);
}
/// -1 1
Future<void> _submit(String status) async {
if (signImages.isEmpty) {
ToastUtil.showNormal(context, '请签字');
return;
}
String reasonText = '';
String DESCR = _contentController.text.trim();
if (DESCR.isEmpty) {
ToastUtil.showNormal(context, '请输入安全管理部门意见');
return;
}
if (status == '1') {
} else {
await showDialog<String>(
context: context,
builder:
(_) => CustomAlertDialog(
title: '作废原因',
mode: DialogMode.input,
hintText: '请输入作废原因',
cancelText: '取消',
confirmText: '确定',
onInputConfirm: (text) {
reasonText = text;
},
),
);
if (reasonText.isEmpty) {
ToastUtil.showNormal(context, '请填写作废原因');
return;
}
}
// measures
final Map<String, dynamic> formData = {};
//
formData['HOTWORK_ID'] = widget.HOTWORK_ID;
formData['SIGNTIME'] = signTimes.join(',');
formData['USER_ID'] = SessionService.instance.loginUserId;
formData['APPLY_STATUS'] = status;
formData['STEP_REASON'] = reasonText;
formData['DESCR'] = DESCR;
await showDialog<String>(
context: context,
builder:
(_) => CustomAlertDialog(
title: '提示',
content: '请确认' + (status == '1' ? "通过" : "作废") + '本作业票?',
cancelText: '取消',
confirmText: '确定',
onConfirm: () async {
LoadingDialogHelper.show(context);
try {
final result = await ApiService.saveSafeFunctionSure(
'highwork',
formData,
signImages,
);
LoadingDialogHelper.hide(context);
if (result['result'] == 'success') {
ToastUtil.showSuccess(context, '保存成功');
Navigator.pop(context);
}
} catch (e) {
LoadingDialogHelper.hide(context);
ToastUtil.showNormal(context, '操作失败:$e');
}
},
),
);
}
///
Future<void> _getData() async {
final data = await ApiService.getHighHomeworkFindById(widget.HOTWORK_ID);
setState(() {
pd = data['pd'];
_getSigns(pd['HOTWORK_ID'] ?? '');
_getMeasures(pd['HOTWORK_ID'] ?? '');
});
}
Future<void> _getMeasures(String homework_id) async {
final data = await ApiService.listSignFinishMeasures('highwork',
homework_id.length > 0 ? homework_id : widget.HOTWORK_ID,
);
setState(() {
measuresList = List<Map<String, dynamic>>.from(
data['finishMeasuresList'] ?? <Map<String, dynamic>>[],
);
});
}
Future<void> _getSigns(String homework_id) async {
final data = await ApiService.listSignFinished(
homework_id.length > 0 ? homework_id : widget.HOTWORK_ID,
);
setState(() {
signs = data['signs'] ?? {};
});
}
///
Widget _bottomButtons() {
return Row(
spacing: 10,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: CustomButton(
height: 45,
textStyle: TextStyle(fontSize: 16, color: Colors.white),
text: '作废',
backgroundColor: Colors.red,
onPressed: () {
_submit('-1');
},
),
),
Expanded(
child: CustomButton(
textStyle: TextStyle(fontSize: 16, color: Colors.white),
text: '通过',
backgroundColor: Colors.green,
onPressed: () {
_submit('1');
},
),
),
],
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: MyAppbar(title: '安全管理部门意见'),
body: SafeArea(
child: SingleChildScrollView(
padding: EdgeInsets.all(12),
child: Column(
spacing: 12,
children: [
// _setSafeDetailWidget(),
SpecialWorkFormBaseWork(
pd: pd,
measuresList: measuresList,
signs: signs,
baseImgPath: ApiService.baseImgPath,
isEditable: false,
onChooseLevel: () {},
onChooseHotworkUser: () {},
onAnalyzeTap: () {
pushPage(
HotworkGasList(HOTWORK_ID: widget.HOTWORK_ID),
context,
);
},
),
ItemListWidget.itemContainer(
Column(
children: [
ListItemFactory.createBuildMultilineInput(
'安全管理部门意见',
'请输入意见',
_contentController,
),
Divider(),
Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
ListItemFactory.headerTitle('安全管理部门负责人'),
CustomButton(
text: '新增手写签字',
height: 36,
backgroundColor: Colors.green,
onPressed: () {
_sign();
},
),
],
),
if (signImages.isNotEmpty) _signListWidget(),
],
)
],
),
),
_bottomButtons(),
],
),
),
),
);
}
}

View File

@ -0,0 +1,363 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:qhd_prevention/customWidget/ItemWidgetFactory.dart';
import 'package:qhd_prevention/customWidget/custom_button.dart';
import 'package:qhd_prevention/customWidget/toast_util.dart';
import 'package:qhd_prevention/pages/home/tap/item_list_widget.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/SpecialWorkFormBaseWork.dart';
import 'package:qhd_prevention/tools/tools.dart';
import 'package:qhd_prevention/customWidget/custom_alert_dialog.dart';
import 'package:qhd_prevention/customWidget/photo_picker_row.dart';
import 'package:qhd_prevention/customWidget/single_image_viewer.dart';
import 'package:qhd_prevention/http/ApiService.dart';
import 'package:qhd_prevention/pages/mine/mine_sign_page.dart';
import 'package:qhd_prevention/pages/my_appbar.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_Wrok/dh_work/qtfx_work_detail/hotwork_gas_list.dart';
/// + 线
class ImageData {
String localPath;
String serverPath;
ImageData({required this.localPath, required this.serverPath});
}
///
class HotworkAqjdDetail extends StatefulWidget {
const HotworkAqjdDetail({
super.key,
required this.HOTWORK_ID,
required this.flow,
});
final String HOTWORK_ID;
final String flow;
@override
State<HotworkAqjdDetail> createState() => _HotworkAqjdDetailState();
}
class _HotworkAqjdDetailState extends State<HotworkAqjdDetail> {
late bool isEditable = false;
///
late Map<String, dynamic> pd = {};
late List<ImageData> imgList = [];
///
late List<Map<String, dynamic>> measuresList = [];
late Map<String, dynamic> signs = {};
List<String> signImages = [];
List<String> signTimes = []; //
@override
void initState() {
super.initState();
_getData();
}
///
Future<void> _onImageAdded(String localPath) async {
//
final res = await ApiService.uploadSaveFile(localPath);
final url = res['FILE_PATH'] as String;
setState(() {
imgList.add(ImageData(localPath: localPath, serverPath: url));
});
}
///
Future<void> _onImageRemoved(ImageData item) async {
if (item.serverPath != null) {
await ApiService.deleteSaveFile(item.serverPath!);
}
setState(() {
imgList.remove(item);
});
}
///
Future<void> _sign() async {
final path = await Navigator.push(
context,
MaterialPageRoute(builder: (context) => MineSignPage()),
);
if (path != null) {
final now = DateFormat('yyyy-MM-dd HH:mm').format(DateTime.now());
setState(() {
signImages.add(path);
signTimes.add(now);
FocusHelper.clearFocus(context);
});
}
}
Widget _signListWidget() {
return Column(
children:
signImages.map((path) {
return Column(
children: [
const SizedBox(height: 10),
const Divider(),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
GestureDetector(
child: // ConstrainedBox BoxFit.contain
ConstrainedBox(
constraints: const BoxConstraints(
maxWidth: 200,
maxHeight: 150,
),
child: Image.file(
File(path),
//
fit: BoxFit.contain,
),
),
onTap: () {
presentOpaque(
SingleImageViewer(imageUrl: path),
context,
);
},
),
Column(
children: [
Container(
padding: const EdgeInsets.only(right: 5),
child: CustomButton(
text: 'X',
height: 30,
padding: const EdgeInsets.symmetric(horizontal: 10),
backgroundColor: Colors.red,
onPressed: () {
setState(() {
signImages.remove(path);
});
},
),
),
const SizedBox(height: 80),
],
),
],
),
],
);
}).toList(),
);
}
/// -1 1
Future<void> _submit(String status) async {
if (signImages.isEmpty) {
ToastUtil.showNormal(context, '请签字');
return;
}
String reasonText = '';
if (status == '1') {
} else {
await showDialog<String>(
context: context,
builder:
(_) => CustomAlertDialog(
title: '作废原因',
mode: DialogMode.input,
hintText: '请输入作废原因',
cancelText: '取消',
confirmText: '确定',
onInputConfirm: (text) {
reasonText = text;
},
),
);
if (reasonText.isEmpty) {
ToastUtil.showNormal(context, '请填写作废原因');
return;
}
}
// serverPath
final serverPathString = imgList
.map((e) => e.serverPath)
.where((s) => s.isNotEmpty)
.map((s) => s) // String? String
.join(',');
// measures
final Map<String, dynamic> formData = {};
//
formData['HOTWORK_ID'] = widget.HOTWORK_ID;
formData['SIGNTIME'] = signTimes.join(',');
formData['USER_ID'] = SessionService.instance.loginUserId;
formData['APPLY_STATUS'] = status;
formData['STEP_REASON'] = reasonText;
formData['IMG_PATH'] = serverPathString;
await showDialog<String>(
context: context,
builder:
(_) => CustomAlertDialog(
title: '提示',
content: '请确认' + (status == '1' ? "通过" : "作废") + '本作业票?',
cancelText: '取消',
confirmText: '确定',
onConfirm: () async {
LoadingDialogHelper.show(context);
try {
final result = await ApiService.saveSafeFunctionSure(
'highwork',
formData,
signImages,
);
LoadingDialogHelper.hide(context);
if (result['result'] == 'success') {
ToastUtil.showSuccess(context, '保存成功');
Navigator.pop(context);
}
} catch (e) {
LoadingDialogHelper.hide(context);
ToastUtil.showNormal(context, '操作失败:$e');
}
},
),
);
}
///
Future<void> _getData() async {
final data = await ApiService.getHighHomeworkFindById(widget.HOTWORK_ID);
setState(() {
pd = data['pd'];
_getSigns(pd['HOTWORK_ID'] ?? '');
_getMeasures(pd['HOTWORK_ID'] ?? '');
});
}
Future<void> _getMeasures(String homework_id) async {
final data = await ApiService.listSignFinishMeasures('highwork',
homework_id.length > 0 ? homework_id : widget.HOTWORK_ID,
);
setState(() {
measuresList = List<Map<String, dynamic>>.from(
data['finishMeasuresList'] ?? <Map<String, dynamic>>[],
);
});
}
Future<void> _getSigns(String homework_id) async {
final data = await ApiService.listSignFinished(
homework_id.length > 0 ? homework_id : widget.HOTWORK_ID,
);
setState(() {
signs = data['signs'] ?? {};
});
}
///
Widget _bottomButtons() {
return Row(
spacing: 10,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: CustomButton(
height: 45,
textStyle: TextStyle(fontSize: 16, color: Colors.white),
text: '作废',
backgroundColor: Colors.red,
onPressed: () {
_submit('-1');
},
),
),
Expanded(
child: CustomButton(
textStyle: TextStyle(fontSize: 16, color: Colors.white),
text: '通过',
backgroundColor: Colors.green,
onPressed: () {
_submit('1');
},
),
),
],
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: MyAppbar(title: '安全交底人签字确认'),
body: SafeArea(
child: SingleChildScrollView(
padding: EdgeInsets.all(12),
child: Column(
spacing: 12,
children: [
// _setSafeDetailWidget(),
SpecialWorkFormBaseWork(
pd: pd,
measuresList: measuresList,
signs: signs,
baseImgPath: ApiService.baseImgPath,
isEditable: false,
onChooseLevel: () {},
onChooseHotworkUser: () {},
onAnalyzeTap: () {
pushPage(
HotworkGasList(HOTWORK_ID: widget.HOTWORK_ID),
context,
);
},
),
ItemListWidget.itemContainer(Column(
children: [RepairedPhotoSection(
title: '上传图片',
maxCount: 2,
mediaType: MediaType.image,
onChanged: (paths) {},
onMediaAdded: _onImageAdded,
onMediaRemoved: (path) {
final item = imgList.firstWhere((e) => e.localPath == path);
_onImageRemoved(item);
},
onAiIdentify: () {},
),
ItemListWidget.itemContainer(
Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
ListItemFactory.headerTitle('安全交底人'),
CustomButton(
text: '新增手写签字',
height: 36,
backgroundColor: Colors.green,
onPressed: () {
_sign();
},
),
],
),
if (signImages.isNotEmpty) _signListWidget(),
],
),
),],
),),
_bottomButtons(),
],
),
),
),
);
}
}

View File

@ -0,0 +1,330 @@
import 'dart:convert';
import 'dart:io';
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:qhd_prevention/customWidget/ItemWidgetFactory.dart';
import 'package:qhd_prevention/customWidget/custom_button.dart';
import 'package:qhd_prevention/customWidget/toast_util.dart';
import 'package:qhd_prevention/pages/home/tap/item_list_widget.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/SpecialWorkFormBaseWork.dart';
import 'package:qhd_prevention/tools/tools.dart';
import 'package:qhd_prevention/customWidget/custom_alert_dialog.dart';
import 'package:qhd_prevention/customWidget/single_image_viewer.dart';
import 'package:qhd_prevention/http/ApiService.dart';
import 'package:qhd_prevention/pages/mine/mine_sign_page.dart';
import 'package:qhd_prevention/pages/my_appbar.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/qtfx_work_detail/hotwork_gas_list.dart';
///
class HotworkDbbzDetail extends StatefulWidget {
const HotworkDbbzDetail({
super.key,
required this.HOTWORK_ID,
required this.flow,
});
final String HOTWORK_ID;
final String flow;
@override
State<HotworkDbbzDetail> createState() => _HotworkDbbzDetailState();
}
class _HotworkDbbzDetailState extends State<HotworkDbbzDetail> {
late bool isEditable = false;
///
late Map<String, dynamic> pd = {};
final TextEditingController _contentController = TextEditingController();
///
late List<Map<String, dynamic>> measuresList = [];
late Map<String, dynamic> signs = {};
List<String> signImages = [];
List<String> signTimes = []; //
@override
void initState() {
super.initState();
_getData();
}
///
Future<void> _sign() async {
final path = await Navigator.push(
context,
MaterialPageRoute(builder: (context) => MineSignPage()),
);
if (path != null) {
final now = DateFormat('yyyy-MM-dd HH:mm').format(DateTime.now());
setState(() {
signImages.add(path);
signTimes.add(now);
FocusHelper.clearFocus(context);
});
}
}
Widget _signListWidget() {
return Column(
children:
signImages.map((path) {
return Column(
children: [
const SizedBox(height: 10),
const Divider(),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
GestureDetector(
child: // ConstrainedBox BoxFit.contain
ConstrainedBox(
constraints: const BoxConstraints(
maxWidth: 200,
maxHeight: 150,
),
child: Image.file(
File(path),
//
fit: BoxFit.contain,
),
),
onTap: () {
presentOpaque(
SingleImageViewer(imageUrl: path),
context,
);
},
),
Column(
children: [
Container(
padding: const EdgeInsets.only(right: 5),
child: CustomButton(
text: 'X',
height: 30,
padding: const EdgeInsets.symmetric(horizontal: 10),
backgroundColor: Colors.red,
onPressed: () {
setState(() {
signImages.remove(path);
});
},
),
),
const SizedBox(height: 80),
],
),
],
),
],
);
}).toList(),
);
}
/// -1 1
Future<void> _submit(String status) async {
if (signImages.isEmpty) {
ToastUtil.showNormal(context, '请签字');
return;
}
String reasonText = '';
String DESCR = _contentController.text.trim();
if (DESCR.isEmpty) {
ToastUtil.showNormal(context, '请输入安全管理部门意见');
return;
}
if (status == '1') {
} else {
await showDialog<String>(
context: context,
builder:
(_) => CustomAlertDialog(
title: '作废原因',
mode: DialogMode.input,
hintText: '请输入作废原因',
cancelText: '取消',
confirmText: '确定',
onInputConfirm: (text) {
reasonText = text;
},
),
);
if (reasonText.isEmpty) {
ToastUtil.showNormal(context, '请填写作废原因');
return;
}
}
// measures
final Map<String, dynamic> formData = {};
//
formData['HOTWORK_ID'] = widget.HOTWORK_ID;
formData['SIGNTIME'] = signTimes.join(',');
formData['USER_ID'] = SessionService.instance.loginUserId;
formData['APPLY_STATUS'] = status;
formData['STEP_REASON'] = reasonText;
formData['DESCR'] = DESCR;
await showDialog<String>(
context: context,
builder:
(_) => CustomAlertDialog(
title: '提示',
content: '请确认' + (status == '1' ? "通过" : "作废") + '本作业票?',
cancelText: '取消',
confirmText: '确定',
onConfirm: () async {
LoadingDialogHelper.show(context);
try {
final result = await ApiService.saveSafeFunctionSure(
'highwork',
formData,
signImages,
);
LoadingDialogHelper.hide(context);
if (result['result'] == 'success') {
ToastUtil.showSuccess(context, '保存成功');
Navigator.pop(context);
}
} catch (e) {
LoadingDialogHelper.hide(context);
ToastUtil.showNormal(context, '操作失败:$e');
}
},
),
);
}
///
Future<void> _getData() async {
final data = await ApiService.getHighHomeworkFindById(widget.HOTWORK_ID);
setState(() {
pd = data['pd'];
_getSigns(pd['HOTWORK_ID'] ?? '');
_getMeasures(pd['HOTWORK_ID'] ?? '');
});
}
Future<void> _getMeasures(String homework_id) async {
final data = await ApiService.listSignFinishMeasures('highwork',
homework_id.length > 0 ? homework_id : widget.HOTWORK_ID,
);
setState(() {
measuresList = List<Map<String, dynamic>>.from(
data['finishMeasuresList'] ?? <Map<String, dynamic>>[],
);
});
}
Future<void> _getSigns(String homework_id) async {
final data = await ApiService.listSignFinished(
homework_id.length > 0 ? homework_id : widget.HOTWORK_ID,
);
setState(() {
signs = data['signs'] ?? {};
});
}
///
Widget _bottomButtons() {
return Row(
spacing: 10,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: CustomButton(
height: 45,
textStyle: TextStyle(fontSize: 16, color: Colors.white),
text: '作废',
backgroundColor: Colors.red,
onPressed: () {
_submit('-1');
},
),
),
Expanded(
child: CustomButton(
textStyle: TextStyle(fontSize: 16, color: Colors.white),
text: '通过',
backgroundColor: Colors.green,
onPressed: () {
_submit('1');
},
),
),
],
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: MyAppbar(title: '班长验票'),
body: SafeArea(
child: SingleChildScrollView(
padding: EdgeInsets.all(12),
child: Column(
spacing: 12,
children: [
// _setSafeDetailWidget(),
SpecialWorkFormBaseWork(
pd: pd,
measuresList: measuresList,
signs: signs,
baseImgPath: ApiService.baseImgPath,
isEditable: false,
onChooseLevel: () {},
onChooseHotworkUser: () {},
onAnalyzeTap: () {
pushPage(
HotworkGasList(HOTWORK_ID: widget.HOTWORK_ID),
context,
);
},
),
ItemListWidget.itemContainer(
Column(
children: [
ListItemFactory.createBuildMultilineInput(
'动火前在岗班长意见',
'请输入意见',
_contentController,
),
Divider(),
Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
ListItemFactory.headerTitle('动火前在岗班长'),
CustomButton(
text: '新增手写签字',
height: 36,
backgroundColor: Colors.green,
onPressed: () {
_sign();
},
),
],
),
if (signImages.isNotEmpty) _signListWidget(),
],
)
],
),
),
_bottomButtons(),
],
),
),
),
);
}
}

View File

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

View File

@ -0,0 +1,682 @@
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:qhd_prevention/customWidget/ItemWidgetFactory.dart';
import 'package:qhd_prevention/customWidget/custom_button.dart';
import 'package:qhd_prevention/customWidget/department_person_picker.dart';
import 'package:qhd_prevention/customWidget/department_picker.dart';
import 'package:qhd_prevention/customWidget/toast_util.dart';
import 'package:qhd_prevention/pages/home/tap/item_list_widget.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/HotWorkDetailFormWidget.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/pages/home/tap/tabList/special_wrok/dh_work/qtfx_work_detail/hotwork_gas_list.dart';
import 'package:qhd_prevention/customWidget/bottom_picker.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_Wrok/MeasuresListWidget.dart';
enum EditUserType {
ANALYZE('分析单位', '分析单位负责人'),
GUARDIAN('监护人单位', '监护人'),
CONFESS('安全交底人单位', '安全交底人'),
ACCEPT_CONFESS('接受交底人单位', '接受交底人'),
CONFIRM('作业负责人单位', '作业负责人'),
LEADER('所在单位', '所在单位负责人'),
AUDIT('安全管理部门', '安全管理部门负责人'),
APPROVE('动火审批单位', '动火审批负责人'),
MONITOR('动火前在岗部门', '动火前在岗班长'),
WORK_START('作业开始负责人单位', '作业开始负责人'),
WORK_END('作业结束负责人单位', '作业结束负责人'),
ACCEPT('验收部门', '验收部门负责人');
///
final String displayName;
final String personName;
const EditUserType(this.displayName, this.personName);
}
class HotworkApplyDetail extends StatefulWidget {
const HotworkApplyDetail({
super.key,
required this.HOTWORK_ID,
required this.flow,
});
final String HOTWORK_ID;
final String flow;
@override
State<HotworkApplyDetail> createState() => _HotworkApplyDetailState();
}
class _HotworkApplyDetailState extends State<HotworkApplyDetail> {
late bool isEditable = false;
final levelList = ["特级", "一级", "二级"];
///
late String msg = 'add';
///
late Map<String, dynamic> pd = {};
late Map<String, dynamic> signs = {};
late List<Map<String, dynamic>> measuresList = [];
final TextEditingController _contentController = TextEditingController();
final TextEditingController _locationController = TextEditingController();
final TextEditingController _methodController = TextEditingController();
final TextEditingController _hotworkPersonController =
TextEditingController();
final TextEditingController _relatedController = TextEditingController();
final TextEditingController _riskController = TextEditingController();
///
late List<dynamic> workUserList = [];
//
final Map<EditUserType, List<Map<String, dynamic>>> _personCache = {};
@override
void initState() {
super.initState();
if (widget.HOTWORK_ID.length > 0) {
msg = 'edit';
_getData();
} else {
isEditable = true;
pd['ANALYZE_TIME'] = 1;
pd['APPLY_DEPARTMENT_ID'] = SessionService.instance.deptId;
pd['APPLY_DEPARTMENT_NAME'] =
SessionService.instance.loginUser!['DEPARTMENT_NAME'] ?? '';
pd['APPLY_USER_ID'] = SessionService.instance.loginUserId;
pd['APPLY_USER_NAME'] = SessionService.instance.username;
}
_getHotWorkNameList();
_contentController.addListener(() {
setState(() {
pd['WORK_CONTENT'] = _contentController.text.trim();
});
});
_locationController.addListener(() {
pd['WORK_PLACE'] = _locationController.text.trim();
});
_methodController.addListener(() {
pd['WORK_FUNCTION'] = _methodController.text.trim();
});
_hotworkPersonController.addListener(() {
pd['WORK_USER'] = _hotworkPersonController.text.trim();
});
_relatedController.addListener(() {
pd['SPECIAL_WORK'] = _relatedController.text.trim();
});
_riskController.addListener(() {
pd['RISK_IDENTIFICATION'] = _riskController.text.trim();
});
}
void set_pd_DEPARTMENT_ID(EditUserType type, String id) {
pd['${type.name}_DEPARTMENT_ID'] = id;
}
void set_pd_DEPARTMENT_NAME(EditUserType type, String name) {
pd['${type.name}_DEPARTMENT_NAME'] = name;
}
void set_pd_USER_ID(EditUserType type, String id) {
pd['${type.name}_USER_ID'] = id;
}
void set_pd_USER_Name(EditUserType type, String name) {
pd['${type.name}_USER_NAME'] = name;
}
String get_pd_DEPARTMENT_ID(EditUserType type) {
return pd['${type.name}_DEPARTMENT_ID'] ?? '';
}
String get_pd_DEPARTMENT_NAME(EditUserType type) {
return pd['${type.name}_DEPARTMENT_NAME'] ?? '';
}
String get_pd_USER_ID(EditUserType type) {
return pd['${type.name}_USER_ID'] ?? '';
}
String get_pd_USER_Name(EditUserType type) {
return pd['${type.name}_USER_NAME'] ?? '';
}
Future<void> _chooseLevel() async {
final choice = await BottomPicker.show<String>(
context,
items: levelList,
itemBuilder: (item) => Text(item, textAlign: TextAlign.center),
initialIndex: 0,
);
if (choice != null) {
// choice
setState(() {
pd['WORK_LEVEL'] = choice;
FocusHelper.clearFocus(context);
});
}
}
Future<void> _chooseHorkUser() async {
final choice = await BottomPicker.show<String>(
context,
items: workUserList.map((item) => item['NAME'] as String).toList(),
itemBuilder: (item) => Text(item, textAlign: TextAlign.center),
initialIndex: 0,
);
if (choice != null) {
setState(() {
pd['WORK_USER'] = choice;
_hotworkPersonController.text = choice;
Map<String, dynamic> result = workUserList.firstWhere(
(item) => item['NAME'] == choice,
orElse: () => {}, //
);
if (FormUtils.hasValue(result, 'USER_ID')) {
pd['WORK_USER_ID'] = result['USER_ID'];
}
FocusHelper.clearFocus(context);
});
}
}
Widget _card(Widget child) {
return Container(
padding: EdgeInsets.symmetric(vertical: 5),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(5),
),
child: child,
);
}
Widget _chooseItem(EditUserType type) {
bool isClean = false;
if (isEditable) {
if (type == EditUserType.AUDIT && (pd['WORK_LEVEL'] ?? '') == '二级') {
isClean = true;
}
if (type == EditUserType.APPROVE &&
((pd['WORK_LEVEL'] ?? '') == '二级' ||
(pd['WORK_LEVEL'] ?? '') == '一级')) {
isClean = true;
}
}
return Column(
children: [
ItemListWidget.selectableLineTitleTextField(
label: type.displayName,
isEditable: isEditable,
isClean: isClean,
onTapClean: () {
setState(() {
pd['${type.name}_DEPARTMENT_NAME'] = '';
pd['${type.name}_USER_NAME'] = '';
_personCache.remove(type);
});
},
text: pd['${type.name}_DEPARTMENT_NAME'] ?? '请选择',
onTap: () => chooseUnitHandle(type),
),
Divider(),
ItemListWidget.selectableLineTitleTextField(
label: type.personName,
isEditable: isEditable,
text: pd['${type.name}_USER_NAME'] ?? '请选择',
onTap: () => choosePersonHandle(type),
),
],
);
}
///
void chooseUnitHandle(EditUserType type) {
FocusHelper.clearFocus(context);
showModalBottomSheet(
context: context,
isScrollControlled: true,
barrierColor: Colors.black54,
backgroundColor: Colors.transparent,
builder:
(_) => DepartmentPicker(
onSelected: (id, name) async {
setState(() {
set_pd_DEPARTMENT_ID(type, id);
set_pd_DEPARTMENT_NAME(type, name);
set_pd_USER_ID(type, '');
set_pd_USER_Name(type, '');
});
_getPersonListForUnitId(id, type);
},
),
).then((_) {
FocusHelper.clearFocus(context);
});
}
Future<void> _getPersonListForUnitId(String id, EditUserType type) async {
//
final result = await ApiService.getListTreePersonList(id);
setState(() {
_personCache[type] = List<Map<String, dynamic>>.from(
result['userList'] as List,
);
});
}
///
void choosePersonHandle(EditUserType type) async {
FocusHelper.clearFocus(context);
String unitId = get_pd_DEPARTMENT_ID(type);
final personList = _personCache[type] ?? [];
if (!unitId.isNotEmpty) {
final unitName = type.displayName;
ToastUtil.showNormal(context, '请先选择$unitName');
return;
}
if (personList.isEmpty) { //
await _getPersonListForUnitId(unitId, type);
final list = _personCache[type] ?? [];
if (list.isEmpty) { //
ToastUtil.showNormal(context, '暂无数据,请选择其他单位');
}else{
choosePersonHandle(type);
}
return;
}
if (personList.isEmpty) {
//
ToastUtil.showNormal(context, '请先选择' + type.displayName);
return;
}
DepartmentPersonPicker.show(
context,
personsData: personList,
onSelected: (userId, name) {
setState(() {
set_pd_USER_ID(type, userId);
set_pd_USER_Name(type, name);
});
},
).then((_) {
FocusHelper.clearFocus(context);
});
}
/// 1 0
Future<void> _submit(String status) async {
//
final textRules = <Map<String, dynamic>>[
{'value': _contentController.text.trim(), 'message': '请填写作业内容'},
{'value': _locationController.text.trim(), 'message': '请填写动火地点及部位'},
{'value': _methodController.text.trim(), 'message': '请填写动火方式'},
{'value': _hotworkPersonController.text.trim(), 'message': '请填写动火人及证书编号'},
{
'value': _relatedController.text.trim(),
'message': '请输入关联的其他特殊作业及安全作业票编号',
},
{'value': _riskController.text.trim(), 'message': '请填写风险辨识结果'},
];
final level = pd['WORK_LEVEL'] ?? '';
print('---level-$level');
///
final unitRules = <EditUserType>[
EditUserType.ANALYZE,
EditUserType.GUARDIAN,
EditUserType.CONFESS,
EditUserType.ACCEPT_CONFESS,
EditUserType.CONFIRM,
EditUserType.LEADER,
EditUserType.AUDIT,
EditUserType.APPROVE,
EditUserType.MONITOR,
EditUserType.WORK_START,
EditUserType.WORK_END,
EditUserType.ACCEPT,
];
if (status == '1') {
//
for (var rule in textRules) {
if ((rule['value'] as String).isEmpty) {
ToastUtil.showNormal(context, rule['message']);
return;
}
}
//
if (level.length == 0) {
ToastUtil.showNormal(context, '请选择动火级别');
return;
}
for (var type in unitRules) {
if (get_pd_DEPARTMENT_ID(type).length == 0) {
ToastUtil.showNormal(context, '请选择${type.displayName}');
return;
}
if (get_pd_USER_ID(type).length == 0) {
ToastUtil.showNormal(context, '请选择${type.displayName}负责人');
return;
}
}
}
// LoadingDialogHelper.show(context);
String taskId = '0';
if (level == '特级') {
taskId = '1';
} else if (level == '一级') {
taskId = '2';
} else if (level == '二级') {
taskId = '3';
}
//
if (msg == 'add') {
pd['CORPINFO_ID'] = SessionService.instance.corpinfoId;
pd['CREATOR'] = SessionService.instance.loginUserId;
pd['OPERATOR'] = SessionService.instance.loginUserId;
pd['ACTION_USER'] = SessionService.instance.username;
pd['APPLY_STATUS'] = status;
pd['STEP_ID'] = status;
pd['TASK_ID'] = taskId;
pd['HOTWORK_ID'] = widget.HOTWORK_ID;
pd['APPLY_DEPARTMENT_ID'] = SessionService.instance.deptId;
pd['APPLY_DEPARTMENT_NAME'] =
SessionService.instance.loginUser?['DEPARTMENT_NAME'] ?? '';
pd['APPLY_USER_ID'] = SessionService.instance.loginUserId;
pd['APPLY_USER_NAME'] = SessionService.instance.username;
pd['USER_ID'] = SessionService.instance.loginUserId;
}
LoadingDialogHelper.show(context);
String jsonStr = jsonEncode(pd);
printLongString(jsonStr);
try {
String url = "/app/hotwork/" + msg;
final result = await ApiService.submitHomework(url, pd);
LoadingDialogHelper.hide(context);
if (result['result'] == 'success') {
ToastUtil.showSuccess(context, status == '1' ? '提交成功' : '已暂存');
Navigator.pop(context);
}
} catch (e) {
LoadingDialogHelper.hide(context);
ToastUtil.showNormal(context, '操作失败:$e');
}
}
void printLongString(String text, {int chunkSize = 800}) {
final pattern = RegExp('.{1,$chunkSize}'); // chunkSize
for (final match in pattern.allMatches(text)) {
print(match.group(0));
}
}
Future<void> _getHotWorkNameList() async {
final result = await ApiService.getHotWorkNameList();
setState(() {
workUserList = result['varList'] ?? '';
List<String> names =
workUserList.map((item) => item['NAME'] as String).toList();
});
}
///
Future<void> _getData() async {
final data = await ApiService.getHighHomeworkFindById(widget.HOTWORK_ID);
setState(() {
pd = data['pd'];
if (pd['STEP_ID'] == 0) {
isEditable = true;
} else {
_getSigns(pd['HOTWORK_ID'] ?? '');
_getMeasures(pd['HOTWORK_ID'] ?? '');
}
//
_contentController.text = pd['WORK_CONTENT'] ?? '';
_locationController.text = pd['WORK_PLACE'] ?? '';
_methodController.text = pd['WORK_FUNCTION'] ?? '';
_hotworkPersonController.text = pd['WORK_USER'] ?? '';
_relatedController.text = pd['SPECIAL_WORK'] ?? '';
_riskController.text = pd['RISK_IDENTIFICATION'] ?? '';
});
// final data = await ApiService.getHighHomeworkFindById(widget.HOTWORK_ID);
// setState(() {
// pd = data['pd'];
// });
// LoadingDialogHelper.hide(context);
}
Future<void> _getSigns(String homework_id) async {
final data = await ApiService.listSignFinished(
homework_id.length > 0 ? homework_id : widget.HOTWORK_ID,
);
setState(() {
signs = data['signs'] ?? {};
});
}
Future<void> _getMeasures(String homework_id) async {
final data = await ApiService.listSignFinishMeasures('highwork',
homework_id.length > 0 ? homework_id : widget.HOTWORK_ID,
);
setState(() {
measuresList = List<Map<String, dynamic>>.from(
data['finishMeasuresList'] ?? <Map<String, dynamic>>[],
);
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: h_backGroundColor(),
appBar: MyAppbar(title: '动火安全作业申请'),
body: SafeArea(
child: SingleChildScrollView(
padding: EdgeInsets.all(12),
child: Column(
children: [
_card(
HotWorkDetailFormWidget(
pd: pd,
isEditable: isEditable,
contentController: _contentController,
locationController: _locationController,
methodController: _methodController,
hotworkPersonController: _hotworkPersonController,
relatedController: _relatedController,
riskController: _riskController,
onChooseLevel: _chooseLevel,
onChooseHotworkUser: _chooseHorkUser,
onAnalyzeTap: () {
pushPage(
HotworkGasList(HOTWORK_ID: widget.HOTWORK_ID),
context,
);
},
),
),
if (isEditable)
Column(
children: [
SizedBox(height: 15),
_card(_chooseItem(EditUserType.ANALYZE)),
SizedBox(height: 15),
_card(_chooseItem(EditUserType.GUARDIAN)),
SizedBox(height: 15),
_card(_chooseItem(EditUserType.CONFESS)),
SizedBox(height: 15),
_card(_chooseItem(EditUserType.ACCEPT_CONFESS)),
SizedBox(height: 15),
_card(_chooseItem(EditUserType.CONFIRM)),
SizedBox(height: 15),
_card(_chooseItem(EditUserType.LEADER)),
SizedBox(height: 15),
_card(_chooseItem(EditUserType.AUDIT)),
SizedBox(height: 15),
_card(_chooseItem(EditUserType.APPROVE)),
SizedBox(height: 15),
_card(_chooseItem(EditUserType.MONITOR)),
SizedBox(height: 15),
_card(
Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
_chooseItem(EditUserType.WORK_START),
Divider(),
Row(
children: [
SizedBox(width: 12),
Text(
'友情提示:负责填写作业实际开始时间',
style: TextStyle(color: Colors.red),
),
],
),
SizedBox(height: 5),
],
),
),
SizedBox(height: 15),
_card(
Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
_chooseItem(EditUserType.WORK_END),
Divider(),
Row(
children: [
SizedBox(width: 12),
Text(
'友情提示:负责填写作业实际结束时间',
style: TextStyle(color: Colors.red),
),
],
),
SizedBox(height: 5),
],
),
),
SizedBox(height: 15),
_card(_chooseItem(EditUserType.ACCEPT)),
SizedBox(height: 15),
],
),
if (measuresList.length > 0)
Column(
children: [
SizedBox(height: 20),
ListItemFactory.createBuildSimpleSection('安全防护措施'),
Container(
color: Colors.white,
child: MeasuresListWidget(
measuresList:
measuresList, // List<Map<String, dynamic>>
baseImgPath: ApiService.baseImgPath,
isAllowEdit: false,
),
),
],
),
if (FormUtils.hasValue(signs, 'MEASURES_CONFIRM'))
Column(
children: [
SizedBox(height: 20),
ListItemFactory.createBuildSimpleSection('其他安全防护措施'),
Container(
color: Colors.white,
child: OtherMeasuresWidget(
otherMeasures: signs['MEASURES_CONFIRM'],
baseImgPath: ApiService.baseImgPath,
),
),
],
),
SignaturesListWidget(
signs: signs,
pd: pd,
baseImgPath: ApiService.baseImgPath,
),
isEditable
? Row(
spacing: 10,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: CustomButton(
height: 45,
textStyle: TextStyle(
fontSize: 16,
color: Colors.white,
),
text: '提交',
backgroundColor: Colors.blue,
onPressed: () {
_submit('1');
},
),
),
Expanded(
child: CustomButton(
textStyle: TextStyle(
fontSize: 16,
color: Colors.white,
),
text: '暂存',
backgroundColor: Colors.green,
onPressed: () {
_submit('0');
},
),
),
],
)
: Column(
children: [
SizedBox(height: 20),
Row(
children: [
SizedBox(width: 50),
Expanded(
child: CustomButton(
height: 45,
textStyle: TextStyle(
fontSize: 16,
color: Colors.white,
),
text: '返回',
backgroundColor: Colors.green,
onPressed: () {
Navigator.pop(context);
},
),
),
SizedBox(width: 50),
],
),
],
),
],
),
),
),
);
}
}

View File

@ -0,0 +1,327 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:qhd_prevention/customWidget/ItemWidgetFactory.dart';
import 'package:qhd_prevention/customWidget/custom_button.dart';
import 'package:qhd_prevention/customWidget/toast_util.dart';
import 'package:qhd_prevention/pages/home/tap/item_list_widget.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/pages/home/tap/tabList/special_wrok/dh_work/qtfx_work_detail/hotwork_gas_list.dart';
import 'package:qhd_prevention/customWidget/custom_alert_dialog.dart';
import 'package:qhd_prevention/customWidget/single_image_viewer.dart';
import 'package:qhd_prevention/pages/mine/mine_sign_page.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/SpecialWorkFormBaseWork.dart';
///
class HotworkDhspDetail extends StatefulWidget {
const HotworkDhspDetail({
super.key,
required this.HOTWORK_ID,
required this.flow,
});
final String HOTWORK_ID;
final String flow;
@override
State<HotworkDhspDetail> createState() => _HotworkDhspDetailState();
}
class _HotworkDhspDetailState extends State<HotworkDhspDetail> {
late bool isEditable = false;
///
late Map<String, dynamic> pd = {};
final TextEditingController _contentController = TextEditingController();
///
late List<Map<String, dynamic>> measuresList = [];
late Map<String, dynamic> signs = {};
List<String> signImages = [];
List<String> signTimes = []; //
@override
void initState() {
super.initState();
_getData();
}
///
Future<void> _sign() async {
final path = await Navigator.push(
context,
MaterialPageRoute(builder: (context) => MineSignPage()),
);
if (path != null) {
final now = DateFormat('yyyy-MM-dd HH:mm').format(DateTime.now());
setState(() {
signImages.add(path);
signTimes.add(now);
FocusHelper.clearFocus(context);
});
}
}
Widget _signListWidget() {
return Column(
children:
signImages.map((path) {
return Column(
children: [
const SizedBox(height: 10),
const Divider(),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
GestureDetector(
child: // ConstrainedBox BoxFit.contain
ConstrainedBox(
constraints: const BoxConstraints(
maxWidth: 200,
maxHeight: 150,
),
child: Image.file(
File(path),
//
fit: BoxFit.contain,
),
),
onTap: () {
presentOpaque(
SingleImageViewer(imageUrl: path),
context,
);
},
),
Column(
children: [
Container(
padding: const EdgeInsets.only(right: 5),
child: CustomButton(
text: 'X',
height: 30,
padding: const EdgeInsets.symmetric(horizontal: 10),
backgroundColor: Colors.red,
onPressed: () {
setState(() {
signImages.remove(path);
});
},
),
),
const SizedBox(height: 80),
],
),
],
),
],
);
}).toList(),
);
}
/// -1 1
Future<void> _submit(String status) async {
if (signImages.isEmpty) {
ToastUtil.showNormal(context, '请签字');
return;
}
String reasonText = '';
String DESCR = _contentController.text.trim();
if (DESCR.isEmpty) {
ToastUtil.showNormal(context, '请输入安全管理部门意见');
return;
}
if (status == '1') {
} else {
await showDialog<String>(
context: context,
builder:
(_) => CustomAlertDialog(
title: '作废原因',
mode: DialogMode.input,
hintText: '请输入作废原因',
cancelText: '取消',
confirmText: '确定',
onInputConfirm: (text) {
reasonText = text;
},
),
);
if (reasonText.isEmpty) {
ToastUtil.showNormal(context, '请填写作废原因');
return;
}
}
// measures
final Map<String, dynamic> formData = {};
//
formData['HOTWORK_ID'] = widget.HOTWORK_ID;
formData['SIGNTIME'] = signTimes.join(',');
formData['USER_ID'] = SessionService.instance.loginUserId;
formData['APPLY_STATUS'] = status;
formData['STEP_REASON'] = reasonText;
formData['DESCR'] = DESCR;
await showDialog<String>(
context: context,
builder:
(_) => CustomAlertDialog(
title: '提示',
content: '请确认' + (status == '1' ? "通过" : "作废") + '本作业票?',
cancelText: '取消',
confirmText: '确定',
onConfirm: () async {
LoadingDialogHelper.show(context);
try {
final result = await ApiService.saveSafeFunctionSure(
'highwork',
formData,
signImages,
);
LoadingDialogHelper.hide(context);
if (result['result'] == 'success') {
ToastUtil.showSuccess(context, '保存成功');
Navigator.pop(context);
}
} catch (e) {
LoadingDialogHelper.hide(context);
ToastUtil.showNormal(context, '操作失败:$e');
}
},
),
);
}
///
Future<void> _getData() async {
final data = await ApiService.getHighHomeworkFindById(widget.HOTWORK_ID);
setState(() {
pd = data['pd'];
_getSigns(pd['HOTWORK_ID'] ?? '');
_getMeasures(pd['HOTWORK_ID'] ?? '');
});
}
Future<void> _getMeasures(String homework_id) async {
final data = await ApiService.listSignFinishMeasures('highwork',
homework_id.length > 0 ? homework_id : widget.HOTWORK_ID,
);
setState(() {
measuresList = List<Map<String, dynamic>>.from(
data['finishMeasuresList'] ?? <Map<String, dynamic>>[],
);
});
}
Future<void> _getSigns(String homework_id) async {
final data = await ApiService.listSignFinished(
homework_id.length > 0 ? homework_id : widget.HOTWORK_ID,
);
setState(() {
signs = data['signs'] ?? {};
});
}
///
Widget _bottomButtons() {
return Row(
spacing: 10,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: CustomButton(
height: 45,
textStyle: TextStyle(fontSize: 16, color: Colors.white),
text: '作废',
backgroundColor: Colors.red,
onPressed: () {
_submit('-1');
},
),
),
Expanded(
child: CustomButton(
textStyle: TextStyle(fontSize: 16, color: Colors.white),
text: '通过',
backgroundColor: Colors.green,
onPressed: () {
_submit('1');
},
),
),
],
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: MyAppbar(title: '审批部门意见'),
body: SafeArea(
child: SingleChildScrollView(
padding: EdgeInsets.all(12),
child: Column(
spacing: 12,
children: [
// _setSafeDetailWidget(),
SpecialWorkFormBaseWork(
pd: pd,
measuresList: measuresList,
signs: signs,
baseImgPath: ApiService.baseImgPath,
isEditable: false,
onChooseLevel: () {},
onChooseHotworkUser: () {},
onAnalyzeTap: () {
pushPage(
HotworkGasList(HOTWORK_ID: widget.HOTWORK_ID),
context,
);
},
),
ItemListWidget.itemContainer(
Column(
children: [
ListItemFactory.createBuildMultilineInput(
'动火审批部门意见',
'请输入意见',
_contentController,
),
Divider(),
Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
ListItemFactory.headerTitle('动火审批人'),
CustomButton(
text: '新增手写签字',
height: 36,
backgroundColor: Colors.green,
onPressed: () {
_sign();
},
),
],
),
if (signImages.isNotEmpty) _signListWidget(),
],
)
],
),
),
_bottomButtons(),
],
),
),
),
);
}
}

View File

@ -0,0 +1,645 @@
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:qhd_prevention/customWidget/ItemWidgetFactory.dart';
import 'package:qhd_prevention/customWidget/custom_button.dart';
import 'package:qhd_prevention/customWidget/department_person_picker.dart';
import 'package:qhd_prevention/customWidget/department_picker.dart';
import 'package:qhd_prevention/customWidget/toast_util.dart';
import 'package:qhd_prevention/pages/home/tap/item_list_widget.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/gc_work/HighWorkDetailFormWidget.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';
import 'package:qhd_prevention/pages/home/tap/tabList/special_Wrok/MeasuresListWidget.dart';
enum EditUserType {
GUARDIAN('监护人单位', '监护人', true),
CONFESS('安全交底人单位', '安全交底人', true),
ACCEPT_CONFESS('接受交底人单位', '接受交底人', true),
WORK_USER('作业人单位', '作业人', true),
CONFIRM('作业负责人单位', '作业负责人', true),
LEADER('所在单位', '所在单位负责人', true),
AUDIT('审核部门', '审核部门负责人', false),
APPROVE('审批部门', '审批部门负责人', false),
WORK_START('作业开始负责人单位', '作业开始负责人', true),
WORK_END('作业结束负责人单位', '作业结束负责人', true),
ACCEPT('验收部门', '验收部门负责人', true);
///
final String displayName;
final String personName;
final bool isRequired;
const EditUserType(this.displayName, this.personName, this.isRequired);
}
class HighworkApplyDetail extends StatefulWidget {
const HighworkApplyDetail({
super.key,
required this.HIGHWORK_ID,
required this.flow,
});
final String HIGHWORK_ID;
final String flow;
@override
State<HighworkApplyDetail> createState() => _HighworkApplyDetailState();
}
class _HighworkApplyDetailState extends State<HighworkApplyDetail> {
late bool isEditable = false;
final levelList = ["I级高处作业", "II级高处作业", "III级高处作业","IV级高处作业"];
///
late String msg = 'add';
///
late Map<String, dynamic> pd = {};
late Map<String, dynamic> signs = {};
late List<Map<String, dynamic>> measuresList = [];
final TextEditingController _locationController = TextEditingController();
final TextEditingController _hightController = TextEditingController();
final TextEditingController _contentController = TextEditingController();
final TextEditingController _relatedController = TextEditingController();
final TextEditingController _riskController = TextEditingController();
///
late List<dynamic> workUserList = [];
//
final Map<EditUserType, List<Map<String, dynamic>>> _personCache = {};
@override
void initState() {
super.initState();
if (widget.HIGHWORK_ID.length > 0) {
msg = 'edit';
_getData();
} else {
isEditable = true;
pd['APPLY_DEPARTMENT_ID'] = SessionService.instance.deptId;
pd['APPLY_DEPARTMENT_NAME'] =
SessionService.instance.loginUser!['DEPARTMENT_NAME'] ?? '';
pd['APPLY_USER_ID'] = SessionService.instance.loginUserId;
pd['APPLY_USER_NAME'] = SessionService.instance.username;
}
_getHotWorkNameList();
_contentController.addListener(() {
setState(() {
pd['WORK_CONTENT'] = _contentController.text.trim();
});
});
_locationController.addListener(() {
pd['WORK_PLACE'] = _locationController.text.trim();
});
_hightController.addListener(() {
pd['WORK_HIGH'] = _hightController.text.trim();
});
_relatedController.addListener(() {
pd['SPECIAL_WORK'] = _relatedController.text.trim();
});
_riskController.addListener(() {
pd['RISK_IDENTIFICATION'] = _riskController.text.trim();
});
}
void set_pd_DEPARTMENT_ID(EditUserType type, String id) {
pd['${type.name}_DEPARTMENT_ID'] = id;
}
void set_pd_DEPARTMENT_NAME(EditUserType type, String name) {
pd['${type.name}_DEPARTMENT_NAME'] = name;
}
void set_pd_USER_ID(EditUserType type, String id) {
pd['${type.name}_USER_ID'] = id;
}
void set_pd_USER_Name(EditUserType type, String name) {
pd['${type.name}_USER_NAME'] = name;
}
String get_pd_DEPARTMENT_ID(EditUserType type) {
return pd['${type.name}_DEPARTMENT_ID'] ?? '';
}
String get_pd_DEPARTMENT_NAME(EditUserType type) {
return pd['${type.name}_DEPARTMENT_NAME'] ?? '';
}
String get_pd_USER_ID(EditUserType type) {
return pd['${type.name}_USER_ID'] ?? '';
}
String get_pd_USER_Name(EditUserType type) {
return pd['${type.name}_USER_NAME'] ?? '';
}
Future<void> _chooseLevel() async {
final choice = await BottomPicker.show<String>(
context,
items: levelList,
itemBuilder: (item) => Text(item, textAlign: TextAlign.center),
initialIndex: 0,
);
if (choice != null) {
// choice
setState(() {
pd['WORK_LEVEL_NAME'] = choice;
pd['WORK_LEVEL'] = (levelList.indexOf(choice) + 1).toString();
FocusHelper.clearFocus(context);
});
}
}
Widget _card(Widget child) {
return Container(
padding: EdgeInsets.symmetric(vertical: 5),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(5),
),
child: child,
);
}
Widget _chooseItem(EditUserType type) {
bool isClean = false;
if (isEditable) {
if (type == EditUserType.AUDIT && (pd['WORK_LEVEL'] ?? '') == '二级') {
isClean = true;
}
if (type == EditUserType.APPROVE &&
((pd['WORK_LEVEL'] ?? '') == '二级' ||
(pd['WORK_LEVEL'] ?? '') == '一级')) {
isClean = true;
}
}
return Column(
children: [
ItemListWidget.selectableLineTitleTextField(
isRequired: type.isRequired,
label: type.displayName,
isEditable: isEditable,
isClean: isClean,
onTapClean: () {
setState(() {
pd['${type.name}_DEPARTMENT_NAME'] = '';
pd['${type.name}_USER_NAME'] = '';
_personCache.remove(type);
});
},
text: pd['${type.name}_DEPARTMENT_NAME'] ?? '请选择',
onTap: () => chooseUnitHandle(type),
),
Divider(),
ItemListWidget.selectableLineTitleTextField(
isRequired: type.isRequired,
label: type.personName,
isEditable: isEditable,
text: pd['${type.name}_USER_NAME'] ?? '请选择',
onTap: () => choosePersonHandle(type),
),
],
);
}
///
void chooseUnitHandle(EditUserType type) {
FocusHelper.clearFocus(context);
showModalBottomSheet(
context: context,
isScrollControlled: true,
barrierColor: Colors.black54,
backgroundColor: Colors.transparent,
builder:
(_) => DepartmentPicker(
onSelected: (id, name) async {
setState(() {
set_pd_DEPARTMENT_ID(type, id);
set_pd_DEPARTMENT_NAME(type, name);
set_pd_USER_ID(type, '');
set_pd_USER_Name(type, '');
});
_getPersonListForUnitId(id, type);
},
),
).then((_) {
FocusHelper.clearFocus(context);
});
}
Future<void> _getPersonListForUnitId(String id, EditUserType type) async {
//
final result = await ApiService.getListTreePersonList(id);
setState(() {
_personCache[type] = List<Map<String, dynamic>>.from(
result['userList'] as List,
);
});
}
///
void choosePersonHandle(EditUserType type) async {
FocusHelper.clearFocus(context);
String unitId = get_pd_DEPARTMENT_ID(type);
final personList = _personCache[type] ?? [];
if (!unitId.isNotEmpty) {
final unitName = type.displayName;
ToastUtil.showNormal(context, '请先选择$unitName');
return;
}
if (personList.isEmpty) { //
await _getPersonListForUnitId(unitId, type);
final list = _personCache[type] ?? [];
if (list.isEmpty) { //
ToastUtil.showNormal(context, '暂无数据,请选择其他单位');
}else{
choosePersonHandle(type);
}
return;
}
if (personList.isEmpty) {
//
ToastUtil.showNormal(context, '请先选择' + type.displayName);
return;
}
DepartmentPersonPicker.show(
context,
personsData: personList,
onSelected: (userId, name) {
setState(() {
set_pd_USER_ID(type, userId);
set_pd_USER_Name(type, name);
});
},
).then((_) {
FocusHelper.clearFocus(context);
});
}
/// 1 0
Future<void> _submit(String status) async {
//
final textRules = <Map<String, dynamic>>[
{'value': _locationController.text.trim(), 'message': '请填写地点及部位'},
{'value': _hightController.text.trim(), 'message': '请填写高度'},
{'value': _contentController.text.trim(), 'message': '请填写作业内容'},
{
'value': _relatedController.text.trim(),
'message': '请输入关联的其他特殊作业及安全作业票编号',
},
{'value': _riskController.text.trim(), 'message': '请填写风险辨识结果'},
];
final level = pd['WORK_LEVEL'] ?? '';
print('---level-$level');
///
final unitRules = <EditUserType>[
EditUserType.GUARDIAN,
EditUserType.CONFESS,
EditUserType.ACCEPT_CONFESS,
EditUserType.CONFIRM,
EditUserType.LEADER,
// EditUserType.AUDIT,
// EditUserType.APPROVE,
EditUserType.WORK_USER,
EditUserType.WORK_START,
EditUserType.WORK_END,
EditUserType.ACCEPT,
];
if (status == '1') {
//
for (var rule in textRules) {
if ((rule['value'] as String).isEmpty) {
ToastUtil.showNormal(context, rule['message']);
return;
}
}
//
if (level.length == 0) {
ToastUtil.showNormal(context, '请输入高处作业级别');
return;
}
for (var type in unitRules) {
if (get_pd_DEPARTMENT_ID(type).length == 0) {
ToastUtil.showNormal(context, '请选择${type.displayName}');
return;
}
if (get_pd_USER_ID(type).length == 0) {
ToastUtil.showNormal(context, '请选择${type.displayName}负责人');
return;
}
}
}
// LoadingDialogHelper.show(context);
String taskId = '0';
if (pd['WORK_LEVEL'] == '1') {
taskId = '5';
} else if (pd['WORK_LEVEL'] == '2' || pd['WORK_LEVEL'] == '3') {
taskId = '6';
} else if (pd['WORK_LEVEL'] == '4') {
taskId = '7';
}
//
if (msg == 'add') {
pd['CORPINFO_ID'] = SessionService.instance.corpinfoId;
pd['CREATOR'] = SessionService.instance.loginUserId;
pd['OPERATOR'] = SessionService.instance.loginUserId;
pd['ACTION_USER'] = SessionService.instance.username;
pd['APPLY_STATUS'] = status;
pd['STEP_ID'] = status;
pd['TASK_ID'] = taskId;
pd['HIGHWORK_ID'] = widget.HIGHWORK_ID;
pd['APPLY_DEPARTMENT_ID'] = SessionService.instance.deptId;
pd['APPLY_DEPARTMENT_NAME'] =
SessionService.instance.loginUser?['DEPARTMENT_NAME'] ?? '';
pd['APPLY_USER_ID'] = SessionService.instance.loginUserId;
pd['APPLY_USER_NAME'] = SessionService.instance.username;
pd['USER_ID'] = SessionService.instance.loginUserId;
}
LoadingDialogHelper.show(context);
String jsonStr = jsonEncode(pd);
printLongString(jsonStr);
try {
String url = "/app/highwork/" + msg;
final result = await ApiService.submitHomework(url, pd);
LoadingDialogHelper.hide(context);
if (result['result'] == 'success') {
ToastUtil.showSuccess(context, status == '1' ? '提交成功' : '已暂存');
Navigator.pop(context);
}
} catch (e) {
LoadingDialogHelper.hide(context);
ToastUtil.showNormal(context, '操作失败:$e');
}
}
void printLongString(String text, {int chunkSize = 800}) {
final pattern = RegExp('.{1,$chunkSize}'); // chunkSize
for (final match in pattern.allMatches(text)) {
print(match.group(0));
}
}
Future<void> _getHotWorkNameList() async {
final result = await ApiService.getHotWorkNameList();
setState(() {
workUserList = result['varList'] ?? '';
List<String> names =
workUserList.map((item) => item['NAME'] as String).toList();
});
}
///
Future<void> _getData() async {
final data = await ApiService.getHighHomeworkFindById(widget.HIGHWORK_ID);
setState(() {
pd = data['pd'];
if (pd['STEP_ID'] == 0) {
isEditable = true;
} else {
_getSigns(pd['HIGHWORK_ID'] ?? '');
_getMeasures(pd['HIGHWORK_ID'] ?? '');
}
//
_contentController.text = pd['WORK_CONTENT'] ?? '';
_locationController.text = pd['WORK_PLACE'] ?? '';
_hightController.text = pd['WORK_HIGH'] ?? '';
_relatedController.text = pd['SPECIAL_WORK'] ?? '';
_riskController.text = pd['RISK_IDENTIFICATION'] ?? '';
});
// final data = await ApiService.getHighHomeworkFindById(widget.HIGHWORK_ID);
// setState(() {
// pd = data['pd'];
// });
// LoadingDialogHelper.hide(context);
}
Future<void> _getSigns(String homework_id) async {
final data = await ApiService.listSignFinished(
homework_id.length > 0 ? homework_id : widget.HIGHWORK_ID,
);
setState(() {
signs = data['signs'] ?? {};
});
}
Future<void> _getMeasures(String homework_id) async {
final data = await ApiService.listSignFinishMeasures('highwork',
homework_id.length > 0 ? homework_id : widget.HIGHWORK_ID,
);
setState(() {
measuresList = List<Map<String, dynamic>>.from(
data['finishMeasuresList'] ?? <Map<String, dynamic>>[],
);
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: h_backGroundColor(),
appBar: MyAppbar(title: '高处作业申请'),
body: SafeArea(
child: SingleChildScrollView(
padding: EdgeInsets.all(12),
child: Column(
children: [
_card(
HighWorkDetailFormWidget(
pd: pd,
isEditable: isEditable,
contentController: _contentController,
locationController: _locationController,
hightController: _hightController,
relatedController: _relatedController,
riskController: _riskController,
onChooseLevel: _chooseLevel,
),
),
if (isEditable)
Column(
children: [
SizedBox(height: 15),
_card(_chooseItem(EditUserType.GUARDIAN)),
SizedBox(height: 15),
_card(_chooseItem(EditUserType.CONFESS)),
SizedBox(height: 15),
_card(_chooseItem(EditUserType.ACCEPT_CONFESS)),
SizedBox(height: 15),
_card(_chooseItem(EditUserType.WORK_USER)),
SizedBox(height: 15),
_card(_chooseItem(EditUserType.CONFIRM)),
SizedBox(height: 15),
_card(_chooseItem(EditUserType.LEADER)),
SizedBox(height: 15),
_card(_chooseItem(EditUserType.AUDIT)),
SizedBox(height: 15),
_card(_chooseItem(EditUserType.APPROVE)),
SizedBox(height: 15),
_card(
Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
_chooseItem(EditUserType.WORK_START),
Divider(),
Row(
children: [
SizedBox(width: 12),
Text(
'友情提示:负责填写作业实际开始时间',
style: TextStyle(color: Colors.red),
),
],
),
SizedBox(height: 5),
],
),
),
SizedBox(height: 15),
_card(
Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
_chooseItem(EditUserType.WORK_END),
Divider(),
Row(
children: [
SizedBox(width: 12),
Text(
'友情提示:负责填写作业实际结束时间',
style: TextStyle(color: Colors.red),
),
],
),
SizedBox(height: 5),
],
),
),
SizedBox(height: 15),
_card(_chooseItem(EditUserType.ACCEPT)),
SizedBox(height: 15),
],
),
if (measuresList.length > 0)
Column(
children: [
SizedBox(height: 20),
ListItemFactory.createBuildSimpleSection('安全防护措施'),
Container(
color: Colors.white,
child: MeasuresListWidget(
measuresList:
measuresList, // List<Map<String, dynamic>>
baseImgPath: ApiService.baseImgPath,
isAllowEdit: false,
),
),
],
),
if (FormUtils.hasValue(signs, 'MEASURES_CONFIRM'))
Column(
children: [
SizedBox(height: 20),
ListItemFactory.createBuildSimpleSection('其他安全防护措施'),
Container(
color: Colors.white,
child: OtherMeasuresWidget(
otherMeasures: signs['MEASURES_CONFIRM'],
baseImgPath: ApiService.baseImgPath,
),
),
],
),
SignaturesListWidget(
signs: signs,
pd: pd,
baseImgPath: ApiService.baseImgPath,
),
isEditable
? Row(
spacing: 10,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: CustomButton(
height: 45,
textStyle: TextStyle(
fontSize: 16,
color: Colors.white,
),
text: '提交',
backgroundColor: Colors.blue,
onPressed: () {
_submit('1');
},
),
),
Expanded(
child: CustomButton(
textStyle: TextStyle(
fontSize: 16,
color: Colors.white,
),
text: '暂存',
backgroundColor: Colors.green,
onPressed: () {
_submit('0');
},
),
),
],
)
: Column(
children: [
SizedBox(height: 20),
Row(
children: [
SizedBox(width: 50),
Expanded(
child: CustomButton(
height: 45,
textStyle: TextStyle(
fontSize: 16,
color: Colors.white,
),
text: '返回',
backgroundColor: Colors.green,
onPressed: () {
Navigator.pop(context);
},
),
),
SizedBox(width: 50),
],
),
],
),
],
),
),
),
);
}
}

View File

@ -1,31 +1,34 @@
import 'package:flutter/material.dart';
import 'package:qhd_prevention/customWidget/toast_util.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/dh_work_detai/hotwork_apply_detail.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/aqcs_work_detail/hotwork_safe_func_sure.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/aqgl_work_detail/hotwork_aqgl_detail.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/aqjd_work_detail/hotwork_aqjd_detail.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/dbbz_work_detail/hotwork_dbbz_detail.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/dhsp_work_detail/hotwork_dhsp_detail.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/jhr_work_detail/hotwork_jhr_detail.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/jszy_work_detail/hotwork_jszy_detail.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/kszy_work_detail/hotwork_kszy_detail.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/szaq_work_detail/hotwork_set_safe_detail.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/szdw_work_detail/hotwork_szdw_detail.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/ysgd_work_detail/hotwork_ysgd_detail.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/zyfz_work_detail/hotwork_zyfz_detail.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/gc_work/gc_work_detai/highwork_apply_detail.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/gc_work/aqcs_work_detail/hotwork_safe_func_sure.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/gc_work/aqgl_work_detail/hotwork_aqgl_detail.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/gc_work/aqjd_work_detail/hotwork_aqjd_detail.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/gc_work/dbbz_work_detail/hotwork_dbbz_detail.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/gc_work/dhsp_work_detail/hotwork_dhsp_detail.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/gc_work/jhr_work_detail/hotwork_jhr_detail.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/gc_work/jszy_work_detail/hotwork_jszy_detail.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/gc_work/kszy_work_detail/hotwork_kszy_detail.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/gc_work/szaq_work_detail/highwork_set_safe_detail.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/gc_work/szdw_work_detail/hotwork_szdw_detail.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/gc_work/ysgd_work_detail/hotwork_ysgd_detail.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/gc_work/zyfz_work_detail/hotwork_zyfz_detail.dart';
import 'package:qhd_prevention/pages/my_appbar.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/tabList/special_Wrok/dh_work/qtfx_work_detail/hotwork_gas_list.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_Wrok/dh_work/jsjd_work_detail/hotwork_jsjd_detail.dart';
class HighworkListPage extends StatefulWidget {
final String flow;
final String workTypeTitle;
const HighworkListPage({Key? key, required this.flow, required this.workTypeTitle}) : super(key: key);
const HighworkListPage({
Key? key,
required this.flow,
required this.workTypeTitle,
}) : super(key: key);
@override
_HighworkListPageState createState() => _HighworkListPageState();
@ -128,16 +131,17 @@ class _HighworkListPageState extends State<HighworkListPage> {
list.clear();
_fetchData();
}
///
void _handleApply() {
//
pushPage(HotworkApplyDetail(HOTWORK_ID: '', flow: widget.flow), context);
pushPage(HighworkApplyDetail(HIGHWORK_ID: '', flow: widget.flow), context);
}
///
Future<void> _openFlowDrawer(String hotworkId) async {
try {
final response = await ApiService.dhGetFlowList(hotworkId);
final response = await ApiService.highGetFlowList(hotworkId);
final List<dynamic>? newFlow = response['flowList'];
if (newFlow == null || newFlow.isEmpty) {
ToastUtil.showNormal(context, '暂无流程图数据');
@ -159,70 +163,73 @@ class _HighworkListPageState extends State<HighworkListPage> {
}
void _goToDetail(Map<String, dynamic> item) async {
final Map<String, dynamic> data = {'HOTWORK_ID': item['HOTWORK_ID'], 'flow': widget.flow};
final Map<String, dynamic> data = {
'HIGHWORK_ID': item['HIGHWORK_ID'],
'flow': widget.flow,
};
String routeName = '';
switch (widget.flow) {
case '提交申请':
//await pushPage(HotworkApplyDetail(HOTWORK_ID: item['HOTWORK_ID'], flow: widget.flow), context);
await pushPage(HighworkApplyDetail(HIGHWORK_ID: item['HIGHWORK_ID'], flow: widget.flow), context);
break;
case '设置安全措施确认人':
//await pushPage(HotworkSetSafeDetail(HOTWORK_ID: item['HOTWORK_ID'], flow: widget.flow), context);
await pushPage(HighworkSetSafeDetail(HIGHWORK_ID: item['HIGHWORK_ID'], flow: widget.flow), context);
break;
case '安全措施确认':
//await pushPage(HotworkSafeFuncSure(HOTWORK_ID: item['HOTWORK_ID'], flow: widget.flow), context);
//await pushPage(HotworkSafeFuncSure(HIGHWORK_ID: item['HIGHWORK_ID'], flow: widget.flow), context);
break;
case '监护人签字':
routeName = '/hotwork-guardian-detail';
//await pushPage(HotworkJhrDetail(HOTWORK_ID: item['HOTWORK_ID'], flow: widget.flow), context);
//await pushPage(HotworkJhrDetail(HIGHWORK_ID: item['HIGHWORK_ID'], flow: widget.flow), context);
break;
case '安全交底人签字':
routeName = '/hotwork-confess-detail';
//await pushPage(HotworkAqjdDetail(HOTWORK_ID: item['HOTWORK_ID'], flow: widget.flow), context);
//await pushPage(HotworkAqjdDetail(HIGHWORK_ID: item['HIGHWORK_ID'], flow: widget.flow), context);
break;
case '接受交底人签字':
routeName = '/hotwork-acceptconfess-detail';
//await pushPage(HotworkJsjdDetail(HOTWORK_ID: item['HOTWORK_ID'], flow: widget.flow), context);
//await pushPage(HotworkJsjdDetail(HIGHWORK_ID: item['HIGHWORK_ID'], flow: widget.flow), context);
break;
case '作业负责人签字':
routeName = '/hotwork-confirm-detail';
//await pushPage(HotworkZyfzDetail(HOTWORK_ID: item['HOTWORK_ID'], flow: widget.flow), context);
//await pushPage(HotworkZyfzDetail(HIGHWORK_ID: item['HIGHWORK_ID'], flow: widget.flow), context);
break;
case '所在单位签字':
routeName = '/hotwork-leader-detail';
//await pushPage(HotworkSzdwDetail(HOTWORK_ID: item['HOTWORK_ID'], flow: widget.flow), context);
//await pushPage(HotworkSzdwDetail(HIGHWORK_ID: item['HIGHWORK_ID'], flow: widget.flow), context);
break;
case '安全管理部门签字':
routeName = '/hotwork-audit-detail';
//await pushPage(HotworkAqglDetail(HOTWORK_ID: item['HOTWORK_ID'], flow: widget.flow), context);
//await pushPage(HotworkAqglDetail(HIGHWORK_ID: item['HIGHWORK_ID'], flow: widget.flow), context);
break;
case '审批人签字':
routeName = '/hotwork-approve-detail';
//await pushPage(HotworkDhspDetail(HOTWORK_ID: item['HOTWORK_ID'], flow: widget.flow), context);
//await pushPage(HotworkDhspDetail(HIGHWORK_ID: item['HIGHWORK_ID'], flow: widget.flow), context);
break;
case '当班班长验票':
routeName = '/hotwork-monitor-detail';
//await pushPage(HotworkDbbzDetail(HOTWORK_ID: item['HOTWORK_ID'], flow: widget.flow), context);
//await pushPage(HotworkDbbzDetail(HIGHWORK_ID: item['HIGHWORK_ID'], flow: widget.flow), context);
break;
case '开始作业':
routeName = '/hotwork-startwork-detail';
//await pushPage(HotworkKszyDetail(HOTWORK_ID: item['HOTWORK_ID'], flow: widget.flow), context);
//await pushPage(HotworkKszyDetail(HIGHWORK_ID: item['HIGHWORK_ID'], flow: widget.flow), context);
break;
case '结束作业':
routeName = '/hotwork-endwork-detail';
//await pushPage(HotworkJszyDetail(HOTWORK_ID: item['HOTWORK_ID'], flow: widget.flow), context);
//await pushPage(HotworkJszyDetail(HIGHWORK_ID: item['HIGHWORK_ID'], flow: widget.flow), context);
break;
case '验收签字':
routeName = '/hotwork-accept-detail';
//await pushPage(HotworkYsgdDetail(HOTWORK_ID: item['HOTWORK_ID'], flow: widget.flow), context);
//await pushPage(HotworkYsgdDetail(HIGHWORK_ID: item['HIGHWORK_ID'], flow: widget.flow), context);
break;
default:
@ -235,7 +242,7 @@ class _HighworkListPageState extends State<HighworkListPage> {
// Navigator.pushNamed(
// context,
// routeName,
// arguments: {'HOTWORK_ID': item['HOTWORK_ID'], 'flow': widget.flow},
// arguments: {'HIGHWORK_ID': item['HIGHWORK_ID'], 'flow': widget.flow},
// );
}
@ -249,9 +256,7 @@ class _HighworkListPageState extends State<HighworkListPage> {
final Color dotColor =
status == 1 ? Colors.green : (status == 0 ? Colors.blue : Colors.grey);
final Color textColor =
status == 1
? Colors.green
: (status == 0 ? Colors.blue : Colors.black);
status == 1 ? Colors.green : (status == 0 ? Colors.blue : Colors.black);
return ListTile(
visualDensity: VisualDensity(vertical: -4),
@ -307,6 +312,7 @@ class _HighworkListPageState extends State<HighworkListPage> {
),
);
}
String _getWorkLevelText(dynamic level) {
switch (level?.toString()) {
case '1':
@ -319,6 +325,7 @@ class _HighworkListPageState extends State<HighworkListPage> {
return 'IV级高处作业';
}
}
Widget _buildListItem(Map<String, dynamic> item) {
return Card(
color: Colors.white,
@ -328,19 +335,22 @@ class _HighworkListPageState extends State<HighworkListPage> {
child: Padding(
padding: const EdgeInsets.all(12.0),
child: Column(
spacing: 8,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text("编号: ${item['CHECK_NO'] ?? ''}", style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),),
Text(
"编号: ${item['CHECK_NO'] ?? ''}",
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
),
Text(
"作业级别: ${_getWorkLevelText(item['WORK_LEVEL'])}",
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
),
],
),
const SizedBox(height: 8),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
@ -348,7 +358,6 @@ class _HighworkListPageState extends State<HighworkListPage> {
Text("监护人: ${item['GUARDIAN_USER_NAME'] ?? ''}"),
],
),
const SizedBox(height: 8),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
@ -356,36 +365,24 @@ class _HighworkListPageState extends State<HighworkListPage> {
Text("接受交底人: ${item['ACCEPT_CONFESS_USER_NAME'] ?? ''}"),
],
),
const SizedBox(height: 8),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text("作业负责人: ${item['CONFIRM_USER_NAME'] ?? ''}"),
Text("所在单位负责人: ${item['LEADER_USER_NAME'] ?? ''}"),
],
),
// const SizedBox(height: 8),
// Row(
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
// children: [
// Text("作业负责人: ${item['CONFIRM_USER_NAME'] ?? ''}"),
// Text("动火点负责人: ${item['LEADER_USER_NAME'] ?? ''}"),
// ],
// ),
const SizedBox(height: 8),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text("作业负责人: ${item['CONFIRM_USER_NAME'] ?? ''}"),
Text("所在单位负责人: ${item['LEADER_USER_NAME'] ?? ''}"),
],
),
if (item['AUDIT_USER_NAME'] != null)
Text("安全管理部门负责人: ${item['AUDIT_USER_NAME'] ?? ''}"),
if (item['APPROVE_USER_NAME'] != null)
Text("安全管理部门负责人: ${item['APPROVE_USER_NAME'] ?? ''}"),
const SizedBox(height: 8),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text("动火前在岗班长: ${item['MONITOR_USER_NAME'] ?? ''}"),
Text("验收部门负责人: ${item['ACCEPT_USER_NAME'] ?? ''}"),
],
),
const SizedBox(height: 8),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
if (item['APPROVE_USER_NAME'] != null)
Text("审批部门负责人: ${item['APPROVE_USER_NAME'] ?? ''}"),
Text("验收部门负责人: ${item['ACCEPT_USER_NAME'] ?? ''}"),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
@ -397,18 +394,19 @@ class _HighworkListPageState extends State<HighworkListPage> {
),
],
),
const SizedBox(height: 8),
Row(children: [
CustomButton(
text: '查看流程图',
height: 35,
padding: EdgeInsets.symmetric(horizontal: 12),
margin: EdgeInsets.only(left: 0),
backgroundColor: Colors.blue,
onPressed: () => _openFlowDrawer(item['HOTWORK_ID']),
),
SizedBox(width: 1,)
],)
Row(
children: [
CustomButton(
text: '查看流程图',
height: 35,
padding: EdgeInsets.symmetric(horizontal: 12),
margin: EdgeInsets.only(left: 0),
backgroundColor: Colors.blue,
onPressed: () => _openFlowDrawer(item['HIGHWORK_ID']),
),
SizedBox(width: 1),
],
),
],
),
),

View File

@ -0,0 +1,352 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:qhd_prevention/customWidget/ItemWidgetFactory.dart';
import 'package:qhd_prevention/customWidget/custom_button.dart';
import 'package:qhd_prevention/customWidget/toast_util.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/HotWorkDetailFormWidget.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/pages/home/tap/tabList/special_wrok/dh_work/qtfx_work_detail/hotwork_gas_list.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_Wrok/MeasuresListWidget.dart';
import 'package:qhd_prevention/customWidget/custom_alert_dialog.dart';
import 'package:qhd_prevention/customWidget/single_image_viewer.dart';
import 'package:qhd_prevention/pages/mine/mine_sign_page.dart';
///
class HotworkJhrDetail extends StatefulWidget {
const HotworkJhrDetail({
super.key,
required this.HOTWORK_ID,
required this.flow,
});
final String HOTWORK_ID;
final String flow;
@override
State<HotworkJhrDetail> createState() => _HotworkJhrDetailState();
}
class _HotworkJhrDetailState extends State<HotworkJhrDetail> {
late bool isEditable = false;
///
late Map<String, dynamic> pd = {};
///
late List<Map<String, dynamic>> measuresList = [];
late Map<String, dynamic> signs = {};
List<String> imagePaths = [];
List<String> signTimes = []; //
@override
void initState() {
super.initState();
_getData();
}
///
Future<void> _sign() async {
final path = await Navigator.push(
context,
MaterialPageRoute(builder: (context) => MineSignPage()),
);
if (path != null) {
final now = DateFormat('yyyy-MM-dd HH:mm').format(DateTime.now());
setState(() {
imagePaths.add(path);
signTimes.add(now);
FocusHelper.clearFocus(context);
});
}
}
Widget _signListWidget() {
return Column(
children:
imagePaths.map((path) {
return Column(
children: [
const SizedBox(height: 10),
const Divider(),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
GestureDetector(
child: // ConstrainedBox BoxFit.contain
ConstrainedBox(
constraints: const BoxConstraints(
maxWidth: 200,
maxHeight: 150,
),
child: Image.file(
File(path),
//
fit: BoxFit.contain,
),
),
onTap: () {
presentOpaque(
SingleImageViewer(imageUrl: path),
context,
);
},
),
Column(
children: [
Container(
padding: const EdgeInsets.only(right: 5),
child: CustomButton(
text: 'X',
height: 30,
padding: const EdgeInsets.symmetric(horizontal: 10),
backgroundColor: Colors.red,
onPressed: () {
setState(() {
imagePaths.remove(path);
});
},
),
),
const SizedBox(height: 80),
],
),
],
),
],
);
}).toList(),
);
}
/// -1 1
Future<void> _submit(String status) async {
if (imagePaths.isEmpty) {
ToastUtil.showNormal(context, '请签字');
return;
}
String reasonText = '';
if (status == '1') {
} else {
await showDialog<String>(
context: context,
builder:
(_) => CustomAlertDialog(
title: '作废原因',
mode: DialogMode.input,
hintText: '请输入作废原因',
cancelText: '取消',
confirmText: '确定',
onInputConfirm: (text) {
reasonText = text;
},
),
);
if (reasonText.isEmpty) {
ToastUtil.showNormal(context, '请填写作废原因');
return;
}
}
final Map<String, dynamic> formData = {};
//
formData['HOTWORK_ID'] = widget.HOTWORK_ID;
formData['SIGNTIME'] = signTimes.join(',');
formData['USER_ID'] = SessionService.instance.loginUserId;
formData['APPLY_STATUS'] = status;
formData['STEP_REASON'] = reasonText;
await showDialog<String>(
context: context,
builder:
(_) => CustomAlertDialog(
title: '提示',
content: '请确认' + (status == '1' ? "通过" : "作废") + '本作业票?',
cancelText: '取消',
confirmText: '确定',
onConfirm: () async {
LoadingDialogHelper.show(context);
try {
final result = await ApiService.saveSafeFunctionSure(
'highwork',
formData,
imagePaths,
);
LoadingDialogHelper.hide(context);
if (result['result'] == 'success') {
ToastUtil.showSuccess(
context,
'保存成功',
);
Navigator.pop(context);
}
} catch (e) {
LoadingDialogHelper.hide(context);
ToastUtil.showNormal(context, '操作失败:$e');
}
},
),
);
}
///
Future<void> _getData() async {
final data = await ApiService.getHighHomeworkFindById(widget.HOTWORK_ID);
setState(() {
pd = data['pd'];
_getSigns(pd['HOTWORK_ID'] ?? '');
_getMeasures(pd['HOTWORK_ID'] ?? '');
});
}
Future<void> _getMeasures(String homework_id) async {
final data = await ApiService.listSignFinishMeasures('highwork',
homework_id.length > 0 ? homework_id : widget.HOTWORK_ID,
);
setState(() {
measuresList = List<Map<String, dynamic>>.from(
data['finishMeasuresList'] ?? <Map<String, dynamic>>[],
);
});
}
Future<void> _getSigns(String homework_id) async {
final data = await ApiService.listSignFinished(
homework_id.length > 0 ? homework_id : widget.HOTWORK_ID,
);
setState(() {
signs = data['signs'] ?? {};
});
}
///
Widget _setSafeDetailWidget() {
return Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(8),
),
padding: EdgeInsets.symmetric(horizontal: 5),
child: Column(
children: [
if (measuresList.isNotEmpty)
Column(
children: [
SizedBox(height: 5),
ListItemFactory.createBuildSimpleSection('安全防护措施'),
Container(
color: Colors.white,
child: MeasuresListWidget(
measuresList:
measuresList, // List<Map<String, dynamic>>
baseImgPath: ApiService.baseImgPath,
isAllowEdit: false,
isShowSign:true,
),
),
],
),
if (FormUtils.hasValue(signs, 'MEASURES_CONFIRM'))
Column(
children: [
SizedBox(height: 20),
ListItemFactory.createBuildSimpleSection('其他安全防护措施'),
Container(
color: Colors.white,
child: OtherMeasuresWidget(
otherMeasures: signs['MEASURES_CONFIRM'],
baseImgPath: ApiService.baseImgPath,
),
),
],
),
SizedBox(height: 20),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
ListItemFactory.createBuildSimpleSection('监护人'),
CustomButton(
text: '新增手写签字',
height: 36,
backgroundColor: Colors.green,
onPressed: () {
_sign();
},
),
],
),
SizedBox(height: 10),
if (imagePaths.isNotEmpty) _signListWidget(),
],
),
);
}
///
Widget _bottomButtons() {
return Row(
spacing: 10,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: CustomButton(
height: 45,
textStyle: TextStyle(fontSize: 16, color: Colors.white),
text: '作废',
backgroundColor: Colors.red,
onPressed: () {
_submit('-1');
},
),
),
Expanded(
child: CustomButton(
textStyle: TextStyle(fontSize: 16, color: Colors.white),
text: '通过',
backgroundColor: Colors.green,
onPressed: () {
_submit('1');
},
),
),
],
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: MyAppbar(title: '监护人签字确认'),
body: SafeArea(
child: SingleChildScrollView(
padding: EdgeInsets.all(12),
child: Column(
children: [
// _card(_defaultDetail()),
HotWorkDetailFormWidget(
pd: pd,
isEditable: false,
onChooseLevel: (){},
onChooseHotworkUser: (){},
onAnalyzeTap: () {
pushPage(
HotworkGasList(HOTWORK_ID: widget.HOTWORK_ID),
context,
);
},
),
SizedBox(height: 20),
_setSafeDetailWidget(),
SizedBox(height: 20),
_bottomButtons(),
],
),
),
),
);
}
}

View File

@ -0,0 +1,308 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:qhd_prevention/customWidget/ItemWidgetFactory.dart';
import 'package:qhd_prevention/customWidget/custom_button.dart';
import 'package:qhd_prevention/customWidget/toast_util.dart';
import 'package:qhd_prevention/pages/home/tap/item_list_widget.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/pages/home/tap/tabList/special_wrok/dh_work/qtfx_work_detail/hotwork_gas_list.dart';
import 'package:qhd_prevention/customWidget/custom_alert_dialog.dart';
import 'package:qhd_prevention/customWidget/single_image_viewer.dart';
import 'package:qhd_prevention/pages/mine/mine_sign_page.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/SpecialWorkFormBaseWork.dart';///
class HotworkJsjdDetail extends StatefulWidget {
const HotworkJsjdDetail({
super.key,
required this.HOTWORK_ID,
required this.flow,
});
final String HOTWORK_ID;
final String flow;
@override
State<HotworkJsjdDetail> createState() => _HotworkJsjdDetailState();
}
class _HotworkJsjdDetailState extends State<HotworkJsjdDetail> {
late bool isEditable = false;
///
late Map<String, dynamic> pd = {};
///
late List<Map<String, dynamic>> measuresList = [];
late Map<String, dynamic> signs = {};
List<String> signImages = [];
List<String> signTimes = []; //
@override
void initState() {
super.initState();
_getData();
}
///
Future<void> _sign() async {
final path = await Navigator.push(
context,
MaterialPageRoute(builder: (context) => MineSignPage()),
);
if (path != null) {
final now = DateFormat('yyyy-MM-dd HH:mm').format(DateTime.now());
setState(() {
signImages.add(path);
signTimes.add(now);
FocusHelper.clearFocus(context);
});
}
}
Widget _signListWidget() {
return Column(
children:
signImages.map((path) {
return Column(
children: [
const SizedBox(height: 10),
const Divider(),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
GestureDetector(
child: // ConstrainedBox BoxFit.contain
ConstrainedBox(
constraints: const BoxConstraints(
maxWidth: 200,
maxHeight: 150,
),
child: Image.file(
File(path),
//
fit: BoxFit.contain,
),
),
onTap: () {
presentOpaque(
SingleImageViewer(imageUrl: path),
context,
);
},
),
Column(
children: [
Container(
padding: const EdgeInsets.only(right: 5),
child: CustomButton(
text: 'X',
height: 30,
padding: const EdgeInsets.symmetric(horizontal: 10),
backgroundColor: Colors.red,
onPressed: () {
setState(() {
signImages.remove(path);
});
},
),
),
const SizedBox(height: 80),
],
),
],
),
],
);
}).toList(),
);
}
/// -1 1
Future<void> _submit(String status) async {
if (signImages.isEmpty) {
ToastUtil.showNormal(context, '请签字');
return;
}
String reasonText = '';
if (status == '1') {
} else {
await showDialog<String>(
context: context,
builder:
(_) => CustomAlertDialog(
title: '作废原因',
mode: DialogMode.input,
hintText: '请输入作废原因',
cancelText: '取消',
confirmText: '确定',
onInputConfirm: (text) {
reasonText = text;
},
),
);
if (reasonText.isEmpty) {
ToastUtil.showNormal(context, '请填写作废原因');
return;
}
}
// measures
final Map<String, dynamic> formData = {};
//
formData['HOTWORK_ID'] = widget.HOTWORK_ID;
formData['SIGNTIME'] = signTimes.join(',');
formData['USER_ID'] = SessionService.instance.loginUserId;
formData['APPLY_STATUS'] = status;
formData['STEP_REASON'] = reasonText;
await showDialog<String>(
context: context,
builder:
(_) => CustomAlertDialog(
title: '提示',
content: '请确认' + (status == '1' ? "通过" : "作废") + '本作业票?',
cancelText: '取消',
confirmText: '确定',
onConfirm: () async {
LoadingDialogHelper.show(context);
try {
final result = await ApiService.saveSafeFunctionSure(
'highwork',
formData,
signImages,
);
LoadingDialogHelper.hide(context);
if (result['result'] == 'success') {
ToastUtil.showSuccess(context, '保存成功');
Navigator.pop(context);
}
} catch (e) {
LoadingDialogHelper.hide(context);
ToastUtil.showNormal(context, '操作失败:$e');
}
},
),
);
}
///
Future<void> _getData() async {
final data = await ApiService.getHighHomeworkFindById(widget.HOTWORK_ID);
setState(() {
pd = data['pd'];
_getSigns(pd['HOTWORK_ID'] ?? '');
_getMeasures(pd['HOTWORK_ID'] ?? '');
});
}
Future<void> _getMeasures(String homework_id) async {
final data = await ApiService.listSignFinishMeasures('highwork',
homework_id.length > 0 ? homework_id : widget.HOTWORK_ID,
);
setState(() {
measuresList = List<Map<String, dynamic>>.from(
data['finishMeasuresList'] ?? <Map<String, dynamic>>[],
);
});
}
Future<void> _getSigns(String homework_id) async {
final data = await ApiService.listSignFinished(
homework_id.length > 0 ? homework_id : widget.HOTWORK_ID,
);
setState(() {
signs = data['signs'] ?? {};
});
}
///
Widget _bottomButtons() {
return Row(
spacing: 10,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: CustomButton(
height: 45,
textStyle: TextStyle(fontSize: 16, color: Colors.white),
text: '作废',
backgroundColor: Colors.red,
onPressed: () {
_submit('-1');
},
),
),
Expanded(
child: CustomButton(
textStyle: TextStyle(fontSize: 16, color: Colors.white),
text: '通过',
backgroundColor: Colors.green,
onPressed: () {
_submit('1');
},
),
),
],
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: MyAppbar(title: '接受交底人签字确认'),
body: SafeArea(
child: SingleChildScrollView(
padding: EdgeInsets.all(12),
child: Column(
spacing: 12,
children: [
// _setSafeDetailWidget(),
SpecialWorkFormBaseWork(
pd: pd,
measuresList: measuresList,
signs: signs,
baseImgPath: ApiService.baseImgPath,
isEditable: false,
onChooseLevel: () {},
onChooseHotworkUser: () {},
onAnalyzeTap: () {
pushPage(
HotworkGasList(HOTWORK_ID: widget.HOTWORK_ID),
context,
);
},
),
ItemListWidget.itemContainer(
Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
ListItemFactory.headerTitle('接受交底人'),
CustomButton(
text: '新增手写签字',
height: 36,
backgroundColor: Colors.green,
onPressed: () {
_sign();
},
),
],
),
if (signImages.isNotEmpty) _signListWidget(),
],
),
),
_bottomButtons(),
],
),
),
),
);
}
}

View File

@ -0,0 +1,370 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:qhd_prevention/customWidget/ItemWidgetFactory.dart';
import 'package:qhd_prevention/customWidget/custom_button.dart';
import 'package:qhd_prevention/customWidget/toast_util.dart';
import 'package:qhd_prevention/pages/home/tap/item_list_widget.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/pages/home/tap/tabList/special_wrok/dh_work/qtfx_work_detail/hotwork_gas_list.dart';
import 'package:qhd_prevention/customWidget/custom_alert_dialog.dart';
import 'package:qhd_prevention/customWidget/single_image_viewer.dart';
import 'package:qhd_prevention/pages/mine/mine_sign_page.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/SpecialWorkFormBaseWork.dart';
import 'package:qhd_prevention/customWidget/picker/CupertinoDatePicker.dart';
///
class HotworkJszyDetail extends StatefulWidget {
const HotworkJszyDetail({
super.key,
required this.HOTWORK_ID,
required this.flow,
});
final String HOTWORK_ID;
final String flow;
@override
State<HotworkJszyDetail> createState() => _HotworkJszyDetailState();
}
class _HotworkJszyDetailState extends State<HotworkJszyDetail> {
late bool isEditable = false;
///
late Map<String, dynamic> pd = {};
///
String endTime = '';
///
late List<Map<String, dynamic>> measuresList = [];
late Map<String, dynamic> signs = {};
List<String> signImages = [];
List<String> signTimes = []; //
@override
void initState() {
super.initState();
_getData();
}
///
Future<void> _sign() async {
final path = await Navigator.push(
context,
MaterialPageRoute(builder: (context) => MineSignPage()),
);
if (path != null) {
final now = DateFormat('yyyy-MM-dd HH:mm').format(DateTime.now());
setState(() {
signImages.add(path);
signTimes.add(now);
FocusHelper.clearFocus(context);
});
}
}
Widget _signListWidget() {
return Column(
children:
signImages.map((path) {
return Column(
children: [
const SizedBox(height: 10),
const Divider(),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
GestureDetector(
child: // ConstrainedBox BoxFit.contain
ConstrainedBox(
constraints: const BoxConstraints(
maxWidth: 200,
maxHeight: 150,
),
child: Image.file(
File(path),
//
fit: BoxFit.contain,
),
),
onTap: () {
presentOpaque(
SingleImageViewer(imageUrl: path),
context,
);
},
),
Column(
children: [
Container(
padding: const EdgeInsets.only(right: 5),
child: CustomButton(
text: 'X',
height: 30,
padding: const EdgeInsets.symmetric(horizontal: 10),
backgroundColor: Colors.red,
onPressed: () {
setState(() {
signImages.remove(path);
});
},
),
),
const SizedBox(height: 80),
],
),
],
),
],
);
}).toList(),
);
}
bool checkWorkTime(Map<String, dynamic> pd, BuildContext context) {
//
final start = DateTime.parse(pd['WORK_START_DATE'] as String);
final end = DateTime.parse(endTime);
//
if (end.isAtSameMomentAs(start) || end.isBefore(start)) {
ToastUtil.showNormal(context, '作业开始时间不能晚于或等于结束时间,请重新选择');
return false;
}
// 8 8 * 60 * 60 * 1000 ms
if (pd['WORK_LEVEL'] == '特级' || pd['WORK_LEVEL'] == '一级') {
final diffMs = end.difference(start).inMilliseconds;
const max8h = 8 * 60 * 60 * 1000;
if (diffMs >= max8h) {
ToastUtil.showNormal(context, '动火级别为特级或一级时动火作业开始时间与结束时间应不超过8小时请重新选择');
return false;
}
}
// 72 72 * 60 * 60 * 1000 ms
if (pd['WORK_LEVEL'] == '二级') {
final diffMs = end.difference(start).inMilliseconds;
const max72h = 72 * 60 * 60 * 1000;
if (diffMs >= max72h) {
ToastUtil.showNormal(context, '动火级别为二级时动火作业开始时间与结束时间应不超过72小时请重新选择');
return false;
}
}
return true;
}
/// -1 1
Future<void> _submit(String status) async {
if (signImages.isEmpty) {
ToastUtil.showNormal(context, '请签字');
return;
}
String reasonText = '';
if (status == '1') {
if (endTime.isEmpty) {
ToastUtil.showNormal(context, '请选择作业结束时间');
return;
}
if (!checkWorkTime(pd, context)) {
return;
}
} else {
await showDialog<String>(
context: context,
builder:
(_) => CustomAlertDialog(
title: '作废原因',
mode: DialogMode.input,
hintText: '请输入作废原因',
cancelText: '取消',
confirmText: '确定',
onInputConfirm: (text) {
reasonText = text;
},
),
);
if (reasonText.isEmpty) {
ToastUtil.showNormal(context, '请填写作废原因');
return;
}
}
// measures
final Map<String, dynamic> formData = {};
//
formData['HOTWORK_ID'] = widget.HOTWORK_ID;
formData['SIGNTIME'] = signTimes.join(',');
formData['USER_ID'] = SessionService.instance.loginUserId;
formData['APPLY_STATUS'] = status;
formData['STEP_REASON'] = reasonText;
formData['WORK_END_DATE'] = endTime;
await showDialog<String>(
context: context,
builder:
(_) => CustomAlertDialog(
title: '提示',
content: '请确认' + (status == '1' ? "通过" : "作废") + '本作业票?',
cancelText: '取消',
confirmText: '确定',
onConfirm: () async {
LoadingDialogHelper.show(context);
try {
final result = await ApiService.saveSafeFunctionSure(
'highwork',
formData,
signImages,
);
LoadingDialogHelper.hide(context);
if (result['result'] == 'success') {
ToastUtil.showSuccess(context, '保存成功');
Navigator.pop(context);
}
} catch (e) {
LoadingDialogHelper.hide(context);
ToastUtil.showNormal(context, '操作失败:$e');
}
},
),
);
}
///
Future<void> _getData() async {
final data = await ApiService.getHighHomeworkFindById(widget.HOTWORK_ID);
setState(() {
pd = data['pd'];
_getSigns(pd['HOTWORK_ID'] ?? '');
_getMeasures(pd['HOTWORK_ID'] ?? '');
});
}
Future<void> _getMeasures(String homework_id) async {
final data = await ApiService.listSignFinishMeasures('highwork',
homework_id.length > 0 ? homework_id : widget.HOTWORK_ID,
);
setState(() {
measuresList = List<Map<String, dynamic>>.from(
data['finishMeasuresList'] ?? <Map<String, dynamic>>[],
);
});
}
Future<void> _getSigns(String homework_id) async {
final data = await ApiService.listSignFinished(
homework_id.length > 0 ? homework_id : widget.HOTWORK_ID,
);
setState(() {
signs = data['signs'] ?? {};
});
}
///
Widget _bottomButtons() {
return Row(
spacing: 10,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: CustomButton(
height: 45,
textStyle: TextStyle(fontSize: 16, color: Colors.white),
text: '作废',
backgroundColor: Colors.red,
onPressed: () {
_submit('-1');
},
),
),
Expanded(
child: CustomButton(
textStyle: TextStyle(fontSize: 16, color: Colors.white),
text: '通过',
backgroundColor: Colors.green,
onPressed: () {
_submit('1');
},
),
),
],
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: MyAppbar(title: '作业结束时间选择'),
body: SafeArea(
child: SingleChildScrollView(
padding: EdgeInsets.all(12),
child: Column(
spacing: 12,
children: [
// _setSafeDetailWidget(),
SpecialWorkFormBaseWork(
pd: pd,
measuresList: measuresList,
signs: signs,
baseImgPath: ApiService.baseImgPath,
isEditable: false,
onChooseLevel: () {},
onChooseHotworkUser: () {},
onAnalyzeTap: () {
pushPage(
HotworkGasList(HOTWORK_ID: widget.HOTWORK_ID),
context,
);
},
),
ItemListWidget.itemContainer(
Column(
children: [
GestureDetector(
child: ListItemFactory.createRowSpaceBetweenItem(leftText: '作业结束时间', rightText: endTime.isEmpty?'请选择':endTime, isRight: true),
onTap: () async {
DateTime? picked = await BottomDateTimePicker.showDate(context);
if (picked != null) {
setState(() {
endTime = DateFormat('yyyy-MM-dd HH:mm').format(picked);
});
}
},
),
Divider(),
Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
ListItemFactory.headerTitle('作业结束时间负责人'),
CustomButton(
text: '新增手写签字',
height: 36,
backgroundColor: Colors.green,
onPressed: () {
_sign();
},
),
],
),
if (signImages.isNotEmpty) _signListWidget(),
],
),
],
),
),
_bottomButtons(),
],
),
),
),
);
}
}

View File

@ -0,0 +1,343 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:qhd_prevention/customWidget/ItemWidgetFactory.dart';
import 'package:qhd_prevention/customWidget/custom_button.dart';
import 'package:qhd_prevention/customWidget/toast_util.dart';
import 'package:qhd_prevention/pages/home/tap/item_list_widget.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/pages/home/tap/tabList/special_wrok/dh_work/qtfx_work_detail/hotwork_gas_list.dart';
import 'package:qhd_prevention/customWidget/custom_alert_dialog.dart';
import 'package:qhd_prevention/customWidget/single_image_viewer.dart';
import 'package:qhd_prevention/pages/mine/mine_sign_page.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/SpecialWorkFormBaseWork.dart';
import 'package:qhd_prevention/customWidget/picker/CupertinoDatePicker.dart';
///
class HotworkKszyDetail extends StatefulWidget {
const HotworkKszyDetail({
super.key,
required this.HOTWORK_ID,
required this.flow,
});
final String HOTWORK_ID;
final String flow;
@override
State<HotworkKszyDetail> createState() => _HotworkKszyDetailState();
}
class _HotworkKszyDetailState extends State<HotworkKszyDetail> {
late bool isEditable = false;
///
late Map<String, dynamic> pd = {};
///
String startTime = '';
///
late List<Map<String, dynamic>> measuresList = [];
late Map<String, dynamic> signs = {};
List<String> signImages = [];
List<String> signTimes = []; //
@override
void initState() {
super.initState();
_getData();
}
///
Future<void> _sign() async {
final path = await Navigator.push(
context,
MaterialPageRoute(builder: (context) => MineSignPage()),
);
if (path != null) {
final now = DateFormat('yyyy-MM-dd HH:mm').format(DateTime.now());
setState(() {
signImages.add(path);
signTimes.add(now);
FocusHelper.clearFocus(context);
});
}
}
Widget _signListWidget() {
return Column(
children:
signImages.map((path) {
return Column(
children: [
const SizedBox(height: 10),
const Divider(),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
GestureDetector(
child: // ConstrainedBox BoxFit.contain
ConstrainedBox(
constraints: const BoxConstraints(
maxWidth: 200,
maxHeight: 150,
),
child: Image.file(
File(path),
//
fit: BoxFit.contain,
),
),
onTap: () {
presentOpaque(
SingleImageViewer(imageUrl: path),
context,
);
},
),
Column(
children: [
Container(
padding: const EdgeInsets.only(right: 5),
child: CustomButton(
text: 'X',
height: 30,
padding: const EdgeInsets.symmetric(horizontal: 10),
backgroundColor: Colors.red,
onPressed: () {
setState(() {
signImages.remove(path);
});
},
),
),
const SizedBox(height: 80),
],
),
],
),
],
);
}).toList(),
);
}
/// -1 1
Future<void> _submit(String status) async {
if (signImages.isEmpty) {
ToastUtil.showNormal(context, '请签字');
return;
}
String reasonText = '';
if (status == '1') {
if (startTime.isEmpty) {
ToastUtil.showNormal(context, '请选择作业开始时间');
return;
}
final workStart = DateTime.parse(pd['WORK_START_DATE'] as String);
final analyzeTime = DateTime.parse(pd['ANALYZE_TIME'] as String);
final intervalMs = workStart.difference(analyzeTime).inMilliseconds;
const thresholdMs = 30 * 60 * 1000;
if (intervalMs >= thresholdMs) {
ToastUtil.showNormal(context, '气体分析时间与开始时间间隔超过30分钟请重新上传气体检测结果');
return;
}
} else {
await showDialog<String>(
context: context,
builder:
(_) => CustomAlertDialog(
title: '作废原因',
mode: DialogMode.input,
hintText: '请输入作废原因',
cancelText: '取消',
confirmText: '确定',
onInputConfirm: (text) {
reasonText = text;
},
),
);
if (reasonText.isEmpty) {
ToastUtil.showNormal(context, '请填写作废原因');
return;
}
}
// measures
final Map<String, dynamic> formData = {};
//
formData['HOTWORK_ID'] = widget.HOTWORK_ID;
formData['SIGNTIME'] = signTimes.join(',');
formData['USER_ID'] = SessionService.instance.loginUserId;
formData['APPLY_STATUS'] = status;
formData['STEP_REASON'] = reasonText;
formData['WORK_START_DATE'] = startTime;
await showDialog<String>(
context: context,
builder:
(_) => CustomAlertDialog(
title: '提示',
content: '请确认' + (status == '1' ? "通过" : "作废") + '本作业票?',
cancelText: '取消',
confirmText: '确定',
onConfirm: () async {
LoadingDialogHelper.show(context);
try {
final result = await ApiService.saveSafeFunctionSure(
'highwork',
formData,
signImages,
);
LoadingDialogHelper.hide(context);
if (result['result'] == 'success') {
ToastUtil.showSuccess(context, '保存成功');
Navigator.pop(context);
}
} catch (e) {
LoadingDialogHelper.hide(context);
ToastUtil.showNormal(context, '操作失败:$e');
}
},
),
);
}
///
Future<void> _getData() async {
final data = await ApiService.getHighHomeworkFindById(widget.HOTWORK_ID);
setState(() {
pd = data['pd'];
_getSigns(pd['HOTWORK_ID'] ?? '');
_getMeasures(pd['HOTWORK_ID'] ?? '');
});
}
Future<void> _getMeasures(String homework_id) async {
final data = await ApiService.listSignFinishMeasures('highwork',
homework_id.length > 0 ? homework_id : widget.HOTWORK_ID,
);
setState(() {
measuresList = List<Map<String, dynamic>>.from(
data['finishMeasuresList'] ?? <Map<String, dynamic>>[],
);
});
}
Future<void> _getSigns(String homework_id) async {
final data = await ApiService.listSignFinished(
homework_id.length > 0 ? homework_id : widget.HOTWORK_ID,
);
setState(() {
signs = data['signs'] ?? {};
});
}
///
Widget _bottomButtons() {
return Row(
spacing: 10,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: CustomButton(
height: 45,
textStyle: TextStyle(fontSize: 16, color: Colors.white),
text: '作废',
backgroundColor: Colors.red,
onPressed: () {
_submit('-1');
},
),
),
Expanded(
child: CustomButton(
textStyle: TextStyle(fontSize: 16, color: Colors.white),
text: '通过',
backgroundColor: Colors.green,
onPressed: () {
_submit('1');
},
),
),
],
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: MyAppbar(title: '作业开始时间选择'),
body: SafeArea(
child: SingleChildScrollView(
padding: EdgeInsets.all(12),
child: Column(
spacing: 12,
children: [
// _setSafeDetailWidget(),
SpecialWorkFormBaseWork(
pd: pd,
measuresList: measuresList,
signs: signs,
baseImgPath: ApiService.baseImgPath,
isEditable: false,
onChooseLevel: () {},
onChooseHotworkUser: () {},
onAnalyzeTap: () {
pushPage(
HotworkGasList(HOTWORK_ID: widget.HOTWORK_ID),
context,
);
},
),
ItemListWidget.itemContainer(
Column(
children: [
GestureDetector(
child: ListItemFactory.createRowSpaceBetweenItem(leftText: '作业开始时间', rightText: startTime.isEmpty?'请选择':startTime, isRight: true),
onTap: () async {
DateTime? picked = await BottomDateTimePicker.showDate(context);
if (picked != null) {
setState(() {
startTime = DateFormat('yyyy-MM-dd HH:mm').format(picked);
});
}
},
),
Divider(),
Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
ListItemFactory.headerTitle('作业开始时间负责人'),
CustomButton(
text: '新增手写签字',
height: 36,
backgroundColor: Colors.green,
onPressed: () {
_sign();
},
),
],
),
if (signImages.isNotEmpty) _signListWidget(),
],
),
],
),
),
_bottomButtons(),
],
),
),
),
);
}
}

View File

@ -0,0 +1,130 @@
import 'package:flutter/material.dart';
import 'package:qhd_prevention/customWidget/custom_button.dart';
///
class SafeFunctionDialog extends StatefulWidget {
/// "PROTECTIVE_MEASURES" Map
final List<Map<String, dynamic>> data;
///
final List<Map<String, dynamic>> initialSelectedItems;
/// Map
final void Function(List<Map<String, dynamic>> selectedItems) onConfirm;
///
const SafeFunctionDialog({
Key? key,
required this.data,
this.initialSelectedItems = const [],
required this.onConfirm,
}) : super(key: key);
@override
State<SafeFunctionDialog> createState() => _SafeFunctionDialogState();
}
class _SafeFunctionDialogState extends State<SafeFunctionDialog> {
/// Map
late final List<Map<String, dynamic>> _allItems;
/// Map
late final List<Map<String, dynamic>> _selectedItems;
@override
void initState() {
super.initState();
//
_allItems = widget.data;
//
_selectedItems = List<Map<String, dynamic>>.from(widget.initialSelectedItems);
}
@override
Widget build(BuildContext context) {
return AlertDialog(
insetPadding: const EdgeInsets.symmetric(horizontal: 12, vertical: 24),
content: SizedBox(
width: MediaQuery.of(context).size.width - 24,
height: MediaQuery.of(context).size.height -
MediaQuery.of(context).padding.top -
MediaQuery.of(context).padding.bottom,
child: Column(
children: [
Expanded(
child: ListView.builder(
itemCount: _allItems.length,
itemBuilder: (ctx, index) {
final item = _allItems[index];
final label = item['PROTECTIVE_MEASURES'] as String? ?? '';
final checked = _selectedItems.contains(item);
return CheckboxListTile(
controlAffinity: ListTileControlAffinity.leading,
contentPadding: const EdgeInsets.symmetric(horizontal: 0),
activeColor: Colors.blue,
title: Text(label, style: const TextStyle(fontSize: 14)),
value: checked,
onChanged: (value) {
setState(() {
if (value == true) {
_selectedItems.add(item);
} else {
_selectedItems.remove(item);
}
});
},
);
},
),
),
const SizedBox(height: 16),
Row(
children: [
Expanded(
child: CustomButton(
text: '确定',
height: 40,
backgroundColor: Colors.blue,
onPressed: () {
widget.onConfirm(_selectedItems);
Navigator.of(context).pop();
},
),
),
const SizedBox(width: 12),
Expanded(
child: CustomButton(
text: '关闭',
height: 40,
backgroundColor: Colors.grey.shade300,
textStyle: TextStyle(color: Colors.grey.shade600),
onPressed: () => Navigator.of(context).pop(),
),
),
],
),
],
),
),
);
}
}
///
/// [initialSelected]
Future<void> showSafeFunctionDialog(
BuildContext context,
List<Map<String, dynamic>> data,
void Function(List<Map<String, dynamic>>) onConfirm, {
List<Map<String, dynamic>> initialSelected = const [],
}) {
return showDialog(
context: context,
barrierDismissible: false,
builder: (_) => SafeFunctionDialog(
data: data,
initialSelectedItems: initialSelected,
onConfirm: onConfirm,
),
);
}

View File

@ -0,0 +1,599 @@
import 'dart:convert';
import 'dart:io';
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:qhd_prevention/customWidget/ItemWidgetFactory.dart';
import 'package:qhd_prevention/customWidget/custom_button.dart';
import 'package:qhd_prevention/customWidget/department_person_picker.dart';
import 'package:qhd_prevention/customWidget/department_picker.dart';
import 'package:qhd_prevention/customWidget/toast_util.dart';
import 'package:qhd_prevention/pages/home/tap/item_list_widget.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/gc_work/HighWorkDetailFormWidget.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/custom_alert_dialog.dart';
import 'package:qhd_prevention/customWidget/single_image_viewer.dart';
import 'package:qhd_prevention/pages/mine/mine_sign_page.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_Wrok/dh_work/szaq_work_detail/SafeFunctionDialog.dart';
///
class HighworkSetSafeDetail extends StatefulWidget {
const HighworkSetSafeDetail({
super.key,
required this.HIGHWORK_ID,
required this.flow,
});
final String HIGHWORK_ID;
final String flow;
@override
State<HighworkSetSafeDetail> createState() => _HighworkSetSafeDetailState();
}
class _HighworkSetSafeDetailState extends State<HighworkSetSafeDetail> {
late bool isEditable = false;
///
late Map<String, dynamic> pd = {};
late List<Map<String, dynamic>> measuresList = [];
///
late List<MeasureItem> measuresListCopy = [];
List<String> imagePaths = [];
List<String> signTimes = []; //
@override
void initState() {
super.initState();
_getData();
addMeasuresListCopy();
}
String measuresListToJson() {
final List<Map<String, dynamic>> jsonList =
measuresListCopy.map((item) => item.toJson()).toList();
return jsonEncode(jsonList);
}
Widget _chooseItem(MeasureItem item) {
return Column(
children: [
ItemListWidget.selectableLineTitleTextField(
label: "确认单位",
isEditable: true,
text: item.DEPARTMENT_NAME ?? '请选择',
onTap: () => chooseUnitHandle(item),
),
Divider(height: 8, color: Colors.grey.shade200),
ItemListWidget.selectableLineTitleTextField(
label: '确认人',
isEditable: true,
text: item.USER_NAME ?? '请选择',
onTap: () => choosePersonHandle(item),
),
Divider(height: 8, color: Colors.grey.shade200),
//
ItemListWidget.OneRowButtonTitle(
isRequired: true,
label: '安全措施:',
buttonText: '选择安全措施',
onTap: () {
showSafeFunctionDialog(
context,
measuresList,
initialSelected: item.selectMeasures,
(selected) {
setState(() {
item.selectMeasures = selected;
});
},
);
},
),
],
);
}
///
void chooseUnitHandle(MeasureItem item) {
showModalBottomSheet(
context: context,
isScrollControlled: true,
barrierColor: Colors.black54,
backgroundColor: Colors.transparent,
builder:
(_) => DepartmentPicker(
onSelected: (id, name) async {
setState(() {
item.DEPARTMENT_ID = id;
item.DEPARTMENT_NAME = name;
});
_getPersonListForUnitId(item);
},
),
).then((_) {});
}
Future<void> _getPersonListForUnitId(MeasureItem item) async {
//
final result = await ApiService.getListTreePersonList(item.DEPARTMENT_ID);
setState(() {
item.userList = List<Map<String, dynamic>>.from(
result['userList'] ?? <Map<String, dynamic>>[],
);
});
}
///
void choosePersonHandle(MeasureItem item) async {
String unitId = item.DEPARTMENT_ID;
final personList = item.userList;
if (!unitId.isNotEmpty) {
ToastUtil.showNormal(context, '请先选择确认单位');
return;
}
if (personList.isEmpty) {
//
await _getPersonListForUnitId(item);
final list = item.userList;
if (list.isEmpty) {
//
ToastUtil.showNormal(context, '暂无数据,请选择其他单位');
} else {
choosePersonHandle(item);
}
return;
}
DepartmentPersonPicker.show(
context,
personsData: personList,
onSelected: (userId, name) {
setState(() {
item.USER_NAME = name;
item.USER_ID = userId;
print(json.encode(measuresListCopy));
});
},
).then((_) {});
}
///
Future<void> _sign() async {
final path = await Navigator.push(
context,
MaterialPageRoute(builder: (context) => MineSignPage()),
);
if (path != null) {
final now = DateFormat('yyyy-MM-dd HH:mm').format(DateTime.now());
setState(() {
imagePaths.add(path);
signTimes.add(now);
FocusHelper.clearFocus(context);
});
}
}
Widget _signListWidget() {
return Column(
children:
imagePaths.map((path) {
return Column(
children: [
const SizedBox(height: 10),
const Divider(),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
GestureDetector(
child: // ConstrainedBox BoxFit.contain
ConstrainedBox(
constraints: const BoxConstraints(
maxWidth: 200,
maxHeight: 150,
),
child: Image.file(
File(path),
//
fit: BoxFit.contain,
),
),
onTap: () {
presentOpaque(
SingleImageViewer(imageUrl: path),
context,
);
},
),
Column(
children: [
Container(
padding: const EdgeInsets.only(right: 5),
child: CustomButton(
text: 'X',
height: 30,
padding: const EdgeInsets.symmetric(horizontal: 10),
backgroundColor: Colors.red,
onPressed: () {
setState(() {
imagePaths.remove(path);
});
},
),
),
const SizedBox(height: 80),
],
),
],
),
],
);
}).toList(),
);
}
/// -1 1
Future<void> _submit(String status) async {
if (imagePaths.isEmpty) {
ToastUtil.showNormal(context, '请签字');
return;
}
List<Map<String, dynamic>> signers = [];
String reasonText = '';
if (status == '1') {
int index = 0;
for (var item in measuresListCopy) {
if (item.USER_ID.isEmpty) {
ToastUtil.showNormal(
context,
'${index + 1}项未设置确认人',
);
return;
}
if (item.selectMeasures.isEmpty) {
ToastUtil.showNormal(
context,
'${index + 1}项未选择安全措施',
);
return;
}
final userId = item.USER_ID;
final selectMeasures = item.selectMeasures as List<dynamic>? ?? [];
for (var item in selectMeasures) {
signers.add({
'BUS_HIGHWORK_MEASURES_ID': item['BUS_HIGHWORK_MEASURES_ID'],
'USER_ID': userId,
});
}
//
if (signers.length != measuresList.length) {
// 使 ScaffoldMessenger
ToastUtil.showNormal(context, '请为每个安全措施选择确认人');
return;
}
index++;
}
} else {
await showDialog<String>(
context: context,
builder:
(_) => CustomAlertDialog(
title: '作废原因',
mode: DialogMode.input,
hintText: '请输入作废原因',
cancelText: '取消',
confirmText: '确定',
onInputConfirm: (text) {
reasonText = text;
},
),
);
if (reasonText.isEmpty) {
ToastUtil.showNormal(context, '请填写作废原因');
return;
}
}
final Map<String, dynamic> formData = {};
//
formData['HIGHWORK_ID'] = widget.HIGHWORK_ID;
formData['SIGNTIME'] = signTimes.join(',');
formData['USER_ID'] = SessionService.instance.loginUserId;
formData['APPLY_STATUS'] = status;
formData['STEP_REASON'] = reasonText;
formData['PREPARERS'] = json.encode(signers);
await showDialog<String>(
context: context,
builder:
(_) => CustomAlertDialog(
title: '提示',
content: '请确认' + (status == '1' ? "通过" : "作废") + '本作业票?',
cancelText: '取消',
confirmText: '确定',
onConfirm: () async {
LoadingDialogHelper.show(context);
try {
final result = await ApiService.saveSafeFunctionSure(
'highwork',
formData,
imagePaths,
);
LoadingDialogHelper.hide(context);
if (result['result'] == 'success') {
ToastUtil.showSuccess(
context,
'保存成功',
);
Navigator.pop(context);
}
} catch (e) {
LoadingDialogHelper.hide(context);
ToastUtil.showNormal(context, '操作失败:$e');
}
},
),
);
}
void printLongString(String text, {int chunkSize = 800}) {
final pattern = RegExp('.{1,$chunkSize}'); // chunkSize
for (final match in pattern.allMatches(text)) {
print(match.group(0));
}
}
///
Future<void> _getData() async {
final data = await ApiService.getHighHomeworkFindById(widget.HIGHWORK_ID);
setState(() {
pd = data['pd'];
_getMeasures();
});
}
Future<void> _getMeasures() async {
final data = await ApiService.listSignFinishAllMeasures('highwork');
setState(() {
measuresList = List<Map<String, dynamic>>.from(
data['measuresList'] ?? <Map<String, dynamic>>[],
);
});
}
void removeMeasuresListCopy(int index) {
setState(() {
measuresListCopy.removeAt(index);
});
}
void addMeasuresListCopy() {
setState(() {
measuresListCopy.add(
MeasureItem(
id: Random().nextDouble(),
DEPARTMENT_ID: '',
DEPARTMENT_NAME: '',
USER_ID: '',
USER_NAME: '',
userList: [],
userIndex: -1,
selectMeasures: [],
),
);
});
}
///
Widget _setSafeDetailWidget() {
return Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(8),
),
padding: EdgeInsets.symmetric(horizontal: 5),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
ListItemFactory.createBuildSimpleSection('安全防护措施'),
CustomButton(
text: '添加',
padding: EdgeInsets.symmetric(horizontal: 15),
backgroundColor: Colors.blue,
height: 32,
onPressed: () => addMeasuresListCopy(),
),
],
),
...measuresListCopy.asMap().entries.map((entry) {
int index = entry.key;
MeasureItem item = entry.value;
return Padding(
padding: EdgeInsets.all(0),
child: Stack(
children: [
Container(
color: Colors.white,
child: Padding(
padding: EdgeInsets.all(12),
child: Container(
padding: EdgeInsets.all(2),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(5),
border: Border.all(color: Colors.grey.shade300),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// picker
_chooseItem(item),
...item.selectMeasures.asMap().entries.map((e) {
int idx = e.key;
String txt = e.value['PROTECTIVE_MEASURES'];
return Padding(
padding: EdgeInsets.only(
top: 4,
left: 12,
right: 12,
bottom: 12,
),
child: Text('${idx + 1}. $txt'),
);
}),
],
),
),
),
),
if (index != 0)
Positioned(
top: 0,
right: 0,
child: GestureDetector(
onTap: () => removeMeasuresListCopy(index),
child: Stack(
alignment: AlignmentDirectional.center,
children: [
Container(
decoration: BoxDecoration(
color: Colors.red,
borderRadius: BorderRadius.circular(10),
),
width: 20,
height: 20,
),
Icon(Icons.close, color: Colors.white, size: 15),
],
),
),
),
],
),
);
}),
SizedBox(height: 20),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
SizedBox(),
CustomButton(
text: '新增手写签字',
height: 36,
backgroundColor: Colors.green,
onPressed: () {
_sign();
},
),
],
),
SizedBox(height: 10),
if (imagePaths.isNotEmpty) _signListWidget(),
],
),
);
}
///
Widget _bottomButtons() {
return Row(
spacing: 10,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: CustomButton(
height: 45,
textStyle: TextStyle(fontSize: 16, color: Colors.white),
text: '作废',
backgroundColor: Colors.red,
onPressed: () {
_submit('-1');
},
),
),
Expanded(
child: CustomButton(
textStyle: TextStyle(fontSize: 16, color: Colors.white),
text: '通过',
backgroundColor: Colors.green,
onPressed: () {
_submit('1');
},
),
),
],
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: MyAppbar(title: '选择安全措施确认人'),
body: SafeArea(
child: SingleChildScrollView(
padding: EdgeInsets.all(12),
child: Column(
children: [
// _card(_defaultDetail()),
HighWorkDetailFormWidget(
pd: pd,
isEditable: false,
onChooseLevel: (){},
),
SizedBox(height: 20),
_setSafeDetailWidget(),
SizedBox(height: 20),
_bottomButtons(),
],
),
),
),
);
}
}
class MeasureItem {
final double id;
String DEPARTMENT_ID;
String DEPARTMENT_NAME;
String USER_ID;
String USER_NAME;
List<Map<String, dynamic>> userList;
int userIndex;
List<Map<String, dynamic>> selectMeasures;
MeasureItem({
required this.id,
this.DEPARTMENT_ID = '',
this.DEPARTMENT_NAME = '',
this.USER_ID = '',
this.USER_NAME = '',
List<Map<String, dynamic>>? userList,
this.userIndex = -1,
List<Map<String, dynamic>>? selectMeasures,
}) : userList = userList ?? [],
selectMeasures = selectMeasures ?? [];
Map<String, dynamic> toJson() {
return {
'id': id,
'DEPARTMENT_ID': DEPARTMENT_ID,
'DEPARTMENT_NAME': DEPARTMENT_NAME,
'USER_ID': USER_ID,
'USER_NAME': USER_NAME,
'userList': userList,
'userIndex': userIndex,
'selectMeasures': selectMeasures,
};
}
}

View File

@ -0,0 +1,327 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:qhd_prevention/customWidget/ItemWidgetFactory.dart';
import 'package:qhd_prevention/customWidget/custom_button.dart';
import 'package:qhd_prevention/customWidget/toast_util.dart';
import 'package:qhd_prevention/pages/home/tap/item_list_widget.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/pages/home/tap/tabList/special_wrok/dh_work/qtfx_work_detail/hotwork_gas_list.dart';
import 'package:qhd_prevention/customWidget/custom_alert_dialog.dart';
import 'package:qhd_prevention/customWidget/single_image_viewer.dart';
import 'package:qhd_prevention/pages/mine/mine_sign_page.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/SpecialWorkFormBaseWork.dart';
///
class HotworkSzdwDetail extends StatefulWidget {
const HotworkSzdwDetail({
super.key,
required this.HOTWORK_ID,
required this.flow,
});
final String HOTWORK_ID;
final String flow;
@override
State<HotworkSzdwDetail> createState() => _HotworkSzdwDetailState();
}
class _HotworkSzdwDetailState extends State<HotworkSzdwDetail> {
late bool isEditable = false;
///
late Map<String, dynamic> pd = {};
final TextEditingController _contentController = TextEditingController();
///
late List<Map<String, dynamic>> measuresList = [];
late Map<String, dynamic> signs = {};
List<String> signImages = [];
List<String> signTimes = []; //
@override
void initState() {
super.initState();
_getData();
}
///
Future<void> _sign() async {
final path = await Navigator.push(
context,
MaterialPageRoute(builder: (context) => MineSignPage()),
);
if (path != null) {
final now = DateFormat('yyyy-MM-dd HH:mm').format(DateTime.now());
setState(() {
signImages.add(path);
signTimes.add(now);
FocusHelper.clearFocus(context);
});
}
}
Widget _signListWidget() {
return Column(
children:
signImages.map((path) {
return Column(
children: [
const SizedBox(height: 10),
const Divider(),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
GestureDetector(
child: // ConstrainedBox BoxFit.contain
ConstrainedBox(
constraints: const BoxConstraints(
maxWidth: 200,
maxHeight: 150,
),
child: Image.file(
File(path),
//
fit: BoxFit.contain,
),
),
onTap: () {
presentOpaque(
SingleImageViewer(imageUrl: path),
context,
);
},
),
Column(
children: [
Container(
padding: const EdgeInsets.only(right: 5),
child: CustomButton(
text: 'X',
height: 30,
padding: const EdgeInsets.symmetric(horizontal: 10),
backgroundColor: Colors.red,
onPressed: () {
setState(() {
signImages.remove(path);
});
},
),
),
const SizedBox(height: 80),
],
),
],
),
],
);
}).toList(),
);
}
/// -1 1
Future<void> _submit(String status) async {
if (signImages.isEmpty) {
ToastUtil.showNormal(context, '请签字');
return;
}
String reasonText = '';
String DESCR = _contentController.text.trim();
if (DESCR.isEmpty) {
ToastUtil.showNormal(context, '请输入所在单位负责人意见');
return;
}
if (status == '1') {
} else {
await showDialog<String>(
context: context,
builder:
(_) => CustomAlertDialog(
title: '作废原因',
mode: DialogMode.input,
hintText: '请输入作废原因',
cancelText: '取消',
confirmText: '确定',
onInputConfirm: (text) {
reasonText = text;
},
),
);
if (reasonText.isEmpty) {
ToastUtil.showNormal(context, '请填写作废原因');
return;
}
}
// measures
final Map<String, dynamic> formData = {};
//
formData['HOTWORK_ID'] = widget.HOTWORK_ID;
formData['SIGNTIME'] = signTimes.join(',');
formData['USER_ID'] = SessionService.instance.loginUserId;
formData['APPLY_STATUS'] = status;
formData['STEP_REASON'] = reasonText;
formData['DESCR'] = DESCR;
await showDialog<String>(
context: context,
builder:
(_) => CustomAlertDialog(
title: '提示',
content: '请确认' + (status == '1' ? "通过" : "作废") + '本作业票?',
cancelText: '取消',
confirmText: '确定',
onConfirm: () async {
LoadingDialogHelper.show(context);
try {
final result = await ApiService.saveSafeFunctionSure(
'highwork',
formData,
signImages,
);
LoadingDialogHelper.hide(context);
if (result['result'] == 'success') {
ToastUtil.showSuccess(context, '保存成功');
Navigator.pop(context);
}
} catch (e) {
LoadingDialogHelper.hide(context);
ToastUtil.showNormal(context, '操作失败:$e');
}
},
),
);
}
///
Future<void> _getData() async {
final data = await ApiService.getHighHomeworkFindById(widget.HOTWORK_ID);
setState(() {
pd = data['pd'];
_getSigns(pd['HOTWORK_ID'] ?? '');
_getMeasures(pd['HOTWORK_ID'] ?? '');
});
}
Future<void> _getMeasures(String homework_id) async {
final data = await ApiService.listSignFinishMeasures('highwork',
homework_id.length > 0 ? homework_id : widget.HOTWORK_ID,
);
setState(() {
measuresList = List<Map<String, dynamic>>.from(
data['finishMeasuresList'] ?? <Map<String, dynamic>>[],
);
});
}
Future<void> _getSigns(String homework_id) async {
final data = await ApiService.listSignFinished(
homework_id.length > 0 ? homework_id : widget.HOTWORK_ID,
);
setState(() {
signs = data['signs'] ?? {};
});
}
///
Widget _bottomButtons() {
return Row(
spacing: 10,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: CustomButton(
height: 45,
textStyle: TextStyle(fontSize: 16, color: Colors.white),
text: '作废',
backgroundColor: Colors.red,
onPressed: () {
_submit('-1');
},
),
),
Expanded(
child: CustomButton(
textStyle: TextStyle(fontSize: 16, color: Colors.white),
text: '通过',
backgroundColor: Colors.green,
onPressed: () {
_submit('1');
},
),
),
],
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: MyAppbar(title: '所在单位意见'),
body: SafeArea(
child: SingleChildScrollView(
padding: EdgeInsets.all(12),
child: Column(
spacing: 12,
children: [
// _setSafeDetailWidget(),
SpecialWorkFormBaseWork(
pd: pd,
measuresList: measuresList,
signs: signs,
baseImgPath: ApiService.baseImgPath,
isEditable: false,
onChooseLevel: () {},
onChooseHotworkUser: () {},
onAnalyzeTap: () {
pushPage(
HotworkGasList(HOTWORK_ID: widget.HOTWORK_ID),
context,
);
},
),
ItemListWidget.itemContainer(
Column(
children: [
ListItemFactory.createBuildMultilineInput(
'所在单位负责人意见',
'请输入意见',
_contentController,
),
Divider(),
Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
ListItemFactory.headerTitle('所在单位负责人'),
CustomButton(
text: '新增手写签字',
height: 36,
backgroundColor: Colors.green,
onPressed: () {
_sign();
},
),
],
),
if (signImages.isNotEmpty) _signListWidget(),
],
)
],
),
),
_bottomButtons(),
],
),
),
),
);
}
}

View File

@ -0,0 +1,411 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:qhd_prevention/customWidget/ItemWidgetFactory.dart';
import 'package:qhd_prevention/customWidget/custom_button.dart';
import 'package:qhd_prevention/customWidget/toast_util.dart';
import 'package:qhd_prevention/pages/home/tap/item_list_widget.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/pages/home/tap/tabList/special_wrok/dh_work/qtfx_work_detail/hotwork_gas_list.dart';
import 'package:qhd_prevention/customWidget/custom_alert_dialog.dart';
import 'package:qhd_prevention/customWidget/single_image_viewer.dart';
import 'package:qhd_prevention/pages/mine/mine_sign_page.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/SpecialWorkFormBaseWork.dart';
import 'package:qhd_prevention/customWidget/picker/CupertinoDatePicker.dart';
import 'package:qhd_prevention/customWidget/photo_picker_row.dart';
///
class ImageData {
String localPath;
String serverPath;
ImageData({required this.localPath, required this.serverPath});
}
class HotworkYsgdDetail extends StatefulWidget {
const HotworkYsgdDetail({
super.key,
required this.HOTWORK_ID,
required this.flow,
});
final String HOTWORK_ID;
final String flow;
@override
State<HotworkYsgdDetail> createState() => _HotworkYsgdDetailState();
}
class _HotworkYsgdDetailState extends State<HotworkYsgdDetail> {
late bool isEditable = false;
///
late Map<String, dynamic> pd = {};
///
String startTime = '';
///
final TextEditingController _contentController = TextEditingController();
late List<ImageData> imgList = [];
///
late List<Map<String, dynamic>> measuresList = [];
late Map<String, dynamic> signs = {};
List<String> signImages = [];
List<String> signTimes = []; //
@override
void initState() {
super.initState();
_getData();
}
///
Future<void> _onImageAdded(String localPath) async {
//
final res = await ApiService.uploadSaveFile(localPath);
final url = res['FILE_PATH'] as String;
setState(() {
imgList.add(ImageData(localPath: localPath, serverPath: url));
});
}
///
Future<void> _onImageRemoved(ImageData item) async {
if (item.serverPath != null) {
await ApiService.deleteSaveFile(item.serverPath!);
}
setState(() {
imgList.remove(item);
});
}
///
Future<void> _sign() async {
final path = await Navigator.push(
context,
MaterialPageRoute(builder: (context) => MineSignPage()),
);
if (path != null) {
final now = DateFormat('yyyy-MM-dd HH:mm').format(DateTime.now());
setState(() {
signImages.add(path);
signTimes.add(now);
FocusHelper.clearFocus(context);
});
}
}
Widget _signListWidget() {
return Column(
children:
signImages.map((path) {
return Column(
children: [
const SizedBox(height: 10),
const Divider(),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
GestureDetector(
child: // ConstrainedBox BoxFit.contain
ConstrainedBox(
constraints: const BoxConstraints(
maxWidth: 200,
maxHeight: 150,
),
child: Image.file(
File(path),
//
fit: BoxFit.contain,
),
),
onTap: () {
presentOpaque(
SingleImageViewer(imageUrl: path),
context,
);
},
),
Column(
children: [
Container(
padding: const EdgeInsets.only(right: 5),
child: CustomButton(
text: 'X',
height: 30,
padding: const EdgeInsets.symmetric(horizontal: 10),
backgroundColor: Colors.red,
onPressed: () {
setState(() {
signImages.remove(path);
});
},
),
),
const SizedBox(height: 80),
],
),
],
),
],
);
}).toList(),
);
}
/// -1 1
Future<void> _submit(String status) async {
if (signImages.isEmpty) {
ToastUtil.showNormal(context, '请签字');
return;
}
String DESCR = _contentController.text.trim();
if (DESCR.isEmpty) {
ToastUtil.showNormal(context, '请输入负责人意见');
return;
}
String reasonText = '';
if (status == '1') {
if (startTime.isEmpty) {
ToastUtil.showNormal(context, '请选择验收时间');
return;
}
// final workStart = DateTime.parse(pd['WORK_START_DATE'] as String);
final endTime = DateTime.parse(pd['WORK_END_DATE'] as String);
final acceptTime = DateTime.parse(startTime);
final intervalMs = endTime.difference(acceptTime).inMilliseconds;
const thresholdMs = 30 * 60 * 1000;
if (intervalMs >= thresholdMs) {
ToastUtil.showNormal(context, '请在作业结束30分钟内完成验收');
return;
}
if (imgList.isNotEmpty) {
ToastUtil.showNormal(context, '请上传验收视频');
return;
}
} else {
await showDialog<String>(
context: context,
builder:
(_) => CustomAlertDialog(
title: '作废原因',
mode: DialogMode.input,
hintText: '请输入作废原因',
cancelText: '取消',
confirmText: '确定',
onInputConfirm: (text) {
reasonText = text;
},
),
);
if (reasonText.isEmpty) {
ToastUtil.showNormal(context, '请填写作废原因');
return;
}
}
final serverPathString = imgList
.map((e) => e.serverPath)
.where((s) => s.isNotEmpty)
.map((s) => s) // String? String
.join(',');
// measures
final Map<String, dynamic> formData = {};
//
formData['HOTWORK_ID'] = widget.HOTWORK_ID;
formData['SIGNTIME'] = signTimes.join(',');
formData['USER_ID'] = SessionService.instance.loginUserId;
formData['APPLY_STATUS'] = status;
formData['STEP_REASON'] = reasonText;
formData['ACCEPT_TIME'] = startTime;
formData['DESCR'] = DESCR;
formData['VIDEO_PATH'] = serverPathString;
await showDialog<String>(
context: context,
builder:
(_) => CustomAlertDialog(
title: '提示',
content: '请确认' + (status == '1' ? "通过" : "作废") + '本作业票?',
cancelText: '取消',
confirmText: '确定',
onConfirm: () async {
LoadingDialogHelper.show(context);
try {
final result = await ApiService.saveSafeFunctionSure(
'highwork',
formData,
signImages,
);
LoadingDialogHelper.hide(context);
if (result['result'] == 'success') {
ToastUtil.showSuccess(context, '保存成功');
Navigator.pop(context);
}
} catch (e) {
LoadingDialogHelper.hide(context);
ToastUtil.showNormal(context, '操作失败:$e');
}
},
),
);
}
///
Future<void> _getData() async {
final data = await ApiService.getHighHomeworkFindById(widget.HOTWORK_ID);
setState(() {
pd = data['pd'];
_getSigns(pd['HOTWORK_ID'] ?? '');
_getMeasures(pd['HOTWORK_ID'] ?? '');
});
}
Future<void> _getMeasures(String homework_id) async {
final data = await ApiService.listSignFinishMeasures('highwork',
homework_id.length > 0 ? homework_id : widget.HOTWORK_ID,
);
setState(() {
measuresList = List<Map<String, dynamic>>.from(
data['finishMeasuresList'] ?? <Map<String, dynamic>>[],
);
});
}
Future<void> _getSigns(String homework_id) async {
final data = await ApiService.listSignFinished(
homework_id.length > 0 ? homework_id : widget.HOTWORK_ID,
);
setState(() {
signs = data['signs'] ?? {};
});
}
///
Widget _bottomButtons() {
return Row(
spacing: 10,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: CustomButton(
height: 45,
textStyle: TextStyle(fontSize: 16, color: Colors.white),
text: '作废',
backgroundColor: Colors.red,
onPressed: () {
_submit('-1');
},
),
),
Expanded(
child: CustomButton(
textStyle: TextStyle(fontSize: 16, color: Colors.white),
text: '通过',
backgroundColor: Colors.green,
onPressed: () {
_submit('1');
},
),
),
],
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: MyAppbar(title: '完工验收'),
body: SafeArea(
child: SingleChildScrollView(
padding: EdgeInsets.all(12),
child: Column(
spacing: 12,
children: [
// _setSafeDetailWidget(),
SpecialWorkFormBaseWork(
pd: pd,
measuresList: measuresList,
signs: signs,
baseImgPath: ApiService.baseImgPath,
isEditable: false,
onChooseLevel: () {},
onChooseHotworkUser: () {},
onAnalyzeTap: () {
pushPage(
HotworkGasList(HOTWORK_ID: widget.HOTWORK_ID),
context,
);
},
),
ItemListWidget.itemContainer(
Column(
children: [
ListItemFactory.createBuildMultilineInput(
'完工验收',
'请输入意见',
_contentController,
),
Divider(),
GestureDetector(
child: ListItemFactory.createRowSpaceBetweenItem(leftText: '验收时间', rightText: startTime.isEmpty?'请选择':startTime, isRight: true),
onTap: () async {
DateTime? picked = await BottomDateTimePicker.showDate(context);
if (picked != null) {
setState(() {
startTime = DateFormat('yyyy-MM-dd HH:mm').format(picked);
});
FocusHelper.clearFocus(context);
}
},
),
Divider(),
RepairedPhotoSection(
title: '验收视频',
maxCount: 1,
mediaType: MediaType.video,
horizontalPadding: 0,
onChanged: (paths) {},
onMediaAdded: _onImageAdded,
onMediaRemoved: (path) {
final item = imgList.firstWhere((e) => e.localPath == path);
_onImageRemoved(item);
},
onAiIdentify: () {},
),
Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
ListItemFactory.headerTitle('验收部门负责人'),
CustomButton(
text: '新增手写签字',
height: 36,
backgroundColor: Colors.green,
onPressed: () {
_sign();
},
),
],
),
if (signImages.isNotEmpty) _signListWidget(),
],
),
],
),
),
_bottomButtons(),
],
),
),
),
);
}
}

View File

@ -0,0 +1,326 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:qhd_prevention/customWidget/ItemWidgetFactory.dart';
import 'package:qhd_prevention/customWidget/custom_button.dart';
import 'package:qhd_prevention/customWidget/toast_util.dart';
import 'package:qhd_prevention/pages/home/tap/item_list_widget.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/pages/home/tap/tabList/special_wrok/dh_work/qtfx_work_detail/hotwork_gas_list.dart';
import 'package:qhd_prevention/customWidget/custom_alert_dialog.dart';
import 'package:qhd_prevention/customWidget/single_image_viewer.dart';
import 'package:qhd_prevention/pages/mine/mine_sign_page.dart';
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/SpecialWorkFormBaseWork.dart';
///
class HotworkZyfzDetail extends StatefulWidget {
const HotworkZyfzDetail({
super.key,
required this.HOTWORK_ID,
required this.flow,
});
final String HOTWORK_ID;
final String flow;
@override
State<HotworkZyfzDetail> createState() => _HotworkZyfzDetailState();
}
class _HotworkZyfzDetailState extends State<HotworkZyfzDetail> {
late bool isEditable = false;
///
late Map<String, dynamic> pd = {};
final TextEditingController _contentController = TextEditingController();
///
late List<Map<String, dynamic>> measuresList = [];
late Map<String, dynamic> signs = {};
List<String> signImages = [];
List<String> signTimes = []; //
@override
void initState() {
super.initState();
_getData();
}
///
Future<void> _sign() async {
final path = await Navigator.push(
context,
MaterialPageRoute(builder: (context) => MineSignPage()),
);
if (path != null) {
final now = DateFormat('yyyy-MM-dd HH:mm').format(DateTime.now());
setState(() {
signImages.add(path);
signTimes.add(now);
FocusHelper.clearFocus(context);
});
}
}
Widget _signListWidget() {
return Column(
children:
signImages.map((path) {
return Column(
children: [
const SizedBox(height: 10),
const Divider(),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
GestureDetector(
child: // ConstrainedBox BoxFit.contain
ConstrainedBox(
constraints: const BoxConstraints(
maxWidth: 200,
maxHeight: 150,
),
child: Image.file(
File(path),
//
fit: BoxFit.contain,
),
),
onTap: () {
presentOpaque(
SingleImageViewer(imageUrl: path),
context,
);
},
),
Column(
children: [
Container(
padding: const EdgeInsets.only(right: 5),
child: CustomButton(
text: 'X',
height: 30,
padding: const EdgeInsets.symmetric(horizontal: 10),
backgroundColor: Colors.red,
onPressed: () {
setState(() {
signImages.remove(path);
});
},
),
),
const SizedBox(height: 80),
],
),
],
),
],
);
}).toList(),
);
}
/// -1 1
Future<void> _submit(String status) async {
if (signImages.isEmpty) {
ToastUtil.showNormal(context, '请签字');
return;
}
String reasonText = '';
String DESCR = _contentController.text.trim();
if (DESCR.isEmpty) {
ToastUtil.showNormal(context, '请输入负责人意见');
return;
}
if (status == '1') {
} else {
await showDialog<String>(
context: context,
builder:
(_) => CustomAlertDialog(
title: '作废原因',
mode: DialogMode.input,
hintText: '请输入作废原因',
cancelText: '取消',
confirmText: '确定',
onInputConfirm: (text) {
reasonText = text;
},
),
);
if (reasonText.isEmpty) {
ToastUtil.showNormal(context, '请填写作废原因');
return;
}
}
// measures
final Map<String, dynamic> formData = {};
//
formData['HOTWORK_ID'] = widget.HOTWORK_ID;
formData['SIGNTIME'] = signTimes.join(',');
formData['USER_ID'] = SessionService.instance.loginUserId;
formData['APPLY_STATUS'] = status;
formData['STEP_REASON'] = reasonText;
formData['DESCR'] = DESCR;
await showDialog<String>(
context: context,
builder:
(_) => CustomAlertDialog(
title: '提示',
content: '请确认' + (status == '1' ? "通过" : "作废") + '本作业票?',
cancelText: '取消',
confirmText: '确定',
onConfirm: () async {
LoadingDialogHelper.show(context);
try {
final result = await ApiService.saveSafeFunctionSure(
'highwork',
formData,
signImages,
);
LoadingDialogHelper.hide(context);
if (result['result'] == 'success') {
ToastUtil.showSuccess(context, '保存成功');
Navigator.pop(context);
}
} catch (e) {
LoadingDialogHelper.hide(context);
ToastUtil.showNormal(context, '操作失败:$e');
}
},
),
);
}
///
Future<void> _getData() async {
final data = await ApiService.getHighHomeworkFindById(widget.HOTWORK_ID);
setState(() {
pd = data['pd'];
_getSigns(pd['HOTWORK_ID'] ?? '');
_getMeasures(pd['HOTWORK_ID'] ?? '');
});
}
Future<void> _getMeasures(String homework_id) async {
final data = await ApiService.listSignFinishMeasures('highwork',
homework_id.length > 0 ? homework_id : widget.HOTWORK_ID,
);
setState(() {
measuresList = List<Map<String, dynamic>>.from(
data['finishMeasuresList'] ?? <Map<String, dynamic>>[],
);
});
}
Future<void> _getSigns(String homework_id) async {
final data = await ApiService.listSignFinished(
homework_id.length > 0 ? homework_id : widget.HOTWORK_ID,
);
setState(() {
signs = data['signs'] ?? {};
});
}
///
Widget _bottomButtons() {
return Row(
spacing: 10,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: CustomButton(
height: 45,
textStyle: TextStyle(fontSize: 16, color: Colors.white),
text: '作废',
backgroundColor: Colors.red,
onPressed: () {
_submit('-1');
},
),
),
Expanded(
child: CustomButton(
textStyle: TextStyle(fontSize: 16, color: Colors.white),
text: '通过',
backgroundColor: Colors.green,
onPressed: () {
_submit('1');
},
),
),
],
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: MyAppbar(title: '作业负责人意见'),
body: SafeArea(
child: SingleChildScrollView(
padding: EdgeInsets.all(12),
child: Column(
spacing: 12,
children: [
SpecialWorkFormBaseWork(
pd: pd,
measuresList: measuresList,
signs: signs,
baseImgPath: ApiService.baseImgPath,
isEditable: false,
onChooseLevel: () {},
onChooseHotworkUser: () {},
onAnalyzeTap: () {
pushPage(
HotworkGasList(HOTWORK_ID: widget.HOTWORK_ID),
context,
);
},
),
ItemListWidget.itemContainer(
Column(
children: [
ListItemFactory.createBuildMultilineInput(
'作业负责人意见',
'请输入意见',
_contentController,
),
Divider(),
Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
ListItemFactory.headerTitle('作业负责人'),
CustomButton(
text: '新增手写签字',
height: 36,
backgroundColor: Colors.green,
onPressed: () {
_sign();
},
),
],
),
if (signImages.isNotEmpty) _signListWidget(),
],
)
],
),
),
_bottomButtons(),
],
),
),
),
);
}
}

View File

@ -289,46 +289,54 @@ void presentPage(BuildContext context, Widget page) {
}
class LoadingDialogHelper {
/// loading
// context
static BuildContext? _dialogContext;
static void show(BuildContext context, {String? message}) {
showDialog(
context: context,
barrierDismissible: false,
builder: (_) => Center(
child: Container(
padding: EdgeInsets.all(20),
decoration: BoxDecoration(
color: Colors.black87,
borderRadius: BorderRadius.circular(8),
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
const CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation(Colors.white),
),
if (message != null) ...[
const SizedBox(height: 12),
Text(
message,
style: TextStyle(color: Colors.white),
builder: (dialogContext) {
// hide
_dialogContext = dialogContext;
return Center(
child: Container(
padding: EdgeInsets.all(20),
decoration: BoxDecoration(
color: Colors.black87,
borderRadius: BorderRadius.circular(8),
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
const CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation(Colors.white),
),
if (message != null) ...[
const SizedBox(height: 12),
Text(
message,
style: TextStyle(color: Colors.white),
),
],
],
],
),
),
),
),
);
},
);
}
/// loading
static void hide(BuildContext context) {
if (Navigator.canPop(context)) {
Navigator.of(context).pop();
if (_dialogContext != null && Navigator.canPop(_dialogContext!)) {
Navigator.of(_dialogContext!).pop();
_dialogContext = null;
}
}
}
/// HH:MM:SS
String secondsCount(dynamic seconds) {
// double