import {useEffect, useState, useRef} from "react"; import {Loading, CellGroup, Input, Form, Avatar, Button, Space} from '@nutui/nutui-react-taro' import {Edit} from '@nutui/icons-react-taro' import Taro from '@tarojs/taro' import {View} from '@tarojs/components' import FixedButton from "@/components/FixedButton"; import {useUser} from "@/hooks/useUser"; import {TenantId} from "@/config/app"; import {updateUser} from "@/api/system/user"; import {User} from "@/api/system/user/model"; import {getStoredInviteParams, handleInviteRelation} from "@/utils/invite"; import {addShopDealerUser} from "@/api/shop/shopDealerUser"; import {addUserRole, listUserRole, updateUserRole} from "@/api/system/userRole"; import { listRoles } from "@/api/system/role"; import type { UserRole } from "@/api/system/userRole/model"; // 类型定义 interface ChooseAvatarEvent { detail: { avatarUrl: string; }; } interface InputEvent { detail: { value: string; }; } const AddUserAddress = () => { const {user, loginUser, fetchUserInfo} = useUser() const [loading, setLoading] = useState(true) const [FormData, setFormData] = useState() const formRef = useRef(null) const reload = async () => { const inviteParams = getStoredInviteParams() if (inviteParams?.inviter) { setFormData({ ...user, refereeId: Number(inviteParams.inviter), // 清空昵称,强制用户手动输入 nickname: '', }) } else { // 如果没有邀请参数,也要确保昵称为空 setFormData({ ...user, nickname: '', }) } } const uploadAvatar = ({detail}: ChooseAvatarEvent) => { // 先更新本地显示的头像(临时显示) const tempFormData = { ...FormData, avatar: `${detail.avatarUrl}`, } setFormData(tempFormData) Taro.uploadFile({ url: 'https://server.websoft.top/api/oss/upload', filePath: detail.avatarUrl, name: 'file', header: { 'content-type': 'application/json', TenantId }, success: async (res) => { const data = JSON.parse(res.data); if (data.code === 0) { const finalAvatarUrl = `${data.data.thumbnail}` try { // 使用 useUser hook 的 updateUser 方法更新头像 await updateUser({ avatar: finalAvatarUrl }) Taro.showToast({ title: '头像上传成功', icon: 'success', duration: 1500 }) } catch (error) { console.error('更新用户头像失败:', error) } // 无论用户信息更新是否成功,都要更新本地FormData const finalFormData = { ...tempFormData, avatar: finalAvatarUrl } setFormData(finalFormData) // 同步更新表单字段 if (formRef.current) { formRef.current.setFieldsValue({ avatar: finalAvatarUrl }) } } else { // 上传失败,恢复原来的头像 setFormData({ ...FormData, avatar: user?.avatar || '' }) Taro.showToast({ title: '上传失败', icon: 'error' }) } }, fail: (error) => { console.error('上传头像失败:', error) Taro.showToast({ title: '上传失败', icon: 'error' }) // 恢复原来的头像 setFormData({ ...FormData, avatar: user?.avatar || '' }) } }) } // 提交表单 const submitSucceed = async (values: User) => { try { // 验证必填字段 if (!values.phone && !FormData?.phone) { Taro.showToast({ title: '请先获取手机号', icon: 'error' }); return; } // 验证昵称:必须填写且不能是默认的微信昵称 const nickname = values.realName || FormData?.nickname || ''; if (!nickname || nickname.trim() === '') { Taro.showToast({ title: '请填写昵称', icon: 'error' }); return; } // 检查是否为默认的微信昵称(常见的默认昵称) const defaultNicknames = ['微信用户', 'WeChat User', '微信昵称']; if (defaultNicknames.includes(nickname.trim())) { Taro.showToast({ title: '请填写真实昵称,不能使用默认昵称', icon: 'error' }); return; } // 验证昵称长度 if (nickname.trim().length < 2) { Taro.showToast({ title: '昵称至少需要2个字符', icon: 'error' }); return; } if (!values.avatar && !FormData?.avatar) { Taro.showToast({ title: '请上传头像', icon: 'error' }); return; } console.log(values,FormData) if (!user?.userId) { Taro.showToast({ title: '用户信息缺失,请先登录', icon: 'error' }); return; } let roles: UserRole[] = []; try { roles = await listUserRole({userId: user.userId}) console.log(roles, 'roles...') } catch (e) { // 新用户/权限限制时可能查不到角色列表,不影响基础注册流程 console.warn('查询用户角色失败,将尝试直接写入默认角色:', e) roles = [] } // 准备提交的数据 await updateUser({ userId: user.userId, nickname: values.realName || FormData?.nickname, phone: values.phone || FormData?.phone, avatar: values.avatar || FormData?.avatar, refereeId: values.refereeId || FormData?.refereeId }); await addShopDealerUser({ userId: user.userId, realName: values.realName || FormData?.nickname, mobile: values.phone || FormData?.phone, refereeId: Number(values.refereeId) || Number(FormData?.refereeId) }) // 角色为空时这里会导致“注册成功但没有角色”,这里做一次兜底写入默认 user 角色 try { // 1) 先尝试通过 roleCode=user 查询角色ID(避免硬编码) // 2) 取不到就回退到旧的默认ID(1848) let userRoleId: number | undefined; try { // 注意:当前 request.get 的封装不支持 axios 风格的 { params: ... }, // 某些自动生成的 API 可能无法按参数过滤;这里直接取全量再本地查找更稳。 const roleList = await listRoles(); userRoleId = roleList?.find(r => r.roleCode === 'user')?.roleId; } catch (_) { // ignore } if (!userRoleId) userRoleId = 1848; const baseRolePayload = { userId: user.userId, tenantId: Number(TenantId), roleId: userRoleId }; // 后端若已创建 user-role 记录则更新;否则尝试“无id更新”触发创建(多数实现会 upsert) if (roles.length > 0) { await updateUserRole({ ...roles[0], roleId: userRoleId }); } else { try { await addUserRole(baseRolePayload); } catch (_) { // 兼容后端仅支持 PUT upsert 的情况 await updateUserRole(baseRolePayload); } } // 刷新一次用户信息,确保 roles 写回本地缓存,避免“我的”页显示为空/不一致 await fetchUserInfo(); } catch (e) { console.warn('写入默认角色失败(不影响注册成功):', e) } Taro.showToast({ title: `注册成功`, icon: 'success' }); setTimeout(() => { // “我的”是 tabBar 页面,注册完成后直接切到“我的” Taro.switchTab({ url: '/pages/user/user' }); }, 1000); } catch (error) { console.error('验证邀请人失败:', error); } } // 获取微信昵称 const getWxNickname = (nickname: string) => { // 更新表单数据 const updatedFormData = { ...FormData, nickname: nickname } setFormData(updatedFormData); // 同步更新表单字段 if (formRef.current) { formRef.current.setFieldsValue({ realName: nickname }) } } /* 获取用户手机号 */ const handleGetPhoneNumber = ({detail}: { detail: { code?: string, encryptedData?: string, iv?: string } }) => { const {code, encryptedData, iv} = detail Taro.login({ success: (loginRes) => { if (code) { Taro.request({ url: 'https://server.websoft.top/api/wx-login/loginByMpWxPhone', method: 'POST', data: { authCode: loginRes.code, code, encryptedData, iv, notVerifyPhone: true, refereeId: 0, sceneType: 'save_referee', tenantId: TenantId }, header: { 'content-type': 'application/json', TenantId }, success: async function (res) { if (res.data.code == 1) { Taro.showToast({ title: res.data.message, icon: 'error', duration: 2000 }) return false; } // 登录成功 const token = res.data.data.access_token; const userData = res.data.data.user; console.log(userData, 'userData...') // 使用useUser Hook的loginUser方法更新状态 loginUser(token, userData); if (userData.phone) { console.log('手机号已获取', userData.phone) const updatedFormData = { ...FormData, phone: userData.phone, // 不自动填充微信昵称,保持用户已输入的昵称 nickname: FormData?.nickname || '', // 只在没有头像时才使用微信头像 avatar: FormData?.avatar || userData.avatar } setFormData(updatedFormData) // 更新表单字段值 if (formRef.current) { formRef.current.setFieldsValue({ phone: userData.phone, // 不覆盖用户已输入的昵称 realName: FormData?.nickname || '', avatar: FormData?.avatar || userData.avatar }) } Taro.showToast({ title: '手机号获取成功', icon: 'success', duration: 1500 }) } // 处理邀请关系 if (userData?.userId) { try { const inviteSuccess = await handleInviteRelation(userData.userId) if (inviteSuccess) { Taro.showToast({ title: '邀请关系建立成功', icon: 'success', duration: 2000 }) } } catch (error) { console.error('处理邀请关系失败:', error) } } // 显示登录成功提示 // Taro.showToast({ // title: '注册成功', // icon: 'success', // duration: 1500 // }) // 不需要重新启动小程序,状态已经通过useUser更新 // 可以选择性地刷新当前页面数据 // await reload(); } }) } else { console.log('登录失败!') } } }) } // 处理固定按钮点击事件 const handleFixedButtonClick = () => { // 触发表单提交 formRef.current?.submit(); }; const submitFailed = (error: any) => { console.log(error, 'err...') } useEffect(() => { reload().then(() => { setLoading(false) }) }, [user?.userId]); // 依赖用户ID,当用户变化时重新加载 // 当FormData变化时,同步更新表单字段值 useEffect(() => { if (formRef.current && FormData) { formRef.current.setFieldsValue({ refereeId: FormData.refereeId, phone: FormData.phone, avatar: FormData.avatar, realName: FormData.nickname }); } }, [FormData]); if (loading) { return 加载中 } return ( <>
submitSucceed(values)} onFinishFailed={(errors) => submitFailed(errors)} > {/**/} {/* */} {/**/} { FormData?.phone && } getWxNickname(e.detail.value)} />
{/* 底部浮动按钮 */} } text={'立即注册'} onClick={handleFixedButtonClick} /> ); }; export default AddUserAddress;