1. uni.request网络请求

1.1 基础请求

// 基本GET请求
uni.request({
    url: 'https://api.example.com/users',
    method: 'GET',
    success: (res) => {
        console.log('请求成功:', res.data)
    },
    fail: (err) => {
        console.error('请求失败:', err)
    },
    complete: () => {
        console.log('请求完成')
    }
})

// 基本POST请求
uni.request({
    url: 'https://api.example.com/users',
    method: 'POST',
    data: {
        name: '张三',
        email: 'zhangsan@example.com'
    },
    header: {
        'Content-Type': 'application/json'
    },
    success: (res) => {
        console.log('创建成功:', res.data)
    },
    fail: (err) => {
        console.error('创建失败:', err)
    }
})

// Promise方式
function requestData(url, options = {}) {
    return new Promise((resolve, reject) => {
        uni.request({
            url,
            ...options,
            success: (res) => {
                if (res.statusCode === 200) {
                    resolve(res.data)
                } else {
                    reject(new Error(`HTTP ${res.statusCode}: ${res.errMsg}`))
                }
            },
            fail: (err) => {
                reject(new Error(err.errMsg || '网络请求失败'))
            }
        })
    })
}

// 使用async/await
async function fetchUserData() {
    try {
        const userData = await requestData('https://api.example.com/user/123')
        console.log('用户数据:', userData)
        return userData
    } catch (error) {
        console.error('获取用户数据失败:', error)
        throw error
    }
}

1.2 请求拦截器

// utils/request.js
class RequestInterceptor {
    constructor() {
        this.requestQueue = []
        this.isRefreshing = false
        this.baseURL = 'https://api.example.com'
        this.timeout = 10000
    }
    
    // 请求拦截
    interceptRequest(config) {
        // 添加基础URL
        if (config.url && !config.url.startsWith('http')) {
            config.url = this.baseURL + config.url
        }
        
        // 添加认证token
        const token = uni.getStorageSync('token')
        if (token) {
            config.header = {
                ...config.header,
                'Authorization': `Bearer ${token}`
            }
        }
        
        // 添加公共请求头
        config.header = {
            'Content-Type': 'application/json',
            'Accept': 'application/json',
            ...config.header
        }
        
        // 设置超时时间
        config.timeout = config.timeout || this.timeout
        
        console.log('请求拦截:', config)
        return config
    }
    
    // 响应拦截
    interceptResponse(response, config) {
        console.log('响应拦截:', response)
        
        // 处理HTTP状态码
        if (response.statusCode >= 200 && response.statusCode < 300) {
            // 处理业务状态码
            const { code, data, message } = response.data
            
            if (code === 200 || code === 0) {
                return Promise.resolve(data)
            } else if (code === 401) {
                // token过期,尝试刷新
                return this.handleTokenExpired(config)
            } else {
                return Promise.reject(new Error(message || '请求失败'))
            }
        } else {
            return Promise.reject(new Error(`HTTP ${response.statusCode}`))
        }
    }
    
    // 处理token过期
    async handleTokenExpired(originalConfig) {
        if (this.isRefreshing) {
            // 如果正在刷新token,将请求加入队列
            return new Promise((resolve, reject) => {
                this.requestQueue.push({ resolve, reject, config: originalConfig })
            })
        }
        
        this.isRefreshing = true
        
        try {
            const refreshToken = uni.getStorageSync('refreshToken')
            if (!refreshToken) {
                throw new Error('无刷新token')
            }
            
            // 刷新token
            const response = await this.refreshTokenRequest(refreshToken)
            const { token, refreshToken: newRefreshToken } = response
            
            // 保存新token
            uni.setStorageSync('token', token)
            uni.setStorageSync('refreshToken', newRefreshToken)
            
            // 重试原始请求
            const retryResponse = await this.request(originalConfig)
            
            // 处理队列中的请求
            this.requestQueue.forEach(({ resolve, config }) => {
                resolve(this.request(config))
            })
            this.requestQueue = []
            
            return retryResponse
        } catch (error) {
            // 刷新失败,清除token并跳转登录
            uni.removeStorageSync('token')
            uni.removeStorageSync('refreshToken')
            
            // 处理队列中的请求
            this.requestQueue.forEach(({ reject }) => {
                reject(new Error('登录已过期,请重新登录'))
            })
            this.requestQueue = []
            
            // 跳转登录页
            uni.reLaunch({
                url: '/pages/login/login'
            })
            
            throw error
        } finally {
            this.isRefreshing = false
        }
    }
    
