2026.5.19 相关方隐患
parent
2b10658adf
commit
f5ec99a72e
Binary file not shown.
|
After Width: | Height: | Size: 235 B |
|
|
@ -0,0 +1,296 @@
|
||||||
|
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/services/SessionService.dart';
|
||||||
|
import '../tools/tools.dart'; // 包含 SessionService
|
||||||
|
|
||||||
|
// 数据模型
|
||||||
|
class Category {
|
||||||
|
final String id;
|
||||||
|
final String name;
|
||||||
|
final Map<String, dynamic> extValues;
|
||||||
|
final String departmentId;
|
||||||
|
final String parentId;
|
||||||
|
final String corpinfoId; // 新增:和 departmentId 同层级
|
||||||
|
final List<Category> childrenList;
|
||||||
|
|
||||||
|
Category({
|
||||||
|
required this.id,
|
||||||
|
required this.name,
|
||||||
|
required this.childrenList,
|
||||||
|
required this.extValues,
|
||||||
|
required this.departmentId,
|
||||||
|
required this.parentId,
|
||||||
|
required this.corpinfoId,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory Category.fromJson(Map<String, dynamic> json) {
|
||||||
|
// 安全读取并兼容字符串或数字类型的 id
|
||||||
|
String parseString(dynamic v) {
|
||||||
|
if (v == null) return '';
|
||||||
|
if (v is String) return v;
|
||||||
|
return v.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
final rawChildren = json['childrenList'];
|
||||||
|
List<Category> children = [];
|
||||||
|
if (rawChildren is List) {
|
||||||
|
try {
|
||||||
|
children = rawChildren
|
||||||
|
.where((e) => e != null)
|
||||||
|
.map((e) => Category.fromJson(Map<String, dynamic>.from(e as Map)))
|
||||||
|
.toList();
|
||||||
|
} catch (e) {
|
||||||
|
// 如果内部解析出错,保持 children 为空并继续
|
||||||
|
children = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// extValues 有可能为 null 或不是 Map
|
||||||
|
final extRaw = json['extValues'];
|
||||||
|
Map<String, dynamic> extMap = {};
|
||||||
|
if (extRaw is Map) {
|
||||||
|
extMap = Map<String, dynamic>.from(extRaw);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Category(
|
||||||
|
id: parseString(json['id']),
|
||||||
|
name: parseString(json['name']),
|
||||||
|
childrenList: children,
|
||||||
|
extValues: extMap,
|
||||||
|
departmentId: parseString(json['departmentId']),
|
||||||
|
parentId: parseString(json['parentId']),
|
||||||
|
corpinfoId: parseString(json['corpinfoId']), // 从 JSON 同层级读取
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 弹窗回调签名:返回选中项的 id 和 name (保持原样,兼容旧代码)
|
||||||
|
typedef DeptSelectCallback = void Function(String id, String name);
|
||||||
|
|
||||||
|
class DepartmentPickerHidden extends StatefulWidget {
|
||||||
|
/// 原回调,返回选中部门 id 与 name(保持不变)
|
||||||
|
final DeptSelectCallback onSelected;
|
||||||
|
|
||||||
|
/// 新增可选扩展回调:当需要 corpinfoId 时使用(不影响原有调用)
|
||||||
|
final void Function(String id, String name, String? corpinfoId)? onSelectedWithCorp;
|
||||||
|
|
||||||
|
/// 是否包含所有公司
|
||||||
|
final bool includeAllFirm;
|
||||||
|
final Map? data;
|
||||||
|
|
||||||
|
const DepartmentPickerHidden({
|
||||||
|
Key? key,
|
||||||
|
required this.onSelected,
|
||||||
|
this.onSelectedWithCorp,
|
||||||
|
this.includeAllFirm = false,
|
||||||
|
this.data,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
_DepartmentPickerHiddenState createState() => _DepartmentPickerHiddenState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _DepartmentPickerHiddenState extends State<DepartmentPickerHidden> {
|
||||||
|
String selectedId = '';
|
||||||
|
String selectedName = '';
|
||||||
|
String? selectedCorpinfoId; // 记录选中项的 corpinfoId(可为 null)
|
||||||
|
Set<String> expandedSet = {};
|
||||||
|
|
||||||
|
List<Category> original = [];
|
||||||
|
List<Category> filtered = [];
|
||||||
|
bool loading = true;
|
||||||
|
|
||||||
|
final TextEditingController _searchController = TextEditingController();
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
// 初始均为空
|
||||||
|
selectedId = '';
|
||||||
|
selectedName = '';
|
||||||
|
selectedCorpinfoId = null;
|
||||||
|
expandedSet = {};
|
||||||
|
_searchController.addListener(_onSearchChanged);
|
||||||
|
_loadData();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_searchController.removeListener(_onSearchChanged);
|
||||||
|
_searchController.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _loadData() async {
|
||||||
|
try {
|
||||||
|
final result = await BasicInfoApi.getDeptFour(widget.includeAllFirm, data: widget.data);
|
||||||
|
final raw = result['data'] as List<dynamic>;
|
||||||
|
print(raw);
|
||||||
|
setState(() {
|
||||||
|
original = raw.map((e) => Category.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<Category> _filterCategories(List<Category> list, String query) {
|
||||||
|
List<Category> result = [];
|
||||||
|
for (var cat in list) {
|
||||||
|
final children = _filterCategories(cat.childrenList, query);
|
||||||
|
if (cat.name.toLowerCase().contains(query) || children.isNotEmpty) {
|
||||||
|
result.add(
|
||||||
|
Category(
|
||||||
|
id: cat.id,
|
||||||
|
name: cat.name,
|
||||||
|
childrenList: children,
|
||||||
|
extValues: cat.extValues,
|
||||||
|
departmentId: cat.departmentId,
|
||||||
|
parentId: cat.parentId,
|
||||||
|
corpinfoId: cat.corpinfoId, // 保持 corpinfoId 传递
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildRow(Category cat, int indent) {
|
||||||
|
final hasChildren = cat.childrenList.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);
|
||||||
|
}
|
||||||
|
selectedId = cat.id;
|
||||||
|
selectedName = cat.name;
|
||||||
|
selectedCorpinfoId = cat.corpinfoId.isEmpty ? null : cat.corpinfoId;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
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.childrenList.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: () {
|
||||||
|
// 关闭弹窗并回调:优先调用扩展回调(带 corpinfoId),否则调用原回调
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
if (widget.onSelectedWithCorp != null) {
|
||||||
|
widget.onSelectedWithCorp!(
|
||||||
|
selectedId,
|
||||||
|
selectedName,
|
||||||
|
selectedCorpinfoId,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
widget.onSelected(selectedId, selectedName);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
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),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -153,6 +153,26 @@ class BasicInfoApi {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 部门树状图
|
||||||
|
static Future<Map<String, dynamic>> getDeptFour(bool includeAllFirm, {Map? data}) async {
|
||||||
|
// var urlPath = includeAllFirm ? '/basicInfo/department/listAllTree' : '/basicInfo/department/listTree';
|
||||||
|
var urlPath = '/basicInfo/department/listTree';
|
||||||
|
|
||||||
|
if (data != null) {
|
||||||
|
// inType 企业类型(0-普通企业,1-集团单位,2-股份单位,3-相关方企业,4-货主单位,5-驻港单位 6-物资中心)
|
||||||
|
// enterpriseType (企业类型1:监管 2:企业 3:相关方", name = "enterpriseType")
|
||||||
|
urlPath = '/basicInfo/department/listAllTreeByCorpType';
|
||||||
|
}
|
||||||
|
return HttpManager().request(
|
||||||
|
ApiService.basePath,
|
||||||
|
urlPath,
|
||||||
|
method: Method.post,
|
||||||
|
data: {
|
||||||
|
...?data,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/// 获取部门下所有用户
|
/// 获取部门下所有用户
|
||||||
static Future<Map<String, dynamic>> getDeptUsers(final departmentId, {int isMyCorp = 0, String corpinfoId = ''}) {
|
static Future<Map<String, dynamic>> getDeptUsers(final departmentId, {int isMyCorp = 0, String corpinfoId = ''}) {
|
||||||
final data = {
|
final data = {
|
||||||
|
|
|
||||||
|
|
@ -502,4 +502,25 @@ class HiddenDangerApi {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///=====================隐患治理==================
|
||||||
|
|
||||||
|
/// 获取过往记录详情
|
||||||
|
static Future<Map<String, dynamic>> getOldDangerDetail(String id) {
|
||||||
|
return HttpManager().request(
|
||||||
|
'${ApiService.basePath}/hidden',
|
||||||
|
'/hidden/history/$id',
|
||||||
|
method: Method.get,
|
||||||
|
data: {},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -139,4 +139,4 @@ class SpecialListInitData {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isKF = true;
|
bool isKF = false;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,680 @@
|
||||||
|
import 'dart:io';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:intl/intl.dart';
|
||||||
|
import 'package:qhd_prevention/customWidget/ItemWidgetFactory.dart';
|
||||||
|
import 'package:qhd_prevention/customWidget/custom_button.dart';
|
||||||
|
import 'package:qhd_prevention/customWidget/department_person_picker.dart';
|
||||||
|
import 'package:qhd_prevention/customWidget/department_picker.dart';
|
||||||
|
import 'package:qhd_prevention/customWidget/department_picker_hidden.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/picker/CupertinoDatePicker.dart';
|
||||||
|
import 'package:qhd_prevention/customWidget/toast_util.dart';
|
||||||
|
import 'package:qhd_prevention/http/ApiService.dart';
|
||||||
|
import 'package:qhd_prevention/services/SessionService.dart';
|
||||||
|
import 'package:qhd_prevention/tools/h_colors.dart';
|
||||||
|
import 'package:qhd_prevention/tools/tools.dart';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class DepartmentEntry {
|
||||||
|
String department;
|
||||||
|
String responsible;
|
||||||
|
|
||||||
|
String index;
|
||||||
|
String departmentId;
|
||||||
|
String responsibleId;
|
||||||
|
|
||||||
|
DepartmentEntry({
|
||||||
|
required this.department,
|
||||||
|
required this.responsible,
|
||||||
|
|
||||||
|
required this.index,
|
||||||
|
required this.departmentId,
|
||||||
|
required this.responsibleId,
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
// 将对象转换为 Map
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return {
|
||||||
|
'deptId': departmentId,
|
||||||
|
'userId': responsibleId,
|
||||||
|
'deptName': department,
|
||||||
|
'userName': responsible,
|
||||||
|
'type': index,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// 将对象转换为 Map
|
||||||
|
Map<String, dynamic> toJsonTwo() {
|
||||||
|
return {
|
||||||
|
'departmentId': departmentId,
|
||||||
|
'userId': responsibleId,
|
||||||
|
'departmentName': department,
|
||||||
|
'userName': responsible,
|
||||||
|
'listManagerId': index,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 隐患整改
|
||||||
|
class DannerRepair extends StatefulWidget {
|
||||||
|
DannerRepair(this.pd, {super.key});
|
||||||
|
|
||||||
|
final Map<String, dynamic> pd;
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<DannerRepair> createState() => DannerRepairState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class DannerRepairState extends State<DannerRepair> {
|
||||||
|
|
||||||
|
// 是否有整改方案
|
||||||
|
bool acceptedPrepare = false;
|
||||||
|
|
||||||
|
// 是否有整改计划
|
||||||
|
bool acceptedPlan = false;
|
||||||
|
|
||||||
|
final standardController = TextEditingController();
|
||||||
|
final methodController = TextEditingController();
|
||||||
|
final fundController = TextEditingController();
|
||||||
|
final personController = TextEditingController();
|
||||||
|
final workTimeController = TextEditingController();
|
||||||
|
final timeController = TextEditingController();
|
||||||
|
final workController = TextEditingController();
|
||||||
|
final otherController = TextEditingController();
|
||||||
|
final TextEditingController miaoShuController = TextEditingController();
|
||||||
|
final TextEditingController linShiSZhengGaiController = TextEditingController();
|
||||||
|
late var _selectData = DateTime.now();
|
||||||
|
|
||||||
|
|
||||||
|
String investmentFunds="";
|
||||||
|
String dataTime="";
|
||||||
|
// 整改后图片
|
||||||
|
List<String> gaiHouImages = [];
|
||||||
|
//方案图片
|
||||||
|
List<String> fangAnImages = [];
|
||||||
|
//计划图片
|
||||||
|
List<String> jiHuaImages = [];
|
||||||
|
int yanShouAdd=1;
|
||||||
|
|
||||||
|
// 是否是相关方
|
||||||
|
bool _isStakeholder = false;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
final List<DepartmentEntry> departments = [
|
||||||
|
DepartmentEntry(department: '请选择', responsible: '请选择',index:'300',departmentId: '',responsibleId:''),
|
||||||
|
];
|
||||||
|
|
||||||
|
void _addDepartment() {
|
||||||
|
setState(() {
|
||||||
|
departments.add(DepartmentEntry(department: '请选择', responsible: '请选择',index:'300',departmentId: '',responsibleId:''));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void _removeDepartment(int index) {
|
||||||
|
if (index == 0) return; // 防止删除第一行
|
||||||
|
setState(() {
|
||||||
|
departments.removeAt(index);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
// TODO: implement initState
|
||||||
|
super.initState();
|
||||||
|
// _yanShouFuZeItem.add(_departmentItem(0));
|
||||||
|
|
||||||
|
setState(() {
|
||||||
|
// _isStakeholder=true;
|
||||||
|
_isStakeholder= widget.pd['isRelated']==1?true:false;
|
||||||
|
if(_isStakeholder){
|
||||||
|
//部门
|
||||||
|
departments[0].departmentId=widget.pd['hiddenConfirmUserCO'][(widget.pd['hiddenConfirmUserCO'].length-1)]['deptId']??'';
|
||||||
|
departments[0].department=widget.pd['hiddenConfirmUserCO'][(widget.pd['hiddenConfirmUserCO'].length-1)]['deptName']??'';
|
||||||
|
//人员
|
||||||
|
departments[0].responsibleId=widget.pd['hiddenConfirmUserCO'][(widget.pd['hiddenConfirmUserCO'].length-1)]['userId']??'';
|
||||||
|
departments[0].responsible=widget.pd['hiddenConfirmUserCO'][(widget.pd['hiddenConfirmUserCO'].length-1)]['userName']??'';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
// 释放资源
|
||||||
|
standardController.dispose();
|
||||||
|
methodController.dispose();
|
||||||
|
fundController.dispose();
|
||||||
|
personController.dispose();
|
||||||
|
workTimeController.dispose();
|
||||||
|
timeController.dispose();
|
||||||
|
workController.dispose();
|
||||||
|
otherController.dispose();
|
||||||
|
miaoShuController.dispose();
|
||||||
|
linShiSZhengGaiController.dispose();
|
||||||
|
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Container(
|
||||||
|
padding: EdgeInsets.only(bottom: 10),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.circular(5),
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
// ListItemFactory.createBuildSimpleSection("隐患整改"),
|
||||||
|
// Divider(height: 1),
|
||||||
|
Container(
|
||||||
|
|
||||||
|
padding: EdgeInsets.all(15),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
ListItemFactory.createBuildMultilineInput(
|
||||||
|
isRequired:true,
|
||||||
|
"整改描述",
|
||||||
|
"请对整改进行详细描述(必填项)",
|
||||||
|
miaoShuController,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Divider(height: 1),
|
||||||
|
GestureDetector(
|
||||||
|
onTap: () async {
|
||||||
|
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||||
|
mode: BottomPickerMode.dateTimeWithSeconds,
|
||||||
|
context,
|
||||||
|
allowPast:false,
|
||||||
|
);
|
||||||
|
if (picked != null) {
|
||||||
|
setState(() {
|
||||||
|
_selectData = picked;
|
||||||
|
dataTime= DateFormat('yyyy-MM-dd HH:mm:ss').format(picked);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
child: Padding(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 15),
|
||||||
|
child: ListItemFactory.createRowSpaceBetweenItem(
|
||||||
|
isRequired:true,
|
||||||
|
leftText: "整改日期",
|
||||||
|
rightText: dataTime.isEmpty?"请选择":dataTime,
|
||||||
|
isRight: true,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
|
||||||
|
Container(
|
||||||
|
padding: EdgeInsets.all(15),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
ListItemFactory.createBuildMultilineInput(
|
||||||
|
isRequired:true,
|
||||||
|
"临时整改措施",
|
||||||
|
"请填写临时整改措施",
|
||||||
|
linShiSZhengGaiController,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
ItemListWidget.singleLineTitleText(
|
||||||
|
label: '投入资金(元)',
|
||||||
|
isEditable: true,
|
||||||
|
text: '',
|
||||||
|
onChanged: (value) {
|
||||||
|
investmentFunds=value;
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Divider(),
|
||||||
|
ItemListWidget.itemContainer(
|
||||||
|
RepairedPhotoSection(
|
||||||
|
isRequired:true,
|
||||||
|
title: "整改后照片",
|
||||||
|
maxCount: 4,
|
||||||
|
mediaType: MediaType.image,
|
||||||
|
onChanged: (files) {
|
||||||
|
// 上传 files 到服务器
|
||||||
|
gaiHouImages.clear();
|
||||||
|
for(int i=0;i<files.length;i++){
|
||||||
|
gaiHouImages.add(files[i].path);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onAiIdentify: () {
|
||||||
|
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Divider(),
|
||||||
|
if(!_isStakeholder)...[
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.only(left: 20,right: 10),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'验收人',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
CustomButton(
|
||||||
|
onPressed: () {
|
||||||
|
_addDepartment();
|
||||||
|
},
|
||||||
|
text: "添加",
|
||||||
|
backgroundColor: Colors.blue,
|
||||||
|
borderRadius: 17,
|
||||||
|
height: 34,
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 20),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
Column(
|
||||||
|
children: List.generate(
|
||||||
|
departments.length,
|
||||||
|
(index) => _departmentItem(
|
||||||
|
departments[index],
|
||||||
|
index,
|
||||||
|
showLabel: index == 0,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
|
||||||
|
if(_isStakeholder)...[
|
||||||
|
Column(
|
||||||
|
children: [
|
||||||
|
GestureDetector(
|
||||||
|
onTap: () {},
|
||||||
|
child: _buildSectionContainer(
|
||||||
|
child: ListItemFactory.createRowSpaceBetweenItem(
|
||||||
|
isRequired:true,
|
||||||
|
leftText: "验收部门",
|
||||||
|
rightText: departments[0].department.isNotEmpty ? departments[0].department : "",
|
||||||
|
isRight: false,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
Divider(),
|
||||||
|
|
||||||
|
GestureDetector(
|
||||||
|
onTap: () {},
|
||||||
|
child:Container(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 15),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.circular(5),
|
||||||
|
),
|
||||||
|
child: ListItemFactory.createRowSpaceBetweenItem(
|
||||||
|
isRequired:true,
|
||||||
|
leftText: "验收人",
|
||||||
|
rightText: departments[0].responsible.isNotEmpty?departments[0].responsible:"",
|
||||||
|
isRight: false,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
|
||||||
|
// for(int m=0;m<_yanShouFuZeItem.length;m++)
|
||||||
|
// _yanShouFuZeItem[m],
|
||||||
|
// _departmentItem(m),
|
||||||
|
// _departmentItem(2),
|
||||||
|
Divider(),
|
||||||
|
ListItemFactory.createYesNoSection(
|
||||||
|
title: "是否有整改方案",
|
||||||
|
yesLabel: "是",
|
||||||
|
noLabel: "否",
|
||||||
|
groupValue: acceptedPrepare,
|
||||||
|
onChanged: (val) {
|
||||||
|
setState(() {
|
||||||
|
acceptedPrepare = val;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
acceptedPrepare ? _acceptPrepare() : SizedBox(height: 1),
|
||||||
|
|
||||||
|
|
||||||
|
Divider(),
|
||||||
|
// 图片上传
|
||||||
|
// const SizedBox(height: 16),
|
||||||
|
if(acceptedPrepare)
|
||||||
|
RepairedPhotoSection(
|
||||||
|
horizontalPadding: 15,
|
||||||
|
isRequired:true,
|
||||||
|
title: "方案图片",
|
||||||
|
maxCount: 4,
|
||||||
|
mediaType: MediaType.image,
|
||||||
|
onChanged: (files) {
|
||||||
|
// 上传 files 到服务器
|
||||||
|
fangAnImages.clear();
|
||||||
|
for(int i=0;i<files.length;i++){
|
||||||
|
fangAnImages.add(files[i].path);
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
onAiIdentify: () {
|
||||||
|
|
||||||
|
},
|
||||||
|
),
|
||||||
|
|
||||||
|
// Divider(),
|
||||||
|
// ListItemFactory.createYesNoSection(
|
||||||
|
// title: "是否有整改计划",
|
||||||
|
// yesLabel: "是",
|
||||||
|
// noLabel: "否",
|
||||||
|
// groupValue: acceptedPlan,
|
||||||
|
// onChanged: (val) {
|
||||||
|
// setState(() {
|
||||||
|
// acceptedPlan = val;
|
||||||
|
// });
|
||||||
|
// },
|
||||||
|
// ),
|
||||||
|
// acceptedPlan ? _acceptPlan() : SizedBox(height: 1),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/// 整改方案
|
||||||
|
Widget _acceptPrepare() {
|
||||||
|
final fields = [
|
||||||
|
// _buildReadOnlyRow("排查日期", widget.pd["CREATTIME"]),
|
||||||
|
// if(FormUtils.hasValue(widget.pd, "LIST_NAME"))
|
||||||
|
// _buildReadOnlyRow("隐患清单", widget.pd["LIST_NAME"]),
|
||||||
|
ListItemFactory.createBuildMultilineInput("治理标准", "请输入治理标准", standardController,isRequired:true),
|
||||||
|
ListItemFactory.createBuildMultilineInput("治理方法", "请输入治理方法", methodController,isRequired:true),
|
||||||
|
ListItemFactory.createBuildMultilineInput("经费落实", "请输入经费落实", fundController,isRequired:true),
|
||||||
|
ListItemFactory.createBuildMultilineInput("负责人员", "请输入负责人员", personController,isRequired:true),
|
||||||
|
ListItemFactory.createBuildMultilineInput("工时安排", "请输入工时安排", workTimeController,isRequired:true),
|
||||||
|
ListItemFactory.createBuildMultilineInput("时限要求", "请输入时限要求", timeController,isRequired:true),
|
||||||
|
ListItemFactory.createBuildMultilineInput("工作要求", "请输入工作要求", workController,isRequired:true),
|
||||||
|
ListItemFactory.createBuildMultilineInput("其他事项", "请输入其他事项", otherController,isRequired:true),
|
||||||
|
];
|
||||||
|
|
||||||
|
return ListView.separated(
|
||||||
|
shrinkWrap: true,
|
||||||
|
physics: const NeverScrollableScrollPhysics(),
|
||||||
|
itemCount: fields.length,
|
||||||
|
separatorBuilder:
|
||||||
|
(_, __) => const Divider(height: 1, color: Colors.black12),
|
||||||
|
itemBuilder:
|
||||||
|
(_, index) => Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 8),
|
||||||
|
child: fields[index],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildSectionContainer({required Widget child}) {
|
||||||
|
return Container(
|
||||||
|
margin: const EdgeInsets.only(top: 1),
|
||||||
|
color: Colors.white,
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 0),
|
||||||
|
child: child,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildReadOnlyRow(String left, String right) {
|
||||||
|
return ListItemFactory.createRowSpaceBetweenItem(
|
||||||
|
leftText: left,
|
||||||
|
rightText: right,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// 验收部门和负责人选择的item
|
||||||
|
Widget _departmentItem(
|
||||||
|
DepartmentEntry entry,
|
||||||
|
int index, {
|
||||||
|
required bool showLabel,
|
||||||
|
}) {
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.all(10),
|
||||||
|
child: Stack(
|
||||||
|
clipBehavior: Clip.none,
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
border: Border.all(color: Colors.black12, width: 1),
|
||||||
|
),
|
||||||
|
child: _noAccepet_repair(false,index),
|
||||||
|
),
|
||||||
|
|
||||||
|
// 当 num > 1 时,左上角显示删除按钮
|
||||||
|
if (index > 0)
|
||||||
|
Positioned(
|
||||||
|
top: -20,
|
||||||
|
left: -20,
|
||||||
|
child: IconButton(
|
||||||
|
padding: EdgeInsets.zero,
|
||||||
|
constraints: const BoxConstraints(),
|
||||||
|
icon: const Icon(Icons.cancel, color: Colors.red, size: 25),
|
||||||
|
onPressed: () {
|
||||||
|
_removeDepartment(index);
|
||||||
|
// 这里处理删除逻辑,比如:
|
||||||
|
// setState(() => _items.removeAt(num));
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 存储各单位的人员列表
|
||||||
|
final Map<String, List<Map<String, dynamic>>> _personCache = {};
|
||||||
|
// #region 不整改
|
||||||
|
Widget _noAccepet_repair(bool _accept,int index, ) {
|
||||||
|
|
||||||
|
return Column(
|
||||||
|
children: [
|
||||||
|
GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
showModalBottomSheet(
|
||||||
|
context: context,
|
||||||
|
isScrollControlled: true,
|
||||||
|
barrierColor: Colors.black54,
|
||||||
|
backgroundColor: Colors.transparent,
|
||||||
|
builder: (ctx) => DepartmentPickerHidden(onSelected: (id, name) async {
|
||||||
|
|
||||||
|
setState(() {
|
||||||
|
// buMenId=id;
|
||||||
|
// buMenName=name;
|
||||||
|
//
|
||||||
|
// // 清空已选人员
|
||||||
|
// renYuanId="";
|
||||||
|
// renYuanName="";
|
||||||
|
departments[index].department=name;
|
||||||
|
departments[index].departmentId=id;
|
||||||
|
|
||||||
|
departments[index].responsible="";
|
||||||
|
departments[index].responsibleId="";
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
// // 拉取该单位的人员列表并缓存
|
||||||
|
// final result = await HiddenDangerApi.getListTreePersonList(id);
|
||||||
|
// _personCache=List<Map<String, dynamic>>.from(
|
||||||
|
// result['userList'] as List,
|
||||||
|
// );
|
||||||
|
// 拉该单位人员并缓存
|
||||||
|
await _getPersonListForUnitId(id);
|
||||||
|
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 10),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.circular(5),
|
||||||
|
),
|
||||||
|
child: ListItemFactory.createRowSpaceBetweenItem(
|
||||||
|
isRequired:true,
|
||||||
|
leftText: "验收部门",
|
||||||
|
rightText: departments[index].department.isNotEmpty?departments[index].department:"请选择",
|
||||||
|
isRight: true,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
Divider(
|
||||||
|
height: 10,
|
||||||
|
color: _accept ? h_backGroundColor() : Colors.transparent,
|
||||||
|
),
|
||||||
|
|
||||||
|
GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
if ( departments[index].departmentId.isEmpty) {
|
||||||
|
ToastUtil.showNormal(context, '请先选择部门');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final unitId = (departments[index].departmentId ?? '').toString();
|
||||||
|
choosePersonHandle(unitId,index);
|
||||||
|
// DepartmentPersonPicker.show(
|
||||||
|
// context,
|
||||||
|
// personsData: _personCache,
|
||||||
|
// onSelected: (userId, name) {
|
||||||
|
// setState(() {
|
||||||
|
// // renYuanId = userId;
|
||||||
|
// // renYuanName = name;
|
||||||
|
//
|
||||||
|
// departments[index].responsible=name;
|
||||||
|
// departments[index].responsibleId=userId;
|
||||||
|
// departments[index].index=(index-1).toString();
|
||||||
|
// });
|
||||||
|
//
|
||||||
|
// },
|
||||||
|
// );
|
||||||
|
},
|
||||||
|
child:Container(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 10),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.circular(5),
|
||||||
|
),
|
||||||
|
child: ListItemFactory.createRowSpaceBetweenItem(
|
||||||
|
isRequired:true,
|
||||||
|
leftText: "验收人",
|
||||||
|
rightText: departments[index].responsible.isNotEmpty?departments[index].responsible:"请选择",
|
||||||
|
isRight: true,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 整改计划
|
||||||
|
Widget _acceptPlan() {
|
||||||
|
return Padding(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 15),
|
||||||
|
child: MediaPickerRow(
|
||||||
|
maxCount: 4,
|
||||||
|
onChanged: (List<File> files) {
|
||||||
|
// images 列表更新
|
||||||
|
// 上传 files 到服务器
|
||||||
|
jiHuaImages.clear();
|
||||||
|
for(int i=0;i<files.length;i++){
|
||||||
|
jiHuaImages.add(files[i].path);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// 拉取某单位人员并缓存(兼容返回结构)
|
||||||
|
Future<void> _getPersonListForUnitId(String id) async {
|
||||||
|
if (id.isEmpty) return;
|
||||||
|
LoadingDialogHelper.show();
|
||||||
|
try {
|
||||||
|
final result = await BasicInfoApi.getDeptUsers(id);
|
||||||
|
LoadingDialogHelper.hide();
|
||||||
|
// 兼容 result['data'] / result['userList'] 等常见字段
|
||||||
|
dynamic raw = result['data'];
|
||||||
|
List<Map<String, dynamic>> list = [];
|
||||||
|
if (raw is List) {
|
||||||
|
list = raw.map<Map<String, dynamic>>((e) {
|
||||||
|
if (e is Map<String, dynamic>) return e;
|
||||||
|
if (e is Map) return Map<String, dynamic>.from(e);
|
||||||
|
return <String, dynamic>{};
|
||||||
|
}).toList();
|
||||||
|
} else {
|
||||||
|
list = [];
|
||||||
|
}
|
||||||
|
setState(() {
|
||||||
|
_personCache[id] = list;
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
LoadingDialogHelper.hide();
|
||||||
|
ToastUtil.showError(context, '获取人员失败:$e');
|
||||||
|
setState(() {
|
||||||
|
_personCache[id] = [];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 弹出人员选择
|
||||||
|
void choosePersonHandle(final unitId, int index) async {
|
||||||
|
|
||||||
|
List<Map<String, dynamic>> personList = _personCache[unitId] ?? [];
|
||||||
|
if (personList.isEmpty) {
|
||||||
|
// 先拉取一次
|
||||||
|
await _getPersonListForUnitId(unitId);
|
||||||
|
personList = _personCache[unitId] ?? [];
|
||||||
|
if (personList.isEmpty) {
|
||||||
|
ToastUtil.showNormal(context, '暂无可选人员,请选择其他单位');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 显示人员选择器(假设 DepartmentPersonPicker.show 接口存在)
|
||||||
|
DepartmentPersonPicker.show(
|
||||||
|
context,
|
||||||
|
personsData: personList,
|
||||||
|
onSelected: (userId, name) {
|
||||||
|
if(SessionService.instance.accountId==userId){
|
||||||
|
ToastUtil.showNormal(context, '整改人和验收人不能是一个人');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setState(() {
|
||||||
|
departments[index].responsible=name;
|
||||||
|
departments[index].responsibleId=userId;
|
||||||
|
departments[index].index=(index-1).toString();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
).then((_) {
|
||||||
|
//FocusHelper.clearFocus(context);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,752 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:intl/intl.dart';
|
||||||
|
import 'package:qhd_prevention/customWidget/custom_button.dart';
|
||||||
|
import 'package:qhd_prevention/customWidget/search_bar_widget.dart';
|
||||||
|
import 'package:qhd_prevention/customWidget/toast_util.dart';
|
||||||
|
import 'package:qhd_prevention/http/ApiService.dart';
|
||||||
|
import 'package:qhd_prevention/pages/home/hiddenDanger/hidden_record_detail_page.dart';
|
||||||
|
|
||||||
|
import 'package:qhd_prevention/pages/my_appbar.dart';
|
||||||
|
import 'package:qhd_prevention/tools/h_colors.dart';
|
||||||
|
import 'package:qhd_prevention/tools/tools.dart';
|
||||||
|
import 'dart:async';
|
||||||
|
|
||||||
|
enum DangerType {
|
||||||
|
detailsHiddenInvestigationRecord("排查隐患记录", "排查隐患记录-详情"),
|
||||||
|
ristRecord("隐患记录", "隐患记录详情"),
|
||||||
|
waitAcceptance("隐患验收", "隐患验收详情"),
|
||||||
|
acceptance("已验收隐患", "已验收隐患"),
|
||||||
|
acceptanced("已验收隐患", "已验收隐患-详情"),
|
||||||
|
hiddenIdentification("隐患确认", "隐患确认详情"),
|
||||||
|
wait("隐患整改", "隐患整改详情"),
|
||||||
|
expired("特殊处置审核", "特殊处置审核详情"),
|
||||||
|
delayReview("延期审核", "延期审核详情"),
|
||||||
|
ignoreHiddenDangers("忽略隐患", "忽略隐患详情"),
|
||||||
|
// 安全环保检查
|
||||||
|
safeCheckHiddenAssign("隐患指派", "指派"),
|
||||||
|
safeCheckHiddenAccept("隐患验收", "验收");
|
||||||
|
// ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
final String displayName;
|
||||||
|
final String detailTitle;
|
||||||
|
|
||||||
|
const DangerType(this.displayName, this.detailTitle);
|
||||||
|
}
|
||||||
|
|
||||||
|
class HiddenDangerAcceptance extends StatefulWidget {
|
||||||
|
const HiddenDangerAcceptance(this.dangerType, this.appItem, {super.key});
|
||||||
|
|
||||||
|
final DangerType dangerType;
|
||||||
|
final int appItem;
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<HiddenDangerAcceptance> createState() => _HiddenDangerAcceptanceState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _HiddenDangerAcceptanceState extends State<HiddenDangerAcceptance> {
|
||||||
|
int _page = 1;
|
||||||
|
String searchKey = "";
|
||||||
|
int _totalPage = 1;
|
||||||
|
late List<dynamic> _list = [];
|
||||||
|
bool _isLoading = false;
|
||||||
|
bool _hasMore = true;
|
||||||
|
Timer? _debounceTimer;
|
||||||
|
String buttonTextOne = '查看';
|
||||||
|
String buttonTextTwo = '确认';
|
||||||
|
|
||||||
|
final TextEditingController _searchController = TextEditingController();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
// 初始均为空
|
||||||
|
|
||||||
|
_searchController.addListener(_onSearchChanged);
|
||||||
|
|
||||||
|
switch (widget.appItem) {
|
||||||
|
case 1:
|
||||||
|
buttonTextTwo = '确认';
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
buttonTextTwo = '查看';
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
buttonTextOne = '延期申请';
|
||||||
|
buttonTextTwo = '整改';
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
buttonTextTwo = '特殊处理审核';
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
buttonTextTwo = '延期审核';
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
buttonTextTwo = '验收';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
_getListData(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_debounceTimer?.cancel();
|
||||||
|
_searchController.removeListener(_onSearchChanged);
|
||||||
|
_searchController.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
// 取屏幕宽度
|
||||||
|
final double screenWidth = MediaQuery.of(context).size.width;
|
||||||
|
|
||||||
|
return Scaffold(
|
||||||
|
appBar: MyAppbar(title: widget.dangerType.displayName),
|
||||||
|
|
||||||
|
body: SafeArea(
|
||||||
|
child: NotificationListener<ScrollNotification>(
|
||||||
|
onNotification: _onScroll,
|
||||||
|
child: _vcDetailWidget(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
backgroundColor: Colors.white,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _vcDetailWidget() {
|
||||||
|
return Column(
|
||||||
|
children: [
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.all(10),
|
||||||
|
child: SearchBarWidget(
|
||||||
|
controller: _searchController,
|
||||||
|
isShowSearchButton: false,
|
||||||
|
hintText: '请输入隐患描述',
|
||||||
|
onTextChanged: (value) {
|
||||||
|
if (_debounceTimer?.isActive ?? false) {
|
||||||
|
_debounceTimer!.cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
_debounceTimer = Timer(const Duration(milliseconds: 500), () {
|
||||||
|
print('搜索关键词: ${_searchController.text}');
|
||||||
|
_performSearch(_searchController.text);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onSearch: (keyboard) {
|
||||||
|
// _performSearch(_searchController.text);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Container(height: 5, color: h_backGroundColor()),
|
||||||
|
Expanded(
|
||||||
|
child:
|
||||||
|
_list.isEmpty
|
||||||
|
? NoDataWidget.show()
|
||||||
|
: ListView.builder(
|
||||||
|
itemCount: _list.length,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
final item = _list[index];
|
||||||
|
return _fxitemCell(item);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _fxitemCell(pageData) {
|
||||||
|
// 使用GestureDetector包裹整个列表项以添加点击事件
|
||||||
|
return GestureDetector(
|
||||||
|
onTap: () {},
|
||||||
|
|
||||||
|
child: Container(
|
||||||
|
margin: EdgeInsets.all(6),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.circular(12),
|
||||||
|
boxShadow: [
|
||||||
|
BoxShadow(
|
||||||
|
color: Colors.grey.withOpacity(0.3),
|
||||||
|
spreadRadius: 2,
|
||||||
|
blurRadius: 5,
|
||||||
|
offset: Offset(0, 3),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
// 标题
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start, // 添加这一行
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: Padding(
|
||||||
|
padding: EdgeInsets.only(left: 10, top: 15, right: 8),
|
||||||
|
child: Text(
|
||||||
|
'隐患描述: ${pageData['hiddenDesc'] ?? ''}',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 18,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
color: Colors.black87,
|
||||||
|
),
|
||||||
|
maxLines: 1, // 只显示一行
|
||||||
|
overflow: TextOverflow.ellipsis, // 超出部分显示省略号
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
// 状态标签
|
||||||
|
Container(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 12, vertical: 6),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: _getLevelColor(pageData),
|
||||||
|
borderRadius: BorderRadius.only(
|
||||||
|
bottomLeft: Radius.circular(12),
|
||||||
|
topRight: Radius.circular(12), // 改为右上角
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
pageData['hiddenLevelName'] ?? '',
|
||||||
|
style: TextStyle(
|
||||||
|
color: Colors.white,
|
||||||
|
fontSize: 12,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
|
||||||
|
SizedBox(height: 16),
|
||||||
|
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.only(left: 10, right: 10),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
// 来源
|
||||||
|
Expanded(
|
||||||
|
child: Text(
|
||||||
|
_getSourceDangers(pageData),
|
||||||
|
style: TextStyle(fontSize: 14, color: Colors.black87),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
// 隐患状态
|
||||||
|
// Expanded(
|
||||||
|
// child: Text(
|
||||||
|
// '隐患状态: ${_getState(pageData)}',
|
||||||
|
// style: TextStyle(fontSize: 14, color: Colors.black87),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
SizedBox(height: 8),
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.only(left: 10, right: 10),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
// 来源
|
||||||
|
// Expanded(
|
||||||
|
// child: Text(
|
||||||
|
// _getSourceDangers(pageData),
|
||||||
|
// style: TextStyle(fontSize: 14, color: Colors.black87),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// 隐患状态
|
||||||
|
Expanded(
|
||||||
|
child: Text(
|
||||||
|
'隐患状态: ${_getState(pageData)}',
|
||||||
|
style: TextStyle(fontSize: 14, color: Colors.black87),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
SizedBox(height: 8),
|
||||||
|
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.only(left: 10, right: 10),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
// 隐患发现人 - 使用 Expanded 包裹
|
||||||
|
Expanded(
|
||||||
|
child: Text(
|
||||||
|
'发现人:${truncateString(pageData['createName'] ?? '')}',
|
||||||
|
style: TextStyle(fontSize: 14, color: Colors.black87),
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
// 隐患发现时间 - 使用 Expanded 包裹
|
||||||
|
Expanded(
|
||||||
|
child: Text(
|
||||||
|
'发现时间:${_changeTime(pageData['hiddenFindTime'] ?? '')}',
|
||||||
|
|
||||||
|
style: TextStyle(fontSize: 14, color: Colors.black87),
|
||||||
|
// maxLines: 1,
|
||||||
|
// overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
if (widget.appItem != 1) SizedBox(height: 8),
|
||||||
|
|
||||||
|
if (widget.appItem != 1)
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.only(left: 10, right: 10),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
// 隐患确认人
|
||||||
|
Expanded(
|
||||||
|
child: Text(
|
||||||
|
'确认人:${pageData['confirmUserName'] ?? ''}',
|
||||||
|
style: TextStyle(fontSize: 14, color: Colors.black87),
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
Expanded(
|
||||||
|
child: Text(
|
||||||
|
'确认时间:${_changeTime(pageData['hiddenFindTime'] ?? '')}',
|
||||||
|
|
||||||
|
style: TextStyle(fontSize: 14, color: Colors.black87),
|
||||||
|
// maxLines: 1,
|
||||||
|
// overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
if (widget.appItem == 6) SizedBox(height: 8),
|
||||||
|
|
||||||
|
if (widget.appItem == 6)
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.only(left: 10, right: 10),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
// 整改人
|
||||||
|
Expanded(
|
||||||
|
child: Text(
|
||||||
|
'整改人:${pageData['rectifyUserName'] ?? ''}',
|
||||||
|
style: TextStyle(fontSize: 14, color: Colors.black87),
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
Expanded(
|
||||||
|
child: Text(
|
||||||
|
'整改时间:${_changeTime(pageData['rectificationTime'] ?? '')}',
|
||||||
|
|
||||||
|
style: TextStyle(fontSize: 14, color: Colors.black87),
|
||||||
|
// maxLines: 1,
|
||||||
|
// overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
if (pageData['hiddenYUserName'] != null &&
|
||||||
|
pageData['hiddenYUserName'].isNotEmpty)
|
||||||
|
SizedBox(height: 8),
|
||||||
|
|
||||||
|
if (pageData['hiddenYUserName'] != null &&
|
||||||
|
pageData['hiddenYUserName'].isNotEmpty)
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.only(left: 10, right: 10),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
// 整改人
|
||||||
|
Text(
|
||||||
|
'验收人: ${pageData['hiddenYUserName'] ?? ''}',
|
||||||
|
style: TextStyle(fontSize: 14, color: Colors.black87),
|
||||||
|
),
|
||||||
|
|
||||||
|
// Text(
|
||||||
|
// '隐患验收时间: ${_changeTime(pageData['hiddenYTime']??'')}',
|
||||||
|
// style: TextStyle(
|
||||||
|
// fontSize: 14,
|
||||||
|
// color: Colors.black87,
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
SizedBox(height: 8),
|
||||||
|
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
// 验收按钮
|
||||||
|
if (widget.appItem != 2 && (widget.appItem != 3 || pageData['noReviewExtensionNum'] == 0))
|
||||||
|
Expanded(
|
||||||
|
child: CustomButton(
|
||||||
|
height: 35,
|
||||||
|
onPressed: () async {
|
||||||
|
// print('查看: ${pageData['title']}');
|
||||||
|
if (widget.appItem == 3) {
|
||||||
|
await pushPage(
|
||||||
|
HiddenRecordDetailPage(
|
||||||
|
widget.dangerType,
|
||||||
|
8,
|
||||||
|
pageData['id'],
|
||||||
|
pageData['hiddenId'],
|
||||||
|
true,
|
||||||
|
),
|
||||||
|
context,
|
||||||
|
);
|
||||||
|
_page=1;
|
||||||
|
_getListData(false);
|
||||||
|
} else {
|
||||||
|
pushPage(
|
||||||
|
HiddenRecordDetailPage(
|
||||||
|
widget.dangerType,
|
||||||
|
widget.appItem,
|
||||||
|
pageData['id'],
|
||||||
|
pageData['hiddenId'],
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
context,
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
backgroundColor: h_backGroundColor(),
|
||||||
|
textStyle: const TextStyle(color: Colors.black),
|
||||||
|
buttonStyle: ButtonStyleType.secondary,
|
||||||
|
text: buttonTextOne,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
// Expanded(
|
||||||
|
// child: Container(
|
||||||
|
// height: 35,
|
||||||
|
// margin: EdgeInsets.only(left: 10, right: 5), // 调整间距
|
||||||
|
// decoration: BoxDecoration(
|
||||||
|
// border: Border.all(color: Colors.blue, width: 1.0),
|
||||||
|
// borderRadius: BorderRadius.circular(8),
|
||||||
|
// ),
|
||||||
|
// child: ElevatedButton(
|
||||||
|
// onPressed: () {
|
||||||
|
// // print('查看: ${pageData['title']}');
|
||||||
|
// if (widget.appItem == 3) {
|
||||||
|
// pushPage(
|
||||||
|
// HiddenRecordDetailPage(
|
||||||
|
// widget.dangerType,
|
||||||
|
// 8,
|
||||||
|
// pageData['id'],
|
||||||
|
// pageData['hiddenId'],
|
||||||
|
// true,
|
||||||
|
// ),
|
||||||
|
// context,
|
||||||
|
// );
|
||||||
|
// } else {
|
||||||
|
// pushPage(
|
||||||
|
// HiddenRecordDetailPage(
|
||||||
|
// widget.dangerType,
|
||||||
|
// widget.appItem,
|
||||||
|
// pageData['id'],
|
||||||
|
// pageData['hiddenId'],
|
||||||
|
// false,
|
||||||
|
// ),
|
||||||
|
// context,
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
// style: ElevatedButton.styleFrom(
|
||||||
|
// backgroundColor: Colors.white,
|
||||||
|
// foregroundColor: Colors.blue,
|
||||||
|
// shape: RoundedRectangleBorder(
|
||||||
|
// borderRadius: BorderRadius.circular(8),
|
||||||
|
// ),
|
||||||
|
// elevation: 0,
|
||||||
|
// ),
|
||||||
|
// child: Text(buttonTextOne),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
SizedBox(width: 10), // 使用width而不是height
|
||||||
|
// 查看详情按钮
|
||||||
|
Expanded(
|
||||||
|
child: CustomButton(
|
||||||
|
height: 35,
|
||||||
|
onPressed: () async {
|
||||||
|
// print('查看详情: ${pageData['title']}');
|
||||||
|
String text = await pushPage(
|
||||||
|
HiddenRecordDetailPage(
|
||||||
|
widget.dangerType,
|
||||||
|
widget.appItem,
|
||||||
|
pageData['id'],
|
||||||
|
pageData['hiddenId'],
|
||||||
|
widget.appItem != 2,
|
||||||
|
),
|
||||||
|
context,
|
||||||
|
);
|
||||||
|
if (text == '1') {
|
||||||
|
_page = 1;
|
||||||
|
_getListData(false);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
backgroundColor: h_AppBarColor(),
|
||||||
|
textStyle: const TextStyle(color: Colors.white),
|
||||||
|
buttonStyle: ButtonStyleType.primary,
|
||||||
|
text: buttonTextTwo,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
// Expanded(
|
||||||
|
// child: Container(
|
||||||
|
// height: 35,
|
||||||
|
// margin: EdgeInsets.only(left: 5, right: 10),
|
||||||
|
// child: ElevatedButton(
|
||||||
|
// onPressed: () async {
|
||||||
|
// // print('查看详情: ${pageData['title']}');
|
||||||
|
// String text = await pushPage(
|
||||||
|
// HiddenRecordDetailPage(
|
||||||
|
// widget.dangerType,
|
||||||
|
// widget.appItem,
|
||||||
|
// pageData['id'],
|
||||||
|
// pageData['hiddenId'],
|
||||||
|
// widget.appItem != 2,
|
||||||
|
// ),
|
||||||
|
// context,
|
||||||
|
// );
|
||||||
|
// if (text == '1') {
|
||||||
|
// _page = 1;
|
||||||
|
// _getListData(false);
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
// style: ElevatedButton.styleFrom(
|
||||||
|
// backgroundColor: Colors.blue,
|
||||||
|
// foregroundColor: Colors.white,
|
||||||
|
// shape: RoundedRectangleBorder(
|
||||||
|
// borderRadius: BorderRadius.circular(8),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// child: Text(buttonTextTwo),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
|
||||||
|
SizedBox(height: 10),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _performSearch(String keyword) {
|
||||||
|
// 执行搜索逻辑
|
||||||
|
// if (keyword.isNotEmpty) {
|
||||||
|
// print('执行搜索: $keyword');
|
||||||
|
// 调用API或其他搜索操作
|
||||||
|
// 输入请求接口
|
||||||
|
_page = 1;
|
||||||
|
searchKey = keyword;
|
||||||
|
_getListData(false);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _onScroll(ScrollNotification n) {
|
||||||
|
if (n.metrics.pixels > n.metrics.maxScrollExtent - 100 &&
|
||||||
|
_hasMore &&
|
||||||
|
!_isLoading) {
|
||||||
|
_page++;
|
||||||
|
_getListData(true);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onSearchChanged() {
|
||||||
|
final query = _searchController.text.toLowerCase().trim();
|
||||||
|
setState(() {
|
||||||
|
print("=====>" + query);
|
||||||
|
// filtered = query.isEmpty ? original : _filterCategories(original, query);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Future<void> _getListData(bool loadMore) async {
|
||||||
|
try {
|
||||||
|
if (_isLoading) return;
|
||||||
|
_isLoading = true;
|
||||||
|
|
||||||
|
LoadingDialogHelper.show();
|
||||||
|
|
||||||
|
final Map<String, dynamic> result;
|
||||||
|
if (widget.appItem == 2) {
|
||||||
|
result = await HiddenDangerApi.getIgnoreList(_page, searchKey);
|
||||||
|
} else if (widget.appItem == 3) {
|
||||||
|
result = await HiddenDangerApi.getRectificationList(_page, searchKey);
|
||||||
|
} else if (widget.appItem == 4) {
|
||||||
|
result = await HiddenDangerApi.getSpecialHandlingList(
|
||||||
|
_page,
|
||||||
|
searchKey,
|
||||||
|
// isJGD ? '1' : '2',
|
||||||
|
);
|
||||||
|
} else if (widget.appItem == 5) {
|
||||||
|
result = await HiddenDangerApi.getDelayReviewList(
|
||||||
|
_page,
|
||||||
|
searchKey,
|
||||||
|
// isJGD ? '1' : '2',
|
||||||
|
);
|
||||||
|
} else if (widget.appItem == 6) {
|
||||||
|
result = await HiddenDangerApi.getHiddenDangerAcceptanceList(
|
||||||
|
_page,
|
||||||
|
searchKey,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
result = await HiddenDangerApi.getConfirmationList(_page, searchKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
LoadingDialogHelper.hide();
|
||||||
|
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 = _page < _totalPage;
|
||||||
|
// if (_hasMore) _page++;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
ToastUtil.showNormal(context, "加载数据失败");
|
||||||
|
// _showMessage('加载数据失败');
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
LoadingDialogHelper.hide();
|
||||||
|
// 出错时可以 Toast 或者在页面上显示错误状态
|
||||||
|
print('加载数据失败:$e');
|
||||||
|
} finally {
|
||||||
|
// if (!loadMore) LoadingDialogHelper.hide();
|
||||||
|
_isLoading = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String _getSourceDangers(final item) {
|
||||||
|
int type = item["source"] ?? 0;
|
||||||
|
if (1 == type) {
|
||||||
|
return "隐患来源:隐患快报";
|
||||||
|
} else if (2 == type) {
|
||||||
|
return "隐患来源:清单排查";
|
||||||
|
} else if (3 == type) {
|
||||||
|
return "隐患来源:标准排查";
|
||||||
|
} else if (4 == type) {
|
||||||
|
return "隐患来源:安全环保检查(监管端)";
|
||||||
|
} else if (5 == type) {
|
||||||
|
return "隐患来源:安全环保检查(企业端)";
|
||||||
|
} else if (6 == type) {
|
||||||
|
return "隐患来源:消防点检";
|
||||||
|
} else if (7 == type) {
|
||||||
|
return "隐患来源:视频巡屏";
|
||||||
|
} else {
|
||||||
|
return "隐患来源:";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 隐患等级颜色
|
||||||
|
Color _getLevelColor(final item) {
|
||||||
|
String type = item["hiddenLevelName"] ?? '';
|
||||||
|
if ("重大隐患" == type) {
|
||||||
|
return Colors.red;
|
||||||
|
} else if ("较大隐患" == type) {
|
||||||
|
return Color(0xFFFF6A4D);
|
||||||
|
} else if ("一般隐患" == type) {
|
||||||
|
return Colors.orange;
|
||||||
|
} else if ("轻微隐患" == type) {
|
||||||
|
return h_AppBarColor();
|
||||||
|
} else {
|
||||||
|
return Colors.green;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String _getState(final item) {
|
||||||
|
int type = item["state"];
|
||||||
|
if(100==type){
|
||||||
|
return "待确认";
|
||||||
|
}else if(200==type){
|
||||||
|
return "未整改";
|
||||||
|
}else if(201==type){
|
||||||
|
return "确认打回";
|
||||||
|
}else if(202==type){
|
||||||
|
return "待处理特殊隐患";
|
||||||
|
}else if(300==type){
|
||||||
|
return "待验收";
|
||||||
|
}else if(301==type){
|
||||||
|
return "已验收";
|
||||||
|
}else if(302==type){
|
||||||
|
return "验收打回";
|
||||||
|
}else if(303==type){
|
||||||
|
return "验收打回";
|
||||||
|
}else if(400==type){
|
||||||
|
return "已处理特殊隐患";
|
||||||
|
}else if(99==type){
|
||||||
|
return "强制关闭(人员变动)";
|
||||||
|
}else if(98==type){
|
||||||
|
return "安全环保检查/清单排查暂存";
|
||||||
|
}else if(102==type){
|
||||||
|
return "安全环保检查,隐患待指派";
|
||||||
|
}else if(97==type){
|
||||||
|
return "已过期";
|
||||||
|
}else if(101==type){
|
||||||
|
return "忽略隐患";
|
||||||
|
}else{
|
||||||
|
return "已过期";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String _changeTime(String time) {
|
||||||
|
try {
|
||||||
|
// 解析 ISO 8601 格式的时间字符串
|
||||||
|
DateTime dateTime = DateTime.parse(time);
|
||||||
|
// 格式化为年月日
|
||||||
|
return DateFormat('yyyy-MM-dd').format(dateTime);
|
||||||
|
} catch (e) {
|
||||||
|
// 如果解析失败,返回原字符串或默认值
|
||||||
|
return ' ';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String truncateString(String input) {
|
||||||
|
if (input.length > 10) {
|
||||||
|
return '${input.substring(0, 10)}...';
|
||||||
|
}
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,613 @@
|
||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:intl/intl.dart';
|
||||||
|
import 'package:qhd_prevention/customWidget/ItemWidgetFactory.dart';
|
||||||
|
import 'package:qhd_prevention/customWidget/MultiDictValuesPicker.dart';
|
||||||
|
import 'package:qhd_prevention/customWidget/bottom_picker_two.dart';
|
||||||
|
import 'package:qhd_prevention/customWidget/department_person_picker.dart';
|
||||||
|
import 'package:qhd_prevention/customWidget/department_picker.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/toast_util.dart';
|
||||||
|
import 'package:qhd_prevention/http/ApiService.dart';
|
||||||
|
|
||||||
|
import 'package:webview_flutter/webview_flutter.dart';
|
||||||
|
import '../../../customWidget/bottom_picker.dart';
|
||||||
|
import '../../../tools/h_colors.dart';
|
||||||
|
import '/customWidget/custom_button.dart';
|
||||||
|
import '../../../tools/tools.dart';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// 自定义抽屉
|
||||||
|
class HiddenDangerDeawer extends StatefulWidget {
|
||||||
|
const HiddenDangerDeawer(this.searchData, {super.key,required this.onClose});
|
||||||
|
|
||||||
|
final Function(Map<String, dynamic>) onClose; // 回调函数
|
||||||
|
final Map<String, dynamic> searchData;
|
||||||
|
// final DangerWaitBean waitBean;
|
||||||
|
|
||||||
|
@override
|
||||||
|
_HiddenDangerDeawerState createState() => _HiddenDangerDeawerState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _HiddenDangerDeawerState extends State<HiddenDangerDeawer> {
|
||||||
|
|
||||||
|
Map<String, dynamic> allData={};
|
||||||
|
|
||||||
|
DateTime? _startDate;
|
||||||
|
DateTime? _endDate;
|
||||||
|
|
||||||
|
// 存储各单位的人员列表
|
||||||
|
List<Map<String, dynamic>> _personCache = [];
|
||||||
|
|
||||||
|
|
||||||
|
// 转换为List<Map<String, dynamic>>
|
||||||
|
late List<Map<String, dynamic>> departmentList ;
|
||||||
|
late List<dynamic> _HazardPersonlist = [];
|
||||||
|
dynamic _hazardLeve;
|
||||||
|
|
||||||
|
|
||||||
|
// final List<String> investigationMethod = ["隐患快报", "隐患排查", "标准排查", "专项检查", "安全检查"];
|
||||||
|
final List<String> investigationMethod = ["风险排查隐患", "隐患排查隐患"];
|
||||||
|
final List<String> hazardLevel = [" 一般风险 ", " 重大风险 "];
|
||||||
|
final List<String> dangerStatus = ["未整改", "已整改", "已验收", "已过期"];
|
||||||
|
final List<String> laiYuanStatus = ["隐患快报", "隐患排查", "标准排查", "专项检查", "安全检查", "NFC设备巡检"];
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
// TODO: implement initState
|
||||||
|
super.initState();
|
||||||
|
|
||||||
|
setState(() {
|
||||||
|
allData=widget.searchData;
|
||||||
|
if(allData['beginTIme']!=''){
|
||||||
|
_startDate= DateTime.parse(allData['beginTIme']);
|
||||||
|
}
|
||||||
|
if(allData['endTime']!='') {
|
||||||
|
_endDate = DateTime.parse(allData['endTime']);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// if(allData['findUserName']==''){
|
||||||
|
// _getUserData();
|
||||||
|
// }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
|
||||||
|
return SafeArea(
|
||||||
|
child:
|
||||||
|
// SingleChildScrollView( // 添加这一行
|
||||||
|
// child:
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 15),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
|
||||||
|
const Text(
|
||||||
|
"高级查询",
|
||||||
|
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
|
||||||
|
),
|
||||||
|
|
||||||
|
const Divider(height: 20, color: Colors.grey),
|
||||||
|
|
||||||
|
// 开始时间 - 结束时间 —— //
|
||||||
|
Column(
|
||||||
|
children: [
|
||||||
|
_buildDatePickerBox(
|
||||||
|
label: "隐患发现开始时间",
|
||||||
|
date: _startDate,
|
||||||
|
onTap: _pickStartDate,
|
||||||
|
),
|
||||||
|
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
|
||||||
|
_buildDatePickerBox(
|
||||||
|
label: "隐患发现结束时间",
|
||||||
|
date: _endDate,
|
||||||
|
onTap: _pickEndDate,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
|
||||||
|
Column(
|
||||||
|
children: [
|
||||||
|
GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
showModalBottomSheet(
|
||||||
|
context: context,
|
||||||
|
isScrollControlled: true,
|
||||||
|
barrierColor: Colors.black54,
|
||||||
|
backgroundColor: Colors.transparent,
|
||||||
|
builder:
|
||||||
|
(ctx) => DepartmentPickerTwo(
|
||||||
|
onSelected: (id, name,pdId) async {
|
||||||
|
setState(() {
|
||||||
|
|
||||||
|
allData['buMenId']= id;
|
||||||
|
allData['buMenName']= name;
|
||||||
|
|
||||||
|
allData['findUserId']= "";
|
||||||
|
allData['findUserName']= "";
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
// 拉取该单位的人员列表并缓存
|
||||||
|
final result = await HiddenDangerApi.getListTreePersonList(id);
|
||||||
|
_personCache=List<Map<String, dynamic>>.from(
|
||||||
|
result['data'] as List,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: _buildSectionContainer(
|
||||||
|
child: ListItemFactory.createRowSpaceBetweenItem(
|
||||||
|
isRequired:false,
|
||||||
|
leftText: "隐患发现部门",
|
||||||
|
rightText: allData['buMenName'].isNotEmpty ? allData['buMenName'] : "请选择",
|
||||||
|
isRight: true,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
|
||||||
|
// GestureDetector(
|
||||||
|
// onTap: () async {
|
||||||
|
// if(_personCache.isEmpty){
|
||||||
|
// // 拉取该单位的人员列表并缓存
|
||||||
|
// final result = await HiddenDangerApi.getListTreePersonList(allData['buMenId']);
|
||||||
|
// _personCache=List<Map<String, dynamic>>.from(
|
||||||
|
// result['data'] as List,
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
// if ( allData['buMenName'].isEmpty) {
|
||||||
|
// ToastUtil.showNormal(context, '请先选择部门');
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// DepartmentPersonPicker.show(
|
||||||
|
// context,
|
||||||
|
// personsData: _personCache,
|
||||||
|
// onSelected: (userId, name) {
|
||||||
|
// setState(() {
|
||||||
|
//
|
||||||
|
// allData['findUserId']= userId;
|
||||||
|
// allData['findUserName']= name;
|
||||||
|
//
|
||||||
|
// });
|
||||||
|
//
|
||||||
|
// },
|
||||||
|
// );
|
||||||
|
// },
|
||||||
|
// child:Container(
|
||||||
|
// padding: EdgeInsets.symmetric(horizontal: 0),
|
||||||
|
// decoration: BoxDecoration(
|
||||||
|
// borderRadius: BorderRadius.circular(4),
|
||||||
|
// border: Border.all(color: Colors.grey.shade400),
|
||||||
|
// color: Colors.white,
|
||||||
|
// ),
|
||||||
|
// child: ListItemFactory.createRowSpaceBetweenItem(
|
||||||
|
// isRequired:false,
|
||||||
|
// leftText: "隐患发现人",
|
||||||
|
// rightText: allData['findUserName'].isNotEmpty?allData['findUserName']:"请选择",
|
||||||
|
// isRight: true,
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
|
||||||
|
Container(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 0),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.circular(4),
|
||||||
|
border: Border.all(color: Colors.grey.shade400),
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
child: ItemListWidget.singleLineTitleText(
|
||||||
|
label: '隐患发现人',
|
||||||
|
isEditable: true,
|
||||||
|
isRequired:false,
|
||||||
|
isTextFont:false,
|
||||||
|
hintText: '',
|
||||||
|
text: allData['confirmUserName'] ?? '',
|
||||||
|
onChanged: (value) {
|
||||||
|
setState(() {
|
||||||
|
allData['confirmUserName'] = value;
|
||||||
|
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
],
|
||||||
|
),
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
GestureDetector(
|
||||||
|
onTap: () async {
|
||||||
|
|
||||||
|
if(_HazardPersonlist.isEmpty){
|
||||||
|
await _getHazardPersonlist();
|
||||||
|
}
|
||||||
|
String choice = await BottomPickerTwo.show<String>(
|
||||||
|
context,
|
||||||
|
items: _HazardPersonlist,
|
||||||
|
itemName: "name",
|
||||||
|
itemBuilder: (item) => Text(item["name"], textAlign: TextAlign.center),
|
||||||
|
initialIndex: 0,
|
||||||
|
);
|
||||||
|
if (choice != null) {
|
||||||
|
for(int i=0;i<_HazardPersonlist.length;i++){
|
||||||
|
if(choice==_HazardPersonlist[i]["name"]){
|
||||||
|
_hazardLeve = _HazardPersonlist[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setState(() {
|
||||||
|
allData['trueUserId']=_hazardLeve["userId"];
|
||||||
|
allData['trueUserName']=_hazardLeve["name"];
|
||||||
|
|
||||||
|
// addData['confirmDeptId']=_hazardLeve["deptId"];
|
||||||
|
// addData['confirmDeptName']=_hazardLeve["deptName"];
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child:Container(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 0),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.circular(4),
|
||||||
|
border: Border.all(color: Colors.grey.shade400),
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
child: ListItemFactory.createRowSpaceBetweenItem(
|
||||||
|
isRequired:false,
|
||||||
|
leftText: "隐患确认人",
|
||||||
|
rightText: allData['trueUserName'].isNotEmpty?allData['trueUserName']:"请选择",
|
||||||
|
isRight: true,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
_getHiddenDangerType();
|
||||||
|
},
|
||||||
|
child: _buildSectionContainer(
|
||||||
|
child: ListItemFactory.createRowSpaceBetweenItem(
|
||||||
|
isRequired:false,
|
||||||
|
leftText: "隐患类型",
|
||||||
|
rightText: allData['hiddenTypeName'].isNotEmpty?allData['hiddenTypeName']:"请选择",
|
||||||
|
isRight: true,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Expanded(child: SizedBox(height: 20),),
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Flexible(
|
||||||
|
flex: 1,
|
||||||
|
child: CustomButton(
|
||||||
|
text: "重置",
|
||||||
|
buttonStyle:ButtonStyleType.secondary,
|
||||||
|
backgroundColor: h_backGroundColor(),
|
||||||
|
textStyle: const TextStyle(color: Colors.black45),
|
||||||
|
onPressed: () {
|
||||||
|
setState(() {
|
||||||
|
|
||||||
|
|
||||||
|
_startDate = null;
|
||||||
|
_endDate = null;
|
||||||
|
|
||||||
|
allData={
|
||||||
|
"beginTIme": "",
|
||||||
|
"endTime": "",
|
||||||
|
"buMenId": "",
|
||||||
|
"buMenName": "",
|
||||||
|
"findUserId": "",
|
||||||
|
"findUserName": "",
|
||||||
|
"trueUserId": "",
|
||||||
|
"trueUserName": "",
|
||||||
|
"type": "",
|
||||||
|
'hiddenTypeName': "",
|
||||||
|
'confirmUserName': "",
|
||||||
|
};
|
||||||
|
|
||||||
|
setResult();
|
||||||
|
// widget.onClose("","","","","","","");
|
||||||
|
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 12),
|
||||||
|
Flexible(
|
||||||
|
flex: 2,
|
||||||
|
child: CustomButton(
|
||||||
|
text: "完成",
|
||||||
|
backgroundColor: Colors.blue,
|
||||||
|
onPressed: () {
|
||||||
|
setResult();
|
||||||
|
// TODO: 提交筛选条件
|
||||||
|
Navigator.pop(context); // 关闭加载对话框
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
// ),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Widget _buildSectionContainer({required Widget child}) {
|
||||||
|
return Container(
|
||||||
|
margin: const EdgeInsets.only(top: 1),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.circular(4),
|
||||||
|
border: Border.all(color: Colors.grey.shade400),
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
// color: Colors.white,
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 0, vertical: 0),
|
||||||
|
child: child,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Future<void> _pickStartDate() async {
|
||||||
|
final now = DateTime.now();
|
||||||
|
final picked = await showDatePicker(
|
||||||
|
context: context,
|
||||||
|
initialDate: _startDate ?? now,
|
||||||
|
firstDate: DateTime(now.year - 5),
|
||||||
|
lastDate: DateTime(now.year + 5),
|
||||||
|
);
|
||||||
|
if (picked != null) {
|
||||||
|
setState(() {
|
||||||
|
|
||||||
|
_startDate = picked;
|
||||||
|
final dateFormat = DateFormat('yyyy-MM-dd');
|
||||||
|
allData['beginTIme']=dateFormat.format(picked);
|
||||||
|
|
||||||
|
// 保证开始 <= 结束
|
||||||
|
if (_endDate != null && _endDate!.isBefore(picked)) {
|
||||||
|
_endDate = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// setResult();
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _pickEndDate() async {
|
||||||
|
final now = DateTime.now();
|
||||||
|
final initial = _endDate ??
|
||||||
|
(_startDate != null && _startDate!.isAfter(now)
|
||||||
|
? _startDate!
|
||||||
|
: now);
|
||||||
|
final picked = await showDatePicker(
|
||||||
|
context: context,
|
||||||
|
initialDate: initial,
|
||||||
|
firstDate: _startDate ?? DateTime(now.year - 5),
|
||||||
|
lastDate: DateTime(now.year + 5),
|
||||||
|
);
|
||||||
|
if (picked != null) {
|
||||||
|
setState(() {
|
||||||
|
_endDate = picked;
|
||||||
|
|
||||||
|
final dateFormat = DateFormat('yyyy-MM-dd');
|
||||||
|
allData['endTime']=dateFormat.format(picked);
|
||||||
|
|
||||||
|
// setResult();
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildDatePickerBox({
|
||||||
|
required String label,
|
||||||
|
DateTime? date,
|
||||||
|
required VoidCallback onTap,
|
||||||
|
}) {
|
||||||
|
final display = date != null
|
||||||
|
? "${date.year.toString().padLeft(4, '0')}-${date.month.toString().padLeft(2, '0')}-${date.day.toString().padLeft(2, '0')}"
|
||||||
|
: label;
|
||||||
|
return GestureDetector(
|
||||||
|
onTap: onTap,
|
||||||
|
child: Container(
|
||||||
|
height: 35,
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 5),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.circular(4),
|
||||||
|
border: Border.all(color: Colors.grey.shade400),
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
const Icon(Icons.calendar_today, size: 18, color: Colors.grey),
|
||||||
|
const SizedBox(width: 6),
|
||||||
|
Text(display, style: const TextStyle(fontSize: 14, color: Colors.black38)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _getHiddenDangerType() async {
|
||||||
|
|
||||||
|
showModalBottomSheet(
|
||||||
|
context: context,
|
||||||
|
isScrollControlled: true,
|
||||||
|
barrierColor: Colors.black54,
|
||||||
|
backgroundColor: Colors.transparent,
|
||||||
|
builder:
|
||||||
|
(_) => MultiDictValuesPicker(
|
||||||
|
title: '隐患类型',
|
||||||
|
dictType: 'hiddenType',
|
||||||
|
allowSelectParent: false,
|
||||||
|
onSelected: (id, name, extraData) {
|
||||||
|
setState(() {
|
||||||
|
allData['type'] = extraData?['dictValue'];
|
||||||
|
allData['hiddenTypeName'] = name;
|
||||||
|
|
||||||
|
//顶层
|
||||||
|
// allData['hiddenType2'] = extraData?['dingValue'];
|
||||||
|
// allData['hiddenType2Name'] = extraData?['dingName'];
|
||||||
|
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
).then((_) {
|
||||||
|
// 可选:FocusHelper.clearFocus(context);
|
||||||
|
});
|
||||||
|
// try {
|
||||||
|
// LoadingDialogHelper.show();
|
||||||
|
// final raw = await HiddenDangerApi.getHiddenDangerType( );
|
||||||
|
// if (raw['success'] ) {
|
||||||
|
// final newList = raw['data'] ?? [];
|
||||||
|
// LoadingDialogHelper.hide();
|
||||||
|
//
|
||||||
|
// for(int i=0;i<newList.length;i++){
|
||||||
|
// newList[i]["dataId"] = newList[i]["id"];
|
||||||
|
// newList[i]["dataName"] = newList[i]["dictLabel"];
|
||||||
|
//
|
||||||
|
// if(newList[i]['children']!=null&&newList[i]['children'].isNotEmpty){
|
||||||
|
// for(int m=0;m<newList[i]["children"].length;m++){
|
||||||
|
// newList[i]["children"][m]["dataId"] = newList[i]["children"][m]["id"];
|
||||||
|
// newList[i]["children"][m]["dataName"] = newList[i]["children"][m]["dictLabel"];
|
||||||
|
//
|
||||||
|
// if(newList[i]['children'][m]['children']!=null&&newList[i]['children'][m]['children'].isNotEmpty){
|
||||||
|
// for(int n=0;n<newList[i]["children"][m]['children'].length;n++){
|
||||||
|
// newList[i]["children"][m]['children'][n]["dataId"] = newList[i]["children"][m]['children'][n]["id"];
|
||||||
|
// newList[i]["children"][m]['children'][n]["dataName"] = newList[i]["children"][m]['children'][n]["dictLabel"];
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// showModalBottomSheet(
|
||||||
|
// context: context,
|
||||||
|
// isScrollControlled: true,
|
||||||
|
// barrierColor: Colors.black54,
|
||||||
|
// backgroundColor: Colors.transparent,
|
||||||
|
// builder: (ctx) => DepartmentPickerThree(
|
||||||
|
// listdata: newList,
|
||||||
|
// onSelected: (id, name,pdId) async {
|
||||||
|
// setState(() {
|
||||||
|
// allData['type']=id;
|
||||||
|
// allData['hiddenTypeName']=name;
|
||||||
|
//
|
||||||
|
// });
|
||||||
|
//
|
||||||
|
// },
|
||||||
|
// ),
|
||||||
|
// );
|
||||||
|
//
|
||||||
|
// }else{
|
||||||
|
// ToastUtil.showNormal(context, "获取列表失败");
|
||||||
|
// LoadingDialogHelper.hide();
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// } catch (e) {
|
||||||
|
// // 出错时可以 Toast 或者在页面上显示错误状态
|
||||||
|
// print('加载首页数据失败:$e');
|
||||||
|
// LoadingDialogHelper.hide();
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Future<void> _getUserData() async {
|
||||||
|
try {
|
||||||
|
|
||||||
|
final raw = await AuthApi.getUserData( );
|
||||||
|
if (raw['success'] ) {
|
||||||
|
|
||||||
|
setState(() {
|
||||||
|
allData['findUserId']=raw['data']['id'];
|
||||||
|
allData['findUserName']=raw['data']['name'];
|
||||||
|
allData['buMenId']=raw['data']['departmentId'];
|
||||||
|
allData['buMenName']=raw['data']['departmentName'];
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
}else{
|
||||||
|
ToastUtil.showNormal(context, "获取个人信息失败");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (e) {
|
||||||
|
// 出错时可以 Toast 或者在页面上显示错误状态
|
||||||
|
print('加载首页数据失败:$e');
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Future<void> _getHazardPersonlist() async {
|
||||||
|
try {
|
||||||
|
LoadingDialogHelper.show();
|
||||||
|
final raw = await HiddenDangerApi.getHazardPersonlist( );
|
||||||
|
if (raw['success'] ) {
|
||||||
|
_HazardPersonlist = raw['data'] ?? [];
|
||||||
|
LoadingDialogHelper.hide();
|
||||||
|
|
||||||
|
|
||||||
|
}else{
|
||||||
|
ToastUtil.showNormal(context, "获取列表失败");
|
||||||
|
LoadingDialogHelper.hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (e) {
|
||||||
|
// 出错时可以 Toast 或者在页面上显示错误状态
|
||||||
|
print('加载首页数据失败:$e');
|
||||||
|
LoadingDialogHelper.hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void setResult(){
|
||||||
|
widget.onClose(
|
||||||
|
allData
|
||||||
|
); // 触发回调
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,874 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:intl/intl.dart';
|
||||||
|
import 'package:qhd_prevention/constants/app_enums.dart';
|
||||||
|
import 'package:qhd_prevention/customWidget/custom_button.dart';
|
||||||
|
import 'package:qhd_prevention/customWidget/search_bar_widget.dart';
|
||||||
|
import 'package:qhd_prevention/customWidget/toast_util.dart';
|
||||||
|
import 'package:qhd_prevention/http/ApiService.dart';
|
||||||
|
import 'package:qhd_prevention/pages/home/hiddenDanger/hidden_danger_acceptance.dart';
|
||||||
|
import 'package:qhd_prevention/pages/home/hiddenDanger/hidden_danger_deawer.dart';
|
||||||
|
import 'package:qhd_prevention/pages/home/hiddenDanger/hidden_record_detail_page.dart';
|
||||||
|
|
||||||
|
import 'package:qhd_prevention/pages/my_appbar.dart';
|
||||||
|
import 'package:qhd_prevention/tools/h_colors.dart';
|
||||||
|
import 'package:qhd_prevention/tools/tools.dart';
|
||||||
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
|
||||||
|
class HiddenDangerRecordTwo extends StatefulWidget {
|
||||||
|
const HiddenDangerRecordTwo(
|
||||||
|
this.dangerType,
|
||||||
|
this.appItem,
|
||||||
|
this.corpId, {
|
||||||
|
super.key,
|
||||||
|
});
|
||||||
|
|
||||||
|
final DangerType dangerType;
|
||||||
|
final int appItem;
|
||||||
|
final String corpId;
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<HiddenDangerRecordTwo> createState() => _HiddenDangerRecordTwoState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _HiddenDangerRecordTwoState extends State<HiddenDangerRecordTwo> {
|
||||||
|
int _page = 1;
|
||||||
|
String searchKey = "";
|
||||||
|
int _totalPage = 1;
|
||||||
|
late List<dynamic> _list = [];
|
||||||
|
bool _isLoading = false;
|
||||||
|
bool _hasMore = true;
|
||||||
|
Timer? _debounceTimer;
|
||||||
|
bool _isShowDelete = true;
|
||||||
|
|
||||||
|
final TextEditingController _searchController = TextEditingController();
|
||||||
|
Map<String, dynamic> searchData = {
|
||||||
|
"beginTIme": "",
|
||||||
|
"endTime": "",
|
||||||
|
"buMenId": "",
|
||||||
|
"buMenName": "",
|
||||||
|
"findUserId": "",
|
||||||
|
"findUserName": "",
|
||||||
|
"trueUserId": "",
|
||||||
|
"trueUserName": "",
|
||||||
|
"type": "",
|
||||||
|
'hiddenTypeName': "",
|
||||||
|
'confirmUserName': "",
|
||||||
|
};
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
// 初始均为空
|
||||||
|
|
||||||
|
_searchController.addListener(_onSearchChanged);
|
||||||
|
|
||||||
|
_initializeVisibility();
|
||||||
|
_getListData(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _initializeVisibility() async {
|
||||||
|
_isShowDelete = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_debounceTimer?.cancel();
|
||||||
|
_searchController.removeListener(_onSearchChanged);
|
||||||
|
_searchController.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
// 取屏幕宽度
|
||||||
|
final double screenWidth = MediaQuery.of(context).size.width;
|
||||||
|
|
||||||
|
return Scaffold(
|
||||||
|
appBar: MyAppbar(
|
||||||
|
title: widget.dangerType.displayName,
|
||||||
|
actions: [
|
||||||
|
Builder(
|
||||||
|
builder: (innerContext) {
|
||||||
|
return TextButton(
|
||||||
|
onPressed: () {
|
||||||
|
// 通过 innerContext 拿到 ScaffoldState,打开右侧抽屉
|
||||||
|
Scaffold.of(innerContext).openEndDrawer();
|
||||||
|
},
|
||||||
|
child: Text(
|
||||||
|
"查询",
|
||||||
|
style: TextStyle(color: Colors.white, fontSize: 16),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
|
||||||
|
//弹窗
|
||||||
|
endDrawer: Drawer(
|
||||||
|
// 用 Container 限制宽度为屏幕的 3/5
|
||||||
|
child: Container(
|
||||||
|
width: screenWidth * 3 / 5,
|
||||||
|
color: Colors.white,
|
||||||
|
child: HiddenDangerDeawer(
|
||||||
|
searchData,
|
||||||
|
onClose: (closeData) {
|
||||||
|
searchData = closeData;
|
||||||
|
_page = 1;
|
||||||
|
_getListData(false);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
body: SafeArea(
|
||||||
|
child: NotificationListener<ScrollNotification>(
|
||||||
|
onNotification: _onScroll,
|
||||||
|
child: _vcDetailWidget(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
backgroundColor: Colors.white,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _vcDetailWidget() {
|
||||||
|
return Column(
|
||||||
|
children: [
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.all(10),
|
||||||
|
child: SearchBarWidget(
|
||||||
|
controller: _searchController,
|
||||||
|
hintText: '请输入隐患描述',
|
||||||
|
isShowSearchButton: false,
|
||||||
|
onTextChanged: (value) {
|
||||||
|
if (_debounceTimer?.isActive ?? false) {
|
||||||
|
_debounceTimer!.cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
_debounceTimer = Timer(const Duration(milliseconds: 500), () {
|
||||||
|
print('搜索关键词: ${_searchController.text}');
|
||||||
|
_performSearch(_searchController.text);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onSearch: (keyboard) {},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Container(height: 5, color: h_backGroundColor()),
|
||||||
|
Expanded(
|
||||||
|
child:
|
||||||
|
_list.isEmpty
|
||||||
|
? NoDataWidget.show()
|
||||||
|
: ListView.builder(
|
||||||
|
itemCount: _list.length,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
final item = _list[index];
|
||||||
|
return _fxitemCell(item, index);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _fxitemCell(pageData, index) {
|
||||||
|
// 使用GestureDetector包裹整个列表项以添加点击事件
|
||||||
|
return GestureDetector(
|
||||||
|
onTap: () {},
|
||||||
|
|
||||||
|
child: Container(
|
||||||
|
margin: EdgeInsets.all(6),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.circular(12),
|
||||||
|
boxShadow: [
|
||||||
|
BoxShadow(
|
||||||
|
color: Colors.grey.withOpacity(0.3),
|
||||||
|
spreadRadius: 2,
|
||||||
|
blurRadius: 5,
|
||||||
|
offset: Offset(0, 3),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
// 标题
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start, // 添加这一行
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: Padding(
|
||||||
|
padding: EdgeInsets.only(left: 10, top: 15, right: 8),
|
||||||
|
child: Text(
|
||||||
|
'隐患描述: ${pageData['hiddenDesc']!}',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 18,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
color: Colors.black87,
|
||||||
|
),
|
||||||
|
maxLines: 1, // 只显示一行
|
||||||
|
overflow: TextOverflow.ellipsis, // 超出部分显示省略号
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
// 状态标签
|
||||||
|
Container(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 12, vertical: 6),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: _getLevelColor(pageData),
|
||||||
|
borderRadius: BorderRadius.only(
|
||||||
|
bottomLeft: Radius.circular(12),
|
||||||
|
topRight: Radius.circular(12), // 改为右上角
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
pageData['hiddenLevelName']!,
|
||||||
|
style: TextStyle(
|
||||||
|
color: Colors.white,
|
||||||
|
fontSize: 12,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
|
||||||
|
SizedBox(height: 16),
|
||||||
|
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.only(left: 10, right: 10),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
// 来源
|
||||||
|
Expanded(
|
||||||
|
child: Text(
|
||||||
|
_getSourceDangers(pageData),
|
||||||
|
style: TextStyle(fontSize: 14, color: Colors.black87),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
// 隐患状态
|
||||||
|
// Expanded(
|
||||||
|
// child: Text(
|
||||||
|
// '隐患状态:${_getState(pageData)}',
|
||||||
|
// style: TextStyle(fontSize: 14, color: Colors.black87),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
SizedBox(height: 8),
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.only(left: 10, right: 10),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
// 来源
|
||||||
|
// Expanded(
|
||||||
|
// child: Text(
|
||||||
|
// _getSourceDangers(pageData),
|
||||||
|
// style: TextStyle(fontSize: 14, color: Colors.black87),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// 隐患状态
|
||||||
|
Expanded(
|
||||||
|
child: Text(
|
||||||
|
'隐患状态:${_getState(pageData)}',
|
||||||
|
style: TextStyle(fontSize: 14, color: Colors.black87),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
SizedBox(height: 8),
|
||||||
|
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.only(left: 10, right: 10),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
// 隐患发现人
|
||||||
|
Expanded(
|
||||||
|
child: Text(
|
||||||
|
'发现人:${truncateString(pageData['createName'] ?? '')}',
|
||||||
|
style: TextStyle(fontSize: 14, color: Colors.black87),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
Expanded(
|
||||||
|
child: Text(
|
||||||
|
'发现时间:${_changeTime(pageData['hiddenFindTime']??'')}',
|
||||||
|
style: TextStyle(fontSize: 14, color: Colors.black87),
|
||||||
|
// maxLines: 1,
|
||||||
|
// overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
if (widget.appItem != 1) SizedBox(height: 8),
|
||||||
|
|
||||||
|
if (widget.appItem != 1)
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.only(left: 10, right: 10),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
// 隐患确认人
|
||||||
|
Expanded(
|
||||||
|
child: Text(
|
||||||
|
'确认人:${pageData['confirmUserName'] ?? ''}',
|
||||||
|
style: TextStyle(fontSize: 14, color: Colors.black87),
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
Expanded(
|
||||||
|
child: Text(
|
||||||
|
'确认时间:${_changeTime(pageData['hiddenFindTime'] ?? '')}',
|
||||||
|
style: TextStyle(fontSize: 14, color: Colors.black87),
|
||||||
|
// maxLines: 1,
|
||||||
|
// overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
if (widget.appItem == 6) SizedBox(height: 8),
|
||||||
|
|
||||||
|
if (widget.appItem == 6)
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.only(left: 10, right: 10),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
// 整改人
|
||||||
|
Expanded(
|
||||||
|
child: Text(
|
||||||
|
'整改人:${pageData['rectifyUserName'] ?? ''}',
|
||||||
|
style: TextStyle(fontSize: 14, color: Colors.black87),
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
Expanded(
|
||||||
|
child: Text(
|
||||||
|
'整改时间:${_changeTime(pageData['rectificationTime'] ?? '')}',
|
||||||
|
style: TextStyle(fontSize: 14, color: Colors.black87),
|
||||||
|
// maxLines: 1,
|
||||||
|
// overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
if (pageData['hiddenYUserName'] != null &&
|
||||||
|
pageData['hiddenYUserName'].isNotEmpty)
|
||||||
|
SizedBox(height: 8),
|
||||||
|
|
||||||
|
if (pageData['hiddenYUserName'] != null &&
|
||||||
|
pageData['hiddenYUserName'].isNotEmpty)
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.only(left: 10, right: 10),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
// 整改人
|
||||||
|
Expanded(
|
||||||
|
child: Text(
|
||||||
|
'验收人:${pageData['hiddenYUserName'] ?? ''}',
|
||||||
|
style: TextStyle(fontSize: 14, color: Colors.black87),
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
Expanded(
|
||||||
|
child: Text(
|
||||||
|
'验收时间:${_changeTime(pageData['hiddenYTime'] ?? '')}',
|
||||||
|
style: TextStyle(fontSize: 14, color: Colors.black87),
|
||||||
|
// maxLines: 1,
|
||||||
|
// overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
SizedBox(height: 8),
|
||||||
|
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
// 查看详情按钮
|
||||||
|
Expanded(
|
||||||
|
child: CustomButton(
|
||||||
|
height: 35,
|
||||||
|
onPressed: () {
|
||||||
|
// print('查看详情: ${pageData['title']}');
|
||||||
|
pushPage(
|
||||||
|
HiddenRecordDetailPage(
|
||||||
|
widget.dangerType,
|
||||||
|
widget.appItem,
|
||||||
|
pageData['id'],
|
||||||
|
pageData['hiddenId'],
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
context,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
backgroundColor: h_AppBarColor(),
|
||||||
|
textStyle: const TextStyle(color: Colors.white),
|
||||||
|
buttonStyle: ButtonStyleType.primary,
|
||||||
|
text: '查看',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
// Expanded(
|
||||||
|
// child: Container(
|
||||||
|
// height: 35,
|
||||||
|
// margin: EdgeInsets.only(left: 5, right: 10),
|
||||||
|
// child: ElevatedButton(
|
||||||
|
// onPressed: () {
|
||||||
|
// // print('查看详情: ${pageData['title']}');
|
||||||
|
// pushPage(HiddenRecordDetailPage(widget.dangerType,widget.appItem,pageData['id'],pageData['hiddenId'],false), context);
|
||||||
|
// },
|
||||||
|
// style: ElevatedButton.styleFrom(
|
||||||
|
// backgroundColor: Colors.blue,
|
||||||
|
// foregroundColor: Colors.white,
|
||||||
|
// shape: RoundedRectangleBorder(
|
||||||
|
// borderRadius: BorderRadius.circular(8),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// child: Text('查看'),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
if (_isShowDelete && 201 == pageData["state"])
|
||||||
|
SizedBox(width: 10),
|
||||||
|
|
||||||
|
// 修改按钮
|
||||||
|
if (_isShowDelete && 201 == pageData["state"])
|
||||||
|
Expanded(
|
||||||
|
child: CustomButton(
|
||||||
|
height: 35,
|
||||||
|
onPressed: () {
|
||||||
|
// print('查看详情: ${pageData['title']}');
|
||||||
|
// pushPage(HiddenDangerModificationPage(pageData['id'],pageData['hiddenId']), context);
|
||||||
|
_getTemporaryStorageOfHiddenYinHuan(
|
||||||
|
pageData,
|
||||||
|
pageData['hiddenId'],
|
||||||
|
index,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
backgroundColor: h_AppBarColor(),
|
||||||
|
textStyle: const TextStyle(color: Colors.white),
|
||||||
|
buttonStyle: ButtonStyleType.primary,
|
||||||
|
text: '修改',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
// Expanded(
|
||||||
|
// child: Container(
|
||||||
|
// height: 35,
|
||||||
|
// margin: EdgeInsets.only(left: 5, right: 10),
|
||||||
|
// child: ElevatedButton(
|
||||||
|
// onPressed: () {
|
||||||
|
// // print('查看详情: ${pageData['title']}');
|
||||||
|
// // pushPage(HiddenDangerModificationPage(pageData['id'],pageData['hiddenId']), context);
|
||||||
|
// _getTemporaryStorageOfHiddenYinHuan(pageData,pageData['hiddenId'],index);
|
||||||
|
// },
|
||||||
|
// style: ElevatedButton.styleFrom(
|
||||||
|
// backgroundColor: Colors.blue,
|
||||||
|
// foregroundColor: Colors.white,
|
||||||
|
// shape: RoundedRectangleBorder(
|
||||||
|
// borderRadius: BorderRadius.circular(8),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// child: Text('修改'),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
if (_isShowDelete && 100 == pageData["state"])
|
||||||
|
SizedBox(width: 10),
|
||||||
|
|
||||||
|
// 查看详情按钮
|
||||||
|
if (_isShowDelete && 100 == pageData["state"]&&pageData["source"]!=4&&pageData["source"]!=5)
|
||||||
|
Expanded(
|
||||||
|
child: CustomButton(
|
||||||
|
height: 35,
|
||||||
|
onPressed: () {
|
||||||
|
// print('查看详情: ${pageData['title']}');
|
||||||
|
_showLogoutConfirmation(pageData);
|
||||||
|
},
|
||||||
|
backgroundColor: Colors.red,
|
||||||
|
textStyle: const TextStyle(color: Colors.white),
|
||||||
|
buttonStyle: ButtonStyleType.primary,
|
||||||
|
text: '删除',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
// Expanded(
|
||||||
|
// child: Container(
|
||||||
|
// height: 35,
|
||||||
|
// margin: EdgeInsets.only(left: 5, right: 10),
|
||||||
|
// child: ElevatedButton(
|
||||||
|
// onPressed: () {
|
||||||
|
// // print('查看详情: ${pageData['title']}');
|
||||||
|
// _showLogoutConfirmation(pageData);
|
||||||
|
// },
|
||||||
|
// style: ElevatedButton.styleFrom(
|
||||||
|
// backgroundColor: Colors.red,
|
||||||
|
// foregroundColor: Colors.white,
|
||||||
|
// shape: RoundedRectangleBorder(
|
||||||
|
// borderRadius: BorderRadius.circular(8),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// child: Text('删除'),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
|
||||||
|
SizedBox(height: 10),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _performSearch(String keyword) {
|
||||||
|
// 执行搜索逻辑
|
||||||
|
// if (keyword.isNotEmpty) {
|
||||||
|
// print('执行搜索: $keyword');
|
||||||
|
// 调用API或其他搜索操作
|
||||||
|
// 输入请求接口
|
||||||
|
_page = 1;
|
||||||
|
searchKey = keyword;
|
||||||
|
_getListData(false);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _onScroll(ScrollNotification n) {
|
||||||
|
if (n.metrics.pixels > n.metrics.maxScrollExtent - 100 &&
|
||||||
|
_hasMore &&
|
||||||
|
!_isLoading) {
|
||||||
|
_page++;
|
||||||
|
_getListData(true);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onSearchChanged() {
|
||||||
|
final query = _searchController.text.toLowerCase().trim();
|
||||||
|
setState(() {
|
||||||
|
print("=====>" + query);
|
||||||
|
// filtered = query.isEmpty ? original : _filterCategories(original, query);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _getListData(bool loadMore) async {
|
||||||
|
try {
|
||||||
|
if (_isLoading) return;
|
||||||
|
_isLoading = true;
|
||||||
|
|
||||||
|
LoadingDialogHelper.show();
|
||||||
|
|
||||||
|
final Map<String, dynamic> result;
|
||||||
|
result = await HiddenDangerApi.getGeneralHazardList(
|
||||||
|
_page,
|
||||||
|
searchKey,
|
||||||
|
searchData,
|
||||||
|
widget.corpId,
|
||||||
|
);
|
||||||
|
|
||||||
|
LoadingDialogHelper.hide();
|
||||||
|
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 = _page < _totalPage;
|
||||||
|
// if (_hasMore) _page++;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
ToastUtil.showNormal(context, "加载数据失败");
|
||||||
|
// _showMessage('加载数据失败');
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
LoadingDialogHelper.hide();
|
||||||
|
// 出错时可以 Toast 或者在页面上显示错误状态
|
||||||
|
print('加载数据失败:$e');
|
||||||
|
} finally {
|
||||||
|
// if (!loadMore) LoadingDialogHelper.hide();
|
||||||
|
_isLoading = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String _getSourceDangers(final item) {
|
||||||
|
int type = item["source"];
|
||||||
|
if (1 == type) {
|
||||||
|
return "隐患来源:隐患快报";
|
||||||
|
} else if (2 == type) {
|
||||||
|
return "隐患来源:清单排查";
|
||||||
|
} else if (3 == type) {
|
||||||
|
return "隐患来源:标准排查";
|
||||||
|
} else if (4 == type) {
|
||||||
|
return "隐患来源:安全环保检查(监管端)";
|
||||||
|
} else if (5 == type) {
|
||||||
|
return "隐患来源:安全环保检查(企业端)";
|
||||||
|
} else if (6 == type) {
|
||||||
|
return "隐患来源:消防点检";
|
||||||
|
} else if (7 == type) {
|
||||||
|
return "隐患来源:视频巡屏";
|
||||||
|
} else {
|
||||||
|
return "隐患来源:NFC设备巡检";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 隐患等级颜色
|
||||||
|
Color _getLevelColor(final item) {
|
||||||
|
String type = item["hiddenLevelName"];
|
||||||
|
if ("重大隐患" == type) {
|
||||||
|
return Colors.red;
|
||||||
|
} else if ("较大隐患" == type) {
|
||||||
|
return Color(0xFFFF6A4D);
|
||||||
|
} else if ("一般隐患" == type) {
|
||||||
|
return Colors.orange;
|
||||||
|
} else if ("轻微隐患" == type) {
|
||||||
|
return h_AppBarColor();
|
||||||
|
} else {
|
||||||
|
return Colors.green;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String _getState(final item) {
|
||||||
|
int type = item["state"];
|
||||||
|
if (100 == type) {
|
||||||
|
return "待确认";
|
||||||
|
} else if (200 == type) {
|
||||||
|
return "未整改";
|
||||||
|
} else if (201 == type) {
|
||||||
|
return "确认打回";
|
||||||
|
} else if (202 == type) {
|
||||||
|
return "待处理特殊隐患";
|
||||||
|
} else if (300 == type) {
|
||||||
|
return "已整改";
|
||||||
|
} else if (301 == type) {
|
||||||
|
return "已验收";
|
||||||
|
} else if (302 == type) {
|
||||||
|
return "验收打回";
|
||||||
|
} else if (303 == type) {
|
||||||
|
return "验收打回";
|
||||||
|
} else if (400 == type) {
|
||||||
|
return "已处理特殊隐患";
|
||||||
|
} else if (99 == type) {
|
||||||
|
return "强制关闭(人员变动)";
|
||||||
|
} else if (98 == type) {
|
||||||
|
return "安全环保检查/清单排查暂存";
|
||||||
|
} else if (102 == type) {
|
||||||
|
return "安全环保检查,隐患带指派";
|
||||||
|
} else if (97 == type) {
|
||||||
|
return "已过期";
|
||||||
|
} else if (101 == type) {
|
||||||
|
return "忽略隐患";
|
||||||
|
} else {
|
||||||
|
return "已过期";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String _changeTime(String time) {
|
||||||
|
try {
|
||||||
|
// 解析 ISO 8601 格式的时间字符串
|
||||||
|
DateTime dateTime = DateTime.parse(time);
|
||||||
|
// 格式化为年月日
|
||||||
|
return DateFormat('yyyy-MM-dd').format(dateTime);
|
||||||
|
} catch (e) {
|
||||||
|
// 如果解析失败,返回原字符串或默认值
|
||||||
|
return ' ';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _showLogoutConfirmation(pageData) {
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder:
|
||||||
|
(context) => AlertDialog(
|
||||||
|
title: const Text("删除隐患"),
|
||||||
|
content: const Text("确定要删除隐患吗??"),
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(16),
|
||||||
|
),
|
||||||
|
actions: [
|
||||||
|
ElevatedButton(
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.pop(context);
|
||||||
|
},
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
backgroundColor: Colors.grey[400],
|
||||||
|
foregroundColor: Colors.white,
|
||||||
|
),
|
||||||
|
child: const Text("取消"),
|
||||||
|
),
|
||||||
|
ElevatedButton(
|
||||||
|
onPressed: () {
|
||||||
|
// 执行删除操作
|
||||||
|
Navigator.pop(context);
|
||||||
|
_deleteData(pageData);
|
||||||
|
},
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
backgroundColor: Colors.blue[700],
|
||||||
|
foregroundColor: Colors.white,
|
||||||
|
),
|
||||||
|
child: const Text("确定"),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _deleteData(pageData) async {
|
||||||
|
try {
|
||||||
|
LoadingDialogHelper.show();
|
||||||
|
|
||||||
|
final Map<String, dynamic> result;
|
||||||
|
result = await HiddenDangerApi.deleteHiddenDangers(pageData['id']);
|
||||||
|
|
||||||
|
LoadingDialogHelper.hide();
|
||||||
|
if (result['success']) {
|
||||||
|
setState(() {
|
||||||
|
ToastUtil.showNormal(context, "删除成功");
|
||||||
|
_page = 1;
|
||||||
|
_getListData(false);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
ToastUtil.showNormal(context, "删除失败");
|
||||||
|
// _showMessage('加载数据失败');
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
LoadingDialogHelper.hide();
|
||||||
|
// 出错时可以 Toast 或者在页面上显示错误状态
|
||||||
|
print('删除失败:$e');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _getTemporaryStorageOfHiddenYinHuan(
|
||||||
|
Map item,
|
||||||
|
String hiddenId,
|
||||||
|
index,
|
||||||
|
) async {
|
||||||
|
// try {
|
||||||
|
// LoadingDialogHelper.show();
|
||||||
|
// final results = await Future.wait([
|
||||||
|
// HiddenDangerApi.getDetailByHiddeNiD(hiddenId),
|
||||||
|
// // HiddenDangerApi.getImagePath(hiddenId, "3"),
|
||||||
|
// // HiddenDangerApi.getImagePath(hiddenId, "102"),
|
||||||
|
// // HiddenDangerApi.getImagePath(hiddenId, "4"),
|
||||||
|
// FileApi.getImagePath(hiddenId, UploadFileType.hiddenDangerPhoto),
|
||||||
|
// FileApi.getImagePath(hiddenId, UploadFileType.hiddenDangerVideo),
|
||||||
|
// // FileApi.getImagePath(item['hiddenUserId'] ?? '', UploadFileType.hiddenDangerRectificationPhoto),
|
||||||
|
// ]);
|
||||||
|
//
|
||||||
|
// LoadingDialogHelper.hide();
|
||||||
|
// if (results[0]['success']) {
|
||||||
|
// Map<String, dynamic> pd = results[0]['data'];
|
||||||
|
//
|
||||||
|
// //隐患图片
|
||||||
|
// List<hiddenImgData> imgList = await _getImagePath(
|
||||||
|
// results[1]['data'],
|
||||||
|
// "3",
|
||||||
|
// );
|
||||||
|
// List<hiddenImgData> videos = await _getImagePath(
|
||||||
|
// results[2]['data'],
|
||||||
|
// "102",
|
||||||
|
// );
|
||||||
|
// // 整改图片
|
||||||
|
// List<hiddenImgData> zgImgList = [];
|
||||||
|
// // List<hiddenImgData> zgImgList = await _getImagePath(results[3]['data'],"4");
|
||||||
|
//
|
||||||
|
// await pushPage(
|
||||||
|
// HiddenDangerModificationPage(pd, imgList, videos, zgImgList),
|
||||||
|
// context,
|
||||||
|
// );
|
||||||
|
// _getListData(false);
|
||||||
|
// } else {
|
||||||
|
// ToastUtil.showNormal(context, "加载数据失败");
|
||||||
|
// }
|
||||||
|
// } catch (e) {
|
||||||
|
// LoadingDialogHelper.hide();
|
||||||
|
// print('加载数据失败:$e');
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Future<List<hiddenImgData>> _getImagePath(
|
||||||
|
// List<dynamic> images,
|
||||||
|
// String type,
|
||||||
|
// ) async {
|
||||||
|
// try {
|
||||||
|
// List<hiddenImgData> dataList = [];
|
||||||
|
// for (int i = 0; i < images.length; i++) {
|
||||||
|
// String filePath = images[i]['filePath'];
|
||||||
|
//
|
||||||
|
// if ("3" == type) {
|
||||||
|
// dataList.add(
|
||||||
|
// // 直接创建实例
|
||||||
|
// hiddenImgData(path: ApiService.baseImgPath + filePath, id: "1"),
|
||||||
|
// );
|
||||||
|
// } else if ("102" == type) {
|
||||||
|
// dataList.add(
|
||||||
|
// // 直接创建实例
|
||||||
|
// hiddenImgData(path: ApiService.baseImgPath + filePath, id: "1"),
|
||||||
|
// );
|
||||||
|
// } else if ("4" == type) {
|
||||||
|
// dataList.add(
|
||||||
|
// // 直接创建实例
|
||||||
|
// hiddenImgData(path: ApiService.baseImgPath + filePath, id: "1"),
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// return dataList;
|
||||||
|
// } catch (e) {
|
||||||
|
// print('Error fetching data: $e');
|
||||||
|
// return [];
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
String truncateString(String input) {
|
||||||
|
if (input.length > 10) {
|
||||||
|
return '${input.substring(0, 10)}...';
|
||||||
|
}
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<String> _getString(String key) async {
|
||||||
|
final prefs = await SharedPreferences.getInstance();
|
||||||
|
String text = prefs.getString(key) ?? '';
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,330 @@
|
||||||
|
// lib/pages/application_template.dart
|
||||||
|
import 'dart:ffi';
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:qhd_prevention/common/route_service.dart';
|
||||||
|
import 'package:qhd_prevention/http/modules/key_tasks_api.dart';
|
||||||
|
import 'package:qhd_prevention/pages/home/doorAndCar/doorCar_tab_page.dart';
|
||||||
|
import 'package:qhd_prevention/pages/home/hiddenDanger/hidden_danger_acceptance.dart';
|
||||||
|
import 'package:qhd_prevention/pages/home/hiddenDanger/hidden_danger_record_two.dart';
|
||||||
|
import 'package:qhd_prevention/pages/home/keyTasks/keyTasksDetail/keyTasksHiddenDanger/key_tasks_hidden_danger_list.dart';
|
||||||
|
import 'package:qhd_prevention/pages/home/keyTasks/key_tasks_check_list_page.dart';
|
||||||
|
import 'package:qhd_prevention/pages/home/keyTasks/key_tasks_confirm_list_page.dart';
|
||||||
|
import 'package:qhd_prevention/pages/my_appbar.dart';
|
||||||
|
import 'package:qhd_prevention/services/SessionService.dart';
|
||||||
|
import 'package:qhd_prevention/tools/tools.dart';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class HiddenDangerTabPage extends StatefulWidget {
|
||||||
|
const HiddenDangerTabPage({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<HiddenDangerTabPage> createState() => _HiddenDangerTabPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _HiddenDangerTabPageState extends State<HiddenDangerTabPage> {
|
||||||
|
|
||||||
|
final String bannerAsset = 'assets/images/key_tasks_banner.jpg';
|
||||||
|
late List<AppSection> defaultSections;
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
// TODO: implement initState
|
||||||
|
super.initState();
|
||||||
|
|
||||||
|
_initSections(); // 初始化 sections
|
||||||
|
_getDoorCarCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 初始化 sections 的方法
|
||||||
|
void _initSections() {
|
||||||
|
defaultSections = [
|
||||||
|
AppSection(title: '隐患治理', items: [
|
||||||
|
AppSectionItem(
|
||||||
|
title: '隐患整改',
|
||||||
|
icon: 'assets/images/key_tasks_ico6.png',
|
||||||
|
menuPerms:'dashboard:Key-assignment:Hidden-danger-rectification',
|
||||||
|
badge: 0,
|
||||||
|
onTap: () async {
|
||||||
|
await pushPage(HiddenDangerAcceptance(DangerType.wait, 3), context);
|
||||||
|
_getDoorCarCount();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
AppSectionItem(
|
||||||
|
title: '隐患记录',
|
||||||
|
icon: 'assets/images/key_tasks_ico7.png',
|
||||||
|
menuPerms:'dashboard:Key-assignment:Hidden-Hazard-Record',
|
||||||
|
badge: 0,
|
||||||
|
onTap: () async {
|
||||||
|
await pushPage(HiddenDangerRecordTwo(DangerType.ristRecord, 7, ''), context);
|
||||||
|
_getDoorCarCount();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
|
||||||
|
]),
|
||||||
|
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _getDoorCarCount() async {
|
||||||
|
// try {
|
||||||
|
// String userId= SessionService.instance.accountId??'';
|
||||||
|
// final result = await KeyTasksApi.getKeyTasksToDoCount(userId);
|
||||||
|
// if (result['success'] ) {
|
||||||
|
// dynamic data = result['data']?? {} ;
|
||||||
|
//
|
||||||
|
// setState(() {
|
||||||
|
// // 隐患治理
|
||||||
|
// final gateSection = defaultSections[0];
|
||||||
|
//
|
||||||
|
// // 隐患治理
|
||||||
|
// gateSection.items[0].badge = int.parse(data['zdzysqCount']??0);
|
||||||
|
// // 确认
|
||||||
|
// gateSection.items[1].badge = int.parse(data['bjcrqrCount']??0);
|
||||||
|
// // 整改
|
||||||
|
// gateSection.items[2].badge = int.parse(data['yhdzgCount']??0);
|
||||||
|
//
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
// // else {
|
||||||
|
// // ToastUtil.showNormal(context, result['errMessage'] ?? "加载数据失败");
|
||||||
|
// // }
|
||||||
|
// } catch (e) {
|
||||||
|
// LoadingDialogHelper.hide();
|
||||||
|
// print('加载数据失败:$e');
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final double bannerHeight = (730.0 / 1125.0) * MediaQuery.of(context).size.width;
|
||||||
|
final double iconSectionHeight =
|
||||||
|
MediaQuery.of(context).size.height - bannerHeight - 30.0;
|
||||||
|
const double iconOverlapBanner = 30.0;
|
||||||
|
|
||||||
|
// 过滤掉没有可见 items 的分组
|
||||||
|
// final visibleSections = defaultSections
|
||||||
|
// .map((s) => AppSection(
|
||||||
|
// title: s.title,
|
||||||
|
// items: s.items.where((it) => it.visible).toList()))
|
||||||
|
// .where((s) => s.items.isNotEmpty)
|
||||||
|
// .toList();
|
||||||
|
final routeService = RouteService();
|
||||||
|
|
||||||
|
return AnimatedBuilder(
|
||||||
|
animation: routeService,
|
||||||
|
builder: (context, _)
|
||||||
|
{
|
||||||
|
final rebuiltVisibleSections = defaultSections.map((section) {
|
||||||
|
final visibleItems = section.items.where((item) {
|
||||||
|
return item.visible && routeService.hasPerm(item.menuPerms);
|
||||||
|
}).toList();
|
||||||
|
|
||||||
|
return AppSection(
|
||||||
|
title: section.title,
|
||||||
|
items: visibleItems,
|
||||||
|
);
|
||||||
|
}).where((section) => section.items.isNotEmpty).toList();
|
||||||
|
|
||||||
|
return Scaffold(
|
||||||
|
extendBodyBehindAppBar: true,
|
||||||
|
appBar: MyAppbar(title: '隐患治理', backgroundColor: Colors.transparent,),
|
||||||
|
body: ListView(
|
||||||
|
physics: const AlwaysScrollableScrollPhysics(),
|
||||||
|
padding: EdgeInsets.zero,
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
height: bannerHeight + iconSectionHeight,
|
||||||
|
child: Stack(
|
||||||
|
clipBehavior: Clip.none,
|
||||||
|
children: [
|
||||||
|
Positioned(
|
||||||
|
top: 0,
|
||||||
|
left: 0,
|
||||||
|
right: 0,
|
||||||
|
height: bannerHeight,
|
||||||
|
child: _buildBannerSection(bannerHeight, context),
|
||||||
|
),
|
||||||
|
Positioned(
|
||||||
|
left: 10,
|
||||||
|
right: 10,
|
||||||
|
top: bannerHeight - iconOverlapBanner,
|
||||||
|
height: iconSectionHeight,
|
||||||
|
child: _buildIconSection(context, rebuiltVisibleSections),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildBannerSection(double bannerHeight, BuildContext context) {
|
||||||
|
return Stack(
|
||||||
|
children: [
|
||||||
|
Image.asset(
|
||||||
|
bannerAsset,
|
||||||
|
width: MediaQuery.of(context).size.width,
|
||||||
|
height: bannerHeight,
|
||||||
|
fit: BoxFit.fitWidth,
|
||||||
|
errorBuilder: (c, e, s) {
|
||||||
|
return Container(
|
||||||
|
color: Colors.blueGrey,
|
||||||
|
height: bannerHeight,
|
||||||
|
alignment: Alignment.center,
|
||||||
|
child: const Text('Banner', style: TextStyle(color: Colors.white)),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildIconSection(BuildContext context, List<AppSection> buttonInfos) {
|
||||||
|
return Container(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 0),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.circular(12),
|
||||||
|
boxShadow: const [
|
||||||
|
BoxShadow(color: Colors.black12, blurRadius: 6, offset: Offset(0, 2)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
child: ListView.builder(
|
||||||
|
physics: const AlwaysScrollableScrollPhysics(),
|
||||||
|
padding: const EdgeInsets.all(0),
|
||||||
|
itemCount: buttonInfos.length,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
final section = buttonInfos[index];
|
||||||
|
final items = section.items;
|
||||||
|
if (items.isEmpty) return const SizedBox.shrink();
|
||||||
|
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.only(top: 10, left: 10, right: 10),
|
||||||
|
child: Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
// 标题
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.fromLTRB(10, 10, 10, 5),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Container(width: 2, height: 10, color: Colors.blue),
|
||||||
|
const SizedBox(width: 5),
|
||||||
|
Text(section.title,
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 14, fontWeight: FontWeight.bold)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
// icons
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.all(10),
|
||||||
|
child: LayoutBuilder(
|
||||||
|
builder: (context, constraints) {
|
||||||
|
const spacing = 20.0;
|
||||||
|
final totalWidth = constraints.maxWidth;
|
||||||
|
final itemWidth = (totalWidth - spacing * 2) / 3;
|
||||||
|
return Wrap(
|
||||||
|
spacing: spacing,
|
||||||
|
runSpacing: spacing,
|
||||||
|
children: items.map<Widget>((item) {
|
||||||
|
return SizedBox(
|
||||||
|
width: itemWidth,
|
||||||
|
child: _buildItem(
|
||||||
|
item,
|
||||||
|
onTap: item.onTap ??
|
||||||
|
() => debugPrint('Tapped ${item.title}'),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}).toList(),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildItem(AppSectionItem item, {VoidCallback? onTap}) {
|
||||||
|
const double iconSize = 30;
|
||||||
|
final int badgeNum = item.badge;
|
||||||
|
final String title = item.title;
|
||||||
|
final String iconPath = item.icon;
|
||||||
|
|
||||||
|
return InkWell(
|
||||||
|
onTap: onTap,
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
child: SizedBox(
|
||||||
|
width: double.infinity,
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Stack(
|
||||||
|
clipBehavior: Clip.none,
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
width: iconSize,
|
||||||
|
height: iconSize,
|
||||||
|
child: Image.asset(
|
||||||
|
iconPath,
|
||||||
|
fit: BoxFit.contain,
|
||||||
|
errorBuilder: (c, e, s) {
|
||||||
|
return Container(
|
||||||
|
color: Colors.grey.shade200,
|
||||||
|
child: const Center(child: Icon(Icons.image, size: 18)),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (badgeNum > 0)
|
||||||
|
Positioned(
|
||||||
|
top: -6,
|
||||||
|
right: -6,
|
||||||
|
child: Container(
|
||||||
|
padding:
|
||||||
|
const EdgeInsets.symmetric(horizontal: 4, vertical: 2),
|
||||||
|
decoration:
|
||||||
|
const BoxDecoration(color: Colors.red, shape: BoxShape.circle),
|
||||||
|
constraints: const BoxConstraints(minWidth: 16, minHeight: 16),
|
||||||
|
child: Center(
|
||||||
|
child: Text(
|
||||||
|
badgeNum > 99 ? '99+' : badgeNum.toString(),
|
||||||
|
style: const TextStyle(color: Colors.white, fontSize: 10, height: 1),
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const SizedBox(height: 4),
|
||||||
|
Text(
|
||||||
|
title,
|
||||||
|
style: const TextStyle(fontSize: 13),
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
maxLines: 2,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -13,6 +13,7 @@ import 'package:qhd_prevention/http/modules/key_tasks_api.dart';
|
||||||
import 'package:qhd_prevention/pages/home/Study/study_tab_list_page.dart';
|
import 'package:qhd_prevention/pages/home/Study/study_tab_list_page.dart';
|
||||||
import 'package:qhd_prevention/pages/home/Tap/work_tab_list_page.dart';
|
import 'package:qhd_prevention/pages/home/Tap/work_tab_list_page.dart';
|
||||||
import 'package:qhd_prevention/pages/home/doorAndCar/doorCar_tab_page.dart';
|
import 'package:qhd_prevention/pages/home/doorAndCar/doorCar_tab_page.dart';
|
||||||
|
import 'package:qhd_prevention/pages/home/hiddenDanger/hidden_danger_tab_page.dart';
|
||||||
import 'package:qhd_prevention/pages/home/keyTasks/key_tasks_tab_page.dart';
|
import 'package:qhd_prevention/pages/home/keyTasks/key_tasks_tab_page.dart';
|
||||||
import 'package:qhd_prevention/pages/home/scan_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/home/unit/unit_tab_page.dart';
|
||||||
|
|
@ -758,9 +759,12 @@ class HomePageState extends RouteAwareState<HomePage>
|
||||||
case "重点作业":
|
case "重点作业":
|
||||||
await pushPage(KeyTasksTabPage(), context);
|
await pushPage(KeyTasksTabPage(), context);
|
||||||
break;
|
break;
|
||||||
case "危险作业":
|
case "危险作业":
|
||||||
await pushPage(WorkTabListPage(), context);
|
await pushPage(WorkTabListPage(), context);
|
||||||
break;
|
break;
|
||||||
|
case "隐患治理":
|
||||||
|
await pushPage(HiddenDangerTabPage(), context);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
ToastUtil.showNormal(context, '功能开发中...');
|
ToastUtil.showNormal(context, '功能开发中...');
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue