package handler import ( "bytes" "encoding/json" "fmt" "io" "net/http" "time" "gotest/internal/model" "github.com/gin-gonic/gin" "gorm.io/gorm" ) // CustomerHandler 客户信息收集处理器 type CustomerHandler struct { db *gorm.DB } // NewCustomerHandler 创建客户信息收集处理器 func NewCustomerHandler(db *gorm.DB) *CustomerHandler { return &CustomerHandler{db: db} } // CustomerRequest 客户信息请求 type CustomerRequest struct { Name string `json:"name" binding:"required"` Phone string `json:"phone" binding:"required"` Company string `json:"company"` Email string `json:"email"` Needs string `json:"needs" binding:"required"` } // Submit 提交客户信息 POST /api/v1/customer/submit func (h *CustomerHandler) Submit(c *gin.Context) { var req CustomerRequest if err := c.ShouldBindJSON(&req); err != nil { FailBadRequest(c, "请填写完整的联系信息") return } // 构建企业微信消息内容 content := fmt.Sprintf("【新客户咨询】\n"+ "━━━━━━━━━━━━━━━━━━━━\n"+ "👤 姓名:%s\n"+ "📱 电话:%s\n"+ "📧 邮箱:%s\n"+ "🏢 公司:%s\n"+ "💼 需求:%s\n"+ "⏰ 时间:%s\n"+ "━━━━━━━━━━━━━━━━━━━━", req.Name, req.Phone, req.Email, req.Company, req.Needs, time.Now().Format("2006-01-02 15:04:05")) // 发送到企业微信webhook if err := h.sendToWechatWebhook(content); err != nil { fmt.Printf("发送企业微信webhook失败: %v\n", err) } Success(c, gin.H{ "message": "提交成功,我们会尽快联系您!", }) } // getWebhookURL 从数据库获取webhook URL func (h *CustomerHandler) getWebhookURL() string { var cfg model.Config if err := h.db.Where("`key` = ?", "wechat_webhook_url").First(&cfg).Error; err == nil && cfg.Value != "" { return cfg.Value } return "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=71110fd5-9f51-4695-88dc-85ca34385d66" } // sendToWechatWebhook 发送消息到企业微信群机器人 func (h *CustomerHandler) sendToWechatWebhook(content string) error { webhookURL := h.getWebhookURL() message := map[string]interface{}{ "msgtype": "text", "text": map[string]string{ "content": content, }, } jsonData, err := json.Marshal(message) if err != nil { return fmt.Errorf("序列化消息失败: %w", err) } resp, err := http.Post(webhookURL, "application/json", bytes.NewBuffer(jsonData)) if err != nil { return fmt.Errorf("发送请求失败: %w", err) } defer resp.Body.Close() body, err := io.ReadAll(resp.Body) if err != nil { return fmt.Errorf("读取响应失败: %w", err) } if resp.StatusCode != http.StatusOK { return fmt.Errorf("请求失败,状态码: %d,响应: %s", resp.StatusCode, string(body)) } var result map[string]interface{} if err := json.Unmarshal(body, &result); err != nil { return fmt.Errorf("解析响应失败: %w", err) } if errcode, ok := result["errcode"].(float64); ok && errcode != 0 { errmsg, _ := result["errmsg"].(string) return fmt.Errorf("企业微信返回错误: %v - %s", errcode, errmsg) } return nil } // TestWebhook 测试webhook POST /api/v1/admin/webhook/test func (h *CustomerHandler) TestWebhook(c *gin.Context) { webhookURL := h.getWebhookURL() content := fmt.Sprintf("✅ Webhook 测试成功\n⏰ 时间:%s", time.Now().Format("2006-01-02 15:04:05")) message := map[string]interface{}{ "msgtype": "text", "text": map[string]string{ "content": content, }, } jsonData, err := json.Marshal(message) if err != nil { FailInternal(c, "序列化失败: "+err.Error()) return } resp, err := http.Post(webhookURL, "application/json", bytes.NewBuffer(jsonData)) if err != nil { FailInternal(c, "发送失败: "+err.Error()) return } defer resp.Body.Close() body, _ := io.ReadAll(resp.Body) var result map[string]interface{} json.Unmarshal(body, &result) if errcode, ok := result["errcode"].(float64); ok && errcode != 0 { errmsg, _ := result["errmsg"].(string) FailInternal(c, fmt.Sprintf("企业微信返回错误: %v - %s", errcode, errmsg)) return } SuccessMsg(c, "测试消息发送成功!请检查企业微信群") }