package api import ( "io" "net/http" "strconv" "time" "cockpit/internal/domain" "cockpit/internal/importer" "cockpit/internal/middleware" "github.com/gin-gonic/gin" ) func (h *Handler) ImportOrdersTemplate(c *gin.Context) { b, err := importer.BuildOrdersTemplate() if err != nil { c.JSON(http.StatusInternalServerError, domain.Fail("生成模板失败:"+err.Error())) return } c.Header("Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") c.Header("Content-Disposition", "attachment; filename=\"orders.xlsx\"") c.Writer.WriteHeader(http.StatusOK) _, _ = c.Writer.Write(b) } func (h *Handler) ImportOrdersPreview(c *gin.Context) { fh, err := c.FormFile("file") if err != nil { c.JSON(http.StatusBadRequest, domain.Fail("请上传文件(form-data: file)")) return } file, err := fh.Open() if err != nil { c.JSON(http.StatusBadRequest, domain.Fail("文件打开失败")) return } defer func() { _ = file.Close() }() total, preview, errs, err := importer.ParseOrdersExcel(c.Request.Context(), h.db, file, 20) if err != nil { c.JSON(http.StatusBadRequest, domain.Fail("解析失败:"+err.Error())) return } c.JSON(http.StatusOK, domain.OK(gin.H{ "totalRows": total, "preview": preview, "errors": errs, "errorCount": len(errs), })) } func (h *Handler) ImportOrdersCommit(c *gin.Context) { uidAny, _ := c.Get(middleware.CtxUserIDKey) uid, _ := uidAny.(uint64) fh, err := c.FormFile("file") if err != nil { c.JSON(http.StatusBadRequest, domain.Fail("请上传文件(form-data: file)")) return } file, err := fh.Open() if err != nil { c.JSON(http.StatusBadRequest, domain.Fail("文件打开失败")) return } defer func() { _ = file.Close() }() job, err := importer.CommitOrdersFromExcel(c.Request.Context(), h.db, file, uid, fh.Filename) if err != nil { c.JSON(http.StatusBadRequest, domain.Fail("导入失败:"+err.Error())) return } c.JSON(http.StatusOK, domain.OK(job)) } func (h *Handler) ImportOrdersJSON(c *gin.Context) { uidAny, _ := c.Get(middleware.CtxUserIDKey) uid, _ := uidAny.(uint64) body, err := io.ReadAll(c.Request.Body) if err != nil { c.JSON(http.StatusBadRequest, domain.Fail("读取请求失败")) return } job, err := importer.CommitOrdersFromJSON(c.Request.Context(), h.db, body, uid) if err != nil { c.JSON(http.StatusBadRequest, domain.Fail("导入失败:"+err.Error())) return } c.JSON(http.StatusOK, domain.OK(job)) } func (h *Handler) ImportJobs(c *gin.Context) { page, _ := strconv.Atoi(c.DefaultQuery("page", "1")) size, _ := strconv.Atoi(c.DefaultQuery("size", "20")) if page < 1 { page = 1 } if size < 1 || size > 200 { size = 20 } q := h.db.Model(&domain.ImportJob{}).Where("type = ?", "orders") var total int64 _ = q.Count(&total).Error var list []domain.ImportJob _ = q.Order("id DESC").Offset((page - 1) * size).Limit(size).Find(&list).Error c.JSON(http.StatusOK, domain.OK(gin.H{ "list": list, "total": total, })) } func (h *Handler) ImportJobGet(c *gin.Context) { id, _ := strconv.ParseUint(c.Param("id"), 10, 64) var job domain.ImportJob if err := h.db.Where("id = ?", id).First(&job).Error; err != nil { c.JSON(http.StatusNotFound, domain.Fail("不存在")) return } c.JSON(http.StatusOK, domain.OK(job)) } func (h *Handler) ImportJobErrors(c *gin.Context) { jobID, _ := strconv.ParseUint(c.Param("id"), 10, 64) page, _ := strconv.Atoi(c.DefaultQuery("page", "1")) size, _ := strconv.Atoi(c.DefaultQuery("size", "20")) if page < 1 { page = 1 } if size < 1 || size > 200 { size = 20 } q := h.db.Model(&domain.ImportJobError{}).Where("job_id = ?", jobID) var total int64 _ = q.Count(&total).Error var list []domain.ImportJobError _ = q.Order("id ASC").Offset((page - 1) * size).Limit(size).Find(&list).Error c.JSON(http.StatusOK, domain.OK(gin.H{ "list": list, "total": total, "at": time.Now(), })) }