// Package handlers 实现单元格相关的API请求处理器 package handlers import ( "excel-api/models" "excel-api/utils" "github.com/gin-gonic/gin" ) // CellRequest 单元格更新请求结构体 type CellRequest struct { Row int `json:"row" binding:"required"` // 行号(0-based),必填 Col int `json:"col" binding:"required"` // 列号(0-based),必填 CellType string `json:"cellType"` // 单元格类型 Value string `json:"value"` // 文本值 Formula string `json:"formula"` // 公式表达式 FileURL string `json:"fileUrl"` // 文件URL FileName string `json:"fileName"` // 文件名 FileSize int64 `json:"fileSize"` // 文件大小 MimeType string `json:"mimeType"` // MIME类型 } // GetCells 获取工作表的单元格数据 // 请求方式: GET // 路径: /api/sheets/:id/cells // 路径参数: id - 工作表ID // 查询参数: row(起始行), col(起始列), endRow(结束行), endCol(结束列) func GetCells(c *gin.Context) { id := c.Param("id") // 验证工作表是否存在 var sheet models.Sheet if result := models.DB.First(&sheet, id); result.Error != nil { utils.Error(c, 404, "工作表不存在") return } // 获取查询参数(可选范围查询) query := models.DB.Where("sheet_id = ?", id) // 如果提供了范围参数,则按范围过滤 if row := c.Query("row"); row != "" { query = query.Where("row >= ?", row) } if col := c.Query("col"); col != "" { query = query.Where("col >= ?", col) } if endRow := c.Query("endRow"); endRow != "" { query = query.Where("row <= ?", endRow) } if endCol := c.Query("endCol"); endCol != "" { query = query.Where("col <= ?", endCol) } var cells []models.Cell result := query.Find(&cells) if result.Error != nil { utils.Error(c, 500, "查询单元格数据失败") return } utils.Success(c, cells) } // BatchUpdateCells 批量更新单元格数据 // 请求方式: POST // 路径: /api/sheets/:id/cells // 路径参数: id - 工作表ID // 请求体: { "cells": [{ "row": 0, "col": 0, "value": "Hello" }, ...] } func BatchUpdateCells(c *gin.Context) { id := c.Param("id") // 验证工作表是否存在 var sheet models.Sheet if result := models.DB.First(&sheet, id); result.Error != nil { utils.Error(c, 404, "工作表不存在") return } var req struct { Cells []CellRequest `json:"cells" binding:"required"` // 单元格更新列表,必填 } if err := c.ShouldBindJSON(&req); err != nil { utils.Error(c, 400, "参数错误: "+err.Error()) return } // 使用事务批量更新单元格 tx := models.DB.Begin() defer func() { if r := recover(); r != nil { tx.Rollback() } }() for _, cellReq := range req.Cells { // 查找已存在的单元格 var cell models.Cell result := tx.Where("sheet_id = ? AND row = ? AND col = ?", id, cellReq.Row, cellReq.Col).First(&cell) if result.Error != nil { // 单元格不存在,创建新记录 cell = models.Cell{ SheetID: sheet.ID, Row: cellReq.Row, Col: cellReq.Col, CellType: cellReq.CellType, Value: cellReq.Value, Formula: cellReq.Formula, FileURL: cellReq.FileURL, FileName: cellReq.FileName, FileSize: cellReq.FileSize, MimeType: cellReq.MimeType, } // 设置默认类型 if cell.CellType == "" { cell.CellType = "text" } if err := tx.Create(&cell).Error; err != nil { tx.Rollback() utils.Error(c, 500, "创建单元格失败") return } } else { // 单元格已存在,更新字段 if cellReq.CellType != "" { cell.CellType = cellReq.CellType } cell.Value = cellReq.Value cell.Formula = cellReq.Formula cell.FileURL = cellReq.FileURL cell.FileName = cellReq.FileName cell.FileSize = cellReq.FileSize cell.MimeType = cellReq.MimeType if err := tx.Save(&cell).Error; err != nil { tx.Rollback() utils.Error(c, 500, "更新单元格失败") return } } } // 提交事务 if err := tx.Commit().Error; err != nil { utils.Error(c, 500, "提交事务失败") return } utils.SuccessWithMessage(c, "批量更新单元格成功", nil) }