Merge remote-tracking branch 'origin/master'

master
hs 2026-04-01 17:53:48 +08:00
commit b79684c14c
26 changed files with 4244 additions and 1374 deletions

View File

@ -0,0 +1,123 @@
package com.qysz.qgxgf
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.provider.Settings
import androidx.core.content.FileProvider
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel
import java.io.File
class MainActivity: FlutterActivity() {
private val CHANNEL = "app.install"
private val REQ_INSTALL_UNKNOWN = 9999
// 暂存安装请求(仅在跳转设置并等待返回时使用)
private var pendingApkPath: String? = null
private var pendingResult: MethodChannel.Result? = null
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result ->
when (call.method) {
"installApk" -> {
val path = call.argument<String>("path")
if (path == null) {
result.error("NO_PATH", "no path provided", null)
return@setMethodCallHandler
}
handleInstallRequest(path, result)
}
else -> result.notImplemented()
}
}
}
private fun handleInstallRequest(path: String, result: MethodChannel.Result) {
val file = File(path)
if (!file.exists()) {
result.error("NO_FILE", "file not exist", null)
return
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
// 8.0+ 需要 app 级别未知来源授权
if (!packageManager.canRequestPackageInstalls()) {
// 存储请求信息以便用户返回后继续
pendingApkPath = path
pendingResult = result
val intent = Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES,
Uri.parse("package:$packageName"))
// 使用 startActivityForResult 以便用户返回后可以继续安装
startActivityForResult(intent, REQ_INSTALL_UNKNOWN)
return
}
}
// 已有授权 或 非 8.0+:直接安装
installApkInternal(path, result)
}
// 真正执行安装的函数(假定有权限)
private fun installApkInternal(path: String, result: MethodChannel.Result) {
val file = File(path)
if (!file.exists()) {
result.error("NO_FILE", "file not exist", null)
return
}
try {
val apkUri: Uri = FileProvider.getUriForFile(this, "$packageName.fileprovider", file)
val intent = Intent(Intent.ACTION_VIEW)
intent.setDataAndType(apkUri, "application/vnd.android.package-archive")
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
startActivity(intent)
result.success(true)
} catch (e: Exception) {
result.error("INSTALL_FAILED", e.message, null)
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == REQ_INSTALL_UNKNOWN) {
// 用户从系统设置页返回后,检查是否已授权
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
if (packageManager.canRequestPackageInstalls()) {
// 授权已开:继续安装
val path = pendingApkPath
val res = pendingResult
// 清理 pending 状态
pendingApkPath = null
pendingResult = null
if (path != null && res != null) {
installApkInternal(path, res)
} else {
// 安全兜底:若没有 pending 数据,通知 caller 重新触发
res?.error("NO_PENDING", "no pending install info", null)
}
} else {
// 用户仍未授权
pendingApkPath = null
pendingResult?.error("NEED_INSTALL_PERMISSION", "user did not allow install unknown apps", null)
pendingResult = null
}
} else {
// API < 26尝试直接安装一次作为尝试某些 ROM 无法精准判断)
val path = pendingApkPath
val res = pendingResult
pendingApkPath = null
pendingResult = null
if (path != null && res != null) {
installApkInternal(path, res)
} else {
res?.error("NO_PENDING", "no pending install info", null)
}
}
}
}
}

View File

@ -394,6 +394,8 @@ enum UploadFileType {
'302',
'fire_safety_inspection_passed_images',
),
// /// - : '303', : 'gate_access_vehicle_signature_photo'
// gateAccessVehicleSignaturePhoto('303', 'gate_access_vehicle_signature_photo'),
/// - : '601', : 'gate_access_vehicle_license_photo'
gateAccessVehicleLicensePhoto('601', 'gate_access_vehicle_license_photo'),
@ -404,14 +406,28 @@ enum UploadFileType {
/// - : '603', : 'gate_access_vehicle_attachment'
gateAccessVehicleAttachment('603', 'gate_access_vehicle_attachment'),
/// - : '604', : 'emission_standard_certificate'
emissionStandardCertificate('604', 'emission_standard_certificate'),
// /// - : '604', : 'emission_standard_certificate'
// emissionStandardCertificate('604', 'emission_standard_certificate'),
/// (绿) - : '605', : 'motor_vehicle_registration_certificate_green_book'
motorVehicleRegistrationCertificateGreenBook(
'605',
'motor_vehicle_registration_certificate_green_book',
);
),
/// - : '611', : 'gate_access_personnel_applicant_signature'
gateAccessPersonnelApplicantSignature('611', 'gate_access_personnel_applicant_signature'),
/// - : '606', : 'gate_access_vehicle_applicant_signature'
gateAccessVehicleApplicantSignature('606', 'gate_access_vehicle_applicant_signature'),
/// - : '609', : 'enclosed_area_personnel_applicant_signature'
enclosedAreaPersonnelApplicantSignature('609', 'enclosed_area_personnel_applicant_signature'),
/// - : '610', : 'enclosed_area_vehicle_applicant_signature'
enclosedAreaVehicleApplicantSignature('610', 'enclosed_area_vehicle_applicant_signature');
const UploadFileType(this.type, this.path);

View File

@ -0,0 +1,252 @@
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:qhd_prevention/customWidget/search_bar_widget.dart';
import 'package:qhd_prevention/http/ApiService.dart';
import 'package:qhd_prevention/http/modules/doorAndCar_api.dart';
import 'package:qhd_prevention/services/SessionService.dart';
import '../tools/tools.dart'; // SessionService
//
class CategoryEnterpriseType {
final String id;
final String name;
final String pdId;
final List<CategoryEnterpriseType> children;
CategoryEnterpriseType({
required this.id,
required this.name,
required this.pdId,
this.children = const [],
});
factory CategoryEnterpriseType.fromJson(Map<String, dynamic> json) {
return CategoryEnterpriseType(
id: json['jurisdictionalCorpId'] != null ? json['jurisdictionalCorpId'].toString() : "",
name: json['jurisdictionalCorpName'] != null ? json['jurisdictionalCorpName'].toString() : "",
pdId: json['parentId'] != null ? json['parentId'].toString() : "",
children: _safeParseChildren(json['childrenList']),
);
}
static List<CategoryEnterpriseType> _safeParseChildren(dynamic childrenData) {
if (childrenData == null) return [];
if (childrenData is! List) return [];
final List<CategoryEnterpriseType> children = [];
for (var item in childrenData) {
if (item is Map<String, dynamic>) {
try {
children.add(CategoryEnterpriseType.fromJson(item));
} catch (e) {
print('解析子项失败: $e');
}
}
}
return children;
}
}
/// id name
typedef DeptSelectCallback = void Function(String id, String name,String pdId);
class DepartmentPickerEnterprise extends StatefulWidget {
/// id name
final DeptSelectCallback onSelected;
///id
final String jurisdictionalAuthorityId;
const DepartmentPickerEnterprise(this.jurisdictionalAuthorityId,{Key? key, required this.onSelected}) : super(key: key);
@override
_DepartmentPickerEnterpriseState createState() => _DepartmentPickerEnterpriseState();
}
class _DepartmentPickerEnterpriseState extends State<DepartmentPickerEnterprise> {
String selectedId = '';
String selectedPDId = '';
String selectedName = '';
Set<String> expandedSet = {};
List<CategoryEnterpriseType> original = [];
List<CategoryEnterpriseType> filtered = [];
bool loading = true;
final TextEditingController _searchController = TextEditingController();
@override
void initState() {
super.initState();
//
selectedId = '';
selectedName = '';
selectedPDId = '';
expandedSet = {};
_searchController.addListener(_onSearchChanged);
_loadData();
}
@override
void dispose() {
_searchController.removeListener(_onSearchChanged);
_searchController.dispose();
super.dispose();
}
Future<void> _loadData() async {
try {
List<dynamic> raw;
// if (SessionService.instance.departmentJsonStr?.isNotEmpty ?? false) {
// raw = json.decode(SessionService.instance.departmentJsonStr!) as List<dynamic>;
// } else {
// final result = await HiddenDangerApi.getHiddenTreatmentListTree();
// final String nodes = result['data'] as String;
// SessionService.instance.departmentJsonStr = nodes;
// raw = result['data'];
// }
final result = await DoorAndCarApi.getJurisdictionalAuthorityListTree(widget.jurisdictionalAuthorityId);
raw = result['data'];
setState(() {
original = raw.map((e) => CategoryEnterpriseType.fromJson(e as Map<String, dynamic>)).toList();
filtered = original;
loading = false;
});
} catch (e) {
setState(() => loading = false);
}
}
void _onSearchChanged() {
final query = _searchController.text.toLowerCase().trim();
setState(() {
filtered = query.isEmpty ? original : _filterCategories(original, query);
});
}
List<CategoryEnterpriseType> _filterCategories(List<CategoryEnterpriseType> list, String query) {
List<CategoryEnterpriseType> result = [];
for (var cat in list) {
final children = _filterCategories(cat.children, query);
if (cat.name.toLowerCase().contains(query) || children.isNotEmpty) {
result.add(CategoryEnterpriseType(id: cat.id, name: cat.name,pdId:cat.pdId, children: children));
}
}
return result;
}
Widget _buildRow(CategoryEnterpriseType cat, int indent) {
final hasChildren = cat.children.isNotEmpty;
final isExpanded = expandedSet.contains(cat.id);
final isSelected = cat.id == selectedId;
return Column(
children: [
InkWell(
onTap: () {
setState(() {
if (hasChildren) {
isExpanded ? expandedSet.remove(cat.id) : expandedSet.add(cat.id);
selectedPDId=cat.pdId;
}else{
selectedPDId=cat.id;
}
selectedId = cat.id;
selectedName = cat.name;
});
},
child: Container(
color: Colors.white,
child: Row(
children: [
SizedBox(width: 16.0 * indent),
SizedBox(
width: 24,
child: hasChildren
? Icon(isExpanded ? Icons.arrow_drop_down_rounded : Icons.arrow_right_rounded,
size: 35, color: Colors.grey[600])
: const SizedBox.shrink(),
),
const SizedBox(width: 5),
Expanded(
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 12),
child: Text(cat.name),
),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: Icon(
isSelected ? Icons.radio_button_checked : Icons.radio_button_unchecked,
color: Colors.blue,
),
),
],
),
),
),
if (hasChildren && isExpanded)
...cat.children.map((c) => _buildRow(c, indent + 1)),
],
);
}
@override
Widget build(BuildContext context) {
return Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height * 0.7,
color: Colors.white,
child: Column(
children: [
Container(
color: Colors.white,
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
child: Row(
children: [
GestureDetector(
onTap: () => Navigator.of(context).pop(),
child: const Text('取消', style: TextStyle(fontSize: 16)),
),
Expanded(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 12),
child: SearchBarWidget(
controller: _searchController,
isShowSearchButton: false,
onSearch: (keyboard) {
},
),
),
),
GestureDetector(
onTap: () {
Navigator.of(context).pop();
widget.onSelected(selectedId, selectedName,selectedPDId);
},
child: const Text('确定', style: TextStyle(fontSize: 16, color: Colors.blue)),
),
],
),
),
Divider(),
Expanded(
child: loading
? const Center(child: CircularProgressIndicator())
: Container(
color: Colors.white,
child: ListView.builder(
itemCount: filtered.length,
itemBuilder: (ctx, idx) => _buildRow(filtered[idx], 0),
),
),
),
],
),
);
}
}

View File

@ -54,8 +54,10 @@ typedef DeptSelectCallback = void Function(String id, String name,String pdId);
class DepartmentPickerTwo extends StatefulWidget {
/// id name
final DeptSelectCallback onSelected;
/// ID
final String id;
const DepartmentPickerTwo({Key? key, required this.onSelected}) : super(key: key);
const DepartmentPickerTwo({Key? key, required this.onSelected, this.id = '', }) : super(key: key);
@override
_DepartmentPickerTwoState createState() => _DepartmentPickerTwoState();
@ -104,7 +106,7 @@ class _DepartmentPickerTwoState extends State<DepartmentPickerTwo> {
// raw = result['data'];
// }
final result = await HiddenDangerApi.getHiddenTreatmentListTree();
final result = await HiddenDangerApi.getHiddenTreatmentListTree(widget.id);
raw = result['data'];
setState(() {

View File

@ -1523,4 +1523,120 @@ class ItemListWidget {
},
);
}
/// (TextEditingController)
/// - + TextField
/// - +
static Widget singleLineTitleTextTwo({
required String label, //
required bool isEditable, //
String? text, // /
TextEditingController? controller, //
String hintText = '请输入',
double fontSize = 14, //
bool isRequired = true,
bool strongRequired = false,
ValueChanged<String>? onChanged,
ValueChanged<String>? onFieldSubmitted,
int maxLines = 5,
bool showMaxLength = false,
//
bool isNumericInput = false,
int maxDecimalPlaces = 2,
TextInputType keyboardType = TextInputType.text,
//
bool isTextFont = true,
}) {
//
final actualKeyboardType =
isNumericInput ? const TextInputType.numberWithOptions(decimal: true) : keyboardType;
//
final List<TextInputFormatter>? numericFormatters = isNumericInput
? [
FilteringTextInputFormatter.allow(RegExp(r'[\d\.]')),
TextInputFormatter.withFunction((oldValue, newValue) {
final newText = newValue.text;
if (newText.isEmpty) return newValue;
if (newText.split('.').length > 2) return oldValue;
final regex = RegExp(r'^\d*\.?\d{0,' + maxDecimalPlaces.toString() + r'}$');
if (regex.hasMatch(newText)) return newValue;
return oldValue;
}),
]
: null;
return Container(
padding: const EdgeInsets.symmetric(
vertical: vertical_inset,
horizontal: horizontal_inset,
),
child: Row(
mainAxisAlignment: isEditable ? MainAxisAlignment.start : MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
if ((isRequired && isEditable) || strongRequired)
Text('* ', style: TextStyle(color: Colors.red)),
Text(
label,
style: TextStyle(
fontSize: fontSize,
fontWeight: FontWeight.w600,
),
),
],
),
const SizedBox(width: 8),
///
isEditable
? Expanded(
child: TextFormField(
controller: controller,
textAlign: isTextFont?TextAlign.start:TextAlign.end,
initialValue: controller == null ? text : null, // controllertext
autofocus: false,
onChanged: onChanged,
onFieldSubmitted: onFieldSubmitted,
keyboardType: actualKeyboardType,
maxLength: showMaxLength ? 120 : null,
style: TextStyle(fontSize: fontSize),
maxLines: 1,
inputFormatters: numericFormatters,
decoration: InputDecoration(
isDense: true,
hintText: hintText,
contentPadding: EdgeInsets.symmetric(vertical: 8),
),
),
)
///
: Expanded(
child: Text(
text ?? '',
maxLines: maxLines,
style: TextStyle(fontSize: fontSize, color: detailtextColor),
textAlign: TextAlign.right,
overflow: TextOverflow.ellipsis,
),
),
],
),
);
}
}

View File

@ -221,3 +221,17 @@ class CertificateApi {
}
}
//
class TodoApi {
static Future<Map<String, dynamic>> getTodoList(Map data) {
return HttpManager().request(
ApiService.basePath + '/appmenu',
'/todoList/list',
method: Method.post,
data: {
...data
},
);
}
}

View File

@ -0,0 +1,242 @@
import 'package:dio/dio.dart';
import 'package:qhd_prevention/http/ApiService.dart';
import 'package:qhd_prevention/http/HttpManager.dart';
import 'package:qhd_prevention/services/SessionService.dart';
class DoorAndCarApi {
///////=======
/// -
static Future<Map<String, dynamic>> getXgfPersonAuditList(Map data) {
return HttpManager().request(
'${ApiService.basePath}/primeport',
'/personApply/xgfPersonApplyList',
method: Method.post,
data: {
...data
},
);
}
/// ---
static Future<Map<String, dynamic>> getXgfAuditInfoById(String id) {
return HttpManager().request(
'${ApiService.basePath}/primeport',
'/personApply/xgfPersonApplyInfoById/$id',
method: Method.get,
data: {
// "id": id,
// ...data ,
},
);
}
/// -
static Future<Map<String, dynamic>> getProjectNameList() {
return HttpManager().request(
'${ApiService.basePath}',
'/xgfManager/project/listAllPassedBySelfCorp',
method: Method.get,
data: {
// ...data ,
},
);
}
/// -
static Future<Map<String, dynamic>> getPeopleinProject(String id) {
return HttpManager().request(
'${ApiService.basePath}',
'/xgfManager/projectUser/getPeopleinProject/$id',
method: Method.get,
data: {
// "id": id,
// ...data ,
},
);
}
///
static Future<Map<String, dynamic>> getApproverList(String corpId,String deptId,
String personnelPermissionFlag, //(1-,2-)
String vehiclePermissionFlag,//(1-,2-)
String temporaryPermissionFlag,//(1-,2-)
) {
return HttpManager().request(
'${ApiService.basePath}/primeport',
'/mkmjApprovalUser/listAll?corpId=$corpId'
'&personnelPermissionFlag=$personnelPermissionFlag'
'&vehiclePermissionFlag=$vehiclePermissionFlag'
'&temporaryPermissionFlag=$temporaryPermissionFlag',
method: Method.get,
data: {
"zgdw-mjspr": '/primeport/container/stakeholder/firstLevelDoor/approverUser',
// ...data
},
);
}
/// -
static Future<Map<String, dynamic>> xgfPersonSave(Map data) {
return HttpManager().request(
'${ApiService.basePath}/primeport',
'/personApply/xgfPersonSave',
method: Method.post,
data: {
...data
},
);
}
///////=======
/// -
static Future<Map<String, dynamic>> getXgfCarAuditList(Map data) {
return HttpManager().request(
'${ApiService.basePath}/primeport',
'/vehicleAudit/pendingApprovalList',
method: Method.post,
data: {
...data
},
);
}
/// -
static Future<Map<String, dynamic>> getLevelCarInfoById(String id) {
return HttpManager().request(
'${ApiService.basePath}/primeport',
'/vehicleApply/$id',
method: Method.get,
data: {
// "id": id,
// ...data ,
},
);
}
///
static Future<Map<String, dynamic>> levelCarSave(Map data) {
return HttpManager().request(
'${ApiService.basePath}/primeport',
'/vehicleApply/save',
method: Method.post,
data: {
...data
},
);
}
/////=========
/// --|-
static Future<Map<String, dynamic>> getEnclosedPersonList(Map data) {
return HttpManager().request(
'${ApiService.basePath}/primeport',
'/closedAreaPersonApply/pendingApprovalRecordList',
method: Method.post,
data: {
...data
},
);
}
/// -
static Future<Map<String, dynamic>> getEnclosedPersonById(String id) {
return HttpManager().request(
'${ApiService.basePath}/primeport',
'/closedAreaPersonApply/$id',
method: Method.get,
data: {
// "id": id,
// ...data ,
},
);
}
/// -
static Future<Map<String, dynamic>> enclosedPersonSave(Map data) {
return HttpManager().request(
'${ApiService.basePath}/primeport',
'/closedAreaPersonApply/save',
method: Method.post,
data: {
...data
},
);
}
/////=========
/// --|-
static Future<Map<String, dynamic>> getEnclosedCarList(Map data) {
return HttpManager().request(
'${ApiService.basePath}/primeport',
'/closedAreaCarApply/list',
method: Method.post,
data: {
...data
},
);
}
/// -
static Future<Map<String, dynamic>> getEnclosedCarById(String id) {
return HttpManager().request(
'${ApiService.basePath}/primeport',
'/closedAreaCarApply/$id',
method: Method.get,
data: {
// "id": id,
// ...data ,
},
);
}
/// -
static Future<Map<String, dynamic>> enclosedAreaCarSave(Map data) {
return HttpManager().request(
'${ApiService.basePath}/primeport',
'/closedAreaCarApply/save',
method: Method.post,
data: {
...data
},
);
}
///
static Future<Map<String, dynamic>> getEnclosedAreaById(String id) {
return HttpManager().request(
'${ApiService.basePath}/primeport',
'/closedArea/listAllByJurisdictionalCorpId/$id',
method: Method.get,
data: {
// "id": id,
// ...data ,
},
);
}
///
static Future<Map<String, dynamic>> getJurisdictionalAuthorityListTree(String id) {
return HttpManager().request(
'${ApiService.basePath}/primeport',
'/closedArea/listAllByhgAuthArea?hgAuthArea=$id',
method: Method.get,
data: {
},
);
}
}

View File

@ -40,14 +40,26 @@ class HiddenDangerApi {
);
}
// ///
// static Future<Map<String, dynamic>> getCorpInfoListTree() {
// return HttpManager().request(
// ApiService.basePath,
// '/basicInfo/corpInfo/listAll',
// method: Method.get,
// data: {
// "inType": '0,1',
// },
// );
// }
///
static Future<Map<String, dynamic>> getHiddenTreatmentListTree() {
static Future<Map<String, dynamic>> getHiddenTreatmentListTree(String id) {
return HttpManager().request(
ApiService.basePath,
'/basicInfo/department/listTree',
method: Method.post,
data: {
// "eqCorpinfoId": "1984137837376081921",
"eqCorpinfoId": id,
},
);
}

View File

@ -66,4 +66,42 @@ class NotifApi {
}
///
static Future<Map<String, dynamic>> getAnnouncementList(Map data) {
return HttpManager().request(
'${ApiService.basePath}/base',
'/messages/page?pageSize=9999&pageIndex=${data['pageIndex']}',
method: Method.get,
data: {
// ...data ,
},
);
}
///
static Future<Map<String, dynamic>> getAnnouncementDetail(String noticeId) {
return HttpManager().request(
'${ApiService.basePath}/message',
'/messages/$noticeId',
method: Method.get,
data: {
// ...data ,
},
);
}
///
static Future<Map<String, dynamic>> getAnnouncementRedPoint() {
return HttpManager().request(
'${ApiService.basePath}/base',
'/messages/page?pageSize=9999&pageIndex=1&statusEnum=UNREAD',
method: Method.get,
data: {
// ...data ,
},
);
}
}

View File

