Skip to content

Commit 88a3df4

Browse files
committed
feat: # v1.0.5 Change Log
--- ## ✨ 新功能 (Features) ### 页面与组件 - **页面恢复功能**: 添加 `usePageResume` hook,集成到聊天和智能体详情页 - **事件轮询系统**: 实现事件轮询功能,新增专用服务器模块和事件总线 - **HTML文件标题解析**: 在文件预览中增加 HTML 文件标题解析功能 - **会话执行状态检测**: 实现会话执行状态检测和管理功能 - **智能体历史记录分页**: 新增智能体历史记录分页加载组件 - **选项卡滑动切换**: 新增 `pane-tabs` 组件支持左右滑动切换标签功能 - **会话列表组件**: 新增会话列表组件,实现动态加载、下拉刷新和上拉加载更多功能 - **阿里云验证码集成**: 新增阿里云验证码页面并集成到登录流程以支持小程序 - **加载中图标**: 添加加载中图标以指示任务执行状态 - **登录状态控制**: 实现登录状态控制显示内容并优化数据加载时机 ### 文件相关 - **文件树下载功能**: 添加文件下载功能和按钮交互,支持导出整个项目的压缩包 - **文件链接支持**: 增加文件链接支持和提示功能 - **文件分享功能**: 添加文件分享功能支持 - **文件树弹窗**: 在输入框中添加工作台按钮,点击后打开文件树弹窗 --- ## 🐛 Bug 修复 (Bug Fixes) ### 聊天相关 - 修复输入框键盘适配及滚动条显示异常 - 发送新消息时取消订阅 `ChatFinished` 事件 - 创建新会话时取消订阅 `ChatFinished` 事件 - 优化 `ChatFinished` 事件订阅逻辑 - 修复页面切换时 SSE 定时器未清除问题 - 修复停止接口意外触发问题并重置按钮状态 - 修复会话接口重复调用问题 ### 文件预览 - 优化文件预览 URL 构建逻辑,统一使用 `baseUrl` 变量 - 修复文件预览 URL 编码问题,添加 `decodeURIComponent` 处理 - 修复小程序端文件预览链接获取逻辑并支持分享 - 修复文件预览页导入路径 ### 配置与系统 - 移除 easycom 强制 uvue 配置以支持 vue 组件 - 修复 uvue 文件格式化功能 - 修复微信登录后跳转路径编码错误 - 修复移动端软键盘导致底部空白问题 - 修复 H5 移动端软键盘弹起时底部白色空白问题 ### 其他 - 修复拼音处理逻辑,移除不常用的生僻字 - 过滤 batch 接口登录与消息提示相关逻辑 - 修改提示信息中的"您"为"你",以提高用户亲切感 - 文件预览参数调整 - 修复文件选择事件处理逻辑 --- ## ♻️ 重构 (Refactoring) - 移除不必要的会话数据清空逻辑并优化任务状态更新 - 使用枚举替代硬编码状态值 - 注释掉未登录检查逻辑 - 移除旧的文件预览相关库和页面 - 调整模块导入路径并优化列表滚动行为 - 更新文件树节点样式和下载图标 --- ## 🎨 样式优化 (Styles) - 优化输入框和图标容器样式布局 - 统一分割线边框样式 - 调整状态标签样式 - 格式化会话组件代码 - 调整执行中状态标签样式 --- ## 📝 其他 (Chores) - 添加 easycom 自动导入组件配置 - 移除阿里云验证码插件配置 - 去除调试日志输出 - 优化函数注释 --- ## 📊 变更统计 | 类型 | 数量 | |------|------| | 新功能 | 14 | | Bug 修复 | 18 | | 重构 | 6 | | 样式优化 | 5 | | 其他 | 4 |
1 parent 6aaac42 commit 88a3df4

File tree

46 files changed

+7494
-18634
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+7494
-18634
lines changed

.prettierrc

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
}
1515
}
1616
],
17-
"prettier.documentSelectors": ["!**/*.uvue", "!**/*.uts"],
1817
"vueIndentScriptAndStyle": true,
1918
"tabWidth": 2,
2019
"useTabs": false

App.uvue

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,33 @@
11
<script lang="uts">
22
import { CONVERSATION_PAYLOAD } from '@/constants/common.constants';
33
import { apiAgentComponentPageResultUpdate } from '@/servers/agentDev';
4+
import { initEventPolling, startEventPolling, stopEventPolling } from '@/hooks/useEventPolling';
45
// #ifdef MP-WEIXIN
56
import { htmlToMarkdown } from '@/utils/htmlToMarkdown';
67
// #endif
78

