feat(interaction): 支持游客点赞收藏评论

This commit is contained in:
Zhou Weidong committed 2026-10-26 22:33:14 +08:00
1 parent 188811fde6
commit a3d50eb935
18 files changed
+364 -121

No files matched your search

+5 -3
View File
@@ -58,14 +58,16 @@ class LikeToggleResult {
/// 控制器统一返回结果;失败消息可直接展示后端 `message`。
class OperationResult<T> {
const OperationResult._(this.data, this.errorMessage);
const OperationResult._(this.data, this.errorMessage, this.errorCode);
const OperationResult.success([T? data]) : this._(data, null);
const OperationResult.success([T? data]) : this._(data, null, null);
const OperationResult.failure(this.errorMessage) : data = null;
const OperationResult.failure(this.errorMessage, {this.errorCode})
: data = null;
final T? data;
final String? errorMessage;
final int? errorCode;
bool get isSuccess => errorMessage == null;
}
+16 -4
View File
@@ -197,7 +197,10 @@ class CommentController extends ChangeNotifier {
_insertPublished(comment, replyTo);
return OperationResult.success(comment);
} catch (failure) {
return OperationResult.failure(_errorMessage(failure));
return OperationResult.failure(
_errorMessage(failure),
errorCode: failure is ApiException ? failure.code : null,
);
} finally {
submitting = false;
_notify();
@@ -217,7 +220,10 @@ class CommentController extends ChangeNotifier {
return const OperationResult.success();
} catch (failure) {
_restoreComment(comment, location);
return OperationResult.failure(_errorMessage(failure));
return OperationResult.failure(
_errorMessage(failure),
errorCode: failure is ApiException ? failure.code : null,
);
} finally {
_deletingCommentIds.remove(comment.id);
_notify();
@@ -253,7 +259,10 @@ class CommentController extends ChangeNotifier {
return OperationResult.success(result);
} catch (failure) {
_replaceComment(current);
return OperationResult.failure(_errorMessage(failure));
return OperationResult.failure(
_errorMessage(failure),
errorCode: failure is ApiException ? failure.code : null,
);
} finally {
_likingCommentIds.remove(comment.id);
_notify();
@@ -277,7 +286,10 @@ class CommentController extends ChangeNotifier {
);
return OperationResult.success(reportId);
} catch (failure) {
return OperationResult.failure(_errorMessage(failure));
return OperationResult.failure(
_errorMessage(failure),
errorCode: failure is ApiException ? failure.code : null,
);
}
}
@@ -3,6 +3,7 @@
import 'package:flutter/foundation.dart';
import '../models/drama.dart';
import '../remote/api_client.dart';
import '../repositories/favorite_repository.dart';
/// 收藏状态:**以服务端为准**。
@@ -24,6 +25,7 @@ class FavoriteController extends ChangeNotifier {
bool hasMore = false;
String? error;
String? loadMoreError;
int? lastErrorCode;
int _pageIndex = 0;
int _requestSeq = 0;
bool _disposed = false;
@@ -112,11 +114,12 @@ class FavoriteController extends ChangeNotifier {
}
}
/// 未登录时不要调用(服务端要求登录态)。
/// 每次切换都以接口状态为准;匿名请求由设备号归属。
///
/// [card] 是当前剧的卡片(播放页/详情页手上就有):收藏成功时直接放进列表,
/// 这样"收藏完打开我的收藏"能立刻看到,不必等下一次整表刷新。
Future<bool> toggle(String dramaId, {Drama? card}) async {
lastErrorCode = null;
final wasSaved = _saved.contains(dramaId);
final previousCards = cards;
final previousTotal = total;
@@ -157,7 +160,7 @@ class FavoriteController extends ChangeNotifier {
}
notify();
return true;
} catch (_) {
} catch (failure) {
// 回滚
cards = previousCards;
total = previousTotal;
@@ -168,6 +171,7 @@ class FavoriteController extends ChangeNotifier {
_saved.remove(dramaId);
}
notify();
if (failure is ApiException) lastErrorCode = failure.code;
return false;
}
}
@@ -115,7 +115,10 @@ class InteractionController extends ChangeNotifier {
} else {
likedIds.remove(id);
}
return OperationResult.failure(_errorMessage(failure));
return OperationResult.failure(
_errorMessage(failure),
errorCode: failure is ApiException ? failure.code : null,
);
} finally {
busyIds.remove(id);
_notify();
@@ -139,7 +142,10 @@ class InteractionController extends ChangeNotifier {
);
return OperationResult.success(reportId);
} catch (failure) {
return OperationResult.failure(_errorMessage(failure));
return OperationResult.failure(
_errorMessage(failure),
errorCode: failure is ApiException ? failure.code : null,
);
}
}