SKE-66 save points

This commit is contained in:
Przemysław Stawujak 2019-01-03 13:28:52 +01:00
parent 9ecd87db5d
commit 180830c921
9 changed files with 222 additions and 6 deletions

View File

@ -3,12 +3,14 @@ import { appModuleAnimation } from '@shared/animations/routerTransition';
import { AppComponentBase } from '@shared/app-component-base';
import { Subscription } from 'rxjs/Rx';
import { ActivatedRoute } from '@angular/router';
import { mergeMap } from 'rxjs/operators';
import { finalize } from 'rxjs/operators';
import { forkJoin } from 'rxjs';
import { CompetitionServiceProxy,
CompetitionDto,
QuestionDto,
QuestionOptionDto } from '@shared/service-proxies/service-proxies';
QuestionOptionDto,
CreateRankingPositionDto } from '@shared/service-proxies/service-proxies';
@Component({
templateUrl: './competition-detail.component.html',
@ -19,6 +21,7 @@ export class CompetitionDetailComponent extends AppComponentBase implements OnIn
private paramSubscription: Subscription;
private routeSubscription: Subscription;
private solveSubscription: Subscription;
public competitionId: number;
public competition: CompetitionDto = null;
@ -121,7 +124,23 @@ export class CompetitionDetailComponent extends AppComponentBase implements OnIn
) points += 1;
});
console.log('Punkty: ' + points);
console.log('Points: ' + points);
let rankingPosition = new CreateRankingPositionDto();
rankingPosition.competitionId = this.competitionId;
rankingPosition.points = points;
this.setBusy(this.competitionDetailAreaId);
this.solveSubscription = this._competitionService.solveCompetition(rankingPosition)
.pipe(mergeMap((result: number) => {
const solveCompetitionStream = this._competitionService.canSolveCompetition(this.competitionId);
return solveCompetitionStream.pipe(finalize(() => { this.clearBusy(this.competitionDetailAreaId); }));
}))
.subscribe((data: boolean) => {
this.canSolveCompetition = data;
});
this.mode = 'result';
}
@ -133,6 +152,10 @@ export class CompetitionDetailComponent extends AppComponentBase implements OnIn
if (this.routeSubscription) {
this.routeSubscription.unsubscribe();
}
if (this.solveSubscription) {
this.solveSubscription.unsubscribe();
}
}
}

View File

