feat: 实现分层架构,包含 domain、service、repository 和 pkg 层
- 新增 domain 层:model、provider、route、stats 实体 - 新增 service 层:models、providers、routing、stats 业务逻辑 - 新增 repository 层:models、providers、stats 数据访问 - 新增 pkg 工具包:errors、logger、validator - 新增中间件:CORS、logging、recovery、request ID - 新增数据库迁移:初始 schema 和索引 - 新增单元测试和集成测试 - 新增规范文档:config-management、database-migration、error-handling、layered-architecture、middleware-system、request-validation、structured-logging、test-coverage - 移除 config 子包和 model_router(已迁移至分层架构)
This commit is contained in:
@@ -2,19 +2,25 @@ package handler
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"gorm.io/gorm"
|
||||
|
||||
"nex/backend/internal/config"
|
||||
appErrors "nex/backend/pkg/errors"
|
||||
|
||||
"nex/backend/internal/domain"
|
||||
"nex/backend/internal/service"
|
||||
)
|
||||
|
||||
// ProviderHandler 供应商管理处理器
|
||||
type ProviderHandler struct{}
|
||||
type ProviderHandler struct {
|
||||
providerService service.ProviderService
|
||||
}
|
||||
|
||||
// NewProviderHandler 创建供应商处理器
|
||||
func NewProviderHandler() *ProviderHandler {
|
||||
return &ProviderHandler{}
|
||||
func NewProviderHandler(providerService service.ProviderService) *ProviderHandler {
|
||||
return &ProviderHandler{providerService: providerService}
|
||||
}
|
||||
|
||||
// CreateProvider 创建供应商
|
||||
@@ -33,43 +39,34 @@ func (h *ProviderHandler) CreateProvider(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
// 创建供应商对象
|
||||
provider := &config.Provider{
|
||||
provider := &domain.Provider{
|
||||
ID: req.ID,
|
||||
Name: req.Name,
|
||||
APIKey: req.APIKey,
|
||||
BaseURL: req.BaseURL,
|
||||
Enabled: true, // 默认启用
|
||||
}
|
||||
|
||||
// 保存到数据库
|
||||
err := config.CreateProvider(provider)
|
||||
err := h.providerService.Create(provider)
|
||||
if err != nil {
|
||||
// 检查是否是唯一约束错误(ID 重复)
|
||||
if err.Error() == "UNIQUE constraint failed: providers.id" {
|
||||
if strings.Contains(err.Error(), "UNIQUE constraint failed") {
|
||||
c.JSON(http.StatusConflict, gin.H{
|
||||
"error": "供应商 ID 已存在",
|
||||
})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusInternalServerError, gin.H{
|
||||
"error": "创建供应商失败: " + err.Error(),
|
||||
})
|
||||
writeError(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
// 掩码 API Key 后返回
|
||||
provider.MaskAPIKey()
|
||||
c.JSON(http.StatusCreated, provider)
|
||||
}
|
||||
|
||||
// ListProviders 列出所有供应商
|
||||
func (h *ProviderHandler) ListProviders(c *gin.Context) {
|
||||
providers, err := config.ListProviders()
|
||||
providers, err := h.providerService.List()
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{
|
||||
"error": "查询供应商失败: " + err.Error(),
|
||||
})
|
||||
writeError(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -80,7 +77,7 @@ func (h *ProviderHandler) ListProviders(c *gin.Context) {
|
||||
func (h *ProviderHandler) GetProvider(c *gin.Context) {
|
||||
id := c.Param("id")
|
||||
|
||||
provider, err := config.GetProvider(id, true) // 掩码 API Key
|
||||
provider, err := h.providerService.Get(id, true)
|
||||
if err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
c.JSON(http.StatusNotFound, gin.H{
|
||||
@@ -88,9 +85,7 @@ func (h *ProviderHandler) GetProvider(c *gin.Context) {
|
||||
})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusInternalServerError, gin.H{
|
||||
"error": "查询供应商失败: " + err.Error(),
|
||||
})
|
||||
writeError(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -109,8 +104,7 @@ func (h *ProviderHandler) UpdateProvider(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
// 更新供应商
|
||||
err := config.UpdateProvider(id, req)
|
||||
err := h.providerService.Update(id, req)
|
||||
if err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
c.JSON(http.StatusNotFound, gin.H{
|
||||
@@ -118,18 +112,13 @@ func (h *ProviderHandler) UpdateProvider(c *gin.Context) {
|
||||
})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusInternalServerError, gin.H{
|
||||
"error": "更新供应商失败: " + err.Error(),
|
||||
})
|
||||
writeError(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
// 返回更新后的供应商
|
||||
provider, err := config.GetProvider(id, true)
|
||||
provider, err := h.providerService.Get(id, true)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{
|
||||
"error": "查询更新后的供应商失败: " + err.Error(),
|
||||
})
|
||||
writeError(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -140,8 +129,7 @@ func (h *ProviderHandler) UpdateProvider(c *gin.Context) {
|
||||
func (h *ProviderHandler) DeleteProvider(c *gin.Context) {
|
||||
id := c.Param("id")
|
||||
|
||||
// 删除供应商(级联删除模型)
|
||||
err := config.DeleteProvider(id)
|
||||
err := h.providerService.Delete(id)
|
||||
if err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
c.JSON(http.StatusNotFound, gin.H{
|
||||
@@ -149,19 +137,23 @@ func (h *ProviderHandler) DeleteProvider(c *gin.Context) {
|
||||
})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusInternalServerError, gin.H{
|
||||
"error": "删除供应商失败: " + err.Error(),
|
||||
})
|
||||
writeError(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
// 删除关联的模型
|
||||
models, _ := config.ListModels("")
|
||||
for _, model := range models {
|
||||
if model.ProviderID == id {
|
||||
_ = config.DeleteModel(model.ID)
|
||||
}
|
||||
}
|
||||
|
||||
c.Status(http.StatusNoContent)
|
||||
}
|
||||
|
||||
// writeError 统一错误响应处理
|
||||
func writeError(c *gin.Context, err error) {
|
||||
if appErr, ok := appErrors.AsAppError(err); ok {
|
||||
c.JSON(appErr.HTTPStatus, gin.H{
|
||||
"error": appErr.Message,
|
||||
"code": appErr.Code,
|
||||
})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusInternalServerError, gin.H{
|
||||
"error": err.Error(),
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user