feat: 提交校园智能助手后端工程源码(Spring Boot 2.7.18 + 平台 starter + JPA + Nacos)
build / build-push (push) Successful in 40s
build / build-push (push) Successful in 40s
- com.yunhai.agent,端口 8093,context-path /agent,制品 target/agent.jar;与 NoticeService 同构 - CAS 单点登录 + 三层角色权限(学生/教师/管理员/访客)+ 会话与工具调用审计落库 - DeepSeek 大模型编排 + 7 个业务模块工具(请假/公告/宿舍/活动/作业/资源库/教师发展) - 浏览器代执行协议(服务端挂起 → 前端用登录态代调 → toolResult 续跑)+ 调用失败深链兜底 - 登出修复:服务端真正 session.invalidate() + 前端两步登出 + logout-guard - 保留 projman 注入的 .gitea/workflows/build.yml 与 docker/Dockerfile;docker/application-prod.yml、run-app.sh 随工程入库
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
package com.yunhai.agent.entity;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Index;
|
||||
import javax.persistence.Lob;
|
||||
import javax.persistence.Table;
|
||||
|
||||
/**
|
||||
* 会话里的一条消息(system / user / assistant / tool),按 seq_no 保序。
|
||||
*
|
||||
* <p>assistant 消息可能携带工具调用请求,序列化进 {@link #toolCalls};
|
||||
* tool 消息用于回填工具执行结果,关联 {@link #toolCallId}。
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "agent_message", indexes = {
|
||||
@Index(name = "idx_agent_msg_sid", columnList = "session_id,seq_no")
|
||||
})
|
||||
@Getter
|
||||
@Setter
|
||||
public class AgentMessage extends BaseEntity {
|
||||
|
||||
/** 所属会话 id */
|
||||
@Column(name = "session_id", nullable = false, length = 64)
|
||||
private String sessionId;
|
||||
|
||||
/** 会话内顺序(从 0 递增) */
|
||||
@Column(name = "seq_no")
|
||||
private Integer seqNo;
|
||||
|
||||
/** 角色:system / user / assistant / tool */
|
||||
@Column(name = "role", length = 16)
|
||||
private String role;
|
||||
|
||||
/** 正文(可能为空:assistant 只想调工具时) */
|
||||
@Lob
|
||||
@Column(name = "content", columnDefinition = "TEXT")
|
||||
private String content;
|
||||
|
||||
/** assistant 的 tool_calls(JSON 数组字符串) */
|
||||
@Lob
|
||||
@Column(name = "tool_calls", columnDefinition = "TEXT")
|
||||
private String toolCalls;
|
||||
|
||||
/** role=tool 时关联的调用 id */
|
||||
@Column(name = "tool_call_id", length = 64)
|
||||
private String toolCallId;
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package com.yunhai.agent.entity;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Index;
|
||||
import javax.persistence.Table;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 智能体会话:一个用户在「一段连续对话」里的上下文台账。
|
||||
*
|
||||
* <p>会话与 userId 绑定(跨用户复用同一 sessionId 会被拒绝并重建),承载多轮对话的归属与审计信息;
|
||||
* 具体消息见 {@link AgentMessage}。
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "agent_session", indexes = {
|
||||
@Index(name = "idx_agent_session_sid", columnList = "session_id", unique = true),
|
||||
@Index(name = "idx_agent_session_user", columnList = "user_id")
|
||||
})
|
||||
@Getter
|
||||
@Setter
|
||||
public class AgentSession extends BaseEntity {
|
||||
|
||||
/** 会话 id(前端持有并复用) */
|
||||
@Column(name = "session_id", nullable = false, length = 64)
|
||||
private String sessionId;
|
||||
|
||||
/** 归属用户 id */
|
||||
@Column(name = "user_id")
|
||||
private Integer userId;
|
||||
|
||||
/** 学校 id */
|
||||
@Column(name = "sch_id")
|
||||
private Integer schId;
|
||||
|
||||
/** 会话标题(取首条用户输入,便于列表展示) */
|
||||
@Column(name = "title", length = 200)
|
||||
private String title;
|
||||
|
||||
/** 角色快照(学生 / 教师 / 管理员),审计留痕用 */
|
||||
@Column(name = "role_snapshot", length = 64)
|
||||
private String roleSnapshot;
|
||||
|
||||
/** 最后访问时间(空闲过期依据) */
|
||||
@Column(name = "last_access")
|
||||
private LocalDateTime lastAccess;
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
package com.yunhai.agent.entity;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Index;
|
||||
import javax.persistence.Lob;
|
||||
import javax.persistence.Table;
|
||||
|
||||
/**
|
||||
* 工具调用审计:每次对业务模块的真实调用留一条痕(含越权被拒的调用)。
|
||||
*
|
||||
* <p>用途:可追溯「谁、什么身份、在哪个会话、调了哪个模块的什么接口、传了什么、成没成、耗时多少」,
|
||||
* 既是运维排障依据,也是「分学生、教师权限」的合规凭证。
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "agent_tool_call_log", indexes = {
|
||||
@Index(name = "idx_agent_log_sid", columnList = "session_id"),
|
||||
@Index(name = "idx_agent_log_tool", columnList = "tool_name"),
|
||||
@Index(name = "idx_agent_log_user", columnList = "user_id")
|
||||
})
|
||||
@Getter
|
||||
@Setter
|
||||
public class AgentToolCallLog extends BaseEntity {
|
||||
|
||||
/** 所属会话 id */
|
||||
@Column(name = "session_id", length = 64)
|
||||
private String sessionId;
|
||||
|
||||
/** 调用者用户 id */
|
||||
@Column(name = "user_id")
|
||||
private Integer userId;
|
||||
|
||||
/** 学校 id */
|
||||
@Column(name = "sch_id")
|
||||
private Integer schId;
|
||||
|
||||
/** 调用者角色(学生 / 教师 / 管理员) */
|
||||
@Column(name = "role", length = 64)
|
||||
private String role;
|
||||
|
||||
/** 业务模块标识 */
|
||||
@Column(name = "module", length = 64)
|
||||
private String module;
|
||||
|
||||
/** 工具名,如 leave.submit */
|
||||
@Column(name = "tool_name", length = 128)
|
||||
private String toolName;
|
||||
|
||||
/** 工具中文名 */
|
||||
@Column(name = "tool_title", length = 128)
|
||||
private String toolTitle;
|
||||
|
||||
/** 是否写操作 */
|
||||
@Column(name = "is_write")
|
||||
private Boolean write;
|
||||
|
||||
/** 调用参数(JSON) */
|
||||
@Lob
|
||||
@Column(name = "arguments", columnDefinition = "TEXT")
|
||||
private String arguments;
|
||||
|
||||
/** 是否成功(越权拦截为 false) */
|
||||
@Column(name = "success")
|
||||
private Boolean success;
|
||||
|
||||
/** 失败原因 */
|
||||
@Lob
|
||||
@Column(name = "error", columnDefinition = "TEXT")
|
||||
private String error;
|
||||
|
||||
/** 耗时(毫秒) */
|
||||
@Column(name = "cost_ms")
|
||||
private Long costMs;
|
||||
|
||||
/** 建议跳转路由 */
|
||||
@Column(name = "landing_path", length = 128)
|
||||
private String landingPath;
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.yunhai.agent.entity;
|
||||
|
||||
import com.yunhai.agent.common.listener.AgentAuditListener;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.EntityListeners;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.MappedSuperclass;
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 所有实体的公共基类:自增主键 + 创建人/时间 + 更新人/时间(由 {@link AgentAuditListener} 自动填充)。
|
||||
*/
|
||||
@MappedSuperclass
|
||||
@Getter
|
||||
@Setter
|
||||
@EntityListeners(AgentAuditListener.class)
|
||||
public abstract class BaseEntity implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Integer id;
|
||||
|
||||
/** 创建人登录账号 */
|
||||
@Column(name = "create_by", updatable = false)
|
||||
private String createBy;
|
||||
|
||||
/** 创建时间 */
|
||||
@Column(name = "create_time", updatable = false)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
/** 更新人登录账号 */
|
||||
@Column(name = "update_by")
|
||||
private String updateBy;
|
||||
|
||||
/** 更新时间 */
|
||||
@Column(name = "update_time")
|
||||
private LocalDateTime updateTime;
|
||||
}
|
||||
Reference in New Issue
Block a user