feat: 重构前后端架构,添加Go后端和Python Agent服务
- 新增 Go 语言后端服务(server/),包含用户认证、Agent管理、数据库连接等API - 新增 Python Agent 服务(agent/),实现Agent核心逻辑和工具集 - 前端从原生HTML迁移到Vue.js框架(web/src/) - 添加 Docker Compose 支持(docker-compose.yml) - 添加项目架构文档(docs/ARCHITECTURE.md) - 添加环境变量示例(.env.example)和本地启动脚本(start-local.ps1) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
53
server/internal/model/agent.go
Normal file
53
server/internal/model/agent.go
Normal file
@@ -0,0 +1,53 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// SecurityLevel 安全等级
|
||||
type SecurityLevel string
|
||||
|
||||
const (
|
||||
SecurityLevelSafe SecurityLevel = "safe"
|
||||
SecurityLevelReview SecurityLevel = "review"
|
||||
SecurityLevelDanger SecurityLevel = "danger"
|
||||
)
|
||||
|
||||
// Agent 智能体
|
||||
type Agent struct {
|
||||
ID string `json:"id" gorm:"primaryKey"`
|
||||
Name string `json:"name" gorm:"size:100;not null"`
|
||||
Description string `json:"description" gorm:"type:text"`
|
||||
OwnerID string `json:"owner_id" gorm:"size:50;not null;index"`
|
||||
|
||||
// Agent能力配置
|
||||
Capabilities []string `json:"capabilities" gorm:"type:text"` // JSON数组,可用工具列表
|
||||
MemoryLimit int64 `json:"memory_limit" gorm:"default:134217728"` // 128MB
|
||||
Timeout int `json:"timeout" gorm:"default:60"` // 60秒
|
||||
|
||||
// 安全配置
|
||||
SecurityLevel SecurityLevel `json:"security_level" gorm:"size:20;default:'safe'"`
|
||||
AllowDangerousTools bool `json:"allow_dangerous_tools" gorm:"default:false"`
|
||||
|
||||
// 状态
|
||||
IsActive bool `json:"is_active" gorm:"default:true"`
|
||||
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
// AgentRequest 聊天请求
|
||||
type AgentRequest struct {
|
||||
AgentID string `json:"agent_id" binding:"required"`
|
||||
Message string `json:"message" binding:"required"`
|
||||
SessionID string `json:"session_id"`
|
||||
Context map[string]interface{} `json:"context"`
|
||||
}
|
||||
|
||||
// AgentResponse 聊天响应
|
||||
type AgentResponse struct {
|
||||
Reply string `json:"reply"`
|
||||
SessionID string `json:"session_id"`
|
||||
ToolsUsed []string `json:"tools_used"`
|
||||
Metadata map[string]interface{} `json:"metadata"`
|
||||
}
|
||||
76
server/internal/model/audit.go
Normal file
76
server/internal/model/audit.go
Normal file
@@ -0,0 +1,76 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"time"
|
||||
)
|
||||
|
||||
// AuditAction 审计动作
|
||||
type AuditAction string
|
||||
|
||||
const (
|
||||
AuditActionLogin AuditAction = "login"
|
||||
AuditActionLogout AuditAction = "logout"
|
||||
AuditActionChat AuditAction = "chat"
|
||||
AuditActionToolExecute AuditAction = "tool_execute"
|
||||
AuditActionToolApprove AuditAction = "tool_approve"
|
||||
AuditActionToolReject AuditAction = "tool_reject"
|
||||
AuditActionAgentCreate AuditAction = "agent_create"
|
||||
AuditActionAgentUpdate AuditAction = "agent_update"
|
||||
AuditActionAgentDelete AuditAction = "agent_delete"
|
||||
)
|
||||
|
||||
// AuditLog 审计日志
|
||||
type AuditLog struct {
|
||||
ID string `json:"id" gorm:"primaryKey"`
|
||||
UserID string `json:"user_id" gorm:"size:50;index"`
|
||||
AgentID string `json:"agent_id" gorm:"size:50;index"`
|
||||
Action AuditAction `json:"action" gorm:"size:50;index"`
|
||||
Details JSONMap `json:"details" gorm:"type:jsonb"`
|
||||
Result string `json:"result" gorm:"size:20"` // success, failed, rejected
|
||||
IPAddress string `json:"ip_address" gorm:"size:45"`
|
||||
UserAgent string `json:"user_agent" gorm:"size:255"`
|
||||
CreatedAt time.Time `json:"created_at" gorm:"index"`
|
||||
}
|
||||
|
||||
// ApprovalStatus 审批状态
|
||||
type ApprovalStatus string
|
||||
|
||||
const (
|
||||
ApprovalStatusPending ApprovalStatus = "pending"
|
||||
ApprovalStatusApproved ApprovalStatus = "approved"
|
||||
ApprovalStatusRejected ApprovalStatus = "rejected"
|
||||
)
|
||||
|
||||
// ToolApprovalRequest 工具审批请求
|
||||
type ToolApprovalRequest struct {
|
||||
ID string `json:"id" gorm:"primaryKey"`
|
||||
ToolName string `json:"tool_name" gorm:"size:100;index"`
|
||||
Params JSONMap `json:"params" gorm:"type:jsonb"`
|
||||
UserID string `json:"user_id" gorm:"size:50;index"`
|
||||
AgentID string `json:"agent_id" gorm:"size:50"`
|
||||
Reason string `json:"reason" gorm:"type:text"`
|
||||
Status ApprovalStatus `json:"status" gorm:"size:20;default:'pending';index"`
|
||||
ReviewedBy *string `json:"reviewed_by" gorm:"size:50"`
|
||||
ReviewedAt *time.Time `json:"reviewed_at"`
|
||||
Result *string `json:"result" gorm:"type:text"` // 执行结果
|
||||
CreatedAt time.Time `json:"created_at" gorm:"index"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
// JSONMap JSON数据映射
|
||||
type JSONMap map[string]interface{}
|
||||
|
||||
func (j JSONMap) MarshalJSON() ([]byte, error) {
|
||||
if j == nil {
|
||||
return []byte("null"), nil
|
||||
}
|
||||
return json.Marshal(j)
|
||||
}
|
||||
|
||||
func (j *JSONMap) UnmarshalJSON(data []byte) error {
|
||||
if j == nil {
|
||||
*j = make(map[string]interface{})
|
||||
}
|
||||
return json.Unmarshal(data, j)
|
||||
}
|
||||
83
server/internal/model/database_info.go
Normal file
83
server/internal/model/database_info.go
Normal file
@@ -0,0 +1,83 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// DatabaseInfo 数据库连接信息
|
||||
type DatabaseInfo struct {
|
||||
ID string `json:"id" gorm:"primaryKey;size:36"` // UUID
|
||||
Name string `json:"name" gorm:"size:100;not null"` // 数据库名称
|
||||
Description string `json:"description" gorm:"size:500"` // 描述
|
||||
DBType string `json:"db_type" gorm:"size:20;not null"` // 数据库类型: mysql, postgres, mongodb等
|
||||
Host string `json:"host" gorm:"size:255;not null"` // 主机地址
|
||||
Port int `json:"port" gorm:"not null"` // 端口
|
||||
Username string `json:"username" gorm:"size:100;not null"` // 用户名
|
||||
Password string `json:"password" gorm:"size:255"` // 密码(建议加密存储)
|
||||
Database string `json:"database" gorm:"size:100"` // 数据库名
|
||||
TableCount int `json:"table_count" gorm:"default:0"` // 子表数量
|
||||
|
||||
// 连接选项
|
||||
Charset string `json:"charset" gorm:"size:20;default:utf8mb4"` // 字符集
|
||||
SSLMode string `json:"ssl_mode" gorm:"size:20"` // SSL模式
|
||||
|
||||
// 时间
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
// TableName 表名
|
||||
func (DatabaseInfo) TableName() string {
|
||||
return "database_info"
|
||||
}
|
||||
|
||||
// CreateRequest 创建数据库信息请求(支持同时保存子表配置)
|
||||
type CreateDatabaseRequest struct {
|
||||
Name string `json:"name" binding:"required"`
|
||||
Description string `json:"description"`
|
||||
DBType string `json:"db_type" binding:"required"`
|
||||
Host string `json:"host" binding:"required"`
|
||||
Port int `json:"port" binding:"required"`
|
||||
Username string `json:"username" binding:"required"`
|
||||
Password string `json:"password"`
|
||||
Database string `json:"database"`
|
||||
Charset string `json:"charset"`
|
||||
SSLMode string `json:"ssl_mode"`
|
||||
SubTables []CreateSubTableRequest `json:"sub_tables"` // 可选,子表配置
|
||||
}
|
||||
|
||||
// UpdateRequest 更新数据库信息请求
|
||||
type UpdateDatabaseRequest struct {
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
DBType string `json:"db_type"`
|
||||
Host string `json:"host"`
|
||||
Port int `json:"port"`
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
Database string `json:"database"`
|
||||
TableCount int `json:"table_count"`
|
||||
Charset string `json:"charset"`
|
||||
SSLMode string `json:"ssl_mode"`
|
||||
}
|
||||
|
||||
// CheckRequest 检查连接请求
|
||||
type CheckRequest struct {
|
||||
DBType string `json:"db_type" binding:"required"`
|
||||
Host string `json:"host" binding:"required"`
|
||||
Port int `json:"port" binding:"required"`
|
||||
Username string `json:"username" binding:"required"`
|
||||
Password string `json:"password"`
|
||||
Database string `json:"database"`
|
||||
Charset string `json:"charset"`
|
||||
SSLMode string `json:"ssl_mode"`
|
||||
DatabaseID string `json:"database_id"` // 可选,用于获取已保存的字段映射
|
||||
}
|
||||
|
||||
// CheckResponse 检查连接响应
|
||||
type CheckResponse struct {
|
||||
Success bool `json:"success"` // 是否连接成功
|
||||
Message string `json:"message"` // 消息
|
||||
Tables []TableDDLInfo `json:"tables,omitempty"` // 表列表(连接成功时返回)
|
||||
Database string `json:"database"` // 数据库名
|
||||
}
|
||||
117
server/internal/model/sub_table_info.go
Normal file
117
server/internal/model/sub_table_info.go
Normal file
@@ -0,0 +1,117 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"time"
|
||||
)
|
||||
|
||||
// TableDDLInfo 表结构信息
|
||||
type TableDDLInfo struct {
|
||||
TableName string `json:"table_name"` // 表名
|
||||
TableComment string `json:"table_comment"` // 表注释
|
||||
Columns []ColumnInfo `json:"columns"` // 列信息
|
||||
DDL string `json:"ddl"` // 建表DDL
|
||||
Indexes []IndexInfo `json:"indexes"` // 索引信息
|
||||
}
|
||||
|
||||
// ColumnInfo 列信息
|
||||
type ColumnInfo struct {
|
||||
ColumnName string `json:"column_name"` // 列名
|
||||
DataType string `json:"data_type"` // 数据类型
|
||||
ColumnType string `json:"column_type"` // 列类型(含长度)
|
||||
IsNullable string `json:"is_nullable"` // 是否可空
|
||||
DefaultValue string `json:"default_value"` // 默认值
|
||||
ColumnKey string `json:"column_key"` // 主键/索引
|
||||
Extra string `json:"extra"` // 自增等
|
||||
ColumnComment string `json:"column_comment"` // 列注释
|
||||
MappedName string `json:"mapped_name"` // 字段中文映射名
|
||||
}
|
||||
|
||||
// IndexInfo 索引信息
|
||||
type IndexInfo struct {
|
||||
IndexName string `json:"index_name"` // 索引名
|
||||
ColumnName string `json:"column_name"` // 列名
|
||||
NonUnique int `json:"non_unique"` // 是否唯一
|
||||
IndexType string `json:"index_type"` // 索引类型
|
||||
}
|
||||
|
||||
// SubTableInfo 子表信息
|
||||
type SubTableInfo struct {
|
||||
ID string `json:"id"` // UUID
|
||||
DatabaseID string `json:"database_id"` // 关联的数据库ID
|
||||
ParentTable string `json:"parent_table"` // 父表名
|
||||
SubTableName string `json:"sub_table_name"` // 子表名
|
||||
SubTableComment string `json:"sub_table_comment"` // 子表注释
|
||||
MappingType string `json:"mapping_type" gorm:"type:varchar(20)"` // 映射类型
|
||||
RelationField string `json:"relation_field" gorm:"type:varchar(100)"` // 关联字段
|
||||
RelationType string `json:"relation_type" gorm:"type:varchar(20)"` // 关联类型
|
||||
Fields string `json:"-" gorm:"type:longtext"` // 字段映射列表(JSON 格式,内部存储)
|
||||
FieldsList []FieldMapping `json:"fields" gorm:"-"` // 字段映射列表(返回给前端)
|
||||
DDL string `json:"ddl" gorm:"type:longtext"` // 建表 DDL
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
// FieldMapping 字段映射
|
||||
type FieldMapping struct {
|
||||
ColumnName string `json:"column_name"` // 列名
|
||||
MappedName string `json:"mapped_name"` // 中文映射名
|
||||
}
|
||||
|
||||
// GetFields 获取字段映射列表
|
||||
func (s *SubTableInfo) GetFields() []FieldMapping {
|
||||
if s.Fields == "" {
|
||||
return nil
|
||||
}
|
||||
var fields []FieldMapping
|
||||
if err := json.Unmarshal([]byte(s.Fields), &fields); err != nil {
|
||||
return nil
|
||||
}
|
||||
return fields
|
||||
}
|
||||
|
||||
// SetFields 设置字段映射列表
|
||||
func (s *SubTableInfo) SetFields(fields []FieldMapping) {
|
||||
if len(fields) == 0 {
|
||||
s.Fields = ""
|
||||
return
|
||||
}
|
||||
data, _ := json.Marshal(fields)
|
||||
s.Fields = string(data)
|
||||
}
|
||||
|
||||
// TableName 表名
|
||||
func (SubTableInfo) TableName() string {
|
||||
return "sub_table_info"
|
||||
}
|
||||
|
||||
// CreateSubTableRequest 创建子表请求
|
||||
type CreateSubTableRequest struct {
|
||||
DatabaseID string `json:"database_id" binding:"required"`
|
||||
ParentTable string `json:"parent_table" binding:"required"`
|
||||
SubTableName string `json:"sub_table_name" binding:"required"`
|
||||
SubTableComment string `json:"sub_table_comment"`
|
||||
MappingType string `json:"mapping_type"`
|
||||
RelationField string `json:"relation_field"`
|
||||
RelationType string `json:"relation_type"`
|
||||
Fields []FieldMapping `json:"fields"` // 字段映射列表
|
||||
}
|
||||
|
||||
// UpdateSubTableRequest 更新子表请求
|
||||
type UpdateSubTableRequest struct {
|
||||
ParentTable string `json:"parent_table"`
|
||||
SubTableName string `json:"sub_table_name"`
|
||||
SubTableComment string `json:"sub_table_comment"`
|
||||
MappingType string `json:"mapping_type"`
|
||||
RelationField string `json:"relation_field"`
|
||||
RelationType string `json:"relation_type"`
|
||||
}
|
||||
|
||||
// SubTableMapping 完整的子表映射配置(存储到文件的格式)
|
||||
type SubTableMapping struct {
|
||||
DatabaseID string `json:"database_id"`
|
||||
DatabaseName string `json:"database_name"`
|
||||
DBType string `json:"db_type"`
|
||||
Tables []SubTableInfo `json:"tables"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
25
server/internal/model/system_info.go
Normal file
25
server/internal/model/system_info.go
Normal file
@@ -0,0 +1,25 @@
|
||||
package model
|
||||
|
||||
// SystemInfo 系统信息
|
||||
type SystemInfo struct {
|
||||
CPU CPUInfo `json:"cpu"`
|
||||
Memory MemoryInfo `json:"memory"`
|
||||
}
|
||||
|
||||
// CPUInfo CPU信息
|
||||
type CPUInfo struct {
|
||||
Percent float64 `json:"percent"` // CPU使用率
|
||||
CoreCount int `json:"core_count"` // 核心数
|
||||
ModelName string `json:"model_name"` // CPU型号
|
||||
}
|
||||
|
||||
// MemoryInfo 内存信息
|
||||
type MemoryInfo struct {
|
||||
Total uint64 `json:"total"` // 总内存(字节)
|
||||
Used uint64 `json:"used"` // 已使用(字节)
|
||||
Available uint64 `json:"available"` // 可用(字节)
|
||||
Percent float64 `json:"percent"` // 使用率
|
||||
TotalGB float64 `json:"total_gb"` // 总内存(GB)
|
||||
UsedGB float64 `json:"used_gb"` // 已使用(GB)
|
||||
AvailableGB float64 `json:"available_gb"` // 可用(GB)
|
||||
}
|
||||
50
server/internal/model/user.go
Normal file
50
server/internal/model/user.go
Normal file
@@ -0,0 +1,50 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// PermissionLevel 权限级别
|
||||
type PermissionLevel int
|
||||
|
||||
const (
|
||||
PermissionRead PermissionLevel = iota + 1
|
||||
PermissionWrite
|
||||
PermissionExecute
|
||||
PermissionAdmin
|
||||
)
|
||||
|
||||
// Role 角色
|
||||
type Role struct {
|
||||
ID string `json:"id" gorm:"primaryKey"`
|
||||
Name string `json:"name" gorm:"uniqueIndex"`
|
||||
Permissions []PermissionLevel `json:"permissions" gorm:"type:int[]"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
// User 用户
|
||||
type User struct {
|
||||
ID string `json:"id" gorm:"primaryKey"`
|
||||
Username string `json:"username" gorm:"uniqueIndex;size:50;not null"`
|
||||
Password string `json:"-" gorm:"not null"`
|
||||
Email string `json:"email" gorm:"index"`
|
||||
RoleID string `json:"role_id" gorm:"size:50;not null"`
|
||||
Role *Role `json:"role,omitempty" gorm:"foreignKey:RoleID"`
|
||||
IsActive bool `json:"is_active" gorm:"default:true"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
// HasPermission 检查是否有权限
|
||||
func (u *User) HasPermission(level PermissionLevel) bool {
|
||||
if u.Role == nil {
|
||||
return false
|
||||
}
|
||||
for _, p := range u.Role.Permissions {
|
||||
if p >= level {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
Reference in New Issue
Block a user