Преглед изворни кода

Merge remote-tracking branch 'origin/v1.0.0' into v1.0.0

hezihao пре 8 месеци
родитељ
комит
44f4800c63

BIN
assets/images/icon_dialog_pay_fail.webp


BIN
assets/images/icon_dialog_pay_fail_service.webp


BIN
assets/images/icon_dialog_pay_success.webp


+ 11 - 2
assets/string/base/string.xml

@@ -172,11 +172,20 @@
     <string name="member_payment_failed">开通失败,请稍后重试</string>
 
     <string name="member_agreement_dialog_title">请阅读并同意以下协议</string>
-    <string name="member_agreement_dialog_agreement">《会员协议》</string>
-    <string name="member_agreement_dialog_auto_renewal">《自动续费协议》。</string>
+
     <string name="member_agreement_dialog_desc">进入下一步前,请先阅读并同意</string>
 
     <string name="member_agreement_dialog_confirm">确定</string>
     <string name="member_agreement_dialog_cancel">取消</string>
 
+    <string name="pay_fail_dialog_title">支付遇到问题</string>
+    <string name="pay_fail_dialog_desc">您可以联系在线客服帮您解决</string>
+    <string name="pay_fail_dialog_continue">继续支付</string>
+    <string name="pay_fail_dialog_cancel">联系客服</string>
+
+    <string name="pay_success_dialog_title">支付成功</string>
+    <string name="pay_success_dialog_desc">到期。</string>
+    <string name="pay_success_dialog_confirm">知道了</string>
+    <string name="pay_success_dialog_permanent">恭喜您成为终身会员,感谢您的支持</string>
+
 </resources>

+ 4 - 0
lib/data/bean/goods_info.dart

@@ -31,6 +31,8 @@ class GoodsInfo {
   String? discountDesc;
   @JsonKey(name: 'mostDesc')
   String? mostDesc;
+  @JsonKey(name: 'selectDesc')
+  String? selectDesc;
 
   GoodsInfo({
     required this.id,
@@ -46,6 +48,7 @@ class GoodsInfo {
     this.description,
     this.discountDesc,
     this.mostDesc,
+    this.selectDesc,
   });
 
   get amountText => (amount / 100).toFormattedString(2);
@@ -76,6 +79,7 @@ class GoodsInfo {
       description: description,
       discountDesc: discountDesc,
       mostDesc: mostDesc,
+      selectDesc: selectDesc,
     );
   }
 }

+ 2 - 0
lib/data/bean/goods_info.g.dart

@@ -23,6 +23,7 @@ GoodsInfo _$GoodsInfoFromJson(Map<String, dynamic> json) => GoodsInfo(
   description: json['description'] as String?,
   discountDesc: json['discountDesc'] as String?,
   mostDesc: json['mostDesc'] as String?,
+  selectDesc: json['selectDesc'] as String?,
 );
 
 Map<String, dynamic> _$GoodsInfoToJson(GoodsInfo instance) => <String, dynamic>{
@@ -39,4 +40,5 @@ Map<String, dynamic> _$GoodsInfoToJson(GoodsInfo instance) => <String, dynamic>{
   'description': instance.description,
   'discountDesc': instance.discountDesc,
   'mostDesc': instance.mostDesc,
+  'selectDesc': instance.selectDesc,
 };

+ 5 - 0
lib/data/consts/web_url.dart

@@ -9,9 +9,14 @@ class WebUrl {
   static const String _kidPolicy =
       "https://doc.v8dashen.com/doc/298eb75d38dc2c4a";
 
+  static const String _qiyuService ="https://qiyu-kefu.atmob.com";
+
+
   static String get privacyPolicy => _privacyPolicy;
 
   static String get kidPolicy => _kidPolicy;
 
   static String get serviceAgreement => _serviceAgreement;
+
+  static String get qiyuService => _qiyuService;
 }

+ 14 - 14
lib/dialog/member_agreement_dialog.dart

@@ -63,7 +63,7 @@ class MemberAgreementDialog {
                               ),
                               ClickTextSpan(
                                 fontSize: 14.sp,
-                                text: StringName.memberAgreementDialogAgreement,
+                                text: StringName.textSpanPrivacyPolicy,
                                 url: WebUrl.privacyPolicy,
                               ),
 
@@ -79,10 +79,20 @@ class MemberAgreementDialog {
                               ClickTextSpan(
                                 fontSize: 14.sp,
                                 text:
-                                    StringName.memberAgreementDialogAutoRenewal,
+                                    StringName.textSpanServiceTerms,
                                 url: WebUrl.serviceAgreement,
                               ),
+                              TextSpan(
+                                text: "。",
+                                style: TextStyle(
+                                  color: Colors.black.withAlpha(153),
+                                  fontSize: 14.sp,
+                                  fontWeight: FontWeight.w400,
+                                ),
+                              ),
+
                             ],
+
                           ),
                         ),
                         SizedBox(height: 20.h),
