fix: 管理员系统 + 注册流程重构 + UI改版 + 全链路修复

- 新增管理员角色(手机号12345678910),管理员可增删医生、查看患者
- 注册页重构:去掉角色选择+审核码,改为选医生+填姓名
- 医生端点按DoctorId过滤患者,Patient↔Doctor关系建立
- Doctor/DoctorProfile/User实体新增关联字段
- JSON循环引用修复(IgnoreCycles)
- /api/doctors改为公开接口
- 登录闪屏修复+原生Android启动页
- 输入框全局白底+灰框
- 蓝牙重连同步修复
- Web端(doctor_web+health_app/web)全部删除
- 全局UI改版:白底企业风,新配色和组件系统
- 新品牌图标和启动图
This commit is contained in:
MingNian
2026-06-16 15:16:44 +08:00
parent b635e9d25f
commit c70d5d4be6
103 changed files with 12284 additions and 13049 deletions

View File

@@ -33,17 +33,15 @@ class AuthNotifier extends Notifier<AuthState> {
@override
AuthState build() {
_checkAuth();
return const AuthState(isLoading: true);
return const AuthState(isLoggedIn: false, isLoading: false);
}
Future<void> _checkAuth() async {
final db = ref.read(localDbProvider);
final refresh = await db.read('refresh_token');
if (refresh == null) {
state = const AuthState(isLoggedIn: false, isLoading: false);
return;
}
if (refresh == null) return; // 无token保持 isLoggedIn: false
state = const AuthState(isLoading: true);
try {
final response = await Dio(BaseOptions(baseUrl: baseUrl))
.post('/api/auth/refresh', data: {'refreshToken': refresh});
@@ -65,6 +63,8 @@ class AuthNotifier extends Notifier<AuthState> {
}
Future<void> _loadProfile() async {
// Admin 不查 profile无 User 记录)
if (state.user?.role == 'Admin') return;
try {
final api = ref.read(apiClientProvider);
final response = await api.get('/api/user/profile');
@@ -95,12 +95,11 @@ class AuthNotifier extends Notifier<AuthState> {
}
/// 注册(新用户,需选身份)
Future<String?> register(String phone, String code, String role, {String? inviteCode}) async {
Future<String?> register(String phone, String code, String name, String doctorId) async {
try {
final api = ref.read(apiClientProvider);
final response = await api.post('/api/auth/register', data: {
'phone': phone, 'smsCode': code, 'role': role,
if (inviteCode != null) 'inviteCode': inviteCode,
'phone': phone, 'smsCode': code, 'name': name, 'doctorId': doctorId,
});
final data = response.data['data'];
if (data == null) return response.data['message'] ?? '注册失败';
@@ -108,7 +107,7 @@ class AuthNotifier extends Notifier<AuthState> {
await api.saveTokens(data['accessToken'], data['refreshToken']);
final user = data['user'];
state = AuthState(isLoggedIn: true, isLoading: false,
user: UserInfo(id: user['id'] ?? '', phone: user['phone'] ?? '', role: role),
user: UserInfo(id: user['id'] ?? '', phone: user['phone'] ?? '', role: user['role'] ?? 'User'),
);
return null;
} catch (e) {

View File

@@ -1,6 +1,7 @@
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'auth_provider.dart';
import '../services/health_service.dart';
import '../services/admin_service.dart';
final exerciseServiceProvider = Provider<ExerciseService>((ref) {
return ExerciseService(ref.watch(apiClientProvider));
@@ -31,6 +32,10 @@ final consultationServiceProvider = Provider<ConsultationService>((ref) {
return ConsultationService(ref.watch(apiClientProvider));
});
final adminServiceProvider = Provider<AdminService>((ref) {
return AdminService(ref.watch(apiClientProvider));
});
/// 最新健康数据 Provider
final latestHealthProvider = FutureProvider<Map<String, dynamic>>((ref) async {
final service = ref.watch(healthServiceProvider);