    // 刷新token请求
    refreshTokenRequest(refreshToken) {
        return new Promise((resolve, reject) => {
            uni.request({
                url: this.baseURL + '/auth/refresh',
                method: 'POST',
                data: { refreshToken },
                success: (res) => {
                    if (res.statusCode === 200 && res.data.code === 200) {
                        resolve(res.data.data)
                    } else {
                        reject(new Error('刷新token失败'))
                    }
                },
                fail: reject
            })
        })
    }
    
    // 主请求方法
    request(config) {
        return new Promise((resolve, reject) => {
            // 请求拦截
            const interceptedConfig = this.interceptRequest(config)
            
            uni.request({
                ...interceptedConfig,
                success: (response) => {
                    // 响应拦截
                    this.interceptResponse(response, config)
                        .then(resolve)
                        .catch(reject)
                },
                fail: (error) => {
                    console.error('网络请求失败:', error)
                    reject(new Error(error.errMsg || '网络连接失败'))
                }
            })
        })
    }
    
    // 便捷方法
    get(url, params = {}, config = {}) {
        return this.request({
            url,
            method: 'GET',
            data: params,
            ...config
        })
    }
    
    post(url, data = {}, config = {}) {
        return this.request({
            url,
            method: 'POST',
            data,
            ...config
        })
    }
    
    put(url, data = {}, config = {}) {
        return this.request({
            url,
            method: 'PUT',
            data,
            ...config
        })
    }
    
    delete(url, config = {}) {
        return this.request({
            url,
            method: 'DELETE',
            ...config
        })
    }
}

// 创建请求实例
const request = new RequestInterceptor()

export default request

1.3 API管理

// api/index.js
import request from '@/utils/request.js'

// 用户相关API
export const userAPI = {
    // 用户登录
    login(credentials) {
        return request.post('/auth/login', credentials)
    },
    
    // 用户注册
    register(userData) {
        return request.post('/auth/register', userData)
    },
    
    // 获取用户信息
    getUserInfo(userId) {
        return request.get(`/users/${userId}`)
    },
    
    // 更新用户信息
    updateUserInfo(userId, userData) {
        return request.put(`/users/${userId}`, userData)
    },
    
    // 上传头像
    uploadAvatar(file) {
        return new Promise((resolve, reject) => {
            uni.uploadFile({
                url: request.baseURL + '/users/avatar',
                filePath: file.path,
                name: 'avatar',
                header: {
                    'Authorization': `Bearer ${uni.getStorageSync('token')}`
                },
                success: (res) => {
                    try {
                        const data = JSON.parse(res.data)
                        if (data.code === 200) {
                            resolve(data.data)
                        } else {
                            reject(new Error(data.message))
                        }
                    } catch (error) {
                        reject(new Error('响应解析失败'))
                    }
                },
                fail: reject
            })
        })
    },
    
    // 修改密码
    changePassword(passwordData) {
        return request.post('/users/change-password', passwordData)
    }
}

// 产品相关API
export const productAPI = {
    // 获取产品列表
    getProducts(params = {}) {
        return request.get('/products', params)
    },
    
    // 获取产品详情
    getProductDetail(productId) {
        return request.get(`/products/${productId}`)
    },
    
    // 搜索产品
    searchProducts(keyword, filters = {}) {
        return request.get('/products/search', {
            keyword,
            ...filters
        })
    },
    
    // 获取产品分类
    getCategories() {
        return request.get('/products/categories')
    },
    
    // 获取热门产品
    getHotProducts(limit = 10) {
        return request.get('/products/hot', { limit })
    }
}

// 订单相关API
export const orderAPI = {
    // 创建订单
    createOrder(orderData) {
        return request.post('/orders', orderData)
    },
    
    // 获取订单列表
    getOrders(params = {}) {
        return request.get('/orders', params)
    },
    
    // 获取订单详情
    getOrderDetail(orderId) {
        return request.get(`/orders/${orderId}`)
    },
    
    // 取消订单
    cancelOrder(orderId, reason) {
        return request.post(`/orders/${orderId}/cancel`, { reason })
    },
    
    // 确认收货
    confirmOrder(orderId) {
        return request.post(`/orders/${orderId}/confirm`)
    },
    
    // 申请退款
    requestRefund(orderId, refundData) {
        return request.post(`/orders/${orderId}/refund`, refundData)
    }
}

