diff --git a/lib/core/utils/message_utils.dart b/lib/core/utils/message_utils.dart index 72131ce..11632dd 100644 --- a/lib/core/utils/message_utils.dart +++ b/lib/core/utils/message_utils.dart @@ -1,18 +1,16 @@ // lib/utils/message_utils.dart -import 'package:palink_v2/data/models/ai_response.dart'; -import 'package:palink_v2/data/models/message_request.dart'; +import 'package:palink_v2/data/models/ai_response/ai_response.dart'; +import 'package:palink_v2/data/models/chat/message_request.dart'; class MessageUtils { // AIResponse 객체를 MessageDto 로 변환 - static MessageRequest convertAIMessageToMessageDto( - AIResponse aiResponse, int conversationId) { + static MessageRequest convertAIMessageToMessageRequest(AIResponse aiResponse) { return MessageRequest( sender: false, messageText: aiResponse.text, timestamp: DateTime.now().toIso8601String(), - conversationId: conversationId, ); } } diff --git a/lib/data/api/auth_api.dart b/lib/data/api/auth/auth_api.dart similarity index 99% rename from lib/data/api/auth_api.dart rename to lib/data/api/auth/auth_api.dart index 2555744..600e05c 100644 --- a/lib/data/api/auth_api.dart +++ b/lib/data/api/auth/auth_api.dart @@ -14,7 +14,6 @@ abstract class AuthApi { @POST("/login") Future login(@Body() UserLoginRequest body); - @POST("/users") Future signUp(@Body() UserCreateRequest body); diff --git a/lib/data/api/auth_api.g.dart b/lib/data/api/auth/auth_api.g.dart similarity index 100% rename from lib/data/api/auth_api.g.dart rename to lib/data/api/auth/auth_api.g.dart diff --git a/lib/data/api/character/character_api.dart b/lib/data/api/character/character_api.dart new file mode 100644 index 0000000..8755e82 --- /dev/null +++ b/lib/data/api/character/character_api.dart @@ -0,0 +1,21 @@ +import 'package:dio/dio.dart'; +import 'package:palink_v2/data/models/character/character_response.dart'; +import 'package:palink_v2/data/models/character/characters_response.dart'; +import 'package:palink_v2/data/models/tip/tip_request.dart'; +import 'package:palink_v2/data/models/tip/tip_response.dart'; +import 'package:retrofit/http.dart'; + +part 'character_api.g.dart'; + + +@RestApi() +abstract class CharacterApi { + factory CharacterApi(Dio dio, {String baseUrl}) = _CharacterApi; + + @GET("/characters") + Future getAllCharacters(); + + @GET("/characters/{character_id}") + Future getCharacterById(@Path("character_id") int characterId); + +} diff --git a/lib/data/api/character/character_api.g.dart b/lib/data/api/character/character_api.g.dart new file mode 100644 index 0000000..011153d --- /dev/null +++ b/lib/data/api/character/character_api.g.dart @@ -0,0 +1,104 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'character_api.dart'; + +// ************************************************************************** +// RetrofitGenerator +// ************************************************************************** + +// ignore_for_file: unnecessary_brace_in_string_interps,no_leading_underscores_for_local_identifiers,unused_element + +class _CharacterApi implements CharacterApi { + _CharacterApi( + this._dio, { + this.baseUrl, + }); + + final Dio _dio; + + String? baseUrl; + + @override + Future getAllCharacters() async { + final _extra = {}; + final queryParameters = {}; + final _headers = {}; + const Map? _data = null; + final _result = await _dio + .fetch>(_setStreamType(Options( + method: 'GET', + headers: _headers, + extra: _extra, + ) + .compose( + _dio.options, + '/characters', + queryParameters: queryParameters, + data: _data, + ) + .copyWith( + baseUrl: _combineBaseUrls( + _dio.options.baseUrl, + baseUrl, + )))); + final _value = CharactersResponse.fromJson(_result.data!); + return _value; + } + + @override + Future getCharacterById(int characterId) async { + final _extra = {}; + final queryParameters = {}; + final _headers = {}; + const Map? _data = null; + final _result = await _dio + .fetch>(_setStreamType(Options( + method: 'GET', + headers: _headers, + extra: _extra, + ) + .compose( + _dio.options, + '/characters/${characterId}', + queryParameters: queryParameters, + data: _data, + ) + .copyWith( + baseUrl: _combineBaseUrls( + _dio.options.baseUrl, + baseUrl, + )))); + final _value = CharacterResponse.fromJson(_result.data!); + return _value; + } + + RequestOptions _setStreamType(RequestOptions requestOptions) { + if (T != dynamic && + !(requestOptions.responseType == ResponseType.bytes || + requestOptions.responseType == ResponseType.stream)) { + if (T == String) { + requestOptions.responseType = ResponseType.plain; + } else { + requestOptions.responseType = ResponseType.json; + } + } + return requestOptions; + } + + String _combineBaseUrls( + String dioBaseUrl, + String? baseUrl, + ) { + if (baseUrl == null || baseUrl.trim().isEmpty) { + return dioBaseUrl; + } + + final url = Uri.parse(baseUrl); + + if (url.isAbsolute) { + return url.toString(); + } + + return Uri.parse(dioBaseUrl).resolveUri(url).toString(); + } +} diff --git a/lib/data/api/chat/chat_api.dart b/lib/data/api/chat/chat_api.dart new file mode 100644 index 0000000..5c26719 --- /dev/null +++ b/lib/data/api/chat/chat_api.dart @@ -0,0 +1,35 @@ +// data/api/chat_api.dart +import 'package:dio/dio.dart'; +import 'package:palink_v2/data/models/chat/conversation_request.dart'; +import 'package:palink_v2/data/models/chat/conversation_response.dart'; +import 'package:palink_v2/data/models/chat/conversations_response.dart'; +import 'package:palink_v2/data/models/chat/message_request.dart'; +import 'package:palink_v2/data/models/chat/message_response.dart'; +import 'package:palink_v2/data/models/chat/messages_response.dart'; +import 'package:retrofit/retrofit.dart'; + +part 'chat_api.g.dart'; + +@RestApi() +abstract class ChatApi { + factory ChatApi(Dio dio, {String baseUrl}) = _ChatApi; + + @POST("/conversations") + Future createConversation(@Body() ConversationRequest conversationRequest); + + @GET("/conversations/{conversation_id}") + Future getConversationById(@Path("conversation_id") int conversationId); + + @GET("/conversations/users/{user_id}") + Future getConversationsByUserId(@Path("user_id") int userId); + + @POST("/conversations/{conversation_id}/messages") + Future saveMessage(@Path("conversation_id") int conversationId, @Body() MessageRequest messageRequest); + + @GET("/conversations/{conversation_id}/messages") + Future getMessagesByChatRoomId(@Path("conversation_id") int conversationId); + + @GET("/conversations/{conversation_id}/messages/{message_id}") + Future getMessageById(@Path("conversation_id") int conversationId, @Path("message_id") int messageId); + +} diff --git a/lib/data/api/chat_api.g.dart b/lib/data/api/chat/chat_api.g.dart similarity index 76% rename from lib/data/api/chat_api.g.dart rename to lib/data/api/chat/chat_api.g.dart index 6400ae0..795346e 100644 --- a/lib/data/api/chat_api.g.dart +++ b/lib/data/api/chat/chat_api.g.dart @@ -34,7 +34,7 @@ class _ChatApi implements ChatApi { ) .compose( _dio.options, - '/api/conversation/create', + '/conversations', queryParameters: queryParameters, data: _data, ) @@ -48,9 +48,9 @@ class _ChatApi implements ChatApi { } @override - Future getConversationById(int chatRoomId) async { + Future getConversationById(int conversationId) async { final _extra = {}; - final queryParameters = {r'conversation_id': chatRoomId}; + final queryParameters = {}; final _headers = {}; const Map? _data = null; final _result = await _dio.fetch>( @@ -61,7 +61,7 @@ class _ChatApi implements ChatApi { ) .compose( _dio.options, - '/api/conversation/get_by_conversation_id', + '/conversations/${conversationId}', queryParameters: queryParameters, data: _data, ) @@ -75,21 +75,20 @@ class _ChatApi implements ChatApi { } @override - Future> getConversationsByUserId( - String userId) async { + Future getConversationsByUserId(int userId) async { final _extra = {}; - final queryParameters = {r'user_id': userId}; + final queryParameters = {}; final _headers = {}; const Map? _data = null; - final _result = await _dio.fetch>( - _setStreamType>(Options( + final _result = await _dio.fetch>( + _setStreamType(Options( method: 'GET', headers: _headers, extra: _extra, ) .compose( _dio.options, - '/api/conversation/get_by_user_id', + '/conversations/users/${userId}', queryParameters: queryParameters, data: _data, ) @@ -98,15 +97,15 @@ class _ChatApi implements ChatApi { _dio.options.baseUrl, baseUrl, )))); - var _value = _result.data! - .map((dynamic i) => - ConversationResponse.fromJson(i as Map)) - .toList(); + final _value = ConversationsResponse.fromJson(_result.data!); return _value; } @override - Future saveMessage(MessageRequest messageRequest) async { + Future saveMessage( + int conversationId, + MessageRequest messageRequest, + ) async { final _extra = {}; final queryParameters = {}; final _headers = {}; @@ -120,7 +119,7 @@ class _ChatApi implements ChatApi { ) .compose( _dio.options, - '/api/message/create', + '/conversations/${conversationId}/messages', queryParameters: queryParameters, data: _data, ) @@ -135,23 +134,20 @@ class _ChatApi implements ChatApi { } @override - Future> getMessagesByChatRoomId( - int conversationId) async { + Future getMessagesByChatRoomId(int conversationId) async { final _extra = {}; - final queryParameters = { - r'conversation_id': conversationId - }; + final queryParameters = {}; final _headers = {}; const Map? _data = null; final _result = await _dio - .fetch>(_setStreamType>(Options( + .fetch?>(_setStreamType(Options( method: 'GET', headers: _headers, extra: _extra, ) .compose( _dio.options, - '/api/message/get_by_conversation_id', + '/conversations/${conversationId}/messages', queryParameters: queryParameters, data: _data, ) @@ -160,29 +156,29 @@ class _ChatApi implements ChatApi { _dio.options.baseUrl, baseUrl, )))); - var _value = _result.data! - .map((dynamic i) => MessageResponse.fromJson(i as Map)) - .toList(); + final _value = + _result.data == null ? null : MessagesResponse.fromJson(_result.data!); return _value; } @override - Future saveLikingLevel( - LikinglevelRequest likinglevelRequest) async { + Future getMessageById( + int conversationId, + int messageId, + ) async { final _extra = {}; final queryParameters = {}; final _headers = {}; - final _data = {}; - _data.addAll(likinglevelRequest.toJson()); - final _result = await _dio.fetch>( - _setStreamType(Options( - method: 'POST', + const Map? _data = null; + final _result = await _dio + .fetch>(_setStreamType(Options( + method: 'GET', headers: _headers, extra: _extra, ) .compose( _dio.options, - '/api/liking/create', + '/conversations/${conversationId}/messages/${messageId}', queryParameters: queryParameters, data: _data, ) @@ -191,7 +187,7 @@ class _ChatApi implements ChatApi { _dio.options.baseUrl, baseUrl, )))); - final _value = LikinglevelResponse.fromJson(_result.data!); + final _value = MessageResponse.fromJson(_result.data!); return _value; } diff --git a/lib/data/api/chat_api.dart b/lib/data/api/chat_api.dart deleted file mode 100644 index e227452..0000000 --- a/lib/data/api/chat_api.dart +++ /dev/null @@ -1,34 +0,0 @@ -// data/api/chat_api.dart -import 'package:dio/dio.dart'; -import 'package:palink_v2/data/models/conversation_request.dart'; -import 'package:palink_v2/data/models/conversation_response.dart'; -import 'package:palink_v2/data/models/likinglevel_request.dart'; -import 'package:palink_v2/data/models/likinglevel_response.dart'; -import 'package:palink_v2/data/models/message_request.dart'; -import 'package:palink_v2/data/models/message_response.dart'; -import 'package:retrofit/retrofit.dart'; - -part 'chat_api.g.dart'; - -@RestApi() -abstract class ChatApi { - factory ChatApi(Dio dio, {String baseUrl}) = _ChatApi; - - @POST("/api/conversation/create") - Future createConversation(@Body() ConversationRequest conversationRequest); - - @GET("/api/conversation/get_by_conversation_id") - Future getConversationById(@Query("conversation_id") int chatRoomId); - - @GET("/api/conversation/get_by_user_id") - Future> getConversationsByUserId(@Query("user_id") String userId); - - @POST("/api/message/create") - Future saveMessage(@Body() MessageRequest messageRequest); - - @GET("/api/message/get_by_conversation_id") - Future> getMessagesByChatRoomId(@Query("conversation_id") int conversationId); - - @POST("/api/liking/create") - Future saveLikingLevel(@Body() LikinglevelRequest likinglevelRequest); -} diff --git a/lib/data/api/emotion/emotion_api.dart b/lib/data/api/emotion/emotion_api.dart new file mode 100644 index 0000000..94a00bb --- /dev/null +++ b/lib/data/api/emotion/emotion_api.dart @@ -0,0 +1,22 @@ +import 'package:dio/dio.dart'; +import 'package:palink_v2/data/models/emotion/emotion_create_request.dart'; +import 'package:palink_v2/data/models/emotion/emotion_response.dart'; +import 'package:retrofit/http.dart'; +part 'emotion_api.g.dart'; + + +@RestApi() +abstract class EmotionApi { + factory EmotionApi(Dio dio, {String baseUrl}) = _EmotionApi; + + + @POST("/emotions") + Future saveEmotion(@Body() EmotionCreateRequest body); + + @GET("/emotion/{emotion_id}") + Future getEmotionById(@Path("emotion_id") int emotionId); + + @GET("/emotions/messages/{message_id}") + Future> getEmotionsByMessageId(@Path("message_id") int messageId); + +} \ No newline at end of file diff --git a/lib/data/api/emotion/emotion_api.g.dart b/lib/data/api/emotion/emotion_api.g.dart new file mode 100644 index 0000000..3b36b3a --- /dev/null +++ b/lib/data/api/emotion/emotion_api.g.dart @@ -0,0 +1,135 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'emotion_api.dart'; + +// ************************************************************************** +// RetrofitGenerator +// ************************************************************************** + +// ignore_for_file: unnecessary_brace_in_string_interps,no_leading_underscores_for_local_identifiers,unused_element + +class _EmotionApi implements EmotionApi { + _EmotionApi( + this._dio, { + this.baseUrl, + }); + + final Dio _dio; + + String? baseUrl; + + @override + Future saveEmotion(EmotionCreateRequest body) async { + final _extra = {}; + final queryParameters = {}; + final _headers = {}; + final _data = {}; + _data.addAll(body.toJson()); + final _result = await _dio + .fetch?>(_setStreamType(Options( + method: 'POST', + headers: _headers, + extra: _extra, + ) + .compose( + _dio.options, + '/emotions', + queryParameters: queryParameters, + data: _data, + ) + .copyWith( + baseUrl: _combineBaseUrls( + _dio.options.baseUrl, + baseUrl, + )))); + final _value = + _result.data == null ? null : EmotionResponse.fromJson(_result.data!); + return _value; + } + + @override + Future getEmotionById(int emotionId) async { + final _extra = {}; + final queryParameters = {}; + final _headers = {}; + const Map? _data = null; + final _result = await _dio + .fetch>(_setStreamType(Options( + method: 'GET', + headers: _headers, + extra: _extra, + ) + .compose( + _dio.options, + '/emotion/${emotionId}', + queryParameters: queryParameters, + data: _data, + ) + .copyWith( + baseUrl: _combineBaseUrls( + _dio.options.baseUrl, + baseUrl, + )))); + final _value = EmotionResponse.fromJson(_result.data!); + return _value; + } + + @override + Future> getEmotionsByMessageId(int messageId) async { + final _extra = {}; + final queryParameters = {}; + final _headers = {}; + const Map? _data = null; + final _result = await _dio + .fetch>(_setStreamType>(Options( + method: 'GET', + headers: _headers, + extra: _extra, + ) + .compose( + _dio.options, + '/emotions/messages/${messageId}', + queryParameters: queryParameters, + data: _data, + ) + .copyWith( + baseUrl: _combineBaseUrls( + _dio.options.baseUrl, + baseUrl, + )))); + var _value = _result.data! + .map((dynamic i) => EmotionResponse.fromJson(i as Map)) + .toList(); + return _value; + } + + RequestOptions _setStreamType(RequestOptions requestOptions) { + if (T != dynamic && + !(requestOptions.responseType == ResponseType.bytes || + requestOptions.responseType == ResponseType.stream)) { + if (T == String) { + requestOptions.responseType = ResponseType.plain; + } else { + requestOptions.responseType = ResponseType.json; + } + } + return requestOptions; + } + + String _combineBaseUrls( + String dioBaseUrl, + String? baseUrl, + ) { + if (baseUrl == null || baseUrl.trim().isEmpty) { + return dioBaseUrl; + } + + final url = Uri.parse(baseUrl); + + if (url.isAbsolute) { + return url.toString(); + } + + return Uri.parse(dioBaseUrl).resolveUri(url).toString(); + } +} diff --git a/lib/data/api/feedback/feedback_api.dart b/lib/data/api/feedback/feedback_api.dart new file mode 100644 index 0000000..da2c156 --- /dev/null +++ b/lib/data/api/feedback/feedback_api.dart @@ -0,0 +1,20 @@ +import 'package:dio/dio.dart'; +import 'package:palink_v2/data/models/feedback/feedback_request.dart'; +import 'package:palink_v2/data/models/feedback/feedback_response.dart'; +import 'package:palink_v2/data/models/feedback/feedbacks_response.dart'; +import 'package:retrofit/http.dart'; + +part 'feedback_api.g.dart'; + + +@RestApi() +abstract class FeedbackApi { + factory FeedbackApi(Dio dio, {String baseUrl}) = _FeedbackApi; + + @POST("/feedbacks") + Future saveFeedback(@Body() FeedbackRequest feedbackRequest); + + @GET("/conversations/{conversation_id}/feedbacks") + Future getFeedbackByConversationId(@Path("conversation_id") int conversationId); + +} diff --git a/lib/data/api/feedback/feedback_api.g.dart b/lib/data/api/feedback/feedback_api.g.dart new file mode 100644 index 0000000..9ed753e --- /dev/null +++ b/lib/data/api/feedback/feedback_api.g.dart @@ -0,0 +1,106 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'feedback_api.dart'; + +// ************************************************************************** +// RetrofitGenerator +// ************************************************************************** + +// ignore_for_file: unnecessary_brace_in_string_interps,no_leading_underscores_for_local_identifiers,unused_element + +class _FeedbackApi implements FeedbackApi { + _FeedbackApi( + this._dio, { + this.baseUrl, + }); + + final Dio _dio; + + String? baseUrl; + + @override + Future saveFeedback(FeedbackRequest feedbackRequest) async { + final _extra = {}; + final queryParameters = {}; + final _headers = {}; + final _data = {}; + _data.addAll(feedbackRequest.toJson()); + final _result = await _dio + .fetch>(_setStreamType(Options( + method: 'POST', + headers: _headers, + extra: _extra, + ) + .compose( + _dio.options, + '/feedbacks', + queryParameters: queryParameters, + data: _data, + ) + .copyWith( + baseUrl: _combineBaseUrls( + _dio.options.baseUrl, + baseUrl, + )))); + final _value = FeedbackResponse.fromJson(_result.data!); + return _value; + } + + @override + Future getFeedbackByConversationId( + int conversationId) async { + final _extra = {}; + final queryParameters = {}; + final _headers = {}; + const Map? _data = null; + final _result = await _dio + .fetch>(_setStreamType(Options( + method: 'GET', + headers: _headers, + extra: _extra, + ) + .compose( + _dio.options, + '/conversations/${conversationId}/feedbacks', + queryParameters: queryParameters, + data: _data, + ) + .copyWith( + baseUrl: _combineBaseUrls( + _dio.options.baseUrl, + baseUrl, + )))); + final _value = FeedbacksResponse.fromJson(_result.data!); + return _value; + } + + RequestOptions _setStreamType(RequestOptions requestOptions) { + if (T != dynamic && + !(requestOptions.responseType == ResponseType.bytes || + requestOptions.responseType == ResponseType.stream)) { + if (T == String) { + requestOptions.responseType = ResponseType.plain; + } else { + requestOptions.responseType = ResponseType.json; + } + } + return requestOptions; + } + + String _combineBaseUrls( + String dioBaseUrl, + String? baseUrl, + ) { + if (baseUrl == null || baseUrl.trim().isEmpty) { + return dioBaseUrl; + } + + final url = Uri.parse(baseUrl); + + if (url.isAbsolute) { + return url.toString(); + } + + return Uri.parse(dioBaseUrl).resolveUri(url).toString(); + } +} diff --git a/lib/data/api/liking/liking_api.dart b/lib/data/api/liking/liking_api.dart new file mode 100644 index 0000000..6e967f3 --- /dev/null +++ b/lib/data/api/liking/liking_api.dart @@ -0,0 +1,22 @@ +import 'package:dio/dio.dart'; +import 'package:palink_v2/data/models/liking/liking_request.dart'; +import 'package:palink_v2/data/models/liking/liking_response.dart'; +import 'package:retrofit/http.dart'; + +part 'liking_api.g.dart'; + + +@RestApi() +abstract class LikingApi { + factory LikingApi(Dio dio, {String baseUrl}) = _LikingApi; + + @POST("/likings") + Future saveLiking(@Body() LikingRequest body); + + @GET("/likings/{liking_id}") + Future getLikingById(@Path("liking_id") int likingId); + + @GET("/likings/messages/{message_id}") + Future> getLikingsByMessageId(@Path("message_id") int messageId); + +} diff --git a/lib/data/api/liking/liking_api.g.dart b/lib/data/api/liking/liking_api.g.dart new file mode 100644 index 0000000..093a9cc --- /dev/null +++ b/lib/data/api/liking/liking_api.g.dart @@ -0,0 +1,134 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'liking_api.dart'; + +// ************************************************************************** +// RetrofitGenerator +// ************************************************************************** + +// ignore_for_file: unnecessary_brace_in_string_interps,no_leading_underscores_for_local_identifiers,unused_element + +class _LikingApi implements LikingApi { + _LikingApi( + this._dio, { + this.baseUrl, + }); + + final Dio _dio; + + String? baseUrl; + + @override + Future saveLiking(LikingRequest body) async { + final _extra = {}; + final queryParameters = {}; + final _headers = {}; + final _data = {}; + _data.addAll(body.toJson()); + final _result = await _dio + .fetch>(_setStreamType(Options( + method: 'POST', + headers: _headers, + extra: _extra, + ) + .compose( + _dio.options, + '/likings', + queryParameters: queryParameters, + data: _data, + ) + .copyWith( + baseUrl: _combineBaseUrls( + _dio.options.baseUrl, + baseUrl, + )))); + final _value = LikingResponse.fromJson(_result.data!); + return _value; + } + + @override + Future getLikingById(int likingId) async { + final _extra = {}; + final queryParameters = {}; + final _headers = {}; + const Map? _data = null; + final _result = await _dio + .fetch>(_setStreamType(Options( + method: 'GET', + headers: _headers, + extra: _extra, + ) + .compose( + _dio.options, + '/likings/${likingId}', + queryParameters: queryParameters, + data: _data, + ) + .copyWith( + baseUrl: _combineBaseUrls( + _dio.options.baseUrl, + baseUrl, + )))); + final _value = LikingResponse.fromJson(_result.data!); + return _value; + } + + @override + Future> getLikingsByMessageId(int messageId) async { + final _extra = {}; + final queryParameters = {}; + final _headers = {}; + const Map? _data = null; + final _result = await _dio + .fetch>(_setStreamType>(Options( + method: 'GET', + headers: _headers, + extra: _extra, + ) + .compose( + _dio.options, + '/likings/messages/${messageId}', + queryParameters: queryParameters, + data: _data, + ) + .copyWith( + baseUrl: _combineBaseUrls( + _dio.options.baseUrl, + baseUrl, + )))); + var _value = _result.data! + .map((dynamic i) => LikingResponse.fromJson(i as Map)) + .toList(); + return _value; + } + + RequestOptions _setStreamType(RequestOptions requestOptions) { + if (T != dynamic && + !(requestOptions.responseType == ResponseType.bytes || + requestOptions.responseType == ResponseType.stream)) { + if (T == String) { + requestOptions.responseType = ResponseType.plain; + } else { + requestOptions.responseType = ResponseType.json; + } + } + return requestOptions; + } + + String _combineBaseUrls( + String dioBaseUrl, + String? baseUrl, + ) { + if (baseUrl == null || baseUrl.trim().isEmpty) { + return dioBaseUrl; + } + + final url = Uri.parse(baseUrl); + + if (url.isAbsolute) { + return url.toString(); + } + + return Uri.parse(dioBaseUrl).resolveUri(url).toString(); + } +} diff --git a/lib/data/api/mindset/mindset_api.dart b/lib/data/api/mindset/mindset_api.dart new file mode 100644 index 0000000..58945e6 --- /dev/null +++ b/lib/data/api/mindset/mindset_api.dart @@ -0,0 +1,19 @@ +import 'package:dio/dio.dart'; +import 'package:palink_v2/data/models/emotion/emotion_create_request.dart'; +import 'package:palink_v2/data/models/emotion/emotion_response.dart'; +import 'package:palink_v2/data/models/mindset/mindset_response.dart'; +import 'package:retrofit/http.dart'; +part 'mindset_api.g.dart'; + + +@RestApi() +abstract class MindsetApi { + factory MindsetApi(Dio dio, {String baseUrl}) = _MindsetApi; + + + @GET("/mindsets/random") + Future getRandomMindset(); + + @GET("/mindsets/{mindset_id}") + Future getMindsetById(@Path("mindset_id") int mindsetId); +} \ No newline at end of file diff --git a/lib/data/api/mindset/mindset_api.g.dart b/lib/data/api/mindset/mindset_api.g.dart new file mode 100644 index 0000000..61d6179 --- /dev/null +++ b/lib/data/api/mindset/mindset_api.g.dart @@ -0,0 +1,105 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'mindset_api.dart'; + +// ************************************************************************** +// RetrofitGenerator +// ************************************************************************** + +// ignore_for_file: unnecessary_brace_in_string_interps,no_leading_underscores_for_local_identifiers,unused_element + +class _MindsetApi implements MindsetApi { + _MindsetApi( + this._dio, { + this.baseUrl, + }); + + final Dio _dio; + + String? baseUrl; + + @override + Future getRandomMindset() async { + final _extra = {}; + final queryParameters = {}; + final _headers = {}; + const Map? _data = null; + final _result = await _dio + .fetch?>(_setStreamType(Options( + method: 'GET', + headers: _headers, + extra: _extra, + ) + .compose( + _dio.options, + '/mindsets/random', + queryParameters: queryParameters, + data: _data, + ) + .copyWith( + baseUrl: _combineBaseUrls( + _dio.options.baseUrl, + baseUrl, + )))); + final _value = + _result.data == null ? null : MindsetResponse.fromJson(_result.data!); + return _value; + } + + @override + Future getMindsetById(int mindsetId) async { + final _extra = {}; + final queryParameters = {}; + final _headers = {}; + const Map? _data = null; + final _result = await _dio + .fetch>(_setStreamType(Options( + method: 'GET', + headers: _headers, + extra: _extra, + ) + .compose( + _dio.options, + '/mindsets/${mindsetId}', + queryParameters: queryParameters, + data: _data, + ) + .copyWith( + baseUrl: _combineBaseUrls( + _dio.options.baseUrl, + baseUrl, + )))); + final _value = MindsetResponse.fromJson(_result.data!); + return _value; + } + + RequestOptions _setStreamType(RequestOptions requestOptions) { + if (T != dynamic && + !(requestOptions.responseType == ResponseType.bytes || + requestOptions.responseType == ResponseType.stream)) { + if (T == String) { + requestOptions.responseType = ResponseType.plain; + } else { + requestOptions.responseType = ResponseType.json; + } + } + return requestOptions; + } + + String _combineBaseUrls( + String dioBaseUrl, + String? baseUrl, + ) { + if (baseUrl == null || baseUrl.trim().isEmpty) { + return dioBaseUrl; + } + + final url = Uri.parse(baseUrl); + + if (url.isAbsolute) { + return url.toString(); + } + + return Uri.parse(dioBaseUrl).resolveUri(url).toString(); + } +} diff --git a/lib/data/api/openai_service.dart b/lib/data/api/openai_service.dart deleted file mode 100644 index 1c43ea7..0000000 --- a/lib/data/api/openai_service.dart +++ /dev/null @@ -1,184 +0,0 @@ -import 'dart:convert'; -import 'package:langchain/langchain.dart'; -import 'package:langchain_openai/langchain_openai.dart'; -import 'package:palink_v2/core/constants/app_url.dart'; -import 'package:palink_v2/core/constants/prompts.dart'; -import 'package:palink_v2/data/models/ai_response.dart'; -import 'package:palink_v2/domain/entities/character/character.dart'; -import 'package:palink_v2/domain/entities/user/user.dart'; - - -class OpenAIService { - String? get apiKey => AppUrl().apiKey; - - final Character character; - late final ChatOpenAI llm; - late final ConversationBufferMemory memory; - late final ConversationBufferMemory tipMemory; - late final ConversationChain chain; - late final LLMChain tip; - late final LLMChain analyze; - late final User user; - - OpenAIService(this.character, this.user) { - _initializeChat(); - } - - final tipPromptTemplate = ChatPromptTemplate.fromTemplate(''' - 당신은 다음 설명에 해당하는 적절한 답변을 해야합니다. - 답변으로 'answer', 'reason' 을 반드시 JSON 객체로 리턴하세요. - 당신의 대화 상대는 AI 캐릭터입니다. 당신은 USER의 입장에서 대답을 해야합니다. - - {input} - '''); - - final promptTemplate = ChatPromptTemplate.fromTemplate(''' - 당신은 USER 를 {userName}으로 부르세요. rejection_score는 누적되어야하고 만약 -5 이하면 is_end를 즉시 1로 설정하세요. - 다음은 당신에 대한 설명입니다. - {description} - 답변으로 'text', 'feeling', 'expected_emotion', 'rejection_score', 'affinity_score', 'is_end'을 반드시 JSON 객체로 리턴하세요. ("```"로 시작하는 문자열을 생성하지 마세요) - - {chat_history} - {userName}: {input} - AI: - '''); - - final analyzeTemplate = ChatPromptTemplate.fromTemplate(''' - 당신은 다음의 거절 점수 표와 대화 기록들을 보고, 사용자의 대화 능력을 평가해야합니다. 거절 점수 표는 캐릭터마다 다릅니다. - 반드시 한국어로 하며, AI 캐릭터의 말투를 사용해서 평가해주세요. - {input} - - 답변으로 'evaluation' (string), 'used_rejection' (string), 'final_rejection_score' (int) 을 반드시 JSON 객체로 리턴하세요. - 'evaluation'은 사용자의 대화 능력을 AI의 입장에서 100자 이내로 평가한 문자열입니다. - 'used_rejection'은 사용자가 대화에서 '사용한 거절 능력(해당 능력의 점수)'의 목록을 나타냅니다. 아이템의 구분은 ',' 로 나타냅니다. - 'final_rejction_score'은 총 거절 점수입니다. - '''); - - - void _initializeChat() { - llm = ChatOpenAI( - apiKey: apiKey, - defaultOptions: const ChatOpenAIOptions( - temperature: 0.8, - model: 'gpt-4-turbo', - maxTokens: 600, - )); - - memory = ConversationBufferMemory( - memoryKey: 'history', - inputKey: 'input', - returnMessages: true, - ); - - tipMemory = ConversationBufferMemory( - memoryKey: 'history', - inputKey: 'input', - returnMessages: true, - ); - - chain = ConversationChain( - memory: memory, - llm: llm, - prompt: promptTemplate, - outputKey: 'response', - inputKey: 'input', // inputKey 설정 - ); - - tip = LLMChain( - prompt: tipPromptTemplate, - llm: llm, - memory: tipMemory, - ); - } - - Future> loadMemory() async { - final variables = await memory.loadMemoryVariables(); - return variables; - } - - Future invokeChain(String userInput) async { - final memoryVariables = await loadMemory(); - final chatHistory = memoryVariables['history'] ?? ''; - - final inputs = { - 'input': userInput, - 'chat_history': chatHistory, - 'userName': user.name, - 'description': character.prompt, - }; - - try { - final result = await chain.invoke(inputs); - print(result); - print(result['response']); - - await memory.saveContext( - inputValues: inputs, - outputValues: {'response': result['response']}, - ); - - final AIChatMessage aiChatMessage = result['response'] as AIChatMessage; - - final Map contentMap = jsonDecode(aiChatMessage.content); - AIResponse aiResponse = AIResponse.fromJson(contentMap); - return aiResponse; - } catch (e) { - print('Failed to invoke chain: $e'); - return null; - } - } - - Future proceedRolePlaying() async { - try { - AIResponse? aiResponse = await invokeChain('당신이 먼저 부탁을 하며 대화를 시작하세요.'); - return aiResponse; - } catch (e) { - print('Error in proceedRolePlaying: $e'); - return null; - } - } - - Future invokeTip(AIResponse aiResponse) async { - final inputs = { - 'input': "${Prompt.tipPrompt}\n${aiResponse.text}", // 단일 input 키로 구성된 텍스트 - }; - - try { - final result = await tip.invoke({'input': inputs}); - final AIChatMessage aiChatMessage = result['output'] as AIChatMessage; - final Map tipMap = jsonDecode(aiChatMessage.content); - return tipMap; - } catch (e) { - print('Failed to invoke tip: $e'); - } - } - - Future invokeAnalyze(String input) async { - analyze = LLMChain( - prompt: analyzeTemplate, - llm: llm, - ); - final inputs = { - 'input': "${character.anaylzePrompt}\n${input}", - }; - try { - final result = await analyze.invoke({'input': inputs}); - - // JSON 문자열이 올바르게 반환되었는지 확인 - AIChatMessage aiChatMessage = result['output'] as AIChatMessage; - String jsonString = aiChatMessage.content; - print(jsonString); - - // JSON 문자열을 디코딩하기 전에 포맷 확인 - if (jsonString.startsWith('```json') && jsonString.endsWith('```')) { - jsonString = jsonString.substring(7, jsonString.length - 3).trim(); - } - - final Map analyzeMap = jsonDecode(jsonString); - return analyzeMap; - } catch (e) { - print('Failed to invoke analyze: $e'); - return null; - } - } -} diff --git a/lib/data/api/rejection/rejection_api.dart b/lib/data/api/rejection/rejection_api.dart new file mode 100644 index 0000000..b887c37 --- /dev/null +++ b/lib/data/api/rejection/rejection_api.dart @@ -0,0 +1,24 @@ +import 'package:dio/dio.dart'; +import 'package:palink_v2/data/models/liking/liking_request.dart'; +import 'package:palink_v2/data/models/liking/liking_response.dart'; +import 'package:palink_v2/data/models/rejection/rejection_request.dart'; +import 'package:palink_v2/data/models/rejection/rejection_response.dart'; +import 'package:retrofit/http.dart'; + +part 'rejection_api.g.dart'; + + +@RestApi() +abstract class RejectionApi { + factory RejectionApi(Dio dio, {String baseUrl}) = _RejectionApi; + + @POST("/rejections") + Future saveRejection(@Body() RejectionRequest body); + + @GET("/rejections/conversations/{conversation_id}") + Future> getRejectionsByConversationId(@Path("conversation_id") int conversationId); + + @GET("/rejections/messages/{message_id}") + Future> getRejectionsByMessageId(@Path("message_id") int messageId); + +} diff --git a/lib/data/api/rejection/rejection_api.g.dart b/lib/data/api/rejection/rejection_api.g.dart new file mode 100644 index 0000000..ea9afd7 --- /dev/null +++ b/lib/data/api/rejection/rejection_api.g.dart @@ -0,0 +1,140 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'rejection_api.dart'; + +// ************************************************************************** +// RetrofitGenerator +// ************************************************************************** + +// ignore_for_file: unnecessary_brace_in_string_interps,no_leading_underscores_for_local_identifiers,unused_element + +class _RejectionApi implements RejectionApi { + _RejectionApi( + this._dio, { + this.baseUrl, + }); + + final Dio _dio; + + String? baseUrl; + + @override + Future saveRejection(RejectionRequest body) async { + final _extra = {}; + final queryParameters = {}; + final _headers = {}; + final _data = {}; + _data.addAll(body.toJson()); + final _result = await _dio + .fetch>(_setStreamType(Options( + method: 'POST', + headers: _headers, + extra: _extra, + ) + .compose( + _dio.options, + '/rejections', + queryParameters: queryParameters, + data: _data, + ) + .copyWith( + baseUrl: _combineBaseUrls( + _dio.options.baseUrl, + baseUrl, + )))); + final _value = RejectionResponse.fromJson(_result.data!); + return _value; + } + + @override + Future> getRejectionsByConversationId( + int conversationId) async { + final _extra = {}; + final queryParameters = {}; + final _headers = {}; + const Map? _data = null; + final _result = await _dio + .fetch>(_setStreamType>(Options( + method: 'GET', + headers: _headers, + extra: _extra, + ) + .compose( + _dio.options, + '/rejections/conversations/${conversationId}', + queryParameters: queryParameters, + data: _data, + ) + .copyWith( + baseUrl: _combineBaseUrls( + _dio.options.baseUrl, + baseUrl, + )))); + var _value = _result.data! + .map((dynamic i) => + RejectionResponse.fromJson(i as Map)) + .toList(); + return _value; + } + + @override + Future> getRejectionsByMessageId( + int messageId) async { + final _extra = {}; + final queryParameters = {}; + final _headers = {}; + const Map? _data = null; + final _result = await _dio + .fetch>(_setStreamType>(Options( + method: 'GET', + headers: _headers, + extra: _extra, + ) + .compose( + _dio.options, + '/rejections/messages/${messageId}', + queryParameters: queryParameters, + data: _data, + ) + .copyWith( + baseUrl: _combineBaseUrls( + _dio.options.baseUrl, + baseUrl, + )))); + var _value = _result.data! + .map((dynamic i) => + RejectionResponse.fromJson(i as Map)) + .toList(); + return _value; + } + + RequestOptions _setStreamType(RequestOptions requestOptions) { + if (T != dynamic && + !(requestOptions.responseType == ResponseType.bytes || + requestOptions.responseType == ResponseType.stream)) { + if (T == String) { + requestOptions.responseType = ResponseType.plain; + } else { + requestOptions.responseType = ResponseType.json; + } + } + return requestOptions; + } + + String _combineBaseUrls( + String dioBaseUrl, + String? baseUrl, + ) { + if (baseUrl == null || baseUrl.trim().isEmpty) { + return dioBaseUrl; + } + + final url = Uri.parse(baseUrl); + + if (url.isAbsolute) { + return url.toString(); + } + + return Uri.parse(dioBaseUrl).resolveUri(url).toString(); + } +} diff --git a/lib/data/api/tip/tip_api.dart b/lib/data/api/tip/tip_api.dart new file mode 100644 index 0000000..cc9b853 --- /dev/null +++ b/lib/data/api/tip/tip_api.dart @@ -0,0 +1,22 @@ +import 'package:dio/dio.dart'; +import 'package:palink_v2/data/models/tip/tip_request.dart'; +import 'package:palink_v2/data/models/tip/tip_response.dart'; +import 'package:retrofit/http.dart'; + +part 'tip_api.g.dart'; + + +@RestApi() +abstract class TipApi { + factory TipApi(Dio dio, {String baseUrl}) = _TipApi; + + @POST("/tips") + Future saveTip(@Body() TipRequest tipRequest); + + @GET("/tips/{tip_id}") + Future getTipById(@Path("tip_id") int tipId); + + @GET("/tips/messages/{message_id}") + Future> getTipsByMessageId(@Path("message_id") int messageId); + +} diff --git a/lib/data/api/tip/tip_api.g.dart b/lib/data/api/tip/tip_api.g.dart new file mode 100644 index 0000000..877f085 --- /dev/null +++ b/lib/data/api/tip/tip_api.g.dart @@ -0,0 +1,134 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'tip_api.dart'; + +// ************************************************************************** +// RetrofitGenerator +// ************************************************************************** + +// ignore_for_file: unnecessary_brace_in_string_interps,no_leading_underscores_for_local_identifiers,unused_element + +class _TipApi implements TipApi { + _TipApi( + this._dio, { + this.baseUrl, + }); + + final Dio _dio; + + String? baseUrl; + + @override + Future saveTip(TipRequest tipRequest) async { + final _extra = {}; + final queryParameters = {}; + final _headers = {}; + final _data = {}; + _data.addAll(tipRequest.toJson()); + final _result = await _dio + .fetch>(_setStreamType(Options( + method: 'POST', + headers: _headers, + extra: _extra, + ) + .compose( + _dio.options, + '/tips', + queryParameters: queryParameters, + data: _data, + ) + .copyWith( + baseUrl: _combineBaseUrls( + _dio.options.baseUrl, + baseUrl, + )))); + final _value = TipResponse.fromJson(_result.data!); + return _value; + } + + @override + Future getTipById(int tipId) async { + final _extra = {}; + final queryParameters = {}; + final _headers = {}; + const Map? _data = null; + final _result = await _dio + .fetch>(_setStreamType(Options( + method: 'GET', + headers: _headers, + extra: _extra, + ) + .compose( + _dio.options, + '/tips/${tipId}', + queryParameters: queryParameters, + data: _data, + ) + .copyWith( + baseUrl: _combineBaseUrls( + _dio.options.baseUrl, + baseUrl, + )))); + final _value = TipResponse.fromJson(_result.data!); + return _value; + } + + @override + Future> getTipsByMessageId(int messageId) async { + final _extra = {}; + final queryParameters = {}; + final _headers = {}; + const Map? _data = null; + final _result = await _dio + .fetch>(_setStreamType>(Options( + method: 'GET', + headers: _headers, + extra: _extra, + ) + .compose( + _dio.options, + '/tips/messages/${messageId}', + queryParameters: queryParameters, + data: _data, + ) + .copyWith( + baseUrl: _combineBaseUrls( + _dio.options.baseUrl, + baseUrl, + )))); + var _value = _result.data! + .map((dynamic i) => TipResponse.fromJson(i as Map)) + .toList(); + return _value; + } + + RequestOptions _setStreamType(RequestOptions requestOptions) { + if (T != dynamic && + !(requestOptions.responseType == ResponseType.bytes || + requestOptions.responseType == ResponseType.stream)) { + if (T == String) { + requestOptions.responseType = ResponseType.plain; + } else { + requestOptions.responseType = ResponseType.json; + } + } + return requestOptions; + } + + String _combineBaseUrls( + String dioBaseUrl, + String? baseUrl, + ) { + if (baseUrl == null || baseUrl.trim().isEmpty) { + return dioBaseUrl; + } + + final url = Uri.parse(baseUrl); + + if (url.isAbsolute) { + return url.toString(); + } + + return Uri.parse(dioBaseUrl).resolveUri(url).toString(); + } +} diff --git a/lib/data/api/tip_api.dart b/lib/data/api/tip_api.dart deleted file mode 100644 index e69de29..0000000 diff --git a/lib/data/api/user/user_api.dart b/lib/data/api/user/user_api.dart new file mode 100644 index 0000000..97a6d4a --- /dev/null +++ b/lib/data/api/user/user_api.dart @@ -0,0 +1,29 @@ +import 'package:dio/dio.dart'; +import 'package:palink_v2/data/models/user/user_collection_request.dart'; +import 'package:palink_v2/data/models/user/user_collection_response.dart'; +import 'package:palink_v2/data/models/user/user_create_request.dart'; +import 'package:palink_v2/data/models/user/user_response.dart'; +import 'package:palink_v2/data/models/user/user_update_request.dart'; +import 'package:retrofit/http.dart'; + +part 'user_api.g.dart'; + +@RestApi() +abstract class UserApi { + factory UserApi(Dio dio, {String baseUrl}) = _UserApi; + + @GET("/users/{user_id}") + Future getUserById(@Path("user_id") int userId); + + @PATCH("/users/{user_id}") + Future updateUserById( + @Path("user_id") int userId, @Body() UserUpdateRequest body); + + @POST("/users/{user_id}/collections") + Future addUserCollection( + @Path("user_id") int userId, @Body() UserCollectionRequest body); + + @GET("/users/{user_id}/collections") + Future> getUserCollections( + @Path("user_id") int userId); +} diff --git a/lib/data/api/user/user_api.g.dart b/lib/data/api/user/user_api.g.dart new file mode 100644 index 0000000..61c9743 --- /dev/null +++ b/lib/data/api/user/user_api.g.dart @@ -0,0 +1,170 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'user_api.dart'; + +// ************************************************************************** +// RetrofitGenerator +// ************************************************************************** + +// ignore_for_file: unnecessary_brace_in_string_interps,no_leading_underscores_for_local_identifiers,unused_element + +class _UserApi implements UserApi { + _UserApi( + this._dio, { + this.baseUrl, + }); + + final Dio _dio; + + String? baseUrl; + + @override + Future getUserById(int userId) async { + final _extra = {}; + final queryParameters = {}; + final _headers = {}; + const Map? _data = null; + final _result = await _dio + .fetch?>(_setStreamType(Options( + method: 'GET', + headers: _headers, + extra: _extra, + ) + .compose( + _dio.options, + '/users/${userId}', + queryParameters: queryParameters, + data: _data, + ) + .copyWith( + baseUrl: _combineBaseUrls( + _dio.options.baseUrl, + baseUrl, + )))); + final _value = + _result.data == null ? null : UserResponse.fromJson(_result.data!); + return _value; + } + + @override + Future updateUserById( + int userId, + UserUpdateRequest body, + ) async { + final _extra = {}; + final queryParameters = {}; + final _headers = {}; + final _data = {}; + _data.addAll(body.toJson()); + final _result = await _dio + .fetch>(_setStreamType(Options( + method: 'PATCH', + headers: _headers, + extra: _extra, + ) + .compose( + _dio.options, + '/users/${userId}', + queryParameters: queryParameters, + data: _data, + ) + .copyWith( + baseUrl: _combineBaseUrls( + _dio.options.baseUrl, + baseUrl, + )))); + final _value = UserResponse.fromJson(_result.data!); + return _value; + } + + @override + Future addUserCollection( + int userId, + UserCollectionRequest body, + ) async { + final _extra = {}; + final queryParameters = {}; + final _headers = {}; + final _data = {}; + _data.addAll(body.toJson()); + final _result = await _dio.fetch>( + _setStreamType(Options( + method: 'POST', + headers: _headers, + extra: _extra, + ) + .compose( + _dio.options, + '/users/${userId}/collections', + queryParameters: queryParameters, + data: _data, + ) + .copyWith( + baseUrl: _combineBaseUrls( + _dio.options.baseUrl, + baseUrl, + )))); + final _value = UserCollectionResponse.fromJson(_result.data!); + return _value; + } + + @override + Future> getUserCollections(int userId) async { + final _extra = {}; + final queryParameters = {}; + final _headers = {}; + const Map? _data = null; + final _result = await _dio.fetch>( + _setStreamType>(Options( + method: 'GET', + headers: _headers, + extra: _extra, + ) + .compose( + _dio.options, + '/users/${userId}/collections', + queryParameters: queryParameters, + data: _data, + ) + .copyWith( + baseUrl: _combineBaseUrls( + _dio.options.baseUrl, + baseUrl, + )))); + var _value = _result.data! + .map((dynamic i) => + UserCollectionResponse.fromJson(i as Map)) + .toList(); + return _value; + } + + RequestOptions _setStreamType(RequestOptions requestOptions) { + if (T != dynamic && + !(requestOptions.responseType == ResponseType.bytes || + requestOptions.responseType == ResponseType.stream)) { + if (T == String) { + requestOptions.responseType = ResponseType.plain; + } else { + requestOptions.responseType = ResponseType.json; + } + } + return requestOptions; + } + + String _combineBaseUrls( + String dioBaseUrl, + String? baseUrl, + ) { + if (baseUrl == null || baseUrl.trim().isEmpty) { + return dioBaseUrl; + } + + final url = Uri.parse(baseUrl); + + if (url.isAbsolute) { + return url.toString(); + } + + return Uri.parse(dioBaseUrl).resolveUri(url).toString(); + } +} diff --git a/lib/data/mapper/ai_response_mapper.dart b/lib/data/mapper/ai_response_mapper.dart new file mode 100644 index 0000000..dd51b64 --- /dev/null +++ b/lib/data/mapper/ai_response_mapper.dart @@ -0,0 +1,13 @@ + +import 'package:palink_v2/data/models/ai_response/ai_response.dart'; +import 'package:palink_v2/data/models/chat/message_request.dart'; + +extension AIResponseMapper on AIResponse { + MessageRequest toMessageRequest() { + return MessageRequest( + sender: false, + messageText: text, + timestamp: DateTime.now().toIso8601String(), + ); + } +} diff --git a/lib/data/mapper/message_response_mapper.dart b/lib/data/mapper/message_response_mapper.dart new file mode 100644 index 0000000..3c1d057 --- /dev/null +++ b/lib/data/mapper/message_response_mapper.dart @@ -0,0 +1,16 @@ +import 'package:palink_v2/data/models/chat/message_response.dart'; +import 'package:palink_v2/domain/entities/chat/message.dart'; + + +extension MessageResponseMapper on MessageResponse { + Message toDomain() { + return Message( + sender: sender, + messageText: messageText, + timestamp: timestamp, + affinityScore: 50, + rejectionScore: 0, + ); + } +} + diff --git a/lib/data/models/ai_response.dart b/lib/data/models/ai_response/ai_response.dart similarity index 100% rename from lib/data/models/ai_response.dart rename to lib/data/models/ai_response/ai_response.dart diff --git a/lib/data/models/ai_response.g.dart b/lib/data/models/ai_response/ai_response.g.dart similarity index 100% rename from lib/data/models/ai_response.g.dart rename to lib/data/models/ai_response/ai_response.g.dart diff --git a/lib/data/models/character/character_response.dart b/lib/data/models/character/character_response.dart new file mode 100644 index 0000000..926a54c --- /dev/null +++ b/lib/data/models/character/character_response.dart @@ -0,0 +1,21 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'character_response.g.dart'; + +@JsonSerializable() +class CharacterResponse { + final String aiName; + final String description; + final int difficultyLevel; + final int characterId; + + CharacterResponse({ + required this.aiName, + required this.description, + required this.difficultyLevel, + required this.characterId, + }); + + factory CharacterResponse.fromJson(Map json) => _$CharacterResponseFromJson(json); + Map toJson() => _$CharacterResponseToJson(this); +} diff --git a/lib/data/models/character/character_response.g.dart b/lib/data/models/character/character_response.g.dart new file mode 100644 index 0000000..ad5b2e9 --- /dev/null +++ b/lib/data/models/character/character_response.g.dart @@ -0,0 +1,23 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'character_response.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +CharacterResponse _$CharacterResponseFromJson(Map json) => + CharacterResponse( + aiName: json['aiName'] as String, + description: json['description'] as String, + difficultyLevel: (json['difficultyLevel'] as num).toInt(), + characterId: (json['characterId'] as num).toInt(), + ); + +Map _$CharacterResponseToJson(CharacterResponse instance) => + { + 'aiName': instance.aiName, + 'description': instance.description, + 'difficultyLevel': instance.difficultyLevel, + 'characterId': instance.characterId, + }; diff --git a/lib/data/models/character/characters_response.dart b/lib/data/models/character/characters_response.dart new file mode 100644 index 0000000..a5e95aa --- /dev/null +++ b/lib/data/models/character/characters_response.dart @@ -0,0 +1,15 @@ +import 'package:json_annotation/json_annotation.dart'; +import 'package:palink_v2/data/models/character/character_response.dart'; + + +part 'characters_response.g.dart'; + +@JsonSerializable() +class CharactersResponse { + final List characters; + + CharactersResponse({required this.characters}); + + factory CharactersResponse.fromJson(Map json) => _$CharactersResponseFromJson(json); + Map toJson() => _$CharactersResponseToJson(this); +} diff --git a/lib/data/models/character/characters_response.g.dart b/lib/data/models/character/characters_response.g.dart new file mode 100644 index 0000000..98068e7 --- /dev/null +++ b/lib/data/models/character/characters_response.g.dart @@ -0,0 +1,19 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'characters_response.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +CharactersResponse _$CharactersResponseFromJson(Map json) => + CharactersResponse( + characters: (json['characters'] as List) + .map((e) => CharacterResponse.fromJson(e as Map)) + .toList(), + ); + +Map _$CharactersResponseToJson(CharactersResponse instance) => + { + 'characters': instance.characters, + }; diff --git a/lib/data/models/conversation_request.dart b/lib/data/models/chat/conversation_request.dart similarity index 85% rename from lib/data/models/conversation_request.dart rename to lib/data/models/chat/conversation_request.dart index 5453803..a2e9758 100644 --- a/lib/data/models/conversation_request.dart +++ b/lib/data/models/chat/conversation_request.dart @@ -5,9 +5,7 @@ part 'conversation_request.g.dart'; @JsonSerializable() class ConversationRequest { final String day; - @JsonKey(name: 'user_id') - final String userId; - @JsonKey(name: 'character_id') + final int userId; final int characterId; ConversationRequest({ diff --git a/lib/data/models/conversation_request.g.dart b/lib/data/models/chat/conversation_request.g.dart similarity index 75% rename from lib/data/models/conversation_request.g.dart rename to lib/data/models/chat/conversation_request.g.dart index 4447153..47ade49 100644 --- a/lib/data/models/conversation_request.g.dart +++ b/lib/data/models/chat/conversation_request.g.dart @@ -9,14 +9,14 @@ part of 'conversation_request.dart'; ConversationRequest _$ConversationRequestFromJson(Map json) => ConversationRequest( day: json['day'] as String, - userId: json['user_id'] as String, - characterId: (json['character_id'] as num).toInt(), + userId: (json['userId'] as num).toInt(), + characterId: (json['characterId'] as num).toInt(), ); Map _$ConversationRequestToJson( ConversationRequest instance) => { 'day': instance.day, - 'user_id': instance.userId, - 'character_id': instance.characterId, + 'userId': instance.userId, + 'characterId': instance.characterId, }; diff --git a/lib/data/models/conversation_response.dart b/lib/data/models/chat/conversation_response.dart similarity index 81% rename from lib/data/models/conversation_response.dart rename to lib/data/models/chat/conversation_response.dart index 9f38407..dda5d58 100644 --- a/lib/data/models/conversation_response.dart +++ b/lib/data/models/chat/conversation_response.dart @@ -4,19 +4,16 @@ part 'conversation_response.g.dart'; @JsonSerializable() class ConversationResponse { - @JsonKey(name: 'conversation_id') - final int conversationId; final String day; - @JsonKey(name: 'user_id') - final String userId; - @JsonKey(name: 'character_id') + final int userId; final int characterId; + final int conversationId; ConversationResponse({ - required this.conversationId, required this.day, required this.userId, required this.characterId, + required this.conversationId, }); factory ConversationResponse.fromJson(Map json) => _$ConversationResponseFromJson(json); diff --git a/lib/data/models/conversation_response.g.dart b/lib/data/models/chat/conversation_response.g.dart similarity index 66% rename from lib/data/models/conversation_response.g.dart rename to lib/data/models/chat/conversation_response.g.dart index c553fe4..56e773e 100644 --- a/lib/data/models/conversation_response.g.dart +++ b/lib/data/models/chat/conversation_response.g.dart @@ -9,17 +9,17 @@ part of 'conversation_response.dart'; ConversationResponse _$ConversationResponseFromJson( Map json) => ConversationResponse( - conversationId: (json['conversation_id'] as num).toInt(), day: json['day'] as String, - userId: json['user_id'] as String, - characterId: (json['character_id'] as num).toInt(), + userId: (json['userId'] as num).toInt(), + characterId: (json['characterId'] as num).toInt(), + conversationId: (json['conversationId'] as num).toInt(), ); Map _$ConversationResponseToJson( ConversationResponse instance) => { - 'conversation_id': instance.conversationId, 'day': instance.day, - 'user_id': instance.userId, - 'character_id': instance.characterId, + 'userId': instance.userId, + 'characterId': instance.characterId, + 'conversationId': instance.conversationId, }; diff --git a/lib/data/models/chat/conversations_response.dart b/lib/data/models/chat/conversations_response.dart new file mode 100644 index 0000000..8b4708f --- /dev/null +++ b/lib/data/models/chat/conversations_response.dart @@ -0,0 +1,15 @@ +import 'package:json_annotation/json_annotation.dart'; +import 'package:palink_v2/data/models/chat/conversation_response.dart'; + + +part 'conversations_response.g.dart'; + +@JsonSerializable() +class ConversationsResponse { + final List conversations; + + ConversationsResponse({required this.conversations}); + + factory ConversationsResponse.fromJson(Map json) => _$ConversationsResponseFromJson(json); + Map toJson() => _$ConversationsResponseToJson(this); +} diff --git a/lib/data/models/chat/conversations_response.g.dart b/lib/data/models/chat/conversations_response.g.dart new file mode 100644 index 0000000..96b848d --- /dev/null +++ b/lib/data/models/chat/conversations_response.g.dart @@ -0,0 +1,21 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'conversations_response.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +ConversationsResponse _$ConversationsResponseFromJson( + Map json) => + ConversationsResponse( + conversations: (json['conversations'] as List) + .map((e) => ConversationResponse.fromJson(e as Map)) + .toList(), + ); + +Map _$ConversationsResponseToJson( + ConversationsResponse instance) => + { + 'conversations': instance.conversations, + }; diff --git a/lib/data/models/message_request.dart b/lib/data/models/chat/message_request.dart similarity index 78% rename from lib/data/models/message_request.dart rename to lib/data/models/chat/message_request.dart index b693735..c384043 100644 --- a/lib/data/models/message_request.dart +++ b/lib/data/models/chat/message_request.dart @@ -5,17 +5,13 @@ part 'message_request.g.dart'; @JsonSerializable() class MessageRequest { final bool sender; - @JsonKey(name: 'message_text') final String messageText; final String timestamp; - @JsonKey(name: 'conversation_id') - final int conversationId; MessageRequest({ required this.sender, required this.messageText, required this.timestamp, - required this.conversationId, }); factory MessageRequest.fromJson(Map json) => _$MessageRequestFromJson(json); diff --git a/lib/data/models/message_request.g.dart b/lib/data/models/chat/message_request.g.dart similarity index 74% rename from lib/data/models/message_request.g.dart rename to lib/data/models/chat/message_request.g.dart index 48c382d..105e345 100644 --- a/lib/data/models/message_request.g.dart +++ b/lib/data/models/chat/message_request.g.dart @@ -9,15 +9,13 @@ part of 'message_request.dart'; MessageRequest _$MessageRequestFromJson(Map json) => MessageRequest( sender: json['sender'] as bool, - messageText: json['message_text'] as String, + messageText: json['messageText'] as String, timestamp: json['timestamp'] as String, - conversationId: (json['conversation_id'] as num).toInt(), ); Map _$MessageRequestToJson(MessageRequest instance) => { 'sender': instance.sender, - 'message_text': instance.messageText, + 'messageText': instance.messageText, 'timestamp': instance.timestamp, - 'conversation_id': instance.conversationId, }; diff --git a/lib/data/models/message_response.dart b/lib/data/models/chat/message_response.dart similarity index 85% rename from lib/data/models/message_response.dart rename to lib/data/models/chat/message_response.dart index d9a6a6c..a2234d0 100644 --- a/lib/data/models/message_response.dart +++ b/lib/data/models/chat/message_response.dart @@ -3,20 +3,17 @@ part 'message_response.g.dart'; @JsonSerializable() class MessageResponse { - @JsonKey(name: 'message_id') - final int messageId; final bool sender; - @JsonKey(name: 'message_text') final String messageText; final String timestamp; - @JsonKey(name: 'conversation_id') + final int messageId; final int conversationId; MessageResponse({ - required this.messageId, required this.sender, required this.messageText, required this.timestamp, + required this.messageId, required this.conversationId, }); diff --git a/lib/data/models/message_response.g.dart b/lib/data/models/chat/message_response.g.dart similarity index 67% rename from lib/data/models/message_response.g.dart rename to lib/data/models/chat/message_response.g.dart index bf06c56..bbc19f5 100644 --- a/lib/data/models/message_response.g.dart +++ b/lib/data/models/chat/message_response.g.dart @@ -8,18 +8,18 @@ part of 'message_response.dart'; MessageResponse _$MessageResponseFromJson(Map json) => MessageResponse( - messageId: (json['message_id'] as num).toInt(), sender: json['sender'] as bool, - messageText: json['message_text'] as String, + messageText: json['messageText'] as String, timestamp: json['timestamp'] as String, - conversationId: (json['conversation_id'] as num).toInt(), + messageId: (json['messageId'] as num).toInt(), + conversationId: (json['conversationId'] as num).toInt(), ); Map _$MessageResponseToJson(MessageResponse instance) => { - 'message_id': instance.messageId, 'sender': instance.sender, - 'message_text': instance.messageText, + 'messageText': instance.messageText, 'timestamp': instance.timestamp, - 'conversation_id': instance.conversationId, + 'messageId': instance.messageId, + 'conversationId': instance.conversationId, }; diff --git a/lib/data/models/chat/messages_response.dart b/lib/data/models/chat/messages_response.dart new file mode 100644 index 0000000..20475e2 --- /dev/null +++ b/lib/data/models/chat/messages_response.dart @@ -0,0 +1,14 @@ +import 'package:json_annotation/json_annotation.dart'; +import 'message_response.dart'; + +part 'messages_response.g.dart'; + +@JsonSerializable() +class MessagesResponse { + final List messages; + + MessagesResponse({required this.messages}); + + factory MessagesResponse.fromJson(Map json) => _$MessagesResponseFromJson(json); + Map toJson() => _$MessagesResponseToJson(this); +} diff --git a/lib/data/models/chat/messages_response.g.dart b/lib/data/models/chat/messages_response.g.dart new file mode 100644 index 0000000..f276950 --- /dev/null +++ b/lib/data/models/chat/messages_response.g.dart @@ -0,0 +1,19 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'messages_response.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +MessagesResponse _$MessagesResponseFromJson(Map json) => + MessagesResponse( + messages: (json['messages'] as List) + .map((e) => MessageResponse.fromJson(e as Map)) + .toList(), + ); + +Map _$MessagesResponseToJson(MessagesResponse instance) => + { + 'messages': instance.messages, + }; diff --git a/lib/data/models/emotion/emotion_create_request.dart b/lib/data/models/emotion/emotion_create_request.dart new file mode 100644 index 0000000..82585c7 --- /dev/null +++ b/lib/data/models/emotion/emotion_create_request.dart @@ -0,0 +1,21 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'emotion_create_request.g.dart'; + +@JsonSerializable() +class EmotionCreateRequest { + final String emotionType; + final int vibrationPattern; + final String backgroundColor; + final int messageId; + + EmotionCreateRequest({ + required this.emotionType, + required this.vibrationPattern, + required this.backgroundColor, + required this.messageId, + }); + + factory EmotionCreateRequest.fromJson(Map json) => _$EmotionCreateRequestFromJson(json); + Map toJson() => _$EmotionCreateRequestToJson(this); +} diff --git a/lib/data/models/emotion/emotion_create_request.g.dart b/lib/data/models/emotion/emotion_create_request.g.dart new file mode 100644 index 0000000..95b12af --- /dev/null +++ b/lib/data/models/emotion/emotion_create_request.g.dart @@ -0,0 +1,25 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'emotion_create_request.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +EmotionCreateRequest _$EmotionCreateRequestFromJson( + Map json) => + EmotionCreateRequest( + emotionType: json['emotionType'] as String, + vibrationPattern: (json['vibrationPattern'] as num).toInt(), + backgroundColor: json['backgroundColor'] as String, + messageId: (json['messageId'] as num).toInt(), + ); + +Map _$EmotionCreateRequestToJson( + EmotionCreateRequest instance) => + { + 'emotionType': instance.emotionType, + 'vibrationPattern': instance.vibrationPattern, + 'backgroundColor': instance.backgroundColor, + 'messageId': instance.messageId, + }; diff --git a/lib/data/models/emotion/emotion_response.dart b/lib/data/models/emotion/emotion_response.dart new file mode 100644 index 0000000..5663097 --- /dev/null +++ b/lib/data/models/emotion/emotion_response.dart @@ -0,0 +1,23 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'emotion_response.g.dart'; + +@JsonSerializable() +class EmotionResponse { + final String emotionType; + final int vibrationPattern; + final String backgroundColor; + final int messageId; + final int emotionId; + + EmotionResponse({ + required this.emotionType, + required this.vibrationPattern, + required this.backgroundColor, + required this.messageId, + required this.emotionId, + }); + + factory EmotionResponse.fromJson(Map json) => _$EmotionResponseFromJson(json); + Map toJson() => _$EmotionResponseToJson(this); +} diff --git a/lib/data/models/emotion/emotion_response.g.dart b/lib/data/models/emotion/emotion_response.g.dart new file mode 100644 index 0000000..d038266 --- /dev/null +++ b/lib/data/models/emotion/emotion_response.g.dart @@ -0,0 +1,25 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'emotion_response.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +EmotionResponse _$EmotionResponseFromJson(Map json) => + EmotionResponse( + emotionType: json['emotionType'] as String, + vibrationPattern: (json['vibrationPattern'] as num).toInt(), + backgroundColor: json['backgroundColor'] as String, + messageId: (json['messageId'] as num).toInt(), + emotionId: (json['emotionId'] as num).toInt(), + ); + +Map _$EmotionResponseToJson(EmotionResponse instance) => + { + 'emotionType': instance.emotionType, + 'vibrationPattern': instance.vibrationPattern, + 'backgroundColor': instance.backgroundColor, + 'messageId': instance.messageId, + 'emotionId': instance.emotionId, + }; diff --git a/lib/data/models/feedback/feedback_request.dart b/lib/data/models/feedback/feedback_request.dart new file mode 100644 index 0000000..22dfb74 --- /dev/null +++ b/lib/data/models/feedback/feedback_request.dart @@ -0,0 +1,21 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'feedback_request.g.dart'; + +@JsonSerializable() +class FeedbackRequest { + final int conversationId; + final String feedbackText; + final int finalLikingLevel; + final int totalRejectionScore; + + FeedbackRequest({ + required this.conversationId, + required this.feedbackText, + required this.finalLikingLevel, + required this.totalRejectionScore, + }); + + factory FeedbackRequest.fromJson(Map json) => _$FeedbackRequestFromJson(json); + Map toJson() => _$FeedbackRequestToJson(this); +} diff --git a/lib/data/models/feedback/feedback_request.g.dart b/lib/data/models/feedback/feedback_request.g.dart new file mode 100644 index 0000000..09b3fc5 --- /dev/null +++ b/lib/data/models/feedback/feedback_request.g.dart @@ -0,0 +1,23 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'feedback_request.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +FeedbackRequest _$FeedbackRequestFromJson(Map json) => + FeedbackRequest( + conversationId: (json['conversationId'] as num).toInt(), + feedbackText: json['feedbackText'] as String, + finalLikingLevel: (json['finalLikingLevel'] as num).toInt(), + totalRejectionScore: (json['totalRejectionScore'] as num).toInt(), + ); + +Map _$FeedbackRequestToJson(FeedbackRequest instance) => + { + 'conversationId': instance.conversationId, + 'feedbackText': instance.feedbackText, + 'finalLikingLevel': instance.finalLikingLevel, + 'totalRejectionScore': instance.totalRejectionScore, + }; diff --git a/lib/data/models/feedback/feedback_response.dart b/lib/data/models/feedback/feedback_response.dart new file mode 100644 index 0000000..b67ea85 --- /dev/null +++ b/lib/data/models/feedback/feedback_response.dart @@ -0,0 +1,23 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'feedback_response.g.dart'; + +@JsonSerializable() +class FeedbackResponse { + final int conversationId; + final String feedbackText; + final int finalLikingLevel; + final int totalRejectionScore; + final int feedbackId; + + FeedbackResponse({ + required this.conversationId, + required this.feedbackText, + required this.finalLikingLevel, + required this.totalRejectionScore, + required this.feedbackId, + }); + + factory FeedbackResponse.fromJson(Map json) => _$FeedbackResponseFromJson(json); + Map toJson() => _$FeedbackResponseToJson(this); +} diff --git a/lib/data/models/feedback/feedback_response.g.dart b/lib/data/models/feedback/feedback_response.g.dart new file mode 100644 index 0000000..a60f153 --- /dev/null +++ b/lib/data/models/feedback/feedback_response.g.dart @@ -0,0 +1,25 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'feedback_response.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +FeedbackResponse _$FeedbackResponseFromJson(Map json) => + FeedbackResponse( + conversationId: (json['conversationId'] as num).toInt(), + feedbackText: json['feedbackText'] as String, + finalLikingLevel: (json['finalLikingLevel'] as num).toInt(), + totalRejectionScore: (json['totalRejectionScore'] as num).toInt(), + feedbackId: (json['feedbackId'] as num).toInt(), + ); + +Map _$FeedbackResponseToJson(FeedbackResponse instance) => + { + 'conversationId': instance.conversationId, + 'feedbackText': instance.feedbackText, + 'finalLikingLevel': instance.finalLikingLevel, + 'totalRejectionScore': instance.totalRejectionScore, + 'feedbackId': instance.feedbackId, + }; diff --git a/lib/data/models/feedback/feedbacks_response.dart b/lib/data/models/feedback/feedbacks_response.dart new file mode 100644 index 0000000..11c9185 --- /dev/null +++ b/lib/data/models/feedback/feedbacks_response.dart @@ -0,0 +1,13 @@ +import 'package:json_annotation/json_annotation.dart'; +import 'package:palink_v2/data/models/feedback/feedback_response.dart'; +part 'feedbacks_response.g.dart'; + +@JsonSerializable() +class FeedbacksResponse { + final List feedbacks; + + FeedbacksResponse({required this.feedbacks}); + + factory FeedbacksResponse.fromJson(Map json) => _$FeedbacksResponseFromJson(json); + Map toJson() => _$FeedbacksResponseToJson(this); +} diff --git a/lib/data/models/feedback/feedbacks_response.g.dart b/lib/data/models/feedback/feedbacks_response.g.dart new file mode 100644 index 0000000..279a540 --- /dev/null +++ b/lib/data/models/feedback/feedbacks_response.g.dart @@ -0,0 +1,19 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'feedbacks_response.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +FeedbacksResponse _$FeedbacksResponseFromJson(Map json) => + FeedbacksResponse( + feedbacks: (json['feedbacks'] as List) + .map((e) => FeedbackResponse.fromJson(e as Map)) + .toList(), + ); + +Map _$FeedbacksResponseToJson(FeedbacksResponse instance) => + { + 'feedbacks': instance.feedbacks, + }; diff --git a/lib/data/models/liking/liking_request.dart b/lib/data/models/liking/liking_request.dart new file mode 100644 index 0000000..3f0f6b0 --- /dev/null +++ b/lib/data/models/liking/liking_request.dart @@ -0,0 +1,21 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'liking_request.g.dart'; + +@JsonSerializable() +class LikingRequest { + final int messageId; + final int likingLevel; + final int conversationId; + final int userId; + + LikingRequest({ + required this.messageId, + required this.likingLevel, + required this.conversationId, + required this.userId, + }); + + factory LikingRequest.fromJson(Map json) => _$LikingRequestFromJson(json); + Map toJson() => _$LikingRequestToJson(this); +} diff --git a/lib/data/models/liking/liking_request.g.dart b/lib/data/models/liking/liking_request.g.dart new file mode 100644 index 0000000..0279f47 --- /dev/null +++ b/lib/data/models/liking/liking_request.g.dart @@ -0,0 +1,23 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'liking_request.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +LikingRequest _$LikingRequestFromJson(Map json) => + LikingRequest( + messageId: (json['messageId'] as num).toInt(), + likingLevel: (json['likingLevel'] as num).toInt(), + conversationId: (json['conversationId'] as num).toInt(), + userId: (json['userId'] as num).toInt(), + ); + +Map _$LikingRequestToJson(LikingRequest instance) => + { + 'messageId': instance.messageId, + 'likingLevel': instance.likingLevel, + 'conversationId': instance.conversationId, + 'userId': instance.userId, + }; diff --git a/lib/data/models/liking/liking_response.dart b/lib/data/models/liking/liking_response.dart new file mode 100644 index 0000000..ae24eb0 --- /dev/null +++ b/lib/data/models/liking/liking_response.dart @@ -0,0 +1,23 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'liking_response.g.dart'; + +@JsonSerializable() +class LikingResponse { + final int messageId; + final int likingLevel; + final int conversationId; + final int userId; + final int likingId; + + LikingResponse({ + required this.messageId, + required this.likingLevel, + required this.conversationId, + required this.userId, + required this.likingId, + }); + + factory LikingResponse.fromJson(Map json) => _$LikingResponseFromJson(json); + Map toJson() => _$LikingResponseToJson(this); +} diff --git a/lib/data/models/liking/liking_response.g.dart b/lib/data/models/liking/liking_response.g.dart new file mode 100644 index 0000000..6025a46 --- /dev/null +++ b/lib/data/models/liking/liking_response.g.dart @@ -0,0 +1,25 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'liking_response.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +LikingResponse _$LikingResponseFromJson(Map json) => + LikingResponse( + messageId: (json['messageId'] as num).toInt(), + likingLevel: (json['likingLevel'] as num).toInt(), + conversationId: (json['conversationId'] as num).toInt(), + userId: (json['userId'] as num).toInt(), + likingId: (json['likingId'] as num).toInt(), + ); + +Map _$LikingResponseToJson(LikingResponse instance) => + { + 'messageId': instance.messageId, + 'likingLevel': instance.likingLevel, + 'conversationId': instance.conversationId, + 'userId': instance.userId, + 'likingId': instance.likingId, + }; diff --git a/lib/data/models/likinglevel_request.dart b/lib/data/models/likinglevel_request.dart deleted file mode 100644 index ff35d72..0000000 --- a/lib/data/models/likinglevel_request.dart +++ /dev/null @@ -1,26 +0,0 @@ -import 'package:json_annotation/json_annotation.dart'; - -part 'likinglevel_request.g.dart'; - -@JsonSerializable() -class LikinglevelRequest { - @JsonKey(name: 'user_id') - final String userId; - @JsonKey(name: 'character_id') - final int characterId; - final int likingLevel; - @JsonKey(name: 'message_id') - final int messageId; - - LikinglevelRequest({ - required this.userId, - required this.characterId, - required this.likingLevel, - required this.messageId, - }); - - factory LikinglevelRequest.fromJson(Map json) => - _$LikinglevelRequestFromJson(json); - - Map toJson() => _$LikinglevelRequestToJson(this); -} diff --git a/lib/data/models/likinglevel_request.g.dart b/lib/data/models/likinglevel_request.g.dart deleted file mode 100644 index b5ca18e..0000000 --- a/lib/data/models/likinglevel_request.g.dart +++ /dev/null @@ -1,23 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'likinglevel_request.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -LikinglevelRequest _$LikinglevelRequestFromJson(Map json) => - LikinglevelRequest( - userId: json['user_id'] as String, - characterId: (json['character_id'] as num).toInt(), - likingLevel: (json['likingLevel'] as num).toInt(), - messageId: (json['message_id'] as num).toInt(), - ); - -Map _$LikinglevelRequestToJson(LikinglevelRequest instance) => - { - 'user_id': instance.userId, - 'character_id': instance.characterId, - 'likingLevel': instance.likingLevel, - 'message_id': instance.messageId, - }; diff --git a/lib/data/models/likinglevel_response.dart b/lib/data/models/likinglevel_response.dart deleted file mode 100644 index 348f920..0000000 --- a/lib/data/models/likinglevel_response.dart +++ /dev/null @@ -1,28 +0,0 @@ -import 'package:json_annotation/json_annotation.dart'; - -part 'likinglevel_response.g.dart'; - -@JsonSerializable() -class LikinglevelResponse { - @JsonKey(name: 'message_id') - final int messageId; - final bool sender; - @JsonKey(name: 'message_text') - final String messageText; - final String timestamp; - @JsonKey(name: 'conversation_id') - final int conversationId; - - LikinglevelResponse({ - required this.messageId, - required this.sender, - required this.messageText, - required this.timestamp, - required this.conversationId, - }); - - factory LikinglevelResponse.fromJson(Map json) => - _$LikinglevelResponseFromJson(json); - - Map toJson() => _$LikinglevelResponseToJson(this); -} diff --git a/lib/data/models/likinglevel_response.g.dart b/lib/data/models/likinglevel_response.g.dart deleted file mode 100644 index dcf24f6..0000000 --- a/lib/data/models/likinglevel_response.g.dart +++ /dev/null @@ -1,26 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'likinglevel_response.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -LikinglevelResponse _$LikinglevelResponseFromJson(Map json) => - LikinglevelResponse( - messageId: (json['message_id'] as num).toInt(), - sender: json['sender'] as bool, - messageText: json['message_text'] as String, - timestamp: json['timestamp'] as String, - conversationId: (json['conversation_id'] as num).toInt(), - ); - -Map _$LikinglevelResponseToJson( - LikinglevelResponse instance) => - { - 'message_id': instance.messageId, - 'sender': instance.sender, - 'message_text': instance.messageText, - 'timestamp': instance.timestamp, - 'conversation_id': instance.conversationId, - }; diff --git a/lib/data/models/mindset/mindset_response.dart b/lib/data/models/mindset/mindset_response.dart new file mode 100644 index 0000000..b2ea176 --- /dev/null +++ b/lib/data/models/mindset/mindset_response.dart @@ -0,0 +1,17 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'mindset_response.g.dart'; + +@JsonSerializable() +class MindsetResponse { + final String mindsetText; + final int mindsetId; + + MindsetResponse({ + required this.mindsetText, + required this.mindsetId, + }); + + factory MindsetResponse.fromJson(Map json) => _$MindsetResponseFromJson(json); + Map toJson() => _$MindsetResponseToJson(this); +} diff --git a/lib/data/models/mindset/mindset_response.g.dart b/lib/data/models/mindset/mindset_response.g.dart new file mode 100644 index 0000000..242a9f5 --- /dev/null +++ b/lib/data/models/mindset/mindset_response.g.dart @@ -0,0 +1,19 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'mindset_response.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +MindsetResponse _$MindsetResponseFromJson(Map json) => + MindsetResponse( + mindsetText: json['mindsetText'] as String, + mindsetId: (json['mindsetId'] as num).toInt(), + ); + +Map _$MindsetResponseToJson(MindsetResponse instance) => + { + 'mindsetText': instance.mindsetText, + 'mindsetId': instance.mindsetId, + }; diff --git a/lib/data/models/rejection/rejection_request.dart b/lib/data/models/rejection/rejection_request.dart new file mode 100644 index 0000000..4bb47b2 --- /dev/null +++ b/lib/data/models/rejection/rejection_request.dart @@ -0,0 +1,23 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'rejection_request.g.dart'; + +@JsonSerializable() +class RejectionRequest { + final int messageId; + final int rejectionLevel; + final int characterId; + final int userId; + final String rejectionText; + + RejectionRequest({ + required this.messageId, + required this.rejectionLevel, + required this.characterId, + required this.userId, + required this.rejectionText, + }); + + factory RejectionRequest.fromJson(Map json) => _$RejectionRequestFromJson(json); + Map toJson() => _$RejectionRequestToJson(this); +} diff --git a/lib/data/models/rejection/rejection_request.g.dart b/lib/data/models/rejection/rejection_request.g.dart new file mode 100644 index 0000000..9f4372d --- /dev/null +++ b/lib/data/models/rejection/rejection_request.g.dart @@ -0,0 +1,25 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'rejection_request.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +RejectionRequest _$RejectionRequestFromJson(Map json) => + RejectionRequest( + messageId: (json['messageId'] as num).toInt(), + rejectionLevel: (json['rejectionLevel'] as num).toInt(), + characterId: (json['characterId'] as num).toInt(), + userId: (json['userId'] as num).toInt(), + rejectionText: json['rejectionText'] as String, + ); + +Map _$RejectionRequestToJson(RejectionRequest instance) => + { + 'messageId': instance.messageId, + 'rejectionLevel': instance.rejectionLevel, + 'characterId': instance.characterId, + 'userId': instance.userId, + 'rejectionText': instance.rejectionText, + }; diff --git a/lib/data/models/rejection/rejection_response.dart b/lib/data/models/rejection/rejection_response.dart new file mode 100644 index 0000000..6fb15cf --- /dev/null +++ b/lib/data/models/rejection/rejection_response.dart @@ -0,0 +1,25 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'rejection_response.g.dart'; + +@JsonSerializable() +class RejectionResponse { + final int messageId; + final int rejectionLevel; + final int characterId; + final int userId; + final String rejectionText; + final int rejectionId; + + RejectionResponse({ + required this.messageId, + required this.rejectionLevel, + required this.characterId, + required this.userId, + required this.rejectionText, + required this.rejectionId, + }); + + factory RejectionResponse.fromJson(Map json) => _$RejectionResponseFromJson(json); + Map toJson() => _$RejectionResponseToJson(this); +} diff --git a/lib/data/models/rejection/rejection_response.g.dart b/lib/data/models/rejection/rejection_response.g.dart new file mode 100644 index 0000000..b35032d --- /dev/null +++ b/lib/data/models/rejection/rejection_response.g.dart @@ -0,0 +1,27 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'rejection_response.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +RejectionResponse _$RejectionResponseFromJson(Map json) => + RejectionResponse( + messageId: (json['messageId'] as num).toInt(), + rejectionLevel: (json['rejectionLevel'] as num).toInt(), + characterId: (json['characterId'] as num).toInt(), + userId: (json['userId'] as num).toInt(), + rejectionText: json['rejectionText'] as String, + rejectionId: (json['rejectionId'] as num).toInt(), + ); + +Map _$RejectionResponseToJson(RejectionResponse instance) => + { + 'messageId': instance.messageId, + 'rejectionLevel': instance.rejectionLevel, + 'characterId': instance.characterId, + 'userId': instance.userId, + 'rejectionText': instance.rejectionText, + 'rejectionId': instance.rejectionId, + }; diff --git a/lib/domain/entities/tip/tip_dto.dart b/lib/data/models/tip/tip_dto.dart similarity index 100% rename from lib/domain/entities/tip/tip_dto.dart rename to lib/data/models/tip/tip_dto.dart diff --git a/lib/domain/entities/tip/tip_dto.g.dart b/lib/data/models/tip/tip_dto.g.dart similarity index 100% rename from lib/domain/entities/tip/tip_dto.g.dart rename to lib/data/models/tip/tip_dto.g.dart diff --git a/lib/data/models/tip/tip_request.dart b/lib/data/models/tip/tip_request.dart index e69de29..ff2988b 100644 --- a/lib/data/models/tip/tip_request.dart +++ b/lib/data/models/tip/tip_request.dart @@ -0,0 +1,17 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'tip_request.g.dart'; + +@JsonSerializable() +class TipRequest { + final int messageId; + final String tipText; + + TipRequest({ + required this.messageId, + required this.tipText, + }); + + factory TipRequest.fromJson(Map json) => _$TipRequestFromJson(json); + Map toJson() => _$TipRequestToJson(this); +} diff --git a/lib/data/models/tip/tip_request.g.dart b/lib/data/models/tip/tip_request.g.dart new file mode 100644 index 0000000..78ceb9c --- /dev/null +++ b/lib/data/models/tip/tip_request.g.dart @@ -0,0 +1,18 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'tip_request.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +TipRequest _$TipRequestFromJson(Map json) => TipRequest( + messageId: (json['messageId'] as num).toInt(), + tipText: json['tipText'] as String, + ); + +Map _$TipRequestToJson(TipRequest instance) => + { + 'messageId': instance.messageId, + 'tipText': instance.tipText, + }; diff --git a/lib/data/models/tip/tip_response.dart b/lib/data/models/tip/tip_response.dart index e69de29..9cf0434 100644 --- a/lib/data/models/tip/tip_response.dart +++ b/lib/data/models/tip/tip_response.dart @@ -0,0 +1,19 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'tip_response.g.dart'; + +@JsonSerializable() +class TipResponse { + final int messageId; + final String tipText; + final int tipId; + + TipResponse({ + required this.messageId, + required this.tipText, + required this.tipId, + }); + + factory TipResponse.fromJson(Map json) => _$TipResponseFromJson(json); + Map toJson() => _$TipResponseToJson(this); +} diff --git a/lib/data/models/tip/tip_response.g.dart b/lib/data/models/tip/tip_response.g.dart new file mode 100644 index 0000000..bc5b906 --- /dev/null +++ b/lib/data/models/tip/tip_response.g.dart @@ -0,0 +1,20 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'tip_response.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +TipResponse _$TipResponseFromJson(Map json) => TipResponse( + messageId: (json['messageId'] as num).toInt(), + tipText: json['tipText'] as String, + tipId: (json['tipId'] as num).toInt(), + ); + +Map _$TipResponseToJson(TipResponse instance) => + { + 'messageId': instance.messageId, + 'tipText': instance.tipText, + 'tipId': instance.tipId, + }; diff --git a/lib/data/models/user/user_collection_request.dart b/lib/data/models/user/user_collection_request.dart new file mode 100644 index 0000000..2480225 --- /dev/null +++ b/lib/data/models/user/user_collection_request.dart @@ -0,0 +1,19 @@ +// data/entities/user_create_request.dart +import 'package:json_annotation/json_annotation.dart'; + +part 'user_collection_request.g.dart'; + +@JsonSerializable() +class UserCollectionRequest { + final int characterId; + final String addedDate; + + UserCollectionRequest({ + required this.characterId, + required this.addedDate, + }); + + factory UserCollectionRequest.fromJson(Map json) => _$UserCollectionRequestFromJson(json); + + Map toJson() => _$UserCollectionRequestToJson(this); +} diff --git a/lib/data/models/user/user_collection_request.g.dart b/lib/data/models/user/user_collection_request.g.dart new file mode 100644 index 0000000..046a851 --- /dev/null +++ b/lib/data/models/user/user_collection_request.g.dart @@ -0,0 +1,21 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'user_collection_request.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +UserCollectionRequest _$UserCollectionRequestFromJson( + Map json) => + UserCollectionRequest( + characterId: (json['characterId'] as num).toInt(), + addedDate: json['addedDate'] as String, + ); + +Map _$UserCollectionRequestToJson( + UserCollectionRequest instance) => + { + 'characterId': instance.characterId, + 'addedDate': instance.addedDate, + }; diff --git a/lib/data/models/user/user_collection_response.dart b/lib/data/models/user/user_collection_response.dart new file mode 100644 index 0000000..f7aa5ac --- /dev/null +++ b/lib/data/models/user/user_collection_response.dart @@ -0,0 +1,21 @@ +// data/entities/user_response.dart +import 'package:json_annotation/json_annotation.dart'; + +part 'user_collection_response.g.dart'; + +@JsonSerializable() +class UserCollectionResponse { + final int characterId; + final String addedDate; + final int userId; + + UserCollectionResponse({ + required this.characterId, + required this.addedDate, + required this.userId, + }); + + factory UserCollectionResponse.fromJson(Map json) => _$UserCollectionResponseFromJson(json); + + Map toJson() => _$UserCollectionResponseToJson(this); +} diff --git a/lib/data/models/user/user_collection_response.g.dart b/lib/data/models/user/user_collection_response.g.dart new file mode 100644 index 0000000..594c5a2 --- /dev/null +++ b/lib/data/models/user/user_collection_response.g.dart @@ -0,0 +1,23 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'user_collection_response.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +UserCollectionResponse _$UserCollectionResponseFromJson( + Map json) => + UserCollectionResponse( + characterId: (json['characterId'] as num).toInt(), + addedDate: json['addedDate'] as String, + userId: (json['userId'] as num).toInt(), + ); + +Map _$UserCollectionResponseToJson( + UserCollectionResponse instance) => + { + 'characterId': instance.characterId, + 'addedDate': instance.addedDate, + 'userId': instance.userId, + }; diff --git a/lib/data/models/user/user_update_request.dart b/lib/data/models/user/user_update_request.dart new file mode 100644 index 0000000..b336f31 --- /dev/null +++ b/lib/data/models/user/user_update_request.dart @@ -0,0 +1,23 @@ +// data/entities/user_create_request.dart +import 'package:json_annotation/json_annotation.dart'; + +part 'user_update_request.g.dart'; + +@JsonSerializable() +class UserUpdateRequest { + final String name; + final String password; + final int age; + final String personalityType; + + UserUpdateRequest({ + required this.name, + required this.password, + required this.age, + required this.personalityType, + }); + + factory UserUpdateRequest.fromJson(Map json) => _$UserUpdateRequestFromJson(json); + + Map toJson() => _$UserUpdateRequestToJson(this); +} diff --git a/lib/data/models/user/user_update_request.g.dart b/lib/data/models/user/user_update_request.g.dart new file mode 100644 index 0000000..eccaef5 --- /dev/null +++ b/lib/data/models/user/user_update_request.g.dart @@ -0,0 +1,23 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'user_update_request.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +UserUpdateRequest _$UserUpdateRequestFromJson(Map json) => + UserUpdateRequest( + name: json['name'] as String, + password: json['password'] as String, + age: (json['age'] as num).toInt(), + personalityType: json['personalityType'] as String, + ); + +Map _$UserUpdateRequestToJson(UserUpdateRequest instance) => + { + 'name': instance.name, + 'password': instance.password, + 'age': instance.age, + 'personalityType': instance.personalityType, + }; diff --git a/lib/data/repository/auth_repositoryImpl.dart b/lib/data/repository/auth_repositoryImpl.dart index 30dce9b..a1f4898 100644 --- a/lib/data/repository/auth_repositoryImpl.dart +++ b/lib/data/repository/auth_repositoryImpl.dart @@ -1,5 +1,6 @@ -import 'package:palink_v2/data/api/auth_api.dart'; +import 'package:palink_v2/data/api/auth/auth_api.dart'; +import 'package:palink_v2/data/api/user/user_api.dart'; import 'package:palink_v2/data/mapper/login_mapper.dart'; import 'package:palink_v2/data/mapper/signup_mapper.dart'; import 'package:palink_v2/data/mapper/user_mapper.dart'; @@ -14,8 +15,10 @@ import '../../domain/repository/auth_repository.dart'; class AuthRepositoryImpl implements AuthRepository { final AuthApi _authApi; + final UserApi _userApi; final SharedPreferences _prefs; - AuthRepositoryImpl(this._authApi, this._prefs); + + AuthRepositoryImpl(this._authApi, this._userApi, this._prefs); @override @@ -23,11 +26,9 @@ class AuthRepositoryImpl implements AuthRepository { try { final response = await _authApi.login(loginModel.toData()); if (response != null) { - // SharedPreferences에 사용자 정보 저장 - await _prefs.setString('accountId', response.accountId); - await _prefs.setString('name', response.name); - await _prefs.setInt('age', response.age); - await _prefs.setString('personalityType', response.personalityType); + // SharedPreferences에 userId 와 로그인 여부 저장 + await _prefs.setInt('userId', response.userId); + await _prefs.setBool('isLoggedIn', true); return response.toDomain(); } @@ -48,4 +49,27 @@ class AuthRepositoryImpl implements AuthRepository { return null; } } + + @override + Future getUserFromPreferences() async { + try { + final userId = _prefs.getInt('userId'); + final isLoggedIn = _prefs.getBool('isLoggedIn') ?? false; + + if (isLoggedIn && userId != null) { + final userResponse = await _userApi.getUserById(userId); + return userResponse?.toDomain(); + } + return null; + } catch (e) { + print('Error in getUserFromPreferences: $e'); + return null; + } + } + + Future logout() async { + await _prefs.remove('userId'); + await _prefs.remove('isLoggedIn'); + } + } \ No newline at end of file diff --git a/lib/data/repository/chat_repositoryImpl.dart b/lib/data/repository/chat_repositoryImpl.dart index f5116c5..bab1e35 100644 --- a/lib/data/repository/chat_repositoryImpl.dart +++ b/lib/data/repository/chat_repositoryImpl.dart @@ -1,15 +1,15 @@ // data/repositories/chat_repository_impl.dart import 'package:palink_v2/core/utils/message_utils.dart'; -import 'package:palink_v2/data/api/chat_api.dart'; -import 'package:palink_v2/data/models/ai_response.dart'; -import 'package:palink_v2/data/models/conversation_request.dart'; -import 'package:palink_v2/data/models/conversation_response.dart'; -import 'package:palink_v2/data/models/likinglevel_request.dart'; -import 'package:palink_v2/data/models/likinglevel_response.dart'; -import 'package:palink_v2/data/models/message_request.dart'; -import 'package:palink_v2/data/models/message_response.dart'; +import 'package:palink_v2/data/api/chat/chat_api.dart'; +import 'package:palink_v2/data/models/ai_response/ai_response.dart'; +import 'package:palink_v2/data/models/chat/conversation_request.dart'; +import 'package:palink_v2/data/models/chat/conversation_response.dart'; +import 'package:palink_v2/data/models/chat/message_request.dart'; +import 'package:palink_v2/data/models/chat/message_response.dart'; +import 'package:palink_v2/data/models/chat/messages_response.dart'; import 'package:palink_v2/domain/repository/chat_repository.dart'; +// ChatRepositoryImpl.dart class ChatRepositoryImpl implements ChatRepository { final ChatApi chatApi; @@ -22,23 +22,18 @@ class ChatRepositoryImpl implements ChatRepository { } @override - Future saveMessage(MessageRequest messageRequest) { - return chatApi.saveMessage(messageRequest); + Future saveMessage(int conversationId, MessageRequest messageRequest) { + return chatApi.saveMessage(conversationId, messageRequest); } @override Future saveAIResponseAsMessage(AIResponse aiResponse, int conversationId) { - final messageRequest = MessageUtils.convertAIMessageToMessageDto(aiResponse, conversationId); - return saveMessage(messageRequest); + final messageRequest = MessageUtils.convertAIMessageToMessageRequest(aiResponse); + return saveMessage(conversationId, messageRequest); } @override - Future saveLikingLevel(LikinglevelRequest likinglevelRequest) { - return chatApi.saveLikingLevel(likinglevelRequest); - } - - @override - Future> fetchMessagesByChatRoomId(int chatRoomId) { + Future fetchMessagesByChatRoomId(int chatRoomId) { return chatApi.getMessagesByChatRoomId(chatRoomId); } @@ -47,3 +42,4 @@ class ChatRepositoryImpl implements ChatRepository { return chatApi.getConversationById(conversationId); } } + diff --git a/lib/data/repository/ai_repositoryImpl.dart b/lib/data/repository/openai_repositoryImpl.dart similarity index 85% rename from lib/data/repository/ai_repositoryImpl.dart rename to lib/data/repository/openai_repositoryImpl.dart index 240534c..5014058 100644 --- a/lib/data/repository/ai_repositoryImpl.dart +++ b/lib/data/repository/openai_repositoryImpl.dart @@ -1,13 +1,14 @@ import 'dart:convert'; + import 'package:langchain/langchain.dart'; import 'package:langchain_openai/langchain_openai.dart'; import 'package:palink_v2/core/constants/prompts.dart'; -import 'package:palink_v2/data/models/ai_response.dart'; -import 'package:palink_v2/domain/entities/analysis/analysis_dto.dart'; -import 'package:palink_v2/domain/entities/tip/tip.dart'; -import 'package:palink_v2/domain/repository/ai_repository.dart'; +import 'package:palink_v2/domain/repository/open_ai_repository.dart'; +import '../../domain/entities/analysis/analysis_dto.dart'; +import '../models/tip/tip_dto.dart'; +import '../models/ai_response/ai_response.dart'; -class AIRepositoryImpl implements AIRepository { +class OpenAIRepositoryImpl implements OpenAIRepository { final ChatOpenAI openAI; final ConversationBufferMemory memoryBuffer; final ConversationBufferMemory tipMemoryBuffer; @@ -15,7 +16,7 @@ class AIRepositoryImpl implements AIRepository { final LLMChain tipChain; final LLMChain analyzeChain; - AIRepositoryImpl(this.openAI, this.memoryBuffer, this.tipMemoryBuffer, + OpenAIRepositoryImpl(this.openAI, this.memoryBuffer, this.tipMemoryBuffer, this.chatChain, this.tipChain, this.analyzeChain); @override @@ -46,7 +47,7 @@ class AIRepositoryImpl implements AIRepository { } @override - Future getTip(String message) async { + Future createTip(String message) async { final inputs = {'input': "${Prompt.tipPrompt}\n${message}"}; try { print('getTip inputs: $inputs'); // 로그 추가 @@ -55,7 +56,6 @@ class AIRepositoryImpl implements AIRepository { AIChatMessage aiChatMessage = result['output'] as AIChatMessage; final Map tipMap = jsonDecode(aiChatMessage.content); return TipDto.fromJson(tipMap); - } catch (e) { print('Failed to get tip: $e'); return null; @@ -79,4 +79,4 @@ class AIRepositoryImpl implements AIRepository { return null; } } -} \ No newline at end of file +} diff --git a/lib/data/repository/user_repositoryImpl.dart b/lib/data/repository/user_repositoryImpl.dart index 7795678..4f79124 100644 --- a/lib/data/repository/user_repositoryImpl.dart +++ b/lib/data/repository/user_repositoryImpl.dart @@ -1,37 +1,32 @@ -// data/repository/shared_pref_user_repository.dart + + +import 'package:palink_v2/data/api/user/user_api.dart'; +import 'package:palink_v2/data/models/user/user_response.dart'; +import 'package:palink_v2/domain/entities/user/user.dart'; +import 'package:palink_v2/domain/repository/user_repository.dart'; +import 'package:palink_v2/data/mapper/user_mapper.dart'; import 'package:shared_preferences/shared_preferences.dart'; -import '../../domain/repository/user_repository.dart'; class UserRepositoryImpl implements UserRepository { final SharedPreferences prefs; + final UserApi _userApi; - UserRepositoryImpl(this.prefs); + UserRepositoryImpl(this.prefs, this._userApi); - @override - Future getUserId() async { - final userId = prefs.getString('userId') ?? ''; - print('Retrieved userId: $userId'); - return userId; - } - - @override - Future getName() async { - final name = prefs.getString('name') ?? ''; - print('Retrieved name: $name'); - return name; - } @override - Future getAge() async { - final age = prefs.getInt('age') ?? 0; - print('Retrieved age: $age'); - return age; + int? getUserId() { + return prefs.getInt('userId'); } @override - Future getPersonalityType() async { - final personalityType = prefs.getString('personalityType') ?? ''; - print('Retrieved personalityType: $personalityType'); - return personalityType; + Future getUser(int userId) async { + try { + UserResponse? response = await _userApi.getUserById(userId); + return response?.toDomain(); + } catch (e) { + print('Error in getUser: $e'); + return null; + } } } diff --git a/lib/di/locator.dart b/lib/di/locator.dart index 95d6553..694f886 100644 --- a/lib/di/locator.dart +++ b/lib/di/locator.dart @@ -5,25 +5,28 @@ import 'package:langchain/langchain.dart'; import 'package:langchain_openai/langchain_openai.dart'; import 'package:palink_v2/core/constants/app_images.dart'; import 'package:palink_v2/core/constants/prompts.dart'; -import 'package:palink_v2/data/api/auth_api.dart'; -import 'package:palink_v2/data/api/chat_api.dart'; +import 'package:palink_v2/data/api/auth/auth_api.dart'; +import 'package:palink_v2/data/api/character/character_api.dart'; +import 'package:palink_v2/data/api/chat/chat_api.dart'; +import 'package:palink_v2/data/api/feedback/feedback_api.dart'; +import 'package:palink_v2/data/api/tip/tip_api.dart'; +import 'package:palink_v2/data/api/user/user_api.dart'; import 'package:palink_v2/data/dao/character_dao.dart'; import 'package:palink_v2/data/dao/character_quest_dao.dart'; import 'package:palink_v2/data/dao/mindset_dao.dart'; import 'package:palink_v2/data/database/app_database.dart'; import 'package:palink_v2/data/entities/character_entity.dart'; -import 'package:palink_v2/data/entities/mindset_entity.dart'; import 'package:palink_v2/data/repository/auth_repositoryImpl.dart'; import 'package:palink_v2/data/repository/character_quest_repositoryImpl.dart'; import 'package:palink_v2/data/repository/character_repositoryImpl.dart'; import 'package:palink_v2/data/repository/chat_repositoryImpl.dart'; import 'package:palink_v2/data/repository/user_repositoryImpl.dart'; -import 'package:palink_v2/domain/repository/ai_repository.dart'; import 'package:palink_v2/domain/repository/auth_repository.dart'; import 'package:palink_v2/domain/repository/character_quest_repository.dart'; import 'package:palink_v2/domain/repository/character_repository.dart'; import 'package:palink_v2/domain/repository/chat_repository.dart'; import 'package:palink_v2/domain/repository/mindset_repository.dart'; +import 'package:palink_v2/domain/repository/open_ai_repository.dart'; import 'package:palink_v2/domain/repository/user_repository.dart'; import 'package:palink_v2/domain/usecase/create_conversation_usecase.dart'; import 'package:palink_v2/domain/usecase/fetch_characters_usecase.dart'; @@ -33,19 +36,16 @@ import 'package:palink_v2/domain/usecase/generate_initial_message_usecase.dart'; import 'package:palink_v2/domain/usecase/generate_response_usecase.dart'; import 'package:palink_v2/domain/usecase/get_random_mindset_usecase.dart'; import 'package:palink_v2/domain/usecase/get_user_info_usecase.dart'; -import 'package:palink_v2/domain/usecase/get_user_usecase.dart'; import 'package:palink_v2/domain/usecase/send_user_message_usecase.dart'; import 'package:palink_v2/domain/usecase/sign_up_usecase.dart'; import 'package:palink_v2/presentation/screens/auth/controller/login_view_model.dart'; import 'package:palink_v2/presentation/screens/auth/controller/signup_view_model.dart'; import 'package:palink_v2/presentation/screens/character_select/controller/character_select_viewmodel.dart'; import 'package:palink_v2/presentation/screens/chatting/controller/tip_viewmodel.dart'; -import 'package:palink_v2/presentation/screens/feedback/controller/feedback_viewmodel.dart'; import 'package:palink_v2/presentation/screens/mypage/controller/mypage_viewmodel.dart'; import 'package:shared_preferences/shared_preferences.dart'; -import 'package:sqflite_common/sqlite_api.dart'; -import '../data/repository/ai_repositoryImpl.dart'; import '../data/repository/mindset_repositoryImpl.dart'; +import '../data/repository/openai_repositoryImpl.dart'; import '../domain/usecase/generate_tip_usecase.dart'; // Import GenerateTipUsecase import '../domain/usecase/login_usecase.dart'; @@ -89,16 +89,21 @@ void _setupDio() { void _setupApis() { getIt.registerLazySingleton(() => AuthApi(getIt())); getIt.registerLazySingleton(() => ChatApi(getIt())); + getIt.registerLazySingleton(() => TipApi(getIt())); + getIt.registerLazySingleton(() => CharacterApi(getIt())); + getIt.registerLazySingleton(() => UserApi(getIt())); + getIt.registerLazySingleton(() => FeedbackApi(getIt())); } void _setupRepositories(SharedPreferences prefs) { - getIt.registerLazySingleton(() => AuthRepositoryImpl(getIt(), prefs)); - getIt.registerLazySingleton(() => UserRepositoryImpl(prefs)); + getIt.registerLazySingleton(() => AuthRepositoryImpl(getIt(), getIt(), prefs)); + getIt.registerLazySingleton(() => UserRepositoryImpl(prefs, getIt())); getIt.registerLazySingleton(() => ChatRepositoryImpl(getIt())); getIt.registerLazySingleton(() => CharacterRepositoryImpl()); getIt.registerLazySingleton(() => MindsetRepositoryImpl()); -} + +} void _setupAI() { getIt.registerLazySingleton(() => ChatOpenAI( apiKey: dotenv.env['API_KEY']!, @@ -123,7 +128,7 @@ void _setupAI() { llm: getIt(), prompt: ChatPromptTemplate.fromTemplate(''' 당신은 마지막 말에 대해 적절한 답변을 해야합니다. - 당신은 USER 를 {userName}으로 부르세요. rejection_score는 누적되어야하고 만약 -5 이하면 is_end를 즉시 1로 설정하세요. + 당신은 USER 를 {userName}으로 부르세요. {userName} 이 풀네임이라면 성은 뺴고 이름만 부르세요. rejection_score는 누적되어야하고 만약 -5 이하면 is_end를 즉시 1로 설정하세요. 다음은 당신에 대한 설명입니다. {description} 답변으로 'text', 'feeling', 'expected_emotion', 'rejection_score', 'affinity_score', 'is_end'을 반드시 JSON 객체로 리턴하세요. ("```"로 시작하는 문자열을 생성하지 마세요) @@ -159,7 +164,7 @@ void _setupAI() { llm: getIt(), ), instanceName: 'analyzeChain'); - getIt.registerLazySingleton(() => AIRepositoryImpl( + getIt.registerLazySingleton(() => OpenAIRepositoryImpl( getIt(), getIt(), getIt(instanceName: 'tipMemory'), @@ -170,27 +175,27 @@ void _setupAI() { getIt.registerLazySingleton(() => CharacterQuestRepositoryImpl(getIt())); } + void _setupUseCases() { getIt.registerFactory(() => CreateConversationUseCase(getIt(), getIt())); getIt.registerFactory(() => LoginUseCase(getIt())); getIt.registerFactory(() => SignUpUseCase(getIt())); getIt.registerFactory(() => GetUserInfoUseCase(getIt())); - getIt.registerFactory(() => GetUserUseCase(getIt())); getIt.registerFactory(() => FetchCharactersUsecase(getIt())); - getIt.registerFactory(() => GenerateInitialMessageUsecase()); getIt.registerFactory(() => FetchChatHistoryUsecase(getIt())); - getIt.registerFactory(() => SendUserMessageUsecase(getIt(), getIt())); + getIt.registerFactory(() => SendUserMessageUsecase(getIt())); getIt.registerFactory(() => GenerateResponseUsecase(getIt(), getIt(), getIt())); getIt.registerFactory(() => GenerateTipUsecase()); getIt.registerFactory(() => GenerateAnalyzeUsecase()); getIt.registerFactory(() => GetRandomMindsetUseCase(getIt())); + getIt.registerFactory(() => GenerateInitialMessageUsecase()); } void _setupViewModels() { getIt.registerFactory(() => LoginViewModel(loginUseCase: getIt())); getIt.registerFactory(() => SignupViewModel(signUpUseCase: getIt())); - getIt.registerFactory(() => MypageViewModel(getUserUseCase: getIt())); + getIt.registerFactory(() => MypageViewModel(getUserInfoUseCase: getIt())); getIt.registerLazySingleton(() => CharacterSelectViewModel(fetchCharactersUsecase: getIt())); getIt.registerFactory(() => TipViewModel()); } @@ -262,56 +267,4 @@ Future _initializeDatabase(CharacterDao characterDao, MindsetDao mindsetDa ]; await characterDao.insertCharacters(characters); - - // 그룹 1: 자기 수용과 자존감 - final group1Data = [ - MindsetEntity(id: 1, group: 1, content: '모든 사람을 만족시킬 수는 없다.', reason: '모든 사람을 만족시키려 하면 자신을 잃게 됩니다. 스스로를 우선시하는 것이 중요합니다. 이는 우리의 정신적, 감정적 건강을 지키는 데 필요합니다.'), - MindsetEntity(id: 2, group: 1, content: '모두가 처음에는 떨린다.', reason: '사람들 앞에서 말하는 것이 두렵다면, 모두가 처음에는 떨린다는 것을 기억하세요. 반복적인 연습과 작은 성공을 통해 자신감을 키울 수 있습니다.'), - MindsetEntity(id: 3, group: 1, content: '자신의 강점을 찾자.', reason: '자신감을 키우기 위해서는 자신의 강점을 찾고 그것을 개발하는 것이 중요합니다. 이는 자기 효능감을 높이고 더 나은 자신을 만드는 데 도움이 됩니다.'), - MindsetEntity(id: 4, group: 1, content: '실수는 누구나 한다.', reason: '실수는 성장의 과정 중 하나입니다. 실수를 통해 배우고 개선할 수 있습니다. 이를 받아들이면 더 나은 관계를 형성할 수 있습니다.'), - MindsetEntity(id: 5, group: 1, content: '자신을 돌보는 시간을 가지자.', reason: '자신을 돌보는 것은 매우 중요합니다. 건강한 마음과 몸이 있어야 다른 사람들과의 관계도 건강하게 유지할 수 있습니다.'), - MindsetEntity(id: 6, group: 1, content: '긍정적인 자기 대화를 하자.', reason: '긍정적인 자기 대화는 자신감을 높이고, 어려운 상황에서도 긍정적인 태도를 유지하는 데 도움이 됩니다. 이는 대인관계에서도 긍정적인 영향을 미칩니다.'), - MindsetEntity(id: 7, group: 1, content: '자기 표현을 두려워하지 말자.', reason: '자신의 생각과 감정을 표현하는 것은 매우 중요합니다. 타인의 반응을 두려워하지 말고 솔직하게 자신을 표현하는 것이 필요합니다. 이는 진정한 나를 보여주고 관계를 깊게 만드는 데 도움이 됩니다.'), - MindsetEntity(id: 8, group: 1, content: '타인의 시선은 나의 가치가 아니다.', reason: '타인의 시선과 평가가 나의 가치를 결정하지 않습니다. 나 자신의 가치와 자존감을 스스로 인정하는 것이 중요합니다. 이는 건강한 자아상을 유지하는 데 도움이 됩니다.'), - MindsetEntity(id: 9, group: 1, content: '과거에 얽매이지 말자.', reason: '과거에 얽매여 현재의 불행한 관계를 유지하는 것은 도움이 되지 않습니다. 과거를 인정하고, 현재와 미래를 위해 필요한 결정을 내리는 것이 중요합니다.'), - MindsetEntity(id: 10, group: 1, content: '나 자신을 있는 그대로 받아들이자.', reason: '내가 편안해야 상대방도 편안해집니다. 나 자신을 \'괜찮다\'고 인정하는 것이 중요합니다.'), - MindsetEntity(id: 11, group: 1, content: '나의 편안함이 상대방에게 전해진다.', reason: '내가 편안한 마음을 가지면, 그 에너지가 상대방에게도 전달됩니다. 이는 자연스럽고 편안한 관계를 형성하는 데 도움이 됩니다.'), - MindsetEntity(id: 12, group: 1, content: '타인의 생각은 그들의 문제다.', reason: '타인의 생각과 의견은 그들의 문제이며, 내가 통제할 수 없는 부분입니다. 나 자신의 감정과 생각에 집중하는 것이 더 중요합니다. 이는 나의 정신적 건강을 지키는 데 도움이 됩니다.'), - MindsetEntity(id: 13, group: 1, content: '타인의 판단은 일시적이다.', reason: '타인의 판단은 일시적이고 변할 수 있습니다. 이에 너무 집착하지 말고 나 자신의 길을 가는 것이 중요합니다. 이는 지속적인 자아 발전과 행복을 추구하는 데 도움이 됩니다.'), - MindsetEntity(id: 14, group: 1, content: '모두에게 좋은 인상을 줄 필요는 없다.', reason: '모든 사람에게 좋은 인상을 주려고 노력하면 지치게 됩니다. 자신에게 중요한 사람들과의 관계에 집중하는 것이 더 중요합니다. 이는 나의 에너지를 효율적으로 사용하는 데 도움이 됩니다.'), - MindsetEntity(id: 15, group: 1, content: '나의 삶은 내가 결정한다.', reason: '나의 삶의 주인은 나 자신입니다. 타인의 의견에 휘둘리지 않고, 나의 결정을 스스로 내리는 것이 중요합니다. 이는 진정한 자유와 자아 존중을 이루는 데 도움이 됩니다.') - ]; - - // 그룹 2: 거절과 경계 설정 - final group2Data = [ - MindsetEntity(id: 16, group: 2, content: '거절은 나의 권리다.', reason: '우리는 자신의 시간과 에너지를 선택할 권리가 있습니다. 거절은 자신의 필요와 우선순위를 지키기 위한 정당한 선택입니다. 이를 통해 삶을 더 주도적으로 이끌 수 있습니다.'), - MindsetEntity(id: 17, group: 2, content: '비난보다는 해결책을 찾자.', reason: '갈등 상황에서 상대방을 비난하기보다는 함께 해결책을 찾는 것이 중요합니다. 이는 문제를 더 효율적으로 해결하고 관계를 강화하는 데 도움이 됩니다.'), - MindsetEntity(id: 18, group: 2, content: '모든 요청에 \'예\'라고 말할 필요는 없다.', reason: '모든 요청에 \'예\'라고 답하는 것은 나의 의지와 필요를 무시하게 만듭니다. 나의 한계를 알고 적절히 거절하는 것이 중요합니다. 이는 나의 자존감을 지키고 대인관계를 건강하게 유지하는 데 도움이 됩니다.'), - MindsetEntity(id: 19, group: 2, content: '거절은 관계를 깨지 않는다.', reason: '올바르게 거절하는 것은 관계를 망치지 않습니다. 오히려, 솔직한 대화는 관계를 더욱 깊게 만들 수 있습니다. 서로의 한계를 존중하는 것이 중요합니다.'), - MindsetEntity(id: 20, group: 2, content: '거절은 자신감의 표현이다.', reason: '거절할 줄 아는 것은 자신감의 표현입니다. 자신의 한계를 알고 그것을 표현하는 것이 진정한 용기입니다. 이는 타인에게 나의 경계를 명확히 알려주는 데 도움이 됩니다.'), - MindsetEntity(id: 21, group: 2, content: '연습을 통해 거절 능력을 키우자.', reason: '거절하는 것은 연습을 통해 더욱 자연스러워질 수 있습니다. 작은 일에서부터 거절을 연습해보면, 점점 더 큰 일에서도 자연스럽게 거절할 수 있습니다. 이는 나의 의사결정 능력을 강화합니다.'), - MindsetEntity(id: 22, group: 2, content: '미안해하지 말자.', reason: '정당한 이유로 거절했을 때 미안해하지 말자. 나의 한계를 지키는 것은 당연한 일입니다. 과도한 죄책감은 나를 힘들게 할 뿐입니다. 거절은 내가 나 자신을 존중하는 한 방법입니다.'), - MindsetEntity(id: 23, group: 2, content: '건설적인 대안을 제시하자.', reason: '거절할 때, 가능한 대안을 제시하면 상대방도 거절을 더 쉽게 받아들일 수 있습니다. 이는 상대방에게 존중받고 있다는 느낌을 주고 관계를 긍정적으로 유지하는 데 도움이 됩니다.'), - MindsetEntity(id: 24, group: 2, content: '자신의 감정을 우선시하자.', reason: '자신의 감정과 필요를 우선시하는 것은 건강한 자아존중감을 형성하는 데 중요합니다. 다른 사람의 기대에 맞추기 위해 자신을 희생하는 것은 장기적으로 건강하지 않습니다.'), - MindsetEntity(id: 25, group: 2, content: '상대방도 거절을 이해할 수 있다.', reason: '대부분의 사람들은 거절에 대해 이해할 수 있습니다. 너무 걱정하지 말고 솔직하게 말하는 것이 좋습니다. 이는 오해를 줄이고 관계를 긍정적으로 유지하는 데 도움이 됩니다.'), - MindsetEntity(id: 26, group: 2, content: '거절을 통해 나의 기준을 세우자.', reason: '거절은 나의 기준과 경계를 명확히 하는 방법입니다. 나의 가치와 원칙을 지키기 위해 거절하는 것이 필요합니다. 이는 타인에게 나의 경계를 알리는 데 중요합니다.') - ]; - - // 그룹 3: 대인관계와 상호작용 - final group3Data = [ - MindsetEntity(id: 27, group: 3, content: '친구의 입장에서 생각해보자.', reason: '친구와의 관계에서 서로의 입장을 이해하려고 노력하면 갈등을 줄이고 더 깊은 유대감을 형성할 수 있습니다. 이는 상대방의 감정을 존중하고, 공감하는 능력을 키우는 데 도움이 됩니다.'), - MindsetEntity(id: 28, group: 3, content: '자신의 감정을 솔직하게 표현하자.', reason: '감정을 솔직하게 표현하면 상대방이 나의 상황과 감정을 더 잘 이해할 수 있습니다. 이는 오해를 줄이고, 신뢰를 쌓으며, 건강한 의사소통을 가능하게 합니다.'), - MindsetEntity(id: 29, group: 3, content: '다양한 관점을 존중하자.', reason: '서로 다른 관점을 존중하면 더 넓은 시각을 가지게 됩니다. 이는 서로의 차이를 이해하고, 갈등을 줄이며, 풍부한 대화를 나누는 데 도움이 됩니다.'), - MindsetEntity(id: 30, group: 3, content: '긍정적인 피드백을 주자.', reason: '긍정적인 피드백은 상대방의 자존감을 높이고, 더 나은 행동을 유도하는 데 효과적입니다. 이는 건강한 대인관계를 유지하고, 서로의 성장을 지원하는 데 중요합니다.'), - MindsetEntity(id: 31, group: 3, content: '배려는 억지로 할 필요가 없다.', reason: '억지로 하는 배려는 나와 상대방 모두에게 부담이 됩니다. 자연스럽게 나오는 배려가 진정한 배려이며, 이는 서로를 더 편안하게 하고 관계를 긍정적으로 유지하는 데 도움이 됩니다.'), - MindsetEntity(id: 32, group: 3, content: '타산적인 배려는 하지 말자.', reason: '타산적인 배려는 상대방을 조작하려는 의도가 담겨 있어 진정한 배려가 아닙니다. 이는 오히려 신뢰를 손상시킬 수 있습니다. 순수한 마음에서 우러나오는 배려가 중요합니다.'), - MindsetEntity(id: 33, group: 3, content: '나와 상대방이 다르다는 사실을 인정하자.', reason: '사람마다 생각과 느낌이 다르다는 사실을 인정하면 상대방을 더 잘 이해할 수 있습니다. 이는 상대방의 감정을 존중하고, 불필요한 갈등을 피하는 데 도움이 됩니다.'), - MindsetEntity(id: 34, group: 3, content: '상대방의 사정을 단정짓지 말자.', reason: '상대방의 상황을 충분히 이해하지 못한 상태에서 결론을 내리는 것은 잘못된 판단으로 이어질 수 있습니다. 이는 오해를 줄이고, 상대방을 더 잘 이해하려는 노력을 통해 건강한 관계를 유지하는 데 중요합니다.'), - MindsetEntity(id: 35, group: 3, content: '조언보다는 공감을 우선하자.', reason: '조언은 때로는 상대방을 바꾸려는 시도로 받아들여질 수 있습니다. 반면, 공감은 상대방의 감정을 이해하고 존중하는 데 초점을 맞춥니다. 이는 서로의 감정을 더 깊이 이해하고 신뢰를 쌓는 데 도움이 됩니다.'), - MindsetEntity(id: 36, group: 3, content: '상호 존중이 없는 관계는 유지할 필요가 없다.', reason: '상호 존중이 없는 관계는 나에게 해로울 뿐입니다. 존중과 이해가 기반이 되는 관계만을 유지하는 것이 중요합니다.') - ]; - - await mindsetDao.insertMindsets(group1Data); - await mindsetDao.insertMindsets(group2Data); - await mindsetDao.insertMindsets(group3Data); } diff --git a/lib/domain/entities/chat/conversation.dart b/lib/domain/entities/chat/conversation.dart index 56f3094..15c848d 100644 --- a/lib/domain/entities/chat/conversation.dart +++ b/lib/domain/entities/chat/conversation.dart @@ -1,16 +1,16 @@ -import 'package:palink_v2/data/models/conversation_response.dart'; +import 'package:palink_v2/data/models/chat/conversation_response.dart'; class Conversation { - int conversationId; String day; - String userId; + int userId; int characterId; + int conversationId; Conversation({ - required this.conversationId, required this.day, required this.userId, required this.characterId, + required this.conversationId, }); // fromResponse 메서드 추가 diff --git a/lib/domain/entities/tip/tip.dart b/lib/domain/entities/tip/tip.dart index 6c46700..8e71c9c 100644 --- a/lib/domain/entities/tip/tip.dart +++ b/lib/domain/entities/tip/tip.dart @@ -21,18 +21,3 @@ class Tip { } } -// Tip 생성 시 사용하는 데이터 DTO -class TipDto { - final String tipText; - final int messageId; - - TipDto({required this.tipText, required this.messageId}); - - factory TipDto.fromJson(Map json) { - return TipDto(tipText: json['tip_text'], messageId: json['message_id']); - } - - Map toJson() { - return {'tip_text': tipText, 'message_id': messageId}; - } -} diff --git a/lib/domain/mapper/message_mapper.dart b/lib/domain/mapper/message_mapper.dart deleted file mode 100644 index 8a29bd1..0000000 --- a/lib/domain/mapper/message_mapper.dart +++ /dev/null @@ -1,15 +0,0 @@ -import 'package:palink_v2/data/models/message_response.dart'; -import 'package:palink_v2/domain/entities/chat/message.dart'; - - -class MessageMapper { - static Message toDomain(MessageResponse response) { - return Message( - sender: response.sender, - messageText: response.messageText, - timestamp: response.timestamp, - affinityScore: 50, - rejectionScore: 0, - ); - } -} diff --git a/lib/domain/repository/auth_repository.dart b/lib/domain/repository/auth_repository.dart index d113538..bb7986d 100644 --- a/lib/domain/repository/auth_repository.dart +++ b/lib/domain/repository/auth_repository.dart @@ -6,4 +6,5 @@ import 'package:palink_v2/domain/entities/user/user.dart'; abstract class AuthRepository { Future login(LoginModel loginModel); Future signUp(SignupModel signUpModel); + Future getUserFromPreferences(); } \ No newline at end of file diff --git a/lib/domain/repository/chat_repository.dart b/lib/domain/repository/chat_repository.dart index 0a07b18..ca96512 100644 --- a/lib/domain/repository/chat_repository.dart +++ b/lib/domain/repository/chat_repository.dart @@ -1,17 +1,15 @@ // domain/repositories/chat_repository.dart -import 'package:palink_v2/data/models/ai_response.dart'; -import 'package:palink_v2/data/models/conversation_request.dart'; -import 'package:palink_v2/data/models/conversation_response.dart'; -import 'package:palink_v2/data/models/likinglevel_request.dart'; -import 'package:palink_v2/data/models/likinglevel_response.dart'; -import 'package:palink_v2/data/models/message_request.dart'; -import 'package:palink_v2/data/models/message_response.dart'; +import 'package:palink_v2/data/models/ai_response/ai_response.dart'; +import 'package:palink_v2/data/models/chat/conversation_request.dart'; +import 'package:palink_v2/data/models/chat/conversation_response.dart'; +import 'package:palink_v2/data/models/chat/message_request.dart'; +import 'package:palink_v2/data/models/chat/message_response.dart'; +import 'package:palink_v2/data/models/chat/messages_response.dart'; abstract class ChatRepository { Future createConversation(ConversationRequest conversationRequest); - Future saveMessage(MessageRequest messageRequest); + Future saveMessage(int conversationId, MessageRequest messageRequest); Future saveAIResponseAsMessage(AIResponse aiResponse, int conversationId); - Future saveLikingLevel(LikinglevelRequest likinglevelRequest); - Future> fetchMessagesByChatRoomId(int chatRoomId); + Future fetchMessagesByChatRoomId(int chatRoomId); Future fetchConversationByChatRoomId(int chatRoomId); } diff --git a/lib/domain/repository/ai_repository.dart b/lib/domain/repository/open_ai_repository.dart similarity index 63% rename from lib/domain/repository/ai_repository.dart rename to lib/domain/repository/open_ai_repository.dart index 4344c74..0b694d4 100644 --- a/lib/domain/repository/ai_repository.dart +++ b/lib/domain/repository/open_ai_repository.dart @@ -1,13 +1,13 @@ -import 'package:palink_v2/data/models/ai_response.dart'; +import 'package:palink_v2/data/models/ai_response/ai_response.dart'; import 'package:palink_v2/domain/entities/analysis/analysis_dto.dart'; -import 'package:palink_v2/domain/entities/tip/tip.dart'; +import '../../data/models/tip/tip_dto.dart'; -abstract class AIRepository { +abstract class OpenAIRepository { Future> getMemory(); Future saveMemoryContext(Map inputValues, Map outputValues); Future processChat(Map inputs); - Future getTip(String message); + Future createTip(String message); Future analyzeResponse(String input); } diff --git a/lib/domain/repository/user_repository.dart b/lib/domain/repository/user_repository.dart index 2702dfc..16bdd1b 100644 --- a/lib/domain/repository/user_repository.dart +++ b/lib/domain/repository/user_repository.dart @@ -1,6 +1,6 @@ +import '../entities/user/user.dart'; + abstract class UserRepository { - Future getUserId(); - Future getName(); - Future getAge(); - Future getPersonalityType(); + int? getUserId(); + Future getUser(int userId); } diff --git a/lib/domain/usecase/create_conversation_usecase.dart b/lib/domain/usecase/create_conversation_usecase.dart index ffe35ea..e174dd1 100644 --- a/lib/domain/usecase/create_conversation_usecase.dart +++ b/lib/domain/usecase/create_conversation_usecase.dart @@ -1,8 +1,8 @@ // domain/usecases/create_conversation_usecase.dart -import 'package:palink_v2/data/models/conversation_request.dart'; -import 'package:palink_v2/data/models/conversation_response.dart'; +import 'package:palink_v2/data/models/chat/conversation_request.dart'; +import 'package:palink_v2/data/models/chat/conversation_response.dart'; import 'package:palink_v2/domain/entities/character/character.dart'; import 'package:palink_v2/domain/entities/chat/conversation.dart'; import 'package:palink_v2/domain/entities/user/user.dart'; @@ -17,10 +17,10 @@ class CreateConversationUseCase { CreateConversationUseCase(this.chatRepository, this.getUserInfoUseCase); Future execute(Character character) async { - User user = await getUserInfoUseCase.execute(); + User? user = await getUserInfoUseCase.execute(); var conversationRequest = ConversationRequest( day: DateTime.now().toIso8601String(), - userId: user.accountId, + userId: user!.userId!, characterId: character.characterId, ); ConversationResponse response = await chatRepository.createConversation(conversationRequest); diff --git a/lib/domain/usecase/fetch_chat_history_usecase.dart b/lib/domain/usecase/fetch_chat_history_usecase.dart index 978f7d1..d4104cf 100644 --- a/lib/domain/usecase/fetch_chat_history_usecase.dart +++ b/lib/domain/usecase/fetch_chat_history_usecase.dart @@ -1,6 +1,7 @@ -import 'package:palink_v2/data/models/message_response.dart'; +import 'package:palink_v2/data/mapper/message_response_mapper.dart'; +import 'package:palink_v2/data/models/chat/message_response.dart'; +import 'package:palink_v2/data/models/chat/messages_response.dart'; import 'package:palink_v2/domain/entities/chat/message.dart'; -import 'package:palink_v2/domain/mapper/message_mapper.dart'; import 'package:palink_v2/domain/repository/chat_repository.dart'; class FetchChatHistoryUsecase { @@ -8,8 +9,8 @@ class FetchChatHistoryUsecase { FetchChatHistoryUsecase(this.repository); - Future> execute(int chatRoomId) async { - List messageResponses = await repository.fetchMessagesByChatRoomId(chatRoomId); - return messageResponses.map((response) => MessageMapper.toDomain(response)).toList(); + Future?> execute(int chatRoomId) async { + final MessagesResponse? response = await repository.fetchMessagesByChatRoomId(chatRoomId); + return response?.messages.map((msg) => msg.toDomain()).toList(); } } diff --git a/lib/domain/usecase/generate_analyze_usecase.dart b/lib/domain/usecase/generate_analyze_usecase.dart index 06ec57c..b2633d8 100644 --- a/lib/domain/usecase/generate_analyze_usecase.dart +++ b/lib/domain/usecase/generate_analyze_usecase.dart @@ -2,10 +2,10 @@ import 'package:palink_v2/di/locator.dart'; import 'package:palink_v2/domain/entities/analysis/analysis_dto.dart'; import 'package:palink_v2/domain/entities/character/character.dart'; import 'package:palink_v2/domain/entities/chat/message.dart'; -import 'package:palink_v2/domain/repository/ai_repository.dart'; +import 'package:palink_v2/domain/repository/open_ai_repository.dart'; class GenerateAnalyzeUsecase { - final AIRepository aiRepository = getIt(); + final OpenAIRepository aiRepository = getIt(); Future execute(Character character, List chatHistory) { String input = '[캐릭터 설명] ${character.description}\n [거절 점수표] ${character.anaylzePrompt} \n[채팅 히스토리] $chatHistory'; diff --git a/lib/domain/usecase/generate_initial_message_usecase.dart b/lib/domain/usecase/generate_initial_message_usecase.dart index a9f2d03..e7d454d 100644 --- a/lib/domain/usecase/generate_initial_message_usecase.dart +++ b/lib/domain/usecase/generate_initial_message_usecase.dart @@ -1,44 +1,36 @@ -import 'package:palink_v2/data/models/ai_response.dart'; -import 'package:palink_v2/data/models/message_request.dart'; +import 'package:palink_v2/data/mapper/ai_response_mapper.dart'; +import 'package:palink_v2/data/models/ai_response/ai_response.dart'; import 'package:palink_v2/di/locator.dart'; -import 'package:palink_v2/domain/repository/ai_repository.dart'; +import 'package:palink_v2/domain/entities/character/character.dart'; +import 'package:palink_v2/domain/entities/user/user.dart'; +import 'package:palink_v2/domain/repository/open_ai_repository.dart'; import 'package:palink_v2/domain/repository/chat_repository.dart'; +// 초기 AI 메시지를 생성하는 유스케이스 class GenerateInitialMessageUsecase { final ChatRepository chatRepository = getIt(); - final AIRepository aiRepository = getIt(); + final OpenAIRepository aiRepository = getIt(); + GenerateInitialMessageUsecase(); - Future execute(int conversationId, String userName, - String description) async { - final memoryVariables = await aiRepository.getMemory(); - final chatHistory = memoryVariables['history'] ?? ''; + Future execute(int conversationId, String userName, String description) async { final inputs = { 'input': '당신이 먼저 부탁을 하며 대화를 시작하세요.', - 'chat_history': chatHistory, + 'chat_history': [], 'userName': userName, 'description': description, - 'conversationId': conversationId.toString(), }; AIResponse? aiResponse = await aiRepository.processChat(inputs); - // AI 응답을 메시지로 변환하여 저장 + if (aiResponse != null) { - var messageRequest = MessageRequest( - sender: false, - messageText: aiResponse.text, - timestamp: DateTime.now().toIso8601String(), - conversationId: conversationId, - ); - await chatRepository.saveMessage(messageRequest); - - if (aiResponse != null) { - await aiRepository.saveMemoryContext(inputs, {'response': aiResponse}); - } - - return aiResponse; + var messageRequest = aiResponse.toMessageRequest(); + await chatRepository.saveMessage(conversationId, messageRequest); + await aiRepository.saveMemoryContext(inputs, {'response': aiResponse}); } + return aiResponse; } } + diff --git a/lib/domain/usecase/generate_response_usecase.dart b/lib/domain/usecase/generate_response_usecase.dart index f69ee54..80268a3 100644 --- a/lib/domain/usecase/generate_response_usecase.dart +++ b/lib/domain/usecase/generate_response_usecase.dart @@ -1,12 +1,12 @@ import 'package:get/get.dart'; -import 'package:palink_v2/data/models/ai_response.dart'; -import 'package:palink_v2/data/models/message_request.dart'; +import 'package:palink_v2/data/mapper/ai_response_mapper.dart'; +import 'package:palink_v2/data/models/ai_response/ai_response.dart'; +import 'package:palink_v2/data/models/chat/message_request.dart'; import 'package:palink_v2/di/locator.dart'; import 'package:palink_v2/domain/entities/character/character.dart'; -import 'package:palink_v2/domain/entities/tip/tip.dart'; import 'package:palink_v2/domain/entities/user/user.dart'; -import 'package:palink_v2/domain/repository/ai_repository.dart'; import 'package:palink_v2/domain/repository/chat_repository.dart'; +import 'package:palink_v2/domain/repository/open_ai_repository.dart'; import 'package:palink_v2/presentation/screens/chatting/controller/tip_viewmodel.dart'; import 'fetch_chat_history_usecase.dart'; import 'generate_tip_usecase.dart'; @@ -14,7 +14,7 @@ import 'get_user_info_usecase.dart'; class GenerateResponseUsecase { final ChatRepository chatRepository = getIt(); - final AIRepository aiRepository = getIt(); + final OpenAIRepository aiRepository = getIt(); final GetUserInfoUseCase getUserInfoUseCase; final FetchChatHistoryUsecase fetchChatHistoryUsecase; final GenerateTipUsecase generateTipUsecase; @@ -23,42 +23,36 @@ class GenerateResponseUsecase { Future execute(int conversationId, Character character) async { // 사용자 정보 가져오기 - User user = await getUserInfoUseCase.execute(); + User? user = await getUserInfoUseCase.execute(); + + // 이전 대화 기록 페치 final memoryVariables = await aiRepository.getMemory(); final chatHistory = memoryVariables['history'] ?? ''; + // AI와의 대화 시작 final inputs = { 'input': '유저의 마지막 말에 대답하세요. 대화 맥락을 기억합니다.', 'chat_history': chatHistory, - 'userName': user.name, + 'userName': user!.name, 'description': character.prompt, - 'conversationId': conversationId.toString(), }; AIResponse? aiResponse = await aiRepository.processChat(inputs); // AI 응답을 메시지로 변환하여 저장 if (aiResponse != null) { - var messageRequest = MessageRequest( - sender: false, - messageText: aiResponse.text, - timestamp: DateTime.now().toIso8601String(), - conversationId: conversationId, - ); - await chatRepository.saveMessage(messageRequest); + final messageRequest = aiResponse.toMessageRequest(); + await chatRepository.saveMessage(conversationId, messageRequest); + await aiRepository.saveMemoryContext(inputs, {'response': aiResponse}); final tip = await generateTipUsecase.execute(aiResponse.text); - if (tip != null) { - Get.find().updateTip(tip.tipText); - } else { - Get.find().updateTip('팁 생성 전입니다!'); - } + final tipViewModel = Get.find(); + tip != null + ? tipViewModel.updateTip(tip.answer) + : tipViewModel.updateTip('팁 생성 전입니다!'); } - return aiResponse; } - - } diff --git a/lib/domain/usecase/generate_tip_usecase.dart b/lib/domain/usecase/generate_tip_usecase.dart index ae50a62..09a88de 100644 --- a/lib/domain/usecase/generate_tip_usecase.dart +++ b/lib/domain/usecase/generate_tip_usecase.dart @@ -1,12 +1,11 @@ -import 'package:palink_v2/data/models/message_request.dart'; +import 'package:palink_v2/data/models/tip/tip_dto.dart'; import 'package:palink_v2/di/locator.dart'; -import 'package:palink_v2/domain/entities/tip/tip.dart'; -import 'package:palink_v2/domain/repository/ai_repository.dart'; +import 'package:palink_v2/domain/repository/open_ai_repository.dart'; class GenerateTipUsecase { - final AIRepository aiRepository = getIt(); + final OpenAIRepository aiRepository = getIt(); Future execute(String message) async { - return await aiRepository.getTip(message); + return await aiRepository.createTip(message); } } diff --git a/lib/domain/usecase/get_chatroom_info_usecase.dart b/lib/domain/usecase/get_chatroom_info_usecase.dart index 3a94e2e..042be2c 100644 --- a/lib/domain/usecase/get_chatroom_info_usecase.dart +++ b/lib/domain/usecase/get_chatroom_info_usecase.dart @@ -1,6 +1,6 @@ // domain/usecases/get_chatroom_info_usecase.dart import 'package:palink_v2/domain/repository/chat_repository.dart'; -import 'package:palink_v2/data/models/conversation_response.dart'; +import 'package:palink_v2/data/models/chat/conversation_response.dart'; class GetChatroomInfoUsecase { final ChatRepository chatRepository; diff --git a/lib/domain/usecase/get_user_info_usecase.dart b/lib/domain/usecase/get_user_info_usecase.dart index 1ec494c..a956083 100644 --- a/lib/domain/usecase/get_user_info_usecase.dart +++ b/lib/domain/usecase/get_user_info_usecase.dart @@ -1,22 +1,14 @@ import 'package:palink_v2/domain/entities/user/user.dart'; import 'package:palink_v2/domain/repository/user_repository.dart'; + class GetUserInfoUseCase { final UserRepository userRepository; - GetUserInfoUseCase(this.userRepository); - Future execute() async { - String accountId = await userRepository.getUserId(); - String name = await userRepository.getName(); - int age = await userRepository.getAge(); - String personalityType = await userRepository.getPersonalityType(); - - return User( - accountId: accountId, - name: name, - age: age, - personalityType: personalityType, - ); + Future execute() async { + int? userId = userRepository.getUserId(); + User? user = await userRepository.getUser(userId!); + return user; } } diff --git a/lib/domain/usecase/get_user_usecase.dart b/lib/domain/usecase/get_user_usecase.dart deleted file mode 100644 index 68d8f92..0000000 --- a/lib/domain/usecase/get_user_usecase.dart +++ /dev/null @@ -1,23 +0,0 @@ -import 'package:palink_v2/domain/repository/user_repository.dart'; - -class GetUserUseCase { - final UserRepository userRepository; - - GetUserUseCase(this.userRepository); - - Future getUserId() { - return userRepository.getUserId(); - } - - Future getName() { - return userRepository.getName(); - } - - Future getAge() { - return userRepository.getAge(); - } - - Future getPersonalityType() { - return userRepository.getPersonalityType(); - } -} diff --git a/lib/domain/usecase/login_usecase.dart b/lib/domain/usecase/login_usecase.dart index 20fadd5..aefdbd9 100644 --- a/lib/domain/usecase/login_usecase.dart +++ b/lib/domain/usecase/login_usecase.dart @@ -12,4 +12,8 @@ class LoginUseCase { Future execute(LoginModel loginModel) { return repository.login(loginModel); } + + Future checkAutoLogin() { + return repository.getUserFromPreferences(); + } } \ No newline at end of file diff --git a/lib/domain/usecase/send_user_message_usecase.dart b/lib/domain/usecase/send_user_message_usecase.dart index 079fd89..65b10e1 100644 --- a/lib/domain/usecase/send_user_message_usecase.dart +++ b/lib/domain/usecase/send_user_message_usecase.dart @@ -1,35 +1,49 @@ -import 'package:palink_v2/data/models/ai_response.dart'; -import 'package:palink_v2/data/models/message_request.dart'; -import 'package:palink_v2/data/models/message_response.dart'; +import 'package:palink_v2/data/mapper/message_response_mapper.dart'; +import 'package:palink_v2/data/models/ai_response/ai_response.dart'; +import 'package:palink_v2/data/models/chat/message_request.dart'; +import 'package:palink_v2/data/models/chat/message_response.dart'; +import 'package:palink_v2/di/locator.dart'; import 'package:palink_v2/domain/entities/character/character.dart'; import 'package:palink_v2/domain/entities/chat/message.dart'; -import 'package:palink_v2/domain/mapper/message_mapper.dart'; import 'package:palink_v2/domain/repository/chat_repository.dart'; import 'package:palink_v2/domain/usecase/generate_response_usecase.dart'; class SendUserMessageUsecase { - final ChatRepository chatRepository; + final ChatRepository chatRepository = getIt(); final GenerateResponseUsecase generateResponseUsecase; - SendUserMessageUsecase(this.chatRepository, this.generateResponseUsecase); + SendUserMessageUsecase( + this.generateResponseUsecase, + ); Future saveUserMessage(String text, int chatRoomId) async { - MessageRequest messageRequest = MessageRequest( + final messageRequest = _createMessageRequest(text); + + final messageResponse = + await _saveMessageToServer(messageRequest, chatRoomId); + + return _mapResponseToDomain(messageResponse); + } + + Future generateAIResponse( + int chatRoomId, Character character) async { + return await generateResponseUsecase.execute(chatRoomId, character); + } + + MessageRequest _createMessageRequest(String text) { + return MessageRequest( sender: true, messageText: text, timestamp: DateTime.now().toIso8601String(), - conversationId: chatRoomId, ); + } - // 유저의 메시지를 서버에 저장 - MessageResponse? response = await chatRepository.saveMessage(messageRequest); - print(response); - return response != null ? MessageMapper.toDomain(response) : null; + Future _saveMessageToServer( + MessageRequest messageRequest, int chatRoomId) async { + return await chatRepository.saveMessage(chatRoomId, messageRequest); } - Future generateAIResponse(int chatRoomId, Character character) async { - // AI의 응답을 생성 - AIResponse? aiResponse = await generateResponseUsecase.execute(chatRoomId, character); - return aiResponse; + Message? _mapResponseToDomain(MessageResponse? response) { + return response?.toDomain(); } } diff --git a/lib/main.dart b/lib/main.dart index 23c2aef..12f45c8 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -2,12 +2,14 @@ import 'package:flutter/material.dart'; import 'package:flutter_dotenv/flutter_dotenv.dart'; import 'package:get/get.dart'; import 'package:get_it/get_it.dart'; +import 'package:palink_v2/domain/entities/user/user.dart'; +import 'package:palink_v2/domain/usecase/login_usecase.dart'; import 'package:palink_v2/presentation/screens/auth/view/login_view.dart'; +import 'package:palink_v2/presentation/screens/main_screens.dart'; import 'package:sizing/sizing.dart'; import 'di/locator.dart'; - Future main() async { await dotenv.load(fileName: "lib/config/.env"); setupLocator(); @@ -24,8 +26,24 @@ class MyApp extends StatelessWidget { color: Colors.white, title: 'Flutter Demo', debugShowCheckedModeBanner: false, - home: LoginView(), + home: FutureBuilder( + future: _checkAutoLogin(), + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.waiting) { + return const CircularProgressIndicator(); + } else if (snapshot.hasData && snapshot.data != null) { + return const MainScreens(); // 로그인된 상태라면 홈 화면으로 이동 + } else { + return LoginView(); // 로그인되지 않은 상태라면 로그인 화면으로 이동 + } + }, + ), ), ); } + + Future _checkAutoLogin() async { + final loginUseCase = GetIt.instance(); + return await loginUseCase.checkAutoLogin(); + } } diff --git a/lib/presentation/screens/chatting/controller/chat_loading_viewmodel.dart b/lib/presentation/screens/chatting/controller/chat_loading_viewmodel.dart index 200749b..9ce8e4b 100644 --- a/lib/presentation/screens/chatting/controller/chat_loading_viewmodel.dart +++ b/lib/presentation/screens/chatting/controller/chat_loading_viewmodel.dart @@ -1,5 +1,5 @@ import 'package:get/get.dart'; -import 'package:palink_v2/data/models/ai_response.dart'; +import 'package:palink_v2/data/models/ai_response/ai_response.dart'; import 'package:palink_v2/di/locator.dart'; import 'package:palink_v2/domain/entities/character/character.dart'; import 'package:palink_v2/domain/entities/chat/conversation.dart'; @@ -34,7 +34,6 @@ class ChatLoadingViewModel extends GetxController { user.value = await getUserInfoUseCase.execute(); await _createConversationAndInitialMessage(); } catch (e) { - print('Initialization failed: $e'); errorMessage.value = 'Initialization failed: $e'; } finally { isLoading.value = false; @@ -51,6 +50,7 @@ class ChatLoadingViewModel extends GetxController { // 첫 메시지 생성하기 await _createInitialMessage(conversationId, user.value!.name); + // ChatScreen으로 이동 Get.off(() => ChatScreen(viewModel: Get.put(ChatViewModel(chatRoomId: conversationId, character: character)))); } } catch (e) { diff --git a/lib/presentation/screens/chatting/controller/chat_viewmodel.dart b/lib/presentation/screens/chatting/controller/chat_viewmodel.dart index 3234081..10f2c6a 100644 --- a/lib/presentation/screens/chatting/controller/chat_viewmodel.dart +++ b/lib/presentation/screens/chatting/controller/chat_viewmodel.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:palink_v2/data/models/ai_response.dart'; +import 'package:palink_v2/data/models/ai_response/ai_response.dart'; import 'package:palink_v2/di/locator.dart'; import 'package:palink_v2/domain/entities/character/character.dart'; import 'package:palink_v2/domain/entities/chat/message.dart'; @@ -21,7 +21,6 @@ class ChatViewModel extends GetxController { var messages = [].obs; var isLoading = false.obs; var likingLevels = [].obs; - var backgroundColor = Colors.white.obs; ChatViewModel({ @@ -45,8 +44,7 @@ class ChatViewModel extends GetxController { isLoading.value = true; try { var loadedMessages = await fetchChatHistoryUsecase.execute(chatRoomId); - messages.value = loadedMessages.reversed.toList(); // 역순으로 정렬 - print('Loaded messages: $messages'); + messages.value = loadedMessages!.reversed.toList(); } catch (e) { print('Failed to load messages: $e'); } finally { @@ -64,15 +62,17 @@ class ChatViewModel extends GetxController { } var aiResponseMessage = await sendMessageUsecase.generateAIResponse(chatRoomId, character); - - - var aiMessage = convertAIResponseToMessage(aiResponseMessage!); - if (aiMessage != null) { - messages.insert(0, aiMessage); // AI 응답 메시지를 리스트에 추가 + if (aiResponseMessage != null) { + var aiMessage = convertAIResponseToMessage(aiResponseMessage); + if (aiMessage != null) { + messages.insert(0, aiMessage); // AI 응답 메시지를 리스트에 추가 + } + } else { + print('AI response message is null'); } - _handleConversationEnd(aiResponseMessage); - + _loadMessages(); + _handleConversationEnd(aiResponseMessage!); textController.clear(); } catch (e) { print('Failed to send message: $e'); @@ -81,6 +81,7 @@ class ChatViewModel extends GetxController { } } + Message? convertAIResponseToMessage(AIResponse aiResponse) { return Message( sender: false, diff --git a/lib/presentation/screens/chatting/controller/tip_viewmodel.dart b/lib/presentation/screens/chatting/controller/tip_viewmodel.dart index 95c377e..4ad5d97 100644 --- a/lib/presentation/screens/chatting/controller/tip_viewmodel.dart +++ b/lib/presentation/screens/chatting/controller/tip_viewmodel.dart @@ -30,8 +30,8 @@ class TipViewModel extends GetxController { startLoading(); final tip = await generateTipUsecase.execute(message.messageText); if (tip != null) { - print('Tip generated: ${tip.tipText}'); // 로그 추가 - updateTip(tip.tipText); + print('Tip generated: ${tip.answer}'); // 로그 추가 + updateTip(tip.answer); } else { print('No tip available'); // 로그 추가 updateTip('No tip available.'); diff --git a/lib/presentation/screens/chatting/view/chat_screen.dart b/lib/presentation/screens/chatting/view/chat_screen.dart index 5bf4f73..ef5b78c 100644 --- a/lib/presentation/screens/chatting/view/chat_screen.dart +++ b/lib/presentation/screens/chatting/view/chat_screen.dart @@ -56,9 +56,8 @@ class ChatScreen extends StatelessWidget { elevation: 0, ), extendBodyBehindAppBar: false, - body: Obx(() { - return Container( - color: viewModel.backgroundColor.value, // Update background color based on emotion + body: Container( + color: Colors.white, child: Stack( children: [ Column( @@ -66,9 +65,9 @@ class ChatScreen extends StatelessWidget { Expanded( child: Obx(() { return viewModel.messages.isEmpty - ? const Center( + ? Center( child: Text( - 'No messages yet.', + '메시지가 없습니다.', style: TextStyle(color: Colors.black), ), ) @@ -97,8 +96,7 @@ class ChatScreen extends StatelessWidget { ), ], ), - ); - }), + ) ), ); } diff --git a/lib/presentation/screens/mypage/controller/mypage_viewmodel.dart b/lib/presentation/screens/mypage/controller/mypage_viewmodel.dart index e3ad2ed..d158064 100644 --- a/lib/presentation/screens/mypage/controller/mypage_viewmodel.dart +++ b/lib/presentation/screens/mypage/controller/mypage_viewmodel.dart @@ -1,29 +1,35 @@ - import 'package:get/get.dart'; -import 'package:palink_v2/domain/usecase/get_user_usecase.dart'; +import 'package:palink_v2/domain/usecase/get_user_info_usecase.dart'; class MypageViewModel extends GetxController { - final GetUserUseCase getUserUseCase; + final GetUserInfoUseCase getUserInfoUseCase; - var userId = ''.obs; + var accountId = ''.obs; var name = ''.obs; var age = 0.obs; var personalityType = ''.obs; - MypageViewModel({required this.getUserUseCase}); + MypageViewModel({required this.getUserInfoUseCase}); @override void onInit() { super.onInit(); loadUserData(); - print('MypageViewmodel onInit'); } void loadUserData() async { - userId.value = await getUserUseCase.getUserId(); - name.value = await getUserUseCase.getName(); - age.value = await getUserUseCase.getAge(); - personalityType.value = await getUserUseCase.getPersonalityType(); + try { + final user = await getUserInfoUseCase.execute(); + if (user != null) { + accountId.value = user.accountId.toString(); + name.value = user.name; + age.value = user.age; + personalityType.value = user.personalityType; + } else { + Get.snackbar('Error', 'Failed to load user data'); + } + } catch (e) { + Get.snackbar('Error', 'An error occurred while loading user data'); + } } - -} \ No newline at end of file +} diff --git a/lib/presentation/screens/mypage/view/component/user_info_section.dart b/lib/presentation/screens/mypage/view/component/user_info_section.dart index 2911125..c785d72 100644 --- a/lib/presentation/screens/mypage/view/component/user_info_section.dart +++ b/lib/presentation/screens/mypage/view/component/user_info_section.dart @@ -17,7 +17,7 @@ class UserInfoCard extends StatelessWidget { padding: const EdgeInsets.all(8.0), child: Column( children: [ - Obx(() => _buildUserInfo('내 아이디', mypageViewmodel.userId.value)), + Obx(() => _buildUserInfo('내 아이디', mypageViewmodel.accountId.value)), Obx(() => _buildUserInfo('내 나이', mypageViewmodel.age.value.toString())), Obx(() => _buildUserInfo('내 MBTI', mypageViewmodel.personalityType.value)), ],