From 9348f657e56d0b5b744c4db1bdaab1596038a31d Mon Sep 17 00:00:00 2001
From: hs <873121290@qq.com>
Date: Mon, 28 Jul 2025 16:50:40 +0800
Subject: [PATCH] =?UTF-8?q?=E8=AE=BE=E7=BD=AE=E5=AE=89=E5=85=A8=E6=8E=AA?=
=?UTF-8?q?=E6=96=BD=E7=A1=AE=E8=AE=A4=E4=BA=BA=EF=BC=8C=E5=A4=9A=E7=BA=A7?=
=?UTF-8?q?=E5=88=86=E7=B1=BB=E5=8F=98=E7=A7=8D?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
ios/Runner/Info.plist | 16 +-
.../department_picker_hidden_type.dart | 231 +++--
.../picker/CupertinoDatePicker.dart | 2 +-
lib/customWidget/single_image_viewer.dart | 6 +-
lib/http/ApiService.dart | 20 +-
.../app/Danger_paicha/quick_report_page.dart | 9 +-
lib/pages/app/hidden_record_detail_page.dart | 4 +-
.../pending_rectification_detail_page.dart | 2 +-
.../dh_work_detai/hotwork_apply_detail.dart | 2 +-
.../dh_work_detai/hotwork_gas_list.dart | 188 ----
.../special_wrok/home_gas_test_page.dart | 21 +-
.../gasWork_apply_detail.dart | 2 +-
.../qtfx_work_detail/hotwork_gas_list.dart | 22 +-
.../special_wrok/special_work_list_page.dart | 5 +-
.../hotwork_set_safe_detail.dart | 809 ++++++++++++++++++
.../work/dangerTypeItems/danger_detail.dart | 2 +-
.../finish/danger_acceptance_finish.dart | 2 +-
.../finish/danner_repair_finish.dart | 2 +-
lib/tools/tools.dart | 21 +-
pubspec.lock | 292 ++++---
20 files changed, 1179 insertions(+), 479 deletions(-)
delete mode 100644 lib/pages/home/tap/tabList/special_wrok/dh_work_detai/hotwork_gas_list.dart
create mode 100644 lib/pages/home/tap/tabList/special_wrok/szaq_work_detail/hotwork_set_safe_detail.dart
diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist
index 5326047..1c9b601 100644
--- a/ios/Runner/Info.plist
+++ b/ios/Runner/Info.plist
@@ -24,6 +24,8 @@
$(FLUTTER_BUILD_NUMBER)
LSRequiresIPhoneOS
+ NFCReaderUsageDescription
+ 用于读取 NFC 标签
NSAppTransportSecurity
NSAllowsArbitraryLoads
@@ -31,8 +33,6 @@
NSBluetoothAlwaysUsageDescription
app需要蓝牙权限连接设备
- NFCReaderUsageDescription
- 用于读取 NFC 标签
NSCameraUsageDescription
app需要相机权限来扫描二维码
NSContactsUsageDescription
@@ -45,8 +45,10 @@
app需要发现本地网络设备
NSLocationAlwaysAndWhenInUseUsageDescription
app需要后台定位以实现持续跟踪
+ NSLocationAlwaysUsageDescription
+ 需要位置权限以提供定位服务
NSLocationWhenInUseUsageDescription
- app需要定位权限来提供附近服务
+ 需要位置权限以提供定位服务
NSMicrophoneUsageDescription
app需要麦克风权限进行语音通话
NSMotionUsageDescription
@@ -57,10 +59,6 @@
app需要访问相册以上传图片
NSUserNotificationsUsageDescription
app需要发送通知提醒重要信息
- NSLocationWhenInUseUsageDescription
- 需要位置权限以提供定位服务
- NSLocationAlwaysUsageDescription
- 需要位置权限以提供定位服务
UIApplicationSupportsIndirectInputEvents
UILaunchStoryboardName
@@ -70,15 +68,11 @@
UISupportedInterfaceOrientations
UIInterfaceOrientationPortrait
- UIInterfaceOrientationLandscapeLeft
- UIInterfaceOrientationLandscapeRight
UISupportedInterfaceOrientations~ipad
UIInterfaceOrientationPortrait
UIInterfaceOrientationPortraitUpsideDown
- UIInterfaceOrientationLandscapeLeft
- UIInterfaceOrientationLandscapeRight
diff --git a/lib/customWidget/department_picker_hidden_type.dart b/lib/customWidget/department_picker_hidden_type.dart
index 2b82562..773a1bb 100644
--- a/lib/customWidget/department_picker_hidden_type.dart
+++ b/lib/customWidget/department_picker_hidden_type.dart
@@ -10,54 +10,48 @@ class Category {
final String name;
final List children;
- Category({
- required this.id,
- required this.name,
- this.children = const [],
- });
+ Category({required this.id, required this.name, this.children = const []});
factory Category.fromJson(Map json) {
return Category(
id: json['id'] as String,
name: json['name'] as String,
- children: (json['nodes'] as List)
- .map((e) => Category.fromJson(e as Map))
- .toList(),
+ children:
+ (json['nodes'] as List)
+ .map((e) => Category.fromJson(e as Map))
+ .toList(),
);
}
}
-/// 弹窗回调签名:返回选中项的 id 和 name
-typedef DeptSelectHiddenTypeCallback = void Function(String id, String name);
+/// 弹窗回调签名:返回完整的多级路径 JSON 对象
+typedef DeptSelectHiddenTypeCallback =
+ void Function(Map> result);
class DepartmentPickerHiddenType extends StatefulWidget {
- /// 回调,返回选中部门 id 与 name
final DeptSelectHiddenTypeCallback onSelected;
- const DepartmentPickerHiddenType({Key? key, required this.onSelected}) : super(key: key);
+ const DepartmentPickerHiddenType({Key? key, required this.onSelected})
+ : super(key: key);
@override
- _DepartmentPickerHiddenTypeState createState() => _DepartmentPickerHiddenTypeState();
+ _DepartmentPickerHiddenTypeState createState() =>
+ _DepartmentPickerHiddenTypeState();
}
-class _DepartmentPickerHiddenTypeState extends State {
+class _DepartmentPickerHiddenTypeState
+ extends State {
String selectedId = '';
- String selectedName = '';
Set expandedSet = {};
-
List original = [];
List filtered = [];
bool loading = true;
-
final TextEditingController _searchController = TextEditingController();
+ final Map parentMap = {};
@override
void initState() {
super.initState();
- // 初始均为空
- selectedId = '';
- selectedName = '';
- expandedSet = {};
_searchController.addListener(_onSearchChanged);
_loadData();
}
@@ -72,102 +66,146 @@ class _DepartmentPickerHiddenTypeState extends State
Future _loadData() async {
try {
List raw;
- if (SessionService.instance.departmentHiddenTypeJsonStr?.isNotEmpty ?? false) {
- raw = json.decode(SessionService.instance.departmentHiddenTypeJsonStr!) as List;
+ // 从 SessionService 读取或通过 API 拉取
+ if (SessionService.instance.departmentHiddenTypeJsonStr?.isNotEmpty ??
+ false) {
+ raw =
+ json.decode(SessionService.instance.departmentHiddenTypeJsonStr!)
+ as List;
} else {
- final resultLevel = await ApiService. getHiddenLevelsListTwo();
+ // ... 同前逻辑,获取 parentId 并调用 API
+ final resultLevel = await ApiService.getHiddenLevelsListTwo();
List levelList = resultLevel['list'] as List;
- String parentId="";
- for(int i=0;i;
+ raw = json.decode(nodes) as List;
}
+
+ // 构建 Category 列表并生成 parentMap
+ final list =
+ raw.map((e) => Category.fromJson(e as Map)).toList();
+ _buildParentMap(list);
+
setState(() {
- original = raw.map((e) => Category.fromJson(e as Map)).toList();
- filtered = original;
+ original = list;
+ filtered = list;
loading = false;
});
- } catch (e) {
+ } catch (_) {
setState(() => loading = false);
}
}
+ void _buildParentMap(List list, [Category? parent]) {
+ for (var cat in list) {
+ parentMap[cat.id] = parent;
+ if (cat.children.isNotEmpty) {
+ _buildParentMap(cat.children, cat);
+ }
+ }
+ }
+
void _onSearchChanged() {
- final query = _searchController.text.toLowerCase().trim();
+ final q = _searchController.text.toLowerCase().trim();
setState(() {
- filtered = query.isEmpty ? original : _filterCategories(original, query);
+ filtered = q.isEmpty ? original : _filterCategories(original, q);
});
}
- List _filterCategories(List list, String query) {
- List result = [];
+ List _filterCategories(List list, String q) {
+ final res = [];
for (var cat in list) {
- final children = _filterCategories(cat.children, query);
- if (cat.name.toLowerCase().contains(query) || children.isNotEmpty) {
- result.add(Category(id: cat.id, name: cat.name, children: children));
+ final children = _filterCategories(cat.children, q);
+ if (cat.name.toLowerCase().contains(q) || children.isNotEmpty) {
+ res.add(Category(id: cat.id, name: cat.name, children: children));
}
}
- return result;
+ return res;
+ }
+
+ Category? _findById(String id) {
+ Category? found;
+ void dfs(List list) {
+ for (var c in list) {
+ if (c.id == id) {
+ found = c;
+ return;
+ }
+ dfs(c.children);
+ if (found != null) return;
+ }
+ }
+
+ dfs(original);
+ return found;
+ }
+
+ /// 构建从根到选中节点的路径列表
+ List _buildPath(String id) {
+ final path = [];
+ var cur = _findById(id);
+ while (cur != null) {
+ path.insert(0, cur);
+ cur = parentMap[cur.id];
+ }
+ return path;
}
Widget _buildRow(Category cat, int indent) {
final hasChildren = cat.children.isNotEmpty;
- final isExpanded = expandedSet.contains(cat.id);
- final isSelected = cat.id == selectedId;
+ final expanded = expandedSet.contains(cat.id);
+ final selected = cat.id == selectedId;
return Column(
children: [
InkWell(
onTap: () {
setState(() {
if (hasChildren) {
- isExpanded ? expandedSet.remove(cat.id) : expandedSet.add(cat.id);
+ expanded ? expandedSet.remove(cat.id) : expandedSet.add(cat.id);
}
selectedId = cat.id;
- selectedName = cat.name;
});
},
child: Container(
color: Colors.white,
+ padding: const EdgeInsets.symmetric(vertical: 12),
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.green,
- ),
+ if (hasChildren)
+ Icon(
+ expanded
+ ? Icons.arrow_drop_down_rounded
+ : Icons.arrow_right_rounded,
+ size: 24,
+ color: Colors.grey[600],
+ )
+ else
+ const SizedBox(width: 24),
+ const SizedBox(width: 8),
+ Expanded(child: Text(cat.name)),
+ Icon(
+ selected
+ ? Icons.radio_button_checked
+ : Icons.radio_button_unchecked,
+ color: Colors.green,
),
+ const SizedBox(width: 16),
],
),
),
),
- if (hasChildren && isExpanded)
+ if (hasChildren && expanded)
...cat.children.map((c) => _buildRow(c, indent + 1)),
],
);
@@ -176,52 +214,55 @@ class _DepartmentPickerHiddenTypeState extends State
@override
Widget build(BuildContext context) {
return Container(
- width: MediaQuery.of(context).size.width,
+ width: double.infinity,
height: MediaQuery.of(context).size.height * 0.7,
color: Colors.white,
child: Column(
children: [
- Container(
- color: Colors.white,
+ // 顶部操作栏
+ Padding(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
child: Row(
children: [
GestureDetector(
onTap: () => Navigator.of(context).pop(),
- child: const Text('取消', style: TextStyle(fontSize: 16)),
+ child: const Text('取消'),
),
+ const SizedBox(width: 16),
Expanded(
- child: Padding(
- padding: const EdgeInsets.symmetric(horizontal: 12),
- child: SearchBarWidget(
- controller: _searchController,
- isShowSearchButton: false,
- onSearch: (keyboard) {
- },
- ),
+ child: SearchBarWidget(
+ controller: _searchController,
+ isShowSearchButton: false,
+ onSearch: (_) {},
),
),
+ const SizedBox(width: 16),
GestureDetector(
onTap: () {
+ final pathCats = _buildPath(selectedId);
+ final ids = pathCats.map((e) => e.id).toList();
+ final names = pathCats.map((e) => e.name).toList();
+ widget.onSelected({'id': ids, 'name': names});
Navigator.of(context).pop();
- widget.onSelected(selectedId, selectedName);
},
- child: const Text('确定', style: TextStyle(fontSize: 16, color: Colors.green)),
+ child: const Text(
+ '确定',
+ style: TextStyle(color: Colors.green),
+ ),
),
],
),
),
- Divider(),
+ const Divider(height: 1),
+ // 列表区
Expanded(
- child: loading
- ? const Center(child: CircularProgressIndicator())
- : Container(
- color: Colors.white,
- child: ListView.builder(
- itemCount: filtered.length,
- itemBuilder: (ctx, idx) => _buildRow(filtered[idx], 0),
- ),
- ),
+ child:
+ loading
+ ? const Center(child: CircularProgressIndicator())
+ : ListView.builder(
+ itemCount: filtered.length,
+ itemBuilder: (_, idx) => _buildRow(filtered[idx], 0),
+ ),
),
],
),
diff --git a/lib/customWidget/picker/CupertinoDatePicker.dart b/lib/customWidget/picker/CupertinoDatePicker.dart
index c7ce1dc..53e7dad 100644
--- a/lib/customWidget/picker/CupertinoDatePicker.dart
+++ b/lib/customWidget/picker/CupertinoDatePicker.dart
@@ -8,7 +8,7 @@ import 'package:flutter/material.dart';
/// print('用户选择的时间:$picked');
/// }
class BottomDateTimePicker {
- static Future show(BuildContext context) {
+ static Future showDate(BuildContext context) {
return showModalBottomSheet(
context: context,
backgroundColor: Colors.white,
diff --git a/lib/customWidget/single_image_viewer.dart b/lib/customWidget/single_image_viewer.dart
index d123767..649840c 100644
--- a/lib/customWidget/single_image_viewer.dart
+++ b/lib/customWidget/single_image_viewer.dart
@@ -9,7 +9,7 @@ class SingleImageViewer extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
- backgroundColor: Colors.black.withValues(alpha: 0.7),
+ backgroundColor: Colors.black.withValues(alpha: 0.5),
appBar: MyAppbar(
isBack: false,
actions: [
@@ -17,12 +17,12 @@ class SingleImageViewer extends StatelessWidget {
Navigator.of(context).pop();
}, icon: Icon(Icons.close, color: Colors.white, size: 40,),)
],
- backgroundColor: Colors.black.withValues(alpha:0.7), title: '',
+ backgroundColor: Colors.black.withValues(alpha:0.5), title: '',
),
body: Center(
child: PhotoView(
imageProvider: NetworkImage(imageUrl),
- backgroundDecoration: BoxDecoration(color: Colors.black.withValues(alpha:00.5)),
+ backgroundDecoration: BoxDecoration(color: Colors.black.withValues(alpha:0.5)),
minScale: PhotoViewComputedScale.contained,
maxScale: PhotoViewComputedScale.covered * 2,
onTapUp: (context, details, controllerValue) {
diff --git a/lib/http/ApiService.dart b/lib/http/ApiService.dart
index 1b8d4b3..6e4930a 100644
--- a/lib/http/ApiService.dart
+++ b/lib/http/ApiService.dart
@@ -657,14 +657,13 @@ U6Hzm1ninpWeE+awIDAQAB
);
}
/// 气体分析详情列表删除
- static Future