// 地址相关API
export const addressAPI = {
    // 获取地址列表
    getAddresses() {
        return request.get('/addresses')
    },
    
    // 添加地址
    addAddress(addressData) {
        return request.post('/addresses', addressData)
    },
    
    // 更新地址
    updateAddress(addressId, addressData) {
        return request.put(`/addresses/${addressId}`, addressData)
    },
    
    // 删除地址
    deleteAddress(addressId) {
        return request.delete(`/addresses/${addressId}`)
    },
    
    // 设置默认地址
    setDefaultAddress(addressId) {
        return request.post(`/addresses/${addressId}/default`)
    }
}

// 支付相关API
export const paymentAPI = {
    // 创建支付订单
    createPayment(paymentData) {
        return request.post('/payments', paymentData)
    },
    
    // 查询支付状态
    getPaymentStatus(paymentId) {
        return request.get(`/payments/${paymentId}/status`)
    },
    
    // 获取支付方式
    getPaymentMethods() {
        return request.get('/payments/methods')
    }
}

// 文件上传API
export const uploadAPI = {
    // 上传单个文件
    uploadFile(filePath, uploadPath = '/upload') {
        return new Promise((resolve, reject) => {
            uni.uploadFile({
                url: request.baseURL + uploadPath,
                filePath,
                name: 'file',
                header: {
                    'Authorization': `Bearer ${uni.getStorageSync('token')}`
                },
                success: (res) => {
                    try {
                        const data = JSON.parse(res.data)
                        if (data.code === 200) {
                            resolve(data.data)
                        } else {
                            reject(new Error(data.message))
                        }
                    } catch (error) {
                        reject(new Error('响应解析失败'))
                    }
                },
                fail: reject
            })
        })
    },
    
    // 上传多个文件
    async uploadMultipleFiles(filePaths, uploadPath = '/upload') {
        const uploadPromises = filePaths.map(filePath => 
            this.uploadFile(filePath, uploadPath)
        )
        
        try {
            const results = await Promise.all(uploadPromises)
            return results
        } catch (error) {
            console.error('批量上传失败:', error)
            throw error
        }
    }
}

2. 文件上传与下载

2.1 图片上传

// utils/upload.js
class UploadManager {
    constructor() {
        this.maxFileSize = 5 * 1024 * 1024 // 5MB
        this.allowedTypes = ['image/jpeg', 'image/png', 'image/gif']
        this.uploadURL = 'https://api.example.com/upload'
    }
    
    // 选择并上传图片
    async chooseAndUploadImage(options = {}) {
        try {
            // 选择图片
            const chooseResult = await this.chooseImage(options)
            
            // 压缩图片
            const compressedFiles = await this.compressImages(chooseResult.tempFiles)
            
            // 上传图片
            const uploadResults = await this.uploadImages(compressedFiles)
            
            return uploadResults
        } catch (error) {
            console.error('图片上传失败:', error)
            throw error
        }
    }
    
    // 选择图片
    chooseImage(options = {}) {
        return new Promise((resolve, reject) => {
            uni.chooseImage({
                count: options.count || 1,
                sizeType: options.sizeType || ['compressed'],
                sourceType: options.sourceType || ['album', 'camera'],
                success: resolve,
                fail: reject
            })
        })
    }
    
    // 压缩图片
    async compressImages(files) {
        const compressPromises = files.map(file => this.compressImage(file))
        return Promise.all(compressPromises)
    }
    
    // 压缩单张图片
    compressImage(file) {
        return new Promise((resolve, reject) => {
            // 检查文件大小
            if (file.size > this.maxFileSize) {
                uni.compressImage({
                    src: file.path,
                    quality: 80,
                    success: (res) => {
                        resolve({
                            ...file,
                            path: res.tempFilePath,
                            size: res.size || file.size
                        })
                    },
                    fail: () => {
                        // 压缩失败,使用原文件
                        resolve(file)
                    }
                })
            } else {
                resolve(file)
            }
        })
    }
    
    // 批量上传图片
    async uploadImages(files) {
        const uploadPromises = files.map(file => this.uploadSingleImage(file))
        
        try {
            const results = await Promise.all(uploadPromises)
            return results
        } catch (error) {
            console.error('批量上传失败:', error)
            throw error
        }
    }
    
