feat(client): 反馈 Bug/功能建议 改为直接提交后台(文字+附图)
- feedback_repository + provider:图片上传 /feedback/images、提交 /feedback - 关于我们的反馈入口改为表单弹窗:多行文字 + 选图上传(缩略图/可删,最多9张), 提交到后台,不再走 mailto - 平台/版本随提交上报(web 安全:defaultTargetPlatform,不引 dart:io) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:package_info_plus/package_info_plus.dart';
|
||||
import '../core/api/api_client.dart';
|
||||
import '../core/exceptions.dart';
|
||||
|
||||
class FeedbackRepository {
|
||||
final ApiClient _client;
|
||||
const FeedbackRepository(this._client);
|
||||
|
||||
/// 上传单张图片,返回服务器相对 URL(/images/feedback/...)。
|
||||
Future<String> uploadImage({
|
||||
Uint8List? bytes,
|
||||
String? filePath,
|
||||
String filename = 'image.jpg',
|
||||
}) async {
|
||||
try {
|
||||
final MultipartFile file;
|
||||
if (bytes != null) {
|
||||
file = MultipartFile.fromBytes(bytes, filename: filename);
|
||||
} else {
|
||||
file = await MultipartFile.fromFile(filePath!);
|
||||
}
|
||||
final formData = FormData.fromMap({'file': file});
|
||||
final resp = await _client.post('/feedback/images', data: formData);
|
||||
return (resp.data as Map<String, dynamic>)['url'] as String;
|
||||
} on DioException catch (e) {
|
||||
throw AppException(
|
||||
e.response?.data?['error'] as String? ?? '图片上传失败',
|
||||
statusCode: e.response?.statusCode,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// 提交反馈(bug / suggestion),文字 + 图片 URL 列表。
|
||||
Future<void> submit({
|
||||
required String type,
|
||||
required String content,
|
||||
required List<String> images,
|
||||
}) async {
|
||||
String appVersion = '';
|
||||
try {
|
||||
appVersion = (await PackageInfo.fromPlatform()).version;
|
||||
} catch (_) {}
|
||||
try {
|
||||
await _client.post('/feedback', data: {
|
||||
'type': type,
|
||||
'content': content,
|
||||
'images': images,
|
||||
'app_version': appVersion,
|
||||
'platform': _platform(),
|
||||
});
|
||||
} on DioException catch (e) {
|
||||
throw AppException(
|
||||
e.response?.data?['error'] as String? ?? '提交失败',
|
||||
statusCode: e.response?.statusCode,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
String _platform() {
|
||||
if (kIsWeb) return 'web';
|
||||
switch (defaultTargetPlatform) {
|
||||
case TargetPlatform.windows:
|
||||
return 'windows';
|
||||
case TargetPlatform.macOS:
|
||||
return 'macos';
|
||||
case TargetPlatform.android:
|
||||
return 'android';
|
||||
case TargetPlatform.iOS:
|
||||
return 'ios';
|
||||
case TargetPlatform.linux:
|
||||
return 'linux';
|
||||
default:
|
||||
return 'unknown';
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user