wlzboy
2025-10-26 2c86a8bd60deed0dd0e044bad6fb83f75d19a332
app/pages/mine/index.vue
New file
@@ -0,0 +1,339 @@
<template>
  <view class="mine-container">
    <!--顶部个人信息栏-->
    <view class="header-section">
      <view class="flex padding justify-between">
        <view class="flex align-center">
          <view v-if="!avatar" class="cu-avatar xl round bg-white">
            <view class="iconfont icon-people text-gray icon"></view>
          </view>
          <image v-if="avatar" @click="handleToAvatar" :src="avatar" class="cu-avatar xl round" mode="widthFix">
          </image>
          <view v-if="!name" @click="handleToLogin" class="login-tip">
            点击登录
          </view>
          <view v-if="name" @click="handleToInfo" class="user-info">
            <view class="u_title">
              {{ name }}
            </view>
          </view>
        </view>
        <view @click="handleToInfo" class="flex align-center">
          <text>个人信息</text>
          <view class="iconfont icon-right"></view>
        </view>
      </view>
    </view>
    <scroll-view class="content-section" scroll-y="true">
      <!-- 用户信息展示 -->
      <view class="user-info-section">
        <view class="info-item">
          <view class="info-label">昵称:</view>
          <view class="info-value">{{ name || '未登录' }}</view>
        </view>
        <view class="info-item">
          <view class="info-label">手机号码:</view>
          <view class="info-value">{{ phonenumber || '未绑定' }}</view>
        </view>
        <view class="info-item">
          <view class="info-label">所属分公司:</view>
          <view class="info-value">{{ deptName || '未设置' }}</view>
        </view>
        <view class="info-item">
          <view class="info-label">绑定车辆:</view>
          <view class="info-value">{{ boundVehicle || '未绑定' }}</view>
        </view>
        <view class="info-item">
          <view class="info-label">App版本号:</view>
          <view class="info-value">{{ version || '1.0.0' }}</view>
        </view>
      </view>
      <view class="menu-list">
        <!-- 绑定/解绑车辆 -->
        <view class="list-cell list-cell-arrow" @click="handleVehicleBinding">
          <view class="menu-item-box">
            <view class="iconfont icon-car menu-icon"></view>
            <view>{{ boundVehicle && boundVehicle !== '未绑定' ? '更换车辆' : '绑定车辆' }}</view>
          </view>
        </view>
        <!-- 退出登录 -->
        <view class="list-cell list-cell-arrow" @click="handleLogout">
          <view class="menu-item-box">
            <view class="iconfont icon-logout menu-icon text-red"></view>
            <view class="text-red">退出登录</view>
          </view>
        </view>
      </view>
    </scroll-view>
  </view>
</template>
<script>
  import storage from '@/utils/storage'
  import { getUserProfile } from "@/api/system/user"
  import { getUserBoundVehicle, unbindVehicleFromUser } from '@/api/vehicle'
  import { getSystemInfo } from '@/utils/common'
  export default {
    data() {
      return {
        name: this.$store.state.user.nickName,
        phonenumber: '',
        deptName: '', // 所属分公司
        boundVehicle: '', // 绑定的车辆信息
        boundVehicleId: null, // 绑定的车辆ID
        version: getApp().globalData.config.appInfo.version
      }
    },
    computed: {
      avatar() {
        return this.$store.state.user.avatar
      },
      windowHeight() {
        return getSystemInfo().windowHeight - 50
      }
    },
    onLoad() {
      this.getUserInfo()
    },
    onShow() {
      // 每次显示页面时刷新用户信息
      this.getUserInfo()
    },
    methods: {
      // 获取用户信息
      getUserInfo() {
        const userId = this.$store.state.user.userId
        // 获取用户基本信息
        getUserProfile().then(response => {
          const user = response.data
          this.name = user.nickName || user.userName // 优先使用昵称
          this.phonenumber = user.phonenumber
          this.deptName = user.dept ? user.dept.deptName : '未设置'
        }).catch(() => {
          // 获取用户信息失败时使用默认值
          this.name = this.$store.state.user.nickName || '未登录'
          this.phonenumber = '未绑定'
          this.deptName = '未设置'
        })
        // 获取用户绑定的车辆信息
        if (userId) {
          getUserBoundVehicle(userId).then(response => {
            if (response.code === 200 && response.data) {
              const vehicle = response.data
              this.boundVehicle = vehicle.vehicleNumber || '未知车牌'
              this.boundVehicleId = vehicle.vehicleId
            } else {
              this.boundVehicle = '未绑定'
              this.boundVehicleId = null
            }
          }).catch(() => {
            this.boundVehicle = '未绑定'
            this.boundVehicleId = null
          })
        }
      },
      // 处理车辆绑定操作
      handleVehicleBinding() {
        this.$tab.navigateTo('/pages/bind-vehicle')
      },
      handleToInfo() {
        this.$tab.navigateTo('/pages/mine/info/index')
      },
      handleToEditInfo() {
        this.$tab.navigateTo('/pages/mine/info/edit')
      },
      handleToSetting() {
        this.$tab.navigateTo('/pages/mine/setting/index')
      },
      handleToLogin() {
        this.$tab.reLaunch('/pages/login')
      },
      handleToAvatar() {
        this.$tab.navigateTo('/pages/mine/avatar/index')
      },
      handleLogout() {
        this.$modal.confirm('确定退出登录吗?').then(() => {
          this.$store.dispatch('LogOut').then(() => {
            this.$tab.reLaunch('/pages/login')
          })
        })
      }
    }
  }
