refactor: 移除前端 Mock API,新增共享组件,优化认证流程

- 删除 mock_api_client、mock_calendar_service、mock_history_service
- 新增 fixed_length_code_input、link_button、message_composer 共享组件
- 优化登录/注册/密码重置页面使用新组件
- 简化 injection.dart 移除 mock 分支
- 更新 env.dart 配置(BACKEND_URL 替换 API_URL)
- 后端 agentscope 工具和测试更新
- 重构 AGENTS.md 文档结构
- 新增 deploy/ 目录和 protocol 文档
This commit is contained in:
qzl
2026-03-12 16:41:45 +08:00
parent d7fbb74bf8
commit 01c36eb32e
70 changed files with 5138 additions and 5829 deletions
-181
View File
@@ -1,181 +0,0 @@
import 'package:dio/dio.dart';
import 'i_api_client.dart';
class MockRequest {
final String path;
final String method;
final dynamic data;
final Options? options;
final Map<String, String>? headers;
MockRequest({
required this.path,
required this.method,
this.data,
this.options,
this.headers,
});
}
typedef MockHandler = dynamic Function(MockRequest request);
class _PatternRoute {
final RegExp pattern;
final String method;
final MockHandler handler;
_PatternRoute({
required this.pattern,
required this.method,
required this.handler,
});
}
class MockApiClient implements IApiClient {
final Map<String, MockHandler> _handlers = {};
final List<_PatternRoute> _patternHandlers = [];
void registerHandler(String path, String method, MockHandler handler) {
final key = '$path:$method';
_handlers[key] = handler;
}
void registerPatternHandler(
RegExp pattern,
String method,
MockHandler handler,
) {
_patternHandlers.add(
_PatternRoute(
pattern: pattern,
method: method.toUpperCase(),
handler: handler,
),
);
}
void clearMocks() {
_handlers.clear();
_patternHandlers.clear();
}
@override
Future<Response<T>> get<T>(String path, {Options? options}) async {
return _handleRequest('GET', path, options: options);
}
@override
Future<Response<T>> post<T>(
String path, {
dynamic data,
Options? options,
}) async {
return _handleRequest('POST', path, data: data, options: options);
}
@override
Future<Response<T>> patch<T>(
String path, {
dynamic data,
Options? options,
}) async {
return _handleRequest('PATCH', path, data: data, options: options);
}
@override
Future<Response<T>> delete<T>(
String path, {
dynamic data,
Options? options,
}) async {
return _handleRequest('DELETE', path, data: data, options: options);
}
@override
Future<Stream<String>> getSseLines(
String path, {
Map<String, String>? headers,
}) async {
final key = '$path:SSE';
final direct = _handlers[key];
if (direct != null) {
final response = direct(
MockRequest(path: path, method: 'SSE', headers: headers),
);
if (response is Stream<String>) {
return response;
}
if (response is Iterable<String>) {
return Stream<String>.fromIterable(response);
}
return const Stream<String>.empty();
}
for (final route in _patternHandlers) {
if (route.method != 'SSE') {
continue;
}
if (!route.pattern.hasMatch(path)) {
continue;
}
final response = route.handler(
MockRequest(path: path, method: 'SSE', headers: headers),
);
if (response is Stream<String>) {
return response;
}
if (response is Iterable<String>) {
return Stream<String>.fromIterable(response);
}
return const Stream<String>.empty();
}
return const Stream<String>.empty();
}
Future<Response<T>> _handleRequest<T>(
String method,
String path, {
dynamic data,
Options? options,
}) async {
await Future.delayed(const Duration(milliseconds: 200));
final handler = _resolveHandler(path: path, method: method);
if (handler != null) {
final response = handler(
MockRequest(path: path, method: method, data: data, options: options),
);
if (response is Response) {
return response as Response<T>;
}
return Response<T>(
data: response as T?,
statusCode: 200,
requestOptions: RequestOptions(path: path),
);
}
return Response<T>(
data: null,
statusCode: 404,
requestOptions: RequestOptions(path: path),
);
}
MockHandler? _resolveHandler({required String path, required String method}) {
final key = '$path:$method';
final direct = _handlers[key];
if (direct != null) {
return direct;
}
for (final route in _patternHandlers) {
if (route.method != method.toUpperCase()) {
continue;
}
if (route.pattern.hasMatch(path)) {
return route.handler;
}
}
return null;
}
}