你好,麻烦提供出现问题的具体机型、微信版本号、系统版本号,以及能复现问题的代码片段(https://developers.weixin.qq.com/miniprogram/dev/devtools/minicode.html)
ios端保存视频超过10M就报错https://developers.weixin.qq.com/miniprogram/dev/api/media/video/wx.saveVideoToPhotosAlbum.html
03-13目前正在灰度3.7.11
小程序基础库3.7.9, 3.7.10导致小程序大量报错[图片][图片] 微信小程序基础库:3.7.9 ,3.7.10版本在有数小程序存在以下问题: a.首页存在组件加载异常和未完成加载; b.弹窗存在无法关闭(签到、广告、切换最近门店) c.控制台存在大量未知错误 影响的基础库:小程序基础库3.7.9, 3.7.10影响范围:非所有用户,只有使用了基础库3.7.9, 3.7.10版本的用户解决措施:目前已经测试3.7.11版本真机测试正常使用;解决时间:需要微信加快推送3.7.11版本解决问题
03-13你好,麻烦提供出现问题的具体机型、微信版本号、系统版本号,以及能复现问题的代码片段(https://developers.weixin.qq.com/miniprogram/dev/devtools/minicode.html)
小程序分包页面扫码进入页面偶尔拉不到最底,显示不全,是什么原因?[图片][图片] 小程序分包页面扫码进入,这是第二个页面,页面偶尔拉不到最底, 最底大概有140rpx的内容不显示,真机才会出现,按钮并未用代码控制显隐,页面并没有用scroll-view,也没有写死高度 做过以下尝试均没用,仍会偶尔出现内容显示不全,拉不到最底 1、把页面代码全删掉,用文本替代,内容是超过一页的,仍出现也就是并非是input组件代码引起的 2、修改页面布局。外框flex竖向排版,高度100vh,滚动区高度flex:1, 按钮固定在底部,仍出现按钮超出界面外 3、打印外框的高度,正常和异常的高度都是一样的
03-13用户网络切换后容易出现这种问题,Wi-Fi切流量、流量切Wi-Fi
{ errno :600001...t:fail 10007: } 报错?网络请求报这个错是什么原因
03-13请具体描述问题出现的流程,并提供能复现问题的简单代码片段(https://developers.weixin.qq.com/miniprogram/dev/devtools/minicode.html)。
WebGL2安卓上部分API返回值类型错误目前发现的一个是 getProgramParameter(program, LINK_STATUS) 时会返回0或1,而WebGL2规范应该是返回boolean。这导致部分第三方库无法正常工作。 大概率还有其他类似API也有问题,也可能WebGL也有问题不止WebGL2,我没有做更多测试。
03-12你好,麻烦提供出现问题的具体机型、微信版本号、系统版本号,以及能复现问题的代码片段(https://developers.weixin.qq.com/miniprogram/dev/devtools/minicode.html)
onShareAppMessage转发不传imageUrl,使用默认图片发送出来展示不对?[图片]如图所示,展示的卡片和打开的内容对应不上。 如图2[图片]转发到企业微信上封面又是对的。 使用onShareAppMessage没有传imageUrl。请问各位大佬这是什么神奇的问题
03-12请具体描述问题出现的流程,并提供能复现问题的简单代码片段(https://developers.weixin.qq.com/miniprogram/dev/devtools/minicode.html)。
CameraContext.startRecord/stopRecord调用fail在已经开启了摄像头和麦克风授权的前提下,以下几种情况都出现过: 1、CameraContext.startRecord调用走fail 2、CameraContext.stopRecord调用走fail(录制很正常时长的视频长度,没有过短或者过长) 3、<camera binderror="binderror"></camera>触发了binderror 请问这个功能api,目前手机兼容性有百分之多少呢,目前客户使用量还是挺大的,有些手机机型用不了。其中一个例子:华为畅享60x
03-12此类消息目前不予开通长期订阅,请采用其他方式进行通知
【订阅消息】申请长期订阅消息模版?【小程序主体】郑州威科姆科技股份有限公司 【申请模板类目】工具 > 设备管理 【申请模板名称】设备告警通知 【使用场景】告警 【模板字段】告警类型、告警时间、备注说明 【消息示例】 设备告警提醒 通知内容:设备异常震动 告警时间:2025-03-11 09:00:00 备注说明:您的设备发生异常震动疑似被盗
03-12你好,麻烦提供现网复现的路径或者能复现问题的代码片段(https://developers.weixin.qq.com/miniprogram/dev/devtools/minicode.html)
ios webview 返回后白屏前面添加了几个页面栈 然后跳转到了webview页面,然后从webview页面点击返回按钮再点击几个页面栈进入返回上一页出现白屏,白屏后上面会出现返回按钮再点击返回按钮再返回到首页依然白屏。 但是如果跳转到webview页面后点上面的返回是不会出现,需要触发webview内的返回事件才会出现。
03-12你好,请移步企微官方讨论区:https://developer.work.weixin.qq.com/community/question
在企业微信小程序无法使用websocket,同样的代码在微信小程序中是正常的,请帮忙指教一下?<template> <view class="ai-chat-container"> <view class="header"> <text class="title">多轮对话</text> </view> <view class="input-group"> <view class="input-row"> <input type="text" v-model="userId" placeholder="用户ID (必填)" /> <input type="text" v-model="userName" placeholder="用户名称" /> <input type="text" v-model="sessionid" placeholder="会话ID" /> </view> <view class="input-row"> <input type="text" v-model="collection" placeholder="知识库名称(可选)" /> </view> <view class="input-row"> <textarea v-model="messageInput" placeholder="输入您的问题(支持多行输入)" class="message-input" /> </view> <button @click="handleSend" :disabled="isProcessing" class="send-btn">发送请求</button> </view> <view class="response-container"> <text>{{ responseBuffer }}</text> </view> <view class="status-bar"> <text>连接状态:{{ connectionStatus }}</text> </view> <view v-if="errorMessage" class="error-message"> <text>{{ errorMessage }}</text> </view> </view> </template> <script> import { ref, onMounted, onUnmounted } from 'vue'; import StompWx from '@/utils/stomp-wx.js'; export default { name: 'AIChat', setup() { // 状态变量 const userId = ref('Q1100325'); const userName = ref('macroswang'); const sessionid = ref('6624663456435635463456435'); const collection = ref(''); const messageInput = ref('你好'); const responseBuffer = ref(''); const connectionStatus = ref('未连接'); const errorMessage = ref(''); const isProcessing = ref(false); // STOMP客户端 let stompClient = null; let currentSubscription = null; let currentUserId = null; // 添加心跳检测机制 let heartbeatInterval = null; // 连接WebSocket const connectWebSocket = async (userIdValue) => { return new Promise((resolve, reject) => { // 如果已连接且用户ID相同,直接复用连接 if (stompClient && stompClient.connected && currentUserId === userIdValue) { resolve(); return; } // 断开旧连接(如果存在) if (stompClient && stompClient.connected) { stompClient.disconnect(); } // 创建新连接 const wsUrl = import.meta.env.VITE_APP_BASE_WEBSOCKET_HOST; console.log("WebSocket URL:", wsUrl); // 确保URL使用wss协议(企业微信要求) const secureWsUrl = wsUrl.replace('ws://', 'wss://'); // 检测是否在企业微信环境 let isEnterpriseWx = false; let cropId = ''; // 基础请求头 const headers = { 'userId': userIdValue, 'crop_id':'ww40f48251ec0cd3b2', 'Authorization': 'eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJcImFIWkJoYUJGaWNkR0NkRVhYbVU3UUtNMTZUVFwiIiwiZXhwIjoxNzQyMDE3OTA5fQ.yx4vkjbZEDt_den6V04CXSPAPD9qiyix4apJlzM4SXE' }; // 添加其他企业微信可能需要的头信息 headers['x-client-type'] = 'wxwork'; headers['x-client-version'] = '1.2'; console.log("创建连接,使用头信息:", headers); // 创建STOMP客户端,针对企业微信环境优化配置 stompClient = new StompWx(secureWsUrl, { headers, // 企业微信环境下的特殊配置 heartbeat: { outgoing: isEnterpriseWx ? 5000 : 10000, // 企业微信环境下更频繁的心跳 incoming: isEnterpriseWx ? 5000 : 10000 }, debug: true, // 添加重连配置 reconnectDelay: isEnterpriseWx ? 2000 : 5000, maxReconnectAttempts: isEnterpriseWx ? 10 : 5 }); console.log("STOMP客户端创建完成,准备连接"); // 减少连接超时时间 let connectionTimeout = setTimeout(() => { if (!stompClient.connected) { console.error("WebSocket连接超时"); showError("连接超时,正在重试..."); // 超时后自动重试一次 clearTimeout(connectionTimeout); stompClient.disconnect(); // 短暂延迟后重试 setTimeout(() => { console.log("尝试重新连接..."); // 使用新的客户端重试 stompClient = new StompWx(secureWsUrl, { headers, heartbeat: { outgoing: 5000, // 进一步减少心跳间隔 incoming: 5000 }, debug: true }); stompClient.connect(() => { console.log("重试连接成功"); currentUserId = userIdValue; updateStatus('已连接(重试成功)'); setupSubscription(userIdValue); resolve(); }, (retryError) => { console.error("重试连接失败:", retryError); showError(`连接失败,请检查网络环境或刷新页面`); reject(new Error("重试连接失败")); }); }, 2000); } }, isEnterpriseWx ? 8000 : 10000); // 企业微信环境下超时时间更短 console.log("开始连接WebSocket..."); stompClient.connect(() => { console.log("WebSocket连接成功"); clearTimeout(connectionTimeout); currentUserId = userIdValue; updateStatus('已连接'); setupSubscription(userIdValue); resolve(); }, (error) => { // 添加错误回调 console.error("连接错误:", error); clearTimeout(connectionTimeout); showError(`连接失败: ${error?.headers?.message || '未知错误'}`); setTimeout(() => { updateStatus('正在重连...'); connectWebSocket(userIdValue).catch(err => { console.error("重连失败:", err); }); }, 3000); reject(error); }); }); }; // 设置消息订阅 const setupSubscription = (userIdValue) => { if (currentSubscription) { try { stompClient.unsubscribe(currentSubscription); } catch (e) { console.warn("取消订阅失败:", e); } currentSubscription = null; } const sessionidValue = sessionid.value.trim(); console.log("检查订阅" + sessionidValue); const destination = '/user/' + sessionidValue + '/topic/data'; console.log("准备订阅:", destination); try { currentSubscription = stompClient.subscribe(destination, (message) => { console.log("收到消息:", message); // 添加消息接收检测 if (!message) { console.warn("接收到空消息"); return; } if (!message.content) { console.warn("消息内容为空:", message); // 尝试解析消息体 try { const body = message.body || message.data; if (body) { handleStreamMessage(body); return; } } catch (e) { console.error("解析消息失败:", e); } return; } handleStreamMessage(message.content); }); // 添加订阅确认日志 console.log("已订阅目标:", destination, "订阅ID:", currentSubscription); // 发送一个测试消息确认连接状态 setTimeout(() => { if (stompClient && stompClient.connected) { console.log("发送测试消息"); try { stompClient.send("/app/ping", JSON.stringify({ userId: userIdValue, timestamp: Date.now() }), {}); } catch (e) { console.error("发送测试消息失败:", e); } } else { console.warn("无法发送测试消息,连接未就绪"); } }, 1000); } catch (e) { console.error("订阅失败:", e); showError("订阅失败,请重试"); } }; // 处理发送请求 const handleSend = async () => { const requestData = validateInputs(); if (!requestData) return; try { // 确保连接的是当前用户 if (currentUserId !== requestData.userId) { await connectWebSocket(requestData.userId); } isProcessing.value = true; updateStatus('连接中...'); if (!stompClient || !stompClient.connected) { await connectWebSocket(requestData.userId); } sendRequest(requestData); clearResponse(); } catch (error) { showError(`请求失败: ${error.message}`); resetState(); } }; // 验证输入 const validateInputs = () => { const userIdValue = userId.value.trim(); const messageValue = messageInput.value.trim(); if (!userIdValue) { showError("用户ID不能为空"); return null; } if (!messageValue) { showError("消息内容不能为空"); return null; } return { userId: userIdValue, userName: userName.value.trim() || '匿名用户', messages: [{ role: "user", content: messageValue }], sessionid: sessionid.value.trim(), collection: collection.value.trim() }; }; // 发送请求体 const sendRequest = (data) => { const headers = { 'userId': data.userId, }; stompClient.send("/app/streamData", JSON.stringify(data), headers); updateStatus('等待响应...'); }; // 处理流式响应 const handleStreamMessage = (chunk) => { console.log("收到数据块:", chunk); if (!chunk) { console.warn("收到空数据块"); return; } if (chunk === '流数据发送完毕') { finalizeResponse(); console.log("发送完毕"); return; } // 尝试解析JSON格式的消息 try { const jsonData = JSON.parse(chunk); if (jsonData.content) { responseBuffer.value += jsonData.content; return; } } catch (e) { // 不是JSON格式,按普通文本处理 } responseBuffer.value += chunk; }; // 完成处理 const finalizeResponse = () => { updateStatus('响应完成'); console.log('完整响应内容:', responseBuffer.value); resetState(); }; // 重置状态 const resetState = () => { isProcessing.value = false; }; // 清空响应区 const clearResponse = () => { responseBuffer.value = ''; }; // 更新状态显示 const updateStatus = (text) => { connectionStatus.value = text; }; // 显示错误信息 const showError = (message) => { errorMessage.value = message; setTimeout(() => { errorMessage.value = ""; }, 5000); }; onMounted(() => { // 设置心跳检测,保持连接活跃 heartbeatInterval = setInterval(() => { if (stompClient && stompClient.connected) { try { stompClient.send("/app/heartbeat", JSON.stringify({ timestamp: Date.now(), userId: userId.value }), {}); console.log("发送心跳"); } catch (e) { console.error("发送心跳失败:", e); // 心跳失败,尝试重连 if (currentUserId) { console.log("心跳失败,尝试重连"); connectWebSocket(currentUserId).catch(err => { console.error("心跳重连失败:", err); }); } } } }, 15000); // 减少到15秒 }); // 组件卸载时断开连接 onUnmounted(() => { if (heartbeatInterval) { clearInterval(heartbeatInterval); } if (stompClient && stompClient.connected) { stompClient.disconnect(); currentUserId = null; } }); return { userId, userName, sessionid, collection, messageInput, responseBuffer, connectionStatus, errorMessage, isProcessing, handleSend }; } }; </script> <style> .ai-chat-container { font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", sans-serif; max-width: 750rpx; margin: 20rpx auto; padding: 20rpx; background-color: #f5f5f5; } .header { margin-bottom: 20rpx; } .title { font-size: 36rpx; font-weight: bold; } .input-group { margin-bottom: 20rpx; background: white; padding: 20rpx; border-radius: 8rpx; box-shadow: 0 2rpx 4rpx rgba(0, 0, 0, 0.1); } .input-row { margin: 10rpx 0; display: flex; gap: 10rpx; } input { flex: 1; padding: 16rpx; border: 1rpx solid #ddd; border-radius: 4rpx; min-width: 120rpx; } .message-input { width: 100%; min-height: 120rpx; padding: 20rpx; border: 1rpx solid #ddd; border-radius: 4rpx; } .send-btn { padding: 20rpx 40rpx; background: #2196F3; color: white; border: none; border-radius: 4rpx; margin-top: 10rpx; } .send-btn:active { background: #1976D2 } .response-container { background: white; padding: 20rpx; border-radius: 8rpx; min-height: 400rpx; max-height: 1000rpx; overflow-y: auto; white-space: pre-wrap; box-shadow: 0 2rpx 4rpx rgba(0, 0, 0, 0.1); line-height: 1.6; } .status-bar { margin-top: 15rpx; color: #666; font-size: 28rpx; } .error-message { color: #f44336; margin: 10rpx 0; font-size: 28rpx; } </style> // 新版导入方式 import { Client } from '@stomp/stompjs' import '@/utils/text-encoder-polyfill.js' // 微信小程序 WebSocket 适配器 class WxWebSocket { constructor(url) { this.url = url this.socketTask = null this.onopen = null this.onmessage = null this.onclose = null this.onerror = null } connect() { try { console.log('正在连接到 WebSocket:', this.url) this.socketTask = uni.connectSocket({ url: this.url, header: { 'content-type': 'application/json' }, success: () => console.log('WebSocket 连接请求已发送'), fail: err => { console.error('WebSocket 连接失败', err) if (this.onerror) this.onerror(err) } }) if (this.socketTask) { this.socketTask.onOpen(() => { console.log('WebSocket 已打开,准备触发 onopen 事件') if (this.onopen) { console.log('调用 onopen 回调') this.onopen({ target: this }) } }) this.socketTask.onMessage(res => { console.log('WebSocket 收到消息:', typeof res.data, res.data.length > 100 ? res.data.substring(0, 100) + '...' : res.data) // 确保消息数据是字符串 let messageData = res.data if (typeof messageData !== 'string') { try { // 如果是对象,尝试转换为字符串 messageData = JSON.stringify(messageData) } catch (e) { console.error('消息数据转换失败:', e) } } if (this.onmessage) { this.onmessage({ data: messageData, target: this }) } }) this.socketTask.onClose(() => { console.log('WebSocket 已关闭') if (this.onclose) { this.onclose({ target: this }) } }) this.socketTask.onError(err => { console.error('WebSocket 错误:', err) if (this.onerror) { this.onerror({ error: err, target: this }) } }) } else { console.error('WebSocket 任务创建失败') if (this.onerror) { this.onerror({ error: new Error('WebSocket 任务创建失败'), target: this }) } } } catch (error) { console.error('WebSocket 连接过程中发生异常:', error) if (this.onerror) { this.onerror({ error, target: this }) } } } send(data) { console.log('发送数据:', typeof data, data.length > 100 ? data.substring(0, 100) + '...' : data) if (this.socketTask) { this.socketTask.send({ data, success: () => console.log('数据发送成功'), fail: err => { console.error('发送消息失败', err) if (this.onerror) { this.onerror({ error: err, target: this }) } } }) } else { console.error('无法发送数据:socketTask 不存在') } } close() { if (this.socketTask) { this.socketTask.close({ success: () => console.log('WebSocket 关闭成功'), fail: err => console.error('WebSocket 关闭失败', err) }) } } addEventListener(event, callback) { console.log('添加事件监听器:', event) if (event === 'open') { this.onopen = callback } else if (event === 'message') { this.onmessage = callback } else if (event === 'close') { this.onclose = callback } else if (event === 'error') { this.onerror = callback } } removeEventListener(event, callback) { console.log('移除事件监听器:', event) if (event === 'open' && this.onopen === callback) { this.onopen = null } else if (event === 'message' && this.onmessage === callback) { this.onmessage = null } else if (event === 'close' && this.onclose === callback) { this.onclose = null } else if (event === 'error' && this.onerror === callback) { this.onerror = null } } } // StompWx 类 - 包装 STOMP 客户端 class StompWx { constructor(url, options = {}) { this.url = url this.options = options this.client = null this.connected = false this.callbacks = { connect: [], error: [], disconnect: [] } this.subscriptions = {} this._init() } _init() { // 创建自定义的 WebSocket 适配器 const webSocketFactory = () => { console.log('创建 WebSocket 连接...') const socket = new WxWebSocket(this.url) socket.connect() return socket } this.client = new Client({ webSocketFactory, connectHeaders: this.options.headers || {}, debug: str => console.log('[STOMP]', str), reconnectDelay: 5000, heartbeatIncoming: 4000, heartbeatOutgoing: 4000 }) this.client.onConnect = frame => { console.log('✅ STOMP 连接成功', frame) this.connected = true this.callbacks.connect.forEach(callback => callback(frame)) } this.client.onStompError = frame => { console.error('❌ STOMP 连接错误', frame) this.callbacks.error.forEach(callback => callback(frame)) } this.client.onDisconnect = () => { console.log('STOMP 连接已断开') this.connected = false this.callbacks.disconnect.forEach(callback => callback()) } } connect(callback) { if (callback) { this.callbacks.connect.push(callback) } if (!this.client.active) { console.log('激活 STOMP 客户端...') this.client.activate() } else if (this.connected) { // 如果已经连接,直接调用回调 callback && callback() } return this } disconnect(callback) { if (callback) { this.callbacks.disconnect.push(callback) } if (this.client.active) { this.client.deactivate() } return this } subscribe(destination, callback, headers = {}) { const id = Math.random().toString(36).substring(2, 15) const doSubscribe = () => { if (!this.connected) { console.warn('尚未连接,订阅将在连接后进行') return } console.log(`订阅主题: ${destination}`) const subscription = this.client.subscribe( destination, message => { console.log('收到订阅消息:', message) try { // 尝试解析 JSON const body = message.body let data try { data = JSON.parse(body) } catch (e) { data = body } callback({ id: message.headers.id, content: data }) } catch (error) { console.error('处理订阅消息时出错:', error) callback({ error: error.message }) } }, headers ) this.subscriptions[id] = subscription console.log('订阅成功,ID:', id) } if (this.connected) { doSubscribe() } else { // 如果尚未连接,添加连接回调 this.callbacks.connect.push(doSubscribe) } return id } unsubscribe(id) { if (this.subscriptions[id]) { this.subscriptions[id].unsubscribe() delete this.subscriptions[id] console.log('取消订阅成功,ID:', id) } } send(destination, body, headers = {}) { if (!this.connected) { console.error('未连接,无法发送消息') return false } try { console.log('发送消息到:', destination) // 确保 body 是字符串 let messageBody = body if (typeof body === 'object') { messageBody = JSON.stringify(body) } this.client.publish({ destination: destination, headers: headers, body: messageBody }) console.log('消息发送成功') return true } catch (error) { console.error('发送消息失败:', error) return false } } onError(callback) { if (callback) { this.callbacks.error.push(callback) } return this } } export default StompWx
03-11