🎨 优化项目结构 && 完善ai配置
This commit is contained in:
@@ -1,230 +0,0 @@
|
||||
# AI 中转代理系统 - App 模块
|
||||
|
||||
## 已完成的功能模块
|
||||
|
||||
按照 server 目录的标准结构,已将 AI 中转代理项目的代码编写到各个 `app` 目录下:
|
||||
|
||||
### 1. Model 层 (server/model/app/)
|
||||
|
||||
**核心模型:**
|
||||
- `ai_preset.go` - AI 预设模板模型(支持 SillyTavern 格式)
|
||||
- `ai_provider.go` - AI 服务提供商模型
|
||||
- `ai_preset_binding.go` - 用户-预设-提供商绑定模型
|
||||
- `ai_request_log.go` - AI 请求日志模型
|
||||
- `ai_preset_types.go` - 预设相关的自定义类型
|
||||
|
||||
**Request 结构体 (server/model/app/request/):**
|
||||
- `ai_preset.go` - 预设相关请求(创建、更新、导入)
|
||||
- `ai_provider.go` - 提供商相关请求(创建、更新)
|
||||
- `ai_proxy.go` - 代理请求(聊天补全、消息、角色卡片)
|
||||
|
||||
**Response 结构体 (server/model/app/response/):**
|
||||
- `ai_proxy.go` - 代理响应(OpenAI 兼容格式)
|
||||
|
||||
### 2. Service 层 (server/service/app/)
|
||||
|
||||
- `ai_preset.go` - 预设服务(CRUD、导入导出)
|
||||
- `ai_provider.go` - 提供商服务(CRUD、连接测试)
|
||||
- `ai_proxy.go` - 代理服务(核心预设注入引擎、转发到上游 AI)
|
||||
- `enter.go` - Service 统一入口
|
||||
|
||||
### 3. API 层 (server/api/v1/app/)
|
||||
|
||||
- `ai_preset.go` - 预设管理 API
|
||||
- `ai_provider.go` - 提供商管理 API
|
||||
- `ai_proxy.go` - 代理转发 API(OpenAI 兼容接口)
|
||||
- `enter.go` - API 统一入口
|
||||
|
||||
### 4. Router 层 (server/router/app/)
|
||||
|
||||
- `ai_preset.go` - 预设路由
|
||||
- `ai_provider.go` - 提供商路由
|
||||
- `ai_proxy.go` - 代理路由
|
||||
- `enter.go` - Router 统一入口
|
||||
|
||||
## 核心功能特性
|
||||
|
||||
### 1. AI 预设管理
|
||||
- ✅ 创建、更新、删除预设
|
||||
- ✅ 获取预设列表和详情
|
||||
- ✅ 导入 SillyTavern 格式预设
|
||||
- ✅ 导出预设为 JSON
|
||||
- ✅ 支持公开/私有预设
|
||||
- ✅ 完整的 Prompt 注入配置
|
||||
- ✅ 正则脚本处理
|
||||
|
||||
### 2. AI 服务提供商管理
|
||||
- ✅ 创建、更新、删除提供商
|
||||
- ✅ 获取提供商列表和详情
|
||||
- ✅ 支持自定义配置
|
||||
- ✅ 启用/禁用状态管理
|
||||
|
||||
### 3. AI 代理服务
|
||||
- ✅ OpenAI 兼容的聊天补全接口
|
||||
- ✅ 预设注入引擎
|
||||
- ✅ 变量替换({{user}}, {{char}})
|
||||
- ✅ 正则脚本处理(输入/输出)
|
||||
- ✅ 转发到上游 AI 服务
|
||||
- ✅ 请求日志记录
|
||||
- ⏳ 流式响应(待实现)
|
||||
|
||||
## API 端点
|
||||
|
||||
### 预设管理
|
||||
```
|
||||
POST /app/preset # 创建预设
|
||||
PUT /app/preset # 更新预设
|
||||
DELETE /app/preset/:id # 删除预设
|
||||
GET /app/preset/:id # 获取预设详情
|
||||
GET /app/preset/list # 获取预设列表
|
||||
POST /app/preset/import # 导入预设
|
||||
GET /app/preset/:id/export # 导出预设
|
||||
```
|
||||
|
||||
### 提供商管理
|
||||
```
|
||||
POST /app/provider # 创建提供商
|
||||
PUT /app/provider # 更新提供商
|
||||
DELETE /app/provider/:id # 删除提供商
|
||||
GET /app/provider/:id # 获取提供商详情
|
||||
GET /app/provider/list # 获取提供商列表
|
||||
```
|
||||
|
||||
### 代理接口(OpenAI 兼容)
|
||||
```
|
||||
POST /v1/chat/completions # 聊天补全
|
||||
```
|
||||
|
||||
## 数据模型说明
|
||||
|
||||
### AiPreset(预设模板)
|
||||
```go
|
||||
- UserID: 用户ID
|
||||
- Name: 预设名称
|
||||
- Description: 预设描述
|
||||
- Prompts: 提示词数组(支持 SillyTavern 格式)
|
||||
- RegexScripts: 正则脚本数组
|
||||
- Temperature, TopP, MaxTokens: 模型参数
|
||||
- StreamEnabled: 是否启用流式
|
||||
- IsDefault: 是否默认
|
||||
- IsPublic: 是否公开
|
||||
```
|
||||
|
||||
### Prompt(提示词)
|
||||
```go
|
||||
- Name: 提示词名称
|
||||
- Role: 角色(system/user/assistant)
|
||||
- Content: 提示词内容
|
||||
- Identifier: 标识符
|
||||
- InjectionPosition: 注入位置
|
||||
- InjectionDepth: 注入深度
|
||||
- InjectionOrder: 注入顺序
|
||||
- Marker: 是否为占位符
|
||||
```
|
||||
|
||||
### RegexScript(正则脚本)
|
||||
```go
|
||||
- ScriptName: 脚本名称
|
||||
- FindRegex: 查找正则
|
||||
- ReplaceString: 替换字符串
|
||||
- Placement: 应用位置(1=输入, 2=输出)
|
||||
- MinDepth, MaxDepth: 深度限制
|
||||
```
|
||||
|
||||
## 预设注入流程
|
||||
|
||||
1. 接收用户请求
|
||||
2. 加载预设配置
|
||||
3. 按 injection_order 排序 prompts
|
||||
4. 根据 injection_depth 插入到对话历史中
|
||||
5. 替换变量({{user}}, {{char}})
|
||||
6. 应用正则脚本(placement=1 处理输入)
|
||||
7. 转发到上游 AI
|
||||
8. 应用正则脚本(placement=2 处理输出)
|
||||
9. 记录日志
|
||||
10. 返回响应
|
||||
|
||||
## 待完善功能
|
||||
|
||||
1. **完整的预设注入引擎**
|
||||
- 完整实现 injection_depth 逻辑
|
||||
- 完整实现正则脚本处理
|
||||
- 支持更多变量替换
|
||||
|
||||
2. **流式响应**
|
||||
- 实现 SSE 流式输出
|
||||
- 支持流式日志记录
|
||||
|
||||
3. **预设绑定管理**
|
||||
- 实现 binding_key 机制
|
||||
- 支持多预设切换
|
||||
|
||||
4. **导入导出**
|
||||
- 完善 SillyTavern JSON 解析
|
||||
- 支持批量导入导出
|
||||
|
||||
## 使用示例
|
||||
|
||||
### 1. 创建 AI 提供商
|
||||
```bash
|
||||
POST /app/provider
|
||||
{
|
||||
"name": "OpenAI",
|
||||
"baseUrl": "https://api.openai.com/v1",
|
||||
"apiKey": "sk-xxx",
|
||||
"model": "gpt-4",
|
||||
"isActive": true
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 导入 SillyTavern 预设
|
||||
```bash
|
||||
POST /app/preset/import
|
||||
{
|
||||
"name": "TG角色扮演",
|
||||
"data": { ... } // TGbreak.json 内容
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 发送聊天请求
|
||||
```bash
|
||||
POST /v1/chat/completions
|
||||
{
|
||||
"messages": [
|
||||
{"role": "user", "content": "你好"}
|
||||
],
|
||||
"presetId": 1,
|
||||
"characterCard": {
|
||||
"name": "小美",
|
||||
"description": "活泼的女孩"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 项目结构
|
||||
|
||||
```
|
||||
server/
|
||||
├── model/app/ # 数据模型
|
||||
│ ├── ai_preset.go
|
||||
│ ├── ai_provider.go
|
||||
│ ├── ai_preset_binding.go
|
||||
│ ├── ai_request_log.go
|
||||
│ ├── request/ # 请求结构体
|
||||
│ └── response/ # 响应结构体
|
||||
├── service/app/ # 业务逻辑
|
||||
│ ├── ai_preset.go
|
||||
│ ├── ai_provider.go
|
||||
│ ├── ai_proxy.go
|
||||
│ └── enter.go
|
||||
├── api/v1/app/ # API 处理器
|
||||
│ ├── ai_preset.go
|
||||
│ ├── ai_provider.go
|
||||
│ ├── ai_proxy.go
|
||||
│ └── enter.go
|
||||
└── router/app/ # 路由注册
|
||||
├── ai_preset.go
|
||||
├── ai_provider.go
|
||||
├── ai_proxy.go
|
||||
└── enter.go
|
||||
```
|
||||
@@ -4,51 +4,62 @@ import (
|
||||
"git.echol.cn/loser/ai_proxy/server/global"
|
||||
)
|
||||
|
||||
// AiPreset AI预设模板
|
||||
// AiPreset AI预设模型
|
||||
type AiPreset struct {
|
||||
global.GVA_MODEL
|
||||
UserID uint `json:"userId" gorm:"comment:用户ID;index"`
|
||||
Name string `json:"name" gorm:"comment:预设名称;size:200;not null"`
|
||||
Description string `json:"description" gorm:"comment:预设描述;type:text"`
|
||||
Prompts Prompts `json:"prompts" gorm:"comment:提示词数组;type:jsonb;not null"`
|
||||
RegexScripts RegexScripts `json:"regexScripts" gorm:"comment:正则脚本;type:jsonb"`
|
||||
Temperature float64 `json:"temperature" gorm:"comment:温度;default:1.0"`
|
||||
TopP float64 `json:"topP" gorm:"comment:TopP;default:0.9"`
|
||||
MaxTokens int `json:"maxTokens" gorm:"comment:最大Token数;default:4096"`
|
||||
FrequencyPenalty float64 `json:"frequencyPenalty" gorm:"comment:频率惩罚;default:0"`
|
||||
PresencePenalty float64 `json:"presencePenalty" gorm:"comment:存在惩罚;default:0"`
|
||||
StreamEnabled bool `json:"streamEnabled" gorm:"comment:是否启用流式;default:true"`
|
||||
IsDefault bool `json:"isDefault" gorm:"comment:是否默认;default:false"`
|
||||
IsPublic bool `json:"isPublic" gorm:"comment:是否公开;default:false"`
|
||||
Name string `json:"name" gorm:"type:varchar(100);not null;uniqueIndex;comment:预设名称"`
|
||||
Description string `json:"description" gorm:"type:text;comment:预设描述"`
|
||||
Temperature float64 `json:"temperature" gorm:"type:decimal(3,2);default:1.0;comment:温度"`
|
||||
FrequencyPenalty float64 `json:"frequency_penalty" gorm:"type:decimal(3,2);default:0;comment:频率惩罚"`
|
||||
PresencePenalty float64 `json:"presence_penalty" gorm:"type:decimal(3,2);default:0;comment:存在惩罚"`
|
||||
TopP float64 `json:"top_p" gorm:"type:decimal(3,2);default:0.9;comment:Top P"`
|
||||
TopK int `json:"top_k" gorm:"type:int;default:0;comment:Top K"`
|
||||
MaxTokens int `json:"max_tokens" gorm:"type:int;default:4096;comment:最大token数"`
|
||||
Prompts PresetPrompts `json:"prompts" gorm:"type:json;comment:提示词列表"`
|
||||
PromptOrder []PromptOrder `json:"prompt_order" gorm:"type:json;comment:提示词顺序"`
|
||||
RegexScripts []RegexScript `json:"regex_scripts" gorm:"type:json;comment:正则脚本"`
|
||||
Extensions PresetExtensions `json:"extensions" gorm:"type:json;comment:扩展配置"`
|
||||
Enabled bool `json:"enabled" gorm:"default:true;comment:是否启用"`
|
||||
UserID uint `json:"user_id" gorm:"index;comment:用户ID"`
|
||||
}
|
||||
|
||||
func (AiPreset) TableName() string {
|
||||
return "ai_presets"
|
||||
}
|
||||
|
||||
// Prompt 提示词结构
|
||||
type Prompt struct {
|
||||
Name string `json:"name"`
|
||||
SystemPrompt bool `json:"system_prompt"`
|
||||
Role string `json:"role"`
|
||||
Content string `json:"content"`
|
||||
// PresetPrompt 预设提示词
|
||||
type PresetPrompt struct {
|
||||
Identifier string `json:"identifier"`
|
||||
InjectionPosition int `json:"injection_position"`
|
||||
Name string `json:"name"`
|
||||
Role string `json:"role"` // system, user, assistant
|
||||
Content string `json:"content"`
|
||||
SystemPrompt bool `json:"system_prompt"`
|
||||
Enabled bool `json:"enabled"`
|
||||
Marker bool `json:"marker"`
|
||||
InjectionPosition int `json:"injection_position"` // 0=相对, 1=绝对
|
||||
InjectionDepth int `json:"injection_depth"`
|
||||
InjectionOrder int `json:"injection_order"`
|
||||
InjectionTrigger []string `json:"injection_trigger"`
|
||||
Marker bool `json:"marker"`
|
||||
ForbidOverrides bool `json:"forbid_overrides"`
|
||||
}
|
||||
|
||||
// RegexScript 正则脚本
|
||||
type PresetPrompts []PresetPrompt
|
||||
|
||||
// PromptOrder 提示词顺序配置
|
||||
type PromptOrder struct {
|
||||
CharacterID int `json:"character_id"`
|
||||
Order []PromptOrderItem `json:"order"`
|
||||
}
|
||||
|
||||
type PromptOrderItem struct {
|
||||
Identifier string `json:"identifier"`
|
||||
Enabled bool `json:"enabled"`
|
||||
}
|
||||
|
||||
// RegexScript 正则替换脚本
|
||||
type RegexScript struct {
|
||||
ID string `json:"id"`
|
||||
ScriptName string `json:"scriptName"`
|
||||
FindRegex string `json:"findRegex"`
|
||||
ReplaceString string `json:"replaceString"`
|
||||
TrimStrings []string `json:"trimStrings"`
|
||||
Placement []int `json:"placement"`
|
||||
Placement []int `json:"placement"` // 1=用户输入前, 2=AI输出后
|
||||
Disabled bool `json:"disabled"`
|
||||
MarkdownOnly bool `json:"markdownOnly"`
|
||||
PromptOnly bool `json:"promptOnly"`
|
||||
@@ -57,3 +68,38 @@ type RegexScript struct {
|
||||
MinDepth *int `json:"minDepth"`
|
||||
MaxDepth *int `json:"maxDepth"`
|
||||
}
|
||||
|
||||
// PresetExtensions 预设扩展配置
|
||||
type PresetExtensions struct {
|
||||
ChatSquash *ChatSquashConfig `json:"ChatSquash,omitempty"`
|
||||
RegexBinding *RegexBindingConfig `json:"RegexBinding,omitempty"`
|
||||
MacroNest bool `json:"MacroNest"`
|
||||
}
|
||||
|
||||
type ChatSquashConfig struct {
|
||||
Enabled bool `json:"enabled"`
|
||||
SeparateChatHistory bool `json:"separate_chat_history"`
|
||||
ParseClewd bool `json:"parse_clewd"`
|
||||
UserRoleSystem bool `json:"user_role_system"`
|
||||
Role string `json:"role"`
|
||||
StopString string `json:"stop_string"`
|
||||
UserPrefix string `json:"user_prefix"`
|
||||
UserSuffix string `json:"user_suffix"`
|
||||
CharPrefix string `json:"char_prefix"`
|
||||
CharSuffix string `json:"char_suffix"`
|
||||
PrefixSystem string `json:"prefix_system"`
|
||||
SuffixSystem string `json:"suffix_system"`
|
||||
EnableSquashedSeparator bool `json:"enable_squashed_separator"`
|
||||
SquashedSeparatorRegex bool `json:"squashed_separator_regex"`
|
||||
SquashedSeparatorString string `json:"squashed_separator_string"`
|
||||
SquashedPostScriptEnable bool `json:"squashed_post_script_enable"`
|
||||
SquashedPostScript string `json:"squashed_post_script"`
|
||||
}
|
||||
|
||||
type RegexBindingConfig struct {
|
||||
Regexes []RegexScript `json:"regexes"`
|
||||
}
|
||||
|
||||
func (AiPreset) TableName() string {
|
||||
return "ai_presets"
|
||||
}
|
||||
|
||||
@@ -4,13 +4,14 @@ import (
|
||||
"git.echol.cn/loser/ai_proxy/server/global"
|
||||
)
|
||||
|
||||
// AiPresetBinding 预设-提供商绑定关系
|
||||
// AiPresetBinding 预设绑定关系
|
||||
type AiPresetBinding struct {
|
||||
global.GVA_MODEL
|
||||
PresetID uint `json:"presetId" gorm:"comment:预设ID;index"`
|
||||
ProviderID uint `json:"providerId" gorm:"comment:提供商ID;index"`
|
||||
Priority int `json:"priority" gorm:"comment:优先级;default:0"` // 多个预设时的执行顺序
|
||||
IsActive bool `json:"isActive" gorm:"comment:是否启用;default:true"`
|
||||
Name string `json:"name" gorm:"type:varchar(100);not null;uniqueIndex:idx_user_binding;comment:绑定名称"`
|
||||
PresetID uint `json:"preset_id" gorm:"not null;index;comment:预设ID"`
|
||||
ProviderID uint `json:"provider_id" gorm:"not null;index;comment:提供商ID"`
|
||||
Enabled bool `json:"enabled" gorm:"default:true;comment:是否启用"`
|
||||
UserID uint `json:"user_id" gorm:"index:idx_user_binding;comment:用户ID"`
|
||||
|
||||
// 关联
|
||||
Preset AiPreset `json:"preset" gorm:"foreignKey:PresetID"`
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"database/sql/driver"
|
||||
"encoding/json"
|
||||
)
|
||||
|
||||
// Prompts 提示词数组类型
|
||||
type Prompts []Prompt
|
||||
|
||||
func (p Prompts) Value() (driver.Value, error) {
|
||||
return json.Marshal(p)
|
||||
}
|
||||
|
||||
func (p *Prompts) Scan(value interface{}) error {
|
||||
bytes, ok := value.([]byte)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
return json.Unmarshal(bytes, p)
|
||||
}
|
||||
|
||||
// RegexScripts 正则脚本数组类型
|
||||
type RegexScripts []RegexScript
|
||||
|
||||
func (r RegexScripts) Value() (driver.Value, error) {
|
||||
return json.Marshal(r)
|
||||
}
|
||||
|
||||
func (r *RegexScripts) Scan(value interface{}) error {
|
||||
bytes, ok := value.([]byte)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
return json.Unmarshal(bytes, r)
|
||||
}
|
||||
@@ -4,18 +4,19 @@ import (
|
||||
"git.echol.cn/loser/ai_proxy/server/global"
|
||||
)
|
||||
|
||||
// AiProvider AI服务提供商配置
|
||||
// AiProvider AI提供商配置
|
||||
type AiProvider struct {
|
||||
global.GVA_MODEL
|
||||
Name string `json:"name" gorm:"comment:提供商名称;size:100;not null;uniqueIndex"`
|
||||
Type string `json:"type" gorm:"comment:提供商类型;size:50;not null"` // openai, claude, gemini 等
|
||||
BaseURL string `json:"baseUrl" gorm:"comment:API基础地址;size:500;not null"`
|
||||
Endpoint string `json:"endpoint" gorm:"comment:API端点;size:200"` // 如 /v1/chat/completions
|
||||
UpstreamKey string `json:"upstreamKey" gorm:"comment:上游API密钥;type:text"` // 上游 AI 的 key
|
||||
Model string `json:"model" gorm:"comment:默认模型;size:100"`
|
||||
ProxyKey string `json:"proxyKey" gorm:"comment:代理访问密钥;size:100;uniqueIndex"` // 用户访问本代理时使用的 key
|
||||
Config map[string]interface{} `json:"config" gorm:"comment:额外配置;type:jsonb;serializer:json"`
|
||||
IsActive bool `json:"isActive" gorm:"comment:是否启用;default:true"`
|
||||
Name string `json:"name" gorm:"type:varchar(100);not null;uniqueIndex:idx_user_provider;comment:提供商名称"`
|
||||
Type string `json:"type" gorm:"type:varchar(50);not null;comment:提供商类型"` // openai, claude, gemini
|
||||
BaseURL string `json:"base_url" gorm:"type:varchar(255);not null;comment:API基础URL"`
|
||||
APIKey string `json:"api_key" gorm:"type:varchar(255);not null;comment:API密钥"`
|
||||
Model string `json:"model" gorm:"type:varchar(100);comment:默认模型"`
|
||||
Enabled bool `json:"enabled" gorm:"default:true;comment:是否启用"`
|
||||
Priority int `json:"priority" gorm:"default:0;comment:优先级"`
|
||||
MaxRetries int `json:"max_retries" gorm:"default:3;comment:最大重试次数"`
|
||||
Timeout int `json:"timeout" gorm:"default:60;comment:超时时间(秒)"`
|
||||
UserID uint `json:"user_id" gorm:"index:idx_user_provider;comment:用户ID"`
|
||||
}
|
||||
|
||||
func (AiProvider) TableName() string {
|
||||
|
||||
@@ -2,23 +2,24 @@ package app
|
||||
|
||||
import (
|
||||
"git.echol.cn/loser/ai_proxy/server/global"
|
||||
"time"
|
||||
)
|
||||
|
||||
// AiRequestLog AI请求日志
|
||||
type AiRequestLog struct {
|
||||
global.GVA_MODEL
|
||||
UserID *uint `json:"userId" gorm:"comment:用户ID;index"`
|
||||
PresetID *uint `json:"presetId" gorm:"comment:预设ID"`
|
||||
ProviderID *uint `json:"providerId" gorm:"comment:提供商ID"`
|
||||
OriginalMessage string `json:"originalMessage" gorm:"comment:原始消息;type:text"`
|
||||
InjectedPrompt map[string]interface{} `json:"injectedPrompt" gorm:"comment:注入后的提示词;type:jsonb;serializer:json"`
|
||||
ResponseText string `json:"responseText" gorm:"comment:响应文本;type:text"`
|
||||
ResponseTokens int `json:"responseTokens" gorm:"comment:响应Token数"`
|
||||
PromptTokens int `json:"promptTokens" gorm:"comment:提示Token数"`
|
||||
TotalTokens int `json:"totalTokens" gorm:"comment:总Token数"`
|
||||
LatencyMs int `json:"latencyMs" gorm:"comment:延迟(毫秒)"`
|
||||
Status string `json:"status" gorm:"comment:状态;size:20"` // success/error/timeout
|
||||
ErrorMessage string `json:"errorMessage" gorm:"comment:错误信息;type:text"`
|
||||
UserID uint `json:"user_id" gorm:"index;comment:用户ID"`
|
||||
BindingID uint `json:"binding_id" gorm:"index;comment:绑定ID"`
|
||||
ProviderID uint `json:"provider_id" gorm:"index;comment:提供商ID"`
|
||||
PresetID uint `json:"preset_id" gorm:"index;comment:预设ID"`
|
||||
Model string `json:"model" gorm:"type:varchar(100);comment:使用的模型"`
|
||||
PromptTokens int `json:"prompt_tokens" gorm:"comment:输入token数"`
|
||||
CompletionTokens int `json:"completion_tokens" gorm:"comment:输出token数"`
|
||||
TotalTokens int `json:"total_tokens" gorm:"comment:总token数"`
|
||||
Duration int64 `json:"duration" gorm:"comment:请求耗时(毫秒)"`
|
||||
Status string `json:"status" gorm:"type:varchar(20);index;comment:请求状态"` // success, error
|
||||
ErrorMessage string `json:"error_message" gorm:"type:text;comment:错误信息"`
|
||||
RequestTime time.Time `json:"request_time" gorm:"index;comment:请求时间"`
|
||||
}
|
||||
|
||||
func (AiRequestLog) TableName() string {
|
||||
|
||||
8
server/model/app/enter.go
Normal file
8
server/model/app/enter.go
Normal file
@@ -0,0 +1,8 @@
|
||||
package app
|
||||
|
||||
var AutoMigrateTables = []interface{}{
|
||||
&AiPreset{},
|
||||
&AiProvider{},
|
||||
&AiPresetBinding{},
|
||||
&AiRequestLog{},
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
package request
|
||||
|
||||
import "git.echol.cn/loser/ai_proxy/server/model/app"
|
||||
|
||||
// CreateAiPresetRequest 创建预设请求
|
||||
type CreateAiPresetRequest struct {
|
||||
Name string `json:"name" binding:"required"`
|
||||
Description string `json:"description"`
|
||||
Prompts []app.Prompt `json:"prompts" binding:"required"`
|
||||
RegexScripts []app.RegexScript `json:"regexScripts"`
|
||||
Temperature float64 `json:"temperature"`
|
||||
TopP float64 `json:"topP"`
|
||||
MaxTokens int `json:"maxTokens"`
|
||||
FrequencyPenalty float64 `json:"frequencyPenalty"`
|
||||
PresencePenalty float64 `json:"presencePenalty"`
|
||||
StreamEnabled bool `json:"streamEnabled"`
|
||||
IsDefault bool `json:"isDefault"`
|
||||
IsPublic bool `json:"isPublic"`
|
||||
}
|
||||
|
||||
// UpdateAiPresetRequest 更新预设请求
|
||||
type UpdateAiPresetRequest struct {
|
||||
ID uint `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
Prompts []app.Prompt `json:"prompts"`
|
||||
RegexScripts []app.RegexScript `json:"regexScripts"`
|
||||
Temperature float64 `json:"temperature"`
|
||||
TopP float64 `json:"topP"`
|
||||
MaxTokens int `json:"maxTokens"`
|
||||
FrequencyPenalty float64 `json:"frequencyPenalty"`
|
||||
PresencePenalty float64 `json:"presencePenalty"`
|
||||
StreamEnabled bool `json:"streamEnabled"`
|
||||
IsDefault bool `json:"isDefault"`
|
||||
IsPublic bool `json:"isPublic"`
|
||||
}
|
||||
|
||||
// ImportAiPresetRequest 导入预设请求(支持SillyTavern格式)
|
||||
type ImportAiPresetRequest struct {
|
||||
Name string `json:"name" binding:"required"`
|
||||
Data interface{} `json:"data" binding:"required"`
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
package request
|
||||
|
||||
// CreateBindingRequest 创建绑定请求
|
||||
type CreateBindingRequest struct {
|
||||
PresetID uint `json:"presetId" binding:"required"`
|
||||
ProviderID uint `json:"providerId" binding:"required"`
|
||||
Priority int `json:"priority"`
|
||||
}
|
||||
|
||||
// UpdateBindingRequest 更新绑定请求
|
||||
type UpdateBindingRequest struct {
|
||||
ID uint `json:"id" binding:"required"`
|
||||
Priority int `json:"priority"`
|
||||
IsActive bool `json:"isActive"`
|
||||
}
|
||||
|
||||
// GetBindingListRequest 获取绑定列表请求
|
||||
type GetBindingListRequest struct {
|
||||
Page int `json:"page" form:"page"`
|
||||
PageSize int `json:"pageSize" form:"pageSize"`
|
||||
ProviderID uint `json:"providerId" form:"providerId"`
|
||||
PresetID uint `json:"presetId" form:"presetId"`
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
package request
|
||||
|
||||
// CreateAiProviderRequest 创建AI提供商请求
|
||||
type CreateAiProviderRequest struct {
|
||||
Name string `json:"name" binding:"required"`
|
||||
Type string `json:"type" binding:"required"`
|
||||
BaseURL string `json:"baseUrl" binding:"required,url"`
|
||||
Endpoint string `json:"endpoint"`
|
||||
UpstreamKey string `json:"upstreamKey" binding:"required"`
|
||||
Model string `json:"model"`
|
||||
ProxyKey string `json:"proxyKey" binding:"required"`
|
||||
Config map[string]interface{} `json:"config"`
|
||||
IsActive bool `json:"isActive"`
|
||||
}
|
||||
|
||||
// UpdateAiProviderRequest 更新AI提供商请求
|
||||
type UpdateAiProviderRequest struct {
|
||||
ID uint `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Type string `json:"type"`
|
||||
BaseURL string `json:"baseUrl"`
|
||||
Endpoint string `json:"endpoint"`
|
||||
UpstreamKey string `json:"upstreamKey"`
|
||||
Model string `json:"model"`
|
||||
ProxyKey string `json:"proxyKey"`
|
||||
Config map[string]interface{} `json:"config"`
|
||||
IsActive bool `json:"isActive"`
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
package request
|
||||
|
||||
// TestConnectionRequest 测试连接请求
|
||||
type TestConnectionRequest struct {
|
||||
BaseURL string `json:"baseUrl" binding:"required"`
|
||||
UpstreamKey string `json:"upstreamKey" binding:"required"`
|
||||
Type string `json:"type" binding:"required"` // openai, claude, gemini 等
|
||||
}
|
||||
|
||||
// GetModelsRequest 获取模型列表请求
|
||||
type GetModelsRequest struct {
|
||||
BaseURL string `json:"baseUrl" binding:"required"`
|
||||
UpstreamKey string `json:"upstreamKey" binding:"required"`
|
||||
Type string `json:"type" binding:"required"`
|
||||
}
|
||||
@@ -1,31 +1,28 @@
|
||||
package request
|
||||
|
||||
// Message 消息结构
|
||||
type Message struct {
|
||||
Role string `json:"role"`
|
||||
Content string `json:"content"`
|
||||
}
|
||||
|
||||
// CharacterCard 角色卡片
|
||||
type CharacterCard struct {
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
Personality string `json:"personality"`
|
||||
Scenario string `json:"scenario"`
|
||||
}
|
||||
|
||||
// ChatCompletionRequest 聊天补全请求(OpenAI兼容)
|
||||
// ChatCompletionRequest OpenAI兼容的聊天请求
|
||||
type ChatCompletionRequest struct {
|
||||
Model string `json:"model"`
|
||||
Messages []Message `json:"messages" binding:"required"`
|
||||
PresetID uint `json:"presetId"`
|
||||
BindingKey string `json:"bindingKey"`
|
||||
CharacterCard *CharacterCard `json:"characterCard"`
|
||||
Variables map[string]string `json:"variables"`
|
||||
Temperature *float64 `json:"temperature"`
|
||||
TopP *float64 `json:"topP"`
|
||||
MaxTokens *int `json:"maxTokens"`
|
||||
FrequencyPenalty *float64 `json:"frequencyPenalty"`
|
||||
PresencePenalty *float64 `json:"presencePenalty"`
|
||||
Stream bool `json:"stream"`
|
||||
Model string `json:"model"`
|
||||
Messages []ChatMessage `json:"messages"`
|
||||
Temperature *float64 `json:"temperature,omitempty"`
|
||||
TopP *float64 `json:"top_p,omitempty"`
|
||||
N *int `json:"n,omitempty"`
|
||||
Stream bool `json:"stream,omitempty"`
|
||||
Stop interface{} `json:"stop,omitempty"`
|
||||
MaxTokens *int `json:"max_tokens,omitempty"`
|
||||
PresencePenalty *float64 `json:"presence_penalty,omitempty"`
|
||||
FrequencyPenalty *float64 `json:"frequency_penalty,omitempty"`
|
||||
LogitBias map[string]float64 `json:"logit_bias,omitempty"`
|
||||
User string `json:"user,omitempty"`
|
||||
|
||||
// 扩展字段 - 用于指定预设和提供商
|
||||
PresetName string `json:"preset_name,omitempty"` // 预设名称
|
||||
ProviderName string `json:"provider_name,omitempty"` // 提供商名称
|
||||
BindingName string `json:"binding_name,omitempty"` // 绑定名称(优先级最高)
|
||||
}
|
||||
|
||||
type ChatMessage struct {
|
||||
Role string `json:"role"` // system, user, assistant
|
||||
Content string `json:"content"`
|
||||
Name string `json:"name,omitempty"`
|
||||
}
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
package response
|
||||
|
||||
import "time"
|
||||
|
||||
// BindingInfo 绑定信息
|
||||
type BindingInfo struct {
|
||||
ID uint `json:"id"`
|
||||
PresetID uint `json:"presetId"`
|
||||
PresetName string `json:"presetName"`
|
||||
ProviderID uint `json:"providerId"`
|
||||
ProviderName string `json:"providerName"`
|
||||
Priority int `json:"priority"`
|
||||
IsActive bool `json:"isActive"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
UpdatedAt time.Time `json:"updatedAt"`
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
package response
|
||||
|
||||
// ModelInfo 模型信息
|
||||
type ModelInfo struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
OwnedBy string `json:"ownedBy"`
|
||||
}
|
||||
|
||||
// TestConnectionResponse 测试连接响应
|
||||
type TestConnectionResponse struct {
|
||||
Success bool `json:"success"`
|
||||
Message string `json:"message"`
|
||||
Latency int64 `json:"latency"` // 延迟(毫秒)
|
||||
}
|
||||
@@ -1,38 +1,48 @@
|
||||
package response
|
||||
|
||||
// ChatCompletionResponse OpenAI兼容的聊天补全响应
|
||||
// ChatCompletionResponse OpenAI兼容的聊天响应
|
||||
type ChatCompletionResponse struct {
|
||||
ID string `json:"id"`
|
||||
Object string `json:"object"`
|
||||
Created int64 `json:"created"`
|
||||
Model string `json:"model"`
|
||||
Choices []Choice `json:"choices"`
|
||||
Usage Usage `json:"usage"`
|
||||
ID string `json:"id"`
|
||||
Object string `json:"object"`
|
||||
Created int64 `json:"created"`
|
||||
Model string `json:"model"`
|
||||
Choices []ChatCompletionChoice `json:"choices"`
|
||||
Usage ChatCompletionUsage `json:"usage"`
|
||||
}
|
||||
|
||||
// Choice 选择项
|
||||
type Choice struct {
|
||||
Index int `json:"index"`
|
||||
Message Message `json:"message"`
|
||||
FinishReason string `json:"finish_reason"`
|
||||
type ChatCompletionChoice struct {
|
||||
Index int `json:"index"`
|
||||
Message ChatMessage `json:"message"`
|
||||
FinishReason string `json:"finish_reason"`
|
||||
}
|
||||
|
||||
// Message 消息
|
||||
type Message struct {
|
||||
type ChatMessage struct {
|
||||
Role string `json:"role"`
|
||||
Content string `json:"content"`
|
||||
}
|
||||
|
||||
// Usage Token使用情况
|
||||
type Usage struct {
|
||||
type ChatCompletionUsage struct {
|
||||
PromptTokens int `json:"prompt_tokens"`
|
||||
CompletionTokens int `json:"completion_tokens"`
|
||||
TotalTokens int `json:"total_tokens"`
|
||||
}
|
||||
|
||||
// StreamChunk 流式响应块
|
||||
type StreamChunk struct {
|
||||
Content string `json:"content"`
|
||||
Done bool `json:"done"`
|
||||
Error error `json:"error,omitempty"`
|
||||
// ChatCompletionStreamResponse 流式响应
|
||||
type ChatCompletionStreamResponse struct {
|
||||
ID string `json:"id"`
|
||||
Object string `json:"object"`
|
||||
Created int64 `json:"created"`
|
||||
Model string `json:"model"`
|
||||
Choices []ChatCompletionStreamChoice `json:"choices"`
|
||||
}
|
||||
|
||||
type ChatCompletionStreamChoice struct {
|
||||
Index int `json:"index"`
|
||||
Delta ChatMessageDelta `json:"delta"`
|
||||
FinishReason *string `json:"finish_reason"`
|
||||
}
|
||||
|
||||
type ChatMessageDelta struct {
|
||||
Role string `json:"role,omitempty"`
|
||||
Content string `json:"content,omitempty"`
|
||||
}
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// GetAppUserID 从上下文获取前台用户 ID
|
||||
func GetAppUserID(c *gin.Context) uint {
|
||||
if userID, exists := c.Get("appUserId"); exists {
|
||||
return userID.(uint)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// GetAppUsername 从上下文获取前台用户名
|
||||
func GetAppUsername(c *gin.Context) string {
|
||||
if username, exists := c.Get("appUsername"); exists {
|
||||
return username.(string)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
@@ -6,9 +6,9 @@ import (
|
||||
|
||||
// PageInfo Paging common input parameter structure
|
||||
type PageInfo struct {
|
||||
Page int `json:"page" form:"page,default=1"` // 页码
|
||||
PageSize int `json:"pageSize" form:"pageSize,default=20"` // 每页大小
|
||||
Keyword string `json:"keyword" form:"keyword"` // 关键字
|
||||
Page int `json:"page" form:"page"` // 页码
|
||||
PageSize int `json:"pageSize" form:"pageSize"` // 每页大小
|
||||
Keyword string `json:"keyword" form:"keyword"` // 关键字
|
||||
}
|
||||
|
||||
func (r *PageInfo) Paginate() func(db *gorm.DB) *gorm.DB {
|
||||
|
||||
16
server/model/example/exa_attachment_category.go
Normal file
16
server/model/example/exa_attachment_category.go
Normal file
@@ -0,0 +1,16 @@
|
||||
package example
|
||||
|
||||
import (
|
||||
"git.echol.cn/loser/ai_proxy/server/global"
|
||||
)
|
||||
|
||||
type ExaAttachmentCategory struct {
|
||||
global.GVA_MODEL
|
||||
Name string `json:"name" form:"name" gorm:"default:null;type:varchar(255);column:name;comment:分类名称;"`
|
||||
Pid uint `json:"pid" form:"pid" gorm:"default:0;type:int;column:pid;comment:父节点ID;"`
|
||||
Children []*ExaAttachmentCategory `json:"children" gorm:"-"`
|
||||
}
|
||||
|
||||
func (ExaAttachmentCategory) TableName() string {
|
||||
return "exa_attachment_category"
|
||||
}
|
||||
24
server/model/example/exa_breakpoint_continue.go
Normal file
24
server/model/example/exa_breakpoint_continue.go
Normal file
@@ -0,0 +1,24 @@
|
||||
package example
|
||||
|
||||
import (
|
||||
"git.echol.cn/loser/ai_proxy/server/global"
|
||||
)
|
||||
|
||||
// file struct, 文件结构体
|
||||
type ExaFile struct {
|
||||
global.GVA_MODEL
|
||||
FileName string
|
||||
FileMd5 string
|
||||
FilePath string
|
||||
ExaFileChunk []ExaFileChunk
|
||||
ChunkTotal int
|
||||
IsFinish bool
|
||||
}
|
||||
|
||||
// file chunk struct, 切片结构体
|
||||
type ExaFileChunk struct {
|
||||
global.GVA_MODEL
|
||||
ExaFileID uint
|
||||
FileChunkNumber int
|
||||
FileChunkPath string
|
||||
}
|
||||
15
server/model/example/exa_customer.go
Normal file
15
server/model/example/exa_customer.go
Normal file
@@ -0,0 +1,15 @@
|
||||
package example
|
||||
|
||||
import (
|
||||
"git.echol.cn/loser/ai_proxy/server/global"
|
||||
"git.echol.cn/loser/ai_proxy/server/model/system"
|
||||
)
|
||||
|
||||
type ExaCustomer struct {
|
||||
global.GVA_MODEL
|
||||
CustomerName string `json:"customerName" form:"customerName" gorm:"comment:客户名"` // 客户名
|
||||
CustomerPhoneData string `json:"customerPhoneData" form:"customerPhoneData" gorm:"comment:客户手机号"` // 客户手机号
|
||||
SysUserID uint `json:"sysUserId" form:"sysUserId" gorm:"comment:管理ID"` // 管理ID
|
||||
SysUserAuthorityID uint `json:"sysUserAuthorityID" form:"sysUserAuthorityID" gorm:"comment:管理角色ID"` // 管理角色ID
|
||||
SysUser system.SysUser `json:"sysUser" form:"sysUser" gorm:"comment:管理详情"` // 管理详情
|
||||
}
|
||||
18
server/model/example/exa_file_upload_download.go
Normal file
18
server/model/example/exa_file_upload_download.go
Normal file
@@ -0,0 +1,18 @@
|
||||
package example
|
||||
|
||||
import (
|
||||
"git.echol.cn/loser/ai_proxy/server/global"
|
||||
)
|
||||
|
||||
type ExaFileUploadAndDownload struct {
|
||||
global.GVA_MODEL
|
||||
Name string `json:"name" form:"name" gorm:"column:name;comment:文件名"` // 文件名
|
||||
ClassId int `json:"classId" form:"classId" gorm:"default:0;type:int;column:class_id;comment:分类id;"` // 分类id
|
||||
Url string `json:"url" form:"url" gorm:"column:url;comment:文件地址"` // 文件地址
|
||||
Tag string `json:"tag" form:"tag" gorm:"column:tag;comment:文件标签"` // 文件标签
|
||||
Key string `json:"key" form:"key" gorm:"column:key;comment:编号"` // 编号
|
||||
}
|
||||
|
||||
func (ExaFileUploadAndDownload) TableName() string {
|
||||
return "exa_file_upload_and_downloads"
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package request
|
||||
|
||||
import (
|
||||
"git.echol.cn/loser/ai_proxy/server/model/common/request"
|
||||
)
|
||||
|
||||
type ExaAttachmentCategorySearch struct {
|
||||
ClassId int `json:"classId" form:"classId"`
|
||||
request.PageInfo
|
||||
}
|
||||
11
server/model/example/response/exa_breakpoint_continue.go
Normal file
11
server/model/example/response/exa_breakpoint_continue.go
Normal file
@@ -0,0 +1,11 @@
|
||||
package response
|
||||
|
||||
import "git.echol.cn/loser/ai_proxy/server/model/example"
|
||||
|
||||
type FilePathResponse struct {
|
||||
FilePath string `json:"filePath"`
|
||||
}
|
||||
|
||||
type FileResponse struct {
|
||||
File example.ExaFile `json:"file"`
|
||||
}
|
||||
7
server/model/example/response/exa_customer.go
Normal file
7
server/model/example/response/exa_customer.go
Normal file
@@ -0,0 +1,7 @@
|
||||
package response
|
||||
|
||||
import "git.echol.cn/loser/ai_proxy/server/model/example"
|
||||
|
||||
type ExaCustomerResponse struct {
|
||||
Customer example.ExaCustomer `json:"customer"`
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package response
|
||||
|
||||
import "git.echol.cn/loser/ai_proxy/server/model/example"
|
||||
|
||||
type ExaFileResponse struct {
|
||||
File example.ExaFileUploadAndDownload `json:"file"`
|
||||
}
|
||||
@@ -1,11 +1,17 @@
|
||||
package request
|
||||
|
||||
import (
|
||||
"github.com/golang-jwt/jwt/v5"
|
||||
jwt "github.com/golang-jwt/jwt/v5"
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
// BaseClaims 基础 Claims
|
||||
// CustomClaims structure
|
||||
type CustomClaims struct {
|
||||
BaseClaims
|
||||
BufferTime int64
|
||||
jwt.RegisteredClaims
|
||||
}
|
||||
|
||||
type BaseClaims struct {
|
||||
UUID uuid.UUID
|
||||
ID uint
|
||||
@@ -13,10 +19,3 @@ type BaseClaims struct {
|
||||
NickName string
|
||||
AuthorityId uint
|
||||
}
|
||||
|
||||
// CustomClaims 自定义 Claims
|
||||
type CustomClaims struct {
|
||||
BaseClaims
|
||||
BufferTime int64
|
||||
jwt.RegisteredClaims
|
||||
}
|
||||
|
||||
@@ -1,27 +1,14 @@
|
||||
package request
|
||||
|
||||
// CreateApiRequest 创建API请求
|
||||
type CreateApiRequest struct {
|
||||
Path string `json:"path" binding:"required"`
|
||||
Description string `json:"description"`
|
||||
ApiGroup string `json:"apiGroup" binding:"required"`
|
||||
Method string `json:"method" binding:"required,oneof=GET POST PUT DELETE PATCH"`
|
||||
}
|
||||
import (
|
||||
"git.echol.cn/loser/ai_proxy/server/model/common/request"
|
||||
"git.echol.cn/loser/ai_proxy/server/model/system"
|
||||
)
|
||||
|
||||
// UpdateApiRequest 更新API请求
|
||||
type UpdateApiRequest struct {
|
||||
ID uint `json:"id" binding:"required"`
|
||||
Path string `json:"path" binding:"required"`
|
||||
Description string `json:"description"`
|
||||
ApiGroup string `json:"apiGroup" binding:"required"`
|
||||
Method string `json:"method" binding:"required,oneof=GET POST PUT DELETE PATCH"`
|
||||
}
|
||||
|
||||
// GetApiListRequest 获取API列表请求
|
||||
type GetApiListRequest struct {
|
||||
Page int `json:"page" form:"page"`
|
||||
PageSize int `json:"pageSize" form:"pageSize"`
|
||||
Path string `json:"path" form:"path"`
|
||||
ApiGroup string `json:"apiGroup" form:"apiGroup"`
|
||||
Method string `json:"method" form:"method"`
|
||||
// api分页条件查询及排序结构体
|
||||
type SearchApiParams struct {
|
||||
system.SysApi
|
||||
request.PageInfo
|
||||
OrderKey string `json:"orderKey"` // 排序
|
||||
Desc bool `json:"desc"` // 排序方式:升序false(默认)|降序true
|
||||
}
|
||||
|
||||
12
server/model/system/request/sys_api_token.go
Normal file
12
server/model/system/request/sys_api_token.go
Normal file
@@ -0,0 +1,12 @@
|
||||
package request
|
||||
|
||||
import (
|
||||
"git.echol.cn/loser/ai_proxy/server/model/common/request"
|
||||
"git.echol.cn/loser/ai_proxy/server/model/system"
|
||||
)
|
||||
|
||||
type SysApiTokenSearch struct {
|
||||
system.SysApiToken
|
||||
request.PageInfo
|
||||
Status *bool `json:"status" form:"status"`
|
||||
}
|
||||
7
server/model/system/request/sys_authority_btn.go
Normal file
7
server/model/system/request/sys_authority_btn.go
Normal file
@@ -0,0 +1,7 @@
|
||||
package request
|
||||
|
||||
type SysAuthorityBtnReq struct {
|
||||
MenuID uint `json:"menuID"`
|
||||
AuthorityId uint `json:"authorityId"`
|
||||
Selected []uint `json:"selected"`
|
||||
}
|
||||
291
server/model/system/request/sys_auto_code.go
Normal file
291
server/model/system/request/sys_auto_code.go
Normal file
@@ -0,0 +1,291 @@
|
||||
package request
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"git.echol.cn/loser/ai_proxy/server/global"
|
||||
model "git.echol.cn/loser/ai_proxy/server/model/system"
|
||||
"github.com/pkg/errors"
|
||||
"go/token"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type AutoCode struct {
|
||||
Package string `json:"package"`
|
||||
PackageT string `json:"-"`
|
||||
TableName string `json:"tableName" example:"表名"` // 表名
|
||||
BusinessDB string `json:"businessDB" example:"业务数据库"` // 业务数据库
|
||||
StructName string `json:"structName" example:"Struct名称"` // Struct名称
|
||||
PackageName string `json:"packageName" example:"文件名称"` // 文件名称
|
||||
Description string `json:"description" example:"Struct中文名称"` // Struct中文名称
|
||||
Abbreviation string `json:"abbreviation" example:"Struct简称"` // Struct简称
|
||||
HumpPackageName string `json:"humpPackageName" example:"go文件名称"` // go文件名称
|
||||
GvaModel bool `json:"gvaModel" example:"false"` // 是否使用gva默认Model
|
||||
AutoMigrate bool `json:"autoMigrate" example:"false"` // 是否自动迁移表结构
|
||||
AutoCreateResource bool `json:"autoCreateResource" example:"false"` // 是否自动创建资源标识
|
||||
AutoCreateApiToSql bool `json:"autoCreateApiToSql" example:"false"` // 是否自动创建api
|
||||
AutoCreateMenuToSql bool `json:"autoCreateMenuToSql" example:"false"` // 是否自动创建menu
|
||||
AutoCreateBtnAuth bool `json:"autoCreateBtnAuth" example:"false"` // 是否自动创建按钮权限
|
||||
OnlyTemplate bool `json:"onlyTemplate" example:"false"` // 是否只生成模板
|
||||
IsTree bool `json:"isTree" example:"false"` // 是否树形结构
|
||||
TreeJson string `json:"treeJson" example:"展示的树json字段"` // 展示的树json字段
|
||||
IsAdd bool `json:"isAdd" example:"false"` // 是否新增
|
||||
Fields []*AutoCodeField `json:"fields"`
|
||||
GenerateWeb bool `json:"generateWeb" example:"true"` // 是否生成web
|
||||
GenerateServer bool `json:"generateServer" example:"true"` // 是否生成server
|
||||
Module string `json:"-"`
|
||||
DictTypes []string `json:"-"`
|
||||
PrimaryField *AutoCodeField `json:"primaryField"`
|
||||
DataSourceMap map[string]*DataSource `json:"-"`
|
||||
HasPic bool `json:"-"`
|
||||
HasFile bool `json:"-"`
|
||||
HasTimer bool `json:"-"`
|
||||
NeedSort bool `json:"-"`
|
||||
NeedJSON bool `json:"-"`
|
||||
HasRichText bool `json:"-"`
|
||||
HasDataSource bool `json:"-"`
|
||||
HasSearchTimer bool `json:"-"`
|
||||
HasArray bool `json:"-"`
|
||||
HasExcel bool `json:"-"`
|
||||
}
|
||||
|
||||
type DataSource struct {
|
||||
DBName string `json:"dbName"`
|
||||
Table string `json:"table"`
|
||||
Label string `json:"label"`
|
||||
Value string `json:"value"`
|
||||
Association int `json:"association"` // 关联关系 1 一对一 2 一对多
|
||||
HasDeletedAt bool `json:"hasDeletedAt"`
|
||||
}
|
||||
|
||||
func (r *AutoCode) Apis() []model.SysApi {
|
||||
return []model.SysApi{
|
||||
{
|
||||
Path: "/" + r.Abbreviation + "/" + "create" + r.StructName,
|
||||
Description: "新增" + r.Description,
|
||||
ApiGroup: r.Description,
|
||||
Method: "POST",
|
||||
},
|
||||
{
|
||||
Path: "/" + r.Abbreviation + "/" + "delete" + r.StructName,
|
||||
Description: "删除" + r.Description,
|
||||
ApiGroup: r.Description,
|
||||
Method: "DELETE",
|
||||
},
|
||||
{
|
||||
Path: "/" + r.Abbreviation + "/" + "delete" + r.StructName + "ByIds",
|
||||
Description: "批量删除" + r.Description,
|
||||
ApiGroup: r.Description,
|
||||
Method: "DELETE",
|
||||
},
|
||||
{
|
||||
Path: "/" + r.Abbreviation + "/" + "update" + r.StructName,
|
||||
Description: "更新" + r.Description,
|
||||
ApiGroup: r.Description,
|
||||
Method: "PUT",
|
||||
},
|
||||
{
|
||||
Path: "/" + r.Abbreviation + "/" + "find" + r.StructName,
|
||||
Description: "根据ID获取" + r.Description,
|
||||
ApiGroup: r.Description,
|
||||
Method: "GET",
|
||||
},
|
||||
{
|
||||
Path: "/" + r.Abbreviation + "/" + "get" + r.StructName + "List",
|
||||
Description: "获取" + r.Description + "列表",
|
||||
ApiGroup: r.Description,
|
||||
Method: "GET",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (r *AutoCode) Menu(template string) model.SysBaseMenu {
|
||||
component := fmt.Sprintf("view/%s/%s/%s.vue", r.Package, r.PackageName, r.PackageName)
|
||||
if template != "package" {
|
||||
component = fmt.Sprintf("plugin/%s/view/%s.vue", r.Package, r.PackageName)
|
||||
}
|
||||
return model.SysBaseMenu{
|
||||
ParentId: 0,
|
||||
Path: r.Abbreviation,
|
||||
Name: r.Abbreviation,
|
||||
Component: component,
|
||||
Meta: model.Meta{
|
||||
Title: r.Description,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// Pretreatment 预处理
|
||||
// Author [SliverHorn](https://github.com/SliverHorn)
|
||||
func (r *AutoCode) Pretreatment() error {
|
||||
r.Module = global.GVA_CONFIG.AutoCode.Module
|
||||
if token.IsKeyword(r.Abbreviation) {
|
||||
r.Abbreviation = r.Abbreviation + "_"
|
||||
} // go 关键字处理
|
||||
if strings.HasSuffix(r.HumpPackageName, "test") {
|
||||
r.HumpPackageName = r.HumpPackageName + "_"
|
||||
} // test
|
||||
length := len(r.Fields)
|
||||
dict := make(map[string]string, length)
|
||||
r.DataSourceMap = make(map[string]*DataSource, length)
|
||||
for i := 0; i < length; i++ {
|
||||
if r.Fields[i].Excel {
|
||||
r.HasExcel = true
|
||||
}
|
||||
if r.Fields[i].DictType != "" {
|
||||
dict[r.Fields[i].DictType] = ""
|
||||
}
|
||||
if r.Fields[i].Sort {
|
||||
r.NeedSort = true
|
||||
}
|
||||
switch r.Fields[i].FieldType {
|
||||
case "file":
|
||||
r.HasFile = true
|
||||
r.NeedJSON = true
|
||||
case "json":
|
||||
r.NeedJSON = true
|
||||
case "array":
|
||||
r.NeedJSON = true
|
||||
r.HasArray = true
|
||||
case "video":
|
||||
r.HasPic = true
|
||||
case "richtext":
|
||||
r.HasRichText = true
|
||||
case "picture":
|
||||
r.HasPic = true
|
||||
case "pictures":
|
||||
r.HasPic = true
|
||||
r.NeedJSON = true
|
||||
case "time.Time":
|
||||
r.HasTimer = true
|
||||
if r.Fields[i].FieldSearchType != "" && r.Fields[i].FieldSearchType != "BETWEEN" && r.Fields[i].FieldSearchType != "NOT BETWEEN" {
|
||||
r.HasSearchTimer = true
|
||||
}
|
||||
}
|
||||
if r.Fields[i].DataSource != nil {
|
||||
if r.Fields[i].DataSource.Table != "" && r.Fields[i].DataSource.Label != "" && r.Fields[i].DataSource.Value != "" {
|
||||
r.HasDataSource = true
|
||||
r.Fields[i].CheckDataSource = true
|
||||
r.DataSourceMap[r.Fields[i].FieldJson] = r.Fields[i].DataSource
|
||||
}
|
||||
}
|
||||
if !r.GvaModel && r.PrimaryField == nil && r.Fields[i].PrimaryKey {
|
||||
r.PrimaryField = r.Fields[i]
|
||||
} // 自定义主键
|
||||
}
|
||||
{
|
||||
for key := range dict {
|
||||
r.DictTypes = append(r.DictTypes, key)
|
||||
}
|
||||
} // DictTypes => 字典
|
||||
{
|
||||
if r.GvaModel {
|
||||
r.PrimaryField = &AutoCodeField{
|
||||
FieldName: "ID",
|
||||
FieldType: "uint",
|
||||
FieldDesc: "ID",
|
||||
FieldJson: "ID",
|
||||
DataTypeLong: "20",
|
||||
Comment: "主键ID",
|
||||
ColumnName: "id",
|
||||
}
|
||||
}
|
||||
} // GvaModel
|
||||
{
|
||||
if r.IsAdd && r.PrimaryField == nil {
|
||||
r.PrimaryField = new(AutoCodeField)
|
||||
}
|
||||
} // 新增字段模式下不关注主键
|
||||
if r.Package == "" {
|
||||
return errors.New("Package为空!")
|
||||
} // 增加判断:Package不为空
|
||||
packages := []rune(r.Package)
|
||||
if len(packages) > 0 {
|
||||
if packages[0] >= 97 && packages[0] <= 122 {
|
||||
packages[0] = packages[0] - 32
|
||||
}
|
||||
r.PackageT = string(packages)
|
||||
} // PackageT 是 Package 的首字母大写
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *AutoCode) History() SysAutoHistoryCreate {
|
||||
bytes, _ := json.Marshal(r)
|
||||
return SysAutoHistoryCreate{
|
||||
Table: r.TableName,
|
||||
Package: r.Package,
|
||||
Request: string(bytes),
|
||||
StructName: r.StructName,
|
||||
BusinessDB: r.BusinessDB,
|
||||
Description: r.Description,
|
||||
}
|
||||
}
|
||||
|
||||
type AutoCodeField struct {
|
||||
FieldName string `json:"fieldName"` // Field名
|
||||
FieldDesc string `json:"fieldDesc"` // 中文名
|
||||
FieldType string `json:"fieldType"` // Field数据类型
|
||||
FieldJson string `json:"fieldJson"` // FieldJson
|
||||
DataTypeLong string `json:"dataTypeLong"` // 数据库字段长度
|
||||
Comment string `json:"comment"` // 数据库字段描述
|
||||
ColumnName string `json:"columnName"` // 数据库字段
|
||||
FieldSearchType string `json:"fieldSearchType"` // 搜索条件
|
||||
FieldSearchHide bool `json:"fieldSearchHide"` // 是否隐藏查询条件
|
||||
DictType string `json:"dictType"` // 字典
|
||||
//Front bool `json:"front"` // 是否前端可见
|
||||
Form bool `json:"form"` // 是否前端新建/编辑
|
||||
Table bool `json:"table"` // 是否前端表格列
|
||||
Desc bool `json:"desc"` // 是否前端详情
|
||||
Excel bool `json:"excel"` // 是否导入/导出
|
||||
Require bool `json:"require"` // 是否必填
|
||||
DefaultValue string `json:"defaultValue"` // 是否必填
|
||||
ErrorText string `json:"errorText"` // 校验失败文字
|
||||
Clearable bool `json:"clearable"` // 是否可清空
|
||||
Sort bool `json:"sort"` // 是否增加排序
|
||||
PrimaryKey bool `json:"primaryKey"` // 是否主键
|
||||
DataSource *DataSource `json:"dataSource"` // 数据源
|
||||
CheckDataSource bool `json:"checkDataSource"` // 是否检查数据源
|
||||
FieldIndexType string `json:"fieldIndexType"` // 索引类型
|
||||
}
|
||||
|
||||
type AutoFunc struct {
|
||||
Package string `json:"package"`
|
||||
FuncName string `json:"funcName"` // 方法名称
|
||||
Router string `json:"router"` // 路由名称
|
||||
FuncDesc string `json:"funcDesc"` // 方法介绍
|
||||
BusinessDB string `json:"businessDB"` // 业务库
|
||||
StructName string `json:"structName"` // Struct名称
|
||||
PackageName string `json:"packageName"` // 文件名称
|
||||
Description string `json:"description"` // Struct中文名称
|
||||
Abbreviation string `json:"abbreviation"` // Struct简称
|
||||
HumpPackageName string `json:"humpPackageName"` // go文件名称
|
||||
Method string `json:"method"` // 方法
|
||||
IsPlugin bool `json:"isPlugin"` // 是否插件
|
||||
IsAuth bool `json:"isAuth"` // 是否鉴权
|
||||
IsPreview bool `json:"isPreview"` // 是否预览
|
||||
IsAi bool `json:"isAi"` // 是否AI
|
||||
ApiFunc string `json:"apiFunc"` // API方法
|
||||
ServerFunc string `json:"serverFunc"` // 服务方法
|
||||
JsFunc string `json:"jsFunc"` // JS方法
|
||||
}
|
||||
|
||||
type InitMenu struct {
|
||||
PlugName string `json:"plugName"`
|
||||
ParentMenu string `json:"parentMenu"`
|
||||
Menus []uint `json:"menus"`
|
||||
}
|
||||
|
||||
type InitApi struct {
|
||||
PlugName string `json:"plugName"`
|
||||
APIs []uint `json:"apis"`
|
||||
}
|
||||
|
||||
type InitDictionary struct {
|
||||
PlugName string `json:"plugName"`
|
||||
Dictionaries []uint `json:"dictionaries"`
|
||||
}
|
||||
|
||||
type LLMAutoCode struct {
|
||||
Prompt string `json:"prompt" form:"prompt" gorm:"column:prompt;comment:提示语;type:text;"` //提示语
|
||||
Mode string `json:"mode" form:"mode" gorm:"column:mode;comment:模式;type:text;"` //模式
|
||||
}
|
||||
16
server/model/system/request/sys_auto_code_mcp.go
Normal file
16
server/model/system/request/sys_auto_code_mcp.go
Normal file
@@ -0,0 +1,16 @@
|
||||
package request
|
||||
|
||||
type AutoMcpTool struct {
|
||||
Name string `json:"name" form:"name" binding:"required"`
|
||||
Description string `json:"description" form:"description" binding:"required"`
|
||||
Params []struct {
|
||||
Name string `json:"name" form:"name" binding:"required"`
|
||||
Description string `json:"description" form:"description" binding:"required"`
|
||||
Type string `json:"type" form:"type" binding:"required"` // string, number, boolean, object, array
|
||||
Required bool `json:"required" form:"required"`
|
||||
Default string `json:"default" form:"default"`
|
||||
} `json:"params" form:"params"`
|
||||
Response []struct {
|
||||
Type string `json:"type" form:"type" binding:"required"` // text, image
|
||||
} `json:"response" form:"response"`
|
||||
}
|
||||
31
server/model/system/request/sys_auto_code_package.go
Normal file
31
server/model/system/request/sys_auto_code_package.go
Normal file
@@ -0,0 +1,31 @@
|
||||
package request
|
||||
|
||||
import (
|
||||
"git.echol.cn/loser/ai_proxy/server/global"
|
||||
model "git.echol.cn/loser/ai_proxy/server/model/system"
|
||||
)
|
||||
|
||||
type SysAutoCodePackageCreate struct {
|
||||
Desc string `json:"desc" example:"描述"`
|
||||
Label string `json:"label" example:"展示名"`
|
||||
Template string `json:"template" example:"模版"`
|
||||
PackageName string `json:"packageName" example:"包名"`
|
||||
Module string `json:"-" example:"模块"`
|
||||
}
|
||||
|
||||
func (r *SysAutoCodePackageCreate) AutoCode() AutoCode {
|
||||
return AutoCode{
|
||||
Package: r.PackageName,
|
||||
Module: global.GVA_CONFIG.AutoCode.Module,
|
||||
}
|
||||
}
|
||||
|
||||
func (r *SysAutoCodePackageCreate) Create() model.SysAutoCodePackage {
|
||||
return model.SysAutoCodePackage{
|
||||
Desc: r.Desc,
|
||||
Label: r.Label,
|
||||
Template: r.Template,
|
||||
PackageName: r.PackageName,
|
||||
Module: global.GVA_CONFIG.AutoCode.Module,
|
||||
}
|
||||
}
|
||||
57
server/model/system/request/sys_auto_history.go
Normal file
57
server/model/system/request/sys_auto_history.go
Normal file
@@ -0,0 +1,57 @@
|
||||
package request
|
||||
|
||||
import (
|
||||
common "git.echol.cn/loser/ai_proxy/server/model/common/request"
|
||||
model "git.echol.cn/loser/ai_proxy/server/model/system"
|
||||
)
|
||||
|
||||
type SysAutoHistoryCreate struct {
|
||||
Table string // 表名
|
||||
Package string // 模块名/插件名
|
||||
Request string // 前端传入的结构化信息
|
||||
StructName string // 结构体名称
|
||||
BusinessDB string // 业务库
|
||||
Description string // Struct中文名称
|
||||
Injections map[string]string // 注入路径
|
||||
Templates map[string]string // 模板信息
|
||||
ApiIDs []uint // api表注册内容
|
||||
MenuID uint // 菜单ID
|
||||
ExportTemplateID uint // 导出模板ID
|
||||
}
|
||||
|
||||
func (r *SysAutoHistoryCreate) Create() model.SysAutoCodeHistory {
|
||||
entity := model.SysAutoCodeHistory{
|
||||
Package: r.Package,
|
||||
Request: r.Request,
|
||||
Table: r.Table,
|
||||
StructName: r.StructName,
|
||||
Abbreviation: r.StructName,
|
||||
BusinessDB: r.BusinessDB,
|
||||
Description: r.Description,
|
||||
Injections: r.Injections,
|
||||
Templates: r.Templates,
|
||||
ApiIDs: r.ApiIDs,
|
||||
MenuID: r.MenuID,
|
||||
ExportTemplateID: r.ExportTemplateID,
|
||||
}
|
||||
if entity.Table == "" {
|
||||
entity.Table = r.StructName
|
||||
}
|
||||
return entity
|
||||
}
|
||||
|
||||
type SysAutoHistoryRollBack struct {
|
||||
common.GetById
|
||||
DeleteApi bool `json:"deleteApi" form:"deleteApi"` // 是否删除接口
|
||||
DeleteMenu bool `json:"deleteMenu" form:"deleteMenu"` // 是否删除菜单
|
||||
DeleteTable bool `json:"deleteTable" form:"deleteTable"` // 是否删除表
|
||||
}
|
||||
|
||||
func (r *SysAutoHistoryRollBack) ApiIds(entity model.SysAutoCodeHistory) common.IdsReq {
|
||||
length := len(entity.ApiIDs)
|
||||
ids := make([]int, 0)
|
||||
for i := 0; i < length; i++ {
|
||||
ids = append(ids, int(entity.ApiIDs[i]))
|
||||
}
|
||||
return common.IdsReq{Ids: ids}
|
||||
}
|
||||
27
server/model/system/request/sys_casbin.go
Normal file
27
server/model/system/request/sys_casbin.go
Normal file
@@ -0,0 +1,27 @@
|
||||
package request
|
||||
|
||||
// CasbinInfo Casbin info structure
|
||||
type CasbinInfo struct {
|
||||
Path string `json:"path"` // 路径
|
||||
Method string `json:"method"` // 方法
|
||||
}
|
||||
|
||||
// CasbinInReceive Casbin structure for input parameters
|
||||
type CasbinInReceive struct {
|
||||
AuthorityId uint `json:"authorityId"` // 权限id
|
||||
CasbinInfos []CasbinInfo `json:"casbinInfos"`
|
||||
}
|
||||
|
||||
func DefaultCasbin() []CasbinInfo {
|
||||
return []CasbinInfo{
|
||||
{Path: "/menu/getMenu", Method: "POST"},
|
||||
{Path: "/jwt/jsonInBlacklist", Method: "POST"},
|
||||
{Path: "/base/login", Method: "POST"},
|
||||
{Path: "/user/changePassword", Method: "POST"},
|
||||
{Path: "/user/setUserAuthority", Method: "POST"},
|
||||
{Path: "/user/getUserInfo", Method: "GET"},
|
||||
{Path: "/user/setSelfInfo", Method: "PUT"},
|
||||
{Path: "/fileUploadAndDownload/upload", Method: "POST"},
|
||||
{Path: "/sysDictionary/findSysDictionary", Method: "GET"},
|
||||
}
|
||||
}
|
||||
9
server/model/system/request/sys_dictionary.go
Normal file
9
server/model/system/request/sys_dictionary.go
Normal file
@@ -0,0 +1,9 @@
|
||||
package request
|
||||
|
||||
type SysDictionarySearch struct {
|
||||
Name string `json:"name" form:"name" gorm:"column:name;comment:字典名(中)"` // 字典名(中)
|
||||
}
|
||||
|
||||
type ImportSysDictionaryRequest struct {
|
||||
Json string `json:"json" binding:"required"` // JSON字符串
|
||||
}
|
||||
43
server/model/system/request/sys_dictionary_detail.go
Normal file
43
server/model/system/request/sys_dictionary_detail.go
Normal file
@@ -0,0 +1,43 @@
|
||||
package request
|
||||
|
||||
import (
|
||||
"git.echol.cn/loser/ai_proxy/server/model/common/request"
|
||||
"git.echol.cn/loser/ai_proxy/server/model/system"
|
||||
)
|
||||
|
||||
type SysDictionaryDetailSearch struct {
|
||||
system.SysDictionaryDetail
|
||||
request.PageInfo
|
||||
ParentID *uint `json:"parentID" form:"parentID"` // 父级字典详情ID,用于查询指定父级下的子项
|
||||
Level *int `json:"level" form:"level"` // 层级深度,用于查询指定层级的数据
|
||||
}
|
||||
|
||||
// CreateSysDictionaryDetailRequest 创建字典详情请求
|
||||
type CreateSysDictionaryDetailRequest struct {
|
||||
Label string `json:"label" form:"label" binding:"required"` // 展示值
|
||||
Value string `json:"value" form:"value" binding:"required"` // 字典值
|
||||
Extend string `json:"extend" form:"extend"` // 扩展值
|
||||
Status *bool `json:"status" form:"status"` // 启用状态
|
||||
Sort int `json:"sort" form:"sort"` // 排序标记
|
||||
SysDictionaryID int `json:"sysDictionaryID" form:"sysDictionaryID" binding:"required"` // 关联标记
|
||||
ParentID *uint `json:"parentID" form:"parentID"` // 父级字典详情ID
|
||||
}
|
||||
|
||||
// UpdateSysDictionaryDetailRequest 更新字典详情请求
|
||||
type UpdateSysDictionaryDetailRequest struct {
|
||||
ID uint `json:"ID" form:"ID" binding:"required"` // 主键ID
|
||||
Label string `json:"label" form:"label" binding:"required"` // 展示值
|
||||
Value string `json:"value" form:"value" binding:"required"` // 字典值
|
||||
Extend string `json:"extend" form:"extend"` // 扩展值
|
||||
Status *bool `json:"status" form:"status"` // 启用状态
|
||||
Sort int `json:"sort" form:"sort"` // 排序标记
|
||||
SysDictionaryID int `json:"sysDictionaryID" form:"sysDictionaryID" binding:"required"` // 关联标记
|
||||
ParentID *uint `json:"parentID" form:"parentID"` // 父级字典详情ID
|
||||
}
|
||||
|
||||
// GetDictionaryDetailsByParentRequest 根据父级ID获取字典详情请求
|
||||
type GetDictionaryDetailsByParentRequest struct {
|
||||
SysDictionaryID int `json:"sysDictionaryID" form:"sysDictionaryID" binding:"required"` // 字典ID
|
||||
ParentID *uint `json:"parentID" form:"parentID"` // 父级字典详情ID,为空时获取顶级
|
||||
IncludeChildren bool `json:"includeChildren" form:"includeChildren"` // 是否包含子级数据
|
||||
}
|
||||
13
server/model/system/request/sys_error.go
Normal file
13
server/model/system/request/sys_error.go
Normal file
@@ -0,0 +1,13 @@
|
||||
package request
|
||||
|
||||
import (
|
||||
"git.echol.cn/loser/ai_proxy/server/model/common/request"
|
||||
"time"
|
||||
)
|
||||
|
||||
type SysErrorSearch struct {
|
||||
CreatedAtRange []time.Time `json:"createdAtRange" form:"createdAtRange[]"`
|
||||
Form *string `json:"form" form:"form"`
|
||||
Info *string `json:"info" form:"info"`
|
||||
request.PageInfo
|
||||
}
|
||||
14
server/model/system/request/sys_export_template.go
Normal file
14
server/model/system/request/sys_export_template.go
Normal file
@@ -0,0 +1,14 @@
|
||||
package request
|
||||
|
||||
import (
|
||||
"git.echol.cn/loser/ai_proxy/server/model/common/request"
|
||||
"git.echol.cn/loser/ai_proxy/server/model/system"
|
||||
"time"
|
||||
)
|
||||
|
||||
type SysExportTemplateSearch struct {
|
||||
system.SysExportTemplate
|
||||
StartCreatedAt *time.Time `json:"startCreatedAt" form:"startCreatedAt"`
|
||||
EndCreatedAt *time.Time `json:"endCreatedAt" form:"endCreatedAt"`
|
||||
request.PageInfo
|
||||
}
|
||||
124
server/model/system/request/sys_init.go
Normal file
124
server/model/system/request/sys_init.go
Normal file
@@ -0,0 +1,124 @@
|
||||
package request
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"git.echol.cn/loser/ai_proxy/server/config"
|
||||
"os"
|
||||
)
|
||||
|
||||
type InitDB struct {
|
||||
AdminPassword string `json:"adminPassword" binding:"required"`
|
||||
DBType string `json:"dbType"` // 数据库类型
|
||||
Host string `json:"host"` // 服务器地址
|
||||
Port string `json:"port"` // 数据库连接端口
|
||||
UserName string `json:"userName"` // 数据库用户名
|
||||
Password string `json:"password"` // 数据库密码
|
||||
DBName string `json:"dbName" binding:"required"` // 数据库名
|
||||
DBPath string `json:"dbPath"` // sqlite数据库文件路径
|
||||
Template string `json:"template"` // postgresql指定template
|
||||
}
|
||||
|
||||
// MysqlEmptyDsn msyql 空数据库 建库链接
|
||||
// Author SliverHorn
|
||||
func (i *InitDB) MysqlEmptyDsn() string {
|
||||
if i.Host == "" {
|
||||
i.Host = "127.0.0.1"
|
||||
}
|
||||
if i.Port == "" {
|
||||
i.Port = "3306"
|
||||
}
|
||||
return fmt.Sprintf("%s:%s@tcp(%s:%s)/", i.UserName, i.Password, i.Host, i.Port)
|
||||
}
|
||||
|
||||
// PgsqlEmptyDsn pgsql 空数据库 建库链接
|
||||
// Author SliverHorn
|
||||
func (i *InitDB) PgsqlEmptyDsn() string {
|
||||
if i.Host == "" {
|
||||
i.Host = "127.0.0.1"
|
||||
}
|
||||
if i.Port == "" {
|
||||
i.Port = "5432"
|
||||
}
|
||||
return "host=" + i.Host + " user=" + i.UserName + " password=" + i.Password + " port=" + i.Port + " dbname=" + "postgres" + " " + "sslmode=disable TimeZone=Asia/Shanghai"
|
||||
}
|
||||
|
||||
// SqliteEmptyDsn sqlite 空数据库 建库链接
|
||||
// Author Kafumio
|
||||
func (i *InitDB) SqliteEmptyDsn() string {
|
||||
separator := string(os.PathSeparator)
|
||||
return i.DBPath + separator + i.DBName + ".db"
|
||||
}
|
||||
|
||||
func (i *InitDB) MssqlEmptyDsn() string {
|
||||
return "sqlserver://" + i.UserName + ":" + i.Password + "@" + i.Host + ":" + i.Port + "?database=" + i.DBName + "&encrypt=disable"
|
||||
}
|
||||
|
||||
// ToMysqlConfig 转换 config.Mysql
|
||||
// Author [SliverHorn](https://github.com/SliverHorn)
|
||||
func (i *InitDB) ToMysqlConfig() config.Mysql {
|
||||
return config.Mysql{
|
||||
GeneralDB: config.GeneralDB{
|
||||
Path: i.Host,
|
||||
Port: i.Port,
|
||||
Dbname: i.DBName,
|
||||
Username: i.UserName,
|
||||
Password: i.Password,
|
||||
MaxIdleConns: 10,
|
||||
MaxOpenConns: 100,
|
||||
LogMode: "error",
|
||||
Config: "charset=utf8mb4&parseTime=True&loc=Local",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// ToPgsqlConfig 转换 config.Pgsql
|
||||
// Author [SliverHorn](https://github.com/SliverHorn)
|
||||
func (i *InitDB) ToPgsqlConfig() config.Pgsql {
|
||||
return config.Pgsql{
|
||||
GeneralDB: config.GeneralDB{
|
||||
Path: i.Host,
|
||||
Port: i.Port,
|
||||
Dbname: i.DBName,
|
||||
Username: i.UserName,
|
||||
Password: i.Password,
|
||||
MaxIdleConns: 10,
|
||||
MaxOpenConns: 100,
|
||||
LogMode: "error",
|
||||
Config: "sslmode=disable TimeZone=Asia/Shanghai",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// ToSqliteConfig 转换 config.Sqlite
|
||||
// Author [Kafumio](https://github.com/Kafumio)
|
||||
func (i *InitDB) ToSqliteConfig() config.Sqlite {
|
||||
return config.Sqlite{
|
||||
GeneralDB: config.GeneralDB{
|
||||
Path: i.DBPath,
|
||||
Port: i.Port,
|
||||
Dbname: i.DBName,
|
||||
Username: i.UserName,
|
||||
Password: i.Password,
|
||||
MaxIdleConns: 10,
|
||||
MaxOpenConns: 100,
|
||||
LogMode: "error",
|
||||
Config: "",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (i *InitDB) ToMssqlConfig() config.Mssql {
|
||||
return config.Mssql{
|
||||
GeneralDB: config.GeneralDB{
|
||||
Path: i.DBPath,
|
||||
Port: i.Port,
|
||||
Dbname: i.DBName,
|
||||
Username: i.UserName,
|
||||
Password: i.Password,
|
||||
MaxIdleConns: 10,
|
||||
MaxOpenConns: 100,
|
||||
LogMode: "error",
|
||||
Config: "",
|
||||
},
|
||||
}
|
||||
}
|
||||
11
server/model/system/request/sys_login_log.go
Normal file
11
server/model/system/request/sys_login_log.go
Normal file
@@ -0,0 +1,11 @@
|
||||
package request
|
||||
|
||||
import (
|
||||
"git.echol.cn/loser/ai_proxy/server/model/common/request"
|
||||
"git.echol.cn/loser/ai_proxy/server/model/system"
|
||||
)
|
||||
|
||||
type SysLoginLogSearch struct {
|
||||
system.SysLoginLog
|
||||
request.PageInfo
|
||||
}
|
||||
27
server/model/system/request/sys_menu.go
Normal file
27
server/model/system/request/sys_menu.go
Normal file
@@ -0,0 +1,27 @@
|
||||
package request
|
||||
|
||||
import (
|
||||
"git.echol.cn/loser/ai_proxy/server/global"
|
||||
"git.echol.cn/loser/ai_proxy/server/model/system"
|
||||
)
|
||||
|
||||
// AddMenuAuthorityInfo Add menu authority info structure
|
||||
type AddMenuAuthorityInfo struct {
|
||||
Menus []system.SysBaseMenu `json:"menus"`
|
||||
AuthorityId uint `json:"authorityId"` // 角色ID
|
||||
}
|
||||
|
||||
func DefaultMenu() []system.SysBaseMenu {
|
||||
return []system.SysBaseMenu{{
|
||||
GVA_MODEL: global.GVA_MODEL{ID: 1},
|
||||
ParentId: 0,
|
||||
Path: "dashboard",
|
||||
Name: "dashboard",
|
||||
Component: "view/dashboard/index.vue",
|
||||
Sort: 1,
|
||||
Meta: system.Meta{
|
||||
Title: "仪表盘",
|
||||
Icon: "setting",
|
||||
},
|
||||
}}
|
||||
}
|
||||
11
server/model/system/request/sys_operation_record.go
Normal file
11
server/model/system/request/sys_operation_record.go
Normal file
@@ -0,0 +1,11 @@
|
||||
package request
|
||||
|
||||
import (
|
||||
"git.echol.cn/loser/ai_proxy/server/model/common/request"
|
||||
"git.echol.cn/loser/ai_proxy/server/model/system"
|
||||
)
|
||||
|
||||
type SysOperationRecordSearch struct {
|
||||
system.SysOperationRecord
|
||||
request.PageInfo
|
||||
}
|
||||
14
server/model/system/request/sys_params.go
Normal file
14
server/model/system/request/sys_params.go
Normal file
@@ -0,0 +1,14 @@
|
||||
package request
|
||||
|
||||
import (
|
||||
"git.echol.cn/loser/ai_proxy/server/model/common/request"
|
||||
"time"
|
||||
)
|
||||
|
||||
type SysParamsSearch struct {
|
||||
StartCreatedAt *time.Time `json:"startCreatedAt" form:"startCreatedAt"`
|
||||
EndCreatedAt *time.Time `json:"endCreatedAt" form:"endCreatedAt"`
|
||||
Name string `json:"name" form:"name" `
|
||||
Key string `json:"key" form:"key" `
|
||||
request.PageInfo
|
||||
}
|
||||
64
server/model/system/request/sys_skills.go
Normal file
64
server/model/system/request/sys_skills.go
Normal file
@@ -0,0 +1,64 @@
|
||||
package request
|
||||
|
||||
import "git.echol.cn/loser/ai_proxy/server/model/system"
|
||||
|
||||
type SkillToolRequest struct {
|
||||
Tool string `json:"tool"`
|
||||
}
|
||||
|
||||
type SkillDetailRequest struct {
|
||||
Tool string `json:"tool"`
|
||||
Skill string `json:"skill"`
|
||||
}
|
||||
|
||||
type SkillSaveRequest struct {
|
||||
Tool string `json:"tool"`
|
||||
Skill string `json:"skill"`
|
||||
Meta system.SkillMeta `json:"meta"`
|
||||
Markdown string `json:"markdown"`
|
||||
SyncTools []string `json:"syncTools"`
|
||||
}
|
||||
|
||||
type SkillScriptCreateRequest struct {
|
||||
Tool string `json:"tool"`
|
||||
Skill string `json:"skill"`
|
||||
FileName string `json:"fileName"`
|
||||
ScriptType string `json:"scriptType"`
|
||||
}
|
||||
|
||||
type SkillResourceCreateRequest struct {
|
||||
Tool string `json:"tool"`
|
||||
Skill string `json:"skill"`
|
||||
FileName string `json:"fileName"`
|
||||
}
|
||||
|
||||
type SkillReferenceCreateRequest struct {
|
||||
Tool string `json:"tool"`
|
||||
Skill string `json:"skill"`
|
||||
FileName string `json:"fileName"`
|
||||
}
|
||||
|
||||
type SkillTemplateCreateRequest struct {
|
||||
Tool string `json:"tool"`
|
||||
Skill string `json:"skill"`
|
||||
FileName string `json:"fileName"`
|
||||
}
|
||||
|
||||
type SkillFileRequest struct {
|
||||
Tool string `json:"tool"`
|
||||
Skill string `json:"skill"`
|
||||
FileName string `json:"fileName"`
|
||||
}
|
||||
|
||||
type SkillFileSaveRequest struct {
|
||||
Tool string `json:"tool"`
|
||||
Skill string `json:"skill"`
|
||||
FileName string `json:"fileName"`
|
||||
Content string `json:"content"`
|
||||
}
|
||||
|
||||
type SkillGlobalConstraintSaveRequest struct {
|
||||
Tool string `json:"tool"`
|
||||
Content string `json:"content"`
|
||||
SyncTools []string `json:"syncTools"`
|
||||
}
|
||||
@@ -1,22 +1,69 @@
|
||||
package request
|
||||
|
||||
type LoginRequest struct {
|
||||
Username string `json:"username" binding:"required"`
|
||||
Password string `json:"password" binding:"required"`
|
||||
import (
|
||||
common "git.echol.cn/loser/ai_proxy/server/model/common/request"
|
||||
"git.echol.cn/loser/ai_proxy/server/model/system"
|
||||
)
|
||||
|
||||
// Register User register structure
|
||||
type Register struct {
|
||||
Username string `json:"userName" example:"用户名"`
|
||||
Password string `json:"passWord" example:"密码"`
|
||||
NickName string `json:"nickName" example:"昵称"`
|
||||
HeaderImg string `json:"headerImg" example:"头像链接"`
|
||||
AuthorityId uint `json:"authorityId" swaggertype:"string" example:"int 角色id"`
|
||||
Enable int `json:"enable" swaggertype:"string" example:"int 是否启用"`
|
||||
AuthorityIds []uint `json:"authorityIds" swaggertype:"string" example:"[]uint 角色id"`
|
||||
Phone string `json:"phone" example:"电话号码"`
|
||||
Email string `json:"email" example:"电子邮箱"`
|
||||
}
|
||||
|
||||
type RegisterRequest struct {
|
||||
Username string `json:"username" binding:"required,min=3,max=50"`
|
||||
Password string `json:"password" binding:"required,min=6"`
|
||||
Email string `json:"email" binding:"email"`
|
||||
// Login User login structure
|
||||
type Login struct {
|
||||
Username string `json:"username"` // 用户名
|
||||
Password string `json:"password"` // 密码
|
||||
Captcha string `json:"captcha"` // 验证码
|
||||
CaptchaId string `json:"captchaId"` // 验证码ID
|
||||
}
|
||||
|
||||
type UpdateUserRequest struct {
|
||||
ID uint `json:"id"`
|
||||
Nickname string `json:"nickname"`
|
||||
Email string `json:"email"`
|
||||
Phone string `json:"phone"`
|
||||
Avatar string `json:"avatar"`
|
||||
Role string `json:"role"`
|
||||
Status string `json:"status"`
|
||||
// ChangePasswordReq Modify password structure
|
||||
type ChangePasswordReq struct {
|
||||
ID uint `json:"-"` // 从 JWT 中提取 user id,避免越权
|
||||
Password string `json:"password"` // 密码
|
||||
NewPassword string `json:"newPassword"` // 新密码
|
||||
}
|
||||
|
||||
type ResetPassword struct {
|
||||
ID uint `json:"ID" form:"ID"`
|
||||
Password string `json:"password" form:"password" gorm:"comment:用户登录密码"` // 用户登录密码
|
||||
}
|
||||
|
||||
// SetUserAuth Modify user's auth structure
|
||||
type SetUserAuth struct {
|
||||
AuthorityId uint `json:"authorityId"` // 角色ID
|
||||
}
|
||||
|
||||
// SetUserAuthorities Modify user's auth structure
|
||||
type SetUserAuthorities struct {
|
||||
ID uint
|
||||
AuthorityIds []uint `json:"authorityIds"` // 角色ID
|
||||
}
|
||||
|
||||
type ChangeUserInfo struct {
|
||||
ID uint `gorm:"primarykey"` // 主键ID
|
||||
NickName string `json:"nickName" gorm:"default:系统用户;comment:用户昵称"` // 用户昵称
|
||||
Phone string `json:"phone" gorm:"comment:用户手机号"` // 用户手机号
|
||||
AuthorityIds []uint `json:"authorityIds" gorm:"-"` // 角色ID
|
||||
Email string `json:"email" gorm:"comment:用户邮箱"` // 用户邮箱
|
||||
HeaderImg string `json:"headerImg" gorm:"default:https://qmplusimg.henrongyi.top/gva_header.jpg;comment:用户头像"` // 用户头像
|
||||
Enable int `json:"enable" gorm:"comment:冻结用户"` //冻结用户
|
||||
Authorities []system.SysAuthority `json:"-" gorm:"many2many:sys_user_authority;"`
|
||||
}
|
||||
|
||||
type GetUserList struct {
|
||||
common.PageInfo
|
||||
Username string `json:"username" form:"username"`
|
||||
NickName string `json:"nickName" form:"nickName"`
|
||||
Phone string `json:"phone" form:"phone"`
|
||||
Email string `json:"email" form:"email"`
|
||||
}
|
||||
|
||||
40
server/model/system/request/sys_version.go
Normal file
40
server/model/system/request/sys_version.go
Normal file
@@ -0,0 +1,40 @@
|
||||
package request
|
||||
|
||||
import (
|
||||
"git.echol.cn/loser/ai_proxy/server/model/common/request"
|
||||
"git.echol.cn/loser/ai_proxy/server/model/system"
|
||||
"time"
|
||||
)
|
||||
|
||||
type SysVersionSearch struct {
|
||||
CreatedAtRange []time.Time `json:"createdAtRange" form:"createdAtRange[]"`
|
||||
VersionName *string `json:"versionName" form:"versionName"`
|
||||
VersionCode *string `json:"versionCode" form:"versionCode"`
|
||||
request.PageInfo
|
||||
}
|
||||
|
||||
// ExportVersionRequest 导出版本请求结构体
|
||||
type ExportVersionRequest struct {
|
||||
VersionName string `json:"versionName" binding:"required"` // 版本名称
|
||||
VersionCode string `json:"versionCode" binding:"required"` // 版本号
|
||||
Description string `json:"description"` // 版本描述
|
||||
MenuIds []uint `json:"menuIds"` // 选中的菜单ID列表
|
||||
ApiIds []uint `json:"apiIds"` // 选中的API ID列表
|
||||
DictIds []uint `json:"dictIds"` // 选中的字典ID列表
|
||||
}
|
||||
|
||||
// ImportVersionRequest 导入版本请求结构体
|
||||
type ImportVersionRequest struct {
|
||||
VersionInfo VersionInfo `json:"version" binding:"required"` // 版本信息
|
||||
ExportMenu []system.SysBaseMenu `json:"menus"` // 菜单数据,直接复用SysBaseMenu
|
||||
ExportApi []system.SysApi `json:"apis"` // API数据,直接复用SysApi
|
||||
ExportDictionary []system.SysDictionary `json:"dictionaries"` // 字典数据,直接复用SysDictionary
|
||||
}
|
||||
|
||||
// VersionInfo 版本信息结构体
|
||||
type VersionInfo struct {
|
||||
Name string `json:"name" binding:"required"` // 版本名称
|
||||
Code string `json:"code" binding:"required"` // 版本号
|
||||
Description string `json:"description"` // 版本描述
|
||||
ExportTime string `json:"exportTime"` // 导出时间
|
||||
}
|
||||
@@ -1,14 +1,18 @@
|
||||
package response
|
||||
|
||||
import "time"
|
||||
import (
|
||||
"git.echol.cn/loser/ai_proxy/server/model/system"
|
||||
)
|
||||
|
||||
// ApiInfo API信息
|
||||
type ApiInfo struct {
|
||||
ID uint `json:"id"`
|
||||
Path string `json:"path"`
|
||||
Description string `json:"description"`
|
||||
ApiGroup string `json:"apiGroup"`
|
||||
Method string `json:"method"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
UpdatedAt time.Time `json:"updatedAt"`
|
||||
type SysAPIResponse struct {
|
||||
Api system.SysApi `json:"api"`
|
||||
}
|
||||
|
||||
type SysAPIListResponse struct {
|
||||
Apis []system.SysApi `json:"apis"`
|
||||
}
|
||||
|
||||
type SysSyncApis struct {
|
||||
NewApis []system.SysApi `json:"newApis"`
|
||||
DeleteApis []system.SysApi `json:"deleteApis"`
|
||||
}
|
||||
|
||||
12
server/model/system/response/sys_authority.go
Normal file
12
server/model/system/response/sys_authority.go
Normal file
@@ -0,0 +1,12 @@
|
||||
package response
|
||||
|
||||
import "git.echol.cn/loser/ai_proxy/server/model/system"
|
||||
|
||||
type SysAuthorityResponse struct {
|
||||
Authority system.SysAuthority `json:"authority"`
|
||||
}
|
||||
|
||||
type SysAuthorityCopyResponse struct {
|
||||
Authority system.SysAuthority `json:"authority"`
|
||||
OldAuthorityId uint `json:"oldAuthorityId"` // 旧角色ID
|
||||
}
|
||||
5
server/model/system/response/sys_authority_btn.go
Normal file
5
server/model/system/response/sys_authority_btn.go
Normal file
@@ -0,0 +1,5 @@
|
||||
package response
|
||||
|
||||
type SysAuthorityBtnRes struct {
|
||||
Selected []uint `json:"selected"`
|
||||
}
|
||||
27
server/model/system/response/sys_auto_code.go
Normal file
27
server/model/system/response/sys_auto_code.go
Normal file
@@ -0,0 +1,27 @@
|
||||
package response
|
||||
|
||||
import "git.echol.cn/loser/ai_proxy/server/model/system"
|
||||
|
||||
type Db struct {
|
||||
Database string `json:"database" gorm:"column:database"`
|
||||
}
|
||||
|
||||
type Table struct {
|
||||
TableName string `json:"tableName" gorm:"column:table_name"`
|
||||
}
|
||||
|
||||
type Column struct {
|
||||
DataType string `json:"dataType" gorm:"column:data_type"`
|
||||
ColumnName string `json:"columnName" gorm:"column:column_name"`
|
||||
DataTypeLong string `json:"dataTypeLong" gorm:"column:data_type_long"`
|
||||
ColumnComment string `json:"columnComment" gorm:"column:column_comment"`
|
||||
PrimaryKey bool `json:"primaryKey" gorm:"column:primary_key"`
|
||||
}
|
||||
|
||||
type PluginInfo struct {
|
||||
PluginName string `json:"pluginName"`
|
||||
PluginType string `json:"pluginType"` // web, server, full
|
||||
Apis []system.SysApi `json:"apis"`
|
||||
Menus []system.SysBaseMenu `json:"menus"`
|
||||
Dictionaries []system.SysDictionary `json:"dictionaries"`
|
||||
}
|
||||
8
server/model/system/response/sys_captcha.go
Normal file
8
server/model/system/response/sys_captcha.go
Normal file
@@ -0,0 +1,8 @@
|
||||
package response
|
||||
|
||||
type SysCaptchaResponse struct {
|
||||
CaptchaId string `json:"captchaId"`
|
||||
PicPath string `json:"picPath"`
|
||||
CaptchaLength int `json:"captchaLength"`
|
||||
OpenCaptcha bool `json:"openCaptcha"`
|
||||
}
|
||||
9
server/model/system/response/sys_casbin.go
Normal file
9
server/model/system/response/sys_casbin.go
Normal file
@@ -0,0 +1,9 @@
|
||||
package response
|
||||
|
||||
import (
|
||||
"git.echol.cn/loser/ai_proxy/server/model/system/request"
|
||||
)
|
||||
|
||||
type PolicyPathResponse struct {
|
||||
Paths []request.CasbinInfo `json:"paths"`
|
||||
}
|
||||
15
server/model/system/response/sys_menu.go
Normal file
15
server/model/system/response/sys_menu.go
Normal file
@@ -0,0 +1,15 @@
|
||||
package response
|
||||
|
||||
import "git.echol.cn/loser/ai_proxy/server/model/system"
|
||||
|
||||
type SysMenusResponse struct {
|
||||
Menus []system.SysMenu `json:"menus"`
|
||||
}
|
||||
|
||||
type SysBaseMenusResponse struct {
|
||||
Menus []system.SysBaseMenu `json:"menus"`
|
||||
}
|
||||
|
||||
type SysBaseMenuResponse struct {
|
||||
Menu system.SysBaseMenu `json:"menu"`
|
||||
}
|
||||
7
server/model/system/response/sys_system.go
Normal file
7
server/model/system/response/sys_system.go
Normal file
@@ -0,0 +1,7 @@
|
||||
package response
|
||||
|
||||
import "git.echol.cn/loser/ai_proxy/server/config"
|
||||
|
||||
type SysConfigResponse struct {
|
||||
Config config.Server `json:"config"`
|
||||
}
|
||||
@@ -1,17 +1,15 @@
|
||||
package response
|
||||
|
||||
type LoginResponse struct {
|
||||
Token string `json:"token"`
|
||||
User UserInfo `json:"user"`
|
||||
import (
|
||||
"git.echol.cn/loser/ai_proxy/server/model/system"
|
||||
)
|
||||
|
||||
type SysUserResponse struct {
|
||||
User system.SysUser `json:"user"`
|
||||
}
|
||||
|
||||
type UserInfo struct {
|
||||
ID uint `json:"id"`
|
||||
Username string `json:"username"`
|
||||
Nickname string `json:"nickname"`
|
||||
Email string `json:"email"`
|
||||
Phone string `json:"phone"`
|
||||
Avatar string `json:"avatar"`
|
||||
Role string `json:"role"`
|
||||
Status string `json:"status"`
|
||||
type LoginResponse struct {
|
||||
User system.SysUser `json:"user"`
|
||||
Token string `json:"token"`
|
||||
ExpiresAt int64 `json:"expiresAt"`
|
||||
}
|
||||
|
||||
14
server/model/system/response/sys_version.go
Normal file
14
server/model/system/response/sys_version.go
Normal file
@@ -0,0 +1,14 @@
|
||||
package response
|
||||
|
||||
import (
|
||||
"git.echol.cn/loser/ai_proxy/server/model/system"
|
||||
"git.echol.cn/loser/ai_proxy/server/model/system/request"
|
||||
)
|
||||
|
||||
// ExportVersionResponse 导出版本响应结构体
|
||||
type ExportVersionResponse struct {
|
||||
Version request.VersionInfo `json:"version"` // 版本信息
|
||||
Menus []system.SysBaseMenu `json:"menus"` // 菜单数据,直接复用SysBaseMenu
|
||||
Apis []system.SysApi `json:"apis"` // API数据,直接复用SysApi
|
||||
Dictionaries []system.SysDictionary `json:"dictionaries"` // 字典数据,直接复用SysDictionary
|
||||
}
|
||||
@@ -4,15 +4,25 @@ import (
|
||||
"git.echol.cn/loser/ai_proxy/server/global"
|
||||
)
|
||||
|
||||
// SysApi API管理
|
||||
type SysApi struct {
|
||||
global.GVA_MODEL
|
||||
Path string `json:"path" gorm:"comment:API路径;size:255;not null"`
|
||||
Description string `json:"description" gorm:"comment:API描述;size:500"`
|
||||
ApiGroup string `json:"apiGroup" gorm:"comment:API分组;size:100"`
|
||||
Method string `json:"method" gorm:"comment:请求方法;size:20;not null"` // GET/POST/PUT/DELETE
|
||||
Path string `json:"path" gorm:"comment:api路径"` // api路径
|
||||
Description string `json:"description" gorm:"comment:api中文描述"` // api中文描述
|
||||
ApiGroup string `json:"apiGroup" gorm:"comment:api组"` // api组
|
||||
Method string `json:"method" gorm:"default:POST;comment:方法"` // 方法:创建POST(默认)|查看GET|更新PUT|删除DELETE
|
||||
}
|
||||
|
||||
func (SysApi) TableName() string {
|
||||
return "sys_apis"
|
||||
}
|
||||
|
||||
type SysIgnoreApi struct {
|
||||
global.GVA_MODEL
|
||||
Path string `json:"path" gorm:"comment:api路径"` // api路径
|
||||
Method string `json:"method" gorm:"default:POST;comment:方法"` // 方法:创建POST(默认)|查看GET|更新PUT|删除DELETE
|
||||
Flag bool `json:"flag" gorm:"-"` // 是否忽略
|
||||
}
|
||||
|
||||
func (SysIgnoreApi) TableName() string {
|
||||
return "sys_ignore_apis"
|
||||
}
|
||||
|
||||
17
server/model/system/sys_api_token.go
Normal file
17
server/model/system/sys_api_token.go
Normal file
@@ -0,0 +1,17 @@
|
||||
package system
|
||||
|
||||
import (
|
||||
"git.echol.cn/loser/ai_proxy/server/global"
|
||||
"time"
|
||||
)
|
||||
|
||||
type SysApiToken struct {
|
||||
global.GVA_MODEL
|
||||
UserID uint `json:"userId" gorm:"comment:用户ID"`
|
||||
User SysUser `json:"user" gorm:"foreignKey:UserID;"`
|
||||
AuthorityID uint `json:"authorityId" gorm:"comment:角色ID"`
|
||||
Token string `json:"token" gorm:"type:text;comment:Token"`
|
||||
Status bool `json:"status" gorm:"default:true;comment:状态"` // true有效 false无效
|
||||
ExpiresAt time.Time `json:"expiresAt" gorm:"comment:过期时间"`
|
||||
Remark string `json:"remark" gorm:"comment:备注"`
|
||||
}
|
||||
23
server/model/system/sys_authority.go
Normal file
23
server/model/system/sys_authority.go
Normal file
@@ -0,0 +1,23 @@
|
||||
package system
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
type SysAuthority struct {
|
||||
CreatedAt time.Time // 创建时间
|
||||
UpdatedAt time.Time // 更新时间
|
||||
DeletedAt *time.Time `sql:"index"`
|
||||
AuthorityId uint `json:"authorityId" gorm:"not null;unique;primary_key;comment:角色ID;size:90"` // 角色ID
|
||||
AuthorityName string `json:"authorityName" gorm:"comment:角色名"` // 角色名
|
||||
ParentId *uint `json:"parentId" gorm:"comment:父角色ID"` // 父角色ID
|
||||
DataAuthorityId []*SysAuthority `json:"dataAuthorityId" gorm:"many2many:sys_data_authority_id;"`
|
||||
Children []SysAuthority `json:"children" gorm:"-"`
|
||||
SysBaseMenus []SysBaseMenu `json:"menus" gorm:"many2many:sys_authority_menus;"`
|
||||
Users []SysUser `json:"-" gorm:"many2many:sys_user_authority;"`
|
||||
DefaultRouter string `json:"defaultRouter" gorm:"comment:默认菜单;default:dashboard"` // 默认菜单(默认dashboard)
|
||||
}
|
||||
|
||||
func (SysAuthority) TableName() string {
|
||||
return "sys_authorities"
|
||||
}
|
||||
8
server/model/system/sys_authority_btn.go
Normal file
8
server/model/system/sys_authority_btn.go
Normal file
@@ -0,0 +1,8 @@
|
||||
package system
|
||||
|
||||
type SysAuthorityBtn struct {
|
||||
AuthorityId uint `gorm:"comment:角色ID"`
|
||||
SysMenuID uint `gorm:"comment:菜单ID"`
|
||||
SysBaseMenuBtnID uint `gorm:"comment:菜单按钮ID"`
|
||||
SysBaseMenuBtn SysBaseMenuBtn ` gorm:"comment:按钮详情"`
|
||||
}
|
||||
19
server/model/system/sys_authority_menu.go
Normal file
19
server/model/system/sys_authority_menu.go
Normal file
@@ -0,0 +1,19 @@
|
||||
package system
|
||||
|
||||
type SysMenu struct {
|
||||
SysBaseMenu
|
||||
MenuId uint `json:"menuId" gorm:"comment:菜单ID"`
|
||||
AuthorityId uint `json:"-" gorm:"comment:角色ID"`
|
||||
Children []SysMenu `json:"children" gorm:"-"`
|
||||
Parameters []SysBaseMenuParameter `json:"parameters" gorm:"foreignKey:SysBaseMenuID;references:MenuId"`
|
||||
Btns map[string]uint `json:"btns" gorm:"-"`
|
||||
}
|
||||
|
||||
type SysAuthorityMenu struct {
|
||||
MenuId string `json:"menuId" gorm:"comment:菜单ID;column:sys_base_menu_id"`
|
||||
AuthorityId string `json:"-" gorm:"comment:角色ID;column:sys_authority_authority_id"`
|
||||
}
|
||||
|
||||
func (s SysAuthorityMenu) TableName() string {
|
||||
return "sys_authority_menus"
|
||||
}
|
||||
68
server/model/system/sys_auto_code_history.go
Normal file
68
server/model/system/sys_auto_code_history.go
Normal file
@@ -0,0 +1,68 @@
|
||||
package system
|
||||
|
||||
import (
|
||||
"git.echol.cn/loser/ai_proxy/server/global"
|
||||
"gorm.io/gorm"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// SysAutoCodeHistory 自动迁移代码记录,用于回滚,重放使用
|
||||
type SysAutoCodeHistory struct {
|
||||
global.GVA_MODEL
|
||||
Table string `json:"tableName" gorm:"column:table_name;comment:表名"`
|
||||
Package string `json:"package" gorm:"column:package;comment:模块名/插件名"`
|
||||
Request string `json:"request" gorm:"type:text;column:request;comment:前端传入的结构化信息"`
|
||||
StructName string `json:"structName" gorm:"column:struct_name;comment:结构体名称"`
|
||||
Abbreviation string `json:"abbreviation" gorm:"column:abbreviation;comment:结构体名称缩写"`
|
||||
BusinessDB string `json:"businessDb" gorm:"column:business_db;comment:业务库"`
|
||||
Description string `json:"description" gorm:"column:description;comment:Struct中文名称"`
|
||||
Templates map[string]string `json:"template" gorm:"serializer:json;type:text;column:templates;comment:模板信息"`
|
||||
Injections map[string]string `json:"injections" gorm:"serializer:json;type:text;column:Injections;comment:注入路径"`
|
||||
Flag int `json:"flag" gorm:"column:flag;comment:[0:创建,1:回滚]"`
|
||||
ApiIDs []uint `json:"apiIDs" gorm:"serializer:json;column:api_ids;comment:api表注册内容"`
|
||||
MenuID uint `json:"menuId" gorm:"column:menu_id;comment:菜单ID"`
|
||||
ExportTemplateID uint `json:"exportTemplateID" gorm:"column:export_template_id;comment:导出模板ID"`
|
||||
AutoCodePackage SysAutoCodePackage `json:"autoCodePackage" gorm:"foreignKey:ID;references:PackageID"`
|
||||
PackageID uint `json:"packageID" gorm:"column:package_id;comment:包ID"`
|
||||
}
|
||||
|
||||
func (s *SysAutoCodeHistory) BeforeCreate(db *gorm.DB) error {
|
||||
templates := make(map[string]string, len(s.Templates))
|
||||
for key, value := range s.Templates {
|
||||
server := filepath.Join(global.GVA_CONFIG.AutoCode.Root, global.GVA_CONFIG.AutoCode.Server)
|
||||
{
|
||||
hasServer := strings.Index(key, server)
|
||||
if hasServer != -1 {
|
||||
key = strings.TrimPrefix(key, server)
|
||||
keys := strings.Split(key, string(os.PathSeparator))
|
||||
key = path.Join(keys...)
|
||||
}
|
||||
} // key
|
||||
web := filepath.Join(global.GVA_CONFIG.AutoCode.Root, global.GVA_CONFIG.AutoCode.WebRoot())
|
||||
hasWeb := strings.Index(value, web)
|
||||
if hasWeb != -1 {
|
||||
value = strings.TrimPrefix(value, web)
|
||||
values := strings.Split(value, string(os.PathSeparator))
|
||||
value = path.Join(values...)
|
||||
templates[key] = value
|
||||
continue
|
||||
}
|
||||
hasServer := strings.Index(value, server)
|
||||
if hasServer != -1 {
|
||||
value = strings.TrimPrefix(value, server)
|
||||
values := strings.Split(value, string(os.PathSeparator))
|
||||
value = path.Join(values...)
|
||||
templates[key] = value
|
||||
continue
|
||||
}
|
||||
}
|
||||
s.Templates = templates
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *SysAutoCodeHistory) TableName() string {
|
||||
return "sys_auto_code_histories"
|
||||
}
|
||||
18
server/model/system/sys_auto_code_package.go
Normal file
18
server/model/system/sys_auto_code_package.go
Normal file
@@ -0,0 +1,18 @@
|
||||
package system
|
||||
|
||||
import (
|
||||
"git.echol.cn/loser/ai_proxy/server/global"
|
||||
)
|
||||
|
||||
type SysAutoCodePackage struct {
|
||||
global.GVA_MODEL
|
||||
Desc string `json:"desc" gorm:"comment:描述"`
|
||||
Label string `json:"label" gorm:"comment:展示名"`
|
||||
Template string `json:"template" gorm:"comment:模版"`
|
||||
PackageName string `json:"packageName" gorm:"comment:包名"`
|
||||
Module string `json:"-" example:"模块"`
|
||||
}
|
||||
|
||||
func (s *SysAutoCodePackage) TableName() string {
|
||||
return "sys_auto_code_packages"
|
||||
}
|
||||
43
server/model/system/sys_base_menu.go
Normal file
43
server/model/system/sys_base_menu.go
Normal file
@@ -0,0 +1,43 @@
|
||||
package system
|
||||
|
||||
import (
|
||||
"git.echol.cn/loser/ai_proxy/server/global"
|
||||
)
|
||||
|
||||
type SysBaseMenu struct {
|
||||
global.GVA_MODEL
|
||||
MenuLevel uint `json:"-"`
|
||||
ParentId uint `json:"parentId" gorm:"comment:父菜单ID"` // 父菜单ID
|
||||
Path string `json:"path" gorm:"comment:路由path"` // 路由path
|
||||
Name string `json:"name" gorm:"comment:路由name"` // 路由name
|
||||
Hidden bool `json:"hidden" gorm:"comment:是否在列表隐藏"` // 是否在列表隐藏
|
||||
Component string `json:"component" gorm:"comment:对应前端文件路径"` // 对应前端文件路径
|
||||
Sort int `json:"sort" gorm:"comment:排序标记"` // 排序标记
|
||||
Meta `json:"meta" gorm:"embedded"` // 附加属性
|
||||
SysAuthoritys []SysAuthority `json:"authoritys" gorm:"many2many:sys_authority_menus;"`
|
||||
Children []SysBaseMenu `json:"children" gorm:"-"`
|
||||
Parameters []SysBaseMenuParameter `json:"parameters"`
|
||||
MenuBtn []SysBaseMenuBtn `json:"menuBtn"`
|
||||
}
|
||||
|
||||
type Meta struct {
|
||||
ActiveName string `json:"activeName" gorm:"comment:高亮菜单"`
|
||||
KeepAlive bool `json:"keepAlive" gorm:"comment:是否缓存"` // 是否缓存
|
||||
DefaultMenu bool `json:"defaultMenu" gorm:"comment:是否是基础路由(开发中)"` // 是否是基础路由(开发中)
|
||||
Title string `json:"title" gorm:"comment:菜单名"` // 菜单名
|
||||
Icon string `json:"icon" gorm:"comment:菜单图标"` // 菜单图标
|
||||
CloseTab bool `json:"closeTab" gorm:"comment:自动关闭tab"` // 自动关闭tab
|
||||
TransitionType string `json:"transitionType" gorm:"comment:路由切换动画"` // 路由切换动画
|
||||
}
|
||||
|
||||
type SysBaseMenuParameter struct {
|
||||
global.GVA_MODEL
|
||||
SysBaseMenuID uint
|
||||
Type string `json:"type" gorm:"comment:地址栏携带参数为params还是query"` // 地址栏携带参数为params还是query
|
||||
Key string `json:"key" gorm:"comment:地址栏携带参数的key"` // 地址栏携带参数的key
|
||||
Value string `json:"value" gorm:"comment:地址栏携带参数的值"` // 地址栏携带参数的值
|
||||
}
|
||||
|
||||
func (SysBaseMenu) TableName() string {
|
||||
return "sys_base_menus"
|
||||
}
|
||||
22
server/model/system/sys_dictionary.go
Normal file
22
server/model/system/sys_dictionary.go
Normal file
@@ -0,0 +1,22 @@
|
||||
// 自动生成模板SysDictionary
|
||||
package system
|
||||
|
||||
import (
|
||||
"git.echol.cn/loser/ai_proxy/server/global"
|
||||
)
|
||||
|
||||
// 如果含有time.Time 请自行import time包
|
||||
type SysDictionary struct {
|
||||
global.GVA_MODEL
|
||||
Name string `json:"name" form:"name" gorm:"column:name;comment:字典名(中)"` // 字典名(中)
|
||||
Type string `json:"type" form:"type" gorm:"column:type;comment:字典名(英)"` // 字典名(英)
|
||||
Status *bool `json:"status" form:"status" gorm:"column:status;comment:状态"` // 状态
|
||||
Desc string `json:"desc" form:"desc" gorm:"column:desc;comment:描述"` // 描述
|
||||
ParentID *uint `json:"parentID" form:"parentID" gorm:"column:parent_id;comment:父级字典ID"` // 父级字典ID
|
||||
Children []SysDictionary `json:"children" gorm:"foreignKey:ParentID"` // 子字典
|
||||
SysDictionaryDetails []SysDictionaryDetail `json:"sysDictionaryDetails" form:"sysDictionaryDetails"`
|
||||
}
|
||||
|
||||
func (SysDictionary) TableName() string {
|
||||
return "sys_dictionaries"
|
||||
}
|
||||
26
server/model/system/sys_dictionary_detail.go
Normal file
26
server/model/system/sys_dictionary_detail.go
Normal file
@@ -0,0 +1,26 @@
|
||||
// 自动生成模板SysDictionaryDetail
|
||||
package system
|
||||
|
||||
import (
|
||||
"git.echol.cn/loser/ai_proxy/server/global"
|
||||
)
|
||||
|
||||
// 如果含有time.Time 请自行import time包
|
||||
type SysDictionaryDetail struct {
|
||||
global.GVA_MODEL
|
||||
Label string `json:"label" form:"label" gorm:"column:label;comment:展示值"` // 展示值
|
||||
Value string `json:"value" form:"value" gorm:"column:value;comment:字典值"` // 字典值
|
||||
Extend string `json:"extend" form:"extend" gorm:"column:extend;comment:扩展值"` // 扩展值
|
||||
Status *bool `json:"status" form:"status" gorm:"column:status;comment:启用状态"` // 启用状态
|
||||
Sort int `json:"sort" form:"sort" gorm:"column:sort;comment:排序标记"` // 排序标记
|
||||
SysDictionaryID int `json:"sysDictionaryID" form:"sysDictionaryID" gorm:"column:sys_dictionary_id;comment:关联标记"` // 关联标记
|
||||
ParentID *uint `json:"parentID" form:"parentID" gorm:"column:parent_id;comment:父级字典详情ID"` // 父级字典详情ID
|
||||
Children []SysDictionaryDetail `json:"children" gorm:"foreignKey:ParentID"` // 子字典详情
|
||||
Level int `json:"level" form:"level" gorm:"column:level;comment:层级深度"` // 层级深度,从0开始
|
||||
Path string `json:"path" form:"path" gorm:"column:path;comment:层级路径"` // 层级路径,如 "1,2,3"
|
||||
Disabled bool `json:"disabled" gorm:"-"` // 禁用状态,根据status字段动态计算
|
||||
}
|
||||
|
||||
func (SysDictionaryDetail) TableName() string {
|
||||
return "sys_dictionary_details"
|
||||
}
|
||||
21
server/model/system/sys_error.go
Normal file
21
server/model/system/sys_error.go
Normal file
@@ -0,0 +1,21 @@
|
||||
// 自动生成模板SysError
|
||||
package system
|
||||
|
||||
import (
|
||||
"git.echol.cn/loser/ai_proxy/server/global"
|
||||
)
|
||||
|
||||
// 错误日志 结构体 SysError
|
||||
type SysError struct {
|
||||
global.GVA_MODEL
|
||||
Form *string `json:"form" form:"form" gorm:"comment:错误来源;column:form;type:text;" binding:"required"` //错误来源
|
||||
Info *string `json:"info" form:"info" gorm:"comment:错误内容;column:info;type:text;"` //错误内容
|
||||
Level string `json:"level" form:"level" gorm:"comment:日志等级;column:level;"`
|
||||
Solution *string `json:"solution" form:"solution" gorm:"comment:解决方案;column:solution;type:text"` //解决方案
|
||||
Status string `json:"status" form:"status" gorm:"comment:处理状态;column:status;type:varchar(20);default:未处理;"` //处理状态:未处理/处理中/处理完成
|
||||
}
|
||||
|
||||
// TableName 错误日志 SysError自定义表名 sys_error
|
||||
func (SysError) TableName() string {
|
||||
return "sys_error"
|
||||
}
|
||||
46
server/model/system/sys_export_template.go
Normal file
46
server/model/system/sys_export_template.go
Normal file
@@ -0,0 +1,46 @@
|
||||
// 自动生成模板SysExportTemplate
|
||||
package system
|
||||
|
||||
import (
|
||||
"git.echol.cn/loser/ai_proxy/server/global"
|
||||
)
|
||||
|
||||
// 导出模板 结构体 SysExportTemplate
|
||||
type SysExportTemplate struct {
|
||||
global.GVA_MODEL
|
||||
DBName string `json:"dbName" form:"dbName" gorm:"column:db_name;comment:数据库名称;"` //数据库名称
|
||||
Name string `json:"name" form:"name" gorm:"column:name;comment:模板名称;"` //模板名称
|
||||
TableName string `json:"tableName" form:"tableName" gorm:"column:table_name;comment:表名称;"` //表名称
|
||||
TemplateID string `json:"templateID" form:"templateID" gorm:"column:template_id;comment:模板标识;"` //模板标识
|
||||
TemplateInfo string `json:"templateInfo" form:"templateInfo" gorm:"column:template_info;type:text;"` //模板信息
|
||||
SQL string `json:"sql" form:"sql" gorm:"column:sql;type:text;comment:自定义导出SQL;"` //自定义导出SQL
|
||||
ImportSQL string `json:"importSql" form:"importSql" gorm:"column:import_sql;type:text;comment:自定义导入SQL;"` //自定义导入SQL
|
||||
Limit *int `json:"limit" form:"limit" gorm:"column:limit;comment:导出限制"`
|
||||
Order string `json:"order" form:"order" gorm:"column:order;comment:排序"`
|
||||
Conditions []Condition `json:"conditions" form:"conditions" gorm:"foreignKey:TemplateID;references:TemplateID;comment:条件"`
|
||||
JoinTemplate []JoinTemplate `json:"joinTemplate" form:"joinTemplate" gorm:"foreignKey:TemplateID;references:TemplateID;comment:关联"`
|
||||
}
|
||||
|
||||
type JoinTemplate struct {
|
||||
global.GVA_MODEL
|
||||
TemplateID string `json:"templateID" form:"templateID" gorm:"column:template_id;comment:模板标识"`
|
||||
JOINS string `json:"joins" form:"joins" gorm:"column:joins;comment:关联"`
|
||||
Table string `json:"table" form:"table" gorm:"column:table;comment:关联表"`
|
||||
ON string `json:"on" form:"on" gorm:"column:on;comment:关联条件"`
|
||||
}
|
||||
|
||||
func (JoinTemplate) TableName() string {
|
||||
return "sys_export_template_join"
|
||||
}
|
||||
|
||||
type Condition struct {
|
||||
global.GVA_MODEL
|
||||
TemplateID string `json:"templateID" form:"templateID" gorm:"column:template_id;comment:模板标识"`
|
||||
From string `json:"from" form:"from" gorm:"column:from;comment:条件取的key"`
|
||||
Column string `json:"column" form:"column" gorm:"column:column;comment:作为查询条件的字段"`
|
||||
Operator string `json:"operator" form:"operator" gorm:"column:operator;comment:操作符"`
|
||||
}
|
||||
|
||||
func (Condition) TableName() string {
|
||||
return "sys_export_template_condition"
|
||||
}
|
||||
10
server/model/system/sys_jwt_blacklist.go
Normal file
10
server/model/system/sys_jwt_blacklist.go
Normal file
@@ -0,0 +1,10 @@
|
||||
package system
|
||||
|
||||
import (
|
||||
"git.echol.cn/loser/ai_proxy/server/global"
|
||||
)
|
||||
|
||||
type JwtBlacklist struct {
|
||||
global.GVA_MODEL
|
||||
Jwt string `gorm:"type:text;comment:jwt"`
|
||||
}
|
||||
16
server/model/system/sys_login_log.go
Normal file
16
server/model/system/sys_login_log.go
Normal file
@@ -0,0 +1,16 @@
|
||||
package system
|
||||
|
||||
import (
|
||||
"git.echol.cn/loser/ai_proxy/server/global"
|
||||
)
|
||||
|
||||
type SysLoginLog struct {
|
||||
global.GVA_MODEL
|
||||
Username string `json:"username" gorm:"column:username;comment:用户名"`
|
||||
Ip string `json:"ip" gorm:"column:ip;comment:请求ip"`
|
||||
Status bool `json:"status" gorm:"column:status;comment:登录状态"`
|
||||
ErrorMessage string `json:"errorMessage" gorm:"column:error_message;comment:错误信息"`
|
||||
Agent string `json:"agent" gorm:"column:agent;comment:代理"`
|
||||
UserID uint `json:"userId" gorm:"column:user_id;comment:用户id"`
|
||||
User SysUser `json:"user" gorm:"foreignKey:UserID"`
|
||||
}
|
||||
10
server/model/system/sys_menu_btn.go
Normal file
10
server/model/system/sys_menu_btn.go
Normal file
@@ -0,0 +1,10 @@
|
||||
package system
|
||||
|
||||
import "git.echol.cn/loser/ai_proxy/server/global"
|
||||
|
||||
type SysBaseMenuBtn struct {
|
||||
global.GVA_MODEL
|
||||
Name string `json:"name" gorm:"comment:按钮关键key"`
|
||||
Desc string `json:"desc" gorm:"按钮备注"`
|
||||
SysBaseMenuID uint `json:"sysBaseMenuID" gorm:"comment:菜单ID"`
|
||||
}
|
||||
24
server/model/system/sys_operation_record.go
Normal file
24
server/model/system/sys_operation_record.go
Normal file
@@ -0,0 +1,24 @@
|
||||
// 自动生成模板SysOperationRecord
|
||||
package system
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"git.echol.cn/loser/ai_proxy/server/global"
|
||||
)
|
||||
|
||||
// 如果含有time.Time 请自行import time包
|
||||
type SysOperationRecord struct {
|
||||
global.GVA_MODEL
|
||||
Ip string `json:"ip" form:"ip" gorm:"column:ip;comment:请求ip"` // 请求ip
|
||||
Method string `json:"method" form:"method" gorm:"column:method;comment:请求方法"` // 请求方法
|
||||
Path string `json:"path" form:"path" gorm:"column:path;comment:请求路径"` // 请求路径
|
||||
Status int `json:"status" form:"status" gorm:"column:status;comment:请求状态"` // 请求状态
|
||||
Latency time.Duration `json:"latency" form:"latency" gorm:"column:latency;comment:延迟" swaggertype:"string"` // 延迟
|
||||
Agent string `json:"agent" form:"agent" gorm:"type:text;column:agent;comment:代理"` // 代理
|
||||
ErrorMessage string `json:"error_message" form:"error_message" gorm:"column:error_message;comment:错误信息"` // 错误信息
|
||||
Body string `json:"body" form:"body" gorm:"type:text;column:body;comment:请求Body"` // 请求Body
|
||||
Resp string `json:"resp" form:"resp" gorm:"type:text;column:resp;comment:响应Body"` // 响应Body
|
||||
UserID int `json:"user_id" form:"user_id" gorm:"column:user_id;comment:用户id"` // 用户id
|
||||
User SysUser `json:"user"`
|
||||
}
|
||||
20
server/model/system/sys_params.go
Normal file
20
server/model/system/sys_params.go
Normal file
@@ -0,0 +1,20 @@
|
||||
// 自动生成模板SysParams
|
||||
package system
|
||||
|
||||
import (
|
||||
"git.echol.cn/loser/ai_proxy/server/global"
|
||||
)
|
||||
|
||||
// 参数 结构体 SysParams
|
||||
type SysParams struct {
|
||||
global.GVA_MODEL
|
||||
Name string `json:"name" form:"name" gorm:"column:name;comment:参数名称;" binding:"required"` //参数名称
|
||||
Key string `json:"key" form:"key" gorm:"column:key;comment:参数键;" binding:"required"` //参数键
|
||||
Value string `json:"value" form:"value" gorm:"column:value;comment:参数值;" binding:"required"` //参数值
|
||||
Desc string `json:"desc" form:"desc" gorm:"column:desc;comment:参数说明;"` //参数说明
|
||||
}
|
||||
|
||||
// TableName 参数 SysParams自定义表名 sys_params
|
||||
func (SysParams) TableName() string {
|
||||
return "sys_params"
|
||||
}
|
||||
25
server/model/system/sys_skills.go
Normal file
25
server/model/system/sys_skills.go
Normal file
@@ -0,0 +1,25 @@
|
||||
package system
|
||||
|
||||
type SkillMeta struct {
|
||||
Name string `json:"name" yaml:"name"`
|
||||
Description string `json:"description" yaml:"description"`
|
||||
AllowedTools string `json:"allowedTools" yaml:"allowed-tools,omitempty"`
|
||||
Context string `json:"context" yaml:"context,omitempty"`
|
||||
Agent string `json:"agent" yaml:"agent,omitempty"`
|
||||
}
|
||||
|
||||
type SkillDetail struct {
|
||||
Tool string `json:"tool"`
|
||||
Skill string `json:"skill"`
|
||||
Meta SkillMeta `json:"meta"`
|
||||
Markdown string `json:"markdown"`
|
||||
Scripts []string `json:"scripts"`
|
||||
Resources []string `json:"resources"`
|
||||
References []string `json:"references"`
|
||||
Templates []string `json:"templates"`
|
||||
}
|
||||
|
||||
type SkillTool struct {
|
||||
Key string `json:"key"`
|
||||
Label string `json:"label"`
|
||||
}
|
||||
10
server/model/system/sys_system.go
Normal file
10
server/model/system/sys_system.go
Normal file
@@ -0,0 +1,10 @@
|
||||
package system
|
||||
|
||||
import (
|
||||
"git.echol.cn/loser/ai_proxy/server/config"
|
||||
)
|
||||
|
||||
// 配置文件结构体
|
||||
type System struct {
|
||||
Config config.Server `json:"config"`
|
||||
}
|
||||
@@ -2,55 +2,61 @@ package system
|
||||
|
||||
import (
|
||||
"git.echol.cn/loser/ai_proxy/server/global"
|
||||
"git.echol.cn/loser/ai_proxy/server/model/common"
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
// SysUser 系统用户
|
||||
type Login interface {
|
||||
GetUsername() string
|
||||
GetNickname() string
|
||||
GetUUID() uuid.UUID
|
||||
GetUserId() uint
|
||||
GetAuthorityId() uint
|
||||
GetUserInfo() any
|
||||
}
|
||||
|
||||
var _ Login = new(SysUser)
|
||||
|
||||
type SysUser struct {
|
||||
global.GVA_MODEL
|
||||
Username string `json:"username" gorm:"comment:用户名;size:100;uniqueIndex;not null"`
|
||||
Password string `json:"-" gorm:"comment:密码;size:255;not null"`
|
||||
Nickname string `json:"nickname" gorm:"comment:昵称;size:100"`
|
||||
Email string `json:"email" gorm:"comment:邮箱;size:100"`
|
||||
Phone string `json:"phone" gorm:"comment:手机号;size:20"`
|
||||
Avatar string `json:"avatar" gorm:"comment:头像;size:500"`
|
||||
Role string `json:"role" gorm:"comment:角色;size:20;default:'user'"` // admin/user
|
||||
Status string `json:"status" gorm:"comment:状态;size:20;default:'active'"` // active/disabled
|
||||
APIKey string `json:"apiKey" gorm:"comment:API密钥;size:255;uniqueIndex"`
|
||||
UUID uuid.UUID `json:"uuid" gorm:"index;comment:用户UUID"` // 用户UUID
|
||||
Username string `json:"userName" gorm:"index;comment:用户登录名"` // 用户登录名
|
||||
Password string `json:"-" gorm:"comment:用户登录密码"` // 用户登录密码
|
||||
NickName string `json:"nickName" gorm:"default:系统用户;comment:用户昵称"` // 用户昵称
|
||||
HeaderImg string `json:"headerImg" gorm:"default:https://qmplusimg.henrongyi.top/gva_header.jpg;comment:用户头像"` // 用户头像
|
||||
AuthorityId uint `json:"authorityId" gorm:"default:888;comment:用户角色ID"` // 用户角色ID
|
||||
Authority SysAuthority `json:"authority" gorm:"foreignKey:AuthorityId;references:AuthorityId;comment:用户角色"` // 用户角色
|
||||
Authorities []SysAuthority `json:"authorities" gorm:"many2many:sys_user_authority;"` // 多用户角色
|
||||
Phone string `json:"phone" gorm:"comment:用户手机号"` // 用户手机号
|
||||
Email string `json:"email" gorm:"comment:用户邮箱"` // 用户邮箱
|
||||
Enable int `json:"enable" gorm:"default:1;comment:用户是否被冻结 1正常 2冻结"` //用户是否被冻结 1正常 2冻结
|
||||
OriginSetting common.JSONMap `json:"originSetting" form:"originSetting" gorm:"type:text;default:null;column:origin_setting;comment:配置;"` //配置
|
||||
}
|
||||
|
||||
func (SysUser) TableName() string {
|
||||
return "sys_users"
|
||||
}
|
||||
|
||||
// Login 接口实现
|
||||
type Login interface {
|
||||
GetUUID() uuid.UUID
|
||||
GetUserId() uint
|
||||
GetUsername() string
|
||||
GetNickname() string
|
||||
GetAuthorityId() uint
|
||||
}
|
||||
|
||||
func (s *SysUser) GetUUID() uuid.UUID {
|
||||
return uuid.New()
|
||||
}
|
||||
|
||||
func (s *SysUser) GetUserId() uint {
|
||||
return s.ID
|
||||
}
|
||||
|
||||
func (s *SysUser) GetUsername() string {
|
||||
return s.Username
|
||||
}
|
||||
|
||||
func (s *SysUser) GetNickname() string {
|
||||
return s.Nickname
|
||||
return s.NickName
|
||||
}
|
||||
|
||||
func (s *SysUser) GetUUID() uuid.UUID {
|
||||
return s.UUID
|
||||
}
|
||||
|
||||
func (s *SysUser) GetUserId() uint {
|
||||
return s.ID
|
||||
}
|
||||
|
||||
func (s *SysUser) GetAuthorityId() uint {
|
||||
if s.Role == "admin" {
|
||||
return 1
|
||||
}
|
||||
return 2
|
||||
return s.AuthorityId
|
||||
}
|
||||
|
||||
func (s *SysUser) GetUserInfo() any {
|
||||
return *s
|
||||
}
|
||||
|
||||
11
server/model/system/sys_user_authority.go
Normal file
11
server/model/system/sys_user_authority.go
Normal file
@@ -0,0 +1,11 @@
|
||||
package system
|
||||
|
||||
// SysUserAuthority 是 sysUser 和 sysAuthority 的连接表
|
||||
type SysUserAuthority struct {
|
||||
SysUserId uint `gorm:"column:sys_user_id"`
|
||||
SysAuthorityAuthorityId uint `gorm:"column:sys_authority_authority_id"`
|
||||
}
|
||||
|
||||
func (s *SysUserAuthority) TableName() string {
|
||||
return "sys_user_authority"
|
||||
}
|
||||
20
server/model/system/sys_version.go
Normal file
20
server/model/system/sys_version.go
Normal file
@@ -0,0 +1,20 @@
|
||||
// 自动生成模板SysVersion
|
||||
package system
|
||||
|
||||
import (
|
||||
"git.echol.cn/loser/ai_proxy/server/global"
|
||||
)
|
||||
|
||||
// 版本管理 结构体 SysVersion
|
||||
type SysVersion struct {
|
||||
global.GVA_MODEL
|
||||
VersionName *string `json:"versionName" form:"versionName" gorm:"comment:版本名称;column:version_name;size:255;" binding:"required"` //版本名称
|
||||
VersionCode *string `json:"versionCode" form:"versionCode" gorm:"comment:版本号;column:version_code;size:100;" binding:"required"` //版本号
|
||||
Description *string `json:"description" form:"description" gorm:"comment:版本描述;column:description;size:500;"` //版本描述
|
||||
VersionData *string `json:"versionData" form:"versionData" gorm:"comment:版本数据JSON;column:version_data;type:text;"` //版本数据
|
||||
}
|
||||
|
||||
// TableName 版本管理 SysVersion自定义表名 sys_versions
|
||||
func (SysVersion) TableName() string {
|
||||
return "sys_versions"
|
||||
}
|
||||
Reference in New Issue
Block a user