Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> [PHP][SQL]moduł osiągnięcia na 30dni
phpuser88
post
Post #1





Grupa: Zarejestrowani
Postów: 66
Pomógł: 1
Dołączył: 4.05.2019
Skąd: PHP5.6

Ostrzeżenie: (0%)
-----


Załóżmy, że chce wyświetlić użytkownikowi możliwość zdobywania osiągnięć, a każde osiągnięcie ma swój własny postęp i zostanie zrealizowane gdy osiągnie swój max.postęp - o ile max.postęp zostanie osiągnięty w max.30dni od chwili zrealizowania pierwszego postępu.
Przykład:
1. Tytuł osiągnięcia: Aktywny komentator
2. Opis osiągnięcia: podejmij się napisania 15x różnorodnych komentarzy powyżej 100 znaków w ciągu 30 dni.
3. Postęp: 0 / 15

Stworzyłem sobie funkcje, która wyświetla właściwy html, ale mam zagwozdkę jak rozsądnie stworzyć bazę danych, bo każde osiągnięcie można zrealizować wciągu 30 dni od chwili zrealizowania pierwszego "postępu", a to wyklucza proste i optymalne rozwiązanie jakim jest wrzucenie wszystkiego w jedną tabele pod ID_USERA i jedynie updatowanie poszczególnych osiągnięć +1 w danym wierszu. Tutaj raczej trzeba dodać jeszcze date realizacji i ew. crona do czyszczenia, a to generalnie zrobi wielki ruch w tabeli, bo z np. 1000000 wpisów zrobi się 1000000*ilość osiągnięć*max.postęp.
Nie jestem zbyt zaawansowany więc niestety nie znam wielu fajnych rozwiązań więc zanim zrobię to tak, jak to widzę w powyższym okropnym opisie wolę zapytać czy istnieje lepszy pomysł?
Tak to widzę:
  1. #BazaSQL:
  2. id_usera | dataRealizacji | osiagniecie1 | osiagniecie2 | osiagniecie3 |
  3. 123456 | 21.01.22 | 0 | 0 | 1 |
  4. 123456 | 21.04.22 | 0 | 0 | 1 |
  5. 123456 | 28.04.22 | 0 | 0 | 1 |
  6. 123456 | 01.05.22 | 0 | 0 | 1 | //to jest ID_usera, który ma postęp 3x w Osiągnięciu3
  7.  
  8. #PHP
  9. function osiagniecia($tytul,$postep,$postepMax,$opis){...}
  10.  
  11. echo osiagniecia("tytul osiagniecia",$row['osiagniecie3 '],15,"opis osiagniecia do zrealizowania");
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi (1 - 12)
trueblue
post
Post #2





Grupa: Zarejestrowani
Postów: 6 806
Pomógł: 1828
Dołączył: 11.03.2014

Ostrzeżenie: (0%)
-----


A jeśli nie osiągnie postępu, to może przystąpić do osiągnięcia jeszcze raz?
Go to the top of the page
+Quote Post
phpuser88
post
Post #3





Grupa: Zarejestrowani
Postów: 66
Pomógł: 1
Dołączył: 4.05.2019
Skąd: PHP5.6

Ostrzeżenie: (0%)
-----


może przystąpić jeszcze raz, ważne aby osiągnął komplet w 30 dni - jeżeli nie osiągnie kompletu, to kolejno każdy postęp osiągnięcia będzie wygasać po 30 dniach.

edit:
Teraz wpadłem na trochę inny pomysł,a mianowicie stworze 30 kolumn odpowiadające za każdy dzień z trzydziestu i jeśli jakieś osiągnięcie zostanie zrealizowane danego dnia, to przypisze mu unikalny identyfikator z sumą i wpakuje do bazy, a później jakoś w PHP to poskładam w całość:
Coś tego typu:
  1. #BazaSQL:
  2. id_usera | dzien1 | dzien2 | dzien3 | dzienX |
  3. 123456 | #id:2=1 | 0 | 0 | 0 |
  4. 123456 | 0 | #id:2=1#id:4=1 | 0 | 0 |
  5. 123456 | 0 | 0 | 0 | #id:2=1 |

