package handler import ( "net/http" "github.com/gin-gonic/gin" "kefu-sys/server/internal/middleware" "kefu-sys/server/internal/model" ) type CustomerHandler struct{} func NewCustomerHandler() *CustomerHandler { return &CustomerHandler{} } func canAccessCustomer(c *gin.Context, customerID uint) bool { if middleware.HasAnyRole(c, "admin", "supervisor") { return true } if middleware.GetRole(c) != "agent" { return false } var count int64 model.DB.Model(&model.Session{}). Where("tenant_id = ? AND customer_id = ? AND agent_id = ?", middleware.GetTenantID(c), customerID, middleware.GetUserID(c)). Count(&count) return count > 0 } func (h *CustomerHandler) List(c *gin.Context) { tenantID := middleware.GetTenantID(c) page, pageSize := middleware.GetPageParams(c) search := c.Query("search") status := c.Query("status") source := c.Query("source") var customers []model.Customer var total int64 query := model.DB.Where("tenant_id = ?", tenantID) if middleware.GetRole(c) == "agent" { assignedCustomers := model.DB.Model(&model.Session{}). Select("customer_id"). Where("tenant_id = ? AND agent_id = ?", tenantID, middleware.GetUserID(c)) query = query.Where("id IN (?)", assignedCustomers) } if search != "" { query = query.Where("name LIKE ? OR phone LIKE ? OR email LIKE ?", "%"+search+"%", "%"+search+"%", "%"+search+"%") } if status != "" { query = query.Where("status = ?", status) } if source != "" { query = query.Where("source = ?", source) } query.Model(&model.Customer{}).Count(&total) query.Order("updated_at desc").Offset((page - 1) * pageSize).Limit(pageSize).Find(&customers) middleware.JSONList(c, customers, total, page, pageSize) } func (h *CustomerHandler) Get(c *gin.Context) { tenantID := middleware.GetTenantID(c) id := c.Param("id") var customer model.Customer if err := model.DB.Where("id = ? AND tenant_id = ?", id, tenantID).First(&customer).Error; err != nil { c.JSON(http.StatusNotFound, gin.H{"code": 404, "message": "客户不存在"}) return } if !canAccessCustomer(c, customer.ID) { c.JSON(http.StatusForbidden, gin.H{"code": 403, "message": "无权查看该客户"}) return } var sessions []model.Session sessionQuery := model.DB.Where("customer_id = ? AND tenant_id = ?", customer.ID, tenantID) if middleware.GetRole(c) == "agent" { sessionQuery = sessionQuery.Where("agent_id = ?", middleware.GetUserID(c)) } sessionQuery.Order("created_at desc").Limit(20).Find(&sessions) middleware.JSON(c, gin.H{"customer": customer, "sessions": sessions}) } func (h *CustomerHandler) Create(c *gin.Context) { var customer model.Customer if err := c.ShouldBindJSON(&customer); err != nil { c.JSON(http.StatusBadRequest, gin.H{"code": 400, "message": "参数错误"}) return } customer.TenantID = middleware.GetTenantID(c) if err := model.DB.Create(&customer).Error; err != nil { c.JSON(http.StatusInternalServerError, gin.H{"code": 500, "message": "创建失败"}) return } middleware.JSON(c, customer) } func (h *CustomerHandler) Update(c *gin.Context) { tenantID := middleware.GetTenantID(c) id := c.Param("id") var customer model.Customer if err := model.DB.Where("id = ? AND tenant_id = ?", id, tenantID).First(&customer).Error; err != nil { c.JSON(http.StatusNotFound, gin.H{"code": 404, "message": "客户不存在"}) return } if !canAccessCustomer(c, customer.ID) { c.JSON(http.StatusForbidden, gin.H{"code": 403, "message": "无权编辑该客户"}) return } var updates map[string]interface{} if err := c.ShouldBindJSON(&updates); err != nil { c.JSON(http.StatusBadRequest, gin.H{"code": 400, "message": "参数错误"}) return } allowed := map[string]bool{"name": true, "phone": true, "email": true, "tags": true, "source": true, "status": true} for key := range updates { if !allowed[key] { delete(updates, key) } } if len(updates) == 0 { c.JSON(http.StatusBadRequest, gin.H{"code": 400, "message": "没有可更新字段"}) return } if err := model.DB.Model(&customer).Updates(updates).Error; err != nil { c.JSON(http.StatusInternalServerError, gin.H{"code": 500, "message": "更新失败"}) return } model.DB.First(&customer, customer.ID) middleware.JSON(c, customer) } func (h *CustomerHandler) Delete(c *gin.Context) { if !middleware.HasAnyRole(c, "admin", "supervisor") { c.JSON(http.StatusForbidden, gin.H{"code": 403, "message": "仅主管或管理员可删除客户"}) return } tenantID := middleware.GetTenantID(c) id := c.Param("id") result := model.DB.Where("id = ? AND tenant_id = ?", id, tenantID).Delete(&model.Customer{}) if result.RowsAffected == 0 { c.JSON(http.StatusNotFound, gin.H{"code": 404, "message": "客户不存在"}) return } middleware.JSON(c, gin.H{"message": "已删除"}) }