@@ -123,18 +133,8 @@ class MemberAgreementDialog {
                                 height: 40.h,
                                 width: 128.r,
                                 alignment: Alignment.center,
-                                decoration: ShapeDecoration(
-                                  shape: RoundedRectangleBorder(
-                                    borderRadius: BorderRadius.circular(50.r),
-                                  ),
-                                  gradient: LinearGradient(
-                                    begin: Alignment.topCenter,
-                                    end: Alignment.centerRight,
-                                    colors: [
-                                      const Color(0xFF7D46FC),
-                                      const Color(0xFFBC87FF),
-                                    ],
-                                  ),
+                                decoration: Styles.getActivateButtonDecoration(
+                                  22.r,
                                 ),
                                 child: Text(
                                   StringName.memberAgreementDialogConfirm,

+ 145 - 0
lib/dialog/payment_fail_dialog.dart

@@ -0,0 +1,145 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_screenutil/flutter_screenutil.dart';
+import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
+import 'package:keyboard/resource/string.gen.dart';
+
+import '../data/consts/web_url.dart';
+import '../module/browser/browser_page.dart';
+import '../resource/assets.gen.dart';
+import '../resource/colors.gen.dart';
+import '../utils/styles.dart';
+import '../widget/click_text_span.dart';
+
+// 支付失败
+class PaymentFailDialog {
+  static const String tag = 'PaymentFailDialog';
+
+  static void show({Function? btnCancel, Function? btnConfirm}) {
+    SmartDialog.show(
+      tag: tag,
+      backType: SmartBackType.block,
+      clickMaskDismiss: true,
+      maskColor: ColorName.black70,
+      builder: (_) {
+        return Column(
+          crossAxisAlignment: CrossAxisAlignment.center,
+          mainAxisAlignment: MainAxisAlignment.center,
+          children: [
+            Container(
+              margin: EdgeInsets.symmetric(horizontal: 31.w),
+              decoration: ShapeDecoration(
+                color: Colors.white,
+                shape: RoundedRectangleBorder(
+                  borderRadius: BorderRadius.circular(20.r),
+                ),
+              ),
+              child: Stack(
+                children: [
+                  Container(
+                    width: double.infinity,
+                    padding: EdgeInsets.symmetric(
+                      horizontal: 16.w,
+                      vertical: 16.h,
+                    ),
+                    child: Column(
+                      mainAxisSize: MainAxisSize.min,
+                      crossAxisAlignment: CrossAxisAlignment.center,
+                      mainAxisAlignment: MainAxisAlignment.center,
+                      children: [
+                        Assets.images.iconDialogPayFail.image(
+                          width: 88.w,
+                          height: 88.h,
+                        ),
+                        SizedBox(height: 8.h),
+                        Text(
+                          StringName.payFailDialogTitle,
+                          style: Styles.getTextStyleBlack204W500(16.sp),
+                        ),
+                        Text(
+                          StringName.payFailDialogDesc,
+                          style: Styles.getTextStyleBlack153W400(14.sp),
+                        ),
+                        SizedBox(height: 24.h),
+                        Row(
+                          children: [
+                            Expanded(
+                              child: GestureDetector(
+                                onTap: () {
+                                  SmartDialog.dismiss();
+                                  BrowserPage.start(WebUrl.qiyuService);
+                                },
+                                child: Container(
+                                  height: 40.h,
+
+                                  decoration: ShapeDecoration(
+                                    color: const Color(0xFFF5F4F9),
+                                    shape: RoundedRectangleBorder(
+                                      borderRadius: BorderRadius.circular(50.r),
+                                    ),
+                                  ),
+                                  child: Row(
+                                    mainAxisAlignment: MainAxisAlignment.center,
+                                    children: [
+                                      Assets.images.iconDialogPayFailService
+                                          .image(width: 22.w, height: 22.w),
+                                      Text(
+                                        StringName.payFailDialogCancel,
+                                        style: Styles.getTextStyleBlack102W500(
+                                          16.sp,
+                                        ),
+                                      ),
+                                    ],
+                                  ),
+                                ),
+                              ),
+                            ),
+                            SizedBox(width: 8.w),
+                            Expanded(
+                              child: GestureDetector(
+                                onTap: () {
+                                  SmartDialog.dismiss();
+                                  btnConfirm?.call();
+                                },
+                                child: Container(
+                                  height: 40.h,
+                                  decoration: Styles.getActivateButtonDecoration(
+                                    22.r,
+                                  ),
+                                  child: Center(
+                                    child: Text(
+                                      StringName.payFailDialogContinue,
+                                      style: Styles.getTextStyleWhiteW500(
+                                        16.sp,
+                                      ),
+                                    ),
+                                  ),
+                                ),
+                              ),
+                            ),
+                          ],
+                        ),
+                      ],
+                    ),
+                  ),
+                  Positioned(
+                    right: 14.w,
+                    top: 14.h,
+                    child: GestureDetector(
+                      onTap: () {
+                        SmartDialog.dismiss();
+                      },
+                      child: Assets.images.iconCustomDialogClose.image(
+                        width: 24.w,
+                        height: 24.h,
+                      ),
+                    ),
+                  ),
+                ],
+              ),
+            ),
+          ],
+        );
+      },
+    );
+  }
+}

+ 50 - 101
lib/dialog/payment_success_dialog.dart

@@ -3,17 +3,15 @@ import 'package:flutter_screenutil/flutter_screenutil.dart';
 import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
 import 'package:keyboard/resource/string.gen.dart';
 
-import '../data/consts/web_url.dart';
 import '../resource/assets.gen.dart';
 import '../resource/colors.gen.dart';
 import '../utils/styles.dart';
-import '../widget/click_text_span.dart';
 
-// 支付成功弹窗
+// 支付成功
 class PaymentSuccessDialog {
   static const String tag = 'PaymentSuccessDialog';
 
-  static void show({Function? btnCancel, Function? btnConfirm}) {
+  static void show({required String infoText, required Function? btnConfirm}) {
     SmartDialog.show(
       tag: tag,
       backType: SmartBackType.block,
@@ -36,124 +34,75 @@ class PaymentSuccessDialog {
               child: Stack(
                 children: [
                   Container(
+                    width: double.infinity,
                     padding: EdgeInsets.symmetric(
                       horizontal: 16.w,
-                      vertical: 24.h,
+                      vertical: 16.h,
                     ),
                     child: Column(
                       mainAxisSize: MainAxisSize.min,
                       crossAxisAlignment: CrossAxisAlignment.center,
                       mainAxisAlignment: MainAxisAlignment.center,
                       children: [
-                        Text(
-                          StringName.memberAgreementDialogTitle,
-                          style: Styles.getTextStyleBlack204W500(16.sp),
-                        ),
-                        SizedBox(height: 16.h),
-                        Text.rich(
-                          TextSpan(
-                            children: [
-                              TextSpan(
-                                text: StringName.memberAgreementDialogDesc,
-                                style: TextStyle(
-                                  color: Colors.black.withAlpha(153),
-                                  fontSize: 14.sp,
-                                  fontWeight: FontWeight.w400,
-                                ),
-                              ),
-                              ClickTextSpan(
-                                fontSize: 14.sp,
-                                text: StringName.memberAgreementDialogAgreement,
-                                url: WebUrl.privacyPolicy,
-                              ),
-
-                              TextSpan(
-                                text: StringName.textSpanAnd,
-                                style: TextStyle(
-                                  color: Colors.black.withAlpha(153),
-                                  fontSize: 14.sp,
-                                  fontWeight: FontWeight.w400,
-                                ),
-                              ),
-
-                              ClickTextSpan(
-                                fontSize: 14.sp,
-                                text:
-                                StringName.memberAgreementDialogAutoRenewal,
-                                url: WebUrl.serviceAgreement,
-                              ),
-                            ],
-                          ),
-                        ),
-                        SizedBox(height: 20.h),
-                        Row(
-                          mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                          children: [
-                            GestureDetector(
-                              onTap: () {
-                                if (btnCancel != null) {
-                                  btnCancel();
-                                }
-                                SmartDialog.dismiss();
-                              },
-                              child: Container(
-                                height: 48.h,
-                                alignment: Alignment.center,
-                                decoration: ShapeDecoration(
-                                  color: const Color(0xFFF5F4F9),
-                                  shape: RoundedRectangleBorder(
-                                    borderRadius: BorderRadius.circular(31.r),
-                                  ),
-                                ),
-                                child: Text(
-                                  StringName.memberAgreementDialogCancel,
-                                  style: Styles.getTextStyleBlack204W500(16.sp),
-                                ),
-                              ),
-                            ),
-
-                            SizedBox(width: 16.w),
-                            GestureDetector(
-                              onTap: () {
-                                if (btnConfirm != null) {
-                                  btnConfirm();
-                                }
-                                SmartDialog.dismiss(tag: tag);
-                              },
-                              child: Container(
-                                height: 48.h,
-                                alignment: Alignment.center,
-                                decoration: Styles.getActivateButtonDecoration(
-                                  20.r,
-                                ),
-                                child: Text(
-                                  StringName.memberAgreementDialogConfirm,
-                                  style: Styles.getTextStyleWhiteW500(16.sp),
-                                ),
-                              ),
-                            ),
-                          ],
-                        ),
-                      ],
+                    Assets.images.iconDialogPaySuccess.image(
+                    width: 88.w,
+                      height: 88.h,
+                    ),
+                    SizedBox(height: 8.h),
+                    Text(
+                      StringName.paySuccessDialogTitle,
+                      style: Styles.getTextStyleBlack204W500(16.sp),
                     ),
+                    Text(
+                        infoText,
+                        style: Styles.getTextStyleBlack153W400(14.sp),
                   ),
-                  Positioned(
-                    right: 14.w,
-                    top: 14.h,
+                  SizedBox(height: 24.h),
+
+                  SizedBox(
+                    width: double.infinity,
                     child: GestureDetector(
                       onTap: () {
                         SmartDialog.dismiss();
+                        btnConfirm?.call();
                       },
-                      child: Assets.images.iconCustomDialogClose.image(
-                        width: 24.w,
-                        height: 24.h,
+                      child: Container(
+                        height: 40.h,
+                        decoration: Styles.getActivateButtonDecoration(
+                          22.r,
+                        ),
+                        child: Center(
+                          child: Text(
+                            StringName.paySuccessDialogConfirm,
+                            style: Styles.getTextStyleWhiteW500(16.sp),
+                          ),
+                        ),
                       ),
                     ),
+
                   ),
                 ],
               ),
             ),
+            Positioned(
+              right: 14.w,
+              top: 14.h,
+              child: GestureDetector(
+                onTap: () {
+                  SmartDialog.dismiss();
+                  btnConfirm?.call();
+                },
+                child: Assets.images.iconCustomDialogClose.image(
+                  width: 24.w,
+                  height: 24.h,
+                ),
+              ),
+            ),
           ],
+        ),)
+        ,
+        ]
+        ,
         );
       },
     );

+ 1 - 1
lib/dialog/tips_dialog.dart

@@ -107,7 +107,7 @@ class TipsDialog {
                                     alignment: Alignment.center,
                                     decoration:
                                         Styles.getActivateButtonDecoration(
-                                          20.r,
+                                          31.r,
                                         ),
                                     child: Text(
                                       btnConfirmText ?? "",

+ 25 - 2
lib/module/store/store_controller.dart

@@ -9,6 +9,8 @@ import 'package:keyboard/data/bean/pay_way_info.dart';
 import 'package:keyboard/data/bean/goods_info.dart';
 import 'package:keyboard/data/repository/account_repository.dart';
 import 'package:keyboard/data/repository/store_repository.dart';
+import 'package:keyboard/dialog/payment_fail_dialog.dart';
+import 'package:keyboard/dialog/payment_success_dialog.dart';
 import 'package:keyboard/module/store/store_banner_bean.dart';
 import 'package:keyboard/module/store/store_user_reviews_bean.dart';
 import 'package:keyboard/utils/async_util.dart';
@@ -25,6 +27,7 @@ import '../../dialog/member_agreement_dialog.dart';
 import '../../dialog/wechat_qr_code_dialog.dart';
 import '../../resource/assets.gen.dart';
 import '../../resource/string.gen.dart';
+import '../../utils/date_util.dart';
 import '../../utils/error_handler.dart';
 import '../../utils/http_handler.dart';
 import '../../utils/payment_status_manager.dart';
@@ -155,7 +158,7 @@ class StoreController extends BaseController implements PaymentStatusCallback {
 
   void onGoodsItemClick(GoodsInfo goodsInfo) {
     _selectedGoodsInfoItem.value = goodsInfo;
-    print('item: ${goodsInfo.toJson()}');
+    debugPrint("'item: ${goodsInfo.toJson()}");
   }
 
   void clickPayWaySwitch() {
@@ -254,9 +257,11 @@ class StoreController extends BaseController implements PaymentStatusCallback {
               LoginPage.start();
             } else {
               ToastUtil.show(error.message);
+              paymentFail();
             }
           } else {
             ToastUtil.show(StringName.memberPaymentFailed);
+            paymentFail();
           }
         })
         .whenComplete(() {
@@ -264,6 +269,14 @@ class StoreController extends BaseController implements PaymentStatusCallback {
         });
   }
 
+  void paymentFail() {
+    PaymentFailDialog.show(
+      btnConfirm: () {
+        clickPayNow();
+      },
+    );
+  }
+
   void _onAliScanPay(
     String outTradeNo,
     String qrHtml,
@@ -372,7 +385,9 @@ class StoreController extends BaseController implements PaymentStatusCallback {
       },
       payError: (int error, String? errorMessage) {
         debugPrint('zk---payError: $error, $errorMessage');
+        paymentFail();
         errorPayToast(error);
+
         errorEventReport(payMethod);
       },
       error: (int errno, String? error) {
@@ -426,6 +441,14 @@ class StoreController extends BaseController implements PaymentStatusCallback {
     PayWayInfo payWayInfo,
     GoodsInfo goodsInfo,
   ) {
-    // showPaymentSuccessDialog(onConfirm: back, onCancel: back);
+    PaymentSuccessDialog.show(
+      infoText:
+          memberStatusInfo?.permanent == true
+              ? StringName.paySuccessDialogPermanent
+              : "${goodsInfo.name}${DateUtil.fromMillisecondsSinceEpoch('yyyy年MM月dd日', memberStatusInfo?.endTimestamp ?? 0)}${StringName.paySuccessDialogDesc}",
+      btnConfirm: () {
+        AtmobLog.d(tag, 'onGoodsItemClick: ${goodsInfo.toJson()}');
+      },
+    );
   }
 }

+ 166 - 157
lib/module/store/store_page.dart

@@ -83,13 +83,13 @@ class StorePage extends BasePage<StoreController> {
                     SizedBox(width: 8.w),
                     controller.isLogin
                         ? Assets.images.iconMineUserLogged.image(
-                          width: 28.w,
-                          height: 28.w,
-                        )
+                      width: 28.w,
+                      height: 28.w,
+                    )
                         : Assets.images.iconMineUserNoLogin.image(
-                          width: 28.w,
-                          height: 28.w,
-                        ),
+                      width: 28.w,
+                      height: 28.w,
+                    ),
                   ],
                 ),
               );
@@ -176,7 +176,6 @@ class StorePage extends BasePage<StoreController> {
   }
 
   Widget _buildGoodsCard() {
-
     return Container(
       margin: EdgeInsets.symmetric(horizontal: 16.w),
       padding: EdgeInsets.only(
@@ -204,17 +203,17 @@ class StorePage extends BasePage<StoreController> {
           Obx(() {
             return Column(
               children:
-                  controller.goodsInfoList.map((item) {
-                    return Obx(() {
-                      return GestureDetector(
-                        onTap: () => controller.onGoodsItemClick(item),
-                        child: _buildGoodsItem(
-                          item,
-                          controller.selectedGoodsInfoItem?.id == item.id,
-                        ),
-                      );
-                    });
-                  }).toList(),
+              controller.goodsInfoList.map((item) {
+                return Obx(() {
+                  return GestureDetector(
+                    onTap: () => controller.onGoodsItemClick(item),
+                    child: _buildGoodsItem(
+                      item,
+                      controller.selectedGoodsInfoItem?.id == item.id,
+                    ),
+                  );
+                });
+              }).toList(),
             );
           }),
           _buildPayWayCard(),
@@ -286,9 +285,9 @@ class StorePage extends BasePage<StoreController> {
           begin: Alignment(0.77, -0.00),
           end: Alignment(0.77, 1.00),
           colors:
-              isSelected
-                  ? [const Color(0xFFFF9416), const Color(0xFFFF7813)]
-                  : [const Color(0xFFFEE057), const Color(0xFFFFC400)],
+          isSelected
+              ? [const Color(0xFFFF9416), const Color(0xFFFF7813)]
+              : [const Color(0xFFFEE057), const Color(0xFFFFC400)],
         ),
         shape: RoundedRectangleBorder(
           borderRadius: BorderRadius.circular(10.r),
@@ -301,16 +300,16 @@ class StorePage extends BasePage<StoreController> {
             height: 70.h,
             decoration: ShapeDecoration(
               gradient:
-                  isSelected
-                      ? LinearGradient(
-                        begin: Alignment(-0.06, 0.50),
-                        end: Alignment(1.14, 0.50),
-                        colors: [
-                          const Color(0xFFFFF895),
-                          const Color(0xFFFFE941),
-                        ],
-                      )
-                      : null,
+              isSelected
+                  ? LinearGradient(
+                begin: Alignment(-0.06, 0.50),
+                end: Alignment(1.14, 0.50),
+                colors: [
+                  const Color(0xFFFFF895),
+                  const Color(0xFFFFE941),
+                ],
+              )
+                  : null,
               color: isSelected ? null : const Color(0xFFFFFDEE),
               shape: RoundedRectangleBorder(
                 side: BorderSide(width: 1, color: const Color(0xFFFEE86B)),
@@ -398,25 +397,25 @@ class StorePage extends BasePage<StoreController> {
                 Text(
                   item.name,
                   style:
-                      isSelected
-                          ? Styles.getTextStyleFFECBBW500(15.sp)
-                          : Styles.getTextStyleFF663300W500(15.sp),
+                  isSelected
+                      ? Styles.getTextStyleFFECBBW500(15.sp)
+                      : Styles.getTextStyleFF663300W500(15.sp),
                 ),
                 Container(
                   padding: EdgeInsets.symmetric(horizontal: 8.w),
                   decoration: ShapeDecoration(
                     color: isSelected ? const Color(0xFFFFECBB) : null,
                     gradient:
-                        isSelected
-                            ? null
-                            : LinearGradient(
-                              begin: Alignment(0.77, -0.00),
-                              end: Alignment(0.77, 1.00),
-                              colors: [
-                                const Color(0xFFFF9416),
-                                const Color(0xFFFF7813),
-                              ],
-                            ),
+                    isSelected
+                        ? null
+                        : LinearGradient(
+                      begin: Alignment(0.77, -0.00),
+                      end: Alignment(0.77, 1.00),
+                      colors: [
+                        const Color(0xFFFF9416),
+                        const Color(0xFFFF7813),
+                      ],
+                    ),
                     shape: RoundedRectangleBorder(
                       borderRadius: BorderRadius.circular(
                         isSelected ? 17.r : 10.r,
@@ -427,9 +426,9 @@ class StorePage extends BasePage<StoreController> {
                     '¥${item.amountText}',
                     textAlign: TextAlign.center,
                     style:
-                        isSelected
-                            ? Styles.getTextStyleFF7F14W500(12.sp)
-                            : Styles.getTextStyleWhiteW500(12.sp),
+                    isSelected
+                        ? Styles.getTextStyleFF7F14W500(12.sp)
+                        : Styles.getTextStyleWhiteW500(12.sp),
                   ),
                 ),
               ],
@@ -468,7 +467,12 @@ class StorePage extends BasePage<StoreController> {
           ),
         ],
       ),
-      child: Text("*选中商品时展示文案", style: Styles.getTextStyle99673300W400(12.sp)),
+      child: Obx(() {
+        return Text(
+          controller.selectedGoodsInfoItem?.selectDesc ?? "",
+          style: Styles.getTextStyle99673300W400(12.sp),
+        );
+      }),
     );
   }
 
@@ -497,12 +501,12 @@ class StorePage extends BasePage<StoreController> {
             ),
 
             items:
-                controller.bannerList.map((item) {
-                  return item.banner.image(
-                    width: double.infinity,
-                    fit: BoxFit.cover,
-                  );
-                }).toList(),
+            controller.bannerList.map((item) {
+              return item.banner.image(
+                width: double.infinity,
+                fit: BoxFit.cover,
+              );
+            }).toList(),
           ),
           Positioned(bottom: 0, left: 0, right: 0, child: _buildIndicator()),
         ],
@@ -524,57 +528,61 @@ class StorePage extends BasePage<StoreController> {
       child: Row(
         mainAxisAlignment: MainAxisAlignment.spaceAround,
         children:
-            controller.bannerList.asMap().entries.map((entry) {
-              return Obx(() {
-                final isSelectedBanner =
-                    controller.currentBannerIndex == entry.key;
-                return Row(
-                  mainAxisAlignment: MainAxisAlignment.spaceAround,
-                  children: [
-                    GestureDetector(
-                      onTap:
-                          () => controller.carouselSliderController
-                              .animateToPage(entry.key),
-                      child: SizedBox(
-                        width: 100.w,
-                        child: Stack(
-                          alignment: Alignment.center,
-                          clipBehavior: Clip.none,
-                          children: [
-                            if (isSelectedBanner)
-                              Positioned(
-                                top: -8.h,
-                                child: controller
-                                    .bannerList[entry.key]
-                                    .indicatorImg
-                                    .image(
-                                      width: 100.w,
-                                      height: 40.h,
-                                      fit: BoxFit.fill,
-                                    ),
-                              )
-                            else
-                              Text(
-                                controller.bannerList[entry.key].unSelectedDesc,
-                                style: Styles.getTextStyleWhiteW400(14.sp),
-                              ),
-                          ],
-                        ),
-                      ),
+        controller.bannerList
+            .asMap()
+            .entries
+            .map((entry) {
+          return Obx(() {
+            final isSelectedBanner =
+                controller.currentBannerIndex == entry.key;
+            return Row(
+              mainAxisAlignment: MainAxisAlignment.spaceAround,
+              children: [
+                GestureDetector(
+                  onTap:
+                      () =>
+                      controller.carouselSliderController
+                          .animateToPage(entry.key),
+                  child: SizedBox(
+                    width: 100.w,
+                    child: Stack(
+                      alignment: Alignment.center,
+                      clipBehavior: Clip.none,
+                      children: [
+                        if (isSelectedBanner)
+                          Positioned(
+                            top: -8.h,
+                            child: controller
+                                .bannerList[entry.key]
+                                .indicatorImg
+                                .image(
+                              width: 100.w,
+                              height: 40.h,
+                              fit: BoxFit.fill,
+                            ),
+                          )
+                        else
+                          Text(
+                            controller.bannerList[entry.key].unSelectedDesc,
+                            style: Styles.getTextStyleWhiteW400(14.sp),
+                          ),
+                      ],
                     ),
-                    if (entry.key != controller.bannerList.length - 1)
-                      Padding(
-                        padding: EdgeInsets.only(left: 4.w),
-                        child: Assets.images.iconStoreDivider.image(
-                          width: 2.w,
-                          height: 17.h,
-                          fit: BoxFit.fill,
-                        ),
-                      ),
-                  ],
-                );
-              });
-            }).toList(),
+                  ),
+                ),
+                if (entry.key != controller.bannerList.length - 1)
+                  Padding(
+                    padding: EdgeInsets.only(left: 4.w),
+                    child: Assets.images.iconStoreDivider.image(
+                      width: 2.w,
+                      height: 17.h,
+                      fit: BoxFit.fill,
+                    ),
+                  ),
+              ],
+            );
+          });
+        }).toList(),
       ),
     );
   }
@@ -642,9 +650,9 @@ class StorePage extends BasePage<StoreController> {
                         ),
                         child: Column(
                           children:
-                              controller.userReviewsList.map((item) {
-                                return _buildReviewsItem(item);
-                              }).toList(),
+                          controller.userReviewsList.map((item) {
+                            return _buildReviewsItem(item);
+                          }).toList(),
                         ),
                       ),
                     ],
@@ -722,11 +730,11 @@ class StorePage extends BasePage<StoreController> {
           SizedBox(height: 8.h),
           Text(
             "1. 本产品为互联网技术服务虚拟产品,会员购买成功立即生效,一经开通不支持退款。\n"
-            "2. 本产品为付费会员制产品,会员费用是指开通平台所有功能使用权限的基础费用。开通权限后,部分功能可能会免费(具体以实际展示情况为准)使用,部分功能需消耗一定的虚拟币(金币)方可使用。\n"
-            "3. 各种功能的金币消耗可参考虚拟币规则(金币中心)。\n"
-            "4. 开通会员后,若赠送虚拟币(金币)消耗完毕,可单独购买金币。\n"
-            "5. 根据业务情况,我方有权调整不同功能的虚拟币消耗价格,价格会在最新的金币中心展示。\n"
-            "6. 请在购买前仔细阅读《会员服务协议》和购买须知,确定您同意所有条款后继续操作。",
+                "2. 本产品为付费会员制产品,会员费用是指开通平台所有功能使用权限的基础费用。开通权限后,部分功能可能会免费(具体以实际展示情况为准)使用,部分功能需消耗一定的虚拟币(金币)方可使用。\n"
+                "3. 各种功能的金币消耗可参考虚拟币规则(金币中心)。\n"
+                "4. 开通会员后,若赠送虚拟币(金币)消耗完毕,可单独购买金币。\n"
+                "5. 根据业务情况,我方有权调整不同功能的虚拟币消耗价格,价格会在最新的金币中心展示。\n"
+                "6. 请在购买前仔细阅读《会员服务协议》和购买须知,确定您同意所有条款后继续操作。",
             style: Styles.getTextStyle99673300W400(10.sp),
           ),
           SizedBox(height: 120.h),
@@ -758,33 +766,34 @@ class StorePage extends BasePage<StoreController> {
       ),
       child: Column(
         children: [
-        GestureDetector(
-          onTap: controller.clickPayNow,
-          child:   Container(
-          width: 328.w,
-          height: 54.h,
-          decoration: ShapeDecoration(
-            gradient: LinearGradient(
-              begin: Alignment(0.60, -0.39),
-              end: Alignment(0.60, 0.95),
-              colors: [
-                const Color(0xFFF95FAC),
-                const Color(0xFFFD5E4D),
-                const Color(0xFFFD5E4D),
-                const Color(0xFFFB8A3C),
-              ],
-            ),
-            shape: RoundedRectangleBorder(
-              borderRadius: BorderRadius.circular(30.55.r),
-            ),
-          ),
-          child: Center(
-            child: Text(
-              StringName.storePayNow,
-              style: Styles.getTextStyleWhiteW500(17.sp),
+          GestureDetector(
+            onTap: controller.clickPayNow,
+            child: Container(
+              width: 328.w,
+              height: 54.h,
+              decoration: ShapeDecoration(
+                gradient: LinearGradient(
+                  begin: Alignment(0.60, -0.39),
+                  end: Alignment(0.60, 0.95),
+                  colors: [
+                    const Color(0xFFF95FAC),
+                    const Color(0xFFFD5E4D),
+                    const Color(0xFFFD5E4D),
+                    const Color(0xFFFB8A3C),
+                  ],
+                ),
+                shape: RoundedRectangleBorder(
+                  borderRadius: BorderRadius.circular(30.55.r),
+                ),
+              ),
+              child: Center(
+                child: Text(
+                  StringName.storePayNow,
+                  style: Styles.getTextStyleWhiteW500(17.sp),
+                ),
+              ),
             ),
           ),
-        ),),
           SizedBox(height: 11.h),
           Row(
             mainAxisAlignment: MainAxisAlignment.center,
@@ -796,27 +805,27 @@ class StorePage extends BasePage<StoreController> {
                     controller.isAgree.value = !controller.isAgree.value;
                   },
                   child:
-                      controller.isAgree.value
-                          ? Assets.images.iconStoreAgreePrivacy.image(
-                            width: 16.w,
-                            height: 16.w,
-                          )
-                          : SizedBox(
-                            child: Container(
-                              padding: EdgeInsets.all(1.w),
-                              width: 16.w,
-                              height: 16.w,
-                              child: Container(
-                                decoration: BoxDecoration(
-                                  shape: BoxShape.circle,
-                                  border: Border.all(
-                                    color: Colors.black.withAlpha(153),
-                                    width: 1.w,
-                                  ),
-                                ),
-                              ),
-                            ),
+                  controller.isAgree.value
+                      ? Assets.images.iconStoreAgreePrivacy.image(
+                    width: 16.w,
+                    height: 16.w,
+                  )
+                      : SizedBox(
+                    child: Container(
+                      padding: EdgeInsets.all(1.w),
+                      width: 16.w,
+                      height: 16.w,
+                      child: Container(
+                        decoration: BoxDecoration(
+                          shape: BoxShape.circle,
+                          border: Border.all(
+                            color: Colors.black.withAlpha(153),
+                            width: 1.w,
                           ),
+                        ),
+                      ),
+                    ),
+                  ),
                 );
               }),
               Text.rich(

+ 15 - 0
lib/resource/assets.gen.dart

@@ -190,6 +190,18 @@ class $AssetsImagesGen {
   AssetGenImage get iconDialogCloseBlack =>
       const AssetGenImage('assets/images/icon_dialog_close_black.webp');
 
+  /// File path: assets/images/icon_dialog_pay_fail.webp
+  AssetGenImage get iconDialogPayFail =>
+      const AssetGenImage('assets/images/icon_dialog_pay_fail.webp');
+
+  /// File path: assets/images/icon_dialog_pay_fail_service.webp
+  AssetGenImage get iconDialogPayFailService =>
+      const AssetGenImage('assets/images/icon_dialog_pay_fail_service.webp');
+
+  /// File path: assets/images/icon_dialog_pay_success.webp
+  AssetGenImage get iconDialogPaySuccess =>
+      const AssetGenImage('assets/images/icon_dialog_pay_success.webp');
+
   /// File path: assets/images/icon_goods_info_title.webp
   AssetGenImage get iconGoodsInfoTitle =>
       const AssetGenImage('assets/images/icon_goods_info_title.webp');
@@ -425,6 +437,9 @@ class $AssetsImagesGen {
     iconCharacterVip,
     iconCustomDialogClose,
     iconDialogCloseBlack,
+    iconDialogPayFail,
+    iconDialogPayFailService,
+    iconDialogPaySuccess,
     iconGoodsInfoTitle,
     iconKeyboardManageCustom,
     iconKeyboardManageFavorite,

+ 16 - 4
lib/resource/string.gen.dart

@@ -122,11 +122,17 @@ class StringName {
   static final String wechatPayQrCodeTips = 'wechat_pay_qr_code_tips'.tr; // 请使用微信扫码支付
   static final String memberPaymentFailed = 'member_payment_failed'.tr; // 开通失败,请稍后重试
   static final String memberAgreementDialogTitle = 'member_agreement_dialog_title'.tr; // 请阅读并同意以下协议
-  static final String memberAgreementDialogAgreement = 'member_agreement_dialog_agreement'.tr; // 《会员协议》
-  static final String memberAgreementDialogAutoRenewal = 'member_agreement_dialog_auto_renewal'.tr; // 《自动续费协议》。
   static final String memberAgreementDialogDesc = 'member_agreement_dialog_desc'.tr; // 进入下一步前,请先阅读并同意
   static final String memberAgreementDialogConfirm = 'member_agreement_dialog_confirm'.tr; // 确定
   static final String memberAgreementDialogCancel = 'member_agreement_dialog_cancel'.tr; // 取消
+  static final String payFailDialogTitle = 'pay_fail_dialog_title'.tr; // 支付遇到问题
+  static final String payFailDialogDesc = 'pay_fail_dialog_desc'.tr; // 您可以联系在线客服帮您解决
+  static final String payFailDialogContinue = 'pay_fail_dialog_continue'.tr; // 继续支付
+  static final String payFailDialogCancel = 'pay_fail_dialog_cancel'.tr; // 联系客服
+  static final String paySuccessDialogTitle = 'pay_success_dialog_title'.tr; // 支付成功
+  static final String paySuccessDialogDesc = 'pay_success_dialog_desc'.tr; // 到期。
+  static final String paySuccessDialogConfirm = 'pay_success_dialog_confirm'.tr; // 知道了
+  static final String paySuccessDialogPermanent = 'pay_success_dialog_permanent'.tr; // 恭喜您成为终身会员,感谢您的支持
 }
 class StringMultiSource {
   StringMultiSource._();
@@ -252,11 +258,17 @@ class StringMultiSource {
       'wechat_pay_qr_code_tips': '请使用微信扫码支付',
       'member_payment_failed': '开通失败,请稍后重试',
       'member_agreement_dialog_title': '请阅读并同意以下协议',
-      'member_agreement_dialog_agreement': '《会员协议》',
-      'member_agreement_dialog_auto_renewal': '《自动续费协议》。',
       'member_agreement_dialog_desc': '进入下一步前,请先阅读并同意',
       'member_agreement_dialog_confirm': '确定',
       'member_agreement_dialog_cancel': '取消',
+      'pay_fail_dialog_title': '支付遇到问题',
+      'pay_fail_dialog_desc': '您可以联系在线客服帮您解决',
+      'pay_fail_dialog_continue': '继续支付',
+      'pay_fail_dialog_cancel': '联系客服',
+      'pay_success_dialog_title': '支付成功',
+      'pay_success_dialog_desc': '到期。',
+      'pay_success_dialog_confirm': '知道了',
+      'pay_success_dialog_permanent': '恭喜您成为终身会员,感谢您的支持',
     },
   };
 }

+ 19 - 8
lib/utils/styles.dart

@@ -1,10 +1,4 @@
-import 'package:flutter/cupertino.dart';
-import 'package:flutter/gestures.dart';
 import 'package:flutter/material.dart';
-import 'package:flutter_screenutil/flutter_screenutil.dart';
-
-import '../module/browser/browser_page.dart';
-import '../resource/colors.gen.dart';
 
 class Styles {
   Styles._();
@@ -12,8 +6,11 @@ class Styles {
   static Decoration getActivateButtonDecoration(double radius) {
     return ShapeDecoration(
       gradient: LinearGradient(
+        begin: Alignment.topCenter,
+        end: Alignment.centerRight,
         colors: [const Color(0xFF7D46FC), const Color(0xFFBC87FF)],
       ),
+
       shape: RoundedRectangleBorder(
         borderRadius: BorderRadius.circular(radius),
       ),
@@ -45,6 +42,22 @@ class Styles {
     );
   }
 
+  static TextStyle getTextStyleBlack153W400(double? sp) {
+    return TextStyle(
+      color: Colors.black.withAlpha(153),
+      fontSize: sp,
+      fontWeight: FontWeight.w400,
+    );
+  }
+
+  static TextStyle getTextStyleBlack102W500(double? sp) {
+    return TextStyle(
+      color: Colors.black.withAlpha(102),
+      fontSize: sp,
+      fontWeight: FontWeight.w500,
+    );
+  }
+
   static TextStyle getTextStyleWhiteW500(double? sp) {
     return TextStyle(
       color: Colors.white,
@@ -109,6 +122,4 @@ class Styles {
       fontWeight: FontWeight.w500,
     );
   }
-
-
 }

+ 3 - 0
pubspec.yaml

@@ -96,6 +96,9 @@ dependencies:
   keyboard_android:
     path: plugins/keyboard_android
 
+  #并发
+  synchronized: ^3.3.1
+
   #支付
   agile_pay:
     path: plugins/agile_pay