✨
This commit is contained in:
191
StopShopping.Services/Implementions/RequestService.cs
Normal file
191
StopShopping.Services/Implementions/RequestService.cs
Normal file
@@ -0,0 +1,191 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using StopShopping.EF;
|
||||
using StopShopping.Services.Extensions;
|
||||
using StopShopping.Services.Models;
|
||||
using StopShopping.Services.Models.Req;
|
||||
using StopShopping.Services.Models.Resp;
|
||||
|
||||
namespace StopShopping.Services.Implementions;
|
||||
|
||||
public class RequestService : IRequestService
|
||||
{
|
||||
public RequestService(
|
||||
StopShoppingContext dbContext,
|
||||
IClaimsService claimsService,
|
||||
ISerialNoGenerator serialNoGenerator)
|
||||
{
|
||||
_dbContext = dbContext;
|
||||
_claimService = claimsService;
|
||||
_serialNoGenerator = serialNoGenerator;
|
||||
}
|
||||
|
||||
private readonly StopShoppingContext _dbContext;
|
||||
private readonly IClaimsService _claimService;
|
||||
private readonly ISerialNoGenerator _serialNoGenerator;
|
||||
|
||||
public async Task<ApiResponse> PublishRequestAsync(CreateRequestParams model)
|
||||
{
|
||||
var serialNo = _serialNoGenerator.GenerateRequestNo();
|
||||
var userId = _claimService.GetCurrentUserId();
|
||||
|
||||
EF.Models.Request req = new()
|
||||
{
|
||||
CategoryId = model.CategoryId,
|
||||
Deadline = DateOnly.Parse(model.Deadline),
|
||||
Description = model.Description,
|
||||
Name = model.Name,
|
||||
PublisherId = userId,
|
||||
SerialNo = serialNo,
|
||||
Status = (short)RequestStatus.Publish,
|
||||
};
|
||||
|
||||
await _dbContext.Requests.AddAsync(req);
|
||||
await _dbContext.SaveChangesAsync();
|
||||
|
||||
return ApiResponse.Succed();
|
||||
}
|
||||
|
||||
public async Task<ApiResponse<PagedResult<Request>>> SearchAsync(RequestSearchParams model)
|
||||
{
|
||||
return await DoSearchAsync(model, null);
|
||||
}
|
||||
|
||||
public async Task<ApiResponse<PagedResult<Request>>> RequestOrderSearchAsync(RequestSearchWithStatusParams model)
|
||||
{
|
||||
return await DoSearchAsync(model, UserRoles.Buyer);
|
||||
}
|
||||
|
||||
public async Task<ApiResponse<PagedResult<Request>>> ReplyOrderSearchAsync(RequestSearchWithStatusParams model)
|
||||
{
|
||||
return await DoSearchAsync(model, UserRoles.Seller);
|
||||
}
|
||||
|
||||
public async Task<ApiResponse> DeleteRequestAsync(RequestIdParams model)
|
||||
{
|
||||
var userId = _claimService.GetCurrentUserId();
|
||||
|
||||
var request = await _dbContext.Requests
|
||||
.Include(r => r.Replies)
|
||||
.Where(r => r.Id == model.RequestId && !r.Deleted)
|
||||
.FirstOrDefaultAsync();
|
||||
|
||||
if (null == request)
|
||||
return ApiResponse.Failed("此需求已不存在,请刷新重试");
|
||||
|
||||
var status = (RequestStatus)request.Status;
|
||||
if (status.CanDelete())
|
||||
return ApiResponse.Failed("此需求状态已改变,请刷新重试");
|
||||
|
||||
request.Deleted = true;
|
||||
request.Status = (short)RequestStatus.Completed;
|
||||
|
||||
foreach (var reply in request.Replies)
|
||||
{
|
||||
reply.Rejected = true;
|
||||
}
|
||||
|
||||
await _dbContext.SaveChangesAsync();
|
||||
|
||||
return ApiResponse.Succed();
|
||||
}
|
||||
|
||||
private async Task<ApiResponse<PagedResult<Request>>> DoSearchAsync<T>(T model, UserRoles? userRoles)
|
||||
where T : RequestSearchParams, new()
|
||||
{
|
||||
var qry = _dbContext.Requests
|
||||
.AsNoTracking()
|
||||
.Where(q => !q.Deleted);
|
||||
|
||||
if (model is RequestSearchWithStatusParams statusParams)
|
||||
{
|
||||
if (statusParams.Status != RequestStatus.All)
|
||||
qry = qry.Where(q => q.Status == (short)statusParams.Status);
|
||||
}
|
||||
else
|
||||
{
|
||||
qry = qry.Where(q => q.Status == (short)RequestStatus.Publish
|
||||
|| q.Status == (short)RequestStatus.Replied);
|
||||
}
|
||||
|
||||
if (model.CategoryId > 0)
|
||||
{
|
||||
string categoryPath = $"/{model.CategoryId.Value}/";
|
||||
qry = qry.Where(q =>
|
||||
_dbContext.Categories
|
||||
.Where(c => c.Path.StartsWith(categoryPath) && !c.Deleted)
|
||||
.Select(c => c.Id)
|
||||
.Contains(q.CategoryId));
|
||||
}
|
||||
if (!string.IsNullOrEmpty(model.Keyword))
|
||||
{
|
||||
qry = qry.Where(q =>
|
||||
q.Name.Contains(model.Keyword)
|
||||
|| (q.Description != null && q.Description.Contains(model.Keyword))
|
||||
|| q.SerialNo.Contains(model.Keyword));
|
||||
}
|
||||
|
||||
if (userRoles.HasValue)
|
||||
{
|
||||
var userId = _claimService.GetCurrentUserId();
|
||||
qry = userRoles.Value switch
|
||||
{
|
||||
UserRoles.Seller => qry.Where(q => q.Replies.Any(r => r.UserId == userId)),
|
||||
UserRoles.Buyer => qry.Where(q => q.PublisherId == userId),
|
||||
_ => qry
|
||||
};
|
||||
}
|
||||
|
||||
var firstOrderBy = model.OrderBys!.First();
|
||||
var included = qry
|
||||
.Include(r => r.Publisher).AsNoTracking()
|
||||
.Include(r => r.Category).AsNoTracking()
|
||||
.Select(r => new
|
||||
{
|
||||
ReplyAmount = r.Replies.Count,
|
||||
r
|
||||
});
|
||||
|
||||
var ordered = firstOrderBy switch
|
||||
{
|
||||
RequestOrderBys.PublishTime => included.OrderBy(q => q.r.PublishTime),
|
||||
RequestOrderBys.PublishTimeDesc => included.OrderByDescending(q => q.r.PublishTime),
|
||||
RequestOrderBys.CategoryId => included.OrderBy(q => q.r.CategoryId),
|
||||
RequestOrderBys.CategoryIdDesc => included.OrderByDescending(q => q.r.CategoryId),
|
||||
RequestOrderBys.ReplyAmount => included.OrderBy(q => q.ReplyAmount),
|
||||
RequestOrderBys.ReplyAmountDesc => included.OrderByDescending(q => q.ReplyAmount),
|
||||
_ => included.OrderBy(q => q.r.PublishTime)
|
||||
};
|
||||
|
||||
foreach (var orderBy in model.OrderBys!.Skip(1))
|
||||
{
|
||||
ordered = orderBy switch
|
||||
{
|
||||
RequestOrderBys.PublishTime => ordered!.ThenBy(q => q.r.PublishTime),
|
||||
RequestOrderBys.PublishTimeDesc => ordered!.ThenByDescending(q => q.r.PublishTime),
|
||||
RequestOrderBys.CategoryId => ordered!.ThenBy(q => q.r.CategoryId),
|
||||
RequestOrderBys.CategoryIdDesc => ordered!.ThenByDescending(q => q.r.CategoryId),
|
||||
RequestOrderBys.ReplyAmount => ordered!.ThenBy(q => q.ReplyAmount),
|
||||
RequestOrderBys.ReplyAmountDesc => ordered!.ThenByDescending(q => q.ReplyAmount),
|
||||
_ => ordered!.ThenBy(q => q.r.PublishTime)
|
||||
};
|
||||
}
|
||||
|
||||
var paged = await ordered.Select(r => new Request
|
||||
{
|
||||
CategoryId = r.r.Category.Id,
|
||||
CategoryName = r.r.Category.Name,
|
||||
Deadline = r.r.Deadline.ToFormatted(),
|
||||
Description = r.r.Description,
|
||||
Id = r.r.Id,
|
||||
Name = r.r.Name,
|
||||
Publisher = r.r.Publisher.NickName,
|
||||
PublishTime = r.r.PublishTime.ToFormatted(),
|
||||
ReplyAmount = r.ReplyAmount,
|
||||
SerialNo = r.r.SerialNo,
|
||||
Status = (RequestStatus)r.r.Status,
|
||||
|
||||
}).ToAsyncEnumerable().ToPagedAsync(model.PageIndex, model.PageSize);
|
||||
|
||||
return new ApiResponse<PagedResult<Request>>(paged);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user