diff --git a/open-isle-cli/src/utils/level.js b/open-isle-cli/src/utils/level.js new file mode 100644 index 000000000..6f1b88daa --- /dev/null +++ b/open-isle-cli/src/utils/level.js @@ -0,0 +1,7 @@ +export const LEVEL_EXP = [100, 200, 300, 600, 1200, 10000] + +export const prevLevelExp = level => { + if (level <= 0) return 0 + if (level - 1 < LEVEL_EXP.length) return LEVEL_EXP[level - 1] + return LEVEL_EXP[LEVEL_EXP.length - 1] +} diff --git a/open-isle-cli/src/views/ProfileView.vue b/open-isle-cli/src/views/ProfileView.vue index f3d585ab8..bad14768e 100644 --- a/open-isle-cli/src/views/ProfileView.vue +++ b/open-isle-cli/src/views/ProfileView.vue @@ -20,6 +20,16 @@ 取消关注 +
+
Lv.{{ levelInfo.currentLevel }}
+
+
+
+
+ {{ levelInfo.exp }} / {{ levelInfo.nextExp }} +
+
目标 Lv.{{ levelInfo.currentLevel + 1 }}
+
@@ -242,6 +252,7 @@ import UserList from '../components/UserList.vue' import BasePlaceholder from '../components/BasePlaceholder.vue' import { stripMarkdown, stripMarkdownLength } from '../utils/markdown' import TimeManager from '../utils/time' +import { prevLevelExp } from '../utils/level' import { hatch } from 'ldrs' hatch.register() @@ -264,7 +275,18 @@ export default { const isLoading = ref(true) const tabLoading = ref(false) const selectedTab = ref('summary') - const followTab = ref('followers') + const followTab = ref('followers') + + const levelInfo = computed(() => { + const exp = user.value.experience || 0 + const currentLevel = user.value.currentLevel || 0 + const nextExp = user.value.nextLevelExp || 0 + const prevExp = prevLevelExp(currentLevel) + const total = nextExp - prevExp + const ratio = total > 0 ? (exp - prevExp) / total : 1 + const percent = Math.max(0, Math.min(1, ratio)) * 100 + return { exp, currentLevel, nextExp, percent } + }) const isMine = computed(() => authState.username === username) @@ -447,7 +469,8 @@ export default { subscribeUser, unsubscribeUser, gotoTag, - hotTags + hotTags, + levelInfo } } } @@ -530,6 +553,37 @@ export default { cursor: pointer; } +.profile-level-container { + display: flex; + flex-direction: column; + gap: 4px; + margin-top: 10px; + font-size: 14px; +} + +.profile-level-current { + font-weight: bold; +} + +.profile-level-bar { + width: 200px; + height: 8px; + background-color: var(--normal-background-color); + border-radius: 4px; + overflow: hidden; +} + +.profile-level-bar-inner { + height: 100%; + background-color: var(--primary-color); +} + +.profile-level-exp, +.profile-level-target { + font-size: 12px; + opacity: 0.8; +} + .profile-info { display: flex; flex-direction: row;