712 lines
25 KiB
Dart
712 lines
25 KiB
Dart
|
|
import 'dart:convert';
|
|||
|
|
|
|||
|
|
import 'package:file_picker/file_picker.dart';
|
|||
|
|
import 'package:flutter/material.dart';
|
|||
|
|
import 'package:qhd_prevention/constants/app_enums.dart';
|
|||
|
|
import 'package:qhd_prevention/customWidget/ItemWidgetFactory.dart';
|
|||
|
|
import 'package:qhd_prevention/customWidget/bottom_picker.dart';
|
|||
|
|
import 'package:qhd_prevention/customWidget/custom_alert_dialog.dart';
|
|||
|
|
import 'package:qhd_prevention/customWidget/custom_button.dart';
|
|||
|
|
import 'package:qhd_prevention/customWidget/item_list_widget.dart';
|
|||
|
|
import 'package:qhd_prevention/customWidget/photo_picker_row.dart';
|
|||
|
|
import 'package:qhd_prevention/customWidget/picker/CupertinoDatePicker.dart';
|
|||
|
|
import 'package:qhd_prevention/customWidget/toast_util.dart';
|
|||
|
|
import 'package:qhd_prevention/http/ApiService.dart';
|
|||
|
|
import 'package:qhd_prevention/pages/main_tab.dart';
|
|||
|
|
import 'package:qhd_prevention/pages/mine/face_ecognition_page.dart';
|
|||
|
|
import 'package:qhd_prevention/pages/my_appbar.dart';
|
|||
|
|
import 'package:qhd_prevention/services/SessionService.dart';
|
|||
|
|
import 'package:qhd_prevention/tools/id_cart_util.dart';
|
|||
|
|
import 'package:qhd_prevention/tools/tools.dart';
|
|||
|
|
|
|||
|
|
class FullUserinfoPage extends StatefulWidget {
|
|||
|
|
const FullUserinfoPage({super.key, required this.isEidt, required this.isChooseFirm});
|
|||
|
|
|
|||
|
|
final bool isEidt;
|
|||
|
|
final bool isChooseFirm; // 是否选择过企业
|
|||
|
|
|
|||
|
|
@override
|
|||
|
|
State<FullUserinfoPage> createState() => _FullUserinfoPageState();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
class _FullUserinfoPageState extends State<FullUserinfoPage> {
|
|||
|
|
Map<String, dynamic> pd = {
|
|||
|
|
"phone": "",
|
|||
|
|
"name": "",
|
|||
|
|
"userIdCard": "",
|
|||
|
|
"birthday": "",
|
|||
|
|
"gender": "",
|
|||
|
|
"nationName": "",
|
|||
|
|
"locationAddress": "",
|
|||
|
|
"currentAddress": "",
|
|||
|
|
"culturalLevel": "",
|
|||
|
|
"politicalAffiliation": "",
|
|||
|
|
"maritalStatus": "",
|
|||
|
|
};
|
|||
|
|
Map rule = {
|
|||
|
|
"name": "请输入姓名",
|
|||
|
|
"userIdCard": "请输入身份证号码",
|
|||
|
|
"nationName": "请选择民族",
|
|||
|
|
"maritalStatus": "请选择婚姻状况",
|
|||
|
|
"culturalLevel": "请选择文化程度",
|
|||
|
|
"politicalAffiliation": "请选择政治面貌",
|
|||
|
|
"currentAddress": "请输入现居住地址",
|
|||
|
|
"locationAddress": "请输入户口所在地",
|
|||
|
|
};
|
|||
|
|
late bool _isEdit;
|
|||
|
|
|
|||
|
|
/// 标记修改
|
|||
|
|
late bool _isChange = false;
|
|||
|
|
|
|||
|
|
String _genderText = '';
|
|||
|
|
String _birthText = '';
|
|||
|
|
String _idValue = '';
|
|||
|
|
List<String> _idCardImgList = [];
|
|||
|
|
List<String> _idCartImgIds = [];
|
|||
|
|
/// 是否修改了身份证
|
|||
|
|
bool _isChangeIdCard = false;
|
|||
|
|
|
|||
|
|
List<String> _idCardImgRemoveList = [];
|
|||
|
|
|
|||
|
|
List<dynamic> _wenhuachengduList = [];
|
|||
|
|
List<dynamic> _zhengzhimianmaoList = [];
|
|||
|
|
List<dynamic> _hunyinList = [
|
|||
|
|
{"name": "已婚", "value": 1},
|
|||
|
|
{"name": "未婚", "value": 0},
|
|||
|
|
];
|
|||
|
|
List<String> idPhotos = [];
|
|||
|
|
|
|||
|
|
@override
|
|||
|
|
void initState() {
|
|||
|
|
super.initState();
|
|||
|
|
_isEdit = widget.isEidt;
|
|||
|
|
if (!_isEdit) {
|
|||
|
|
_getUserDetail();
|
|||
|
|
} else {
|
|||
|
|
pd['username'] = SessionService.instance.userName;
|
|||
|
|
pd['id'] = SessionService.instance.accountId;
|
|||
|
|
pd['flowFlag'] = 0;
|
|||
|
|
}
|
|||
|
|
_getKeyValues();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Future<void> _getUserDetail() async {
|
|||
|
|
final res = await BasicInfoApi.getUserMessage(
|
|||
|
|
'${SessionService.instance.accountId}',
|
|||
|
|
);
|
|||
|
|
if (res['success']) {
|
|||
|
|
final data = res['data'];
|
|||
|
|
_genderText = data['sex'] ?? '';
|
|||
|
|
_birthText = data['birthday'] ?? '';
|
|||
|
|
final eqForeignKey = data['userId'];
|
|||
|
|
await FileApi.getImagePathWithType(
|
|||
|
|
eqForeignKey,
|
|||
|
|
'',
|
|||
|
|
UploadFileType.idCardPhoto,
|
|||
|
|
).then((result) {
|
|||
|
|
if (result['success']) {
|
|||
|
|
List files = result['data'] ?? [];
|
|||
|
|
_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{
|
|||
|
|
final idCardBase64 = utf8.decode(base64.decode(pd['userIdCard']));
|
|||
|
|
if (idCardBase64.isNotEmpty) {
|
|||
|
|
pd['userIdCard'] =idCardBase64;
|
|||
|
|
}
|
|||
|
|
}catch(e){
|
|||
|
|
print(e);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Future<void> _getKeyValues() async {
|
|||
|
|
await BasicInfoApi.getDictValues('wenhuachengdu').then((res) {
|
|||
|
|
_wenhuachengduList = res['data'];
|
|||
|
|
});
|
|||
|
|
await BasicInfoApi.getDictValues('zhengzhimianmao').then((res) {
|
|||
|
|
_zhengzhimianmaoList = res['data'];
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
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 ;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
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) {
|
|||
|
|
pd['userIdCard'] = base64.encode(utf8.encode(pd['userIdCard']));
|
|||
|
|
await BasicInfoApi.updateUserInfo(pd).then((res) {
|
|||
|
|
LoadingDialogHelper.hide();
|
|||
|
|
if (res['success']) {
|
|||
|
|
ToastUtil.showNormal(context, '保存成功');
|
|||
|
|
Navigator.pushReplacement(
|
|||
|
|
context,
|
|||
|
|
MaterialPageRoute(builder: (_) => const MainPage(isChooseFirm: false)),
|
|||
|
|
);
|
|||
|
|
} else {
|
|||
|
|
ToastUtil.showNormal(context, '保存失败');
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
}else{
|
|||
|
|
ToastUtil.showNormal(context, '保存失败');
|
|||
|
|
LoadingDialogHelper.hide();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
Future<bool> _checkDeleteImage() async {
|
|||
|
|
late bool isSuccess = true;
|
|||
|
|
if (_idCardImgRemoveList.isNotEmpty) {
|
|||
|
|
final delIds = _idCardImgRemoveList;
|
|||
|
|
await FileApi.deleteImages(delIds).then((result) {
|
|||
|
|
if (result['success']) {
|
|||
|
|
isSuccess = true;
|
|||
|
|
} else {
|
|||
|
|
isSuccess = false;
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
}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, '').then((result) {
|
|||
|
|
if (result['success']) {
|
|||
|
|
pd['userAvatarUrl'] = result['data']['filePath'] ?? '';
|
|||
|
|
isSuccess = true;
|
|||
|
|
} else {
|
|||
|
|
LoadingDialogHelper.hide();
|
|||
|
|
ToastUtil.showNormal(context, '人脸照片上传失败');
|
|||
|
|
isSuccess = false;
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
} catch (e) {
|
|||
|
|
LoadingDialogHelper.hide();
|
|||
|
|
ToastUtil.showNormal(context, '签名上传失败');
|
|||
|
|
isSuccess = false;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return isSuccess;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// 校验是否需要上传身份证图片
|
|||
|
|
Future<bool> _checkIDCartImages() async {
|
|||
|
|
late bool isSuccess = true;
|
|||
|
|
// 身份证上传图片
|
|||
|
|
if (idPhotos.isEmpty) {
|
|||
|
|
return isSuccess;
|
|||
|
|
}
|
|||
|
|
try {
|
|||
|
|
await FileApi.uploadFiles(
|
|||
|
|
idPhotos,
|
|||
|
|
UploadFileType.idCardPhoto,
|
|||
|
|
pd['userId'] ?? '',
|
|||
|
|
).then((result) {
|
|||
|
|
if (result['success']) {
|
|||
|
|
pd['userId'] = result['data']['foreignKey'] ?? '';
|
|||
|
|
} else {
|
|||
|
|
LoadingDialogHelper.hide();
|
|||
|
|
ToastUtil.showNormal(context, '图片上传失败');
|
|||
|
|
isSuccess = false;
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
} catch (e) {
|
|||
|
|
ToastUtil.showNormal(context, '图片上传失败');
|
|||
|
|
isSuccess = false;
|
|||
|
|
}
|
|||
|
|
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 {
|
|||
|
|
// 解析失败或校验位不正确 — 清除解析字段但保留输入
|
|||
|
|
ToastUtil.showNormal(context, '请输入正确格式身份证号');
|
|||
|
|
|
|||
|
|
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;
|
|||
|
|
if (!_isEdit && FormUtils.hasValue(pd, 'id')) {
|
|||
|
|
isShow = true;
|
|||
|
|
}
|
|||
|
|
return Scaffold(
|
|||
|
|
appBar: MyAppbar(
|
|||
|
|
title: '信息补充',
|
|||
|
|
isBack: (!_isEdit || _isChange),
|
|||
|
|
onBackPressed: () async {
|
|||
|
|
if (_isChange) {
|
|||
|
|
await CustomAlertDialog.showConfirm(
|
|||
|
|
context,
|
|||
|
|
title: '温馨提示',
|
|||
|
|
content: '是否放弃修改?',
|
|||
|
|
cancelText: '取消',
|
|||
|
|
).then(
|
|||
|
|
(isSure) => {
|
|||
|
|
if (isSure) {Navigator.pop(context)},
|
|||
|
|
},
|
|||
|
|
);
|
|||
|
|
} else {
|
|||
|
|
Navigator.pop(context);
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
actions: [
|
|||
|
|
if (!_isEdit)
|
|||
|
|
TextButton(
|
|||
|
|
onPressed: () {
|
|||
|
|
setState(() {
|
|||
|
|
_isChange = true;
|
|||
|
|
_isEdit = true;
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
child: Text(
|
|||
|
|
'修改',
|
|||
|
|
style: TextStyle(color: Colors.white, fontSize: 17),
|
|||
|
|
),
|
|||
|
|
),
|
|||
|
|
],
|
|||
|
|
),
|
|||
|
|
|
|||
|
|
body: SafeArea(
|
|||
|
|
child: ItemListWidget.itemContainer(
|
|||
|
|
horizontal: 5,
|
|||
|
|
isShow
|
|||
|
|
? ListView(
|
|||
|
|
children: [
|
|||
|
|
RepairedPhotoSection(
|
|||
|
|
title: '人脸照片',
|
|||
|
|
inlineSingle: true,
|
|||
|
|
isRequired: _isEdit,
|
|||
|
|
initialMediaPaths:
|
|||
|
|
FormUtils.hasValue(pd, 'userAvatarUrl')
|
|||
|
|
? [
|
|||
|
|
'${ApiService.baseImgPath}${pd['userAvatarUrl'] ?? ''}',
|
|||
|
|
]
|
|||
|
|
: [],
|
|||
|
|
horizontalPadding: _isEdit ? 12 : 0,
|
|||
|
|
inlineImageWidth: 60,
|
|||
|
|
isFaceImage: true,
|
|||
|
|
isEdit: _isEdit,
|
|||
|
|
onChanged: (files) {
|
|||
|
|
if (files.isEmpty) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
pd['faceFiles'] = files.first.path;
|
|||
|
|
},
|
|||
|
|
onAiIdentify: () {},
|
|||
|
|
// onMediaRemovedForIndex: (index) async {
|
|||
|
|
// final deleFile = pd['userAvatarUrl'] ?? '';
|
|||
|
|
// if (deleFile.contains(UploadFileType.idCardPhoto.path)) {
|
|||
|
|
// _idCardImgRemoveList.add(deleFile);
|
|||
|
|
// }
|
|||
|
|
// },
|
|||
|
|
),
|
|||
|
|
if (_isEdit)
|
|||
|
|
ItemListWidget.itemContainer(
|
|||
|
|
const Text(
|
|||
|
|
'温馨提示:该照片为进入项目施工场所口门人脸识别使用',
|
|||
|
|
style: TextStyle(color: Colors.red, fontSize: 10),
|
|||
|
|
),
|
|||
|
|
),
|
|||
|
|
const Divider(),
|
|||
|
|
ItemListWidget.singleLineTitleText(
|
|||
|
|
label: '姓名:',
|
|||
|
|
isRequired: true,
|
|||
|
|
hintText: '请输入姓名',
|
|||
|
|
text: pd['name'] ?? '',
|
|||
|
|
isEditable: _isEdit,
|
|||
|
|
onChanged: (value) {
|
|||
|
|
pd['name'] = value;
|
|||
|
|
},
|
|||
|
|
),
|
|||
|
|
const Divider(),
|
|||
|
|
ItemListWidget.singleLineTitleText(
|
|||
|
|
label: '手机号:',
|
|||
|
|
isRequired: true,
|
|||
|
|
text: pd['username'] ?? '',
|
|||
|
|
isNumericInput: true,
|
|||
|
|
hintText: '请输入手机号',
|
|||
|
|
strongRequired: _isEdit,
|
|||
|
|
isEditable: false,
|
|||
|
|
),
|
|||
|
|
const Divider(),
|
|||
|
|
// 身份证输入:只使用 onChanged 回调(value 是实时输入框的值)
|
|||
|
|
ItemListWidget.singleLineTitleText(
|
|||
|
|
label: '身份证:',
|
|||
|
|
isRequired: true,
|
|||
|
|
hintText: '请输入身份证号',
|
|||
|
|
text: pd['userIdCard'] ?? '',
|
|||
|
|
isEditable: _isEdit,
|
|||
|
|
onChanged: (value) {
|
|||
|
|
// value 是实时输入框值
|
|||
|
|
_onIdChanged(value ?? '');
|
|||
|
|
},
|
|||
|
|
),
|
|||
|
|
const Divider(),
|
|||
|
|
ItemListWidget.selectableLineTitleTextRightButton(
|
|||
|
|
label: '民族:',
|
|||
|
|
isEditable: _isEdit,
|
|||
|
|
text: pd['nationName'] ?? '请选择',
|
|||
|
|
isRequired: _isEdit,
|
|||
|
|
onTap: () async {
|
|||
|
|
final found = await BottomPicker.show(
|
|||
|
|
context,
|
|||
|
|
items: nationMapList,
|
|||
|
|
itemBuilder:
|
|||
|
|
(i) =>
|
|||
|
|
Text(i['name']!, textAlign: TextAlign.center),
|
|||
|
|
initialIndex: 0,
|
|||
|
|
);
|
|||
|
|
//FocusHelper.clearFocus(context);
|
|||
|
|
|
|||
|
|
if (found != null) {
|
|||
|
|
setState(() {
|
|||
|
|
pd['nationName'] = found['name'];
|
|||
|
|
pd['nation'] = found['code'];
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
),
|
|||
|
|
const Divider(),
|
|||
|
|
// 性别:不可编辑,显示解析结果(也允许手动覆盖)
|
|||
|
|
ItemListWidget.selectableLineTitleTextRightButton(
|
|||
|
|
label: '性别:',
|
|||
|
|
isEditable: false,
|
|||
|
|
text: _genderText,
|
|||
|
|
|
|||
|
|
strongRequired: _isEdit,
|
|||
|
|
isRequired: true,
|
|||
|
|
onTap: () {
|
|||
|
|
// 允许手动选择覆盖解析结果
|
|||
|
|
showModalBottomSheet(
|
|||
|
|
context: context,
|
|||
|
|
builder: (_) {
|
|||
|
|
return Column(
|
|||
|
|
mainAxisSize: MainAxisSize.min,
|
|||
|
|
children: [
|
|||
|
|
ListTile(
|
|||
|
|
title: const Text('男'),
|
|||
|
|
onTap: () {
|
|||
|
|
setState(() {
|
|||
|
|
pd['gender'] = '男';
|
|||
|
|
_genderText = '男';
|
|||
|
|
});
|
|||
|
|
Navigator.pop(context);
|
|||
|
|
},
|
|||
|
|
),
|
|||
|
|
ListTile(
|
|||
|
|
title: const Text('女'),
|
|||
|
|
onTap: () {
|
|||
|
|
setState(() {
|
|||
|
|
pd['gender'] = '女';
|
|||
|
|
_genderText = '女';
|
|||
|
|
});
|
|||
|
|
Navigator.pop(context);
|
|||
|
|
},
|
|||
|
|
),
|
|||
|
|
],
|
|||
|
|
);
|
|||
|
|
},
|
|||
|
|
);
|
|||
|
|
},
|
|||
|
|
),
|
|||
|
|
const Divider(),
|
|||
|
|
// 出生年月:显示解析结果,但仍然可以手动修改
|
|||
|
|
ItemListWidget.selectableLineTitleTextRightButton(
|
|||
|
|
label: '出生年月:',
|
|||
|
|
isEditable: false,
|
|||
|
|
text: _birthText,
|
|||
|
|
strongRequired: _isEdit,
|
|||
|
|
isRequired: true,
|
|||
|
|
onTap: () async {
|
|||
|
|
},
|
|||
|
|
),
|
|||
|
|
const Divider(),
|
|||
|
|
|
|||
|
|
ItemListWidget.singleLineTitleText(
|
|||
|
|
label: '户口所在地:',
|
|||
|
|
isRequired: _isEdit,
|
|||
|
|
hintText: '请输入户口所在地',
|
|||
|
|
text: pd['locationAddress'] ?? '',
|
|||
|
|
isEditable: _isEdit,
|
|||
|
|
onChanged: (value) {
|
|||
|
|
pd['locationAddress'] = value;
|
|||
|
|
},
|
|||
|
|
),
|
|||
|
|
const Divider(),
|
|||
|
|
ItemListWidget.singleLineTitleText(
|
|||
|
|
label: '现住址:',
|
|||
|
|
isRequired: true,
|
|||
|
|
text: pd['currentAddress'] ?? '',
|
|||
|
|
hintText: '请输入现住址',
|
|||
|
|
isEditable: _isEdit,
|
|||
|
|
onChanged: (value) {
|
|||
|
|
pd['currentAddress'] = value;
|
|||
|
|
},
|
|||
|
|
),
|
|||
|
|
const Divider(),
|
|||
|
|
if (_isEdit || _idCardImgList.isNotEmpty)
|
|||
|
|
RepairedPhotoSection(
|
|||
|
|
title: '身份证照片',
|
|||
|
|
isRequired: _isEdit,
|
|||
|
|
maxCount: 2,
|
|||
|
|
initialMediaPaths:
|
|||
|
|
_idCardImgList
|
|||
|
|
.map(
|
|||
|
|
(item) =>
|
|||
|
|
ApiService.baseImgPath + item,
|
|||
|
|
)
|
|||
|
|
.toList(),
|
|||
|
|
isEdit: _isEdit,
|
|||
|
|
horizontalPadding: _isEdit ? 12 : 0,
|
|||
|
|
inlineImageWidth: 60,
|
|||
|
|
onChanged: (files) {
|
|||
|
|
idPhotos = files.map((file) => file.path).toList();
|
|||
|
|
},
|
|||
|
|
onMediaRemovedForIndex: (index) async {
|
|||
|
|
final deleFile = _idCardImgList[index];
|
|||
|
|
final deleId = _idCartImgIds[index];
|
|||
|
|
if (deleFile.contains(UploadFileType.idCardPhoto.path)) {
|
|||
|
|
_idCardImgList.removeAt(index);
|
|||
|
|
_idCartImgIds.removeAt(index);
|
|||
|
|
_idCardImgRemoveList.add(deleId);
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
onAiIdentify: () {
|
|||
|
|
/* ... */
|
|||
|
|
},
|
|||
|
|
),
|
|||
|
|
if (_isEdit)
|
|||
|
|
ItemListWidget.itemContainer(
|
|||
|
|
const Text(
|
|||
|
|
'温馨提示:用户要上传身份证正反面(身份证照片数量是2张才能进行人员培训)',
|
|||
|
|
style: TextStyle(color: Colors.red, fontSize: 10),
|
|||
|
|
),
|
|||
|
|
),
|
|||
|
|
const Divider(),
|
|||
|
|
ItemListWidget.selectableLineTitleTextRightButton(
|
|||
|
|
label: '文化程度:',
|
|||
|
|
isEditable: _isEdit,
|
|||
|
|
text: pd['culturalLevelName'] ?? '请选择',
|
|||
|
|
isRequired: _isEdit,
|
|||
|
|
onTap: () async {
|
|||
|
|
final found = await BottomPicker.show(
|
|||
|
|
context,
|
|||
|
|
items: _wenhuachengduList,
|
|||
|
|
itemBuilder:
|
|||
|
|
(i) => Text(
|
|||
|
|
i['dictLabel']!,
|
|||
|
|
textAlign: TextAlign.center,
|
|||
|
|
),
|
|||
|
|
initialIndex: 0,
|
|||
|
|
);
|
|||
|
|
//FocusHelper.clearFocus(context);
|
|||
|
|
|
|||
|
|
if (found != null) {
|
|||
|
|
setState(() {
|
|||
|
|
pd['culturalLevelName'] = found['dictLabel'];
|
|||
|
|
pd['culturalLevel'] = found['dictValue'];
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
),
|
|||
|
|
const Divider(),
|
|||
|
|
ItemListWidget.selectableLineTitleTextRightButton(
|
|||
|
|
label: '政治面貌:',
|
|||
|
|
isEditable: _isEdit,
|
|||
|
|
text: pd['politicalAffiliationName'] ?? '请选择',
|
|||
|
|
isRequired: _isEdit,
|
|||
|
|
onTap: () async {
|
|||
|
|
final found = await BottomPicker.show(
|
|||
|
|
context,
|
|||
|
|
items: _zhengzhimianmaoList,
|
|||
|
|
itemBuilder:
|
|||
|
|
(i) => Text(
|
|||
|
|
i['dictLabel']!,
|
|||
|
|
textAlign: TextAlign.center,
|
|||
|
|
),
|
|||
|
|
initialIndex: 0,
|
|||
|
|
);
|
|||
|
|
//FocusHelper.clearFocus(context);
|
|||
|
|
|
|||
|
|
if (found != null) {
|
|||
|
|
setState(() {
|
|||
|
|
pd['politicalAffiliationName'] = found['dictLabel'];
|
|||
|
|
pd['politicalAffiliation'] = found['dictValue'];
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
),
|
|||
|
|
const Divider(),
|
|||
|
|
ItemListWidget.selectableLineTitleTextRightButton(
|
|||
|
|
label: '婚姻状态:',
|
|||
|
|
isEditable: _isEdit,
|
|||
|
|
text: pd['maritalStatusName'] ?? '请选择',
|
|||
|
|
isRequired: _isEdit,
|
|||
|
|
onTap: () async {
|
|||
|
|
final found = await BottomPicker.show(
|
|||
|
|
context,
|
|||
|
|
items: _hunyinList,
|
|||
|
|
itemBuilder:
|
|||
|
|
(i) =>
|
|||
|
|
Text(i['name']!, textAlign: TextAlign.center),
|
|||
|
|
initialIndex: 0,
|
|||
|
|
);
|
|||
|
|
//FocusHelper.clearFocus(context);
|
|||
|
|
|
|||
|
|
if (found != null) {
|
|||
|
|
setState(() {
|
|||
|
|
pd['maritalStatusName'] = found['name'];
|
|||
|
|
pd['maritalStatus'] = found['value'];
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
),
|
|||
|
|
const Divider(),
|
|||
|
|
ListItemFactory.createYesNoSection(
|
|||
|
|
title: "是否流动人员:",
|
|||
|
|
horizontalPadding: 2,
|
|||
|
|
verticalPadding: 0,
|
|||
|
|
yesLabel: "是",
|
|||
|
|
noLabel: "否",
|
|||
|
|
text: pd['flowFlag'] == 1 ? '是' : '否',
|
|||
|
|
isRequired: true,
|
|||
|
|
isEdit: _isEdit,
|
|||
|
|
groupValue: (pd['flowFlag'] ?? 0) == 1,
|
|||
|
|
onChanged: (val) {
|
|||
|
|
setState(() {
|
|||
|
|
pd['flowFlag'] = val ? 1 : 0;
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
),
|
|||
|
|
const Divider(),
|
|||
|
|
ItemListWidget.singleLineTitleText(
|
|||
|
|
label: '电子邮箱:',
|
|||
|
|
isRequired: false,
|
|||
|
|
isNumericInput: false,
|
|||
|
|
hintText: '请输入电子邮箱',
|
|||
|
|
text: pd['email'] ?? '',
|
|||
|
|
isEditable: _isEdit,
|
|||
|
|
onChanged: (value) {
|
|||
|
|
pd['email'] = value;
|
|||
|
|
},
|
|||
|
|
),
|
|||
|
|
const Divider(),
|
|||
|
|
const SizedBox(height: 20),
|
|||
|
|
if (_isEdit)
|
|||
|
|
CustomButton(
|
|||
|
|
text: '保存',
|
|||
|
|
backgroundColor: Colors.blue,
|
|||
|
|
onPressed: () {
|
|||
|
|
_saveSuccess();
|
|||
|
|
},
|
|||
|
|
),
|
|||
|
|
],
|
|||
|
|
)
|
|||
|
|
: const SizedBox(),
|
|||
|
|
),
|
|||
|
|
),
|
|||
|
|
);
|
|||
|
|
}
|
|||
|
|
}
|