feat: 完成智能电网电工端 Flutter 应用初始化

创建完整的 Flutter 项目结构,包含 Android 和 iOS 平台配置、核心网络层、路由、状态管理及业务模块(订单、收益、认证),适配原 uni-app 项目功能逻辑
This commit is contained in:
andyesfly committed 2026-10-06 11:54:10 +08:00
commit 56830e94ec
108 files changed
+9272

No files matched your search

+149
View File
@@ -0,0 +1,149 @@
import '../../../core/network/api_client.dart';
import '../../../core/network/api_response.dart';
import '../../../core/utils/id_util.dart';
/// 站内消息。对应后端 `sys_notice` 的电工端视图。
///
/// 后端 `toJSON()` 返回原始列名,时间字段为下划线命名 `created_at`,
/// `is_read` 为 0/1。
class Notice {
const Notice({
required this.id,
required this.noticeType,
required this.title,
required this.content,
required this.bizType,
required this.bizId,
required this.receiverType,
required this.ruleId,
required this.batchId,
required this.isRead,
required this.createdAt,
});
final int id;
/// 通知类型,如 `cert_expire`。
final String noticeType;
final String title;
final String content;
/// 业务类型,如 `worker_cert`。
final String bizType;
/// 业务主键。
final int? bizId;
/// `user` 管理端 / `worker` 电工端。
final String receiverType;
/// 来源通知规则 / 群发批次,可能为空。
final int? ruleId;
final int? batchId;
final bool isRead;
/// 原始 `created_at`,交给 `format_util` 渲染。
final Object? createdAt;
factory Notice.fromJson(Map<String, dynamic> json) => Notice(
id: toIntOr(json['id'], 0),
noticeType: json['noticeType'] as String? ?? '',
title: json['title'] as String? ?? '',
content: json['content'] as String? ?? '',
bizType: json['bizType'] as String? ?? '',
bizId: toIntOrNull(json['bizId']),
receiverType: json['receiverType'] as String? ?? '',
ruleId: toIntOrNull(json['ruleId']),
batchId: toIntOrNull(json['batchId']),
isRead: _toBool(json['isRead']),
createdAt: json['created_at'],
);
/// 复制为已读,用于标记成功后本地更新,避免整页重拉。
Notice copiedWithRead() => Notice(
id: id,
noticeType: noticeType,
title: title,
content: content,
bizType: bizType,
bizId: bizId,
receiverType: receiverType,
ruleId: ruleId,
batchId: batchId,
isRead: true,
createdAt: createdAt,
);
}
/// 消息分页结果。
class NoticePage {
const NoticePage({
required this.list,
required this.total,
required this.page,
required this.pageSize,
});
final List<Notice> list;
final int total;
final int page;
final int pageSize;
factory NoticePage.fromJson(Map<String, dynamic> json) => NoticePage(
list: (json['list'] as List? ?? const [])
.map((e) => Notice.fromJson((e as Map).cast<String, dynamic>()))
.toList(),
total: toIntOr(json['total'], 0),
page: toIntOr(json['page'], 1),
pageSize: toIntOr(json['pageSize'], 10),
);
}
/// 站内消息中心接口,对应后端 `/api/worker-app/notices*`。
class NoticeApi {
NoticeApi(this._client);
final ApiClient _client;
/// 消息列表。`isRead` 传 true/false 时按已读状态筛选,null 取全部。
///
/// 后端 `Number(query.isRead)` 解析,故这里显式传 1 / 0。
Future<ApiResponse<NoticePage>> list({
int page = 1,
int pageSize = 10,
bool? isRead,
}) => _client.get<NoticePage>(
'/worker-app/notices',
query: {
'page': page,
'pageSize': pageSize,
if (isRead != null) 'isRead': isRead ? 1 : 0,
},
parse: (d) => NoticePage.fromJson((d as Map).cast<String, dynamic>()),
);
/// 未读消息数。
Future<ApiResponse<int>> unreadCount() => _client.get<int>(
'/worker-app/notices/unread-count',
parse: (d) => toIntOr((d as Map)['count'], 0),
);
/// 全部标记已读,返回更新条数。
Future<ApiResponse<int>> readAll() => _client.put<int>(
'/worker-app/notices/read-all',
parse: (d) => toIntOr((d as Map)['updated'], 0),
);
/// 单条标记已读。
Future<ApiResponse<void>> markRead(int id) =>
_client.put<void>('/worker-app/notices/$id/read');
}
bool _toBool(Object? v) {
if (v is bool) return v;
if (v is num) return v != 0;
final s = v?.toString().toLowerCase();
return s == '1' || s == 'true';
}