|
|
@@ -4,61 +4,83 @@
|
|
|
|
|
|
<!-- 我的主页 -->
|
|
|
<view v-else class="my-page">
|
|
|
- <!-- 自定义头部 -->
|
|
|
- <view class="custom-header" :style="{ paddingTop: statusBarHeight + 'px' }">
|
|
|
- <view class="header-content">
|
|
|
- <text class="header-title">{{ t('common.mine.title') }}</text>
|
|
|
- </view>
|
|
|
+ <!-- 顶部渐变背景区域 -->
|
|
|
+ <view class="header-bg" :style="{ paddingTop: statusBarHeight + 'px' }">
|
|
|
+ <text class="header-title">eTMF</text>
|
|
|
</view>
|
|
|
|
|
|
<!-- 页面内容 -->
|
|
|
- <view class="page-body">
|
|
|
- <!-- 用户名片区域 -->
|
|
|
+ <view class="page-content">
|
|
|
+ <!-- 用户信息卡片 -->
|
|
|
<view class="user-card">
|
|
|
- <image
|
|
|
- class="avatar"
|
|
|
- :src="userInfo.avatar"
|
|
|
- mode="aspectFill"
|
|
|
- :class="{ loading: loading }"
|
|
|
- @error="handleAvatarError"
|
|
|
- />
|
|
|
- <text class="nickname" :class="{ loading: loading }">{{ displayNickname }}</text>
|
|
|
+ <view class="user-info">
|
|
|
+ <image
|
|
|
+ class="avatar"
|
|
|
+ :src="userInfo.avatar"
|
|
|
+ mode="aspectFill"
|
|
|
+ @error="handleAvatarError"
|
|
|
+ />
|
|
|
+ <view class="user-details">
|
|
|
+ <text class="nickname">{{ displayNickname }}</text>
|
|
|
+ <text class="phone">{{ displayPhone }}</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view class="vip-badge" @click="handleVipClick">
|
|
|
+ <text class="vip-text">普通会员</text>
|
|
|
+ <text class="arrow">›</text>
|
|
|
+ </view>
|
|
|
</view>
|
|
|
|
|
|
- <!-- 功能列表 -->
|
|
|
- <view class="function-list">
|
|
|
- <!-- 基本信息 -->
|
|
|
- <view class="list-item" @click="handleBasicInfo">
|
|
|
- <view class="item-left">
|
|
|
- <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>
|
|
|
+ <!-- 我的任务 -->
|
|
|
+ <view class="task-section">
|
|
|
+ <view class="section-header">
|
|
|
+ <text class="section-title">我的任务</text>
|
|
|
+ <text class="arrow">›</text>
|
|
|
</view>
|
|
|
-
|
|
|
- <!-- 文件管理 -->
|
|
|
- <view class="list-item" @click="handleFileManage">
|
|
|
- <view class="item-left">
|
|
|
- <image class="item-icon" src="/static/pages-content/my/file.png" mode="aspectFit" />
|
|
|
- <text class="item-label">{{ t('common.mine.fileManage') }}</text>
|
|
|
+ <view class="task-grid">
|
|
|
+ <view class="task-item" @click="handleTaskClick('pending')">
|
|
|
+ <view class="task-icon-wrapper">
|
|
|
+ <image class="task-icon" src="/static/pages-content/my/task-pending.png" mode="aspectFit" />
|
|
|
+ <view v-if="taskCounts.pending > 0" class="task-badge">{{ taskCounts.pending }}</view>
|
|
|
+ </view>
|
|
|
+ <text class="task-label">待传递</text>
|
|
|
+ </view>
|
|
|
+ <view class="task-item" @click="handleTaskClick('delivered')">
|
|
|
+ <view class="task-icon-wrapper">
|
|
|
+ <image class="task-icon" src="/static/pages-content/my/task-delivered.png" mode="aspectFit" />
|
|
|
+ </view>
|
|
|
+ <text class="task-label">已传递</text>
|
|
|
+ </view>
|
|
|
+ <view class="task-item" @click="handleTaskClick('reviewing')">
|
|
|
+ <view class="task-icon-wrapper">
|
|
|
+ <image class="task-icon" src="/static/pages-content/my/task-reviewing.png" mode="aspectFit" />
|
|
|
+ <view v-if="taskCounts.reviewing > 0" class="task-badge">{{ taskCounts.reviewing }}</view>
|
|
|
+ </view>
|
|
|
+ <text class="task-label">待审核</text>
|
|
|
+ </view>
|
|
|
+ <view class="task-item" @click="handleTaskClick('approved')">
|
|
|
+ <view class="task-icon-wrapper">
|
|
|
+ <image class="task-icon" src="/static/pages-content/my/task-approved.png" mode="aspectFit" />
|
|
|
+ </view>
|
|
|
+ <text class="task-label">已审核</text>
|
|
|
</view>
|
|
|
- <text class="item-arrow">›</text>
|
|
|
</view>
|
|
|
-
|
|
|
- <!-- 审核管理 -->
|
|
|
- <view class="list-item" @click="handleAuditManage">
|
|
|
- <view class="item-left">
|
|
|
- <image class="item-icon" src="/static/pages-content/my/audit.png" mode="aspectFit" />
|
|
|
- <text class="item-label">{{ t('common.mine.auditManage') }}</text>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <!-- 功能列表 -->
|
|
|
+ <view class="menu-list">
|
|
|
+ <view class="menu-item" @click="handleProtocol">
|
|
|
+ <view class="menu-left">
|
|
|
+ <image class="menu-icon" src="/static/pages-content/my/icon-protocol.png" mode="aspectFit" />
|
|
|
+ <text class="menu-label">用户协议</text>
|
|
|
</view>
|
|
|
- <text class="item-arrow">›</text>
|
|
|
+ <text class="arrow">›</text>
|
|
|
</view>
|
|
|
|
|
|
- <!-- 语言切换 -->
|
|
|
- <view class="list-item">
|
|
|
- <view class="item-left">
|
|
|
- <image class="item-icon" src="/static/pages-content/my/language.png" mode="aspectFit" />
|
|
|
- <text class="item-label">{{ t('common.mine.languageSwitch') }}</text>
|
|
|
+ <view class="menu-item">
|
|
|
+ <view class="menu-left">
|
|
|
+ <image class="menu-icon" src="/static/pages-content/my/icon-language.png" mode="aspectFit" />
|
|
|
+ <text class="menu-label">语言切换</text>
|
|
|
</view>
|
|
|
<view class="language-switcher" @click="handleLanguageChange">
|
|
|
<text class="language-text" :class="{ active: locale === 'zh-CN' }">中</text>
|
|
|
@@ -67,19 +89,18 @@
|
|
|
</view>
|
|
|
</view>
|
|
|
|
|
|
- <!-- 协议说明 -->
|
|
|
- <view class="list-item" @click="handleProtocol">
|
|
|
- <view class="item-left">
|
|
|
- <image class="item-icon" src="/static/pages-content/my/aggrement.png" mode="aspectFit" />
|
|
|
- <text class="item-label">{{ t('common.mine.protocol') }}</text>
|
|
|
+ <view class="menu-item" @click="handleAbout">
|
|
|
+ <view class="menu-left">
|
|
|
+ <image class="menu-icon" src="/static/pages-content/my/icon-about.png" mode="aspectFit" />
|
|
|
+ <text class="menu-label">关于我们</text>
|
|
|
</view>
|
|
|
- <text class="item-arrow">›</text>
|
|
|
+ <text class="arrow">›</text>
|
|
|
</view>
|
|
|
</view>
|
|
|
|
|
|
<!-- 退出登录按钮 -->
|
|
|
<view class="logout-section">
|
|
|
- <button class="logout-btn" @click="handleLogout">{{ t('common.mine.logout') }}</button>
|
|
|
+ <button class="logout-btn" @click="handleLogout">退出登录</button>
|
|
|
</view>
|
|
|
</view>
|
|
|
</view>
|
|
|
@@ -106,18 +127,42 @@ const statusBarHeight = ref(0)
|
|
|
// 用户信息
|
|
|
const userInfo = ref({
|
|
|
avatar: '/static/default-avatar.svg',
|
|
|
- nickname: ''
|
|
|
+ nickname: '',
|
|
|
+ phoneNumber: ''
|
|
|
})
|
|
|
|
|
|
-// 加载状态
|
|
|
-const loading = ref(false)
|
|
|
+// 任务数量
|
|
|
+const taskCounts = ref({
|
|
|
+ pending: 6,
|
|
|
+ delivered: 0,
|
|
|
+ reviewing: 8,
|
|
|
+ approved: 0
|
|
|
+})
|
|
|
|
|
|
-// 显示的昵称(带加载状态)
|
|
|
+// 显示的昵称
|
|
|
const displayNickname = computed(() => {
|
|
|
- if (loading.value) {
|
|
|
- return t('common.mine.loading')
|
|
|
+ return userInfo.value.nickname || '未设置昵称'
|
|
|
+})
|
|
|
+
|
|
|
+// 加密手机号
|
|
|
+const encryptPhone = (phone) => {
|
|
|
+ if (!phone) return ''
|
|
|
+ // 如果手机号长度为11位,则加密中间4位
|
|
|
+ if (phone.length === 11) {
|
|
|
+ return phone.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2')
|
|
|
+ }
|
|
|
+ // 如果手机号长度不是11位,则加密中间部分
|
|
|
+ if (phone.length > 6) {
|
|
|
+ const start = phone.substring(0, 3)
|
|
|
+ const end = phone.substring(phone.length - 4)
|
|
|
+ return `${start}****${end}`
|
|
|
}
|
|
|
- return userInfo.value.nickname || t('common.mine.defaultNickname')
|
|
|
+ return phone
|
|
|
+}
|
|
|
+
|
|
|
+// 显示的手机号(加密)
|
|
|
+const displayPhone = computed(() => {
|
|
|
+ return encryptPhone(userInfo.value.phoneNumber)
|
|
|
})
|
|
|
|
|
|
onMounted(() => {
|
|
|
@@ -127,142 +172,116 @@ onMounted(() => {
|
|
|
|
|
|
// 获取用户信息
|
|
|
fetchUserInfo()
|
|
|
-
|
|
|
- console.log('我的内容组件已加载')
|
|
|
})
|
|
|
|
|
|
// 头像加载失败处理
|
|
|
const handleAvatarError = () => {
|
|
|
- console.log('头像加载失败,使用默认头像')
|
|
|
userInfo.value.avatar = '/static/default-avatar.svg'
|
|
|
}
|
|
|
|
|
|
// 获取用户信息
|
|
|
const fetchUserInfo = async () => {
|
|
|
try {
|
|
|
- loading.value = true
|
|
|
-
|
|
|
- // 调用 API 获取用户信息
|
|
|
const response = await getUserInfoAPI()
|
|
|
|
|
|
if (response && response.data) {
|
|
|
- // 更新用户信息
|
|
|
userInfo.value = {
|
|
|
avatar: response.data.avatar || '/static/default-avatar.svg',
|
|
|
- nickname: response.data.nickname || ''
|
|
|
+ nickname: response.data.nickname || '',
|
|
|
+ phoneNumber: response.data.phoneNumber || ''
|
|
|
}
|
|
|
|
|
|
- // 同步更新 store
|
|
|
userStore.setUserInfo(response.data)
|
|
|
}
|
|
|
} catch (error) {
|
|
|
console.error('获取用户信息失败:', error)
|
|
|
|
|
|
- // 如果API失败,尝试从本地store获取
|
|
|
const storedUserInfo = userStore.userInfo
|
|
|
- if (storedUserInfo && storedUserInfo.nickname) {
|
|
|
+ if (storedUserInfo) {
|
|
|
userInfo.value = {
|
|
|
avatar: storedUserInfo.avatar || '/static/default-avatar.svg',
|
|
|
- nickname: storedUserInfo.nickname
|
|
|
- }
|
|
|
- } else {
|
|
|
- userInfo.value = {
|
|
|
- avatar: '/static/default-avatar.svg',
|
|
|
- nickname: ''
|
|
|
+ nickname: storedUserInfo.nickname || '',
|
|
|
+ phoneNumber: storedUserInfo.phoneNumber || ''
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
- uni.showToast({
|
|
|
- title: t('common.mine.getUserInfoFailed'),
|
|
|
- icon: 'none',
|
|
|
- duration: 2000
|
|
|
- })
|
|
|
- } finally {
|
|
|
- loading.value = false
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-// 基本信息
|
|
|
-const handleBasicInfo = () => {
|
|
|
- showBasicInfo.value = true
|
|
|
-}
|
|
|
-
|
|
|
// 从基本信息返回主页
|
|
|
const handleBackToMain = () => {
|
|
|
showBasicInfo.value = false
|
|
|
}
|
|
|
|
|
|
-// 文件管理
|
|
|
-const handleFileManage = () => {
|
|
|
+// VIP点击
|
|
|
+const handleVipClick = () => {
|
|
|
uni.showToast({
|
|
|
- title: '文件管理',
|
|
|
+ title: '会员功能',
|
|
|
icon: 'none'
|
|
|
})
|
|
|
- // TODO: 跳转到文件管理页面
|
|
|
}
|
|
|
|
|
|
-// 审核管理
|
|
|
-const handleAuditManage = () => {
|
|
|
+// 任务点击
|
|
|
+const handleTaskClick = (type) => {
|
|
|
uni.showToast({
|
|
|
- title: '审核管理',
|
|
|
+ title: `${type}任务`,
|
|
|
icon: 'none'
|
|
|
})
|
|
|
- // TODO: 跳转到审核管理页面
|
|
|
+}
|
|
|
+
|
|
|
+// 协议说明
|
|
|
+const handleProtocol = () => {
|
|
|
+ uni.navigateTo({
|
|
|
+ url: '/pages-content/my/aggreement/index'
|
|
|
+ })
|
|
|
}
|
|
|
|
|
|
// 语言切换
|
|
|
const handleLanguageChange = () => {
|
|
|
localeStore.toggleLocale()
|
|
|
|
|
|
- // 延迟一下让语言切换生效后再显示提示
|
|
|
setTimeout(() => {
|
|
|
uni.showToast({
|
|
|
- title: t('common.language.switchSuccess'),
|
|
|
+ title: '语言切换成功',
|
|
|
icon: 'success',
|
|
|
duration: 1500
|
|
|
})
|
|
|
}, 100)
|
|
|
}
|
|
|
|
|
|
-// 协议说明
|
|
|
-const handleProtocol = () => {
|
|
|
- uni.navigateTo({
|
|
|
- url: '/pages-content/my/aggreement/index'
|
|
|
+// 关于我们
|
|
|
+const handleAbout = () => {
|
|
|
+ uni.showToast({
|
|
|
+ title: '关于我们',
|
|
|
+ icon: 'none'
|
|
|
})
|
|
|
}
|
|
|
|
|
|
// 退出登录
|
|
|
const handleLogout = () => {
|
|
|
uni.showModal({
|
|
|
- title: t('common.button.confirm'),
|
|
|
- content: t('common.mine.logoutConfirm'),
|
|
|
- confirmText: t('common.button.confirm'),
|
|
|
- cancelText: t('common.button.cancel'),
|
|
|
+ title: '提示',
|
|
|
+ content: '确定要退出登录吗?',
|
|
|
+ confirmText: '确定',
|
|
|
+ cancelText: '取消',
|
|
|
success: async (res) => {
|
|
|
if (res.confirm) {
|
|
|
try {
|
|
|
- // 显示加载状态
|
|
|
uni.showLoading({
|
|
|
- title: t('common.message.loading'),
|
|
|
+ title: '退出中...',
|
|
|
mask: true
|
|
|
})
|
|
|
|
|
|
- // 调用后端API
|
|
|
await logoutAPI()
|
|
|
-
|
|
|
- // API调用成功后,清除本地token和用户信息缓存
|
|
|
userStore.logout()
|
|
|
|
|
|
uni.hideLoading()
|
|
|
|
|
|
- // 显示退出成功提示
|
|
|
uni.showToast({
|
|
|
- title: t('common.mine.logoutSuccess'),
|
|
|
+ title: '已退出登录',
|
|
|
icon: 'success',
|
|
|
duration: 1500
|
|
|
})
|
|
|
|
|
|
- // 延迟跳转到登录页
|
|
|
setTimeout(() => {
|
|
|
uni.reLaunch({
|
|
|
url: '/pages/login/login'
|
|
|
@@ -273,11 +292,10 @@ const handleLogout = () => {
|
|
|
uni.hideLoading()
|
|
|
console.error('退出登录失败:', error)
|
|
|
|
|
|
- // 即使 API失败,也清除本地数据并跳转
|
|
|
userStore.logout()
|
|
|
|
|
|
uni.showToast({
|
|
|
- title: t('common.mine.logoutSuccess'),
|
|
|
+ title: '已退出登录',
|
|
|
icon: 'success',
|
|
|
duration: 1500
|
|
|
})
|
|
|
@@ -298,173 +316,217 @@ const handleLogout = () => {
|
|
|
.my-page {
|
|
|
width: 100%;
|
|
|
min-height: 100vh;
|
|
|
- display: flex;
|
|
|
- flex-direction: column;
|
|
|
- background: linear-gradient(180deg, #f8fcff 0%, #ffffff 100%);
|
|
|
+ background-color: #f5f5f5;
|
|
|
|
|
|
- // 自定义头部
|
|
|
- .custom-header {
|
|
|
- position: fixed;
|
|
|
- top: 0;
|
|
|
- left: 0;
|
|
|
- right: 0;
|
|
|
- background-color: #ffffff;
|
|
|
- border-bottom: 1rpx solid #e5e5e5;
|
|
|
- z-index: 100;
|
|
|
+ // 顶部渐变背景
|
|
|
+ .header-bg {
|
|
|
+ background: linear-gradient(180deg, #1ec9c9 0%, #1eb8b8 100%);
|
|
|
+ height: 200rpx;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
|
|
|
- .header-content {
|
|
|
- height: 88rpx;
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- justify-content: center;
|
|
|
-
|
|
|
- .header-title {
|
|
|
- font-size: 32rpx;
|
|
|
- font-weight: 500;
|
|
|
- color: #000000;
|
|
|
- }
|
|
|
+ .header-title {
|
|
|
+ font-size: 36rpx;
|
|
|
+ font-weight: 600;
|
|
|
+ color: #ffffff;
|
|
|
+ letter-spacing: 4rpx;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 页面内容
|
|
|
- .page-body {
|
|
|
- flex: 1;
|
|
|
- margin-top: 88rpx;
|
|
|
- padding: 40rpx;
|
|
|
+ .page-content {
|
|
|
+ padding: 0 24rpx;
|
|
|
+ margin-top: -80rpx;
|
|
|
|
|
|
- // 用户名片区域
|
|
|
+ // 用户信息卡片
|
|
|
.user-card {
|
|
|
- background: linear-gradient(135deg, #6ec7f5 0%, #4eb8f0 100%);
|
|
|
- border-radius: 24rpx;
|
|
|
- padding: 80rpx 40rpx 60rpx;
|
|
|
+ background: #ffffff;
|
|
|
+ border-radius: 16rpx;
|
|
|
+ padding: 32rpx 24rpx;
|
|
|
+ margin-bottom: 24rpx;
|
|
|
display: flex;
|
|
|
- flex-direction: column;
|
|
|
align-items: center;
|
|
|
- margin-bottom: 40rpx;
|
|
|
- box-shadow: 0 8rpx 24rpx rgba(110, 199, 245, 0.25);
|
|
|
- position: relative;
|
|
|
- overflow: hidden;
|
|
|
+ justify-content: space-between;
|
|
|
+ box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.08);
|
|
|
|
|
|
- // 背景装饰
|
|
|
- &::before {
|
|
|
- content: '';
|
|
|
- position: absolute;
|
|
|
- top: -50%;
|
|
|
- right: -20%;
|
|
|
- width: 400rpx;
|
|
|
- height: 400rpx;
|
|
|
- background: rgba(255, 255, 255, 0.1);
|
|
|
- border-radius: 50%;
|
|
|
+ .user-info {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ flex: 1;
|
|
|
+
|
|
|
+ .avatar {
|
|
|
+ width: 100rpx;
|
|
|
+ height: 100rpx;
|
|
|
+ border-radius: 50%;
|
|
|
+ margin-right: 24rpx;
|
|
|
+ border: 4rpx solid #f0f0f0;
|
|
|
+ }
|
|
|
+
|
|
|
+ .user-details {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ gap: 8rpx;
|
|
|
+
|
|
|
+ .nickname {
|
|
|
+ font-size: 32rpx;
|
|
|
+ font-weight: 600;
|
|
|
+ color: #333333;
|
|
|
+ }
|
|
|
+
|
|
|
+ .phone {
|
|
|
+ font-size: 26rpx;
|
|
|
+ color: #999999;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- &::after {
|
|
|
- content: '';
|
|
|
- position: absolute;
|
|
|
- bottom: -30%;
|
|
|
- left: -10%;
|
|
|
- width: 300rpx;
|
|
|
- height: 300rpx;
|
|
|
- background: rgba(255, 255, 255, 0.08);
|
|
|
- border-radius: 50%;
|
|
|
+ .vip-badge {
|
|
|
+ background: linear-gradient(135deg, #666666 0%, #555555 100%);
|
|
|
+ border-radius: 30rpx;
|
|
|
+ padding: 12rpx 24rpx;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ gap: 8rpx;
|
|
|
+
|
|
|
+ .vip-text {
|
|
|
+ font-size: 24rpx;
|
|
|
+ color: #ffffff;
|
|
|
+ font-weight: 500;
|
|
|
+ }
|
|
|
+
|
|
|
+ .arrow {
|
|
|
+ font-size: 32rpx;
|
|
|
+ color: #ffffff;
|
|
|
+ font-weight: 300;
|
|
|
+ }
|
|
|
}
|
|
|
+ }
|
|
|
+
|
|
|
+ // 我的任务
|
|
|
+ .task-section {
|
|
|
+ background: #ffffff;
|
|
|
+ border-radius: 16rpx;
|
|
|
+ padding: 32rpx 24rpx;
|
|
|
+ margin-bottom: 24rpx;
|
|
|
+ box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.08);
|
|
|
|
|
|
- .avatar {
|
|
|
- width: 140rpx;
|
|
|
- height: 140rpx;
|
|
|
- border-radius: 70rpx;
|
|
|
- margin-bottom: 24rpx;
|
|
|
- border: 6rpx solid rgba(255, 255, 255, 0.3);
|
|
|
- box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.2);
|
|
|
- position: relative;
|
|
|
- z-index: 1;
|
|
|
- transition: opacity 0.3s;
|
|
|
+ .section-header {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: space-between;
|
|
|
+ margin-bottom: 32rpx;
|
|
|
|
|
|
- &.loading {
|
|
|
- opacity: 0.5;
|
|
|
- animation: pulse 1.5s ease-in-out infinite;
|
|
|
+ .section-title {
|
|
|
+ font-size: 30rpx;
|
|
|
+ font-weight: 600;
|
|
|
+ color: #333333;
|
|
|
+ }
|
|
|
+
|
|
|
+ .arrow {
|
|
|
+ font-size: 40rpx;
|
|
|
+ color: #cccccc;
|
|
|
+ font-weight: 300;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- .nickname {
|
|
|
- font-size: 40rpx;
|
|
|
- font-weight: bold;
|
|
|
- color: #ffffff;
|
|
|
- text-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.2);
|
|
|
- position: relative;
|
|
|
- z-index: 1;
|
|
|
- transition: opacity 0.3s;
|
|
|
+ .task-grid {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
|
|
|
- &.loading {
|
|
|
- opacity: 0.7;
|
|
|
+ .task-item {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ align-items: center;
|
|
|
+ gap: 16rpx;
|
|
|
+ flex: 1;
|
|
|
+
|
|
|
+ .task-icon-wrapper {
|
|
|
+ position: relative;
|
|
|
+ width: 88rpx;
|
|
|
+ height: 88rpx;
|
|
|
+
|
|
|
+ .task-icon {
|
|
|
+ width: 88rpx;
|
|
|
+ height: 88rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .task-badge {
|
|
|
+ position: absolute;
|
|
|
+ top: -8rpx;
|
|
|
+ right: -8rpx;
|
|
|
+ background: #ff4444;
|
|
|
+ color: #ffffff;
|
|
|
+ font-size: 20rpx;
|
|
|
+ font-weight: 600;
|
|
|
+ min-width: 32rpx;
|
|
|
+ height: 32rpx;
|
|
|
+ border-radius: 16rpx;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ padding: 0 8rpx;
|
|
|
+ border: 3rpx solid #ffffff;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .task-label {
|
|
|
+ font-size: 24rpx;
|
|
|
+ color: #666666;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 功能列表
|
|
|
- .function-list {
|
|
|
- background-color: #ffffff;
|
|
|
- border-radius: 20rpx;
|
|
|
+ .menu-list {
|
|
|
+ background: #ffffff;
|
|
|
+ border-radius: 16rpx;
|
|
|
overflow: hidden;
|
|
|
- margin-bottom: 40rpx;
|
|
|
- box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.06);
|
|
|
+ margin-bottom: 24rpx;
|
|
|
+ box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.08);
|
|
|
|
|
|
- .list-item {
|
|
|
+ .menu-item {
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
justify-content: space-between;
|
|
|
- padding: 36rpx 40rpx;
|
|
|
- border-bottom: 1rpx solid #f0f0f0;
|
|
|
- transition: all 0.3s ease;
|
|
|
- position: relative;
|
|
|
+ padding: 32rpx 24rpx;
|
|
|
+ border-bottom: 1rpx solid #f5f5f5;
|
|
|
|
|
|
&:last-child {
|
|
|
border-bottom: none;
|
|
|
}
|
|
|
|
|
|
&:active {
|
|
|
- background-color: #f0faff;
|
|
|
- }
|
|
|
-
|
|
|
- // 左侧渐变条
|
|
|
- &::before {
|
|
|
- content: '';
|
|
|
- position: absolute;
|
|
|
- left: 0;
|
|
|
- top: 50%;
|
|
|
- transform: translateY(-50%);
|
|
|
- width: 6rpx;
|
|
|
- height: 60%;
|
|
|
- background: linear-gradient(180deg, #6ec7f5 0%, #4eb8f0 100%);
|
|
|
- border-radius: 0 6rpx 6rpx 0;
|
|
|
- opacity: 0;
|
|
|
- transition: opacity 0.3s;
|
|
|
- }
|
|
|
-
|
|
|
- &:active::before {
|
|
|
- opacity: 1;
|
|
|
+ background-color: #f8f8f8;
|
|
|
}
|
|
|
|
|
|
- .item-left {
|
|
|
+ .menu-left {
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
|
|
|
- .item-icon {
|
|
|
- width: 44rpx;
|
|
|
- height: 44rpx;
|
|
|
- margin-right: 28rpx;
|
|
|
+ .menu-icon {
|
|
|
+ width: 40rpx;
|
|
|
+ height: 40rpx;
|
|
|
+ margin-right: 24rpx;
|
|
|
}
|
|
|
|
|
|
- .item-label {
|
|
|
- font-size: 30rpx;
|
|
|
+ .menu-label {
|
|
|
+ font-size: 28rpx;
|
|
|
color: #333333;
|
|
|
- font-weight: 500;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ .arrow {
|
|
|
+ font-size: 40rpx;
|
|
|
+ color: #cccccc;
|
|
|
+ font-weight: 300;
|
|
|
+ }
|
|
|
+
|
|
|
.language-switcher {
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
- background: rgba(110, 199, 245, 0.08);
|
|
|
+ background: rgba(30, 201, 201, 0.08);
|
|
|
backdrop-filter: blur(10rpx);
|
|
|
border-radius: 30rpx;
|
|
|
padding: 8rpx 20rpx;
|
|
|
@@ -474,7 +536,7 @@ const handleLogout = () => {
|
|
|
|
|
|
&:active {
|
|
|
transform: scale(0.95);
|
|
|
- background: rgba(110, 199, 245, 0.15);
|
|
|
+ background: rgba(30, 201, 201, 0.15);
|
|
|
}
|
|
|
|
|
|
.language-text {
|
|
|
@@ -484,7 +546,7 @@ const handleLogout = () => {
|
|
|
transition: all 0.3s;
|
|
|
|
|
|
&.active {
|
|
|
- color: #6ec7f5;
|
|
|
+ color: #1ec9c9;
|
|
|
font-weight: 700;
|
|
|
}
|
|
|
}
|
|
|
@@ -495,36 +557,27 @@ const handleLogout = () => {
|
|
|
font-weight: 300;
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
- .item-arrow {
|
|
|
- font-size: 48rpx;
|
|
|
- color: #d0d0d0;
|
|
|
- font-weight: 300;
|
|
|
- }
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 退出登录
|
|
|
.logout-section {
|
|
|
- padding: 0;
|
|
|
+ padding: 32rpx 0 60rpx;
|
|
|
|
|
|
.logout-btn {
|
|
|
width: 100%;
|
|
|
- height: 96rpx;
|
|
|
- line-height: 96rpx;
|
|
|
- background: linear-gradient(135deg, #ff6b6b 0%, #ee5a6f 100%);
|
|
|
- border-radius: 20rpx;
|
|
|
+ height: 88rpx;
|
|
|
+ line-height: 88rpx;
|
|
|
+ background: #ffffff;
|
|
|
+ border-radius: 16rpx;
|
|
|
border: none;
|
|
|
- font-size: 32rpx;
|
|
|
- color: #ffffff;
|
|
|
- font-weight: 600;
|
|
|
- box-shadow: 0 6rpx 20rpx rgba(255, 107, 107, 0.3);
|
|
|
- letter-spacing: 2rpx;
|
|
|
- padding: 0;
|
|
|
+ font-size: 28rpx;
|
|
|
+ color: #1ec9c9;
|
|
|
+ font-weight: 500;
|
|
|
+ box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.08);
|
|
|
|
|
|
&:active {
|
|
|
- opacity: 0.9;
|
|
|
- transform: scale(0.98);
|
|
|
+ opacity: 0.8;
|
|
|
}
|
|
|
|
|
|
&::after {
|
|
|
@@ -534,14 +587,4 @@ const handleLogout = () => {
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
-// 加载动画
|
|
|
-@keyframes pulse {
|
|
|
- 0%, 100% {
|
|
|
- opacity: 0.5;
|
|
|
- }
|
|
|
- 50% {
|
|
|
- opacity: 0.8;
|
|
|
- }
|
|
|
-}
|
|
|
</style>
|