    // 上传单张图片
    uploadSingleImage(file) {
        return new Promise((resolve, reject) => {
            const uploadTask = uni.uploadFile({
                url: this.uploadURL,
                filePath: file.path,
                name: 'image',
                formData: {
                    type: 'image',
                    timestamp: Date.now()
                },
                header: {
                    'Authorization': `Bearer ${uni.getStorageSync('token')}`
                },
                success: (res) => {
                    try {
                        const data = JSON.parse(res.data)
                        if (data.code === 200) {
                            resolve({
                                url: data.data.url,
                                filename: data.data.filename,
                                size: file.size,
                                originalFile: file
                            })
                        } else {
                            reject(new Error(data.message || '上传失败'))
                        }
                    } catch (error) {
                        reject(new Error('响应解析失败'))
                    }
                },
                fail: reject
            })
            
            // 监听上传进度
            uploadTask.onProgressUpdate((res) => {
                console.log('上传进度:', res.progress + '%')
                // 可以通过事件或回调通知UI更新进度
                uni.$emit('uploadProgress', {
                    filename: file.name,
                    progress: res.progress
                })
            })
        })
    }
    
    // 预览图片
    previewImages(urls, current = 0) {
        uni.previewImage({
            urls,
            current: urls[current]
        })
    }
    
    // 保存图片到相册
    async saveImageToPhotosAlbum(url) {
        try {
            // 先下载图片
            const downloadResult = await this.downloadFile(url)
            
            // 保存到相册
            await new Promise((resolve, reject) => {
                uni.saveImageToPhotosAlbum({
                    filePath: downloadResult.tempFilePath,
                    success: resolve,
                    fail: reject
                })
            })
            
            uni.showToast({
                title: '保存成功',
                icon: 'success'
            })
        } catch (error) {
            console.error('保存图片失败:', error)
            uni.showToast({
                title: '保存失败',
                icon: 'none'
            })
        }
    }
    
    // 下载文件
    downloadFile(url) {
        return new Promise((resolve, reject) => {
            uni.downloadFile({
                url,
                success: resolve,
                fail: reject
            })
        })
    }
}

// 创建上传管理实例
const uploadManager = new UploadManager()

export default uploadManager

2.2 文件下载

// utils/download.js
class DownloadManager {
    constructor() {
        this.downloadQueue = []
        this.maxConcurrent = 3
        this.activeDownloads = 0
    }
    
    // 下载文件
    async downloadFile(url, options = {}) {
        return new Promise((resolve, reject) => {
            const downloadTask = uni.downloadFile({
                url,
                header: options.header || {},
                success: (res) => {
                    if (res.statusCode === 200) {
                        resolve({
                            tempFilePath: res.tempFilePath,
                            statusCode: res.statusCode,
                            url
                        })
                    } else {
                        reject(new Error(`下载失败: HTTP ${res.statusCode}`))
                    }
                },
                fail: reject
            })
            
            // 监听下载进度
            if (options.onProgress) {
                downloadTask.onProgressUpdate(options.onProgress)
            }
            
            // 支持取消下载
            if (options.onCancel) {
                options.onCancel(() => {
                    downloadTask.abort()
                })
            }
        })
    }
    
    // 批量下载
    async downloadMultipleFiles(urls, options = {}) {
        const downloadPromises = urls.map(url => 
            this.downloadWithQueue(url, options)
        )
        
        try {
            const results = await Promise.all(downloadPromises)
            return results
        } catch (error) {
            console.error('批量下载失败:', error)
            throw error
        }
    }
    
    // 队列下载(控制并发数)
    async downloadWithQueue(url, options = {}) {
        return new Promise((resolve, reject) => {
            this.downloadQueue.push({
                url,
                options,
                resolve,
                reject
            })
            
            this.processQueue()
        })
    }
    
    // 处理下载队列
    async processQueue() {
        if (this.activeDownloads >= this.maxConcurrent || this.downloadQueue.length === 0) {
            return
        }
        
        const { url, options, resolve, reject } = this.downloadQueue.shift()
        this.activeDownloads++
        
        try {
            const result = await this.downloadFile(url, options)
            resolve(result)
        } catch (error) {
            reject(error)
        } finally {
            this.activeDownloads--
            this.processQueue() // 处理下一个
        }
    }
    
    // 下载并保存文件
    async downloadAndSave(url, filename, options = {}) {
        try {
            // 下载文件
            const downloadResult = await this.downloadFile(url, options)
            
            // 保存文件
            const saveResult = await this.saveFile(downloadResult.tempFilePath, filename)
            
            uni.showToast({
                title: '下载完成',
                icon: 'success'
            })
            
            return saveResult
        } catch (error) {
            console.error('下载保存失败:', error)
            uni.showToast({
                title: '下载失败',
                icon: 'none'
            })
            throw error
        }
    }
    
