Files
ichni_Official/Assets/Scripts/Online/Network/Models/ApiResponse.cs
stevesensei 97c9fba14e feat(online): implement IchniOnline API integration with BestHTTP
- Add BestHTTP reference to IchniOnline.asmdef
- Create ApiClient.cs: HTTP singleton with JWT auto-injection
- Create ApiResponse.cs: ResponseCode enum, GlobalResponse<T>, ApiResult<T>
- Create AuthDtos.cs: ThirdPartyLoginRequestDto, LoginRequestDto, RegisterRequestDto, LoginResponseDto, UserResponseDto
- Create AuthService.cs: TapTap/password/register/logout flows with events
- Extend LoginCacheData.cs: JWT + server user data fields
- Extend LoginCacheManager.cs: SaveAuthSession, ClearSession, HasValidSession
- Extend ThirdPartyServiceManager.cs: OnLoginWithToken event for AuthService
- Update LoginPage.cs: Use AuthService with loading states and null-safe callbacks
- Update StartUIPage.cs: Use HasValidSession for session check

Fixes post-review:
- LoginPage: Add null check for Register success (response may be null)
- AuthService: Add try/catch around TapTap login API call
2026-06-15 16:56:00 +08:00

83 lines
2.4 KiB
C#

namespace IchniOnline.Online.Network.Models
{
using System;
[System.Serializable]
public enum ResponseCode
{
Ok = 10000,
BadRequest = 10400,
Unauthorized = 10401,
Forbidden = 10403,
NotFound = 10404,
InternalServerError = 10500
}
/// <summary>
/// Non-generic base class for Unity JsonUtility deserialization.
/// Concrete generic GlobalResponse<T> inherits from this.
/// </summary>
[System.Serializable]
public abstract class GlobalResponseBase
{
public ResponseCode Code;
public string Message;
}
/// <summary>
/// Generic server response wrapper. JsonUtility can deserialize this to the base class,
/// then cast to the concrete type for Data access.
/// </summary>
/// <typeparam name="T">Data payload type</typeparam>
[System.Serializable]
public class GlobalResponse<T> : GlobalResponseBase
{
public T Data;
}
/// <summary>
/// Unified API result wrapper with factory methods.
/// Note: JsonUtility doesn't support generic deserialization directly,
/// so use GlobalResponseBase for deserialization then wrap in ApiResult.
/// </summary>
/// <typeparam name="T">Data payload type</typeparam>
[System.Serializable]
public class ApiResult<T>
{
public bool IsSuccess => Code == ResponseCode.Ok;
public T Data { get; private set; }
public ResponseCode Code { get; private set; }
public string Message { get; private set; }
public string ErrorDetail { get; private set; }
private ApiResult() { }
public static ApiResult<T> Ok(T data)
{
return new ApiResult<T>
{
Data = data,
Code = ResponseCode.Ok,
Message = "Success",
ErrorDetail = null
};
}
public static ApiResult<T> Fail(ResponseCode code, string message, string detail = null)
{
return new ApiResult<T>
{
Data = default(T),
Code = code,
Message = message,
ErrorDetail = detail
};
}
public static ApiResult<T> Fail(int code, string message, string detail = null)
{
return Fail((ResponseCode)code, message, detail);
}
}
}