chore: release client-v1.0.70
Deploy Client / build-client-web (push) Successful in 38s
Deploy Client / build-macos (push) Successful in 2m10s
Deploy Client / build-android (push) Successful in 56s
Deploy Client / build-ios (push) Successful in 2m35s
Deploy Client / build-windows (push) Successful in 1m49s
Deploy Client / release-deploy-client (push) Successful in 1m23s
Deploy Client / build-client-web (push) Successful in 38s
Deploy Client / build-macos (push) Successful in 2m10s
Deploy Client / build-android (push) Successful in 56s
Deploy Client / build-ios (push) Successful in 2m35s
Deploy Client / build-windows (push) Successful in 1m49s
Deploy Client / release-deploy-client (push) Successful in 1m23s
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YZ4DskSRKsSiheQonFtQvx
This commit is contained in:
@@ -7,6 +7,7 @@ import '../config/app_constants.dart';
|
||||
|
||||
const _kAccessToken = 'access_token';
|
||||
const _kRefreshToken = 'refresh_token';
|
||||
const _kUserId = 'user_id';
|
||||
const _kUsername = 'username';
|
||||
const _kRealName = 'real_name';
|
||||
const _kShopNo = 'shop_no';
|
||||
@@ -16,6 +17,7 @@ const _kRole = 'role';
|
||||
class AuthUser {
|
||||
final String accessToken;
|
||||
final String refreshToken;
|
||||
final int id;
|
||||
final String username;
|
||||
final String realName;
|
||||
final String shopNo;
|
||||
@@ -25,6 +27,7 @@ class AuthUser {
|
||||
const AuthUser({
|
||||
required this.accessToken,
|
||||
required this.refreshToken,
|
||||
this.id = 0,
|
||||
required this.username,
|
||||
required this.realName,
|
||||
required this.shopNo,
|
||||
@@ -74,12 +77,14 @@ class AuthNotifier extends StateNotifier<AuthState> {
|
||||
final shopIdStr = prefs.getString(_kShopId);
|
||||
|
||||
final role = prefs.getString(_kRole);
|
||||
final userId = prefs.getInt(_kUserId) ?? 0;
|
||||
if (accessToken != null && refreshToken != null && username != null) {
|
||||
state = AuthState(
|
||||
initialized: true,
|
||||
user: AuthUser(
|
||||
accessToken: accessToken,
|
||||
refreshToken: refreshToken,
|
||||
id: userId,
|
||||
username: username,
|
||||
realName: realName ?? username,
|
||||
shopNo: shopNo ?? '',
|
||||
@@ -103,6 +108,7 @@ class AuthNotifier extends StateNotifier<AuthState> {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
await prefs.setString(_kAccessToken, user.accessToken);
|
||||
await prefs.setString(_kRefreshToken, user.refreshToken);
|
||||
await prefs.setInt(_kUserId, user.id);
|
||||
await prefs.setString(_kUsername, user.username);
|
||||
await prefs.setString(_kRealName, user.realName);
|
||||
await prefs.setString(_kShopNo, user.shopNo);
|
||||
@@ -134,6 +140,7 @@ class AuthNotifier extends StateNotifier<AuthState> {
|
||||
user: AuthUser(
|
||||
accessToken: newToken,
|
||||
refreshToken: refreshToken,
|
||||
id: state.user!.id,
|
||||
username: state.user!.username,
|
||||
realName: state.user!.realName,
|
||||
shopNo: state.user!.shopNo,
|
||||
@@ -167,6 +174,7 @@ class AuthNotifier extends StateNotifier<AuthState> {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
await prefs.remove(_kAccessToken);
|
||||
await prefs.remove(_kRefreshToken);
|
||||
await prefs.remove(_kUserId);
|
||||
await prefs.remove(_kUsername);
|
||||
await prefs.remove(_kRealName);
|
||||
await prefs.remove(_kShopNo);
|
||||
@@ -195,9 +203,14 @@ final isReadonlyProvider = Provider<bool>((ref) {
|
||||
return role == 'readonly';
|
||||
});
|
||||
|
||||
/// 当前登录用户是否为管理员(role == 'admin')。
|
||||
/// 用于「撤回审核中单据」等仅管理员可用的操作;后端 middleware.AdminOnly() 兜底。
|
||||
/// 当前登录用户是否具备管理员权限(admin 或 superadmin)。
|
||||
/// 与后端 middleware.AdminOnly() 一致(两者皆放行),用于「撤回审核中单据」等操作。
|
||||
final isAdminProvider = Provider<bool>((ref) {
|
||||
final role = ref.watch(authStateProvider.select((s) => s.user?.role));
|
||||
return role == 'admin';
|
||||
return role == 'admin' || role == 'superadmin';
|
||||
});
|
||||
|
||||
/// 当前登录用户 id(未登录为 0)。用于「撤回本人单据」等需要判断单据归属的场景。
|
||||
final currentUserIdProvider = Provider<int>((ref) {
|
||||
return ref.watch(authStateProvider.select((s) => s.user?.id)) ?? 0;
|
||||
});
|
||||
|
||||
@@ -14,6 +14,8 @@ class AppTheme {
|
||||
|
||||
static const Color success = Color(0xFF2E8B57);
|
||||
static const Color danger = Color(0xFFD14343);
|
||||
/// 警示色(amber):用于「撤回」等谨慎但非破坏性的操作,文字在白底对比足够。
|
||||
static const Color warning = Color(0xFFB45309);
|
||||
static const Color background = Color(0xFFF5F7FA);
|
||||
static const Color surface = Color(0xFFFFFFFF);
|
||||
static const Color border = Color(0xFFDCE2EB);
|
||||
|
||||
Reference in New Issue
Block a user