Award post

This commit is contained in:
2025-09-06 11:19:23 +08:00
parent 5e328509bd
commit 6eacfcd8f2
8 changed files with 182 additions and 16 deletions

View File

@@ -1,4 +1,5 @@
using System.ComponentModel.DataAnnotations;
using System.Globalization;
using DysonNetwork.Shared.Auth;
using DysonNetwork.Shared.Content;
using DysonNetwork.Shared.Data;
@@ -24,6 +25,7 @@ public class PostController(
PublisherService pub,
AccountService.AccountServiceClient accounts,
ActionLogService.ActionLogServiceClient als,
PaymentService.PaymentServiceClient payments,
PollService polls,
RealmService rs
)
@@ -324,7 +326,6 @@ public class PostController(
.OrderByDescending(p => p.CreatedAt)
.FilterWithVisibility(currentUser, userFriends, userPublishers)
.ToListAsync();
if (posts is null) return NotFound();
posts = await ps.LoadPostInfo(posts, currentUser);
return Ok(posts);
@@ -582,14 +583,22 @@ public class PostController(
public class PostAwardRequest
{
public decimal Amount { get; set; }
public PostReactionAttitude Attitude { get; set; }
[MaxLength(4096)] public string? Message { get; set; }
}
public class PostAwardResponse
{
public Guid OrderId { get; set; }
}
[HttpPost("{id:guid}/awards")]
[Authorize]
public async Task<ActionResult<PostAward>> AwardPost(Guid id, [FromBody] PostAwardRequest request)
public async Task<ActionResult<PostAwardResponse>> AwardPost(Guid id, [FromBody] PostAwardRequest request)
{
if (HttpContext.Items["CurrentUser"] is not Account currentUser) return Unauthorized();
if (request.Attitude == PostReactionAttitude.Neutral)
return BadRequest("You cannot create a neutral post award");
var friendsResponse =
await accounts.ListFriendsAsync(new ListRelationshipSimpleRequest
@@ -605,10 +614,27 @@ public class PostController(
if (post is null) return NotFound();
var accountId = Guid.Parse(currentUser.Id);
// TODO Make payment, add record
return Ok();
var orderRemark = string.IsNullOrWhiteSpace(post.Title) ? "from @" + post.Publisher.Name : post.Title;
var order = await payments.CreateOrderAsync(new CreateOrderRequest
{
ProductIdentifier = "posts.award",
Currency = "points", // NSP - Source Points
Remarks = $"Award post {orderRemark}",
Meta = GrpcTypeHelper.ConvertObjectToByteString(new Dictionary<string, object?>()
{
["account_id"] = accountId,
["post_id"] = post.Id,
["amount"] = request.Amount.ToString(CultureInfo.InvariantCulture),
["message"] = request.Message,
["attitude"] = request.Attitude,
})
});
return Ok(new PostAwardResponse()
{
OrderId = Guid.Parse(order.Id),
});
}
public class PostPinRequest

View File

@@ -424,10 +424,12 @@ public partial class PostService(
var accountId = Guid.Parse(currentUser.Id);
if (post.RepliedPostId != null)
{
if (pinMode != PostPinMode.ReplyPage) throw new InvalidOperationException("Replies can only be pinned in the reply page.");
if (pinMode != PostPinMode.ReplyPage)
throw new InvalidOperationException("Replies can only be pinned in the reply page.");
if (post.RepliedPost == null) throw new ArgumentNullException(nameof(post.RepliedPost));
if (!await ps.IsMemberWithRole(post.RepliedPost.PublisherId, accountId, Publisher.PublisherMemberRole.Editor))
if (!await ps.IsMemberWithRole(post.RepliedPost.PublisherId, accountId,
Publisher.PublisherMemberRole.Editor))
throw new InvalidOperationException("Only editors of original post can pin replies.");
post.PinMode = pinMode;
@@ -453,7 +455,8 @@ public partial class PostService(
{
if (post.RepliedPost == null) throw new ArgumentNullException(nameof(post.RepliedPost));
if (!await ps.IsMemberWithRole(post.RepliedPost.PublisherId, accountId, Publisher.PublisherMemberRole.Editor))
if (!await ps.IsMemberWithRole(post.RepliedPost.PublisherId, accountId,
Publisher.PublisherMemberRole.Editor))
throw new InvalidOperationException("Only editors of original post can unpin replies.");
}
else
@@ -815,9 +818,10 @@ public partial class PostService(
{
// The previous day highest rated posts
var today = SystemClock.Instance.GetCurrentInstant();
var periodStart = today.InUtc().Date.AtStartOfDayInZone(DateTimeZone.Utc).ToInstant().Minus(Duration.FromDays(1));
var periodStart = today.InUtc().Date.AtStartOfDayInZone(DateTimeZone.Utc).ToInstant()
.Minus(Duration.FromDays(1));
var periodEnd = today.InUtc().Date.AtStartOfDayInZone(DateTimeZone.Utc).ToInstant();
var postsInPeriod = await db.Posts
.Where(e => e.Visibility == PostVisibility.Public)
.Where(e => e.CreatedAt >= periodStart && e.CreatedAt < periodEnd)
@@ -890,6 +894,34 @@ public partial class PostService(
return posts;
}
public async Task<PostAward> AwardPost(
Guid postId,
Guid accountId,
decimal amount,
PostReactionAttitude attitude,
string? message
)
{
var award = new PostAward
{
Amount = amount,
Attitude = attitude,
Message = message,
PostId = postId,
AccountId = accountId
};
db.PostAwards.Add(award);
await db.SaveChangesAsync();
var delta = award.Attitude == PostReactionAttitude.Positive ? amount : -amount;
await db.Posts.Where(p => p.Id == postId)
.ExecuteUpdateAsync(s => s.SetProperty(p => p.AwardedScore, p => p.AwardedScore + delta));
return award;
}
}
public static class PostQueryExtensions
@@ -925,4 +957,4 @@ public static class PostQueryExtensions
(e.Publisher.AccountId != null && userFriends.Contains(e.Publisher.AccountId.Value)) ||
publishersId.Contains(e.PublisherId));
}
}
}