Ale to nadal tylko gdybanie nad sensownym rozwiązaniem.

edit2:
To rozwiązanie jest niewypałem... bo jeśli user zrealizuje pierwsze osiągnięcie 30 dnia, to powinien mieć czas 30 dni na realizacje całego postępu, a tu w teorii wszystko powinno być kasowane (IMG:style_emoticons/default/dry.gif)
Czyli całość musi być oparta na datach i wychodzi na to, że pierwsze założenie jest niestety prawidłowe. (IMG:style_emoticons/default/sciana.gif)

edit3:
Chyba że dodam kolejną kolumnę z nazwą osiągnięcia i pierwszy postęp to będzie `dzien1`.
Następnie z wszystkich kolumn stworze tzw. licznik aby wiedzieć na którym dniu jest aktualnie dane osiągnięcie. Mogę to chyba zrobić za pomocą crona dodając każdego dnia +1 do `dzien2` (tj. nastepnego dnia gdzie dzienX==0) - w sensie jeśli dzień >0 i następny dzień==0, to jest to ten dzień na którym stoi całe osiągnięcie. Później w PHP odejmę 1 od każdego dnia i uzyskam prawidłową sume postępu danego osiągnięcia...
Dzięki temu zredukuje tone wpisów i liczenia o ile myślę w prawidłowy sposób haha (IMG:style_emoticons/default/co_jest.gif)
  1. #BazaSQL:
  2. id_usera | osiagniecie | dzien1 | dzien2 | dzien3 | dzienX |
  3. 123456 | 10 | 2 | 2 | 2 | 0 | //=3
  4. 123456 | 50 | 2 | 1 | 2 | 0 | //=2

Tu jest chyba taki minus, że każdy postęp osiągnięcia NIE będzie wygasać po 30 dniach, a zamiast tego wygaśnie całe osiągnięcie wraz z wszystkimi postępami, ale to raczej lepsze rozwiązanie od pierwszej metody.

Ten post edytował phpuser88 1.05.2022, 15:09:22
Go to the top of the page
+Quote Post
trueblue
post
Post #4





Grupa: Zarejestrowani
Postów: 6 806
Pomógł: 1828
Dołączył: 11.03.2014

Ostrzeżenie: (0%)
-----


Czy to oznacza, że mogę dokonać jednego postępu na dzień?
Go to the top of the page
+Quote Post
phpuser88
post
Post #5





Grupa: Zarejestrowani
Postów: 66
Pomógł: 1
Dołączył: 4.05.2019
Skąd: PHP5.6

Ostrzeżenie: (0%)
-----


Nie, można dokonać nawet wszystkich postępów jednego dnia.
Go to the top of the page
+Quote Post
trueblue
post
Post #6





Grupa: Zarejestrowani
Postów: 6 806
Pomógł: 1828
Dołączył: 11.03.2014

Ostrzeżenie: (0%)
-----


Jak będziesz identyfikował konkretny postęp? Czy każdy postęp jest innym działaniem?
Go to the top of the page
+Quote Post
phpuser88
post
Post #7





Grupa: Zarejestrowani
Postów: 66
Pomógł: 1
Dołączył: 4.05.2019
Skąd: PHP5.6

Ostrzeżenie: (0%)
-----


Każdy postęp jest innym działaniem. Myślę, że za pomocą unikalnego ID. Jeszcze dokładnie tego nie przemyślałem, ale tak to widzę.
Przykładowo jeśli chodzi o przykład:
Cytat
Przykład:
1. Tytuł osiągnięcia: Aktywny komentator
2. Opis osiągnięcia: podejmij się napisania 15x różnorodnych komentarzy powyżej 100 znaków w ciągu 30 dni.
3. Postęp: 0 / 15

To myślę aby każdy komentarz przed insertem w komentarze sprawdzić dodatkowo pod kątem ilości znaków i jeśli znaki>99, to +1 do postępu z ID(osiagniecia_komentarze)

edit: ha!... czyli jeśli zastosuje rozwiązanie z edit3 będę musiał za każdym razem weryfikować w jaki dzień dodać update+1 - troche kulawo...

Ten post edytował phpuser88 1.05.2022, 15:25:44
Go to the top of the page
+Quote Post
trueblue
post
Post #8





