| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239 |
- <route lang="json5" type="page">
- {
- layout: 'default',
- style: {
- navigationBarTitleText: '我的',
- navigationStyle: 'custom',
- },
- }
- </route>
- <template>
- <view class="user-container">
- <!-- 状态栏占位 -->
- <view class="status-bar-placeholder" :style="{ height: statusBarHeight + 'px' }"></view>
- <!-- 头部区域 -->
- <view class="header-view">
- <image class="logo" :src="iconMap.Logo_tj" mode="aspectFit" />
- <view class="dept-view">
- <text class="dept-text">{{ currentUserInfo.nickname }}</text>
- <text class="dept-text">{{ currentUserInfo.deptName }}</text>
- </view>
- </view>
- <!-- 表单信息 -->
- <view class="form-view">
- <view
- v-for="item in userConfig"
- :key="item.field"
- class="form-item"
- @click="handleItemClick(item)"
- >
- <text>{{ item.label }}</text>
- <text v-if="item.type === 'text'" class="normal-text">
- {{ currentUserInfo[item.field] }}
- </text>
- <image v-else-if="item.type === 'image'" class="avatar" :src="getImage(item.field)" />
- <text v-if="item.field === 'version'" class="arrow-indicator">></text>
- </view>
- </view>
- <!-- 退出登录 -->
- <view class="logout">
- <button class="logout-btn" @click="handleLogout">
- <text class="logout-btn-text">退出登录</text>
- </button>
- </view>
- </view>
- </template>
- <script lang="ts" setup>
- import { ref, onMounted } from 'vue'
- import { onShow } from '@dcloudio/uni-app'
- import { useUserStore } from '@/store/user'
- import { logout } from '@/api/login'
- import iconMap from '@/utils/imagesMap'
- import { config } from '@/utils/config'
- defineOptions({
- name: 'user',
- })
- // 状态栏高度
- const statusBarHeight = ref(20)
- const systemInfo = uni.getSystemInfoSync()
- statusBarHeight.value = systemInfo.statusBarHeight || 20
- const userStore = useUserStore()
- const currentUserInfo = computed(() => userStore.userInfo)
- // 用户配置
- const userConfig = [
- { label: '头像', field: 'avatar', type: 'image' },
- { label: '姓名', field: 'username', type: 'text' },
- { label: '昵称', field: 'nickname', type: 'text' },
- { label: '手机号', field: 'mobile', type: 'text' },
- { label: '邮箱地址', field: 'email', type: 'text' },
- // { label: '关于系统', field: 'version', type: 'text' },
- ]
- // onShow(() => {
- // console.log('load user info')
- // loadUserInfo()
- // })
- // 加载用户信息
- // const loadUserInfo = () => {
- // try {
- // const userInfo = uni.getStorageSync('APP_USER_INFO')
- // if (userInfo) {
- // const info = { ...JSON.parse(userInfo) }
- // currentUserInfo.value = info
- // } else {
- // // 没有用户信息,跳转到登录页
- // uni.redirectTo({ url: '/pages/login/login' })
- // }
- // } catch (err) {
- // console.error('获取用户信息失败:', err)
- // uni.redirectTo({ url: '/pages/login/login' })
- // }
- // }
- // 获取图片 URL
- const getImage = (key: string) => {
- return config.file_url + currentUserInfo.value[key]
- }
- // 处理点击
- const handleItemClick = (item: any) => {
- if (item.field === 'version') {
- // 跳转到关于系统页面
- uni.navigateTo({ url: '/pages/aboutSystem/index' })
- }
- }
- // 退出登录
- const handleLogout = async () => {
- try {
- await logout()
- // 清除 store
- userStore.clearUserInfo()
- // 清除本地存储
- uni.removeStorageSync('APP_ACCESS_TOKEN')
- uni.removeStorageSync('APP_USER_INFO')
- uni.removeStorageSync('USER_LIST')
- // 通知RN端也退出登录
- if (window.ReactNativeWebView) {
- window.ReactNativeWebView.postMessage(JSON.stringify({ type: 'logout' }))
- }
- // 跳转到登录页
- uni.reLaunch({ url: '/pages/login/login' })
- } catch (error) {
- console.error('退出登录失败:', error)
- }
- }
- </script>
- <style lang="scss" scoped>
- .user-container {
- display: flex;
- flex-direction: column;
- min-height: 100vh;
- background-color: #fff;
- }
- .status-bar-placeholder {
- width: 100%;
- background-color: #d8d8d8;
- }
- .header-view {
- display: flex;
- flex-direction: column;
- gap: 10px;
- align-items: center;
- padding-top: 20px;
- padding-bottom: 20px;
- background-color: #d8d8d8;
- }
- .logo {
- width: 160px;
- height: 160px;
- border-radius: 10px;
- }
- .dept-view {
- display: flex;
- flex-direction: row;
- gap: 10px;
- align-items: center;
- }
- .dept-text {
- font-size: 20px;
- color: #081f50;
- }
- .form-view {
- padding: 0 16px;
- }
- .form-item {
- display: flex;
- flex-direction: row;
- gap: 10px;
- align-items: center;
- justify-content: space-between;
- height: 44px;
- border-bottom: 1px solid rgba(0, 0, 0, 0.1);
- }
- .avatar {
- width: 40px;
- height: 40px;
- border-radius: 20px;
- }
- .normal-text {
- flex: 1;
- font-size: 14px;
- color: #333;
- text-align: right;
- }
- .arrow-indicator {
- font-size: 16px;
- font-weight: bold;
- color: #ccc;
- }
- .logout {
- display: flex;
- flex-direction: row;
- justify-content: center;
- padding: 0 16px;
- margin-top: 60px;
- }
- .logout-btn {
- display: flex;
- align-items: center;
- justify-content: center;
- height: 40px;
- padding: 0 24px;
- background-color: transparent;
- border: none;
- border-radius: 20px;
- }
- .logout-btn-text {
- font-size: 16px;
- color: #081f50;
- }
- </style>
|