ai-clone/frontend-ai/pages/user-switch/user-switch.vue
2026-03-05 14:29:21 +08:00

401 lines
8.0 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="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>