Files
JoyD/Claw/client/wechat_app/utils/api.js

392 lines
8.8 KiB
JavaScript
Raw Normal View History

2026-03-16 15:47:55 +08:00
// API接口封装
const API_BASE = 'https://pactgo.cn/api/v1'
class API {
// 用户登录
static async login(code) {
return this.request('/wechat/login', 'POST', { code })
}
// 获取用户信息
static async getUserInfo() {
return this.request('/wechat/userinfo', 'GET')
}
// 提交任务
static async submitTask(taskData) {
return this.request('/task/submit', 'POST', taskData)
}
// 获取任务列表
static async getTaskList(page = 1, limit = 20) {
return this.request(`/task/list?page=${page}&limit=${limit}`, 'GET')
}
// 获取任务详情
static async getTaskDetail(taskId) {
return this.request(`/task/${taskId}`, 'GET')
}
// 获取任务状态
static async getTaskStatus(taskId) {
return this.request(`/task/${taskId}/status`, 'GET')
}
// 发送聊天消息
static async sendMessage(content, type = 'text') {
return this.request('/chat/message', 'POST', { content, type })
}
// 获取聊天记录
static async getChatHistory(page = 1, limit = 50) {
return this.request(`/chat/history?page=${page}&limit=${limit}`, 'GET')
}
// 获取设备信息
static async getDeviceInfo() {
return this.request('/device/info', 'GET')
}
// 更新设备状态
static async updateDeviceStatus(status) {
return this.request('/device/status', 'POST', { status })
}
// 获取系统状态
static async getSystemStatus() {
return this.request('/system/status', 'GET')
}
// 通用请求方法
static async request(url, method = 'GET', data = null) {
return new Promise((resolve, reject) => {
const token = wx.getStorageSync('token') || ''
wx.request({
url: API_BASE + url,
method,
data,
header: {
'Content-Type': 'application/json',
'Authorization': token ? `Bearer ${token}` : ''
},
success: (res) => {
if (res.statusCode === 200) {
if (res.data.success !== false) {
resolve(res.data)
} else {
reject(new Error(res.data.message || '请求失败'))
}
} else if (res.statusCode === 401) {
// Token过期重新登录
wx.removeStorageSync('token')
wx.showToast({
title: '登录已过期,请重新登录',
icon: 'none'
})
reject(new Error('登录已过期'))
} else {
reject(new Error(`请求失败: ${res.statusCode}`))
}
},
fail: (err) => {
console.error('API请求失败:', err)
wx.showToast({
title: '网络连接失败',
icon: 'none'
})
reject(err)
}
})
})
}
// 上传文件
static async uploadFile(filePath, formData = {}) {
return new Promise((resolve, reject) => {
const token = wx.getStorageSync('token') || ''
wx.uploadFile({
url: API_BASE + '/upload',
filePath: filePath,
name: 'file',
formData: formData,
header: {
'Authorization': token ? `Bearer ${token}` : ''
},
success: (res) => {
if (res.statusCode === 200) {
try {
const data = JSON.parse(res.data)
resolve(data)
} catch (e) {
reject(new Error('解析响应失败'))
}
} else {
reject(new Error(`上传失败: ${res.statusCode}`))
}
},
fail: (err) => {
console.error('文件上传失败:', err)
reject(err)
}
})
})
}
}
// WebSocket管理器
class WebSocketManager {
constructor() {
this.socket = null
this.isConnected = false
this.reconnectTimer = null
this.messageHandlers = new Map()
}
connect(url) {
if (this.socket) {
this.disconnect()
}
this.socket = wx.connectSocket({
url: url,
header: {
'content-type': 'application/json'
}
})
this.socket.onOpen(() => {
console.log('WebSocket连接已打开')
this.isConnected = true
this.clearReconnectTimer()
// 发送认证信息
this.send({
type: 'auth',
userId: wx.getStorageSync('userId') || 'anonymous',
deviceId: wx.getSystemInfoSync().model,
timestamp: Date.now()
})
})
this.socket.onMessage((res) => {
console.log('收到WebSocket消息:', res.data)
try {
const data = JSON.parse(res.data)
this.handleMessage(data)
} catch (e) {
console.error('解析WebSocket消息失败:', e)
}
})
this.socket.onClose(() => {
console.log('WebSocket连接已关闭')
this.isConnected = false
this.socket = null
this.scheduleReconnect(url)
})
this.socket.onError((err) => {
console.error('WebSocket连接错误:', err)
this.isConnected = false
this.scheduleReconnect(url)
})
}
disconnect() {
this.clearReconnectTimer()
if (this.socket) {
this.socket.close()
this.socket = null
}
this.isConnected = false
}
send(data) {
if (this.isConnected && this.socket) {
this.socket.send({
data: JSON.stringify(data)
})
} else {
console.warn('WebSocket未连接无法发送消息')
}
}
onMessage(type, handler) {
if (!this.messageHandlers.has(type)) {
this.messageHandlers.set(type, [])
}
this.messageHandlers.get(type).push(handler)
}
offMessage(type, handler) {
if (this.messageHandlers.has(type)) {
const handlers = this.messageHandlers.get(type)
const index = handlers.indexOf(handler)
if (index > -1) {
handlers.splice(index, 1)
}
}
}
handleMessage(data) {
if (data.type && this.messageHandlers.has(data.type)) {
const handlers = this.messageHandlers.get(data.type)
handlers.forEach(handler => {
try {
handler(data)
} catch (e) {
console.error('消息处理错误:', e)
}
})
}
}
scheduleReconnect(url) {
this.clearReconnectTimer()
this.reconnectTimer = setTimeout(() => {
console.log('尝试重新连接WebSocket...')
this.connect(url)
}, 3000)
}
clearReconnectTimer() {
if (this.reconnectTimer) {
clearTimeout(this.reconnectTimer)
this.reconnectTimer = null
}
}
}
// 工具函数
const util = {
// 格式化时间
formatTime(date) {
const year = date.getFullYear()
const month = date.getMonth() + 1
const day = date.getDate()
const hour = date.getHours()
const minute = date.getMinutes()
const second = date.getSeconds()
return [year, month, day].map(this.formatNumber).join('/') + ' ' +
[hour, minute, second].map(this.formatNumber).join(':')
},
formatNumber(n) {
n = n.toString()
return n[1] ? n : '0' + n
},
// 显示加载提示
showLoading(title = '加载中...') {
wx.showLoading({
title: title,
mask: true
})
},
// 隐藏加载提示
hideLoading() {
wx.hideLoading()
},
// 显示成功提示
showSuccess(title = '操作成功') {
wx.showToast({
title: title,
icon: 'success',
duration: 2000
})
},
// 显示错误提示
showError(title = '操作失败') {
wx.showToast({
title: title,
icon: 'error',
duration: 2000
})
},
// 显示模态框
showModal(title, content) {
return new Promise((resolve) => {
wx.showModal({
title: title,
content: content,
success: (res) => {
resolve(res.confirm)
}
})
})
},
// 防抖函数
debounce(func, wait) {
let timeout
return function executedFunction(...args) {
const later = () => {
clearTimeout(timeout)
func(...args)
}
clearTimeout(timeout)
timeout = setTimeout(later, wait)
}
},
// 节流函数
throttle(func, limit) {
let inThrottle
return function() {
const args = arguments
const context = this
if (!inThrottle) {
func.apply(context, args)
inThrottle = true
setTimeout(() => inThrottle = false, limit)
}
}
}
}
// 常量定义
const constants = {
// API基础地址
API_BASE: 'https://pactgo.cn/api/v1',
// WebSocket地址
WEBSOCKET_URL: 'wss://pactgo.cn/ws/task',
// 任务状态
TASK_STATUS: {
PENDING: 'pending',
PROCESSING: 'processing',
COMPLETED: 'completed',
FAILED: 'failed'
},
// 消息类型
MESSAGE_TYPE: {
TEXT: 'text',
IMAGE: 'image',
FILE: 'file',
SYSTEM: 'system'
},
// 本地存储键名
STORAGE_KEYS: {
TOKEN: 'token',
USER_INFO: 'userInfo',
DEVICE_ID: 'deviceId',
TASK_HISTORY: 'taskHistory'
}
}
module.exports = {
API,
WebSocketManager,
util,
constants
}