Files
zgty-mas-m/pages/index/index.vue
2025-09-30 00:08:23 +08:00

547 lines
13 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!-- 首页 - 重新设计 -->
<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>