import { Injector, Next } from "@nger/core"; import { COMPLETE, DATA, FAIL, Task, TaskManager } from "@nger/rabbitmq"; import { Db } from "@nger/typeorm"; import { In } from "typeorm"; import { SpilderFactory } from "../adapter/spilder-factory"; import { SpilderTopicArticle } from "../entities/spilder-topic-article"; import { SpilderTopicArticleComment } from "../entities/spilder-topic-article-comment"; import { SpilderTopicArticleCommentTend } from "../entities/spilder-topic-article-comment-tend"; export interface TopicArticleComment { type: string; eid: number; tid: number; aid: number; id: number; uid: number; mblogid: string; } export class TopicArticleCommentTask extends Task { constructor() { super(`@nger/weibo/topic-article-comment`) this.count = 100; } async handle(injector: Injector, next?: Next | undefined) { const db = injector.get(Db); const data = injector.get(DATA); const complete = injector.get(COMPLETE); const fail = injector.get(FAIL); let { aid, tid, eid, type, id, uid, mblogid } = data; if (!(aid && tid && eid && type)) { await complete(); return next && next(); } if (!id || !uid) { const article = await db.manager.findOne(SpilderTopicArticle, { where: { id: aid }, select: ['mid', 'uid', 'mblogid'] }); if (article) { id = Number(article.mid); uid = Number(article.uid); mblogid = article.mblogid; if (!(id && uid)) { await complete(); return next && next(); } } else { await complete(); return next && next(); } } try { const spilderFactory = injector.get(SpilderFactory); const spilder = await spilderFactory.create(type); try { const data = await spilder.loadComments(id, uid); if (!data) { await complete(); return next && next(); } const manager = injector.get(TaskManager); await manager.send({ topic: '@nger/weibo/spilder-account-task', data: { uid, type, } }); if (data.data.length === 0) { await complete(); return next && await next(); } else { const { max_id, total_number, ok } = data; if (ok !== 1) { await complete(); return next && await next(); } if (max_id > 0) { await manager.send({ topic: '@nger/weibo/topic-article-more-comment', data: { type, eid, tid, aid, max_id, id, uid, mblogid } }); } const list = data.data; const comments: SpilderTopicArticleComment[] = list.map((item: any) => { const c = new SpilderTopicArticleComment(); c.aid = aid; c.tid = tid; c.eid = eid; c.platform = type; c.created_at = new Date(item.created_at); c.floor_number = item.floor_number; c.isLikedByMblogAuthor = item.isLikedByMblogAuthor; c.like_counts = item.like_counts; c.max_id = item.max_id; c.cid = item.id; c.text = item.text_raw; c.source = item.source; const { user } = item; c.uid = user.id; c.nickname = user.screen_name; return c; }); const inIds = comments.map(c => c.cid); const exisitComments = await db.manager.find(SpilderTopicArticleComment, { where: { cid: In(inIds) } }); let allCommnets = comments.map(c => { const item = exisitComments.find(item => item.cid === c.cid); if (item) { c.id = item.id; } return c; }) allCommnets = await db.manager.save(SpilderTopicArticleComment, allCommnets); // 创建子连接 const tends = allCommnets.map(comment => { const tend = new SpilderTopicArticleCommentTend(); tend.cid = comment.id; tend.like_counts = comment.like_counts; return tend; }); await Promise.all(allCommnets.map(async c => { await manager.send({ topic: '@nger/weibo/topic-article-child-comment', data: { type, eid, tid, aid, id: c.cid, uid, mblogid, pid: c.id } }); })); await db.manager.save(SpilderTopicArticleCommentTend, tends) await complete(); } } catch (e: any) { await spilder.delay(20) await fail(); } } catch (e: any) { await fail(); } return next && await next(); } }