购物车页面代码如下,包含了ui设计和对应的api_service代码:

import 'package:flutter/material.dart'; import 'package:fluttertoast/fluttertoast.dart'; import 'package:shopping_app/api/api_service.dart'; import 'package:shopping_app/models/cart_item.dart'; import 'package:shopping_app/models/product.dart';

class ShoppingCartPage extends StatefulWidget { const ShoppingCartPage({Key? key}) : super(key: key);

@override _ShoppingCartPageState createState() => _ShoppingCartPageState(); }

class _ShoppingCartPageState extends State { late List<List> cartList; late double totalPrice;

@override void initState() { super.initState(); _getShoppingCart(); }

Future _getShoppingCart() async { try { List jsonData = await ApiService.getShoppingCart(); setState(() { cartList = jsonData[0] .map((cartJson) => CartItem.fromJson(cartJson, Product.fromJson(cartJson[1]))) .toList() .fold<List<List>>([], (prev, cur) { if (prev.isNotEmpty && prev.last.first.cartId == cur.cartId) { prev.last.add(cur); } else { prev.add([cur]); } return prev; }); totalPrice = jsonData[1]; }); } catch (e) { Fluttertoast.showToast(msg: "获取购物车失败,请检查网络连接"); } }

Future _updateCartItem(CartItem item, int quantity) async { try { dynamic jsonData = await ApiService.updateCart(item.product.productId, quantity); setState(() { totalPrice = jsonData[0]; item.quantity = jsonData[1]['quantity']; item.price = jsonData[1]['price']; }); } catch (e) { Fluttertoast.showToast(msg: "更新购物车失败,请检查网络连接"); } }

Future _deleteCartItem(CartItem item) async { try { dynamic jsonData = await ApiService.deleteCart(item.product.productId); setState(() { totalPrice = jsonData; cartList.forEach((group) => group.remove(item)); cartList.removeWhere((group) => group.isEmpty); }); } catch (e) { Fluttertoast.showToast(msg: "删除购物车商品失败,请检查网络连接"); } }

Widget _buildCartItem(CartItem item) { return GestureDetector( onTap: () async { int? result = await showDialog( context: context, builder: (context) => _buildQuantityDialog(item), ); if (result != null) { await _updateCartItem(item, result); } }, child: Container( padding: EdgeInsets.symmetric(vertical: 10, horizontal: 15), decoration: BoxDecoration( border: Border(bottom: BorderSide(color: Colors.grey.shade300)), ), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( width: 80, height: 100, margin: EdgeInsets.only(right: 10), decoration: BoxDecoration( image: DecorationImage( image: NetworkImage(item.product.imageUrl), fit: BoxFit.cover, ), ), ), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(item.product.name, style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold), overflow: TextOverflow.ellipsis), SizedBox(height: 5), Row( children: [ Text("单价:"), Text( "¥${item.product.price}", style: TextStyle( color: Colors.red, fontWeight: FontWeight.bold), ), ], ), SizedBox(height: 5), Row( children: [ Text("数量:"), Text(item.quantity.toString(), style: TextStyle(fontWeight: FontWeight.bold)), ], ), ], ), ), GestureDetector( onTap: () async { bool? confirm = await showDialog(context: context, builder: (context) { return AlertDialog( title: Text("确认删除?"), content: Text("您确定要从购物车中删除此商品吗?"), actions: [ TextButton( onPressed: () => Navigator.of(context).pop(false), child: Text("取消"), ), TextButton( onPressed: () => Navigator.of(context).pop(true), child: Text("删除"), ), ], ); }); if (confirm == true) { await _deleteCartItem(item); } }, child: Icon( Icons.delete_outline, size: 20, color: Colors.grey.shade500, ), ), ], ), ), ); }

