Compare commits

...

2 Commits

Author SHA1 Message Date
coltea 9eee8b72a2 feat widget setting 2025-11-04 17:21:59 +08:00
coltea f72966e13a feat: node release user info 2025-11-04 14:07:00 +08:00
14 changed files with 86 additions and 28 deletions

View File

@ -7379,6 +7379,18 @@ const docTemplate = `{
"is_open": { "is_open": {
"type": "boolean" "type": "boolean"
}, },
"recommend_node_ids": {
"type": "array",
"items": {
"type": "string"
}
},
"recommend_questions": {
"type": "array",
"items": {
"type": "string"
}
},
"theme_mode": { "theme_mode": {
"type": "string" "type": "string"
} }

View File

@ -7372,6 +7372,18 @@
"is_open": { "is_open": {
"type": "boolean" "type": "boolean"
}, },
"recommend_node_ids": {
"type": "array",
"items": {
"type": "string"
}
},
"recommend_questions": {
"type": "array",
"items": {
"type": "string"
}
},
"theme_mode": { "theme_mode": {
"type": "string" "type": "string"
} }

View File

@ -2407,6 +2407,14 @@ definitions:
type: string type: string
is_open: is_open:
type: boolean type: boolean
recommend_node_ids:
items:
type: string
type: array
recommend_questions:
items:
type: string
type: array
theme_mode: theme_mode:
type: string type: string
type: object type: object

View File

@ -380,10 +380,12 @@ type FooterSettings struct {
} }
type WidgetBotSettings struct { type WidgetBotSettings struct {
IsOpen bool `json:"is_open,omitempty"` IsOpen bool `json:"is_open,omitempty"`
ThemeMode string `json:"theme_mode,omitempty"` ThemeMode string `json:"theme_mode,omitempty"`
BtnText string `json:"btn_text,omitempty"` BtnText string `json:"btn_text,omitempty"`
BtnLogo string `json:"btn_logo,omitempty"` BtnLogo string `json:"btn_logo,omitempty"`
RecommendQuestions []string `json:"recommend_questions,omitempty"`
RecommendNodeIDs []string `json:"recommend_node_ids,omitempty"`
} }
type BrandGroup struct { type BrandGroup struct {

View File

@ -129,6 +129,10 @@ type KBReleaseNodeRelease struct {
CreatedAt time.Time `json:"created_at"` CreatedAt time.Time `json:"created_at"`
} }
func (KBReleaseNodeRelease) TableName() string {
return "kb_release_node_releases"
}
type CreateKBReleaseReq struct { type CreateKBReleaseReq struct {
KBID string `json:"kb_id" validate:"required"` KBID string `json:"kb_id" validate:"required"`
Message string `json:"message" validate:"required"` Message string `json:"message" validate:"required"`

View File

@ -279,10 +279,12 @@ type GetRecommendNodeListReq struct {
// table: node_releases // table: node_releases
type NodeRelease struct { type NodeRelease struct {
ID string `json:"id" gorm:"primaryKey"` ID string `json:"id" gorm:"primaryKey"`
KBID string `json:"kb_id" gorm:"index"` KBID string `json:"kb_id" gorm:"index"`
NodeID string `json:"node_id" gorm:"index"` PublisherId string `json:"publisher_id"`
DocID string `json:"doc_id" gorm:"index"` // for rag service EditorId string `json:"editor_id"`
NodeID string `json:"node_id" gorm:"index"`
DocID string `json:"doc_id" gorm:"index"` // for rag service
Type NodeType `json:"type"` Type NodeType `json:"type"`
@ -312,3 +314,9 @@ type BatchMoveReq struct {
KBID string `json:"kb_id" validate:"required"` KBID string `json:"kb_id" validate:"required"`
ParentID string `json:"parent_id"` ParentID string `json:"parent_id"`
} }
type NodeCreateInfo struct {
ID string `json:"id"`
Account string `json:"account"`
CreatorId string `json:"creator_id"`
}

View File

@ -244,6 +244,12 @@ func (h *KnowledgeBaseHandler) DeleteKnowledgeBase(c echo.Context) error {
// @Success 200 {object} domain.Response // @Success 200 {object} domain.Response
// @Router /api/v1/knowledge_base/release [post] // @Router /api/v1/knowledge_base/release [post]
func (h *KnowledgeBaseHandler) CreateKBRelease(c echo.Context) error { func (h *KnowledgeBaseHandler) CreateKBRelease(c echo.Context) error {
ctx := c.Request().Context()
authInfo := domain.GetAuthInfoFromCtx(ctx)
if authInfo == nil {
return h.NewResponseWithError(c, "authInfo not found in context", nil)
}
req := &domain.CreateKBReleaseReq{} req := &domain.CreateKBReleaseReq{}
if err := c.Bind(req); err != nil { if err := c.Bind(req); err != nil {
return h.NewResponseWithError(c, "request body is invalid", err) return h.NewResponseWithError(c, "request body is invalid", err)
@ -252,7 +258,7 @@ func (h *KnowledgeBaseHandler) CreateKBRelease(c echo.Context) error {
return h.NewResponseWithError(c, "validate request body failed", err) return h.NewResponseWithError(c, "validate request body failed", err)
} }
id, err := h.usecase.CreateKBRelease(c.Request().Context(), req) id, err := h.usecase.CreateKBRelease(ctx, req, authInfo.UserId)
if err != nil { if err != nil {
return h.NewResponseWithError(c, "create kb release failed", err) return h.NewResponseWithError(c, "create kb release failed", err)
} }

View File

@ -53,7 +53,7 @@ func (m *MigrationNodeVersion) Execute(tx *gorm.DB) error {
Message: "release all old nodes", Message: "release all old nodes",
Tag: "init", Tag: "init",
NodeIDs: nodeIDs, NodeIDs: nodeIDs,
}) }, "")
if err != nil { if err != nil {
return fmt.Errorf("create kb release failed: %w", err) return fmt.Errorf("create kb release failed: %w", err)
} }

@ -1 +1 @@
Subproject commit e7bf0a030242425c83291b369770c113fd503a5a Subproject commit 9c899db37070ea801d74370ef7e01853c5c5fde9

View File

@ -810,7 +810,7 @@ func (r *NodeRepository) TraverseNodesByCursor(ctx context.Context, callback fun
} }
// CreateNodeReleases create node releases // CreateNodeReleases create node releases
func (r *NodeRepository) CreateNodeReleases(ctx context.Context, kbID string, nodeIDs []string) ([]string, error) { func (r *NodeRepository) CreateNodeReleases(ctx context.Context, kbID, userId string, nodeIDs []string) ([]string, error) {
releaseIDs := make([]string, 0) releaseIDs := make([]string, 0)
if err := r.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error { if err := r.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
// update node status to published and return node ids // update node status to published and return node ids
@ -829,17 +829,19 @@ func (r *NodeRepository) CreateNodeReleases(ctx context.Context, kbID string, no
for i, updatedNode := range updatedNodes { for i, updatedNode := range updatedNodes {
// create node release // create node release
nodeRelease := &domain.NodeRelease{ nodeRelease := &domain.NodeRelease{
ID: uuid.New().String(), ID: uuid.New().String(),
KBID: kbID, KBID: kbID,
NodeID: updatedNode.ID, PublisherId: userId,
Type: updatedNode.Type, EditorId: updatedNode.EditorId,
Name: updatedNode.Name, NodeID: updatedNode.ID,
Meta: updatedNode.Meta, Type: updatedNode.Type,
Content: updatedNode.Content, Name: updatedNode.Name,
ParentID: updatedNode.ParentID, Meta: updatedNode.Meta,
Position: updatedNode.Position, Content: updatedNode.Content,
CreatedAt: updatedNode.CreatedAt, ParentID: updatedNode.ParentID,
UpdatedAt: time.Now(), Position: updatedNode.Position,
CreatedAt: updatedNode.CreatedAt,
UpdatedAt: time.Now(),
} }
nodeReleases[i] = nodeRelease nodeReleases[i] = nodeRelease
releaseIDs = append(releaseIDs, nodeRelease.ID) releaseIDs = append(releaseIDs, nodeRelease.ID)

View File

@ -0,0 +1,2 @@
ALTER TABLE node_releases DROP COLUMN IF EXISTS publisher_id;
ALTER TABLE node_releases DROP COLUMN IF EXISTS editor_id;

View File

@ -0,0 +1,2 @@
ALTER TABLE node_releases ADD COLUMN IF NOT EXISTS publisher_id text default '';
ALTER TABLE node_releases ADD COLUMN IF NOT EXISTS editor_id text default '';

View File

@ -642,14 +642,14 @@ func (u *AppUsecase) GetWidgetAppInfo(ctx context.Context, kbID string) (*domain
Icon: webApp.Settings.Icon, Icon: webApp.Settings.Icon,
WelcomeStr: webApp.Settings.WelcomeStr, WelcomeStr: webApp.Settings.WelcomeStr,
SearchPlaceholder: webApp.Settings.SearchPlaceholder, SearchPlaceholder: webApp.Settings.SearchPlaceholder,
RecommendQuestions: webApp.Settings.RecommendQuestions, RecommendQuestions: widgetApp.Settings.WidgetBotSettings.RecommendQuestions,
WidgetBotSettings: widgetApp.Settings.WidgetBotSettings, WidgetBotSettings: widgetApp.Settings.WidgetBotSettings,
}, },
} }
if len(webApp.Settings.RecommendNodeIDs) > 0 { if len(widgetApp.Settings.WidgetBotSettings.RecommendNodeIDs) > 0 {
nodes, err := u.nodeUsecase.GetRecommendNodeList(ctx, &domain.GetRecommendNodeListReq{ nodes, err := u.nodeUsecase.GetRecommendNodeList(ctx, &domain.GetRecommendNodeListReq{
KBID: kbID, KBID: kbID,
NodeIDs: webApp.Settings.RecommendNodeIDs, NodeIDs: widgetApp.Settings.WidgetBotSettings.RecommendNodeIDs,
}) })
if err != nil { if err != nil {
return nil, err return nil, err

View File

@ -146,10 +146,10 @@ func (u *KnowledgeBaseUsecase) DeleteKnowledgeBase(ctx context.Context, kbID str
return nil return nil
} }
func (u *KnowledgeBaseUsecase) CreateKBRelease(ctx context.Context, req *domain.CreateKBReleaseReq) (string, error) { func (u *KnowledgeBaseUsecase) CreateKBRelease(ctx context.Context, req *domain.CreateKBReleaseReq, userId string) (string, error) {
if len(req.NodeIDs) > 0 { if len(req.NodeIDs) > 0 {
// create published nodes // create published nodes
releaseIDs, err := u.nodeRepo.CreateNodeReleases(ctx, req.KBID, req.NodeIDs) releaseIDs, err := u.nodeRepo.CreateNodeReleases(ctx, req.KBID, userId, req.NodeIDs)
if err != nil { if err != nil {
return "", fmt.Errorf("failed to create published nodes: %w", err) return "", fmt.Errorf("failed to create published nodes: %w", err)
} }