@ -329,6 +329,62 @@ export class CompetitionServiceProxy {
return _observableOf<CompetitionDto>(<any>null);
}
/**
* @input (optional)
* @return Success
*/
solveCompetition(input: CreateRankingPositionDto | null | undefined): Observable<number> {
let url_ = this.baseUrl + "/api/services/app/Competition/SolveCompetition";
url_ = url_.replace(/[?&]$/, "");
const content_ = JSON.stringify(input);
let options_ : any = {
body: content_,
observe: "response",
responseType: "blob",
headers: new HttpHeaders({
"Content-Type": "application/json",
"Accept": "application/json"
})
};
return this.http.request("post", url_, options_).pipe(_observableMergeMap((response_ : any) => {
return this.processSolveCompetition(response_);
})).pipe(_observableCatch((response_: any) => {
if (response_ instanceof HttpResponseBase) {
try {
return this.processSolveCompetition(<any>response_);
} catch (e) {
return <Observable<number>><any>_observableThrow(e);
}
} else
return <Observable<number>><any>_observableThrow(response_);
}));
}
protected processSolveCompetition(response: HttpResponseBase): Observable<number> {
const status = response.status;
const responseBlob =
response instanceof HttpResponse ? response.body :
(<any>response).error instanceof Blob ? (<any>response).error : undefined;
let _headers: any = {}; if (response.headers) { for (let key of response.headers.keys()) { _headers[key] = response.headers.get(key); }};
if (status === 200) {
return blobToText(responseBlob).pipe(_observableMergeMap(_responseText => {
let result200: any = null;
let resultData200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver);
result200 = resultData200 !== undefined ? resultData200 : <any>null;
return _observableOf(result200);
}));
} else if (status !== 200 && status !== 204) {
return blobToText(responseBlob).pipe(_observableMergeMap(_responseText => {
return throwException("An unexpected server error occurred.", status, _responseText, _headers);
}));
}
return _observableOf<number>(<any>null);
}
/**
* @competitionId (optional)
* @return Success
@ -2508,6 +2564,53 @@ export interface IQuestionOptionDto {
id: number | undefined;
}
export class CreateRankingPositionDto implements ICreateRankingPositionDto {
competitionId: number | undefined;
points: number | undefined;
constructor(data?: ICreateRankingPositionDto) {
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
(<any>this)[property] = (<any>data)[property];
}
}
}
init(data?: any) {
if (data) {
this.competitionId = data["competitionId"];
this.points = data["points"];
}
}
static fromJS(data: any): CreateRankingPositionDto {
data = typeof data === 'object' ? data : {};
let result = new CreateRankingPositionDto();
result.init(data);
return result;
}
toJSON(data?: any) {
data = typeof data === 'object' ? data : {};
data["competitionId"] = this.competitionId;
data["points"] = this.points;
return data;
}
clone(): CreateRankingPositionDto {
const json = this.toJSON();
let result = new CreateRankingPositionDto();
result.init(json);
return result;
}
}
export interface ICreateRankingPositionDto {
competitionId: number | undefined;
points: number | undefined;
}
export class ChangeUiThemeInput implements IChangeUiThemeInput {
theme: string;

View File

@ -18,13 +18,15 @@ namespace SystemKonkursow.Competition.CompetitionCategory
private readonly IRepository<Domain.QuestionOption, int> _questionOptionRepository;
private readonly UserManager _userManager;
private readonly IRepository<Domain.Participant, int> _participantRepository;
private readonly IRepository<Domain.RankingPosition, int> _rankingPositionRepository;
public CompetitionAppService(IRepository<Domain.CompetitionCategory, int> competitionCategoryRepository,
IRepository<Domain.Competition, long> competitionRepository,
IRepository<Domain.Question, int> questionRepository,
IRepository<Domain.QuestionOption, int> questionOptionRepository,
UserManager userManager,
IRepository<Domain.Participant, int> participantRepository)
IRepository<Domain.Participant, int> participantRepository,
IRepository<Domain.RankingPosition, int> rankingPositionRepository)
{
_competitionCategoryRepository = competitionCategoryRepository;
_competitionRepository = competitionRepository;
@ -32,6 +34,7 @@ namespace SystemKonkursow.Competition.CompetitionCategory
_questionOptionRepository = questionOptionRepository;
_userManager = userManager;
_participantRepository = participantRepository;
_rankingPositionRepository = rankingPositionRepository;
}
[AbpAuthorize]
@ -123,6 +126,20 @@ namespace SystemKonkursow.Competition.CompetitionCategory
return mappedObject;
}
[AbpAuthorize]
public async Task<int> SolveCompetition(CreateRankingPositionDto input)
{
var user = await GetCurrentUserAsync();
var mappedRankingPosition = ObjectMapper.Map<Domain.RankingPosition>(input);
mappedRankingPosition.UserId = user.Id;
var newRankingPositionId = await _rankingPositionRepository.InsertAndGetIdAsync(mappedRankingPosition);
return newRankingPositionId;
}
[AbpAuthorize]
public async Task<bool> CanSolveCompetition(int competitionId)
{
@ -143,6 +160,13 @@ namespace SystemKonkursow.Competition.CompetitionCategory
return false;
}
var rankingPosition = await _rankingPositionRepository.GetAll().Where(t => t.UserId == user.Id).FirstOrDefaultAsync();
if (null != rankingPosition)
{
return false;
}
return true;
}

View File

@ -22,6 +22,8 @@ namespace SystemKonkursow.Competition.CompetitionCategory.Dto
CreateMap<Domain.Competition, CompetitionDto>()
.ForMember(dest => dest.CreatorName, opt => opt.MapFrom(src => src.Creator.UserName));
CreateMap<CreateRankingPositionDto, Domain.RankingPosition>();
}
}
}

View File

@ -0,0 +1,9 @@
namespace SystemKonkursow.Competition.CompetitionCategory.Dto
{
public class CreateRankingPositionDto
{
public long CompetitionId { get; set; }
public int Points { get; set; }
}
}

View File

@ -0,0 +1,22 @@
using Abp.Domain.Entities;
using System.ComponentModel.DataAnnotations.Schema;
using SystemKonkursow.Authorization.Users;
namespace SystemKonkursow.Domain
{
[Table("RankingPositions")]
public class RankingPosition : Entity<int>
{
public long UserId { get; set; }
public long CompetitionId { get; set; }
public int Points { get; set; }
[ForeignKey(nameof(UserId))]
public virtual User User { get; set; }
[ForeignKey(nameof(CompetitionId))]
public virtual Competition Competition { get; set; }
}
}

View File

@ -28,5 +28,7 @@ namespace SystemKonkursow.EntityFrameworkCore
public DbSet<Domain.QuestionOption> QuestionOptions { get; set; }
public DbSet<Domain.RankingPosition> RankingPositions { get; set; }
}
}

View File

@ -1134,6 +1134,27 @@ namespace SystemKonkursow.Migrations
b.ToTable("QuestionOptions");
});
modelBuilder.Entity("SystemKonkursow.Domain.RankingPosition", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<long>("CompetitionId");
b.Property<int>("Points");
b.Property<long>("UserId");
b.HasKey("Id");
b.HasIndex("CompetitionId");
b.HasIndex("UserId");
b.ToTable("RankingPositions");
});
modelBuilder.Entity("SystemKonkursow.MultiTenancy.Tenant", b =>
{
b.Property<int>("Id")
@ -1379,6 +1400,19 @@ namespace SystemKonkursow.Migrations
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("SystemKonkursow.Domain.RankingPosition", b =>
{
b.HasOne("SystemKonkursow.Domain.Competition", "Competition")
.WithMany()
.HasForeignKey("CompetitionId")
.OnDelete(DeleteBehavior.Cascade);
b.HasOne("SystemKonkursow.Authorization.Users.User", "User")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("SystemKonkursow.MultiTenancy.Tenant", b =>
{
b.HasOne("SystemKonkursow.Authorization.Users.User", "CreatorUser")

View File

@ -25,7 +25,4 @@
<ItemGroup>
<DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="2.0.0" />
</ItemGroup>
<ItemGroup>
<Folder Include="Migrations\" />
</ItemGroup>
</Project>