confirm_order.dart 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435
  1. import 'package:flutter/material.dart';
  2. import 'package:liftmanager/net/api_service.dart';
  3. import 'package:liftmanager/utils/toast.dart';
  4. import 'package:liftmanager/widgets/app_bar.dart';
  5. import 'package:liftmanager/routers/fluro_navigator.dart';
  6. import 'package:liftmanager/widgets/selected_image_change.dart';
  7. import 'package:image_picker/image_picker.dart';
  8. import 'package:flutter_screenutil/flutter_screenutil.dart';
  9. import 'package:liftmanager/internal/wode/wode_router.dart';
  10. import 'package:permission_handler/permission_handler.dart';
  11. import 'package:liftmanager/utils/oss_upload.dart';
  12. import 'dart:async';
  13. import 'package:liftmanager/utils/fast_notification.dart';
  14. import 'package:chewie/chewie.dart';
  15. import 'package:flutter/services.dart';
  16. import 'package:liftmanager/utils/utils.dart';
  17. import 'package:orientation/orientation.dart';
  18. import 'package:video_player/video_player.dart';
  19. import 'package:liftmanager/utils/theme_utils.dart';
  20. import 'package:liftmanager/widgets/selected_video_change.dart';
  21. import 'dart:io';
  22. class ConfirmOrder extends StatefulWidget {
  23. ConfirmOrder(this.id);
  24. final String id;
  25. @override
  26. State<StatefulWidget> createState() {
  27. return ConfirmOrderState();
  28. }
  29. }
  30. class ConfirmOrderState extends State<ConfirmOrder> {
  31. VideoPlayerController _controller;
  32. VideoPlayerController _controllerFile;
  33. // final FijkPlayer player = FijkPlayer();
  34. // List<String> imagesUrl = [];
  35. // List<String> videoUrl = [];
  36. String videoUrl;
  37. String str;
  38. String imagesUrl;
  39. double percent = 0.0;
  40. @override
  41. void initState() {
  42. super.initState();
  43. }
  44. ///选择图片
  45. void selectPicker() {
  46. showDialog(
  47. context: context,
  48. builder: (BuildContext context) {
  49. return SimpleDialog(
  50. title: Text("选择方式"),
  51. children: ["拍照", '从手机相册选择'].map((String value) {
  52. print("$value");
  53. return SimpleDialogOption(
  54. child: Text(
  55. "${value}",
  56. style: TextStyle(fontSize: 16, fontWeight: FontWeight.w500),
  57. ),
  58. onPressed: () {
  59. _getImage(value == '拍照' ? 1 : 0);
  60. Navigator.of(context).pop();
  61. },
  62. );
  63. }).toList(),
  64. );
  65. },
  66. );
  67. }
  68. void _getImage(int key) async {
  69. print(key);
  70. print(333);
  71. try {
  72. await ImagePicker.pickVideo(
  73. source: key == 1 ? ImageSource.camera : ImageSource.gallery,
  74. )
  75. .then((File f) async{
  76. if (f != null) {
  77. _controllerFile = VideoPlayerController.file(f);
  78. _controllerFile.initialize().then((val){
  79. _controllerFile.setLooping(true);
  80. int seconds = _controllerFile.value.duration.inSeconds;
  81. print("视频时长:$seconds");
  82. int fileSize=f.lengthSync();//单位B
  83. print("视频大小:${fileSize}");
  84. print("视频大小:${f.path}");
  85. if (seconds <= 300) {
  86. _uploadImage(f.path);
  87. // upLoadFileOnce(_imageFile.path);
  88. // setState(() {});
  89. }else {
  90. toasts("视频时长不能大于5分钟!");
  91. }
  92. }).catchError((error){
  93. print(error);
  94. print("error");
  95. toasts("上传失败,不支持此格式");
  96. });}
  97. })
  98. ;
  99. } catch (e) {
  100. toasts("没有权限,无法打开相册!");
  101. }
  102. }
  103. void _uploadImage(filePath) async {
  104. showPercent(context, (){
  105. dismissLoading(context);
  106. toasts("上传失败");
  107. },(){
  108. if(videoUrl == null && str != null){
  109. setState(() {
  110. videoUrl = str;
  111. print("videoUrl:"+videoUrl);
  112. dismissLoading(context);
  113. toasts("上传成功");
  114. });
  115. }
  116. });
  117. String uploadName = OssUtil.instance.getImageUploadName(filePath);
  118. await NewApiService.uploadImage(context, uploadName, filePath).then((data) {
  119. if (data.statusCode == 200) {
  120. str = NewApiUrl.URL_UPLOAD_IMAGE_OSS + "/" + uploadName;
  121. print("str:"+str);
  122. print(videoUrl);
  123. if(str != null){
  124. Map obj = {
  125. "uploadName":uploadName,
  126. "success":true
  127. };
  128. FastNotification.push("percent",obj);
  129. }
  130. }else {
  131. Map obj = {
  132. "uploadName":uploadName,
  133. "success":false
  134. };
  135. FastNotification.push("percent",obj);
  136. }
  137. }).catchError((data) {
  138. Map obj = {
  139. "uploadName":uploadName,
  140. "success":false
  141. };
  142. FastNotification.push("percent",obj);
  143. });
  144. }
  145. upLoadFileOnce(path) {
  146. showLoading(context, "正在上传...");
  147. NewApiService().upload(path, onSuccess: (res) {
  148. dismissLoading(context);
  149. setState(() {
  150. videoUrl = res.pathUrl;
  151. imagesUrl = res.coverUrl;
  152. });
  153. }, onError: (code, msg) {
  154. dismissLoading(context);
  155. toasts(msg);
  156. });
  157. }
  158. submitApply() {
  159. if (videoUrl == null || videoUrl == '') {
  160. toasts("请上传视频");
  161. return;
  162. }
  163. showLoading(context);
  164. NewApiService().chargeMakeSureCase({
  165. "id": widget.id,
  166. "afterRepair": videoUrl,
  167. }, onSuccess: (res) {
  168. dismissLoading(context);
  169. toasts("确认完成");
  170. NavigatorUtils.push(context, "${WodeRouter.orderPageMaster}?checkType=0");
  171. setState(() {});
  172. }, onError: (code, msg) {
  173. dismissLoading(context);
  174. toasts(msg);
  175. });
  176. }
  177. // 文本编辑控制
  178. GlobalKey _formKey = new GlobalKey<FormState>();
  179. @override
  180. Widget build(BuildContext context) {
  181. double width = MediaQuery.of(context).size.width;
  182. return Scaffold(
  183. resizeToAvoidBottomPadding: false, //不让键盘弹上去
  184. appBar: MyAppBar(
  185. centerTitle: "确认订单",
  186. ),
  187. body: Container(
  188. child: ListView(
  189. children: <Widget>[
  190. Form(
  191. key: _formKey, //设置globalKey,用于后面获取FormState
  192. // autovalidate: true, //开启自动校验
  193. child: Column(
  194. children: <Widget>[
  195. Container(
  196. width: width,
  197. padding: EdgeInsets.only(left:15,bottom:15),
  198. child: Text(
  199. "(建议时长3分钟,建议大小50M)",
  200. style: TextStyle(
  201. color: Colors.red,
  202. fontSize:
  203. ScreenUtil()
  204. .setSp(14),
  205. ),
  206. textAlign: TextAlign.left,
  207. ),
  208. ),
  209. // Container(
  210. // color: Colors.white,
  211. // child: GridView.builder(
  212. // shrinkWrap: true,
  213. // padding: const EdgeInsets.fromLTRB(8.0, 12, 8.0, 12.0),
  214. // physics: NeverScrollableScrollPhysics(),
  215. // gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
  216. // crossAxisCount: 3, childAspectRatio: 1.18),
  217. // itemCount: 1,
  218. // itemBuilder: (_, index) {
  219. // return Stack(
  220. // children: <Widget>[
  221. // Center(
  222. // child: SelectedImage(
  223. // image: imagesUrl,
  224. // index: index,
  225. // onTap: () {
  226. // selectPicker();
  227. // FocusScope.of(context).requestFocus(FocusNode());
  228. // },
  229. // ),
  230. // ),
  231. // videoUrl != null
  232. // ? Positioned(
  233. // top: 0,
  234. // right: 0,
  235. // child: GestureDetector(
  236. // onTap: () {
  237. // print(index);
  238. // videoUrl = null;
  239. // imagesUrl = null;
  240. // setState(() {});
  241. // },
  242. // child: Icon(
  243. // IconData(0xe62a, fontFamily: "myfont"),
  244. // size: 24.0,
  245. // color: Color(0xff999999),
  246. // ),
  247. // ),
  248. // )
  249. // : Container(
  250. // child: null,
  251. // )
  252. // ],
  253. // );
  254. // },
  255. // ),
  256. // ),
  257. Container(
  258. color: ThemeUtils.getDialogTextFieldColor(context),
  259. child: GridView.builder(
  260. shrinkWrap: true,
  261. padding: const EdgeInsets.fromLTRB(8.0, 12, 8.0, 12.0),
  262. physics: NeverScrollableScrollPhysics(),
  263. gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
  264. crossAxisCount: 1, childAspectRatio: 1.18),
  265. itemCount: 1,
  266. itemBuilder: (_, index) {
  267. return Stack(
  268. children: <Widget>[
  269. Center(
  270. child: SelectedVideo(
  271. image: videoUrl,
  272. index: index,
  273. videoPlay:videoPlay(),
  274. onTap: () {
  275. if(videoUrl == null){
  276. selectPicker();
  277. }
  278. },
  279. ),
  280. ),
  281. videoUrl != null
  282. ? Positioned(
  283. top: 0,
  284. right: 0,
  285. child: GestureDetector(
  286. onTap: () {
  287. print(index);
  288. // imagesUrl = null;
  289. setState(() {
  290. videoUrl = null;
  291. str = null;
  292. _controller.pause();
  293. // player.reset();
  294. });
  295. },
  296. child: Icon(
  297. IconData(0xe62a, fontFamily: "myfont"),
  298. size: 24.0,
  299. color: Color(0xff999999),
  300. ),
  301. ),
  302. )
  303. : Container(
  304. child: null,
  305. )
  306. ],
  307. );
  308. },
  309. ),
  310. ),
  311. Container(
  312. height: ScreenUtil().setWidth(44),
  313. decoration: BoxDecoration(
  314. borderRadius:
  315. BorderRadius.circular(ScreenUtil().setWidth(22)),
  316. gradient: const LinearGradient(
  317. colors: [Color(0xFF00D9FF), Color(0xFF0287FF)]),
  318. ),
  319. margin: EdgeInsets.all(20.0),
  320. width: double.infinity,
  321. child: FlatButton(
  322. // padding: EdgeInsets.all(15.0),
  323. child: Text("提交"),
  324. // color: Theme
  325. // .of(context)
  326. // .primaryColor,
  327. textColor: Colors.white,
  328. onPressed: () {
  329. /*
  330. * 如果:context不对。可以使用GlobalKey,
  331. * 通过_formKey.currentState 获取FormState后,
  332. * 调用validate()方法校验用户名密码是否合法,校验
  333. * 通过后再提交数据。
  334. */
  335. if ((_formKey.currentState as FormState).validate()) {
  336. submitApply();
  337. }
  338. },
  339. ),
  340. ),
  341. ],
  342. ),
  343. ),
  344. ],
  345. ),
  346. ),
  347. );
  348. }
  349. Widget videoPlay() {
  350. _controller = VideoPlayerController.network(
  351. Utils.getImagePath(videoUrl)
  352. // imgFontUrl + detailObj.url
  353. );
  354. double width = MediaQuery.of(context).size.width;
  355. return
  356. // Container(
  357. // width: width,
  358. // height: width*0.6,
  359. // alignment: Alignment.center,
  360. // child: FijkView(
  361. // player: player,
  362. // color: Colors.black,
  363. // fit:FijkFit.fill,
  364. // // cover: NetworkImage(detailObj.cover),
  365. // // cover: new Image(image: detailObj.cover!=null&& detailObj.cover!=""?NetworkImage(detailObj.cover):AssetImage("assets/images/video_image.png"),).image,
  366. // //
  367. // ),
  368. // );
  369. Container(
  370. padding: EdgeInsets.only(
  371. left: ScreenUtil().setWidth(15),
  372. right: ScreenUtil().setWidth(15),
  373. top: ScreenUtil().setWidth(15)),
  374. child: ClipRRect(
  375. borderRadius: BorderRadius.circular(5),
  376. child:
  377. new Chewie(
  378. controller: ChewieController(
  379. videoPlayerController:
  380. // VideoPlayerController.network(
  381. // imgFontUrl + detailObj.url
  382. // ),
  383. _controller,
  384. aspectRatio: 3 / 2,
  385. allowFullScreen:false,
  386. autoPlay: false,
  387. looping: true,
  388. // startAt: Duration(seconds: 1,minutes: 1),
  389. showControls: true,
  390. deviceOrientationsAfterFullScreen:[DeviceOrientation.portraitUp],
  391. // 占位图
  392. // placeholder: Image.network(
  393. // imgFontUrl+detailObj.cover,
  394. // fit: BoxFit.contain,
  395. // ),
  396. // 是否在 UI 构建的时候就加载视频
  397. autoInitialize: true,
  398. // 拖动条样式颜色
  399. materialProgressColors:
  400. new ChewieProgressColors(
  401. playedColor: Colors.red,
  402. handleColor: Colors.blue,
  403. backgroundColor: Colors.grey,
  404. bufferedColor: Colors.lightGreen,
  405. ),
  406. ),
  407. ),
  408. )
  409. );
  410. }
  411. }