Grupa: Zarejestrowani
Postów: 6 806
Pomógł: 1828
Dołączył: 11.03.2014

Ostrzeżenie: (0%)
-----


Tabela:
id_user, numer_osiagniecia, data_start, data_ostatni_postep, id_ostatni_postep
Wpisujesz start danego osiągnięcia (nie wiem kiedy u Ciebie przypada ten termin - po zrealizowaniu pierwszego postępu?).
Kiedy użytkownik zrealizuje dany postęp, wpisujesz (aktualizujesz) jego date i id w tabeli.
id_ostatni_postep informuje czy użytkownik osiągnał całość. Możesz też dodać odrębne pole na wartość postępu.

To jest najprostsze rozwiązanie, ale niekoniecznie najlepsze.

Innym było po prostu zapisywanie kolejnych postępów:

user_osiagniecie:
id_user_numer_osiagniecia, id_user, numer_osiagniecia, data_start
osiagniecie_postep:
id_user_numer_osiagniecia, data_postep, id_postep

lub na jednej tabeli, jeśli data startu osiągnięcia jest równoznaczna z zakończeniem pierwszego postępu:
id_user, numer_osiagniecia, data_postep, id_postep


Wszystko zależy od specyfiki Twojego problemu.

Go to the top of the page
+Quote Post
phpuser88
post
Post #9





Grupa: Zarejestrowani
Postów: 66
Pomógł: 1
Dołączył: 4.05.2019
Skąd: PHP5.6

Ostrzeżenie: (0%)
-----


Tak, data_start to realizacja pierwszego postępu, ale w sumie to chyba jej nie potrzebuje. (IMG:style_emoticons/default/dry.gif)
Myślę aby weryfikację całości zostawić całkiem po stronie PHP, a w bazie trzymać jedynie tzw. licznik.
Na podstawie Twoich przykładów zlepiłem coś takiego w jedną tabele:
(przy założeniu, że data_koniec oznacza koniec czasu na realizację danego osiągnięcia)

id_user, id_osiagniecia, postep_osiagniecia, data_koniec(+30dni)

Czyli jeśli chcemy dodać nowy postęp, to musimy najpierw sprawdzić czy istnieje oraz if(data_koniec>$data_dzis), a następnie updatować+1, a jeśli data końca przeminęła zrobić update daty_konca i postep=1 (jako rozpoczęcie od nowa osiągnięcia). Albo za pomocą crona sprawdzać i czyścić raz dziennie przestarzałe daty.

A funkcje wyświetlania ustawić jakoś tak:
function osiągnięcia($id,$postepSQL,$postepMax,$data_koniecSQL,$tytul,$opis);

Hmm... patrząc na Twoje wzorce wydaje się to całkiem proste... a ja sobie od początku ostro komplikowałem (IMG:style_emoticons/default/facepalmxd.gif) dzięki wielkie za naprowadzenie! (IMG:style_emoticons/default/biggrin.gif)
Go to the top of the page
+Quote Post
trueblue
post
Post #10





Grupa: Zarejestrowani
Postów: 6 806
Pomógł: 1828
Dołączył: 11.03.2014

Ostrzeżenie: (0%)
-----


Cron tu raczej nie jest potrzebny.
Przyda się jednak data_start i data_ostatni_postep.
Dzięki data_start, wiesz czy działania mieszczą się w 30 dniach. Aktualizacja postępu może nastąpić jeśli aktualna_data-data_start<=30 dni.
Tak więc użytkownik poprzez swoje działania, a następnie Twój skrypt, zaktualizuje datę ostatniego postępu i sam postęp.

Chyba, że piszesz o sytuacji kiedy użytkownik nie zrealizował osiągnięcia i chcemy dodać nowe. Wtedy można to zrobić cronem lub też przed zapisem nowego, pierwszego postępu danego osiągnięcia.
Go to the top of the page
+Quote Post
phpuser88
post
Post #11





Grupa: Zarejestrowani
Postów: 66
Pomógł: 1
Dołączył: 4.05.2019
Skąd: PHP5.6

Ostrzeżenie: (0%)
-----


