Files
read_book/src/rpc/router/persona.router.ts

72 lines
2.7 KiB
TypeScript

import { ReadingPersona } from '@main/db/entities/ReadingPersona'
import { router, t } from '@rpc/index'
import { entityToUserReadingPersona, PersonaService } from '@main/services/persona.service'
import { ReadingReflectionTaskBatch } from '@main/db/entities/ReadingReflectionTaskBatch'
import { ReadingReflectionTaskItem } from '@main/db/entities/ReadingReflectionTaskItem'
import { z } from 'zod'
export const personaRouter = router({
/**
* 获取用户画像:直接从数据库读取缓存结果,极快
* */
getUserPersona: t.procedure.query(async ({ ctx }) => {
const entity = await ctx.db.getRepository(ReadingPersona).findOneBy({
id: 'current_user_persona'
})
if (!entity) return null
// 将数据库扁平实体映射为前端需要的结构化 IUserReadingPersona
return entityToUserReadingPersona(entity)
}),
/**
* 刷新用户画像
* */
forceRefreshUserPersona: t.procedure.mutation(async ({ ctx }) => {
const items = await ctx.db
.getRepository(ReadingReflectionTaskItem)
.find({ where: { status: 'COMPLETED' } })
const batches = await ctx.db.getRepository(ReadingReflectionTaskBatch).find()
const personaService = new PersonaService(ctx.db.getRepository(ReadingPersona))
return await personaService.refreshPersona(items, batches)
}),
/**
* 聚合统计:从数据库中聚合数据并计算画像分值
* */
getContributionData: t.procedure.query(async ({ ctx }) => {
const itemRepo = ctx.db.getRepository(ReadingReflectionTaskItem)
// 关键:关联 batch 获取时间,并强制格式化为 YYYY-MM-DD
const rawData = await itemRepo
.createQueryBuilder('item')
.leftJoin('reading_reflection_task_batches', 'batch', 'item.batchId = batch.id')
.select("strftime('%Y-%m-%d', batch.createdAt)", 'date')
.addSelect('COUNT(item.id)', 'count')
.where("item.status = 'COMPLETED'")
.groupBy('date')
.getRawMany()
return rawData as { date: string; count: number }[]
}),
/**
* 获取指定日期的心得
* */
getReflectionsByDate: t.procedure
.input(z.object({ date: z.string() }))
.query(async ({ ctx, input }) => {
const repo = ctx.db.getRepository(ReadingReflectionTaskItem)
// 关键修正:必须在 batch 表上进行日期过滤
return await repo
.createQueryBuilder('item')
// 这里的 'batchId' 必须是你数据库中 item 表关联 batch 的实际外键列名
.leftJoinAndSelect('reading_reflection_task_batches', 'batch', 'item.batchId = batch.id')
.where('date(batch.createdAt) = :date', { date: input.date })
.andWhere("item.status = 'COMPLETED'")
.getMany()
})
})