ai-clone/frontend-ai/pages/user-switch/user-switch.vue

401 lines
8.0 KiB
Vue
Raw Normal View History

2026-03-05 14:29:21 +08:00
<template>
<view class="user-switch-container">
<view class="header">
<text class="title">👤 用户切换</text>
<text class="subtitle">用于测试用户数据隔离</text>
</view>
<!-- 当前用户信息 -->
<view class="current-user">
<view class="section-title">当前用户</view>
<view class="user-card">
<view class="user-info">
<text class="user-id">ID: {{ currentUserId || '未设置' }}</text>
<text class="user-name">{{ currentUserName }}</text>
</view>
</view>
</view>
<!-- 用户列表 -->
<view class="user-list">
<view class="section-title">选择用户</view>
<view
v-for="user in users"
:key="user.id"
:class="['user-item', currentUserId == user.id ? 'active' : '']"
@click="switchUser(user)"
>
<view class="user-avatar">{{ user.avatar }}</view>
<view class="user-details">
<text class="user-name">{{ user.nickname }}</text>
<text class="user-phone">{{ user.phone }}</text>
<text class="user-desc">{{ user.desc }}</text>
</view>
<view v-if="currentUserId == user.id" class="check-icon"></view>
</view>
</view>
<!-- 操作按钮 -->
<view class="actions">
<button class="action-btn refresh" @click="refreshData">
🔄 刷新数据
</button>
<button class="action-btn clear" @click="clearUser">
<image src="/static/iconfont/delete.svg" class="delete-icon" mode="aspectFit"></image>
清除用户
</button>
</view>
<!-- 说明 -->
<view class="tips">
<text class="tips-title">💡 使用说明</text>
<text class="tips-item"> 切换用户后只能看到该用户的数据</text>
<text class="tips-item"> 新创建的数据会关联到当前用户</text>
<text class="tips-item"> 默认用户是张三13800138001</text>
<text class="tips-item"> 切换后需要刷新页面才能看到效果</text>
</view>
</view>
</template>
<script>
export default {
data() {
return {
currentUserId: null,
currentUserName: '未登录',
users: [
{
id: 1,
username: 'zhangsan',
nickname: '张三',
phone: '13800138001',
avatar: '👨',
desc: '默认测试用户'
},
{
id: 2,
username: 'lisi',
nickname: '李四',
phone: '13800138002',
avatar: '👩',
desc: '测试用户2'
},
{
id: 3,
username: 'wangwu',
nickname: '王五',
phone: '13800138003',
avatar: '👨‍💼',
desc: '测试用户3'
},
{
id: 4,
username: 'zhaoliu',
nickname: '赵六',
phone: '13800138004',
avatar: '👩‍💼',
desc: '测试用户4'
},
{
id: 5,
username: 'testuser',
nickname: '测试用户',
phone: '13800138005',
avatar: '🧑',
desc: '测试用户5'
}
]
}
},
onLoad() {
this.loadCurrentUser();
},
methods: {
// 加载当前用户
loadCurrentUser() {
const userId = uni.getStorageSync('userId');
const userNickname = uni.getStorageSync('userNickname');
this.currentUserId = userId;
this.currentUserName = userNickname || '未登录';
console.log('[UserSwitch] 当前用户ID:', userId);
},
// 切换用户
switchUser(user) {
uni.showModal({
title: '切换用户',
content: `确定要切换到 ${user.nickname}${user.phone})吗?`,
success: (res) => {
if (res.confirm) {
// 保存用户信息
uni.setStorageSync('userId', user.id);
uni.setStorageSync('userPhone', user.phone);
uni.setStorageSync('userNickname', user.nickname);
uni.setStorageSync('username', user.username);
// 更新当前用户
this.currentUserId = user.id;
this.currentUserName = user.nickname;
uni.showToast({
title: `已切换到 ${user.nickname}`,
icon: 'success',
duration: 2000
});
console.log('[UserSwitch] 切换到用户:', user);
// 提示刷新
setTimeout(() => {
uni.showModal({
title: '提示',
content: '用户已切换,是否返回首页刷新数据?',
confirmText: '返回首页',
cancelText: '稍后',
success: (res) => {
if (res.confirm) {
uni.switchTab({
url: '/pages/index/index'
});
}
}
});
}, 2000);
}
}
});
},
// 刷新数据
refreshData() {
uni.showLoading({
title: '刷新中...'
});
// 重新加载当前用户
this.loadCurrentUser();
setTimeout(() => {
uni.hideLoading();
uni.showToast({
title: '刷新成功',
icon: 'success'
});
}, 500);
},
// 清除用户
clearUser() {
uni.showModal({
title: '清除用户',
content: '确定要清除当前用户信息吗?',
confirmColor: '#ff4444',
success: (res) => {
if (res.confirm) {
uni.removeStorageSync('userId');
uni.removeStorageSync('userPhone');
uni.removeStorageSync('userNickname');
uni.removeStorageSync('username');
this.currentUserId = null;
this.currentUserName = '未登录';
uni.showToast({
title: '已清除',
icon: 'success'
});
}
}
});
}
}
}
</script>
<style lang="scss" scoped>
.user-switch-container {
min-height: 100vh;
background: linear-gradient(180deg, #f8f9fa 0%, #e9ecef 100%);
padding-bottom: 40rpx;
}
.header {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
padding: 60rpx 30rpx 40rpx;
text-align: center;
box-shadow: 0 8rpx 24rpx rgba(102, 126, 234, 0.3);
}
.title {
font-size: 48rpx;
font-weight: bold;
color: white;
display: block;
margin-bottom: 12rpx;
}
.subtitle {
font-size: 26rpx;
color: rgba(255, 255, 255, 0.8);
display: block;
}
.current-user {
padding: 30rpx;
}
.section-title {
font-size: 32rpx;
font-weight: bold;
color: #333;
margin-bottom: 20rpx;
}
.user-card {
background: white;
border-radius: 20rpx;
padding: 30rpx;
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.08);
}
.user-info {
display: flex;
flex-direction: column;
gap: 12rpx;
}
.user-id {
font-size: 28rpx;
color: #666;
font-family: monospace;
}
.user-name {
font-size: 36rpx;
font-weight: bold;
color: #333;
}
.user-list {
padding: 0 30rpx 30rpx;
}
.user-item {
background: white;
border-radius: 20rpx;
padding: 30rpx;
margin-bottom: 20rpx;
display: flex;
align-items: center;
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.08);
transition: all 0.3s;
&.active {
background: linear-gradient(135deg, rgba(102, 126, 234, 0.1) 0%, rgba(118, 75, 162, 0.1) 100%);
border: 2rpx solid #667eea;
box-shadow: 0 8rpx 24rpx rgba(102, 126, 234, 0.2);
}
&:active {
transform: scale(0.98);
}
}
.user-avatar {
font-size: 60rpx;
margin-right: 24rpx;
flex-shrink: 0;
}
.user-details {
flex: 1;
display: flex;
flex-direction: column;
gap: 8rpx;
}
.user-details .user-name {
font-size: 32rpx;
font-weight: bold;
color: #333;
}
.user-phone {
font-size: 26rpx;
color: #666;
font-family: monospace;
}
.user-desc {
font-size: 24rpx;
color: #999;
}
.check-icon {
font-size: 40rpx;
color: #667eea;
font-weight: bold;
margin-left: 16rpx;
}
.actions {
padding: 0 30rpx;
display: flex;
gap: 20rpx;
margin-bottom: 30rpx;
}
.action-btn {
flex: 1;
padding: 28rpx;
border: none;
border-radius: 16rpx;
font-size: 28rpx;
font-weight: bold;
color: white;
&.refresh {
background: linear-gradient(135deg, #34d399 0%, #10b981 100%);
box-shadow: 0 4rpx 12rpx rgba(52, 211, 153, 0.3);
}
&.clear {
background: linear-gradient(135deg, #f87171 0%, #ef4444 100%);
box-shadow: 0 4rpx 12rpx rgba(248, 113, 113, 0.3);
}
&:active {
transform: translateY(2rpx);
}
}
.tips {
background: white;
border-radius: 20rpx;
padding: 30rpx;
margin: 0 30rpx;
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.08);
}
.tips-title {
font-size: 28rpx;
font-weight: bold;
color: #333;
display: block;
margin-bottom: 16rpx;
}
.tips-item {
font-size: 26rpx;
color: #666;
line-height: 1.8;
display: block;
margin-bottom: 8rpx;
}
</style>