feat: 添加图文回复关联问题

- 启用关联问题后,图文回复直接链接至对应问题页面
This commit is contained in:
2025-12-13 07:17:57 +00:00
parent 948e7bf109
commit 9f5157c5e1
2 changed files with 71 additions and 13 deletions

View File

@ -2,7 +2,7 @@ import { defineEndpoint } from "@directus/extensions-sdk";
import { parseDecryptedXML, parseWechatEncryptMessage } from "./utils/wechatXmlParser"; import { parseDecryptedXML, parseWechatEncryptMessage } from "./utils/wechatXmlParser";
import { verifyEncrypt, verifySignature } from "./utils/verification"; import { verifyEncrypt, verifySignature } from "./utils/verification";
import { WechatCrypto } from "./utils/wechatCrypto"; import { WechatCrypto } from "./utils/wechatCrypto";
import { WechatReply } from "./types/directus-schema"; import { Question, WechatReply } from "./types/directus-schema";
import { WechatReplyBuilder } from "./utils/wechatReplyBuilder"; import { WechatReplyBuilder } from "./utils/wechatReplyBuilder";
import { WechatEncryptBuilder } from "./utils/wechatEncryptBuilder"; import { WechatEncryptBuilder } from "./utils/wechatEncryptBuilder";
@ -93,24 +93,58 @@ export default defineEndpoint({
const textItem = firstReply.item as { content: string }; const textItem = firstReply.item as { content: string };
reply = replyBuilder.buildTextReply(textItem.content); reply = replyBuilder.buildTextReply(textItem.content);
} else if (firstReply && firstReply.collection === 'wechat_link_replies') { } else if (firstReply && firstReply.collection === 'wechat_link_replies') {
const linkItem = firstReply.item as unknown as { title: string; description: string; url: string; pic_url: string; link_with_questions: boolean; related_question?: string; }; const linkItem = firstReply.item as unknown as { title: string; description: string; url: string; thumbnail: string; link_with_questions: boolean; related_question?: string; };
console.log("Link Item:", linkItem); if (!linkItem.link_with_questions) {
// 构造图文消息XML // 构造图文消息XML
reply = replyBuilder.buildNewsReply( reply = replyBuilder.buildNewsReply(
linkItem.title, linkItem.title,
linkItem.description, linkItem.description,
linkItem.pic_url, linkItem.thumbnail,
linkItem.url linkItem.url
); );
} else {
const questionId = linkItem.related_question ?? undefined;
if (!questionId) {
replyContent = "未找到匹配的回复内容";
} else {
// 查询相关问题
const questionService = new ItemsService<Question>('questions', { schema: await getSchema() });
try {
const question = await questionService.readOne(questionId, {
fields: ['translations.*'],
});
// 查询翻译内容,优先中文
const translation = question.translations.find(t => t.languages_code === 'zh-CN') || question.translations[0];
if (!translation) {
throw new Error("未找到问题翻译内容");
}
const baseUrl = env.WECHAT_WEBSITE_URL ?? undefined;
// 构造图文消息XML
reply = replyBuilder.buildNewsReply(
'常见问题',
translation.title,
baseUrl ? `${baseUrl}/api/assets/${linkItem.thumbnail}` : linkItem.thumbnail,
baseUrl ? `${baseUrl}/support/faq?focus=${questionId}` : linkItem.url,
);
console.log(reply);
} catch (err) {
replyContent = "未找到匹配的回复内容";
}
}
}
} else { } else {
replyContent = "未找到匹配的回复内容"; replyContent = "未找到匹配的回复内容";
reply = undefined; reply = undefined;
} }
} }
console.log("Matched Replies:", replies);
} }
if(!reply) { if (!reply) {
reply = replyBuilder.buildTextReply('未找到匹配的回复内容'); reply = replyBuilder.buildTextReply('未找到匹配的回复内容');
} }

View File

@ -1,3 +1,27 @@
/**
* 相关问题类型
*/
export interface Question {
/** 唯一标识符 */
id: string;
translations: QuestionTranslation[];
}
/**
* 相关问题翻译类型
*/
export interface QuestionTranslation {
/** 唯一标识符 */
id: string;
/** 语言代码 */
languages_code: string;
/** 问题标题 */
title: string;
/** 问题内容 */
content: string;
}
/** /**
* 微信回复消息类型——文本消息 * 微信回复消息类型——文本消息
*/ */
@ -14,7 +38,7 @@ export interface WechatLinkReply {
title: string; title: string;
description: string; description: string;
url: string; url: string;
pic_url: string; thumbnail: string;
link_with_questions: boolean; link_with_questions: boolean;
related_question?: string; related_question?: string;
} }