wechat-article / utils /comment.ts
asemxin2000's picture
Deploy wechat-article-exporter to Space
6e41657 verified
Raw
History Blame Contribute Delete
9.17 kB
import { formatTimeStamp } from '#shared/utils/helpers';
import { getCommentCache } from '~/store/v2/comment';
import { getCommentReplyCache } from '~/store/v2/comment_reply';
import { getMetadataCache } from '~/store/v2/metadata';
/**
* ไปŽๆ–‡็ซ  HTML ไธญๆๅ– comment_idใ€‚
* ๆ–‡ๆœฌๅˆ†ไบซไธŽๆ™ฎ้€šๅ›พๆ–‡็š„้กต้ข็ป“ๆž„ไธๅŒ๏ผŒๅ› ๆญค้œ€่ฆๅ…ผๅฎนๅคš็งๅ†™ๆณ•ใ€‚
*/
export function extractCommentId(html: string): string | null {
const patterns = [
// ๆ™ฎ้€šๅ›พๆ–‡: var comment_id = 'xxx' || '0';
/var comment_id = '(?<comment_id>\d+)' \|\| '0';/,
// ๆ–‡ๆœฌๅˆ†ไบซ็ญ‰: d.comment_id = xml ? getXmlValue('comment_id.DATA') : 'xxx';
/comment_id:\s*JsDecode\('(?<comment_id>\d+)'\)/,
// ๆœ‰ไบ›ๆจกๆฟ้‡Œไปฅ JsDecode ๅฝขๅผๅ†™ๅœจ้…็ฝฎ้‡Œ
/d\.comment_id\s*=\s*xml \? getXmlValue\('comment_id\.DATA'\) : '(?<comment_id>\d+)';/,
// ๅ…œๅบ•: window.segment_comment_id = 'xxx';
/window\.comment_id\s*=\s*'(?<comment_id>\d+)'/,
];
for (const pattern of patterns) {
const match = html.match(pattern);
if (match) {
// ไผ˜ๅ…ˆไฝฟ็”จๅ‘ฝๅๅˆ†็ป„๏ผŒๅฆๅˆ™้€€ๅ›ž็ฌฌไธ€ไธชๅˆ†็ป„
if ('groups' in match && match.groups && match.groups.comment_id) {
return match.groups.comment_id;
}
if (match[1]) {
return match[1];
}
}
}
return null;
}
/**
* ๆธฒๆŸ“ๆ–‡็ซ ็š„่ฏ„่ฎบๅ†…ๅฎน
* @param url ๆ–‡็ซ ้“พๆŽฅ
*/
export async function renderComments(url: string) {
let commentHTML = '';
let elected_comments = [];
const commentCache = await getCommentCache(url);
if (commentCache) {
const commentResponse = commentCache.data;
if (Array.isArray(commentResponse)) {
elected_comments = commentResponse.flatMap(response => response.elected_comment);
} else if (commentResponse) {
elected_comments = commentResponse.elected_comment;
}
if (elected_comments.length > 0) {
// ่ฏ„่ฎบๆ€ปๆ•ฐ
const metadata = await getMetadataCache(url);
commentHTML += '<div style="max-width: 667px;margin: 0 auto;padding: 10px 10px 80px;">';
commentHTML += `<p style="font-size: 15px;color: #949494;">็•™่จ€ ${metadata?.commentNum}</p>`;
commentHTML += '<div style="margin-top: -10px;">';
// ็•™่จ€ๅˆ—่กจ
for (const comment of elected_comments) {
commentHTML += '<div style="margin-top: 25px;"><div style="display: flex;">';
if ([1, 2].includes(comment.identity_type)) {
commentHTML += `<img src="${comment.logo_url}" style="display: block;width: 30px;height: 30px;border-radius: 50%;margin-right: 8px;" alt="">`;
} else {
commentHTML += `<img src="${comment.logo_url}" style="display: block;width: 30px;height: 30px;border-radius: 2px;margin-right: 8px;" alt="">`;
}
commentHTML += '<div style="flex: 1;"><p style="display: flex;line-height: 16px;margin-block: 5px;">';
commentHTML += `<span style="margin-right: 5px;font-size: 15px;color: #949494;">${comment.nick_name}</span>`;
if (comment.is_from_friend === 1) {
commentHTML += `<span style="margin-right: 5px;font-size: 12px;color: #00BA5A;">ๆœ‹ๅ‹</span>`;
}
if (comment.ip_wording) {
commentHTML += `<span style="margin-right: 5px;font-size: 12px;color: #b5b5b5;">${comment.ip_wording?.province_name}</span>`;
} else {
commentHTML += `<span style="margin-right: 5px;font-size: 12px;color: #00BA5A;">ไฝœ่€…</span>`;
}
commentHTML += `<span style="font-size: 12px;color: #b5b5b5;">${formatTimeStamp(comment.create_time)}</span>`;
commentHTML += '<span style="flex: 1;"></span><span style="display: inline-flex;align-items: center;">';
commentHTML += `<span class="sns_opr_btn sns_praise_btn" style="font-size: 12px;color: #8b8a8a;">${comment.like_num || ''}</span>`;
commentHTML += '</span></p>';
commentHTML += `<p style="font-size: 15px;color: #333;white-space: pre-line;margin-block: .5em;">${comment.content}</p>`;
if (comment.multi_info && comment.multi_info.pictures && comment.multi_info.pictures.length > 0) {
commentHTML += `<p>${comment.multi_info.pictures.map((pic: any) => '<img src="' + pic.url + '" style="max-width: 100%;" alt="">').join('')}</p>`;
}
if (comment.author_like_status === 1) {
commentHTML += '<p style="font-size: 12px;color: #00BA5A;margin-block: .5em;">ไฝœ่€…่ตž่ฟ‡</p>';
}
commentHTML += '</div></div>';
// ็•™่จ€ๅ›žๅคๅˆ—่กจ
let reply_list = [];
const commentReplyResponse = await getCommentReplyCache(url, comment.content_id);
if (
commentReplyResponse &&
commentReplyResponse.data &&
commentReplyResponse.data.reply_list.reply_list.length > 0
) {
reply_list = commentReplyResponse.data.reply_list.reply_list;
} else if (comment.reply_new && comment.reply_new.reply_list.length > 0) {
reply_list = comment.reply_new.reply_list;
}
commentHTML += '<div style="padding-left: 38px;">';
reply_list
.sort((a: any, b: any) => a.create_time - b.create_time)
.forEach((reply: any) => {
commentHTML += '<div style="display: flex;margin-top: 15px;">';
if ([1, 2].includes(reply.identity_type)) {
commentHTML += `<img src="${reply.logo_url}" style="display: block;width: 23px;height: 23px;border-radius: 50%;margin-right: 8px;" alt="">`;
} else {
commentHTML += `<img src="${reply.logo_url}" style="display: block;width: 23px;height: 23px;border-radius: 2px;margin-right: 8px;" alt="">`;
}
commentHTML += '<div style="flex: 1;"><p style="display: flex;line-height: 16px;margin-block: 5px;">';
commentHTML += `<span style="margin-right: 5px;font-size: 15px;color: #949494;">${reply.nick_name}</span>`;
if (reply.is_from_friend === 1) {
commentHTML += `<span style="margin-right: 5px;font-size: 12px;color: #00BA5A;">ๆœ‹ๅ‹</span>`;
}
if (reply.ip_wording) {
commentHTML += `<span style="margin-right: 5px;font-size: 12px;color: #b5b5b5;">${reply.ip_wording?.province_name}</span>`;
} else {
commentHTML += `<span style="margin-right: 5px;font-size: 12px;color: #00BA5A;">ไฝœ่€…</span>`;
}
commentHTML += `<span style="font-size: 12px;color: #b5b5b5;">${formatTimeStamp(reply.create_time)}</span>`;
commentHTML +=
'<span style="flex: 1;"></span><span style="display: inline-flex;align-items: center; font-size: 12px;color: #b5b5b5;">';
commentHTML += `<span class="sns_opr_btn sns_praise_btn" style="font-size: 12px;color: #8b8a8a;">${reply.reply_like_num || ''}</span>`;
commentHTML += '</span></p>';
commentHTML += `<p style="font-size: 15px;color: #333;white-space: pre-line;margin-block: .5em;">${reply.to_nick_name ? 'ๅ›žๅค ' + reply.to_nick_name + ':' : ''} ${reply.content}</p>`;
if (reply.multi_info && reply.multi_info.pictures && reply.multi_info.pictures.length > 0) {
commentHTML += `<p>${reply.multi_info.pictures.map((pic: any) => '<img src="' + pic.url + '" style="max-width: 100%;" alt="">').join('')}</p>`;
}
if (reply.author_like_status === 1) {
commentHTML += '<p style="font-size: 12px;color: #00BA5A;margin-block: .5em;">ไฝœ่€…่ตž่ฟ‡</p>';
}
commentHTML += '</div></div>';
});
commentHTML += '</div>';
commentHTML += '</div>';
}
commentHTML += '</div></div>';
}
}
return commentHTML;
}
// ไปŽๆœฌๅœฐ็ผ“ๅญ˜่Žทๅ–ๆ–‡็ซ ็š„่ฏ„่ฎบๆ•ฐๆฎ
export async function getArticleComments(url: string) {
let elected_comments = [];
const commentCache = await getCommentCache(url);
if (commentCache) {
const commentResponse = commentCache.data;
if (Array.isArray(commentResponse)) {
elected_comments = commentResponse.flatMap(response => response.elected_comment);
} else if (commentResponse) {
elected_comments = commentResponse.elected_comment;
}
if (elected_comments.length > 0) {
for (const comment of elected_comments) {
// ็•™่จ€ๅ›žๅคๅˆ—่กจ
let reply_list = [];
const commentReplyResponse = await getCommentReplyCache(url, comment.content_id);
if (
commentReplyResponse &&
commentReplyResponse.data &&
commentReplyResponse.data.reply_list.reply_list.length > 0
) {
reply_list = commentReplyResponse.data.reply_list.reply_list;
} else if (comment.reply_new && comment.reply_new.reply_list.length > 0) {
reply_list = comment.reply_new.reply_list;
}
reply_list.sort((a: any, b: any) => a.create_time - b.create_time);
comment.$reply_list = reply_list;
}
}
}
return elected_comments;
}