diff --git a/android/app/src/main/java/com/czg/cashier_reserve/call/CallManager.java b/android/app/src/main/java/com/czg/cashier_reserve/call/CallManager.java index eba35fb..d810a5d 100644 --- a/android/app/src/main/java/com/czg/cashier_reserve/call/CallManager.java +++ b/android/app/src/main/java/com/czg/cashier_reserve/call/CallManager.java @@ -40,7 +40,7 @@ public class CallManager { @SuppressLint("Range") String number = cursor.getString(cursor.getColumnIndex(CallLog.Calls.NUMBER)); //号码 @SuppressLint("Range") long dateLong = cursor.getLong(cursor.getColumnIndex(CallLog.Calls.DATE)); //获取通话日期 @SuppressLint("SimpleDateFormat") String date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(dateLong)); -// @SuppressLint("SimpleDateFormat") String time = new SimpleDateFormat("HH:mm").format(new Date(dateLong)); + @SuppressLint("SimpleDateFormat") String time = new SimpleDateFormat("HH:mm").format(new Date(dateLong)); @SuppressLint("Range") int duration = cursor.getInt(cursor.getColumnIndex(CallLog.Calls.DURATION));//获取通话时长,值为多少秒 @SuppressLint("Range") int type = cursor.getInt(cursor.getColumnIndex(CallLog.Calls.TYPE)); //获取通话类型:1.呼入2.呼出3.未接 // @SuppressLint("SimpleDateFormat") String dayCurrent = new SimpleDateFormat("dd").format(new Date()); @@ -53,6 +53,7 @@ public class CallManager { callLog.put("date", date); callLog.put("duration", duration); callLog.put("type", type); + callLog.put("time", time); } catch (Exception e) { e.printStackTrace(); } diff --git a/images/reserve/create.png b/images/reserve/create.png new file mode 100644 index 0000000..bcdfda1 Binary files /dev/null and b/images/reserve/create.png differ diff --git a/images/reserve/phone_fail.png b/images/reserve/phone_fail.png new file mode 100644 index 0000000..22ccd3d Binary files /dev/null and b/images/reserve/phone_fail.png differ diff --git a/images/reserve/phone_suc.png b/images/reserve/phone_suc.png new file mode 100644 index 0000000..389fab4 Binary files /dev/null and b/images/reserve/phone_suc.png differ diff --git a/lib/common/channel/call_log_model.dart b/lib/common/channel/call_log_model.dart new file mode 100644 index 0000000..d93d6f5 --- /dev/null +++ b/lib/common/channel/call_log_model.dart @@ -0,0 +1,86 @@ +import 'dart:convert'; + +/// number : "18092171236" +/// date : "2024-11-21 09:32:27" +/// duration : 0 +/// type : 5 +/// name : gong + +CallLogModel callLogModelFromJson(String str) => + CallLogModel.fromJson(json.decode(str)); + +String callLogModelToJson(CallLogModel data) => json.encode(data.toJson()); + +class CallLogModel { + CallLogModel({ + String? number, + String? date, + num? duration, + num? type, + String? name, + String? time, + }) { + _number = number; + _date = date; + _duration = duration; + _type = type; + _name = name; + _time = time; + } + + CallLogModel.fromJson(dynamic json) { + _number = json['number']; + _date = json['date']; + _duration = json['duration']; + _type = json['type']; + _name = json['name']; + _time = json['time']; + } + + String? _number; + String? _date; + num? _duration; + num? _type; + String? _name; + String? _time; + + CallLogModel copyWith({ + String? number, + String? date, + num? duration, + num? type, + String? name, + String? time, + }) => + CallLogModel( + number: number ?? _number, + date: date ?? _date, + duration: duration ?? _duration, + type: type ?? _type, + name: name ?? _name, + time: time ?? _time, + ); + + String? get number => _number; + + String? get date => _date; + + num? get duration => _duration; + + num? get type => _type; + + String? get name => _name; + + String? get time => _time; + + Map toJson() { + final map = {}; + map['number'] = _number; + map['date'] = _date; + map['duration'] = _duration; + map['type'] = _type; + map['name'] = _name; + map['time'] = _time; + return map; + } +} diff --git a/lib/common/channel/channel_event.dart b/lib/common/channel/channel_event.dart index a17f83f..710937e 100644 --- a/lib/common/channel/channel_event.dart +++ b/lib/common/channel/channel_event.dart @@ -1,6 +1,10 @@ +import 'dart:convert'; + import 'package:cashier_reserve/common/print/print.dart'; import 'package:flutter/services.dart'; +import '../manager/event_manager.dart'; +import 'call_log_model.dart'; import 'names.dart'; class MyEventChannel { @@ -13,13 +17,19 @@ class MyEventChannel { channel.receiveBroadcastStream().listen((Object? o) { yjPrint("onGetCallLogResult"); yjPrint(o); - // AlipayPayResultEvent event = AlipayPayResultEvent(); - // if (o is int) { - // event.resultStatus = o; - // } else { - // event.resultStatus = int.parse(o as String); - // } - // EventManager.postEvent(event); + GetCallLogEvent event = GetCallLogEvent(); + if (o is String) { + event.isSuccess = true; + List list = json.decode(o); + List callLogs = []; + for (var item in list) { + callLogs.add(CallLogModel.fromJson(item)); + } + event.callLogs = callLogs.reversed.toList(); + } else { + event.isSuccess = false; + } + EventManager.postEvent(event); }, onError: (Object error) { yjPrint("onGetCallLogResult error"); }); diff --git a/lib/common/manager/event_manager.dart b/lib/common/manager/event_manager.dart new file mode 100644 index 0000000..2c523b1 --- /dev/null +++ b/lib/common/manager/event_manager.dart @@ -0,0 +1,54 @@ +import 'dart:async'; + +import 'package:cashier_reserve/common/channel/call_log_model.dart'; +import 'package:event_bus/event_bus.dart'; + + +class EventManager { + static EventBus? _eventBus; + + static final Map> _eventMap = {}; + + static EventBus? get eventBus => getEventBus(); + + static EventBus? getEventBus() { + _eventBus ??= EventBus(); + return _eventBus; + } + + static void postEvent(MyEvent event) { + getEventBus()!.fire(event); + } + + static void addListener(dynamic widget, void Function(T event) onData) { + StreamSubscription event = EventManager.eventBus!.on().listen((T e) { + onData(e); + }); + List? list = _eventMap[widget]; + list ??= []; + list.add(event); + _eventMap[widget] = list; + } + + static void cancelListener(dynamic widget) { + List? list = _eventMap[widget]; + if (list == null) { + return; + } + for (var event in list) { + event.cancel(); + } + } +} + +class MyEvent { + String name = ''; +} + +class GetCallLogEvent extends MyEvent { + List callLogs; + bool isLoadMore = false; + bool isSuccess = false; + + GetCallLogEvent({this.callLogs = const [], this.isLoadMore = false, this.isSuccess = false}); +} \ No newline at end of file diff --git a/lib/home/reserve_view.dart b/lib/home/reserve_view.dart index b7150d1..0a15701 100644 --- a/lib/home/reserve_view.dart +++ b/lib/home/reserve_view.dart @@ -1,5 +1,7 @@ import 'package:cashier_reserve/common/base/ui.dart'; import 'package:cashier_reserve/common/base/ui_model.dart'; +import 'package:cashier_reserve/common/channel/call_log_model.dart'; +import 'package:cashier_reserve/common/print/print.dart'; import 'package:cashier_reserve/home/reserve_view_model.dart'; import '../common/base/provider.dart'; @@ -43,7 +45,7 @@ class ReserveView extends BaseUI { width: 15, ), InkWell( - onTap: () {}, + onTap: () {}, child: SizedBox( width: 40, height: 40, @@ -84,7 +86,10 @@ class ReserveView extends BaseUI { width: 40, height: 40, child: Center( - child: Text("刷新", style: TextStyle(fontSize: 15, color: Colors.blue),), + child: Text( + "刷新", + style: TextStyle(fontSize: 15, color: Colors.blue), + ), ), ), ), @@ -95,7 +100,156 @@ class ReserveView extends BaseUI { Widget _buildContentView(BuildContext context, ReserveViewModel provider) { return Row( - children: [], + children: [ + _buildLeftContent(context, provider), + Expanded(child: _buildRightContent(context, provider)), + ], + ); + } + + Widget _buildLeftContent(BuildContext context, ReserveViewModel provider) { + yjPrint("callLogs length: ${provider.callLogs?.length}"); + return Column( + children: [ + Expanded( + child: SizedBox( + width: 430, + child: ListView.builder( + itemCount: provider.callLogs?.length ?? 0, + itemBuilder: (context, index) { + return _buildCallRecordItem(context, provider.callLogs?[index]); + }, + ), + )), + Container( + padding: const EdgeInsets.fromLTRB(20, 10, 20, 15), + child: InkWell( + onTap: () {}, + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(5), + color: const Color(0xff318AFE), + ), + width: 300, + height: 36, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Image.asset( + 'images/reserve/create.png', + width: 20, + height: 20, + ), + const SizedBox( + width: 5, + ), + const Text( + "创建订单", + style: TextStyle(color: Colors.white, fontSize: 14), + ), + ], + ), + ), + ), + ) + ], + ); + } + + Widget _buildRightContent(BuildContext context, ReserveViewModel provider) { + return Container(); + } + + /// _buildCallRecordItem 通话记录item + Widget _buildCallRecordItem(BuildContext context, CallLogModel? model) { + return Container( + padding: const EdgeInsets.fromLTRB(15, 15, 15, 5), + child: Column( + children: [ + Row( + children: [ + Column( + children: [ + Image.asset( + (model?.type ?? 0) == 3 + ? "images/reserve/phone_fail.png" + : "images/reserve/phone_suc.png", + width: 24, + height: 24, + ), + const SizedBox(height: 2), + Text( + model?.time ?? "", + style: + const TextStyle(color: Color(0xff999999), fontSize: 12), + ), + ], + ), + const SizedBox(width: 10), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + model?.name ?? "未知电话", + style: + const TextStyle(color: Color(0xff333333), fontSize: 14), + ), + const SizedBox(height: 5), + Row( + children: [ + Text( + model?.number ?? "", + style: const TextStyle( + color: Color(0xff333333), fontSize: 14), + ), + const SizedBox( + width: 15, + ), + const Text( + "已消费0单", + style: + TextStyle(color: Color(0xff333333), fontSize: 14), + ), + const SizedBox( + width: 15, + ), + const Text( + "已撤0单", + style: + TextStyle(color: Color(0xff333333), fontSize: 14), + ), + ], + ), + ], + ), + const Expanded(child: SizedBox()), + InkWell( + onTap: () {}, + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(5), + border: + Border.all(color: const Color(0xff318AFE), width: 1), + ), + padding: const EdgeInsets.fromLTRB(20, 7, 20, 7), + child: const Text( + "处理", + style: TextStyle(color: Color(0xff318AFE), fontSize: 14), + ), + ), + ) + ], + ), + const SizedBox( + height: 10, + ), + Container( + height: 1, + color: const Color(0xffededed), + ), + ], + ), ); } diff --git a/lib/home/reserve_view_model.dart b/lib/home/reserve_view_model.dart index 61162a4..24f3d31 100644 --- a/lib/home/reserve_view_model.dart +++ b/lib/home/reserve_view_model.dart @@ -1,5 +1,8 @@ import 'package:cashier_reserve/common/base/ui_model.dart'; +import 'package:cashier_reserve/common/channel/call_log_model.dart'; import 'package:cashier_reserve/common/channel/channel_manager.dart'; +import 'package:cashier_reserve/common/manager/event_manager.dart'; +import 'package:cashier_reserve/common/print/print.dart'; class ReserveViewModel extends BaseUIModel { Map weekdayMap = { @@ -17,10 +20,22 @@ class ReserveViewModel extends BaseUIModel { 1: "明", 2: "后", }; + + List? callLogs = []; - // ReserveViewModel() { - // loadData(); - // } + ReserveViewModel() { + EventManager.addListener(this, (event) { + if (event.isSuccess) { + if (!event.isSuccess) { + return; + } + callLogs = event.callLogs; + notifyListeners(); + } + }); + + loadCallLog(); + } void loadCallLog() { ChannelManager.getCallLog("getCallLog"); diff --git a/pubspec.lock b/pubspec.lock index 0924138..4e57b1a 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -97,6 +97,14 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "2.0.0" + event_bus: + dependency: "direct main" + description: + name: event_bus + sha256: "1a55e97923769c286d295240048fc180e7b0768902c3c2e869fe059aafa15304" + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.0.1" fake_async: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 773dc49..d71d3a5 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -41,6 +41,7 @@ dependencies: cached_network_image: ^3.4.1 timeago: ^3.7.0 percent_indicator: ^4.0.1 + event_bus: ^2.0.1 dev_dependencies: flutter_test: