feat(documents): rebuild project document workbench

This commit is contained in:
2026-07-24 12:16:02 +08:00
parent 366136cee9
commit 77beaebb30
73 changed files with 5867 additions and 1264 deletions

View File

@@ -13,7 +13,7 @@ type workspaceCounts struct {
inbox int64
tasks int64
aiSessions int64
notesSources int64
documents int64
cronPlans int64
}
@@ -48,7 +48,7 @@ func (s *Service) Workspace(ownerID uint, projectIdentity string) (WorkspaceDTO,
if err != nil {
return WorkspaceDTO{}, err
}
notesSources, err := s.workspaceNotesSources(project.ID, project.Identity)
documents, err := s.workspaceDocuments(project.ID, project.Identity)
if err != nil {
return WorkspaceDTO{}, err
}
@@ -74,7 +74,7 @@ func (s *Service) Workspace(ownerID uint, projectIdentity string) (WorkspaceDTO,
Inbox: inboxItems,
Tasks: tasks,
AISessions: aiSessions,
NotesSources: notesSources,
Documents: documents,
CronPlans: cronPlans,
}, nil
}
@@ -90,15 +90,9 @@ func (s *Service) workspaceCounts(projectID uint) (workspaceCounts, error) {
if err := models.DBService.Model(&models.SaAISession{}).Where("project_id = ?", projectID).Count(&counts.aiSessions).Error; err != nil {
return counts, err
}
var noteCount int64
if err := models.DBService.Model(&models.SaNote{}).Where("project_id = ?", projectID).Count(&noteCount).Error; err != nil {
if err := models.DBService.Model(&models.SaDocument{}).Where("project_id = ?", projectID).Count(&counts.documents).Error; err != nil {
return counts, err
}
var sourceCount int64
if err := models.DBService.Model(&models.SaSource{}).Where("project_id = ?", projectID).Count(&sourceCount).Error; err != nil {
return counts, err
}
counts.notesSources = noteCount + sourceCount
if err := models.DBService.Model(&models.SaCronPlan{}).Where("project_id = ?", projectID).Count(&counts.cronPlans).Error; err != nil {
return counts, err
}
@@ -118,13 +112,13 @@ func (s *Service) workspaceTags(projectID uint) ([]WorkspaceTagDTO, error) {
}
func (s *Service) workspaceChannels(projectID uint, projectIdentity string, counts workspaceCounts) ([]WorkspaceChannelDTO, error) {
total := counts.inbox + counts.tasks + counts.aiSessions + counts.notesSources + counts.cronPlans
total := counts.inbox + counts.tasks + counts.aiSessions + counts.documents + counts.cronPlans
channels := []WorkspaceChannelDTO{
{ID: projectIdentity + ":overview", ProjectID: projectIdentity, Type: "overview", Title: "Overview", Icon: "home", Count: total, URL: "", SortOrder: 1},
{ID: projectIdentity + ":inbox", ProjectID: projectIdentity, Type: "inbox", Title: "Message Flow", Icon: "mail", Count: counts.inbox, URL: "", SortOrder: 2},
{ID: projectIdentity + ":tasks", ProjectID: projectIdentity, Type: "tasks", Title: "Work Plan", Icon: "list", Count: counts.tasks, URL: "", SortOrder: 3},
{ID: projectIdentity + ":ai", ProjectID: projectIdentity, Type: "ai_sessions", Title: "AI Sessions", Icon: "sparkles", Count: counts.aiSessions, URL: "", SortOrder: 4},
{ID: projectIdentity + ":notes", ProjectID: projectIdentity, Type: "notes_sources", Title: "Notes & Sources", Icon: "file", Count: counts.notesSources, URL: "", SortOrder: 5},
{ID: projectIdentity + ":documents", ProjectID: projectIdentity, Type: "documents", Title: "Documents", Icon: "file", Count: counts.documents, URL: "", SortOrder: 5},
{ID: projectIdentity + ":cron", ProjectID: projectIdentity, Type: "cron", Title: "Cron Plans", Icon: "clock", Count: counts.cronPlans, URL: "", SortOrder: 6},
}
var customChannels []models.SaProjectChannel
@@ -229,27 +223,16 @@ func (s *Service) workspaceAISessions(projectID uint, projectIdentity string) ([
return items, nil
}
func (s *Service) workspaceNotesSources(projectID uint, projectIdentity string) ([]WorkspaceNoteSourceDTO, error) {
var notes []models.SaNote
if err := models.DBService.Where("project_id = ?", projectID).Order("updated_at desc, id desc").Limit(50).Find(&notes).Error; err != nil {
func (s *Service) workspaceDocuments(projectID uint, projectIdentity string) ([]WorkspaceDocumentDTO, error) {
var documents []models.SaDocument
if err := models.DBService.Where("project_id = ?", projectID).Order("updated_at desc, id desc").Limit(50).Find(&documents).Error; err != nil {
return nil, err
}
items := make([]WorkspaceNoteSourceDTO, 0, len(notes))
for _, note := range notes {
items = append(items, WorkspaceNoteSourceDTO{
ID: note.Identity, ProjectID: projectIdentity, Kind: "note", Title: note.Title,
UpdatedAt: note.UpdatedAt.UTC(), Source: "Markdown",
})
}
var sources []models.SaSource
if err := models.DBService.Where("project_id = ?", projectID).Order("updated_at desc, id desc").Limit(50).Find(&sources).Error; err != nil {
return nil, err
}
for _, source := range sources {
items = append(items, WorkspaceNoteSourceDTO{
ID: source.Identity, ProjectID: projectIdentity, Kind: source.Kind, Title: source.Title,
UpdatedAt: source.UpdatedAt.UTC(), Source: sourceDisplayName(source),
items := make([]WorkspaceDocumentDTO, 0, len(documents))
for _, document := range documents {
items = append(items, WorkspaceDocumentDTO{
ID: document.Identity, ProjectID: projectIdentity, Kind: document.Kind, Name: document.Name,
Extension: document.Extension, MimeType: document.MimeType, UpdatedAt: document.UpdatedAt.UTC(),
})
}
return items, nil
@@ -283,17 +266,6 @@ func utcOptionalTime(value *time.Time) *time.Time {
return &utc
}
func sourceDisplayName(source models.SaSource) string {
switch source.Kind {
case "file":
return "Attachment"
case "link":
return "URL"
default:
return source.Kind
}
}
func userDisplayName(assigneeID *uint, createdBy uint) (string, error) {
userID := createdBy
if assigneeID != nil && *assigneeID != 0 {