Add admin-frontend and user-frontend standalone projects, certification/invoice/discovery features, fix auth header and theme consistency
This commit is contained in:
@@ -0,0 +1,119 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="8">
|
||||
<el-card shadow="never">
|
||||
<div style="text-align:center;padding:20px 0">
|
||||
<el-avatar :size="72" style="background:#409eff;font-size:28px">{{ (user?.username || 'U')[0].toUpperCase() }}</el-avatar>
|
||||
<h3 style="margin:12px 0 4px">{{ user?.username || '用户' }}</h3>
|
||||
<el-tag size="small" :type="tierType(user?.tier)">{{ user?.tier || 'free' }}</el-tag>
|
||||
<el-tag v-if="user?.role === 'admin'" type="danger" size="small" style="margin-left:4px">管理员</el-tag>
|
||||
</div>
|
||||
<el-divider style="margin:8px 0" />
|
||||
<div class="profile-menu">
|
||||
<div class="menu-item" @click="$router.push('/upgrade')">
|
||||
<el-icon><Crown /></el-icon><span>升级会员</span>
|
||||
</div>
|
||||
<div class="menu-item" @click="$router.push('/certification')">
|
||||
<el-icon><Stamp /></el-icon><span>实名认证</span>
|
||||
</div>
|
||||
<div class="menu-item" @click="$router.push('/invoice')">
|
||||
<el-icon><List /></el-icon><span>发票管理</span>
|
||||
</div>
|
||||
<div class="menu-item" @click="$router.push('/notifications')">
|
||||
<el-icon><Bell /></el-icon><span>通知中心</span>
|
||||
</div>
|
||||
<div class="menu-item" @click="$router.push('/feedback')">
|
||||
<el-icon><ChatDotSquare /></el-icon><span>意见反馈</span>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="16">
|
||||
<el-card shadow="never">
|
||||
<template #header><span>编辑资料</span></template>
|
||||
<el-form :model="form" label-width="80" size="large">
|
||||
<el-form-item label="用户名">
|
||||
<el-input v-model="form.username" :disabled="true" />
|
||||
</el-form-item>
|
||||
<el-form-item label="邮箱">
|
||||
<el-input v-model="form.email" placeholder="输入邮箱" />
|
||||
</el-form-item>
|
||||
<el-form-item label="手机">
|
||||
<el-input v-model="form.phone" :disabled="true" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" :loading="saving" @click="saveProfile">保存</el-button>
|
||||
<el-button @click="showPassword = true">修改密码</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-dialog v-model="showPassword" title="修改密码" width="400">
|
||||
<el-form :model="pwForm" label-width="80">
|
||||
<el-form-item label="旧密码"><el-input v-model="pwForm.old_password" type="password" /></el-form-item>
|
||||
<el-form-item label="新密码"><el-input v-model="pwForm.new_password" type="password" /></el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="showPassword = false">取消</el-button>
|
||||
<el-button type="primary" :loading="pwLoading" @click="changePw">确认</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, onMounted } from 'vue'
|
||||
import { useAuthStore } from '@/stores/auth'
|
||||
import { updateProfile, changePassword } from '@/api'
|
||||
import { ElMessage } from 'element-plus'
|
||||
|
||||
const auth = useAuthStore()
|
||||
const user = auth.user
|
||||
const saving = ref(false)
|
||||
const showPassword = ref(false)
|
||||
const pwLoading = ref(false)
|
||||
const form = reactive({ username: '', email: '', phone: '' })
|
||||
const pwForm = reactive({ old_password: '', new_password: '' })
|
||||
|
||||
function tierType(t) { return { free: 'warning', pro: 'primary', enterprise: 'success' }[t] || 'info' }
|
||||
|
||||
onMounted(() => {
|
||||
if (user.value) {
|
||||
form.username = user.value.username || ''
|
||||
form.email = user.value.email || ''
|
||||
form.phone = user.value.phone || ''
|
||||
}
|
||||
})
|
||||
|
||||
async function saveProfile() {
|
||||
saving.value = true
|
||||
try {
|
||||
await updateProfile({ email: form.email })
|
||||
ElMessage.success('已保存')
|
||||
auth.fetchUser()
|
||||
} catch (e) { ElMessage.error(e?.detail || '保存失败') }
|
||||
finally { saving.value = false }
|
||||
}
|
||||
|
||||
async function changePw() {
|
||||
if (!pwForm.old_password || !pwForm.new_password) { ElMessage.warning('请填写完整'); return }
|
||||
pwLoading.value = true
|
||||
try {
|
||||
await changePassword(pwForm)
|
||||
ElMessage.success('密码已修改')
|
||||
showPassword.value = false
|
||||
pwForm.old_password = ''
|
||||
pwForm.new_password = ''
|
||||
} catch (e) { ElMessage.error(e?.detail || '修改失败') }
|
||||
finally { pwLoading.value = false }
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.profile-menu { padding: 0; }
|
||||
.menu-item { display: flex; align-items: center; gap: 10px; padding: 12px 16px; cursor: pointer; border-radius: 6px; transition: background 0.2s; }
|
||||
.menu-item:hover { background: #f0f5ff; color: #409eff; }
|
||||
</style>
|
||||
Reference in New Issue
Block a user