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;