    // 保存文件
    saveFile(tempFilePath, filename) {
        return new Promise((resolve, reject) => {
            uni.saveFile({
                tempFilePath,
                success: (res) => {
                    resolve({
                        savedFilePath: res.savedFilePath,
                        filename
                    })
                },
                fail: reject
            })
        })
    }
    
    // 获取已保存的文件列表
    getSavedFileList() {
        return new Promise((resolve, reject) => {
            uni.getSavedFileList({
                success: resolve,
                fail: reject
            })
        })
    }
    
    // 删除已保存的文件
    removeSavedFile(filePath) {
        return new Promise((resolve, reject) => {
            uni.removeSavedFile({
                filePath,
                success: resolve,
                fail: reject
            })
        })
    }
    
    // 获取文件信息
    getFileInfo(filePath) {
        return new Promise((resolve, reject) => {
            uni.getFileInfo({
                filePath,
                success: resolve,
                fail: reject
            })
        })
    }
}

// 创建下载管理实例
const downloadManager = new DownloadManager()

export default downloadManager

3. WebSocket实时通信

3.1 WebSocket封装

// utils/websocket.js
class WebSocketManager {
    constructor(url, options = {}) {
        this.url = url
        this.options = {
            reconnectInterval: 5000,
            maxReconnectAttempts: 5,
            heartbeatInterval: 30000,
            ...options
        }
        
        this.ws = null
        this.isConnected = false
        this.reconnectAttempts = 0
        this.heartbeatTimer = null
        this.reconnectTimer = null
        
        this.eventListeners = {
            open: [],
            message: [],
            close: [],
            error: []
        }
        
        this.messageQueue = []
    }
    
    // 连接WebSocket
    connect() {
        try {
            this.ws = uni.connectSocket({
                url: this.url,
                header: this.options.header || {},
                protocols: this.options.protocols || []
            })
            
            this.setupEventListeners()
        } catch (error) {
            console.error('WebSocket连接失败:', error)
            this.handleError(error)
        }
    }
    
    // 设置事件监听
    setupEventListeners() {
        // 连接打开
        this.ws.onOpen(() => {
            console.log('WebSocket连接已打开')
            this.isConnected = true
            this.reconnectAttempts = 0
            
            // 发送队列中的消息
            this.flushMessageQueue()
            
            // 开始心跳
            this.startHeartbeat()
            
            // 触发open事件
            this.emit('open')
        })
        
        // 接收消息
        this.ws.onMessage((res) => {
            try {
                const data = JSON.parse(res.data)
                console.log('收到WebSocket消息:', data)
                
                // 处理心跳响应
                if (data.type === 'pong') {
                    return
                }
                
                // 触发message事件
                this.emit('message', data)
            } catch (error) {
                console.error('消息解析失败:', error)
                this.emit('message', res.data)
            }
        })
        
        // 连接关闭
        this.ws.onClose((res) => {
            console.log('WebSocket连接已关闭:', res)
            this.isConnected = false
            
            // 停止心跳
            this.stopHeartbeat()
            
            // 触发close事件
            this.emit('close', res)
            
            // 尝试重连
            if (res.code !== 1000) { // 非正常关闭
                this.attemptReconnect()
            }
        })
        
        // 连接错误
        this.ws.onError((error) => {
            console.error('WebSocket错误:', error)
            this.handleError(error)
        })
    }
    
    // 发送消息
    send(data) {
        const message = typeof data === 'string' ? data : JSON.stringify(data)
        
        if (this.isConnected) {
            this.ws.send({
                data: message,
                success: () => {
                    console.log('消息发送成功:', message)
                },
                fail: (error) => {
                    console.error('消息发送失败:', error)
                    // 将失败的消息加入队列
                    this.messageQueue.push(message)
                }
            })
        } else {
            // 连接未建立,将消息加入队列
            this.messageQueue.push(message)
            console.log('连接未建立,消息已加入队列')
        }
    }
    
    // 发送队列中的消息
    flushMessageQueue() {
        while (this.messageQueue.length > 0) {
            const message = this.messageQueue.shift()
            this.send(message)
        }
    }
    
    // 关闭连接
    close(code = 1000, reason = '正常关闭') {
        if (this.ws) {
            this.ws.close({
                code,
                reason
            })
        }
        
        this.stopHeartbeat()
        this.stopReconnect()
    }
    
    // 开始心跳
    startHeartbeat() {
        this.heartbeatTimer = setInterval(() => {
            if (this.isConnected) {
                this.send({ type: 'ping', timestamp: Date.now() })
            }
        }, this.options.heartbeatInterval)
    }
    
