main
parent
137ae571e6
commit
3fd86e7ca2
|
|
@ -1228,6 +1228,110 @@ U6Hzm1ninpWeE+awIDAQAB
|
|||
},
|
||||
);
|
||||
}
|
||||
// 安全检查确认列表
|
||||
static Future<Map<String, dynamic>> getSafeCheckSureList(String INSPECTION_ID) {
|
||||
return HttpManager().request(
|
||||
basePath,
|
||||
'/app/safetyenvironmental/goShow',
|
||||
method: Method.post,
|
||||
data: {
|
||||
"INSPECTION_ID":INSPECTION_ID,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 安全检查操作
|
||||
static Future<Map<String, dynamic>> SafeCheckStartGoEditMsg(
|
||||
String imagePath,
|
||||
String msg,
|
||||
Map data
|
||||
) async {
|
||||
|
||||
Map<String, dynamic> formData = {
|
||||
...data,
|
||||
};
|
||||
if (imagePath.isNotEmpty) {
|
||||
final file = File(imagePath);
|
||||
if (!await file.exists()) {
|
||||
throw ApiException('file_not_found', '图片不存在:$imagePath');
|
||||
}
|
||||
final fileName = file.path.split(Platform.pathSeparator).last;
|
||||
formData['FFILE'] =
|
||||
await MultipartFile.fromFile(file.path, filename: fileName);
|
||||
return HttpManager().uploadFaceImage(
|
||||
baseUrl: basePath,
|
||||
path: '/app/safetyenvironmental/$msg',
|
||||
fromData: formData,
|
||||
);
|
||||
}else {
|
||||
return HttpManager().request(
|
||||
basePath,
|
||||
'/app/safetyenvironmental/$msg',
|
||||
data: formData,
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
// 安全检查核实
|
||||
static Future<Map<String, dynamic>> getSafePersonCheck(Map formData, String imagePath) async {
|
||||
final file = File(imagePath);
|
||||
if (!await file.exists()) {
|
||||
throw ApiException('file_not_found', '图片不存在:$imagePath');
|
||||
}
|
||||
final fileName = file.path
|
||||
.split(Platform.pathSeparator)
|
||||
.last;
|
||||
|
||||
return HttpManager().uploadFaceImage(
|
||||
baseUrl: basePath,
|
||||
path: '/app/safetyenvironmentalinspector/verify',
|
||||
fromData: {
|
||||
...formData,
|
||||
'FFILE': await MultipartFile.fromFile(
|
||||
file.path,
|
||||
filename: fileName
|
||||
),
|
||||
}
|
||||
);
|
||||
}
|
||||
// 安全检查确认
|
||||
static Future<Map<String, dynamic>> getSafePersonSignSure(Map formData, String imagePath) async {
|
||||
final file = File(imagePath);
|
||||
if (!await file.exists()) {
|
||||
throw ApiException('file_not_found', '图片不存在:$imagePath');
|
||||
}
|
||||
final fileName = file.path
|
||||
.split(Platform.pathSeparator)
|
||||
.last;
|
||||
|
||||
return HttpManager().uploadFaceImage(
|
||||
baseUrl: basePath,
|
||||
path: '/app/safetyenvironmentalexplain/add',
|
||||
fromData: {
|
||||
...formData,
|
||||
'FFILE': await MultipartFile.fromFile(
|
||||
file.path,
|
||||
filename: fileName
|
||||
),
|
||||
}
|
||||
);
|
||||
}
|
||||
// 安全检查隐患指派列表
|
||||
static Future<Map<String, dynamic>> getSafeCheckDangerList(String INSPECTION_ID) {
|
||||
return HttpManager().request(
|
||||
basePath,
|
||||
'/app/hidden/listForSafetyEnvironmental',
|
||||
method: Method.post,
|
||||
data: {
|
||||
"INSPECTION_ID":INSPECTION_ID,
|
||||
'INSPECTION_STATUS': '3-7',
|
||||
'tm': DateTime.now().millisecondsSinceEpoch.toString(),
|
||||
'KEYWORDS' : ''
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -285,7 +285,7 @@ class _MultiTextFieldWithTitleState extends State<MultiTextFieldWithTitle> {
|
|||
focusNode: _focusNodes[index],
|
||||
keyboardType: TextInputType.multiline,
|
||||
maxLines: 3,
|
||||
minLines: 3,
|
||||
// minLines: 3,
|
||||
style: TextStyle(fontSize: widget.fontSize),
|
||||
),
|
||||
)),
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:qhd_prevention/customWidget/toast_util.dart';
|
||||
import 'package:qhd_prevention/pages/home/SafeCheck/CheckPersonSign/safecheck_sign_detail.dart';
|
||||
import 'package:qhd_prevention/pages/home/SafeCheck/CheckPersonSure/check_person_detail.dart';
|
||||
import 'package:qhd_prevention/pages/home/SafeCheck/Start/safeCheck_start_detail.dart';
|
||||
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/dh_work_detai/hotwork_apply_detail.dart';
|
||||
import 'package:qhd_prevention/pages/my_appbar.dart';
|
||||
|
|
@ -9,17 +11,17 @@ import 'package:qhd_prevention/customWidget/custom_button.dart';
|
|||
import 'package:qhd_prevention/customWidget/search_bar_widget.dart';
|
||||
import 'package:qhd_prevention/http/ApiService.dart';
|
||||
|
||||
class SafecheckStartListPage extends StatefulWidget {
|
||||
class SafecheckSignListPage extends StatefulWidget {
|
||||
final String flow;
|
||||
|
||||
const SafecheckStartListPage({Key? key, required this.flow})
|
||||
const SafecheckSignListPage({Key? key, required this.flow})
|
||||
: super(key: key);
|
||||
|
||||
@override
|
||||
_SafecheckStartListPageState createState() => _SafecheckStartListPageState();
|
||||
_SafecheckSignListPageState createState() => _SafecheckSignListPageState();
|
||||
}
|
||||
|
||||
class _SafecheckStartListPageState extends State<SafecheckStartListPage> {
|
||||
class _SafecheckSignListPageState extends State<SafecheckSignListPage> {
|
||||
// Data and state variables
|
||||
List<dynamic> list = [];
|
||||
int currentPage = 1;
|
||||
|
|
@ -81,10 +83,11 @@ class _SafecheckStartListPageState extends State<SafecheckStartListPage> {
|
|||
try {
|
||||
final data = {
|
||||
'INSPECTION_STATUS': sindex > 0 ? stepList[sindex]['id'] : '',
|
||||
'INSPECTED_SITEUSER_ID': SessionService.instance.loginUserId,
|
||||
'KEYWORDS': searchKeywords,
|
||||
};
|
||||
final url =
|
||||
'/app/safetyenvironmental/list?showCount=-1¤tPage=$currentPage';
|
||||
'/app/safetyenvironmentalexplain/list?showCount=-1¤tPage=$currentPage';
|
||||
final response = await ApiService.getSafeCheckSearchList(data, url);
|
||||
|
||||
setState(() {
|
||||
|
|
@ -110,39 +113,10 @@ class _SafecheckStartListPageState extends State<SafecheckStartListPage> {
|
|||
_fetchData();
|
||||
}
|
||||
|
||||
/// 申请
|
||||
void _handleApply() {
|
||||
// 处理申请按钮点击逻辑
|
||||
pushPage(SafecheckStartDetail(INSPECTION_ID: '', isEdit: true), context);
|
||||
}
|
||||
|
||||
/// 打开流程图
|
||||
Future<void> _openFlowDrawer(String ID) async {
|
||||
try {
|
||||
final response = await ApiService.safeCheckFlowList(ID);
|
||||
final List<dynamic>? newFlow = response['varList'];
|
||||
if (newFlow == null || newFlow.isEmpty) {
|
||||
ToastUtil.showNormal(context, '暂无流程图数据');
|
||||
return;
|
||||
}
|
||||
|
||||
setState(() {
|
||||
flowList = List<Map<String, dynamic>>.from(newFlow);
|
||||
});
|
||||
Future.microtask(() {
|
||||
_scaffoldKey.currentState?.openEndDrawer();
|
||||
});
|
||||
} catch (e) {
|
||||
print('Error fetching flow data: $e');
|
||||
ScaffoldMessenger.of(
|
||||
context,
|
||||
).showSnackBar(SnackBar(content: Text('获取流程图失败: $e')));
|
||||
}
|
||||
}
|
||||
|
||||
void _goToDetail(Map<String, dynamic> item) async {
|
||||
|
||||
pushPage(SafecheckStartDetail(INSPECTION_ID: item['INSPECTION_ID'] ?? '', isEdit: false), context);
|
||||
await pushPage(SafecheckSignDetail(INSPECTION_ID: item['INSPECTION_ID'] ?? '', INSPECTION_INSPECTOR_ID: item['INSPECTION_INSPECTOR_ID'] ?? '',isEdit: false), context);
|
||||
|
||||
setState(() {
|
||||
_fetchData();
|
||||
|
|
@ -243,7 +217,7 @@ class _SafecheckStartListPageState extends State<SafecheckStartListPage> {
|
|||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text("检查人: ${item['INSPECTION_USER_NAME'] ?? ''}"),
|
||||
Text("检查人: ${item['INSPECTION_USER_NAME'] ?? ''}", maxLines: 5, overflow: TextOverflow.ellipsis),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
|
|
@ -274,19 +248,21 @@ class _SafecheckStartListPageState extends State<SafecheckStartListPage> {
|
|||
],
|
||||
),
|
||||
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['INSPECTION_ID']),
|
||||
),
|
||||
SizedBox(width: 1),
|
||||
],
|
||||
),
|
||||
if (item['INSPECTION_STATUS'] == '2')
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
SizedBox(),
|
||||
CustomButton(
|
||||
text: '确认',
|
||||
height: 32,
|
||||
padding: EdgeInsets.symmetric(horizontal: 12),
|
||||
margin: EdgeInsets.only(left: 0),
|
||||
backgroundColor: Colors.blue,
|
||||
onPressed: () => _goToDetail(item),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
|
@ -367,16 +343,7 @@ class _SafecheckStartListPageState extends State<SafecheckStartListPage> {
|
|||
key: _scaffoldKey,
|
||||
appBar: MyAppbar(
|
||||
title: '${widget.flow}',
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: _handleApply,
|
||||
child: const Text(
|
||||
'发起',
|
||||
style: TextStyle(color: Colors.white, fontSize: 17),
|
||||
),
|
||||
),
|
||||
|
||||
],
|
||||
actions: [],
|
||||
),
|
||||
endDrawer: Drawer(
|
||||
child: SafeArea(
|
||||
|
|
@ -0,0 +1,471 @@
|
|||
import 'dart:convert';
|
||||
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/bottom_picker.dart';
|
||||
import 'package:qhd_prevention/customWidget/custom_alert_dialog.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/dotted_border_box.dart';
|
||||
import 'package:qhd_prevention/customWidget/picker/CupertinoDatePicker.dart';
|
||||
import 'package:qhd_prevention/customWidget/single_image_viewer.dart';
|
||||
import 'package:qhd_prevention/customWidget/toast_util.dart';
|
||||
import 'package:qhd_prevention/http/ApiService.dart';
|
||||
import 'package:qhd_prevention/pages/KeyProjects/SafeCheck/custom/MultiTextFieldWithTitle.dart';
|
||||
import 'package:qhd_prevention/pages/KeyProjects/SafeCheck/custom/safeCheck_table.dart';
|
||||
import 'package:qhd_prevention/pages/KeyProjects/SafeCheck/custom/safe_drawer_page.dart';
|
||||
import 'package:qhd_prevention/pages/app/Danger_paicha/quick_report_page.dart';
|
||||
import 'package:qhd_prevention/pages/home/SafeCheck/SafeCheckFormView.dart';
|
||||
import 'package:qhd_prevention/pages/home/SafeCheck/Start/safeCheck_drawer_page.dart';
|
||||
import 'package:qhd_prevention/pages/home/tap/item_list_widget.dart';
|
||||
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/dh_work_detai/hotwork_apply_detail.dart';
|
||||
import 'package:qhd_prevention/pages/mine/mine_sign_page.dart';
|
||||
import 'package:qhd_prevention/pages/my_appbar.dart';
|
||||
import 'package:qhd_prevention/tools/tools.dart';
|
||||
|
||||
class SafecheckSignDetail extends StatefulWidget {
|
||||
const SafecheckSignDetail({
|
||||
super.key,
|
||||
required this.INSPECTION_ID,
|
||||
required this.INSPECTION_INSPECTOR_ID,
|
||||
required this.isEdit,
|
||||
});
|
||||
|
||||
final String INSPECTION_ID;
|
||||
final String INSPECTION_INSPECTOR_ID;
|
||||
final bool isEdit;
|
||||
|
||||
@override
|
||||
State<SafecheckSignDetail> createState() => _SafecheckSignDetailState();
|
||||
}
|
||||
|
||||
class _SafecheckSignDetailState extends State<SafecheckSignDetail> {
|
||||
String msg = 'add';
|
||||
bool _isEdit = false;
|
||||
bool forbidEdit = false;
|
||||
List<String> signImages = [];
|
||||
List<String> signTimes = []; // 签字时间列表
|
||||
Map<String, dynamic> inspectedForm = {};
|
||||
List<Map<String, dynamic>> inspectorRules = [
|
||||
{'name': 'INSPECTION_STATUS', 'message': '核实结果不能为空'},
|
||||
{'name': 'INSPECTION_ID', 'message': '安全检查ID不能为空'},
|
||||
{'name': 'INSPECTION_USER_ID', 'message': '检查人不能为空'},
|
||||
];
|
||||
Map<String, dynamic> form = {};
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_isEdit = widget.isEdit;
|
||||
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
_getData();
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> _getData() async {
|
||||
try {
|
||||
final result = await ApiService.getSafeCheckSureList(
|
||||
widget.INSPECTION_ID,
|
||||
);
|
||||
// 在 await 之后检查 mounted,避免页面已经被 pop 导致 setState 报错
|
||||
if (!mounted) return;
|
||||
setState(() {
|
||||
form = result['pd'] ?? {};
|
||||
inspectedForm = {
|
||||
'INSPECTION_EXPLAIN_ID': '', // 安全检查人员主键ID
|
||||
'INSPECTION_STATUS': '3',
|
||||
'INSPECTION_ID': widget.INSPECTION_ID, // 安全检查ID
|
||||
'INSPECTED_EXPLAIN': '', // 申辩内容
|
||||
'INSPECTED_EXPLAIN_FILENAME': '', // 申辩附件名称
|
||||
'INSPECTED_SITEUSER_SIGN_IMG': '', // 被检查单位现场负责人签字
|
||||
'INSPECTED_SITEUSER_SIGN_TIME': '',
|
||||
};
|
||||
List inspectorVerifyList = form['inspectorVerifyList'] ?? [];
|
||||
for (int i = 0; i < inspectorVerifyList.length; i++) {
|
||||
dynamic item = inspectorVerifyList[i];
|
||||
if (SessionService.instance.loginUserId ==
|
||||
(item['INSPECTION_USER_ID'] ?? '')) {
|
||||
forbidEdit = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (e, st) {
|
||||
print('加载单条数据失败: $e\n$st');
|
||||
if (mounted) {
|
||||
ToastUtil.showNormal(context, '加载数据失败:$e');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _openDrawer(Map<String, dynamic> hiddenForm, int index) async {
|
||||
try {
|
||||
final result = await openCustomDrawer<Map>(
|
||||
context,
|
||||
SafeCheckDrawerPage(
|
||||
initialHidden: hiddenForm,
|
||||
editType:
|
||||
_isEdit
|
||||
? (index < 0 ? SafeCheckEditType.add : SafeCheckEditType.edit)
|
||||
: SafeCheckEditType.see,
|
||||
toCheckUnitList: [],
|
||||
),
|
||||
);
|
||||
|
||||
if (result != null && mounted) {
|
||||
setState(() {
|
||||
if (index < 0) {
|
||||
// 新增
|
||||
form['hiddenList'].add(result);
|
||||
print(form);
|
||||
} else {
|
||||
// 修改
|
||||
form['hiddenList'][index] = result;
|
||||
}
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
print("打开抽屉失败: $e");
|
||||
ToastUtil.showNormal(context, "打开抽屉失败");
|
||||
}
|
||||
}
|
||||
|
||||
Future<T?> openCustomDrawer<T>(BuildContext context, Widget child) {
|
||||
return Navigator.of(context).push<T>(
|
||||
PageRouteBuilder(
|
||||
opaque: false,
|
||||
barrierDismissible: true,
|
||||
barrierColor: Colors.black54,
|
||||
pageBuilder: (_, __, ___) {
|
||||
return Align(
|
||||
alignment: Alignment.centerRight,
|
||||
child: FractionallySizedBox(
|
||||
widthFactor: 4 / 5,
|
||||
child: Material(color: Colors.white, child: child),
|
||||
),
|
||||
);
|
||||
},
|
||||
transitionsBuilder: (_, anim, __, child) {
|
||||
return SlideTransition(
|
||||
position: Tween(
|
||||
begin: const Offset(1, 0),
|
||||
end: Offset.zero,
|
||||
).animate(CurvedAnimation(parent: anim, curve: Curves.easeOut)),
|
||||
child: child,
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// 将 form['situationList'](若存在)转换为 List<String>
|
||||
List<String> _situationListToStrings() {
|
||||
final List<dynamic> cur = List<dynamic>.from(form['situationList'] ?? []);
|
||||
if (cur.isEmpty) return ['']; // 保持至少一行,和 uni-app 行为一致
|
||||
return cur.map((e) {
|
||||
if (e is Map && e['SITUATION'] != null) return e['SITUATION'].toString();
|
||||
return '';
|
||||
}).toList();
|
||||
}
|
||||
|
||||
// ------------ 提交入口 ------------
|
||||
Future<void> _submit() async {
|
||||
if (forbidEdit) {
|
||||
Navigator.of(context).pop();
|
||||
return;
|
||||
}
|
||||
for (var rule in inspectorRules) {
|
||||
if ((rule['name'] as String).isEmpty &&
|
||||
!FormUtils.hasValue(inspectedForm, rule['name'])) {
|
||||
ToastUtil.showNormal(context, rule['message']);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (inspectedForm['INSPECTION_STATUS']?.toString() == '-2' &&
|
||||
(inspectedForm['INSPECTED_EXPLAIN']?.toString().trim().isEmpty ??
|
||||
true)) {
|
||||
ToastUtil.showNormal(context, '请填写申辩说明');
|
||||
return;
|
||||
}
|
||||
|
||||
// 签字必填
|
||||
if (signImages.isEmpty) {
|
||||
ToastUtil.showNormal(context, '请签字');
|
||||
return;
|
||||
}
|
||||
|
||||
// 显示加载
|
||||
LoadingDialogHelper.show();
|
||||
|
||||
inspectedForm['CREATOR'] = SessionService.instance.loginUserId;
|
||||
inspectedForm['ACTION_USER'] = SessionService.instance.username;
|
||||
inspectedForm['CORPINFO_ID'] = SessionService.instance.corpinfoId;
|
||||
|
||||
try {
|
||||
// 准备上传文件路径(兼容多种 signImgList 存法)
|
||||
String filePath = signImages.first;
|
||||
final resp = await ApiService.getSafePersonSignSure(
|
||||
inspectedForm,
|
||||
filePath,
|
||||
);
|
||||
if (resp['result'] == 'success') {
|
||||
Navigator.of(context).pop(); // 关闭 loading
|
||||
} else {
|
||||
ToastUtil.showNormal(context, '提交失败');
|
||||
}
|
||||
LoadingDialogHelper.hide();
|
||||
} catch (e) {
|
||||
LoadingDialogHelper.hide();
|
||||
|
||||
ToastUtil.showNormal(context, '请求失败:${e.toString()}');
|
||||
}
|
||||
}
|
||||
|
||||
// ========== 罚单提交方法
|
||||
Future<bool> fnSubmit(Map<String, dynamic>? ordForm) async {
|
||||
if (ordForm == null) return false;
|
||||
|
||||
final Map<String, String> punishRules = {
|
||||
'REASON': '请填写处罚原因',
|
||||
'AMOUT': '请填写处罚金额',
|
||||
'DATE': '请选择下发处罚时间',
|
||||
};
|
||||
// 校验
|
||||
for (final entry in punishRules.entries) {
|
||||
final key = entry.key;
|
||||
final msg = entry.value;
|
||||
final val = ordForm[key];
|
||||
if (val == null || val.toString().trim().isEmpty) {
|
||||
ToastUtil.showNormal(context, msg);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
final requestData = Map<String, dynamic>.from(ordForm);
|
||||
requestData['CORPINFO_ID'] = SessionService.instance.corpinfoId ?? '';
|
||||
requestData['CREATOR'] = SessionService.instance.loginUserId ?? '';
|
||||
requestData['OPERATOR'] = SessionService.instance.loginUserId ?? '';
|
||||
|
||||
try {
|
||||
LoadingDialogHelper.show();
|
||||
final res = await ApiService.safeCheckPunishSubmit(requestData);
|
||||
LoadingDialogHelper.hide();
|
||||
if (FormUtils.hasValue(res, 'result') && res['result'] == 'success') {
|
||||
return true;
|
||||
} else {
|
||||
final msg =
|
||||
res != null
|
||||
? (res['msg'] ?? res['msaesge'] ?? res['message'] ?? '提交失败')
|
||||
: '提交失败';
|
||||
ToastUtil.showNormal(context, msg);
|
||||
return false;
|
||||
}
|
||||
} catch (e) {
|
||||
LoadingDialogHelper.hide();
|
||||
ToastUtil.showNormal(context, '罚单提交异常:$e');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// 签字
|
||||
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 = [];
|
||||
signTimes = [];
|
||||
signImages.add(path);
|
||||
signTimes.add(now);
|
||||
inspectedForm['INSPECTED_SITEUSER_SIGN_TIME'] = 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(),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _mainWidget() {
|
||||
return ListView(
|
||||
children: [
|
||||
Column(
|
||||
children: [
|
||||
SafeCheckFormView(
|
||||
form: form,
|
||||
isEdit: false,
|
||||
onHiddenShow: (item, index) {
|
||||
_openDrawer(item, index);
|
||||
},
|
||||
),
|
||||
|
||||
if (!forbidEdit)
|
||||
Column(
|
||||
children: [
|
||||
SizedBox(height: 10),
|
||||
ItemListWidget.itemContainer(
|
||||
horizontal: 0,
|
||||
Column(
|
||||
children: [
|
||||
ListItemFactory.createYesNoSection(
|
||||
title: '被检查单位现场负责人意见:',
|
||||
groupValue:
|
||||
inspectedForm['INSPECTION_STATUS'] == '3'
|
||||
? true
|
||||
: false,
|
||||
yesLabel: '同意',
|
||||
noLabel: '申辩',
|
||||
isEdit: true,
|
||||
isRequired: false,
|
||||
horizontalPadding: 3,
|
||||
verticalPadding: 0,
|
||||
onChanged: (val) {
|
||||
// 如果需要把选择写回 form,可以在这里 setState 更新 widget.form
|
||||
setState(() {
|
||||
inspectedForm['INSPECTION_STATUS'] =
|
||||
val ? '3' : '-2';
|
||||
});
|
||||
},
|
||||
),
|
||||
const Divider(),
|
||||
if (inspectedForm['INSPECTION_STATUS'] == '-2')
|
||||
Column(
|
||||
children: [
|
||||
ItemListWidget.multiLineTitleTextField(
|
||||
label: '申辩说明',
|
||||
isEditable: true,
|
||||
isRequired: false,
|
||||
hintText: '检查人意见(有异议时必填)',
|
||||
onChanged: (val) {
|
||||
inspectedForm['INSPECTED_EXPLAIN'] = val;
|
||||
},
|
||||
),
|
||||
const Divider(),
|
||||
],
|
||||
),
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: 12),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
ListItemFactory.headerTitle('签字:'),
|
||||
CustomButton(
|
||||
text: '手写签字',
|
||||
height: 36,
|
||||
backgroundColor: Colors.green,
|
||||
onPressed: _sign,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
if (signImages.isNotEmpty)
|
||||
ItemListWidget.itemContainer(
|
||||
horizontal: 0,
|
||||
Column(
|
||||
children: [
|
||||
if (signImages.isNotEmpty) _signListWidget(),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 150,
|
||||
child: CustomButton(
|
||||
text: !forbidEdit ? '提交' : '返回',
|
||||
textStyle: TextStyle(color: Colors.white, fontSize: 17),
|
||||
backgroundColor: Colors.blue,
|
||||
onPressed: _submit,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: MyAppbar(title: "安全检查确认", actions: []),
|
||||
|
||||
body: SafeArea(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 12, vertical: 12),
|
||||
child: form.isNotEmpty ? _mainWidget() : SizedBox(),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,27 +1,14 @@
|
|||
import 'dart:convert';
|
||||
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/bottom_picker.dart';
|
||||
import 'package:qhd_prevention/customWidget/custom_alert_dialog.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/dotted_border_box.dart';
|
||||
import 'package:qhd_prevention/customWidget/picker/CupertinoDatePicker.dart';
|
||||
import 'package:qhd_prevention/customWidget/single_image_viewer.dart';
|
||||
import 'package:qhd_prevention/customWidget/toast_util.dart';
|
||||
import 'package:qhd_prevention/http/ApiService.dart';
|
||||
import 'package:qhd_prevention/pages/KeyProjects/SafeCheck/custom/MultiTextFieldWithTitle.dart';
|
||||
import 'package:qhd_prevention/pages/KeyProjects/SafeCheck/custom/safeCheck_table.dart';
|
||||
import 'package:qhd_prevention/pages/KeyProjects/SafeCheck/custom/safe_drawer_page.dart';
|
||||
import 'package:qhd_prevention/pages/app/Danger_paicha/quick_report_page.dart';
|
||||
import 'package:qhd_prevention/pages/home/SafeCheck/SafeCheckFormView.dart';
|
||||
import 'package:qhd_prevention/pages/home/SafeCheck/Start/safeCheck_drawer_page.dart';
|
||||
import 'package:qhd_prevention/pages/home/tap/item_list_widget.dart';
|
||||
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/dh_work_detai/hotwork_apply_detail.dart';
|
||||
import 'package:qhd_prevention/pages/mine/mine_sign_page.dart';
|
||||
import 'package:qhd_prevention/pages/my_appbar.dart';
|
||||
import 'package:qhd_prevention/tools/tools.dart';
|
||||
|
|
@ -30,10 +17,12 @@ class CheckPersonDetail extends StatefulWidget {
|
|||
const CheckPersonDetail({
|
||||
super.key,
|
||||
required this.INSPECTION_ID,
|
||||
required this.INSPECTION_INSPECTOR_ID,
|
||||
required this.isEdit,
|
||||
});
|
||||
|
||||
final String INSPECTION_ID;
|
||||
final String INSPECTION_INSPECTOR_ID;
|
||||
final bool isEdit;
|
||||
|
||||
@override
|
||||
|
|
@ -41,15 +30,18 @@ class CheckPersonDetail extends StatefulWidget {
|
|||
}
|
||||
|
||||
class _CheckPersonDetailState extends State<CheckPersonDetail> {
|
||||
|
||||
String msg = 'add';
|
||||
bool _isEdit = false;
|
||||
|
||||
bool forbidEdit = false;
|
||||
List<String> signImages = [];
|
||||
List<String> signTimes = []; // 签字时间列表
|
||||
|
||||
Map<String, dynamic> form = {
|
||||
};
|
||||
Map<String, dynamic> inspectorForm = {};
|
||||
List<Map<String, dynamic>> inspectorRules = [
|
||||
{'name': 'INSPECTION_STATUS', 'message': '核实结果不能为空'},
|
||||
{'name': 'INSPECTION_ID', 'message': '安全检查ID不能为空'},
|
||||
{'name': 'INSPECTION_USER_ID', 'message': '检查人不能为空'},
|
||||
];
|
||||
Map<String, dynamic> form = {};
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
|
|
@ -59,7 +51,6 @@ class _CheckPersonDetailState extends State<CheckPersonDetail> {
|
|||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
_getData();
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
Future<void> _getData() async {
|
||||
|
|
@ -71,6 +62,23 @@ class _CheckPersonDetailState extends State<CheckPersonDetail> {
|
|||
if (!mounted) return;
|
||||
setState(() {
|
||||
form = result['pd'] ?? {};
|
||||
inspectorForm = {
|
||||
'INSPECTION_STATUS': '-1',
|
||||
'INSPECTION_INSPECTOR_ID':widget.INSPECTION_INSPECTOR_ID, // 安全检查人员主键ID
|
||||
'INSPECTION_ID': widget.INSPECTION_ID, // 安全检查ID
|
||||
'INSPECTION_USER_ID': SessionService.instance.loginUserId, // 检查人
|
||||
'INSPECTION_USER_OPINION': '', // 检查人意见(有异议时必填)
|
||||
'INSPECTION_USER_SIGN_IMG': '', // 检查人签字
|
||||
'INSPECTION_USER_SIGN_TIME': '', // 检查人签字时间
|
||||
};
|
||||
List inspectorVerifyList = form['inspectorVerifyList'] ?? [];
|
||||
for (int i = 0; i < inspectorVerifyList.length; i++) {
|
||||
dynamic item = inspectorVerifyList[i];
|
||||
if (SessionService.instance.loginUserId ==
|
||||
(item['INSPECTION_USER_ID'] ?? '')) {
|
||||
forbidEdit = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (e, st) {
|
||||
print('加载单条数据失败: $e\n$st');
|
||||
|
|
@ -80,7 +88,6 @@ class _CheckPersonDetailState extends State<CheckPersonDetail> {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
Future<void> _openDrawer(Map<String, dynamic> hiddenForm, int index) async {
|
||||
try {
|
||||
final result = await openCustomDrawer<Map>(
|
||||
|
|
@ -151,25 +158,56 @@ class _CheckPersonDetailState extends State<CheckPersonDetail> {
|
|||
}).toList();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// ------------ 提交入口 ------------
|
||||
Future<void> _submit() async { 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);
|
||||
});
|
||||
Future<void> _submit() async {
|
||||
if (forbidEdit) {
|
||||
Navigator.of(context).pop();
|
||||
return;
|
||||
}
|
||||
}
|
||||
for (var rule in inspectorRules) {
|
||||
if ((rule['name'] as String).isEmpty && !FormUtils.hasValue(inspectorForm, rule['name'])) {
|
||||
ToastUtil.showNormal(context, rule['message']);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (inspectorForm['INSPECTION_STATUS']?.toString() == '-1' &&
|
||||
(inspectorForm['INSPECTION_USER_OPINION']?.toString().trim().isEmpty ?? true)) {
|
||||
ToastUtil.showNormal(context, '核实结果有异议时必填');
|
||||
return;
|
||||
}
|
||||
|
||||
// 签字必填
|
||||
if (signImages.isEmpty) {
|
||||
ToastUtil.showNormal(context, '请签字');
|
||||
return;
|
||||
}
|
||||
|
||||
// 显示加载
|
||||
LoadingDialogHelper.show();
|
||||
|
||||
inspectorForm['OPERATOR'] = SessionService.instance.loginUserId;
|
||||
inspectorForm['ACTION_USER'] = SessionService.instance.username;
|
||||
|
||||
try {
|
||||
// 准备上传文件路径(兼容多种 signImgList 存法)
|
||||
String filePath = signImages.first;
|
||||
final resp = await ApiService.getSafePersonCheck(inspectorForm, filePath);
|
||||
if (resp['result'] == 'success') {
|
||||
Navigator.of(context).pop(); // 关闭 loading
|
||||
}else {
|
||||
ToastUtil.showNormal(context, '提交失败');
|
||||
}
|
||||
LoadingDialogHelper.hide();
|
||||
|
||||
|
||||
} catch (e) {
|
||||
LoadingDialogHelper.hide();
|
||||
|
||||
ToastUtil.showNormal(context, '请求失败:${e.toString()}');
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
// ========== 罚单提交方法
|
||||
|
|
@ -228,115 +266,157 @@ class _CheckPersonDetailState extends State<CheckPersonDetail> {
|
|||
final now = DateFormat('yyyy-MM-dd HH:mm').format(DateTime.now());
|
||||
|
||||
setState(() {
|
||||
signImages = [];
|
||||
signTimes = [];
|
||||
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,
|
||||
signImages.map((path) {
|
||||
return Column(
|
||||
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(
|
||||
const SizedBox(height: 10),
|
||||
const Divider(),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
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);
|
||||
});
|
||||
},
|
||||
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),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 80),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
}).toList(),
|
||||
);
|
||||
}).toList(),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _mainWidget() {
|
||||
return ListView(
|
||||
children: [
|
||||
Column(
|
||||
children: [
|
||||
SafeCheckFormView(form: form, isEdit: false, onHiddenShow: (item, index) {
|
||||
SafeCheckFormView(
|
||||
form: form,
|
||||
isEdit: false,
|
||||
onHiddenShow: (item, index) {
|
||||
_openDrawer(item, index);
|
||||
|
||||
}),
|
||||
ItemListWidget.itemContainer(
|
||||
horizontal: 0,
|
||||
Column(
|
||||
children: [
|
||||
|
||||
|
||||
|
||||
|
||||
if (signImages.isNotEmpty) _signListWidget(),
|
||||
|
||||
],
|
||||
),
|
||||
},
|
||||
),
|
||||
SizedBox(height: 20),
|
||||
|
||||
if (!forbidEdit)
|
||||
ItemListWidget.itemContainer(
|
||||
horizontal: 0,
|
||||
Column(
|
||||
children: [
|
||||
ListItemFactory.createYesNoSection(
|
||||
title: '核实结果:',
|
||||
groupValue: inspectorForm['INSPECTION_STATUS'] == '1' ? true : false,
|
||||
yesLabel: '同意',
|
||||
noLabel: '不同意',
|
||||
isEdit: true,
|
||||
isRequired: false,
|
||||
horizontalPadding: 5,
|
||||
verticalPadding: 0,
|
||||
onChanged: (val) {
|
||||
// 如果需要把选择写回 form,可以在这里 setState 更新 widget.form
|
||||
setState(() {
|
||||
inspectorForm['INSPECTION_STATUS'] = val ? '1' : '-1';
|
||||
});
|
||||
},
|
||||
),
|
||||
if (inspectorForm['INSPECTION_STATUS'] == '-1')
|
||||
Column(
|
||||
children: [
|
||||
const Divider(),
|
||||
ItemListWidget.multiLineTitleTextField(
|
||||
label: '核实意见',
|
||||
isEditable: true,
|
||||
isRequired: false,
|
||||
hintText: '检查人意见(有异议时必填)',
|
||||
onChanged: (val) {
|
||||
inspectorForm['INSPECTION_USER_OPINION'] = val;
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
const Divider(),
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: 12),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
ListItemFactory.headerTitle('签字:'),
|
||||
CustomButton(
|
||||
text: '手写签字',
|
||||
height: 36,
|
||||
backgroundColor: Colors.green,
|
||||
onPressed: _sign,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
if (signImages.isNotEmpty)
|
||||
ItemListWidget.itemContainer(
|
||||
horizontal: 0,
|
||||
Column(children: [if (signImages.isNotEmpty) _signListWidget()]),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
if (_isEdit)
|
||||
SizedBox(
|
||||
width: 150,
|
||||
child: CustomButton(
|
||||
text: '返回',
|
||||
textStyle: TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 17,
|
||||
),
|
||||
backgroundColor: Colors.black38,
|
||||
onPressed: () => Navigator.pop(context),
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
width: 150,
|
||||
child: CustomButton(
|
||||
text: _isEdit ? '提交' : '返回',
|
||||
textStyle: TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 17,
|
||||
),
|
||||
text: !forbidEdit ? '提交' : '返回',
|
||||
textStyle: TextStyle(color: Colors.white, fontSize: 17),
|
||||
backgroundColor: Colors.blue,
|
||||
onPressed: _submit,
|
||||
),
|
||||
|
|
@ -348,18 +428,16 @@ class _CheckPersonDetailState extends State<CheckPersonDetail> {
|
|||
],
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: MyAppbar(title: "安全检查发起", actions: []),
|
||||
appBar: MyAppbar(title: "安全检查确认", actions: []),
|
||||
|
||||
body: SafeArea(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 12, vertical: 12),
|
||||
child:
|
||||
form.isNotEmpty
|
||||
? _mainWidget()
|
||||
: SizedBox(),
|
||||
child: form.isNotEmpty ? _mainWidget() : SizedBox(),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
|
|
|||
|
|
@ -82,6 +82,7 @@ class _CheckPersonListPageState extends State<CheckPersonListPage> {
|
|||
try {
|
||||
final data = {
|
||||
'INSPECTION_STATUS': sindex > 0 ? stepList[sindex]['id'] : '',
|
||||
'INSPECTION_USER_ID': SessionService.instance.loginUserId,
|
||||
'KEYWORDS': searchKeywords,
|
||||
};
|
||||
final url =
|
||||
|
|
@ -111,39 +112,9 @@ class _CheckPersonListPageState extends State<CheckPersonListPage> {
|
|||
_fetchData();
|
||||
}
|
||||
|
||||
/// 申请
|
||||
void _handleApply() {
|
||||
// 处理申请按钮点击逻辑
|
||||
pushPage(SafecheckStartDetail(INSPECTION_ID: '', isEdit: true), context);
|
||||
}
|
||||
|
||||
/// 打开流程图
|
||||
Future<void> _openFlowDrawer(String ID) async {
|
||||
try {
|
||||
final response = await ApiService.safeCheckFlowList(ID);
|
||||
final List<dynamic>? newFlow = response['varList'];
|
||||
if (newFlow == null || newFlow.isEmpty) {
|
||||
ToastUtil.showNormal(context, '暂无流程图数据');
|
||||
return;
|
||||
}
|
||||
|
||||
setState(() {
|
||||
flowList = List<Map<String, dynamic>>.from(newFlow);
|
||||
});
|
||||
Future.microtask(() {
|
||||
_scaffoldKey.currentState?.openEndDrawer();
|
||||
});
|
||||
} catch (e) {
|
||||
print('Error fetching flow data: $e');
|
||||
ScaffoldMessenger.of(
|
||||
context,
|
||||
).showSnackBar(SnackBar(content: Text('获取流程图失败: $e')));
|
||||
}
|
||||
}
|
||||
|
||||
void _goToDetail(Map<String, dynamic> item) async {
|
||||
|
||||
pushPage(CheckPersonDetail(INSPECTION_ID: item['INSPECTION_ID'] ?? '', isEdit: false), context);
|
||||
await pushPage(CheckPersonDetail(INSPECTION_ID: item['INSPECTION_ID'] ?? '', INSPECTION_INSPECTOR_ID: item['INSPECTION_INSPECTOR_ID'],isEdit: false), context);
|
||||
|
||||
setState(() {
|
||||
_fetchData();
|
||||
|
|
@ -244,7 +215,7 @@ class _CheckPersonListPageState extends State<CheckPersonListPage> {
|
|||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text("检查人: ${item['INSPECTION_USER_NAME'] ?? ''}"),
|
||||
Text("检查人: ${item['INSPECTION_USER_NAME'] ?? ''}", maxLines: 5, overflow: TextOverflow.ellipsis),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
|
|
@ -370,16 +341,7 @@ class _CheckPersonListPageState extends State<CheckPersonListPage> {
|
|||
key: _scaffoldKey,
|
||||
appBar: MyAppbar(
|
||||
title: '${widget.flow}',
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: _handleApply,
|
||||
child: const Text(
|
||||
'发起',
|
||||
style: TextStyle(color: Colors.white, fontSize: 17),
|
||||
),
|
||||
),
|
||||
|
||||
],
|
||||
actions: [],
|
||||
),
|
||||
endDrawer: Drawer(
|
||||
child: SafeArea(
|
||||
|
|
|
|||
|
|
@ -0,0 +1,19 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:qhd_prevention/pages/my_appbar.dart';
|
||||
|
||||
class SafecheckAssignmentDetailPage extends StatefulWidget {
|
||||
const SafecheckAssignmentDetailPage({super.key});
|
||||
|
||||
@override
|
||||
State<SafecheckAssignmentDetailPage> createState() => _SafecheckAssignmentDetailPageState();
|
||||
}
|
||||
|
||||
class _SafecheckAssignmentDetailPageState extends State<SafecheckAssignmentDetailPage> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: MyAppbar(title: '安全检查指派'),
|
||||
body: SafeArea(child: SizedBox()),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,357 @@
|
|||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:qhd_prevention/customWidget/toast_util.dart';
|
||||
import 'package:qhd_prevention/pages/home/SafeCheck/CheckPersonSure/check_person_detail.dart';
|
||||
import 'package:qhd_prevention/pages/home/SafeCheck/Start/safeCheck_start_detail.dart';
|
||||
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/dh_work_detai/hotwork_apply_detail.dart';
|
||||
import 'package:qhd_prevention/pages/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';
|
||||
|
||||
class SafecheckAssignmentList extends StatefulWidget {
|
||||
final String INSPECTION_ID;
|
||||
|
||||
const SafecheckAssignmentList({Key? key, required this.INSPECTION_ID})
|
||||
: super(key: key);
|
||||
|
||||
@override
|
||||
_SafecheckAssignmentListState createState() => _SafecheckAssignmentListState();
|
||||
}
|
||||
|
||||
class _SafecheckAssignmentListState extends State<SafecheckAssignmentList> {
|
||||
// Data and state variables
|
||||
List<dynamic> list = [];
|
||||
int currentPage = 1;
|
||||
int rows = 10;
|
||||
int totalPage = 1;
|
||||
bool isLoading = false;
|
||||
final List<Map<String, String>> hiddenStatusList = [
|
||||
{'ID': '', 'NAME': '请选择'},
|
||||
{'ID': '1', 'NAME': '待整改'},
|
||||
{'ID': '2', 'NAME': '待验收'},
|
||||
{'ID': '3', 'NAME': '已整改'},
|
||||
{'ID': '4', 'NAME': '已验收'},
|
||||
{'ID': '5', 'NAME': '忽略隐患'},
|
||||
{'ID': '6', 'NAME': '重大隐患'},
|
||||
{'ID': '7', 'NAME': '待处理的特殊申请隐患'},
|
||||
{'ID': '8', 'NAME': '已处理的特殊隐患'},
|
||||
{'ID': '10', 'NAME': '验收打回'},
|
||||
{'ID': '11', 'NAME': '分公司安委会办公室副主任核定'},
|
||||
{'ID': '12', 'NAME': '分公司安委会办公室副主任核定'},
|
||||
{'ID': '13', 'NAME': '港股分公司安委会办公室副主任核定、重大隐患待整改'},
|
||||
{'ID': '13', 'NAME': '重大隐患待验收'},
|
||||
{'ID': '15', 'NAME': '重大隐患已归档'},
|
||||
{'ID': '16', 'NAME': '确认打回'},
|
||||
{'ID': '100','NAME': '安全检查暂存的隐患'},
|
||||
{'ID': '100','NAME': '检查已归档,待指派'},
|
||||
{'ID': '101','NAME': '待指派整改人'},
|
||||
{'ID': '-1', 'NAME': '已过期'},
|
||||
{'ID': '-2', 'NAME': '待确认'},
|
||||
];
|
||||
|
||||
List<Map<String, dynamic>> flowList = [];
|
||||
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
|
||||
|
||||
final ScrollController _scrollController = ScrollController();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_fetchData();
|
||||
_scrollController.addListener(_onScroll);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_scrollController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
void _onScroll() {
|
||||
if (_scrollController.position.pixels >=
|
||||
_scrollController.position.maxScrollExtent &&
|
||||
!isLoading) {
|
||||
if (currentPage < totalPage) {
|
||||
currentPage++;
|
||||
_fetchData();
|
||||
}
|
||||
}
|
||||
}
|
||||
String? translateHidden(String id) {
|
||||
final match = hiddenStatusList.firstWhere(
|
||||
(item) => item['ID'] == id,
|
||||
orElse: () => {},
|
||||
);
|
||||
return match['NAME']; // 如果 orElse 返回 {},这里会是 null(安全)
|
||||
}
|
||||
Future<void> _fetchData() async {
|
||||
if (isLoading) return;
|
||||
setState(() => isLoading = true);
|
||||
|
||||
try {
|
||||
|
||||
final response = await ApiService.getSafeCheckDangerList(widget.INSPECTION_ID);
|
||||
|
||||
setState(() {
|
||||
if (currentPage == 1) {
|
||||
list = response['varList'];
|
||||
} else {
|
||||
list.addAll(response['varList']);
|
||||
}
|
||||
Map<String, dynamic> page = response['page'];
|
||||
totalPage = page['totalPage'] ?? 1;
|
||||
isLoading = false;
|
||||
});
|
||||
} catch (e) {
|
||||
print('Error fetching data: $e');
|
||||
setState(() => isLoading = false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//查看
|
||||
void _goToDetail(Map<String, dynamic> item) async {
|
||||
|
||||
// await pushPage(CheckPersonDetail(INSPECTION_ID: item['INSPECTION_ID'] ?? '', INSPECTION_INSPECTOR_ID: item['INSPECTION_INSPECTOR_ID'],isEdit: false), context);
|
||||
//
|
||||
// setState(() {
|
||||
// _fetchData();
|
||||
// });
|
||||
|
||||
}
|
||||
/// 指派
|
||||
void _goToAssign(Map<String, dynamic> item) async {
|
||||
|
||||
// await pushPage(SafecheckSignDetail(INSPECTION_ID: item['INSPECTION_ID'] ?? '', INSPECTION_INSPECTOR_ID: item['INSPECTION_INSPECTOR_ID'] ?? '',isEdit: false), context);
|
||||
_fetchData();
|
||||
|
||||
|
||||
}
|
||||
/// 验收
|
||||
void _goAccept(Map<String, dynamic> item) async {
|
||||
|
||||
// await pushPage(SafecheckSignDetail(INSPECTION_ID: item['INSPECTION_ID'] ?? '', INSPECTION_INSPECTOR_ID: item['INSPECTION_INSPECTOR_ID'] ?? '',isEdit: false), context);
|
||||
_fetchData();
|
||||
|
||||
|
||||
}
|
||||
|
||||
Widget _buildFlowStepItem({
|
||||
required Map<String, dynamic> item,
|
||||
required bool isFirst,
|
||||
required bool isLast,
|
||||
}) {
|
||||
bool status = item['active'] == item['order'];
|
||||
// 依据状态设色
|
||||
final Color dotColor = status ? Colors.blue :Colors.grey;
|
||||
final Color textColor = status ? Colors.blue :Colors.black54;
|
||||
|
||||
return ListTile(
|
||||
visualDensity: VisualDensity(vertical: -4),
|
||||
|
||||
contentPadding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
leading: Container(
|
||||
width: 24,
|
||||
alignment: Alignment.center,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
children: [
|
||||
// 上方线段或占位
|
||||
isFirst
|
||||
? SizedBox(height: 6 + 5)
|
||||
: Expanded(child: Container(width: 1, color: Colors.grey[300])),
|
||||
// 圆点
|
||||
CircleAvatar(radius: 6, backgroundColor: dotColor),
|
||||
// 下方线段或占位
|
||||
isLast
|
||||
? SizedBox(height: 6 + 5)
|
||||
: Expanded(child: Container(width: 1, color: Colors.grey[300])),
|
||||
],
|
||||
),
|
||||
),
|
||||
title: Text(
|
||||
item['title'] ?? '',
|
||||
style: TextStyle(color: textColor, fontSize: 15),
|
||||
),
|
||||
subtitle: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
if (item['desc'] != null)
|
||||
Text(
|
||||
item['desc'],
|
||||
style: TextStyle(color: textColor, fontSize: 13),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Widget _buildListItem(Map<String, dynamic> item) {
|
||||
return Card(
|
||||
color: Colors.white,
|
||||
margin: const EdgeInsets.all(8.0),
|
||||
child: InkWell(
|
||||
onTap: () => _goToDetail(item),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(12.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
item['HIDDENDESCR'] ?? '',
|
||||
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text("隐患状态: ${translateHidden(item['HIDDEN_STATUS'] ?? '')}"),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text("隐患描述: ${item['HIDDENDESCR'] ?? ''}", maxLines: 5, overflow: TextOverflow.ellipsis),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
SizedBox(),
|
||||
Row(
|
||||
spacing: 5,
|
||||
children: [
|
||||
CustomButton(
|
||||
text: '查看',
|
||||
height: 32,
|
||||
padding: EdgeInsets.symmetric(horizontal: 12),
|
||||
margin: EdgeInsets.only(left: 0),
|
||||
backgroundColor: Colors.green,
|
||||
onPressed: () => _goToDetail(item),
|
||||
),
|
||||
if (item['INSPECTED_SITEUSER_ID'] == SessionService.instance.loginUserId && item['HIDDEN_STATUS'] == '101')
|
||||
CustomButton(
|
||||
text: '指派',
|
||||
height: 32,
|
||||
padding: EdgeInsets.symmetric(horizontal: 12),
|
||||
margin: EdgeInsets.only(left: 0),
|
||||
backgroundColor: Colors.blue,
|
||||
onPressed: () => _goToAssign(item),
|
||||
),
|
||||
if (item['CREATOR'] == SessionService.instance.loginUserId &&
|
||||
(item['HIDDEN_STATUS'] == '4' || item['HIDDEN_STATUS'] == '8') &&
|
||||
(item['HIDDEN_STATUS'] == '4' || item['HIDDEN_STATUS'] == '8') &&
|
||||
FormUtils.hasValue(item, 'FINAL_CHECK'))
|
||||
CustomButton(
|
||||
text: '验收',
|
||||
height: 32,
|
||||
padding: EdgeInsets.symmetric(horizontal: 12),
|
||||
margin: EdgeInsets.only(left: 0),
|
||||
backgroundColor: Colors.blue,
|
||||
onPressed: () => _goAccept(item),
|
||||
),
|
||||
],
|
||||
)
|
||||
|
||||
],
|
||||
),
|
||||
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildListContent() {
|
||||
if (isLoading && list.isEmpty) {
|
||||
// 初始加载时显示居中的加载指示器
|
||||
return Center(child: CircularProgressIndicator());
|
||||
} else if (list.isEmpty) {
|
||||
// 没有数据
|
||||
return NoDataWidget.show();
|
||||
} else {
|
||||
// 有数据或加载更多
|
||||
return ListView.builder(
|
||||
padding: EdgeInsets.zero,
|
||||
|
||||
controller: _scrollController,
|
||||
itemCount: list.length + (isLoading ? 1 : 0),
|
||||
itemBuilder: (context, index) {
|
||||
if (index >= list.length) {
|
||||
// 加载更多时在列表底部显示加载指示器
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 16.0),
|
||||
child: Center(child: CircularProgressIndicator()),
|
||||
);
|
||||
}
|
||||
return _buildListItem(list[index]);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final int lastDoneIndex = flowList.lastIndexWhere((e) => e['STATUS'] == 1);
|
||||
|
||||
return Scaffold(
|
||||
key: _scaffoldKey,
|
||||
appBar: MyAppbar(
|
||||
title: '发现问题',
|
||||
actions: [],
|
||||
),
|
||||
endDrawer: Drawer(
|
||||
child: SafeArea(
|
||||
child:
|
||||
flowList.isEmpty
|
||||
? Center(child: Text('暂无流程图数据'))
|
||||
: ListView.builder(
|
||||
padding: const EdgeInsets.symmetric(vertical: 16),
|
||||
itemCount: flowList.length + 1, // +1 用来放标题
|
||||
itemBuilder: (context, i) {
|
||||
if (i == 0) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 16,
|
||||
vertical: 8,
|
||||
),
|
||||
child: Text(
|
||||
'查看流程图',
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
final idx = i - 1;
|
||||
final item = flowList[idx];
|
||||
final bool isFirst = idx == 0;
|
||||
final bool isLast = idx == flowList.length - 1;
|
||||
|
||||
return _buildFlowStepItem(
|
||||
item: item,
|
||||
isFirst: isFirst,
|
||||
isLast: isLast,
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
body: SafeArea(child: Expanded(child: _buildListContent()),),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,9 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:qhd_prevention/customWidget/toast_util.dart';
|
||||
import 'package:qhd_prevention/pages/home/SafeCheck/CheckPersonSign/safecheck_sign_detail.dart';
|
||||
import 'package:qhd_prevention/pages/home/SafeCheck/CheckPersonSure/check_person_detail.dart';
|
||||
import 'package:qhd_prevention/pages/home/SafeCheck/DangeCheck/safeCheck_assignment_list.dart';
|
||||
import 'package:qhd_prevention/pages/home/SafeCheck/DangeCheck/safecheck_danger_detail.dart';
|
||||
import 'package:qhd_prevention/pages/home/SafeCheck/Start/safeCheck_start_detail.dart';
|
||||
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/dh_work_detai/hotwork_apply_detail.dart';
|
||||
import 'package:qhd_prevention/pages/my_appbar.dart';
|
||||
|
|
@ -9,17 +13,17 @@ import 'package:qhd_prevention/customWidget/custom_button.dart';
|
|||
import 'package:qhd_prevention/customWidget/search_bar_widget.dart';
|
||||
import 'package:qhd_prevention/http/ApiService.dart';
|
||||
|
||||
class SafecheckStartListPage extends StatefulWidget {
|
||||
class SafecheckDangerListPage extends StatefulWidget {
|
||||
final String flow;
|
||||
|
||||
const SafecheckStartListPage({Key? key, required this.flow})
|
||||
const SafecheckDangerListPage({Key? key, required this.flow})
|
||||
: super(key: key);
|
||||
|
||||
@override
|
||||
_SafecheckStartListPageState createState() => _SafecheckStartListPageState();
|
||||
_SafecheckDangerListPageState createState() => _SafecheckDangerListPageState();
|
||||
}
|
||||
|
||||
class _SafecheckStartListPageState extends State<SafecheckStartListPage> {
|
||||
class _SafecheckDangerListPageState extends State<SafecheckDangerListPage> {
|
||||
// Data and state variables
|
||||
List<dynamic> list = [];
|
||||
int currentPage = 1;
|
||||
|
|
@ -27,18 +31,14 @@ class _SafecheckStartListPageState extends State<SafecheckStartListPage> {
|
|||
int totalPage = 1;
|
||||
bool isLoading = false;
|
||||
List stepList = [
|
||||
{'id': '', 'name': '请选择'},
|
||||
{'id': '0', 'name': '待检查人核实'},
|
||||
{'id': '1', 'name': '检查人核实中'},
|
||||
{'id': '2', 'name': '待被检查人确认'},
|
||||
{'id': '3-7', 'name': '请选择'},
|
||||
{'id': '3', 'name': '待指派'},
|
||||
{'id': '4', 'name': '指派中'},
|
||||
{'id': '5', 'name': '指派完成'},
|
||||
{'id': '6', 'name': '检查待验收'},
|
||||
{'id': '7', 'name': '检查已验收'},
|
||||
{'id': '8', 'name': '已归档'},
|
||||
{'id': '-1', 'name': '检查人核实打回'},
|
||||
{'id': '-2', 'name': '被检查人申辩'},
|
||||
|
||||
];
|
||||
final TextEditingController _searchController = TextEditingController();
|
||||
|
||||
|
|
@ -81,10 +81,11 @@ class _SafecheckStartListPageState extends State<SafecheckStartListPage> {
|
|||
try {
|
||||
final data = {
|
||||
'INSPECTION_STATUS': sindex > 0 ? stepList[sindex]['id'] : '',
|
||||
'ARCHIVE_USER_ID': SessionService.instance.loginUserId,
|
||||
'KEYWORDS': searchKeywords,
|
||||
};
|
||||
final url =
|
||||
'/app/safetyenvironmental/list?showCount=-1¤tPage=$currentPage';
|
||||
'/app/safetyenvironmental/checkList?showCount=-1¤tPage=$currentPage';
|
||||
final response = await ApiService.getSafeCheckSearchList(data, url);
|
||||
|
||||
setState(() {
|
||||
|
|
@ -109,44 +110,28 @@ class _SafecheckStartListPageState extends State<SafecheckStartListPage> {
|
|||
list.clear();
|
||||
_fetchData();
|
||||
}
|
||||
|
||||
/// 申请
|
||||
void _handleApply() {
|
||||
// 处理申请按钮点击逻辑
|
||||
pushPage(SafecheckStartDetail(INSPECTION_ID: '', isEdit: true), context);
|
||||
}
|
||||
|
||||
/// 打开流程图
|
||||
Future<void> _openFlowDrawer(String ID) async {
|
||||
try {
|
||||
final response = await ApiService.safeCheckFlowList(ID);
|
||||
final List<dynamic>? newFlow = response['varList'];
|
||||
if (newFlow == null || newFlow.isEmpty) {
|
||||
ToastUtil.showNormal(context, '暂无流程图数据');
|
||||
return;
|
||||
}
|
||||
|
||||
setState(() {
|
||||
flowList = List<Map<String, dynamic>>.from(newFlow);
|
||||
});
|
||||
Future.microtask(() {
|
||||
_scaffoldKey.currentState?.openEndDrawer();
|
||||
});
|
||||
} catch (e) {
|
||||
print('Error fetching flow data: $e');
|
||||
ScaffoldMessenger.of(
|
||||
context,
|
||||
).showSnackBar(SnackBar(content: Text('获取流程图失败: $e')));
|
||||
}
|
||||
}
|
||||
|
||||
/// 查看
|
||||
void _goToDetail(Map<String, dynamic> item) async {
|
||||
|
||||
pushPage(SafecheckStartDetail(INSPECTION_ID: item['INSPECTION_ID'] ?? '', isEdit: false), context);
|
||||
await pushPage(SafecheckDangerDetail(INSPECTION_ID: item['INSPECTION_ID'] ?? '', INSPECTION_INSPECTOR_ID: item['INSPECTION_INSPECTOR_ID'] ?? '',isEdit: false), context);
|
||||
_fetchData();
|
||||
|
||||
|
||||
}
|
||||
/// 指派
|
||||
void _goToAssign(Map<String, dynamic> item) async {
|
||||
|
||||
await pushPage(SafecheckAssignmentList(INSPECTION_ID: item['INSPECTION_ID'] ?? ''), context);
|
||||
_fetchData();
|
||||
|
||||
|
||||
}
|
||||
/// 验收
|
||||
void _goAccept(Map<String, dynamic> item) async {
|
||||
|
||||
// await pushPage(SafecheckSignDetail(INSPECTION_ID: item['INSPECTION_ID'] ?? '', INSPECTION_INSPECTOR_ID: item['INSPECTION_INSPECTOR_ID'] ?? '',isEdit: false), context);
|
||||
_fetchData();
|
||||
|
||||
setState(() {
|
||||
_fetchData();
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -243,7 +228,7 @@ class _SafecheckStartListPageState extends State<SafecheckStartListPage> {
|
|||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text("检查人: ${item['INSPECTION_USER_NAME'] ?? ''}"),
|
||||
Text("检查人: ${item['INSPECTION_USER_NAME'] ?? ''}", maxLines: 5, overflow: TextOverflow.ellipsis),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
|
|
@ -274,19 +259,43 @@ class _SafecheckStartListPageState extends State<SafecheckStartListPage> {
|
|||
],
|
||||
),
|
||||
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['INSPECTION_ID']),
|
||||
),
|
||||
SizedBox(width: 1),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
SizedBox(),
|
||||
Row(
|
||||
spacing: 5,
|
||||
children: [
|
||||
CustomButton(
|
||||
text: '查看',
|
||||
height: 32,
|
||||
padding: EdgeInsets.symmetric(horizontal: 12),
|
||||
margin: EdgeInsets.only(left: 0),
|
||||
backgroundColor: Colors.green,
|
||||
onPressed: () => _goToDetail(item),
|
||||
),
|
||||
if ((item['INSPECTION_STATUS'] == '3' || item['INSPECTION_STATUS'] == '4') && item['INSPECTED_SITEUSER_ID'] == SessionService.instance.loginUserId)
|
||||
CustomButton(
|
||||
text: '指派',
|
||||
height: 32,
|
||||
padding: EdgeInsets.symmetric(horizontal: 12),
|
||||
margin: EdgeInsets.only(left: 0),
|
||||
backgroundColor: Colors.blue,
|
||||
onPressed: () => _goToAssign(item),
|
||||
),
|
||||
if ((item['INSPECTION_STATUS'] == '5' || item['INSPECTION_STATUS'] == '6' || item['INSPECTION_STATUS'] == '7') && item['checkout'].toString() == '1')
|
||||
CustomButton(
|
||||
text: '验收',
|
||||
height: 32,
|
||||
padding: EdgeInsets.symmetric(horizontal: 12),
|
||||
margin: EdgeInsets.only(left: 0),
|
||||
backgroundColor: Colors.blue,
|
||||
onPressed: () => _goAccept(item),
|
||||
),
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
|
@ -367,16 +376,7 @@ class _SafecheckStartListPageState extends State<SafecheckStartListPage> {
|
|||
key: _scaffoldKey,
|
||||
appBar: MyAppbar(
|
||||
title: '${widget.flow}',
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: _handleApply,
|
||||
child: const Text(
|
||||
'发起',
|
||||
style: TextStyle(color: Colors.white, fontSize: 17),
|
||||
),
|
||||
),
|
||||
|
||||
],
|
||||
actions: [],
|
||||
),
|
||||
endDrawer: Drawer(
|
||||
child: SafeArea(
|
||||
|
|
@ -0,0 +1,311 @@
|
|||
import 'dart:convert';
|
||||
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/bottom_picker.dart';
|
||||
import 'package:qhd_prevention/customWidget/custom_alert_dialog.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/dotted_border_box.dart';
|
||||
import 'package:qhd_prevention/customWidget/picker/CupertinoDatePicker.dart';
|
||||
import 'package:qhd_prevention/customWidget/single_image_viewer.dart';
|
||||
import 'package:qhd_prevention/customWidget/toast_util.dart';
|
||||
import 'package:qhd_prevention/http/ApiService.dart';
|
||||
import 'package:qhd_prevention/pages/KeyProjects/SafeCheck/custom/MultiTextFieldWithTitle.dart';
|
||||
import 'package:qhd_prevention/pages/KeyProjects/SafeCheck/custom/safeCheck_table.dart';
|
||||
import 'package:qhd_prevention/pages/KeyProjects/SafeCheck/custom/safe_drawer_page.dart';
|
||||
import 'package:qhd_prevention/pages/app/Danger_paicha/quick_report_page.dart';
|
||||
import 'package:qhd_prevention/pages/home/SafeCheck/SafeCheckFormView.dart';
|
||||
import 'package:qhd_prevention/pages/home/SafeCheck/Start/safeCheck_drawer_page.dart';
|
||||
import 'package:qhd_prevention/pages/home/tap/item_list_widget.dart';
|
||||
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/dh_work_detai/hotwork_apply_detail.dart';
|
||||
import 'package:qhd_prevention/pages/mine/mine_sign_page.dart';
|
||||
import 'package:qhd_prevention/pages/my_appbar.dart';
|
||||
import 'package:qhd_prevention/tools/tools.dart';
|
||||
|
||||
class SafecheckDangerDetail extends StatefulWidget {
|
||||
const SafecheckDangerDetail({
|
||||
super.key,
|
||||
required this.INSPECTION_ID,
|
||||
required this.INSPECTION_INSPECTOR_ID,
|
||||
required this.isEdit,
|
||||
});
|
||||
|
||||
final String INSPECTION_ID;
|
||||
final String INSPECTION_INSPECTOR_ID;
|
||||
final bool isEdit;
|
||||
|
||||
@override
|
||||
State<SafecheckDangerDetail> createState() => _SafecheckDangerDetailState();
|
||||
}
|
||||
|
||||
class _SafecheckDangerDetailState extends State<SafecheckDangerDetail> {
|
||||
String msg = 'add';
|
||||
bool _isEdit = false;
|
||||
List<String> signImages = [];
|
||||
List<String> signTimes = []; // 签字时间列表
|
||||
Map<String, dynamic> inspectedForm = {};
|
||||
List<Map<String, dynamic>> inspectorRules = [
|
||||
{'name': 'INSPECTION_STATUS', 'message': '核实结果不能为空'},
|
||||
{'name': 'INSPECTION_ID', 'message': '安全检查ID不能为空'},
|
||||
{'name': 'INSPECTION_USER_ID', 'message': '检查人不能为空'},
|
||||
];
|
||||
Map<String, dynamic> form = {};
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_isEdit = widget.isEdit;
|
||||
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
_getData();
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> _getData() async {
|
||||
try {
|
||||
final result = await ApiService.getSafeCheckSureList(
|
||||
widget.INSPECTION_ID,
|
||||
);
|
||||
// 在 await 之后检查 mounted,避免页面已经被 pop 导致 setState 报错
|
||||
if (!mounted) return;
|
||||
setState(() {
|
||||
form = result['pd'] ?? {};
|
||||
inspectedForm = {
|
||||
'INSPECTION_EXPLAIN_ID': '', // 安全检查人员主键ID
|
||||
'INSPECTION_STATUS': '3',
|
||||
'INSPECTION_ID': widget.INSPECTION_ID, // 安全检查ID
|
||||
'INSPECTED_EXPLAIN': '', // 申辩内容
|
||||
'INSPECTED_EXPLAIN_FILENAME': '', // 申辩附件名称
|
||||
'INSPECTED_SITEUSER_SIGN_IMG': '', // 被检查单位现场负责人签字
|
||||
'INSPECTED_SITEUSER_SIGN_TIME': '',
|
||||
};
|
||||
|
||||
});
|
||||
} catch (e, st) {
|
||||
print('加载单条数据失败: $e\n$st');
|
||||
if (mounted) {
|
||||
ToastUtil.showNormal(context, '加载数据失败:$e');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _openDrawer(Map<String, dynamic> hiddenForm, int index) async {
|
||||
try {
|
||||
final result = await openCustomDrawer<Map>(
|
||||
context,
|
||||
SafeCheckDrawerPage(
|
||||
initialHidden: hiddenForm,
|
||||
editType:
|
||||
_isEdit
|
||||
? (index < 0 ? SafeCheckEditType.add : SafeCheckEditType.edit)
|
||||
: SafeCheckEditType.see,
|
||||
toCheckUnitList: [],
|
||||
),
|
||||
);
|
||||
|
||||
if (result != null && mounted) {
|
||||
setState(() {
|
||||
if (index < 0) {
|
||||
// 新增
|
||||
form['hiddenList'].add(result);
|
||||
print(form);
|
||||
} else {
|
||||
// 修改
|
||||
form['hiddenList'][index] = result;
|
||||
}
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
print("打开抽屉失败: $e");
|
||||
ToastUtil.showNormal(context, "打开抽屉失败");
|
||||
}
|
||||
}
|
||||
|
||||
Future<T?> openCustomDrawer<T>(BuildContext context, Widget child) {
|
||||
return Navigator.of(context).push<T>(
|
||||
PageRouteBuilder(
|
||||
opaque: false,
|
||||
barrierDismissible: true,
|
||||
barrierColor: Colors.black54,
|
||||
pageBuilder: (_, __, ___) {
|
||||
return Align(
|
||||
alignment: Alignment.centerRight,
|
||||
child: FractionallySizedBox(
|
||||
widthFactor: 4 / 5,
|
||||
child: Material(color: Colors.white, child: child),
|
||||
),
|
||||
);
|
||||
},
|
||||
transitionsBuilder: (_, anim, __, child) {
|
||||
return SlideTransition(
|
||||
position: Tween(
|
||||
begin: const Offset(1, 0),
|
||||
end: Offset.zero,
|
||||
).animate(CurvedAnimation(parent: anim, curve: Curves.easeOut)),
|
||||
child: child,
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// 将 form['situationList'](若存在)转换为 List<String>
|
||||
List<String> _situationListToStrings() {
|
||||
final List<dynamic> cur = List<dynamic>.from(form['situationList'] ?? []);
|
||||
if (cur.isEmpty) return ['']; // 保持至少一行,和 uni-app 行为一致
|
||||
return cur.map((e) {
|
||||
if (e is Map && e['SITUATION'] != null) return e['SITUATION'].toString();
|
||||
return '';
|
||||
}).toList();
|
||||
}
|
||||
|
||||
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(),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _mainWidget() {
|
||||
return ListView(
|
||||
children: [
|
||||
Column(
|
||||
children: [
|
||||
SafeCheckFormView(
|
||||
form: form,
|
||||
isEdit: false,
|
||||
onHiddenShow: (item, index) {
|
||||
_openDrawer(item, index);
|
||||
},
|
||||
),
|
||||
|
||||
Column(
|
||||
children: [
|
||||
SizedBox(height: 10),
|
||||
ItemListWidget.itemContainer(
|
||||
horizontal: 0,
|
||||
Column(
|
||||
children: [
|
||||
ItemListWidget.singleLineTitleText(
|
||||
label: '被检查单位现场负责人意见:',
|
||||
isEditable: false,
|
||||
text: FormUtils.hasValue(form, 'INSPECTED_EXPLAIN') ? '申辩' : '同意',
|
||||
),
|
||||
const Divider(),
|
||||
if (FormUtils.hasValue(form, 'INSPECTED_EXPLAIN'))
|
||||
Column(
|
||||
children: [
|
||||
ItemListWidget.multiLineTitleTextField(
|
||||
label: '申辩说明',
|
||||
isEditable: false,
|
||||
text: form['INSPECTED_EXPLAIN'] ?? '',
|
||||
),
|
||||
const Divider(),
|
||||
|
||||
],
|
||||
),
|
||||
ItemListWidget.OneRowImageTitle(
|
||||
label: '被检查单位现场负责人签字',
|
||||
text: form['INSPECTED_SITEUSER_SIGN_TIME'],
|
||||
onTapCallBack: (path) {
|
||||
presentOpaque(SingleImageViewer(imageUrl: path), context);
|
||||
},
|
||||
imgPath: form['INSPECTED_SITEUSER_SIGN_IMG'],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 150,
|
||||
child: CustomButton(
|
||||
text: '返回',
|
||||
textStyle: TextStyle(color: Colors.white, fontSize: 17),
|
||||
backgroundColor: Colors.blue,
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: MyAppbar(title: "安全检查详情", actions: []),
|
||||
|
||||
body: SafeArea(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 12, vertical: 12),
|
||||
child: form.isNotEmpty ? _mainWidget() : SizedBox(),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,473 +0,0 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:qhd_prevention/customWidget/toast_util.dart';
|
||||
import 'package:qhd_prevention/pages/home/SafeCheck/Start/safeCheck_start_detail.dart';
|
||||
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/dh_work_detai/hotwork_apply_detail.dart';
|
||||
import 'package:qhd_prevention/pages/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';
|
||||
|
||||
class SafecheckStartListPage extends StatefulWidget {
|
||||
final String flow;
|
||||
|
||||
const SafecheckStartListPage({Key? key, required this.flow})
|
||||
: super(key: key);
|
||||
|
||||
@override
|
||||
_SafecheckStartListPageState createState() => _SafecheckStartListPageState();
|
||||
}
|
||||
|
||||
class _SafecheckStartListPageState extends State<SafecheckStartListPage> {
|
||||
// Data and state variables
|
||||
List<dynamic> list = [];
|
||||
int currentPage = 1;
|
||||
int rows = 10;
|
||||
int totalPage = 1;
|
||||
bool isLoading = false;
|
||||
List stepList = [
|
||||
{'id': '', 'name': '请选择'},
|
||||
{'id': '0', 'name': '待检查人核实'},
|
||||
{'id': '1', 'name': '检查人核实中'},
|
||||
{'id': '2', 'name': '待被检查人确认'},
|
||||
{'id': '3', 'name': '待指派'},
|
||||
{'id': '4', 'name': '指派中'},
|
||||
{'id': '5', 'name': '指派完成'},
|
||||
{'id': '6', 'name': '检查待验收'},
|
||||
{'id': '7', 'name': '检查已验收'},
|
||||
{'id': '8', 'name': '已归档'},
|
||||
{'id': '-1', 'name': '检查人核实打回'},
|
||||
{'id': '-2', 'name': '被检查人申辩'},
|
||||
];
|
||||
final TextEditingController _searchController = TextEditingController();
|
||||
|
||||
int sindex = 0;
|
||||
String searchKeywords = '';
|
||||
|
||||
List<Map<String, dynamic>> flowList = [];
|
||||
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
|
||||
|
||||
final ScrollController _scrollController = ScrollController();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_fetchData();
|
||||
_scrollController.addListener(_onScroll);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_scrollController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
void _onScroll() {
|
||||
if (_scrollController.position.pixels >=
|
||||
_scrollController.position.maxScrollExtent &&
|
||||
!isLoading) {
|
||||
if (currentPage < totalPage) {
|
||||
currentPage++;
|
||||
_fetchData();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _fetchData() async {
|
||||
if (isLoading) return;
|
||||
setState(() => isLoading = true);
|
||||
|
||||
try {
|
||||
final data = {
|
||||
'INSPECTION_STATUS': sindex > 0 ? stepList[sindex]['id'] : '',
|
||||
'KEYWORDS': searchKeywords,
|
||||
};
|
||||
final url =
|
||||
'/app/safetyenvironmental/list?showCount=-1¤tPage=$currentPage';
|
||||
final response = await ApiService.getSafeCheckSearchList(data, url);
|
||||
|
||||
setState(() {
|
||||
if (currentPage == 1) {
|
||||
list = response['varList'];
|
||||
} else {
|
||||
list.addAll(response['varList']);
|
||||
}
|
||||
Map<String, dynamic> page = response['page'];
|
||||
totalPage = page['totalPage'] ?? 1;
|
||||
isLoading = false;
|
||||
});
|
||||
} catch (e) {
|
||||
print('Error fetching data: $e');
|
||||
setState(() => isLoading = false);
|
||||
}
|
||||
}
|
||||
|
||||
void _search() {
|
||||
searchKeywords = _searchController.text.trim();
|
||||
currentPage = 1;
|
||||
list.clear();
|
||||
_fetchData();
|
||||
}
|
||||
|
||||
/// 申请
|
||||
void _handleApply() {
|
||||
// 处理申请按钮点击逻辑
|
||||
pushPage(SafecheckStartDetail(INSPECTION_ID: '', isEdit: true), context);
|
||||
}
|
||||
|
||||
/// 打开流程图
|
||||
Future<void> _openFlowDrawer(String ID) async {
|
||||
try {
|
||||
final response = await ApiService.safeCheckFlowList(ID);
|
||||
final List<dynamic>? newFlow = response['varList'];
|
||||
if (newFlow == null || newFlow.isEmpty) {
|
||||
ToastUtil.showNormal(context, '暂无流程图数据');
|
||||
return;
|
||||
}
|
||||
|
||||
setState(() {
|
||||
flowList = List<Map<String, dynamic>>.from(newFlow);
|
||||
});
|
||||
Future.microtask(() {
|
||||
_scaffoldKey.currentState?.openEndDrawer();
|
||||
});
|
||||
} catch (e) {
|
||||
print('Error fetching flow data: $e');
|
||||
ScaffoldMessenger.of(
|
||||
context,
|
||||
).showSnackBar(SnackBar(content: Text('获取流程图失败: $e')));
|
||||
}
|
||||
}
|
||||
|
||||
void _goToDetail(Map<String, dynamic> item) async {
|
||||
|
||||
pushPage(SafecheckStartDetail(INSPECTION_ID: item['INSPECTION_ID'] ?? '', isEdit: false), context);
|
||||
|
||||
setState(() {
|
||||
_fetchData();
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
Widget _buildFlowStepItem({
|
||||
required Map<String, dynamic> item,
|
||||
required bool isFirst,
|
||||
required bool isLast,
|
||||
}) {
|
||||
bool status = item['active'] == item['order'];
|
||||
// 依据状态设色
|
||||
final Color dotColor = status ? Colors.blue :Colors.grey;
|
||||
final Color textColor = status ? Colors.blue :Colors.black54;
|
||||
|
||||
return ListTile(
|
||||
visualDensity: VisualDensity(vertical: -4),
|
||||
|
||||
contentPadding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
leading: Container(
|
||||
width: 24,
|
||||
alignment: Alignment.center,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
children: [
|
||||
// 上方线段或占位
|
||||
isFirst
|
||||
? SizedBox(height: 6 + 5)
|
||||
: Expanded(child: Container(width: 1, color: Colors.grey[300])),
|
||||
// 圆点
|
||||
CircleAvatar(radius: 6, backgroundColor: dotColor),
|
||||
// 下方线段或占位
|
||||
isLast
|
||||
? SizedBox(height: 6 + 5)
|
||||
: Expanded(child: Container(width: 1, color: Colors.grey[300])),
|
||||
],
|
||||
),
|
||||
),
|
||||
title: Text(
|
||||
item['title'] ?? '',
|
||||
style: TextStyle(color: textColor, fontSize: 15),
|
||||
),
|
||||
subtitle: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
if (item['desc'] != null)
|
||||
Text(
|
||||
item['desc'],
|
||||
style: TextStyle(color: textColor, fontSize: 13),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
String _checkStatusWithId(String id) {
|
||||
for (Map item in stepList) {
|
||||
if (item['id'] == id) {
|
||||
return item['name'];
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
Widget _buildListItem(Map<String, dynamic> item) {
|
||||
return Card(
|
||||
color: Colors.white,
|
||||
margin: const EdgeInsets.all(8.0),
|
||||
child: InkWell(
|
||||
onTap: () => _goToDetail(item),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(12.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
"安全检查记录",
|
||||
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
"检查状态: ${_checkStatusWithId(item['INSPECTION_STATUS'].toString())}",
|
||||
),
|
||||
Text("检查类型: ${item['INSPECTION_TYPE_NAME'] ?? ''}"),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text("检查人: ${item['INSPECTION_USER_NAME'] ?? ''}"),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
"检查发起人: ${item['INSPECTION_ORIGINATOR_NAME'] ?? ''}",
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text("被检查人: ${item['INSPECTED_SITEUSER_NAME'] ?? ''}"),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
"检查时间: ${item['INSPECTION_TIME_START'] ?? ''}至${item['INSPECTION_TIME_END'] ?? ''}",
|
||||
),
|
||||
],
|
||||
),
|
||||
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['INSPECTION_ID']),
|
||||
),
|
||||
SizedBox(width: 1),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// 显示底部选择器
|
||||
Future<void> _showStepPicker() async {
|
||||
if (stepList.isEmpty) {
|
||||
ScaffoldMessenger.of(
|
||||
context,
|
||||
).showSnackBar(SnackBar(content: Text('正在加载步骤数据,请稍后...')));
|
||||
if (stepList.isEmpty) {
|
||||
ScaffoldMessenger.of(
|
||||
context,
|
||||
).showSnackBar(SnackBar(content: Text('无法加载步骤数据')));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 创建选项列表
|
||||
final options = stepList.map((e) => e['name'] as String).toList();
|
||||
|
||||
// 显示底部选择器
|
||||
final choice = await BottomPicker.show<String>(
|
||||
context,
|
||||
items: options,
|
||||
itemBuilder: (item) => Text(item, textAlign: TextAlign.center),
|
||||
initialIndex: sindex,
|
||||
);
|
||||
|
||||
if (choice != null) {
|
||||
// 找到选择的索引
|
||||
final newIndex = options.indexOf(choice);
|
||||
if (newIndex != -1) {
|
||||
setState(() {
|
||||
sindex = newIndex;
|
||||
});
|
||||
_search();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Widget _buildListContent() {
|
||||
if (isLoading && list.isEmpty) {
|
||||
// 初始加载时显示居中的加载指示器
|
||||
return Center(child: CircularProgressIndicator());
|
||||
} else if (list.isEmpty) {
|
||||
// 没有数据
|
||||
return NoDataWidget.show();
|
||||
} else {
|
||||
// 有数据或加载更多
|
||||
return ListView.builder(
|
||||
padding: EdgeInsets.zero,
|
||||
|
||||
controller: _scrollController,
|
||||
itemCount: list.length + (isLoading ? 1 : 0),
|
||||
itemBuilder: (context, index) {
|
||||
if (index >= list.length) {
|
||||
// 加载更多时在列表底部显示加载指示器
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 16.0),
|
||||
child: Center(child: CircularProgressIndicator()),
|
||||
);
|
||||
}
|
||||
return _buildListItem(list[index]);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final int lastDoneIndex = flowList.lastIndexWhere((e) => e['STATUS'] == 1);
|
||||
|
||||
return Scaffold(
|
||||
key: _scaffoldKey,
|
||||
appBar: MyAppbar(
|
||||
title: '${widget.flow}',
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: _handleApply,
|
||||
child: const Text(
|
||||
'发起',
|
||||
style: TextStyle(color: Colors.white, fontSize: 17),
|
||||
),
|
||||
),
|
||||
|
||||
],
|
||||
),
|
||||
endDrawer: Drawer(
|
||||
child: SafeArea(
|
||||
child:
|
||||
flowList.isEmpty
|
||||
? Center(child: Text('暂无流程图数据'))
|
||||
: ListView.builder(
|
||||
padding: const EdgeInsets.symmetric(vertical: 16),
|
||||
itemCount: flowList.length + 1, // +1 用来放标题
|
||||
itemBuilder: (context, i) {
|
||||
if (i == 0) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 16,
|
||||
vertical: 8,
|
||||
),
|
||||
child: Text(
|
||||
'查看流程图',
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
final idx = i - 1;
|
||||
final item = flowList[idx];
|
||||
final bool isFirst = idx == 0;
|
||||
final bool isLast = idx == flowList.length - 1;
|
||||
|
||||
return _buildFlowStepItem(
|
||||
item: item,
|
||||
isFirst: isFirst,
|
||||
isLast: isLast,
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
body: SafeArea(child: Column(
|
||||
children: [
|
||||
// Filter bar
|
||||
Container(
|
||||
color: Colors.white,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 5, vertical: 8),
|
||||
child: Row(
|
||||
children: [
|
||||
// 底部弹窗选择器
|
||||
SizedBox(
|
||||
width: 65,
|
||||
child: TextButton(
|
||||
onPressed: _showStepPicker,
|
||||
style: TextButton.styleFrom(
|
||||
padding: EdgeInsets.symmetric(
|
||||
vertical: 12,
|
||||
horizontal: 5,
|
||||
),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
'筛选',
|
||||
style: TextStyle(color: Colors.black87, fontSize: 16),
|
||||
),
|
||||
Icon(Icons.arrow_drop_down, color: Colors.grey),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: SearchBarWidget(
|
||||
showResetButton: false,
|
||||
hintText: "请输入关键字",
|
||||
// isClickableOnly: true,
|
||||
onSearch: (text) {
|
||||
_search();
|
||||
},
|
||||
controller: _searchController,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const Divider(height: 1),
|
||||
// List
|
||||
Expanded(child: _buildListContent()),
|
||||
],
|
||||
)),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -5,10 +5,12 @@ import 'package:qhd_prevention/customWidget/ItemWidgetFactory.dart';
|
|||
import 'package:qhd_prevention/customWidget/custom_alert_dialog.dart';
|
||||
import 'package:qhd_prevention/customWidget/custom_button.dart';
|
||||
import 'package:qhd_prevention/customWidget/dotted_border_box.dart';
|
||||
import 'package:qhd_prevention/customWidget/single_image_viewer.dart';
|
||||
import 'package:qhd_prevention/http/ApiService.dart';
|
||||
import 'package:qhd_prevention/pages/KeyProjects/SafeCheck/custom/MultiTextFieldWithTitle.dart';
|
||||
import 'package:qhd_prevention/pages/KeyProjects/SafeCheck/custom/safeCheck_table.dart';
|
||||
import 'package:qhd_prevention/pages/home/tap/item_list_widget.dart';
|
||||
import 'package:qhd_prevention/tools/tools.dart';
|
||||
|
||||
class SafeCheckFormView extends StatefulWidget {
|
||||
const SafeCheckFormView({
|
||||
|
|
@ -32,7 +34,9 @@ class SafeCheckFormView extends StatefulWidget {
|
|||
class _SafeCheckFormViewState extends State<SafeCheckFormView> {
|
||||
/// 将 widget.form['situationList'] 转为 MultiTextFieldWithTitle 需要的 List<String>
|
||||
List<String> _situationListToStrings() {
|
||||
final List<dynamic> cur = List<dynamic>.from(widget.form['situationList'] ?? []);
|
||||
final List<dynamic> cur = List<dynamic>.from(
|
||||
widget.form['situationList'] ?? [],
|
||||
);
|
||||
if (cur.isEmpty) return ['']; // 保持至少一行,和 uni-app 行为一致
|
||||
return cur.map((e) {
|
||||
if (e is Map && e['SITUATION'] != null) return e['SITUATION'].toString();
|
||||
|
|
@ -40,11 +44,12 @@ class _SafeCheckFormViewState extends State<SafeCheckFormView> {
|
|||
return '';
|
||||
}).toList();
|
||||
}
|
||||
|
||||
Widget _personUnitItem(Map item, int index) {
|
||||
return Stack(
|
||||
children: [
|
||||
Container(
|
||||
padding: EdgeInsets.all(5),
|
||||
padding: EdgeInsets.symmetric(vertical: 5),
|
||||
child: DottedBorderBox(
|
||||
child: SizedBox(
|
||||
child: Column(
|
||||
|
|
@ -57,7 +62,6 @@ class _SafeCheckFormViewState extends State<SafeCheckFormView> {
|
|||
setState(() {});
|
||||
},
|
||||
text: item['INSPECTION_DEPARTMENT_NAME'] ?? '请选择',
|
||||
|
||||
),
|
||||
Divider(),
|
||||
ItemListWidget.selectableLineTitleTextRightButton(
|
||||
|
|
@ -65,166 +69,209 @@ class _SafeCheckFormViewState extends State<SafeCheckFormView> {
|
|||
label: '${index + 1}.检查人员:',
|
||||
isEditable: false,
|
||||
text: item['INSPECTION_USER_NAME'] ?? '请选择',
|
||||
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
],
|
||||
);
|
||||
// 删除按钮(叠加在左上角)
|
||||
}
|
||||
|
||||
Widget _checkItem(Map item, int index) {
|
||||
return Column(
|
||||
children: [
|
||||
const SizedBox(height: 10),
|
||||
ItemListWidget.singleLineTitleText(
|
||||
label: '检查人员核查结果:',
|
||||
isEditable: false,
|
||||
text: '',
|
||||
),
|
||||
const Divider(),
|
||||
ItemListWidget.multiLineTitleTextField(
|
||||
label: '检查人意见',
|
||||
isEditable: false,
|
||||
text: item['INSPECTION_USER_OPINION'] ?? '',
|
||||
),
|
||||
const Divider(),
|
||||
ItemListWidget.OneRowImageTitle(
|
||||
label: '检查人签字',
|
||||
text: item['INSPECTION_USER_SIGN_TIME'],
|
||||
onTapCallBack: (path) {
|
||||
presentOpaque(SingleImageViewer(imageUrl: path), context);
|
||||
},
|
||||
imgPath: item['INSPECTION_USER_SIGN_IMG'],
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final form = widget.form;
|
||||
final isEdit = widget.isEdit;
|
||||
List<dynamic> inspectorList = widget.form['inspectorList'];
|
||||
List<dynamic> inspectorList = widget.form['inspectorList'] ?? [];
|
||||
List<dynamic> inspectorVerifyList =
|
||||
widget.form['inspectorVerifyList'] ?? widget.form['inspectorList'];
|
||||
|
||||
return SizedBox(
|
||||
// padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 12),
|
||||
child:
|
||||
Column(
|
||||
children: [
|
||||
// 顶部表单区容器
|
||||
ItemListWidget.itemContainer(
|
||||
Column(
|
||||
children: [
|
||||
// 检查题目选择(示例复用你项目的 ListItemFactory)
|
||||
ListItemFactory.createYesNoSection(
|
||||
title: '检查题目:',
|
||||
groupValue: (form['INSPECTION_CATEGORY']?.toString() ?? '').toLowerCase() == '安全'
|
||||
? true
|
||||
: (form['INSPECTION_CATEGORY']?.toString() ?? '').toLowerCase() == '综合'
|
||||
? false
|
||||
: null,
|
||||
yesLabel: '安全',
|
||||
noLabel: '综合',
|
||||
isEdit: isEdit,
|
||||
isRequired: true,
|
||||
horizontalPadding: 5,
|
||||
verticalPadding: 0,
|
||||
text:'${form['INSPECTION_SUBJECT'] ?? ''}现场检查记录',
|
||||
child: Column(
|
||||
children: [
|
||||
// 顶部表单区容器
|
||||
ItemListWidget.itemContainer(
|
||||
horizontal: 0,
|
||||
Column(
|
||||
children: [
|
||||
// 检查题目选择(示例复用你项目的 ListItemFactory)
|
||||
ListItemFactory.createYesNoSection(
|
||||
title: '检查题目:',
|
||||
groupValue:
|
||||
(form['INSPECTION_CATEGORY']?.toString() ?? '')
|
||||
.toLowerCase() ==
|
||||
'安全'
|
||||
? true
|
||||
: (form['INSPECTION_CATEGORY']?.toString() ?? '')
|
||||
.toLowerCase() ==
|
||||
'综合'
|
||||
? false
|
||||
: null,
|
||||
yesLabel: '安全',
|
||||
noLabel: '综合',
|
||||
isEdit: isEdit,
|
||||
isRequired: true,
|
||||
horizontalPadding: 5,
|
||||
verticalPadding: 0,
|
||||
text: '${form['INSPECTION_SUBJECT'] ?? ''}现场检查记录',
|
||||
|
||||
onChanged: (val) {
|
||||
// 如果需要把选择写回 form,可以在这里 setState 更新 widget.form
|
||||
// setState(() { widget.form['INSPECTION_CATEGORY'] = val ? '安全' : '综合'; });
|
||||
},
|
||||
onChanged: (val) {
|
||||
// 如果需要把选择写回 form,可以在这里 setState 更新 widget.form
|
||||
// setState(() { widget.form['INSPECTION_CATEGORY'] = val ? '安全' : '综合'; });
|
||||
},
|
||||
),
|
||||
|
||||
const Divider(),
|
||||
ItemListWidget.singleLineTitleText(
|
||||
label: '被检查单位:',
|
||||
isEditable: false,
|
||||
text: form['INSPECTED_DEPARTMENT_NAMES'] ?? '',
|
||||
),
|
||||
const Divider(),
|
||||
|
||||
ItemListWidget.selectableLineTitleTextRightButton(
|
||||
label: '被检查单位现场负责人:',
|
||||
isEditable: isEdit,
|
||||
text: form['INSPECTED_SITEUSER_NAME'] ?? '',
|
||||
),
|
||||
const Divider(),
|
||||
|
||||
ItemListWidget.singleLineTitleText(
|
||||
label: '检查场所:',
|
||||
isEditable: isEdit,
|
||||
text: form['INSPECTION_PLACE'],
|
||||
hintText: '请输入检查场所',
|
||||
onChanged: (val) {
|
||||
// 可选择写回 form
|
||||
// setState(() { widget.form['INSPECTION_PLACE'] = val; });
|
||||
},
|
||||
),
|
||||
const Divider(),
|
||||
|
||||
ItemListWidget.selectableLineTitleTextRightButton(
|
||||
label: '检查类型:',
|
||||
isEditable: isEdit,
|
||||
text: form['INSPECTION_TYPE_NAME'] ?? '',
|
||||
),
|
||||
const Divider(),
|
||||
|
||||
ItemListWidget.selectableLineTitleTextRightButton(
|
||||
label: '检查开始时间:',
|
||||
isEditable: isEdit,
|
||||
text: form['INSPECTION_TIME_START'] ?? '',
|
||||
onTap: () {},
|
||||
),
|
||||
const Divider(),
|
||||
|
||||
ItemListWidget.selectableLineTitleTextRightButton(
|
||||
label: '检查结束时间:',
|
||||
isEditable: isEdit,
|
||||
text: form['INSPECTION_TIME_END'] ?? '',
|
||||
onTap: () {},
|
||||
),
|
||||
|
||||
const Divider(),
|
||||
|
||||
// MultiTextFieldWithTitle(检查情况),外部通过 onMultiTextsChanged 更新 form['situationList']
|
||||
MultiTextFieldWithTitle(
|
||||
label: "检查情况",
|
||||
isEditable: isEdit,
|
||||
hintText: "请输入检查情况...",
|
||||
texts: _situationListToStrings(),
|
||||
onTextsChanged: (val) {},
|
||||
),
|
||||
|
||||
const Divider(),
|
||||
|
||||
ItemListWidget.itemContainer(
|
||||
Column(
|
||||
children: [
|
||||
ListItemFactory.headerTitle('检查人员'),
|
||||
SizedBox(height: 5),
|
||||
ListView.builder(
|
||||
shrinkWrap: true,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
itemCount: inspectorList.length,
|
||||
itemBuilder: (context, index) {
|
||||
return _personUnitItem(inspectorList[index], index);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
const Divider(),
|
||||
ItemListWidget.singleLineTitleText(
|
||||
label: '被检查单位:',
|
||||
isEditable: false,
|
||||
text: form['INSPECTED_DEPARTMENT_NAMES'] ??'',
|
||||
const Divider(),
|
||||
|
||||
ItemListWidget.itemContainer(
|
||||
horizontal: 12,
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [ListItemFactory.headerTitle('发现问题')],
|
||||
),
|
||||
const Divider(),
|
||||
),
|
||||
|
||||
ItemListWidget.selectableLineTitleTextRightButton(
|
||||
label: '被检查单位现场负责人:',
|
||||
isEditable: isEdit,
|
||||
text: form['INSPECTED_SITEUSER_NAME'] ?? '',
|
||||
),
|
||||
const Divider(),
|
||||
|
||||
ItemListWidget.singleLineTitleText(
|
||||
label: '检查场所:',
|
||||
isEditable: isEdit,
|
||||
text: form['INSPECTION_PLACE'],
|
||||
hintText: '请输入检查场所',
|
||||
onChanged: (val) {
|
||||
// 可选择写回 form
|
||||
// setState(() { widget.form['INSPECTION_PLACE'] = val; });
|
||||
},
|
||||
),
|
||||
const Divider(),
|
||||
|
||||
ItemListWidget.selectableLineTitleTextRightButton(
|
||||
label: '检查类型:',
|
||||
isEditable: isEdit,
|
||||
text: form['INSPECTION_TYPE_NAME'] ?? '',
|
||||
),
|
||||
const Divider(),
|
||||
|
||||
ItemListWidget.selectableLineTitleTextRightButton(
|
||||
label: '检查开始时间:',
|
||||
isEditable: isEdit,
|
||||
text: form['INSPECTION_TIME_START'] ?? '',
|
||||
onTap: () {
|
||||
},
|
||||
),
|
||||
const Divider(),
|
||||
|
||||
ItemListWidget.selectableLineTitleTextRightButton(
|
||||
label: '检查结束时间:',
|
||||
isEditable: isEdit,
|
||||
text: form['INSPECTION_TIME_END'] ?? '',
|
||||
onTap: () {
|
||||
},
|
||||
),
|
||||
|
||||
const Divider(),
|
||||
|
||||
// MultiTextFieldWithTitle(检查情况),外部通过 onMultiTextsChanged 更新 form['situationList']
|
||||
MultiTextFieldWithTitle(
|
||||
label: "检查情况",
|
||||
isEditable: isEdit,
|
||||
hintText: "请输入检查情况...",
|
||||
texts: _situationListToStrings(),
|
||||
onTextsChanged: (val) {
|
||||
},
|
||||
),
|
||||
|
||||
const Divider(),
|
||||
|
||||
ListItemFactory.headerTitle('检查人员'),
|
||||
SizedBox(height: 10),
|
||||
ListView.builder(
|
||||
shrinkWrap: true,
|
||||
physics:
|
||||
const NeverScrollableScrollPhysics(),
|
||||
itemCount: inspectorList.length,
|
||||
itemBuilder: (context, index) {
|
||||
return _personUnitItem(
|
||||
inspectorList[index],
|
||||
index,
|
||||
);
|
||||
},
|
||||
),
|
||||
const Divider(),
|
||||
|
||||
ItemListWidget.itemContainer(
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
ListItemFactory.headerTitle('发现问题'),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
// HiddenListTable:隐患列表展示(外部通过 onHiddenShow/onHiddenRemove 处理具体交互)
|
||||
HiddenListTable(
|
||||
hiddenList: (form['hiddenList'] as List<dynamic>?) ?? [],
|
||||
forbidEdit: false,
|
||||
baseImgPath: ApiService.baseImgPath,
|
||||
personSignImg: '',
|
||||
personSignTime: '',
|
||||
showHidden: widget.onHiddenShow,
|
||||
removeHidden: (item, index){},
|
||||
context: context,
|
||||
),
|
||||
|
||||
],
|
||||
),
|
||||
// HiddenListTable:隐患列表展示(外部通过 onHiddenShow/onHiddenRemove 处理具体交互)
|
||||
HiddenListTable(
|
||||
hiddenList: (form['hiddenList'] as List<dynamic>?) ?? [],
|
||||
forbidEdit: false,
|
||||
baseImgPath: ApiService.baseImgPath,
|
||||
personSignImg: '',
|
||||
personSignTime: '',
|
||||
showHidden: widget.onHiddenShow,
|
||||
removeHidden: (item, index) {},
|
||||
context: context,
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
const SizedBox(height: 20),
|
||||
],
|
||||
),
|
||||
|
||||
),
|
||||
SizedBox(height: 10,),
|
||||
ItemListWidget.itemContainer(
|
||||
horizontal: 0,
|
||||
inspectorVerifyList.isNotEmpty
|
||||
? ListView.builder(
|
||||
padding: EdgeInsets.symmetric(horizontal: 0),
|
||||
itemCount: inspectorVerifyList.length,
|
||||
shrinkWrap: true,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
itemBuilder: (context, index) {
|
||||
return _checkItem(inspectorVerifyList[index], index);
|
||||
},
|
||||
)
|
||||
: SizedBox(),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,48 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:qhd_prevention/customWidget/toast_util.dart';
|
||||
import 'package:qhd_prevention/http/ApiService.dart';
|
||||
import 'package:qhd_prevention/pages/home/tap/item_list_widget.dart';
|
||||
import 'package:qhd_prevention/pages/my_appbar.dart';
|
||||
|
||||
class SafecheckDefendSetPage extends StatefulWidget {
|
||||
const SafecheckDefendSetPage({super.key, required this.INSPECTION_ID});
|
||||
final String INSPECTION_ID;
|
||||
|
||||
@override
|
||||
State<SafecheckDefendSetPage> createState() => _SafecheckDefendSetPageState();
|
||||
}
|
||||
|
||||
class _SafecheckDefendSetPageState extends State<SafecheckDefendSetPage> {
|
||||
|
||||
late Map<String, dynamic> form = {};
|
||||
|
||||
Future<void> _getData() async {
|
||||
try {
|
||||
final result = await ApiService.getSafeCheckStartGoEdit(
|
||||
widget.INSPECTION_ID,
|
||||
);
|
||||
// 在 await 之后检查 mounted,避免页面已经被 pop 导致 setState 报错
|
||||
if (!mounted) return;
|
||||
setState(() {
|
||||
form = result['pd'] ?? {};
|
||||
|
||||
});
|
||||
} catch (e, st) {
|
||||
print('加载单条数据失败: $e\n$st');
|
||||
if (mounted) {
|
||||
ToastUtil.showNormal(context, '加载数据失败:$e');
|
||||
}
|
||||
}
|
||||
}
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: MyAppbar(title: '申辩处理'),
|
||||
body: SafeArea(child: Padding(
|
||||
padding: EdgeInsets.all(12),
|
||||
child: ItemListWidget.itemContainer(Column(children: [
|
||||
|
||||
],)))),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -352,7 +352,7 @@ class _SafeCheckDrawerPageState extends State<SafeCheckDrawerPage> {
|
|||
Expanded(
|
||||
child: CustomButton(
|
||||
onPressed: cancelHidden,
|
||||
text: '取消',
|
||||
text: '返回',
|
||||
textStyle: TextStyle(color: Colors.black87),
|
||||
backgroundColor: Colors.grey.shade300,
|
||||
),
|
||||
|
|
|
|||
|
|
@ -29,11 +29,11 @@ class SafecheckStartDetail extends StatefulWidget {
|
|||
const SafecheckStartDetail({
|
||||
super.key,
|
||||
required this.INSPECTION_ID,
|
||||
required this.isEdit,
|
||||
required this.type,
|
||||
});
|
||||
|
||||
final String INSPECTION_ID;
|
||||
final bool isEdit;
|
||||
final String type;
|
||||
|
||||
@override
|
||||
State<SafecheckStartDetail> createState() => _SafecheckStartDetailState();
|
||||
|
|
@ -42,9 +42,11 @@ class SafecheckStartDetail extends StatefulWidget {
|
|||
class _SafecheckStartDetailState extends State<SafecheckStartDetail> {
|
||||
|
||||
String msg = 'add';
|
||||
bool _isEdit = false;
|
||||
bool _isEdit = false; // 禁止修改
|
||||
/// 被检查单位负责人
|
||||
late List<dynamic> personList = [];
|
||||
/// 打回信息
|
||||
late List<dynamic> inspectorVerifyList = [];
|
||||
|
||||
/// 检查类型
|
||||
late List<dynamic> typeList = [];
|
||||
|
|
@ -96,11 +98,15 @@ class _SafecheckStartDetailState extends State<SafecheckStartDetail> {
|
|||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_isEdit = widget.isEdit;
|
||||
form['INSPECTION_ID'] = widget.INSPECTION_ID;
|
||||
form['hiddenList'] = [];
|
||||
if (widget.INSPECTION_ID.isNotEmpty) {
|
||||
msg = 'edit';
|
||||
}else{
|
||||
_isEdit = true;
|
||||
}
|
||||
if (widget.type == 'look') {
|
||||
_isEdit = false;
|
||||
}
|
||||
if (_isEdit) {
|
||||
inspectorList.add({
|
||||
|
|
@ -133,7 +139,12 @@ class _SafecheckStartDetailState extends State<SafecheckStartDetail> {
|
|||
FormUtils.hasValue(form, 'inspectorList')
|
||||
? form['inspectorList']
|
||||
: [];
|
||||
if (FormUtils.hasValue(form, 'INSPECTION_STATUS') && int.parse(form['INSPECTION_STATUS']) < 1) {
|
||||
inspectorVerifyList =
|
||||
FormUtils.hasValue(form, 'inspectorVerifyList')
|
||||
? form['inspectorVerifyList']
|
||||
: [];
|
||||
|
||||
if (FormUtils.hasValue(form, 'INSPECTION_STATUS') && int.parse(form['INSPECTION_STATUS']) < 1 && widget.type != 'look') {
|
||||
_isEdit = true;
|
||||
}
|
||||
chooseTitleType = form['INSPECTION_SUBJECT'] == '安全' ? true : false;
|
||||
|
|
@ -693,20 +704,43 @@ class _SafecheckStartDetailState extends State<SafecheckStartDetail> {
|
|||
children: [
|
||||
ItemListWidget.multiLineTitleTextField(
|
||||
label: '检查人意见:',
|
||||
isEditable: _isEdit,
|
||||
isEditable: false,
|
||||
text: item['opinion'],
|
||||
hintText: '请输入作业负责人意见',
|
||||
),
|
||||
const Divider(),
|
||||
|
||||
ItemListWidget.OneRowImageTitle(
|
||||
label: '检查人签字',
|
||||
text: item['time'],
|
||||
text: item['time'] ?? '',
|
||||
onTapCallBack: (path) {
|
||||
presentOpaque(SingleImageViewer(imageUrl: path), context);
|
||||
},
|
||||
imgPath: item['img'],
|
||||
imgPath: item['img'] ?? '',
|
||||
),
|
||||
const Divider(),
|
||||
Column(
|
||||
children: [
|
||||
if (form['INSPECTION_STATUS'] == '3')
|
||||
|
||||
ItemListWidget.multiLineTitleTextField(
|
||||
label: '被检查单位现场负责人意见:',
|
||||
isEditable: false,
|
||||
text: item['INSPECTED_EXPLAIN'],
|
||||
),
|
||||
if (FormUtils.hasValue(form, 'INSPECTED_EXPLAIN'))
|
||||
ItemListWidget.multiLineTitleTextField(label: '申辩说明', isEditable: false,text: form['INSPECTED_EXPLAIN'] ?? ''),
|
||||
if (form['INSPECTION_STATUS'] == '3')
|
||||
ItemListWidget.OneRowImageTitle(
|
||||
label: '检查人签字',
|
||||
text: form['INSPECTED_SITEUSER_SIGN_TIME'],
|
||||
onTapCallBack: (path) {
|
||||
presentOpaque(SingleImageViewer(imageUrl: path), context);
|
||||
},
|
||||
imgPath: item['INSPECTED_SITEUSER_SIGN_IMG'],
|
||||
),
|
||||
|
||||
],
|
||||
)
|
||||
|
||||
],
|
||||
),
|
||||
);
|
||||
|
|
@ -1113,35 +1147,53 @@ class _SafecheckStartDetailState extends State<SafecheckStartDetail> {
|
|||
},
|
||||
context: context,
|
||||
),
|
||||
if (_isEdit)
|
||||
ItemListWidget.multiLineTitleTextField(
|
||||
label: '核实意见',
|
||||
isEditable: _isEdit,
|
||||
isRequired: false,
|
||||
hintText: '检查人意见',
|
||||
onChanged: (val) {
|
||||
form['INSPECTION_USER_OPINION'] = val;
|
||||
},
|
||||
text: form['INSPECTION_USER_OPINION'] ?? '',
|
||||
),
|
||||
if (form['INSPECTION_USER_OPINION'].toString().isNotEmpty && _isEdit)
|
||||
ItemListWidget.itemContainer(Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
if (widget.type == 'look' && inspectorVerifyList.isNotEmpty)
|
||||
/// TODO ——————————————————————————————————————————————
|
||||
/// TODO ——————————————————————————————————————————————
|
||||
/// TODO ——————————————————————————————————————————————
|
||||
/// TODO ——————————————————————————————————————————————
|
||||
/// TODO ——————————————————————————————————————————————
|
||||
/// TODO ——————————————————————————————————————————————
|
||||
/// TODO ——————————————————————————————————————————————
|
||||
/// TODO ——————————————————————————————————————————————
|
||||
/// TODO ——————————————————————————————————————————————
|
||||
/// TODO ——————————————————————————————————————————————
|
||||
/// TODO ——————————————————————————————————————————————
|
||||
/// TODO ——————————————————————————————————————————————
|
||||
|
||||
if (_isEdit && widget.type != 'detail')
|
||||
Column(
|
||||
children: [
|
||||
ListItemFactory.headerTitle('签字'),
|
||||
CustomButton(
|
||||
text: '手写签字',
|
||||
height: 36,
|
||||
backgroundColor: Colors.green,
|
||||
onPressed: () {
|
||||
_sign();
|
||||
ItemListWidget.multiLineTitleTextField(
|
||||
label: '核实意见',
|
||||
isEditable: _isEdit,
|
||||
isRequired: false,
|
||||
hintText: '检查人意见',
|
||||
onChanged: (val) {
|
||||
form['INSPECTION_USER_OPINION'] = val;
|
||||
},
|
||||
text: form['INSPECTION_USER_OPINION'] ?? '',
|
||||
),
|
||||
if (form['INSPECTION_USER_OPINION'].toString().isNotEmpty && _isEdit)
|
||||
ItemListWidget.itemContainer(Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
ListItemFactory.headerTitle('签字'),
|
||||
CustomButton(
|
||||
text: '手写签字',
|
||||
height: 36,
|
||||
backgroundColor: Colors.green,
|
||||
onPressed: () {
|
||||
_sign();
|
||||
},
|
||||
),
|
||||
],
|
||||
),),
|
||||
],
|
||||
),),
|
||||
),
|
||||
if (signImages.isNotEmpty) _signListWidget(),
|
||||
|
||||
if (!_isEdit)
|
||||
if (widget.type == 'detail')
|
||||
Column(
|
||||
children: [
|
||||
const Divider(),
|
||||
|
|
@ -1150,7 +1202,7 @@ class _SafecheckStartDetailState extends State<SafecheckStartDetail> {
|
|||
children: [
|
||||
ItemListWidget.selectableLineTitleTextRightButton(
|
||||
label: '检查人员核实结果',
|
||||
isEditable: _isEdit,
|
||||
isEditable: false,
|
||||
text: ' ',
|
||||
),
|
||||
SizedBox(height: 5,),
|
||||
|
|
@ -1178,31 +1230,33 @@ class _SafecheckStartDetailState extends State<SafecheckStartDetail> {
|
|||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
if (_isEdit)
|
||||
SizedBox(
|
||||
width: 150,
|
||||
child: CustomButton(
|
||||
text: '返回',
|
||||
textStyle: TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 17,
|
||||
),
|
||||
backgroundColor: Colors.black38,
|
||||
onPressed: () => Navigator.pop(context),
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
if (_isEdit) ...[SizedBox(
|
||||
width: 150,
|
||||
child: CustomButton(
|
||||
text: _isEdit ? '提交' : '返回',
|
||||
text: '提交',
|
||||
textStyle: TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 17,
|
||||
),
|
||||
backgroundColor: Colors.blue,
|
||||
onPressed: _submit,
|
||||
onPressed: () => Navigator.pop(context),
|
||||
),
|
||||
),
|
||||
),]else...[
|
||||
SizedBox(
|
||||
width: 150,
|
||||
child: CustomButton(
|
||||
text:'返回',
|
||||
textStyle: TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 17,
|
||||
),
|
||||
backgroundColor: Colors.blue,
|
||||
onPressed: _submit,
|
||||
),
|
||||
),
|
||||
]
|
||||
|
||||
|
||||
],
|
||||
),
|
||||
],
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:qhd_prevention/customWidget/toast_util.dart';
|
||||
import 'package:qhd_prevention/pages/home/SafeCheck/Start/safeCheck_defend_set_page.dart';
|
||||
import 'package:qhd_prevention/pages/home/SafeCheck/Start/safeCheck_start_detail.dart';
|
||||
import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/dh_work_detai/hotwork_apply_detail.dart';
|
||||
import 'package:qhd_prevention/pages/my_appbar.dart';
|
||||
|
|
@ -113,7 +114,7 @@ class _SafecheckStartListPageState extends State<SafecheckStartListPage> {
|
|||
/// 申请
|
||||
void _handleApply() {
|
||||
// 处理申请按钮点击逻辑
|
||||
pushPage(SafecheckStartDetail(INSPECTION_ID: '', isEdit: true), context);
|
||||
pushPage(SafecheckStartDetail(INSPECTION_ID: '', type: 'add',), context);
|
||||
}
|
||||
|
||||
/// 打开流程图
|
||||
|
|
@ -140,9 +141,9 @@ class _SafecheckStartListPageState extends State<SafecheckStartListPage> {
|
|||
}
|
||||
}
|
||||
|
||||
void _goToDetail(Map<String, dynamic> item) async {
|
||||
void _goToDetail(Map<String, dynamic> item, String type) async {
|
||||
|
||||
pushPage(SafecheckStartDetail(INSPECTION_ID: item['INSPECTION_ID'] ?? '', isEdit: false), context);
|
||||
pushPage(SafecheckStartDetail(INSPECTION_ID: item['INSPECTION_ID'] ?? '', type: type), context);
|
||||
|
||||
setState(() {
|
||||
_fetchData();
|
||||
|
|
@ -154,11 +155,15 @@ class _SafecheckStartListPageState extends State<SafecheckStartListPage> {
|
|||
required Map<String, dynamic> item,
|
||||
required bool isFirst,
|
||||
required bool isLast,
|
||||
required int status, // 1 = 完成, 0 = 进行中, -1 = 未到达
|
||||
}) {
|
||||
bool status = item['active'] == item['order'];
|
||||
// 依据状态设色
|
||||
final Color dotColor = status ? Colors.blue :Colors.grey;
|
||||
final Color textColor = status ? Colors.blue :Colors.black54;
|
||||
final Color dotColor =
|
||||
status == 1 ? Colors.blue : (status == 0 ? Colors.blue : Colors.grey);
|
||||
final Color textColor =
|
||||
status == 1
|
||||
? Colors.blue
|
||||
: (status == 0 ? Colors.blue : Colors.black54);
|
||||
|
||||
return ListTile(
|
||||
visualDensity: VisualDensity(vertical: -4),
|
||||
|
|
@ -208,13 +213,19 @@ class _SafecheckStartListPageState extends State<SafecheckStartListPage> {
|
|||
}
|
||||
return '';
|
||||
}
|
||||
void _goToDefend(Map<String, dynamic> item) async {
|
||||
|
||||
await pushPage(SafecheckDefendSetPage(INSPECTION_ID: item['INSPECTION_ID'] ?? ''), context);
|
||||
_fetchData();
|
||||
|
||||
|
||||
}
|
||||
Widget _buildListItem(Map<String, dynamic> item) {
|
||||
return Card(
|
||||
color: Colors.white,
|
||||
margin: const EdgeInsets.all(8.0),
|
||||
child: InkWell(
|
||||
onTap: () => _goToDetail(item),
|
||||
onTap: () => _goToDetail(item, 'detail'),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(12.0),
|
||||
child: Column(
|
||||
|
|
@ -275,6 +286,8 @@ class _SafecheckStartListPageState extends State<SafecheckStartListPage> {
|
|||
),
|
||||
const SizedBox(height: 8),
|
||||
Row(
|
||||
spacing: 5,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
CustomButton(
|
||||
text: '流程图',
|
||||
|
|
@ -284,7 +297,41 @@ class _SafecheckStartListPageState extends State<SafecheckStartListPage> {
|
|||
backgroundColor: Colors.blue,
|
||||
onPressed: () => _openFlowDrawer(item['INSPECTION_ID']),
|
||||
),
|
||||
SizedBox(width: 1),
|
||||
if (item['INSPECTION_STATUS'] == '0' ||
|
||||
item['INSPECTION_STATUS'] == '-1'||
|
||||
item['INSPECTION_STATUS'] == '-2')
|
||||
Row(
|
||||
spacing: 5,
|
||||
children: [
|
||||
if (item['INSPECTION_STATUS'] == '-1')
|
||||
CustomButton(
|
||||
text: '编辑',
|
||||
height: 35,
|
||||
padding: EdgeInsets.symmetric(horizontal: 12),
|
||||
margin: EdgeInsets.only(left: 0),
|
||||
backgroundColor: Colors.green,
|
||||
onPressed: () => _goToDetail(item, 'edit'),
|
||||
),
|
||||
if (item['INSPECTION_STATUS'] == '-1')
|
||||
CustomButton(
|
||||
text: '查看',
|
||||
height: 35,
|
||||
padding: EdgeInsets.symmetric(horizontal: 12),
|
||||
margin: EdgeInsets.only(left: 0),
|
||||
backgroundColor: Colors.green,
|
||||
onPressed: () => _goToDetail(item, 'look'),
|
||||
),
|
||||
if (item['INSPECTION_STATUS'] == '-2' && item['INSPECTION_ORIGINATOR_ID'] == SessionService.instance.loginUserId)
|
||||
CustomButton(
|
||||
text: '申辩处理',
|
||||
height: 35,
|
||||
padding: EdgeInsets.symmetric(horizontal: 12),
|
||||
margin: EdgeInsets.only(left: 0),
|
||||
backgroundColor: Colors.green,
|
||||
onPressed: () => _goToDefend(item),
|
||||
),
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
],
|
||||
|
|
@ -407,10 +454,14 @@ class _SafecheckStartListPageState extends State<SafecheckStartListPage> {
|
|||
final bool isFirst = idx == 0;
|
||||
final bool isLast = idx == flowList.length - 1;
|
||||
|
||||
// 根据 lastDoneIndex 自动计算“进行中”
|
||||
final int status = item['active'] == '1' ? 1 : -1;
|
||||
|
||||
return _buildFlowStepItem(
|
||||
item: item,
|
||||
isFirst: isFirst,
|
||||
isLast: isLast,
|
||||
status: status,
|
||||
);
|
||||
},
|
||||
),
|
||||
|
|
|
|||
|
|
@ -4,7 +4,9 @@ import 'package:qhd_prevention/http/ApiService.dart';
|
|||
import 'package:qhd_prevention/pages/KeyProjects/Danger/danger_list_page.dart';
|
||||
import 'package:qhd_prevention/pages/KeyProjects/KeyProject/keyProject_list_page.dart';
|
||||
import 'package:qhd_prevention/pages/KeyProjects/SafeCheck/safeCheck_list_page.dart';
|
||||
import 'package:qhd_prevention/pages/home/SafeCheck/CheckPersonSign/safeCheck_sign_list_page.dart';
|
||||
import 'package:qhd_prevention/pages/home/SafeCheck/CheckPersonSure/check_person_list_page.dart';
|
||||
import 'package:qhd_prevention/pages/home/SafeCheck/DangeCheck/safeCheck_danger_list_page.dart';
|
||||
import 'package:qhd_prevention/pages/home/SafeCheck/Start/safeCheck_start_list_page.dart';
|
||||
import 'package:qhd_prevention/pages/home/tap/tabList/work_tab_icon_grid.dart';
|
||||
import 'package:qhd_prevention/pages/my_appbar.dart';
|
||||
|
|
@ -106,10 +108,14 @@ class _SafecheckTabListState extends State<SafecheckTabList> {
|
|||
} break;
|
||||
case 2: {
|
||||
title = '安全检查确认';
|
||||
// await pushPage(DangerListPage(flow: title), context);
|
||||
await pushPage(SafecheckSignListPage(flow: title), context);
|
||||
|
||||
} break;
|
||||
case 3: {
|
||||
title = '隐患指派及验收';
|
||||
await pushPage(SafecheckDangerListPage(flow: title), context);
|
||||
|
||||
} break;
|
||||
case 3: title = '隐患指派及验收'; break;
|
||||
case 4: title = '申辩记录'; break;
|
||||
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ class ItemListWidget {
|
|||
keyboardType: keyboardType,
|
||||
style: TextStyle(fontSize: fontSize),
|
||||
maxLines: 1,
|
||||
|
||||
decoration: InputDecoration(
|
||||
isDense: true,
|
||||
hintText: hintText,
|
||||
|
|
@ -65,11 +66,13 @@ class ItemListWidget {
|
|||
),
|
||||
),
|
||||
)
|
||||
: Text(
|
||||
text ?? '',
|
||||
style: TextStyle(fontSize: fontSize, color: detailtextColor),
|
||||
overflow: TextOverflow.ellipsis, // 超出省略
|
||||
),
|
||||
: Expanded(child: Text(
|
||||
text ?? '',
|
||||
maxLines: 5,
|
||||
style: TextStyle(fontSize: fontSize, color: detailtextColor),
|
||||
textAlign: TextAlign.right,
|
||||
overflow: TextOverflow.ellipsis, // 超出省略
|
||||
)),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
|
|
|||
308
pubspec.lock
308
pubspec.lock
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue