547 lines
13 KiB
Vue
547 lines
13 KiB
Vue
<!-- 首页 - 重新设计 -->
|
||
<template>
|
||
<view class="container">
|
||
<s-layout
|
||
title="首页"
|
||
navbar="custom"
|
||
tabbar="/pages/index/index"
|
||
onShareAppMessage
|
||
>
|
||
<!-- 用户信息区域 - 使用 uview-plus Card 组件 -->
|
||
<u-card
|
||
v-if="isLogin"
|
||
:show-head="false"
|
||
:show-foot="false"
|
||
margin="30rpx"
|
||
>
|
||
<template #body>
|
||
<view class="user-info-section">
|
||
<view class="user-avatar">
|
||
<s-avatar
|
||
:src="userInfo.avatar"
|
||
:nickname="userInfo.nickname || userInfo.username"
|
||
:size="60"
|
||
:bg-color="getAvatarBgColor(userInfo.nickname || userInfo.username)"
|
||
@click="handleUserClick"
|
||
/>
|
||
</view>
|
||
<view class="user-details">
|
||
<u-text
|
||
:text="userInfo.nickname || '用户'"
|
||
size="18"
|
||
color="#333"
|
||
bold
|
||
/>
|
||
<u-text
|
||
:text="userInfo.mobile || '欢迎使用系统'"
|
||
size="14"
|
||
color="#999"
|
||
margin="6rpx 0 0 0"
|
||
/>
|
||
</view>
|
||
<view class="user-actions">
|
||
<u-button
|
||
text="个人中心"
|
||
size="mini"
|
||
type="primary"
|
||
plain
|
||
@click="navigateTo('/pages/index/user')"
|
||
margin="0 0 10rpx 0"
|
||
/>
|
||
<u-button
|
||
text="退出登录"
|
||
size="mini"
|
||
type="error"
|
||
plain
|
||
@click="handleLogout"
|
||
/>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
</u-card>
|
||
|
||
<!-- 未登录提示区域 - 使用 uview-plus Card 和 Button -->
|
||
<u-card
|
||
v-else
|
||
:show-head="false"
|
||
:show-foot="false"
|
||
margin="30rpx"
|
||
>
|
||
<template #body>
|
||
<view class="login-prompt">
|
||
<view class="prompt-content">
|
||
<u-text text="欢迎使用" size="20" color="#333" bold />
|
||
<u-text
|
||
text="请先登录以使用完整功能"
|
||
size="14"
|
||
color="#999"
|
||
margin="10rpx 0 30rpx 0"
|
||
/>
|
||
<u-button
|
||
text="立即登录"
|
||
type="primary"
|
||
size="normal"
|
||
@click="goToLogin"
|
||
/>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
</u-card>
|
||
|
||
<!-- 功能模块入口 - 使用 uview-plus Grid 组件 -->
|
||
<u-card
|
||
v-if="isLogin"
|
||
:show-head="false"
|
||
:show-foot="false"
|
||
margin="30rpx"
|
||
>
|
||
<template #body>
|
||
<view class="function-modules">
|
||
<view class="section-title">
|
||
<u-text text="功能模块" size="16" color="#333" bold />
|
||
</view>
|
||
<u-grid :col="3" :border="false">
|
||
<u-grid-item
|
||
v-for="module in functionModules"
|
||
:key="module.id"
|
||
@click="handleModuleClick(module)"
|
||
>
|
||
<view class="module-content">
|
||
<view class="module-icon" :style="{ backgroundColor: module.color + '20' }">
|
||
<u-icon :name="module.icon" size="24" :color="module.color" />
|
||
</view>
|
||
<u-text
|
||
:text="module.name"
|
||
size="12"
|
||
color="#666"
|
||
margin="10rpx 0 0 0"
|
||
/>
|
||
</view>
|
||
</u-grid-item>
|
||
</u-grid>
|
||
</view>
|
||
</template>
|
||
</u-card>
|
||
|
||
</s-layout>
|
||
</view>
|
||
</template>
|
||
|
||
<script setup>
|
||
import { onLoad, onPullDownRefresh, onShow } from '@dcloudio/uni-app';
|
||
import { computed, ref } from 'vue';
|
||
import sheep from '@/sheep';
|
||
import { getAvatarBgColor } from '@/sheep/utils/avatar.js';
|
||
|
||
// 隐藏原生tabBar
|
||
uni.hideTabBar({
|
||
fail: () => {},
|
||
});
|
||
|
||
// 跳转到登录页
|
||
function goToLogin() {
|
||
uni.navigateTo({
|
||
url: '/pages/login/index'
|
||
});
|
||
}
|
||
|
||
const isLogin = computed(() => sheep.$store('user').isLogin);
|
||
const userInfo = computed(() => sheep.$store('user').userInfo);
|
||
|
||
// 用于防止重复验证
|
||
let isValidating = false;
|
||
|
||
// 用户头像点击事件
|
||
function handleUserClick() {
|
||
if (!isLogin.value) {
|
||
goToLogin();
|
||
return;
|
||
}
|
||
uni.navigateTo({
|
||
url: '/pages/index/user'
|
||
});
|
||
}
|
||
|
||
// 格式化最后登录时间
|
||
const formatLastLoginTime = computed(() => {
|
||
const now = new Date();
|
||
return `${now.getMonth() + 1}月${now.getDate()}日 ${now.getHours()}:${now.getMinutes().toString().padStart(2, '0')}`;
|
||
});
|
||
|
||
// 功能模块数据
|
||
const functionModules = ref([
|
||
{
|
||
id: 'profile',
|
||
name: '个人资料',
|
||
icon: 'account',
|
||
color: 'var(--ui-BG-Main)', // 主题色
|
||
path: '/pages/index/user'
|
||
},
|
||
{
|
||
id: 'settings',
|
||
name: '系统设置',
|
||
icon: 'setting',
|
||
color: '#666666', // $dark-6
|
||
action: 'showSettings'
|
||
},
|
||
{
|
||
id: 'security',
|
||
name: '安全中心',
|
||
icon: 'lock',
|
||
color: '#d10019', // $red
|
||
action: 'showSecurity'
|
||
},
|
||
{
|
||
id: 'feedback',
|
||
name: '意见反馈',
|
||
icon: 'chat',
|
||
color: '#8dc63f', // $green
|
||
action: 'showFeedback'
|
||
}
|
||
]);
|
||
|
||
// 快捷操作数据
|
||
const quickActions = ref([
|
||
|
||
{
|
||
id: 'logout',
|
||
title: '退出登录',
|
||
desc: '安全退出当前账户',
|
||
icon: 'logout',
|
||
action: 'logout'
|
||
}
|
||
]);
|
||
|
||
onLoad((options) => {
|
||
console.log('首页加载完成');
|
||
checkLoginStatus();
|
||
});
|
||
|
||
onShow(() => {
|
||
// 只有在页面从后台返回前台时才需要重新验证登录状态
|
||
// 避免首次加载时的重复验证
|
||
console.log('页面显示,检查是否需要验证登录状态');
|
||
|
||
// 延迟一点时间,确保不与onLoad的验证冲突
|
||
setTimeout(() => {
|
||
checkLoginStatus();
|
||
}, 100);
|
||
});
|
||
|
||
onPullDownRefresh(async () => {
|
||
console.log('下拉刷新');
|
||
try {
|
||
// 刷新用户信息
|
||
if (isLogin.value) {
|
||
await sheep.$store('user').getInfo();
|
||
console.log('用户信息刷新成功');
|
||
}
|
||
} catch (error) {
|
||
console.log('刷新用户信息失败,可能登录已过期', error);
|
||
// 如果刷新失败,可能是登录过期,重新验证登录状态
|
||
await checkLoginStatus();
|
||
} finally {
|
||
setTimeout(() => {
|
||
uni.stopPullDownRefresh();
|
||
}, 1000);
|
||
}
|
||
});
|
||
|
||
// 检查登录状态
|
||
async function checkLoginStatus() {
|
||
// 防止重复验证
|
||
if (isValidating) {
|
||
console.log('正在验证中,跳过重复验证');
|
||
return;
|
||
}
|
||
|
||
console.log('检查登录状态...');
|
||
|
||
// 如果本地显示未登录,直接跳转到登录页
|
||
if (!isLogin.value) {
|
||
console.log('本地状态未登录,跳转到登录页');
|
||
setTimeout(() => {
|
||
goToLogin();
|
||
}, 500);
|
||
return;
|
||
}
|
||
|
||
// 如果本地显示已登录,需要验证token是否还有效
|
||
console.log('本地状态已登录,验证token有效性...');
|
||
isValidating = true;
|
||
|
||
try {
|
||
// 尝试获取用户信息来验证token是否有效
|
||
await sheep.$store('user').getInfo();
|
||
console.log('Token有效,用户已登录');
|
||
} catch (error) {
|
||
console.log('Token已失效,需要重新登录', error);
|
||
// 清除本地登录状态
|
||
sheep.$store('user').logout(false);
|
||
// 延迟显示登录弹窗,确保页面渲染完成
|
||
setTimeout(() => {
|
||
uni.showToast({
|
||
title: '登录已过期,请重新登录',
|
||
icon: 'none',
|
||
duration: 2000
|
||
});
|
||
setTimeout(() => {
|
||
goToLogin();
|
||
}, 2000);
|
||
}, 500);
|
||
} finally {
|
||
// 验证完成,重置标志
|
||
setTimeout(() => {
|
||
isValidating = false;
|
||
}, 1000);
|
||
}
|
||
}
|
||
|
||
// 导航到指定页面
|
||
function navigateTo(path) {
|
||
uni.navigateTo({
|
||
url: path
|
||
});
|
||
}
|
||
|
||
// 处理退出登录
|
||
function handleLogout() {
|
||
uni.showModal({
|
||
title: '退出登录',
|
||
content: '确定要退出登录吗?',
|
||
showCancel: true,
|
||
confirmText: '确定',
|
||
cancelText: '取消',
|
||
success: async (res) => {
|
||
if (res.confirm) {
|
||
try {
|
||
// 显示加载提示
|
||
uni.showLoading({
|
||
title: '退出中...',
|
||
mask: true
|
||
});
|
||
|
||
// 调用退出登录API
|
||
await sheep.$store('user').logout(true);
|
||
|
||
// 隐藏加载提示
|
||
uni.hideLoading();
|
||
|
||
// 显示退出成功提示
|
||
uni.showToast({
|
||
title: '退出成功',
|
||
icon: 'success',
|
||
duration: 1500
|
||
});
|
||
|
||
// 延迟跳转到登录页
|
||
setTimeout(() => {
|
||
goToLogin();
|
||
}, 1500);
|
||
|
||
} catch (error) {
|
||
// 隐藏加载提示
|
||
uni.hideLoading();
|
||
|
||
console.error('退出登录失败:', error);
|
||
uni.showToast({
|
||
title: '退出失败,请重试',
|
||
icon: 'none',
|
||
duration: 2000
|
||
});
|
||
}
|
||
}
|
||
}
|
||
});
|
||
}
|
||
|
||
// 处理模块点击
|
||
function handleModuleClick(module) {
|
||
if (module.path) {
|
||
navigateTo(module.path);
|
||
} else if (module.action) {
|
||
handleAction(module.action);
|
||
}
|
||
}
|
||
|
||
// 处理快捷操作点击
|
||
function handleActionClick(action) {
|
||
handleAction(action.action);
|
||
}
|
||
|
||
// 处理各种操作
|
||
function handleAction(action) {
|
||
switch (action) {
|
||
case 'showSettings':
|
||
uni.showToast({
|
||
title: '系统设置功能开发中',
|
||
icon: 'none'
|
||
});
|
||
break;
|
||
case 'showSecurity':
|
||
uni.showToast({
|
||
title: '安全中心功能开发中',
|
||
icon: 'none'
|
||
});
|
||
break;
|
||
case 'showFeedback':
|
||
uni.showToast({
|
||
title: '意见反馈功能开发中',
|
||
icon: 'none'
|
||
});
|
||
break;
|
||
case 'showAbout':
|
||
uni.showModal({
|
||
title: '关于应用',
|
||
content: '应用版本:v1.0.0\n开发者:Yudao Team\n更新时间:2024年',
|
||
showCancel: false
|
||
});
|
||
break;
|
||
case 'scanCode':
|
||
uni.scanCode({
|
||
success: (res) => {
|
||
uni.showModal({
|
||
title: '扫描结果',
|
||
content: res.result,
|
||
showCancel: false
|
||
});
|
||
},
|
||
fail: (err) => {
|
||
uni.showToast({
|
||
title: '扫描失败',
|
||
icon: 'none'
|
||
});
|
||
}
|
||
});
|
||
break;
|
||
case 'shareApp':
|
||
uni.share({
|
||
provider: 'weixin',
|
||
scene: 'WXSceneSession',
|
||
type: 0,
|
||
href: '',
|
||
title: '推荐一个好用的应用',
|
||
summary: '快来试试这个应用吧!',
|
||
imageUrl: ''
|
||
});
|
||
break;
|
||
case 'clearCache':
|
||
uni.showModal({
|
||
title: '清理缓存',
|
||
content: '确定要清理应用缓存吗?',
|
||
success: (res) => {
|
||
if (res.confirm) {
|
||
// 这里可以添加清理缓存的逻辑
|
||
uni.clearStorageSync();
|
||
uni.showToast({
|
||
title: '缓存清理完成',
|
||
icon: 'success'
|
||
});
|
||
}
|
||
}
|
||
});
|
||
break;
|
||
case 'logout':
|
||
handleLogout();
|
||
break;
|
||
default:
|
||
uni.showToast({
|
||
title: '功能开发中',
|
||
icon: 'none'
|
||
});
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.container {
|
||
min-height: 100vh;
|
||
background: #f5f5f5;
|
||
}
|
||
|
||
/* 用户信息区域 */
|
||
.user-info-section {
|
||
display: flex;
|
||
align-items: center;
|
||
padding: 20rpx;
|
||
}
|
||
|
||
.user-avatar {
|
||
margin-right: 20rpx;
|
||
}
|
||
|
||
.user-details {
|
||
flex: 1;
|
||
}
|
||
|
||
.user-actions {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 10rpx;
|
||
}
|
||
|
||
/* 未登录提示区域 */
|
||
.login-prompt {
|
||
text-align: center;
|
||
padding: 40rpx 20rpx;
|
||
}
|
||
|
||
.prompt-content {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
gap: 10rpx;
|
||
}
|
||
|
||
/* 功能模块 */
|
||
.function-modules {
|
||
padding: 20rpx;
|
||
}
|
||
|
||
.section-title {
|
||
margin-bottom: 20rpx;
|
||
}
|
||
|
||
.module-content {
|
||
text-align: center;
|
||
padding: 20rpx 10rpx;
|
||
}
|
||
|
||
.module-icon {
|
||
width: 60rpx;
|
||
height: 60rpx;
|
||
border-radius: 50%;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
margin: 0 auto 10rpx;
|
||
}
|
||
|
||
/* 快捷操作 */
|
||
.quick-actions {
|
||
padding: 20rpx;
|
||
}
|
||
|
||
.action-icon {
|
||
width: 40rpx;
|
||
height: 40rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
margin-right: 15rpx;
|
||
background: #f0f0f0;
|
||
border-radius: 8rpx;
|
||
}
|
||
|
||
/* 系统信息 */
|
||
.system-info {
|
||
padding: 20rpx;
|
||
}
|
||
|
||
.info-row {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
padding: 15rpx 0;
|
||
}
|
||
</style> |