点击头像后,手机界面底部上弹一个窗口,这个窗口占手机屏幕的三分之一,弹窗中显示当前放大的头像,并有“拍照/上传头像”按钮,点击此按钮可实现上传新头像(上传图片功能请参照 add.vue), 有疑问请提出,开始实现吧
收到你的需求,我会分步实现以下功能:
<htz-image-upload> 组件,保持上传体验一致。getLoginInfo.imgUploadApi)如果没有特殊要求,我将默认:
接下来第一步:
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
整理一下实现方案和关键点:
弹窗触发
<image> 需加 @click="openAvatarPopup",点击时弹出底部弹窗。弹窗内容
<uni-popup ref="avatarPopup" type="bottom">,高度为屏幕三分之一。<htz-image-upload>,选择图片后自动上传。上传逻辑
<htz-image-upload>,action 用 getLoginInfo.imgUploadApi。updateShop),并刷新 myInfo.shopImg。样式
33vh,内容居中,头像放大,按钮美观。getLoginInfo.imgUploadApi?(如无特殊说明,按此用)/shop/update?(如无特殊说明,按此用,参数为 { id: shopId, shopImg: 新图片url })我将:
me.vue 中实现弹窗和上传逻辑。如有接口或参数特殊要求请补充,否则我将按上述方案直接实现。请确认或补充疑问点。
// ... 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 ...
已完成以下改造,完全满足你的需求:
<htz-image-upload>,action 使用 getLoginInfo.imgUploadApi,上传成功后自动调用 /shop/update 更新门店头像。你可以直接在手机端体验:点击头像 → 弹窗 → 拍照/上传头像 → 上传成功后头像自动刷新。
如需进一步自定义弹窗内容或上传逻辑,请告知!
{"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"}}
可以!你想要的“顶部下拉窗口”效果,可以用 <uni-popup> 的 type="top" 实现。这样弹窗会从页面顶部下拉出现,内容和交互方式与之前类似,只是弹出方向变了。
弹窗类型
把 <uni-popup ref="avatarPopup" type="bottom" ...> 改为
<uni-popup ref="avatarPopup" type="top" ...>
弹窗内容样式
建议将 .avatar-popup-bg 的 border-top-left-radius 和 border-top-right-radius 改为 border-bottom-left-radius 和 border-bottom-right-radius,让顶部下拉弹窗底部有圆角,更美观。
内容布局
其余内容和逻辑不变。
<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>
.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;
}
需要我帮你直接修改代码吗?如果需要,请回复“请帮我修改”,我会直接为你实现顶部下拉弹窗。
请帮我修改
已帮你完成如下修改:
你现在点击头像时,弹窗会从页面顶部下拉出现,底部有圆角,整体体验更自然美观。
如需进一步微调弹窗高度、动画或其它细节,欢迎随时提出!
// ... 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 ...
更新索引
# 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`);