Commit 478b8b33 authored by 宁天庆's avatar 宁天庆

修改代码

parent c4898f28
/// 全局配置项,主要配置外部sdk,内部可变的 url 以及其它参数
///
///
///
class GlobalConfig {
/// 平台后端接口 oauth 参数
static String product;
static String appKey;
/// jpush key, 外部系统引入 base 模块时,需要自行提供
static String jpushKey;
/// 登录页面系统名称
static String loginSysName;
static String loginFooter;
/// 显示系统配置
static bool showSysConfig;
/// 内部 url
///
/// 网管 gateway 地址
static String gatewayUrl;
/// app 升级 url地址
static String updateApkUrl;
}
\ No newline at end of file
......@@ -21,12 +21,12 @@ class HttpConfig {
/// 注意,整个升级,仅判断 version 字段
///
static const String UpdateApkUrl =
'http://172.16.10.72/app/apk/apk-version.json';
'/app/apk/apk-version.json';
//static const String ImageUrl = 'http://39.98.45.134:9000/';
static const String ImageUrl = 'http://172.16.11.201:3006/yibin/yeejoin/';
static const String ImageUrl = 'http://172.16.3.18:8808/';
static const String mqttUrl = 'ws://172.16.11.201:1883/mqtt';
static const String mqttUrl = 'ws://172.16.3.18:1883/mqtt';
static const int connTimeout = 60000;
static const int recTimeout = 10000;
......
......@@ -498,6 +498,6 @@ mixin URLConst {
/// 根据计量编号获取设备详情
static const String queryEquipDetailsByCode = '/qis/v1/equipmentLedger/queryByEquipCode';
/// 根据计量编号进行送检、接收、报废
static const String scanEquipQrCodeBiz = '/qis/v1/equipmentLedger/queryByEquipCode';
static const String scanEquipQrCodeBiz = '/qis/v1/planEquipment/';
}
......@@ -6,11 +6,11 @@ import 'package:get/get_navigation/src/root/get_material_app.dart';
import 'package:get/get_navigation/src/routes/get_route.dart';
import 'package:amos_flutter_utils/amos_flutter_utils.dart';
import 'package:amos_iot_login_tpl/amos_iot_login_tpl.dart';
import 'package:base/view/common/not_found_page.dart';
// import 'package:base/view/common/not_found_page.dart';
import 'package:jcs_airport/routes/routes.dart';
import 'package:base/consts/global_config.dart';
// import 'package:base/consts/global_config.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';
import 'package:equipment_manage/routes/routes.dart' as equipment_manager_routes;
import 'package:jcs_airport/view/sign/routes.dart';
import 'package:jcs_airport/view/sign/application.dart' as application_dl;
......@@ -18,6 +18,8 @@ import '../consts/http_config.dart';
import '../consts/url_const.dart';
import '../services/application.dart';
import '../utils/app_theme.dart';
import '../view/common/not_found_page.dart';
import '../consts/global_config.dart';
void initSysConfig() {
GlobalConfig.appKey = HttpConfig.appKey;
......@@ -31,7 +33,7 @@ void initSysConfig() {
LoginGlobalConfig.showSysConfig = true;
LoginGlobalConfig.gatewayUrl = HttpConfig.GateWayURL;
LoginGlobalConfig.imageUrl = HttpConfig.ImageUrl;
LoginGlobalConfig.mqttUrl = HttpConfig.mqttUrl;
// LoginGlobalConfig.mqttUrl = HttpConfig.mqttUrl;
LoginGlobalConfig.updateApkUrl = HttpConfig.UpdateApkUrl;
/// 内嵌 h5 页面
......@@ -43,7 +45,6 @@ class MyApp extends StatefulWidget {
MyApp() {
initSysConfig();
final router = FluroRouter();
equipment_manager_routes.Routes.configureRoutes(router);
Routes.configureRoutes(router);
Application.router = router;
// application_dl.Application.router = router;
......
......@@ -2,12 +2,14 @@ import 'dart:async';
import 'package:amos_iot_login_tpl/amos_iot_login_tpl.dart';
import 'package:base/model/initialize_providers.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'entry/index.dart';
import './viewmodel/initialize_providers.dart';
void main() {
FlutterError.onError = ErrorCrash.instance.onFlutterError;
/// 错误日志存储到文件
......
This diff is collapsed.
This diff is collapsed.
import 'dart:io';
import 'package:base/services/api_address.dart';
import 'package:dio/dio.dart';
import 'package:jcs_airport/consts/file_type.dart';
import 'package:jcs_airport/consts/url_const.dart';
import 'package:jcs_airport/utils/request.dart';
import 'package:jcs_airport/view/common/image_picker.dart';
import 'package:jcs_airport/viewmodel/confirm_alam.dart';
import 'package:jcs_airport/viewmodel/monitor_event.dart';
class API {
......@@ -20,6 +14,6 @@ class API {
/// 根据计量编号进行送检、接收、报废
static Future scanEquipQrCodeBizCode(String code, String type) async {
return await AmosHttp.client.get(URLConst.scanEquipQrCodeBiz, query: { "equipmentCode": code, 'type': type });
return await AmosHttp.client.get(URLConst.scanEquipQrCodeBiz + type + '/execute/app', query: { "equipmentCode": code });
}
}
import 'package:amos_flutter_ui/amos_flutter_ui.dart';
import 'package:amos_iot_login_tpl/amos_iot_login_tpl.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:jcs_airport/routes/routes.dart';
import 'package:jcs_airport/services/api.dart';
import 'package:safe_control/routes/routes.dart' as safe_control_routes;
///@Description 首页当前隐患
///@author helinlin
///@create 2021-10-29 9:44
class CurrentDanger extends StatefulWidget {
static String currentPatrolDangerWaitHandle = 'currentPatrolDangerWaitHandle';
static String currentSupervisionDangerWaitHandle = 'currentSupervisionDangerWaitHandle';
const CurrentDanger({Key key}) : super(key: key);
@override
_CurrentDangerState createState() => _CurrentDangerState();
}
class _CurrentDangerState extends State<CurrentDanger> {
List countData = [
{
'type': '消防巡查隐患处理:',
'image': 'assets/images/fire_warning.png',
'count': 0,
'firstRecord': {'title': '', 'subTitle': ''},
'onClick': () {
Get.toNamed(safe_control_routes.Routes.waitHandlePage,
arguments: PlatformMenu(frontComponent: CurrentDanger.currentPatrolDangerWaitHandle));
}
},
{
'type': '防火监督隐患处理:',
'image': 'assets/images/danger_audit.png',
'count': 0,
'firstRecord': {'title': '', 'subTitle': ''},
'onClick': () {
Get.toNamed(JCSRoutes.hiddenDanger,
arguments: PlatformMenu(frontComponent: CurrentDanger.currentSupervisionDangerWaitHandle));
}
},
];
@override
void initState() {
super.initState();
getCount();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('当前隐患'),
),
body: Column(
children: [
ListView.builder(
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemBuilder: (BuildContext context, int index) {
return CommonCard(
child: InkWell(
onTap: countData[index]['onClick'],
child: Padding(
padding: const EdgeInsets.all(15.0),
child: Row(
children: [
Padding(
padding: const EdgeInsets.only(right: 8.0),
child: Image.asset(
countData[index]['image'],
width: 45,
),
),
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Row(
children: [
Text(
countData[index]['type'],
style: const TextStyle(fontSize: 16),
),
const SizedBox(
width: 5,
),
Text('${countData[index]['count']}', style: const TextStyle(fontSize: 16)),
],
),
countData[index]['firstRecord'].isNotEmpty
? Column(
children: [
const SizedBox(
height: 5,
),
Opacity(
opacity: 0.6,
child: Row(
children: [
Text(
'${countData[index]['firstRecord']['title'] ?? ''}',
style: const TextStyle(fontSize: 14),
overflow: TextOverflow.ellipsis,
),
Expanded(
child: Text(
'${countData[index]['firstRecord']['subTitle'] ?? ''}',
textAlign: TextAlign.end,
style: const TextStyle(fontSize: 14),
overflow: TextOverflow.ellipsis,
),
)
],
),
)
],
)
: Container(),
],
),
),
],
),
),
),
);
},
itemCount: countData.length)
],
),
);
}
Future<void> getCount() async {
Future.delayed(Duration.zero, () {
MsgBox.showProgressDialog(context, content: '加载中,请稍后。。。');
List<Future> tasks = [];
tasks.add(getHiddenDangerNum());
tasks.add(getPatrolFirst());
tasks.add(getSupervisionFirst());
Future.wait(tasks).then((value) {}).whenComplete(() => Get.back());
});
}
Future<void> getHiddenDangerNum() async {
var data = await API.unFinishedDanger();
if (data != null) {
setState(() {
countData[0]['count'] = data['patrol'];
countData[1]['count'] = data['supervision'];
});
}
}
Future<void> getPatrolFirst() async {
Map filterData = {
'dangerLevel': -1,
'pageSize': 10,
'pageNumber': 0,
'isHandle': false,
'dangerState': 0,
'belongType': 0,
'dangerId': null
};
var data = await API.patrolHiddenDangerList(filterData);
if (data != null && data['content'] is List && data['content'].isNotEmpty) {
setState(() {
countData[0]
['firstRecord'] = {'title': data['content'].first['dangerName'], 'subTitle': data['content'].first['limitDesc']};
});
}
}
Future<void> getSupervisionFirst() async {
Map filterData = {'my': '0', 'dangerState': '', 'dangerLevel': ''};
var data = await API.dangerAuditList(filterData..addAll({'current': 1, 'size': 1}));
if (data != null && data['records'] is List && data['records'].isNotEmpty) {
setState(() {
countData[1]['firstRecord'] = {
'title': data['records'].first['dangerName'],
'subTitle': data['records'].first['reformLimitDate']
};
});
}
}
}
import 'package:amos_flutter_ui/card/index.dart';
import 'package:amos_iot_login_tpl/amos_iot_login_tpl.dart';
import 'package:amos_iot_login_tpl/message/conf.dart';
import 'package:amos_iot_login_tpl/message/message_list.dart';
import 'package:amos_iot_login_tpl/message/message_list_item.dart';
import 'package:amos_iot_login_tpl/utils/EventBusUtil.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:jcs_airport/entity/message.dart';
import 'package:jcs_airport/services/api.dart';
import 'package:jcs_airport/view/workBench/maintenance/maintenanceTask/task_detail.dart';
import './RichText.dart';
import 'WaitingTask.dart';
import 'dart:async';
///@Description 非领导首页 待办任务、消息通知卡片
///@author helinlin
///@create 2021-11-17 13:46
class HomeMessageCard extends StatefulWidget {
final MessageType type;
final ValueChanged editMessageCount;
const HomeMessageCard(this.type, {Key key, this.editMessageCount})
: super(key: key);
@override
_HomeMessageCardState createState() => _HomeMessageCardState();
}
class _HomeMessageCardState extends State<HomeMessageCard> {
final List<Message> _messageList = <Message>[];
@override
void initState() {
super.initState();
// getMessage();
// API.msgList({
// 'current': 0,
// 'size': 10,
// 'terminal': 'APP',
// 'category': widget.type == MessageType.Task ? 0 : 1
// }).then((value) {
// if (value['records'] != null) {
// setState(() {
// value['records'].forEach((item) {
// _messageList.add(Message.fromJson(item));
// });
// });
// if (widget.type == MessageType.Message) {
// widget.editMessageCount(value['total']);
// }
// }
// });
}
@override
Widget build(BuildContext context) {
return CommonCard(
child: Padding(
padding: const EdgeInsets.only(right: 8, left: 8, top: 8),
child: Column(
children: [
Row(
children: [
Expanded(
child: Text(
widget.type == MessageType.Message ? '消息通知' : '待办任务',
style: const TextStyle(fontSize: 15),
)),
InkWell(
onTap: () {
widget.type == MessageType.Message
? EventBusUtil.getInstance().fire(EventFn(2))
: Get.to(const WaitingTask()).then((value){
API.msgList({
'current': 0,
'size': 10,
'terminal': 'APP',
'category': widget.type == MessageType.Task ? 0 : 1
}).then((value) {
if (value['records'] != null) {
setState(() {
value['records'].forEach((item) {
_messageList.add(Message.fromJson(item));
});
});
if (widget.type == MessageType.Message) {
widget.editMessageCount(value['total']);
}
}
});
});
},
child: Opacity(
opacity: 0.6,
child: Row(
children: const [
Text(
'更多',
style: TextStyle(fontSize: 13),
),
Icon(
Icons.chevron_right,
size: 18,
)
],
)),
)
],
),
const Divider(
color: Colors.black,
height: 15,
thickness: 0.1,
),
ListView.builder(
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
//只显示5条
itemCount: _messageList.length > 3 ? 3 : _messageList.length,
itemBuilder: (BuildContext context, int index) {
return InkWell(
onTap: () async {
Map<String, dynamic> data = _messageList[index].toJson();
var id = data['extras']['planTaskDetailId'];
var routePointId = data['extras']['routePointId'];
var msgType = data['msgType'];
if (msgType == 'maintenance') {
var result = await API.inquirePoint(id);
// print(result);
// print('result11');
Get.to(TaskDetail(id, routePointId, result));
}else {
ListViewItem.linkRoute(context, data);
}
},
child: Column(
children: [
Padding(
padding: const EdgeInsets.all(0.0),
child: Row(
children: [
Padding(
padding:
const EdgeInsets.only(left: 10, right: 20),
child: Image.asset(
imgMap[_messageList[index].msgType] ??
'assets/images/car_default.png',
width: 32,
),
),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Expanded(
child:_messageList[index].body!=null ?RichText1(content:_messageList[index].body):const Text(''))
],
),
const SizedBox(
height: 4,
),
Opacity(
opacity: 0.6,
child: Row(
children: [
Expanded(
child: Text(
_messageList[index].msgTypeName ??
'',
style:
const TextStyle(fontSize: 13),
overflow: TextOverflow.ellipsis,
)),
Text(
_messageList[index].sendTime ??
'',
style:
const TextStyle(fontSize: 13),
overflow: TextOverflow.ellipsis,
)
],
)),
],
),
)
],
),
),
const Divider(
color: Colors.black,
thickness: 0.1,
)
],
),
);
})
],
),
),
);
}
///获取消息
void getMessage() {
var timer = null;
timer=Timer.periodic(
const Duration(milliseconds: 30000),(timer) {
API.msgList({
'current': 0,
'size': 10,
'terminal': 'APP',
'category': widget.type == MessageType.Task ? 0 : 1
}).then((value) {
if (value['records'] != null) {
setState(() {
value['records'].forEach((item) {
_messageList.add(Message.fromJson(item));
});
});
if (widget.type == MessageType.Message) {
widget.editMessageCount(value['total']);
}
}
}).catchError((Object obj) {
timer.cancel();
});;
});
}
}
import 'package:amos_flutter_ui/amos_flutter_ui.dart';
import 'package:amos_iot_login_tpl/message/message_list.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
///@Description HomeWaitingCard
///@author helinlin
///@create 2021-11-17 15:45
class HomeWaitingCard extends StatefulWidget {
final Type type;
const HomeWaitingCard({Key key, this.type}) : super(key: key);
@override
_HomeWaitingCardState createState() => _HomeWaitingCardState();
}
class _HomeWaitingCardState extends State<HomeWaitingCard> {
@override
Widget build(BuildContext context) {
return CommonCard(
child: Padding(
padding: const EdgeInsets.only(right: 8, left: 8, top: 8),
child: Column(
children: [
Row(
children: [
const Expanded(
child: Text(
'待办任务',
style: TextStyle(fontSize: 15),
)),
InkWell(
onTap: () => Get.to(MessageList(type: MessageType.Task)),
child: Opacity(
opacity: 0.6,
child: Row(
children: const [
Text(
'更多',
style: TextStyle(fontSize: 13),
),
Icon(
Icons.chevron_right,
size: 18,
)
],
)),
)
],
),
const Divider(
color: Colors.black,
height: 15,
thickness: 0.1,
),
ListView.builder(
itemBuilder: (BuildContext context, int index) {
return Column(
children: [
Row(
children: [
Padding(
padding: const EdgeInsets.only(left: 10, right: 20),
child: Image.asset(
'assets/images/car_default.png',
width: 32,
),
),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text('油区进油后明火作业'),
const SizedBox(
height: 4,
),
Opacity(
opacity: 0.6,
child: Row(
children: const [
Expanded(
child: Text(
'技术经验',
style: TextStyle(fontSize: 13),
overflow: TextOverflow.ellipsis,
),
),
Text(
'2021-11-17 14:54:30',
style: TextStyle(fontSize: 13),
overflow: TextOverflow.ellipsis,
),
],
),
)
],
),
)
],
),
const Divider(
color: Colors.black,
thickness: 0.1,
)
],
);
},
itemCount: 3,
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
)
],
),
),
);
}
}
import 'package:flutter/material.dart';
class RichText1 extends StatefulWidget {
String content = '';
RichText1({Key key,this.content}) : super(key: key);
@override
State<RichText1> createState() => _RichTextState();
}
class _RichTextState extends State<RichText1> {
// 全文、收起 的状态
bool mIsExpansion = false;
// 最大显示行数
int mMaxLine = 5;
@override
Widget build(BuildContext context) {
return Container(
child:_RichText(widget.content) ,
);
}
///[_text ] 传入的字符串
Widget _RichText(String _text) {
if (IsExpansion(_text)) {
//是否截断
if (mIsExpansion) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
_text,
textAlign: TextAlign.left,
),
Container(
child: InkWell(
onTap: (){_isShowText();},
child: Row(mainAxisAlignment:MainAxisAlignment.end ,children: [ Text('收起',style: TextStyle(color: Colors.grey))],),
),
)
],
);
} else {
return Column(
children: <Widget>[
Text(
_text,
maxLines: 3,
textAlign: TextAlign.left,
overflow: TextOverflow.ellipsis,
),
Container(
child: InkWell(
onTap: (){_isShowText();},
child: Row(mainAxisAlignment:MainAxisAlignment.end ,children: [ Text('全文',style: TextStyle(color: Colors.grey))],),
),
)
],
);
}
} else {
return Text(
_text,
maxLines: 3,
textAlign: TextAlign.left,
overflow: TextOverflow.ellipsis,
);
}
}
bool IsExpansion(String text) {
TextPainter _textPainter = TextPainter(
maxLines: 3,
text: TextSpan(
text: text, style: const TextStyle(fontSize: 16.0, color: Colors.black)),
textDirection: TextDirection.ltr)..layout(maxWidth: 90, minWidth: 50);
// if (_textPainter.didExceedMaxLines) {//判断 文本是否需要截断
if (text.length > 65) {//判断 文本是否需要截断
return true;
} else {
return false;
}
}
void _isShowText() {
if (mIsExpansion) {
//关闭
setState(() {
mIsExpansion = false;
});
} else {
//打开
setState(() {
mIsExpansion = true;
});
}
}
}
import 'package:amos_iot_login_tpl/message/index.dart';
import 'package:flutter/material.dart';
///@Description WaitingTask
///@author helinlin
///@create 2021-11-19 14:50
class WaitingTask extends StatefulWidget {
const WaitingTask({Key key}) : super(key: key);
@override
_WaitingTaskState createState() => _WaitingTaskState();
}
class _WaitingTaskState extends State<WaitingTask> {
@override
Widget build(BuildContext context) {
return MessageList(
type: MessageType.Task,
);
}
}
import 'package:amos_flutter_ui/amos_flutter_ui.dart';
import 'package:flutter/material.dart';
///@Description WaitingTask备份,后续不再需要可以删除
///@author helinlin
///@create 2021-11-17 16:19
class WaitingTask extends StatefulWidget {
const WaitingTask({Key key}) : super(key: key);
@override
_WaitingTaskState createState() => _WaitingTaskState();
}
class _WaitingTaskState extends State<WaitingTask> {
List<Map> data = [
{'icon': '', 'title': '消防监督', 'time': '2021-11-18 10:47:21', 'content': '数据数据数据数据数据数据数据数据数据数据数据数据'},
{'icon': '', 'title': '消防巡查', 'time': '2021-11-18 10:47:21', 'content': '数据数据数据数据数据数据数据数据数据数据数据数据'},
{'icon': '', 'title': '接处警', 'time': '2021-11-18 10:47:21', 'content': '数据数据数据数据数据数据数据数据数据数据数据数据'},
];
List<Map> type = [
{'name': '全部'},
{'name': '消防监督'},
{'name': '消防巡查'},
{'name': '接处警'},
];
String typeValue = '全部';
Divider divider = const Divider(
color: Colors.black,
thickness: 0.1,
);
@override
Widget build(BuildContext context) {
List<Map> filterData = [];
if (typeValue == '全部') {
filterData.addAll(data);
} else {
data.forEach((element) {
if (element['title'] == typeValue) {
filterData.add(element);
}
});
}
return Scaffold(
appBar: AppBar(
title: const Text('我的待办'),
),
backgroundColor: const Color.fromARGB(255, 245, 250, 245),
body: SingleChildScrollView(
child: Column(
children: [
CommonCard(
child: Row(
children: <Widget>[
Expanded(
flex: 2,
child: Container(
height: 40,
margin: const EdgeInsets.only(left: 10, top: 10, right: 5, bottom: 10),
padding: const EdgeInsets.all(5),
decoration: BoxDecoration(
border: Border.all(color: Colors.black26, width: 1),
borderRadius: const BorderRadius.all(Radius.circular(6))),
child: DropdownButton<String>(
hint: const Text('请选择'),
isExpanded: true,
underline: Container(
height: 0,
),
value: typeValue,
items: type
.map((t) => DropdownMenuItem<String>(
child: Text(t['name']),
value: t['name'],
))
.toList(),
onChanged: (String value) {
setState(() {
typeValue = value;
});
},
),
),
),
Expanded(
flex: 3,
child: Container(
height: 40,
margin: const EdgeInsets.only(left: 5, top: 10, right: 10, bottom: 10),
decoration: BoxDecoration(
border: Border.all(color: Colors.black26, width: 1),
borderRadius: const BorderRadius.all(Radius.circular(6))),
child: TextField(
autofocus: false,
decoration: const InputDecoration(
hintText: '搜索',
border: InputBorder.none,
contentPadding: EdgeInsets.only(left: 10, top: 10, right: 5, bottom: 10)),
onChanged: (String value) {},
),
),
)
],
),
),
CommonCard(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: ListView.separated(
itemBuilder: (BuildContext context, int index) {
return InkWell(
onTap: () {
//Get.to(WaitingTaskDetail(type: filterData[index]['title']))
},
child: Row(
children: [
Image.asset('assets/images/car_default.png'),
const SizedBox(
width: 10,
),
Expanded(
child: Column(
children: [
Row(
children: [
Expanded(
child: Text(
filterData[index]['title'],
overflow: TextOverflow.ellipsis,
style: const TextStyle(fontSize: 17),
)),
Text(filterData[index]['time']),
],
),
const SizedBox(
height: 4,
),
Opacity(
opacity: 0.8,
child: Row(
children: [
Expanded(child: Text(filterData[index]['content'], overflow: TextOverflow.ellipsis)),
],
),
)
],
),
)
],
),
);
},
separatorBuilder: (BuildContext context, int index) => divider,
itemCount: filterData.length,
shrinkWrap: true,
),
),
)
],
),
),
);
}
}
import 'package:amos_flutter_ui/card/common_card.dart';
import 'package:amos_iot_login_tpl/amos_iot_login_tpl.dart';
import 'package:amos_iot_login_tpl/message/index.dart';
import 'package:amos_iot_login_tpl/utils/EventBusUtil.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:jcs_airport/services/api.dart';
import 'package:amap_flutter_location/amap_flutter_location.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:permission_handler_platform_interface/permission_handler_platform_interface.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:amap_flutter_location/amap_flutter_location.dart';
import 'package:amap_flutter_location/amap_location_option.dart';
import 'package:jcs_airport/view/workBench/fireproofSupervision/planCheck/add_hidden_danger.dart';
import 'HomeMenuCard.dart';
import 'HomeMessageCard.dart';
import 'dart:async';
......@@ -79,6 +67,26 @@ class _HomeCommonState extends State<HomeCommon> {
}
Widget getPersonInfo() {
var aa = amosUser['companys'];
String companyId = '';
var companiesList = amosUser["companys"];
if (companiesList is List && companiesList.length > 0) {
var companyItem = companiesList[0];
if (companyItem is Map && companyItem.containsKey("sequenceNbr")) {
companyId = companyItem["sequenceNbr"];
}
}
String dptName = null;
var companyDepartments = amosUser["companyDepartments"];
if (companyDepartments is Map<String, dynamic> && companyDepartments != null) {
var deptList = companyDepartments[companyId];
if (deptList is List && deptList.length > 0) {
var deptItem = deptList[0];
if (deptItem is Map && deptItem.containsKey("departmentName")) {
dptName = deptItem["departmentName"];
}
}
}
return Padding(
padding: const EdgeInsets.all(25.0),
child: Row(
......@@ -111,7 +119,7 @@ class _HomeCommonState extends State<HomeCommon> {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('${amosUser['mobile'] ?? ''}', style: const TextStyle(color: Colors.white, fontSize: 13)),
Text('${(amosUser['companys'][0] ?? [])['companyName'] ?? ''}',
Text('${dptName ?? (amosUser['companys'][0] ?? [])['companyName'] ?? ''}',
style: const TextStyle(color: Colors.white, fontSize: 13)),
],
),
......
import 'package:amos_iot_login_tpl/amos_iot_login_tpl.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:jcs_airport/services/api.dart';
import 'package:jcs_airport/view/dispatch/statistics/dispatch_alarm_list.dart';
import 'package:percent_indicator/percent_indicator.dart';
import 'package:amos_flutter_utils/extension/int_extension.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:permission_handler_platform_interface/permission_handler_platform_interface.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:amap_flutter_location/amap_flutter_location.dart';
import 'package:amap_flutter_location/amap_location_option.dart';
import 'package:jcs_airport/view/workBench/fireproofSupervision/planCheck/add_hidden_danger.dart';
import 'CurrentDanger.dart';
import 'HomeMenuCard.dart';
import 'HomeMessageCard.dart';
import 'iot_monitor.dart';
import 'dart:async';
///@Description 领导首页
///@author helinlin
///@create 2021-10-25 9:57
class HomeLeader extends StatefulWidget {
const HomeLeader({Key key}) : super(key: key);
@override
_HomeLeaderState createState() => _HomeLeaderState();
}
class _HomeLeaderState extends State<HomeLeader> {
final List _countList = [
{
'description': '当前警情',
'count': 0,
'countColor': Colors.cyanAccent,
'onClick': () {
Get.to(const CurrentAlarmList(), arguments: 'fromHome');
}
},
{
'description': '物联监测',
'count': 0,
'countColor': Colors.redAccent,
'onClick': () {
Get.to(const IotMonitor());
}
},
{
'description': '当前隐患',
'count': 0,
'countColor': Colors.lightGreenAccent,
'onClick': () {
Get.to(const CurrentDanger());
}
}
];
int allCount = 0;
double latitude;
double longitude;
final AMapFlutterLocation aMapFlutterLocation = AMapFlutterLocation();
@override
void initState() {
super.initState();
getCurrentAlert();
getFireAlarmFirstRecord();
getFaultAlarmFirstRecord();
getIotMonitorEventFirstRecord();
getAlarmGiveStatistics();
_timerLocation();
}
/// 高德定位
Future<void> _timerLocation() async {
var timer = null;
var result = await API.getuserBJ();
if(result != null){
aMapFlutterLocation.onLocationChanged().listen((Map<String, Object> res) {
if (res != null) {
latitude = res['latitude'];
longitude = res['longitude'];
// aMapFlutterLocation.stopLocation();
}
});
aMapFlutterLocation.startLocation();
timer=Timer.periodic(
const Duration(milliseconds: 60000),(timer) async{
var data = {
'carNum':result['carNum'],
'sequenceNbr':result['carId'],
'longitude': longitude,
'latitude': latitude,
};
// longitude = longitude + 0.0003;
// var data = {
// 'carNum':'机场·消0014',
// 'sequenceNbr':'1438718392776286210',
// 'longitude': longitude,
// 'latitude': latitude,
// };
if(longitude != null && latitude != null){
API.addESCar(data).then((value){
print(value);
if (value == true) {}
else{
aMapFlutterLocation.stopLocation();
timer.cancel();
}
}).catchError((Object obj) {
print('报错了!!!!!!!!!!');
print(obj);
aMapFlutterLocation.stopLocation();
timer.cancel();
});
}
// timer.cancel();//取消定时器
});
}else{
aMapFlutterLocation.stopLocation();
timer.cancel();
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('首页'),
centerTitle: true,
),
body: SingleChildScrollView(
child: Container(
color: const Color.fromARGB(255, 245, 250, 245),
child: Stack(
children: [
Container(
height: 300,
decoration: const BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: [Colors.blue, Colors.blue])),
child: Container(),
),
Column(
children: [
Column(
children: [
Padding(
padding: const EdgeInsets.only(top: 15, bottom: 0),
child: CircularPercentIndicator(
curve: Curves.easeInOut,
circularStrokeCap: CircularStrokeCap.round,
animation: false,
radius: 130.0,
lineWidth: 15.0,
percent: 1.0,
center: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
allCount.toString() + '个',
style: const TextStyle(color: Colors.white, fontSize: 25, fontWeight: FontWeight.bold),
),
],
),
progressColor: Colors.greenAccent,
backgroundColor: Colors.white,
),
),
Padding(
padding: const EdgeInsets.only(top: 20, bottom: 20),
child: Row(
children: _countList
.map((element) => buildCountItem(element['count'].toString(), element['countColor'],
element['description'], element['onClick']))
.toList()
.cast<Widget>()
..insert(1, buildCountDivider())
..insert(3, buildCountDivider()),
),
)
],
),
const HomeMenuCard(),
const HomeMessageCard(MessageType.Task),
const HomeMessageCard(MessageType.Message)
],
),
],
),
),
));
}
Container buildCountDivider() {
return Container(
height: 30,
child: const Opacity(
opacity: 0.4,
child: VerticalDivider(
color: Colors.white,
thickness: 1,
),
),
);
}
Widget buildCountItem(String count, Color countColor, String description, Function onClick) {
return Expanded(
child: InkWell(
onTap: onClick,
child: Column(
children: [
Text(
count,
style: TextStyle(color: countColor, fontWeight: FontWeight.bold, fontSize: 25.px),
),
Opacity(
opacity: 0.9,
child: Text(
description,
style: TextStyle(color: Colors.white, fontSize: 16.px),
),
),
],
),
),
);
}
///获取统计信息
void getAlarmGiveStatistics() {
API.getAlarmGiveStatistics().then((value) {
if (value != null) {
setState(() {
_countList[2]['count'] = value['currentHiddenDanger'] ?? 0;
allCount += value['currentHiddenDanger'] ?? 0;
});
}
});
}
///当前警情
Future<void> getCurrentAlert() async {
var data = await API.commandHistoryList({'status': '0', 'orderTime': '1', 'pageNum': 1, 'pageSize': 1});
if (data != null) {
setState(() {
int count = int.parse(data['total'] ?? '0');
_countList[0]['count'] = count;
allCount += count;
});
}
}
///消防报警
Future<void> getFireAlarmFirstRecord() async {
Map<String, dynamic> query = {'pageNum': 1, 'pageSize': 20, 'isFirm': 'no', 'type': 'FIREALARM'};
var data = await API.getAlarmPage(query);
if (data != null && data['records'].isNotEmpty) {
setState(() {
int total = int.parse(data['total'] ?? '0');
_countList[1]['count'] += total;
allCount += total;
});
}
}
///故障告警
Future<void> getFaultAlarmFirstRecord() async {
Map<String, dynamic> query = {'pageNum': 1, 'pageSize': 20, 'isFirm': 'no', 'type': 'BREAKDOWN'};
var data = await API.getAlarmPage(query);
if (data != null && data['records'].isNotEmpty) {
setState(() {
int total = int.parse(data['total'] ?? '0');
_countList[1]['count'] += total;
allCount += total;
});
}
}
///在岗监测
Future<void> getIotMonitorEventFirstRecord() async {
Map<String, dynamic> query = {
'current': 1,
'size': 20,
'eventState': '未处理',
};
var data = await API.getMonitorEventPage(query);
if (data != null && data['records'].isNotEmpty) {
setState(() {
int total = int.parse(data['total'] ?? '0');
_countList[1]['count'] += total;
allCount += total;
});
}
}
}
import 'package:amos_flutter_ui/amos_flutter_ui.dart';
import 'package:amos_iot_login_tpl/amos_iot_login_tpl.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:jcs_airport/routes/routes.dart';
import 'package:jcs_airport/services/api.dart';
///@Description 首页物联监测
///@author helinlin
///@create 2021-10-29 9:44
class IotMonitor extends StatefulWidget {
static String iotMonitorFireControlWarning = 'iotMonitorFireControlWarning';
static String iotMonitorMalfunctionWarning = 'iotMonitorMalfunctionWarning';
static String iotMonitorIotWarning = 'iotMonitorIotWarning';
static String onGuardWarning = 'onGuardWarning';
const IotMonitor({Key key}) : super(key: key);
@override
_IotMonitorState createState() => _IotMonitorState();
}
class _IotMonitorState extends State<IotMonitor> {
List countData = [
{
'type': '消防报警:',
'image': 'assets/images/fire_warning.png',
'count': 0,
'firstRecord': {},
'onClick': () {
Get.toNamed(JCSRoutes.alarmInfo, arguments: PlatformMenu(frontComponent: IotMonitor.iotMonitorFireControlWarning));
}
},
{
'type': '故障告警:',
'image': 'assets/images/fault_warning.png',
'count': 0,
'firstRecord': {},
'onClick': () {
Get.toNamed(JCSRoutes.alarmInfo, arguments: PlatformMenu(frontComponent: IotMonitor.iotMonitorMalfunctionWarning));
}
},
{
'type': '在岗监测:',
'image': 'assets/images/iot_warning.png',
'count': 0,
'firstRecord': {},
'onClick': () {
Get.toNamed(JCSRoutes.monitorEvent, arguments: PlatformMenu(frontComponent: IotMonitor.onGuardWarning));
}
},
];
@override
void initState() {
super.initState();
//getCount();
getFireAlarmFirstRecord();
getFaultAlarmFirstRecord();
getIotMonitorEventFirstRecord();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('物联监测'),
),
body: Column(
children: [
ListView.builder(
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemBuilder: (BuildContext context, int index) {
return CommonCard(
child: InkWell(
onTap: countData[index]['onClick'],
child: Padding(
padding: const EdgeInsets.all(15.0),
child: Row(
children: [
Padding(
padding: const EdgeInsets.only(right: 8.0),
child: Image.asset(
countData[index]['image'],
width: 45,
),
),
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Row(
children: [
Text(
countData[index]['type'],
style: const TextStyle(fontSize: 16),
),
const SizedBox(
width: 5,
),
Text('${countData[index]['count']}', style: const TextStyle(fontSize: 16)),
],
),
countData[index]['firstRecord'].isNotEmpty
? Column(
children: [
const SizedBox(
height: 5,
),
Opacity(
opacity: 0.6,
child: Row(
children: [
Expanded(
child: Text(
'${countData[index]['firstRecord']['fireEquipmentName'] ?? countData[index]['firstRecord']['videoName'] ?? ''}',
style: const TextStyle(fontSize: 14),
overflow: TextOverflow.ellipsis,
),
),
Expanded(
child: Text(
'${countData[index]['firstRecord']['createDate'] ?? ''}',
style: const TextStyle(fontSize: 14),
overflow: TextOverflow.ellipsis,
),
)
],
),
)
],
)
: Container(),
],
),
),
],
),
),
),
);
},
itemCount: countData.length)
],
),
);
}
Future<void> getCount() async {
Future.delayed(Duration.zero, () {
MsgBox.showProgressDialog(context, content: '加载中,请稍后。。。');
API.getFireAndDutyAndIOT().then((value) {
if (value != null) {
setState(() {
countData[0]['count'] = value['fireNum'];
countData[1]['count'] = value['faultAlarmNum'];
countData[2]['count'] = value['iotNum'];
});
}
}).whenComplete(() => Get.back());
});
}
///消防报警
Future<void> getFireAlarmFirstRecord() async {
Map<String, dynamic> query = {'pageNum': 1, 'pageSize': 20, 'isFirm': 'no', 'type': 'FIREALARM'};
var data = await API.getAlarmPage(query);
if (data != null && data['records'].isNotEmpty) {
setState(() {
countData[0]['firstRecord'] = data['records'].first ?? {};
countData[0]['count'] = int.parse(data['total'] ?? '0');
});
}
}
///故障告警
Future<void> getFaultAlarmFirstRecord() async {
Map<String, dynamic> query = {'pageNum': 1, 'pageSize': 20, 'isFirm': 'no', 'type': 'BREAKDOWN'};
var data = await API.getAlarmPage(query);
if (data != null && data['records'].isNotEmpty) {
setState(() {
countData[1]['firstRecord'] = data['records'].first ?? {};
countData[1]['count'] = int.parse(data['total'] ?? '0');
});
}
}
///在岗监测
Future<void> getIotMonitorEventFirstRecord() async {
Map<String, dynamic> query = {
'current': 1,
'size': 20,
'eventState': '未处理',
};
var data = await API.getMonitorEventPage(query);
if (data != null && data['records'].isNotEmpty) {
setState(() {
countData[2]['firstRecord'] = data['records'].first ?? {};
countData[2]['count'] = int.parse(data['total'] ?? '0');
});
}
}
}
import 'package:flutter/material.dart';
import 'package:amos_flutter_utils/amos_flutter_utils.dart';
import '../../widgets/back_button.dart';
class NotFoundPage extends StatelessWidget {
const NotFoundPage();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('未知页面'),
),
body: buildContent(),
);
}
Widget buildContent() {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Image.asset(
'assets/images/not_found.png',
width: 128.px,
),
SizedBox(
height: 36.px,
),
Text(
'抱歉,您访问的页面不存在',
style: TextStyle(fontSize: 12.px, color: const Color(0xFF999999)),
)
],
),
);
}
}
import 'package:amos_iot_login_tpl/mine/offline/color.dart';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:jcs_airport/view/sign/back_button.dart';
import 'package:jcs_airport/view/sign/SearchWidget.dart';
// 选择具体人员
class SelectDefectPersonList extends StatelessWidget {
List persons;
String title;
String flag;
SelectDefectPersonList(this.persons,this.title,this.flag);
@override
Widget build(BuildContext context) {
return SelectPersonListContent(persons,title,flag);
}
}
class SelectPersonListContent extends StatefulWidget {
List persons;
String title;
String flag;
SelectPersonListContent(this.persons,this.title,this.flag);
@override
_SelectPersonListContentState createState() => _SelectPersonListContentState(persons,title,flag);
}
class _SelectPersonListContentState extends State<SelectPersonListContent> {
List persons;
String title;
String flag;
_SelectPersonListContentState(this.persons, this.title, this.flag);
int _index;
String theme='';
@override
void initState() {
// TODO: implement initState
super.initState();
initThemeConfig();
}
initThemeConfig() async {
SharedPreferences.getInstance().then((preferences) {
setState(() {
this.theme =
preferences.getString("theme") ?? KColorConstant.DEFAULT_COLOR;
});
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Color(0xFFefeff4),
appBar: AppBar(
title: Text(widget.title,style: TextStyle(color: Colors.black),),
leading: LeadingButton(
theme:this.theme
),
centerTitle: true,
backgroundColor: Colors.white,
),
body:Column(
children: <Widget>[
buildSearch(),
Expanded(
// padding: EdgeInsets.only(bottom: _index == null? 0: 50.px),
child: ListView.builder(
itemCount: persons.length,
shrinkWrap: true,
itemBuilder: (ctx,index){
final item = persons[index];
String name = item["name"];
String fir = name.substring(0,1);
// String jobTitle = item["jobTitle"] == null ? '' : item["jobTitle"];
return InkWell(
onTap: (){
setState(() {
_index = index;
});
confirm(context);
},
child: Container(
alignment: Alignment(-1,0),
color: (index != _index? Colors.white : Colors.blue),
padding: EdgeInsets.fromLTRB(10.0, 13.0, 24.0, 13.0),
// style: Theme.of(context).textTheme.headline2.copyWith(color: index == _index? GetConfig.getColor(theme):Color(0xFF333333),)),
child: Container(
padding:
EdgeInsets.only(left: 0, top: 10, bottom: 10),
height: 80,
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Expanded(
child: CircleAvatar(
//'assets/images/login/username_blue.png',
//'assets/images/login/icon_person.svg',
//backgroundColor: Colors.grey[100],
radius: 30.0,
child: Text(fir)
),
flex: 0,
),
Expanded(
child: Container(
padding: EdgeInsets.only(
left: 10, top: 10, bottom: 5),
width: MediaQuery.of(context).size.width - 50,
child: Column(children: <Widget>[
Container(
alignment: Alignment(-1,0),
child: Text(
" $name",
textAlign: TextAlign.left,
style: TextStyle(
color: Colors.black,
fontSize: 15,
)
)
),
// Container(
// alignment: Alignment(-1,0),
// child: Text(
// " $jobTitle",
// textAlign: TextAlign.left,
// style: TextStyle(
// color: Colors.black,
// fontSize: 15,
// )
// )
// )
]
)),
// ),
flex: 9,
),
],
),
),
// ([
//
// ]),
// ,
// Text(
// "$title",
// style: Theme.of(context).textTheme.headline2.copyWith(color: index == _index? GetConfig.getColor(theme):Color(0xFF333333),)),
),
);
}
),
),
// _index == null? Container(): buildBottomButton(context)
],
));
}
// Widget buildBottomButton(context) {
// return Align(
// alignment: Alignment.bottomCenter,
// child: Container(
// height: 50.px,
// width: double.infinity,
// child: RaisedButton(
// color: GetConfig.getColor(theme),
// child: Text("确定",style: Theme.of(context).textTheme.headline2),
// onPressed: () => confirm(context),
// ),
// ),
// );
// }
// 确定
void confirm(BuildContext context) {
Map<String, String> map = new Map();
map.putIfAbsent("name", () => persons[_index]["name"]);
map.putIfAbsent("flag", () => this.flag);
Navigator.of(context).pop(map);
}
Widget buildSearch() => SearchWidget(
onEditingComplete: onchange
);
void onchange(key) {
final res = this.widget.persons.where((element) {
final entry = element["name"];
return entry.contains(key);
}).toList();
setState(() {
this.persons = res;
});
}
}
/// 计算公式 - 通用页面和结果页面
///
///
import 'package:flutter/material.dart';
import 'package:amos_flutter_ui/amos_flutter_ui.dart';
/// 通用计算 form page
class CommonFormulaPage extends StatelessWidget {
const CommonFormulaPage({Key key, this.title, this.formChild, this.onSubmit, this.onReset}) : super(key: key);
final String title;
final Widget formChild;
final Function onSubmit;
final Function onReset;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(title ?? ''),
),
body: CommonFormulaContent(
formChild: formChild,
onSubmit: onSubmit,
onReset: onReset,
),
);
}
}
/// 通用计算 form page
class FormulaButtonSubmit extends StatelessWidget {
const FormulaButtonSubmit({Key key, this.title, this.body, this.formChild, this.onSubmit, this.onReset})
: super(key: key);
final String title;
final Widget formChild;
/// 自定义 body,如果不为 null,则采用自定义的 body,此时 formChild 不起效
final Widget body;
final Function onSubmit;
final Function onReset;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(title ?? ''),
),
body: body ??
CommonFormulaContent(
formChild: formChild,
hasFooter: false,
),
/// 将计算按钮放置在最底部
persistentFooterButtons: [
Row(
children: [
Button(
width: (MediaQuery.of(context).size.width / 2) - 20,
background: Theme.of(context).primaryColor,
child: const Text('计算'),
onPressed: () {
onSubmit(context);
}),
const SizedBox(
width: 20,
),
Button(
width: (MediaQuery.of(context).size.width / 2) - 20,
background: const Color(0xffe3e3e3),
child: const Text(
'重置',
style: TextStyle(color: Color(0xff333333)),
),
onPressed: onReset,
),
],
),
],
);
}
}
class CommonFormulaContent extends StatelessWidget {
const CommonFormulaContent({Key key, this.formChild, this.onSubmit, this.onReset, this.hasFooter = true})
: super(key: key);
final Widget formChild;
final Function onSubmit;
final Function onReset;
/// 是否内置 footer,如果为 true,则需要传入 onSubmit 与 onReset
final bool hasFooter;
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: Column(children: [
formChild,
hasFooter
? FormFooter(
padding: const EdgeInsets.symmetric(vertical: 6, horizontal: 15.0),
child: Flex(direction: Axis.horizontal, children: [
Expanded(
flex: 1,
child: GradientButton(
color: const Color(0xff345fa6),
child: const Text('计算'),
onPressed: () {
onSubmit(context);
}),
),
Expanded(
flex: 1,
child: GradientButton(
color: const Color(0xffe3e3e3),
textColor: const Color(0xff333333),
child: const Text('重置'),
onPressed: onReset,
),
)
]),
)
: Container(),
]),
);
}
}
/// 通用计算结果面板
class CommonResultPanel extends StatelessWidget {
const CommonResultPanel({Key key, this.resultChild}) : super(key: key);
final Widget resultChild;
@override
Widget build(BuildContext context) {
return Container(
height: 360.0,
child: Column(
children: [
Padding(
padding: const EdgeInsets.symmetric(vertical: 16.0),
child: Center(
child: Column(
children: [
Image.asset(
'assets/dispatch/calc.png',
width: 45.0,
),
const Text('计算结果')
],
),
),
),
Expanded(
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 16.0, horizontal: 6.0),
child: resultChild,
),
),
Row(children: [
ExpandedButton(
height: 50.0,
child: const Text(
'重新计算',
style: TextStyle(color: Colors.white),
),
color: const Color(0xff345fa6),
onPressed: () {
Navigator.of(context).pop();
})
])
],
),
);
}
}
/// 计算结果页面
class CalcResultPanel extends StatelessWidget {
const CalcResultPanel({Key key, this.results}) : super(key: key);
final List<Map<String, dynamic>> results;
@override
Widget build(BuildContext context) {
return CommonResultPanel(
resultChild: ListView.separated(
separatorBuilder: (context, index) {
return const Divider(
height: 0,
);
},
itemBuilder: (context, index) {
Widget title;
Map item = results[index];
title = LabelValue(
label: item['title'],
value: '${item['value']}',
labelStyle: const TextStyle(fontSize: 16.0),
valueStyle: const TextStyle(fontSize: 16.0, fontWeight: FontWeight.bold),
);
return ListTile(
title: title,
);
},
itemCount: results.length ?? 0,
),
);
}
}
/// 计算公式 - 泡沫原液量
///
///
import 'package:flutter/material.dart';
import 'package:amos_flutter_ui/amos_flutter_ui.dart';
import './common_formula.dart';
/// 泡沫原液量
class FoamFluid extends StatefulWidget {
const FoamFluid({Key key}) : super(key: key);
@override
_FoamFluidState createState() => _FoamFluidState();
}
class _FoamFluidState extends State<FoamFluid> {
GlobalKey<FormState> formKey = GlobalKey<FormState>();
Map<String, dynamic> _config = {'mixRatio': 0.01, 'gunType': 4};
@override
Widget build(BuildContext context) {
return FormulaButtonSubmit(
title: '泡沫原液量计算',
formChild: AmosForm(
formKey: formKey,
children: renderAmosForm(context),
onChanged: (value) {
print('AmosForm changed: ${value.toString()}');
_config = value;
},
),
onSubmit: onSubmit,
onReset: onReset,
);
}
List<Widget> renderAmosForm(BuildContext context) {
return <Widget>[
FormItem(
layout: FormLayout.vertical,
label: '泡沫混合液供给强度(L/s·m²)',
invert: true,
formfield: AmosTextNumberField(
fieldKey: 'strength',
maxLines: 1,
),
),
FormItem(
layout: FormLayout.vertical,
label: '泡沫混合比',
invert: true,
formfield: AmosRadioGroup(
fieldKey: 'mixRatio',
initialValue: _config['mixRatio'],
layout: RadioGroupLayout.horizontal,
mini: true,
options: const [
{'title': '1%', 'value': 0.01},
{'title': '2%', 'value': 0.02},
{'title': '6%', 'value': 0.06},
],
),
),
FormItem(
layout: FormLayout.vertical,
label: '液体燃烧面积(L/s·m²)',
invert: true,
formfield: AmosTextNumberField(
fieldKey: 'area',
maxLines: 1,
),
),
FormItem(
layout: FormLayout.vertical,
label: '供液时间(分钟)',
invert: true,
formfield: AmosTextNumberField(
fieldKey: 'time',
maxLines: 1,
),
),
FormItem(
layout: FormLayout.vertical,
label: '泡沫枪型号',
invert: true,
formfield: AmosRadioGroup(
fieldKey: 'gunType',
initialValue: _config['gunType'],
layout: RadioGroupLayout.horizontal,
mini: true,
options: const [
{'title': 'PQ4', 'value': 4},
{'title': 'PQ8', 'value': 8},
{'title': 'PQ16', 'value': 16},
],
),
),
FormItem(
layout: FormLayout.vertical,
label: '泡沫炮流量(L/s)',
invert: true,
formfield: AmosTextNumberField(
fieldKey: 'liquidRate',
maxLines: 1,
),
),
FormItem(
layout: FormLayout.vertical,
label: '泡沫钩管流量(L/s)',
invert: true,
formfield: AmosTextNumberField(
fieldKey: 'hookRate',
maxLines: 1,
),
),
];
}
void onSubmit(context) {
if (!FoamFluidValue.check(_config)) {
shortMessage('计算参数不能为空');
return;
}
FoamFluidValue ffv = FoamFluidValue.fromMap(_config);
showBottomSheetDialog(
context: context,
builder: (BuildContext context) {
return CalcResultPanel(results: FoamFluidValue.getResult(ffv));
});
}
void onReset() {
formKey.currentState.reset();
}
}
class FoamFluidValue {
/// v1
double strength;
/// v2
double mixRatio;
/// v3
double area;
/// v4
double time;
/// v5
int gunType;
/// v6
double liquidRate;
/// v7
double hookRate;
FoamFluidValue(
{this.strength,
this.mixRatio,
this.area,
this.time,
this.gunType,
this.liquidRate,
this.hookRate});
Map toJson() {
Map map = <String, dynamic>{};
map['strength'] = strength;
map['mixRatio'] = mixRatio;
map['area'] = area;
map['time'] = time;
map['gunType'] = gunType;
map['liquidRate'] = liquidRate;
map['hookRate'] = hookRate;
return map;
}
static bool check(Map<String, dynamic> map) {
String strength = map['strength'];
double mixRatio = map['mixRatio'];
String area = map['area'];
String time = map['time'];
int gunType = map['gunType'];
String liquidRate = map['liquidRate'];
String hookRate = map['hookRate'];
if (strength == null ||
strength.isEmpty ||
mixRatio == null ||
area == null ||
area.isEmpty ||
time == null ||
time.isEmpty ||
gunType == null ||
liquidRate == null ||
liquidRate.isEmpty ||
hookRate == null ||
hookRate.isEmpty) {
return false;
}
return true;
}
static FoamFluidValue fromMap(Map<String, dynamic> map) {
FoamFluidValue ffv = FoamFluidValue(
strength: double.parse(map['strength'] ?? ''),
mixRatio: map['mixRatio'],
area: double.parse(map['area'] ?? ''),
time: double.parse(map['time'] ?? ''),
gunType: map['gunType'],
liquidRate: double.parse(map['liquidRate'] ?? ''),
hookRate: double.parse(map['hookRate'] ?? ''),
);
return ffv;
}
/// 需泡沫原液量(L)
static double calcLiquid(FoamFluidValue ffv) {
double liquid = ffv.strength * ffv.mixRatio * ffv.area * ffv.time * 60;
/// 保留两位小数
return double.parse(liquid.toStringAsFixed(2));
}
static String calcLiquidStr(FoamFluidValue ffv) {
double liquid = calcLiquid(ffv);
return '${liquid}L 或 ${(liquid / 1000).toStringAsFixed(4)}吨';
}
/// 需泡沫枪数量(支), 向上取整
static int calcGun(FoamFluidValue ffv) {
double gun = ffv.strength * ffv.area / ffv.gunType;
/// 保留两位小数
return gun.ceil();
}
/// 需泡沫炮数量(门), 向上取整
static int calcCannon(FoamFluidValue ffv) {
double gun = ffv.strength * ffv.area / ffv.liquidRate;
/// 保留两位小数
return gun.ceil();
}
/// 需泡沫枪数量(架), 向上取整
static int calcGuns(FoamFluidValue ffv) {
double gun = ffv.strength * ffv.area / ffv.hookRate;
/// 保留两位小数
return gun.ceil();
}
/// 计算结果
static List<Map<String, dynamic>> getResult(FoamFluidValue ffv) {
String liquid = calcLiquidStr(ffv);
int gun = calcGun(ffv);
int cann = calcCannon(ffv);
int gun2 = calcGuns(ffv);
List<Map<String, dynamic>> res = [];
res.add({'title': '需泡沫原液量', 'value': '$liquid'});
res.add({'title': '需泡沫枪数量', 'value': '$gun 支 或$gun2 架'});
res.add({'title': '需泡沫炮数量', 'value': '$cann 门'});
return res;
}
}
/// 计算公式 - 液化烃球罐冷却用水量
///
///
import 'package:flutter/material.dart';
import 'package:amos_flutter_ui/amos_flutter_ui.dart';
import './common_formula.dart';
import './vertical_tank_water.dart';
/// 液化烃球罐冷却用水量
class HydrocarbonTank extends StatefulWidget {
const HydrocarbonTank({Key key}) : super(key: key);
@override
_HydrocarbonTankState createState() => _HydrocarbonTankState();
}
class _HydrocarbonTankState extends State<HydrocarbonTank>
with SingleTickerProviderStateMixin {
TabController tabController;
GlobalKey<FormState> oneformKeyformKey = GlobalKey<FormState>();
Map<String, dynamic> _oneConfig = {'strength': '0.2', 'time': '6'};
GlobalKey<FormState> twoformKeyformKey = GlobalKey<FormState>();
Map<String, dynamic> _twoConfig = {'strength': '0.2', 'time': '6'};
GlobalKey<FormState> threeformKeyformKey = GlobalKey<FormState>();
Map<String, dynamic> _threeConfig = {};
@override
void initState() {
super.initState();
tabController = TabController(length: 3, vsync: this);
}
@override
Widget build(BuildContext context) {
return FormulaButtonSubmit(
title: '液化烃球罐冷却用水量',
onSubmit: onSubmit,
onReset: onReset,
body: Container(
child: Column(
children: [
Container(
height: 42,
child: TabBar(
labelColor: Colors.black,
isScrollable: true,
unselectedLabelColor: Colors.black54,
indicatorSize: TabBarIndicatorSize.label,
indicatorColor: Colors.lightBlue,
tabs: const [
Tab(text: '着火罐冷却用水量'),
Tab(text: '冷近罐冷却用水量'),
Tab(text: '冷却枪炮数量')
],
controller: tabController,
)),
Expanded(
child: TabBarView(
children: [
CommonFormulaContent(
formChild: AmosForm(
formKey: oneformKeyformKey,
children: renderTabOneForm(context),
onChanged: (value) {
_oneConfig = value;
},
),
hasFooter: false,
),
CommonFormulaContent(
formChild: AmosForm(
formKey: twoformKeyformKey,
children: renderTabTwoForm(context),
onChanged: (value) {
_twoConfig = value;
},
),
hasFooter: false,
),
CommonFormulaContent(
formChild: AmosForm(
formKey: threeformKeyformKey,
children: renderTabThreeForm(context),
onChanged: (value) {
_threeConfig = value;
},
),
hasFooter: false,
),
],
controller: tabController,
))
],
)));
}
List<Widget> renderTabOneForm(BuildContext context) {
return <Widget>[
FormItem(
layout: FormLayout.vertical,
label: '着火罐直径(m)',
invert: true,
formfield: AmosTextNumberField(
fieldKey: 'diameter',
maxLines: 1,
),
),
FormItem(
layout: FormLayout.vertical,
label: '着火罐冷却水供给强度(L/s*m)',
invert: true,
formfield: AmosTextNumberField(
initialValue: _oneConfig['strength'],
fieldKey: 'strength',
maxLines: 1,
),
),
FormItem(
layout: FormLayout.vertical,
label: '着火罐数量(个)',
invert: true,
formfield: AmosTextNumberField(
fieldKey: 'count',
maxLines: 1,
),
),
FormItem(
layout: FormLayout.vertical,
label: '冷却持续时间(小时)',
invert: true,
formfield: AmosTextNumberField(
initialValue: _oneConfig['time'],
fieldKey: 'time',
maxLines: 1,
),
)
];
}
List<Widget> renderTabTwoForm(BuildContext context) {
return <Widget>[
FormItem(
layout: FormLayout.vertical,
label: '冷近罐直径(m)',
invert: true,
formfield: AmosTextNumberField(
fieldKey: 'diameter',
maxLines: 1,
),
),
FormItem(
layout: FormLayout.vertical,
label: '冷近罐冷却水供给强度(L/s·m²)',
invert: true,
formfield: AmosTextNumberField(
initialValue: _twoConfig['strength'],
fieldKey: 'strength',
maxLines: 1,
),
),
FormItem(
layout: FormLayout.vertical,
label: '冷近罐数量(个)',
invert: true,
formfield: AmosTextNumberField(
fieldKey: 'count',
maxLines: 1,
),
),
FormItem(
layout: FormLayout.vertical,
label: '冷却持续时间(小时)',
invert: true,
formfield: AmosTextNumberField(
initialValue: _twoConfig['time'],
fieldKey: 'time',
maxLines: 1,
),
)
];
}
List<Widget> renderTabThreeForm(BuildContext context) {
return <Widget>[
FormItem(
layout: FormLayout.vertical,
label: '水枪流量(m)',
invert: true,
formfield: AmosTextNumberField(
fieldKey: 'gunsCount',
maxLines: 1,
),
),
FormItem(
layout: FormLayout.vertical,
label: '移动炮流量(m)',
invert: true,
formfield: AmosTextNumberField(
fieldKey: 'moveGunsCount',
maxLines: 1,
),
)
];
}
void onSubmit(context) {
if (tabController.index == 0) {
if (!CatchFireValue.check(_oneConfig)) {
shortMessage('计算参数不能为空');
return;
}
CatchFireValue ffv = CatchFireValue.fromMap(_oneConfig);
showBottomSheetDialog(
context: context,
builder: (BuildContext context) {
return CalcResultPanel(results: CatchFireValue.getResult(ffv));
});
}
if (tabController.index == 1) {
if (!ColdFireValue.check(_twoConfig)) {
shortMessage('计算参数不能为空');
return;
}
ColdFireValue ffv = ColdFireValue.fromMap(_twoConfig);
showBottomSheetDialog(
context: context,
builder: (BuildContext context) {
return CalcResultPanel(results: ColdFireValue.getResult(ffv));
});
}
if (tabController.index == 2) {
if (!ColdgunsCountValue.check(_threeConfig)) {
shortMessage('计算参数不能为空');
return;
}
ColdgunsCountValue ffv = ColdgunsCountValue.fromMap(_threeConfig);
showBottomSheetDialog(
context: context,
builder: (BuildContext context) {
return CalcResultPanel(results: ColdgunsCountValue.getResult(ffv));
});
}
}
void onReset() {
if (tabController.index == 0) {
oneformKeyformKey.currentState.reset();
}
if (tabController.index == 1) {
twoformKeyformKey.currentState.reset();
}
if (tabController.index == 2) {
threeformKeyformKey.currentState.reset();
}
}
}
/// 冷却枪炮数量
class ColdgunsCountValue {
/// 水枪流量
double gunsCount;
/// 移动炮流量
double moveGunsCount;
ColdgunsCountValue({this.gunsCount, this.moveGunsCount});
Map toJson() {
Map map = <String, dynamic>{};
map['gunsCount'] = gunsCount;
map['moveGunsCount'] = moveGunsCount;
return map;
}
static bool check(Map<String, dynamic> map) {
String gunsCount = map['gunsCount'];
String moveGunsCount = map['moveGunsCount'];
if (gunsCount == null ||
gunsCount.isEmpty ||
moveGunsCount == null ||
moveGunsCount.isEmpty) {
return false;
}
return true;
}
static ColdgunsCountValue fromMap(Map<String, dynamic> map) {
ColdgunsCountValue ffv = ColdgunsCountValue(
gunsCount: double.parse(map['gunsCount'] ?? ''),
moveGunsCount: double.parse(map['moveGunsCount'] ?? ''));
return ffv;
}
/// 计算冷却水枪数量(支)
static int calcOne(ColdgunsCountValue ffv) {
int liquid = (1000 / ffv.gunsCount).ceil();
return liquid;
}
/// 计算冷却移动炮数量(门)
static int calcTwo(ColdgunsCountValue ffv) {
int liquid = (1000 / ffv.moveGunsCount).ceil();
return liquid;
}
/// 计算结果
static List<Map<String, dynamic>> getResult(ColdgunsCountValue ffv) {
int one = calcOne(ffv);
int two = calcTwo(ffv);
List<Map<String, dynamic>> res = [];
res.add({'title': '冷却水枪数量', 'value': '$one 支'});
res.add({'title': '冷却移动炮数量', 'value': '$two 门'});
return res;
}
}
/// 计算公式
///
///
export './foam_fluid.dart';
export './hydrocarbon_tank.dart';
export './pipe_water.dart';
export './vertical_tank_water.dart';
\ No newline at end of file
/// 计算公式 - 管网供水能力
///
///
import 'package:flutter/material.dart';
import 'package:amos_flutter_ui/amos_flutter_ui.dart';
import './common_formula.dart';
/// 管网供水能力
class PipeWater extends StatefulWidget {
const PipeWater({Key key}) : super(key: key);
@override
_PipeWaterState createState() => _PipeWaterState();
}
class _PipeWaterState extends State<PipeWater> {
GlobalKey<FormState> oneformKeyformKey = GlobalKey<FormState>();
Map<String, dynamic> _oneConfig = {'speed': 1.0};
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return FormulaButtonSubmit(
title: '管网供水能力',
formChild: AmosForm(
formKey: oneformKeyformKey,
children: renderTabOneForm(context),
onChanged: (value) {
_oneConfig = value;
},
),
onSubmit: onSubmit,
onReset: onReset,
);
}
List<Widget> renderTabOneForm(BuildContext context) {
return <Widget>[
FormItem(
layout: FormLayout.vertical,
label: '供水管网直径(m)',
invert: true,
formfield: AmosTextNumberField(
fieldKey: 'diameter',
maxLines: 1,
),
),
FormItem(
layout: FormLayout.vertical,
label: '管网内水流速',
invert: true,
formfield: AmosRadioGroup(
fieldKey: 'speed',
initialValue: _oneConfig['speed'],
options: const [
{'title': '支状管网1m/s', 'value': 1.0},
{'title': '环状管网1.5m/s', 'value': 1.5}
],
),
),
FormItem(
layout: FormLayout.vertical,
label: '消防车泵流量(L/s)',
invert: true,
formfield: AmosTextNumberField(
fieldKey: 'count',
maxLines: 1,
),
)
];
}
void onSubmit(context) {
if (!PipeValue.check(_oneConfig)) {
shortMessage('计算参数不能为空');
return;
}
PipeValue ffv = PipeValue.fromMap(_oneConfig);
showBottomSheetDialog(
context: context,
builder: (BuildContext context) {
return CalcResultPanel(results: PipeValue.getResult(ffv));
});
}
void onReset() {
oneformKeyformKey.currentState.reset();
}
}
/// 管网供水能力
class PipeValue {
/// 供水管网直径
double diameter;
/// 管网内水流速
double speed;
/// 消防车泵流量
double count;
PipeValue({this.diameter, this.speed, this.count});
Map toJson() {
Map map = <String, dynamic>{};
map['speed'] = speed;
map['count'] = count;
map['diameter'] = diameter;
return map;
}
static bool check(Map<String, dynamic> map) {
String diameter = map['diameter'];
double speed = map['speed'];
String count = map['count'];
if (diameter == null ||
diameter.isEmpty ||
count == null ||
count.isEmpty ||
speed == null) {
return false;
}
return true;
}
static PipeValue fromMap(Map<String, dynamic> map) {
PipeValue ffv = PipeValue(
count: double.parse(map['count'] ?? ''),
diameter: double.parse(map['diameter'] ?? ''),
speed: map['speed']);
return ffv;
}
/// 计算管网供水流量(L/s)
static double calcOne(PipeValue ffv) {
double liquid = double.parse(
(ffv.diameter * ffv.diameter * 0.0008 * ffv.speed).toStringAsFixed(2));
return liquid;
}
/// 计算停靠消防车数量(辆)
static int calcTwo(PipeValue ffv) {
double liquid = double.parse(
(ffv.diameter * ffv.diameter * 0.0008 * ffv.speed).toStringAsFixed(2));
return (liquid / ffv.count).ceil();
}
/// 计算结果
static List<Map<String, dynamic>> getResult(PipeValue ffv) {
double one = calcOne(ffv);
int two = calcTwo(ffv);
List<Map<String, dynamic>> res = [];
res.add({'title': '管网供水流量', 'value': '$one L/s'});
res.add({'title': '停靠消防车数量', 'value': '$two 辆'});
return res;
}
}
import 'package:amos_flutter_ui/card/common_card.dart';
import 'package:amos_flutter_ui/common/index.dart';
import 'package:flutter/material.dart';
import 'package:full_screen_image/full_screen_image.dart';
import 'package:jcs_airport/services/api.dart';
import 'package:amos_iot_login_tpl/const/global_config.dart';
///@Description 重点部位
///@author helinlin
///@create 2022-01-17 17:05
class ImportantPoint extends StatefulWidget {
final String sequenceNbr;
const ImportantPoint({Key key, this.sequenceNbr}) : super(key: key);
@override
_ImportantPointState createState() => _ImportantPointState();
}
class _ImportantPointState extends State<ImportantPoint> {
Map keySiteInfo = {
'attachmentsList': [] //照片
}; //重点部位信息
//List<String> images = ['assets/11.jpg', 'assets/11.jpg', 'assets/11.jpg'];
String imageUrl = '';
@override
void initState() {
super.initState();
_getkeySite(widget.sequenceNbr);
APIUrlManager.getImageUrl().then((value) {
setState(() {
imageUrl = value;
});
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('重点部位'),
),
body: SingleChildScrollView(
child: Column(
children: [
CommonCard(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(children: [
buildRow('重点部位名称', keySiteInfo['name']),
buildRow('所属部门', keySiteInfo['belongName']),
buildRow('所在建筑', keySiteInfo['buildingName']),
buildRow('位置描述', keySiteInfo['addressDesc']),
buildRow('建筑面积(㎡)', keySiteInfo['buildingArea']),
buildRow('耐火等级', keySiteInfo['fireEnduranceRateName']),
buildRow('使用性质', keySiteInfo['useNatureName']),
buildRow('责任人', keySiteInfo['chargePerson']),
buildRow('确定重点防火部位原因', keySiteInfo['keyPreventionReason']),
buildRow('消防设施情况', (keySiteInfo['firePreventionFlag'] ?? false) ? '已设立' : '未设立'),
buildRow('危险源', keySiteInfo['hazard']),
buildRow('消防安全管理措施', keySiteInfo['safetyManagementMeasures']),
buildRow('防范手段和措施', keySiteInfo['preventiveMeasures']),
const SizedBox(
height: 5,
),
// SingleChildScrollView(
// child:
// Row(
// children: (keySiteInfo['attachmentsList'] ?? [])
// .map((image) => Padding(
// padding: const EdgeInsets.all(8.0),
// child:
// FullScreenWidget(
// disposeLevel: DisposeLevel.Low,
// child: Image.asset(
// image,
// width: 100,
// ),
// ),
// ))
// .cast<Widget>()
// .toList(),
// ),
// )
Padding(
padding: const EdgeInsets.all(4.0),
child: Column(
children: [
const Text('重点部位照片'),
const SizedBox(
height: 5,
),
keySiteInfo['attachmentsList'].isEmpty
? const Opacity(
opacity: 0.6,
child: Text(
'暂无',
style: TextStyle(fontSize: 12),
),
)
: buildGridimg(keySiteInfo['attachmentsList'])
],
),
),
]),
),
)
],
),
),
);
}
// Widget buildGrid(List formList) {
// List<Widget> tiles = [];//先建一个数组用于存放循环生成的widget
// Widget content; //单独一个widget组件,用于返回需要生成的内容widget
// for(var item in formList) {
// tiles.add(
// FullScreenWidget(
// disposeLevel: DisposeLevel.Low,
// child:
// Image.network(
// imageUrl + item,
// width: 100,
// ),
// )
// );
// }
// content = Row(
// mainAxisAlignment: MainAxisAlignment.start,
// children:
// tiles//重点在这里,因为用编辑器写Column生成的children后面会跟一个<Widget>[],
// );
// return tiles;
// }
Widget buildGridimg(List formList) {
List<Widget> tiles = [];//先建一个数组用于存放循环生成的widget
for(var item in formList) {
tiles.add(
FullScreenWidget(
disposeLevel: DisposeLevel.Low,
child:
Image.network(
imageUrl + item,
width: 100,
),
)
);
}
return Wrap(
spacing: 2, //主轴上子控件的间距
runSpacing: 5, //交叉轴上子控件之间的间距
children: tiles, //要显示的子控件集合
);
}
Widget buildRow(String title, String content) {
return Padding(
padding: const EdgeInsets.only(bottom: 5.0),
child: Row(
children: [
Expanded(child: Text(title + ':')),
Expanded(child: Text(content ?? '')),
],
),
);
}
///获取重点部位
void _getkeySite(String sequenceNbr) {
API.getkeySite(sequenceNbr).then((value) {
if (value != null) {
setState(() {
keySiteInfo.addAll(value);
});
}
});
}
}
/// 重新设置警情位置
///
///
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
import './../h5_base_map.dart';
/// 点击工具来,重新设置警情位置
class AlarmPositionSet extends StatefulWidget {
const AlarmPositionSet(
{Key key, this.callh5, this.h5Url, this.alarmId, this.token})
: super(key: key);
final String alarmId;
final String token;
final String h5Url;
/// main map 向 H5 端发送指令
final Function callh5;
@override
_AlarmPositionSetState createState() => _AlarmPositionSetState();
}
class _AlarmPositionSetState extends State<AlarmPositionSet> {
WebViewController webViewController;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('警情定位'),
actions: <Widget>[
IconButton(
icon: const Icon(
Icons.save,
color: Colors.white,
),
onPressed: () {
/// 通知 h5 端进行警情定位保存
executeJs('alarmPointSave("goBack")');
},
)
],
),
body: Stack(
children: [
Container(
child: H5MapBase(
h5Url:
'${widget.h5Url}?token=${widget.token}&page=alarmPoint&alarmId=${widget.alarmId ?? ''}',
onCreated: (wvc) => {webViewController = wvc}))
],
));
}
void executeJs(String method, {dynamic data}) {
webViewController.evaluateJavascript('$method()');
}
}
/// 集结点设定
///
///
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
import './../h5_base_map.dart';
class AssemblyPointSet extends StatefulWidget {
const AssemblyPointSet(
{Key key,
this.assemblyPointId,
this.h5Url,
this.alarmId,
this.callh5,
this.token})
: super(key: key);
/// 集结点Id
final String assemblyPointId;
/// 警情ID
final String alarmId;
final String token;
final String h5Url;
/// main map 向 H5 端发送指令
final Function callh5;
@override
_AssemblyPointSetState createState() => _AssemblyPointSetState();
}
class _AssemblyPointSetState extends State<AssemblyPointSet> {
WebViewController webViewController;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('集结区设定'),
actions: <Widget>[
IconButton(
icon: const Icon(
Icons.save,
color: Colors.white,
),
onPressed: () {
/// 通知 h5 端进行集结区保存
executeJs('assemblyPointSave("goBack")');
},
)
],
),
body: Stack(
children: [
Container(
child: H5MapBase(
h5Url:
'${widget.h5Url}?token=${widget.token}&page=assemblyPoint&alarmId=${widget.alarmId ?? ''}&assemblyPointId=${widget.assemblyPointId ?? ''}',
onCreated: (wvc) => {webViewController = wvc}))
],
));
}
/// 当前 webview 向 h5 执行方法
void executeJs(String method, {dynamic data}) {
webViewController.evaluateJavascript('$method()');
}
}
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'package:webview_flutter/platform_interface.dart';
import 'package:flutter/src/widgets/navigator.dart';
import 'package:base/view/ImageViewPage.dart';
///@Description 富文本指令流
///@author helinlin
///@create 2022-06-01 14:37
class CommandStream extends StatefulWidget {
List commandFlows;
CommandStream({Key key, this.commandFlows}) : super(key: key);
@override
_CommandStreamState createState() => _CommandStreamState();
}
class _CommandStreamState extends State<CommandStream> {
WebViewController webViewController;
String path = 'assets/html/command_stream.html';
String jsPath = 'assets/html/js/vue.min.js';
@override
void didChangeDependencies() {
super.didChangeDependencies();
initVueInstence();
}
@override
void didUpdateWidget(covariant CommandStream oldWidget) {
super.didUpdateWidget(oldWidget);
initVueInstence();
}
@override
Widget build(BuildContext context) {
return WebView(
initialUrl: '',
javascriptMode: JavascriptMode.unrestricted,
onWebViewCreated: (WebViewController wvc) {
webViewController = wvc;
_loadHtmlFromAssets();
},
onPageStarted: (String url) {
print(url);
},
onPageFinished: (String url) {
print(url);
_loadJsFromAssets();
},
onWebResourceError: (WebResourceError error) {
print(error);
},
// JS和Flutter通信的Channel
javascriptChannels: <JavascriptChannel>{
_alertJavascriptChannel(context),
},
);
}
Future<void> initVueInstence()async{
if(webViewController==null){return;}
await _loadHtmlFromAssets();
await _loadJsFromAssets();
}
/// 加载js资源
Future<void> _loadJsFromAssets() async {
String jsContents = await rootBundle.loadString(jsPath);
//加载Vue
webViewController.evaluateJavascript(jsContents);
String jsonResult = json.encode(widget.commandFlows);
//传递参数,初始化Vue
webViewController.evaluateJavascript('init($jsonResult)');
}
/// 加载HTML资源
Future<void> _loadHtmlFromAssets() async {
String fileHtmlContents = await rootBundle.loadString(path);
String result=Uri.dataFromString(fileHtmlContents, mimeType: 'text/html', encoding: Encoding.getByName('utf-8')).toString();
webViewController.loadUrl(result);
}
/// JS和Flutter通信的Channel
JavascriptChannel _alertJavascriptChannel(BuildContext context) {
return JavascriptChannel(
name: 'GetImgUrl',
onMessageReceived: (JavascriptMessage message) {
print(message.message);
List<String> imgList = [];
imgList.add(message.message);
Navigator.push(context, MaterialPageRoute(builder: (context) {
return PhotoViewPage(imgList);
}));
});
}
}
import 'package:flutter/material.dart';
import 'package:amos_flutter_ui/amos_flutter_ui.dart';
import 'package:amos_flutter_utils/amos_flutter_utils.dart';
import './../entity/alarm_disaster.dart';
import './../entity/assembley_point.dart';
import './../event_bus.dart';
import './../native_bridge.dart';
import './assembly_point.dart';
import './realtime_distance.dart';
/// 集结点编辑
class EditAssembleyPoint extends StatefulWidget {
const EditAssembleyPoint(
{Key key,
this.callJSMethod,
this.assembleyPoint,
this.token,
this.h5Url,
this.controller,
this.currentLngLat,
this.alarmDisaster})
: super(key: key);
final ExecuteJSMethod callJSMethod;
final AlarmDisaster alarmDisaster;
final String h5Url;
final AssembleyPoint assembleyPoint;
final ScrollController controller;
final String token;
final Map currentLngLat;
@override
_EditAssembleyPointState createState() => _EditAssembleyPointState();
}
class _EditAssembleyPointState extends State<EditAssembleyPoint> {
@override
Widget build(BuildContext context) {
return ListView(
controller: widget.controller,
padding: const EdgeInsets.fromLTRB(10, 0, 10, 0),
children: <Widget>[buildBasicInfo(context)]);
}
/// 基本信息
Widget buildBasicInfo(BuildContext context) {
AlarmDisaster alarm = widget.alarmDisaster ?? AlarmDisaster();
AssembleyPoint assembleyPoint = widget.assembleyPoint ?? AssembleyPoint();
Function callback = widget.callJSMethod;
return Container(
child: Column(children: [
Container(
child: Row(children: [
RealtimeDistance(
callJSMethod: widget.callJSMethod,
targetLanLat: {
'latitude': assembleyPoint.latitude,
'longitude': assembleyPoint.longitude
},
currentLngLat: widget.currentLngLat,
distance: alarm.distance,
msgType: EventDataType.Self2AlarmDistance,
style: const TextStyle(
color: Color(0xff333333),
fontWeight: FontWeight.bold,
fontSize: 18))
])),
Container(child: Row(children: [Text('车辆集结区')])),
Container(
height: 25.0,
child: Row(children: [
const Expanded(child: SizedBox(width: 100)),
OutlineButton(
shape: const RoundedRectangleBorder(
side: BorderSide.none,
borderRadius: BorderRadius.all(Radius.circular(50))),
textColor: CoreColors.textColor,
padding: EdgeInsets.zero,
child: const Text(
'修改',
style: TextStyle(fontSize: 12),
),
onPressed: () {
Navigator.push(context, MaterialPageRoute(builder: (context) {
return AssemblyPointSet(
callh5: callback,
alarmId: alarm.sequenceNbr,
h5Url: widget.h5Url,
assemblyPointId: assembleyPoint.sequenceNbr,
token: widget.token);
})).then((value) {
if (value != null) {
/// 保存完集结点之后,执行刷新操作
/// 采用 callback 执行主地图消息
// callback('refreshAssemblyPoint()');
callback('$value()');
}
});
}),
const Text(' '),
OutlineButton(
shape: const RoundedRectangleBorder(
side: BorderSide.none,
borderRadius: BorderRadius.all(Radius.circular(50))),
textColor: CoreColors.textColor,
padding: EdgeInsets.zero,
child: const Text(
'导航',
style: TextStyle(fontSize: 12),
),
onPressed: () {
/// 直接唤起高德、百度 app
showBottomSheetList(
context: context,
items: ['腾讯地图', '百度地图', '高德地图'],
onItemTap: (int index, String item) {
if (widget.assembleyPoint.longitude == null ||
widget.assembleyPoint.latitude == null) {
return null;
}
switch (index) {
case 0:
List<num> latlng = GISUtil.gps84_To_Gcj02(double.parse(assembleyPoint.latitude),
double.parse(assembleyPoint.longitude));
CallMapUtil.callTencentMap(latlng[1], latlng[0]);
break;
case 1:
List<num> latlng = GISUtil.gps84_To_bd09(double.parse(assembleyPoint.latitude),
double.parse(assembleyPoint.longitude));
CallMapUtil.callBaiduMap(latlng[1], latlng[0]);
break;
case 2:
List<num> latlng = GISUtil.gps84_To_Gcj02(double.parse(assembleyPoint.latitude),
double.parse(assembleyPoint.longitude));
CallMapUtil.callAMap(latlng[1], latlng[0]);
break;
default:
}
});
})
]),
)
]));
}
}
import 'package:flutter/material.dart';
import 'package:amos_flutter_ui/amos_flutter_ui.dart';
import '../../../services/api.dart';
/// 车辆状态
class CarInfo extends StatefulWidget {
const CarInfo(this.alarmId, this.carInfo);
final String alarmId;
final dynamic carInfo;
@override
_CarInfoState createState() => _CarInfoState();
}
class _CarInfoState extends State<CarInfo> {
List staskSquadrons = [];
String selectKey = '';
dynamic usrInfo;
List<Map<String, String>> _resourceMaps = [];
@override
void initState() {
super.initState();
getCarStatusList();
}
@override
Widget build(BuildContext context) {
return Positioned(
top: 10,
right: 5.0,
child: Container(
height: 30,
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(8.0))),
child: Stack(alignment: AlignmentDirectional.center, children: [
Wrap(spacing: 0,
/// 子Widget列表
children: [renderSquadron(context)])
])),
);
}
Widget renderSquadron(BuildContext context) {
return Container(
width: 70,
alignment: Alignment.center,
child: InkWell(
child: Row(mainAxisAlignment: MainAxisAlignment.center, children: [
Column(mainAxisAlignment: MainAxisAlignment.center, children: [
Container(
child: Row(children: [
Image.asset('assets/map_power.png', width: 20, height: 20),
const SizedBox(width: 8),
Text(widget.carInfo['carStatus']),
]))
])
]),
onTap: () {
openSourceTypeSheet(context);
},
));
}
void openSourceTypeSheet(BuildContext context) {
TopSheetDialog.show(
context: context,
child: StatefulBuilder(builder: (BuildContext context, StateSetter ss) {
return SelectCarStatusTypePanel(
onChanged: (selectKeys) {
selectKey = selectKeys;
},
selectKeys: selectKey,
resourceMaps: _resourceMaps,
reset: () {
setState(() {
selectKey = '';
ss(() {});
});
},
ok: () {
/// 掉持久化方法,改变车辆状态
if (selectKey != '') {
doSaveCarStatus(selectKey);
}
},
);
}),
backgroundColor: Colors.transparent,
direction: TopSheetDialogDirection.TOP);
}
dynamic doSaveCarStatus(selectKey) {
API.updateCarStatus('', selectKey).then((resp) => {});
}
dynamic getCarStatusList() {
API.getCarStatusList().then((resp) => {
setState(() {
_resourceMaps = resp;
})
});
}
}
/// 选择资源类型, 包含 底部按钮
class SelectCarStatusTypePanel extends StatelessWidget {
const SelectCarStatusTypePanel(
{Key key,
this.selectKeys,
this.onChanged,
this.resourceMaps,
this.reset,
this.ok})
: super(key: key);
final String selectKeys;
final void Function(String selectKeys) onChanged;
final Function reset;
final Function ok;
final List resourceMaps;
@override
Widget build(BuildContext context) {
return Container(
height: 256.0,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
TagSelectPanel(
crossAxisCount: 3,
datas: resourceMaps,
selectKey: selectKeys,
onChanged: onChanged),
Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
ExpandedButton(
height: 48.0,
child: const Text('重置'),
onPressed: reset,
),
ExpandedButton(
height: 48.0,
color: const Color(0xff345fa6),
child: const Text(
'确定',
style: TextStyle(color: Colors.white),
),
onPressed: () {
Navigator.of(context).pop();
ok();
},
),
])
]));
}
}
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:jcs_airport/routes/routes.dart';
import 'package:jcs_airport/services/api.dart';
/// 力量调度
class PowerInfo extends StatefulWidget {
const PowerInfo(this.alarmId, this.latitude, this.longitude, {Key key}) : super(key: key);
final String alarmId;
final String latitude;
final String longitude;
@override
_PowerState createState() => _PowerState();
}
class _PowerState extends State<PowerInfo> {
List staskSquadrons = [];
@override
void initState() {
super.initState();
getSquadronList();
}
@override
Widget build(BuildContext context) {
return staskSquadrons.isNotEmpty
? Container(
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(
Radius.circular(8.0),
),
boxShadow: <BoxShadow>[
BoxShadow(offset: Offset(0, 1), color: Color.fromRGBO(0, 0, 0, 0.2), blurRadius: 3.0, spreadRadius: 1.0)
],
),
margin: const EdgeInsets.only(left: 10, top: 10, right: 10),
padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 6),
child: Stack(alignment: AlignmentDirectional.center, children: [
Wrap(
spacing: 0,
/// 子Widget列表
children: renderSquadron())
]))
: Container();
}
List<Widget> renderSquadron() {
List<Widget> list = [];
staskSquadrons.forEach((element) {
list.add(Container(
width: 100,
alignment: Alignment.center,
decoration: const BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(5)),
),
child: InkWell(
child: Row(mainAxisAlignment: MainAxisAlignment.center, children: [
Image.asset('assets/map_power.png', width: 30, height: 30),
const SizedBox(width: 5),
Column(mainAxisAlignment: MainAxisAlignment.center, children: [
Container(
child: Row(
children: [const Text('车辆:'), const SizedBox(width: 8), Text(element['carNum'].toString())])),
Container(
child: Row(
children: [const Text('人员:'), const SizedBox(width: 8), Text(element['userNum'].toString())]))
])
]),
onTap: () {
Get.toNamed(JCSRoutes.powerDispatching, arguments: widget.alarmId);
},
)));
});
return list;
}
void getSquadronList() {
if (widget.alarmId == null) {
return;
}
API.taskSquadronList(widget.alarmId).then((linkageForce) {
if (linkageForce != null) {
setState(() {
staskSquadrons = linkageForce;
});
}
});
}
}
import 'package:amos_flutter_utils/amos_flutter_utils.dart';
import 'package:amos_iot_login_tpl/amos_iot_login_tpl.dart';
import 'package:flutter/material.dart';
import 'package:jcs_airport/consts/Logger.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'package:amos_iot_login_tpl/const/global_config.dart';
import 'package:jcs_airport/consts/url_const.dart';
///@Description 救援预案
///@author helinlin
///@create 2021-12-10 10:55
class PlanWebView extends StatefulWidget {
final String sequenceNbr;
const PlanWebView({Key key, this.sequenceNbr}) : super(key: key);
@override
_PlanWebViewState createState() => _PlanWebViewState();
}
class _PlanWebViewState extends State<PlanWebView> {
WebViewController webViewController;
String _h5Url;
String token;
@override
void initState() {
super.initState();
getUrl();
}
Future<void> getUrl() async {
//获取token
SPTools _sp = await SPTools.instance;
token = _sp.getString(GlobalConst.token);
//获取文档地址
_h5Url = await APIUrlManager.getH5Url();
Uri uri = Uri.parse(_h5Url ?? URLConst.MAP_H5_URL);
String address = uri.scheme + '://' + uri.host + ':' + uri.port.toString();
setState(() {
_h5Url = address + URLConst.PLAN_H5_URL + '?fileid=' + widget.sequenceNbr + '&token=' + token;
Logger.info(_h5Url);
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('救援预案'),
),
body: _h5Url != null
? WebView(
initialUrl: _h5Url,
javascriptMode: JavascriptMode.unrestricted,
onWebViewCreated: (WebViewController controller) {
webViewController = controller;
},
)
: Container(),
);
}
}
import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import './../native_bridge.dart';
/// 目标位置距当前设备的距离
class RealtimeDistance extends StatefulWidget {
const RealtimeDistance(
{Key key, this.callJSMethod, this.distance, this.targetLanLat, this.msgType, this.currentLngLat, this.style})
: super(key: key);
final ExecuteJSMethod callJSMethod;
final Map targetLanLat;
final Map currentLngLat;
final String distance;
final String msgType;
final TextStyle style;
@override
_RealtimeDistanceState createState() => _RealtimeDistanceState();
}
class _RealtimeDistanceState extends State<RealtimeDistance> {
Timer _timer;
@override
void initState() {
super.initState();
distanceTimer();
calcDistance();
}
@override
Widget build(BuildContext context) {
return Text(widget.distance != null ? '距您${widget.distance} ' : '', style: widget.style);
}
void distanceTimer() {
if (widget.currentLngLat.isNotEmpty && widget.targetLanLat.isNotEmpty) {
Timer.periodic(const Duration(seconds: 10), (timer) {
_timer = timer;
calcDistance();
});
}
}
void calcDistance() {
Function callback = widget.callJSMethod;
String args = jsonEncode(
{'currentLngLat': widget.currentLngLat, 'targetLanLat': widget.targetLanLat, 'msgType': widget.msgType});
callback('getDistanceData($args)');
}
@override
void dispose() {
if (_timer != null) {
_timer.cancel();
_timer = null;
}
super.dispose();
}
}
import 'package:flutter/material.dart';
import 'package:amos_flutter_ui/amos_flutter_ui.dart';
import 'package:jcs_airport/services/api.dart';
/// 修改车辆状态
class CarStatusSelect extends StatefulWidget {
const CarStatusSelect(
{Key key,
this.selectKey,
this.onChanged,
this.bindingCarId,
this.alertCallId,
this.carStatus,
this.ok})
: super(key: key);
final void Function(String selectKey) onChanged;
final String bindingCarId;
final String alertCallId;
final String selectKey;
final List<Map<String, String>> carStatus;
final Function ok;
@override
_CarStatusSelectState createState() => _CarStatusSelectState();
}
class _CarStatusSelectState extends State<CarStatusSelect> {
String selectKey;
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return Center(
child: Container(
height: 400.0,
child: Column(
children: [
TagSelectPanel(
crossAxisCount: 3,
datas: widget.carStatus ?? [],
selectKey: widget.selectKey ?? '',
onChanged: (key) {
setState(() {
selectKey = key ?? '';
});
}),
Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
ExpandedButton(
height: 48.0,
child: const Text('取消'),
onPressed: (){
Navigator.of(context).pop();
},
),
ExpandedButton(
height: 48.0,
color: const Color(0xff345fa6),
child: const Text(
'确定',
style: TextStyle(color: Colors.white),
),
onPressed: () {
setCarStatus();
widget.ok();
Navigator.of(context).pop();
},
),
])
],
),
),
);
}
///车辆状态选择后回调
void setCarStatus() {
API.setCurrentCarOrTaskState(widget.bindingCarId, widget.alertCallId, selectKey, '1').then((value) {});
}
}
///车辆状态选择弹出框
void openSourceTypeDialog(BuildContext context, {Function onChanged, String selectKey}) {
showDialog(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return StatefulBuilder(builder: (BuildContext context, StateSetter ss) {
return Dialog(
insetPadding: const EdgeInsets.symmetric(horizontal: 6.0),
child: CarStatusSelect(
onChanged: onChanged,
selectKey: selectKey,
),
);
});
},
);
}
import 'package:flutter/material.dart';
import 'package:amos_flutter_ui/amos_flutter_ui.dart';
const List<Map<String, String>> _resourceMaps = [
{'key': 'linkageForce', 'label': '联动力量'},
{'key': 'rescueTeam', 'label': '救援队伍'},
{'key': 'miniFireStation', 'label': '微型消防站'},
{'key': 'SY500', 'label': '500m水源'},
{'key': 'SY1000', 'label': '1000m水源'},
{'key': 'professionalTeam', 'label': '志愿救援'},
{'key': 'defendTarget', 'label': '重点单位'},
{'key': 'video', 'label': '视频'},
];
/// 选择资源类型
class SelectResourceType extends StatelessWidget {
const SelectResourceType({Key key, this.selectKeys, this.onChanged})
: super(key: key);
final List<String> selectKeys;
final void Function(List<String> selectKeys) onChanged;
@override
Widget build(BuildContext context) {
return Container(
child: MultiTagSelectPanel(
crossAxisCount: 3,
datas: _resourceMaps,
selectKeys: selectKeys,
onChanged: onChanged));
}
}
/// 选择资源类型, 包含 底部按钮
class SelectResourceTypePanel extends StatelessWidget {
const SelectResourceTypePanel(
{Key key, this.selectKeys, this.onChanged, this.reset, this.ok})
: super(key: key);
final List<String> selectKeys;
final void Function(List<String> selectKeys) onChanged;
final Function reset;
final Function ok;
@override
Widget build(BuildContext context) {
return Container(
height: 256.0,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
MultiTagSelectPanel(
crossAxisCount: 3,
datas: _resourceMaps,
selectKeys: selectKeys,
onChanged: onChanged),
Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
ExpandedButton(
height: 48.0,
child: const Text('重置'),
onPressed: reset,
),
ExpandedButton(
height: 48.0,
color: const Color(0xff345fa6),
child: const Text(
'确定',
style: TextStyle(color: Colors.white),
),
onPressed: () {
Navigator.of(context).pop();
ok();
},
),
])
]));
}
}
void openSourceTypeDialog(BuildContext context,
{Function reset,
Function ok,
Function onChanged,
List<String> selectKeys}) {
showDialog(
context: context,
/// 只有点击按钮才能关闭
barrierDismissible: false,
builder: (BuildContext context) {
return StatefulBuilder(builder: (BuildContext context, StateSetter ss) {
return Dialog(
// insetPadding: EdgeInsets.zero,
insetPadding: const EdgeInsets.symmetric(horizontal: 6.0),
child: SelectResourceTypePanel(
onChanged: onChanged,
selectKeys: selectKeys,
reset: () {
reset(() {
ss(() {});
});
},
ok: ok,
),
);
});
},
);
}
import 'dart:convert';
/// 警情详情
class AlarmDisaster {
String sequenceNbr;
String alertStage;
String callTime;
String alertType;
String alarmTypeCode;
String unitInvolved;
int trappedNum;
int casualtiesNum;
String address;
String rescueGrid;
String longitude;
String latitude;
String distance;
String responseLevelCode;
Map<String, dynamic> strengthCount;
Map<String, dynamic> alarmDetails;
List rescueObject;
AlarmDisaster(
{this.sequenceNbr,
this.alertStage,
this.callTime,
this.alertType,
this.alarmTypeCode,
this.unitInvolved,
this.trappedNum,
this.casualtiesNum,
this.address,
this.rescueGrid,
this.longitude,
this.latitude,
this.responseLevelCode,});
AlarmDisaster.fromJson(Map<String, dynamic> json) {
sequenceNbr = json['sequenceNbr'];
alertStage = json['alertStage'];
callTime = json['callTime'];
alertType = json['alertType'];
alarmTypeCode = json['alarmTypeCode'];
unitInvolved = json['unitInvolved'];
trappedNum = json['trappedNum'];
casualtiesNum = json['casualtiesNum'];
address = json['address'];
rescueGrid = json['rescueGrid'];
longitude = json['longitude'];
latitude = json['latitude'];
responseLevelCode = json['responseLevelCode'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['sequenceNbr'] = sequenceNbr;
data['alertStage'] = alertStage;
data['callTime'] = callTime;
data['alertType'] = alertType;
data['alarmTypeCode'] = alarmTypeCode;
data['unitInvolved'] = unitInvolved;
data['trappedNum'] = trappedNum;
data['casualtiesNum'] = casualtiesNum;
data['address'] = address;
data['rescueGrid'] = rescueGrid;
data['longitude'] = longitude;
data['latitude'] = latitude;
data['responseLevelCode'] = responseLevelCode;
return data;
}
}
/// 经纬度实体对象
class LngLat {
LngLat(this.lng, this.lat);
/// 经度
double lng;
/// 纬度
double lat;
LngLat.fromJson(Map<String, double> json) {
lng = json['lng'];
lat = json['lat'];
}
LngLat.fromJsonStr(String jsonStr) {
Map<String, double> map = jsonDecode(jsonStr);
lng = map['lng'];
lat = map['lat'];
}
static LngLat fromMap(Map<String, double> map) {
LngLat jsonModel = LngLat(map['lng'], map['lat']);
return jsonModel;
}
/// 将 LngLat 转化为 js 识别的数据
static String toJsJson(LngLat ll) {
return jsonEncode(ll);
}
Map toJson() {
Map map = <String, double>{};
map['lng'] = lng;
map['lat'] = lat;
return map;
}
@override
String toString() {
return 'LngLat: {lng: $lng, lat: $lat}';
}
}
/// 集结点详情
class AssembleyPoint {
String sequenceNbr;
String name;
String longitude;
String latitude;
AssembleyPoint({this.sequenceNbr, this.name, this.longitude, this.latitude});
AssembleyPoint.fromJson(Map<String, dynamic> json) {
sequenceNbr = json['sequenceNbr'];
name = json['name'];
longitude = json['longitude'];
latitude = json['latitude'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['sequenceNbr'] = sequenceNbr;
data['name'] = name;
data['longitude'] = longitude;
data['latitude'] = latitude;
return data;
}
}
import 'dart:async';
import 'dart:convert';
import 'package:amos_flutter_utils/amos_flutter_utils.dart';
import 'package:event_bus/event_bus.dart';
PubSub _ps;
EventBus _eb = EventBus();
class EventDataType {
/// 警情数据
static const String AlarmDisaster = 'AlarmDisaster';
/// 编辑集结点数据
static const String EditAssemblyPoint = 'editAssemblyPoint';
/// 当前设备距离灾情的距离
static const String Self2AlarmDistance = 'self2AlarmDistance';
/// 当前设备距离集结点的距离
static const String Self2AssemblyPointDistance = 'self2AssemblyPointDistance';
/// 点击地图空白处
static const String MapClickEmpty = 'mapClickEmpty';
/// 定位
static const String ChooseLocation = 'chooseLocation';
}
/// 事件数据,主要用于事件发送时进行分发
class EventData {
EventData({this.type, this.content});
/// 数据类型
String type;
/// 内容
dynamic content;
/// jsonEncode 方法中会调用实体类的这个方法。如果实体类中没有这个方法,会报错。
Map toJson() {
Map map = <String, dynamic>{};
map['type'] = type;
map['content'] = content;
return map;
}
static EventData fromMap(Map<String, dynamic> map) {
EventData jsonModel = EventData(type: map['type'], content: map['content']);
return jsonModel;
}
/// 将json字符串转化成对象
static EventData parseJson(String jsonStr) {
EventData edModel = fromMap(jsonDecode(jsonStr));
return edModel;
}
@override
String toString() {
return 'EventData: {type: $type, content: $content}';
}
}
/// 指挥事件总线
class DispatchEvents {
static PubSub getInstance() {
_ps ??= PubSub(_eb);
return _ps;
}
/// 订阅消息
/// - [listener] 订阅消息执行方法
/// - [tagName] 订阅消息的别名,不能同名
static StreamSubscription on(Function listener, String tagName) {
return getInstance().on(listener, tagName);
}
static void fire(event) {
getInstance().fire(event);
}
static void off(event) {
getInstance().fire(event);
}
/// 取消订阅
static void cancel(dynamic tar) {
getInstance().cancel(tar);
}
static void destroy() {
getInstance().destroy();
}
}
class DispatchTagNames {
/// main map 主消息 tagName
static const String MAIN_MAP = 'MAIN_MAP';
}
\ No newline at end of file
/// 所有 h5 地图公共模块
///
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'package:amos_flutter_ui/amos_flutter_ui.dart';
import './../../consts/url_const.dart';
import './native_bridge.dart';
/// 地图基类,作战地图相关的所有地图 h5 功能
class H5MapBase extends StatefulWidget {
const H5MapBase({Key key, this.onCreated, this.h5Url = URLConst.MAP_H5_URL}) : super(key: key);
final Function onCreated;
/// h5 地图 URL
final String h5Url;
@override
_H5MapBaseState createState() => _H5MapBaseState();
}
class _H5MapBaseState extends State<H5MapBase> {
WebViewController webViewController;
@override
Widget build(BuildContext context) {
print('h5 base map url:${widget.h5Url}');
if (widget.h5Url == null || widget.h5Url.isEmpty) {
return Container();
}
return Container(
height: MediaQuery.of(context).size.height,
child: WebView(
// initialUrl: 'https://www.amap.com/',
initialUrl: '${widget.h5Url}',
javascriptMode: JavascriptMode.unrestricted,
onWebViewCreated: (WebViewController wvc) {
webViewController = wvc;
widget.onCreated(wvc);
},
/// 路由委托(可以通过在此处拦截url实现 JS 调用 Flutter部分);
navigationDelegate: (NavigationRequest request) {
/// 通过拦截 url 来实现 js 与 flutter 交互
if (request.url.startsWith('js://webview')) {
AmosToast.show('JS调用了Flutter By navigationDelegate', context);
print('blocking navigation to $request}');
/// 阻止路由替换,不能跳转,因为这是js交互给我们发送的消息
return NavigationDecision.prevent;
}
/// 允许路由替换
return NavigationDecision.navigate;
},
/// 与h5 通信
javascriptChannels: <JavascriptChannel>{
_pageChange(context),
_publickChanel(context),
}));
}
JavascriptChannel _pageChange(BuildContext context) {
return JavascriptChannel(
name: 'PageChange',
onMessageReceived: (JavascriptMessage jm) {
String jsonStr = jm.message;
JsBridgeUtil.execute(context, jsonStr, webViewController);
});
}
/// 公共通道
JavascriptChannel _publickChanel(BuildContext context) {
return JavascriptChannel(
name: 'CommonChanel',
onMessageReceived: (JavascriptMessage jm) {
String jsonStr = jm.message;
JsBridgeUtil.execute(context, jsonStr, webViewController);
});
}
void executeJs(String method, {dynamic data}) {
webViewController.evaluateJavascript('$method()');
}
}
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:get/get.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:jcs_airport/services/api.dart';
import '../../../consts/colors.dart';
import '../../../utils/GetConfig.dart';
import './hotSug.dart';
class HazardousChemicalsSearchPage extends StatefulWidget {
const HazardousChemicalsSearchPage();
@override
State<StatefulWidget> createState() => _HazardousChemicalsSearchPage();
}
class _HazardousChemicalsSearchPage extends State<HazardousChemicalsSearchPage> {
final TextEditingController _controller = TextEditingController();
final FocusNode _focusNode = FocusNode();
List<String> hotWords = [];
List<_SearchKey> searchKeyCount = [];
List<String> orderKeyword = [];
final bool _isNotSearching = true;
String theme = 'blue';
BuildContext me;
// 当前页码
int pageIndex = 1;
// 是否有下一页
bool hasNext = false;
// 分页所需控件
bool isAnimating = false;
dynamic initConfig() async {
SharedPreferences.getInstance().then((preferences) {
setState(() {
theme = preferences.getString('theme') ?? KColorConstant.DEFAULT_COLOR;
});
});
}
@override
Widget build(BuildContext context) {
me = context;
return Scaffold(
backgroundColor: const Color.fromRGBO(240, 243, 245, 1),
appBar: AppBar(
elevation: 0.2,
brightness: Brightness.light,
backgroundColor: const Color(0xFFFFFFFF),
leading: Container(
child: GestureDetector(
onTap: () {
_focusNode.unfocus();
Navigator.pop(context);
},
child: Icon(Icons.keyboard_arrow_left, color: GetConfig.getColor(theme), size: 32)),
),
title: Container(
height: 38,
padding: const EdgeInsets.symmetric(horizontal: 18),
decoration: BoxDecoration(color: Colors.grey.shade100, borderRadius: const BorderRadius.all(Radius.circular(45))),
child: Center(
child: TextField(
textInputAction: TextInputAction.search,
controller: _controller,
autofocus: true,
focusNode: _focusNode,
style: const TextStyle(fontSize: 14.0, color: Color(0xFF999999)),
onSubmitted: (value) {
search(_controller.text);
},
decoration: const InputDecoration(
hintText: '请输入搜索内容', border: InputBorder.none, contentPadding: EdgeInsets.only(bottom: 10)),
onChanged: (val) {},
),
),
),
actions: <Widget>[
Align(
child: Padding(
padding: const EdgeInsets.only(right: 10),
child: GestureDetector(
onTap: () {
setState(() {
search(_controller.text);
});
},
child: const Text('搜索',
style: TextStyle(color: Color(0xFF999999), fontSize: 14.0, fontWeight: FontWeight.w500)))))
]),
body: ListView(children: <Widget>[
Offstage(
offstage: !_isNotSearching,
child: Container(
color: Colors.white,
child: HotSugWidget(title: '搜索历史', hotWords: hotWords, deleteBtnClick: deleteSearchHistory, theme: theme)))
]),
resizeToAvoidBottomPadding: false);
}
@override
void initState() {
super.initState();
initData();
initConfig();
}
dynamic initData() async {
final prefs = await SharedPreferences.getInstance();
setState(() {
List<String> data = prefs.getStringList('hotWordsHistory');
if (data != null && data.isNotEmpty) {
hotWords = data;
} else {
hotWords = [];
}
});
}
dynamic search(String keyword) async {
if (keyword != null && keyword.isNotEmpty) {
// 添加搜索历史
if (hotWords.contains(keyword)) {
} else {
setState(() {
hotWords.add(keyword);
});
final prefs = await SharedPreferences.getInstance();
prefs.setStringList('hotWordsHistory', hotWords);
}
Get.back(result: keyword);
// 页面跳转,查询并显示结果
//_searchData(keyword);
}
}
dynamic searchByHistory(String text) {
// 页面跳转,查询并显示结果
search(text);
}
dynamic deleteSearchHistory() async {
final prefs = await SharedPreferences.getInstance();
prefs.remove('hotWordsHistory');
initData();
}
/*dynamic _searchData(keyword) {
setState(() {
pageIndex = 1;
});
_loadMore(keyword);
}*/
/* Future<void> _loadMore(keyword) async {
Map<String, dynamic> query = {'pageNum': pageIndex, 'pageSize': 20};
query['name'] = keyword;
setState(() {
isAnimating = true;
});
var data = await API.getHazardousChemicals(query);
setState(() {
isAnimating = false;
List hazardousList = [];
if (data != null && data['records'].length > 0) {
for (dynamic p in data['records']) {
hazardousList.add(p);
}
}
widget.callback(hazardousList);
if (data['current'] == data['pages']) {
hasNext = false;
}
Navigator.pop(me);
});
}*/
}
class _SearchKey {
String keyword;
int count;
_SearchKey();
_SearchKey.fromJson(jsonRes) {
keyword = jsonRes['keyword'];
count = jsonRes['count'];
}
}
import 'package:flutter/material.dart';
import 'package:amos_flutter_ui/amos_flutter_ui.dart';
import 'package:get/get.dart';
/// 危化品详情
class HazardousChemicalsDetail extends StatefulWidget {
const HazardousChemicalsDetail({Key key}) : super(key: key);
@override
_HazardousChemicalsDetailState createState() =>
_HazardousChemicalsDetailState();
}
class _HazardousChemicalsDetailState extends State<HazardousChemicalsDetail> {
int pageIndex = 1;
bool hasNext = false;
// 分页所需控件
bool isAnimating = false;
String theme = '';
dynamic hazardousChemicalsModel = {};
List hazardousList = [
{'key': 'name', 'name': '名 称', 'title': ''},
{'key': 'englishName', 'name': '英 文 名', 'title': ''},
{'key': 'ingredient', 'name': '主要成分', 'title': ''},
{'key': 'formula', 'name': '分 子 式', 'title': ''},
{'key': 'type', 'name': '类 型', 'title': ''},
{'key': 'un', 'name': '国 标 号', 'title': ''},
{'key': 'tabu', 'name': '禁 忌 物', 'title': ''},
{'key': 'store', 'name': '贮藏方法', 'title': ''},
{'key': 'property', 'name': '性 状', 'title': ''},
{'key': 'leakWay', 'name': '泄漏处理', 'title': ''},
{'key': 'dispose', 'name': '处理措施', 'title': ''},
{'key': 'defendWay', 'name': '防护处理', 'title': ''},
{'key': 'symptom', 'name': '症 状', 'title': ''},
];
@override
void initState() {
super.initState();
hazardousChemicalsModel = Get.arguments;
hazardousList.forEach((element) {
String key = element['key'];
element['title'] = hazardousChemicalsModel[key];
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('危化品详情',
style: Theme.of(context).appBarTheme.textTheme.headline1),
),
body: Stack(
children: <Widget>[
Container(
decoration: const BoxDecoration(color: Color(0xffefefef)),
margin: const EdgeInsets.only(top: 10),
child: Column(children: <Widget>[
Expanded(
child: Stack(children: <Widget>[
SingleChildScrollView(
child: ListView.builder(
physics: const NeverScrollableScrollPhysics(),
key: const PageStorageKey('data'),
itemCount: hazardousList.length,
shrinkWrap: true,
itemBuilder: (BuildContext context, int index) =>
ListInfoView(index, hazardousList[index])))
]))
])),
],
),
);
}
}
class ListInfoView extends StatelessWidget {
int row;
dynamic bean;
ListInfoView(this.row, this.bean, {Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
alignment: Alignment.center,
//单双行con颜色
color: row % 2 == 0 ? Colors.white : const Color(0xffefeff4),
child: getTextView(),
);
}
//返回文字view
Widget getTextView() {
return Container(
padding: const EdgeInsets.all(10),
child: LabelValue(label: bean['name'], value: bean['title'] ?? ''));
}
}
import 'package:flutter/material.dart';
import 'package:get/get.dart';
class HotSugWidget extends StatelessWidget {
final List hotWords;
final Function deleteBtnClick;
final String title;
final String theme;
const HotSugWidget({Key key, this.theme, this.hotWords, this.title, this.deleteBtnClick}) : super(key: key);
@override
Widget build(BuildContext context) {
if (theme == '') {
return Container();
} //Color.fromRGBO(240, 243, 245, 1)
return Column(crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[
Container(
height: 40,
padding: const EdgeInsets.only(left: 20),
alignment: Alignment.centerLeft,
color: Colors.white,
child: Row(children: <Widget>[
Expanded(
child: Text(title, style: const TextStyle(color: Color(0xff333333), fontSize: 17, fontWeight: FontWeight.bold)),
flex: 9)
]),
margin: const EdgeInsets.only(bottom: 10)),
const Divider(height: 1),
Padding(
padding: const EdgeInsets.only(left: 10, right: 10, top: 10, bottom: 10),
child: Wrap(
spacing: 10,
runSpacing: 10,
children: hotWords
.map((i) => GestureDetector(
onTap: () => Get.back(result: i),
child: Container(
decoration: BoxDecoration(color: const Color(0xFFF2F2F2), borderRadius: BorderRadius.circular(5)),
padding: const EdgeInsets.symmetric(vertical: 5, horizontal: 7),
child: Text(i, style: const TextStyle(color: Color(0xFF999999))))))
.toList(),
))
]);
}
}
/// 作战指挥
/// 该模块将所有作战指挥的模块进行导出
///
export './main_map.dart';
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment