mirror of
https://wget.la/https://github.com/Wxw-Gu/WechatExplorer
synced 2026-08-17 19:47:08 +08:00
fix: 修复日报成员名称与图片识别兼容性
This commit is contained in:
@@ -9,7 +9,7 @@ macOS / Windows 微信聊天记录查看,AI 一键生成群聊总结。
|
|||||||
|
|
||||||
在微信 4.0 数据库解析、解密思路上,项目参考了 [WeFlow](https://github.com/hicccc77/WeFlow) 等开源项目的实现方式;此项目围绕我自己的使用场景做的定制化工具,重点放在本地聊天记录查看、群聊总结和个人工作流集成上。
|
在微信 4.0 数据库解析、解密思路上,项目参考了 [WeFlow](https://github.com/hicccc77/WeFlow) 等开源项目的实现方式;此项目围绕我自己的使用场景做的定制化工具,重点放在本地聊天记录查看、群聊总结和个人工作流集成上。
|
||||||
|
|
||||||
> 当前版本:`v2.1.0`。macOS 支持相对稳定;Windows 已初步支持微信 4.0 数据库连接、自动获取密钥和聊天记录查看,仍在持续兼容不同微信版本与本地目录结构。
|
> 当前版本:`v2.1.2`。macOS 支持相对稳定;Windows 已初步支持微信 4.0 数据库连接、自动获取密钥和聊天记录查看,仍在持续兼容不同微信版本与本地目录结构。
|
||||||
|
|
||||||
## ✨ 功能特性
|
## ✨ 功能特性
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -556,9 +556,9 @@ app.whenReady().then(async () => {
|
|||||||
if (!provider || !model) {
|
if (!provider || !model) {
|
||||||
return { success: false, error: '当前 AI 模型不存在' }
|
return { success: false, error: '当前 AI 模型不存在' }
|
||||||
}
|
}
|
||||||
if (!model.capabilities.vision) {
|
// Capability metadata is stored per machine. A model verified on macOS
|
||||||
return { success: false, error: '当前模型不支持图片理解' }
|
// may still be unmarked on Windows, so do not reject before making the
|
||||||
}
|
// real multimodal request. The provider response remains authoritative.
|
||||||
// request 来自 renderer,imageHash 是 md5(优先)或 sha256(...),dataUrl 在内部算出
|
// request 来自 renderer,imageHash 是 md5(优先)或 sha256(...),dataUrl 在内部算出
|
||||||
// 这里直接调 service,dataUrl 由 renderer 通过 window.api.getImage 拿到再传进来
|
// 这里直接调 service,dataUrl 由 renderer 通过 window.api.getImage 拿到再传进来
|
||||||
return imageInsightService.analyze(request)
|
return imageInsightService.analyze(request)
|
||||||
|
|||||||
@@ -195,6 +195,9 @@ export class AIProviderService {
|
|||||||
const imageError = validateVisionImage(imagePart.dataUrl)
|
const imageError = validateVisionImage(imagePart.dataUrl)
|
||||||
if (imageError) throw new Error(imageError)
|
if (imageError) throw new Error(imageError)
|
||||||
const result = await this.request(messages as AIMessage[], options)
|
const result = await this.request(messages as AIMessage[], options)
|
||||||
|
if (options?.providerId && options.modelId) {
|
||||||
|
this.markCapabilities(options.providerId, options.modelId, { vision: true, ocr: true })
|
||||||
|
}
|
||||||
return { success: true, ...result }
|
return { success: true, ...result }
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return { success: false, error: safeAIError(error) }
|
return { success: false, error: safeAIError(error) }
|
||||||
|
|||||||
@@ -175,13 +175,18 @@ const applyGroupMemberNames = async (
|
|||||||
const member = memberMap.get(senderId)
|
const member = memberMap.get(senderId)
|
||||||
if (!member) return message
|
if (!member) return message
|
||||||
const preferredNames: Record<ReportMemberNamePreference, string[]> = {
|
const preferredNames: Record<ReportMemberNamePreference, string[]> = {
|
||||||
groupNickname: [member.groupNickname, member.wechatNickname, member.remark, member.nickname],
|
// Keep the three modes semantically distinct. `member.nickname` may
|
||||||
wechatNickname: [member.wechatNickname, member.groupNickname, member.remark, member.nickname],
|
// already be a contact remark, so it must not leak into the first two.
|
||||||
|
groupNickname: [member.groupNickname, member.wechatNickname],
|
||||||
|
wechatNickname: [member.wechatNickname, member.groupNickname],
|
||||||
remark: [member.remark, member.groupNickname, member.wechatNickname, member.nickname]
|
remark: [member.remark, member.groupNickname, member.wechatNickname, member.nickname]
|
||||||
}
|
}
|
||||||
const name = preferredNames[preference].find((value) => value && !isInternalName(value))
|
const name = preferredNames[preference].find((value) => value && !isInternalName(value))
|
||||||
if (!name) return message
|
return {
|
||||||
return { ...message, name, img: message.img || member.avatar }
|
...message,
|
||||||
|
name: name || (preference === 'remark' ? message.name : ''),
|
||||||
|
img: message.img || member.avatar
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -222,11 +227,12 @@ export function useGroupReportGeneration({
|
|||||||
const [generatedImage, setGeneratedImage] = useState<string | null>(null)
|
const [generatedImage, setGeneratedImage] = useState<string | null>(null)
|
||||||
const [reportPaths, setReportPaths] = useState<ReportPaths | null>(null)
|
const [reportPaths, setReportPaths] = useState<ReportPaths | null>(null)
|
||||||
const [templateId, setTemplateId] = useState<ReportTemplateId>('v1')
|
const [templateId, setTemplateId] = useState<ReportTemplateId>('v1')
|
||||||
const [memberNamePreference, setMemberNamePreferenceState] =
|
const [memberNamePreference, setMemberNamePreferenceState] = useState<ReportMemberNamePreference>(
|
||||||
useState<ReportMemberNamePreference>(() => {
|
() => {
|
||||||
const saved = localStorage.getItem('group_report_member_name_preference')
|
const saved = localStorage.getItem('group_report_member_name_preference')
|
||||||
return saved === 'wechatNickname' || saved === 'remark' ? saved : 'groupNickname'
|
return saved === 'wechatNickname' || saved === 'remark' ? saved : 'groupNickname'
|
||||||
})
|
}
|
||||||
|
)
|
||||||
const [reportTimeoutSeconds, setReportTimeoutSecondsState] = useState<number>(() => {
|
const [reportTimeoutSeconds, setReportTimeoutSecondsState] = useState<number>(() => {
|
||||||
const saved = Number(localStorage.getItem('group_report_timeout_seconds'))
|
const saved = Number(localStorage.getItem('group_report_timeout_seconds'))
|
||||||
return Number.isFinite(saved) && saved >= 30 ? saved : 300
|
return Number.isFinite(saved) && saved >= 30 ? saved : 300
|
||||||
|
|||||||
Reference in New Issue
Block a user