sign_page.dart 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401
  1. import 'dart:async';
  2. import 'package:amap_location_flutter_plugin/amap_location_flutter_plugin.dart';
  3. import 'package:amap_location_flutter_plugin/amap_location_option.dart';
  4. import 'package:amap_map_fluttify/amap_map_fluttify.dart';
  5. import 'package:flutter/material.dart';
  6. import 'package:liftmanager/internal/sign/model/sign_config_item.dart';
  7. import 'package:liftmanager/internal/sign/model/sign_list_entity.dart';
  8. import 'package:liftmanager/internal/sign/sign_router.dart';
  9. import 'package:liftmanager/net/api_service.dart';
  10. import 'package:liftmanager/res/resources.dart';
  11. import 'package:liftmanager/routers/fluro_navigator.dart';
  12. import 'package:liftmanager/utils/theme_utils.dart';
  13. import 'package:liftmanager/utils/toast.dart';
  14. import 'package:liftmanager/widgets/app_bar.dart';
  15. import 'package:permission_handler/permission_handler.dart';
  16. class SignPage extends StatefulWidget {
  17. @override
  18. State<StatefulWidget> createState() {
  19. return SignPageState();
  20. }
  21. }
  22. class SignPageState extends State<SignPage> {
  23. Map<String, Object> _locationResult;
  24. StreamSubscription<Map<String, Object>> _locationListener;
  25. AmapLocationFlutterPlugin _locationPlugin = new AmapLocationFlutterPlugin();
  26. //计时器。
  27. Timer _timer;
  28. String _nowTimeStr = "";
  29. LatLng latLng = LatLng(0, 0);
  30. String currentAddress = "";
  31. SignConfigItem configItem = SignConfigItem();
  32. List<SignListItem> list = [];
  33. BuildContext mContext;
  34. AmapController _controller;
  35. startTime() async {
  36. _timer = Timer.periodic(Duration(seconds: 1), (timer) {
  37. if (!mounted) return;
  38. setState(() {
  39. _nowTimeStr = DateTime.now().toString().split(" ")[1].split(".")[0];
  40. });
  41. });
  42. }
  43. @override
  44. void initState() {
  45. super.initState();
  46. _locationListener = _locationPlugin
  47. .onLocationChanged()
  48. .listen((Map<String, Object> result) {
  49. setState(() {
  50. _locationPlugin.stopLocation();
  51. _locationResult = result;
  52. // address latitude longitude
  53. _locationResult.forEach((key, value) {
  54. if(key == 'address'){
  55. currentAddress = '$value';
  56. setState(() {});
  57. }else if(key == 'latitude'){
  58. latLng.latitude = double.parse('$value');
  59. setState(() {});
  60. }else if(key == 'longitude'){
  61. latLng.longitude = double.parse('$value');
  62. setState(() {});
  63. }
  64. print(111);
  65. print('key:$key :');
  66. print('value:$value :');
  67. });
  68. });
  69. });
  70. mContext = context;
  71. startTime();
  72. getSignConfig();
  73. getTodayList();
  74. getLocation();
  75. }
  76. void _setLocationOption() {
  77. if (null != _locationPlugin) {
  78. AMapLocationOption locationOption = new AMapLocationOption();
  79. ///是否单次定位
  80. locationOption.onceLocation = true;
  81. ///是否需要返回逆地理信息
  82. locationOption.needAddress = true;
  83. ///逆地理信息的语言类型
  84. locationOption.geoLanguage = GeoLanguage.DEFAULT;
  85. ///设置Android端连续定位的定位间隔
  86. locationOption.locationInterval = 20000;
  87. ///设置Android端的定位模式<br>
  88. ///可选值:<br>
  89. ///<li>[AMapLocationMode.Battery_Saving]</li>
  90. ///<li>[AMapLocationMode.Device_Sensors]</li>
  91. ///<li>[AMapLocationMode.Hight_Accuracy]</li>
  92. locationOption.locationMode = AMapLocationMode.Hight_Accuracy;
  93. ///设置iOS端的定位最小更新距离<br>
  94. locationOption.distanceFilter = -1;
  95. ///设置iOS端期望的定位精度
  96. /// 可选值:<br>
  97. /// <li>[DesiredAccuracy.Best] 最高精度</li>
  98. /// <li>[DesiredAccuracy.BestForNavigation] 适用于导航场景的高精度 </li>
  99. /// <li>[DesiredAccuracy.NearestTenMeters] 10米 </li>
  100. /// <li>[DesiredAccuracy.Kilometer] 1000米</li>
  101. /// <li>[DesiredAccuracy.ThreeKilometers] 3000米</li>
  102. locationOption.desiredAccuracy = DesiredAccuracy.NearestTenMeters;
  103. ///设置iOS端是否允许系统暂停定位
  104. locationOption.pausesLocationUpdatesAutomatically = false;
  105. ///将定位参数设置给定位插件
  106. _locationPlugin.setLocationOption(locationOption);
  107. }
  108. }
  109. @override
  110. void didChangeDependencies() {
  111. super.didChangeDependencies();
  112. mContext.dependOnInheritedWidgetOfExactType();
  113. }
  114. getLocation() async {
  115. if (await requestPermission()) {
  116. if (null != _locationPlugin) {
  117. ///开始定位之前设置定位参数
  118. _setLocationOption();
  119. _locationPlugin.startLocation();
  120. }
  121. }
  122. }
  123. @override
  124. void dispose() {
  125. _timer.cancel();
  126. if (null != _locationListener) {
  127. _locationListener.cancel();
  128. }
  129. ///销毁定位
  130. if (null != _locationPlugin) {
  131. _locationPlugin.destroy();
  132. }
  133. super.dispose();
  134. }
  135. getSignConfig() {
  136. ApiService(context: context).signConfig(
  137. onSuccess: (res) {
  138. configItem = res;
  139. setState(() {});
  140. },
  141. onError: (code, msg) {});
  142. }
  143. getTodayList() {
  144. ApiService(context: context).signList(
  145. 1, 10, DateTime.now().toString().split(" ")[0], onSuccess: (data) {
  146. list = data.rows;
  147. }, onError: (code, msg) {
  148. toasts(msg);
  149. });
  150. }
  151. getSignAdd() {
  152. if (configItem.topTime.length == 0) {
  153. toasts("未设置打卡");
  154. return;
  155. }
  156. if (currentAddress.length == 0) {
  157. toasts("定位正在初始化,请重试。");
  158. return;
  159. }
  160. NavigatorUtils.pushResult(context,
  161. "${SignRouter.signAddPage}?address=${Uri.encodeComponent(currentAddress)}&coordinate=${latLng.longitude},${latLng.latitude}&toptime=${configItem.topTime}&downtime=${configItem.downTime}&toptimepm=${configItem.topTimePm}&downtimepm=${configItem.downTimePm}&toptimeot=${configItem.topTimeOt}&downtimeot=${configItem.downTimeOt}",
  162. (res) {
  163. getTodayList();
  164. });
  165. }
  166. Future<bool> requestPermission() async {
  167. final permissions = await PermissionHandler()
  168. .requestPermissions([PermissionGroup.location]);
  169. if (permissions[PermissionGroup.location] == PermissionStatus.granted) {
  170. // toasts("已经定位.");
  171. return true;
  172. } else {
  173. toasts('需要定位权限!');
  174. return false;
  175. }
  176. }
  177. @override
  178. Widget build(BuildContext context) {
  179. return Scaffold(
  180. appBar: MyAppBar(
  181. centerTitle: "考勤",
  182. actions: <Widget>[
  183. FlatButton(
  184. child: Text("考勤记录", key: const Key('actionName')),
  185. textColor: Colours.dark_text,
  186. highlightColor: Colors.transparent,
  187. onPressed: () {
  188. NavigatorUtils.push(context, SignRouter.signListPage);
  189. },
  190. )
  191. ],
  192. ),
  193. body: Container(
  194. child: Column(
  195. children: <Widget>[
  196. Container(
  197. color: ThemeUtils.getTabsBg(context),
  198. padding: EdgeInsets.fromLTRB(15, 10, 15, 10),
  199. child: Row(
  200. children: <Widget>[
  201. Expanded(
  202. flex: 1,
  203. child: Text(
  204. "当前位置:${currentAddress ?? ''}",
  205. maxLines: 1,
  206. overflow: TextOverflow.ellipsis,
  207. ),
  208. )
  209. ],
  210. )),
  211. Container(
  212. height: 345,
  213. child: Stack(
  214. children: <Widget>[
  215. AmapView(
  216. mapType: MapType.Standard,
  217. showZoomControl: false,
  218. centerCoordinate: latLng,
  219. zoomLevel: 17,
  220. maskDelay: Duration(milliseconds: 500),
  221. onMapCreated: (controller) async {
  222. _controller = controller;
  223. await _controller?.showMyLocation(MyLocationOption(
  224. myLocationType: MyLocationType.Locate,
  225. ));
  226. },
  227. ),
  228. // AmapView(
  229. // mapType: MapType.Standard,
  230. // // 是否显示缩放控件
  231. // showZoomControl: false,
  232. // // 是否显示指南针控件
  233. // showCompass: false,
  234. // // 是否显示比例尺控件
  235. // showScaleControl: false,
  236. // // 是否使能缩放手势
  237. // zoomGesturesEnabled: true,
  238. // // 是否使能滚动手势
  239. // scrollGesturesEnabled: true,
  240. // // 是否使能旋转手势
  241. // rotateGestureEnabled: true,
  242. // // 是否使能倾斜手势
  243. // tiltGestureEnabled: true,
  244. // // 缩放级别
  245. // zoomLevel: 18,
  246. //// markers: _markers,
  247. // // 中心点坐标
  248. // centerCoordinate: latLng,
  249. // // 标记
  250. // onMapCreated: (controller) async {
  251. // if (await requestPermission()) {
  252. // await controller.showMyLocation(MyLocationOption(show: true));
  253. // }
  254. //// await getLocation();
  255. //// _markers = [
  256. //// MarkerOption(
  257. //// title: "我的位置",
  258. //// latLng: latLng,
  259. //// iconUri: _assetsIcon,
  260. //// imageConfig:
  261. //// createLocalImageConfiguration(mContext),
  262. //// width: 28,
  263. //// height: 28)
  264. //// ];
  265. //// controller.setCenterCoordinate(latLng);
  266. //// controller.showMyLocation(MyLocationOption());
  267. //// setState(() {});
  268. // },
  269. // ),
  270. // BoxShadow(color: Colors.grey[300],offset: Offset(1, 1),
  271. // ///模糊阴影半径
  272. // blurRadius: 5,
  273. // )
  274. Positioned(
  275. right: 14,
  276. bottom: 19,
  277. child: GestureDetector(
  278. onTap: () {
  279. getSignAdd();
  280. },
  281. child: Container(
  282. height: 75,
  283. width: 75,
  284. decoration: BoxDecoration(
  285. color: Colours.app_main,
  286. boxShadow: [
  287. ///阴影颜色/位置/大小等
  288. BoxShadow(
  289. color: Colors.grey[300], offset: Offset(1, 1),
  290. ///模糊阴影半径
  291. blurRadius: 5,
  292. ),
  293. BoxShadow(
  294. color: Colors.grey[300],
  295. offset: Offset(-1, -1),
  296. blurRadius: 5),
  297. BoxShadow(
  298. color: Colors.grey[300],
  299. offset: Offset(1, -1),
  300. blurRadius: 5),
  301. BoxShadow(
  302. color: Colors.grey[300],
  303. offset: Offset(-1, 1),
  304. blurRadius: 5)
  305. ],
  306. borderRadius: BorderRadius.circular(73)),
  307. child: Column(
  308. mainAxisAlignment: MainAxisAlignment.center,
  309. children: <Widget>[
  310. Text(
  311. "打卡",
  312. style: TextStyle(
  313. fontSize: 13,
  314. fontWeight: FontWeight.w500,
  315. color: Colors.white),
  316. ),
  317. Text("${_nowTimeStr}",
  318. style: TextStyle(
  319. fontSize: 13,
  320. fontWeight: FontWeight.w500,
  321. color: Colors.white))
  322. ],
  323. ),
  324. ),
  325. ),
  326. ),
  327. ],
  328. )),
  329. Container(
  330. padding: EdgeInsets.only(left: 10),
  331. alignment: Alignment.centerLeft,
  332. height: 45,
  333. decoration: BoxDecoration(
  334. border: Border(
  335. bottom: BorderSide(width: 0.5, color: Colours.line),
  336. ),
  337. ),
  338. child: Text(
  339. "今日打卡记录",
  340. style: TextStyle(fontSize: 14, color: Color(0xFF333333)),
  341. ),
  342. ),
  343. Expanded(
  344. flex: 1,
  345. child: ListView.separated(
  346. shrinkWrap: true,
  347. itemCount: list.length,
  348. separatorBuilder: (BuildContext context, int index) {
  349. return Container(
  350. height: 0.5,
  351. color: Color(0xFFF5F5F5),
  352. );
  353. },
  354. itemBuilder: (_, index) {
  355. return Container(
  356. color: Colors.white,
  357. padding: const EdgeInsets.symmetric(
  358. horizontal: 15.0, vertical: 12.0),
  359. alignment: Alignment.centerLeft,
  360. child: Column(
  361. crossAxisAlignment: CrossAxisAlignment.start,
  362. mainAxisAlignment: MainAxisAlignment.start,
  363. children: <Widget>[
  364. Text("类型:${list[index].typeDesc}"),
  365. Text("时间:${list[index].createDate}"),
  366. Text("地址:${list[index].address}"),
  367. Text("状态:${list[index].statusDesc}")
  368. ],
  369. ),
  370. );
  371. },
  372. ))
  373. ],
  374. ),
  375. ),
  376. );
  377. }
  378. }