product_detail.dart 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539
  1. import 'dart:math';
  2. import 'package:flustars/flustars.dart' as FlutterStars;
  3. import 'package:flutter/material.dart';
  4. import 'package:flutter_screenutil/flutter_screenutil.dart';
  5. import 'package:flutter_swiper/flutter_swiper.dart';
  6. import 'package:fluwx/fluwx.dart' as fluwx;
  7. import 'package:liftmanager/common/common.dart';
  8. import 'package:liftmanager/internal/account/account_router.dart';
  9. import 'package:liftmanager/internal/bbs/model/shop_detail.dart';
  10. import 'package:liftmanager/net/api_service.dart';
  11. import 'package:liftmanager/res/iconfont.dart';
  12. import 'package:liftmanager/res/resources.dart';
  13. import 'package:liftmanager/routers/fluro_navigator.dart';
  14. import 'package:liftmanager/utils/fast_notification.dart';
  15. import 'package:liftmanager/utils/theme_utils.dart';
  16. import 'package:liftmanager/utils/toast.dart';
  17. import 'package:liftmanager/utils/url.dart';
  18. import 'package:liftmanager/widgets/app_bar.dart';
  19. import 'package:liftmanager/widgets/load_image.dart';
  20. import 'package:umeng_common_sdk/umeng_common_sdk.dart';
  21. import 'package:url_launcher/url_launcher.dart';
  22. import 'package:liftmanager/widgets/preview_images.dart';
  23. import '../../recommend_ask.dart';
  24. class ProductDetail extends StatefulWidget {
  25. ProductDetail(this.id);
  26. final String id;
  27. @override
  28. State<StatefulWidget> createState() {
  29. return ProductDetailState();
  30. }
  31. }
  32. class ProductDetailState extends State<ProductDetail> {
  33. @override
  34. void initState() {
  35. UmengCommonSdk.onPageStart("商品详情");
  36. super.initState();
  37. getShopDetail();
  38. }
  39. @override
  40. void dispose() {
  41. UmengCommonSdk.onPageEnd("商品详情");
  42. super.dispose();
  43. }
  44. bool _hasData = false;
  45. ShopDetailModel detailObj;
  46. Future getShopDetail() async {
  47. await NewApiService().getShopDetail(int.parse(widget.id), 1,
  48. onSuccess: (res) {
  49. if (res != null) {
  50. _hasData = true;
  51. detailObj = res;
  52. setState(() {});
  53. }
  54. }, onError: (code, msg) {
  55. toasts(msg);
  56. });
  57. }
  58. showAlertEvent() {
  59. showAlert(
  60. context,
  61. "提示",
  62. "确定登录?",
  63. "确定",
  64. () {
  65. NavigatorUtils.push(context, AccountRouter.loginPage, clearStack: true);
  66. },
  67. txt2: "取消",
  68. onPre2: () {
  69. NavigatorUtils.goBack(context);
  70. },
  71. );
  72. }
  73. Future changeFav(type) async {
  74. await NewApiService().shopFav(detailObj.id, type, 1, onSuccess: (res) {
  75. toasts("收藏成功");
  76. initCollect();
  77. getShopDetail();
  78. }, onError: (code, msg) {
  79. toasts(msg);
  80. });
  81. }
  82. Future cancelFav() async {
  83. await NewApiService().shopFavCancel(detailObj.favoriteId, onSuccess: (res) {
  84. toasts("取消收藏成功");
  85. initCollect();
  86. getShopDetail();
  87. }, onError: (code, msg) {
  88. toasts(msg);
  89. });
  90. }
  91. _launchPhone(url) async {
  92. if (await canLaunch(url)) {
  93. await launch(url);
  94. } else {
  95. throw 'Could not launch $url';
  96. }
  97. }
  98. initCollect() {
  99. String collectInit = randomInt(1111, 9999).toString() +
  100. DateTime.now().millisecondsSinceEpoch.toString();
  101. FastNotification.push("collectAction", collectInit);
  102. }
  103. randomInt(int min, int max) {
  104. return new Random().nextInt(max) % (max - min + 1) + min;
  105. }
  106. @override
  107. Widget build(BuildContext context) {
  108. double width = MediaQuery.of(context).size.width;
  109. return Scaffold(
  110. resizeToAvoidBottomPadding: false, //不让键盘弹上去
  111. appBar: MyAppBar(
  112. centerTitle: "商品详情",
  113. ),
  114. body: _hasData
  115. ? Stack(
  116. children: <Widget>[
  117. Container(
  118. child: ListView(children: <Widget>[
  119. Column(
  120. mainAxisAlignment: MainAxisAlignment.start,
  121. crossAxisAlignment: CrossAxisAlignment.start,
  122. children: <Widget>[
  123. Container(
  124. padding: EdgeInsets.symmetric(horizontal: 10),
  125. decoration: BoxDecoration(
  126. border: Border(
  127. bottom: BorderSide(width: 0.5, color: Colours.line),
  128. ),
  129. ),
  130. child: Column(
  131. mainAxisAlignment: MainAxisAlignment.start,
  132. crossAxisAlignment: CrossAxisAlignment.start,
  133. children: <Widget>[
  134. Container(
  135. width: width,
  136. height: ScreenUtil().setWidth(220),
  137. padding: EdgeInsets.only(bottom: 10),
  138. child: Container(
  139. child: Swiper(
  140. itemBuilder: (BuildContext context, index) {
  141. return Container(
  142. width: width,
  143. height: ScreenUtil().setWidth(220),
  144. key: Key(
  145. detailObj.imgs.split(",")[index]),
  146. child: LoadNetworkImage(
  147. detailObj.imgs.split(",")[index],
  148. width: width,
  149. height: ScreenUtil().setWidth(220),
  150. fit: BoxFit.fill,
  151. isWater: true,
  152. ),
  153. );
  154. },
  155. pagination: SwiperPagination(
  156. builder: DotSwiperPaginationBuilder(
  157. color: Colors.grey,
  158. activeColor: Colors.white,
  159. size: 6,
  160. activeSize: 6)),
  161. itemCount: detailObj.imgs.split(",").length,
  162. scrollDirection: Axis.horizontal,
  163. autoplay: false,
  164. onTap: (index) {
  165. Navigator.of(context).push(
  166. FadeRoute(
  167. page: PhotoViewGalleryScreen(
  168. images: detailObj.imgs
  169. .split(","), //传入图片list
  170. index: index, //传入当前点击的图片的index
  171. // heroTag: img,//传入当前点击的图片的hero tag (可选)
  172. ),
  173. ),
  174. );
  175. // print(index);
  176. },
  177. ),
  178. ),
  179. ),
  180. SizedBox(height: 5),
  181. Text(
  182. detailObj.name ?? "",
  183. style:
  184. TextStyle(fontSize: ScreenUtil().setSp(16)),
  185. textAlign: TextAlign.start,
  186. ),
  187. SizedBox(
  188. height: 10,
  189. ),
  190. if (detailObj.brandName != null)
  191. Container(
  192. padding: EdgeInsets.all(3),
  193. decoration: BoxDecoration(
  194. color: Color(0x33448EFA),
  195. ),
  196. child: Text(
  197. detailObj.brandName ?? "",
  198. style: TextStyle(
  199. color: Color(0xff5888FF),
  200. fontSize: 11,
  201. fontWeight: FontWeight.w500,
  202. ),
  203. textAlign: TextAlign.start,
  204. ),
  205. ),
  206. SizedBox(
  207. height: 10,
  208. ),
  209. Row(
  210. crossAxisAlignment: CrossAxisAlignment.baseline,
  211. children: <Widget>[
  212. if (detailObj.discountPrice != null)
  213. Text(
  214. '¥${detailObj.discountPrice.toInt()}',
  215. style: TextStyle(
  216. color: Color(0xffFF5C00),
  217. fontSize: 16,
  218. ),
  219. ),
  220. if (detailObj.discountPrice == null)
  221. Text(
  222. '¥${detailObj.price?.toInt() ?? '暂无'}',
  223. style: TextStyle(
  224. color: Color(0xffFF5C00),
  225. fontSize: 16,
  226. ),
  227. ),
  228. if (detailObj.discountPrice != null)
  229. Text(
  230. '¥${detailObj.price.toInt()}',
  231. style: TextStyle(
  232. color: Color(0xff999999),
  233. fontSize: 11,
  234. decoration: TextDecoration.lineThrough,
  235. ),
  236. ),
  237. // Text(
  238. // '¥${detailObj?.price?.toInt() ?? ""}',
  239. // style: TextStyle(
  240. // color: Color(0xffFF5B00),
  241. // fontSize: 16,
  242. // ),
  243. // textAlign: TextAlign.start,
  244. // ),
  245. ],
  246. ),
  247. SizedBox(height: 15),
  248. ]),
  249. ),
  250. Column(
  251. crossAxisAlignment: CrossAxisAlignment.start,
  252. mainAxisAlignment: MainAxisAlignment.start,
  253. children: <Widget>[
  254. SizedBox(
  255. height: 10,
  256. ),
  257. Container(
  258. padding: EdgeInsets.only(left: 10),
  259. decoration: BoxDecoration(
  260. border: Border(
  261. left: BorderSide(
  262. width: 2,
  263. color: Color(0xff568AFF),
  264. ),
  265. ),
  266. ),
  267. child: Text(
  268. "商品简介",
  269. style: TextStyle(
  270. fontSize: 15,
  271. color: Color(0xff333333),
  272. ),
  273. textAlign: TextAlign.left,
  274. ),
  275. ),
  276. SizedBox(
  277. height: 10,
  278. ),
  279. Container(
  280. padding: EdgeInsets.symmetric(horizontal: 10),
  281. child: Text(
  282. detailObj.descr,
  283. style: TextStyle(
  284. color: Color(0xff333333), fontSize: 13),
  285. textAlign: TextAlign.left,
  286. ),
  287. ),
  288. ],
  289. ),
  290. SizedBox(
  291. height: 10,
  292. ),
  293. Container(
  294. height: 1,
  295. color: ThemeUtils.getDialogTextFieldColor(context)),
  296. Column(
  297. crossAxisAlignment: CrossAxisAlignment.start,
  298. mainAxisAlignment: MainAxisAlignment.start,
  299. children: <Widget>[
  300. SizedBox(
  301. height: 10,
  302. ),
  303. Container(
  304. padding: EdgeInsets.only(left: 10),
  305. decoration: BoxDecoration(
  306. border: Border(
  307. left: BorderSide(
  308. width: 2,
  309. color: Color(0xff568AFF),
  310. ),
  311. ),
  312. ),
  313. child: Text(
  314. "商家信息",
  315. style: TextStyle(
  316. color: Color(0xff333333),
  317. fontSize: 15,
  318. ),
  319. textAlign: TextAlign.left,
  320. ),
  321. ),
  322. SizedBox(
  323. height: 10,
  324. ),
  325. Container(
  326. padding: EdgeInsets.symmetric(
  327. horizontal: 10,
  328. ),
  329. child: Column(children: [
  330. Row(
  331. children: [
  332. Icon(
  333. Iconfont.shangjia,
  334. color: Colors.orange,
  335. size: 13,
  336. ),
  337. SizedBox(
  338. width: 10,
  339. ),
  340. Text(
  341. "${detailObj.manufacturer}",
  342. style: TextStyle(
  343. color: Color(0xff666666),
  344. fontSize: 11,
  345. ),
  346. textAlign: TextAlign.left,
  347. ),
  348. ],
  349. ),
  350. SizedBox(
  351. height: 10,
  352. ),
  353. Row(
  354. children: [
  355. Icon(
  356. Iconfont.lianxi,
  357. color: Colors.orange,
  358. size: 13,
  359. ),
  360. SizedBox(
  361. width: 10,
  362. ),
  363. Text(
  364. "${detailObj.telephone} (${detailObj.contactPerson})",
  365. style: TextStyle(
  366. color: Color(0xff666666),
  367. fontSize: 11,
  368. ),
  369. textAlign: TextAlign.left,
  370. ),
  371. ],
  372. ),
  373. ]),
  374. ),
  375. ],
  376. ),
  377. SizedBox(height: ScreenUtil().setWidth(70))
  378. ],
  379. ),
  380. ])),
  381. Positioned(
  382. bottom: 0,
  383. left: 0,
  384. child: Container(
  385. width: width,
  386. color: Colors.white,
  387. padding: EdgeInsets.all(10),
  388. child: Row(
  389. crossAxisAlignment: CrossAxisAlignment.center,
  390. children: <Widget>[
  391. Expanded(
  392. child: Row(
  393. mainAxisAlignment: MainAxisAlignment.spaceAround,
  394. children: [
  395. GestureDetector(
  396. onTap: () {
  397. if (FlutterStars.SpUtil.getString(
  398. Constant.userId) ==
  399. "-1") {
  400. showAlertEvent();
  401. } else {
  402. String initThis =
  403. randomInt(1111, 9999).toString() +
  404. DateTime.now()
  405. .millisecondsSinceEpoch
  406. .toString();
  407. fluwx
  408. .shareToWeChat(
  409. fluwx.WeChatShareWebPageModel(
  410. scene: fluwx.WeChatScene.SESSION,
  411. webPage:
  412. "$jumpUrl/h5/index.html?num=$initThis&page=/bbs/productDetail&id=${widget.id}",
  413. title: detailObj.name,
  414. description: detailObj.descr,
  415. thumbnail: detailObj.imgs.split(",")[0],
  416. ))
  417. .then((result) {}, onError: (msg) {
  418. // print(msg);
  419. });
  420. }
  421. },
  422. child: Container(
  423. // padding: EdgeInsets.only(left:25,right:30),
  424. child: Column(children: <Widget>[
  425. Icon(
  426. Iconfont.fenxiang,
  427. size: 20.0,
  428. color: Color(0xff333333),
  429. ),
  430. Text(
  431. "分享",
  432. style: TextStyle(
  433. color: Color(0xff555A64),
  434. fontSize: 12,
  435. ),
  436. textAlign: TextAlign.start,
  437. ),
  438. ])),
  439. ),
  440. GestureDetector(
  441. onTap: () {
  442. if (FlutterStars.SpUtil.getString(
  443. Constant.userId) ==
  444. "-1") {
  445. showAlertEvent();
  446. } else {
  447. if (detailObj.isFavorite == 1) {
  448. cancelFav();
  449. } else {
  450. changeFav(3);
  451. }
  452. }
  453. },
  454. child: Container(
  455. child: Column(children: <Widget>[
  456. Icon(
  457. // : 0xe604,&#xe62a;
  458. detailObj.isFavorite == 1
  459. ? Iconfont.shoucang1
  460. : Iconfont.shoucang,
  461. size: 20.0,
  462. color: Color(detailObj.isFavorite == 1
  463. ? 0xff5589FF
  464. : 0xff555A64),
  465. ),
  466. Text(
  467. detailObj.isFavorite == 1 ? "已收藏" : "收藏",
  468. style: TextStyle(
  469. color: Color(detailObj.isFavorite == 1
  470. ? 0xff5589FF
  471. : 0xff555A64),
  472. fontSize: 12,
  473. ),
  474. textAlign: TextAlign.start,
  475. ),
  476. ])),
  477. ),
  478. ],
  479. ),
  480. ),
  481. Container(
  482. height: 45,
  483. width: 240,
  484. decoration: BoxDecoration(
  485. color: Color(0xff5589FF),
  486. borderRadius: BorderRadius.circular(30),
  487. ),
  488. child: FlatButton(
  489. // padding: EdgeInsets.all(15.0),
  490. child: Text(
  491. "联系商家",
  492. style: TextStyle(
  493. fontSize: 16,
  494. ),
  495. ),
  496. textColor: Colors.white,
  497. onPressed: () {
  498. if (FlutterStars.SpUtil.getString(
  499. Constant.userId) ==
  500. "-1") {
  501. showAlertEvent();
  502. } else {
  503. _launchPhone("tel:" + detailObj.telephone);
  504. }
  505. },
  506. ),
  507. ),
  508. ],
  509. ),
  510. ),
  511. )
  512. ],
  513. )
  514. : Center(
  515. child: Text("正在加载..."),
  516. ),
  517. );
  518. }
  519. }