| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190 |
- package api
- import (
- "encoding/json"
- "fmt"
- "net/http"
- "strconv"
- "strings"
- "AI-Status-Light/internal/database"
- )
- type Server struct {
- db *database.DB
- server *http.Server
- }
- type Response struct {
- Code int `json:"code"`
- Message string `json:"message"`
- Data interface{} `json:"data,omitempty"`
- }
- func New(db *database.DB, addr string) *Server {
- s := &Server{db: db}
- mux := http.NewServeMux()
- mux.HandleFunc("/api/mqtt", s.handleMQTT)
- mux.HandleFunc("/api/mqtt/", s.handleMQTTByID)
- mux.HandleFunc("/api/health", s.handleHealth)
- s.server = &http.Server{
- Addr: addr,
- Handler: corsMiddleware(mux),
- }
- return s
- }
- func (s *Server) Start() error {
- return s.server.ListenAndServe()
- }
- func corsMiddleware(next http.Handler) http.Handler {
- return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- w.Header().Set("Access-Control-Allow-Origin", "*")
- w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
- w.Header().Set("Access-Control-Allow-Headers", "Content-Type")
- if r.Method == "OPTIONS" {
- w.WriteHeader(http.StatusOK)
- return
- }
- next.ServeHTTP(w, r)
- })
- }
- func (s *Server) handleHealth(w http.ResponseWriter, r *http.Request) {
- writeJSON(w, http.StatusOK, Response{Code: 0, Message: "ok"})
- }
- func (s *Server) handleMQTT(w http.ResponseWriter, r *http.Request) {
- switch r.Method {
- case http.MethodGet:
- s.listMQTTConfigs(w, r)
- case http.MethodPost:
- s.createMQTTConfig(w, r)
- default:
- writeJSON(w, http.StatusMethodNotAllowed, Response{Code: -1, Message: "方法不允许"})
- }
- }
- func (s *Server) handleMQTTByID(w http.ResponseWriter, r *http.Request) {
- idStr := strings.TrimPrefix(r.URL.Path, "/api/mqtt/")
- id, err := strconv.Atoi(idStr)
- if err != nil {
- writeJSON(w, http.StatusBadRequest, Response{Code: -1, Message: "无效的 ID"})
- return
- }
- switch r.Method {
- case http.MethodGet:
- s.getMQTTConfig(w, id)
- case http.MethodPut:
- s.updateMQTTConfig(w, r, id)
- case http.MethodDelete:
- s.deleteMQTTConfig(w, id)
- default:
- writeJSON(w, http.StatusMethodNotAllowed, Response{Code: -1, Message: "方法不允许"})
- }
- }
- func (s *Server) listMQTTConfigs(w http.ResponseWriter, r *http.Request) {
- configs, err := s.db.ListMQTTConfigs()
- if err != nil {
- writeJSON(w, http.StatusInternalServerError, Response{Code: -1, Message: err.Error()})
- return
- }
- writeJSON(w, http.StatusOK, Response{Code: 0, Message: "ok", Data: configs})
- }
- func (s *Server) createMQTTConfig(w http.ResponseWriter, r *http.Request) {
- var cfg database.MQTTConfig
- if err := json.NewDecoder(r.Body).Decode(&cfg); err != nil {
- writeJSON(w, http.StatusBadRequest, Response{Code: -1, Message: "无效的请求体"})
- return
- }
- if cfg.Broker == "" {
- writeJSON(w, http.StatusBadRequest, Response{Code: -1, Message: "broker 不能为空"})
- return
- }
- if cfg.ClientID == "" {
- cfg.ClientID = "opencode-monitor"
- }
- if cfg.Topic == "" {
- cfg.Topic = "opencode/status"
- }
- if err := s.db.SaveMQTTConfig(&cfg); err != nil {
- writeJSON(w, http.StatusInternalServerError, Response{Code: -1, Message: err.Error()})
- return
- }
- writeJSON(w, http.StatusCreated, Response{Code: 0, Message: "创建成功", Data: cfg})
- }
- func (s *Server) getMQTTConfig(w http.ResponseWriter, id int) {
- configs, err := s.db.ListMQTTConfigs()
- if err != nil {
- writeJSON(w, http.StatusInternalServerError, Response{Code: -1, Message: err.Error()})
- return
- }
- for _, cfg := range configs {
- if cfg.ID == id {
- writeJSON(w, http.StatusOK, Response{Code: 0, Message: "ok", Data: cfg})
- return
- }
- }
- writeJSON(w, http.StatusNotFound, Response{Code: -1, Message: "配置不存在"})
- }
- func (s *Server) updateMQTTConfig(w http.ResponseWriter, r *http.Request, id int) {
- var cfg database.MQTTConfig
- if err := json.NewDecoder(r.Body).Decode(&cfg); err != nil {
- writeJSON(w, http.StatusBadRequest, Response{Code: -1, Message: "无效的请求体"})
- return
- }
- cfg.ID = id
- if cfg.Broker == "" {
- writeJSON(w, http.StatusBadRequest, Response{Code: -1, Message: "broker 不能为空"})
- return
- }
- if cfg.ClientID == "" {
- cfg.ClientID = "opencode-monitor"
- }
- if cfg.Topic == "" {
- cfg.Topic = "opencode/status"
- }
- if err := s.db.SaveMQTTConfig(&cfg); err != nil {
- writeJSON(w, http.StatusInternalServerError, Response{Code: -1, Message: err.Error()})
- return
- }
- writeJSON(w, http.StatusOK, Response{Code: 0, Message: "更新成功", Data: cfg})
- }
- func (s *Server) deleteMQTTConfig(w http.ResponseWriter, id int) {
- if err := s.db.DeleteMQTTConfig(id); err != nil {
- writeJSON(w, http.StatusInternalServerError, Response{Code: -1, Message: err.Error()})
- return
- }
- writeJSON(w, http.StatusOK, Response{Code: 0, Message: "删除成功"})
- }
- func writeJSON(w http.ResponseWriter, statusCode int, data interface{}) {
- w.Header().Set("Content-Type", "application/json")
- w.WriteHeader(statusCode)
- json.NewEncoder(w).Encode(data)
- }
- func (s *Server) GetAddr() string {
- return s.server.Addr
- }
|