    // 停止心跳
    stopHeartbeat() {
        if (this.heartbeatTimer) {
            clearInterval(this.heartbeatTimer)
            this.heartbeatTimer = null
        }
    }
    
    // 尝试重连
    attemptReconnect() {
        if (this.reconnectAttempts >= this.options.maxReconnectAttempts) {
            console.error('达到最大重连次数,停止重连')
            return
        }
        
        this.reconnectAttempts++
        console.log(`尝试第${this.reconnectAttempts}次重连...`)
        
        this.reconnectTimer = setTimeout(() => {
            this.connect()
        }, this.options.reconnectInterval)
    }
    
    // 停止重连
    stopReconnect() {
        if (this.reconnectTimer) {
            clearTimeout(this.reconnectTimer)
            this.reconnectTimer = null
        }
    }
    
    // 处理错误
    handleError(error) {
        this.emit('error', error)
    }
    
    // 添加事件监听
    on(event, callback) {
        if (this.eventListeners[event]) {
            this.eventListeners[event].push(callback)
        }
    }
    
    // 移除事件监听
    off(event, callback) {
        if (this.eventListeners[event]) {
            const index = this.eventListeners[event].indexOf(callback)
            if (index > -1) {
                this.eventListeners[event].splice(index, 1)
            }
        }
    }
    
    // 触发事件
    emit(event, data) {
        if (this.eventListeners[event]) {
            this.eventListeners[event].forEach(callback => {
                try {
                    callback(data)
                } catch (error) {
                    console.error('事件回调执行失败:', error)
                }
            })
        }
    }
    
    // 获取连接状态
    getReadyState() {
        return this.isConnected ? 1 : 0
    }
}

export default WebSocketManager

3.2 聊天应用示例

// utils/chat.js
import WebSocketManager from './websocket.js'

class ChatManager {
    constructor() {
        this.ws = null
        this.currentRoom = null
        this.userId = null
        this.messageHandlers = new Map()
        
        this.init()
    }
    
    // 初始化
    init() {
        this.userId = uni.getStorageSync('userId')
        
        if (this.userId) {
            this.connect()
        }
    }
    
    // 连接聊天服务器
    connect() {
        const token = uni.getStorageSync('token')
        const wsUrl = `wss://chat.example.com/ws?token=${token}&userId=${this.userId}`
        
        this.ws = new WebSocketManager(wsUrl, {
            reconnectInterval: 3000,
            maxReconnectAttempts: 10,
            heartbeatInterval: 25000
        })
        
        this.setupEventHandlers()
        this.ws.connect()
    }
    
    // 设置事件处理
    setupEventHandlers() {
        // 连接成功
        this.ws.on('open', () => {
            console.log('聊天服务连接成功')
            uni.$emit('chatConnected')
        })
        
        // 接收消息
        this.ws.on('message', (data) => {
            this.handleMessage(data)
        })
        
        // 连接关闭
        this.ws.on('close', () => {
            console.log('聊天服务连接关闭')
            uni.$emit('chatDisconnected')
        })
        
        // 连接错误
        this.ws.on('error', (error) => {
            console.error('聊天服务连接错误:', error)
            uni.$emit('chatError', error)
        })
    }
    
    // 处理接收到的消息
    handleMessage(data) {
        const { type, payload } = data
        
        switch (type) {
            case 'message':
                this.handleChatMessage(payload)
                break
            case 'userJoined':
                this.handleUserJoined(payload)
                break
            case 'userLeft':
                this.handleUserLeft(payload)
                break
            case 'typing':
                this.handleTyping(payload)
                break
            case 'messageRead':
                this.handleMessageRead(payload)
                break
            default:
                console.log('未知消息类型:', type, payload)
        }
    }
    
    // 处理聊天消息
    handleChatMessage(message) {
        console.log('收到聊天消息:', message)
        
        // 保存消息到本地
        this.saveMessageToLocal(message)
        
        // 通知UI更新
        uni.$emit('newMessage', message)
        
        // 如果不是当前房间的消息,显示通知
        if (message.roomId !== this.currentRoom) {
            this.showMessageNotification(message)
        }
    }
    
    // 处理用户加入
    handleUserJoined(data) {
        console.log('用户加入:', data)
        uni.$emit('userJoined', data)
    }
    
    // 处理用户离开
    handleUserLeft(data) {
        console.log('用户离开:', data)
        uni.$emit('userLeft', data)
    }
    
