ver1.00.00

update
This commit is contained in:
spasolreisa
2026-04-21 00:28:41 +08:00
parent b985cd1f9e
commit f5f62c828d
13 changed files with 1496 additions and 175 deletions

View File

@@ -1,22 +1,33 @@
import 'dart:convert';
import 'dart:typed_data'; // 确保导入,因为 uploadStegImage 需要 Uint8List
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../model/user_model.dart';
import '../service/user_service.dart';
import '../tool/encryption_util.dart';
import 'dart:async'; // 必须加这个
class UserProvider with ChangeNotifier {
UserModel? _user;
String? _token;
List<String> _sexTags = [];
// --- 成绩数据源相关状态 ---
String _scoreDataSource = 'cn'; // 'cn' or 'sega'
String? _selectedSegaId; // 选中的 SegaID
String _scoreDataSource = 'cn';
String? _selectedSegaId;
String? _selectedCnUserName;
// --- 新增:国服多账号支持 ---
String? _selectedCnUserName; // 选中的国服用户名 (对应 userName2userId 的 key)
// ===================== 【新增:初始化等待控制】 =====================
bool _isInitialized = false;
Completer<void>? _initCompleter;
// 外部等待初始化完成的方法
Future<void> waitInit() async {
if (_isInitialized) return;
if (_initCompleter == null) {
_initCompleter = Completer<void>();
}
await _initCompleter!.future;
}
UserModel? get user => _user;
String? get token => _token;
@@ -30,7 +41,6 @@ class UserProvider with ChangeNotifier {
List<SegaCard> get availableSegaCards => _user?.segaCards ?? [];
// 获取可用的国服账号列表
List<String> get availableCnUserNames {
final map = _user?.userName2userId;
if (map == null || map.isEmpty) return [];
@@ -52,35 +62,38 @@ class UserProvider with ChangeNotifier {
}
Future<void> initUser() async {
final prefs = await SharedPreferences.getInstance();
_token = prefs.getString("token");
try {
final prefs = await SharedPreferences.getInstance();
_token = prefs.getString("token");
// 读取偏好设置
_scoreDataSource = prefs.getString("scoreDataSource") ?? 'cn';
_selectedSegaId = prefs.getString("selectedSegaId");
_selectedCnUserName = prefs.getString("selectedCnUserName");
_scoreDataSource = prefs.getString("scoreDataSource") ?? 'cn';
_selectedSegaId = prefs.getString("selectedSegaId");
_selectedCnUserName = prefs.getString("selectedCnUserName");
if (_token != null) {
try {
_user = await UserService.getUserInfo(_token!);
await fetchSexTags();
if (_token != null) {
try {
_user = await UserService.getUserInfo(_token!);
await fetchSexTags();
// 校验 SegaID 有效性
if (_selectedSegaId != null && !availableSegaCards.any((c) => c.segaId == _selectedSegaId)) {
_selectedSegaId = null;
await prefs.remove("selectedSegaId");
if (_selectedSegaId != null && !availableSegaCards.any((c) => c.segaId == _selectedSegaId)) {
_selectedSegaId = null;
await prefs.remove("selectedSegaId");
}
if (_selectedCnUserName != null && !availableCnUserNames.contains(_selectedCnUserName)) {
_selectedCnUserName = null;
await prefs.remove("selectedCnUserName");
}
} catch (e) {
await logout();
}
// 校验国服用户名有效性
if (_selectedCnUserName != null && !availableCnUserNames.contains(_selectedCnUserName)) {
_selectedCnUserName = null;
await prefs.remove("selectedCnUserName");
}
} catch (e) {
await logout();
}
} finally {
// ===================== 【关键:标记初始化完成】 =====================
_isInitialized = true;
_initCompleter?.complete();
notifyListeners();
}
notifyListeners();
}
Future<void> login(String username, String twoKeyCode) async {
@@ -101,8 +114,6 @@ class UserProvider with ChangeNotifier {
Future<void> register(String username, String password, String inviter) async {
await UserService.register(username, password, inviter);
// 注意:注册后通常不直接登录,或者根据业务需求决定。这里保持原逻辑。
// await login(username, password);
}
Future<void> logout() async {
@@ -166,7 +177,6 @@ class UserProvider with ChangeNotifier {
notifyListeners();
}
// --- 设置数据源 ---
Future<void> setScoreDataSource(String source) async {
_scoreDataSource = source;
final prefs = await SharedPreferences.getInstance();
@@ -174,7 +184,6 @@ class UserProvider with ChangeNotifier {
notifyListeners();
}
// --- 设置选中的 SegaID ---
Future<void> setSelectedSegaId(String? segaId) async {
_selectedSegaId = segaId;
final prefs = await SharedPreferences.getInstance();
@@ -186,7 +195,6 @@ class UserProvider with ChangeNotifier {
notifyListeners();
}
// --- 设置选中的国服用户名 ---
Future<void> setSelectedCnUserName(String? userName) async {
_selectedCnUserName = userName;
final prefs = await SharedPreferences.getInstance();
@@ -225,17 +233,11 @@ class UserProvider with ChangeNotifier {
}
}
// ================= 新增:上传隐写图片 =================
/// 上传带有隐写数据的图片
/// [imageBytes] 原始图片的字节数据 (Uint8List)
/// [segaId] 要隐藏进图片的 SegaID (如果为 null则使用当前选中的 _selectedSegaId)
Future<Map<String, dynamic>> uploadStegImage(Uint8List imageBytes, {String? segaId}) async {
if (_token == null) {
throw Exception("请先登录");
}
// 如果未指定 segaId则使用当前选中的
final targetSegaId = segaId ?? _selectedSegaId;
if (targetSegaId == null || targetSegaId.isEmpty) {