88
server/model/app/response/ai_config.go
Normal file
88
server/model/app/response/ai_config.go
Normal file
@@ -0,0 +1,88 @@
|
||||
package response
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"time"
|
||||
|
||||
"git.echol.cn/loser/st/server/model/app"
|
||||
)
|
||||
|
||||
// AIConfigResponse AI配置响应
|
||||
type AIConfigResponse struct {
|
||||
ID uint `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Provider string `json:"provider"`
|
||||
BaseURL string `json:"baseUrl"`
|
||||
APIKey string `json:"apiKey"` // 前端显示时应该脱敏
|
||||
Models []string `json:"models"`
|
||||
DefaultModel string `json:"defaultModel"`
|
||||
Settings map[string]interface{} `json:"settings"`
|
||||
IsActive bool `json:"isActive"`
|
||||
IsDefault bool `json:"isDefault"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
UpdatedAt time.Time `json:"updatedAt"`
|
||||
}
|
||||
|
||||
// AIConfigListResponse AI配置列表响应
|
||||
type AIConfigListResponse struct {
|
||||
List []AIConfigResponse `json:"list"`
|
||||
Total int64 `json:"total"`
|
||||
}
|
||||
|
||||
// TestAIConfigResponse 测试AI配置响应
|
||||
type TestAIConfigResponse struct {
|
||||
Success bool `json:"success"`
|
||||
Message string `json:"message"`
|
||||
Latency int64 `json:"latency"` // 响应延迟(ms)
|
||||
}
|
||||
|
||||
// GetModelsResponse 获取模型列表响应
|
||||
type GetModelsResponse struct {
|
||||
Models []ModelInfo `json:"models"`
|
||||
}
|
||||
|
||||
// ModelInfo 模型信息
|
||||
type ModelInfo struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
OwnedBy string `json:"ownedBy"`
|
||||
}
|
||||
|
||||
// ToAIConfigResponse 转换为AI配置响应结构
|
||||
func ToAIConfigResponse(config *app.AIConfig) AIConfigResponse {
|
||||
resp := AIConfigResponse{
|
||||
ID: config.ID,
|
||||
Name: config.Name,
|
||||
Provider: config.Provider,
|
||||
BaseURL: config.BaseURL,
|
||||
APIKey: maskAPIKey(config.APIKey),
|
||||
DefaultModel: config.DefaultModel,
|
||||
IsActive: config.IsActive,
|
||||
IsDefault: config.IsDefault,
|
||||
CreatedAt: config.CreatedAt,
|
||||
UpdatedAt: config.UpdatedAt,
|
||||
}
|
||||
|
||||
// 解析 JSON 字段
|
||||
if len(config.Models) > 0 {
|
||||
var models []string
|
||||
json.Unmarshal(config.Models, &models)
|
||||
resp.Models = models
|
||||
}
|
||||
|
||||
if len(config.Settings) > 0 {
|
||||
var settings map[string]interface{}
|
||||
json.Unmarshal(config.Settings, &settings)
|
||||
resp.Settings = settings
|
||||
}
|
||||
|
||||
return resp
|
||||
}
|
||||
|
||||
// maskAPIKey 脱敏API Key
|
||||
func maskAPIKey(apiKey string) string {
|
||||
if len(apiKey) <= 8 {
|
||||
return "****"
|
||||
}
|
||||
return apiKey[:4] + "****" + apiKey[len(apiKey)-4:]
|
||||
}
|
||||
55
server/model/app/response/auth.go
Normal file
55
server/model/app/response/auth.go
Normal file
@@ -0,0 +1,55 @@
|
||||
package response
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"git.echol.cn/loser/st/server/model/app"
|
||||
)
|
||||
|
||||
// AppUserResponse 用户信息响应
|
||||
type AppUserResponse struct {
|
||||
ID uint `json:"id"`
|
||||
UUID string `json:"uuid"`
|
||||
Username string `json:"username"`
|
||||
NickName string `json:"nickName"`
|
||||
Email string `json:"email"`
|
||||
Phone string `json:"phone"`
|
||||
Avatar string `json:"avatar"`
|
||||
Status string `json:"status"`
|
||||
Enable bool `json:"enable"`
|
||||
IsAdmin bool `json:"isAdmin"`
|
||||
LastLoginAt *time.Time `json:"lastLoginAt"`
|
||||
LastLoginIP string `json:"lastLoginIp"`
|
||||
ChatCount int `json:"chatCount"`
|
||||
MessageCount int `json:"messageCount"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
}
|
||||
|
||||
// LoginResponse 登录响应
|
||||
type LoginResponse struct {
|
||||
User AppUserResponse `json:"user"`
|
||||
Token string `json:"token"`
|
||||
RefreshToken string `json:"refreshToken"`
|
||||
ExpiresAt int64 `json:"expiresAt"`
|
||||
}
|
||||
|
||||
// ToAppUserResponse 转换为用户响应结构
|
||||
func ToAppUserResponse(user *app.AppUser) AppUserResponse {
|
||||
return AppUserResponse{
|
||||
ID: user.ID,
|
||||
UUID: user.UUID,
|
||||
Username: user.Username,
|
||||
NickName: user.NickName,
|
||||
Email: user.Email,
|
||||
Phone: user.Phone,
|
||||
Avatar: user.Avatar,
|
||||
Status: user.Status,
|
||||
Enable: user.Enable,
|
||||
IsAdmin: user.IsAdmin,
|
||||
LastLoginAt: user.LastLoginAt,
|
||||
LastLoginIP: user.LastLoginIP,
|
||||
ChatCount: user.ChatCount,
|
||||
MessageCount: user.MessageCount,
|
||||
CreatedAt: user.CreatedAt,
|
||||
}
|
||||
}
|
||||
108
server/model/app/response/character.go
Normal file
108
server/model/app/response/character.go
Normal file
@@ -0,0 +1,108 @@
|
||||
package response
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"time"
|
||||
|
||||
"git.echol.cn/loser/st/server/model/app"
|
||||
)
|
||||
|
||||
// CharacterResponse 角色卡响应
|
||||
type CharacterResponse struct {
|
||||
ID uint `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Avatar string `json:"avatar"`
|
||||
Creator string `json:"creator"`
|
||||
Version string `json:"version"`
|
||||
Description string `json:"description"`
|
||||
Personality string `json:"personality"`
|
||||
Scenario string `json:"scenario"`
|
||||
FirstMes string `json:"firstMes"`
|
||||
MesExample string `json:"mesExample"`
|
||||
CreatorNotes string `json:"creatorNotes"`
|
||||
SystemPrompt string `json:"systemPrompt"`
|
||||
PostHistoryInstructions string `json:"postHistoryInstructions"`
|
||||
Tags []string `json:"tags"`
|
||||
AlternateGreetings []string `json:"alternateGreetings"`
|
||||
CharacterBook map[string]interface{} `json:"characterBook"`
|
||||
Extensions map[string]interface{} `json:"extensions"`
|
||||
Spec string `json:"spec"`
|
||||
SpecVersion string `json:"specVersion"`
|
||||
IsPublic bool `json:"isPublic"`
|
||||
UseCount int `json:"useCount"`
|
||||
FavoriteCount int `json:"favoriteCount"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
UpdatedAt time.Time `json:"updatedAt"`
|
||||
}
|
||||
|
||||
// CharacterSimpleResponse 角色卡简化响应(用于列表)
|
||||
type CharacterSimpleResponse struct {
|
||||
ID uint `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Avatar string `json:"avatar"`
|
||||
Description string `json:"description"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
UpdatedAt time.Time `json:"updatedAt"`
|
||||
}
|
||||
|
||||
// CharacterListResponse 角色卡列表响应
|
||||
type CharacterListResponse struct {
|
||||
List []CharacterResponse `json:"list"`
|
||||
Total int64 `json:"total"`
|
||||
Page int `json:"page"`
|
||||
PageSize int `json:"pageSize"`
|
||||
}
|
||||
|
||||
// ToCharacterResponse 转换为角色卡响应结构
|
||||
func ToCharacterResponse(character *app.AICharacter) CharacterResponse {
|
||||
resp := CharacterResponse{
|
||||
ID: character.ID,
|
||||
Name: character.Name,
|
||||
Avatar: character.Avatar,
|
||||
Creator: character.Creator,
|
||||
Version: character.Version,
|
||||
Description: character.Description,
|
||||
Personality: character.Personality,
|
||||
Scenario: character.Scenario,
|
||||
FirstMes: character.FirstMes,
|
||||
MesExample: character.MesExample,
|
||||
CreatorNotes: character.CreatorNotes,
|
||||
SystemPrompt: character.SystemPrompt,
|
||||
PostHistoryInstructions: character.PostHistoryInstructions,
|
||||
Spec: character.Spec,
|
||||
SpecVersion: character.SpecVersion,
|
||||
IsPublic: character.IsPublic,
|
||||
UseCount: character.UseCount,
|
||||
FavoriteCount: character.FavoriteCount,
|
||||
CreatedAt: character.CreatedAt,
|
||||
UpdatedAt: character.UpdatedAt,
|
||||
}
|
||||
|
||||
// 解析 JSON 字段
|
||||
if len(character.Tags) > 0 {
|
||||
json.Unmarshal(character.Tags, &resp.Tags)
|
||||
}
|
||||
if len(character.AlternateGreetings) > 0 {
|
||||
json.Unmarshal(character.AlternateGreetings, &resp.AlternateGreetings)
|
||||
}
|
||||
if len(character.CharacterBook) > 0 {
|
||||
json.Unmarshal(character.CharacterBook, &resp.CharacterBook)
|
||||
}
|
||||
if len(character.Extensions) > 0 {
|
||||
json.Unmarshal(character.Extensions, &resp.Extensions)
|
||||
}
|
||||
|
||||
return resp
|
||||
}
|
||||
|
||||
// ToCharacterSimpleResponse 转换为角色卡简化响应结构(用于列表)
|
||||
func ToCharacterSimpleResponse(character *app.AICharacter) CharacterSimpleResponse {
|
||||
return CharacterSimpleResponse{
|
||||
ID: character.ID,
|
||||
Name: character.Name,
|
||||
Avatar: character.Avatar,
|
||||
Description: character.Description,
|
||||
CreatedAt: character.CreatedAt,
|
||||
UpdatedAt: character.UpdatedAt,
|
||||
}
|
||||
}
|
||||
122
server/model/app/response/conversation.go
Normal file
122
server/model/app/response/conversation.go
Normal file
@@ -0,0 +1,122 @@
|
||||
package response
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"time"
|
||||
|
||||
"git.echol.cn/loser/st/server/model/app"
|
||||
)
|
||||
|
||||
// ConversationResponse 对话响应
|
||||
type ConversationResponse struct {
|
||||
ID uint `json:"id"`
|
||||
CharacterID uint `json:"characterId"`
|
||||
Title string `json:"title"`
|
||||
PresetID *uint `json:"presetId"`
|
||||
AIProvider string `json:"aiProvider"`
|
||||
Model string `json:"model"`
|
||||
Settings map[string]interface{} `json:"settings,omitempty"`
|
||||
MessageCount int `json:"messageCount"`
|
||||
TokenCount int `json:"tokenCount"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
UpdatedAt time.Time `json:"updatedAt"`
|
||||
|
||||
// 关联数据
|
||||
Character *CharacterResponse `json:"character,omitempty"`
|
||||
}
|
||||
|
||||
// ConversationListItemResponse 对话列表项响应(轻量级)
|
||||
type ConversationListItemResponse struct {
|
||||
ID uint `json:"id"`
|
||||
CharacterID uint `json:"characterId"`
|
||||
Title string `json:"title"`
|
||||
MessageCount int `json:"messageCount"`
|
||||
TokenCount int `json:"tokenCount"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
UpdatedAt time.Time `json:"updatedAt"`
|
||||
Character *CharacterSimpleResponse `json:"character,omitempty"`
|
||||
}
|
||||
|
||||
// MessageResponse 消息响应
|
||||
type MessageResponse struct {
|
||||
ID uint `json:"id"`
|
||||
ConversationID uint `json:"conversationId"`
|
||||
Role string `json:"role"`
|
||||
Content string `json:"content"`
|
||||
TokenCount int `json:"tokenCount"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
}
|
||||
|
||||
// ConversationListResponse 对话列表响应
|
||||
type ConversationListResponse struct {
|
||||
List []ConversationListItemResponse `json:"list"`
|
||||
Total int64 `json:"total"`
|
||||
Page int `json:"page"`
|
||||
PageSize int `json:"pageSize"`
|
||||
}
|
||||
|
||||
// MessageListResponse 消息列表响应
|
||||
type MessageListResponse struct {
|
||||
List []MessageResponse `json:"list"`
|
||||
Total int64 `json:"total"`
|
||||
Page int `json:"page"`
|
||||
PageSize int `json:"pageSize"`
|
||||
}
|
||||
|
||||
// ToConversationResponse 转换为对话响应结构
|
||||
func ToConversationResponse(conv *app.Conversation) ConversationResponse {
|
||||
// 解析 settings JSON
|
||||
var settings map[string]interface{}
|
||||
if len(conv.Settings) > 0 {
|
||||
// 尝试解析 JSON,如果失败则返回 nil
|
||||
if err := json.Unmarshal(conv.Settings, &settings); err != nil {
|
||||
settings = nil
|
||||
}
|
||||
}
|
||||
|
||||
return ConversationResponse{
|
||||
ID: conv.ID,
|
||||
CharacterID: conv.CharacterID,
|
||||
Title: conv.Title,
|
||||
PresetID: conv.PresetID,
|
||||
AIProvider: conv.AIProvider,
|
||||
Model: conv.Model,
|
||||
Settings: settings,
|
||||
MessageCount: conv.MessageCount,
|
||||
TokenCount: conv.TokenCount,
|
||||
CreatedAt: conv.CreatedAt,
|
||||
UpdatedAt: conv.UpdatedAt,
|
||||
}
|
||||
}
|
||||
|
||||
// ToMessageResponse 转换为消息响应结构
|
||||
func ToMessageResponse(msg *app.Message) MessageResponse {
|
||||
return MessageResponse{
|
||||
ID: msg.ID,
|
||||
ConversationID: msg.ConversationID,
|
||||
Role: msg.Role,
|
||||
Content: msg.Content,
|
||||
TokenCount: msg.TokenCount,
|
||||
CreatedAt: msg.CreatedAt,
|
||||
}
|
||||
}
|
||||
|
||||
// ToConversationListItemResponse 转换为对话列表项响应结构(轻量级)
|
||||
func ToConversationListItemResponse(conv *app.Conversation, character *app.AICharacter) ConversationListItemResponse {
|
||||
resp := ConversationListItemResponse{
|
||||
ID: conv.ID,
|
||||
CharacterID: conv.CharacterID,
|
||||
Title: conv.Title,
|
||||
MessageCount: conv.MessageCount,
|
||||
TokenCount: conv.TokenCount,
|
||||
CreatedAt: conv.CreatedAt,
|
||||
UpdatedAt: conv.UpdatedAt,
|
||||
}
|
||||
|
||||
if character != nil {
|
||||
simpleChar := ToCharacterSimpleResponse(character)
|
||||
resp.Character = &simpleChar
|
||||
}
|
||||
|
||||
return resp
|
||||
}
|
||||
78
server/model/app/response/preset.go
Normal file
78
server/model/app/response/preset.go
Normal file
@@ -0,0 +1,78 @@
|
||||
package response
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"time"
|
||||
|
||||
"git.echol.cn/loser/st/server/model/app"
|
||||
)
|
||||
|
||||
// PresetResponse 预设响应
|
||||
type PresetResponse struct {
|
||||
ID uint `json:"id"`
|
||||
UserID uint `json:"userId"`
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
IsPublic bool `json:"isPublic"`
|
||||
IsDefault bool `json:"isDefault"`
|
||||
Temperature float64 `json:"temperature"`
|
||||
TopP float64 `json:"topP"`
|
||||
TopK int `json:"topK"`
|
||||
FrequencyPenalty float64 `json:"frequencyPenalty"`
|
||||
PresencePenalty float64 `json:"presencePenalty"`
|
||||
MaxTokens int `json:"maxTokens"`
|
||||
RepetitionPenalty float64 `json:"repetitionPenalty"`
|
||||
MinP float64 `json:"minP"`
|
||||
TopA float64 `json:"topA"`
|
||||
SystemPrompt string `json:"systemPrompt"`
|
||||
StopSequences []string `json:"stopSequences"`
|
||||
Extensions map[string]interface{} `json:"extensions"`
|
||||
UseCount int `json:"useCount"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
UpdatedAt time.Time `json:"updatedAt"`
|
||||
}
|
||||
|
||||
// PresetListResponse 预设列表响应
|
||||
type PresetListResponse struct {
|
||||
List []PresetResponse `json:"list"`
|
||||
Total int64 `json:"total"`
|
||||
Page int `json:"page"`
|
||||
PageSize int `json:"pageSize"`
|
||||
}
|
||||
|
||||
// ToPresetResponse 转换为预设响应结构
|
||||
func ToPresetResponse(preset *app.AIPreset) PresetResponse {
|
||||
var stopSequences []string
|
||||
if len(preset.StopSequences) > 0 {
|
||||
json.Unmarshal(preset.StopSequences, &stopSequences)
|
||||
}
|
||||
|
||||
var extensions map[string]interface{}
|
||||
if len(preset.Extensions) > 0 {
|
||||
json.Unmarshal(preset.Extensions, &extensions)
|
||||
}
|
||||
|
||||
return PresetResponse{
|
||||
ID: preset.ID,
|
||||
UserID: preset.UserID,
|
||||
Name: preset.Name,
|
||||
Description: preset.Description,
|
||||
IsPublic: preset.IsPublic,
|
||||
IsDefault: preset.IsDefault,
|
||||
Temperature: preset.Temperature,
|
||||
TopP: preset.TopP,
|
||||
TopK: preset.TopK,
|
||||
FrequencyPenalty: preset.FrequencyPenalty,
|
||||
PresencePenalty: preset.PresencePenalty,
|
||||
MaxTokens: preset.MaxTokens,
|
||||
RepetitionPenalty: preset.RepetitionPenalty,
|
||||
MinP: preset.MinP,
|
||||
TopA: preset.TopA,
|
||||
SystemPrompt: preset.SystemPrompt,
|
||||
StopSequences: stopSequences,
|
||||
Extensions: extensions,
|
||||
UseCount: preset.UseCount,
|
||||
CreatedAt: preset.CreatedAt,
|
||||
UpdatedAt: preset.UpdatedAt,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user