942 lines
30 KiB
TypeScript
942 lines
30 KiB
TypeScript
import React, { useState, useEffect } from "react";
|
||
import { View, Text, Image, Button } from "@tarojs/components";
|
||
import { PopupPicker } from "@/components/Picker/index";
|
||
import Taro from "@tarojs/taro";
|
||
import "./index.scss";
|
||
import { UserService, PickerOption } from "@/services/userService";
|
||
import { clear_login_state } from "@/services/loginService";
|
||
import { convert_db_gender_to_display } from "@/utils/genderUtils";
|
||
import { EditModal, GeneralNavbar } from "@/components";
|
||
// import img from "@/config/images";
|
||
import CommonDialog from "@/components/CommonDialog";
|
||
import {
|
||
useUserActions,
|
||
useUserInfo,
|
||
useNicknameChangeStatus,
|
||
} from "@/store/userStore";
|
||
import { UserInfoType } from "@/services/userService";
|
||
import {
|
||
useCities,
|
||
useProfessions,
|
||
useNtrpLevels,
|
||
} from "@/store/pickerOptionsStore";
|
||
import { handleCustomerService } from "@/services/userService";
|
||
import evaluateService from "@/services/evaluateService";
|
||
|
||
const EditProfilePage: React.FC = () => {
|
||
const { updateUserInfo, updateNickname } = useUserActions();
|
||
// 直接从store获取用户信息,确保响应式更新
|
||
const user_info = useUserInfo();
|
||
const nickname_change_status = useNicknameChangeStatus();
|
||
const ntrpLevels = useNtrpLevels();
|
||
|
||
// 表单状态,基于store中的用户信息初始化
|
||
const getInitialFormData = () => {
|
||
const info = user_info as UserInfoType;
|
||
return {
|
||
nickname: info?.nickname ?? "",
|
||
personal_profile: info?.personal_profile ?? "",
|
||
occupation: info?.occupation ?? "",
|
||
ntrp_level: info?.ntrp_level ?? "",
|
||
phone: info?.phone ?? "",
|
||
gender: info?.gender ?? "",
|
||
birthday: info?.birthday ?? "",
|
||
country: info?.country ?? "",
|
||
province: info?.province ?? "",
|
||
city: info?.city ?? "",
|
||
district: info?.district ?? "",
|
||
};
|
||
};
|
||
const [form_data, setFormData] = useState(getInitialFormData());
|
||
|
||
// 加载状态
|
||
const [loading, setLoading] = useState(false);
|
||
const [showLogoutDialog, setShowLogoutDialog] = useState(false);
|
||
|
||
// 编辑弹窗状态
|
||
const [edit_modal_visible, setEditModalVisible] = useState(false);
|
||
const [editing_field, setEditingField] = useState<string>("");
|
||
const [gender_picker_visible, setGenderPickerVisible] = useState(false);
|
||
const [birthday_picker_visible, setBirthdayPickerVisible] = useState(false);
|
||
const [location_picker_visible, setLocationPickerVisible] = useState(false);
|
||
const [ntrp_picker_visible, setNtrpPickerVisible] = useState(false);
|
||
const [occupation_picker_visible, setOccupationPickerVisible] =
|
||
useState(false);
|
||
|
||
// 职业数据
|
||
const professions = useProfessions();
|
||
|
||
// 城市数据
|
||
const cities = useCities();
|
||
|
||
const [ntrpTested, setNtrpTested] = useState<boolean>(false);
|
||
|
||
// 监听store中的用户信息变化,同步到表单状态
|
||
useEffect(() => {
|
||
if (user_info && Object.keys(user_info).length > 0) {
|
||
const info = user_info as UserInfoType;
|
||
setFormData({
|
||
nickname: info?.nickname ?? "",
|
||
personal_profile: info?.personal_profile ?? "",
|
||
occupation: info?.occupation ?? "",
|
||
ntrp_level: info?.ntrp_level ?? "",
|
||
phone: info?.phone ?? "",
|
||
gender: info?.gender ?? "",
|
||
birthday: info?.birthday ?? "",
|
||
country: info?.country ?? "",
|
||
province: info?.province ?? "",
|
||
city: info?.city ?? "",
|
||
district: info?.district ?? "",
|
||
});
|
||
}
|
||
|
||
const getLastResult = async () => {
|
||
// 获取测试结果
|
||
const res = await evaluateService.getLastResult();
|
||
if (res.code === 0) {
|
||
setNtrpTested(res.data.has_test_in_last_month);
|
||
}
|
||
};
|
||
getLastResult();
|
||
}, [user_info]);
|
||
|
||
// 页面加载时初始化数据
|
||
// useEffect(() => {
|
||
// getCities();
|
||
// getProfessions();
|
||
// }, []);
|
||
|
||
// const getProfessions = async () => {
|
||
// try {
|
||
// const res = await UserService.getProfessions();
|
||
// setProfessions(res);
|
||
// } catch (e) {
|
||
// console.log("获取职业失败:", e);
|
||
// }
|
||
// };
|
||
// const getCities = async () => {
|
||
// try {
|
||
// const res = await UserService.getCities();
|
||
// setCities(res);
|
||
// } catch (e) {
|
||
// console.log("获取城市列表失败:", e);
|
||
// }
|
||
// };
|
||
|
||
// 加载用户信息
|
||
// const load_user_info = async () => {
|
||
// try {
|
||
// setLoading(true);
|
||
// const user_data = await UserService.get_user_info();
|
||
// setUserInfo(user_data);
|
||
// setFormData({
|
||
// nickname: user_data.nickname || "",
|
||
// personal_profile: user_data.personal_profile || "",
|
||
// occupation: user_data.occupation || "",
|
||
// ntrp_level: user_data.ntrp_level || "NTRP 4.0",
|
||
// phone: user_data.phone || "",
|
||
// gender: user_data.gender || "",
|
||
// birthday: user_data.birthday || "",
|
||
// country: user_data.country || "",
|
||
// province: user_data.province || "",
|
||
// city: user_data.city || "",
|
||
// });
|
||
// } catch (error) {
|
||
// console.warn("加载用户信息失败:", error);
|
||
// Taro.showToast({
|
||
// title: "加载用户信息失败",
|
||
// icon: "error",
|
||
// duration: 2000,
|
||
// });
|
||
// } finally {
|
||
// setLoading(false);
|
||
// }
|
||
// };
|
||
|
||
// 处理头像上传
|
||
const handle_avatar_upload = () => {
|
||
Taro.chooseImage({
|
||
count: 1,
|
||
sizeType: ["compressed"],
|
||
sourceType: ["album", "camera"],
|
||
success: async (res) => {
|
||
const tempFilePath = res.tempFilePaths[0];
|
||
try {
|
||
const avatar_url = await UserService.upload_avatar(tempFilePath);
|
||
await updateUserInfo({ avatar_url: avatar_url });
|
||
Taro.showToast({
|
||
title: "头像上传成功",
|
||
icon: "success",
|
||
});
|
||
} catch (error) {
|
||
console.warn("头像上传失败:", error);
|
||
Taro.showToast({
|
||
title: error.message,
|
||
icon: "none",
|
||
});
|
||
}
|
||
},
|
||
});
|
||
};
|
||
|
||
// 处理编辑弹窗
|
||
const handle_open_edit_modal = (field: string) => {
|
||
if (field === "gender") {
|
||
setGenderPickerVisible(true);
|
||
return;
|
||
}
|
||
if (field === "birthday") {
|
||
setBirthdayPickerVisible(true);
|
||
return;
|
||
}
|
||
if (field === "location") {
|
||
setLocationPickerVisible(true);
|
||
return;
|
||
}
|
||
if (field === "ntrp_level") {
|
||
setNtrpPickerVisible(true);
|
||
return;
|
||
}
|
||
if (field === "occupation") {
|
||
setOccupationPickerVisible(true);
|
||
return;
|
||
}
|
||
if (field === "nickname") {
|
||
if (!nickname_change_status.can_change) {
|
||
return Taro.showToast({
|
||
title: `30天内仅可修改4次昵称,${nickname_change_status.next_period_start_date}后可修改`,
|
||
icon: "none",
|
||
duration: 2000,
|
||
});
|
||
}
|
||
// 手动输入
|
||
setEditingField(field);
|
||
setEditModalVisible(true);
|
||
} else {
|
||
setEditingField(field);
|
||
setEditModalVisible(true);
|
||
}
|
||
};
|
||
|
||
const handle_edit_modal_save = async (value: string) => {
|
||
try {
|
||
// 验证值不能是 undefined 或 null
|
||
if (value === undefined || value === null) {
|
||
Taro.showToast({
|
||
title: "数据不完整,请重新输入",
|
||
icon: "none",
|
||
});
|
||
return;
|
||
}
|
||
// 调用更新用户信息接口,只传递修改的字段
|
||
const update_data = { [editing_field]: value };
|
||
editing_field === "nickname"
|
||
? await updateNickname(value)
|
||
: await updateUserInfo(update_data);
|
||
// 更新表单状态(store会自动更新)
|
||
setFormData((prev) => ({ ...prev, [editing_field]: value }));
|
||
|
||
// 关闭弹窗
|
||
setEditModalVisible(false);
|
||
setEditingField("");
|
||
|
||
// 显示成功提示
|
||
Taro.showToast({
|
||
title: "保存成功",
|
||
icon: "success",
|
||
});
|
||
} catch (error) {
|
||
console.warn("保存失败:", error);
|
||
Taro.showToast({
|
||
title: "保存失败",
|
||
icon: "error",
|
||
});
|
||
}
|
||
};
|
||
|
||
const handle_edit_modal_cancel = () => {
|
||
setEditModalVisible(false);
|
||
setEditingField("");
|
||
};
|
||
|
||
// 处理字段编辑
|
||
const handle_field_edit = async (
|
||
field: string | { [key: string]: string },
|
||
value?: string
|
||
) => {
|
||
try {
|
||
if (
|
||
typeof field === "object" &&
|
||
field !== null &&
|
||
!Array.isArray(field)
|
||
) {
|
||
// 验证对象中的值不能是 undefined
|
||
const hasUndefined = Object.values(field).some(
|
||
(v) => v === undefined || v === null
|
||
);
|
||
if (hasUndefined) {
|
||
Taro.showToast({
|
||
title: "数据不完整,请重新选择",
|
||
icon: "none",
|
||
});
|
||
return;
|
||
}
|
||
await updateUserInfo({ ...field });
|
||
|
||
// 更新表单状态(store会自动更新)
|
||
setFormData((prev) => ({ ...prev, ...field }));
|
||
} else {
|
||
// 验证值不能是 undefined
|
||
if (value === undefined || value === null) {
|
||
Taro.showToast({
|
||
title: "数据不完整,请重新选择",
|
||
icon: "none",
|
||
});
|
||
return;
|
||
}
|
||
// 调用更新用户信息接口,只传递修改的字段
|
||
const update_data = { [field as string]: value };
|
||
await updateUserInfo(update_data);
|
||
|
||
// 更新表单状态(store会自动更新)
|
||
setFormData((prev) => ({ ...prev, [field as string]: value }));
|
||
}
|
||
// 显示成功提示
|
||
Taro.showToast({
|
||
title: "保存成功",
|
||
icon: "success",
|
||
});
|
||
} catch (error) {
|
||
console.warn("保存失败:", error);
|
||
Taro.showToast({
|
||
title: "保存失败",
|
||
icon: "error",
|
||
});
|
||
}
|
||
};
|
||
|
||
// 处理性别选择
|
||
const handle_gender_change = (e: any) => {
|
||
if (!Array.isArray(e) || e.length === 0 || e[0] === undefined) {
|
||
Taro.showToast({
|
||
title: "请选择性别",
|
||
icon: "none",
|
||
});
|
||
return;
|
||
}
|
||
const gender_value = e[0];
|
||
handle_field_edit("gender", String(gender_value));
|
||
};
|
||
|
||
// 处理生日选择
|
||
const handle_birthday_change = (e: any) => {
|
||
if (!Array.isArray(e) || e.length < 3 || e.some((v) => v === undefined)) {
|
||
Taro.showToast({
|
||
title: "请完整选择生日",
|
||
icon: "none",
|
||
});
|
||
return;
|
||
}
|
||
const [year, month, day] = e;
|
||
handle_field_edit(
|
||
"birthday",
|
||
`${year}-${String(month).padStart(2, "0")}-${String(day).padStart(
|
||
2,
|
||
"0"
|
||
)}`
|
||
);
|
||
};
|
||
|
||
// 处理地区选择
|
||
const handle_location_change = (e: any) => {
|
||
if (
|
||
!Array.isArray(e) ||
|
||
e.length < 3 ||
|
||
e.some((v) => v === undefined || v === null)
|
||
) {
|
||
Taro.showToast({
|
||
title: "请完整选择地区",
|
||
icon: "none",
|
||
});
|
||
return;
|
||
}
|
||
const [province, city, district] = e;
|
||
handle_field_edit({
|
||
province: String(province ?? ""),
|
||
city: String(city ?? ""),
|
||
district: String(district ?? ""),
|
||
});
|
||
};
|
||
|
||
// 处理NTRP水平选择
|
||
const handle_ntrp_level_change = (e: any) => {
|
||
// if (!Array.isArray(e) || e.length === 0 || e[0] === undefined) {
|
||
// Taro.showToast({
|
||
// title: "请选择NTRP水平",
|
||
// icon: "none",
|
||
// });
|
||
// return;
|
||
// }
|
||
const ntrp_level_value = e[0];
|
||
handle_field_edit("ntrp_level", ntrp_level_value);
|
||
};
|
||
|
||
// 处理职业选择
|
||
const handle_occupation_change = (e: any) => {
|
||
if (
|
||
!Array.isArray(e) ||
|
||
e.length === 0 ||
|
||
e.some((v) => v === undefined || v === null)
|
||
) {
|
||
Taro.showToast({
|
||
title: "请完整选择职业",
|
||
icon: "none",
|
||
});
|
||
return;
|
||
}
|
||
// 职业可能是多级联动,将所有选中的值用空格连接
|
||
const occupation_value = e
|
||
.map((v) => String(v ?? ""))
|
||
.filter(Boolean)
|
||
.join(" ");
|
||
handle_field_edit("occupation", occupation_value);
|
||
};
|
||
|
||
// 处理退出登录
|
||
const handle_logout = () => {
|
||
Taro.showModal({
|
||
title: "确认退出",
|
||
content: "确定要退出登录吗?",
|
||
success: (res) => {
|
||
if (res.confirm) {
|
||
// 清除用户数据
|
||
clear_login_state();
|
||
|
||
Taro.reLaunch({
|
||
url: "/login_pages/index/index",
|
||
});
|
||
}
|
||
},
|
||
});
|
||
};
|
||
|
||
// 注销账户
|
||
const handle_close_account = () => {
|
||
setShowLogoutDialog(true);
|
||
};
|
||
|
||
const onGetPhoneNumber = async (e) => {
|
||
if (!e.detail || !e.detail.code) {
|
||
Taro.showToast({
|
||
title: "获取手机号失败,请重试",
|
||
icon: "none",
|
||
duration: 2000,
|
||
});
|
||
return;
|
||
}
|
||
try {
|
||
const phone = await UserService.parse_phone(e.detail.code);
|
||
handle_field_edit("phone", phone);
|
||
} catch (e) {
|
||
console.warn("解析手机号失败:", e);
|
||
Taro.showToast({
|
||
title: "解析手机号失败,请重试",
|
||
icon: "none",
|
||
duration: 2000,
|
||
});
|
||
}
|
||
};
|
||
|
||
const handleJoinGroup = () => {
|
||
Taro.navigateTo({
|
||
url: "/user_pages/joinGroup/index",
|
||
});
|
||
};
|
||
|
||
const getDefaultOption = (options) => {
|
||
if (!Array.isArray(options) || options.length === 0) {
|
||
return [];
|
||
}
|
||
|
||
const defaultOptions: string[] = [];
|
||
let current = options[0];
|
||
|
||
while (current) {
|
||
defaultOptions.push(current.text);
|
||
current = current.children?.[0];
|
||
}
|
||
|
||
return defaultOptions;
|
||
};
|
||
|
||
return (
|
||
<View className="edit_profile_page">
|
||
{/* 导航栏 */}
|
||
{/* <View className="custom-navbar">
|
||
<View className="detail-navigator">
|
||
<View
|
||
className="detail-navigator-back"
|
||
onClick={() => {
|
||
Taro.navigateBack();
|
||
}}
|
||
>
|
||
<Image
|
||
className="detail-navigator-back-icon"
|
||
src={img.ICON_NAVIGATOR_BACK}
|
||
/>
|
||
</View>
|
||
</View>
|
||
</View> */}
|
||
{/* 顶部导航栏 */}
|
||
<GeneralNavbar
|
||
title=""
|
||
showBack={true}
|
||
showAvatar={false}
|
||
onBack={() => {
|
||
Taro.navigateBack();
|
||
}}
|
||
/>
|
||
{/* 主要内容 */}
|
||
<View className="edit_main_content">
|
||
{loading ? (
|
||
<View className="loading_container">
|
||
<Text className="loading_text">加载中...</Text>
|
||
</View>
|
||
) : (
|
||
<>
|
||
{/* 头像编辑区域 */}
|
||
<View className="avatar_section">
|
||
<View className="avatar_container" onClick={handle_avatar_upload}>
|
||
<Image
|
||
className="avatar"
|
||
src={(user_info as UserInfoType)?.avatar_url || ""}
|
||
mode="aspectFill"
|
||
/>
|
||
<View className="avatar_overlay">
|
||
<Image
|
||
className="upload_icon"
|
||
src={require("@/static/userInfo/edit2.svg")}
|
||
/>
|
||
</View>
|
||
</View>
|
||
</View>
|
||
|
||
{/* 基本信息编辑 */}
|
||
<View className="form_section">
|
||
{/* 名字 */}
|
||
<View className="form_group">
|
||
<View
|
||
className="form_item"
|
||
onClick={() => handle_open_edit_modal("nickname")}
|
||
>
|
||
<View className="item_left">
|
||
<Image
|
||
className="item_icon"
|
||
src={require("@/static/userInfo/user.svg")}
|
||
/>
|
||
<Text className="item_label">名字</Text>
|
||
</View>
|
||
<View className="item_right">
|
||
<Text className="item_value">
|
||
{form_data.nickname || ""}
|
||
</Text>
|
||
<Image
|
||
className="arrow_icon"
|
||
src={require("@/static/list/icon-list-right-arrow.svg")}
|
||
/>
|
||
</View>
|
||
</View>
|
||
<View className="divider"></View>
|
||
</View>
|
||
|
||
{/* 性别 */}
|
||
<View className="form_group">
|
||
<View
|
||
className="form_item"
|
||
onClick={() => handle_open_edit_modal("gender")}
|
||
>
|
||
<View className="item_left">
|
||
<Image
|
||
className="item_icon"
|
||
src={require("@/static/userInfo/gender.svg")}
|
||
/>
|
||
<Text className="item_label">性别</Text>
|
||
</View>
|
||
<View className="item_right">
|
||
<Text
|
||
className={`item_value ${form_data.gender ? "" : "placeholder"
|
||
}`}
|
||
>
|
||
{convert_db_gender_to_display(form_data.gender)}
|
||
</Text>
|
||
<Image
|
||
className="arrow_icon"
|
||
src={require("@/static/list/icon-list-right-arrow.svg")}
|
||
/>
|
||
</View>
|
||
</View>
|
||
<View
|
||
className="divider"
|
||
style="transform: translate(0, 0);"
|
||
></View>
|
||
</View>
|
||
|
||
{/* 生日 */}
|
||
<View className="form_group">
|
||
<View
|
||
className="form_item"
|
||
onClick={() => handle_open_edit_modal("birthday")}
|
||
>
|
||
<View className="item_left">
|
||
<Image
|
||
className="item_icon"
|
||
src={require("@/static/userInfo/birthday.svg")}
|
||
/>
|
||
<Text className="item_label">生日</Text>
|
||
</View>
|
||
<View className="item_right">
|
||
<Text
|
||
className={`item_value ${form_data.birthday ? "" : "placeholder"
|
||
}`}
|
||
>
|
||
{form_data.birthday || "选择生日"}
|
||
</Text>
|
||
<Image
|
||
className="arrow_icon"
|
||
src={require("@/static/list/icon-list-right-arrow.svg")}
|
||
/>
|
||
</View>
|
||
</View>
|
||
</View>
|
||
</View>
|
||
|
||
{/* 简介编辑 */}
|
||
<View className="form_section">
|
||
<View className="form_group">
|
||
<View
|
||
className="form_item"
|
||
onClick={() => handle_open_edit_modal("personal_profile")}
|
||
>
|
||
<View className="item_left">
|
||
<Image
|
||
className="item_icon"
|
||
src={require("@/static/userInfo/introduce.svg")}
|
||
/>
|
||
<Text className="item_label">简介</Text>
|
||
</View>
|
||
<View className="item_right">
|
||
<Text
|
||
className={`item_value ${form_data.personal_profile ? "" : "placeholder"
|
||
}`}
|
||
>
|
||
{form_data.personal_profile.replace(/\n/g, " ") ||
|
||
"介绍一下自己"}
|
||
</Text>
|
||
<Image
|
||
className="arrow_icon"
|
||
src={require("@/static/list/icon-list-right-arrow.svg")}
|
||
/>
|
||
</View>
|
||
</View>
|
||
</View>
|
||
</View>
|
||
|
||
{/* 地区、NTRP水平、职业 */}
|
||
<View className="form_section">
|
||
<View className="form_group">
|
||
{/* 地区 */}
|
||
<View
|
||
className="form_item"
|
||
onClick={() => handle_open_edit_modal("location")}
|
||
>
|
||
<View className="item_left">
|
||
<Image
|
||
className="item_icon"
|
||
src={require("@/static/userInfo/gender.svg")}
|
||
/>
|
||
<Text className="item_label">地区</Text>
|
||
</View>
|
||
<View className="item_right">
|
||
<Text
|
||
className={`item_value ${form_data.province ||
|
||
form_data.city ||
|
||
form_data.district
|
||
? ""
|
||
: "placehoder"
|
||
}`}
|
||
>
|
||
{form_data.province ||
|
||
form_data.city ||
|
||
form_data.district
|
||
? `${form_data.province} ${form_data.city} ${form_data.district}`
|
||
: "选择所在地区"}
|
||
</Text>
|
||
<Image
|
||
className="arrow_icon"
|
||
src={require("@/static/list/icon-list-right-arrow.svg")}
|
||
/>
|
||
</View>
|
||
</View>
|
||
<View className="divider"></View>
|
||
|
||
{/* NTRP水平 */}
|
||
<View
|
||
className="form_item"
|
||
onClick={() => handle_open_edit_modal("ntrp_level")}
|
||
>
|
||
<View className="item_left">
|
||
<Image
|
||
className="item_icon"
|
||
src={require("@/static/userInfo/ball.svg")}
|
||
/>
|
||
<Text className="item_label">NTRP 水平</Text>
|
||
</View>
|
||
<View className="item_right">
|
||
<Text
|
||
className={`item_value ${form_data.ntrp_level ? "" : "placeholder"
|
||
}`}
|
||
>
|
||
{form_data.ntrp_level || "测测你的 NTRP 水平"}
|
||
</Text>
|
||
<Image
|
||
className="arrow_icon"
|
||
src={require("@/static/list/icon-list-right-arrow.svg")}
|
||
/>
|
||
</View>
|
||
</View>
|
||
<View className="divider"></View>
|
||
|
||
{/* 职业 */}
|
||
<View
|
||
className="form_item"
|
||
onClick={() => handle_open_edit_modal("occupation")}
|
||
>
|
||
<View className="item_left">
|
||
<Image
|
||
className="item_icon"
|
||
src={require("@/static/userInfo/business.svg")}
|
||
/>
|
||
<Text className="item_label">职业</Text>
|
||
</View>
|
||
<View
|
||
className={`item_right ${form_data.occupation ? "" : "placeholder"
|
||
}`}
|
||
>
|
||
<Text
|
||
className={`item_value ${form_data.occupation ? "" : "placeholder"
|
||
}`}
|
||
>
|
||
{form_data.occupation || "填写你的职业"}
|
||
</Text>
|
||
<Image
|
||
className="arrow_icon"
|
||
src={require("@/static/list/icon-list-right-arrow.svg")}
|
||
/>
|
||
</View>
|
||
</View>
|
||
</View>
|
||
</View>
|
||
|
||
{/* 手机号 */}
|
||
<View className="form_section">
|
||
<View className="form_group">
|
||
<View className="form_item">
|
||
<View className="item_left">
|
||
<Image
|
||
className="item_icon"
|
||
src={require("@/static/userInfo/phone.svg")}
|
||
/>
|
||
<Text className="item_label">手机</Text>
|
||
</View>
|
||
<View className="item_right">
|
||
{/* <Input
|
||
className="item_input"
|
||
value={form_data.phone}
|
||
placeholder="请输入手机号"
|
||
type="number"
|
||
onInput={handle_phone_input}
|
||
onBlur={handle_phone_blur}
|
||
/> */}
|
||
<Button
|
||
className={form_data.phone ? "" : "placeholer"}
|
||
openType="getPhoneNumber"
|
||
onGetPhoneNumber={onGetPhoneNumber}
|
||
>
|
||
{form_data.phone
|
||
? form_data.phone.replace(
|
||
/(\d{3})(\d{4})(\d{4})/,
|
||
"$1 $2 $3"
|
||
)
|
||
: "未绑定"}
|
||
</Button>
|
||
<Image
|
||
className="arrow_icon"
|
||
src={require("@/static/list/icon-list-right-arrow.svg")}
|
||
/>
|
||
</View>
|
||
</View>
|
||
{/* <View className="divider"></View> */}
|
||
</View>
|
||
</View>
|
||
|
||
<View className="logout_section group">
|
||
<View className="logout_button" onClick={handleCustomerService}>
|
||
<Image
|
||
src={require("@/static/wallet/custom-service.svg")}
|
||
></Image>
|
||
<Text className="logout_text">客服聊天</Text>
|
||
</View>
|
||
<View className="logout_button" onClick={handleJoinGroup}>
|
||
<Image src={require("@/static/userInfo/chat.svg")}></Image>
|
||
<Text className="logout_text">加入社群</Text>
|
||
</View>
|
||
</View>
|
||
|
||
{/* 退出登录 */}
|
||
<View className="logout_section">
|
||
<View className="logout_button" onClick={handle_logout}>
|
||
<Text className="logout_text">退出登录</Text>
|
||
</View>
|
||
</View>
|
||
|
||
{/* 注销账号 */}
|
||
<View className="logout_section">
|
||
<View className="logout_button" onClick={handle_close_account}>
|
||
<Text className="logout_text close_account">注销账号</Text>
|
||
</View>
|
||
</View>
|
||
</>
|
||
)}
|
||
</View>
|
||
|
||
{/* 编辑弹窗 */}
|
||
<EditModal
|
||
visible={edit_modal_visible}
|
||
type={editing_field}
|
||
title={editing_field === "nickname" ? "编辑名字" : "编辑简介"}
|
||
placeholder={
|
||
editing_field === "nickname"
|
||
? "请输入您的名字"
|
||
: "介绍一下你的喜好,或者训练习惯"
|
||
}
|
||
initialValue={form_data[editing_field as keyof typeof form_data] || ""}
|
||
maxLength={editing_field === "nickname" ? 24 : 100}
|
||
invalidCharacters={
|
||
editing_field === "nickname"
|
||
? /^[\u4e00-\u9fa5a-zA-Z0-9_\-\.\(\)\s]*$/
|
||
: null
|
||
}
|
||
onSave={handle_edit_modal_save}
|
||
onCancel={handle_edit_modal_cancel}
|
||
validationMessage={
|
||
editing_field === "nickname"
|
||
? `请填写 2-24 个字符,不包括 @<>/等无效字符。30 天内可修改 4 次昵称,${nickname_change_status.next_period_start_date} 前还可修改 ${nickname_change_status.remaining_count} 次。`
|
||
: "请填写 2-100 个字符"
|
||
}
|
||
/>
|
||
{/* 性别选择弹窗 */}
|
||
{gender_picker_visible && (
|
||
<PopupPicker
|
||
showHeader={true}
|
||
title="选择性别"
|
||
confirmText="保存"
|
||
options={[
|
||
[
|
||
{ text: "男", value: "0" },
|
||
{ text: "女", value: "1" },
|
||
{ text: "保密", value: "2" },
|
||
],
|
||
]}
|
||
visible={gender_picker_visible}
|
||
setvisible={setGenderPickerVisible}
|
||
value={form_data.gender === "" ? ["0"] : [form_data.gender]}
|
||
onChange={handle_gender_change}
|
||
/>
|
||
)}
|
||
{/* 生日选择弹窗 */}
|
||
{birthday_picker_visible && (
|
||
<PopupPicker
|
||
minYear={1970}
|
||
maxYear={new Date().getFullYear()}
|
||
showHeader={true}
|
||
title="选择生日"
|
||
confirmText="保存"
|
||
visible={birthday_picker_visible}
|
||
setvisible={setBirthdayPickerVisible}
|
||
value={[
|
||
new Date(form_data.birthday || Date.now()).getFullYear(),
|
||
new Date(form_data.birthday || Date.now()).getMonth() + 1,
|
||
new Date(form_data.birthday || Date.now()).getDate(),
|
||
]}
|
||
type="day"
|
||
onChange={handle_birthday_change}
|
||
/>
|
||
)}
|
||
{/* 地区选择弹窗 */}
|
||
{location_picker_visible && (
|
||
<PopupPicker
|
||
showHeader={true}
|
||
title="选择地区"
|
||
confirmText="保存"
|
||
options={cities}
|
||
visible={location_picker_visible}
|
||
setvisible={setLocationPickerVisible}
|
||
value={
|
||
form_data.province
|
||
? [form_data.province, form_data.city, form_data.district]
|
||
: getDefaultOption(cities)
|
||
}
|
||
onChange={handle_location_change}
|
||
/>
|
||
)}
|
||
{/* NTRP水平选择弹窗 */}
|
||
{ntrp_picker_visible && (
|
||
<PopupPicker
|
||
showHeader={true}
|
||
title="选择 NTRP 自评水平"
|
||
confirmText="保存"
|
||
ntrpTested={ntrpTested}
|
||
options={ntrpLevels}
|
||
type="ntrp"
|
||
// img={(user_info as UserInfoType)?.avatar_url}
|
||
visible={ntrp_picker_visible}
|
||
setvisible={setNtrpPickerVisible}
|
||
value={!form_data.ntrp_level ? ["2.5"] : [form_data.ntrp_level]}
|
||
onChange={handle_ntrp_level_change}
|
||
/>
|
||
)}
|
||
{/* 职业选择弹窗 */}
|
||
{occupation_picker_visible && (
|
||
<PopupPicker
|
||
showHeader={true}
|
||
title="选择职业"
|
||
confirmText="保存"
|
||
options={professions}
|
||
visible={occupation_picker_visible}
|
||
setvisible={setOccupationPickerVisible}
|
||
value={
|
||
form_data.occupation
|
||
? [...form_data.occupation.split(" ")]
|
||
: getDefaultOption(professions)
|
||
}
|
||
onChange={handle_occupation_change}
|
||
/>
|
||
)}
|
||
{/* 取消关注确认弹窗 */}
|
||
<CommonDialog
|
||
visible={showLogoutDialog}
|
||
cancelText="确定注销"
|
||
confirmText="再想想"
|
||
onCancel={() => {
|
||
UserService.logout();
|
||
}}
|
||
onConfirm={() => setShowLogoutDialog(false)}
|
||
contentTitle="确定要注销账号吗?"
|
||
contentDesc="你的账号将会彻底删除,该操作不可恢复。"
|
||
/>
|
||
</View>
|
||
);
|
||
};
|
||
|
||
export default EditProfilePage;
|