chore:优化服务配置缓存逻辑,减少不必要的 API 调用;修复欢迎语加载逻辑,避免重复推送欢迎气泡;调整快捷问题样式以兼容低版本环境

This commit is contained in:
2026-09-20 15:45:12 +08:00
parent 8fd68033ed
commit ee20c214de
2 changed files with 48 additions and 2 deletions

View File

@@ -424,6 +424,18 @@ function disconnectWebSocket() {
}
// #endif
// PR-FIX (2026-09-20): getServiceConfig 短 TTL 缓存
// 服务配置(含欢迎语)变更频率极低, 每次进聊天页都打 /api/kefu/info 纯属浪费;
// TTL 60s + 失败不缓存, 配置保存后最多延迟 1 分钟生效
var _serviceConfigCache = null;
var _serviceConfigCacheAt = 0;
var SERVICE_CONFIG_CACHE_TTL = 60 * 1000;
function resetServiceConfigCache() {
_serviceConfigCache = null;
_serviceConfigCacheAt = 0;
}
export default {
/**
* 获取uniacid
@@ -872,6 +884,12 @@ export default {
* PR-7: URL 按 agent_id 路由
*/
async getServiceConfig() {
// PR-FIX (2026-09-20): 命中缓存直接返回
const nowTs = Date.now();
if (_serviceConfigCache && (nowTs - _serviceConfigCacheAt) < SERVICE_CONFIG_CACHE_TTL) {
console.log('[AI Service] getServiceConfig 命中缓存 (age=' + Math.round((nowTs - _serviceConfigCacheAt) / 1000) + 's)');
return _serviceConfigCache;
}
try {
const params = {
url: resolveApiUrl('info'),
@@ -901,6 +919,9 @@ export default {
} else {
console.warn('[AI Service] info 响应中未找到 config_uuid/config_uid/uuid 字段, 上传将缺少该参数。响应结构:', JSON.stringify(cfg));
}
// PR-FIX (2026-09-20): 成功响应写缓存 (失败不缓存, 下次重试)
_serviceConfigCache = response.data;
_serviceConfigCacheAt = Date.now();
return response.data;
} catch (error) {
console.error('[AI Service] getServiceConfig error:', error);
@@ -908,6 +929,14 @@ export default {
}
},
/**
* PR-FIX (2026-09-20): 清除服务配置缓存
* 供配置变更后主动调用 (目前 60s TTL 已足够, 预留显式失效入口)
*/
clearServiceConfigCache() {
resetServiceConfigCache();
},
/**
* 清除会话历史(调用后端接口)
* PR-7: URL 按 agent_id 路由

View File

@@ -1017,9 +1017,14 @@ export default {
// 加载欢迎语:优先 API,API 失败或禁用时用父页面传入的 fallbackWelcome
async _loadWelcomeMessage() {
// PR-FIX (2026-09-20): 防重入 (created 异步加载期间 mounted/loadHistoryIfNeeded
// 等路径再触发会造成欢迎气泡重复 push; 网络慢时尤其容易)
if (this._welcomeLoading) return
this._welcomeLoading = true
// 仅全新会话才需要欢迎语
if (this.currentConversationId) {
console.log('[AI Chat] 已有会话,跳过欢迎语')
this._welcomeLoading = false
return
}
@@ -1059,6 +1064,7 @@ export default {
console.log('[AI Chat] 使用降级欢迎语')
} else {
console.log('[AI Chat] 无可用欢迎语')
this._welcomeLoading = false
return
}
}
@@ -1081,6 +1087,7 @@ export default {
this.$nextTick(() => this.scrollToBottom())
this.$emit('ai-response', welcomeMsg)
}
this._welcomeLoading = false
},
// PR-WELCOME-QUICK-CHIPS (2026-09-19): 归一化 quick_questions 数据格式
@@ -1328,6 +1335,13 @@ async loadChatHistoryIfExist() {
if (!hasContent && !hasEmoji && !allPending.length) return
// PR-FIX (2026-09-20): 手动发送消息后清掉欢迎气泡上的快捷问题 chips
// 原来只有点击 chip 才摘除, 用户手动打字发消息后 chips 一直挂着,
// 与"引导一次性"的语义不符
this.messages.forEach(msg => {
if (msg.quickQuestions && msg.quickQuestions.length) msg.quickQuestions = []
})
// 待发送文件/视频/音频附件 (与图片一并带出给后端)
const fileAttachments = pendingFilesList
.filter(p => p.uploaded)
@@ -3890,18 +3904,20 @@ _handleStreamError(msg) {
}
// PR-WELCOME-QUICK-CHIPS (2026-09-19): 欢迎语配套快捷问题 chip 样式
// PR-FIX (2026-09-20): flex gap 在低版本微信基础库/部分安卓 WebView(小米) 不生效,
// 间距全部改用 margin 实现, 不依赖 gap
.quick-questions-row {
margin-top: 16rpx;
display: flex;
flex-wrap: wrap;
gap: 16rpx;
justify-content: flex-start;
max-width: 100%;
.quick-question-chip {
display: inline-flex;
align-items: center;
gap: 8rpx;
margin-right: 16rpx;
margin-bottom: 16rpx;
padding: 12rpx 24rpx;
background: #ffffff;
border: 1rpx solid #1E9FFF;
@@ -3916,6 +3932,7 @@ _handleStreamError(msg) {
.quick-question-icon {
font-size: 24rpx;
flex-shrink: 0;
margin-right: 8rpx;
}
.quick-question-text {