89
// #ifdef H5
910
function fix100vh() {
11+
// 检测是否有输入框聚焦(键盘可能弹起)
12+
const focusedElement = document.activeElement;
13+
const isInputFocused = focusedElement && (
14+
focusedElement.tagName === 'TEXTAREA' ||
15+
focusedElement.tagName === 'INPUT'
16+
);
17+
18+
// 如果有输入框聚焦(键盘弹起),不更新 --vh 变量,保持页面容器高度稳定
19+
// 这样可以防止输入框因页面高度变化而"飘起"
20+
if (isInputFocused) {
21+
return;
22+
}
23+
1024
let vh = window.innerHeight;
1125
if (window.visualViewport && window.visualViewport.height) {
1226
vh = Math.round(window.visualViewport.height);
1327
} else {
1428
vh = window.innerHeight;
1529
}
1630
document.documentElement.style.setProperty('--vh', `${vh}px`);
17-
18-
const isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
19-
20-
if (isIOS) {
21-
// 调整布局以适应键盘
22-
const activeElement = document.activeElement;
23-
24-
const isTextInput = activeElement && (
25-
activeElement.tagName === 'TEXTAREA' ||
26-
activeElement.tagName === 'INPUT'
27-
);
28-
29-
if (isTextInput) {
30-
// 滚动到活动元素
31-
activeElement.scrollIntoView({ behavior: 'smooth', block: 'center' });
32-
}
33-
}
3431
}
3532
fix100vh();
3633
window.addEventListener('resize', fix100vh);
@@ -83,13 +80,25 @@
8380
}
8481
})
8582
// #endif
86-
83+
84+
// 初始化全局事件轮询
85+
// H5: 自动监听 visibilitychange,切换标签页时自动暂停/恢复
86+
// 小程序: 需要依赖 onHide/onShow 手动控制
87+
initEventPolling();
8788
},
8889
onShow: function () {
8990
console.log('App Show')
91+
// #ifndef H5
92+
// 非 H5 端:从后台回到前台,恢复轮询(H5 由 visibilitychange 自动处理)
93+
startEventPolling();
94+
// #endif
9095
},
9196
onHide: function () {
9297
console.log('App Hide')
98+
// #ifndef H5
99+
// 非 H5 端:切换到后台,暂停轮询(H5 由 visibilitychange 自动处理)
100+
stopEventPolling();
101+
// #endif
93102
},
94103
// #ifdef APP-ANDROID || APP-HARMONY
95104
onLastPageBackPress: function () {
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
<template>
2+
<view class="captcha-a">
3+
<view id="captcha-element"></view>
4+
</view>
5+
</template>
6+
7+
<script lang="uts" setup>
8+
// 阿里云验证码配置类型定义
9+
interface AliyunCaptchaConfig {
10+
captchaSceneId: string; // 场景ID
11+
captchaPrefix: string; // 身份标
12+
openCaptcha?: boolean; // 是否开启验证码
13+
// 其他可能的配置项
14+
}
15+
16+
// 阿里云验证码初始化选项
17+
interface CaptchaOptions {
18+
SceneId: string; // 场景ID
19+
prefix: string; // 身份标
20+
mode: 'popup' | 'embed'; // 验证码模式:弹出式或嵌入式
21+
element: string; // 渲染验证码的元素
22+
button: string; // 触发验证码弹窗的元素
23+
captchaVerifyCallback: (param: any) => {
24+
captchaResult: boolean;
25+
bizResult: boolean;
26+
};
27+
onBizResultCallback: () => void;
28+
getInstance: (instance: any) => void;
29+
slideStyle?: {
30+
width: number;
31+
height: number;
32+
};
33+
language?: 'cn' | 'tw' | 'en'; // 验证码语言类型
34+
}
35+
36+
// 全局类型声明
37+
declare global {
38+
interface Window {
39+
initAliyunCaptcha: (options: CaptchaOptions) => void;
40+
}
41+
}
42+
43+
interface AliyunCaptchaProps {
44+
config: AliyunCaptchaConfig;
45+
elementId: string;
46+
// doAction: (captchaVerifyParam: any) => void;
47+
// onReady?: () => void; // 使用可选属性避免undefined调用
48+
}
49+
50+
const props = defineProps<AliyunCaptchaProps>()
51+
52+
const emit = defineEmits(['doAction', 'onReady'])
53+
// 验证码是否初始化完成
54+
const captchaInited = ref<boolean>(false)
55+
56+
// 使用useCallback缓存回调函数,避免不必要的重新渲染
57+
const captchaVerifyCallback = (captchaVerifyParam: any) => {
58+
emit('doAction', captchaVerifyParam);
59+
return {
60+
captchaResult: true,
61+
bizResult: true,
62+
};
63+
};
64+
65+
// 清理验证码相关DOM元素
66+
const cleanupCaptchaElements = () => {
67+
document.getElementById('aliyunCaptcha-mask')?.remove();
68+
document.getElementById('aliyunCaptcha-window-popup')?.remove();
69+
}
70+
71+
// 获取验证码实例
72+
const getInstance = (instance: any) => {
73+
if (instance) {
74+
captchaInited.value = true;
75+
}
76+
}
77+
78+
watch(captchaInited, (newVal) => {
79+
if (newVal) {
80+
emit('onReady');
81+
console.log('验证码初始化完成,onReady已调用');
82+
}
83+
})
84+
85+
// 初始化阿里云验证码
86+
const initCaptcha = () => {
87+
try {
88+
// 初始化验证码
89+
window.initAliyunCaptcha({
90+
SceneId: props.config.captchaSceneId, // 场景ID
91+
prefix: props.config.captchaPrefix, // 身份标
92+
mode: 'popup', // 验证码模式:弹出式
93+
element: '#captcha-element', // 渲染验证码的元素
94+
button: `#${props.elementId}`, // 触发验证码弹窗的元素
95+
captchaVerifyCallback, // 业务请求回调函数
96+
onBizResultCallback: () => {}, // 业务请求结果回调函数
97+
getInstance, // 绑定验证码实例函数
98+
slideStyle: {
99+
width: 360,
100+
height: 40,
101+
}, // 滑块验证码样式
102+
language: 'cn', // 验证码语言类型
103+
});
104+
} catch (error) {
105+
console.error('阿里云验证码初始化错误:', error);
106+
}
107+
};
108+
109+
watch(() => props.config, (newVal) => {
110+
if (newVal && newVal.openCaptcha) {
111+
initCaptcha();
112+
}
113+
}, { deep: true, immediate: true })
114+
115+
onUnmounted(() => {
116+
// 组件卸载时清理DOM元素
117+
cleanupCaptchaElements();
118+
});
119+
</script>
120+
121+
<style lang="scss" scoped>
122+
123+
</style>

components/chat-input-phone/chat-input-phone.uvue

Lines changed: 36 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@
7070
<!-- #ifdef MP-WEIXIN -->
7171
:maxlength="-1"
7272
<!-- #endif -->
73+
:disable-default-padding="true"
7374
>
7475
</textarea>
7576
<!-- 图标容器 -->
@@ -632,7 +633,7 @@
632633
// 权限被拒绝,引导用户手动开启
633634
uni.showModal({
634635
title: '需要录音权限',
635-
content: '录音功能需要访问您的麦克风,请在设置中允许录音权限',
636+
content: '录音功能需要访问你的麦克风,请在设置中允许录音权限',
636637
confirmText: '去设置',
637638
success: (res) => {
638639
if (res.confirm) {
@@ -853,21 +854,38 @@
853854

854855
.input {
855856
width: 480rpx;
856-
min-height: 44rpx;
857-
line-height: 32rpx;
858-
max-height: 308rpx;
859-
// padding: 22rpx 16rpx 22rpx 32rpx;
860-
padding: 18rpx 64rpx 14rpx 32rpx;
857+
// width: 90%;
858+
// min-height: 44rpx;
859+
// line-height: 32rpx; // 过小导致闪烁
860+
line-height: 44rpx; // 恢复正常行高
861+
max-height: 320rpx;
862+
margin: 10rpx 0 10rpx 10rpx;
863+
// 彻底移除垂直 padding,消除底部留白
864+
padding: 0 10rpx;
861865
border: none;
862866
font-size: 32rpx;
863867
font-weight: 400;
864868
color: #000;
865869
box-sizing: border-box;
866870
resize: none;
867871
outline: none;
872+
873+
// #ifndef MP-WEIXIN
874+
// 允许纵向滚动,但隐藏滚动条样式 (H5等)
875+
overflow-y: auto;
876+
// #endif
868877

869878
&.input-text {
870-
width: 100%;
879+
width: 87%;
880+
}
881+
882+
// 隐藏滚动条 - 兼容各浏览器
883+
scrollbar-width: none; // Firefox
884+
-ms-overflow-style: none; // IE/Edge
885+
&::-webkit-scrollbar {
886+
display: none;
887+
width: 0;
888+
height: 0;
871889
}
872890
}
873891

@@ -880,15 +898,20 @@
880898

881899
.icon-container {
882900
position: absolute;
883-
right: 16rpx;
884-
bottom: 20rpx;
901+
right: 0rpx;
902+
bottom: 0rpx;
885903
display: flex;
886904
flex-direction: row;
887905
align-items: center;
888906
flex-shrink: 0;
889-
gap: 32rpx;
890-
height: 50rpx;
907+
// gap: 32rpx;
908+
// height: 50rpx;
891909
z-index: 50;
910+
background-color: #fff;
911+
912+
.iconfont{
913+
padding: 15rpx;
914+
}
892915

893916
.icon-image {
894917
color: #5147FF
@@ -907,12 +930,12 @@
907930
gap: 16rpx;
908931

909932
.input {
910-
width: 100%;
933+
width: 87%;
911934
line-height: 44rpx;
912935
}
913936

914937
.icon-container {
915-
position: inherit;
938+
// position: inherit;
916939
align-self: flex-end; // Align icons to right or adjust as needed
917940
flex-direction: row;
918941
justify-content: flex-end;

0 commit comments

Comments
 (0)