    // 处理正在输入
    handleTyping(data) {
        uni.$emit('userTyping', data)
    }
    
    // 处理消息已读
    handleMessageRead(data) {
        uni.$emit('messageRead', data)
    }
    
    // 发送聊天消息
    sendMessage(roomId, content, type = 'text') {
        const message = {
            type: 'message',
            payload: {
                id: this.generateMessageId(),
                roomId,
                senderId: this.userId,
                content,
                messageType: type,
                timestamp: Date.now()
            }
        }
        
        this.ws.send(message)
        
        // 保存到本地(发送状态)
        this.saveMessageToLocal({
            ...message.payload,
            status: 'sending'
        })
        
        return message.payload.id
    }
    
    // 发送图片消息
    async sendImageMessage(roomId, imagePath) {
        try {
            // 上传图片
            const uploadResult = await uploadManager.uploadSingleImage({ path: imagePath })
            
            // 发送图片消息
            return this.sendMessage(roomId, {
                url: uploadResult.url,
                width: uploadResult.width || 0,
                height: uploadResult.height || 0
            }, 'image')
        } catch (error) {
            console.error('发送图片消息失败:', error)
            throw error
        }
    }
    
    // 加入房间
    joinRoom(roomId) {
        this.currentRoom = roomId
        
        this.ws.send({
            type: 'joinRoom',
            payload: { roomId }
        })
    }
    
    // 离开房间
    leaveRoom(roomId) {
        this.ws.send({
            type: 'leaveRoom',
            payload: { roomId }
        })
        
        if (this.currentRoom === roomId) {
            this.currentRoom = null
        }
    }
    
    // 发送正在输入状态
    sendTyping(roomId, isTyping = true) {
        this.ws.send({
            type: 'typing',
            payload: {
                roomId,
                userId: this.userId,
                isTyping
            }
        })
    }
    
    // 标记消息为已读
    markMessageAsRead(messageId, roomId) {
        this.ws.send({
            type: 'markAsRead',
            payload: {
                messageId,
                roomId,
                userId: this.userId
            }
        })
    }
    
    // 保存消息到本地
    saveMessageToLocal(message) {
        const messages = uni.getStorageSync(`messages_${message.roomId}`) || []
        messages.push(message)
        
        // 只保留最近1000条消息
        if (messages.length > 1000) {
            messages.splice(0, messages.length - 1000)
        }
        
        uni.setStorageSync(`messages_${message.roomId}`, messages)
    }
    
    // 获取本地消息
    getLocalMessages(roomId) {
        return uni.getStorageSync(`messages_${roomId}`) || []
    }
    
    // 显示消息通知
    showMessageNotification(message) {
        // 这里可以根据平台显示不同的通知
        uni.showToast({
            title: `${message.senderName}: ${message.content}`,
            icon: 'none',
            duration: 2000
        })
    }
    
    // 生成消息ID
    generateMessageId() {
        return `msg_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`
    }
    
    // 断开连接
    disconnect() {
        if (this.ws) {
            this.ws.close()
            this.ws = null
        }
        this.currentRoom = null
    }
    
    // 获取连接状态
    isConnected() {
        return this.ws && this.ws.getReadyState() === 1
    }
}

// 创建聊天管理实例
const chatManager = new ChatManager()

export default chatManager

4. 数据缓存策略

4.1 智能缓存

// utils/smartCache.js
class SmartCache {
    constructor() {
        this.cache = new Map()
        this.cacheConfig = {
            // 不同类型数据的缓存策略
            user: { ttl: 30 * 60 * 1000, maxSize: 100 }, // 30分钟
            product: { ttl: 10 * 60 * 1000, maxSize: 500 }, // 10分钟
            order: { ttl: 5 * 60 * 1000, maxSize: 200 }, // 5分钟
            default: { ttl: 15 * 60 * 1000, maxSize: 300 } // 15分钟
        }
        
        this.init()
    }
    
    // 初始化
    init() {
        // 从本地存储恢复缓存
        this.loadFromStorage()
        
        // 定期清理过期缓存
        setInterval(() => {
            this.cleanExpiredCache()
        }, 5 * 60 * 1000) // 5分钟清理一次
    }
    
    // 设置缓存
    set(key, data, type = 'default') {
        const config = this.cacheConfig[type] || this.cacheConfig.default
        const now = Date.now()
        
        const cacheItem = {
            data,
            type,
            timestamp: now,
            expireTime: now + config.ttl,
            accessCount: 0,
            lastAccess: now
        }
        
        this.cache.set(key, cacheItem)
        
        // 检查缓存大小
        this.checkCacheSize(type)
        
        // 保存到本地存储
        this.saveToStorage()
    }
    