Widget _buildQuantityDialog(CartItem item) { return AlertDialog( title: Text("修改数量"), content: Column( mainAxisSize: MainAxisSize.min, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text("当前数量:${item.quantity}"), Text("单价:${item.product.price}元"), ], ), SizedBox(height: 20), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text("数量:"), SizedBox( width: 120, child: TextField( keyboardType: TextInputType.number, controller: TextEditingController( text: item.quantity.toString()), decoration: InputDecoration( border: OutlineInputBorder(), contentPadding: EdgeInsets.symmetric(horizontal: 10), ), ), ), ], ), ], ), actions: [ TextButton( onPressed: () => Navigator.of(context).pop(null), child: Text("取消"), ), TextButton( onPressed: () { String text = (context.findWidgetThatIsScrollable()!.controller as TextEditingController) .text; int quantity = int.tryParse(text) ?? 0; if (quantity <= 0) { Fluttertoast.showToast(msg: "数量必须为正整数"); } else { Navigator.of(context).pop(quantity); } }, child: Text("确定"), ), ], ); }

Widget _buildCheckoutButton() { return ElevatedButton( onPressed: () async { List addressList = await ApiService.getAddresses(); bool? result = await showDialog( context: context, builder: (context) => _buildPaymentDialog(addressList), ); if (result == true) { // 结算 try { await ApiService.submitOrder(1013, "支付宝"); Fluttertoast.showToast(msg: "结算成功!"); _getShoppingCart(); } catch (e) { Fluttertoast.showToast(msg: "结算失败,请检查网络连接"); } } }, child: Text("结算"), ); }

Widget _buildPaymentDialog(List addressList) { return AlertDialog( title: Text("结算"), content: Column( mainAxisSize: MainAxisSize.min, children: [ Text("选择收货地址:"), SizedBox(height: 10), ...addressList.map((address) { return RadioListTile( title: Text("${address['name']} ${address['phone']}"), subtitle: Text("${address['country']} ${address['provience']} ${address['city']} ${address['district']} ${address['addressLine']}"), value: address, groupValue: null, onChanged: null, ); }).toList(), SizedBox(height: 20), Text("选择支付方式:"), SizedBox(height: 10), Row( children: [ Radio( value: "支付宝", groupValue: null, onChanged: null, ), Text("支付宝"), ], ), Row( children: [ Radio( value: "微信", groupValue: null, onChanged: null, ), Text("微信"), ], ), ], ), actions: [ TextButton( onPressed: () => Navigator.of(context).pop(false), child: Text("取消"), ), TextButton( onPressed: () => Navigator.of(context).pop(true), child: Text("结算"), ), ], ); }

@override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text("购物车"), ), body: cartList == null ? Center(child: CircularProgressIndicator()) : cartList.isEmpty ? Center(child: Text("购物车为空")) : Column( children: [ Expanded( child: ListView.builder( itemCount: cartList.length, itemBuilder: (context, index) { return Column( children: [ Container( padding: EdgeInsets.symmetric(vertical: 10, horizontal: 15), color: Colors.grey.shade100, child: Row( children: [ Icon(Icons.location_on, size: 16), SizedBox(width: 5), Text( "收货地址", style: TextStyle(fontWeight: FontWeight.bold), ), SizedBox(width: 10), Text( "东北石油大学", ), ], ), ), ...cartList[index].map(_buildCartItem), ], ); }, ), ), Container( padding: EdgeInsets.symmetric(vertical: 10, horizontal: 15), decoration: BoxDecoration( border: Border(top: BorderSide(color: Colors.grey.shade300)), ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text("合计:¥$totalPrice"), _buildCheckoutButton(), ], ), ), ], ), ); } }

class CartItem { late int cartId; late int quantity; late double price; late Product product;

CartItem.fromJson(Map<String, dynamic> json, Product product) : cartId = jso

我现在用flutter写了一个商城我需要你按照下面的要求给我对应的文件和代码所有的网络请求都要写在apiservice里面我的网络请求这部分需要一个model去解析我现在需要你给我写一个购物车页面要好看的ui给我写解析数据的model和api_service的代码购物车需要请求网址是httpbookmusecloudtechgetshoppingcart返回的是一个json数组数组的第一个是每个购

原文地址: https://www.cveoy.top/t/topic/fzd4 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录