You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Gin框架报错:无法将entities.Kendaraan作为*gin.Context使用

解决Go Gin类型不匹配错误:Cannot use 'kendaraan' (type entities.Kendaraan) as the type *gin.Context

问题根源

你遇到的类型不匹配问题,核心是函数设计用途不匹配:

  • process.go中的CreateKendaraan是Gin框架的HTTP请求处理器方法,专门接收*gin.Context参数,用于处理JSON格式的API请求(通过c.ShouldBindJSON解析请求体)。
  • 但你在parsehtml.go中把它当成普通业务函数,直接传入entities.Kendaraan实例,自然触发类型错误。

另外,你的parsehtml.go代码里还有逻辑错误:kendaraan.NomorKendaraan被连续赋值两次,覆盖了之前的vecType值,应该把其中一个赋值给JenisID(对应数据库表的id_jenis字段)。


解决方案一:重构业务逻辑(推荐)

把数据库操作从HTTP处理器中抽离成独立业务函数,让表单处理和API请求复用同一份逻辑:

1. 修改process.go,新增独立插入函数

// InsertKendaraan 独立处理Kendaraan数据插入的业务函数
func (h *KendaraanHandler) InsertKendaraan(kendaraan entities.Kendaraan) (int, error) {
    kendaraan.TanggalServis = time.Now()

    stmt := `INSERT INTO data_servis_kendaraan (
        id_jenis, 
        nama_pemilik, 
        nama_kendaraan, 
        nomor_kendaraan, 
        detail_servis, 
        tanggal_servis, 
        status_servis
    ) VALUES ($1, $2, $3, $4, $5, $6, $7)
    RETURNING id`
    var id int
    err := h.DB.QueryRow(stmt,
        kendaraan.JenisID,
        kendaraan.NamaPemilik,
        kendaraan.NamaKendaraan,
        int32(kendaraan.NomorKendaraan),
        kendaraan.DetailServis,
        kendaraan.TanggalServis,
        kendaraan.StatusServis).Scan(&id)
    return id, err
}

// 保留原有的Gin Handler,继续处理JSON请求
func (h *KendaraanHandler) CreateKendaraan(c *gin.Context) {
    var kendaraan entities.Kendaraan
    err := c.ShouldBindJSON(&kendaraan)
    if err != nil {
        fmt.Println("Received JSON payload:", c.Request.Body)
        c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
        return
    }

    id, err := h.InsertKendaraan(kendaraan)
    if err != nil {
        c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
        return
    }

    response := gin.H{
        "message": "Data telah dibuat!",
        "id":      id,
    }
    c.JSON(http.StatusCreated, response)
}

2. 修改parsehtml.go的调用逻辑

修正字段赋值错误,并调用新的业务函数:

} else if r.Method == http.MethodPost {
    r.ParseForm()

    var kendaraan entities.Kendaraan
    kendaraan.NamaPemilik = r.Form.Get("owner_name")
    kendaraan.NamaKendaraan = r.Form.Get("vec_name")
    
    // 修正字段赋值错误:vec_type对应id_jenis,vec_code对应nomor_kendaraan
    vecTypeStr := r.Form.Get("vec_type")
    vecType, err := strconv.ParseInt(vecTypeStr, 10, 32)
    if err != nil {
        panic(err)
    }
    kendaraan.JenisID = int32(vecType)
    
    vecCodeStr := r.Form.Get("vec_code")
    vecCode, err := strconv.ParseInt(vecCodeStr, 10, 32)
    if err != nil {
        panic(err)
    }
    kendaraan.NomorKendaraan = int32(vecCode)
    
    kendaraan.DetailServis = r.Form.Get("vec_detail")

    var data = make(map[string]interface{})
    vErrors := validateData.Struct(kendaraan)

    if vErrors != nil {
        data["tabel"] = kendaraan
        data["validation"] = vErrors
    } else {
        // 调用新的业务函数插入数据
        id, err := processModel.InsertKendaraan(kendaraan)
        if err != nil {
            data["error"] = fmt.Sprintf("Gagal menyimpan data: %v", err)
        } else {
            data["pesan"] = fmt.Sprintf("Data pasien berhasil disimpan (ID: %d)", id)
        }
    }

    temp, _ := template.ParseFiles("web/forms.html")
    temp.Execute(w, data)
}

解决方案二:适配现有Handler(临时应急)

如果不想重构代码,可以通过Gin的响应捕获机制,把表单处理适配到现有Handler(耦合度较高,不推荐长期使用):

修改parsehtml.go的POST处理部分:

} else if r.Method == http.MethodPost {
    var kendaraan entities.Kendaraan
    // 用Gin的ShouldBind绑定表单数据(需确保结构体字段和表单name对应,或添加`form`标签)
    err := c.ShouldBind(&kendaraan)
    if err != nil {
        panic(err)
    }

    var data = make(map[string]interface{})
    vErrors := validateData.Struct(kendaraan)

    if vErrors != nil {
        data["tabel"] = kendaraan
        data["validation"] = vErrors
    } else {
        // 捕获Handler的JSON响应
        originalWriter := c.Writer
        rec := httptest.NewRecorder()
        c.Writer = rec

        // 调用原Handler
        processModel.CreateKendaraan(c)

        // 恢复原Writer
        c.Writer = originalWriter

        // 解析响应结果
        if rec.Code == http.StatusCreated {
            data["pesan"] = "Data pasien berhasil disimpan"
        } else {
            var respErr map[string]string
            json.Unmarshal(rec.Body.Bytes(), &respErr)
            data["error"] = respErr["error"]
        }
    }

    temp, _ := template.ParseFiles("web/forms.html")
    temp.Execute(w, data)
}

内容的提问来源于stack exchange,提问作者MiPremix

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 16:47:01