view.dart 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642
  1. import 'package:electronic_assistant/base/base_page.dart';
  2. import 'package:electronic_assistant/resource/assets.gen.dart';
  3. import 'package:electronic_assistant/resource/colors.gen.dart';
  4. import 'package:electronic_assistant/utils/expand.dart';
  5. import 'package:electronic_assistant/widget/login_code_btn.dart';
  6. import 'package:flutter/material.dart';
  7. import 'package:flutter/services.dart';
  8. import 'package:flutter_screenutil/flutter_screenutil.dart';
  9. import 'package:get/get.dart';
  10. import 'controller.dart';
  11. class StorePage extends BasePage<StoreController> {
  12. const StorePage({super.key});
  13. @override
  14. bool immersive() {
  15. return true;
  16. }
  17. @override
  18. Widget buildBody(BuildContext context) {
  19. return Stack(
  20. children: [
  21. Stack(
  22. alignment: AlignmentDirectional.topStart,
  23. children: [
  24. _buildBackgroundGradient(),
  25. _buildTopBG(),
  26. Positioned(
  27. left: 12.w,
  28. top: 280,
  29. width: ScreenUtil().screenWidth - 24.w,
  30. child: Column(
  31. crossAxisAlignment: CrossAxisAlignment.start,
  32. children: [
  33. SizedBox(
  34. height: 20.h,
  35. child: Assets.images.iconStoreDescripe.image(),
  36. ),
  37. SizedBox(
  38. height: 16.h,
  39. ),
  40. _buildGoods(),
  41. SizedBox(
  42. height: 16.h,
  43. ),
  44. Text(
  45. "·该套餐约可倾听45小时",
  46. style: TextStyle(
  47. fontSize: 10.sp,
  48. color: "#AFAFAF".toColor(),
  49. ),
  50. ),
  51. SizedBox(
  52. height: 16.h,
  53. ),
  54. _buildPayMethod(),
  55. SizedBox(
  56. height: 39.h,
  57. ),
  58. _buildService(),
  59. ],
  60. ),
  61. ),
  62. ],
  63. ),
  64. _buildTopBar(),
  65. Positioned(
  66. bottom: 0,
  67. left: 0,
  68. right: 0,
  69. child: _buildBottombar(),
  70. ),
  71. ],
  72. );
  73. }
  74. // 背景颜色
  75. Widget _buildBackgroundGradient() {
  76. return Container(
  77. width: 1.sw,
  78. height: 1.sh,
  79. decoration: BoxDecoration(
  80. gradient: LinearGradient(
  81. colors: ['#071935'.toColor(), '#283B58'.toColor()],
  82. begin: Alignment.topCenter,
  83. end: Alignment.bottomCenter,
  84. stops: const [0.4, 1.0],
  85. ),
  86. ),
  87. );
  88. }
  89. // 顶部背景图片
  90. Widget _buildTopBG() {
  91. return Assets.images.bgStoreTop.image();
  92. }
  93. Widget _buildTopBar() {
  94. return Container(
  95. height: 44.h,
  96. margin: EdgeInsets.only(
  97. left: 0,
  98. right: 0,
  99. top: ScreenUtil().statusBarHeight,
  100. ),
  101. padding: EdgeInsets.symmetric(horizontal: 12.w),
  102. child: Row(
  103. children: [
  104. IconButton(
  105. onPressed: () {},
  106. icon: ImageIcon(
  107. Assets.images.iconArrowBackWhite.provider(),
  108. color: Colors.white,
  109. ),
  110. ),
  111. const Spacer(),
  112. Container(
  113. padding:
  114. EdgeInsets.only(left: 6.w, top: 6.h, bottom: 6.h, right: 12.w),
  115. decoration: BoxDecoration(
  116. color: "#01051C".toColor(),
  117. border: Border.all(
  118. color: "#7688B1".toColor(),
  119. width: 1,
  120. ),
  121. borderRadius: BorderRadius.circular(16.h),
  122. ),
  123. child: Row(
  124. children: [
  125. SizedBox(
  126. width: 20,
  127. child: Assets.images.iconStoreLogo.image(),
  128. ),
  129. SizedBox(
  130. width: 3.w,
  131. ),
  132. const Text(
  133. "电量 ",
  134. style: TextStyle(
  135. fontSize: 12,
  136. color: Colors.white,
  137. ),
  138. ),
  139. Text(
  140. "600",
  141. style: TextStyle(
  142. fontSize: 12,
  143. color: Colors.white,
  144. ),
  145. ),
  146. ],
  147. ),
  148. ),
  149. ],
  150. ),
  151. );
  152. }
  153. Widget _buildGoods() {
  154. return ListView.builder(
  155. padding: const EdgeInsets.only(top: 0),
  156. physics: const NeverScrollableScrollPhysics(),
  157. itemBuilder: (context, index) {
  158. return _buildGoodItem();
  159. },
  160. itemCount: 2,
  161. );
  162. }
  163. Widget _buildGoodItem() {
  164. return Container(
  165. height: 154,
  166. child: Stack(
  167. clipBehavior: Clip.none,
  168. children: [
  169. Positioned(
  170. left: 0,
  171. top: 10,
  172. width: 132,
  173. height: 144,
  174. child: Container(
  175. padding: const EdgeInsets.all(2),
  176. decoration: BoxDecoration(
  177. borderRadius: BorderRadius.circular(12),
  178. gradient: LinearGradient(
  179. colors: ['#9075FF'.toColor(), '#4366FF'.toColor()],
  180. begin: Alignment.centerLeft,
  181. end: Alignment.centerRight,
  182. stops: const [0.0, 1.0],
  183. ),
  184. ),
  185. child: Container(
  186. width: 128,
  187. decoration: BoxDecoration(
  188. gradient: LinearGradient(
  189. colors: ['#FFF3F6'.toColor(), '#DADBFF'.toColor()],
  190. begin: Alignment.topCenter,
  191. end: Alignment.bottomCenter,
  192. stops: const [0.0, 1.0],
  193. ),
  194. borderRadius: BorderRadius.circular(12),
  195. ),
  196. child: Column(
  197. mainAxisAlignment: MainAxisAlignment.start,
  198. children: [
  199. SizedBox(
  200. height: 12,
  201. ),
  202. Text(
  203. "大电池",
  204. style: TextStyle(
  205. fontSize: 13,
  206. fontWeight: FontWeight.w700,
  207. color: "#6177F2".toColor(),
  208. ),
  209. ),
  210. Row(
  211. crossAxisAlignment: CrossAxisAlignment.end,
  212. mainAxisAlignment: MainAxisAlignment.center,
  213. mainAxisSize: MainAxisSize.min,
  214. children: [
  215. Container(
  216. margin: EdgeInsets.only(bottom: 9),
  217. child: Text(
  218. "¥",
  219. style: TextStyle(
  220. fontSize: 16,
  221. color: "#6177F2".toColor(),
  222. ),
  223. ),
  224. ),
  225. Text(
  226. "198",
  227. textAlign: TextAlign.center,
  228. style: TextStyle(
  229. fontSize: 39,
  230. fontWeight: FontWeight.bold,
  231. color: "#6177F2".toColor(),
  232. ),
  233. ),
  234. ],
  235. ),
  236. Text(
  237. "¥258",
  238. style: TextStyle(
  239. color: "#AFAFAF".toColor(),
  240. decoration: TextDecoration.lineThrough,
  241. decorationColor: "#AFAFAF".toColor(),
  242. fontSize: 14.0,
  243. ),
  244. ),
  245. Container(
  246. padding: EdgeInsets.symmetric(horizontal: 8, vertical: 4),
  247. decoration: BoxDecoration(
  248. gradient: LinearGradient(
  249. colors: ['#9075FF'.toColor(), '#4366FF'.toColor()],
  250. begin: Alignment.topCenter,
  251. end: Alignment.bottomCenter,
  252. stops: const [0.0, 1.0],
  253. ),
  254. borderRadius: BorderRadius.circular(12),
  255. ),
  256. child: Expanded(
  257. child: Row(
  258. mainAxisSize: MainAxisSize.min,
  259. children: [
  260. SizedBox(
  261. width: 16,
  262. child: Assets.images.iconStoreGoodFlash.image(),
  263. ),
  264. Text(
  265. "550电量",
  266. style: TextStyle(
  267. fontSize: 13,
  268. color: Colors.white,
  269. ),
  270. )
  271. ],
  272. ),
  273. ),
  274. )
  275. ],
  276. ),
  277. ),
  278. ),
  279. ),
  280. Stack(
  281. children: [
  282. Container(
  283. height: 29,
  284. child: Assets.images.iconStoreGoodTag.image(),
  285. ),
  286. Positioned(
  287. left: 8,
  288. top: 2,
  289. child: Text(
  290. "最多人买",
  291. style: TextStyle(
  292. fontSize: 12,
  293. fontWeight: FontWeight.w500,
  294. color: "#703D27".toColor(),
  295. ),
  296. ),
  297. ),
  298. ],
  299. ),
  300. ],
  301. ),
  302. );
  303. }
  304. Widget _buildTopPayMethod(Image icon, String title) {
  305. return Row(
  306. children: [
  307. SizedBox(
  308. width: 20.w,
  309. child: icon,
  310. ),
  311. const SizedBox(
  312. width: 6,
  313. ),
  314. Text(
  315. title,
  316. style: TextStyle(color: Colors.white, fontSize: 14.sp),
  317. ),
  318. ],
  319. );
  320. }
  321. Widget _buildPayMethod() {
  322. return Column(
  323. children: [
  324. Row(
  325. children: [
  326. Text(
  327. "支付方式",
  328. style: TextStyle(
  329. fontSize: 14.sp,
  330. color: Colors.white,
  331. fontWeight: FontWeight.w500,
  332. ),
  333. ),
  334. const Spacer(),
  335. Obx(() {
  336. return GestureDetector(
  337. onTap: () {
  338. controller.isExpanded.value = !controller.isExpanded.value;
  339. },
  340. child: Row(
  341. children: [
  342. Visibility(
  343. visible: !controller.isExpanded.value,
  344. child: _buildTopPayMethod(
  345. Assets.images.iconStoreAlipay.image(),
  346. "支付宝",
  347. ),
  348. ),
  349. Visibility(
  350. visible: controller.isExpanded.value,
  351. child: Text(
  352. "收起",
  353. style: TextStyle(
  354. fontSize: 14.sp,
  355. color: Colors.white,
  356. ),
  357. ),
  358. ),
  359. Container(
  360. width: 16.w,
  361. child: controller.isExpanded.value
  362. ? Assets.images.iconArrowUpWhite.image()
  363. : Assets.images.iconArrowDownWhite.image(),
  364. ),
  365. ],
  366. ),
  367. );
  368. }),
  369. ],
  370. ),
  371. Obx(() {
  372. return Visibility(
  373. visible: controller.isExpanded.value,
  374. child: SizedBox(
  375. height: 2 * 32,
  376. child: ListView.builder(
  377. padding: const EdgeInsets.only(top: 0),
  378. physics: const NeverScrollableScrollPhysics(),
  379. itemBuilder: (context, index) {
  380. return _buildPayItem(
  381. Assets.images.iconStoreAlipay.image().obs.value,
  382. "支付宝",
  383. true);
  384. },
  385. itemCount: 2,
  386. ),
  387. ),
  388. );
  389. }),
  390. ],
  391. );
  392. }
  393. Widget _buildPayItem(Image icon, String title, bool isSelect) {
  394. return Container(
  395. height: 20.h,
  396. margin: const EdgeInsets.only(top: 12),
  397. child: Row(
  398. children: [
  399. SizedBox(
  400. width: 20.w,
  401. child: icon,
  402. ),
  403. const SizedBox(
  404. width: 6,
  405. ),
  406. Text(
  407. title,
  408. style: TextStyle(color: Colors.white, fontSize: 14.sp),
  409. ),
  410. const Spacer(),
  411. GestureDetector(
  412. onTap: () {
  413. // controller.isAgree.value = !controller.isAgree.value;
  414. },
  415. child: SizedBox(
  416. width: 20.w,
  417. height: 20.w,
  418. child: isSelect
  419. ? Assets.images.iconSelectTrue.image()
  420. : Assets.images.iconSelectFalse.image(),
  421. ),
  422. ),
  423. ],
  424. ),
  425. );
  426. }
  427. Widget _buildService() {
  428. return Column(
  429. children: [
  430. Row(
  431. children: [
  432. Container(
  433. width: 4.w,
  434. height: 16.h,
  435. decoration: BoxDecoration(
  436. color: Colors.white,
  437. borderRadius: BorderRadius.circular(2),
  438. gradient: LinearGradient(
  439. colors: ['#357AFF'.toColor(), '#E389FF'.toColor()],
  440. begin: Alignment.topCenter,
  441. end: Alignment.bottomCenter,
  442. stops: const [0.0, 1.0],
  443. ),
  444. ),
  445. ),
  446. SizedBox(
  447. width: 6.w,
  448. ),
  449. Text(
  450. "多种专属服务·高效辅助办公",
  451. style: TextStyle(
  452. fontSize: 15.sp,
  453. color: Colors.white,
  454. fontWeight: FontWeight.w500,
  455. ),
  456. ),
  457. ],
  458. ),
  459. Container(
  460. padding: EdgeInsets.only(
  461. left: 9,
  462. right: 9,
  463. top: 16,
  464. ),
  465. child: Row(
  466. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  467. children: [
  468. _buildServiceItem(
  469. Assets.images.iconStoreServiceSum.image(),
  470. "智能谈话总结",
  471. ),
  472. _buildServiceItem(
  473. Assets.images.iconStoreServiceRemain.image(),
  474. "待办任务处理",
  475. ),
  476. _buildServiceItem(
  477. Assets.images.iconStoreServiceAdvice.image(),
  478. "专业工作建议",
  479. ),
  480. _buildServiceItem(
  481. Assets.images.iconStoreServiceDeal.image(),
  482. "处理交代事宜",
  483. ),
  484. ],
  485. ),
  486. ),
  487. SizedBox(
  488. height: 26.h,
  489. ),
  490. Container(
  491. width: double.infinity,
  492. padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 12),
  493. decoration: BoxDecoration(
  494. color: "#40567D".toColor().withOpacity(0.2),
  495. borderRadius: BorderRadius.circular(8),
  496. ),
  497. child: Column(
  498. crossAxisAlignment: CrossAxisAlignment.start,
  499. children: [
  500. Text(
  501. "扣电规则",
  502. style: TextStyle(
  503. fontSize: 12,
  504. fontWeight: FontWeight.w500,
  505. color: Colors.white.withOpacity(0.6),
  506. ),
  507. ),
  508. SizedBox(
  509. height: 6.h,
  510. ),
  511. Text(
  512. "1、小听每听5分钟扣1电量,不满5分钟按5分钟算。",
  513. style: TextStyle(
  514. fontSize: 12,
  515. color: Colors.white.withOpacity(0.6),
  516. ),
  517. ),
  518. Text(
  519. "2、大文件、超大文件生成新的总结,每次扣1电量。",
  520. style: TextStyle(
  521. fontSize: 12,
  522. fontWeight: FontWeight.w500,
  523. color: Colors.white.withOpacity(0.6),
  524. ),
  525. ),
  526. Text(
  527. "3、用大文件和小听对话,每次对话扣1电量。",
  528. style: TextStyle(
  529. fontSize: 12,
  530. fontWeight: FontWeight.w500,
  531. color: Colors.white.withOpacity(0.6),
  532. ),
  533. ),
  534. ],
  535. ),
  536. ),
  537. ],
  538. );
  539. }
  540. Widget _buildServiceItem(Image icon, String title) {
  541. return Column(
  542. children: [
  543. SizedBox(
  544. width: 32.w,
  545. child: icon,
  546. ),
  547. SizedBox(
  548. height: 2.h,
  549. ),
  550. Text(
  551. title,
  552. style: TextStyle(
  553. color: ColorName.white.withOpacity(0.8),
  554. fontSize: 11.sp,
  555. ),
  556. ),
  557. ],
  558. );
  559. }
  560. Widget _buildBottombar() {
  561. return Container(
  562. padding: EdgeInsets.only(
  563. left: 16.w,
  564. right: 16.w,
  565. top: 12.h,
  566. bottom: ScreenUtil().bottomBarHeight + 12.h),
  567. alignment: Alignment.topCenter,
  568. decoration: BoxDecoration(
  569. color: "#283B58".toColor(),
  570. boxShadow: const [
  571. BoxShadow(
  572. color: Color.fromARGB(1, 42, 48, 59), // 阴影颜色
  573. spreadRadius: 0, // 阴影扩散半径
  574. blurRadius: 20, // 阴影模糊半径
  575. offset: Offset(0, 0), // 阴影偏移量
  576. ),
  577. ],
  578. borderRadius: BorderRadius.only(
  579. topLeft: Radius.circular(12.w),
  580. topRight: Radius.circular(12.w),
  581. ),
  582. ),
  583. child: GestureDetector(
  584. onTap: () {
  585. // print(ScreenUtil().bottomBarHeight);
  586. },
  587. child: Container(
  588. height: 48.h,
  589. alignment: Alignment.center,
  590. decoration: BoxDecoration(
  591. gradient: LinearGradient(
  592. colors: ['#9075FF'.toColor(), '#4366FF'.toColor()],
  593. begin: Alignment.centerRight,
  594. end: Alignment.centerRight,
  595. stops: const [0.0, 1.0],
  596. ),
  597. borderRadius: BorderRadius.circular(8.h),
  598. ),
  599. child: Row(
  600. mainAxisAlignment: MainAxisAlignment.center,
  601. children: [
  602. Text(
  603. "立即购买",
  604. style: TextStyle(
  605. color: Colors.white,
  606. fontSize: 16.sp,
  607. fontWeight: FontWeight.w500,
  608. ),
  609. ),
  610. SizedBox(
  611. width: 4.w,
  612. ),
  613. Text(
  614. "¥198",
  615. style: TextStyle(
  616. color: Colors.white,
  617. fontSize: 18.sp,
  618. fontWeight: FontWeight.w500,
  619. ),
  620. ),
  621. ],
  622. ),
  623. ),
  624. ),
  625. );
  626. }
  627. }