|                                                                                                                                                                                                                                                                                                      |  | <template>  <view class="profile-container">    <!-- 个人信息表单 -->    <view class="form-container">      <view class="form-title">个人信息</view>            <!-- 昵称 -->      <view class="form-item">        <view class="label">          <text class="required">*</text>          <text>昵称</text>        </view>        <uv-input           v-model="userInfo.name"           placeholder="请输入昵称"          type="nickname"          :customStyle="inputStyle"          border="bottom"        ></uv-input>      </view>            <!-- 电话 -->      <view class="form-item">        <view class="label">          <text class="required">*</text>          <text>电话</text>        </view>        <uv-input           v-model="userInfo.phone"           placeholder="请输入手机号"          :customStyle="inputStyle"          border="bottom"          type="number"        ></uv-input>      </view>            <!-- 头像 -->      <view class="form-item">        <view class="label">          <text class="required">*</text>          <text>头像</text>        </view>        <!-- #ifdef MP-WEIXIN -->        <button class="avatar-container" open-type="chooseAvatar" @chooseavatar="onChooseAvatar">          <view             v-if="userInfo.avatar === 'undefined'"            class="avatar-image"          >              <uv-icon name="camera" size="40" color="white"></uv-icon>          </view>          <image             v-else            :src="userInfo.avatar || '/static/default-avatar.png'"             class="avatar-image"            mode="aspectFill"          ></image>
        </button>        <!-- #endif -->
        <!-- #ifndef MP-WEIXIN -->        <button class="avatar-container" @click="chooseImageH5">          <view             v-if="userInfo.avatar === 'undefined'"            class="avatar-image"          >              <uv-icon name="camera" size="40" color="white"></uv-icon>          </view>          <image             v-else            :src="userInfo.avatar || '/static/default-avatar.png'"             class="avatar-image"            mode="aspectFill"          ></image>
        </button>        <!-- #endif -->      </view>    </view>        <!-- 固定底部保存按钮 -->    <view class="save-button-container">      <uv-button         @click="saveProfile"        :customStyle="saveButtonStyle"        shape="circle"      >        保存      </uv-button>    </view>  </view></template>
