fix:将侧边栏兼容移动端

This commit is contained in:
2026-01-20 17:54:45 +08:00
parent 0b57581799
commit e3e70114fb
18 changed files with 3059 additions and 316 deletions
+130 -59
View File
@@ -44,24 +44,32 @@
</div>
</div>
</div>
<div class="profile-stats">
<div class="stat-item">
<div class="stat-label">实名状态</div>
<div class="stat-value">
<el-tag :type="userInfo.RealName?.Status === 1 ? 'success' : 'warning'" size="small" effect="light">
{{ getRealNameStatusText(userInfo.RealName?.Status) }}
</el-tag>
</div>
</div>
<div class="stat-item">
<div class="stat-label">推荐人ID</div>
<div class="stat-value">{{ userInfo.RecommendUserId || '-' }}</div>
</div>
<div class="stat-item">
<div class="stat-label">用户组ID</div>
<div class="stat-value">{{ userInfo.UserGroupId || '-' }}</div>
</div>
<!-- 统一的用户数据概览区域 -->
<div class="profile-stats-unified">
<!-- 余额数据 -->
<div class="stat-item" v-for="balance in userBalanceList" :key="balance.id">
<div class="stat-label">{{ balance.typeName }}</div>
<div class="stat-value" :style="{ color: balance.typeColor }">{{ formatBalance(balance.price) }}</div>
</div>
<!-- 分隔线 -->
<el-divider direction="vertical" v-if="userBalanceList.length > 0" class="stats-divider" />
<!-- 其他状态数据 -->
<div class="stat-item">
<div class="stat-label">实名状态</div>
<div class="stat-value">
<el-tag :type="userInfo.RealName?.Status === 1 ? 'success' : 'warning'" size="small" effect="light">
{{ getRealNameStatusText(userInfo.RealName?.Status) }}
</el-tag>
</div>
</div>
<div class="stat-item">
<div class="stat-label">推荐人ID</div>
<div class="stat-value">{{ userInfo.RecommendUserId || '-' }}</div>
</div>
<div class="stat-item">
<div class="stat-label">用户组ID</div>
<div class="stat-value">{{ userInfo.UserGroupId || '-' }}</div>
</div>
</div>
</div>
@@ -298,19 +306,34 @@
</el-select>
</el-form-item>
<el-form-item label="推荐人">
<div class="recommend-user-selector">
<div class="selected-user" v-if="recommendUserInfo.UserId">
<el-avatar :size="32" :src="recommendUserInfo.Avatar" />
<span class="user-name">{{ recommendUserInfo.UserName }}</span>
<span class="user-id">(ID: {{ recommendUserInfo.UserId }})</span>
<el-button type="danger" link size="small" @click="clearRecommendUser">
<el-icon><Close /></el-icon>
<el-input
v-if="recommendUserInfo.UserId"
:model-value="`${recommendUserInfo.UserName} (ID: ${recommendUserInfo.UserId})`"
readonly
style="width: 100%"
>
<template #suffix>
<el-icon class="clear-icon" @click="clearRecommendUser"><Close /></el-icon>
</template>
<template #append>
<el-button @click="showUserSelectorDialog = true">
<el-icon><User /></el-icon>
</el-button>
</div>
<el-button v-else type="primary" plain @click="showUserSelectorDialog = true">
<el-icon><User /></el-icon> 选择推荐人
</el-button>
</div>
</template>
</el-input>
<el-input
v-else
placeholder="请选择推荐人"
readonly
style="width: 100%"
@click="showUserSelectorDialog = true"
>
<template #append>
<el-button @click="showUserSelectorDialog = true">
<el-icon><User /></el-icon>
</el-button>
</template>
</el-input>
</el-form-item>
</el-form>
<template #footer>
@@ -559,6 +582,16 @@ const userBalance = ref({
total_consume: 0
})
// 用户余额列表(用于概览卡片展示)
const userBalanceList = ref([])
// 余额类型映射
const balanceTypeMap = {
entity: { name: '云钻', type: 'cloud_diamond', color: '#409EFF' },
general: { name: '云币', type: 'cloud_coin', color: '#67C23A' },
withdraw: { name: '云点', type: 'cloud_points', color: '#E6A23C' }
}
// 编辑用户相关
const editDialogVisible = ref(false)
const editForm = reactive({
@@ -684,6 +717,8 @@ const fetchUserInfo = async () => {
if (userInfo.value.CoverID) {
fetchCurrentAvatar(userInfo.value.CoverID)
}
// 获取用户余额列表
fetchUserBalanceList(userId)
}
} catch (error) {
ElMessage.error('获取用户信息失败')
@@ -692,6 +727,25 @@ const fetchUserInfo = async () => {
}
}
// 获取用户余额列表(用于概览卡片展示)
const fetchUserBalanceList = async (userId) => {
try {
const res = await getUserBalanceCount({ user_id: userId })
if (res.data.code === 200) {
// 只保留映射类型中存在的余额
userBalanceList.value = (res.data.data || []).filter(item => {
return balanceTypeMap[item.type]
}).map(item => ({
...item,
typeName: balanceTypeMap[item.type]?.name || item.type,
typeColor: '#000000'
}))
}
} catch (error) {
console.error('获取用户余额失败:', error)
}
}
// 刷新数据
const refreshData = () => {
fetchUserInfo()
@@ -1038,7 +1092,7 @@ const handleViewOrder = (row) => {
const handleViewTicket = (row) => {
router.push({
path: '/ticket/detail',
query: { work_id: row.work_id }
query: { id: row.work_id }
})
}
@@ -1286,6 +1340,12 @@ const formatDate = (dateString) => {
})
}
// 余额格式化(分转元,保留2位小数)
const formatBalance = (price) => {
if (price === undefined || price === null) return '0.00'
return (price / 100).toFixed(2)
}
const loadUserData = async () => {
if(!route.query.user_id){
ElMessage.error('缺少用户ID参数');
@@ -1375,6 +1435,7 @@ onActivated(() => {
display: flex;
align-items: center;
gap: 24px;
flex-shrink: 0;
}
.avatar-wrapper {
@@ -1435,27 +1496,37 @@ onActivated(() => {
margin-left: 4px;
}
.profile-stats {
/* 统一的用户数据概览区域 */
.profile-stats-unified {
display: flex;
gap: 32px;
align-items: center;
gap: 24px;
margin-left: auto;
flex-wrap: wrap;
}
.stat-item {
.profile-stats-unified .stat-item {
text-align: center;
min-width: 70px;
}
.stat-label {
.profile-stats-unified .stat-label {
font-size: 12px;
color: #909399;
margin-bottom: 4px;
}
.stat-value {
.profile-stats-unified .stat-value {
font-size: 16px;
font-weight: 600;
color: #303133;
}
.stats-divider {
height: 40px;
margin: 0 8px;
}
.action-divider {
margin: 0 0 20px 0;
}
@@ -1540,28 +1611,15 @@ onActivated(() => {
}
/* 推荐人选择器 */
.recommend-user-selector {
width: 100%;
}
.selected-user {
display: flex;
align-items: center;
gap: 10px;
padding: 8px 12px;
background: #f5f7fa;
border-radius: 6px;
border: 1px solid #e4e7ed;
}
.selected-user .user-name {
font-weight: 500;
color: #303133;
}
.selected-user .user-id {
/* 推荐人选择器样式 */
.clear-icon {
cursor: pointer;
color: #909399;
font-size: 12px;
transition: color 0.2s;
}
.clear-icon:hover {
color: #f56c6c;
}
@@ -1671,12 +1729,17 @@ onActivated(() => {
gap: 20px;
}
.profile-stats {
.profile-stats-unified {
width: 100%;
justify-content: space-around;
justify-content: flex-start;
background: #f9fafc;
padding: 16px;
border-radius: 8px;
margin-left: 0;
}
.stats-divider {
display: none;
}
.balance-overview {
@@ -1688,5 +1751,13 @@ onActivated(() => {
.balance-overview {
grid-template-columns: 1fr;
}
.profile-stats-unified {
gap: 16px;
}
.profile-stats-unified .stat-item {
min-width: 60px;
}
}
</style>