Hmm myślałem bardziej w sposób, że jeśli użytkownik doda +1 do postępu osiągnięcia, to automatycznie `data_koniec` przyjmuje wartość +30dni na spełnienie całości osiągnięcia.
Jeśli ma nastąpić kolejny update_postep+1, to sprawdzamy czy $data_dziś<`data_koniec` - to raczej powinno wystarczyć. Nieco ograniczy możliwości użytkownika przy realizacji osiągnięcia, bo zostanie mu odebrany postęp dodany np. 29 dnia, jeśli niefortunnie data_konca tak zakłada. Z drugiej strony teraz myślę, że jeśli użytkownik zrealizuje cały postęp w osiągnięciu, to powinno być ono ważne przez następne 30dni więc `data_start` mogłaby odpowiadać właśnie za czas działania korzyści ze zrealizowanego osiągnięcia. Tak to widzę i chyba już całkiem poprawnie dzięki Tobie. (IMG:style_emoticons/default/biggrin.gif)

Ten post edytował phpuser88 1.05.2022, 17:03:46
Go to the top of the page
+Quote Post
trueblue
post
Post #12





Grupa: Zarejestrowani
Postów: 6 806
Pomógł: 1828
Dołączył: 11.03.2014

Ostrzeżenie: (0%)
-----


Czy dobrze rozumiem, że użytkownik ma 30 dni na wypełnienie postępu od ostatniego działania (czyli de facto na każdy postęp), a nie 30 dni na całość osiągnięcia?

Ten post edytował trueblue 1.05.2022, 18:45:15
Go to the top of the page
+Quote Post
phpuser88
post
Post #13





Grupa: Zarejestrowani
Postów: 66
Pomógł: 1
Dołączył: 4.05.2019
Skąd: PHP5.6

Ostrzeżenie: (0%)
-----


No ostatecznie tak, bo dzięki temu zamknę się z jednym osiągnięciem w jednym wierszu. User ma 30 dni na zrobienie wszystkich postępów od chwili zrealizowania pierwszego postępu w danym osiągnięciu. Nie jest to eleganckie w stosunku do usera, ale wydajność jest istotniejsza. Coś pomieszałem w tym założeniu? haha

Przy założeniu że chodzi o osiągnięcie z przykładu:
1. Tytuł osiągnięcia: Aktywny komentator
2. Opis osiągnięcia: podejmij się napisania 15x różnorodnych komentarzy powyżej 100 znaków w ciągu 30 dni.
3. Postęp: 0 / 15

Zrobiłbym to tak, aby dodać +1:
  1. if($INSERT_KOMENTARZ){//dodano nowy komentarz
  2. if(strlen($tresc_komentarza)>99){//sprawdz czy komentarz kwalifikuje sie na osiagniecie
  3. $datakoniec = date("Y-m-d", strtotime('+30 day'));
  4. $datadzis = date("Y-m-d");
  5. $sql="SELECT * FROM `osiagniecia` WHERE `user`='123456' AND `idos`=1 LIMIT 1";
  6. if($result = mysqli_query($con, $sql)){
  7. if(mysqli_num_rows($result)){//sprawdz czy istnieje
  8. while($row = mysqli_fetch_assoc($result)){
  9. if($row['koniec']>$datadzis){
  10. UPDATE `osiganiecia` SET `postep` = postep+1 WHERE `user` = 123456 AND `idos`=1; //dodaj +1 skoro user ma jeszcze czas na realizacje
  11. }else{//istnieje, ale czas zostal przekroczony
  12. UPDATE `osiganiecia` SET `postep` = 1, `koniec` = '$datakoniec' WHERE `user` = 123456 AND `idos`=1; //ustawia od nowa postep=1 i date_konca+30dni
  13. }
  14. }
  15. }else{//nie istnieje
  16. INSERT INTO `osiganiecia` (`id`, `user`, `idos`, `postep`, `koniec`, `start`) VALUES (NULL, '123456', '1', '1', '$datakoniec', '0000-00-00'); //dodaj osiagniecie z postepem i max.data jako rama czasowa
  17. }}}}
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
2 Użytkowników czyta ten temat (2 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 4.10.2025 - 13:20