diff --git a/pages/champion/champion.vue b/pages/champion/champion.vue index 76094fd..fd05ef9 100644 --- a/pages/champion/champion.vue +++ b/pages/champion/champion.vue @@ -22,6 +22,12 @@ class="tab-item" :class="{ active: activeTab === 'practice' }" @click="switchTab('practice')"> + 场景 + + 陪练 + + 陪练 + + 编辑 @@ -279,6 +289,106 @@ + + + + 共{{ trainingTotal }}条 + + + + + + + 刷新 + + + + + + + + {{ (item.title || '陪').charAt(0) }} + + {{ item.title || '未命名陪练' }} + + + + + + + + + + 开始 + + + + + 陪练场景: {{ item.scenario }} + + + + + 参与人: {{ item.participantName }} + + + 电话: {{ item.participantPhone }} + + + + + 创建时间: {{ formatDateTime(item.createTime) }} + + + 结束时间: {{ formatDateTime(item.endTime) }} + + + + 暂无陪练记录 + + + 正在加载更多... + + + + + + {{ contentPopupText }} + + + + + + + 生成陪练 + + + + + + + + 陪练标题 + + + + 陪练场景 + + + + 参与人姓名 + + + + 参与人电话 + + + + + + + + 取消 + + + + 生成 + + + + + + + + + + 陪练详情 + + + + + + + + + + {{ (item.question || '题').charAt(0) }} + + {{ item.question || '未命名题目' }} + + + + + 答案: {{ item.answer }} + + + + 创建时间: {{ formatDateTime(item.createTime) }} + + + + 暂无详情记录 + + + 正在加载更多... + + + @@ -650,13 +870,52 @@ // 陪练操作菜单 selectedPracticeItem: null, showPracticeActionMenu: false, + // 陪练弹出框 + showPracticeTrainingPopup: false, + practiceTrainingForm: { + scenarioId: '', + title: '', + scenario: '', + participantName: '', + participantPhone: '' + }, + // 陪练列表相关数据 + trainingList: [], + trainingLoading: false, + trainingTotal: 0, + trainingPage: { + current: 1, + size: 10 + }, + trainingQuery: { + title: '', + participantName: '', + participantPhone: '' + }, // 内容详情弹出框 showContentPopup: false, contentPopupTitle: '', - contentPopupText: '' + contentPopupText: '', + // 陪练操作菜单 + selectedTrainingItem: null, + showTrainingActionMenu: false, + // 陪练详情列表弹出框 + showTrainingItemListPopup: false, + trainingItemList: [], + trainingItemLoading: false, + trainingItemTotal: 0, + trainingItemPage: { + current: 1, + size: 10 + }, + currentTrainingParentId: '' } }, onLoad() { + // 页面加载时,如果默认是场景tab页,则调用接口填充数据 + if (this.activeTab === 'practice') { + this.fetchPracticeList(); + } }, methods: { goBack() { @@ -668,8 +927,11 @@ // 当进入素材页面时,请求接口填充数据 this.fetchMaterialList(); } else if (tab === 'practice') { - // 当进入陪练页面时,请求接口填充数据 + // 当进入场景页面时,请求接口填充数据 this.fetchPracticeList(); + } else if (tab === 'training') { + // 当进入陪练页面时,请求接口填充数据 + this.fetchTrainingList(); } }, // 素材相关方法 @@ -1285,6 +1547,136 @@ this.showPracticeActionMenu = false; this.selectedPracticeItem = null; }, + handleStartPractice(item) { + this.closePracticeActionMenu(); + + // 获取当前登录用户信息 + let participantName = ''; + let participantPhone = ''; + try { + const loginResponse = uni.getStorageSync('backend-login-response') || {}; + const phone = loginResponse.phone || ''; + const userName = loginResponse.userName || ''; + + // 参与人电话默认为当前登录人的电话 + participantPhone = phone; + + // 参与人姓名默认为当前登录人的登录手机号或者登录账号(优先手机号) + participantName = phone || userName; + } catch (e) { + console.error('获取登录用户信息失败:', e); + } + + // 填充陪练表单 + this.practiceTrainingForm = { + scenarioId: item.id || '', + title: item.title || '', + scenario: item.content || item.detail || '', + participantName: participantName, + participantPhone: participantPhone + }; + this.showPracticeTrainingPopup = true; + }, + closePracticeTrainingPopup() { + this.showPracticeTrainingPopup = false; + this.practiceTrainingForm = { + scenarioId: '', + title: '', + scenario: '', + participantName: '', + participantPhone: '' + }; + }, + async submitPracticeTraining() { + // 表单验证 + if (!this.practiceTrainingForm.title || !this.practiceTrainingForm.title.trim()) { + uni.showToast({ + title: "请输入陪练标题", + icon: "none" + }); + return; + } + if (!this.practiceTrainingForm.participantName || !this.practiceTrainingForm.participantName.trim()) { + uni.showToast({ + title: "请输入参与人姓名", + icon: "none" + }); + return; + } + if (!this.practiceTrainingForm.participantPhone || !this.practiceTrainingForm.participantPhone.trim()) { + uni.showToast({ + title: "请输入参与人电话", + icon: "none" + }); + return; + } + + try { + uni.showLoading({ + title: "创建中..." + }); + + // 获取租户ID + const tenantId = getTenantId(); + + const payload = { + scenarioId: this.practiceTrainingForm.scenarioId || '', + title: this.practiceTrainingForm.title?.trim() || '', + scenario: this.practiceTrainingForm.scenario?.trim() || '', + participantName: this.practiceTrainingForm.participantName.trim(), + participantPhone: this.practiceTrainingForm.participantPhone.trim() + }; + + // 添加租户ID到payload + if (tenantId) { + payload.tenantId = tenantId; + } + + const headers = { + "Content-Type": "application/json" + }; + + // 添加租户ID到header + if (tenantId) { + headers['X-Tenant-Id'] = tenantId; + } + + const res = await uni.request({ + url: getApiUrl('/api/trainingMain/add'), + method: 'POST', + data: payload, + header: headers, + timeout: 15000 + }); + + uni.hideLoading(); + + if (res.statusCode === 200 && res.data && (res.data.success || res.data.code === 200)) { + uni.showToast({ + title: res.data?.message || "创建成功", + icon: "success" + }); + // 关闭弹出框 + this.closePracticeTrainingPopup(); + // 跳转到陪练页面并刷新列表 + this.switchTab('training'); + this.trainingPage.current = 1; + this.fetchTrainingList({ force: true }); + } else { + uni.showToast({ + title: res.data?.message || "创建失败", + icon: "none" + }); + } + } catch (error) { + uni.hideLoading(); + console.error("创建陪练失败:", error); + uni.showToast({ + title: error?.message || "创建失败,请重试", + icon: "none" + }); + } + }, handleEditPractice(item) { this.closePracticeActionMenu(); // 填充编辑表单 @@ -1569,6 +1961,280 @@ icon: "none" }); } + }, + // 陪练列表相关方法 + onTrainingSearch() { + if (this.activeTab !== 'training') { + this.activeTab = 'training'; + } + this.trainingPage.current = 1; + this.fetchTrainingList({ force: true }); + }, + onTrainingRefresh() { + this.trainingPage.current = 1; + this.fetchTrainingList({ force: true }); + }, + onTrainingReachBottom() { + // 已在加载中或全部加载完成则不再触发 + if (this.trainingLoading) return; + if (this.trainingList.length >= this.trainingTotal) return; + this.trainingPage.current += 1; + this.fetchTrainingList(); + }, + async fetchTrainingList({ force = false } = {}) { + if (this.trainingLoading && !force) { + return; + } + this.trainingLoading = true; + try { + // 构建查询参数 + const queryParams = { + current: this.trainingPage.current, + size: this.trainingPage.size + }; + + const trimmedTitle = this.trainingQuery?.title?.trim(); + const trimmedParticipantName = this.trainingQuery?.participantName?.trim(); + const trimmedParticipantPhone = this.trainingQuery?.participantPhone?.trim(); + + if (trimmedTitle) { + queryParams.title = trimmedTitle; + } + if (trimmedParticipantName) { + queryParams.participantName = trimmedParticipantName; + } + if (trimmedParticipantPhone) { + queryParams.participantPhone = trimmedParticipantPhone; + } + + // 将参数转换为 URL 查询字符串 + const queryString = Object.keys(queryParams) + .map(key => `${key}=${encodeURIComponent(queryParams[key])}`) + .join('&'); + const url = `${getApiUrl('/api/trainingMain/list')}?${queryString}`; + + // 获取租户ID + const tenantId = getTenantId(); + const headers = {}; + if (tenantId) { + headers['X-Tenant-Id'] = tenantId; + // 同时添加到查询参数中 + queryParams.tenantId = tenantId; + } + + // 重新构建查询字符串(包含tenantId) + const finalQueryString = Object.keys(queryParams) + .map(key => `${key}=${encodeURIComponent(queryParams[key])}`) + .join('&'); + const finalUrl = `${getApiUrl('/api/trainingMain/list')}?${finalQueryString}`; + + const res = await uni.request({ + url: finalUrl, + method: 'POST', + header: headers, + timeout: 10000 + }); + + if (res.statusCode === 200 && res.data && res.data.success) { + const records = Array.isArray(res.data.data) ? res.data.data : []; + // 第一页或强制刷新时重置列表,否则追加 + if (this.trainingPage.current === 1 || force) { + this.trainingList = records; + } else { + this.trainingList = this.trainingList.concat(records); + } + this.trainingTotal = Number(res.data.total) || 0; + } else { + this.trainingList = []; + this.trainingTotal = 0; + uni.showToast({ + title: res.data?.message || '获取陪练列表失败', + icon: 'none' + }); + } + } catch (error) { + console.error('获取陪练列表失败:', error); + uni.showToast({ + title: '获取陪练列表失败,请稍后重试', + icon: 'none' + }); + } finally { + this.trainingLoading = false; + } + }, + // 陪练操作菜单相关方法 + onTrainingActionBtnClick(item) { + // 如果已经选中当前项,则关闭菜单 + if (this.selectedTrainingItem && this.selectedTrainingItem.id === item.id && this.showTrainingActionMenu) { + this.closeTrainingActionMenu(); + return; + } + + // 显示菜单 + this.selectedTrainingItem = item; + this.showTrainingActionMenu = true; + }, + closeTrainingActionMenu() { + this.showTrainingActionMenu = false; + this.selectedTrainingItem = null; + }, + async startTraining(item) { + this.closeTrainingActionMenu(); + // 打开详情列表弹窗 + this.currentTrainingParentId = item.id || ''; + this.trainingItemList = []; + this.showTrainingItemListPopup = true; + // 加载详情列表(调用listAll接口) + await this.fetchTrainingItemListAll(item.id || ''); + }, + closeTrainingItemListPopup() { + this.showTrainingItemListPopup = false; + this.currentTrainingParentId = ''; + this.trainingItemPage.current = 1; + this.trainingItemList = []; + }, + onTrainingItemListReachBottom() { + // 已在加载中或全部加载完成则不再触发 + if (this.trainingItemLoading) return; + if (this.trainingItemList.length >= this.trainingItemTotal) return; + this.trainingItemPage.current += 1; + this.fetchTrainingItemList(); + }, + async fetchTrainingItemListAll(parentId) { + if (!parentId) { + uni.showToast({ + title: '缺少父ID参数', + icon: 'none' + }); + return; + } + + this.trainingItemLoading = true; + try { + // 获取租户ID + const tenantId = getTenantId(); + + // 构建查询参数 + const queryParams = { + parentId: parentId + }; + + if (tenantId) { + queryParams.tenantId = tenantId; + } + + // 将参数转换为 URL 查询字符串 + const queryString = Object.keys(queryParams) + .filter(key => queryParams[key] !== null && queryParams[key] !== undefined && queryParams[key] !== '') + .map(key => `${encodeURIComponent(key)}=${encodeURIComponent(queryParams[key])}`) + .join('&'); + const url = `${getApiUrl('/api/trainingItem/listAll')}?${queryString}`; + + // 构建请求头 + const headers = { + "Content-Type": "application/json" + }; + if (tenantId) { + headers['X-Tenant-Id'] = tenantId; + } + + const res = await uni.request({ + url: url, + method: 'POST', + header: headers, + timeout: 30000 + }); + + if (res.statusCode === 200 && res.data && res.data.success) { + const records = Array.isArray(res.data.data) ? res.data.data : []; + this.trainingItemList = records; + this.trainingItemTotal = Number(res.data.count) || records.length; + } else { + this.trainingItemList = []; + this.trainingItemTotal = 0; + uni.showToast({ + title: res.data?.message || '获取陪练详情列表失败', + icon: 'none' + }); + } + } catch (error) { + console.error('获取陪练详情列表失败:', error); + uni.showToast({ + title: '获取陪练详情列表失败,请稍后重试', + icon: 'none' + }); + } finally { + this.trainingItemLoading = false; + } + }, + async fetchTrainingItemList({ force = false } = {}) { + if (this.trainingItemLoading && !force) { + return; + } + if (!this.currentTrainingParentId) { + return; + } + this.trainingItemLoading = true; + try { + // 构建查询参数 + const queryParams = { + current: this.trainingItemPage.current, + size: this.trainingItemPage.size, + parentId: this.currentTrainingParentId + }; + + // 获取租户ID + const tenantId = getTenantId(); + if (tenantId) { + queryParams.tenantId = tenantId; + } + + // 将参数转换为 URL 查询字符串 + const queryString = Object.keys(queryParams) + .filter(key => queryParams[key] !== null && queryParams[key] !== undefined && queryParams[key] !== '') + .map(key => `${encodeURIComponent(key)}=${encodeURIComponent(queryParams[key])}`) + .join('&'); + const url = `${getApiUrl('/api/trainingItem/list')}?${queryString}`; + + // 构建请求头 + const headers = {}; + if (tenantId) { + headers['X-Tenant-Id'] = tenantId; + } + + const res = await uni.request({ + url: url, + method: 'GET', + header: headers, + timeout: 30000 + }); + + if (res.statusCode === 200 && res.data && res.data.success) { + const records = Array.isArray(res.data.data) ? res.data.data : []; + // 第一页或强制刷新时重置列表,否则追加 + if (this.trainingItemPage.current === 1 || force) { + this.trainingItemList = records; + } else { + this.trainingItemList = this.trainingItemList.concat(records); + } + this.trainingItemTotal = Number(res.data.total) || 0; + } else { + this.trainingItemList = []; + this.trainingItemTotal = 0; + uni.showToast({ + title: res.data?.message || '获取陪练详情列表失败', + icon: 'none' + }); + } + } catch (error) { + console.error('获取陪练详情列表失败:', error); + uni.showToast({ + title: '获取陪练详情列表失败,请稍后重试', + icon: 'none' + }); + } finally { + this.trainingItemLoading = false; + } } } } @@ -1652,7 +2318,8 @@ /* 素材内容区域和陪练内容区域使用相同定位 */ .material-content, - .practice-content { + .practice-content, + .training-content { position: absolute; top: 160rpx; /* 导航栏(88rpx) + tab页(72rpx) = 160rpx */ left: 0; @@ -1769,7 +2436,8 @@ overflow: visible; } - .material-card-item { + .material-card-item, + .training-card-item { padding-left: 32rpx; padding-right: 32rpx; padding-top: 32rpx; @@ -2302,5 +2970,90 @@ white-space: pre-wrap; word-wrap: break-word; } + + /* 陪练操作菜单样式 */ + .training-card-item { + position: relative; + } + + .training-card-action-btn { + width: 60rpx; + height: 60rpx; + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + margin-left: auto; + margin-right: 0; + margin-top: 0; + margin-bottom: 0; + flex-shrink: 0; + flex-grow: 0; + position: relative; + padding: 0; + } + + .training-card-action-btn uni-icons { + display: block; + margin: 0; + padding: 0; + line-height: 1; + } + + .training-card-action-btn:active { + opacity: 0.7; + } + + .training-action-menu { + position: absolute; + top: 60rpx; + right: 32rpx; + width: 160rpx; + background-color: #FFFFFF; + border-radius: 12rpx; + box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.15); + z-index: 100; + overflow: hidden; + margin-right: 0; + } + + .training-action-menu-item { + padding: 24rpx 32rpx; + font-size: 28rpx; + color: #333; + text-align: center; + background-color: #FFFFFF; + } + + .training-action-menu-item:active { + background-color: #F5F5F5; + } + + .training-action-menu-mask { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: transparent; + z-index: 99; + } + + /* 陪练详情列表弹窗样式 */ + .training-item-list-popup { + max-height: 80vh; + } + + .training-item-list-popup .popup-content { + padding: 24rpx; + } + + .training-item-card { + margin-bottom: 24rpx; + } + + .training-item-card:last-child { + margin-bottom: 0; + } diff --git a/pages/reception/reception.vue b/pages/reception/reception.vue index b2aeb33..c92341f 100644 --- a/pages/reception/reception.vue +++ b/pages/reception/reception.vue @@ -596,14 +596,33 @@ import { getApiUrl } from "@/common/config.js"; const baseUrl = getApiUrl('/api/audioManagement/list'); const url = queryString ? `${baseUrl}?${queryString}` : baseUrl; + // 获取认证信息 + let tenantId = ''; + let token = ''; + try { + tenantId = uni.getStorageSync('backend-tenant-id') || ''; + token = uni.getStorageSync('backend-token') || ''; + } catch (e) { + console.error('获取认证信息失败:', e); + } + + // 构建请求头 + const headers = { + 'Content-Type': 'application/json' + }; + if (token) { + headers['Authorization'] = `Bearer ${token}`; + } + if (tenantId) { + headers['X-Tenant-Id'] = tenantId; + } + const res = await uni.request({ url, method: 'POST', data: {}, // POST 请求体为空,参数都在 URL 查询字符串中 - header: { - 'Content-Type': 'application/json' - }, - timeout: 10000 + header: headers, + timeout: 30000 // 增加超时时间到30秒 }); if (res.statusCode === 200 && res.data && res.data.success) { @@ -637,9 +656,19 @@ import { getApiUrl } from "@/common/config.js"; } } catch (error) { console.error('获取服务中列表失败:', error); + // 根据错误类型提供更详细的错误信息 + let errorMessage = '获取服务状态失败,请稍后重试'; + if (error.errMsg) { + if (error.errMsg.includes('timeout')) { + errorMessage = '请求超时,请检查网络连接后重试'; + } else if (error.errMsg.includes('fail')) { + errorMessage = '网络请求失败,请检查网络连接'; + } + } uni.showToast({ - title: '获取服务状态失败,请稍后重试', - icon: 'none' + title: errorMessage, + icon: 'none', + duration: 3000 }); } finally { this.serviceStatusLoading = false; @@ -728,10 +757,31 @@ import { getApiUrl } from "@/common/config.js"; this.isFetchingContact = true; // 统一使用 getApiUrl,根据 env.js 配置自动切换环境 const url = `${getApiUrl('/api/customerManagement/getByContact')}?contact=${encodeURIComponent(contact)}`; + + // 获取认证信息 + let tenantId = ''; + let token = ''; + try { + tenantId = uni.getStorageSync('backend-tenant-id') || ''; + token = uni.getStorageSync('backend-token') || ''; + } catch (e) { + console.error('获取认证信息失败:', e); + } + + // 构建请求头 + const headers = {}; + if (token) { + headers['Authorization'] = `Bearer ${token}`; + } + if (tenantId) { + headers['X-Tenant-Id'] = tenantId; + } + const res = await uni.request({ url: url, method: 'GET', - timeout: 8000 + header: headers, + timeout: 30000 // 增加超时时间到30秒 }); const list = res.data?.data; if (res.statusCode === 200 && res.data?.success && Array.isArray(list) && list.length) { @@ -857,11 +907,33 @@ import { getApiUrl } from "@/common/config.js"; title: "保存中..." }); + // 获取认证信息 + let tenantId = ''; + let token = ''; + try { + tenantId = uni.getStorageSync('backend-tenant-id') || ''; + token = uni.getStorageSync('backend-token') || ''; + } catch (e) { + console.error('获取认证信息失败:', e); + } + + // 构建请求头 + const headers = { + 'Content-Type': 'application/json' + }; + if (token) { + headers['Authorization'] = `Bearer ${token}`; + } + if (tenantId) { + headers['X-Tenant-Id'] = tenantId; + } + const res = await uni.request({ url: getApiUrl('/api/customerManagement/add'), method: "POST", data: params, - timeout: 10000 + header: headers, + timeout: 30000 // 增加超时时间到30秒 }); uni.hideLoading(); @@ -927,14 +999,34 @@ import { getApiUrl } from "@/common/config.js"; } // 后端接口不支持 GET,改为 POST 传参 const url = getApiUrl('/api/industryTags/list'); + + // 获取认证信息 + let tenantId = ''; + let token = ''; + try { + tenantId = uni.getStorageSync('backend-tenant-id') || ''; + token = uni.getStorageSync('backend-token') || ''; + } catch (e) { + console.error('获取认证信息失败:', e); + } + + // 构建请求头 + const headers = { + 'Content-Type': 'application/json' + }; + if (token) { + headers['Authorization'] = `Bearer ${token}`; + } + if (tenantId) { + headers['X-Tenant-Id'] = tenantId; + } + const res = await uni.request({ url, method: 'POST', data: queryParams, - header: { - 'Content-Type': 'application/json' - }, - timeout: 10000 + header: headers, + timeout: 30000 // 增加超时时间到30秒 }); if (res.statusCode === 200 && res.data && res.data.success) { const records = Array.isArray(res.data.data) ? res.data.data : []; @@ -955,9 +1047,19 @@ import { getApiUrl } from "@/common/config.js"; } } catch (error) { console.error('获取标签列表失败:', error); + // 根据错误类型提供更详细的错误信息 + let errorMessage = '获取标签列表失败,请稍后重试'; + if (error.errMsg) { + if (error.errMsg.includes('timeout')) { + errorMessage = '请求超时,请检查网络连接后重试'; + } else if (error.errMsg.includes('fail')) { + errorMessage = '网络请求失败,请检查网络连接'; + } + } uni.showToast({ - title: '获取标签列表失败,请稍后重试', - icon: 'none' + title: errorMessage, + icon: 'none', + duration: 3000 }); } finally { this.tagLoading = false; @@ -1030,10 +1132,31 @@ import { getApiUrl } from "@/common/config.js"; }); const deleteUrl = getApiUrl(`/api/industryTags/delete/${tagId}`); + + // 获取认证信息 + let tenantId = ''; + let token = ''; + try { + tenantId = uni.getStorageSync('backend-tenant-id') || ''; + token = uni.getStorageSync('backend-token') || ''; + } catch (e) { + console.error('获取认证信息失败:', e); + } + + // 构建请求头 + const headers = {}; + if (token) { + headers['Authorization'] = `Bearer ${token}`; + } + if (tenantId) { + headers['X-Tenant-Id'] = tenantId; + } + const deleteRes = await uni.request({ url: deleteUrl, method: 'DELETE', - timeout: 10000 + header: headers, + timeout: 30000 // 增加超时时间到30秒 }); uni.hideLoading(); @@ -1055,9 +1178,19 @@ import { getApiUrl } from "@/common/config.js"; } catch (error) { uni.hideLoading(); console.error('删除标签失败:', error); + // 根据错误类型提供更详细的错误信息 + let errorMessage = '删除失败,请重试'; + if (error.errMsg) { + if (error.errMsg.includes('timeout')) { + errorMessage = '请求超时,请检查网络连接后重试'; + } else if (error.errMsg.includes('fail')) { + errorMessage = '网络请求失败,请检查网络连接'; + } + } uni.showToast({ - title: '删除失败,请重试', - icon: 'none' + title: errorMessage, + icon: 'none', + duration: 3000 }); } } @@ -1126,14 +1259,33 @@ import { getApiUrl } from "@/common/config.js"; const method = this.tagViewMode === 'edit' ? 'PUT' : 'POST'; + // 获取认证信息 + let tenantId = ''; + let token = ''; + try { + tenantId = uni.getStorageSync('backend-tenant-id') || ''; + token = uni.getStorageSync('backend-token') || ''; + } catch (e) { + console.error('获取认证信息失败:', e); + } + + // 构建请求头 + const headers = { + "Content-Type": "application/json" + }; + if (token) { + headers['Authorization'] = `Bearer ${token}`; + } + if (tenantId) { + headers['X-Tenant-Id'] = tenantId; + } + const res = await uni.request({ url: url, method: method, data: payload, - header: { - "Content-Type": "application/json" - }, - timeout: 10000 + header: headers, + timeout: 30000 // 增加超时时间到30秒 }); const { statusCode, data } = res; @@ -1151,9 +1303,19 @@ import { getApiUrl } from "@/common/config.js"; } } catch (error) { console.error("保存标签失败:", error); + // 根据错误类型提供更详细的错误信息 + let errorMessage = error?.message || (this.tagViewMode === 'edit' ? "更新失败,请重试" : "保存失败,请重试"); + if (error.errMsg) { + if (error.errMsg.includes('timeout')) { + errorMessage = '请求超时,请检查网络连接后重试'; + } else if (error.errMsg.includes('fail')) { + errorMessage = '网络请求失败,请检查网络连接'; + } + } uni.showToast({ - title: error?.message || (this.tagViewMode === 'edit' ? "更新失败,请重试" : "保存失败,请重试"), - icon: "none" + title: errorMessage, + icon: "none", + duration: 3000 }); } finally { uni.hideLoading();