mirror of
https://github.com/nagisa77/OpenIsle.git
synced 2026-05-09 20:27:30 +08:00
feat: add pioneer medal dto
This commit is contained in:
10
backend/src/main/java/com/openisle/dto/PioneerMedalDto.java
Normal file
10
backend/src/main/java/com/openisle/dto/PioneerMedalDto.java
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
package com.openisle.dto;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
public class PioneerMedalDto extends MedalDto {
|
||||||
|
private long rank;
|
||||||
|
}
|
||||||
@@ -4,5 +4,6 @@ public enum MedalType {
|
|||||||
COMMENT,
|
COMMENT,
|
||||||
POST,
|
POST,
|
||||||
CONTRIBUTOR,
|
CONTRIBUTOR,
|
||||||
SEED
|
SEED,
|
||||||
|
PIONEER
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package com.openisle.repository;
|
|||||||
|
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
import com.openisle.model.User;
|
import com.openisle.model.User;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
public interface UserRepository extends JpaRepository<User, Long> {
|
public interface UserRepository extends JpaRepository<User, Long> {
|
||||||
@@ -10,4 +11,5 @@ public interface UserRepository extends JpaRepository<User, Long> {
|
|||||||
java.util.List<User> findByUsernameContainingIgnoreCase(String keyword);
|
java.util.List<User> findByUsernameContainingIgnoreCase(String keyword);
|
||||||
java.util.List<User> findByRole(com.openisle.model.Role role);
|
java.util.List<User> findByRole(com.openisle.model.Role role);
|
||||||
long countByExperienceGreaterThanEqual(int experience);
|
long countByExperienceGreaterThanEqual(int experience);
|
||||||
|
long countByCreatedAtBefore(LocalDateTime createdAt);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import com.openisle.dto.ContributorMedalDto;
|
|||||||
import com.openisle.dto.MedalDto;
|
import com.openisle.dto.MedalDto;
|
||||||
import com.openisle.dto.PostMedalDto;
|
import com.openisle.dto.PostMedalDto;
|
||||||
import com.openisle.dto.SeedUserMedalDto;
|
import com.openisle.dto.SeedUserMedalDto;
|
||||||
|
import com.openisle.dto.PioneerMedalDto;
|
||||||
import com.openisle.model.MedalType;
|
import com.openisle.model.MedalType;
|
||||||
import com.openisle.model.User;
|
import com.openisle.model.User;
|
||||||
import com.openisle.repository.CommentRepository;
|
import com.openisle.repository.CommentRepository;
|
||||||
@@ -24,6 +25,7 @@ public class MedalService {
|
|||||||
private static final long POST_TARGET = 100;
|
private static final long POST_TARGET = 100;
|
||||||
private static final LocalDateTime SEED_USER_DEADLINE = LocalDateTime.of(2025, 9, 16, 0, 0);
|
private static final LocalDateTime SEED_USER_DEADLINE = LocalDateTime.of(2025, 9, 16, 0, 0);
|
||||||
private static final long CONTRIBUTION_TARGET = 1;
|
private static final long CONTRIBUTION_TARGET = 1;
|
||||||
|
private static final long PIONEER_LIMIT = 1000;
|
||||||
|
|
||||||
private final CommentRepository commentRepository;
|
private final CommentRepository commentRepository;
|
||||||
private final PostRepository postRepository;
|
private final PostRepository postRepository;
|
||||||
@@ -102,6 +104,21 @@ public class MedalService {
|
|||||||
}
|
}
|
||||||
seedUserMedal.setSelected(selected == MedalType.SEED);
|
seedUserMedal.setSelected(selected == MedalType.SEED);
|
||||||
medals.add(seedUserMedal);
|
medals.add(seedUserMedal);
|
||||||
|
|
||||||
|
PioneerMedalDto pioneerMedal = new PioneerMedalDto();
|
||||||
|
pioneerMedal.setIcon("https://openisle-1307107697.cos.ap-guangzhou.myqcloud.com/assert/icons/achi_pioneer.png");
|
||||||
|
pioneerMedal.setTitle("开山鼻祖");
|
||||||
|
pioneerMedal.setDescription("前1000位加入的用户");
|
||||||
|
pioneerMedal.setType(MedalType.PIONEER);
|
||||||
|
if (user != null) {
|
||||||
|
long rank = userRepository.countByCreatedAtBefore(user.getCreatedAt()) + 1;
|
||||||
|
pioneerMedal.setRank(rank);
|
||||||
|
pioneerMedal.setCompleted(rank <= PIONEER_LIMIT);
|
||||||
|
} else {
|
||||||
|
pioneerMedal.setCompleted(false);
|
||||||
|
}
|
||||||
|
pioneerMedal.setSelected(selected == MedalType.PIONEER);
|
||||||
|
medals.add(pioneerMedal);
|
||||||
if (user != null && selected == null) {
|
if (user != null && selected == null) {
|
||||||
for (MedalDto medal : medals) {
|
for (MedalDto medal : medals) {
|
||||||
if (medal.isCompleted()) {
|
if (medal.isCompleted()) {
|
||||||
@@ -126,6 +143,8 @@ public class MedalService {
|
|||||||
user.setDisplayMedal(MedalType.POST);
|
user.setDisplayMedal(MedalType.POST);
|
||||||
} else if (contributorService.getContributionLines(user.getUsername()) >= CONTRIBUTION_TARGET) {
|
} else if (contributorService.getContributionLines(user.getUsername()) >= CONTRIBUTION_TARGET) {
|
||||||
user.setDisplayMedal(MedalType.CONTRIBUTOR);
|
user.setDisplayMedal(MedalType.CONTRIBUTOR);
|
||||||
|
} else if (userRepository.countByCreatedAtBefore(user.getCreatedAt()) < PIONEER_LIMIT) {
|
||||||
|
user.setDisplayMedal(MedalType.PIONEER);
|
||||||
} else if (user.getCreatedAt().isBefore(SEED_USER_DEADLINE)) {
|
} else if (user.getCreatedAt().isBefore(SEED_USER_DEADLINE)) {
|
||||||
user.setDisplayMedal(MedalType.SEED);
|
user.setDisplayMedal(MedalType.SEED);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ class MedalServiceTest {
|
|||||||
|
|
||||||
List<MedalDto> medals = service.getMedals(null);
|
List<MedalDto> medals = service.getMedals(null);
|
||||||
medals.forEach(m -> assertFalse(m.isCompleted()));
|
medals.forEach(m -> assertFalse(m.isCompleted()));
|
||||||
assertEquals(4, medals.size());
|
assertEquals(5, medals.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -40,6 +40,7 @@ class MedalServiceTest {
|
|||||||
when(commentRepo.countByAuthor_Id(1L)).thenReturn(120L);
|
when(commentRepo.countByAuthor_Id(1L)).thenReturn(120L);
|
||||||
when(postRepo.countByAuthor_Id(1L)).thenReturn(80L);
|
when(postRepo.countByAuthor_Id(1L)).thenReturn(80L);
|
||||||
when(contributorService.getContributionLines(anyString())).thenReturn(0L);
|
when(contributorService.getContributionLines(anyString())).thenReturn(0L);
|
||||||
|
when(userRepo.countByCreatedAtBefore(any())).thenReturn(50L);
|
||||||
User user = new User();
|
User user = new User();
|
||||||
user.setId(1L);
|
user.setId(1L);
|
||||||
user.setCreatedAt(LocalDateTime.of(2025, 9, 15, 0, 0));
|
user.setCreatedAt(LocalDateTime.of(2025, 9, 15, 0, 0));
|
||||||
@@ -56,6 +57,8 @@ class MedalServiceTest {
|
|||||||
assertFalse(medals.stream().filter(m -> m.getType() == MedalType.POST).findFirst().orElseThrow().isSelected());
|
assertFalse(medals.stream().filter(m -> m.getType() == MedalType.POST).findFirst().orElseThrow().isSelected());
|
||||||
assertTrue(medals.stream().filter(m -> m.getType() == MedalType.SEED).findFirst().orElseThrow().isCompleted());
|
assertTrue(medals.stream().filter(m -> m.getType() == MedalType.SEED).findFirst().orElseThrow().isCompleted());
|
||||||
assertFalse(medals.stream().filter(m -> m.getType() == MedalType.SEED).findFirst().orElseThrow().isSelected());
|
assertFalse(medals.stream().filter(m -> m.getType() == MedalType.SEED).findFirst().orElseThrow().isSelected());
|
||||||
|
assertTrue(medals.stream().filter(m -> m.getType() == MedalType.PIONEER).findFirst().orElseThrow().isCompleted());
|
||||||
|
assertFalse(medals.stream().filter(m -> m.getType() == MedalType.PIONEER).findFirst().orElseThrow().isSelected());
|
||||||
verify(userRepo).save(user);
|
verify(userRepo).save(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -69,6 +72,7 @@ class MedalServiceTest {
|
|||||||
when(commentRepo.countByAuthor_Id(1L)).thenReturn(120L);
|
when(commentRepo.countByAuthor_Id(1L)).thenReturn(120L);
|
||||||
when(postRepo.countByAuthor_Id(1L)).thenReturn(0L);
|
when(postRepo.countByAuthor_Id(1L)).thenReturn(0L);
|
||||||
when(contributorService.getContributionLines(anyString())).thenReturn(0L);
|
when(contributorService.getContributionLines(anyString())).thenReturn(0L);
|
||||||
|
when(userRepo.countByCreatedAtBefore(any())).thenReturn(0L);
|
||||||
User user = new User();
|
User user = new User();
|
||||||
user.setId(1L);
|
user.setId(1L);
|
||||||
user.setCreatedAt(LocalDateTime.of(2025, 9, 15, 0, 0));
|
user.setCreatedAt(LocalDateTime.of(2025, 9, 15, 0, 0));
|
||||||
@@ -90,6 +94,7 @@ class MedalServiceTest {
|
|||||||
when(commentRepo.countByAuthor_Id(1L)).thenReturn(10L);
|
when(commentRepo.countByAuthor_Id(1L)).thenReturn(10L);
|
||||||
when(postRepo.countByAuthor_Id(1L)).thenReturn(0L);
|
when(postRepo.countByAuthor_Id(1L)).thenReturn(0L);
|
||||||
when(contributorService.getContributionLines(anyString())).thenReturn(0L);
|
when(contributorService.getContributionLines(anyString())).thenReturn(0L);
|
||||||
|
when(userRepo.countByCreatedAtBefore(any())).thenReturn(0L);
|
||||||
User user = new User();
|
User user = new User();
|
||||||
user.setId(1L);
|
user.setId(1L);
|
||||||
user.setCreatedAt(LocalDateTime.of(2025, 9, 15, 0, 0));
|
user.setCreatedAt(LocalDateTime.of(2025, 9, 15, 0, 0));
|
||||||
|
|||||||
@@ -29,6 +29,7 @@
|
|||||||
<template v-else-if="medal.type === 'CONTRIBUTOR'">
|
<template v-else-if="medal.type === 'CONTRIBUTOR'">
|
||||||
{{ medal.currentContributionLines }}/{{ medal.targetContributionLines }}
|
{{ medal.currentContributionLines }}/{{ medal.targetContributionLines }}
|
||||||
</template>
|
</template>
|
||||||
|
<template v-else-if="medal.type === 'PIONEER'"> 第{{ medal.rank }}位 </template>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ export const medalTitles = {
|
|||||||
POST: '发帖达人',
|
POST: '发帖达人',
|
||||||
SEED: '种子用户',
|
SEED: '种子用户',
|
||||||
CONTRIBUTOR: '贡献者',
|
CONTRIBUTOR: '贡献者',
|
||||||
|
PIONEER: '开山鼻祖',
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getMedalTitle(type) {
|
export function getMedalTitle(type) {
|
||||||
|
|||||||
Reference in New Issue
Block a user