From c7ba9dc97bd9adb0042ded14858638ede7050ae9 Mon Sep 17 00:00:00 2001 From: guozhigq Date: Sun, 30 Jun 2024 22:01:12 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E7=B3=BB=E7=BB=9F=E6=B6=88=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/http/api.dart | 4 + lib/http/constants.dart | 1 + lib/http/msg.dart | 27 +++++- lib/models/msg/system.dart | 77 +++++++++++++++++ lib/pages/message/system/controller.dart | 14 ++- lib/pages/message/system/view.dart | 104 +++++++++++++++++++++++ lib/pages/whisper/view.dart | 2 +- 7 files changed, 226 insertions(+), 3 deletions(-) create mode 100644 lib/models/msg/system.dart diff --git a/lib/http/api.dart b/lib/http/api.dart index f20b8bcf..46bbb6ac 100644 --- a/lib/http/api.dart +++ b/lib/http/api.dart @@ -548,4 +548,8 @@ class Api { /// 收到的赞 static const String messageLikeAPi = '/x/msgfeed/like'; + + /// 系统通知 + static const String messageSystemAPi = + '${HttpString.messageBaseUrl}/x/sys-msg/query_unified_notify'; } diff --git a/lib/http/constants.dart b/lib/http/constants.dart index 3d749ee8..cad413ef 100644 --- a/lib/http/constants.dart +++ b/lib/http/constants.dart @@ -5,6 +5,7 @@ class HttpString { static const String appBaseUrl = 'https://app.bilibili.com'; static const String liveBaseUrl = 'https://api.live.bilibili.com'; static const String passBaseUrl = 'https://passport.bilibili.com'; + static const String messageBaseUrl = 'https://message.bilibili.com'; static const List validateStatusCodes = [ 302, 304, diff --git a/lib/http/msg.dart b/lib/http/msg.dart index 7c168230..86789fd1 100644 --- a/lib/http/msg.dart +++ b/lib/http/msg.dart @@ -3,6 +3,7 @@ import 'dart:math'; import 'package:dio/dio.dart'; import 'package:pilipala/models/msg/like.dart'; import 'package:pilipala/models/msg/reply.dart'; +import 'package:pilipala/models/msg/system.dart'; import '../models/msg/account.dart'; import '../models/msg/session.dart'; import '../utils/wbi_sign.dart'; @@ -149,7 +150,7 @@ class MsgHttp { 'msg[msg_status]': 0, 'msg[content]': jsonEncode(content), 'msg[timestamp]': DateTime.now().millisecondsSinceEpoch ~/ 1000, - 'msg[new_face_version]': 0, + 'msg[new_face_version]': 1, 'msg[dev_id]': getDevId(), 'from_firework': 0, 'build': 0, @@ -287,4 +288,28 @@ class MsgHttp { return {'status': false, 'date': [], 'msg': res.data['message']}; } } + + static Future messageSystem() async { + var res = await Request().get(Api.messageSystemAPi, data: { + 'csrf': await Request.getCsrf(), + 'page_size': 20, + 'build': 0, + 'mobi_app': 'web', + }); + if (res.data['code'] == 0) { + try { + print(res.data['data']['system_notify_list']); + return { + 'status': true, + 'data': res.data['data']['system_notify_list'] + .map((e) => MessageSystemModel.fromJson(e)) + .toList(), + }; + } catch (err) { + return {'status': false, 'date': [], 'msg': err.toString()}; + } + } else { + return {'status': false, 'date': [], 'msg': res.data['message']}; + } + } } diff --git a/lib/models/msg/system.dart b/lib/models/msg/system.dart new file mode 100644 index 00000000..20427707 --- /dev/null +++ b/lib/models/msg/system.dart @@ -0,0 +1,77 @@ +import 'dart:convert'; + +class MessageSystemModel { + int? id; + int? cursor; + int? type; + String? title; + Map? content; + Source? source; + String? timeAt; + int? cardType; + String? cardBrief; + String? cardMsgBrief; + String? cardCover; + String? cardStoryTitle; + String? cardLink; + String? mc; + int? isStation; + int? isSend; + int? notifyCursor; + + MessageSystemModel({ + this.id, + this.cursor, + this.type, + this.title, + this.content, + this.source, + this.timeAt, + this.cardType, + this.cardBrief, + this.cardMsgBrief, + this.cardCover, + this.cardStoryTitle, + this.cardLink, + this.mc, + this.isStation, + this.isSend, + this.notifyCursor, + }); + + factory MessageSystemModel.fromJson(Map jsons) => + MessageSystemModel( + id: jsons["id"], + cursor: jsons["cursor"], + type: jsons["type"], + title: jsons["title"], + content: json.decode(jsons["content"]), + source: Source.fromJson(jsons["source"]), + timeAt: jsons["time_at"], + cardType: jsons["card_type"], + cardBrief: jsons["card_brief"], + cardMsgBrief: jsons["card_msg_brief"], + cardCover: jsons["card_cover"], + cardStoryTitle: jsons["card_story_title"], + cardLink: jsons["card_link"], + mc: jsons["mc"], + isStation: jsons["is_station"], + isSend: jsons["is_send"], + notifyCursor: jsons["notify_cursor"], + ); +} + +class Source { + String? name; + String? logo; + + Source({ + this.name, + this.logo, + }); + + factory Source.fromJson(Map json) => Source( + name: json["name"], + logo: json["logo"], + ); +} diff --git a/lib/pages/message/system/controller.dart b/lib/pages/message/system/controller.dart index ad28af56..bf31f6bc 100644 --- a/lib/pages/message/system/controller.dart +++ b/lib/pages/message/system/controller.dart @@ -1,3 +1,15 @@ import 'package:get/get.dart'; +import 'package:pilipala/http/msg.dart'; +import 'package:pilipala/models/msg/system.dart'; -class MessageSystemController extends GetxController {} +class MessageSystemController extends GetxController { + RxList systemItems = [].obs; + + Future queryMessageSystem({String type = 'init'}) async { + var res = await MsgHttp.messageSystem(); + if (res['status']) { + systemItems.addAll(res['data']); + } + return res; + } +} diff --git a/lib/pages/message/system/view.dart b/lib/pages/message/system/view.dart index da0f1219..f7b94e5a 100644 --- a/lib/pages/message/system/view.dart +++ b/lib/pages/message/system/view.dart @@ -1,4 +1,8 @@ import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:pilipala/common/widgets/http_error.dart'; +import 'package:pilipala/models/msg/system.dart'; +import 'controller.dart'; class MessageSystemPage extends StatefulWidget { const MessageSystemPage({super.key}); @@ -8,12 +12,112 @@ class MessageSystemPage extends StatefulWidget { } class _MessageSystemPageState extends State { + final MessageSystemController _messageSystemCtr = + Get.put(MessageSystemController()); + late Future _futureBuilderFuture; + final ScrollController scrollController = ScrollController(); + + @override + void initState() { + super.initState(); + _futureBuilderFuture = _messageSystemCtr.queryMessageSystem(); + } + @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('系统通知'), ), + body: RefreshIndicator( + onRefresh: () async { + await _messageSystemCtr.queryMessageSystem(); + }, + child: FutureBuilder( + future: _futureBuilderFuture, + builder: (BuildContext context, AsyncSnapshot snapshot) { + if (snapshot.connectionState == ConnectionState.done) { + if (snapshot.data == null) { + return const SizedBox(); + } + if (snapshot.data['status']) { + final systemItems = _messageSystemCtr.systemItems; + print(systemItems.length); + return Obx( + () => ListView.separated( + controller: scrollController, + itemBuilder: (context, index) => SystemItem( + item: systemItems[index], + index: index, + messageSystemCtr: _messageSystemCtr, + ), + itemCount: systemItems.length, + separatorBuilder: (BuildContext context, int index) { + return Divider( + indent: 14, + endIndent: 14, + height: 1, + color: Colors.grey.withOpacity(0.1), + ); + }, + ), + ); + } else { + // 请求错误 + return CustomScrollView( + slivers: [ + HttpError( + errMsg: snapshot.data['msg'], + fn: () { + setState(() { + _futureBuilderFuture = + _messageSystemCtr.queryMessageSystem(); + }); + }, + ) + ], + ); + } + } else { + return const SizedBox(); + } + }, + ), + ), + ); + } +} + +class SystemItem extends StatelessWidget { + final MessageSystemModel item; + final int index; + final MessageSystemController messageSystemCtr; + + const SystemItem( + {super.key, + required this.item, + required this.index, + required this.messageSystemCtr}); + + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.fromLTRB(14, 14, 14, 12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(item.title!, + style: + const TextStyle(fontSize: 16, fontWeight: FontWeight.bold)), + const SizedBox(height: 4), + Text( + item.timeAt!, + style: TextStyle(color: Theme.of(context).colorScheme.outline), + ), + const SizedBox(height: 6), + Text(item.content!['web']), + ], + ), ); } } diff --git a/lib/pages/whisper/view.dart b/lib/pages/whisper/view.dart index 9436e2be..1814c274 100644 --- a/lib/pages/whisper/view.dart +++ b/lib/pages/whisper/view.dart @@ -71,7 +71,7 @@ class _WhisperPageState extends State { ..._whisperController.noticesList.map((element) { return InkWell( onTap: () { - if (['/messageAt', '/messageSystem'] + if (['/messageAt'] .contains(element['path'])) { SmartDialog.showToast('功能开发中'); return;