Прототип имплементација на случаите на употреба
Случаи на употреба кои се имплементирани до оваа фаза
ID | Име |
---|---|
1 | прелистување на секции за дискусија |
2 | корисничка најава |
3 | корисничка регистрација (делумно, без кор. интерфејс) |
4 | додавање мислење во секција за дискусија (делумно, само за професори) |
5 | оценување туѓо мислење |
6 | коментирање туѓо мислење |
Прелистување секции за дискусија (1)
За секој професор во базата постои соодветна секција за дискусија во која се содржани мислењата поврзани за него/неа. При отворање на страницата тие се преземаат со позадински повик (неавтентициран), а хиерархијата на коментари се прикажува со рекурзивно изминување на вратените податоци. Доколку има најавен корисник, се прикажуваат и опции за објавување ново мислење, како и давање реплика, правење upvote или downvote на постоечко мислење, реализирани со соодветни повици, пр. "GET /secure/professor/[professorId]/upvoteOpinion/[opinionId]".
Заради олеснета навигација помеѓу секциите за дискусија апликацијата содржи функционалност за пребарување.
Service.MainService.java, ревизија ebc5176
public List<Professor> getProfessorsByNameContains(String contained) { List<Professor> list = new ArrayList<>(); professorRepository.findByProfessorNameContainingIgnoreCase(contained).forEach(list::add); return list; }
Додавање мислења во секција за дискусија (4)
Во фазата прототип беше делумно имплементирано и сценариото за додавање мислења. Подолу се прикажани главните отсечоци од код каде се имплементирани чекорите кои ги презема системот при тригер на сценариото, односно:
1. Javascript апликацијата јавува modal со полиња за внес на содржина и наслов (условно, само ако се отвара нова тема за предмет)
2. Javascript апликацијата ги валидира полињата (дали некое е празно), по што праќа барање со споменатите полиња, кое на серверска страна го пречекува контролерот и наредува тек од повици што завршува со складирање на диск нова торка во соодветната релација (Post).
3. По добивање на одговорот, JS апликацијата го освежува прелистувачот, значи се прикажува истата страница за дискусија, но во одговорот на fetch повикот за мислењата кои и припаѓаат сега ќе се најде и новододаденото мислење
Service.MainService.java, ревизија ebc5176
public void addOpinion(String title, String content, Long professorId, CustomUserDetails currentUser) { Professor targetProfessor = professorRepository.findByProfessorId(professorId); Opinion opinionToAdd = new Opinion(title, content, currentUser, null, null, null, targetProfessor); opinionRepository.save(opinionToAdd); }
Оценување на туѓо мислење (5)
Во оваа фаза е имплементирано и сценариото за оценување мислења. Подолу се прикажани главните отсечоци од код каде се имплементирани чекорите кои ги презема системот при тригер на сценариото, односно:
1. Апликацијата на клиентска страна со самото вчитување на мислењата кои одговараат на секцијата има достапна во меморија листа од кориснички ИД-а кои го оцениле секое мислење. Врз основа на тоа кликот го игнорира (доколку ИД на моменталниот корисник е исто со некое ИД од листата), или праќа повик до серверот што резултира со додавање на ставка во релацијата што ги чува податоците за оцени (корисник-пост) и инкрементирање/декрементирање на кармата на авторот на корисникот.
Service.MainService.java, ревизија ebc5176
public void upvoteOpinion(Long postId, CustomUserDetails currentUser) { Opinion targetOpinion = opinionRepository.findByPostId(postId); if (!targetOpinion.getLikes().contains(currentUser)) { targetOpinion.getLikes().add(currentUser); // opinionRepository.save(targetOpinion); targetOpinion.getAuthor().setKarma(targetOpinion.getAuthor().getKarma() + 1); userRepository.save(targetOpinion.getAuthor()); currentUser.getLikedPosts().add(targetOpinion); userRepository.save(currentUser); } } public void downvoteOpinion(Long postId, CustomUserDetails currentUser) { Opinion targetOpinion = opinionRepository.findByPostId(postId); if (!targetOpinion.getDislikes().contains(currentUser)) { targetOpinion.getDislikes().add(currentUser); // opinionRepository.save(targetOpinion); targetOpinion.getAuthor().setKarma(targetOpinion.getAuthor().getKarma() - 1); userRepository.save(targetOpinion.getAuthor()); currentUser.getDislikedPosts().add(targetOpinion); userRepository.save(currentUser); } }
Коментирање туѓо мислење (6)
Имплементирана е и функционалноста за додавање реплики на мислења. Подолу се прикажани главните отсечоци од код каде се имплементирани чекорите кои ги презема системот при тригер на сценариото, односно:
1. Javascript апликацијата јавува modal со единствено поле за содржина на коментарот
2. Javascript апликацијата проверува дали полето е празно (ако е, не испраќа повик и рендерира порака за грешка), а потоа испраќа барање (кое во телото содржи ИД на засегнатото мислење и содржина на коментарот) до одредена патека на која реагира контролерот. Тој потоа повикува соодветен метод од сервисната логика, што резултира со зачувување на диск нова торка во релацијата за мислења (Post) со атрибут ИД на родител-мислење еднаков на ИД-то добиено во payload-от на барањето.
3. По добивање на одговорот, JS апликацијата го освежува прелистувачот, значи се прикажува истата страница за дискусија, но во одговорот на fetch повикот за мислењата кои и припаѓаат сега ќе се најде и новододадената реплика
Service.MainService.java, ревизија ebc5176
public void replyToOpinion(String content, Long professorId, Long postId, CustomUserDetails currentUser) { Professor targetProfessor = professorRepository.findByProfessorId(professorId); Opinion targetOpinion = opinionRepository.findByPostId(postId); Opinion opinionToAdd = new Opinion(null, content, currentUser, null, null, targetOpinion, null, targetProfessor); opinionRepository.save(opinionToAdd); targetOpinion.getChildren().add(opinionToAdd); opinionRepository.save(targetOpinion); }
Корисничка регистрација (3)
Во оваа фаза за регистрацијата на корисник нема интерфејс, но може да се изврши со POST повик до позадински сервис. Пример за валиден повик:
По овој чекор корисникот е внесен во базата, но неговата сметка сè уште не е активирана (има знаменце enabled==false) и не може да се најави. За таа цел, со помош на библиотеката Java Mail се испраќа email до наведената адреса со линк што содржи уникатен токен за потврда со ограничено времетраење. Линкот води до GET повик до позадината (/registration/confirm?token=[TOKEN]) кој ја активира сметката.
Корисничка најава (2)
Најавата се врши преку кориснички интерфејс, со POST повик до сервисот за најава.
Апликацијата користи автентикација со помош на колачиња. Доколку корисничкото име и лозинката се валидни, сервисот за најава му враќа на клиентот променлива (JSESSIONID), која вториот ја зачувува како колаче во прелистувачот и ја користи за сите понатамошни повици до други сервиси, сè додека корисникот не се одјави и колачето не се избрише.
Колачето не се користи само за backend сервиси кои бараат автентикација, туку и за контрола на погледот во самиот клиент. Имено, многу UI компоненти се ограничени (се целосно скриени или видоизменети) зависно од глобална променлива „auth“ која се поставува на true доколку колачето е вчитано.
По најавата, корисникот е редиректиран на својот dashboard, каде има преглед на својата активност, како и на неговите основни податоци (треба да може да менува некои од нив, неимплементирано). Полето „Карма“ е разлика на вкупниот број добиени upvotes и downvotes од сите објавени мислења на корисникот.
Attachments (7)
- registracija.png (21.7 KB ) - added by 2 years ago.
- registracija-verifikacija.png (35.0 KB ) - added by 2 years ago.
- najava.png (16.1 KB ) - added by 2 years ago.
- dashboard.png (54.1 KB ) - added by 2 years ago.
- kod1.png (15.8 KB ) - added by 2 years ago.
- profesor.png (67.9 KB ) - added by 2 years ago.
- prebaruvanje.png (45.4 KB ) - added by 2 years ago.
Download all attachments as: .zip