package handlers import ( "database/sql" "encoding/json" "fmt" "licensing-cotton/internal/config" "net/http" "time" "licensing-cotton/internal/database" "licensing-cotton/internal/models" ) // HandleRenewLicense 让设备只续 1 小时;需满足某些逻辑才能续 func HandleRenewLicense(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { http.Error(w, `{"error":"Only POST allowed","code":405}`, http.StatusMethodNotAllowed) return } var req struct { DeviceID string `json:"device_id"` Expiration string `json:"expiration"` } if err := json.NewDecoder(r.Body).Decode(&req); err != nil { http.Error(w, `{"error":"解析请求失败","code":400}`, http.StatusBadRequest) return } if config.AutoRenewAllDevices { // 计算新的到期时间 newExpiration := time.Now().Add(1 * time.Hour) // 更新数据库 expiration _, errUpdate := database.DB.Exec(`UPDATE devices SET expiration=? WHERE device_id=?`, newExpiration, req.DeviceID) if errUpdate != nil { http.Error(w, fmt.Sprintf(`{"error":"更新Expiration失败:%s","code":500}`, errUpdate.Error()), http.StatusInternalServerError) return } lic, signErr := SignLicense(req.DeviceID, newExpiration) if signErr != nil { http.Error(w, fmt.Sprintf(`{"error":"签名失败: %v","code":500}`, signErr.Error()), http.StatusInternalServerError) return } // 返回成功续期的 License resp := struct { License License `json:"license"` Message string `json:"message"` }{ License: lic, Message: "License renewed automatically (AutoRenewAllDevices).", } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(resp) return } // **查询设备** var dev models.Device err := database.DB.QueryRow(`SELECT id, device_id, expiration FROM devices WHERE device_id=?`, req.DeviceID). Scan(&dev.ID, &dev.DeviceID, &dev.Expiration) if err == sql.ErrNoRows { if err := CreateRequest(req.DeviceID); err != nil { http.Error(w, fmt.Sprintf(`{"error":"续期申请失败: %s","code":409}`, err.Error()), http.StatusConflict) return } http.Error(w, `{"error":"设备不存在,已提交申请,等待管理员审批","code":404}`, http.StatusAccepted) return } else if err != nil { http.Error(w, fmt.Sprintf(`{"error":"数据库查询错误: %s","code":500}`, err.Error()), http.StatusInternalServerError) return } newExpiration := time.Now().Add(1 * time.Hour) if dev.Expiration.Before(time.Now()) { if err := CreateRequest(req.DeviceID); err != nil { http.Error(w, fmt.Sprintf(`{"error":"续期申请失败: %s","code":409}`, err.Error()), http.StatusConflict) return } http.Error(w, `{"error":"设备过期,已提交续期申请,等待管理员审批","code":404}`, http.StatusAccepted) return } if dev.Expiration.Before(newExpiration) { // 如果时间不够1小时了,就续期到可以运行的极限 newExpiration = dev.Expiration } // **创建新 License 并签名** lic, signErr := SignLicense(dev.DeviceID, newExpiration) if signErr != nil { http.Error(w, fmt.Sprintf(`{"error":"%v","code":500}`, signErr.Error()), http.StatusInternalServerError) return } // **返回成功续期的 License** resp := struct { License License `json:"license"` Message string `json:"message"` }{ License: lic, Message: "License renewed successfully.", } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(resp) }