72 lines
2.7 KiB
TypeScript
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()
|
|
})
|
|
})
|