初始提交:OCI 面板后端(含 GenAI 网关一期)
This commit is contained in:
@@ -0,0 +1,115 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
"oci-portal/internal/service"
|
||||
)
|
||||
|
||||
// proxyHandler 处理出站代理配置的增删改查。
|
||||
type proxyHandler struct {
|
||||
svc *service.ProxyService
|
||||
}
|
||||
|
||||
// list 返回全部代理(脱敏视图,含引用计数)。
|
||||
func (h *proxyHandler) list(c *gin.Context) {
|
||||
items, err := h.svc.List(c.Request.Context())
|
||||
if err != nil {
|
||||
respondError(c, err)
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, gin.H{"items": items})
|
||||
}
|
||||
|
||||
// create 新建代理。
|
||||
func (h *proxyHandler) create(c *gin.Context) {
|
||||
var req service.ProxyInput
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
view, err := h.svc.Create(c.Request.Context(), req)
|
||||
if err != nil {
|
||||
h.respond(c, err)
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusCreated, view)
|
||||
}
|
||||
|
||||
// update 更新代理;密码缺省沿用、空串清除。
|
||||
func (h *proxyHandler) update(c *gin.Context) {
|
||||
id, ok := pathID(c)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
var req service.ProxyInput
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
view, err := h.svc.Update(c.Request.Context(), id, req)
|
||||
if err != nil {
|
||||
h.respond(c, err)
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, view)
|
||||
}
|
||||
|
||||
// remove 删除代理;仍被租户引用时返回 409。
|
||||
func (h *proxyHandler) remove(c *gin.Context) {
|
||||
id, ok := pathID(c)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
if err := h.svc.Delete(c.Request.Context(), id); err != nil {
|
||||
h.respond(c, err)
|
||||
return
|
||||
}
|
||||
c.Status(http.StatusNoContent)
|
||||
}
|
||||
|
||||
// importBatch 批量导入代理;逐行解析,返回成功与脱敏后的失败明细。
|
||||
func (h *proxyHandler) importBatch(c *gin.Context) {
|
||||
var req struct {
|
||||
Text string `json:"text" binding:"required"`
|
||||
}
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
res, err := h.svc.Import(c.Request.Context(), req.Text)
|
||||
if err != nil {
|
||||
respondError(c, err)
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, res)
|
||||
}
|
||||
|
||||
// probe 手动重测代理出口地区,同步返回最新视图。
|
||||
func (h *proxyHandler) probe(c *gin.Context) {
|
||||
id, ok := pathID(c)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
view, err := h.svc.Probe(c.Request.Context(), id)
|
||||
if err != nil {
|
||||
h.respond(c, err)
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, view)
|
||||
}
|
||||
|
||||
// respond 把代理业务错误映射到语义状态码。
|
||||
func (h *proxyHandler) respond(c *gin.Context, err error) {
|
||||
switch {
|
||||
case errors.Is(err, service.ErrProxyInvalid):
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
case errors.Is(err, service.ErrProxyInUse):
|
||||
c.JSON(http.StatusConflict, gin.H{"error": err.Error()})
|
||||
default:
|
||||
respondError(c, err)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user