166a284359
Merge branch 'dev/1.0' of http://git.aigc-quickapp.com/Uniapp/lucky_shop into temp221
...
# Conflicts:
# .local.config.js
# common/js/ai-service.js
# common/js/media-upload.js
# docs/ai-agent-integration.md
# pages_tool/ai-chat/ai-chat-message.vue
# pages_tool/ai-chat/components/ai-chat-tools-panel.vue
# pages_tool/ai-chat/index.vue
2026-09-29 11:02:53 +08:00
4168c24fd6
feat(ai-chat): 增强位置消息处理,支持透传位置、时间、页面上下文,优化用户体验
2026-09-28 13:48:56 +08:00
306f2f7ff7
feat(voice-input): 改进音频消息处理,支持音频时长和指令文本,优化后端交互
2026-09-28 09:33:57 +08:00
fff10a2e19
feat(media-upload): 增加全量音视频格式支持,确保与后端一致
2026-09-24 18:03:08 +08:00
9d990e6aac
feat: implement voice input feature with press-and-hold gesture
...
- Added new language strings for voice input functionality in English and Chinese.
- Updated manifest to include microphone permission for voice recording.
- Enhanced ai-chat-message component to support voice input with visual feedback for recording and cancellation gestures.
- Integrated voice recorder functionality in ai-chat-voice-panel, allowing users to record audio with a maximum duration of 60 seconds.
- Implemented audio handling logic to upload recorded audio files and display them in the chat interface.
- Added error handling for voice recording failures and user notifications.
- Updated styles for improved UI/UX during voice recording interactions.
2026-09-24 17:47:37 +08:00
e079afc0a2
feat(media-upload): 增加自愈机制,自动切换 STS 直传以应对后端策略变化
2026-09-24 16:27:33 +08:00
70f8fb867d
feat(chat-ui): 增加聊天 UI 配置的本地持久化和预加载功能,优化首帧渲染体验
2026-09-24 11:10:21 +08:00
86b87eeb9d
feat(ai-chat): 聊天 UI 配置 V3 — 名称/头像/时间配置项消费
...
- CHAT_UI_DEFAULTS 同步后端 4 新键 (show_name/show_avatar/avatar/time_format/time_humanize)
- 标题与 AI 头像按开关显隐, 自定义头像 (素材库 pic_path / URL) 优先于内置
- formatTime 支持 auto(智能分段)/full(完整) 与 humanizeTime 相对时间优先 (刚刚/N分钟前/N小时前/昨天/前天/M月D日/Y年M月D日)
- i18n 中英各+5 键
2026-09-24 10:30:28 +08:00
297b545e55
fix(media-upload): alioss 直传 endpoint 缺 oss- 前缀修复
...
- sts.region 是简写 (cn-hangzhou), 真实 OSS endpoint 须完整形式 (oss-cn-hangzhou)
- 优先使用后端 sts.oss_url (OssProviderRegistry::buildDirectEndpoint 已拼好), 兜底 oss-${region} 拼接
2026-09-24 10:29:55 +08:00
bac5583ecb
强制合并
2026-09-22 10:52:56 +08:00
aefb0c1550
Merge branch 'temp221' of http://git.aigc-quickapp.com/Uniapp/lucky_shop into temp221
2026-09-21 08:53:52 +08:00
744981ed93
chore:添加 chat_ui_config 支持,优化前端 UI 行为开关;实现附件类型动态控制,确保与后端配置同步
2026-09-20 18:01:43 +08:00
ee20c214de
chore:优化服务配置缓存逻辑,减少不必要的 API 调用;修复欢迎语加载逻辑,避免重复推送欢迎气泡;调整快捷问题样式以兼容低版本环境
2026-09-20 15:45:12 +08:00
62b4b44f88
chore :真机可以支持测试
2026-09-20 14:06:28 +08:00
2b1f8a4fe2
chore:修复清除会话的 URL 格式,确保使用 camelCase,避免 404 错误;优化 agent 切换时的会话 ID 管理
2026-09-19 16:25:16 +08:00
67ce0f8b39
chore:更新 AI 服务会话管理逻辑,优化用户状态切换时的 key 迁移与会话隔离,确保 H5 端 elicitResponse 请求正常处理
2026-09-19 15:26:38 +08:00
29699a66fd
chore:AI智能输入框样式改变
2026-09-17 14:21:28 +08:00
8cfc144ba9
fix(frontend): 端用户附件走 inline base64 路径, 避开 MediaGuard SSRF 闸门
...
PR-FRONTEND-MEDIA-INLINE-BASE64 (2026-09-16)
PR-WB-MP-INBOUND-MEDIA 配套
症状: 用户在前端上传图片成功后 (OSS URL 已返回), AI Agent 仍回复
"我这边并没有收到或看到任何图片附件".
根因链路:
1. backend Upload.php::buildPublicUrl 用 request()->domain() 拼 URL
(LAN 部署返回 http://192.168.x.x:8050/upload/ ..., 公网部署返回公网域名)
2. 前端把 upload 响应直接透给 AI chat attachments[] 字段
3. backend MediaGuard::urlAllowed 把 192.168.x.x 当内网 IP
(FILTER_FLAG_NO_PRIV_RANGE) 拒绝 → attachments 整批丢
4. 静默失败: MediaGuard 在 '白名单过滤后空集' 时返回 ok=true + media=[]
→ Kefu.php 不 return error, 业务继续走
5. WB 收到 0 个 media block → Agent 看不到附件
修复:
- media-upload.js 新增 fileToBase64(filePath, opts) helper
- H5: fetch(blobUrl) → blob → FileReader.readAsDataURL → strip data: 前缀
- MP-WEIXIN/APP-PLUS: uni.getFileSystemManager().readFileSync(base64)
- SIZE_LIMIT_INLINE_BASE64 = 5MB, 与后端 INLINE_MEDIA_LIMIT 对齐
- 超限 / 失败返回 null, 调用方退回 URL 路径
- ai-chat-message.vue sendMessage 改为 await Promise.all 模式:
- 对每个 pending item 调 fileToBase64(tempPath) 拿 base64
- 把 data + encoding='base64' 注入 attachment
- enrichedPendingAttachments 同时用于 readyAttachments + userMessage.attachments
- 复用同一份 base64, 不重复读 file
后端接收 data 字段后整条链路已对齐:
- MessageMedia::normalizeInput 直接透传 data 字段
- MediaGuard::check data 非空时无条件放行, 不参与 URL 校验
- WbAgentOsClient::buildMediaBlocks (A 路) 路径 1 优先 data + image/audio
- WbAcpClient::buildMediaBlocks (B 路) data 非空也走 inline base64
- inline_media_sanity.php 39 个断言全部覆盖 (test 3.1, 3.2, 4.1, 4.2, 7.6)
测试:
- E2E test_inline_base64.py 10/10 通过
- mock 上传返回 LAN URL 模拟 MediaGuard 拦截场景
- 抓 /api/kefu/chat POST body, 验证 attachments[].data 是有效 PNG base64
- magic bytes 89504E47 验证通过
- 既有 test_ai_chat_upload.py 20/20 通过 (无回归)
边界:
- >5MB 图片 fileToBase64 返回 null, 退回 URL 路径 (buildMediaBlocks 走
路径 2 fetchInline / 路径 3 resource_link); LAN 部署下仍可能被 MediaGuard
拦截, 但 5MB 以下的图片(主流微信/支付宝截图等)不受影响
- H5/MINIProgram/APP 三端都加了 #ifdef 编译条件
2026-09-16 17:55:49 +08:00
065fba7cf8
fix(media-upload): H5 pathToFile 修复 multipart filename 缺扩展名
...
PR-FRONTEND-MEDIA-UPLOAD-FIX-HOTFIX (2026-09-16)
诊断: 直接打后端 (curl) 验证后端 ext_rule 完全 OK,
所有 jpg/png/heic 标准 mime 都返回 code:0, 只有 filename=空
(无扩展名) 才会被拒. 所以问题在前端.
定位: common/js/media-upload.js pathToFile() H5 分支:
原代码 filePath.split('/').pop() 对 blob:http://xxx/uuid
取出 'uuid' (无扩展名)
→ new File([blob], 'uuid', ...) 没有 .jpg/.png 后缀
→ multipart Content-Disposition: filename='uuid'
→ 后端 fileExt 规则检查 'uuid' 不在白名单 → 拒绝
修复: 提取 extractExt() 到模块顶层 (之前内联在 uploadViaSts 里),
pathToFile 调用 extractExt(filePath, blob.type) 三段兜底:
1) filePath 最后一段正则
2) filePath.name 兜底
3) blob.type mimeHint 反查 EXT_MIME_MAP → png/jpg/heic 等
修复后 multipart filename = 'test-img1.png' (有扩展名),
后端 ext_rule 通过, 上传成功.
E2E 验证 (verify_filename2.py):
- 修复前: filename='test-img2' → 后端拒绝
- 修复后: filename='test-img2.png' → 后端接受
教训: PR-FRONTEND-MEDIA-UPLOAD-FIX 加 extractExt 时只修了 STS 路径,
PHP 路径漏修; H5 blob URL + multipart 是双盲点 (前端不知道后端需要
filename 扩展名, 后端拿到 filename 才检查). 任何 file.toBlob() 或
URL.createObjectURL 出来的 file 都要在 File 构造时补扩展名.
2026-09-16 17:32:03 +08:00
fe2d3dcfe2
fix(ai-chat): 全面修复前端图片附件 4 个 P0 + 3 个 P1 + 3 个 P2 bug
...
PR-FRONTEND-MEDIA-UPLOAD-FIX (2026-09-16)
配合后端 PR-WB-MP-UPLOAD-EXT (HEIC/AVIF/BMP/TIFF 双层修复), 前端用户上传链路全面打通:
**4 个 P0 (阻塞用户上传)**:
- pendingImage 单数 → pendingImages 数组: 选 9 张图只发 1 张 → 全部一起发
- 每个图独立 localId 独立上传独立失败
- 失败给删除按钮 (用户不再卡死)
- MP-WEIXIN 不压缩 HEIC → H5+MP-WEIXIN 双端都压缩
- 微信 chooseImage 默认 compressed 不支持 HEIC, 必须本地 uni.compressImage
- getFileSize 失败兜底 0 → 失败抛错, 探测完全失败时兜底走 STS
- 0 > 2MB = false 让 auto 模式永远走 PHP 中转, 大文件 OOM
- 现: totallyUnknown → 兜底 STS
- guessMime 缺 HEIC 等 → 与后端 guessMimeFromPath 对齐 26 个 mime
**3 个 P1 (业务级)**:
- selectFile 微信小程序死按钮 → 加 #ifdef MP-WEIXIN 分支 (uni.chooseMessageFile/wx.chooseMessageFile)
- 兼容检测两个 API 哪个可用
- 上传失败后 pendingImage 永远卡住 → 失败时给 删除 按钮 (pending-retry-delete)
- URL.createObjectURL 永不释放 → upload 完成后 (成功/失败都) revokeObjectURL
**3 个 P2 (优化)**:
- filePath.split('.').pop() 在 blob URL 翻车 → 用 lastSegment + 正则提取 + 兜底 'bin'
- STS MP-WEIXIN size 永远 0 → 用已知 detectedSize + pathToFile 再探测
- H5 压缩阈值 10MB → 3MB
**新增**:
- tests/media-upload-fix.test.js (12 个单测全过): guessMime 现代格式 / extractExt blob URL / decideSts 兜底 STS 决策
2026-09-16 16:52:49 +08:00
78973c99a3
chore:
2026-09-16 16:38:34 +08:00
7952f5a722
feat(ai-chat): frontend 媒体上传/播放全栈接通 (PR-FRONTEND-MEDIA-UPLOAD 2026-09-16)
...
P0 — 新建 common/js/media-upload.js (12KB)
- uploadImage(filePath) / uploadMedia(filePath, kind) 落地
- 此前 ai-chat-tools-panel.vue 引用但文件从未入库, 选图立即抛 "Cannot find module"
- 12 cloud provider 分流: 4-field STS (alioss/qiniu/txcos/baidubos/qingstor/jdoss/ucloud/wyoss) vs single-URL signed PUT (huaweiobs/volcengine/awsoss/minio)
- 端点必须 addon namespace: /<addon>/api/upload/{image|file|ossSts}, 普通 /api/kefu/upload/* 不命中 InitRoute
- 补 docs 设计稿漏写的 `import store from '@/store/index.js'` (H5 上传需带 token)
P1 — ai-chat-message.vue 用户附件全支持
- P1.1 filter 不再丢 file/audio/video 消息
- P1.2 用户气泡加 type==='file' 分支: 文件图标 + 名称 + 大小 + 上传状态
- P1.3 sendMessage type 不再强制把 audio/video 折成 file
P2 — AI 侧 audio 播放引擎接通
- P2.1 previewAttachment audio 分支 → 跳 file-preview
- P2.2 音频气泡接 uni.createInnerAudioContext: data 加 innerAudioCtx/_innerAudioSrc, 改写 playAudio/pauseAudio, beforeDestroy 必 destroy, slider 区分 change (显示) / changeend (实际 seek)
- P2.3 file-preview.vue 加 image-viewer + audio-viewer 两个分支;inferFileType 识别 jpg/png/mp3/wav 等扩展
P3 — sendMessageWithContent 透传 attachments 参数
- 默认 attachments = [], 传给 sendStreamMessage/sendNormalMessage
- tools panel 选完文件 push 到 attachments → 链到 send
lang — zh-cn + en-us file-preview 加 4 项
- audioUrlNotExist / audioDefaultTitle / audioPlaying / audioPaused
docs — docs/ai-agent-integration.md (跨 PR 累积同步, 2149 行)
- 版本基线提到 PR-WB-MP-INLINE-MEDIA (2026-09-16) 及之后
- 加 §3.1.5 attachments.data 字段协议 (PR-WB-MP-INLINE-MEDIA)
- 12 cloud provider 替换原"阿里云"单点 (PR-OSS-REGISTRY)
- media-upload.js 章节补 fileToBase64 (PR-FRONTEND-MEDIA-UPLOAD)
- 上传策略表 backend/oss_sts/auto 全替换为"云存储"措辞
对齐后端:
- PR-WB-MP-INLINE-MEDIA (a707b90): media data 字段
- PR-OSS-REGISTRY (12 provider): OssProviderRegistry
- PR-FRONTEND-MEDIA-UPLOAD (本 commit): 前端落地
兼容性:
- 后端未升级到 PR-WB-MP-INLINE-MEDIA 之前, attachments 不带 data 字段, 走 URL 路径 (退化到老行为, 不破)
- 后端 oss_sts 单点 alioss 时, securityToken 不带 -SIGNED 后缀, 走 4-field STS 分支 (与 PR-OSS-REGISTRY 之前兼容)
回归:
- node --check media-upload.js OK
- lang zh ESM import OK, 输出 8 个 key 全对
- ai-chat-message.vue 11 处 PR-FRONTEND-MEDIA-UPLOAD 标记, file-preview.vue 9 处
- 旧 chat 路径不带 attachments 走默认 [], 不破坏现有响应结构
安全约束: 不涉及 nginx 层防盗链 / 限速
2026-09-16 11:42:18 +08:00
3f99a1b9e4
chore:AI回答显示思考...
2026-09-16 11:14:53 +08:00
782a26f446
chore:AI智能显示思考过程
2026-09-14 17:49:30 +08:00
3fffab81c8
chore:可以复制回答
2026-09-12 11:03:34 +08:00
429487b1d1
chore:微信小程序真机智能客服正常
2026-09-12 09:20:51 +08:00
f6038575cc
chore:表单弹窗正常
2026-08-29 16:04:20 +08:00
876f639bb5
chore:红色按钮不乱飘了
2026-08-20 18:26:59 +08:00
37463a173c
chore:一级分类的不选中的样式后台可以自定义
2026-08-15 10:37:55 +08:00
422ca8cdb5
Merge branch 'dev/1.0' of http://git.aigc-quickapp.com/Uniapp/lucky_shop into temp2797
2026-08-15 09:53:01 +08:00
a0043418c8
chore:
2026-08-15 09:46:12 +08:00
927f763d0a
chore:后台可以自定义配置一级分类选中后的字体颜色和字体大小
2026-08-15 09:28:15 +08:00
69ad814985
Merge remote-tracking branch 'remotes/origin/dev/1.0' into PR-1-ai-agent-link
2026-08-15 09:27:58 +08:00
19cb332645
refactor(ai-page): 统一页面路由管理并修复AI智能体路径
...
1. 将硬编码的页面路径替换为PAGE_KEY_MAP常量统一管理
2. 修正AI智能体页面路径为/pages_tool/ai-agent/index
3. 优化客服跳转逻辑,避免重复注入tabBar隐藏标记
4. 为AI聊天页面添加自定义组件占位配置
2026-08-14 09:36:04 +08:00
e5406a27ba
chore:苹果ios表单显示正常,商品详情的视频可以支持竖版横板视频
2026-08-14 09:09:07 +08:00
ffa170ff13
feat(ai): PR-7 前端 ai-service 按 agent_id 路由 endpoint
...
背景:
- 后端 aikefu 和 ai-agent 两个独立 addon (PR-6 v2.0)
- 前端 ai-chat 之前所有 API endpoint 都 hardcode 到 /api/kefu/* + /ws/aikefu
- 5 个 agent (智能客服默认 + 4 个 AI智能体) 实际上无法被前端独立路由
改动:
- 新增 resolveAddonName(agentId) -> 'aikefu' / 'aiagent'
- 新增 resolveApiUrl(apiName) -> '/api/kefu/X' / '/api/aiagent/X'
- 新增 resolveWsPath() -> '/ws/aikefu' / '/ws/aiagent'
- 全量替换 sendMessage / sendHttpStream / sendStreamMessage / generateConversationId /
getServiceStatus / getServiceConfig / clearConversation / getConversationHistory /
chatWithEventSource / WebSocket connect URL:
全部用 resolveApiUrl / resolveWsPath 动态计算
- setAgentId 跨 addon 切换时自动 disconnectWebSocket (路径变了)
- 新增 getAddonName() / getApiPrefix() 测试辅助方法
后端配套 PR-8+9:
- /api/aiagent/api/Chat/chat (HTTP, 含流式 SSE)
- /api/aiagent/api/Chat/{info,health,getHistory,clearConversation,createConversation}
- /ws/aiagent WebSocket 端点 (从 aikefu WebSocket 复制改名)
路由规则:
- agent_aikefu -> aikefu addon (老路径, 默认智能客服)
- 其他 agent (knowledge / quick_reply / sales / hr) -> aiagent addon (新路径)
Co-Authored-By: Claude <noreply@anthropic.com >
2026-08-13 18:30:00 +08:00
8a95b0310d
feat(ai-chat): 适配浮动按钮入口隐藏底部tabBar
...
实现浮动按钮跳转AI聊天页时自动隐藏底部tabBar,通过__dyu标记区分入口来源:
1. 浮动按钮点击时注入__dyu=FloatBtn来源标记
2. AI聊天页根据该标记临时隐藏tabBar并在卸载时恢复
3. 兼容旧store无对应mutation的场景
2026-08-12 18:18:19 +08:00
f656be789d
feat(ai-agent): 新增AI智能体通用支持框架
...
1. 新增多语言文案,适配AI智能体通用场景
2. 新增AI智能体页面路由常量与跳转逻辑
3. 改造AI聊天页面支持动态agent_id和页面标题
4. 升级AI服务层,支持多agent_id自动传递
2026-08-12 15:12:00 +08:00
bbef0ecf55
feat(util): add coerceBool function for parsing URL query booleans
...
添加专门用于处理URL查询参数的布尔值转换函数,解决直接使用Boolean转换字符串'false'、'0'时不符合预期的问题,兼容多种合法的布尔值参数写法。
2026-08-07 16:09:02 +08:00
1cda06573e
refactor: 移除旧的邀请码来源追踪逻辑
...
1. 删除App.vue中全局邀请码持久化逻辑与相关工具函数
2. 简化http请求的方法与请求头处理逻辑
3. 移除diy-form组件内的邀请码暂存、提交与展示逻辑
4. 清理不再使用的工具类邀请码辅助函数
2026-08-03 16:24:18 +08:00
0598f97efe
chore:修改了会员中心页面弹出【网络异常,请稍后重试】,无法获取推荐码。
2026-08-03 14:55:36 +08:00
cd91ff9d49
chore:邀请码初步更改
2026-08-03 14:19:21 +08:00
df9d45fc1d
refactor(mp-harmony): add HAR dependency checks and debug logs
...
1. add debug logs for diy component lifecycle and data flow
2. add required HAR dependency declarations for mp-harmony entry module
3. add har-deps config, validation script and documentation
2026-07-30 11:43:25 +08:00
3bbf8c9531
feat(http): 添加HTTP请求全链路日志打印
...
新增请求ID、耗时统计,打印请求参数、响应结果与失败信息,同时添加重试相关日志,完善各个接口的调用日志输出
2026-07-30 10:40:07 +08:00
ed8a316bc0
chore:
2026-07-24 17:20:34 +08:00
dac27ca43b
Merge branch 'dev/1.0' of https://git.aigc-quickapp.com/Uniapp/lucky_shop into dev/1.0
2026-07-24 16:40:27 +08:00
f5f893b445
refactor(splash&diy): 重构启动页逻辑,优化白屏问题
...
1. 统一全平台启动页为strict模式,仅在12s兜底超时才强制关闭
2. 新增网络自适应超时策略,根据网络环境调整兜底时长
3. 补充diy加载失败时的启动页关闭逻辑,避免严格模式下无限等待
4. 优化代码格式与注释,修复部分代码细节问题
2026-07-24 16:11:41 +08:00
45c0c2afb1
refactor(鸿蒙元服务): 适配鸿蒙平台隐私托管与启动屏时序优化
...
1. 适配鸿蒙元服务平台隐私托管,由系统自动弹出隐私弹窗,应用层不再弹出自建弹窗
2. 新增启动屏strict模式,鸿蒙场景下严格等待首页DIY渲染完成再关闭启动屏,避免白屏
3. 新增splash-state单元测试覆盖新旧模式与鸿蒙场景
4. 清理隐私相关冗余代码与注释,统一平台逻辑分支
2026-07-24 15:10:49 +08:00
3debab7291
chore:VR有返回箭头了
2026-07-23 18:27:34 +08:00
ff0d26908c
fix(member): 修复账号注销/退出登录后无法正常跳转到微信原生授权登录的问题
...
修复背景:
账号注销成功后, 用户被重定向到 native 登录页 (手机号+验证码表单风格, 像 H5),
而不是微信小程序原生授权登录 (ns-login 弹窗 + getPhoneNumber 授权).
此外, 微信小程序下短时间内连发 reLaunch 会触发 native 错误:
appLaunch with non-empty page stack
以及历史遗留的 navigateTo push 登录页 + 旧页面在栈中导致的死循环问题.
主要修复:
1. util.js redirectTo reLaunch 分支 (4 平台兼容):
- H5 平台: window.location.replace (真正清空 history, 避免 history.back + router.replace 假清栈)
- 小程序平台 (mp-weixin/mp-harmony/...): 加 300ms 全局跳转锁 + setTimeout(0) 包裹
解决 appLaunch with non-empty page stack 错误
- APP/其他: 保留原生 uni.reLaunch
2. util.js redirectTo 入口智能默认 (跨平台兜底):
- 目标 == LOGIN_PAGE_URL && mode 是默认 navigateTo && 没传 back 参数
→ 自动改成 reLaunch (避免注销后死循环)
- 显式传 mode 或带 back 参数的场景保持原行为 (不影响登录后回原页面)
3. member-public.js mixin 增强:
- getLoginEntryUrl(): 跨平台登录入口智能分流
微信小程序/鸿蒙/其他小程序 → INDEX_PAGE_URL (首页, 走 ns-login 原生授权弹窗)
H5/快应用/APP → LOGIN_PAGE_URL (原生登录页)
- redirectToLoginOnce(): 统一封装 clearLoginState + 跳登录入口, 带 800ms 组件级防抖锁
- logout / getCancelStatus 兜底 / submitCancelApply 三个地方都改用 redirectToLoginOnce()
4. 5 个注销/退出流程页面改造:
- cancelsuccess.vue / cancelstatus.vue / cancellation.vue / cancelrefuse.vue
/ assets.vue: 跳登录入口全部用 redirectToLoginOnce (不再直接 redirectTo(LOGIN_PAGE_URL))
- cancellation.vue / cancelrefuse.vue: 加 memberPublic mixin (原本没有)
5. 取消了在 pages/index/public/js/index.js 中 onShow 自动弹登录弹窗的尝试
(因触发 Vue 框架的 dataset of null pre-existing 错误, 改由其他途径处理)
测试覆盖 (300+ 测试用例全部通过):
- tests/member-cancel-flow.test.js (28 个测试, 9 个用户故事场景)
- tests/redirectTo-relaunch-h5.test.js (11 个测试, 9 个跨平台场景)
- tests/redirectTo-real.test.js (12 个)
- tests/util.test.js (30 个)
- 其他 8 个测试文件全部通过
2026-07-23 17:26:00 +08:00