优化个人页

This commit is contained in:
2025-10-17 16:24:07 +08:00
parent 8f688378e1
commit f3ab0020d3
7 changed files with 549 additions and 429 deletions

View File

@@ -1,12 +1,11 @@
import { UserInfo } from '@/components/UserInfo';
import { API_CONFIG } from '@/config/api';
import httpService, { ApiResponse } from './httpService';
import uploadFiles from './uploadFiles';
import Taro from '@tarojs/taro';
import getCurrentConfig from '@/config/env';
import { UserInfo } from "@/components/UserInfo";
import { API_CONFIG } from "@/config/api";
import httpService, { ApiResponse } from "./httpService";
import uploadFiles from "./uploadFiles";
import Taro from "@tarojs/taro";
import getCurrentConfig from "@/config/env";
import { clear_login_state } from "@/services/loginService";
// 用户详情接口
interface UserDetailData {
id: number;
@@ -33,7 +32,7 @@ interface UserDetailData {
personal_profile: string;
occupation: string;
birthday: string;
ntrp_level: string,
ntrp_level: string;
stats: {
followers_count: number;
following_count: number;
@@ -55,27 +54,42 @@ export interface Profession {
// 用户详细信息接口(从 loginService 移过来)
export interface UserInfoType {
id: number
openid: string
unionid: string
session_key: string
nickname: string
avatar_url: string
gender: string
country: string
province: string
city: string
district: string
language: string
phone: string
is_subscribed: string
latitude: number
longitude: number
subscribe_time: string
last_login_time: string
id: number;
openid: string;
unionid: string;
session_key: string;
nickname: string;
avatar_url: string;
gender: string;
country: string;
province: string;
city: string;
district: string;
language: string;
phone: string;
is_subscribed: string;
latitude: number;
longitude: number;
subscribe_time: string;
last_login_time: string;
avatar: string;
join_date: string;
stats: {
following_count: number;
followers_count: number;
hosted_games_count: number;
participated_games_count: number;
};
personal_profile: string;
occupation: string;
ntrp_level: string;
bio?: string;
birthday?: string;
is_following?: boolean;
tags?: string[];
ongoing_games?: string[];
}
// 后端球局数据接口
interface BackendGameData {
id: number;
@@ -138,37 +152,43 @@ const formatOptions = (data: Profession[]): PickerOption[] => {
const itm: PickerOption = {
text,
value: text,
children: children ? formatOptions(children) : []
}
children: children ? formatOptions(children) : [],
};
if (!itm.children!.length) {
delete itm.children
delete itm.children;
}
return itm
})
}
return itm;
});
};
// 用户服务类
export class UserService {
// 数据转换函数将后端数据转换为ListContainer期望的格式
private static transform_game_data(backend_data: BackendGameData[]): any[] {
return backend_data.map(game => {
return backend_data.map((game) => {
// 处理时间格式
const start_time = new Date(game.start_time.replace(/\s/, 'T'));
const start_time = new Date(game.start_time.replace(/\s/, "T"));
const date_time = this.format_date_time(start_time);
// 处理图片数组 - 兼容两种数据格式
let images: string[] = [];
if (game.image_list && game.image_list.length > 0) {
images = game.image_list.filter(img => img && img.trim() !== '');
images = game.image_list.filter((img) => img && img.trim() !== "");
} else if (game.venue_image_list && game.venue_image_list.length > 0) {
images = game.venue_image_list
.filter(img => img && img.url && img.url.trim() !== '')
.map(img => img.url);
.filter((img) => img && img.url && img.url.trim() !== "")
.map((img) => img.url);
}
// 处理距离 - 优先使用venue_dtl中的坐标其次使用game中的坐标
let latitude: number = typeof game.latitude === 'number' ? game.latitude : parseFloat(game.latitude || '0') || 0;
let longitude: number = typeof game.longitude === 'number' ? game.longitude : parseFloat(game.longitude || '0') || 0;
let latitude: number =
typeof game.latitude === "number"
? game.latitude
: parseFloat(game.latitude || "0") || 0;
let longitude: number =
typeof game.longitude === "number"
? game.longitude
: parseFloat(game.longitude || "0") || 0;
if (game.venue_dtl) {
latitude = parseFloat(game.venue_dtl.latitude) || latitude;
longitude = parseFloat(game.venue_dtl.longitude) || longitude;
@@ -176,33 +196,34 @@ export class UserService {
const distance = this.calculate_distance(latitude, longitude);
// 处理地点信息 - 优先使用venue_dtl中的信息
let location = game.location_name || game.location || '未知地点';
let location = game.location_name || game.location || "未知地点";
if (game.venue_dtl && game.venue_dtl.name) {
location = game.venue_dtl.name;
}
// 处理人数统计 - 兼容不同的字段名
const registered_count = game.current_players || game.participant_count || 0;
const registered_count =
game.current_players || game.participant_count || 0;
const max_count = game.max_players || game.max_participants || 0;
// 转换为 ListCard 期望的格式
return {
id: game.id,
title: game.title || '未命名球局',
title: game.title || "未命名球局",
start_time: date_time,
original_start_time: game.start_time,
end_time: game.end_time || '',
end_time: game.end_time || "",
location: location,
distance_km: parseFloat(distance.replace('km', '')) || 0,
distance_km: parseFloat(distance.replace("km", "")) || 0,
current_players: registered_count,
max_players: max_count,
skill_level_min: parseInt(game.skill_level_min) || 0,
skill_level_max: parseInt(game.skill_level_max) || 0,
play_type: game.play_type || '不限',
play_type: game.play_type || "不限",
image_list: images,
court_type: game.court_type || '未知',
matchType: game.play_type || '不限',
shinei: game.court_type || '未知',
court_type: game.court_type || "未知",
matchType: game.play_type || "不限",
shinei: game.court_type || "未知",
participants: game.participants || [],
};
});
@@ -210,8 +231,12 @@ export class UserService {
private static is_date_in_this_week(date: Date): boolean {
const today = new Date();
const firstDayOfWeek = new Date(today.setDate(today.getDate() - today.getDay()));
const lastDayOfWeek = new Date(firstDayOfWeek.setDate(firstDayOfWeek.getDate() + 6));
const firstDayOfWeek = new Date(
today.setDate(today.getDate() - today.getDay())
);
const lastDayOfWeek = new Date(
firstDayOfWeek.setDate(firstDayOfWeek.getDate() + 6)
);
return date >= firstDayOfWeek && date <= lastDayOfWeek;
}
@@ -219,17 +244,27 @@ export class UserService {
// 格式化时间显示
private static format_date_time(start_time: Date): string {
const now = new Date();
const today = new Date(now.getFullYear(), now.getMonth() + 1, now.getDate());
const today = new Date(
now.getFullYear(),
now.getMonth() + 1,
now.getDate()
);
const tomorrow = new Date(today.getTime() + 24 * 60 * 60 * 1000);
const day_after_tomorrow = new Date(today.getTime() + 2 * 24 * 60 * 60 * 1000);
const weekdays = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];
const day_after_tomorrow = new Date(
today.getTime() + 2 * 24 * 60 * 60 * 1000
);
const weekdays = ["周日", "周一", "周二", "周三", "周四", "周五", "周六"];
const start_date = new Date(start_time.getFullYear(), start_time.getMonth() + 1, start_time.getDate());
const start_date = new Date(
start_time.getFullYear(),
start_time.getMonth() + 1,
start_time.getDate()
);
const weekday = weekdays[start_time.getDay()];
let date_str = '';
let date_str = "";
if (start_date.getTime() === today.getTime()) {
date_str = '今天';
date_str = "今天";
} else if (start_date.getTime() === tomorrow.getTime()) {
date_str = `明天(${weekday})`;
} else if (start_date.getTime() === day_after_tomorrow.getTime()) {
@@ -237,63 +272,84 @@ export class UserService {
} else if (this.is_date_in_this_week(start_time)) {
date_str = weekday;
} else {
date_str = `${start_time.getFullYear()}-${(start_time.getMonth() + 1).toString().padStart(2, '0')}-${start_time.getDate().toString().padStart(2, '0')}(${weekday})`;
date_str = `${start_time.getFullYear()}-${(start_time.getMonth() + 1)
.toString()
.padStart(2, "0")}-${start_time
.getDate()
.toString()
.padStart(2, "0")}(${weekday})`;
}
const time_str = `${start_time.getHours().toString().padStart(2, '0')}:${start_time.getMinutes().toString().padStart(2, '0')}`;
const time_str = `${start_time
.getHours()
.toString()
.padStart(2, "0")}:${start_time
.getMinutes()
.toString()
.padStart(2, "0")}`;
return `${date_str} ${time_str}`;
}
// 计算距离(模拟实现,实际需要根据用户位置计算)
private static calculate_distance(latitude: number, longitude: number): string {
private static calculate_distance(
latitude: number,
longitude: number
): string {
if (latitude === 0 && longitude === 0) {
return '未知距离';
return "未知距离";
}
// 这里应该根据用户当前位置计算实际距离
// 暂时返回模拟距离
const distances = ['1.2km', '2.5km', '3.8km', '5.1km', '7.3km'];
const distances = ["1.2km", "2.5km", "3.8km", "5.1km", "7.3km"];
return distances[Math.floor(Math.random() * distances.length)];
}
// 获取用户信息
static async get_user_info(user_id?: string): Promise<UserInfo> {
try {
const response = await httpService.post<UserDetailData>(API_CONFIG.USER.DETAIL, user_id ? { user_id } : {}, {
showLoading: false
});
const response = await httpService.post<UserDetailData>(
API_CONFIG.USER.DETAIL,
user_id ? { user_id } : {},
{
showLoading: false,
}
);
if (response.code === 0) {
const userData = response.data;
return {
id: userData.id || '',
nickname: userData.nickname || '',
avatar: userData.avatar_url || '',
join_date: userData.subscribe_time ? `${new Date(userData.subscribe_time).getFullYear()}${new Date(userData.subscribe_time).getMonth() + 1}月加入` : '',
id: userData.id || "",
nickname: userData.nickname || "",
avatar: userData.avatar_url || "",
join_date: userData.subscribe_time
? `${new Date(userData.subscribe_time).getFullYear()}${
new Date(userData.subscribe_time).getMonth() + 1
}月加入`
: "",
stats: {
following: userData.stats?.following_count || 0,
friends: userData.stats?.followers_count || 0,
hosted: userData.stats?.hosted_games_count || 0,
participated: userData.stats?.participated_games_count || 0
participated: userData.stats?.participated_games_count || 0,
},
personal_profile: userData.personal_profile || '',
occupation: userData.occupation || '',
ntrp_level: userData.ntrp_level || '',
phone: userData.phone || '',
gender: userData.gender || '',
birthday: userData.birthday || '',
country: userData.country || '',
province: userData.province || '',
city: userData.city || '',
personal_profile: userData.personal_profile || "",
occupation: userData.occupation || "",
ntrp_level: userData.ntrp_level || "",
phone: userData.phone || "",
gender: userData.gender || "",
birthday: userData.birthday || "",
country: userData.country || "",
province: userData.province || "",
city: userData.city || "",
};
} else {
throw new Error(response.message || '获取用户信息失败');
throw new Error(response.message || "获取用户信息失败");
}
} catch (error) {
console.error('获取用户信息失败:', error);
console.error("获取用户信息失败:", error);
// 返回默认用户信息
return {} as UserInfo
return {} as UserInfo;
}
}
@@ -303,32 +359,36 @@ export class UserService {
// 过滤掉空字段
const filtered_data: Record<string, any> = {};
Object.keys(update_data).forEach(key => {
Object.keys(update_data).forEach((key) => {
const value = update_data[key as keyof UserInfo];
// 只添加非空且非空字符串的字段
if (value !== null && value !== undefined && value !== '') {
if (typeof value === 'string' && value.trim() !== '') {
if (value !== null && value !== undefined && value !== "") {
if (typeof value === "string" && value.trim() !== "") {
filtered_data[key] = value.trim();
} else if (typeof value !== 'string') {
} else if (typeof value !== "string") {
filtered_data[key] = value;
}
}
});
// 如果没有需要更新的字段,直接返回
if (Object.keys(filtered_data).length === 0) {
console.log('没有需要更新的字段');
console.log("没有需要更新的字段");
return;
}
const response = await httpService.post(API_CONFIG.USER.UPDATE, filtered_data, {
showLoading: true
});
const response = await httpService.post(
API_CONFIG.USER.UPDATE,
filtered_data,
{
showLoading: true,
}
);
if (response.code !== 0) {
throw new Error(response.message || '更新用户信息失败');
throw new Error(response.message || "更新用户信息失败");
}
} catch (error) {
console.error('更新用户信息失败:', error);
console.error("更新用户信息失败:", error);
throw error;
}
}
@@ -336,53 +396,61 @@ export class UserService {
// 获取用户主办的球局
static async get_hosted_games(userId: string | number): Promise<any[]> {
try {
const response = await httpService.post<any>(API_CONFIG.USER.HOSTED_GAMES, {
userId
}, {
showLoading: false
});
const response = await httpService.post<any>(
API_CONFIG.USER.HOSTED_GAMES,
{
userId,
},
{
showLoading: false,
}
);
if (response.code === 0) {
// 使用数据转换函数将后端数据转换为ListContainer期望的格式
return this.transform_game_data(response.data.rows || []);
} else {
throw new Error(response.message || '获取主办球局失败');
throw new Error(response.message || "获取主办球局失败");
}
} catch (error) {
console.error('获取主办球局失败:', error);
console.error("获取主办球局失败:", error);
// 返回符合ListContainer data格式的模拟数据
return []
return [];
}
}
// 获取用户参与的球局
static async get_participated_games(userId: string | number): Promise<any[]> {
try {
const response = await httpService.post<any>(API_CONFIG.USER.PARTICIPATED_GAMES, {
userId
}, {
showLoading: false
});
const response = await httpService.post<any>(
API_CONFIG.USER.PARTICIPATED_GAMES,
{
userId,
},
{
showLoading: false,
}
);
if (response.code === 0) {
// 使用数据转换函数将后端数据转换为ListContainer期望的格式
return this.transform_game_data(response.data.rows || []);
} else {
throw new Error(response.message || '获取参与球局失败');
throw new Error(response.message || "获取参与球局失败");
}
} catch (error) {
console.error('获取参与球局失败:', error);
console.error("获取参与球局失败:", error);
// 返回符合ListContainer data格式的模拟数据
return [];
}
}
// 获取用户球局记录(兼容旧方法)
static async get_user_games(user_id: string | number, type: 'hosted' | 'participated'): Promise<any[]> {
if (type === 'hosted') {
static async get_user_games(
user_id: string | number,
type: "hosted" | "participated"
): Promise<any[]> {
if (type === "hosted") {
return this.get_hosted_games(user_id);
} else {
return this.get_participated_games(user_id);
@@ -390,98 +458,118 @@ export class UserService {
}
// 关注/取消关注用户
static async toggle_follow(following_id: string | number, is_following: boolean): Promise<boolean> {
static async toggle_follow(
following_id: string | number,
is_following: boolean
): Promise<boolean> {
try {
const endpoint = is_following ? API_CONFIG.USER.UNFOLLOW : API_CONFIG.USER.FOLLOW;
const response = await httpService.post<any>(endpoint, { following_id }, {
showLoading: true,
loadingText: is_following ? '取消关注中...' : '关注中...'
});
const endpoint = is_following
? API_CONFIG.USER.UNFOLLOW
: API_CONFIG.USER.FOLLOW;
const response = await httpService.post<any>(
endpoint,
{ following_id },
{
showLoading: true,
loadingText: is_following ? "取消关注中..." : "关注中...",
}
);
if (response.code === 0) {
return !is_following;
} else {
throw new Error(response.message || '操作失败');
throw new Error(response.message || "操作失败");
}
} catch (error) {
console.error('关注操作失败:', error);
console.error("关注操作失败:", error);
throw error;
}
}
// 保存用户信息
static async save_user_info(user_info: Partial<UserInfo> & { phone?: string; gender?: string }): Promise<boolean> {
static async save_user_info(
user_info: Partial<UserInfo> & { phone?: string; gender?: string }
): Promise<boolean> {
try {
// 字段映射配置
const field_mapping: Record<string, string> = {
nickname: 'nickname',
avatar: 'avatar_url',
gender: 'gender',
phone: 'phone',
latitude: 'latitude',
longitude: 'longitude',
province: 'province',
nickname: "nickname",
avatar: "avatar_url",
gender: "gender",
phone: "phone",
latitude: "latitude",
longitude: "longitude",
province: "province",
country: "country",
city: "city",
personal_profile: 'personal_profile',
occupation: 'occupation',
ntrp_level: 'ntrp_level'
personal_profile: "personal_profile",
occupation: "occupation",
ntrp_level: "ntrp_level",
};
// 构建更新参数,只包含非空字段
const updateParams: Record<string, string> = {};
// 循环处理所有字段
Object.keys(field_mapping).forEach(key => {
Object.keys(field_mapping).forEach((key) => {
const value = user_info[key as keyof typeof user_info];
if (value && typeof value === 'string' && value.trim() !== '') {
if (value && typeof value === "string" && value.trim() !== "") {
updateParams[field_mapping[key]] = value.trim();
}
});
// 如果没有需要更新的字段,直接返回成功
if (Object.keys(updateParams).length === 0) {
console.log('没有需要更新的字段');
console.log("没有需要更新的字段");
return true;
}
const response = await httpService.post<any>(API_CONFIG.USER.UPDATE, updateParams, {
showLoading: true,
loadingText: '保存中...'
});
const response = await httpService.post<any>(
API_CONFIG.USER.UPDATE,
updateParams,
{
showLoading: true,
loadingText: "保存中...",
}
);
if (response.code === 0) {
return true;
} else {
throw new Error(response.message || '更新用户信息失败');
throw new Error(response.message || "更新用户信息失败");
}
} catch (error) {
console.error('保存用户信息失败:', error);
console.error("保存用户信息失败:", error);
throw error;
}
}
// 获取用户动态
static async get_user_activities(user_id: string, page: number = 1, limit: number = 10): Promise<any[]> {
static async get_user_activities(
user_id: string,
page: number = 1,
limit: number = 10
): Promise<any[]> {
try {
const response = await httpService.post<any>('/user/activities', {
user_id,
page,
limit
}, {
showLoading: false
});
const response = await httpService.post<any>(
"/user/activities",
{
user_id,
page,
limit,
},
{
showLoading: false,
}
);
if (response.code === 0) {
return response.data.activities || [];
} else {
throw new Error(response.message || '获取用户动态失败');
throw new Error(response.message || "获取用户动态失败");
}
} catch (error) {
console.error('获取用户动态失败:', error);
console.error("获取用户动态失败:", error);
return [];
}
}
@@ -490,34 +578,38 @@ export class UserService {
static async upload_avatar(file_path: string): Promise<string> {
try {
// 先上传文件到服务器
const result = await uploadFiles.upload_oss_img(file_path)
const result = await uploadFiles.upload_oss_img(file_path);
await this.save_user_info({ avatar: result.ossPath })
await this.save_user_info({ avatar: result.ossPath });
// 使用新的响应格式中的file_url字段
return result.ossPath;
} catch (error) {
console.error('头像上传失败:', error);
console.error("头像上传失败:", error);
// 如果上传失败,返回默认头像
return require('../static/userInfo/default_avatar.svg');
return require("../static/userInfo/default_avatar.svg");
}
}
// 解析用户手机号
static async parse_phone(phone_code: string): Promise<string> {
try {
const response = await httpService.post<{ phone: string }>(API_CONFIG.USER.PARSE_PHONE, { phone_code }, {
showLoading: true,
loadingText: '获取手机号中...'
});
const response = await httpService.post<{ phone: string }>(
API_CONFIG.USER.PARSE_PHONE,
{ phone_code },
{
showLoading: true,
loadingText: "获取手机号中...",
}
);
if (response.code === 0) {
return response.data.phone || '';
return response.data.phone || "";
} else {
throw new Error(response.message || '获取手机号失败');
throw new Error(response.message || "获取手机号失败");
}
} catch (error) {
console.error('获取手机号失败:', error);
return '';
console.error("获取手机号失败:", error);
return "";
}
}
@@ -529,10 +621,10 @@ export class UserService {
if (code === 0) {
return formatOptions(data || []);
} else {
throw new Error(message || '获取职业树失败');
throw new Error(message || "获取职业树失败");
}
} catch (error) {
console.error('获取职业树失败:', error);
console.error("获取职业树失败:", error);
return [];
}
}
@@ -545,10 +637,10 @@ export class UserService {
if (code === 0) {
return formatOptions(data || []);
} else {
throw new Error(message || '获取城市树失败');
throw new Error(message || "获取城市树失败");
}
} catch (error) {
console.error('获取职业树失败:', error);
console.error("获取职业树失败:", error);
return [];
}
}
@@ -566,10 +658,10 @@ export class UserService {
url: "/login_pages/index/index",
});
} else {
throw new Error(message || '注销账户失败');
throw new Error(message || "注销账户失败");
}
} catch (error) {
console.error('注销账户失败:', error);
console.error("注销账户失败:", error);
}
}
}
@@ -577,12 +669,14 @@ export class UserService {
// 从 loginService 移过来的用户相关方法
// 获取用户详细信息
export const fetchUserProfile = async (): Promise<ApiResponse<UserInfoType>> => {
export const fetchUserProfile = async (): Promise<
ApiResponse<UserInfoType>
> => {
try {
const response = await httpService.post('user/detail');
const response = await httpService.post("user/detail");
return response;
} catch (error) {
console.error('获取用户信息失败:', error);
console.error("获取用户信息失败:", error);
throw error;
}
};
@@ -590,24 +684,27 @@ export const fetchUserProfile = async (): Promise<ApiResponse<UserInfoType>> =>
// 更新用户信息
export const updateUserProfile = async (payload: Partial<UserInfoType>) => {
try {
const response = await httpService.post('/user/update', payload);
const response = await httpService.post("/user/update", payload);
return response;
} catch (error) {
console.error('更新用户信息失败:', error);
console.error("更新用户信息失败:", error);
throw error;
}
};
// 更新用户坐标位置
export const updateUserLocation = async (latitude: number, longitude: number) => {
export const updateUserLocation = async (
latitude: number,
longitude: number
) => {
try {
const response = await httpService.post('/user/update_location', {
const response = await httpService.post("/user/update_location", {
latitude,
longitude,
});
return response;
} catch (error) {
console.error('更新用户坐标位置失败:', error);
console.error("更新用户坐标位置失败:", error);
throw error;
}
};
@@ -615,9 +712,9 @@ export const updateUserLocation = async (latitude: number, longitude: number) =>
// 获取用户信息(从本地存储)
export const get_user_info = (): any | null => {
try {
let userinfo = Taro.getStorageSync('user_info')
let userinfo = Taro.getStorageSync("user_info");
if (userinfo) {
return JSON.parse(userinfo)
return JSON.parse(userinfo);
}
return null;
} catch (error) {
@@ -632,25 +729,25 @@ export const handleCustomerService = async (): Promise<void> => {
const config = getCurrentConfig;
const { customerService } = config;
console.log('打开客服中心,配置信息:', customerService);
console.log("打开客服中心,配置信息:", customerService);
// 使用微信官方客服能力
await Taro.openCustomerServiceChat({
extInfo: {
url: customerService.serviceUrl
url: customerService.serviceUrl,
},
corpId: customerService.corpId,
success: (res) => {
console.log('打开客服成功:', res);
console.log("打开客服成功:", res);
},
fail: (error) => {
console.error('打开客服失败:', error);
console.error("打开客服失败:", error);
// 如果官方客服不可用,显示备用联系方式
showCustomerServiceFallback(customerService);
}
},
});
} catch (error) {
console.error('客服功能异常:', error);
console.error("客服功能异常:", error);
// 备用方案:显示联系信息
showCustomerServiceFallback();
}
@@ -658,14 +755,14 @@ export const handleCustomerService = async (): Promise<void> => {
// 客服备用方案
const showCustomerServiceFallback = (customerInfo?: any) => {
const options = ['拨打客服电话', '复制邮箱地址'];
const options = ["拨打客服电话", "复制邮箱地址"];
// 如果没有客服信息,只显示通用提示
if (!customerInfo?.phoneNumber && !customerInfo?.email) {
Taro.showModal({
title: '联系客服',
content: '如需帮助,请通过其他方式联系我们',
showCancel: false
title: "联系客服",
content: "如需帮助,请通过其他方式联系我们",
showCancel: false,
});
return;
}
@@ -677,33 +774,33 @@ const showCustomerServiceFallback = (customerInfo?: any) => {
// 拨打客服电话
try {
await Taro.makePhoneCall({
phoneNumber: customerInfo.phoneNumber
phoneNumber: customerInfo.phoneNumber,
});
} catch (error) {
console.error('拨打电话失败:', error);
console.error("拨打电话失败:", error);
Taro.showToast({
title: '拨打电话失败',
icon: 'none'
title: "拨打电话失败",
icon: "none",
});
}
} else if (res.tapIndex === 1 && customerInfo?.email) {
// 复制邮箱地址
try {
await Taro.setClipboardData({
data: customerInfo.email
data: customerInfo.email,
});
Taro.showToast({
title: '邮箱地址已复制',
icon: 'success'
title: "邮箱地址已复制",
icon: "success",
});
} catch (error) {
console.error('复制邮箱失败:', error);
console.error("复制邮箱失败:", error);
Taro.showToast({
title: '复制失败',
icon: 'none'
title: "复制失败",
icon: "none",
});
}
}
}
},
});
};