|
|
@@ -1,5 +1,9 @@
|
|
|
<template>
|
|
|
- <view class="my-page">
|
|
|
+ <!-- 基本信息组件 -->
|
|
|
+ <BasicInfo v-if="showBasicInfo" @back="handleBackToMain" />
|
|
|
+
|
|
|
+ <!-- 我的主页 -->
|
|
|
+ <view v-else class="my-page">
|
|
|
<!-- 自定义头部 -->
|
|
|
<view class="custom-header" :style="{ paddingTop: statusBarHeight + 'px' }">
|
|
|
<view class="header-content">
|
|
|
@@ -26,7 +30,7 @@
|
|
|
<!-- 基本信息 -->
|
|
|
<view class="list-item" @click="handleBasicInfo">
|
|
|
<view class="item-left">
|
|
|
- <text class="item-icon">👤</text>
|
|
|
+ <image class="item-icon" src="/static/pages-content/my/info.png" mode="aspectFit" />
|
|
|
<text class="item-label">{{ t('common.mine.basicInfo') }}</text>
|
|
|
</view>
|
|
|
<text class="item-arrow">›</text>
|
|
|
@@ -35,7 +39,7 @@
|
|
|
<!-- 文件管理 -->
|
|
|
<view class="list-item" @click="handleFileManage">
|
|
|
<view class="item-left">
|
|
|
- <text class="item-icon">📁</text>
|
|
|
+ <image class="item-icon" src="/static/pages-content/my/file.png" mode="aspectFit" />
|
|
|
<text class="item-label">{{ t('common.mine.fileManage') }}</text>
|
|
|
</view>
|
|
|
<text class="item-arrow">›</text>
|
|
|
@@ -44,7 +48,7 @@
|
|
|
<!-- 审核管理 -->
|
|
|
<view class="list-item" @click="handleAuditManage">
|
|
|
<view class="item-left">
|
|
|
- <text class="item-icon">📋</text>
|
|
|
+ <image class="item-icon" src="/static/pages-content/my/audit.png" mode="aspectFit" />
|
|
|
<text class="item-label">{{ t('common.mine.auditManage') }}</text>
|
|
|
</view>
|
|
|
<text class="item-arrow">›</text>
|
|
|
@@ -53,23 +57,20 @@
|
|
|
<!-- 语言切换 -->
|
|
|
<view class="list-item">
|
|
|
<view class="item-left">
|
|
|
- <text class="item-icon">🌐</text>
|
|
|
+ <image class="item-icon" src="/static/pages-content/my/language.png" mode="aspectFit" />
|
|
|
<text class="item-label">{{ t('common.mine.languageSwitch') }}</text>
|
|
|
</view>
|
|
|
- <view class="item-right">
|
|
|
- <text class="language-text">{{ currentLanguage }}</text>
|
|
|
- <switch
|
|
|
- :checked="isEnglish"
|
|
|
- @change="handleLanguageChange"
|
|
|
- color="#007aff"
|
|
|
- />
|
|
|
+ <view class="language-switcher" @click="handleLanguageChange">
|
|
|
+ <text class="language-text" :class="{ active: locale === 'zh-CN' }">中</text>
|
|
|
+ <text class="language-separator">|</text>
|
|
|
+ <text class="language-text" :class="{ active: locale === 'en-US' }">EN</text>
|
|
|
</view>
|
|
|
</view>
|
|
|
|
|
|
<!-- 协议说明 -->
|
|
|
<view class="list-item" @click="handleProtocol">
|
|
|
<view class="item-left">
|
|
|
- <text class="item-icon">📄</text>
|
|
|
+ <image class="item-icon" src="/static/pages-content/my/aggrement.png" mode="aspectFit" />
|
|
|
<text class="item-label">{{ t('common.mine.protocol') }}</text>
|
|
|
</view>
|
|
|
<text class="item-arrow">›</text>
|
|
|
@@ -85,16 +86,20 @@
|
|
|
</template>
|
|
|
|
|
|
<script setup>
|
|
|
+import BasicInfo from './info/index.vue'
|
|
|
import { ref, computed, onMounted } from 'vue'
|
|
|
import { useI18n } from 'vue-i18n'
|
|
|
import { useUserStore } from '@/store/index'
|
|
|
import { useLocaleStore } from '@/store/locale'
|
|
|
-import { getUserInfo as getUserInfoAPI } from '@/apis/auth'
|
|
|
+import { getUserInfo as getUserInfoAPI, logout as logoutAPI } from '@/apis/auth'
|
|
|
|
|
|
const { t, locale } = useI18n()
|
|
|
const userStore = useUserStore()
|
|
|
const localeStore = useLocaleStore()
|
|
|
|
|
|
+// 控制显示哪个组件
|
|
|
+const showBasicInfo = ref(false)
|
|
|
+
|
|
|
// 状态栏高度
|
|
|
const statusBarHeight = ref(0)
|
|
|
|
|
|
@@ -107,11 +112,6 @@ const userInfo = ref({
|
|
|
// 加载状态
|
|
|
const loading = ref(false)
|
|
|
|
|
|
-// 当前语言显示
|
|
|
-const currentLanguage = computed(() => {
|
|
|
- return locale.value === 'zh-CN' ? t('common.language.zh') : t('common.language.en')
|
|
|
-})
|
|
|
-
|
|
|
// 显示的昵称(带加载状态)
|
|
|
const displayNickname = computed(() => {
|
|
|
if (loading.value) {
|
|
|
@@ -120,11 +120,6 @@ const displayNickname = computed(() => {
|
|
|
return userInfo.value.nickname || t('common.mine.defaultNickname')
|
|
|
})
|
|
|
|
|
|
-// 是否英文
|
|
|
-const isEnglish = computed(() => {
|
|
|
- return locale.value === 'en-US'
|
|
|
-})
|
|
|
-
|
|
|
onMounted(() => {
|
|
|
// 获取系统信息
|
|
|
const systemInfo = uni.getSystemInfoSync()
|
|
|
@@ -189,11 +184,12 @@ const fetchUserInfo = async () => {
|
|
|
|
|
|
// 基本信息
|
|
|
const handleBasicInfo = () => {
|
|
|
- uni.showToast({
|
|
|
- title: '基本信息',
|
|
|
- icon: 'none'
|
|
|
- })
|
|
|
- // TODO: 跳转到基本信息页面
|
|
|
+ showBasicInfo.value = true
|
|
|
+}
|
|
|
+
|
|
|
+// 从基本信息返回主页
|
|
|
+const handleBackToMain = () => {
|
|
|
+ showBasicInfo.value = false
|
|
|
}
|
|
|
|
|
|
// 文件管理
|
|
|
@@ -215,31 +211,24 @@ const handleAuditManage = () => {
|
|
|
}
|
|
|
|
|
|
// 语言切换
|
|
|
-const handleLanguageChange = (e) => {
|
|
|
- const isChecked = e.detail.value
|
|
|
- const newLocale = isChecked ? 'en-US' : 'zh-CN'
|
|
|
-
|
|
|
- const success = localeStore.setLocale(newLocale)
|
|
|
+const handleLanguageChange = () => {
|
|
|
+ localeStore.toggleLocale()
|
|
|
|
|
|
- if (success) {
|
|
|
- // 延迟一下让语言切换生效后再显示提示
|
|
|
- setTimeout(() => {
|
|
|
- uni.showToast({
|
|
|
- title: t('common.language.switchSuccess'),
|
|
|
- icon: 'success',
|
|
|
- duration: 1500
|
|
|
- })
|
|
|
- }, 100)
|
|
|
- }
|
|
|
+ // 延迟一下让语言切换生效后再显示提示
|
|
|
+ setTimeout(() => {
|
|
|
+ uni.showToast({
|
|
|
+ title: t('common.language.switchSuccess'),
|
|
|
+ icon: 'success',
|
|
|
+ duration: 1500
|
|
|
+ })
|
|
|
+ }, 100)
|
|
|
}
|
|
|
|
|
|
// 协议说明
|
|
|
const handleProtocol = () => {
|
|
|
- uni.showToast({
|
|
|
- title: '协议说明',
|
|
|
- icon: 'none'
|
|
|
+ uni.navigateTo({
|
|
|
+ url: '/pages-content/my/aggreement/index'
|
|
|
})
|
|
|
- // TODO: 跳转到协议说明页面
|
|
|
}
|
|
|
|
|
|
// 退出登录
|
|
|
@@ -249,24 +238,56 @@ const handleLogout = () => {
|
|
|
content: t('common.mine.logoutConfirm'),
|
|
|
confirmText: t('common.button.confirm'),
|
|
|
cancelText: t('common.button.cancel'),
|
|
|
- success: (res) => {
|
|
|
+ success: async (res) => {
|
|
|
if (res.confirm) {
|
|
|
- // 清除本地token和用户信息缓存
|
|
|
- userStore.logout()
|
|
|
-
|
|
|
- // 显示退出成功提示
|
|
|
- uni.showToast({
|
|
|
- title: t('common.mine.logoutSuccess'),
|
|
|
- icon: 'success',
|
|
|
- duration: 1500
|
|
|
- })
|
|
|
-
|
|
|
- // 延迟跳转到登录页
|
|
|
- setTimeout(() => {
|
|
|
- uni.reLaunch({
|
|
|
- url: '/pages/login/login'
|
|
|
+ try {
|
|
|
+ // 显示加载状态
|
|
|
+ uni.showLoading({
|
|
|
+ title: t('common.message.loading'),
|
|
|
+ mask: true
|
|
|
})
|
|
|
- }, 1500)
|
|
|
+
|
|
|
+ // 调用后端API
|
|
|
+ await logoutAPI()
|
|
|
+
|
|
|
+ // API调用成功后,清除本地token和用户信息缓存
|
|
|
+ userStore.logout()
|
|
|
+
|
|
|
+ uni.hideLoading()
|
|
|
+
|
|
|
+ // 显示退出成功提示
|
|
|
+ uni.showToast({
|
|
|
+ title: t('common.mine.logoutSuccess'),
|
|
|
+ icon: 'success',
|
|
|
+ duration: 1500
|
|
|
+ })
|
|
|
+
|
|
|
+ // 延迟跳转到登录页
|
|
|
+ setTimeout(() => {
|
|
|
+ uni.reLaunch({
|
|
|
+ url: '/pages/login/login'
|
|
|
+ })
|
|
|
+ }, 1500)
|
|
|
+
|
|
|
+ } catch (error) {
|
|
|
+ uni.hideLoading()
|
|
|
+ console.error('退出登录失败:', error)
|
|
|
+
|
|
|
+ // 即使 API失败,也清除本地数据并跳转
|
|
|
+ userStore.logout()
|
|
|
+
|
|
|
+ uni.showToast({
|
|
|
+ title: t('common.mine.logoutSuccess'),
|
|
|
+ icon: 'success',
|
|
|
+ duration: 1500
|
|
|
+ })
|
|
|
+
|
|
|
+ setTimeout(() => {
|
|
|
+ uni.reLaunch({
|
|
|
+ url: '/pages/login/login'
|
|
|
+ })
|
|
|
+ }, 1500)
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
})
|
|
|
@@ -279,7 +300,7 @@ const handleLogout = () => {
|
|
|
min-height: 100vh;
|
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
|
- background: linear-gradient(180deg, #f0f4ff 0%, #f8f9fa 100%);
|
|
|
+ background: linear-gradient(180deg, #f8fcff 0%, #ffffff 100%);
|
|
|
|
|
|
// 自定义头部
|
|
|
.custom-header {
|
|
|
@@ -313,14 +334,14 @@ const handleLogout = () => {
|
|
|
|
|
|
// 用户名片区域
|
|
|
.user-card {
|
|
|
- background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
|
+ background: linear-gradient(135deg, #6ec7f5 0%, #4eb8f0 100%);
|
|
|
border-radius: 24rpx;
|
|
|
padding: 80rpx 40rpx 60rpx;
|
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
|
align-items: center;
|
|
|
margin-bottom: 40rpx;
|
|
|
- box-shadow: 0 8rpx 24rpx rgba(102, 126, 234, 0.3);
|
|
|
+ box-shadow: 0 8rpx 24rpx rgba(110, 199, 245, 0.25);
|
|
|
position: relative;
|
|
|
overflow: hidden;
|
|
|
|
|
|
@@ -385,7 +406,7 @@ const handleLogout = () => {
|
|
|
border-radius: 20rpx;
|
|
|
overflow: hidden;
|
|
|
margin-bottom: 40rpx;
|
|
|
- box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.08);
|
|
|
+ box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.06);
|
|
|
|
|
|
.list-item {
|
|
|
display: flex;
|
|
|
@@ -401,8 +422,7 @@ const handleLogout = () => {
|
|
|
}
|
|
|
|
|
|
&:active {
|
|
|
- background-color: #f8f9ff;
|
|
|
- transform: scale(0.98);
|
|
|
+ background-color: #f0faff;
|
|
|
}
|
|
|
|
|
|
// 左侧渐变条
|
|
|
@@ -414,7 +434,7 @@ const handleLogout = () => {
|
|
|
transform: translateY(-50%);
|
|
|
width: 6rpx;
|
|
|
height: 60%;
|
|
|
- background: linear-gradient(180deg, #667eea 0%, #764ba2 100%);
|
|
|
+ background: linear-gradient(180deg, #6ec7f5 0%, #4eb8f0 100%);
|
|
|
border-radius: 0 6rpx 6rpx 0;
|
|
|
opacity: 0;
|
|
|
transition: opacity 0.3s;
|
|
|
@@ -429,9 +449,9 @@ const handleLogout = () => {
|
|
|
align-items: center;
|
|
|
|
|
|
.item-icon {
|
|
|
- font-size: 44rpx;
|
|
|
+ width: 44rpx;
|
|
|
+ height: 44rpx;
|
|
|
margin-right: 28rpx;
|
|
|
- filter: drop-shadow(0 2rpx 4rpx rgba(0, 0, 0, 0.1));
|
|
|
}
|
|
|
|
|
|
.item-label {
|
|
|
@@ -441,15 +461,38 @@ const handleLogout = () => {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- .item-right {
|
|
|
+ .language-switcher {
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
- gap: 20rpx;
|
|
|
+ background: rgba(110, 199, 245, 0.08);
|
|
|
+ backdrop-filter: blur(10rpx);
|
|
|
+ border-radius: 30rpx;
|
|
|
+ padding: 8rpx 20rpx;
|
|
|
+ cursor: pointer;
|
|
|
+ transition: all 0.3s;
|
|
|
+ gap: 8rpx;
|
|
|
+
|
|
|
+ &:active {
|
|
|
+ transform: scale(0.95);
|
|
|
+ background: rgba(110, 199, 245, 0.15);
|
|
|
+ }
|
|
|
|
|
|
.language-text {
|
|
|
- font-size: 26rpx;
|
|
|
- color: #667eea;
|
|
|
+ font-size: 24rpx;
|
|
|
+ color: #999;
|
|
|
font-weight: 500;
|
|
|
+ transition: all 0.3s;
|
|
|
+
|
|
|
+ &.active {
|
|
|
+ color: #6ec7f5;
|
|
|
+ font-weight: 700;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .language-separator {
|
|
|
+ font-size: 24rpx;
|
|
|
+ color: #ccc;
|
|
|
+ font-weight: 300;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -468,6 +511,7 @@ const handleLogout = () => {
|
|
|
.logout-btn {
|
|
|
width: 100%;
|
|
|
height: 96rpx;
|
|
|
+ line-height: 96rpx;
|
|
|
background: linear-gradient(135deg, #ff6b6b 0%, #ee5a6f 100%);
|
|
|
border-radius: 20rpx;
|
|
|
border: none;
|
|
|
@@ -476,11 +520,16 @@ const handleLogout = () => {
|
|
|
font-weight: 600;
|
|
|
box-shadow: 0 6rpx 20rpx rgba(255, 107, 107, 0.3);
|
|
|
letter-spacing: 2rpx;
|
|
|
+ padding: 0;
|
|
|
|
|
|
&:active {
|
|
|
opacity: 0.9;
|
|
|
transform: scale(0.98);
|
|
|
}
|
|
|
+
|
|
|
+ &::after {
|
|
|
+ border: none;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|