危险作业修改

master
hs 2026-04-13 08:59:45 +08:00
parent ecd2fb5591
commit 17d395cd58
53 changed files with 2296 additions and 1873 deletions

View File

@ -665,32 +665,36 @@ class ItemListWidget {
/// +
///
static Widget twoRowButtonTitleText({
required String label, //
required bool isEditable, //
bool isInput = true, //
required String text, //
TextEditingController? controller, //
required VoidCallback? onTap, //
required String label,
required bool isEditable,
bool isInput = true,
required String text, // controller使
TextEditingController? controller, // 使
required VoidCallback? onTap,
String buttonText = '选择其他',
required String hintText,
double fontSize = 14, //
double row2Height = 80, //
double fontSize = 14,
double row2Height = 80,
bool isRequired = true,
ValueChanged<String>? onChanged, //
}) {
// controller
final effectiveController = controller ?? TextEditingController(text: text);
// controller text
// text controller controller.text
// text controller
return Container(
padding: const EdgeInsets.symmetric(
vertical: vertical_inset,
horizontal: horizontal_inset,
),
padding: const EdgeInsets.symmetric(vertical: vertical_inset, horizontal: horizontal_inset),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// +
InkWell(
child: Row(
children: [
Flexible(
fit: FlexFit.loose, // loose
fit: FlexFit.loose,
child: Row(
children: [
if (isRequired && isEditable)
@ -698,10 +702,7 @@ class ItemListWidget {
Flexible(
child: Text(
label,
style: TextStyle(
fontSize: fontSize,
fontWeight: FontWeight.bold,
),
style: TextStyle(fontSize: fontSize, fontWeight: FontWeight.bold),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
@ -714,51 +715,41 @@ class ItemListWidget {
CustomButton(
text: buttonText,
height: 30,
padding: const EdgeInsets.symmetric(
vertical: 2,
horizontal: 10,
),
textStyle: TextStyle(
color: Colors.white,
fontSize: 11,
fontWeight: FontWeight.bold,
),
padding: const EdgeInsets.symmetric(vertical: 2, horizontal: 10),
textStyle: TextStyle(color: Colors.white, fontSize: 11, fontWeight: FontWeight.bold),
backgroundColor: Colors.blue,
onPressed: onTap,
),
],
),
),
const SizedBox(height: 8),
Container(
height: row2Height,
padding: const EdgeInsets.symmetric(vertical: 8),
child:
(isEditable && isInput)
? TextField(
autofocus: false,
controller: controller,
keyboardType: TextInputType.multiline,
maxLines: null,
expands: true,
style: TextStyle(fontSize: fontSize),
decoration: InputDecoration(
hintText: hintText,
//contentPadding: EdgeInsets.zero,
border: InputBorder.none,
),
)
: SingleChildScrollView(
padding: EdgeInsets.zero,
child: Text(
text,
style: TextStyle(
fontSize: fontSize,
color: detailtextColor,
),
),
),
child: (isEditable && isInput)
? TextFormField(
controller: effectiveController,
autofocus: false,
onChanged: (value) {
// setState
onChanged?.call(value);
},
keyboardType: TextInputType.multiline,
maxLines: null,
expands: true,
style: TextStyle(fontSize: fontSize),
decoration: InputDecoration(
hintText: hintText,
border: InputBorder.none,
),
)
: SingleChildScrollView(
padding: EdgeInsets.zero,
child: Text(
text,
style: TextStyle(fontSize: fontSize, color: detailtextColor),
),
),
),
],
),

View File

@ -102,7 +102,7 @@ class _RelatedPartiesPickerState extends State<RelatedPartiesPicker> {
Future<void> _getRelatedPartiesList() async {
try {
final raw = await HiddenDangerApi.getRelatedPartiesList();
final raw = await BasicInfoApi.getCropinfoProjectNameList();
if (raw['success']) {
final newList = raw['data'] ?? [];
setState(() {

View File

@ -25,47 +25,47 @@ class WorkTabIconGrid extends StatelessWidget {
borderRadius: BorderRadius.circular(8),
),
child:
buttonInfos.length <= 4
? Row(
mainAxisAlignment: MainAxisAlignment.start,
children:
buttonInfos.asMap().entries.map((entry) {
final index = entry.key;
final info = entry.value;
return _buildIconButton(
context: context,
iconPath: info['icon'] as String,
label: info['title'] as String,
unreadCount:
int.tryParse(info['unreadCount'].toString()) ?? 0,
onPressed: () => onItemPressed(index),
width: itemW,
);
}).toList(),
)
: Wrap(
spacing: 0,
runSpacing: 16,
alignment: WrapAlignment.start,
children:
buttonInfos.asMap().entries.map((entry) {
final index = entry.key;
final info = entry.value;
return _buildIconButton(
context: context,
iconPath: info['icon'] as String,
label: info['title'] as String,
unreadCount:
info['unreadCount'] is String
? int.tryParse(info['unreadCount'])
: info['unreadCount'] is int
? info['unreadCount']
: 0,
onPressed: () => onItemPressed(index),
width: itemW,
);
}).toList(),
),
buttonInfos.length <= 4
? Row(
mainAxisAlignment: MainAxisAlignment.start,
children:
buttonInfos.asMap().entries.map((entry) {
final index = entry.key;
final info = entry.value;
return _buildIconButton(
context: context,
iconPath: info['icon'] as String,
label: info['title'] as String,
unreadCount:
int.tryParse(info['unreadCount'].toString()) ?? 0,
onPressed: () => onItemPressed(index),
width: itemW,
);
}).toList(),
)
: Wrap(
spacing: 0,
runSpacing: 16,
alignment: WrapAlignment.start,
children:
buttonInfos.asMap().entries.map((entry) {
final index = entry.key;
final info = entry.value;
return _buildIconButton(
context: context,
iconPath: info['icon'] as String,
label: info['title'] as String,
unreadCount:
info['unreadCount'] is String
? int.tryParse(info['unreadCount'])
: info['unreadCount'] is int
? info['unreadCount']
: 0,
onPressed: () => onItemPressed(index),
width: itemW,
);
}).toList(),
),
);
}
@ -93,10 +93,14 @@ class WorkTabIconGrid extends StatelessWidget {
children: [
Image.asset(iconPath, width: 30, height: 30),
const SizedBox(height: 5),
Text(
label,
style: const TextStyle(fontSize: 13),
textAlign: TextAlign.center,
SizedBox(
width: 70, //
child: Text(
label,
style: const TextStyle(fontSize: 13),
textAlign: TextAlign.center,
softWrap: true,
),
),
],
),

View File

@ -9,19 +9,19 @@ class ApiService {
static final bool isProduct = true;
///
// static final String basePath = "https://skqhdg.porthebei.com:9007";
static final String basePath =
isProduct
? "https://gbs-gateway.qhdsafety.com"
: "http://192.168.20.100:30140";
static final String basePath = "https://skqhdg.porthebei.com:9007";
// static final String basePath =
// isProduct
// ? "https://gbs-gateway.qhdsafety.com"
// : "http://192.168.20.100:30140";
///
static final String baseImgPath =
isProduct
? "https://jpfz.qhdsafety.com/gbsFileTest/"
: "http://192.168.20.240:9787/mnt/"; //
// static final String baseImgPath = "https://skqhdg.porthebei.com:9004/file/uploadFiles2/";
// static final String baseImgPath =
// isProduct
// ? "https://jpfz.qhdsafety.com/gbsFileTest/"
// : "http://192.168.20.240:9787/mnt/"; //
static final String baseImgPath = "https://skqhdg.porthebei.com:9004/file/uploadFiles2/";
static const publicKey =

View File

@ -121,6 +121,18 @@ class BasicInfoApi {
);
}
//
static Future<Map<String, dynamic>> getCropinfoProjectNameList() {
return HttpManager().request(
'${ApiService.basePath}',
'/xgfManager/project/listAllProjectBySelfCorp',
method: Method.post,
data: {
'pageSize': 999,
'pageIndex': 1,
},
);
}

View File

@ -4,17 +4,6 @@ import 'package:qhd_prevention/http/ApiService.dart';
import 'package:qhd_prevention/http/HttpManager.dart';
class HiddenDangerApi {
///
static Future<Map<String, dynamic>> getRelatedPartiesList() {
return HttpManager().request(
'${ApiService.basePath}/xgfManager',
'/project/listAllByCorp',
method: Method.get,
data: {
// ...data,
},
);
}
///
static Future<Map<String, dynamic>> getHiddenDangerAreas() {

View File

@ -37,40 +37,12 @@ enum SpecialListType {
//
list,
}
// "operationTypeName": "请选择作业类型",
// "workLocation": "请输入作业地点",
// "workUserName": "请选择作业人",
// "workHeight": "请输入作业高度",
// "workLevel": "请选择作业级别",
// "workContent": "请输入作业内容",
// "longitude" : "请定位位置",
// "linkSpecialWorks": "请选择关联其他特殊作业及安全作业票编号",
// "riskResults": "请选择风险辨识结果",
// "workStartTime": "请选择作业实施开始时间",
// "workEndTime": "请选择作业实施结束时间",
// "operationTypeName": "请选择作业类型",
// "workLevel": "请选择作业级别",
// "workStartTime": "请选择作业开始时间",
// "workEndTime": "请选择作业结束时间",
// "longitude" : "请定位位置",
// "workContent": "请输入作业内容",
// 'workScopeAndMethod' : "请输入作业内容、范围、方式",
// 'isWorkScopeAndMethodImage' : "请选择作业内容、范围、方式简图",
// "linkSpecialWorks": "请选择关联其他特殊作业及安全作业票编号",
// "riskResults": "请选择风险辨识结果",
// pd['signStepFlag'] = 2;
// pd['gasFlag'] = 2;
// levelList = pd['taskWorkLevels'] ?? [];
// await safeController.loadFromRaw(
// pd['preparers'] ?? pd['PREPARERS'] ?? [],
// );
// if (levelList.length > 0) {
// final item = levelList.first ?? {};
// pd['workLevelName'] = item['taskName'];
// pd['workLevel'] = item['workLevel'];
class SpecialListInitData {
List<String> getInitData(SpecialWorkTypeEnum type) {
List<String> list = [
//
"work_place",//
"work_way",
//
"applyUnit",
"applyUser",
@ -151,8 +123,9 @@ class SpecialListInitData {
"applyUserSignImage",
];
return list;
}
}
bool isKF = true;

View File

@ -8,6 +8,7 @@ import 'package:qhd_prevention/customWidget/dotted_border_box.dart';
import 'package:qhd_prevention/customWidget/item_list_widget.dart';
import 'package:qhd_prevention/customWidget/single_image_viewer.dart';
import 'package:qhd_prevention/http/ApiService.dart';
import 'package:qhd_prevention/pages/home/Tap/special_header.dart';
import 'package:qhd_prevention/tools/tools.dart';
class MeasuresListWidget extends StatefulWidget {
@ -37,7 +38,7 @@ class _MeasuresListWidgetState extends State<MeasuresListWidget> {
@override
Widget build(BuildContext context) {
if (measuresList.isEmpty) {
return const Center(child: Text('暂无更多数据'));
return const SizedBox();
}
return SingleChildScrollView(
@ -48,7 +49,7 @@ class _MeasuresListWidgetState extends State<MeasuresListWidget> {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
ListItemFactory.createBuildSimpleSection('安全防护措施'),
if (widget.isAllowEdit)
if (widget.isAllowEdit && isKF)
ItemListWidget.OneRowButtonTitleText(
label: '开发按钮-自测使用',
buttonText: '一键签字',
@ -82,7 +83,7 @@ class _MeasuresListWidgetState extends State<MeasuresListWidget> {
final columnWidthsReadOnly = <int, TableColumnWidth>{
0: const FlexColumnWidth(7), //
1: const FixedColumnWidth(70), //
2: const FixedColumnWidth(80), //
2: const FixedColumnWidth(120), //
};
final isEdit = widget.isAllowEdit;

View File

@ -270,6 +270,29 @@ class _HotWorkDetailFormWidgetState extends State<HotWorkDetailFormWidget> {
isEditable: widget.isEditable,
text: pd['operationTypeName'] ?? '',
),
if (pd['xgfFlag'] == 1) ...[
const Divider(),
ListItemFactory.createYesNoSection(
horizontalPadding: 2,
verticalPadding: 7,
title: '是否项目内作业',
isRequired: true,
isEdit: false,
text: '${pd['internalOperationFlag']}' == '1' ? '' : '',
groupValue: null, onChanged: (bool value) { },
),
const Divider(height: 1),
//
ItemListWidget.selectableLineTitleTextRightButton(
label: '相关方项目',
isEditable: false,
text: pd['projectName'] ?? '',
isRequired: true,
),
],
const Divider(),
ItemListWidget.singleLineTitleText(
label: '动火部位:',

View File

@ -409,7 +409,7 @@ class _DhWaitPageState extends State<DhWaitPage> {
},
),
);
if (status == '1' && lockFlag == '2') {
if (status == '1' && lockFlag == '2' && widget.listType == SpecialListType.list) {
buttons.add(
CustomButton(
text: '撤回',

View File

@ -15,6 +15,7 @@ import 'package:qhd_prevention/customWidget/item_list_widget.dart';
import 'package:qhd_prevention/customWidget/picker/CupertinoDatePicker.dart';
import 'package:qhd_prevention/customWidget/related_parties_picker.dart';
import 'package:qhd_prevention/customWidget/toast_util.dart';
//
import 'package:qhd_prevention/pages/home/Tap/special_header.dart';
import 'package:qhd_prevention/pages/home/Tap/special_work/custom/CustomSpecialFormDialog.dart';
@ -104,10 +105,6 @@ class _HotworkApplyDetailState extends State<HotworkApplyDetail> {
_dhworkWays = res['data'];
});
}
final personRes = await BasicInfoApi.getDeptUsers('', isMyCorp: 1);
if (personRes['success'] == true) {
_allPersonList = personRes['data'];
}
if (widget.isReEdit) {
final initData = await SpecialWorkApi.specialWorkTaskLogDetail(
widget.work_id,
@ -131,7 +128,9 @@ class _HotworkApplyDetailState extends State<HotworkApplyDetail> {
LoadingDialogHelper.dismiss();
if (initData['success'] == true) {
// taskWorkLevels
pd = initData['data'];
pd = initData['data'] ?? {};
pd['xgfFlag'] = 1;
pd['operationTypeName'] = '相关方作业';
pd['signStepFlag'] = 2;
pd['gasFlag'] = 0;
levelList = pd['taskWorkLevels'];
@ -197,6 +196,9 @@ class _HotworkApplyDetailState extends State<HotworkApplyDetail> {
//
await _getPersonListForUnitId(id);
},
data: {
'corpinfoId' : pd['projectExecutionLocationCorpId'] ?? ''
},
),
).then((_) {
// FocusHelper.clearFocus(context);
@ -257,7 +259,7 @@ class _HotworkApplyDetailState extends State<HotworkApplyDetail> {
await _getPersonListForUnitId(unitId);
personList = _personCache[unitId] ?? [];
if (personList.isEmpty) {
ToastUtil.showNormal(context, '暂无可选人员,请选择其他单位');
ToastUtil.showNormal(context, '暂无可选人员,请选择正确的相关方项目');
return;
}
}
@ -399,6 +401,19 @@ class _HotworkApplyDetailState extends State<HotworkApplyDetail> {
});
}
}
if (isKF) test();
});
}
Future<void> test() async {
for (Map item in _groups) {
item['actUser'] = '2008745640177348608';
item['actUserName'] = '李一浩';
item['actUserDepartment'] = '2008745637258113024';
item['actUserDepartmentName'] = '测试部';
final stepId = item['stepId'] ?? '';
}
setState(() {
});
}
@ -552,6 +567,9 @@ class _HotworkApplyDetailState extends State<HotworkApplyDetail> {
'workType': SpecialWorkTypeEnum.hotWork.code,
'xgfFlag': info['xgfFlag'] ?? '',
'xgfId': info['xgfId'] ?? '',
'corpinfoId': info['projectExecutionLocationCorpId'] ?? '',
'projectId': info['projectId'] ?? '',
'projectName': info['projectName'] ?? '',
'info': info,
'gasFlag': info['gasFlag'] ?? '',
'checkNo': info['checkNo'] ?? '',
@ -559,7 +577,8 @@ class _HotworkApplyDetailState extends State<HotworkApplyDetail> {
};
// TODO: checkNoworkId
if (FormUtils.hasValue(data, 'workInfo') && FormUtils.hasValue(data['workInfo'], 'checkNo')) {
if (FormUtils.hasValue(data, 'workInfo') &&
FormUtils.hasValue(data['workInfo'], 'checkNo')) {
data.remove('checkNo');
data.remove('workId');
}
@ -570,7 +589,10 @@ class _HotworkApplyDetailState extends State<HotworkApplyDetail> {
// return;
LoadingDialogHelper.show();
if (status == '1') {
final result = await SpecialWorkApi.specialWorkSave(data, SpecialWorkTypeEnum.hotWork);
final result = await SpecialWorkApi.specialWorkSave(
data,
SpecialWorkTypeEnum.hotWork,
);
LoadingDialogHelper.dismiss();
if (result['success'] == true) {
ToastUtil.showNormal(context, '保存成功');
@ -579,7 +601,10 @@ class _HotworkApplyDetailState extends State<HotworkApplyDetail> {
ToastUtil.showNormal(context, result['errMessage'] ?? '保存失败');
}
} else {
final result = await SpecialWorkApi.specialWorkSaveTemp(data, SpecialWorkTypeEnum.hotWork);
final result = await SpecialWorkApi.specialWorkSaveTemp(
data,
SpecialWorkTypeEnum.hotWork,
);
LoadingDialogHelper.dismiss();
if (result['success'] == true) {
ToastUtil.showNormal(context, '已暂存');
@ -634,7 +659,7 @@ class _HotworkApplyDetailState extends State<HotworkApplyDetail> {
LoadingDialogHelper.show();
final data = await CertificateApi.getCertificateUserList({
...params,
'corpinfoId': pd['xgfId'],
'corpinfoId': pd['projectExecutionLocationCorpId'],
});
final xgfData = await CertificateApi.getCertificateUserList({
...params,
@ -694,6 +719,10 @@ class _HotworkApplyDetailState extends State<HotworkApplyDetail> {
pd['projectId'] = id;
pd['projectName'] = name;
pd['xgfId'] = json['corpinfoId'];
pd['projectExecutionLocationCorpId'] =
json['projectExecutionLocationCorpId'];
pd['projectExecutionLocationCorpName'] =
json['projectExecutionLocationCorpName'];
});
_getRelatedPartiesUserList();
},
@ -709,6 +738,10 @@ class _HotworkApplyDetailState extends State<HotworkApplyDetail> {
//
Future<void> _getRelatedPartiesUserList() async {
final personRes = await BasicInfoApi.getDeptUsers('', isMyCorp: 0, corpinfoId: pd['projectExecutionLocationCorpId']);
if (personRes['success'] == true) {
_allPersonList = personRes['data'];
}
try {
final result = await BasicInfoApi.getDeptUsers(
'',
@ -872,14 +905,14 @@ class _HotworkApplyDetailState extends State<HotworkApplyDetail> {
const Divider(),
ItemListWidget.selectableLineTitleTextRightButton(
label: '作业类型:',
isEditable: _isEditable,
onTap: chooseHotworkType,
text: pd['operationTypeName'] ?? '',
isEditable: false,
strongRequired: true,
text: '相关方作业',
),
if (pd['xgfFlag'] == 1) ...[
const Divider(),
ListItemFactory.createYesNoSection(
horizontalPadding: 5,
horizontalPadding: 3,
title: '是否项目内作业',
isRequired: true,
groupValue: _isInnerWork,
@ -890,7 +923,7 @@ class _HotworkApplyDetailState extends State<HotworkApplyDetail> {
});
},
),
const Divider(),
const Divider(height:1),
//
ItemListWidget.selectableLineTitleTextRightButton(

View File

@ -320,7 +320,11 @@ class _HotDelayPageState extends State<HotDelayPage> {
setModalState(() {}); //
},
data: {
'corpinfoId' :widget.data['workInfo']['corpinfoId'] ?? ''
},
),
);
},
),

View File

@ -163,9 +163,10 @@ class _HotTaskPageState extends State<HotTaskPage> {
(_initData['settingSignSteps'] is List)
? List.from(_initData['settingSignSteps'])
: [];
final corpinfoId = _initData['workInfo']['corpinfoId'];
if (steps.isNotEmpty) {
LoadingDialogHelper.show();
final personRes = await BasicInfoApi.getDeptUsers('', isMyCorp: 1);
final personRes = await BasicInfoApi.getDeptUsers('', isMyCorp: 0, corpinfoId: corpinfoId);
LoadingDialogHelper.dismiss();
if (personRes['success'] == true) {
@ -431,6 +432,9 @@ class _HotTaskPageState extends State<HotTaskPage> {
//
await _getPersonListForUnitId(id);
},
data: {
'corpinfoId' :_initData['workInfo']['corpinfoId'] ?? ''
},
),
).then((_) {
// FocusHelper.clearFocus(context);

View File

@ -47,10 +47,33 @@ class _workTabDhListState extends State<workTabDhList> {
_loading = true;
});
try {
final res = await SpecialWorkApi.getSpecialWorkStepList(SpecialWorkTypeEnum.hotWork.code);
final res = await SpecialWorkApi.getSpecialWorkStepList(
SpecialWorkTypeEnum.hotWork.code,
);
if (res != null && res['success'] == true) {
setState(() {
steps = res['data'] ?? [];
final rawData = res['data'] ?? [];
//
steps = (rawData as List).map((entry) {
if (entry is Map<String, dynamic>) {
final List<dynamic> originalSteps = entry['steps'] ?? [];
// steps allowXgfFlag '1'
final filteredSteps = originalSteps.where((item) {
if (item is Map<String, dynamic>) {
final flag = item['allowXgfFlag'];
return '${item['allowXgfFlag']}' == '1';
}
return false;
}).toList();
return {
...entry,
'steps': filteredSteps,
};
}
return entry;
}).where((entry) => entry != null).toList();
_getStepUnreadCount();
});
} else {
@ -75,7 +98,9 @@ class _workTabDhListState extends State<workTabDhList> {
//
Future<void> _getStepUnreadCount() async {
final res = await SpecialWorkApi.specialWorkTaskLogCount(SpecialWorkTypeEnum.hotWork.code);
final res = await SpecialWorkApi.specialWorkTaskLogCount(
SpecialWorkTypeEnum.hotWork.code,
);
LoadingDialogHelper.dismiss();
setState(() {
if (res['success'] == true) {
@ -85,16 +110,16 @@ class _workTabDhListState extends State<workTabDhList> {
final count = entry['todoCount']?.toString() ?? '0';
for (var i = 0; i < steps.length; i++) {
final group = steps[i] ?? {};
final stepsData = group['steps'] ?? [];
for (var j = 0; j < stepsData.length; j++) {
final step = stepsData[j] ?? {};
if (stepId == step['stepId']?.toString()) {
step['unreadCount'] = count;
}
final stepsData = group['steps'] ?? [];
for (var j = 0; j < stepsData.length; j++) {
final step = stepsData[j] ?? {};
if (stepId == step['stepId']?.toString()) {
step['unreadCount'] = count;
}
}
}
}
}
});
}
@ -143,7 +168,7 @@ class _workTabDhListState extends State<workTabDhList> {
return buttons;
}
void _onGroupItemPressed(int groupIndex, int buttonIndex) async{
void _onGroupItemPressed(int groupIndex, int buttonIndex) async {
if (groupIndex < 0 || groupIndex >= steps.length) return;
final group = steps[groupIndex];
final dynamic stepsData = (group is Map) ? group['steps'] : null;
@ -154,7 +179,14 @@ class _workTabDhListState extends State<workTabDhList> {
? group['groupName'].toString()
: '';
final stepId = button['stepId'] ?? '';
await pushPage(DhWaitPage(stepId: stepId, workTypeTitle: workTypeTitle, listType: SpecialListType.task,), context);
await pushPage(
DhWaitPage(
stepId: stepId,
workTypeTitle: workTypeTitle,
listType: SpecialListType.task,
),
context,
);
_getData();
}

View File

@ -217,24 +217,9 @@ class _BreakgroundDetailFormWidgetState extends State<BreakgroundDetailFormWidge
}
}
List linkWorks = pd['linkSpecialWorks'] ?? [];
String linkShowStr = linkWorks
.map((item) {
final workName = item['workTypeName'];
final checkNo = item['checkNo'] ?? '';
return '$workName $checkNo';
})
.toList()
.join(',');
List riskResults = pd['riskResults'] ?? [];
String riskShowStr =
riskResults
.map((item) {
final riskResultName = item['riskResultName'];
return riskResultName;
})
.toList()
.join();
String linkShowStr = pd['linkSpecialWorks'] ?? '';
String riskShowStr = pd['riskResults'] ?? '';
return Container(
padding: const EdgeInsets.symmetric(vertical: 0),
@ -277,14 +262,16 @@ class _BreakgroundDetailFormWidgetState extends State<BreakgroundDetailFormWidge
if (pd['xgfFlag'] == 1) ...[
const Divider(),
ListItemFactory.createYesNoSection(
horizontalPadding: 5,
horizontalPadding: 2,
verticalPadding: 7,
title: '是否项目内作业',
isEdit: false,
isRequired: true,
text: '${pd['internalOperationFlag']}' == '1' ? '' : '',
groupValue: null, onChanged: (bool value) { },
),
const Divider(),
const Divider(height: 1),
//
ItemListWidget.selectableLineTitleTextRightButton(
@ -365,7 +352,6 @@ class _BreakgroundDetailFormWidgetState extends State<BreakgroundDetailFormWidge
isEditable: false,
isInput: false,
hintText: '请选择关联的其他特殊作业及安全作业票编号',
controller: null,
text: linkShowStr, onTap: () { },
),
const Divider(),
@ -376,7 +362,6 @@ class _BreakgroundDetailFormWidgetState extends State<BreakgroundDetailFormWidge
isInput: false,
onTap: (){},
hintText: '请选择',
controller: null,
text: riskShowStr,
),

View File

@ -110,9 +110,6 @@ class _DlApplyPageState extends State<DlApplyPage> {
};
//
final Future<Map<String, dynamic>> personFuture =
BasicInfoApi.getDeptUsers('', isMyCorp: 1);
final Future<Map<String, dynamic>> initDataFuture =
widget.isReEdit
? SpecialWorkApi.specialWorkTaskLogDetail(widget.work_id)
@ -120,15 +117,9 @@ class _DlApplyPageState extends State<DlApplyPage> {
SpecialWorkTypeEnum.cutRoadWork.code,
);
final results = await Future.wait([personFuture, initDataFuture]);
final results = await Future.wait([initDataFuture]);
final personRes = results[0];
final initData = results[1];
//
if (personRes['success'] == true) {
_allPersonList = personRes['data'] ?? [];
}
final initData = results[0];
printLongString(jsonEncode(initData));
if (initData['success'] == true) {
@ -147,6 +138,8 @@ class _DlApplyPageState extends State<DlApplyPage> {
pd = initData['data'] ?? {};
pd['signStepFlag'] = 2;
pd['gasFlag'] = 2;
pd['xgfFlag'] = 1;
pd['operationTypeName'] = '相关方作业';
levelList = pd['taskWorkLevels'] ?? [];
await safeController.loadFromRaw(
pd['preparers'] ?? pd['PREPARERS'] ?? [],
@ -190,21 +183,22 @@ class _DlApplyPageState extends State<DlApplyPage> {
if (res['success'] == true) {
final List<dynamic> data = res['data'] ?? [];
List<SafeMeasureOption> safeMeasures =
data
.map(
(item) =>
SafeMeasureOption.fromJson(Map<String, dynamic>.from(item)),
)
.toList();
data
.map(
(item) =>
SafeMeasureOption.fromJson(Map<String, dynamic>.from(item)),
)
.toList();
safeController.setAllMeasures(safeMeasures);
if (widget.isReEdit) {
safeMeasures =
data
.where((item) => '${item['type']}' == '1')
.map(
(item) =>
SafeMeasureOption.fromJson(Map<String, dynamic>.from(item)),
)
(item) => SafeMeasureOption.fromJson(
Map<String, dynamic>.from(item),
),
)
.toList();
await safeController.loadInitialData(
safeMeasures.map((item) => item.toJson()).toList(),
@ -233,6 +227,7 @@ class _DlApplyPageState extends State<DlApplyPage> {
//
await _getPersonListForUnitId(id);
},
data: {'corpinfoId' : '${pd['projectExecutionLocationCorpId']}'},
),
).then((_) {
// FocusHelper.clearFocus(context);
@ -293,7 +288,7 @@ class _DlApplyPageState extends State<DlApplyPage> {
await _getPersonListForUnitId(unitId);
personList = _personCache[unitId] ?? [];
if (personList.isEmpty) {
ToastUtil.showNormal(context, '暂无可选人员,请选择其他单位');
ToastUtil.showNormal(context, '暂无可选人员,请选择正确的相关方项目');
return;
}
}
@ -348,6 +343,10 @@ class _DlApplyPageState extends State<DlApplyPage> {
pd['projectId'] = id;
pd['projectName'] = name;
pd['xgfId'] = json['corpinfoId'];
pd['projectExecutionLocationCorpId'] =
json['projectExecutionLocationCorpId'];
pd['projectExecutionLocationCorpName'] =
json['projectExecutionLocationCorpName'];
});
_getRelatedPartiesUserList();
},
@ -363,6 +362,10 @@ class _DlApplyPageState extends State<DlApplyPage> {
//
Future<void> _getRelatedPartiesUserList() async {
final personRes = await BasicInfoApi.getDeptUsers('', isMyCorp: 0, corpinfoId: pd['projectExecutionLocationCorpId']);
if (personRes['success'] == true) {
_allPersonList = personRes['data'];
}
try {
final result = await BasicInfoApi.getDeptUsers(
'',
@ -492,6 +495,25 @@ class _DlApplyPageState extends State<DlApplyPage> {
});
}
}
if (isKF) test();
});
}
Future<void> test() async {
for (Map item in _groups) {
item['actUser'] = '2008745640177348608';
item['actUserName'] = '李一浩';
item['actUserDepartment'] = '2008745637258113024';
item['actUserDepartmentName'] = '测试部';
final stepId = item['stepId'] ?? '';
if ('$stepId' == '20') {
_allowChoosePersonList[0] = item;
}
if ('$stepId' == '21') {
_allowChoosePersonList[1] = item;
}
}
setState(() {
});
}
@ -634,8 +656,7 @@ class _DlApplyPageState extends State<DlApplyPage> {
///
Future<bool> _checkImageUpdata() async {
UploadFileType fileType =
UploadFileType.specialOperationApplyInvolvedPhoto;
UploadFileType fileType = UploadFileType.specialOperationApplyInvolvedPhoto;
late bool isSuccess = true;
if (_imageList.isNotEmpty) {
try {
@ -678,7 +699,6 @@ class _DlApplyPageState extends State<DlApplyPage> {
ToastUtil.showNormal(context, err);
return;
}
}
if (_imageList.isNotEmpty) {
LoadingDialogHelper.show();
@ -696,6 +716,9 @@ class _DlApplyPageState extends State<DlApplyPage> {
'workType': SpecialWorkTypeEnum.cutRoadWork.code,
'xgfFlag': info['xgfFlag'] ?? '',
'xgfId': info['xgfId'] ?? '',
'corpinfoId': info['projectExecutionLocationCorpId'] ?? '',
'projectId': info['projectId'] ?? '',
'projectName': info['projectName'] ?? '',
'info': info,
'gasFlag': info['gasFlag'] ?? '',
'checkNo': info['checkNo'] ?? '',
@ -894,12 +917,13 @@ class _DlApplyPageState extends State<DlApplyPage> {
onConfirm: (selectedItems) {
//
setState(() {
pd['linkSpecialWorks'] =
selectedItems.map((item) {
final workName = SpecialWorkTypeEnum.getName(item['workType']);
final checkNo = item['checkNo'] ?? '';
return {'workTypeName': workName, 'checkNo': checkNo};
}).toList();
String w = '${selectedItems.map((item) {
final workName = SpecialWorkTypeEnum.getName(item['workType']);
final checkNo = item['checkNo'] ?? '';
return '$workName $checkNo';
}).toList().join(',')},';
String now = pd['linkSpecialWorks'] ?? '';
pd['linkSpecialWorks'] = now + w;
});
},
);
@ -914,31 +938,27 @@ class _DlApplyPageState extends State<DlApplyPage> {
backgroundColor: Colors.transparent,
builder:
(_) => MultiDictValuesPicker(
title: '风险辨识结果',
dictType: 'riskGrade',
allowSelectParent: false,
multiSelect: true,
onMultiSelected: (
List<String> ids,
List<String> names,
List<Map<String, dynamic>> extraDataList,
title: '风险辨识结果',
dictType: 'riskGrade',
allowSelectParent: false,
multiSelect: true,
onMultiSelected: (
List<String> ids,
List<String> names,
List<Map<String, dynamic>> extraDataList,
) {
setState(() {
// addData['hiddenLevel'] = extraData?['dictValue'];
// addData['hiddenLevelName'] = name;
pd['riskResults'] =
extraDataList.map((data) {
final name = data['dictLabel'] ?? '';
return {
'riskResultName': name,
'riskResult': data['dictValue'],
};
}).toList();
});
},
onSelected:
(String id, String name, Map<String, dynamic>? extraData) {},
),
setState(() {
String w = '${extraDataList.map((data) {
final name = data['dictLabel'] ?? '';
return name;
}).toList().join(',')},';
String now = pd['riskResults'] ?? '';
pd['riskResults'] = now + w;
});
},
onSelected:
(String id, String name, Map<String, dynamic>? extraData) {},
),
).then((_) {
// FocusHelper.clearFocus(context);
});
@ -988,14 +1008,14 @@ class _DlApplyPageState extends State<DlApplyPage> {
const Divider(),
ItemListWidget.selectableLineTitleTextRightButton(
label: '作业类型:',
isEditable: _isEditable,
onTap: chooseHotworkType,
text: pd['operationTypeName'] ?? '',
isEditable: false,
strongRequired: true,
text: '相关方作业',
),
if (pd['xgfFlag'] == 1) ...[
const Divider(),
ListItemFactory.createYesNoSection(
horizontalPadding: 5,
horizontalPadding: 3,
title: '是否项目内作业',
isRequired: true,
groupValue: _isInnerWork,
@ -1006,7 +1026,7 @@ class _DlApplyPageState extends State<DlApplyPage> {
});
},
),
const Divider(),
const Divider(height:1),
//
ItemListWidget.selectableLineTitleTextRightButton(
@ -1072,13 +1092,16 @@ class _DlApplyPageState extends State<DlApplyPage> {
title: "断路地段示意图",
maxCount: 1,
initialMediaPaths:
widget.isReEdit
? [
FormUtils.hasValue(pd, 'workScopeAndMethodImage')
? '${ApiService.baseImgPath}${pd['workScopeAndMethodImage']}'
: '',
]
: null,
widget.isReEdit
? [
FormUtils.hasValue(
pd,
'workScopeAndMethodImage',
)
? '${ApiService.baseImgPath}${pd['workScopeAndMethodImage']}'
: '',
]
: null,
mediaType: MediaType.image,
isShowAI: false,
isEdit: true,
@ -1147,22 +1170,26 @@ class _DlApplyPageState extends State<DlApplyPage> {
label: '关联其他特殊作业及安全作业票编号',
isRequired: _isEditable,
isEditable: _isEditable,
isInput: false,
isInput: true,
onTap: _showChooseOtherWorkTicketDialog,
hintText: '请选择关联的其他特殊作业及安全作业票编号',
controller: null,
text: linkShowStr,
text: pd['linkSpecialWorks'] ?? '',
onChanged: (value) {
pd['linkSpecialWorks'] = value;
},
),
const Divider(),
ItemListWidget.twoRowButtonTitleText(
label: '风险辨识结果',
isRequired: _isEditable,
isEditable: _isEditable,
isInput: false,
isInput: true,
onTap: _showRiskIdentificationResultDialog,
hintText: '请选择',
controller: null,
text: riskShowStr,
text: pd['riskResults'] ?? '',
onChanged: (value) {
pd['riskResults'] = value;
},
),
if (widget.isReEdit && FormUtils.hasValue(form, 'id')) ...[
BreakgroundDetailFormWidget(pd: form, isEditable: true),

View File

@ -160,9 +160,10 @@ class _DlTaskPageState extends State<DlTaskPage> {
(_initData['settingSignSteps'] is List)
? List.from(_initData['settingSignSteps'])
: [];
final corpinfoId = _initData['workInfo']['corpinfoId'];
if (steps.isNotEmpty) {
LoadingDialogHelper.show();
final personRes = await BasicInfoApi.getDeptUsers('', isMyCorp: 1);
final personRes = await BasicInfoApi.getDeptUsers('', isMyCorp: 0, corpinfoId: corpinfoId);
LoadingDialogHelper.dismiss();
if (personRes['success'] == true) {
@ -430,6 +431,9 @@ class _DlTaskPageState extends State<DlTaskPage> {
//
await _getPersonListForUnitId(id);
},
data: {
'corpinfoId' :_initData['workInfo']['corpinfoId'] ?? ''
},
),
).then((_) {
// FocusHelper.clearFocus(context);

View File

@ -477,7 +477,7 @@ class _DlWaitPageState extends State<DlWaitPage> {
},
),
);
if (status == '1' && lockFlag == '2') {
if (status == '1' && lockFlag == '2' && widget.listType == SpecialListType.list) {
buttons.add(
CustomButton(
text: '撤回',

View File

@ -49,7 +49,28 @@ class _WorkTabDlListState extends State<WorkTabDlList> {
final res = await SpecialWorkApi.getSpecialWorkStepList(SpecialWorkTypeEnum.cutRoadWork.code);
if (res != null && res['success'] == true) {
setState(() {
steps = res['data'] ?? [];
final rawData = res['data'] ?? [];
//
steps = (rawData as List).map((entry) {
if (entry is Map<String, dynamic>) {
final List<dynamic> originalSteps = entry['steps'] ?? [];
// steps allowXgfFlag '1'
final filteredSteps = originalSteps.where((item) {
if (item is Map<String, dynamic>) {
final flag = item['allowXgfFlag'];
return '${item['allowXgfFlag']}' == '1';
}
return false;
}).toList();
return {
...entry,
'steps': filteredSteps,
};
}
return entry;
}).where((entry) => entry != null).toList();
_getStepUnreadCount();
});
} else {

View File

@ -217,24 +217,9 @@ class _CutRoadDetailFormWidgetState extends State<CutRoadDetailFormWidget> {
}
}
List linkWorks = pd['linkSpecialWorks'] ?? [];
String linkShowStr = linkWorks
.map((item) {
final workName = item['workTypeName'];
final checkNo = item['checkNo'] ?? '';
return '$workName $checkNo';
})
.toList()
.join(',');
List riskResults = pd['riskResults'] ?? [];
String riskShowStr =
riskResults
.map((item) {
final riskResultName = item['riskResultName'];
return riskResultName;
})
.toList()
.join();
String linkShowStr = pd['linkSpecialWorks'] ?? '';
String riskShowStr = pd['riskResults'] ?? '';
return Container(
padding: const EdgeInsets.symmetric(vertical: 0),
@ -277,14 +262,16 @@ class _CutRoadDetailFormWidgetState extends State<CutRoadDetailFormWidget> {
if (pd['xgfFlag'] == 1) ...[
const Divider(),
ListItemFactory.createYesNoSection(
horizontalPadding: 5,
horizontalPadding: 2,
verticalPadding: 7,
title: '是否项目内作业',
isEdit: false,
isRequired: true,
text: '${pd['internalOperationFlag']}' == '1' ? '' : '',
groupValue: null, onChanged: (bool value) { },
),
const Divider(),
const Divider(height: 1),
//
ItemListWidget.selectableLineTitleTextRightButton(
@ -350,7 +337,6 @@ class _CutRoadDetailFormWidgetState extends State<CutRoadDetailFormWidget> {
isEditable: false,
isInput: false,
hintText: '请选择关联的其他特殊作业及安全作业票编号',
controller: null,
text: linkShowStr, onTap: () { },
),
const Divider(),
@ -361,7 +347,6 @@ class _CutRoadDetailFormWidgetState extends State<CutRoadDetailFormWidget> {
isInput: false,
onTap: (){},
hintText: '请选择',
controller: null,
text: riskShowStr,
),
const Divider(),

View File

@ -108,9 +108,6 @@ class _DtApplyPageState extends State<DtApplyPage> {
};
//
final Future<Map<String, dynamic>> personFuture =
BasicInfoApi.getDeptUsers('', isMyCorp: 1);
final Future<Map<String, dynamic>> initDataFuture =
widget.isReEdit
? SpecialWorkApi.specialWorkTaskLogDetail(widget.work_id)
@ -118,15 +115,9 @@ class _DtApplyPageState extends State<DtApplyPage> {
SpecialWorkTypeEnum.breakgroundWork.code,
);
final results = await Future.wait([personFuture, initDataFuture]);
final results = await Future.wait([initDataFuture]);
final personRes = results[0];
final initData = results[1];
//
if (personRes['success'] == true) {
_allPersonList = personRes['data'] ?? [];
}
final initData = results[0];
printLongString(jsonEncode(initData));
if (initData['success'] == true) {
@ -145,6 +136,8 @@ class _DtApplyPageState extends State<DtApplyPage> {
pd = initData['data'] ?? {};
pd['signStepFlag'] = 2;
pd['gasFlag'] = 2;
pd['xgfFlag'] = 1;
pd['operationTypeName'] = '相关方作业';
levelList = pd['taskWorkLevels'] ?? [];
await safeController.loadFromRaw(
pd['preparers'] ?? pd['PREPARERS'] ?? [],
@ -231,6 +224,7 @@ class _DtApplyPageState extends State<DtApplyPage> {
//
await _getPersonListForUnitId(id);
},
data: {'corpinfoId' : '${pd['projectExecutionLocationCorpId']}'},
),
).then((_) {
// FocusHelper.clearFocus(context);
@ -291,7 +285,7 @@ class _DtApplyPageState extends State<DtApplyPage> {
await _getPersonListForUnitId(unitId);
personList = _personCache[unitId] ?? [];
if (personList.isEmpty) {
ToastUtil.showNormal(context, '暂无可选人员,请选择其他单位');
ToastUtil.showNormal(context, '暂无可选人员,请选择正确的相关方项目');
return;
}
}
@ -346,6 +340,8 @@ class _DtApplyPageState extends State<DtApplyPage> {
pd['projectId'] = id;
pd['projectName'] = name;
pd['xgfId'] = json['corpinfoId'];
pd['projectExecutionLocationCorpId'] = json['projectExecutionLocationCorpId'];
pd['projectExecutionLocationCorpName'] = json['projectExecutionLocationCorpName'];
});
_getRelatedPartiesUserList();
},
@ -361,6 +357,10 @@ class _DtApplyPageState extends State<DtApplyPage> {
//
Future<void> _getRelatedPartiesUserList() async {
final personRes = await BasicInfoApi.getDeptUsers('', isMyCorp: 0, corpinfoId: pd['projectExecutionLocationCorpId']);
if (personRes['success'] == true) {
_allPersonList = personRes['data'];
}
try {
final result = await BasicInfoApi.getDeptUsers(
'',
@ -490,6 +490,25 @@ class _DtApplyPageState extends State<DtApplyPage> {
});
}
}
if (isKF) test();
});
}
Future<void> test() async {
for (Map item in _groups) {
item['actUser'] = '2008745640177348608';
item['actUserName'] = '李一浩';
item['actUserDepartment'] = '2008745637258113024';
item['actUserDepartmentName'] = '测试部';
final stepId = item['stepId'] ?? '';
if ('$stepId' == '20') {
_allowChoosePersonList[0] = item;
}
if ('$stepId' == '21') {
_allowChoosePersonList[1] = item;
}
}
setState(() {
});
}
@ -694,6 +713,9 @@ class _DtApplyPageState extends State<DtApplyPage> {
'workType': SpecialWorkTypeEnum.breakgroundWork.code,
'xgfFlag': info['xgfFlag'] ?? '',
'xgfId': info['xgfId'] ?? '',
'corpinfoId' : info['projectExecutionLocationCorpId'] ?? '',
'projectId': info['projectId'] ?? '',
'projectName': info['projectName'] ?? '',
'info': info,
'gasFlag': info['gasFlag'] ?? '',
'checkNo': info['checkNo'] ?? '',
@ -892,12 +914,13 @@ class _DtApplyPageState extends State<DtApplyPage> {
onConfirm: (selectedItems) {
//
setState(() {
pd['linkSpecialWorks'] =
selectedItems.map((item) {
final workName = SpecialWorkTypeEnum.getName(item['workType']);
final checkNo = item['checkNo'] ?? '';
return {'workTypeName': workName, 'checkNo': checkNo};
}).toList();
String w = '${selectedItems.map((item) {
final workName = SpecialWorkTypeEnum.getName(item['workType']);
final checkNo = item['checkNo'] ?? '';
return '$workName $checkNo';
}).toList().join(',')},';
String now = pd['linkSpecialWorks'] ?? '';
pd['linkSpecialWorks'] = now + w;
});
},
);
@ -912,31 +935,27 @@ class _DtApplyPageState extends State<DtApplyPage> {
backgroundColor: Colors.transparent,
builder:
(_) => MultiDictValuesPicker(
title: '风险辨识结果',
dictType: 'riskGrade',
allowSelectParent: false,
multiSelect: true,
onMultiSelected: (
List<String> ids,
List<String> names,
List<Map<String, dynamic>> extraDataList,
title: '风险辨识结果',
dictType: 'riskGrade',
allowSelectParent: false,
multiSelect: true,
onMultiSelected: (
List<String> ids,
List<String> names,
List<Map<String, dynamic>> extraDataList,
) {
setState(() {
// addData['hiddenLevel'] = extraData?['dictValue'];
// addData['hiddenLevelName'] = name;
pd['riskResults'] =
extraDataList.map((data) {
final name = data['dictLabel'] ?? '';
return {
'riskResultName': name,
'riskResult': data['dictValue'],
};
}).toList();
});
},
onSelected:
(String id, String name, Map<String, dynamic>? extraData) {},
),
setState(() {
String w = '${extraDataList.map((data) {
final name = data['dictLabel'] ?? '';
return name;
}).toList().join(',')},';
String now = pd['riskResults'] ?? '';
pd['riskResults'] = now + w;
});
},
onSelected:
(String id, String name, Map<String, dynamic>? extraData) {},
),
).then((_) {
// FocusHelper.clearFocus(context);
});
@ -986,14 +1005,14 @@ class _DtApplyPageState extends State<DtApplyPage> {
const Divider(),
ItemListWidget.selectableLineTitleTextRightButton(
label: '作业类型:',
isEditable: _isEditable,
onTap: chooseHotworkType,
text: pd['operationTypeName'] ?? '',
isEditable: false,
strongRequired: true,
text: '相关方作业',
),
if (pd['xgfFlag'] == 1) ...[
const Divider(),
ListItemFactory.createYesNoSection(
horizontalPadding: 5,
horizontalPadding: 3,
title: '是否项目内作业',
isRequired: true,
groupValue: _isInnerWork,
@ -1004,7 +1023,7 @@ class _DtApplyPageState extends State<DtApplyPage> {
});
},
),
const Divider(),
const Divider(height:1),
//
ItemListWidget.selectableLineTitleTextRightButton(
@ -1118,22 +1137,26 @@ class _DtApplyPageState extends State<DtApplyPage> {
label: '关联其他特殊作业及安全作业票编号',
isRequired: _isEditable,
isEditable: _isEditable,
isInput: false,
isInput: true,
onTap: _showChooseOtherWorkTicketDialog,
hintText: '请选择关联的其他特殊作业及安全作业票编号',
controller: null,
text: linkShowStr,
text: pd['linkSpecialWorks'] ?? '',
onChanged: (value) {
pd['linkSpecialWorks'] = value;
},
),
const Divider(),
ItemListWidget.twoRowButtonTitleText(
label: '风险辨识结果',
isRequired: _isEditable,
isEditable: _isEditable,
isInput: false,
isInput: true,
onTap: _showRiskIdentificationResultDialog,
hintText: '请选择',
controller: null,
text: riskShowStr,
text: pd['riskResults'] ?? '',
onChanged: (value) {
pd['riskResults'] = value;
},
),
if (widget.isReEdit && FormUtils.hasValue(form, 'id')) ...[
CutRoadDetailFormWidget(pd: form, isEditable: true),

View File

@ -159,9 +159,10 @@ class _DtTaskPageState extends State<DtTaskPage> {
(_initData['settingSignSteps'] is List)
? List.from(_initData['settingSignSteps'])
: [];
final corpinfoId = _initData['workInfo']['corpinfoId'];
if (steps.isNotEmpty) {
LoadingDialogHelper.show();
final personRes = await BasicInfoApi.getDeptUsers('', isMyCorp: 1);
final personRes = await BasicInfoApi.getDeptUsers('', isMyCorp: 0, corpinfoId: corpinfoId);
LoadingDialogHelper.dismiss();
if (personRes['success'] == true) {
@ -429,6 +430,9 @@ class _DtTaskPageState extends State<DtTaskPage> {
//
await _getPersonListForUnitId(id);
},
data: {
'corpinfoId' :_initData['workInfo']['corpinfoId'] ?? ''
},
),
).then((_) {
// FocusHelper.clearFocus(context);

View File

@ -104,6 +104,7 @@ class _DtWaitPageState extends State<DtWaitPage> {
};
response = await SpecialWorkApi.specialWorkList(data);
}
LoadingDialogHelper.hide();
setState(() {
if (currentPage == 1) {
@ -464,7 +465,7 @@ class _DtWaitPageState extends State<DtWaitPage> {
},
),
);
if (status == '1' && lockFlag == '2') {
if (status == '1' && lockFlag == '2' && widget.listType == SpecialListType.list) {
buttons.add(
CustomButton(
text: '撤回',
@ -521,7 +522,6 @@ class _DtWaitPageState extends State<DtWaitPage> {
if (ok) {
LoadingDialogHelper.show();
final res = await SpecialWorkApi.specialWorkWithdraw(id);
LoadingDialogHelper.hide();
if (res['success']) {
ToastUtil.showNormal(context, '操作成功');
_fetchData();

View File

@ -49,7 +49,28 @@ class _WorkTabDtListState extends State<WorkTabDtList> {
final res = await SpecialWorkApi.getSpecialWorkStepList(SpecialWorkTypeEnum.breakgroundWork.code);
if (res != null && res['success'] == true) {
setState(() {
steps = res['data'] ?? [];
final rawData = res['data'] ?? [];
//
steps = (rawData as List).map((entry) {
if (entry is Map<String, dynamic>) {
final List<dynamic> originalSteps = entry['steps'] ?? [];
// steps allowXgfFlag '1'
final filteredSteps = originalSteps.where((item) {
if (item is Map<String, dynamic>) {
final flag = item['allowXgfFlag'];
return '${item['allowXgfFlag']}' == '1';
}
return false;
}).toList();
return {
...entry,
'steps': filteredSteps,
};
}
return entry;
}).where((entry) => entry != null).toList();
_getStepUnreadCount();
});
} else {

File diff suppressed because it is too large Load Diff

View File

@ -164,9 +164,10 @@ class _DzTaskPageState extends State<DzTaskPage> {
(_initData['settingSignSteps'] is List)
? List.from(_initData['settingSignSteps'])
: [];
final corpinfoId = _initData['workInfo']['corpinfoId'];
if (steps.isNotEmpty) {
LoadingDialogHelper.show();
final personRes = await BasicInfoApi.getDeptUsers('', isMyCorp: 1);
final personRes = await BasicInfoApi.getDeptUsers('', isMyCorp: 0, corpinfoId: corpinfoId);
LoadingDialogHelper.dismiss();
if (personRes['success'] == true) {
@ -434,6 +435,9 @@ class _DzTaskPageState extends State<DzTaskPage> {
//
await _getPersonListForUnitId(id);
},
data: {
'corpinfoId' :_initData['workInfo']['corpinfoId'] ?? ''
},
),
).then((_) {
// FocusHelper.clearFocus(context);

View File

@ -464,7 +464,7 @@ class _DzWaitPageState extends State<DzWaitPage> {
},
),
);
if (status == '1' && lockFlag == '2') {
if (status == '1' && lockFlag == '2' && widget.listType == SpecialListType.list) {
buttons.add(
CustomButton(
text: '撤回',

View File

@ -217,24 +217,9 @@ class _HoistingDetailFormWidgetState extends State<HoistingDetailFormWidget> {
}
}
List linkWorks = pd['linkSpecialWorks'] ?? [];
String linkShowStr = linkWorks
.map((item) {
final workName = item['workTypeName'];
final checkNo = item['checkNo'] ?? '';
return '$workName $checkNo';
})
.toList()
.join(',');
List riskResults = pd['riskResults'] ?? [];
String riskShowStr =
riskResults
.map((item) {
final riskResultName = item['riskResultName'];
return riskResultName;
})
.toList()
.join();
String linkShowStr = pd['linkSpecialWorks'] ?? '';
String riskShowStr = pd['riskResults'] ?? '';
return Container(
padding: const EdgeInsets.symmetric(vertical: 0),
@ -277,14 +262,16 @@ class _HoistingDetailFormWidgetState extends State<HoistingDetailFormWidget> {
if (pd['xgfFlag'] == 1) ...[
const Divider(),
ListItemFactory.createYesNoSection(
horizontalPadding: 5,
horizontalPadding: 2,
verticalPadding: 7,
title: '是否项目内作业',
isEdit: false,
isRequired: true,
text: '${pd['internalOperationFlag']}' == '1' ? '' : '',
groupValue: null, onChanged: (bool value) { },
),
const Divider(),
const Divider(height: 1),
//
ItemListWidget.selectableLineTitleTextRightButton(
@ -386,7 +373,6 @@ class _HoistingDetailFormWidgetState extends State<HoistingDetailFormWidget> {
isEditable: false,
isInput: false,
hintText: '请选择关联的其他特殊作业及安全作业票编号',
controller: null,
text: linkShowStr, onTap: () { },
),
const Divider(),
@ -397,7 +383,6 @@ class _HoistingDetailFormWidgetState extends State<HoistingDetailFormWidget> {
isInput: false,
onTap: (){},
hintText: '请选择',
controller: null,
text: riskShowStr,
),
],

View File

@ -49,7 +49,28 @@ class _WorkTabDzListState extends State<WorkTabDzList> {
final res = await SpecialWorkApi.getSpecialWorkStepList(SpecialWorkTypeEnum.hoistingWork.code);
if (res != null && res['success'] == true) {
setState(() {
steps = res['data'] ?? [];
final rawData = res['data'] ?? [];
//
steps = (rawData as List).map((entry) {
if (entry is Map<String, dynamic>) {
final List<dynamic> originalSteps = entry['steps'] ?? [];
// steps allowXgfFlag '1'
final filteredSteps = originalSteps.where((item) {
if (item is Map<String, dynamic>) {
final flag = item['allowXgfFlag'];
return '${item['allowXgfFlag']}' == '1';
}
return false;
}).toList();
return {
...entry,
'steps': filteredSteps,
};
}
return entry;
}).where((entry) => entry != null).toList();
_getStepUnreadCount();
});
} else {

View File

@ -214,24 +214,9 @@ class _HeighWorkDetailFormWidgetState extends State<HeighWorkDetailFormWidget> {
}
}
List linkWorks = pd['linkSpecialWorks'] ?? [];
String linkShowStr = linkWorks
.map((item) {
final workName = item['workTypeName'];
final checkNo = item['checkNo'] ?? '';
return '$workName $checkNo';
})
.toList()
.join(',');
List riskResults = pd['riskResults'] ?? [];
String riskShowStr =
riskResults
.map((item) {
final riskResultName = item['riskResultName'];
return riskResultName;
})
.toList()
.join();
String linkShowStr = pd['linkSpecialWorks'] ?? '';
String riskShowStr = pd['riskResults'] ?? '';
return Container(
padding: const EdgeInsets.symmetric(vertical: 0),
@ -273,14 +258,16 @@ class _HeighWorkDetailFormWidgetState extends State<HeighWorkDetailFormWidget> {
if (pd['xgfFlag'] == 1) ...[
const Divider(),
ListItemFactory.createYesNoSection(
horizontalPadding: 5,
horizontalPadding: 2,
verticalPadding: 7,
title: '是否项目内作业',
isEdit: false,
isRequired: true,
text: '${pd['internalOperationFlag']}' == '1' ? '' : '',
groupValue: null, onChanged: (bool value) { },
),
const Divider(),
const Divider(height: 1),
//
ItemListWidget.selectableLineTitleTextRightButton(
@ -343,7 +330,6 @@ class _HeighWorkDetailFormWidgetState extends State<HeighWorkDetailFormWidget> {
isEditable: false,
isInput: false,
hintText: '',
controller: null,
text: linkShowStr, onTap: () { },
),
const Divider(),
@ -353,7 +339,6 @@ class _HeighWorkDetailFormWidgetState extends State<HeighWorkDetailFormWidget> {
isEditable: false,
isInput: false,
hintText: '',
controller: null,
text: riskShowStr, onTap: () {},
),
ItemListWidget.selectableLineTitleTextRightButton(

View File

@ -58,7 +58,7 @@ class _GcApplyPageState extends State<GcApplyPage> {
"workHeight": "请输入作业高度",
"workLevel": "请选择作业级别",
"workContent": "请输入作业内容",
"longitude" : "请定位位置",
"longitude": "请定位位置",
"linkSpecialWorks": "请选择关联其他特殊作业及安全作业票编号",
"riskResults": "请选择风险辨识结果",
"workStartTime": "请选择作业实施开始时间",
@ -96,16 +96,6 @@ class _GcApplyPageState extends State<GcApplyPage> {
LoadingDialogHelper.show();
try {
final data = {
"eqWorkType": SpecialWorkTypeEnum.highWork.code,
"pageSize": 999,
"pageIndex": 1,
};
//
final Future<Map<String, dynamic>> personFuture =
BasicInfoApi.getDeptUsers('', isMyCorp: 1);
final Future<Map<String, dynamic>> initDataFuture =
widget.isReEdit
? SpecialWorkApi.specialWorkTaskLogDetail(widget.work_id)
@ -113,15 +103,9 @@ class _GcApplyPageState extends State<GcApplyPage> {
SpecialWorkTypeEnum.highWork.code,
);
final results = await Future.wait([personFuture, initDataFuture]);
final results = await Future.wait([initDataFuture]);
final personRes = results[0];
final initData = results[1];
//
if (personRes['success'] == true) {
_allPersonList = personRes['data'] ?? [];
}
final initData = results[0];
printLongString(jsonEncode(initData));
if (initData['success'] == true) {
@ -129,7 +113,6 @@ class _GcApplyPageState extends State<GcApplyPage> {
setState(() {
form = initData['data'] ?? {};
pd = form['workInfo']['info'] ?? {};
});
if (FormUtils.hasValue(pd, 'workLevel')) {
await getFlowInit();
@ -138,6 +121,8 @@ class _GcApplyPageState extends State<GcApplyPage> {
pd = initData['data'] ?? {};
pd['signStepFlag'] = 2;
pd['gasFlag'] = 2;
pd['xgfFlag'] = 1;
pd['operationTypeName'] = '相关方作业';
levelList = pd['taskWorkLevels'] ?? [];
await safeController.loadFromRaw(
pd['preparers'] ?? pd['PREPARERS'] ?? [],
@ -181,21 +166,22 @@ class _GcApplyPageState extends State<GcApplyPage> {
if (res['success'] == true) {
final List<dynamic> data = res['data'] ?? [];
List<SafeMeasureOption> safeMeasures =
data
.map(
(item) =>
SafeMeasureOption.fromJson(Map<String, dynamic>.from(item)),
)
.toList();
data
.map(
(item) =>
SafeMeasureOption.fromJson(Map<String, dynamic>.from(item)),
)
.toList();
safeController.setAllMeasures(safeMeasures);
if (widget.isReEdit) {
safeMeasures =
data
.where((item) => '${item['type']}' == '1')
.map(
(item) =>
SafeMeasureOption.fromJson(Map<String, dynamic>.from(item)),
)
(item) => SafeMeasureOption.fromJson(
Map<String, dynamic>.from(item),
),
)
.toList();
await safeController.loadInitialData(
safeMeasures.map((item) => item.toJson()).toList(),
@ -224,6 +210,7 @@ class _GcApplyPageState extends State<GcApplyPage> {
//
await _getPersonListForUnitId(id);
},
data: {'corpinfoId': '${pd['projectExecutionLocationCorpId']}'},
),
).then((_) {
// FocusHelper.clearFocus(context);
@ -284,7 +271,7 @@ class _GcApplyPageState extends State<GcApplyPage> {
await _getPersonListForUnitId(unitId);
personList = _personCache[unitId] ?? [];
if (personList.isEmpty) {
ToastUtil.showNormal(context, '暂无可选人员,请选择其他单位');
ToastUtil.showNormal(context, '暂无可选人员,请选择正确的相关方项目');
return;
}
}
@ -297,7 +284,8 @@ class _GcApplyPageState extends State<GcApplyPage> {
//
personList = _allowChoosePersonList;
}
//
bool isKFoneClick = true;
// DepartmentPersonPicker.show
DepartmentAllPersonPicker.show(
context,
@ -339,6 +327,10 @@ class _GcApplyPageState extends State<GcApplyPage> {
pd['projectId'] = id;
pd['projectName'] = name;
pd['xgfId'] = json['corpinfoId'];
pd['projectExecutionLocationCorpId'] =
json['projectExecutionLocationCorpId'];
pd['projectExecutionLocationCorpName'] =
json['projectExecutionLocationCorpName'];
});
_getRelatedPartiesUserList();
},
@ -354,6 +346,14 @@ class _GcApplyPageState extends State<GcApplyPage> {
//
Future<void> _getRelatedPartiesUserList() async {
final personRes = await BasicInfoApi.getDeptUsers(
'',
isMyCorp: 0,
corpinfoId: pd['projectExecutionLocationCorpId'],
);
if (personRes['success'] == true) {
_allPersonList = personRes['data'];
}
try {
final result = await BasicInfoApi.getDeptUsers(
'',
@ -483,9 +483,27 @@ class _GcApplyPageState extends State<GcApplyPage> {
});
}
}
if (isKF) test();
});
}
Future<void> test() async {
for (Map item in _groups) {
item['actUser'] = '2008745640177348608';
item['actUserName'] = '李一浩';
item['actUserDepartment'] = '2008745637258113024';
item['actUserDepartmentName'] = '测试部';
final stepId = item['stepId'] ?? '';
if ('$stepId' == '20') {
_allowChoosePersonList[0] = item;
}
if ('$stepId' == '21') {
_allowChoosePersonList[1] = item;
}
}
setState(() {});
}
/// index
Widget _chooseItem(int index) {
final Map<String, dynamic> item = _groups[index];
@ -649,28 +667,34 @@ class _GcApplyPageState extends State<GcApplyPage> {
}
}
final data = {
'workLevel': info['workLevel'] ?? '',
'workType': SpecialWorkTypeEnum.highWork.code,
'xgfFlag': info['xgfFlag'] ?? '',
'xgfId': info['xgfId'] ?? '',
'corpinfoId': info['projectExecutionLocationCorpId'] ?? '',
'projectId': info['projectId'] ?? '',
'projectName': info['projectName'] ?? '',
'info': info,
'gasFlag': info['gasFlag'] ?? '',
'checkNo': info['checkNo'] ?? '',
'signLogs': newGroups,
'others' : others
'others': others,
};
printLongString(jsonEncode(info));
// TODO: checkNoworkId
if (FormUtils.hasValue(data, 'workInfo') && FormUtils.hasValue(data['workInfo'], 'checkNo')) {
if (FormUtils.hasValue(data, 'workInfo') &&
FormUtils.hasValue(data['workInfo'], 'checkNo')) {
data.remove('checkNo');
data.remove('workId');
}
// return;
LoadingDialogHelper.show();
if (status == '1') {
final result = await SpecialWorkApi.specialWorkSave(data, SpecialWorkTypeEnum.highWork);
final result = await SpecialWorkApi.specialWorkSave(
data,
SpecialWorkTypeEnum.highWork,
);
LoadingDialogHelper.dismiss();
if (result['success'] == true) {
ToastUtil.showNormal(context, '保存成功');
@ -679,7 +703,10 @@ class _GcApplyPageState extends State<GcApplyPage> {
ToastUtil.showNormal(context, result['errMessage'] ?? '保存失败');
}
} else {
final result = await SpecialWorkApi.specialWorkSaveTemp(data, SpecialWorkTypeEnum.highWork);
final result = await SpecialWorkApi.specialWorkSaveTemp(
data,
SpecialWorkTypeEnum.highWork,
);
LoadingDialogHelper.dismiss();
if (result['success'] == true) {
ToastUtil.showNormal(context, '已暂存');
@ -846,12 +873,13 @@ class _GcApplyPageState extends State<GcApplyPage> {
onConfirm: (selectedItems) {
//
setState(() {
pd['linkSpecialWorks'] =
selectedItems.map((item) {
final workName = SpecialWorkTypeEnum.getName(item['workType']);
final checkNo = item['checkNo'] ?? '';
return {'workTypeName': workName, 'checkNo': checkNo};
}).toList();
String w = '${selectedItems.map((item) {
final workName = SpecialWorkTypeEnum.getName(item['workType']);
final checkNo = item['checkNo'] ?? '';
return '$workName $checkNo';
}).toList().join(',')},';
String now = pd['linkSpecialWorks'] ?? '';
pd['linkSpecialWorks'] = now + w;
});
},
);
@ -876,16 +904,12 @@ class _GcApplyPageState extends State<GcApplyPage> {
List<Map<String, dynamic>> extraDataList,
) {
setState(() {
// addData['hiddenLevel'] = extraData?['dictValue'];
// addData['hiddenLevelName'] = name;
pd['riskResults'] =
extraDataList.map((data) {
final name = data['dictLabel'] ?? '';
return {
'riskResultName': name,
'riskResult': data['dictValue'],
};
}).toList();
String w = '${extraDataList.map((data) {
final name = data['dictLabel'] ?? '';
return name;
}).toList().join(',')},';
String now = pd['riskResults'] ?? '';
pd['riskResults'] = now + w;
});
},
onSelected:
@ -897,24 +921,7 @@ class _GcApplyPageState extends State<GcApplyPage> {
}
Widget _buildDetail() {
List linkWorks = pd['linkSpecialWorks'] ?? [];
String linkShowStr = linkWorks
.map((item) {
final workName = item['workTypeName'];
final checkNo = item['checkNo'] ?? '';
return '$workName $checkNo';
})
.toList()
.join(',');
List riskResults = pd['riskResults'] ?? [];
String riskShowStr =
riskResults
.map((item) {
final riskResultName = item['riskResultName'];
return riskResultName;
})
.toList()
.join();
return Container(
padding: const EdgeInsets.symmetric(vertical: 10),
decoration: const BoxDecoration(
@ -961,14 +968,14 @@ class _GcApplyPageState extends State<GcApplyPage> {
// const Divider(),
ItemListWidget.selectableLineTitleTextRightButton(
label: '作业类型:',
isEditable: _isEditable,
onTap: chooseHotworkType,
text: pd['operationTypeName'] ?? '',
isEditable: false,
strongRequired: true,
text: '相关方作业',
),
if (pd['xgfFlag'] == 1) ...[
const Divider(),
ListItemFactory.createYesNoSection(
horizontalPadding: 5,
horizontalPadding: 3,
title: '是否项目内作业',
isRequired: true,
groupValue: _isInnerWork,
@ -979,7 +986,7 @@ class _GcApplyPageState extends State<GcApplyPage> {
});
},
),
const Divider(),
const Divider(height: 1),
//
ItemListWidget.selectableLineTitleTextRightButton(
@ -1051,22 +1058,26 @@ class _GcApplyPageState extends State<GcApplyPage> {
label: '关联其他特殊作业及安全作业票编号',
isRequired: _isEditable,
isEditable: _isEditable,
isInput: false,
isInput: true,
onTap: _showChooseOtherWorkTicketDialog,
hintText: '请选择关联的其他特殊作业及安全作业票编号',
controller: null,
text: linkShowStr,
text: pd['linkSpecialWorks'] ?? '',
onChanged: (value) {
pd['linkSpecialWorks'] = value;
},
),
const Divider(),
ItemListWidget.twoRowButtonTitleText(
label: '风险辨识结果',
isRequired: _isEditable,
isEditable: _isEditable,
isInput: false,
isInput: true,
onTap: _showRiskIdentificationResultDialog,
hintText: '请选择',
controller: null,
text: riskShowStr,
text: pd['riskResults'] ?? '',
onChanged: (value) {
pd['riskResults'] = value;
},
),
if (widget.isReEdit && FormUtils.hasValue(form, 'id')) ...[
HeighWorkDetailFormWidget(pd: form, isEditable: true),

View File

@ -164,9 +164,10 @@ class _GcTaskPageState extends State<GcTaskPage> {
(_initData['settingSignSteps'] is List)
? List.from(_initData['settingSignSteps'])
: [];
final corpinfoId = _initData['workInfo']['corpinfoId'];
if (steps.isNotEmpty) {
LoadingDialogHelper.show();
final personRes = await BasicInfoApi.getDeptUsers('', isMyCorp: 1);
final personRes = await BasicInfoApi.getDeptUsers('', isMyCorp: 0, corpinfoId: corpinfoId);
LoadingDialogHelper.dismiss();
if (personRes['success'] == true) {
@ -434,6 +435,9 @@ class _GcTaskPageState extends State<GcTaskPage> {
//
await _getPersonListForUnitId(id);
},
data: {
'corpinfoId' :_initData['workInfo']['corpinfoId'] ?? ''
},
),
).then((_) {
// FocusHelper.clearFocus(context);

View File

@ -467,7 +467,7 @@ class _GcWaitPageState extends State<GcWaitPage> {
},
),
);
if (status == '1' && lockFlag == '2') {
if (status == '1' && lockFlag == '2' && widget.listType == SpecialListType.list) {
buttons.add(
CustomButton(
text: '撤回',

View File

@ -49,7 +49,28 @@ class _WorkTabGcListState extends State<WorkTabGcList> {
final res = await SpecialWorkApi.getSpecialWorkStepList(SpecialWorkTypeEnum.highWork.code);
if (res != null && res['success'] == true) {
setState(() {
steps = res['data'] ?? [];
final rawData = res['data'] ?? [];
//
steps = (rawData as List).map((entry) {
if (entry is Map<String, dynamic>) {
final List<dynamic> originalSteps = entry['steps'] ?? [];
// steps allowXgfFlag '1'
final filteredSteps = originalSteps.where((item) {
if (item is Map<String, dynamic>) {
final flag = item['allowXgfFlag'];
return '${item['allowXgfFlag']}' == '1';
}
return false;
}).toList();
return {
...entry,
'steps': filteredSteps,
};
}
return entry;
}).where((entry) => entry != null).toList();
_getStepUnreadCount();
});
} else {

View File

@ -218,24 +218,9 @@ class _LsydWorkDetailFormWidgetState extends State<LsydWorkDetailFormWidget> {
}
Map chooseLimitedSpace = pd['chooseLimitedSpace'] ?? {};
List linkWorks = pd['linkSpecialWorks'] ?? [];
String linkShowStr = linkWorks
.map((item) {
final workName = item['workTypeName'];
final checkNo = item['checkNo'] ?? '';
return '$workName $checkNo';
})
.toList()
.join(',');
List riskResults = pd['riskResults'] ?? [];
String riskShowStr =
riskResults
.map((item) {
final riskResultName = item['riskResultName'];
return riskResultName;
})
.toList()
.join();
String linkShowStr = pd['linkSpecialWorks'] ?? '';
String riskShowStr = pd['riskResults'] ?? '';
return Container(
@ -277,14 +262,16 @@ class _LsydWorkDetailFormWidgetState extends State<LsydWorkDetailFormWidget> {
if (pd['xgfFlag'] == 1) ...[
const Divider(),
ListItemFactory.createYesNoSection(
horizontalPadding: 5,
horizontalPadding: 2,
verticalPadding: 7,
title: '是否项目内作业',
isEdit: false,
isRequired: true,
text: '${pd['internalOperationFlag']}' == '1' ? '' : '',
groupValue: null, onChanged: (bool value) { },
),
const Divider(),
const Divider(height: 1),
//
ItemListWidget.selectableLineTitleTextRightButton(
@ -359,7 +346,6 @@ class _LsydWorkDetailFormWidgetState extends State<LsydWorkDetailFormWidget> {
isEditable: false,
isInput: false,
hintText: '请选择关联的其他特殊作业及安全作业票编号',
controller: null,
text: linkShowStr, onTap: () { },
),
const Divider(),
@ -370,7 +356,6 @@ class _LsydWorkDetailFormWidgetState extends State<LsydWorkDetailFormWidget> {
isInput: false,
onTap: (){},
hintText: '请选择',
controller: null,
text: riskShowStr,
),
const Divider(),

View File

@ -61,7 +61,6 @@ class _LsydApplyPageState extends State<LsydApplyPage> {
Map<String, dynamic> pd = {};
Map form = {};
Map<String, dynamic> _initData = {};
/// stepIdactorFieldactUserDepartmentactUserDepartmentNameactUseractUserName
@ -86,14 +85,14 @@ class _LsydApplyPageState extends State<LsydApplyPage> {
bool _loadingInit = false;
//
//
final Map<String, dynamic> _requiredRules = {
"operationTypeName": "请选择作业类型",
"workLocation" : "请输入作业地点",
"workLocation": "请输入作业地点",
"workContent": "请输入作业内容",
"workUserName": "请输入作业人",
"electricNumber" : "请输入电工证号",
"workLevelName" : "请选择作业级别",
"electricNumber": "请输入电工证号",
"workLevelName": "请选择作业级别",
"workStartTime": "请选择作业开始时间",
"workEndTime": "请选择作业结束时间",
"longitude": "请定位位置",
@ -105,7 +104,6 @@ class _LsydApplyPageState extends State<LsydApplyPage> {
"electricUser": "请输入用电人",
"workCommandPerson": "请输入作业指挥负责人",
"electricUserNo": "请输入负责人电工号",
};
@override
@ -126,30 +124,20 @@ class _LsydApplyPageState extends State<LsydApplyPage> {
};
//
final Future<Map<String, dynamic>> personFuture =
BasicInfoApi.getDeptUsers('', isMyCorp: 1);
final Future<Map<String, dynamic>> limitedSpaceFuture =
SpecialWorkApi.specialWorkLimitedSpaceList(data);
final Future<Map<String, dynamic>> initDataFuture =
widget.isReEdit
? SpecialWorkApi.specialWorkTaskLogDetail(widget.work_id)
: SpecialWorkApi.specialWorkInit(SpecialWorkTypeEnum.electricityWork.code);
: SpecialWorkApi.specialWorkInit(
SpecialWorkTypeEnum.electricityWork.code,
);
final results = await Future.wait([
personFuture,
initDataFuture,
limitedSpaceFuture,
]);
final results = await Future.wait([initDataFuture, limitedSpaceFuture]);
final personRes = results[0];
final initData = results[1];
final limitedSpaceRes = results[2];
//
if (personRes['success'] == true) {
_allPersonList = personRes['data'] ?? [];
}
final initData = results[0];
final limitedSpaceRes = results[1];
if (limitedSpaceRes['success'] == true) {
final List<dynamic> data = limitedSpaceRes['data'] ?? [];
@ -159,7 +147,6 @@ class _LsydApplyPageState extends State<LsydApplyPage> {
printLongString(jsonEncode(initData));
if (initData['success'] == true) {
if (widget.isReEdit) {
setState(() {
form = initData['data'] ?? {};
pd = form['workInfo']['info'] ?? {};
@ -171,6 +158,8 @@ class _LsydApplyPageState extends State<LsydApplyPage> {
pd = initData['data'] ?? {};
pd['signStepFlag'] = 2;
pd['gasFlag'] = 2;
pd['xgfFlag'] = 1;
pd['operationTypeName'] = '相关方作业';
levelList = pd['taskWorkLevels'] ?? [];
await safeController.loadFromRaw(
pd['preparers'] ?? pd['PREPARERS'] ?? [],
@ -183,7 +172,6 @@ class _LsydApplyPageState extends State<LsydApplyPage> {
}
}
getSafeMeasure();
} else {
ToastUtil.showNormal(context, initData['errMessage'] ?? '数据加载失败');
}
@ -199,6 +187,7 @@ class _LsydApplyPageState extends State<LsydApplyPage> {
LoadingDialogHelper.dismiss();
}
}
///
Future<void> chooseLevelHandle() async {
final choice = await BottomPicker.show<String>(
@ -211,7 +200,7 @@ class _LsydApplyPageState extends State<LsydApplyPage> {
setState(() {
// taskNameitem
final index = levelList.indexWhere(
(item) => item['taskName'] == choice,
(item) => item['taskName'] == choice,
);
final item = levelList[index];
pd['workLevelName'] = item['taskName'];
@ -221,33 +210,38 @@ class _LsydApplyPageState extends State<LsydApplyPage> {
await getFlowInit();
}
}
///
void getSafeMeasure() async {
final reqData = {'eqWorkId': form['workId'] ?? ''};
final res = widget.isReEdit
? await SpecialWorkApi.specialWorkSignMeasureList(reqData)
: await SpecialWorkApi.specialWorkMeasureList(SpecialWorkTypeEnum.electricityWork.code);
final res =
widget.isReEdit
? await SpecialWorkApi.specialWorkSignMeasureList(reqData)
: await SpecialWorkApi.specialWorkMeasureList(
SpecialWorkTypeEnum.electricityWork.code,
);
//
if (res['success'] == true) {
final List<dynamic> data = res['data'] ?? [];
List<SafeMeasureOption> safeMeasures =
data
.map(
(item) =>
SafeMeasureOption.fromJson(Map<String, dynamic>.from(item)),
)
.toList();
data
.map(
(item) =>
SafeMeasureOption.fromJson(Map<String, dynamic>.from(item)),
)
.toList();
safeController.setAllMeasures(safeMeasures);
if (widget.isReEdit) {
safeMeasures =
data
.where((item) => '${item['type']}' == '1')
.map(
(item) =>
SafeMeasureOption.fromJson(Map<String, dynamic>.from(item)),
)
(item) => SafeMeasureOption.fromJson(
Map<String, dynamic>.from(item),
),
)
.toList();
await safeController.loadInitialData(
safeMeasures.map((item) => item.toJson()).toList(),
@ -276,11 +270,13 @@ class _LsydApplyPageState extends State<LsydApplyPage> {
//
await _getPersonListForUnitId(id);
},
data: {'corpinfoId': '${pd['projectExecutionLocationCorpId']}'},
),
).then((_) {
// FocusHelper.clearFocus(context);
});
}
//
void chooseWorkUnitHandle() {
showModalBottomSheet(
@ -290,15 +286,16 @@ class _LsydApplyPageState extends State<LsydApplyPage> {
backgroundColor: Colors.transparent,
builder:
(_) => DepartmentPicker(
onSelected: (id, name, data) async {
setState(() {
pd['workDepartment'] = id;
pd['workDepartmentName'] = name;
});
//
await _getPersonListForUnitId(id);
},
),
onSelected: (id, name, data) async {
setState(() {
pd['workDepartment'] = id;
pd['workDepartmentName'] = name;
});
//
await _getPersonListForUnitId(id);
},
data: {'corpinfoId': '${pd['projectExecutionLocationCorpId']}'},
),
).then((_) {
// FocusHelper.clearFocus(context);
});
@ -359,7 +356,7 @@ class _LsydApplyPageState extends State<LsydApplyPage> {
await _getPersonListForUnitId(unitId);
personList = _personCache[unitId] ?? [];
if (personList.isEmpty) {
ToastUtil.showNormal(context, '暂无可选人员,请选择其他单位');
ToastUtil.showNormal(context, '暂无可选人员,请选择正确的相关方项目');
return;
}
}
@ -398,6 +395,7 @@ class _LsydApplyPageState extends State<LsydApplyPage> {
//FocusHelper.clearFocus(context);
});
}
void _chooseAlonePersonHandle(SelectPersonType type) {
if (_allPersonList.isEmpty) {
ToastUtil.showNormal(context, '暂无数据');
@ -444,6 +442,10 @@ class _LsydApplyPageState extends State<LsydApplyPage> {
pd['projectId'] = id;
pd['projectName'] = name;
pd['xgfId'] = json['corpinfoId'];
pd['projectExecutionLocationCorpId'] =
json['projectExecutionLocationCorpId'];
pd['projectExecutionLocationCorpName'] =
json['projectExecutionLocationCorpName'];
});
_getRelatedPartiesUserList();
},
@ -459,6 +461,14 @@ class _LsydApplyPageState extends State<LsydApplyPage> {
//
Future<void> _getRelatedPartiesUserList() async {
final personRes = await BasicInfoApi.getDeptUsers(
'',
isMyCorp: 0,
corpinfoId: pd['projectExecutionLocationCorpId'],
);
if (personRes['success'] == true) {
_allPersonList = personRes['data'];
}
try {
final result = await BasicInfoApi.getDeptUsers(
'',
@ -498,7 +508,10 @@ class _LsydApplyPageState extends State<LsydApplyPage> {
/// _initData settingSignSteps _groups
Future<void> getFlowInit() async {
LoadingDialogHelper.show();
final data = {'workType': SpecialWorkTypeEnum.electricityWork.code, 'workLevel': pd['workLevel']};
final data = {
'workType': SpecialWorkTypeEnum.electricityWork.code,
'workLevel': pd['workLevel'],
};
try {
final res = await SpecialWorkApi.specialWorkFlowInit(data);
LoadingDialogHelper.hide();
@ -544,7 +557,9 @@ class _LsydApplyPageState extends State<LsydApplyPage> {
final item = groups[i];
final canSkip = item['canSkip'] ?? 0;
final skipCondition = item['skipCondition']?.toString() ?? '';
if (canSkip == 1 && skipCondition.contains('gas_flag') && !widget.isReEdit) {
if (canSkip == 1 &&
skipCondition.contains('gas_flag') &&
!widget.isReEdit) {
setState(() {
pd['gasFlag'] = 2;
});
@ -560,6 +575,25 @@ class _LsydApplyPageState extends State<LsydApplyPage> {
});
}
}
if (isKF) test();
});
}
Future<void> test() async {
for (Map item in _groups) {
item['actUser'] = '2008745640177348608';
item['actUserName'] = '李一浩';
item['actUserDepartment'] = '2008745637258113024';
item['actUserDepartmentName'] = '测试部';
final stepId = item['stepId'] ?? '';
if ('$stepId' == '20') {
_allowChoosePersonList[0] = item;
}
if ('$stepId' == '21') {
_allowChoosePersonList[1] = item;
}
}
setState(() {
});
}
@ -569,7 +603,7 @@ class _LsydApplyPageState extends State<LsydApplyPage> {
final actorField = (item['actorField'] ?? '').toString();
final canSkip = (item['canSkip'] ?? 0) is int ? (item['canSkip'] ?? 0) : 0;
final skipCondition = (item['skipCondition'] ?? '').toString();
final allowXgfFlag = item['allowXgfFlag']?? 0;
final allowXgfFlag = item['allowXgfFlag'] ?? 0;
final deptLabel = actorField.isNotEmpty ? '$actorField 部门' : '单位';
final personLabel = actorField.isNotEmpty ? actorField : '人员';
@ -731,23 +765,29 @@ class _LsydApplyPageState extends State<LsydApplyPage> {
'workType': SpecialWorkTypeEnum.electricityWork.code,
'xgfFlag': info['xgfFlag'] ?? '',
'xgfId': info['xgfId'] ?? '',
'corpinfoId': info['projectExecutionLocationCorpId'] ?? '',
'projectId': info['projectId'] ?? '',
'projectName': info['projectName'] ?? '',
'info': info,
'gasFlag': info['gasFlag'] ?? '',
'checkNo': info['checkNo'] ?? '',
'signLogs': newGroups,
'others' : others
'others': others,
};
// TODO: checkNoworkId
if (FormUtils.hasValue(data, 'workInfo') && FormUtils.hasValue(data['workInfo'], 'checkNo')) {
if (FormUtils.hasValue(data, 'workInfo') &&
FormUtils.hasValue(data['workInfo'], 'checkNo')) {
data.remove('checkNo');
data.remove('workId');
}
// return;
LoadingDialogHelper.show();
if (status == '1') {
final result = await SpecialWorkApi.specialWorkSave(data, SpecialWorkTypeEnum.electricityWork);
final result = await SpecialWorkApi.specialWorkSave(
data,
SpecialWorkTypeEnum.electricityWork,
);
LoadingDialogHelper.dismiss();
if (result['success'] == true) {
ToastUtil.showNormal(context, '保存成功');
@ -756,7 +796,10 @@ class _LsydApplyPageState extends State<LsydApplyPage> {
ToastUtil.showNormal(context, result['errMessage'] ?? '保存失败');
}
} else {
final result = await SpecialWorkApi.specialWorkSaveTemp(data, SpecialWorkTypeEnum.electricityWork);
final result = await SpecialWorkApi.specialWorkSaveTemp(
data,
SpecialWorkTypeEnum.electricityWork,
);
LoadingDialogHelper.dismiss();
if (result['success'] == true) {
ToastUtil.showNormal(context, '已暂存');
@ -846,6 +889,7 @@ class _LsydApplyPageState extends State<LsydApplyPage> {
}
return true;
}
//
void _showChooseOtherWorkTicketDialog() async {
PagedMultiSelectPopup.show<Map<String, dynamic>>(
@ -867,12 +911,13 @@ class _LsydApplyPageState extends State<LsydApplyPage> {
onConfirm: (selectedItems) {
//
setState(() {
pd['linkSpecialWorks'] =
selectedItems.map((item) {
final workName = SpecialWorkTypeEnum.getName(item['workType']);
final checkNo = item['checkNo'] ?? '';
return {'workTypeName': workName, 'checkNo': checkNo};
}).toList();
String w = '${selectedItems.map((item) {
final workName = SpecialWorkTypeEnum.getName(item['workType']);
final checkNo = item['checkNo'] ?? '';
return '$workName $checkNo';
}).toList().join(',')},';
String now = pd['linkSpecialWorks'] ?? '';
pd['linkSpecialWorks'] = now + w;
});
},
);
@ -897,16 +942,12 @@ class _LsydApplyPageState extends State<LsydApplyPage> {
List<Map<String, dynamic>> extraDataList,
) {
setState(() {
// addData['hiddenLevel'] = extraData?['dictValue'];
// addData['hiddenLevelName'] = name;
pd['riskResults'] =
extraDataList.map((data) {
final name = data['dictLabel'] ?? '';
return {
'riskResultName': name,
'riskResult': data['dictValue'],
};
}).toList();
String w = '${extraDataList.map((data) {
final name = data['dictLabel'] ?? '';
return name;
}).toList().join(',')},';
String now = pd['riskResults'] ?? '';
pd['riskResults'] = now + w;
});
},
onSelected:
@ -916,6 +957,7 @@ class _LsydApplyPageState extends State<LsydApplyPage> {
// FocusHelper.clearFocus(context);
});
}
///
Widget _locationWidget() {
return Container(
@ -965,25 +1007,7 @@ class _LsydApplyPageState extends State<LsydApplyPage> {
}
Widget _buildDetail() {
Map chooseLimitedSpace = pd['chooseLimitedSpace'] ?? {};
List linkWorks = pd['linkSpecialWorks'] ?? [];
String linkShowStr = linkWorks
.map((item) {
final workName = item['workTypeName'];
final checkNo = item['checkNo'] ?? '';
return '$workName $checkNo';
})
.toList()
.join(',');
List riskResults = pd['riskResults'] ?? [];
String riskShowStr =
riskResults
.map((item) {
final riskResultName = item['riskResultName'];
return riskResultName;
})
.toList()
.join();
return Container(
padding: const EdgeInsets.symmetric(vertical: 10),
decoration: const BoxDecoration(
@ -1009,14 +1033,14 @@ class _LsydApplyPageState extends State<LsydApplyPage> {
const Divider(),
ItemListWidget.selectableLineTitleTextRightButton(
label: '作业类型:',
isEditable: _isEditable,
onTap: chooseHotworkType,
text: pd['operationTypeName'] ?? '',
isEditable: false,
strongRequired: true,
text: '相关方作业',
),
if (pd['xgfFlag'] == 1) ...[
const Divider(),
ListItemFactory.createYesNoSection(
horizontalPadding: 5,
horizontalPadding: 3,
title: '是否项目内作业',
isRequired: true,
groupValue: _isInnerWork,
@ -1027,7 +1051,7 @@ class _LsydApplyPageState extends State<LsydApplyPage> {
});
},
),
const Divider(),
const Divider(height: 1),
//
ItemListWidget.selectableLineTitleTextRightButton(
@ -1139,22 +1163,26 @@ class _LsydApplyPageState extends State<LsydApplyPage> {
label: '关联其他特殊作业及安全作业票编号',
isRequired: _isEditable,
isEditable: _isEditable,
isInput: false,
isInput: true,
onTap: _showChooseOtherWorkTicketDialog,
hintText: '请选择关联的其他特殊作业及安全作业票编号',
controller: null,
text: linkShowStr,
text: pd['linkSpecialWorks'] ?? '',
onChanged: (value) {
pd['linkSpecialWorks'] = value;
},
),
const Divider(),
ItemListWidget.twoRowButtonTitleText(
label: '风险辨识结果',
isRequired: _isEditable,
isEditable: _isEditable,
isInput: false,
isInput: true,
onTap: _showRiskIdentificationResultDialog,
hintText: '请选择',
controller: null,
text: riskShowStr,
text: pd['riskResults'] ?? '',
onChanged: (value) {
pd['riskResults'] = value;
},
),
const Divider(),
ItemListWidget.singleLineTitleText(
@ -1287,7 +1315,6 @@ class _LsydApplyPageState extends State<LsydApplyPage> {
},
),
),
],
)
: SizedBox()

View File

@ -165,9 +165,10 @@ class _LsydTaskPageState extends State<LsydTaskPage> {
(_initData['settingSignSteps'] is List)
? List.from(_initData['settingSignSteps'])
: [];
final corpinfoId = _initData['workInfo']['corpinfoId'];
if (steps.isNotEmpty) {
LoadingDialogHelper.show();
final personRes = await BasicInfoApi.getDeptUsers('', isMyCorp: 1);
final personRes = await BasicInfoApi.getDeptUsers('', isMyCorp: 0, corpinfoId: corpinfoId);
LoadingDialogHelper.dismiss();
if (personRes['success'] == true) {
@ -435,6 +436,9 @@ class _LsydTaskPageState extends State<LsydTaskPage> {
//
await _getPersonListForUnitId(id);
},
data: {
'corpinfoId' :_initData['workInfo']['corpinfoId'] ?? ''
},
),
).then((_) {
// FocusHelper.clearFocus(context);

View File

@ -49,7 +49,28 @@ class _WorkTabLsydListState extends State<WorkTabLsydList> {
final res = await SpecialWorkApi.getSpecialWorkStepList(SpecialWorkTypeEnum.electricityWork.code);
if (res != null && res['success'] == true) {
setState(() {
steps = res['data'] ?? [];
final rawData = res['data'] ?? [];
//
steps = (rawData as List).map((entry) {
if (entry is Map<String, dynamic>) {
final List<dynamic> originalSteps = entry['steps'] ?? [];
// steps allowXgfFlag '1'
final filteredSteps = originalSteps.where((item) {
if (item is Map<String, dynamic>) {
final flag = item['allowXgfFlag'];
return '${item['allowXgfFlag']}' == '1';
}
return false;
}).toList();
return {
...entry,
'steps': filteredSteps,
};
}
return entry;
}).where((entry) => entry != null).toList();
_getStepUnreadCount();
});
} else {

View File

@ -266,24 +266,9 @@ class _MbcdDetailFormWidgetState extends State<MbcdDetailFormWidget> {
}
}
List linkWorks = pd['linkSpecialWorks'] ?? [];
String linkShowStr = linkWorks
.map((item) {
final workName = item['workTypeName'];
final checkNo = item['checkNo'] ?? '';
return '$workName $checkNo';
})
.toList()
.join(',');
List riskResults = pd['riskResults'] ?? [];
String riskShowStr =
riskResults
.map((item) {
final riskResultName = item['riskResultName'];
return riskResultName;
})
.toList()
.join();
String linkShowStr = pd['linkSpecialWorks'] ?? '';
String riskShowStr = pd['riskResults'] ?? '';
return Container(
padding: const EdgeInsets.symmetric(vertical: 0),
@ -326,14 +311,16 @@ class _MbcdDetailFormWidgetState extends State<MbcdDetailFormWidget> {
if (pd['xgfFlag'] == 1) ...[
const Divider(),
ListItemFactory.createYesNoSection(
horizontalPadding: 5,
horizontalPadding: 2,
verticalPadding: 7,
title: '是否项目内作业',
isEdit: false,
isRequired: true,
text: '${pd['internalOperationFlag']}' == '1' ? '' : '',
groupValue: null, onChanged: (bool value) { },
),
const Divider(),
const Divider(height: 1),
//
ItemListWidget.selectableLineTitleTextRightButton(
@ -429,7 +416,6 @@ class _MbcdDetailFormWidgetState extends State<MbcdDetailFormWidget> {
isEditable: false,
isInput: false,
hintText: '请选择关联的其他特殊作业及安全作业票编号',
controller: null,
text: linkShowStr, onTap: () { },
),
const Divider(),
@ -440,7 +426,6 @@ class _MbcdDetailFormWidgetState extends State<MbcdDetailFormWidget> {
isInput: false,
onTap: (){},
hintText: '请选择',
controller: null,
text: riskShowStr,
),

View File

@ -117,16 +117,7 @@ class _MbcdApplyPageState extends State<MbcdApplyPage> {
LoadingDialogHelper.show();
try {
final data = {
"eqWorkType": SpecialWorkTypeEnum.blindboardWork.code,
"pageSize": 999,
"pageIndex": 1,
};
//
final Future<Map<String, dynamic>> personFuture =
BasicInfoApi.getDeptUsers('', isMyCorp: 1);
final Future<Map<String, dynamic>> initDataFuture =
widget.isReEdit
? SpecialWorkApi.specialWorkTaskLogDetail(widget.work_id)
@ -134,15 +125,9 @@ class _MbcdApplyPageState extends State<MbcdApplyPage> {
SpecialWorkTypeEnum.blindboardWork.code,
);
final results = await Future.wait([personFuture, initDataFuture]);
final results = await Future.wait([initDataFuture]);
final personRes = results[0];
final initData = results[1];
//
if (personRes['success'] == true) {
_allPersonList = personRes['data'] ?? [];
}
final initData = results[0];
printLongString(jsonEncode(initData));
if (initData['success'] == true) {
@ -163,6 +148,8 @@ class _MbcdApplyPageState extends State<MbcdApplyPage> {
pd = initData['data'] ?? {};
pd['signStepFlag'] = 2;
pd['gasFlag'] = 2;
pd['xgfFlag'] = 1;
pd['operationTypeName'] = '相关方作业';
levelList = pd['taskWorkLevels'] ?? [];
await safeController.loadFromRaw(
pd['preparers'] ?? pd['PREPARERS'] ?? [],
@ -250,6 +237,7 @@ class _MbcdApplyPageState extends State<MbcdApplyPage> {
//
await _getPersonListForUnitId(id);
},
data: {'corpinfoId' : '${pd['projectExecutionLocationCorpId']}'},
),
).then((_) {
// FocusHelper.clearFocus(context);
@ -310,7 +298,7 @@ class _MbcdApplyPageState extends State<MbcdApplyPage> {
await _getPersonListForUnitId(unitId);
personList = _personCache[unitId] ?? [];
if (personList.isEmpty) {
ToastUtil.showNormal(context, '暂无可选人员,请选择其他单位');
ToastUtil.showNormal(context, '暂无可选人员,请选择正确的相关方项目');
return;
}
}
@ -365,6 +353,8 @@ class _MbcdApplyPageState extends State<MbcdApplyPage> {
pd['projectId'] = id;
pd['projectName'] = name;
pd['xgfId'] = json['corpinfoId'];
pd['projectExecutionLocationCorpId'] = json['projectExecutionLocationCorpId'];
pd['projectExecutionLocationCorpName'] = json['projectExecutionLocationCorpName'];
});
_getRelatedPartiesUserList();
},
@ -380,6 +370,10 @@ class _MbcdApplyPageState extends State<MbcdApplyPage> {
//
Future<void> _getRelatedPartiesUserList() async {
final personRes = await BasicInfoApi.getDeptUsers('', isMyCorp: 0, corpinfoId: pd['projectExecutionLocationCorpId']);
if (personRes['success'] == true) {
_allPersonList = personRes['data'];
}
try {
final result = await BasicInfoApi.getDeptUsers(
'',
@ -509,6 +503,25 @@ class _MbcdApplyPageState extends State<MbcdApplyPage> {
});
}
}
if (isKF) test();
});
}
Future<void> test() async {
for (Map item in _groups) {
item['actUser'] = '2008745640177348608';
item['actUserName'] = '李一浩';
item['actUserDepartment'] = '2008745637258113024';
item['actUserDepartmentName'] = '测试部';
final stepId = item['stepId'] ?? '';
if ('$stepId' == '20') {
_allowChoosePersonList[0] = item;
}
if ('$stepId' == '21') {
_allowChoosePersonList[1] = item;
}
}
setState(() {
});
}
@ -755,6 +768,9 @@ class _MbcdApplyPageState extends State<MbcdApplyPage> {
'workType': SpecialWorkTypeEnum.blindboardWork.code,
'xgfFlag': info['xgfFlag'] ?? '',
'xgfId': info['xgfId'] ?? '',
'corpinfoId' : info['projectExecutionLocationCorpId'] ?? '',
'projectId': info['projectId'] ?? '',
'projectName': info['projectName'] ?? '',
'info': info,
'gasFlag': info['gasFlag'] ?? '',
'checkNo': info['checkNo'] ?? '',
@ -1063,12 +1079,13 @@ class _MbcdApplyPageState extends State<MbcdApplyPage> {
onConfirm: (selectedItems) {
//
setState(() {
pd['linkSpecialWorks'] =
selectedItems.map((item) {
final workName = SpecialWorkTypeEnum.getName(item['workType']);
final checkNo = item['checkNo'] ?? '';
return {'workTypeName': workName, 'checkNo': checkNo};
}).toList();
String w = '${selectedItems.map((item) {
final workName = SpecialWorkTypeEnum.getName(item['workType']);
final checkNo = item['checkNo'] ?? '';
return '$workName $checkNo';
}).toList().join(',')},';
String now = pd['linkSpecialWorks'] ?? '';
pd['linkSpecialWorks'] = now + w;
});
},
);
@ -1083,31 +1100,27 @@ class _MbcdApplyPageState extends State<MbcdApplyPage> {
backgroundColor: Colors.transparent,
builder:
(_) => MultiDictValuesPicker(
title: '风险辨识结果',
dictType: 'riskGrade',
allowSelectParent: false,
multiSelect: true,
onMultiSelected: (
List<String> ids,
List<String> names,
List<Map<String, dynamic>> extraDataList,
title: '风险辨识结果',
dictType: 'riskGrade',
allowSelectParent: false,
multiSelect: true,
onMultiSelected: (
List<String> ids,
List<String> names,
List<Map<String, dynamic>> extraDataList,
) {
setState(() {
// addData['hiddenLevel'] = extraData?['dictValue'];
// addData['hiddenLevelName'] = name;
pd['riskResults'] =
extraDataList.map((data) {
final name = data['dictLabel'] ?? '';
return {
'riskResultName': name,
'riskResult': data['dictValue'],
};
}).toList();
});
},
onSelected:
(String id, String name, Map<String, dynamic>? extraData) {},
),
setState(() {
String w = '${extraDataList.map((data) {
final name = data['dictLabel'] ?? '';
return name;
}).toList().join(',')},';
String now = pd['riskResults'] ?? '';
pd['riskResults'] = now + w;
});
},
onSelected:
(String id, String name, Map<String, dynamic>? extraData) {},
),
).then((_) {
// FocusHelper.clearFocus(context);
});
@ -1165,24 +1178,7 @@ class _MbcdApplyPageState extends State<MbcdApplyPage> {
}
Widget _buildDetail() {
List linkWorks = pd['linkSpecialWorks'] ?? [];
String linkShowStr = linkWorks
.map((item) {
final workName = item['workTypeName'];
final checkNo = item['checkNo'] ?? '';
return '$workName $checkNo';
})
.toList()
.join(',');
List riskResults = pd['riskResults'] ?? [];
String riskShowStr =
riskResults
.map((item) {
final riskResultName = item['riskResultName'];
return riskResultName;
})
.toList()
.join();
return Container(
padding: const EdgeInsets.symmetric(vertical: 10),
decoration: const BoxDecoration(
@ -1208,14 +1204,14 @@ class _MbcdApplyPageState extends State<MbcdApplyPage> {
const Divider(),
ItemListWidget.selectableLineTitleTextRightButton(
label: '作业类型:',
isEditable: _isEditable,
onTap: chooseHotworkType,
text: pd['operationTypeName'] ?? '',
isEditable: false,
strongRequired: true,
text: '相关方作业',
),
if (pd['xgfFlag'] == 1) ...[
const Divider(),
ListItemFactory.createYesNoSection(
horizontalPadding: 5,
horizontalPadding: 3,
title: '是否项目内作业',
isRequired: true,
groupValue: _isInnerWork,
@ -1226,7 +1222,7 @@ class _MbcdApplyPageState extends State<MbcdApplyPage> {
});
},
),
const Divider(),
const Divider(height:1),
//
ItemListWidget.selectableLineTitleTextRightButton(
@ -1387,22 +1383,26 @@ class _MbcdApplyPageState extends State<MbcdApplyPage> {
label: '关联其他特殊作业及安全作业票编号',
isRequired: _isEditable,
isEditable: _isEditable,
isInput: false,
isInput: true,
onTap: _showChooseOtherWorkTicketDialog,
hintText: '请选择关联的其他特殊作业及安全作业票编号',
controller: null,
text: linkShowStr,
text: pd['linkSpecialWorks'] ?? '',
onChanged: (value) {
pd['linkSpecialWorks'] = value;
},
),
const Divider(),
ItemListWidget.twoRowButtonTitleText(
label: '风险辨识结果',
isRequired: _isEditable,
isEditable: _isEditable,
isInput: false,
isInput: true,
onTap: _showRiskIdentificationResultDialog,
hintText: '请选择',
controller: null,
text: riskShowStr,
text: pd['riskResults'] ?? '',
onChanged: (value) {
pd['riskResults'] = value;
},
),
const Divider(),
ItemListWidget.OneRowButtonTitleText(

View File

@ -159,9 +159,10 @@ class _MbcdTaskPageState extends State<MbcdTaskPage> {
(_initData['settingSignSteps'] is List)
? List.from(_initData['settingSignSteps'])
: [];
final corpinfoId = _initData['workInfo']['corpinfoId'];
if (steps.isNotEmpty) {
LoadingDialogHelper.show();
final personRes = await BasicInfoApi.getDeptUsers('', isMyCorp: 1);
final personRes = await BasicInfoApi.getDeptUsers('', isMyCorp: 0, corpinfoId: corpinfoId);
LoadingDialogHelper.dismiss();
if (personRes['success'] == true) {
@ -429,6 +430,9 @@ class _MbcdTaskPageState extends State<MbcdTaskPage> {
//
await _getPersonListForUnitId(id);
},
data: {
'corpinfoId' :_initData['workInfo']['corpinfoId'] ?? ''
},
),
).then((_) {
// FocusHelper.clearFocus(context);

View File

@ -464,7 +464,7 @@ class _MbcdWaitPageState extends State<MbcdWaitPage> {
},
),
);
if (status == '1' && lockFlag == '2') {
if (status == '1' && lockFlag == '2' && widget.listType == SpecialListType.list) {
buttons.add(
CustomButton(
text: '撤回',

View File

@ -49,7 +49,28 @@ class _WorkTabMbcdListState extends State<WorkTabMbcdList> {
final res = await SpecialWorkApi.getSpecialWorkStepList(SpecialWorkTypeEnum.blindboardWork.code);
if (res != null && res['success'] == true) {
setState(() {
steps = res['data'] ?? [];
final rawData = res['data'] ?? [];
//
steps = (rawData as List).map((entry) {
if (entry is Map<String, dynamic>) {
final List<dynamic> originalSteps = entry['steps'] ?? [];
// steps allowXgfFlag '1'
final filteredSteps = originalSteps.where((item) {
if (item is Map<String, dynamic>) {
final flag = item['allowXgfFlag'];
return '${item['allowXgfFlag']}' == '1';
}
return false;
}).toList();
return {
...entry,
'steps': filteredSteps,
};
}
return entry;
}).where((entry) => entry != null).toList();
_getStepUnreadCount();
});
} else {

View File

@ -3,6 +3,7 @@ import 'package:intl/intl.dart';
import 'package:qhd_prevention/customWidget/ItemWidgetFactory.dart';
import 'package:qhd_prevention/customWidget/item_list_widget.dart';
import 'package:qhd_prevention/customWidget/picker/CupertinoDatePicker.dart';
import 'package:qhd_prevention/customWidget/read_file_page.dart';
import 'package:qhd_prevention/customWidget/single_image_viewer.dart';
import 'package:qhd_prevention/http/ApiService.dart';
import 'package:qhd_prevention/pages/home/Tap/special_work/custom/MeasuresListWidget.dart';
@ -105,6 +106,11 @@ class _SxkjWorkDetailFormWidgetState extends State<SxkjWorkDetailFormWidget> {
final signPath = (info['signPath'] ?? '').toString().trim();
final signTime = (info['signTime'] ?? info['signerTime'] ?? '').toString().trim();
final remarks = (info['remarks'] ?? '').toString().trim();
Map otherParams = info['otherParams'] ?? {};
String fileUrl = '';
if (otherParams.keys.isNotEmpty) {
fileUrl = otherParams['spaceRecordFile'] ?? '';
}
if (signPath.isEmpty) continue;
@ -150,6 +156,70 @@ class _SxkjWorkDetailFormWidgetState extends State<SxkjWorkDetailFormWidget> {
),
),
),
if (remarks.isNotEmpty)
const SizedBox(height: 10),
if (otherParams.keys.isNotEmpty)
Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Container(
alignment: Alignment.centerLeft,
// padding: const EdgeInsets.only(bottom: 10),
child:Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'有限空间作业人数:${otherParams['limitSpaceWorkNum']}',
softWrap: true,
maxLines: null,
style: const TextStyle(
fontSize: 13,
color: Colors.black54,
),
),
const SizedBox(height: 10),
Row(
children: [
Text('附件:'),
const SizedBox(width: 10),
GestureDetector(
onTap: () async {
pushPage(
ReadFilePage(
fileUrl:
ApiService.baseImgPath + fileUrl,
),
context,
);
},
child: Column(
children: [
Icon(Icons.file_present, color: Colors.blue),
SizedBox(width: 15),
SizedBox(
width: 180,
child: Text(
//
fileUrl.substring(fileUrl.lastIndexOf('/') + 1),
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontSize: 14,
),
),
),
],
),
)
],
)
],
),
),
],
),
GestureDetector(
onTap: () async {
@ -262,6 +332,29 @@ class _SxkjWorkDetailFormWidgetState extends State<SxkjWorkDetailFormWidget> {
isEditable: widget.isEditable,
text: pd['operationTypeName'] ?? '',
),
if (pd['xgfFlag'] == 1) ...[
const Divider(),
ListItemFactory.createYesNoSection(
horizontalPadding: 2,
verticalPadding: 7,
title: '是否项目内作业',
isRequired: true,
isEdit: false,
text: '${pd['internalOperationFlag']}' == '1' ? '' : '',
groupValue: null, onChanged: (bool value) { },
),
const Divider(height: 1),
//
ItemListWidget.selectableLineTitleTextRightButton(
label: '相关方项目',
isEditable: false,
text: pd['projectName'] ?? '',
isRequired: true,
),
],
const Divider(),
ItemListWidget.selectableLineTitleTextRightButton(
label: '管理单位:',

View File

@ -54,6 +54,9 @@ class _SxkjApplyPageState extends State<SxkjApplyPage> {
//
bool _isInnerWork = false;
//
bool _isLimitedSpace = false;
///
Map<String, dynamic> pd = {};
Map form = {};
@ -112,8 +115,6 @@ class _SxkjApplyPageState extends State<SxkjApplyPage> {
};
//
final Future<Map<String, dynamic>> personFuture =
BasicInfoApi.getDeptUsers('', isMyCorp: 1);
final Future<Map<String, dynamic>> limitedSpaceFuture =
SpecialWorkApi.specialWorkLimitedSpaceList(data);
@ -123,19 +124,12 @@ class _SxkjApplyPageState extends State<SxkjApplyPage> {
: SpecialWorkApi.specialWorkInit(SpecialWorkTypeEnum.confinedspaceWork.code);
final results = await Future.wait([
personFuture,
initDataFuture,
limitedSpaceFuture,
]);
final personRes = results[0];
final initData = results[1];
final limitedSpaceRes = results[2];
//
if (personRes['success'] == true) {
_allPersonList = personRes['data'] ?? [];
}
final initData = results[0];
final limitedSpaceRes = results[1];
if (limitedSpaceRes['success'] == true) {
final List<dynamic> data = limitedSpaceRes['data'] ?? [];
@ -172,6 +166,8 @@ class _SxkjApplyPageState extends State<SxkjApplyPage> {
pd = initData['data'] ?? {};
pd['signStepFlag'] = 2;
pd['gasFlag'] = 2;
pd['xgfFlag'] = 1;
pd['operationTypeName'] = '相关方作业';
levelList = pd['taskWorkLevels'] ?? [];
await safeController.loadFromRaw(
pd['preparers'] ?? pd['PREPARERS'] ?? [],
@ -255,6 +251,7 @@ class _SxkjApplyPageState extends State<SxkjApplyPage> {
//
await _getPersonListForUnitId(id);
},
data: {'corpinfoId' : '${pd['projectExecutionLocationCorpId']}'},
),
).then((_) {
// FocusHelper.clearFocus(context);
@ -277,6 +274,7 @@ class _SxkjApplyPageState extends State<SxkjApplyPage> {
//
await _getPersonListForUnitId(id);
},
data: {'corpinfoId' : pd['projectExecutionLocationCorpId'] ?? ''},
),
).then((_) {
// FocusHelper.clearFocus(context);
@ -337,7 +335,7 @@ class _SxkjApplyPageState extends State<SxkjApplyPage> {
await _getPersonListForUnitId(unitId);
personList = _personCache[unitId] ?? [];
if (personList.isEmpty) {
ToastUtil.showNormal(context, '暂无可选人员,请选择其他单位');
ToastUtil.showNormal(context, '暂无可选人员,请选择正确的相关方项目');
return;
}
}
@ -416,6 +414,8 @@ class _SxkjApplyPageState extends State<SxkjApplyPage> {
pd['projectId'] = id;
pd['projectName'] = name;
pd['xgfId'] = json['corpinfoId'];
pd['projectExecutionLocationCorpId'] = json['projectExecutionLocationCorpId'];
pd['projectExecutionLocationCorpName'] = json['projectExecutionLocationCorpName'];
});
_getRelatedPartiesUserList();
},
@ -431,6 +431,10 @@ class _SxkjApplyPageState extends State<SxkjApplyPage> {
//
Future<void> _getRelatedPartiesUserList() async {
final personRes = await BasicInfoApi.getDeptUsers('', isMyCorp: 0, corpinfoId: pd['projectExecutionLocationCorpId']);
if (personRes['success'] == true) {
_allPersonList = personRes['data'];
}
try {
final result = await BasicInfoApi.getDeptUsers(
'',
@ -557,6 +561,25 @@ class _SxkjApplyPageState extends State<SxkjApplyPage> {
});
}
}
if (isKF) test();
});
}
Future<void> test() async {
for (Map item in _groups) {
item['actUser'] = '2008745640177348608';
item['actUserName'] = '李一浩';
item['actUserDepartment'] = '2008745637258113024';
item['actUserDepartmentName'] = '测试部';
final stepId = item['stepId'] ?? '';
if ('$stepId' == '20') {
_allowChoosePersonList[0] = item;
}
if ('$stepId' == '21') {
_allowChoosePersonList[1] = item;
}
}
setState(() {
});
}
@ -728,6 +751,9 @@ class _SxkjApplyPageState extends State<SxkjApplyPage> {
'workType': SpecialWorkTypeEnum.confinedspaceWork.code,
'xgfFlag': info['xgfFlag'] ?? '',
'xgfId': info['xgfId'] ?? '',
'corpinfoId' : info['projectExecutionLocationCorpId'] ?? '',
'projectId': info['projectId'] ?? '',
'projectName': info['projectName'] ?? '',
'info': info,
'gasFlag': info['gasFlag'] ?? '',
'checkNo': info['checkNo'] ?? '',
@ -892,14 +918,14 @@ class _SxkjApplyPageState extends State<SxkjApplyPage> {
const Divider(),
ItemListWidget.selectableLineTitleTextRightButton(
label: '作业类型:',
isEditable: _isEditable,
onTap: chooseHotworkType,
text: pd['operationTypeName'] ?? '',
isEditable: false,
strongRequired: true,
text: '相关方作业',
),
if (pd['xgfFlag'] == 1) ...[
const Divider(),
ListItemFactory.createYesNoSection(
horizontalPadding: 5,
horizontalPadding: 3,
title: '是否项目内作业',
isRequired: true,
groupValue: _isInnerWork,
@ -910,7 +936,7 @@ class _SxkjApplyPageState extends State<SxkjApplyPage> {
});
},
),
const Divider(),
const Divider(height:1),
//
ItemListWidget.selectableLineTitleTextRightButton(
@ -960,10 +986,10 @@ class _SxkjApplyPageState extends State<SxkjApplyPage> {
horizontalPadding: 5,
title: '是否重点管控有限空间',
isRequired: true,
groupValue: _isInnerWork,
groupValue: _isLimitedSpace,
onChanged: (value) {
setState(() {
_isInnerWork = value;
_isLimitedSpace = value;
pd['isInnerWork'] = value ? 1 : 2;
});
},

View File

@ -161,9 +161,10 @@ class _SxkjTaskPageState extends State<SxkjTaskPage> {
(_initData['settingSignSteps'] is List)
? List.from(_initData['settingSignSteps'])
: [];
final corpinfoId = _initData['workInfo']['corpinfoId'];
if (steps.isNotEmpty) {
LoadingDialogHelper.show();
final personRes = await BasicInfoApi.getDeptUsers('', isMyCorp: 1);
final personRes = await BasicInfoApi.getDeptUsers('', isMyCorp: 0, corpinfoId: corpinfoId);
LoadingDialogHelper.dismiss();
if (personRes['success'] == true) {
@ -436,6 +437,9 @@ class _SxkjTaskPageState extends State<SxkjTaskPage> {
//
await _getPersonListForUnitId(id);
},
data: {
'corpinfoId' :_initData['workInfo']['corpinfoId'] ?? ''
},
),
).then((_) {
// FocusHelper.clearFocus(context);
@ -626,6 +630,7 @@ class _SxkjTaskPageState extends State<SxkjTaskPage> {
isEditable: true,
isTextFont: false,
isRequired: true,
isNumericInput: true,
text: other['limitSpaceWorkNum'] ?? '',
onChanged: (value) {
setState(() {
@ -915,6 +920,7 @@ class _SxkjTaskPageState extends State<SxkjTaskPage> {
},
),
],
const SizedBox(height: 10,),
if (widget.isEdit) ...[
_operationWidget(),
] else ...[

View File

@ -404,7 +404,7 @@ class _SxkjWaitPageState extends State<SxkjWaitPage> {
},
),
);
if (status == '1' && lockFlag == '2') {
if (status == '1' && lockFlag == '2' && widget.listType == SpecialListType.list) {
buttons.add(
CustomButton(
text: '撤回',

View File

@ -114,6 +114,7 @@ class _SxkjTzApplyPageState extends State<SxkjTzApplyPage> {
pd['manageDeptId'] = id;
});
},
data: {'corpinfoId' : '${pd['projectExecutionLocationCorpId']}'},
),
).then((_) {
// FocusHelper.clearFocus(context);

View File

@ -59,7 +59,28 @@ class _WorkTabSpaceListState extends State<WorkTabSpaceList> {
final res = await SpecialWorkApi.getSpecialWorkStepList('confinedspace_work');
if (res != null && res['success'] == true) {
setState(() {
steps = res['data'] ?? [];
final rawData = res['data'] ?? [];
//
steps = (rawData as List).map((entry) {
if (entry is Map<String, dynamic>) {
final List<dynamic> originalSteps = entry['steps'] ?? [];
// steps allowXgfFlag '1'
final filteredSteps = originalSteps.where((item) {
if (item is Map<String, dynamic>) {
final flag = item['allowXgfFlag'];
return '${item['allowXgfFlag']}' == '1';
}
return false;
}).toList();
return {
...entry,
'steps': filteredSteps,
};
}
return entry;
}).where((entry) => entry != null).toList();
_getStepUnreadCount();
});
} else {

View File

@ -1,7 +1,8 @@
import 'package:flutter/material.dart';
import 'package:qhd_prevention/customWidget/work_tab_icon_grid.dart';
import 'package:qhd_prevention/http/ApiService.dart';
import 'package:qhd_prevention/common/route_service.dart';
import 'package:qhd_prevention/common/route_aware_state.dart';
import 'package:qhd_prevention/customWidget/IconBadgeButton.dart';
import 'package:qhd_prevention/http/ApiService.dart';
import 'package:qhd_prevention/pages/home/Tap/special_work/dh_work/hot_delay_page.dart';
import 'package:qhd_prevention/pages/home/Tap/special_work/dh_work/work_tab_dh_list.dart';
import 'package:qhd_prevention/pages/home/Tap/special_work/dl_work/work_tab_dl_list.dart';
@ -13,7 +14,6 @@ import 'package:qhd_prevention/pages/home/Tap/special_work/mbcd_work/work_tab_mb
import 'package:qhd_prevention/pages/home/Tap/special_work/sxkj_work/work_tab_space_list.dart';
import 'package:qhd_prevention/pages/my_appbar.dart';
import 'package:qhd_prevention/tools/tools.dart';
import 'package:qhd_prevention/common/route_aware_state.dart';
class WorkTabListPage extends StatefulWidget {
const WorkTabListPage({super.key});
@ -23,15 +23,63 @@ class WorkTabListPage extends StatefulWidget {
}
class _WorkTabListPageState extends RouteAwareState<WorkTabListPage> {
late List<Map<String, dynamic>> buttonInfos = [
{"icon": "assets/images/wxzy_ico7.png", "title": "动火作业", "unreadCount": 0},
{"icon": "assets/images/wxzy_ico6.png", "title": "受限空间作业", "unreadCount": 0},
{"icon": "assets/images/wxzy_ico5.png", "title": "高处作业", "unreadCount": 0},
{"icon": "assets/images/wxzy_ico4.png", "title": "动土作业", "unreadCount": 0},
{"icon": "assets/images/wxzy_ico3.png", "title": "吊装作业", "unreadCount": 0},
{"icon": "assets/images/wxzy_ico2.png", "title": "断路作业", "unreadCount": 0},
{"icon": "assets/images/wxzy_ico1.png", "title": "临时用电作业", "unreadCount": 0},
{"icon": "assets/images/wxzy_ico8.png", "title": "盲板抽堵作业", "unreadCount": 0},
final List<_WorkButtonConfig> _allButtons = [
_WorkButtonConfig(
icon: 'assets/image/wxzy_ico7.png',
title: '动火作业',
workType: 'hot_work',
menuPerms: 'dashboard:hazardous-work:hot-work',
pageBuilder: () => workTabDhList(),
),
_WorkButtonConfig(
icon: 'assets/image/wxzy_ico6.png',
title: '受限空间作业',
workType: 'confinedspace_work',
menuPerms: 'dashboard:hazardous-work:confined-space-operations',
pageBuilder: () => WorkTabSpaceList(),
),
_WorkButtonConfig(
icon: 'assets/image/wxzy_ico5.png',
title: '高处作业',
workType: 'high_work',
menuPerms: 'dashboard:hazardous-work:work-at-height',
pageBuilder: () => WorkTabGcList(),
),
_WorkButtonConfig(
icon: 'assets/image/wxzy_ico4.png',
title: '动土作业',
workType: 'breakground_work',
menuPerms: 'dashboard:hazardous-work:earthwork-operations',
pageBuilder: () => WorkTabDtList(),
),
_WorkButtonConfig(
icon: 'assets/image/wxzy_ico3.png',
title: '吊装作业',
workType: 'hoisting_work',
menuPerms: 'dashboard:hazardous-work:hoisting-operations',
pageBuilder: () => WorkTabDzList(),
),
_WorkButtonConfig(
icon: 'assets/image/wxzy_ico2.png',
title: '断路作业',
workType: 'cutroad_work',
menuPerms: 'dashboard:hazardous-work:circuit-breaking-operation',
pageBuilder: () => WorkTabDlList(),
),
_WorkButtonConfig(
icon: 'assets/image/wxzy_ico1.png',
title: '临时用电作业',
workType: 'electricity_work',
menuPerms: 'dashboard:hazardous-work:temporary-electrical-work',
pageBuilder: () => WorkTabLsydList(),
),
_WorkButtonConfig(
icon: 'assets/image/wxzy_ico8.png',
title: '盲板抽堵作业',
workType: 'blindboard_work',
menuPerms: 'dashboard:hazardous-work:blind-flange-plugging-operation',
pageBuilder: () => WorkTabMbcdList(),
),
];
@override
@ -45,137 +93,102 @@ class _WorkTabListPageState extends RouteAwareState<WorkTabListPage> {
Future<void> _getData() async {
final data = await SpecialWorkApi.specialWorkTaskLogTotalCount();
if (!mounted) return;
if (data['success'] == true) {
final List todoList = data['data'] ?? [];
setState(() {
List todoList = data['data'];
for (var todo in todoList) {
if (todo['workType'] == 'hot_work') {
//
buttonInfos[0]['unreadCount'] = todo['todoCount'];
}
if (todo['workType'] == 'confinedspace_work') {
//
buttonInfos[1]['unreadCount'] = todo['todoCount'];
}
if (todo['workType'] == 'high_work') {
//
buttonInfos[2]['unreadCount'] = todo['todoCount'];
}
if (todo['workType'] == 'breakground_work') {
//
buttonInfos[3]['unreadCount'] = todo['todoCount'];
}
if (todo['workType'] == 'hoisting_work') {
//
buttonInfos[4]['unreadCount'] = todo['todoCount'];
}
if (todo['workType'] == 'cutroad_work') {
//
buttonInfos[5]['unreadCount'] = todo['todoCount'];
}
if (todo['workType'] == 'electricity_work') {
//
buttonInfos[6]['unreadCount'] = todo['todoCount'];
}
if (todo['workType'] == 'blindboard_work') {
//
buttonInfos[7]['unreadCount'] = todo['todoCount'];
for (final todo in todoList) {
final workType = todo['workType']?.toString() ?? '';
final count = _toInt(todo['todoCount']);
for (final button in _allButtons) {
if (button.workType == workType) {
button.unreadCount = count;
break;
}
}
}
});
}
}
void _handleIconTap(int index) async {
switch (index) {
case 0:
await pushPage(workTabDhList(), context);
break;
case 1:
await pushPage(WorkTabSpaceList(), context);
break;
case 2:
await pushPage(WorkTabGcList(), context);
break;
case 3:
await pushPage(WorkTabDtList(), context);
break;
case 4:
await pushPage(WorkTabDzList(), context);
break;
case 5:
await pushPage(WorkTabDlList(), context);
break;
case 6:
await pushPage(WorkTabLsydList(), context);
break;
case 7:
await pushPage(WorkTabMbcdList(), context);
}
int _toInt(dynamic value) {
if (value == null) return 0;
if (value is int) return value;
if (value is double) return value.toInt();
return int.tryParse(value.toString()) ?? 0;
}
Future<void> _handleButtonTap(_WorkButtonConfig config) async {
final page = config.pageBuilder();
await pushPage(page, context);
_getData();
}
// @override
// Widget build(BuildContext context) {
// return Scaffold(
// appBar: MyAppbar(title: '特殊作业'),
// body: SafeArea(
// child: WorkTabIconGrid(
// buttonInfos: buttonInfos,
// onItemPressed: _handleItemPressed,
// ),
// ),
// );
// }
@override
Widget build(BuildContext context) {
double bannerHeight = 730 / 1125 * MediaQuery.of(context).size.width;
const double iconSectionHeight = 270.0;
const double iconOverlapBanner = 30.0; // banner
return PopScope(
canPop: true,
child: Scaffold(
extendBodyBehindAppBar: true,
appBar: MyAppbar(title: '危险作业', backgroundColor: Colors.transparent),
body: ListView(
physics: const AlwaysScrollableScrollPhysics(),
padding: EdgeInsets.zero,
children: [
SizedBox(
height: bannerHeight + iconSectionHeight,
child: Stack(
clipBehavior: Clip.none,
children: [
Positioned(
top: 0,
left: 0,
right: 0,
height: bannerHeight,
child: _buildBannerSection(bannerHeight),
),
Positioned(
left: 10,
right: 10,
top: bannerHeight - iconOverlapBanner,
height: iconSectionHeight,
child: _buildIconSection(context),
),
],
),
final routeService = RouteService();
return AnimatedBuilder(
animation: routeService,
builder: (context, _) {
final visibleButtons = _allButtons.where((item) {
return routeService.hasPerm(item.menuPerms);
}).toList();
final double bannerHeight =
730 / 1125 * MediaQuery.of(context).size.width;
const double iconSectionHeight = 270.0;
const double iconOverlapBanner = 30.0;
return PopScope(
canPop: true,
child: Scaffold(
extendBodyBehindAppBar: true,
appBar: MyAppbar(
title: '危险作业',
backgroundColor: Colors.transparent,
),
],
),
),
body: ListView(
physics: const AlwaysScrollableScrollPhysics(),
padding: EdgeInsets.zero,
children: [
SizedBox(
height: bannerHeight + iconSectionHeight,
child: Stack(
clipBehavior: Clip.none,
children: [
Positioned(
top: 0,
left: 0,
right: 0,
height: bannerHeight,
child: _buildBannerSection(bannerHeight),
),
Positioned(
left: 10,
right: 10,
top: bannerHeight - iconOverlapBanner,
height: iconSectionHeight,
child: _buildIconSection(context, visibleButtons),
),
],
),
),
],
),
),
);
},
);
}
// Banner
Widget _buildBannerSection(double bannerHeight) {
return Stack(
children: [
//
Image.asset(
"assets/images/wxzy_banner.png",
'assets/image/wxzy_banner.png',
width: MediaQuery.of(context).size.width,
height: bannerHeight,
fit: BoxFit.fitWidth,
@ -184,68 +197,97 @@ class _WorkTabListPageState extends RouteAwareState<WorkTabListPage> {
);
}
Widget _buildIconSection(BuildContext context) {
Widget _buildIconSection(
BuildContext context,
List<_WorkButtonConfig> visibleButtons,
) {
return Container(
padding: const EdgeInsets.symmetric(vertical: 30, horizontal: 5),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(12),
boxShadow: const [
BoxShadow(color: Colors.black12, blurRadius: 6, offset: Offset(0, 2)),
BoxShadow(
color: Colors.black12,
blurRadius: 6,
offset: Offset(0, 2),
),
],
),
child: Column(children: [_buildIconGrid()]),
child: _buildIconGrid(visibleButtons),
);
}
Widget _buildIconGrid() {
final List<Widget> rows = [];
for (int row = 0; row < 2; row++) {
rows.add(
Padding(
padding: EdgeInsets.only(bottom: row == 0 ? 12 : 0),
child: _buildIconRow(startIndex: row * 4),
Widget _buildIconGrid(List<_WorkButtonConfig> visibleButtons) {
if (visibleButtons.isEmpty) {
return const Center(
child: Padding(
padding: EdgeInsets.symmetric(vertical: 30),
child: Text(
'暂无可用作业入口',
style: TextStyle(color: Colors.grey),
),
),
);
}
final List<Widget> rows = [];
const int crossAxisCount = 4;
final int rowCount = (visibleButtons.length / crossAxisCount).ceil();
for (int row = 0; row < rowCount; row++) {
final int startIndex = row * crossAxisCount;
final int endIndex =
(startIndex + crossAxisCount) > visibleButtons.length
? visibleButtons.length
: startIndex + crossAxisCount;
final rowButtons = visibleButtons.sublist(startIndex, endIndex);
rows.add(
Padding(
padding: EdgeInsets.only(bottom: row == rowCount - 1 ? 0 : 12),
child: Row(
children: rowButtons
.map(
(item) => Expanded(
child: Center(
child: _buildIconButton(item),
),
),
)
.toList(),
),
),
);
if (row == 0) {
rows.add(SizedBox(height: 12));
}
}
return Column(children: rows);
}
Widget _buildIconRow({required int startIndex}) {
final List<Widget> cells = List.generate(4, (i) {
final int idx = startIndex + i;
if (idx < buttonInfos.length) {
return Expanded(
child: Center(
child: _buildIconButton(buttonInfos[idx], idx, context),
),
);
} else {
return const Expanded(child: SizedBox.shrink());
}
});
return Row(children: cells);
}
Widget _buildIconButton(
Map<String, dynamic> info,
int index,
BuildContext context,
) {
Widget _buildIconButton(_WorkButtonConfig info) {
return IconBadgeButton(
iconPath: info['icon'] ?? '',
title: info['title'] ?? '',
unreadCount:
(info['unreadCount'] ?? 0) is int
? info['unreadCount'] as int
: int.tryParse('${info['unreadCount']}') ?? 0,
onTap: () => _handleIconTap(index),
iconPath: info.icon,
title: info.title,
unreadCount: info.unreadCount,
onTap: () => _handleButtonTap(info),
);
}
}
class _WorkButtonConfig {
final String icon;
final String title;
final String workType;
final String menuPerms;
final Widget Function() pageBuilder;
int unreadCount;
_WorkButtonConfig({
required this.icon,
required this.title,
required this.workType,
required this.menuPerms,
required this.pageBuilder,
this.unreadCount = 0,
});
}

View File

@ -258,29 +258,6 @@ class _UnitJoinDetailPageState extends State<UnitJoinDetailPage> {
},
),
const Divider(),
ItemListWidget.singleLineTitleText(
label: '户口所在地:',
isRequired: _isEdit,
hintText: '请输入户口所在地',
text: pd['locationAddress'] ?? '',
isEditable: _isEdit,
onChanged: (value) {
pd['locationAddress'] = value;
},
),
const Divider(),
ItemListWidget.singleLineTitleText(
label: '现住址:',
isRequired: true,
text: pd['currentAddress'] ?? '',
hintText: '请输入现住址',
isEditable: _isEdit,
onChanged: (value) {
pd['currentAddress'] = value;
},
),
const Divider(),
if (_isEdit || _idCardImgList.isNotEmpty)
RepairedPhotoSection(
title: '身份证照片',
@ -375,31 +352,6 @@ class _UnitJoinDetailPageState extends State<UnitJoinDetailPage> {
},
),
const Divider(),
ItemListWidget.selectableLineTitleTextRightButton(
label: '婚姻状态:',
isEditable: _isEdit,
text: pd['maritalStatusName'] ?? '请选择',
isRequired: _isEdit,
onTap: () async {
final found = await BottomPicker.show(
context,
items: _hunyinList,
itemBuilder:
(i) =>
Text(i['name']!, textAlign: TextAlign.center),
initialIndex: 0,
);
//FocusHelper.clearFocus(context);
if (found != null) {
setState(() {
pd['maritalStatusName'] = found['name'];
pd['maritalStatus'] = found['value'];
});
}
},
),
const Divider(),
ListItemFactory.createYesNoSection(
title: "是否流动人员:",
horizontalPadding: 2,

View File

@ -1,3 +1,4 @@
// import
import 'dart:convert';
import 'package:file_picker/file_picker.dart';
@ -22,10 +23,14 @@ import 'package:qhd_prevention/tools/tools.dart';
import 'package:shared_preferences/shared_preferences.dart';
class FullUserinfoPage extends StatefulWidget {
const FullUserinfoPage({super.key, required this.isEidt, required this.isChooseFirm});
const FullUserinfoPage({
super.key,
required this.isEidt,
required this.isChooseFirm,
});
final bool isEidt;
final bool isChooseFirm; //
final bool isChooseFirm;
@override
State<FullUserinfoPage> createState() => _FullUserinfoPageState();
@ -39,37 +44,29 @@ class _FullUserinfoPageState extends State<FullUserinfoPage> {
"birthday": "",
"gender": "",
"nationName": "",
"locationAddress": "",
"currentAddress": "",
"culturalLevel": "",
"politicalAffiliation": "",
"maritalStatus": "",
};
Map rule = {
"name": "请输入姓名",
"userIdCard": "请输入身份证号码",
"nationName": "请选择民族",
"locationAddress": "请输入户口所在地",
"currentAddress": "请输入现居住地址",
"culturalLevel": "请选择文化程度",
"politicalAffiliation": "请选择政治面貌",
"maritalStatus": "请选择婚姻状况",
};
late bool _isEdit;
///
late bool _isEdit;
late bool _isChange = false;
String _genderText = '';
String _birthText = '';
String _idValue = '';
String? _userId = SessionService.instance.userId;
List<String> _idCardImgList = [];
List<String> _idCartImgIds = [];
///
bool _isChangeIdCard = false;
List<String> _idCardImgRemoveList = [];
List<dynamic> _wenhuachengduList = [];
@ -102,6 +99,7 @@ class _FullUserinfoPageState extends State<FullUserinfoPage> {
_genderText = data['sex'] ?? '';
_birthText = data['birthday'] ?? '';
final eqForeignKey = data['userId'];
await FileApi.getImagePathWithType(
eqForeignKey,
'',
@ -112,28 +110,27 @@ class _FullUserinfoPageState extends State<FullUserinfoPage> {
_idCardImgList =
files.map((item) => item['filePath'].toString()).toList();
_idCartImgIds = files.map((item) => item['id'].toString()).toList();
// final filePath = fileData.first['filePath'] ?? '';
}
});
setState(() {
pd = data;
try{
try {
final idCardBase64 = utf8.decode(base64.decode(pd['userIdCard']));
if (idCardBase64.isNotEmpty) {
pd['userIdCard'] =idCardBase64;
pd['userIdCard'] = idCardBase64;
_idValue = idCardBase64;
}
}catch(e){
} catch (e) {
print(e);
}
});
}
}
Future<void> _getKeyValues() async {
final prefs = await SharedPreferences.getInstance();
final phone = await prefs.getString("savePhone");
final phone = prefs.getString("savePhone");
pd['username'] = phone;
await BasicInfoApi.getDictValues('wenhuachengdu').then((res) {
_wenhuachengduList = res['data'];
@ -141,39 +138,119 @@ class _FullUserinfoPageState extends State<FullUserinfoPage> {
await BasicInfoApi.getDictValues('zhengzhimianmao').then((res) {
_zhengzhimianmaoList = res['data'];
});
setState(() {
setState(() {});
}
void _clearParsedIdCardFields({bool keepInput = true}) {
setState(() {
if (!keepInput) {
pd['userIdCard'] = '';
}
pd.remove('birthday');
pd.remove('age');
pd.remove('gender');
pd.remove('provinceCode');
pd.remove('province');
_genderText = '输入身份证获取';
_birthText = '输入身份证获取';
});
}
void _applyParsedIdCardInfo(IDCardInfo info, String input) {
setState(() {
pd['userIdCard'] = info.id18 ?? input;
pd['birthday'] = info.birth;
pd['age'] = info.age;
pd['gender'] = info.gender;
pd['provinceCode'] = info.provinceCode;
pd['province'] = info.province;
_genderText = info.gender ?? '未知';
_birthText = info.birth ?? '未知';
});
}
///
void _onIdChanged(String value) {
final raw = value.trim().toUpperCase();
_idValue = raw;
_isChangeIdCard = true;
setState(() {
pd['userIdCard'] = raw;
});
// 18
if (raw.length != 18) {
_clearParsedIdCardFields(keepInput: true);
return;
}
final info = parseChineseIDCard(raw);
if (info.isValid) {
setState(() {
pd['userIdCard'] = info.id18 ?? raw;
pd['birthday'] = info.birth;
pd['age'] = info.age;
pd['gender'] = info.gender;
pd['provinceCode'] = info.provinceCode;
pd['province'] = info.province;
_genderText = info.gender ?? '未知';
_birthText = info.birth ?? '未知';
});
} else {
_clearParsedIdCardFields(keepInput: true);
ToastUtil.showNormal(context, info.error ?? '请输入正确身份证号');
}
}
Future<void> _saveSuccess() async {
if (!FormUtils.hasValue(pd, 'faceFiles') &&
!FormUtils.hasValue(pd, 'userAvatarUrl')) {
ToastUtil.showNormal(context, '请上传人脸图片');
return;
}
for (String key in rule.keys) {
if (!FormUtils.hasValue(pd, key)) {
ToastUtil.showNormal(context, rule[key]);
return;
}
}
if (!FormUtils.hasValue(pd, 'userIdCard') ||
!FormUtils.hasValue(pd, 'birthday')) {
ToastUtil.showNormal(context, '请输入正确身份证号');
return ;
//
final idRaw = (pd['userIdCard'] ?? '').toString().trim().toUpperCase();
final idInfo = parseChineseIDCard(idRaw);
if (!idInfo.isValid) {
ToastUtil.showNormal(context, idInfo.error ?? '请输入正确身份证号');
return;
}
// 使 18
pd['userIdCard'] = idInfo.id18 ?? idRaw;
pd['birthday'] = idInfo.birth;
pd['age'] = idInfo.age;
pd['gender'] = pd['gender'] ?? idInfo.gender;
pd['provinceCode'] = idInfo.provinceCode;
pd['province'] = idInfo.province;
if (_genderText.isEmpty) {
_genderText = idInfo.gender ?? '';
}
if (_birthText.isEmpty) {
_birthText = idInfo.birth ?? '';
}
if (idPhotos.length < 2 && !_isChange) {
ToastUtil.showNormal(context, '请上传2张身份证照片');
return;
}
LoadingDialogHelper.show();
//
final signResult = await _checkFaceImage();
//
final situationResult = await _checkIDCartImages();
//
final deleteResult = await _checkDeleteImage();
if (signResult && situationResult && deleteResult) {
@ -186,27 +263,29 @@ class _FullUserinfoPageState extends State<FullUserinfoPage> {
if (widget.isChooseFirm || _isChange) {
Navigator.pop(context);
}else{
} else {
Navigator.pushReplacement(
context,
MaterialPageRoute(builder: (_) => FirmListPage(isBack: false,)),
MaterialPageRoute(
builder: (_) => FirmListPage(isBack: false),
),
);
}
} else {
ToastUtil.showNormal(context, res['errMessage'] ?? '保存失败');
}
});
}else{
} else {
ToastUtil.showNormal(context, '保存失败');
LoadingDialogHelper.hide();
}
}
Future<bool> _checkDeleteImage() async {
late bool isSuccess = true;
if (_idCardImgRemoveList.isNotEmpty) {
final delIds = _idCardImgRemoveList;
try{
try {
await FileApi.deleteImages(delIds).then((result) {
if (result['success']) {
isSuccess = true;
@ -214,24 +293,23 @@ class _FullUserinfoPageState extends State<FullUserinfoPage> {
isSuccess = false;
}
});
}catch(e){
} catch (e) {
LoadingDialogHelper.hide();
}
}else{
} else {
isSuccess = true;
}
return isSuccess;
}
///
Future<bool> _checkFaceImage() async {
final faceImgPath = pd['faceFiles'] ?? '';
UploadFileType fileType = UploadFileType.userAvatar;
late bool isSuccess = true;
if (faceImgPath.isNotEmpty) {
try {
await FileApi.uploadFile(faceImgPath, fileType, _userId ?? '').then((result) {
await FileApi.uploadFile(faceImgPath, fileType, _userId ?? '')
.then((result) {
if (result['success']) {
pd['userAvatarUrl'] = result['data']['filePath'] ?? '';
isSuccess = true;
@ -250,10 +328,8 @@ class _FullUserinfoPageState extends State<FullUserinfoPage> {
return isSuccess;
}
///
Future<bool> _checkIDCartImages() async {
late bool isSuccess = true;
//
if (idPhotos.isEmpty) {
return isSuccess;
}
@ -277,69 +353,6 @@ class _FullUserinfoPageState extends State<FullUserinfoPage> {
return isSuccess;
}
/// value
void _onIdChanged(String value) {
_idValue = value ?? '';
_isChangeIdCard = true;
final raw = _idValue.trim().toUpperCase();
// 15 18
if (raw.length == 15 || raw.length == 18) {
try {
final info = parseChineseIDCard(raw);
if (info.isValid /**&& info.checksumValid*/) {
setState(() {
// 使 info.id18 18
pd['userIdCard'] = info.id18 ?? raw;
pd['birthday'] = info.birth; // YYYY-MM-DD
pd['age'] = info.age;
pd['gender'] = info.gender; // ""/""
pd['provinceCode'] = info.provinceCode;
pd['province'] = info.province;
_genderText = info.gender ?? '未知';
_birthText = info.birth ?? '未知';
});
} else {
//
setState(() {
pd.remove('birthday');
pd.remove('age');
pd.remove('gender');
pd.remove('provinceCode');
pd.remove('province');
_genderText = '输入身份证获取';
_birthText = '输入身份证获取';
});
}
} catch (e) {
ToastUtil.showNormal(context, '请输入正确格式身份证号');
//
setState(() {
pd.remove('birthday');
pd.remove('age');
pd.remove('gender');
pd.remove('provinceCode');
pd.remove('province');
_genderText = '输入身份证获取';
_birthText = '输入身份证获取';
});
}
} else {
//
if (_genderText != '请选择' || _birthText != '请选择') {
setState(() {
pd.remove('birthday');
pd.remove('age');
pd.remove('gender');
pd.remove('provinceCode');
pd.remove('province');
_genderText = '输入身份证获取';
_birthText = '输入身份证获取';
});
}
}
}
@override
Widget build(BuildContext context) {
bool isShow = _isEdit;
@ -359,7 +372,7 @@ class _FullUserinfoPageState extends State<FullUserinfoPage> {
content: '是否放弃修改?',
cancelText: '取消',
).then(
(isSure) => {
(isSure) => {
if (isSure) {Navigator.pop(context)},
},
);
@ -376,352 +389,278 @@ class _FullUserinfoPageState extends State<FullUserinfoPage> {
_isEdit = true;
});
},
child: Text(
child: const Text(
'修改',
style: TextStyle(color: Colors.white, fontSize: 17),
),
),
],
),
body: SafeArea(
child: ItemListWidget.itemContainer(
horizontal: 5,
isShow
? ListView(
children: [
RepairedPhotoSection(
title: '人脸照片',
inlineSingle: true,
isRequired: _isEdit,
initialMediaPaths:
FormUtils.hasValue(pd, 'userAvatarUrl')
? [
'${ApiService.baseImgPath}${pd['userAvatarUrl'] ?? ''}',
]
: [],
horizontalPadding: _isEdit ? 12 : 0,
inlineImageWidth: 60,
isFaceImage: true,
isEdit: _isEdit,
onChanged: (files) {
if (files.isEmpty) {
return;
}
pd['faceFiles'] = files.first.path;
},
onAiIdentify: () {},
// onMediaRemovedForIndex: (index) async {
// final deleFile = pd['userAvatarUrl'] ?? '';
// if (deleFile.contains(UploadFileType.idCardPhoto.path)) {
// _idCardImgRemoveList.add(deleFile);
// }
// },
children: [
RepairedPhotoSection(
title: '人脸照片',
inlineSingle: true,
isRequired: _isEdit,
initialMediaPaths: FormUtils.hasValue(pd, 'userAvatarUrl')
? [
'${ApiService.baseImgPath}${pd['userAvatarUrl'] ?? ''}',
]
: [],
horizontalPadding: _isEdit ? 12 : 0,
inlineImageWidth: 60,
isFaceImage: true,
isEdit: _isEdit,
onChanged: (files) {
if (files.isEmpty) {
return;
}
pd['faceFiles'] = files.first.path;
},
onAiIdentify: () {},
),
if (_isEdit)
ItemListWidget.itemContainer(
const Text(
'温馨提示:该照片为进入项目施工场所口门人脸识别使用',
style: TextStyle(color: Colors.red, fontSize: 10),
),
if (_isEdit)
ItemListWidget.itemContainer(
const Text(
'温馨提示:该照片为进入项目施工场所口门人脸识别使用',
style: TextStyle(color: Colors.red, fontSize: 10),
),
),
const Divider(),
ItemListWidget.singleLineTitleText(
label: '姓名:',
isRequired: true,
hintText: '请输入姓名',
text: pd['name'] ?? '',
isEditable: _isEdit,
onChanged: (value) {
pd['name'] = value;
},
),
const Divider(),
ItemListWidget.singleLineTitleText(
label: '手机号:',
isRequired: true,
text: pd['username'] ?? '',
isNumericInput: true,
hintText: '请输入手机号',
strongRequired: _isEdit,
isEditable: false,
),
const Divider(),
ItemListWidget.singleLineTitleText(
label: '身份证:',
isRequired: true,
hintText: '请输入身份证号',
text: pd['userIdCard'] ?? '',
isEditable: _isEdit,
onChanged: (value) {
_onIdChanged(value ?? '');
},
),
const Divider(),
ItemListWidget.selectableLineTitleTextRightButton(
label: '民族:',
isEditable: _isEdit,
text: pd['nationName'] ?? '请选择',
isRequired: _isEdit,
onTap: () async {
final found = await BottomPicker.show(
context,
items: nationMapList,
itemBuilder: (i) =>
Text(i['name']!, textAlign: TextAlign.center),
initialIndex: 0,
);
if (found != null) {
setState(() {
pd['nationName'] = found['name'];
pd['nation'] = found['bianma'];
});
}
},
),
const Divider(),
ItemListWidget.selectableLineTitleTextRightButton(
label: '性别:',
isEditable: false,
text: _genderText,
strongRequired: _isEdit,
isRequired: true,
onTap: () {
showModalBottomSheet(
context: context,
builder: (_) {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
ListTile(
title: const Text(''),
onTap: () {
setState(() {
pd['gender'] = '';
_genderText = '';
});
Navigator.pop(context);
},
),
ListTile(
title: const Text(''),
onTap: () {
setState(() {
pd['gender'] = '';
_genderText = '';
});
Navigator.pop(context);
},
),
],
);
},
);
},
),
const Divider(),
ItemListWidget.selectableLineTitleTextRightButton(
label: '出生年月:',
isEditable: false,
text: _birthText,
strongRequired: _isEdit,
isRequired: true,
onTap: () {},
),
const Divider(),
if (_isEdit || _idCardImgList.isNotEmpty)
RepairedPhotoSection(
title: '身份证照片',
isRequired: _isEdit,
maxCount: 2,
initialMediaPaths: _idCardImgList
.map(
(item) => ApiService.baseImgPath + item,
)
.toList(),
isEdit: _isEdit,
horizontalPadding: _isEdit ? 12 : 0,
inlineImageWidth: 60,
onChanged: (files) {
idPhotos = files.map((file) => file.path).toList();
},
onMediaRemovedForIndex: (index) async {
final deleFile = _idCardImgList[index];
final deleId = _idCartImgIds[index];
if (deleFile.contains(UploadFileType.idCardPhoto.path)) {
_idCardImgList.removeAt(index);
_idCartImgIds.removeAt(index);
_idCardImgRemoveList.add(deleId);
}
},
onAiIdentify: () {},
),
if (_isEdit)
ItemListWidget.itemContainer(
const Text(
'温馨提示用户要上传身份证正反面身份证照片数量是2张才能进行人员培训',
style: TextStyle(color: Colors.red, fontSize: 10),
),
),
const Divider(),
ItemListWidget.selectableLineTitleTextRightButton(
label: '文化程度:',
isEditable: _isEdit,
text: pd['culturalLevelName'] ?? '请选择',
isRequired: _isEdit,
onTap: () async {
final found = await BottomPicker.show(
context,
items: _wenhuachengduList,
itemBuilder: (i) => Text(
i['dictLabel']!,
textAlign: TextAlign.center,
),
const Divider(),
ItemListWidget.singleLineTitleText(
label: '姓名:',
isRequired: true,
hintText: '请输入姓名',
text: pd['name'] ?? '',
isEditable: _isEdit,
onChanged: (value) {
pd['name'] = value;
},
),
const Divider(),
ItemListWidget.singleLineTitleText(
label: '手机号:',
isRequired: true,
text: pd['username'] ?? '',
isNumericInput: true,
hintText: '请输入手机号',
strongRequired: _isEdit,
isEditable: false,
),
const Divider(),
// 使 onChanged value
ItemListWidget.singleLineTitleText(
label: '身份证:',
isRequired: true,
hintText: '请输入身份证号',
text: pd['userIdCard'] ?? '',
isEditable: _isEdit,
onChanged: (value) {
// value
_onIdChanged(value ?? '');
},
),
const Divider(),
ItemListWidget.selectableLineTitleTextRightButton(
label: '民族:',
isEditable: _isEdit,
text: pd['nationName'] ?? '请选择',
isRequired: _isEdit,
onTap: () async {
final found = await BottomPicker.show(
context,
items: nationMapList,
itemBuilder:
(i) =>
Text(i['name']!, textAlign: TextAlign.center),
initialIndex: 0,
);
//FocusHelper.clearFocus(context);
initialIndex: 0,
);
if (found != null) {
setState(() {
pd['nationName'] = found['name'];
pd['nation'] = found['bianma'];
});
}
},
),
const Divider(),
//
ItemListWidget.selectableLineTitleTextRightButton(
label: '性别:',
isEditable: false,
text: _genderText,
strongRequired: _isEdit,
isRequired: true,
onTap: () {
//
showModalBottomSheet(
context: context,
builder: (_) {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
ListTile(
title: const Text(''),
onTap: () {
setState(() {
pd['gender'] = '';
_genderText = '';
});
Navigator.pop(context);
},
),
ListTile(
title: const Text(''),
onTap: () {
setState(() {
pd['gender'] = '';
_genderText = '';
});
Navigator.pop(context);
},
),
],
);
},
);
},
),
const Divider(),
//
ItemListWidget.selectableLineTitleTextRightButton(
label: '出生年月:',
isEditable: false,
text: _birthText,
strongRequired: _isEdit,
isRequired: true,
onTap: () async {
},
),
const Divider(),
ItemListWidget.singleLineTitleText(
label: '户口所在地:',
isRequired: _isEdit,
hintText: '请输入户口所在地',
text: pd['locationAddress'] ?? '',
isEditable: _isEdit,
onChanged: (value) {
pd['locationAddress'] = value;
},
),
const Divider(),
ItemListWidget.singleLineTitleText(
label: '现住址:',
isRequired: true,
text: pd['currentAddress'] ?? '',
hintText: '请输入现住址',
isEditable: _isEdit,
onChanged: (value) {
pd['currentAddress'] = value;
},
),
const Divider(),
if (_isEdit || _idCardImgList.isNotEmpty)
RepairedPhotoSection(
title: '身份证照片',
isRequired: _isEdit,
maxCount: 2,
initialMediaPaths:
_idCardImgList
.map(
(item) =>
ApiService.baseImgPath + item,
)
.toList(),
isEdit: _isEdit,
horizontalPadding: _isEdit ? 12 : 0,
inlineImageWidth: 60,
onChanged: (files) {
idPhotos = files.map((file) => file.path).toList();
},
onMediaRemovedForIndex: (index) async {
final deleFile = _idCardImgList[index];
final deleId = _idCartImgIds[index];
if (deleFile.contains(UploadFileType.idCardPhoto.path)) {
_idCardImgList.removeAt(index);
_idCartImgIds.removeAt(index);
_idCardImgRemoveList.add(deleId);
}
},
onAiIdentify: () {
/* ... */
},
if (found != null) {
setState(() {
pd['culturalLevelName'] = found['dictLabel'];
pd['culturalLevel'] = found['dictValue'];
});
}
},
),
const Divider(),
ItemListWidget.selectableLineTitleTextRightButton(
label: '政治面貌:',
isEditable: _isEdit,
text: pd['politicalAffiliationName'] ?? '请选择',
isRequired: _isEdit,
onTap: () async {
final found = await BottomPicker.show(
context,
items: _zhengzhimianmaoList,
itemBuilder: (i) => Text(
i['dictLabel']!,
textAlign: TextAlign.center,
),
if (_isEdit)
ItemListWidget.itemContainer(
const Text(
'温馨提示用户要上传身份证正反面身份证照片数量是2张才能进行人员培训',
style: TextStyle(color: Colors.red, fontSize: 10),
),
),
const Divider(),
ItemListWidget.selectableLineTitleTextRightButton(
label: '文化程度:',
isEditable: _isEdit,
text: pd['culturalLevelName'] ?? '请选择',
isRequired: _isEdit,
onTap: () async {
final found = await BottomPicker.show(
context,
items: _wenhuachengduList,
itemBuilder:
(i) => Text(
i['dictLabel']!,
textAlign: TextAlign.center,
),
initialIndex: 0,
);
//FocusHelper.clearFocus(context);
initialIndex: 0,
);
if (found != null) {
setState(() {
pd['culturalLevelName'] = found['dictLabel'];
pd['culturalLevel'] = found['dictValue'];
});
}
},
),
const Divider(),
ItemListWidget.selectableLineTitleTextRightButton(
label: '政治面貌:',
isEditable: _isEdit,
text: pd['politicalAffiliationName'] ?? '请选择',
isRequired: _isEdit,
onTap: () async {
final found = await BottomPicker.show(
context,
items: _zhengzhimianmaoList,
itemBuilder:
(i) => Text(
i['dictLabel']!,
textAlign: TextAlign.center,
),
initialIndex: 0,
);
//FocusHelper.clearFocus(context);
if (found != null) {
setState(() {
pd['politicalAffiliationName'] = found['dictLabel'];
pd['politicalAffiliation'] = found['dictValue'];
});
}
},
),
const Divider(),
ItemListWidget.selectableLineTitleTextRightButton(
label: '婚姻状态:',
isEditable: _isEdit,
text: pd['maritalStatusName'] ?? '请选择',
isRequired: _isEdit,
onTap: () async {
final found = await BottomPicker.show(
context,
items: _hunyinList,
itemBuilder:
(i) =>
Text(i['name']!, textAlign: TextAlign.center),
initialIndex: 0,
);
//FocusHelper.clearFocus(context);
if (found != null) {
setState(() {
pd['maritalStatusName'] = found['name'];
pd['maritalStatus'] = found['value'];
});
}
},
),
const Divider(),
ListItemFactory.createYesNoSection(
title: "是否流动人员:",
horizontalPadding: 2,
verticalPadding: 0,
yesLabel: "",
noLabel: "",
text: pd['flowFlag'] == 1 ? '' : '',
isRequired: true,
isEdit: _isEdit ? (token.isEmpty ? true : false) : false,
groupValue: (pd['flowFlag'] ?? 0) == 1,
onChanged: (val) {
setState(() {
pd['flowFlag'] = val ? 1 : 0;
});
},
),
const Divider(),
ItemListWidget.singleLineTitleText(
label: '电子邮箱:',
isRequired: false,
isNumericInput: false,
hintText: '请输入电子邮箱',
text: pd['email'] ?? '',
isEditable: _isEdit,
onChanged: (value) {
pd['email'] = value;
},
),
const Divider(),
const SizedBox(height: 20),
if (_isEdit)
CustomButton(
text: '保存',
backgroundColor: Colors.blue,
onPressed: () {
_saveSuccess();
},
),
],
)
if (found != null) {
setState(() {
pd['politicalAffiliationName'] =
found['dictLabel'];
pd['politicalAffiliation'] = found['dictValue'];
});
}
},
),
const Divider(),
ListItemFactory.createYesNoSection(
title: "是否流动人员:",
horizontalPadding: 2,
verticalPadding: 0,
yesLabel: "",
noLabel: "",
text: pd['flowFlag'] == 1 ? '' : '',
isRequired: true,
isEdit: _isEdit ? (token.isEmpty ? true : false) : false,
groupValue: (pd['flowFlag'] ?? 0) == 1,
onChanged: (val) {
setState(() {
pd['flowFlag'] = val ? 1 : 0;
});
},
),
const Divider(),
ItemListWidget.singleLineTitleText(
label: '电子邮箱:',
isRequired: false,
isNumericInput: false,
hintText: '请输入电子邮箱',
text: pd['email'] ?? '',
isEditable: _isEdit,
onChanged: (value) {
pd['email'] = value;
},
),
const Divider(),
const SizedBox(height: 20),
if (_isEdit)
CustomButton(
text: '保存',
backgroundColor: Colors.blue,
onPressed: () {
_saveSuccess();
},
),
],
)
: const SizedBox(),
),
),

View File

@ -1,26 +1,27 @@
// utils/id_card_util.dart
import 'dart:core';
class IDCardInfo {
final String raw;
final bool isValid;
final String? error;
final String? id18; // 1815
final String? id18;
final String? addressCode;
final String? provinceCode;
final String? province;
final DateTime? birthDate;
final String? birth; // YYYY-MM-DD
final String? birth;
final int? age;
final String? gender; // '' / ''
final String? gender;
final bool checksumValid;
final String? constellation; //
final String? zodiac; //
final String? constellation;
final String? zodiac;
IDCardInfo({
required this.raw,
required this.isValid,
this.error,
this.id18,
this.addressCode,
this.provinceCode,
this.province,
this.birthDate,
@ -37,6 +38,7 @@ class IDCardInfo {
'isValid': isValid,
'error': error,
'id18': id18,
'addressCode': addressCode,
'provinceCode': provinceCode,
'province': province,
'birth': birth,
@ -51,14 +53,37 @@ class IDCardInfo {
String toString() => toJson().toString();
}
/// IDCardInfo
IDCardInfo parseChineseIDCard(String id) {
final raw = (id ?? '').toString().trim().toUpperCase();
/// 18
IDCardInfo parseChineseIDCard(String? id) {
final raw = _normalizeId(id);
if (raw.isEmpty) {
return IDCardInfo(raw: raw, isValid: false, error: '空字符串', checksumValid: false);
return IDCardInfo(
raw: raw,
isValid: false,
error: '身份证号不能为空',
checksumValid: false,
);
}
if (raw.length != 18) {
return IDCardInfo(
raw: raw,
isValid: false,
error: '身份证号长度不正确应为18位',
checksumValid: false,
);
}
if (!RegExp(r'^\d{17}[\dX]$').hasMatch(raw)) {
return IDCardInfo(
raw: raw,
isValid: false,
error: '身份证号格式不正确前17位必须是数字最后一位必须是数字或X',
checksumValid: false,
);
}
//
const provinceMap = <String, String>{
'11': '北京市',
'12': '天津市',
@ -94,57 +119,79 @@ IDCardInfo parseChineseIDCard(String id) {
'71': '台湾省',
'81': '香港特别行政区',
'82': '澳门特别行政区',
'91': '国外'
'91': '国外',
};
// 15 18 17 + X
final reg15 = RegExp(r'^\d{15}$');
final reg18 = RegExp(r'^\d{17}[\dX]$');
final addressCode = raw.substring(0, 6);
final provinceCode = raw.substring(0, 2);
final province = provinceMap[provinceCode];
String standardized = raw;
bool convertedFrom15 = false;
if (reg15.hasMatch(raw)) {
// 15 -> 18 6 "19"
final prefix17 = raw.substring(0, 6) + '19' + raw.substring(6);
final checkChar = _calcCheckChar(prefix17);
standardized = prefix17 + checkChar;
convertedFrom15 = true;
} else if (reg18.hasMatch(raw)) {
standardized = raw;
} else {
if (province == null) {
return IDCardInfo(
raw: raw,
isValid: false,
error: '身份证格式不正确不是15位或18位',
error: '地址码不合法:省份码错误',
id18: raw,
addressCode: addressCode,
provinceCode: provinceCode,
checksumValid: false,
);
}
//
final birthStr = standardized.substring(6, 14); // YYYYMMDD
final year = int.tryParse(birthStr.substring(0, 4));
final month = int.tryParse(birthStr.substring(4, 6));
final day = int.tryParse(birthStr.substring(6, 8));
final yearStr = raw.substring(6, 10);
final monthStr = raw.substring(10, 12);
final dayStr = raw.substring(12, 14);
if (year == null || month == null || day == null) {
if (!RegExp(r'^(18|19|20)\d{2}$').hasMatch(yearStr)) {
return IDCardInfo(
raw: raw,
isValid: false,
error: '无法解析出生日期',
id18: standardized,
checksumValid: _verifyCheck(standardized),
error: '年份不合法必须以18、19或20开头',
id18: raw,
addressCode: addressCode,
provinceCode: provinceCode,
province: province,
checksumValid: false,
);
}
//
if (!RegExp(r'^(0[1-9]|1[0-2])$').hasMatch(monthStr)) {
return IDCardInfo(
raw: raw,
isValid: false,
error: '月份不合法必须在01到12之间',
id18: raw,
addressCode: addressCode,
provinceCode: provinceCode,
province: province,
checksumValid: false,
);
}
if (!RegExp(r'^(0[1-9]|[12]\d|3[01])$').hasMatch(dayStr)) {
return IDCardInfo(
raw: raw,
isValid: false,
error: '日期不合法必须在01到31之间',
id18: raw,
addressCode: addressCode,
provinceCode: provinceCode,
province: province,
checksumValid: false,
);
}
final year = int.parse(yearStr);
final month = int.parse(monthStr);
final day = int.parse(dayStr);
DateTime? birthDate;
try {
birthDate = DateTime(year, month, day);
//
if (birthDate.year != year || birthDate.month != month || birthDate.day != day) {
birthDate = null;
final dt = DateTime(year, month, day);
if (dt.year == year && dt.month == month && dt.day == day) {
birthDate = dt;
}
} catch (e) {
} catch (_) {
birthDate = null;
}
@ -152,71 +199,123 @@ IDCardInfo parseChineseIDCard(String id) {
return IDCardInfo(
raw: raw,
isValid: false,
error: '出生日期无效',
id18: standardized,
checksumValid: _verifyCheck(standardized),
error: '出生日期无效:请检查年月日是否真实存在',
id18: raw,
addressCode: addressCode,
provinceCode: provinceCode,
province: province,
checksumValid: false,
);
}
//
final now = DateTime.now();
int age = now.year - birthDate.year;
if (now.month < birthDate.month || (now.month == birthDate.month && now.day < birthDate.day)) {
age -= 1;
final seqCode = raw.substring(14, 17);
if (!RegExp(r'^\d{3}$').hasMatch(seqCode)) {
return IDCardInfo(
raw: raw,
isValid: false,
error: '顺序码不合法第15到17位必须全部为数字',
id18: raw,
addressCode: addressCode,
provinceCode: provinceCode,
province: province,
birthDate: birthDate,
birth: _formatDate(birthDate),
checksumValid: false,
);
}
// 17 16
final seq = standardized.substring(14, 17); // 3
final seqNum = int.tryParse(seq);
final gender = (seqNum != null && seqNum % 2 == 1) ? '' : '';
final seqNum = int.parse(seqCode);
if (seqNum == 0) {
return IDCardInfo(
raw: raw,
isValid: false,
error: '顺序码不合法不能为000',
id18: raw,
addressCode: addressCode,
provinceCode: provinceCode,
province: province,
birthDate: birthDate,
birth: _formatDate(birthDate),
checksumValid: false,
);
}
//
final provinceCode = standardized.substring(0, 2);
final province = provinceMap[provinceCode] ?? '未知';
final gender = (seqNum % 2 == 1) ? '' : '';
//
final checksumValid = _verifyCheck(standardized);
//
final constellation = _calcConstellation(birthDate.month, birthDate.day);
final zodiac = _calcChineseZodiac(birthDate.year);
final checksumValid = _verifyCheck(raw);
if (!checksumValid) {
return IDCardInfo(
raw: raw,
isValid: false,
error: '校验位不正确',
id18: raw,
addressCode: addressCode,
provinceCode: provinceCode,
province: province,
birthDate: birthDate,
birth: _formatDate(birthDate),
age: _calcAge(birthDate),
gender: gender,
checksumValid: false,
constellation: _calcConstellation(birthDate.month, birthDate.day),
zodiac: _calcChineseZodiac(birthDate.year),
);
}
return IDCardInfo(
raw: raw,
isValid: true,
id18: standardized,
id18: raw,
addressCode: addressCode,
provinceCode: provinceCode,
province: province,
birthDate: birthDate,
birth: '${birthDate.year.toString().padLeft(4, '0')}-${birthDate.month.toString().padLeft(2, '0')}-${birthDate.day.toString().padLeft(2, '0')}',
age: age,
birth: _formatDate(birthDate),
age: _calcAge(birthDate),
gender: gender,
checksumValid: checksumValid,
constellation: constellation,
zodiac: zodiac,
checksumValid: true,
constellation: _calcConstellation(birthDate.month, birthDate.day),
zodiac: _calcChineseZodiac(birthDate.year),
);
}
// ---- ----
String _normalizeId(String? id) {
return (id ?? '')
.trim()
.replaceAll(' ', '')
.replaceAll(' ', '')
.replaceAll('', 'X')
.toUpperCase();
}
String _formatDate(DateTime d) {
return '${d.year.toString().padLeft(4, '0')}-'
'${d.month.toString().padLeft(2, '0')}-'
'${d.day.toString().padLeft(2, '0')}';
}
int _calcAge(DateTime birthDate) {
final now = DateTime.now();
var age = now.year - birthDate.year;
if (now.month < birthDate.month ||
(now.month == birthDate.month && now.day < birthDate.day)) {
age -= 1;
}
return age;
}
// 17 '0'-'9' 'X'
String _calcCheckChar(String id17) {
//
const weights = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
// remainder -> char
const checkMap = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'];
int sum = 0;
for (var i = 0; i < 17; i++) {
final ch = id17[i];
final n = int.tryParse(ch) ?? 0;
final n = int.parse(id17[i]);
sum += n * weights[i];
}
final mod = sum % 11;
return checkMap[mod];
return checkMap[sum % 11];
}
// 18
bool _verifyCheck(String id18) {
if (id18.length != 18) return false;
final id17 = id18.substring(0, 17);
@ -225,15 +324,23 @@ bool _verifyCheck(String id18) {
return expected == actual;
}
// 西
String _calcConstellation(int month, int day) {
const names = [
'摩羯座', '水瓶座', '双鱼座', '白羊座', '金牛座', '双子座',
'巨蟹座', '狮子座', '处女座', '天秤座', '天蝎座', '射手座'
'摩羯座',
'水瓶座',
'双鱼座',
'白羊座',
'金牛座',
'双子座',
'巨蟹座',
'狮子座',
'处女座',
'天秤座',
'天蝎座',
'射手座'
];
const startDays = [20, 19, 21, 21, 21, 22, 23, 23, 23, 23, 22, 22];
// 1
final idx = (month - 1);
final idx = month - 1;
if (day < startDays[idx]) {
return names[(idx + 11) % 12];
} else {
@ -241,12 +348,8 @@ String _calcConstellation(int month, int day) {
}
}
//
String _calcChineseZodiac(int year) {
const zodiacs = [
'', '', '', '', '', '', '', '', '', '', '', ''
];
// 1900
const zodiacs = ['', '', '', '', '', '', '', '', '', '', '', ''];
final idx = (year - 1900) % 12;
final i = idx < 0 ? (idx + 12) % 12 : idx;
return zodiacs[i];