feat(channel-monitor): apply template via subset picker; CC 2.1.114 baseline doc
Apply flow: - POST /admin/channel-monitor-templates/:id/apply now requires monitor_ids (non-empty array). Service applies the template only to the selected subset, gated by AND template_id = :id (so users can't sneak in unrelated monitor IDs). - New GET /admin/channel-monitor-templates/:id/monitors returns the associated monitor briefs (id/name/provider/enabled) for the picker. - ApplyToMonitors signature gains monitorIDs []int64; empty list returns ErrChannelMonitorTemplateApplyEmpty. Frontend: - New MonitorTemplateApplyPickerDialog.vue: list of associated monitors with checkboxes (default all checked), 全选 / 全不选 shortcuts, live selected/total count. Submit calls apply(id, ids). - MonitorTemplateManagerDialog replaces the old ConfirmDialog flow with the picker; onApplied refetches the list to refresh associated counts. i18n: applyPicker* + common.selectAll keys. chore: bump version to 0.1.114.33 The CC 2.1.114 (sdk-cli) UA / APIKeyBetaHeader / JSON metadata.user_id baseline (already verified working via the in-process apply on prod template id=1) is documented in internal/pkg/claude/constants.go and is what the seed template in the manager UI should follow.
This commit is contained in:
@@ -179,17 +179,56 @@ func (h *ChannelMonitorRequestTemplateHandler) Delete(c *gin.Context) {
|
||||
response.Success(c, nil)
|
||||
}
|
||||
|
||||
type channelMonitorTemplateApplyRequest struct {
|
||||
// MonitorIDs 必填、非空:用户在 picker 里勾选的要被覆盖的监控 ID 列表。
|
||||
// 仅当对应监控当前 template_id == :id 时才会真的被覆盖。
|
||||
MonitorIDs []int64 `json:"monitor_ids" binding:"required,min=1"`
|
||||
}
|
||||
|
||||
// Apply POST /api/v1/admin/channel-monitor-templates/:id/apply
|
||||
// 一键把模板当前配置覆盖到所有关联监控上。
|
||||
// 把模板当前配置覆盖到 monitor_ids 列表里的关联监控(picker 选中的子集)。
|
||||
func (h *ChannelMonitorRequestTemplateHandler) Apply(c *gin.Context) {
|
||||
id, ok := parseTemplateID(c)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
affected, err := h.templateService.ApplyToMonitors(c.Request.Context(), id)
|
||||
var req channelMonitorTemplateApplyRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
response.ErrorFrom(c, infraerrors.BadRequest("VALIDATION_ERROR", err.Error()))
|
||||
return
|
||||
}
|
||||
affected, err := h.templateService.ApplyToMonitors(c.Request.Context(), id, req.MonitorIDs)
|
||||
if err != nil {
|
||||
response.ErrorFrom(c, err)
|
||||
return
|
||||
}
|
||||
response.Success(c, gin.H{"affected": affected})
|
||||
}
|
||||
|
||||
type associatedMonitorBriefResponse struct {
|
||||
ID int64 `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Provider string `json:"provider"`
|
||||
Enabled bool `json:"enabled"`
|
||||
}
|
||||
|
||||
// AssociatedMonitors GET /api/v1/admin/channel-monitor-templates/:id/monitors
|
||||
// 列出关联监控(picker 弹窗用)。
|
||||
func (h *ChannelMonitorRequestTemplateHandler) AssociatedMonitors(c *gin.Context) {
|
||||
id, ok := parseTemplateID(c)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
items, err := h.templateService.ListAssociatedMonitors(c.Request.Context(), id)
|
||||
if err != nil {
|
||||
response.ErrorFrom(c, err)
|
||||
return
|
||||
}
|
||||
out := make([]associatedMonitorBriefResponse, 0, len(items))
|
||||
for _, m := range items {
|
||||
out = append(out, associatedMonitorBriefResponse{
|
||||
ID: m.ID, Name: m.Name, Provider: m.Provider, Enabled: m.Enabled,
|
||||
})
|
||||
}
|
||||
response.Success(c, gin.H{"items": out})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user