    // 获取缓存
    get(key) {
        const cacheItem = this.cache.get(key)
        
        if (!cacheItem) {
            return null
        }
        
        // 检查是否过期
        if (Date.now() > cacheItem.expireTime) {
            this.cache.delete(key)
            this.saveToStorage()
            return null
        }
        
        // 更新访问信息
        cacheItem.accessCount++
        cacheItem.lastAccess = Date.now()
        
        return cacheItem.data
    }
    
    // 删除缓存
    delete(key) {
        const deleted = this.cache.delete(key)
        if (deleted) {
            this.saveToStorage()
        }
        return deleted
    }
    
    // 清空指定类型的缓存
    clearByType(type) {
        let cleared = 0
        
        for (const [key, item] of this.cache.entries()) {
            if (item.type === type) {
                this.cache.delete(key)
                cleared++
            }
        }
        
        if (cleared > 0) {
            this.saveToStorage()
        }
        
        return cleared
    }
    
    // 清空所有缓存
    clear() {
        this.cache.clear()
        this.saveToStorage()
    }
    
    // 检查缓存大小
    checkCacheSize(type) {
        const config = this.cacheConfig[type] || this.cacheConfig.default
        const typeItems = Array.from(this.cache.entries())
            .filter(([key, item]) => item.type === type)
        
        if (typeItems.length > config.maxSize) {
            // 按最后访问时间排序,删除最旧的
            typeItems.sort((a, b) => a[1].lastAccess - b[1].lastAccess)
            
            const deleteCount = typeItems.length - config.maxSize
            for (let i = 0; i < deleteCount; i++) {
                this.cache.delete(typeItems[i][0])
            }
        }
    }
    
    // 清理过期缓存
    cleanExpiredCache() {
        const now = Date.now()
        let cleaned = 0
        
        for (const [key, item] of this.cache.entries()) {
            if (now > item.expireTime) {
                this.cache.delete(key)
                cleaned++
            }
        }
        
        if (cleaned > 0) {
            console.log(`清理了${cleaned}个过期缓存`)
            this.saveToStorage()
        }
    }
    
    // 保存到本地存储
    saveToStorage() {
        try {
            const cacheData = Array.from(this.cache.entries())
            uni.setStorageSync('smart_cache', cacheData)
        } catch (error) {
            console.error('保存缓存到本地存储失败:', error)
        }
    }
    
    // 从本地存储加载
    loadFromStorage() {
        try {
            const cacheData = uni.getStorageSync('smart_cache')
            if (cacheData && Array.isArray(cacheData)) {
                this.cache = new Map(cacheData)
                
                // 清理过期的缓存
                this.cleanExpiredCache()
            }
        } catch (error) {
            console.error('从本地存储加载缓存失败:', error)
        }
    }
    
    // 获取缓存统计
    getStats() {
        const stats = {
            total: this.cache.size,
            byType: {},
            memoryUsage: 0
        }
        
        for (const [key, item] of this.cache.entries()) {
            // 按类型统计
            if (!stats.byType[item.type]) {
                stats.byType[item.type] = 0
            }
            stats.byType[item.type]++
            
            // 估算内存使用
            stats.memoryUsage += JSON.stringify(item).length
        }
        
        return stats
    }
    
    // 获取或设置缓存(如果不存在则执行函数)
    async getOrSet(key, asyncFunction, type = 'default') {
        // 先尝试从缓存获取
        const cached = this.get(key)
        if (cached !== null) {
            return cached
        }
        
        try {
            // 执行异步函数获取数据
            const data = await asyncFunction()
            
            // 缓存结果
            this.set(key, data, type)
            
            return data
        } catch (error) {
            console.error('获取数据失败:', error)
            throw error
        }
    }
}

// 创建智能缓存实例
const smartCache = new SmartCache()

export default smartCache

5. 总结

网络请求与数据交互是UniApp应用的核心功能:

  1. uni.request:基础的网络请求API,支持多种HTTP方法
  2. 请求拦截器:统一处理请求头、认证、错误等
  3. API管理:模块化管理不同业务的API接口
  4. 文件上传下载:处理图片、文档等文件的上传下载
  5. WebSocket:实现实时通信功能
  6. 数据缓存:提升应用性能和用户体验
  7. 错误处理:完善的错误处理和重试机制
  8. 离线支持:处理网络异常情况下的数据同步