feat(player): 重构客服悬浮入口与设置抽屉,优化消息页交互

- 新增可拖拽悬浮客服按钮,支持贴边吸附与位置记忆
- 顶部栏改为设置抽屉入口,将语言/规则/登出等从个人页迁出
- 余额芯片集成用户头像,移除独立头像菜单
- 消息列表去掉冗余未读白点,统一消息页返回导航
- 补充 profile.settings 多语言文案

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-06-18 13:32:37 +08:00
parent fce2333322
commit 46155018ce
9 changed files with 885 additions and 181 deletions

View File

@@ -2,17 +2,26 @@
import { ref, onMounted, onUnmounted, computed } from 'vue';
import { useRouter } from 'vue-router';
import { useI18n } from 'vue-i18n';
import { playerAvatarUrl, randomAvatarKey } from '@thebet365/shared';
import { useAuthStore } from '../stores/auth';
import { formatMoney } from '../utils/localeDisplay';
import { usePlayerProfile } from '../composables/usePlayerProfile';
const { locale, t } = useI18n();
const { profileRaw, refreshProfile } = usePlayerProfile();
const { profileRaw, refreshProfile, avatarUrl } = usePlayerProfile();
const auth = useAuthStore();
const router = useRouter();
const open = ref(false);
const root = ref<HTMLElement | null>(null);
const wallet = computed(() => profileRaw.value?.wallet ?? null);
const displayAvatarUrl = computed(() => {
if (avatarUrl.value) return avatarUrl.value;
const seed = auth.user?.username;
return seed ? playerAvatarUrl(randomAvatarKey(seed)) : null;
});
function amountValue(value: unknown): number {
if (value == null) return 0;
if (typeof value === 'number') return Number.isFinite(value) ? value : 0;
@@ -74,7 +83,11 @@ onUnmounted(() => {
<span class="chip-label">{{ t('wallet.cash_balance') }}</span>
<span class="chip-amount">{{ available }}</span>
</span>
<span class="chevron" :class="{ open }"></span>
<!-- Integrated Avatar image -->
<span class="chip-avatar-wrap">
<img v-if="displayAvatarUrl" :src="displayAvatarUrl" alt="" class="chip-avatar-img" />
</span>
</button>
<div v-if="open" class="cash-panel">
@@ -110,9 +123,9 @@ onUnmounted(() => {
.cash-chip {
display: flex;
align-items: center;
gap: 4px;
gap: 10px;
height: 36px;
padding: 0 10px;
padding: 0 6px 0 10px;
min-width: 0;
cursor: pointer;
border: 1px solid var(--border);
@@ -149,15 +162,25 @@ onUnmounted(() => {
font-variant-numeric: tabular-nums;
}
.chevron {
font-size: 10px;
color: var(--text-muted);
transition: transform 0.2s;
margin-left: 0;
/* Integrated Avatar Styling */
.chip-avatar-wrap {
width: 24px;
height: 24px;
border-radius: 50%;
overflow: hidden;
display: flex;
align-items: center;
justify-content: center;
border: 1px solid var(--border-gold-soft);
flex-shrink: 0;
background: var(--bg-body);
}
.chevron.open {
transform: rotate(180deg);
.chip-avatar-img {
width: 100%;
height: 100%;
object-fit: cover;
object-position: top;
}
.cash-panel {