wxapp使用submodule

This commit is contained in:
lik
2026-05-27 15:10:30 +08:00
parent 43436f9a37
commit afc0e4d2e2
957 changed files with 14404 additions and 1 deletions

29
utils/api.js Normal file
View File

@@ -0,0 +1,29 @@
const request = require('./request.js')
const API = {
user: {
wxGetPhoneNumber: (data) => request.post('/user/wxgetphonenumber', data),
wxSignin: (data) => request.post('/user/wxsignin', data),
signout: (data) => request.post('/user/signout', data),
update: (data) => request.post('/user/update', data),
},
escort: {
getMyRecords: (params) => request.get('/health/escort-record/my', params),
getAttendantRecords: (params) => request.get('/health/escort-record/attendant', params),
getRecordById: (id) => request.get(`/health/escort-record/${id}`),
createRecord: (data) => request.post('/health/escort-record', data),
updateRecord: (id, data) => request.put(`/health/escort-record/${id}`, data),
updateStatus: (id, data) => request.patch(`/health/escort-record/${id}/status`, data),
},
resource: {
getServices: (params) => request.get('/health/service', params),
},
ai: {
chat: (data) => request.post('/ai/chat', data),
},
}
module.exports = API

222
utils/chatmsg.js Normal file
View File

@@ -0,0 +1,222 @@
const WS_BASE_URL = 'wss://api.huashengtec.com/health-ws'
//const WS_BASE_URL = 'ws://127.0.0.1:9005'
class AIChatSocket {
constructor(url = `${WS_BASE_URL}/chat`, options = {}) {
this.url = url
this.options = {
timeout: 10000,
heartbeatInterval: 30000,
autoReconnect: true,
maxReconnectAttempts: 3,
reconnectDelay: 3000,
...options
}
this.socketTask = null
this.isConnected = false
this.isConnecting = false
this.messageQueue = []
this.reconnectAttempts = 0
this._openCallback = null
this._closeCallback = null
this._errorCallback = null
this._messageCallback = null
this._heartbeatTimer = null
}
connect() {
if (this.isConnected || this.isConnecting) {
console.log('[AIChatSocket] Already connected or connecting')
return Promise.resolve()
}
this.isConnecting = true
return new Promise((resolve, reject) => {
this.socketTask = wx.connectSocket({
url: this.url,
header: {
'content-type': 'application/json',
...this.options.header
},
protocols: this.options.protocols || [],
success: () => {
console.log('[AIChatSocket] WebSocket connecting...')
},
fail: (err) => {
this.isConnecting = false
console.error('[AIChatSocket] Connect failed:', err)
reject(err)
}
})
if (!this.socketTask) {
this.isConnecting = false
reject(new Error('SocketTask creation failed'))
return
}
this.socketTask.onOpen(() => {
console.log('[AIChatSocket] Connection opened')
this.isConnected = true
this.isConnecting = false
this.reconnectAttempts = 0
this._startHeartbeat()
this._flushMessageQueue()
if (this._openCallback) {
this._openCallback()
}
resolve()
})
this.socketTask.onClose((res) => {
console.log('[AIChatSocket] Connection closed:', res)
this.isConnected = false
this.isConnecting = false
this._stopHeartbeat()
if (this._closeCallback) {
this._closeCallback(res)
}
if (this.options.autoReconnect && this.reconnectAttempts < this.options.maxReconnectAttempts) {
this._reconnect()
}
})
this.socketTask.onError((err) => {
console.error('[AIChatSocket] WebSocket error:', err)
this.isConnected = false
this.isConnecting = false
if (this._errorCallback) {
this._errorCallback(err)
}
})
this.socketTask.onMessage((res) => {
try {
const data = typeof res.data === 'string' ? JSON.parse(res.data) : res.data
if (this._messageCallback) {
this._messageCallback(data)
}
} catch (e) {
if (this._messageCallback) {
this._messageCallback(res.data)
}
}
})
})
}
send(data) {
const message = typeof data === 'string' ? data : JSON.stringify(data)
if (!this.isConnected || !this.socketTask) {
console.log('[AIChatSocket] Not connected, queueing message')
this.messageQueue.push(message)
return false
}
try {
this.socketTask.send({
data: message,
fail: (err) => {
console.error('[AIChatSocket] Send failed:', err)
this.messageQueue.push(message)
}
})
return true
} catch (err) {
console.error('[AIChatSocket] Send error:', err)
this.messageQueue.push(message)
return false
}
}
close() {
this._stopHeartbeat()
this.options.autoReconnect = false
if (this.socketTask) {
this.socketTask.close({
code: 1000,
reason: 'User closed',
fail: (err) => {
console.error('[AIChatSocket] Close failed:', err)
}
})
this.socketTask = null
}
this.isConnected = false
this.isConnecting = false
this.messageQueue = []
}
onOpen(callback) {
this._openCallback = callback
}
onClose(callback) {
this._closeCallback = callback
}
onError(callback) {
this._errorCallback = callback
}
onMessage(callback) {
this._messageCallback = callback
}
_flushMessageQueue() {
if (this.messageQueue.length === 0) return
console.log(`[AIChatSocket] Flushing ${this.messageQueue.length} queued messages`)
while (this.messageQueue.length > 0) {
const message = this.messageQueue.shift()
this.send(message)
}
}
_reconnect() {
this.reconnectAttempts++
console.log(`[AIChatSocket] Reconnecting... Attempt ${this.reconnectAttempts}/${this.options.maxReconnectAttempts}`)
setTimeout(() => {
this.connect().catch((err) => {
console.error('[AIChatSocket] Reconnect failed:', err)
})
}, this.options.reconnectDelay)
}
_startHeartbeat() {
this._stopHeartbeat()
this._heartbeatTimer = setInterval(() => {
if (this.isConnected && this.socketTask) {
this.socketTask.send({
data: JSON.stringify({ type: 'ping' }),
fail: (err) => {
console.error('[AIChatSocket] Heartbeat failed:', err)
this._stopHeartbeat()
}
})
}
}, this.options.heartbeatInterval)
}
_stopHeartbeat() {
if (this._heartbeatTimer) {
clearInterval(this._heartbeatTimer)
this._heartbeatTimer = null
}
}
}
module.exports = AIChatSocket

52
utils/request.js Normal file
View File

@@ -0,0 +1,52 @@
class Request {
constructor(baseURL = 'https://api.huashengtec.com') {
//constructor(baseURL = 'http://127.0.0.1:9010') {
this.baseURL = baseURL
}
request(options) {
return new Promise((resolve, reject) => {
const { url, method = 'GET', data = {}, header = {}, ...rest } = options
const app = getApp()
const token = app?.globalData?.user?.security?.token || ''
data.appId = 'wxapp-escort'
wx.request({
url: url.startsWith('http') ? url : `${this.baseURL}${url}`,
method,
data,
header: {
'Content-Type': 'application/json',
...(token ? { 'token': token } : {}),
...header
},
...rest,
success: (res) => {
if (res.statusCode >= 200 && res.statusCode < 300) {
resolve(res.data)
} else {
reject(new Error(`HTTP ${res.statusCode}`))
}
},
fail: (err) => {
reject(err)
}
})
})
}
get(url, params = {}, options = {}) {
return this.request({ url, method: 'GET', data: params, ...options })
}
post(url, data = {}, options = {}) {
return this.request({ url, method: 'POST', data, ...options })
}
}
const request = new Request()
module.exports = request