<script>export default {  data() {    return {      userInfo: {        avatar: 'undefined',        name: '',         phone: ''      },      saveButtonStyle: {        backgroundColor: '#06DADC',        borderRadius: '41rpx',        height: '94rpx',        width: '594rpx',        border: 'none',        color: '#fff',        fontSize: '32rpx',        fontWeight: '500'      },      inputStyle: {        backgroundColor: '#fff',        borderRadius: '12rpx',        padding: '0 -20rpx',        fontSize: '28rpx'      }    }  },  methods: {
            // 选择头像并上传到OSS
    async onChooseAvatar(e) {      console.log('选择头像回调', e);      if (e.detail.avatarUrl) {        try {          // 显示上传中提示
          uni.showLoading({ title: '上传头像中...' });                    // 构造文件对象
          const file = {            path: e.detail.avatarUrl,            tempFilePath: e.detail.avatarUrl          };                    // 上传到OSS
          const uploadResult = await this.$utils.uploadImage(file);                    uni.hideLoading();                    if (uploadResult.success) {            // 上传成功,更新头像URL
            this.userInfo.avatar = uploadResult.url;            console.log('头像上传成功', uploadResult.url);            uni.showToast({              title: '头像上传成功',              icon: 'success'            });          } else {
          }        } catch (error) {          uni.hideLoading();          console.error('头像上传异常:', error);          // 异常情况下使用本地头像
          // this.userInfo.avatar = e.detail.avatarUrl;
          uni.showToast({            title: '头像处理异常,使用本地头像',            icon: 'none'          });        }      } else {        uni.showToast({          title: '头像选择失败',          icon: 'none'        });      }    },
    // 公众号/H5 选择图片并上传头像
    // #ifndef MP-WEIXIN
    async chooseImageH5() {      try {        const res = await uni.chooseImage({          count: 1,          sizeType: ['compressed'],          sourceType: ['album', 'camera']        })
        const filePath = (res.tempFilePaths && res.tempFilePaths[0])          || (res.tempFiles && res.tempFiles[0] && (res.tempFiles[0].path || res.tempFiles[0].tempFilePath))
        if (!filePath) {          uni.showToast({ title: '未选择图片', icon: 'none' })          return        }
        uni.showLoading({ title: '上传头像中...' })
        const file = { path: filePath, tempFilePath: filePath }        const uploadResult = await this.$utils.uploadImage(file)
        uni.hideLoading()
        if (uploadResult && uploadResult.success) {          this.userInfo.avatar = uploadResult.url          uni.showToast({ title: '头像上传成功', icon: 'success' })        } else {          // 上传失败则先本地显示
          this.userInfo.avatar = filePath          uni.showToast({ title: '头像已选择', icon: 'none' })        }      } catch (error) {        uni.hideLoading()        console.error('选择/上传头像异常:', error)        uni.showToast({ title: '头像处理异常', icon: 'none' })      }    },    // #endif
        // 保存资料
    async saveProfile() {      if (!this.userInfo.name?.trim()) {        uni.showToast({          title: '请输入昵称',          icon: 'none'        })        return      }            if (!this.userInfo.phone?.trim()) {        uni.showToast({          title: '请输入手机号',          icon: 'none'        })        return      }            // 简单的手机号验证
      const phoneReg = /^1[3-9]\d{9}$/      if (!phoneReg.test(this.userInfo.phone)) {        uni.showToast({          title: '请输入正确的手机号',          icon: 'none'        })        return      }            // TODO: 调用API保存用户信息
      const res = await this.$api.login.updateUserInfo({        avatar: this.userInfo.avatar,        name: this.userInfo.name,        phone: this.userInfo.phone      })      if (res.code === 200) {        uni.showToast({          title: '保存成功',          icon: 'success'        })                // 延迟返回上一页
        setTimeout(() => {          uni.navigateBack()        }, 1500)      }     },
    // 获取个人信息
    async getProfile() {      const res = await this.$api.login.getUserInfo()      if (res.code === 200) {        this.userInfo = res.result        this.$store.dispatch('updateUserInfo', this.userInfo)      }    }  },  onLoad() {    this.getProfile()    // 3秒后隐藏遮罩层
  }}</script>
<style lang="scss" scoped>.profile-container {  min-height: 100vh;  background-color: #f5f5f5;  padding: 40rpx 32rpx 200rpx;    .form-container {    background: #fff;    border-radius: 20rpx;    padding: 40rpx 32rpx;        .form-title {      font-size: 36rpx;      font-weight: 600;      color: #333;      margin-bottom: 60rpx;    }        .form-item {      margin-bottom: 60rpx;            &:last-child {        margin-bottom: 0;      }            .label {        display: flex;        align-items: center;        margin-bottom: 20rpx;        font-size: 28rpx;        color: #333;                .required {          color: #ff4757;          margin-right: 8rpx;        }      }    }        .avatar-container {      position: relative;      width: 200rpx;      height: 200rpx;      border-radius: 16rpx;      overflow: hidden;      display: block;      text-align: left;      margin: 0;      padding: 0;      background: none;      border: none;            .avatar-image {        width: 100%;        height: 100%;        background: #00000080;        display: flex;        align-items: center;        justify-content: center;      }            .avatar-mask {        position: absolute;        top: 0;        left: 0;        right: 0;        bottom: 0;        background: rgba(0, 0, 0, 0.6);        display: flex;        align-items: center;        justify-content: center;        color: #fff;        font-size: 24rpx;        transition: opacity 1s ease-out;                &.fade-out {          opacity: 0;        }      }    }  }    .save-button-container {    position: fixed;    bottom: 60rpx;    left: 50%;    transform: translateX(-50%);    z-index: 999;  }}</style>
 |