Files
lucky_shop/components-diy/diy-member-info.vue
ZF sun 013eef46fb refactor(common,components): 优化底部导航栏显隐逻辑
1. 新增isCurrentPageTabBarRoot工具方法封装页面判断逻辑
2. 调整弹窗打开时的导航栏隐藏时机,仅在非TabBar根页面执行
3. 移除弹窗open回调中的导航栏显示逻辑,改为在关闭弹窗时显式处理
4. 补充注释说明回调不可靠的问题和根页面不隐藏导航的原因
2026-07-10 15:46:48 +08:00

1513 lines
39 KiB
Vue
Raw 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 data-component-name="diy-member-info" class="container" :style="warpCss">
<!-- 会员信息 -->
<view class="common-wrap info-wrap" :class="[`data-style-${value.style}`]">
<view class="member-info" :style="memberInfoStyle">
<view class="info-wrap" :style="infoStyle" v-if="memberInfo">
<view class="headimg" @tap.stop="getWxAuth">
<image :src="memberInfo.headimg ? $util.img(memberInfo.headimg) : $util.getDefaultImage().head"
mode="widthFix" @error="memberInfo.headimg = $util.getDefaultImage().head" show-menu-by-longpress/>
</view>
<view class="info">
<!-- #ifdef MP -->
<block
v-if="(memberInfo.nickname.indexOf('u_') != -1 && memberInfo.nickname == memberInfo.username) || memberInfo.nickname == memberInfo.mobile">
<view class="nickname"><text class="name" @tap.stop="getWxAuth">{{ $lang('components-diy.diy-member-info.clickToAuthorizeAvatarNickname') }}</text></view>
</block>
<view class="nickname" v-else>
<text class="name" @tap.stop="getWxAuth">{{ memberInfo.nickname }}</text>
<view class="member-level"
v-if="(value.style == 1 || value.style == 2) && memberInfo.member_level">
<!-- <text class="icondiy icon-system-huangguan"></text> -->
<text class="level-name">{{ memberInfo.member_level_name }}</text>
</view>
</view>
<view class="member-level" v-if="value.style == 3 && memberInfo.member_level">
<!-- <image :src="$util.img('public/uniapp/member/supervip_icon.png')" mode="widthFix" class="level-icon"/> -->
<view class="level-name">{{ memberInfo.member_level_name }}</view>
</view>
<view class="member-level" v-if="value.style == 4 && memberInfo.member_level">
<image :src="$util.img('app/component/view/member_info/img/style_4_vip_tag.png')"
mode="widthFix" class="level-icon" />
<text class="level-name">{{ memberInfo.member_level_name }}</text>
</view>
<!-- #endif -->
<!-- #ifdef H5 -->
<block
v-if="$util.isWeiXin() && ((memberInfo.nickname.indexOf('u_') != -1 && memberInfo.nickname == memberInfo.username) || memberInfo.nickname == memberInfo.mobile)">
<view class="nickname"><text class="name" @tap.stop="getWxAuth">{{ $lang('components-diy.diy-member-info.clickToGetWechatAvatar') }}</text></view>
</block>
<view class="nickname" v-else>
<text class="name" @tap.stop="redirect('/pages_tool/member/info')">{{ memberInfo.nickname
}}</text>
<view class="member-level"
v-if="(value.style == 1 || value.style == 2) && memberInfo.member_level">
<!-- <text class="icondiy icon-system-huangguan"></text> -->
<text class="level-name">{{ memberInfo.member_level_name }}VIP1</text>
</view>
</view>
<view class="member-level" v-if="value.style == 3 && memberInfo.member_level">
<!-- <image :src="$util.img('public/uniapp/member/supervip_icon.png')" mode="widthFix" class="level-icon"/> -->
<view class="level-name">{{ memberInfo.member_level_name }}</view>
</view>
<view class="member-level" v-if="value.style == 4 && memberInfo.member_level">
<image :src="$util.img('app/component/view/member_info/img/style_4_vip_tag.png')"
mode="widthFix" class="level-icon" />
<text class="level-name">{{ memberInfo.member_level_name }}</text>
</view>
<!-- #endif -->
</view>
<view v-if="ischina == 1"
style="background: #fff;height: 60rpx;width: 60rpx;border-radius: 50rpx;line-height:65rpx;text-align: center;color:#000"
@tap.stop="modifyInfo()">{{ langIndex == 0 ? 'CN' : 'EN' }}</view>
</view>
<view class="info-wrap" v-else :style="infoStyle" @tap.stop="redirect($util.MEMBER_PAGE_URL)">
<view class="headimg">
<image :src="$util.getDefaultImage().head" mode="widthFix" show-menu-by-longpress></image>
</view>
<view class="info">
<view class="nickname"><text class="name">{{ $lang('member.index.login') }}</text></view>
<view class="desc">{{ $lang('member.index.loginTips') }}</view>
</view>
<view v-if="ischina == 1"
style="background: #fff;height: 60rpx;width: 60rpx;border-radius: 50rpx;line-height:65rpx;text-align: center;color:#000"
@tap.stop="modifyInfo()">{{ langIndex == 0 ? 'CN' : 'EN' }}</view>
</view>
<view class="account-info" v-show="value.style == 1"
:style="{ 'margin-left': parseInt(value.infoMargin) * 2 + 'rpx', 'margin-right': parseInt(value.infoMargin) * 2 + 'rpx' }">
<view class="account-item" @tap.stop="redirect('/pages_tool/member/balance')">
<view class="value price-font">
{{ memberInfo ? (parseFloat(memberInfo.balance) +
parseFloat(memberInfo.balance_money)).toFixed(2) : '--' }}
</view>
<view class="title">{{ $lang('member.index.balance') }}</view>
</view>
<view class="solid"></view>
<view class="account-item" @tap.stop="redirect('/pages_tool/member/point_detail')">
<view class="value price-font">{{ memberInfo ? parseFloat(memberInfo.point) : '--' }}</view>
<view class="title">{{ $lang('member.index.point') }}</view>
</view>
<view class="solid"></view>
<view class="account-item" @tap.stop="redirect('/pages_tool/member/coupon')">
<view class="value price-font">
{{ memberInfo && memberInfo.coupon_num != undefined ? memberInfo.coupon_num : '--' }}
</view>
<view class="title">{{ $lang('member.index.coupon') }}</view>
</view>
</view>
<!--
<view class="super-member"
v-if="superMember && (value.style == 1 || value.style == 2 || value.style == 3)"
:style="superMemberStyle">
<block v-if="value.style == 1 || value.style == 2">
<view class="super-info">
<text class="icondiy icon-system-huangguan"></text>
<text>超级会员</text>
</view>
<view class="super-text">
<text class="see" v-if="memberInfo && memberInfo.member_level_type" @tap.stop="redirectBeforeAuth('/pages_tool/member/card')">查看特权</text>
<text class="see" v-else @tap.stop="redirectBeforeAuth('/pages_tool/member/card_buy')">会员可享更多权益</text>
<text class="iconfont icon-right"></text>
</view>
</block>
<block v-if="value.style == 3">
<view class="super-info">
<image :src="$util.img('public/uniapp/member/open_member.png')" class="title" mode="heightFix" show-menu-by-longpress/>
<view class="desc">开通可享更多权益</view>
</view>
<view class="super-text">
<text class="see" v-if="memberInfo && memberInfo.member_level_type" @tap.stop="redirectBeforeAuth('/pages_tool/member/card')">查看特权</text>
<text class="see" v-else @tap.stop="redirectBeforeAuth('/pages_tool/member/card_buy')">立即开通</text>
</view>
</block>
</view>
<view class="member-info-style4" v-show="value.style == 4">
<view class="super-member" v-if="superMember" :style="superMemberStyle">
<view class="super-info">
<image :src="$util.img('app/component/view/member_info/img/style_4_vip_huangguan.png')" class="title" mode="widthFix" show-menu-by-longpress/>
<view class="desc">开通可享更多权益</view>
</view>
<view class="super-text" :class="{ 'more' : memberInfo && memberInfo.member_level_type }">
<text class="see" v-if="memberInfo && memberInfo.member_level_type" @tap.stop="redirectBeforeAuth('/pages_tool/member/card')">查看更多权益</text>
<text class="see" v-else @tap.stop="redirectBeforeAuth('/pages_tool/member/card_buy')">立即开通</text>
</view>
</view>
<view class="account-info" :style="{ 'margin-left': parseInt(value.infoMargin) * 2 + 'rpx', 'margin-right': parseInt(value.infoMargin) * 2 + 'rpx' }">
<view class="account-item" @tap.stop="redirect('/pages_tool/member/balance_detail')">
<view class="value price-font">
{{ memberInfo ? (parseFloat(memberInfo.balance) + parseFloat(memberInfo.balance_money)).toFixed(2) : '--' }}
</view>
<view class="title">余额</view>
</view>
<view class="solid"></view>
<view class="account-item" @tap.stop="redirect('/pages_tool/member/point_detail')">
<view class="value price-font">{{ memberInfo ? parseFloat(memberInfo.point) : '--' }}
</view>
<view class="title">积分</view>
</view>
<view class="solid"></view>
<view class="account-item" @tap.stop="redirect('/pages_tool/member/coupon')">
<view class="value price-font">
{{ memberInfo && memberInfo.coupon_num != undefined ? memberInfo.coupon_num : '--' }}
</view>
<view class="title">优惠券</view>
</view>
</view>
<view class="style4-other">
<view class="style4-btn-wrap">
<view @tap.stop="redirect('/pages_tool/recharge/list')" class="recharge-btn">余额充值</view>
</view>
</view>
</view> -->
</view>
<view class="account-info" v-show="value.style == 2"
:style="{ 'margin-left': parseInt(value.infoMargin) * 2 + 'rpx', 'margin-right': parseInt(value.infoMargin) * 2 + 'rpx' }">
<view class="account-item" @tap.stop="redirect('/pages_tool/member/balance')">
<view class="value price-font">{{ memberInfo ? (parseFloat(memberInfo.balance) +
parseFloat(memberInfo.balance_money)).toFixed(2) : '--' }}</view>
<view class="title">{{ $lang('member.index.balance') }}</view>
</view>
<view class="solid"></view>
<view class="account-item" @tap.stop="redirect('/pages_tool/member/point_detail')">
<view class="value price-font">{{ memberInfo ? parseFloat(memberInfo.point) : '--' }}</view>
<view class="title">{{ $lang('member.index.point') }}</view>
</view>
<view class="solid"></view>
<view class="account-item" @tap.stop="redirect('/pages_tool/member/coupon')">
<view class="value price-font">
{{ memberInfo && memberInfo.coupon_num != undefined ? memberInfo.coupon_num : '--' }}
</view>
<view class="title">{{ $lang('member.index.coupon') }}</view>
</view>
</view>
</view>
<!-- 完善会员资料 -->
<view @touchmove.prevent.stop class="member-complete-info-popup">
<uni-popup ref="completeInfoPopup" type="bottom" :maskClick="false">
<view class="complete-info-wrap">
<view class="head">
<text class="title">{{ $lang('components-diy.diy-member-info.completeInfoTitle') }}</text>
<text class="color-tip tips">{{ $lang('components-diy.diy-member-info.completeInfoTip') }}</text>
<text class="iconfont icon-close color-tip" @tap.stop="cancelCompleteInfo"></text>
</view>
<!-- #ifdef MP-WEIXIN -->
<view class="item-wrap">
<text class="label">{{ $lang('components-diy.diy-member-info.avatarLabel') }}</text>
<button open-type="chooseAvatar" @chooseavatar="onChooseAvatar">
<image :src="avatarUrl ? avatarUrl : $util.getDefaultImage().head"
@error="avatarUrl = $util.getDefaultImage().head" mode="aspectFill" show-menu-by-longpress/>
<text class="iconfont icon-right color-tip"></text>
</button>
</view>
<view class="item-wrap">
<text class="label">{{ $lang('components-diy.diy-member-info.nicknameLabel') }}</text>
<input type="nickname" :placeholder="$lang('components-diy.diy-member-info.nicknamePlaceholder')" v-model="nickName" @blur="blurNickName" />
</view>
<!-- #endif -->
<!-- #ifdef MP-ALIPAY -->
<view class="item-wrap">
<text class="label">{{ $lang('components-diy.diy-member-info.avatarLabel') }}</text>
<button open-type="getAuthorize" scope="userInfo" @getAuthorize="aliappGetUserinfo"
:plain="true" class="border-0">
<image :src="avatarUrl ? avatarUrl : $util.getDefaultImage().head"
@error="avatarUrl = $util.getDefaultImage().head" mode="aspectFill" show-menu-by-longpress/>
<text class="iconfont icon-right color-tip"></text>
</button>
</view>
<view class="item-wrap">
<text class="label">{{ $lang('components-diy.diy-member-info.nicknameLabel') }}</text>
<input type="nickname" :placeholder="$lang('components-diy.diy-member-info.nicknamePlaceholder')" v-model="nickName" @blur="blurNickName" />
</view>
<!-- #endif -->
<button type="default" class="save-btn" @tap.stop="saveCompleteInfo" :disabled="isDisabled">{{ $lang('components-diy.diy-member-info.save') }}</button>
</view>
</uni-popup>
</view>
<ns-login ref="login"></ns-login>
</view>
</template>
<script>
let menuButtonInfo = {};
// 如果是小程序,获取右上角胶囊的尺寸信息,避免导航栏右侧内容与胶囊重叠(支付宝小程序非本API,尚未兼容)
// #ifdef MP-WEIXIN || MP-BAIDU || MP-TOUTIAO || MP-QQ
menuButtonInfo = uni.getMenuButtonBoundingClientRect();
// #endif
// 自定义会员中心——会员信息展示
import DiyMinx from './minx.js'
export default {
name: 'diy-member-info',
props: {
value: {
type: Object
},
global: {
type: Object,
default: () => {
return {};
}
}
},
mixins: [DiyMinx],
data() {
return {
info: null,
superMember: null,
memberCode: null,
avatarUrl: '', // 头像预览
headImg: '', // 头像保存
nickName: '',
completeInfoCallback: null,
menuButtonInfo: menuButtonInfo,
langList: [],
langIndex: 0,
ischina: 0
};
},
options: {
styleIsolation: 'shared'
},
created() {
this.ischina = uni.getStorageSync('shopInfo').ischina
this.initLang()
this.init(false);
},
watch: {
storeToken(nVal, oVal) {
this.init();
},
// 组件刷新监听
componentRefresh: function (nval) {
this.init();
}
},
computed: {
memberInfoStyle() {
let style = {},
img = '',
backSize = 'contain';
if (this.global.navBarSwitch == false) {
// #ifdef MP
// this.menuButtonInfo.height + this.menuButtonInfo.top ==>是胶囊按钮到顶部的距离,因为后台有可能设置margin.top,所以要减去
style['padding-top'] = this.menuButtonInfo.height + this.menuButtonInfo.top - this.value.margin
.top + 'px';
// #endif
}
if (this.value.style == 4) {
img = this.$util.img('app/component/view/member_info/img/style_4_bg.png');
backSize = 'cover';
} else if (this.value.style != 3) {
img = this.$util.img('public/static/img/diy_view/member_info_bg.png');
}
if (this.value.theme == 'default') {
style.background = `url('${img}') no-repeat bottom / ${backSize}, var(--base-color)`;
} else {
style.background =
`url('${img}') no-repeat bottom / ${backSize},linear-gradient(${this.value.gradientAngle}deg, ${this.value.bgColorStart} 0%, ${this.value.bgColorEnd} 100%)`;
}
return this.$util.objToStyle(style);
},
infoStyle() {
let style = {};
if (this.value.style == 4) {
if (this.superMember) {
style['padding-bottom'] = '276rpx';
} else {
style['padding-bottom'] = '166rpx';
}
}
return this.$util.objToStyle(style);
},
superMemberStyle() {
let style = {
'margin-left': parseInt(this.value.infoMargin) * 2 + 'rpx ',
'margin-right': parseInt(this.value.infoMargin) * 2 + 'rpx '
};
if (this.value.style == 3) {
style.background = `#292f45 url(` + this.$util.img('public/uniapp/member/supervip_bg.png') + `) no-repeat bottom / 100% 100%`;
} else if (this.value.style == 4) {
style = {};
style.background = `url(` + this.$util.img('app/component/view/member_info/img/super_vip_bg_4.png') + `) no-repeat bottom / contain`;
} else {
const superMemberStartBg = this.themeStyle?.super_member?.super_member_start_bg || '#292f45';
const superMemberEndBg = this.themeStyle?.super_member?.super_member_end_bg || '#292f45';
if (superMemberStartBg && superMemberEndBg) {
style.background = `url('` + this.$util.img('public/static/img/diy_view/super_member_bg.png') + `') no-repeat bottom / 100% 100%, linear-gradient(107deg, ${superMemberStartBg} 0%, ${superMemberEndBg} 100%)`;
}
}
return this.$util.objToStyle(style);
},
warpCss() {
var obj = '';
obj += 'background-color:' + this.value.componentBgColor + ';';
if (this.value.componentAngle == 'round') {
obj += 'border-top-left-radius:' + this.value.topAroundRadius * 2 + 'rpx;';
obj += 'border-top-right-radius:' + this.value.topAroundRadius * 2 + 'rpx;';
obj += 'border-bottom-left-radius:' + this.value.bottomAroundRadius * 2 + 'rpx;';
obj += 'border-bottom-right-radius:' + this.value.bottomAroundRadius * 2 + 'rpx;';
}
return obj;
},
isDisabled() {
if (this.nickName.length > 0) return false;
return true;
}
},
methods: {
initLang() {
//获取语言列表
this.langList = this.$langConfig.list();
if (!uni.getStorageSync("lang")) {
this.langIndex = 0;
} else {
for (let i = 0; i < this.langList.length; i++) {
if (this.langList[i].value == uni.getStorageSync("lang")) {
this.langIndex = i;
break;
}
}
}
},
modifyInfo() {
this.$langConfig.change(this.langIndex == 1 ? 'zh-cn' : 'en-us')
},
// isRefresh 是否刷新会员数据,true:刷新,false:不刷新
init(isRefresh = true) {
if (isRefresh) {
if (this.storeToken) this.getMemberInfo();
else this.$store.commit('setMemberInfo', '');
} else {
if (this.memberInfo) {
this.headImg = this.memberInfo.headimg;
this.nickName = this.memberInfo.nickname;
this.avatarUrl = this.headImg ? this.$util.img(this.headImg) : this.$util
.getDefaultImage().head;
/*
小程序用户头像昵称获取规则调整公告
https://developers.weixin.qq.com/community/develop/doc/00022c683e8a80b29bed2142b56c01
用于处理昵称将统一返回 “微信用户”
*/
if (this.nickName == '微信用户') {
this.openCompleteInfoPop();
}
this.getCouponNum();
}
}
this.getMemberCardInfo();
},
/**
* 查询会员信息
*/
getMemberInfo() {
this.$api.sendRequest({
url: '/api/member/info',
data: {},
success: res => {
if (res.code == 0) {
this.info = res.data;
this.headImg = this.info.headimg;
this.nickName = this.info.nickname;
this.avatarUrl = this.headImg ? this.$util.img(this.headImg) : this.$util
.getDefaultImage().head;
/*
小程序用户头像昵称获取规则调整公告
https://developers.weixin.qq.com/community/develop/doc/00022c683e8a80b29bed2142b56c01
用于处理昵称将统一返回 “微信用户”
*/
if (this.nickName == '微信用户') {
this.openCompleteInfoPop();
}
this.getCouponNum();
}
}
});
},
/**
* 查询优惠券数量
*/
getCouponNum() {
this.$api.sendRequest({
url: '/coupon/api/coupon/num',
success: res => {
if (res.code == 0) {
if (this.info) {
// 二次刷新数据
this.info.coupon_num = res.data;
this.$store.commit('setMemberInfo', this.info);
} else {
// 第一次赋值
this.memberInfo.coupon_num = res.data;
this.$forceUpdate();
this.$store.commit('setMemberInfo', this.memberInfo);
}
}
}
});
},
/**
* 查询超级会员信息
*/
getMemberCardInfo() {
this.$api.sendRequest({
url: '/supermember/api/membercard/firstcard',
success: res => {
if (res.code == 0 && res.data) {
this.superMember = res.data;
}
}
});
},
/**
* 跳转
* @param {Object} url
*/
redirect(url) {
if (!this.storeToken) {
this.$refs.login.open(url);
} else {
this.$util.redirectTo(url);
}
},
/**
* 显示会员码
*/
showMemberQrcode() {
if (!this.memberInfo.mobile && !this.memberInfo.member_code) {
uni.showModal({
title: this.$lang('components-diy.diy-member-info.tip'),
content: this.$lang('components-diy.diy-member-info.bindMobileTip'),
success: res => {
if (res.confirm) {
// #ifdef MP-WEIXIN
this.$util.redirectTo('/pages_tool/member/info_edit', {
action: 'bind_mobile'
});
// #endif
// #ifndef MP-WEIXIN
this.$util.redirectTo('/pages_tool/member/info_edit', {
action: 'mobile'
});
// #endif
}
}
});
return;
}
if (this.memberCode) {
this.$refs.erWeiPopup.open();
}
this.$api.sendRequest({
url: '/api/member/membereqrcode',
data: {
page: ''
},
success: res => {
if (res.code == 0) {
let time = new Date().getTime();
this.memberCode = {
barcode: res.bar_code + '?rand=' + time,
qrcode: res.data.path + '?rand=' + time,
member_code: res.member_code
};
this.$refs.erWeiPopup.open();
}
}
});
},
/**
* 关闭会员码
*/
closeMemberQrcode() {
this.$refs.erWeiPopup.close();
},
/**
* 跳转之前需先进行授权
* @param {Object} url
*/
redirectBeforeAuth(url) {
if (!this.storeToken) {
this.$refs.login.open(this.$util.MEMBER_PAGE_URL);
return;
}
// #ifdef MP
if ((this.memberInfo.nickname.indexOf('u_') != -1 && this.memberInfo.nickname == this.memberInfo.username) || this.memberInfo.nickname == this.memberInfo.mobile) {
this.getWxAuth(() => {
this.$util.redirectTo(url);
});
} else {
this.$util.redirectTo(url);
}
// #endif
// #ifdef H5
if (this.$util.isWeiXin() && ((this.memberInfo.nickname.indexOf('u_') != -1 && this.memberInfo.nickname == this.memberInfo.username) || this.memberInfo.nickname == this.memberInfo.mobile)) {
this.getWxAuth();
} else {
this.$util.redirectTo(url);
}
// #endif
// #ifndef MP || H5
this.$util.redirectTo(url);
// #endif
},
/**
* 获取微信授权
*/
getWxAuth(callback) {
// #ifdef MP
this.openCompleteInfoPop(() => {
typeof callback == 'function' && callback();
});
// #endif
// #ifdef H5
if (this.$util.isWeiXin()) {
this.$api.sendRequest({
url: '/wechat/api/wechat/authcode',
data: {
scopes: 'snsapi_userinfo',
redirect_url: this.$config.h5Domain + this.$util.MEMBER_PAGE_URL
},
success: res => {
if (res.code >= 0) {
location.href = res.data;
}
}
});
}
// #endif
},
/**
* 修改昵称
* @param {Object} nickName
*/
modifyNickname(nickName) {
this.$api.sendRequest({
url: '/api/member/modifynickname',
data: {
nickname: nickName
},
success: res => {
if (res.code == 0) {
this.memberInfo.nickname = nickName;
this.$store.commit('setMemberInfo', this.memberInfo);
}
}
});
},
/**
* 修改头像
*/
modifyHeadimg(headimg) {
this.$api.sendRequest({
url: '/api/member/modifyheadimg',
data: {
headimg: headimg
},
success: res => {
if (res.code == 0) {
this.memberInfo.headimg = headimg;
this.$store.commit('setMemberInfo', this.memberInfo);
}
}
});
},
openCompleteInfoPop(callback) {
this.$refs.completeInfoPopup.open();
// 关闭时(setBottomNavHidden=false)由 saveCompleteInfo / cancelCompleteInfo 显式处理,
// 不在 open 回调里写 — 回调在"弹窗被销毁/页面被卸载"等异常路径下不保证触发,会卡住 TabBar 隐藏态
// TabBar 根页面(如会员中心)不能藏 TabBar — 否则会被自己藏起来
if (!this.$util.isCurrentPageTabBarRoot()) {
this.$store.commit('setBottomNavHidden', true); // 隐藏底部导航
}
this.completeInfoCallback = callback;
},
saveCompleteInfo() {
if (this.nickName.length == 0) {
this.$util.showToast({
title: this.$lang('components-diy.diy-member-info.pleaseEnterNickname')
});
return;
}
this.modifyNickname(this.nickName);
this.modifyHeadimg(this.headImg);
this.$refs.completeInfoPopup.close();
this.$store.commit('setBottomNavHidden', false); // 显示底部导航
typeof this.completeInfoCallback == 'function' && this.completeInfoCallback();
},
cancelCompleteInfo() {
this.$refs.completeInfoPopup.close();
this.$store.commit('setBottomNavHidden', false); // 显示底部导航
},
blurNickName(e) {
if (e.detail.value) this.nickName = e.detail.value;
},
onChooseAvatar(e) {
this.avatarUrl = e.detail.avatarUrl;
uni.getFileSystemManager().readFile({
filePath: this.avatarUrl, //选择图片返回的相对路径
encoding: 'base64', //编码格式
success: res => {
let base64 = 'data:image/jpeg;base64,' + res.data; //不加上这串字符,在页面无法显示的哦
this.$api.uploadBase64({
base64,
success: res => {
if (res.code == 0) {
this.headImg = res.data.pic_path;
} else {
this.$util.showToast({
title: res.message
});
}
},
fail: () => {
this.$util.showToast({
title: this.$lang('components-diy.diy-member-info.uploadFailed')
});
}
})
}
});
},
splitFn(str) {
return str.replace(/(?=(\d{4})+$)/g, ' ');
},
// #ifdef MP-ALIPAY
aliappGetUserinfo() {
my.getOpenUserInfo({
success: (res) => {
let userInfo = JSON.parse(res.response).response
if (userInfo.code && userInfo.code == '10000') {
if (userInfo.avatar) {
this.avatarUrl = userInfo.avatar;
this.$api.pullImage({
path: this.avatarUrl,
success: res => {
if (res.code == 0) {
this.headImg = res.data.pic_path;
} else {
this.$util.showToast({
title: res.message
});
}
},
fail: () => {
this.$util.showToast({
title: this.$lang('components-diy.diy-member-info.avatarPullFailed')
});
}
})
}
this.nickName = userInfo.nickName
} else {
this.$util.showToast({
title: userInfo.subMsg
})
}
},
fail: (err) => {
this.$util.showToast({
title: err.subMsg
})
}
});
}
// #endif
}
};
</script>
<style lang="scss">
// 增加超出隐藏,是为样式四进行占位【样式四是有定位部分】,定位部分也可以设置颜色
.container {
overflow: hidden;
}
.common-wrap {
width: 100%;
box-sizing: border-box;
}
// 会员信息
.member-info {
.info-wrap {
padding: 44rpx 30rpx;
display: flex;
align-items: center;
view {
color: var(--btn-text-color);
}
.info {
flex: 1;
width: 0;
padding-right: 20rpx;
overflow: hidden;
}
}
.headimg {
width: 120rpx;
height: 120rpx;
overflow: hidden;
border-radius: 50%;
margin-right: 20rpx;
image {
width: 100%;
}
}
.nickname {
font-weight: bold;
white-space: nowrap;
margin-bottom: 0;
// display: flex;
align-items: center;
flex-wrap: wrap;
}
.name {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
font-size: 38rpx;
font-weight: 600;
}
.mobile {
font-size: 26rpx;
line-height: 1.5;
}
.desc {
font-size: 24rpx;
}
.member-code,
.user-info {
font-size: 40rpx;
margin-left: 20rpx;
line-height: 1;
color: var(--btn-text-color);
}
.member-level {
font-size: 24rpx;
background: none;
color: #f7c774 !important;
line-height: 40rpx;
height: 40rpx;
border-radius: 4rpx;
// padding: 0 16rpx;
// margin-left: 20rpx;
// display: flex;
align-items: center;
.icondiy {
line-height: 1;
font-size: 24rpx;
margin-right: 10rpx;
}
&.auth {
margin-left: 0;
}
.level-name {
background: #31312d;
color: rgb(242, 220, 172) !important;
padding: 6rpx 24rpx;
border-radius: 50rpx;
font-size: 24rpx;
font-weight: 500;
}
// .level-name {
// max-width: 240rpx;
// xword-break: break-all;
// text-overflow: ellipsis;
// overflow: hidden;
// display: -webkit-box;
// -webkit-line-clamp: 1;
// -webkit-box-orient: vertical;
// white-space: break-spaces;
// }
}
.super-member {
display: flex;
align-items: center;
justify-content: space-between;
height: 120rpx;
border-top-left-radius: 10rpx;
border-top-right-radius: 10rpx;
// P0: 用现有 token,主题切换时会员卡背景跟着变
// 旧字面: #7c7878 / #201a18(默认 preset 值) → 现在由 token 决定
// 兼容: 微信小程序 / 鸿蒙元服务 — var() 在 linear-gradient 中现代 runtime 均支持
background: #7c7878; // 兜底(微信小程序老 runtime 无 var() 兜底)
background: linear-gradient(107deg, var(--super-member-start-bg) 0%, var(--super-member-end-bg) 100%);
padding: 30rpx 40rpx;
box-sizing: border-box;
.icon-huangguan {
margin-right: 10rpx;
font-size: 40rpx;
}
.super-info {
flex: 1;
width: 0;
font-size: 36rpx;
color: var(--super-member-start-text-color);
// background-image: linear-gradient(90deg, var(--super-member-start-text-color) 0%, var(--super-member-end-text-color) 100%);
// -webkit-background-clip: text;
// -webkit-text-fill-color: transparent;
display: flex;
align-items: center;
.icondiy {
margin-right: 10rpx;
}
}
.see {
line-height: 1;
font-size: 30rpx;
}
.icon-right {
font-size: 28rpx;
margin-left: 10rpx;
}
}
}
.account-info {
display: flex;
padding: 40rpx 0;
align-items: center;
justify-content: center;
view {
color: #fff;
}
.solid {
height: 70rpx;
width: 2rpx;
background: #fff;
border-radius: 2rpx;
}
.account-item {
flex: 1;
text-align: center;
.value {
font-size: 34rpx;
font-weight: bold !important;
margin-bottom: 4rpx;
line-height: 1.3;
}
.title {
font-size: 26rpx;
}
}
}
.data-style-1 {
.account-info {
padding: 20rpx 0;
}
.super-member {
height: 100rpx;
}
.super-text {
// P0: 3 停渐变 → 2 停(start + end),token 化
// 旧字面: #ffdba6 / #ffebca (默认 preset 文字色) + 中间色 #f7c774
// 中间色 #f7c774 不在 token 系统中,合并为 start→end 渐变(视觉差异可接受)
// 兼容: -webkit-background-clip: text 在微信小程序 / 鸿蒙元服务均支持
background: #ffdba6; // 兜底
background-image: linear-gradient(90deg, var(--super-member-start-text-color) 0%, var(--super-member-end-text-color) 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
display: flex;
align-items: center;
}
}
.data-style-2 {
.member-info {
// border-radius: 0 0 100% 100%/0 0 70rpx 70rpx;
overflow: hidden;
.member-level {
background: none;
.level-name {
background: #31312d;
color: rgb(242, 220, 172) !important;
padding: 6rpx 24rpx;
border-radius: 50rpx;
font-size: 24rpx;
font-weight: 500;
}
}
}
.account-info {
background: #fff;
margin: 20rpx 0 0 0;
color: #333;
border-radius: 18rpx;
.solid {
background: #f2f2f2;
}
.account-item {
.value {
color: #000000;
}
.title {
color: #666666;
}
}
}
.super-member {
color: #8d4b16;
// P0 注释 A 修复: 之前这个渐变是 black preset 的字面,导致 data-style-2 在 default 主题下显示错误
// 现在用 var() 让主题切换时自动跟着变(无论 data-style-1 还是 data-style-2)
// 兼容: 同 865 行,微信小程序 / 鸿蒙元服务均 OK
background: #fadcb5; // 兜底
background: linear-gradient(107deg, var(--super-member-start-bg) 0%, var(--super-member-end-bg) 100%);
border-top-left-radius: 18rpx;
border-top-right-radius: 18rpx;
.super-info {
color: var(--super-member-start-text-color);
// background-image: linear-gradient(90deg, var(--super-member-start-text-color) 0%, var(--super-member-end-text-color) 100%);
}
.see {
color: var(--super-member-start-text-color);
}
.icon-right {
color: var(--super-member-start-text-color);
}
}
}
.data-style-3 {
.info-wrap view {
color: #282c38;
}
.member-code,
.user-info {
color: #282c38;
font-weight: bold;
}
.member-code {
font-size: 36rpx;
}
.super-member {
border-radius: 22rpx;
.super-text {
.see {
width: 160rpx;
height: 56rpx;
line-height: 56rpx;
background: #e3c377;
border-radius: 56rpx;
color: #77413e;
text-align: center;
font-weight: bold;
font-size: 24rpx;
display: block;
}
}
.super-info {
flex-direction: column;
align-items: normal;
.title {
height: 36rpx;
width: auto;
margin-bottom: 14rpx;
}
.desc {
color: #e3c377;
line-height: 1;
}
}
}
.account-info {
.solid {
background: none;
}
}
.account-item {
.value {
color: #282c38;
font-size: 44rpx;
}
.title {
color: #aab0ba;
}
}
.member-level {
background: none;
padding: 0;
margin: 0;
height: auto;
display: flex;
align-items: center;
.level-icon {
width: 40rpx;
height: auto;
will-change: transform;
}
.level-name {
height: 36rpx;
line-height: 36rpx;
padding: 2rpx 20rpx;
color: #f2dcac;
background: #31312d;
font-size: 24rpx;
margin-left: 10rpx;
border-radius: 36rpx;
// border-bottom-left-radius: 0;
// border-top-left-radius: 40rpx;
// font-weight: bold;
}
}
}
.data-style-4 {
position: relative;
.info-wrap {
padding-bottom: 276rpx;
margin-bottom: 226rpx;
view {
color: #282c38;
}
.info {
display: flex;
flex-direction: column;
align-items: baseline;
.name,
.desc {
color: #fff;
}
}
}
.member-code,
.user-info {
color: #fff;
font-weight: bold;
font-size: 36rpx;
}
.member-level {
background: #474758;
padding: 0;
margin: 10rpx 0 0;
height: auto;
border-radius: 10px;
.level-icon {
width: 40rpx;
height: auto;
vertical-align: middle;
will-change: transform;
}
.level-name {
padding: 0 20rpx 0 6rpx;
color: #ddc095;
font-size: 24rpx;
}
}
.member-info-style4 {
position: absolute;
bottom: -226rpx;
left: 24rpx;
right: 24rpx;
padding: 30rpx;
background-color: #fff;
border-radius: 16rpx;
.account-info {
padding: 50rpx 0;
.account-item {
.value {
color: #282c38;
font-size: 38rpx;
}
.title {
color: #666666;
font-size: $font-size-tag;
}
}
}
.super-member {
border-radius: 22rpx;
height: 120rpx;
line-height: 100rpx;
padding: 20rpx;
.super-info {
display: flex;
align-items: center;
.title {
width: 80rpx;
height: auto;
will-change: transform;
margin-right: 20rpx;
}
.desc {
font-size: 30rpx;
color: #333;
font-weight: bold;
}
}
.super-text {
display: flex;
align-items: center;
justify-content: center;
background-color: #333;
border-radius: 26rpx;
width: 138rpx;
height: 52rpx;
&.more {
width: 180rpx;
}
.see {
color: #f6dcad;
font-size: $font-size-goods-tag;
}
}
}
.style4-other {
display: flex;
justify-content: space-between;
padding: 0 10rpx;
.style4-btn-wrap {
flex: 1;
display: flex;
.recharge-btn,
.kefu-btn {
margin: 0;
width: 200rpx;
height: 80rpx;
line-height: 84rpx;
border-radius: 44rpx;
text-align: center;
border: 2rpx solid transparent;
}
.recharge-btn {
margin-right: 30rpx;
background-color: $base-color;
color: #fff;
}
.kefu-btn {
color: $base-color;
border-color: $base-color;
}
.contact-wrap {
flex: 1;
}
}
.code {
width: 80rpx;
height: 80rpx;
padding: 20rpx;
background-color: $base-color;
border-radius: 50%;
box-sizing: border-box;
image {
width: 40rpx;
height: 40rpx;
}
}
}
}
}
.member-code-popup {
width: 100%;
min-height: 900rpx;
background: none;
.popup-top {
padding: 40rpx;
box-sizing: border-box;
width: 100%;
height: 800rpx;
background: #ffffff;
border-radius: 12rpx;
.popup-top-title {
display: flex;
align-items: center;
margin-bottom: 60rpx;
.popup-top-title-txt {
font-size: 30rpx;
margin-left: 16rpx;
}
}
.popup-top-tiao {
width: 480rpx;
height: 130rpx;
overflow: hidden;
margin: 0 auto 20rpx;
image {
width: 480rpx;
height: 160rpx;
max-height: unset !important;
}
}
.popup-top-code {
text-align: center;
color: #000;
font-size: 28rpx;
margin: 0 auto 20rpx;
line-height: 1;
}
.popup-top-tiaoJie {
text-align: center;
font-size: 28rpx;
color: rgb(153, 153, 153);
margin-bottom: 40rpx;
}
.popup-top-erwei {
width: 254rpx;
height: 254rpx;
margin: 0 auto 20rpx;
image {
width: 100%;
height: 100%;
}
}
.popup-top-shauxin {
width: 350rpx;
height: 80rpx;
border-radius: $border-radius;
background: rgb(245, 249, 247);
margin: 0 auto;
font-size: 30rpx;
text-align: center;
display: flex;
align-items: center;
justify-content: center;
.iconfont {
margin-left: 20rpx;
}
}
.popup-top-text {
text-align: center;
font-size: 18rpx;
color: rgb(153, 153, 153);
margin-top: 30rpx;
}
}
.popup-bottom {
display: flex;
align-items: center;
justify-content: center;
background: none !important;
.iconfont-delete {
font-size: 60rpx;
margin-top: 20rpx;
color: white;
}
}
}
::v-deep .uni-popup__wrapper.uni-custom .uni-popup__wrapper-box {
background: none !important;
}
::v-deep .member-info-style4 .uni-popup__wrapper.uni-custom .uni-popup__wrapper-box {
background: #fff !important;
}
.member-code-popup .popup-top {
height: auto;
}
.member-complete-info-popup {
.complete-info-wrap {
background: #fff;
padding: 50rpx 40rpx 40rpx;
padding-bottom: calc(40rpx + constant(safe-area-inset-bottom));
padding-bottom: calc(40rpx + env(safe-area-inset-bottom));
.head {
position: relative;
border-bottom: 2rpx solid $color-line;
padding-bottom: 20rpx;
.title {
font-size: $font-size-toolbar;
display: block;
}
.tips {
font-size: $font-size-base;
display: block;
}
.iconfont {
position: absolute;
right: 0;
top: -30rpx;
display: inline-block;
width: 56rpx;
height: 56rpx;
line-height: 56rpx;
text-align: right;
font-size: $font-size-toolbar;
font-weight: bold;
}
}
.item-wrap {
border-bottom: 2rpx solid $color-line;
display: flex;
align-items: center;
padding: 20rpx 0;
.label {
font-size: $font-size-toolbar;
margin-right: 40rpx;
}
button {
background: transparent;
margin: 0;
padding: 0;
border-radius: 0;
flex: 1;
text-align: left;
display: flex;
align-items: center;
font-size: $font-size-toolbar;
border: none;
image {
width: 100rpx;
height: 100rpx;
border-radius: 10rpx;
overflow: hidden;
}
}
.iconfont {
flex: 1;
text-align: right;
}
input {
flex: 1;
height: 80rpx;
box-sizing: border-box;
font-size: $font-size-toolbar;
}
}
.save-btn {
width: 280rpx;
height: 90rpx;
line-height: 90rpx;
background-color: #07c160;
color: #fff;
margin: 40rpx auto 20rpx;
}
}
}
</style>
<style scoped>
.member-complete-info-popup ::v-deep .uni-popup__wrapper.bottom,
.member-complete-info-popup ::v-deep .uni-popup__wrapper.bottom .uni-popup__wrapper-box {
border-top-left-radius: 30rpx !important;
border-top-right-radius: 30rpx !important;
}
</style>