@@ -1,5 +1,5 @@
import { useEffect , useState } from 'react' ;
import { View , Text , Image , Button , Input } from '@tarojs/components' ;
import { View , Text , Image } from '@tarojs/components' ;
import Taro , { useDidShow } from '@tarojs/taro' ;
import { isWxAuthorizeEnabled , type ClientRuntimeConfig } from '@dukang/shared-types' ;
import PageShell from '../../components/PageShell' ;
@@ -8,12 +8,10 @@ import UserTabBar, { shouldRenderPageTabBar, syncTabBarSelected } from '../../co
import { BRAND_LOGO_MARK_URL } from '@dukang/shared-types' ;
import { goLogin } from '../../lib/auth-nav' ;
import { bindWechatForUser } from '../../lib/wechat-auth' ;
import { fetchUserProfile } from '../../lib/pay-wechat' ;
import {
fetchMiniWechatUserInfo ,
mergeWxDisplayProfile ,
needsWxProfileFill ,
uploadAvatarTempFile ,
uploadMiniWechatProfile ,
} from '../../lib/mini-wechat-profile' ;
import { isLoggedIn , logout , request , toast , type UserProfile } from '../../lib/api' ;
import { isWechatEnv } from '../../lib/weixin' ;
@@ -44,30 +42,15 @@ export default function MinePage() {
const [ orderCounts , setOrderCounts ] = useState < Record < string , number > > ( { } ) ;
const [ wxAuthorize , setWxAuthorize ] = useState ( true ) ;
const [ bindingWx , setBindingWx ] = useState ( false ) ;
const [ savingProfile , setSavingProfile ] = useState ( false ) ;
const [ editingProfile , setEditingProfile ] = useState ( false ) ;
const [ draftNickname , setDraftNickname ] = useState ( '' ) ;
function resetGuestState() {
setProfile ( null ) ;
setBenefitBalance ( 0 ) ;
setOrderCounts ( { } ) ;
setDraftNickname ( '' ) ;
setEditingProfile ( false ) ;
}
function applyProfile ( me : UserProfile ) {
const merged = mergeWxDisplayProfile ( me ) ;
setProfile ( merged ) ;
if ( ! needsWxProfileFill ( merged ) ) {
setDraftNickname ( merged . nickname || '' ) ;
setEditingProfile ( false ) ;
return ;
}
// 缺头像但有真实昵称时预填
if ( merged . nickname && ! /^用户\d{4}$/ . test ( merged . nickname ) && merged . nickname !== '微信用户' ) {
setDraftNickname ( merged . nickname ) ;
}
setProfile ( mergeWxDisplayProfile ( me ) ) ;
}
function loadProfile() {
@@ -159,83 +142,13 @@ export default function MinePage() {
}
}
async function persistProfile ( patch : { nickname? : string ; avatarUrl? : string } , opts ? : { silent? : boolean } ) {
setSavingProfile ( true ) ;
try {
const bound = await ensureWechatBound ( ) ;
if ( ! bound ) return false ;
const updated = await uploadMiniWechatProfile ( patch ) ;
if ( updated ) {
applyProfile ( updated ) ;
} else {
const me = await fetchUserProfile ( ) ;
applyProfile ( me ) ;
}
if ( ! opts ? . silent ) toast ( '资料已更新' , 'success' ) ;
return true ;
} catch ( e ) {
toast ( e instanceof Error ? e . message : '保存失败' ) ;
return false ;
} finally {
setSavingProfile ( false ) ;
}
}
async function handleChooseAvatar ( e : { detail ? : { avatarUrl? : string } } ) {
const tempPath = e . detail ? . avatarUrl ? . trim ( ) ;
if ( ! tempPath ) {
toast ( '未获取到头像' ) ;
return ;
}
/** 未绑定微信时点击头像走授权(小程序 openId / H5 公众号 OAuth) */
async function handleAvatarTap() {
if ( ! isLoggedIn ( ) ) {
goLogin ( '/pages/mine/index' ) ;
return ;
}
try {
setSavingProfile ( true ) ;
const bound = await ensureWechatBound ( ) ;
if ( ! bound ) return ;
const url = await uploadAvatarTempFile ( tempPath ) ;
setProfile ( ( prev ) = >
prev
? mergeWxDisplayProfile ( { . . . prev , hasWechat : true , avatarUrl : url } )
: { id : '' , hasWechat : true , avatarUrl : url , nickname : draftNickname || null } ,
) ;
setSavingProfile ( false ) ;
const ok = await persistProfile (
{
avatarUrl : url ,
nickname : draftNickname.trim ( ) || undefined ,
} ,
{ silent : true } ,
) ;
if ( ok ) toast ( '头像已更新' , 'success' ) ;
} catch ( err ) {
toast ( err instanceof Error ? err . message : '头像更新失败' ) ;
setSavingProfile ( false ) ;
}
}
async function handleNicknameConfirm() {
const nickname = draftNickname . trim ( ) ;
if ( ! nickname ) {
toast ( '请填写微信昵称' ) ;
return ;
}
if ( ! isLoggedIn ( ) ) {
goLogin ( '/pages/mine/index' ) ;
return ;
}
await persistProfile ( { nickname } ) ;
}
/** H5:点击头像走公众号 OAuth */
async function handleH5AvatarTap() {
if ( ! isLoggedIn ( ) ) {
goLogin ( '/pages/mine/index' ) ;
return ;
}
if ( profile ? . hasWechat && ! needsWxProfileFill ( profile ) ) return ;
if ( profile ? . hasWechat ) return ;
await ensureWechatBound ( ) ;
loadProfile ( ) ;
}
@@ -291,19 +204,17 @@ export default function MinePage() {
}
const hasWechat = ! ! profile ? . hasWechat ;
const needFill = needsWxProfileFill ( profile ) || editingProfile ;
const canWxProfile = wxAuthorize && isWeapp ;
const canWxAuth = wxAuthorize && ( isWeapp || isWechatEnv ( ) ) ;
const display = mergeWxDisplayProfile (
profile || { id : '' , nickname : null , avatarUrl : null , hasWechat : false } ,
) ;
// 强制保留 common 导出,避免开发者工具「旧页 + 新 common」混用时报 is not a function
if ( typeof needsWxProfileFill !== 'function' || typeof fetchMiniWechatUserInfo !== 'function' ) {
throw new Error ( 'wx profile helpers missing' ) ;
}
const nickname = display . nickname || '用户' ;
const memberLabel = hasWechat
? needFill
? '完善头像昵称'
: '好客会员'
: canWxProfile
? '微信未授权'
: '未授权微信' ;
const memberLabel = hasWechat ? '好客会员' : canWxAuth ? '微信未授权' : '未授权微信' ;
void needsWxProfileFill ( display ) ;
return (
< PageShell variant = "tab" className = "mine-page no-tab-header" >
@@ -311,77 +222,27 @@ export default function MinePage() {
< View className = "mine-header" >
< View className = "mine-header-texture" / >
< View className = "mine-profile" >
{ canWxProfile ? (
< Button
className = "mine-avatar-btn"
openType = "chooseAvatar"
onChooseAvatar = { ( e ) = > void handleChooseAvatar ( e ) }
disabled = { bindingWx || savingProfile }
>
< View
className = { ` mine-avatar ${ hasWechat && ! needFill ? ' mine-avatar--wx-ok' : ' mine-avatar--wx-pending' } ` }
>
{ renderAvatarContent ( display . avatarUrl ) }
< / View >
{ needFill || ! hasWechat ? (
< View className = "mine-avatar-status mine-avatar-status--pending" >
< Text > { bindingWx || savingProfile ? '处理中' : hasWechat ? '选头像' : '去授权' } < / Text >
< / View >
) : null }
< / Button >
) : (
< View
className = { ` mine-avatar-wrap ${ ! hasWechat && canWxAuth ? ' mine-avatar-wrap--action' : '' } ` }
onClick = { ! hasWechat && canWxAuth ? ( ) = > void handleAvatarTap ( ) : undefined }
>
< View
className = { ` mine-avatar-wrap ${ ! hasWechat ? ' mine-avatar-wrap--action' : ' '} ` }
onClick = { ( ) = > void handleH5AvatarTap ( ) }
className = { ` mine-avatar ${ hasWechat ? ' mine-avatar--wx-ok' : ' mine-avatar--wx-pending '} ` }
>
< View
className = { ` mine-avatar ${ hasWechat ? ' mine-avatar--wx-ok' : ' mine-avatar--wx-pending' } ` }
>
{ renderAvatarContent ( display . avatarUrl ) }
< / View >
{ ! hasWechat ? (
< View className = "mine-avatar-status mine-avatar-status--pending" >
< Text > { bindingWx ? '授权中' : '去授权' } < / Text >
< / View >
) : null }
{ renderAvatarContent ( display . avatarUrl ) }
< / View >
) }
{ ! hasWechat && canWxAuth ? (
< View className = "mine-avatar-status mine-avatar-status--pending" >
< Text > { bindingWx ? '授权中' : '去授权' } < / Text >
< / View >
) : null }
< / View >
< View className = "mine-profile-meta" >
{ canWxProfile && needFill ? (
< >
< Input
className = "mine-nickname-input"
type = "nickname"
value = { draftNickname }
placeholder = "点击填写微信昵称"
maxlength = { 32 }
onInput = { ( e ) = > setDraftNickname ( e . detail . value ) }
onBlur = { ( ) = > void handleNicknameConfirm ( ) }
onConfirm = { ( ) = > void handleNicknameConfirm ( ) }
/ >
< Text className = "mine-member-tag" > { memberLabel } < / Text >
< Text className = "mine-wechat-hint" > 点 击 头 像 选 微 信 头 像 , 并 填 写 昵 称 < / Text >
< / >
) : (
< >
< Text className = "mine-profile-name" > { nickname } < / Text >
< Text className = { ` mine-member-tag ${ hasWechat && ! needFill ? ' mine-member-tag--wechat' : '' } ` } >
{ memberLabel }
< / Text >
{ canWxProfile ? (
< Text
className = "mine-wechat-hint mine-wechat-hint--link"
onClick = { ( ) = > {
setDraftNickname ( needsWxProfileFill ( profile ) ? '' : nickname ) ;
setEditingProfile ( true ) ;
} }
>
更 新 头 像 昵 称
< / Text >
) : null }
< / >
) }
< Text className = "mine-profile-name" > { nickname } < / Text >
< Text className = { ` mine-member-tag ${ hasWechat ? ' mine-member-tag--wechat' : '' } ` } >
{ memberLabel }
< / Text >
< / View >
< / View >
< / View >