feat: add WeCom outbox management features including retry and ignore actions, permissions, and UI integration

This commit is contained in:
mlogclub
2026-08-02 14:03:23 +08:00
parent c69b30a659
commit 1d6c0e37db
16 changed files with 457 additions and 1 deletions
+9 -1
View File
@@ -103,6 +103,10 @@ var (
PermissionChannelUpdate = Permission{Name: "更新接入渠道", Code: "channel.update", Type: "api", GroupName: "channel", Method: "POST", APIPath: "/api/dashboard/channel/update", SortNo: 627}
PermissionChannelDelete = Permission{Name: "删除接入渠道", Code: "channel.delete", Type: "api", GroupName: "channel", Method: "POST", APIPath: "/api/dashboard/channel/delete", SortNo: 628}
// 企微 Outbox 相关权限
PermissionWxWorkOutboxView = Permission{Name: "查看企微 Outbox", Code: "wxworkOutbox.view", Type: "api", GroupName: "wxworkOutbox", Method: "ANY", APIPath: "/api/dashboard/channel/wxwork/outbox/failed/list", SortNo: 629}
PermissionWxWorkOutboxUpdate = Permission{Name: "处置企微 Outbox", Code: "wxworkOutbox.update", Type: "api", GroupName: "wxworkOutbox", Method: "POST", APIPath: "/api/dashboard/channel/wxwork/outbox/retry", SortNo: 630}
// 客户相关权限
PermissionCustomerView = Permission{Name: "查看客户", Code: "customer.view", Type: "api", GroupName: "customer", Method: "POST", APIPath: "/api/dashboard/customer/list", SortNo: 630}
PermissionCustomerCreate = Permission{Name: "创建客户", Code: "customer.create", Type: "api", GroupName: "customer", Method: "POST", APIPath: "/api/dashboard/customer/create", SortNo: 640}
@@ -223,6 +227,8 @@ var Permissions = []Permission{
PermissionChannelCreate,
PermissionChannelUpdate,
PermissionChannelDelete,
PermissionWxWorkOutboxView,
PermissionWxWorkOutboxUpdate,
PermissionCustomerView,
PermissionCustomerCreate,
PermissionCustomerUpdate,
@@ -355,6 +361,7 @@ var builtinPermissionResourceLabels = map[string]string{
"tag": "tags",
"company": "companies",
"channel": "channels",
"wxworkOutbox": "WeCom outbox records",
"customer": "customers",
"agent": "agents",
"agentTeam": "agent teams",
@@ -379,6 +386,7 @@ var builtinPermissionNameOverrides = map[string]string{
"ticket.progress": "Update ticket progress",
"agent.config": "Configure agent service rules",
"agentTeamSchedule.batchGenerate": "Batch generate agent team schedules",
"wxworkOutbox.update": "Handle WeCom outbox records",
"mcp.view": "View MCP debug information",
"mcp.call": "Call MCP tools",
}
@@ -409,7 +417,7 @@ var RolePermissions = map[string][]Permission{
PermissionQuickReplyView, PermissionQuickReplyCreate, PermissionQuickReplyUpdate, PermissionQuickReplyDelete,
PermissionTagView, PermissionTagCreate, PermissionTagUpdate, PermissionTagDelete,
PermissionCompanyView, PermissionCompanyCreate, PermissionCompanyUpdate, PermissionCompanyDelete,
PermissionChannelView, PermissionChannelCreate, PermissionChannelUpdate, PermissionChannelDelete,
PermissionChannelView, PermissionChannelCreate, PermissionChannelUpdate, PermissionChannelDelete, PermissionWxWorkOutboxView, PermissionWxWorkOutboxUpdate,
PermissionCustomerView, PermissionCustomerCreate, PermissionCustomerUpdate, PermissionCustomerDelete,
PermissionAgentView, PermissionAgentCreate, PermissionAgentUpdate, PermissionAgentDelete, PermissionAgentUpdateStatus, PermissionAgentConfig,
PermissionAgentTeamView, PermissionAgentTeamCreate, PermissionAgentTeamUpdate, PermissionAgentTeamDelete,
+1
View File
@@ -36,6 +36,7 @@ func TestBuiltinAuthSeedNamesDefaultToEnglish(t *testing.T) {
"ticket.create": "Create tickets",
"conversation.send": "Send conversation messages",
"channel.view": "View channels",
"wxworkOutbox.view": "View WeCom outbox records",
"agent.view": "View agents",
}
for code, want := range permissionTests {
@@ -31,3 +31,7 @@ type DeleteChannelRequest struct {
type ResetChannelUserTokenSecretRequest struct {
ID int64 `json:"id"`
}
type ChannelMessageOutboxActionRequest struct {
ID int64 `json:"id"`
}
@@ -3,6 +3,7 @@ package response
import (
"agent-desk/internal/models"
"agent-desk/internal/pkg/enums"
"agent-desk/internal/pkg/utils"
)
type ChannelResponse struct {
@@ -26,6 +27,23 @@ type WxWorkKFAccountResponse struct {
ManagePrivilege bool `json:"managePrivilege"`
}
type ChannelMessageOutboxResponse struct {
ID int64 `json:"id"`
ChannelType string `json:"channelType"`
ConversationID int64 `json:"conversationId"`
MessageID int64 `json:"messageId"`
Payload string `json:"payload"`
SendStatus string `json:"sendStatus"`
RetryCount int `json:"retryCount"`
NextRetryAt string `json:"nextRetryAt"`
LastError string `json:"lastError"`
SentAt string `json:"sentAt"`
CreatedAt string `json:"createdAt"`
UpdatedAt string `json:"updatedAt"`
CreateUserName string `json:"createUserName"`
UpdateUserName string `json:"updateUserName"`
}
func BuildChannelResponse(item *models.Channel) ChannelResponse {
if item == nil {
return ChannelResponse{}
@@ -43,3 +61,25 @@ func BuildChannelResponse(item *models.Channel) ChannelResponse {
Remark: item.Remark,
}
}
func BuildChannelMessageOutboxResponse(item *models.ChannelMessageOutbox) ChannelMessageOutboxResponse {
if item == nil {
return ChannelMessageOutboxResponse{}
}
return ChannelMessageOutboxResponse{
ID: item.ID,
ChannelType: item.ChannelType,
ConversationID: item.ConversationID,
MessageID: item.MessageID,
Payload: item.Payload,
SendStatus: item.SendStatus,
RetryCount: item.RetryCount,
NextRetryAt: utils.FormatTimePtr(item.NextRetryAt),
LastError: item.LastError,
SentAt: utils.FormatTimePtr(item.SentAt),
CreatedAt: utils.FormatTime(item.CreatedAt),
UpdatedAt: utils.FormatTime(item.UpdatedAt),
CreateUserName: item.CreateUserName,
UpdateUserName: item.UpdateUserName,
}
}
+1
View File
@@ -14,6 +14,7 @@ const (
ChannelMessageOutboxStatusSending ChannelMessageOutboxStatus = "sending"
ChannelMessageOutboxStatusSent ChannelMessageOutboxStatus = "sent"
ChannelMessageOutboxStatusFailed ChannelMessageOutboxStatus = "failed"
ChannelMessageOutboxStatusIgnored ChannelMessageOutboxStatus = "ignored"
)
const (