archive.dart 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460
  1. import 'dart:convert';
  2. import 'package:flutter/cupertino.dart';
  3. import 'package:flutter/material.dart';
  4. import 'package:flutter_screenutil/flutter_screenutil.dart';
  5. import 'package:image_picker/image_picker.dart';
  6. import 'package:liftmanager/internal/account/provider/user_provider.dart';
  7. import 'package:liftmanager/internal/wode/wode_router.dart';
  8. import 'package:liftmanager/net/api_service.dart';
  9. import 'package:liftmanager/res/resources.dart';
  10. import 'package:liftmanager/routers/fluro_navigator.dart';
  11. import 'package:liftmanager/utils/toast.dart';
  12. import 'package:liftmanager/widgets/app_bar.dart';
  13. import 'package:liftmanager/widgets/selected_image_change.dart';
  14. import 'package:liftmanager/widgets/text_field_item.dart';
  15. import 'package:provider/provider.dart';
  16. class Archive extends StatefulWidget {
  17. Archive(this.id);
  18. final String id;
  19. @override
  20. ArchiveState createState() => ArchiveState();
  21. }
  22. class ArchiveState extends State<Archive> {
  23. final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
  24. UserProvider provider = UserProvider();
  25. TextEditingController _title = TextEditingController();
  26. TextEditingController _expression = TextEditingController();
  27. TextEditingController _solution = TextEditingController();
  28. List<String> images = [];
  29. @override
  30. void initState() {
  31. // getBountyList();
  32. getQuestionDetail();
  33. super.initState();
  34. }
  35. dynamic detailObj;
  36. Future getQuestionDetail() async {
  37. await NewApiService().getQuestionDetailAll(int.parse(widget.id),
  38. onSuccess: (res) {
  39. if (res != null) {
  40. detailObj = res.records[0];
  41. print(123456);
  42. print(jsonEncode(res));
  43. _title.text = detailObj.title;
  44. _expression.text = detailObj.expression;
  45. _solution.text = detailObj.solution;
  46. images = [];
  47. detailObj.imgs.split(",").forEach((item) {
  48. images.add(item);
  49. });
  50. setState(() {});
  51. }
  52. }, onError: (code, msg) {
  53. toasts(msg);
  54. });
  55. }
  56. List<String> bountyList = [];
  57. void confirmArchive() {
  58. if (_title.text == '') {
  59. toasts("请输入标题");
  60. return;
  61. }
  62. if (_expression.text == '') {
  63. toasts("请输入问题现象");
  64. return;
  65. }
  66. if (_solution.text == '') {
  67. toasts("请输入解决方案");
  68. return;
  69. }
  70. NewApiService().questionCollect({
  71. "id": detailObj != null ? detailObj.id : null,
  72. "liftCaseId": widget.id,
  73. "title": _title.text,
  74. "expression": _expression.text,
  75. "solution": _solution.text,
  76. "imgs": images.join(",")
  77. }, onSuccess: (res) {
  78. toasts("归档提交成功");
  79. NavigatorUtils.push(context, "${WodeRouter.orderPageMaster}?checkType=0");
  80. setState(() {});
  81. }, onError: (code, msg) {
  82. toasts(msg);
  83. });
  84. }
  85. void getBountyList() {
  86. NewApiService().queryConstant('reward_setting', 'reward', onSuccess: (res) {
  87. print(res);
  88. bountyList.clear();
  89. for (var i = 0; i < res.length; i++) {
  90. bountyList.add(res[i].value);
  91. }
  92. setState(() {});
  93. }, onError: (code, msg) {
  94. toasts(msg);
  95. });
  96. }
  97. ///选择图片
  98. void selectPicker() {
  99. showDialog(
  100. context: context,
  101. builder: (BuildContext context) {
  102. return SimpleDialog(
  103. title: Text("选择方式"),
  104. children: ["拍照", '从手机相册选择'].map((String value) {
  105. print("$value");
  106. return SimpleDialogOption(
  107. child: Text(
  108. "${value}",
  109. style: TextStyle(fontSize: 16, fontWeight: FontWeight.w500),
  110. ),
  111. onPressed: () {
  112. _getImage(value == '拍照' ? 1 : 0);
  113. Navigator.of(context).pop();
  114. },
  115. );
  116. }).toList(),
  117. );
  118. },
  119. );
  120. }
  121. void _getImage(int key) async {
  122. try {
  123. var _imageFile = await ImagePicker.pickImage(
  124. source: key == 1 ? ImageSource.camera : ImageSource.gallery,
  125. maxWidth: 800,
  126. imageQuality: 95);
  127. if (_imageFile != null) {
  128. // images.add(_imageFile);
  129. // setState(() {});
  130. upLoadFileOnce(_imageFile.path);
  131. }
  132. } catch (e) {
  133. toasts("没有权限,无法打开相册!");
  134. }
  135. }
  136. upLoadFileOnce(path) {
  137. showLoading(context, "正在上传...");
  138. NewApiService().upload(path, onSuccess: (res) {
  139. // imagesUrl.add(res.pathUrl);
  140. dismissLoading(context);
  141. setState(() {
  142. images.add(res.pathUrl);
  143. });
  144. }, onError: (code, msg) {
  145. dismissLoading(context);
  146. toasts(msg);
  147. });
  148. }
  149. @override
  150. void dispose() {
  151. // provider.dispose();
  152. super.dispose();
  153. }
  154. FocusNode blankNode = FocusNode();
  155. @override
  156. Widget build(BuildContext context) {
  157. double width = MediaQuery.of(context).size.width;
  158. return
  159. // Center(child:new Text("个人中心"));
  160. ChangeNotifierProvider<UserProvider>(
  161. create: (_) => provider,
  162. child: Scaffold(
  163. key: _scaffoldKey,
  164. resizeToAvoidBottomPadding: false,
  165. appBar: MyAppBar(
  166. centerTitle: "归档",
  167. ),
  168. body: GestureDetector(
  169. onTap: () {
  170. // 点击空白页面关闭键盘
  171. FocusScope.of(context).requestFocus(blankNode);
  172. },
  173. child: Consumer<UserProvider>(
  174. builder: (_, provider, __) {
  175. return Stack(
  176. children: <Widget>[
  177. ListView(
  178. padding: EdgeInsets.all(0.0),
  179. children: <Widget>[
  180. TextFieldItem(
  181. title: "标题",
  182. content: "",
  183. controller: _title,
  184. keyboardType: TextInputType.text,
  185. // maxLength: 30,
  186. hintText: "请输入标题",
  187. onChanged: (res) {},
  188. ),
  189. Container(
  190. decoration: BoxDecoration(
  191. border: Border(
  192. bottom: BorderSide(width: 0.5, color: Colours.line),
  193. ),
  194. ),
  195. child: Column(
  196. children: <Widget>[
  197. Row(
  198. crossAxisAlignment: CrossAxisAlignment.start,
  199. mainAxisAlignment: MainAxisAlignment.start,
  200. children: <Widget>[
  201. Container(
  202. padding: EdgeInsets.only(
  203. left: ScreenUtil().setWidth(15),
  204. top: ScreenUtil().setWidth(10),
  205. bottom: ScreenUtil().setWidth(5),
  206. ),
  207. child: Text(
  208. "问题现象",
  209. textAlign: TextAlign.left,
  210. ),
  211. ),
  212. ],
  213. ),
  214. Container(
  215. padding: EdgeInsets.only(
  216. left: ScreenUtil().setWidth(15),
  217. right: ScreenUtil().setWidth(15),
  218. bottom: ScreenUtil().setWidth(20),
  219. ),
  220. child: TextFormField(
  221. cursorColor: Color(0xffcccccc),
  222. controller: _expression,
  223. maxLines: 5,
  224. maxLength: 500,
  225. decoration: InputDecoration(
  226. contentPadding: EdgeInsets.all(0),
  227. hintText: '请输入问题现象',
  228. hintStyle:
  229. TextStyle(color: Color(0xffcccccc)),
  230. focusedBorder: InputBorder.none,
  231. border: InputBorder.none,
  232. ),
  233. // 校验
  234. validator: (val) {
  235. // return val.trim().length > 0 ? null : "不能为空";
  236. },
  237. ),
  238. ),
  239. ],
  240. ),
  241. ),
  242. Container(
  243. decoration: BoxDecoration(
  244. border: Border(
  245. bottom: BorderSide(width: 0.5, color: Colours.line),
  246. ),
  247. ),
  248. child: Column(
  249. children: <Widget>[
  250. Row(
  251. crossAxisAlignment: CrossAxisAlignment.start,
  252. mainAxisAlignment: MainAxisAlignment.start,
  253. children: <Widget>[
  254. Container(
  255. padding: EdgeInsets.only(
  256. left: ScreenUtil().setWidth(15),
  257. top: ScreenUtil().setWidth(10),
  258. bottom: ScreenUtil().setWidth(5),
  259. ),
  260. child: Text(
  261. "解决方法",
  262. textAlign: TextAlign.left,
  263. ),
  264. ),
  265. ],
  266. ),
  267. Container(
  268. padding: EdgeInsets.only(
  269. left: ScreenUtil().setWidth(15),
  270. right: ScreenUtil().setWidth(15),
  271. bottom: ScreenUtil().setWidth(20),
  272. ),
  273. child: TextFormField(
  274. cursorColor: Color(0xffcccccc),
  275. controller: _solution,
  276. maxLines: 5,
  277. maxLength: 500,
  278. decoration: InputDecoration(
  279. contentPadding: EdgeInsets.all(0),
  280. hintText: '请输入解决方法',
  281. hintStyle:
  282. TextStyle(color: Color(0xffcccccc)),
  283. focusedBorder: InputBorder.none,
  284. border: InputBorder.none,
  285. ),
  286. // 校验
  287. validator: (val) {
  288. // return val.trim().length > 0 ? null : "不能为空";
  289. },
  290. ),
  291. ),
  292. ],
  293. ),
  294. ),
  295. Container(
  296. color: Colors.white,
  297. child: GridView.builder(
  298. shrinkWrap: true,
  299. padding:
  300. const EdgeInsets.fromLTRB(8.0, 12, 8.0, 12.0),
  301. physics: NeverScrollableScrollPhysics(),
  302. gridDelegate:
  303. SliverGridDelegateWithFixedCrossAxisCount(
  304. crossAxisCount: 3, childAspectRatio: 1.18),
  305. itemCount: images.length >= 3 ? 3 : images.length + 1,
  306. itemBuilder: (_, index) {
  307. return Stack(
  308. children: <Widget>[
  309. Center(
  310. child: SelectedImage(
  311. image: index < images.length
  312. ? images[index]
  313. : null,
  314. onTap: () {
  315. if (index >= images.length) {
  316. selectPicker();
  317. }
  318. FocusScope.of(context)
  319. .requestFocus(FocusNode());
  320. },
  321. ),
  322. ),
  323. index < images.length
  324. ? Positioned(
  325. top: 0,
  326. right: 0,
  327. child: GestureDetector(
  328. onTap: () {
  329. print(index);
  330. images.remove(images[index]);
  331. setState(() {});
  332. },
  333. child: Icon(
  334. const IconData(0xe651,
  335. fontFamily: "Iconfont"),
  336. size: 24.0,
  337. color: Color(0xff999999),
  338. ),
  339. ))
  340. : Container(
  341. child: null,
  342. )
  343. ],
  344. );
  345. },
  346. ),
  347. ),
  348. // ChioseThis(
  349. // list: bountyList,
  350. // label: "赏金",
  351. // value: '',
  352. // fun: (index) {
  353. // print(index);
  354. // Navigator.maybePop(context);
  355. // },
  356. // ),
  357. // InkWell(
  358. // onTap: () {
  359. // showPicker(context);
  360. // },
  361. // child: Container(
  362. // height: 50.0,
  363. // margin: const EdgeInsets.only(left: 16.0),
  364. // width: double.infinity,
  365. // decoration: BoxDecoration(
  366. // border: Border(
  367. // bottom: Divider.createBorderSide(context, width: 0.6),
  368. // )),
  369. // child: Row(
  370. // children: <Widget>[
  371. // Padding(
  372. // padding: const EdgeInsets.only(right: 5.0),
  373. // child: Text("赏金"),
  374. // ),
  375. // Expanded(
  376. // flex: 1,
  377. // child: Text(""),
  378. // ),
  379. // Text("请选择"),
  380. // Text(">"),
  381. // Gaps.hGap16
  382. // ],
  383. // ),
  384. // ),
  385. // ),
  386. SizedBox(height: ScreenUtil().setWidth(80))
  387. ],
  388. ),
  389. Positioned(
  390. bottom: 0,
  391. left: 0,
  392. child: Container(
  393. width: width,
  394. padding: EdgeInsets.only(
  395. top: ScreenUtil().setWidth(15),
  396. bottom: ScreenUtil().setWidth(15),
  397. left: ScreenUtil().setWidth(25),
  398. right: ScreenUtil().setWidth(25),
  399. ),
  400. color: Colors.white,
  401. child: Container(
  402. height: ScreenUtil().setWidth(44),
  403. decoration: BoxDecoration(
  404. color: Colours.blue_app_main,
  405. borderRadius: BorderRadius.circular(
  406. ScreenUtil().setWidth(22),
  407. ),
  408. // gradient: const LinearGradient(
  409. // colors: [Color(0xFF00D9FF), Color(0xFF0287FF)],
  410. // ),
  411. ),
  412. child: FlatButton(
  413. // padding: EdgeInsets.all(15.0),
  414. child: Text("立即归档"),
  415. textColor: Colors.white,
  416. // textColor: Colors.white,
  417. onPressed: () {
  418. if (_title.text.length > 30) {
  419. toasts("标题长度不得大于30!");
  420. } else {
  421. confirmArchive();
  422. }
  423. },
  424. ),
  425. ),
  426. ),
  427. )
  428. ],
  429. );
  430. },
  431. ),
  432. ),
  433. ),
  434. );
  435. }
  436. @override
  437. bool get wantKeepAlive => true;
  438. }