From 52bdaaf789c2632115918e397ebb2d2257efc434 Mon Sep 17 00:00:00 2001 From: WindowBird <13870814+windows-bird@user.noreply.gitee.com> Date: Wed, 20 Aug 2025 11:45:42 +0800 Subject: [PATCH] =?UTF-8?q?=E8=AE=BE=E7=BD=AE=E9=A1=B5=E9=9D=A2=E4=B8=8A?= =?UTF-8?q?=E4=BC=A0=E5=A4=B4=E5=83=8F=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/user/user.js | 28 ++++ config/dev.js | 4 +- debug-upload.js | 297 +++++++++++++++++++++++++++++++++++ pages/set/set.vue | 114 +++++++++++++- utils/request.js | 388 +++++++++++++++++++++++++++++++++++++++++++++- 5 files changed, 815 insertions(+), 16 deletions(-) create mode 100644 debug-upload.js diff --git a/api/user/user.js b/api/user/user.js index b35c2de..029d9b9 100644 --- a/api/user/user.js +++ b/api/user/user.js @@ -1,5 +1,6 @@ import request from '@/utils/request' import { mockUserInfo, mockFinancialData, mockAgentStats, mockAgentList, mockWithdrawInfo, mockBanks, createMockResponse } from './mockData.js' +import { uploadFile, uploadFileWithPut } from '@/utils/request.js' /** * 获取用户信息 @@ -177,4 +178,31 @@ export function submitWithdraw(data) { console.warn('提现申请API调用失败:', error) throw error }) +} + +/** + * 上传头像 + * @param {string} filePath - 文件路径 + * @returns {Promise} 返回上传结果 + */ +export function uploadAvatar(filePath) { + // 由于服务端只支持PUT方法,我们直接使用PUT方法 + // 但需要修复multipart格式问题 + return uploadFileWithPut('/app/user/avatar', filePath, 'avatarfile', {}, { + timeout: 60000 + }).then(data => { + // 上传成功后更新本地存储 + const userInfo = uni.getStorageSync('userInfo') || {} + userInfo.avatar = data.data?.avatar || data.data + uni.setStorageSync('userInfo', userInfo) + + // 通知其他页面更新头像 + uni.$emit('avatarUpdated', userInfo.avatar) + + console.log('头像上传成功,已更新本地存储:', userInfo.avatar) + return data + }).catch(error => { + console.error('头像上传失败:', error) + throw error + }) } \ No newline at end of file diff --git a/config/dev.js b/config/dev.js index 19b26ef..3712489 100644 --- a/config/dev.js +++ b/config/dev.js @@ -1,9 +1,7 @@ // 开发环境配置 export const DEV_CONFIG = { // 临时token,用于开发测试 - TEMP_TOKEN: - '\n' + - 'eyJhbGciOiJIUzUxMiJ9.eyJsb2dpbl91c2VyX2tleSI6IjY2M2UzOWVkLTg4N2MtNGUxOS1iZDBiLWFmZTY1ZmI3Mjk2YiJ9.nMIcrWJK3l5itjQH-okwKL2X4Tresr_sKmgMQ66nHsjYGHK9Xyz5YHO2oDeF-sPt1BxHbz4fyBXcSWhr1HwWTQ', + TEMP_TOKEN: 'eyJhbGciOiJIUzUxMiJ9.eyJsb2dpbl91c2VyX2tleSI6IjY2M2UzOWVkLTg4N2MtNGUxOS1iZDBiLWFmZTY1ZmI3Mjk2YiJ9.nMIcrWJK3l5itjQH-okwKL2X4Tresr_sKmgMQ66nHsjYGHK9Xyz5YHO2oDeF-sPt1BxHbz4fyBXcSWhr1HwWTQ', // 是否使用临时token USE_TEMP_TOKEN: true, diff --git a/debug-upload.js b/debug-upload.js new file mode 100644 index 0000000..4e0dd31 --- /dev/null +++ b/debug-upload.js @@ -0,0 +1,297 @@ +/** + * 头像上传调试脚本 + * 用于分析和解决头像上传问题 + */ + +// 调试配置 +const DEBUG_CONFIG = { + baseUrl: 'http://192.168.2.143:4601', + uploadUrl: '/app/user/avatar', + timeout: 60000 +} + +// 调试工具类 +class UploadDebugger { + constructor() { + this.logs = [] + this.testResults = [] + } + + // 添加日志 + addLog(type, message, data = null) { + const log = { + type, + message, + data, + timestamp: new Date().toISOString() + } + this.logs.push(log) + console.log(`[${log.timestamp}] ${type.toUpperCase()}: ${message}`, data || '') + } + + // 检查token + checkToken() { + try { + const token = uni.getStorageSync('token') + const result = { + exists: !!token, + length: token ? token.length : 0, + preview: token ? token.substring(0, 20) + '...' : 'none', + valid: this.validateToken(token) + } + + this.addLog('info', 'Token检查完成', result) + return result + } catch (error) { + this.addLog('error', 'Token检查失败', error) + return { exists: false, error: error.message } + } + } + + // 验证token格式 + validateToken(token) { + if (!token) return false + + // 检查是否是JWT格式 + const parts = token.split('.') + if (parts.length === 3) { + try { + // 尝试解码payload部分 + const payload = JSON.parse(atob(parts[1])) + return payload && payload.exp && payload.exp > Date.now() / 1000 + } catch (e) { + return false + } + } + + return true // 如果不是JWT格式,假设是其他格式的token + } + + // 检查网络连接 + checkNetwork() { + return new Promise((resolve) => { + uni.getNetworkType({ + success: (res) => { + this.addLog('info', '网络状态检查', res) + resolve(res) + }, + fail: (err) => { + this.addLog('error', '网络状态检查失败', err) + resolve({ networkType: 'unknown', error: err }) + } + }) + }) + } + + // 检查服务器连接 + checkServerConnection() { + return new Promise((resolve) => { + uni.request({ + url: DEBUG_CONFIG.baseUrl + '/health', // 假设有健康检查接口 + method: 'GET', + timeout: 5000, + success: (res) => { + this.addLog('info', '服务器连接检查成功', res) + resolve({ connected: true, status: res.statusCode }) + }, + fail: (err) => { + this.addLog('error', '服务器连接检查失败', err) + resolve({ connected: false, error: err }) + } + }) + }) + } + + // 测试文件上传 + async testFileUpload(filePath) { + this.addLog('info', '开始文件上传测试', { filePath }) + + try { + // 检查文件信息 + const fileInfo = await this.getFileInfo(filePath) + this.addLog('info', '文件信息', fileInfo) + + // 检查文件大小 + if (fileInfo.size > 10 * 1024 * 1024) { // 10MB + this.addLog('warn', '文件过大,可能影响上传', { size: fileInfo.size }) + } + + // 执行上传 + const result = await this.performUpload(filePath) + this.addLog('info', '上传测试完成', result) + + return result + } catch (error) { + this.addLog('error', '上传测试失败', error) + throw error + } + } + + // 获取文件信息 + getFileInfo(filePath) { + return new Promise((resolve, reject) => { + uni.getFileInfo({ + filePath: filePath, + success: resolve, + fail: reject + }) + }) + } + + // 执行上传 + performUpload(filePath) { + return new Promise((resolve, reject) => { + const token = uni.getStorageSync('token') + + // 构建请求头 + let authorization = token + // #ifdef H5 + authorization = token ? `Bearer ${token}` : '' + // #endif + + const header = { + Authorization: authorization + } + + this.addLog('info', '开始上传请求', { + url: DEBUG_CONFIG.baseUrl + DEBUG_CONFIG.uploadUrl, + header: header, + filePath: filePath + }) + + uni.uploadFile({ + url: DEBUG_CONFIG.baseUrl + DEBUG_CONFIG.uploadUrl, + filePath: filePath, + name: 'avatarfile', + header: header, + timeout: DEBUG_CONFIG.timeout, + success: (res) => { + this.addLog('info', '上传响应', { + statusCode: res.statusCode, + header: res.header, + data: res.data + }) + + try { + const data = JSON.parse(res.data) + if (res.statusCode === 200 && data.code === 200) { + resolve({ success: true, data: data }) + } else { + reject({ success: false, error: data.msg || '上传失败', data: data }) + } + } catch (parseError) { + reject({ success: false, error: '响应解析失败', parseError: parseError }) + } + }, + fail: (err) => { + this.addLog('error', '上传失败', err) + reject({ success: false, error: err.errMsg || '网络错误', details: err }) + } + }) + }) + } + + // 生成诊断报告 + generateReport() { + const report = { + timestamp: new Date().toISOString(), + logs: this.logs, + summary: { + totalLogs: this.logs.length, + errors: this.logs.filter(log => log.type === 'error').length, + warnings: this.logs.filter(log => log.type === 'warn').length, + info: this.logs.filter(log => log.type === 'info').length + }, + recommendations: this.generateRecommendations() + } + + console.log('=== 诊断报告 ===') + console.log(JSON.stringify(report, null, 2)) + + return report + } + + // 生成建议 + generateRecommendations() { + const recommendations = [] + const errors = this.logs.filter(log => log.type === 'error') + const warnings = this.logs.filter(log => log.type === 'warn') + + // 检查token问题 + const tokenErrors = errors.filter(log => log.message.includes('token') || log.message.includes('Token')) + if (tokenErrors.length > 0) { + recommendations.push('检查用户登录状态和token有效性') + } + + // 检查网络问题 + const networkErrors = errors.filter(log => log.message.includes('网络') || log.message.includes('timeout')) + if (networkErrors.length > 0) { + recommendations.push('检查网络连接和服务器状态') + } + + // 检查文件问题 + const fileErrors = errors.filter(log => log.message.includes('文件') || log.message.includes('file')) + if (fileErrors.length > 0) { + recommendations.push('检查文件格式和大小是否符合要求') + } + + // 检查服务器问题 + const serverErrors = errors.filter(log => log.message.includes('服务器') || log.message.includes('server')) + if (serverErrors.length > 0) { + recommendations.push('检查服务器接口是否正常工作') + } + + if (recommendations.length === 0) { + recommendations.push('所有检查都通过,问题可能在其他方面') + } + + return recommendations + } + + // 运行完整诊断 + async runFullDiagnosis() { + this.addLog('info', '开始完整诊断') + + // 1. 检查token + const tokenResult = this.checkToken() + + // 2. 检查网络 + const networkResult = await this.checkNetwork() + + // 3. 检查服务器连接 + const serverResult = await this.checkServerConnection() + + // 4. 生成报告 + const report = this.generateReport() + + return { + token: tokenResult, + network: networkResult, + server: serverResult, + report: report + } + } +} + +// 导出调试器 +export default UploadDebugger + +// 使用示例 +export function debugUpload() { + const debugger = new UploadDebugger() + return debugger.runFullDiagnosis() +} + +// 在页面中使用 +export function useUploadDebugger() { + const debugger = new UploadDebugger() + + return { + debugger, + checkToken: () => debugger.checkToken(), + checkNetwork: () => debugger.checkNetwork(), + testUpload: (filePath) => debugger.testFileUpload(filePath), + runDiagnosis: () => debugger.runFullDiagnosis(), + getLogs: () => debugger.logs + } +} \ No newline at end of file diff --git a/pages/set/set.vue b/pages/set/set.vue index 966ccfe..c6e7712 100644 --- a/pages/set/set.vue +++ b/pages/set/set.vue @@ -27,7 +27,7 @@