1182 lines
25 KiB
Vue
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="page">
<!-- 页面内容 -->
<view class="page-content">
<!-- 个人资料部分 -->
<view class="section">
<view class="section-title">个人资料</view>
<view class="info-list">
<view class="info-item">
<text>头像</text>
<view class="right-content">
<button class="avatar-btn" open-type="chooseAvatar" @chooseavatar="onChooseAvatar">
<image v-if="form.barLogo" :src="form.barLogo" class="avatar"></image>
<view v-else class="avatar-placeholder">
<text class="cuIcon-camerafill"></text>
</view>
</button>
</view>
</view>
<view class="info-item">
<text>用户名</text>
<view class="right-content">
<input class="input-field" type="text" v-model="form.nickName" placeholder="请输入用户名" />
</view>
</view>
<view class="info-item" @click="showChangePhone">
<text>关联手机</text>
<view class="right-content">
<text class="info-text">{{maskedPhone}}</text>
<text class="cuIcon-right"></text>
</view>
</view>
</view>
</view>
<!-- 选项卡 -->
<view class="tab-box">
<view class="tab-item" :class="{'active': currentTab === 1}" @click="changeTab(1)">
门店信息
</view>
<view class="tab-item" :class="{'active': currentTab === 2}" @click="changeTab(2)">
认证信息
</view>
</view>
<!-- 门店资料部分 -->
<view v-if="currentTab === 1" class="section">
<view class="info-list">
<view class="info-item" @click="showStoreEditTip">
<text>所在地区</text>
<view class="right-content">
<text class="info-text">{{form.city || '--'}}</text>
<text class="cuIcon-right"></text>
</view>
</view>
<view class="info-item" @click="toAddress">
<text>门店地址</text>
<view class="right-content">
<text class="info-text">{{form.address}}</text>
<text class="cuIcon-right"></text>
</view>
</view>
<view class="info-item" @click="showStoreEditTip">
<text>门店名称</text>
<view class="right-content">
<text class="info-text">{{form.barName}}</text>
<text class="cuIcon-right"></text>
</view>
</view>
<view class="info-item">
<text>门店ID</text>
<view class="right-content">
<text class="info-text">{{ barInfo.barNumber || '--' }}</text>
<text class="cuIcon-copy text-gray" @click="copyId"></text>
</view>
</view>
</view>
</view>
<!-- 认证信息部分 -->
<view v-if="currentTab === 2" class="section">
<view class="info-list">
<view class="info-item">
<text>认证到期时间</text>
<view class="right-content">
<text class="text-gray">{{barInfo.authEndTime || '--'}}</text>
</view>
</view>
<view class="info-item">
<text>营业执照</text>
<view class="right-content" @click="previewImage('businessLicense')">
<text class="text-blue">点击查看</text>
</view>
</view>
<view class="info-item">
<text>门头照片</text>
<view class="right-content" @click="previewImage('storefrontPhoto')">
<text class="text-blue">点击查看</text>
</view>
</view>
</view>
</view>
<!-- 保存按钮 -->
<view class="save-btn" @click="handleSub">
保存
</view>
</view>
<!-- 更换手机号弹窗 -->
<view class="change-phone-modal" v-if="showPhoneModal" @click.stop>
<view class="modal-content">
<view class="modal-title">确认更换手机号</view>
<view class="modal-desc">更换后现手机号{{maskedPhone}}将不能用于登录180天内只可更换一次</view>
<view class="modal-buttons">
<view class="btn cancel-btn" @click="closePhoneModal">我再想想</view>
<view class="btn confirm-btn" @click="confirmChangePhone">确认更换</view>
</view>
</view>
</view>
<!-- 更换手机号输入弹窗 -->
<view class="phone-input-modal" v-if="showPhoneInputModal" @click.stop>
<view class="modal-content">
<view class="modal-title">更换手机号</view>
<view class="input-section">
<view class="input-box">
<text class="prefix">+86</text>
<input
type="number"
v-model="newPhone"
maxlength="11"
placeholder="请输入新的手机号"
class="phone-input"
/>
</view>
<view class="verify-box" v-if="showVerifyCode">
<input
type="number"
v-model="verifyCode"
maxlength="6"
placeholder="请输入验证码"
class="verify-input"
/>
<view
class="verify-btn"
:class="{'disabled': counting}"
@click="getVerifyCode"
>
{{counting ? `${countdown}s后重新获取` : '获取验证码'}}
</view>
</view>
</view>
<view class="modal-buttons">
<view class="btn cancel-btn" @click="closePhoneInputModal">取消</view>
<view class="btn confirm-btn" @click="saveNewPhone">确定</view>
</view>
</view>
</view>
<!-- 图片预览弹窗 -->
<view class="preview-modal" v-if="showPreview" @click.stop>
<view class="preview-content">
<image :src="previewUrl" mode="aspectFit" class="preview-image"></image>
<view class="close-btn" @click="closePreview">关闭</view>
</view>
</view>
<!-- 门店信息修改提示弹窗 -->
<view class="store-edit-modal" v-if="showStoreEditModal" @click.stop>
<view class="modal-content">
<view class="modal-title">温馨提示</view>
<view class="modal-desc">门店信息修改需联系客服</view>
<view class="modal-buttons">
<view class="btn cancel-btn" @click="closeStoreEditModal">关闭</view>
<view class="btn confirm-btn" @click="toContactService">联系客服</view>
</view>
</view>
</view>
</view>
</template>
<style lang="scss" scoped>
.page {
min-height: 100vh;
background: #F7F7F7;
.page-content {
padding: 24rpx 32rpx;
}
.section {
background: #FFFFFF;
border-radius: 16rpx;
margin-bottom: 24rpx;
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.04);
.section-title {
font-size: 32rpx;
font-weight: 600;
padding: 32rpx;
color: #333333;
position: relative;
&::after {
content: '';
position: absolute;
left: 32rpx;
bottom: 0;
width: 48rpx;
height: 4rpx;
background: #19367A;
border-radius: 2rpx;
}
}
}
.info-list {
.info-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 32rpx;
border-bottom: 1rpx solid rgba(0, 0, 0, 0.05);
transition: all 0.3s ease;
&:active {
background: rgba(25, 54, 122, 0.05);
}
&:last-child {
border-bottom: none;
}
text {
font-size: 28rpx;
color: #333333;
}
.right-content {
display: flex;
align-items: center;
gap: 16rpx;
.input-field {
text-align: right;
font-size: 28rpx;
color: #666666;
}
.avatar {
width: 88rpx;
height: 88rpx;
border-radius: 50%;
border: 2rpx solid #19367A;
box-shadow: 0 2rpx 8rpx rgba(25, 54, 122, 0.1);
}
.avatar-placeholder {
width: 88rpx;
height: 88rpx;
border-radius: 50%;
background: #F5F5F5;
display: flex;
align-items: center;
justify-content: center;
color: #19367A;
font-size: 32rpx;
}
.text-gray {
color: #999999;
font-size: 28rpx;
text-align: left;
margin-top: 8rpx;
}
.text-blue {
color: #19367A;
font-size: 28rpx;
font-weight: 600;
}
.info-text {
font-size: 28rpx;
color: #666666;
text-align: right;
}
.cuIcon-right {
color: #CCCCCC;
font-size: 24rpx;
margin-left: 8rpx;
}
.cuIcon-copy {
padding: 8rpx;
font-size: 32rpx;
}
}
}
}
.tab-box {
display: flex;
background: #FFFFFF;
margin-bottom: 24rpx;
padding: 8rpx 20rpx;
border-radius: 16rpx;
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.04);
.tab-item {
flex: 1;
text-align: center;
font-size: 28rpx;
color: #666666;
padding: 24rpx 0;
position: relative;
transition: all 0.3s ease;
&.active {
color: #19367A;
font-weight: 600;
&::after {
content: '';
position: absolute;
bottom: 0;
left: 50%;
transform: translateX(-50%);
width: 48rpx;
height: 4rpx;
background: #19367A;
border-radius: 2rpx;
transition: all 0.3s ease;
}
}
}
}
.save-btn {
width: 686rpx;
height: 88rpx;
background: linear-gradient(135deg, #19367A, #2C4C99);
border-radius: 44rpx;
color: #FFFFFF;
font-size: 32rpx;
font-weight: 600;
letter-spacing: 2rpx;
display: flex;
align-items: center;
justify-content: center;
margin: 48rpx auto;
box-shadow: 0 4rpx 16rpx rgba(25, 54, 122, 0.2);
transition: all 0.3s ease;
&:active {
transform: scale(0.98);
box-shadow: 0 2rpx 8rpx rgba(25, 54, 122, 0.1);
}
}
.avatar-btn {
padding: 0;
width: 88rpx !important;
height: 88rpx !important;
background: none;
border: none;
line-height: 1;
transition: all 0.3s ease;
&:active {
transform: scale(0.95);
}
&::after {
border: none;
}
.avatar {
width: 88rpx;
height: 88rpx;
border-radius: 50%;
border: 2rpx solid #19367A;
box-shadow: 0 2rpx 8rpx rgba(25, 54, 122, 0.1);
}
.avatar-placeholder {
width: 88rpx;
height: 88rpx;
border-radius: 50%;
background: #F5F5F5;
display: flex;
align-items: center;
justify-content: center;
color: #19367A;
font-size: 32rpx;
}
}
.preview-modal {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.6);
display: flex;
align-items: center;
justify-content: center;
z-index: 999;
.preview-content {
width: 600rpx;
background: #FFFFFF;
border-radius: 20rpx;
padding: 32rpx;
position: relative;
.preview-image {
width: 100%;
height: 600rpx;
border-radius: 12rpx;
}
.close-btn {
width: 160rpx;
height: 72rpx;
background: #19367A;
color: #FFFFFF;
font-size: 28rpx;
border-radius: 36rpx;
display: flex;
align-items: center;
justify-content: center;
margin: 32rpx auto 0;
transition: all 0.3s ease;
&:active {
transform: scale(0.95);
background: #142c62;
}
}
}
}
.change-phone-modal {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.6);
display: flex;
align-items: center;
justify-content: center;
z-index: 999;
.modal-content {
width: 600rpx;
background: #FFFFFF;
border-radius: 20rpx;
padding: 48rpx 32rpx;
.modal-title {
font-size: 36rpx;
color: #333333;
font-weight: 600;
text-align: center;
margin-bottom: 24rpx;
}
.modal-desc {
font-size: 28rpx;
color: #666666;
text-align: center;
padding: 0 32rpx;
margin-bottom: 48rpx;
line-height: 1.6;
}
.modal-buttons {
display: flex;
justify-content: space-between;
gap: 24rpx;
padding: 0 32rpx;
.btn {
flex: 1;
height: 88rpx;
border-radius: 44rpx;
display: flex;
align-items: center;
justify-content: center;
font-size: 32rpx;
font-weight: 600;
transition: all 0.3s ease;
&:active {
transform: scale(0.98);
}
}
.cancel-btn {
background: #F5F5F5;
color: #666666;
&:active {
background: #EBEBEB;
}
}
.confirm-btn {
background: #19367A;
color: #FFFFFF;
&:active {
background: #142c62;
}
}
}
}
}
.phone-input-modal {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.6);
display: flex;
align-items: center;
justify-content: center;
z-index: 999;
.modal-content {
width: 600rpx;
background: #FFFFFF;
border-radius: 20rpx;
padding: 48rpx 32rpx;
.modal-title {
font-size: 36rpx;
color: #333333;
font-weight: 600;
text-align: center;
margin-bottom: 48rpx;
}
.input-section {
margin-bottom: 48rpx;
.input-box {
display: flex;
align-items: center;
background: #F5F5F5;
border-radius: 12rpx;
padding: 24rpx;
margin-bottom: 24rpx;
.prefix {
font-size: 28rpx;
color: #333333;
margin-right: 24rpx;
font-weight: 600;
}
.phone-input {
flex: 1;
font-size: 28rpx;
color: #333333;
}
}
.verify-box {
display: flex;
align-items: center;
gap: 24rpx;
.verify-input {
flex: 1;
background: #F5F5F5;
border-radius: 12rpx;
padding: 24rpx;
font-size: 28rpx;
color: #333333;
}
.verify-btn {
width: 200rpx;
height: 80rpx;
background: #19367A;
color: #FFFFFF;
font-size: 24rpx;
border-radius: 12rpx;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.3s ease;
&:active {
transform: scale(0.98);
background: #142c62;
}
&.disabled {
background: #CCCCCC;
pointer-events: none;
}
}
}
}
.modal-buttons {
display: flex;
justify-content: space-between;
gap: 24rpx;
.btn {
flex: 1;
height: 88rpx;
border-radius: 44rpx;
display: flex;
align-items: center;
justify-content: center;
font-size: 32rpx;
font-weight: 600;
transition: all 0.3s ease;
&:active {
transform: scale(0.98);
}
}
.cancel-btn {
background: #F5F5F5;
color: #666666;
&:active {
background: #EBEBEB;
}
}
.confirm-btn {
background: #19367A;
color: #FFFFFF;
&:active {
background: #142c62;
}
}
}
}
}
.store-edit-modal {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.6);
z-index: 999;
display: flex;
align-items: center;
justify-content: center;
.modal-content {
width: 600rpx;
background: #FFFFFF;
border-radius: 24rpx;
padding: 48rpx 32rpx;
.modal-title {
font-size: 36rpx;
font-weight: 600;
color: #333333;
text-align: center;
margin-bottom: 24rpx;
}
.modal-desc {
font-size: 28rpx;
color: #666666;
text-align: center;
margin-bottom: 48rpx;
}
.modal-buttons {
display: flex;
justify-content: space-between;
gap: 24rpx;
.btn {
flex: 1;
height: 88rpx;
display: flex;
align-items: center;
justify-content: center;
font-size: 32rpx;
border-radius: 44rpx;
&.cancel-btn {
background: #F5F5F5;
color: #666666;
}
&.confirm-btn {
background: #19367A;
color: #FFFFFF;
}
}
}
}
}
}
</style>
<script>
// import QQMapSdk from '@/common/qqmap-wx-jssdk.js'
import {
barRegister
} from '@/api/login.js'
import {
base_url
} from '@/api/config.js'
import {
getBarInfo,
editBarInfo,
reAuth
} from '@/api/bar.js'
import { getToken } from '@/utils/auth.js'
import { updatePhone } from '@/api/user.js' // 请确保添加相关API
export default {
data() {
return {
form: {
barLogo: '',
nickName: '',
barContactPhone: '',
barName: '',
address: '',
businessLicense: '', // 营业执照
storefrontPhoto: '', // 门头照
position: '', // 职务
openId: '',
city: ''
},
userInfo: {},
currentTab: 1,
QQMap: null,
barInfo: {},
showPreview: false,
previewUrl: '',
showPhoneModal: false,
showPhoneInputModal: false,
newPhone: '',
verifyCode: '',
showVerifyCode: false,
counting: false,
countdown: 60,
showStoreEditModal: false,
};
},
computed: {
maskedPhone() {
if (!this.form.barContactPhone) return '';
return this.form.barContactPhone.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2');
}
},
onLoad() {
// this.QQMap = new QQMapSdk({
// key: "YQCBZ-SQZ6A-P6EKD-CAUGZ-L7IWO-JMFMJ"//密钥
// });
this.getBarInfoFun()
},
onShow() {
// 获取最新的门店信息
const barInfo = uni.getStorageSync('barInfo');
if (barInfo) {
this.barInfo = barInfo;
}
},
methods: {
goBack() {
uni.navigateBack();
},
copyId() {
uni.setClipboardData({
data: this.barInfo.barNumber || '',
success: () => {
uni.showToast({
title: '复制成功',
icon: 'none'
});
}
});
},
changeTab(key) {
this.currentTab = key
},
// 获取酒吧信息
getBarInfoFun() {
getBarInfo().then(res => {
this.barInfo = res.data
this.form = JSON.parse(JSON.stringify(res.data))
})
},
handleSub() {
if(this.currentTab == 1) {
this.submitForm()
}else if(this.currentTab == 2) {
this.reAuthFun()
}
},
// 重新认证
reAuthFun() {
if (!this.form.businessLicense) {
uni.showToast({
title: '请上传营业执照',
icon: 'none',
mask: true
})
return
}
if (!this.form.storefrontPhoto) {
uni.showToast({
title: '请上传门头照',
icon: 'none',
mask: true
})
return
}
let data = {
businessLicense: this.form.businessLicense,
storefrontPhoto: this.form.storefrontPhoto,
}
reAuth(data).then(res => {
if (res.code == 200) {
uni.showToast({
title: '提交成功,等待审核',
icon: 'none',
mask: true
})
uni.hideLoading()
setTimeout(() => {
uni.switchTab({
url: '/pages/index/my'
})
}, 500)
}
})
},
// 提交
submitForm() {
if (!this.form.barLogo) {
uni.showToast({
title: '请上传头像',
icon: 'none',
mask: true
})
return
}
if (!this.form.nickName) {
uni.showToast({
title: '请输入用户名',
icon: 'none',
mask: true
})
return
}
if (!this.form.barContactPhone) {
uni.showToast({
title: '请输入手机号',
icon: 'none',
mask: true
})
return
}
if (!this.form.barName) {
uni.showToast({
title: '请输入门店名称',
icon: 'none',
mask: true
})
return
}
if (!this.form.address) {
uni.showToast({
title: '请输入门店地址',
icon: 'none',
mask: true
})
return
}
if(!this.form.latitude || !this.form.longitude) {
uni.showToast({
title: '请通过定位获取位置',
icon: 'none',
mask: true,
})
return
}
uni.showLoading({
title: '提交中',
mask: true
})
editBarInfo(this.form).then(res => {
if (res.code == 200) {
// this.userInfo = res.data // 暂存用户信息
uni.showToast({
title: '保存成功',
icon: 'none',
mask: true
})
uni.hideLoading()
setTimeout(() => {
uni.switchTab({
url: '/pages/index/my'
})
}, 500)
}
}).catch(() => {
// uni.hideLoading()
})
},
toHome() {
uni.setStorageSync('userInfo', this.userInfo)
uni.reLaunch({
url: '/pages/index/index'
})
},
// 选择头像
async onChooseAvatar(e) {
try {
console.log('开始选择头像:', e);
// 获取头像临时路径
const avatarUrl = e.detail.avatarUrl;
console.log('获取到的头像临时路径:', avatarUrl);
if (!avatarUrl) {
throw new Error('未获取到头像');
}
uni.showLoading({
title: '上传中...'
});
const token = getToken();
console.log('当前token:', token);
// 上传头像
uni.uploadFile({
url: base_url + '/api/bar/common/upload',
filePath: avatarUrl,
name: 'file',
header: {
'Authorization': token,
'Content-Type': 'multipart/form-data'
},
formData: {
type: 'image'
},
success: (uploadFileRes) => {
console.log('上传响应原始数据:', uploadFileRes);
try {
// 检查状态码
if (uploadFileRes.statusCode !== 200) {
throw new Error(`服务器响应错误: ${uploadFileRes.statusCode}`);
}
let result;
try {
result = JSON.parse(uploadFileRes.data);
} catch (parseError) {
console.error('解析响应数据失败,原始数据:', uploadFileRes.data);
throw new Error('服务器响应格式错误');
}
console.log('解析后的响应数据:', result);
if (result.code === 200) {
const imageUrl = result.data || result.url;
if (!imageUrl) {
throw new Error('未获取到图片地址');
}
// 更新表单数据
this.form.barLogo = imageUrl;
// 更新本地存储的门店信息
const barInfo = uni.getStorageSync('barInfo') || {};
barInfo.barLogo = imageUrl;
uni.setStorageSync('barInfo', barInfo);
uni.showToast({
title: '更新成功',
icon: 'success'
});
} else {
throw new Error(result.msg || '上传失败');
}
} catch (error) {
console.error('处理响应数据时出错:', error);
throw error;
}
},
fail: (err) => {
console.error('上传请求失败:', err);
throw new Error(err.errMsg || '上传失败');
},
complete: () => {
uni.hideLoading();
}
});
} catch (error) {
console.error('选择头像完整错误信息:', error);
uni.showToast({
title: error.message || '选择头像失败',
icon: 'none'
});
uni.hideLoading();
}
},
// 跳转到地址页面
toAddress() {
uni.navigateTo({
url: '/pagesMy/myAddress'
})
},
// 预览图片
previewImage(type) {
const imageUrl = type === 'businessLicense' ? this.barInfo.businessLicense : this.barInfo.storefrontPhoto;
if (!imageUrl) {
uni.showToast({
title: '暂无图片',
icon: 'none'
});
return;
}
this.previewUrl = imageUrl;
this.showPreview = true;
},
// 关闭预览
closePreview() {
this.showPreview = false;
this.previewUrl = '';
},
// 显示更换手机号弹窗
showChangePhone() {
this.showPhoneModal = true;
},
// 关闭更换手机号弹窗
closePhoneModal() {
this.showPhoneModal = false;
},
// 确认更换手机号
confirmChangePhone() {
this.closePhoneModal();
this.showPhoneInputModal = true;
this.newPhone = '';
this.verifyCode = '';
this.showVerifyCode = false;
},
// 关闭手机号输入弹窗
closePhoneInputModal() {
this.showPhoneInputModal = false;
this.newPhone = '';
this.verifyCode = '';
this.showVerifyCode = false;
this.counting = false;
},
// 获取验证码
getVerifyCode() {
if (this.counting) return;
if (!this.newPhone) {
uni.showToast({
title: '请输入手机号',
icon: 'none'
});
return;
}
if (!/^1[3-9]\d{9}$/.test(this.newPhone)) {
uni.showToast({
title: '请输入正确的手机号',
icon: 'none'
});
return;
}
// TODO: 调用发送验证码接口
this.showVerifyCode = true;
this.counting = true;
this.countdown = 60;
const timer = setInterval(() => {
if (this.countdown > 0) {
this.countdown--;
} else {
this.counting = false;
clearInterval(timer);
}
}, 1000);
},
// 保存新手机号
saveNewPhone() {
if (!this.newPhone) {
uni.showToast({
title: '请输入手机号',
icon: 'none'
});
return;
}
if (!/^1[3-9]\d{9}$/.test(this.newPhone)) {
uni.showToast({
title: '请输入正确的手机号',
icon: 'none'
});
return;
}
uni.showLoading({
title: '保存中...'
});
editBarInfo({ barContactPhone: this.newPhone }).then(res => {
if (res.code === 200) {
uni.showToast({
title: '更换成功',
icon: 'success'
});
this.closePhoneInputModal();
this.getBarInfoFun(); // 刷新页面信息
} else {
uni.showToast({
title: res.msg || '更换失败',
icon: 'none'
});
}
}).catch(err => {
uni.showToast({
title: err.msg || '更换失败',
icon: 'none'
});
}).finally(() => {
uni.hideLoading();
});
},
// 显示门店信息修改提示弹窗
showStoreEditTip() {
this.showStoreEditModal = true;
},
// 关闭门店信息修改提示弹窗
closeStoreEditModal() {
this.showStoreEditModal = false;
},
// 联系客服
toContactService() {
uni.navigateTo({
url: '/pagesMy/addAiad'
});
this.closeStoreEditModal();
},
}
}
</script>