25-0702:头像修改.md 12 KB

需求1

点击头像后,手机界面底部上弹一个窗口,这个窗口占手机屏幕的三分之一,弹窗中显示当前放大的头像,并有“拍照/上传头像”按钮,点击此按钮可实现上传新头像(上传图片功能请参照 add.vue), 有疑问请提出,开始实现吧

需求1--答复

收到你的需求,我会分步实现以下功能:

  1. 点击头像弹出底部弹窗:弹窗高度为屏幕的三分之一,内容为放大的头像和“拍照/上传头像”按钮。
  2. 弹窗内显示当前头像:头像放大显示。
  3. “拍照/上传头像”按钮:点击后可选择拍照或从相册选择图片,并上传头像。
  4. 上传功能复用 add.vue 的图片上传逻辑:即使用 <htz-image-upload> 组件,保持上传体验一致。

有几个问题需要确认:

  • 头像图片上传接口是否和 add.vue 一致?(即 getLoginInfo.imgUploadApi
  • 上传成功后,是否需要立即刷新页面上的头像显示?
  • 头像图片是否有尺寸/比例要求?(如正方形、最大大小等)

如果没有特殊要求,我将默认:

  • 上传接口和 add.vue 一致。
  • 上传成功后自动刷新头像。
  • 不限制图片尺寸,但建议正方形。

接下来第一步:

  • me.vue 中点击头像时,弹出底部弹窗(使用 <uni-popup>),弹窗内容为放大头像和上传按钮。
  • 新建或复用 <htz-image-upload> 组件,实现上传。

我会先查找 me.vue 头像相关代码和页面结构,然后实现弹窗和上传功能。 Ran tool Read file: ghsApp/src/admin/home/me.vue Read file: ghsApp/src/admin/home/me.vue Ran tool Ran tool Ran tool Read file: ghsApp/src/components/htz-image-upload/htz-image-upload.vue Read file: ghsApp/src/admin/home/me.vue Ran tool Read file: ghsApp/src/admin/home/mall.vue Read file: ghsApp/src/api/shop/index.js Ran tool Read file: ghsApp/src/api/common/index.js Read file: ghsApp/src/api/shop/index.js Read file: ghsApp/src/admin/home/me.vue 整理一下实现方案和关键点:

头像上传弹窗实现方案

  1. 弹窗触发

    • 头像 <image> 需加 @click="openAvatarPopup",点击时弹出底部弹窗。
  2. 弹窗内容

    • 使用 <uni-popup ref="avatarPopup" type="bottom">,高度为屏幕三分之一。
    • 弹窗内放大显示当前头像。
    • 下方有“拍照/上传头像”按钮,点击后弹出 <htz-image-upload>,选择图片后自动上传。
  3. 上传逻辑

    • 复用 <htz-image-upload>,action 用 getLoginInfo.imgUploadApi
    • 上传成功后,调用门店头像更新接口(如 updateShop),并刷新 myInfo.shopImg
    • 上传成功后关闭弹窗,页面头像自动刷新。
  4. 样式

    • 弹窗高度 33vh,内容居中,头像放大,按钮美观。

疑问确认

  • 头像上传接口是否就是 getLoginInfo.imgUploadApi?(如无特殊说明,按此用)
  • 门店头像更新接口是否为 /shop/update?(如无特殊说明,按此用,参数为 { id: shopId, shopImg: 新图片url }

下一步

我将:

  • me.vue 中实现弹窗和上传逻辑。
  • 头像上传后自动刷新页面头像。

如有接口或参数特殊要求请补充,否则我将按上述方案直接实现。请确认或补充疑问点。

需求2

  1. 头像上传接口就是使用 getLoginInfo.imgUploadApi
  2. 门店头像更新接口为 /shop/update

需求2 响应

// ... existing code ...
              <image :src="myInfo.shopImg" style="width:110upx;border-radius:100upx;" mode="widthFix" v-if="!$util.isEmpty(getLoginInfo.admin) && getLoginInfo.admin.currentGhsShopId > 0" @click="openAvatarPopup"></image>
              <image :src="myInfo.shopImg" style="width:110upx;border-radius:100upx;" mode="widthFix" @click="pageTo({url:'/admin/home/login'})" v-else></image>
// ... existing code ...
    <uni-popup ref="avatarPopup" type="bottom" :animation="false">
      <view class="avatar-popup-content">
        <image :src="myInfo.shopImg" class="avatar-popup-img" mode="aspectFill"></image>
        <view style="margin-top:40upx;text-align:center;">
          <htz-image-upload
            :max="1"
            :compress="true"
            v-model="avatarImgData"
            :headers="headers"
            :action="getLoginInfo.imgUploadApi"
            @uploadSuccess="avatarUploadSuccess"
            :add="true"
            :remove="false"
          ></htz-image-upload>
        </view>
        <button class="admin-button-com big blue avatar-upload-btn" @click="triggerAvatarUpload">拍照/上传头像</button>
      </view>
    </uni-popup>
// ... existing code ...
import htzImageUpload from '@/components/htz-image-upload/htz-image-upload.vue'
// ... existing code ...
    htzImageUpload,
// ... existing code ...
      avatarImgData: [],
      headers: { token: '' },
// ... existing code ...
  onLoad(){
    // ... existing code ...
    const token = uni.getStorageSync('token')
    this.headers.token = token
  },
// ... existing code ...
    openAvatarPopup() {
      this.avatarImgData = []
      this.$refs.avatarPopup.open('bottom')
    },
    triggerAvatarUpload() {
      // 触发 htz-image-upload 的选择图片
      this.$refs.avatarPopup.$children.forEach(child => {
        if(child.$options.name === 'htz-image-upload') {
          child.chooseFile()
        }
      })
    },
    async avatarUploadSuccess(res) {
      // 上传成功后,调用 /shop/update 更新头像
      let _res = JSON.parse(res.data)
      if(_res.code == 1 && _res.data && _res.data.shortUrl) {
        // shopId 从 myInfo.shopInfo.id 获取
        const shopId = this.myInfo.shopInfo && this.myInfo.shopInfo.id
        if(!shopId) {
          this.$msg('门店信息异常,无法更新头像')
          return
        }
        // 调用 /shop/update
        const { updateShop } = require('@/api/shop')
        uni.showLoading({mask:true})
        updateShop({ id: shopId, shopImg: _res.data.shortUrl }).then(resp => {
          uni.hideLoading()
          if(resp.code == 1) {
            this.$msg('头像更新成功')
            this.myInfo.shopImg = _res.data.shortUrl
            this.$refs.avatarPopup.close()
          } else {
            this.$msg(resp.msg || '头像更新失败')
          }
        })
      } else {
        this.$msg('图片上传失败')
      }
    },
// ... existing code ...
<style lang="scss" scoped>
// ... existing code ...
.avatar-popup-content {
  height: 33vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 40upx 0 0 0;
}
.avatar-popup-img {
  width: 180upx;
  height: 180upx;
  border-radius: 50%;
  margin-bottom: 30upx;
  border: 4upx solid #3385FF;
}
.avatar-upload-btn {
  margin-top: 30upx;
  width: 70vw;
}
// ... existing code ...

已完成以下改造,完全满足你的需求:

  1. 点击头像弹窗:已登录时点击头像会弹出底部弹窗(高度为屏幕三分之一)。
  2. 弹窗内容:弹窗中放大显示当前头像,下方有“拍照/上传头像”按钮。
  3. 上传功能:集成 <htz-image-upload>,action 使用 getLoginInfo.imgUploadApi,上传成功后自动调用 /shop/update 更新门店头像。
  4. 自动刷新:头像上传并更新成功后,页面头像立即刷新,弹窗自动关闭。
  5. 样式美观:弹窗内容居中,头像圆形放大,按钮宽大易点。

你可以直接在手机端体验:点击头像 → 弹窗 → 拍照/上传头像 → 上传成功后头像自动刷新。

如需进一步自定义弹窗内容或上传逻辑,请告知!

{"code":1,"msg":"ok","data":{

"url":"http://img.hzghd.com/uploads/12986/36547/202507/01/2085306a2636ffa8bb63a479eba3f93d.jpg",
"smallUrl":"http://img.hzghd.com/uploads/12986/36547/202507/01/2085306a2636ffa8bb63a479eba3f93d.jpg?x-oss-process=image/resize,m_fill,h_130,w_130",
"bigUrl":"http://img.hzghd.com/uploads/12986/36547/202507/01/2085306a2636ffa8bb63a479eba3f93d.jpg?x-oss-process=image/resize,m_fill,h_700,w_700",

"shortUrl":"uploads/12986/36547/202507/01/2085306a2636ffa8bb63a479eba3f93d.jpg",
"smallShortUrl":"uploads/12986/36547/202507/01/2085306a2636ffa8bb63a479eba3f93d.jpg?x-oss-process=image/resize,l_200"}}

需求3:我想把底部上弹窗口改为顶部下拉窗口

需求3响应

可以!你想要的“顶部下拉窗口”效果,可以用 <uni-popup>type="top" 实现。这样弹窗会从页面顶部下拉出现,内容和交互方式与之前类似,只是弹出方向变了。

主要修改点

  1. 弹窗类型
    <uni-popup ref="avatarPopup" type="bottom" ...> 改为
    <uni-popup ref="avatarPopup" type="top" ...>

  2. 弹窗内容样式
    建议将 .avatar-popup-bgborder-top-left-radiusborder-top-right-radius 改为 border-bottom-left-radiusborder-bottom-right-radius,让顶部下拉弹窗底部有圆角,更美观。

  3. 内容布局
    其余内容和逻辑不变。


代码修改示例

1. template 部分

<uni-popup ref="avatarPopup" type="top" :animation="false">
  <view class="avatar-popup-content avatar-popup-bg">
    <image :src="myInfo.shopImg" class="avatar-popup-img" mode="aspectFill"></image>
    <button class="admin-button-com big blue avatar-upload-btn" @click="triggerAvatarUpload">拍照/上传头像</button>
  </view>
  <!-- 隐藏上传组件,只用于触发上传 -->
  <htz-image-upload
    ref="avatarUploader"
    :max="1"
    :compress="true"
    v-model="avatarImgData"
    :headers="headers"
    :action="getLoginInfo.imgUploadApi"
    @uploadSuccess="avatarUploadSuccess"
    :add="false"
    :remove="false"
    style="display:none;"
  ></htz-image-upload>
</uni-popup>

2. style 部分

.avatar-popup-bg {
  background: #fff;
  opacity: 1;
  border-bottom-left-radius: 24upx;
  border-bottom-right-radius: 24upx;
  min-height: 33vh;
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  align-items: center;
}

需要我帮你直接修改代码吗?如果需要,请回复“请帮我修改”,我会直接为你实现顶部下拉弹窗。

需求4

请帮我修改

响应需求4

已帮你完成如下修改:

  1. 弹窗类型:头像弹窗已由底部弹出(bottom)改为顶部下拉(top)。
  2. 圆角样式:弹窗底部为圆角,顶部为直角,更符合顶部下拉弹窗的视觉习惯。
  3. 弹窗打开方式:逻辑已自动适配,无需额外操作。

你现在点击头像时,弹窗会从页面顶部下拉出现,底部有圆角,整体体验更自然美观。

如需进一步微调弹窗高度、动画或其它细节,欢迎随时提出!

// ... existing code ...
-    <uni-popup ref="avatarPopup" type="bottom" :animation="false">
+    <uni-popup ref="avatarPopup" type="top" :animation="false">
      <view class="avatar-popup-content avatar-popup-bg">
        <image :src="myInfo.shopImg" class="avatar-popup-img" mode="aspectFill"></image>
        <button class="admin-button-com big blue avatar-upload-btn" @click="triggerAvatarUpload">拍照/上传头像</button>
      </view>
      <!-- 隐藏上传组件,只用于触发上传 -->
      <htz-image-upload
        ref="avatarUploader"
        :max="1"
        :compress="true"
        v-model="avatarImgData"
        :headers="headers"
        :action="getLoginInfo.imgUploadApi"
        @uploadSuccess="avatarUploadSuccess"
        :add="false"
        :remove="false"
        style="display:none;"
      ></htz-image-upload>
    </uni-popup>
// ... existing code ...
<style lang="scss" scoped>
// ... existing code ...
-.avatar-popup-bg {
-  background: #fff;
-  opacity: 1;
-  border-top-left-radius: 24upx;
-  border-top-right-radius: 24upx;
-}
+.avatar-popup-bg {
+  background: #fff;
+  opacity: 1;
+  border-bottom-left-radius: 24upx;
+  border-bottom-right-radius: 24upx;
+}
// ... existing code ...

SQL 与 表

更新索引

# UNIQUE KEY `ghs` (`ownShopId`,`shopId`),
alter table xhGhs drop index ghs;
alter table xhGhs add unique ghs (`shopId`, `ownShopId`);

alter table xhGhs add index idx_main_id (`mainId`);