package handler import ( "io" "net/http" "strings" "github.com/gin-gonic/gin" "github.com/user-management-system/internal/service" ) // ExportHandler handles user export/import requests type ExportHandler struct { exportService *service.ExportService } // NewExportHandler creates a new ExportHandler func NewExportHandler(exportService *service.ExportService) *ExportHandler { return &ExportHandler{exportService: exportService} } func (h *ExportHandler) ExportUsers(c *gin.Context) { format := c.DefaultQuery("format", "csv") fieldsStr := c.Query("fields") keyword := c.Query("keyword") statusStr := c.Query("status") var fields []string if fieldsStr != "" { fields = strings.Split(fieldsStr, ",") } var status *int if statusStr != "" { s, err := strconvAtoi(statusStr) if err == nil { status = &s } } req := &service.ExportUsersRequest{ Format: format, Fields: fields, Keyword: keyword, Status: status, } data, filename, contentType, err := h.exportService.ExportUsers(c.Request.Context(), req) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"code": 500, "message": "导出失败: " + err.Error()}) return } c.Header("Content-Type", contentType) c.Header("Content-Disposition", "attachment; filename="+filename) c.Data(http.StatusOK, contentType, data) } func (h *ExportHandler) ImportUsers(c *gin.Context) { file, _, err := c.Request.FormFile("file") if err != nil { c.JSON(http.StatusBadRequest, gin.H{"code": 400, "message": "请上传文件"}) return } defer file.Close() data, err := io.ReadAll(file) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"code": 500, "message": "读取文件失败"}) return } format := c.DefaultQuery("format", "csv") successCount, failCount, errs := h.exportService.ImportUsers(c.Request.Context(), data, format) c.JSON(http.StatusOK, gin.H{ "code": 0, "data": gin.H{ "success_count": successCount, "fail_count": failCount, "errors": errs, }, }) } func (h *ExportHandler) GetImportTemplate(c *gin.Context) { format := c.DefaultQuery("format", "csv") data, filename, contentType, err := h.exportService.GetImportTemplateByFormat(format) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"code": 500, "message": "获取模板失败"}) return } c.Header("Content-Type", contentType) c.Header("Content-Disposition", "attachment; filename="+filename) c.Data(http.StatusOK, contentType, data) } func strconvAtoi(s string) (int, error) { var n int for _, c := range s { if c < '0' || c > '9' { return 0, nil } n = n*10 + int(c-'0') } return n, nil }