heavy_sign_page.dart 15 KB

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