From 1105dbb2cf1b0f6c4a7fbbc98734a33734cdbb67 Mon Sep 17 00:00:00 2001 From: xufei <727302827@qq.com> Date: Thu, 4 Jun 2026 15:58:37 +0800 Subject: [PATCH 1/5] =?UTF-8?q?2026.6.4=20=E4=B8=AA=E4=BA=BA=E4=BF=A1?= =?UTF-8?q?=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- android/gradle.properties | 6 +- .../home/unit/unit_service_list_page.dart | 205 ++++++++++++++++++ lib/pages/home/unit/unit_tab_page.dart | 4 +- lib/pages/user/login_page.dart | 6 +- 4 files changed, 217 insertions(+), 4 deletions(-) create mode 100644 lib/pages/home/unit/unit_service_list_page.dart diff --git a/android/gradle.properties b/android/gradle.properties index 24863d2..475a628 100644 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -1,3 +1,7 @@ org.gradle.jvmargs=-Xmx8G -XX:MaxMetaspaceSize=4G -XX:ReservedCodeCacheSize=512m -XX:+HeapDumpOnOutOfMemoryError android.useAndroidX=true -android.enableJetifier=true \ No newline at end of file +android.enableJetifier=true +# This builtInKotlin flag was added automatically by Flutter migrator +android.builtInKotlin=false +# This newDsl flag was added automatically by Flutter migrator +android.newDsl=false diff --git a/lib/pages/home/unit/unit_service_list_page.dart b/lib/pages/home/unit/unit_service_list_page.dart new file mode 100644 index 0000000..86226b6 --- /dev/null +++ b/lib/pages/home/unit/unit_service_list_page.dart @@ -0,0 +1,205 @@ +import 'dart:convert'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:qhd_prevention/pages/home/unit/unit_join_detail_page.dart'; +import 'package:qhd_prevention/pages/home/unit/unit_quit_apply_page.dart'; +import 'package:qhd_prevention/pages/my_appbar.dart'; +import 'package:qhd_prevention/services/SessionService.dart'; +import 'package:qhd_prevention/services/StorageService.dart'; + +import 'package:qhd_prevention/tools/tools.dart'; +import 'package:qhd_prevention/customWidget/custom_button.dart'; +import 'package:qhd_prevention/http/ApiService.dart'; + +class UnitServiceListPage extends StatefulWidget { + const UnitServiceListPage({Key? key}) : super(key: key); + + @override + _UnitServiceListPageState createState() => _UnitServiceListPageState(); +} + +class _UnitServiceListPageState extends State { + // Data and state variables + List list = []; + int currentPage = 1; + int rows = 10; + int totalPage = 1; + bool isLoading = false; + + List> flowList = []; + final GlobalKey _scaffoldKey = GlobalKey(); + final ScrollController _scrollController = ScrollController(); + final employmentFlag = {'0': '离职', '1': '在职', '3': '未入职'}; + final statusInfo = { + '1': '待审批', + '2': '通过', + '3': '驳回', + }; + + @override + void initState() { + super.initState(); + _fetchData(); + _scrollController.addListener(_onScroll); + } + + @override + void dispose() { + _scrollController.dispose(); + super.dispose(); + } + + void _onScroll() { + if (_scrollController.position.pixels >= + _scrollController.position.maxScrollExtent && + !isLoading) { + if (currentPage < totalPage) { + currentPage++; + _fetchData(); + } + } + } + String formatDate(String dateTimeStr) { + if (dateTimeStr == null || dateTimeStr.isEmpty) { + return ''; + } + // 解析字符串为DateTime对象 + DateTime dateTime = DateTime.parse(dateTimeStr); + final time = dateTime == null ? '' : '${dateTime.year}年${dateTime.month}月${dateTime.day}日'; + // 格式化为年月日 + return time; + } + Future _fetchData() async { + // if (isLoading) return; + // setState(() => isLoading = true); + // + // try { + // + // final data = { + // 'pageIndex': currentPage, + // 'pageSize': rows, + // 'eqUserId': SessionService.instance.accountId + // }; + // final response = await BasicInfoApi.getFirmListByUser(data); + // setState(() { + // if (currentPage == 1) { + // list = response['data']; + // } else { + // list.addAll(response['data']); + // } + // Map page = response['page']; + // totalPage = page['totalPage'] ?? 1; + // isLoading = false; + // }); + // } catch (e) { + // print('Error fetching data: $e'); + // setState(() => isLoading = false); + // } + } + + //查看 + void _goToDetail(Map item) async { + await pushPage( + UnitJoinDetailPage(firmId: item['id'],), + context, + ); + _fetchData(); + } + + + + + Widget _buildListItem(Map item) { + return Card( + color: Colors.white, + margin: const EdgeInsets.all(8.0), + child: InkWell( + onTap: () => _goToDetail(item), + child: Padding( + padding: const EdgeInsets.all(12.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + '服务单位名称:${item['corpinfoName'] ?? ''}', + style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold), + ), + ], + ), + const SizedBox(height: 8), + + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + "所属公司: ${item['corpinfoName'] ?? ''}(相关方)", + maxLines: 5, + overflow: TextOverflow.ellipsis, + ), + ], + ), + const SizedBox(height: 8), + + Text( + "项目名称: ${item['corpinfoName'] ?? ''}", + maxLines: 5, + overflow: TextOverflow.ellipsis, + ), + + const SizedBox(height: 8), + Text( + "项目类型: ${statusInfo['${item['status']}'] ?? ''}", + maxLines: 5, + overflow: TextOverflow.ellipsis, + ), + + ], + ), + ), + ), + ); + } + + + Widget _buildListContent() { + if (isLoading && list.isEmpty) { + // 初始加载时显示居中的加载指示器 + return Center(child: CircularProgressIndicator()); + } else if (list.isEmpty) { + // 没有数据 + return NoDataWidget.show(); + } else { + // 有数据或加载更多 + return ListView.builder( + padding: EdgeInsets.zero, + + controller: _scrollController, + itemCount: list.length + (isLoading ? 1 : 0), + itemBuilder: (context, index) { + if (index >= list.length) { + // 加载更多时在列表底部显示加载指示器 + return Padding( + padding: const EdgeInsets.symmetric(vertical: 16.0), + child: Center(child: CircularProgressIndicator()), + ); + } + return _buildListItem(list[index]); + }, + ); + } + } + + @override + Widget build(BuildContext context) { + return Scaffold( + key: _scaffoldKey, + appBar: MyAppbar(title: '服务单位', actions: []), + + body: SafeArea(child: _buildListContent()), + ); + } +} diff --git a/lib/pages/home/unit/unit_tab_page.dart b/lib/pages/home/unit/unit_tab_page.dart index 5cf0c50..ed7aca7 100644 --- a/lib/pages/home/unit/unit_tab_page.dart +++ b/lib/pages/home/unit/unit_tab_page.dart @@ -6,6 +6,7 @@ import 'package:qhd_prevention/customWidget/work_tab_icon_grid.dart'; import 'package:qhd_prevention/http/ApiService.dart'; import 'package:qhd_prevention/customWidget/IconBadgeButton.dart'; import 'package:qhd_prevention/pages/home/unit/unit_join_list_page.dart'; +import 'package:qhd_prevention/pages/home/unit/unit_service_list_page.dart'; import 'package:qhd_prevention/pages/my_appbar.dart'; import 'package:qhd_prevention/tools/tools.dart'; import 'package:qhd_prevention/common/route_aware_state.dart'; @@ -144,7 +145,8 @@ class _UnitTabPageState extends RouteAwareState { final title = _masterButtons[index]['title'] as String; switch (title) { case '服务单位管理': - ToastUtil.showNormal(context, '您还没有参与项目'); + // ToastUtil.showNormal(context, '您还没有参与项目'); + pushPage(UnitServiceListPage(), context); break; case '就职单位管理': pushPage(UnitJoinListPage(), context); diff --git a/lib/pages/user/login_page.dart b/lib/pages/user/login_page.dart index c44933a..72c4c48 100644 --- a/lib/pages/user/login_page.dart +++ b/lib/pages/user/login_page.dart @@ -402,7 +402,8 @@ class _LoginPageState extends State { const WebViewPage( name: "用户服务协议", url: - 'http://47.92.102.56:7811/file/xieyi/zsyhxy.htm', + 'https://qaaq.qhdsafety.com/help/gwj/gwj-zsyhxy.htm', + // 'http://47.92.102.56:7811/file/xieyi/zsyhxy.htm', ), context, ); @@ -428,7 +429,8 @@ class _LoginPageState extends State { const WebViewPage( name: "隐私政策", url: - 'http://47.92.102.56:7811/file/xieyi/zsysq.htm', + 'https://qaaq.qhdsafety.com/help/gwj/gwj-zsysq.htm', + // 'http://47.92.102.56:7811/file/xieyi/zsysq.htm', ), context, ); From 547325941ac46c59786cf7248857befec7319b61 Mon Sep 17 00:00:00 2001 From: xufei <727302827@qq.com> Date: Fri, 5 Jun 2026 15:59:42 +0800 Subject: [PATCH 2/5] =?UTF-8?q?2026.6.5=20=E6=9C=8D=E5=8A=A1=E5=8D=95?= =?UTF-8?q?=E4=BD=8D=E7=AE=A1=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/http/modules/basic_info_api.dart | 10 +++ .../home/unit/unit_service_list_page.dart | 70 +++++++++++-------- 2 files changed, 50 insertions(+), 30 deletions(-) diff --git a/lib/http/modules/basic_info_api.dart b/lib/http/modules/basic_info_api.dart index 28bda1e..31aa69d 100644 --- a/lib/http/modules/basic_info_api.dart +++ b/lib/http/modules/basic_info_api.dart @@ -93,6 +93,16 @@ class BasicInfoApi { data: {...data}, ); } + + /// 服务单位管理接口 + static Future> getUnitServiceList(Map data) { + return HttpManager().request( + ApiService.basePath , + '/xgfManager/project/projectPageByUser', + method: Method.post, + data: {...data}, + ); + } /// 企业入职详情 static Future> getFirmInfo(String id) { return HttpManager().request( diff --git a/lib/pages/home/unit/unit_service_list_page.dart b/lib/pages/home/unit/unit_service_list_page.dart index 86226b6..2b05311 100644 --- a/lib/pages/home/unit/unit_service_list_page.dart +++ b/lib/pages/home/unit/unit_service_list_page.dart @@ -2,6 +2,7 @@ import 'dart:convert'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; +import 'package:qhd_prevention/customWidget/toast_util.dart'; import 'package:qhd_prevention/pages/home/unit/unit_join_detail_page.dart'; import 'package:qhd_prevention/pages/home/unit/unit_quit_apply_page.dart'; import 'package:qhd_prevention/pages/my_appbar.dart'; @@ -23,7 +24,7 @@ class _UnitServiceListPageState extends State { // Data and state variables List list = []; int currentPage = 1; - int rows = 10; + int rows = 20; int totalPage = 1; bool isLoading = false; @@ -71,31 +72,40 @@ class _UnitServiceListPageState extends State { return time; } Future _fetchData() async { - // if (isLoading) return; - // setState(() => isLoading = true); - // - // try { - // - // final data = { - // 'pageIndex': currentPage, - // 'pageSize': rows, - // 'eqUserId': SessionService.instance.accountId - // }; - // final response = await BasicInfoApi.getFirmListByUser(data); - // setState(() { - // if (currentPage == 1) { - // list = response['data']; - // } else { - // list.addAll(response['data']); - // } - // Map page = response['page']; - // totalPage = page['totalPage'] ?? 1; - // isLoading = false; - // }); - // } catch (e) { - // print('Error fetching data: $e'); - // setState(() => isLoading = false); - // } + if (isLoading) return; + setState(() => isLoading = true); + + try { + + final data = { + 'pageIndex': currentPage, + 'pageSize': rows, + "eqProjectStatus":4, + "searchType":5, + // 'eqUserId': SessionService.instance.accountId + }; + // LoadingDialogHelper.show(); + final response = await BasicInfoApi.getUnitServiceList(data); + // LoadingDialogHelper.hide(); + if (response['success']) { + setState(() { + if (currentPage == 1) { + list = response['data']; + } else { + list.addAll(response['data']); + } + Map page = response['page']; + totalPage = page['totalPage'] ?? 1; + isLoading = false; + }); + }else { + ToastUtil.showNormal(context, '获取列表失败'); + setState(() => isLoading = false); + } + } catch (e) { + print('Error fetching data: $e'); + setState(() => isLoading = false); + } } //查看 @@ -125,7 +135,7 @@ class _UnitServiceListPageState extends State { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( - '服务单位名称:${item['corpinfoName'] ?? ''}', + '服务单位名称:${item['companyName'] ?? ''}', style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold), ), ], @@ -136,7 +146,7 @@ class _UnitServiceListPageState extends State { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( - "所属公司: ${item['corpinfoName'] ?? ''}(相关方)", + "所属公司: ${item['corpinfoName'] ?? ''}", maxLines: 5, overflow: TextOverflow.ellipsis, ), @@ -145,14 +155,14 @@ class _UnitServiceListPageState extends State { const SizedBox(height: 8), Text( - "项目名称: ${item['corpinfoName'] ?? ''}", + "项目名称: ${item['projectName'] ?? ''}", maxLines: 5, overflow: TextOverflow.ellipsis, ), const SizedBox(height: 8), Text( - "项目类型: ${statusInfo['${item['status']}'] ?? ''}", + "项目类型: ${item['qualificationsTypeName']??''}", maxLines: 5, overflow: TextOverflow.ellipsis, ), From 3269868f8341f874085496b5189412c7fc40595d Mon Sep 17 00:00:00 2001 From: xufei <727302827@qq.com> Date: Fri, 5 Jun 2026 17:00:48 +0800 Subject: [PATCH 3/5] =?UTF-8?q?2026.6.5=20=E4=BA=8C=E7=BB=B4=E7=A0=81?= =?UTF-8?q?=E6=89=AB=E7=A0=81=E6=8F=90=E7=A4=BA=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/pages/home/scan_page.dart | 54 +++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/lib/pages/home/scan_page.dart b/lib/pages/home/scan_page.dart index 8050ac3..78fd144 100644 --- a/lib/pages/home/scan_page.dart +++ b/lib/pages/home/scan_page.dart @@ -30,14 +30,20 @@ class ScanPage extends StatefulWidget { class _ScanPageState extends State { final MobileScannerController _controller = MobileScannerController(); bool _torchOn = false; + bool _hasPermission = true; // 默认有权限 @override void initState() { super.initState(); + + // 监听 controller 的状态变化 + _controller.addListener(_onControllerStateChange); + } @override void dispose() { + _controller.removeListener(_onControllerStateChange); // 移除监听 _controller.dispose(); super.dispose(); } @@ -72,6 +78,27 @@ class _ScanPageState extends State { } + + // 监听权限状态变化 + void _onControllerStateChange() { + final error = _controller.value.error; + + if (error != null && mounted) { + // 检查是否是权限被拒绝的错误 + if (error.errorCode == MobileScannerErrorCode.permissionDenied) { + setState(() { + _hasPermission = false; + }); + print('相机权限被拒绝'); + } + } else if (_controller.value.isRunning && mounted) { + // 如果相机正在运行,说明有权限 + setState(() { + _hasPermission = true; + }); + } + } + // 人脸识别跳转 void goToFace(Map stuInfo) async { print('navigate to face with $stuInfo'); @@ -234,6 +261,33 @@ class _ScanPageState extends State { }, ), ), + + + // 权限遮罩 - 放在最上层覆盖所有内容 + if (!_hasPermission) + Container( + color: Colors.black, + child: const Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon(Icons.camera_alt, color: Colors.white, size: 64), + SizedBox(height: 20), + Text( + '需要相机权限才能使用扫码功能', + style: TextStyle(color: Colors.white, fontSize: 16), + ), + SizedBox(height: 10), + Text( + '请在设置中允许相机权限', + style: TextStyle(color: Colors.white70, fontSize: 14), + ), + ], + ), + ), + ), + + ], ), ); From 44727015e9d6f420bc7e0535be0b8506e1d67f21 Mon Sep 17 00:00:00 2001 From: xufei <727302827@qq.com> Date: Mon, 8 Jun 2026 10:18:43 +0800 Subject: [PATCH 4/5] =?UTF-8?q?2026.6.8=20=E4=B8=AA=E4=BA=BA=E4=BF=A1?= =?UTF-8?q?=E6=81=AFbug=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../home/unit/unit_service_list_page.dart | 10 +-- lib/pages/user/full_userinfo_page.dart | 74 +++++++++++++++---- 2 files changed, 66 insertions(+), 18 deletions(-) diff --git a/lib/pages/home/unit/unit_service_list_page.dart b/lib/pages/home/unit/unit_service_list_page.dart index 2b05311..1c300e0 100644 --- a/lib/pages/home/unit/unit_service_list_page.dart +++ b/lib/pages/home/unit/unit_service_list_page.dart @@ -110,11 +110,11 @@ class _UnitServiceListPageState extends State { //查看 void _goToDetail(Map item) async { - await pushPage( - UnitJoinDetailPage(firmId: item['id'],), - context, - ); - _fetchData(); + // await pushPage( + // UnitJoinDetailPage(firmId: item['id'],), + // context, + // ); + // _fetchData(); } diff --git a/lib/pages/user/full_userinfo_page.dart b/lib/pages/user/full_userinfo_page.dart index 1bd9d53..6014644 100644 --- a/lib/pages/user/full_userinfo_page.dart +++ b/lib/pages/user/full_userinfo_page.dart @@ -252,7 +252,7 @@ class _FullUserinfoPageState extends State { _birthText = idInfo.birth ?? ''; } - if (idPhotos.length < 2 && !_isChange) { + if (_idCardImgList.length < 2 && _isChange) { ToastUtil.showNormal(context, '请上传2张身份证照片'); return; } @@ -547,33 +547,81 @@ class _FullUserinfoPageState extends State { onTap: () {}, ), const Divider(), - if (_isEdit || _idCardImgList.isNotEmpty) + if (!_isEdit&&_idCardImgList.isNotEmpty)//_isEdit||_idCardImgList.isNotEmpty RepairedPhotoSection( title: '身份证照片', - isRequired: _isEdit, + isRequired: false, maxCount: 2, initialMediaPaths: _idCardImgList .map( (item) => ApiService.baseImgPath + item, ) .toList(), - isEdit: _isEdit, - horizontalPadding: _isEdit ? 12 : 0, + isEdit: false, + horizontalPadding: false ? 12 : 0, inlineImageWidth: 60, onChanged: (files) { - idPhotos = files.map((file) => file.path).toList(); + // idPhotos = files.map((file) => file.path).toList(); }, onMediaRemovedForIndex: (index) async { - final deleFile = _idCardImgList[index]; - final deleId = _idCartImgIds[index]; - if (deleFile.contains(UploadFileType.idCardPhoto.path)) { - _idCardImgList.removeAt(index); - _idCartImgIds.removeAt(index); - _idCardImgRemoveList.add(deleId); - } + // final deleFile = _idCardImgList[index]; + // final deleId = _idCartImgIds[index]; + // if (deleFile.contains(UploadFileType.idCardPhoto.path)) { + // _idCardImgList.removeAt(index); + // _idCartImgIds.removeAt(index); + // _idCardImgRemoveList.add(deleId); + // } }, onAiIdentify: () {}, ), + + if (_isEdit ) + RepairedPhotoSection( + title: '身份证照片', + isRequired: true, + maxCount: 2, + followInitialUpdates:true, + initialMediaPaths: _idCardImgList + .map( + (item) => ApiService.baseImgPath + item, + ) + .toList(), + isEdit: true, + horizontalPadding: true ? 12 : 0, + inlineImageWidth: 60, + onChanged: (files) { + // idPhotos = files.map((file) => file.path).toList(); + }, + onMediaAdded: (value) { + setState(() { + idPhotos.add(value); + _idCardImgList.add(value); + }); + }, + onMediaRemovedForIndex: (index) async { + final deleFile = _idCardImgList[index]; + try{ + final deleId = _idCartImgIds[index]; + if (deleFile.contains(UploadFileType.idCardPhoto.path)) { + setState(() { + _idCardImgList.removeAt(index); + _idCartImgIds.removeAt(index); + _idCardImgRemoveList.add(deleId); + }); + } + }catch(e){ + setState(() { + _idCardImgList.removeAt(index); + // 删除匹配的文件路径 + idPhotos.removeWhere((path) => path == deleFile); + }); + debugPrint('$e'); + } + + }, + onAiIdentify: () {}, + ), + if (_isEdit) ItemListWidget.itemContainer( const Text( From c7b315e5b1b53b916658ef86db712a96f7190479 Mon Sep 17 00:00:00 2001 From: xufei <727302827@qq.com> Date: Mon, 8 Jun 2026 11:21:08 +0800 Subject: [PATCH 5/5] =?UTF-8?q?=E6=88=91=E7=9A=84=E9=A1=B5=E9=9D=A2?= =?UTF-8?q?=E5=90=8D=E5=AD=97=E4=B8=8D=E8=BF=94=E6=98=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/pages/mine/mine_page.dart | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/lib/pages/mine/mine_page.dart b/lib/pages/mine/mine_page.dart index 0175d20..2580f75 100644 --- a/lib/pages/mine/mine_page.dart +++ b/lib/pages/mine/mine_page.dart @@ -195,10 +195,7 @@ class MinePageState extends State { // 获取用户信息 Future _getUserInfo() async { - setState(() { - name = SessionService.instance.userData?.name ?? "登录/注册"; - phone = SessionService.instance.userData?.phone ?? ""; - }); + // final accountId = // SessionService.instance.accountId ?? // SessionService.instance.userData?.id ?? @@ -214,6 +211,24 @@ class MinePageState extends State { // phone = SessionService.instance.userData?.phone ?? ""; // }); // } + + final res = await BasicInfoApi.getUserMessage( + '${SessionService.instance.accountId}', + ); + if (res['success']) { + final data = res['data']; + + setState(() { + name = data['name'] ?? "登录/注册"; + phone = data['username'] ?? ""; + }); + }else{ + setState(() { + name = SessionService.instance.userData?.name ?? "登录/注册"; + phone = SessionService.instance.userData?.phone ?? ""; + }); + } + } Future _logout() async { @@ -354,6 +369,7 @@ class MinePageState extends State { FullUserinfoPage(isEidt: false, isChooseFirm: true), context, ); + _getUserInfo(); break; case 'changePwd': await pushPage(MineSetPwdPage('0'), context); @@ -364,7 +380,9 @@ class MinePageState extends State { context, ); if (result == null) return; - pushPage(OnboardingFullPage(scanData: result), context); + await pushPage(OnboardingFullPage(scanData: result), context); + + _getUserInfo(); break; case 'face': pushPage( @@ -395,6 +413,7 @@ class MinePageState extends State { _logout(); break; default: + break; } }