fix: 评论区符号不正常显示

This commit is contained in:
hanyixuanten
2026-08-07 17:08:28 +08:00
parent ab466d75b3
commit 5685d32206
2 changed files with 49 additions and 7 deletions
+22 -2
View File
@@ -1,16 +1,18 @@
import { decodeHtmlEntities } from "../../htmlparser";
export const BilibiliClientCommentMethods = {
// 获取评论区内容
async getReplies(this: any, type: string, oid: string, pn: number = 1, ps: number = 10, sort: number = 1) {
const url = `https://api.bilibili.com/x/v2/reply?type=${type}&oid=${oid}&pn=${pn}&ps=${ps}&sort=${sort}`;
const response = await this.getRequest(url);
return response.data.data;
return decodeReplyMessages(response.data.data);
},
// 获取二级评论区内容
async getSecReplies(this: any, type: string, oid: string, root: string, pn: number = 1, ps: number = 10) {
const url = `https://api.bilibili.com/x/v2/reply/reply?type=${type}&oid=${oid}&pn=${pn}&ps=${ps}&root=${root}`;
const response = await this.getRequest(url);
return response.data.data;
return decodeReplyMessages(response.data.data);
},
// 点赞评论
@@ -45,3 +47,21 @@ export const BilibiliClientCommentMethods = {
return response.data;
},
};
/**
* 评论内容中的引号、大小于号等字符会以 HTML 实体形式返回(例如 "、<、>)。
* 在进入 UI 前统一解码,避免 QuickApp 的 text 组件把实体直接显示成乱码。
*/
function decodeReplyMessages(replyData: any): any {
if (!replyData || !Array.isArray(replyData.replies)) {
return replyData;
}
replyData.replies.forEach((reply: any) => {
if (reply && reply.content && typeof reply.content.message === "string") {
reply.content.message = decodeHtmlEntities(reply.content.message);
}
});
return replyData;
}
+26 -4
View File
@@ -18,13 +18,35 @@ const htmlEntities: { [key: string]: string } = {
// 可以在这里扩展其他常用的 HTML 实体
};
// 处理转义符,将   等转义符转换为对应的字符
function decodeEntities(text: string): string {
return text.replace(/&([^;]+);/g, (match, entity) => {
return htmlEntities[entity] || match; // 如果实体存在,则替换;否则保留原样
// 处理 HTML 实体,将评论或文章接口返回的转义符还原为可显示字符
// 同时支持十进制和十六进制数字实体,避免只处理少数几个命名实体。
export function decodeHtmlEntities(text: string): string {
return text.replace(/&(#(?:x[0-9a-f]+|\d+)|[a-z][a-z0-9]+);/gi, (match, entity) => {
if (entity.charAt(0) === '#') {
const isHex = entity.charAt(1).toLowerCase() === 'x';
const codePoint = parseInt(entity.slice(isHex ? 2 : 1), isHex ? 16 : 10);
if (!isNaN(codePoint) && codePoint >= 0 && codePoint <= 0x10ffff) {
// String.fromCodePoint 在部分 QuickApp 运行时不可用,手动处理代理项。
if (codePoint <= 0xffff) {
return String.fromCharCode(codePoint);
}
const offset = codePoint - 0x10000;
return String.fromCharCode(
0xd800 + (offset >> 10),
0xdc00 + (offset & 0x3ff)
);
}
return match;
}
return htmlEntities[entity.toLowerCase()] || match;
});
}
function decodeEntities(text: string): string {
return decodeHtmlEntities(text);
}
// 移除 HTML 标签,保留纯文本
function stripHtmlTags(html: string): string {
return html.replace(/<\/?[^>]+(>|$)/g, "");