Initial commit
This commit is contained in:
57
lib/providers/auth_provider.dart
Normal file
57
lib/providers/auth_provider.dart
Normal file
@@ -0,0 +1,57 @@
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import '../models/user.dart';
|
||||
import '../services/storage_service.dart';
|
||||
import '../services/api_service.dart';
|
||||
|
||||
class AuthState {
|
||||
final User? user;
|
||||
final bool isLoading;
|
||||
final String? error;
|
||||
|
||||
const AuthState({this.user, this.isLoading = false, this.error});
|
||||
|
||||
bool get isLoggedIn => user != null;
|
||||
|
||||
AuthState copyWith({User? user, bool? isLoading, String? error}) {
|
||||
return AuthState(
|
||||
user: user ?? this.user,
|
||||
isLoading: isLoading ?? this.isLoading,
|
||||
error: error,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class AuthNotifier extends StateNotifier<AuthState> {
|
||||
AuthNotifier() : super(const AuthState()) {
|
||||
_checkLoginStatus();
|
||||
}
|
||||
|
||||
Future<void> _checkLoginStatus() async {
|
||||
await storageService.init();
|
||||
final user = storageService.getUser();
|
||||
if (user != null) {
|
||||
state = state.copyWith(user: user);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> login(String phone, String password) async {
|
||||
state = state.copyWith(isLoading: true, error: null);
|
||||
try {
|
||||
final response = await apiService.login(phone, password);
|
||||
final user = User.fromJson(response['user']);
|
||||
await storageService.saveUser(user);
|
||||
state = state.copyWith(user: user, isLoading: false);
|
||||
} catch (e) {
|
||||
state = state.copyWith(isLoading: false, error: e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> logout() async {
|
||||
await storageService.clearUser();
|
||||
state = const AuthState();
|
||||
}
|
||||
}
|
||||
|
||||
final authProvider = StateNotifierProvider<AuthNotifier, AuthState>((ref) {
|
||||
return AuthNotifier();
|
||||
});
|
||||
89
lib/providers/chat_provider.dart
Normal file
89
lib/providers/chat_provider.dart
Normal file
@@ -0,0 +1,89 @@
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import '../models/message.dart';
|
||||
import '../services/api_service.dart';
|
||||
|
||||
class ChatState {
|
||||
final List<ChatMessage> messages;
|
||||
final bool isLoading;
|
||||
final String? error;
|
||||
|
||||
const ChatState({this.messages = const [], this.isLoading = false, this.error});
|
||||
|
||||
ChatState copyWith({List<ChatMessage>? messages, bool? isLoading, String? error}) {
|
||||
return ChatState(
|
||||
messages: messages ?? this.messages,
|
||||
isLoading: isLoading ?? this.isLoading,
|
||||
error: error,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class ChatNotifier extends StateNotifier<ChatState> {
|
||||
ChatNotifier() : super(const ChatState()) {
|
||||
_loadHistory();
|
||||
}
|
||||
|
||||
Future<void> _loadHistory() async {
|
||||
try {
|
||||
final messages = await apiService.getChatHistory();
|
||||
state = state.copyWith(messages: messages);
|
||||
} catch (_) {}
|
||||
}
|
||||
|
||||
Future<void> sendMessage(String content) async {
|
||||
if (content.trim().isEmpty) return;
|
||||
|
||||
final userMessage = ChatMessage(
|
||||
id: 'msg_user_${DateTime.now().millisecondsSinceEpoch}',
|
||||
content: content.trim(),
|
||||
type: MessageType.text,
|
||||
sender: MessageSender.user,
|
||||
timestamp: DateTime.now(),
|
||||
);
|
||||
|
||||
state = state.copyWith(
|
||||
messages: [...state.messages, userMessage],
|
||||
isLoading: true,
|
||||
);
|
||||
|
||||
final loadingMessage = ChatMessage(
|
||||
id: 'msg_loading_${DateTime.now().millisecondsSinceEpoch}',
|
||||
content: '',
|
||||
type: MessageType.loading,
|
||||
sender: MessageSender.ai,
|
||||
timestamp: DateTime.now(),
|
||||
);
|
||||
|
||||
state = state.copyWith(
|
||||
messages: [...state.messages, loadingMessage],
|
||||
);
|
||||
|
||||
try {
|
||||
final response = await apiService.sendMessage(content);
|
||||
final updatedMessages = [...state.messages];
|
||||
updatedMessages.removeLast();
|
||||
updatedMessages.add(response);
|
||||
state = state.copyWith(messages: updatedMessages, isLoading: false);
|
||||
} catch (e) {
|
||||
final updatedMessages = [...state.messages];
|
||||
updatedMessages.removeLast();
|
||||
updatedMessages.add(ChatMessage(
|
||||
id: 'msg_err_${DateTime.now().millisecondsSinceEpoch}',
|
||||
content: '抱歉,消息发送失败,请稍后重试。',
|
||||
type: MessageType.text,
|
||||
sender: MessageSender.ai,
|
||||
timestamp: DateTime.now(),
|
||||
));
|
||||
state = state.copyWith(messages: updatedMessages, isLoading: false, error: e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
void clearMessages() {
|
||||
state = const ChatState();
|
||||
_loadHistory();
|
||||
}
|
||||
}
|
||||
|
||||
final chatProvider = StateNotifierProvider<ChatNotifier, ChatState>((ref) {
|
||||
return ChatNotifier();
|
||||
});
|
||||
67
lib/providers/event_provider.dart
Normal file
67
lib/providers/event_provider.dart
Normal file
@@ -0,0 +1,67 @@
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import '../models/event.dart';
|
||||
import '../services/api_service.dart';
|
||||
|
||||
class EventState {
|
||||
final List<EventItem> events;
|
||||
final bool isLoading;
|
||||
final String? error;
|
||||
final bool publishSuccess;
|
||||
|
||||
const EventState({
|
||||
this.events = const [],
|
||||
this.isLoading = false,
|
||||
this.error,
|
||||
this.publishSuccess = false,
|
||||
});
|
||||
|
||||
EventState copyWith({
|
||||
List<EventItem>? events,
|
||||
bool? isLoading,
|
||||
String? error,
|
||||
bool? publishSuccess,
|
||||
}) {
|
||||
return EventState(
|
||||
events: events ?? this.events,
|
||||
isLoading: isLoading ?? this.isLoading,
|
||||
error: error,
|
||||
publishSuccess: publishSuccess ?? this.publishSuccess,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class EventNotifier extends StateNotifier<EventState> {
|
||||
EventNotifier() : super(const EventState());
|
||||
|
||||
Future<void> loadEvents() async {
|
||||
state = state.copyWith(isLoading: true, error: null);
|
||||
try {
|
||||
final events = await apiService.getEvents();
|
||||
state = state.copyWith(events: events, isLoading: false);
|
||||
} catch (e) {
|
||||
state = state.copyWith(isLoading: false, error: e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> publishEvent(Map<String, dynamic> data) async {
|
||||
state = state.copyWith(isLoading: true, error: null, publishSuccess: false);
|
||||
try {
|
||||
final event = await apiService.publishEvent(data);
|
||||
state = state.copyWith(
|
||||
events: [event, ...state.events],
|
||||
isLoading: false,
|
||||
publishSuccess: true,
|
||||
);
|
||||
} catch (e) {
|
||||
state = state.copyWith(isLoading: false, error: e.toString(), publishSuccess: false);
|
||||
}
|
||||
}
|
||||
|
||||
void clearPublishSuccess() {
|
||||
state = state.copyWith(publishSuccess: false);
|
||||
}
|
||||
}
|
||||
|
||||
final eventProvider = StateNotifierProvider<EventNotifier, EventState>((ref) {
|
||||
return EventNotifier();
|
||||
});
|
||||
91
lib/providers/order_provider.dart
Normal file
91
lib/providers/order_provider.dart
Normal file
@@ -0,0 +1,91 @@
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import '../models/order.dart';
|
||||
import '../services/api_service.dart';
|
||||
|
||||
class OrderState {
|
||||
final List<OrderItem> orders;
|
||||
final OrderItem? currentOrder;
|
||||
final bool isLoading;
|
||||
final String? error;
|
||||
final bool verifySuccess;
|
||||
|
||||
const OrderState({
|
||||
this.orders = const [],
|
||||
this.currentOrder,
|
||||
this.isLoading = false,
|
||||
this.error,
|
||||
this.verifySuccess = false,
|
||||
});
|
||||
|
||||
OrderState copyWith({
|
||||
List<OrderItem>? orders,
|
||||
OrderItem? currentOrder,
|
||||
bool? isLoading,
|
||||
String? error,
|
||||
bool? verifySuccess,
|
||||
}) {
|
||||
return OrderState(
|
||||
orders: orders ?? this.orders,
|
||||
currentOrder: currentOrder ?? this.currentOrder,
|
||||
isLoading: isLoading ?? this.isLoading,
|
||||
error: error,
|
||||
verifySuccess: verifySuccess ?? this.verifySuccess,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class OrderNotifier extends StateNotifier<OrderState> {
|
||||
OrderNotifier() : super(const OrderState());
|
||||
|
||||
Future<void> loadOrders(OrderStatus status) async {
|
||||
state = state.copyWith(isLoading: true, error: null);
|
||||
try {
|
||||
final orders = await apiService.getOrders(status);
|
||||
state = state.copyWith(orders: orders, isLoading: false);
|
||||
} catch (e) {
|
||||
state = state.copyWith(isLoading: false, error: e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> getDetail(String id) async {
|
||||
state = state.copyWith(isLoading: true, error: null);
|
||||
try {
|
||||
final order = await apiService.getOrderDetail(id);
|
||||
state = state.copyWith(currentOrder: order, isLoading: false);
|
||||
} catch (e) {
|
||||
state = state.copyWith(isLoading: false, error: e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> verifyOrder(String id) async {
|
||||
state = state.copyWith(isLoading: true, error: null, verifySuccess: false);
|
||||
try {
|
||||
final order = await apiService.verifyOrder(id);
|
||||
state = state.copyWith(
|
||||
currentOrder: order,
|
||||
isLoading: false,
|
||||
verifySuccess: true,
|
||||
);
|
||||
} catch (e) {
|
||||
state = state.copyWith(isLoading: false, error: e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> scanVerify(String code) async {
|
||||
state = state.copyWith(isLoading: true, error: null);
|
||||
try {
|
||||
final order = await apiService.scanVerify(code);
|
||||
state = state.copyWith(currentOrder: order, isLoading: false);
|
||||
} catch (e) {
|
||||
state = state.copyWith(isLoading: false, error: e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
void clearVerifySuccess() {
|
||||
state = state.copyWith(verifySuccess: false);
|
||||
}
|
||||
}
|
||||
|
||||
final orderProvider = StateNotifierProvider<OrderNotifier, OrderState>((ref) {
|
||||
return OrderNotifier();
|
||||
});
|
||||
93
lib/providers/settings_provider.dart
Normal file
93
lib/providers/settings_provider.dart
Normal file
@@ -0,0 +1,93 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import '../services/storage_service.dart';
|
||||
|
||||
enum AppThemeMode { light, dark, system }
|
||||
|
||||
class SettingsState {
|
||||
final bool pushNotification;
|
||||
final bool soundNotification;
|
||||
final AppThemeMode themeMode;
|
||||
final Locale locale;
|
||||
|
||||
const SettingsState({
|
||||
this.pushNotification = true,
|
||||
this.soundNotification = true,
|
||||
this.themeMode = AppThemeMode.light,
|
||||
this.locale = const Locale('zh', 'CN'),
|
||||
});
|
||||
|
||||
SettingsState copyWith({
|
||||
bool? pushNotification,
|
||||
bool? soundNotification,
|
||||
AppThemeMode? themeMode,
|
||||
Locale? locale,
|
||||
}) {
|
||||
return SettingsState(
|
||||
pushNotification: pushNotification ?? this.pushNotification,
|
||||
soundNotification: soundNotification ?? this.soundNotification,
|
||||
themeMode: themeMode ?? this.themeMode,
|
||||
locale: locale ?? this.locale,
|
||||
);
|
||||
}
|
||||
|
||||
ThemeMode get flutterThemeMode {
|
||||
switch (themeMode) {
|
||||
case AppThemeMode.light:
|
||||
return ThemeMode.light;
|
||||
case AppThemeMode.dark:
|
||||
return ThemeMode.dark;
|
||||
case AppThemeMode.system:
|
||||
return ThemeMode.system;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class SettingsNotifier extends StateNotifier<SettingsState> {
|
||||
SettingsNotifier() : super(const SettingsState()) {
|
||||
_loadSettings();
|
||||
}
|
||||
|
||||
Future<void> _loadSettings() async {
|
||||
await storageService.init();
|
||||
final push = storageService.getBool('push_notification');
|
||||
final sound = storageService.getBool('sound_notification');
|
||||
final theme = storageService.getString('theme_mode');
|
||||
final lang = storageService.getString('locale');
|
||||
|
||||
state = state.copyWith(
|
||||
pushNotification: push ?? true,
|
||||
soundNotification: sound ?? true,
|
||||
themeMode: theme != null
|
||||
? AppThemeMode.values.byName(theme)
|
||||
: AppThemeMode.light,
|
||||
locale: lang != null
|
||||
? Locale(lang.split('_')[0], lang.split('_')[1])
|
||||
: const Locale('zh', 'CN'),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> setPushNotification(bool value) async {
|
||||
await storageService.setBool('push_notification', value);
|
||||
state = state.copyWith(pushNotification: value);
|
||||
}
|
||||
|
||||
Future<void> setSoundNotification(bool value) async {
|
||||
await storageService.setBool('sound_notification', value);
|
||||
state = state.copyWith(soundNotification: value);
|
||||
}
|
||||
|
||||
Future<void> setThemeMode(AppThemeMode mode) async {
|
||||
await storageService.setString('theme_mode', mode.name);
|
||||
state = state.copyWith(themeMode: mode);
|
||||
}
|
||||
|
||||
Future<void> setLocale(Locale locale) async {
|
||||
await storageService.setString('locale', '${locale.languageCode}_${locale.countryCode}');
|
||||
state = state.copyWith(locale: locale);
|
||||
}
|
||||
}
|
||||
|
||||
final settingsProvider = StateNotifierProvider<SettingsNotifier, SettingsState>((ref) {
|
||||
return SettingsNotifier();
|
||||
});
|
||||
45
lib/providers/work_order_provider.dart
Normal file
45
lib/providers/work_order_provider.dart
Normal file
@@ -0,0 +1,45 @@
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import '../models/work_order.dart';
|
||||
import '../services/api_service.dart';
|
||||
|
||||
class WorkOrderState {
|
||||
final List<WorkOrder> orders;
|
||||
final bool isLoading;
|
||||
final String? error;
|
||||
|
||||
const WorkOrderState({this.orders = const [], this.isLoading = false, this.error});
|
||||
|
||||
WorkOrderState copyWith({List<WorkOrder>? orders, bool? isLoading, String? error}) {
|
||||
return WorkOrderState(
|
||||
orders: orders ?? this.orders,
|
||||
isLoading: isLoading ?? this.isLoading,
|
||||
error: error,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class WorkOrderNotifier extends StateNotifier<WorkOrderState> {
|
||||
WorkOrderNotifier() : super(const WorkOrderState());
|
||||
|
||||
Future<void> loadOrders(WorkOrderStatus status) async {
|
||||
state = state.copyWith(isLoading: true, error: null);
|
||||
try {
|
||||
final orders = await apiService.getWorkOrders(status);
|
||||
state = state.copyWith(orders: orders, isLoading: false);
|
||||
} catch (e) {
|
||||
state = state.copyWith(isLoading: false, error: e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
Future<WorkOrder?> getDetail(String id) async {
|
||||
try {
|
||||
return await apiService.getWorkOrderDetail(id);
|
||||
} catch (_) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final workOrderProvider = StateNotifierProvider<WorkOrderNotifier, WorkOrderState>((ref) {
|
||||
return WorkOrderNotifier();
|
||||
});
|
||||
Reference in New Issue
Block a user