feat: 人物编辑弹窗改为CKB计划选择下拉框
- 新增 GET /api/admin/ckb/plans 获取存客宝获客计划列表 - 新增 GET /api/admin/ckb/plan-detail 获取计划详情 - PersonAddEditModal: 密钥字段改为可搜索的计划选择器 选择计划后自动覆盖 greeting/tips/设备/时间等参数 - 删除"修复 CKB 密钥"按钮 Made-with: Cursor
This commit is contained in:
@@ -306,3 +306,117 @@ func AdminCKBDevices(c *gin.Context) {
|
||||
})
|
||||
}
|
||||
|
||||
// AdminCKBPlans GET /api/admin/ckb/plans 管理端-存客宝获客计划列表
|
||||
func AdminCKBPlans(c *gin.Context) {
|
||||
token, err := ckbOpenGetToken()
|
||||
if err != nil {
|
||||
c.JSON(http.StatusOK, gin.H{"success": false, "error": err.Error()})
|
||||
return
|
||||
}
|
||||
pageStr := c.DefaultQuery("page", "1")
|
||||
limitStr := c.DefaultQuery("limit", "50")
|
||||
keyword := c.Query("keyword")
|
||||
|
||||
values := url.Values{}
|
||||
values.Set("page", pageStr)
|
||||
values.Set("limit", limitStr)
|
||||
if keyword != "" {
|
||||
values.Set("keyword", keyword)
|
||||
}
|
||||
planURL := ckbOpenBaseURL + "/v1/plans?" + values.Encode()
|
||||
req, err := http.NewRequest(http.MethodGet, planURL, nil)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusOK, gin.H{"success": false, "error": "构造请求失败"})
|
||||
return
|
||||
}
|
||||
req.Header.Set("Authorization", "Bearer "+token)
|
||||
resp, err := http.DefaultClient.Do(req)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusOK, gin.H{"success": false, "error": "请求存客宝计划列表失败"})
|
||||
return
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
b, _ := io.ReadAll(resp.Body)
|
||||
|
||||
var parsed map[string]interface{}
|
||||
if err := json.Unmarshal(b, &parsed); err != nil {
|
||||
c.JSON(http.StatusOK, gin.H{"success": false, "error": "解析计划列表失败"})
|
||||
return
|
||||
}
|
||||
|
||||
var listAny interface{}
|
||||
if dataVal, ok := parsed["data"].(map[string]interface{}); ok {
|
||||
listAny = dataVal["list"]
|
||||
if _, ok := parsed["total"]; !ok {
|
||||
if tv, ok := dataVal["total"]; ok {
|
||||
parsed["total"] = tv
|
||||
}
|
||||
}
|
||||
} else if la, ok := parsed["list"]; ok {
|
||||
listAny = la
|
||||
}
|
||||
|
||||
plans := make([]map[string]interface{}, 0)
|
||||
if arr, ok := listAny.([]interface{}); ok {
|
||||
for _, item := range arr {
|
||||
if m, ok := item.(map[string]interface{}); ok {
|
||||
plans = append(plans, map[string]interface{}{
|
||||
"id": m["id"],
|
||||
"name": m["name"],
|
||||
"apiKey": m["apiKey"],
|
||||
"sceneId": m["sceneId"],
|
||||
"scenario": m["scenario"],
|
||||
"enabled": m["enabled"],
|
||||
"greeting": m["greeting"],
|
||||
"tips": m["tips"],
|
||||
"remarkType": m["remarkType"],
|
||||
"remarkFormat": m["remarkFormat"],
|
||||
"addInterval": m["addInterval"],
|
||||
"startTime": m["startTime"],
|
||||
"endTime": m["endTime"],
|
||||
"deviceGroups": m["deviceGroups"],
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
total := 0
|
||||
switch tv := parsed["total"].(type) {
|
||||
case float64:
|
||||
total = int(tv)
|
||||
case int:
|
||||
total = tv
|
||||
case string:
|
||||
if n, err := strconv.Atoi(tv); err == nil {
|
||||
total = n
|
||||
}
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{"success": true, "plans": plans, "total": total})
|
||||
}
|
||||
|
||||
// AdminCKBPlanDetail GET /api/admin/ckb/plan-detail?planId=xxx 管理端-存客宝获客计划详情
|
||||
func AdminCKBPlanDetail(c *gin.Context) {
|
||||
planIDStr := c.Query("planId")
|
||||
if planIDStr == "" {
|
||||
c.JSON(http.StatusOK, gin.H{"success": false, "error": "缺少 planId"})
|
||||
return
|
||||
}
|
||||
planID, _ := strconv.ParseInt(planIDStr, 10, 64)
|
||||
if planID <= 0 {
|
||||
c.JSON(http.StatusOK, gin.H{"success": false, "error": "planId 无效"})
|
||||
return
|
||||
}
|
||||
token, err := ckbOpenGetToken()
|
||||
if err != nil {
|
||||
c.JSON(http.StatusOK, gin.H{"success": false, "error": err.Error()})
|
||||
return
|
||||
}
|
||||
apiKey, err := ckbOpenGetPlanDetail(token, planID)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusOK, gin.H{"success": false, "error": err.Error()})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, gin.H{"success": true, "apiKey": apiKey})
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user