|
@@ -52,6 +52,86 @@ namespace Kitty_Fall.Website.Controllers
|
|
|
return Json(new { success = true });
|
|
return Json(new { success = true });
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ [HttpPost]
|
|
|
|
|
+ [RequestSizeLimit(5 * 1024 * 1024)]
|
|
|
|
|
+ public async Task<IActionResult> UpdateProfile(string? fullName, IFormFile? avatar)
|
|
|
|
|
+ {
|
|
|
|
|
+ var msisdn = HttpContext.Session.GetComplexData<string>("msisdn") ?? "";
|
|
|
|
|
+ var apiToken = HttpContext.Session.GetString("apiToken");
|
|
|
|
|
+ var baseUrl = GetParameter("url");
|
|
|
|
|
+ var normalizedName = fullName?.Trim() ?? "";
|
|
|
|
|
+
|
|
|
|
|
+ if (string.IsNullOrWhiteSpace(msisdn) || string.IsNullOrWhiteSpace(apiToken))
|
|
|
|
|
+ return Unauthorized(new { success = false, message = "Please login again." });
|
|
|
|
|
+ if (normalizedName.Length > 100)
|
|
|
|
|
+ return BadRequest(new { success = false, message = "Full name must not exceed 100 characters." });
|
|
|
|
|
+ if (string.IsNullOrWhiteSpace(normalizedName) && avatar == null)
|
|
|
|
|
+ return BadRequest(new { success = false, message = "Please enter a full name or select an avatar." });
|
|
|
|
|
+
|
|
|
|
|
+ string? picture = null;
|
|
|
|
|
+ if (avatar is { Length: > 0 })
|
|
|
|
|
+ {
|
|
|
|
|
+ if (avatar.Length > 5 * 1024 * 1024)
|
|
|
|
|
+ return BadRequest(new { success = false, message = "Avatar must not exceed 5 MB." });
|
|
|
|
|
+
|
|
|
|
|
+ var allowedTypes = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
|
|
|
|
|
+ {
|
|
|
|
|
+ ["image/jpeg"] = ".jpg", ["image/png"] = ".png", ["image/webp"] = ".webp"
|
|
|
|
|
+ };
|
|
|
|
|
+ if (!allowedTypes.TryGetValue(avatar.ContentType, out var extension))
|
|
|
|
|
+ return BadRequest(new { success = false, message = "Only JPG, PNG or WEBP images are supported." });
|
|
|
|
|
+
|
|
|
|
|
+ var avatarDirectory = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "kitty", "assets", "kitty-fall", "avatar");
|
|
|
|
|
+ Directory.CreateDirectory(avatarDirectory);
|
|
|
|
|
+ var fileName = $"{DateTime.UtcNow:yyyyMMddHHmmss}-{Guid.NewGuid():N}{extension}";
|
|
|
|
|
+ await using var stream = System.IO.File.Create(Path.Combine(avatarDirectory, fileName));
|
|
|
|
|
+ await avatar.CopyToAsync(stream);
|
|
|
|
|
+ picture = $"avatar/{fileName}";
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ try
|
|
|
|
|
+ {
|
|
|
|
|
+ var language = GetCurrentLanguage();
|
|
|
|
|
+ var postTask = DotnetLib.Rest.RestHandler.SendPostWithAuthen(
|
|
|
|
|
+ log,
|
|
|
|
|
+ baseUrl + UrlConstant.UserUpdateProfileUrl,
|
|
|
|
|
+ new UserUpdateProfileReq
|
|
|
|
|
+ {
|
|
|
|
|
+ msisdn = msisdn,
|
|
|
|
|
+ fullname = string.IsNullOrWhiteSpace(normalizedName) ? null : normalizedName,
|
|
|
|
|
+ picture = picture
|
|
|
|
|
+ },
|
|
|
|
|
+ apiToken,
|
|
|
|
|
+ "",
|
|
|
|
|
+ "",
|
|
|
|
|
+ language
|
|
|
|
|
+ );
|
|
|
|
|
+ if (postTask == null)
|
|
|
|
|
+ {
|
|
|
|
|
+ return BadRequest(new { success = false, message = "Profile update API returned empty response." });
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ ReturnDataPost? response = await postTask;
|
|
|
|
|
+ if (response?.data == null)
|
|
|
|
|
+ {
|
|
|
|
|
+ return BadRequest(new { success = false, message = "Profile update API returned empty response." });
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ var result = JObject.Parse(response.data);
|
|
|
|
|
+ if (ReadErrorCode(result) != CommonErrorCode.SUCCESS)
|
|
|
|
|
+ return BadRequest(new { success = false, message = result["message"]?.ToString() ?? "Profile update failed." });
|
|
|
|
|
+
|
|
|
|
|
+ if (!string.IsNullOrWhiteSpace(normalizedName)) HttpContext.Session.SetComplexData("fullName", normalizedName);
|
|
|
|
|
+ if (!string.IsNullOrWhiteSpace(picture)) HttpContext.Session.SetComplexData("profilePicture", picture);
|
|
|
|
|
+ return Json(new { success = true, fullName = normalizedName, picture });
|
|
|
|
|
+ }
|
|
|
|
|
+ catch (Exception ex)
|
|
|
|
|
+ {
|
|
|
|
|
+ log.Error("UpdateProfile error: ", ex);
|
|
|
|
|
+ return StatusCode(500, new { success = false, message = "Profile update failed." });
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
[HttpPost]
|
|
[HttpPost]
|
|
|
public async Task<IActionResult> RegisterQAction(string? productName)
|
|
public async Task<IActionResult> RegisterQAction(string? productName)
|
|
|
{
|
|
{
|
|
@@ -136,6 +216,75 @@ namespace Kitty_Fall.Website.Controllers
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ [HttpPost]
|
|
|
|
|
+ public async Task<IActionResult> CancelPackage(string? packageName)
|
|
|
|
|
+ {
|
|
|
|
|
+ var msisdn = HttpContext.Session.GetComplexData<string>("msisdn") ?? "";
|
|
|
|
|
+ var apiToken = HttpContext.Session.GetString("apiToken");
|
|
|
|
|
+ var normalizedPackageName = packageName?.Trim() ?? "";
|
|
|
|
|
+
|
|
|
|
|
+ if (string.IsNullOrWhiteSpace(msisdn) || string.IsNullOrWhiteSpace(apiToken))
|
|
|
|
|
+ return Unauthorized(new { success = false, message = "Please login again." });
|
|
|
|
|
+ if (string.IsNullOrWhiteSpace(normalizedPackageName))
|
|
|
|
|
+ return BadRequest(new { success = false, message = "No active package was selected." });
|
|
|
|
|
+
|
|
|
|
|
+ try
|
|
|
|
|
+ {
|
|
|
|
|
+ var language = GetCurrentLanguage();
|
|
|
|
|
+ var postTask = DotnetLib.Rest.RestHandler.SendPostWithAuthen(
|
|
|
|
|
+ log,
|
|
|
|
|
+ GetParameter("url") + UrlConstant.UserDisableRegisterUrl,
|
|
|
|
|
+ new UserRegisterReq
|
|
|
|
|
+ {
|
|
|
|
|
+ msisdn = msisdn,
|
|
|
|
|
+ packageName = normalizedPackageName,
|
|
|
|
|
+ language = language
|
|
|
|
|
+ },
|
|
|
|
|
+ apiToken,
|
|
|
|
|
+ "",
|
|
|
|
|
+ "",
|
|
|
|
|
+ language
|
|
|
|
|
+ );
|
|
|
|
|
+ if (postTask == null)
|
|
|
|
|
+ return BadRequest(new { success = false, message = "Cancel package API returned empty response." });
|
|
|
|
|
+
|
|
|
|
|
+ ReturnDataPost? response = await postTask;
|
|
|
|
|
+ if (response?.data == null)
|
|
|
|
|
+ return BadRequest(new { success = false, message = "Cancel package API returned empty response." });
|
|
|
|
|
+
|
|
|
|
|
+ var result = JObject.Parse(response.data);
|
|
|
|
|
+ if (ReadErrorCode(result) != CommonErrorCode.SUCCESS)
|
|
|
|
|
+ return BadRequest(new { success = false, message = result["message"]?.ToString() ?? "Package cancellation failed." });
|
|
|
|
|
+
|
|
|
|
|
+ var regInfos = HttpContext.Session.GetComplexData<JArray>("regInfos");
|
|
|
|
|
+ if (regInfos != null)
|
|
|
|
|
+ {
|
|
|
|
|
+ foreach (var item in regInfos
|
|
|
|
|
+ .Where(x => string.Equals(
|
|
|
|
|
+ (x["productName"] ?? x["ProductName"])?.ToString(),
|
|
|
|
|
+ normalizedPackageName,
|
|
|
|
|
+ StringComparison.OrdinalIgnoreCase))
|
|
|
|
|
+ .ToList())
|
|
|
|
|
+ {
|
|
|
|
|
+ item["status"] = false;
|
|
|
|
|
+ item["renew"] = 0;
|
|
|
|
|
+ }
|
|
|
|
|
+ HttpContext.Session.SetComplexData("regInfos", regInfos);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return Json(new
|
|
|
|
|
+ {
|
|
|
|
|
+ success = true,
|
|
|
|
|
+ message = result["message"]?.ToString() ?? "Package cancelled successfully."
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ catch (Exception ex)
|
|
|
|
|
+ {
|
|
|
|
|
+ log.Error("CancelPackage error: ", ex);
|
|
|
|
|
+ return StatusCode(500, new { success = false, message = "Package cancellation failed." });
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
[HttpPost]
|
|
[HttpPost]
|
|
|
public async Task<IActionResult> BuyTurnQAction(string? productName)
|
|
public async Task<IActionResult> BuyTurnQAction(string? productName)
|
|
|
{
|
|
{
|
|
@@ -227,11 +376,13 @@ namespace Kitty_Fall.Website.Controllers
|
|
|
{
|
|
{
|
|
|
var msisdn = HttpContext.Session.GetComplexData<string>("msisdn") ?? "";
|
|
var msisdn = HttpContext.Session.GetComplexData<string>("msisdn") ?? "";
|
|
|
var profilePicture = HttpContext.Session.GetComplexData<string>("profilePicture") ?? "";
|
|
var profilePicture = HttpContext.Session.GetComplexData<string>("profilePicture") ?? "";
|
|
|
|
|
+ var fullName = HttpContext.Session.GetComplexData<string>("fullName") ?? "";
|
|
|
var totalTurn = HttpContext.Session.GetComplexData<long?>("totalTurn") ?? 0;
|
|
var totalTurn = HttpContext.Session.GetComplexData<long?>("totalTurn") ?? 0;
|
|
|
var totalPoint = HttpContext.Session.GetComplexData<long?>("totalPoint") ?? 0;
|
|
var totalPoint = HttpContext.Session.GetComplexData<long?>("totalPoint") ?? 0;
|
|
|
|
|
|
|
|
ViewBag.Msisdn = msisdn;
|
|
ViewBag.Msisdn = msisdn;
|
|
|
ViewBag.ProfilePicture = profilePicture;
|
|
ViewBag.ProfilePicture = profilePicture;
|
|
|
|
|
+ ViewBag.FullName = fullName;
|
|
|
ViewBag.TotalTurn = totalTurn;
|
|
ViewBag.TotalTurn = totalTurn;
|
|
|
ViewBag.TotalPoint = totalPoint;
|
|
ViewBag.TotalPoint = totalPoint;
|
|
|
|
|
|
|
@@ -285,6 +436,9 @@ namespace Kitty_Fall.Website.Controllers
|
|
|
var loadedPicture = accountUser?["picture"]?.ToString()
|
|
var loadedPicture = accountUser?["picture"]?.ToString()
|
|
|
?? accountUser?["Picture"]?.ToString()
|
|
?? accountUser?["Picture"]?.ToString()
|
|
|
?? profilePicture;
|
|
?? profilePicture;
|
|
|
|
|
+ var loadedFullName = accountUser?["fullname"]?.ToString()
|
|
|
|
|
+ ?? accountUser?["Fullname"]?.ToString()
|
|
|
|
|
+ ?? fullName;
|
|
|
var loadedTurn = ReadLong(data?["totalTurn"] ?? data?["TotalTurn"]);
|
|
var loadedTurn = ReadLong(data?["totalTurn"] ?? data?["TotalTurn"]);
|
|
|
var loadedPoint = ReadLong(
|
|
var loadedPoint = ReadLong(
|
|
|
data?["totalPoint"]
|
|
data?["totalPoint"]
|
|
@@ -299,6 +453,7 @@ namespace Kitty_Fall.Website.Controllers
|
|
|
|
|
|
|
|
HttpContext.Session.SetComplexData("msisdn", loadedMsisdn);
|
|
HttpContext.Session.SetComplexData("msisdn", loadedMsisdn);
|
|
|
HttpContext.Session.SetComplexData("profilePicture", loadedPicture);
|
|
HttpContext.Session.SetComplexData("profilePicture", loadedPicture);
|
|
|
|
|
+ HttpContext.Session.SetComplexData("fullName", loadedFullName);
|
|
|
HttpContext.Session.SetComplexData("totalTurn", loadedTurn);
|
|
HttpContext.Session.SetComplexData("totalTurn", loadedTurn);
|
|
|
HttpContext.Session.SetComplexData("totalPoint", loadedPoint);
|
|
HttpContext.Session.SetComplexData("totalPoint", loadedPoint);
|
|
|
HttpContext.Session.SetComplexData("totalDataMb", loadedDataMb);
|
|
HttpContext.Session.SetComplexData("totalDataMb", loadedDataMb);
|
|
@@ -310,6 +465,7 @@ namespace Kitty_Fall.Website.Controllers
|
|
|
|
|
|
|
|
ViewBag.Msisdn = loadedMsisdn;
|
|
ViewBag.Msisdn = loadedMsisdn;
|
|
|
ViewBag.ProfilePicture = loadedPicture;
|
|
ViewBag.ProfilePicture = loadedPicture;
|
|
|
|
|
+ ViewBag.FullName = loadedFullName;
|
|
|
ViewBag.TotalTurn = loadedTurn;
|
|
ViewBag.TotalTurn = loadedTurn;
|
|
|
ViewBag.TotalPoint = loadedPoint;
|
|
ViewBag.TotalPoint = loadedPoint;
|
|
|
}
|
|
}
|