危险作业修改
parent
ecd2fb5591
commit
17d395cd58
|
|
@ -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,38 +715,31 @@ 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(
|
||||
child: (isEditable && isInput)
|
||||
? TextFormField(
|
||||
controller: effectiveController,
|
||||
autofocus: false,
|
||||
controller: controller,
|
||||
onChanged: (value) {
|
||||
// 触发外部回调,外部可以在回调中 setState 更新自己的变量
|
||||
onChanged?.call(value);
|
||||
},
|
||||
keyboardType: TextInputType.multiline,
|
||||
maxLines: null,
|
||||
expands: true,
|
||||
style: TextStyle(fontSize: fontSize),
|
||||
decoration: InputDecoration(
|
||||
hintText: hintText,
|
||||
//contentPadding: EdgeInsets.zero,
|
||||
border: InputBorder.none,
|
||||
),
|
||||
)
|
||||
|
|
@ -753,10 +747,7 @@ class ItemListWidget {
|
|||
padding: EdgeInsets.zero,
|
||||
child: Text(
|
||||
text,
|
||||
style: TextStyle(
|
||||
fontSize: fontSize,
|
||||
color: detailtextColor,
|
||||
),
|
||||
style: TextStyle(fontSize: fontSize, color: detailtextColor),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -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(() {
|
||||
|
|
|
|||
|
|
@ -93,10 +93,14 @@ class WorkTabIconGrid extends StatelessWidget {
|
|||
children: [
|
||||
Image.asset(iconPath, width: 30, height: 30),
|
||||
const SizedBox(height: 5),
|
||||
Text(
|
||||
SizedBox(
|
||||
width: 70, // 指定宽度,超过则自动换行
|
||||
child: Text(
|
||||
label,
|
||||
style: const TextStyle(fontSize: 13),
|
||||
textAlign: TextAlign.center,
|
||||
softWrap: true,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
|
|
|||
|
|
@ -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 =
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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: '动火部位:',
|
||||
|
|
|
|||
|
|
@ -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: '撤回',
|
||||
|
|
|
|||
|
|
@ -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: 打回删除 checkNo、workId
|
||||
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(
|
||||
|
|
|
|||
|
|
@ -320,7 +320,11 @@ class _HotDelayPageState extends State<HotDelayPage> {
|
|||
|
||||
setModalState(() {}); // 刷新弹窗内容
|
||||
},
|
||||
data: {
|
||||
'corpinfoId' :widget.data['workInfo']['corpinfoId'] ?? ''
|
||||
},
|
||||
),
|
||||
|
||||
);
|
||||
},
|
||||
),
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
),
|
||||
|
||||
|
|
|
|||
|
|
@ -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'] ?? [],
|
||||
|
|
@ -202,8 +195,9 @@ class _DlApplyPageState extends State<DlApplyPage> {
|
|||
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(
|
||||
|
|
@ -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) {
|
||||
String w = '${selectedItems.map((item) {
|
||||
final workName = SpecialWorkTypeEnum.getName(item['workType']);
|
||||
final checkNo = item['checkNo'] ?? '';
|
||||
return {'workTypeName': workName, 'checkNo': checkNo};
|
||||
}).toList();
|
||||
return '$workName $checkNo';
|
||||
}).toList().join(',')},';
|
||||
String now = pd['linkSpecialWorks'] ?? '';
|
||||
pd['linkSpecialWorks'] = now + w;
|
||||
});
|
||||
},
|
||||
);
|
||||
|
|
@ -924,16 +948,12 @@ class _DlApplyPageState extends State<DlApplyPage> {
|
|||
List<Map<String, dynamic>> extraDataList,
|
||||
) {
|
||||
setState(() {
|
||||
// addData['hiddenLevel'] = extraData?['dictValue'];
|
||||
// addData['hiddenLevelName'] = name;
|
||||
pd['riskResults'] =
|
||||
extraDataList.map((data) {
|
||||
String w = '${extraDataList.map((data) {
|
||||
final name = data['dictLabel'] ?? '';
|
||||
return {
|
||||
'riskResultName': name,
|
||||
'riskResult': data['dictValue'],
|
||||
};
|
||||
}).toList();
|
||||
return name;
|
||||
}).toList().join(',')},';
|
||||
String now = pd['riskResults'] ?? '';
|
||||
pd['riskResults'] = now + w;
|
||||
});
|
||||
},
|
||||
onSelected:
|
||||
|
|
@ -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(
|
||||
|
|
@ -1074,7 +1094,10 @@ class _DlApplyPageState extends State<DlApplyPage> {
|
|||
initialMediaPaths:
|
||||
widget.isReEdit
|
||||
? [
|
||||
FormUtils.hasValue(pd, 'workScopeAndMethodImage')
|
||||
FormUtils.hasValue(
|
||||
pd,
|
||||
'workScopeAndMethodImage',
|
||||
)
|
||||
? '${ApiService.baseImgPath}${pd['workScopeAndMethodImage']}'
|
||||
: '',
|
||||
]
|
||||
|
|
@ -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),
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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: '撤回',
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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(),
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
String w = '${selectedItems.map((item) {
|
||||
final workName = SpecialWorkTypeEnum.getName(item['workType']);
|
||||
final checkNo = item['checkNo'] ?? '';
|
||||
return {'workTypeName': workName, 'checkNo': checkNo};
|
||||
}).toList();
|
||||
return '$workName $checkNo';
|
||||
}).toList().join(',')},';
|
||||
String now = pd['linkSpecialWorks'] ?? '';
|
||||
pd['linkSpecialWorks'] = now + w;
|
||||
});
|
||||
},
|
||||
);
|
||||
|
|
@ -922,16 +945,12 @@ class _DtApplyPageState extends State<DtApplyPage> {
|
|||
List<Map<String, dynamic>> extraDataList,
|
||||
) {
|
||||
setState(() {
|
||||
// addData['hiddenLevel'] = extraData?['dictValue'];
|
||||
// addData['hiddenLevelName'] = name;
|
||||
pd['riskResults'] =
|
||||
extraDataList.map((data) {
|
||||
String w = '${extraDataList.map((data) {
|
||||
final name = data['dictLabel'] ?? '';
|
||||
return {
|
||||
'riskResultName': name,
|
||||
'riskResult': data['dictValue'],
|
||||
};
|
||||
}).toList();
|
||||
return name;
|
||||
}).toList().join(',')},';
|
||||
String now = pd['riskResults'] ?? '';
|
||||
pd['riskResults'] = now + w;
|
||||
});
|
||||
},
|
||||
onSelected:
|
||||
|
|
@ -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),
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -112,9 +112,6 @@ class _DzApplyPageState extends State<DzApplyPage> {
|
|||
};
|
||||
|
||||
// 并发请求
|
||||
final Future<Map<String, dynamic>> personFuture =
|
||||
BasicInfoApi.getDeptUsers('', isMyCorp: 1);
|
||||
|
||||
final Future<Map<String, dynamic>> initDataFuture =
|
||||
widget.isReEdit
|
||||
? SpecialWorkApi.specialWorkTaskLogDetail(widget.work_id)
|
||||
|
|
@ -122,15 +119,10 @@ class _DzApplyPageState extends State<DzApplyPage> {
|
|||
SpecialWorkTypeEnum.hoistingWork.code,
|
||||
);
|
||||
|
||||
final results = await Future.wait([personFuture, initDataFuture]);
|
||||
final results = await Future.wait([initDataFuture]);
|
||||
|
||||
final personRes = results[0];
|
||||
final initData = results[1];
|
||||
final initData = results[0];
|
||||
|
||||
// 人员列表
|
||||
if (personRes['success'] == true) {
|
||||
_allPersonList = personRes['data'] ?? [];
|
||||
}
|
||||
|
||||
printLongString(jsonEncode(initData));
|
||||
if (initData['success'] == true) {
|
||||
|
|
@ -149,6 +141,10 @@ class _DzApplyPageState extends State<DzApplyPage> {
|
|||
pd = initData['data'] ?? {};
|
||||
pd['signStepFlag'] = 2;
|
||||
pd['gasFlag'] = 2;
|
||||
pd['xgfFlag'] = 1;
|
||||
pd['operationTypeName'] = '相关方作业';
|
||||
pd['xgfFlag'] = 1;
|
||||
pd['operationTypeName'] = '相关方作业';
|
||||
levelList = pd['taskWorkLevels'] ?? [];
|
||||
await safeController.loadFromRaw(
|
||||
pd['preparers'] ?? pd['PREPARERS'] ?? [],
|
||||
|
|
@ -204,8 +200,9 @@ class _DzApplyPageState extends State<DzApplyPage> {
|
|||
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(
|
||||
|
|
@ -235,6 +232,7 @@ class _DzApplyPageState extends State<DzApplyPage> {
|
|||
// 拉该单位人员并缓存
|
||||
await _getPersonListForUnitId(id);
|
||||
},
|
||||
data: {'corpinfoId' : '${pd['projectExecutionLocationCorpId']}'},
|
||||
),
|
||||
).then((_) {
|
||||
// 可选:FocusHelper.clearFocus(context);
|
||||
|
|
@ -295,7 +293,7 @@ class _DzApplyPageState extends State<DzApplyPage> {
|
|||
await _getPersonListForUnitId(unitId);
|
||||
personList = _personCache[unitId] ?? [];
|
||||
if (personList.isEmpty) {
|
||||
ToastUtil.showNormal(context, '暂无可选人员,请选择其他单位');
|
||||
ToastUtil.showNormal(context, '暂无可选人员,请选择正确的相关方项目');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -350,6 +348,8 @@ class _DzApplyPageState extends State<DzApplyPage> {
|
|||
pd['projectId'] = id;
|
||||
pd['projectName'] = name;
|
||||
pd['xgfId'] = json['corpinfoId'];
|
||||
pd['projectExecutionLocationCorpId'] = json['projectExecutionLocationCorpId'];
|
||||
pd['projectExecutionLocationCorpName'] = json['projectExecutionLocationCorpName'];
|
||||
});
|
||||
_getRelatedPartiesUserList();
|
||||
},
|
||||
|
|
@ -365,6 +365,10 @@ class _DzApplyPageState extends State<DzApplyPage> {
|
|||
|
||||
// 获取相关方企业用户列表
|
||||
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(
|
||||
'',
|
||||
|
|
@ -494,6 +498,25 @@ class _DzApplyPageState extends State<DzApplyPage> {
|
|||
});
|
||||
}
|
||||
}
|
||||
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(() {
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -636,8 +659,7 @@ class _DzApplyPageState extends State<DzApplyPage> {
|
|||
|
||||
/// 校验是否有签字需要上传
|
||||
Future<bool> _checkImageUpdata() async {
|
||||
UploadFileType fileType =
|
||||
UploadFileType.specialOperationApplyInvolvedPhoto;
|
||||
UploadFileType fileType = UploadFileType.specialOperationApplyInvolvedPhoto;
|
||||
late bool isSuccess = true;
|
||||
if (_imageList.isNotEmpty) {
|
||||
try {
|
||||
|
|
@ -680,7 +702,6 @@ class _DzApplyPageState extends State<DzApplyPage> {
|
|||
ToastUtil.showNormal(context, err);
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
if (_imageList.isNotEmpty) {
|
||||
LoadingDialogHelper.show();
|
||||
|
|
@ -698,6 +719,9 @@ class _DzApplyPageState extends State<DzApplyPage> {
|
|||
'workType': SpecialWorkTypeEnum.hoistingWork.code,
|
||||
'xgfFlag': info['xgfFlag'] ?? '',
|
||||
'xgfId': info['xgfId'] ?? '',
|
||||
'corpinfoId' : info['projectExecutionLocationCorpId'] ?? '',
|
||||
'projectId': info['projectId'] ?? '',
|
||||
'projectName': info['projectName'] ?? '',
|
||||
'info': info,
|
||||
'gasFlag': info['gasFlag'] ?? '',
|
||||
'checkNo': info['checkNo'] ?? '',
|
||||
|
|
@ -896,12 +920,13 @@ class _DzApplyPageState extends State<DzApplyPage> {
|
|||
onConfirm: (selectedItems) {
|
||||
// 选中的数据列表
|
||||
setState(() {
|
||||
pd['linkSpecialWorks'] =
|
||||
selectedItems.map((item) {
|
||||
String w = '${selectedItems.map((item) {
|
||||
final workName = SpecialWorkTypeEnum.getName(item['workType']);
|
||||
final checkNo = item['checkNo'] ?? '';
|
||||
return {'workTypeName': workName, 'checkNo': checkNo};
|
||||
}).toList();
|
||||
return '$workName $checkNo';
|
||||
}).toList().join(',')},';
|
||||
String now = pd['linkSpecialWorks'] ?? '';
|
||||
pd['linkSpecialWorks'] = now + w;
|
||||
});
|
||||
},
|
||||
);
|
||||
|
|
@ -926,16 +951,12 @@ class _DzApplyPageState extends State<DzApplyPage> {
|
|||
List<Map<String, dynamic>> extraDataList,
|
||||
) {
|
||||
setState(() {
|
||||
// addData['hiddenLevel'] = extraData?['dictValue'];
|
||||
// addData['hiddenLevelName'] = name;
|
||||
pd['riskResults'] =
|
||||
extraDataList.map((data) {
|
||||
String w = '${extraDataList.map((data) {
|
||||
final name = data['dictLabel'] ?? '';
|
||||
return {
|
||||
'riskResultName': name,
|
||||
'riskResult': data['dictValue'],
|
||||
};
|
||||
}).toList();
|
||||
return name;
|
||||
}).toList().join(',')},';
|
||||
String now = pd['riskResults'] ?? '';
|
||||
pd['riskResults'] = now + w;
|
||||
});
|
||||
},
|
||||
onSelected:
|
||||
|
|
@ -990,14 +1011,15 @@ class _DzApplyPageState extends State<DzApplyPage> {
|
|||
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,
|
||||
|
|
@ -1008,7 +1030,7 @@ class _DzApplyPageState extends State<DzApplyPage> {
|
|||
});
|
||||
},
|
||||
),
|
||||
const Divider(),
|
||||
const Divider(height:1),
|
||||
|
||||
// 相关方作业
|
||||
ItemListWidget.selectableLineTitleTextRightButton(
|
||||
|
|
@ -1159,22 +1181,26 @@ class _DzApplyPageState extends State<DzApplyPage> {
|
|||
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')) ...[
|
||||
HoistingDetailFormWidget(pd: form, isEditable: true),
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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: '撤回',
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
),
|
||||
],
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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'] ?? [],
|
||||
|
|
@ -193,8 +178,9 @@ class _GcApplyPageState extends State<GcApplyPage> {
|
|||
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(
|
||||
|
|
@ -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: 打回删除 checkNo、workId
|
||||
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) {
|
||||
String w = '${selectedItems.map((item) {
|
||||
final workName = SpecialWorkTypeEnum.getName(item['workType']);
|
||||
final checkNo = item['checkNo'] ?? '';
|
||||
return {'workTypeName': workName, 'checkNo': checkNo};
|
||||
}).toList();
|
||||
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) {
|
||||
String w = '${extraDataList.map((data) {
|
||||
final name = data['dictLabel'] ?? '';
|
||||
return {
|
||||
'riskResultName': name,
|
||||
'riskResult': data['dictValue'],
|
||||
};
|
||||
}).toList();
|
||||
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),
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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: '撤回',
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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(),
|
||||
|
|
|
|||
|
|
@ -61,7 +61,6 @@ class _LsydApplyPageState extends State<LsydApplyPage> {
|
|||
Map<String, dynamic> pd = {};
|
||||
Map form = {};
|
||||
|
||||
|
||||
Map<String, dynamic> _initData = {};
|
||||
|
||||
/// 每一组:stepId,actorField、actUserDepartment、actUserDepartmentName、actUser、actUserName
|
||||
|
|
@ -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>(
|
||||
|
|
@ -221,13 +210,17 @@ class _LsydApplyPageState extends State<LsydApplyPage> {
|
|||
await getFlowInit();
|
||||
}
|
||||
}
|
||||
|
||||
/// 获取安全措施
|
||||
void getSafeMeasure() async {
|
||||
final reqData = {'eqWorkId': form['workId'] ?? ''};
|
||||
|
||||
final res = widget.isReEdit
|
||||
final res =
|
||||
widget.isReEdit
|
||||
? await SpecialWorkApi.specialWorkSignMeasureList(reqData)
|
||||
: await SpecialWorkApi.specialWorkMeasureList(SpecialWorkTypeEnum.electricityWork.code);
|
||||
: await SpecialWorkApi.specialWorkMeasureList(
|
||||
SpecialWorkTypeEnum.electricityWork.code,
|
||||
);
|
||||
|
||||
// 安全防护措施列表
|
||||
if (res['success'] == true) {
|
||||
|
|
@ -245,8 +238,9 @@ class _LsydApplyPageState extends State<LsydApplyPage> {
|
|||
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(
|
||||
|
|
@ -276,11 +270,13 @@ class _LsydApplyPageState extends State<LsydApplyPage> {
|
|||
// 拉该单位人员并缓存
|
||||
await _getPersonListForUnitId(id);
|
||||
},
|
||||
data: {'corpinfoId': '${pd['projectExecutionLocationCorpId']}'},
|
||||
),
|
||||
).then((_) {
|
||||
// 可选:FocusHelper.clearFocus(context);
|
||||
});
|
||||
}
|
||||
|
||||
// 选择作业单位
|
||||
void chooseWorkUnitHandle() {
|
||||
showModalBottomSheet(
|
||||
|
|
@ -298,6 +294,7 @@ class _LsydApplyPageState extends State<LsydApplyPage> {
|
|||
// 拉该单位人员并缓存
|
||||
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: 打回删除 checkNo、workId
|
||||
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) {
|
||||
String w = '${selectedItems.map((item) {
|
||||
final workName = SpecialWorkTypeEnum.getName(item['workType']);
|
||||
final checkNo = item['checkNo'] ?? '';
|
||||
return {'workTypeName': workName, 'checkNo': checkNo};
|
||||
}).toList();
|
||||
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) {
|
||||
String w = '${extraDataList.map((data) {
|
||||
final name = data['dictLabel'] ?? '';
|
||||
return {
|
||||
'riskResultName': name,
|
||||
'riskResult': data['dictValue'],
|
||||
};
|
||||
}).toList();
|
||||
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()
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
),
|
||||
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
String w = '${selectedItems.map((item) {
|
||||
final workName = SpecialWorkTypeEnum.getName(item['workType']);
|
||||
final checkNo = item['checkNo'] ?? '';
|
||||
return {'workTypeName': workName, 'checkNo': checkNo};
|
||||
}).toList();
|
||||
return '$workName $checkNo';
|
||||
}).toList().join(',')},';
|
||||
String now = pd['linkSpecialWorks'] ?? '';
|
||||
pd['linkSpecialWorks'] = now + w;
|
||||
});
|
||||
},
|
||||
);
|
||||
|
|
@ -1093,16 +1110,12 @@ class _MbcdApplyPageState extends State<MbcdApplyPage> {
|
|||
List<Map<String, dynamic>> extraDataList,
|
||||
) {
|
||||
setState(() {
|
||||
// addData['hiddenLevel'] = extraData?['dictValue'];
|
||||
// addData['hiddenLevelName'] = name;
|
||||
pd['riskResults'] =
|
||||
extraDataList.map((data) {
|
||||
String w = '${extraDataList.map((data) {
|
||||
final name = data['dictLabel'] ?? '';
|
||||
return {
|
||||
'riskResultName': name,
|
||||
'riskResult': data['dictValue'],
|
||||
};
|
||||
}).toList();
|
||||
return name;
|
||||
}).toList().join(',')},';
|
||||
String now = pd['riskResults'] ?? '';
|
||||
pd['riskResults'] = now + w;
|
||||
});
|
||||
},
|
||||
onSelected:
|
||||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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: '撤回',
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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: '管理单位:',
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
});
|
||||
},
|
||||
|
|
|
|||
|
|
@ -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 ...[
|
||||
|
|
|
|||
|
|
@ -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: '撤回',
|
||||
|
|
|
|||
|
|
@ -114,6 +114,7 @@ class _SxkjTzApplyPageState extends State<SxkjTzApplyPage> {
|
|||
pd['manageDeptId'] = id;
|
||||
});
|
||||
},
|
||||
data: {'corpinfoId' : '${pd['projectExecutionLocationCorpId']}'},
|
||||
),
|
||||
).then((_) {
|
||||
// 可选:FocusHelper.clearFocus(context);
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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,98 +93,63 @@ 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'];
|
||||
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;
|
||||
}
|
||||
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'];
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
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; // 图标区覆盖 banner 的高度
|
||||
const double iconOverlapBanner = 30.0;
|
||||
|
||||
return PopScope(
|
||||
canPop: true,
|
||||
child: Scaffold(
|
||||
extendBodyBehindAppBar: true,
|
||||
appBar: MyAppbar(title: '危险作业', backgroundColor: Colors.transparent),
|
||||
appBar: MyAppbar(
|
||||
title: '危险作业',
|
||||
backgroundColor: Colors.transparent,
|
||||
),
|
||||
body: ListView(
|
||||
physics: const AlwaysScrollableScrollPhysics(),
|
||||
padding: EdgeInsets.zero,
|
||||
|
|
@ -158,7 +171,7 @@ class _WorkTabListPageState extends RouteAwareState<WorkTabListPage> {
|
|||
right: 10,
|
||||
top: bannerHeight - iconOverlapBanner,
|
||||
height: iconSectionHeight,
|
||||
child: _buildIconSection(context),
|
||||
child: _buildIconSection(context, visibleButtons),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
|
@ -167,15 +180,15 @@ class _WorkTabListPageState extends RouteAwareState<WorkTabListPage> {
|
|||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
// 构建顶部 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),
|
||||
),
|
||||
),
|
||||
);
|
||||
if (row == 0) {
|
||||
rows.add(SizedBox(height: 12));
|
||||
}
|
||||
|
||||
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(),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
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,
|
||||
});
|
||||
}
|
||||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -376,14 +389,13 @@ 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,
|
||||
|
|
@ -394,8 +406,7 @@ class _FullUserinfoPageState extends State<FullUserinfoPage> {
|
|||
title: '人脸照片',
|
||||
inlineSingle: true,
|
||||
isRequired: _isEdit,
|
||||
initialMediaPaths:
|
||||
FormUtils.hasValue(pd, 'userAvatarUrl')
|
||||
initialMediaPaths: FormUtils.hasValue(pd, 'userAvatarUrl')
|
||||
? [
|
||||
'${ApiService.baseImgPath}${pd['userAvatarUrl'] ?? ''}',
|
||||
]
|
||||
|
|
@ -411,12 +422,6 @@ class _FullUserinfoPageState extends State<FullUserinfoPage> {
|
|||
pd['faceFiles'] = files.first.path;
|
||||
},
|
||||
onAiIdentify: () {},
|
||||
// onMediaRemovedForIndex: (index) async {
|
||||
// final deleFile = pd['userAvatarUrl'] ?? '';
|
||||
// if (deleFile.contains(UploadFileType.idCardPhoto.path)) {
|
||||
// _idCardImgRemoveList.add(deleFile);
|
||||
// }
|
||||
// },
|
||||
),
|
||||
if (_isEdit)
|
||||
ItemListWidget.itemContainer(
|
||||
|
|
@ -447,7 +452,6 @@ class _FullUserinfoPageState extends State<FullUserinfoPage> {
|
|||
isEditable: false,
|
||||
),
|
||||
const Divider(),
|
||||
// 身份证输入:只使用 onChanged 回调(value 是实时输入框的值)
|
||||
ItemListWidget.singleLineTitleText(
|
||||
label: '身份证:',
|
||||
isRequired: true,
|
||||
|
|
@ -455,7 +459,6 @@ class _FullUserinfoPageState extends State<FullUserinfoPage> {
|
|||
text: pd['userIdCard'] ?? '',
|
||||
isEditable: _isEdit,
|
||||
onChanged: (value) {
|
||||
// value 是实时输入框值
|
||||
_onIdChanged(value ?? '');
|
||||
},
|
||||
),
|
||||
|
|
@ -469,12 +472,10 @@ class _FullUserinfoPageState extends State<FullUserinfoPage> {
|
|||
final found = await BottomPicker.show(
|
||||
context,
|
||||
items: nationMapList,
|
||||
itemBuilder:
|
||||
(i) =>
|
||||
itemBuilder: (i) =>
|
||||
Text(i['name']!, textAlign: TextAlign.center),
|
||||
initialIndex: 0,
|
||||
);
|
||||
//FocusHelper.clearFocus(context);
|
||||
|
||||
if (found != null) {
|
||||
setState(() {
|
||||
|
|
@ -485,16 +486,13 @@ class _FullUserinfoPageState extends State<FullUserinfoPage> {
|
|||
},
|
||||
),
|
||||
const Divider(),
|
||||
// 性别:不可编辑,显示解析结果(也允许手动覆盖)
|
||||
ItemListWidget.selectableLineTitleTextRightButton(
|
||||
label: '性别:',
|
||||
isEditable: false,
|
||||
text: _genderText,
|
||||
|
||||
strongRequired: _isEdit,
|
||||
isRequired: true,
|
||||
onTap: () {
|
||||
// 允许手动选择覆盖解析结果
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
builder: (_) {
|
||||
|
|
@ -528,38 +526,13 @@ class _FullUserinfoPageState extends State<FullUserinfoPage> {
|
|||
},
|
||||
),
|
||||
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;
|
||||
},
|
||||
onTap: () {},
|
||||
),
|
||||
const Divider(),
|
||||
if (_isEdit || _idCardImgList.isNotEmpty)
|
||||
|
|
@ -567,11 +540,9 @@ class _FullUserinfoPageState extends State<FullUserinfoPage> {
|
|||
title: '身份证照片',
|
||||
isRequired: _isEdit,
|
||||
maxCount: 2,
|
||||
initialMediaPaths:
|
||||
_idCardImgList
|
||||
initialMediaPaths: _idCardImgList
|
||||
.map(
|
||||
(item) =>
|
||||
ApiService.baseImgPath + item,
|
||||
(item) => ApiService.baseImgPath + item,
|
||||
)
|
||||
.toList(),
|
||||
isEdit: _isEdit,
|
||||
|
|
@ -589,10 +560,7 @@ class _FullUserinfoPageState extends State<FullUserinfoPage> {
|
|||
_idCardImgRemoveList.add(deleId);
|
||||
}
|
||||
},
|
||||
|
||||
onAiIdentify: () {
|
||||
/* ... */
|
||||
},
|
||||
onAiIdentify: () {},
|
||||
),
|
||||
if (_isEdit)
|
||||
ItemListWidget.itemContainer(
|
||||
|
|
@ -611,14 +579,12 @@ class _FullUserinfoPageState extends State<FullUserinfoPage> {
|
|||
final found = await BottomPicker.show(
|
||||
context,
|
||||
items: _wenhuachengduList,
|
||||
itemBuilder:
|
||||
(i) => Text(
|
||||
itemBuilder: (i) => Text(
|
||||
i['dictLabel']!,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
initialIndex: 0,
|
||||
);
|
||||
//FocusHelper.clearFocus(context);
|
||||
|
||||
if (found != null) {
|
||||
setState(() {
|
||||
|
|
@ -638,49 +604,23 @@ class _FullUserinfoPageState extends State<FullUserinfoPage> {
|
|||
final found = await BottomPicker.show(
|
||||
context,
|
||||
items: _zhengzhimianmaoList,
|
||||
itemBuilder:
|
||||
(i) => Text(
|
||||
itemBuilder: (i) => Text(
|
||||
i['dictLabel']!,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
initialIndex: 0,
|
||||
);
|
||||
//FocusHelper.clearFocus(context);
|
||||
|
||||
if (found != null) {
|
||||
setState(() {
|
||||
pd['politicalAffiliationName'] = found['dictLabel'];
|
||||
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,
|
||||
|
|
@ -693,7 +633,6 @@ class _FullUserinfoPageState extends State<FullUserinfoPage> {
|
|||
groupValue: (pd['flowFlag'] ?? 0) == 1,
|
||||
onChanged: (val) {
|
||||
setState(() {
|
||||
|
||||
pd['flowFlag'] = val ? 1 : 0;
|
||||
});
|
||||
},
|
||||
|
|
|
|||
|
|
@ -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; // 标准化到18位(若输入15位则自动转换)
|
||||
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', '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];
|
||||
|
|
|
|||
Loading…
Reference in New Issue