package main import ( "encoding/json" "net/http" ) func registerAfterSalesRoutes(router *http.ServeMux) { router.HandleFunc("/api/after-sales/issues", handleAfterSalesIssues) router.HandleFunc("/api/after-sales/issues/save", handleAfterSalesSaveIssue) router.HandleFunc("/api/after-sales/issues/resolve", handleAfterSalesResolveIssue) router.HandleFunc("/api/after-sales/issues/delete", handleAfterSalesDeleteIssue) router.HandleFunc("/api/after-sales/collect", handleAfterSalesCollect) router.HandleFunc("/api/after-sales/import-history", handleAfterSalesImportHistory) router.HandleFunc("/api/after-sales/status", handleAfterSalesStatus) router.HandleFunc("/api/after-sales/auto-collect", handleAfterSalesAutoCollect) router.HandleFunc("/api/after-sales/knowledge/cases", handleAfterSalesKnowledgeCases) router.HandleFunc("/api/after-sales/knowledge/cases/update", handleAfterSalesKnowledgeCaseUpdate) router.HandleFunc("/api/after-sales/knowledge/cases/reveal", handleAfterSalesKnowledgeCaseReveal) router.HandleFunc("/api/after-sales/dispatch/config", handleAfterSalesDispatchConfig) router.HandleFunc("/api/after-sales/dispatch/queue", handleAfterSalesDispatchQueue) router.HandleFunc("/api/after-sales/dispatch/assign", handleAfterSalesDispatchAssign) router.HandleFunc("/api/after-sales/dispatch/notify", handleAfterSalesDispatchNotify) router.HandleFunc("/api/after-sales/dispatch/batch-notify", handleAfterSalesDispatchBatchNotify) } func handleAfterSalesIssues(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodGet { http.Error(w, "method not allowed", http.StatusMethodNotAllowed) return } sendJSONResponse(w, http.StatusOK, map[string]interface{}{ "success": true, "message": "ok", "data": getAfterSalesIssueEngine().snapshotIssues(), }) } func handleAfterSalesStatus(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodGet { http.Error(w, "method not allowed", http.StatusMethodNotAllowed) return } sendJSONResponse(w, http.StatusOK, map[string]interface{}{ "success": true, "message": "ok", "data": getAfterSalesIssueEngine().snapshotStatus(), }) } func handleAfterSalesSaveIssue(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { http.Error(w, "method not allowed", http.StatusMethodNotAllowed) return } var issue AfterSalesIssue if err := json.NewDecoder(r.Body).Decode(&issue); err != nil { sendJSONResponse(w, http.StatusBadRequest, map[string]interface{}{"success": false, "message": err.Error()}) return } if err := getAfterSalesIssueEngine().saveIssue(issue); err != nil { sendJSONResponse(w, http.StatusInternalServerError, map[string]interface{}{"success": false, "message": err.Error()}) return } sendJSONResponse(w, http.StatusOK, map[string]interface{}{"success": true, "message": "saved"}) } func handleAfterSalesResolveIssue(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { http.Error(w, "method not allowed", http.StatusMethodNotAllowed) return } var payload struct { IssueID string `json:"issueId"` ResolutionContent string `json:"resolutionContent"` } if err := json.NewDecoder(r.Body).Decode(&payload); err != nil { sendJSONResponse(w, http.StatusBadRequest, map[string]interface{}{"success": false, "message": err.Error()}) return } knowledgeCase, err := getAfterSalesIssueEngine().resolveIssue(payload.IssueID, payload.ResolutionContent) if err != nil { sendJSONResponse(w, http.StatusBadRequest, map[string]interface{}{"success": false, "message": err.Error()}) return } sendJSONResponse(w, http.StatusOK, map[string]interface{}{"success": true, "message": "已处理并保存到知识库", "data": knowledgeCase}) } func handleAfterSalesDeleteIssue(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { http.Error(w, "method not allowed", http.StatusMethodNotAllowed) return } var payload struct { ID string `json:"id"` } if err := json.NewDecoder(r.Body).Decode(&payload); err != nil { sendJSONResponse(w, http.StatusBadRequest, map[string]interface{}{"success": false, "message": err.Error()}) return } if !getAfterSalesIssueEngine().deleteIssue(payload.ID) { sendJSONResponse(w, http.StatusNotFound, map[string]interface{}{"success": false, "message": "问题不存在"}) return } sendJSONResponse(w, http.StatusOK, map[string]interface{}{"success": true, "message": "deleted"}) } func handleAfterSalesCollect(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { http.Error(w, "method not allowed", http.StatusMethodNotAllowed) return } var payload struct { ConversationID string `json:"conversationId"` } if r.Body != nil { _ = json.NewDecoder(r.Body).Decode(&payload) } ok, message := getAfterSalesIssueEngine().triggerCollectAsync(payload.ConversationID, true) status := http.StatusOK if !ok { status = http.StatusConflict } sendJSONResponse(w, status, map[string]interface{}{"success": ok, "message": message}) } func handleAfterSalesImportHistory(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { http.Error(w, "method not allowed", http.StatusMethodNotAllowed) return } var payload AfterSalesHistoryImportRequest if err := json.NewDecoder(r.Body).Decode(&payload); err != nil { sendJSONResponse(w, http.StatusBadRequest, map[string]interface{}{"success": false, "message": err.Error()}) return } result, err := getAfterSalesIssueEngine().importHistoryAndCollectDetailed(payload) if err != nil { sendJSONResponse(w, http.StatusBadRequest, map[string]interface{}{"success": false, "message": err.Error()}) return } sendJSONResponse(w, http.StatusOK, map[string]interface{}{ "success": true, "message": afterSalesHistoryImportMessage(result.Imported, result.Segments, result.Added), "data": map[string]interface{}{ "imported": result.Imported, "segments": result.Segments, "added": result.Added, "status": getAfterSalesIssueEngine().snapshotStatus(), }, }) } func handleAfterSalesAutoCollect(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { http.Error(w, "method not allowed", http.StatusMethodNotAllowed) return } var payload struct { Enabled bool `json:"enabled"` } if err := json.NewDecoder(r.Body).Decode(&payload); err != nil { sendJSONResponse(w, http.StatusBadRequest, map[string]interface{}{"success": false, "message": err.Error()}) return } if err := getAfterSalesIssueEngine().setAutoCollectEnabled(payload.Enabled); err != nil { sendJSONResponse(w, http.StatusInternalServerError, map[string]interface{}{"success": false, "message": err.Error()}) return } sendJSONResponse(w, http.StatusOK, map[string]interface{}{ "success": true, "message": "saved", "data": getAfterSalesIssueEngine().snapshotStatus(), }) } func handleAfterSalesKnowledgeCases(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodGet { http.Error(w, "method not allowed", http.StatusMethodNotAllowed) return } if err := getAfterSalesIssueEngine().syncResolvedKnowledgeCases(); err != nil { sendJSONResponse(w, http.StatusInternalServerError, map[string]interface{}{"success": false, "message": err.Error(), "data": []AfterSalesKnowledgeCase{}}) return } cases, err := listAfterSalesKnowledgeCases() if err != nil { sendJSONResponse(w, http.StatusInternalServerError, map[string]interface{}{"success": false, "message": err.Error(), "data": []AfterSalesKnowledgeCase{}}) return } sendJSONResponse(w, http.StatusOK, map[string]interface{}{"success": true, "message": "ok", "data": cases}) } func handleAfterSalesKnowledgeCaseUpdate(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { http.Error(w, "method not allowed", http.StatusMethodNotAllowed) return } var payload struct { IssueID string `json:"issueId"` ResolutionContent string `json:"resolutionContent"` } if err := json.NewDecoder(r.Body).Decode(&payload); err != nil { sendJSONResponse(w, http.StatusBadRequest, map[string]interface{}{"success": false, "message": err.Error()}) return } knowledgeCase, err := getAfterSalesIssueEngine().resolveIssue(payload.IssueID, payload.ResolutionContent) if err != nil { sendJSONResponse(w, http.StatusBadRequest, map[string]interface{}{"success": false, "message": err.Error()}) return } sendJSONResponse(w, http.StatusOK, map[string]interface{}{"success": true, "message": "知识案例已更新", "data": knowledgeCase}) } func handleAfterSalesKnowledgeCaseReveal(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { http.Error(w, "method not allowed", http.StatusMethodNotAllowed) return } var payload struct { IssueID string `json:"issueId"` } if err := json.NewDecoder(r.Body).Decode(&payload); err != nil { sendJSONResponse(w, http.StatusBadRequest, map[string]interface{}{"success": false, "message": err.Error()}) return } ok, message := revealAfterSalesKnowledgeCase(payload.IssueID) status := http.StatusOK if !ok { status = http.StatusBadRequest } sendJSONResponse(w, status, map[string]interface{}{"success": ok, "message": message}) } func handleAfterSalesDispatchConfig(w http.ResponseWriter, r *http.Request) { switch r.Method { case http.MethodGet: cfg, err := readAfterSalesDispatchConfig() if err != nil { sendJSONResponse(w, http.StatusInternalServerError, map[string]interface{}{"success": false, "message": err.Error()}) return } sendJSONResponse(w, http.StatusOK, map[string]interface{}{"success": true, "message": "ok", "data": cfg}) case http.MethodPost: var cfg AfterSalesDispatchConfig if err := json.NewDecoder(r.Body).Decode(&cfg); err != nil { sendJSONResponse(w, http.StatusBadRequest, map[string]interface{}{"success": false, "message": err.Error()}) return } if err := saveAfterSalesDispatchConfig(cfg); err != nil { sendJSONResponse(w, http.StatusInternalServerError, map[string]interface{}{"success": false, "message": err.Error()}) return } sendJSONResponse(w, http.StatusOK, map[string]interface{}{"success": true, "message": "saved"}) default: http.Error(w, "method not allowed", http.StatusMethodNotAllowed) } } func handleAfterSalesDispatchQueue(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodGet { http.Error(w, "method not allowed", http.StatusMethodNotAllowed) return } queue, err := getAfterSalesIssueEngine().dispatchQueue() if err != nil { sendJSONResponse(w, http.StatusInternalServerError, map[string]interface{}{"success": false, "message": err.Error()}) return } sendJSONResponse(w, http.StatusOK, map[string]interface{}{"success": true, "message": "ok", "data": queue}) } func handleAfterSalesDispatchAssign(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { http.Error(w, "method not allowed", http.StatusMethodNotAllowed) return } var payload struct { IssueID string `json:"issueId"` EngineerUserID string `json:"engineerUserId"` } if err := json.NewDecoder(r.Body).Decode(&payload); err != nil { sendJSONResponse(w, http.StatusBadRequest, map[string]interface{}{"success": false, "message": err.Error()}) return } if err := getAfterSalesIssueEngine().assignEngineer(payload.IssueID, payload.EngineerUserID); err != nil { sendJSONResponse(w, http.StatusBadRequest, map[string]interface{}{"success": false, "message": err.Error()}) return } sendJSONResponse(w, http.StatusOK, map[string]interface{}{"success": true, "message": "assigned"}) } func handleAfterSalesDispatchNotify(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { http.Error(w, "method not allowed", http.StatusMethodNotAllowed) return } var payload struct { IssueID string `json:"issueId"` } if err := json.NewDecoder(r.Body).Decode(&payload); err != nil { sendJSONResponse(w, http.StatusBadRequest, map[string]interface{}{"success": false, "message": err.Error()}) return } result := getAfterSalesIssueEngine().notifyEngineer(payload.IssueID) status := http.StatusOK if !result.Success { status = http.StatusBadRequest } sendJSONResponse(w, status, map[string]interface{}{"success": result.Success, "message": result.Message, "data": result}) } func handleAfterSalesDispatchBatchNotify(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { http.Error(w, "method not allowed", http.StatusMethodNotAllowed) return } var payload struct { IssueIDs []string `json:"issueIds"` } if err := json.NewDecoder(r.Body).Decode(&payload); err != nil { sendJSONResponse(w, http.StatusBadRequest, map[string]interface{}{"success": false, "message": err.Error()}) return } result := getAfterSalesIssueEngine().batchNotifyEngineers(payload.IssueIDs) sendJSONResponse(w, http.StatusOK, result) }