@ -17,11 +17,12 @@ class BadgeManager extends ChangeNotifier {
Map<String, dynamic> get workData => _workData;
//
int _notifCount = 0;
int _AnnouncementCount = 0;
// getter
int get count => _notifCount ;
int get notifCount => _notifCount;
int get notifCount => _notifCount+_AnnouncementCount;
@ -76,14 +77,13 @@ class BadgeManager extends ChangeNotifier {
Future<void> initAllModules() async {
// await Future.wait使
try {
// _safe
final fNotif = _safe<Map<String, dynamic>>(
NotifApi.getNotifRedPoint().then((r) => r as Map<String, dynamic>),
<String, dynamic>{},
timeout: const Duration(seconds: 4),
);
fNotif.then((notifJson) {
try {
_notifCount = ((notifJson['data'] as int?) ?? 0);
@ -94,6 +94,22 @@ class BadgeManager extends ChangeNotifier {
_syncNativeDebounced();
});
// _safe
final aNotif = _safe<Map<String, dynamic>>(
NotifApi.getAnnouncementRedPoint().then((r) => r as Map<String, dynamic>),
<String, dynamic>{},
timeout: const Duration(seconds: 4),
);
aNotif.then((notifJson) {
try {
_AnnouncementCount = ((notifJson['totalCount'] as int?) ?? 0);
} catch (e, st) {
debugPrint('BadgeManager.parse notifJson error: $e\n$st');
}
_scheduleNotify();
_syncNativeDebounced();
});
} catch (e, st) {
debugPrint('BadgeManager.initAllModules unexpected error: $e\n$st');
@ -110,6 +126,16 @@ class BadgeManager extends ChangeNotifier {
timeout: const Duration(seconds: 4),
);
_notifCount = (notifJson['data'] as int?) ?? 0;
final aNotifJson = await _safe<Map<String, dynamic>>(
NotifApi.getAnnouncementRedPoint().then((r) => r as Map<String, dynamic>),
<String, dynamic>{},
timeout: const Duration(seconds: 4),
);
_AnnouncementCount = (aNotifJson['totalCount'] as int?) ?? 0;
_onModuleChanged();
} catch (e) {
debugPrint('updateNotifCount error: $e');

View File

@ -1,23 +1,32 @@
import 'dart:convert';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:qhd_prevention/constants/app_enums.dart';
import 'package:qhd_prevention/customWidget/ItemWidgetFactory.dart';
import 'package:qhd_prevention/customWidget/MultiDictValuesPicker.dart';
import 'package:qhd_prevention/customWidget/bottom_picker.dart';
import 'package:qhd_prevention/customWidget/center_multi_picker.dart';
import 'package:qhd_prevention/customWidget/custom_alert_dialog.dart';
import 'package:qhd_prevention/customWidget/custom_button.dart';
import 'package:qhd_prevention/customWidget/department_picker_enterprise.dart';
import 'package:qhd_prevention/customWidget/department_picker_three.dart';
import 'package:qhd_prevention/customWidget/item_list_widget.dart';
import 'package:qhd_prevention/customWidget/photo_picker_row.dart';
import 'package:qhd_prevention/customWidget/single_image_viewer.dart';
import 'package:qhd_prevention/customWidget/toast_util.dart';
import 'package:qhd_prevention/http/ApiService.dart';
import 'package:qhd_prevention/http/modules/basic_info_api.dart';
import 'package:qhd_prevention/http/modules/doorAndCar_api.dart';
import 'package:qhd_prevention/pages/home/doorAndCar/person_selection_page.dart';
import 'package:qhd_prevention/pages/home/doorAndCar/sign_instructions_webView.dart';
import 'package:qhd_prevention/pages/mine/mine_sign_page.dart';
import 'package:qhd_prevention/pages/mine/webViewPage.dart';
import 'package:qhd_prevention/pages/my_appbar.dart';
import 'package:qhd_prevention/services/SessionService.dart';
import 'package:qhd_prevention/tools/car_licence_type.dart';
import 'package:qhd_prevention/tools/tools.dart';
import 'package:flutter/gestures.dart';
@ -29,12 +38,12 @@ class DoorareaCarAddPage extends StatefulWidget {
}
class _DoorareaCarAddPageState extends State<DoorareaCarAddPage> {
Map<String, dynamic> pd = {};
bool _agreed = false;
//
List<dynamic> _deptList = [];
List<Map> _personList = [];
List<Person> _personList = [];
List<String> signImages = [];
late bool _isMyCompanyArea = false;
@ -44,128 +53,21 @@ class _DoorareaCarAddPageState extends State<DoorareaCarAddPage> {
List<String> _vehicleImages = [];
List<String> _vehicleLicenseImages = [];
String corpinfoId = "";//
String corpinfoName = "";
String buMenId = "";//
String buMenName = "";
String responsibleId="";//
String responsibleName="";
@override
void initState() {
super.initState();
_getDept();
_getUserData();
}
//
Future<void> _getDept() async {
// try {
// final data = {
// 'eqCorpinfoId': widget.scanData['id'],
// // 'eqParentId': widget.scanData['corpinfoId'],
// };
// final result = await BasicInfoApi.getDeptTree(data);
// if (result['success'] == true) {
// final list = result['data'] ?? [];
// if (list.length > 0) {
// setState(() {
// _deptList = list[0]['childrenList'] ?? [];
// });
// }
// }
// } catch (e) {}
}
//
Future<void> _saveSuccess() async {
if (!FormUtils.hasValue(pd, 'corpinfoId')) {
ToastUtil.showNormal(context, '请选择部门');
return;
}
if (!FormUtils.hasValue(pd, 'postName')) {
ToastUtil.showNormal(context, '请输入岗位');
return;
}
// try {
// final result = await BasicInfoApi.userFirmEntry(pd);
// LoadingDialogHelper.hide();
// if (result['success'] == true) {
// ToastUtil.showNormal(context, '申请成功');
// _relogin();
// } else {
// ToastUtil.showNormal(context, result['errMessage']);
// }
// } catch (e) {
// LoadingDialogHelper.hide();
// ToastUtil.showNormal(context, '操作失败,请重试');
// }
}
Widget _addPersonWight(Map personData) {
return Stack(
children: [
Padding(padding: const EdgeInsets.only(top: 5),child: Container(
margin: const EdgeInsets.symmetric(horizontal: 12),
// padding: const EdgeInsets.symmetric(horizontal: 10),
decoration: BoxDecoration(
color: Colors.white,
//
border: Border.all(
color: Colors.grey.shade300,
width: 1.0,
style: BorderStyle.solid,
),
borderRadius: BorderRadius.circular(5),
),
child: Column(
children: [
const SizedBox(height: 10),
ItemListWidget.selectableLineTitleTextRightButton(
label: '选择部门:',
isEditable: true,
text: personData['departmentName'] ?? '请选择',
isRequired: true,
onTap: () async {},
),
const Divider(),
ItemListWidget.selectableLineTitleTextRightButton(
label: '选择人员:',
isEditable: true,
text: personData['postName'] ?? '请选择',
isRequired: true,
onTap: () async {},
),
const Divider(),
ItemListWidget.itemContainer(RepairedPhotoSection(
isRequired: true,
title: "人员照片",
maxCount: 1,
horizontalPadding: 0,
mediaType: MediaType.image,
isShowAI: false,
onChanged: (List<File> files) {},
onAiIdentify: () {},
),),
const SizedBox(height: 10)
],
)
),),
Positioned(
top: 0,
right: 2,
child: Container(
padding: const EdgeInsets.all(2),
decoration: const BoxDecoration(
shape: BoxShape.circle,
color: Colors.red,
),
child: GestureDetector(
child: const Icon(Icons.close, size: 14, color: Colors.white,),
onTap: () {
setState(() {
_personList.remove(personData);
});
},
),
),
),
],
);
}
@override
Widget build(BuildContext context) {
@ -180,36 +82,52 @@ class _DoorareaCarAddPageState extends State<DoorareaCarAddPage> {
ListItemFactory.createBuildSimpleSection('申请信息'),
const Divider(),
ItemListWidget.selectableLineTitleTextRightButton(
label: '选择港区:',
isEditable: true,
text: addData['portAreaName'] ?? '请选择',
isRequired: true,
onTap: () async {
_getPortAreaType();
},
),
const Divider(),
ItemListWidget.selectableLineTitleTextRightButton(
label: '选择管辖单位:',
isEditable: true,
text: pd['departmentName'] ?? '请选择',
text: addData['jurisdictionalCorpName'] ?? '请选择',
isRequired: true,
onTap: () async {
if (_deptList.isEmpty) {
ToastUtil.showNormal(context, '暂无部门信息');
onTap: () {
if( addData['portAreaId'].isEmpty){
ToastUtil.showNormal(context, '请先选择港区');
return;
}
final found = await BottomPicker.show(
context,
items: _deptList,
itemBuilder:
(i) => Text(i['name']!, textAlign: TextAlign.center),
initialIndex: 0,
);
//FocusHelper.clearFocus(context);
showModalBottomSheet(
context: context,
isScrollControlled: true,
barrierColor: Colors.black54,
backgroundColor: Colors.transparent,
builder:
(ctx) => DepartmentPickerEnterprise(
addData['portAreaId'],
onSelected: (id, name,pdId) async {
setState(() {
addData['jurisdictionalCorpId']= id;
addData['jurisdictionalCorpName']= name;
addData['auditPersonCorpId']= id;
addData['auditPersonCorpName']= name;
addData['auditPersonDepartmentId']= '';
addData['auditPersonDepartmentName']= '';
addData['auditPersonUserId']='';
addData['auditPersonUserName']='';
});
},
),
);
if (found != null) {
setState(() {
pd['departmentId'] = found['id'];
pd['departmentName'] = found['name'];
pd['corpinfoId'] = found['corpinfoId'];
pd['corpinfoName'] = found['corpinfoName'];
});
}
},
),
@ -218,33 +136,48 @@ class _DoorareaCarAddPageState extends State<DoorareaCarAddPage> {
ItemListWidget.selectableLineTitleTextRightButton(
label: '选择管辖区域:',
isEditable: true,
text: pd['departmentName'] ?? '请选择',
text: addData['closedAreaName']?? "请选择",
isRequired: true,
onTap: () async {},
),
const Divider(),
ItemListWidget.selectableLineTitleTextRightButton(
label: '审核人员部门:',
isEditable: true,
text: pd['departmentName'] ?? '请选择',
isRequired: true,
onTap: () async {},
onTap: () {
if(addData['jurisdictionalCorpName'].isEmpty){
ToastUtil.showNormal(context, '请选择管辖单位');
return ;
}
_getVisitPortArea();
},
),
// const Divider(),
// ItemListWidget.selectableLineTitleTextRightButton(
// label: '审核人员部门:',
// isEditable: true,
// text: addData['departmentName'] ?? '请选择',
// isRequired: true,
// onTap: () async {},
// ),
const Divider(),
ItemListWidget.selectableLineTitleTextRightButton(
label: '审核人员:',
isEditable: true,
text: pd['departmentName'] ?? '请选择',
text: addData['auditPersonUserName'] ?? '请选择',
isRequired: true,
onTap: () async {},
onTap: () {
// if ( addData['auditPersonUserName'].isEmpty) {
// ToastUtil.showNormal(context, '请先选择部门');
// return;
// }
_getApproverList();
},
),
const Divider(),
ItemListWidget.selectableLineTitleTextRightButton(
label: '选择项目:',
isEditable: true,
text: pd['departmentName'] ?? '请选择',
text: addData['projectName'] ?? '请选择',
isRequired: true,
onTap: () async {},
onTap: () {
_getProjectNameList();
},
),
const Divider(),
Padding(
@ -252,7 +185,7 @@ class _DoorareaCarAddPageState extends State<DoorareaCarAddPage> {
child: ItemListWidget.selectableLineTitleTextRightButton(
label: '选择时间:',
isEditable: false,
text: pd['departmentName'] ?? '',
text: addData['auditAllTime'] ?? '',
isRequired: true,
onTap: () async {},
),
@ -262,6 +195,9 @@ class _DoorareaCarAddPageState extends State<DoorareaCarAddPage> {
ItemListWidget.multiLineTitleTextField(
label: '申请原因',
isEditable: true,
onChanged: (value) {
addData['applyReason']=value;
},
),
@ -272,28 +208,41 @@ class _DoorareaCarAddPageState extends State<DoorareaCarAddPage> {
const Divider(),
Padding(
padding: EdgeInsets.symmetric(vertical: 8),
child: ItemListWidget.selectableLineTitleTextRightButton(
label: '驾驶人部门',
isEditable: !_isSelectCar,
onTap: () {
},
text: '',
),
),
const Divider(height: 1,),
// Padding(
// padding: EdgeInsets.symmetric(vertical: 8),
// child: ItemListWidget.selectableLineTitleTextRightButton(
// label: '驾驶人部门',
// isEditable: !_isSelectCar,
// onTap: () {
//
// },
// text: '',
// ),
// ),
// const Divider(height: 1,),
Padding(
padding: EdgeInsets.symmetric(vertical: 8),
child: ItemListWidget.selectableLineTitleTextRightButton(
label: '驾驶人',
isEditable: !_isSelectCar,
onTap: () {
onTap: () async {
if(addData['projectId'].isEmpty){
ToastUtil.showNormal(context, '请先选择项目');
return;
}
final result = await Navigator.push<SelectionPersonResult>(
context,
MaterialPageRoute(builder: (context) => PersonSelectionPage(_personList,addData['projectId'],isMoreSelect: false,)),
);
if (result != null) {
//
_showSelectedResult(context, result);
}
},
text: '',
text: _personList.isNotEmpty?_personList[0].employeePersonUserName: '请选择',
),
),
const Divider(height: 1,),
@ -305,9 +254,9 @@ class _DoorareaCarAddPageState extends State<DoorareaCarAddPage> {
label: '车牌类型',
isEditable: !_isSelectCar,
onTap: () {
_getLicensePlateType();
},
text: '',
text: addData['licenceTypeName'].isNotEmpty ? addData['licenceTypeName'] : "请选择",
),
),
@ -318,22 +267,23 @@ class _DoorareaCarAddPageState extends State<DoorareaCarAddPage> {
label: '车辆类型',
isEditable: !_isSelectCar,
onTap: () {
_getVehicleType();
},
text: '',
text: addData['vehicleTypeName'].isNotEmpty ? addData['vehicleTypeName'] : "请选择",
),
),
const Divider(height: 1,),
Padding(
padding: EdgeInsets.symmetric(vertical: 8),
child: ItemListWidget.selectableLineTitleTextRightButton(
child:ItemListWidget.singleLineTitleText(
label: '车牌号',
isEditable: !_isSelectCar,
onTap: () {
isEditable: true,
text: addData['licenceNo']??'',
onChanged: (value) {
addData['licenceNo']=value;
},
text: '',
),
),
// ItemListWidget.singleLineTitleText(
@ -399,7 +349,7 @@ class _DoorareaCarAddPageState extends State<DoorareaCarAddPage> {
side: const BorderSide(color: Colors.grey),
onChanged: (value) {
setState(() {
_agreed = value ?? false;
// _agreed = value ?? false;
});
},
),
@ -557,6 +507,464 @@ class _DoorareaCarAddPageState extends State<DoorareaCarAddPage> {
}
Future<void> _getVisitPortArea() async {
try {
LoadingDialogHelper.show();
final raw = await DoorAndCarApi.getEnclosedAreaById(addData['jurisdictionalCorpId']);
LoadingDialogHelper.hide();
if (raw['success'] ) {
List<dynamic> newList = raw['data'] ?? [];
for(int i=0;i<newList.length;i++){
newList[i]["dataId"] = newList[i]["id"];
newList[i]["dataName"] = newList[i]["closedAreaName"];
}
showModalBottomSheet(
context: context,
isScrollControlled: true,
barrierColor: Colors.black54,
backgroundColor: Colors.transparent,
builder:
(ctx) => DepartmentPickerThree(
listdata: newList,
onSelected: (id, name,pdId) async {
setState(() {
addData['closedAreaId']=id;//id
addData['closedAreaName']=name;//
});
},
),
);
}else{
ToastUtil.showNormal(context, "获取列表失败");
LoadingDialogHelper.hide();
// _showMessage('反馈提交失败');
// return "";
}
} catch (e) {
// Toast
print('加载首页数据失败:$e');
// return "";
LoadingDialogHelper.hide();
}
}
Future<void> _getApproverList() async {
try {
LoadingDialogHelper.show();
final raw = await DoorAndCarApi.getApproverList( addData['auditPersonCorpId'],'','','1','');//addData['auditDeptId']
LoadingDialogHelper.hide();
if (raw['success'] ) {
List<dynamic> newList = raw['data'] ?? [];
for(int i=0;i<newList.length;i++){
newList[i]["dataId"] = newList[i]["userId"];
newList[i]["dataName"] = newList[i]["userName"];
}
showModalBottomSheet(
context: context,
isScrollControlled: true,
barrierColor: Colors.black54,
backgroundColor: Colors.transparent,
builder:
(ctx) => DepartmentPickerThree(
listdata: newList,
onSelected: (id, name,pdId) async {
setState(() {
for(int i=0;i<newList.length;i++){
if(newList[i]["userId"]==id){
addData['auditPersonDepartmentId']=newList[i]["deptId"];//
addData['auditPersonDepartmentName']=newList[i]["deptName"];//
addData['auditPersonUserId']=newList[i]["userId"];//
addData['auditPersonUserName']=newList[i]["userName"]; //
}
}
});
},
),
);
}else{
ToastUtil.showNormal(context, "获取列表失败");
LoadingDialogHelper.hide();
// _showMessage('反馈提交失败');
// return "";
}
} catch (e) {
// Toast
print('加载首页数据失败:$e');
// return "";
LoadingDialogHelper.hide();
}
}
Future<void> _getProjectNameList() async {
try {
LoadingDialogHelper.show();
final raw = await DoorAndCarApi.getProjectNameList( );
LoadingDialogHelper.hide();
printLongString(jsonEncode(raw));
if (raw['success'] ) {
final newList = raw['data'] ?? [];
for(int i=0;i<newList.length;i++){
newList[i]["dataId"] = newList[i]["id"];
newList[i]["dataName"] = newList[i]["projectName"];
}
showModalBottomSheet(
context: context,
isScrollControlled: true,
barrierColor: Colors.black54,
backgroundColor: Colors.transparent,
builder:
(ctx) => DepartmentPickerThree(
listdata: newList,
onSelected: (id, name,pdId) async {
setState(() {
addData['projectId']=id;
addData['projectName']=name;
//
for(int i=0;i<newList.length;i++){
if(id==newList[i]["id"]){
String startProjectTime= newList[i]["startProjectTime"]??'';
String endProjectTime= newList[i]["endProjectTime"]??'';
if(startProjectTime.isNotEmpty){
addData['visitStartTime']=DateFormat('yyyy-MM-dd').format(DateTime.parse(startProjectTime));
}
if(startProjectTime.isNotEmpty){
addData['visitEndTime']=DateFormat('yyyy-MM-dd').format(DateTime.parse(endProjectTime));
}
addData['auditAllTime']='${addData['visitStartTime']}${addData['visitEndTime']}';
}
}
_personList.clear();
});
},
),
);
}else{
ToastUtil.showNormal(context, "获取列表失败");
LoadingDialogHelper.hide();
// _showMessage('反馈提交失败');
// return "";
}
} catch (e) {
// Toast
print('加载首页数据失败:$e');
// return "";
LoadingDialogHelper.hide();
}
}
void _showSelectedResult(BuildContext context, SelectionPersonResult result) {
setState(() {
_personList.clear();
for(int i=0;i<result.selectedPersons.length;i++){
_personList.add(result.selectedPersons[i]);
}
});
}
Future<void> _getPortAreaType() async {
showModalBottomSheet(
context: context,
isScrollControlled: true,
barrierColor: Colors.black54,
backgroundColor: Colors.transparent,
builder:
(_) => MultiDictValuesPicker(
title: '港区',
dictType: 'HG_AUTH_AREA',
allowSelectParent: false,
onSelected: (id, name, extraData) {
setState(() {
addData['portAreaId'] = extraData?['dictValue'];//id
addData['portAreaName'] = name;//
});
},
),
).then((_) {
// FocusHelper.clearFocus(context);
});
}
Future<void> _getLicensePlateType() async {
showModalBottomSheet(
context: context,
isScrollControlled: true,
barrierColor: Colors.black54,
backgroundColor: Colors.transparent,
builder:
(_) => MultiDictValuesPicker(
title: '车牌类型',
dictType: 'LICENSE_PLATE_TYPE',
allowSelectParent: false,
onSelected: (id, name, extraData) {
setState(() {
addData['licenceType'] = extraData?['dictValue'];
addData['licenceTypeName'] = name;
});
},
),
).then((_) {
// FocusHelper.clearFocus(context);
});
}
Future<void> _getVehicleType() async {
showModalBottomSheet(
context: context,
isScrollControlled: true,
barrierColor: Colors.black54,
backgroundColor: Colors.transparent,
builder:
(_) => MultiDictValuesPicker(
title: '车辆类型',
dictType: 'VEHICLE_TYPE',
allowSelectParent: false,
onSelected: (id, name, extraData) {
setState(() {
addData['vehicleType'] = extraData?['dictValue'];
addData['vehicleTypeName'] = name;
});
},
),
).then((_) {
// FocusHelper.clearFocus(context);
});
}
//
Future<void> _getUserData() async {
try {
final raw = await AuthApi.getUserData( );
if (raw['success'] ) {
setState(() {
corpinfoId = raw['data']['corpinfoId'];//
corpinfoName = raw['data']['corpinfoName'];
buMenId = raw['data']['departmentId'];
buMenName = raw['data']['departmentName'];
responsibleId=raw['data']['id'];
responsibleName=raw['data']['name'];
addData['applyPersonCorpId']=corpinfoId;//
addData['applyPersonCorpName']=corpinfoName;
});
}else{
ToastUtil.showNormal(context, "获取个人信息失败");
}
} catch (e) {
// Toast
print('加载首页数据失败:$e');
}
}
//
Future<void> _saveSuccess() async {
try {
if(addData['jurisdictionalCorpId'].isEmpty){
ToastUtil.showNormal(context, '请选择选择管辖单位');
return;
}
if(addData['auditPersonUserName'].isEmpty){
ToastUtil.showNormal(context, '请选择审核人员');
return;
}
if(addData['projectName'].isEmpty){
ToastUtil.showNormal(context, '请选择项目');
return;
}
if(addData['applyReason'].isEmpty){
ToastUtil.showNormal(context, '请填写申请原因');
return;
}
if(_personList.isEmpty){
ToastUtil.showNormal(context, '请选择驾驶人');
return;
}
addData['applyPersonCorpId']=_personList[0].personCorpId;
addData['applyPersonCorpName']=_personList[0].personCorpName;
addData['applyPersonDepartmentId']=_personList[0].personDepartmentId;
addData['applyPersonDepartmentName']=_personList[0].personDepartmentName;
addData['applyPersonUserId']=_personList[0].employeePersonUserId;
addData['applyPersonUserName']=_personList[0].employeePersonUserName;
addData['userFaceUrl']=_personList[0].userFaceUrl;
addData['userPhone']=_personList[0].userPhone;
addData['userCard']=_personList[0].userCard;
if(addData['licenceTypeName'].isEmpty){
ToastUtil.showNormal(context, '请选择车牌类型');
return;
}
if(addData['vehicleTypeName'].isEmpty){
ToastUtil.showNormal(context, '请选择车辆类型');
return;
}
if(addData['licenceNo'].isEmpty){
ToastUtil.showNormal(context, '请输入车牌号');
return;
}
bool isLicenseTrue = isValidChineseLicensePlate(addData['licenceNo']);
if(!isLicenseTrue){
ToastUtil.showNormal(context, '车牌号错误,请注意字母大小写');
return;
}
if(_vehicleImages.isEmpty){
ToastUtil.showNormal(context, '请上传车辆照片');
return;
}
if(_vehicleLicenseImages.isEmpty){
ToastUtil.showNormal(context, '请上传行驶证照片');
return;
}else if(_vehicleLicenseImages.length==1){
ToastUtil.showNormal(context, '请上传行驶证正反面照片');
return;
}
if(signImages.isEmpty){
ToastUtil.showNormal(context, '请阅读《安全进港须知》并签字');
return;
}
LoadingDialogHelper.show();
if(_vehicleLicenseImages.isNotEmpty){
String licenseId= await _addImgFilesLicense(_vehicleLicenseImages, UploadFileType.gateAccessVehicleLicensePhoto,addData['drivingLicenseId']);
addData['drivingLicenseId']=licenseId;
}
if(_vehicleImages.isNotEmpty){
String carImageId= await _addImgFilesLicense(_vehicleImages, UploadFileType.gateAccessVehiclePhoto,'',);
addData['attachmentId']=carImageId;
}
if(signImages.isNotEmpty){
String signImagesId= await _addImgFilesLicense(signImages, UploadFileType.enclosedAreaVehicleApplicantSignature,'');
addData['informSignId']=signImagesId;
}
LoadingDialogHelper.hide();
LoadingDialogHelper.show();
final result = await DoorAndCarApi.enclosedAreaCarSave(addData);
LoadingDialogHelper.hide();
if (result['success'] ) {
ToastUtil.showNormal(context, '提交成功');
Navigator.pop(context);
} else {
ToastUtil.showNormal(context, result['errMessage']);
}
} catch (e) {
LoadingDialogHelper.hide();
ToastUtil.showNormal(context, '操作失败,请重试');
}
}
Future<String> _addImgFilesLicense(List<String> imagePaths,UploadFileType type,String idType) async {
try {
final raw = await FileApi.uploadFiles( imagePaths, type,idType);
if (raw['success'] ) {
return raw['data']['foreignKey'];
}else{
// _showMessage('反馈提交失败');
return "";
}
} catch (e) {
// Toast
print('加载首页数据失败:$e');
return "";
}
}
Map<String, dynamic> addData={
"carBelongType": "3", //12345
"licenceType": "", //
"licenceTypeName": "", //0- 1- 2- 3-绿 4-
"licenceNo": "", //
"vehicleType": "", //
"vehicleTypeName": "", //-
"levelOneMkmjId": "", //id
"levelTwoMkmjId": "", //id()
"closedAreaId": "", //id
"closedAreaName": "", //
"visitStartTime": "", //访
"visitEndTime": "", //访
"jurisdictionalCorpId": "", //id
"jurisdictionalCorpName": "", //
"projectId": "", //id
"projectName": "", //
"applyReason": "", //
// "entourage": null, //
"informSignId": "", //
"drivingLicenseId": "", //
"attachmentId": "", //
"auditPersonCorpId": "", //ID
"auditPersonCorpName": "", //
"auditPersonDepartmentId": "", //id
"auditPersonDepartmentName": "", //
"auditPersonUserId": "", //id
"auditPersonUserName": "", //
"applyPersonCorpId": "", //ID
"applyPersonCorpName": "", //
"applyPersonDepartmentId": "", //id
"applyPersonDepartmentName": "", //
"applyPersonUserId": "", //id
"applyPersonUserName": "", //
"userFaceUrl": "", //
"userPhone": "", //
"userCard": "", //
"portAreaId": '', //id
"portAreaName": '', //
"auditAllTime": '', //
};

View File

@ -1,23 +1,31 @@
import 'dart:convert';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:qhd_prevention/constants/app_enums.dart';
import 'package:qhd_prevention/customWidget/ItemWidgetFactory.dart';
import 'package:qhd_prevention/customWidget/MultiDictValuesPicker.dart';
import 'package:qhd_prevention/customWidget/bottom_picker.dart';
import 'package:qhd_prevention/customWidget/center_multi_picker.dart';
import 'package:qhd_prevention/customWidget/custom_alert_dialog.dart';
import 'package:qhd_prevention/customWidget/custom_button.dart';
import 'package:qhd_prevention/customWidget/department_picker_three.dart';
import 'package:qhd_prevention/customWidget/item_list_widget.dart';
import 'package:qhd_prevention/customWidget/photo_picker_row.dart';
import 'package:qhd_prevention/customWidget/single_image_viewer.dart';
import 'package:qhd_prevention/customWidget/toast_util.dart';
import 'package:qhd_prevention/http/ApiService.dart';
import 'package:qhd_prevention/http/modules/basic_info_api.dart';
import 'package:qhd_prevention/http/modules/doorAndCar_api.dart';
import 'package:qhd_prevention/pages/home/doorAndCar/person_selection_page.dart';
import 'package:qhd_prevention/pages/home/doorAndCar/sign_instructions_webView.dart';
import 'package:qhd_prevention/pages/mine/mine_sign_page.dart';
import 'package:qhd_prevention/pages/mine/webViewPage.dart';
import 'package:qhd_prevention/pages/my_appbar.dart';
import 'package:qhd_prevention/services/SessionService.dart';
import 'package:qhd_prevention/tools/car_licence_type.dart';
import 'package:qhd_prevention/tools/tools.dart';
import 'package:flutter/gestures.dart';
@ -29,12 +37,14 @@ class FirstlevelCarAddPage extends StatefulWidget {
}
class _FirstlevelCarAddPageState extends State<FirstlevelCarAddPage> {
Map<String, dynamic> pd = {};
final TextEditingController _licenseController = TextEditingController();
bool _agreed = false;
//
List<dynamic> _deptList = [];
List<Map> _personList = [];
List<Person> _personList = [];
List<String> signImages = [];
late bool _isMyCompanyArea = false;
@ -44,128 +54,23 @@ class _FirstlevelCarAddPageState extends State<FirstlevelCarAddPage> {
List<String> _vehicleImages = [];
List<String> _vehicleLicenseImages = [];
String corpinfoId = "";//
String corpinfoName = "";
String buMenId = "";//
String buMenName = "";
String responsibleId="";//
String responsibleName="";
@override
void initState() {
super.initState();
_getDept();
_getUserData();
}
//
Future<void> _getDept() async {
// try {
// final data = {
// 'eqCorpinfoId': widget.scanData['id'],
// // 'eqParentId': widget.scanData['corpinfoId'],
// };
// final result = await BasicInfoApi.getDeptTree(data);
// if (result['success'] == true) {
// final list = result['data'] ?? [];
// if (list.length > 0) {
// setState(() {
// _deptList = list[0]['childrenList'] ?? [];
// });
// }
// }
// } catch (e) {}
}
//
Future<void> _saveSuccess() async {
if (!FormUtils.hasValue(pd, 'corpinfoId')) {
ToastUtil.showNormal(context, '请选择部门');
return;
}
if (!FormUtils.hasValue(pd, 'postName')) {
ToastUtil.showNormal(context, '请输入岗位');
return;
}
// try {
// final result = await BasicInfoApi.userFirmEntry(pd);
// LoadingDialogHelper.hide();
// if (result['success'] == true) {
// ToastUtil.showNormal(context, '申请成功');
// _relogin();
// } else {
// ToastUtil.showNormal(context, result['errMessage']);
// }
// } catch (e) {
// LoadingDialogHelper.hide();
// ToastUtil.showNormal(context, '操作失败,请重试');
// }
}
Widget _addPersonWight(Map personData) {
return Stack(
children: [
Padding(padding: const EdgeInsets.only(top: 5),child: Container(
margin: const EdgeInsets.symmetric(horizontal: 12),
// padding: const EdgeInsets.symmetric(horizontal: 10),
decoration: BoxDecoration(
color: Colors.white,
//
border: Border.all(
color: Colors.grey.shade300,
width: 1.0,
style: BorderStyle.solid,
),
borderRadius: BorderRadius.circular(5),
),
child: Column(
children: [
const SizedBox(height: 10),
ItemListWidget.selectableLineTitleTextRightButton(
label: '选择部门:',
isEditable: true,
text: personData['departmentName'] ?? '请选择',
isRequired: true,
onTap: () async {},
),
const Divider(),
ItemListWidget.selectableLineTitleTextRightButton(
label: '选择人员:',
isEditable: true,
text: personData['postName'] ?? '请选择',
isRequired: true,
onTap: () async {},
),
const Divider(),
ItemListWidget.itemContainer(RepairedPhotoSection(
isRequired: true,
title: "人员照片",
maxCount: 1,
horizontalPadding: 0,
mediaType: MediaType.image,
isShowAI: false,
onChanged: (List<File> files) {},
onAiIdentify: () {},
),),
const SizedBox(height: 10)
],
)
),),
Positioned(
top: 0,
right: 2,
child: Container(
padding: const EdgeInsets.all(2),
decoration: const BoxDecoration(
shape: BoxShape.circle,
color: Colors.red,
),
child: GestureDetector(
child: const Icon(Icons.close, size: 14, color: Colors.white,),
onTap: () {
setState(() {
_personList.remove(personData);
});
},
),
),
),
],
);
}
@override
Widget build(BuildContext context) {
@ -184,17 +89,21 @@ class _FirstlevelCarAddPageState extends State<FirstlevelCarAddPage> {
ItemListWidget.selectableLineTitleTextRightButton(
label: '选择项目名称:',
isEditable: true,
text: pd['departmentName'] ?? '请选择',
text: addData['projectName'] ?? '请选择',
isRequired: true,
onTap: () async {},
onTap: () {
_getProjectNameList();
},
),
const Divider(),
ItemListWidget.selectableLineTitleTextRightButton(
label: '审核人员:',
isEditable: true,
text: pd['departmentName'] ?? '请选择',
text: addData['auditUserName'] ?? '请选择',
isRequired: true,
onTap: () async {},
onTap: () {
_getApproverList();
},
),
const Divider(),
Padding(
@ -202,7 +111,7 @@ class _FirstlevelCarAddPageState extends State<FirstlevelCarAddPage> {
child: ItemListWidget.selectableLineTitleTextRightButton(
label: '选择时间:',
isEditable: false,
text: pd['departmentName'] ?? '',
text: addData['auditAllTime'] ?? '',
isRequired: true,
onTap: () async {},
),
@ -211,19 +120,21 @@ class _FirstlevelCarAddPageState extends State<FirstlevelCarAddPage> {
ItemListWidget.selectableLineTitleTextRightButton(
label: '访问港区:',
isEditable: true,
text: pd['departmentName'] ?? '请选择',
text: addData['gateLevelAuthAreaName'] ?? '请选择',
isRequired: true,
onTap: () async {},
),
const Divider(),
ItemListWidget.selectableLineTitleTextRightButton(
label: '选择范围:',
isEditable: true,
text: pd['departmentName'] ?? '请选择',
isRequired: true,
onTap: () async {},
onTap: () {
_getVisitPortArea();
},
),
const Divider(),
// ItemListWidget.selectableLineTitleTextRightButton(
// label: '选择范围:',
// isEditable: true,
// text: pd['departmentName'] ?? '请选择',
// isRequired: true,
// onTap: () async {},
// ),
// const Divider(),
// ItemListWidget.multiLineTitleTextField(
// label: '申请原因',
// isEditable: true,
@ -237,28 +148,41 @@ class _FirstlevelCarAddPageState extends State<FirstlevelCarAddPage> {
const Divider(),
Padding(
padding: EdgeInsets.symmetric(vertical: 8),
child: ItemListWidget.selectableLineTitleTextRightButton(
label: '驾驶人部门',
isEditable: !_isSelectCar,
onTap: () {
},
text: '',
),
),
const Divider(height: 1,),
// Padding(
// padding: EdgeInsets.symmetric(vertical: 8),
// child: ItemListWidget.selectableLineTitleTextRightButton(
// label: '驾驶人部门',
// isEditable: !_isSelectCar,
// onTap: () {
//
// },
// text: '',
// ),
// ),
// const Divider(height: 1,),
Padding(
padding: EdgeInsets.symmetric(vertical: 8),
child: ItemListWidget.selectableLineTitleTextRightButton(
label: '驾驶人',
isEditable: !_isSelectCar,
onTap: () {
onTap: () async {
if(addData['projectId'].isEmpty){
ToastUtil.showNormal(context, '请先选择项目');
return;
}
final result = await Navigator.push<SelectionPersonResult>(
context,
MaterialPageRoute(builder: (context) => PersonSelectionPage(_personList,addData['projectId'],isMoreSelect: false,)),
);
if (result != null) {
//
_showSelectedResult(context, result);
}
},
text: '',
text: _personList.isNotEmpty?_personList[0].employeePersonUserName: '请选择',
),
),
const Divider(height: 1,),
@ -270,9 +194,9 @@ class _FirstlevelCarAddPageState extends State<FirstlevelCarAddPage> {
label: '车牌类型',
isEditable: !_isSelectCar,
onTap: () {
_getLicensePlateType();
},
text: '',
text: addData['licenceTypeName'].isNotEmpty ? addData['licenceTypeName'] : "请选择",
),
),
@ -283,32 +207,26 @@ class _FirstlevelCarAddPageState extends State<FirstlevelCarAddPage> {
label: '车辆类型',
isEditable: !_isSelectCar,
onTap: () {
_getVehicleType();
},
text: '',
text: addData['vehicleTypeName'].isNotEmpty ? addData['vehicleTypeName'] : "请选择",
),
),
const Divider(height: 1,),
Padding(
padding: EdgeInsets.symmetric(vertical: 8),
child: ItemListWidget.selectableLineTitleTextRightButton(
child:ItemListWidget.singleLineTitleTextTwo(
controller: _licenseController,
label: '车牌号',
isEditable: !_isSelectCar,
onTap: () {
isEditable: true,
text: addData['licenceNo']??'',
onChanged: (value) {
addData['licenceNo']=value;
},
text: '',
),
),
// ItemListWidget.singleLineTitleText(
// label: '车牌号',
// isEditable: !_isSelectCar,
// text: '',
// onChanged: (value) {
//
// },
// ),
const Divider(),
@ -364,7 +282,7 @@ class _FirstlevelCarAddPageState extends State<FirstlevelCarAddPage> {
side: const BorderSide(color: Colors.grey),
onChanged: (value) {
setState(() {
_agreed = value ?? false;
// _agreed = value ?? false;
});
},
),
@ -522,6 +440,450 @@ class _FirstlevelCarAddPageState extends State<FirstlevelCarAddPage> {
}
//
Future<void> _getUserData() async {
try {
final raw = await AuthApi.getUserData( );
if (raw['success'] ) {
setState(() {
corpinfoId = raw['data']['corpinfoId'];//
corpinfoName = raw['data']['corpinfoName'];
buMenId = raw['data']['departmentId'];
buMenName = raw['data']['departmentName'];
responsibleId=raw['data']['id'];
responsibleName=raw['data']['name'];
addData['vehicleCorpId']=corpinfoId;//
addData['vehicleCorpName']=corpinfoName;
});
}else{
ToastUtil.showNormal(context, "获取个人信息失败");
}
} catch (e) {
// Toast
print('加载首页数据失败:$e');
}
}
Future<void> _getProjectNameList() async {
try {
LoadingDialogHelper.show();
final raw = await DoorAndCarApi.getProjectNameList( );
LoadingDialogHelper.hide();
printLongString(jsonEncode(raw));
if (raw['success'] ) {
final newList = raw['data'] ?? [];
for(int i=0;i<newList.length;i++){
newList[i]["dataId"] = newList[i]["id"];
newList[i]["dataName"] = newList[i]["projectName"];
}
showModalBottomSheet(
context: context,
isScrollControlled: true,
barrierColor: Colors.black54,
backgroundColor: Colors.transparent,
builder:
(ctx) => DepartmentPickerThree(
listdata: newList,
onSelected: (id, name,pdId) {
setState(() {
addData['projectId']=id;
addData['projectName']=name;
//
for(int i=0;i<newList.length;i++){
if(id==newList[i]["id"]){
String startProjectTime= newList[i]["startProjectTime"]??'';
String endProjectTime= newList[i]["endProjectTime"]??'';
if(startProjectTime.isNotEmpty){
addData['visitStartTime']=DateFormat('yyyy-MM-dd').format(DateTime.parse(startProjectTime));
}
if(startProjectTime.isNotEmpty){
addData['visitEndTime']=DateFormat('yyyy-MM-dd').format(DateTime.parse(endProjectTime));
}
addData['auditAllTime']='${addData['visitStartTime']}${addData['visitEndTime']}';
}
}
_personList.clear();
});
},
),
);
}else{
ToastUtil.showNormal(context, "获取列表失败");
LoadingDialogHelper.hide();
// _showMessage('反馈提交失败');
// return "";
}
} catch (e) {
// Toast
print('加载首页数据失败:$e');
// return "";
LoadingDialogHelper.hide();
}
}
Future<void> _getApproverList() async {
try {
LoadingDialogHelper.show();
final raw = await DoorAndCarApi.getApproverList( corpinfoId,'','','1','');
LoadingDialogHelper.hide();
if (raw['success'] ) {
List<dynamic> newList = raw['data'] ?? [];
for(int i=0;i<newList.length;i++){
newList[i]["dataId"] = newList[i]["userId"];
newList[i]["dataName"] = newList[i]["userName"];
}
showModalBottomSheet(
context: context,
isScrollControlled: true,
barrierColor: Colors.black54,
backgroundColor: Colors.transparent,
builder:
(ctx) => DepartmentPickerThree(
listdata: newList,
onSelected: (id, name,pdId) async {
setState(() {
for(int i=0;i<newList.length;i++){
if(newList[i]["userId"]==id){
addData['auditCorpId']=newList[i]["corpId"];//
addData['auditCorpName']=newList[i]["corpName"];//
addData['auditDeptId']=newList[i]["deptId"];//
addData['auditDeptName']=newList[i]["deptName"];//
addData['auditUserId']=newList[i]["userId"];//
addData['auditUserName']=newList[i]["userName"]; //
}
}
});
},
),
);
}else{
ToastUtil.showNormal(context, "获取列表失败");
LoadingDialogHelper.hide();
// _showMessage('反馈提交失败');
// return "";
}
} catch (e) {
// Toast
print('加载首页数据失败:$e');
// return "";
LoadingDialogHelper.hide();
}
}
Future<void> _getVisitPortArea() async {
List<String> result = [];
//
final List<int> initialIndices = [];
final resultList = await BasicInfoApi.getDictValues('HG_AUTH_AREA');
List<dynamic> raw = resultList["data"] as List<dynamic>;
result = raw.map((item) => item['dictLabel'].toString()).toList();
if(addData['gateLevelAuthArea'].isNotEmpty){
// JSON
Map<String, dynamic> jsonData = json.decode(addData['gateLevelAuthArea']);
List<dynamic> areaList = jsonData['area'];
// value
List<String> targetValues = areaList.map((item) => item['value'].toString()).toList();
// raw
for (String targetValue in targetValues) {
for (int i = 0; i < raw.length; i++) {
var item = raw[i];
if (item != null && item is Map && item.containsKey('dictLabel')) {
if (item['dictLabel'].toString() == targetValue) {
initialIndices.add(i);// 0
break;
}
}
}
}
}
//
final selectedItems = await CenterMultiPicker.show<String>(
context,
items: result,
itemBuilder: (item) => Text(
item,
style: const TextStyle(fontSize: 16),
),
initialSelectedIndices: initialIndices, //
maxSelection: null, //
allowEmpty: true,
title: '访问港区范围',
);
//
if (selectedItems != null) {
setState(() {
addData['gateLevelAuthAreaName'] = selectedItems.join(',');
// JSON
List<Map<String, dynamic>> areaList = [];
// raw
for (String selectedItem in selectedItems) {
for (var item in raw) {
if (item != null && item is Map && item.containsKey('dictLabel')) {
if (item['dictLabel'].toString() == selectedItem) {
// value(dictLabel) bianma(dictValue)
areaList.add({
'value': item['dictLabel'].toString(),
'bianma': item['dictValue'].toString(), // 使 toString()
});
break;
}
}
}
}
// JSON
Map<String, dynamic> jsonData = {
'area': areaList
};
// Map JSON
addData['gateLevelAuthArea'] = json.encode(jsonData);
});
}
}
void _showSelectedResult(BuildContext context, SelectionPersonResult result) {
setState(() {
_personList.clear();
for(int i=0;i<result.selectedPersons.length;i++){
_personList.add(result.selectedPersons[i]);
}
});
}
Future<void> _getLicensePlateType() async {
showModalBottomSheet(
context: context,
isScrollControlled: true,
barrierColor: Colors.black54,
backgroundColor: Colors.transparent,
builder:
(_) => MultiDictValuesPicker(
title: '车牌类型',
dictType: 'LICENSE_PLATE_TYPE',
allowSelectParent: false,
onSelected: (id, name, extraData) {
setState(() {
addData['licenceType'] = extraData?['dictValue'];
addData['licenceTypeName'] = name;
});
},
),
).then((_) {
// FocusHelper.clearFocus(context);
});
}
Future<void> _getVehicleType() async {
showModalBottomSheet(
context: context,
isScrollControlled: true,
barrierColor: Colors.black54,
backgroundColor: Colors.transparent,
builder:
(_) => MultiDictValuesPicker(
title: '车辆类型',
dictType: 'VEHICLE_TYPE',
allowSelectParent: false,
onSelected: (id, name, extraData) {
setState(() {
addData['vehicleType'] = extraData?['dictValue'];
addData['vehicleTypeName'] = name;
});
},
),
).then((_) {
// FocusHelper.clearFocus(context);
});
}
//
Future<void> _saveSuccess() async {
try {
if(addData['projectName'].isEmpty){
ToastUtil.showNormal(context, '请选择选择项目名称');
return;
}
if(addData['auditUserName'].isEmpty){
ToastUtil.showNormal(context, '请选择审核人员');
return;
}
if(addData['gateLevelAuthAreaName'].isEmpty){
ToastUtil.showNormal(context, '请选择访问港区');
return;
}
if(_personList.isEmpty){
ToastUtil.showNormal(context, '请选择驾驶人');
return;
}
addData['drivingUserId']=_personList[0].userPhone;
addData['drivingUserName']=_personList[0].userCard;
addData['lsUserPhone']=_personList[0].userPhone;
addData['lsUserIdcard']=_personList[0].userCard;
if(addData['licenceTypeName'].isEmpty){
ToastUtil.showNormal(context, '请选择车牌类型');
return;
}
if(addData['vehicleTypeName'].isEmpty){
ToastUtil.showNormal(context, '请选择车辆类型');
return;
}
if(addData['licenceNo'].isEmpty){
ToastUtil.showNormal(context, '请输入车牌号');
return;
}
bool isLicenseTrue = isValidChineseLicensePlate(addData['licenceNo']);
if(!isLicenseTrue){
ToastUtil.showNormal(context, '车牌号错误,请注意字母大小写');
return;
}
if(_vehicleLicenseImages.isEmpty){
ToastUtil.showNormal(context, '请上传行驶证照片');
return;
}else if(_vehicleLicenseImages.length==1){
ToastUtil.showNormal(context, '请上传行驶证正反面照片');
return;
}
if(_vehicleImages.isEmpty){
ToastUtil.showNormal(context, '请上传车辆照片');
return;
}
if(signImages.isEmpty){
ToastUtil.showNormal(context, '请阅读《安全进港须知》并签字');
return;
}
LoadingDialogHelper.show();
if(_vehicleLicenseImages.isNotEmpty){
String licenseId= await _addImgFilesLicense(_vehicleLicenseImages, UploadFileType.gateAccessVehicleLicensePhoto,addData['drivingLicenseId']);
addData['drivingLicenseId']=licenseId;
}
if(_vehicleImages.isNotEmpty){
String carImageId= await _addImgFilesLicense(_vehicleImages, UploadFileType.gateAccessVehiclePhoto,'',);
addData['attachmentId']=carImageId;
}
if(signImages.isNotEmpty){
String signImagesId= await _addImgFilesLicense(signImages, UploadFileType.gateAccessVehicleApplicantSignature,'');
addData['informSignId']=signImagesId;
}
LoadingDialogHelper.hide();
LoadingDialogHelper.show();
final result = await DoorAndCarApi.levelCarSave(addData);
LoadingDialogHelper.hide();
if (result['success'] == true) {
ToastUtil.showNormal(context, '提交成功');
Navigator.pop(context);
} else {
ToastUtil.showNormal(context, result['errMessage']);
}
} catch (e) {
LoadingDialogHelper.hide();
ToastUtil.showNormal(context, '操作失败,请重试');
}
}
Future<String> _addImgFilesLicense(List<String> imagePaths,UploadFileType type,String idType) async {
try {
final raw = await FileApi.uploadFiles( imagePaths, type,idType);
if (raw['success'] ) {
return raw['data']['foreignKey'];
}else{
// _showMessage('反馈提交失败');
return "";
}
} catch (e) {
// Toast
print('加载首页数据失败:$e');
return "";
}
}
Map<String, dynamic> addData={
"licenceType": "", //
"licenceTypeName": "", //0- 1- 2- 3-绿 4-
"licenceNo": "", //
"vehicleType": "", //
"vehicleTypeName": "", //-
"vehicleBelongType": "5", // 1-2-3-4- 5- 6:7
"gateLevelAuthArea": "", //
"visitStartTime": "", //访
"visitEndTime": "", //访
"emissionStandards": "", //
"emissionStandardsName": "", //
"drivingLicenseId": '', //
"attachmentId": '', //
"informSignId": '', //
"projectId": '', //id
"projectName": "", //
"blockedFlag": '', //12
"mkmjId": '', //id
"lsUserPhone": "", //
"lsUserIdcard": "", //
"auditCorpId": '', //
"auditCorpName": "", //
"auditDeptId": '', //
"auditDeptName": "", //
"auditUserId": '', //
"auditUserName": "", //
"auditAllTime": '', //
"gateLevelAuthAreaName": "", //访
};

View File

@ -1,41 +1,51 @@
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:qhd_prevention/constants/app_enums.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/single_image_viewer.dart';
import 'package:qhd_prevention/customWidget/toast_util.dart';
import 'package:qhd_prevention/http/ApiService.dart';
import 'package:qhd_prevention/http/modules/doorAndCar_api.dart';
import 'package:qhd_prevention/pages/my_appbar.dart';
import 'package:qhd_prevention/tools/h_colors.dart';
import 'package:qhd_prevention/tools/tools.dart';
class CarApplicationRecord extends StatefulWidget {
const CarApplicationRecord(this.type, {super.key});
class OnlylookCarApplication extends StatefulWidget {
const OnlylookCarApplication(this.type, this.id, {super.key});
final int type;//1 2 3 () 4 ()
final String id;
@override
State<CarApplicationRecord> createState() => _CarApplicationRecordState();
State<OnlylookCarApplication> createState() => _OnlylookCarApplicationState();
}
class _CarApplicationRecordState extends State<CarApplicationRecord> {
//
final Map<String, String> applicationInfo = {
'mingcheng': '项目名称',
'bumen': '审核人员部门',
'renyuan': '审核人员',
'shijian': '2024-01-01 至 2024-12-31',
'gangqu': '访问港区',
'diqu': '访问地区',
};
class _OnlylookCarApplicationState extends State<OnlylookCarApplication> {
//
final Map<String, String> vehicleInfo = {
'name': '驾驶人姓名',
'type': '车辆类型',
'licenseType': '车牌号类型',
'license': '车牌号',};
//
dynamic applicationInfo = {};
//
List<dynamic> personnelList = [];
//
List<String> signList = [];
//
List<String> licenseList = [];
//
List<String> attachmentList = [];
@override
void initState() {
super.initState();
_getXgfApplyInfoById();
}
@override
@ -63,7 +73,7 @@ class _CarApplicationRecordState extends State<CarApplicationRecord> {
SizedBox(height: 12),
//
_buildCarCard(vehicleInfo),
_buildCarCard(applicationInfo),
SizedBox(height: 16),
@ -113,7 +123,7 @@ class _CarApplicationRecordState extends State<CarApplicationRecord> {
label: '项目名称:',
isEditable: false,
horizontalnum: 0,
text: applicationInfo['mingcheng'] ?? '',
text: applicationInfo['projectName'] ?? '',
onTap: () {},
),
const Divider(),
@ -121,52 +131,52 @@ class _CarApplicationRecordState extends State<CarApplicationRecord> {
label: '访问港区:',
isEditable: false,
horizontalnum: 0,
text: applicationInfo['gangqu'] ?? '',
text: _getAccessArea(applicationInfo),
onTap: () {},
),
const Divider(),
ItemListWidget.selectableLineTitleTextRightButton(
label: '区域范围:',
isEditable: false,
horizontalnum: 0,
text: applicationInfo['diqu'] ?? '',
onTap: () {},
),
const Divider(),
// ItemListWidget.selectableLineTitleTextRightButton(
// label: '区域范围:',
// isEditable: false,
// horizontalnum: 0,
// text: applicationInfo['diqu'] ?? '',
// onTap: () {},
// ),
// const Divider(),
ItemListWidget.selectableLineTitleTextRightButton(
label: '审核人员部门:',
isEditable: false,
horizontalnum: 0,
text: applicationInfo['bumen'] ?? '',
onTap: () {},
),
const Divider(),
// ItemListWidget.selectableLineTitleTextRightButton(
// label: '审核人员部门:',
// isEditable: false,
// horizontalnum: 0,
// text: applicationInfo['bumen'] ?? '',
// onTap: () {},
// ),
// const Divider(),
ItemListWidget.selectableLineTitleTextRightButton(
label: '审核人员:',
isEditable: false,
horizontalnum: 0,
text: applicationInfo['renyuan'] ?? '',
text: personnelList.isNotEmpty? personnelList[0]['auditUserName'] ?? '':'',
onTap: () {},
),
const Divider(),
ItemListWidget.selectableLineTitleTextRightButton(
label: '所属项目:',
isEditable: false,
horizontalnum: 0,
text: applicationInfo['mingcheng'] ?? '',
onTap: () {},
),
const Divider(),
// ItemListWidget.selectableLineTitleTextRightButton(
// label: '所属项目:',
// isEditable: false,
// horizontalnum: 0,
// text: applicationInfo['mingcheng'] ?? '',
// onTap: () {},
// ),
// const Divider(),
ItemListWidget.selectableLineTitleTextRightButton(
label: '选择时间:',
isEditable: false,
horizontalnum: 0,
text: applicationInfo['shijian'] ?? '',
text: _changeTime(applicationInfo),
onTap: () {},
),
const Divider(),
@ -187,7 +197,7 @@ class _CarApplicationRecordState extends State<CarApplicationRecord> {
label: '驾驶人姓名:',
isEditable: false,
horizontalnum: 0,
text: info['name'] ?? '',
text: info['employeeVehicleUserName'] ?? '',
onTap: () {},
),
const Divider(),
@ -195,7 +205,7 @@ class _CarApplicationRecordState extends State<CarApplicationRecord> {
label: '车辆类型:',
isEditable: false,
horizontalnum: 0,
text: info['type'] ?? '',
text: info['vehicleTypeName'] ?? '',
onTap: () {},
),
const Divider(),
@ -204,7 +214,7 @@ class _CarApplicationRecordState extends State<CarApplicationRecord> {
label: '车牌号类型:',
isEditable: false,
horizontalnum: 0,
text: info['licenseType'] ?? '',
text: info['licenceTypeName'] ?? '',
onTap: () {},
),
const Divider(),
@ -213,22 +223,24 @@ class _CarApplicationRecordState extends State<CarApplicationRecord> {
label: '车牌号:',
isEditable: false,
horizontalnum: 0,
text: info['license'] ?? '',
text: info['licenceNo'] ?? '',
onTap: () {},
),
const Divider(),
//
_buildPhotoItem(1),
_buildPhotoItem(1,licenseList),
const Divider(),
_buildPhotoItem(2),
_buildPhotoItem(2,attachmentList),
const Divider(),
// _buildPhotoItem(3),
if(signList.isNotEmpty)
Container(
height: 150,
padding: EdgeInsets.all(8),
alignment: Alignment.center,
child: Image.network('${ApiService.baseImgPath}1983773013086048256/202601/ai_recognition_images/a9c8e701f773470d8a8485ccb6fb35b7.jpg'),
child: Image.network('${ApiService.baseImgPath}${signList[0]}'),
),
// const Divider(),
@ -238,7 +250,7 @@ class _CarApplicationRecordState extends State<CarApplicationRecord> {
);
}
Widget _buildPhotoItem(int witch) {
Widget _buildPhotoItem(int witch,List<String> listData) {
String labelName='';
switch(witch){
case 1:
@ -260,16 +272,9 @@ class _CarApplicationRecordState extends State<CarApplicationRecord> {
onTapCallBack: (path) {
presentOpaque(SingleImageViewer(imageUrl: path), context);
},
imageUrls: ['1983773013086048256/202601/ai_recognition_images/a9c8e701f773470d8a8485ccb6fb35b7.jpg','1983773013086048256/202601/ai_recognition_images/a9c8e701f773470d8a8485ccb6fb35b7.jpg'],
imageUrls: listData,
),
// ItemListWidget.OneRowImageTitle(
// label: labelName,
// text: '',
// onTapCallBack: (path) {
// presentOpaque(SingleImageViewer(imageUrl: path), context);
// },
// imgPath: '1983773013086048256/202601/ai_recognition_images/a9c8e701f773470d8a8485ccb6fb35b7.jpg',
// ),
);
}
@ -317,4 +322,79 @@ class _CarApplicationRecordState extends State<CarApplicationRecord> {
],
);
}
String _getAccessArea(final item) {
//(1:;2; 34)
String type = item["gateLevelAuthArea"]??'';
if(type.isNotEmpty){
// JSON
Map<String, dynamic> jsonData = json.decode(type);
List<dynamic> areaList = jsonData['area'];
// value
List<String> targetValues = areaList.map((item) => item['value'].toString()).toList();
return targetValues.join(',');
}else{
return '';
}
}
String _changeTime(item) {
String timeStart=item['visitStartTime']??'';
String timeEnd=item['visitEndTime']??'';
if(timeStart.isNotEmpty&&timeEnd.isNotEmpty){
return '$timeStart$timeEnd';
}else{
return '';
}
}
Future<void> _getXgfApplyInfoById() async {
try {
LoadingDialogHelper.show();
final Map<String, dynamic> result= await DoorAndCarApi.getLevelCarInfoById(widget.id);
LoadingDialogHelper.hide();
if (result['success'] ) {
// final dynamic newList = result['data'] ;
setState(() async {
applicationInfo=result['data'];
personnelList=applicationInfo['vehicleAuditLogList']??[];
final imageResults = await Future.wait([
FileApi.getImagePath(applicationInfo['informSignId'], UploadFileType.gateAccessVehicleApplicantSignature),
FileApi.getImagePath(applicationInfo['drivingLicenseId'], UploadFileType.gateAccessVehicleLicensePhoto),
FileApi.getImagePath(applicationInfo['attachmentId'], UploadFileType.gateAccessVehiclePhoto),
]);
if (imageResults[0]['success']) {
setState(() {
// -
List<dynamic> signData = imageResults[0]['data'] as List<dynamic>;
signList = signData.map((item) => item['filePath'].toString()).toList();
//
List<dynamic> licenseData = imageResults[1]['data'] as List<dynamic>;
licenseList = licenseData.map((item) => item['filePath'].toString()).toList();
//
List<dynamic> attachmentData = imageResults[2]['data'] as List<dynamic>;
attachmentList = attachmentData.map((item) => item['filePath'].toString()).toList();
});
}
});
}else{
ToastUtil.showNormal(context, '加载数据失败');
// _showMessage('加载数据失败');
}
} catch (e) {
LoadingDialogHelper.hide();
// Toast
print('加载数据失败:$e');
}
}
}

View File

@ -1,10 +1,12 @@
import 'package:flutter/material.dart';
import 'package:qhd_prevention/constants/app_enums.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/single_image_viewer.dart';
import 'package:qhd_prevention/customWidget/toast_util.dart';
import 'package:qhd_prevention/http/ApiService.dart';
import 'package:qhd_prevention/http/modules/doorAndCar_api.dart';
import 'package:qhd_prevention/pages/my_appbar.dart';
import 'package:qhd_prevention/tools/h_colors.dart';
import 'package:qhd_prevention/tools/tools.dart';
@ -12,9 +14,10 @@ import 'package:shared_preferences/shared_preferences.dart';
class OnlylookDoorareaCar extends StatefulWidget {
const OnlylookDoorareaCar(this.type, {super.key});
const OnlylookDoorareaCar(this.type, this.id, {super.key});
final int type;//1 2
final String id;
@override
State<OnlylookDoorareaCar> createState() => _OnlylookDoorareaCarState();
@ -22,24 +25,18 @@ class OnlylookDoorareaCar extends StatefulWidget {
class _OnlylookDoorareaCarState extends State<OnlylookDoorareaCar> {
//
final Map<String, String> applicationInfo = {
'mingcheng': '项目名称',
'bumen': '审核人员部门',
'renyuan': '审核人员',
'shijian': '2024-01-01 至 2024-12-31',
'gangqu': '访问港区',
'diqu': '访问地区',
};
//
dynamic applicationInfo = {};
//
final Map<String, String> personnelList =
{
'name': '张三',
'bumen': '技术部',
'isPei': '',
'wan': 'A区、B区',
};
//
List<dynamic> personnelList = [];
//
List<String> signList = [];
//
List<String> licenseList = [];
//
List<String> attachmentList = [];
///
bool isJGD = false;
@ -50,7 +47,7 @@ class _OnlylookDoorareaCarState extends State<OnlylookDoorareaCar> {
super.initState();
_getTypeTitle();
_getXgfApplyInfoById();
}
@ -169,7 +166,7 @@ class _OnlylookDoorareaCarState extends State<OnlylookDoorareaCar> {
label: '管辖单位:',
isEditable: false,
horizontalnum:0,
text: applicationInfo['mingcheng'] ?? '',
text: applicationInfo['jurisdictionalCorpName'] ?? '',
onTap: () {},
),
const Divider(),
@ -178,7 +175,7 @@ class _OnlylookDoorareaCarState extends State<OnlylookDoorareaCar> {
label: '管辖区域:',
isEditable: false,
horizontalnum:0,
text: applicationInfo['bumen'] ?? '',
text: applicationInfo['closedAreaName'] ?? '',
onTap: () {},
),
const Divider(),
@ -187,7 +184,7 @@ class _OnlylookDoorareaCarState extends State<OnlylookDoorareaCar> {
label: '审核人员部门:',
isEditable: false,
horizontalnum:0,
text: applicationInfo['renyuan'] ?? '',
text: applicationInfo['applyPersonDepartmentName'] ?? '',
onTap: () {},
),
const Divider(),
@ -196,7 +193,7 @@ class _OnlylookDoorareaCarState extends State<OnlylookDoorareaCar> {
label: '审核人员:',
isEditable: false,
horizontalnum:0,
text: applicationInfo['diqu'] ?? '',
text: applicationInfo['applyPersonUserName'] ?? '',
onTap: () {},
),
@ -207,7 +204,7 @@ class _OnlylookDoorareaCarState extends State<OnlylookDoorareaCar> {
label: '所属项目:',
isEditable: false,
horizontalnum:0,
text: applicationInfo['gangqu'] ?? '',
text: applicationInfo['projectName'] ?? '',
onTap: () {},
),
const Divider(),
@ -216,7 +213,7 @@ class _OnlylookDoorareaCarState extends State<OnlylookDoorareaCar> {
label: '时间范围:',
isEditable: false,
horizontalnum:0,
text: applicationInfo['shijian'] ?? '',
text: _changeTime(applicationInfo),
onTap: () {},
),
const Divider(),
@ -224,7 +221,7 @@ class _OnlylookDoorareaCarState extends State<OnlylookDoorareaCar> {
ItemListWidget.twoRowTitleText(
label: '申请原因:',
text: applicationInfo['shijian']??'',
text: applicationInfo['applyReason']??'',
horizontalInset:0,
),
const Divider(),
@ -259,7 +256,7 @@ class _OnlylookDoorareaCarState extends State<OnlylookDoorareaCar> {
label: '驾驶人部门:',
isEditable: false,
horizontalnum:0,
text: personnelList['name'] ?? '',
text: applicationInfo['applyPersonDepartmentName'] ?? '',
onTap: () {},
),
const Divider(),
@ -268,7 +265,7 @@ class _OnlylookDoorareaCarState extends State<OnlylookDoorareaCar> {
label: '驾驶人:',
isEditable: false,
horizontalnum:0,
text: personnelList['bumen'] ?? '',
text: applicationInfo['applyPersonUserName'] ?? '',
onTap: () {},
),
const Divider(),
@ -295,7 +292,7 @@ class _OnlylookDoorareaCarState extends State<OnlylookDoorareaCar> {
label: '车辆类型:',
isEditable: false,
horizontalnum:0,
text: personnelList['wan'] ?? '',
text: applicationInfo['vehicleTypeName'] ?? '',
onTap: () {},
),
const Divider(),
@ -304,7 +301,7 @@ class _OnlylookDoorareaCarState extends State<OnlylookDoorareaCar> {
label: '车牌类型:',
isEditable: false,
horizontalnum:0,
text: personnelList['wan'] ?? '',
text: applicationInfo['licenceTypeName'] ?? '',
onTap: () {},
),
const Divider(),
@ -313,28 +310,29 @@ class _OnlylookDoorareaCarState extends State<OnlylookDoorareaCar> {
label: '车牌号:',
isEditable: false,
horizontalnum:0,
text: personnelList['wan'] ?? '',
text: applicationInfo['licenceNo'] ?? '',
onTap: () {},
),
const Divider(),
ItemListWidget.twoRowTitleAndImages(
title: '车辆照片',
horizontalInset:0,
onTapCallBack: (path) {
presentOpaque(SingleImageViewer(imageUrl: path), context);
},
imageUrls: attachmentList,
),
ItemListWidget.twoRowTitleAndImages(
title: '车辆照片',
horizontalInset:0,
onTapCallBack: (path) {
presentOpaque(SingleImageViewer(imageUrl: path), context);
},
imageUrls: ['1983773013086048256/202601/ai_recognition_images/a9c8e701f773470d8a8485ccb6fb35b7.jpg','1983773013086048256/202601/ai_recognition_images/a9c8e701f773470d8a8485ccb6fb35b7.jpg'],
),
// ItemListWidget.OneRowImageTitle(
// label: '车辆照片:',
// imgPath: '1983773013086048256/202601/ai_recognition_images/a9c8e701f773470d8a8485ccb6fb35b7.jpg',
// ItemListWidget.twoRowTitleAndImages(
// title: '车辆照片',
// horizontalInset:0,
// onTapCallBack: (imgUrl) {
// presentOpaque(SingleImageViewer(imageUrl: imgUrl), context);
// onTapCallBack: (path) {
// presentOpaque(SingleImageViewer(imageUrl: path), context);
// },
// imageUrls: ['1983773013086048256/202601/ai_recognition_images/a9c8e701f773470d8a8485ccb6fb35b7.jpg','1983773013086048256/202601/ai_recognition_images/a9c8e701f773470d8a8485ccb6fb35b7.jpg'],
// ),
const Divider(),
ItemListWidget.twoRowTitleAndImages(
@ -343,15 +341,25 @@ class _OnlylookDoorareaCarState extends State<OnlylookDoorareaCar> {
onTapCallBack: (path) {
presentOpaque(SingleImageViewer(imageUrl: path), context);
},
imageUrls: ['1983773013086048256/202601/ai_recognition_images/a9c8e701f773470d8a8485ccb6fb35b7.jpg','1983773013086048256/202601/ai_recognition_images/a9c8e701f773470d8a8485ccb6fb35b7.jpg'],
imageUrls: licenseList,
),
// ItemListWidget.twoRowTitleAndImages(
// title: '行驶证照片',
// horizontalInset:0,
// onTapCallBack: (path) {
// presentOpaque(SingleImageViewer(imageUrl: path), context);
// },
// imageUrls: ['1983773013086048256/202601/ai_recognition_images/a9c8e701f773470d8a8485ccb6fb35b7.jpg','1983773013086048256/202601/ai_recognition_images/a9c8e701f773470d8a8485ccb6fb35b7.jpg'],
// ),
const Divider(),
if(signList.isNotEmpty)
Container(
height: 150,
padding: EdgeInsets.all(8),
alignment: Alignment.center,
child: Image.network('${ApiService.baseImgPath}1983773013086048256/202601/ai_recognition_images/a9c8e701f773470d8a8485ccb6fb35b7.jpg'),
child: Image.network('${ApiService.baseImgPath}${signList[0]}'),
),
@ -380,4 +388,68 @@ class _OnlylookDoorareaCarState extends State<OnlylookDoorareaCar> {
}
String _changeTime(item) {
String timeStart=item['visitStartTime']??'';
String timeEnd=item['visitEndTime']??'';
if(timeStart.isNotEmpty&&timeEnd.isNotEmpty){
return '$timeStart$timeEnd';
}else{
return '';
}
}
Future<void> _getXgfApplyInfoById() async {
try {
LoadingDialogHelper.show();
final Map<String, dynamic> result= await DoorAndCarApi.getEnclosedCarById(widget.id);
LoadingDialogHelper.hide();
if (result['success'] ) {
// final dynamic newList = result['data'] ;
setState(() async {
applicationInfo=result['data'];
personnelList=applicationInfo['vehicleAuditLogList']??[];
final imageResults = await Future.wait([
FileApi.getImagePath(applicationInfo['informSignId'], UploadFileType.enclosedAreaVehicleApplicantSignature),
FileApi.getImagePath(applicationInfo['drivingLicenseId'], UploadFileType.gateAccessVehicleLicensePhoto),
FileApi.getImagePath(applicationInfo['attachmentId'], UploadFileType.gateAccessVehiclePhoto),
]);
if (imageResults[0]['success']) {
setState(() {
// -
List<dynamic> signData = imageResults[0]['data'] as List<dynamic>;
signList = signData.map((item) => item['filePath'].toString()).toList();
//
List<dynamic> licenseData = imageResults[1]['data'] as List<dynamic>;
licenseList = licenseData.map((item) => item['filePath'].toString()).toList();
//
List<dynamic> attachmentData = imageResults[2]['data'] as List<dynamic>;
attachmentList = attachmentData.map((item) => item['filePath'].toString()).toList();
});
}
});
}else{
ToastUtil.showNormal(context, '加载数据失败');
// _showMessage('加载数据失败');
}
} catch (e) {
LoadingDialogHelper.hide();
// Toast
print('加载数据失败:$e');
}
}
}

View File

@ -70,7 +70,7 @@ class _DoorareaTypePageState extends State<DoorareaTypePage> {
}
},
text: '',
text: ' ',
),
const Divider(),
@ -90,7 +90,7 @@ class _DoorareaTypePageState extends State<DoorareaTypePage> {
}
},
text: '',
text: ' ',
),
const Divider(),

View File

@ -1,17 +1,26 @@
import 'dart:convert';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:qhd_prevention/constants/app_enums.dart';
import 'package:qhd_prevention/customWidget/ItemWidgetFactory.dart';
import 'package:qhd_prevention/customWidget/MultiDictValuesPicker.dart';
import 'package:qhd_prevention/customWidget/bottom_picker.dart';
import 'package:qhd_prevention/customWidget/center_multi_picker.dart';
import 'package:qhd_prevention/customWidget/custom_alert_dialog.dart';
import 'package:qhd_prevention/customWidget/custom_button.dart';
import 'package:qhd_prevention/customWidget/department_person_picker.dart' hide Person;
import 'package:qhd_prevention/customWidget/department_picker_enterprise.dart';
import 'package:qhd_prevention/customWidget/department_picker_three.dart';
import 'package:qhd_prevention/customWidget/department_picker_two.dart';
import 'package:qhd_prevention/customWidget/item_list_widget.dart';
import 'package:qhd_prevention/customWidget/photo_picker_row.dart';
import 'package:qhd_prevention/customWidget/single_image_viewer.dart';
import 'package:qhd_prevention/customWidget/toast_util.dart';
import 'package:qhd_prevention/http/ApiService.dart';
import 'package:qhd_prevention/http/modules/basic_info_api.dart';
import 'package:qhd_prevention/http/modules/doorAndCar_api.dart';
import 'package:qhd_prevention/pages/home/doorAndCar/person_selection_page.dart';
import 'package:qhd_prevention/pages/home/doorAndCar/sign_instructions_webView.dart';
@ -32,150 +41,33 @@ class DoorareaPersonApplyPage extends StatefulWidget {
}
class _DoorareaPersonApplyPageState extends State<DoorareaPersonApplyPage> {
Map<String, dynamic> pd = {};
bool _agreed = false;
//
List<dynamic> _deptList = [];
List<Person> _personList = [];
List<String> signImages = [];
//
List<Map<String, dynamic>> _personCache = [];
String corpinfoId = "";//
String corpinfoName = "";
String buMenId = "";//
String buMenName = "";
String responsibleId="";//
String responsibleName="";
@override
void initState() {
super.initState();
_getDept();
}
//
Future<void> _getDept() async {
// try {
// final data = {
// 'eqCorpinfoId': widget.scanData['id'],
// // 'eqParentId': widget.scanData['corpinfoId'],
// };
// final result = await BasicInfoApi.getDeptTree(data);
// if (result['success'] == true) {
// final list = result['data'] ?? [];
// if (list.length > 0) {
// setState(() {
// _deptList = list[0]['childrenList'] ?? [];
// });
// }
// }
// } catch (e) {}
}
//
Future<void> _saveSuccess() async {
if (!FormUtils.hasValue(pd, 'corpinfoId')) {
ToastUtil.showNormal(context, '请选择部门');
return;
}
if (!FormUtils.hasValue(pd, 'postName')) {
ToastUtil.showNormal(context, '请输入岗位');
return;
}
// try {
// final result = await BasicInfoApi.userFirmEntry(pd);
// LoadingDialogHelper.hide();
// if (result['success'] == true) {
// ToastUtil.showNormal(context, '申请成功');
// _relogin();
// } else {
// ToastUtil.showNormal(context, result['errMessage']);
// }
// } catch (e) {
// LoadingDialogHelper.hide();
// ToastUtil.showNormal(context, '操作失败,请重试');
// }
}
Widget _addPersonWight(Person personData) {
return Stack(
children: [
Card(
margin: EdgeInsets.only(bottom: 12),
color: Colors.white,
elevation: 2,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
child: Padding(
padding: EdgeInsets.all(16),
child: Column(
children: [
//
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Text(
'姓名: ${personData.name??''}',
style: TextStyle(
fontSize: 14,
color: Colors.grey[700],
),
),
),
// _buildInfoItem('姓名:', person['姓名'] ?? '',),
SizedBox(width: 24),
Expanded(
child: Text(
'部门: ${personData.group??''}',
style: TextStyle(
fontSize: 14,
color: Colors.grey[700],
),
),
),
// _buildInfoItem('部门:', person['部门'] ?? ''),
],
),
// SizedBox(height: 8),
//
// Row(
// mainAxisAlignment: MainAxisAlignment.end,
// children: [
// CustomButton(
// height: 35,
// onPressed: () async {
//
// },
// backgroundColor: Colors.red,
// textStyle: const TextStyle(color: Colors.black),
// buttonStyle:ButtonStyleType.primary,
// text: '删除')
// ],
// ),
],
),
),
),
Positioned(
top: 0,
right: 2,
child: Container(
padding: const EdgeInsets.all(2),
decoration: const BoxDecoration(
shape: BoxShape.circle,
color: Colors.red,
),
child: GestureDetector(
child: const Icon(Icons.close, size: 14, color: Colors.white,),
onTap: () {
setState(() {
_personList.remove(personData);
});
},
),
),
),
],
);
}
@override
Widget build(BuildContext context) {
@ -190,65 +82,129 @@ class _DoorareaPersonApplyPageState extends State<DoorareaPersonApplyPage> {
ListItemFactory.createBuildSimpleSection('申请信息'),
const Divider(),
ItemListWidget.selectableLineTitleTextRightButton(
label: '选择管辖单位',
label: '选择港区',
isEditable: true,
text: pd['departmentName'] ?? '请选择',
text: addData['portAreaName'] ?? '请选择',
isRequired: true,
onTap: () async {
if (_deptList.isEmpty) {
ToastUtil.showNormal(context, '暂无部门信息');
_getPortAreaType();
},
),
const Divider(),
ItemListWidget.selectableLineTitleTextRightButton(
label: '选择管辖单位:',
isEditable: true,
text: addData['jurisdictionalCorpName'] ?? '请选择',
isRequired: true,
onTap: () {
if( addData['portAreaId'].isEmpty){
ToastUtil.showNormal(context, '请先选择港区');
return;
}
final found = await BottomPicker.show(
context,
items: _deptList,
itemBuilder:
(i) => Text(i['name']!, textAlign: TextAlign.center),
initialIndex: 0,
);
//FocusHelper.clearFocus(context);
showModalBottomSheet(
context: context,
isScrollControlled: true,
barrierColor: Colors.black54,
backgroundColor: Colors.transparent,
builder:
(ctx) => DepartmentPickerEnterprise(
addData['portAreaId'],
onSelected: (id, name,pdId) async {
setState(() {
addData['jurisdictionalCorpId']= id;
addData['jurisdictionalCorpName']= name;
addData['auditPersonCorpId']= id;
addData['auditPersonCorpName']= name;
addData['auditPersonDepartmentId']= '';
addData['auditPersonDepartmentName']= '';
addData['auditPersonUserId']='';
addData['auditPersonUserName']='';
});
},
),
);
if (found != null) {
setState(() {
pd['departmentId'] = found['id'];
pd['departmentName'] = found['name'];
pd['corpinfoId'] = found['corpinfoId'];
pd['corpinfoName'] = found['corpinfoName'];
});
}
},
),
const Divider(),
ItemListWidget.selectableLineTitleTextRightButton(
label: '选择管辖区域:',
isEditable: true,
text: pd['departmentName'] ?? '请选择',
text: addData['closedAreaName']?? "请选择",
isRequired: true,
onTap: () async {},
),
const Divider(),
ItemListWidget.selectableLineTitleTextRightButton(
label: '审核人员部门:',
isEditable: true,
text: pd['departmentName'] ?? '请选择',
isRequired: true,
onTap: () async {},
onTap: () {
if(addData['jurisdictionalCorpName'].isEmpty){
ToastUtil.showNormal(context, '请选择管辖单位');
return ;
}
_getVisitPortArea();
},
),
// const Divider(),
// ItemListWidget.selectableLineTitleTextRightButton(
// label: '审核人员部门:',
// isEditable: true,
// text: addData['auditDeptName'] ?? '请选择',
// isRequired: true,
// onTap: () {
// if ( addData['auditCorpName'].isEmpty) {
// ToastUtil.showNormal(context, '请先选择企业');
// return;
// }
// showModalBottomSheet(
// context: context,
// isScrollControlled: true,
// barrierColor: Colors.black54,
// backgroundColor: Colors.transparent,
// builder:
// (ctx) => DepartmentPickerTwo(
// onSelected: (id, name,pdId) async {
// setState(() {
// addData['auditDeptId']= id;
// addData['auditDeptName']= name;
//
// addData['auditUserId']='';
// addData['auditUserName']='';
//
// });
// //
// final result = await HiddenDangerApi.getListTreePersonList(id);
// _personCache=List<Map<String, dynamic>>.from(
// result['data'] as List,
// );
// },
// ),
// );
//
// },
// ),
//
const Divider(),
ItemListWidget.selectableLineTitleTextRightButton(
label: '审核人员:',
isEditable: true,
text: pd['departmentName'] ?? '请选择',
text: addData['auditPersonUserName'] ?? '请选择',
isRequired: true,
onTap: () async {},
onTap: () {
// if ( addData['auditPersonUserName'].isEmpty) {
// ToastUtil.showNormal(context, '请先选择部门');
// return;
// }
_getApproverList();
},
),
const Divider(),
ItemListWidget.selectableLineTitleTextRightButton(
label: '选择项目:',
isEditable: true,
text: pd['departmentName'] ?? '请选择',
text: addData['projectName'] ?? '请选择',
isRequired: true,
onTap: () async {},
onTap: () {
_getProjectNameList();
},
),
const Divider(),
Padding(
@ -256,7 +212,7 @@ class _DoorareaPersonApplyPageState extends State<DoorareaPersonApplyPage> {
child: ItemListWidget.selectableLineTitleTextRightButton(
label: '选择时间:',
isEditable: false,
text: pd['departmentName'] ?? '',
text: addData['auditAllTime'] ?? '',
isRequired: true,
onTap: () async {},
),
@ -265,6 +221,9 @@ class _DoorareaPersonApplyPageState extends State<DoorareaPersonApplyPage> {
ItemListWidget.multiLineTitleTextField(
label: '申请原因',
isEditable: true,
onChanged: (value) {
addData['applyReason']=value;
},
),
const Divider(),
@ -285,9 +244,13 @@ class _DoorareaPersonApplyPageState extends State<DoorareaPersonApplyPage> {
height: 35,
backgroundColor: Colors.blue,
onPressed: () async {
if(addData['projectId'].isEmpty){
ToastUtil.showNormal(context, '请先选择项目');
return;
}
final result = await Navigator.push<SelectionPersonResult>(
context,
MaterialPageRoute(builder: (context) => PersonSelectionPage(_personList)),
MaterialPageRoute(builder: (context) => PersonSelectionPage(_personList,addData['projectId']??'')),
);
if (result != null) {
@ -313,7 +276,7 @@ class _DoorareaPersonApplyPageState extends State<DoorareaPersonApplyPage> {
side: const BorderSide(color: Colors.grey),
onChanged: (value) {
setState(() {
_agreed = value ?? false;
// _agreed = value ?? false;
});
},
),
@ -401,7 +364,92 @@ class _DoorareaPersonApplyPageState extends State<DoorareaPersonApplyPage> {
);
}
Widget _addPersonWight(Person personData) {
return Stack(
children: [
Card(
margin: EdgeInsets.only(bottom: 12),
color: Colors.white,
elevation: 2,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
child: Padding(
padding: EdgeInsets.all(16),
child: Column(
children: [
//
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Text(
'姓名: ${personData.employeePersonUserName??''}',
style: TextStyle(
fontSize: 14,
color: Colors.grey[700],
),
),
),
// _buildInfoItem('姓名:', person['姓名'] ?? '',),
SizedBox(width: 24),
Expanded(
child: Text(
'部门: ${personData.personDepartmentName??''}',
style: TextStyle(
fontSize: 14,
color: Colors.grey[700],
),
),
),
// _buildInfoItem('部门:', person['部门'] ?? ''),
],
),
// SizedBox(height: 8),
//
// Row(
// mainAxisAlignment: MainAxisAlignment.end,
// children: [
// CustomButton(
// height: 35,
// onPressed: () async {
//
// },
// backgroundColor: Colors.red,
// textStyle: const TextStyle(color: Colors.black),
// buttonStyle:ButtonStyleType.primary,
// text: '删除')
// ],
// ),
],
),
),
),
Positioned(
top: 0,
right: 2,
child: Container(
padding: const EdgeInsets.all(2),
decoration: const BoxDecoration(
shape: BoxShape.circle,
color: Colors.red,
),
child: GestureDetector(
child: const Icon(Icons.close, size: 14, color: Colors.white,),
onTap: () {
setState(() {
_personList.remove(personData);
});
},
),
),
),
],
);
}
Widget _signListWidget() {
return Column(
@ -495,5 +543,325 @@ class _DoorareaPersonApplyPageState extends State<DoorareaPersonApplyPage> {
}
Future<void> _getPortAreaType() async {
showModalBottomSheet(
context: context,
isScrollControlled: true,
barrierColor: Colors.black54,
backgroundColor: Colors.transparent,
builder:
(_) => MultiDictValuesPicker(
title: '港区',
dictType: 'HG_AUTH_AREA',
allowSelectParent: false,
onSelected: (id, name, extraData) {
setState(() {
addData['portAreaId'] = extraData?['dictValue'];//id
addData['portAreaName'] = name;//
});
},
),
).then((_) {
// FocusHelper.clearFocus(context);
});
}
Future<void> _getVisitPortArea() async {
try {
LoadingDialogHelper.show();
final raw = await DoorAndCarApi.getEnclosedAreaById(addData['jurisdictionalCorpId']);
LoadingDialogHelper.hide();
if (raw['success'] ) {
List<dynamic> newList = raw['data'] ?? [];
for(int i=0;i<newList.length;i++){
newList[i]["dataId"] = newList[i]["id"];
newList[i]["dataName"] = newList[i]["closedAreaName"];
}
showModalBottomSheet(
context: context,
isScrollControlled: true,
barrierColor: Colors.black54,
backgroundColor: Colors.transparent,
builder:
(ctx) => DepartmentPickerThree(
listdata: newList,
onSelected: (id, name,pdId) async {
setState(() {
addData['closedAreaId']=id;//id
addData['closedAreaName']=name;//
});
},
),
);
}else{
ToastUtil.showNormal(context, "获取列表失败");
LoadingDialogHelper.hide();
// _showMessage('反馈提交失败');
// return "";
}
} catch (e) {
// Toast
print('加载首页数据失败:$e');
// return "";
LoadingDialogHelper.hide();
}
}
Future<void> _getApproverList() async {
try {
LoadingDialogHelper.show();
final raw = await DoorAndCarApi.getApproverList( addData['auditPersonCorpId'],'','1','','');//addData['auditDeptId']
LoadingDialogHelper.hide();
if (raw['success'] ) {
List<dynamic> newList = raw['data'] ?? [];
for(int i=0;i<newList.length;i++){
newList[i]["dataId"] = newList[i]["userId"];
newList[i]["dataName"] = newList[i]["userName"];
}
showModalBottomSheet(
context: context,
isScrollControlled: true,
barrierColor: Colors.black54,
backgroundColor: Colors.transparent,
builder:
(ctx) => DepartmentPickerThree(
listdata: newList,
onSelected: (id, name,pdId) async {
setState(() {
for(int i=0;i<newList.length;i++){
if(newList[i]["userId"]==id){
addData['auditPersonDepartmentId']=newList[i]["deptId"];//
addData['auditPersonDepartmentName']=newList[i]["deptName"];//
addData['auditPersonUserId']=newList[i]["userId"];//
addData['auditPersonUserName']=newList[i]["userName"]; //
}
}
});
},
),
);
}else{
ToastUtil.showNormal(context, "获取列表失败");
LoadingDialogHelper.hide();
// _showMessage('反馈提交失败');
// return "";
}
} catch (e) {
// Toast
print('加载首页数据失败:$e');
// return "";
LoadingDialogHelper.hide();
}
}
Future<void> _getProjectNameList() async {
try {
LoadingDialogHelper.show();
final raw = await DoorAndCarApi.getProjectNameList( );
LoadingDialogHelper.hide();
printLongString(jsonEncode(raw));
if (raw['success'] ) {
final newList = raw['data'] ?? [];
for(int i=0;i<newList.length;i++){
newList[i]["dataId"] = newList[i]["id"];
newList[i]["dataName"] = newList[i]["projectName"];
}
showModalBottomSheet(
context: context,
isScrollControlled: true,
barrierColor: Colors.black54,
backgroundColor: Colors.transparent,
builder:
(ctx) => DepartmentPickerThree(
listdata: newList,
onSelected: (id, name,pdId) async {
setState(() {
addData['projectId']=id;
addData['projectName']=name;
//
for(int i=0;i<newList.length;i++){
if(id==newList[i]["id"]){
String startProjectTime= newList[i]["startProjectTime"]??'';
String endProjectTime= newList[i]["endProjectTime"]??'';
if(startProjectTime.isNotEmpty){
addData['visitStartTime']=DateFormat('yyyy-MM-dd').format(DateTime.parse(startProjectTime));
}
if(startProjectTime.isNotEmpty){
addData['visitEndTime']=DateFormat('yyyy-MM-dd').format(DateTime.parse(endProjectTime));
}
addData['auditAllTime']='${addData['visitStartTime']}${addData['visitEndTime']}';
}
}
_personList.clear();
});
},
),
);
}else{
ToastUtil.showNormal(context, "获取列表失败");
LoadingDialogHelper.hide();
// _showMessage('反馈提交失败');
// return "";
}
} catch (e) {
// Toast
print('加载首页数据失败:$e');
// return "";
LoadingDialogHelper.hide();
}
}
//
Future<void> _saveSuccess() async {
try {
if(addData['jurisdictionalCorpName'].isEmpty){
ToastUtil.showNormal(context, '请选择管辖单位');
return;
}
if(addData['closedAreaName'].isEmpty){
ToastUtil.showNormal(context, '请选择管辖区域');
return;
}
// if(addData['auditDeptName'].isEmpty){
// ToastUtil.showNormal(context, '请选择审核人员部门');
// return;
// }
if(addData['auditPersonUserName'].isEmpty){
ToastUtil.showNormal(context, '请选择审核人员');
return;
}
if(addData['projectName'].isEmpty){
ToastUtil.showNormal(context, '请选择项目');
return;
}
if(addData['applyReason'].isEmpty){
ToastUtil.showNormal(context, '请填写原因');
return;
}
if(_personList.isEmpty){
ToastUtil.showNormal(context, '请选择人员');
return;
}
// List<Person> List<Map<String, dynamic>>
List<Map<String, dynamic>> jsonList = _personList.map((person) => person.toJson()).toList();
// JSON
addData['entourage'] = jsonEncode(jsonList);
if(signImages.isEmpty){
ToastUtil.showNormal(context, '请阅读《安全进港须知》并签字');
return;
}
LoadingDialogHelper.show();
if(signImages.isNotEmpty){
String licenseId= await _addImgFilesLicense(signImages, UploadFileType.enclosedAreaPersonnelApplicantSignature,'');
addData['informSignId']=licenseId;
}
final result = await DoorAndCarApi.enclosedPersonSave(addData);
LoadingDialogHelper.hide();
if (result['success'] == true) {
ToastUtil.showNormal(context, '提交成功');
Navigator.pop(context);
} else {
ToastUtil.showNormal(context, result['errMessage']);
}
} catch (e) {
LoadingDialogHelper.hide();
ToastUtil.showNormal(context, '操作失败,请重试');
}
}
Future<String> _addImgFilesLicense(List<String> imagePaths,UploadFileType type,String idType) async {
try {
final raw = await FileApi.uploadFiles( imagePaths, type,idType);
if (raw['success'] ) {
return raw['data']['foreignKey'];
}else{
// _showMessage('反馈提交失败');
return "";
}
} catch (e) {
// Toast
print('加载首页数据失败:$e');
return "";
}
}
Map<String, dynamic> addData={
"personBelongType": '3', //1234
"levelOneMkmjId": '', //id
"levelTwoMkmjId": '', //id()
"closedAreaId": '', //id
"closedAreaName": "", //
"visitStartTime": "", //访
"visitEndTime": "", //访
"jurisdictionalCorpId": '', //id
"jurisdictionalCorpName": "", //
"projectId": '', //id
"projectName": "", //
"applyReason": "", //
"entourage": "", //
"informSignId": '', //
"auditPersonCorpId": '', //ID
"auditPersonCorpName": "", //
"auditPersonDepartmentId": '', //id
"auditPersonDepartmentName": "", //
"auditPersonUserId": '', //id
"auditPersonUserName": "", //
"applyPersonUserName": "", //
"userFaceUrl": "", //
"userPhone": "", //
"userCard": "", //
"portAreaId": '', //id
"portAreaName": '', //
"auditAllTime": '', //
"personApplyList": [],
};
// Map<String, dynamic> addPersonData= {
// "personCorpId": '', //ID
// "personCorpName": '', //
// "personDepartmentId": '', //id
// "personDepartmentName": '', //
// "employeePersonUserId": '', //id
// "employeePersonUserName": '', //
// "userFaceUrl": '', //
// "userPhone": '', //
// "userCard": '', //
// };
}

View File

@ -1,4 +1,8 @@
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:qhd_prevention/customWidget/toast_util.dart';
import 'package:qhd_prevention/http/modules/doorAndCar_api.dart';
import 'package:qhd_prevention/pages/home/doorAndCar/car/doorArea_car_add_page.dart';
import 'package:qhd_prevention/pages/home/doorAndCar/car/firstlevel_car_add_page.dart';
import 'package:qhd_prevention/pages/home/doorAndCar/car/onlyLook_car_application.dart';
@ -28,43 +32,9 @@ class DoorareaPersonRecordPage extends StatefulWidget {
class _DoorareaPersonRecordPageState extends State<DoorareaPersonRecordPage> {
// Data and state variables
// List<dynamic> list = [];
final List<Map<String, dynamic>> list = [
{
'applicant': '封闭区域申请',
'region': '申请人',
'people': '人数',
'startTime': '2025-10-29 00:00',
'endTime': '2025-10-31 00:00',
'license': '申请区域',
'status': '待审核',
'statusColor': Colors.orange,
},
{
'applicant': '封闭区域申请',
'region': '申请人',
'people': '人数',
'startTime': '2025-10-29 00:00',
'endTime': '2025-10-31 00:00',
'license': '申请区域',
'status': '待审核',
'statusColor': Colors.orange,
},
{
'applicant': '封闭区域申请',
'region': '申请人',
'people': '人数',
'startTime': '2025-10-29 00:00',
'endTime': '2025-10-31 00:00',
'license': '申请区域',
'status': '待审核',
'statusColor': Colors.orange,
},
List<dynamic> list = [];
];
Map pd = {};
// Map pd = {};
int currentPage = 1;
int rows = 10;
@ -91,29 +61,75 @@ class _DoorareaPersonRecordPageState extends State<DoorareaPersonRecordPage> {
super.initState();
switch(widget.type){
case 1:
case 3:
titleName='人员审核';
buttonName='查看';
isAdd=true;
case 1://1 ()
titleName='人员审核';
buttonName='查看';
isAdd=true;
xgfDataApplyListData['processOrRecord']=1;
xgfDataApplyListData['menuPath'] = '/primeport/container/stakeholder/firstLevelDoor/personnelApplication/list';
break;
case 2:
case 4:
case 2:// 2 ()
titleName='人员审核记录';
buttonName='查看';
isAdd=false;
xgfDataApplyListData['processOrRecord']=2;
xgfDataApplyListData['menuPath'] = '/primeport/container/stakeholder/firstLevelDoor/personnelApplicationRecords/list';
break;
case 5:
case 7:
case 3://3 ()
titleName='人员审核';
buttonName='查看';
isAdd=true;
xgfDataApplyListData['processOrRecord']=1;
xgfDataApplyListData['personBelongType']=3;
xgfDataApplyListData['menuPath'] = '/primeport/container/stakeholder/enclosedArea/apply/personnel/list';
break;
case 4://4 ()
titleName='人员审核记录';
buttonName='查看';
isAdd=false;
xgfDataApplyListData['processOrRecord']=2;
xgfDataApplyListData['personBelongType']=3;
xgfDataApplyListData['menuPath'] = '/primeport/container/stakeholder/enclosedArea/apply/personnelRecords/list';
break;
case 5: //5 ()
titleName='车辆审核';
buttonName='查看';
isAdd=true;
xgfDataApplyListData['processOrRecord']=1;
xgfDataApplyListData['vehicleBelongType']='5';
xgfDataApplyListData['menuPath'] = '/primeport/container/stakeholder/firstLevelDoor/vehicleApplication/list';
break;
case 6:
case 8:
case 6: // 6 ()
titleName='车辆审核记录';
buttonName='查看';
isAdd=false;
xgfDataApplyListData['processOrRecord']=2;
xgfDataApplyListData['vehicleBelongType']='5';
xgfDataApplyListData['menuPath'] = '/primeport/container/stakeholder/firstLevelDoor/vehicleApplicationRecords/list';
break;
case 7: // 7 ()
titleName='车辆审核';
buttonName='查看';
isAdd=true;
xgfDataApplyListData['processOrRecord']=1;
xgfDataApplyListData['personBelongType']=3;
xgfDataApplyListData['menuPath'] = '/primeport/container/stakeholder/enclosedArea/apply/vehicle/list';
break;
case 8: // 8 ()
titleName='车辆审核记录';
buttonName='查看';
isAdd=false;
xgfDataApplyListData['processOrRecord']=2;
xgfDataApplyListData['personBelongType']=3;
xgfDataApplyListData['menuPath'] = '/primeport/container/stakeholder/enclosedArea/apply/vehicleRecords/list';
break;
}
@ -142,31 +158,45 @@ class _DoorareaPersonRecordPageState extends State<DoorareaPersonRecordPage> {
Future<void> _fetchData() async {
// if (isLoading) return;
// setState(() => isLoading = true);
//
// try {
// final data = {
// "likeCorpName": searchKeywords,
// "pageSize": rows,
// "pageIndex": currentPage,
// };
// final response = await RiskwarningApi.getCorpRiskStatement();
// final firmRes = await RiskwarningApi.getCorpRiskList(data);
// setState(() {
// pd = response['data'];
// if (currentPage == 1) {
// list = firmRes['data'];
// } else {
// list.addAll(firmRes['data']);
// }
// totalPage = firmRes['totalPages'] ?? 1;
// isLoading = false;
// });
// } catch (e) {
// print('Error fetching data: $e');
// setState(() => isLoading = false);
// }
if (isLoading) return;
setState(() => isLoading = true);
try {
xgfDataApplyListData['projectName']=searchKeywords.isNotEmpty?searchKeywords:'';
xgfDataApplyListData['pageIndex']=currentPage;
final Map<String, dynamic> result;
if(widget.type==1||widget.type==2) {
result = await DoorAndCarApi.getXgfPersonAuditList(xgfDataApplyListData);
}else if(widget.type==3||widget.type==4) {
result = await DoorAndCarApi.getEnclosedPersonList(xgfDataApplyListData);
}else if(widget.type==5||widget.type==6) {
result = await DoorAndCarApi.getXgfCarAuditList(xgfDataApplyListData);
}else if(widget.type==7||widget.type==8) {
result = await DoorAndCarApi.getEnclosedCarList(xgfDataApplyListData);
} else{
result = await DoorAndCarApi.getXgfPersonAuditList(xgfDataApplyListData);
}
if (result['success'] ) {
setState(() {
// pd = result['data'];
if (currentPage == 1) {
list = result['data'];
} else {
list.addAll(result['data']);
}
totalPage = result['totalCount'] ?? 1;
isLoading = false;
});
}else{
ToastUtil.showNormal(context, '加载数据失败');
// _showMessage('加载数据失败');
}
} catch (e) {
print('Error fetching data: $e');
setState(() => isLoading = false);
}
}
void _search() {
@ -180,22 +210,22 @@ class _DoorareaPersonRecordPageState extends State<DoorareaPersonRecordPage> {
switch(widget.type){
case 1:
case 2:
await pushPage(OnlylookDoorareaPerson(2), context);
await pushPage(OnlylookPersonApplication(3,item['id']), context);
break;
case 3:
case 4:
await pushPage(OnlylookPersonApplication(3), context);
await pushPage(OnlylookDoorareaPerson(2,item['id']), context);
break;
case 5:
case 6:
await pushPage(OnlylookDoorareaCar(2), context);
await pushPage(OnlylookCarApplication(4,item['vehicleApplyId']), context);
break;
case 7:
case 8:
await pushPage(CarApplicationRecord(4), context);
await pushPage(OnlylookDoorareaCar(2,item['id']), context);
break;
}
_fetchData();
// _fetchData();
}
Widget _buildListItem(Map<String, dynamic> item,int index) {
@ -221,7 +251,7 @@ class _DoorareaPersonRecordPageState extends State<DoorareaPersonRecordPage> {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
item['applicant'],
item['projectName']??'',
// '${item['name']??''}',
style: const TextStyle(
fontSize: 16,
@ -231,20 +261,23 @@ class _DoorareaPersonRecordPageState extends State<DoorareaPersonRecordPage> {
const SizedBox(height: 8),
Text('申请人:${item['region']??""}',),
if(widget.type==1||widget.type==2||widget.type==5||widget.type==6)
Text('审核人:${item['auditUserName']??""}',),
if(widget.type==3||widget.type==4||widget.type==7||widget.type==8)
Text('审核人:${item['auditPersonUserName']??""}',),
if(widget.type==5||widget.type==6||widget.type==7||widget.type==8)...[
const SizedBox(height: 8),
Text('车牌号:${item['region']??""}',),
Text('车牌号:${item['licenceNo']??""}',),
],
const SizedBox(height: 8),
Text('申请区域:${item['license']??""}',),
Text('申请区域:${_getAccessArea(item)}',),
const SizedBox(height: 8),
Text('时间范围:自${item['startTime']??""}${item['endTime']??""}'),
Text('时间范围:自${item['visitStartTime']??""}${item['visitEndTime']??""}'),
const SizedBox(height: 8),
Text('审核状态:${item['status']??""}',),
if(widget.type==2||widget.type==4||widget.type==6||widget.type==8)...[
Text('审核状态:${_getReviewStatus(item)}',),
if((widget.type==2||widget.type==4||widget.type==6||widget.type==8)&&(item['reasonsRefusal']??"").isNotEmpty)...[
const SizedBox(height: 8),
Text('驳回原因:${item['status']??""}',),
Text('驳回原因:${item['reasonsRefusal']??""}',),
],
@ -308,18 +341,19 @@ class _DoorareaPersonRecordPageState extends State<DoorareaPersonRecordPage> {
onPressed: () async {
switch(widget.type){
case 1:
await pushPage(DoorareaPersonApplyPage(), context);
break;
case 3:
await pushPage(FirstlevelPersonAddPage(), context);
break;
case 5:
await pushPage(DoorareaCarAddPage(), context);
case 3:
await pushPage(DoorareaPersonApplyPage(), context);
break;
case 7:
case 5:
await pushPage(FirstlevelCarAddPage(), context);
break;
case 7:
await pushPage(DoorareaCarAddPage(), context);
break;
}
currentPage=1;
_fetchData();
},
@ -335,33 +369,33 @@ class _DoorareaPersonRecordPageState extends State<DoorareaPersonRecordPage> {
child: Row(
children: [
//
GestureDetector(
onTap: () {
//
},
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
child: Row(
children: [
Text(
'筛选',
style: TextStyle(
fontSize: 14,
color: Colors.black,
),
),
const SizedBox(width: 2),
Icon(
Icons.expand_more,
size: 20,
color: Colors.black,
),
],
),
),
),
const SizedBox(width: 8),
// GestureDetector(
// onTap: () {
// //
// },
// child: Container(
// padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
// child: Row(
// children: [
// Text(
// '筛选',
// style: TextStyle(
// fontSize: 14,
// color: Colors.black,
// ),
// ),
// const SizedBox(width: 2),
// Icon(
// Icons.expand_more,
// size: 20,
// color: Colors.black,
// ),
//
// ],
// ),
// ),
// ),
// const SizedBox(width: 8),
//
Expanded(
child: SearchBarWidget(
@ -391,4 +425,68 @@ class _DoorareaPersonRecordPageState extends State<DoorareaPersonRecordPage> {
),
);
}
String _getAccessArea(final item) {
//(1:;2; 34)
String type ='';
if(widget.type==1||widget.type==2||widget.type==5||widget.type==6){
type = item["gateLevelAuthArea"]??'';
if(type.isNotEmpty){
// JSON
Map<String, dynamic> jsonData = json.decode(type);
List<dynamic> areaList = jsonData['area'];
// value
List<String> targetValues = areaList.map((item) => item['value'].toString()).toList();
return targetValues.join(',');
}else{
return '';
}
}else{
return item["closedAreaName"]??'';
}
}
String _getReviewStatus(final item) {
//(1:;2; 34)
// int type = item['auditFlag']??"";
int type =0;
if(widget.type==1||widget.type==2||widget.type==3||widget.type==4){
type = int.tryParse(item['auditFlag']?.toString() ?? '') ?? 0;
}else{
type = int.tryParse(item['auditStatus']?.toString() ?? '') ?? 0;
}
if (1 == type) {
return "待审核";
} else if (2 == type) {
return "审核通过";
} else if (3 == type) {
return "审核驳回";
} else if (4 == type) {
return "无需审批(长期人员)";
} else {
return "无需审批";
}
}
Map<String, dynamic> xgfDataApplyListData={
"processOrRecord": '', //12
"projectName": "", //
"applyCorpName": "", //
"userCard": "", //访h5
"pageSize": 10,
"pageIndex": 1,
"licenceNo": "", //
"vehicleBelongTypeArr": "", // 1-2-3-4- 5- 6:7
"vehicleBelongType": "", // 1-2-3-4- 5- 6:7
"personBelongType": '', //1234
};
}

View File

@ -1,17 +1,22 @@
import 'dart:convert';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:intl/intl.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/center_multi_picker.dart';
import 'package:qhd_prevention/customWidget/custom_alert_dialog.dart';
import 'package:qhd_prevention/customWidget/custom_button.dart';
import 'package:qhd_prevention/customWidget/department_picker_three.dart';
import 'package:qhd_prevention/customWidget/item_list_widget.dart';
import 'package:qhd_prevention/customWidget/photo_picker_row.dart';
import 'package:qhd_prevention/customWidget/single_image_viewer.dart';
import 'package:qhd_prevention/customWidget/toast_util.dart';
import 'package:qhd_prevention/http/ApiService.dart';
import 'package:qhd_prevention/http/modules/basic_info_api.dart';
import 'package:qhd_prevention/http/modules/doorAndCar_api.dart';
import 'package:qhd_prevention/pages/home/doorAndCar/person_selection_page.dart';
import 'package:qhd_prevention/pages/home/doorAndCar/sign_instructions_webView.dart';
@ -32,7 +37,7 @@ class FirstlevelPersonAddPage extends StatefulWidget {
}
class _FirstlevelPersonAddPageState extends State<FirstlevelPersonAddPage> {
Map<String, dynamic> pd = {};
bool _agreed = false;
//
@ -40,142 +45,20 @@ class _FirstlevelPersonAddPageState extends State<FirstlevelPersonAddPage> {
List<Person> _personList = [];
List<String> signImages = [];
String corpinfoId = "";//
String corpinfoName = "";
String buMenId = "";//
String buMenName = "";
String responsibleId="";//
String responsibleName="";
@override
void initState() {
super.initState();
_getDept();
_getUserData();
}
//
Future<void> _getDept() async {
// try {
// final data = {
// 'eqCorpinfoId': widget.scanData['id'],
// // 'eqParentId': widget.scanData['corpinfoId'],
// };
// final result = await BasicInfoApi.getDeptTree(data);
// if (result['success'] == true) {
// final list = result['data'] ?? [];
// if (list.length > 0) {
// setState(() {
// _deptList = list[0]['childrenList'] ?? [];
// });
// }
// }
// } catch (e) {}
}
//
Future<void> _saveSuccess() async {
if (!FormUtils.hasValue(pd, 'corpinfoId')) {
ToastUtil.showNormal(context, '请选择部门');
return;
}
if (!FormUtils.hasValue(pd, 'postName')) {
ToastUtil.showNormal(context, '请输入岗位');
return;
}
// try {
// final result = await BasicInfoApi.userFirmEntry(pd);
// LoadingDialogHelper.hide();
// if (result['success'] == true) {
// ToastUtil.showNormal(context, '申请成功');
// _relogin();
// } else {
// ToastUtil.showNormal(context, result['errMessage']);
// }
// } catch (e) {
// LoadingDialogHelper.hide();
// ToastUtil.showNormal(context, '操作失败,请重试');
// }
}
Widget _addPersonWight(Person personData) {
return Stack(
children: [
Card(
margin: EdgeInsets.only(bottom: 12),
color: Colors.white,
elevation: 2,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
child: Padding(
padding: EdgeInsets.all(16),
child: Column(
children: [
//
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Text(
'姓名: ${personData.name??''}',
style: TextStyle(
fontSize: 14,
color: Colors.grey[700],
),
),
),
// _buildInfoItem('姓名:', person['姓名'] ?? '',),
SizedBox(width: 24),
Expanded(
child: Text(
'部门: ${personData.group??''}',
style: TextStyle(
fontSize: 14,
color: Colors.grey[700],
),
),
),
// _buildInfoItem('部门:', person['部门'] ?? ''),
],
),
// SizedBox(height: 8),
//
// Row(
// mainAxisAlignment: MainAxisAlignment.end,
// children: [
// CustomButton(
// height: 35,
// onPressed: () async {
//
// },
// backgroundColor: Colors.red,
// textStyle: const TextStyle(color: Colors.black),
// buttonStyle:ButtonStyleType.primary,
// text: '删除')
// ],
// ),
],
),
),
),
Positioned(
top: 0,
right: 2,
child: Container(
padding: const EdgeInsets.all(2),
decoration: const BoxDecoration(
shape: BoxShape.circle,
color: Colors.red,
),
child: GestureDetector(
child: const Icon(Icons.close, size: 14, color: Colors.white,),
onTap: () {
setState(() {
_personList.remove(personData);
});
},
),
),
),
],
);
}
@override
Widget build(BuildContext context) {
@ -192,17 +75,21 @@ class _FirstlevelPersonAddPageState extends State<FirstlevelPersonAddPage> {
ItemListWidget.selectableLineTitleTextRightButton(
label: '选择项目名称:',
isEditable: true,
text: pd['departmentName'] ?? '请选择',
text: addData['projectName'] ?? '请选择',
isRequired: true,
onTap: () async {},
onTap: () {
_getProjectNameList();
},
),
const Divider(),
ItemListWidget.selectableLineTitleTextRightButton(
label: '审核人员:',
isEditable: true,
text: pd['departmentName'] ?? '请选择',
text: addData['auditUserName'] ?? '请选择',
isRequired: true,
onTap: () async {},
onTap: () {
_getApproverList();
},
),
const Divider(),
Padding(
@ -210,7 +97,7 @@ class _FirstlevelPersonAddPageState extends State<FirstlevelPersonAddPage> {
child: ItemListWidget.selectableLineTitleTextRightButton(
label: '选择时间:',
isEditable: false,
text: pd['departmentName'] ?? '',
text: addData['auditAllTime'] ?? '',
isRequired: true,
onTap: () async {},
),
@ -219,19 +106,23 @@ class _FirstlevelPersonAddPageState extends State<FirstlevelPersonAddPage> {
ItemListWidget.selectableLineTitleTextRightButton(
label: '访问港区:',
isEditable: true,
text: pd['departmentName'] ?? '请选择',
text: addData['gateLevelAuthAreaName'] ?? '请选择',
isRequired: true,
onTap: () async {},
),
const Divider(),
ItemListWidget.selectableLineTitleTextRightButton(
label: '选择范围:',
isEditable: true,
text: pd['departmentName'] ?? '请选择',
isRequired: true,
onTap: () async {},
onTap: () {
_getVisitPortArea();
},
),
// const Divider(),
// ItemListWidget.selectableLineTitleTextRightButton(
// label: '选择范围:',
// isEditable: true,
// text: pd['departmentName'] ?? '请选择',
// isRequired: true,
// onTap: () {
//
// },
// ),
// const Divider(),
// ItemListWidget.multiLineTitleTextField(
// label: '申请原因',
// isEditable: true,
@ -255,9 +146,13 @@ class _FirstlevelPersonAddPageState extends State<FirstlevelPersonAddPage> {
height: 35,
backgroundColor: Colors.blue,
onPressed: () async {
if(addData['projectId'].isEmpty){
ToastUtil.showNormal(context, '请先选择项目');
return;
}
final result = await Navigator.push<SelectionPersonResult>(
context,
MaterialPageRoute(builder: (context) => PersonSelectionPage(_personList)),
MaterialPageRoute(builder: (context) => PersonSelectionPage(_personList,addData['projectId'])),
);
if (result != null) {
@ -283,7 +178,7 @@ class _FirstlevelPersonAddPageState extends State<FirstlevelPersonAddPage> {
side: const BorderSide(color: Colors.grey),
onChanged: (value) {
setState(() {
_agreed = value ?? false;
// _agreed = value ?? false;
});
},
),
@ -372,6 +267,93 @@ class _FirstlevelPersonAddPageState extends State<FirstlevelPersonAddPage> {
}
Widget _addPersonWight(Person personData) {
return Stack(
children: [
Card(
margin: EdgeInsets.only(bottom: 12),
color: Colors.white,
elevation: 2,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
child: Padding(
padding: EdgeInsets.all(16),
child: Column(
children: [
//
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Text(
'姓名: ${personData.employeePersonUserName??''}',
style: TextStyle(
fontSize: 14,
color: Colors.grey[700],
),
),
),
// _buildInfoItem('姓名:', person['姓名'] ?? '',),
SizedBox(width: 24),
Expanded(
child: Text(
'部门: ${personData.personDepartmentName??''}',
style: TextStyle(
fontSize: 14,
color: Colors.grey[700],
),
),
),
// _buildInfoItem('部门:', person['部门'] ?? ''),
],
),
// SizedBox(height: 8),
//
// Row(
// mainAxisAlignment: MainAxisAlignment.end,
// children: [
// CustomButton(
// height: 35,
// onPressed: () async {
//
// },
// backgroundColor: Colors.red,
// textStyle: const TextStyle(color: Colors.black),
// buttonStyle:ButtonStyleType.primary,
// text: '删除')
// ],
// ),
],
),
),
),
Positioned(
top: 0,
right: 2,
child: Container(
padding: const EdgeInsets.all(2),
decoration: const BoxDecoration(
shape: BoxShape.circle,
color: Colors.red,
),
child: GestureDetector(
child: const Icon(Icons.close, size: 14, color: Colors.white,),
onTap: () {
setState(() {
_personList.remove(personData);
});
},
),
),
),
],
);
}
Widget _signListWidget() {
return Column(
@ -465,5 +447,344 @@ class _FirstlevelPersonAddPageState extends State<FirstlevelPersonAddPage> {
}
Future<void> _getUserData() async {
try {
final raw = await AuthApi.getUserData( );
if (raw['success'] ) {
setState(() {
corpinfoId = raw['data']['corpinfoId'];//
corpinfoName = raw['data']['corpinfoName'];
buMenId = raw['data']['departmentId'];
buMenName = raw['data']['departmentName'];
responsibleId=raw['data']['id'];
responsibleName=raw['data']['name'];
addData['vehicleCorpId']=corpinfoId;//
addData['vehicleCorpName']=corpinfoName;
});
}else{
ToastUtil.showNormal(context, "获取个人信息失败");
}
} catch (e) {
// Toast
print('加载首页数据失败:$e');
}
}
Future<void> _getProjectNameList() async {
try {
LoadingDialogHelper.show();
final raw = await DoorAndCarApi.getProjectNameList( );
LoadingDialogHelper.hide();
printLongString(jsonEncode(raw));
if (raw['success'] ) {
final newList = raw['data'] ?? [];
for(int i=0;i<newList.length;i++){
newList[i]["dataId"] = newList[i]["id"];
newList[i]["dataName"] = newList[i]["projectName"];
}
showModalBottomSheet(
context: context,
isScrollControlled: true,
barrierColor: Colors.black54,
backgroundColor: Colors.transparent,
builder:
(ctx) => DepartmentPickerThree(
listdata: newList,
onSelected: (id, name,pdId) {
setState(() {
addData['projectId']=id;
addData['projectName']=name;
//
for(int i=0;i<newList.length;i++){
if(id==newList[i]["id"]){
String startProjectTime= newList[i]["startProjectTime"]??'';
String endProjectTime= newList[i]["endProjectTime"]??'';
if(startProjectTime.isNotEmpty){
addData['visitStartTime']=DateFormat('yyyy-MM-dd').format(DateTime.parse(startProjectTime));
}
if(startProjectTime.isNotEmpty){
addData['visitEndTime']=DateFormat('yyyy-MM-dd').format(DateTime.parse(endProjectTime));
}
addData['auditAllTime']='${addData['visitStartTime']}${addData['visitEndTime']}';
}
}
_personList.clear();
});
},
),
);
}else{
ToastUtil.showNormal(context, "获取列表失败");
LoadingDialogHelper.hide();
// _showMessage('反馈提交失败');
// return "";
}
} catch (e) {
// Toast
print('加载首页数据失败:$e');
// return "";
LoadingDialogHelper.hide();
}
}
Future<void> _getApproverList() async {
try {
LoadingDialogHelper.show();
final raw = await DoorAndCarApi.getApproverList( corpinfoId,'','1','','');
LoadingDialogHelper.hide();
if (raw['success'] ) {
List<dynamic> newList = raw['data'] ?? [];
for(int i=0;i<newList.length;i++){
newList[i]["dataId"] = newList[i]["userId"];
newList[i]["dataName"] = newList[i]["userName"];
}
showModalBottomSheet(
context: context,
isScrollControlled: true,
barrierColor: Colors.black54,
backgroundColor: Colors.transparent,
builder:
(ctx) => DepartmentPickerThree(
listdata: newList,
onSelected: (id, name,pdId) async {
setState(() {
for(int i=0;i<newList.length;i++){
if(newList[i]["userId"]==id){
addData['auditCorpId']=newList[i]["corpId"];//
addData['auditCorpName']=newList[i]["corpName"];//
addData['auditDeptId']=newList[i]["deptId"];//
addData['auditDeptName']=newList[i]["deptName"];//
addData['auditUserId']=newList[i]["userId"];//
addData['auditUserName']=newList[i]["userName"]; //
}
}
});
},
),
);
}else{
ToastUtil.showNormal(context, "获取列表失败");
LoadingDialogHelper.hide();
// _showMessage('反馈提交失败');
// return "";
}
} catch (e) {
// Toast
print('加载首页数据失败:$e');
// return "";
LoadingDialogHelper.hide();
}
}
Future<void> _getVisitPortArea() async {
List<String> result = [];
//
final List<int> initialIndices = [];
final resultList = await BasicInfoApi.getDictValues('HG_AUTH_AREA');
List<dynamic> raw = resultList["data"] as List<dynamic>;
result = raw.map((item) => item['dictLabel'].toString()).toList();
if(addData['gateLevelAuthArea'].isNotEmpty){
// JSON
Map<String, dynamic> jsonData = json.decode(addData['gateLevelAuthArea']);
List<dynamic> areaList = jsonData['area'];
// value
List<String> targetValues = areaList.map((item) => item['value'].toString()).toList();
// raw
for (String targetValue in targetValues) {
for (int i = 0; i < raw.length; i++) {
var item = raw[i];
if (item != null && item is Map && item.containsKey('dictLabel')) {
if (item['dictLabel'].toString() == targetValue) {
initialIndices.add(i);// 0
break;
}
}
}
}
}
//
final selectedItems = await CenterMultiPicker.show<String>(
context,
items: result,
itemBuilder: (item) => Text(
item,
style: const TextStyle(fontSize: 16),
),
initialSelectedIndices: initialIndices, //
maxSelection: null, //
allowEmpty: true,
title: '访问港区范围',
);
//
if (selectedItems != null) {
setState(() {
addData['gateLevelAuthAreaName'] = selectedItems.join(',');
// JSON
List<Map<String, dynamic>> areaList = [];
// raw
for (String selectedItem in selectedItems) {
for (var item in raw) {
if (item != null && item is Map && item.containsKey('dictLabel')) {
if (item['dictLabel'].toString() == selectedItem) {
// value(dictLabel) bianma(dictValue)
areaList.add({
'value': item['dictLabel'].toString(),
'bianma': item['dictValue'].toString(), // 使 toString()
});
break;
}
}
}
}
// JSON
Map<String, dynamic> jsonData = {
'area': areaList
};
// Map JSON
addData['gateLevelAuthArea'] = json.encode(jsonData);
});
}
}
Future<String> _addImgFilesLicense(List<String> imagePaths,UploadFileType type,String idType) async {
try {
final raw = await FileApi.uploadFiles( imagePaths, type,idType);
if (raw['success'] ) {
return raw['data']['foreignKey'];
}else{
// _showMessage('反馈提交失败');
return "";
}
} catch (e) {
// Toast
print('加载首页数据失败:$e');
return "";
}
}
//
Future<void> _saveSuccess() async {
try {
if(addData['projectName'].isEmpty){
ToastUtil.showNormal(context, '请选择选择项目名称');
return;
}
if(addData['auditUserName'].isEmpty){
ToastUtil.showNormal(context, '请选择审核人员');
return;
}
if(addData['gateLevelAuthAreaName'].isEmpty){
ToastUtil.showNormal(context, '请选择访问港区');
return;
}
if(_personList.isEmpty){
ToastUtil.showNormal(context, '请选择人员');
return;
}
// List<Person> List<Map<String, dynamic>>
addData['personApplyList'] = _personList.map((person) => person.toJson()).toList();
if(signImages.isEmpty){
ToastUtil.showNormal(context, '请阅读《安全进港须知》并签字');
return;
}
if(signImages.isNotEmpty){
String licenseId= await _addImgFilesLicense(signImages, UploadFileType.gateAccessPersonnelApplicantSignature,'');
addData['informSignId']=licenseId;
}
LoadingDialogHelper.show();
final result = await DoorAndCarApi.xgfPersonSave(addData);
LoadingDialogHelper.hide();
if (result['success'] == true) {
ToastUtil.showNormal(context, '提交成功');
Navigator.pop(context);
} else {
ToastUtil.showNormal(context, result['errMessage']);
}
} catch (e) {
LoadingDialogHelper.hide();
ToastUtil.showNormal(context, '操作失败,请重试');
}
}
Map<String, dynamic> addData={
"personBelongType": '3', //1234
"gateLevelAuthArea": '', //
"gateLevelAuthAreaName": "", //访
"visitStartTime": '', //访
"visitEndTime": '', //访
"informSignId": '', //
"projectId": '', //id
"mkmjId": '', //id
"projectName": '', //
"auditCorpId": '', //
"auditCorpName": '', //
"auditDeptId": '', //
"auditDeptName": '', //
"auditUserId": '', //
"auditUserName": '', //
"auditAllTime": '', //
"personApplyList": [],
};
Map<String, dynamic> addPersonData= {
"personCorpId": '', //ID
"personCorpName": '', //
"personDepartmentId": '', //id
"personDepartmentName": '', //
"employeePersonUserId": '', //id
"employeePersonUserName": '', //
"userFaceUrl": '', //
"userPhone": '', //
"userCard": '', //
};
}

View File

@ -1,10 +1,14 @@
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:qhd_prevention/constants/app_enums.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/single_image_viewer.dart';
import 'package:qhd_prevention/customWidget/toast_util.dart';
import 'package:qhd_prevention/http/ApiService.dart';
import 'package:qhd_prevention/http/modules/doorAndCar_api.dart';
import 'package:qhd_prevention/pages/my_appbar.dart';
import 'package:qhd_prevention/tools/h_colors.dart';
import 'package:qhd_prevention/tools/tools.dart';
@ -12,9 +16,10 @@ import 'package:shared_preferences/shared_preferences.dart';
class OnlylookDoorareaPerson extends StatefulWidget {
const OnlylookDoorareaPerson(this.type, {super.key});
const OnlylookDoorareaPerson(this.type, this.id, {super.key});
final int type;//1 2
final String id;
@override
State<OnlylookDoorareaPerson> createState() => _OnlylookDoorareaPersonState();
@ -22,50 +27,23 @@ class OnlylookDoorareaPerson extends StatefulWidget {
class _OnlylookDoorareaPersonState extends State<OnlylookDoorareaPerson> {
//
final Map<String, String> applicationInfo = {
'mingcheng': '项目名称',
'bumen': '审核人员部门',
'renyuan': '审核人员',
'shijian': '2024-01-01 至 2024-12-31',
'gangqu': '访问港区',
'diqu': '访问地区',
};
//
dynamic applicationInfo = {};
//
final List<Map<String, String>> personnelList = [
{
'name': '张三',
'bumen': '技术部',
'isPei': '',
'wan': 'A区、B区',
},
{
'name': '李四',
'bumen': '安全部',
'isPei': '',
'wan': 'C区',
},
{
'name': '王五',
'bumen': '运营部',
'isPei': '',
'wan': 'A区、C区、D区',
},
];
List<dynamic> personnelList = [];
//
List<String> signList = [];
@override
void initState() {
super.initState();
_getXgfApplyInfoById();
}
@override
Widget build(BuildContext context) {
return Scaffold(
@ -179,7 +157,7 @@ class _OnlylookDoorareaPersonState extends State<OnlylookDoorareaPerson> {
label: '管辖单位:',
isEditable: false,
horizontalnum:0,
text: applicationInfo['mingcheng'] ?? '',
text: applicationInfo['jurisdictionalCorpName'] ?? '',
onTap: () {},
),
const Divider(),
@ -188,7 +166,8 @@ class _OnlylookDoorareaPersonState extends State<OnlylookDoorareaPerson> {
label: '管辖区域:',
isEditable: false,
horizontalnum:0,
text: applicationInfo['bumen'] ?? '',
text: applicationInfo['closedAreaName'] ?? '',
// text: _getAccessArea(applicationInfo),
onTap: () {},
),
const Divider(),
@ -197,7 +176,7 @@ class _OnlylookDoorareaPersonState extends State<OnlylookDoorareaPerson> {
label: '审核人员部门:',
isEditable: false,
horizontalnum:0,
text: applicationInfo['renyuan'] ?? '',
text: applicationInfo['auditPersonDepartmentName'] ?? '',
onTap: () {},
),
const Divider(),
@ -206,7 +185,7 @@ class _OnlylookDoorareaPersonState extends State<OnlylookDoorareaPerson> {
label: '审核人员:',
isEditable: false,
horizontalnum:0,
text: applicationInfo['diqu'] ?? '',
text: applicationInfo['auditPersonUserName'] ?? '',
onTap: () {},
),
@ -217,7 +196,7 @@ class _OnlylookDoorareaPersonState extends State<OnlylookDoorareaPerson> {
label: '所属项目:',
isEditable: false,
horizontalnum:0,
text: applicationInfo['gangqu'] ?? '',
text: applicationInfo['projectName'] ?? '',
onTap: () {},
),
const Divider(),
@ -226,7 +205,7 @@ class _OnlylookDoorareaPersonState extends State<OnlylookDoorareaPerson> {
label: '时间范围:',
isEditable: false,
horizontalnum:0,
text: applicationInfo['shijian'] ?? '',
text: _changeTime(applicationInfo),
onTap: () {},
),
const Divider(),
@ -234,7 +213,7 @@ class _OnlylookDoorareaPersonState extends State<OnlylookDoorareaPerson> {
ItemListWidget.twoRowTitleText(
label: '申请原因:',
text: applicationInfo['shijian']??'',
text: applicationInfo['applyReason']??'',
horizontalInset:0,
),
const Divider(),
@ -267,11 +246,12 @@ class _OnlylookDoorareaPersonState extends State<OnlylookDoorareaPerson> {
//
...personnelList.map((person) => _buildPersonCard(person)),
if(signList.isNotEmpty)
Container(
height: 150,
padding: EdgeInsets.all(8),
alignment: Alignment.center,
child: Image.network('${ApiService.baseImgPath}1983773013086048256/202601/ai_recognition_images/a9c8e701f773470d8a8485ccb6fb35b7.jpg'),
child: Image.network('${ApiService.baseImgPath}${signList[0]}'),
),
@ -299,7 +279,7 @@ class _OnlylookDoorareaPersonState extends State<OnlylookDoorareaPerson> {
children: [
Expanded(
child: Text(
'姓名: ${person['name']}',
'姓名: ${person['employeePersonUserName']}',
style: TextStyle(
fontSize: 14,
color: Colors.grey[700],
@ -310,7 +290,7 @@ class _OnlylookDoorareaPersonState extends State<OnlylookDoorareaPerson> {
SizedBox(width: 24),
Expanded(
child: Text(
'部门: ${person['bumen']}',
'部门: ${person['personDepartmentName']}',
style: TextStyle(
fontSize: 14,
color: Colors.grey[700],
@ -344,8 +324,69 @@ class _OnlylookDoorareaPersonState extends State<OnlylookDoorareaPerson> {
);
}
String _getAccessArea(final item) {
//(1:;2; 34)
String type = item["gateLevelAuthArea"]??'';
if(type.isNotEmpty){
// JSON
Map<String, dynamic> jsonData = json.decode(type);
List<dynamic> areaList = jsonData['area'];
// value
List<String> targetValues = areaList.map((item) => item['value'].toString()).toList();
return targetValues.join(',');
}else{
return '';
}
}
String _changeTime(item) {
String timeStart=item['visitStartTime']??'';
String timeEnd=item['visitEndTime']??'';
if(timeStart.isNotEmpty&&timeEnd.isNotEmpty){
return '$timeStart$timeEnd';
}else{
return '';
}
}
Future<void> _getXgfApplyInfoById() async {
try {
LoadingDialogHelper.show();
final Map<String, dynamic> result= await DoorAndCarApi.getEnclosedPersonById(widget.id);
LoadingDialogHelper.hide();
if (result['success'] ) {
// final dynamic newList = result['data'] ;
setState(() async {
applicationInfo=result['data'];
personnelList=applicationInfo['personApplyList']??[];
final imageResults = await Future.wait([
FileApi.getImagePath(applicationInfo['informSignId'], UploadFileType.enclosedAreaPersonnelApplicantSignature),
]);
if (imageResults[0]['success']) {
setState(() {
// -
List<dynamic> licenseData = imageResults[0]['data'] as List<dynamic>;
signList = licenseData.map((item) => item['filePath'].toString()).toList();
});
}
});
}else{
ToastUtil.showNormal(context, '加载数据失败');
// _showMessage('加载数据失败');
}
} catch (e) {
LoadingDialogHelper.hide();
// Toast
print('加载数据失败:$e');
}
}
}

View File

@ -1,17 +1,23 @@
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:qhd_prevention/constants/app_enums.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/toast_util.dart';
import 'package:qhd_prevention/http/ApiService.dart';
import 'package:qhd_prevention/http/modules/doorAndCar_api.dart';
import 'package:qhd_prevention/pages/my_appbar.dart';
import 'package:qhd_prevention/tools/h_colors.dart';
import 'package:qhd_prevention/tools/tools.dart';
class OnlylookPersonApplication extends StatefulWidget {
const OnlylookPersonApplication(this.type, {super.key});
const OnlylookPersonApplication(this.type, this.id,{super.key});
final int type;//1 2 3 () 4 ()
final int type;//1 2
final String id;
@override
State<OnlylookPersonApplication> createState() => _OnlylookPersonApplicationState();
@ -19,37 +25,21 @@ class OnlylookPersonApplication extends StatefulWidget {
class _OnlylookPersonApplicationState extends State<OnlylookPersonApplication> {
//
final Map<String, String> applicationInfo = {
'mingcheng': '项目名称',
'bumen': '审核人员部门',
'renyuan': '审核人员',
'shijian': '2024-01-01 至 2024-12-31',
'gangqu': '访问港区',
'diqu': '访问地区',
};
//
dynamic applicationInfo = {};
//
final List<Map<String, String>> personnelList = [
{
'name': '张三',
'bumen': '技术部',
'isPei': '',
'wan': 'A区、B区',
},
{
'name': '李四',
'bumen': '安全部',
'isPei': '',
'wan': 'C区',
},
{
'name': '王五',
'bumen': '运营部',
'isPei': '',
'wan': 'A区、C区、D区',
},
];
List<dynamic> personnelList = [];
//
late List<String> signList = [];
@override
void initState() {
super.initState();
_getXgfApplyInfoById();
}
@override
@ -73,11 +63,12 @@ class _OnlylookPersonApplicationState extends State<OnlylookPersonApplication> {
//
...personnelList.map((person) => _buildPersonCard(person)),
if (signList.isNotEmpty)
Container(
height: 150,
padding: EdgeInsets.all(8),
alignment: Alignment.center,
child: Image.network('${ApiService.baseImgPath}1983773013086048256/202601/ai_recognition_images/a9c8e701f773470d8a8485ccb6fb35b7.jpg'),
child: Image.network('${ApiService.baseImgPath}${signList[0]}'),
),
SizedBox(height: 10,),
@ -171,25 +162,25 @@ class _OnlylookPersonApplicationState extends State<OnlylookPersonApplication> {
label: '项目名称:',
isEditable: false,
horizontalnum:0,
text: applicationInfo['mingcheng'] ?? '',
text: applicationInfo['projectName'] ?? '',
onTap: () {},
),
const Divider(),
ItemListWidget.selectableLineTitleTextRightButton(
label: '审核人员部门:',
isEditable: false,
horizontalnum:0,
text: applicationInfo['bumen'] ?? '',
onTap: () {},
),
const Divider(),
// ItemListWidget.selectableLineTitleTextRightButton(
// label: '审核人员部门:',
// isEditable: false,
// horizontalnum:0,
// text: applicationInfo['auditDeptName'] ?? '',
// onTap: () {},
// ),
// const Divider(),
ItemListWidget.selectableLineTitleTextRightButton(
label: '审核人员:',
isEditable: false,
horizontalnum:0,
text: applicationInfo['renyuan'] ?? '',
text: applicationInfo['auditUserName'] ?? '',
onTap: () {},
),
const Divider(),
@ -198,7 +189,7 @@ class _OnlylookPersonApplicationState extends State<OnlylookPersonApplication> {
label: '时间范围:',
isEditable: false,
horizontalnum:0,
text: applicationInfo['shijian'] ?? '',
text: _changeTime(applicationInfo),
onTap: () {},
),
const Divider(),
@ -207,26 +198,26 @@ class _OnlylookPersonApplicationState extends State<OnlylookPersonApplication> {
label: '访问港区:',
isEditable: false,
horizontalnum:0,
text: applicationInfo['gangqu'] ?? '',
text: _getAccessArea(applicationInfo),
onTap: () {},
),
const Divider(),
ItemListWidget.selectableLineTitleTextRightButton(
label: '区域范围:',
isEditable: false,
horizontalnum:0,
text: applicationInfo['diqu'] ?? '',
onTap: () {},
),
const Divider(),
// ItemListWidget.selectableLineTitleTextRightButton(
// label: '区域范围:',
// isEditable: false,
// horizontalnum:0,
// text: applicationInfo['diqu'] ?? '',
// onTap: () {},
// ),
// const Divider(),
],
),
);
}
Widget _buildPersonCard(Map<String, String> person) {
Widget _buildPersonCard(Map<String, dynamic> person) {
return Card(
margin: EdgeInsets.only(bottom: 12),
color: Colors.white,
@ -244,7 +235,7 @@ class _OnlylookPersonApplicationState extends State<OnlylookPersonApplication> {
children: [
Expanded(
child: Text(
'姓名: ${person['name']}',
'姓名: ${person['employeePersonUserName']}',
style: TextStyle(
fontSize: 14,
color: Colors.grey[700],
@ -255,7 +246,7 @@ class _OnlylookPersonApplicationState extends State<OnlylookPersonApplication> {
SizedBox(width: 24),
Expanded(
child: Text(
'部门: ${person['bumen']}',
'部门: ${person['personDepartmentName']}',
style: TextStyle(
fontSize: 14,
color: Colors.grey[700],
@ -266,23 +257,25 @@ class _OnlylookPersonApplicationState extends State<OnlylookPersonApplication> {
// _buildInfoItem('部门:', person['部门'] ?? ''),
],
),
SizedBox(height: 12),
SizedBox(height: 12),
//
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_buildInfoItem('是否培训:', person['isPei'] ?? ''), // 'isPei'
_buildInfoItem('是否培训:', ''), // 'isPei'
SizedBox(width: 24),
Expanded(
child: _buildInfoItem(
'现口门权限范围:',
person['wan'] ?? '', // 'wan'
_getAccessArea(applicationInfo), // 'wan'
isExpanded: true,
),
),
],
),
],
),
),
@ -326,4 +319,69 @@ class _OnlylookPersonApplicationState extends State<OnlylookPersonApplication> {
),
);
}
String _getAccessArea(final item) {
//(1:;2; 34)
String type = item["gateLevelAuthArea"]??'';
if(type.isNotEmpty){
// JSON
Map<String, dynamic> jsonData = json.decode(type);
List<dynamic> areaList = jsonData['area'];
// value
List<String> targetValues = areaList.map((item) => item['value'].toString()).toList();
return targetValues.join(',');
}else{
return '';
}
}
String _changeTime(item) {
String timeStart=item['visitStartTime']??'';
String timeEnd=item['visitEndTime']??'';
if(timeStart.isNotEmpty&&timeEnd.isNotEmpty){
return '$timeStart$timeEnd';
}else{
return '';
}
}
Future<void> _getXgfApplyInfoById() async {
try {
LoadingDialogHelper.show();
final Map<String, dynamic> result= await DoorAndCarApi.getXgfAuditInfoById(widget.id);
LoadingDialogHelper.hide();
if (result['success'] ) {
// final dynamic newList = result['data'] ;
setState(() async {
applicationInfo=result['data'];
personnelList=applicationInfo['personApplyList']??[];
final imageResults = await Future.wait([
FileApi.getImagePath(applicationInfo['informSignId'], UploadFileType.gateAccessPersonnelApplicantSignature),
]);
if (imageResults[0]['success']) {
setState(() {
// -
List<dynamic> licenseData = imageResults[0]['data'] as List<dynamic>;
signList = licenseData.map((item) => item['filePath'].toString()).toList();
});
}
});
}else{
ToastUtil.showNormal(context, '加载数据失败');
// _showMessage('加载数据失败');
}
} catch (e) {
LoadingDialogHelper.hide();
// Toast
print('加载数据失败:$e');
}
}
}

View File

@ -1,17 +1,48 @@
import 'package:flutter/material.dart';
import 'package:lpinyin/lpinyin.dart';
import 'package:qhd_prevention/customWidget/search_bar_widget.dart';
import 'package:qhd_prevention/customWidget/toast_util.dart';
import 'package:qhd_prevention/http/modules/doorAndCar_api.dart';
import 'package:qhd_prevention/pages/my_appbar.dart';
//
class Person {
final String id;
final String name;
final String employeePersonUserId;
final String employeePersonUserName;
final String group;
Person({required this.id, required this.name, required this.group});
final String personCorpId;
final String personCorpName;
final String personDepartmentId;
final String personDepartmentName;
final String userFaceUrl;
final String userPhone;
final String userCard;
Person({required this.employeePersonUserId, required this.employeePersonUserName, required this.group,
required this.personCorpId, required this.personCorpName, required this.personDepartmentId,
required this.personDepartmentName, required this.userFaceUrl, required this.userPhone,
required this.userCard, });
// toJson
Map<String, dynamic> toJson() {
return {
'employeePersonUserId': employeePersonUserId,
'employeePersonUserName': employeePersonUserName,
'group': group,
'personCorpId': personCorpId,
'personCorpName': personCorpName,
'personDepartmentId': personDepartmentId,
'personDepartmentName': personDepartmentName,
'userFaceUrl': userFaceUrl,
'userPhone': userPhone,
'userCard': userCard,
};
}
}
//
class SelectionPersonResult {
final List<Person> selectedPersons;
@ -24,9 +55,11 @@ class SelectionPersonResult {
}
class PersonSelectionPage extends StatefulWidget {
const PersonSelectionPage(this.oldList, {super.key});
const PersonSelectionPage(this.oldList,this.id, {super.key,this.isMoreSelect=true,});
final List<Person> oldList;
final String id;
final bool isMoreSelect;//
@override
State<PersonSelectionPage> createState() => _PersonSelectionPageState();
@ -45,67 +78,10 @@ class _PersonSelectionPageState extends State<PersonSelectionPage> {
late final List<String> sortedGroupKeys;
// GlobalKey
final Map<String, GlobalKey> groupKeys = {};
List< dynamic> list =[];
final List<Map<String, dynamic>> list = [
{
'id': 'p1',
'name': '',
},
{
'id': 'p2',
'name': '',
},
{
'id': 'p3',
'name': '',
},
{
'id': 'p4',
'name': '',
},
{
'id': 'p5',
'name': '',
},
{
'id': 'p6',
'name': '',
},
{
'id': 'p7',
'name': '',
},
{
'id': 'p8',
'name': '',
},
{
'id': 'p9',
'name': '',
},
{
'id': 'p10',
'name': '饿',
},
{
'id': 'p11',
'name': '',
},
{
'id': 'p12',
'name': '',
},
{
'id': 'p13',
'name': '123', //
},
{
'id': 'p14',
'name': '@@@', //
},
];
late Future<void> _dataFuture;
//
final Map<String, bool> selectedStates = {};
//
@ -125,28 +101,41 @@ class _PersonSelectionPageState extends State<PersonSelectionPage> {
void initState() {
super.initState();
// oldListID
_oldSelectedIds = widget.oldList.map((person) => person.id).toSet();
_initData();
_oldSelectedIds = widget.oldList.map((person) => person.employeePersonUserId).toSet();
_dataFuture = _initData();
}
void _initData() {
Future<void> _initData() async {
await _getProJectUserList(widget.id);
//
groupedPersons = {};
for (var item in list) {
String name = item['name'];
String id = item['id'];
String id = item['userId']??'';
String name = item['userName']??'';
// 使lpinyin
String firstLetter = _getFirstLetter(name);
// Person
Person person = Person(
id: id,
name: name,
employeePersonUserId: id,
employeePersonUserName: name,
group: firstLetter,
personCorpId: item['deptId']??'',
personCorpName: item['deptName']??'',
personDepartmentId: item['deptId']??'',
personDepartmentName: item['deptName']??'',
userFaceUrl: item['deptName']??'',
userPhone: item['phone']??'',
userCard: item['deptName']??'',
);
//
if (!groupedPersons.containsKey(firstLetter)) {
groupedPersons[firstLetter] = [];
@ -156,7 +145,7 @@ class _PersonSelectionPageState extends State<PersonSelectionPage> {
//
groupedPersons.forEach((key, value) {
value.sort((a, b) => a.name.compareTo(b.name));
value.sort((a, b) => a.employeePersonUserName.compareTo(b.employeePersonUserName));
});
// #
@ -178,7 +167,7 @@ class _PersonSelectionPageState extends State<PersonSelectionPage> {
for (var group in groupedPersons.keys) {
for (var person in groupedPersons[group]!) {
// oldListtrue
selectedStates[person.id] = _oldSelectedIds.contains(person.id);
selectedStates[person.employeePersonUserId] = _oldSelectedIds.contains(person.employeePersonUserId);
}
//
groupSelectedStates[group] = false;
@ -191,6 +180,26 @@ class _PersonSelectionPageState extends State<PersonSelectionPage> {
}
}
Future<void> _getProJectUserList(String id) async {
try {
final Map<String, dynamic> result = await DoorAndCarApi.getPeopleinProject(id);
if (result['success'] ) {
setState(() {
list = result['data'];
});
}else{
ToastUtil.showNormal(context, '加载数据失败');
// _showMessage('加载数据失败');
}
} catch (e) {
print('Error fetching data: $e');
}
}
// 使lpinyin
String _getFirstLetter(String name) {
if (name.isEmpty) return '#';
@ -276,8 +285,8 @@ class _PersonSelectionPageState extends State<PersonSelectionPage> {
//
void _updateGroupSelection(String group) {
final groupPersons = groupedPersons[group]!;
final allSelected = groupPersons.every((person) => selectedStates[person.id] == true);
final anySelected = groupPersons.any((person) => selectedStates[person.id] == true);
final allSelected = groupPersons.every((person) => selectedStates[person.employeePersonUserId] == true);
final anySelected = groupPersons.any((person) => selectedStates[person.employeePersonUserId] == true);
setState(() {
groupSelectedStates[group] = allSelected;
@ -292,7 +301,7 @@ class _PersonSelectionPageState extends State<PersonSelectionPage> {
setState(() {
groupSelectedStates[group] = newState;
for (var person in groupPersons) {
selectedStates[person.id] = newState;
selectedStates[person.employeePersonUserId] = newState;
}
});
}
@ -305,7 +314,7 @@ class _PersonSelectionPageState extends State<PersonSelectionPage> {
for (var group in groupedPersons.keys) {
final groupPersons = groupedPersons[group]!;
final selectedInGroup = groupPersons
.where((person) => selectedStates[person.id] == true)
.where((person) => selectedStates[person.employeePersonUserId] == true)
.toList();
if (selectedInGroup.isNotEmpty) {
@ -323,6 +332,13 @@ class _PersonSelectionPageState extends State<PersonSelectionPage> {
//
void _confirmSelection() {
final result = _getSelectedResult();
//
if (result.selectedPersons.isEmpty) {
ToastUtil.showNormal(context, '请选择一个人');
return;
}
Navigator.pop(context, result);
}
@ -343,84 +359,95 @@ class _PersonSelectionPageState extends State<PersonSelectionPage> {
),
],),
body: Column(
children: [
Container(
color: Colors.white,
padding: const EdgeInsets.symmetric(horizontal: 5, vertical: 8),
child: SearchBarWidget(
showResetButton: true,
hintText: '请输入关键字',
resetButtonText: '重置',
onReset: () {
FocusScope.of(context).unfocus();
_searchController.text = '';
_search();
},
onSearch: (text) {
FocusScope.of(context).unfocus();
_search();
},
controller: _searchController,
),
),
body:
FutureBuilder(
future: _dataFuture,
builder: (context, snapshot) {
if (snapshot.connectionState != ConnectionState.done) {
return const Center(child: CircularProgressIndicator());
}
//
Expanded(
child: Row(
children: [
//
Expanded(
child: ListView.builder(
controller: _scrollController,
itemCount: sortedGroupKeys.length,
itemBuilder: (context, index) {
String group = sortedGroupKeys[index];
List<Person> persons = groupedPersons[group]!;
return _buildGroupSection(group, persons);
},
),
return Column(
children: [
Container(
color: Colors.white,
padding: const EdgeInsets.symmetric(horizontal: 5, vertical: 8),
child: SearchBarWidget(
showResetButton: true,
hintText: '请输入关键字',
resetButtonText: '重置',
onReset: () {
FocusScope.of(context).unfocus();
_searchController.text = '';
_search();
},
onSearch: (text) {
FocusScope.of(context).unfocus();
_search();
},
controller: _searchController,
),
),
//
Container(
width: 30,
color: Colors.grey.shade50,
child: ListView.builder(
itemCount: alphabet.length,
itemBuilder: (context, index) {
final letter = alphabet[index];
final hasGroup = groupedPersons.containsKey(letter);
return GestureDetector(
onTap: hasGroup ? () => _scrollToGroup(letter) : null,
child: Container(
height: 30,
alignment: Alignment.center,
child: Text(
letter,
style: TextStyle(
fontSize: 12,
color: hasGroup
? Colors.blue
: Colors.grey.shade400,
fontWeight: hasGroup
? FontWeight.bold
: FontWeight.normal,
//
Expanded(
child: Row(
children: [
//
Expanded(
child: ListView.builder(
controller: _scrollController,
itemCount: sortedGroupKeys.length,
itemBuilder: (context, index) {
String group = sortedGroupKeys[index];
List<Person> persons = groupedPersons[group]!;
return _buildGroupSection(group, persons);
},
),
),
//
Container(
width: 30,
color: Colors.grey.shade50,
child: ListView.builder(
itemCount: alphabet.length,
itemBuilder: (context, index) {
final letter = alphabet[index];
final hasGroup = groupedPersons.containsKey(letter);
return GestureDetector(
onTap: hasGroup ? () => _scrollToGroup(letter) : null,
child: Container(
height: 30,
alignment: Alignment.center,
child: Text(
letter,
style: TextStyle(
fontSize: 12,
color: hasGroup
? Colors.blue
: Colors.grey.shade400,
fontWeight: hasGroup
? FontWeight.bold
: FontWeight.normal,
),
),
),
),
),
);
},
),
);
},
),
),
],
),
],
),
),
],
),
],
);
},
),
);
}
@ -470,14 +497,29 @@ class _PersonSelectionPageState extends State<PersonSelectionPage> {
height: 56, // 便
child: CheckboxListTile(
title: Text(
person.name,
person.employeePersonUserName,
style: const TextStyle(fontSize: 14),
),
value: selectedStates[person.id] ?? false,
value: selectedStates[person.employeePersonUserId] ?? false,
onChanged: (bool? value) {
setState(() {
selectedStates[person.id] = value ?? false;
_updateGroupSelection(person.group);
if(widget.isMoreSelect){
selectedStates[person.employeePersonUserId] = value ?? false;
_updateGroupSelection(person.group);
}else{
//
for (var group in groupedPersons.keys) {
for (var p in groupedPersons[group]!) {
selectedStates[p.employeePersonUserId] = false;
}
}
//
selectedStates[person.employeePersonUserId] = true;
}
});
},
activeColor: Colors.blue,

View File

@ -111,6 +111,7 @@ class _SignInstructionsWebviewState extends State<SignInstructionsWebview> {
onPressed: () {
if( signImages.isEmpty){
ToastUtil.showNormal(context, '请先签字');
return;
}
Navigator.pop(context, signImages[0]);

View File

@ -10,6 +10,7 @@ import 'package:qhd_prevention/customWidget/custom_button.dart';
import 'package:qhd_prevention/customWidget/toast_util.dart';
import 'package:qhd_prevention/http/ApiService.dart';
import 'package:qhd_prevention/pages/home/Study/study_tab_list_page.dart';
import 'package:qhd_prevention/pages/home/doorAndCar/doorCar_tab_page.dart';
import 'package:qhd_prevention/pages/home/scan_page.dart';
import 'package:qhd_prevention/pages/home/unit/unit_tab_page.dart';
import 'package:qhd_prevention/pages/main_tab.dart';
@ -60,28 +61,31 @@ class HomePageState extends RouteAwareState<HomePage>
List totalList = [];
Map<String, int> workStats = {'total': 36, 'processed': 30, 'pending': 6};
//
Map<String, int> workStats = {'total': 0, 'processed': 0, 'pending': 0};
List<Map<String, dynamic>> checkLists = [
{
"title": "电工班车间清单",
"type": "隐患排查",
"time": "2025-11-17",
"color": Color(0xFF4CAF50),
},
{
"title": "工地区消防点检清单",
"type": "消防点检",
"time": "2025-11-17",
"color": Color(0xFF2196F3),
},
{
"title": "消防专项检查清单",
"type": "重点作业",
"time": "2025-11-17",
"color": Color(0xFFFF9800),
},
];
//
List<dynamic> checkLists = [];
// List<Map<String, dynamic>> checkLists = [
// {
// "title": "电工班车间清单",
// "type": "隐患排查",
// "time": "2025-11-17",
// "color": Color(0xFF4CAF50),
// },
// {
// "title": "工地区消防点检清单",
// "type": "消防点检",
// "time": "2025-11-17",
// "color": Color(0xFF2196F3),
// },
// {
// "title": "消防专项检查清单",
// "type": "安环检查",
// "time": "2025-11-17",
// "color": Color(0xFFFF9800),
// },
// ];
final List<String> _notifications = [
"系统通知今晚20:00 将进行系统维护,请提前保存数据。",
@ -129,6 +133,8 @@ class HomePageState extends RouteAwareState<HomePage>
"joinFirm": "dashboard-start-work",
};
int pcType=1;
@override
void initState() {
super.initState();
@ -159,6 +165,10 @@ class HomePageState extends RouteAwareState<HomePage>
Future.microtask(() {
_updateModuleAndButtonVisibility();
});
if(_isShowCheckLogin){
_getToDoWorkList(pcType);
}
}
@override
@ -623,6 +633,9 @@ class HomePageState extends RouteAwareState<HomePage>
case "入港培训":
pushPage(StudyTabListPage(), context);
break;
case "口门门禁":
pushPage(DoorcarTabPage(), context);
break;
default:
ToastUtil.showNormal(context, '功能开发中...');
break;
@ -630,37 +643,79 @@ class HomePageState extends RouteAwareState<HomePage>
}
Widget _buildWorkStatsSection() {
double buttonHeight = 45.0;
return Container(
padding: const EdgeInsets.all(1),
padding: const EdgeInsets.all(15),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(12),
boxShadow: const [BoxShadow(color: Colors.black12, blurRadius: 6, offset: Offset(0, 2))],
boxShadow: const [
BoxShadow(color: Colors.black12, blurRadius: 6, offset: Offset(0, 2)),
],
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
width: double.infinity,
padding: const EdgeInsets.symmetric(vertical: 0),
child: RichText(
text: TextSpan(
children: [
TextSpan(
text: "今日有工作项",
style: TextStyle(fontSize: 16, color: Colors.black87),
),
TextSpan(
text: " ${workStats['total']}",
style: const TextStyle(
fontSize: 16,
color: Color(0xFF2A75F8),
fontWeight: FontWeight.bold,
),
),
TextSpan(
text: "",
style: TextStyle(fontSize: 16, color: Colors.black87),
),
],
),
),
),
const SizedBox(height: 15),
Container(
width: screenWidth(context),
height: buttonHeight,
height: 36,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(20),
border: Border.all(color: Colors.grey[300]!, width: 1),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Expanded(
child: GestureDetector(
onTap: () => setState(() => _isMobileSelected = true),
onTap: () {
setState(() {
_isMobileSelected = true;
});
pcType=1;
_getToDoWorkList(pcType);
},
child: Container(
decoration: BoxDecoration(
color: _isMobileSelected ? const Color(0xFFE9F4FE) : Colors.white,
borderRadius: const BorderRadius.only(topLeft: Radius.circular(12)),
color:
_isMobileSelected ? const Color(0xFF2A75F8) : Colors.white,
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(20),
bottomLeft: Radius.circular(20),
),
),
child: Center(
child: Text(
"手机端",
style: TextStyle(
fontSize: 14,
color: _isMobileSelected ? Colors.black : Colors.blue,
color: _isMobileSelected ? Colors.white : Colors.black87,
fontWeight: FontWeight.w500,
),
),
@ -668,26 +723,29 @@ class HomePageState extends RouteAwareState<HomePage>
),
),
),
Image.asset(
'assets/images/${_isMobileSelected ? 'img2.png' : 'img1.png'}',
fit: BoxFit.cover,
height: buttonHeight,
width: 30,
),
Expanded(
child: GestureDetector(
onTap: () => setState(() => _isMobileSelected = false),
onTap: () {
setState(() {
_isMobileSelected = false;
});
pcType=2;
_getToDoWorkList(pcType);
},
child: Container(
decoration: BoxDecoration(
color: !_isMobileSelected ? const Color(0xFFE9F4FE) : Colors.white,
borderRadius: const BorderRadius.only(topRight: Radius.circular(12)),
color: !_isMobileSelected ? const Color(0xFF2A75F8) : Colors.white,
borderRadius: const BorderRadius.only(
topRight: Radius.circular(20),
bottomRight: Radius.circular(20),
),
),
child: Center(
child: Text(
"电脑端",
style: TextStyle(
fontSize: 15,
color: !_isMobileSelected ? Colors.black : Colors.blue,
fontSize: 14,
color: !_isMobileSelected ? Colors.white : Colors.black87,
fontWeight: FontWeight.w500,
),
),
@ -698,147 +756,192 @@ class HomePageState extends RouteAwareState<HomePage>
],
),
),
Padding(
padding: const EdgeInsets.all(15),
child: Column(
children: [
Container(
width: double.infinity,
padding: const EdgeInsets.symmetric(vertical: 0),
child: RichText(
text: TextSpan(
children: [
const TextSpan(text: "今日有工作项", style: TextStyle(fontSize: 16, color: Colors.black87)),
TextSpan(
text: " ${workStats['total']}",
style: const TextStyle(fontSize: 16, color: Color(0xFF2A75F8), fontWeight: FontWeight.bold),
),
const TextSpan(text: "", style: TextStyle(fontSize: 16, color: Colors.black87)),
],
),
),
),
const SizedBox(height: 15),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
RichText(
text: TextSpan(
children: [
const TextSpan(text: "已处理工作项:", style: TextStyle(fontSize: 14, color: Colors.black87)),
TextSpan(
text: " ${workStats['processed']}",
style: const TextStyle(fontSize: 14, color: Colors.greenAccent, fontWeight: FontWeight.bold),
),
const TextSpan(text: "", style: TextStyle(fontSize: 14, color: Colors.black87)),
],
),
),
RichText(
text: TextSpan(
children: [
const TextSpan(text: "待处理工作项:", style: TextStyle(fontSize: 14, color: Colors.black87)),
TextSpan(
text: " ${workStats['pending']}",
style: const TextStyle(fontSize: 14, color: Colors.orange, fontWeight: FontWeight.bold),
),
const TextSpan(text: "", style: TextStyle(fontSize: 14, color: Colors.black87)),
],
),
),
],
),
],
),
),
// const SizedBox(height: 15),
// Row(
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
// children: [
// RichText(
// text: TextSpan(
// children: [
// TextSpan(
// text: "已处理工作项:",
// style: TextStyle(fontSize: 14, color: Colors.black87),
// ),
// TextSpan(
// text: " ${workStats['processed']}",
// style: const TextStyle(
// fontSize: 14,
// color: Colors.greenAccent,
// fontWeight: FontWeight.bold,
// ),
// ),
// TextSpan(
// text: "",
// style: TextStyle(fontSize: 14, color: Colors.black87),
// ),
// ],
// ),
// ),
// RichText(
// text: TextSpan(
// children: [
// TextSpan(
// text: "待处理工作项:",
// style: TextStyle(fontSize: 14, color: Colors.black87),
// ),
// TextSpan(
// text: " ${workStats['processed']}",
// style: const TextStyle(
// fontSize: 14,
// color: Colors.orange,
// fontWeight: FontWeight.bold,
// ),
// ),
// TextSpan(
// text: "",
// style: TextStyle(fontSize: 14, color: Colors.black87),
// ),
// ],
// ),
// ),
// ],
// ),
],
),
);
}
// Widget _buildCheckListSection() {
// return Column(
// children: [
// Row(
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
// children: const [
// Text(' 待办清单', style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)),
// SizedBox(),
// ],
// ),
// const SizedBox(height: 8),
// Container(
// decoration: BoxDecoration(
// color: Colors.white,
// borderRadius: BorderRadius.circular(12),
// boxShadow: const [BoxShadow(color: Colors.black12, blurRadius: 6, offset: Offset(0, 2))],
// ),
// child: Column(children: [...checkLists.map((item) => _buildCheckListItem(item))]),
// ),
// ],
// );
// }
Widget _buildCheckListSection() {
return Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: const [
Text(' 待办清单', style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)),
SizedBox(),
],
),
const SizedBox(height: 8),
Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(12),
boxShadow: const [BoxShadow(color: Colors.black12, blurRadius: 6, offset: Offset(0, 2))],
),
child: Column(children: [...checkLists.map((item) => _buildCheckListItem(item))]),
),
],
return Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(12),
boxShadow: const [
BoxShadow(color: Colors.black12, blurRadius: 6, offset: Offset(0, 2)),
],
),
child: Column(
children: checkLists.map((item) => _buildCheckListItem(item)).toList(),
),
);
}
Widget _buildCheckListItem(Map<String, dynamic> item) {
return Container(
padding: const EdgeInsets.all(15),
decoration: BoxDecoration(
border: Border(bottom: BorderSide(color: Colors.grey[200]!, width: 1)),
),
child: Row(
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Flexible(
child: Text(
return GestureDetector(
onTap: () async {
if(pcType==2){
return;
}
switch(item['appName']){
case "隐患治理":
case "隐患管理":
case "风险管控应用":
// await pushPage(ApplicationPageTwo(), context);
break;
case "消防检查":
// await pushPage(FireManagementTabPage(), context);
break;
case "一级口门管理":
await pushPage(DoorcarTabPage(), context);
break;
case "安全环保检查":
// await pushPage(SafecheckTabList(), context);
break;
}
_getToDoWorkList(pcType);
// _getHiddenIssuesNum();
},
child: Container(
padding: const EdgeInsets.all(15),
decoration:
BoxDecoration(border: Border(bottom: BorderSide(color: Colors.grey[200]!, width: 1))),
child: Row(
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
item['title'],
style: const TextStyle(fontSize: 15, fontWeight: FontWeight.bold, color: Colors.black87),
overflow: TextOverflow.ellipsis,
maxLines: 1,
),
),
const SizedBox(width: 8),
Text(item['type'], style: TextStyle(fontSize: 12, color: Colors.grey[500])),
],
),
const SizedBox(height: 8),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Flexible(
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2),
decoration: BoxDecoration(
color: Colors.grey[100],
borderRadius: BorderRadius.circular(4),
),
child: Text(
"类型:${item['type']}",
style: const TextStyle(fontSize: 12, color: Colors.blue),
overflow: TextOverflow.ellipsis,
),
Text(item['content'], style: TextStyle(fontSize: 12, color: Colors.grey[500])),
],
),
const Divider(),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
Image.asset('assets/images/mine1.png', width: 15, height: 15),
Container(
padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2),
decoration: BoxDecoration(color: Colors.grey[100], borderRadius: BorderRadius.circular(4)),
child: Text("类型:${item['appName']}", style: const TextStyle(fontSize: 12, color: Colors.blue)),
),
],
),
),
const SizedBox(width: 8),
Flexible(
child: Text(
"时间:${item['time']}",
style: const TextStyle(fontSize: 12, color: Colors.grey),
overflow: TextOverflow.ellipsis,
),
),
],
),
],
Text("时间:${item['createTime']}", style: const TextStyle(fontSize: 12, color: Colors.grey)),
],
),
],
),
),
),
],
],
),
),
);
}
//
void _getToDoWorkList(int type) async {
Map data = {
"eqAppFlag": type==1?"1":"",
"eqPcFlag": type==1?"":"1",
"eqStatus": "1",
"pageIndex": '1',
"pageSize": '999',
};
final result = await TodoApi.getTodoList(data);
if (result['success']) {
setState(() {
workStats['total'] =result['totalCount'] ;
checkLists=result['data'];
// checkLists = result['data'];
int m= checkLists.length;
});
}
}
}

View File

@ -50,9 +50,10 @@ class _NotifDetailPageState extends State<NotifDetailPage> {
}
Future<void> _getNotifDetail() async {
// LoadingDialogHelper.show();
try {
LoadingDialogHelper.show();
final result = await NotifApi.getNoticeDetail(item['noticeId']);
LoadingDialogHelper.hide();
if (result['success']) {
final dynamic newList = result['data'] ;
setState(() {
@ -72,23 +73,29 @@ class _NotifDetailPageState extends State<NotifDetailPage> {
}
} catch (e) {
print('加载出错: $e');
LoadingDialogHelper.hide();
}
}
Future<void> _getNotifEnterpriseDetail() async {
// LoadingDialogHelper.show();
try {
// final result = await HiddenDangerApi.getNotifEnterpriseDetail(item['NOTICECORPUSERID_ID']);
// if (result['result'] == 'success') {
// final dynamic newList = result['pd'] ;
// setState(() {
// title= newList['SYNOPSIS'];
// time= newList['CREATTIME'];
// text= newList['CONTENT'];
// });
// }
LoadingDialogHelper.show();
final result = await NotifApi.getAnnouncementDetail(item['id']);
LoadingDialogHelper.hide();
if (result['success']) {
final dynamic newList = result['data'] ;
setState(() {
title= newList['title']??'';
time= newList['sendTime']??'';
text= newList['content']??'';
isShowReply=false;
// noticeReadId=newList['noticeReadId']??'';
// replyText=newList['replyContent']??'';
});
}
} catch (e) {
print('加载出错: $e');
LoadingDialogHelper.hide();
}
}
@ -127,30 +134,30 @@ class _NotifDetailPageState extends State<NotifDetailPage> {
),
SizedBox(height: 8),
// if(isShowReply&&replyText.isEmpty)
CustomButton(
height: 35,
margin: EdgeInsets.only(right: 10),
onPressed: () async {
if(isShowReply&&replyText.isEmpty)
CustomButton(
height: 35,
margin: EdgeInsets.only(right: 10),
onPressed: () async {
final confirmed = await CustomAlertDialogTwo.showInput(
context,
title: "回复",
hintText: '输入内容',
cancelText: '关闭',
confirmText: '确定',
);
if (confirmed != null&&confirmed.isNotEmpty) {
//
// ToastUtil.showNormal(context, confirmed);
_replyContent(confirmed);
}
},
backgroundColor: h_AppBarColor(),
textStyle: const TextStyle(color: Colors.white),
buttonStyle: ButtonStyleType.primary,
text: '回复',
),
final confirmed = await CustomAlertDialogTwo.showInput(
context,
title: "回复",
hintText: '输入内容',
cancelText: '关闭',
confirmText: '确定',
);
if (confirmed != null&&confirmed.isNotEmpty) {
//
// ToastUtil.showNormal(context, confirmed);
_replyContent(confirmed);
}
},
backgroundColor: h_AppBarColor(),
textStyle: const TextStyle(color: Colors.white),
buttonStyle: ButtonStyleType.primary,
text: '回复',
),
],
),
),

View File

@ -189,35 +189,35 @@ class NotifPageState extends RouteAwareState<NotifPage>
if(_selectedTab==0){
result = await NotifApi.getNoticeList(data);
}else{
result = await NotifApi.getNoticeList(data);
result = await NotifApi.getAnnouncementList(data);
}
BadgeManager().updateNotifCount();
LoadingDialogHelper.hide();
if(_selectedTab==0){
if (result['success']) {
_totalPage =result['totalPages'] ?? 1;
final List<dynamic> newList = result['data'] ?? [];
// setState(() {
// _list.addAll(newList);
// });
setState(() {
if (loadMore) {
_list.addAll(newList);
} else {
_list = newList;
}
_hasMore = pageNum < _totalPage;
// if (_hasMore) _page++;
});
if (result['success']) {
_totalPage =result['totalPages'] ?? 1;
final List<dynamic> newList = result['data'] ?? [];
// setState(() {
// _list.addAll(newList);
// });
}else{
ToastUtil.showNormal(context, "加载数据失败");
// _showMessage('加载数据失败');
}
setState(() {
if (loadMore) {
_list.addAll(newList);
} else {
_list = newList;
}
_hasMore = pageNum < _totalPage;
// if (_hasMore) _page++;
});
}else{
ToastUtil.showNormal(context, "加载数据失败");
// _showMessage('加载数据失败');
}
} catch (e) {
LoadingDialogHelper.hide();
// Toast
@ -371,7 +371,7 @@ class NotifPageState extends RouteAwareState<NotifPage>
SizedBox(height: 8.0),
Text(
'发布时间:${item['publishTime']??''}',
'发布时间:${_selectedTab==0?item['publishTime']??'':item['sendTime']??''}',
style: TextStyle(fontSize: 14.0, color: Colors.grey[500]),
),
],
@ -384,7 +384,7 @@ class NotifPageState extends RouteAwareState<NotifPage>
mainAxisSize: MainAxisSize.min,
children: [
Text(
item['readStatus']=='1'?'已阅':'待阅',
_readStates(item),
style: TextStyle(
fontSize: 16.0,
color: Colors.black,
@ -393,7 +393,8 @@ class NotifPageState extends RouteAwareState<NotifPage>
),
const SizedBox(width: 6.0),
Image.asset(
item['readStatus']=='1'?'assets/icon-apps/read_message.png':'assets/icon-apps/unread_message.png',
_readStatesOne(item),
// item['readStatus']=='1'?'assets/icon-apps/read_message.png':'assets/icon-apps/unread_message.png',
width: 25,
height: 25,
),
@ -407,7 +408,21 @@ class NotifPageState extends RouteAwareState<NotifPage>
);
}
String _readStatesOne(item){
if(_selectedTab==0){
return item['readStatus']=='1'?'assets/icon-apps/read_message.png':'assets/icon-apps/unread_message.png';
}else{
return item['readTime']!=null?'assets/icon-apps/read_message.png':'assets/icon-apps/unread_message.png';
}
}
String _readStates(item){
if(_selectedTab==0){
return item['readStatus']=='1'?'已阅':'待阅';
}else{
return item['readTime']!=null?'已阅':'待阅';
}
}

View File

@ -0,0 +1,53 @@
/// 绿
///
/// 1. 92 1 + 1 + 5/I/O
/// 2. 1 + 1 + 6
/// - DF + 5/
/// - 5/ + DF
/// 使
bool isValidChineseLicensePlate(String plate) {
if (plate.isEmpty) return false;
// ·
plate = plate.replaceAll(RegExp(r'[\s·\-]'), '');
//
final provinces = '京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼';
//
// + + 5IO
final fuelRegex = RegExp('^[$provinces][A-HJ-NP-Z][A-HJ-NP-Z0-9]{5}\$');
// + + 6DF
// IODF
final newEnergyRegex = RegExp('^[$provinces][A-HJ-NP-Z][A-HJ-NP-Z0-9]{6}\$');
// 7
if (plate.length == 7) {
return fuelRegex.hasMatch(plate);
}
// 8
if (plate.length == 8) {
//
if (!newEnergyRegex.hasMatch(plate)) {
return false;
}
// DF
// 6
String suffix = plate.substring(2);
// DF
if (!suffix.contains(RegExp(r'[DF]'))) {
return false;
}
return true;
}
return false;
}