415 lines
13 KiB
Dart
415 lines
13 KiB
Dart
import 'dart:convert';
|
||
import 'package:flutter/material.dart';
|
||
import 'package:shared_preferences/shared_preferences.dart';
|
||
|
||
class BizAttr {
|
||
final String? mobileRedirectUrl;
|
||
final String? webRedirectUrl;
|
||
|
||
BizAttr({this.mobileRedirectUrl, this.webRedirectUrl});
|
||
|
||
factory BizAttr.fromJson(Map<String, dynamic>? json) {
|
||
if (json == null) return BizAttr();
|
||
return BizAttr(
|
||
mobileRedirectUrl: json['mobileRedirectUrl'] as String?,
|
||
webRedirectUrl: json['webRedirectUrl'] as String?,
|
||
);
|
||
}
|
||
|
||
Map<String, dynamic> toJson() => {
|
||
'mobileRedirectUrl': mobileRedirectUrl,
|
||
'webRedirectUrl': webRedirectUrl,
|
||
};
|
||
}
|
||
|
||
class UserData {
|
||
final String? id;
|
||
final String? userId;
|
||
final String? username;
|
||
final String? name;
|
||
final String? corpinfoId;
|
||
final String? corpinfoName;
|
||
final int? mainCorpFlag;
|
||
final int? userType;
|
||
final String? departmentId;
|
||
final String? departmentName;
|
||
final String? postId;
|
||
final String? postName;
|
||
final String? roleId;
|
||
final String? email;
|
||
final String? personnelType;
|
||
final String? personnelTypeName;
|
||
final String? nation;
|
||
final String? nationName;
|
||
final String? userIdCard;
|
||
final String? userAvatarUrl;
|
||
final String? currentAddress;
|
||
final String? locationAddress;
|
||
final dynamic rankLevel;
|
||
final String? rankLevelName;
|
||
final String? phone;
|
||
final int? sort;
|
||
final int? version;
|
||
final String? createId;
|
||
final String? createName;
|
||
final String? createTime;
|
||
final String? updateId;
|
||
final String? updateName;
|
||
final String? updateTime;
|
||
final String? remarks;
|
||
final String? deleteEnum;
|
||
final String? tenantId;
|
||
final String? orgId;
|
||
final String? env;
|
||
final int? departmentLeaderFlag;
|
||
final int? deputyLeaderFlag;
|
||
final String? culturalLevel;
|
||
final String? culturalLevelName;
|
||
final String? maritalStatus;
|
||
final String? maritalStatusName;
|
||
final String? politicalAffiliation;
|
||
final String? politicalAffiliationName;
|
||
final String? mappingName;
|
||
final String? mappingUserName;
|
||
final String? mappingPostName;
|
||
final String? mappingDeptName;
|
||
final dynamic employmentFlag;
|
||
|
||
UserData({
|
||
this.id,
|
||
this.userId,
|
||
this.username,
|
||
this.name,
|
||
this.corpinfoId,
|
||
this.corpinfoName,
|
||
this.mainCorpFlag,
|
||
this.userType,
|
||
this.departmentId,
|
||
this.departmentName,
|
||
this.postId,
|
||
this.postName,
|
||
this.roleId,
|
||
this.email,
|
||
this.personnelType,
|
||
this.personnelTypeName,
|
||
this.nation,
|
||
this.nationName,
|
||
this.userIdCard,
|
||
this.userAvatarUrl,
|
||
this.currentAddress,
|
||
this.locationAddress,
|
||
this.rankLevel,
|
||
this.rankLevelName,
|
||
this.phone,
|
||
this.sort,
|
||
this.version,
|
||
this.createId,
|
||
this.createName,
|
||
this.createTime,
|
||
this.updateId,
|
||
this.updateName,
|
||
this.updateTime,
|
||
this.remarks,
|
||
this.deleteEnum,
|
||
this.tenantId,
|
||
this.orgId,
|
||
this.env,
|
||
this.departmentLeaderFlag,
|
||
this.deputyLeaderFlag,
|
||
this.culturalLevel,
|
||
this.culturalLevelName,
|
||
this.maritalStatus,
|
||
this.maritalStatusName,
|
||
this.politicalAffiliation,
|
||
this.politicalAffiliationName,
|
||
this.mappingName,
|
||
this.mappingUserName,
|
||
this.mappingPostName,
|
||
this.mappingDeptName,
|
||
this.employmentFlag,
|
||
});
|
||
|
||
factory UserData.fromJson(Map<String, dynamic> json) {
|
||
return UserData(
|
||
id: json['id']?.toString(),
|
||
userId: json['userId']?.toString(),
|
||
username: json['username'] as String?,
|
||
name: json['name'] as String?,
|
||
corpinfoId: json['corpinfoId']?.toString(),
|
||
corpinfoName: json['corpinfoName'] as String?,
|
||
mainCorpFlag: json['mainCorpFlag'] as int?,
|
||
userType: json['userType'] as int?,
|
||
departmentId: json['departmentId']?.toString(),
|
||
departmentName: json['departmentName'] as String?,
|
||
postId: json['postId']?.toString(),
|
||
postName: json['postName'] as String?,
|
||
roleId: json['roleId']?.toString(),
|
||
email: json['email'] as String?,
|
||
personnelType: json['personnelType'] as String?,
|
||
personnelTypeName: json['personnelTypeName'] as String?,
|
||
nation: json['nation'] as String?,
|
||
nationName: json['nationName'] as String?,
|
||
userIdCard: json['userIdCard'] as String?,
|
||
userAvatarUrl: json['userAvatarUrl'] as String?,
|
||
currentAddress: json['currentAddress'] as String?,
|
||
locationAddress: json['locationAddress'] as String?,
|
||
rankLevel: json['rankLevel'],
|
||
rankLevelName: json['rankLevelName'] as String?,
|
||
phone: json['phone'] as String?,
|
||
sort: json['sort'] as int?,
|
||
version: json['version'] as int?,
|
||
createId: json['createId']?.toString(),
|
||
createName: json['createName'] as String?,
|
||
createTime: json['createTime'] as String?,
|
||
updateId: json['updateId']?.toString(),
|
||
updateName: json['updateName'] as String?,
|
||
updateTime: json['updateTime'] as String?,
|
||
remarks: json['remarks'] as String?,
|
||
deleteEnum: json['deleteEnum'] as String?,
|
||
tenantId: json['tenantId']?.toString(),
|
||
orgId: json['orgId']?.toString(),
|
||
env: json['env'] as String?,
|
||
departmentLeaderFlag: json['departmentLeaderFlag'] as int?,
|
||
deputyLeaderFlag: json['deputyLeaderFlag'] as int?,
|
||
culturalLevel: json['culturalLevel'] as String?,
|
||
culturalLevelName: json['culturalLevelName'] as String?,
|
||
maritalStatus: json['maritalStatus'] as String?,
|
||
maritalStatusName: json['maritalStatusName'] as String?,
|
||
politicalAffiliation: json['politicalAffiliation'] as String?,
|
||
politicalAffiliationName: json['politicalAffiliationName'] as String?,
|
||
mappingName: json['mappingName'] as String?,
|
||
mappingUserName: json['mappingUserName'] as String?,
|
||
mappingPostName: json['mappingPostName'] as String?,
|
||
mappingDeptName: json['mappingDeptName'] as String?,
|
||
employmentFlag: json['employmentFlag'],
|
||
);
|
||
}
|
||
|
||
Map<String, dynamic> toJson() {
|
||
return {
|
||
'id': id,
|
||
'userId': userId,
|
||
'username': username,
|
||
'name': name,
|
||
'corpinfoId': corpinfoId,
|
||
'corpinfoName': corpinfoName,
|
||
'mainCorpFlag': mainCorpFlag,
|
||
'userType': userType,
|
||
'departmentId': departmentId,
|
||
'departmentName': departmentName,
|
||
'postId': postId,
|
||
'postName': postName,
|
||
'roleId': roleId,
|
||
'email': email,
|
||
'personnelType': personnelType,
|
||
'personnelTypeName': personnelTypeName,
|
||
'nation': nation,
|
||
'nationName': nationName,
|
||
'userIdCard': userIdCard,
|
||
'userAvatarUrl': userAvatarUrl,
|
||
'currentAddress': currentAddress,
|
||
'locationAddress': locationAddress,
|
||
'rankLevel': rankLevel,
|
||
'rankLevelName': rankLevelName,
|
||
'phone': phone,
|
||
'sort': sort,
|
||
'version': version,
|
||
'createId': createId,
|
||
'createName': createName,
|
||
'createTime': createTime,
|
||
'updateId': updateId,
|
||
'updateName': updateName,
|
||
'updateTime': updateTime,
|
||
'remarks': remarks,
|
||
'deleteEnum': deleteEnum,
|
||
'tenantId': tenantId,
|
||
'orgId': orgId,
|
||
'env': env,
|
||
'departmentLeaderFlag': departmentLeaderFlag,
|
||
'deputyLeaderFlag': deputyLeaderFlag,
|
||
'culturalLevel': culturalLevel,
|
||
'culturalLevelName': culturalLevelName,
|
||
'maritalStatus': maritalStatus,
|
||
'maritalStatusName': maritalStatusName,
|
||
'politicalAffiliation': politicalAffiliation,
|
||
'politicalAffiliationName': politicalAffiliationName,
|
||
'mappingName': mappingName,
|
||
'mappingUserName': mappingUserName,
|
||
'mappingPostName': mappingPostName,
|
||
'mappingDeptName': mappingDeptName,
|
||
'employmentFlag': employmentFlag,
|
||
};
|
||
}
|
||
}
|
||
|
||
class SessionService {
|
||
SessionService._();
|
||
|
||
static final SessionService instance = SessionService._();
|
||
|
||
// 新接口返回的用户数据
|
||
UserData? userData;
|
||
|
||
// 原有的认证相关字段(保留用于兼容性)
|
||
String? token;
|
||
String? accessTicket;
|
||
String? refreshTicket;
|
||
String? expireIn;
|
||
String? refreshExpiresIn;
|
||
|
||
// 自加字段
|
||
String? loginPhone;
|
||
String? loginPass;
|
||
|
||
// 内部:Prefs key
|
||
static const String _prefsKey = 'session_service_v2';
|
||
|
||
// ---------- helpers ----------
|
||
bool get isLoggedIn => token != null && userData?.userId != null && token!.isNotEmpty;
|
||
|
||
// 兼容性getter - 映射到新字段
|
||
String? get userId => userData?.userId;
|
||
String? get accountId => userData?.id;
|
||
String? get name => userData?.name;
|
||
String? get userName => userData?.username;
|
||
String? get phone => userData?.phone;
|
||
String? get email => userData?.email;
|
||
String? get tenantId => userData?.tenantId;
|
||
String? get orgId => userData?.orgId;
|
||
String? get departmentId => userData?.departmentId;
|
||
String? get departmentName => userData?.departmentName;
|
||
String? get roleId => userData?.roleId;
|
||
String? get userTypeEnum => userData?.userType?.toString();
|
||
|
||
/// 如果未登录则跳转登录页
|
||
void loginSession(BuildContext context) {
|
||
if (!isLoggedIn) {
|
||
Navigator.pushReplacementNamed(context, '/login');
|
||
}
|
||
}
|
||
|
||
/// 清空内存并清除本地存储
|
||
Future<void> clear({bool clearPrefs = true}) async {
|
||
userData = null;
|
||
token = null;
|
||
accessTicket = null;
|
||
refreshTicket = null;
|
||
expireIn = null;
|
||
refreshExpiresIn = null;
|
||
loginPhone = null;
|
||
loginPass = null;
|
||
|
||
if (clearPrefs) {
|
||
await clearPrefsData();
|
||
}
|
||
}
|
||
|
||
// ---------- json serialization ----------
|
||
factory SessionService.fromJson(Map<String, dynamic> json) {
|
||
final s = SessionService._();
|
||
|
||
// 解析用户数据
|
||
if (json['userData'] != null) {
|
||
s.userData = UserData.fromJson(json['userData'] as Map<String, dynamic>);
|
||
}
|
||
|
||
// 解析认证字段
|
||
s.token = json['token'] as String?;
|
||
s.accessTicket = json['accessTicket'] as String?;
|
||
s.refreshTicket = json['refreshTicket'] as String?;
|
||
s.expireIn = json['expireIn'] as String?;
|
||
s.refreshExpiresIn = json['refreshExpiresIn'] as String?;
|
||
s.loginPhone = json['loginPhone'] as String?;
|
||
s.loginPass = json['loginPass'] as String?;
|
||
|
||
return s;
|
||
}
|
||
|
||
Map<String, dynamic> toJson() {
|
||
return {
|
||
'userData': userData?.toJson(),
|
||
'token': token,
|
||
'accessTicket': accessTicket,
|
||
'refreshTicket': refreshTicket,
|
||
'expireIn': expireIn,
|
||
'refreshExpiresIn': refreshExpiresIn,
|
||
'loginPhone': loginPhone,
|
||
'loginPass': loginPass,
|
||
};
|
||
}
|
||
|
||
// ---------- update helpers ----------
|
||
|
||
/// 从完整的API响应更新会话数据
|
||
void updateFromApiResponse(Map<String, dynamic> responseJson) {
|
||
if (responseJson['data'] != null) {
|
||
userData = UserData.fromJson(responseJson['data'] as Map<String, dynamic>);
|
||
}
|
||
// 注意:token可能需要从响应头或其他地方单独设置
|
||
}
|
||
|
||
/// 从JSON更新会话数据(兼容旧版本)
|
||
void updateFromJson(Map<String, dynamic> json) {
|
||
final newSession = SessionService.fromJson(json);
|
||
// 将 newSession 的值复制到单例 instance
|
||
final i = SessionService.instance;
|
||
i.userData = newSession.userData;
|
||
i.token = newSession.token;
|
||
i.accessTicket = newSession.accessTicket;
|
||
i.refreshTicket = newSession.refreshTicket;
|
||
i.expireIn = newSession.expireIn;
|
||
i.refreshExpiresIn = newSession.refreshExpiresIn;
|
||
i.loginPhone = newSession.loginPhone;
|
||
i.loginPass = newSession.loginPass;
|
||
}
|
||
|
||
// ---------- persistence ----------
|
||
Future<void> saveToPrefs() async {
|
||
final prefs = await SharedPreferences.getInstance();
|
||
final jsonStr = jsonEncode(toJson());
|
||
await prefs.setString(_prefsKey, jsonStr);
|
||
}
|
||
|
||
Future<bool> loadFromPrefs() async {
|
||
final prefs = await SharedPreferences.getInstance();
|
||
final jsonStr = prefs.getString(_prefsKey);
|
||
if (jsonStr == null || jsonStr.isEmpty) return false;
|
||
try {
|
||
final Map<String, dynamic> map = jsonDecode(jsonStr) as Map<String, dynamic>;
|
||
updateFromJson(map);
|
||
return true;
|
||
} catch (_) {
|
||
return false;
|
||
}
|
||
}
|
||
|
||
Future<void> clearPrefsData() async {
|
||
final prefs = await SharedPreferences.getInstance();
|
||
await prefs.remove(_prefsKey);
|
||
}
|
||
|
||
// ---------- convenience setters ----------
|
||
void setToken(String t) => token = t;
|
||
void setLoginPhone(String phone) => loginPhone = phone;
|
||
void setLoginPass(String pass) => loginPass = pass;
|
||
|
||
// ---------- 打印用户信息(调试用) ----------
|
||
void printUserInfo() {
|
||
if (userData != null) {
|
||
print('用户ID: ${userData!.userId}');
|
||
print('用户名: ${userData!.username}');
|
||
print('姓名: ${userData!.name}');
|
||
print('部门: ${userData!.departmentName}');
|
||
print('租户ID: ${userData!.tenantId}');
|
||
}
|
||
}
|
||
}
|
||
|
||
// ---------- example usage ----------
|
||
// 在登录成功后:
|
||
// SessionService.instance.updateFromApiResponse(responseJson);
|
||
// SessionService.instance.setToken('从响应头获取的token'); // 如果需要
|
||
// await SessionService.instance.saveToPrefs();
|
||
//
|
||
// 程序启动时尝试恢复:
|
||
// await SessionService.instance.loadFromPrefs(); |