18.1 下单界面编写

18.1 下单界面编写

image-20220804122106978

实现步骤:


第 1 步:i18n

lib/common/i18n/locale_keys.dart

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 下单 checkout
static const placeOrderTitle = "place_order_title";
static const placeOrderPayment = "place_order_payment";
static const placeOrderShippingAddress = "place_order_shipping_address";
static const placeOrderQuantity = "place_order_quantity";
static const placeOrderPrice = "place_order_price";
static const placeOrderPriceShipping = "place_order_price_shipping";
static const placeOrderPriceDiscount = "place_order_price_discount";
static const placeOrderPriceVoucherCode = "place_order_price_voucher_code";
static const placeOrderPriceVoucherCodeEnter =
"place_order_price_voucher_code_enter";
static const placeOrderTotal = "place_order_total";
static const placeOrderBtnPlaceOrder = "place_order_btn_place_order";

// 下单确认
static const orderConfirmationTitle = "order_confirmation_title";
static const orderConfirmationDesc = "order_confirmation_desc";
static const orderConfirmationBtnHome = "order_confirmation_btn_home";

lib/common/i18n/locales/locale_en.dart

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 下单 checkout
LocaleKeys.placeOrderTitle: 'Checkout',
LocaleKeys.placeOrderPayment: 'Payment Method',
LocaleKeys.placeOrderShippingAddress: 'Shipping Address',
LocaleKeys.placeOrderQuantity: 'Quantity',
LocaleKeys.placeOrderPrice: 'Price',
LocaleKeys.placeOrderPriceShipping: 'Shipping',
LocaleKeys.placeOrderPriceDiscount: 'Discount',
LocaleKeys.placeOrderPriceVoucherCode: 'Voucher Code',
LocaleKeys.placeOrderPriceVoucherCodeEnter: 'Voucher Code Enter',
LocaleKeys.placeOrderTotal: 'Total',
LocaleKeys.placeOrderBtnPlaceOrder: 'Place Order',

// 下单确认
LocaleKeys.orderConfirmationTitle: 'Order Placed',
LocaleKeys.orderConfirmationDesc: 'Your order was placed Successfully',
LocaleKeys.orderConfirmationBtnHome: 'Go Home',

lib/common/i18n/locales/locale_zh.dart

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 下单 Checkout
LocaleKeys.placeOrderTitle: '确认订单',
LocaleKeys.placeOrderPayment: '支付方式',
LocaleKeys.placeOrderShippingAddress: '送货地址',
LocaleKeys.placeOrderQuantity: '数量',
LocaleKeys.placeOrderPrice: '价格',
LocaleKeys.placeOrderPriceShipping: '运费',
LocaleKeys.placeOrderPriceDiscount: '折扣',
LocaleKeys.placeOrderPriceVoucherCode: '代金券',
LocaleKeys.placeOrderPriceVoucherCodeEnter: '输入代金券',
LocaleKeys.placeOrderTotal: '小计',
LocaleKeys.placeOrderBtnPlaceOrder: '下单确认',

// 下单确认
LocaleKeys.orderConfirmationTitle: '已下订单',
LocaleKeys.orderConfirmationDesc: '您的订单已成功下达',
LocaleKeys.orderConfirmationBtnHome: '返回首页',

第 2 步:控制器

lib/pages/cart/buy_now/controller.dart

1
2
// 商品详情
final ProductModel product;
1
2
3
4
5
6
7
// 支付方式图标
List<String> paymentList = [
AssetsImages.pVisaPng,
AssetsImages.pCashPng,
AssetsImages.pMastercardPng,
AssetsImages.pPaypalPng,
];
1
2
// 下单 checkout
void onCheckout() async {}

第 3 步:视图

lib/pages/cart/buy_now/view.dart

1
2
// 商品数据
final ProductModel product;
1
2
3
4
const BuyNowPage({
Key? key,
required this.product,
}) : super(key: key);
1
2
3
4
// 标题
Widget _buildTitle(String text) {
return TextWidget.title2(text).paddingBottom(AppSpace.listRow);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// 支付方式
Widget _buildPayment() {
return List<Widget>.generate(
controller.paymentList.length,
(index) => ImageWidget.asset(
controller.paymentList[index],
width: 106.w,
height: 50.w,
backgroundColor: AppColors.surface,
)
.decorated(
border: Border.all(
color: AppColors.surfaceVariant,
width: 0.5,
),
borderRadius: BorderRadius.all(Radius.circular(AppRadius.button)),
)
.paddingRight(AppSpace.iconTextSmail),
)
.toList()
.toListView(
scrollDirection: Axis.horizontal,
)
.height(50.w)
.paddingBottom(AppSpace.listRow);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 底部按钮
Widget _buildButtons() {
return <Widget>[
// 取消
ButtonWidget.secondary(
LocaleKeys.commonBottomCancel.tr,
onTap: () => Get.back(),
).expanded(),

// 间距
SizedBox(width: AppSpace.iconTextLarge),

// 立刻购买 Place Order
ButtonWidget.primary(
LocaleKeys.placeOrderBtnPlaceOrder.tr,
onTap: controller.onCheckout,
).expanded(),
].toRow(
mainAxisAlignment: MainAxisAlignment.spaceAround,
);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// 主视图
Widget _buildView() {
return <Widget>[
// 支付方式
_buildTitle(LocaleKeys.placeOrderPayment.tr),
_buildPayment(),

// 送货地址
_buildTitle(LocaleKeys.placeOrderShippingAddress.tr),

// 数量
_buildTitle(LocaleKeys.placeOrderQuantity.tr),

// 小计
_buildTitle(LocaleKeys.placeOrderPrice.tr),

// 按钮
_buildButtons(),

// end
]
.toColumn(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
)
.paddingAll(AppSpace.page);
}
1
2
3
4
5
6
7
8
9
10
@override
Widget build(BuildContext context) {
return GetBuilder<BuyNowController>(
init: BuyNowController(product),
id: "buy_now",
builder: (_) {
return _buildView();
},
);
}

第 4 步:商品详情 “立刻下单”

控制器

lib/pages/goods/product_details/controller.dart

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 立刻购买 checkout
void onCheckoutTap() async {
// 检查是否登录
if (!await UserService.to.checkIsLogin()) {
return;
}

// 检查空
if (product == null || product?.id == null) {
Loading.error("product is empty");
return;
}

// 立刻购买 checkout
ActionBottomSheet.barModel(
BuyNowPage(product: product!),
);
}

ActionBottomSheet.barModel 采用底部弹出视图的方式展示

视图

lib/pages/goods/product_details/view.dart

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 底部按钮
Widget _buildButtons() {
return controller.product == null
? const SizedBox.shrink()
: <Widget>[
...

// 立刻购买
ButtonWidget.primary(
LocaleKeys.gDetailBtnBuy.tr,
// 点击弹出购买窗口
onTap: controller.onCheckoutTap,
).expanded(),
]
.toRow(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceAround,
)
.paddingHorizontal(AppSpace.page);
}
image-20220729094212099

提交代码到 git