mirror of
https://github.com/nagisa77/OpenIsle.git
synced 2026-04-19 10:27:29 +08:00
Compare commits
4 Commits
codex/impl
...
feature/co
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f1c83b0f68 | ||
|
|
22c2b1564d | ||
|
|
628d28c12d | ||
|
|
2577992ee3 |
@@ -48,12 +48,13 @@ public class AuthController {
|
|||||||
}
|
}
|
||||||
if (req.getInviteToken() != null && !req.getInviteToken().isEmpty()) {
|
if (req.getInviteToken() != null && !req.getInviteToken().isEmpty()) {
|
||||||
if (!inviteService.validate(req.getInviteToken())) {
|
if (!inviteService.validate(req.getInviteToken())) {
|
||||||
return ResponseEntity.badRequest().body(Map.of("error", "Invalid invite token"));
|
return ResponseEntity.badRequest().body(Map.of("error", "邀请码使用次数过多"));
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
User user = userService.registerWithInvite(
|
User user = userService.registerWithInvite(
|
||||||
req.getUsername(), req.getEmail(), req.getPassword());
|
req.getUsername(), req.getEmail(), req.getPassword());
|
||||||
inviteService.consume(req.getInviteToken());
|
inviteService.consume(req.getInviteToken());
|
||||||
|
emailService.sendEmail(user.getEmail(), "在网站填写验证码以验证", "您的验证码是 " + user.getVerificationCode());
|
||||||
return ResponseEntity.ok(Map.of(
|
return ResponseEntity.ok(Map.of(
|
||||||
"token", jwtService.generateToken(user.getUsername()),
|
"token", jwtService.generateToken(user.getUsername()),
|
||||||
"reason_code", "INVITE_APPROVED"
|
"reason_code", "INVITE_APPROVED"
|
||||||
@@ -78,10 +79,26 @@ public class AuthController {
|
|||||||
public ResponseEntity<?> verify(@RequestBody VerifyRequest req) {
|
public ResponseEntity<?> verify(@RequestBody VerifyRequest req) {
|
||||||
boolean ok = userService.verifyCode(req.getUsername(), req.getCode());
|
boolean ok = userService.verifyCode(req.getUsername(), req.getCode());
|
||||||
if (ok) {
|
if (ok) {
|
||||||
return ResponseEntity.ok(Map.of(
|
Optional<User> userOpt = userService.findByUsername(req.getUsername());
|
||||||
"message", "Verified",
|
if (userOpt.isEmpty()) {
|
||||||
"token", jwtService.generateReasonToken(req.getUsername())
|
return ResponseEntity.badRequest().body(Map.of("error", "Invalid credentials"));
|
||||||
));
|
}
|
||||||
|
|
||||||
|
User user = userOpt.get();
|
||||||
|
|
||||||
|
if (user.isApproved()) {
|
||||||
|
return ResponseEntity.ok(Map.of(
|
||||||
|
"message", "Verified and isApproved",
|
||||||
|
"reason_code", "VERIFIED_AND_APPROVED",
|
||||||
|
"token", jwtService.generateToken(req.getUsername())
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
return ResponseEntity.ok(Map.of(
|
||||||
|
"message", "Verified",
|
||||||
|
"reason_code", "VERIFIED",
|
||||||
|
"token", jwtService.generateReasonToken(req.getUsername())
|
||||||
|
));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return ResponseEntity.badRequest().body(Map.of("error", "Invalid verification code"));
|
return ResponseEntity.badRequest().body(Map.of("error", "Invalid verification code"));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ public class UserService {
|
|||||||
public User registerWithInvite(String username, String email, String password) {
|
public User registerWithInvite(String username, String email, String password) {
|
||||||
User user = register(username, email, password, "", com.openisle.model.RegisterMode.DIRECT);
|
User user = register(username, email, password, "", com.openisle.model.RegisterMode.DIRECT);
|
||||||
user.setVerified(true);
|
user.setVerified(true);
|
||||||
user.setVerificationCode(null);
|
user.setVerificationCode(genCode());
|
||||||
return userRepository.save(user);
|
return userRepository.save(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,13 @@
|
|||||||
/>
|
/>
|
||||||
<NotificationSettingPopup :visible="showNotificationPopup" @close="closeNotificationPopup" />
|
<NotificationSettingPopup :visible="showNotificationPopup" @close="closeNotificationPopup" />
|
||||||
<MedalPopup :visible="showMedalPopup" :medals="newMedals" @close="closeMedalPopup" />
|
<MedalPopup :visible="showMedalPopup" :medals="newMedals" @close="closeMedalPopup" />
|
||||||
|
|
||||||
|
<ActivityPopup
|
||||||
|
:visible="showInviteCodePopup"
|
||||||
|
:icon="inviteCodeIcon"
|
||||||
|
text="邀请码活动开始了,速来参与大伙们🔥🔥🔥"
|
||||||
|
@close="closeInviteCodePopup"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -21,7 +28,10 @@ const config = useRuntimeConfig()
|
|||||||
const API_BASE_URL = config.public.apiBaseUrl
|
const API_BASE_URL = config.public.apiBaseUrl
|
||||||
|
|
||||||
const showMilkTeaPopup = ref(false)
|
const showMilkTeaPopup = ref(false)
|
||||||
|
const showInviteCodePopup = ref(false)
|
||||||
const milkTeaIcon = ref('')
|
const milkTeaIcon = ref('')
|
||||||
|
const inviteCodeIcon = ref('')
|
||||||
|
|
||||||
const showNotificationPopup = ref(false)
|
const showNotificationPopup = ref(false)
|
||||||
const showMedalPopup = ref(false)
|
const showMedalPopup = ref(false)
|
||||||
const newMedals = ref([])
|
const newMedals = ref([])
|
||||||
@@ -30,6 +40,9 @@ onMounted(async () => {
|
|||||||
await checkMilkTeaActivity()
|
await checkMilkTeaActivity()
|
||||||
if (showMilkTeaPopup.value) return
|
if (showMilkTeaPopup.value) return
|
||||||
|
|
||||||
|
await checkInviteCodeActivity()
|
||||||
|
if (showInviteCodePopup.value) return
|
||||||
|
|
||||||
await checkNotificationSetting()
|
await checkNotificationSetting()
|
||||||
if (showNotificationPopup.value) return
|
if (showNotificationPopup.value) return
|
||||||
|
|
||||||
@@ -53,12 +66,38 @@ const checkMilkTeaActivity = async () => {
|
|||||||
// ignore network errors
|
// ignore network errors
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const checkInviteCodeActivity = async () => {
|
||||||
|
if (!process.client) return
|
||||||
|
if (localStorage.getItem('inviteCodeActivityPopupShown')) return
|
||||||
|
try {
|
||||||
|
const res = await fetch(`${API_BASE_URL}/api/activities`)
|
||||||
|
if (res.ok) {
|
||||||
|
const list = await res.json()
|
||||||
|
const a = list.find((i) => i.type === 'INVITE_POINTS' && !i.ended)
|
||||||
|
if (a) {
|
||||||
|
inviteCodeIcon.value = a.icon
|
||||||
|
showInviteCodePopup.value = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
// ignore network errors
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const closeInviteCodePopup = () => {
|
||||||
|
if (!process.client) return
|
||||||
|
localStorage.setItem('inviteCodeActivityPopupShown', 'true')
|
||||||
|
showInviteCodePopup.value = false
|
||||||
|
}
|
||||||
|
|
||||||
const closeMilkTeaPopup = () => {
|
const closeMilkTeaPopup = () => {
|
||||||
if (!process.client) return
|
if (!process.client) return
|
||||||
localStorage.setItem('milkTeaActivityPopupShown', 'true')
|
localStorage.setItem('milkTeaActivityPopupShown', 'true')
|
||||||
showMilkTeaPopup.value = false
|
showMilkTeaPopup.value = false
|
||||||
checkNotificationSetting()
|
checkNotificationSetting()
|
||||||
}
|
}
|
||||||
|
|
||||||
const checkNotificationSetting = async () => {
|
const checkNotificationSetting = async () => {
|
||||||
if (!process.client) return
|
if (!process.client) return
|
||||||
if (!authState.loggedIn) return
|
if (!authState.loggedIn) return
|
||||||
|
|||||||
@@ -6,11 +6,11 @@
|
|||||||
<span class="invite-code-description-title-text">邀请规则说明</span>
|
<span class="invite-code-description-title-text">邀请规则说明</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="invite-code-description-content">
|
<div class="invite-code-description-content">
|
||||||
<p>邀请好友注册并登录,每次可以获得500积分</p>
|
<p>⚠️邀请好友注册并登录,每次可以获得500积分🎉🎉🎉</p>
|
||||||
<p>邀请链接的有效期为1个月</p>
|
<p>邀请链接的有效期为1个月</p>
|
||||||
<p>每一个邀请链接的邀请人数上限为3人</p>
|
<p>每一个邀请链接的邀请人数上限为3人</p>
|
||||||
<p>通过邀请链接注册,无需注册审核</p>
|
<p>通过邀请链接注册,无需注册审核</p>
|
||||||
<p>每人每天仅能生产3个邀请链接</p>
|
<p>每人每天仅能生产1个邀请链接</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -48,9 +48,9 @@ onMounted(async () => {
|
|||||||
isLoadingUser.value = true
|
isLoadingUser.value = true
|
||||||
user.value = await fetchCurrentUser()
|
user.value = await fetchCurrentUser()
|
||||||
isLoadingUser.value = false
|
isLoadingUser.value = false
|
||||||
if (user.value) {
|
// if (user.value) {
|
||||||
await fetchInvite(false)
|
// await fetchInvite(false)
|
||||||
}
|
// }
|
||||||
})
|
})
|
||||||
|
|
||||||
const fetchInvite = async (showToast = true) => {
|
const fetchInvite = async (showToast = true) => {
|
||||||
|
|||||||
@@ -145,7 +145,7 @@ onMounted(async () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.activity-card-normal-right {
|
.activity-card-normal-right {
|
||||||
width: calc(100% - 150px);
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (max-width: 768px) {
|
@media screen and (max-width: 768px) {
|
||||||
|
|||||||
@@ -63,6 +63,7 @@ const pointRules = [
|
|||||||
'评论:每天前四条评论可获 10 积分,你的帖子被评论也可获 10 积分',
|
'评论:每天前四条评论可获 10 积分,你的帖子被评论也可获 10 积分',
|
||||||
'帖子被点赞:每次 10 积分',
|
'帖子被点赞:每次 10 积分',
|
||||||
'评论被点赞:每次 10 积分',
|
'评论被点赞:每次 10 积分',
|
||||||
|
'邀请好友加入可获得 500 积分/次,注意需要使用邀请链接注册',
|
||||||
]
|
]
|
||||||
|
|
||||||
const goods = ref([])
|
const goods = ref([])
|
||||||
|
|||||||
@@ -96,6 +96,7 @@ import { discordAuthorize } from '~/utils/discord'
|
|||||||
import { githubAuthorize } from '~/utils/github'
|
import { githubAuthorize } from '~/utils/github'
|
||||||
import { googleAuthorize } from '~/utils/google'
|
import { googleAuthorize } from '~/utils/google'
|
||||||
import { twitterAuthorize } from '~/utils/twitter'
|
import { twitterAuthorize } from '~/utils/twitter'
|
||||||
|
import { loadCurrentUser, setToken } from '~/utils/auth'
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const config = useRuntimeConfig()
|
const config = useRuntimeConfig()
|
||||||
@@ -160,6 +161,7 @@ const sendVerification = async () => {
|
|||||||
username: username.value,
|
username: username.value,
|
||||||
email: email.value,
|
email: email.value,
|
||||||
password: password.value,
|
password: password.value,
|
||||||
|
inviteToken: inviteToken.value,
|
||||||
}),
|
}),
|
||||||
})
|
})
|
||||||
isWaitingForEmailSent.value = false
|
isWaitingForEmailSent.value = false
|
||||||
@@ -192,11 +194,18 @@ const verifyCode = async () => {
|
|||||||
})
|
})
|
||||||
const data = await res.json()
|
const data = await res.json()
|
||||||
if (res.ok) {
|
if (res.ok) {
|
||||||
if (registerMode.value === 'WHITELIST') {
|
if (data.reason_code === 'VERIFIED_AND_APPROVED') {
|
||||||
navigateTo(`/signup-reason?token=${data.token}`, { replace: true })
|
toast.success('注册成功')
|
||||||
} else {
|
setToken(data.token)
|
||||||
toast.success('注册成功,请登录')
|
loadCurrentUser()
|
||||||
navigateTo('/login', { replace: true })
|
navigateTo('/', { replace: true })
|
||||||
|
} else if (data.reason_code === 'VERIFIED') {
|
||||||
|
if (registerMode.value === 'WHITELIST') {
|
||||||
|
navigateTo(`/signup-reason?token=${data.token}`, { replace: true })
|
||||||
|
} else {
|
||||||
|
toast.success('注册成功,请登录')
|
||||||
|
navigateTo('/login', { replace: true })
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
toast.error(data.error || '注册失败')
|
toast.error(data.error || '注册失败')
|
||||||
|
|||||||
Reference in New Issue
Block a user