台球开关台小程序
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

244 lines
6.9 KiB

/**
* 编辑个人信息页
*/
import { View, Text, Image, Input, Button as WxButton } from '@tarojs/components'
import Taro, { useLoad } from '@tarojs/taro'
import { useState } from 'react'
import { observer } from 'mobx-react'
import { Image as TaroifyImage, Button, ActionSheet } from '@taroify/core'
import { updateCustomer, readImageAsBase64 } from '../../api/customer'
import { userStore } from '../../store'
import myAvatar from '../../assets/icon/my_avatar.png'
import './index.scss'
const EditProfile = observer(() => {
const info = userStore.userInfo
const [nickname, setNickname] = useState(info?.name || info?.nickname || '')
const [phone, setPhone] = useState(info?.phone || '')
const [wchart, setWchart] = useState(info?.wchart || '')
const [avatarUrl, setAvatarUrl] = useState(info?.avatar || myAvatar)
// 是否选了新的本地头像(需要上传)
const [newAvatarPath, setNewAvatarPath] = useState<string>('')
const [loading, setLoading] = useState(false)
const [avatarActionOpen, setAvatarActionOpen] = useState(false)
useLoad(() => {
console.log('编辑个人信息页面加载')
})
// 点击头像区域
const handleAvatarClick = () => {
setAvatarActionOpen(true)
}
// 微信头像回调
const handleChooseAvatar = (e: any) => {
const url = e.detail.avatarUrl
setAvatarUrl(url)
setNewAvatarPath(url)
setAvatarActionOpen(false)
}
// 从相册选择
const handleChooseFromAlbum = () => {
setAvatarActionOpen(false)
Taro.chooseImage({
count: 1,
sizeType: ['compressed'],
sourceType: ['album'],
success: (res) => {
const path = res.tempFilePaths[0]
setAvatarUrl(path)
setNewAvatarPath(path)
},
})
}
// 拍照
const handleTakePhoto = () => {
setAvatarActionOpen(false)
Taro.chooseImage({
count: 1,
sizeType: ['compressed'],
sourceType: ['camera'],
success: (res) => {
const path = res.tempFilePaths[0]
setAvatarUrl(path)
setNewAvatarPath(path)
},
})
}
// 保存
const handleSave = async () => {
if (loading) return
const userId = info?.id
if (!userId) {
Taro.showToast({ title: '用户信息异常,请重新登录', icon: 'none', duration: 2000 })
return
}
if (!nickname.trim()) {
Taro.showToast({ title: '昵称不能为空', icon: 'none', duration: 2000 })
return
}
setLoading(true)
try {
// 如果选了新头像,先转成 Base64
let avatarImage: string | undefined
if (newAvatarPath) {
try {
avatarImage = await readImageAsBase64(newAvatarPath)
} catch (e) {
console.warn('头像转 Base64 失败,跳过头像更新:', e)
}
}
await updateCustomer(userId, {
id: userId,
name: nickname.trim(),
phone: phone.trim() || undefined,
wchart: wchart.trim() || undefined,
avatarImage,
})
// 同步更新本地 store
userStore.setUserInfo({
...userStore.userInfo!,
name: nickname.trim(),
nickname: nickname.trim(),
phone: phone.trim() || userStore.userInfo?.phone,
wchart: wchart.trim() || userStore.userInfo?.wchart,
avatar: newAvatarPath || userStore.userInfo?.avatar,
})
Taro.showToast({ title: '保存成功', icon: 'success', duration: 2000 })
setTimeout(() => Taro.navigateBack(), 1500)
} catch (error: any) {
console.error('保存失败:', error)
// 错误提示由 request 拦截器统一处理
} finally {
setLoading(false)
}
}
return (
<View className="edit-profile-page">
<View className="content-area">
{/* 头像区域 */}
<View className="avatar-section" onClick={handleAvatarClick}>
<View className="avatar-wrapper">
<TaroifyImage
className="avatar"
src={avatarUrl || myAvatar}
round
mode="aspectFill"
/>
<View className="camera-icon">
<Image
className="camera-img"
src={require('../../assets/icon/phototake.png')}
mode="widthFix"
/>
</View>
</View>
</View>
{/* 表单区域 */}
<View className="form-section">
{/* 昵称 */}
<View className="form-item">
<Text className="form-label"></Text>
<Input
className="form-input"
value={nickname}
onInput={(e) => setNickname(e.detail.value)}
placeholder="请输入昵称"
placeholderClass="form-placeholder"
maxlength={20}
/>
</View>
{/* 手机号 */}
<View className="form-item">
<Text className="form-label"></Text>
<Input
className="form-input"
value={phone}
onInput={(e) => setPhone(e.detail.value)}
placeholder="请输入手机号"
placeholderClass="form-placeholder"
type="number"
maxlength={11}
/>
</View>
{/* 微信号 */}
<View className="form-item">
<Text className="form-label"></Text>
<Input
className="form-input"
value={wchart}
onInput={(e) => setWchart(e.detail.value)}
placeholder="请输入微信号"
placeholderClass="form-placeholder"
maxlength={30}
/>
</View>
</View>
{/* 保存按钮 */}
<Button
className={`save-button ${loading ? 'disabled' : ''}`}
loading={loading}
onClick={handleSave}
>
{loading ? '保存中...' : '保存'}
</Button>
</View>
{/* 头像选择菜单 */}
<ActionSheet
open={avatarActionOpen}
onSelect={() => {}}
onClose={() => setAvatarActionOpen(false)}
>
<WxButton
className="avatar-action-item wechat-avatar-btn"
openType="chooseAvatar"
onChooseAvatar={handleChooseAvatar}
>
<Text className="avatar-emoji">🤵</Text>
<Text></Text>
</WxButton>
<ActionSheet.Action
className="avatar-action-item"
onClick={handleChooseFromAlbum}
>
</ActionSheet.Action>
<ActionSheet.Action
className="avatar-action-item"
onClick={handleTakePhoto}
>
</ActionSheet.Action>
<ActionSheet.Action
className="avatar-action-item cancel-action"
onClick={() => setAvatarActionOpen(false)}
>
</ActionSheet.Action>
</ActionSheet>
</View>
)
})
export default EditProfile