feat(sdk): 升级HaveADrink SDK并集成邀请系统

- 将HaveADrink依赖从1.0.8升级至1.0.12版本
- 集成邀请码功能,新增common/invite.js处理邀请链路
- 实现发送好友请求返回邀请码的新流程
- 添加删除动态功能,新增DeleteFeed接口
- 集成UniAppWebSocket适配器,重构WebSocket连接管理
- 优化好友请求支持关键词搜索功能
- 在FeedCard组件中添加删除按钮和分享按钮
- 更新SDK类型定义文件以匹配新接口规范
This commit is contained in:
cg
2026-08-04 23:32:45 +08:00
parent f988c8d868
commit 57eef74eb1
19 changed files with 1461 additions and 223 deletions
+156
View File
@@ -0,0 +1,156 @@
/* 碰盏日记 - UniAppWebSocket 适配器
* 将 uni-app 的 uni.connectSocket 适配为 HaveADrink SDK WebsocketInterface
* (标准 WebSocket 风格:constructor(host)、onopen/onmessage/onclose/onerror、send、close
* 用法:在 SDK 初始化时传入 websocket: UniAppWebSocket
*/
export default class UniAppWebSocket {
/**
* @param {string} host - 完整 ws/wss 连接地址(SDK 已处理 https→wss 协议转换)
*/
constructor(host) {
this.url = host
// 可赋值的事件回调(SDK ChatWebSocketConn.connect() 中直接赋值)
this.onopen = null
this.onmessage = null
this.onclose = null
this.onerror = null
// 连接状态: connecting | open | closed
this.readyState = 0
this._sendQueue = []
this._closedByUser = false
this._connect()
}
_connect() {
// 微信小程序下直接用 wx.connectSocket
// uni 的 API 运行时(uni.api.esm.js)会向 connectSocket 注入 success/fail/complete 回调,
// 而微信规则是“传入回调后不再返回 SocketTask”,导致 uni.connectSocket 永远拿不到 task。
// wx.connectSocket 不传回调时正常返回 SocketTask,避免降级到全局 socket API
// (全局 API 重连时会重复注册监听器,引发重连风暴)
console.log('[UniAppWebSocket] 发起连接:', this.url)
const rawConnect = (typeof wx !== 'undefined' && typeof wx.connectSocket === 'function')
? wx.connectSocket.bind(wx)
: uni.connectSocket
const task = rawConnect({ url: this.url })
// 部分平台 uni.connectSocket 无返回值,降级为全局 API 监听
if (task && typeof task.onOpen === 'function') {
this.socketTask = task
task.onOpen((res) => {
console.log('[UniAppWebSocket] 连接已打开(open)')
this.readyState = 1
this._flush()
if (typeof this.onopen === 'function') {
this.onopen({ type: 'open' })
}
})
task.onMessage((res) => {
if (typeof this.onmessage === 'function') {
// 与浏览器 MessageEvent 对齐:消息内容放在 event.data
this.onmessage({ type: 'message', data: res.data })
}
})
task.onClose((event) => {
// 诊断:打印关闭码/原因,用于判断是服务端拒连还是网络问题
// 常见 code1006 异常断开、1000 正常关闭;reason 由服务端给出
console.warn('[UniAppWebSocket] 连接被关闭(close) code:', event && event.code,
'reason:', event && event.reason)
this.readyState = 3
if (!this._closedByUser && typeof this.onclose === 'function') {
this.onclose(Object.assign({ type: 'close' }, event || {}))
}
})
task.onError((err) => {
// 诊断:微信会在 errMsg 中给出具体原因(域名不在合法列表、TLS 失败等)
console.warn('[UniAppWebSocket] 连接错误(error):', err && (err.errMsg || err.message || JSON.stringify(err)))
if (typeof this.onerror === 'function') {
this.onerror(Object.assign({ type: 'error' }, err || {}))
}
})
} else {
console.warn('[UniAppWebSocket] 未获得 SocketTask,降级到全局 socket API')
// 兜底:旧版小程序全局 socket API
uni.onSocketOpen(() => {
this.readyState = 1
this._flush()
if (typeof this.onopen === 'function') {
this.onopen({ type: 'open' })
}
})
uni.onSocketMessage((res) => {
if (typeof this.onmessage === 'function') {
this.onmessage({ type: 'message', data: res.data })
}
})
uni.onSocketClose((event) => {
this.readyState = 3
if (!this._closedByUser && typeof this.onclose === 'function') {
this.onclose(Object.assign({ type: 'close' }, event || {}))
}
})
uni.onSocketError((err) => {
if (typeof this.onerror === 'function') {
this.onerror(Object.assign({ type: 'error' }, err || {}))
}
})
}
}
/**
* 发送数据(与浏览器 WebSocket.send 签名一致)
* @param {string} data
*/
send(data) {
if (this.readyState !== 1) {
// 连接未就绪时暂存,连接建立后补发
this._sendQueue.push(data)
return
}
if (this.socketTask) {
this.socketTask.send({
data,
fail: (err) => {
console.warn('[UniAppWebSocket] 发送失败', err)
}
})
} else {
// 兜底:旧版小程序全局 socket API
uni.sendSocketMessage({
data,
fail: (err) => {
console.warn('[UniAppWebSocket] 发送失败', err)
}
})
}
}
/** 主动关闭连接(主动关闭不再触发 onclose,由 SDK 自行控制重连) */
close() {
this._closedByUser = true
this.readyState = 3
if (this.socketTask) {
this.socketTask.close({
complete: () => {}
})
this.socketTask = null
} else {
uni.closeSocket({
complete: () => {}
})
}
}
/** 连接建立后补发暂存消息 */
_flush() {
if (!this._sendQueue.length) return
const queue = [...this._sendQueue]
this._sendQueue = []
queue.forEach((data) => this.send(data))
}
}