feat(desktop&tenant): Enhance desktop account and task consumer presence management
Desktop Client Build / Resolve Build Metadata (push) Successful in 1m13s
Desktop Client Build / Build Desktop Client (push) Has been cancelled
Desktop Client Build / Publish Client Artifacts to NAS (push) Has been cancelled
Backend CI / Backend (push) Failing after 13m49s
Frontend CI / Frontend (push) Successful in 6m38s

- Added new fields to DesktopAccountInfo for tracking account session and task consumer online status, along with queued publish task count and oldest queued publish task timestamp.
- Updated DesktopDispatchEvent to include server time for better synchronization.
- Implemented separate presence management for task consumers, including marking presence and loading presence state.
- Enhanced DesktopAccountService to apply publish queue summaries and manage task consumer presence.
- Introduced new methods for replaying queued publish tasks in DesktopDispatchHandler.
- Updated tests to cover new presence management logic and ensure correct behavior of account session and task consumer online status.
This commit is contained in:
2026-06-07 19:15:20 +08:00
parent 88c37e50b2
commit 67be43319e
15 changed files with 636 additions and 129 deletions
@@ -20,27 +20,28 @@ import (
// the existing SSE handler on the desktop client can treat both channels the
// same way and dedupe by task_id.
type DesktopDispatchEvent struct {
Type string `json:"type"`
TaskID string `json:"task_id"`
JobID string `json:"job_id,omitempty"`
WorkspaceID int64 `json:"workspace_id"`
TargetAccountID string `json:"target_account_id,omitempty"`
TargetClientID string `json:"target_client_id"`
Platform string `json:"platform,omitempty"`
Title *string `json:"title,omitempty"`
BusinessDate *string `json:"business_date,omitempty"`
SchedulerGroupKey *string `json:"scheduler_group_key,omitempty"`
QuestionText *string `json:"question_text,omitempty"`
Status string `json:"status"`
Kind string `json:"kind"`
Priority int `json:"priority,omitempty"`
Lane string `json:"lane,omitempty"`
InterruptGeneration int `json:"interrupt_generation,omitempty"`
SignalOnly bool `json:"signal_only,omitempty"`
Control string `json:"control,omitempty"`
Reason string `json:"reason,omitempty"`
ReplacementTaskID string `json:"replacement_task_id,omitempty"`
UpdatedAt time.Time `json:"updated_at"`
Type string `json:"type"`
TaskID string `json:"task_id"`
JobID string `json:"job_id,omitempty"`
WorkspaceID int64 `json:"workspace_id"`
TargetAccountID string `json:"target_account_id,omitempty"`
TargetClientID string `json:"target_client_id"`
Platform string `json:"platform,omitempty"`
Title *string `json:"title,omitempty"`
BusinessDate *string `json:"business_date,omitempty"`
SchedulerGroupKey *string `json:"scheduler_group_key,omitempty"`
QuestionText *string `json:"question_text,omitempty"`
Status string `json:"status"`
Kind string `json:"kind"`
Priority int `json:"priority,omitempty"`
Lane string `json:"lane,omitempty"`
InterruptGeneration int `json:"interrupt_generation,omitempty"`
SignalOnly bool `json:"signal_only,omitempty"`
Control string `json:"control,omitempty"`
Reason string `json:"reason,omitempty"`
ReplacementTaskID string `json:"replacement_task_id,omitempty"`
UpdatedAt time.Time `json:"updated_at"`
ServerTime *time.Time `json:"server_time,omitempty"`
}
// DispatchSubscriber represents a live WebSocket connection bound to a single
@@ -202,6 +202,16 @@ var routeDocs = map[string]routeDoc{
// --- Tenant:媒体 ---
"GET /api/tenant/media/platforms": {"媒体平台列表", "返回当前租户可用的媒体平台元数据(图标、能力开关等)。"},
// --- Tenant:企业站点发布 ---
"GET /api/tenant/enterprise-sites": {"企业站点列表", "查询当前 Workspace 已配置的企业官网/CMS 发布连接。"},
"POST /api/tenant/enterprise-sites": {"新增企业站点", "保存企业站点 CMS 连接配置和凭证,用于服务端直投文章。"},
"PATCH /api/tenant/enterprise-sites/:id": {"更新企业站点", "更新指定企业站点连接配置、状态或凭证。"},
"DELETE /api/tenant/enterprise-sites/:id": {"删除企业站点", "删除指定企业站点连接配置。"},
"POST /api/tenant/enterprise-sites/:id/ping": {"检测企业站点连接", "调用目标 CMS 探测接口,验证站点凭证和发布能力。"},
"GET /api/tenant/enterprise-sites/:id/categories": {"企业站点栏目列表", "读取已同步的企业站点栏目。"},
"POST /api/tenant/enterprise-sites/:id/categories/sync": {"同步企业站点栏目", "从目标 CMS 拉取栏目树并写入本地缓存。"},
"POST /api/tenant/enterprise-sites/:id/publish": {"发布文章到企业站点", "将指定文章内容直投到企业站点 CMS,并回写发布记录。"},
// --- Tenant:桌面客户端 ---
"GET /api/tenant/desktop-client/releases/downloadable": {"可下载桌面客户端版本", "返回当前租户可下载的已启用桌面客户端版本列表。"},