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 = ''}) {
|
||||
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/Tap/work_tab_list_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/scan_page.dart';
|
||||
import 'package:qhd_prevention/pages/home/unit/unit_tab_page.dart';
|
||||
|
|
@ -758,9 +759,12 @@ class HomePageState extends RouteAwareState<HomePage>
|
|||
case "重点作业":
|
||||
await pushPage(KeyTasksTabPage(), context);
|
||||
break;
|
||||
case "危险作业":
|
||||
await pushPage(WorkTabListPage(), context);
|
||||
break;
|
||||
case "危险作业":
|
||||
await pushPage(WorkTabListPage(), context);
|
||||
break;
|
||||
case "隐患治理":
|
||||
await pushPage(HiddenDangerTabPage(), context);
|
||||
break;
|
||||
default:
|
||||
ToastUtil.showNormal(context, '功能开发中...');
|
||||
break;
|
||||
|
|
|
|||
Loading…
Reference in New Issue