From 9742b6f0947543f5dbda48aa6d6e12fe6a57816a Mon Sep 17 00:00:00 2001 From: npmrun <1549469775@qq.com> Date: Fri, 7 Aug 2026 23:28:47 +0800 Subject: [PATCH] feat: update feedback handling to support null values and enhance message retrieval with user feedback --- app/composables/useAgentChat.ts | 7 ++-- packages/drizzle-pkg/db.sqlite | Bin 1556480 -> 1634304 bytes server/api/agent/feedback.post.ts | 13 +++++-- server/api/agent/sessions/[id]/messages.get.ts | 2 +- server/service/agent/session.ts | 45 ++++++++++++++++++------- server/service/agent/types.ts | 4 +++ 6 files changed, 52 insertions(+), 19 deletions(-) diff --git a/app/composables/useAgentChat.ts b/app/composables/useAgentChat.ts index 60c7635..b88f955 100644 --- a/app/composables/useAgentChat.ts +++ b/app/composables/useAgentChat.ts @@ -503,14 +503,15 @@ export function useAgentChat(options: UseAgentChatOptions) { async function sendFeedback(messageId: string, feedback: "like" | "dislike") { if (!auth.loggedIn.value) return; + const msg = messages.value.find((m) => m.id === messageId); + const newFeedback = msg?.feedback === feedback ? null : feedback; try { await $fetch("/api/agent/feedback", { method: "POST", - body: { messageId, feedback }, + body: { messageId, feedback: newFeedback }, }); - const msg = messages.value.find((m) => m.id === messageId); if (msg) { - msg.feedback = msg.feedback === feedback ? null : feedback; + msg.feedback = newFeedback; } } catch { } diff --git a/packages/drizzle-pkg/db.sqlite b/packages/drizzle-pkg/db.sqlite index 1cfa76e889c2c59c39f5fd5a73fadec8a76c7924..eb648403f4967f5f0a5f82a0c591d4ba2e71112d 100644 GIT binary patch delta 78629 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 JVF3kK{W?JU9j1?K*ml^-Lf1?J? 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

AUkZITd-I^T=0{0`9{ldi zFpjHi&q~UN(w)k@5An^Eeki$yxG4`|Gv=1?@ojLsvAP+DhO!%L(ivbsRvV!mML%{! z#=g{}I0*R_&(P z4$b{1qecHMnjZfgH|Y?JJ&87HYSuqun;zG_mksws06S0uvNi>L+>D$~7iPQ5fz0QKwRf*L$-tFyr4 z$*C%-a965jl$Bab3aqYRUS(|s0s#DOe?ZCo_q1t>GCOr#h%bl;g@Dg#ujP;xc?3b} zyZ-jkgCnS+BBDS$)>u3xmBj_M)fE+%YL6B<5myN{w8TvXd^qA44-Xe-nQ`^6UuQVW zSe$iL!GbzZsLWDf%gR;{M`hKHqJpZ@y3$g(XY{j-stAcxl8G^n*AA)+Q8LhvL)Cp+ zpgK}_RlJu5sSB|Y3d_iVm^uTbP8>%*RYYA#w?EMdC?4)d<|R5|eU^Z_5ap-QE9wuZ z`_%AsLiXYa5Ia@@;uhj;CgPl-IV#9eDQI*)4KSUM;J{eA&{e>6L&MTh2X!Q!dXm!5 zjdA^poghvAkWj>c739r_0Fa*$SSLE109Th7Ru?kGaCIX`es-w3fk1Vke-Nr}AW)tA zKz~%7;ZUhAPO#y8B1|1Y>J;-dDSO$P(}YDAHX&gUWp5~s@npVeyY%d2OaM#;T&AP_ z>Vst07bYN-fb%Ycs@06jEy(A4LV4iah>0t)ctFBH)WAfHK_r_JP$9=(L3}B_B}f5|Nv~re%`v;V4d+Xamj~RWjP0FQNnF*fxper>0_& z-wutZ-O^2U=AI9DB-k&dqDDs9ad{j4kWY#g=6c6$c*j zc;_y+*^nCrq|sBy8-=Nwxdhf>!h$E}2eXRYRV78$`8AcxD_stN!&YS}%fe|{${jzG z#w2_-4$EM^4y6-{!5mWIXQnJmc4lszR~S?S05>7=N4Tl0XImFcB;n4^=s{!y*#s0= z{yYZI&Zg*bC2~|vYDuDLZ+LccxVr(5>x0tU_9k9J#^TA5i_MX)y<|)|za!kZ zLafE#d)8YFv*4 zc4z>`FlX=5FpSF?#E7TWW!n*BH>)2%0&V64$$<- z?hOn{H=!HhgNbz)VIddeeCCyvMuXTbB=A6Y_{3*U^gU4t^Byl%P_=z zk4IikPxIS#mM# z0WPF^0=Pu>s?XKZA7ouO!cgXF_$8DO^f*eY;IehPW{GL!=+k{6XMzEUA8f9On_=Zh z+Q}eeP3W{I$F7R^2wg3H25{t0z+66{%J}2u90{q>AOz)u1_a@*X+BVHDup4 zoY}yiIb0P1C29vj3sH5z&dZK&;M3r-_q$wW@T1!+z2y~ve8 zs^=2;_5oB7uze>$b;iOq5(ePAf}Q|bpvlHN=ch1tZ?B(Vo49O2@FC}83-a<@59L-r zne{}~0>=~CwyZ2t5NEJ5_|*K8hv#M4vJ0OoUsn3e{Dn(wkIu7|d6jWX(y}Sz)L3N* zwtVtfOh{p4{_kFv?&!GbthD%QCj3chHd|Is|F~6x`c71yA3b_}%*k}i06>kgWZTw+ zkF|SDBiAUb)xD5gIm@c~l4zzwghK)95#AsmNmAJ~W zGdlu76jm!d4@BsKu`c%oXv%=#Lql~K`jVlX>;gab2Va~p)}y=A!`BRuqp3FlM2?NF zpEE}8Nt~kM8v=a@CpUJienMo$6j3+{fKPfxm|V={Jan8~j^1eYU>MM2?67ASfx4Ni zFoVv<7*H-B=gAlzAr2_V?dn%Z7yhLgF9m@{1!F^8k2@FYwf_8qdr?>aXU*xj2_ F{trIpVt4=m delta 15570 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 diff --git a/server/api/agent/feedback.post.ts b/server/api/agent/feedback.post.ts index 6ce93d1..50b7004 100644 --- a/server/api/agent/feedback.post.ts +++ b/server/api/agent/feedback.post.ts @@ -15,11 +15,11 @@ export default defineWrappedResponseHandler(async (event) => { const body = await readBody(event); const { messageId, feedback, comment } = body as { messageId: string; - feedback: "like" | "dislike"; + feedback: "like" | "dislike" | null; comment?: string; }; - if (!messageId || !feedback || !["like", "dislike"].includes(feedback)) { + if (!messageId || (feedback !== null && !["like", "dislike"].includes(feedback))) { return R.error("参数无效", null); } @@ -39,6 +39,15 @@ export default defineWrappedResponseHandler(async (event) => { .where(and(eq(agentMessageFeedback.messageId, messageId), eq(agentMessageFeedback.userId, user.id))) .limit(1); + if (feedback === null) { + if (existing) { + await dbGlobal + .delete(agentMessageFeedback) + .where(eq(agentMessageFeedback.id, existing.id)); + } + return R.success({ messageId, feedback: null }); + } + if (existing) { await dbGlobal .update(agentMessageFeedback) diff --git a/server/api/agent/sessions/[id]/messages.get.ts b/server/api/agent/sessions/[id]/messages.get.ts index 92d576a..43c866f 100644 --- a/server/api/agent/sessions/[id]/messages.get.ts +++ b/server/api/agent/sessions/[id]/messages.get.ts @@ -19,6 +19,6 @@ export default defineWrappedResponseHandler(async (event) => { const before = query.before ? Number(query.before) : undefined; const limit = Number(query.limit) || 50; - const messages = await getMessagesBySession(id, { before, limit }); + const messages = await getMessagesBySession(id, { before, limit, userId: identity.userId }); return R.success({ messages, hasMore: messages.length === limit }); }); diff --git a/server/service/agent/session.ts b/server/service/agent/session.ts index 2259b7a..5fc587a 100644 --- a/server/service/agent/session.ts +++ b/server/service/agent/session.ts @@ -1,7 +1,7 @@ import { dbGlobal } from "drizzle-pkg/lib/db"; import { agentSessions, agentMessages, agentMessageFeedback } from "drizzle-pkg/lib/schema/agent"; import { eq, desc, asc, and, lt, isNull, sql, max } from "drizzle-orm"; -import type { AgentSessionRow, AgentMessageRow } from "./types"; +import type { AgentSessionRow, AgentMessageRow, AgentMessageWithFeedback } from "./types"; export async function createSession(params: { userId?: number | null; @@ -118,28 +118,47 @@ export async function softDeleteSession(id: string): Promise { export async function getMessagesBySession( sessionId: string, - params?: { before?: number; limit?: number; latest?: boolean }, -): Promise { - const { before, limit = 50, latest = false } = params ?? {}; + params?: { before?: number; limit?: number; latest?: boolean; userId?: number | null }, +): Promise { + const { before, limit = 50, latest = false, userId = null } = params ?? {}; const conditions = [eq(agentMessages.sessionId, sessionId)]; if (before !== undefined) { conditions.push(lt(agentMessages.sortOrder, before)); } - if (latest) { - const rows = await dbGlobal - .select() + + const baseQuery = () => + dbGlobal + .select({ + message: agentMessages, + feedback: agentMessageFeedback.feedback, + }) .from(agentMessages) - .where(and(...conditions)) + .leftJoin( + agentMessageFeedback, + and( + eq(agentMessageFeedback.messageId, agentMessages.id), + userId ? eq(agentMessageFeedback.userId, userId) : sql`false`, + ), + ) + .where(and(...conditions)); + + if (latest) { + const rows = await baseQuery() .orderBy(desc(agentMessages.sortOrder)) .limit(limit); - return rows.reverse(); + const reversed = rows.reverse(); + return reversed.map((r) => ({ + ...r.message, + feedback: (r.feedback ?? null) as "like" | "dislike" | null, + })); } - return dbGlobal - .select() - .from(agentMessages) - .where(and(...conditions)) + const rows = await baseQuery() .orderBy(asc(agentMessages.sortOrder)) .limit(limit); + return rows.map((r) => ({ + ...r.message, + feedback: (r.feedback ?? null) as "like" | "dislike" | null, + })); } export async function getMaxSortOrder(sessionId: string): Promise { diff --git a/server/service/agent/types.ts b/server/service/agent/types.ts index 331312c..3cf49fc 100644 --- a/server/service/agent/types.ts +++ b/server/service/agent/types.ts @@ -4,6 +4,10 @@ export type AgentSessionRow = typeof agentSessions.$inferSelect; export type AgentMessageRow = typeof agentMessages.$inferSelect; export type AgentMessageFeedbackRow = typeof agentMessageFeedback.$inferSelect; +export interface AgentMessageWithFeedback extends AgentMessageRow { + feedback: "like" | "dislike" | null; +} + export interface AgentIdentity { userId: number | null; tempToken: string | null;