From 893b925a041d2412ff5ba9127aa7ab6ddf2aebad Mon Sep 17 00:00:00 2001 From: Sergey Elpashev Date: Tue, 18 Jun 2024 20:40:45 +0300 Subject: [PATCH] fix: ultra-fake orders --- lib/components/history_item_card.dart | 2 +- lib/interfaces/items.dart | 59 ++++++++----- lib/mobile_example.dart | 13 ++- lib/pages/order_confirmation.dart | 60 +++++++++++-- lib/pages/order_history.dart | 20 ++++- lib/pages/order_info.dart | 118 +++----------------------- lib/tools/history.dart | 89 +++++++++---------- 7 files changed, 170 insertions(+), 191 deletions(-) diff --git a/lib/components/history_item_card.dart b/lib/components/history_item_card.dart index 762eff5..2817622 100644 --- a/lib/components/history_item_card.dart +++ b/lib/components/history_item_card.dart @@ -16,7 +16,7 @@ class HistoryItemCard extends StatelessWidget { final String id; final String cost; final String date; - final Image image; + final Widget image; const HistoryItemCard({ super.key, diff --git a/lib/interfaces/items.dart b/lib/interfaces/items.dart index 4ac47c8..7607088 100644 --- a/lib/interfaces/items.dart +++ b/lib/interfaces/items.dart @@ -31,6 +31,8 @@ class GymItem { final double price; final String categoryId; final List images; + final String supplierId; + final String supplierName; int localCount = 0; GymItem({ @@ -42,23 +44,31 @@ class GymItem { required this.price, required this.categoryId, required this.images, + required this.supplierId, + required this.supplierName, }); factory GymItem.fromRawJson(String str) => GymItem.fromJson(json.decode(str)); String toRawJson() => json.encode(toJson()); - factory GymItem.fromJson(Map json) => GymItem( - id: json["id"], - externalId: json["ExternalId"], - title: json["title"], - description: json["description"], - count: json["count"], - price: json["price"] / 100, - categoryId: json["categoryId"], - images: List.from( - json["images"].map((x) => GymImage.fromJson(x))), - ); + factory GymItem.fromJson(Map json) { + return GymItem( + id: json["id"], + externalId: json["ExternalId"], + title: json["title"], + description: json["description"], + count: json["count"], + price: json["price"] / 100, + categoryId: json["categoryId"], + images: + List.from(json["images"].map((x) => GymImage.fromJson(x))), + supplierId: json["supplier"] == null ? '' : json["supplier"]["id"] ?? '', + supplierName: json["supplier"] == null + ? '' + : json["supplier"]["title"] ?? "Поставщик", + ); + } Map toJson() => { "id": id, @@ -69,6 +79,8 @@ class GymItem { "price": price, "categoryId": categoryId, "images": List.from(images.map((x) => x.toJson())), + "supplier": + supplierId == '' ? null : {"id": supplierId, "title": supplierName}, }; } @@ -183,7 +195,7 @@ class GymHistoryItem { } class GymHistoryItemDetail { - final String id; + String id; final String date; final String sum; String? payUrl; @@ -236,7 +248,7 @@ class GymHistoryItemDetail { class GymHistoryItemDetailProvider { final String id; final String name; - final String status; + String status; final List items; GymHistoryItemDetailProvider({ @@ -251,14 +263,15 @@ class GymHistoryItemDetailProvider { String toRawJson() => json.encode(toJson()); - factory GymHistoryItemDetailProvider.fromJson(Map json) => - GymHistoryItemDetailProvider( - id: json["id"], - name: json["name"], - status: json["status"], - items: List.from( - json["items"].map((x) => GymHistoryItemDetailItem.fromJson(x))), - ); + factory GymHistoryItemDetailProvider.fromJson(Map json) { + return GymHistoryItemDetailProvider( + id: json["id"], + name: json["name"], + status: json["status"], + items: List.from( + json["items"].map((x) => GymHistoryItemDetailItem.fromJson(x))), + ); + } Map toJson() => { "id": id, @@ -272,6 +285,7 @@ class GymHistoryItemDetailItem { final String photo; final String id; final int count; + final String name; final String price; GymHistoryItemDetailItem({ @@ -279,6 +293,7 @@ class GymHistoryItemDetailItem { required this.id, required this.count, required this.price, + required this.name, }); factory GymHistoryItemDetailItem.fromRawJson(String str) => @@ -292,6 +307,7 @@ class GymHistoryItemDetailItem { id: json["id"], count: json["count"], price: json["price"], + name: json["name"], ); Map toJson() => { @@ -299,5 +315,6 @@ class GymHistoryItemDetailItem { "id": id, "count": count, "price": price, + "name": name, }; } diff --git a/lib/mobile_example.dart b/lib/mobile_example.dart index 1430122..077dc3c 100644 --- a/lib/mobile_example.dart +++ b/lib/mobile_example.dart @@ -6,6 +6,7 @@ import 'package:gymlink_module_web/main_mobile.dart'; import 'package:gymlink_module_web/providers/main.dart'; import 'package:http/http.dart' as http; import 'package:provider/provider.dart'; +import 'package:shared_preferences/shared_preferences.dart'; void main() { runApp(const MyExampleApp()); @@ -250,8 +251,16 @@ class ExampleSecondPage extends StatelessWidget { title: const Text('GymLink Example App'), ), drawer: getDrawer(context), - body: const Center( - child: Text('Example page'), + body: Center( + child: TextButton( + onPressed: () async { + final prefs = await SharedPreferences.getInstance(); + prefs.remove('token'); + prefs.remove('history'); + prefs.remove('cart'); + prefs.remove('detail_history'); + }, + child: const Text('Clear')), ), ); } diff --git a/lib/pages/order_confirmation.dart b/lib/pages/order_confirmation.dart index 993519c..56d3a55 100644 --- a/lib/pages/order_confirmation.dart +++ b/lib/pages/order_confirmation.dart @@ -1,3 +1,5 @@ +import 'dart:math'; + import 'package:flutter/material.dart'; import 'package:flutter_markdown/flutter_markdown.dart'; import 'package:gymlink_module_web/components/app_bar.dart'; @@ -69,6 +71,57 @@ class _OrderConfirmationPageState extends State { final _addressController = TextEditingController(); final _nameController = TextEditingController(); + Future _addOrderToHistory() async { + String name = _nameController.text; + String email = _emailController.text; + String address = _addressController.text; + + Set supplierIdsSet = {}; + for (final item in cartItems) { + supplierIdsSet.add(item.supplierId); + } + List providers = []; + for (final supplierId in supplierIdsSet) { + List items = + cartItems.where((e) => e.supplierId == supplierId).toList(); + List detailItems = []; + for (final item in items) { + detailItems.add(GymHistoryItemDetailItem( + id: item.id, + photo: item.images[0].url, + count: item.localCount, + price: item.price.toString(), + name: item.title, + )); + } + GymHistoryItemDetailProvider provider = GymHistoryItemDetailProvider( + id: supplierId, + name: items.first.supplierName, + items: detailItems, + // status: 'Не оплачен' + status: Random().nextBool() + ? 'Не оплачен' + : Random().nextBool() + ? 'Не оплачен' + : Random().nextBool() + ? 'Сборка' + : 'Доставляется', + ); + providers.add(provider); + } + + final order = GymHistoryItemDetail( + id: Random().nextInt(1000000).toString(), + receiver: name, + email: email, + address: address, + sum: totalPrice.toString(), + date: '', + providers: providers, + ); + await addToHistory(order); + } + @override void initState() { super.initState(); @@ -248,12 +301,7 @@ class _OrderConfirmationPageState extends State { if (!_checkInputs()) return; _goToPage(); await clearCart(); - await addToHistory(GymHistoryItem( - id: '123', - date: '01.01.1970', - sum: '123', - photo: 'product.png', - )); + await _addOrderToHistory(); Provider.of(context, listen: false) .updateCartLength(); Navigator.of(context).pushAndRemoveUntil( diff --git a/lib/pages/order_history.dart b/lib/pages/order_history.dart index ecac66b..b4821c4 100644 --- a/lib/pages/order_history.dart +++ b/lib/pages/order_history.dart @@ -153,10 +153,22 @@ class _HistoryPageState extends State { id: item.id, cost: item.sum, date: item.date, - image: Image( - image: AssetImage( - 'assets/${item.photo}'), - width: 50, + image: FutureBuilder( + future: precacheImage( + NetworkImage(item.photo), + context), + builder: (context, snapshot) { + if (snapshot.connectionState == + ConnectionState.done) { + return Image( + image: NetworkImage( + item.photo), + width: 50, + ); + } else { + return const CircularProgressIndicator(); + } + }, ), ); }, diff --git a/lib/pages/order_info.dart b/lib/pages/order_info.dart index bddce0f..ef3262d 100644 --- a/lib/pages/order_info.dart +++ b/lib/pages/order_info.dart @@ -8,6 +8,7 @@ import 'package:gymlink_module_web/components/heading.dart'; import 'package:gymlink_module_web/components/order_detail_item_card.dart'; import 'package:gymlink_module_web/interfaces/items.dart'; import 'package:gymlink_module_web/tools/history.dart'; +import 'package:gymlink_module_web/tools/text.dart'; import 'package:url_launcher/url_launcher.dart'; final GymHistoryItemDetail item = GymHistoryItemDetail.fromJson({ @@ -77,8 +78,7 @@ class _OrderInfoPageState extends State { Future _goToPage() async { if (detail?.payUrl != null) { - final Uri url = Uri.parse(detail?.payUrl ?? 'example.org'); - detail!.payUrl = null; + final Uri url = Uri.parse(detail?.payUrl ?? 'https://example.org'); if (!await launchUrl(url, webOnlyWindowName: '_blank')) { throw 'Could not launch $url'; } @@ -160,14 +160,12 @@ class _OrderInfoPageState extends State { OrderDetailCardItemCard( image: FutureBuilder( future: precacheImage( - const AssetImage('assets/product.png'), - context), + NetworkImage(item.photo), context), builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.done) { - return const Image( - image: - AssetImage('assets/product.png'), + return Image( + image: NetworkImage(item.photo), width: 50, ); } else { @@ -175,7 +173,7 @@ class _OrderInfoPageState extends State { } }, ), - name: 'Протеин', + name: shortString(item.name), count: item.count, price: double.parse(item.price), ), @@ -207,13 +205,15 @@ class _OrderInfoPageState extends State { Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ + MarkdownBody( + data: '## Итого: ${detail!.sum} руб.'), MarkdownBody( data: "### Адрес получателя: __${detail!.address}__"), MarkdownBody( data: '### Почта: __${detail!.email}__'), MarkdownBody( - data: '### ФИО: _${detail!.receiver}_'), + data: '### ФИО: __${detail!.receiver}__'), ], ), detail?.payUrl == null @@ -222,7 +222,7 @@ class _OrderInfoPageState extends State { child: ElevatedButton( onPressed: () async { await _goToPage(); - debugPrint('clicked'); + await payOrder(detail!.id); }, style: ElevatedButton.styleFrom( backgroundColor: @@ -261,102 +261,4 @@ class _OrderInfoPageState extends State { : _buildContent(), ); } - - // @override - // Widget build(BuildContext context) { - // return Scaffold( - // appBar: const GymLinkAppBar(), - // body: detail == null - // ? const Center(child: CircularProgressIndicator()) - // : Column( - // mainAxisAlignment: MainAxisAlignment.start, - // children: [ - // GymLinkHeader(title: "Заказ #${detail?.id} от ${detail?.date}"), - // Expanded( - // child: RefreshIndicator( - // onRefresh: () => _onRefresh(), - // edgeOffset: 55, - // child: Scrollbar( - // controller: _scrollController, - // child: ListView( - // shrinkWrap: true, - // controller: _scrollController, - // children: [ - // detail != null - // ? ListView.builder( - // itemCount: (detail!.providers.length + 1), - // shrinkWrap: true, - // physics: const NeverScrollableScrollPhysics(), - // itemBuilder: (context, index) { - // final provider = detail!.providers[0]; - // return Card( - // elevation: 3, - // child: Column( - // children: [ - // MarkdownBody( - // data: '# ${provider.name}'), - // MarkdownBody( - // data: - // '## Статус: ${provider.status}'), - // const MarkdownBody( - // data: '### Состав:'), - // for (final item in provider.items) - // OrderDetailCardItemCard( - // image: FutureBuilder( - // future: precacheImage( - // const AssetImage( - // 'assets/product.png'), - // context), - // builder: (context, snapshot) { - // if (snapshot - // .connectionState == - // ConnectionState.done) { - // return const Image( - // image: AssetImage( - // 'assets/product.png'), - // width: 50, - // ); - // } else { - // return const CircularProgressIndicator(); - // } - // }, - // ), - // name: 'Протеин', - // count: item.count, - // price: double.parse(item.price), - // ), - // ], - // ), - // ); - // }, - // ) - // : const SizedBox.shrink(), - // Card( - // elevation: 4, - // child: Padding( - // padding: const EdgeInsetsDirectional.symmetric( - // horizontal: 10, vertical: 20), - // child: Column( - // mainAxisSize: MainAxisSize.min, - // children: [ - // MarkdownBody( - // data: - // "### Адрес получателя: _${detail!.address}_"), - // Markdown( - // data: '### Почта: _${detail!.email}_'), - // // Markdown( - // // data: '### ФИО: _${detail!.receiver}_'), - // ], - // ), - // ), - // ), - // ], - // ), - // ), - // ), - // ), - // ], - // ), - // ); - // } } diff --git a/lib/tools/history.dart b/lib/tools/history.dart index be67806..8b4c6e0 100644 --- a/lib/tools/history.dart +++ b/lib/tools/history.dart @@ -16,7 +16,7 @@ Future> getHistory() async { return history; } -Future addToHistory(GymHistoryItem item) async { +Future addToHistory(GymHistoryItemDetail item) async { final prefs = await SharedPreferences.getInstance(); String historyString = prefs.getString('history') ?? "[]"; List history = []; @@ -29,6 +29,10 @@ Future addToHistory(GymHistoryItem item) async { for (var historyItem in jsonDecode(detailHistoryString) as List) { detailHistory.add(GymHistoryItemDetail.fromJson(historyItem)); } + List> providers = []; + for (final provider in item.providers) { + providers.add(provider.toJson()); + } var json = { "id": item.id, "date": DateTime.now() @@ -40,58 +44,23 @@ Future addToHistory(GymHistoryItem item) async { .split('.') .reversed .join('.'), - "sum": Random().nextInt(100000).toString(), - "pay_url": [null, "https://example.org"][Random().nextInt(2)], - "receiver": "Иванов Иван Иванович ${Random().nextInt(100000).toString()}", - "email": "a${Random().nextInt(100000).toString()}@a.ru", - "address": - "г. ${['Москва', 'Петербург', 'Новгород'][Random().nextInt(3)]}, ул. ${[ - 'Пушкина', - 'Ленина', - 'Лермонтова' - ][Random().nextInt(3)]}, д. ${Random().nextInt(100).toString()}", - "providers": [ - { - "id": Random().nextInt(100000).toString(), - "name": "Поставщик ${Random().nextInt(100000).toString()}", - "status": ["Доставлен", "Доставляется", "Ожидает"][Random().nextInt(3)], - "items": [ - { - "photo": "url${Random().nextInt(100000).toString()}", - "id": Random().nextInt(100000).toString(), - "count": Random().nextInt(100), - "price": Random().nextInt(100000).toString() - }, - { - "photo": "url${Random().nextInt(100000).toString()}", - "id": Random().nextInt(100000).toString(), - "count": Random().nextInt(100), - "price": Random().nextInt(100000).toString() - } - ] - }, - { - "id": Random().nextInt(100000).toString(), - "name": "Поставщик ${Random().nextInt(100000).toString()}", - "status": ["Доставлен", "Доставляется", "Ожидает"][Random().nextInt(3)], - "items": [ - { - "photo": "url${Random().nextInt(100000).toString()}", - "id": Random().nextInt(100000).toString(), - "count": Random().nextInt(100), - "price": Random().nextInt(100000).toString() - } - ] - } - ] + "sum": item.sum, + "pay_url": item.providers.where((e) => e.status == 'Не оплачен').isNotEmpty + ? 'https://example.org' + : null, + "receiver": item.receiver, + "email": item.email, + "address": item.address, + "providers": providers }; final detailHistoryItem = GymHistoryItemDetail.fromJson(json); detailHistory.add(detailHistoryItem); history.add(GymHistoryItem( - date: detailHistoryItem.date, - id: detailHistoryItem.id, - photo: 'product.png', - sum: detailHistoryItem.sum)); + date: detailHistoryItem.date, + id: detailHistoryItem.id, + photo: detailHistoryItem.providers[0].items[0].photo, + sum: detailHistoryItem.sum, + )); prefs.setString('history', jsonEncode(history)); prefs.setString('detail_history', jsonEncode(detailHistory)); } @@ -106,3 +75,25 @@ Future getHistoryDetail(String id) async { } return null; } + +Future payOrder(String id) async { + final prefs = await SharedPreferences.getInstance(); + String historyString = prefs.getString('detail_history') ?? "[]"; + List history = []; + for (var historyItem in jsonDecode(historyString) as List) { + history.add(GymHistoryItemDetail.fromJson(historyItem)); + } + List newHistory = []; + for (final historyItem in history) { + if (historyItem.id == id) { + for (final provider in historyItem.providers) { + if (provider.status == 'Не оплачен') { + provider.status = 'Оплачен'; + } + } + historyItem.payUrl = null; + } + newHistory.add(historyItem); + } + prefs.setString('detail_history', jsonEncode(newHistory)); +}