</script>
<style lang="scss">
  page {
    background-color: #f5f6f7;
  }
  .mine-container {
    width: 100%;
    height: 100vh;
    display: flex;
    flex-direction: column;
    // 隐藏滚动条但保持滚动功能
    ::-webkit-scrollbar {
      display: none;
      width: 0 !important;
      height: 0 !important;
      background: transparent;
    }
    // Firefox滚动条隐藏
    * {
      scrollbar-width: none; /* Firefox */
    }
    // IE/Edge滚动条隐藏
    * {
      -ms-overflow-style: none; /* IE 10+ */
    }
    .header-section {
      padding: 15px 15px 45px 15px;
      background-color: #3c96f3;
      color: white;
      flex-shrink: 0; // 防止收缩
      .login-tip {
        font-size: 18px;
        margin-left: 10px;
      }
      .cu-avatar {
        border: 2px solid #eaeaea;
        .icon {
          font-size: 40px;
        }
      }
      .user-info {
        margin-left: 15px;
        .u_title {
          font-size: 18px;
          line-height: 30px;
        }
      }
    }
    .content-section {
      flex: 1;
      position: relative;
      top: -50px;
      // 隐藏滚动条但保持滚动功能
      ::-webkit-scrollbar {
        display: none;
        width: 0 !important;
        height: 0 !important;
        background: transparent;
      }
      // Firefox滚动条隐藏
      * {
        scrollbar-width: none; /* Firefox */
      }
      // IE/Edge滚动条隐藏
      * {
        -ms-overflow-style: none; /* IE 10+ */
      }
      // 用户信息展示区域
      .user-info-section {
        background-color: white;
        border-radius: 8px;
        padding: 20rpx 30rpx;
        margin: 15rpx;
        box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
        .info-item {
          display: flex;
          padding: 15rpx 0;
          border-bottom: 1rpx solid #f0f0f0;
          &:last-child {
            border-bottom: none;
          }
          .info-label {
            font-size: 28rpx;
            color: #666;
            width: 180rpx;
            flex-shrink: 0;
          }
          .info-value {
            font-size: 28rpx;
            color: #333;
            flex: 1;
          }
        }
      }
      // 菜单列表样式
      .menu-list {
        background-color: white;
        border-radius: 8px;
        margin: 15rpx;
        overflow: hidden;
        .list-cell {
          padding: 30rpx;
          border-bottom: 1rpx solid #f0f0f0;
          cursor: pointer;
          transition: background-color 0.2s;
          &:last-child {
            border-bottom: none;
          }
          &:active {
            background-color: #f5f5f5;
          }
          .menu-item-box {
            display: flex;
            align-items: center;
            justify-content: space-between;
            .menu-icon {
              font-size: 36rpx;
              margin-right: 20rpx;
            }
            view {
              flex: 1;
              font-size: 32rpx;
              color: #333;
            }
            .text-red {
              color: #ff4d4f;
            }
          }
          &.list-cell-arrow .menu-item-box::after {
            content: '';
            width: 16rpx;
            height: 16rpx;
            border-top: 2rpx solid #999;
            border-right: 2rpx solid #999;
            transform: rotate(45deg);
            margin-left: 20rpx;
          }
        }
      }
    }
  }
</style>